diff --git a/apps/hand-factory/api/wms/employeeInfo.js b/apps/hand-factory/api/wms/employeeInfo.js
new file mode 100644
index 0000000..ba694c6
--- /dev/null
+++ b/apps/hand-factory/api/wms/employeeInfo.js
@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 查询员工信息列表
+export function listEmployeeInfo(query) {
+ return request({
+ url: '/wms/employeeInfo/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询员工信息详细
+export function getEmployeeInfo(infoId) {
+ return request({
+ url: '/wms/employeeInfo/' + infoId,
+ method: 'get'
+ })
+}
+
+// 新增员工信息
+export function addEmployeeInfo(data) {
+ return request({
+ url: '/wms/employeeInfo',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改员工信息
+export function updateEmployeeInfo(data) {
+ return request({
+ url: '/wms/employeeInfo',
+ method: 'put',
+ data: data
+ })
+}
+
+// 删除员工信息
+export function delEmployeeInfo(infoId) {
+ return request({
+ url: '/wms/employeeInfo/' + infoId,
+ method: 'delete'
+ })
+}
diff --git a/apps/hand-factory/config.js b/apps/hand-factory/config.js
index 90812a9..b198d01 100644
--- a/apps/hand-factory/config.js
+++ b/apps/hand-factory/config.js
@@ -9,7 +9,7 @@ module.exports = {
// 应用名称
name: "ruoyi-app",
// 应用版本
- version: "1.3.34",
+ version: "1.3.37",
// 应用logo
logo: "/static/logo.jpg",
// 官方网站
diff --git a/apps/hand-factory/manifest.json b/apps/hand-factory/manifest.json
index 8327ca4..4584875 100644
--- a/apps/hand-factory/manifest.json
+++ b/apps/hand-factory/manifest.json
@@ -15,7 +15,18 @@
"delay" : 0
},
"modules" : {
- "Barcode" : {}
+ "Barcode" : {},
+ "Contacts" : {},
+ "Bluetooth" : {},
+ "FaceID" : {},
+ "Fingerprint" : {},
+ "Geolocation" : {},
+ "Record" : {},
+ "Camera" : {},
+ "iBeacon" : {},
+ "LivePusher" : {},
+ "Messaging" : {},
+ "VideoPlayer" : {}
},
"distribute" : {
"android" : {
@@ -41,7 +52,13 @@
"ios" : {
"dSYMs" : false
},
- "sdkConfigs" : {},
+ "sdkConfigs" : {
+ "geolocation" : {
+ "system" : {
+ "__platform__" : [ "android" ]
+ }
+ }
+ },
"icons" : {
"android" : {
"hdpi" : "unpackage/res/icons/72x72.png",
diff --git a/apps/hand-factory/pages/meal/meal.vue b/apps/hand-factory/pages/meal/meal.vue
index 415e558..5d68947 100644
--- a/apps/hand-factory/pages/meal/meal.vue
+++ b/apps/hand-factory/pages/meal/meal.vue
@@ -23,51 +23,93 @@
-
+
+
+ ✅ 有效报餐
+
+
+
+
+
+
+
+
+ 🌶 吃辣
+ {{ ms.validDine }}
+ {{ ms.validTake }}
+ {{ ms.validTotal }}
+
+
+ 🌿 不吃辣
+ {{ mn.validDine }}
+ {{ mn.validTake }}
+ {{ mn.validTotal }}
+
+
+ 小计
+ {{ ma.validDine }}
+ {{ ma.validTake }}
+ {{ ma.validTotal }}
+
+
+
+
+
+ ❌ 无效报餐
+
+
+
+
+
+
+
+
+ 🌶 吃辣
+ {{ ms.invalidDine }}
+ {{ ms.invalidTake }}
+ {{ ms.invalidTotal }}
+
+
+ 🌿 不吃辣
+ {{ mn.invalidDine }}
+ {{ mn.invalidTake }}
+ {{ mn.invalidTotal }}
+
+
+ 小计
+ {{ ma.invalidDine }}
+ {{ ma.invalidTake }}
+ {{ ma.invalidTotal }}
+
+
+
+
- 报餐人数统计
-
-
-
- 堂食人数
- {{ validDineIn + invalidDineIn }}
-
-
- 打包人数
- {{ validTakeout + invalidTakeout }}
-
-
- 总人数
- {{ validTotal + invalidTotal }}
-
+ 📊 总计
+
+
+
+
+
+
-
-
- 有效堂食人数
- {{ validDineIn }}
-
-
- 有效打包人数
- {{ validTakeout }}
-
-
- 有效总人数
- {{ validTotal }}
-
+
+ 🌶 吃辣
+ {{ ms.dine }}
+ {{ ms.take }}
+ {{ ms.total }}
-
-
- 无效堂食人数
- {{ invalidDineIn }}
-
-
- 无效打包人数
- {{ invalidTakeout }}
-
-
- 无效总人数
- {{ invalidTotal }}
-
+
+ 🌿 不吃辣
+ {{ mn.dine }}
+ {{ mn.take }}
+ {{ mn.total }}
+
+
+ 小计
+ {{ ma.dine }}
+ {{ ma.take }}
+ {{ ma.total }}
@@ -115,6 +157,9 @@
import {
listMealReport
} from "@/api/wms/mealReport";
+ import {
+ listEmployeeInfo
+ } from "@/api/wms/employeeInfo";
import {
getDicts
} from '@/api/system/dict/data.js'
@@ -127,13 +172,17 @@
data() {
return {
queryParams: {
- mealType: '',
+ mealType: undefined,
reportDate: '',
+ deptName: undefined,
+ reportUserName: undefined,
+ status: undefined,
+ deadlineTime: '16:00:00',
pageSize: 9999,
pageNum: 1
},
- deadlineDate: '', // 截止日期
- deadlineTime: '12:00:00', // 截止时间(原始值)
+ deadlineDate: '',
+ deadlineTime: '16:00:00', // 截止时间(原始值)
// 时分秒选择器临时变量
timeSelect: {
hour: 12,
@@ -141,14 +190,14 @@
second: 0
},
list: [],
+ employeeSpicyMap: {}, // name -> isSpicyEater (1吃辣/0不吃辣)
loading: false,
- // 统计数据
- 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 }
+ },
range: []
}
},
@@ -157,7 +206,11 @@
formattedDeadlineTime() {
const [hour, minute, second] = this.deadlineTime.split(':');
return `${hour.padStart(2, '0')}:${minute.padStart(2, '0')}:${second.padStart(2, '0')}`;
- }
+ },
+ // 从 matrix 对象中提取快捷访问属性(保持模板简洁)
+ ms() { return this.matrix.spicy; },
+ mn() { return this.matrix.nonSpicy; },
+ ma() { return this.matrix.all; }
},
onLoad() {
// 初始化今日日期
@@ -166,6 +219,8 @@
this.deadlineDate = this.queryParams.reportDate;
// 获取餐别字典数据
this.getRangeData();
+ // 加载员工信息(含吃辣偏好)
+ this.getEmployeeList();
// 加载报餐数据
this.getList();
this.getDeadlineConfig();
@@ -182,7 +237,9 @@
getDeadlineConfig() {
getConfigKey('hrm.meal.deadline').then(response => {
- this.queryParams.deadlineTime = response.msg || '16:00:00'
+ const time = response.msg || '16:00:00';
+ this.queryParams.deadlineTime = time;
+ this.deadlineTime = time;
})
},
@@ -196,6 +253,94 @@
});
},
+ /** 构建员工吃辣偏好映射(name -> isSpicyEater) */
+ getEmployeeList() {
+ listEmployeeInfo({ pageSize: 9999, pageNum: 1 }).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;
+ if (this.list.length > 0) {
+ this.calcTableSum();
+ }
+ }).catch(err => {
+ console.error('获取员工信息失败:', err);
+ });
+ },
+
+ /** 从逗号分隔的姓名列表中统计不吃辣人数 */
+ 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() {
+ 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.list.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;
+
+ // 从姓名列表统计不吃辣人数
+ 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.matrix = m;
+ console.log('【移动端矩阵结果】吃辣总计:', m.spicy.total, '不吃辣总计:', m.nonSpicy.total, '合计:', m.all.total);
+ console.log('【移动端矩阵明细】吃辣:', JSON.stringify(m.spicy), '不吃辣:', JSON.stringify(m.nonSpicy));
+ },
+
/** 查询部门报餐列表 */
getList() {
this.loading = true;
@@ -209,53 +354,23 @@
});
},
- /** 核心逻辑:区分有效/无效报餐统计 */
- calcTableSum() {
- let validDine = 0,
- validTake = 0,
- validAll = 0;
- let invalidDine = 0,
- invalidTake = 0,
- invalidAll = 0;
-
- this.list.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;
- }
- });
-
- // 赋值到统计变量
- this.validDineIn = validDine;
- this.validTakeout = validTake;
- this.validTotal = validAll;
- this.invalidDineIn = invalidDine;
- this.invalidTakeout = invalidTake;
- this.invalidTotal = invalidAll;
+ /** 判断报餐是否有效:仅比较时分秒(参考PC端逻辑) */
+ isValidMealReport(createTime) {
+ if (!createTime || !this.queryParams.deadlineTime) return true; // 无时间默认有效
+
+ // 提取报餐时间的时分秒
+ const reportTime = new Date(createTime);
+ const reportHms = this.addZero(reportTime.getHours()) + ':' +
+ this.addZero(reportTime.getMinutes()) + ':' +
+ this.addZero(reportTime.getSeconds());
+
+ // 比较时分秒字符串(格式HH:mm:ss,可直接字符串比较)
+ return reportHms <= this.queryParams.deadlineTime;
},
- /** 判断报餐是否有效:创建时间在截止时间之前则有效 */
- isValidMealReport(createTime) {
- if (!createTime) return false;
-
- // 拼接完整的截止时间字符串
- const deadlineDateTime = `${this.deadlineDate || this.queryParams.reportDate} ${this.deadlineTime}`;
- // 比较时间
- const createTimeObj = new Date(createTime);
- const deadlineTimeObj = new Date(deadlineDateTime);
-
- return createTimeObj <= deadlineTimeObj;
+ /** 数字补零 */
+ addZero(num) {
+ return num < 10 ? '0' + num : num;
},
/** 报餐日期选择确认 */
@@ -307,8 +422,9 @@
const hour = String(this.timeSelect.hour).padStart(2, '0');
const minute = String(this.timeSelect.minute).padStart(2, '0');
const second = String(this.timeSelect.second).padStart(2, '0');
- // 更新截止时间
+ // 更新截止时间(同步到 queryParams 供有效性判断使用)
this.deadlineTime = `${hour}:${minute}:${second}`;
+ this.queryParams.deadlineTime = `${hour}:${minute}:${second}`;
// 重新计算统计数据
this.calcTableSum();
// 关闭弹窗
@@ -394,6 +510,14 @@
border-top: none;
}
+ /* 交叉表网格:4列(标签 + 堂食 + 打包 + 小计) */
+ .cross-grid {
+ display: grid;
+ grid-template-columns: 70px repeat(3, 1fr);
+ border: 1px solid #eee;
+ border-top: none;
+ }
+
/* 统计项样式 */
.stats-item {
padding: 12px 8px;
@@ -404,18 +528,54 @@
font-size: 14px;
}
- /* 去掉最后一列右边框 */
+ /* 3列网格:去掉最后一列右边框 */
.stats-grid .stats-item:nth-child(3n) {
border-right: none;
}
- /* 去掉最后一行下边框 */
+ /* 3列网格:去掉最后一行下边框 */
.stats-grid .stats-item:last-child,
.stats-grid .stats-item:nth-last-child(2),
.stats-grid .stats-item:nth-last-child(3) {
border-bottom: none;
}
+ /* 4列交叉网格:去掉最后一列右边框 */
+ .cross-grid .stats-item:nth-child(4n) {
+ border-right: none;
+ }
+
+ /* 4列交叉网格:去掉最后一行下边框(每行4个,最后4个) */
+ .cross-grid .stats-item:nth-last-child(-n+4) {
+ border-bottom: none;
+ }
+
+ /* 交叉表行标签(吃辣/不吃辣/小计) */
+ .cross-label {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 3px;
+ font-weight: 500;
+ color: #333;
+ font-size: 13px;
+ background-color: #fafafa;
+ }
+
+ /* 交叉表头(堂食/打包/小计) */
+ .cross-header {
+ font-weight: 600;
+ color: #555;
+ font-size: 12px;
+ background-color: #f5f7fa;
+ }
+
+ /* 交叉表汇总行背景 */
+ .cross-total {
+ background-color: #f9f9f9;
+ font-weight: 600;
+ }
+
/* 标签和值样式 */
.item-label {
display: block;
@@ -496,12 +656,6 @@
color: #999;
}
- .colon {
- font-size: 20px;
- color: #333;
- margin: 0 5px;
- }
-
/* 适配小屏手机 */
@media (max-width: 375px) {
.stats-item {
diff --git a/apps/hand-factory/utils/update.js b/apps/hand-factory/utils/update.js
index eb9e0aa..d60f080 100644
--- a/apps/hand-factory/utils/update.js
+++ b/apps/hand-factory/utils/update.js
@@ -73,7 +73,7 @@ function checkStorageSpace() {
function checkUpdate(forceCheck = false) {
// 1. 准备本地版本信息
const localVersion = plus.runtime.version; // 基座版本
- const staticVersion = '1.3.34'; // 静态默认版本
+ const staticVersion = '1.3.37'; // 静态默认版本
// const localWgtVersion = staticVersion;
const localWgtVersion = uni.getStorageSync('wgtVersion') || staticVersion; // 本地wgt版本(从存储获取或用默认)
const currentVersion = compareVersion(localWgtVersion, localVersion) > 0
diff --git a/apps/hand-factory/version.json b/apps/hand-factory/version.json
index 5a14ab8..d5e2c86 100644
--- a/apps/hand-factory/version.json
+++ b/apps/hand-factory/version.json
@@ -1,5 +1,5 @@
{
- "version": "klp 1.3.34",
+ "version": "klp 1.3.37",
"wgtUrl": "http://49.232.154.205:10900/fadapp-update/klp/klp.wgt",
"apkUrl": "http://49.232.154.205:10900/fadapp-update/klp/klp.apk"
}
\ No newline at end of file