addAndEdit.vue 20 KB

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