diff --git a/src/api/index.ts b/src/api/index.ts index 26226a9..520e2e6 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -34,12 +34,16 @@ request.interceptors.request.use( (request) => { const userStore = useUserStore() + console.log('userStore', userStore) /** * 全局拦截请求发送前提交的参数 * 以下代码为示例,在请求头里带上 token 信息 */ if (userStore.isLogin && request.headers) { - request.headers.token = userStore.token + // request.headers.token = userStore.token + console.log('userStore.username', userStore.username) + request.headers.token = localStorage[`token-${userStore.username}`] + console.log('token', localStorage[`token-${userStore.username}`]) } // 是否将 POST 请求参数进行字符串化处理 if (request.method === 'post') { diff --git a/src/api/index.ts b/src/api/index.ts index 26226a9..520e2e6 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -34,12 +34,16 @@ request.interceptors.request.use( (request) => { const userStore = useUserStore() + console.log('userStore', userStore) /** * 全局拦截请求发送前提交的参数 * 以下代码为示例,在请求头里带上 token 信息 */ if (userStore.isLogin && request.headers) { - request.headers.token = userStore.token + // request.headers.token = userStore.token + console.log('userStore.username', userStore.username) + request.headers.token = localStorage[`token-${userStore.username}`] + console.log('token', localStorage[`token-${userStore.username}`]) } // 是否将 POST 请求参数进行字符串化处理 if (request.method === 'post') { diff --git a/src/router/index.ts b/src/router/index.ts index 6404758..eaab2c8 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -35,7 +35,7 @@ // 获取用户信息 await userStore.getUserInfo() - console.log('index.ts-after userinfo', localStorage.token, userStore.username) + console.log('index.ts-after userinfo', localStorage[`token-${userStore.id}`], userStore.username) } // 是否已根据权限动态生成并注册路由 if (routeStore.isGenerate) { diff --git a/src/api/index.ts b/src/api/index.ts index 26226a9..520e2e6 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -34,12 +34,16 @@ request.interceptors.request.use( (request) => { const userStore = useUserStore() + console.log('userStore', userStore) /** * 全局拦截请求发送前提交的参数 * 以下代码为示例,在请求头里带上 token 信息 */ if (userStore.isLogin && request.headers) { - request.headers.token = userStore.token + // request.headers.token = userStore.token + console.log('userStore.username', userStore.username) + request.headers.token = localStorage[`token-${userStore.username}`] + console.log('token', localStorage[`token-${userStore.username}`]) } // 是否将 POST 请求参数进行字符串化处理 if (request.method === 'post') { diff --git a/src/router/index.ts b/src/router/index.ts index 6404758..eaab2c8 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -35,7 +35,7 @@ // 获取用户信息 await userStore.getUserInfo() - console.log('index.ts-after userinfo', localStorage.token, userStore.username) + console.log('index.ts-after userinfo', localStorage[`token-${userStore.id}`], userStore.username) } // 是否已根据权限动态生成并注册路由 if (routeStore.isGenerate) { diff --git a/src/store/modules/user.ts b/src/store/modules/user.ts index 7a6ebea..9d61072 100644 --- a/src/store/modules/user.ts +++ b/src/store/modules/user.ts @@ -12,8 +12,8 @@ { state: () => ({ username: localStorage.username || '', // 账户 - token: localStorage.token || '', // token id: '', // 用户id + token: '', // token name: '', // 姓名 deptId: '', // 部门id deptName: '', // 部门名称 @@ -64,17 +64,19 @@ // 获取项目基础配置 getBaseConfig() { return new Promise((resolve, reject) => { - getConfig().then((res) => { - this.publicKey = res.data.publicKey - localStorage.setItem('publicKey', res.data.publicKey) - // 保存私钥 - setPrivateKey(privateStr) - this.privateKey = privateStr - this.isLogout = 0 - resolve(res.data) - }).catch((e) => { - reject(e) - }) + getConfig() + .then((res) => { + this.publicKey = res.data.publicKey + localStorage.setItem('publicKey', res.data.publicKey) + // 保存私钥 + setPrivateKey(privateStr) + this.privateKey = privateStr + this.isLogout = 0 + resolve(res.data) + }) + .catch((e) => { + reject(e) + }) }) }, // 登录 @@ -84,16 +86,20 @@ kaptcha: string sid: string }) { + this.username = data.username + console.log('------------------', this.username) return new Promise((resolve, reject) => { - doLogin(data).then((res) => { - localStorage.setItem('token', res.data.token) - this.username = res.data.username - this.token = res.data.token - this.isLogout = 0 - resolve() - }).catch((error) => { - reject(error) - }) + doLogin(data) + .then((res) => { + localStorage.setItem(`login-${data.username}`, data.username) + localStorage.setItem(`token-${data.username}`, res.data.token) + this.token = res.data.token + this.isLogout = 0 + resolve() + }) + .catch((error) => { + reject(error) + }) }) }, // 注销 @@ -102,7 +108,8 @@ const routeStore = useRouteStore() const menuStore = useMenuStore() localStorage.removeItem('username') - localStorage.removeItem('token') + localStorage.removeItem(`login-${this.username}`) + localStorage.removeItem(`token-${this.username}`) localStorage.removeItem('nameId') localStorage.removeItem('depId') this.username = '' @@ -117,31 +124,33 @@ // 获取用户信息 getUserInfo() { return new Promise((resolve) => { - getInfo().then((res) => { - if (res.data.roleIds && res.data.roleIds.length > 0) { - this.roleList = res.data.roleIds - this.roleNames = res.data.roleNames - this.roleTips = res.data.roleTips - localStorage.setItem('nameId', res.data.id) - localStorage.setItem('depId', res.data.deptId) - } - else { - reject('该用户无角色') - } - if (res.data.deptId) { - this.deptId = res.data.deptId - this.deptName = res.data.deptName - } - else { - reject('该用户无组织机构') - } - this.id = res.data.id - this.username = res.data.account - this.name = res.data.name - resolve(res.data) - }).catch(() => { - reject('获取用户信息错误') - }) + getInfo() + .then((res) => { + if (res.data.roleIds && res.data.roleIds.length > 0) { + this.roleList = res.data.roleIds + this.roleNames = res.data.roleNames + this.roleTips = res.data.roleTips + localStorage.setItem('nameId', res.data.id) + localStorage.setItem('depId', res.data.deptId) + } + else { + reject('该用户无角色') + } + if (res.data.deptId) { + this.deptId = res.data.deptId + this.deptName = res.data.deptName + } + else { + reject('该用户无组织机构') + } + this.id = res.data.id + this.username = res.data.account + this.name = res.data.name + resolve(res.data) + }) + .catch(() => { + reject('获取用户信息错误') + }) }) }, // 获取菜单按钮权限 @@ -161,8 +170,10 @@ if (data.menus && data.menus.length > 0) { const allmenus = [...data.menus] this.menus = allmenus - for (const menu of allmenus) { // 遍历菜单,获取所有的权限项 - if (menu.resourceType === '02' || menu.resourceType === '03') { // 将是菜单的放入menus + for (const menu of allmenus) { + // 遍历菜单,获取所有的权限项 + if (menu.resourceType === '02' || menu.resourceType === '03') { + // 将是菜单的放入menus const menu_tmp = { url: menu.url, name: menu.name, @@ -185,10 +196,7 @@ }) }, // 修改密码 - editPassword(data: { - oldPwd: string - newPwd: string - }) { + editPassword(data: { oldPwd: string; newPwd: string }) { return new Promise((resolve) => { changePwd(data).then((response) => { resolve(response) diff --git a/src/api/index.ts b/src/api/index.ts index 26226a9..520e2e6 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -34,12 +34,16 @@ request.interceptors.request.use( (request) => { const userStore = useUserStore() + console.log('userStore', userStore) /** * 全局拦截请求发送前提交的参数 * 以下代码为示例,在请求头里带上 token 信息 */ if (userStore.isLogin && request.headers) { - request.headers.token = userStore.token + // request.headers.token = userStore.token + console.log('userStore.username', userStore.username) + request.headers.token = localStorage[`token-${userStore.username}`] + console.log('token', localStorage[`token-${userStore.username}`]) } // 是否将 POST 请求参数进行字符串化处理 if (request.method === 'post') { diff --git a/src/router/index.ts b/src/router/index.ts index 6404758..eaab2c8 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -35,7 +35,7 @@ // 获取用户信息 await userStore.getUserInfo() - console.log('index.ts-after userinfo', localStorage.token, userStore.username) + console.log('index.ts-after userinfo', localStorage[`token-${userStore.id}`], userStore.username) } // 是否已根据权限动态生成并注册路由 if (routeStore.isGenerate) { diff --git a/src/store/modules/user.ts b/src/store/modules/user.ts index 7a6ebea..9d61072 100644 --- a/src/store/modules/user.ts +++ b/src/store/modules/user.ts @@ -12,8 +12,8 @@ { state: () => ({ username: localStorage.username || '', // 账户 - token: localStorage.token || '', // token id: '', // 用户id + token: '', // token name: '', // 姓名 deptId: '', // 部门id deptName: '', // 部门名称 @@ -64,17 +64,19 @@ // 获取项目基础配置 getBaseConfig() { return new Promise((resolve, reject) => { - getConfig().then((res) => { - this.publicKey = res.data.publicKey - localStorage.setItem('publicKey', res.data.publicKey) - // 保存私钥 - setPrivateKey(privateStr) - this.privateKey = privateStr - this.isLogout = 0 - resolve(res.data) - }).catch((e) => { - reject(e) - }) + getConfig() + .then((res) => { + this.publicKey = res.data.publicKey + localStorage.setItem('publicKey', res.data.publicKey) + // 保存私钥 + setPrivateKey(privateStr) + this.privateKey = privateStr + this.isLogout = 0 + resolve(res.data) + }) + .catch((e) => { + reject(e) + }) }) }, // 登录 @@ -84,16 +86,20 @@ kaptcha: string sid: string }) { + this.username = data.username + console.log('------------------', this.username) return new Promise((resolve, reject) => { - doLogin(data).then((res) => { - localStorage.setItem('token', res.data.token) - this.username = res.data.username - this.token = res.data.token - this.isLogout = 0 - resolve() - }).catch((error) => { - reject(error) - }) + doLogin(data) + .then((res) => { + localStorage.setItem(`login-${data.username}`, data.username) + localStorage.setItem(`token-${data.username}`, res.data.token) + this.token = res.data.token + this.isLogout = 0 + resolve() + }) + .catch((error) => { + reject(error) + }) }) }, // 注销 @@ -102,7 +108,8 @@ const routeStore = useRouteStore() const menuStore = useMenuStore() localStorage.removeItem('username') - localStorage.removeItem('token') + localStorage.removeItem(`login-${this.username}`) + localStorage.removeItem(`token-${this.username}`) localStorage.removeItem('nameId') localStorage.removeItem('depId') this.username = '' @@ -117,31 +124,33 @@ // 获取用户信息 getUserInfo() { return new Promise((resolve) => { - getInfo().then((res) => { - if (res.data.roleIds && res.data.roleIds.length > 0) { - this.roleList = res.data.roleIds - this.roleNames = res.data.roleNames - this.roleTips = res.data.roleTips - localStorage.setItem('nameId', res.data.id) - localStorage.setItem('depId', res.data.deptId) - } - else { - reject('该用户无角色') - } - if (res.data.deptId) { - this.deptId = res.data.deptId - this.deptName = res.data.deptName - } - else { - reject('该用户无组织机构') - } - this.id = res.data.id - this.username = res.data.account - this.name = res.data.name - resolve(res.data) - }).catch(() => { - reject('获取用户信息错误') - }) + getInfo() + .then((res) => { + if (res.data.roleIds && res.data.roleIds.length > 0) { + this.roleList = res.data.roleIds + this.roleNames = res.data.roleNames + this.roleTips = res.data.roleTips + localStorage.setItem('nameId', res.data.id) + localStorage.setItem('depId', res.data.deptId) + } + else { + reject('该用户无角色') + } + if (res.data.deptId) { + this.deptId = res.data.deptId + this.deptName = res.data.deptName + } + else { + reject('该用户无组织机构') + } + this.id = res.data.id + this.username = res.data.account + this.name = res.data.name + resolve(res.data) + }) + .catch(() => { + reject('获取用户信息错误') + }) }) }, // 获取菜单按钮权限 @@ -161,8 +170,10 @@ if (data.menus && data.menus.length > 0) { const allmenus = [...data.menus] this.menus = allmenus - for (const menu of allmenus) { // 遍历菜单,获取所有的权限项 - if (menu.resourceType === '02' || menu.resourceType === '03') { // 将是菜单的放入menus + for (const menu of allmenus) { + // 遍历菜单,获取所有的权限项 + if (menu.resourceType === '02' || menu.resourceType === '03') { + // 将是菜单的放入menus const menu_tmp = { url: menu.url, name: menu.name, @@ -185,10 +196,7 @@ }) }, // 修改密码 - editPassword(data: { - oldPwd: string - newPwd: string - }) { + editPassword(data: { oldPwd: string; newPwd: string }) { return new Promise((resolve) => { changePwd(data).then((response) => { resolve(response) diff --git a/src/views/business/lab/certificateReportRetrieval/reportList.vue b/src/views/business/lab/certificateReportRetrieval/reportList.vue index 2a4276b..c8d9cb9 100644 --- a/src/views/business/lab/certificateReportRetrieval/reportList.vue +++ b/src/views/business/lab/certificateReportRetrieval/reportList.vue @@ -31,6 +31,7 @@ customerName: '', // 委托方名称 measureType: '', // 校验类别 measurePersonId: '', // 检定人员 + templateDesc: '', // 模板描述 }) // 多选选中 const list = ref([]) // 数据列表 @@ -85,6 +86,7 @@ customerName: '', // 委托方名称 measureType: '', // 校验类别 measurePersonId: '', // 检定人员 + templateDesc: '', // 模板描述 } fetchData(true) } @@ -357,6 +359,13 @@ + + + diff --git a/src/api/index.ts b/src/api/index.ts index 26226a9..520e2e6 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -34,12 +34,16 @@ request.interceptors.request.use( (request) => { const userStore = useUserStore() + console.log('userStore', userStore) /** * 全局拦截请求发送前提交的参数 * 以下代码为示例,在请求头里带上 token 信息 */ if (userStore.isLogin && request.headers) { - request.headers.token = userStore.token + // request.headers.token = userStore.token + console.log('userStore.username', userStore.username) + request.headers.token = localStorage[`token-${userStore.username}`] + console.log('token', localStorage[`token-${userStore.username}`]) } // 是否将 POST 请求参数进行字符串化处理 if (request.method === 'post') { diff --git a/src/router/index.ts b/src/router/index.ts index 6404758..eaab2c8 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -35,7 +35,7 @@ // 获取用户信息 await userStore.getUserInfo() - console.log('index.ts-after userinfo', localStorage.token, userStore.username) + console.log('index.ts-after userinfo', localStorage[`token-${userStore.id}`], userStore.username) } // 是否已根据权限动态生成并注册路由 if (routeStore.isGenerate) { diff --git a/src/store/modules/user.ts b/src/store/modules/user.ts index 7a6ebea..9d61072 100644 --- a/src/store/modules/user.ts +++ b/src/store/modules/user.ts @@ -12,8 +12,8 @@ { state: () => ({ username: localStorage.username || '', // 账户 - token: localStorage.token || '', // token id: '', // 用户id + token: '', // token name: '', // 姓名 deptId: '', // 部门id deptName: '', // 部门名称 @@ -64,17 +64,19 @@ // 获取项目基础配置 getBaseConfig() { return new Promise((resolve, reject) => { - getConfig().then((res) => { - this.publicKey = res.data.publicKey - localStorage.setItem('publicKey', res.data.publicKey) - // 保存私钥 - setPrivateKey(privateStr) - this.privateKey = privateStr - this.isLogout = 0 - resolve(res.data) - }).catch((e) => { - reject(e) - }) + getConfig() + .then((res) => { + this.publicKey = res.data.publicKey + localStorage.setItem('publicKey', res.data.publicKey) + // 保存私钥 + setPrivateKey(privateStr) + this.privateKey = privateStr + this.isLogout = 0 + resolve(res.data) + }) + .catch((e) => { + reject(e) + }) }) }, // 登录 @@ -84,16 +86,20 @@ kaptcha: string sid: string }) { + this.username = data.username + console.log('------------------', this.username) return new Promise((resolve, reject) => { - doLogin(data).then((res) => { - localStorage.setItem('token', res.data.token) - this.username = res.data.username - this.token = res.data.token - this.isLogout = 0 - resolve() - }).catch((error) => { - reject(error) - }) + doLogin(data) + .then((res) => { + localStorage.setItem(`login-${data.username}`, data.username) + localStorage.setItem(`token-${data.username}`, res.data.token) + this.token = res.data.token + this.isLogout = 0 + resolve() + }) + .catch((error) => { + reject(error) + }) }) }, // 注销 @@ -102,7 +108,8 @@ const routeStore = useRouteStore() const menuStore = useMenuStore() localStorage.removeItem('username') - localStorage.removeItem('token') + localStorage.removeItem(`login-${this.username}`) + localStorage.removeItem(`token-${this.username}`) localStorage.removeItem('nameId') localStorage.removeItem('depId') this.username = '' @@ -117,31 +124,33 @@ // 获取用户信息 getUserInfo() { return new Promise((resolve) => { - getInfo().then((res) => { - if (res.data.roleIds && res.data.roleIds.length > 0) { - this.roleList = res.data.roleIds - this.roleNames = res.data.roleNames - this.roleTips = res.data.roleTips - localStorage.setItem('nameId', res.data.id) - localStorage.setItem('depId', res.data.deptId) - } - else { - reject('该用户无角色') - } - if (res.data.deptId) { - this.deptId = res.data.deptId - this.deptName = res.data.deptName - } - else { - reject('该用户无组织机构') - } - this.id = res.data.id - this.username = res.data.account - this.name = res.data.name - resolve(res.data) - }).catch(() => { - reject('获取用户信息错误') - }) + getInfo() + .then((res) => { + if (res.data.roleIds && res.data.roleIds.length > 0) { + this.roleList = res.data.roleIds + this.roleNames = res.data.roleNames + this.roleTips = res.data.roleTips + localStorage.setItem('nameId', res.data.id) + localStorage.setItem('depId', res.data.deptId) + } + else { + reject('该用户无角色') + } + if (res.data.deptId) { + this.deptId = res.data.deptId + this.deptName = res.data.deptName + } + else { + reject('该用户无组织机构') + } + this.id = res.data.id + this.username = res.data.account + this.name = res.data.name + resolve(res.data) + }) + .catch(() => { + reject('获取用户信息错误') + }) }) }, // 获取菜单按钮权限 @@ -161,8 +170,10 @@ if (data.menus && data.menus.length > 0) { const allmenus = [...data.menus] this.menus = allmenus - for (const menu of allmenus) { // 遍历菜单,获取所有的权限项 - if (menu.resourceType === '02' || menu.resourceType === '03') { // 将是菜单的放入menus + for (const menu of allmenus) { + // 遍历菜单,获取所有的权限项 + if (menu.resourceType === '02' || menu.resourceType === '03') { + // 将是菜单的放入menus const menu_tmp = { url: menu.url, name: menu.name, @@ -185,10 +196,7 @@ }) }, // 修改密码 - editPassword(data: { - oldPwd: string - newPwd: string - }) { + editPassword(data: { oldPwd: string; newPwd: string }) { return new Promise((resolve) => { changePwd(data).then((response) => { resolve(response) diff --git a/src/views/business/lab/certificateReportRetrieval/reportList.vue b/src/views/business/lab/certificateReportRetrieval/reportList.vue index 2a4276b..c8d9cb9 100644 --- a/src/views/business/lab/certificateReportRetrieval/reportList.vue +++ b/src/views/business/lab/certificateReportRetrieval/reportList.vue @@ -31,6 +31,7 @@ customerName: '', // 委托方名称 measureType: '', // 校验类别 measurePersonId: '', // 检定人员 + templateDesc: '', // 模板描述 }) // 多选选中 const list = ref([]) // 数据列表 @@ -85,6 +86,7 @@ customerName: '', // 委托方名称 measureType: '', // 校验类别 measurePersonId: '', // 检定人员 + templateDesc: '', // 模板描述 } fetchData(true) } @@ -357,6 +359,13 @@ + + + diff --git a/src/views/business/lab/excelEdit/excelEditDialogTest.vue b/src/views/business/lab/excelEdit/excelEditDialogTest.vue new file mode 100644 index 0000000..8868b3b --- /dev/null +++ b/src/views/business/lab/excelEdit/excelEditDialogTest.vue @@ -0,0 +1,134 @@ + + + + + + diff --git a/src/views/business/lab/excelEdit/methods/file.ts b/src/views/business/lab/excelEdit/methods/file.ts index 312ee55..4aae1d6 100644 --- a/src/views/business/lab/excelEdit/methods/file.ts +++ b/src/views/business/lab/excelEdit/methods/file.ts @@ -16,12 +16,15 @@ * @returns */ export function getFileType(file: Blob) { + console.log('getFileType: ', file) if (!file) { return } if (!isBlob(file)) { + console.log('不是blob文件', file) return } + console.log('是blob文件:', file, '文件类型为', file.type) const extensionName = file.type if (extensionName === 'sjs') { return FileType.SJS @@ -45,14 +48,18 @@ return file instanceof Blob } -/** +/** * @param spread spread实例 * @param file 文件 + * @param fileTypeParam 文件类型 * @returns */ -export async function importFile(spread: any, file: Blob) { - const fileType = getFileType(file) - console.log('获取到的文件类型', fileType, fileType === FileType.SJS) +export async function importFile(spread: any, file: Blob, fileTypeParam = '') { + let fileType = fileTypeParam! + if (!fileTypeParam) { + fileType = getFileType(file)! + } + console.log('获取到的文件类型', fileTypeParam, fileType) return new Promise((resolve) => { if (fileType === FileType.SJS) { @@ -68,6 +75,8 @@ ) } else { + const type + = fileType === 'xlsx' ? 'excel' : fileType === 'ssjson' ? 'ssjson' : 'csv' spread.import( file, () => { @@ -77,6 +86,9 @@ (e: any) => { console.log('importFile-import:上传文件发生错误', e) }, + { + fileType: fileType === 'xlsm' ? null : GC.Spread.Sheets.FileType[type], + }, ) } }) diff --git a/src/views/business/lab/excelEdit/templateFiles/calibrationCert.sjs b/src/views/business/lab/excelEdit/templateFiles/calibrationCert.sjs deleted file mode 100644 index e395d36..0000000 --- a/src/views/business/lab/excelEdit/templateFiles/calibrationCert.sjs +++ /dev/null Binary files differ diff --git a/src/views/business/lab/measureData/measureDataDetail.vue b/src/views/business/lab/measureData/measureDataDetail.vue index 0ee7c70..e7dffb3 100644 --- a/src/views/business/lab/measureData/measureDataDetail.vue +++ b/src/views/business/lab/measureData/measureDataDetail.vue @@ -235,7 +235,8 @@ // ---------------------------------文件上传(上传证书)------------------------------------------- const fileRef = ref() -const onFileChange = (event: any) => { +const excelEditFileName = ref('') // 进行excel编辑的文件名称 +const onFileChange = (event: any, blob: Blob) => { // 原生上传 if (event.target.files?.length !== 0) { // 创建formdata对象 @@ -273,6 +274,47 @@ fileRef.value.click() } +// excel在线编辑完成自动上传证书 +const handleImportFile = (blob: Blob) => { + const file = new File([blob], excelEditFileName.value, { + type: blob.type, + lastModified: new Date().getTime(), + }) + // 创建formdata对象 + const fd = new FormData() + fd.append('multipartFile', file) + const loading = ElLoading.service({ + lock: true, + background: 'rgba(255, 255, 255, 0.8)', + }) + UploadFile(fd).then((res) => { + if (res.code === 200) { + form.value.certificateReportFile = res.data[0] + loading.close() + ElMessageBox.confirm( + '文件上传成功,是否保存上传的文件?', + '提示', + { + confirmButtonText: '是', + cancelButtonText: '否', + type: 'warning', + }, + ) + .then(() => { + handleSave('saveUploadFile') + }) + } + else { + ElMessage.error(res.message) + loading.close() + } + }).catch((e) => { + ElMessage.error('上传失败,请联系管理员') + console.log('上传文件失败:', e) + loading.close() + }) +} + // ----------------------------------------------样品-------------------------------------------- const selectOrderSamplesDialogRef = ref() // 选择委托书下的样品清单组件ref const selectMyMeasureDialogRef = ref() // 选择我的检测下的样品ref @@ -875,6 +917,43 @@ const handleClickExcelEdit = () => { excelEditRef.value.initDialog() } + +// 解码 +function decodePartialUrlEncoded(str: string) { + if (typeof str !== 'string') { + console.error('输入必须是字符串') + return null + } + // 正则:匹配所有连续的URL编码片段(%XX格式,至少1个,支持多字节字符如%E7%83%AD) + const urlEncodeRegex = /%[0-9A-Fa-f]{2}/gi + // 拆分为非编码部分和编码部分 + const parts = str.split(urlEncodeRegex) // 非编码部分(数组) + const encodedParts = str.match(urlEncodeRegex) || [] // 编码部分(数组) + + let decoded = '' + for (let i = 0; i < parts.length; i++) { + decoded += parts[i] // 添加非编码部分 + if (encodedParts[i]) { + // 处理连续的编码片段(如%E7%83%AD是3个%XX,需合并为完整编码) + let currentEncoded = encodedParts[i] + // 检查下一个编码是否属于同一字符(UTF-8多字节字符可能由多个%XX组成) + // 这里简单合并相邻的编码片段(实际需根据编码规则严格处理,此处简化) + while (encodedParts[i + 1] && encodedParts[i + 1].startsWith('%')) { + currentEncoded += encodedParts[i + 1] + i++ // 跳过已处理的编码 + } + try { + decoded += decodeURIComponent(currentEncoded) // 解码合并后的编码 + } + catch (error) { + console.warn('部分编码解码失败,保留原始片段:', currentEncoded) + decoded += currentEncoded // 解码失败时保留原编码 + } + } + } + return decoded +} + // excel初始化完成 const ExcelEditInitComplete = async (spread: any) => { const params = solveParams() @@ -883,26 +962,37 @@ text: '模板自动导入中,请稍后!', background: 'rgba(255, 255, 255, 0.8)', }) - console.log('---------------------------------') - console.log(params) + downLoadTemplate(params).then((res) => { + if (res.data) { + // 获取文件类型 + const contentDisposition = res.headers.get('Content-Disposition') + excelEditFileName.value = decodePartialUrlEncoded(contentDisposition.slice(contentDisposition.indexOf('=') + 1))! + console.log('文件名称:', excelEditFileName.value) + const match = contentDisposition.match(/\.([^.]+)$/) + const fileType = `${match[1]}` + if (fileType === 'xlsx') { + console.log('获取到模板文件') + loading.close() + excelEditRef.value.handleImportFile(res.data, form.value, fileType) + } + else { + console.log('获取到模板文件') + ElMessage.warning('仅支持自动导入xslx文件,若为xls请转换xlsx,其他类型请手动导入') + } + } + else { + console.log('未获取到模板文件') + } + }).catch(() => { + loading.close() + }) - // downLoadTemplate(params).then((res) => { - // if (res.data) { - // loading.close() - // excelEditRef.value.handleImportFile(res.data, form) - // } - // else { - // console.log('未获取到模板文件') - // } - // }).catch(() => { + // ==================练习测试================== + // const res = await getPhotoUrl(form.value.certificateReportFile) + // const certUrl = await fetch(res.data) + // const file = await certUrl.blob() + // excelEditRef.value.handleImportFile(file, form.value, 'xlsm') // loading.close() - // }) - const res = await getPhotoUrl(form.value.certificateReportFile) - const certUrl = await fetch(res.data) - const file = await certUrl.blob() - excelEditRef.value.handleImportFile(file, form.value) - loading.close() - // importFile(spread, file) } // 监听到驳回原因 @@ -1466,7 +1556,8 @@ - + + diff --git a/src/views/system/tool/certTempate/addDDialog.vue b/src/views/system/tool/certTempate/addDDialog.vue index 7718e76..ff3ea5d 100644 --- a/src/views/system/tool/certTempate/addDDialog.vue +++ b/src/views/system/tool/certTempate/addDDialog.vue @@ -4,13 +4,17 @@ import { ElLoading, ElMessage } from 'element-plus' import dayjs from 'dayjs' import showPhoto from '../showPhoto.vue' +import { UploadFile } from '@/api/measure/file' import { uploadApi } from '@/api/system/notice' import useUserStore from '@/store/modules/user' -import { templateAdd, templateUpdate } from '@/api/system/tool' +import { getPhotoUrl, listPageApi, templateAdd, templateUpdate } from '@/api/system/tool' +import ExcelEdit from '@/views/business/lab/excelEdit/excelEditDialog.vue' import { getDictByCode } from '@/api/system/dict' import type { dictType } from '@/global' // 用户信息 -const emits = defineEmits(['resetData']); const user = useUserStore() +const emits = defineEmits(['resetData']) +const { proxy } = getCurrentInstance() as any +const user = useUserStore() const ruleFormRef = ref() // from组件 const ruleForm = reactive({ templateNo: '', // 模板编号 @@ -137,11 +141,79 @@ const upload = () => { fileRef.value.click() } + +// ------------------------------------excel在线编辑-------------------------------------- +const excelEditFileName = ref('') // 进行excel编辑的文件名称 +const excelEditRef = ref() +// 点击ExcelEdit在线编辑按钮,打开ExcelEdit在线编辑工具 +const handleClickExcelEdit = () => { + excelEditRef.value.initDialog() +} + +function getFileExtension(fileName: string) { + // 去除前后空格(可选) + fileName = fileName.trim() + // 找到最后一个点的索引 + const dotIndex = fileName.lastIndexOf('.') + // 若存在点,且点不在第一个字符,且点后有内容 + if (dotIndex > 0 && dotIndex < fileName.length - 1) { + return fileName.slice(dotIndex + 1).toLowerCase() // 转小写(可选) + } + return '' // 无后缀 +} + +// excel初始化完成 +const ExcelEditInitComplete = async () => { + excelEditFileName.value = ruleForm.minioFileName + if (ruleForm.minioFileName) { + const loading = ElLoading.service({ + lock: true, + text: '模板自动导入中,请稍后!', + background: 'rgba(255, 255, 255, 0.8)', + }) + const res = await getPhotoUrl(ruleForm.minioFileName) + const certUrl = await fetch(res.data) + const file = await certUrl.blob() + excelEditRef.value.handleImportFile(file, ruleForm, getFileExtension(ruleForm.minioFileName)) + loading.close() + } +} + +// excel在线编辑完成自动上传证书 +const handleImportFile = (blob: Blob) => { + const file = new File([blob], excelEditFileName.value, { + type: blob.type, + lastModified: new Date().getTime(), + }) + // 创建formdata对象 + const fd = new FormData() + fd.append('multipartFile', file) + const loading = ElLoading.service({ + lock: true, + background: 'rgba(255, 255, 255, 0.8)', + }) + UploadFile(fd).then((res) => { + if (res.code === 200) { + ruleForm.minioFileName = res.data[0] + loading.close() + } + else { + ElMessage.error(res.message) + loading.close() + } + }).catch((e) => { + ElMessage.error('上传失败,请联系管理员') + console.log('上传文件失败:', e) + loading.close() + }) +} + +// ------------------------------------------------------------------------------------ defineExpose({ initDialog }) + + diff --git a/src/views/business/lab/excelEdit/methods/file.ts b/src/views/business/lab/excelEdit/methods/file.ts index 312ee55..4aae1d6 100644 --- a/src/views/business/lab/excelEdit/methods/file.ts +++ b/src/views/business/lab/excelEdit/methods/file.ts @@ -16,12 +16,15 @@ * @returns */ export function getFileType(file: Blob) { + console.log('getFileType: ', file) if (!file) { return } if (!isBlob(file)) { + console.log('不是blob文件', file) return } + console.log('是blob文件:', file, '文件类型为', file.type) const extensionName = file.type if (extensionName === 'sjs') { return FileType.SJS @@ -45,14 +48,18 @@ return file instanceof Blob } -/** +/** * @param spread spread实例 * @param file 文件 + * @param fileTypeParam 文件类型 * @returns */ -export async function importFile(spread: any, file: Blob) { - const fileType = getFileType(file) - console.log('获取到的文件类型', fileType, fileType === FileType.SJS) +export async function importFile(spread: any, file: Blob, fileTypeParam = '') { + let fileType = fileTypeParam! + if (!fileTypeParam) { + fileType = getFileType(file)! + } + console.log('获取到的文件类型', fileTypeParam, fileType) return new Promise((resolve) => { if (fileType === FileType.SJS) { @@ -68,6 +75,8 @@ ) } else { + const type + = fileType === 'xlsx' ? 'excel' : fileType === 'ssjson' ? 'ssjson' : 'csv' spread.import( file, () => { @@ -77,6 +86,9 @@ (e: any) => { console.log('importFile-import:上传文件发生错误', e) }, + { + fileType: fileType === 'xlsm' ? null : GC.Spread.Sheets.FileType[type], + }, ) } }) diff --git a/src/views/business/lab/excelEdit/templateFiles/calibrationCert.sjs b/src/views/business/lab/excelEdit/templateFiles/calibrationCert.sjs deleted file mode 100644 index e395d36..0000000 --- a/src/views/business/lab/excelEdit/templateFiles/calibrationCert.sjs +++ /dev/null Binary files differ diff --git a/src/views/business/lab/measureData/measureDataDetail.vue b/src/views/business/lab/measureData/measureDataDetail.vue index 0ee7c70..e7dffb3 100644 --- a/src/views/business/lab/measureData/measureDataDetail.vue +++ b/src/views/business/lab/measureData/measureDataDetail.vue @@ -235,7 +235,8 @@ // ---------------------------------文件上传(上传证书)------------------------------------------- const fileRef = ref() -const onFileChange = (event: any) => { +const excelEditFileName = ref('') // 进行excel编辑的文件名称 +const onFileChange = (event: any, blob: Blob) => { // 原生上传 if (event.target.files?.length !== 0) { // 创建formdata对象 @@ -273,6 +274,47 @@ fileRef.value.click() } +// excel在线编辑完成自动上传证书 +const handleImportFile = (blob: Blob) => { + const file = new File([blob], excelEditFileName.value, { + type: blob.type, + lastModified: new Date().getTime(), + }) + // 创建formdata对象 + const fd = new FormData() + fd.append('multipartFile', file) + const loading = ElLoading.service({ + lock: true, + background: 'rgba(255, 255, 255, 0.8)', + }) + UploadFile(fd).then((res) => { + if (res.code === 200) { + form.value.certificateReportFile = res.data[0] + loading.close() + ElMessageBox.confirm( + '文件上传成功,是否保存上传的文件?', + '提示', + { + confirmButtonText: '是', + cancelButtonText: '否', + type: 'warning', + }, + ) + .then(() => { + handleSave('saveUploadFile') + }) + } + else { + ElMessage.error(res.message) + loading.close() + } + }).catch((e) => { + ElMessage.error('上传失败,请联系管理员') + console.log('上传文件失败:', e) + loading.close() + }) +} + // ----------------------------------------------样品-------------------------------------------- const selectOrderSamplesDialogRef = ref() // 选择委托书下的样品清单组件ref const selectMyMeasureDialogRef = ref() // 选择我的检测下的样品ref @@ -875,6 +917,43 @@ const handleClickExcelEdit = () => { excelEditRef.value.initDialog() } + +// 解码 +function decodePartialUrlEncoded(str: string) { + if (typeof str !== 'string') { + console.error('输入必须是字符串') + return null + } + // 正则:匹配所有连续的URL编码片段(%XX格式,至少1个,支持多字节字符如%E7%83%AD) + const urlEncodeRegex = /%[0-9A-Fa-f]{2}/gi + // 拆分为非编码部分和编码部分 + const parts = str.split(urlEncodeRegex) // 非编码部分(数组) + const encodedParts = str.match(urlEncodeRegex) || [] // 编码部分(数组) + + let decoded = '' + for (let i = 0; i < parts.length; i++) { + decoded += parts[i] // 添加非编码部分 + if (encodedParts[i]) { + // 处理连续的编码片段(如%E7%83%AD是3个%XX,需合并为完整编码) + let currentEncoded = encodedParts[i] + // 检查下一个编码是否属于同一字符(UTF-8多字节字符可能由多个%XX组成) + // 这里简单合并相邻的编码片段(实际需根据编码规则严格处理,此处简化) + while (encodedParts[i + 1] && encodedParts[i + 1].startsWith('%')) { + currentEncoded += encodedParts[i + 1] + i++ // 跳过已处理的编码 + } + try { + decoded += decodeURIComponent(currentEncoded) // 解码合并后的编码 + } + catch (error) { + console.warn('部分编码解码失败,保留原始片段:', currentEncoded) + decoded += currentEncoded // 解码失败时保留原编码 + } + } + } + return decoded +} + // excel初始化完成 const ExcelEditInitComplete = async (spread: any) => { const params = solveParams() @@ -883,26 +962,37 @@ text: '模板自动导入中,请稍后!', background: 'rgba(255, 255, 255, 0.8)', }) - console.log('---------------------------------') - console.log(params) + downLoadTemplate(params).then((res) => { + if (res.data) { + // 获取文件类型 + const contentDisposition = res.headers.get('Content-Disposition') + excelEditFileName.value = decodePartialUrlEncoded(contentDisposition.slice(contentDisposition.indexOf('=') + 1))! + console.log('文件名称:', excelEditFileName.value) + const match = contentDisposition.match(/\.([^.]+)$/) + const fileType = `${match[1]}` + if (fileType === 'xlsx') { + console.log('获取到模板文件') + loading.close() + excelEditRef.value.handleImportFile(res.data, form.value, fileType) + } + else { + console.log('获取到模板文件') + ElMessage.warning('仅支持自动导入xslx文件,若为xls请转换xlsx,其他类型请手动导入') + } + } + else { + console.log('未获取到模板文件') + } + }).catch(() => { + loading.close() + }) - // downLoadTemplate(params).then((res) => { - // if (res.data) { - // loading.close() - // excelEditRef.value.handleImportFile(res.data, form) - // } - // else { - // console.log('未获取到模板文件') - // } - // }).catch(() => { + // ==================练习测试================== + // const res = await getPhotoUrl(form.value.certificateReportFile) + // const certUrl = await fetch(res.data) + // const file = await certUrl.blob() + // excelEditRef.value.handleImportFile(file, form.value, 'xlsm') // loading.close() - // }) - const res = await getPhotoUrl(form.value.certificateReportFile) - const certUrl = await fetch(res.data) - const file = await certUrl.blob() - excelEditRef.value.handleImportFile(file, form.value) - loading.close() - // importFile(spread, file) } // 监听到驳回原因 @@ -1466,7 +1556,8 @@ - + + diff --git a/src/views/system/tool/certTempate/addDDialog.vue b/src/views/system/tool/certTempate/addDDialog.vue index 7718e76..ff3ea5d 100644 --- a/src/views/system/tool/certTempate/addDDialog.vue +++ b/src/views/system/tool/certTempate/addDDialog.vue @@ -4,13 +4,17 @@ import { ElLoading, ElMessage } from 'element-plus' import dayjs from 'dayjs' import showPhoto from '../showPhoto.vue' +import { UploadFile } from '@/api/measure/file' import { uploadApi } from '@/api/system/notice' import useUserStore from '@/store/modules/user' -import { templateAdd, templateUpdate } from '@/api/system/tool' +import { getPhotoUrl, listPageApi, templateAdd, templateUpdate } from '@/api/system/tool' +import ExcelEdit from '@/views/business/lab/excelEdit/excelEditDialog.vue' import { getDictByCode } from '@/api/system/dict' import type { dictType } from '@/global' // 用户信息 -const emits = defineEmits(['resetData']); const user = useUserStore() +const emits = defineEmits(['resetData']) +const { proxy } = getCurrentInstance() as any +const user = useUserStore() const ruleFormRef = ref() // from组件 const ruleForm = reactive({ templateNo: '', // 模板编号 @@ -137,11 +141,79 @@ const upload = () => { fileRef.value.click() } + +// ------------------------------------excel在线编辑-------------------------------------- +const excelEditFileName = ref('') // 进行excel编辑的文件名称 +const excelEditRef = ref() +// 点击ExcelEdit在线编辑按钮,打开ExcelEdit在线编辑工具 +const handleClickExcelEdit = () => { + excelEditRef.value.initDialog() +} + +function getFileExtension(fileName: string) { + // 去除前后空格(可选) + fileName = fileName.trim() + // 找到最后一个点的索引 + const dotIndex = fileName.lastIndexOf('.') + // 若存在点,且点不在第一个字符,且点后有内容 + if (dotIndex > 0 && dotIndex < fileName.length - 1) { + return fileName.slice(dotIndex + 1).toLowerCase() // 转小写(可选) + } + return '' // 无后缀 +} + +// excel初始化完成 +const ExcelEditInitComplete = async () => { + excelEditFileName.value = ruleForm.minioFileName + if (ruleForm.minioFileName) { + const loading = ElLoading.service({ + lock: true, + text: '模板自动导入中,请稍后!', + background: 'rgba(255, 255, 255, 0.8)', + }) + const res = await getPhotoUrl(ruleForm.minioFileName) + const certUrl = await fetch(res.data) + const file = await certUrl.blob() + excelEditRef.value.handleImportFile(file, ruleForm, getFileExtension(ruleForm.minioFileName)) + loading.close() + } +} + +// excel在线编辑完成自动上传证书 +const handleImportFile = (blob: Blob) => { + const file = new File([blob], excelEditFileName.value, { + type: blob.type, + lastModified: new Date().getTime(), + }) + // 创建formdata对象 + const fd = new FormData() + fd.append('multipartFile', file) + const loading = ElLoading.service({ + lock: true, + background: 'rgba(255, 255, 255, 0.8)', + }) + UploadFile(fd).then((res) => { + if (res.code === 200) { + ruleForm.minioFileName = res.data[0] + loading.close() + } + else { + ElMessage.error(res.message) + loading.close() + } + }).catch((e) => { + ElMessage.error('上传失败,请联系管理员') + console.log('上传文件失败:', e) + loading.close() + }) +} + +// ------------------------------------------------------------------------------------ defineExpose({ initDialog }) + + diff --git a/src/views/business/lab/excelEdit/methods/file.ts b/src/views/business/lab/excelEdit/methods/file.ts index 312ee55..4aae1d6 100644 --- a/src/views/business/lab/excelEdit/methods/file.ts +++ b/src/views/business/lab/excelEdit/methods/file.ts @@ -16,12 +16,15 @@ * @returns */ export function getFileType(file: Blob) { + console.log('getFileType: ', file) if (!file) { return } if (!isBlob(file)) { + console.log('不是blob文件', file) return } + console.log('是blob文件:', file, '文件类型为', file.type) const extensionName = file.type if (extensionName === 'sjs') { return FileType.SJS @@ -45,14 +48,18 @@ return file instanceof Blob } -/** +/** * @param spread spread实例 * @param file 文件 + * @param fileTypeParam 文件类型 * @returns */ -export async function importFile(spread: any, file: Blob) { - const fileType = getFileType(file) - console.log('获取到的文件类型', fileType, fileType === FileType.SJS) +export async function importFile(spread: any, file: Blob, fileTypeParam = '') { + let fileType = fileTypeParam! + if (!fileTypeParam) { + fileType = getFileType(file)! + } + console.log('获取到的文件类型', fileTypeParam, fileType) return new Promise((resolve) => { if (fileType === FileType.SJS) { @@ -68,6 +75,8 @@ ) } else { + const type + = fileType === 'xlsx' ? 'excel' : fileType === 'ssjson' ? 'ssjson' : 'csv' spread.import( file, () => { @@ -77,6 +86,9 @@ (e: any) => { console.log('importFile-import:上传文件发生错误', e) }, + { + fileType: fileType === 'xlsm' ? null : GC.Spread.Sheets.FileType[type], + }, ) } }) diff --git a/src/views/business/lab/excelEdit/templateFiles/calibrationCert.sjs b/src/views/business/lab/excelEdit/templateFiles/calibrationCert.sjs deleted file mode 100644 index e395d36..0000000 --- a/src/views/business/lab/excelEdit/templateFiles/calibrationCert.sjs +++ /dev/null Binary files differ diff --git a/src/views/business/lab/measureData/measureDataDetail.vue b/src/views/business/lab/measureData/measureDataDetail.vue index 0ee7c70..e7dffb3 100644 --- a/src/views/business/lab/measureData/measureDataDetail.vue +++ b/src/views/business/lab/measureData/measureDataDetail.vue @@ -235,7 +235,8 @@ // ---------------------------------文件上传(上传证书)------------------------------------------- const fileRef = ref() -const onFileChange = (event: any) => { +const excelEditFileName = ref('') // 进行excel编辑的文件名称 +const onFileChange = (event: any, blob: Blob) => { // 原生上传 if (event.target.files?.length !== 0) { // 创建formdata对象 @@ -273,6 +274,47 @@ fileRef.value.click() } +// excel在线编辑完成自动上传证书 +const handleImportFile = (blob: Blob) => { + const file = new File([blob], excelEditFileName.value, { + type: blob.type, + lastModified: new Date().getTime(), + }) + // 创建formdata对象 + const fd = new FormData() + fd.append('multipartFile', file) + const loading = ElLoading.service({ + lock: true, + background: 'rgba(255, 255, 255, 0.8)', + }) + UploadFile(fd).then((res) => { + if (res.code === 200) { + form.value.certificateReportFile = res.data[0] + loading.close() + ElMessageBox.confirm( + '文件上传成功,是否保存上传的文件?', + '提示', + { + confirmButtonText: '是', + cancelButtonText: '否', + type: 'warning', + }, + ) + .then(() => { + handleSave('saveUploadFile') + }) + } + else { + ElMessage.error(res.message) + loading.close() + } + }).catch((e) => { + ElMessage.error('上传失败,请联系管理员') + console.log('上传文件失败:', e) + loading.close() + }) +} + // ----------------------------------------------样品-------------------------------------------- const selectOrderSamplesDialogRef = ref() // 选择委托书下的样品清单组件ref const selectMyMeasureDialogRef = ref() // 选择我的检测下的样品ref @@ -875,6 +917,43 @@ const handleClickExcelEdit = () => { excelEditRef.value.initDialog() } + +// 解码 +function decodePartialUrlEncoded(str: string) { + if (typeof str !== 'string') { + console.error('输入必须是字符串') + return null + } + // 正则:匹配所有连续的URL编码片段(%XX格式,至少1个,支持多字节字符如%E7%83%AD) + const urlEncodeRegex = /%[0-9A-Fa-f]{2}/gi + // 拆分为非编码部分和编码部分 + const parts = str.split(urlEncodeRegex) // 非编码部分(数组) + const encodedParts = str.match(urlEncodeRegex) || [] // 编码部分(数组) + + let decoded = '' + for (let i = 0; i < parts.length; i++) { + decoded += parts[i] // 添加非编码部分 + if (encodedParts[i]) { + // 处理连续的编码片段(如%E7%83%AD是3个%XX,需合并为完整编码) + let currentEncoded = encodedParts[i] + // 检查下一个编码是否属于同一字符(UTF-8多字节字符可能由多个%XX组成) + // 这里简单合并相邻的编码片段(实际需根据编码规则严格处理,此处简化) + while (encodedParts[i + 1] && encodedParts[i + 1].startsWith('%')) { + currentEncoded += encodedParts[i + 1] + i++ // 跳过已处理的编码 + } + try { + decoded += decodeURIComponent(currentEncoded) // 解码合并后的编码 + } + catch (error) { + console.warn('部分编码解码失败,保留原始片段:', currentEncoded) + decoded += currentEncoded // 解码失败时保留原编码 + } + } + } + return decoded +} + // excel初始化完成 const ExcelEditInitComplete = async (spread: any) => { const params = solveParams() @@ -883,26 +962,37 @@ text: '模板自动导入中,请稍后!', background: 'rgba(255, 255, 255, 0.8)', }) - console.log('---------------------------------') - console.log(params) + downLoadTemplate(params).then((res) => { + if (res.data) { + // 获取文件类型 + const contentDisposition = res.headers.get('Content-Disposition') + excelEditFileName.value = decodePartialUrlEncoded(contentDisposition.slice(contentDisposition.indexOf('=') + 1))! + console.log('文件名称:', excelEditFileName.value) + const match = contentDisposition.match(/\.([^.]+)$/) + const fileType = `${match[1]}` + if (fileType === 'xlsx') { + console.log('获取到模板文件') + loading.close() + excelEditRef.value.handleImportFile(res.data, form.value, fileType) + } + else { + console.log('获取到模板文件') + ElMessage.warning('仅支持自动导入xslx文件,若为xls请转换xlsx,其他类型请手动导入') + } + } + else { + console.log('未获取到模板文件') + } + }).catch(() => { + loading.close() + }) - // downLoadTemplate(params).then((res) => { - // if (res.data) { - // loading.close() - // excelEditRef.value.handleImportFile(res.data, form) - // } - // else { - // console.log('未获取到模板文件') - // } - // }).catch(() => { + // ==================练习测试================== + // const res = await getPhotoUrl(form.value.certificateReportFile) + // const certUrl = await fetch(res.data) + // const file = await certUrl.blob() + // excelEditRef.value.handleImportFile(file, form.value, 'xlsm') // loading.close() - // }) - const res = await getPhotoUrl(form.value.certificateReportFile) - const certUrl = await fetch(res.data) - const file = await certUrl.blob() - excelEditRef.value.handleImportFile(file, form.value) - loading.close() - // importFile(spread, file) } // 监听到驳回原因 @@ -1466,7 +1556,8 @@ - + + diff --git a/src/views/system/tool/certTempate/addDDialog.vue b/src/views/system/tool/certTempate/addDDialog.vue index 7718e76..ff3ea5d 100644 --- a/src/views/system/tool/certTempate/addDDialog.vue +++ b/src/views/system/tool/certTempate/addDDialog.vue @@ -4,13 +4,17 @@ import { ElLoading, ElMessage } from 'element-plus' import dayjs from 'dayjs' import showPhoto from '../showPhoto.vue' +import { UploadFile } from '@/api/measure/file' import { uploadApi } from '@/api/system/notice' import useUserStore from '@/store/modules/user' -import { templateAdd, templateUpdate } from '@/api/system/tool' +import { getPhotoUrl, listPageApi, templateAdd, templateUpdate } from '@/api/system/tool' +import ExcelEdit from '@/views/business/lab/excelEdit/excelEditDialog.vue' import { getDictByCode } from '@/api/system/dict' import type { dictType } from '@/global' // 用户信息 -const emits = defineEmits(['resetData']); const user = useUserStore() +const emits = defineEmits(['resetData']) +const { proxy } = getCurrentInstance() as any +const user = useUserStore() const ruleFormRef = ref() // from组件 const ruleForm = reactive({ templateNo: '', // 模板编号 @@ -137,11 +141,79 @@ const upload = () => { fileRef.value.click() } + +// ------------------------------------excel在线编辑-------------------------------------- +const excelEditFileName = ref('') // 进行excel编辑的文件名称 +const excelEditRef = ref() +// 点击ExcelEdit在线编辑按钮,打开ExcelEdit在线编辑工具 +const handleClickExcelEdit = () => { + excelEditRef.value.initDialog() +} + +function getFileExtension(fileName: string) { + // 去除前后空格(可选) + fileName = fileName.trim() + // 找到最后一个点的索引 + const dotIndex = fileName.lastIndexOf('.') + // 若存在点,且点不在第一个字符,且点后有内容 + if (dotIndex > 0 && dotIndex < fileName.length - 1) { + return fileName.slice(dotIndex + 1).toLowerCase() // 转小写(可选) + } + return '' // 无后缀 +} + +// excel初始化完成 +const ExcelEditInitComplete = async () => { + excelEditFileName.value = ruleForm.minioFileName + if (ruleForm.minioFileName) { + const loading = ElLoading.service({ + lock: true, + text: '模板自动导入中,请稍后!', + background: 'rgba(255, 255, 255, 0.8)', + }) + const res = await getPhotoUrl(ruleForm.minioFileName) + const certUrl = await fetch(res.data) + const file = await certUrl.blob() + excelEditRef.value.handleImportFile(file, ruleForm, getFileExtension(ruleForm.minioFileName)) + loading.close() + } +} + +// excel在线编辑完成自动上传证书 +const handleImportFile = (blob: Blob) => { + const file = new File([blob], excelEditFileName.value, { + type: blob.type, + lastModified: new Date().getTime(), + }) + // 创建formdata对象 + const fd = new FormData() + fd.append('multipartFile', file) + const loading = ElLoading.service({ + lock: true, + background: 'rgba(255, 255, 255, 0.8)', + }) + UploadFile(fd).then((res) => { + if (res.code === 200) { + ruleForm.minioFileName = res.data[0] + loading.close() + } + else { + ElMessage.error(res.message) + loading.close() + } + }).catch((e) => { + ElMessage.error('上传失败,请联系管理员') + console.log('上传文件失败:', e) + loading.close() + }) +} + +// ------------------------------------------------------------------------------------ defineExpose({ initDialog }) + +