lxp
2025-03-12 952a20f1c005d80e9bf881287c40e6f4e4266a0b
src/views/CNAS/personnel/personnelInfo/Department/components/PersonnelTraining/Edit.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,662 @@
<template>
  <div>
    <div class="page-header">
      <h4><span class="line"></span><span>培训与考核记录</span></h4>
      <div class="btns">
        <el-button size="small" type="primary" @click="submitForm" :disabled="![1, 4].includes(currentRow.state)">{{
          currentRow.assessmentUserId ? '保存' : '提交' }}</el-button>
        <el-button size="small" @click="$emit('goBack')">返回</el-button>
      </div>
    </div>
    <div class="form_title">
      <el-row>
        <el-col :span="5">
          <span class="form_label">课程编号:</span>
          <span> {{ trainingForm.courseCode }} </span>
        </el-col>
        <el-col :span="6">
          <span class="form_label">培训内容:</span>
          <span> {{ trainingForm.trainingContent }} </span>
        </el-col>
        <el-col :span="4">
          <span class="form_label">状态:</span>
          <el-tag v-if="trainingForm.state === 1" type="success">已完成</el-tag>
          <el-tag v-if="trainingForm.state === 2" type="warning">进行中</el-tag>
          <el-tag v-if="trainingForm.state === 3" type="primary">未开始</el-tag>
          <el-tag v-if="trainingForm.state === 4" type="info">已结束</el-tag>
        </el-col>
        <el-col :span="4">
          <span class="form_label">培训讲师:</span>
          <span> {{ trainingForm.trainingLecturerId }} </span>
        </el-col>
        <el-col :span="4">
          <span class="form_label">培训日期:</span>
          <span> {{ trainingForm.trainingDate }} </span>
        </el-col>
      </el-row>
      <el-row style="margin: 15px 0">
        <el-form>
          <el-col :span="12">
            <el-form-item label="考核方式">
              <el-input v-model="trainingForm.assessmentMethod"
                :disabled="currentRow.state == 1 || currentRow.assessmentUserId" :rows="2" placeholder="请输入"
                size="small" style="width: 79%" type="textarea"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="本次培训综合评价">
              <el-input v-model="trainingForm.comprehensiveAssessment"
                :disabled="currentRow.state == 1 || ((currentRow.assessmentUserId !== user.userId) && ![35, 16, 36].includes(user.userId)) || !currentRow.assessmentUserId"
                :rows="2" placeholder="请输入" size="small" style="width: 68%" type="textarea"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="评价人">
              <el-select v-model="trainingForm.assessmentUserId"
                :disabled="currentRow.state == 1 || currentRow.assessmentUserId" placeholder="请选择" size="small"
                style="width: 68%">
                <el-option v-for="item in userList" :key="item.id" :label="item.name" :value="item.id"></el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="评价时间">
              <el-date-picker v-model="trainingForm.assessmentDate"
                :disabled="currentRow.state == 1 || ((currentRow.assessmentUserId !== user.userId) && ![35, 16, 36].includes(user.userId)) || !currentRow.assessmentUserId"
                style="width:40%" type="date" format="yyyy-MM-dd" value-format="yyyy-MM-dd" size="small"
                placeholder="选择日期">
              </el-date-picker>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="培训摘要">
              <el-input v-model="trainingForm.trainingAbstract"
                :disabled="currentRow.state == 1 || currentRow.assessmentUserId" :rows="2" placeholder="请输入"
                size="small" style="width: 79%" type="textarea"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item>
              <!-- <el-upload
                ref="upload"
                :action="action"
                :before-upload="beforeUpload"
                :on-error="onError"
                :data="uploadData"
                :headers="uploadHeader"
                :on-success="attachmentUpload"
                >
                <el-button size="small" type="primary">点击上传</el-button>
              </el-upload> -->
              <el-button type="primary" size="small" @click="attachmentFrame = true">附件</el-button>
            </el-form-item>
          </el-col>
          <!-- <el-col :span="12" :offset="12">
            <el-image
              v-if="currentRow.url"
              style="width: 70%; height: 100px"
              :src="javaApi + '/img/' + currentRow.url">
              </el-image>
          </el-col> -->
        </el-form>
      </el-row>
    </div>
    <!-- æ–‡ä»¶é¢„览 -->
    <el-dialog :visible.sync="lookDialogVisible" fullscreen title="查看附件" width="800px">
      <filePreview v-if="lookDialogVisible" :currentFile="{}" :fileUrl="previewFile"
        style="height: 90vh;overflow-y: auto;top: 0" />
    </el-dialog>
    <!-- é™„件弹框 -->
    <el-dialog title="附件" :visible.sync="attachmentFrame" width="70%" border :before-close="handleClose">
      <el-upload ref="upload" :action="action" :before-upload="beforeUpload" :on-error="onError" :data="uploadData"
        :headers="uploadHeader" :on-success="attachmentUpload" style="margin-bottom: 10px">
        <el-button size="small" type="primary" :disabled="currentRow.state == 1">上传附件</el-button>
      </el-upload>
      <el-table ref="fileData" :data="fileData" height="400px">
        <el-table-column label="序号" type="index" width="100" header-align="center" align="center">
        </el-table-column>
        <el-table-column label="文件名称" prop="fileName" header-align="center" align="center">
        </el-table-column>
        <el-table-column label="操作" fixed="right" width="200px" header-align="center" align="center">
          <template slot-scope="scope">
            <el-button type="text" size="small" @click="preview(scope.row)">预览</el-button>
            <el-button type="text" size="small" @click="download(scope.row)">下载</el-button>
            <el-button type="text" style="color: red;" size="small" @click="deleteFile(scope.row)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
      <span slot="footer" class="dialog-footer">
        <el-button @click="attachmentFrame = false">取 æ¶ˆ</el-button>
        <el-button type="primary" @click="attachmentFrame = false">ç¡® å®š</el-button>
      </span>
    </el-dialog>
    <el-divider>人员详情</el-divider>
    <div>
      <div class="items_center">
        <span>姓名</span>
        <el-input v-model="userName" class="search" placeholder="请输入" size="small"></el-input>
        <el-button size="small" type="primary" @click="getInfo">查询</el-button>
      </div>
      <div class="items_btn">
        <el-button :disabled="currentRow.state === 1" size="small" type="primary" @click="addPerson">新增人员</el-button>
        <el-button :disabled="currentRow.state === 1" size="small" @click="batchDelete">批量删除</el-button>
      </div>
      <el-table :data="trainingTableData" height="calc(100vh - 30em)" stripe style="width: 100%"
        @selection-change="handleSelectionChange">
        <el-table-column type="selection" width="55"></el-table-column>
        <el-table-column label="序号" type="index" width="60"></el-table-column>
        <el-table-column label="姓名" prop="userName"></el-table-column>
        <el-table-column label="工号" prop="account"></el-table-column>
        <el-table-column label="角色" prop="roleName"></el-table-column>
        <el-table-column label="电话号码" prop="phone"></el-table-column>
        <el-table-column label="考核结果" prop="examinationResults">
          <template v-slot="scope">
            <el-select v-model="scope.row.examinationResults" :disabled="currentRow.state === 1" size="small"
              style="width: 100%" @change="updatePersonResult(scope.row)">
              <el-option label="合格" value="合格"></el-option>
              <el-option label="不合格" value="不合格"></el-option>
            </el-select>
          </template>
        </el-table-column>
      </el-table>
    </div>
    <el-dialog :visible.sync="selectUserDia" title="选择用户" width="70%">
      <div class="search" style="margin-bottom: 9px;">
        <div class="search_thing">
          <div class="search_label">用户名:</div>
          <div class="search_input">
            <el-input v-model="queryParams.name" clearable placeholder="请输入" size="small"
              @keyup.enter.native="$refs.ValueTable.selectList()"></el-input>
          </div>
        </div>
      </div>
      <div v-if="selectUserDia" class="body" style="height: 60vh;">
        <lims-table :tableData="tableData" :column="column" :tableLoading="tableLoading" :height="'calc(100vh - 290px)'"
          :page="page" @pagination="pagination" :isSelection="true"
          :handleSelectionChange="handleSelectionChange"></lims-table>
        <!-- <ValueTable ref="ValueTable" :componentData="addUserTableInfo" :isSelectedList="isSelectedList"
          :url="$api.user.selectUserList" /> -->
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="selectUserDia = false">取 æ¶ˆ</el-button>
        <el-button type="primary" @click="selectUser">ç¡® å®š</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import TableCard from '@/components/TableCard/index.vue';
