addAndEdit.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579
  1. <!--
  2. * @Description: 新增/编辑弹框
  3. * @Author: Sugar.
  4. * @Date: 2023-11-24 13:55:00
  5. * @LastEditors: gcz
  6. * @LastEditTime: 2024-03-14 17:48:20
  7. * @FilePath: \great_webui\src\views\marketing\coupon\dialog\addAndEdit.vue
  8. * @Copyright: Copyright (c) 2016~2023 by Sugar., All Rights Reserved.
  9. -->
  10. <template>
  11. <el-dialog
  12. :title="title"
  13. :visible.sync="open"
  14. width="750px"
  15. append-to-body
  16. :close-on-click-modal="false"
  17. @close="cancel"
  18. >
  19. <div class="dialog">
  20. <el-form :model="form" ref="form" :rules="rules" label-width="100px">
  21. <el-form-item label="使用剧目" prop="usePerform" required>
  22. <el-select v-model="form.usePerform" @change="performChange" placeholder="请选择使用剧目">
  23. <el-option
  24. v-for="dict in performList"
  25. :key="dict.value"
  26. :label="dict.label"
  27. :value="dict.value"
  28. ></el-option>
  29. </el-select>
  30. </el-form-item>
  31. <el-form-item label="优惠劵名称" prop="couponName" required>
  32. <el-input
  33. v-model="form.couponName"
  34. placeholder="优惠劵名称"
  35. clearable
  36. style="width: 100%;"
  37. />
  38. </el-form-item>
  39. <el-form-item label="优惠劵类型" prop="type" required>
  40. <el-radio v-model="form.type" :label="1">满减券</el-radio>
  41. <el-radio v-model="form.type" :label="2">折扣券</el-radio>
  42. </el-form-item>
  43. <el-form-item label="使用门槛" prop="useThresholdType" required>
  44. <el-radio v-model="form.useThresholdType" :label="1">无条件</el-radio>
  45. <el-radio v-model="form.useThresholdType" :label="2">指定条件</el-radio>
  46. </el-form-item>
  47. <el-form-item label="优惠额度" prop="quota" required>
  48. <el-input placeholder="优惠额度" v-model="form.quota">
  49. <template slot="append">
  50. <span v-if="form.type==1">元</span>
  51. <span v-if="form.type==2">%</span>
  52. </template>
  53. </el-input>
  54. </el-form-item>
  55. <el-form-item v-if="form.useThresholdType==2" label="累计消费满" prop="useThresholdAmount" required>
  56. <el-input placeholder="" v-model="form.useThresholdAmount">
  57. <template slot="append">元</template>
  58. </el-input>
  59. </el-form-item>
  60. <el-form-item label="使用对象" prop="useUserType" required>
  61. <el-radio-group v-model="form.useUserType" :disabled ="isDisabled" @input="handleChange">
  62. <el-radio :label="1">所有用户</el-radio>
  63. <el-radio :label="2">指定分销商</el-radio>
  64. </el-radio-group>
  65. </el-form-item>
  66. <el-form-item v-if="form.useUserType==2" label="选择分销商:" prop="useUserId" key="useUserId" required>
  67. <el-select
  68. v-model="form.useUserId"
  69. filterable
  70. multiple
  71. remote
  72. reserve-keyword
  73. clearable
  74. placeholder="请输入关键词进行查询"
  75. :remote-method="getOptions"
  76. :loading="isLoading"
  77. style="width: 80%;margin-right: 5px;"
  78. >
  79. <el-option
  80. v-for="item in options"
  81. :key="item.id"
  82. :label="item.name"
  83. :value="item.id">
  84. </el-option>
  85. </el-select>
  86. <el-button v-if="form.useUserId.length == 0" type="primary" @click="allUser">全选</el-button>
  87. <el-button v-else @click="cancelSelected">取消选择</el-button>
  88. </el-form-item>
  89. <el-form-item label="发放渠道" prop="channelType" key="channelType" required>
  90. <el-select v-model="form.channelType" :disabled ="isDisabled" placeholder="请选择发放渠道">
  91. <el-option
  92. v-for="dict in channelTypeList"
  93. :key="dict.value"
  94. :label="dict.label"
  95. :value="dict.value"
  96. ></el-option>
  97. </el-select>
  98. </el-form-item>
  99. <!-- <el-form-item label="使用票务" prop="useGood" required>
  100. <el-select v-model="form.useGood" multiple placeholder="请选择使用票务">
  101. <el-option
  102. v-for="dict in goodsList"
  103. :key="dict.goodsId"
  104. :label="dict.goodsName"
  105. :value="dict.goodsId"
  106. ></el-option>
  107. </el-select>
  108. </el-form-item> -->
  109. <el-form-item label="发放数量" prop="issuseNum" required>
  110. <el-input placeholder="" v-model="form.issuseNum" @change="changeNumber('issuseNum')">
  111. <template slot="append">张</template>
  112. </el-input>
  113. </el-form-item>
  114. <!-- <el-form-item label="是否叠加" prop="isAdd" required>
  115. <el-radio v-model="form.isAdd" :label="1">否</el-radio>
  116. <el-radio v-model="form.isAdd" :label="2">是</el-radio>
  117. </el-form-item> -->
  118. <el-form-item label="领取限制" prop="receiveType" required>
  119. <el-radio-group v-model="form.receiveType">
  120. <el-radio :label="1">否</el-radio>
  121. <el-radio :label="2">是</el-radio>
  122. </el-radio-group>
  123. </el-form-item>
  124. <el-form-item v-if="form.receiveType==2" label="领取限制数量" prop="receiveNum" required>
  125. <el-input placeholder="" v-model="form.receiveNum" @change="changeNumber('issuseNum')">
  126. <template slot="append">张</template>
  127. </el-input>
  128. </el-form-item>
  129. <el-form-item label="使用时间" prop="useType" required>
  130. <el-radio-group v-model="form.useType" :disabled="isDisabled">
  131. <el-radio v-model="form.useType" :label="1">指定时间</el-radio>
  132. <el-radio v-model="form.useType" :label="2">领用后开始计算</el-radio>
  133. </el-radio-group>
  134. </el-form-item>
  135. <el-form-item v-if="form.useType==1" label="指定时间" prop="useStartDate" required>
  136. <el-date-picker
  137. @change="useStartDateChange"
  138. v-model="form.useDate"
  139. value-format="yyyy-MM-dd HH:mm:ss"
  140. type="datetimerange"
  141. range-separator="至"
  142. start-placeholder="开始日期"
  143. end-placeholder="结束日期">
  144. </el-date-picker>
  145. </el-form-item>
  146. <el-form-item v-if="form.useType==2" label="领用后开始计算" prop="useDay" required>
  147. <el-input placeholder="领取后优惠券有效使用时间" :disabled="isDisabled" v-model="form.useDay">
  148. <template slot="append">小时</template>
  149. </el-input>
  150. </el-form-item>
  151. </el-form>
  152. </div>
  153. <span slot="footer" class="dialog-footer">
  154. <el-button @click="cancel">取消</el-button>
  155. <el-button
  156. type="primary"
  157. @click="submitForm"
  158. v-loading.fullscreen.lock="loading"
  159. element-loading-text="提交中..."
  160. element-loading-spinner="el-icon-loading"
  161. element-loading-background="rgba(0, 0, 0, 0.8)"
  162. >
  163. <span v-if="loading">提交中...</span>
  164. <span v-else>保存</span>
  165. </el-button>
  166. </span>
  167. </el-dialog>
  168. </template>
  169. <script>
  170. // import { updateNoticeMgr } from "@/api/system/noticeMgr";
  171. import { saveAndEdit, pageTableList } from "@/api/coupon/coupon";
  172. import { goodsPageList } from "@/api/programmeMr/programmeMr";
  173. import { pageList } from '@/api/ticketMr/ticketMr'
  174. // import { tr } from "voca";
  175. // import { getToken } from "@/utils/auth";
  176. // import { log } from 'mathjs';
  177. export default {
  178. name: "addAndEdit",
  179. props: {
  180. dict: {
  181. type: Object,
  182. default: () => [],
  183. },
  184. },
  185. components: {
  186. },
  187. data() {
  188. return {
  189. title: "编辑",
  190. model: "EDIT",
  191. activeName: '01',
  192. open: false,
  193. loading: false,
  194. form: {
  195. id: undefined,
  196. },
  197. rules: {
  198. couponName: [{ required: true, message: "请输入优惠劵名称", trigger: ["change","blur"] }],
  199. type: [{ required: true, message: "请选择优惠劵类型", trigger: ["change","blur"] }],
  200. quota: [{ required: true, message: "请输入优惠额度", trigger: ["change","blur"] }],
  201. useUserType: [{ required: true, message: "请选择使用对象", trigger: ["change","blur"] }],
  202. usePerform: [
  203. { required: true, message: "请选择使用剧目", trigger: ["change","blur"] },
  204. ],
  205. useUserId:[{ required: true, message: "请选择分销商", trigger: ["change","blur"] }],
  206. // useGood : [{ required: true, message: "请选择使用票务", trigger: ["change","blur"] }],
  207. useThresholdType: [{ required: true, message: "请选择使用门槛", trigger: ["change","blur"] }],
  208. useThresholdAmount: [{ required: true, message: "请输入累计消费满", trigger: ["change","blur"] }],
  209. channelType : [{ required: true, message: "请选择发放渠道", trigger: ["change","blur"] }],
  210. issuseNum : [{ required: true, message: "请输入发放数量", trigger: ["change","blur"] }],
  211. isAdd : [{ required: true, message: "请选择是否叠加", trigger: ["change","blur"] }],
  212. receiveType : [{ required: true, message: "请选择是否限制", trigger: ["change","blur"] }],
  213. receiveNum : [{ required: true, message: "请输入领取限制数量", trigger: ["change","blur"] }],
  214. useType : [{ required: true, message: "请选择使用时间", trigger: ["change","blur"] }],
  215. useStartDate : [{ required: true, message: "请选择指定时间", trigger: ["change","blur"] }],
  216. useDay : [{ required: true, message: "请输入有效天数", trigger: ["change","blur"] }],
  217. },
  218. channelTypeList:[
  219. { label: '小程序', value: 1 },
  220. { label: '分销', value: 2 },
  221. ],
  222. performList:[],
  223. goodsList:[],
  224. options: [],
  225. timer: null,
  226. isLoading: null,
  227. // rowId: [],
  228. isDisabled: false,
  229. dataList: [],
  230. };
  231. },
  232. created() {
  233. this.getPerformList();
  234. this.getGoodsList();
  235. },
  236. methods: {
  237. /**
  238. * 打开弹框
  239. * @date 2023-11-22
  240. * @param {any} obj
  241. * @returns {any}
  242. */
  243. openDialog(title, obj) {
  244. this.open = true;
  245. this.reset();
  246. this.getOptions();
  247. this.isDisabled = true
  248. if (obj){
  249. this.title = "编辑优惠券";
  250. this.$nextTick(() => {
  251. console.log(obj,'4444');
  252. // if(obj.useUserId) {
  253. // this.rowId = obj.useUserId.split(",");
  254. // } else {
  255. // this.rowId = []
  256. // }
  257. // this.$set(this.form, 'useUserId', this.rowId);
  258. this.$set(this.form, 'useUserId', obj.useUserId);
  259. if(obj.useUserId) {
  260. this.form.useUserId = this.getGoodsIds(this.form.useUserId);
  261. } else {
  262. this.form.useUserId = []
  263. }
  264. obj.useUserType == 2 ? this.isDisabled = true: this.isDisabled = false;
  265. this.$set(this.form, 'useUserType', obj.useUserType);
  266. this.$set(this.form, 'id', obj.id);
  267. this.$set(this.form, 'couponName', obj.couponName);
  268. this.$set(this.form, 'type', obj.type);
  269. this.$set(this.form, 'quota', obj.quota);
  270. this.$set(this.form, 'usePerform', obj.usePerform);
  271. this.$set(this.form, 'useThresholdType', obj.useThresholdType);
  272. this.$set(this.form, 'useThresholdAmount', obj.useThresholdAmount);
  273. this.$set(this.form, 'channelType', obj.channelType);
  274. this.$set(this.form, 'issuseNum', obj.issuseNum);
  275. this.$set(this.form, 'isAdd', obj.isAdd);
  276. this.$set(this.form, 'receiveType', obj.receiveType);
  277. this.$set(this.form, 'receiveNum', obj.receiveNum);
  278. this.$set(this.form, 'useType', obj.useType);
  279. this.$set(this.form, 'useStartDate', obj.useStartDate);
  280. this.$set(this.form, 'useEndDate', obj.useEndDate);
  281. this.$set(this.form, 'useDay', obj.useDay);
  282. this.$set(this.form, 'useDate', [obj.useStartDate, obj.useEndDate]);
  283. this.performChange(obj.usePerform);
  284. this.$set(this.form, 'useGood', '');
  285. // this.$set(this.form, 'useGood', obj.useGood);
  286. //this.form.useGood= this.getGoodsIds(this.form.useGood);
  287. });
  288. } else {
  289. this.title = "新增优惠券";
  290. this.$set(this.form, 'useUserType', 2);
  291. this.$set(this.form, 'channelType', 2);
  292. this.$set(this.form, 'useType', 2);
  293. this.$set(this.form, 'useDay', '24');
  294. this.$set(this.form, 'useUserId', []);
  295. }
  296. this.$nextTick(() => {
  297. this.$refs["form"].clearValidate();
  298. });
  299. },
  300. // 获取分销票档
  301. getGoodsList() {
  302. // this.loading = true;
  303. let query ={
  304. pageNum: 1,
  305. pageSize: 999,
  306. goodsType: 2,
  307. classifyId: 1,
  308. channelType: 'retail'
  309. }
  310. pageList(query).then(response => {
  311. let resArr = response.data.rows || [];
  312. if(resArr.length > 0){
  313. this.dataList = resArr.filter(ele => ele.status == 0)
  314. } else {
  315. this.dataList = []
  316. }
  317. }
  318. );
  319. },
  320. /** 查询团队列表 */
  321. getOptions(value) {
  322. // if(!value) {
  323. // this.options = []
  324. // return
  325. // }
  326. if(this.timer) {
  327. clearTimeout(this.timer)
  328. }
  329. this.timer = setTimeout(()=>{
  330. this.isLoading = true;
  331. this.options = []
  332. pageTableList({
  333. pageNum: 1,
  334. pageSize: 999,
  335. name: value,
  336. status: 1
  337. })
  338. .then(response => {
  339. // let teamArr = response.data.rows || []
  340. // if(teamArr.length != 0) {
  341. // this.options = teamArr.filter(ele => ele.id != this.rowId)
  342. // } else {
  343. // this.options = []
  344. // }
  345. this.options = response.data.rows || []
  346. this.isLoading = false;
  347. }
  348. ).catch(()=>{
  349. this.options = []
  350. this.isLoading = false;
  351. })
  352. },1000)
  353. },
  354. // 全选 分销商
  355. allUser(){
  356. if(this.options.length != 0){
  357. let ids = this.options.map(ele => ele.id)|| [];
  358. console.log(ids,'ids');
  359. this.$set(this.form, 'useUserId', ids);
  360. }
  361. },
  362. // 取消全选 分销商
  363. cancelSelected() {
  364. this.$set(this.form, 'useUserId', []);
  365. },
  366. // 使用对象切换
  367. handleChange(val) {
  368. if(val == 2) {
  369. this.$set(this.form, 'channelType', 2);
  370. this.$set(this.form, 'useType', 2);
  371. this.$set(this.form, 'useDay', '24');
  372. // this.form.channelType = 2;
  373. // this.form.useType = 2
  374. // this.form.useDay = 24
  375. this.isDisabled = true
  376. } else {
  377. // this.form.channelType = 1;
  378. // this.form.useType = 1
  379. this.$set(this.form, 'useUserId', []);
  380. this.$set(this.form, 'channelType', 1);
  381. this.$set(this.form, 'useType', 1);
  382. this.$set(this.form, 'useDay', '');
  383. this.isDisabled = false
  384. }
  385. },
  386. getGoodsIds(data, type) {
  387. if (type == "array") {
  388. let array = data.join(",")
  389. return array
  390. } else {
  391. let string = data.split(",");
  392. return string
  393. }
  394. },
  395. changeNumber(key) {
  396. if(this.form[key] * 1 < 1){
  397. this.$message.error("输入需大于或等于1!");
  398. this.$set(this.form, key, '');
  399. return false
  400. }
  401. },
  402. /**
  403. * 保存
  404. * @date 2023-11-22
  405. * @returns {any}
  406. */
  407. submitForm() {
  408. delete this.form.useDate;
  409. this.$refs["form"].validate(async (valid) => {
  410. if (valid) {
  411. try {
  412. this.loading = true;
  413. let params = JSON.parse(JSON.stringify(this.form))
  414. params.useUserId = this.form.useUserId.join(",");
  415. // params.useGood = this.getGoodsIds(params.useGood, "array")
  416. console.log(this.form,'this.form');
  417. console.log(params,'params');
  418. const { code } = await saveAndEdit({ ...params });
  419. if (code === 200) {
  420. this.$message.success("操作成功!");
  421. this.$emit("getList");
  422. this.cancel();
  423. }
  424. } catch (error) {
  425. } finally {
  426. this.loading = false;
  427. }
  428. }
  429. });
  430. },
  431. /**
  432. * 重置
  433. * @date 2023-11-22
  434. * @returns {any}
  435. */
  436. reset() {
  437. this.$set(this.form, 'id', '');
  438. this.$set(this.form, 'couponName', '');
  439. this.$set(this.form, 'type', '');
  440. this.$set(this.form, 'quota', '');
  441. this.$set(this.form, 'useUserType', 1);
  442. this.$set(this.form, 'usePerform', '');
  443. this.$set(this.form, 'useGood', '');
  444. this.$set(this.form, 'useThresholdType', '');
  445. this.$set(this.form, 'useThresholdAmount', '');
  446. this.$set(this.form, 'channelType', 1);
  447. this.$set(this.form, 'issuseNum', '');
  448. this.$set(this.form, 'isAdd', '');
  449. this.$set(this.form, 'receiveType', '');
  450. this.$set(this.form, 'receiveNum', '');
  451. this.$set(this.form, 'useType', '');
  452. this.$set(this.form, 'useStartDate', '');
  453. this.$set(this.form, 'useEndDate', '');
  454. this.$set(this.form, 'useDay', '');
  455. this.$set(this.form, 'useDate', '');
  456. },
  457. /**
  458. * 关闭弹框
  459. * @date 2023-11-22
  460. * @returns {any}
  461. */
  462. cancel() {
  463. this.reset();
  464. this.open = false;
  465. },
  466. /** 查询剧目列表 */
  467. getPerformList() {
  468. goodsPageList({status:1,pageNum:1,pageSize:999})
  469. .then(response => {
  470. this.performList = response.data.rows.map(item => {return {label:item.name,value:item.id,goodsList:item.goodsList}});
  471. }
  472. );
  473. },
  474. performChange(e){
  475. // console.log('performChange',e);
  476. // console.log('this.performList',this.performList);
  477. // this.$set(this.form, 'useGood', '');
  478. console.log('performChange',e);
  479. let goodsList = this.performList.filter(item => {return item.value == e})[0].goodsList;
  480. if(this.dataList.length != 0) {
  481. this.dataList.forEach(j => {
  482. if(j.id) {
  483. j.goodsId = j.id
  484. }
  485. // if(j.name) {
  486. // j.goodsName = j.name
  487. // }
  488. })
  489. this.goodsList = this.getMergedCommonById(goodsList, this.dataList, 'goodsId');
  490. } else {
  491. this.goodsList = [];
  492. }
  493. // this.goodsList = goodsList;
  494. // console.log('useGood',this.form.useGood);
  495. // this.$set(this.form, 'useGood', null);
  496. this.$set(this.form, 'useGood', '');
  497. },
  498. /**
  499. * 从两个数组中找出 id 相同的对象,并合并它们
  500. * @param {Array} arr1 - 第一个对象数组
  501. * @param {Array} arr2 - 第二个对象数组
  502. * @param {string} [idKey='id'] - 用作唯一标识的字段名,默认是 'id'
  503. * @returns {Array} 合并后的结果数组
  504. */
  505. getMergedCommonById(arr1, arr2, idKey = 'id') {
  506. // 容错处理:确保传入的是数组
  507. if (!Array.isArray(arr1)) arr1 = [];
  508. if (!Array.isArray(arr2)) arr2 = [];
  509. // 构建 Set 存储 arr2 中所有的 id
  510. const idSetInArr2 = new Set(
  511. arr2.filter(obj => obj && typeof obj === 'object' && idKey in obj)
  512. .map(obj => obj[idKey])
  513. );
  514. // 找出 arr1 中 id 在 arr2 中也存在的对象
  515. const commonInArr1 = arr1.filter(obj =>
  516. obj && typeof obj === 'object' && idSetInArr2.has(obj[idKey])
  517. );
  518. // 构建 Map 来快速查找 arr2 中的数据
  519. const mapInArr2 = new Map();
  520. arr2.forEach(obj => {
  521. if (obj && typeof obj === 'object' && idKey in obj) {
  522. mapInArr2.set(obj[idKey], obj);
  523. }
  524. });
  525. // 合并数据
  526. return commonInArr1.map(obj => {
  527. const match = mapInArr2.get(obj[idKey]);
  528. return match ? { ...obj, ...match } : obj;
  529. });
  530. },
  531. useStartDateChange(e){
  532. // console.log('useStartDateChange',e);
  533. // console.log('useStartDate',this.form.useDate);
  534. this.form.useStartDate = e[0];
  535. this.form.useEndDate = e[1];
  536. console.log(' this.form.useStartDate', this.form.useStartDate);
  537. }
  538. },
  539. };
  540. </script>
  541. <style lang="scss" scoped>
  542. .dialog {
  543. padding: 0 30px;
  544. max-height: 65vh;
  545. overflow-y: auto;
  546. }
  547. .dialog {
  548. padding: 0 30px;
  549. .upload-btn {
  550. width: 100px;
  551. height: 100px;
  552. background-color: #fbfdff;
  553. border: dashed 1px #c0ccda;
  554. border-radius: 5px;
  555. i {
  556. font-size: 30px;
  557. margin-top: 20px;
  558. }
  559. &-text {
  560. margin-top: -10px;
  561. }
  562. }
  563. .avatar {
  564. cursor: pointer;
  565. }
  566. }
  567. </style>