| 2026-02-03 | gongchunyi | ![]() |
| 2026-02-03 | gongchunyi | ![]() |
| 2026-02-03 | huminmin | ![]() |
| 2026-02-03 | gongchunyi | ![]() |
| 2026-02-03 | gongchunyi | ![]() |
| 2026-02-03 | gongchunyi | ![]() |
| 2026-02-03 | gongchunyi | ![]() |
| 2026-02-03 | gaoluyang | ![]() |
| 2026-02-03 | gaoluyang | ![]() |
| 2026-02-03 | gongchunyi | ![]() |
| 2026-02-03 | gongchunyi | ![]() |
| 2026-02-03 | gaoluyang | ![]() |
| 2026-02-03 | gaoluyang | ![]() |
| 2026-02-03 | zss | ![]() |
| 2026-02-03 | zss | ![]() |
| 2026-02-03 | gaoluyang | ![]() |
| 2026-02-03 | gaoluyang | ![]() |
| 2026-02-03 | huminmin | ![]() |
src/api/viewIndex.js
@@ -1,6 +1,15 @@ // 首页接口 import request from "@/utils/request"; // 工单执行效率分析 export const workOrderEfficiencyAnalysis = (query) => { return request({ url: "/home/workOrderEfficiencyAnalysis", method: "get", params: query, }); }; // 原材料检测 export const rawMaterialDetection = (query) => { return request({ src/views/basicData/product/index.vue
@@ -30,11 +30,8 @@ :props="{ children: 'children', label: 'label' }" highlight-current node-key="id" style=" height: calc(100vh - 190px); overflow-y: scroll; scrollbar-width: none; " class="product-tree-scroll" style="height: calc(100vh - 190px); overflow-y: auto" > <template #default="{ node, data }"> <div class="custom-tree-node"> @@ -43,7 +40,7 @@ <component :is="data.children && data.children.length > 0 ? node.expanded ? 'FolderOpened' : 'Folder' : 'Tickets'" /> </el-icon> {{ data.label }} <span class="tree-node-label">{{ data.label }}</span> </span> <div> <el-button @@ -111,6 +108,8 @@ <el-input v-model="form.productName" placeholder="请输入产品名称" maxlength="20" show-word-limit clearable @keydown.enter.prevent /> @@ -239,7 +238,10 @@ productName: "", }, rules: { productName: [{ required: true, message: "请输入", trigger: "blur" }], productName: [ { required: true, message: "请输入", trigger: "blur" }, { max: 20, message: "产品名称不能超过20个字符", trigger: "blur" }, ], }, modelForm: { model: "", @@ -467,18 +469,21 @@ display: flex; } .left { width: 380px; width: 450px; min-width: 450px; padding: 16px; background: #ffffff; } .right { width: calc(100% - 380px); flex: 1; min-width: 0; padding: 16px; margin-left: 20px; background: #ffffff; } .custom-tree-node { flex: 1; min-width: 0; display: flex; align-items: center; justify-content: space-between; @@ -486,13 +491,42 @@ padding-right: 8px; } .tree-node-content { flex: 1; min-width: 0; display: flex; align-items: center; /* 垂直居中 */ align-items: center; height: 100%; overflow: hidden; } .tree-node-content .orange-icon { flex-shrink: 0; } .tree-node-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .orange-icon { color: orange; font-size: 18px; margin-right: 8px; /* 图标与文字之间加点间距 */ } .product-tree-scroll { scrollbar-width: thin; scrollbar-color: #c0c4cc #f5f7fa; } .product-tree-scroll::-webkit-scrollbar { width: 8px; } .product-tree-scroll::-webkit-scrollbar-track { background: #f5f7fa; border-radius: 4px; } .product-tree-scroll::-webkit-scrollbar-thumb { background: #c0c4cc; border-radius: 4px; } .product-tree-scroll::-webkit-scrollbar-thumb:hover { background: #909399; } </style> src/views/collaborativeApproval/knowledgeBase/index.vue
@@ -425,8 +425,15 @@ listKnowledgeBase({...page.value, ...searchForm.value}) .then(res => { tableLoading.value = false; tableData.value = res.data.records page.value.total = res.data.total; // 如果当前页数超过总页数,重置到第1页并重新查询 const maxPage = Math.ceil(res.data.total / page.value.size) || 1; if (page.value.current > maxPage && maxPage > 0) { page.value.current = 1; // 重新查询第1页数据 return getList(); } tableData.value = res.data.records; }).catch(err => { tableLoading.value = false; }) @@ -434,9 +441,14 @@ // 分页处理 const pagination = (obj) => { const oldSize = page.value.size; page.value.current = obj.page; page.value.size = obj.limit; handleQuery(); // 如果 size 改变了,重置到第1页,避免当前页超出范围 if (oldSize !== obj.limit) { page.value.current = 1; } getList(); }; // 选择变化处理 src/views/collaborativeApproval/rulesRegulationsManagement/index.vue
@@ -42,68 +42,15 @@ </el-button> </el-col> </el-row> <el-table :data="regulations" border v-loading="tableLoading" style="width: 100%"> <el-table-column prop="regulationNum" label="制度编号" width="120" /> <el-table-column prop="title" label="制度标题" min-width="150" /> <el-table-column prop="category" label="分类" width="120"> <template #default="scope"> <el-tag>{{ getCategoryText(scope.row.category) }}</el-tag> </template> </el-table-column> <el-table-column prop="version" label="版本" width="120" /> <el-table-column prop="createUserName" label="发布人" width="120" /> <el-table-column prop="createTime" label="发布时间" width="180" /> <el-table-column prop="status" label="状态" width="100"> <template #default="scope"> <el-tag :type="scope.row.status === 'active' ? 'success' : 'info'"> {{ scope.row.status === 'active' ? '生效中' : '已废止' }} </el-tag> </template> </el-table-column> <el-table-column prop="readCount" label="已读人数" width="100" /> <el-table-column label="操作" width="320" fixed="right"> <template #default="scope"> <el-button link @click="viewRegulation(scope.row)">查看</el-button> <el-button link type="primary" @click="handleEdit(scope.row)">编辑</el-button> <el-button link type="danger" @click="repealEdit(scope.row)">废弃</el-button> <el-button link type="success" @click="viewVersionHistory(scope.row)">版本历史</el-button> <!-- <el-button link type="warning" @click="viewReadStatus(scope.row)">阅读状态</el-button> --> <el-button link type="primary" @click="openFileDialog(scope.row)">附件</el-button> </template> </el-table-column> </el-table> <pagination v-show="page.total > 0" :total="page.total" layout="total, sizes, prev, pager, next, jumper" :page="page.current" :limit="page.size" @pagination="paginationChange" /> <PIMTable rowKey="id" :column="regulationTableColumn" :tableData="regulations" :tableLoading="tableLoading" :page="page" :isShowPagination="true" @pagination="paginationChange" /> </div> </el-card> <!-- 用印申请对话框(已移除) --> @@ -295,6 +242,7 @@ delRuleFile, addRuleFile, } from "@/api/collaborativeApproval/rulesRegulationsManagementFile.js"; import PIMTable from "@/components/PIMTable/PIMTable.vue"; // 响应式数据 const operationType = ref("add"); @@ -363,6 +311,45 @@ const regulations = ref([]); // 表格列配置 const regulationTableColumn = ref([ { label: "制度编号", prop: "regulationNum"}, { label: "制度标题", prop: "title" }, { label: "分类", prop: "category", dataType: "tag", formatData: (v) => getCategoryText(v), formatType: () => "info", }, { label: "版本", prop: "version", width: 120 }, { label: "发布人", prop: "createUserName", width: 120 }, { label: "发布时间", prop: "createTime", width: 180 }, { label: "状态", prop: "status", width: 100, dataType: "tag", formatData: (v) => (v === "active" ? "生效中" : "已废止"), formatType: (v) => (v === "active" ? "success" : "info"), }, { label: "已读人数", prop: "readCount", width: 100 }, { dataType: "action", label: "操作", width: 320, fixed: "right", align: "center", operation: [ { name: "查看", clickFun: (row) => viewRegulation(row) }, { name: "编辑", clickFun: (row) => handleEdit(row) }, { name: "废弃", clickFun: (row) => repealEdit(row) }, { name: "版本历史", clickFun: (row) => viewVersionHistory(row) }, { name: "附件", clickFun: (row) => openFileDialog(row) }, ], }, ]); const versionHistory = ref([]); const readStatusList = ref([]); src/views/collaborativeApproval/sealManagement/index.vue
@@ -36,48 +36,15 @@ </el-col> </el-row> <el-table :data="sealApplications" border v-loading="tableLoading" style="width: 100%"> <el-table-column prop="applicationNum" label="申请编号" width="120" /> <el-table-column prop="title" label="申请标题" min-width="200" /> <el-table-column prop="createUserName" label="申请人" width="120" /> <el-table-column prop="department" label="所属部门" width="150" /> <el-table-column prop="sealType" label="用印类型" width="120"> <template #default="scope"> {{ getSealTypeText(scope.row.sealType) }} </template> </el-table-column> <el-table-column prop="createTime" label="申请时间" width="180" /> <el-table-column prop="status" label="状态" width="100"> <template #default="scope"> <el-tag :type="getStatusType(scope.row.status)"> {{ getStatusText(scope.row.status) }} </el-tag> </template> </el-table-column> <el-table-column label="操作" width="200" fixed="right"> <template #default="scope"> <el-button link @click="viewSealDetail(scope.row)">查看</el-button> <el-button v-if="scope.row.status === 'pending'" link type="primary" @click="approveSeal(scope.row)" > 审批 </el-button> <el-button v-if="scope.row.status === 'pending'" link type="danger" @click="rejectSeal(scope.row)" > 拒绝 </el-button> </template> </el-table-column> </el-table> <pagination v-show="page.total > 0" :total="page.total" layout="total, sizes, prev, pager, next, jumper" :page="page.current" :limit="page.size" @pagination="paginationChange" /> <PIMTable rowKey="id" :column="sealTableColumn" :tableData="sealApplications" :tableLoading="tableLoading" :page="page" :isShowPagination="true" @pagination="paginationChange" /> </div> </el-card> @@ -128,55 +95,6 @@ </el-form> </FormDialog> <!-- 规章制度发布对话框 --> <!-- <el-dialog v-model="showRegulationDialog" :title="operationType === 'add' ? '发布制度' : '编辑制度'" width="800px"> <el-form :model="regulationForm" :rules="regulationRules" ref="regulationFormRef" label-width="100px"> <el-form-item label="制度编号" prop="regulationNum"> <el-input v-model="regulationForm.regulationNum" placeholder="请输入制度编号" /> </el-form-item> <el-form-item label="制度标题" prop="title"> <el-input v-model="regulationForm.title" placeholder="请输入制度标题" /> </el-form-item> <el-form-item label="制度分类" prop="category"> <el-select v-model="regulationForm.category" placeholder="请选择制度分类" style="width: 100%"> <el-option label="人事制度" value="hr" /> <el-option label="财务制度" value="finance" /> <el-option label="安全制度" value="safety" /> <el-option label="技术制度" value="tech" /> </el-select> </el-form-item> <el-form-item label="制度内容" prop="content"> <el-input v-model="regulationForm.content" type="textarea" :rows="10" placeholder="请输入制度详细内容" /> </el-form-item> <el-form-item label="制度版本" prop="version"> <el-input v-model="regulationForm.version" placeholder="请输入制度版本" /> </el-form-item> <el-form-item label="生效时间" prop="effectiveTime"> <el-date-picker v-model="regulationForm.effectiveTime" type="datetime" format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" placeholder="选择生效时间" style="width: 100%" /> </el-form-item> <el-form-item label="适用范围" prop="scope"> <el-checkbox-group v-model="regulationForm.scope"> <el-checkbox label="all">全体员工</el-checkbox> <el-checkbox label="manager">管理层</el-checkbox> <el-checkbox label="hr">人事部门</el-checkbox> <el-checkbox label="finance">财务部门</el-checkbox> <el-checkbox label="tech">技术部门</el-checkbox> </el-checkbox-group> </el-form-item> <el-form-item label="是否需要确认" prop="requireConfirm"> <el-switch v-model="regulationForm.requireConfirm" /> <span class="ml-10">开启后员工需要阅读确认</span> </el-form-item> </el-form> <template #footer> <span class="dialog-footer"> <el-button @click="showRegulationDialog = false">取消</el-button> <el-button type="primary" @click="submitRegulation">发布制度</el-button> </span> </template> </el-dialog> --> <!-- 用印详情对话框 --> <FormDialog v-model="showSealDetailDialog" @@ -204,81 +122,6 @@ </div> </FormDialog> <!-- 规章制度详情对话框 --> <FormDialog v-model="showRegulationDetailDialog" title="规章制度详情" :width="'800px'" @close="closeRegulationDetailDialog" @confirm="handleRegulationDetailConfirm" @cancel="closeRegulationDetailDialog" > <div v-if="currentRegulationDetail"> <el-descriptions :column="2" border> <el-descriptions-item label="制度编号">{{ currentRegulationDetail.id }}</el-descriptions-item> <el-descriptions-item label="制度标题">{{ currentRegulationDetail.title }}</el-descriptions-item> <el-descriptions-item label="分类">{{ getCategoryText(currentRegulationDetail.category) }}</el-descriptions-item> <el-descriptions-item label="版本">{{ currentRegulationDetail.version }}</el-descriptions-item> <el-descriptions-item label="发布人">{{ currentRegulationDetail.createUserName }}</el-descriptions-item> <el-descriptions-item label="发布时间">{{ currentRegulationDetail.createTime }}</el-descriptions-item> </el-descriptions> <div class="mt-20"> <h4>制度内容</h4> <div class="regulation-content">{{ currentRegulationDetail.content }}</div> </div> <!-- 如果tableData>0 显示 --> <div style="margin: 10px 0;" v-if="tableData && tableData.length > 0" > <el-button type="success" @click="resetForm(currentRegulationDetail)">确认查看</el-button> </div> </div> </FormDialog> <!-- 版本历史对话框 --> <FormDialog v-model="showVersionHistoryDialog" title="版本历史" :width="'800px'" @close="closeVersionHistoryDialog" @confirm="closeVersionHistoryDialog" @cancel="closeVersionHistoryDialog" > <el-table :data="versionHistory" style="width: 100%;margin-bottom: 10px"> <el-table-column prop="version" label="版本号" width="100" /> <el-table-column prop="updateTime" label="更新时间" width="180" /> <el-table-column prop="createUserName" label="更新人" width="120" /> <el-table-column prop="changeLog" label="变更说明"> <template #default="scope"> <el-tag :type="scope.row.status === 'active' ? 'success' : 'info'"> {{ scope.row.status === 'active' ? '生效中' : '已废止' }} </el-tag> </template> </el-table-column> </el-table> </FormDialog> <!-- 阅读状态对话框 --> <FormDialog v-model="showReadStatusDialog" title="阅读状态" :width="'800px'" @close="closeReadStatusDialog" @confirm="closeReadStatusDialog" @cancel="closeReadStatusDialog" > <el-table :data="readStatusList" style="width: 100%;margin-bottom: 10px"> <el-table-column prop="employee" label="员工姓名" width="120" /> <el-table-column prop="department" label="所属部门" width="150" /> <el-table-column prop="createTime" label="阅读时间" width="180" /> <el-table-column prop="confirmTime" label="确认时间" width="180" /> <el-table-column prop="status" label="状态" width="100"> <template #default="scope"> <el-tag :type="scope.row.status === 'confirmed' ? 'success' : 'warning'"> {{ scope.row.status === 'confirmed' ? '已确认' : '未确认' }} </el-tag> </template> </el-table-column> </el-table> </FormDialog> </div> </template> @@ -286,20 +129,13 @@ import { ref, reactive, onMounted, getCurrentInstance, watch } from 'vue' import { useRoute } from 'vue-router' import { ElMessage, ElMessageBox } from 'element-plus' import { Plus } from '@element-plus/icons-vue' import { listSealApplication, addSealApplication, updateSealApplication,listRuleManagement,addRuleManagement,updateRuleManagement,delRuleManagement,getReadingStatusByRuleId,getReadingStatusList,addReadingStatus,updateReadingStatus } from '@/api/collaborativeApproval/sealManagement.js' import { el } from 'element-plus/es/locales.mjs' import { getUserProfile, userListNoPageByTenantId } from '@/api/system/user.js' import { listSealApplication, addSealApplication, updateSealApplication } from '@/api/collaborativeApproval/sealManagement.js' import { userListNoPageByTenantId } from '@/api/system/user.js' import useUserStore from '@/store/modules/user' import { userLoginFacotryList } from "@/api/system/user.js" import {staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js" import FormDialog from '@/components/Dialog/FormDialog.vue' import PIMTable from '@/components/PIMTable/PIMTable.vue' // 响应式数据 const currentUser = ref(null) const activeTab = ref('seal') const operationType = ref('add') const tableData = ref([]) // 用印申请相关 const userStore = useUserStore() const route = useRoute() @@ -335,64 +171,11 @@ // 分页参数 const page = reactive({ current: 1, size: 100, size: 10, total: 0 }) // 规章制度相关 const showRegulationDialog = ref(false) const showRegulationDetailDialog = ref(false) const showVersionHistoryDialog = ref(false) const showReadStatusDialog = ref(false) const currentRegulationDetail = ref(null) const regulationFormRef = ref() const regulationForm = reactive({ id: '', regulationNum: '', title: '', category: '', content: '', version: '', status: 'active', readCount: 0, effectiveTime: '', scope: [], requireConfirm: false }) const readStatus = ref({ id: '', ruleId: '', employee: '', department: '', createTime: '', confirmTime: '', status: 'unconfirmed' }) const regulationRules = { title: [{ required: true, message: '请输入制度标题', trigger: 'blur' }], category: [{ required: true, message: '请选择制度分类', trigger: 'change' }], content: [{ required: true, message: '请输入制度内容', trigger: 'blur' }], effectiveTime: [{ required: true, message: '请选择生效时间', trigger: 'change' }], scope: [{ required: true, message: '请选择适用范围', trigger: 'change' }] } const regulationSearchForm = reactive({ title: '', category: '' }) // 假数据 const sealApplications = ref([]) const regulations = ref([]) const versionHistory = ref([]) const readStatusList = ref([]) // { employee: '陈志强', department: '销售部', readTime: '2025-01-11 10:30:00', confirmTime: '2025-01-11 10:35:00', status: 'confirmed' }, // { employee: '刘雅婷', department: '技术部', readTime: '2025-01-11 14:20:00', confirmTime: '', status: 'unconfirmed' }, // { employee: '王建国', department: '财务部', readTime: '2025-01-12 09:15:00', confirmTime: '2025-01-12 09:20:00', status: 'confirmed' } // 用印申请状态 const getStatusType = (status) => { @@ -403,7 +186,7 @@ } return statusMap[status] || 'info' } // 制度状态 // 用印申请状态文本 const getStatusText = (status) => { const statusMap = { pending: '待审批', @@ -418,20 +201,56 @@ official: '公章', contract: '合同专用章', finance: '财务专用章', legal: '法人章', tegal: '技术专用章' } return sealTypeMap[sealType] || '未知' } // 制度分类 const getCategoryText = (category) => { const categoryMap = { hr: '人事制度', finance: '财务制度', safety: '安全制度', tech: '技术制度' // 用印申请表格列配置(需在 getStatusText/getSealTypeText 等之后定义) const sealTableColumn = ref([ { label: '申请编号', prop: 'applicationNum',}, { label: '申请标题', prop: 'title', showOverflowTooltip: true }, { label: '申请人', prop: 'createUserName', }, { label: '所属部门', prop: 'department', width: 150 }, { label: '用印类型', prop: 'sealType', dataType: 'tag', formatData: (v) => getSealTypeText(v), formatType: () => 'info' }, { label: '申请时间', prop: 'createTime', width: 180 }, { label: '状态', prop: 'status', width: 100, dataType: 'tag', formatData: (v) => getStatusText(v), formatType: (v) => getStatusType(v) }, { dataType: 'action', label: '操作', width: 200, fixed: 'right', align: 'center', operation: [ { name: '查看', clickFun: (row) => viewSealDetail(row) }, { name: '审批', clickFun: (row) => approveSeal(row), showHide: (row) => row.status === 'pending' }, { name: '拒绝', clickFun: (row) => rejectSeal(row), showHide: (row) => row.status === 'pending' } ] } return categoryMap[category] || '未知' } ]) // 搜索印章申请 const searchSealApplications = () => { page.current=1 @@ -445,17 +264,6 @@ sealSearchForm.status = '' sealSearchForm.applicationNum = '' searchSealApplications() } // 搜索制度 const searchRegulations = () => { page.current=1 getRegulationList() } // 重置制度搜索 const resetRegulationSearch = () => { regulationSearchForm.title = '' regulationSearchForm.category = '' searchRegulations() } // 提交用印申请 const submitSealApplication = async () => { @@ -505,106 +313,6 @@ const closeSealDetailDialog = () => { showSealDetailDialog.value = false } // 关闭规章制度详情对话框 const closeRegulationDetailDialog = () => { showRegulationDetailDialog.value = false } // 处理规章制度详情确认 const handleRegulationDetailConfirm = () => { // 如果tableData>0,执行确认查看操作 if (currentRegulationDetail.value && tableData.value && tableData.value.length > 0) { resetForm(currentRegulationDetail.value) } closeRegulationDetailDialog() } // 关闭版本历史对话框 const closeVersionHistoryDialog = () => { showVersionHistoryDialog.value = false } // 关闭阅读状态对话框 const closeReadStatusDialog = () => { showReadStatusDialog.value = false } // 新增 const handleAdd = () => { operationType.value = 'add' resetRegulationForm() showRegulationDialog.value = true } // 编辑 const handleEdit = (row) => { operationType.value = 'edit' Object.assign(regulationForm, row) showRegulationDialog.value = true } // 废弃 const repealEdit = (row) => { operationType.value = 'edit' Object.assign(regulationForm, row) regulationForm.status = 'repealed' ElMessageBox.confirm('确认废弃该制度?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => { updateRuleManagement(regulationForm).then(res => { if(res.code == 200){ ElMessage.success('制度废弃成功') // showRegulationDialog.value = false getRegulationList() resetRegulationForm() } }) }).catch(() => { ElMessage({ type: 'info', message: '已取消废弃' }) }) } // 发布制度 const submitRegulation = async () => { try { await regulationFormRef.value.validate() if(operationType.value == 'add'){ addRuleManagement(regulationForm).then(res => { if(res.code == 200){ ElMessage.success('制度发布成功') showRegulationDialog.value = false getRegulationList() resetRegulationForm() } }) }else{ updateRuleManagement(regulationForm).then(res => { if(res.code == 200){ ElMessage.success('制度编辑成功') showRegulationDialog.value = false resetRegulationForm() getRegulationList() }})} }catch(err){ ElMessage.error(err.msg) } } //重置制度表单 const resetRegulationForm = () => { Object.assign(regulationForm, { id: '', regulationNum: '', title: '', category: '', content: '', version: '', status: 'active', readCount: 0, effectiveTime: '', scope: [], requireConfirm: false }) } // 查看用印申请详情 const viewSealDetail = (row) => { @@ -613,7 +321,6 @@ } // 审批用印申请 const approveSeal = (row) => { console.log(row) ElMessageBox.confirm('确认通过该用印申请?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', @@ -623,6 +330,7 @@ updateSealApplication(row).then(res => { if(res.code == 200){ ElMessage.success('审批通过') getSealApplicationList() } }) }) @@ -638,122 +346,10 @@ row.status = 'rejected' updateSealApplication(row).then(res => { if(res.code == 200){ ElMessage.success('审批拒绝') ElMessage.success('已拒绝申请') getSealApplicationList() } }) ElMessage.success('已拒绝申请') }) } // 获取在职员工列表 const getList = () => { tableLoading.value = true; //获取当前登录用户信息 getUserProfile().then(res => { if(res.code == 200){ console.log(res.data.userName) currentUser.value = res.data.userName } }) staffOnJobListPage({staffState: 1, ...page}).then(res => { tableLoading.value = false; // tableData.value = res.data.records // //筛选出和currentUser同名的人员 tableData.value = res.data.records.filter(item => item.staffName === currentUser.value) page.total = res.data.total; if(tableData.value.length == 0){ ElMessage.error('当前用户未加入任何部门') } }).catch(err => { tableLoading.value = false; }) }; // 查看制度版本历史 const viewVersionHistory = (row) => { showVersionHistoryDialog.value = true const params = { category: row.category } listRuleManagement(page,params).then(res => { if(res.code == 200){ versionHistory.value = res.data.records } }) } // 查看制度详情 const viewRegulation = (row) => { getList() currentRegulationDetail.value = row showRegulationDetailDialog.value = true getReadingStatusByRuleId(row.id).then(res => { if(res.code == 200){ readStatusList.value = res.data if(readStatusList.value.length==0 && tableData.value.length>0){ const params = { ruleId: row.id, employee: tableData.value[0].staffName, department: tableData.value[0].postJob, status: 'unconfirmed' } addReadingStatus(params).then(res => { if(res.code == 200){ ElMessage.success('制度阅读成功') } }) } } }) } // 查看制度阅读状态 const viewReadStatus = (row) => { showReadStatusDialog.value = true //查看阅读状态列表 getReadingStatusByRuleId(row.id).then(res => { if(res.code == 200){ readStatusList.value = res.data } }) } //确认查看 const resetForm = (row) => { console.log("row",row) row.readCount = row.readCount + 1 updateRuleManagement(row).then(res => { if(res.code == 200){ ElMessage.success('查看数量修改成功') //修改阅读状态 //根据制度id和当前登录的员工得到阅读状态 // let item = readStatusList.value.filter(item => item.employee == tableData.value[0].staffName ) // if(item.length>0){ // item[0].status = 'confirmed', // item[0].confirmTime = new Date().toISOString().replace('T', ' ').split('.')[0]; // } // 筛选当前员工对应该制度的阅读状态记录 let statusItem = readStatusList.value.find(item => item.employee === tableData.value[0].staffName && item.ruleId === row.id); if (statusItem) { // 如果找到记录,更新状态和确认时间 statusItem.status = 'confirmed'; // 格式化时间为"YYYY-MM-DD HH:mm:ss"格式 const now = new Date(); statusItem.confirmTime = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')} ${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}:${String(now.getSeconds()).padStart(2, '0')}`; // statusItem.confirmTime = new Date().toISOString().replace('T', ' ').split('.')[0]; updateReadingStatus(statusItem).then(res => { if(res.code == 200){ ElMessage.success('制度阅读状态修改成功') } }) } } }) } @@ -766,46 +362,15 @@ // 获取印章申请列表数据 const getSealApplicationList = async () => { tableLoading.value = true listSealApplication(page,sealSearchForm) listSealApplication(page, sealSearchForm) .then(res => { //获取当前登录的部门信息 // 获取当前登录的部门信息并过滤数据 const currentFactoryName = userStore.currentFactoryName if (currentFactoryName) { // 根据currentFactoryName过滤出department相同的数据 sealApplications.value = res.data.records.filter(item => item.department === currentFactoryName) // 更新过滤后的总数 page.total = sealApplications.value.length } else { // 如果没有currentFactoryName,则显示所有数据 sealApplications.value = res.data.records page.total = res.data.total } // sealApplications.value = res.data.records // page.value.total = res.data.total; tableLoading.value = false; sealApplications.value = res.data.records page.total = res.data.total tableLoading.value = false }).catch(err => { tableLoading.value = false; tableLoading.value = false }) } // 获取规章制度列表数据 const getRegulationList = async () => { tableLoading.value = true listRuleManagement(page,regulationSearchForm) .then(res => { regulations.value = res.data.records // 过滤掉已废弃的制度 // regulations.value = res.data.records.filter(item => item.status !== 'repealed') page.total = res.data.total; tableLoading.value = false; }).catch(err => { tableLoading.value = false; }) } // 分页变化处理 const paginationChange = (obj) => { page.current = obj.page; @@ -831,7 +396,6 @@ } else { getSealApplicationList() } getRegulationList() }) </script> @@ -854,26 +418,7 @@ margin-bottom: 20px; } .mt-20 { margin-top: 20px; } .ml-10 { margin-left: 10px; } .regulation-content { background-color: #f5f5f5; padding: 15px; border-radius: 4px; line-height: 1.6; white-space: pre-wrap; height: 200px; } .dialog-footer { display: flex; justify-content: flex-end; gap: 10px; } </style> src/views/index.vue
@@ -118,11 +118,11 @@ <div class="main-panel"> <div style="display: flex;justify-content: space-between;"> <div class="section-title">应收应付统计</div> <el-radio-group v-model="radio1" size="large" @change="statisticsReceivable"> <el-radio-button label="按周" :value="1" /> <el-radio-button label="按月" :value="2" /> <el-radio-button label="按季度" :value="3" /> </el-radio-group> <!-- <el-radio-group v-model="radio1" size="large" @change="statisticsReceivable">--> <!-- <el-radio-button label="按周" :value="1" />--> <!-- <el-radio-button label="按月" :value="2" />--> <!-- <el-radio-button label="按季度" :value="3" />--> <!-- </el-radio-group>--> </div> <Echarts ref="chart" :color="barColors2" src/views/procurementManagement/procurementLedger/index.vue
@@ -157,6 +157,10 @@ prop="entryDate" width="100" show-overflow-tooltip /> <el-table-column label="备注" prop="remarks" width="200" show-overflow-tooltip /> <el-table-column fixed="right" label="操作" width="120" @@ -450,8 +454,8 @@ <el-row :gutter="30"> <el-col :span="24"> <el-form-item label="备注·:" prop="remark"> <el-input v-model="form.remark" prop="remarks"> <el-input v-model="form.remarks" placeholder="请输入" clearable type="textarea" @@ -462,7 +466,7 @@ <el-row :gutter="30"> <el-col :span="24"> <el-form-item label="附件材料:" prop="remark"> prop="purchaseLedgerFiles"> <el-upload v-model:file-list="fileList" :action="upload.url" multiple src/views/productionManagement/productionOrder/index.vue
@@ -239,8 +239,9 @@ // 添加表行类名方法 const tableRowClassName = ({ row }) => { const diff = row.deliveryDaysDiff; if (row.isFh) return ''; const diff = row.deliveryDaysDiff; if (diff === 15) { return 'yellow'; } else if (diff === 10) { src/views/qualityManagement/finalInspection/components/formDia.vue
@@ -201,64 +201,91 @@ const openDialog = async (type, row) => { operationType.value = type; dialogFormVisible.value = true; getOptions().then((res) => { supplierList.value = res.data; }); let userLists = await userListNoPage(); userList.value = userLists.data; form.value = {} // 先清空表单验证状态,避免闪烁 await nextTick(); proxy.$refs.formRef?.clearValidate(); // 并行加载基础数据 const [userListsRes] = await Promise.all([ userListNoPage(), getProductOptions(), getOptions().then((res) => { supplierList.value = res.data; }) ]); userList.value = userListsRes.data; form.value = {} testStandardOptions.value = []; tableData.value = []; getProductOptions(); if (operationType.value === 'edit') { // 先保存 testStandardId,避免被清空 const savedTestStandardId = row.testStandardId; // 先设置表单数据,但暂时清空 testStandardId,等选项加载完成后再设置 form.value = {...row, testStandardId: ''} currentProductId.value = row.productId || 0 // 编辑模式下,先加载指标选项,然后加载参数列表 if (currentProductId.value) { // 先加载指标选项 let params = { productId: currentProductId.value, inspectType: 2 } qualityInspectDetailByProductId(params).then(res => { testStandardOptions.value = res.data || []; // 使用 nextTick 和 setTimeout 确保选项已经渲染到 DOM nextTick(() => { setTimeout(() => { // 如果编辑数据中有 testStandardId,则设置并加载对应的参数 if (savedTestStandardId) { // 确保类型匹配(item.id 可能是数字或字符串) const matchedOption = testStandardOptions.value.find(item => item.id == savedTestStandardId || String(item.id) === String(savedTestStandardId) ); if (matchedOption) { // 确保使用匹配项的 id(保持类型一致) form.value.testStandardId = matchedOption.id; // 编辑场景保留已有检验值,直接拉取原参数数据 getQualityInspectParamList(row.id); } else { // 如果找不到匹配项,尝试直接使用原值 console.warn('未找到匹配的指标选项,testStandardId:', savedTestStandardId, '可用选项:', testStandardOptions.value); form.value.testStandardId = savedTestStandardId; getQualityInspectParamList(row.id); } } else { // 否则使用旧的逻辑 getQualityInspectParamList(row.id); } }, 100); }); }); } else { getQualityInspectParamList(row.id); } currentProductId.value = row.productId || 0 // 清空验证状态,避免数据加载过程中的校验闪烁 nextTick(() => { proxy.$refs.formRef?.clearValidate(); }); // 编辑模式下,并行加载规格型号和指标选项 if (currentProductId.value) { // 设置产品名称 form.value.productName = findNodeById(productOptions.value, currentProductId.value); // 并行加载规格型号和指标选项 const params = { productId: currentProductId.value, inspectType: 2 }; Promise.all([ modelList({ id: currentProductId.value }), qualityInspectDetailByProductId(params) ]).then(([modelRes, testStandardRes]) => { // 设置规格型号选项 modelOptions.value = modelRes || []; // 如果表单中已有 productModelId,设置对应的 model 和 unit if (form.value.productModelId && modelOptions.value.length > 0) { const selectedModel = modelOptions.value.find(item => item.id == form.value.productModelId); if (selectedModel) { form.value.model = selectedModel.model || ''; form.value.unit = selectedModel.unit || ''; } } // 设置指标选项 testStandardOptions.value = testStandardRes.data || []; // 设置 testStandardId 并加载参数列表 nextTick(() => { if (savedTestStandardId) { // 确保类型匹配(item.id 可能是数字或字符串) const matchedOption = testStandardOptions.value.find(item => item.id == savedTestStandardId || String(item.id) === String(savedTestStandardId) ); if (matchedOption) { // 确保使用匹配项的 id(保持类型一致) form.value.testStandardId = matchedOption.id; } else { // 如果找不到匹配项,尝试直接使用原值 console.warn('未找到匹配的指标选项,testStandardId:', savedTestStandardId, '可用选项:', testStandardOptions.value); form.value.testStandardId = savedTestStandardId; } } // 编辑场景保留已有检验值,直接拉取原参数数据 getQualityInspectParamList(row.id); }); }); } else { getQualityInspectParamList(row.id); } } } const getProductOptions = () => { productTreeList().then((res) => { return productTreeList().then((res) => { productOptions.value = convertIdToValue(res); }); }; src/views/qualityManagement/finalInspection/index.vue
@@ -96,6 +96,11 @@ width: 120 }, { label: "生产工单号", prop: "workOrderNo", width: 120 }, { label: "检验员", prop: "checkName", }, src/views/qualityManagement/processInspection/index.vue
@@ -96,6 +96,11 @@ width: 120 }, { label: "生产工单号", prop: "workOrderNo", width: 120 }, { label: "工序", prop: "process", width: 230 src/views/qualityManagement/rawMaterialInspection/index.vue
@@ -98,6 +98,11 @@ width: 120 }, { label: "采购订单号", prop: "purchaseContractNo", width: 120 }, { label: "供应商", prop: "supplier", width: 230 src/views/reportAnalysis/productionAnalysis/components/right-top.vue
@@ -2,25 +2,16 @@ <div> <PanelHeader title="工单执行效率分析" /> <div class="main-panel panel-item-customers"> <Echarts ref="chart" :chartStyle="chartStyle" :grid="grid" :legend="barLegend" :series="chartSeries" :tooltip="tooltip" :xAxis="xAxis1" :yAxis="yAxis1" :options="{ backgroundColor: 'transparent', textStyle: { color: '#B8C8E0' } }" style="height: 260px" /> <Echarts ref="chart" :chartStyle="chartStyle" :grid="grid" :legend="barLegend" :series="chartSeries" :tooltip="tooltip" :xAxis="xAxis1" :yAxis="yAxis1" :options="{ backgroundColor: 'transparent', textStyle: { color: '#B8C8E0' } }" style="height: 260px" /> </div> </div> </template> <script setup> import { ref, onMounted } from 'vue' import { qualityStatistics } from '@/api/viewIndex.js' import { workOrderEfficiencyAnalysis } from '@/api/viewIndex.js' import PanelHeader from './PanelHeader.vue' import Echarts from '@/components/Echarts/echarts.vue' @@ -37,7 +28,6 @@ data: ['开工', '完成', '良品率'], } // 柱状图:开工、完成;折线图:良品率(颜色 rgba(90, 216, 166, 1)) const chartSeries = ref([ { name: '开工', @@ -111,6 +101,7 @@ const xAxis1 = ref([ { type: 'category', axisTick: { show: false }, axisLabel: { color: '#B8C8E0' }, data: [] }, ]) const yAxis1 = [ { type: 'value', name: '件', axisLabel: { color: '#B8C8E0' }, nameTextStyle: { color: '#B8C8E0' } }, { @@ -125,25 +116,23 @@ ] const fetchData = () => { qualityStatistics() workOrderEfficiencyAnalysis() .then((res) => { if (!res?.data?.item || !Array.isArray(res.data.item)) return const items = res.data.item xAxis1.value[0].data = items.map((d) => d.date) // 开工:过程检验数 chartSeries.value[0].data = items.map((d) => Number(d.processNum) || 0) // 完成:出厂数 chartSeries.value[1].data = items.map((d) => Number(d.factoryNum) || 0) // 良品率:出厂数/过程数*100(无单独接口时用此占位) chartSeries.value[2].data = items.map((d) => { const processNum = Number(d.processNum) || 0 const factoryNum = Number(d.factoryNum) || 0 if (processNum <= 0) return 0 return Math.min(100, Math.round((factoryNum / processNum) * 100)) }) // 根据你的结构,数据直接在 res.data 中 if (!res?.data || !Array.isArray(res.data)) return const list = res.data xAxis1.value[0].data = list.map((item) => item.date) chartSeries.value[0].data = list.map((item) => Number(item.startQuantity) || 0) chartSeries.value[1].data = list.map((item) => Number(item.finishQuantity) || 0) chartSeries.value[2].data = list.map((item) => Number(item.yieldRate) || 0) }) .catch((err) => { console.error('获取开工与良品率数据失败:', err) console.error('获取工单效率数据失败:', err) }) } src/views/safeProduction/dangerInvestigation/index.vue
@@ -111,13 +111,13 @@ </el-table-column> <el-table-column fixed="right" label="操作" min-width="250" min-width="150" align="center"> <template #default="scope"> <el-button link <!-- <el-button link type="primary" size="small" @click="openForm('edit', scope.row)">编辑</el-button> @click="openForm('edit', scope.row)">编辑</el-button> --> <el-button link type="primary" size="small" @@ -125,12 +125,12 @@ <el-button link type="primary" size="small" :disabled="scope.row.isRectify" :disabled="scope.row.isRectify || scope.row.rectifyActualTime" @click="openForm('edit2', scope.row)">整改</el-button> <el-button link type="primary" size="small" :disabled="!scope.row.rectifyActualTime" :disabled="!scope.row.rectifyActualTime || scope.row.verifyTime" @click="openForm('edit3', scope.row)">验收</el-button> </template> </el-table-column> src/views/salesManagement/salesLedger/index.vue
@@ -118,6 +118,7 @@ <el-table-column label="录入日期" prop="entryDate" width="120" show-overflow-tooltip /> <el-table-column label="签订日期" prop="executionDate" width="120" show-overflow-tooltip /> <el-table-column label="交付日期" prop="deliveryDate" width="120" show-overflow-tooltip /> <el-table-column label="备注" prop="remarks" width="200" show-overflow-tooltip /> <el-table-column fixed="right" label="操作" min-width="100" align="center"> <template #default="scope"> <el-button link type="primary" size="small" @click="openForm('edit', scope.row)">编辑</el-button> @@ -242,14 +243,14 @@ </el-table> <el-row :gutter="30"> <el-col :span="24"> <el-form-item label="备注·:" prop="remark"> <el-input v-model="form.remark" placeholder="请输入" clearable type="textarea" :rows="2" :disabled="operationType === 'view'" /> <el-form-item label="备注:" prop="remarks"> <el-input v-model="form.remarks" placeholder="请输入" clearable type="textarea" :rows="2" :disabled="operationType === 'view'" /> </el-form-item> </el-col> </el-row> <el-row :gutter="30"> <el-col :span="24"> <el-form-item label="附件材料:" prop="remark"> <el-form-item label="附件材料:" prop="salesLedgerFiles"> <el-upload v-model:file-list="fileList" :action="upload.url" multiple ref="fileUpload" auto-upload :headers="upload.headers" :before-upload="handleBeforeUpload" :on-error="handleUploadError" :on-success="handleUploadSuccess" :on-remove="handleRemove"> @@ -1004,8 +1005,9 @@ // 添加表行类名方法 const tableRowClassName = ({ row }) => { const diff = row.deliveryDaysDiff; if (row.isFh) return ''; const diff = row.deliveryDaysDiff; if (diff === 15) { return 'yellow'; } else if (diff === 10) { src/views/salesManagement/salesQuotation/index.vue
@@ -231,43 +231,52 @@ <el-table :data="form.products" border style="width: 100%" class="product-table" v-if="form.products.length > 0"> <el-table-column prop="product" label="产品名称" width="200"> <template #default="scope"> <el-tree-select v-model="scope.row.productId" placeholder="请选择" clearable check-strictly @change="getModels($event, scope.row)" :data="productOptions" :render-after-expand="false" style="width: 100%" /> <el-form-item :prop="`products.${scope.$index}.productId`" class="product-table-form-item"> <el-tree-select v-model="scope.row.productId" placeholder="请选择" clearable check-strictly @change="getModels($event, scope.row)" :data="productOptions" :render-after-expand="false" style="width: 100%" /> </el-form-item> </template> </el-table-column> <el-table-column prop="specification" label="规格型号" width="150"> <el-table-column prop="specification" label="规格型号" width="200"> <template #default="scope"> <el-select v-model="scope.row.specificationId" placeholder="请选择" clearable @change="getProductModel($event, scope.row)" > <el-option v-for="item in scope.row.modelOptions || []" :key="item.id" :label="item.model" :value="item.id" /> </el-select> <el-form-item :prop="`products.${scope.$index}.specificationId`" class="product-table-form-item"> <el-select v-model="scope.row.specificationId" placeholder="请选择" clearable @change="getProductModel($event, scope.row)" style="width: 100%" > <el-option v-for="item in scope.row.modelOptions || []" :key="item.id" :label="item.model" :value="item.id" /> </el-select> </el-form-item> </template> </el-table-column> <el-table-column prop="unit" label="单位"> <template #default="scope"> <el-input v-model="scope.row.unit" placeholder="单位" /> <el-form-item :prop="`products.${scope.$index}.unit`" class="product-table-form-item"> <el-input v-model="scope.row.unit" placeholder="单位" clearable/> </el-form-item> </template> </el-table-column> <el-table-column prop="unitPrice" label="单价"> <template #default="scope"> <el-input-number v-model="scope.row.unitPrice" :min="0" :precision="2" style="width: 100%" /> <el-form-item :prop="`products.${scope.$index}.unitPrice`" class="product-table-form-item"> <el-input-number v-model="scope.row.unitPrice" :min="0" :precision="2" style="width: 100%" /> </el-form-item> </template> </el-table-column> <el-table-column label="操作" width="80" align="center"> @@ -393,13 +402,30 @@ totalAmount: 0 }) const rules = { const baseRules = { customer: [{ required: true, message: '请选择客户', trigger: 'change' }], salesperson: [{ required: true, message: '请选择业务员', trigger: 'change' }], quotationDate: [{ required: true, message: '请选择报价日期', trigger: 'change' }], validDate: [{ required: true, message: '请选择有效期', trigger: 'change' }], paymentMethod: [{ required: true, message: '请输入付款方式', trigger: 'blur' }] } const productRowRules = { productId: [{ required: true, message: '请选择产品名称', trigger: 'change' }], specificationId: [{ required: true, message: '请选择规格型号', trigger: 'change' }], unit: [{ required: true, message: '请填写单位', trigger: 'blur' }], unitPrice: [{ required: true, message: '请填写单价', trigger: 'change' }] } const rules = computed(() => { const r = { ...baseRules } ;(form.products || []).forEach((_, i) => { r[`products.${i}.productId`] = productRowRules.productId r[`products.${i}.specificationId`] = productRowRules.specificationId r[`products.${i}.unit`] = productRowRules.unit r[`products.${i}.unitPrice`] = productRowRules.unitPrice }) return r }) const userList = ref([]); const customerOption = ref([]); @@ -774,7 +800,7 @@ ElMessage.warning('请至少添加一个产品') return } // 审批人必填校验 const hasEmptyApprover = approverNodes.value.some(node => !node.userId) if (hasEmptyApprover) { @@ -956,6 +982,17 @@ padding: 8px 0; } .product-table-form-item { margin-bottom: 0; :deep(.el-form-item__content) { margin-left: 0 !important; } :deep(.el-form-item__label) { width: auto; min-width: auto; } } .approver-nodes-container { display: flex; flex-wrap: wrap;