已添加6个文件
已修改5个文件
219 ■■■■ 文件已修改
multiple/assets/favicon/BTWfavicon.ico 补丁 | 查看 | 原始文档 | blame | 历史
multiple/assets/favicon/JFHYfavicon.ico 补丁 | 查看 | 原始文档 | blame | 历史
multiple/assets/logo/BTWLogo.png 补丁 | 查看 | 原始文档 | blame | 历史
multiple/assets/logo/JFHYLogo.png 补丁 | 查看 | 原始文档 | blame | 历史
multiple/config.json 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/mock/dataCheck.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/personnelManagement/staffSalaryMain.js 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mock/dataCheck/index.vue 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/personnelManagement/monthlyStatistics/components/auditDia.vue 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/personnelManagement/monthlyStatistics/components/formDia.vue 84 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/personnelManagement/monthlyStatistics/index.vue 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
multiple/assets/favicon/BTWfavicon.ico
multiple/assets/favicon/JFHYfavicon.ico
multiple/assets/logo/BTWLogo.png
multiple/assets/logo/JFHYLogo.png
multiple/config.json
@@ -278,6 +278,24 @@
    "logo": "logo/NYLogo.png",
    "favicon": "favicon/NYfavicon.ico"
  },
  "JFHY": {
    "env": {
      "VITE_APP_TITLE": "山西金福恒远商贸有限公司",
      "VITE_BASE_API": "http://36.134.76.148:9100",
      "VITE_JAVA_API": "http://36.134.76.148:9099"
    },
    "logo": "logo/JFHYLogo.png",
    "favicon": "favicon/JFHYfavicon.ico"
  },
  "BTW": {
    "env": {
      "VITE_APP_TITLE": "山西比特维科技有限公司",
      "VITE_BASE_API": "http://36.134.76.148:9102",
      "VITE_JAVA_API": "http://36.134.76.148:9101"
    },
    "logo": "logo/BTWLogo.png",
    "favicon": "favicon/BTWfavicon.ico"
  },
  "logo": "/src/assets/logo/logo.png",
  "favicon": "/public/favicon.ico"
}
src/api/mock/dataCheck.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,10 @@
import request from "@/utils/request";
// æ£€æµ‹æŒ‡å®šæ¨¡å—的基础数据是否就绪
export function dataCheck(modules) {
  return request({
    url: "/mock/dataCheck",
    method: "post",
    data: { modules },
  });
}
src/api/personnelManagement/staffSalaryMain.js
@@ -48,3 +48,12 @@
    data: ids,
  });
}
// èŽ·å–å¯ç”¨éƒ¨é—¨åˆ—è¡¨ï¼ˆæ ¹æ®æœˆä»½æŸ¥è¯¢ï¼ŒæŽ’é™¤å·²å‘æ”¾å·¥èµ„è¡¨çš„éƒ¨é—¨ï¼‰
export function staffSalaryMainAvailableDepts(salaryMonth) {
  return request({
    url: "/staffSalaryMain/availableDepts",
    method: "get",
    params: { salaryMonth },
  });
}
src/views/mock/dataCheck/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,65 @@
<template>
  <div class="app-container">
    <el-card header="基础数据检测">
      <el-checkbox-group v-model="selectedModules">
        <el-checkbox label="sales">销售模块</el-checkbox>
        <el-checkbox label="purchase">采购模块</el-checkbox>
        <el-checkbox label="quality">质量模块</el-checkbox>
      </el-checkbox-group>
      <div style="margin-top: 16px">
        <el-button type="primary" @click="handleCheck" :loading="checking">
          å¼€å§‹æ£€æµ‹
        </el-button>
      </div>
    </el-card>
    <el-card v-if="checkResult" header="检测结果" style="margin-top: 16px">
      <el-alert
        :title="`通过 ${checkResult.passedItems} / ${checkResult.totalItems} é¡¹`"
        :type="checkResult.passedItems === checkResult.totalItems ? 'success' : 'warning'"
        :closable="false"
        show-icon
      />
      <el-table :data="checkResult.items" style="margin-top: 12px" border>
        <el-table-column prop="module" label="模块" width="100" />
        <el-table-column prop="itemName" label="检测项" width="160" />
        <el-table-column prop="minRequired" label="最低要求" width="80" align="center" />
        <el-table-column prop="currentCount" label="当前数量" width="80" align="center" />
        <el-table-column label="状态" width="80" align="center">
          <template #default="{ row }">
            <el-tag :type="row.passed ? 'success' : 'danger'">
              {{ row.passed ? "通过" : "未通过" }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="message" label="提示" min-width="200" />
      </el-table>
    </el-card>
  </div>
</template>
<script setup>
import { ref } from "vue";
import { ElMessage } from "element-plus";
import { dataCheck } from "@/api/mock/dataCheck.js";
const selectedModules = ref(["sales", "purchase", "quality"]);
const checking = ref(false);
const checkResult = ref(null);
const handleCheck = async () => {
  if (selectedModules.value.length === 0) {
    ElMessage.warning("请至少选择一个模块");
    return;
  }
  checking.value = true;
  try {
    const res = await dataCheck(selectedModules.value);
    checkResult.value = res.data;
  } finally {
    checking.value = false;
  }
};
</script>
<style scoped></style>
src/views/personnelManagement/monthlyStatistics/components/auditDia.vue
@@ -86,7 +86,7 @@
<script setup>
import { ref, computed, reactive, toRefs, getCurrentInstance, watch } from "vue";
import { ElMessage } from "element-plus";
import Cookies from "js-cookie";
import useUserStore from "@/store/modules/user";
import FormDialog from "@/components/Dialog/FormDialog.vue";
import { staffSalaryMainUpdate } from "@/api/personnelManagement/staffSalaryMain.js";
@@ -98,6 +98,7 @@
});
const { proxy } = getCurrentInstance();
const userStore = useUserStore();
const dialogVisible = computed({
  get: () => props.modelValue,
@@ -176,15 +177,21 @@
      return;
    }
    
    const username = Cookies.get("username") || "";
    const userIdRaw = Cookies.get("userId");
    const auditUserId = userIdRaw ? Number(userIdRaw) : undefined;
    const username = userStore.name || "";
    const currentUserId = Number(userStore.id);
    const assignedAuditUserId = Number(row?.auditUserId);
    // æƒé™éªŒè¯ï¼šåªæœ‰æŒ‡å®šçš„审核人才能进行审核
    if (!currentUserId || currentUserId !== assignedAuditUserId) {
      ElMessage.warning("您不是指定的审核人,无法进行审核操作");
      return;
    }
    
    // æž„建审核数据
    const submitData = {
      id: row.id,
      status: Number(auditResult.value) === 2 ? 2 : 4, // 2=不通过 4=通过(待发放)
      auditUserId,
      auditUserId: currentUserId,
      auditUserName: username,
    };
    loading.value = true;
src/views/personnelManagement/monthlyStatistics/components/formDia.vue
@@ -36,6 +36,18 @@
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="选择工资月份"
                            prop="salaryMonth">
                <el-date-picker v-model="form.salaryMonth"
                                type="month"
                                value-format="YYYY-MM"
                                format="YYYY-MM"
                                placeholder="请选择工资月份"
                                style="width: 100%"
                                clearable />
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="选择部门"
                            prop="deptIds">
                <el-select v-model="form.deptIds"
@@ -47,20 +59,9 @@
                  <el-option v-for="item in deptOptions"
                             :key="item.deptId"
                             :label="item.deptName"
                             :value="item.deptId" />
                             :value="item.deptId"
                             :disabled="isDeptDisabled(item.deptId)" />
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="选择工资月份"
                            prop="salaryMonth">
                <el-date-picker v-model="form.salaryMonth"
                                type="month"
                                value-format="YYYY-MM"
                                format="YYYY-MM"
                                placeholder="请选择工资月份"
                                style="width: 100%"
                                clearable />
              </el-form-item>
            </el-col>
            <el-col :span="6">
@@ -344,18 +345,20 @@
    computed,
    getCurrentInstance,
    nextTick,
    watch,
  } from "vue";
  import { ArrowUp } from "@element-plus/icons-vue";
  import FormDialog from "@/components/Dialog/FormDialog.vue";
  import { listDept } from "@/api/system/dept.js";
  import { staffOnJobList } from "@/api/personnelManagement/monthlyStatistics.js";
  import { bankList } from "@/api/personnelManagement/bank.js";
  import {
    staffSalaryMainAdd,
    staffSalaryMainUpdate,
    staffSalaryMainCalculateSalary,
    staffSalaryMainCalculateByEmployeeId,
  } from "@/api/personnelManagement/staffSalaryMain.js";
