選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

product-detail.vue 14KB

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