ActivityQRCode.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. <template>
  2. <div class="ActivityQRCode">
  3. <van-form
  4. ref="tabstoreVal"
  5. class="QRCodeActivity"
  6. :readonly="
  7. approvalStatus == '1' ||
  8. approvalStatus == '2' ||
  9. (approvalStatus == null && !!userSummaryId)
  10. ">
  11. <div class="activityItem">
  12. <span class="van-f-red">*</span>
  13. <van-field
  14. v-model="activityForm.summaryEventName"
  15. name="summaryEventName"
  16. label="活动名称"
  17. placeholder="请输入活动名称"
  18. :rules="[{ required: true }]" />
  19. </div>
  20. <div class="activityItem">
  21. <span class="van-f-red">*</span>
  22. <van-field
  23. readonly
  24. clickable
  25. name="summaryEventDate"
  26. :value="activityForm.summaryEventDate"
  27. label="活动日期"
  28. placeholder="请选择活动日期"
  29. @click="activityShowCalendarFun"
  30. :rules="[{ required: true }]" />
  31. </div>
  32. <div class="activityItem">
  33. <span class="van-f-red">*</span>
  34. <van-field
  35. readonly
  36. clickable
  37. name="qrStartTime"
  38. :value="activityForm.qrStartTime"
  39. label="生效开始日期"
  40. placeholder="请选择开始日期"
  41. @click="clickValidDateShow('start')"
  42. :rules="[{ required: true }]" />
  43. </div>
  44. <div class="activityItem">
  45. <span class="van-f-red">*</span>
  46. <van-field
  47. readonly
  48. clickable
  49. name="qrEndTime"
  50. :value="activityForm.qrEndTime"
  51. label="生效结束日期"
  52. placeholder="请选择结束日期"
  53. @click="clickValidDateShow('end')"
  54. :rules="[{ required: true }]" />
  55. </div>
  56. <div class="activityItem">
  57. <div class="van-cell QRCodeBtnBox">
  58. <van-button style="width: 88px" class="QRCodeBtn" color="#0057ba" @click="openQRCode">
  59. 生成签到码
  60. </van-button>
  61. <div class="tips">
  62. 1、生成签到码后自动暂存任务;<br />2、请门店老板使用企微扫码签到
  63. <!-- <div>1、点击【暂存】后签到码生效;</div>
  64. <div>2、请门店老板使用企微扫码签到</div> -->
  65. </div>
  66. </div>
  67. </div>
  68. <div class="activityItem">
  69. <div class="van-cell refreshBtnBox" style="padding: 5px 16px" @click="getQRChainList">
  70. <div style="font-size: 16px; margin-right: 10px">
  71. 已签到成功门店:
  72. <span style="margin-left: 5px; color: red">{{ QRChainList.length }}家 </span>
  73. </div>
  74. <div class="refresh">
  75. <van-icon
  76. style="font-weight: 600; margin-top: 1px"
  77. name="replay"
  78. size="20"
  79. color="#1989fa" />
  80. </div>
  81. </div>
  82. </div>
  83. <div class="activityItem">
  84. <div class="van-cell chainListBox">
  85. <div class="jxsContent">
  86. <div class="item" v-for="(val, index) in QRChainList">
  87. <el-popover
  88. placement="bottom"
  89. trigger="click"
  90. :content="val.storeName + '(' + val.storeCode + ')'">
  91. <template slot="reference">
  92. <div class="selectItem">{{ val.storeName }} &nbsp; ({{ val.storeCode }})</div>
  93. </template>
  94. </el-popover>
  95. </div>
  96. </div>
  97. </div>
  98. </div>
  99. </van-form>
  100. <!-- 活动日期 -->
  101. <van-calendar v-model="activityShowCalendar" @confirm="activityOnConfirm" />
  102. <!-- 生效日期 -->
  103. <van-popup v-model="validDateShow" capture position="bottom">
  104. <van-datetime-picker
  105. v-model="validDate"
  106. :title="activate.title"
  107. :min-date="activate.minDate"
  108. :max-date="activate.maxDate"
  109. type="datetime"
  110. @cancel="validDateShow = false"
  111. @confirm="onValidDateConfirm" />
  112. </van-popup>
  113. <!-- 二维码 -->
  114. <div class="QRCodeBox" v-if="QRCodeBox">
  115. <div class="centerBox">
  116. <div class="title">{{ activityForm.summaryEventName }}</div>
  117. <div class="activityDate">{{ activityForm.summaryEventDate }}</div>
  118. <img class="QRCodeUrl" :src="this.QRCodeUrl" />
  119. <div class="validTimeBox">
  120. <div class="text">二维码有效期</div>
  121. <div class="validTime">
  122. <div>{{ activityForm.qrStartTime }}</div>
  123. <div>~</div>
  124. <div>{{ activityForm.qrEndTime }}</div>
  125. </div>
  126. </div>
  127. <div class="close" @click="QRCodeBox = false">关闭</div>
  128. </div>
  129. </div>
  130. </div>
  131. </template>
  132. <script>
  133. import { getSummaryQrCheckList, getSummaryQrCodeUUID } from '@/api/index';
  134. export default {
  135. props: {
  136. ActivityQRCodeData: {
  137. type: Object,
  138. },
  139. qrUuid: {
  140. type: String,
  141. },
  142. approvalStatus: {
  143. type: String,
  144. },
  145. userSummaryId: {
  146. type: [String, Number],
  147. },
  148. },
  149. data() {
  150. return {
  151. // 活动数据
  152. activityForm: {
  153. summaryEventName: '',
  154. summaryEventDate: '',
  155. qrStartTime: '',
  156. qrEndTime: '',
  157. },
  158. activityShowCalendar: false,
  159. validDateShow: false,
  160. QRCodeUrl: '',
  161. QRCodeBox: false,
  162. activate: {
  163. type: '',
  164. title: '',
  165. minDate: new Date(),
  166. maxDate: new Date(2035, 10, 1),
  167. },
  168. validDate: new Date(),
  169. QRChainList: [],
  170. qrUuids: null,
  171. };
  172. },
  173. watch: {
  174. ActivityQRCodeData: {
  175. handler(val) {
  176. if (val) this.activityForm = val;
  177. if (this.qrUuid) {
  178. this.qrUuids = this.qrUuid;
  179. this.getQRChainList();
  180. }
  181. console.log(val);
  182. },
  183. deep: true,
  184. immediate: true,
  185. },
  186. },
  187. methods: {
  188. activityOnConfirm(date) {
  189. this.activityForm.summaryEventDate = this.formatDate(date);
  190. this.activityShowCalendar = false;
  191. },
  192. // 打开二维码
  193. openQRCode(value) {
  194. this.toastLoading(0, '加载中...', true);
  195. // approvalStatus//1-待审批 2-审批通过 不支持修改,直接查看二维码
  196. if (
  197. this.approvalStatus == '1' ||
  198. this.approvalStatus == '2' ||
  199. this.approvalStatus == '3' ||
  200. (this.approvalStatus == null && this.userSummaryId) ||
  201. (this.qrUuid && this.userSummaryId)
  202. ) {
  203. getSummaryQrCodeUUID({ qrUuid: this.qrUuid, userSummaryId: this.userSummaryId }).then(
  204. (res) => {
  205. this.toastLoading().clear();
  206. this.QRCodeUrl = res.data.base64Png;
  207. this.QRCodeBox = true;
  208. }
  209. );
  210. } else {
  211. this.$refs.tabstoreVal
  212. .validate()
  213. .then(() => {
  214. // 验证通过
  215. this.$emit('onSubmit', (res) => {
  216. this.toastLoading().clear();
  217. this.QRCodeBox = true;
  218. this.QRCodeUrl = res.data.base64Png;
  219. this.qrUuids = res.data.qrUuid;
  220. });
  221. })
  222. .catch((errors) => {
  223. this.toastLoading().clear();
  224. //验证失败
  225. window.scrollTo(0, 0);
  226. });
  227. }
  228. },
  229. activityShowCalendarFun() {
  230. if (
  231. this.approvalStatus == '1' ||
  232. this.approvalStatus == '2' ||
  233. (this.approvalStatus == null && this.userSummaryId)
  234. )
  235. return;
  236. this.activityShowCalendar = true;
  237. },
  238. clickValidDateShow(type) {
  239. if (
  240. this.approvalStatus == '1' ||
  241. this.approvalStatus == '2' ||
  242. (this.approvalStatus == null && this.userSummaryId)
  243. )
  244. return;
  245. if (type == 'start') {
  246. this.activate = {
  247. type: type,
  248. title: '请选择开始日期',
  249. minDate: new Date(),
  250. maxDate: new Date(2035, 9, 1),
  251. };
  252. this.validDate = new Date();
  253. } else {
  254. this.activate = {
  255. type: type,
  256. title: '请选择结束日期',
  257. minDate: this.activityForm.qrStartTime
  258. ? new Date(this.activityForm.qrStartTime)
  259. : new Date(),
  260. maxDate: new Date(2035, 9, 1),
  261. };
  262. this.validDate = this.activityForm.qrEndTime
  263. ? new Date(this.activityForm.qrEndTime)
  264. : new Date();
  265. }
  266. this.validDateShow = true;
  267. },
  268. onValidDateConfirm(date) {
  269. let time = this.parseTime(new Date(date), '{y}-{m}-{d} {h}:{i}:{s}') + '';
  270. if (this.activate.type == 'start') {
  271. this.activityForm.qrStartTime = time;
  272. if (
  273. new Date(this.activityForm.qrStartTime).getTime() >
  274. new Date(this.activityForm.qrEndTime).getTime()
  275. ) {
  276. this.activityForm.qrEndTime = null;
  277. }
  278. } else {
  279. this.activityForm.qrEndTime = time;
  280. }
  281. this.validDateShow = false;
  282. },
  283. formatDate(date) {
  284. var Month = date.getMonth() + 1;
  285. var Day = date.getDate();
  286. if (Month < 10) {
  287. Month = '0' + Month;
  288. }
  289. if (Day < 10) {
  290. Day = '0' + Day;
  291. }
  292. return `${date.getFullYear()}-${Month}-${Day}`;
  293. },
  294. getQRChainList() {
  295. if (!this.qrUuids) return;
  296. this.QRChainList = [];
  297. this.toastLoading(0, '加载中...', true);
  298. getSummaryQrCheckList({ qrUuid: this.qrUuids }).then((res) => {
  299. this.toastLoading().clear();
  300. if (res.code == 200) {
  301. this.QRChainList = res.data || [];
  302. } else {
  303. this.QRChainList = [];
  304. }
  305. });
  306. },
  307. },
  308. };
  309. </script>
  310. <style scoped lang="scss">
  311. .ActivityQRCode {
  312. .QRCodeActivity {
  313. background-color: white;
  314. margin-bottom: 10px;
  315. .activityItem {
  316. display: flex;
  317. .van-f-red {
  318. position: relative;
  319. left: 16px;
  320. top: 10px;
  321. z-index: 1;
  322. }
  323. .QRCodeBtnBox {
  324. justify-content: space-between;
  325. align-items: end;
  326. .QRCodeBtn {
  327. width: auto;
  328. border-radius: 10px;
  329. }
  330. .tips {
  331. flex: 1;
  332. font-size: 14px;
  333. line-height: 15px;
  334. text-align: right;
  335. color: red;
  336. }
  337. .van-button--normal {
  338. padding: 0 8px;
  339. }
  340. }
  341. .jxsContent {
  342. margin-bottom: 10px;
  343. .item {
  344. padding: 5px;
  345. background: #e9e9e9;
  346. margin: 5px 0;
  347. .el-popover__reference-wrapper {
  348. display: flex;
  349. justify-content: space-between;
  350. align-items: center;
  351. }
  352. .selectItem {
  353. flex: 1;
  354. white-space: nowrap;
  355. overflow: hidden;
  356. text-overflow: ellipsis;
  357. font-size: 14px;
  358. }
  359. }
  360. }
  361. }
  362. }
  363. .QRCodeBox {
  364. position: fixed;
  365. width: 100%;
  366. height: 100%;
  367. z-index: 9999999999;
  368. top: 0;
  369. left: 0;
  370. right: 0;
  371. bottom: 0;
  372. background: linear-gradient(135deg, #6a11cb 0%, #2575fc 100%);
  373. display: flex;
  374. align-items: center;
  375. justify-content: center;
  376. .centerBox {
  377. width: 90%;
  378. // height: 100%;
  379. background: rgba(255, 255, 255, 0.1);
  380. backdrop-filter: blur(10px);
  381. border-radius: 20px;
  382. padding: 10px 20px;
  383. box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
  384. text-align: center;
  385. color: #fff;
  386. font-size: 18px;
  387. display: flex;
  388. flex-direction: column;
  389. align-items: center;
  390. .title {
  391. font-size: 24px;
  392. font-weight: 600;
  393. margin-bottom: 10px;
  394. }
  395. .activityDate {
  396. // font-size: 20px;
  397. margin: 10px 0;
  398. }
  399. .QRCodeUrl {
  400. // width: 100%;
  401. margin: 10px 0;
  402. }
  403. .validTimeBox {
  404. margin-top: 10px;
  405. .validTime {
  406. margin: 10px 0;
  407. font-size: 12px;
  408. }
  409. }
  410. .close {
  411. width: 40%;
  412. padding: 10px 15px;
  413. background: rgba(255, 255, 255, 0.2);
  414. border-radius: 12px;
  415. }
  416. }
  417. }
  418. }
  419. </style>