备货单 审核功能
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
<canvas
|
||||
ref="canvasRef"
|
||||
class="canvas"
|
||||
:style="{ pointerEvents: locked ? 'none' : 'auto' }"
|
||||
@touchstart.prevent="onStart"
|
||||
@touchmove.prevent="onMove"
|
||||
@touchend.prevent="onEnd"
|
||||
@@ -14,35 +15,126 @@
|
||||
></canvas>
|
||||
</div>
|
||||
<div class="toolbar">
|
||||
<el-button @click="clearCanvas">清空</el-button>
|
||||
<el-button @click="toggleLandscape">横屏</el-button>
|
||||
<el-button type="primary" :loading="submitting" @click="saveSignature">保存</el-button>
|
||||
<el-button :disabled="locked" @click="clearCanvas">清空</el-button>
|
||||
<el-button :disabled="locked" @click="toggleLandscape">横屏</el-button>
|
||||
<el-button type="primary" :disabled="locked" :loading="submitting" @click="saveSignature">
|
||||
保存
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="tip">
|
||||
{{ locked ? '签名已保存,页面已锁定' : '请在画布上手写签名,然后点击保存' }}
|
||||
</div>
|
||||
<div class="tip">请在画布上手写签名,然后点击保存</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { ref, onMounted, computed } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { useUploadHeaders } from '@/composables/useUploadHeaders'
|
||||
import { CrmService } from '@/api/crmApi'
|
||||
// import { CrmService } from '@/api/crmApi'
|
||||
import { commonService } from '@/api/commonApi'
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
|
||||
const route = useRoute()
|
||||
const userId = route.query.userId as string | undefined
|
||||
const userStore = useUserStore()
|
||||
// 优先使用URL传入的token,否则取当前应用内的token
|
||||
const urlToken = route.query.token as string | undefined
|
||||
const urlToken =
|
||||
(route.query.accessToken as string | undefined) || (route.query.token as string | undefined)
|
||||
// 其他头部信息从URL透传(便于直达页调用接口)
|
||||
const urlLang = route.query.lang as string | undefined
|
||||
const urlCorp = (route.query.companyabbr as string | undefined) || userStore.companyabbr
|
||||
const urlLoginType = route.query.loginType as string | undefined
|
||||
const urlSys = (route.query.systemsabbr as string | undefined) || userStore.systemsabbr || 'fdesk'
|
||||
const effectiveToken = urlToken || userStore.accessToken
|
||||
|
||||
// 从URL参数获取公司信息并存储到userStore(如果路由守卫没有处理)
|
||||
const companyid = route.query.companyid as string | undefined
|
||||
const companyabbr = route.query.companyabbr as string | undefined
|
||||
if (companyid && companyabbr && (!userStore.companyid || !userStore.companyabbr)) {
|
||||
userStore.setCompany(companyid, companyabbr)
|
||||
}
|
||||
|
||||
// 从URL参数获取系统信息并存储到userStore(如果路由守卫没有处理)
|
||||
const systemsabbr = route.query.systemsabbr as string | undefined
|
||||
const systemsid = route.query.systemsid as string | undefined
|
||||
if (systemsid && systemsabbr && (!userStore.systemsid || !userStore.systemsabbr)) {
|
||||
userStore.setSystems(systemsid, systemsabbr)
|
||||
}
|
||||
|
||||
// 从URL参数获取登录类型并存储到userStore(如果路由守卫没有处理)
|
||||
if (urlLoginType && !userStore.loginType) {
|
||||
userStore.setLoginType(urlLoginType as 'feishu' | 'upwd')
|
||||
}
|
||||
|
||||
// 从URL参数获取token并存储到userStore(如果路由守卫没有处理)
|
||||
if (urlToken && !userStore.accessToken) {
|
||||
userStore.setToken(urlToken)
|
||||
}
|
||||
// 调试信息:打印初始化时的userStore状态
|
||||
// console.log('Signature page initialized:', {
|
||||
// urlParams: {
|
||||
// userId,
|
||||
// urlToken: urlToken ? 'exists' : 'missing',
|
||||
// urlLang,
|
||||
// urlCorp,
|
||||
// urlLoginType,
|
||||
// urlSys
|
||||
// },
|
||||
// userStore: {
|
||||
// companyabbr: userStore.companyabbr,
|
||||
// companyid: userStore.companyid,
|
||||
// systemsabbr: userStore.systemsabbr,
|
||||
// systemsid: userStore.systemsid,
|
||||
// language: userStore.language,
|
||||
// loginType: userStore.loginType,
|
||||
// accessToken: userStore.accessToken ? 'exists' : 'missing',
|
||||
// isLogin: userStore.isLogin
|
||||
// }
|
||||
// })
|
||||
|
||||
const { uploadHeaders } = useUploadHeaders()
|
||||
// 基于URL参数动态构造上传头,优先使用URL透传值
|
||||
const dynamicHeaders = computed(() => {
|
||||
const headers: Record<string, string> = { ...(uploadHeaders.value || {}) }
|
||||
|
||||
// 语言设置
|
||||
if (urlLang) headers['Fdesk-Language'] = urlLang
|
||||
|
||||
// 公司标识 - 优先使用URL参数,其次使用userStore,最后使用默认值
|
||||
const corpAbbr = urlCorp || userStore.companyabbr || 'default'
|
||||
headers['Fdesk-Corp-Abbr'] = corpAbbr
|
||||
|
||||
// 登录类型
|
||||
if (urlLoginType) headers['Fdesk-Login-Type'] = urlLoginType
|
||||
|
||||
// 系统标识
|
||||
headers['Fdesk-System-Code'] = urlSys
|
||||
|
||||
// 认证令牌
|
||||
if (effectiveToken) headers['Fdesk-Auth-Token'] = 'Bearer ' + effectiveToken
|
||||
|
||||
// 调试信息:打印请求头
|
||||
// console.log('Signature page headers:', headers)
|
||||
// console.log('URL params:', {
|
||||
// urlLang,
|
||||
// urlCorp,
|
||||
// urlLoginType,
|
||||
// urlSys,
|
||||
// effectiveToken
|
||||
// })
|
||||
// console.log('Final corp abbr:', corpAbbr)
|
||||
|
||||
return headers
|
||||
})
|
||||
|
||||
const canvasRef = ref<HTMLCanvasElement | null>(null)
|
||||
const ctx = ref<CanvasRenderingContext2D | null>(null)
|
||||
const drawing = ref(false)
|
||||
const submitting = ref(false)
|
||||
const landscape = ref(false)
|
||||
const locked = ref(false)
|
||||
|
||||
const resizeCanvas = () => {
|
||||
const canvas = canvasRef.value
|
||||
@@ -94,18 +186,21 @@
|
||||
}
|
||||
|
||||
const onStart = (e: TouchEvent) => {
|
||||
if (locked.value) return
|
||||
drawing.value = true
|
||||
const p = getPoint(e)
|
||||
ctx.value!.beginPath()
|
||||
ctx.value!.moveTo(p.x, p.y)
|
||||
}
|
||||
const onMove = (e: TouchEvent) => {
|
||||
if (locked.value) return
|
||||
if (!drawing.value) return
|
||||
const p = getPoint(e)
|
||||
ctx.value!.lineTo(p.x, p.y)
|
||||
ctx.value!.stroke()
|
||||
}
|
||||
const onEnd = () => {
|
||||
if (locked.value) return
|
||||
drawing.value = false
|
||||
}
|
||||
|
||||
@@ -114,6 +209,7 @@
|
||||
const onMouseUp = () => onEnd()
|
||||
|
||||
const clearCanvas = () => {
|
||||
if (locked.value) return
|
||||
resizeCanvas()
|
||||
}
|
||||
|
||||
@@ -147,11 +243,16 @@
|
||||
}
|
||||
}
|
||||
|
||||
const isLimitedWebview = () => /MicroMessenger|Lark|Feishu|DingTalk/i.test(navigator.userAgent)
|
||||
|
||||
const toggleLandscape = async () => {
|
||||
landscape.value = !landscape.value
|
||||
if (landscape.value) {
|
||||
await requestFullscreen(document.documentElement)
|
||||
await lockOrientationLandscape()
|
||||
// 在微信/飞书等内置浏览器中,强制横屏普遍受限,采用 CSS 旋转兜底
|
||||
if (!isLimitedWebview()) {
|
||||
await requestFullscreen(document.documentElement)
|
||||
await lockOrientationLandscape()
|
||||
}
|
||||
}
|
||||
setTimeout(resizeCanvas, 200)
|
||||
}
|
||||
@@ -170,30 +271,42 @@
|
||||
const form = new FormData()
|
||||
form.append('file', file)
|
||||
|
||||
const headers: Record<string, string> = { ...(uploadHeaders.value || {}) }
|
||||
if (effectiveToken) {
|
||||
headers['Authorization'] = `Bearer ${effectiveToken}`
|
||||
}
|
||||
const headers: Record<string, string> = { ...(dynamicHeaders.value || {}) }
|
||||
// 兼容后端可能验 Authorization 的情况
|
||||
if (effectiveToken) headers['Authorization'] = `Bearer ${effectiveToken}`
|
||||
|
||||
// 调试信息:打印上传请求详情
|
||||
// console.log('Upload URL:', uploadUrl)
|
||||
// console.log('Upload headers:', headers)
|
||||
// console.log('UserStore state:', {
|
||||
// systemsabbr: userStore.systemsabbr,
|
||||
// systemsid: userStore.systemsid,
|
||||
// companyabbr: userStore.companyabbr,
|
||||
// companyid: userStore.companyid,
|
||||
// language: userStore.language,
|
||||
// loginType: userStore.loginType
|
||||
// })
|
||||
|
||||
const res = await fetch(uploadUrl, {
|
||||
method: 'POST',
|
||||
headers,
|
||||
body: form
|
||||
})
|
||||
const json = await res.json()
|
||||
// console.log('Upload response:', json)
|
||||
if (json.code !== 200) throw new Error(json.message || '上传失败')
|
||||
|
||||
// 将签名保存到个人信息(假设 crmuseredit 接受 signature 和 signature_pic_full 字段)
|
||||
await CrmService.crmuseredit({
|
||||
id: userId,
|
||||
signature: json.data.file_name,
|
||||
signature_pic_full: json.data.file_url
|
||||
const res1 = await commonService.signatureEdit({
|
||||
sign_img: json.data.file_name
|
||||
})
|
||||
|
||||
ElMessage.success('签名已保存')
|
||||
ElMessage.success(res1?.message || '签名已保存')
|
||||
locked.value = true
|
||||
// 完成后可提示返回或自动关闭
|
||||
setTimeout(() => {
|
||||
if (window.history.length > 1) window.history.back()
|
||||
}, 800)
|
||||
// setTimeout(() => {
|
||||
// if (window.history.length > 1) window.history.back()
|
||||
// }, 800)
|
||||
} catch (e: any) {
|
||||
ElMessage.error(e?.message || '保存失败')
|
||||
} finally {
|
||||
|
||||
Reference in New Issue
Block a user