create.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  1. <template>
  2. <div class="app-container">
  3. <div class="base-info">
  4. <div class="base-info-title">基础信息</div>
  5. <!-- 基础信息 -->
  6. <div class="base-info-form">
  7. <el-form :model="form" :rules="rules" ref="form" label-width="100px">
  8. <el-form-item label="盲票类型" prop="type">
  9. <el-radio-group v-model="form.type" size="small">
  10. <el-radio label="online">线上盲票</el-radio>
  11. <el-radio label="offline">线下盲票</el-radio>
  12. </el-radio-group>
  13. </el-form-item>
  14. <el-form-item label="盲票组名称" prop="title">
  15. <el-input
  16. v-model="form.title"
  17. style="width: 587px"
  18. size="small"
  19. placeholder="请输入盲票组名称"
  20. ></el-input>
  21. </el-form-item>
  22. <el-form-item label="图片" prop="picUrl">
  23. <image-upload
  24. v-model="ticketPicUrl"
  25. :limit="1"
  26. :file-size="0.2"
  27. />
  28. </el-form-item>
  29. <div class="tip">
  30. 上传1张图片,支持jpg、png格式上传,大小不超过200k;
  31. </div>
  32. <el-form-item label="面值" prop="facePrice">
  33. <el-input
  34. v-model="form.facePrice"
  35. style="width: 240px"
  36. size="small"
  37. placeholder="请输入面值"
  38. >
  39. <template slot="append">元</template>
  40. </el-input>
  41. </el-form-item>
  42. <el-form-item label="售价" prop="salePrice">
  43. <el-input
  44. v-model="form.salePrice"
  45. style="width: 240px"
  46. size="small"
  47. placeholder="请输入售价"
  48. >
  49. <template slot="append">元</template>
  50. </el-input>
  51. </el-form-item>
  52. <el-form-item label="盲票总数" prop="quantity">
  53. <el-input
  54. v-model="form.quantity"
  55. style="width: 240px"
  56. size="small"
  57. placeholder="请输入盲票总数"
  58. >
  59. <template slot="append">张</template>
  60. </el-input>
  61. </el-form-item>
  62. <el-form-item label="每包张数" prop="pkgUnit">
  63. <el-input
  64. v-model="form.pkgUnit"
  65. style="width: 240px"
  66. size="small"
  67. placeholder="请输入每包张数"
  68. >
  69. <template slot="append">张</template>
  70. </el-input>
  71. </el-form-item>
  72. <el-form-item
  73. label="采购单价"
  74. prop="pkgSalePrice"
  75. v-if="form.type == 'offline'"
  76. >
  77. <el-input
  78. v-model="form.pkgSalePrice"
  79. style="width: 240px"
  80. size="small"
  81. placeholder="请输入采购单价"
  82. >
  83. <template slot="append">元/包</template>
  84. </el-input>
  85. </el-form-item>
  86. <el-form-item label="佣金系数" prop="saleCommRate">
  87. <el-input
  88. v-model="form.saleCommRate"
  89. style="width: 240px"
  90. size="small"
  91. placeholder="请输入佣金系数"
  92. >
  93. <template slot="append">%</template>
  94. </el-input>
  95. </el-form-item>
  96. <div class="tip">
  97. 例如:一张盲票用户支付10元,盲票佣金系数90%,经销商佣金比例20%,那么经销商佣金为10元*90%*20%=1.8元
  98. </div>
  99. </el-form>
  100. </div>
  101. <div class="base-info-title">奖级设置</div>
  102. <!-- 奖级设置 -->
  103. <!-- 奖级列表 -->
  104. <awards-list ref="awards" v-model="awardsList" @handleCommand="handleCommand" @close="close" />
  105. <!-- 保存 -->
  106. <div class="save-btn">
  107. <el-button size="small" @click="back"> 取 消 </el-button>
  108. <div class="ge"></div>
  109. <el-button type="primary" size="small" @click="submitForm">
  110. 保 存
  111. </el-button>
  112. </div>
  113. </div>
  114. <!-- 添加商品 -->
  115. <goods-add :dialog-visible="goodsTableVisible" @close="close" @confirmGoods="confirmGoods" v-if="goodsTableVisible" />
  116. <!-- 添加券 -->
  117. <coupon-add :dialog-visible="couponTableVisible" @close="close" @confirmCoupon="confirmCoupon" v-if="couponTableVisible" />
  118. <!-- 添加盲豆 -->
  119. <coin-add :dialog-visible="coinTableVisible" @close="close" @confirmCoin="confirmCoin" v-if="coinTableVisible" />
  120. </div>
  121. </template>
  122. <script>
  123. import CustomFieldsMixin from "@/mixins/CustomFields";
  124. import { ticketBoxCreate } from "@/api/business/ticket";
  125. import { accMul } from "@/utils/util";
  126. import AwardsList from "./components/AwardsList"
  127. import GoodsAdd from "./components/GoodsAdd"
  128. import CouponAdd from "./components/CouponAdd"
  129. import CoinAdd from "./components/CoinAdd"
  130. export default {
  131. name: "TicketCreate",
  132. mixins: [CustomFieldsMixin],
  133. components: {
  134. AwardsList,
  135. GoodsAdd,
  136. CouponAdd,
  137. CoinAdd,
  138. },
  139. data() {
  140. return {
  141. loading: false,
  142. form: {
  143. type: "online", //盲票类型
  144. title: "", // 盲票名称
  145. picUrl: "", // 图片
  146. facePrice: "", // 面值
  147. salePrice: "", // 售价
  148. quantity: "", // 数量
  149. pkgUnit: 200, // 张数
  150. pkgSalePrice: 0, // 单价
  151. saleCommRate: "", // 基数
  152. },
  153. rules: {
  154. type: [
  155. { required: true, message: "请选择盲票类型", trigger: "change" },
  156. ],
  157. title: [
  158. { required: true, message: "请输入盲票组名称", trigger: "blur" },
  159. ],
  160. picUrl: [
  161. {
  162. required: true,
  163. message: "请上传盲票图片",
  164. trigger: "change",
  165. },
  166. ],
  167. facePrice: [
  168. { required: true, message: "请输入面值", trigger: "blur" },
  169. {
  170. pattern:
  171. /^([1-9]\d*(\.\d{1,2})?|([0](\.([0][1-9]|[1-9]\d{0,1}))))$/,
  172. message: "请输入合法的金额数字,最多两位小数",
  173. trigger: ["blur", "change"],
  174. },
  175. ],
  176. salePrice: [
  177. { required: true, message: "请输入售价", trigger: "blur" },
  178. {
  179. pattern:
  180. /^([1-9]\d*(\.\d{1,2})?|([0](\.([0][1-9]|[1-9]\d{0,1}))))$/,
  181. message: "请输入合法的金额数字,最多两位小数",
  182. trigger: ["blur", "change"],
  183. },
  184. ],
  185. quantity: [
  186. { required: true, message: "请输入数量", trigger: "blur" },
  187. {
  188. pattern: /^([1-9]\d*)$/,
  189. message: "请输入合法的数字",
  190. trigger: ["blur", "change"],
  191. },
  192. ],
  193. pkgUnit: [
  194. { required: true, message: "请输入每包张数", trigger: "blur" },
  195. {
  196. pattern: /^([1-9]\d*)$/,
  197. message: "请输入合法的数字",
  198. trigger: ["blur", "change"],
  199. },
  200. ],
  201. pkgSalePrice: [
  202. { required: true, message: "请输入采购单价", trigger: "blur" },
  203. {
  204. pattern:
  205. /^([1-9]\d*(\.\d{1,2})?|([0](\.([0][1-9]|[1-9]\d{0,1}))))$/,
  206. message: "请输入合法的金额数字,最多两位小数",
  207. trigger: ["blur", "change"],
  208. },
  209. ],
  210. saleCommRate: [
  211. { required: true, message: "请输入分佣基数", trigger: "blur" },
  212. {
  213. pattern:
  214. /^([1-9]\d*(\.\d{1,2})?|([0](\.([0][1-9]|[1-9]\d{0,1}))))$/,
  215. message: "请输入合法的数字,最多两位小数",
  216. trigger: ["blur", "change"],
  217. },
  218. ],
  219. },
  220. // 奖级列表
  221. awardsList: [],
  222. goodsTableVisible: false, // 添加商品弹框
  223. couponTitle: "", // 券名称
  224. couponTableVisible: false, // 添加卡券弹框
  225. coinTableVisible: false, // 添加盲豆弹框
  226. pageParams: {
  227. pageNum: 1,
  228. pageSize: 10,
  229. },
  230. };
  231. },
  232. computed: {
  233. ticketPicUrl: {
  234. get() {
  235. return this.form.picUrl ? this.form.picUrl.split(',').map(item => {
  236. return {
  237. fileName: item
  238. }
  239. }) : []
  240. },
  241. set(val) {
  242. console.log('val', val)
  243. this.$set(this.form, 'picUrl', val.map(item => { return item.fileName }).toString())
  244. }
  245. }
  246. },
  247. methods: {
  248. // 保存
  249. submitForm() {
  250. const subForm = this.$refs["form"];
  251. subForm.validate((valid) => {
  252. if (valid) {
  253. // let prizeIndex = this.awardsList.findIndex((item) => {
  254. // return !item.prizeList.length;
  255. // });
  256. // // 判断没有设置奖品的奖级
  257. // if (prizeIndex != -1) {
  258. // this.$message.error(
  259. // `请设置${this.awardsList[prizeIndex].name}的奖品!`
  260. // );
  261. // return;
  262. // }
  263. let prizeIndex = this.awardsList.findIndex((item) => {
  264. return !item.prizeList.length && item.quantity > 0;
  265. });
  266. // 判断没有设置奖品的奖级
  267. if (prizeIndex != -1) {
  268. this.$message.error(
  269. `请设置${this.awardsList[prizeIndex].name}的奖品!`
  270. );
  271. return;
  272. }
  273. if (this.form.quantity % this.form.pkgUnit != 0) {
  274. this.$message.error("每包数量错误!");
  275. return;
  276. }
  277. let quantityTotal = 0;
  278. this.awardsList.forEach((item) => {
  279. quantityTotal += item.quantity;
  280. });
  281. if (this.form.quantity != quantityTotal) {
  282. this.$message.error("盲票数量和奖品数量不一致!");
  283. return;
  284. }
  285. // if (this.form.saleCommRate > 100) {
  286. // this.$message.error("分佣基数不能大于100!");
  287. // return;
  288. // }
  289. this.awardsList.forEach((item) => {
  290. item.prizeList = item.prizeList.map((ele) => {
  291. return {
  292. ...ele,
  293. refId: ele.goodsId || ele.couponId,
  294. prizeType: ele.prizeType,
  295. quantity: ele.quantity,
  296. value: Number(ele.coinValue),
  297. };
  298. });
  299. });
  300. let filterArr = this.awardsList.filter((item) => {
  301. return item.prizeList.length != 0;
  302. });
  303. let filterArr2 = filterArr.filter((item) => {
  304. return item.quantity != 0;
  305. });
  306. let data = {
  307. ...this.form,
  308. facePrice: accMul(this.form.facePrice, 100),
  309. salePrice: accMul(this.form.salePrice, 100),
  310. pkgSalePrice: accMul(this.form.pkgSalePrice, 100),
  311. awardsList: filterArr2,
  312. };
  313. const loading = this.$loading({
  314. lock: true,
  315. text: "保存中",
  316. spinner: "el-icon-loading",
  317. background: "rgba(0, 0, 0, 0.4)",
  318. });
  319. ticketBoxCreate(data)
  320. .then((res) => {
  321. loading.close();
  322. if (res.code == 0) {
  323. this.msgSuccess("保存成功");
  324. this.$store.dispatch("tagsView/delView", this.$route);
  325. this.$router.go(-1);
  326. }
  327. })
  328. .catch(() => {
  329. loading.close();
  330. });
  331. } else {
  332. this.getFormErrorMessage(subForm);
  333. return false;
  334. }
  335. });
  336. },
  337. // 关闭弹框
  338. close() {
  339. this.goodsTableVisible = false;
  340. this.couponTableVisible = false;
  341. this.coinTableVisible = false;
  342. },
  343. // 添加奖品种类
  344. handleCommand(e) {
  345. if (e == "goods") {
  346. this.goodsTableVisible = true;
  347. } else if (e == "coupon") {
  348. this.couponTableVisible = true;
  349. } else if (e == "coin") {
  350. this.coinTableVisible = true;
  351. }
  352. },
  353. // 确认选中商品
  354. confirmGoods(arr) {
  355. this.$refs.awards.add(1, arr)
  356. },
  357. // 确认选中卡券
  358. confirmCoupon(arr) {;
  359. this.$refs.awards.add(1, arr)
  360. },
  361. // 确认输入盲豆
  362. confirmCoin(obj) {
  363. this.$refs.awards.add(2, obj)
  364. },
  365. // 取消
  366. back() {
  367. this.$store.dispatch("tagsView/delView", this.$route);
  368. this.$router.go(-1);
  369. },
  370. },
  371. };
  372. </script>
  373. <style lang="scss" scoped>
  374. .base-info-title {
  375. padding: 10px;
  376. border-bottom: 1px solid #eaeaea;
  377. margin-bottom: 20px;
  378. }
  379. .tip {
  380. padding-left: 100px;
  381. height: 32px;
  382. margin-bottom: 20px;
  383. color: #828282;
  384. font-size: 14px;
  385. }
  386. .save-btn {
  387. display: flex;
  388. align-content: center;
  389. justify-content: center;
  390. margin-bottom: 100px;
  391. .ge {
  392. width: 100px;
  393. }
  394. }
  395. .prize {
  396. width: 1000px;
  397. margin-bottom: 50px;
  398. background: #f9f9f9;
  399. border: 1px solid #bbbbbb;
  400. font-size: 14px;
  401. &-top {
  402. padding: 10px 20px;
  403. margin-bottom: 10px;
  404. display: flex;
  405. align-content: center;
  406. justify-content: space-around;
  407. border-bottom: 1px solid #bbbbbb;
  408. div {
  409. line-height: 36px;
  410. }
  411. }
  412. &-btn {
  413. border-top: 1px solid #bbbbbb;
  414. padding: 10px;
  415. }
  416. }
  417. .dialog-search {
  418. display: flex;
  419. line-height: 32px;
  420. margin-bottom: 20px;
  421. .ge {
  422. width: 40px;
  423. }
  424. }
  425. .dialog-btn {
  426. display: flex;
  427. align-content: center;
  428. justify-content: flex-end;
  429. padding: 40px 0 0;
  430. .ge {
  431. width: 40px;
  432. }
  433. }
  434. </style>