detail.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426
  1. <template>
  2. <view v-if="!isLoading" class="container b-f p-b">
  3. <view class="base">
  4. <view class="coupon-main">
  5. <view class="left">
  6. <image class="image" :src="detail.image"></image>
  7. </view>
  8. <view class="right">
  9. <view class="item">
  10. <view class="name">{{ detail.name ? detail.name : '' }}</view>
  11. </view>
  12. <view v-if="detail.useRule > 0" class="item">
  13. <view class="amount"><text class="num">{{ detail.useRule }}</text>次卡</view>
  14. </view>
  15. </view>
  16. </view>
  17. <view class="item">
  18. <view class="label">有效期至:</view>
  19. <view>{{ detail.effectiveDate }}</view>
  20. </view>
  21. <view class="item">
  22. <view class="label">适用门店:</view>
  23. <view>{{ detail.storeNames ? detail.storeNames : '全部'}}</view>
  24. </view>
  25. </view>
  26. <view v-if="detail.qrCode" class="coupon-qr">
  27. <view>
  28. <image class="image" :src="detail.qrCode"></image>
  29. </view>
  30. <view class="qr-code">
  31. <p class="code">核销码:{{ detail.code }}</p>
  32. <p class="tips">请出示以上券码给核销人员</p>
  33. </view>
  34. </view>
  35. <view v-if="dataList.length > 0" class="coupon-timer">
  36. <view class="tips">核销记录({{detail.confirmCount}}/{{detail.useRule}})</view>
  37. <uni-row class="time-row" v-for="row in dataList" :key="row.id">
  38. <uni-col :span="rowCount" v-for="item in row.data" :key="item.id" class="time-item">
  39. <view v-if="item.isActive == true">
  40. <view class="time active"></view>
  41. <view class="show-time">{{ item.showTime ? timeStamp(item.showTime) : '' }}</view>
  42. </view>
  43. <view v-else class="time"></view>
  44. </uni-col>
  45. </uni-row>
  46. </view>
  47. <view class="coupon-content m-top20">
  48. <view class="title">使用须知</view>
  49. <view class="content"><jyf-parser :html="detail.description ? detail.description : '暂无...'"></jyf-parser></view>
  50. </view>
  51. <!-- 快捷导航 -->
  52. <shortcut />
  53. <!--领取码 start-->
  54. <view class="receive-pop">
  55. <uni-popup ref="receiveCodePopup" type="dialog">
  56. <uni-popup-dialog mode="input" v-model="receiveCode" focus="false" title="领取码" type="info" placeholder="请输入领取码" :before-close="true" @close="cancelReceive" @confirm="doReceive"></uni-popup-dialog>
  57. </uni-popup>
  58. </view>
  59. <!--领取码 end-->
  60. <!-- 底部选项卡 -->
  61. <view class="footer-fixed">
  62. <view class="footer-container">
  63. <view class="foo-item-btn">
  64. <view class="btn-wrapper">
  65. <view v-if="!detail.code && !detail.isReceive" class="btn-item btn-item-main" @click="receive(detail.id)">
  66. <text>领取次卡</text>
  67. </view>
  68. <view v-if="userCouponId && detail.status != 'D'" class="btn-item btn-item-main" @click="remove(userCouponId)">
  69. <text>删除卡券</text>
  70. </view>
  71. <view v-if="detail.status == 'D'" class="btn-item btn-item-main state">
  72. <text>已删除</text>
  73. </view>
  74. </view>
  75. </view>
  76. </view>
  77. </view>
  78. </view>
  79. </template>
  80. <script>
  81. import jyfParser from '@/components/jyf-parser/jyf-parser'
  82. import Shortcut from '@/components/shortcut'
  83. import * as myCouponApi from '@/api/myCoupon'
  84. import * as couponApi from '@/api/coupon'
  85. export default {
  86. components: {
  87. Shortcut
  88. },
  89. data() {
  90. return {
  91. // 当前会员卡券ID
  92. userCouponId: null,
  93. // 领取码
  94. receiveCode: '',
  95. // 加载中
  96. isLoading: true,
  97. // 当前卡券详情
  98. detail: null,
  99. rowCount: 0,
  100. dataList: []
  101. }
  102. },
  103. /**
  104. * 生命周期函数--监听页面加载
  105. */
  106. onLoad(options) {
  107. this.userCouponId = options.userCouponId ? options.userCouponId : 0;
  108. this.couponId = options.couponId ?options.couponId : 0;
  109. this.getCouponDetail();
  110. },
  111. methods: {
  112. // 获取卡券详情
  113. getCouponDetail() {
  114. const app = this
  115. app.isLoading = false
  116. myCouponApi.detail(app.couponId, app.userCouponId, "")
  117. .then(result => {
  118. app.detail = result.data;
  119. app.detail.confirmCount = app.detail.confirmLogs ? app.detail.confirmLogs.length : 0;
  120. app.getRowCount(app.detail.useRule);
  121. app.getDataList(app.detail.useRule, app.detail.confirmLogs);
  122. })
  123. .finally(() => app.isLoading = false)
  124. },
  125. // 组织数据
  126. getDataList(num, confirmLogs) {
  127. const app = this;
  128. const use = confirmLogs.length;
  129. // 只有一行的情况
  130. if (num <= 4 && num > 0) {
  131. app.dataList = [ { "data": [] } ]
  132. for (let i = 0; i < num; i++) {
  133. app.dataList[0].data.push({ "isActive": (i < use ? true : false), showTime: confirmLogs[i] ? confirmLogs[i].createTime : '' })
  134. }
  135. } else {
  136. let rowCount = Math.ceil(num / 4);
  137. let c = 1;
  138. for (let i = 0; i < rowCount; i++) {
  139. app.dataList[i] = {"data": []}
  140. for (let j = 1; j <= 4; j++) {
  141. if (c <= num) {
  142. let showTime = '';
  143. if (c <= use && confirmLogs[c-1]) {
  144. showTime = confirmLogs[c-1].createTime;
  145. }
  146. app.dataList[i].data.push({ "isActive": (c <= use ? true : false), showTime: showTime });
  147. c++;
  148. }
  149. }
  150. }
  151. }
  152. },
  153. // 计算行数
  154. getRowCount(num) {
  155. if (num < 4 && num > 0) {
  156. this.rowCount = 24 / num;
  157. } else if (num >= 4) {
  158. this.rowCount = 6;
  159. }
  160. },
  161. // 取消领取码
  162. cancelReceive() {
  163. this.receiveCode = '';
  164. this.$refs.receiveCodePopup.close();
  165. },
  166. // 确认领取码
  167. doReceive(vCode) {
  168. if (!vCode || vCode.length < 1) {
  169. this.$error("请先输入领取码!");
  170. return false;
  171. }
  172. this.receiveCode = vCode;
  173. this.$refs.receiveCodePopup.close();
  174. this.receive(this.couponId);
  175. },
  176. // 领取卡券
  177. receive(couponId) {
  178. const app = this;
  179. if (app.detail.needReceiveCode && !app.receiveCode) {
  180. app.$refs.receiveCodePopup.open('top');
  181. return false;
  182. }
  183. couponApi.receive({ 'couponId': couponId, 'receiveCode': app.receiveCode })
  184. .then(result => {
  185. // 显示提示
  186. app.receiveCode = '';
  187. if (parseInt(result.code) === 200) {
  188. app.detail.isReceive = true;
  189. app.$success("领取成功!");
  190. } else {
  191. app.$error(result.message);
  192. }
  193. })
  194. },
  195. // 删除卡券
  196. remove() {
  197. const app = this;
  198. if (app.isLoading == true) {
  199. return false;
  200. }
  201. uni.showModal({
  202. title: "提示",
  203. content: "您确定要删除吗?",
  204. success({ confirm }) {
  205. if (confirm) {
  206. app.isLoading = true;
  207. myCouponApi.remove(app.userCouponId)
  208. .then(result => {
  209. app.getCouponDetail();
  210. app.isLoading = false;
  211. })
  212. .finally(() => app.isLoading = false)
  213. }
  214. }
  215. });
  216. },
  217. timeStamp: function(value) {
  218. var date = new Date(value);
  219. var year = date.getFullYear();
  220. var month = ("0" + (date.getMonth() + 1)).slice(-2);
  221. var sdate = ("0" + date.getDate()).slice(-2);
  222. var hour = ("0" + date.getHours()).slice(-2);
  223. var minute = ("0" + date.getMinutes()).slice(-2);
  224. var second = ("0" + date.getSeconds()).slice(-2);
  225. // 拼接
  226. var result = year + "." + month + "." + sdate + " " + hour + ":" + minute;
  227. // 返回
  228. return result;
  229. }
  230. }
  231. }
  232. </script>
  233. <style lang="scss" scoped>
  234. .container {
  235. min-height: 100vh;
  236. padding: 20rpx;
  237. background: #fff;
  238. color:#666666;
  239. }
  240. .base {
  241. border: dashed 5rpx #cccccc;
  242. padding: 30rpx;
  243. border-radius: 10rpx;
  244. margin: 20rpx;
  245. height: auto;
  246. min-height: 365rpx;
  247. .coupon-main {
  248. clear: both;
  249. min-height: 164rpx;
  250. border: #ccc dashed 2rpx;
  251. border-radius: 5rpx;
  252. margin-bottom: 20rpx;
  253. .left {
  254. width: 215rpx;
  255. float: left;
  256. .image {
  257. width: 210rpx;
  258. height: 160rpx;
  259. border-radius: 8rpx;
  260. border-right: #cccccc dashed 2rpx;
  261. }
  262. }
  263. .right {
  264. width: 380rpx;
  265. float: left;
  266. overflow: hidden;
  267. .name {
  268. font-size: 38rpx;
  269. }
  270. .num {
  271. font-size: 58rpx;
  272. color: red;
  273. }
  274. }
  275. }
  276. .item {
  277. clear: both;
  278. margin-bottom: 10rpx;
  279. font-size: 30rpx;
  280. color: #666666;
  281. .label {
  282. float: left;
  283. }
  284. .amount {
  285. font-weight: bold;
  286. }
  287. .name {
  288. font-weight: bold;
  289. margin-left: 6rpx;
  290. }
  291. }
  292. }
  293. .coupon-timer {
  294. border: dashed 5rpx #cccccc;
  295. margin-top:20rpx;
  296. padding: 15px 30rpx 5rpx 30rpx;
  297. border-radius: 10rpx;
  298. margin: 20rpx;
  299. overflow: hidden;
  300. .tips{
  301. margin-bottom: 20rpx;
  302. }
  303. .time-row {
  304. margin-bottom: 10rpx;
  305. height: 100rpx;
  306. display: flex;
  307. }
  308. .time-item {
  309. padding-top: 10rpx;
  310. text-align: center;
  311. align-items: center;
  312. justify-content: center;
  313. }
  314. .time {
  315. height: 80rpx;
  316. margin-top: 20rpx;
  317. margin-bottom: 20rpx;
  318. text-align: center;
  319. padding-top: 20rpx;
  320. border-radius: 40rpx;
  321. color: #ffffff;
  322. font-weight: bold;
  323. background: url('~@/static/confirm/undo.png') no-repeat center center;
  324. background-size: contain;
  325. }
  326. .active {
  327. background: url('~@/static/confirm/do.png') no-repeat center center;
  328. background-size: contain;
  329. border: solid 1px #ffffff;
  330. }
  331. .show-time {
  332. font-size: 22rpx;
  333. text-align: center;
  334. margin-bottom: 30rpx;
  335. }
  336. min-height: 160rpx;
  337. }
  338. .coupon-qr{
  339. border: dashed 5rpx #cccccc;
  340. border-radius: 10rpx;
  341. margin: 20rpx;
  342. text-align: center;
  343. padding-top: 30rpx;
  344. padding-bottom: 30rpx;
  345. .image{
  346. width: 360rpx;
  347. height: 360rpx;
  348. margin: 0 auto;
  349. }
  350. .qr-code{
  351. .code{
  352. font-weight: bold;
  353. font-size: 30rpx;
  354. line-height: 50rpx;
  355. }
  356. .tips{
  357. font-size: 25rpx;
  358. color:#C0C4CC;
  359. }
  360. }
  361. }
  362. .coupon-content {
  363. font-size: 28rpx;
  364. padding: 30rpx;
  365. border: dashed 5rpx #cccccc;
  366. border-radius: 5rpx;
  367. margin: 20rpx 20rpx 200rpx 20rpx;
  368. min-height: 450rpx;
  369. }
  370. /* 底部操作栏 */
  371. .footer-fixed {
  372. position: fixed;
  373. bottom: var(--window-bottom);
  374. left: 0;
  375. right: 0;
  376. display: flex;
  377. height: 180rpx;
  378. padding-bottom: 30rpx;
  379. z-index: 11;
  380. box-shadow: 0 -4rpx 40rpx 0 rgba(144, 52, 52, 0.1);
  381. background: #fff;
  382. }
  383. .footer-container {
  384. width: 100%;
  385. display: flex;
  386. }
  387. // 操作按钮
  388. .foo-item-btn {
  389. flex: 1;
  390. .btn-wrapper {
  391. height: 100%;
  392. display: flex;
  393. align-items: center;
  394. }
  395. .btn-item {
  396. flex: 1;
  397. font-size: 28rpx;
  398. height: 80rpx;
  399. line-height: 80rpx;
  400. margin-right: 16rpx;
  401. margin-left: 16rpx;
  402. text-align: center;
  403. color: #fff;
  404. border-radius: 80rpx;
  405. }
  406. // 领取按钮
  407. .btn-item-main {
  408. background: linear-gradient(to right, #f9211c, #ff6335);
  409. &.state {
  410. border: none;
  411. color: #cccccc;
  412. background: #F5F5F5;
  413. }
  414. }
  415. }
  416. </style>