specialOfferModal.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  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="80%">
  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="请输入促销简称(最多10个字符)"
  26. :maxLength="10"></a-input>
  27. </a-form-model-item>
  28. <a-form-model-item label="规则门槛" prop="gateFlag">
  29. <a-radio-group v-model="form.gateFlag" button-style="solid" size="small" @change="handleChange">
  30. <a-radio-button value="1">
  31. </a-radio-button>
  32. <a-radio-button value="0">
  33. </a-radio-button>
  34. </a-radio-group>
  35. <div v-if="form.gateFlag && form.gateFlag === '1'">
  36. <v-select
  37. size="small"
  38. style="width:60%;"
  39. v-model="form.gateType"
  40. id="promotionList-gateType"
  41. code="PROMOTION_GATE_TYPE"
  42. placeholder="请选择"
  43. allowClear></v-select>
  44. <div v-if="form.gateType==='RATIO_AMOUNT'">
  45. 购买门槛产品金额 <a-input-number v-model="form.gateAmount" :min="0" :max="100" size="small"/> %作为配额
  46. <a-tooltip title="如:填写100%,则购买10000元门槛产品,可享受10000配额购买正价产品,根据门槛金额动态调整配额">
  47. <a-icon type="question-circle" theme="filled" :style="{ fontSize: '14px', color: 'gray' }"/>
  48. </a-tooltip>
  49. </div>
  50. <div v-if="form.gateType==='MIN_AMOUNT'">
  51. 购买门槛产品满最低金额 <a-input-number v-model="form.gateAmount" :min="0" :precision="2" size="small"/> 不限制配额。
  52. </div>
  53. <div class="ruleDescList" v-if="form.gateType==='FIXED_AMOUNT'">
  54. 购买满
  55. <a-input-number v-model="form.gateAmount" :min="0" :precision="2" size="small"/>
  56. 元门槛产品,可使用
  57. <a-input-number v-model="form.quotaAmount" :max="form.gateAmount" :min="0" :precision="2" size="small"/>
  58. 元配额,采购规则中的正价商品(配额算销售额)
  59. </div>
  60. </div>
  61. </a-form-model-item>
  62. <a-form-model-item prop="minOrderFlag">
  63. <span slot="label">
  64. <a-tooltip title="What do you want others to call you?">
  65. <a-icon type="info-circle" />
  66. </a-tooltip>
  67. 订单起订金额
  68. </span>
  69. <a-select default-value="1" v-model="form.minOrderFlag" style="width: 160px" size="small">
  70. <a-select-option value="0">
  71. 不限
  72. </a-select-option>
  73. <a-select-option value="1">
  74. 限制
  75. </a-select-option>
  76. </a-select>
  77. <a-input-number
  78. v-show="form.minOrderFlag && form.minOrderFlag=='1'"
  79. size="small"
  80. style="margin-left:10px;width:300px;"
  81. v-model="form.minOrderAmount"
  82. :min="0"
  83. :step="1"
  84. :precision="2"
  85. placeholder="请输入金额"/>
  86. </a-form-model-item>
  87. <a-form-model-item prop="upperLimitFlag">
  88. <span slot="label">
  89. <a-tooltip title="What do you want others to call you?">
  90. <a-icon type="info-circle" />
  91. </a-tooltip>
  92. 活动经费上限
  93. </span>
  94. <a-select default-value="1" v-model="form.upperLimitFlag" style="width: 160px" size="small">
  95. <a-select-option value="0">
  96. 不限
  97. </a-select-option>
  98. <a-select-option value="1">
  99. 限制
  100. </a-select-option>
  101. </a-select>
  102. <a-input-number
  103. v-show="form.upperLimitFlag&&form.upperLimitFlag=='1'"
  104. size="small"
  105. style="margin-left:10px;width:300px;"
  106. v-model="form.upperLimitAmount"
  107. :min="0"
  108. :step="1"
  109. :precision="2"
  110. placeholder="请输入金额"/>
  111. </a-form-model-item>
  112. </a-form-model>
  113. <a-card size="small" :bordered="false" class="pages-wrap">
  114. <div class="flex">
  115. <a-radio-group v-model="chooseVal" button-style="solid" size="small">
  116. <a-radio-button value="a" v-show="form.gateFlag==='1'">
  117. 门槛产品
  118. </a-radio-button>
  119. <a-radio-button value="d">
  120. 特价产品
  121. </a-radio-button>
  122. </a-radio-group>
  123. <div>
  124. <a-button
  125. size="small"
  126. type="link"
  127. class="button-info"
  128. id="promotionList-edit-btn">+导入产品</a-button>
  129. <a-button
  130. v-show="chooseVal==='d'"
  131. style="margin-left:10px;"
  132. size="small"
  133. type="link"
  134. class="button-error"
  135. id="promotionList-edit-btn"
  136. @click="openProductsModal = true">+新增产品</a-button>
  137. </div>
  138. </div>
  139. <div v-show="chooseVal=='a'"><tableType1 ref="cillProduct"></tableType1></div>
  140. <div v-show="chooseVal=='d'"><tableType3 ref="specialProduct"></tableType3></div>
  141. </a-card>
  142. <div class="btn-cont">
  143. <a-button id="promotionList-basicInfo-modal-back" @click="isShow = false">取消</a-button>
  144. <a-button style="margin-left: 15px;" type="primary" id="promotionList-modal-save" @click="handleSave">确定</a-button>
  145. </div>
  146. </a-spin>
  147. <!-- 选择产品 -->
  148. <chooseProductsModal
  149. type="dealership"
  150. :openModal="openProductsModal"
  151. :chooseData="chooseProducts"
  152. @close="openProductsModal=false"
  153. @ok="handleProductsOk" />
  154. </a-modal>
  155. </template>
  156. <script>
  157. import { commonMixin } from '@/utils/mixin'
  158. import { VSelect } from '@/components'
  159. import tableType1 from './tableType1.vue'
  160. import tableType3 from './tableType3.vue'
  161. import { promotionSave, getRuleDetail, getNewScopeSn } from '@/api/promotion'
  162. import chooseProductsModal from './chooseProductsModal.vue'
  163. export default {
  164. name: 'PromotionListBasicInfoModal',
  165. mixins: [commonMixin],
  166. components: { VSelect, tableType1, tableType3, chooseProductsModal },
  167. props: {
  168. openModal: { // 弹框显示状态
  169. type: Boolean,
  170. default: false
  171. },
  172. promotionSn: {
  173. type: [Number, String],
  174. default: ''
  175. },
  176. itemSn: {
  177. type: [Number, String],
  178. default: ''
  179. }
  180. },
  181. data () {
  182. return {
  183. isShow: this.openModal, // 是否打开弹框
  184. spinning: false,
  185. formItemLayout: {
  186. labelCol: { span: 4 },
  187. wrapperCol: { span: 17 }
  188. },
  189. form: {
  190. promotionRuleType: 'PROMO_PROD', // 特价产品
  191. description: '',
  192. gateFlag: '0', // 门槛
  193. gateType: undefined,
  194. gateAmount: undefined,
  195. quotaAmount: undefined,
  196. minOrderFlag: '1', // 起订金额
  197. minOrderAmount: undefined,
  198. upperLimitFlag: '1', // 活动经费上限
  199. upperLimitAmount: undefined
  200. },
  201. rules: {
  202. description: [ { required: true, message: '请输入规则简称', trigger: 'blur' } ],
  203. gateFlag: [ { required: true, message: '请选择规则门槛', trigger: 'change' } ],
  204. minOrderFlag: [{ required: true, message: '请选择订单起订金额', trigger: 'change' }],
  205. upperLimitFlag: [{ required: true, message: '请选择活动经费上限', trigger: 'change' }]
  206. },
  207. chooseVal: 'a',
  208. openProductsModal: false,
  209. chooseProducts: []
  210. }
  211. },
  212. methods: {
  213. // 门槛产品
  214. handleChange (e) {
  215. if (e.target.value == '1') {
  216. this.chooseVal = 'a'
  217. } else {
  218. this.chooseVal = 'd'
  219. }
  220. },
  221. // 保存
  222. handleSave () {
  223. const _this = this
  224. this.$refs.ruleForm.validate(valid => {
  225. if (valid) {
  226. // 验证必填
  227. if (_this.form.gateFlag == '1') {
  228. if (!_this.form.gateAmount || !_this.form.quotaAmount) {
  229. _this.$message.warning('规则门槛条件不能为空!')
  230. return
  231. }
  232. }
  233. if (_this.form.minOrderFlag == 1 && !_this.form.minOrderAmount) {
  234. _this.$message.warning('请输入订单起订限制金额数!')
  235. return
  236. }
  237. if (_this.form.upperLimitFlag == 1 && !_this.form.upperLimitAmount) {
  238. _this.$message.warning('请输入活动经费上限金额!')
  239. return
  240. }
  241. const form = JSON.parse(JSON.stringify(_this.form))
  242. if (form.gateFlag == '1') {
  243. form.gateProductList = _this.$refs.cillProduct.getResultVal()
  244. } else {
  245. form.gateProductList = []
  246. }
  247. form.specialProductList = _this.$refs.specialProduct.getResultVal()
  248. form.promotionSn = _this.promotionSn
  249. _this.spinning = true
  250. promotionSave(form).then(res => {
  251. if (res.status == 200) {
  252. _this.$message.success(res.message)
  253. setTimeout(() => {
  254. _this.isShow = false
  255. _this.$emit('ok')
  256. _this.spinning = false
  257. }, 1000)
  258. } else {
  259. _this.spinning = false
  260. }
  261. })
  262. } else {
  263. return false
  264. }
  265. })
  266. },
  267. // 重置表格
  268. resetSearchForm () {
  269. this.form = {
  270. promotionRuleType: 'PROMO_PROD', // 特价产品
  271. description: '',
  272. gateFlag: '0', // 门槛
  273. gateType: undefined,
  274. gateAmount: undefined,
  275. quotaAmount: undefined,
  276. minOrderFlag: '1', // 起订金额
  277. minOrderAmount: undefined,
  278. upperLimitFlag: '1', // 活动经费上限
  279. upperLimitAmount: undefined,
  280. gateProductList: undefined,
  281. specialProductList: undefined
  282. }
  283. this.$nextTick(() => {
  284. this.$refs.ruleForm.resetFields()
  285. this.$refs.cillProduct.reSetTableData()
  286. this.$refs.specialProduct.reSetTableData()
  287. })
  288. },
  289. // 获取编辑详情
  290. getDetail () {
  291. const _this = this
  292. getRuleDetail({ sn: this.itemSn }).then(res => {
  293. if (res.status == 200) {
  294. this.chooseVal = res.data.gateFlag == '0' ? 'd' : 'a'
  295. const resultObj = res.data
  296. // 重新组成保存数据
  297. if (resultObj.gateProductList && resultObj.gateProductList.length > 0) {
  298. resultObj.gateProductList = _this.newData(resultObj.gateProductList)
  299. this.$refs.cillProduct.setTabVal(resultObj.gateProductList)
  300. }
  301. if (resultObj.specialProductList && resultObj.specialProductList.length > 0) {
  302. resultObj.specialProductList = _this.newData(resultObj.specialProductList)
  303. this.$refs.specialProduct.setSourceData(resultObj.specialProductList)
  304. }
  305. this.form = { ...this.form, ...resultObj }
  306. }
  307. })
  308. },
  309. newData (list) {
  310. list.forEach(con => {
  311. // 品牌
  312. if (con.productBrandList) {
  313. const brandList = []
  314. con.productBrandList.forEach(item => {
  315. item.brandName = item.productBrandName
  316. const brandObj = {
  317. productBrandSn: item.productBrandSn
  318. }
  319. brandList.push(brandObj)
  320. })
  321. con.productBrandArr = con.productBrandList
  322. con.productBrandList = brandList
  323. }
  324. // 分类
  325. if (con.productTypeList) {
  326. const typeList = []
  327. con.productTypeList.forEach(item => {
  328. const typeObj = {}
  329. item.title = ''
  330. const num = 3
  331. for (var i = 0; i < num; i++) {
  332. if (item['productTypeName' + (i + 1)]) {
  333. item.title += item['productTypeName' + (i + 1)] + (item['productTypeName' + (i + 1)] ? '/' : '')
  334. typeObj['productTypeSn' + (i + 1)] = item['productTypeSn' + (i + 1)] ? item['productTypeSn' + (i + 1)] : ''
  335. }
  336. }
  337. item.title = item.title.slice(0, item.title.length - 1)
  338. item.id = item.productTypeSn3 ? item.productTypeSn3 : item.productTypeSn2 ? item.productTypeSn2 : item.productTypeSn1
  339. typeList.push(typeObj)
  340. })
  341. con.productTypeArr = con.productTypeList
  342. con.productTypeList = typeList
  343. }
  344. // 产品
  345. if (con.productThisList) {
  346. const productList = []
  347. con.productThisList.forEach(item => {
  348. const productObj = {
  349. productCode: item.productCode,
  350. productSn: item.productSn
  351. }
  352. productList.push(productObj)
  353. })
  354. con.productThisList = productList
  355. }
  356. })
  357. return list
  358. },
  359. // +新增产品
  360. handleProductsOk (con) {
  361. const chooseProductsList = []
  362. const _this = this
  363. con.forEach(item => {
  364. getNewScopeSn({}).then(res => {
  365. if (res.status == 200) {
  366. const newData = {
  367. productScopeSn: res.data,
  368. dataSourceOrigin: '1',
  369. productTypeArr: [],
  370. productTypeList: [],
  371. productBrandArr: [{ brandSn: item.productBrandSn, brandName: item.productBrandName }],
  372. productBrandList: [{ brandSn: item.productBrandSn }],
  373. productThisList: [{
  374. productSn: item.productSn,
  375. productCode: item.code
  376. }],
  377. provincePrice: item.provincePrice,
  378. cityPrice: item.cityPrice,
  379. specialPrice: item.specialPrice
  380. }
  381. const obj = {}
  382. if (item.productTypeSn1) {
  383. obj.productType1 = item.productTypeSn1
  384. }
  385. if (item.productTypeSn2) {
  386. obj.productType2 = item.productTypeSn2
  387. }
  388. if (item.productTypeSn3) {
  389. obj.productType3 = item.productTypeSn3
  390. }
  391. const newObj = { ...obj, ...{} }
  392. if (Object.keys(obj).length == 1) {
  393. newObj.title = item.productTypeName1
  394. newObj.id = item.productTypeSn1
  395. } else if (Object.keys(obj).length == 2) {
  396. newObj.title = item.productTypeName1 + '/' + item.productTypeName2
  397. newObj.id = item.productTypeSn2
  398. } else {
  399. newObj.title = item.productTypeName1 + '/' + item.productTypeName2 + '/' + item.productTypeName3
  400. newObj.id = item.productTypeSn3
  401. }
  402. newData.productTypeList[0] = obj
  403. newData.productTypeArr[0] = newObj
  404. chooseProductsList.push(newData)
  405. _this.$refs.specialProduct.setSourceData(chooseProductsList)
  406. }
  407. })
  408. })
  409. }
  410. },
  411. watch: {
  412. // 父页面传过来的弹框状态
  413. openModal (newValue, oldValue) {
  414. this.isShow = newValue
  415. },
  416. // 重定义的弹框状态
  417. isShow (newValue, oldValue) {
  418. if (!newValue) {
  419. this.$emit('close')
  420. this.resetSearchForm()
  421. } else {
  422. if (this.itemSn) {
  423. this.getDetail()
  424. } else {
  425. this.chooseVal = this.form.gateFlag == '0' ? 'd' : 'a'
  426. }
  427. }
  428. }
  429. }
  430. }
  431. </script>
  432. <style lang="less" scoped>
  433. .promotionList-basicInfo-modal{
  434. /deep/.ant-modal-body {
  435. padding: 40px 40px 24px;
  436. max-height: 745px !important;
  437. overflow-y: scroll !important;
  438. }
  439. .ant-radio-button-wrapper{
  440. width:80px;
  441. text-align: center;
  442. }
  443. .ant-form-item{
  444. margin-bottom:5px;
  445. }
  446. .buyerBox{
  447. border:1px solid #d9d9d9;margin-top:10px;border-radius:4px;padding:4px 10px;background:#f2f2f2;max-height:130px;overflow-y:scroll;
  448. }
  449. .btn-cont {
  450. text-align: center;
  451. margin: 35px 0 10px;
  452. }
  453. .flex{
  454. display:flex;
  455. align-items:center;
  456. justify-content:space-between;
  457. }
  458. }
  459. </style>