Просмотр исходного кода

资质管理模块功能修改

Z 1 год назад
Родитель
Сommit
2dfcae931f

+ 1 - 1
src/api/bpm/processClass.js

@@ -3,7 +3,7 @@ import request from '@/utils/request'
 export async function getProcessTypePageAPI(data) {
   const res = await request.post('/bpm/processtype/page', data);
   if (res.data.code == 0) {
-    return res.data.data.list
+    return res.data.data
   }
   return Promise.reject(new Error(res.data.message));
 }

+ 61 - 0
src/api/qualification/index.js

@@ -0,0 +1,61 @@
+import request from '@/utils/request';
+
+
+// 资质列表查询
+export async function getProfessionCertificationPageList(params) {
+  const res = await request.get(`/main/professionCertification/page`, {
+    params
+  });
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 新增资质
+export async function saveProfessionCertification(data) {
+  const res = await request.post(`/main/professionCertification/save`, data);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 通过id查询资质详情
+export async function getProfessionCertificationById(id) {
+  const res = await request.get(`/main/professionCertification/getById/${id}`);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 删除资质
+export async function deleteProfessionCertificationById(data) {
+  const res = await request.delete(`/main/professionCertification/delete`, {
+    data
+  });
+  if (res.data.code == 0) {
+    return res.data.message;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 修改资质
+export async function updateProfessionCertificationById(data) {
+  const res = await request.put(`/main/professionCertification/update`, data);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+/**
+ * 提交客户证书资质信息  开启流程
+ */
+export async function contactQcSubmit(data) {
+  const res = await request.post(`/bpm/ProfessionCertification/submit`, data);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}

+ 9 - 1
src/enum/dict.js

@@ -45,7 +45,8 @@ export default {
   角色数据权限字典: 'role_data_authority_dic',
   区域等级: 'main_area_level',
   区域类型: 'main_area_type',
-  工种类型: 'work_type'
+  工种类型: 'work_type',
+  '客户/供应商资质类型': 'contact_qc_type'
 };
 
 export const numberList = [
@@ -62,3 +63,10 @@ export const numberList = [
   'rule_status',
   'ledger'
 ];
+//审核状态
+export const reviewStatus = {
+  0: '未提交',
+  1: '审核中',
+  2: '已审核',
+  3: '审核不通过'
+};

+ 34 - 1
src/styles/transition/common.scss

@@ -63,5 +63,38 @@
   display: flex;
   align-items: center;
   justify-content: flex-end !important;
-  
+
+}
+.form_item_label {
+  .el-form-item__label {
+    line-height: 21px !important;
+  }
+}
+
+.el-form-box {
+  .el-row {
+    .el-form-item {
+      margin-bottom: 17px;
+
+      .el-form-item__error {
+        font-size: 11px;
+      }
+    }
+    .el-col {
+      .el-form-item {
+        margin-bottom: 17px;
+
+        .el-form-item__error {
+          font-size: 11px;
+        }
+      }
+    }
+  }
+
+  .el-form-item {
+    margin-bottom: 17px;
+    .el-form-item__error {
+      font-size: 11px;
+    }
+  }
 }

+ 2 - 1
src/views/bpm/model/index.vue

@@ -247,10 +247,11 @@ export default {
       this.form.processTypeName = this.processTypeList.find(item => item.id == val)?.name
     },
     async getProcessTypeList() {
-      this.processTypeList = await getProcessTypePageAPI({
+      const {list} = await getProcessTypePageAPI({
         pageNum: 1,
         size: 9999,
       });
+      this.processTypeList = list
     },
 
     /* 表格数据源 */

+ 5 - 2
src/views/bpm/processClass/index.vue

@@ -106,12 +106,15 @@ export default {
   },
 
   methods: {
-    datasource({page, where, limit}) {
-      return getProcessTypePageAPI({
+  async  datasource({page, where, limit}) {
+    let arr = await getProcessTypePageAPI({
         ...where,
         pageNum: page,
         size: limit,
       });
+      console.log(arr);
+
+      return arr
     },
     search(where) {
       this.$refs.table.reload({

+ 647 - 0
src/views/factoryModel/qualificationManagement/components/addOrEditDialog.vue

@@ -0,0 +1,647 @@
+<template>
+  <ele-modal custom-class="ele-dialog-form long-dialog-form"
+             :centered="true" :visible.sync="addOrEditDialogFlag" :title="title"
+             append-to-body
+             :close-on-click-modal="false" width="70%" :before-close="cancel">
+    <el-form ref="form" :model="form" :rules="rules" class="el-form-box">
+      <headerTitle title="基本信息"/>
+      <el-row :gutter="20">
+        <!--        <el-col :span="12">-->
+        <!--          <el-form-item label="编码:" prop="code" label-width="90px">-->
+        <!--            <el-input-->
+        <!--              :disabled="type=='view'"-->
+        <!--              v-model="form.code"-->
+        <!--              clearable-->
+        <!--              placeholder="请输入"-->
+        <!--            />-->
+        <!--          </el-form-item>-->
+        <!--        </el-col>-->
+        <el-col :span="12">
+          <el-form-item label="名称" prop="name"
+                        label-width="90px"
+                        :rules=" {required: true, message: '请输入',trigger: 'blur' }">
+            <el-input v-model="form.name" :disabled="type=='view'" clearable></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="有效时间:" prop="date" label-width="90px">
+            <el-date-picker
+              :disabled="type=='view'"
+              v-model="form.date"
+              style="width: 100%;"
+              type="daterange"
+              value-format="yyyy-MM-dd"
+              range-separator="至"
+              start-placeholder="开始日期"
+              end-placeholder="结束日期"
+            >
+            </el-date-picker>
+          </el-form-item>
+        </el-col>
+
+      </el-row>
+      <el-row :gutter="20">
+        <el-col :span="12">
+          <el-form-item label="资质类型:" prop="certificationType" label-width="90px">
+            <el-select
+              style="width: 100%"
+              :disabled="type=='view'"
+              v-model="form.certificationType"
+              @change="changeCertificationType"
+              filterable
+            >
+              <el-option
+                v-for="item in qualificationOptions"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value"
+              >
+              </el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="关联类型:" prop="relationName" label-width="90px">
+            <el-input
+              :disabled="type=='view'"
+              v-model="form.relationName"
+              readonly
+              clearable
+              @click.native="handleClick"
+              placeholder="请选择"
+            />
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row :gutter="20">
+        <el-col :span="12">
+          <el-form-item label="备注" label-width="90px">
+            <el-input type="textarea" v-model="form.remark" :disabled="type=='view'" clearable></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="附件:" prop="accessory" label-width="90px">
+            <fileUpload
+              v-if="type!=='view'"
+              v-model="form.accessory"
+              module="main"
+              :showLib="false"
+              :limit="10"/>
+            <div v-else>
+              <el-link
+                v-for="link in form.accessory"
+                :key="link.id"
+                type="primary"
+                :underline="false"
+                @click="downloadFile(link)">
+                {{ link.name }}
+              </el-link>
+            </div>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <headerTitle title="资质信息"/>
+      <ele-pro-table ref="linkTable" :columns="columns" :datasource="form.detailsList" :toolkit="[]" height="300px"
+                     :need-page="false">
+        <!-- 表头工具栏 -->
+        <template v-slot:toolbar>
+
+          <el-button v-if="type!=='view'" type="primary" @click="handleAdd">添加</el-button>
+        </template>
+        <template v-slot:name="scope">
+          <el-form-item :prop="'detailsList.' + scope.$index + '.name'" :rules="{
+            required: true,
+            message: '',
+            trigger: 'change'
+          }">
+            <el-select v-if="type!=='view'" v-model="scope.row.name" clearable>
+              <el-option :disabled="disabledToType(scope.row).includes(item.dictCode)"
+                         v-for="item in dictList" :value="item.dictCode"
+                         :label="item.dictValue"></el-option>
+            </el-select>
+            <!--                <DictSelection v-if="type!=='view'" clearable dictName="客户/供应商资质类型" v-model="scope.row.type"-->
+            <!--                               @itemChange="(val)=>handleChangeType(val,scope.row)"></DictSelection>-->
+            <span v-else>{{ getLabelName(dictList, scope.row.name) }}</span>
+          </el-form-item>
+
+        </template>
+        <template v-slot:code="scope">
+          <el-form-item :prop="'detailsList.' + scope.$index + '.code'" :rules="{
+            required: true,
+            message: '',
+            trigger: 'blur'
+          }">
+            <el-input v-model="scope.row.code" :disabled="type=='view'" clearable></el-input>
+          </el-form-item>
+
+        </template>
+        <template v-slot:businessRange="scope">
+          <el-form-item :prop="'detailsList.' + scope.$index + '.businessRange'">
+            <el-input type="textarea" v-model="scope.row.businessRange" :disabled="type=='view'" clearable></el-input>
+          </el-form-item>
+        </template>
+        <template v-slot:startTime="scope">
+          <el-form-item inline-message :prop="'detailsList.' + scope.$index + '.startTime'" :rules="{
+            required: true,
+            message: '',
+            trigger: 'change'
+
+          }">
+            <el-date-picker
+              :disabled="type=='view'"
+              v-model="scope.row.startTime"
+              type="date"
+              style="width: 100%"
+              value-format="yyyy-MM-dd"
+              placeholder="选择日期">
+            </el-date-picker>
+          </el-form-item>
+
+        </template>
+        <template v-slot:endTime="scope">
+          <el-form-item :prop="'detailsList.' + scope.$index + '.endTime'"
+                        :rules="{
+            required: true,
+            validator: validateEndDate(scope.row,scope.$index),
+            trigger: ['blur','change']
+          }">
+            <el-date-picker
+              :disabled="type=='view'"
+              v-model="scope.row.endTime"
+              type="date"
+              style="width: 100%"
+              value-format="yyyy-MM-dd"
+              placeholder="选择日期">
+            </el-date-picker>
+          </el-form-item>
+
+        </template>
+        <template v-slot:noticePersonName="scope">
+          <el-form-item :prop="'detailsList.' + scope.$index + '.noticePersonName'" :rules="{
+            required: true,
+            message: '',
+            trigger: ['blur','change']
+
+          }">
+            <el-input
+              :disabled="type=='view'"
+              @click.native="openStaffSelection(scope.$index)"
+              v-model="scope.row.noticePersonName"
+              placeholder="请选择"
+            ></el-input>
+          </el-form-item>
+
+        </template>
+        <template v-slot:accessory="scope">
+          <el-form-item :prop="'detailsList.' + scope.$index + '.accessory'" :rules="{
+            required: true,
+            message: '',
+            trigger: ['change','blur']
+          }">
+            <fileUpload
+              v-if="type!=='view'"
+              v-model="scope.row.accessory"
+              module="main"
+              :showLib="false"
+              :limit="10"/>
+            <div v-else>
+              <el-link
+                v-for="link in scope.row.accessory"
+                :key="link.id"
+                type="primary"
+                :underline="false"
+                @click="downloadFile(link)">
+                {{ link.name }}
+              </el-link>
+            </div>
+          </el-form-item>
+
+        </template>
+        <template v-slot:type="scope">
+          <el-form-item :prop="'detailsList.' + scope.$index + '.type'">
+            <el-select v-if="type!=='view'" v-model="scope.row.type" clearable>
+              <el-option v-for="item in typeList" :value="item.dictCode"
+                         :label="item.dictValue"></el-option>
+            </el-select>
+            <!--                <DictSelection v-if="type!=='view'" clearable dictName="客户/供应商资质类型" v-model="scope.row.type"-->
+            <!--                               @itemChange="(val)=>handleChangeType(val,scope.row)"></DictSelection>-->
+            <span v-else>{{ getLabelName(typeList, scope.row.type) }}</span>
+          </el-form-item>
+
+        </template>
+        <template v-slot:level="scope">
+          <el-form-item :prop="'detailsList.' + scope.$index + '.level'">
+            <el-select v-if="type!=='view'" v-model="scope.row.level" clearable>
+              <el-option v-for="item in levelOptions" :value="item.dictCode"
+                         :label="item.dictValue"></el-option>
+            </el-select>
+            <!--                <DictSelection v-if="type!=='view'" clearable dictName="客户/供应商资质类型" v-model="scope.row.type"-->
+            <!--                               @itemChange="(val)=>handleChangeType(val,scope.row)"></DictSelection>-->
+            <span v-else>{{ getLabelName(levelOptions, scope.row.type) }}</span>
+          </el-form-item>
+
+        </template>
+        <template v-slot:remark="scope">
+          <el-form-item :prop="'detailsList.' + scope.$index + '.remark'">
+            <el-input type="textarea" :disabled="type=='view'" v-model="scope.row.remark"></el-input>
+          </el-form-item>
+        </template>
+        <template v-slot:status="scope">
+          <el-form-item :prop="'detailsList.' + scope.$index + '.status'">
+            <el-tag v-if="scope.row.status" :type="statusTagTypeList[scope.row.status]">
+              {{ statusList[scope.row.status] }}
+            </el-tag>
+          </el-form-item>
+        </template>
+        <template v-slot:isRequired="{ column }">
+          <span class="is-required">{{ column.label }}</span>
+        </template>
+        <template v-slot:action="{ row, $index }">
+          <el-popconfirm
+            class="ele-action"
+            title="确定要删除该信息吗?"
+            @confirm="handleRemove($index)"
+          >
+            <template v-slot:reference>
+              <el-link
+                v-if="type!=='view'"
+                type="danger"
+                :underline="false"
+                icon="el-icon-delete"
+              >
+                删除
+              </el-link>
+            </template>
+          </el-popconfirm>
+        </template>
+
+      </ele-pro-table>
+
+    </el-form>
+    <!--    <el-tabs v-model="activeName" type="card">-->
+    <!--      <el-tab-pane label="证书资质" name="QC">-->
+    <!--     -->
+
+    <!--      </el-tab-pane>-->
+    <!--      <el-tab-pane v-if="form.processInstanceId" label="流程详情" name="processInstance">-->
+    <!--        <bpmDetail :id="form.processInstanceId"></bpmDetail>-->
+    <!--      </el-tab-pane>-->
+    <!--    </el-tabs>-->
+    <div slot="footer">
+      <el-button v-if="type!=='view'" type="primary" @click="handleSave(false)">保存</el-button>
+      <el-button v-if="type!=='view'" type="primary" plan @click="handleSave(true)">提交</el-button>
+      <el-button @click="cancel">返回</el-button>
+    </div>
+    <staffSelection
+      ref="staffSelection"
+      @confirm="confirmStaffSelection"
+    ></staffSelection>
+    <vendorDialog
+      ref="vendorDialogRef"
+      @success="confirmSelection"
+    ></vendorDialog>
+    <clientDialog
+      ref="clientSelection"
+      @success="confirmSelection"
+    ></clientDialog>
+  </ele-modal>
+</template>
+<script>
+import FileUpload from "@/components/upload/fileUpload.vue";
+import staffSelection from "./staffSelection.vue";
+import {
+  getProfessionCertificationById,
+  saveProfessionCertification,
+  updateProfessionCertificationById,
+  contactQcSubmit
+} from "@/api/qualification";
+import {getFile} from "@/api/system/file";
+import bpmDetail from "@/views/bpm/processInstance/detail.vue";
+import {mapActions, mapGetters} from "vuex";
+import dictEnum from "@/enum/dict";
+import clientDialog from "@/views/factoryModel/qualificationManagement/components/clientDialog.vue";
+import vendorDialog from "@/views/factoryModel/qualificationManagement/components/vendorDialog.vue";
+
+export default {
+  name: "addOrEditDialog",
+  components: {vendorDialog, clientDialog, bpmDetail, FileUpload, staffSelection},
+  props: {
+    addOrEditDialogFlag: Boolean,
+    typeInfo: String,
+    typeList: Array
+
+  },
+  data() {
+    return {
+      title: '',
+      type: '',
+      qualificationOptions: [
+        {
+          label: '客户资质',
+          value: '1'
+        },
+        {
+          label: '供应商资质',
+          value: '2'
+        },
+        {
+          label: '个人资质',
+          value: '3'
+        }
+      ],
+      levelOptions: [
+        {
+          dictValue: '初级',
+          dictCode: '1'
+        },
+        {
+          dictValue: '中级',
+          dictCode: '2'
+        },
+        {
+          dictValue: '高级',
+          dictCode: '3'
+        }
+      ],
+      defaultData: {
+        accessory: [],
+        name: "",
+        noticePersonId: "",
+        noticePersonName: "",
+        num: "",
+        remark: "",
+        businessRange: "",
+        type: "",
+        endTime: "",
+        startTime: ""
+      },
+      form: {
+        accessory: [],
+        detailsList: [],
+        relationName: '',
+        name: '',
+        date: [],
+        remark: '',
+
+      },
+      rules: {
+        name: [{required: true, message: '请输入名称', trigger: 'blur'}],
+        code: [{required: true, message: '请输入编码', trigger: 'blur'}],
+        certificationType: [{required: true, message: '请选择资质类型', trigger: 'change'}],
+        relationName: [{required: true, message: '请选择关联类型', trigger: 'change'}],
+        date: [{required: true, message: '请选择有效时间', trigger: 'change'}],
+      },
+      curIndex: null,
+      StaffType: '',
+
+      statusList: {
+        10: '有效',
+        20: '无效',
+        30: '已过期',
+      },
+      statusTagTypeList: {
+        10: 'success',
+        20: 'info',
+        30: 'danger',
+      },
+    }
+  },
+  computed: {
+    ...mapGetters(['dict']),
+    dictList() {
+      return this.dict[dictEnum['客户/供应商资质类型']] || [];
+    },
+    columns() {
+      return [
+        {
+          type: 'index',
+          width: 55,
+          align: 'center'
+        },
+        {
+          label: '名称',
+          prop: 'name',
+          slot: 'name',
+          headerSlot: 'isRequired',
+          minWidth: 180,
+          align: 'center'
+        },
+        {
+          label: '编号',
+          prop: 'code',
+          slot: 'code',
+          headerSlot: 'isRequired',
+          minWidth: 120,
+          align: 'center'
+        },
+        {
+          label: '许可/经营范围',
+          prop: 'businessRange',
+          slot: 'businessRange',
+          minWidth: 140,
+          align: 'center'
+        },
+        {
+          label: '有效期起始日期',
+          prop: 'startTime',
+          slot: 'startTime',
+          headerSlot: 'isRequired',
+          minWidth: 160,
+          align: 'center'
+        },
+        {
+          label: '有效期截止日期',
+          prop: 'endTime',
+          slot: 'endTime',
+          headerSlot: 'isRequired',
+          minWidth: 160,
+          align: 'center'
+        },
+        {
+          label: '通知人',
+          prop: 'noticePersonName',
+          slot: 'noticePersonName',
+          headerSlot: 'isRequired',
+          minWidth: 140,
+          align: 'center'
+        },
+        {
+          label: '附件',
+          prop: 'accessory',
+          slot: 'accessory',
+          headerSlot: 'isRequired',
+          minWidth: 140,
+        },
+        {
+          label: '等级',
+          prop: 'level',
+          slot: 'level',
+          minWidth: 140,
+          align: 'center'
+        },
+        {
+          label: '分类',
+          prop: 'type',
+          slot: 'type',
+          minWidth: 140,
+          align: 'center'
+        },
+        {
+          label: '备注',
+          prop: 'remark',
+          slot: 'remark',
+          minWidth: 140,
+          align: 'center'
+        },
+        {
+          label: '状态',
+          prop: 'status',
+          slot: 'status',
+          align: 'center',
+        },
+        {
+          action: 'action',
+          slot: 'action',
+          label: '操作',
+          align: 'center',
+          fixed: 'right'
+        }
+      ]
+    },
+    disabledToType() {
+      return (row) => {
+        let list = this.form.detailsList.map(item => item.name)
+        let dictCodeList = this.dictList.map(item => item.dictCode)
+        let intersectionList = list.filter((v) => dictCodeList.indexOf(v) > -1)
+        intersectionList = intersectionList.filter(v => row.name !== v)
+        return intersectionList
+      }
+    },
+  },
+  created() {
+    this.requestDict('客户/供应商资质类型');
+  },
+  methods: {
+    ...mapActions('dict', ['requestDict']),
+    getLabelName(arr, id) {
+      if (!id) return ''
+      return arr.find(item => item.dictCode == id)?.dictValue
+    },
+    //删除资质
+    handleRemove(index) {
+      this.form.detailsList.splice(index, 1)
+    },
+    //结束日期验证
+    validateEndDate(row, index) {
+      return (rule, value, callback) => {
+        if (!value) return callback(new Error(''))
+        if (
+          row.endTime &&
+          row.startTime &&
+          value < row.startTime
+        ) {
+          callback(new Error('截止日期不能小于起始日期'))
+        } else {
+          callback()
+        }
+      }
+    },
+    //页面初始化
+    init(type, row = {}) {
+      this.title = type == 'add' ? '新增' : type == 'edit' ? '修改' : '详情'
+      this.type = type
+      if (type !== 'add') {
+        this.getCertificateInfo(row)
+      }
+    },
+
+    handleClick() {
+      switch (this.form.certificationType) {
+        case '1':
+          this.$refs.clientSelection.open();
+          break;
+        case '2':
+          this.$refs.vendorDialogRef.open();
+          break;
+        case '3':
+          this.StaffType = 2
+          this.$refs.staffSelection.open([]);
+          break;
+      }
+    },
+    changeCertificationType(value) {
+      this.form.certificationType = value;
+      this.form.relationName = '';
+      this.form.relationId = '';
+    },
+    confirmSelection(obj) {
+      this.form.relationId = obj.id
+      this.form.relationName = obj.name
+      this.$forceUpdate();
+    },
+    async getCertificateInfo(row) {
+      this.form = await getProfessionCertificationById(row.id)
+      this.form.date = [this.form.startTime, this.form.endTime]
+    },
+    //打开选择负责人弹窗
+    openStaffSelection(index) {
+      this.curIndex = index
+      this.StaffType = 1
+      this.$refs.staffSelection.open([]);
+    },
+    //选择负责人回调
+    confirmStaffSelection(data, type) {
+      if (this.StaffType == 1) {
+        this.form.detailsList[this.curIndex].noticePersonName = data.map((item) => item.name).toString();
+        this.form.detailsList[this.curIndex].noticePersonId = data.map((item) => item.id).toString();
+      } else {
+        this.form.relationId = data.map((item) => item.id).join(',');
+        this.form.relationName = data.map((item) => item.name).join(',');
+      }
+
+    },
+    //新增
+    handleAdd() {
+      this.form.detailsList.push({...this.defaultData})
+    },
+    //修改资质证书
+    handleChangeType(val, row) {
+      if (!val) return row.name = ''
+      row.name = this.dictList.find(i => i.dictCode == val)?.dictValue || ''
+
+    },
+    downloadFile(file) {
+      getFile({objectName: file.storePath}, file.name);
+    },
+    //保存/提交
+    handleSave(isSub) {
+      this.$refs.form.validate(async (valid) => {
+        if (!valid) return this.$message.warning('有必填项未填写,请检查')
+        if (!this.form.detailsList.length) return this.$message.warning('至少保存一条资质信息')
+        this.form.startTime = this.form.date[0]
+        this.form.endTime = this.form.date[1]
+        let api = this.type == 'add' ? saveProfessionCertification : updateProfessionCertificationById
+        let id = await api(this.form)
+        if (isSub) {
+          let businessId = this.type == 'add' ? id : this.form.id
+          await contactQcSubmit({businessId: businessId, certificationType: this.form.certificationType})
+        }
+        this.$message.success('保存成功')
+        this.$emit('reload')
+        this.cancel()
+      })
+
+    },
+    //关闭弹窗
+    cancel() {
+      this.$emit('update:addOrEditDialogFlag', false)
+    },
+  }
+
+}
+</script>
+<style scoped lang="scss">
+:deep.el-form-item {
+  margin-bottom: 0
+}
+</style>

+ 25 - 16
src/views/factoryModel/qualificationManagement/components/clientDialog.vue

@@ -1,8 +1,11 @@
 <template>
-  <el-dialog
+  <ele-modal
+    v-if="visible"
     :visible.sync="visible"
     title="供应商列表"
-    width="80vw"
+    width="70%"
+    :centered="true"
+    :close-on-click-modal="false"
     append-to-body
   >
     <el-form :model="params" label-width="100px">
@@ -50,7 +53,7 @@
       </el-row>
     </el-form>
     <el-container class="assets-dialog">
-      <el-aside width="200px" style="max-height: auto" class="wrapper-assets">
+      <el-aside width="200px" style="max-height:calc(100vh - 345px)" class="wrapper-assets">
         <AssetTree
           @handleNodeClick="handleNodeClick"
           id="17"
@@ -63,12 +66,17 @@
           ref="table"
           :columns="columns"
           :datasource="datasource"
-          height="calc(100vh - 325px)"
+          height="calc(100vh - 405px)"
           full-height="calc(100vh - 116px)"
           tool-class="ele-toolbar-form"
-          :selection.sync="selection"
+          :current.sync="current"
+          :highlight-current-row="true"
+          @current-change="handleCurrentChange"
           cache-key="eomContactPageTable"
         >
+          <template v-slot:current="{row,_index}">
+            <el-radio class="radio" v-model="radio" :label="row.id"><i></i></el-radio>
+          </template>
         </ele-pro-table>
       </el-main>
     </el-container>
@@ -77,7 +85,7 @@
       <el-button type="primary" @click="confirm">确定</el-button>
       <el-button @click="visible = false">关闭</el-button>
     </div>
-  </el-dialog>
+  </ele-modal>
 </template>
 
 <script>
@@ -90,7 +98,7 @@
       return {
         params: {},
         visible: false,
-        selection: [],
+        radio: '',
         statusList: [
           { value: 1, label: '启用' },
           { value: 2, label: '禁用' }
@@ -100,9 +108,9 @@
         loading: false,
         columns: [
           {
-            width: 45,
-            type: 'selection',
-            columnKey: 'selection',
+            width: 55,
+            columnKey: 'current',
+            slot: 'current',
             align: 'center'
           },
           {
@@ -246,6 +254,9 @@
           ...where
         });
       },
+      handleCurrentChange(row){
+        this.radio = row.id
+      },
       open() {
         this.visible = true;
         this.$nextTick(() => {
@@ -253,8 +264,7 @@
         });
       },
       confirm() {
-        console.log(this.selection);
-        this.$emit('success', this.selection);
+        this.$emit('success', this.current);
         this.visible = false;
       }
     }
@@ -263,14 +273,13 @@
 
 <style lang="scss" scoped>
   .el-dialog__wrapper {
+    margin-top: 0 !important;
     ::v-deep .el-aside {
       background-color: #fff !important;
       border: 1px solid #ccc;
+      transform: translateY(20px);
     }
   }
 
-  .wrapper-assets {
-    max-height: 53vh;
-    overflow: auto;
-  }
+
 </style>

+ 0 - 1
src/views/factoryModel/qualificationManagement/components/user-edit.vue

@@ -277,7 +277,6 @@
         this.form.personnelIds = '';
       },
       handleClick() {
-        console.log(this.form);
         switch (this.form.certificationType) {
           case '1':
             this.$refs.clientSelection.open();

+ 0 - 14
src/views/factoryModel/qualificationManagement/components/user-search.vue

@@ -7,19 +7,6 @@
     @submit.native.prevent
   >
     <el-row :gutter="15">
-      <el-col v-bind="styleResponsive ? { lg: 6, md: 12 } : { span: 6 }">
-        <el-form-item label="类型:" prop="type">
-          <el-select clearable v-model="where.type" style="width: 100%">
-            <el-option
-              v-for="item in typeList"
-              :key="item.dictCode"
-              :label="item.dictValue"
-              :value="item.dictCode"
-            >
-            </el-option>
-          </el-select>
-        </el-form-item>
-      </el-col>
       <el-col v-bind="styleResponsive ? { lg: 6, md: 12 } : { span: 6 }">
         <el-form-item label="编码:">
           <el-input clearable v-model="where.code" placeholder="请输入" />
@@ -58,7 +45,6 @@
       const defaultWhere = {
         code: '',
         name: '',
-        type: null
       };
       return {
         // 表单数据

+ 23 - 10
src/views/factoryModel/qualificationManagement/components/vendorDialog.vue

@@ -1,8 +1,11 @@
 <template>
-  <el-dialog
+  <ele-modal
+    v-if="visible"
     :visible.sync="visible"
     title="供应商列表"
-    width="80vw"
+    width="70%"
+    :centered="true"
+    :close-on-click-modal="false"
     append-to-body
   >
     <el-form :model="params" label-width="100px">
@@ -50,7 +53,7 @@
       </el-row>
     </el-form>
     <el-container class="assets-dialog">
-      <el-aside width="200px" style="max-height: auto" class="wrapper-assets">
+      <el-aside width="200px" style="max-height: calc(100vh - 355px)" class="wrapper-assets">
         <AssetTree
           @handleNodeClick="handleNodeClick"
           id="19"
@@ -63,12 +66,17 @@
           ref="table"
           :columns="columns"
           :datasource="datasource"
-          height="calc(100vh - 325px)"
+          height="calc(100vh - 405px)"
           full-height="calc(100vh - 116px)"
           tool-class="ele-toolbar-form"
-          :selection.sync="selection"
+          :current.sync="current"
+          :highlight-current-row="true"
+          @current-change="handleCurrentChange"
           cache-key="eomContactPageTable"
         >
+          <template v-slot:current="{row,_index}">
+            <el-radio class="radio" v-model="radio" :label="row.id"><i></i></el-radio>
+          </template>
         </ele-pro-table>
       </el-main>
     </el-container>
@@ -77,7 +85,7 @@
       <el-button type="primary" @click="confirm">确定</el-button>
       <el-button @click="visible = false">关闭</el-button>
     </div>
-  </el-dialog>
+  </ele-modal>
 </template>
 
 <script>
@@ -91,6 +99,7 @@
         params: {},
         visible: false,
         selection: [],
+        radio: '',
         statusList: [
           { value: 1, label: '启用' },
           { value: 2, label: '禁用' }
@@ -100,9 +109,9 @@
         loading: false,
         columns: [
           {
-            width: 45,
-            type: 'selection',
-            columnKey: 'selection',
+            width: 55,
+            columnKey: 'current',
+            slot: 'current',
             align: 'center'
           },
           {
@@ -227,6 +236,9 @@
         this.curNodeData = data;
         this.reload({ categoryId: data.id });
       },
+      handleCurrentChange(row){
+        this.radio = row.id
+      },
       reload(where) {
         this.$refs.table.reload({ page: 1, where });
       },
@@ -245,7 +257,7 @@
         });
       },
       confirm() {
-        this.$emit('success', this.selection);
+        this.$emit('success', this.current);
         this.visible = false;
       }
     }
@@ -257,6 +269,7 @@
     ::v-deep .el-aside {
       background-color: #fff !important;
       border: 1px solid #ccc;
+      transform: translateY(20px);
     }
   }
 

+ 269 - 249
src/views/factoryModel/qualificationManagement/index.vue

@@ -2,10 +2,11 @@
   <div class="ele-body">
     <el-card shadow="never">
       <!-- 搜索表单 -->
-      <user-search :typeList="typeOptions" @search="reload" />
+      <user-search :typeList="typeOptions" @search="reload"/>
       <!-- 数据表格 -->
       <ele-pro-table
         ref="table"
+        height="calc(100vh - 325px)"
         :columns="columns"
         :datasource="datasource"
         :selection.sync="selection"
@@ -18,7 +19,7 @@
             type="primary"
             icon="el-icon-plus"
             class="ele-btn-icon"
-            @click="openEdit()"
+            @click="openEdit('','add')"
           >
             新建
           </el-button>
@@ -32,48 +33,58 @@
           >
             删除
           </el-button>
-          <el-button
-            size="small"
-            type="primary"
-            icon="el-icon-upload2"
-            class="ele-btn-icon"
-            plain
-          >
-            导出
-          </el-button>
-          <el-button
-            size="small"
-            type="primary"
-            icon="el-icon-download"
-            class="ele-btn-icon"
-            plain
-          >
-            导入
-          </el-button>
+<!--          <el-button-->
+<!--            size="small"-->
+<!--            type="primary"-->
+<!--            icon="el-icon-upload2"-->
+<!--            class="ele-btn-icon"-->
+<!--            plain-->
+<!--          >-->
+<!--            导出-->
+<!--          </el-button>-->
+<!--          <el-button-->
+<!--            size="small"-->
+<!--            type="primary"-->
+<!--            icon="el-icon-download"-->
+<!--            class="ele-btn-icon"-->
+<!--            plain-->
+<!--          >-->
+<!--            导入-->
+<!--          </el-button>-->
         </template>
 
         <!-- 操作列 -->
         <template v-slot:action="{ row }">
           <el-link
+            v-if="[0,3].includes(row.processStatus)"
             type="primary"
             :underline="false"
             icon="el-icon-edit"
-            @click="openEdit(row)"
+            @click="openEdit(row,'edit')"
           >
             修改
           </el-link>
           <el-link
+            v-if="[1,2].includes(row.processStatus)"
             type="primary"
             :underline="false"
             icon="el-icon-setting"
-            @click="openEdit(row, true)"
+            @click="openEdit(row, 'view')"
           >
             详情
           </el-link>
-
+          <el-link
+            v-if="[0,3].includes(row.processStatus)"
+            type="primary"
+            :underline="false"
+            icon="el-icon-plus"
+            @click="submit(row)">
+            提交
+          </el-link>
           <el-popconfirm
             class="ele-action"
             title="确定要删除当前资质吗?"
+            v-if="[0,3].includes(row.processStatus)"
             @confirm="remove(row)"
           >
             <template v-slot:reference>
@@ -83,252 +94,261 @@
             </template>
           </el-popconfirm>
         </template>
+        <template v-slot:accessory="scope">
+          <el-link
+            v-for="link in scope.row.accessory"
+            :key="link.id"
+            type="primary"
+            :underline="false"
+            @click="downloadFile(link)">
+            {{ link.name }}
+          </el-link>
+        </template>
       </ele-pro-table>
     </el-card>
-    <!-- 编辑弹窗 -->
-    <user-edit
-      :visible.sync="showEdit"
+    <!-- 新增/编辑/详情弹窗 -->
+    <add-or-edit-dialog
+      :addOrEditDialogFlag.sync="addOrEditDialogFlag"
+      v-if="addOrEditDialogFlag"
+      ref="addOrEditDialogRef"
       :data="current"
       :controlList="controlList"
-      :isView="isView"
       @done="reload"
-      ref="userEdit"
       :typeList="typeOptions"
     />
   </div>
 </template>
 
 <script>
-  import UserSearch from './components/user-search.vue';
-  import UserEdit from './components/user-edit.vue';
-  import {
-    getProfessionCertificationPageList,
-    deleteProfessionCertificationById
-  } from '@/api/factoryModel';
-  import control from '@/api/technology/control';
-  import dictMixins from '@/mixins/dictMixins';
+import UserSearch from './components/user-search.vue';
+import addOrEditDialog from './components/addOrEditDialog.vue';
+import {
+  contactQcSubmit,
+  deleteProfessionCertificationById,
+  getProfessionCertificationPageList
+} from '@/api/qualification';
+import control from '@/api/technology/control';
+import dictMixins from '@/mixins/dictMixins';
+import FileUpload from "@/components/upload/fileUpload.vue";
+import {getFile} from "@/api/system/file";
+import {reviewStatus} from "@/enum/dict";
 
-  export default {
-    name: 'technologyProduction',
-    components: {
-      UserSearch,
-      UserEdit
-    },
-    mixins: [dictMixins],
-    data() {
-      return {
-        levelOptions: [
-          {
-            label: '初级',
-            value: '1'
-          },
-          {
-            label: '中级',
-            value: '2'
-          },
-          {
-            label: '高级',
-            value: '3'
-          }
-        ],
-        isView: false,
-        // 表格列配置
-        columns: [
-          {
-            columnKey: 'selection',
-            type: 'selection',
-            width: 45,
-            align: 'center',
-            fixed: 'left'
-          },
-          {
-            label: '序号',
-            type: 'index',
-            width: 55,
-            align: 'center'
-          },
-          {
-            slot: 'type',
-            label: '类型',
-            showOverflowTooltip: true,
-            align: 'center',
-            minWidth: 110,
-            formatter: (_row) => {
-              return this.getDictValue('工种类型', _row.type);
-            }
-          },
-          {
-            align: 'center',
-            prop: 'code',
-            label: '编码',
-            showOverflowTooltip: true,
-            minWidth: 110
-          },
-          {
-            slot: 'name',
-            prop: 'name',
-            label: '名称',
-            showOverflowTooltip: true,
-            align: 'center',
-            minWidth: 110
-          },
-          {
-            slot: 'level',
-            prop: 'level',
-            label: '等级',
-            showOverflowTooltip: true,
-            align: 'center',
-            minWidth: 110,
-            formatter: (_row) => {
-              return this.levelOptions.filter(
-                (item) => _row.level == item.value
-              )[0].label;
-            }
-          },
-          {
-            slot: 'startTime',
-            prop: 'startTime',
-            label: '有效开始时间',
-            showOverflowTooltip: true,
-            align: 'center',
-            minWidth: 110
-          },
-          {
-            slot: 'endTime',
-            prop: 'endTime',
-            label: '有效结束时间',
-            showOverflowTooltip: true,
-            align: 'center',
-            minWidth: 110
-          },
-          {
-            slot: 'accessory.name',
-            prop: 'accessory.name',
-            label: '附件',
-            showOverflowTooltip: true,
-            align: 'center',
-            minWidth: 110
-          },
-          {
-            columnKey: 'action',
-            label: '操作',
-            width: 260,
-            align: 'center',
-            resizable: false,
-            slot: 'action',
-            showOverflowTooltip: true
+export default {
+  name: 'technologyProduction',
+  components: {
+    FileUpload,
+    UserSearch,
+    addOrEditDialog
+  },
+  mixins: [dictMixins],
+  data() {
+    return {
+      levelOptions: [
+        {
+          label: '初级',
+          value: '1'
+        },
+        {
+          label: '中级',
+          value: '2'
+        },
+        {
+          label: '高级',
+          value: '3'
+        }
+      ],
+      isView: false,
+      // 表格列配置
+      columns: [
+        {
+          columnKey: 'selection',
+          type: 'selection',
+          width: 45,
+          align: 'center',
+          fixed: 'left'
+        },
+        {
+          label: '序号',
+          type: 'index',
+          width: 55,
+          align: 'center'
+        },
+        {
+          align: 'center',
+          prop: 'code',
+          label: '编码',
+          showOverflowTooltip: true,
+          minWidth: 110
+        },
+        {
+          slot: 'name',
+          prop: 'name',
+          label: '名称',
+          showOverflowTooltip: true,
+          align: 'center',
+          minWidth: 110
+        },
+        {
+          slot: 'startTime',
+          prop: 'startTime',
+          label: '有效开始时间',
+          showOverflowTooltip: true,
+          align: 'center',
+          minWidth: 110
+        },
+        {
+          slot: 'endTime',
+          prop: 'endTime',
+          label: '有效结束时间',
+          showOverflowTooltip: true,
+          align: 'center',
+          minWidth: 110
+        },
+
+        {
+          label: '状态',
+          prop: 'processStatus',
+          slot: 'processStatus',
+          align: "center",
+          width: 120,
+          formatter: (_row, _column, cellValue) => {
+            return reviewStatus[_row.processStatus];
           }
-        ],
-        // 表格选中数据
-        selection: [],
-        // 当前编辑数据
-        current: null,
-        // 是否显示编辑弹窗
-        showEdit: false,
-        // 是否显示参数弹窗
-        showSetting: false,
-        controlList: [],
-        sampleShow: false,
-        taskId: null
-      };
+        },
+        {
+          columnKey: 'action',
+          label: '操作',
+          width: 260,
+          align: 'center',
+          resizable: false,
+          slot: 'action',
+          showOverflowTooltip: true
+        }
+      ],
+      // 表格选中数据
+      selection: [],
+      // 当前编辑数据
+      current: null,
+      // 是否显示编辑弹窗
+      addOrEditDialogFlag: false,
+      // 是否显示参数弹窗
+      showSetting: false,
+      controlList: [],
+      sampleShow: false,
+      taskId: null
+    };
+  },
+  created() {
+    this.requestDict('工种类型');
+  },
+  computed: {
+    typeOptions() {
+      return this.dict[this.dictEnum['工种类型']];
+    }
+  },
+  methods: {
+    /*配置工艺参数 */
+    openSetting(row) {
+      this.current = row;
+      this.showSetting = true;
     },
-    created() {
-      this.requestDict('工种类型');
+    /* 表格数据源 */
+    async datasource({page, limit, where, order}) {
+      return await getProfessionCertificationPageList({
+        ...where,
+        ...order,
+        pageNum: page,
+        size: limit
+      });
     },
-    computed: {
-      typeOptions() {
-        return this.dict[this.dictEnum['工种类型']];
-      }
+    downloadFile(file) {
+      getFile({objectName: file.storePath}, file.name);
+    },
+    /* 刷新表格 */
+    reload(where) {
+      this.$refs.table.reload({page: 1, where: where});
+    },
+    /* 打开编辑弹窗 */
+    openEdit(row = {}, type) {
+      this.addOrEditDialogFlag = true
+      this.$nextTick(() => {
+        this.$refs.addOrEditDialogRef.init(type,{...row} )
+      })
+      // this.isView = !!isView;
+      // this.getControlList();
+      // this.current = row;
+      // this.showEdit = true;
+      // this.$refs.userEdit.$refs.form &&
+      //   this.$refs.userEdit.$refs.form.clearValidate();
     },
-    methods: {
-      /*配置工艺参数 */
-      openSetting(row) {
-        this.current = row;
-        this.showSetting = true;
-      },
-      /* 表格数据源 */
-      async datasource({ page, limit, where, order }) {
-        const res = await getProfessionCertificationPageList({
-          ...where,
-          ...order,
-          pageNum: page,
-          size: limit
-        });
-        return res;
-      },
-
-      /* 刷新表格 */
-      reload(where) {
-        this.$refs.table.reload({ page: 1, where: where });
-      },
-      /* 打开编辑弹窗 */
-      openEdit(row, isView) {
-        this.isView = !!isView;
-        this.getControlList();
-        this.current = row;
-        this.showEdit = true;
-        this.$refs.userEdit.$refs.form &&
-          this.$refs.userEdit.$refs.form.clearValidate();
-      },
 
-      getControlList() {
-        const params = {
-          pageNum: 1,
-          size: -1
-        };
-        control.list().then((res) => {
-          this.controlList = res.list;
-        });
-      },
+    getControlList() {
+      const params = {
+        pageNum: 1,
+        size: -1
+      };
+      control.list().then((res) => {
+        this.controlList = res.list;
+      });
+    },
 
-      /* 删除 */
-      remove(row) {
-        const loading = this.$loading({ lock: true });
+    /* 删除 */
+    remove(row) {
+      const loading = this.$loading({lock: true});
 
-        deleteProfessionCertificationById([row.id])
-          .then((msg) => {
-            loading.close();
-            this.$message.success('删除' + msg);
-            this.reload();
-          })
-          .catch((e) => {
-            loading.close();
-            // this.$message.error(e.message);
-          });
-      },
-      /* 批量删除 */
-      removeBatch() {
-        if (!this.selection.length) {
-          this.$message.error('请至少选择一条数据');
-          return;
-        }
-        this.$confirm('确定要删除选中的资质吗?', '提示', {
-          type: 'warning'
+      deleteProfessionCertificationById([row.id])
+        .then((msg) => {
+          loading.close();
+          this.$message.success('删除' + msg);
+          this.reload();
         })
-          .then(() => {
-            const loading = this.$loading({ lock: true });
-            deleteProfessionCertificationById(this.selection.map((d) => d.id))
-              .then((msg) => {
-                loading.close();
-                this.$message.success('删除' + msg);
-                this.reload();
-              })
-              .catch((e) => {
-                loading.close();
-                // this.$message.error(e.message);
-              });
-          })
-          .catch(() => {});
-      },
-
-      sampleParam(row) {
-        this.taskId = row.id;
-        this.sampleShow = true;
-      },
-
-      close(done) {
-        this.sampleShow = false;
+        .catch((e) => {
+          loading.close();
+          // this.$message.error(e.message);
+        });
+    },
+    /* 批量删除 */
+    removeBatch() {
+      if (!this.selection.length) {
+        this.$message.error('请至少选择一条数据');
+        return;
       }
+      if (this.selection.length === 0) return;
+      let flag = this.selection.some(item => [1, 2].includes(item.processStatus))
+      if (flag) return this.$message.warning('抱歉已审核、审核中的数据不能删除,请检查')
+      this.$confirm('确定要删除选中的资质吗?', '提示', {
+        type: 'warning'
+      })
+        .then(() => {
+          const loading = this.$loading({lock: true});
+          deleteProfessionCertificationById(this.selection.map((d) => d.id))
+            .then((msg) => {
+              loading.close();
+              this.$message.success('删除' + msg);
+              this.reload();
+            })
+            .catch((e) => {
+              loading.close();
+              // this.$message.error(e.message);
+            });
+        })
+        .catch(() => {
+        });
+    },
+//开启资质提交流程
+    async submit(row) {
+      await contactQcSubmit({businessId: row.id,certificationType:row.certificationType})
+      this.$message.success('操作成功')
+      this.reload()
+    },
+    sampleParam(row) {
+      this.taskId = row.id;
+      this.sampleShow = true;
+    },
+
+    close(done) {
+      this.sampleShow = false;
     }
-  };
+  }
+};
 </script>