| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074 |
- <route lang="json5" type="page">
- {
- layout: 'default',
- style: {
- navigationBarTitleText: '签字',
- navigationStyle: 'custom',
- },
- }
- </route>
- <template>
- <view class="sign-container">
- <!-- 导航栏 -->
- <NavBar>
- <template #title>
- <text class="nav-title">{{ title }}</text>
- </template>
- </NavBar>
- <!-- 内容区域 -->
- <scroll-view class="scroll-content" scroll-y>
- <!-- PDF 图片预览 -->
- <SpreadPDFViewer
- ref="spreadPdfViewerRef"
- :businessConfig="businessConfig"
- :templateData="templateData"
- :templateBlob="templateBlob"
- viewer-height="50vh"
- />
- <!-- 签名区域分割线 -->
- <view class="sign-divider"></view>
- <!-- 签名区域(三种状态:空/签名中/已签名) -->
- <view class="sign-section">
- <!-- 状态1:空状态 - 点击签名 -->
- <template v-if="signStatus === 'empty'">
- <view class="sign-header">
- <text class="sign-title-text">手写签名</text>
- </view>
- <view class="sign-view" @click="handleToSign">
- <text class="sign-view-text">点击签名</text>
- </view>
- </template>
- <!-- 状态2:签名中 - 显示画布 -->
- <template v-if="signStatus === 'signing'">
- <view class="sign-header">
- <text class="sign-title-text">手写签名</text>
- <view class="sign-header-actions">
- <button class="header-action-btn header-reset-btn" @click="clearCanvas">清除</button>
- <button class="header-action-btn header-cancel-btn" @click="handleCancelSign">
- 取消
- </button>
- <button class="header-action-btn header-confirm-btn" @click="confirmSign">
- 确认
- </button>
- </view>
- </view>
- <view class="sign-canvas-wrapper">
- <SignatureCanvas
- ref="signatureRef"
- canvas-id="signCanvas"
- :width="canvasWidth"
- :height="178"
- @signed="onCanvasSigned"
- />
- </view>
- </template>
- <!-- 状态3:已签名 - 显示签名图片 -->
- <template v-if="signStatus === 'signed'">
- <view class="sign-header">
- <text class="sign-title-text">签名时间:</text>
- <text class="sign-title-text">{{ signTime }}</text>
- </view>
- <view class="sign-img">
- <view class="sign-img-del" @click="handleDelSign">X</view>
- <image :src="showSignImg" mode="aspectFit" class="sign-image" :style="signImgStyle" />
- </view>
- </template>
- </view>
- <!-- 联系信息表单(服务单/受理单类型) -->
- <view v-if="routeType === 'FWD'" class="form-section">
- <view class="form-item">
- <text class="form-label">接收人手机号:</text>
- <input
- v-model="fwdInputPhone"
- class="form-input"
- type="number"
- maxlength="11"
- placeholder="请输入接收人手机号"
- />
- </view>
- </view>
- </scroll-view>
- <!-- 底部按钮 -->
- <view class="footer-bar">
- <button class="footer-btn more-btn" @click="handlePushOrder">更多操作</button>
- <button class="footer-btn confirm-btn" @click="signSubmit">{{ signButtonText }}</button>
- </view>
- <!-- 底部操作面板 -->
- <wd-action-sheet
- v-model="showActionSheet"
- :actions="actionSheetActions"
- @select="handleActionSelect"
- />
- <!-- 服务单接收人确认弹窗 -->
- <view v-if="showFwdPopup" class="popup-overlay" @click="closeFwdPopup">
- <view class="popup-content" @click.stop>
- <text class="popup-title">确认提交</text>
- <text class="popup-message">是否确认签约代表签名?</text>
- <view class="popup-actions">
- <button class="action-btn cancel-btn" @click="closeFwdPopup">取消</button>
- <button class="action-btn confirm-btn" @click="confirmFwdSubmit">确定</button>
- </view>
- </view>
- </view>
- <!-- 推送任务单弹窗 -->
- <view v-if="showInputPopup" class="popup-overlay" @click="closeInputPopup">
- <view class="popup-content input-popup" @click.stop>
- <text class="popup-title">推送任务单</text>
- <view class="input-row">
- <text class="row-label">接收人名称:</text>
- <input class="row-input" v-model="inputName" placeholder="请输入接收人名称" />
- </view>
- <view class="input-row">
- <text class="row-label">接收人手机号:</text>
- <input
- class="row-input"
- v-model="inputPhone"
- type="number"
- maxlength="11"
- placeholder="请输入接收人手机号"
- />
- </view>
- <view v-if="routeType !== 'ZXXX'" class="input-row">
- <text class="row-label">电子邮箱:</text>
- <input
- class="row-input"
- v-model="inputEmail"
- type="text"
- placeholder="请输入电子邮箱(选填)"
- />
- </view>
- <view class="popup-actions">
- <button class="action-btn cancel-btn" @click="closeInputPopup">取消</button>
- <button class="action-btn confirm-btn" @click="handlePushOrderSubmit">确定</button>
- </view>
- </view>
- </view>
- </view>
- </template>
- <script lang="ts" setup>
- import { ref, computed, onMounted, nextTick } from 'vue'
- import { onLoad } from '@dcloudio/uni-app'
- import SignatureCanvas from '@/components/Signature/SignatureCanvas.vue'
- import SpreadPDFViewer from '@/components/SpreadDesigner/SpreadPDFViewer.vue'
- import NavBar from '@/components/NavBar/NavBar.vue'
- import { useUserStore } from '@/store/user'
- import { useConfigStore } from '@/store/config'
- import { getGcConfig, getTaskOrderImg, pushPressure2TaskOrder, uploadSignImage } from '@/api/sign'
- import { getDynamicTbVal } from '@/api/task'
- import { getStandardTemplate } from '@/api/index'
- import { getTaskOrderReport } from '@/api/orderReport'
- import { buildFileUrl } from '@/utils/index'
- import { SignFuncName, requestFunc } from '@/api/ApiRouter/sign'
- import { TaskOrderFuncName, requestFunc as taskOrderRequestFunc } from '@/api/ApiRouter/taskOrder'
- import { EquipmentType } from '@/utils/dictMap'
- const equipType = useConfigStore().getEquipType()
- const title = ref('')
- const routeType = ref<'FWD' | 'JYRS' | 'AQJC' | 'ZXXX'>()
- const orderId = ref('')
- const orderItemId = ref('')
- const securityCheckId = ref('')
- const reportId = ref('')
- const unitContact = ref('')
- const unitPhone = ref('')
- const receiverEmail = ref('')
- const templateId = ref('')
- const refId = ref('')
- const showSignImg = ref('')
- const signImg = ref('')
- const uploadedSignUrl = ref('')
- const signImgStyle = ref<any>({})
- const signTime = ref('')
- const fwdInputPhone = ref('')
- const showFwdPopup = ref(false)
- const showInputPopup = ref(false)
- const showActionSheet = ref(false)
- const actionSheetActions = ref<any[]>([])
- const canvasWidth = ref(300)
- const inputName = ref('')
- const inputPhone = ref('')
- const inputEmail = ref('')
- const gcConfig = ref<any>(null)
- const spreadPdfViewerRef = ref<any>(null)
- const templateBlob = ref<any>(null)
- const businessConfig = ref<any>({
- businessType: 'AQJC',
- title: '安全检查记录编辑',
- disableNavigate: true, // 是否禁用跳转,默认不禁用
- ui: {
- title: '安全检查记录',
- saveButtonText: '保存',
- cancelButtonText: '取消',
- showAdditionalToolbar: true,
- customButtons: [],
- },
- })
- const templateData = ref<any>({})
- // 签名区域状态:empty | signing | signed
- const signStatus = ref<'empty' | 'signing' | 'signed'>('empty')
- const signatureRef = ref<any>(null)
- const userStore = useUserStore()
- const userInfo = computed(() => userStore.userInfo)
- const titleTextMap: Record<string, string> = {
- FWD: '服务单/受理单',
- JYRS: '检验结果告知',
- AQJC: '安全检查记录',
- ZXXX: '重大问题线索告知',
- }
- const businessTypeMap: Record<string, number> = {
- FWD: 100,
- JYRS: 200,
- AQJC: 300,
- ZXXX: 400,
- }
- const signButtonTextMap: Record<string, string> = {
- FWD: '签约代表签名',
- JYRS: '客户代表签名',
- AQJC: '受检单位签名',
- ZXXX: '受检单位签名',
- }
- const confirmTextMap: Record<string, string> = {
- FWD: '是否确认签约代表签名?',
- JYRS: '是否确认客户代表签名?',
- AQJC: '是否确认受检单位签名?',
- ZXXX: '是否提交审核?',
- }
- const signButtonText = computed(() => {
- return routeType.value ? signButtonTextMap[routeType.value] || '签名' : '签名'
- })
- onLoad((options) => {
- const type = options?.type as string
- routeType.value = type as any
- title.value = titleTextMap[type] || '签字'
- orderId.value = options?.orderId || ''
- orderItemId.value = options?.orderItemId || ''
- securityCheckId.value = options?.securityCheckId || ''
- reportId.value = options?.reportId || ''
- unitContact.value = options?.unitContact || ''
- unitPhone.value = options?.unitPhone || ''
- receiverEmail.value = options?.receiverEmail || ''
- templateId.value = options?.templateId || ''
- fwdInputPhone.value = unitPhone.value
- inputName.value = unitContact.value
- inputPhone.value = unitPhone.value
- inputEmail.value = receiverEmail.value
- // 初始化画布宽度
- const sysInfo = uni.getSystemInfoSync()
- canvasWidth.value = sysInfo.windowWidth - 32
- })
- // 获取任务单配置
- // const getTaskOrderGcConfig = async () => {
- // try {
- // const result: any = await getGcConfig(
- // {
- // orderId: orderId.value,
- // businessType: routeType.value ? businessTypeMap[routeType.value] : '',
- // orderItemId: orderItemId.value || undefined,
- // templateId: templateId.value || undefined,
- // },
- // userInfo.value,
- // )
- // const res = result?.data
- // gcConfig.value = res
- // if (res) {
- // fetchTaskOrderImg(res)
- // } else {
- // uni.showToast({ title: '获取配置信息失败', icon: 'error' })
- // }
- // } catch (error) {
- // console.error('获取配置失败:', error)
- // uni.showToast({ title: '获取配置失败', icon: 'error' })
- // }
- // }
- // 获取任务单图片
- // const fetchTaskOrderImg = async (res: any) => {
- // const { dataStr, templateUrl, templateId, fileVersionId } = res
- // if (!orderId.value) return
- // if (orderId.value && dataStr && templateUrl) {
- // const params: any = {
- // dataStr,
- // templateUrl,
- // orderId: orderId.value,
- // businessType: routeType.value ? businessTypeMap[routeType.value] : '',
- // fileType: 100,
- // orderItemId: orderItemId.value || undefined,
- // templateId,
- // }
- // if (routeType.value === 'ZXXX' && fileVersionId) {
- // params.fileVersionId = fileVersionId
- // }
- // try {
- // const result: any = await getTaskOrderImg(params)
- // if (result) {
- // pdfImg.value = result
- // uni.getImageInfo({
- // src: result,
- // success: (imageInfo) => {
- // const screenWidth = uni.getSystemInfoSync().windowWidth - 32
- // pdfWidth.value = screenWidth
- // pdfHeight.value = (screenWidth * imageInfo.height) / imageInfo.width
- // },
- // })
- // }
- // } catch (error) {
- // console.error('获取图片失败:', error)
- // }
- // }
- // }
- const orderReportId = ref('')
- const getPreviewData = async () => {
- // orderId --> templateId + refId --> templateBlob 和 templateData
- /*
- orderId: 1fd8970b25933aee9486431bfbc10751
- templateId: dce2478ef6a153fbd2874b1f2ea33389
- */
- // orderId 查询服务单,获取 templateId + refId
- if (!routeType.value) {
- uni.showToast({ title: '必须选择签字文件类型', icon: 'error' })
- return
- }
- switch (routeType.value) {
- case 'FWD':
- const orderReportResp = await getTaskOrderReport({ taskOrderId: orderId.value })
- const orderReportRespList = orderReportResp.data?.list
- let orderReport = null
- if (orderReportRespList?.length) {
- orderReport = orderReportRespList[0]
- }
- templateId.value = orderReport?.templateId
- refId.value = orderReport?.acceptOrderId
- orderReportId.value = orderReport?.id || ''
- break
- case 'JYRS':
- const orderDetail = await taskOrderRequestFunc(TaskOrderFuncName.TaskOrderDetail, equipType, {
- id: orderId.value,
- })
- const notificationformReport = orderDetail.data?.notificationformReport
- if (!notificationformReport) {
- uni.showToast({ title: '暂无检验结果告知报表', icon: 'error' })
- return
- }
- break
- default:
- uni.showToast({ title: '请选择正确的签字文件类型', icon: 'error' })
- break
- }
- // 获取templateSchema
- const res = await getStandardTemplate({ id: templateId.value })
- const resData = (res as any).data
- // 加载报表数据
- const dataMap: any = {}
- const dynamicTbResp = await getDynamicTbVal({
- refId: refId.value,
- })
- const dynamicTb: any = dynamicTbResp.data
- for (let i = 0; i < dynamicTb.dynamicTbValRespVOList.length; i++) {
- const item = dynamicTb.dynamicTbValRespVOList[i]
- dataMap[item.colCode] = item.valValue
- }
- // 组装templateData
- templateData.value = {
- schema: resData.bindingPathSchema ? JSON.parse(resData.bindingPathSchema) : {},
- data: {
- ...dataMap,
- templateId: templateId.value,
- templateUrl: resData.fileUrl,
- },
- pathNameMapping: JSON.parse(resData.bindingPathNameJson),
- template: templateId.value,
- templateUrl: resData.fileUrl,
- }
- // 获取 template 文件
- const fileUri = resData.fileUrl
- const fileUrl = buildFileUrl(fileUri)
- const fileBase64 = await spreadPdfViewerRef.value.downloadFileAsBase64(fileUrl)
- templateBlob.value = fileBase64
- }
- const handleToSign = () => {
- signStatus.value = 'signing'
- // 重新计算画布宽度
- const sysInfo = uni.getSystemInfoSync()
- canvasWidth.value = sysInfo.windowWidth - 32
- }
- // 画布签名完成回调
- const onCanvasSigned = (hasContent: boolean) => {
- console.log('画布签名状态:', hasContent)
- }
- // 清除画布
- const clearCanvas = () => {
- if (signatureRef.value) {
- signatureRef.value.clear()
- }
- }
- // 取消签名 - 返回空状态
- const handleCancelSign = () => {
- signStatus.value = 'empty'
- }
- const base64ToFile = (base64Data: string, fileName: string = 'signature.png'): File | null => {
- // #ifdef H5
- try {
- const arr = base64Data.split(',')
- const mime = arr[0].match(/:(.*?);/)?.[1] || 'image/png'
- const bstr = atob(arr[1])
- let n = bstr.length
- const u8arr = new Uint8Array(n)
- while (n--) {
- u8arr[n] = bstr.charCodeAt(n)
- }
- return new File([u8arr], fileName, { type: mime })
- } catch (e) {
- console.error('base64 转 File 失败:', e)
- return null
- }
- // #endif
- }
- const base64ToTempFilePath = (base64Data: string): Promise<string> => {
- return new Promise((resolve, reject) => {
- // #ifdef H5
- const file = base64ToFile(base64Data)
- if (file) {
- resolve('') // H5 使用 File 对象
- } else {
- reject(new Error('转换失败'))
- }
- // #endif
- // #ifndef H5
- const fs = uni.getFileSystemManager()
- const filePath = `${uni.env.USER_DATA_PATH}/signature_${Date.now()}.png`
- // 移除 data:image/png;base64, 前缀
- const base64 = base64Data.replace(/^data:image\/\w+;base64,/, '')
- fs.writeFile({
- filePath,
- data: base64,
- encoding: 'base64',
- success: () => {
- resolve(filePath)
- },
- fail: (err) => {
- reject(err)
- },
- })
- // #endif
- })
- }
- const uploadSignature = async (base64Data: string): Promise<string> => {
- try {
- // #ifdef H5
- const file = base64ToFile(base64Data)
- if (!file) {
- throw new Error('签名图片转换失败')
- }
- const fd = new FormData()
- fd.append('file', file)
- const resp: any = await uploadSignImage(fd)
- if (resp?.code === 0 && resp?.data) {
- return resp.data
- }
- throw new Error(resp?.msg || '上传失败')
- // #endif
- } catch (error) {
- console.error('签名图片上传失败:', error)
- throw error
- }
- }
- // 确认签名
- const confirmSign = async () => {
- if (!signatureRef.value) return
- if (signatureRef.value.isEmpty()) {
- uni.showToast({ title: '请先签字再保存', icon: 'none' })
- return
- }
- try {
- uni.showLoading({ title: '正在保存...' })
- const path = await signatureRef.value.getImage()
- signImg.value = path
- showSignImg.value = path
- console.log('imagePath....', path)
- uni.getImageInfo({
- src: path,
- success: (imageInfo) => {
- const screenWidth = uni.getSystemInfoSync().windowWidth - 32
- signImgStyle.value = {
- width: `${screenWidth}px`,
- height: `${(screenWidth * imageInfo.height) / imageInfo.width}px`,
- }
- },
- })
- // 上传签名图片
- try {
- const uploadedUrl = await uploadSignature(path)
- uploadedSignUrl.value = uploadedUrl
- console.log('签名图片上传成功:', uploadedUrl)
- } catch (uploadError) {
- console.error('签名图片上传失败,继续使用原图片:', uploadError)
- uni.showToast({ title: '签名保存成功,上传失败', icon: 'none' })
- }
- const now = new Date()
- signTime.value = `${now.getFullYear()}年${now.getMonth() + 1}月${now.getDate()}日`
- signStatus.value = 'signed'
- uni.hideLoading()
- } catch (err) {
- uni.hideLoading()
- console.error('转换失败:', err)
- uni.showToast({ title: '签名失败', icon: 'error' })
- }
- }
- // 删除签名
- const handleDelSign = () => {
- signImg.value = ''
- showSignImg.value = ''
- uploadedSignUrl.value = ''
- signTime.value = ''
- signStatus.value = 'empty'
- }
- // 提交签名
- const signSubmit = () => {
- if (!signImg.value) {
- uni.showToast({ title: '请先签名', icon: 'none' })
- return
- }
- if (routeType.value === 'FWD') {
- if (!fwdInputPhone.value) {
- uni.showToast({ title: '请输入接收人手机号', icon: 'none' })
- return
- }
- if (!/^1[3456789]\d{9}$/.test(fwdInputPhone.value)) {
- uni.showToast({ title: '请输入正确的手机号', icon: 'none' })
- return
- }
- showFwdPopup.value = true
- return
- }
- submitConfirm()
- }
- // 确认提交
- const submitConfirm = async () => {
- try {
- const params: any = {
- id: orderId.value,
- signUrl: uploadedSignUrl.value || signImg.value,
- // signTime: ,
- businessType: routeType.value ? businessTypeMap[routeType.value] : '',
- // orderItemId: orderItemId.value || undefined,
- // securityCheckId: ,
- }
- if (routeType.value === 'FWD') {
- params.receiverPhone = fwdInputPhone.value
- params.orderReportId = orderReportId.value
- }
- const result: any = await requestFunc(SignFuncName.SubmitSign, equipType, params)
- if (result?.code === 0) {
- uni.showToast({
- title: routeType.value === 'ZXXX' ? '已自动提交审核' : '签名成功',
- icon: 'success',
- })
- // setTimeout(() => {
- // uni.redirectTo({
- // url: `/pages/orderDetail/detail?orderId=${orderId.value}&type=${routeType.value}`,
- // })
- // }, 1500)
- } else {
- uni.showToast({ title: result?.msg || '签名失败', icon: 'error' })
- }
- } catch (error: any) {
- console.error('签名失败:', error)
- uni.showToast({ title: error?.msg || '签名失败', icon: 'error' })
- } finally {
- showFwdPopup.value = false
- }
- }
- // 服务单提交确认
- const confirmFwdSubmit = () => {
- submitConfirm()
- }
- // 关闭服务单弹窗
- const closeFwdPopup = () => {
- showFwdPopup.value = false
- }
- // 更多操作
- const handlePushOrder = () => {
- if (routeType.value === 'ZXXX') {
- actionSheetActions.value = [{ name: '小程序推送签名' }, { name: '更新' }]
- } else {
- actionSheetActions.value = [{ name: '推送' }, { name: '更新' }]
- }
- showActionSheet.value = true
- }
- // 处理操作面板选择
- const handleActionSelect = (item: any) => {
- const name = item.item.name
- if (name === '推送' || name === '小程序推送签名') {
- showInputPopup.value = true
- } else if (name === '更新') {
- if (!templateId.value || !refId.value) {
- return uni.showToast({ title: '配置信息不完整', icon: 'none' })
- }
- let url = ''
- if (routeType.value === 'FWD') {
- url = `/pages/serviceOrderDetail/serviceOrderEditor?templateId=${templateId.value}&refId=${refId.value}`
- } else if (routeType.value === 'JYRS') {
- uni.showToast({ title: '更新检验结果告知表单暂未实现', icon: 'none' })
- } else {
- uni.showToast({ title: '系统错误,不能更新', icon: 'none' })
- }
- uni.navigateTo({ url })
- }
- }
- // 关闭推送弹窗
- const closeInputPopup = () => {
- showInputPopup.value = false
- inputEmail.value = ''
- }
- // 推送任务单提交
- const handlePushOrderSubmit = () => {
- if (!inputName.value || !inputPhone.value) {
- return uni.showToast({ title: '请输入接收人姓名和手机号', icon: 'none' })
- }
- if (!/^1[3456789]\d{9}$/.test(inputPhone.value)) {
- return uni.showToast({ title: '请输入正确的手机号', icon: 'none' })
- }
- const params: any = {
- orderId: orderId.value,
- receiver: inputName.value,
- receiverPhone: inputPhone.value,
- receiverEmail: routeType.value !== 'ZXXX' ? inputEmail.value || '' : '',
- businessType: routeType.value ? businessTypeMap[routeType.value] : '',
- orderItemId: orderItemId.value || undefined,
- securityCheckId: securityCheckId.value,
- equipMainType: equipTypeCode(equipType),
- }
- pushPressure2TaskOrder(params)
- .then((res: any) => {
- if (res?.code === 0) {
- uni.showToast({ title: '推送成功', icon: 'success' })
- showInputPopup.value = false
- // getTaskOrderGcConfig()
- } else {
- uni.showToast({ title: res?.msg || '推送失败', icon: 'none' })
- }
- })
- .catch((error) => {
- console.error('推送失败:', error)
- uni.showToast({ title: '推送失败', icon: 'none' })
- })
- }
- const equipTypeCode = (type: EquipmentType) => {
- switch (type) {
- case EquipmentType.BOILER:
- return '200'
- case EquipmentType.PIPE:
- return '300'
- case EquipmentType.CONTAINER:
- return '100'
- default:
- return ''
- }
- }
- onMounted(() => {
- if (orderId.value) {
- // getTaskOrderGcConfig()
- getPreviewData()
- }
- })
- </script>
- <style lang="scss" scoped>
- .sign-container {
- display: flex;
- flex-direction: column;
- height: 100vh;
- background-color: #fff;
- }
- .navigate-view {
- display: flex;
- flex-direction: row;
- align-items: center;
- justify-content: space-between;
- height: 44px;
- padding: 0 15px;
- background-color: #fff;
- border-bottom: 1px solid #eee;
- .navigate-left {
- display: flex;
- align-items: center;
- }
- .back-icon {
- width: 20px;
- height: 20px;
- }
- .navigate-title {
- font-size: 17px;
- font-weight: 500;
- color: #333;
- }
- .navigate-right {
- width: 20px;
- }
- }
- .nav-title {
- font-size: 17px;
- font-weight: 500;
- color: #333;
- }
- .scroll-content {
- flex: 1;
- padding: 16px;
- }
- // 分割线
- .sign-divider {
- width: 100%;
- height: 1px;
- margin: 0 0 12px;
- background-color: #e0e0e0;
- }
- // 签名区域
- .sign-section {
- width: 100%;
- padding-bottom: 12px;
- background-color: #fff;
- .sign-header {
- display: flex;
- flex-direction: row;
- align-items: center;
- justify-content: space-between;
- margin-bottom: 8px;
- .sign-title-text {
- font-size: 20px;
- line-height: 28px;
- color: #333;
- }
- .sign-header-actions {
- display: flex;
- flex-direction: row;
- gap: 8px;
- .header-action-btn {
- display: flex;
- align-items: center;
- justify-content: center;
- height: 30px;
- padding: 0 12px;
- font-size: 14px;
- border: none;
- border-radius: 6px;
- }
- .header-reset-btn {
- color: rgb(16, 16, 16);
- background-color: rgb(230, 238, 245);
- border: 1px solid rgb(187, 187, 187);
- }
- .header-cancel-btn {
- color: rgb(16, 16, 16);
- background-color: #f5f5f5;
- border: 1px solid rgb(187, 187, 187);
- }
- .header-confirm-btn {
- color: #fff;
- background-color: rgb(7, 31, 80);
- }
- }
- }
- // 空状态 - 点击签名
- .sign-view {
- display: flex;
- align-items: center;
- justify-content: center;
- width: 100%;
- height: 178px;
- background-color: #d8d8d8;
- .sign-view-text {
- font-size: 42px;
- font-weight: bold;
- color: #999;
- }
- }
- // 签名画布区域
- .sign-canvas-wrapper {
- width: 100%;
- overflow: hidden;
- background-color: #ffffff;
- border: 2px dashed rgb(187, 187, 187);
- border-radius: 8px;
- }
- // 已签名 - 图片展示
- .sign-img {
- position: relative;
- display: flex;
- align-items: center;
- justify-content: center;
- padding: 10px;
- border: 1px solid #ccc;
- border-radius: 10px;
- .sign-img-del {
- position: absolute;
- top: 0;
- right: 0;
- z-index: 2;
- display: flex;
- align-items: center;
- justify-content: center;
- width: 20px;
- height: 20px;
- font-size: 12px;
- color: #333;
- background-color: #e0e0e0;
- border-radius: 10px;
- }
- .sign-image {
- display: block;
- width: 100%;
- }
- }
- }
- // 表单区域
- .form-section {
- padding: 15px 0;
- margin-bottom: 10px;
- background-color: #fff;
- border-top: 1px solid #eee;
- .form-item {
- display: flex;
- flex-direction: row;
- align-items: center;
- .form-label {
- width: 120px;
- font-size: 14px;
- color: #666;
- }
- .form-input {
- flex: 1;
- height: 40px;
- padding: 0 10px;
- font-size: 14px;
- border: 1px solid #ddd;
- border-radius: 5px;
- }
- }
- }
- // 底部按钮
- .footer-bar {
- display: flex;
- flex-direction: row;
- gap: 12px;
- padding: 12px 16px 16px;
- background-color: #ffffff;
- border-top: 1px solid #e0e0e0;
- .footer-btn {
- display: flex;
- flex: 1;
- align-items: center;
- justify-content: center;
- height: 44px;
- font-size: 16px;
- color: #fff;
- border: none;
- border-radius: 6px;
- }
- .more-btn {
- background-color: #e6a23c;
- }
- .confirm-btn {
- background-color: #00a811;
- }
- }
- // 弹窗
- .popup-overlay {
- position: fixed;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- z-index: 999;
- display: flex;
- align-items: center;
- justify-content: center;
- background-color: rgba(0, 0, 0, 0.5);
- .popup-content {
- display: flex;
- flex-direction: column;
- align-items: center;
- width: 66.67%;
- padding: 20px;
- background-color: #fff;
- border-radius: 10px;
- &.input-popup {
- width: 80%;
- max-width: 360px;
- }
- .popup-title {
- margin-bottom: 15px;
- font-size: 18px;
- font-weight: 500;
- color: #333;
- }
- .popup-message {
- margin-bottom: 20px;
- font-size: 15px;
- color: #666;
- }
- .popup-actions {
- display: flex;
- flex-direction: row;
- gap: 10px;
- width: 100%;
- .action-btn {
- display: flex;
- flex: 1;
- align-items: center;
- justify-content: center;
- height: 40px;
- font-size: 15px;
- border: none;
- border-radius: 5px;
- }
- .cancel-btn {
- color: #fff;
- background-color: #94bddf;
- }
- .confirm-btn {
- color: #fff;
- background-color: #071f50;
- }
- }
- }
- }
- .input-row {
- display: flex;
- flex-direction: row;
- align-items: center;
- width: 100%;
- margin-bottom: 12px;
- .row-label {
- flex-shrink: 0;
- width: 90px;
- font-size: 14px;
- color: #666;
- }
- .row-input {
- flex: 1;
- height: 36px;
- padding: 0 10px;
- font-size: 14px;
- border: 1px solid #ddd;
- border-radius: 5px;
- }
- }
- </style>
|