choosePriceProductsModal.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493
  1. <template>
  2. <a-modal
  3. centered
  4. class="choosePosPriceProducts-modal"
  5. :footer="null"
  6. :maskClosable="false"
  7. title="选择产品"
  8. v-model="isShow"
  9. @cancel="isShow=false"
  10. :width="900">
  11. <div class="table-operator">
  12. <a-button v-if="!(ruleType=='PROMO_PROD') && !((ruleType=='ADD_PRICE_PURCH') && (goodsType == 'promo'))" id="choosePosPriceProducts-brand" type="primary" class="button-error" @click="choosePModal('BRAND')">选择产品品牌</a-button>
  13. <a-button v-if="!(ruleType=='PROMO_PROD') && !((ruleType=='ADD_PRICE_PURCH') && (goodsType == 'promo'))" id="choosePosPriceProducts-type" type="primary" class="button-info" @click="choosePModal('CATEGORY')">选择产品分类</a-button>
  14. <a-button id="choosePosPriceProducts-product" type="primary" class="button-success" @click="choosePModal('PRODUCT')">选择产品</a-button>
  15. </div>
  16. <!-- 参与产品 -->
  17. <div class="products-con">
  18. <!-- 标题栏 -->
  19. <div class="products-header">
  20. <div class="header-con">
  21. <div class="products-tit">
  22. 参与产品:
  23. <a-button id="choosePosPriceProducts-import" type="primary" class="button-info" @click="openGuideModal=true">导入产品</a-button>
  24. </div>
  25. <div class="products-operation" v-if="goodsType=='normal'">
  26. <a-row :gutter="15">
  27. <a-col :span="9">
  28. <a-select id="choosePosPriceProducts-orderGoodsUnit" v-model="orderGoodsUnit" placeholder="请选择" allowClear style="width: 100%;" >
  29. <a-select-option v-for="item in orderGoodsUnitData" :key="item.code" :value="item.code">{{ item.dispName }}</a-select-option>
  30. </a-select>
  31. </a-col>
  32. <a-col :span="10">
  33. <a-input-number
  34. v-if="orderGoodsUnit=='PROD_UNIT'"
  35. id="choosePosPriceProducts-orderGoodsQty"
  36. v-model="orderGoodsQty"
  37. :min="1"
  38. :max="99999999"
  39. :precision="0"
  40. style="width: 85%;margin-right: 5px;"
  41. placeholder="请输入限制数量(1~999999)"
  42. allowClear />
  43. </a-col>
  44. <a-col :span="5">
  45. <a-button id="choosePosPriceProducts-import" type="primary" class="button-info" @click="handlerBulkCopy">批量复制</a-button>
  46. </a-col>
  47. </a-row>
  48. </div>
  49. </div>
  50. <p><a-icon type="exclamation-circle" style="color: #f90;margin-right: 5px;" />提示:导入时会清空下方已选内容,只展示导出成功的产品,请谨慎使用。</p>
  51. </div>
  52. <!-- 表格 -->
  53. <a-table
  54. class="sTable"
  55. ref="table"
  56. size="small"
  57. :rowKey="(record, index) => index"
  58. :columns="nowColumns"
  59. :dataSource="loadData"
  60. :scroll="{ x: goodsType == 'normal' ? 1090 : null, y: 500 }"
  61. :pagination="false"
  62. bordered>
  63. <!-- 序号 -->
  64. <template slot="no" slot-scope="text, record, index">
  65. {{ index+1 }}
  66. </template>
  67. <!-- 起订量限制 -->
  68. <template slot="orderGoodsUnit" slot-scope="text, record">
  69. <a-select id="choosePosPriceProducts-orderGoodsUnit" size="small" v-model="record.orderGoodsUnit" placeholder="请选择" allowClear style="width: 40%;" >
  70. <a-select-option v-for="item in orderGoodsUnitData" :key="item.code" :value="item.code">{{ item.dispName }}</a-select-option>
  71. </a-select>
  72. <a-input-number
  73. size="small"
  74. v-if="record.orderGoodsUnit=='PROD_UNIT'"
  75. id="choosePosPriceProducts-orderGoodsQty"
  76. v-model="record.orderGoodsQty"
  77. :precision="0"
  78. :min="1"
  79. :max="99999999"
  80. placeholder="请输入限制数量(1~999999)"
  81. style="width: 50%;margin-left: 5px;" />
  82. </template>
  83. <!-- 特惠单价 / 换购单价 -->
  84. <template slot="goodsPrice" slot-scope="text, record">
  85. <a-input-number
  86. size="small"
  87. id="choosePosPriceProducts-goodsPrice"
  88. v-model="record.goodsPrice"
  89. :precision="2"
  90. :min="0.1"
  91. :max="99999999"
  92. placeholder="请输入限制数量(0.1~999999)"
  93. style="width: 100%;" />
  94. </template>
  95. <!-- 操作 -->
  96. <template slot="action" slot-scope="text, record, index">
  97. <a-button size="small" type="primary" class="button-error" @click="handleDel(record, index)" id="choosePosPriceProducts-del-btn">删除</a-button>
  98. </template>
  99. </a-table>
  100. <!-- 按钮 -->
  101. <div class="btn-con">
  102. <a-button
  103. type="primary"
  104. id="choosePosPriceProducts-submit"
  105. size="large"
  106. class="button-primary"
  107. @click="handleSave"
  108. style="padding: 0 60px;">保存</a-button>
  109. <a-button
  110. id="choosePosPriceProducts-cancel"
  111. size="large"
  112. class="button-cancel"
  113. @click="isShow=false"
  114. style="padding: 0 60px;margin-left: 15px;">取消</a-button>
  115. </div>
  116. </div>
  117. <!-- 选择产品品牌 -->
  118. <chooseBrandModal :openModal="openBrandModal" :chooseData="chooseBrand" @close="openBrandModal=false" @ok="handleBrandOk" />
  119. <!-- 选择产品分类 -->
  120. <chooseTypeModal :openModal="openTypeModal" :chooseData="chooseType" type="promo" @close="openTypeModal=false" @ok="handleTypeOk" />
  121. <!-- 选择产品 -->
  122. <chooseProductsModal :openModal="openProductsModal" :chooseData="chooseProducts" @close="openProductsModal=false" @ok="handleProductsOk" />
  123. <!-- 导入产品 -->
  124. <importGuideModal :openModal="openGuideModal" type="promo" :params="importParams" @close="openGuideModal=false" @ok="hanldeOk" />
  125. </a-modal>
  126. </template>
  127. <script>
  128. import ChooseProductsModal from '@/views/common/chooseProductsModal.vue'
  129. import ChooseBrandModal from '@/views/common/chooseBrandModal.vue'
  130. import ChooseTypeModal from '@/views/common/chooseTypeModal.vue'
  131. import ImportGuideModal from './importGuideModal.vue'
  132. import { VSelect } from '@/components'
  133. import { getLookUpData } from '@/api/data'
  134. export default {
  135. name: 'ChoosePriceProductsModal',
  136. components: { VSelect, ChooseProductsModal, ChooseBrandModal, ChooseTypeModal, ImportGuideModal },
  137. props: {
  138. openModal: { // 弹框显示状态
  139. type: Boolean,
  140. default: false
  141. },
  142. ruleType: { // 买产品送产品...
  143. type: String,
  144. default: ''
  145. },
  146. goodsType: { // 正价/促销
  147. type: String,
  148. default: ''
  149. },
  150. nowData: {
  151. type: Array,
  152. default: () => {
  153. return []
  154. }
  155. }
  156. },
  157. data () {
  158. return {
  159. isShow: this.openModal, // 是否打开弹框
  160. orderGoodsUnit: undefined, // 起订量限制 批量
  161. orderGoodsQty: '', // 限制数量
  162. // 表头
  163. columns: [ // 正品
  164. { title: '序号', scopedSlots: { customRender: 'no' }, width: 70, align: 'center' },
  165. { title: '类型', dataIndex: 'goodsTypeName', width: 100, align: 'center', customRender: function (text) { return text || '--' } },
  166. { title: '类型名称', dataIndex: 'goodsName', width: 180, align: 'center', customRender: function (text) { return text || '--' }, ellipsis: true },
  167. { title: '产品名称', dataIndex: 'name', align: 'center', customRender: function (text) { return text || '--' }, ellipsis: true },
  168. { title: '产品编码', dataIndex: 'goodsCode', width: 180, align: 'center', customRender: function (text) { return text || '--' } },
  169. { title: '起订量限制', scopedSlots: { customRender: 'orderGoodsUnit' }, width: 300, align: 'center' },
  170. { title: '操作', scopedSlots: { customRender: 'action' }, width: 80, align: 'center', fixed: 'right' }
  171. ],
  172. promoColumns: [ // 促销品
  173. { title: '序号', scopedSlots: { customRender: 'no' }, width: 70, align: 'center' },
  174. { title: '类型', dataIndex: 'goodsTypeName', width: 100, align: 'center', customRender: function (text) { return text || '--' } },
  175. { title: '类型名称', dataIndex: 'goodsName', width: 180, align: 'center', customRender: function (text) { return text || '--' }, ellipsis: true },
  176. { title: '产品名称', dataIndex: 'name', align: 'center', customRender: function (text) { return text || '--' }, ellipsis: true },
  177. { title: '产品编码', dataIndex: 'goodsCode', width: 180, align: 'center', customRender: function (text) { return text || '--' } },
  178. { title: '操作', scopedSlots: { customRender: 'action' }, width: 80, align: 'center', fixed: 'right' }
  179. ],
  180. promoSpecialColumns: [ // 特价产品/加价促销品
  181. { title: '序号', scopedSlots: { customRender: 'no' }, width: 70, align: 'center' },
  182. { title: '产品名称', dataIndex: 'name', align: 'center', customRender: function (text) { return text || '--' }, ellipsis: true },
  183. { title: '产品编码', dataIndex: 'goodsCode', width: 180, align: 'center', customRender: function (text) { return text || '--' } },
  184. { title: this.ruleType == 'PROMO_PROD' ? '特惠单价(¥)' : '换购单价(¥)', scopedSlots: { customRender: 'goodsPrice' }, width: 180, align: 'center' },
  185. { title: '操作', scopedSlots: { customRender: 'action' }, width: 80, align: 'center', fixed: 'right' }
  186. ],
  187. loadData: [],
  188. openBrandModal: false, // 选择产品品牌
  189. openTypeModal: false, // 选择产品分类
  190. openProductsModal: false, // 选择产品
  191. openGuideModal: false, // 导入产品引导
  192. chooseBrand: [], // 所选品牌
  193. chooseProducts: [], // 所选产品
  194. chooseType: [], // 所选分类
  195. chooseImport: [], // 导入产品
  196. orderGoodsUnitData: []
  197. }
  198. },
  199. computed: {
  200. nowColumns () {
  201. let columns = this.columns
  202. if ((this.ruleType == 'BUY_PROD_GIVE_PROD') || (this.ruleType == 'BUY_PROD_GIVE_MONEY')) { // 买产品送产品/买产品送采购额
  203. if (this.goodsType == 'normal') { // 正品
  204. columns = this.columns
  205. } else if (this.goodsType == 'promo') { // 促销
  206. columns = this.promoColumns
  207. }
  208. } else if (this.ruleType == 'PROMO_PROD') { // 特价产品
  209. if (this.goodsType == 'promo') { // 促销
  210. columns = this.promoSpecialColumns
  211. }
  212. } else if (this.ruleType == 'ADD_PRICE_PURCH') { // 加价换购
  213. if (this.goodsType == 'normal') { // 正品
  214. columns = this.columns
  215. } else if (this.goodsType == 'promo') { // 促销
  216. columns = this.promoSpecialColumns
  217. }
  218. }
  219. return columns
  220. },
  221. importParams () {
  222. const obj = {
  223. promoRuleType: this.ruleType,
  224. promoGoodsType: ''
  225. }
  226. if (this.goodsType == 'normal') { // 正品
  227. obj.promoGoodsType = 'NORMAL_PROD'
  228. } else if (this.goodsType == 'promo') { // 促销
  229. obj.promoGoodsType = 'PROMO_PROD'
  230. }
  231. return obj
  232. }
  233. },
  234. methods: {
  235. // 选择产品
  236. choosePModal (type) {
  237. const productList = []
  238. const brandList = []
  239. const typeList = []
  240. const importSnList = []
  241. this.chooseImport.map(item => {
  242. importSnList.push(item.goodsSn)
  243. })
  244. this.loadData.map(item => {
  245. if (item.goodsType == 'PRODUCT' && importSnList.indexOf(item.goodsSn) == -1) {
  246. productList.push(item)
  247. } else if (item.goodsType == 'BRAND') {
  248. brandList.push(item)
  249. } else if (item.goodsType == 'CATEGORY') {
  250. typeList.push(item)
  251. }
  252. })
  253. if (type == 'PRODUCT') { // 选择产品
  254. this.chooseProducts = productList
  255. this.openProductsModal = true
  256. } else if (type == 'BRAND') { // 选择品牌
  257. this.chooseBrand = brandList
  258. this.openBrandModal = true
  259. } else if (type == 'CATEGORY') { // 选择分类
  260. this.chooseType = typeList
  261. this.openTypeModal = true
  262. }
  263. },
  264. // 导入产品
  265. hanldeOk (obj) {
  266. console.log('----------处理导入产品', obj)
  267. const _this = this
  268. _this.loadData = []
  269. if (obj && obj.length > 0) {
  270. obj.map(item => {
  271. _this.loadData.push({
  272. goodsType: 'PRODUCT',
  273. goodsTypeName: '产品',
  274. goodsName: item.goodsName,
  275. name: item.goodsName,
  276. goodsCode: item.goodsCode,
  277. goodsSn: item.goodsSn,
  278. goodsPrice: item.goodsPrice,
  279. orderGoodsUnit: item.orderGoodsUnit,
  280. orderGoodsQty: item.orderGoodsQty
  281. })
  282. })
  283. }
  284. _this.chooseImport = JSON.parse(JSON.stringify(_this.loadData))
  285. },
  286. // 品牌
  287. handleBrandOk (obj) {
  288. this.chooseBrand = obj
  289. this.changeData()
  290. },
  291. // 产品
  292. handleProductsOk (obj) {
  293. this.chooseProducts = obj
  294. this.changeData()
  295. },
  296. // 分类
  297. handleTypeOk (obj) {
  298. this.chooseType = obj
  299. this.changeData()
  300. },
  301. // 保存
  302. handleSave () {
  303. const _this = this
  304. const arr = []
  305. if (this.goodsType == 'normal') { // 正品
  306. _this.loadData.map((item, index) => {
  307. if ((item.orderGoodsUnit == 'PROD_UNIT') && (!item.orderGoodsQty)) {
  308. arr.push(index)
  309. }
  310. })
  311. if (arr.length > 0) {
  312. this.$message.warning('请完善起订量限制后再保存!')
  313. return
  314. }
  315. } else if (this.goodsType == 'promo') { // 促销
  316. let num = 0
  317. if ((this.ruleType == 'PROMO_PROD') || (this.ruleType == 'ADD_PRICE_PURCH')) { // 特价产品 / 加价换购
  318. _this.loadData.map((item, index) => {
  319. if (!item.goodsPrice) {
  320. num++
  321. }
  322. })
  323. if (num > 0) {
  324. this.$message.warning('存在未填写的内容,请填写完整后再提交!')
  325. return
  326. }
  327. }
  328. }
  329. this.$emit('ok', this.loadData)
  330. this.isShow = false
  331. },
  332. changeData () {
  333. const _this = this
  334. _this.loadData = JSON.parse(JSON.stringify(_this.chooseImport))
  335. if (_this.chooseBrand.length > 0) {
  336. _this.chooseBrand.map(item => {
  337. const obj = {
  338. goodsType: 'BRAND',
  339. goodsTypeName: '品牌',
  340. goodsName: item.brandName,
  341. goodsSn: item.brandSn,
  342. orderGoodsUnit: undefined,
  343. orderGoodsQty: ''
  344. }
  345. delete item.id
  346. _this.loadData.push(Object.assign(obj, item))
  347. })
  348. }
  349. if (_this.chooseType.length > 0) {
  350. _this.chooseType.map(item => {
  351. const obj = {
  352. goodsType: 'CATEGORY',
  353. goodsTypeName: '分类',
  354. goodsName: item.productTypeName,
  355. goodsSn: item.productTypeSn,
  356. orderGoodsUnit: undefined,
  357. orderGoodsQty: ''
  358. }
  359. delete item.id
  360. // _this.loadData.push(Object.assign(obj, item))
  361. _this.loadData.push({ ...obj, ...item })
  362. })
  363. }
  364. if (_this.chooseProducts.length > 0) {
  365. _this.chooseProducts.map(item => {
  366. const obj = {
  367. goodsType: 'PRODUCT',
  368. goodsTypeName: '产品',
  369. goodsName: item.name,
  370. name: item.name,
  371. goodsCode: item.code,
  372. goodsSn: item.productSn,
  373. orderGoodsUnit: undefined,
  374. orderGoodsQty: ''
  375. }
  376. delete item.id
  377. _this.loadData.push(Object.assign(obj, item))
  378. })
  379. }
  380. console.log(_this.loadData, '-----liebiao')
  381. console.log(_this.chooseImport, '-----导入')
  382. },
  383. // 批量复制
  384. handlerBulkCopy () {
  385. const _this = this
  386. if ((!this.orderGoodsUnit) || ((this.orderGoodsUnit == 'PROD_UNIT') && !this.orderGoodsQty)) {
  387. this.$message.warning('请选择需要批量复制的选项值后再操作!')
  388. return
  389. }
  390. if (this.loadData.length == 0) {
  391. this.$message.warning('请先添加产品后再批量复制起订限制规则!')
  392. return
  393. }
  394. this.$confirm({
  395. title: '提示',
  396. content: '批量复制会覆盖原单独设置的规则,确定要批量复制吗?',
  397. centered: true,
  398. onOk () {
  399. _this.loadData.map(item => {
  400. item.orderGoodsUnit = _this.orderGoodsUnit
  401. item.orderGoodsQty = _this.orderGoodsQty
  402. })
  403. }
  404. })
  405. },
  406. // 删除
  407. handleDel (record, ind) {
  408. this.loadData.splice(ind, 1)
  409. },
  410. // 起订量限制 数据字典 (避免多次请求同一数据字典)
  411. getOrderGoodsUnitList () {
  412. const _this = this
  413. getLookUpData({
  414. pageNo: 1,
  415. pageSize: 1000,
  416. lookupCode: 'ORDER_GOODS_UNIT'
  417. }).then(res => {
  418. if (res.status == 200) {
  419. _this.orderGoodsUnitData = res.data.list
  420. } else {
  421. _this.orderGoodsUnitData = []
  422. }
  423. })
  424. }
  425. },
  426. watch: {
  427. // 父页面传过来的弹框状态
  428. openModal (newValue, oldValue) {
  429. this.isShow = newValue
  430. },
  431. // 重定义的弹框状态
  432. isShow (newValue, oldValue) {
  433. if (!newValue) {
  434. this.chooseBrand = []
  435. this.chooseProducts = []
  436. this.chooseType = []
  437. this.chooseImport = []
  438. this.orderGoodsUnit = undefined // 起订量限制 批量
  439. this.orderGoodsQty = '' // 限制数量
  440. this.$emit('close')
  441. } else {
  442. if (this.orderGoodsUnitData.length == 0) {
  443. this.getOrderGoodsUnitList()
  444. }
  445. }
  446. },
  447. nowData: {
  448. handler (newValue, oldValue) {
  449. if (this.isShow && newValue) {
  450. this.loadData = newValue
  451. }
  452. },
  453. deep: true
  454. }
  455. }
  456. }
  457. </script>
  458. <style lang="less" scoped>
  459. .choosePosPriceProducts-modal{
  460. // 参与产品
  461. .products-con{
  462. .products-header{
  463. padding: 10px 15px;
  464. color: rgba(0,0,0,.85);
  465. background-color: #fafafa;
  466. border-radius: 6px;
  467. margin: 10px 0;
  468. .header-con{
  469. display: flex;
  470. justify-content: space-between;
  471. align-items: center;
  472. .products-operation{
  473. width: 50%;
  474. }
  475. }
  476. p{
  477. margin: 8px 0 0;
  478. color: #909399;
  479. font-size: 12px;
  480. }
  481. }
  482. .btn-con{
  483. text-align: center;
  484. margin: 30px 0 20px;
  485. .button-cancel{
  486. font-size: 12px;
  487. }
  488. }
  489. }
  490. }
  491. </style>