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