zhouwx
2 天以前 03b3624455b2f3a495ebb34349080e3bd35faff9
修改
已修改3个文件
已添加21个文件
5316 ■■■■■ 文件已修改
public/purchaseRequisitionExample.docx 补丁 | 查看 | 原始文档 | blame | 历史
public/qualityOrganizeExample.docx 补丁 | 查看 | 原始文档 | blame | 历史
public/recordsExample.docx 补丁 | 查看 | 原始文档 | blame | 历史
src/api/procurementPlatform/procurementPlatform.js 129 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/satisfiedNew/satisfiedNew.js 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/standardSys/standardSys.js 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/build/conpanyFunctionConsult/digitalFileDep/manageType/qualityOrganize/components/editDialog.vue 392 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/build/conpanyFunctionConsult/digitalFileDep/manageType/qualityOrganize/index.vue 299 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/work/onlineEducation/offlineEducation/components/recordDialog.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/work/onlineEducation/offlineEducation/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/work/procurementPlatform/incomingInspection/inspectionRecords/components/editDialog.vue 348 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/work/procurementPlatform/incomingInspection/inspectionRecords/index.vue 260 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/work/procurementPlatform/incomingInspection/inspectionStandards/components/editDialog.vue 215 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/work/procurementPlatform/incomingInspection/inspectionStandards/index.vue 267 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/work/procurementPlatform/purchaseContract/components/editDialog.vue 215 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/work/procurementPlatform/purchaseContract/index.vue 266 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/work/procurementPlatform/purchaseRequisition/components/editDialog.vue 500 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/work/procurementPlatform/purchaseRequisition/index.vue 286 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/work/qualityInfo/supplierQuality/satisfiedEvaluste/deliver/components/editDialog.vue 391 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/work/qualityInfo/supplierQuality/satisfiedEvaluste/deliver/index.vue 270 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/work/qualityInfo/supplierQuality/satisfiedEvaluste/report/components/editDialog.vue 390 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/work/qualityInfo/supplierQuality/satisfiedEvaluste/report/index.vue 271 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/work/qualityInfo/supplierQuality/satisfiedEvaluste/research/components/editDialog.vue 409 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/work/qualityInfo/supplierQuality/satisfiedEvaluste/research/index.vue 270 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/purchaseRequisitionExample.docx
Binary files differ
public/qualityOrganizeExample.docx
Binary files differ
public/recordsExample.docx
Binary files differ
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'
    })
}
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'
    })
}
src/api/standardSys/standardSys.js
@@ -62,4 +62,36 @@
        method: 'get',
        params: params
    })
}
}
//质量体系策划
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'
    })
}
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>
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>
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>-->
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(() => {
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>