goods.js 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962
  1. define({
  2. name: "basic",
  3. template: `
  4. <div id="basicGoods">
  5. <div class="vue-main-title">
  6. <div class="vue-main-title-left"></div>
  7. <div class="vue-main-title-content">基础信息</div>
  8. </div>
  9. <div style="margin:0 auto;width:80%;">
  10. <el-form :rules="rules" :model="form" label-width="130px">
  11. <el-form-item label="排序" prop="sort" required>
  12. <el-input v-model="form.goods.display_order"></el-input>
  13. <div class="form-item_tips">数字大的排名在前,默认排序方式为创建时间,注意:输入最大数为9位数,只能输入数字</div>
  14. </el-form-item>
  15. <el-form-item label="商品名称" prop="title" required>
  16. <el-input v-model="form.goods.title"></el-input>
  17. </el-form-item>
  18. <el-form-item label="商品简称" prop="alias">
  19. <el-input v-model="form.goods.alias"></el-input>
  20. <div class="form-item_tips">用于打印电子面单,支付通道推送,不填默认用商品名称</div>
  21. </el-form-item>
  22. <el-form-item label="商品分类" required prop="category" v-if="!attr_hide.hide_category">
  23. <el-row v-for="(categoryItem,itemIndex) in categoryList" style="margin-bottom:10px;" :key="itemIndex">
  24. <el-col :span="4" v-if="form.category_level * 1 >= 1">
  25. <el-select placeholder="请选择一级分类" v-model="categoryItem[0].id" clearable filterable @change="btnfirst($event,itemIndex,categoryItem[0].id)" >
  26. <el-option :value="firstItem.id" :label="firstItem.name" v-for="(firstItem,firstIndex) in form.category_list" :key="firstItem.id">{{firstItem.name}}</el-option>
  27. </el-select>
  28. </el-col>
  29. <el-col :span="4" v-if="form.category_level * 1 >= 2">
  30. <el-select v-if="secondChildrensIsshow" placeholder="请选择二级分类" style="margin:0 10px;" v-model="categoryItem[1].id" clearable filterable @change="btnSecond($event,itemIndex,categoryItem[1].id)" @click.native="btnChangeSecond($event,itemIndex,categoryItem[0])">
  31. <el-option :value="secondItem.id" :label="secondItem.name" v-for="(secondItem,secondIndex) in category_list_box[itemIndex].secondCategory" :key="secondItem.id">{{secondItem.name}}</el-option>
  32. </el-select>
  33. </el-col>
  34. <el-col :span="4" v-if="form.category_level * 1 >= 3">
  35. <el-select v-if="threeChildrensIsshow" placeholder="请选择三级分类" style="margin:0 10px;" v-model="categoryItem[2].id" clearable filterable @change="btnThree($event,itemIndex)" @click.native="btnChangeThree($event,itemIndex,categoryItem[1],categoryItem[0])">
  36. <el-option :value="threeItem.id" :label="threeItem.name" v-for="(threeItem,threeIndex) in category_list_box[itemIndex].threeCategory" :key="threeItem.id">{{threeItem.name}}</el-option>
  37. </el-select>
  38. </el-col>
  39. <el-col :span="4" v-if="form.category_to_option_open==1">
  40. <el-select placeholder="请选择规格" style="margin:0 10px;" v-model="form.goods.category_to_option[itemIndex].goods_option_id" clearable filterable>
  41. <el-option :value="optionItem.id" :label="optionItem.title" v-for="(optionItem,optionIndex) in form.options" :key="optionItem.id">{{optionItem.title}}</el-option>
  42. </el-select>
  43. </el-col>
  44. <el-col :span="4" >
  45. <el-button icon="el-icon-plus" v-if="itemIndex==0" @click="addCategory">添加分类</el-button>
  46. <el-button icon="el-icon-delete" v-else @click="removeCategory(itemIndex)"></el-button>
  47. </el-col>
  48. </el-row>
  49. </el-form-item>
  50. <el-form-item label="品牌" v-if="!attr_hide.hide_brand">
  51. <el-select v-model="form.goods.brand_id" placeholder="请选择" clearable filterable>
  52. <el-option
  53. v-for="item in form.brand"
  54. :key="item.id"
  55. :label="item.name"
  56. :value="item.id">
  57. </el-option>
  58. </el-select>
  59. </el-form-item>
  60. <el-form-item label="商品类型" v-if="isGoodsType() == true" >
  61. <el-radio-group v-model="form.goods.type">
  62. <el-radio v-if="(!attr_hide.appoint_type) || attr_hide.appoint_type === 1" :label="1">实体商品</el-radio>
  63. <el-radio v-if="(!attr_hide.appoint_type) || attr_hide.appoint_type === 2" :label="2">虚拟商品</el-radio>
  64. </el-radio-group>
  65. </el-form-item>
  66. <el-form-item label="下单是否需要地址" v-if="form.goods.type === 2 && form.goods.plugin_id != 154">
  67. <el-radio-group v-model="form.goods.need_address">
  68. <el-radio v-if="(!attr_hide.appoint_need_address) || attr_hide.appoint_need_address === 0" :label="0">需要地址</el-radio>
  69. <el-radio v-if="(!attr_hide.appoint_need_address) || attr_hide.appoint_need_address === 1" :label="1">不需要地址</el-radio>
  70. </el-radio-group>
  71. </el-form-item>
  72. <el-form-item label="商品单位" required>
  73. <el-input v-model="form.goods.sku"></el-input>
  74. <div class="form-item_tips">如: 个/件/包</div>
  75. </el-form-item>
  76. <el-form-item label="商品属性">
  77. <el-checkbox :true-label="1" false-label="0"label="推荐" v-model="form.goods.is_recommand" ></el-checkbox>
  78. <el-checkbox :true-label="1" false-label="0"label="新上" v-model="form.goods.is_new"></el-checkbox>
  79. <el-checkbox :true-label="1" false-label="0"label="热卖" v-model="form.goods.is_hot"></el-checkbox>
  80. <el-checkbox :true-label="1" false-label="0"label="促销" v-model="form.goods.is_discount"></el-checkbox>
  81. </el-form-item>
  82. <el-form-item label="商品图片" required prop="thumb">
  83. <div class="upload-boxed" @click="displaySelectMaterialPopup('thumb')">
  84. <img
  85. :src="form.goods.thumb_link"
  86. style="width: 150px; height: 150px; border-radius: 5px; cursor: pointer;object-fit:cover;"
  87. v-show="form.goods.thumb"
  88. />
  89. <div class="el-icon-plus" v-show="!form.goods.thumb"></div>
  90. <div class="upload-boxed-text">点击重新上传</div>
  91. </div>
  92. <div v-if="isDecorate" class="form-item_tips">建议尺寸: 640 * 640 ,或正方型图片 <span @click.stop="jumpUrl" style="color: #196dfa;font-weight: 600;margin-left: 15px;cursor:pointer;">图片智能在线设计</span><i class="el-icon-question" style="color:#196dfa;margin-left:2px;" @click="showIntroduce = true;"></i> </div>
  93. </el-form-item>
  94. <el-form-item label="其他图片">
  95. <div class="goods-image_list">
  96. <draggable v-model="form.goods.thumb_url">
  97. <div
  98. class="upload-boxed"
  99. v-for="(imageItem,itemIndex) in form.goods.thumb_url"
  100. :key="itemIndex"
  101. >
  102. <img
  103. :src="imageItem.thumb_link"
  104. style="width: 150px; height: 150px; border-radius: 5px; cursor: pointer;object-fit:cover;"
  105. />
  106. <i class="goods-images_remove el-icon-close" @click.stop="removeGoodsImage(itemIndex)"></i>
  107. <!-- <div class="upload-boxed-text" @click="displaySelectMaterialPopup('other')">点击重新上传</div> -->
  108. </div>
  109. </draggable>
  110. <div
  111. class="upload-boxed goods-image_list-upload"
  112. @click="displaySelectMaterialPopup('other')"
  113. >
  114. <div class="el-icon-plus"></div>
  115. <div class="upload-boxed-text">点击上传图片</div>
  116. </div>
  117. </div>
  118. <div class="form-item_tips">建议尺寸: 640 * 640 ,或正方型图片</div>
  119. </el-form-item>
  120. <el-form-item label="首图视频">
  121. <el-row>
  122. <!-- <el-col :span="4">
  123. <video v-if="form.goods.goods_video" style="width: 150px;height:100px" controls="controls" class="" :src="form.goods.goods_video"></video>
  124. </el-col> -->
  125. <el-col :span="6">
  126. <div class="upload-boxed">
  127. <div class="el-icon-plus" v-show="!form.goods.goods_video_link" @click="displaySelectMaterialPopup('video',3)"></div>
  128. <div>
  129. <video v-if="form.goods.goods_video_link" style="width: 150px;height:119px;object-fit: cover;" controls="controls" class="" :src="form.goods.goods_video_link"></video>
  130. <i class="goods-images_remove el-icon-close" style="top:-6px" v-if="form.goods.goods_video_link" @click="removeVideo('video')"></i>
  131. </div>
  132. <div class="upload-boxed-text" @click="displaySelectMaterialPopup('video',3)">点击重新上传视频</div>
  133. </div>
  134. </el-col>
  135. <el-col :span="6">
  136. <div class="upload-boxed">
  137. <img
  138. :src="form.goods.video_image_link"
  139. style="width: 150px; height: 150px; border-radius: 5px; cursor: pointer;object-fit:cover;"
  140. v-show="form.goods.video_image_link"
  141. v-if="form.goods"
  142. />
  143. <i class="goods-images_remove el-icon-close" v-if="form.goods.video_image_link" @click="removeVideo('image')"></i>
  144. <div class="el-icon-plus" v-show="!form.goods||!form.goods.video_image_link" @click="displaySelectMaterialPopup('video_cover')"></div>
  145. <div class="upload-boxed-text" @click="displaySelectMaterialPopup('video_cover')">点击重新上传封面</div>
  146. </div>
  147. </el-col>
  148. </el-row>
  149. <div class="form-item_tips">
  150. 设置后商品详情首图默认显示视频,建议时长9-30秒
  151. <div>视频封面不上传默认商品主图</div>
  152. </div>
  153. </el-form-item>
  154. <el-form-item label="商品价格" v-if="!attr_hide.hide_price">
  155. <el-row :gutter="10">
  156. <el-col :span="7">
  157. <el-input v-model="form.goods.price" :min="0" :disabled="readonly" oninput="if(value<0)value=0" type="number">
  158. <template slot="prepend">现价</template>
  159. <template slot="append">元</template>
  160. </el-input>
  161. </el-col>
  162. <el-col :span="7">
  163. <el-input v-model="form.goods.market_price" :min="0" :disabled="readonly" oninput="if(value<0)value=0" type="number">
  164. <template slot="prepend">原价</template>
  165. <template slot="append">元</template>
  166. </el-input>
  167. </el-col>
  168. <el-col :span="7">
  169. <el-input v-model="form.goods.cost_price" :min="0" :disabled="readonly" oninput="if(value<0)value=0" type="number">
  170. <template slot="prepend">成本</template>
  171. <template slot="append">元</template>
  172. </el-input>
  173. </el-col>
  174. </el-row>
  175. <div class="form-item_tips">尽量填写完整,有助于于商品销售的数据分析</div>
  176. </el-form-item>
  177. <el-form-item label="商品编码">
  178. <el-input v-model="form.goods.goods_sn"></el-input>
  179. </el-form-item>
  180. <el-form-item label="商品条码" v-if="!attr_hide.hide_product_sn">
  181. <el-input v-model="form.goods.product_sn"></el-input>
  182. </el-form-item>
  183. <el-form-item label="重量" v-if="!attr_hide.hide_weight">
  184. <el-input style="width:30%" v-model="form.goods.weight" :min="0" oninput="if(value<0)value=0" type="number">
  185. <template slot="append">克</template>
  186. </el-input>
  187. <div class="form-item_tips">商品重量设置为空或者0,则不计算重量</div>
  188. </el-form-item>
  189. <el-form-item label="体积" v-if="!attr_hide.hide_volume">
  190. <el-input style="width:30%" v-model="form.goods.volume" :min="0" oninput="if(value<0)value=0" type="number">
  191. <template slot="append">m³</template>
  192. </el-input>
  193. </el-form-item>
  194. <el-form-item label="第三方销量" required prop="virtualSales">
  195. <el-input style="width:30%" v-model="form.goods.virtual_sales">
  196. <template slot="append">件</template>
  197. </el-input>
  198. <div class="form-item_tips">第三方销量为平台再其他第三方平台销量同步汇总,前端显示销量=第三方销量+商城销量</div>
  199. </el-form-item>
  200. <template v-if="form.goods.hide_goods_sales_switch">
  201. <el-form-item label="总销量">
  202. <el-switch v-model="form.goods.hide_goods_sales_alone" :active-value="1" :inactive-value="0"></el-switch>
  203. <div class="form-item_tips">
  204. 开启后,商品详情隐藏总销量走独立设置,不受默认设置限制
  205. </div>
  206. </el-form-item>
  207. <el-form-item v-if="form.goods.hide_goods_sales_alone" label="隐藏总销量">
  208. <el-switch v-model="form.goods.hide_goods_sales" :active-value="1" :inactive-value="0"></el-switch>
  209. <div class="form-item_tips">
  210. 开启后,商品详情隐藏总销量,只对自营商品与拍卖商品起效
  211. </div>
  212. </el-form-item>
  213. </template>
  214. <el-form-item label="库存" required prop="stock">
  215. <el-input style="width:30%" v-model="form.goods.stock">
  216. <template slot="append">件</template>
  217. </el-input>
  218. <div class="form-item_tips">商品的剩余数量, 如启用多规格或为虚拟卡密产品,则此处设置无效,请移至“商品规格”或“虚拟物品插件”中设置</div>
  219. </el-form-item>
  220. <el-form-item label="减库存方式">
  221. <el-radio-group v-model="form.goods.reduce_stock_method">
  222. <el-radio :label="0">拍下减库存</el-radio>
  223. <el-radio :label="1">付款减库存</el-radio>
  224. <el-radio :label="2">永不减库存</el-radio>
  225. </el-radio-group>
  226. <div class="form-item_tips">
  227. 拍下减库存:买家拍下商品即减少库存,存在恶拍风险。秒杀、超低价等热销商品,如需避免超卖可选此方式。
  228. <div>付款减库存:买家拍下并完成付款方减少库存,存在超卖风险。如需减少恶拍、提高回款效率,可选此方式。</div>
  229. <div>订单支付前关闭或取消返还库存,订单支付后退换货的订单不返还库存。</div>
  230. </div>
  231. </el-form-item>
  232. <el-form-item label="预扣库存">
  233. <el-input style="width:30%" disabled v-model="form.goods.withhold_stock">
  234. <template slot="append">件</template>
  235. </el-input>
  236. <div class="form-item_tips">
  237. 拍下减库存时,下单即锁定商品库存。
  238. <div>付款减库存时,用户点击支付订单后,1分钟内锁定商品库存。</div>
  239. <div>存在预扣库存时,无法编辑商品库存和减库存方式设置。</div>
  240. </div>
  241. </el-form-item>
  242. <el-form-item label="商品前端隐藏">
  243. <el-switch v-model="form.goods.is_hide" :active-value="2" :inactive-value="1"></el-switch>
  244. <div class="form-item_tips">
  245. 开启后,该商品在前端列表中不显示,也不能在搜索框中搜索出该商品,可以通过分享链接购买
  246. </div>
  247. </el-form-item>
  248. <el-form-item label="不可退款退货">
  249. <el-switch v-model="form.goods.no_refund" :active-value="1" :inactive-value="0"></el-switch>
  250. </el-form-item>
  251. <el-form-item label="是否上架" v-if="!attr_hide.hide_status">
  252. <el-switch v-model="form.goods.status" :active-value="1" :inactive-value="0"></el-switch>
  253. </el-form-item>
  254. </el-form>
  255. </div>
  256. <upload-multimedia-img
  257. :upload-show="showSelectMaterialPopup"
  258. :type="materialType"
  259. :name="formFieldName"
  260. :selNum="selNum"
  261. :select="select"
  262. @replace="showSelectMaterialPopup = !showSelectMaterialPopup"
  263. @sureSelect="sureSelectImg"
  264. @sure="selectedMaterial"
  265. ></upload-multimedia-img>
  266. <introduce v-model="showIntroduce" v-show="showIntroduce"></introduce>
  267. </div>`,
  268. style: `
  269. .goods-image_list {
  270. margin-right:20px;
  271. }
  272. .goods-image_list .upload-boxed {
  273. position:relative;
  274. }
  275. .goods-image_list > div {
  276. display:inline-flex;
  277. flex-wrap:wrap;
  278. column-gap:10px;
  279. row-gap:10px;
  280. }
  281. #basicGoods input::-webkit-outer-spin-button,
  282. #basicGoods input::-webkit-inner-spin-button {
  283. -webkit-appearance: none;
  284. }
  285. #basicGoods input[type="number"] {
  286. -moz-appearance: textfield;
  287. }
  288. `,
  289. props: {
  290. form: {
  291. default() {
  292. return ;
  293. },
  294. },
  295. formKey: {
  296. type: String,
  297. default: "goods",
  298. },
  299. attr_hide:{
  300. default() {
  301. return {}
  302. }
  303. }
  304. },
  305. data() {
  306. let regular = new RegExp("^[0-9][0-9]*$")
  307. let checkoutSort = (rule, value, callback) => {
  308. this.sortRegular = true
  309. let sort = regular.test(this.form.goods.display_order);
  310. if(!sort){
  311. callback(new Error('请输入正整数'));
  312. this.sortRegular = false
  313. }
  314. };
  315. let checkoutTitle = (rule, value, callback) => {
  316. this.titleRegular = true
  317. if(!this.form.goods.title){
  318. callback(new Error('请输入商品名称'));
  319. this.titleRegular = false
  320. }
  321. };
  322. // let checkoutSku = (rule, value, callback) => {
  323. // let sku = true
  324. // if(this.form.goods.sku !== '个' || this.form.goods.sku !== '件' || this.form.goods.sku !== '包'){
  325. // sku = false
  326. // }else{
  327. // sku = true
  328. // }
  329. // this.skuRegular = true
  330. // if(!sku){
  331. // callback(new Error('个/件/包'));
  332. // this.skuRegular = false
  333. // }
  334. // };
  335. let checkoutCategory = (rule, value, callback) => {
  336. if(!this.attr_hide.hide_category){
  337. let info = true
  338. this.categoryList.forEach(item => {
  339. item.forEach(el => {
  340. if(!el.id){
  341. info = false
  342. return
  343. }
  344. })
  345. })
  346. this.categoryRegular = true
  347. if(!info){
  348. callback(new Error('请选择商品分类'));
  349. this.categoryRegular = false
  350. }
  351. }else{
  352. this.categoryRegular = true
  353. }
  354. };
  355. let checkoutThumb = (rule, value, callback) => {
  356. this.thumbRegular = true
  357. if(!this.form.goods.thumb){
  358. callback(new Error('请选择商品图片'));
  359. this.thumbRegular = false
  360. }
  361. };
  362. let checkoutVirtualSales = (rule, value, callback) => {
  363. let virtualSales = regular.test(this.form.goods.virtual_sales);
  364. this.virtualSalesRegular = true
  365. if(!virtualSales){
  366. callback(new Error('请输入正整数'));
  367. this.virtualSalesRegular = false
  368. }
  369. };
  370. let checkoutStock = (rule, value, callback) => {
  371. let stock = regular.test(this.form.goods.stock);
  372. this.stockRegular = true
  373. if(!stock){
  374. callback(new Error('请输入正整数'));
  375. this.stockRegular = false
  376. }
  377. };
  378. return {
  379. readonly:readonly,
  380. showIntroduce:false,
  381. showSelectMaterialPopup: false,
  382. formFieldName: "",
  383. goodsImagesChangeIndex: null,
  384. materialType: "",
  385. selNum: "one",
  386. select:"open",
  387. rules:{
  388. sort:{ validator: checkoutSort},
  389. title:{validator:checkoutTitle},
  390. category:{validator:checkoutCategory},
  391. // goodsSku:{validator:checkoutSku},
  392. thumb:{validator:checkoutThumb},
  393. virtualSales:{validator:checkoutVirtualSales},
  394. stock:{validator:checkoutStock},
  395. },
  396. submitPropertyKeyWhiteList: [],
  397. // yesRegular:true,
  398. categoryList:[],
  399. // 原始值
  400. OriginCategory:[],
  401. // 改变后的值
  402. changeCategoryList:[],
  403. // 分类值
  404. category_list_box:[],
  405. isShow:true,
  406. sortRegular:true,
  407. titleRegular:true,
  408. // skuRegular:true,
  409. categoryRegular:true,
  410. virtualSalesRegular:true,
  411. stockRegular:true,
  412. thumbRegular:true,
  413. // 提交的数据
  414. threeChildrensIsshow:true,
  415. secondChildrensIsshow:true,
  416. isDecorate:IsDecorate,
  417. };
  418. },
  419. mounted() {
  420. this.addDefaul()
  421. // 设置默认品牌
  422. if(this.form.goods.brand_id === 0){
  423. this.form.goods.brand_id = ""
  424. }
  425. this.goodsCategoryShow()
  426. this.getCategoryValue()
  427. },
  428. methods: {
  429. //是否显示商品类型
  430. isGoodsType(){
  431. let plugin_ids = [140, 154, 157];
  432. if (plugin_ids.indexOf(this.form.goods.plugin_id) === -1){
  433. return true;
  434. }else{
  435. return false;
  436. }
  437. },
  438. jumpUrl() {
  439. window.open(CktUrl);
  440. },
  441. // 添加默认值
  442. addDefaul(){
  443. if(JSON.stringify(this.attr_hide) !== '[]'){
  444. if(this.attr_hide.appoint_type){
  445. this.form.goods.type = this.attr_hide.appoint_type
  446. }
  447. if(this.attr_hide.appoint_need_address){
  448. this.form.goods.need_address = this.attr_hide.appoint_need_address
  449. }
  450. }
  451. if(!this.form.goods.display_order){
  452. this.$set(this.form.goods,"display_order",0)
  453. }
  454. if(!this.form.goods.category_to_option){
  455. this.$set(this.form.goods,"category_to_option",[{goods_option_id:""}])
  456. }
  457. if(!this.form.goods.type){
  458. this.$set(this.form.goods,"type",1)
  459. }
  460. if(!this.form.goods.need_address){
  461. this.$set(this.form.goods,"need_address",0)
  462. }
  463. if(!this.form.goods.price){
  464. this.$set(this.form.goods,"price",0)
  465. }
  466. if(!this.form.goods.market_price){
  467. this.$set(this.form.goods,"market_price",0)
  468. }
  469. if(!this.form.goods.cost_price){
  470. this.$set(this.form.goods,"cost_price",0)
  471. }
  472. if(!this.form.goods.weight){
  473. this.$set(this.form.goods,"weight",0)
  474. }
  475. if(!this.form.goods.volume){
  476. this.$set(this.form.goods,"volume",0)
  477. }
  478. if(!this.form.goods.reduce_stock_method){
  479. this.$set(this.form.goods,"reduce_stock_method",0)
  480. }
  481. if(!this.form.goods.withhold_stock){
  482. this.$set(this.form.goods,"withhold_stock",0)
  483. }
  484. if(!this.form.goods.is_hide){
  485. this.$set(this.form.goods,"is_hide",1)
  486. }
  487. if(!this.form.goods.no_refund){
  488. this.$set(this.form.goods,"no_refund",0)
  489. }
  490. if(!this.form.goods.cost_price){
  491. this.$set(this.form.goods,"cost_price",0)
  492. }
  493. if(!this.form.goods.virtual_sales){
  494. this.$set(this.form.goods,"virtual_sales",0)
  495. }
  496. },
  497. // 商品分类回显
  498. goodsCategoryShow(){
  499. // 判断回显时商品类型是否存在,不存在根据category_level长度添加数据--this.judgeCategoryLevel()
  500. // 如果category_level的长度与返回的长度不一致,则不全默认值
  501. if(this.form.goods.category){
  502. this.OriginCategory = JSON.parse(JSON.stringify(this.form.goods.category))
  503. if(this.form.category_level == 3){
  504. this.OriginCategory.forEach(item => {
  505. if(item.length === 2){
  506. item.push({ "id": '', "level": 3 })
  507. }
  508. })
  509. }else if(this.form.category_level == 2){
  510. this.OriginCategory.forEach(item => {
  511. if(item.length === 1){
  512. item.push({ "id": '', "level": 2 })
  513. }
  514. })
  515. }
  516. }else{
  517. this.judgeCategoryLevel()
  518. }
  519. if(!this.form.goods.category){ this.isShow = false }
  520. if(this.form.goods.category){
  521. if(this.form.goods.category.length){
  522. if(this.form.goods.category[0].length){
  523. for(item of this.form.goods.category){
  524. item.forEach(cateItem => {
  525. let id = cateItem.id
  526. cateItem.id = cateItem.name
  527. cateItem.name = id
  528. })
  529. item = item.map(el => ({'id':el.id , 'level':el.level,'name':el.name}))
  530. // 判断是否有一级分类
  531. let firstLevel = item.find(threeItem => threeItem.level === 1)
  532. if(this.form.category_level * 1 === 1 && !firstLevel){
  533. item.push({'id':'' , 'level':1})
  534. }
  535. // 判断是否有二级分类
  536. let secondLevel = item.find(threeItem => threeItem.level === 2)
  537. if(this.form.category_level * 1 === 2 && !secondLevel){
  538. item.push({'id':'' , 'level':2})
  539. }
  540. // 判断是否有三级分类
  541. let threeLevel = item.find(threeItem => threeItem.level === 3)
  542. if(this.form.category_level * 1 === 3 && !threeLevel){
  543. item.push({'id':'' , 'level':3})
  544. }
  545. this.categoryList.push(item)
  546. this.changeCategoryList = this.categoryList
  547. }
  548. }else{
  549. this.judgeCategoryLevel()
  550. }
  551. }else{
  552. this.judgeCategoryLevel()
  553. }
  554. }else{
  555. this.judgeCategoryLevel()
  556. this.changeCategoryList = this.categoryList
  557. }
  558. },
  559. // 获取分类值
  560. getCategoryValue(){
  561. this.category_list_box = []
  562. this.categoryList.forEach((item,index) => {
  563. let filterCategry = []
  564. filterCategry.push({secondCategory:[]})
  565. filterCategry.push({threeCategory:[]})
  566. this.category_list_box.push(filterCategry)
  567. })
  568. },
  569. // 判断分类等级
  570. judgeCategoryLevel(){
  571. switch (this.form.category_level * 1){
  572. case 1 :
  573. this.categoryList = [[{ "id": '', "level": 1 }]];
  574. this.OriginCategory = this.categoryList
  575. break;
  576. case 2 :
  577. this.categoryList = [[{ "id": '', "level": 1 }, { "id": '', "level": 2 }]];
  578. this.OriginCategory = this.categoryList
  579. break;
  580. default:
  581. this.categoryList = [[{ "id": '', "level": 1 }, { "id": '', "level": 2 }, { "id": '', "level": 3 }]];
  582. this.OriginCategory = this.categoryList
  583. break;
  584. }
  585. },
  586. displaySelectMaterialPopup(fieldName = "thumb", type = 1) {
  587. if(fieldName == 'other'){
  588. this.selNum = 'more'
  589. }else{
  590. this.selNum = 'one'
  591. }
  592. this.formFieldName = fieldName;
  593. this.showSelectMaterialPopup = !this.showSelectMaterialPopup;
  594. this.materialType = String(type);
  595. },
  596. selectedMaterial(name, image, imageUrl) {
  597. let originalImageUrl = JSON.parse(JSON.stringify(imageUrl))
  598. if(name == "video"){
  599. if(typeof imageUrl == 'string') {
  600. this.form.goods.goods_video_link = imageUrl;
  601. this.form.goods.goods_video = imageUrl;
  602. return
  603. }
  604. this.form.goods.goods_video_link = imageUrl[0].url
  605. this.form.goods.goods_video = originalImageUrl[0].attachment
  606. }
  607. if(name == "video_cover"){
  608. this.form.goods.video_image_link = imageUrl[0].url
  609. this.form.goods.video_image = originalImageUrl[0].attachment
  610. }
  611. if (Array.isArray(imageUrl)) {
  612. imageUrl = imageUrl.map((item) => {
  613. return item.url;
  614. });
  615. }
  616. if (this.formFieldName === "other") {
  617. if (this.goodsImagesChangeIndex === null) {
  618. if(!this.form.goods.thumb_url){
  619. this.$set(this.form.goods,"thumb_url",[])
  620. }
  621. for(let item of originalImageUrl){
  622. this.form.goods["thumb_url"].push({
  623. thumb_link:item.url,
  624. thumb:item.attachment
  625. });
  626. }
  627. } else {
  628. // this.form.goods["thumb_url"][this.goodsImagesChangeIndex] = imageUrl[0];
  629. this.goodsImagesChangeIndex = null;
  630. }
  631. } else {
  632. this.form.goods[this.formFieldName] = originalImageUrl[0].attachment;
  633. if(this.formFieldName == 'thumb') {
  634. this.form.goods['thumb_link'] = imageUrl[0]
  635. }
  636. }
  637. },
  638. // 点击图片选中
  639. sureSelectImg(val,id,item){
  640. // console.log(val,id,item,'点击图片选中');
  641. // if(this.formFieldName == "video_cover"){
  642. // this.form.goods.video_image = item.url
  643. // }
  644. // if(this.formFieldName == "thumb"){
  645. // this.form.goods[this.formFieldName] = item.url
  646. // }
  647. },
  648. changeGoodsImage(index,val) {
  649. this.goodsImagesChangeIndex = index;
  650. this.displayUploadImagePopup("images");
  651. },
  652. addCategory() {
  653. switch (this.form.category_level * 1){
  654. case 1 :
  655. this.categoryList.push([{ "id": '', "level": 1 }]);
  656. if(this.isShow){this.OriginCategory.push([{ "id": '', "level": 1 }])}
  657. break;
  658. case 2 :
  659. this.categoryList.push([{ "id": '', "level": 1 }, { "id": '', "level": 2 }]);
  660. if(this.isShow){this.OriginCategory.push([{ "id": '', "level": 1 }, { "id": '', "level": 2 }])}
  661. break;
  662. default:
  663. this.categoryList.push([{ "id": '', "level": 1 }, { "id": '', "level": 2 }, { "id": '', "level": 3 }]);
  664. if(this.isShow){this.OriginCategory.push([{ "id": '', "level": 1 }, { "id": '', "level": 2 },{ "id": '', "level": 3 }])}
  665. break;
  666. }
  667. this.form.goods.category_to_option.push({'goods_option_id':""});
  668. this.getCategoryValue()
  669. },
  670. removeCategory(itemIndex) {
  671. this.categoryList.splice(itemIndex, 1);
  672. this.category_list_box.splice(itemIndex,1)
  673. this.OriginCategory.splice(itemIndex,1)
  674. this.form.goods.category_to_option.splice(itemIndex,1);
  675. },
  676. // 视频删除
  677. removeVideo(type){
  678. if(type == 'video'){
  679. this.form.goods.goods_video = ""
  680. this.form.goods.goods_video_link = ""
  681. }
  682. if(type == 'image'){
  683. this.form.goods.video_image = ""
  684. this.form.goods.video_image_link = ""
  685. }
  686. this.$forceUpdate()
  687. },
  688. removeGoodsImage(itemIndex) {
  689. this.form.goods.thumb_url.splice(itemIndex, 1);
  690. },
  691. validate() {
  692. let submitCategoryList = []
  693. this.OriginCategory.forEach(element => {
  694. element = element.map(item => {
  695. delete item.name
  696. })
  697. })
  698. this.OriginCategory.forEach(item =>{
  699. let filterCatrgorys = item.filter((value, index, arr) => {
  700. return value.id !== ''
  701. })
  702. submitCategoryList.push(filterCatrgorys)
  703. })
  704. // 过滤空数组
  705. let filterSubmitCategoryList = []
  706. submitCategoryList.forEach((element,index) => {
  707. if(element.length !== 0){
  708. filterSubmitCategoryList.push(element)
  709. }
  710. });
  711. // 过滤商品分类重复的数据
  712. let idList = []
  713. filterSubmitCategoryList.forEach(item => {
  714. if(item.length >= this.form.category_level){
  715. idList.push(item[this.form.category_level * 1 - 1].id)
  716. }else{
  717. idList = []
  718. }
  719. })
  720. if(!this.attr_hide.hide_category){
  721. if(new Set(idList).size !== idList.length || idList.length == 0){
  722. this.$message({
  723. message: '请选择不同的商品分类',
  724. type: 'warning'
  725. });
  726. this.categoryRegular = false
  727. }else{
  728. this.categoryRegular = true
  729. }
  730. }else{ this.categoryRegular = true }
  731. this.tipValidator();
  732. if(this.form.goods.type == 1){
  733. this.form.goods.need_address = 0
  734. }
  735. let thumb_url = [];
  736. // 过滤其他图片http字段
  737. if(this.form.goods.thumb_url !== undefined ){
  738. for(let item of this.form.goods.thumb_url){
  739. thumb_url.push(item.thumb);
  740. }
  741. }
  742. if (this.categoryRegular && this.sortRegular && this.titleRegular && this.virtualSalesRegular && this.stockRegular && this.thumbRegular && this.form.goods.sku) {
  743. let saveGoods = {
  744. brand_id:this.form.goods.brand_id ? this.form.goods.brand_id : "",
  745. category: filterSubmitCategoryList,
  746. display_order:this.form.goods.display_order,
  747. title:this.form.goods.title,
  748. alias:this.form.goods.alias? this.form.goods.alias :'',
  749. type:this.form.goods.type,
  750. need_address: this.form.goods.need_address,
  751. sku:this.form.goods.sku,
  752. is_recommand:this.form.goods.is_recommand,
  753. is_new:this.form.goods.is_new,
  754. is_hot:this.form.goods.is_hot,
  755. is_discount:this.form.goods.is_discount,
  756. thumb:this.form.goods.thumb,
  757. thumb_url:thumb_url,
  758. price:this.form.goods.price,
  759. market_price:this.form.goods.market_price,
  760. cost_price:this.form.goods.cost_price,
  761. goods_sn:this.form.goods.goods_sn ? this.form.goods.goods_sn : "",
  762. product_sn:this.form.goods.product_sn ? this.form.goods.product_sn : "",
  763. weight:this.form.goods.weight,
  764. volume:this.form.goods.volume,
  765. virtual_sales:this.form.goods.virtual_sales,
  766. stock:this.form.goods.stock,
  767. reduce_stock_method:this.form.goods.reduce_stock_method,
  768. is_hide:this.form.goods.is_hide,
  769. no_refund:this.form.goods.no_refund,
  770. video_image:this.form.goods.video_image ? this.form.goods.video_image : "",
  771. goods_video:this.form.goods.goods_video ? this.form.goods.goods_video : "",
  772. withhold_stock:this.form.goods.withhold_stock,
  773. category_to_option:this.form.goods.category_to_option,
  774. hide_goods_sales:this.form.goods.hide_goods_sales,
  775. hide_goods_sales_alone:this.form.goods.hide_goods_sales_alone,
  776. };
  777. if(!this.attr_hide.hide_status){
  778. saveGoods.status = this.form.goods.status;
  779. }
  780. return saveGoods;
  781. } else {
  782. return false;
  783. }
  784. },
  785. tipValidator(){
  786. if(!this.sortRegular){
  787. this.$message({
  788. message: '请输入排序',
  789. type: 'warning'
  790. });
  791. return
  792. }else if(!this.form.goods.title){
  793. this.$message({
  794. message: '请输入商品名称',
  795. type: 'warning'
  796. });
  797. return
  798. }else if(!this.form.goods.sku){
  799. this.$message({
  800. message: '请填写商品单位',
  801. type: 'warning'
  802. });
  803. }else if(!this.form.goods.thumb){
  804. this.$message({
  805. message: '请选择商品图片',
  806. type: 'warning'
  807. });
  808. return
  809. }else if(!this.virtualSalesRegular && this.form.goods.virtual_sales !== ''){
  810. this.$message({
  811. message: '请输入第三方销量',
  812. type: 'warning'
  813. });
  814. return
  815. }else if(!this.stockRegular){
  816. this.$message({
  817. message: '请输入库存',
  818. type: 'warning'
  819. });
  820. return
  821. }
  822. // if(!this.form.goods.virtual_sales){this.virtualSalesRegular = false }
  823. // if(!this.form.goods.stock){this.stockRegular = false }
  824. },
  825. // extraDate(){
  826. // return {
  827. // 'extra':"额外数据"
  828. // }
  829. // },
  830. // 监听一级商品分类
  831. btnfirst(value,itemIndex,firstValue){
  832. if(!firstValue){
  833. this.category_list_box[itemIndex].secondCategory = []
  834. this.category_list_box[itemIndex].threeCategory = []
  835. this.categoryList[itemIndex].forEach(item => {
  836. item.id = ""
  837. })
  838. }
  839. this.categoryList[itemIndex].forEach((item,key) => {
  840. if(key == 0){
  841. item.id = item.id
  842. }else{
  843. item.id = ""
  844. }
  845. })
  846. // 点击一级分类获取二级分类数据
  847. this.form.category_list.forEach(item => {
  848. if(item.id == value){
  849. // this.secondCategory = item.childrens
  850. this.category_list_box[itemIndex].secondCategory = item.childrens
  851. return
  852. }
  853. })
  854. this.listenCategory(value,itemIndex,0)
  855. },
  856. // 监听二级商品分类
  857. btnChangeSecond(value,itemIndex,secondValue){
  858. let category_list = JSON.parse(JSON.stringify(this.form.category_list))
  859. let secondChildrens = []
  860. if(typeof secondValue.id == "string" && secondValue.id){
  861. this.secondChildrensIsshow = false
  862. category_list.forEach((item,index) => {
  863. if(item.id == secondValue.name){
  864. secondChildrens.push(...item.childrens)
  865. return
  866. }
  867. })
  868. this.category_list_box[itemIndex].secondCategory = secondChildrens
  869. this.secondChildrensIsshow = true
  870. }
  871. },
  872. btnSecond(value,itemIndex,secondValue){
  873. if(!secondValue){
  874. this.category_list_box[itemIndex].threeCategory = []
  875. }
  876. this.categoryList[itemIndex].forEach((item,key) => {
  877. if(key === 2){
  878. item.id = ''
  879. }
  880. })
  881. // 点击二级分类获取三级分类数据
  882. if(this.category_list_box[itemIndex].secondCategory){
  883. this.category_list_box[itemIndex].secondCategory.forEach((item,index) => {
  884. if(item.id == value ){
  885. // this.threeCategory = item.childrens
  886. this.category_list_box[itemIndex].threeCategory = item.childrens
  887. return
  888. }
  889. })
  890. }
  891. this.listenCategory(value,itemIndex,1)
  892. },
  893. // 监听三级商品分类
  894. btnChangeThree(value,itemIndex,secondValue,oneValue){
  895. let category_list = JSON.parse(JSON.stringify(this.form.category_list))
  896. let threeChildrens = []
  897. if(typeof secondValue.id == "string" && secondValue.id){
  898. this.threeChildrensIsshow = false
  899. category_list.forEach((item,index) => {
  900. if(item.id == oneValue.name){
  901. item.childrens.forEach((el,key) => {
  902. if(el.id == secondValue.name){
  903. threeChildrens.push(...el.childrens)
  904. return
  905. }
  906. })
  907. return
  908. }
  909. })
  910. this.category_list_box[itemIndex].threeCategory = threeChildrens
  911. this.threeChildrensIsshow = true
  912. }
  913. },
  914. btnThree(value,itemIndex){
  915. this.listenCategory(value,itemIndex,2)
  916. },
  917. listenCategory(value,itemIndex,type){
  918. let info = false
  919. this.changeCategoryList[itemIndex].forEach((el,key) => {
  920. if(el.id === this.categoryList[itemIndex][key].id){
  921. info = true
  922. return
  923. }
  924. })
  925. if(this.isShow){
  926. if(info){
  927. let categoryBoxList = []
  928. this.OriginCategory[itemIndex].forEach((item,key) => {
  929. if(type == 2){
  930. if(key === 2){
  931. item = this.categoryList[itemIndex][key]
  932. }
  933. }else if(type == 1){
  934. if(key === 2 || key === 1){
  935. item = this.categoryList[itemIndex][key]
  936. }
  937. }else if(type == 0){
  938. if(key === 2 || key === 1 || key === 0){
  939. item = this.categoryList[itemIndex][key]
  940. // item.id = ""
  941. }
  942. }
  943. categoryBoxList.push(item)
  944. })
  945. this.OriginCategory[itemIndex] = categoryBoxList
  946. }else{
  947. this.OriginCategory[itemIndex] = this.categoryList[itemIndex]
  948. }
  949. }
  950. }
  951. },
  952. });