add.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561
  1. <template>
  2. <div class="app-container goods-add">
  3. <el-divider content-position="left">商品信息</el-divider>
  4. <el-form ref="addItem" :rules="rules" :model="addData" label-width="130px">
  5. <el-row :gutter="40" style="width: 500px">
  6. <el-col :span="23">
  7. <el-form-item label="商品类型:" prop="type">
  8. <el-radio-group v-model="addData.type" :disabled="addData.goodsId ? true : false" @input="typeChange">
  9. <el-radio :label="1">实物商品</el-radio>
  10. <el-radio :label="2">卡密商品</el-radio>
  11. <el-radio :label="3">采购商品</el-radio>
  12. </el-radio-group>
  13. </el-form-item>
  14. </el-col>
  15. </el-row>
  16. <el-row :gutter="40" style="width: 600px">
  17. <el-col :span="23">
  18. <el-form-item label="商品名称:" prop="title">
  19. <el-input v-model="addData.title" placeholder="请输入商品名称"/>
  20. </el-form-item>
  21. </el-col>
  22. <el-col :span="23">
  23. <el-form-item label="商品主图:" prop="picUrl">
  24. <Upload v-model="mainPicUrl" :limit="10"/>
  25. <div class="tip">第一张图片将作为商品列表图片,最多上传10张,多张图片之间可随意调整位置,支持jpg、png格式,推荐750*750px;</div>
  26. </el-form-item>
  27. </el-col>
  28. </el-row>
  29. <el-row :gutter="40" style="width: 500px">
  30. <el-col :span="23">
  31. <el-form-item label="支持盲豆兑换:" prop="exchangeShow">
  32. <!-- <el-switch-->
  33. <!-- v-model="addData.exchangeShow"-->
  34. <!-- :active-value="1"-->
  35. <!-- :inactive-value="0"-->
  36. <!-- />-->
  37. <!-- <div class="tip">关闭则不再兑换大厅显示,不支持盲豆兑换。</div>-->
  38. <el-radio-group v-model="addData.exchangeShow">
  39. <el-radio :label="0">不支持</el-radio>
  40. <el-radio :label="1" :disabled="addData.type == '3'">支持</el-radio>
  41. <el-radio :label="2" :disabled="addData.type == '3'">盲票商品</el-radio>
  42. </el-radio-group>
  43. </el-form-item>
  44. </el-col>
  45. </el-row>
  46. <el-row :gutter="40" style="width: 500px">
  47. <el-col :span="23">
  48. <el-form-item label="商品分类:" prop="categoryId">
  49. <el-cascader
  50. v-model="addData.categoryId" clearable
  51. :options="goodsCategoryItemsList"
  52. :props="{ expandTrigger: 'hover', value: 'categoryId',label: 'name', children: 'goodsCategoryList', }"></el-cascader>
  53. </el-form-item>
  54. </el-col>
  55. </el-row>
  56. <el-row :gutter="40" style="width: 500px">
  57. <el-col :span="23">
  58. <el-form-item label="供应商:" prop="supplierId">
  59. <el-select
  60. v-model="addData.supplierId"
  61. placeholder="请选择供应商"
  62. filterable
  63. clearable
  64. >
  65. <el-option :label="item.name" :value="item.id" v-for="(item, index) in SupplierList" :key="index"/>
  66. </el-select>
  67. <a style="margin-left: 20px;color: #1890FF;" @click="handleAdd">添加供应商</a>
  68. </el-form-item>
  69. </el-col>
  70. </el-row>
  71. <el-row :gutter="40" style="width: 600px" v-if="addData.type == '3'">
  72. <el-col :span="23">
  73. <el-form-item label="关联采购优惠券:" prop="refId">
  74. <el-select
  75. v-model="addData.refId" :disabled="addData.goodsId ? true : false"
  76. placeholder="请选择采购优惠券"
  77. filterable
  78. clearable>
  79. <el-option :label="item.title" :value="item.couponId" v-for="(item, index) in CouponList" :key="index">
  80. <div>
  81. <span style="float: left; width: 130px; overflow: hidden; text-overflow: ellipsis;">{{ item.title }} </span>
  82. <span style="float: left; width: 110px; overflow: hidden; text-overflow: ellipsis;">¥{{ $numberFormat(item.discount) }}</span>
  83. <span style="float: right;">{{ item.channelSharedRate }}%</span>
  84. </div>
  85. </el-option>
  86. </el-select>
  87. <div class="tip">根据优惠券名称查询(优惠券名称--价格--门店承担比例)</div>
  88. </el-form-item>
  89. </el-col>
  90. </el-row>
  91. <el-row :gutter="40" style="width: 500px">
  92. <el-col :span="23">
  93. <el-form-item label="商品采购链接:">
  94. <el-input v-model="addData.shoppingLink" placeholder="请输入商品采购链接"/>
  95. </el-form-item>
  96. </el-col>
  97. </el-row>
  98. <el-row :gutter="40" style="width: 500px">
  99. <el-col :span="23">
  100. <el-form-item label="商品标签:">
  101. <el-select
  102. v-model="addData.tagIds"
  103. placeholder="请选择商品标签"
  104. multiple
  105. clearable
  106. >
  107. <el-option :label="item.name" :value="item.tagId" v-for="(item, index) in goodsTagItemsList"
  108. :key="index"/>
  109. </el-select>
  110. </el-form-item>
  111. </el-col>
  112. <el-col :span="23">
  113. <el-form-item label="商家信息:">
  114. <Upload v-model="MerchantInformation" :limit="10"/>
  115. <div class="tip">上传商家营业执照</div>
  116. </el-form-item>
  117. </el-col>
  118. </el-row>
  119. <el-divider content-position="left">价格库存</el-divider>
  120. <el-row>
  121. <el-col :span="23">
  122. <el-form-item label="启用多SKU:" v-if="addData.type == '1' || addData.type == '3'">
  123. <el-switch
  124. v-model="addData.multiSku"
  125. :active-value="1"
  126. :inactive-value="0"
  127. />
  128. </el-form-item>
  129. </el-col>
  130. </el-row>
  131. <el-row>
  132. <el-col :span="22" v-if="addData.type != 3">
  133. <el-form-item prop="skuList">
  134. <Spec ref="spec" @valid="update" :multiSku="addData.multiSku"/>
  135. </el-form-item>
  136. </el-col>
  137. <el-col :span="22" v-else>
  138. <el-form-item prop="skuList">
  139. <SpeTwo ref="spec" @valid="update" :multiSku="addData.multiSku"/>
  140. </el-form-item>
  141. </el-col>
  142. </el-row>
  143. <el-row v-if="addData.multiSku === 0" :gutter="40" style="width: 600px">
  144. <el-col :span="23">
  145. <el-form-item label="价格:" prop="value">
  146. <el-input v-model="addData.value" type="number" placeholder="请输入商品价格">
  147. <template slot="append">元</template>
  148. </el-input>
  149. </el-form-item>
  150. </el-col>
  151. <el-col :span="23">
  152. <el-form-item label="采购成本:" prop="purchaseCost" v-if="addData.type == '3'">
  153. <el-input v-model="addData.purchaseCost" type="number" placeholder="请输入采购成本">
  154. <template slot="append">元</template>
  155. </el-input>
  156. <div class="tip">注:指展示给经销商采购的成本,即商品的结算价格</div>
  157. </el-form-item>
  158. </el-col>
  159. <el-col :span="23">
  160. <el-form-item label="零售价:" prop="purchasePrice" v-if="addData.type == '3'">
  161. <el-input v-model="addData.purchasePrice" type="number" placeholder="请输入零售价">
  162. <template slot="append">元</template>
  163. </el-input>
  164. <div class="tip">注:指商品铺设给经销商的价格,仅作记录</div>
  165. </el-form-item>
  166. </el-col>
  167. <el-col :span="23">
  168. <el-form-item label="盲豆兑换数量:" prop="exchangePrice">
  169. <el-input v-model="addData.exchangePrice" type="number" placeholder="请输入盲豆数量">
  170. <template slot="append">盲豆</template>
  171. </el-input>
  172. </el-form-item>
  173. </el-col>
  174. <el-col :span="23">
  175. <el-form-item label="回收折扣:" prop="discountRate">
  176. <el-input v-model="addData.discountRate" type="number" placeholder="请输入回收折扣">
  177. <template slot="append">%</template>
  178. </el-input>
  179. </el-form-item>
  180. </el-col>
  181. <el-col :span="23">
  182. <el-form-item label="盲豆划线价:">
  183. <el-input v-model="addData.originPrice" type="number" placeholder="请输入盲豆数量">
  184. <template slot="append">盲豆</template>
  185. </el-input>
  186. </el-form-item>
  187. </el-col>
  188. <el-col :span="23">
  189. <el-form-item label="商品成本:" prop="cost">
  190. <el-input v-model="addData.cost" type="number" placeholder="请输入商品成本">
  191. <template slot="append">元</template>
  192. </el-input>
  193. </el-form-item>
  194. </el-col>
  195. <el-col :span="23">
  196. <el-form-item label="商品编码:" prop="goodsCode">
  197. <el-input v-model="addData.goodsCode" type="text" placeholder="请输入商品编码">
  198. </el-input>
  199. </el-form-item>
  200. </el-col>
  201. <el-col :span="23">
  202. <el-form-item label="库存:" prop="quantity" v-if="addData.type == '1' || addData.type == '3'">
  203. <el-input v-model="addData.quantity" type="number" placeholder="请输入商品库存">
  204. <template slot="append">件</template>
  205. </el-input>
  206. </el-form-item>
  207. </el-col>
  208. <el-col :span="23">
  209. <el-form-item label="卡密使用链接:" v-if="addData.type == '2'">
  210. <el-input v-model="addData.useLink" placeholder="请输入商品采购链接"/>
  211. </el-form-item>
  212. </el-col>
  213. </el-row>
  214. <!-- <el-divider content-position="left">商品详情</el-divider> -->
  215. <el-row>
  216. <el-col :span="22">
  217. <el-form-item label="商品详情" prop="description">
  218. <wang-editor ref="editor" v-model="addData.description"/>
  219. </el-form-item>
  220. </el-col>
  221. </el-row>
  222. </el-form>
  223. <br>
  224. <el-row>
  225. <el-col :span="24" style="text-align: center">
  226. <el-button type="info" @click="$router.replace('/goods/list')">取消</el-button>
  227. <el-button type="primary" @click="updateItem()">保存</el-button>
  228. </el-col>
  229. </el-row>
  230. <add-supplier
  231. v-if="createShow"
  232. :dialog-show="createShow"
  233. @close="close"
  234. />
  235. </div>
  236. </template>
  237. <script>
  238. import Upload from '@/components/DragImageUpload'
  239. import WangEditor from '@/components/WangEditor'
  240. import Spec from './components/spec'
  241. import SpeTwo from './components/spec2'
  242. import TinyEditor from '@/components/TinyEditor'
  243. import {getGoodsDetail, addGoods} from '@/api/business/goods'
  244. import {getCouponAllList} from '@/api/business/coupon'
  245. import {goodsCategoryListTree} from '@/api/business/category'
  246. import {getSupplierList} from '@/api/business/supplier'
  247. import {goodsTagItems} from '@/api/business/tag'
  248. import {publicFileGetUrl} from "@/api/common"
  249. import {accDiv, accMul} from '@/utils/util'
  250. import AddSupplier from "../supplier/components/addSupplier";
  251. export default {
  252. name: 'GoodsAdd',
  253. components: {
  254. TinyEditor,
  255. WangEditor,
  256. Upload,
  257. Spec,
  258. SpeTwo,
  259. AddSupplier,
  260. },
  261. data() {
  262. return {
  263. IMG_URL: publicFileGetUrl,
  264. id: this.$route.query.id,
  265. goodsCategoryItemsList: [],
  266. SupplierList: [],
  267. CouponList: [],
  268. goodsTagItemsList: [],
  269. addData: {
  270. type: 1,
  271. multiSku: 0,
  272. description: '',
  273. originPrice: 0,
  274. exchangeShow: 0,
  275. },
  276. createShow: false,
  277. rules: {
  278. title: [{required: true, message: '请输入商品名称', trigger: 'blur'}],
  279. picUrl: [{required: true, message: '请上传商品图片', trigger: 'change'}],
  280. categoryId: [{required: true, message: '请选择商品分类', trigger: 'change'}],
  281. supplierId: [{required: true, message: '请选择供应商', trigger: 'change'}],
  282. exchangeShow: [{required: true, message: '请选择是否支持盲豆兑换', trigger: 'change'}],
  283. multiSku: [{required: true, message: '请选择SKU类型', trigger: 'change'}],
  284. refId: [{required: true, message: '请选择关联采购优惠券', trigger: 'change'}],
  285. value: [
  286. {required: true, message: '请输入商品价格', trigger: 'blur'},
  287. {
  288. pattern: /^([1-9]\d*(\.\d{1,2})?|([0](\.([0][1-9]|[1-9]\d{0,1}))))$/,
  289. message: "请输入正确的金额,最多两位小数",
  290. trigger: ["blur", "change"]
  291. }
  292. ],
  293. purchaseCost: [
  294. {required: true, message: '请输入采购成本', trigger: 'blur'},
  295. {
  296. pattern: /^([1-9]\d*(\.\d{1,2})?|([0](\.([0][1-9]|[1-9]\d{0,1}))))$/,
  297. message: "请输入正确的金额,最多两位小数",
  298. trigger: ["blur", "change"]
  299. }
  300. ],
  301. purchasePrice: [
  302. {required: true, message: '请输入零售价', trigger: 'blur'},
  303. {
  304. pattern: /^([1-9]\d*(\.\d{1,2})?|([0](\.([0][1-9]|[1-9]\d{0,1}))))$/,
  305. message: "请输入正确的金额,最多两位小数",
  306. trigger: ["blur", "change"]
  307. }
  308. ],
  309. exchangePrice: [
  310. {required: true, message: '请输入盲豆数量', trigger: 'blur'},
  311. {pattern: /^([1-9]\d*)$/, message: "请输入正确盲豆数量", trigger: ["blur", "change"]}
  312. ],
  313. discountRate: [
  314. {required: true, message: '请输入回收折扣', trigger: 'blur'},
  315. {
  316. pattern:
  317. /^([0-9]\d*(\.\d{1,2})?|([0](\.([0][1-9]|[1-9]\d{0,1}))))$/,
  318. message: "请输入合法的数字,最多两位小数",
  319. trigger: ["blur", "change"],
  320. },
  321. ],
  322. cost: [
  323. {required: false, message: '请输入商品成本', trigger: 'blur'},
  324. {
  325. pattern: /^([1-9]\d*(\.\d{1,2})?|([0](\.([0][1-9]|[1-9]\d{0,1}))))$/,
  326. message: "请输入正确的金额,最多两位小数",
  327. trigger: ["blur", "change"]
  328. }
  329. ],
  330. quantity: [
  331. {required: true, message: '请输入库存', trigger: 'blur'},
  332. {pattern: /^([1-9]\d*)$/, message: "请输入正确的数字", trigger: ["blur", "change"]}
  333. ],
  334. description: [{required: true, message: '请输入商品详情', trigger: 'blur'}]
  335. },
  336. }
  337. },
  338. computed: {
  339. mainPicUrl: {
  340. get() {
  341. return this.addData.picUrl ? this.addData.picUrl.split(',').map(item => {
  342. return {
  343. fileName: item
  344. }
  345. }) : []
  346. },
  347. set(val) {
  348. this.$set(this.addData, 'picUrl', val.map(item => {
  349. return item.fileName
  350. }).toString())
  351. }
  352. },
  353. MerchantInformation: {
  354. get() {
  355. return this.addData.merchantInfo ? this.addData.merchantInfo.split(',').map(item => {
  356. return {
  357. fileName: item
  358. }
  359. }) : []
  360. },
  361. set(val) {
  362. this.$set(this.addData, 'merchantInfo', val.map(item => {
  363. return item.fileName
  364. }).toString())
  365. }
  366. }
  367. },
  368. created() {
  369. this.getGoodsCategoryItems()
  370. this.getSupplierItems()
  371. this.getGoodsTagItems()
  372. this.getCouponList()
  373. if (this.id) {
  374. getGoodsDetail(this.id).then(res => {
  375. const {
  376. goodsId,
  377. title,
  378. type,
  379. goodsCode,
  380. picUrl,
  381. merchantInfo,
  382. exchangeShow,
  383. multiSku,
  384. value,
  385. refId,
  386. exchangePrice,
  387. purchaseCost,
  388. purchasePrice,
  389. originPrice,
  390. discountRate,
  391. cost,
  392. quantity,
  393. description,
  394. skuList,
  395. categoryId,
  396. supplierId,
  397. shoppingLink,
  398. tagIds,
  399. useLink
  400. } = res.data
  401. this.addData = {
  402. value: accDiv(value, 100),
  403. purchaseCost: type == '3' ? accDiv(purchaseCost, 100) : '',
  404. purchasePrice: type == '3' ? accDiv(purchasePrice, 100) : '',
  405. cost: cost == '' || cost == null ? '' : accDiv(cost, 100),
  406. goodsId,
  407. title,
  408. type,
  409. refId: refId ? Number(refId): '',
  410. goodsCode,
  411. picUrl,
  412. merchantInfo,
  413. exchangeShow,
  414. multiSku,
  415. exchangePrice,
  416. discountRate,
  417. originPrice,
  418. quantity,
  419. description,
  420. skuList,
  421. categoryId,
  422. supplierId,
  423. shoppingLink,
  424. tagIds,
  425. useLink
  426. }
  427. if (description) {
  428. this.$refs.editor.setContent(description)
  429. }
  430. if (multiSku && skuList instanceof Array && skuList.length > 0) {
  431. this.$nextTick(() => {
  432. this.$refs.spec.setSkuList(skuList)
  433. })
  434. }
  435. })
  436. }
  437. },
  438. methods: {
  439. typeChange(e) {
  440. if(e == 2) {
  441. this.addData.quantity = ''
  442. this.addData.multiSku = 0
  443. this.addData.purchaseCost = ''
  444. this.addData.purchasePrice = ''
  445. this.addData.refId = ''
  446. }else if(e == 1){
  447. this.addData.useLink = ''
  448. this.addData.purchaseCost = ''
  449. this.addData.purchasePrice = ''
  450. this.addData.refId = ''
  451. }else if(e == 3){
  452. this.addData.useLink = ''
  453. this.addData.exchangeShow = 0
  454. }
  455. },
  456. // 获取采购优惠券下拉列表
  457. getCouponList() {
  458. let data = {
  459. type: 4,
  460. status: "on",
  461. isExcludePurchaseCoupon: true,
  462. }
  463. if(this.addData.goodsId) {
  464. data.refId = this.addData.refId
  465. }
  466. getCouponAllList(data).then(response => {
  467. this.CouponList = response.rows || [];
  468. });
  469. },
  470. getGoodsCategoryItems() {
  471. goodsCategoryListTree("", {}).then(res => {
  472. this.goodsCategoryItemsList = res && res.rows
  473. })
  474. },
  475. //获取供应商
  476. getSupplierItems() {
  477. getSupplierList('', {name: ""}).then(res => {
  478. this.SupplierList = res && res.rows
  479. })
  480. },
  481. handleAdd() {
  482. this.createShow = true;
  483. },
  484. close() {
  485. this.createShow = false;
  486. this.getSupplierItems()
  487. },
  488. getGoodsTagItems() {
  489. goodsTagItems({}).then(res => {
  490. this.goodsTagItemsList = res && res.data
  491. })
  492. },
  493. updateItem() {
  494. if (this.addData.multiSku == 1) {
  495. this.$refs.spec.getSkuList()
  496. } else {
  497. this.update()
  498. }
  499. },
  500. update(skuList) {
  501. this.$refs.addItem.validate((valid, items) => {
  502. if (valid) {
  503. this.addData.skuList = skuList
  504. const {value, type, categoryId, purchaseCost, purchasePrice, cost, exchangePrice, description, ...rest} = this.addData
  505. addGoods({
  506. ...rest, ...{
  507. value: accMul(value, 100),
  508. purchaseCost: type == '3' ? accMul(purchaseCost, 100) : '',
  509. purchasePrice: type == '3' ? accMul(purchasePrice, 100) : '',
  510. cost: cost == '' || cost == null ? '' : accMul(cost, 100),
  511. exchangePrice: accMul(exchangePrice, 1),
  512. description: encodeURI(description),
  513. categoryId: categoryId[1],
  514. type,
  515. }
  516. }).then(res => {
  517. if (res.code === 0) {
  518. this.$message({
  519. message: this.addData.goodsId ? '修改成功!' : '添加成功!',
  520. type: 'success'
  521. })
  522. this.$store.dispatch('tagsView/delView', this.$route)
  523. this.$router.go(-1)
  524. }
  525. })
  526. } else {
  527. if (items && Object.keys(items).length > 0) {
  528. this.$message({
  529. message: items[Object.keys(items)[0]][0].message,
  530. type: 'warning'
  531. })
  532. }
  533. }
  534. })
  535. }
  536. }
  537. }
  538. </script>
  539. <style lang="scss">
  540. .goods-add {
  541. .tip {
  542. font-size: 12px;
  543. color: #999;
  544. }
  545. .el-divider {
  546. .is-left {
  547. color: #409EFF;
  548. font-size: 20px;
  549. font-weight: bolder;
  550. left: 10px;
  551. }
  552. }
  553. }
  554. </style>