zouyu
2026-04-21 7b936dc5e04df96d319e6895fe883cad8ff57dd4
奖惩记录功能调整并迁移到绩效模块
已添加2个文件
已修改4个文件
583 ■■■■■ 文件已修改
src/assets/icons/svg/jcjilu.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/personnel/personnelInfo/index.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/performance/attendance/components/staffClockInRecord.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/performance/attendance/index.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/performance/rewardAndPunishment/index.vue 549 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/user/index.vue 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/icons/svg/jcjilu.svg
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1776757351956" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1675" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16"><path d="M574.4 396.7c-1.8-9.8-4.3-22.1-4.3-22.1h76.2l130.2-249c2.8-6.3 2-13.6-2.1-19-4-5.9-10.7-9.3-17.8-9.2h-481c-6.7 0.3-12.8 3.7-16.6 9.2-4.4 5.3-5.7 12.5-3.4 19l127.7 248.1h75.8s-2.5 12.9-4.6 22.7c-130.3 25.6-224.7 139-226.3 271.8 3.5 155.6 132.1 279.1 287.7 276.4 155.6 2.7 284.2-120.8 287.7-276.4-1.6-133.7-97.7-247.4-229.2-271.5z m-58.4 499c-128.5 2.3-234.5-99.9-237-228.4 2.5-128.4 108.6-230.6 237.1-228.2 128.4-2.4 234.5 99.7 237.1 228.2C750.6 795.8 644.5 898 516 895.7z m0 0" fill="#ffffff" p-id="1676"></path><path d="M330.3 668.2c1.8-100.1 84.1-180.1 184.2-179 48.4-0.9 95.1 17.5 130 51 34.8 33.6 54.9 79.6 55.8 128-2.7 100.4-85.3 180.2-185.8 179.3-99.9 0.1-181.6-79.5-184.2-179.3z m0 0" fill="#ffffff" p-id="1677"></path></svg>
src/views/CNAS/personnel/personnelInfo/index.vue
@@ -66,10 +66,10 @@
                                :departId="departId"
                                :isDepartment="isDepartment"></job-responsibilities>
        </el-tab-pane>
        <el-tab-pane label="奖惩记录" name="奖惩记录">
        <!-- <el-tab-pane label="奖惩记录" name="奖惩记录">
          <rewardPunishmentRecord v-if="activeName === '奖惩记录'"
                                  :departId="departId" :isDepartment="isDepartment"></rewardPunishmentRecord>
        </el-tab-pane>
                                  :departId="departId" :isDepartment="isDepartment"></rewardPunishmentRecord> -->
        <!-- </el-tab-pane> -->
        <el-tab-pane label="培训记录" name="培训记录">
          <training-record v-if="activeName === '培训记录'" ref="trainingRecord"
                           :departId="departId"
src/views/performance/attendance/components/staffClockInRecord.vue
@@ -333,7 +333,7 @@
    getDataSourceTypeTag(type) {
      const tagMap = {
        0: 'success',
        1: '',
        1: 'info',
      };
      return tagMap[type] || '';
    },
