scoreProdInfo.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500
  1. <template>
  2. <div class="mod-prod-info">
  3. <!-- <div class="title">新增积分商品</div> -->
  4. <el-form :model="dataForm" ref="dataForm" label-width="100px" size="small">
  5. <el-form-item label="商品类别">
  6. <el-radio-group v-model="dataForm.mold">
  7. <el-radio :label="0">实物商品</el-radio>
  8. <el-radio :label="1">虚拟商品</el-radio>
  9. </el-radio-group>
  10. </el-form-item>
  11. <el-form-item label="商品视频">
  12. <video-upload v-model="dataForm.video" />
  13. </el-form-item>
  14. <el-form-item label="商品图片"
  15. class="productImg-label"
  16. >
  17. <!-- <mul-pic-upload v-model="dataForm.imgs" /> -->
  18. <imgs-upload v-model="dataForm.imgs" />
  19. <span>建议图片尺寸为 800*800</span>
  20. </el-form-item>
  21. <score-sku-tag ref="skuTag" @change="skuTagChangeSkuHandler" :skuList="dataForm.skuList"></score-sku-tag>
  22. <score-sku-table
  23. ref="skuTable"
  24. v-model="dataForm.skuList"
  25. :prodNameCn.sync="prodNameCn"
  26. :prodNameEn.sync="prodNameEn"
  27. ></score-sku-table>
  28. <prod-transport
  29. v-model="dataForm.deliveryTemplateId"
  30. ></prod-transport>
  31. <el-tabs type="card">
  32. <el-tab-pane label="中文信息">
  33. <el-form-item label="产品名称" prop="prodNameCn">
  34. <!-- :rules="[{ required: true, message: '产品名称不能为空'}]" -->
  35. <el-col :span="8">
  36. <el-input
  37. v-model="prodNameCn"
  38. placeholder="产品名称"
  39. maxlength="50"
  40. ></el-input>
  41. </el-col>
  42. </el-form-item>
  43. <el-form-item label="商品卖点" prop="briefCn">
  44. <el-col :span="8">
  45. <el-input
  46. v-model="briefCn"
  47. type="textarea"
  48. :autosize="{minRows: 2, maxRows: 4}"
  49. placeholder="商品卖点"
  50. ></el-input>
  51. </el-col>
  52. </el-form-item>
  53. <el-form-item :label="this.$i18n.t('homes.productDetails')" prop="contentCn">
  54. <tiny-mce v-model="contentCn" ref="content" style="width:95%"></tiny-mce>
  55. </el-form-item>
  56. </el-tab-pane>
  57. <el-tab-pane label="English Information">
  58. <el-form-item label="Prod name" prop="prodNameEn">
  59. <!-- :rules="[{ required: true, message: 'Product English name cannot be empty'}]" -->
  60. <el-col :span="8">
  61. <el-input v-model="prodNameEn" placeholder="Prod name" maxlength="50"></el-input>
  62. </el-col>
  63. </el-form-item>
  64. <el-form-item label="Selling point" prop="briefEn">
  65. <el-col :span="8">
  66. <el-input
  67. v-model="briefEn"
  68. type="textarea"
  69. :autosize="{minRows: 2, maxRows: 4}"
  70. placeholder="Selling point"
  71. ></el-input>
  72. </el-col>
  73. </el-form-item>
  74. <el-form-item label="Product Details" prop="contentEn">
  75. <tiny-mce v-model="contentEn" ref="content" style="width:95%"></tiny-mce>
  76. </el-form-item>
  77. </el-tab-pane>
  78. </el-tabs>
  79. <el-form-item>
  80. <div class="default-btn primary-btn" @click="dataFormSubmit()">{{$t("crud.filter.submitBtn")}}</div>
  81. </el-form-item>
  82. </el-form>
  83. <!-- 品牌选择弹窗-->
  84. <brand-select
  85. v-if="brandSelectVisible"
  86. ref="brandSelect"
  87. :isSingle="true"
  88. @refreshSelectBrand="selectBrand"
  89. ></brand-select>
  90. </div>
  91. </template>
  92. <script>
  93. import VideoUpload from '@/components/video-upload'
  94. import ScoreSkuTag from './score-sku-tag'
  95. import ScoreSkuTable from './score-sku-table'
  96. import TinyMce from '@/components/tiny-mce'
  97. import ImgUpload from '@/components/img-upload'
  98. import ImgsUpload from '@/components/imgs-upload'
  99. import BrandSelect from '@/components/brand-select'
  100. import ProdTransport from './prod-transport'
  101. export default {
  102. data () {
  103. return {
  104. brandSelectVisible: false,
  105. prodNameEn: '',
  106. prodNameCn: '',
  107. contentEn: '',
  108. contentCn: '',
  109. briefEn: '',
  110. briefCn: '',
  111. sameCityStatus: 0,
  112. // 规格列表
  113. dataForm: {
  114. prodName: '',
  115. brief: '',
  116. pic: '',
  117. imgs: '',
  118. video: '',
  119. categoryId: this.$route.query.categoryId ? parseInt(this.$route.query.categoryId) : null,
  120. shopCategoryId: null, // 店铺分类id
  121. prodId: 0,
  122. brandId: 0,
  123. prodScore: 0,
  124. scorePrice: 0,
  125. skuList: [],
  126. scoreProdType: 0,
  127. prodNameEn: '',
  128. prodNameCn: '',
  129. contentEn: '',
  130. contentCn: '',
  131. briefEn: '',
  132. briefCn: '',
  133. content: '',
  134. brandName: '',
  135. deliveryMode: {},
  136. isCheck: false,
  137. value: false,
  138. deliveryTemplateId: null,
  139. prodLangList: [],
  140. mold: 1
  141. },
  142. deliveryMode: {
  143. hasShopDelivery: true,
  144. hasUserPickUp: false,
  145. hasCityDelivery: false
  146. },
  147. brandName: '',
  148. isSubmit: false,
  149. resourcesUrl: process.env.VUE_APP_RESOURCES_URL
  150. }
  151. },
  152. watch: {
  153. 'dataForm.imgs': {
  154. deep: true, // 深度监听设置为 true
  155. immediate: true,
  156. handler (newV, oldV) {
  157. if (newV.split(',').length > 9) {
  158. this.dataForm.imgs = oldV
  159. this.errorMsg(this.$i18n.t('product.downloadTemplateTips3'))
  160. }
  161. }
  162. }
  163. },
  164. components: {
  165. // MulPicUpload,
  166. BrandSelect,
  167. ImgUpload,
  168. ImgsUpload,
  169. VideoUpload,
  170. TinyMce,
  171. ScoreSkuTag,
  172. ScoreSkuTable,
  173. ProdTransport
  174. },
  175. computed: {
  176. defalutSku () {
  177. return this.$store.state.prod.defalutSku
  178. }
  179. },
  180. mounted () {
  181. // console.log(2222222)
  182. this.dataForm.prodId = this.$route.query.prodId
  183. // this.getCategoryList()
  184. // this.getCategoryTree()
  185. this.getDataList()
  186. },
  187. methods: {
  188. // 获取分类数据
  189. getDataList () {
  190. this.isSubmit = false
  191. if (this.dataForm.prodId) {
  192. // 获取产品数据
  193. this.$http({
  194. url: this.$http.adornUrl(`/shop/scoreProduct/info/${this.dataForm.prodId}`),
  195. method: 'get',
  196. params: this.$http.adornParams()
  197. }).then(({ data }) => {
  198. this.dataForm = data
  199. this.dataForm.prodLangList.forEach(prodLang => {
  200. if (prodLang.lang === 0) {
  201. this.prodNameCn = prodLang.prodName
  202. this.briefCn = prodLang.brief
  203. this.contentCn = prodLang.content
  204. }
  205. if (prodLang.lang === 1) {
  206. this.prodNameEn = prodLang.prodName
  207. this.briefEn = prodLang.brief
  208. this.contentEn = prodLang.content
  209. }
  210. })
  211. this.dataForm.deliveryMode = JSON.parse(data.deliveryMode)
  212. this.dataForm.deliveryMode.hasShopDelivery = true
  213. // this.category.selected = idList(this.category.list, this.dataForm.categoryId, 'categoryId', 'children').reverse()
  214. if (data.brand) {
  215. this.dataForm.brandId = data.brand.brandId
  216. this.dataForm.brandName = data.brand.brandName
  217. this.brandName = data.brandName
  218. }
  219. this.$refs.skuTag.init(data.skuList)
  220. this.dataForm.skuList.forEach(sku => {
  221. sku.oriStock = sku.stocks
  222. sku.skuLangList.forEach(skulang => {
  223. if (skulang.lang === 0) {
  224. sku.prodNameCn = skulang.prodName
  225. } else {
  226. sku.prodNameEn = skulang.prodName
  227. }
  228. })
  229. })
  230. this.$refs.skuTable.init()
  231. this.dataForm.skuList.forEach(item => {
  232. item.changeStock = item.stocks
  233. })
  234. })
  235. } else {
  236. this.$nextTick(() => {
  237. this.$refs['dataForm'].resetFields()
  238. this.$refs.skuTag.init()
  239. this.dataForm.pic = ''
  240. this.dataForm.imgs = ''
  241. this.dataForm.video = ''
  242. })
  243. }
  244. },
  245. // 表单提交
  246. dataFormSubmit () {
  247. this.$refs['dataForm'].validate((valid) => {
  248. if (!this.dataForm.imgs) {
  249. this.errorMsg(this.$i18n.t('product.choosePicUpload'))
  250. return
  251. }
  252. if (!this.dataForm.skuList.find(el => el.status)) {
  253. // 至少要启用一种商品规格
  254. this.$message({
  255. message: this.$i18n.t('product.enableSpec'),
  256. type: 'error',
  257. duration: 500
  258. })
  259. return
  260. }
  261. // 检验是否有选择品牌
  262. // if (!this.dataForm.brandName) {
  263. // this.errorMsg('请选择一个所属品牌')
  264. // return
  265. // }
  266. // 校验sku列表
  267. this.checkSkuList()
  268. if (this.isCheck) {
  269. this.errorMsg(this.value)
  270. return
  271. }
  272. if (!this.prodNameCn) {
  273. this.errorMsg(this.$i18n.t('product.pleComAndEnName'))
  274. return
  275. }
  276. if (!this.prodNameEn) {
  277. this.prodNameEn = this.prodNameCn
  278. }
  279. if (/^\s+$/g.test(this.prodNameEn)) {
  280. this.prodNameEn = this.prodNameCn
  281. }
  282. if (/^\s+$/g.test(this.briefEn) || /^\s+$/g.test(this.briefCn)) {
  283. this.errorMsg(this.$i18n.t('shopProcess.inputAllSpace'))
  284. return
  285. }
  286. if (!this.dataForm.deliveryTemplateId) {
  287. this.errorMsg(this.$i18n.t('product.pleShgTlate'))
  288. return
  289. }
  290. this.dataForm.prodNameCn = this.prodNameCn
  291. this.dataForm.briefCn = this.briefCn
  292. this.dataForm.contentCn = this.contentCn
  293. this.dataForm.prodNameEn = this.prodNameEn
  294. this.dataForm.briefEn = this.briefEn
  295. this.dataForm.contentEn = this.contentEn
  296. this.dataForm.prodName = this.dataForm.prodNameCn
  297. let param = Object.assign({}, this.dataForm)
  298. // 设置价格和库存
  299. this.paramSetPriceAndStocks(param)
  300. param.deliveryMode = undefined
  301. param.deliveryModeVo = this.deliveryMode
  302. this.dataForm.skuList.forEach(item => {
  303. item.changeStock = item.stocks - item.oriStock
  304. })
  305. // 商品主图
  306. let newImgs = this.dataForm.imgs.split(',')
  307. for(let idx in newImgs){
  308. newImgs[idx] = newImgs[idx].split('?')[0]
  309. }
  310. this.dataForm.imgs = newImgs.join(',')
  311. param.pic = this.dataForm.imgs.split(',')[1]
  312. param.imgs = this.dataForm.imgs
  313. if (this.isSubmit) {
  314. return false
  315. }
  316. this.isSubmit = true
  317. this.$http({
  318. url: this.$http.adornUrl(`/shop/scoreProduct`),
  319. method: param.prodId ? 'put' : 'post',
  320. data: this.$http.adornData(param)
  321. }).then(({ data }) => {
  322. this.$message({
  323. message: this.$i18n.t('remindPop.success'),
  324. type: 'success',
  325. duration: 800,
  326. onClose: () => {
  327. this.visible = false
  328. this.$store.commit('common/removeMainActiveTab')
  329. this.$router.push({ name: 'prod-scoreProdList' })
  330. this.$emit('refreshDataList')
  331. }
  332. })
  333. }).catch((e) => {
  334. this.isSubmit = false
  335. })
  336. })
  337. },
  338. /**
  339. * 品牌删除按钮
  340. */
  341. handleClose () {
  342. this.dataForm.brandId = null
  343. this.brandName = ''
  344. this.dataForm.brandName = this.brandName
  345. },
  346. /**
  347. * 显示添加指定品牌弹框
  348. */
  349. brandSelectHandle () {
  350. this.brandSelectVisible = true
  351. this.$nextTick(() => {
  352. this.$refs.brandSelect.init()
  353. })
  354. },
  355. /**
  356. * 添加指定品牌
  357. */
  358. selectBrand (brands) {
  359. if (brands) {
  360. this.brandName = brands[0].brandName
  361. this.dataForm.brandId = brands[0].brandId
  362. this.dataForm.brandName = this.brandName
  363. // this.$set(this.dataForm, 'brandId', this.dataForm.brandId)
  364. // this.$set(this.dataForm, 'brandName', this.dataForm.brandName)
  365. }
  366. },
  367. /**
  368. * 删除视频
  369. */
  370. deleteVideo () {
  371. this.dataForm.video = null
  372. },
  373. checkSkuList () {
  374. // console.log('skuList', this.dataForm.skuList)
  375. this.dataForm.skuList.forEach(item => {
  376. this.isCheck = false
  377. // if (!item.pic) {
  378. // this.isCheck = true
  379. // this.value = '请上传sku图片'
  380. // return false
  381. // }
  382. if (!item.price && item.price !== 0) {
  383. this.isCheck = true
  384. this.value = this.$i18n.t('product.emptyPrice')
  385. return false
  386. }
  387. if (!item.oriPrice && item.oriPrice !== 0) {
  388. this.isCheck = true
  389. this.value = this.$i18n.t('product.emptyMarketValue')
  390. return false
  391. }
  392. if (!item.skuScore) {
  393. this.isCheck = true
  394. this.value = this.$i18n.t('product.emptyScorePrice')
  395. return false
  396. }
  397. if (item.stocks === null || item.stocks === undefined) {
  398. this.isCheck = true
  399. this.value = this.$i18n.t('product.emptyStocks')
  400. return false
  401. }
  402. })
  403. },
  404. paramSetPriceAndStocks (param) {
  405. // 获取规格属性信息
  406. // param.skuList = this.$refs.prodSpec.getTableSpecData()
  407. // 商品库存
  408. param.totalStocks = 0
  409. // 商品价格
  410. param.price = param.skuList[0].price
  411. // 商品原价
  412. param.oriPrice = 0
  413. // 商品积分价格
  414. param.scorePrice = param.skuList[0].skuScore
  415. // 商品实际库存
  416. for (let i = 0; i < param.skuList.length; i++) {
  417. const element = param.skuList[i]
  418. console.log('element.status', element.status)
  419. if (element.status !== 1) {
  420. console.log('end', param.totalStocks, element.stocks)
  421. continue
  422. }
  423. if (i === 0) {
  424. param.price = element.price ? Number.parseFloat(element.price) : 0
  425. param.scorePrice = element.skuScore ? Number.parseFloat(element.skuScore) : 0
  426. param.oriPrice = element.oriPrice ? Number.parseFloat(element.oriPrice) : 0
  427. }
  428. // 商品价格为最低价的那件商品的价格
  429. param.price = Math.min(param.price, element.price)
  430. if (param.price === element.price) {
  431. param.price = element.price
  432. }
  433. // 设置最低市场价
  434. param.oriPrice = Math.min(param.oriPrice, element.oriPrice)
  435. if (param.oriPrice === element.oriPrice) {
  436. param.oriPrice = element.oriPrice
  437. }
  438. // 设置最低积分价格
  439. param.scorePrice = Math.min(param.scorePrice, element.skuScore)
  440. if (param.scorePrice === element.skuScore) {
  441. param.scorePrice = element.skuScore
  442. }
  443. console.log(element.skuScore)
  444. console.log(param.scorePrice)
  445. param.totalStocks += element.stocks ? Number.parseInt(element.stocks) : 0
  446. }
  447. // 如果sku没有商品名称,则使用商品的商品名称
  448. if (param.skuList.length === 1 && !param.skuList[0].skuName) {
  449. param.skuList[0].prodNameCn = this.dataForm.prodNameCn
  450. param.skuList[0].prodNameEn = this.dataForm.prodNameEn
  451. }
  452. },
  453. skuTagChangeSkuHandler (skuList) {
  454. const prodNameCn = this.prodNameCn
  455. const prodNameEn = this.prodNameEn
  456. skuList.forEach(sku => {
  457. if (sku.properties) {
  458. sku.skuName = ''
  459. let properties = sku.properties.split(';')
  460. for (const propertiesKey in properties) {
  461. sku.skuName += properties[propertiesKey].split(':')[1] + ' '
  462. }
  463. sku.prodNameCn = prodNameCn + ' ' + sku.skuName
  464. sku.prodNameEn = prodNameEn + ' ' + sku.skuName
  465. }
  466. })
  467. this.dataForm.skuList = skuList
  468. },
  469. errorMsg (message) {
  470. this.$message({
  471. message: message,
  472. type: 'error',
  473. duration: 1500
  474. })
  475. }
  476. }
  477. }
  478. </script>
  479. <style>
  480. .el-upload--picture-card{
  481. background: #ffffff;
  482. }
  483. .productImg-label .el-form-item__label:before{
  484. content: '*';
  485. color: #F56C6C;
  486. margin-right: 4px;
  487. }
  488. .productImg-label .el-upload--picture-card i {
  489. position: absolute;
  490. top: 39%;
  491. left: 37%;
  492. }
  493. </style>