registrationActivity.html 23 KB

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