| | |
| | | <el-table-column label="序号" type="index" align="center" width="80"/> |
| | | <el-table-column label="质量手册" prop="fileName" align="center"> |
| | | <template #default="scope"> |
| | | <el-button link type="primary" @click="initFile(scope.row)">{{scope.row.companyName + scope.row.qualityName + '.docx'}}</el-button> |
| | | <el-button link type="primary" @click="initFile(scope.row)"> |
| | | {{ scope.row.companyName + scope.row.qualityName + '.docx' }} |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> |
| | | <template #default="scope"> |
| | | <el-button link type="primary" @click="initFile(scope.row)" v-hasPermi="['qualityManage2:list:edit']">下载</el-button> |
| | | <el-button link type="primary" @click="openDialog('add',scope.row)" v-hasPermi="['qualityManage2:list:add']">上传</el-button> |
| | | <el-button link type="danger" @click="handleDelete(scope.row)" v-hasPermi="['qualityManage2:list:del']">删除</el-button> |
| | | <el-button link type="primary" @click="initFile(scope.row)" v-hasPermi="['qualityManage2:list:edit']">下载 |
| | | </el-button> |
| | | <el-button link type="primary" @click="openDialog('add',scope.row)" v-hasPermi="['qualityManage2:list:add']"> |
| | | 上传 |
| | | </el-button> |
| | | <el-button link type="danger" @click="handleDelete(scope.row)" v-hasPermi="['qualityManage2:list:del']">删除 |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | |
| | | @pagination="getList" |
| | | /> |
| | | <edit-dialog ref="dialogRef" @getList=getList></edit-dialog> |
| | | <el-dialog |
| | | v-model="dialogVisible" |
| | | width="750px" |
| | | :before-close="handleClose" |
| | | :close-on-press-escape="false" |
| | | :close-on-click-modal="false" |
| | | > |
| | | <el-form :model="dialogForm" size="default" ref="formRef" :rules="formRules" label-width="150px"> |
| | | <el-form-item label="编号:" prop="number"> |
| | | <el-input v-model.trim="dialogForm.number" placeholder="手册编号"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="版本号:" prop="versionNum"> |
| | | <el-input v-model.trim="dialogForm.versionNum" placeholder="版本号"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="文件状态:" prop="fileStatus"> |
| | | <el-input v-model.trim="dialogForm.fileStatus" placeholder="文件状态"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="发布号:" prop="grantNum"> |
| | | <el-input v-model.trim="dialogForm.grantNum" placeholder="发布号"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="编制:" prop="fictionName"> |
| | | <el-select clearable v-model="dialogForm.fictionName" filterable placeholder="编制" style="width: 100%"> |
| | | <el-option |
| | | v-for="item in userList" |
| | | :key="item.name" |
| | | :label="item.name" |
| | | :value="item.name" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="审核:" prop="checkName"> |
| | | <el-select clearable v-model="dialogForm.checkName" filterable placeholder="审核" style="width: 100%"> |
| | | <el-option |
| | | v-for="item in userList" |
| | | :key="item.name" |
| | | :label="item.name" |
| | | :value="item.name" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="批准:" prop="ratifyName"> |
| | | <el-select clearable v-model="dialogForm.ratifyName" filterable placeholder="批准" style="width: 100%"> |
| | | <el-option |
| | | v-for="item in userList" |
| | | :key="item.name" |
| | | :label="item.name" |
| | | :value="item.name" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="发布日期:" prop="releaseDate"> |
| | | <el-date-picker |
| | | v-model="dialogForm.releaseDate" |
| | | type="date" |
| | | placeholder="请选择日期" |
| | | value-format="YYYY-MM-DD" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="实施日期:" prop="executionDate"> |
| | | <el-date-picker |
| | | v-model="dialogForm.executionDate" |
| | | type="date" |
| | | placeholder="请选择日期" |
| | | value-format="YYYY-MM-DD" |
| | | /> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button @click="handleClose" size="default">取 消</el-button> |
| | | <el-button type="primary" @click="onSubmitAdd" size="default" v-preReClick>确认</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | |
| | | getStandardQuality |
| | | } from "@/api/standardSys/standardSys"; |
| | | import {getDepart, getDistribution, getFunctionalRemarkList, getSysClause} from "@/api/orgStructure/depart"; |
| | | import {getEmployeeRecords} from "@/api/onlineEducation/user"; |
| | | |
| | | const userStore = useUserStore() |
| | | const { proxy } = getCurrentInstance(); |
| | |
| | | isAdmin: false, |
| | | companyInfo: {}, |
| | | caluseList: [], |
| | | originDeptList: [] |
| | | originDeptList: [], |
| | | dialogVisible: false, |
| | | dialogForm: { |
| | | qualityName: '质量手册', |
| | | companyId: null, |
| | | number: '', |
| | | versionNum: '', |
| | | fileStatus: '', |
| | | grantNum: '', |
| | | fictionName: '', |
| | | checkName: '', |
| | | ratifyName: '', |
| | | releaseDate: '', |
| | | executionDate: '' |
| | | }, |
| | | formRules: {}, |
| | | userList: [] |
| | | }); |
| | | |
| | | const { queryParams, total, dataList,deptList,treeProps,tools,labelStyle,companyList, isAdmin, companyInfo, caluseList } = toRefs(data); |
| | | const { |
| | | queryParams, |
| | | total, |
| | | dataList, |
| | | deptList, |
| | | treeProps, |
| | | tools, |
| | | labelStyle, |
| | | companyList, |
| | | isAdmin, |
| | | companyInfo, |
| | | caluseList, |
| | | dialogVisible, |
| | | dialogForm, |
| | | formRules, |
| | | userList |
| | | } = toRefs(data); |
| | | const userInfo = ref() |
| | | const formRef = ref() |
| | | onMounted(async ()=>{ |
| | | await getSysClauseList() |
| | | if(userStore.roles.includes('admin')){ |
| | |
| | | onUnmounted(()=>{ |
| | | |
| | | }) |
| | | const handleClose = () => { |
| | | data.dialogForm = { |
| | | qualityName: '质量手册', |
| | | companyId: null, |
| | | number: '', |
| | | versionNum: '', |
| | | fileStatus: '', |
| | | grantNum: '', |
| | | fictionName: '', |
| | | checkName: '', |
| | | ratifyName: '', |
| | | releaseDate: '', |
| | | executionDate: '' |
| | | } |
| | | data.dialogVisible = false |
| | | } |
| | | |
| | | const onSubmitAdd = async () => { |
| | | const valid = await formRef.value.validate() |
| | | if (valid) { |
| | | const res = await addStandardQuality(data.dialogForm) |
| | | if (res.code == 200) { |
| | | ElMessage.success(res.message) |
| | | await handleClose() |
| | | await reset() |
| | | } else { |
| | | ElMessage.warning(res.message) |
| | | } |
| | | } |
| | | } |
| | | |
| | | const getSysClauseList = async ()=> { |
| | | const res = await getSysClause() |
| | |
| | | ElMessage.warning(res.message) |
| | | } |
| | | } |
| | | |
| | | const getUserList = async (companyId)=> { |
| | | const res = await getEmployeeRecords({companyId: companyId}) |
| | | if(res.code == 200){ |
| | | data.userList = res.data ? res.data :[] |
| | | }else{ |
| | | ElMessage.warning(res.message) |
| | | } |
| | | } |
| | | const getList = async () => { |
| | | loading.value = true |
| | | const res = await getStandardQuality(data.queryParams) |
| | |
| | | } |
| | | } |
| | | const addFile = async ()=>{ |
| | | let params={} |
| | | if(data.queryParams.companyId){ |
| | | params = { |
| | | qualityName: '质量手册', |
| | | companyId: data.queryParams.companyId |
| | | data.dialogForm.companyId = data.queryParams.companyId |
| | | const res = await getStandardQuality(data.queryParams) |
| | | if (res.code == 200) { |
| | | const val = res.data.data[0] |
| | | Object.keys(data.dialogForm).forEach(key => { |
| | | if (key in val) { |
| | | data.dialogForm[key] = val[key] |
| | | } |
| | | }) |
| | | } else { |
| | | ElMessage.warning(res.message) |
| | | } |
| | | await getUserList(data.queryParams.companyId) |
| | | data.dialogVisible = true |
| | | }else{ |
| | | ElMessage.warning('请先选择对应的企业') |
| | | return |
| | | } |
| | | const res = await addStandardQuality(params) |
| | | if(res.code == 200){ |
| | | ElMessage.success(res.message) |
| | | await getList() |
| | | }else{ |
| | | ElMessage.warning(res.message) |
| | | } |
| | | } |
| | | |
| | |
| | | const getInfo = async (val) => { |
| | | const res = await getStandardDetail({companyId: val.companyId}); |
| | | if(res.code === 200){ |
| | | |
| | | // 调试 proclaim 数据 |
| | | if(!res.data || (res.data.companyIndustryTemplates.length == 0 && res.data.companyQualityPolicies.length == 0 && res.data.companySummaries.length == 0 && res.data.sysFunctionalDistributions |
| | | .length == 0 && res.data.treeSelects.length == 0)){ |
| | | loading.value = false |
| | |
| | | } |
| | | }) || [] |
| | | data.companyInfo.productServiceImages = res.data.productServiceDatas ? await processImagesToBase64(res.data.productServiceDatas): [] |
| | | data.companyInfo.proclaim1 = res.data.proclaim.find(i=>i.type == 1)?.content || '' |
| | | data.companyInfo.sign1 = await urlToBase64(res.data.proclaim.find(i=>i.type == 1)?.sign) || '' |
| | | data.companyInfo.updateTime1 = res.data.proclaim.find(i=>i.type == 1 && i.status == 1)?.updateTime?.substring(0,10) || '' |
| | | data.companyInfo.proclaim2 = res.data.proclaim.find(i=>i.type == 2)?.content || '' |
| | | data.companyInfo.sign2 = await urlToBase64(res.data.proclaim.find(i=>i.type == 2)?.sign) || '' |
| | | data.companyInfo.updateTime2 = res.data.proclaim.find(i=>i.type == 2 && i.status == 1)?.updateTime?.substring(0,10) || '' |
| | | data.companyInfo.proclaim3 = res.data.proclaim.find(i=>i.type == 3)?.content || '' |
| | | data.companyInfo.sign3 = await urlToBase64(res.data.proclaim.find(i=>i.type == 3)?.sign) || '' |
| | | data.companyInfo.updateTime3 = res.data.proclaim.find(i=>i.type == 3 && i.status == 1)?.updateTime?.substring(0,10) || '' |
| | | data.companyInfo.proclaim4 = res.data.proclaim.find(i=>i.type == 4)?.content || '' |
| | | data.companyInfo.sign4 = await urlToBase64(res.data.proclaim.find(i=>i.type == 4)?.sign) || '' |
| | | data.companyInfo.updateTime4 = res.data.proclaim.find(i=>i.type == 4 && i.status == 1)?.updateTime?.substring(0,10) || '' |
| | | }else{ |
| | | ElMessage.warning(res.message) |
| | | } |
| | |
| | | |
| | | // 新增:将图片URL转换为Base64 |
| | | async function urlToBase64(imageUrl) { |
| | | if (!imageUrl || imageUrl.trim() === '') { |
| | | console.log('urlToBase64: 接收到空URL'); |
| | | return ''; |
| | | } |
| | | return new Promise((resolve, reject) => { |
| | | // 如果是相对路径,添加基础URL |
| | | let fullUrl = imageUrl; |
| | |
| | | } |
| | | |
| | | // 新增:处理图片数组 |
| | | async function processImagesToBase64(imageUrls) { |
| | | async function processImagesToBase64(imagePaths) { |
| | | if (!imagePaths || imagePaths.length === 0) return []; |
| | | |
| | | const processed = []; |
| | | for (const path of imagePaths) { |
| | | try { |
| | | const base64Images = []; |
| | | for (const url of imageUrls) { |
| | | try { |
| | | const base64 = await urlToBase64(url); |
| | | base64Images.push(base64); |
| | | // 如果是网络路径,先下载 |
| | | const base64 = await urlToBase64(path); |
| | | processed.push(base64); |
| | | } catch (error) { |
| | | console.warn(`无法加载图片 ${url}:`, error); |
| | | // 可以添加一个占位图片或跳过 |
| | | base64Images.push(''); |
| | | console.error('处理图片失败:', path, error); |
| | | processed.push(''); // 或保持原始路径 |
| | | } |
| | | } |
| | | return base64Images; |
| | | } catch (error) { |
| | | console.error('处理图片失败:', error); |
| | | return []; |
| | | } |
| | | return processed; |
| | | } |
| | | |
| | | const initFile = async (val) => { |
| | |
| | | const orgChartImage = await captureElementToImage('org-tree-container'); |
| | | data.companyInfo.orgChart = orgChartImage |
| | | data.companyInfo.companyName = val.companyName |
| | | const templatePath = '/qualityFile.docx' |
| | | data.companyInfo.number = val.number |
| | | data.companyInfo.versionNum = val.versionNum |
| | | data.companyInfo.fileStatus = val.fileStatus |
| | | data.companyInfo.grantNum = val.grantNum |
| | | data.companyInfo.fictionName = val.fictionName |
| | | data.companyInfo.checkName = val.checkName |
| | | data.companyInfo.ratifyName = val.ratifyName |
| | | data.companyInfo.releaseDate = val.releaseDate?.substring(0,10) |
| | | data.companyInfo.executionDate = val.executionDate?.substring(0,10) |
| | | const templatePath = '/qualityFile1.docx' |
| | | await generateWordDocument( |
| | | templatePath, |
| | | data.companyInfo, |