You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

signContract.vue 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516
  1. <template>
  2. <view class="content" v-if="online === 2">
  3. <image class="bg-image" mode="widthFix"
  4. src="https://qtzl.etcjz.cn/default-bucket/20240324/3eba2095f5204798a1f8101b_beijing.jpg"></image>
  5. <view class="content-re">
  6. <custom-header title="支付账户签约" :back="false"></custom-header>
  7. <view style="padding: 20rpx 0 30rpx" class="order-content">
  8. <!-- 获取产品展示 -->
  9. <view class="order-car" v-for="(item, index) in paymentChannelList" :key="index">
  10. <view class="l-img">
  11. <image class="icon-tip" :src="item.imgUrl" mode="aspectFit"></image>
  12. </view>
  13. <view class="c-amount">
  14. <view class="goods-name">
  15. {{ item.name }}
  16. </view>
  17. <view class="goods-des">
  18. {{ item.desc }}
  19. </view>
  20. <view class="goods-label">
  21. <view class="label-item" v-for="(labelItem, index) in item.label" :key="index">
  22. <u-tag :text="labelItem" mode="light" size="mini" bg-color="#38ca83" border-color="#38ca83"
  23. color="#fff" />
  24. </view>
  25. </view>
  26. </view>
  27. <view class="r-btn">
  28. <u-button shape="circle" plain class="custom-style" @click="handleCon">
  29. 签约
  30. </u-button>
  31. </view>
  32. </view>
  33. </view>
  34. </view>
  35. <u-popup v-model="show" mode="right" :closeable="true" length="100%" z-index="990">
  36. <view style="background-color: #f4f4f4; height: 100vh; position: relative">
  37. <view class="title">签约</view>
  38. <view class="slot-content">
  39. <view style="background-color: #fff">
  40. <view class="con-img">
  41. <!-- <qrcode-vue :value="qrCodeValue" level="H" :render-as="renderAs" style='width: 100%;height: 100%;' /> -->
  42. <image style="width: 100%; height: 100%" :src="imageSign" mode="aspectFit"></image>
  43. </view>
  44. <view class="con-info">请打开微信扫码完成签约</view>
  45. </view>
  46. </view>
  47. <view class="bottom-btn">
  48. <button type="success" class="btn-txt btn" @click="handleNext">
  49. 下一步
  50. </button>
  51. </view>
  52. </view>
  53. </u-popup>
  54. </view>
  55. </template>
  56. <script setup lang="ts">
  57. import { fileURL } from '@/utils/network/api.js';
  58. import { reactive, ref } from 'vue';
  59. import { unifyTemplate } from '@/hooks/unifyTemplate';
  60. import { onLoad } from '@dcloudio/uni-app';
  61. import { request, requestNew } from '@/utils/network/request';
  62. import wx from 'weixin-js-sdk';
  63. import QrcodeVue, { Level, RenderAs } from 'qrcode.vue';
  64. import { setToken, getToken, StorageKeys, setItem } from '@/utils/storage';
  65. import { handleToTypes } from '@/utils/utils';
  66. const {
  67. CustomHeader //头部组件
  68. } = unifyTemplate(); //初始化数据
  69. const qrCodeValue = ref('111')
  70. const {
  71. initData, //初始化数据
  72. qdOrderVal //qdOrder中数据 ref
  73. } = unifyTemplate(); //初始化数据
  74. const online = ref(1); //1为线上,2为线下
  75. const jumpPage = ref('pages/payment/signAContract');
  76. //获取页面配置
  77. onLoad((opin) => {
  78. initData(opin, 4).then(async (data) => {
  79. uni.showLoading({
  80. title: '加载中',
  81. mask: true
  82. });
  83. // if (opin.jumpPage) {
  84. // jumpPage.value = opin.jumpPage
  85. // }
  86. jumpPage.value = data.config.jumpPage || jumpPage.value;
  87. online.value = data.order.promotionModes;
  88. await login(data);
  89. let key = await contractTesting(
  90. qdOrderVal.value.orderNo,
  91. jumpPage.value,
  92. true
  93. );
  94. if (key) {
  95. return;
  96. }
  97. if (data.order.promotionModes === 1) {
  98. // 线上直接去内部判断
  99. handleToType(data.order.orderNo);
  100. } else {
  101. uni.hideLoading();
  102. getCodeIamge(data.order.orderNo);
  103. }
  104. });
  105. });
  106. // 获取签约二维码
  107. const getCodeIamge = (orderId) => {
  108. let data = {
  109. orderId,
  110. accessToken: loginData.token
  111. };
  112. // const code = '5f0b52cc55b94827840966e3af05ec53' //原有签约
  113. // const code = '79d2e1d45b88470985b358394748e45e'//更改签约
  114. requestNew('/iaw/issue/order/generateOrderSignQR', {
  115. data
  116. }).then((res) => {
  117. if (res.code === 0) {
  118. let bizContent = res.data;
  119. const reg = /^\//;
  120. if (!reg.test(bizContent.codeUrl)) {
  121. bizContent.codeUrl = '/' + bizContent.codeUrl;
  122. }
  123. // 处理为完整路径
  124. imageSign.value =
  125. window.location.protocol +
  126. '//' +
  127. window.location.host +
  128. bizContent.codeUrl;
  129. console.log('签约图片', bizContent);
  130. }
  131. });
  132. };
  133. // 无感登录,如果没有登录调用登录
  134. const loginData = reactive({
  135. token: '',
  136. openId: ''
  137. });
  138. async function login(orderData) {
  139. let data = {
  140. userType: '',
  141. accountNumber: '',
  142. loginSource: '431bfdc8b9c645e0b293b85d6ce1948n',
  143. };
  144. if (orderData.order.userType === 'PERSONAL_USER') {
  145. // 个人办理
  146. data.userType = 'PERSONAL';
  147. data.accountNumber = orderData.order.customerTel;
  148. } else {
  149. // 单位办理
  150. data.userType = 'ENTERPRISE';
  151. data.accountNumber = orderData.order.customerIdnum;
  152. }
  153. console.log(data, '无感登录', qdOrderVal.value);
  154. await requestNew('/iaw/portal/loginByNoPassword', {
  155. data
  156. }).then((res) => {
  157. if (res.code === 0) {
  158. let data = res.data;
  159. console.log('login', data);
  160. setToken(data.accessToken);
  161. setItem(StorageKeys.OpenId, data.openId)
  162. // 保存token
  163. loginData.token = data.accessToken;
  164. loginData.openId = data.openId;
  165. }
  166. });
  167. }
  168. // 处理进入类型
  169. const handleToType = (orderNo) => {
  170. let type = parseInt(uni.getStorageSync('web_type')) || '';
  171. let userAgent = navigator.userAgent.toLowerCase();
  172. console.log('类型', type);
  173. const agentType = handleToTypes();
  174. if (type) {
  175. if (type === 1) {
  176. // 微信小程序
  177. handleTonei();
  178. } else if (type === 2) {
  179. // 微信公众号
  180. handleToWai();
  181. } else if (type === 3) {
  182. // 支付宝小程序
  183. handleToZhifubao();
  184. } else {
  185. uni.hideLoading();
  186. getCodeIamge(orderNo);
  187. }
  188. } else {
  189. if (agentType === 'alipaymini') {
  190. // 支付宝小程序环境
  191. handleToZhifubao();
  192. } else if (agentType === 'wechatmini') {
  193. // 微信内部
  194. handleTonei();
  195. } else if (agentType === 'wechat') {
  196. // 微信公众号
  197. handleToWai();
  198. } else {
  199. uni.hideLoading();
  200. online.value = 2;
  201. getCodeIamge(orderNo);
  202. }
  203. }
  204. };
  205. const paymentChannelList = [
  206. {
  207. name: '微信支付',
  208. imgUrl: `${fileURL}image/applyCard/wx.png`,
  209. desc: '服务费是每笔交易金额的0',
  210. label: ['微信代付', '微信便捷支付']
  211. }
  212. ];
  213. const show = ref(false);
  214. const imageSign = ref<String>('');
  215. const renderAs = ref<RenderAs>('svg');
  216. // 签约按钮
  217. function handleCon() {
  218. show.value = true;
  219. }
  220. // 点击下一步
  221. function handleNext() {
  222. contractTesting(qdOrderVal.value.orderNo, jumpPage.value);
  223. }
  224. // 跳转支付宝小程序
  225. function handleToZhifubao() {
  226. let token = loginData.token;
  227. let openId = loginData.openId;
  228. my.navigateTo({
  229. // appid:'2021004102619032',
  230. url: `/subpackage/orders/sign/sign-up-ali?token=${token}&openId=${openId}&orderId=${qdOrderVal.value.orderNo}&qdOrderNo=${qdOrderVal.value.orderNo}`
  231. });
  232. }
  233. // 跳转微信小程序内部
  234. function handleTonei() {
  235. let token = loginData.token;
  236. let openId = loginData.openId;
  237. // let data = JSON.parse(res.data.rd.bizContent)
  238. wx.miniProgram.navigateTo({
  239. // appId: 'wx008c60533388527a', // 要打开的小程序的AppID
  240. // url: `/pages/sign/auth?accessToken=${token}&openId=${openId}&orderId=${qdOrderVal.value.qtOrderNo}&qdOrderNo=${qdOrderVal.value.qdOrderNo}&reset=111`, // 可选,小程序的页面路径,可以不填
  241. url: `/carPark/pages/dmc/signingAContract/signingAContract?accessToken=${token}&openId=${openId}&orderId=${qdOrderVal.value.orderNo}&qdOrderNo=${qdOrderVal.value.orderNo}&reset=111`, // 可选,小程序的页面路径,可以不填
  242. extraData: {
  243. // 可选,传递给小程序的数据,如分享信息等
  244. },
  245. success(res) {
  246. // 打开小程序成功的回调
  247. // console.log(res);
  248. // alert(JSON.stringify(res) + '123')
  249. },
  250. fail(err) {
  251. // 打开小程序失败的回调
  252. // console.error(err);
  253. // alert(JSON.stringify(err) + '456')
  254. }
  255. });
  256. }
  257. // 跳转微信小程序-外链
  258. function handleToWai() {
  259. let token = loginData.token;
  260. let openId = loginData.openId;
  261. let getTokenUrl =
  262. '/cgi-bin/token?grant_type=client_credential&appid=wx008c60533388527a&secret=95197718b43b497f02732bd9f8011080';
  263. let getUrl = '/wxa/generatescheme?access_token=';
  264. uni.request({
  265. url: getTokenUrl,
  266. method: 'GET', //请求方式,必须为大写
  267. success: (res) => {
  268. // console.log('接口返回------', res);
  269. let accessToken = res.data['access_token'];
  270. uni.request({
  271. url: getUrl + accessToken,
  272. method: 'POST', //请求方式,必须为大写
  273. data: {
  274. jump_wxa: {
  275. path: '/carPark/pages/dmc/signingAContract/signingAContract',
  276. query: `accessToken=${token}&openId=${openId}&orderId=${qdOrderVal.value.orderNo}&qdOrderNo=${qdOrderVal.value.orderNo}&reset=111`,
  277. env_version: 'develop' //正式版为"release",体验版为"trial",开发版为"develop",仅在微信外打开时生效。
  278. }
  279. },
  280. success: (res) => {
  281. console.log('接口返回------', res);
  282. if (res.data.errcode === 0) {
  283. location.href = res.data.openlink;
  284. }
  285. uni.hideLoading();
  286. }
  287. });
  288. }
  289. });
  290. }
  291. // 签约检测
  292. const contractTesting = async (orderNo, jumpPage, isInit = false) => {
  293. const data = {
  294. orderNo: orderNo
  295. };
  296. return await requestNew('/iaw/h5/order/web/signcheck', {
  297. data
  298. }).then((res) => {
  299. if (res.code === 0) {
  300. const data = res.data;
  301. if (
  302. data.signStatus === 1 &&
  303. data.accountStatus === 1 &&
  304. data.bindStatus === 1
  305. ) {
  306. // 上面三值都为1才进行下一步,否则进行签约初始化
  307. uni.navigateTo({
  308. url: '/' + jumpPage + `?qdOrderNo=${orderNo}`,
  309. animationType: 'pop-in',
  310. animationDuration: 500
  311. });
  312. return true;
  313. /* 自定义返回 */
  314. } else {
  315. // 进行签约初始化
  316. // 提醒未通过
  317. if (!isInit) {
  318. uni.showModal({
  319. title: '提示',
  320. content: '请使用微信扫描二维码进行签约',
  321. success: function (res) { }
  322. });
  323. }
  324. }
  325. // qdOrderStore.orderInfo.value.orderId = JSON.parse(res.bizContent).orderId
  326. // 通过检测
  327. }
  328. });
  329. };
  330. // async function contractTesting(qdOrderNo, jumpPage, isInit = false) {
  331. // const data = {
  332. // qdOrderNo
  333. // };
  334. // // uni.navigateTo({
  335. // // url: '/' + jumpPage,
  336. // // animationType: 'pop-in',
  337. // // animationDuration: 500
  338. // // })
  339. // // signingInitialization(qdOrderNo)
  340. // // return
  341. // uni.showModal({
  342. // title: '提示',
  343. // content: '请使用微信扫描二维码进行签约',
  344. // success: (res) =>{
  345. // console.log(res);
  346. // },
  347. // fail:(err)=>{
  348. // console.log(err);
  349. // }
  350. // });
  351. // return request('fdfbdddba6ec49f8b451cf2e299b4feb', {
  352. // data
  353. // }).then((res) => {
  354. // if (res.statusCode === 0) {
  355. // const data = JSON.parse(res.bizContent);
  356. // if (
  357. // data.signStatus === 1 &&
  358. // data.accountStatus === 1 &&
  359. // data.bindStatus === 1
  360. // ) {
  361. // // 上面三值都为1才进行下一步,否则进行签约初始化
  362. // uni.navigateTo({
  363. // url: '/' + jumpPage + `?qdOrderNo=${qdOrderNo}`,
  364. // animationType: 'pop-in',
  365. // animationDuration: 500
  366. // });
  367. // return true;
  368. // /* 自定义返回 */
  369. // } else {
  370. // // 进行签约初始化
  371. // // 提醒未通过
  372. // console.log('isInit', isInit);
  373. // if (!isInit) {
  374. // console.log('isInit', isInit, uni.showModal);
  375. // uni.showModal({
  376. // title: '提示',
  377. // content: '请使用微信扫描二维码进行签约',
  378. // success: function (res) {}
  379. // });
  380. // }
  381. // }
  382. // // qdOrderStore.orderInfo.value.orderId = JSON.parse(res.bizContent).orderId
  383. // // 通过检测
  384. // }
  385. // });
  386. // }
  387. </script>
  388. <!-- 签约管理 -->
  389. <style lang="scss" scoped>
  390. .order-car {
  391. margin: 30rpx 30rpx 0;
  392. width: calc(100% - 60rpx);
  393. height: 190rpx;
  394. border-radius: 20rpx;
  395. background-image: linear-gradient(to right, #15e5c3, #44a2df);
  396. display: flex;
  397. justify-content: space-between;
  398. box-shadow: rgba(99, 99, 99, 0.2) 0px 2px 8px 0px;
  399. align-items: center;
  400. color: #fff;
  401. .l-img {
  402. flex-shrink: 0;
  403. width: 120rpx;
  404. height: 120rpx;
  405. .icon-tip {
  406. height: 100%;
  407. width: 100%;
  408. object-fit: contain;
  409. }
  410. }
  411. .c-amount {
  412. flex: 1;
  413. padding: 20rpx 0;
  414. height: 100%;
  415. box-sizing: border-box;
  416. .goods-name {
  417. margin-bottom: 15rpx;
  418. font-size: 38rpx;
  419. }
  420. .goods-des {
  421. font-size: 26rpx;
  422. margin-bottom: 15rpx;
  423. color: #eff;
  424. }
  425. .goods-label {
  426. display: flex;
  427. align-items: center;
  428. .label-item {
  429. margin-right: 10rpx;
  430. }
  431. }
  432. }
  433. .r-btn {
  434. margin-left: 10rpx;
  435. flex-shrink: 0;
  436. width: 130rpx;
  437. margin-right: 20rpx;
  438. .custom-style {
  439. height: 70rpx;
  440. color: #fff;
  441. border-color: #fff;
  442. background-color: rgba(255, 255, 255, 0.2);
  443. }
  444. }
  445. }
  446. .title {
  447. font-size: 36rpx;
  448. text-align: center;
  449. font-weight: bold;
  450. padding: 20rpx 0;
  451. }
  452. .slot-content {
  453. display: flex;
  454. flex-direction: column;
  455. justify-content: center;
  456. align-items: center;
  457. position: absolute;
  458. top: 40%;
  459. left: 50%;
  460. transform: translate(-50%, -50%);
  461. .con-img {
  462. width: 550rpx;
  463. height: 550rpx;
  464. padding: 100rpx;
  465. box-sizing: border-box;
  466. }
  467. .con-info {
  468. text-align: center;
  469. font-size: 26rpx;
  470. margin-bottom: 100rpx;
  471. }
  472. }
  473. .bottom-btn {
  474. position: absolute;
  475. padding: 20rpx;
  476. display: flex;
  477. align-items: center;
  478. bottom: 100rpx;
  479. width: 750rpx;
  480. .btn {
  481. height: 80rpx;
  482. opacity: 1;
  483. border-radius: 100rpx;
  484. margin: 20rpx 20rpx 20rpx 20rpx;
  485. width: 100%;
  486. }
  487. .btn-txt {
  488. background: #1aac1b;
  489. margin: 10px;
  490. color: #ffffff;
  491. font-size: 28rpx;
  492. }
  493. }
  494. </style>