diff --git a/env/.env b/env/.env index a9c1363..eb94ac2 100644 --- a/env/.env +++ b/env/.env @@ -10,8 +10,8 @@ VITE_WX_APPID = 'wxa023ce905b13a4de' VITE_APP_PUBLIC_BASE=/ # 后台请求地址localhost -VITE_SERVER_BASEURL = 'http://1.14.158.154:48080/admin-api' -VITE_UPLOAD_BASEURL = 'http://1.14.158.154:48080/upload' +VITE_SERVER_BASEURL = 'https://api.tuanbanlv.com/admin-api' +VITE_UPLOAD_BASEURL = 'https://api.tuanbanlv.com/upload' # 备注:如果后台带统一前缀,则也要加到后面,eg: https://ukw0y1.laf.run/api # 注意,如果是微信小程序,还有一套请求地址的配置,根据 develop、trial、release 分别设置上传地址,见 `src/utils/index.ts`。 diff --git a/private.wxa023ce905b13a4de.key b/private.wxa023ce905b13a4de.key new file mode 100644 index 0000000..ad97be5 --- /dev/null +++ b/private.wxa023ce905b13a4de.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAqu4smP/F2ib/J2+pJp1Y379U8N18eEdNEIi0+Bw/TZSn90sN +mZvTAu/fB1kkSzjHLhvK8+TMTx/WDvD9u/9WpVlBK9rE6bx8+OcFCk5gePqDZdY0 +ybd99D1oicudmO2yU+YMyBD4zM5qvdVyU5EDj6OnV1zB6D5n3pw2thICplYobN5K +osTEBr/c33RX8/3ZbRo0AdyZPcY5I3Uq6vDMCKdmJn4H0klWG3jXYtsen8HVzO3F +UWFFeiZeyBSq5iVBtm6s8w2mQhRbjc6rS0ERalrGL7mV0RjVQauL6TJrIxoI/8v4 +aIOgo7gApFlqTf3nfyZw4OTEPQWrTKM2s7/qIwIDAQABAoIBAG0EoW8n2sHrk1tM +rV7ShmeWeY9yRDvWhgFgn8OLCJjrkkF4HgF10ByUbvQZ17seSHNRCJ2LtP9WN8mp +zLtF/LZS+e0FiAfnzvFVLvLG0GL4rCucdmidXnkTXYRdWHO8TruSA17q7DR8Brpy +04sW92V6pHVk1MvSWZ8ylPaFACmjyPjc/gvUdeZG1v0tUg6069r+RZegLotzhcDi +0T2N9W/0nWFIkNNCQrG5ze24NFD+FmhcNQnx/TQMUeU02JxAfA6sM6jdFcRm1j8Z +M2H/VBe1fOZjQceBHgfeexEBNWNqHB9QJIRdk51+EFC7I+CL1wIvJegrUYAQvwNm +njCzhnkCgYEA2SX45T5Zyicp8FGrYH1ufVRnipO/mwAkvlY8tbFd1C4fPB8Hkbx7 +ZrM5G3293HJ2TBQO+kCIU1WyT9weVeJ7P9bruDyjNOSu1q7d4xjq49LSLXvo7C4+ +T8V7z1fUZt0A0jOdaqfmw+R7ICzQAna8PI/J8elW3Vh7uNk0TRcIXZ0CgYEAyYNI +yrrpabP/sxGYfUpb+Ko6iAcISPTT7rZcN+dVGqqFb8tkvHUSPhhy/H5WYcdFFhzI +S5nMXXmRsgDDRdltukUg4zoA1um5gdI8SeOLzEdcFF0p/Pfc60G+LoY7K/aUlvy2 +DeSpSHJgblZVMKw+2/lfvc2M/100BOjObWkWur8CgYEAgNthqVeonKdE4dD065tD +N6ggkUE/0FDzfOdbu033KfP8oQagzUCV0cnEt6WURv69aEP251XoD9uopm8uqTRu +guGcm4WQK9EQV2EJVrvwlyUBh/AhthVy8I91+wJZjnjTBemPHj1oWRJ6ZgtxnCSt +axrAcYdP/qWFNZneyWhDlJkCgYB+7jwuvteB5oidAetcmDcghhGCV3OniNfqGGI0 +MHoR5vFQPvzAHLoV9Q6Q7v94ba2dxRmBTWpGQuo8BnD6EYAlgZ+6oXGf7e8U0Bl7 +rWIElbpxdVGab4JviaTC53hkM9ja1mnSjIL5CFqnhaf5lbWumADvrIcw30OCCCbn +EffoPwKBgQDU/Q3/lZahWTr4w6NtNmyhi0EnoLv+a9afhYdii1+v5g5PfG0mDvx0 +0lmX2+JNqhF5ZMlVACLY1wR0trz4Iz2LstOst1XE3ipy2zbQTF/g6ujudOxrzOuw +jr+1JcbjZfywRQO+2wgegm8Qut7cZe5AraR6cqzIZ6DUO8QtbmsJnw== +-----END RSA PRIVATE KEY----- diff --git a/src/api/car/renewalorder/index.ts b/src/api/car/renewalorder/index.ts index 6534f32..2d2a663 100644 --- a/src/api/car/renewalorder/index.ts +++ b/src/api/car/renewalorder/index.ts @@ -81,3 +81,13 @@ export function generateContract(id: number) { export function generateContractHtml(id: number) { return http.get(`/car/renewal-order/generate-contract-html?id=${id}`) } + +/** 创建线上签名令牌(用于分享签名) */ +export function createSignToken(id: number) { + return http.post<{ uuid: string; signUrl: string }>('/car/renewal-order/create-sign-token', undefined, { id }) +} + +/** 清空订单合同与客户签名(重新生成合同时先清空再扫码签名) */ +export function clearContractAndSignature(id: number) { + return http.post('/car/renewal-order/clear-contract-sign', undefined, { id }) +} diff --git a/src/api/car/renewalproduct/index.ts b/src/api/car/renewalproduct/index.ts index b517fee..2472fc3 100644 --- a/src/api/car/renewalproduct/index.ts +++ b/src/api/car/renewalproduct/index.ts @@ -7,6 +7,7 @@ export interface RenewalProductVO { productName?: string // 产品名称 productContent?: string // 产品内容 productType?: string // 产品类别 + effectiveYear?: string // 生效年限(仅产品类别为无忧时有值) remark?: string // 备注 } diff --git a/src/pages-system/renewalproduct/detail/index.vue b/src/pages-system/renewalproduct/detail/index.vue index e2d2031..4f9da18 100644 --- a/src/pages-system/renewalproduct/detail/index.vue +++ b/src/pages-system/renewalproduct/detail/index.vue @@ -17,6 +17,9 @@ + + + @@ -54,6 +57,7 @@ import { onLoad, onShow } from '@dcloudio/uni-app' import { computed, onMounted, ref } from 'vue' import { useToast } from 'wot-design-uni' import { deleteRenewalProduct, getRenewalProduct } from '@/api/car/renewalproduct' +import { getDictLabel } from '@/hooks/useDict' import { useAccess } from '@/hooks/useAccess' import { navigateBackPlus } from '@/utils' import { DICT_TYPE } from '@/utils/constants' @@ -73,6 +77,12 @@ const deleting = ref(false) const productId = ref() const productData = ref(null) +/** 仅当产品类别为「无忧」或「无忧延保」时显示生效年限 */ +const showEffectiveYear = computed(() => { + const label = getDictLabel(DICT_TYPE.CAR_RENEWAL_PRODUCT_TYPE, productData.value?.productType) || '' + return label === '无忧' || label === '无忧延保' +}) + /** 返回上一页 */ function handleBack() { navigateBackPlus() @@ -101,6 +111,8 @@ function handleDelete() { try { await deleteRenewalProduct(Number(productId.value)) toast.success('删除成功') + // 标记列表页需要刷新,返回后列表会重新拉取数据 + uni.setStorageSync('renewalproduct_list_need_refresh', true) setTimeout(() => { handleBack() }, 500) diff --git a/src/pages-system/renewalproduct/form/index.vue b/src/pages-system/renewalproduct/form/index.vue index 9427fb0..1599b94 100644 --- a/src/pages-system/renewalproduct/form/index.vue +++ b/src/pages-system/renewalproduct/form/index.vue @@ -36,6 +36,17 @@ label-key="label" value-key="value" /> + { })) }) +// 生效年限选项(仅产品类别为「无忧」时展示) +const effectiveYearOptions = computed(() => { + return getStrDictOptions(DICT_TYPE.CAR_RENEWAL_YEAR).map(item => ({ + label: item.label, + value: item.value, + })) +}) + +/** 仅当产品类别为「无忧」或「无忧延保」时显示生效年限 */ +const showEffectiveYear = computed(() => { + const label = getDictLabel(DICT_TYPE.CAR_RENEWAL_PRODUCT_TYPE, formData.value.productType) || '' + return label === '无忧' || label === '无忧延保' +}) + +// 产品类别切换为「无忧」或「无忧延保」时设置生效年限默认值,切换为其他时清空 +watch( + () => formData.value.productType, + (type) => { + const label = getDictLabel(DICT_TYPE.CAR_RENEWAL_PRODUCT_TYPE, type) || '' + if (label === '无忧' || label === '无忧延保') { + const opts = getStrDictOptions(DICT_TYPE.CAR_RENEWAL_YEAR) + if (opts.length > 0 && !formData.value.effectiveYear) { + formData.value.effectiveYear = opts[0].value + } + } else { + formData.value.effectiveYear = undefined + } + }, +) + const formData = ref({ productName: undefined, productContent: undefined, productType: undefined, + effectiveYear: undefined, remark: undefined, }) @@ -161,6 +203,8 @@ async function handleSubmit() { await createRenewalProduct(formData.value) toast.success('新增成功') } + // 标记列表页需要刷新,返回后列表会重新拉取数据 + uni.setStorageSync('renewalproduct_list_need_refresh', true) setTimeout(() => { navigateBackPlus() }, 500) diff --git a/src/pages-system/renewalproduct/index.vue b/src/pages-system/renewalproduct/index.vue index 9f54c71..9a451fb 100644 --- a/src/pages-system/renewalproduct/index.vue +++ b/src/pages-system/renewalproduct/index.vue @@ -170,16 +170,24 @@ onReachBottom(() => { loadMore() }) -/** 页面显示时刷新(从编辑页面返回时) */ +/** 是否首次显示(首次不依赖 onShow 刷新,由 onMounted 拉取;从子页返回时 onShow 会再次触发并刷新) */ +const isFirstShow = ref(true) + +/** 页面显示时刷新(与订单列表一致:从新增/编辑/详情页返回后刷新列表) */ onShow(() => { - // 检查页面栈,如果上一个页面是编辑页面,则刷新 - const pages = getCurrentPages() - if (pages.length > 1) { - const prevPage = pages[pages.length - 2] - if (prevPage?.route?.includes('/renewalproduct/form/index')) { - getList(true) - } + // 检查存储中的刷新标志(新增、编辑、删除成功后子页会设置) + const needRefresh = uni.getStorageSync('renewalproduct_list_need_refresh') + if (needRefresh) { + uni.removeStorageSync('renewalproduct_list_need_refresh') + getList(true) + isFirstShow.value = false + return } + // 非首次显示时也刷新一次(从表单页或详情页返回,确保列表是最新) + if (!isFirstShow.value) { + getList(true) + } + isFirstShow.value = false }) /** 初始化 */ diff --git a/src/pages/car/renewalorder/add/index.vue b/src/pages/car/renewalorder/add/index.vue index c6f01f2..38c24da 100644 --- a/src/pages/car/renewalorder/add/index.vue +++ b/src/pages/car/renewalorder/add/index.vue @@ -82,6 +82,7 @@ + - + - + - + @@ -187,6 +189,7 @@ v-model="formData.carBuyer" label="车辆购买方" label-width="180rpx" + prop="carBuyer" clearable placeholder="请输入车辆购买方" /> @@ -195,6 +198,7 @@ :columns="certTypeOptions" label="证件类型" label-width="180rpx" + prop="certType" placeholder="请选择证件类型" value-key="value" label-key="label" @@ -203,6 +207,7 @@ v-model="formData.certNo" label="证件号码" label-width="180rpx" + prop="certNo" clearable placeholder="请输入证件号码" /> @@ -210,6 +215,7 @@ v-model="formData.mobile" label="联系电话" label-width="180rpx" + prop="mobile" type="number" clearable placeholder="请输入联系电话" @@ -234,12 +240,12 @@ :columns="storeOptions" label="门店" label-width="180rpx" + prop="storeId" placeholder="请选择门店" value-key="id" label-key="storeName" - disabled /> - + - + @@ -287,6 +294,7 @@ v-model="formData.productValidity" label="产品时效" label-width="180rpx" + prop="productValidity" readonly placeholder="选择产品后自动填充" /> @@ -294,6 +302,7 @@ :model-value="productTypeLabel" label="产品类别" label-width="180rpx" + prop="productType" readonly placeholder="选择产品后自动填充" /> @@ -301,16 +310,18 @@ v-model="formData.productFee" label="产品费用" label-width="180rpx" + prop="productFee" type="digit" clearable placeholder="请输入产品费用" /> - - + '新增续保订单') +const getTitle = computed(() => '新增订单') const formLoading = ref(false) const tabIndex = ref(0) // 当前选项卡索引 const invoiceFileList = ref([]) // 发票图片文件列表 @@ -447,6 +462,11 @@ const productList = ref([]) // 续保产品列表 const storeOptions = computed(() => storeList.value.map(item => ({ id: item.id, storeName: item.storeName }))) const productOptions = computed(() => productList.value.map(item => ({ id: item.id, productName: item.productName }))) const certTypeOptions = computed(() => getStrDictOptions('car_renewal_identity_type')) +const settlementMethodOptions = computed(() => getStrDictOptions(DICT_TYPE.CAR_RENEWAL_PAY_METHOD)) +// 判断是否显示合同相关组件(仅当产品类别为00或02时显示) +const showContractComponents = computed(() => { + return formData.value.productType === '00' || formData.value.productType === '02' +}) const formData = ref({ id: undefined, @@ -472,10 +492,10 @@ const formData = ref({ serviceProduct: undefined, productType: undefined, productValidity: undefined, - originalWarrantyYears: undefined, + originalWarrantyYears: '3', originalWarrantyMileage: undefined, productFee: undefined, - settlementMethod: undefined, + settlementMethod: '00', remark: undefined, inputUser: undefined, contractUrl: undefined, @@ -497,9 +517,23 @@ const formRules = { carModel: [{ required: true, message: '车型不能为空' }], vin: [{ required: true, message: '车架号不能为空' }], engineNo: [{ required: true, message: '发动机号不能为空' }], + invoiceDate: [{ required: true, message: '发票日期不能为空' }], invoiceAmount: [{ required: true, message: '发票金额不能为空' }], purchaseMileage: [{ required: true, message: '购买时公里数不能为空' }], + serviceBuyer: [{ required: true, message: '服务购买方不能为空' }], + carBuyer: [{ required: true, message: '车辆购买方不能为空' }], + certType: [{ required: true, message: '证件类型不能为空' }], + certNo: [{ required: true, message: '证件号码不能为空' }], + mobile: [{ required: true, message: '联系电话不能为空' }], + storeId: [{ required: true, message: '门店不能为空' }], productId: [{ required: true, message: '续保产品不能为空' }], + serviceProduct: [{ required: true, message: '服务产品不能为空' }], + productType: [{ required: true, message: '产品类别不能为空' }], + productValidity: [{ required: true, message: '产品时效不能为空' }], + productFee: [{ required: true, message: '产品费用不能为空' }], + settlementMethod: [{ required: true, message: '结算方式不能为空' }], + inputUser: [{ required: true, message: '录单人不能为空' }], + originalWarrantyYears: [{ required: true, message: '产品年限不能为空' }], } // 根据 productType 值获取字典 label @@ -713,7 +747,7 @@ function createUploadMethod(fieldName: keyof RenewalOrderVO): UploadMethod { } } -/** 多张图片上传(购车发票、购置税发票、商业险保单) */ +/** 多张图片上传(购车发票、购置税凭证、商业险保单) */ function createMultiUploadMethod(fieldName: 'carInvoiceUrls' | 'purchaseTaxInvoiceUrls' | 'businessInsurancePolicyUrls'): UploadMethod { return (file, uploadFormData, options) => { const uploadTask = uni.uploadFile({ @@ -756,14 +790,36 @@ function createMultiUploadMethod(fieldName: 'carInvoiceUrls' | 'purchaseTaxInvoi // 订单录入页面不需要加载详情,只允许新增 -// ========== 新增完成后合同预览逻辑(产品类别 00) ========== -// 流程:提交 → 创建订单 → 若 productType===00 则跳转合同预览页 → 客户签名 → 确认生成合同 → 再跳转订单详情 +// ========== 新增完成后合同预览逻辑(产品类别 00 或 02) ========== +// 流程:提交 → 创建订单 → 若 productType===00 或 02 则跳转合同预览页 → 客户签名 → 确认生成合同 → 再跳转订单详情 // 否则:创建成功 → 提示 → 跳转订单详情 async function handleSubmit() { const { valid } = await formRef.value!.validate() if (!valid) return + // 必传文件校验:行驶证、购车发票、购置税凭证、身份证正反面 + if (!formData.value.drivingLicenseUrl) { + toast.error('请上传行驶证') + return + } + if (!formData.value.carInvoiceUrls?.length) { + toast.error('请上传购车发票') + return + } + if (!formData.value.purchaseTaxInvoiceUrls?.length) { + toast.error('请上传购置税凭证') + return + } + if (!formData.value.idCardFrontUrl) { + toast.error('请上传身份证正面') + return + } + if (!formData.value.idCardBackUrl) { + toast.error('请上传身份证反面') + return + } + formLoading.value = true try { const data = { ...formData.value } @@ -777,17 +833,49 @@ async function handleSubmit() { data.invoiceDate = dayjs(data.invoiceDate).format('YYYY-MM-DD') } } + // 确保 productType 被正确传递 + if (!data.productType && formData.value.productType) { + data.productType = formData.value.productType + } const raw = await createRenewalOrder(data) as unknown const id = (raw as { data?: number })?.data ?? (raw as number) - const isProduct00 = formData.value.productType === '00' + // 检查产品类别是否为 00 或 02 + const productType = data.productType || formData.value.productType + const needContract = (productType === '00' || productType === '02') && id - if (isProduct00 && id) { - // 新增完成 → 跳转合同预览 → 客户签名 → 确认生成合同 → 合同预览页内再跳转详情 + console.log('新增订单提交 - productType:', productType, 'needContract:', needContract, 'id:', id, 'data:', data) + + if (needContract) { + // 新增完成 → 弹出选项:直接签名 / 分享签名 uni.setStorageSync('renewalorder_list_need_refresh', true) - uni.navigateTo({ - url: `/pages/car/renewalorder/contract-preview/index?id=${id}&from=add`, + toast.show('订单已创建,请选择签名方式') + uni.showActionSheet({ + itemList: ['直接签名', '分享签名'], + success: async (res) => { + if (res.tapIndex === 0) { + uni.navigateTo({ + url: `/pages/car/renewalorder/contract-preview/index?id=${id}&from=add`, + }) + toast.show('请完成客户签名后生成合同') + } else if (res.tapIndex === 1) { + try { + const tokenRes = await createSignToken(id) as { data?: { signUrl?: string }; signUrl?: string } + const signUrl = tokenRes?.data?.signUrl ?? tokenRes?.signUrl + if (!signUrl) { + toast.show('生成签名链接失败') + return + } + uni.navigateTo({ + url: `/pages/car/renewalorder/sign-share/index?signUrl=${encodeURIComponent(signUrl)}`, + }) + toast.show('请分享链接给客户签名,签名成功后合同将自动生成') + } catch (e) { + console.error(e) + toast.error('操作失败') + } + } + }, }) - toast.show('订单已创建,请完成客户签名后生成合同') } else { // 非 00 产品:直接提示成功并跳转详情 toast.success('新增成功') @@ -806,14 +894,24 @@ async function handleSubmit() { /** 初始化 */ onMounted(async () => { await Promise.all([getStoreList(), getProductList()]) - // 新增:默认选择门店第一项 - if (!formData.value.storeId && storeList.value.length > 0) { - formData.value.storeId = storeList.value[0].id + // 新增:默认选择当前用户所在门店;车辆购买方默认为当前用户门店名称,均可修改 + if (userStore.storeId != null && storeList.value.some(s => s.id === userStore.storeId)) { + formData.value.storeId = userStore.storeId + formData.value.serviceBuyer = userStore.storeName || storeList.value.find(s => s.id === userStore.storeId)?.storeName || '' + } else if (storeList.value.length > 0) { + if (!formData.value.storeId) formData.value.storeId = storeList.value[0].id + if (!formData.value.serviceBuyer) formData.value.serviceBuyer = userStore.storeName || storeList.value[0].storeName || '' } // 新增:默认选择证件类型字典第一项 if (!formData.value.certType && certTypeOptions.value.length > 0) { formData.value.certType = certTypeOptions.value[0].value } + // 新增:默认选择结算方式为 '00' + if (!formData.value.settlementMethod) { + formData.value.settlementMethod = '00' + } + // 新增:录单人默认当前登录用户名称,可修改 + formData.value.inputUser = userStore.userInfo?.nickname || userStore.userInfo?.username || '' }) diff --git a/src/pages/car/renewalorder/contract-preview/index.vue b/src/pages/car/renewalorder/contract-preview/index.vue index e151a78..a4a54d6 100644 --- a/src/pages/car/renewalorder/contract-preview/index.vue +++ b/src/pages/car/renewalorder/contract-preview/index.vue @@ -115,6 +115,12 @@ async function load() { previewLoading.value = true try { await Promise.all([fetchOrder(), fetchHtml()]) + // 如果是新增订单后跳转过来的,提示用户可以签名 + if (fromAdd.value === 'add' || fromAdd.value === 'form_create') { + setTimeout(() => { + toast.show('请预览合同内容,确认无误后点击"点击签名"按钮进行签名') + }, 500) + } } catch (e) { console.error('加载合同预览失败', e) toast.error('加载失败') @@ -172,9 +178,13 @@ onLoad((options) => { }) /** 从签名页返回时刷新订单,以更新“已签名”状态 */ -onShow(() => { +onShow(async () => { if (orderId.value && !previewLoading.value) { - fetchOrder() + await fetchOrder() + // 如果是新增订单后跳转过来的(add 或 form_create),签名完成后自动提示可以生成合同 + if ((fromAdd.value === 'add' || fromAdd.value === 'form_create') && order.value?.customerSignatureUrl) { + toast.show('签名已完成,请点击"确认生成合同"按钮生成合同') + } } }) diff --git a/src/pages/car/renewalorder/detail/index.vue b/src/pages/car/renewalorder/detail/index.vue index dc47fd7..948f4ab 100644 --- a/src/pages/car/renewalorder/detail/index.vue +++ b/src/pages/car/renewalorder/detail/index.vue @@ -153,7 +153,7 @@ /> - + - + ([]) // 合格证文件 const odometerPhotoFileList = ref([]) // 里程表照片文件列表 const nameplatePhotoFileList = ref([]) // 车名牌照片文件列表 const carInvoiceFileList = ref([]) // 购车发票文件列表 -const purchaseTaxInvoiceFileList = ref([]) // 购置税发票文件列表 +const purchaseTaxInvoiceFileList = ref([]) // 购置税凭证文件列表 const businessInsurancePolicyFileList = ref([]) // 商业险保单文件列表 const storeOptions = computed(() => storeList.value.map(item => ({ id: item.id, storeName: item.storeName }))) @@ -488,7 +487,7 @@ const formData = ref({ productId: undefined, serviceProduct: undefined, productValidity: undefined, - originalWarrantyYears: undefined, + originalWarrantyYears: '3', originalWarrantyMileage: undefined, productFee: undefined, settlementMethod: undefined, @@ -718,21 +717,57 @@ async function getDetail() { } } -/** 预览并生成合同:跳转合同预览页,签名后可确认生成 */ +/** 生成/重新生成合同:弹出选项(直接签名 / 分享签名) */ function handlePreviewContract() { if (!orderId.value) { toast.show('订单编号为空') return } - if (formData.value.productType !== '00') { - toast.show('当前产品类别不支持生成合同') + if (formData.value.productType !== '00' && formData.value.productType !== '02') { + toast.show('当前产品类别不支持生成合同,仅产品类别为 00 或 02 时可生成合同') return } - uni.navigateTo({ - url: `/pages/car/renewalorder/contract-preview/index?id=${orderId.value}`, + uni.showActionSheet({ + itemList: ['直接签名', '分享签名'], + success: (res) => { + if (res.tapIndex === 0) { + // 直接签名:跳转合同预览页 + uni.navigateTo({ + url: `/pages/car/renewalorder/contract-preview/index?id=${orderId.value}`, + }) + } else if (res.tapIndex === 1) { + // 分享签名:创建令牌后跳转分享页 + doOpenShareSign(Number(orderId.value)) + } + }, }) } +/** 分享签名:若有合同则先清空,再创建令牌并跳转分享页 */ +async function doOpenShareSign(id: number) { + try { + const hadContract = !!formData.value.contractUrl + if (hadContract) { + await clearContractAndSignature(id) + formData.value.contractUrl = undefined + formData.value.customerSignatureUrl = undefined + toast.show('已清空合同与签名,请分享链接给客户签名') + } + const res = await createSignToken(id) as { data?: { signUrl?: string }; signUrl?: string } + const signUrl = res?.data?.signUrl ?? res?.signUrl + if (!signUrl) { + toast.show('生成签名链接失败') + return + } + uni.navigateTo({ + url: `/pages/car/renewalorder/sign-share/index?signUrl=${encodeURIComponent(signUrl)}`, + }) + } catch (e) { + console.error(e) + toast.error('操作失败') + } +} + /** 页面加载时获取路由参数 */ onLoad((options) => { if (options?.id) { diff --git a/src/pages/car/renewalorder/form/index.vue b/src/pages/car/renewalorder/form/index.vue index 9312e69..3b4d4c4 100644 --- a/src/pages/car/renewalorder/form/index.vue +++ b/src/pages/car/renewalorder/form/index.vue @@ -69,13 +69,20 @@ clearable placeholder="请输入发动机号" /> - + + + + - + - + - + - + - +