Bläddra i källkod

调整葡萄城编辑器,增加填写字段颜色提示、不可填字段限制

yangguanjin 5 dagar sedan
förälder
incheckning
065e43e6fc

+ 53 - 30
src/pages/editor/equipCheckRecordEditor.vue

@@ -34,7 +34,7 @@ import SpreadDesigner from '@/components/SpreadDesigner/spreadDesigner.vue'
 import { onLoad } from '@dcloudio/uni-app'
 import { getCheckerEquipmentDetailById, getDynamicTbVal, saveDynamicTbVal } from '@/api/task'
 import { getStandardTemplate } from '@/api/index'
-import { buildFileUrl } from '@/utils/index'
+import { getEnvBaseUrl } from '@/utils/index'
 import { PressureCheckerMyTaskStatus } from '@/utils/dictMap'
 
 const spreadDesignerRef = ref<any>(null)
@@ -42,6 +42,7 @@ const checkItemData = ref<any>(null)
 const reportList = ref<any[]>([])
 const taskOrderItem = ref<any>(null)
 const templateBlob = ref<string>('')
+const skipEntryKeys = ref<string[]>([])
 
 let orderItemId = ''
 let checkItemId = ''
@@ -68,6 +69,7 @@ const handleGetCheckItemDetail = async (
   }
 
   if (useOnline === '1') {
+    skipEntryKeys.value = []
     const templateResult = await getStandardTemplate({ id: newTemplateId || '' })
     const templateDetail = (templateResult as any).data
 
@@ -84,12 +86,18 @@ const handleGetCheckItemDetail = async (
     const initJSONResult = {}
     for (let i = 0; i < dynamicTb.dynamicTbValRespVOList.length; i++) {
       const item = dynamicTb.dynamicTbValRespVOList[i]
-      initJSONResult[item.colCode] = item.valValue
+      const val = item.valValue
+      if (typeof val === 'string' && /\.(jpg|png)$/i.test(val)) {
+        skipEntryKeys.value.push(item.colCode)
+        continue
+      }
+      initJSONResult[item.colCode] = val
     }
 
     const recordTemplateUrl: string | undefined = templateDetail.fileUrl
 
-    const blob = await getBlob(recordTemplateUrl || '')
+    const excelBlob = await fetchExcel(reportId, newTemplateId || '')
+    const blob = await blobToBase64(excelBlob)
 
     const dic = {
       blob: blob || '',
@@ -152,35 +160,43 @@ const getDetail = async () => {
   }
 }
 
-const getBlob = async (url: string): Promise<string> => {
-  if (!url) return ''
-  const fileUrl = buildFileUrl(url)
-  return downloadFileAsBase64(fileUrl)
+const fetchExcel = async (refId: string | number, templateId: string | number): Promise<Blob> => {
+  const apiPath = '/pressure2/excel/excel'
+  let requestUrl = apiPath
+  if (JSON.parse(import.meta.env.VITE_APP_PROXY) && import.meta.env.MODE === 'development') {
+    requestUrl = import.meta.env.VITE_APP_PROXY_PREFIX + apiPath
+  } else {
+    requestUrl = getEnvBaseUrl() + apiPath
+  }
+
+  const token = uni.getStorageSync('APP_ACCESS_TOKEN')
+  const headers: Record<string, string> = { 'Content-Type': 'application/json' }
+  if (token) {
+    headers.Authorization = `Bearer ${token}`
+  }
+
+  const response = await fetch(requestUrl, {
+    method: 'POST',
+    headers,
+    body: JSON.stringify({ refId, templateId }),
+  })
+
+  if (!response.ok) {
+    throw new Error(`获取Excel失败, status ${response.status}`)
+  }
+
+  return await response.blob()
 }
 
-const downloadFileAsBase64 = (fileUrl: string): Promise<string> => {
+const blobToBase64 = (blob: Blob): Promise<string> => {
   return new Promise((resolve, reject) => {
-    uni.request({
-      url: fileUrl,
-      method: 'GET',
-      responseType: 'arraybuffer',
-      success: (res) => {
-        if (res.statusCode === 200) {
-          const arrayBuffer = res.data as ArrayBuffer
-          const uint8Array = new Uint8Array(arrayBuffer)
-          const binaryString = uint8Array.reduce((data, byte) => {
-            return data + String.fromCharCode(byte)
-          }, '')
-          const base64 = btoa(binaryString)
-          resolve(base64)
-        } else {
-          reject(new Error(`Request failed with status ${res.statusCode}`))
-        }
-      },
-      fail: (err) => {
-        reject(err)
-      },
-    })
+    const reader = new FileReader()
+    reader.onload = () => {
+      const base64 = (reader.result as string).split(',')[1]
+      resolve(base64)
+    }
+    reader.onerror = reject
+    reader.readAsDataURL(blob)
   })
 }
 
@@ -188,7 +204,14 @@ const handleSave = async (data: any) => {
   try {
     if (useOnline === '1') {
       const instId = data.instId
-      const result = await saveDynamicTbVal({ params: data.prepareJson, instId })
+      const reqData = {}
+      for (const key in data.prepareJson) {
+        if (skipEntryKeys.value.includes(key)) {
+          continue
+        }
+        reqData[key] = data.prepareJson[key]
+      }
+      const result = await saveDynamicTbVal({ params: reqData, instId })
       if (result?.code === 0 && result?.data) {
         uni.showToast({ title: '保存成功', icon: 'success' })
       } else {

+ 56 - 28
src/pages/editor/inspectionPlanEditor.vue

@@ -88,7 +88,7 @@ import { ref, onUnmounted } from 'vue'
 import SpreadDesignerGeneric from '@/components/SpreadDesigner/spreadDesignerGeneric.vue'
 import ReportNavBar from '@/components/NavBar/ReportNavBar.vue'
 import { onLoad } from '@dcloudio/uni-app'
-import { buildFileUrl } from '@/utils/index'
+import { getEnvBaseUrl } from '@/utils/index'
 import { getStandardTemplate, uploadFile } from '@/api/index'
 import { getAuditList } from '@/api/system/user'
 import { getDynamicTbVal, saveDynamicTbVal } from '@/api/task'
@@ -122,6 +122,7 @@ const businessConfig = ref({
     ],
   },
 })
+const skipEntryKeys = ref<string[]>([])
 const templateBlob = ref<string>('')
 const templateData = ref<any>({})
 const equipType = useConfigStore().getEquipType()
@@ -152,6 +153,7 @@ onUnmounted(() => {
 const instId = ref<string>('')
 const init = async () => {
   uni.hideLoading()
+  skipEntryKeys.value = []
   if (!templateId || !refId) {
     return
   }
@@ -165,7 +167,12 @@ const init = async () => {
   instId.value = dynamicTb?.dynamicTbInsRespVO?.id || ''
   for (let i = 0; i < dynamicTb.dynamicTbValRespVOList.length; i++) {
     const item = dynamicTb.dynamicTbValRespVOList[i]
-    dataMap[item.colCode] = item.valValue
+    const val = item.valValue
+    if (typeof val === 'string' && /\.(jpg|png)$/i.test(val)) {
+      skipEntryKeys.value.push(item.colCode)
+      continue
+    }
+    dataMap[item.colCode] = val
   }
 
   templateData.value = {
@@ -180,40 +187,61 @@ const init = async () => {
     templateUrl: resData.fileUrl,
   }
 
-  const fileUri = resData.fileUrl
-  const fileUrl = buildFileUrl(fileUri)
-  const fileBase64 = await downloadFileAsBase64(fileUrl)
+  const excelBlob = await fetchExcel(refId, templateId)
+  const fileBase64 = await blobToBase64(excelBlob)
   templateBlob.value = fileBase64
 }
 
-const downloadFileAsBase64 = (fileUrl: string): Promise<string> => {
+const fetchExcel = async (refId: string | number, templateId: string | number): Promise<Blob> => {
+  const apiPath = '/pressure2/excel/excel'
+  let requestUrl = apiPath
+  if (JSON.parse(import.meta.env.VITE_APP_PROXY) && import.meta.env.MODE === 'development') {
+    requestUrl = import.meta.env.VITE_APP_PROXY_PREFIX + apiPath
+  } else {
+    requestUrl = getEnvBaseUrl() + apiPath
+  }
+
+  const token = uni.getStorageSync('APP_ACCESS_TOKEN')
+  const headers: Record<string, string> = { 'Content-Type': 'application/json' }
+  if (token) {
+    headers.Authorization = `Bearer ${token}`
+  }
+
+  const response = await fetch(requestUrl, {
+    method: 'POST',
+    headers,
+    body: JSON.stringify({ refId, templateId }),
+  })
+
+  if (!response.ok) {
+    throw new Error(`获取Excel失败, status ${response.status}`)
+  }
+
+  return await response.blob()
+}
+
+const blobToBase64 = (blob: Blob): Promise<string> => {
   return new Promise((resolve, reject) => {
-    uni.request({
-      url: fileUrl,
-      method: 'GET',
-      responseType: 'arraybuffer',
-      success: (res) => {
-        if (res.statusCode === 200) {
-          const arrayBuffer = res.data as ArrayBuffer
-          const uint8Array = new Uint8Array(arrayBuffer)
-          const binaryString = uint8Array.reduce((data, byte) => {
-            return data + String.fromCharCode(byte)
-          }, '')
-          const base64 = btoa(binaryString)
-          resolve(base64)
-        } else {
-          reject(new Error(`Request failed with status ${res.statusCode}`))
-        }
-      },
-      fail: (err) => {
-        reject(err)
-      },
-    })
+    const reader = new FileReader()
+    reader.onload = () => {
+      const base64 = (reader.result as string).split(',')[1]
+      resolve(base64)
+    }
+    reader.onerror = reject
+    reader.readAsDataURL(blob)
   })
 }
 
 const handleSave = async (data: any) => {
-  const result = await saveDynamicTbVal({ params: data.dataJSON, instId: instId.value })
+  const reqData = {}
+  for (const key in data.dataJSON) {
+    if (skipEntryKeys.value.includes(key)) {
+      continue
+    }
+    const element = data.dataJSON[key];
+    reqData[key] = element
+  }
+  const result = await saveDynamicTbVal({ params: reqData, instId: instId.value })
   if (result?.code === 0 && result?.data) {
     uni.showToast({ title: '保存报表成功', icon: 'success' })
   } else {

+ 56 - 28
src/pages/editor/mainQuestionEditor.vue

@@ -26,7 +26,7 @@
 import { ref } from 'vue'
 import SpreadDesignerGeneric from '@/components/SpreadDesigner/spreadDesignerGeneric.vue'
 import { onLoad } from '@dcloudio/uni-app'
-import { buildFileUrl } from '@/utils/index'
+import { getEnvBaseUrl } from '@/utils/index'
 import { getStandardTemplate } from '@/api/index'
 import { getDynamicTbVal, saveDynamicTbVal } from '@/api/task'
 
@@ -45,6 +45,7 @@ const businessConfig = ref({
 })
 const templateBlob = ref<string>('')
 const templateData = ref<any>({})
+const skipEntryKeys = ref<string[]>([])
 
 let templateId: string = ''
 let refId: string = ''
@@ -58,6 +59,7 @@ onLoad((options: any) => {
 const instId = ref<string>('')
 const init = async () => {
   uni.hideLoading()
+  skipEntryKeys.value = []
   if (!templateId || !refId) {
     return
   }
@@ -71,7 +73,12 @@ const init = async () => {
   instId.value = dynamicTb?.dynamicTbInsRespVO?.id || ''
   for (let i = 0; i < dynamicTb.dynamicTbValRespVOList.length; i++) {
     const item = dynamicTb.dynamicTbValRespVOList[i]
-    dataMap[item.colCode] = item.valValue
+    const val = item.valValue
+    if (typeof val === 'string' && /\.(jpg|png)$/i.test(val)) {
+      skipEntryKeys.value.push(item.colCode)
+      continue
+    }
+    dataMap[item.colCode] = val
   }
 
   templateData.value = {
@@ -86,40 +93,61 @@ const init = async () => {
     templateUrl: resData.fileUrl,
   }
 
-  const fileUri = resData.fileUrl
-  const fileUrl = buildFileUrl(fileUri)
-  const fileBase64 = await downloadFileAsBase64(fileUrl)
+  const excelBlob = await fetchExcel(refId, templateId)
+  const fileBase64 = await blobToBase64(excelBlob)
   templateBlob.value = fileBase64
 }
 
-const downloadFileAsBase64 = (fileUrl: string): Promise<string> => {
+const fetchExcel = async (refId: string | number, templateId: string | number): Promise<Blob> => {
+  const apiPath = '/pressure2/excel/excel'
+  let requestUrl = apiPath
+  if (JSON.parse(import.meta.env.VITE_APP_PROXY) && import.meta.env.MODE === 'development') {
+    requestUrl = import.meta.env.VITE_APP_PROXY_PREFIX + apiPath
+  } else {
+    requestUrl = getEnvBaseUrl() + apiPath
+  }
+
+  const token = uni.getStorageSync('APP_ACCESS_TOKEN')
+  const headers: Record<string, string> = { 'Content-Type': 'application/json' }
+  if (token) {
+    headers.Authorization = `Bearer ${token}`
+  }
+
+  const response = await fetch(requestUrl, {
+    method: 'POST',
+    headers,
+    body: JSON.stringify({ refId, templateId }),
+  })
+
+  if (!response.ok) {
+    throw new Error(`获取Excel失败, status ${response.status}`)
+  }
+
+  return await response.blob()
+}
+
+const blobToBase64 = (blob: Blob): Promise<string> => {
   return new Promise((resolve, reject) => {
-    uni.request({
-      url: fileUrl,
-      method: 'GET',
-      responseType: 'arraybuffer',
-      success: (res) => {
-        if (res.statusCode === 200) {
-          const arrayBuffer = res.data as ArrayBuffer
-          const uint8Array = new Uint8Array(arrayBuffer)
-          const binaryString = uint8Array.reduce((data, byte) => {
-            return data + String.fromCharCode(byte)
-          }, '')
-          const base64 = btoa(binaryString)
-          resolve(base64)
-        } else {
-          reject(new Error(`Request failed with status ${res.statusCode}`))
-        }
-      },
-      fail: (err) => {
-        reject(err)
-      },
-    })
+    const reader = new FileReader()
+    reader.onload = () => {
+      const base64 = (reader.result as string).split(',')[1]
+      resolve(base64)
+    }
+    reader.onerror = reject
+    reader.readAsDataURL(blob)
   })
 }
 
 const handleSave = async (data: any) => {
-  const result = await saveDynamicTbVal({ params: data.dataJSON, instId: instId.value })
+  const reqData = {}
+  for (const key in data.dataJSON) {
+    if (skipEntryKeys.value.includes(key)) {
+      continue
+    }
+    const element = data.dataJSON[key];
+    reqData[key] = element
+  }
+  const result = await saveDynamicTbVal({ params: reqData, instId: instId.value })
   if (result?.code === 0 && result?.data) {
     uni.showToast({ title: '保存成功', icon: 'success' })
   } else {

+ 57 - 29
src/pages/editor/securityCheckEditor.vue

@@ -26,7 +26,7 @@
 import { ref } from 'vue'
 import SpreadDesignerGeneric from '@/components/SpreadDesigner/spreadDesignerGeneric.vue'
 import { onLoad } from '@dcloudio/uni-app'
-import { buildFileUrl } from '@/utils/index'
+import { getEnvBaseUrl } from '@/utils/index'
 import { useConfigStore } from '@/store/config'
 import {
   SecurityCheckFuncName,
@@ -53,6 +53,7 @@ const businessConfig = ref({
 })
 const templateBlob = ref<string>('')
 const templateData = ref<any>({})
+const skipEntryKeys = ref<string[]>([])
 
 let templateId: string = ''
 let orderId: string = ''
@@ -70,6 +71,7 @@ onLoad((options: any) => {
 const instId = ref<string>('')
 const refId = ref<string>('')
 const init = async () => {
+  skipEntryKeys.value = []
   if (!templateId) {
     return
   }
@@ -101,7 +103,12 @@ const init = async () => {
   instId.value = dynamicTb?.dynamicTbInsRespVO?.id || ''
   for (let i = 0; i < dynamicTb.dynamicTbValRespVOList.length; i++) {
     const item = dynamicTb.dynamicTbValRespVOList[i]
-    dataMap[item.colCode] = item.valValue
+    const val = item.valValue
+    if (typeof val === 'string' && /\.(jpg|png)$/i.test(val)) {
+      skipEntryKeys.value.push(item.colCode)
+      continue
+    }
+    dataMap[item.colCode] = val
   }
 
   templateData.value = {
@@ -116,40 +123,61 @@ const init = async () => {
     templateUrl: resData.fileUrl,
   }
 
-  const fileUri = resData.fileUrl
-  const fileUrl = buildFileUrl(fileUri)
-  const fileBase64 = await downloadFileAsBase64(fileUrl)
+  const excelBlob = await fetchExcel(refId.value, templateId)
+  const fileBase64 = await blobToBase64(excelBlob)
   templateBlob.value = fileBase64
 }
 
-const downloadFileAsBase64 = (fileUrl: string): Promise<string> => {
+const fetchExcel = async (refId: string | number, templateId: string | number): Promise<Blob> => {
+  const apiPath = '/pressure2/excel/excel'
+  let requestUrl = apiPath
+  if (JSON.parse(import.meta.env.VITE_APP_PROXY) && import.meta.env.MODE === 'development') {
+    requestUrl = import.meta.env.VITE_APP_PROXY_PREFIX + apiPath
+  } else {
+    requestUrl = getEnvBaseUrl() + apiPath
+  }
+
+  const token = uni.getStorageSync('APP_ACCESS_TOKEN')
+  const headers: Record<string, string> = { 'Content-Type': 'application/json' }
+  if (token) {
+    headers.Authorization = `Bearer ${token}`
+  }
+
+  const response = await fetch(requestUrl, {
+    method: 'POST',
+    headers,
+    body: JSON.stringify({ refId, templateId }),
+  })
+
+  if (!response.ok) {
+    throw new Error(`获取Excel失败, status ${response.status}`)
+  }
+
+  return await response.blob()
+}
+
+const blobToBase64 = (blob: Blob): Promise<string> => {
   return new Promise((resolve, reject) => {
-    uni.request({
-      url: fileUrl,
-      method: 'GET',
-      responseType: 'arraybuffer',
-      success: (res) => {
-        if (res.statusCode === 200) {
-          const arrayBuffer = res.data as ArrayBuffer
-          const uint8Array = new Uint8Array(arrayBuffer)
-          const binaryString = uint8Array.reduce((data, byte) => {
-            return data + String.fromCharCode(byte)
-          }, '')
-          const base64 = btoa(binaryString)
-          resolve(base64) // 成功时 resolve Base64 字符串
-        } else {
-          reject(new Error(`Request failed with status ${res.statusCode}`))
-        }
-      },
-      fail: (err) => {
-        reject(err) // 失败时 reject 错误
-      },
-    })
+    const reader = new FileReader()
+    reader.onload = () => {
+      const base64 = (reader.result as string).split(',')[1]
+      resolve(base64)
+    }
+    reader.onerror = reject
+    reader.readAsDataURL(blob)
   })
 }
 
 const handleSave = async (data: any) => {
-  const result = await saveDynamicTbVal({ params: data.dataJSON, instId: instId.value })
+  const reqData = {}
+  for (const key in data.dataJSON) {
+    if (skipEntryKeys.value.includes(key)) {
+      continue
+    }
+    const element = data.dataJSON[key];
+    reqData[key] = element
+  }
+  const result = await saveDynamicTbVal({ params: reqData, instId: instId.value })
   if (result?.code === 0 && result?.data) {
     uni.showToast({ title: '保存成功', icon: 'success' })
   } else {
@@ -161,7 +189,7 @@ const handleSave = async (data: any) => {
     equipType,
     {
       id: refId.value,
-      jsonData: JSON.stringify(data.dataJSON),
+      jsonData: JSON.stringify(reqData),
     },
   )
 }

+ 56 - 28
src/pages/editor/serviceOrderEditor.vue

@@ -26,7 +26,7 @@
 import { ref } from 'vue'
 import SpreadDesignerGeneric from '@/components/SpreadDesigner/spreadDesignerGeneric.vue'
 import { onLoad } from '@dcloudio/uni-app'
-import { buildFileUrl } from '@/utils/index'
+import { getEnvBaseUrl } from '@/utils/index'
 import { useConfigStore } from '@/store/config'
 import { getStandardTemplate } from '@/api/index'
 import { getDynamicTbVal, saveDynamicTbVal } from '@/api/task'
@@ -48,6 +48,7 @@ const businessConfig = ref({
 })
 const templateBlob = ref<string>('')
 const templateData = ref<any>({})
+const skipEntryKeys = ref<string[]>([])
 
 let templateId: string = ''
 let refId: string = ''
@@ -60,6 +61,7 @@ onLoad((options: any) => {
 
 const instId = ref<string>('')
 const init = async () => {
+  skipEntryKeys.value = []
   if (!templateId) {
     return
   }
@@ -73,7 +75,12 @@ const init = async () => {
   instId.value = dynamicTb?.dynamicTbInsRespVO?.id || ''
   for (let i = 0; i < dynamicTb.dynamicTbValRespVOList.length; i++) {
     const item = dynamicTb.dynamicTbValRespVOList[i]
-    dataMap[item.colCode] = item.valValue
+    const val = item.valValue
+    if (typeof val === 'string' && /\.(jpg|png)$/i.test(val)) {
+      skipEntryKeys.value.push(item.colCode)
+      continue
+    }
+    dataMap[item.colCode] = val
   }
 
   templateData.value = {
@@ -88,40 +95,61 @@ const init = async () => {
     templateUrl: resData.fileUrl,
   }
 
-  const fileUri = resData.fileUrl
-  const fileUrl = buildFileUrl(fileUri)
-  const fileBase64 = await downloadFileAsBase64(fileUrl)
+  const excelBlob = await fetchExcel(refId, templateId)
+  const fileBase64 = await blobToBase64(excelBlob)
   templateBlob.value = fileBase64
 }
 
-const downloadFileAsBase64 = (fileUrl: string): Promise<string> => {
+const fetchExcel = async (refId: string | number, templateId: string | number): Promise<Blob> => {
+  const apiPath = '/pressure2/excel/excel'
+  let requestUrl = apiPath
+  if (JSON.parse(import.meta.env.VITE_APP_PROXY) && import.meta.env.MODE === 'development') {
+    requestUrl = import.meta.env.VITE_APP_PROXY_PREFIX + apiPath
+  } else {
+    requestUrl = getEnvBaseUrl() + apiPath
+  }
+
+  const token = uni.getStorageSync('APP_ACCESS_TOKEN')
+  const headers: Record<string, string> = { 'Content-Type': 'application/json' }
+  if (token) {
+    headers.Authorization = `Bearer ${token}`
+  }
+
+  const response = await fetch(requestUrl, {
+    method: 'POST',
+    headers,
+    body: JSON.stringify({ refId, templateId }),
+  })
+
+  if (!response.ok) {
+    throw new Error(`获取Excel失败, status ${response.status}`)
+  }
+
+  return await response.blob()
+}
+
+const blobToBase64 = (blob: Blob): Promise<string> => {
   return new Promise((resolve, reject) => {
-    uni.request({
-      url: fileUrl,
-      method: 'GET',
-      responseType: 'arraybuffer',
-      success: (res) => {
-        if (res.statusCode === 200) {
-          const arrayBuffer = res.data as ArrayBuffer
-          const uint8Array = new Uint8Array(arrayBuffer)
-          const binaryString = uint8Array.reduce((data, byte) => {
-            return data + String.fromCharCode(byte)
-          }, '')
-          const base64 = btoa(binaryString)
-          resolve(base64) // 成功时 resolve Base64 字符串
-        } else {
-          reject(new Error(`Request failed with status ${res.statusCode}`))
-        }
-      },
-      fail: (err) => {
-        reject(err) // 失败时 reject 错误
-      },
-    })
+    const reader = new FileReader()
+    reader.onload = () => {
+      const base64 = (reader.result as string).split(',')[1]
+      resolve(base64)
+    }
+    reader.onerror = reject
+    reader.readAsDataURL(blob)
   })
 }
 
 const handleSave = async (data: any) => {
-  const result = await saveDynamicTbVal({ params: data.dataJSON, instId: instId.value })
+  const reqData = {}
+  for (const key in data.dataJSON) {
+    if (skipEntryKeys.value.includes(key)) {
+      continue
+    }
+    const element = data.dataJSON[key];
+    reqData[key] = element
+  }
+  const result = await saveDynamicTbVal({ params: reqData, instId: instId.value })
   if (result?.code === 0 && result?.data) {
     uni.showToast({ title: '保存成功', icon: 'success' })
   } else {

+ 56 - 28
src/pages/editor/workInstructionEditor.vue

@@ -26,7 +26,7 @@
 import { ref } from 'vue'
 import SpreadDesignerGeneric from '@/components/SpreadDesigner/spreadDesignerGeneric.vue'
 import { onLoad } from '@dcloudio/uni-app'
-import { buildFileUrl } from '@/utils/index'
+import { getEnvBaseUrl } from '@/utils/index'
 import { getStandardTemplate } from '@/api/index'
 import { getDynamicTbVal, saveDynamicTbVal } from '@/api/task'
 
@@ -45,6 +45,7 @@ const businessConfig = ref({
 })
 const templateBlob = ref<string>('')
 const templateData = ref<any>({})
+const skipEntryKeys = ref<string[]>([])
 
 let templateId: string = ''
 let orderId: string = ''
@@ -61,6 +62,7 @@ onLoad((options: any) => {
 
 const instId = ref<string>('')
 const init = async () => {
+  skipEntryKeys.value = []
   if (!templateId) {
     return
   }
@@ -73,7 +75,12 @@ const init = async () => {
   instId.value = dynamicTb?.dynamicTbInsRespVO?.id || ''
   for (let i = 0; i < dynamicTb.dynamicTbValRespVOList.length; i++) {
     const item = dynamicTb.dynamicTbValRespVOList[i]
-    dataMap[item.colCode] = item.valValue
+    const val = item.valValue
+    if (typeof val === 'string' && /\.(jpg|png)$/i.test(val)) {
+      skipEntryKeys.value.push(item.colCode)
+      continue
+    }
+    dataMap[item.colCode] = val
   }
 
   templateData.value = {
@@ -88,40 +95,61 @@ const init = async () => {
     templateUrl: resData.fileUrl,
   }
 
-  const fileUri = resData.fileUrl
-  const fileUrl = buildFileUrl(fileUri)
-  const fileBase64 = await downloadFileAsBase64(fileUrl)
+  const excelBlob = await fetchExcel(workInstructionId, templateId)
+  const fileBase64 = await blobToBase64(excelBlob)
   templateBlob.value = fileBase64
 }
 
-const downloadFileAsBase64 = (fileUrl: string): Promise<string> => {
+const fetchExcel = async (refId: string | number, templateId: string | number): Promise<Blob> => {
+  const apiPath = '/pressure2/excel/excel'
+  let requestUrl = apiPath
+  if (JSON.parse(import.meta.env.VITE_APP_PROXY) && import.meta.env.MODE === 'development') {
+    requestUrl = import.meta.env.VITE_APP_PROXY_PREFIX + apiPath
+  } else {
+    requestUrl = getEnvBaseUrl() + apiPath
+  }
+
+  const token = uni.getStorageSync('APP_ACCESS_TOKEN')
+  const headers: Record<string, string> = { 'Content-Type': 'application/json' }
+  if (token) {
+    headers.Authorization = `Bearer ${token}`
+  }
+
+  const response = await fetch(requestUrl, {
+    method: 'POST',
+    headers,
+    body: JSON.stringify({ refId, templateId }),
+  })
+
+  if (!response.ok) {
+    throw new Error(`获取Excel失败, status ${response.status}`)
+  }
+
+  return await response.blob()
+}
+
+const blobToBase64 = (blob: Blob): Promise<string> => {
   return new Promise((resolve, reject) => {
-    uni.request({
-      url: fileUrl,
-      method: 'GET',
-      responseType: 'arraybuffer',
-      success: (res) => {
-        if (res.statusCode === 200) {
-          const arrayBuffer = res.data as ArrayBuffer
-          const uint8Array = new Uint8Array(arrayBuffer)
-          const binaryString = uint8Array.reduce((data, byte) => {
-            return data + String.fromCharCode(byte)
-          }, '')
-          const base64 = btoa(binaryString)
-          resolve(base64) // 成功时 resolve Base64 字符串
-        } else {
-          reject(new Error(`Request failed with status ${res.statusCode}`))
-        }
-      },
-      fail: (err) => {
-        reject(err) // 失败时 reject 错误
-      },
-    })
+    const reader = new FileReader()
+    reader.onload = () => {
+      const base64 = (reader.result as string).split(',')[1]
+      resolve(base64)
+    }
+    reader.onerror = reject
+    reader.readAsDataURL(blob)
   })
 }
 
 const handleSave = async (data: any) => {
-  const result = await saveDynamicTbVal({ params: data.dataJSON, instId: instId.value })
+  const reqData = {}
+  for (const key in data.dataJSON) {
+    if (skipEntryKeys.value.includes(key)) {
+      continue
+    }
+    const element = data.dataJSON[key];
+    reqData[key] = element
+  }
+  const result = await saveDynamicTbVal({ params: reqData, instId: instId.value })
   if (result?.code === 0 && result?.data) {
     uni.showToast({ title: '保存成功', icon: 'success' })
   } else {

+ 3 - 2
src/pages/equipment/detail/components/OtherReport.vue

@@ -226,10 +226,11 @@ const handleDelReport = async (reason: string) => {
   try {
     uni.showLoading({ title: '作废中...' })
     const invalidItems = selectedProjects.value.filter(
-      (item) => item.reportType === PressureReportType.WORKINSTRUCTION && item.status !== 0,
+      (item) => (item.reportType === PressureReportType.WORKINSTRUCTION && item.status !== 0) 
+      || (item.reportType === PressureReportType.INSPECTIONPLAN && item.status !== 0)
     )
     if (invalidItems.length) {
-      uni.showToast({ title: '只能作废待提交的操作指导书', icon: 'error' })
+      uni.showToast({ title: '只能作废待提交的操作指导书和检验方案', icon: 'error' })
       uni.hideLoading()
       return
     }