registrationActivity.html 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
  7. <!--引入 element-ui 的样式,-->
  8. <link rel="stylesheet"
  9. href="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1742018383195/element-ui.css">
  10. <!-- 必须先引入vue, 后使用element-ui -->
  11. <script
  12. src="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1742017957144/vue.js"></script>
  13. <!-- 引入element 的组件库-->
  14. <script
  15. src="https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1742017747738/element-ui.js"></script>
  16. <!-- <script src="js/vconsole.min.js"></script>
  17. <script>
  18. var vConsole = new window.VConsole();
  19. </script> -->
  20. </head>
  21. <style>
  22. body {
  23. margin: 0;
  24. padding: 0;
  25. }
  26. .box {
  27. width: 100vw;
  28. height: 100%;
  29. box-sizing: border-box;
  30. background: #FAFAFA;
  31. }
  32. .page6 {
  33. width: 100vw;
  34. height: 100%;
  35. background-size: 100vw 300px;
  36. background-repeat: no-repeat;
  37. position: relative;
  38. overflow-y: auto;
  39. }
  40. .enrollment {
  41. width: 100%;
  42. height: 25px;
  43. background: #C30011;
  44. opacity: 0.8;
  45. font-weight: 400;
  46. font-size: 12px;
  47. color: #FFFFFF;
  48. line-height: 25px;
  49. text-align: center;
  50. position: fixed;
  51. top: 0;
  52. left: 0;
  53. }
  54. .activity_content {
  55. width: 100%;
  56. margin-top: 250px;
  57. background: #FFFFFF;
  58. border-radius: 20px 20px 0px 0px;
  59. padding: 30px 20px 66px;
  60. box-sizing: border-box;
  61. }
  62. .activity_item {
  63. display: flex;
  64. align-items: flex-start;
  65. margin-bottom: 30px;
  66. }
  67. .item_title {
  68. font-weight: 500;
  69. font-size: 14px;
  70. color: #222222;
  71. min-width: 100px;
  72. }
  73. .item_content {
  74. font-weight: 400;
  75. font-size: 14px;
  76. color: #222222;
  77. }
  78. .item_content p {
  79. margin: 0;
  80. }
  81. .foot_btn {
  82. position: fixed;
  83. bottom: 14px;
  84. padding: 0 35px;
  85. width: 100%;
  86. box-sizing: border-box;
  87. }
  88. .signUp_btn {
  89. height: 52px;
  90. width: 100%;
  91. background: #1677FF;
  92. border-radius: 20px;
  93. font-weight: 500;
  94. font-size: 16px;
  95. color: #FFFFFF;
  96. text-align: center;
  97. padding: 0;
  98. line-height: 22px;
  99. }
  100. .signUp_btn_tip {
  101. font-weight: bold;
  102. font-size: 12px;
  103. line-height: 17px;
  104. }
  105. .form_content {
  106. width: 100%;
  107. margin-top: 250px;
  108. background: #FFFFFF;
  109. border-radius: 20px 20px 0px 0px;
  110. padding: 20px 20px 66px;
  111. box-sizing: border-box;
  112. }
  113. .form_title {
  114. font-weight: 500;
  115. font-size: 16px;
  116. color: #222222;
  117. text-align: center;
  118. line-height: 24px;
  119. }
  120. .form_title_tip {
  121. font-weight: bold;
  122. font-size: 12px;
  123. color: #FF4E4E;
  124. text-align: center;
  125. line-height: 17px;
  126. }
  127. .el-form-item__label {
  128. padding-right: 0;
  129. font-weight: 500;
  130. font-size: 14px;
  131. color: #666666;
  132. }
  133. .el-input__inner {
  134. border: none;
  135. font-weight: 500;
  136. font-size: 14px;
  137. color: #222222;
  138. text-align: right;
  139. }
  140. .el-input--prefix .el-input__inner {
  141. padding-left: 0;
  142. padding-right: 0;
  143. }
  144. .el-form-item {
  145. margin-bottom: 0;
  146. border-bottom: 1px solid #F9F9F9;
  147. padding: 10px 0;
  148. }
  149. .el-textarea__inner {
  150. border: none;
  151. font-weight: 500;
  152. font-size: 14px;
  153. color: #222222;
  154. text-align: right;
  155. }
  156. .el-form-item__content .el-select {
  157. margin-left: 55px;
  158. }
  159. .el-form-item__content .el-cascader {
  160. margin-left: 55px;
  161. }
  162. .el-select-dropdown__item {
  163. white-space: normal;
  164. overflow: unset;
  165. height: auto;
  166. }
  167. .signup_page {
  168. width: 100vw;
  169. min-height: 100vh;
  170. background: url('./img/sign_up.png') no-repeat center;
  171. /* background-size: 100vw 100%; */
  172. background-size: cover;
  173. }
  174. .signupSucc_page {
  175. width: 100vw;
  176. height: 100vh;
  177. background: url('./img/signup_success.png') no-repeat center;
  178. background-size: 100vw 100vh;
  179. background-repeat: no-repeat;
  180. }
  181. .succ_tip {
  182. padding-top: 240px;
  183. font-weight: bold;
  184. font-size: 24px;
  185. color: #222222;
  186. line-height: 40px;
  187. text-align: center;
  188. width: 100%;
  189. word-break: keep-all;
  190. }
  191. .signup_title {
  192. padding-top: 80px;
  193. }
  194. .form_guide {
  195. font-weight: bold;
  196. font-size: 24px;
  197. color: #FFFFFF;
  198. line-height: 41px;
  199. text-align: center;
  200. white-space: pre-line;
  201. }
  202. .signup_box {
  203. margin: 30px 20px 0;
  204. height: auto;
  205. background: linear-gradient(#D5E6FF 50%, #FFFFFF 100%);
  206. border-radius: 20px;
  207. box-sizing: border-box;
  208. border: 1px solid #FFFFFF;
  209. }
  210. .signup_tip {
  211. font-weight: 400;
  212. font-size: 16px;
  213. color: #222222;
  214. padding: 40px 31px 10px 32px;
  215. text-align: center;
  216. line-height: 27px;
  217. white-space: pre-line;
  218. box-sizing: border-box;
  219. }
  220. .store_msg {
  221. display: flex;
  222. align-items: center;
  223. justify-content: center;
  224. font-weight: 400;
  225. font-size: 12px;
  226. color: #1677FF;
  227. margin-bottom: 15px;
  228. padding-left: 30px;
  229. padding-right: 36px;
  230. }
  231. .store_icon {
  232. width: 24px;
  233. height: 24px;
  234. margin-right: 5px;
  235. }
  236. .signup_code_box {
  237. padding: 0 20px;
  238. box-sizing: border-box;
  239. }
  240. .signup_code {
  241. font-weight: 500;
  242. font-size: 26px;
  243. color: #222222;
  244. padding: 15px 0;
  245. background: #D3E0F5;
  246. border-radius: 20px;
  247. text-align: center;
  248. }
  249. .copy_text {
  250. display: flex;
  251. align-items: center;
  252. justify-content: center;
  253. padding-top: 10px;
  254. font-weight: 400;
  255. font-size: 12px;
  256. color: #9FB3C7;
  257. }
  258. .copy_icon {
  259. width: 11px;
  260. height: 11px;
  261. margin-right: 3px;
  262. }
  263. .attention {
  264. font-weight: 400;
  265. font-size: 12px;
  266. color: #999999;
  267. line-height: 24px;
  268. text-align: start;
  269. padding-top: 20px;
  270. padding-left: 20px;
  271. padding-bottom: 20px;
  272. }
  273. .qrcode_info {
  274. display: flex;
  275. align-items: center;
  276. padding: 20px 0 20px 35px;
  277. border-top: 1px dashed #AEBFCE;
  278. font-weight: 400;
  279. font-size: 14px;
  280. color: #222222;
  281. }
  282. .qrcode_info2 {
  283. display: flex;
  284. align-items: center;
  285. flex-direction: column;
  286. padding: 20px 35px;
  287. font-weight: 400;
  288. font-size: 14px;
  289. color: #222222;
  290. }
  291. .bm_qrcode {
  292. width: 70px;
  293. height: 70px;
  294. margin-right: 25px;
  295. }
  296. .bm_qrcode2 {
  297. width: 120px;
  298. height: 120px;
  299. margin-bottom: 25px;
  300. }
  301. .bm_title {
  302. padding-bottom: 10px;
  303. white-space: pre-line;
  304. box-sizing: border-box;
  305. text-align: center;
  306. }
  307. .fail_box {
  308. margin: 80px 20px 0;
  309. height: 287px;
  310. background: linear-gradient(#D5E6FF 50%, #FFFFFF 100%);
  311. border-radius: 20px;
  312. box-sizing: border-box;
  313. text-align: center;
  314. }
  315. .fail_img {
  316. width: 246px;
  317. height: 144px;
  318. margin-top: -20px;
  319. }
  320. .fail_title {
  321. font-weight: 500;
  322. font-size: 20px;
  323. color: #222222;
  324. line-height: 30px;
  325. padding: 20px 0;
  326. }
  327. .fail_tip {
  328. font-weight: 400;
  329. font-size: 16px;
  330. color: #666666;
  331. line-height: 30px;
  332. }
  333. </style>
  334. <body>
  335. <div id="box" class="box">
  336. <div class="signup_page" v-if="step === 3">
  337. <div class="signup_title">
  338. <div class="form_guide">{{toshopData.formGuide1}}</div>
  339. </div>
  340. <div class="signup_box" v-if="toshopData.formGuide2 || toshopData.verificationShowSwitch || toshopData.sucImgShowSwitch">
  341. <div class="signup_tip">{{toshopData.formGuide2}}</div>
  342. <div v-if="toshopData.verificationShowSwitch">
  343. <div class="store_msg">
  344. <img class="store_icon" src="./img/store.png" />
  345. <span>{{storeName}}</span>
  346. </div>
  347. <div class="signup_code_box">
  348. <div class="signup_code">{{verificationCode}}</div>
  349. </div>
  350. <div class="copy_text" @click="handleCopy(verificationCode)">
  351. <img class="copy_icon" src="./img/copy_icon.png" />
  352. <span>点击复制核销码</span>
  353. </div>
  354. <div class="attention">
  355. <div>注意:</div>
  356. <div>1.凭证码仅可核销一次,请注意保管</div>
  357. <div>2.不记名,不挂失</div>
  358. </div>
  359. </div>
  360. <div v-if="toshopData.sucImgShowSwitch">
  361. <div class="qrcode_info" v-if="toshopData.verificationShowSwitch">
  362. <img class="bm_qrcode" :src="toshopData.sucImg" />
  363. <div>
  364. <div class="bm_title">{{toshopData.sucImgGuide}}</div>
  365. </div>
  366. </div>
  367. <div class="qrcode_info2" v-else>
  368. <img class="bm_qrcode2" :src="toshopData.sucImg" />
  369. <div class="bm_title">{{toshopData.sucImgGuide}}</div>
  370. </div>
  371. </div>
  372. </div>
  373. </div>
  374. <div class="signupSucc_page" v-else-if="step === 4">
  375. <div class="succ_tip">
  376. {{toshopData.verificationGuide}}
  377. </div>
  378. </div>
  379. <div class="signup_page" v-else-if="step === 5">
  380. <div class="signup_title">
  381. <div class="form_guide">{{toshopData.name}}</div>
  382. </div>
  383. <div class="fail_box">
  384. <img class="fail_img" src="./img/fail_img.png" />
  385. <div class="fail_title">{{toshopData.verificationFailGuide}}</div>
  386. <div class="fail_tip">{{toshopData.verificationFailGuide2}}</div>
  387. </div>
  388. </div>
  389. <div class="page6" :style="{'background-image': 'url('+toshopData.banner+')'}" v-else-if="step === 1 || step === 2">
  390. <div class="enrollment">已有23333人参与活动</div>
  391. <!-- <div class="activity_content" v-if="step === 1">
  392. <div class="activity_item">
  393. <div class="item_title">活动主题:</div>
  394. <div class="item_content">{{toshopData.name}}</div>
  395. </div>
  396. <div class="activity_item">
  397. <div class="item_title">活动对象:</div>
  398. <div class="item_content">{{toshopData.target}}</div>
  399. </div>
  400. <div class="activity_item">
  401. <div class="item_title">活动时间:</div>
  402. <div class="item_content">{{toshopData.startTime.slice(0, 10) + '~' + toshopData.endTime.slice(0, 10)}}</div>
  403. </div>
  404. <div class="activity_item">
  405. <div class="item_title">活动规则:</div>
  406. <div class="item_content" v-html="toshopData.activityInfo"></div>
  407. </div>
  408. </div> -->
  409. <div class="form_content" v-if="step === 2">
  410. <div class="form_title">报名表单</div>
  411. <div class="form_title_tip" v-if="Number(toshopData.id) !== 116262865210171 && Number(toshopData.id) !== 116568649610001 && Number(toshopData.id) !== 116816531710011 && Number(toshopData.id) !== 117422198310041">【 报名成功还能抽华为手机! 】</div>
  412. <el-form ref="form" label-position="left" label-width="120px">
  413. <el-form-item v-for="(item, index) in toshopData.formProList" :key="index" :label="item.name"
  414. :required="Boolean(item.isNeed)">
  415. <el-cascader v-if="item.type === 10" v-model="item.value" :options="transformedData"
  416. @change="handleInfoCity">
  417. </el-cascader>
  418. <el-select v-if="item.type === 11" v-model="item.value" placeholder="请选择" @change="handlechange">
  419. <el-option v-for="(sto, sindex) in storeList" :key="sindex" :label="sto.name" :value="sto.name">
  420. </el-option>
  421. </el-select>
  422. <el-input v-if="item.type === 0" v-model="item.value" placeholder="请输入"></el-input>
  423. <el-input v-if="item.type === 1" type="textarea" autosize v-model="item.value" placeholder="请输入"></el-input>
  424. <el-input v-if="item.type === 2" type="number" v-model="item.value" placeholder="请输入"></el-input>
  425. <el-select v-if="item.type === 3" v-model="item.value" placeholder="请选择">
  426. <el-option v-for="sto in item.formProTagReqs" :key="sto.proValue" :label="sto.proValue"
  427. :value="sto.proValue">
  428. </el-option>
  429. </el-select>
  430. <el-col :span="22" v-if="item.type === 5">
  431. <el-date-picker v-model="item.value" type="date" placeholder="选择日期" style="width: 100%;">
  432. </el-col>
  433. <el-col :span="22" v-if="item.type === 6">
  434. <el-time-picker v-model="item.value" placeholder="请选择"></el-time-picker>
  435. </el-col>
  436. <el-col :span="22" v-if="item.type === 7">
  437. <el-date-picker v-if="item.type === 7" v-model="item.value" type="datetime"
  438. placeholder="选择日期时间"></el-date-picker>
  439. </el-col>
  440. </el-form-item>
  441. </el-form>
  442. </div>
  443. <div class="foot_btn">
  444. <el-button class="signUp_btn" :loading="loading" @click="toSignUp" v-if="step === 1">
  445. <div>去报名</div>
  446. <div class="signUp_btn_tip" v-if="Number(toshopData.id) !== 116262865210171 && Number(toshopData.id) !== 116568649610001 && Number(toshopData.id) !== 116816531710011 && Number(toshopData.id) !== 117422198310041">【 报名成功还能抽华为手机 】</div>
  447. </el-button>
  448. <el-button class="signUp_btn" :loading="loading" @click="toSignUp" v-else>确定</el-button>
  449. </div>
  450. </div>
  451. </div>
  452. </body>
  453. <script>
  454. new Vue({
  455. el: '#box',
  456. data () {
  457. return {
  458. httpUrl: '',
  459. bId: null,
  460. env: '',
  461. toshopData: {
  462. id: null,
  463. banner: '',
  464. name: '',
  465. target: '',
  466. startTime: '',
  467. endTime: '',
  468. activityInfo: '',
  469. formProList: [],
  470. verificationGuide: '',
  471. formGuide1: '',
  472. formGuide2: '',
  473. verificationFailGuide: '',
  474. verificationFailGuide2: '',
  475. browseId: null,
  476. verificationShowSwitch: 0,
  477. sucImgShowSwitch: 0,
  478. sucImg: '',
  479. sucImgGuide: '',
  480. },
  481. step: 2,
  482. verificationCode: '',
  483. storeName: '',
  484. transformedData: [],
  485. storeList: [],
  486. province: '',
  487. city: '',
  488. loading: false,
  489. intervalId: null, // 定时任务的ID
  490. loadTime: null, // 页面加载的时间戳
  491. }
  492. },
  493. created () {
  494. var hrt = document.documentElement.clientHeight; //获取当前可视区域的高度存到hrt变量
  495. document.getElementById('box').style.height = hrt + 'px'//把获取到的高度赋值给根div
  496. this.bId = this.getQueryParam('bId')
  497. this.env = this.getQueryParam('env')
  498. if (!this.env || this.env === 'prod') {
  499. this.httpUrl = 'https://wlapi.wefanbot.com'
  500. } else {
  501. this.httpUrl = 'https://test.wefanbot.com:28993'
  502. // this.httpUrl = 'http://192.168.1.147:18993'
  503. }
  504. localStorage.removeItem('openId')
  505. if (this.isWeChatBrowser()) {
  506. // 微信浏览器
  507. this.ifH5Type()
  508. } else {
  509. // 不是微信浏览器
  510. this.lightenShare()
  511. }
  512. },
  513. beforeDestroy() {
  514. this.clearIntervalTask() // 在组件销毁前清除定时任务
  515. },
  516. methods: {
  517. ifH5Type () {
  518. if (this.getQueryParam('openId') || localStorage.getItem('openId')) {
  519. if (!this.getQueryParam('externalUserid')) {
  520. this.gerQwAuth(this.bId);
  521. } else {
  522. this.lightenShare()
  523. }
  524. } else {
  525. // 走授权操作
  526. this.getAuth();
  527. }
  528. },
  529. getAuth () {
  530. // 获取url上的code
  531. let code = this.getQueryParam('code')
  532. if (code) {
  533. // 判断业务id是否生产环境业务id
  534. fetch(this.httpUrl + `/p/insuite/p/isProdId?id=${this.bId}`)
  535. .then(res => {
  536. return res.json()
  537. }).then(result => {
  538. let { data, msg } = result
  539. if (typeof data === 'boolean' && data) {
  540. this.httpUrl = 'https://wlapi.wefanbot.com'
  541. } else {
  542. this.httpUrl = 'http://test.wefanbot.com:18993'
  543. }
  544. this.getInfoByh5Code(this.getQueryParam('code'))
  545. })
  546. } else {
  547. let redirect_uri = window.location.href
  548. // code 不存在,走微信网页授权逻辑
  549. let url = `https://open.weixin.qq.com/connect/oauth2/authorize?appId=wx99ec0d0828a4d2d3&redirect_uri=${redirect_uri}&scope=snsapi_userinfo&state=STATE#wechat_redirect`
  550. window.location.replace(url)
  551. }
  552. },
  553. getInfoByh5Code (code) {
  554. fetch(this.httpUrl + `/scrm/v1/mp-client/p/getInfoByh5Code?code=${code}&bId=${this.bId}`)
  555. .then(res => {
  556. return res.json()
  557. }).then(result => {
  558. let { data, code, msg } = result
  559. if (code === 1) {
  560. localStorage.setItem('openId', data.openId)
  561. this.ifH5Type()
  562. }
  563. })
  564. },
  565. // 企微授权
  566. gerQwAuth (bId) {
  567. let openId = this.getQueryParam('openId') || localStorage.getItem('openId')
  568. fetch(this.httpUrl + `/p/insuite/p/getOAUrl?openId=${openId}&bId=${bId}`)
  569. .then(res => {
  570. return res.json()
  571. }).then(result => {
  572. let { data, code, msg } = result
  573. if (code === 1) {
  574. window.location.replace(data)
  575. } else {
  576. this.$message({
  577. message: msg,
  578. type: 'warning'
  579. })
  580. }
  581. })
  582. },
  583. // 获取城市数据
  584. getCityLevel () {
  585. let url = ''
  586. if (this.toshopData.id == 115399319210021) {
  587. url = 'https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1744104152989/five-province.json'
  588. } else {
  589. url = 'https://wl-1306604067.cos.ap-guangzhou.myqcloud.com/production/ct/103548289110001/1742009720857/four-province.json'
  590. }
  591. fetch(url)
  592. .then(res => {
  593. return res.json()
  594. }).then(result => {
  595. this.transformedData = this.transformData(result)
  596. })
  597. },
  598. // 省市数据做转换
  599. transformData (data) {
  600. return data.map(item => {
  601. // 创建一个新对象,避免直接修改原始对象
  602. const newItem = { ...item };
  603. // 重命名 text 为 label
  604. if (newItem.text) {
  605. newItem.label = newItem.text;
  606. newItem.value = newItem.text;
  607. delete newItem.text;
  608. }
  609. // 如果存在 children 数组,则递归处理每个子项
  610. if (newItem.children && Array.isArray(newItem.children)) {
  611. newItem.children = this.transformData(newItem.children);
  612. }
  613. return newItem;
  614. })
  615. },
  616. handleInfoCity (value) {
  617. this.province = value[0]
  618. this.city = value[1]
  619. // 清空经销商类型的数据
  620. this.toshopData.formProList.forEach(item => {
  621. if (item.type === 11) {
  622. item.value = ''
  623. }
  624. })
  625. this.storeList = []
  626. this.getStoreList()
  627. },
  628. handlechange (value) {
  629. this.toshopData.formProList.forEach(item => {
  630. if (item.type === 11) {
  631. item.value = value
  632. }
  633. })
  634. this.$forceUpdate()
  635. },
  636. getStoreList () {
  637. fetch(this.httpUrl + `/scrm/v1/wxcp-toshop-store/p/findListByPage?city=${this.city}&province=${this.province}`, {
  638. method: 'post',
  639. body: JSON.stringify({
  640. page: 1,
  641. pageCount: 10000,
  642. }),
  643. headers: {
  644. 'Content-Type': 'application/json'
  645. }
  646. }).then(res => {
  647. return res.json()
  648. }).then(result => {
  649. let { data, code, msg } = result
  650. if (code === 1) {
  651. this.storeList = data.records
  652. } else {
  653. this.$message({
  654. message: msg,
  655. type: 'warning'
  656. })
  657. }
  658. })
  659. },
  660. lightenShare () {
  661. let externalUserid = this.getQueryParam('externalUserid') || ''
  662. let openId = this.getQueryParam('openId') || localStorage.getItem('openId') || ''
  663. const headers = new Headers();
  664. headers.append('police', 110);
  665. fetch(this.httpUrl + `/scrm/v1/wxcp-toshop-share/p/lottery?clientId=${localStorage.getItem('bkClientId') || ''}&externalUserid=${externalUserid}&openId=${openId}&bId=${this.bId}`, {
  666. method: 'GET',
  667. headers: headers
  668. })
  669. .then(res => {
  670. return res.json()
  671. }).then(result => {
  672. let { data, code, msg } = result
  673. if (code === 1) {
  674. this.toshopData = data
  675. if (!this.isWeChatBrowser()) {
  676. localStorage.setItem('bkClientId', data.client.id)
  677. }
  678. this.getCityLevel()
  679. if (data.client.state === 1) {
  680. // 未提交表单
  681. this.step = 2
  682. } else if (data.client.state === 2) {
  683. // 已提交表单
  684. this.verificationCode = data.client.verificationCode
  685. if (data.client.formData) {
  686. let arr = JSON.parse(data.client.formData)
  687. const filteredItems = arr.filter(item => item.name.includes("门店"))
  688. if (filteredItems.length) {
  689. const names = filteredItems.map(item => item.value[0])
  690. this.storeName = names[0]
  691. }
  692. }
  693. this.step = 3
  694. } else if (data.client.state === 3) {
  695. // 已核销
  696. this.step = 4
  697. } else if (data.client.state === -1) {
  698. // 不符合资格
  699. this.step = 5
  700. }
  701. this.loadTime = Date.now() // 记录页面加载时间
  702. this.startInterval() // 启动定时任务
  703. } else {
  704. this.$message({
  705. message: msg,
  706. })
  707. }
  708. })
  709. },
  710. startInterval() {
  711. if (this.intervalId !== null) {
  712. clearInterval(this.intervalId); // 如果定时任务已经存在,先清除它
  713. }
  714. this.intervalId = setInterval(() => {
  715. const elapsedTime = Math.floor((Date.now() - this.loadTime) / 1000); // 计算停留时长(秒)
  716. this.sendDataToServer(this.toshopData.browseId, elapsedTime);
  717. }, 10000); // 每10秒调用一次
  718. },
  719. sendDataToServer(browseId, elapsedTime) {
  720. let openId = this.getQueryParam('openId') || localStorage.getItem('openId') || ''
  721. fetch(this.httpUrl + `/scrm/v1/wxcp-toshop-client-browse-history/p/updateBrowseDuration?openId=${openId}`, {
  722. method: 'post',
  723. body: JSON.stringify({
  724. id: browseId,
  725. duration: elapsedTime,
  726. }),
  727. headers: {
  728. 'Content-Type': 'application/json'
  729. }
  730. }).then(res => {
  731. return res.json()
  732. }).then(result => {
  733. let { data, code, msg } = result
  734. if (data) {
  735. } else {
  736. }
  737. })
  738. },
  739. clearIntervalTask() {
  740. if (this.intervalId !== null) {
  741. clearInterval(this.intervalId)
  742. this.intervalId = null // 清空定时任务的ID
  743. }
  744. },
  745. toSignUp () {
  746. if (this.step === 1) {
  747. this.step = 2
  748. } else {
  749. if (!this.toshopData.formProList || !this.toshopData.formProList.length) {
  750. this.$message({
  751. message: '请完善表单信息',
  752. type: 'warning'
  753. })
  754. return false
  755. }
  756. const isValid = this.toshopData.formProList.some(item => {
  757. if (item.isNeed && !item.value) {
  758. this.$message({
  759. message: '必填项不能为空',
  760. type: 'warning'
  761. })
  762. return true
  763. }
  764. if (this.containsAllChineseCharacters(item.name, '手机') && item.value.length !== 11) {
  765. this.$message({
  766. message: '请输入正确的手机号',
  767. type: 'warning'
  768. })
  769. return true
  770. }
  771. return false
  772. })
  773. if (isValid) return
  774. let cols = []
  775. cols = this.toshopData.formProList.map(item => {
  776. return {
  777. name: item.name,
  778. type: item.type,
  779. value: item.type === 10 ? [JSON.stringify({
  780. province: item.value[0],
  781. city: item.value[1]
  782. })] : [item.value],
  783. }
  784. })
  785. let openId = this.getQueryParam('openId') || localStorage.getItem('openId') || ''
  786. this.loading = true
  787. fetch(this.httpUrl + `/scrm/v1/wxcp-toshop-share/p/formData?clientId=${localStorage.getItem('bkClientId') || ''}&openId=${openId}`, {
  788. method: 'post',
  789. body: JSON.stringify({
  790. bid: this.bId,
  791. cols: cols,
  792. }),
  793. headers: {
  794. 'Content-Type': 'application/json'
  795. }
  796. }).then(res => {
  797. return res.json()
  798. }).then(result => {
  799. let { data, code, msg } = result
  800. if (data) {
  801. this.verificationCode = data.client.verificationCode
  802. if (data.client.state === 2) {
  803. // 已提交表单
  804. this.step = 3
  805. if (data.client.formData) {
  806. let arr = JSON.parse(data.client.formData)
  807. const filteredItems = arr.filter(item => item.name.includes("门店"))
  808. if (filteredItems.length) {
  809. const names = filteredItems.map(item => item.value[0])
  810. this.storeName = names[0]
  811. }
  812. }
  813. } else if (data.client.state === 3) {
  814. // 已核销
  815. this.step = 4
  816. } else if (data.client.state === -1) {
  817. // 不符合资格
  818. this.step = 5
  819. }
  820. } else {
  821. this.$message({
  822. message: msg,
  823. type: 'warning'
  824. })
  825. }
  826. }).finally(() => {
  827. this.loading = false
  828. })
  829. }
  830. },
  831. // 检查字符串中是否包含所有指定的中文字符
  832. containsAllChineseCharacters (str, chineseChars) {
  833. // 将要检查的字符拆分为数组
  834. const charsArray = chineseChars.split('')
  835. // 遍历每个字符并检查是否存在
  836. for (const char of charsArray) {
  837. if (!str.includes(char)) {
  838. return false
  839. }
  840. }
  841. return true
  842. },
  843. // 检测是否iOS端
  844. iosAgent () {
  845. return navigator.userAgent.match(/(iPhone|iPod|iPad);?/i);
  846. },
  847. // 复制文本函数,微信端,需要在用户触发 Click 事件里面才能执行成功
  848. handleCopy (message) {
  849. if (this.iosAgent()) {
  850. let inputObj = document.createElement("input");
  851. inputObj.value = message;
  852. document.body.appendChild(inputObj);
  853. inputObj.select();
  854. inputObj.setSelectionRange(0, inputObj.value.length);
  855. this.execCommand('Copy');
  856. document.body.removeChild(inputObj);
  857. } else {
  858. let domObj = document.createElement("span");
  859. domObj.innerHTML = message;
  860. document.body.appendChild(domObj);
  861. let selection = window.getSelection();
  862. let range = document.createRange();
  863. range.selectNodeContents(domObj);
  864. selection.removeAllRanges();
  865. selection.addRange(range);
  866. this.execCommand('Copy');
  867. document.body.removeChild(domObj);
  868. }
  869. },
  870. // 执行浏览器命令 Copy 顺便输出一下日志,如果在移动端推荐写个方法展示日志或者用alert(msg)也行。
  871. execCommand (action) {
  872. let is = document.execCommand(action);
  873. if (is) {
  874. this.$message({
  875. message: '复制成功',
  876. type: 'success'
  877. })
  878. } else {
  879. this.$message({
  880. message: '复制失败',
  881. type: 'error'
  882. })
  883. }
  884. },
  885. // 截取url中的数据
  886. getQueryParam (paramName) {
  887. // 获取当前URL的查询字符串部分
  888. const queryString = window.location.search;
  889. // 创建一个URLSearchParams对象
  890. const urlParams = new URLSearchParams(queryString);
  891. // 返回指定参数的值,如果不存在则返回null
  892. return urlParams.get(paramName);
  893. },
  894. // 判断当前是否为微信浏览器
  895. isWeChatBrowser() {
  896. const ua = navigator.userAgent.toLowerCase();
  897. return ua.includes('micromessenger');
  898. },
  899. }
  900. })
  901. </script>
  902. </html>