import { bankList } from "@/api/personnelManagement/bank.js";
import {
  staffSalaryMainAdd,
  staffSalaryMainUpdate,
  staffSalaryMainCalculateSalary,
  staffSalaryMainCalculateByEmployeeId,
  staffSalaryMainAvailableDepts,
} from "@/api/personnelManagement/staffSalaryMain.js";
  import { userListNoPageByTenantId } from "@/api/system/user.js";
  const emit = defineEmits(["update:modelValue", "close"]);
@@ -378,6 +381,7 @@
  const addPersonVisible = ref(false);
  const taxDialogVisible = ref(false);
  const deptOptions = ref([]);
  const availableDeptIds = ref(new Set());
  const deptStaffTree = ref([]);
  const employeeList = ref([]);
  const selectedEmployees = ref([]);
@@ -573,11 +577,32 @@
    return list;
  }
  const loadDeptOptions = () => {
  // åŠ è½½æ‰€æœ‰éƒ¨é—¨
  const loadAllDeptOptions = () => {
    listDept().then(res => {
      const tree = res.data ?? [];
      deptOptions.value = flattenDept(tree);
    });
  };
  // åŠ è½½å¯ç”¨éƒ¨é—¨åˆ—è¡¨ï¼ˆç”¨äºŽåˆ¤æ–­éƒ¨é—¨æ˜¯å¦å¯é€‰ï¼‰
  const loadAvailableDepts = (salaryMonth) => {
    if (!salaryMonth) {
      availableDeptIds.value = new Set();
      return;
    }
    staffSalaryMainAvailableDepts(salaryMonth).then(res => {
      const availableDepts = Array.isArray(res.data) ? res.data : [];
      availableDeptIds.value = new Set(availableDepts.map(d => d.deptId));
    });
  };
  // åˆ¤æ–­éƒ¨é—¨æ˜¯å¦ç¦ç”¨
  const isDeptDisabled = (deptId) => {
    // å¦‚果没有选择月份,所有部门都可选
    if (!form.value.salaryMonth) return false;
    // å¦‚果已选择月份,只有在可用部门列表中的部门才可选
    return !availableDeptIds.value.has(deptId);
  };
  // æž„建 éƒ¨é—¨-人员 æ ‘(用于新增人员弹窗)
@@ -621,9 +646,9 @@
  const openDialog = (type, row) => {
    nextTick(() => {
      resetRecalcState();
      loadDeptOptions();
      loadBankOptions();
      loadUserList();
      loadAllDeptOptions();
      employeeList.value = [];
      Object.assign(form.value, {
        id: undefined,
@@ -655,8 +680,21 @@
          employeeList.value = row.staffSalaryDetailList.map(e => normalizeEmployeeRow(e));
        }
      }
      // ç¼–辑状态且有月份时,加载可用部门列表
      if (type === "edit" && form.value.salaryMonth) {
        loadAvailableDepts(form.value.salaryMonth);
      }
    });
  };
  // ç›‘听工资月份变化,清空部门选择并加载可用部门列表
  watch(() => form.value.salaryMonth, (newMonth, oldMonth) => {
    // åˆ‡æ¢æœˆä»½æ—¶æ¸…空已选择的部门
    if (newMonth !== oldMonth) {
      form.value.deptIds = [];
    }
    loadAvailableDepts(newMonth);
  });
  const openAddPerson = () => {
    loadDeptStaffTree();
@@ -895,4 +933,4 @@
    font-weight: bold;
    font-size: 18px;
  }
</style>
</style>
src/views/personnelManagement/monthlyStatistics/index.vue
@@ -107,7 +107,7 @@
  nextTick,
} from "vue";
import { ElMessageBox } from "element-plus";
import Cookies from "js-cookie";
import useUserStore from "@/store/modules/user";
import FormDia from "./components/formDia.vue";
import BankSettingDia from "./components/bankSettingDia.vue";
import AuditDia from "./components/auditDia.vue";
@@ -167,7 +167,12 @@
      {
        name: "审核",
        type: "text",
        disabled: (row) => Number(row?.status) !== 3,
        disabled: (row) => {
          const currentUserId = Number(userStore.id);
          const auditUserId = Number(row?.auditUserId);
          // çŠ¶æ€ä¸æ˜¯å¾…å®¡æ ¸ æˆ– å½“前用户不是指定的审核人,则禁用审核按钮
          return Number(row?.status) !== 3 || !currentUserId || currentUserId !== auditUserId;
        },
        clickFun: (row) => openAudit(row),
      },
      {
@@ -193,6 +198,7 @@
const operationType = ref("add");
const currentRow = ref({});
const { proxy } = getCurrentInstance();
const userStore = useUserStore();
const bankSetting = ref({});
const bankDialogVisible = ref(false);
const bankDiaRef = ref(null);
@@ -378,8 +384,8 @@
const handleExport = () => {
  proxy.download(
    "/compensationPerformance/export",
    { ...searchForm.value, current: page.current, size: page.size },
    "/staffSalaryMain/export",
    { ...searchForm.value },
    "工资表.xlsx"
  );
};
@@ -404,4 +410,4 @@
.table_list {
  margin-top: 20px;
}
</style>
</style>