您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

product-detail.vue 15KB

1周前
1周前
1 个月前
10 个月前
10 个月前
10 个月前
1年前
1年前
10 个月前
1年前
10 个月前
10 个月前
10 个月前
1年前
1年前
10 个月前
1年前
1年前
10 个月前
10 个月前
1年前
10 个月前
1年前
10 个月前
1年前
11 个月前
10 个月前
1年前
1年前
1年前
1年前
1年前
10 个月前
1周前
2 年前
1年前
10 个月前
8 个月前
1周前
1周前
1周前
11 个月前
11 个月前
10 个月前
11 个月前
8 个月前
8 个月前
8 个月前
7 个月前
7 个月前
8 个月前
8 个月前
8 个月前
1周前
8 个月前
10 个月前
10 个月前
10 个月前
10 个月前
10 个月前
10 个月前
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611
  1. <template>
  2. <view class="container">
  3. <view class="t-card">
  4. <view class="title">
  5. <image :src="`${$imgUrl}issuance/title-bg.png`" mode="aspectFit" class='bg'></image>
  6. <image :src="`${$imgUrl}issuance/bg-xia.png`" mode="aspectFit" class='bg-xia'></image>
  7. <view class="txt">
  8. 合同签署
  9. </view>
  10. </view>
  11. <view class="value">
  12. <view class="item">
  13. <view class="l-icon"></view>
  14. <view class="r-txt">
  15. 尊敬的车主用户,为保障您与我们的权益,ETC办理需签署电子合同,该合同严格遵循《电子签名法》,与纸质合同具有同等法律效力。
  16. </view>
  17. </view>
  18. <view class="item item2">
  19. <view class="l-icon"></view>
  20. <view class="r-txt">
  21. 签署前请您认真阅读合同中条款内容,然后完成合同签署,若您有疑问可随时联系客服解答,感谢您的理解与支持!
  22. </view>
  23. </view>
  24. </view>
  25. <view class="as-layout-horizontal agreement">
  26. <view class="checked-group" @click="checkboxChange">
  27. <!-- <checkbox :checked="state.checked" style="transform: scale(0.65)" /> -->
  28. <view class="column-checkbox">
  29. <view class="checkbox-icon" :class="{'is-checked': state.checked}">
  30. <u-icon name="checkbox-mark" :color="state.checked ? '#FFFFFF' : '#FFFFFF'"></u-icon>
  31. </view>
  32. </view>
  33. <text class='txt'>我已阅读并同意</text>
  34. <!-- <text class='txt'>签署协议</text> -->
  35. </view>
  36. <text v-for="(item,index) in state.agreeURL" class="txt xieyi" @click="downAuthD(item)">《{{item.name}}》</text>
  37. </view>
  38. </view>
  39. </view>
  40. <FixedFooter>
  41. <view class="footer-action">
  42. <!-- <button type="default" class="button" @click="goSign()">去签署</button> -->
  43. <button type="default" class="button" @click="queryAgreement()">下一步</button>
  44. </view>
  45. </FixedFooter>
  46. </template>
  47. <script setup lang="ts">
  48. import FixedFooter from '@/components/common/FixedFooter.vue'
  49. import {
  50. onLoad, onShow
  51. } from "@dcloudio/uni-app";
  52. import {
  53. reactive,
  54. ref
  55. } from "vue";
  56. import {
  57. getOpenId,
  58. envs, payQuery, agreementInSertOrder, agreeOrderProdcut, contractQuery, accountSign
  59. } from "@/utils/network/api.js";
  60. import { requestNew } from "@/utils/network/request.js";
  61. import {
  62. stringToJson
  63. } from "@/utils/network/encryption";
  64. import navBgCar from "./components/nav-bg-car1";
  65. import navBar from "@/components/nav-bar/nav-bar2.vue";
  66. import {
  67. msg, navTo
  68. } from "@/utils/utils";
  69. let signFlag = "NO";//触发按钮标识
  70. const savaHandle = () => {
  71. console.log("state.productId.length", state.productId.length, "111", state.typeScanCode)
  72. if (state.typeScanCode == 2) {
  73. console.log("233")
  74. // 扫码进来
  75. if (state.checked) {
  76. agreementConfirm().then((value) => {
  77. console.log("协议确认", value)
  78. msg("协议确认成功");
  79. })
  80. } else {
  81. msg("请勾选协议");
  82. }
  83. } else {
  84. console.log("state.checked", state.checked)
  85. if (state.checked) {
  86. agreementConfirm().then((value) => {
  87. console.log("协议确认", value)
  88. navTo(
  89. `/subpackage/orders/order_payment?orderId=${state.orderId}&&clientFee=${state.clientFee}&&id=${state.id}&&isValueCard=${state.isValueCard}&vehicleId=${state.vehicleId}`,
  90. );
  91. })
  92. } else {
  93. msg("请勾选协议");
  94. }
  95. }
  96. };
  97. const downAuthD = (item) => {
  98. console.log('=======123', item)
  99. console.log("uni.env.USER_DATA_PATH '", uni.env.USER_DATA_PATH + '/' + '产品协议.docx')
  100. // 文件后缀截取
  101. var index = item.url.lastIndexOf("\.");
  102. let fileType = item.url.substring(index + 1, item.url.length);
  103. let arr = item.url.split(".");
  104. fileType = arr[arr.length - 1];
  105. console.log("fileType", fileType)
  106. uni.downloadFile({
  107. url: item.url,
  108. // filePath: uni.env.USER_DATA_PATH + '/' + item.name + '.' + fileType,
  109. // uni.env.USER_DATA_PATH + '/' + item.name + '.' + fileType
  110. success(res) {
  111. console.log("文件下载返回数据:", res)
  112. const filePath = res.tempFilePath
  113. console.log("filePath", filePath)
  114. uni.openDocument({
  115. filePath: filePath,
  116. fileType: fileType,
  117. showMenu: true, //关键点
  118. success: function (res) {
  119. state.isWatchContract = true
  120. },
  121. fail: function (err) {
  122. msg("打开文档失败");
  123. }
  124. });
  125. },
  126. fail: function (err) {
  127. msg("下载文档失败");
  128. console.log("err", err)
  129. },
  130. complete(res) {
  131. }
  132. })
  133. }
  134. //获取微信小程序openid
  135. const getOpenID = () => {
  136. uni.login({
  137. provider: "weixin",
  138. success: function (e) {
  139. getOpenid(e.code);
  140. },
  141. });
  142. };
  143. const getOpenid = (code) => {
  144. const options = {
  145. type: 2,
  146. data: {
  147. "jsCode": code
  148. },
  149. method: "POST",
  150. showLoading: true,
  151. };
  152. // #ifdef MP-WEIXIN
  153. requestNew(getOpenId, options).then((res) => {
  154. const result = res;
  155. console.log("获取微信小程序openid", result);
  156. const openidData = stringToJson(result.bizContent);
  157. console.log("获取微信小程序openid====", openidData);
  158. state.openid = openidData.openid;
  159. refresh();
  160. });
  161. // #endif
  162. }
  163. // 协议确认接口
  164. const agreementConfirm = () => {
  165. const options = {
  166. type: 2,
  167. data: {
  168. orderId: state.orderId,
  169. protocol: state.checked ? 1 : 0,
  170. agreements: state.agreements
  171. },
  172. method: "POST",
  173. showLoading: true,
  174. };
  175. return new Promise(async (resolve, reject) => {
  176. const res = await requestNew(agreeOrderProdcut, options);
  177. const data = res;
  178. console.log("确认协议", data)
  179. resolve(data);
  180. }).catch((error) => {
  181. reject(error);
  182. });
  183. };
  184. onLoad((option : any) => {
  185. state.orderId = option.orderId;
  186. state.isValueCard = option.isValueCard;
  187. state.redirectUrl = option.redirectUrl // 重定向页面
  188. console.log("传递过来的参数", option)
  189. console.log("查协议", envs[process.env.NODE_ENV].baseUrl)
  190. state.id = option.id;
  191. state.vehicleId = option.vehicleId;
  192. // getOpenID();
  193. if (option.typeScanCode) {
  194. state.typeScanCode = option.typeScanCode
  195. console.log("state.agreeURL", state.agreeURL)
  196. }
  197. queryAgreement();
  198. });
  199. onShow(() => {
  200. contractRequest()
  201. })
  202. const state = reactive({
  203. openid: "",
  204. orderId: "",
  205. clientFee: undefined,
  206. id: "",
  207. options2: [{
  208. text: '删除',
  209. style: {
  210. backgroundColor: '#F56C6C'
  211. }
  212. }],
  213. list: [],
  214. productMoney: 0,
  215. allMoney: 0,
  216. productId: [],
  217. // 弹框
  218. type: 'center',
  219. msgType: 'success',
  220. messageText: '这是一条成功提示',
  221. value: '',
  222. detailsObj: '',
  223. isValueCard: "",
  224. dataArray: [],
  225. checked: false,
  226. agreeURL: [],
  227. typeScanCode: 0,//扫码进来得
  228. vehicleId: "",
  229. agreements: [],
  230. isSign: false,
  231. isWatchContract: false,
  232. redirectUrl: ''
  233. });
  234. // 查协议
  235. const queryAgreement = () => {
  236. if(signFlag === "NO") return;
  237. const options = {
  238. type: 2,
  239. data: {
  240. orderNo: state.orderId, //订单编号
  241. customerId: "",
  242. protocol: state.checked ? 1 : 0,
  243. },
  244. method: "POST",
  245. showLoading: true,
  246. };
  247. if (state.isSign) {
  248. if (state.checked) {
  249. requestNew(agreementInSertOrder, options).then((res) => {
  250. goNextPage()
  251. });
  252. } else {
  253. msg("请勾选协议");
  254. }
  255. } else {
  256. if (state.checked) {
  257. goNextPage()
  258. } else {
  259. msg("请勾选协议");
  260. }
  261. }
  262. }
  263. const goNextPage = () => {
  264. if (state.redirectUrl) {
  265. navTo(decodeURIComponent(state.redirectUrl))
  266. } else {
  267. navTo(
  268. `/subpackage/orders/order_payment?orderId=${state.orderId}&&clientFee=${state.clientFee}&&id=${state.id}&&isValueCard=${state.isValueCard}&vehicleId=${state.vehicleId}`,
  269. );
  270. }
  271. }
  272. const checkboxChange = () => {
  273. // wx.navigateToMiniProgram({
  274. // appId: 'wx371151823f6f3edf', // 电子签appId; 联调时, 请使用demo小程序appId: 'wx371151823f6f3edf'
  275. // path: 'pages/home/home-index', // 跳转的页面路径,可选,默认跳转到目标小程序首页; 签署时,需使用后台API返回的完整链接(类似pages/guide?id=xxx&foo=bar)
  276. // extraData: { // 需要传递给目标小程序的数据,可选;签署时,腾讯电子签小程序未使用到该参数
  277. // foo: 'bar'
  278. // },
  279. // envVersion: 'release', // 跳转正式或demo小程序,都需要传 'release'
  280. // success(res) {
  281. // // 成功跳转到目标小程序后的回调函数
  282. // console.log(res)
  283. // },
  284. // fail(res) {
  285. // console.log(res)
  286. // // 跳转失败的回调函数
  287. // }
  288. // })
  289. if (state.isWatchContract) {
  290. state.checked = !state.checked;
  291. } else {
  292. msg("请先阅读相关文件");
  293. }
  294. };
  295. const refresh = () => {
  296. let source = ""
  297. // #ifdef MP-ALIPAY
  298. source = "ALI"
  299. // #endif
  300. // #ifdef MP-WEIXIN
  301. source = "WECHAT"
  302. // #endif
  303. var data = {
  304. orderNo: state.orderId,
  305. wxOpenId: state.openid,
  306. };
  307. const options = {
  308. type: 2,
  309. data: data,
  310. method: "POST",
  311. showLoading: true,
  312. };
  313. console.log("输出内容", options);
  314. requestNew(payQuery, options).then((res) => {
  315. const data = res
  316. console.log(data);
  317. if (data.paymentStatus == 'ALLSUCCESS') {
  318. state.allMoney = data.sumFee * 0.01
  319. return;
  320. }
  321. state.dataArray = data.datas;
  322. // HANDLE("办理费",1){},
  323. // MARGIN("保证金",2){},
  324. // PRESTORE("预存金",3){},
  325. // EQUITY("权益费",4){},
  326. for (let i = 0; i < state.dataArray.length; i++) {
  327. if (state.dataArray[i].payType === 'HANDLE') {
  328. state.dataArray[i].payName = '权益金'
  329. } else if (state.dataArray[i].payType === 'MARGIN') {
  330. state.dataArray[i].payName = '保证金'
  331. } else if (state.dataArray[i].payType === 'PRESTORE') {
  332. state.dataArray[i].payName = '预存金'
  333. } else if (state.dataArray[i].payType === 'EQUITY') {
  334. state.dataArray[i].payName = '权益费'
  335. } else {
  336. state.dataArray[i].payName = '未知费'
  337. }
  338. // SUCCESS("支付成功",1){},
  339. // PAYING("支付中",2){},
  340. // FAILED("支付失败",3){},
  341. // UNPAY("未支付",4){},
  342. // CLOSED("已关闭",5){},
  343. // CANCELED("已撤销",6){},
  344. // REFUND("转入退费",7){},
  345. if (state.dataArray[i].payStatus === 'SUCCESS') {
  346. state.dataArray[i].payStatusName = '已支付'
  347. } else if (state.dataArray[i].payStatus === 'PAYING') {
  348. state.dataArray[i].payStatusName = '支付中'
  349. } else if (state.dataArray[i].payStatus === 'FAILED') {
  350. state.dataArray[i].payStatusName = '支付失败'
  351. } else if (state.dataArray[i].payStatus === 'UNPAY') {
  352. state.dataArray[i].payStatusName = '未支付'
  353. } else if (state.dataArray[i].payStatus === 'CLOSED') {
  354. state.dataArray[i].payStatusName = '已关闭'
  355. } else if (state.dataArray[i].payStatus === 'CANCELED') {
  356. state.dataArray[i].payStatusName = '已撤销'
  357. } else if (state.dataArray[i].payStatus === 'REFUND') {
  358. state.dataArray[i].payStatusName = '转入退费'
  359. } else {
  360. state.dataArray[i].payStatusName = '未知'
  361. }
  362. state.allMoney += state.dataArray[i]["fee"] * 0.01
  363. }
  364. console.log("state.dataArray", state.dataArray)
  365. });
  366. }
  367. // 去签署协议
  368. const sign = () => {
  369. const options = {
  370. type: 2,
  371. data: {
  372. orderId: state.orderId, //订单编号
  373. },
  374. method: "POST",
  375. showLoading: true,
  376. };
  377. requestNew(accountSign, options).then((res) => {
  378. uni.navigateToMiniProgram({
  379. appId: 'wxeee4ac6e61915479',
  380. path: `/pages/externel/view/view?random=${res.random}&envType=product`,
  381. envVersion: 'release',
  382. fail: (error) => {
  383. console.log(error);
  384. }
  385. })
  386. console.log("去签署协议", res)
  387. });
  388. }
  389. // 查询是否签署协议
  390. const contractRequest = () => {
  391. const options = {
  392. type: 2,
  393. data: {
  394. orderNo: state.orderId, //订单编号
  395. },
  396. method: "POST",
  397. showLoading: true,
  398. };
  399. requestNew(contractQuery, options).then((res) => {
  400. if (res.flag) {
  401. state.isSign = true
  402. } else {
  403. state.isSign = false
  404. }
  405. signFlag = "YES"
  406. console.log("查询是否签署协议", res)
  407. let data = res;
  408. let supAgreeArr = data.agreements;
  409. if (state.agreeURL && state.agreeURL.length === 0) {
  410. state.agreeURL = [];
  411. console.log("data==", supAgreeArr)
  412. for (var m = 0; m < supAgreeArr.length; m++) {
  413. let obj = {}
  414. for (let key in supAgreeArr[m]) {
  415. obj['name'] = key;
  416. obj['url'] = supAgreeArr[m][key];
  417. state.agreeURL.push(obj);
  418. }
  419. }
  420. }
  421. console.log("查协议", state.agreeURL, state.agreements)
  422. });
  423. }
  424. // 签署
  425. const goSign = () => {
  426. }
  427. </script>
  428. <style>
  429. page{
  430. background: #E9EDF0;
  431. }
  432. </style>
  433. <style lang="scss" scoped>
  434. .t-card {
  435. margin: 30rpx;
  436. background-color: #fff;
  437. border-radius: 12rpx;
  438. padding: 50rpx 30rpx;
  439. }
  440. .title {
  441. margin: 0 auto;
  442. width: 322rpx;
  443. height: 44rpx;
  444. position: relative;
  445. .bg {
  446. width: 322rpx;
  447. height: 44rpx;
  448. }
  449. .bg-xia {
  450. left: 50%;
  451. position: absolute;
  452. width: 200rpx;
  453. height: 8rpx;
  454. transform: translateX(-50%);
  455. bottom: 0;
  456. }
  457. .txt {
  458. font-family: SourceHanSansSC, SourceHanSansSC;
  459. font-weight: bold;
  460. font-size: 36rpx;
  461. color: #004576;
  462. position: absolute;
  463. width: 322rpx;
  464. text-align: center;
  465. bottom: 0;
  466. }
  467. }
  468. .item {
  469. display: flex;
  470. margin-top: 60rpx;
  471. font-size: 28rpx;
  472. font-family: SourceHanSansSC, SourceHanSansSC;
  473. font-weight: 400;
  474. color: #222;
  475. line-height: 48rpx;
  476. .l-icon {
  477. margin-top: 20rpx;
  478. flex-shrink: 0;
  479. border-radius: 50%;
  480. height: 10rpx;
  481. width: 10rpx;
  482. background-color: #004576;
  483. margin-right: 18rpx;
  484. }
  485. }
  486. .item2 {
  487. margin-top: 30rpx;
  488. }
  489. .footer-action {
  490. display: flex;
  491. align-items: center;
  492. justify-content: center;
  493. flex-direction: column;
  494. .btn-tip {
  495. font-family: SourceHanSansSC, SourceHanSansSC;
  496. font-weight: 400;
  497. font-size: 24rpx;
  498. color: #CCB375;
  499. margin-bottom: 14rpx;
  500. display: flex;
  501. align-items: center;
  502. .tip-icon{
  503. width: 26rpx;
  504. height: 26rpx;
  505. margin-right: 10rpx;
  506. }
  507. }
  508. .button {
  509. height: 88rpx;
  510. background: radial-gradient(at 0% 0%, #C6B077 0%, #DFCC96 100%);
  511. border-radius: 40rpx;
  512. font-size: 32rpx;
  513. font-weight: 400;
  514. color: #ffffff;
  515. line-height: 88rpx;
  516. width: 660rpx;
  517. margin: 0 auto;
  518. }
  519. }
  520. .agreement {
  521. font-size: 30rpx;
  522. display: flex;
  523. flex-wrap: wrap;
  524. margin-top: 20rpx;
  525. align-items: center;
  526. .txt {
  527. font-size: 24rpx;
  528. font-family: SourceHanSansCN, SourceHanSansCN;
  529. font-weight: 400;
  530. color: #111111;
  531. }
  532. .xieyi {
  533. color: #999;
  534. text-decoration: underline;
  535. }
  536. }
  537. .checked-group{
  538. display: flex;
  539. align-items: center;
  540. }
  541. .column-checkbox{
  542. display: flex;
  543. align-items: center;
  544. flex: 1;
  545. .u-icon{
  546. font-size: 24rpx;
  547. color: #004576;
  548. }
  549. .checkbox-icon{
  550. width: 32rpx;
  551. height: 32rpx;
  552. border: 1px solid #c8c9cc;
  553. border-radius: 8rpx;
  554. display: flex;
  555. justify-content: center;
  556. align-items: center;
  557. margin-right: 20rpx;
  558. margin-left: 24rpx;
  559. }
  560. .is-checked{
  561. border-color: #004576;
  562. background-color: #004576;
  563. }
  564. .u-icon{
  565. margin-right: 10rpx;
  566. }
  567. }
  568. </style>