addGoods.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584
  1. <template>
  2. <view class="add-goods">
  3. <u-form :model="form" ref="goodsForm" label-width="160">
  4. <view class="form-title">基本信息</view>
  5. <view class="form-cont">
  6. <u-form-item required label="商品相册" label-position="top"><upload :images="form.images" @handleRemove="imgRemove" @uploadSuccess="uploadSuccess" /></u-form-item>
  7. <u-form-item required label="商品名称"><u-input input-align="right" v-model="form.title" /></u-form-item>
  8. <u-form-item required label="商品分类">
  9. <view class="form-main" @click="openSel('cate_show')">
  10. <text v-if="category_name">{{ category_name }}</text>
  11. <text class="input-pl" v-else>请选择商品分类</text>
  12. </view>
  13. <view slot="right"><u-icon name="arrow-down-fill" size="24"></u-icon></view>
  14. </u-form-item>
  15. <u-form-item label="商品品牌">
  16. <view class="form-main" @click="goPage('/pagesT/brand/selBrand')">
  17. <text v-if="brand_name">{{ brand_name }}</text>
  18. <text class="input-pl" v-else>请选择品牌</text>
  19. </view>
  20. <view slot="right"><u-icon name="arrow-down-fill" size="24"></u-icon></view>
  21. </u-form-item>
  22. <u-form-item label="商品卖点"><u-input input-align="right" v-model="form.describe" /></u-form-item>
  23. <u-form-item label="抄码商品">
  24. <view class="form-value">
  25. <u-switch style="transform: translateY(14rpx);" @change="switchChange" v-model="isEq" :active-value="5" :inactive-value="4" size="40"></u-switch>
  26. </view>
  27. </u-form-item>
  28. <u-form-item label="保质期">
  29. <u-input input-align="right" v-model="form.expireTime" />
  30. <view slot="right">天</view>
  31. </u-form-item>
  32. <!-- <u-form-item label="货架编码"><u-input input-align="right" v-model="form.storage" /></u-form-item> -->
  33. <u-form-item label="禁止销售店铺" label-position="top">
  34. <view class="top-value">
  35. <u-tag class="tag-li" v-for="(item, index) in no_sales_shop" :key="index" :text="item.name" closeable type="primary" @close="deletShop(index)" />
  36. <u-button size="mini" @click="selShop">
  37. <u-icon name="plus" margin-right="20"></u-icon>
  38. 新增
  39. </u-button>
  40. </view>
  41. </u-form-item>
  42. <u-form-item label="关键词" label-position="top">
  43. <view class="top-value">
  44. <u-tag class="tag-li" v-for="(item, index) in form.tag" :key="index" :text="item" closeable type="primary" @close="deletTag(index)" />
  45. <u-button size="mini" @click="openSel('tag_show')">
  46. <u-icon name="plus" margin-right="20"></u-icon>
  47. 新增
  48. </u-button>
  49. </view>
  50. </u-form-item>
  51. </view>
  52. <view class="form-title">规格明细</view>
  53. <view class="form-cont">
  54. <u-form-item required label="基本单位">
  55. <view class="form-main" @click="openSel('m_unit_show')">
  56. <text v-if="master_unit">{{ master_unit }}</text>
  57. <text class="input-pl" v-else>请选择基本单位</text>
  58. </view>
  59. <view slot="right"><u-icon name="arrow-down-fill" size="24"></u-icon></view>
  60. </u-form-item>
  61. <u-form-item label="辅助单位" label-position="top">
  62. <view class="top-value">
  63. <block v-for="(item, index) in form.unitData" :key="index">
  64. <u-tag
  65. class="tag-li"
  66. v-if="item.isMaster === 4"
  67. :text="'1' + item.unitName + '=' + item.conversion + master_unit"
  68. :closeable="isEditSpec === 5 || isEq"
  69. type="primary"
  70. @close="deletUnit(index, item)"
  71. />
  72. </block>
  73. <u-button v-if="!isEq || (isEq && form.unitData.length < 1)" size="mini" @click="openSel('unit_show')">
  74. <u-icon name="plus" margin-right="20"></u-icon>
  75. 新增
  76. </u-button>
  77. </view>
  78. </u-form-item>
  79. <u-form-item label="商品规格">
  80. <view @click="editSku" slot="right" style="font-size: 28rpx; color: #007AFF;">
  81. <u-icon name="edit-pen" size="28"></u-icon>
  82. <text style="margin-left: 10rpx;">编辑</text>
  83. </view>
  84. </u-form-item>
  85. </view>
  86. <view class="form-title">商品详情</view>
  87. <view class="form-cont"><editorW :html="form.description" @editInput="editInput"></editorW></view>
  88. </u-form>
  89. <view class="submit-btn"><view class="btn-min" @click="submit">提交发布</view></view>
  90. <u-popup v-model="tag_show" border-radius="10" mode="center">
  91. <view class="pop-model">
  92. <view class="pop-tit">新增关键词</view>
  93. <input :focus="true" type="text" confirm-type="done" @confirm="tagConfirm" placeholder-class="input-pl" placeholder="请输入" v-model="tag_key" />
  94. <u-button type="primary" size="medium" @click="tagConfirm">确定</u-button>
  95. </view>
  96. </u-popup>
  97. <u-popup v-model="unit_show" mode="center" border-radius="10">
  98. <view class="pop-model">
  99. <view class="pop-tit">新增辅助单位</view>
  100. <view class="unit-model-main">
  101. <text>1</text>
  102. <view class="sel-view" @click="openSel('fz_unit_show')">
  103. <text v-if="pop_unit_obj.label">{{ pop_unit_obj.label }}</text>
  104. <text class="input-pl" v-else>请选择</text>
  105. </view>
  106. =
  107. <input class="uni-num-input" type="digit" v-model="conversion" />
  108. <text>{{ master_unit }}</text>
  109. </view>
  110. <view class="confirm-btn" @click="unitPopConfirm">确定</view>
  111. </view>
  112. </u-popup>
  113. <tki-tree ref="tkitree" :selectParent="true" :range="cate_list" rangeKey="title" @confirm="cateConfirm"></tki-tree>
  114. <u-select v-model="m_unit_show" mode="single-column" value-name="id" label-name="unitName" :list="unit_options" @confirm="unitConfirm"></u-select>
  115. <u-select z-index="10080" v-model="fz_unit_show" mode="single-column" value-name="id" label-name="unitName" :list="unit_options" @confirm="unitPopSelConfirm"></u-select>
  116. </view>
  117. </template>
  118. <script>
  119. import editorW from '@/components/editor/editor.vue';
  120. import upload from '@/components/qiniu/QiniuUpload.vue';
  121. import tkiTree from '@/components/tki-tree/tki-tree.vue';
  122. export default {
  123. components: { editorW, upload, tkiTree },
  124. data() {
  125. return {
  126. isEq: false,
  127. shopData: '',
  128. conversion: '', //辅助单位换算比例
  129. master_unit: '', //基本单位
  130. pop_unit_obj: {}, // 弹窗辅助单位
  131. tag_show: false, //新增关键词弹窗
  132. tag_key: '', // 新增关键词
  133. brandData: {}, //品牌数据
  134. brand_name: '', //品牌名称
  135. category_name: '', //分类名称
  136. unit_options: [], //计量单位
  137. copy_unit_options: [], //计量单位
  138. expressType_list: [
  139. {
  140. label: '包邮',
  141. value: 1
  142. },
  143. {
  144. label: '运费模版',
  145. value: 2
  146. },
  147. {
  148. label: '统一运费',
  149. value: 3
  150. }
  151. ],
  152. unit_show: false, // 新增辅助弹窗
  153. cate_show: false, // 商品分类弹窗
  154. m_unit_show: false, // 单位弹窗
  155. fz_unit_show: false,
  156. brand_list: [],
  157. cate_list: [],
  158. no_sales_shop: [],
  159. origin_unit_obj: [],
  160. isEditSpec: 5, // 5 表示此商品从未采购过,允许用户随意编辑单位和属性;4 表示商品已经采购过,隐藏添加属性按钮,避免skuid重组
  161. form: {
  162. delUnitIds: [], // 辅助单位删除delUnitIds (unitId)
  163. delSpecSkuIds: [], // 属性删除delSpecSkuIds(这个用id)
  164. title: '', //商品名称
  165. storage: '', //货架编码
  166. specType: 1, // 是否启用多规格 1单规格 2多规格
  167. specGroup: [], //多规格数据
  168. specMultiple: '', //多规格明细
  169. unitData: [], //计量单位
  170. describe: '', //商品卖点
  171. code: '', //商品code
  172. barCode: '', //商品条码
  173. weight: '', //商品重量
  174. categoryId: '', //分类ID
  175. categoryPath: '', //分类路径
  176. assistCategoryPath: '', //副分类
  177. assistCategoryId: '',
  178. expireTime: '', //保质期
  179. brandId: '', //品牌ID
  180. tag: [], //关键词
  181. description: '', //商品详情
  182. noSalesShop: '', //不销售店铺ID
  183. images: [], //商品图片
  184. enableStatus: 5, //是否上架
  185. isStore: false, //是否是商户后台上传商品
  186. isEq: 4, //超码商品 4否 5是
  187. merchantId: '', //商户ID
  188. salesShop: ''
  189. }
  190. };
  191. },
  192. watch: {
  193. brandData(val) {
  194. if (val.id) {
  195. this.form.brandId = val.id;
  196. this.brand_name = val.title;
  197. }
  198. },
  199. shopData(val) {
  200. if (val) {
  201. this.no_sales_shop = val;
  202. }
  203. }
  204. },
  205. onLoad(options) {
  206. if (options.id) {
  207. this.goods_id = options.id;
  208. this.getGoodsBasicInfoById();
  209. uni.setNavigationBarTitle({
  210. title: '编辑商品资料'
  211. });
  212. }
  213. this.getAllCategory();
  214. this.getAllUnit();
  215. },
  216. methods: {
  217. selShop() {
  218. let selId = '';
  219. if (this.no_sales_shop.length) {
  220. selId = JSON.stringify(this.no_sales_shop.map(item => item.id));
  221. }
  222. this.goPage('/pagesT/shop/selShop?check=1&selId=' + selId);
  223. },
  224. switchChange(val) {
  225. this.form.isEq = val;
  226. // if(this.isEditSpec !== 4 &&val){
  227. // this.form.unitData = [];
  228. // this.master_unit = '';
  229. // }
  230. },
  231. cateConfirm(arr) {
  232. this.category_name = arr[0].title;
  233. this.form.categoryId = arr[0].id;
  234. if (arr[0].parents.length) {
  235. this.form.categoryPath = arr[0].parents.map(item => item.id).join(',') + ',' + arr[0].id;
  236. } else {
  237. this.form.categoryPath = arr[0].id;
  238. }
  239. },
  240. editInput(val) {
  241. this.form.description = val;
  242. },
  243. // 获取商品详情
  244. getGoodsBasicInfoById() {
  245. this.$u.api.getGoodsBasicInfoById(this.goods_id).then(({ data }) => {
  246. this.isEditSpec = data.isEditSpec;
  247. // 备份
  248. this.origin_unit_obj = this.$u.deepClone(data.unitData);
  249. this.form = {
  250. title: data.title, //商品名称
  251. storage: data.storage, //货架编码
  252. specType: data.specType, // 是否启用多规格 1单规格 2多规格
  253. specGroup: data.specGroup, //多规格数据
  254. specMultiple: data.specMultiple, //多规格明细
  255. unitData: data.unitData, //计量单位
  256. describe: data.describe, //商品卖点
  257. code: data.code, //商品code
  258. barCode: data.barCode, //商品条码
  259. weight: data.weight, //商品重量
  260. categoryId: data.categoryId, //分类ID
  261. categoryPath: data.categoryPath, //分类路径
  262. expireTime: data.expireTime, //保质期
  263. brandId: data.brandId, //品牌ID
  264. tag: data.tag ? data.tag.split(',') : [], //关键词
  265. description: data.description, //商品详情
  266. noSalesShop: data.noSalesShop, //不销售店铺ID
  267. images: data.images, //商品图片
  268. enableStatus: data.enableStatus, //是否上架
  269. isStore: false, //是否是商户后台上传商品
  270. isEq: data.isEq,
  271. salesShop: data.salesShop,
  272. delUnitIds: [], // 辅助单位删除delUnitIds (unitId)
  273. delSpecSkuIds: [], // 属性删除delSpecSkuIds(这个用id)
  274. assistCategoryId: data.assistCategoryId,
  275. assistCategoryPath: data.assistCategoryPath
  276. };
  277. this.isEq = data.isEq === 5;
  278. this.no_sales_shop = data.noSalesShopNames
  279. ? data.noSalesShopNames.split(',').map((item, index) => {
  280. const id = data.noSalesShop.split(',')[index];
  281. return {
  282. name: item,
  283. id: id
  284. };
  285. })
  286. : [];
  287. this.category_name = data.categoryTitle;
  288. this.brand_name = data.brandTitle;
  289. const masterUnit = data.unitData.find(item => item.isMaster === 5).unitName;
  290. this.master_unit = masterUnit;
  291. });
  292. },
  293. // 辅助单位删除
  294. deletUnit(index, row) {
  295. if (!!this.goods_id) {
  296. this.form.delUnitIds.push(row.unitId);
  297. }
  298. this.form.unitData.splice(index, 1);
  299. },
  300. //基本单位选择
  301. unitConfirm(arr) {
  302. // 编辑页面把删除 的单位ID存储下来
  303. if (!!this.goods_id) {
  304. const unitData = this.$u.deepClone(this.origin_unit_obj);
  305. this.form.delUnitIds = unitData.map(item => item.unitId);
  306. if (this.form.specType === 1) {
  307. const specMultiple = this.$u.deepClone(this.form.specMultiple);
  308. this.form.delSpecSkuIds = specMultiple.map(item => item.id);
  309. }
  310. }
  311. // 重置单位
  312. this.form.unitData = [];
  313. this.master_unit = arr[0].label;
  314. const unit = {
  315. isDefault: 4,
  316. isMaster: 5,
  317. weight: '',
  318. unitName: arr[0].label,
  319. unitId: arr[0].value,
  320. barCode: ''
  321. };
  322. this.form.unitData.unshift(unit);
  323. },
  324. editSku() {
  325. if (!this.master_unit) {
  326. this.$u.toast('请先选择基本单位');
  327. return;
  328. }
  329. if (this.form.specType === 1) {
  330. this.goPage('/pages/goods/sku?specType=' + this.form.specType + '&unitData=' + JSON.stringify(this.form.unitData));
  331. } else {
  332. this.goPage(
  333. '/pages/goods/sku?specType=' +
  334. this.form.specType +
  335. '&unitData=' +
  336. JSON.stringify(this.form.unitData) +
  337. '&specMultiple=' +
  338. JSON.stringify(this.form.specMultiple) +
  339. '&specGroup=' +
  340. JSON.stringify(this.form.specGroup)
  341. );
  342. }
  343. },
  344. openSel(key) {
  345. if (key === 'unit_show') {
  346. if (!this.master_unit) {
  347. this.$u.toast('请先选择基本单位');
  348. return;
  349. }
  350. } else if (key === 'cate_show') {
  351. this.$refs.tkitree._show();
  352. return;
  353. } else if (key === 'm_unit_show') {
  354. if (this.isEditSpec === 4) {
  355. return;
  356. }
  357. // 抄码商品主单位只能选择KG
  358. if (this.isEq) {
  359. this.unit_options = this.copy_unit_options.filter(item => item.unitName === 'KG');
  360. } else {
  361. this.unit_options = this.$u.deepClone(this.copy_unit_options);
  362. }
  363. } else if (key === 'fz_unit_show') {
  364. if (this.isEq) {
  365. this.unit_options = this.copy_unit_options.filter(item => item.unitName === '件');
  366. } else {
  367. this.unit_options = this.$u.deepClone(this.copy_unit_options);
  368. }
  369. }
  370. this[key] = true;
  371. },
  372. // 新增关键词确定
  373. tagConfirm() {
  374. this.tag_show = false;
  375. this.form.tag.push(this.tag_key);
  376. this.tag_key = '';
  377. },
  378. deletTag(index) {
  379. this.form.tag.splice(index, 1);
  380. },
  381. deletShop(index) {
  382. this.no_sales_shop.splice(index, 1);
  383. },
  384. // 图片上传成功
  385. uploadSuccess(imgUrl) {
  386. this.form.images.push(imgUrl);
  387. },
  388. //移除图片
  389. imgRemove(arr) {
  390. this.form.images = arr;
  391. },
  392. // 获取所有商品分类
  393. getAllCategory() {
  394. this.$u.api
  395. .getAllCategory({
  396. enableStatus: 5
  397. })
  398. .then(res => {
  399. this.cate_list = res.data;
  400. });
  401. },
  402. reduceCate(list) {
  403. list.forEach(item => {
  404. if (!item.children) {
  405. item.children = [
  406. {
  407. id: '',
  408. title: '全部'
  409. }
  410. ];
  411. } else {
  412. item.children = this.reduceCate(item.children);
  413. }
  414. });
  415. return list;
  416. },
  417. getAllUnit() {
  418. this.$u.api
  419. .getAllUnit({
  420. page: 1,
  421. pageSize: 99
  422. })
  423. .then(res => {
  424. // 备份一份单位数据
  425. this.copy_unit_options = this.$u.deepClone(res.data);
  426. this.unit_options = res.data;
  427. });
  428. },
  429. unitPopSelConfirm(arr) {
  430. if (arr[0].label === this.master_unit) {
  431. this.$u.toast('辅助单位不能与基本单位用同一个');
  432. return;
  433. }
  434. const index = this.form.unitData.findIndex(item => item.unitName === arr[0].label);
  435. if (index > -1) {
  436. this.$u.toast('该单位已被选择');
  437. return;
  438. }
  439. this.pop_unit_obj = arr[0];
  440. },
  441. unitPopConfirm() {
  442. if (!this.conversion) {
  443. this.$u.toast('请输入换算比例');
  444. return;
  445. }
  446. this.unit_show = false;
  447. this.form.unitData.push({
  448. unitName: this.pop_unit_obj.label,
  449. isMaster: 4,
  450. unitId: this.pop_unit_obj.value,
  451. conversion: this.conversion,
  452. weight: '',
  453. isDefault: 4,
  454. barCode: ''
  455. });
  456. this.conversion = '';
  457. this.pop_unit_obj = {};
  458. },
  459. // 提交发布
  460. submit() {
  461. if (!this.form.images.length) {
  462. this.$u.toast('请至少选择一张商品图片');
  463. return;
  464. }
  465. if (!this.form.title) {
  466. this.$u.toast('请输入商品名称');
  467. return;
  468. }
  469. if (!this.form.categoryId) {
  470. this.$u.toast('请选择商品分类');
  471. return;
  472. }
  473. if (!this.form.unitData.length) {
  474. this.$u.toast('请选择基本单位');
  475. return;
  476. }
  477. // 做延迟处理是为了获取富文本框中的值
  478. setTimeout(() => {
  479. if (this.no_sales_shop.length) {
  480. this.form.noSalesShop = this.no_sales_shop.map(item => item.id).join(',');
  481. }
  482. if (this.goods_id) {
  483. this.$u.api
  484. .editGoodsBasic(this.goods_id, {
  485. ...this.form,
  486. tag: this.form.tag ? this.form.tag.join(',') : '',
  487. specMultiple: this.form.specType === 1 ? [] : this.form.specMultiple,
  488. specGroup: this.form.specType === 1 ? [] : this.form.specGroup
  489. })
  490. .then(res => {
  491. this.$u.toast('修改成功');
  492. uni.navigateBack();
  493. });
  494. } else {
  495. this.$u.api.addGoodsBasic({ ...this.form, tag: this.form.tag ? this.form.tag.join(',') : '' }).then(res => {
  496. this.$u.toast('新增成功');
  497. uni.navigateBack();
  498. });
  499. }
  500. }, 200);
  501. }
  502. }
  503. };
  504. </script>
  505. <style scoped lang="scss">
  506. .add-goods {
  507. padding-bottom: 120rpx;
  508. .form-title {
  509. line-height: 90rpx;
  510. font-weight: 700;
  511. padding: 0 24rpx;
  512. }
  513. .form-cont {
  514. padding: 0 24rpx;
  515. background-color: #ffffff;
  516. .form-value {
  517. text-align: right;
  518. width: 100%;
  519. }
  520. .top-value {
  521. text-align: left;
  522. width: 100%;
  523. }
  524. .form-main {
  525. text-align: right;
  526. .input-pl {
  527. color: #c0c4cc;
  528. font-size: 28rpx;
  529. }
  530. }
  531. }
  532. }
  533. .pop-model {
  534. padding: 0 30rpx 20rpx;
  535. text-align: center;
  536. input {
  537. border: 1px solid #f5f5f5;
  538. line-height: 70rpx;
  539. height: 70rpx;
  540. margin-bottom: 20rpx;
  541. }
  542. .pop-tit {
  543. line-height: 70rpx;
  544. }
  545. .confirm-btn {
  546. width: 80%;
  547. display: block;
  548. background-color: $uni-color-primary;
  549. text-align: center;
  550. color: #ffffff;
  551. line-height: 70rpx;
  552. height: 70rpx;
  553. border-radius: 10rpx;
  554. margin: 0 auto;
  555. }
  556. .unit-model-main {
  557. margin-bottom: 30rpx;
  558. margin-top: 10rpx;
  559. width: 600rpx;
  560. line-height: 70rpx;
  561. input {
  562. display: inline-block;
  563. vertical-align: middle;
  564. width: 200rpx;
  565. margin: 0 10rpx;
  566. }
  567. .sel-view {
  568. margin: 0 10rpx;
  569. display: inline-block;
  570. vertical-align: middle;
  571. width: 200rpx;
  572. height: 70rpx;
  573. border: 1px solid #f5f5f5;
  574. }
  575. }
  576. }
  577. .tag-li {
  578. margin-right: 20rpx;
  579. }
  580. </style>