import limsTable from "@/components/Table/lims-table.vue";
// import ValueTable from '@/components/Table/value-table.vue';
import filePreview from "@/components/Preview/filePreview.vue";
import {
  fileDownLoad,
  deleteFile,
  getFileData,
  trainingAndAssessmentRecordsPage,
  outOfFocusPreservation,
  newPersonnelAddedToTrainingRecords,
  deleteTrainingAndAssessmentRecords,
  trainingAndAssessmentRecordsAdded,
  selectUserList,
} from '@/api/cnas/personnel/personnelInfo.js'
import { selectUserCondition } from "@/api/system/user";
import { mapGetters } from "vuex";
export default {
  name: 'Edit',
  // import å¼•入的组件需要注入到对象中才能使用
  components: { limsTable, TableCard, filePreview },
  props: {
    currentRow: {
      type: Object,
      default: () => {
        return {}
      }
    },
  },
  data() {
    // è¿™é‡Œå­˜æ”¾æ•°æ®
    return {
      previewFile: '',
      lookDialogVisible: false,
      user: {},
      fileData: [],
      attachmentFrame: false,
      isSelectedList: [], // ç¦ç”¨çš„多选
      userName: undefined,
      trainingForm: {
        code: '111111',
        date: '2024-10-10',
      },
      uploadData: {},
      trainingColumn: [
        {
          label: '姓名',
          prop: 'userName'
        },
        {
          label: '工号',
          prop: 'account'
        },
        {
          label: '角色',
          prop: 'roleName'
        },
        {
          label: '电话号码',
          prop: 'phone'
        },
        {
          label: '考核结果',
          prop: 'result'
        }
      ],
      trainingTableData: [],
      trainingLoading: false,
      selectUserDia: false, // æ·»åŠ äººå‘˜å¼¹æ¡†
      addUserTableInfo: {
        name: null,
        entity: {
          departLimsId: '1',
          orderBy: {
            field: 'id',
            order: 'asc'
          }
        },
        isIndex: true,
        showSelect: true,
        select: true,
        do: [],
        tagField: {
          state: {
            select: [
              {
                value: 1,
                type: 'success',
                label: '启用'
              },
              {
                value: 0,
                type: 'danger',
                label: '停用'
              }
            ]
          }
        },
        selectField: {},
        upUserDepardLimsIdPower: true
      },
      multipleSelection: [],
      multipleSelections: [],
      userList: [],
      stateList: [
        {
          value: 1,
          type: 'success',
          label: '启用'
        },
        {
          value: 0,
          type: 'danger',
          label: '停用'
        }
      ],
      queryParams: {},
      tableData: [],
      column: [
        { label: "姓名", prop: "name" },
        { label: "账号", prop: "account" },
        {
          label: "角色",
          prop: "roleName",
        },
        {
          label: "状态", prop: "state", dataType: "tag",
          formatData: (params) => {
            let index = this.stateList.findIndex(
              (item) => item.value == params
            );
            if (index > -1) {
              return this.stateList[index].label;
            } else {
              return null;
            }
          },
          formatType: (params) => {
            let index = this.stateList.findIndex(
              (item) => item.value == params
            );
            if (index > -1) {
              return this.stateList[index].type;
            } else {
              return null;
            }
          },
        },
        { label: "电话号码", prop: "phone" },
      ],
      page: {
        total: 0,
        size: 10,
        current: 0,
      },
      tableLoading: false,
    };
  },
  computed: {
    action() {
      return this.javaApi + '/personTraining/fileUpload';
    },
    ...mapGetters(["userId"]),
  },
  mounted() {
    this.trainingForm = JSON.parse(JSON.stringify(this.currentRow))
    this.getInfo()
    this.getUserList()
    this.getFileData(this.trainingForm.id)
    // èŽ·å–å½“å‰ç™»å½•äººä¿¡æ¯
    this.loginPerson();
  },
  // æ–¹æ³•集合
  methods: {
    // é™„件预览
    preview(row) {
      let folder = '';
      if (row.fileUrl.includes('xls')) {
        folder = 'excel'
      } else if (row.fileUrl.includes('docx')) {
        folder = 'word'
      } else {
        folder = 'img'
      }
      this.previewFile = this.javaApi + folder + row.fileUrl
      this.$nextTick(() => {
        this.lookDialogVisible = true
      })
    },
    // ä¸‹è½½
    download(row) {
      fileDownLoad({ id: row.id }).then(res => {
        console.log('2123');
        const blob = new Blob([res], { type: row.mime });
        this.$download.saveAs(blob, row.fileName)
      })
    },
    // åˆ é™¤
    deleteFile(row) {
      this.$confirm('此操作将永久删除该文件, æ˜¯å¦ç»§ç»­?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        deleteFile({ id: row.id }).then(res => {
          this.$message({
            type: 'success',
            message: '删除成功!'
          });
          this.getFileData(this.trainingForm.id);
        })
      })
    },
    // æŸ¥è¯¢
    getFileData(id) {
      getFileData({ detailedId: id }).then(res => {
        this.fileData = res.data
      })
    },
    // é™„件上传 æˆåŠŸçš„é’©å­
    attachmentUpload(res, file, fileList) {
      // ç»™å›¾ç‰‡è·¯å¾„赋值
      this.$message.success('上传成功')
      this.currentRow.url = res.data.url
      this.$refs.upload.clearFiles();
      this.getFileData(this.trainingForm.id);
    },
    // å¤±è´¥çš„钩子
    onError(err, file, fileList) {
      this.$message.error('上传失败')
    },
    // ä¸Šä¼ å‰çš„钩子
    beforeUpload(file) {
      // ç»™ä¼ é€’的参数赋值
      this.$set(this.uploadData, "id", this.currentRow.id)
    },
    // å½“前登录人信息
    loginPerson() {
      this.user = {
        userId: this.userId
      }
    },
    // èŽ·å–å½“å‰æ•°æ®
    async getInfo() {
      this.trainingLoading = true
      trainingAndAssessmentRecordsPage({
        trainingDetailedId: this.currentRow.id,
        userName: this.userName
      }).then(res => {
        if (res.code === 200) {
          this.trainingTableData = res.data
        }
        this.trainingLoading = false
      })
    },
    async updatePersonResult(row) {
      const { code } = await outOfFocusPreservation(row)
      if (code === 200) {
        this.$message.success("操作成功!")
      }
    },
    getList() {
      this.tableLoading = true;
      let param = { ...this.queryParams, ...this.page };
      delete param.total;
      selectUserList({ ...param })
        .then((res) => {
          this.tableLoading = false;
          if (res.code === 200) {
            this.tableData = res.data.records;
            this.page.total = res.data.total;
          }
        })
        .catch((err) => {
          this.tableLoading = false;
        });
    },
    pagination({ page, limit }) {
      this.page.current = page;
      this.page.size = limit;
      this.getList();
    },
    handleSelectionChange(val) {
      this.multipleSelections = val
    },
    addPerson() {
      this.isSelectedList = this.trainingTableData.map(item => item.userId)
      this.getList()
      this.selectUserDia = true;
    },
    selectUser() {
      let selects = this.multipleSelections;
      if (selects.length == 0) {
        this.$message.error('未选择数据');
        return;
      }
      let list = []
      selects.forEach(a => {
        const obj = {
          courseId: this.currentRow.id,
          examinationResults: "",
          userId: a.id
        }
        list.push(obj)
        // this.trainingTableData.push(obj);
      });
      newPersonnelAddedToTrainingRecords(list).then(res => {
        this.isSelectedList = []
        this.selectUserDia = false;
        this.getInfo()
      })
    },
    // æ‰¹é‡åˆ é™¤
    handleSelectionChange(list) {
      this.multipleSelection = list
    },
    batchDelete() {
      console.log('批量删除', this.multipleSelection)
      if (this.multipleSelection.length > 0) {
        let ids = this.multipleSelection.map(item => item.trainingRecordId)
        this.$confirm('是否确认删除所选择的数据?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          let formData = new FormData()
          formData.append('ids', ids)
          deleteTrainingAndAssessmentRecords(formData)
            .then(res => {
              if (res.code == 200) {
                this.$message.success('删除成功');
                this.getInfo()
              }
            });
        }).catch(() => {
          this.$message.warning('取消删除');
        });
      } else {
        this.$message.warning('请选择需要删除的数据')
      }
    },
    handleSizeChange(val) {
      this.search.size = val;
      this.getInfo();
    },
    handleCurrentChange(val) {
      this.search.current = val;
      this.getInfo();
    },
    /**
     * @desc æäº¤è¡¨å•
     */
    async submitForm() {
      console.log('this.currentRow.state', this.currentRow.state);
      if (this.currentRow.state !== 4 && this.currentRow.state !== 1) {
        this.$message.warning("当前状态无法提交/撤销!")
        return
      }
      // å¦‚果等于4 è¡¨ç¤ºè¯¥çŠ¶æ€ä¸ºå·²ç»“æŸï¼Œ1 è¡¨ç¤ºå·²å®Œæˆ
      let state = 4
      if (this.currentRow.assessmentUserId == this.user.userId) {
        state = 1
      }
      let data = {
        assessmentMethod: this.trainingForm.assessmentMethod,
        comprehensiveAssessment: this.trainingForm.comprehensiveAssessment,
        trainingDetailedId: this.trainingForm.id,
        assessmentUserId: this.currentRow.assessmentUserId ? this.currentRow.assessmentUserId : this.trainingForm.assessmentUserId,
        assessmentDate: this.trainingForm.assessmentDate,
        state: state,
        trainingAbstract: this.trainingForm.trainingAbstract
      }
      const { code } = await trainingAndAssessmentRecordsAdded(data)
      if (code === 200) {
        this.currentRow.state = state
        this.$message.success("操作成功")
        // this.$emit('refresh',this.currentRow.id)
      }
    },
    getUserList() {
      selectUserCondition().then(res => {
        if (res.code === 201) {
          return
        }
        this.userList = res.data
      })
    },
    handleClose() {
      this.attachmentFrame = false;
    },
  }
};
</script>
<style scoped>
.page-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 20px;
  margin-bottom: 10px;
}
h4 {
  display: flex;
  align-items: center;
}
h4 .line {
  display: inline-block;
  width: 3px;
  height: 16px;
  background: #3A7BFA;
  margin-right: 4px;
}
.form_title {
  font-size: 14px;
  padding: 0 20px;
  margin-bottom: 10px;
}
.el-divider {
  margin: 0 1em 1em 0;
}
.form__input_label {
  width: 90px;
  margin-right: 6px;
  color: #606266;
}
.form__input_label2 {
  width: 210px;
  margin-right: 6px;
  color: #606266;
}
.search_thing {
  display: flex;
  align-items: center
}
.search_label {
  width: 120px;
}
.pagination {
  display: flex;
  justify-content: space-between
}
.items_center {
  float: left;
  width: 50%;
  text-align: left;
}
.items_btn {
  text-align: right;
  width: 50%;
  float: right;
  margin-bottom: 1em;
}
.search {
  width: 180px;
  padding: 0 16px;
}
</style>