src/views/performance/attendance/index.vue
@@ -255,7 +255,7 @@
<script>
import StaffClockInRecord from "./components/staffClockInRecord.vue";
import {selectAllUser} from '@/api/system/user'
import {selectUserListByPerformance} from '@/api/system/user'
import {
  pageAttendanceRecord,
  checkDutyDate,
@@ -622,7 +622,7 @@
    },
    //查询用户列表
    getUserList(){
      selectAllUser().then(res=>{
      selectUserListByPerformance().then(res=>{
        this.userList = res.data
      }).catch(error=>{
        console.error(error)
src/views/performance/rewardAndPunishment/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,549 @@
<!-- å¥–惩记录 -->
<template>
  <div class="app-container">
    <div style="display: flex; justify-content: space-between">
      <div style="display: flex">
        <div
          style="
            margin-bottom: 18px;
            margin-right: 10px;
            display: flex;
            align-items: center;
            line-height: 32px;
          "
        >
          <span
            style="
              width: 48px;
              font-size: 14px;
              font-weight: 700;
              color: #606266;
            "
            >姓名</span
          >
          <el-input
            size="small"
            placeholder="请输入"
            clearable
            v-model="search.userName"
            @keyup.enter.native="getPersonnelTraining()"
          ></el-input>
        </div>
        <div
          style="
            margin-bottom: 18px;
            margin-right: 10px;
            display: flex;
            align-items: center;
            line-height: 32px;
          "
        >
          <span
            style="
              width: 88px;
              font-size: 14px;
              font-weight: 700;
              color: #606266;
            "
            >奖惩日期</span
          >
          <el-date-picker
            v-model="search.searchTimeList"
            :picker-options="pickerOptions"
            align="right"
            clearable
            @change="getPersonnelTraining()"
            end-placeholder="结束日期"
            format="yyyy-MM-dd HH:mm:ss"
            range-separator="至"
            size="small"
            start-placeholder="开始日期"
            style="width: 100%"
            type="daterange"
            unlink-panels
            :default-time="['00:00:00', '23:59:59']"
            value-format="yyyy-MM-dd HH:mm:ss"
          >
          </el-date-picker>
        </div>
        <div style="line-height: 30px">
          <el-button size="mini" type="primary" @click="getPersonnelTraining()"
            >查询</el-button
          >
          <el-button size="mini" @click="refreshTable()">重置</el-button>
          <el-button size="small" type="primary" @click="addRow"
            >新增</el-button
          >
          <el-button
            :loading="outLoading"
            size="small"
            type="success"
            @click="handleDown"
            >导出</el-button
          >
        </div>
      </div>
    </div>
    <div class="table">
      <el-table
        :data="tableData"
        v-loading="tableLoading"
        :header-cell-style="{
          background: '#f8f8f9',
          color: '#515a6e',
          textAlign: 'center',
        }"
        :cell-style="{ textAlign: 'center' }"
        border
        height="66.5vh"
        style="width: 100%"
      >
        <el-table-column label="序号" type="index" width="80"></el-table-column>
        <el-table-column
          label="员工编号"
          min-width="120"
          width="120"
          prop="account"
        ></el-table-column>
        <el-table-column
          label="员工姓名"
          min-width="180"
          width="120"
          prop="userName"
        ></el-table-column>
        <el-table-column
          label="奖惩名称"
          min-width="140"
          width="140"
          prop="rewardPunishName"
        ></el-table-column>
        <el-table-column
          label="奖惩时间"
          min-width="160"
          width="160"
          prop="rewardPunishTime"
        ></el-table-column>
        <el-table-column
          label="奖惩计分"
          min-width="120"
          width="120"
          prop="rewardPunishScore"
        ></el-table-column>
        <el-table-column
          label="奖惩金额"
          min-width="120"
          width="120"
          prop="rewardPunishSum"
        ></el-table-column>
        <el-table-column
          label="奖惩内容"
          min-width="160"
          prop="rewardPunishContent"
          show-overflow-tooltip
        ></el-table-column>
        <el-table-column
          label="创建人"
          min-width="120"
          width="120"
          prop="createUserName"
        ></el-table-column>
        <el-table-column
          label="创建时间"
          min-width="160"
          width="160"
          prop="createTime"
        ></el-table-column>
        <el-table-column
          label="更新人"
          min-width="120"
          width="120"
          prop="updateUserName"
        ></el-table-column>
        <el-table-column
          label="更新时间"
          min-width="160"
          width="160"
          prop="updateTime"
        ></el-table-column>
        <el-table-column fixed="right" label="操作" width="100" align="center">
          <template v-slot="scope">
            <el-button size="small" type="text" @click="editForm(scope.row)"
              >编辑</el-button
            >
            <el-button
              size="small"
              type="text"
              style="color: #f56c6c"
              @click="deleteRow(scope.row)"
              >删除</el-button
            >
          </template>
        </el-table-column>
      </el-table>
      <el-pagination
        :current-page="1"
        :page-size="search.size"
        :page-sizes="[10, 20, 30, 50, 100]"
        :total="search.total"
        layout="->,total, sizes, prev, pager, next, jumper"
        background
        style="margin-top: 10px"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      >
      </el-pagination>
    </div>
    <el-dialog
      :visible.sync="dialogVisible"
      title="奖惩记录"
      width="50%"
      @open="getUserList"
    >
      <div style="height: 40vh">
        <el-form ref="form" :model="form" :rules="rules" label-width="120px">
          <el-row>
            <el-col :span="12">
              <el-form-item label="员工编号">
                <el-input
                  v-model="form.account"
                  disabled
                  size="small"
                ></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="员工姓名" prop="userId">
                <el-select
                  :disabled="form.id"
                  v-model="form.userId"
                  placeholder="请选择员工姓名"
                  size="small"
                  style="width: 100%"
                  @change="selectUserChange"
                >
                  <el-option
                    v-for="item in responsibleOptions"
                    :key="item.id"
                    :label="item.name"
                    :value="item.id"
                  >
                  </el-option>
                </el-select>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="12">
              <el-form-item label="奖惩名称" prop="rewardPunishName">
                <el-input
                  placeholder="请输入奖惩名称"
                  type="textarea"
                  :rows="1"
                  v-model="form.rewardPunishName"
                  size="small"
                ></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="奖惩时间" prop="rewardPunishTime">
                <el-date-picker
                  v-model="form.rewardPunishTime"
                  format="yyyy-MM-dd"
                  placeholder="选择日期"
                  size="small"
                  style="width: 100%"
                  type="date"
                  value-format="yyyy-MM-dd"
                >
                </el-date-picker>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="12">
              <el-form-item label="奖惩计分" prop="rewardPunishScore">
                <el-input-number
                  controls-position="right"
                  :precision="1"
                  style="width: 100%"
                  v-model="form.rewardPunishScore"
                  size="small"
                  placeholder="请输入奖惩计分"
                ></el-input-number>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="奖惩金额" prop="rewardPunishSum">
                <el-input-number
                  controls-position="right"
                  :precision="2"
                  style="width: 100%"
                  :min="0"
                  v-model="form.rewardPunishSum"
                  size="small"
                  placeholder="请输入奖惩金额"
                ></el-input-number>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="24">
              <el-form-item label="奖惩内容">
                <el-input
                  v-model="form.rewardPunishContent"
                  :rows="2"
                  size="small"
                  type="textarea"
                  placeholder="请输入奖惩内容"
                ></el-input>
              </el-form-item>
            </el-col>
          </el-row>
        </el-form>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 æ¶ˆ</el-button>
        <el-button type="primary" @click="saveOrUpdate">ç¡® å®š</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import {
  addOrUpdateRewardPunishment,
  deleteRewardPunishment,
  rewardPunishmentExport,
  rewardPunishmentPage,
} from "@/api/cnas/personal/personRewardPunishmentRecord";
import { selectUserListByPerformance } from "@/api/system/user";
import { transformExcel } from "@/utils/file";
export default {
  data() {
    return {
      tableData: [],
      tableLoading: false,
      search: {
        size: 20,
        current: 1,
        total: 0,
        userName: "",
        searchTimeList: [],
      },
      form: {
        account: "",
        userId: null,
        rewardPunishScore: null,
        rewardPunishName: "",
        rewardPunishTime: null,
        rewardPunishSum: null,
        rewardPunishContent: "",
      },
      dialogVisible: false,
      outLoading: false,
      pickerOptions: {
        shortcuts: [
          {
            text: "最近一周",
            onClick(picker) {
              const end = new Date();
              const start = new Date();
              start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
              picker.$emit("pick", [start, end]);
            },
          },
          {
            text: "最近一个月",
            onClick(picker) {
              const end = new Date();
              const start = new Date();
              start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
              picker.$emit("pick", [start, end]);
            },
          },
          {
            text: "最近三个月",
            onClick(picker) {
              const end = new Date();
              const start = new Date();
              start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
              picker.$emit("pick", [start, end]);
            },
          },
        ],
      },
      rules: {
        userId: [
          {
            required: true,
            message: "请选择员工",
            trigger: "change",
          },
        ],
        rewardPunishScore: [
          {
            required: true,
            message: "请输入奖惩计分",
            trigger: "blur",
          },
        ],
        rewardPunishName: [
          {
            required: true,
            message: "请输入奖惩名称",
            trigger: "blur",
          },
        ],
        rewardPunishTime: [
          {
            required: true,
            message: "请输入奖惩时间",
            trigger: "blur",
          },
        ],
        rewardPunishSum: [
          {
            required: true,
            message: "请输入奖惩金额",
            trigger: "blur",
          },
        ],
      },
      responsibleOptions: [],
    };
  },
  mounted() {
    this.getPersonnelTraining();
    this.getUserList();
  },
  methods: {
    refreshTable() {
      this.search.userName = "";
      this.search.searchTimeList = [];
      this.$nextTick(() => {
        this.getPersonnelTraining();
      });
    },
    handleSizeChange(val) {
      this.search.size = val;
      this.getPersonnelTraining();
    },
    handleCurrentChange(val) {
      this.search.current = val;
      this.getPersonnelTraining();
    },
    async getPersonnelTraining() {
      const params = {
        userId: "",
        departmentId: "",
        current: this.search.curent,
        size: this.search.size,
        userName: this.search.userName,
        startTime: this.search.searchTimeList && this.search.searchTimeList[0],
        endTime: this.search.searchTimeList && this.search.searchTimeList[1],
      };
      this.tableLoading = true;
      rewardPunishmentPage(params)
        .then((res) => {
          this.tableLoading = false;
          this.tableData = res.data.records;
          this.search.total = res.data.total;
        })
        .catch((err) => {
          this.tableLoading = false;
        });
    },
    addRow() {
      this.dialogVisible = true;
    },
    handleDown() {
      this.outLoading = true;
      let params = {
        userName: this.search.userName,
      };
      if (this.search.searchTimeList && this.search.searchTimeList.length > 0) {
        params.startTime = this.search.searchTimeList[0];
        params.endTime = this.search.searchTimeList[1];
      }
      rewardPunishmentExport(params).then((res) => {
        transformExcel(res, "中天耐丝质量部奖惩记录.xlsx");
        this.$message.success("导出成功");
        this.$nextTick(() => {
          this.outLoading = false;
        });
      });
    },
    // èŽ·å–è´Ÿè´£äººä¿¡æ¯æŽ¥å£
    getUserList() {
      this.responsibleOptions = [];
      selectUserListByPerformance({ isTestUser: true }).then((res) => {
        if (res.code == 200) {
          this.responsibleOptions = res.data;
        }
      });
    },
    selectUserChange(val) {
      const index = this.responsibleOptions.findIndex(
        (item) => item.id === val
      );
      console.log(val, index);
      if (index > -1) {
        this.form.userName = this.responsibleOptions[index].name;
        this.form.account = this.responsibleOptions[index].account;
      }
    },
    // æ‰“开表单弹框
    editForm(row) {
      this.dialogVisible = true;
      this.form = { ...row };
    },
    // æäº¤è¡¨å•数据
    saveOrUpdate() {
      this.$refs.form.validate(async (valid) => {
        if (valid) {
          addOrUpdateRewardPunishment(this.form).then((res) => {
            this.dialogVisible = false;
            this.$message.success("操作成功");
            this.getPersonnelTraining();
          });
        }
      });
    },
    deleteRow(row) {
      this.$confirm("是否删除当前数据?", "警告", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          deleteRewardPunishment({ id: row.id })
            .then((res) => {
              if (res.code === 500) {
                return;
              }
              this.$message.success("删除成功");
              this.getPersonnelTraining();
            })
            .catch((e) => {
              this.$message.error("删除失败");
            });
        })
        .catch(() => {});
    },
  },
  watch: {
    dialogVisible(newVal) {
      if (newVal === false) {
        this.form = {};
        this.$refs.form.resetFields();
      }
    },
  },
};
</script>
<style scoped>
.dateTime >>> .el-form-item__content {
  width: 260px;
}
</style>
src/views/system/user/index.vue
@@ -48,6 +48,11 @@
          </div>
          <el-col>
            <el-table ref="dragTable" v-loading="loading" row-key="userId" :data="userList" :header-cell-style="{ background: '#f8f8f9', color: '#515a6e' }" border>
              <el-table-column label="拖拽" align="center" width="60">
                <template slot-scope="scope">
                  <i class="el-icon-rank drag-handle" :data-user-id="scope.row.userId"></i>
                </template>
              </el-table-column>
              <el-table-column label="序号" align="center" type="index" />
              <el-table-column label="姓名" align="center" key="nickName" prop="nickName" :show-overflow-tooltip="true" />
              <el-table-column label="账号" align="center" key="userName" prop="userName" :show-overflow-tooltip="true" />
@@ -523,6 +528,7 @@
        ghostClass: 'sortable-ghost', // æ‹–拽占位符样式
        chosenClass: 'sortable-chosen', // é€‰ä¸­è¡Œæ ·å¼
        dragClass: 'sortable-drag', // æ‹–拽元素样式
        handle: '.drag-handle',
        disabled: this.loading || this.sortSaving,
        // æ‹–拽结束触发(核心逻辑)
        onEnd: async({ oldIndex, newIndex }) => {
@@ -1000,8 +1006,19 @@
</script>
<style scoped lang="scss">
:deep(.el-table__body-wrapper tbody tr) {
  cursor: move;
:deep(.drag-handle) {
  cursor: grab;
  color: #909399;
  font-size: 16px;
  display: inline-block;
  user-select: none;
}
:deep(.drag-handle:hover) {
  color: #409EFF;
  cursor: grab;
}
:deep(.drag-handle:active) {
  cursor: grabbing;
}
:deep(.sortable-ghost) {
  opacity: 0.8;