From 6a136d606c4ab31b7c75a1571ddda278ccd34f03 Mon Sep 17 00:00:00 2001 From: zhouwx <1175765986@qq.com> Date: 星期五, 13 六月 2025 13:46:08 +0800 Subject: [PATCH] 修改 --- src/views/system/role/index.vue | 6 src/views/homePage.vue | 2 src/views/build/conpanyFunctionConsult/companyInfo/overview/components/overviewDialog.vue | 74 - src/api/companyInfo/qualifications.js | 35 src/views/build/conpanyFunctionConsult/companyInfo/overview/index.vue | 56 src/views/build/conpanyFunctionConsult/companyInfo/qualifications/index.vue | 262 ++++++ src/views/build/conpanyFunctionConsult/companyInfo/basicInfo/index.vue | 230 +++++ src/api/companyInfo/policy.js | 35 src/views/build/conpanyFunctionConsult/qualityObjectives/reportsituation/index.vue | 11 src/views/build/conpanyFunctionConsult/qualityObjectives/objective/components/objectiveDialog.vue | 378 +++++++++ src/api/companyInfo/overview.js | 35 src/views/build/conpanyFunctionConsult/companyInfo/policy/components/policyDialog.vue | 235 +++++ src/views/build/conpanyFunctionConsult/qualityObjectives/table/index.vue | 11 src/views/build/conpanyFunctionConsult/companyInfo/policy/index.vue | 197 ++++ src/utils/exportWord.js | 55 + src/views/build/conpanyFunctionConsult/qualityObjectives/objective/index.vue | 319 +++++++ package.json | 3 src/views/build/conpanyFunctionConsult/companyInfo/basicInfo/components/basicInfoDialog.vue | 166 ++++ src/views/build/conpanyFunctionConsult/companyInfo/qualifications/components/qualificationsDialog.vue | 232 +++++ src/api/companyInfo/basicInfo.js | 35 20 files changed, 2,303 insertions(+), 74 deletions(-) diff --git a/package.json b/package.json index 5c845dd..bc40b46 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "@wangeditor/editor-for-vue": "^5.1.12", "@wangeditor/plugin-upload-attachment": "^1.1.0", "axios": "0.27.2", + "docxtemplater": "^3.63.2", "echarts": "5.4.0", "element-plus": "2.2.27", "file-saver": "2.0.5", @@ -30,9 +31,11 @@ "js-base64": "^3.7.5", "js-cookie": "3.0.1", "jsencrypt": "3.3.1", + "jszip-utils": "^0.1.0", "moment": "^2.30.1", "nprogress": "0.2.0", "pinia": "2.0.22", + "pizzip": "^3.2.0", "quill": "^2.0.0-dev.3", "spark-md5": "^3.0.2", "tinymce": "^5.10.2", diff --git a/src/api/companyInfo/basicInfo.js b/src/api/companyInfo/basicInfo.js new file mode 100644 index 0000000..253fe4e --- /dev/null +++ b/src/api/companyInfo/basicInfo.js @@ -0,0 +1,35 @@ +import request from '@/utils/request' + + +export function getBasic(params) { + return request({ + url: '/company/basic/list', + method: 'get', + params: params + }) +} + +export function addBasic(data) { + return request({ + url: '/company/basic/insert', + method: 'post', + data: data + }) +} + +export function editBasic(params) { + return request({ + url: `/company/basic/update`, + method: 'post', + data: params + }) +} + +export function delBasic(data) { + return request({ + url: `/company/basic/deleted?companyBasicId=${data}`, + method: 'get' + }) +} + + diff --git a/src/api/companyInfo/overview.js b/src/api/companyInfo/overview.js new file mode 100644 index 0000000..f672594 --- /dev/null +++ b/src/api/companyInfo/overview.js @@ -0,0 +1,35 @@ +import request from '@/utils/request' + + +export function getCom(params) { + return request({ + url: '/company/summary/list', + method: 'get', + params: params + }) +} + +export function addCom(data) { + return request({ + url: '/company/summary/insert', + method: 'post', + data: data + }) +} + +export function editCom(params) { + return request({ + url: `/company/summary/update`, + method: 'post', + data: params + }) +} + +export function delCom(data) { + return request({ + url: `/company/summary/deleted?companySummaryId=${data}`, + method: 'get' + }) +} + + diff --git a/src/api/companyInfo/policy.js b/src/api/companyInfo/policy.js new file mode 100644 index 0000000..3b7ebdf --- /dev/null +++ b/src/api/companyInfo/policy.js @@ -0,0 +1,35 @@ +import request from '@/utils/request' + + +export function getPolicy(params) { + return request({ + url: '/company/policy/list', + method: 'get', + params: params + }) +} + +export function addPolicy(data) { + return request({ + url: '/company/policy/insert', + method: 'post', + data: data + }) +} + +export function editPolicy(params) { + return request({ + url: `/company/policy/update`, + method: 'post', + data: params + }) +} + +export function delPolicy(data) { + return request({ + url: `/company/policy/deleted?qualityPolicyId=${data}`, + method: 'get' + }) +} + + diff --git a/src/api/companyInfo/qualifications.js b/src/api/companyInfo/qualifications.js new file mode 100644 index 0000000..c916975 --- /dev/null +++ b/src/api/companyInfo/qualifications.js @@ -0,0 +1,35 @@ +import request from '@/utils/request' + + +export function getQualification(params) { + return request({ + url: '/company/certificate/list', + method: 'get', + params: params + }) +} + +export function addQualification(data) { + return request({ + url: '/company/certificate/insert', + method: 'post', + data: data + }) +} + +export function editQualification(params) { + return request({ + url: `/company/certificate/update`, + method: 'post', + data: params + }) +} + +export function delQualification(data) { + return request({ + url: `/company/certificate/deleted?companyCertificateId=${data}`, + method: 'get' + }) +} + + diff --git a/src/utils/exportWord.js b/src/utils/exportWord.js new file mode 100644 index 0000000..3ba3d7b --- /dev/null +++ b/src/utils/exportWord.js @@ -0,0 +1,55 @@ +//引入工具 +import PizZip from 'pizzip'; +import Docxtemplater from 'docxtemplater'; +import JSZipUtils from 'jszip-utils'; +import { saveAs } from 'file-saver'; + +// 加载 .docx 模板文件 +function loadFile(url, callback) { + JSZipUtils.getBinaryContent(url, callback); +} + +// 下载生成的文档 +export function download(file, name) { + +} + +// 生成并下载 Word 文档(templatePath是word文档模版地址,data是对应的数据) +export function generateWordDocument(templatePath, data, name) { + loadFile(templatePath, function (error, content) { + if (error) { + throw error + return; + } + + try { + // 加载模板文件内容到 PizZip + const zip = new PizZip(content); + const doc = new Docxtemplater(zip, { + paragraphLoop: true, + linebreaks: true, + }); + + // 设置模板中的占位符数据 + doc.setData(data); + + // 渲染文档 + doc.render(); + + // 生成最终的文档 Blob + const fileWord = doc.getZip().generate({ + type: 'blob', + mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + }); + + saveAs(fileWord, name); + + // // 返回生成的文档 Blob + // resolve(fileWord); + } catch (error) { + console.error('Error rendering document:', error); + throw error + } + }); + +} diff --git a/src/views/build/conpanyFunctionConsult/companyInfo/basicInfo/components/basicInfoDialog.vue b/src/views/build/conpanyFunctionConsult/companyInfo/basicInfo/components/basicInfoDialog.vue new file mode 100644 index 0000000..84bbb10 --- /dev/null +++ b/src/views/build/conpanyFunctionConsult/companyInfo/basicInfo/components/basicInfoDialog.vue @@ -0,0 +1,166 @@ +<template> + <div class="notice"> + <el-dialog + v-model="dialogVisible" + :title="title" + width="50%" + :before-close="handleClose" + :close-on-press-escape="false" + :close-on-click-modal="false" + > + <el-form :model="state.form" size="default" ref="busRef" :rules="state.formRules" label-position="top" label-width="150px" > + <el-form-item label="1.企业的基本情况,主要包括:法人证书编号,所属部门、法人代表姓名、身份证号、职务、人员总数、技术人员数、不良情况记录、保密等资质。" prop="basic" > + <el-input v-model="state.form.basic" :rows="4" type="textarea" :disabled="title === '查看'"/> + </el-form-item> + <el-form-item label="2.企业简介、行业特点、资源和能力情况。特别是上次审核以来领导层、组织机构(包括分场所)及体系变动情况。" prop="introduce" > + <el-input v-model="state.form.introduce" :rows="4" type="textarea" :disabled="title === '查看'"/> + </el-form-item> + <el-form-item label="3.最高管理者对体系的重视程度,员工的质量意识,企业的经营宗旨和质量方针的确定,质量方针与经营宗旨是否相适宜,质量目标的适宜性及实现情况,及上年度目标的实现情况,本年度目标的阶段性实现情况,当目标没有实现时,采取的措施。" prop="target" > + <el-input v-model="state.form.target" :rows="4" type="textarea" :disabled="title === '查看'"/> + </el-form-item> + <el-form-item label="4.自上次审核以来签订了多少份合同(军)、交付情况,以及取得的绩效(顾客满意度情况、订货及销售收入、利润及增加情况;产值/利润递增情况;质量损失减少情况;产品一次交验合格率提升情况;取得的专利和奖励成果情况;顾客表扬方面的内容),按照年度统计数据或年递增率。" prop="quality"> + <el-input v-model="state.form.quality" :rows="4" type="textarea" :disabled="title === '查看'"/> + </el-form-item> + <el-form-item label="5.总结自上次审核以来开展了哪些质量管理专项活动,特别是有效提高质量管理意识和质量管理技能、产品实物质量方面的管理改进活动,效果如何,以及纠正/预防措施落实情况。" prop="activity"> + <el-input v-model="state.form.activity" :rows="4" type="textarea" :disabled="title === '查看'"/> + </el-form-item> + <el-form-item label="6.本年度内审时间、开出不符合项数量及整改验收;管理评审时间、改进事项及完成情况。" prop="audit"> + <el-input v-model="state.form.audit" :rows="4" type="textarea" :disabled="title === '查看'"/> + </el-form-item> + <el-form-item label="7.公司的外包过程有哪些?如何控制以及风险管理的应用情况。" prop="epiboly"> + <el-input v-model="state.form.epiboly" :rows="4" type="textarea" :disabled="title === '查看'"/> + </el-form-item> + <el-form-item label="8.自上次审核以来资源投入情况(人员、环境、生产/检测设备等配置增加或者变动的数据),教育培训实施次数/人次等。" prop="resource"> + <el-input v-model="state.form.resource" :disabled="title === '查看'" :rows="4" type="textarea" /> + </el-form-item> + </el-form> + <template #footer v-if="title !== '查看'"> + <span class="dialog-footer"> + <el-button @click="handleClose" size="default">取 消</el-button> + <el-button type="primary" @click="onSubmit" size="default" v-preReClick>确认</el-button> + </span> + </template> + </el-dialog> + </div> +</template> +<script setup> +import {reactive, ref, toRefs} from 'vue' +import Editor from "@/components/Editor/index.vue"; +import {ElMessage} from "element-plus"; +import {addNotice} from "@/api/backManage/notice"; +import {addDict, editDict, getDictDetail} from "@/api/backManage/evaluate"; +import {addCompany, checkName, distributeCompany, editCompany} from "@/api/onlineEducation/company"; +import {verifyPhone} from "@/utils/validate"; +import {addBasic, editBasic} from "@/api/companyInfo/basicInfo"; +import Cookies from "js-cookie"; + +const dialogVisible = ref(false); +const title = ref(""); +const busRef = ref(); +const length = ref() +const emit = defineEmits(["getList"]); +const state = reactive({ + form: { + id: '', + companyId: null, + companyName: '', + basic: '', + introduce: '', + target: '', + quality: '', + activity: '', + audit: '', + epiboly: '', + resource: '', + }, + formRules:{ + basic: [{ required: true, message: '请输入', trigger: 'blur' }], + introduce:[{ required: true, message: '请输入', trigger: 'blur' }], + target: [{ required: true, message: '请输入', trigger: 'blur' }], + quality: [{ required: true, message: '请输入', trigger: 'blur' }], + activity: [{ required: true, message: '请输入', trigger: 'blur' }], + audit: [{ required: true, message: '请输入', trigger: 'blur' }], + epiboly: [{ required: true, message: '请输入', trigger: 'blur' }], + resource: [{ required: true, message: '请输入', trigger: 'blur' }], + }, +}) + + +const openDialog = async (type, value) => { + title.value = type === 'add' ? '新增' : type ==='edit' ? '编辑' : '查看' ; + if(type === 'edit' || type === 'review') { + state.form = JSON.parse(JSON.stringify(value)); + } + dialogVisible.value = true; +} + +const onSubmit = async () => { + const valid = await busRef.value.validate(); + const userInfo = JSON.parse(Cookies.get('userInfo')) + state.form.companyId = userInfo.companyId + if(valid){ + if(title.value === '新增'){ + const {id, ...data} = JSON.parse(JSON.stringify(state.form)) + const res = await addBasic(data) + if(res.code === 200){ + ElMessage({ + type: 'success', + message: '新增成功' + }); + }else{ + ElMessage.warning(res.message) + } + emit("getList") + busRef.value.clearValidate(); + reset(); + dialogVisible.value = false; + }else if(title.value === '编辑'){ + const {...data} = JSON.parse(JSON.stringify(state.form)) + const res = await editBasic(data) + if(res.code === 200){ + ElMessage({ + type: 'success', + message: '编辑成功' + }); + }else{ + ElMessage.warning(res.message) + } + emit("getList") + busRef.value.clearValidate(); + reset(); + dialogVisible.value = false; + } + } +} + +const handleClose = () => { + busRef.value.clearValidate(); + reset(); + dialogVisible.value = false; + emit("getList") + +} +const reset = () => { + state.form = { + id: '', + + } +} +defineExpose({ + openDialog +}); + +</script> + +<style scoped lang="scss"> +.notice{ + :deep(.el-form .el-form-item__label) { + font-size: 15px; + } + .file { + display: flex; + flex-direction: column; + align-items: flex-start; + } +} +</style> diff --git a/src/views/build/conpanyFunctionConsult/companyInfo/basicInfo/index.vue b/src/views/build/conpanyFunctionConsult/companyInfo/basicInfo/index.vue new file mode 100644 index 0000000..e7b9096 --- /dev/null +++ b/src/views/build/conpanyFunctionConsult/companyInfo/basicInfo/index.vue @@ -0,0 +1,230 @@ +<template> + <div class="app-container"> + <div style="margin-bottom: 10px"> + <el-form style="display: flex;flex-wrap: wrap;"> + <el-form-item v-if="!data.isAdmin"> + <el-button + type="primary" + plain + icon="Plus" + @click="openDialog('add',{})" + >新增</el-button> + </el-form-item> + <el-form-item label="企业名称:" v-if="data.isAdmin" style="margin-left: 20px"> + <el-select + v-model="data.queryParams.companyName" + filterable + remote + @change="selectValue" + reserve-keyword + placeholder="请输入企业名称" + remote-show-suffix + :remote-method="getCompanyList" + :loading="loadingCompany" + style="width: 240px" + > + <el-option + v-for="item in data.companyList" + :key="item.id" + :label="item.name" + :value="item.name" + /> + </el-select> + </el-form-item> + <el-form-item v-if="data.isAdmin"> + <el-button type="primary" style="margin-left: 30px" @click="searchClick">查询</el-button> + <el-button plain @click="reset">重置</el-button> + </el-form-item> + + + <el-form-item style="margin-left: 15px"> + <el-button + type="primary" + @click="exportData" + >导出</el-button> + </el-form-item> + + </el-form> + </div> + <!-- 表格数据 --> + <el-table v-loading="loading" :data="dataList" :border="true" @selection-change="handleSelectionChange"> + <el-table-column type="selection" width="55" /> + <el-table-column type="index" label="序号" width="80" align="center"></el-table-column> + <el-table-column label="企业名称" prop="companyName" align="center" /> + <el-table-column label="操作" align="center" class-name="small-padding fixed-width" > + <template #default="scope"> + <el-button link type="primary" @click="openDialog('review',scope.row)" >查看</el-button> + <el-button link type="primary" @click="openDialog('edit',scope.row)" >编辑</el-button> + <el-button link type="danger" @click="handleDelete(scope.row)" >删除</el-button> + </template> + </el-table-column> + </el-table> + + <div class="pag-container"> + <el-pagination + v-model:current-page="data.queryParams.pageNum" + v-model:page-size="data.queryParams.pageSize" + :page-sizes="[10,15,20,25]" + layout="total, sizes, prev, pager, next, jumper" + :total="total" + @size-change="handleSizeChange" + @current-change="handleCurrentChange" + /> + </div> + <basicInfoDialog ref="noticeRef" @getList = "getList"></basicInfoDialog> + </div> +</template> + +<script setup> +import {getCurrentInstance, onMounted, reactive, ref, toRefs} from "vue"; +import basicInfoDialog from "./components/basicInfoDialog.vue" +import {ElMessage, ElMessageBox} from "element-plus"; +import {getCompany} from "@/api/onlineEducation/company"; +import Cookies from "js-cookie"; +import {generateWordDocument} from "@/utils/exportWord"; +import {delBasic, getBasic} from "@/api/companyInfo/basicInfo"; + +const { proxy } = getCurrentInstance(); +const loading = ref(false); +const noticeRef = ref(); +const loadingCompany = ref(false) +const choosedData = ref([]) +const data = reactive({ + queryParams: { + pageNum: 1, + pageSize: 10, + companyId: null, + }, + companyList: [], + isAdmin: false +}); +const dataList = ref([]); +const total = ref(0); + +const { queryParams } = toRefs(data); + +onMounted(() => { + const userInfo = JSON.parse(Cookies.get('userInfo')) + console.log("userInfo",userInfo) + data.isAdmin = userInfo.userType === 0; + data.queryParams.companyId = userInfo.companyId ? userInfo.companyId : null + getList(); +}); +const getList = async () => { + loading.value = true; + const res = await getBasic(data.queryParams); + if(res.code === 200){ + dataList.value = res.data.list + total.value = res.data.total + }else{ + ElMessage.warning(res.message) + } + loading.value = false; + +} + +const searchClick = () => { + getList(); +} +const openDialog = (type, value) => { + noticeRef.value.openDialog(type, value); +} +const selectValue = (val) => { + data.companyList.forEach(item => { + if(item.name === val){ + data.queryParams.companyId = item.id + } + }) +} + +const getCompanyList = async (val)=>{ + if(val != ""){ + loadingCompany.value = true; + const queryParams = { + name: val + } + const res = await getCompany(queryParams) + if (res.code == 200) { + loadingCompany.value = false; + data.companyList = res.data.list + + } else { + ElMessage.warning(res.message) + } + } +} + +const handleSizeChange = (val) => { + data.queryParams.pageSize = val + getList() +} +const handleCurrentChange = (val) => { + data.queryParams.pageNum = val + getList() +} + +/** 重置新增的表单以及其他数据 */ +function reset() { + data.queryParams = { + companyId: '', + pageNum: 1, + pageSize: 10, + } + choosedData.value = [] + data.companyList = []; + getList(); +} +const exportData = () => { + if(choosedData.value && choosedData.value.length === 0){ + ElMessage.warning('请选择需要导出的数据') + }else { + startGeneration() + } +} +const templatePath = '/infoExample.docx' +const startGeneration = async () => { + choosedData.value.forEach(item => { + try { + generateWordDocument(templatePath, item, item.companyName+'_基本情况.docx'); + } catch (error){ + ElMessage({ + type: 'warning', + message: '导出失败' + }); + } + }) +} + +const handleSelectionChange = (val) => { + choosedData.value = val +} +const handleDelete = (val) => { + ElMessageBox.confirm( + '确定删除此条数据?', + '提示', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning', + }) + .then( async() => { + const res = await delBasic(val.id); + if(res.code === 200){ + ElMessage({ + type: 'success', + message: '删除成功' + }); + getList(); + }else{ + ElMessage.warning(res.message) + } + }) +} + +</script> +<style lang="scss"> +.pag-container{ + float: right; + margin-top: 10px; +} +</style> diff --git a/src/views/build/conpanyFunctionConsult/companyInfo/overview/components/overviewDialog.vue b/src/views/build/conpanyFunctionConsult/companyInfo/overview/components/overviewDialog.vue index a521f1e..28a213c 100644 --- a/src/views/build/conpanyFunctionConsult/companyInfo/overview/components/overviewDialog.vue +++ b/src/views/build/conpanyFunctionConsult/companyInfo/overview/components/overviewDialog.vue @@ -8,12 +8,12 @@ > <el-form :model="state.noticeForm" size="default" ref="noticeRef" :rules="title === '新增' || title === '编辑' ? state.formRules : {}" label-width="110px" > <el-form-item label="企业概括:" v-if="showEditor" required> - <t-editor style="width: 800px" ref="myEditor" :value="state.noticeForm.noticeContent" ></t-editor> + <t-editor style="width: 800px" ref="myEditor" :value="state.noticeForm.companySummary" ></t-editor> </el-form-item> - <el-form-item label="公告内容:" v-else> + <el-form-item label="企业概括:" v-else> <div class="ql-container ql-snow" style="height: 500px;width: 100%;margin-top: 10px;" > <div class="ql-editor"> - <div class="reviewTable" v-html="state.noticeForm.noticeContent" @click="showFile($event)"></div> + <div class="reviewTable" v-html="state.noticeForm.companySummary" @click="showFile($event)"></div> </div> </div> </el-form-item> @@ -28,7 +28,7 @@ </div> </template> <script setup> -import {nextTick, reactive, ref, toRefs, watch} from 'vue' +import {nextTick, onMounted, reactive, ref, toRefs, watch} from 'vue' import WeEditor from "@/components/WeEditor/index.vue"; import TEditor from "@/components/Tinymce/Tinymce.vue" import {ElMessage} from "element-plus"; @@ -37,6 +37,8 @@ import {getToken} from "@/utils/auth"; import {handleThemeStyle} from "@/utils/theme"; import useSettingsStore from "@/store/modules/settings"; +import {addCom, editCom} from "@/api/companyInfo/overview"; +import Cookies from "js-cookie"; const emit = defineEmits(["getList"]); @@ -51,34 +53,27 @@ const state = reactive({ noticeForm: { id: '', - noticeTitle: '', - noticeContent: '', + companySummary: '', + companyId:null, + companyName: '' }, formRules:{ - // noticeContent: [{ required: true, message: '请输入公告内容', trigger: 'blur' }], + companySummary: [{ required: true, message: '企业概况', trigger: 'blur' }], }, }) +onMounted(() => { + +}); const openDialog = async (type, value) => { - dialogVisible.value = true; - // state.noticeForm.noticeContent = "" + isReview.value = false; showEditor.value = false title.value = type === 'add' ? '新增' : type ==='edit' ? '编辑' : '查看' ; if(type === 'edit' || type === 'review') { - // const param = { - // noticeId: value.id - // } - // const res = await getNoticeDetail(param); - // if(res.code === 200){ - // state.noticeForm.id = res.data.id - // state.noticeForm.noticeTitle = res.data.title - // state.noticeForm.noticeContent = res.data.content - // }else{ - // ElMessage.warning(res.message) - // } - + state.noticeForm.companySummary = value.companySummary + state.noticeForm.id = value.id } if(type === 'review') { showEditor.value = false @@ -91,11 +86,10 @@ if(type === 'add'){ reset() } - - + dialogVisible.value = true; } const getEditorData = (val) =>{ - state.noticeForm.noticeContent = val; + state.noticeForm.companySummary = val; } const showFile = (e) => { @@ -133,25 +127,23 @@ } const onSubmit = async () => { - state.noticeForm.noticeContent = tinyMCE.activeEditor.getContent(); - console.log("点击提交") - console.log('data',state.noticeForm.noticeContent) + state.noticeForm.companySummary = tinyMCE.activeEditor.getContent(); + const userInfo = JSON.parse(Cookies.get('userInfo')) + state.noticeForm.companyId = userInfo.companyId + state.noticeForm.companyName = userInfo.companyName // // myEditor.value.submit(); const valid = await noticeRef.value.validate(); if(valid){ - - if(state.noticeForm.noticeContent == "") { + if(state.noticeForm.companySummary == "") { ElMessage({ type: 'warning', - message: '请输入公司概况' + message: '请输入企业概况' }); return; } if(title.value === '新增'){ - const param = { - content: state.noticeForm.noticeContent, - } - const res = await addNotice(param) + const {id,...data} = JSON.parse(JSON.stringify(state.noticeForm)) + const res = await addCom(data) if(res.code === 200){ ElMessage({ type: 'success', @@ -167,11 +159,8 @@ noticeRef.value.clearValidate(); dialogVisible.value = false; }else if(title.value === '编辑') { - const param = { - id: state.noticeForm.id, - content: state.noticeForm.noticeContent, - } - const res = await editNotice(param) + const {...data} = JSON.parse(JSON.stringify(state.noticeForm)) + const res = await editCom(data) if(res.code === 200){ ElMessage({ type: 'success', @@ -202,9 +191,10 @@ } const reset = () => { state.noticeForm = { - id: '', - noticeTitle: '', - noticeContent: '' + id: '', + companySummary: '', + companyId:null, + companyName: '' } } diff --git a/src/views/build/conpanyFunctionConsult/companyInfo/overview/index.vue b/src/views/build/conpanyFunctionConsult/companyInfo/overview/index.vue index b829ad5..2ac8fc0 100644 --- a/src/views/build/conpanyFunctionConsult/companyInfo/overview/index.vue +++ b/src/views/build/conpanyFunctionConsult/companyInfo/overview/index.vue @@ -2,7 +2,7 @@ <div class="app-container"> <div style="margin-bottom: 10px"> <el-form style="display: flex;flex-wrap: wrap"> - <el-form-item> + <el-form-item v-if="!data.isAdmin"> <el-button type="primary" plain @@ -12,7 +12,7 @@ </el-form-item> <el-form-item label="企业名称:" v-if="data.isAdmin" style="margin-left: 20px"> <el-select - v-model="data.queryParams.companyName" + v-model="data.companyName" filterable remote @change="selectValue" @@ -31,7 +31,7 @@ /> </el-select> </el-form-item> - <el-form-item> + <el-form-item v-if="data.isAdmin"> <el-button type="primary" style="margin-left: 30px" @click="searchClick">查询</el-button> <el-button plain @click="reset">重置</el-button> </el-form-item> @@ -41,7 +41,7 @@ <!-- 表格数据 --> <el-table v-loading="loading" :data="dataList" :border="true"> <el-table-column type="index" label="序号" width="80" align="center"></el-table-column> - <el-table-column label="企业名称" prop="conpanyName" align="center" /> + <el-table-column label="企业名称" prop="companyName" align="center" /> <el-table-column label="操作" align="center" class-name="small-padding fixed-width" > <template #default="scope"> <el-button link type="primary" @click="openDialog('review',scope.row)" >查看</el-button> @@ -72,6 +72,7 @@ import {ElMessage, ElMessageBox} from "element-plus"; import {getCompany} from "@/api/onlineEducation/company"; import Cookies from "js-cookie"; +import {delCom, getCom} from "@/api/companyInfo/overview"; const { proxy } = getCurrentInstance(); const loading = ref(false); const noticeRef = ref(); @@ -83,7 +84,8 @@ companyId: null, }, companyList: [], - isAdmin: false + isAdmin: false, + companyName: '' }); const dataList = ref([]); const total = ref(0); @@ -94,22 +96,19 @@ const userInfo = JSON.parse(Cookies.get('userInfo')) console.log("userInfo",userInfo) data.isAdmin = userInfo.userType === 0; + data.queryParams.companyId = userInfo.companyId ? userInfo.companyId : null getList(); }); const getList = async () => { loading.value = true; - // const res = await getNoticeList(data.queryParams); - // if(res.code === 200){ - // dataList.value = res.data.list.map(item => { - // return { - // ...item, - // createTime: item.createTime.replace(/T/g," ") - // } - // }) - // total.value = res.data.total - // }else{ - // ElMessage.warning(res.message) - // } + const res = await getCom(data.queryParams); + if(res.code === 200){ + dataList.value = res.data.list + total.value = res.data.total + }else{ + ElMessage.warning(res.message) + } + loading.value = false; loading.value = false; } @@ -157,10 +156,11 @@ /** 重置新增的表单以及其他数据 */ function reset() { data.queryParams = { - companyId: '', + companyId: null, pageNum: 1, pageSize: 10, } + data.companyName = '' data.companyList = []; getList(); } @@ -174,16 +174,16 @@ type: 'warning', }) .then( async() => { - // const res = await delNotice(val); - // if(res.code === 200){ - // ElMessage({ - // type: 'success', - // message: '删除成功' - // }); - // getList(); - // }else{ - // ElMessage.warning(res.message) - // } + const res = await delCom(val.id); + if(res.code === 200){ + ElMessage({ + type: 'success', + message: '删除成功' + }); + getList(); + }else{ + ElMessage.warning(res.message) + } }) } diff --git a/src/views/build/conpanyFunctionConsult/companyInfo/policy/components/policyDialog.vue b/src/views/build/conpanyFunctionConsult/companyInfo/policy/components/policyDialog.vue new file mode 100644 index 0000000..310c34e --- /dev/null +++ b/src/views/build/conpanyFunctionConsult/companyInfo/policy/components/policyDialog.vue @@ -0,0 +1,235 @@ +<template> + <div class="notice"> + <el-dialog + v-model="dialogVisible" + :title="title" + width="800px" + :before-close="handleClose" + > + <el-form :model="state.noticeForm" size="default" ref="noticeRef" :rules="title === '新增' || title === '编辑' ? state.formRules : {}" label-width="110px" > + <el-form-item label="质量方针:" v-if="showEditor" required> + <t-editor style="width: 800px" ref="myEditor" :value="state.noticeForm.policy" ></t-editor> + </el-form-item> + <el-form-item label="质量方针:" v-else> + <div class="ql-container ql-snow" style="height: 500px;width: 100%;margin-top: 10px;" > + <div class="ql-editor"> + <div class="reviewTable" v-html="state.noticeForm.policy" @click="showFile($event)"></div> + </div> + </div> + </el-form-item> + </el-form> + <template #footer v-if="!isReview"> + <span class="dialog-footer"> + <el-button @click="handleClose" size="default">取 消</el-button> + <el-button type="primary" @click="onSubmit" size="default" v-preReClick>确认</el-button> + </span> + </template> + </el-dialog> + </div> +</template> +<script setup> +import {nextTick, onMounted, reactive, ref, toRefs, watch} from 'vue' +import WeEditor from "@/components/WeEditor/index.vue"; +import TEditor from "@/components/Tinymce/Tinymce.vue" +import {ElMessage} from "element-plus"; +import {addNotice, editNotice, getNoticeDetail} from "@/api/backManage/notice"; +import axios from "axios"; +import {getToken} from "@/utils/auth"; +import {handleThemeStyle} from "@/utils/theme"; +import useSettingsStore from "@/store/modules/settings"; +import {addCom, editCom} from "@/api/companyInfo/overview"; +import Cookies from "js-cookie"; +import {addPolicy, editPolicy} from "@/api/companyInfo/policy"; + + +const emit = defineEmits(["getList"]); + +const dialogVisible = ref(false); +const title = ref(""); +const noticeRef = ref(); +const fileList = ref([]); +const myEditor = ref(); +const isReview = ref(false); +const showEditor = ref(true); +const state = reactive({ + noticeForm: { + id: '', + policy: '', + companyId:null, + companyName: '' + }, + formRules:{ + policy: [{ required: true, message: '质量方针', trigger: 'blur' }], + }, + +}) + +onMounted(() => { + +}); +const openDialog = async (type, value) => { + + isReview.value = false; + showEditor.value = false + title.value = type === 'add' ? '新增' : type ==='edit' ? '编辑' : '查看' ; + if(type === 'edit' || type === 'review') { + state.noticeForm.policy = value.policy + state.noticeForm.id = value.id + } + if(type === 'review') { + showEditor.value = false + isReview.value = true; + } + if(type === 'edit' || type === 'add') { + showEditor.value = true; + isReview.value = false; + } + if(type === 'add'){ + reset() + } + dialogVisible.value = true; +} +const getEditorData = (val) =>{ + state.noticeForm.policy = val; +} + +const showFile = (e) => { + if(e.target.nodeName === 'A'){ + console.log("e",e) + e.preventDefault(); + const file = { + fileUrl: e.target.href, + fileName: e.target.innerHTML + } + axios.get( file.fileUrl,{ + headers: + { + 'Content-Type': 'application/json', + 'Authorization':getToken(), + }, + responseType: 'blob' + } + ).then(res=>{ + if (res) { + const link = document.createElement('a') + let blob = new Blob([res.data],{type: res.data.type}) + link.style.display = "none"; + link.href = URL.createObjectURL(blob); // 创建URL + link.setAttribute("download", file.fileName); + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + } else { + this.$message.error('获取文件失败') + } + // handleClose(); + }) + } +} + +const onSubmit = async () => { + state.noticeForm.policy = tinyMCE.activeEditor.getContent(); + const userInfo = JSON.parse(Cookies.get('userInfo')) + state.noticeForm.companyId = userInfo.companyId + state.noticeForm.companyName = userInfo.companyName + // // myEditor.value.submit(); + const valid = await noticeRef.value.validate(); + if(valid){ + if(state.noticeForm.policy == "") { + ElMessage({ + type: 'warning', + message: '请输入企业概况' + }); + return; + } + if(title.value === '新增'){ + const {id,...data} = JSON.parse(JSON.stringify(state.noticeForm)) + const res = await addPolicy(data) + if(res.code === 200){ + ElMessage({ + type: 'success', + message: '新增成功' + }); + }else{ + ElMessage.warning(res.message) + } + emit("getList") + reset(); + showEditor.value=false + myEditor.value.clear(); + noticeRef.value.clearValidate(); + dialogVisible.value = false; + }else if(title.value === '编辑') { + const {...data} = JSON.parse(JSON.stringify(state.noticeForm)) + const res = await editPolicy(data) + if(res.code === 200){ + ElMessage({ + type: 'success', + message: '编辑成功' + }); + }else{ + ElMessage.warning(res.message) + } + emit("getList") + reset(); + showEditor.value=false + myEditor.value.clear(); + noticeRef.value.clearValidate(); + dialogVisible.value = false; + } + } +} + +const handleClose = () => { + if(title.value ==="新增"|| title.value ==='编辑'){ + myEditor.value.clear(); + showEditor.value=false + } + + // reset() + noticeRef.value.clearValidate(); + dialogVisible.value = false; +} +const reset = () => { + state.noticeForm = { + id: '', + policy: '', + companyId:null, + companyName: '' + } +} + +defineExpose({ + openDialog +}); + +</script> + +<style scoped lang="scss"> +.notice{ + :deep(.el-form .el-form-item__label) { + font-size: 15px; + } + .file { + display: flex; + flex-direction: column; + align-items: flex-start; + } +} +.reviewTable { + :deep(table){ + border: 1px solid #ccc; + text-align: center; + } + :deep(table td){ + border: 1px solid #ccc; + text-align: center; + padding: 0 5px; + } + :deep(table th){ + border: 1px solid #ccc; + } +} + + +</style> diff --git a/src/views/build/conpanyFunctionConsult/companyInfo/policy/index.vue b/src/views/build/conpanyFunctionConsult/companyInfo/policy/index.vue new file mode 100644 index 0000000..5f06dd7 --- /dev/null +++ b/src/views/build/conpanyFunctionConsult/companyInfo/policy/index.vue @@ -0,0 +1,197 @@ +<template> + <div class="app-container"> + <div style="margin-bottom: 10px"> + <el-form style="display: flex;flex-wrap: wrap"> + <el-form-item v-if="!data.isAdmin"> + <el-button + type="primary" + plain + icon="Plus" + @click="openDialog('add',{})" + >新增</el-button> + </el-form-item> + <el-form-item label="企业名称:" v-if="data.isAdmin" style="margin-left: 20px"> + <el-select + v-model="data.companyName" + filterable + remote + @change="selectValue" + reserve-keyword + placeholder="请输入企业名称" + remote-show-suffix + :remote-method="getCompanyList" + :loading="loadingCompany" + style="width: 240px" + > + <el-option + v-for="item in data.companyList" + :key="item.id" + :label="item.name" + :value="item.name" + /> + </el-select> + </el-form-item> + <el-form-item v-if="data.isAdmin"> + <el-button type="primary" style="margin-left: 30px" @click="searchClick">查询</el-button> + <el-button plain @click="reset">重置</el-button> + </el-form-item> + + </el-form> + </div> + <!-- 表格数据 --> + <el-table v-loading="loading" :data="dataList" :border="true"> + <el-table-column type="index" label="序号" width="80" align="center"></el-table-column> + <el-table-column label="企业名称" prop="companyName" align="center" /> + <el-table-column label="操作" align="center" class-name="small-padding fixed-width" > + <template #default="scope"> + <el-button link type="primary" @click="openDialog('review',scope.row)" >查看</el-button> + <el-button link type="primary" @click="openDialog('edit',scope.row)" >编辑</el-button> + <el-button link type="danger" @click="handleDelete(scope.row)" >删除</el-button> + </template> + </el-table-column> + </el-table> + + <div class="pag-container"> + <el-pagination + v-model:current-page="data.queryParams.pageNum" + v-model:page-size="data.queryParams.pageSize" + :page-sizes="[10,15,20,25]" + layout="total, sizes, prev, pager, next, jumper" + :total="total" + @size-change="handleSizeChange" + @current-change="handleCurrentChange" + /> + </div> + <policyDialog ref="noticeRef" @getList = "getList"></policyDialog> + </div> +</template> + +<script setup> +import {getCurrentInstance, onMounted, reactive, ref, toRefs} from "vue"; +import policyDialog from "./components/policyDialog.vue" +import {ElMessage, ElMessageBox} from "element-plus"; +import {getCompany} from "@/api/onlineEducation/company"; +import Cookies from "js-cookie"; +import {delCom, getCom} from "@/api/companyInfo/overview"; +import {delPolicy, getPolicy} from "@/api/companyInfo/policy"; +const { proxy } = getCurrentInstance(); +const loading = ref(false); +const noticeRef = ref(); +const loadingCompany = ref(false) +const data = reactive({ + queryParams: { + pageNum: 1, + pageSize: 10, + companyId: null, + }, + companyList: [], + isAdmin: false, + companyName: '' +}); +const dataList = ref([]); +const total = ref(0); + +const { queryParams } = toRefs(data); + +onMounted(() => { + const userInfo = JSON.parse(Cookies.get('userInfo')) + console.log("userInfo",userInfo) + data.isAdmin = userInfo.userType === 0; + data.queryParams.companyId = userInfo.companyId ? userInfo.companyId : null + getList(); +}); +const getList = async () => { + loading.value = true; + const res = await getPolicy(data.queryParams); + if(res.code === 200){ + dataList.value = res.data.list + total.value = res.data.total + }else{ + ElMessage.warning(res.message) + } + loading.value = false; + loading.value = false; + +} + +const searchClick = () => { + getList(); +} +const openDialog = (type, value) => { + noticeRef.value.openDialog(type, value); +} +const selectValue = (val) => { + data.companyList.forEach(item => { + if(item.name === val){ + data.queryParams.companyId = item.id + } + }) +} + +const getCompanyList = async (val)=>{ + if(val != ""){ + loadingCompany.value = true; + const queryParams = { + name: val + } + const res = await getCompany(queryParams) + if (res.code == 200) { + loadingCompany.value = false; + data.companyList = res.data.list + + } else { + ElMessage.warning(res.message) + } + } +} + +const handleSizeChange = (val) => { + data.queryParams.pageSize = val + getList() +} +const handleCurrentChange = (val) => { + data.queryParams.pageNum = val + getList() +} + +/** 重置新增的表单以及其他数据 */ +function reset() { + data.queryParams = { + companyId: null, + pageNum: 1, + pageSize: 10, + } + data.companyName = '' + data.companyList = []; + getList(); +} +const handleDelete = (val) => { + ElMessageBox.confirm( + '确定删除此条数据?', + '提示', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning', + }) + .then( async() => { + const res = await delPolicy(val.id); + if(res.code === 200){ + ElMessage({ + type: 'success', + message: '删除成功' + }); + getList(); + }else{ + ElMessage.warning(res.message) + } + }) +} + +</script> +<style lang="scss"> +.pag-container{ + float: right; + margin-top: 10px; +} +</style> diff --git a/src/views/build/conpanyFunctionConsult/companyInfo/qualifications/components/qualificationsDialog.vue b/src/views/build/conpanyFunctionConsult/companyInfo/qualifications/components/qualificationsDialog.vue new file mode 100644 index 0000000..a519dfd --- /dev/null +++ b/src/views/build/conpanyFunctionConsult/companyInfo/qualifications/components/qualificationsDialog.vue @@ -0,0 +1,232 @@ +<template> + <div class="notice"> + <el-dialog + v-model="dialogVisible" + :title="title" + width="550px" + :before-close="handleClose" + :close-on-press-escape="false" + :close-on-click-modal="false" + > + <el-form :model="state.form" size="default" ref="busRef" :rules="state.formRules" label-width="150px" > + <el-form-item label="取得资质证书名称:" prop="certificateName" > + <el-input v-model="state.form.certificateName" :disabled="title === '查看'" placeholder="请输入取得资质证书名称"/> + </el-form-item> + <el-form-item label="证书编号:" prop="certificateNum" > + <el-input v-model="state.form.certificateNum" :disabled="title === '查看'" placeholder="请输入证书编号"/> + </el-form-item> + <el-form-item label="有效期:" prop="effectiveTime" > + <el-date-picker + :disabled="title === '查看'" + v-model="state.form.effectiveTime" + type="date" + placeholder="请选择截止日期" + style="width: 100%" + value-format="YYYY-MM-DD" + /> + </el-form-item> + <el-form-item label="证书附件:" prop="filePath" > + <el-upload + :disabled="title === '查看'" + style="width: 100%;" + accept=".pdf" + :action="state.uploadUrl" + :headers="state.header" + method="post" + :on-success="(res, uploadFile)=>handleAvatarSuccess(res, uploadFile)" + :on-exceed="showTip" + v-model:file-list="state.fileList" + :on-remove="handleRemove" + :limit='1' + :before-upload="picSize" + > + <el-button type="primary">证书上传</el-button> + <template #tip> + <div class="el-upload__tip">上传文件尺寸小于15M,最多可上传1份</div> + </template> + </el-upload> + </el-form-item> + + </el-form> + <template #footer v-if="title !== '查看'"> + <span class="dialog-footer"> + <el-button @click="handleClose" size="default">取 消</el-button> + <el-button type="primary" @click="onSubmit" size="default" v-preReClick>确认</el-button> + </span> + </template> + </el-dialog> + </div> +</template> +<script setup> +import {reactive, ref, toRefs} from 'vue' +import Editor from "@/components/Editor/index.vue"; +import {ElMessage, ElMessageBox} from "element-plus"; +import {addNotice} from "@/api/backManage/notice"; +import {addDict, editDict, getDictDetail} from "@/api/backManage/evaluate"; +import {addCompany, checkName, distributeCompany, editCompany} from "@/api/onlineEducation/company"; +import {verifyPhone} from "@/utils/validate"; +import {getToken} from "@/utils/auth"; +import {addQualification, editQualification} from "@/api/companyInfo/qualifications"; +import Cookies from "js-cookie"; + +const dialogVisible = ref(false); +const title = ref(""); +const busRef = ref(); +const length = ref() +const emit = defineEmits(["getList"]); +const state = reactive({ + form: { + id: '', + companyId: '', + certificateName: '', + certificateNum: '', + effectiveTime: '', + filePath: '', + fileName: '' + }, + formRules:{ + certificateName:[{ required: true, message: '请输入取得资质证书名称', trigger: 'blur' }], + certificateNum:[{ required: true, message: '请输入证书编号', trigger: 'blur' }], + effectiveTime:[{ required: true, message: '请选择截止日期', trigger: 'blur' }], + filePath:[{ required: true, message: '请上传证书', trigger: 'blur' }], + }, + uploadUrl: import.meta.env.VITE_APP_BASE_API + '/system/common/uploadFile', + header: { + Authorization: getToken() + }, + fileList: [], +}) + + +const openDialog = async (type, value) => { + title.value = type === 'add' ? '新增' : type ==='edit' ? '编辑' : '查看' ; + if(type === 'edit' || type === 'review') { + state.form = JSON.parse(JSON.stringify(value)); + const obj = { + path: state.form.filePath, + name: state.form.fileName + } + state.fileList.push(obj) + } + dialogVisible.value = true; +} + +const onSubmit = async () => { + const valid = await busRef.value.validate(); + const userInfo = JSON.parse(Cookies.get('userInfo')) + state.form.companyId = userInfo.companyId + if(valid){ + if(title.value === '新增'){ + const {id, ...data} = JSON.parse(JSON.stringify(state.form)) + const res = await addQualification(data) + if(res.code === 200){ + ElMessage({ + type: 'success', + message: '新增成功' + }); + }else{ + ElMessage.warning(res.message) + } + emit("getList") + busRef.value.clearValidate(); + reset(); + dialogVisible.value = false; + }else if(title.value === '编辑'){ + const {...data} = JSON.parse(JSON.stringify(state.form)) + const res = await editQualification(data) + if(res.code === 200){ + ElMessage({ + type: 'success', + message: '编辑成功' + }); + }else{ + ElMessage.warning(res.message) + } + emit("getList") + busRef.value.clearValidate(); + reset(); + dialogVisible.value = false; + } + } +} + +const handleClose = () => { + busRef.value.clearValidate(); + reset(); + dialogVisible.value = false; + emit("getList") + +} +const handleAvatarSuccess = (res,uploadFile) => { + if(res.code === 200){ + state.form.filePath = state.fileList[0].response.data.path + state.form.fileName = state.fileList[0].response.data.originName + }else { + state.fileList = [] + ElMessage({ + type: 'warning', + message: res.message + }) + } +} +// 上传 +const showTip =()=>{ + ElMessage({ + type: 'warning', + message: '超出文件上传数量' + }); +} + +const picSize = async (rawFile) => { + console.log("111",rawFile.name.length) + if(rawFile.name.length >100){ + ElMessage({ + type: 'warning', + message: '文件名不能超过100字' + }); + return false + } + if(rawFile.size / 1024 / 1024 > 15){ + ElMessage({ + type: 'warning', + message: '文件大小不能超过15M' + }); + return false + } +}; +const handleRemove = async (file, uploadFiles) => { + state.form.filePath = '' + state.form.fileName = '' + state.fileList = [] + +} +const reset = () => { + state.form = { + id: '', + companyId: '', + certificateName: '', + certificateNum: '', + effectiveTime: '', + filePath: '', + fileName: '' + } + state.fileList = []; +} +defineExpose({ + openDialog +}); + +</script> + +<style scoped lang="scss"> +.notice{ + :deep(.el-form .el-form-item__label) { + font-size: 15px; + } + .file { + display: flex; + flex-direction: column; + align-items: flex-start; + } +} +</style> diff --git a/src/views/build/conpanyFunctionConsult/companyInfo/qualifications/index.vue b/src/views/build/conpanyFunctionConsult/companyInfo/qualifications/index.vue new file mode 100644 index 0000000..a12e16c --- /dev/null +++ b/src/views/build/conpanyFunctionConsult/companyInfo/qualifications/index.vue @@ -0,0 +1,262 @@ +<template> + <div class="app-container"> + <div style="margin-bottom: 10px"> + <el-form style="display: flex;flex-wrap: wrap;"> + <el-form-item v-if="!data.isAdmin"> + <el-button + type="primary" + plain + icon="Plus" + @click="openDialog('add',{})" + >新增</el-button> + </el-form-item> + <el-form-item label="企业名称:" v-if="data.isAdmin" style="margin-left: 20px"> + <el-select + v-model="data.queryParams.companyName" + filterable + remote + @change="selectValue" + reserve-keyword + placeholder="请输入企业名称" + remote-show-suffix + :remote-method="getCompanyList" + :loading="loadingCompany" + style="width: 240px" + > + <el-option + v-for="item in data.companyList" + :key="item.id" + :label="item.name" + :value="item.name" + /> + </el-select> + </el-form-item> + <el-form-item v-if="data.isAdmin"> + <el-button type="primary" style="margin-left: 30px" @click="searchClick">查询</el-button> + <el-button plain @click="reset">重置</el-button> + </el-form-item> + + + <el-form-item style="margin-left: 15px"> + <el-button + type="primary" + @click="exportData" + >导出</el-button> + </el-form-item> + + </el-form> + </div> + <!-- 表格数据 --> + <el-table v-loading="loading" :data="dataList" :border="true" > + <el-table-column type="index" label="序号" width="80" align="center"></el-table-column> + <el-table-column label="企业名称" prop="companyName" align="center" /> + <el-table-column label="取得资质证书名称" prop="certificateName" align="center" width="130"/> + <el-table-column label="证书编号" prop="certificateNum" align="center" /> + <el-table-column label="有效期" prop="effectiveTime" align="center" /> + <el-table-column label="证书附件" align="center" > + <template #default="scope"> + <el-link type="primary" @click="showFile(scope.row)">{{scope.row.fileName}}</el-link> + </template> + </el-table-column> + <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="160"> + <template #default="scope"> + <el-button link type="primary" @click="openDialog('review',scope.row)" >查看</el-button> + <el-button link type="primary" @click="openDialog('edit',scope.row)" >编辑</el-button> + <el-button link type="danger" @click="handleDelete(scope.row)" >删除</el-button> + </template> + </el-table-column> + </el-table> + + <div class="pag-container"> + <el-pagination + v-model:current-page="data.queryParams.pageNum" + v-model:page-size="data.queryParams.pageSize" + :page-sizes="[10,15,20,25]" + layout="total, sizes, prev, pager, next, jumper" + :total="total" + @size-change="handleSizeChange" + @current-change="handleCurrentChange" + /> + </div> + <qualificationsDialog ref="noticeRef" @getList = "getList"></qualificationsDialog> + </div> +</template> + +<script setup> +import {getCurrentInstance, onMounted, reactive, ref, toRefs} from "vue"; +import qualificationsDialog from "./components/qualificationsDialog.vue" +import {ElMessage, ElMessageBox} from "element-plus"; +import {getCompany} from "@/api/onlineEducation/company"; +import Cookies from "js-cookie"; +import {generateWordDocument} from "@/utils/exportWord"; +import {delQualification, getQualification} from "@/api/companyInfo/qualifications"; +import axios from "axios"; +import {getToken} from "@/utils/auth"; +const { proxy } = getCurrentInstance(); +const loading = ref(false); +const noticeRef = ref(); +const loadingCompany = ref(false) +const choosedData = ref([]) +const data = reactive({ + queryParams: { + pageNum: 1, + pageSize: 10, + companyId: null, + }, + companyList: [], + isAdmin: false +}); +const dataList = ref([]); +const total = ref(0); + +const { queryParams } = toRefs(data); + +onMounted(() => { + const userInfo = JSON.parse(Cookies.get('userInfo')) + console.log("userInfo",userInfo) + data.isAdmin = userInfo.userType === 0; + data.queryParams.companyId = userInfo.companyId + getList(); +}); +const getList = async () => { + loading.value = true; + const res = await getQualification(data.queryParams); + if(res.code === 200){ + dataList.value = res.data.list.map(item => { + return{ + ...item, + effectiveTime: item.effectiveTime.substring(0,10), + } + }) + total.value = res.data.total + }else{ + ElMessage.warning(res.message) + } + loading.value = false; + +} + +const searchClick = () => { + getList(); +} +const openDialog = (type, value) => { + noticeRef.value.openDialog(type, value); +} +const selectValue = (val) => { + data.companyList.forEach(item => { + if(item.name === val){ + data.queryParams.companyId = item.id + } + }) +} + +const getCompanyList = async (val)=>{ + if(val != ""){ + loadingCompany.value = true; + const queryParams = { + name: val + } + const res = await getCompany(queryParams) + if (res.code == 200) { + loadingCompany.value = false; + data.companyList = res.data.list + + } else { + ElMessage.warning(res.message) + } + } +} + +const handleSizeChange = (val) => { + data.queryParams.pageSize = val + getList() +} +const handleCurrentChange = (val) => { + data.queryParams.pageNum = val + getList() +} + +/** 重置新增的表单以及其他数据 */ +function reset() { + data.queryParams = { + companyId: '', + pageNum: 1, + pageSize: 10, + } + choosedData.value = [] + data.companyList = []; + getList(); +} +const exportData = () => { + if(data.isAdmin && !data.queryParams.companyId){ + ElMessage.warning('管理员请先选择企业') + }else { + startGeneration() + } +} +const templatePath = '/certificateExample.docx' +const startGeneration = async () => { + const data = {} + data.name = dataList.value[0].companyName + data.tableData = dataList.value + try { + generateWordDocument(templatePath, data, data.name+'_证书.docx'); + } catch (error){ + ElMessage({ + type: 'warning', + message: '导出失败' + }); + } + +} +const showFile = (e) => { + axios.get(import.meta.env.VITE_APP_BASE_API + '/' +e.filePath,{headers:{'Content-Type': 'application/json','Authorization': `${getToken()}`},responseType: 'blob'}).then(res=>{ + if (res) { + const link = document.createElement('a') + let blob = new Blob([res.data],{type: res.data.type}) + link.style.display = "none"; + link.href = URL.createObjectURL(blob); // 创建URL + window.open(link.href) + } else { + ElMessage({ + type: 'warning', + message: '文件读取失败' + }); + } + }) + +} + +const handleSelectionChange = (val) => { + choosedData.value = val +} +const handleDelete = (val) => { + ElMessageBox.confirm( + '确定删除此条数据?', + '提示', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning', + }) + .then( async() => { + const res = await delQualification(val.id); + if(res.code === 200){ + ElMessage({ + type: 'success', + message: '删除成功' + }); + getList(); + }else{ + ElMessage.warning(res.message) + } + }) +} + +</script> +<style lang="scss"> +.pag-container{ + float: right; + margin-top: 10px; +} +</style> diff --git a/src/views/build/conpanyFunctionConsult/qualityObjectives/objective/components/objectiveDialog.vue b/src/views/build/conpanyFunctionConsult/qualityObjectives/objective/components/objectiveDialog.vue new file mode 100644 index 0000000..e8d2b7d --- /dev/null +++ b/src/views/build/conpanyFunctionConsult/qualityObjectives/objective/components/objectiveDialog.vue @@ -0,0 +1,378 @@ +<template> + <div class="notice"> + <el-dialog + v-model="dialogVisible" + :title="title" + width="50%" + :before-close="handleClose" + :close-on-press-escape="false" + :close-on-click-modal="false" + > + <el-form :model="state.form" size="default" ref="busRef" :rules="state.formRules" label-width="120px" > + <el-row :gutter="24"> + <el-col :span="12"> + <el-form-item label="年份:" prop="creditCode" > + <el-select + v-model="state.form.year" + placeholder="请选择年份" + style="width: 100%" + > + <el-option + v-for="item in state.yearList" + :key="item.value" + :label="item.label" + :value="item.value" + /> + </el-select> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="序号:" prop="creditCode" > + <el-input v-model="state.form.code" placeholder="请输入序号" style="width: 100%"></el-input> + </el-form-item> + </el-col> + </el-row> + <el-row :gutter="24"> + <el-col :span="12"> + <el-form-item label="质量目标级别:" prop="creditCode" > + <el-select + v-model="state.form.level" + placeholder="请选择质量目标级别" + style="width: 100%" + > + <el-option + v-for="item in state.levelList" + :key="item.value" + :label="item.label" + :value="item.value" + /> + </el-select> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="公司名称:" prop="creditCode" v-if="state.form.level == 1"> + <el-input v-model="state.form.companyName" disabled></el-input> + </el-form-item> + <el-form-item label="部门名称:" prop="creditCode" v-else-if="state.form.level == 2"> + <el-select + v-model="state.form.dept" + placeholder="请选择部门" + style="width: 240px" + > + <el-option + v-for="item in state.deptList" + :key="item.value" + :label="item.label" + :value="item.value" + /> + </el-select> + </el-form-item> + </el-col> + </el-row> + <el-row :gutter="24"> + <el-col :span="24"> + <el-form-item :label= "state.form.level==1 ? '公司质量目标' :state.form.level==2 ?'部门质量目标':'质量目标'" > + <div style="display: flex;width: 100%"> + <el-table :data="state.form.objectList" :border="true"> + <el-table-column type="index" label="序号" width="80" align="center"></el-table-column> + <el-table-column label="目标" align="center" > + <template #default="{row,$index}"> + <el-form-item :prop="'objectList.' + '[' + $index + ']' + '.objName'" :rules="state.rules.objName"> + <el-input v-model.number="row.objName" placeholder="请输入质量目标"></el-input> + </el-form-item> + </template> + </el-table-column> + <el-table-column label="操作" align="center" class-name="small-padding fixed-width" > + <template #default="scope" > + <el-button link type="danger" @click="handleDelete(scope.row)" >删除</el-button> + </template> + </el-table-column> + </el-table> + <el-button + style="margin-left: 20px" + type="primary" + @click="addObject" + >新增</el-button> + </div> + </el-form-item> + </el-col> + </el-row> + <el-row :gutter="24"> + <el-col :span="24"> + <el-form-item label="目标测量方法:" prop="method" > + <el-input v-model="state.form.method" :rows="4" type="textarea" placeholder="请输入目标测量方法"/> + </el-form-item> + </el-col> + </el-row> + <el-row :gutter="24" v-if="state.form.level == 2"> + <el-col :span="12"> + <el-form-item label="编制:" prop="creditCode" > + <el-select + v-model="state.form.peopleName" + filterable + remote + @change="selectValue" + reserve-keyword + placeholder="请输入人员名称" + remote-show-suffix + :remote-method="getPeopleList" + style="width: 240px" + > + <el-option + v-for="item in state.peopleList" + :key="item.id" + :label="item.name" + :value="item.name" + /> + </el-select> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="日期:" prop="creditCode" > + <el-date-picker + v-model="value1" + type="date" + placeholder="请选择日期" + /> + </el-form-item> + </el-col> + </el-row> + <el-row :gutter="24" > + <el-col :span="12"> + <el-form-item label="质量管理部:" prop="creditCode" > + <el-select + v-model="state.form.peopleName2" + filterable + remote + @change="selectValue" + reserve-keyword + placeholder="请输入人员名称" + remote-show-suffix + :remote-method="getPeopleList" + style="width: 240px" + > + <el-option + v-for="item in state.peopleList" + :key="item.id" + :label="item.name" + :value="item.name" + /> + </el-select> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="日期:" prop="creditCode" > + <el-date-picker + v-model="value1" + type="date" + placeholder="请选择日期" + /> + </el-form-item> + </el-col> + </el-row> + <el-row :gutter="24"> + <el-col :span="12"> + <el-form-item label="公司分管领导:" prop="creditCode" > + <el-select + v-model="state.form.peopleName3" + filterable + remote + @change="selectValue" + reserve-keyword + placeholder="请输入人员名称" + remote-show-suffix + :remote-method="getPeopleList" + style="width: 240px" + > + <el-option + v-for="item in state.peopleList" + :key="item.id" + :label="item.name" + :value="item.name" + /> + </el-select> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="日期:" prop="creditCode" > + <el-date-picker + v-model="value1" + type="date" + placeholder="请选择日期" + /> + </el-form-item> + </el-col> + </el-row> + </el-form> + <template #footer> + <span class="dialog-footer"> + <el-button @click="handleClose" size="default">取 消</el-button> + <el-button type="primary" @click="onSubmit" size="default" v-preReClick>确认</el-button> + </span> + </template> + </el-dialog> + </div> +</template> +<script setup> +import {onMounted, reactive, ref, toRefs} from 'vue' +import Cookies from "js-cookie"; +import {getCompany} from "@/api/onlineEducation/company"; +import {ElMessage} from "element-plus"; +import {getUser} from "@/api/onlineEducation/user"; + +const dialogVisible = ref(false); +const title = ref(""); +const busRef = ref(); +const length = ref() +const emit = defineEmits(["getList"]); +const dataRef = ref(); +const state = reactive({ + form: { + id: '', + objectList:[], + + }, + rules: { + objName: [ + {required: true, message: "质量目标不能为空", trigger: "blur"} + ], + }, + deptList: [], + peopleList: [], + yearList: [ + { + value: 1, + label: '2025年' + }, + { + value: 2, + label: '2024年' + }, + { + value: 3, + label: '2023年' + }, + ], + levelList: [ + { + value: 1, + label: '公司级' + }, + { + value: 2, + label: '部门级' + }, + ] +}) + +onMounted(() => { + const userInfo = JSON.parse(Cookies.get('userInfo')) + state.form.companyName = userInfo.companyName + state.form.companyId = userInfo.companyId + +}); +const openDialog = async (type, value) => { + title.value = type === 'add' ? '新增' : type ==='edit' ? '编辑' : '查看' ; + if(type === 'edit' || type === 'view') { + state.form = JSON.parse(JSON.stringify(value)); + } + dialogVisible.value = true; +} +const addObject = () => { + state.form.objectList.push({}) +} +const onSubmit = async () => { + const valid = await busRef.value.validate(); + if(valid){ + if(title.value === '新增'){ + console.log('sta',state.form) + // const {id, ...data} = JSON.parse(JSON.stringify(state.form)) + // const res = await addCompany(data) + // if(res.code === 200){ + // ElMessage({ + // type: 'success', + // message: '新增成功' + // }); + // }else{ + // ElMessage.warning(res.message) + // } + emit("getList") + busRef.value.clearValidate(); + reset(); + dialogVisible.value = false; + }else if(title.value === '编辑'){ + // const {...data} = JSON.parse(JSON.stringify(state.form)) + // const res = await editCompany(data) + // if(res.code === 200){ + // ElMessage({ + // type: 'success', + // message: '编辑成功' + // }); + // }else{ + // ElMessage.warning(res.message) + // } + emit("getList") + busRef.value.clearValidate(); + reset(); + dialogVisible.value = false; + } + } +} + +const handleClose = () => { + busRef.value.clearValidate(); + reset(); + dialogVisible.value = false; + emit("getList") + +} +const reset = () => { + state.form = { + id: '', + + } + state.form.objectList=[] +} +const handleDelete = (val) => { + state.form.objectList = state.form.objectList.filter(item=> item != val) +} +const getPeopleList = async (val)=>{ + if(val != ""){ + const queryParams = { + name: val + } + const res = await getUser(queryParams) + if (res.code == 200) { + state.peopleList = res.data.list + + } else { + ElMessage.warning(res.message) + } + } +} +const selectValue = (val) => { + state.peopleList.forEach(item => { + if(item.name === val){ + state.form.peopleId = item.id + } + }) +} + +defineExpose({ + openDialog +}); + +</script> + +<style scoped lang="scss"> +.notice{ + :deep(.el-form .el-form-item__label) { + font-size: 15px; + } + .file { + display: flex; + flex-direction: column; + align-items: flex-start; + } +} +</style> diff --git a/src/views/build/conpanyFunctionConsult/qualityObjectives/objective/index.vue b/src/views/build/conpanyFunctionConsult/qualityObjectives/objective/index.vue new file mode 100644 index 0000000..a4f69ec --- /dev/null +++ b/src/views/build/conpanyFunctionConsult/qualityObjectives/objective/index.vue @@ -0,0 +1,319 @@ +<template> + <div class="app-container"> + <div style="margin-bottom: 10px"> + <el-form style="display: flex;flex-wrap: wrap;"> +<!-- v-if="!data.isAdmin"--> + <el-form-item > + <el-button + type="primary" + plain + icon="Plus" + @click="openDialog('add',{})" + >新增</el-button> + </el-form-item> + <el-form-item label="企业名称:" v-if="data.isAdmin" style="margin-left: 20px"> + <el-select + v-model="data.queryParams.companyName" + filterable + remote + @change="selectValue" + reserve-keyword + placeholder="请输入企业名称" + remote-show-suffix + :remote-method="getCompanyList" + :loading="loadingCompany" + style="width: 240px" + > + <el-option + v-for="item in data.companyList" + :key="item.id" + :label="item.name" + :value="item.name" + /> + </el-select> + </el-form-item> + <el-form-item label="年份:" style="margin-left: 20px"> + <el-select + v-model="data.queryParams.year" + placeholder="请选择年份" + style="width: 240px" + > + <el-option + v-for="item in data.yearList" + :key="item.value" + :label="item.label" + :value="item.value" + /> + </el-select> + </el-form-item> + <el-form-item label="目标级别:" style="margin-left: 20px"> + <el-select + v-model="data.queryParams.level" + placeholder="请选择目标级别" + style="width: 240px" + > + <el-option + v-for="item in data.levelList" + :key="item.value" + :label="item.label" + :value="item.value" + /> + </el-select> + </el-form-item> + <el-form-item v-if="data.isAdmin"> + <el-button type="primary" style="margin-left: 30px" @click="searchClick">查询</el-button> + <el-button plain @click="reset">重置</el-button> + </el-form-item> + <el-form-item style="margin-left: 15px"> + <el-button + type="primary" + @click="exportData" + >导出</el-button> + </el-form-item> + + </el-form> + </div> + <!-- 表格数据 --> + <el-table v-loading="loading" :data="dataList" :border="true" @selection-change="handleSelectionChange"> + <el-table-column type="selection" width="55" /> + <el-table-column type="index" label="序号" width="80" align="center"></el-table-column> + <el-table-column label="企业名称" prop="companyName" align="center" /> + <el-table-column label="年份" prop="year" align="center" /> + <el-table-column label="质量目标级别" prop="level" align="center" /> + <el-table-column label="部门名称" prop="name" align="center" /> + <el-table-column label="质量目标" prop="name" align="center" /> + <el-table-column label="目标测量方法" prop="name" align="center" /> + <el-table-column label="操作" align="center" class-name="small-padding fixed-width" > + <template #default="scope"> + <el-button link type="primary" @click="openDialog('review',scope.row)" >查看</el-button> + <el-button link type="primary" @click="openDialog('edit',scope.row)" >编辑</el-button> + <el-button link type="danger" @click="handleDelete(scope.row)" >删除</el-button> + </template> + </el-table-column> + </el-table> + + <div class="pag-container"> + <el-pagination + v-model:current-page="data.queryParams.pageNum" + v-model:page-size="data.queryParams.pageSize" + :page-sizes="[10,15,20,25]" + layout="total, sizes, prev, pager, next, jumper" + :total="total" + @size-change="handleSizeChange" + @current-change="handleCurrentChange" + /> + </div> + <objectiveDialog ref="noticeRef" @getList = "getList"></objectiveDialog> + </div> +</template> + +<script setup> +import {getCurrentInstance, onMounted, reactive, ref, toRefs} from "vue"; +import objectiveDialog from "./components/objectiveDialog.vue" +import {ElMessage, ElMessageBox} from "element-plus"; +import {getCompany} from "@/api/onlineEducation/company"; +import Cookies from "js-cookie"; +import {generateWordDocument} from "@/utils/exportWord"; +const { proxy } = getCurrentInstance(); +const loading = ref(false); +const noticeRef = ref(); +const loadingCompany = ref(false) +const choosedData = ref([]) +const data = reactive({ + queryParams: { + pageNum: 1, + pageSize: 10, + companyId: null, + year: '', + level: '' + }, + companyList: [], + isAdmin: false, + yearList: [ + { + value: 1, + label: '2025年' + }, + { + value: 2, + label: '2024年' + }, + { + value: 3, + label: '2023年' + }, + ], + levelList: [ + { + value: 1, + label: '公司级' + }, + { + value: 2, + label: '部门级' + }, + ] +}); +const dataList = ref([]); +const total = ref(0); + +const { queryParams } = toRefs(data); + +onMounted(() => { + const userInfo = JSON.parse(Cookies.get('userInfo')) + console.log("userInfo",userInfo) + data.isAdmin = userInfo.userType === 0; + getList(); +}); +const getList = async () => { + dataList.value = [ + { + id: 1, + level: 1, + object: 'xxxx', + method:'方法', + people2: '秦', + date2:'2015-8-1', + people3: '秦', + date3:'2015-8-1' + }, + { + id: 2, + level: 2, + object: 'xxxxfg ', + deptName: '质量管理部', + method:'方法', + people1: '秦', + date1:'2015-8-1', + people2: '秦', + date2:'2015-8-1', + people3: '秦', + date3:'2015-8-1' + }, + ] + // loading.value = true; + // const res = await getCom(data.queryParams); + // if(res.code === 200){ + // dataList.value = res.data.list + // total.value = res.data.total + // }else{ + // ElMessage.warning(res.message) + // } + // loading.value = false; + +} + +const searchClick = () => { + getList(); +} +const openDialog = (type, value) => { + noticeRef.value.openDialog(type, value); +} +const selectValue = (val) => { + data.companyList.forEach(item => { + if(item.name === val){ + data.queryParams.companyId = item.id + } + }) +} + +const getCompanyList = async (val)=>{ + if(val != ""){ + loadingCompany.value = true; + const queryParams = { + name: val + } + const res = await getCompany(queryParams) + if (res.code == 200) { + loadingCompany.value = false; + data.companyList = res.data.list + + } else { + ElMessage.warning(res.message) + } + } +} + +const handleSizeChange = (val) => { + data.queryParams.pageSize = val + getList() +} +const handleCurrentChange = (val) => { + data.queryParams.pageNum = val + getList() +} + +/** 重置新增的表单以及其他数据 */ +function reset() { + data.queryParams = { + companyId: '', + pageNum: 1, + pageSize: 10, + } + choosedData.value = [] + data.companyList = []; + getList(); +} +const exportData = () => { + if(choosedData.value && choosedData.value.length === 0){ + ElMessage.warning('请选择需要导出的数据') + }else { + startGeneration() + } +} +const templatePath = ref('') +const startGeneration = async () => { + choosedData.value.forEach(item => { + if(item.level == 1){ + templatePath.value = '/objectCompanyExample.docx' + }else { + templatePath.value = '/objectDeptExample.docx' + } + const now = new Date() + const year = now.getFullYear() + const month = (now.getMonth() +1).toString().padStart(2, '0'); + item.nowDate = year + '-' + month + try { + generateWordDocument(templatePath.value, item, '质量目标.docx'); + } catch (error){ + ElMessage({ + type: 'warning', + message: '导出失败' + }); + } + }) +} + +const handleSelectionChange = (val) => { + choosedData.value = val +} +const handleDelete = (val) => { + ElMessageBox.confirm( + '确定删除此条数据?', + '提示', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning', + }) + .then( async() => { + // const res = await delNotice(val); + // if(res.code === 200){ + // ElMessage({ + // type: 'success', + // message: '删除成功' + // }); + // getList(); + // }else{ + // ElMessage.warning(res.message) + // } + }) +} + +</script> +<style lang="scss"> +.pag-container{ + float: right; + margin-top: 10px; +} +</style> diff --git a/src/views/build/conpanyFunctionConsult/qualityObjectives/reportsituation/index.vue b/src/views/build/conpanyFunctionConsult/qualityObjectives/reportsituation/index.vue new file mode 100644 index 0000000..762e8b7 --- /dev/null +++ b/src/views/build/conpanyFunctionConsult/qualityObjectives/reportsituation/index.vue @@ -0,0 +1,11 @@ +<script setup> + +</script> + +<template> + +</template> + +<style scoped lang="scss"> + +</style> diff --git a/src/views/build/conpanyFunctionConsult/qualityObjectives/table/index.vue b/src/views/build/conpanyFunctionConsult/qualityObjectives/table/index.vue new file mode 100644 index 0000000..762e8b7 --- /dev/null +++ b/src/views/build/conpanyFunctionConsult/qualityObjectives/table/index.vue @@ -0,0 +1,11 @@ +<script setup> + +</script> + +<template> + +</template> + +<style scoped lang="scss"> + +</style> diff --git a/src/views/homePage.vue b/src/views/homePage.vue index f70c6c5..d7d488d 100644 --- a/src/views/homePage.vue +++ b/src/views/homePage.vue @@ -1,7 +1,7 @@ <template> <el-row class="login-panel"> <el-col :sm="24" :md="12" class="login-img"> - 多体系<br/>建设信息化条统 + 多体系<br/>建设信息化系统 </el-col> <el-col :sm="24" :md="12" class="login-box"> <div class="login-card"> diff --git a/src/views/system/role/index.vue b/src/views/system/role/index.vue index 7b2decd..d2303c9 100644 --- a/src/views/system/role/index.vue +++ b/src/views/system/role/index.vue @@ -124,9 +124,9 @@ <!-- <el-tooltip content="数据权限" placement="top" v-if="scope.row.roleId !== 1">--> <!-- <el-button link type="primary" icon="CircleCheck" @click="handleDataScope(scope.row)" v-hasPermi="['system:role:edit']"></el-button>--> <!-- </el-tooltip>--> - <el-tooltip content="分配用户" placement="top" v-if="scope.row.roleId !== 1"> - <el-button link type="primary" icon="User" @click="handleAuthUser(scope.row)" v-hasPermi="['system:role:edit']"></el-button> - </el-tooltip> +<!-- <el-tooltip content="分配用户" placement="top" v-if="scope.row.roleId !== 1">--> +<!-- <el-button link type="primary" icon="User" @click="handleAuthUser(scope.row)" v-hasPermi="['system:role:edit']"></el-button>--> +<!-- </el-tooltip>--> </template> </el-table-column> </el-table> -- Gitblit v1.9.2