feat(hrm/meal&employee): 新增员工吃辣偏好字段与就餐统计矩阵
1. 在员工入职/信息页面新增是否吃辣单选表单字段 2. 重构就餐统计模块,替换原有简单统计为吃辣/不吃辣 × 堂食/打包 × 有效/无效的三维交叉统计矩阵 3. 新增员工吃辣偏好映射接口,自动获取员工饮食偏好进行分类统计
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<div style="display: flex; align-items: center; margin-bottom: 12px;">
|
||||
<el-select v-model="selectedValue" placeholder="请选择合同" style="width: 100%">
|
||||
<div style="display: flex; align-items: center; margin-bottom: 0px;">
|
||||
<el-select v-model="selectedValue" placeholder="请选择合同" style="width: 100%" clearable>
|
||||
<el-option v-for="item in contractList" :key="item.orderId" :value="item.orderId"
|
||||
:label="item.contractCode" />
|
||||
</el-select>
|
||||
|
||||
@@ -158,11 +158,11 @@
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-dialog title="完成退火" :visible.sync="completeOpen" width="720px" append-to-body>
|
||||
<el-dialog title="完成退火" :visible.sync="completeOpen" width="800px" append-to-body>
|
||||
<div class="complete-tip">请为每条钢卷分配逻辑库区去向和关联合同,未分配将无法完成。</div>
|
||||
<el-table :data="completeCoils" v-loading="completeLoading" height="360px">
|
||||
<el-table-column label="入场钢卷号" prop="enterCoilNo" align="center" />
|
||||
<el-table-column label="钢卷去向" align="center" width="240">
|
||||
<el-table-column label="钢卷去向" align="center" width="270">
|
||||
<template slot-scope="scope">
|
||||
<el-select v-model="scope.row.warehouseId" @change="handlePLanCoilChange(scope.row)">
|
||||
<el-option v-for="item in warehouseList" :key="item.warehouseId" :label="item.warehouseName"
|
||||
@@ -170,9 +170,11 @@
|
||||
</el-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="关联合同" align="center" width="240">
|
||||
<el-table-column label="关联合同" align="center" width="270">
|
||||
<template slot-scope="scope">
|
||||
<ContractSelect v-model="scope.row.contractId" placeholder="请选择合同" />
|
||||
<div style="width: 100%; display: flex; align-items: center;">
|
||||
<ContractSelect v-model="scope.row.contractId" placeholder="请选择合同" />
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
@@ -160,6 +160,14 @@
|
||||
<el-input v-model="form.phone" placeholder="请输入联系电话" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="是否吃辣" prop="isSpicyEater">
|
||||
<el-radio-group v-model="form.isSpicyEater" size="small">
|
||||
<el-radio :label="1">是</el-radio>
|
||||
<el-radio :label="0">否</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="家庭住址" prop="homeAddress">
|
||||
<el-input v-model="form.homeAddress" placeholder="请输入家庭住址" />
|
||||
@@ -404,6 +412,7 @@ export default {
|
||||
homeAddress: undefined,
|
||||
phone: undefined,
|
||||
entryTime: undefined,
|
||||
isSpicyEater: undefined,
|
||||
emergencyContact: undefined,
|
||||
relationship: undefined,
|
||||
emergencyContactPhone: undefined,
|
||||
|
||||
@@ -216,6 +216,14 @@
|
||||
<el-input v-model="form.phone" placeholder="请输入联系电话" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="是否吃辣" prop="isSpicyEater">
|
||||
<el-radio-group v-model="form.isSpicyEater" size="small">
|
||||
<el-radio :label="1">是</el-radio>
|
||||
<el-radio :label="0">否</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="家庭住址" prop="homeAddress">
|
||||
<el-input v-model="form.homeAddress" placeholder="请输入家庭住址" />
|
||||
@@ -432,6 +440,7 @@ export default {
|
||||
homeAddress: undefined,
|
||||
phone: undefined,
|
||||
entryTime: undefined,
|
||||
isSpicyEater: undefined,
|
||||
emergencyContact: undefined,
|
||||
relationship: undefined,
|
||||
emergencyContactPhone: undefined,
|
||||
|
||||
@@ -65,18 +65,44 @@
|
||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
|
||||
<!-- 修改:统计组件扩展为6列,展示有效/无效的6项统计 -->
|
||||
<el-descriptions size="small" border class="mb8" :column="3">
|
||||
<el-descriptions-item label="堂食人数">{{ validDineIn + invalidDineIn }}</el-descriptions-item>
|
||||
<el-descriptions-item label="打包人数">{{ validTakeout + invalidTakeout }}</el-descriptions-item>
|
||||
<el-descriptions-item label="总人数">{{ validTotal + invalidTotal }}</el-descriptions-item>
|
||||
<el-descriptions-item label="有效堂食人数">{{ validDineIn }}</el-descriptions-item>
|
||||
<el-descriptions-item label="有效打包人数">{{ validTakeout }}</el-descriptions-item>
|
||||
<el-descriptions-item label="有效总人数">{{ validTotal }}</el-descriptions-item>
|
||||
<el-descriptions-item label="无效堂食人数">{{ invalidDineIn }}</el-descriptions-item>
|
||||
<el-descriptions-item label="无效打包人数">{{ invalidTakeout }}</el-descriptions-item>
|
||||
<el-descriptions-item label="无效总人数">{{ invalidTotal }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<!-- 三维交叉统计矩阵表 -->
|
||||
<div class="stats-matrix mb8">
|
||||
<table class="matrix-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th rowspan="2" class="label-col"></th>
|
||||
<th colspan="3" class="group-header group-valid">有效</th>
|
||||
<th colspan="3" class="group-header group-invalid">无效</th>
|
||||
<th colspan="3" class="group-header group-all">合计</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>堂食</th><th>打包</th><th>小计</th>
|
||||
<th>堂食</th><th>打包</th><th>小计</th>
|
||||
<th>堂食</th><th>打包</th><th>小计</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="label-col">吃辣</td>
|
||||
<td>{{ matrix.spicy.validDine }}</td><td>{{ matrix.spicy.validTake }}</td><td class="subtotal">{{ matrix.spicy.validTotal }}</td>
|
||||
<td>{{ matrix.spicy.invalidDine }}</td><td>{{ matrix.spicy.invalidTake }}</td><td class="subtotal">{{ matrix.spicy.invalidTotal }}</td>
|
||||
<td>{{ matrix.spicy.dine }}</td><td>{{ matrix.spicy.take }}</td><td class="subtotal">{{ matrix.spicy.total }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label-col">不吃辣</td>
|
||||
<td>{{ matrix.nonSpicy.validDine }}</td><td>{{ matrix.nonSpicy.validTake }}</td><td class="subtotal">{{ matrix.nonSpicy.validTotal }}</td>
|
||||
<td>{{ matrix.nonSpicy.invalidDine }}</td><td>{{ matrix.nonSpicy.invalidTake }}</td><td class="subtotal">{{ matrix.nonSpicy.invalidTotal }}</td>
|
||||
<td>{{ matrix.nonSpicy.dine }}</td><td>{{ matrix.nonSpicy.take }}</td><td class="subtotal">{{ matrix.nonSpicy.total }}</td>
|
||||
</tr>
|
||||
<tr class="total-row">
|
||||
<td class="label-col">合计</td>
|
||||
<td>{{ matrix.all.validDine }}</td><td>{{ matrix.all.validTake }}</td><td class="subtotal">{{ matrix.all.validTotal }}</td>
|
||||
<td>{{ matrix.all.invalidDine }}</td><td>{{ matrix.all.invalidTake }}</td><td class="subtotal">{{ matrix.all.invalidTotal }}</td>
|
||||
<td>{{ matrix.all.dine }}</td><td>{{ matrix.all.take }}</td><td class="subtotal">{{ matrix.all.total }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- 修改:添加行样式判断,为无效报餐行加背景色 -->
|
||||
<el-table
|
||||
@@ -196,6 +222,7 @@
|
||||
|
||||
<script>
|
||||
import { listMealReport, getMealReport, delMealReport, addMealReport, updateMealReport } from "@/api/wms/mealReport";
|
||||
import { listEmployeeInfo } from "@/api/wms/employeeInfo";
|
||||
import DictSelect from "@/components/DictSelect";
|
||||
import EmployeeSelector from "@/components/EmployeeSelector";
|
||||
import { listDept } from "@/api/wms/dept"
|
||||
@@ -254,13 +281,13 @@ export default {
|
||||
updateTime: undefined,
|
||||
remark: undefined
|
||||
},
|
||||
// 替换原有统计变量,新增6个有效/无效统计项
|
||||
validDineIn: 0, // 有效堂食人数
|
||||
validTakeout: 0, // 有效打包人数
|
||||
validTotal: 0, // 有效总人数
|
||||
invalidDineIn: 0, // 无效堂食人数
|
||||
invalidTakeout: 0, // 无效打包人数
|
||||
invalidTotal: 0, // 无效总人数
|
||||
// 三维交叉统计矩阵
|
||||
matrix: {
|
||||
spicy: { validDine: 0, validTake: 0, validTotal: 0, invalidDine: 0, invalidTake: 0, invalidTotal: 0, dine: 0, take: 0, total: 0 },
|
||||
nonSpicy: { validDine: 0, validTake: 0, validTotal: 0, invalidDine: 0, invalidTake: 0, invalidTotal: 0, dine: 0, take: 0, total: 0 },
|
||||
all: { validDine: 0, validTake: 0, validTotal: 0, invalidDine: 0, invalidTake: 0, invalidTotal: 0, dine: 0, take: 0, total: 0 }
|
||||
},
|
||||
employeeSpicyMap: {},
|
||||
// 表单校验规则
|
||||
rules: {
|
||||
reportDate: [{ required: true, message: '用餐日期不能为空', trigger: 'change' }],
|
||||
@@ -278,6 +305,7 @@ export default {
|
||||
this.getList();
|
||||
this.getDeptList();
|
||||
this.getDeadlineConfig();
|
||||
this.buildEmployeeMap();
|
||||
},
|
||||
watch: {
|
||||
'form.dineInPeople': {
|
||||
@@ -324,37 +352,78 @@ export default {
|
||||
this.form.takeoutPeople = val?.length || 0;
|
||||
this.calcTotalPeople();
|
||||
},
|
||||
/** 核心修改:区分有效/无效统计 */
|
||||
/** 构建员工吃辣偏好映射(name -> isSpicyEater) */
|
||||
buildEmployeeMap() {
|
||||
listEmployeeInfo({ pageNum: 1, pageSize: 9999 }).then(response => {
|
||||
const map = {};
|
||||
(response.rows || []).forEach(emp => {
|
||||
if (emp.name && emp.isLeave !== 1 && emp.isSpicyEater !== undefined && emp.isSpicyEater !== null) {
|
||||
map[emp.name] = emp.isSpicyEater == 1 ? 1 : 0;
|
||||
}
|
||||
});
|
||||
this.employeeSpicyMap = map;
|
||||
this.calcTableSum();
|
||||
});
|
||||
},
|
||||
/** 根据人员名单统计不吃辣人数 */
|
||||
countNonSpicy(nameList) {
|
||||
if (!nameList) return 0;
|
||||
const names = nameList.split(',').map(n => n.trim()).filter(n => n);
|
||||
let count = 0;
|
||||
const counted = {};
|
||||
names.forEach(name => {
|
||||
if (!counted[name] && this.employeeSpicyMap[name] === 0) {
|
||||
count++;
|
||||
counted[name] = true;
|
||||
}
|
||||
});
|
||||
return count;
|
||||
},
|
||||
/** 三维交叉统计:吃辣/不吃辣 × 堂食/打包 × 有效/无效 */
|
||||
calcTableSum(){
|
||||
// 初始化统计变量
|
||||
let validDine = 0, validTake = 0, validAll = 0;
|
||||
let invalidDine = 0, invalidTake = 0, invalidAll = 0;
|
||||
const m = {
|
||||
spicy: { validDine: 0, validTake: 0, validTotal: 0, invalidDine: 0, invalidTake: 0, invalidTotal: 0, dine: 0, take: 0, total: 0 },
|
||||
nonSpicy: { validDine: 0, validTake: 0, validTotal: 0, invalidDine: 0, invalidTake: 0, invalidTotal: 0, dine: 0, take: 0, total: 0 },
|
||||
all: { validDine: 0, validTake: 0, validTotal: 0, invalidDine: 0, invalidTake: 0, invalidTotal: 0, dine: 0, take: 0, total: 0 }
|
||||
};
|
||||
|
||||
this.mealReportList.forEach(item => {
|
||||
// 处理空值,转为数字
|
||||
const dine = item.dineInPeople ? Number(item.dineInPeople) : 0;
|
||||
const take = item.takeoutPeople ? Number(item.takeoutPeople) : 0;
|
||||
const total = item.totalPeople ? Number(item.totalPeople) : 0;
|
||||
|
||||
// 判断当前报餐是否有效
|
||||
if (this.isValidMealReport(item.createTime)) {
|
||||
validDine += dine;
|
||||
validTake += take;
|
||||
validAll += total;
|
||||
} else {
|
||||
invalidDine += dine;
|
||||
invalidTake += take;
|
||||
invalidAll += total;
|
||||
}
|
||||
const nonSpicyDine = this.countNonSpicy(item.dineInPeopleList);
|
||||
const nonSpicyTake = this.countNonSpicy(item.takeoutPeopleList);
|
||||
const spicyDine = dine - nonSpicyDine;
|
||||
const spicyTake = take - nonSpicyTake;
|
||||
const nonSpicyTotal = nonSpicyDine + nonSpicyTake;
|
||||
const spicyTotal = spicyDine + spicyTake;
|
||||
|
||||
const v = this.isValidMealReport(item.createTime) ? 'valid' : 'invalid';
|
||||
|
||||
m.spicy[v + 'Dine'] += spicyDine;
|
||||
m.spicy[v + 'Take'] += spicyTake;
|
||||
m.spicy[v + 'Total'] += spicyTotal;
|
||||
m.spicy.dine += spicyDine;
|
||||
m.spicy.take += spicyTake;
|
||||
m.spicy.total += spicyTotal;
|
||||
|
||||
m.nonSpicy[v + 'Dine'] += nonSpicyDine;
|
||||
m.nonSpicy[v + 'Take'] += nonSpicyTake;
|
||||
m.nonSpicy[v + 'Total'] += nonSpicyTotal;
|
||||
m.nonSpicy.dine += nonSpicyDine;
|
||||
m.nonSpicy.take += nonSpicyTake;
|
||||
m.nonSpicy.total += nonSpicyTotal;
|
||||
|
||||
m.all[v + 'Dine'] += dine;
|
||||
m.all[v + 'Take'] += take;
|
||||
m.all[v + 'Total'] += total;
|
||||
m.all.dine += dine;
|
||||
m.all.take += take;
|
||||
m.all.total += total;
|
||||
});
|
||||
|
||||
// 赋值到统计变量
|
||||
this.validDineIn = validDine;
|
||||
this.validTakeout = validTake;
|
||||
this.validTotal = validAll;
|
||||
this.invalidDineIn = invalidDine;
|
||||
this.invalidTakeout = invalidTake;
|
||||
this.invalidTotal = invalidAll;
|
||||
this.matrix = m;
|
||||
},
|
||||
/** 新增:判断报餐是否有效(仅比较时分秒) */
|
||||
isValidMealReport(createTime) {
|
||||
@@ -504,12 +573,69 @@ export default {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 新增:无效报餐行样式 */
|
||||
/* 无效报餐行样式 */
|
||||
.invalid-meal-row {
|
||||
background-color: #fff0f0 !important; /* 浅红色背景,可根据需求调整 */
|
||||
background-color: #fff0f0 !important;
|
||||
}
|
||||
/* 优化表格行hover样式 */
|
||||
::v-deep .el-table .invalid-meal-row:hover>td {
|
||||
background-color: #ffe0e0 !important;
|
||||
}
|
||||
|
||||
/* 三维交叉统计矩阵表 */
|
||||
.matrix-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: 13px;
|
||||
border: 1px solid #EBEEF5;
|
||||
}
|
||||
.matrix-table th,
|
||||
.matrix-table td {
|
||||
padding: 8px 6px;
|
||||
text-align: center;
|
||||
border: 1px solid #EBEEF5;
|
||||
min-width: 52px;
|
||||
}
|
||||
.matrix-table th {
|
||||
background-color: #F5F7FA;
|
||||
color: #909399;
|
||||
font-weight: 500;
|
||||
}
|
||||
.matrix-table .label-col {
|
||||
background-color: #F5F7FA;
|
||||
color: #909399;
|
||||
font-weight: 500;
|
||||
text-align: center;
|
||||
min-width: 60px;
|
||||
}
|
||||
.matrix-table .group-header {
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
}
|
||||
.matrix-table .group-valid {
|
||||
background-color: #F0F9EB;
|
||||
color: #67C23A;
|
||||
}
|
||||
.matrix-table .group-invalid {
|
||||
background-color: #FEF0F0;
|
||||
color: #F56C6C;
|
||||
}
|
||||
.matrix-table .group-all {
|
||||
background-color: #ECF5FF;
|
||||
color: #409EFF;
|
||||
}
|
||||
.matrix-table .subtotal {
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
background-color: #FAFAFA;
|
||||
}
|
||||
.matrix-table .total-row td {
|
||||
font-weight: 700;
|
||||
border-top: 2px solid #DCDFE6;
|
||||
}
|
||||
.matrix-table .total-row .label-col {
|
||||
font-weight: 700;
|
||||
}
|
||||
.matrix-table .total-row .subtotal {
|
||||
font-weight: 700;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user