specialOfferModal.vue 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006
  1. <template>
  2. <a-modal
  3. centered
  4. class="promotionList-basicInfo-modal"
  5. :footer="null"
  6. :maskClosable="false"
  7. title="规则设置"
  8. v-model="isShow"
  9. @cancel="isShow=false"
  10. width="83%">
  11. <a-spin :spinning="spinning" tip="Loading...">
  12. <a-form-model
  13. id="promotionList-basicInfo-form"
  14. ref="ruleForm"
  15. :model="form"
  16. :rules="rules"
  17. :label-col="formItemLayout.labelCol"
  18. :wrapper-col="formItemLayout.wrapperCol" >
  19. <a-form-model-item label="规则简称" prop="description">
  20. <a-input
  21. size="small"
  22. id="promotionList-description"
  23. v-model.trim="form.description"
  24. allowClear
  25. placeholder="请输入规则简称(最多20个字符)"
  26. :maxLength="20"></a-input>
  27. </a-form-model-item>
  28. <a-form-model-item label="规则叠加">
  29. <v-select
  30. style="width:40%;"
  31. size="small"
  32. v-model="form.gateType"
  33. id="promotionList-gateType"
  34. code="FLAG"
  35. placeholder="请选择是否叠加规则"
  36. allowClear></v-select>
  37. <span>(销售单内的产品可同时参与多个叠加规则)</span>
  38. </a-form-model-item>
  39. <a-form-model-item label="规则门槛" prop="gateFlag">
  40. <div class="fixWidthBox">
  41. <a-radio-group id="promotionList-gateFlag" v-model="form.gateFlag" button-style="solid" size="small" @change="handleChange">
  42. <a-radio-button value="1" id="promotionList-gateFlag1">
  43. </a-radio-button>
  44. <a-radio-button value="0" id="promotionList-gateFlag0">
  45. </a-radio-button>
  46. </a-radio-group>
  47. </div>
  48. <div v-if="form.gateFlag && form.gateFlag === '1'">
  49. <v-select
  50. size="small"
  51. style="width:60%;"
  52. v-model="form.gateType"
  53. id="promotionList-gateType"
  54. code="PROMOTION_GATE_TYPE"
  55. placeholder="请选择门槛与配额设置要求"
  56. @change="changeGateTypeFlag"
  57. allowClear></v-select>
  58. <div v-if="form.gateType==='RATIO_AMOUNT'">
  59. 购买门槛产品金额 <a-input-number
  60. id="promotionList-gateValue"
  61. v-model="form.gateValue"
  62. :min="0"
  63. :max="99999999"
  64. :precision="2"
  65. size="small"/> %作为配额
  66. <a-tooltip title="如:填写100%,则购买10000元门槛产品,可享受10000配额购买特价产品,根据门槛金额动态调整配额">
  67. <a-icon type="question-circle" theme="filled" :style="{ fontSize: '14px', color: 'gray' }"/>
  68. </a-tooltip>
  69. </div>
  70. <div v-if="form.gateType==='MIN_AMOUNT'">
  71. 购买门槛产品满最低金额 <a-input-number
  72. id="promotionList-gateValue"
  73. v-model="form.gateValue"
  74. :min="0"
  75. :max="99999999"
  76. :precision="2"
  77. size="small"/>元,不限制配额。
  78. </div>
  79. <div class="ruleDescList" v-if="form.gateType==='FIXED_AMOUNT'">
  80. 购买每满
  81. <a-input-number
  82. v-model="form.gateValue"
  83. id="promotionList-gateValue"
  84. :max="99999999"
  85. :min="0"
  86. :precision="form.gateUnit=='YUAN'?2:0"
  87. size="small"/>
  88. <a-select
  89. default-value="GE"
  90. id="promotionList-gateUnit"
  91. v-model="form.gateUnit"
  92. style="width: 50px;margin-left:5px;"
  93. size="small"
  94. @change="handleUnit">
  95. <a-select-option value="GE" id="promotionList-gateUnit-ge">
  96. </a-select-option>
  97. <a-select-option value="YUAN" id="promotionList-gateUnit-yuan">
  98. </a-select-option>
  99. </a-select>
  100. 门槛产品,可采购
  101. <a-input-number
  102. v-model="form.quotaAmount"
  103. id="promotionList-quotaAmount"
  104. :max="99999999"
  105. :min="0"
  106. :precision="0"
  107. size="small"/>
  108. 个特价产品(配额算销售额)
  109. </div>
  110. </div>
  111. </a-form-model-item>
  112. <a-form-model-item label="产品累计">
  113. <v-select
  114. style="width:40%;margin-right:10px;"
  115. size="small"
  116. v-model="form.gateType"
  117. id="promotionList-gateType"
  118. code="FLAG"
  119. placeholder="请选择累计时间"
  120. allowClear></v-select>
  121. <a-checkbox id="promotionList-restrictFlag" :checked="form.restrictFlag === '1'" size="small" @change="onChange">
  122. 客户采购单显示转促标签
  123. </a-checkbox>
  124. </a-form-model-item>
  125. <a-form-model-item label="特价规则" prop="discountType">
  126. <a-select
  127. id="promotionList-discountType"
  128. default-value="0"
  129. v-model="form.discountType"
  130. placeholder="请选择"
  131. style="width:60%;"
  132. size="small"
  133. @change="handleDiscountType"
  134. allowClear>
  135. <a-select-option value="0" id="promotionList-discountType0">
  136. 手动输入特价
  137. </a-select-option>
  138. <a-select-option value="1" id="promotionList-discountType1">
  139. 各级别价打折
  140. </a-select-option>
  141. <a-select-option value="2" id="promotionList-discountType2">
  142. 各级别价直降
  143. </a-select-option>
  144. </a-select>
  145. <a-table
  146. v-show="form.discountType!=0"
  147. class="sTable"
  148. ref="setTable"
  149. size="small"
  150. :rowKey="(record) => record.id"
  151. :columns="setColumns"
  152. :dataSource="setTableData"
  153. :pagination="false"
  154. style="width:60%;"
  155. bordered>
  156. <template slot="provinceDiscount" slot-scope="text, record">
  157. <a-input-number
  158. size="small"
  159. :id="'promotionList-provinceDiscount'+record.id"
  160. v-model="record.provinceValue"
  161. :min="0"
  162. :step="1"
  163. :precision="2"
  164. :max="99999999"
  165. placeholder="请输入"/>%
  166. </template>
  167. <template slot="cityDiscount" slot-scope="text, record">
  168. <a-input-number
  169. size="small"
  170. :id="'promotionList-cityValue'+record.id"
  171. v-model="record.cityValue"
  172. :min="record.provinceValue||0"
  173. :step="1"
  174. :precision="2"
  175. :max="99999999"
  176. placeholder="请输入"/>%
  177. </template>
  178. <template slot="specialDiscount" slot-scope="text, record">
  179. <a-input-number
  180. size="small"
  181. :id="'promotionList-specialValue'+record.id"
  182. v-model="record.specialValue"
  183. :min="record.cityValue ||0"
  184. :step="1"
  185. :precision="2"
  186. :max="99999999"
  187. placeholder="请输入"/>%
  188. </template>
  189. <template slot="provincePrice" slot-scope="text, record">
  190. <a-input-number
  191. size="small"
  192. :value="record.provinceValue"
  193. :id="'promotionList-provinceValue'+record.id"
  194. :min="0"
  195. :step="1"
  196. :precision="2"
  197. :max="99999999"
  198. placeholder="请输入"
  199. @blur="handleProvincePrice"/>
  200. </template>
  201. <template slot="cityPrice" slot-scope="text, record">
  202. <a-input-number
  203. size="small"
  204. :value="record.cityValue"
  205. :id="'promotionList-cityValue'+record.id"
  206. :min="0"
  207. :step="1"
  208. :precision="2"
  209. :max="99999999"
  210. placeholder="请输入"
  211. @blur="handleCityPrice"/>
  212. </template>
  213. <template slot="specialPrice" slot-scope="text, record">
  214. <a-input-number
  215. size="small"
  216. :value="record.specialValue"
  217. :id="'promotionList-specialValue'+record.id"
  218. :min="0"
  219. :step="1"
  220. :precision="2"
  221. :max="99999999"
  222. placeholder="请输入"
  223. @blur="handleSpecialPrice"/>
  224. </template>
  225. </a-table>
  226. </a-form-model-item>
  227. </a-form-model>
  228. <a-card size="small" :bordered="false" class="pages-wrap">
  229. <div class="flex" style="margin-bottom:10px;">
  230. <a-radio-group id="promotionList-chooseVal" v-model="chooseVal" button-style="solid">
  231. <a-radio-button value="a" v-show="form.gateFlag==='1'" id="promotionList-chooseVal-a">
  232. 门槛产品
  233. </a-radio-button>
  234. <a-radio-button value="d" id="promotionList-chooseVal-d">
  235. 特价产品
  236. </a-radio-button>
  237. </a-radio-group>
  238. <div>
  239. <a-button
  240. size="small"
  241. type="link"
  242. class="button-info"
  243. id="promotionList-import-btn"
  244. @click="openGuideModal=true"
  245. >+导入产品</a-button>
  246. <a-button
  247. v-show="chooseVal==='d'"
  248. style="margin-left:10px;"
  249. size="small"
  250. type="link"
  251. class="button-info"
  252. id="promotionList-add-btn"
  253. @click="addProducts">+新增产品</a-button>
  254. <a-button type="link" id="promotionList-preview-btn" class="button-error" @click="handlePreview">预览</a-button>
  255. </div>
  256. </div>
  257. <div v-show="chooseVal=='a'"><tableType1 :unitTypeList="unitTypeDataList" ref="cillProduct"></tableType1></div>
  258. <div v-show="chooseVal=='d'"><tableType3 :setData="setTableData" :rulesType="form.discountType" :unitTypeList="unitTypeDataList" ref="specialProduct"></tableType3></div>
  259. </a-card>
  260. <div class="btn-cont">
  261. <a-button id="promotionList-cancel-btn" @click="isShow = false">取消</a-button>
  262. <a-button style="margin-left: 15px;" type="primary" id="promotionList-save-btn" @click="handleSave">确定</a-button>
  263. </div>
  264. </a-spin>
  265. <!-- 选择产品 -->
  266. <chooseProductsModal
  267. type="dealership"
  268. ref="productBox"
  269. :openModal="openProductsModal"
  270. :chooseData="chooseProducts"
  271. @close="openProductsModal=false"
  272. @ok="handleProductsAdd" />
  273. <!-- 导入产品 -->
  274. <importGuideModal :goodFlag="chooseVal=='a'?'1':'0'" :rulesType="form.discountType" :openModal="openGuideModal" @close="closeGuideModel" @ok="hanldeOk" />
  275. <!-- 预览弹窗 -->
  276. <productPreviewModal ref="previewModal" :openModal="openProductModal" :dataList="previewList" @close="closeProductModal"></productPreviewModal>
  277. </a-modal>
  278. </template>
  279. <script>
  280. import { commonMixin } from '@/utils/mixin'
  281. // 组件
  282. import { VSelect } from '@/components'
  283. import tableType1 from './tableType1.vue'
  284. import tableType3 from './tableType3.vue'
  285. import chooseProductsModal from './chooseProductsModal.vue'
  286. import ImportGuideModal from './importGuideModal.vue'
  287. import productPreviewModal from './productPreviewModal'
  288. // 接口
  289. import { getLookUpData } from '@/api/data'
  290. import { promotionSave, getRuleDetail } from '@/api/promotion'
  291. export default {
  292. name: 'PromotionListBasicInfoModal',
  293. mixins: [commonMixin],
  294. components: { VSelect, tableType1, tableType3, chooseProductsModal, ImportGuideModal, productPreviewModal },
  295. props: {
  296. openModal: { // 弹框显示状态
  297. type: Boolean,
  298. default: false
  299. },
  300. promotionSn: {
  301. type: [Number, String],
  302. default: ''
  303. },
  304. itemSn: {
  305. type: [Number, String],
  306. default: ''
  307. }
  308. },
  309. data () {
  310. return {
  311. isShow: this.openModal, // 是否打开弹框
  312. spinning: false,
  313. // form表单label布局
  314. formItemLayout: {
  315. labelCol: { span: 4 },
  316. wrapperCol: { span: 17 }
  317. },
  318. // 提交参数
  319. form: {
  320. promotionRuleType: 'PROMO_PROD', // 特价产品
  321. description: '', // 规则简称
  322. gateFlag: '0', // 门槛
  323. gateType: undefined, // 门槛产品类型
  324. gateValue: undefined, // 门槛产品配额值、满最低金额值、最低门槛金额和最低个数值
  325. gateUnit: 'GE', // 门槛产品单位
  326. quotaUnit: undefined, // 赠特价产品单位
  327. quotaAmount: undefined, // 赠特价产品金额
  328. discountType: '0', // 特价规则
  329. gateInfo: undefined, // 门槛产品规则描述
  330. ruleInfo: undefined// 特价产品规则描述
  331. },
  332. // 表单验证规则
  333. rules: {
  334. description: [ { required: true, message: '请输入规则简称', trigger: 'blur' } ],
  335. gateFlag: [ { required: true, message: '请选择规则门槛', trigger: 'change' } ],
  336. discountType: [{ required: true, message: '请选择特价规则', trigger: 'change' }]
  337. },
  338. setTableData: null, // 特价表格规则
  339. chooseVal: 'a', // 显示规则类型 a门槛产品 d特价产品
  340. openProductsModal: false, // 打开选择产品弹窗
  341. chooseProducts: [], // 已选产品集合
  342. openGuideModal: false, // 导入弹窗
  343. code: 'SCOPE_UNIT_TYPE', // 起订类型数据字典
  344. unitTypeDataList: [], // 起订量集合
  345. openProductModal: false, // 预览弹窗
  346. previewList: []// 预览值
  347. }
  348. },
  349. computed: {
  350. setColumns () {
  351. const _this = this
  352. var arr = []
  353. if (_this.form.discountType === '1') {
  354. arr = [
  355. { title: '省价折扣', scopedSlots: { customRender: 'provinceDiscount' }, width: '33%', align: 'center' },
  356. { title: '市价折扣', scopedSlots: { customRender: 'cityDiscount' }, width: '33%', align: 'center' },
  357. { title: '特约折扣', scopedSlots: { customRender: 'specialDiscount' }, width: '33%', align: 'center' }
  358. ]
  359. } else if (_this.form.discountType === '2') {
  360. arr = [
  361. { title: '省价直降', scopedSlots: { customRender: 'provincePrice' }, width: '33%', align: 'center' },
  362. { title: '市价直降', scopedSlots: { customRender: 'cityPrice' }, width: '33%', align: 'center' },
  363. { title: '特约直降', scopedSlots: { customRender: 'specialPrice' }, width: '33%', align: 'center' }
  364. ]
  365. }
  366. return arr
  367. }
  368. },
  369. methods: {
  370. // 单位切换时,满赠规则数据清空
  371. handleUnit (val) {
  372. this.form.gateUnit = val
  373. this.form.gateValue = undefined
  374. },
  375. // 省价 change
  376. handleProvincePrice (e) {
  377. this.setTableData[0].provinceValue = Number(e.target.value)
  378. },
  379. // 市价 change
  380. handleCityPrice (e) {
  381. this.setTableData[0].cityValue = Number(e.target.value)
  382. },
  383. // 特约价 change
  384. handleSpecialPrice (e) {
  385. this.setTableData[0].specialValue = Number(e.target.value)
  386. },
  387. // 特价规则切换时清空数据
  388. handleDiscountType (val) {
  389. this.form.discountType = val
  390. this.$refs.specialProduct.reSetTableData()
  391. this.setTableData = [{
  392. provinceValue: undefined,
  393. cityValue: undefined,
  394. specialValue: undefined
  395. }]
  396. },
  397. // 导入
  398. closeGuideModel () {
  399. this.openGuideModal = false
  400. },
  401. // 门槛产品
  402. handleChange (e) {
  403. if (e.target.value == '1') {
  404. this.chooseVal = 'a'
  405. } else {
  406. this.chooseVal = 'd'
  407. this.form.gateType = undefined
  408. this.form.gateValue = undefined
  409. this.form.quotaAmount = undefined
  410. }
  411. },
  412. // 门槛与配额设置要求
  413. changeGateTypeFlag (val) {
  414. this.form.gateType = val
  415. this.form.gateValue = undefined
  416. this.form.quotaAmount = undefined
  417. },
  418. // 保存
  419. handleSave () {
  420. const _this = this
  421. this.$refs.ruleForm.validate(valid => {
  422. if (valid) {
  423. // 验证必填
  424. if (_this.form.gateFlag === '1') {
  425. if (!_this.form.gateType) {
  426. _this.$message.warning('请选择规则门槛设置类型!')
  427. return
  428. }
  429. if (!_this.form.gateValue) {
  430. _this.$message.warning('规则门槛条件不能为空!')
  431. return
  432. }
  433. if (_this.form.gateType === 'FIXED_AMOUNT' && !_this.form.quotaAmount) {
  434. _this.$message.warning('规则门槛条件不能为空!')
  435. return
  436. }
  437. }
  438. // 判断特价规则必填
  439. if (_this.form.discountType != '0' && _this.setTableData) {
  440. if (_this.setTableData[0].provinceValue == undefined || _this.setTableData[0].cityValue == undefined || _this.setTableData[0].specialValue == undefined) {
  441. _this.$message.warning('特价规则条件不能为空!')
  442. return
  443. }
  444. }
  445. const form = JSON.parse(JSON.stringify(_this.form))
  446. if (form.gateFlag === '1') {
  447. form.gateProductList = _this.$refs.cillProduct.getResultVal()
  448. form.gateValue = form.gateType === 'RATIO_AMOUNT' ? form.gateValue / 100 : form.gateValue
  449. if (form.gateProductList.length == 0) {
  450. _this.$message.warning('请添加门槛产品!')
  451. return
  452. } else {
  453. const qtyFlag = form.gateProductList.some(newCon => { return (!newCon.unitType || !newCon.unitQty) })
  454. if (qtyFlag) {
  455. _this.$message.warning('订单起订量设置不能为空!')
  456. return
  457. }
  458. const rowFlag = _this.isJudge(form.gateProductList)
  459. if (rowFlag) {
  460. _this.$message.warning('请选择产品分类、品牌或产品!')
  461. return
  462. }
  463. }
  464. form.gateUnit = form.gateType == 'RATIO_AMOUNT' ? 'RATIO' : form.gateType == 'MIN_AMOUNT' ? 'YUAN' : form.gateUnit
  465. form.quotaUnit = 'GE'
  466. } else {
  467. form.gateProductList = []
  468. form.gateValue = ''
  469. form.quotaAmount = ''
  470. form.gateType = undefined
  471. form.gateUnit = 'GE'
  472. form.quotaUnit = undefined
  473. }
  474. form.specialProductList = _this.$refs.specialProduct.getResultVal()
  475. if (form.specialProductList.length == 0) {
  476. _this.$message.warning('请添加特价产品!')
  477. return
  478. } else {
  479. // 为空判断
  480. const isTypeEmpty = form.specialProductList.some(item => (item.productTypeList && item.productTypeList.length == 0) && (item.productBrandList && item.productBrandList.length == 0))
  481. if (isTypeEmpty) {
  482. _this.$message.warning('产品分类或品牌不能为空!')
  483. return
  484. }
  485. const isNumEmpty = form.specialProductList.some(item => (!item.unitType || !item.unitQty))
  486. if (isNumEmpty) {
  487. _this.$message.warning('订单起订量设置不能为空!')
  488. return
  489. }
  490. }
  491. if (form.discountType === '0') { // 手动输入
  492. const isCountEmpty = _this.isNumEmpty(form.specialProductList)
  493. if (isCountEmpty.flag) {
  494. _this.$message.warning('折扣不能为空!')
  495. return
  496. }
  497. if (isCountEmpty.flag1) {
  498. _this.$message.warning('折扣金额不能为空!')
  499. return
  500. }
  501. } else {
  502. // if (form.discountType === '2') { // 直降价格为负判断
  503. // const hasNegativePrice = form.specialProductList.some((item) => (item.provinceDiscountPrice < 0 || item.cityDiscountPrice < 0 || item.specialDiscountPrice < 0))
  504. // if (hasNegativePrice) {
  505. // _this.$message.warning('直降后价格不能为负值!')
  506. // return
  507. // }
  508. // }
  509. form.provinceValue = _this.setTableData[0].provinceValue
  510. form.cityValue = _this.setTableData[0].cityValue
  511. form.specialValue = _this.setTableData[0].specialValue
  512. }
  513. form.promotionSn = _this.promotionSn
  514. if (form.gateFlag == '1') {
  515. if (form.gateType === 'RATIO_AMOUNT') {
  516. form.gateInfo = '购买门槛产品金额' + (form.gateValue * 100).toFixed(2) + '%作为配额'
  517. } else if (form.gateType === 'MIN_AMOUNT') {
  518. form.gateInfo = '购买门槛产品满最低金额' + (form.gateValue).toFixed(2) + '元,不限制配额'
  519. } else {
  520. form.gateInfo = '购买每满' + (form.gateUnit == 'YUAN' ? (form.gateValue).toFixed(2) : form.gateValue) + (form.gateUnit == 'YUAN' ? '元' : '个') + '门槛产品,可采购' + form.quotaAmount + '个特价产品(配额算销售额)'
  521. }
  522. }
  523. if (form.discountType == '0') {
  524. form.ruleInfo = '手动输入特价'
  525. } else if (form.discountType == '1') {
  526. form.ruleInfo = '各级别价打折;省级折扣' + form.provinceValue.toFixed(2) + '%,市级折扣' + form.cityValue.toFixed(2) + '%,特约折扣' + form.specialValue.toFixed(2) + '%'
  527. } else {
  528. form.ruleInfo = '各级别价直降;省级直降' + form.provinceValue.toFixed(2) + ',市级直降' + form.cityValue.toFixed(2) + ',特约直降' + form.specialValue.toFixed(2)
  529. }
  530. _this.spinning = true
  531. promotionSave(form).then(res => {
  532. if (res.status == 200) {
  533. _this.$message.success(res.message)
  534. setTimeout(() => {
  535. _this.isShow = false
  536. _this.$emit('ok')
  537. _this.spinning = false
  538. }, 1000)
  539. } else {
  540. _this.spinning = false
  541. }
  542. })
  543. } else {
  544. return false
  545. }
  546. })
  547. },
  548. // 判断是否为空
  549. isNumEmpty (dataList) {
  550. const arr = []
  551. const arr1 = []
  552. dataList.forEach(item => {
  553. if (item.dataSourceOrigin === '0') { // 判断分类品牌
  554. if (!item.provinceDiscountRate || !item.cityDiscountRate || !item.specialDiscountRate) {
  555. arr.push(item.productScopeSn)
  556. }
  557. } else {
  558. if (!item.cityDiscountPrice || !item.provinceDiscountPrice || !item.specialDiscountPrice) {
  559. arr1.push(item.productScopeSn)
  560. }
  561. }
  562. })
  563. return { flag: arr.length > 0, flag1: arr1.length > 0 }
  564. },
  565. // 判断门槛产品中品牌,分类,产品其中一个必填
  566. isJudge (list) {
  567. const flag = list.some(con => {
  568. if (con.productThisList) {
  569. if (con.productThisList.length > 0) {
  570. return false
  571. } else {
  572. if ((con.productTypeList && con.productTypeList.length > 0) || (con.productBrandList && con.productBrandList.length > 0)) {
  573. return false
  574. } else {
  575. return true
  576. }
  577. }
  578. } else {
  579. if ((con.productTypeList && con.productTypeList.length > 0) || (con.productBrandList && con.productBrandList.length > 0)) {
  580. return false
  581. } else {
  582. return true
  583. }
  584. }
  585. })
  586. return flag
  587. },
  588. // 重置表格
  589. resetSearchForm () {
  590. this.form = {
  591. promotionRuleType: 'PROMO_PROD', // 特价产品
  592. description: '', // 规则简称
  593. gateFlag: '0', // 门槛
  594. gateType: undefined,
  595. gateValue: undefined,
  596. gateUnit: 'GE',
  597. quotaAmount: undefined,
  598. discountType: '0', // 特价规则
  599. gateProductList: undefined,
  600. specialProductList: undefined,
  601. quotaUnit: undefined
  602. }
  603. this.$nextTick(() => {
  604. this.$refs.ruleForm.resetFields()
  605. this.$refs.cillProduct.reSetTableData()
  606. this.$refs.specialProduct.reSetTableData()
  607. })
  608. if (this.form.discountType != '0') {
  609. this.$refs[0].setTable.clearTable()
  610. }
  611. this.setTableData = []
  612. },
  613. // 获取编辑详情
  614. getDetail () {
  615. const _this = this
  616. _this.spinning = true
  617. getRuleDetail({ sn: this.itemSn }).then(res => {
  618. if (res.status == 200) {
  619. this.chooseVal = res.data.gateFlag == '0' ? 'd' : 'a'
  620. const resultObj = res.data
  621. if (resultObj.gateFlag === '1') {
  622. resultObj.gateValue = resultObj.gateType === 'RATIO_AMOUNT' ? resultObj.gateValue * 100 : resultObj.gateValue
  623. }
  624. if (resultObj.discountType != '0') {
  625. _this.setTableData = [{
  626. provinceValue: resultObj.provinceValue,
  627. cityValue: resultObj.cityValue,
  628. specialValue: resultObj.specialValue
  629. }]
  630. }
  631. // 重新组成保存数据
  632. if (resultObj.gateProductList && resultObj.gateProductList.length > 0) {
  633. resultObj.gateProductList = _this.newData(resultObj.gateProductList)
  634. this.$refs.cillProduct.setTabVal(resultObj.gateProductList)
  635. }
  636. if (resultObj.specialProductList && resultObj.specialProductList.length > 0) {
  637. resultObj.specialProductList = _this.newData(resultObj.specialProductList)
  638. this.$refs.specialProduct.setSourceData(resultObj.specialProductList)
  639. }
  640. this.form = { ...this.form, ...resultObj }
  641. }
  642. _this.spinning = false
  643. })
  644. },
  645. // 重组所需数据格式
  646. newData (list) {
  647. list.forEach(con => {
  648. // 品牌
  649. if (con.productBrandList) {
  650. const brandList = []
  651. con.productBrandList.forEach(item => {
  652. item.brandName = item.productBrandName
  653. item.brandSn = item.productBrandSn
  654. const brandObj = {
  655. productBrandSn: item.productBrandSn
  656. }
  657. brandList.push(brandObj)
  658. })
  659. con.productBrandArr = con.productBrandList
  660. con.productBrandList = brandList
  661. }
  662. // 分类
  663. if (con.productTypeList) {
  664. const typeList = []
  665. con.productTypeList.forEach(item => {
  666. const typeObj = {}
  667. item.title = ''
  668. const num = 3
  669. for (var i = 0; i < num; i++) {
  670. if (item['productTypeName' + (i + 1)]) {
  671. typeObj['productTypeSn' + (i + 1)] = item['productTypeSn' + (i + 1)] ? item['productTypeSn' + (i + 1)] : ''
  672. }
  673. }
  674. if (item.productTypeName3) {
  675. item.title = item.productTypeName2 + '/' + item.productTypeName3
  676. } else if (!item.productTypeName3 && item.productTypeName2) {
  677. item.title = item.productTypeName2
  678. } else {
  679. item.title = item.productTypeName1
  680. }
  681. item.id = item.productTypeSn3 ? item.productTypeSn3 : item.productTypeSn2 ? item.productTypeSn2 : item.productTypeSn1
  682. typeList.push(typeObj)
  683. })
  684. con.productTypeArr = con.productTypeList
  685. con.productTypeList = typeList
  686. }
  687. // 产品
  688. if (con.productThisList) {
  689. const productList = []
  690. con.productThisList.forEach(item => {
  691. const productObj = {
  692. productCode: item.productCode,
  693. productSn: item.productSn
  694. }
  695. productList.push(productObj)
  696. })
  697. con.productThisList = productList
  698. }
  699. })
  700. return list
  701. },
  702. // 导入
  703. hanldeOk (arr) {
  704. // 门槛产品导入
  705. const resultArr = []
  706. if (this.chooseVal == 'a') {
  707. const name = this.chooseVal == 'a' ? 'cill' : this.chooseVal == 'b' ? 'normalPrice' : 'offer'
  708. this.$refs[name + 'Product'].importRow(arr)
  709. } else {
  710. // 特价产品导入
  711. const dataList = this.setShowData('This')
  712. arr.forEach(item => {
  713. item = { ...item, ...item.product }
  714. item.code = item.productCode
  715. if (this.form.discountType == '0') {
  716. if (item.provincePrice) {
  717. item.provinceDiscountRate = Math.floor(((item.provinceDiscountPriceText / item.provincePrice) * 100).toFixed(2))
  718. }
  719. if (item.cityPrice) {
  720. item.cityDiscountRate = Math.floor(((item.cityDiscountPriceText / item.cityPrice) * 100).toFixed(2))
  721. }
  722. if (item.specialPrice) {
  723. item.specialDiscountRate = Math.floor(((item.specialDiscountPriceText / item.specialPrice) * 100).toFixed(2))
  724. }
  725. } else if (this.form.discountType == '1') {
  726. if (item.provincePrice) {
  727. item.provinceDiscountRate = this.form.provinceValue
  728. item.provinceDiscountPriceText = (item.provincePrice * this.form.provinceValue / 100).toFixed(2)
  729. }
  730. if (item.cityPrice) {
  731. item.cityDiscountRate = this.form.cityValue
  732. item.cityDiscountPriceText = (item.cityPrice * this.form.cityValue / 100).toFixed(2)
  733. }
  734. if (item.specialPrice) {
  735. item.specialDiscountRate = this.form.specialValue
  736. item.specialDiscountPriceText = (item.specialPrice * this.form.specialValue / 100).toFixed(2)
  737. }
  738. } else {
  739. if (item.provincePrice) {
  740. item.provinceSubtract = item.provincePrice - this.form.provinceValue
  741. }
  742. if (item.cityPrice) {
  743. item.citySubtract = item.cityPrice - this.form.cityValue
  744. }
  745. if (item.specialPrice) {
  746. item.specialSubtract = item.specialPrice - this.form.specialValue
  747. }
  748. }
  749. const flag = dataList.includes(item.productSn)
  750. if (!flag) {
  751. resultArr.push(item)
  752. }
  753. })
  754. if (resultArr.length > 0) {
  755. this.handleProductsOk(resultArr)
  756. } else {
  757. this.$message.warning('请勿添加重复数据!')
  758. }
  759. }
  760. },
  761. // 打开新增产品弹窗(禁用已选)
  762. addProducts () {
  763. this.chooseProducts = []
  764. this.openProductsModal = true
  765. const dataList = this.setShowData('This')
  766. this.$refs.productBox.handleDisabled(dataList)
  767. },
  768. // 获取回显禁用数据
  769. setShowData (name) {
  770. const _this = this
  771. const snArr = []
  772. const valList = _this.$refs.specialProduct.getResultVal()
  773. valList.forEach(item => {
  774. if (item['product' + name + 'List'] && item['product' + name + 'List'].length > 0) {
  775. item['product' + name + 'List'].forEach(con => {
  776. const newName = name === 'This' ? '' : name
  777. snArr.push(con['product' + newName + 'Sn'])
  778. })
  779. }
  780. })
  781. return snArr
  782. },
  783. // 添加产品 重组回显数据
  784. handleProductsAdd (con) {
  785. const newArr = []
  786. const newConArr = []
  787. con.forEach(newCon => {
  788. if (!newCon.provincePrice || !newCon.cityPrice || !newCon.specialPrice) {
  789. newArr.push(newCon.code)
  790. }
  791. })
  792. con.forEach((list, pos) => {
  793. if (list.provincePrice && list.cityPrice && list.specialPrice) {
  794. newConArr.push(list)
  795. }
  796. })
  797. const _this = this
  798. if (newArr && newArr.length > 0) {
  799. _this.$info({
  800. title: '提示',
  801. content: newArr.toString() + '(产品编码),没有定价,不可添加',
  802. closable: true,
  803. centered: true,
  804. onOk () {
  805. _this.handleProductsOk(newConArr)
  806. }
  807. })
  808. } else {
  809. _this.handleProductsOk(newConArr)
  810. }
  811. },
  812. // 生成随机数
  813. generateUniqueRandomNumber () {
  814. const timestamp = new Date().getTime()
  815. const randomNumber = Math.floor(Math.random() * 1e5).toString().padStart(5, '0')
  816. const uniqueRandomNumber = timestamp + randomNumber
  817. return uniqueRandomNumber
  818. },
  819. // +新增产品
  820. handleProductsOk (con) {
  821. const _this = this
  822. _this.spinning = true
  823. setTimeout(() => {
  824. _this.spinning = false
  825. }, 1500)
  826. con.forEach(async (item) => {
  827. const chooseProductsList = []
  828. const getSn = this.generateUniqueRandomNumber()
  829. if (getSn) {
  830. const newData = {
  831. productScopeSn: getSn,
  832. dataSourceOrigin: '1',
  833. productTypeArr: [],
  834. productTypeList: [],
  835. productBrandArr: [{ productBrandSn: item.productBrandSn, brandName: item.productBrandName }],
  836. productBrandList: [{ productBrandSn: item.productBrandSn }],
  837. productThisList: [{
  838. productSn: item.productSn,
  839. productCode: item.code
  840. }],
  841. provincePrice: item.provincePrice,
  842. cityPrice: item.cityPrice,
  843. specialPrice: item.specialPrice,
  844. provinceDiscountPrice: item.provinceDiscountPriceText,
  845. cityDiscountPrice: item.cityDiscountPriceText,
  846. specialDiscountPrice: item.specialDiscountPriceText,
  847. unitType: item.unitType || 'SL',
  848. unitQty: item.unitQty || '1',
  849. provinceDiscountRate: item.provinceDiscountRate ? item.provinceDiscountRate : undefined,
  850. cityDiscountRate: item.cityDiscountRate ? item.cityDiscountRate : undefined,
  851. specialDiscountRate: item.specialDiscountRate ? item.specialDiscountRate : undefined
  852. }
  853. const obj = {}
  854. if (item.productTypeSn1) {
  855. obj.productTypeSn1 = item.productTypeSn1
  856. }
  857. if (item.productTypeSn2) {
  858. obj.productTypeSn2 = item.productTypeSn2
  859. }
  860. if (item.productTypeSn3) {
  861. obj.productTypeSn3 = item.productTypeSn3
  862. }
  863. const newObj = { ...obj, ...{} }
  864. if (Object.keys(obj).length == 1) {
  865. newObj.title = item.productTypeName1
  866. newObj.id = item.productTypeSn1
  867. } else if (Object.keys(obj).length == 2) {
  868. newObj.title = item.productTypeName2
  869. newObj.id = item.productTypeSn2
  870. } else {
  871. newObj.title = item.productTypeName2 + '/' + item.productTypeName3
  872. newObj.id = item.productTypeSn3
  873. }
  874. newData.productTypeList[0] = obj
  875. newData.productTypeArr[0] = newObj
  876. chooseProductsList.push(newData)
  877. }
  878. _this.$refs.specialProduct.setSourceData(chooseProductsList)
  879. })
  880. },
  881. // 获取起订类型数据字典
  882. getUnitTypeList () {
  883. const _this = this
  884. getLookUpData({
  885. pageNo: 1,
  886. pageSize: 1000,
  887. lookupCode: _this.code
  888. }).then(res => {
  889. if (res.status == 200) {
  890. _this.unitTypeDataList = res.data.list
  891. }
  892. })
  893. },
  894. // 获取预览数据
  895. getPreviewList (dataList) {
  896. if (dataList && dataList.length > 0) {
  897. let newList = []
  898. dataList.forEach(con => {
  899. if (con.productThisList) {
  900. con.productThisList.forEach((item, i) => {
  901. item.unitTypeInfo = (con.unitType === 'SL' ? '按数量设置' : '按整箱设置') + con.unitQty
  902. item.productTypeInfo = con.promotionProductType
  903. })
  904. newList = [ ...newList, ...con.productThisList ]
  905. }
  906. })
  907. return newList
  908. } else {
  909. return []
  910. }
  911. },
  912. // 预览 删除标签,添加标签 预览按钮显示不显示
  913. handlePreview () {
  914. const dataName = this.chooseVal === 'a' ? 'gate' : 'special'
  915. const titName = this.chooseVal === 'a' ? '门槛产品' : '特价产品'
  916. if (!this.itemSn) {
  917. if (this.chooseVal === 'a') {
  918. this.form.gateProductList = this.$refs.cillProduct.getResultVal()
  919. } else {
  920. this.form.specialProductList = this.$refs.specialProduct.getResultVal()
  921. }
  922. }
  923. this.$nextTick(() => {
  924. const newPreviewList = this.getPreviewList(this.form[dataName + 'ProductList'])
  925. if (newPreviewList.length === 0) {
  926. this.$message.warning('暂时没有可预览的产品')
  927. return
  928. }
  929. this.previewList = newPreviewList
  930. const resuleObj = {
  931. tit: titName
  932. }
  933. this.$refs.previewModal.pageInit(resuleObj)
  934. this.openProductModal = true
  935. })
  936. },
  937. // 关闭产品弹窗
  938. closeProductModal () {
  939. this.previewList = []
  940. this.openProductModal = false
  941. }
  942. },
  943. watch: {
  944. // 父页面传过来的弹框状态
  945. openModal (newValue, oldValue) {
  946. this.isShow = newValue
  947. },
  948. // 重定义的弹框状态
  949. isShow (newValue, oldValue) {
  950. if (!newValue) {
  951. this.$emit('close')
  952. this.resetSearchForm()
  953. } else {
  954. // 获取起订类型数据字典
  955. this.getUnitTypeList()
  956. if (this.itemSn) {
  957. this.getDetail()
  958. } else {
  959. this.chooseVal = this.form.gateFlag == '0' ? 'd' : 'a'
  960. }
  961. }
  962. }
  963. }
  964. }
  965. </script>
  966. <style lang="less" scoped>
  967. // .ant-modal-confirm-body{
  968. // max-height: 500px;
  969. // overflow-y:scroll;
  970. // }
  971. .promotionList-basicInfo-modal{
  972. /deep/.ant-modal-body {
  973. padding: 20px 30px;
  974. max-height: 745px !important;
  975. overflow-y: scroll !important;
  976. }
  977. .fixWidthBox .ant-radio-button-wrapper{
  978. width:80px;
  979. text-align: center;
  980. }
  981. .ant-form-item{
  982. margin-bottom:5px;
  983. }
  984. .buyerBox{
  985. border:1px solid #d9d9d9;margin-top:10px;border-radius:4px;padding:4px 10px;background:#f2f2f2;max-height:130px;overflow-y:scroll;
  986. }
  987. .btn-cont {
  988. text-align: center;
  989. margin: 20px 0 10px;
  990. }
  991. .flex{
  992. display:flex;
  993. align-items:center;
  994. justify-content:space-between;
  995. }
  996. }
  997. /deep/.ve-table{
  998. border-radius:5px;
  999. }
  1000. </style>