edit.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492
  1. <!-- eslint-disable space-before-function-paren -->
  2. <!-- eslint-disable space-before-function-paren -->
  3. <template>
  4. <div ref="scrollDiv" class="app-container">
  5. <div v-if="editType === 'add'" class="filter-container">
  6. <div class="filter-control">
  7. <span style="color: red">
  8. 在本页面,对每三个月给超级会员自动发放的优惠券进行配置,配置完成后下一阶段才生效(最少配置1个,最多5个)。
  9. </span>
  10. <el-button type="primary" icon="el-icon-plus" size="mini" :disabled="disabled" @click="handleAddList">
  11. 新增优惠券
  12. </el-button>
  13. </div>
  14. </div>
  15. <div v-else class="filter-container">
  16. <div class="filter-control">
  17. <span>优惠月份:</span>
  18. <el-input
  19. v-model="formParams.month"
  20. placeholder="开始月份"
  21. clearable
  22. suffix-icon="el-icon-date"
  23. :disabled="true"
  24. style="width: 100px"
  25. />
  26. -
  27. <el-input
  28. v-model="formParams.endMonth"
  29. placeholder="结束月份"
  30. clearable
  31. suffix-icon="el-icon-date"
  32. :disabled="true"
  33. style="width: 100px"
  34. />
  35. <el-button
  36. type="primary"
  37. icon="el-icon-plus"
  38. size="mini"
  39. :disabled="disabled"
  40. style="margin-left: 30px"
  41. @click="handleAddList"
  42. >
  43. 新增优惠券
  44. </el-button>
  45. </div>
  46. </div>
  47. <el-form ref="couponFrom" :model="form" label-width="100px">
  48. <div v-for="(formItem, index) in form.formList" :key="formItem.key" class="form-cell" :data-key="formItem.key">
  49. <el-form-item :label="`优惠券${index + 1}:`" style="margin-bottom: 10px" :rules="rules.couponType">
  50. <el-radio-group v-model="formItem.couponType">
  51. <el-radio :label="0">活动券</el-radio>
  52. <el-radio :label="1">品类券</el-radio>
  53. <el-radio :label="3">店铺券</el-radio>
  54. </el-radio-group>
  55. </el-form-item>
  56. <template v-if="formItem.couponType === 3">
  57. <el-form-item label="供应商" :prop="`formList.${index}.shopData`" :rules="rules.shopData">
  58. <template v-if="formItem.shopData && formItem.shopData.length === 0">
  59. <el-button
  60. type="primary"
  61. autofocussize="mini"
  62. size="mini"
  63. icon="el-icon-plus"
  64. @click="handleShopDialogVisible(index)"
  65. >
  66. 选择供应商
  67. </el-button>
  68. <el-checkbox-group v-show="false" v-model="formItem.shopData" />
  69. </template>
  70. <template v-else>
  71. <el-table :data="formItem.shopData" border width="1000">
  72. <el-table-column prop="name" label="供应商名称" align="center" width="300" />
  73. <el-table-column prop="sname" label="供应商简称" align="center" width="200" />
  74. <el-table-column prop="linkMan" label="联系人" align="center" width="100" />
  75. <el-table-column prop="contractMobile" label="手机号" align="center" width="150">
  76. <template slot-scope="{ row }">
  77. {{ row.contractMobile ? row.contractMobile : '---' }}
  78. </template>
  79. </el-table-column>
  80. <el-table-column label="操作" align="center">
  81. <el-button type="text" @click="deleteShop(formItem, index)">删除</el-button>
  82. </el-table-column>
  83. </el-table>
  84. </template>
  85. </el-form-item>
  86. </template>
  87. <el-form-item label="优惠券金额:" :prop="`formList.${index}.couponAmount`" :rules="rules.couponAmount">
  88. <el-input v-model="formItem.couponAmount" style="width: 150px" size="mini" />
  89. </el-form-item>
  90. <el-form-item label="优惠条件:" :prop="`formList.${index}.touchPrice`" :rules="rules.touchPrice">
  91. <el-input v-model="formItem.touchPrice" style="width: 220px" size="mini">
  92. <template slot="prepend" style="padding: 0 10px">订单商品总额满:</template>
  93. </el-input>
  94. </el-form-item>
  95. <el-form-item
  96. label="优惠商品:"
  97. :hidden="formItem.couponType === 0 ? false : true"
  98. style="margin-bottom: 10px"
  99. :rules="rules.productType"
  100. >
  101. <el-radio-group v-model="formItem.productType">
  102. <el-radio :label="'1'">全商城商品</el-radio>
  103. <el-radio :label="'2'">指定商品</el-radio>
  104. </el-radio-group>
  105. </el-form-item>
  106. <template v-if="formItem.productType === '2' && formItem.couponType === 0">
  107. <el-form-item label="商品信息" :prop="`formList.${index}.associateList`" :rules="rules.associateList">
  108. <el-button
  109. type="primary"
  110. icon="el-icon-sort"
  111. size="mini"
  112. :disabled="disabled3(formItem.associateList)"
  113. @click="handleOnInputBlur(formItem, index)"
  114. >
  115. 一键排序
  116. </el-button>
  117. <el-button type="primary" icon="el-icon-plus" size="mini" @click="handleGoodDialogVisible(index)">
  118. 添加商品
  119. </el-button>
  120. <el-checkbox-group v-show="false" v-model="formItem.associateList" />
  121. <el-table
  122. v-show="formItem.associateList && formItem.associateList.length > 0"
  123. :data="formItem.associateList"
  124. border
  125. >
  126. <el-table-column property="mainImage" label="商品图片" align="center" width="80">
  127. <template slot-scope="{ row }">
  128. <el-popover placement="top-start" title="" width="180" trigger="hover">
  129. <img :src="row.mainImage" alt="" style="width: 150px; height: 150px" />
  130. <img slot="reference" :src="row.mainImage" alt="" style="width: 30px; height: 30px" />
  131. </el-popover>
  132. </template>
  133. </el-table-column>
  134. <el-table-column property="name" label="商品名称" align="center" />
  135. <el-table-column property="shopName" label="供应商" align="center" />
  136. <el-table-column label="网站状态" align="center" width="80">
  137. <template slot-scope="scope">
  138. <el-switch
  139. v-model="scope.row.pcStatus"
  140. active-color="#1890ff"
  141. inactive-color="#DCDFE6"
  142. active-value="1"
  143. inactive-value="0"
  144. />
  145. </template>
  146. </el-table-column>
  147. <el-table-column label="小程序状态" align="center" width="100">
  148. <template slot-scope="scope">
  149. <el-switch
  150. v-model="scope.row.appletsStatus"
  151. active-color="#1890ff"
  152. inactive-color="#DCDFE6"
  153. active-value="1"
  154. inactive-value="0"
  155. />
  156. </template>
  157. </el-table-column>
  158. <el-table-column label="排序" align="center" width="100">
  159. <template slot-scope="{ row }">
  160. <el-input v-model="row.sort" maxlength="4" minlength="1" />
  161. </template>
  162. </el-table-column>
  163. <el-table-column label="操作" align="center">
  164. <template slot-scope="scope">
  165. <el-button type="text" @click="handleDeletePros(formItem, scope.$index)">删除</el-button>
  166. </template>
  167. </el-table-column>
  168. </el-table>
  169. </el-form-item>
  170. </template>
  171. <el-form-item label="优惠品类:" :hidden="formItem.couponType === 1 ? false : true" :rules="rules.categoryType">
  172. <el-radio-group v-model="formItem.categoryType">
  173. <el-radio :label="'1'">产品</el-radio>
  174. <el-radio :label="'2'">仪器</el-radio>
  175. </el-radio-group>
  176. </el-form-item>
  177. <el-button
  178. class="delete_label"
  179. :disabled="disabled1"
  180. icon="el-icon-delete"
  181. size="mini"
  182. type="danger"
  183. @click="handleDelete(formItem, index)"
  184. >
  185. 删除
  186. </el-button>
  187. </div>
  188. </el-form>
  189. <div class="el-dialog__footer">
  190. <el-button type="primary" @click="onSubmit('couponFrom')">保存</el-button>
  191. </div>
  192. <!-- 供应商弹框 -->
  193. <shop-dialog v-if="dialogShopVisible" ref="shopDialog" @cancel="handleShopCancel" @confirm="handleShopConfirm" />
  194. <!-- 商品弹框 -->
  195. <good-dialog v-if="dialogGoodVisible" ref="goodDialog" @cancel="handleGoodCancel" @confirm="handleGoodConfirm" />
  196. </div>
  197. </template>
  198. <script>
  199. import { svipCoupon, saveVipCoupon, delCoupon } from '@/api/member/member'
  200. import goodDialog from './components/good-dialog'
  201. import shopDialog from './components/shop-dialog'
  202. const defaultForm = () => {
  203. return {
  204. shopId: 0,
  205. shopData: [],
  206. couponType: 0,
  207. couponAmount: '',
  208. touchPrice: '',
  209. productType: '1',
  210. categoryType: '1',
  211. associateList: [] // 指定商品信息
  212. }
  213. }
  214. export default {
  215. name: 'MemberEdit',
  216. components: { goodDialog, shopDialog },
  217. data() {
  218. return {
  219. form: {
  220. formList: []
  221. },
  222. formParams: {
  223. id: '',
  224. month: '',
  225. endMonth: '',
  226. status: '',
  227. configure: 1, // 专属优惠券配置 1是、0否
  228. coupons: []
  229. },
  230. doctorId: '',
  231. editType: 'add',
  232. time: '',
  233. dialogTableVisible: false,
  234. shopTotal: 0,
  235. rows: [],
  236. // 供应商列表
  237. shopTableData: [],
  238. // 商品列表
  239. dialogProductVisible: false,
  240. productTableData: [],
  241. productTotal: 0,
  242. addIndex: 0,
  243. dialogShopVisible: false,
  244. dialogGoodVisible: false,
  245. rules: {
  246. couponType: [{ required: true, message: '请选择优惠券类型', trigger: 'blur' }],
  247. shopId: [{ required: true, message: '请选择供应商', trigger: 'blur' }],
  248. productType: [{ required: true, message: '请选择优惠商品', trigger: 'blur' }],
  249. shopData: [{ required: true, type: 'array', message: '请添加一个供应商', trigger: ['change'] }],
  250. associateList: [{ required: true, type: 'array', message: '请至少添加一个商品', trigger: ['change'] }],
  251. categoryType: [{ required: true, message: '请选择优惠品类', trigger: 'blur' }],
  252. couponAmount: [{ required: true, message: '优惠券金额不能为空', trigger: 'blur' }],
  253. touchPrice: [{ required: true, message: '优惠条件不能为空', trigger: 'blur' }]
  254. },
  255. delFlag: false
  256. }
  257. },
  258. computed: {
  259. disabled() {
  260. return this.form.formList.length === 5
  261. },
  262. disabled1() {
  263. return this.form.formList.length === 1
  264. }
  265. },
  266. created() {
  267. this.editType = this.$route.query.type || 'edit'
  268. console.log('editType', this.editType)
  269. this.initForm(this.editType)
  270. },
  271. methods: {
  272. initForm(type) {
  273. if (type === 'add') {
  274. console.log('add')
  275. this.svipCoupon(type, 1, 0)
  276. } else {
  277. console.log('edit')
  278. this.svipCoupon(type, 0, this.$route.query.id)
  279. }
  280. },
  281. async svipCoupon(type, configure, id) {
  282. const res = await svipCoupon({ id: id, configure: configure })
  283. const data = res.data.svipcouponForm
  284. this.formParams = { ...this.formParams, ...data }
  285. if (data.coupons.length > 0) {
  286. this.delFlag = true
  287. this.form.formList = data.coupons.map((el) => {
  288. if (el.shop) {
  289. el.shopData = []
  290. el.shopData.push(el.shop)
  291. } else {
  292. el.shopData = []
  293. }
  294. return el
  295. })
  296. } else {
  297. for (let i = 0; i <= 2; i++) {
  298. this.form.formList.push(defaultForm())
  299. }
  300. }
  301. },
  302. handleShopDialogVisible(index) {
  303. // 显示选择供应商弹窗
  304. this.addIndex = index
  305. this.dialogShopVisible = true
  306. },
  307. handleGoodDialogVisible(index) {
  308. // 显示选择商品弹窗
  309. this.addIndex = index
  310. this.dialogGoodVisible = true
  311. },
  312. deleteShop(formItem, index) {
  313. // 清除供应商
  314. formItem.shopId = ''
  315. formItem.shopData = []
  316. this.$nextTick(() => {
  317. this.form.formList[index].shopId = ''
  318. this.form.formList[index].shopData = []
  319. })
  320. this.$forceUpdate()
  321. console.log('shopData', this.form.formList)
  322. },
  323. handleShopConfirm(data) {
  324. // 确认选择供应商
  325. this.form.formList[this.addIndex].shopId = data.shopId
  326. this.form.formList[this.addIndex].shopData.push(data)
  327. console.log('formList', this.form.formList[this.addIndex])
  328. this.handleShopCancel()
  329. },
  330. handleGoodConfirm(data) {
  331. // 确认选择商品
  332. console.log('data', data)
  333. console.log('addIndex', this.addIndex)
  334. const from = this.form.formList[this.addIndex]
  335. from.associateList.push(data)
  336. console.log('from', this.form.formList)
  337. this.handleGoodCancel()
  338. },
  339. handleDeletePros(formItem, index) {
  340. // 删除商品
  341. this.$confirm('确定删除吗?', '提示', {
  342. confirmButtonText: '确定',
  343. cancelButtonText: '取消',
  344. type: 'warning'
  345. }).then(() => {
  346. formItem.associateList.splice(index, 1)
  347. })
  348. },
  349. onSubmit(formName) {
  350. this.$refs[formName].validate((valid) => {
  351. if (valid) {
  352. this.handleFormParams()
  353. this.$confirm('是否提交数据', '提示', {
  354. confirmButtonText: '确定',
  355. cancelButtonText: '取消',
  356. type: 'warning'
  357. }).then(() => {
  358. console.log('formParams', this.formParams)
  359. if (this.editType === 'add') {
  360. this.formParams.configure = 1
  361. } else {
  362. this.formParams.configure = 0
  363. }
  364. this.saveVipCoupon(this.formParams)
  365. })
  366. } else {
  367. return false
  368. }
  369. })
  370. },
  371. handleFormParams() {
  372. // 处理参数
  373. this.formParams.coupons = this.form.formList.map((el) => {
  374. if (el.associateList && el.associateList.length > 0) {
  375. el.associateList = el.associateList.map((pro) => {
  376. return {
  377. sort: pro.sort,
  378. pcStatus: pro.pcStatus,
  379. appletsStatus: pro.appletsStatus,
  380. name: pro.name,
  381. shopName: pro.shopName,
  382. mainImage: pro.mainImage,
  383. productId: pro.productId
  384. }
  385. })
  386. }
  387. return el
  388. })
  389. },
  390. async saveVipCoupon(params) {
  391. // 保存超级会员优惠券
  392. await saveVipCoupon(params)
  393. this.$message.success('保存成功')
  394. setTimeout(() => {
  395. this.$router.push({ path: '/member/coupon/list' })
  396. }, 1000)
  397. },
  398. handleShopCancel() {
  399. // 取消选择供应商
  400. this.dialogShopVisible = false
  401. this.$refs.shopDialog.visible = false
  402. },
  403. handleGoodCancel() {
  404. // 取消编辑商品
  405. this.dialogGoodVisible = false
  406. this.$refs.goodDialog.visible = false
  407. },
  408. handleAddList() {
  409. // 新增优惠券
  410. this.form.formList.push(defaultForm())
  411. },
  412. handleDelete(item, index) {
  413. // 删除单挑优惠券
  414. this.$confirm('确定删除此优惠券吗?', '提示', {
  415. confirmButtonText: '确定',
  416. cancelButtonText: '取消',
  417. type: 'warning'
  418. }).then(() => {
  419. if (this.delFlag) {
  420. this.delCoupon(item.id, index)
  421. } else {
  422. this.form.formList.splice(index, 1)
  423. }
  424. })
  425. },
  426. async delCoupon(id, index) {
  427. // 保存超级会员优惠券
  428. if (id) {
  429. try {
  430. await delCoupon(id)
  431. } catch (error) {
  432. console.log(error)
  433. }
  434. }
  435. this.form.formList.splice(index, 1)
  436. },
  437. handleOnInputBlur(formItem) {
  438. // 商品排序
  439. formItem.associateList.sort(this.sortByEnent('sort'))
  440. },
  441. sortByEnent(i) {
  442. // 排序
  443. return function(a, b) {
  444. return a[i] - b[i] // a[i] - b[i]为正序,倒叙为 b[i] - a[i]
  445. }
  446. },
  447. handlePcStatusChange(row) {
  448. // PC状态开启关闭
  449. console.log('row', row)
  450. if (row.pcStatus === '0') {
  451. row.pcStatus = '1'
  452. } else {
  453. row.pcStatus = '0'
  454. }
  455. },
  456. handleAppStatusChange(row) {
  457. // 小程序状态开启关闭
  458. if (row.appletsStatus === '0') {
  459. row.appletsStatus = '1'
  460. } else {
  461. row.appletsStatus = '0'
  462. }
  463. },
  464. disabled3(array) {
  465. if (array && array.length >= 2) {
  466. return false
  467. } else {
  468. return true
  469. }
  470. }
  471. }
  472. }
  473. </script>
  474. <style>
  475. .form-cell {
  476. border: 1px solid #e1e1e1;
  477. border-radius: 8px;
  478. box-sizing: border-box;
  479. box-shadow: 0px 3px 6px 0px rgba(0, 0, 0, 0.07);
  480. padding: 20px;
  481. position: relative;
  482. margin-bottom: 20px;
  483. }
  484. .delete_label {
  485. position: absolute;
  486. right: 2%;
  487. top: 20px;
  488. }
  489. </style>