From 03b3624455b2f3a495ebb34349080e3bd35faff9 Mon Sep 17 00:00:00 2001
From: zhouwx <1175765986@qq.com>
Date: 星期二, 19 八月 2025 14:19:40 +0800
Subject: [PATCH] 修改
---
public/purchaseRequisitionExample.docx | 0
public/qualityOrganizeExample.docx | 0
src/api/standardSys/standardSys.js | 34
src/views/work/procurementPlatform/purchaseContract/index.vue | 266 ++
src/views/work/onlineEducation/offlineEducation/components/recordDialog.vue | 2
src/views/work/onlineEducation/offlineEducation/index.vue | 2
src/views/build/conpanyFunctionConsult/digitalFileDep/manageType/qualityOrganize/components/editDialog.vue | 392 ++++
src/views/work/qualityInfo/supplierQuality/satisfiedEvaluste/report/index.vue | 271 +++
src/views/work/procurementPlatform/incomingInspection/inspectionRecords/index.vue | 260 ++
src/views/work/qualityInfo/supplierQuality/satisfiedEvaluste/research/index.vue | 270 +++
src/views/work/procurementPlatform/purchaseRequisition/index.vue | 286 +++
src/views/work/procurementPlatform/purchaseRequisition/components/editDialog.vue | 500 +++++
src/views/work/procurementPlatform/incomingInspection/inspectionStandards/index.vue | 267 +++
src/views/work/qualityInfo/supplierQuality/satisfiedEvaluste/deliver/index.vue | 270 +++
src/views/work/qualityInfo/supplierQuality/satisfiedEvaluste/deliver/components/editDialog.vue | 391 ++++
public/recordsExample.docx | 0
src/views/work/procurementPlatform/incomingInspection/inspectionRecords/components/editDialog.vue | 348 +++
src/api/procurementPlatform/procurementPlatform.js | 129 +
src/views/build/conpanyFunctionConsult/digitalFileDep/manageType/qualityOrganize/index.vue | 299 +++
src/views/work/procurementPlatform/purchaseContract/components/editDialog.vue | 215 ++
src/views/work/qualityInfo/supplierQuality/satisfiedEvaluste/report/components/editDialog.vue | 390 ++++
src/views/work/procurementPlatform/incomingInspection/inspectionStandards/components/editDialog.vue | 215 ++
src/views/work/qualityInfo/supplierQuality/satisfiedEvaluste/research/components/editDialog.vue | 409 ++++
src/api/satisfiedNew/satisfiedNew.js | 100 +
24 files changed, 5,313 insertions(+), 3 deletions(-)
diff --git a/public/purchaseRequisitionExample.docx b/public/purchaseRequisitionExample.docx
new file mode 100644
index 0000000..2b012bb
--- /dev/null
+++ b/public/purchaseRequisitionExample.docx
Binary files differ
diff --git a/public/qualityOrganizeExample.docx b/public/qualityOrganizeExample.docx
new file mode 100644
index 0000000..a1d3929
--- /dev/null
+++ b/public/qualityOrganizeExample.docx
Binary files differ
diff --git a/public/recordsExample.docx b/public/recordsExample.docx
new file mode 100644
index 0000000..fe38604
--- /dev/null
+++ b/public/recordsExample.docx
Binary files differ
diff --git a/src/api/procurementPlatform/procurementPlatform.js b/src/api/procurementPlatform/procurementPlatform.js
new file mode 100644
index 0000000..786064e
--- /dev/null
+++ b/src/api/procurementPlatform/procurementPlatform.js
@@ -0,0 +1,129 @@
+import request from "@/utils/request";
+
+//采购申请
+export function getApply(params) {
+ return request({
+ url: '/purchase/audit/apply/list',
+ method: 'get',
+ params: params
+ })
+}
+
+export function addApply(data) {
+ return request({
+ url: '/purchase/audit/apply/insert',
+ method: 'post',
+ data: data
+ })
+}
+
+export function editApply(params) {
+ return request({
+ url: `/purchase/audit/apply/update`,
+ method: 'post',
+ data: params
+ })
+}
+
+export function delApply(data) {
+ return request({
+ url: `/purchase/audit/apply/deleted?applyId=${data}`,
+ method: 'get'
+ })
+}
+
+//采购合同
+export function getContract(params) {
+ return request({
+ url: '/purchase/audit/contract/list',
+ method: 'get',
+ params: params
+ })
+}
+
+export function addContract(data) {
+ return request({
+ url: '/purchase/audit/contract/insert',
+ method: 'post',
+ data: data
+ })
+}
+
+export function editContract(params) {
+ return request({
+ url: `/purchase/audit/contract/update`,
+ method: 'post',
+ data: params
+ })
+}
+
+export function delContract(data) {
+ return request({
+ url: `purchase/audit/contract/deleted?contractId=${data}`,
+ method: 'get'
+ })
+}
+
+//检验规范
+export function getStandard(params) {
+ return request({
+ url: '/purchase/audit/specification/list',
+ method: 'get',
+ params: params
+ })
+}
+
+export function addStandard(data) {
+ return request({
+ url: '/purchase/audit/specification/insert',
+ method: 'post',
+ data: data
+ })
+}
+
+export function editStandard(params) {
+ return request({
+ url: `/purchase/audit/specification/update`,
+ method: 'post',
+ data: params
+ })
+}
+
+export function delStandard(data) {
+ return request({
+ url: `/purchase/audit/specification/deleted?specificationId=${data}`,
+ method: 'get'
+ })
+}
+
+//检验记录
+export function getRecord(params) {
+ return request({
+ url: '/purchase/audit/record/list',
+ method: 'get',
+ params: params
+ })
+}
+
+export function addRecord(data) {
+ return request({
+ url: '/purchase/audit/record/insert',
+ method: 'post',
+ data: data
+ })
+}
+
+export function editRecord(params) {
+ return request({
+ url: `/purchase/audit/record/update`,
+ method: 'post',
+ data: params
+ })
+}
+
+export function delRecord(data) {
+ return request({
+ url: `/purchase/audit/record/deleted?recordId=${data}`,
+ method: 'get'
+ })
+}
diff --git a/src/api/satisfiedNew/satisfiedNew.js b/src/api/satisfiedNew/satisfiedNew.js
new file mode 100644
index 0000000..419c896
--- /dev/null
+++ b/src/api/satisfiedNew/satisfiedNew.js
@@ -0,0 +1,100 @@
+import request from "@/utils/request";
+
+//在研项目
+export function getResearch(params) {
+ return request({
+ url: '/internal/audit/research/list',
+ method: 'get',
+ params: params
+ })
+}
+
+export function addResearch(data) {
+ return request({
+ url: '/internal/audit/research/insert',
+ method: 'post',
+ data: data
+ })
+}
+
+export function editResearch(params) {
+ return request({
+ url: `/internal/audit/research/update`,
+ method: 'post',
+ data: params
+ })
+}
+
+export function delResearch(data) {
+ return request({
+ url: `/internal/audit/research/deleted?researchId=${data}`,
+ method: 'get'
+ })
+}
+
+
+//交付项目
+export function getDelivery(params) {
+ return request({
+ url: '/internal/audit/delivery/list',
+ method: 'get',
+ params: params
+ })
+}
+
+export function addDelivery(data) {
+ return request({
+ url: '/internal/audit/delivery/insert',
+ method: 'post',
+ data: data
+ })
+}
+
+export function editDelivery(params) {
+ return request({
+ url: `/internal/audit/delivery/update`,
+ method: 'post',
+ data: params
+ })
+}
+
+export function delDelivery(data) {
+ return request({
+ url: `/internal/audit/delivery/deleted?deliveryId=${data}`,
+ method: 'get'
+ })
+}
+
+//年度报告
+export function getReport(params) {
+ return request({
+ url: '/internal/audit/annual/list',
+ method: 'get',
+ params: params
+ })
+}
+
+export function addReport(data) {
+ return request({
+ url: '/internal/audit/annual/insert',
+ method: 'post',
+ data: data
+ })
+}
+
+export function editReport(params) {
+ return request({
+ url: `/internal/audit/annual/update`,
+ method: 'post',
+ data: params
+ })
+}
+
+export function delReport(data) {
+ return request({
+ url: `/internal/audit/annual/deleted?annualId=${data}`,
+ method: 'get'
+ })
+}
+
+
diff --git a/src/api/standardSys/standardSys.js b/src/api/standardSys/standardSys.js
index fb192d8..5a924e0 100644
--- a/src/api/standardSys/standardSys.js
+++ b/src/api/standardSys/standardSys.js
@@ -62,4 +62,36 @@
method: 'get',
params: params
})
-}
\ No newline at end of file
+}
+
+//质量体系策划
+export function getQualityTemplate(params) {
+ return request({
+ url: '/template/list',
+ method: 'get',
+ params: params
+ })
+}
+
+export function addQualityTemplate(data) {
+ return request({
+ url: '/template/insert',
+ method: 'post',
+ data: data
+ })
+}
+
+export function editQualityTemplate(params) {
+ return request({
+ url: `/template/update`,
+ method: 'post',
+ data: params
+ })
+}
+
+export function delQualityTemplate(data) {
+ return request({
+ url: `/template/deleted?planId=${data}`,
+ method: 'get'
+ })
+}
diff --git a/src/views/build/conpanyFunctionConsult/digitalFileDep/manageType/qualityOrganize/components/editDialog.vue b/src/views/build/conpanyFunctionConsult/digitalFileDep/manageType/qualityOrganize/components/editDialog.vue
new file mode 100644
index 0000000..53c3ed4
--- /dev/null
+++ b/src/views/build/conpanyFunctionConsult/digitalFileDep/manageType/qualityOrganize/components/editDialog.vue
@@ -0,0 +1,392 @@
+<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.rules" >
+ <el-row :gutter="24">
+ <el-col :span="24">
+ <el-form-item label="企业名称:" prop="companyId" v-if="state.isAdmin">
+ <el-select v-model="state.form.companyId" placeholder="请选择" filterable clearable style="width: 100%" :disabled="title == '查看' || title == '编辑' || !state.isAdmin" @change="selectValueCom">
+ <el-option
+ v-for="item in state.companyList"
+ :key="item.id"
+ :label="item.name"
+ :value="item.id">
+ </el-option>
+ </el-select>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="24">
+ <el-col :span="24">
+ <el-form-item label="年份:" prop="year" >
+ <el-select
+ v-model="state.form.year"
+ placeholder="请选择年份"
+ :disabled="title === '查看'"
+ style="width: 100%"
+ filterable
+ allow-create
+ default-first-option
+ :reserve-keyword="false"
+ @change="handleChangeNum"
+ >
+ <el-option
+ v-for="item in state.yearList"
+ :key="item.value"
+ :label="item.label"
+ :value="item.label"
+ />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="24">
+ <el-col :span="24">
+ <div style="display: flex;align-items: center;margin-bottom: 10px">
+ <span style="font-size: 15px;font-weight: 700;" >质量管理体系工作策划安排及完成情况:</span>
+ <el-button
+ :disabled="title === '查看'"
+ type="primary"
+ @click="addTableData"
+ style="margin-left: 20px"
+ >新增</el-button>
+ </div>
+ <el-table :data="state.form.planMesses" style="margin-bottom: 15px" :border="true" >
+ <el-table-column type="index" label="序号" align="center"></el-table-column>
+ <el-table-column label="项目" prop="project" align="center" width="150">
+ <template #default="{row,$index}">
+ <el-form-item :prop="'planMesses.' + '[' + $index + ']' + '.project'" :rules="state.rules.project">
+ <el-input style="margin-top: 10px" :disabled="title === '查看'" :rows="4" type="textarea" v-model="row.project" placeholder="请输入"></el-input>
+ </el-form-item>
+ </template>
+ </el-table-column>
+ <el-table-column label="内容" prop="content" align="center" width="150">
+ <template #default="{row,$index}">
+ <el-form-item :prop="'planMesses.' + '[' + $index + ']' + '.content'" :rules="state.rules.content">
+ <el-input style="margin-top: 10px" :disabled="title === '查看'" :rows="4" type="textarea" v-model="row.content" placeholder="请输入"></el-input>
+ </el-form-item>
+ </template>
+ </el-table-column>
+ <el-table-column label="参加人员" prop="participant" align="center" width="150">
+ <template #default="{row,$index}">
+ <el-form-item :prop="'planMesses.' + '[' + $index + ']' + '.participant'" :rules="state.rules.participant">
+ <el-input style="margin-top: 10px" :disabled="title === '查看'" :rows="4" type="textarea" v-model="row.participant" placeholder="请输入"></el-input>
+ </el-form-item>
+ </template>
+ </el-table-column>
+ <el-table-column label="时间" prop="applyTime" align="center" width="150">
+ <template #default="{row,$index}">
+ <el-form-item :prop="'planMesses.' + '[' + $index + ']' + '.applyTime'" :rules="state.rules.applyTime">
+ <el-input style="margin-top: 10px" :disabled="title === '查看'" :rows="4" type="textarea" v-model="row.applyTime" placeholder="请输入"></el-input>
+ </el-form-item>
+ </template>
+ </el-table-column>
+ <el-table-column label="完成时间" prop="accomplishTime" align="center" width="150">
+ <template #default="{row,$index}">
+ <el-form-item :prop="'planMesses.' + '[' + $index + ']' + '.accomplishTime'" :rules="state.rules.accomplishTime">
+ <el-input style="margin-top: 10px" :disabled="title === '查看'" :rows="4" type="textarea" v-model="row.accomplishTime" placeholder="请输入"></el-input>
+ </el-form-item>
+ </template>
+ </el-table-column>
+ <el-table-column label="完成情况" prop="accomplishStatus" align="center" width="150">
+ <template #default="{row,$index}">
+ <el-form-item :prop="'planMesses.' + '[' + $index + ']' + '.accomplishStatus'" :rules="state.rules.accomplishStatus">
+ <el-input style="margin-top: 10px" :disabled="title === '查看'" :rows="4" type="textarea" v-model="row.accomplishStatus" placeholder="请输入"></el-input>
+ </el-form-item>
+ </template>
+ </el-table-column>
+ <el-table-column label="操作" align="center" v-if="title !== '查看'" >
+ <template #default="scope">
+ <el-button link type="danger" @click="delTableData(scope.row)" >删除</el-button>
+ </template>
+ </el-table-column>
+ </el-table>
+ </el-col>
+ </el-row>
+ <el-row :gutter="24">
+ <el-col :span="24">
+ <el-form-item label="编制:" prop="writeId" >
+ <el-select clearable v-model="state.form.writeId" :disabled="title =='查看'" filterable style="width: 240px">
+ <el-option
+ v-for="item in state.peopleList"
+ :key="item.id"
+ :label="item.name"
+ :value="item.id"
+ />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="24">
+ <el-col :span="24">
+ <el-form-item label="审核:" prop="checkId" >
+ <el-select clearable v-model="state.form.checkId" :disabled="title =='查看'" filterable style="width: 240px">
+ <el-option
+ v-for="item in state.peopleList"
+ :key="item.id"
+ :label="item.name"
+ :value="item.id"
+ />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="24">
+ <el-col :span="24">
+ <el-form-item label="批准:" prop="ratifyId" >
+ <el-select clearable v-model="state.form.ratifyId" :disabled="title =='查看'" filterable style="width: 240px">
+ <el-option
+ v-for="item in state.peopleList"
+ :key="item.id"
+ :label="item.name"
+ :value="item.id"
+ />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ </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 {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";
+import {getDept, getObject, getObjectPage} from "@/api/qualityObjectives/object";
+import {addTable, editTable, getTargetById} from "@/api/qualityObjectives/table";
+import {addNeedDiscren, editNeedDiscren} from "@/api/need/need";
+import {addQualityTemplate, editQualityTemplate} from "@/api/standardSys/standardSys";
+
+const dialogVisible = ref(false);
+const title = ref("");
+const busRef = ref();
+const length = ref()
+const selectPopperClass = "max-width-select";
+const emit = defineEmits(["getList"]);
+const dataRef = ref();
+const state = reactive({
+ form: {
+ id: '',
+ companyId: null,
+ year: '',
+ writeId: null,
+ checkId: null,
+ ratifyId: null,
+ planMesses:[],
+ },
+ rules: {
+ companyId: [{ required: true, message: '请选择企业', trigger: 'blur' }],
+ year: [{ required: true, message: '请选择年份', trigger: 'blur' }],
+ writeId: [{ required: true, message: '请选择编制人', trigger: 'blur' }],
+ ratifyId: [{ required: true, message: '请选择批准人', trigger: 'blur' }],
+ checkId: [{ required: true, message: '请选择审核人', trigger: 'blur' }],
+ project: [{required: true, message: "", trigger: "blur"}],
+ content: [{required: true, message: "", trigger: "blur"}],
+ participant: [{required: true, message: "", trigger: "blur"}],
+ applyTime: [{required: true, message: "", trigger: "blur"}],
+ accomplishTime: [{required: true, message: "", trigger: "blur"}],
+ accomplishStatus: [{required: true, message: "", trigger: "blur"}],
+ planMesses:[{ required: true, message: '请填写质量管理体系工作策划安排及完成情况表', trigger: 'blur' }],
+ },
+ peopleList: [],
+ isAdmin: false,
+ companyList: [],
+ deptList: [],
+ yearList: [
+ {
+ value: 1,
+ label: '2025'
+ },
+ {
+ value: 2,
+ label: '2024'
+ },
+ {
+ value: 3,
+ label: '2023'
+ },
+ {
+ value: 4,
+ label: '2022'
+ },
+ {
+ value: 5,
+ label: '2021'
+ },
+ ],
+})
+
+onMounted(() => {
+
+
+});
+const openDialog = async (type, value,companyList) => {
+ const userInfo = JSON.parse(Cookies.get('userInfo'))
+ state.isAdmin = userInfo.userType === 0;
+ state.form.companyName = userInfo.companyName
+ state.form.companyId = userInfo.companyId
+ if(state.isAdmin){
+ state.form.companyId = value.companyId
+ state.form.companyName = value.companyName
+ state.companyList = companyList
+ }
+ title.value = type === 'add' ? '新增' : type ==='edit' ? '编辑' : '查看' ;
+ if(type === 'edit' || type === 'review') {
+ state.form = JSON.parse(JSON.stringify(value));
+
+ if(state.isAdmin){
+ state.form.companyId = value.companyId
+ state.form.companyName = value.companyName
+ }
+ }
+ await getPeopleList()
+ dialogVisible.value = true;
+}
+
+
+const onSubmit = async () => {
+ if(state.form.planMesses && state.form.planMesses.length == 0){
+ ElMessage.warning('请填写质量管理体系工作策划安排及完成情况')
+ return
+ }
+ 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 addQualityTemplate(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 === '编辑'){
+ state.form.planMesses.forEach(item => {
+ item.planId = state.form.id
+ })
+ const {...data} = JSON.parse(JSON.stringify(state.form))
+ const res = await editQualityTemplate(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: '',
+ companyId: null,
+ year: '',
+ writeId: null,
+ checkId: null,
+ ratifyId: null,
+ planMesses:[],
+ }
+ state.peopleList = []
+ state.companyList = []
+}
+const getPeopleList = async ()=> {
+ if(state.isAdmin && (state.form.companyId == 0 || state.form.companyId == null)){
+ return
+ }
+ const queryParams = {
+ pageNum: 1,
+ pageSize: 9999,
+ companyId: state.form.companyId
+ }
+ const res = await getUser(queryParams)
+ if(res.code == 200){
+ state.peopleList = res.data.list?res.data.list:[]
+ }else{
+ ElMessage.warning(res.message)
+ }
+};
+
+
+
+
+const selectValueCom = (val) => {
+ state.form.writeId = null
+ state.form.checkId = null
+ state.form.ratifyId = null
+ state.companyList.forEach(item => {
+ if(item.name === val){
+ state.form.companyId = item.id
+ }
+ })
+ getPeopleList()
+}
+
+const handleChangeNum = (value) => {
+ if (!/^\d+$/.test(value)) { // 验证是否为数字
+ ElMessage.warning('只能输入数字')
+ state.form.year = '' // 重置选择,避免非法值被添加到options中
+ } else if (!state.yearList.some(option => option.label === value)) { // 确保不是已存在的选项
+ state.yearList.push({ value, label: value }); // 添加新选项(这里简单地将值和标签设为相同)
+ }
+}
+const addTableData = () => {
+ state.form.planMesses.push({})
+}
+const delTableData = (val) => {
+ state.form.planMesses = state.form.planMesses.filter(item=> item != val)
+}
+
+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/digitalFileDep/manageType/qualityOrganize/index.vue b/src/views/build/conpanyFunctionConsult/digitalFileDep/manageType/qualityOrganize/index.vue
new file mode 100644
index 0000000..e8190ef
--- /dev/null
+++ b/src/views/build/conpanyFunctionConsult/digitalFileDep/manageType/qualityOrganize/index.vue
@@ -0,0 +1,299 @@
+<template>
+ <div class="app-container">
+ <div style="margin-bottom: 10px">
+ <el-form style="display: flex;flex-wrap: wrap;">
+ <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.companyId" placeholder="请选择" filterable clearable>
+ <el-option
+ v-for="item in data.companyList"
+ :key="item.id"
+ :label="item.name"
+ :value="item.id">
+ </el-option>
+ </el-select>
+ </el-form-item>
+ <el-form-item label="年份:" style="margin-left: 20px">
+ <el-select
+ v-model="data.queryParams.year"
+ placeholder="请选择年份"
+ style="width: 240px"
+ filterable
+ allow-create
+ default-first-option
+ :reserve-keyword="false"
+ @change="handleChangeNum"
+ >
+ <el-option
+ v-for="item in data.yearList"
+ :key="item.value"
+ :label="item.label"
+ :value="item.label"
+ />
+ </el-select>
+ </el-form-item>
+ <el-form-item>
+ <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" >
+ <template #default="scope">
+ <span>{{scope.row.year}}年度{{scope.row.companyName}}质量管理体系工作策划安排及完成情况</span>
+ </template>
+ </el-table-column>
+ <el-table-column label="操作" align="center" class-naame="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>
+ <editDialog ref="noticeRef" @getList = "getList"></editDialog>
+ </div>
+</template>
+
+<script setup>
+import {getCurrentInstance, onMounted, reactive, ref, toRefs} from "vue";
+import editDialog from "./components/editDialog.vue"
+import {ElMessage, ElMessageBox} from "element-plus";
+import {getCompany} from "@/api/onlineEducation/company";
+import Cookies from "js-cookie";
+import {generateWordDocument} from "@/utils/exportWord";
+import {delTable, getTable} from "@/api/qualityObjectives/table";
+import {delDiscern, getDiscern} from "@/api/environment/factors";
+import {delQualityTemplate, getQualityTemplate} from "@/api/standardSys/standardSys";
+const { proxy } = getCurrentInstance();
+const loading = ref(false);
+const noticeRef = ref();
+const deptRef = ref()
+const loadingCompany = ref(false)
+const choosedData = ref([])
+const data = reactive({
+ queryParams: {
+ pageNum: 1,
+ pageSize: 10,
+ companyId: null,
+ year: '',
+ type: ''
+ },
+ companyList: [],
+ isAdmin: false,
+ dialogVisible: false,
+ yearList: [
+ {
+ value: 1,
+ label: '2025'
+ },
+ {
+ value: 2,
+ label: '2024'
+ },
+ {
+ value: 3,
+ label: '2023'
+ },
+ {
+ value: 4,
+ label: '2022'
+ },
+ {
+ value: 5,
+ label: '2021'
+ },
+ ],
+});
+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;
+ if(data.isAdmin){
+ data.queryParams.companyId = null
+ }else {
+ data.queryParams.companyId = userInfo.companyId
+ }
+ getList();
+ if(data.isAdmin){
+ getCompanyList()
+ }
+});
+const getList = async () => {
+ loading.value = true;
+ const res = await getQualityTemplate(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,data.companyList);
+}
+
+const selectValue = (val) => {
+ data.companyList.forEach(item => {
+ if(item.name === val){
+ data.queryParams.companyId = item.id
+ }
+ })
+}
+
+const getCompanyList = async ()=>{
+ const queryParams = {
+ pageNum: 1,
+ pageSize: 999
+ }
+ const res = await getCompany(queryParams)
+ if (res.code == 200) {
+ data.companyList = res.data.list?res.data.list:[]
+ } else {
+ ElMessage.warning(res.message)
+ }
+}
+
+const handleSizeChange = (val) => {
+ data.queryParams.pageSize = val
+ getList()
+}
+const handleCurrentChange = (val) => {
+ data.queryParams.pageNum = val
+ getList()
+}
+const handleClose = () => {
+ data.dialogVisible = false
+}
+
+/** 重置新增的表单以及其他数据 */
+function reset() {
+ if(data.isAdmin){
+ data.queryParams = {
+ companyId: '',
+ pageNum: 1,
+ pageSize: 10,
+ year: '',
+ type: ''
+ }
+ choosedData.value = []
+ data.companyList = [];
+ getCompanyList()
+ }else {
+ data.queryParams = {
+ companyId: data.queryParams.companyId,
+ pageNum: 1,
+ pageSize: 10,
+ year: '',
+ type: ''
+ }
+ }
+ getList();
+
+}
+const exportData = () => {
+ if(choosedData.value && choosedData.value.length === 0){
+ ElMessage.warning('请选择需要导出的数据')
+ }else {
+ startGeneration()
+ }
+}
+const templatePath = ref('/qualityOrganizeExample.docx')
+const startGeneration = async () => {
+ const data = JSON.parse(JSON.stringify(choosedData.value))
+ data.forEach(item => {
+
+ item.tableList = item.planMesses
+
+ try {
+ generateWordDocument(templatePath.value, 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 delQualityTemplate(val.id);
+ if(res.code === 200){
+ ElMessage({
+ type: 'success',
+ message: '删除成功'
+ });
+ getList();
+ }else{
+ ElMessage.warning(res.message)
+ }
+ })
+}
+const handleChangeNum = (value) => {
+ if (!/^\d+$/.test(value)) { // 验证是否为数字
+ ElMessage.warning('只能输入数字')
+ data.queryParams.year = '' // 重置选择,避免非法值被添加到options中
+ } else if (!data.yearList.some(option => option.label === value)) { // 确保不是已存在的选项
+ data.yearList.push({ value, label: value }); // 添加新选项(这里简单地将值和标签设为相同)
+ }
+}
+
+</script>
+<style lang="scss">
+.pag-container{
+ float: right;
+ margin-top: 10px;
+}
+</style>
diff --git a/src/views/work/onlineEducation/offlineEducation/components/recordDialog.vue b/src/views/work/onlineEducation/offlineEducation/components/recordDialog.vue
index 84a4743..390ac8f 100644
--- a/src/views/work/onlineEducation/offlineEducation/components/recordDialog.vue
+++ b/src/views/work/onlineEducation/offlineEducation/components/recordDialog.vue
@@ -89,7 +89,7 @@
<!-- </el-radio-group>-->
<!-- </el-form-item>-->
<el-form-item label="培训记录:" prop="passed" >
- <el-upload accept=".jpg,.jpeg,.png,.doc,.docx,.pdf,.xls,xlsx,ppt,pptx" style="width: 100%" :action="state.uploadUrl" :headers="state.header" method="post" :on-success="(res, uploadFile)=>handleAvatarSuccess(res, uploadFile)" :on-exceed="showTip" v-model:file-list="state.fileList" :before-upload="picSize" :on-remove="(file, uploadFiles)=>handleRemove(file, uploadFiles)" >
+ <el-upload accept=".jpg,.jpeg,.png,.doc,.docx,.pdf,.xls,.xlsx,.ppt,.pptx" style="width: 100%" :action="state.uploadUrl" :headers="state.header" method="post" :on-success="(res, uploadFile)=>handleAvatarSuccess(res, uploadFile)" :on-exceed="showTip" v-model:file-list="state.fileList" :before-upload="picSize" :on-remove="(file, uploadFiles)=>handleRemove(file, uploadFiles)" >
<el-button type="primary">点击上传</el-button>
<!-- <template #tip>-->
<!-- <div class="el-upload__tip">尺寸小于5M,最多可上传1份</div>-->
diff --git a/src/views/work/onlineEducation/offlineEducation/index.vue b/src/views/work/onlineEducation/offlineEducation/index.vue
index d7bb0ff..7bea66f 100644
--- a/src/views/work/onlineEducation/offlineEducation/index.vue
+++ b/src/views/work/onlineEducation/offlineEducation/index.vue
@@ -205,7 +205,7 @@
}
const openFile = async(path)=>{
const ext = path.split('.').pop().toLowerCase();
- if (ext === 'doc' || ext === 'xls' || ext === 'xlsx') {
+ if (ext === 'doc' || ext === 'xls' || ext === 'xlsx' || ext === 'ppt' || ext === 'pptx') {
ElMessageBox.confirm(`暂不支持线上预览.${ext}文件,是否下载查看?`, '提示', { confirmButtonText: '确认', cancelButtonText: '取消', type: 'warning' }).then(() => {
window.open(`${import.meta.env.VITE_APP_BASE_API}/${path}`, '_blank');
}).catch(() => {
diff --git a/src/views/work/procurementPlatform/incomingInspection/inspectionRecords/components/editDialog.vue b/src/views/work/procurementPlatform/incomingInspection/inspectionRecords/components/editDialog.vue
new file mode 100644
index 0000000..5203848
--- /dev/null
+++ b/src/views/work/procurementPlatform/incomingInspection/inspectionRecords/components/editDialog.vue
@@ -0,0 +1,348 @@
+<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.rules" >
+ <el-row :gutter="24">
+ <el-col :span="24">
+ <el-form-item label="企业名称:" prop="companyId" v-if="state.isAdmin">
+ <el-select v-model="state.form.companyId" placeholder="请选择" filterable clearable style="width: 100%" :disabled="title == '查看' || title == '编辑' || !state.isAdmin" @change="selectValueCom">
+ <el-option
+ v-for="item in state.companyList"
+ :key="item.id"
+ :label="item.name"
+ :value="item.id">
+ </el-option>
+ </el-select>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="24">
+ <el-col :span="24">
+ <el-form-item label="记录名称:" prop="recordName" >
+ <el-input :disabled="title === '查看'" v-model="state.form.recordName" placeholder="请输入"></el-input>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="24">
+ <el-col :span="24">
+ <div style="display: flex;align-items: center;margin-bottom: 10px">
+ <span style="font-size: 15px;font-weight: 700;" >材料清单:</span>
+ <el-button
+ :disabled="title === '查看'"
+ type="primary"
+ @click="addTableData"
+ style="margin-left: 20px"
+ >新增</el-button>
+ </div>
+ <el-table :data="state.form.recordMesses" style="margin-bottom: 10px" :border="true" >
+ <el-table-column type="index" label="序号" align="center"></el-table-column>
+ <el-table-column label="材料名称" prop="materialsName" align="center" width="150">
+ <template #default="{row,$index}">
+ <el-form-item :prop="'recordMesses.' + '[' + $index + ']' + '.materialsName'" :rules="state.rules.materialsName">
+ <el-input style="margin-top: 10px" :disabled="title === '查看'" :rows="2" type="textarea" v-model="row.materialsName" placeholder="请输入"></el-input>
+ </el-form-item>
+ </template>
+ </el-table-column>
+ <el-table-column label="合格证明材料检验" prop="qualifiedMaterials" align="center" width="150">
+ <template #default="{row,$index}">
+ <el-form-item :prop="'recordMesses.' + '[' + $index + ']' + '.qualifiedMaterials'" :rules="state.rules.qualifiedMaterials">
+ <el-input style="margin-top: 10px" :disabled="title === '查看'" :rows="2" type="textarea" v-model="row.qualifiedMaterials" placeholder="请输入"></el-input>
+ </el-form-item>
+ </template>
+ </el-table-column>
+ <el-table-column label="外观检验" prop="appearance" align="center" width="150">
+ <template #default="{row,$index}">
+ <el-form-item :prop="'recordMesses.' + '[' + $index + ']' + '.appearance'" :rules="state.rules.appearance">
+ <el-input style="margin-top: 10px" :disabled="title === '查看'" :rows="2" type="textarea" v-model="row.appearance" placeholder="请输入"></el-input>
+ </el-form-item>
+ </template>
+ </el-table-column>
+ <el-table-column label="功能检验" prop="function" align="center" width="150">
+ <template #default="{row,$index}">
+ <el-form-item :prop="'recordMesses.' + '[' + $index + ']' + '.function'" :rules="state.rules.function">
+ <el-input style="margin-top: 10px" :disabled="title === '查看'" :rows="2" type="textarea" v-model="row.function" placeholder="请输入"></el-input>
+ </el-form-item>
+ </template>
+ </el-table-column>
+ <el-table-column label="单位" prop="unit" align="center" width="150">
+ <template #default="{row,$index}">
+ <el-form-item :prop="'recordMesses.' + '[' + $index + ']' + '.unit'" :rules="state.rules.unit">
+ <el-input style="margin-top: 10px" :disabled="title === '查看'" :rows="2" type="textarea" v-model="row.unit" placeholder="请输入"></el-input>
+ </el-form-item>
+ </template>
+ </el-table-column>
+ <el-table-column label="数量" prop="amount" align="center" width="150">
+ <template #default="{row,$index}">
+ <el-form-item :prop="'recordMesses.' + '[' + $index + ']' + '.amount'" :rules="state.rules.amount">
+ <el-input style="margin-top: 10px" :disabled="title === '查看'" v-model.trim.number="row.amount" placeholder="请输入"></el-input>
+ </el-form-item>
+ </template>
+ </el-table-column>
+ <el-table-column label="检验员" prop="checkUser" align="center" width="150">
+ <template #default="{row,$index}">
+ <el-form-item :prop="'recordMesses.' + '[' + $index + ']' + '.checkUser'" :rules="state.rules.checkUser">
+ <el-input style="margin-top: 10px" :disabled="title === '查看'" :rows="2" type="textarea" v-model="row.checkUser" placeholder="请输入"></el-input>
+ </el-form-item>
+ </template>
+ </el-table-column>
+ <el-table-column label="操作" align="center" v-if="title !== '查看'" >
+ <template #default="scope">
+ <el-button link type="danger" @click="delTableData(scope.row)" >删除</el-button>
+ </template>
+ </el-table-column>
+ </el-table>
+ </el-col>
+ </el-row>
+ <el-row :gutter="24">
+ <el-col :span="24">
+ <el-form-item label="说明:" prop="explain" >
+ <el-input :disabled="title === '查看'" :rows="4" type="textarea" v-model="state.form.explain" placeholder="请输入"></el-input>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="24">
+ <el-col :span="24">
+ <el-form-item label="现场签收人:" prop="signId" >
+ <el-select clearable v-model="state.form.signId" :disabled="title =='查看'" filterable style="width: 240px">
+ <el-option
+ v-for="item in state.peopleList"
+ :key="item.id"
+ :label="item.name"
+ :value="item.id"
+ />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="24">
+ <el-col :span="24">
+ <el-form-item label="日期:" prop="signTime" >
+ <el-date-picker
+ :disabled="title === '查看'"
+ v-model="state.form.signTime"
+ type="date"
+ placeholder="请选择日期"
+ />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="24">
+ <el-col :span="24">
+ <el-form-item label="备注:" prop="remark" >
+ <el-input :disabled="title === '查看'" :rows="4" type="textarea" v-model="state.form.remark" placeholder="请输入"></el-input>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ </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 {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";
+import {getDept, getObject, getObjectPage} from "@/api/qualityObjectives/object";
+import {addTable, editTable, getTargetById} from "@/api/qualityObjectives/table";
+import {addNeedDiscren, editNeedDiscren} from "@/api/need/need";
+import {addRecord, editRecord} from "@/api/procurementPlatform/procurementPlatform";
+
+const dialogVisible = ref(false);
+const title = ref("");
+const busRef = ref();
+const length = ref()
+const selectPopperClass = "max-width-select";
+const emit = defineEmits(["getList"]);
+const dataRef = ref();
+const state = reactive({
+ form: {
+ id: '',
+ companyId: null,
+ recordName: null,
+ explain: '',
+ signId: null,
+ signTime: null,
+ remark: '',
+ recordMesses:[],
+ },
+ rules: {
+ companyId: [{ required: true, message: '请选择企业', trigger: 'blur' }],
+ recordName: [{ required: true, message: '请输入记录名称', trigger: 'blur' }],
+ signId: [{ required: true, message: '请选择现场签收人', trigger: 'blur' }],
+ signTime: [{ required: true, message: '请选择日期', trigger: 'blur' }],
+ materialsName: [{required: true, message: "", trigger: "blur"}],
+ qualifiedMaterials: [{required: true, message: "", trigger: "blur"}],
+ appearance: [{required: true, message: "", trigger: "blur"}],
+ function: [{required: true, message: "", trigger: "blur"}],
+ unit: [{required: true, message: "", trigger: "blur"}],
+ amount: [{required: true, message: "", trigger: "blur"}],
+ checkUser: [{required: true, message: "", trigger: "blur"}],
+
+ },
+ peopleList: [],
+ isAdmin: false,
+ companyList: [],
+})
+
+onMounted(() => {
+
+
+});
+const openDialog = async (type, value,companyList) => {
+ const userInfo = JSON.parse(Cookies.get('userInfo'))
+ state.isAdmin = userInfo.userType === 0;
+ state.form.companyName = userInfo.companyName
+ state.form.companyId = userInfo.companyId
+ if(state.isAdmin){
+ state.form.companyId = value.companyId
+ state.form.companyName = value.companyName
+ state.companyList = companyList
+ }
+ title.value = type === 'add' ? '新增' : type ==='edit' ? '编辑' : '查看' ;
+ if(type === 'edit' || type === 'review') {
+ state.form = JSON.parse(JSON.stringify(value));
+ if(state.isAdmin){
+ state.form.companyId = value.companyId
+ state.form.companyName = value.companyName
+ }
+ }
+ await getPeopleList()
+ dialogVisible.value = true;
+}
+
+
+const onSubmit = async () => {
+ if(state.form.recordMesses && state.form.recordMesses.length == 0){
+ ElMessage.warning('请填写材料清单')
+ return
+ }
+ 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 addRecord(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 === '编辑'){
+ state.form.recordMesses.forEach(item => {
+ item.recordId = state.form.id
+ })
+ const {...data} = JSON.parse(JSON.stringify(state.form))
+ const res = await editRecord(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: '',
+ companyId: null,
+ recordName: null,
+ explain: '',
+ signId: null,
+ signTime: null,
+ remark: '',
+ recordMesses:[],
+ }
+ state.peopleList = []
+ state.companyList = []
+}
+const getPeopleList = async ()=> {
+ if(state.isAdmin && (state.form.companyId == 0 || state.form.companyId == null)){
+ return
+ }
+ const queryParams = {
+ pageNum: 1,
+ pageSize: 9999,
+ companyId: state.form.companyId
+ }
+ const res = await getUser(queryParams)
+ if(res.code == 200){
+ state.peopleList = res.data.list?res.data.list:[]
+ }else{
+ ElMessage.warning(res.message)
+ }
+};
+
+
+
+
+const selectValueCom = (val) => {
+ state.form.signId = null
+ state.companyList.forEach(item => {
+ if(item.name === val){
+ state.form.companyId = item.id
+ }
+ })
+ getPeopleList()
+}
+
+const addTableData = () => {
+ state.form.recordMesses.push({})
+}
+const delTableData = (val) => {
+ state.form.recordMesses = state.form.recordMesses.filter(item=> item != val)
+}
+
+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/work/procurementPlatform/incomingInspection/inspectionRecords/index.vue b/src/views/work/procurementPlatform/incomingInspection/inspectionRecords/index.vue
new file mode 100644
index 0000000..685920e
--- /dev/null
+++ b/src/views/work/procurementPlatform/incomingInspection/inspectionRecords/index.vue
@@ -0,0 +1,260 @@
+<template>
+ <div class="app-container">
+ <div style="margin-bottom: 10px">
+ <el-form style="display: flex;flex-wrap: wrap;">
+ <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.companyId" placeholder="请选择" filterable clearable>
+ <el-option
+ v-for="item in data.companyList"
+ :key="item.id"
+ :label="item.name"
+ :value="item.id">
+ </el-option>
+ </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="recordName" align="center" />
+ <el-table-column label="操作" align="center" class-naame="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>
+ <editDialog ref="noticeRef" @getList = "getList"></editDialog>
+ </div>
+</template>
+
+<script setup>
+import {getCurrentInstance, onMounted, reactive, ref, toRefs} from "vue";
+import editDialog from "./components/editDialog.vue"
+import {ElMessage, ElMessageBox} from "element-plus";
+import {getCompany} from "@/api/onlineEducation/company";
+import Cookies from "js-cookie";
+import {generateWordDocument} from "@/utils/exportWord";
+import {delTable, getTable} from "@/api/qualityObjectives/table";
+import {delDiscern, getDiscern} from "@/api/environment/factors";
+import {delRecord, getRecord} from "@/api/procurementPlatform/procurementPlatform";
+const { proxy } = getCurrentInstance();
+const loading = ref(false);
+const noticeRef = ref();
+const deptRef = ref()
+const loadingCompany = ref(false)
+const choosedData = ref([])
+const data = reactive({
+ queryParams: {
+ pageNum: 1,
+ pageSize: 10,
+ companyId: null,
+ year: '',
+ type: ''
+ },
+ companyList: [],
+ isAdmin: false,
+ dialogVisible: 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;
+ if(data.isAdmin){
+ data.queryParams.companyId = null
+ }else {
+ data.queryParams.companyId = userInfo.companyId
+ }
+ getList();
+ if(data.isAdmin){
+ getCompanyList()
+ }
+});
+const getList = async () => {
+ loading.value = true;
+ const res = await getRecord(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,data.companyList);
+}
+
+const selectValue = (val) => {
+ data.companyList.forEach(item => {
+ if(item.name === val){
+ data.queryParams.companyId = item.id
+ }
+ })
+}
+
+const getCompanyList = async ()=>{
+ const queryParams = {
+ pageNum: 1,
+ pageSize: 999
+ }
+ const res = await getCompany(queryParams)
+ if (res.code == 200) {
+ data.companyList = res.data.list?res.data.list:[]
+ } else {
+ ElMessage.warning(res.message)
+ }
+}
+
+const handleSizeChange = (val) => {
+ data.queryParams.pageSize = val
+ getList()
+}
+const handleCurrentChange = (val) => {
+ data.queryParams.pageNum = val
+ getList()
+}
+const handleClose = () => {
+ data.dialogVisible = false
+}
+
+/** 重置新增的表单以及其他数据 */
+function reset() {
+ if(data.isAdmin){
+ data.queryParams = {
+ companyId: '',
+ pageNum: 1,
+ pageSize: 10,
+ year: '',
+ type: ''
+ }
+ choosedData.value = []
+ data.companyList = [];
+ getCompanyList()
+ }else {
+ data.queryParams = {
+ companyId: data.queryParams.companyId,
+ pageNum: 1,
+ pageSize: 10,
+ year: '',
+ type: ''
+ }
+ }
+ getList();
+
+}
+const exportData = () => {
+ if(choosedData.value && choosedData.value.length === 0){
+ ElMessage.warning('请选择需要导出的数据')
+ }else {
+ startGeneration()
+ }
+}
+const templatePath = ref('/recordsExample.docx')
+const startGeneration = async () => {
+ const data = JSON.parse(JSON.stringify(choosedData.value))
+ data.forEach(item => {
+ item.signTime = item.signTime.substring(0,10)
+ item.tableList = item.recordMesses.map((item,index) => {
+ return {
+ ...item,
+ num: index +1
+ }
+ })
+
+ try {
+ generateWordDocument(templatePath.value, 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 delRecord(val.id);
+ if(res.code === 200){
+ ElMessage({
+ type: 'success',
+ message: '删除成功'
+ });
+ getList();
+ }else{
+ ElMessage.warning(res.message)
+ }
+ })
+}
+const handleChangeNum = (value) => {
+ if (!/^\d+$/.test(value)) { // 验证是否为数字
+ ElMessage.warning('只能输入数字')
+ data.queryParams.year = '' // 重置选择,避免非法值被添加到options中
+ } else if (!data.yearList.some(option => option.label === value)) { // 确保不是已存在的选项
+ data.yearList.push({ value, label: value }); // 添加新选项(这里简单地将值和标签设为相同)
+ }
+}
+
+</script>
+<style lang="scss">
+.pag-container{
+ float: right;
+ margin-top: 10px;
+}
+</style>
diff --git a/src/views/work/procurementPlatform/incomingInspection/inspectionStandards/components/editDialog.vue b/src/views/work/procurementPlatform/incomingInspection/inspectionStandards/components/editDialog.vue
new file mode 100644
index 0000000..2191325
--- /dev/null
+++ b/src/views/work/procurementPlatform/incomingInspection/inspectionStandards/components/editDialog.vue
@@ -0,0 +1,215 @@
+<template>
+ <div class="notice">
+ <el-dialog
+ v-model="dialogVisible"
+ :title="state.title"
+ width="600px"
+ :before-close="handleClose"
+ :close-on-press-escape="false"
+ :close-on-click-modal="false"
+ >
+ <el-form :model="state.form" size="default" ref="superRef" :rules="state.formRules" label-width="150px" >
+ <el-form-item v-if="state.isAdmin" label="企业:" prop="companyId">
+ <el-select v-model="state.form.companyId" placeholder="请选择" clearable style="width: 100%">
+ <el-option
+ v-for="item in state.companyList"
+ :key="item.id"
+ :label="item.name"
+ :value="item.id">
+ </el-option>
+ </el-select>
+ </el-form-item>
+ <el-form-item label="文件名称:" prop="fileName">
+ <el-input v-model.trim="state.form.fileName" :disabled="state.title =='查看'" placeholder="文件名称"></el-input>
+ </el-form-item>
+ <el-form-item label="文件:" prop="filePath">
+ <el-upload accept=".jpg,.jpeg,.png,.doc,.docx,.pdf,.xls,.xlsx,.ppt,.pptx" :action="state.uploadUrl" :headers="state.header" method="post" :on-success="(res, uploadFile)=>handleAvatarSuccess(res, uploadFile)" :on-exceed="showTip" :limit='state.fileLimit' v-model:file-list="state.fileList" :before-upload="picSize" :on-remove="(file, uploadFiles)=>handleRemove(file, uploadFiles)" >
+ <el-button type="primary">点击上传</el-button>
+ <template #tip>
+ <div class="el-upload__tip">尺寸小于5M,最多可上传1张</div>
+ </template>
+ </el-upload>
+ </el-form-item>
+ </el-form>
+ <template #footer v-if="state.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, defineEmits, nextTick, onMounted} from 'vue'
+import {ElMessage} from "element-plus";
+import {addUser, editUser, getUserById, resetPwd} from "@/api/onlineEducation/user"
+import {Base64} from "js-base64"
+import {getCompany} from "@/api/onlineEducation/company";
+import {addIndustryTemp, updateIndustryTemp, updateInfoPlatforms} from "@/api/staffManage/staff";
+import {getToken} from "@/utils/auth";
+import {delPic} from "@/api/onlineEducation/banner";
+import {getIndustry} from "@/api/system/industry";
+import {addContract, addStandard, editContract, editStandard} from "@/api/procurementPlatform/procurementPlatform";
+
+const emit = defineEmits(["getList"]);
+const dialogVisible = ref(false)
+const superRef = ref()
+
+const state = reactive({
+ title: '',
+ form: {
+ id: null,
+ fileName: '',
+ filePath: '',
+
+ format: '',
+ companyId: null,
+
+ },
+ formRules:{
+ companyId: [{ required: true, message: '请选择企业', trigger: 'blur' }],
+ fileName: [{ required: true, message: '请输入文件名称', trigger: 'blur' }],
+ filePath: [{ required: true, message: '请上传文件', trigger: 'blur' }],
+ },
+ isAdmin: false,
+ companyList: [],
+ industryList: [],
+ uploadUrl: import.meta.env.VITE_APP_BASE_API + '/system/common/uploadFile',
+ header: {
+ Authorization: getToken()
+ },
+ fileLimit: 1,
+ fileList: []
+})
+onMounted(() => {
+
+});
+
+const openDialog = async (type, value,companyId, isAdmin, companyList) => {
+ state.isAdmin = isAdmin
+ if(isAdmin){
+ state.companyList = companyList
+ }
+ state.title = type === 'add' ? '新增' : type ==='edit' ? '编辑' : '查看'
+ state.form.companyId = companyId
+ if(state.title == '编辑'||state.title == '查看'){
+ Object.keys(state.form).forEach(key => {
+ if (key in value) {
+ state.form[key] = value[key]
+ }
+ })
+ if(value.filePath) {
+ const obj = {
+ url: value.filePath,
+ name: value.fileName
+ }
+ state.fileList = [obj]
+ }
+ }
+ dialogVisible.value = true
+}
+
+const onSubmit = async () => {
+ const valid = await superRef.value.validate();
+ if(valid){
+ if(state.title == '新增'){
+ const {id,...data} = state.form
+ const res = await addStandard(data)
+ if(res.code == 200){
+ ElMessage.success(res.message)
+ emit('getList')
+ handleClose()
+ dialogVisible.value = false;
+ }else{
+ ElMessage.warning(res.message)
+ }
+ }else{
+ const res = await editStandard(state.form)
+ if(res.code == 200){
+ ElMessage.success(res.message)
+ emit('getList')
+ handleClose()
+ dialogVisible.value = false;
+ }else{
+ ElMessage.warning(res.message)
+ }
+ }
+ }
+}
+
+const handleAvatarSuccess = (res, uploadFile) => {
+ if(res.code == 200){
+ state.form.fileName = res.data.originName
+ state.form.filePath = res.data.path
+ }else{
+ state.fileList = []
+ ElMessage({
+ type: 'warning',
+ message: '文件上传失败'
+ })
+ }
+}
+
+const showTip =()=>{
+ ElMessage({
+ type: 'warning',
+ message: '超出文件上传数量'
+ });
+}
+const picSize = async (rawFile) => {
+ if(rawFile.size / 1024 / 1024 > 5){
+ ElMessage({
+ type: 'warning',
+ message: '文件大小不能超过5M'
+ });
+ return false
+ }
+};
+const handleRemove = async (file, uploadFiles) => {
+ let path = state.form.filePath;
+ await delPic({path: path}).then(res => {
+ if(res.code == 200){
+ state.form.filePath = ''
+ state.form.fileName = ''
+ }else{
+ ElMessage({
+ type: 'warning',
+ message: res.message
+ })
+ }
+ }).catch(() => {
+ });
+}
+
+const handleClose = () => {
+ state.form = {
+ id: null,
+ filePath: '',
+ fileName: '',
+ companyId: null,
+ }
+ state.fileList = []
+ superRef.value.clearValidate();
+ superRef.value.resetFields()
+ dialogVisible.value = false;
+}
+
+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/work/procurementPlatform/incomingInspection/inspectionStandards/index.vue b/src/views/work/procurementPlatform/incomingInspection/inspectionStandards/index.vue
new file mode 100644
index 0000000..1cb9bdd
--- /dev/null
+++ b/src/views/work/procurementPlatform/incomingInspection/inspectionStandards/index.vue
@@ -0,0 +1,267 @@
+<template>
+ <div class="app-container">
+ <div style="display: flex;justify-content: space-between">
+ <el-form :inline="true" style="display: flex;align-items: center;flex-wrap: wrap;" >
+ <el-form-item>
+ <el-button
+ type="primary"
+ plain
+ icon="Plus"
+ @click="openDialog('add',{})"
+ >新增</el-button>
+ </el-form-item>
+ <el-form-item v-if="isAdmin" label="企业:" >
+ <el-select v-model="data.queryParams.companyId" placeholder="请选择" clearable>
+ <el-option
+ v-for="item in companyList"
+ :key="item.id"
+ :label="item.name"
+ :value="item.id">
+ </el-option>
+ </el-select>
+ </el-form-item>
+ <el-form-item v-if="isAdmin">
+ <el-button type="primary" @click="getList">查询</el-button>
+ <el-button type="primary" plain @click="reset">重置</el-button>
+ </el-form-item>
+ </el-form>
+ </div>
+ <!-- 表格数据 -->
+ <el-table v-loading="loading" :data="dataList" :border="true">
+ <el-table-column label="序号" type="index" align="center" width="80"/>
+ <el-table-column label="规范" prop="fileNameSimple" align="center"/>
+ <el-table-column label="文件" prop="fileName" align="center">
+ <template #default="scope">
+ <el-link style="" type="primary" @click="openFile(scope.row.filePath)">{{scope.row.fileName}}</el-link>
+ </template>
+ </el-table-column>
+ <el-table-column label="操作" align="center" class-name="small-padding fixed-width" >
+ <template #default="scope">
+ <el-button link type="primary" @click="downloadFile(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>
+
+ <pagination
+ v-show="total > 0"
+ :total="total"
+ v-model:page="queryParams.pageNum"
+ v-model:limit="queryParams.pageSize"
+ @pagination="getList"
+ />
+
+ <edit-dialog ref="dialogRef" @getList=getList></edit-dialog>
+ </div>
+</template>
+
+<script setup>
+import {getCurrentInstance, onMounted, onUnmounted, reactive, ref, toRefs} from "vue";
+import {ElMessage, ElMessageBox} from "element-plus";
+import {delCompany, getCompany} from "@/api/onlineEducation/company";
+import { Plus, Upload, Download} from '@element-plus/icons-vue';
+import {delUser, getUser} from "@/api/onlineEducation/user";
+import Cookies from "js-cookie";
+import editDialog from './components/editDialog.vue'
+import {
+ delIndustryTemp,
+ getIndustryTemp, uploadTemplate,
+} from "@/api/staffManage/staff";
+import useUserStore from "@/store/modules/user";
+import axios from "axios";
+import {getToken} from "@/utils/auth";
+import {getIndustry} from "@/api/system/industry";
+import {renderAsync} from "docx-preview";
+import {delContract, delStandard, getContract, getStandard} from "@/api/procurementPlatform/procurementPlatform";
+const userStore = useUserStore()
+const { proxy } = getCurrentInstance();
+const loading = ref(false);
+const dialogRef = ref();
+
+const data = reactive({
+ queryParams: {
+ pageNum: 1,
+ pageSize: 10,
+ companyId: null,
+ industryType: null,
+ type: '',
+ templateName: ''
+ },
+ total: 0,
+ dataList: [],
+ companyList: [],
+ industryList: [],
+ isAdmin: false,
+ typeList: [],
+ exportDialog: false,
+
+});
+
+
+const { queryParams, total, dataList,companyList,industryList, isAdmin } = toRefs(data);
+const userInfo = ref()
+onMounted(async ()=>{
+ if(userStore.roles.includes('admin')){
+ data.isAdmin = true
+ data.queryParams.companyId = null
+ await getCompanyList()
+ }else{
+ data.isAdmin = false
+ data.queryParams.companyId = userStore.companyId
+ }
+ await getList()
+})
+
+onUnmounted(()=>{
+
+})
+const openFile = async(path)=>{
+ const ext = path.split('.').pop().toLowerCase();
+ if (ext === 'doc' || ext === 'xls' || ext === 'xlsx' || ext === 'ppt' || ext === 'pptx') {
+ ElMessageBox.confirm('暂不支持线上预览文件,是否下载查看?', '提示', { confirmButtonText: '确认', cancelButtonText: '取消', type: 'warning' }).then(() => {
+ window.open(`${import.meta.env.VITE_APP_BASE_API}/${path}`, '_blank');
+ }).catch(() => {
+ console.log('取消预览')
+ });
+ return
+ }
+ if(ext === 'docx'){
+ try {
+ // 1. 获取文件
+ const response = await fetch(import.meta.env.VITE_APP_BASE_API + '/' + path);
+ const arrayBuffer = await response.arrayBuffer();
+ // 2. 创建新窗口
+ const win = window.open('', '_blank')
+ win.document.write(`
+ <!DOCTYPE html>
+ <html>
+ <head>
+ <title>预览</title>
+ <style>
+ body { margin: 20px; font-family: Arial; }
+ .docx-container { width: 100%; height: 100%; }
+ </style>
+ </head>
+ <body>
+ <div id="container" class="docx-container"></div>
+ </body>
+ </html>
+ `);
+ // 3. 渲染 DOCX
+ await renderAsync(arrayBuffer, win.document.getElementById('container'));
+
+ } catch (error) {
+ console.error('预览失败:', error);
+ alert(`预览失败: ${error.message}`);
+ }
+ }else {
+ window.open(`${import.meta.env.VITE_APP_BASE_API}/${path}`, '_blank');
+ }
+
+}
+const getList = async () => {
+ loading.value = true
+ const res = await getStandard(data.queryParams)
+ if(res.code == 200){
+ data.dataList = res.data.list.map(item => {
+ return {
+ ...item,
+ fileNameSimple: item.fileName.split('.')[0]
+ }
+ })
+ data.total = res.data.total
+ }else{
+ ElMessage.warning(res.message)
+ }
+ loading.value = false
+}
+
+
+const getCompanyList = async ()=>{
+ const queryParams = {
+ pageNum: 1,
+ pageSize: 999
+ }
+ const res = await getCompany(queryParams)
+ if (res.code == 200) {
+ data.companyList = res.data.list?res.data.list:[]
+ // data.queryParams.companyId = data.companyList[0].id
+ } else {
+ ElMessage.warning(res.message)
+ }
+}
+
+const downloadFile = (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
+ link.setAttribute("download", e.fileName);
+ document.body.appendChild(link);
+ link.click();
+ document.body.removeChild(link);
+ } else {
+ ElMessage({
+ type: 'warning',
+ message: '文件读取失败'
+ });
+ }
+ })
+}
+
+const openDialog = (type, value) => {
+ dialogRef.value.openDialog(type, value, data.queryParams.companyId, data.isAdmin, data.companyList);
+}
+
+
+
+
+/** 重置新增的表单以及其他数据 */
+const reset= async()=> {
+ if(data.isAdmin){
+ data.queryParams = {
+ pageNum: 1,
+ pageSize: 10,
+ companyId: null,
+ industryType: null,
+ type: '',
+ templateName: ''
+ }
+ await getCompanyList()
+ }else {
+ data.queryParams = {
+ pageNum: 1,
+ pageSize: 10,
+ companyId: data.queryParams.companyId,
+ industryType: null,
+ type: '',
+ templateName: ''
+ }
+ }
+ await getList()
+}
+const handleDelete = (val) => {
+ ElMessageBox.confirm(
+ '确定删除此条数据?',
+ '提示',
+ {
+ confirmButtonText: '确定',
+ cancelButtonText: '取消',
+ type: 'warning',
+ })
+ .then( async() => {
+ const res = await delStandard(val.id)
+ if(res.code == 200){
+ ElMessage.success('数据删除成功')
+ await getList()
+ }else{
+ ElMessage.warning(res.message)
+ }
+ })
+}
+
+
+</script>
diff --git a/src/views/work/procurementPlatform/purchaseContract/components/editDialog.vue b/src/views/work/procurementPlatform/purchaseContract/components/editDialog.vue
new file mode 100644
index 0000000..572dd86
--- /dev/null
+++ b/src/views/work/procurementPlatform/purchaseContract/components/editDialog.vue
@@ -0,0 +1,215 @@
+<template>
+ <div class="notice">
+ <el-dialog
+ v-model="dialogVisible"
+ :title="state.title"
+ width="600px"
+ :before-close="handleClose"
+ :close-on-press-escape="false"
+ :close-on-click-modal="false"
+ >
+ <el-form :model="state.form" size="default" ref="superRef" :rules="state.formRules" label-width="150px" >
+ <el-form-item v-if="state.isAdmin" label="企业:" prop="companyId">
+ <el-select v-model="state.form.companyId" placeholder="请选择" clearable style="width: 100%">
+ <el-option
+ v-for="item in state.companyList"
+ :key="item.id"
+ :label="item.name"
+ :value="item.id">
+ </el-option>
+ </el-select>
+ </el-form-item>
+ <el-form-item label="文件名称:" prop="fileName">
+ <el-input v-model.trim="state.form.fileName" :disabled="state.title =='查看'" placeholder="文件名称"></el-input>
+ </el-form-item>
+ <el-form-item label="文件:" prop="filePath">
+ <el-upload accept=".jpg,.jpeg,.png,.doc,.docx,.pdf,.xls,.xlsx,.ppt,.pptx" :action="state.uploadUrl" :headers="state.header" method="post" :on-success="(res, uploadFile)=>handleAvatarSuccess(res, uploadFile)" :on-exceed="showTip" :limit='state.fileLimit' v-model:file-list="state.fileList" :before-upload="picSize" :on-remove="(file, uploadFiles)=>handleRemove(file, uploadFiles)" >
+ <el-button type="primary">点击上传</el-button>
+ <template #tip>
+ <div class="el-upload__tip">尺寸小于5M,最多可上传1张</div>
+ </template>
+ </el-upload>
+ </el-form-item>
+ </el-form>
+ <template #footer v-if="state.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, defineEmits, nextTick, onMounted} from 'vue'
+import {ElMessage} from "element-plus";
+import {addUser, editUser, getUserById, resetPwd} from "@/api/onlineEducation/user"
+import {Base64} from "js-base64"
+import {getCompany} from "@/api/onlineEducation/company";
+import {addIndustryTemp, updateIndustryTemp, updateInfoPlatforms} from "@/api/staffManage/staff";
+import {getToken} from "@/utils/auth";
+import {delPic} from "@/api/onlineEducation/banner";
+import {getIndustry} from "@/api/system/industry";
+import {addContract, editContract} from "@/api/procurementPlatform/procurementPlatform";
+
+const emit = defineEmits(["getList"]);
+const dialogVisible = ref(false)
+const superRef = ref()
+
+const state = reactive({
+ title: '',
+ form: {
+ id: null,
+ fileName: '',
+ filePath: '',
+
+ format: '',
+ companyId: null,
+
+ },
+ formRules:{
+ companyId: [{ required: true, message: '请选择企业', trigger: 'blur' }],
+ fileName: [{ required: true, message: '请输入文件名称', trigger: 'blur' }],
+ filePath: [{ required: true, message: '请上传文件', trigger: 'blur' }],
+ },
+ isAdmin: false,
+ companyList: [],
+ industryList: [],
+ uploadUrl: import.meta.env.VITE_APP_BASE_API + '/system/common/uploadFile',
+ header: {
+ Authorization: getToken()
+ },
+ fileLimit: 1,
+ fileList: []
+})
+onMounted(() => {
+
+});
+
+const openDialog = async (type, value,companyId, isAdmin, companyList) => {
+ state.isAdmin = isAdmin
+ if(isAdmin){
+ state.companyList = companyList
+ }
+ state.title = type === 'add' ? '新增' : type ==='edit' ? '编辑' : '查看'
+ state.form.companyId = companyId
+ if(state.title == '编辑'||state.title == '查看'){
+ Object.keys(state.form).forEach(key => {
+ if (key in value) {
+ state.form[key] = value[key]
+ }
+ })
+ if(value.filePath) {
+ const obj = {
+ url: value.filePath,
+ name: value.fileName
+ }
+ state.fileList = [obj]
+ }
+ }
+ dialogVisible.value = true
+}
+
+const onSubmit = async () => {
+ const valid = await superRef.value.validate();
+ if(valid){
+ if(state.title == '新增'){
+ const {id,...data} = state.form
+ const res = await addContract(data)
+ if(res.code == 200){
+ ElMessage.success(res.message)
+ emit('getList')
+ handleClose()
+ dialogVisible.value = false;
+ }else{
+ ElMessage.warning(res.message)
+ }
+ }else{
+ const res = await editContract(state.form)
+ if(res.code == 200){
+ ElMessage.success(res.message)
+ emit('getList')
+ handleClose()
+ dialogVisible.value = false;
+ }else{
+ ElMessage.warning(res.message)
+ }
+ }
+ }
+}
+
+const handleAvatarSuccess = (res, uploadFile) => {
+ if(res.code == 200){
+ state.form.fileName = res.data.originName
+ state.form.filePath = res.data.path
+ }else{
+ state.fileList = []
+ ElMessage({
+ type: 'warning',
+ message: '文件上传失败'
+ })
+ }
+}
+
+const showTip =()=>{
+ ElMessage({
+ type: 'warning',
+ message: '超出文件上传数量'
+ });
+}
+const picSize = async (rawFile) => {
+ if(rawFile.size / 1024 / 1024 > 5){
+ ElMessage({
+ type: 'warning',
+ message: '文件大小不能超过5M'
+ });
+ return false
+ }
+};
+const handleRemove = async (file, uploadFiles) => {
+ let path = state.form.filePath;
+ await delPic({path: path}).then(res => {
+ if(res.code == 200){
+ state.form.filePath = ''
+ state.form.fileName = ''
+ }else{
+ ElMessage({
+ type: 'warning',
+ message: res.message
+ })
+ }
+ }).catch(() => {
+ });
+}
+
+const handleClose = () => {
+ state.form = {
+ id: null,
+ filePath: '',
+ fileName: '',
+ companyId: null,
+ }
+ state.fileList = []
+ superRef.value.clearValidate();
+ superRef.value.resetFields()
+ dialogVisible.value = false;
+}
+
+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/work/procurementPlatform/purchaseContract/index.vue b/src/views/work/procurementPlatform/purchaseContract/index.vue
new file mode 100644
index 0000000..8eb2eb6
--- /dev/null
+++ b/src/views/work/procurementPlatform/purchaseContract/index.vue
@@ -0,0 +1,266 @@
+<template>
+ <div class="app-container">
+ <div style="display: flex;justify-content: space-between">
+ <el-form :inline="true" style="display: flex;align-items: center;flex-wrap: wrap;" >
+ <el-form-item>
+ <el-button
+ type="primary"
+ plain
+ icon="Plus"
+ @click="openDialog('add',{})"
+ >新增</el-button>
+ </el-form-item>
+ <el-form-item v-if="isAdmin" label="企业:" >
+ <el-select v-model="data.queryParams.companyId" placeholder="请选择" clearable>
+ <el-option
+ v-for="item in companyList"
+ :key="item.id"
+ :label="item.name"
+ :value="item.id">
+ </el-option>
+ </el-select>
+ </el-form-item>
+ <el-form-item v-if="isAdmin">
+ <el-button type="primary" @click="getList">查询</el-button>
+ <el-button type="primary" plain @click="reset">重置</el-button>
+ </el-form-item>
+ </el-form>
+ </div>
+ <!-- 表格数据 -->
+ <el-table v-loading="loading" :data="dataList" :border="true">
+ <el-table-column label="序号" type="index" align="center" width="80"/>
+ <el-table-column label="文件名称" prop="fileNameSimple" align="center"/>
+ <el-table-column label="文件" prop="fileName" align="center">
+ <template #default="scope">
+ <el-link style="" type="primary" @click="openFile(scope.row.filePath)">{{scope.row.fileName}}</el-link>
+ </template>
+ </el-table-column>
+ <el-table-column label="操作" align="center" class-name="small-padding fixed-width" >
+ <template #default="scope">
+ <el-button link type="primary" @click="downloadFile(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>
+
+ <pagination
+ v-show="total > 0"
+ :total="total"
+ v-model:page="queryParams.pageNum"
+ v-model:limit="queryParams.pageSize"
+ @pagination="getList"
+ />
+
+ <edit-dialog ref="dialogRef" @getList=getList></edit-dialog>
+ </div>
+</template>
+
+<script setup>
+import {getCurrentInstance, onMounted, onUnmounted, reactive, ref, toRefs} from "vue";
+import {ElMessage, ElMessageBox} from "element-plus";
+import {delCompany, getCompany} from "@/api/onlineEducation/company";
+import { Plus, Upload, Download} from '@element-plus/icons-vue';
+import {delUser, getUser} from "@/api/onlineEducation/user";
+import Cookies from "js-cookie";
+import editDialog from './components/editDialog.vue'
+import {
+ delIndustryTemp,
+ getIndustryTemp, uploadTemplate,
+} from "@/api/staffManage/staff";
+import useUserStore from "@/store/modules/user";
+import axios from "axios";
+import {getToken} from "@/utils/auth";
+import {getIndustry} from "@/api/system/industry";
+import {renderAsync} from "docx-preview";
+import {delContract, getContract} from "@/api/procurementPlatform/procurementPlatform";
+const userStore = useUserStore()
+const { proxy } = getCurrentInstance();
+const loading = ref(false);
+const dialogRef = ref();
+
+const data = reactive({
+ queryParams: {
+ pageNum: 1,
+ pageSize: 10,
+ companyId: null,
+ industryType: null,
+ type: '',
+ templateName: ''
+ },
+ total: 0,
+ dataList: [],
+ companyList: [],
+ industryList: [],
+ isAdmin: false,
+ typeList: [],
+ exportDialog: false,
+
+});
+
+const { queryParams, total, dataList,companyList,industryList, isAdmin } = toRefs(data);
+const userInfo = ref()
+onMounted(async ()=>{
+ if(userStore.roles.includes('admin')){
+ data.isAdmin = true
+ data.queryParams.companyId = null
+ await getCompanyList()
+ }else{
+ data.isAdmin = false
+ data.queryParams.companyId = userStore.companyId
+ }
+ await getList()
+})
+
+onUnmounted(()=>{
+
+})
+const openFile = async(path)=>{
+ const ext = path.split('.').pop().toLowerCase();
+ if (ext === 'doc' || ext === 'xls' || ext === 'xlsx' || ext === 'ppt' || ext === 'pptx') {
+ ElMessageBox.confirm('暂不支持线上预览文件,是否下载查看?', '提示', { confirmButtonText: '确认', cancelButtonText: '取消', type: 'warning' }).then(() => {
+ window.open(`${import.meta.env.VITE_APP_BASE_API}/${path}`, '_blank');
+ }).catch(() => {
+ console.log('取消预览')
+ });
+ return
+ }
+ if(ext === 'docx'){
+ try {
+ // 1. 获取文件
+ const response = await fetch(import.meta.env.VITE_APP_BASE_API + '/' + path);
+ const arrayBuffer = await response.arrayBuffer();
+ // 2. 创建新窗口
+ const win = window.open('', '_blank')
+ win.document.write(`
+ <!DOCTYPE html>
+ <html>
+ <head>
+ <title>预览</title>
+ <style>
+ body { margin: 20px; font-family: Arial; }
+ .docx-container { width: 100%; height: 100%; }
+ </style>
+ </head>
+ <body>
+ <div id="container" class="docx-container"></div>
+ </body>
+ </html>
+ `);
+ // 3. 渲染 DOCX
+ await renderAsync(arrayBuffer, win.document.getElementById('container'));
+
+ } catch (error) {
+ console.error('预览失败:', error);
+ alert(`预览失败: ${error.message}`);
+ }
+ }else {
+ window.open(`${import.meta.env.VITE_APP_BASE_API}/${path}`, '_blank');
+ }
+
+}
+const getList = async () => {
+ loading.value = true
+ const res = await getContract(data.queryParams)
+ if(res.code == 200){
+ data.dataList = res.data.list.map(item => {
+ return {
+ ...item,
+ fileNameSimple: item.fileName.split('.')[0]
+ }
+ })
+ data.total = res.data.total
+ }else{
+ ElMessage.warning(res.message)
+ }
+ loading.value = false
+}
+
+
+const getCompanyList = async ()=>{
+ const queryParams = {
+ pageNum: 1,
+ pageSize: 999
+ }
+ const res = await getCompany(queryParams)
+ if (res.code == 200) {
+ data.companyList = res.data.list?res.data.list:[]
+ // data.queryParams.companyId = data.companyList[0].id
+ } else {
+ ElMessage.warning(res.message)
+ }
+}
+
+const downloadFile = (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
+ link.setAttribute("download", e.fileName);
+ document.body.appendChild(link);
+ link.click();
+ document.body.removeChild(link);
+ } else {
+ ElMessage({
+ type: 'warning',
+ message: '文件读取失败'
+ });
+ }
+ })
+}
+
+const openDialog = (type, value) => {
+ dialogRef.value.openDialog(type, value, data.queryParams.companyId, data.isAdmin, data.companyList);
+}
+
+
+
+
+/** 重置新增的表单以及其他数据 */
+const reset= async()=> {
+ if(data.isAdmin){
+ data.queryParams = {
+ pageNum: 1,
+ pageSize: 10,
+ companyId: null,
+ industryType: null,
+ type: '',
+ templateName: ''
+ }
+ await getCompanyList()
+ }else {
+ data.queryParams = {
+ pageNum: 1,
+ pageSize: 10,
+ companyId: data.queryParams.companyId,
+ industryType: null,
+ type: '',
+ templateName: ''
+ }
+ }
+ await getList()
+}
+const handleDelete = (val) => {
+ ElMessageBox.confirm(
+ '确定删除此条数据?',
+ '提示',
+ {
+ confirmButtonText: '确定',
+ cancelButtonText: '取消',
+ type: 'warning',
+ })
+ .then( async() => {
+ const res = await delContract(val.id)
+ if(res.code == 200){
+ ElMessage.success('数据删除成功')
+ await getList()
+ }else{
+ ElMessage.warning(res.message)
+ }
+ })
+}
+
+
+</script>
diff --git a/src/views/work/procurementPlatform/purchaseRequisition/components/editDialog.vue b/src/views/work/procurementPlatform/purchaseRequisition/components/editDialog.vue
new file mode 100644
index 0000000..1e11f93
--- /dev/null
+++ b/src/views/work/procurementPlatform/purchaseRequisition/components/editDialog.vue
@@ -0,0 +1,500 @@
+<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.rules" >
+ <el-row :gutter="24">
+ <el-col :span="24">
+ <el-form-item label="企业名称:" prop="companyId" v-if="state.isAdmin">
+ <el-select v-model="state.form.companyId" placeholder="请选择" filterable clearable style="width: 100%" :disabled="title == '查看' || title == '编辑' || !state.isAdmin" @change="selectValueCom">
+ <el-option
+ v-for="item in state.companyList"
+ :key="item.id"
+ :label="item.name"
+ :value="item.id">
+ </el-option>
+ </el-select>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="24">
+ <el-col :span="24">
+ <el-form-item label="申购单名称:" prop="applyName" >
+ <el-input :disabled="title === '查看'" v-model="state.form.applyName" placeholder="请输入"></el-input>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="24">
+ <el-col :span="12">
+ <el-form-item label="申请部门:" prop="deptId" >
+ <el-select
+ :disabled="title === '查看'"
+ v-model="state.form.deptId"
+ placeholder="请选择部门"
+ style="width: 240px"
+ >
+ <el-option
+ v-for="item in state.deptList"
+ :key="item.deptId"
+ :label="item.deptName"
+ :value="item.deptId"
+ />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="申请日期:" prop="applyTime" >
+ <el-date-picker
+ :disabled="title === '查看'"
+ v-model="state.form.applyTime"
+ type="date"
+ placeholder="请选择日期"
+ style="width: 100%"
+ />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="24">
+ <el-col :span="12">
+ <el-form-item label="申请理由:" prop="applyReason" >
+ <el-input :disabled="title === '查看'" :rows="2" type="textarea" v-model="state.form.applyReason" placeholder="请输入"></el-input>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="申请人:" prop="applyUser" >
+ <el-select clearable v-model="state.form.applyUser" :disabled="title =='查看'" filterable style="width: 100%">
+ <el-option
+ v-for="item in state.peopleList"
+ :key="item.id"
+ :label="item.name"
+ :value="item.id"
+ />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="24">
+ <el-col :span="12">
+ <el-form-item label="直属部门领导:" prop="deptUser" >
+ <el-select clearable v-model="state.form.deptUser" :disabled="title =='查看'" filterable style="width: 100%">
+ <el-option
+ v-for="item in state.peopleList"
+ :key="item.id"
+ :label="item.name"
+ :value="item.id"
+ />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="财务部:" prop="financeUser" >
+ <el-select clearable v-model="state.form.financeUser" :disabled="title =='查看'" filterable style="width: 100%">
+ <el-option
+ v-for="item in state.peopleList"
+ :key="item.id"
+ :label="item.name"
+ :value="item.id"
+ />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="24">
+ <el-col :span="24">
+ <div style="display: flex;align-items: center;margin-bottom: 10px">
+ <span style="font-size: 15px;font-weight: 700;" >采购计划:</span>
+ <el-button
+ :disabled="title === '查看'"
+ type="primary"
+ @click="addTableData"
+ style="margin-left: 20px"
+ >新增</el-button>
+ </div>
+ <el-table
+ ref="tableRef"
+ :data="state.form.purchaseApplyPlans"
+ show-summary
+ :summary-method="getSummaries"
+ style="margin-bottom: 10px"
+ :border="true"
+
+ >
+ <el-table-column type="index" label="序号" width="80" align="center"></el-table-column>
+ <el-table-column label="品名" prop="name" align="center" width="150">
+ <template #default="{row,$index}">
+ <el-form-item :prop="'purchaseApplyPlans.' + '[' + $index + ']' + '.name'" :rules="state.rules.name">
+ <el-input style="margin-top: 10px" :disabled="title === '查看'" :rows="2" type="textarea" v-model="row.name" placeholder="请输入"></el-input>
+ </el-form-item>
+ </template>
+ </el-table-column>
+ <el-table-column label="型号规格" prop="model" align="center" width="150">
+ <template #default="{row,$index}">
+ <el-form-item :prop="'purchaseApplyPlans.' + '[' + $index + ']' + '.model'" :rules="state.rules.model">
+ <el-input style="margin-top: 10px" :disabled="title === '查看'" :rows="2" type="textarea" v-model="row.model" placeholder="请输入"></el-input>
+ </el-form-item>
+ </template>
+ </el-table-column>
+ <el-table-column label="建议供应商" prop="supplier" align="center" width="150">
+ <template #default="{row,$index}">
+ <el-form-item :prop="'purchaseApplyPlans.' + '[' + $index + ']' + '.supplier'" :rules="state.rules.supplier">
+ <el-input style="margin-top: 10px" :disabled="title === '查看'" :rows="2" type="textarea" v-model="row.supplier" placeholder="请输入"></el-input>
+ </el-form-item>
+ </template>
+ </el-table-column>
+ <el-table-column label="数量" prop="amount" align="center" width="150">
+ <template #default="{row,$index}">
+ <el-form-item :prop="'purchaseApplyPlans.' + '[' + $index + ']' + '.amount'" :rules="state.rules.amount">
+ <el-input
+ :disabled="title === '查看'"
+ v-model.trim.number="row.amount"
+ placeholder="请输入"
+ @input="debouncedUpdate"
+ @blur="handleBlur(row, 'amount')"
+ >
+ </el-input>
+ </el-form-item>
+ </template>
+ </el-table-column>
+ <el-table-column label="预计单价" prop="money" align="center" width="150">
+ <template #default="{row,$index}">
+ <el-form-item :prop="'purchaseApplyPlans.' + '[' + $index + ']' + '.money'" :rules="state.rules.money">
+ <el-input
+ :disabled="title === '查看'"
+ v-model="row.money"
+ placeholder="请输入"
+ @change="debouncedUpdate"
+ @input="row.money= row.money.replace(/[^\d.]/g, '') .replace(/\.+/g, '.').replace(/^\./, '0.').replace(/^(\d*\.?\d{0,2}).*/, '$1')"
+ @blur="handleBlur(row, 'money')"
+ >
+ </el-input>
+ </el-form-item>
+ </template>
+ </el-table-column>
+ <el-table-column label="分类" prop="solutions" align="center" width="150">
+ <template #default="{row,$index}">
+ <el-form-item :prop="'purchaseApplyPlans.' + '[' + $index + ']' + '.type'" :rules="state.rules.type">
+ <el-input style="margin-top: 10px" :disabled="title === '查看'" :rows="2" type="textarea" v-model="row.type" placeholder="请输入"></el-input>
+ </el-form-item>
+ </template>
+ </el-table-column>
+ <el-table-column label="操作" align="center" v-if="title !== '查看'" >
+ <template #default="scope">
+ <el-button link type="danger" @click="delTableData(scope.row)" >删除</el-button>
+ </template>
+ </el-table-column>
+ </el-table>
+ </el-col>
+ </el-row>
+ </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 {computed, 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";
+import {getDept, getObject, getObjectPage} from "@/api/qualityObjectives/object";
+import {addTable, editTable, getTargetById} from "@/api/qualityObjectives/table";
+import {addNeedDiscren, editNeedDiscren} from "@/api/need/need";
+import {debounce} from "@/utils";
+import {addApply, editApply} from "@/api/procurementPlatform/procurementPlatform";
+
+const dialogVisible = ref(false);
+const title = ref("");
+const busRef = ref();
+const length = ref()
+const selectPopperClass = "max-width-select";
+const emit = defineEmits(["getList"]);
+const dataRef = ref();
+const tableRef = ref();
+const state = reactive({
+ form: {
+ id: '',
+ companyId: null,
+ deptId: null,
+ applyName: '',
+ applyTime: null,
+ applyReason: null,
+ applyUser: null,
+ deptUser: null,
+ financeUser: '',
+ purchaseApplyPlans:[],
+ },
+ rules: {
+ companyId: [{ required: true, message: '请选择企业', trigger: 'blur' }],
+ deptId: [{ required: true, message: '请选择部门', trigger: 'blur' }],
+ applyName: [{ required: true, message: '请输入申购单名称', trigger: 'blur' }],
+ applyTime: [{ required: true, message: '请选择申请日期', trigger: 'blur' }],
+ applyReason: [{ required: true, message: '请输入申请理由', trigger: 'blur' }],
+ applyUser: [{ required: true, message: '请选择申请人', trigger: 'blur' }],
+ deptUser: [{ required: true, message: '请选择直属部门领导', trigger: 'blur' }],
+ financeUser: [{ required: true, message: '请选择财务部人员', trigger: 'blur' }],
+ name: [{required: true, message: "", trigger: "blur"}],
+ model: [{required: true, message: "", trigger: "blur"}],
+ supplier: [{required: true, message: "", trigger: "blur"}],
+ amount: [{required: true, message: "", trigger: "blur"}],
+ money: [{required: true, message: "", trigger: "blur"}],
+ type: [{required: true, message: "", trigger: "blur"}],
+ },
+ peopleList: [],
+ isAdmin: false,
+ companyList: [],
+ deptList: [],
+})
+
+onMounted(() => {
+
+
+});
+
+
+const openDialog = async (type, value,companyList) => {
+ const userInfo = JSON.parse(Cookies.get('userInfo'))
+ state.isAdmin = userInfo.userType === 0;
+ state.form.companyName = userInfo.companyName
+ state.form.companyId = userInfo.companyId
+ if(state.isAdmin){
+ state.form.companyId = value.companyId
+ state.form.companyName = value.companyName
+ state.companyList = companyList
+ }
+ title.value = type === 'add' ? '新增' : type ==='edit' ? '编辑' : '查看' ;
+ if(type === 'edit' || type === 'review') {
+ state.form = JSON.parse(JSON.stringify(value));
+ if(state.isAdmin){
+ state.form.companyId = value.companyId
+ state.form.companyName = value.companyName
+ }
+ }
+ await getDeptList()
+ await getPeopleList()
+ dialogVisible.value = true;
+}
+
+const getDeptList = async () => {
+ if(state.isAdmin && (state.form.companyId == 0 || state.form.companyId == null)){
+ return
+ }
+ const param = {
+ pageNum: 1,
+ pageSize: 999,
+ companyId: state.form.companyId
+ }
+ const res = await getDept(param)
+ if(res.code === 200){
+ state.deptList = res.data
+ }
+}
+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 addApply(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 === '编辑'){
+ state.form.purchaseApplyPlans.forEach(item => {
+ item.applyId = state.form.id
+ })
+ const {...data} = JSON.parse(JSON.stringify(state.form))
+ const res = await editApply(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: '',
+ companyId: null,
+ deptId: null,
+ year: '',
+ fictionId: null,
+ checkId: null,
+ ratifyId: null,
+ fictionTime: null,
+ frequency: '',
+ purchaseApplyPlans:[],
+ }
+ state.deptList = []
+ state.peopleList = []
+ state.companyList = []
+}
+const getPeopleList = async ()=> {
+ if(state.isAdmin && (state.form.companyId == 0 || state.form.companyId == null)){
+ return
+ }
+ const queryParams = {
+ pageNum: 1,
+ pageSize: 9999,
+ companyId: state.form.companyId
+ }
+ const res = await getUser(queryParams)
+ if(res.code == 200){
+ state.peopleList = res.data.list?res.data.list:[]
+ }else{
+ ElMessage.warning(res.message)
+ }
+};
+
+
+
+const selectValueCom = (val) => {
+ state.form.applyUser = null
+ state.form.deptUser = null
+ state.form.financeUser = null
+ state.form.deptId = null
+ state.companyList.forEach(item => {
+ if(item.name === val){
+ state.form.companyId = item.id
+ }
+ })
+ getDeptList()
+ getPeopleList()
+}
+
+const handleChangeNum = (value) => {
+ if (!/^\d+$/.test(value)) { // 验证是否为数字
+ ElMessage.warning('只能输入数字')
+ state.form.year = '' // 重置选择,避免非法值被添加到options中
+ } else if (!state.yearList.some(option => option.label === value)) { // 确保不是已存在的选项
+ state.yearList.push({ value, label: value }); // 添加新选项(这里简单地将值和标签设为相同)
+ }
+}
+// const addTableData = () => {
+// state.form.purchaseApplyPlans.push({})
+// }
+// const delTableData = (val) => {
+// state.form.purchaseApplyPlans = state.form.purchaseApplyPlans.filter(item=> item != val)
+// }
+
+
+const summaryData = computed(() => {
+ return state.form.purchaseApplyPlans.reduce((acc, row) => {
+ const money = Number(row.money) || 0
+ const quantity = Number(row.amount) || 0
+ acc.money += money
+ acc.amount += quantity
+ return acc
+ }, {
+ money: 0,
+ amount: 0,
+ })
+})
+// 格式化货币显示
+const formatCurrency = (value) => {
+ return '¥' + (Number(value) || 0).toFixed(2)
+}
+// 自定义合计行方法
+const getSummaries = ({ columns }) => {
+ const sums = []
+ const data = summaryData.value
+ columns.forEach((column, index) => {
+ if (index === 0) {
+ sums[index] = `合计`
+ return
+ }
+ switch (column.property) {
+ case 'money':
+ sums[index] = `${formatCurrency(data.money)}`
+ break
+ case 'amount':
+ sums[index] = data.amount
+ break
+ default:
+ sums[index] = ''
+ }
+ })
+
+ return sums
+}
+// 防抖更新 - 防止频繁触发重计算
+const debouncedUpdate = debounce(() => {
+ // 强制更新表格布局
+ tableRef.value?.doLayout()
+}, 300)
+
+// 输入框失去焦点时的处理
+const handleBlur = (row, field) => {
+ row[field] = Number(row[field]) || 0
+ debouncedUpdate()
+}
+// 添加新行
+const addTableData = () => {
+ state.form.purchaseApplyPlans.push({
+ money: null,
+ amount: null
+ })
+
+ debouncedUpdate()
+}
+// 删除行
+const delTableData = (index) => {
+ state.form.purchaseApplyPlans.splice(index, 1)
+ debouncedUpdate()
+}
+
+
+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/work/procurementPlatform/purchaseRequisition/index.vue b/src/views/work/procurementPlatform/purchaseRequisition/index.vue
new file mode 100644
index 0000000..6f4b804
--- /dev/null
+++ b/src/views/work/procurementPlatform/purchaseRequisition/index.vue
@@ -0,0 +1,286 @@
+<template>
+ <div class="app-container">
+ <div style="margin-bottom: 10px">
+ <el-form style="display: flex;flex-wrap: wrap;">
+ <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.companyId" placeholder="请选择" filterable clearable>
+ <el-option
+ v-for="item in data.companyList"
+ :key="item.id"
+ :label="item.name"
+ :value="item.id">
+ </el-option>
+ </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="applyName" align="center" />
+ <el-table-column label="申请部门" prop="deptName" align="center" />
+ <el-table-column label="申请人" prop="applyUserName" align="center" />
+ <el-table-column label="操作" align="center" class-naame="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>
+ <editDialog ref="noticeRef" @getList = "getList"></editDialog>
+ </div>
+</template>
+
+<script setup>
+import {getCurrentInstance, onMounted, reactive, ref, toRefs} from "vue";
+import editDialog from "./components/editDialog.vue"
+import {ElMessage, ElMessageBox} from "element-plus";
+import {getCompany} from "@/api/onlineEducation/company";
+import Cookies from "js-cookie";
+import {generateWordDocument} from "@/utils/exportWord";
+import {delTable, getTable} from "@/api/qualityObjectives/table";
+import {delDiscern, getDiscern} from "@/api/environment/factors";
+import {delApply, getApply} from "@/api/procurementPlatform/procurementPlatform";
+const { proxy } = getCurrentInstance();
+const loading = ref(false);
+const noticeRef = ref();
+const deptRef = ref()
+const loadingCompany = ref(false)
+const choosedData = ref([])
+const data = reactive({
+ queryParams: {
+ pageNum: 1,
+ pageSize: 10,
+ companyId: null,
+ year: '',
+ type: ''
+ },
+ companyList: [],
+ isAdmin: false,
+ dialogVisible: false,
+ yearList: [
+ {
+ value: 1,
+ label: '2025'
+ },
+ {
+ value: 2,
+ label: '2024'
+ },
+ {
+ value: 3,
+ label: '2023'
+ },
+ {
+ value: 4,
+ label: '2022'
+ },
+ {
+ value: 5,
+ label: '2021'
+ },
+ ],
+});
+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;
+ if(data.isAdmin){
+ data.queryParams.companyId = null
+ }else {
+ data.queryParams.companyId = userInfo.companyId
+ }
+ getList();
+ if(data.isAdmin){
+ getCompanyList()
+ }
+});
+const getList = async () => {
+ loading.value = true;
+ const res = await getApply(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,data.companyList);
+}
+
+const selectValue = (val) => {
+ data.companyList.forEach(item => {
+ if(item.name === val){
+ data.queryParams.companyId = item.id
+ }
+ })
+}
+
+const getCompanyList = async ()=>{
+ const queryParams = {
+ pageNum: 1,
+ pageSize: 999
+ }
+ const res = await getCompany(queryParams)
+ if (res.code == 200) {
+ data.companyList = res.data.list?res.data.list:[]
+ } else {
+ ElMessage.warning(res.message)
+ }
+}
+
+const handleSizeChange = (val) => {
+ data.queryParams.pageSize = val
+ getList()
+}
+const handleCurrentChange = (val) => {
+ data.queryParams.pageNum = val
+ getList()
+}
+const handleClose = () => {
+ data.dialogVisible = false
+}
+
+/** 重置新增的表单以及其他数据 */
+function reset() {
+ if(data.isAdmin){
+ data.queryParams = {
+ companyId: '',
+ pageNum: 1,
+ pageSize: 10,
+ year: '',
+ type: ''
+ }
+ choosedData.value = []
+ data.companyList = [];
+ getCompanyList()
+ }else {
+ data.queryParams = {
+ companyId: data.queryParams.companyId,
+ pageNum: 1,
+ pageSize: 10,
+ year: '',
+ type: ''
+ }
+ }
+ getList();
+
+}
+const exportData = () => {
+ if(choosedData.value && choosedData.value.length === 0){
+ ElMessage.warning('请选择需要导出的数据')
+ }else {
+ startGeneration()
+ }
+}
+const templatePath = ref('/purchaseRequisitionExample.docx')
+const startGeneration = async () => {
+ const data = JSON.parse(JSON.stringify(choosedData.value))
+ let amountSum = 0
+ let moneySum = 0
+ data.forEach(item => {
+ amountSum = 0
+ moneySum = 0
+ item.applyTime = item.applyTime.substring(0,10)
+ item.purchaseApplyPlans.forEach(i => {
+ amountSum += i.amount
+ moneySum += i.money
+ })
+ item.amountSum = amountSum
+ item.moneySum = moneySum.toFixed(2)
+ item.tableList = item.purchaseApplyPlans.map((item,index) => {
+ return {
+ ...item,
+ num: index +1 ,
+ }
+ })
+
+ try {
+ generateWordDocument(templatePath.value, 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 delApply(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/work/qualityInfo/supplierQuality/satisfiedEvaluste/deliver/components/editDialog.vue b/src/views/work/qualityInfo/supplierQuality/satisfiedEvaluste/deliver/components/editDialog.vue
new file mode 100644
index 0000000..49fa348
--- /dev/null
+++ b/src/views/work/qualityInfo/supplierQuality/satisfiedEvaluste/deliver/components/editDialog.vue
@@ -0,0 +1,391 @@
+<template>
+ <div class="notice">
+ <el-dialog
+ v-model="dialogVisible"
+ :title="title"
+ width="700px"
+ :before-close="handleClose"
+ :close-on-press-escape="false"
+ :close-on-click-modal="false"
+ >
+ <el-form :model="state.form" size="default" ref="busRef" :rules="state.rules" >
+ <el-row :gutter="24">
+ <el-col :span="24">
+ <el-form-item label="企业名称:" prop="companyId" v-if="state.isAdmin">
+ <el-select v-model="state.form.companyId" placeholder="请选择" filterable clearable style="width: 100%" :disabled="title == '查看' || title == '编辑' || !state.isAdmin" @change="selectValueCom">
+ <el-option
+ v-for="item in state.companyList"
+ :key="item.id"
+ :label="item.name"
+ :value="item.id">
+ </el-option>
+ </el-select>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="24">
+ <el-col :span="12">
+ <el-form-item label="问卷名称:" prop="questionName" >
+ <el-input :disabled="title === '查看'" v-model="state.form.questionName" placeholder="问卷名称"></el-input>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="编号:" prop="number" >
+ <el-input :disabled="title === '查看'" v-model="state.form.number" placeholder="编号"></el-input>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="24">
+ <el-col :span="12">
+ <el-form-item label="单位名称:" prop="unitName" >
+ <el-input :disabled="title === '查看'" v-model="state.form.unitName" placeholder="单位名称"></el-input>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="联系人:" prop="person" >
+ <el-input :disabled="title === '查看'" v-model="state.form.person" placeholder="联系人"></el-input>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="24">
+ <el-col :span="12">
+ <el-form-item label="联系地址:" prop="address" >
+ <el-input :disabled="title === '查看'" v-model="state.form.address" placeholder="联系地址"></el-input>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="电话、传真:" prop="phone" >
+ <el-input :disabled="title === '查看'" v-model="state.form.phone" placeholder="电话、传真"></el-input>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="24">
+ <el-col :span="24">
+ <div style="display:flex;flex-direction: column">
+ <span style="font-size: 11px;font-weight: 700;margin-bottom: 5px" >贵单位使用我所何种类型的产品(可多选,在相应的选项“⬜︎︎︎”内打“√”):</span>
+ <el-checkbox-group v-model="state.checkProductTypes" size="small" :disabled="title === '查看'" style="display:flex;flex-wrap: wrap;margin-left: 20px">
+ <div v-for="item in state.productTypeList">
+ <el-checkbox :label="item.id" :key="item.id" style="margin-left: 20px;">{{item.name}}</el-checkbox>
+ </div>
+ </el-checkbox-group>
+ </div>
+ <div style="display: flex;align-items: center;margin-top: 5px">
+ <span style="font-size: 11px;font-weight: 700;margin-bottom: 5px;margin-right: 10px" >请注明产品的名称(如有保密情况可以不填):</span>
+ <el-input style="width: 200px;" size="small" :disabled="title === '查看'" v-model="state.form.productName"></el-input>
+ </div>
+ </el-col>
+ </el-row>
+ <el-row :gutter="24">
+ <el-col :span="24">
+ <el-table style="margin: 20px 0" :data="state.dataList" :border="true">
+ <el-table-column label="序号" width="80" prop="num" align="center"></el-table-column>
+ <el-table-column label="调查项目" prop="item" align="center" >
+ <template #default="scope">
+ <div v-if="scope.row.num == '说明'">
+ <span>{{scope.row.item}}</span>
+ </div>
+ <div v-else style="display: flex;align-items: center">
+ <span v-if="scope.row.num == 1" style="width: 210px">交付产品质量:</span>
+ <span v-if="scope.row.num == 2" style="width: 210px">项目进度的符合性:</span>
+ <span v-if="scope.row.num == 3" style="width: 210px">售后服务情况:</span>
+ <span v-if="scope.row.num == 4" style="width: 210px">技术/售后服务人员:</span>
+ <span v-if="scope.row.num == 5" style="width: 210px">市场人员服务与跟踪意识:</span>
+ <el-checkbox-group v-model="scope.row.checkItem" size="small" :disabled="title === '查看'" style="display:flex;flex-wrap: wrap;width: 600px;margin-left: 10px">
+ <div v-for="item in scope.row.item">
+ <el-checkbox style="margin-right: 15px" :label="item" :key="item" >{{item}}</el-checkbox>
+ </div>
+ </el-checkbox-group>
+ </div>
+ </template>
+ </el-table-column>
+ <el-table-column label="满意度" prop="satisfied" align="center" >
+ <template #default="scope">
+ <div v-if="scope.row.num == '说明'">
+ <span>{{scope.row.satisfied}}</span>
+ </div>
+ <el-radio-group v-else v-model="scope.row.check" size="small" :disabled="title === '查看'" style="display:flex;flex-wrap: wrap;margin-left: 20px">
+ <div v-for="item in scope.row.satisfied">
+ <el-radio style="margin-right: 15px" :label="item" :key="item" >{{item}}</el-radio>
+ </div>
+ </el-radio-group>
+ </template>
+ </el-table-column>
+ </el-table>
+ </el-col>
+ </el-row>
+ <el-row :gutter="24">
+ <el-col :span="24">
+ <span style="font-size: 12px;font-weight: 700;margin-bottom: 5px" >重点说明不满意的原因以及其他意见、要求或建议,如同类产品的差距、市场信息、改进的建议等:</span>
+ <el-input style="margin-top: 5px" :disabled="title === '查看'" v-model="state.form.suggest" type="textarea" :rows="4"></el-input>
+ </el-col>
+ </el-row>
+ </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 {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";
+import {getDept, getObject, getObjectPage} from "@/api/qualityObjectives/object";
+import {addTable, editTable, getTargetById} from "@/api/qualityObjectives/table";
+import {addNeedDiscren, editNeedDiscren} from "@/api/need/need";
+import {verifyPhone} from "@/utils/validate";
+import {developList} from "@/views/work/qualityInfo/supplierQuality/supplierList/components/qualityDatas";
+import {addDelivery, editDelivery} from "@/api/satisfiedNew/satisfiedNew";
+
+const dialogVisible = ref(false);
+const title = ref("");
+const busRef = ref();
+const length = ref()
+const selectPopperClass = "max-width-select";
+const emit = defineEmits(["getList"]);
+const dataRef = ref();
+const validatePhone = (rule, value, callback)=>{
+ if(value === ''){
+ callback(new Error('请输入手机号'))
+ }else{
+ if(!verifyPhone(value)){
+ callback(new Error('手机号格式有误'))
+ }else{
+ callback()
+ }
+ }
+}
+const state = reactive({
+ form: {
+ id: '',
+ companyId: null,
+ questionName: null,
+ number: '',
+ unitName: null,
+ person: null,
+ address: null,
+ phone: null,
+ product: '',
+ productName:'',
+ mess: '',
+ suggest: ''
+ },
+ rules: {
+ companyId: [{ required: true, message: '请选择企业', trigger: 'blur' }],
+ questionName: [{ required: true, message: '请输入问卷名称', trigger: 'blur' }],
+ number: [{ required: true, message: '请输入编号', trigger: 'blur' }],
+ unitName: [{ required: true, message: '请输入单位名称', trigger: 'blur' }],
+ person: [{ required: true, message: '请输入联系人', trigger: 'blur' }],
+ address: [{ required: true, message: '请输入联系地址', trigger: 'blur' }],
+ product: [{ required: true, message: '请选择产品', trigger: 'blur' }],
+ phone: [{required: true, trigger: "blur", validator: validatePhone}],
+
+ },
+ isAdmin: false,
+ companyList: [],
+ dataList: [
+ {
+ num: '说明',
+ item: '哪项不满意,请在相应的选项“⬜︎︎︎”内打“√”',
+ satisfied:'总体评价,请在相应的选项“⬜︎︎︎”内打“√”'
+ },
+ {
+ num: '1',
+ item: ['产品性能','技术资料','操作性','维护性','稳定性'],
+ satisfied:['满意','基本满意','不满意']
+ },
+ {
+ num: '2',
+ item: ['节点控制','交付及时性','可靠性'],
+ satisfied:['满意','基本满意','不满意']
+ },
+ {
+ num: '3',
+ item: ['顾客培训','技术支持','售后维修','备品及备件供应'],
+ satisfied:['满意','基本满意','不满意']
+ },
+ {
+ num: '4',
+ item: ['技术技能','服务态度','过程规范','综合素质'],
+ satisfied:['满意','基本满意','不满意']
+ },
+ {
+ num: '5',
+ item: ['服务的及时性','有效性','服务态度'],
+ satisfied:['满意','基本满意','不满意']
+ },
+ ],
+ productTypeList: [
+ {
+ id: 1,
+ name: '系统'
+ },
+ {
+ id: 2,
+ name: '软件'
+ },
+ {
+ id: 3,
+ name: '整机'
+ },
+ {
+ id: 4,
+ name: '试剂柜'
+ },
+ {
+ id: 5,
+ name: '印制板'
+ },
+ {
+ id: 6,
+ name: '手持终端'
+ },
+ {
+ id: 7,
+ name: '其他'
+ },
+ ],
+ checkProductTypes: []
+})
+
+onMounted(() => {
+
+
+});
+const openDialog = async (type, value,companyList) => {
+ const userInfo = JSON.parse(Cookies.get('userInfo'))
+ state.isAdmin = userInfo.userType === 0;
+ state.form.companyName = userInfo.companyName
+ state.form.companyId = userInfo.companyId
+ if(state.isAdmin){
+ state.form.companyId = value.companyId
+ state.form.companyName = value.companyName
+ state.companyList = companyList
+ }
+ title.value = type === 'add' ? '新增' : type ==='edit' ? '编辑' : '查看' ;
+ if(type === 'edit' || type === 'review') {
+ state.form = JSON.parse(JSON.stringify(value));
+ if(state.isAdmin){
+ state.form.companyId = value.companyId
+ state.form.companyName = value.companyName
+ }
+ //解析json
+ state.dataList = JSON.parse(value.mess)
+ state.checkProductTypes = value.product.split(',').map(Number)
+ }
+ dialogVisible.value = true;
+}
+
+const onSubmit = async () => {
+ state.form.mess = JSON.stringify(state.dataList)
+ state.form.product = state.checkProductTypes.join(',')
+ 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 addDelivery(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 editDelivery(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: '',
+ companyId: null,
+ deptId: null,
+ year: '',
+ fictionId: null,
+ checkId: null,
+ ratifyId: null,
+ fictionTime: null,
+ frequency: '',
+ expectContents:[],
+ }
+ state.checkProductTypes = []
+ state.companyList = []
+}
+
+
+
+const selectValueCom = (val) => {
+ state.form.fictionId = null
+ state.form.checkId = null
+ state.form.ratifyId = null
+ state.form.deptId = null
+ state.companyList.forEach(item => {
+ if(item.name === val){
+ state.form.companyId = item.id
+ }
+ })
+}
+
+const handleChangeNum = (value) => {
+ if (!/^\d+$/.test(value)) { // 验证是否为数字
+ ElMessage.warning('只能输入数字')
+ state.form.year = '' // 重置选择,避免非法值被添加到options中
+ } else if (!state.yearList.some(option => option.label === value)) { // 确保不是已存在的选项
+ state.yearList.push({ value, label: value }); // 添加新选项(这里简单地将值和标签设为相同)
+ }
+}
+
+defineExpose({
+ openDialog
+});
+
+</script>
+
+<style scoped lang="scss">
+.notice{
+ :deep(.el-form .el-form-item__label) {
+ font-size: 15px;
+ }
+ :deep(.el-table .cell){
+ font-size: small;
+ }
+ .file {
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+ }
+}
+</style>
diff --git a/src/views/work/qualityInfo/supplierQuality/satisfiedEvaluste/deliver/index.vue b/src/views/work/qualityInfo/supplierQuality/satisfiedEvaluste/deliver/index.vue
new file mode 100644
index 0000000..f2acac4
--- /dev/null
+++ b/src/views/work/qualityInfo/supplierQuality/satisfiedEvaluste/deliver/index.vue
@@ -0,0 +1,270 @@
+<template>
+ <div class="app-container">
+ <div style="margin-bottom: 10px">
+ <el-form style="display: flex;flex-wrap: wrap;">
+ <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.companyId" placeholder="请选择" filterable clearable>
+ <el-option
+ v-for="item in data.companyList"
+ :key="item.id"
+ :label="item.name"
+ :value="item.id">
+ </el-option>
+ </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="questionName" align="center" />
+ <el-table-column label="操作" align="center" class-naame="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>
+ <editDialog ref="noticeRef" @getList = "getList"></editDialog>
+ </div>
+</template>
+
+<script setup>
+import {getCurrentInstance, onMounted, reactive, ref, toRefs} from "vue";
+import editDialog from "./components/editDialog.vue"
+import {ElMessage, ElMessageBox} from "element-plus";
+import {getCompany} from "@/api/onlineEducation/company";
+import Cookies from "js-cookie";
+import {generateWordDocument} from "@/utils/exportWord";
+import {delTable, getTable} from "@/api/qualityObjectives/table";
+import {delDiscern, getDiscern} from "@/api/environment/factors";
+import {delDelivery, getDelivery} from "@/api/satisfiedNew/satisfiedNew";
+const { proxy } = getCurrentInstance();
+const loading = ref(false);
+const noticeRef = ref();
+const deptRef = ref()
+const loadingCompany = ref(false)
+const choosedData = ref([])
+const data = reactive({
+ queryParams: {
+ pageNum: 1,
+ pageSize: 10,
+ companyId: null,
+ year: '',
+ type: ''
+ },
+ companyList: [],
+ isAdmin: false,
+ dialogVisible: 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;
+ if(data.isAdmin){
+ data.queryParams.companyId = null
+ }else {
+ data.queryParams.companyId = userInfo.companyId
+ }
+ getList();
+ if(data.isAdmin){
+ getCompanyList()
+ }
+});
+const getList = async () => {
+ loading.value = true;
+ const res = await getDelivery(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,data.companyList);
+}
+
+const selectValue = (val) => {
+ data.companyList.forEach(item => {
+ if(item.name === val){
+ data.queryParams.companyId = item.id
+ }
+ })
+}
+
+const getCompanyList = async ()=>{
+ const queryParams = {
+ pageNum: 1,
+ pageSize: 999
+ }
+ const res = await getCompany(queryParams)
+ if (res.code == 200) {
+ data.companyList = res.data.list?res.data.list:[]
+ } else {
+ ElMessage.warning(res.message)
+ }
+}
+
+const handleSizeChange = (val) => {
+ data.queryParams.pageSize = val
+ getList()
+}
+const handleCurrentChange = (val) => {
+ data.queryParams.pageNum = val
+ getList()
+}
+const handleClose = () => {
+ data.dialogVisible = false
+}
+
+/** 重置新增的表单以及其他数据 */
+function reset() {
+ if(data.isAdmin){
+ data.queryParams = {
+ companyId: '',
+ pageNum: 1,
+ pageSize: 10,
+ year: '',
+ type: ''
+ }
+ choosedData.value = []
+ data.companyList = [];
+ getCompanyList()
+ }else {
+ data.queryParams = {
+ companyId: data.queryParams.companyId,
+ pageNum: 1,
+ pageSize: 10,
+ year: '',
+ type: ''
+ }
+ }
+ getList();
+
+}
+const exportData = () => {
+ if(choosedData.value && choosedData.value.length === 0){
+ ElMessage.warning('请选择需要导出的数据')
+ }else {
+ startGeneration()
+ }
+}
+const templatePath = ref('/environmentalFactorsExample.docx')
+const startGeneration = async () => {
+ const data = JSON.parse(JSON.stringify(choosedData.value))
+ data.forEach(item => {
+ item.fictionTime = item.fictionTime.substring(0,10)
+ console.log('u',item)
+ const datax = idGroupToTree(item.factorContents)
+ item.tableList = datax.map((item,index) => {
+ return {
+ ...item,
+ fileList: item.children.map((f,findex) => {
+ return{
+ ...f,
+ first: findex == 0,
+ typeName: f.type == 1 ? '外部环境' : '内部环境'
+ }
+ })
+ }
+ })
+ console.log(' item.tableList', item.tableList)
+ try {
+ generateWordDocument(templatePath.value, item, item.companyName+`_${item.year}年内、外部环境要素识别表.docx`);
+ } catch (error){
+ ElMessage({
+ type: 'warning',
+ message: '导出失败'
+ });
+ }
+ })
+}
+function idGroupToTree(data) {
+ const groups = data.reduce((map, item) => {
+ map.has(item.type) || map.set(item.type, []);
+ map.get(item.type).push(item);
+ return map;
+ }, new Map());
+ return Array.from(groups).map(([type, items]) => ({
+ type,
+ children: items
+ }));
+}
+const handleSelectionChange = (val) => {
+ choosedData.value = val
+}
+const handleDelete = (val) => {
+ ElMessageBox.confirm(
+ '确定删除此条数据?',
+ '提示',
+ {
+ confirmButtonText: '确定',
+ cancelButtonText: '取消',
+ type: 'warning',
+ })
+ .then( async() => {
+ const res = await delDelivery(val.id);
+ if(res.code === 200){
+ ElMessage({
+ type: 'success',
+ message: '删除成功'
+ });
+ await getList();
+ }else{
+ ElMessage.warning(res.message)
+ }
+ })
+}
+
+
+</script>
+<style lang="scss">
+.pag-container{
+ float: right;
+ margin-top: 10px;
+}
+</style>
diff --git a/src/views/work/qualityInfo/supplierQuality/satisfiedEvaluste/report/components/editDialog.vue b/src/views/work/qualityInfo/supplierQuality/satisfiedEvaluste/report/components/editDialog.vue
new file mode 100644
index 0000000..7721461
--- /dev/null
+++ b/src/views/work/qualityInfo/supplierQuality/satisfiedEvaluste/report/components/editDialog.vue
@@ -0,0 +1,390 @@
+<template>
+ <div class="notice">
+ <el-dialog
+ v-model="dialogVisible"
+ :title="title"
+ width="800px"
+ :before-close="handleClose"
+ :close-on-press-escape="false"
+ :close-on-click-modal="false"
+ >
+ <el-form :model="state.form" size="default" ref="busRef" :rules="state.rules" label-position="left" label-width="135">
+ <el-row :gutter="24">
+ <el-col :span="24">
+ <el-form-item label="企业名称:" prop="companyId" v-if="state.isAdmin">
+ <el-select v-model="state.form.companyId" placeholder="请选择" filterable clearable style="width: 100%" :disabled="title == '查看' || title == '编辑' || !state.isAdmin" @change="selectValueCom">
+ <el-option
+ v-for="item in state.companyList"
+ :key="item.id"
+ :label="item.name"
+ :value="item.id">
+ </el-option>
+ </el-select>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="24">
+ <el-col :span="12">
+ <el-form-item label="报告名称:" prop="reportName" >
+ <el-input :disabled="title === '查看'" v-model="state.form.reportName" placeholder="报告名称"></el-input>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="编号:" prop="number" >
+ <el-input :disabled="title === '查看'" v-model="state.form.number" placeholder="编号"></el-input>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="24">
+ <el-col :span="12">
+ <el-form-item label="实施调查的部门:" prop="deptId" >
+ <el-select v-model="state.form.deptId" placeholder="请选择" :disabled="title === '查看'" clearable>
+ <el-option
+ v-for="item in state.deptList"
+ :key="item.deptId"
+ :label="item.deptName"
+ :value="item.deptId">
+ </el-option>
+ </el-select>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="调查结束日期:" prop="endTime" >
+ <el-date-picker
+ :disabled="title === '查看'"
+ v-model="state.form.endTime"
+ type="date"
+ placeholder="请选择"
+ />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <div style="text-align: center;font-weight: 600;font-size: 18px;margin-bottom: 15px">调查情况</div>
+ <el-row :gutter="24">
+ <el-col :span="8">
+ <el-form-item label="问卷发放数:" prop="grantAmount" >
+ <el-input :disabled="title === '查看'" v-model="state.form.grantAmount" placeholder="问卷发放数"></el-input>
+ </el-form-item>
+ </el-col>
+ <el-col :span="8">
+ <el-form-item label="问卷回收数:" prop="recycleAmount" >
+ <el-input :disabled="title === '查看'" v-model="state.form.recycleAmount" placeholder="问卷回收数"></el-input>
+ </el-form-item>
+ </el-col>
+ <el-col :span="8">
+ <el-form-item label="回收率:" prop="recycleRate" >
+ <el-input :disabled="title === '查看'" v-model="state.form.recycleRate" placeholder="回收率"></el-input>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="24">
+ <el-col :span="8">
+ <el-form-item label="检查的项目总数:" prop="checkAmount" >
+ <el-input :disabled="title === '查看'" v-model="state.form.checkAmount" placeholder="检查的项目总数"></el-input>
+ </el-form-item>
+ </el-col>
+ <el-col :span="8">
+ <el-form-item label="今年项目覆盖率:" prop="yearRate" >
+ <el-input :disabled="title === '查看'" v-model="state.form.yearRate" placeholder="今年项目覆盖率"></el-input>
+ </el-form-item>
+ </el-col>
+ <el-col :span="8">
+ <el-form-item label="以往项目覆盖率:" prop="ancientlyRate" >
+ <el-input :disabled="title === '查看'" v-model="state.form.ancientlyRate" placeholder="以往项目覆盖率"></el-input>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="24">
+ <el-col :span="8">
+ <el-form-item label="在研项目顾客满意度:" prop="researchSatisficing" >
+ <el-input :disabled="title === '查看'" v-model="state.form.researchSatisficing" placeholder="在研项目顾客满意度"></el-input>
+ </el-form-item>
+ </el-col>
+ <el-col :span="8">
+ <el-form-item label="交付项目顾客满意度:" prop="deliverySatisficing" >
+ <el-input :disabled="title === '查看'" v-model="state.form.deliverySatisficing" placeholder="交付项目顾客满意度"></el-input>
+ </el-form-item>
+ </el-col>
+ <el-col :span="8">
+ <el-form-item label="总体顾客满意度:" prop="sumSatisficing" >
+ <el-input :disabled="title === '查看'" v-model="state.form.sumSatisficing" placeholder="总体顾客满意度"></el-input>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="24" style="margin-top: 15px">
+ <el-col :span="24" >
+ <span style="font-size: 14px;font-weight: 700;" >用户反馈的主要意见和建议:</span>
+ <el-input style="margin-top: 5px" :disabled="title === '查看'" v-model="state.form.suggest" type="textarea" :rows="4"></el-input>
+ </el-col>
+ </el-row>
+ <el-row :gutter="24" style="margin-top: 15px">
+ <el-col :span="24">
+ <el-form-item label="经办人:" prop="agentId" >
+ <el-select clearable v-model="state.form.agentId" :disabled="title =='查看'" filterable style="width: 240px">
+ <el-option
+ v-for="item in state.peopleList"
+ :key="item.id"
+ :label="item.name"
+ :value="item.id"
+ />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="24">
+ <el-col :span="24">
+ <el-form-item label="部门领导:" prop="deptUser" >
+ <el-select clearable v-model="state.form.deptUser" :disabled="title =='查看'" filterable style="width: 240px">
+ <el-option
+ v-for="item in state.peopleList"
+ :key="item.id"
+ :label="item.name"
+ :value="item.id"
+ />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ </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 {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";
+import {getDept, getObject, getObjectPage} from "@/api/qualityObjectives/object";
+import {addTable, editTable, getTargetById} from "@/api/qualityObjectives/table";
+import {addNeedDiscren, editNeedDiscren} from "@/api/need/need";
+import {verifyPhone} from "@/utils/validate";
+import {developList} from "@/views/work/qualityInfo/supplierQuality/supplierList/components/qualityDatas";
+import {getDepart} from "@/api/orgStructure/depart";
+import {addReport, editReport} from "@/api/satisfiedNew/satisfiedNew";
+
+const dialogVisible = ref(false);
+const title = ref("");
+const busRef = ref();
+const length = ref()
+const selectPopperClass = "max-width-select";
+const emit = defineEmits(["getList"]);
+const dataRef = ref();
+const validatePhone = (rule, value, callback)=>{
+ if(value === ''){
+ callback(new Error('请输入手机号'))
+ }else{
+ if(!verifyPhone(value)){
+ callback(new Error('手机号格式有误'))
+ }else{
+ callback()
+ }
+ }
+}
+const state = reactive({
+ form: {
+ id: '',
+ companyId: null,
+ deptId: null,
+ reportName: '',
+ number: null,
+ endTime: null,
+ grantAmount: null,
+ recycleAmount: null,
+ recycleRate: '',
+ checkAmount:'',
+ yearRate:'',
+ ancientlyRate:'',
+ researchSatisficing:'',
+ deliverySatisficing:'',
+ sumSatisficing:'',
+ suggest:'',
+ agentId:'',
+ deptUser:'',
+ },
+ rules: {
+ companyId: [{ required: true, message: '请选择企业', trigger: 'blur' }],
+ reportName: [{ required: true, message: '请输入报告名称', trigger: 'blur' }],
+ number: [{ required: true, message: '请输入编号', trigger: 'blur' }],
+ deptId: [{ required: true, message: '请选择实施部门', trigger: 'blur' }],
+ endTime: [{ required: true, message: '请选择调查结束日期', trigger: 'blur' }],
+ grantAmount: [{ required: true, message: '请输入问卷发放数', trigger: 'blur' }],
+ recycleAmount: [{ required: true, message: '请输入问卷回收数', trigger: 'blur' }],
+ recycleRate: [{ required: true, message: '请输入回收率', trigger: 'blur' }],
+ checkAmount: [{ required: true, message: '请输入检查项目数量', trigger: 'blur' }],
+ yearRate: [{ required: true, message: '请输入今年覆盖率', trigger: 'blur' }],
+ ancientlyRate: [{ required: true, message: '请输入以往覆盖率', trigger: 'blur' }],
+ researchSatisficing: [{ required: true, message: '请输入在研满意度', trigger: 'blur' }],
+ deliverySatisficing: [{ required: true, message: '请输入交付满意度', trigger: 'blur' }],
+ sumSatisficing: [{ required: true, message: '请输入总体满意度', trigger: 'blur' }],
+ agentId: [{ required: true, message: '请选择经办人', trigger: 'blur' }],
+ deptUser: [{ required: true, message: '请选择部门领导', trigger: 'blur' }],
+
+ },
+ isAdmin: false,
+ companyList: [],
+ deptList:[],
+ peopleList: [],
+})
+
+onMounted(() => {
+
+
+});
+const openDialog = async (type, value,companyList) => {
+ const userInfo = JSON.parse(Cookies.get('userInfo'))
+ state.isAdmin = userInfo.userType === 0;
+ state.form.companyName = userInfo.companyName
+ state.form.companyId = userInfo.companyId
+ if(state.isAdmin){
+ state.form.companyId = value.companyId
+ state.form.companyName = value.companyName
+ state.companyList = companyList
+ }
+ title.value = type === 'add' ? '新增' : type ==='edit' ? '编辑' : '查看' ;
+ if(type === 'edit' || type === 'review') {
+ state.form = JSON.parse(JSON.stringify(value));
+ if(state.isAdmin){
+ state.form.companyId = value.companyId
+ state.form.companyName = value.companyName
+ }
+ // state.dataList = JSON.parse(value.data)
+ }
+ await getDepartList()
+ await getPeopleList()
+ dialogVisible.value = true;
+}
+
+const onSubmit = async () => {
+ state.form.mess = JSON.stringify(state.dataList)
+ 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 addReport(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 editReport(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: '',
+ companyId: null,
+ deptId: null,
+ year: '',
+ fictionId: null,
+ checkId: null,
+ ratifyId: null,
+ fictionTime: null,
+ frequency: '',
+ expectContents:[],
+ }
+ state.checkProductTypes = []
+ state.companyList = []
+}
+const getDepartList = async (companyId)=> {
+ const params = {
+ companyId: companyId
+ }
+ const res = await getDepart(params)
+ if(res.code == 200){
+ state.deptList = res.data
+ }else{
+ ElMessage.warning(res.message)
+ }
+}
+
+const getPeopleList = async ()=> {
+ if(state.isAdmin && (state.form.companyId == 0 || state.form.companyId == null)){
+ return
+ }
+ const queryParams = {
+ pageNum: 1,
+ pageSize: 9999,
+ companyId: state.form.companyId
+ }
+ const res = await getUser(queryParams)
+ if(res.code == 200){
+ state.peopleList = res.data.list?res.data.list:[]
+ }else{
+ ElMessage.warning(res.message)
+ }
+};
+
+const selectValueCom = async (val) => {
+ state.form.agentId = null
+ state.form.deptUser = null
+ state.form.deptId = null
+ state.companyList.forEach(item => {
+ if(item.name === val){
+ state.form.companyId = item.id
+ }
+ })
+ await getDepartList()
+ await getPeopleList()
+}
+
+
+
+defineExpose({
+ openDialog
+});
+
+</script>
+
+<style scoped lang="scss">
+.notice{
+ :deep(.el-form .el-form-item__label) {
+ font-size: 15px;
+ }
+ :deep(.el-table .cell){
+ font-size: small;
+ }
+ .file {
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+ }
+}
+</style>
diff --git a/src/views/work/qualityInfo/supplierQuality/satisfiedEvaluste/report/index.vue b/src/views/work/qualityInfo/supplierQuality/satisfiedEvaluste/report/index.vue
new file mode 100644
index 0000000..745859f
--- /dev/null
+++ b/src/views/work/qualityInfo/supplierQuality/satisfiedEvaluste/report/index.vue
@@ -0,0 +1,271 @@
+<template>
+ <div class="app-container">
+ <div style="margin-bottom: 10px">
+ <el-form style="display: flex;flex-wrap: wrap;">
+ <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.companyId" placeholder="请选择" filterable clearable>
+ <el-option
+ v-for="item in data.companyList"
+ :key="item.id"
+ :label="item.name"
+ :value="item.id">
+ </el-option>
+ </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="reportName" align="center" />
+ <el-table-column label="操作" align="center" class-naame="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>
+ <editDialog ref="noticeRef" @getList = "getList"></editDialog>
+ </div>
+</template>
+
+<script setup>
+import {getCurrentInstance, onMounted, reactive, ref, toRefs} from "vue";
+import editDialog from "./components/editDialog.vue"
+import {ElMessage, ElMessageBox} from "element-plus";
+import {getCompany} from "@/api/onlineEducation/company";
+import Cookies from "js-cookie";
+import {generateWordDocument} from "@/utils/exportWord";
+import {delTable, getTable} from "@/api/qualityObjectives/table";
+import {delDiscern, getDiscern} from "@/api/environment/factors";
+import {delReport, getReport} from "@/api/satisfiedNew/satisfiedNew";
+const { proxy } = getCurrentInstance();
+const loading = ref(false);
+const noticeRef = ref();
+const deptRef = ref()
+const loadingCompany = ref(false)
+const choosedData = ref([])
+const data = reactive({
+ queryParams: {
+ pageNum: 1,
+ pageSize: 10,
+ companyId: null,
+ year: '',
+ type: ''
+ },
+ companyList: [],
+ isAdmin: false,
+ dialogVisible: 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;
+ if(data.isAdmin){
+ data.queryParams.companyId = null
+ }else {
+ data.queryParams.companyId = userInfo.companyId
+ }
+ getList();
+ if(data.isAdmin){
+ getCompanyList()
+ }
+});
+const getList = async () => {
+ loading.value = true;
+ const res = await getReport(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,data.companyList);
+}
+
+const selectValue = (val) => {
+ data.companyList.forEach(item => {
+ if(item.name === val){
+ data.queryParams.companyId = item.id
+ }
+ })
+}
+
+const getCompanyList = async ()=>{
+ const queryParams = {
+ pageNum: 1,
+ pageSize: 999
+ }
+ const res = await getCompany(queryParams)
+ if (res.code == 200) {
+ data.companyList = res.data.list?res.data.list:[]
+ } else {
+ ElMessage.warning(res.message)
+ }
+}
+
+const handleSizeChange = (val) => {
+ data.queryParams.pageSize = val
+ getList()
+}
+const handleCurrentChange = (val) => {
+ data.queryParams.pageNum = val
+ getList()
+}
+const handleClose = () => {
+ data.dialogVisible = false
+}
+
+/** 重置新增的表单以及其他数据 */
+function reset() {
+ if(data.isAdmin){
+ data.queryParams = {
+ companyId: '',
+ pageNum: 1,
+ pageSize: 10,
+ year: '',
+ type: ''
+ }
+ choosedData.value = []
+ data.companyList = [];
+ getCompanyList()
+ }else {
+ data.queryParams = {
+ companyId: data.queryParams.companyId,
+ pageNum: 1,
+ pageSize: 10,
+ year: '',
+ type: ''
+ }
+ }
+ getList();
+
+}
+const exportData = () => {
+ if(choosedData.value && choosedData.value.length === 0){
+ ElMessage.warning('请选择需要导出的数据')
+ }else {
+ startGeneration()
+ }
+}
+const templatePath = ref('/environmentalFactorsExample.docx')
+const startGeneration = async () => {
+ const data = JSON.parse(JSON.stringify(choosedData.value))
+ data.forEach(item => {
+ item.fictionTime = item.fictionTime.substring(0,10)
+ console.log('u',item)
+ const datax = idGroupToTree(item.factorContents)
+ item.tableList = datax.map((item,index) => {
+ return {
+ ...item,
+ fileList: item.children.map((f,findex) => {
+ return{
+ ...f,
+ first: findex == 0,
+ typeName: f.type == 1 ? '外部环境' : '内部环境'
+ }
+ })
+ }
+ })
+ console.log(' item.tableList', item.tableList)
+ try {
+ generateWordDocument(templatePath.value, item, item.companyName+`_${item.year}年内、外部环境要素识别表.docx`);
+ } catch (error){
+ ElMessage({
+ type: 'warning',
+ message: '导出失败'
+ });
+ }
+ })
+}
+function idGroupToTree(data) {
+ const groups = data.reduce((map, item) => {
+ map.has(item.type) || map.set(item.type, []);
+ map.get(item.type).push(item);
+ return map;
+ }, new Map());
+ return Array.from(groups).map(([type, items]) => ({
+ type,
+ children: items
+ }));
+}
+const handleSelectionChange = (val) => {
+ choosedData.value = val
+}
+const handleDelete = (val) => {
+ ElMessageBox.confirm(
+ '确定删除此条数据?',
+ '提示',
+ {
+ confirmButtonText: '确定',
+ cancelButtonText: '取消',
+ type: 'warning',
+ })
+ .then( async() => {
+ const res = await delReport(val.id);
+ if(res.code === 200){
+ ElMessage({
+ type: 'success',
+ message: '删除成功'
+ });
+ await getList();
+ }else{
+ ElMessage.warning(res.message)
+ }
+ })
+}
+
+
+</script>
+<style lang="scss">
+.pag-container{
+ float: right;
+ margin-top: 10px;
+}
+</style>
diff --git a/src/views/work/qualityInfo/supplierQuality/satisfiedEvaluste/research/components/editDialog.vue b/src/views/work/qualityInfo/supplierQuality/satisfiedEvaluste/research/components/editDialog.vue
new file mode 100644
index 0000000..3113075
--- /dev/null
+++ b/src/views/work/qualityInfo/supplierQuality/satisfiedEvaluste/research/components/editDialog.vue
@@ -0,0 +1,409 @@
+<template>
+ <div class="notice">
+ <el-dialog
+ v-model="dialogVisible"
+ :title="title"
+ width="700px"
+ :before-close="handleClose"
+ :close-on-press-escape="false"
+ :close-on-click-modal="false"
+ >
+ <el-form :model="state.form" size="default" ref="busRef" :rules="state.rules" >
+ <el-row :gutter="24">
+ <el-col :span="24">
+ <el-form-item label="企业名称:" prop="companyId" v-if="state.isAdmin">
+ <el-select v-model="state.form.companyId" placeholder="请选择" filterable clearable style="width: 100%" :disabled="title == '查看' || title == '编辑' || !state.isAdmin" @change="selectValueCom">
+ <el-option
+ v-for="item in state.companyList"
+ :key="item.id"
+ :label="item.name"
+ :value="item.id">
+ </el-option>
+ </el-select>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="24">
+ <el-col :span="12">
+ <el-form-item label="问卷名称:" prop="questionName" >
+ <el-input :disabled="title === '查看'" v-model="state.form.questionName" placeholder="问卷名称"></el-input>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="编号:" prop="number" >
+ <el-input :disabled="title === '查看'" v-model="state.form.number" placeholder="编号"></el-input>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="24">
+ <el-col :span="12">
+ <el-form-item label="单位名称:" prop="unitName" >
+ <el-input :disabled="title === '查看'" v-model="state.form.unitName" placeholder="单位名称"></el-input>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="联系人:" prop="person" >
+ <el-input :disabled="title === '查看'" v-model="state.form.person" placeholder="联系人"></el-input>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="24">
+ <el-col :span="12">
+ <el-form-item label="联系地址:" prop="address" >
+ <el-input :disabled="title === '查看'" v-model="state.form.address" placeholder="联系地址"></el-input>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="电话、传真:" prop="phone" >
+ <el-input :disabled="title === '查看'" v-model="state.form.phone" placeholder="电话、传真"></el-input>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="24">
+ <el-col :span="24">
+ <div style="display:flex;flex-direction: column">
+ <span style="font-size: 11px;font-weight: 700;margin-bottom: 5px" >贵单位使用我所何种类型的产品(可多选,在相应的选项“⬜︎︎︎”内打“√”):</span>
+ <el-checkbox-group v-model="state.checkProductTypes" size="small" :disabled="title === '查看'" style="display:flex;flex-wrap: wrap;margin-left: 20px">
+ <div v-for="item in state.productTypeList">
+ <el-checkbox :label="item.id" :key="item.id" style="margin-left: 20px;">{{item.name}}</el-checkbox>
+ </div>
+ </el-checkbox-group>
+ </div>
+ <div style="display: flex;align-items: center;margin-top: 5px">
+ <span style="font-size: 11px;font-weight: 700;margin-bottom: 5px;margin-right: 10px" >请注明产品的名称(如有保密情况可以不填):</span>
+ <el-input style="width: 200px;" size="small" :disabled="title === '查看'" v-model="state.form.productName"></el-input>
+ </div>
+ </el-col>
+ </el-row>
+ <el-row :gutter="24">
+ <el-col :span="24">
+ <el-table style="margin: 20px 0" :data="state.dataList" :border="true">
+ <el-table-column label="序号" width="80" prop="num" align="center"></el-table-column>
+ <el-table-column label="调查项目" prop="item" align="center" >
+ <template #default="scope">
+ <div v-if="scope.row.num == '说明'">
+ <span>{{scope.row.item}}</span>
+ </div>
+ <div v-else style="display: flex;align-items: center">
+ <span v-if="scope.row.num == 3" style="width: 210px">技术人员:</span>
+ <span v-if="scope.row.num == 4" style="width: 210px">市场人员服务与跟踪意识:</span>
+ <el-checkbox-group v-model="scope.row.checkItem" size="small" :disabled="title === '查看'" style="display:flex;flex-wrap: wrap;width: 600px;margin-left: 10px">
+ <div v-for="item in scope.row.item">
+ <el-checkbox style="margin-right: 15px" :label="item" :key="item" >{{item}}</el-checkbox>
+ </div>
+ </el-checkbox-group>
+ </div>
+ </template>
+ </el-table-column>
+ <el-table-column label="满意度" prop="satisfied" align="center" >
+ <template #default="scope">
+ <div v-if="scope.row.num == '说明'">
+ <span>{{scope.row.satisfied}}</span>
+ </div>
+ <el-radio-group v-else v-model="scope.row.check" size="small" :disabled="title === '查看'" style="display:flex;flex-wrap: wrap;margin-left: 20px">
+ <div v-for="item in scope.row.satisfied">
+ <el-radio style="margin-right: 15px" :label="item" :key="item" >{{item}}</el-radio>
+ </div>
+ </el-radio-group>
+ </template>
+ </el-table-column>
+ </el-table>
+ </el-col>
+ </el-row>
+ <el-row :gutter="24">
+ <el-col :span="24">
+ <span style="font-size: 12px;font-weight: 700;margin-bottom: 5px" >重点说明不满意的原因以及其他意见、要求或建议,如同类产品的差距、市场信息、改进的建议等:</span>
+ <el-input style="margin-top: 5px" :disabled="title === '查看'" v-model="state.form.suggest" type="textarea" :rows="4"></el-input>
+ </el-col>
+ </el-row>
+ </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 {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";
+import {getDept, getObject, getObjectPage} from "@/api/qualityObjectives/object";
+import {addTable, editTable, getTargetById} from "@/api/qualityObjectives/table";
+import {addNeedDiscren, editNeedDiscren} from "@/api/need/need";
+import {verifyPhone} from "@/utils/validate";
+import {developList} from "@/views/work/qualityInfo/supplierQuality/supplierList/components/qualityDatas";
+import {addResearch, editResearch} from "@/api/satisfiedNew/satisfiedNew";
+
+const dialogVisible = ref(false);
+const title = ref("");
+const busRef = ref();
+const length = ref()
+const selectPopperClass = "max-width-select";
+const emit = defineEmits(["getList"]);
+const dataRef = ref();
+const validatePhone = (rule, value, callback)=>{
+ if(value === ''){
+ callback(new Error('请输入手机号'))
+ }else{
+ if(!verifyPhone(value)){
+ callback(new Error('手机号格式有误'))
+ }else{
+ callback()
+ }
+ }
+}
+const state = reactive({
+ form: {
+ id: '',
+ companyId: null,
+ questionName: null,
+ number: '',
+ unitName: null,
+ person: null,
+ address: null,
+ phone: null,
+ product: '',
+ productName:'',
+ mess:'',
+ suggest: ''
+ },
+ rules: {
+ companyId: [{ required: true, message: '请选择企业', trigger: 'blur' }],
+ questionName: [{ required: true, message: '请输入问卷名称', trigger: 'blur' }],
+ number: [{ required: true, message: '请输入编号', trigger: 'blur' }],
+ unitName: [{ required: true, message: '请输入单位名称', trigger: 'blur' }],
+ person: [{ required: true, message: '请输入联系人', trigger: 'blur' }],
+ address: [{ required: true, message: '请输入联系地址', trigger: 'blur' }],
+ product: [{ required: true, message: '请选择产品', trigger: 'blur' }],
+ phone: [{required: true, trigger: "blur", validator: validatePhone}],
+
+ },
+ isAdmin: false,
+ companyList: [],
+ dataList: [
+ {
+ num: '说明',
+ item: '哪项不满意,请在相应的选项“⬜︎︎︎”内打“√”',
+ satisfied:'总体评价,请在相应的选项“⬜︎︎︎”内打“√”'
+ },
+ {
+ num: '1',
+ item: ['研制过程质里管理'],
+ satisfied:['满意','基本满意','不满意']
+ },
+ {
+ num: '2',
+ item: ['项目进度的符合性','节点控制'],
+ satisfied:['满意','基本满意','不满意']
+ },
+ {
+ num: '3',
+ item: ['技术技能','工作态度','过程规范','综合素质'],
+ satisfied:['满意','基本满意','不满意']
+ },
+ {
+ num: '4',
+ item: ['服务的及时性','有效性','服务态度'],
+ satisfied:['满意','基本满意','不满意']
+ },
+ ],
+ productTypeList: [
+ {
+ id: 1,
+ name: '系统'
+ },
+ {
+ id: 2,
+ name: '软件'
+ },
+ {
+ id: 3,
+ name: '整机'
+ },
+ {
+ id: 4,
+ name: '试剂柜'
+ },
+ {
+ id: 5,
+ name: '印制板'
+ },
+ {
+ id: 6,
+ name: '手持终端'
+ },
+ {
+ id: 7,
+ name: '其他'
+ },
+ ],
+ checkProductTypes: []
+})
+
+onMounted(() => {
+
+
+});
+const openDialog = async (type, value,companyList) => {
+ const userInfo = JSON.parse(Cookies.get('userInfo'))
+ state.isAdmin = userInfo.userType === 0;
+ state.form.companyName = userInfo.companyName
+ state.form.companyId = userInfo.companyId
+ if(state.isAdmin){
+ state.form.companyId = value.companyId
+ state.form.companyName = value.companyName
+ state.companyList = companyList
+ }
+ title.value = type === 'add' ? '新增' : type ==='edit' ? '编辑' : '查看' ;
+ if(type === 'edit' || type === 'review') {
+ state.form = JSON.parse(JSON.stringify(value));
+ if(state.isAdmin){
+ state.form.companyId = value.companyId
+ state.form.companyName = value.companyName
+ }
+ state.dataList = JSON.parse(value.mess)
+ state.checkProductTypes = value.product.split(',').map(Number)
+
+ }
+ dialogVisible.value = true;
+}
+
+const onSubmit = async () => {
+ state.form.mess = JSON.stringify(state.dataList)
+ state.form.product = state.checkProductTypes.join(',')
+ 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 addResearch(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 editResearch(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: '',
+ companyId: null,
+ questionName: null,
+ number: '',
+ unitName: null,
+ person: null,
+ address: null,
+ phone: null,
+ product: '',
+ productName:'',
+ mess:'',
+ suggest: ''
+ }
+ state.checkProductTypes = []
+ state.companyList = []
+ state.dataList = [
+ {
+ num: '说明',
+ item: '哪项不满意,请在相应的选项“⬜︎︎︎”内打“√”',
+ satisfied:'总体评价,请在相应的选项“⬜︎︎︎”内打“√”'
+ },
+ {
+ num: '1',
+ item: ['研制过程质里管理'],
+ satisfied:['满意','基本满意','不满意']
+ },
+ {
+ num: '2',
+ item: ['项目进度的符合性','节点控制'],
+ satisfied:['满意','基本满意','不满意']
+ },
+ {
+ num: '3',
+ item: ['技术技能','工作态度','过程规范','综合素质'],
+ satisfied:['满意','基本满意','不满意']
+ },
+ {
+ num: '4',
+ item: ['服务的及时性','有效性','服务态度'],
+ satisfied:['满意','基本满意','不满意']
+ },
+ ]
+}
+
+
+
+const selectValueCom = (val) => {
+
+ state.companyList.forEach(item => {
+ if(item.name === val){
+ state.form.companyId = item.id
+ }
+ })
+}
+
+const handleChangeNum = (value) => {
+ if (!/^\d+$/.test(value)) { // 验证是否为数字
+ ElMessage.warning('只能输入数字')
+ state.form.year = '' // 重置选择,避免非法值被添加到options中
+ } else if (!state.yearList.some(option => option.label === value)) { // 确保不是已存在的选项
+ state.yearList.push({ value, label: value }); // 添加新选项(这里简单地将值和标签设为相同)
+ }
+}
+
+defineExpose({
+ openDialog
+});
+
+</script>
+
+<style scoped lang="scss">
+.notice{
+ :deep(.el-form .el-form-item__label) {
+ font-size: 15px;
+ }
+ :deep(.el-table .cell){
+ font-size: small;
+ }
+ .file {
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+ }
+}
+</style>
diff --git a/src/views/work/qualityInfo/supplierQuality/satisfiedEvaluste/research/index.vue b/src/views/work/qualityInfo/supplierQuality/satisfiedEvaluste/research/index.vue
new file mode 100644
index 0000000..5742182
--- /dev/null
+++ b/src/views/work/qualityInfo/supplierQuality/satisfiedEvaluste/research/index.vue
@@ -0,0 +1,270 @@
+<template>
+ <div class="app-container">
+ <div style="margin-bottom: 10px">
+ <el-form style="display: flex;flex-wrap: wrap;">
+ <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.companyId" placeholder="请选择" filterable clearable>
+ <el-option
+ v-for="item in data.companyList"
+ :key="item.id"
+ :label="item.name"
+ :value="item.id">
+ </el-option>
+ </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="questionName" align="center" />
+ <el-table-column label="操作" align="center" class-naame="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>
+ <editDialog ref="noticeRef" @getList = "getList"></editDialog>
+ </div>
+</template>
+
+<script setup>
+import {getCurrentInstance, onMounted, reactive, ref, toRefs} from "vue";
+import editDialog from "./components/editDialog.vue"
+import {ElMessage, ElMessageBox} from "element-plus";
+import {getCompany} from "@/api/onlineEducation/company";
+import Cookies from "js-cookie";
+import {generateWordDocument} from "@/utils/exportWord";
+import {delTable, getTable} from "@/api/qualityObjectives/table";
+import {delDiscern, getDiscern} from "@/api/environment/factors";
+import {delResearch, getResearch} from "@/api/satisfiedNew/satisfiedNew";
+const { proxy } = getCurrentInstance();
+const loading = ref(false);
+const noticeRef = ref();
+const deptRef = ref()
+const loadingCompany = ref(false)
+const choosedData = ref([])
+const data = reactive({
+ queryParams: {
+ pageNum: 1,
+ pageSize: 10,
+ companyId: null,
+ year: '',
+ type: ''
+ },
+ companyList: [],
+ isAdmin: false,
+ dialogVisible: 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;
+ if(data.isAdmin){
+ data.queryParams.companyId = null
+ }else {
+ data.queryParams.companyId = userInfo.companyId
+ }
+ getList();
+ if(data.isAdmin){
+ getCompanyList()
+ }
+});
+const getList = async () => {
+ loading.value = true;
+ const res = await getResearch(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,data.companyList);
+}
+
+const selectValue = (val) => {
+ data.companyList.forEach(item => {
+ if(item.name === val){
+ data.queryParams.companyId = item.id
+ }
+ })
+}
+
+const getCompanyList = async ()=>{
+ const queryParams = {
+ pageNum: 1,
+ pageSize: 999
+ }
+ const res = await getCompany(queryParams)
+ if (res.code == 200) {
+ data.companyList = res.data.list?res.data.list:[]
+ } else {
+ ElMessage.warning(res.message)
+ }
+}
+
+const handleSizeChange = (val) => {
+ data.queryParams.pageSize = val
+ getList()
+}
+const handleCurrentChange = (val) => {
+ data.queryParams.pageNum = val
+ getList()
+}
+const handleClose = () => {
+ data.dialogVisible = false
+}
+
+/** 重置新增的表单以及其他数据 */
+function reset() {
+ if(data.isAdmin){
+ data.queryParams = {
+ companyId: '',
+ pageNum: 1,
+ pageSize: 10,
+ year: '',
+ type: ''
+ }
+ choosedData.value = []
+ data.companyList = [];
+ getCompanyList()
+ }else {
+ data.queryParams = {
+ companyId: data.queryParams.companyId,
+ pageNum: 1,
+ pageSize: 10,
+ year: '',
+ type: ''
+ }
+ }
+ getList();
+
+}
+const exportData = () => {
+ if(choosedData.value && choosedData.value.length === 0){
+ ElMessage.warning('请选择需要导出的数据')
+ }else {
+ startGeneration()
+ }
+}
+const templatePath = ref('/environmentalFactorsExample.docx')
+const startGeneration = async () => {
+ const data = JSON.parse(JSON.stringify(choosedData.value))
+ data.forEach(item => {
+ item.fictionTime = item.fictionTime.substring(0,10)
+ console.log('u',item)
+ const datax = idGroupToTree(item.factorContents)
+ item.tableList = datax.map((item,index) => {
+ return {
+ ...item,
+ fileList: item.children.map((f,findex) => {
+ return{
+ ...f,
+ first: findex == 0,
+ typeName: f.type == 1 ? '外部环境' : '内部环境'
+ }
+ })
+ }
+ })
+ console.log(' item.tableList', item.tableList)
+ try {
+ generateWordDocument(templatePath.value, item, item.companyName+`_${item.year}年内、外部环境要素识别表.docx`);
+ } catch (error){
+ ElMessage({
+ type: 'warning',
+ message: '导出失败'
+ });
+ }
+ })
+}
+function idGroupToTree(data) {
+ const groups = data.reduce((map, item) => {
+ map.has(item.type) || map.set(item.type, []);
+ map.get(item.type).push(item);
+ return map;
+ }, new Map());
+ return Array.from(groups).map(([type, items]) => ({
+ type,
+ children: items
+ }));
+}
+const handleSelectionChange = (val) => {
+ choosedData.value = val
+}
+const handleDelete = (val) => {
+ ElMessageBox.confirm(
+ '确定删除此条数据?',
+ '提示',
+ {
+ confirmButtonText: '确定',
+ cancelButtonText: '取消',
+ type: 'warning',
+ })
+ .then( async() => {
+ const res = await delResearch(val.id);
+ if(res.code === 200){
+ ElMessage({
+ type: 'success',
+ message: '删除成功'
+ });
+ await getList();
+ }else{
+ ElMessage.warning(res.message)
+ }
+ })
+}
+
+
+</script>
+<style lang="scss">
+.pag-container{
+ float: right;
+ margin-top: 10px;
+}
+</style>
--
Gitblit v1.9.2