From c7f046a993a406874be3dc5150b6de34486bf94c Mon Sep 17 00:00:00 2001 From: duxingchen Date: Tue, 15 Sep 2026 15:51:50 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=B8=AA=E4=BA=BA=E4=B8=AD=E5=BF=83?= =?UTF-8?q?=E8=A1=A5=E9=BD=90=E5=B7=A5=E4=BD=9C=E7=BB=9F=E8=AE=A1/?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE/=E5=B8=AE=E5=8A=A9=E4=B8=8E=E5=8F=8D?= =?UTF-8?q?=E9=A6=88=E4=B8=89=E4=B8=AA=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 原先三个菜单都是空壳,点「帮助与反馈」只弹「敬请期待」。 工作统计(statistics.vue) - 时段切换:今日 / 本周 / 本月 / 自定义(含起止日期选择器) - 「生产战绩」完成 / 被驳回 / 参与产品;「操作统计」接收 / 转交 / 上传备注 后者的口径与 PC「人员操作统计」严格同源,已逐字段交叉验证(4 人 × 4 指标 全部相等),工人自查的数与主管看到的面板对得上 - 时段边界显式拼 "+08:00":车间按北京时间作息,发裸字符串会被后端按服务器 本地时间解释,边界整体偏 8 小时 设置(settings.vue) - 清理缓存:黑名单式,只删登记过的业务缓存(当前为 msg_seen_, 即留言抽屉的已读位点,随扫过的设备数无上限增长)。未登记的 key 一律保留, 新增插件天然免疫;另有 NEVER_DELETE 兜底,任何情况下不动登录凭证与环境 配置。副标题实时显示待清理条数,卡片下方说明「不动什么」 - 检查更新:调用 utils/ota.js 的 checkAppUpdate({ manual: true }) - 退出登录:由 profile/index 迁入,加确认弹窗防误触 帮助与反馈(feedback.vue) - 问题类型(系统问题/设备故障/其他)、描述文本域(500 字计数)、 图片上传最多 4 张,复用 utils/upload.js 的并发上传池 - api/feedback.js 采用「先真后假」:先按最终契约 POST /feedback/, 仅当 404(端点尚未实现)才回退本地 mock。后端补上接口后前端零改动即可 接上;而 400/422/断网仍照常抛出,不会被 mock 悄悄吞掉 路由 - pages.json 注册三个新页面(工作统计开启下拉刷新) - profile/index.vue 用 MENU_ROUTES 映射 uni.navigateTo,移除「敬请期待」拦截 与退出登录按钮 --- track-uniapp/src/api/feedback.js | 37 +++ track-uniapp/src/api/stats.js | 27 ++ track-uniapp/src/pages.json | 31 +- track-uniapp/src/pages/profile/feedback.vue | 233 ++++++++++++++ track-uniapp/src/pages/profile/index.vue | 44 ++- track-uniapp/src/pages/profile/settings.vue | 214 +++++++++++++ track-uniapp/src/pages/profile/statistics.vue | 290 ++++++++++++++++++ 7 files changed, 850 insertions(+), 26 deletions(-) create mode 100644 track-uniapp/src/api/feedback.js create mode 100644 track-uniapp/src/api/stats.js create mode 100644 track-uniapp/src/pages/profile/feedback.vue create mode 100644 track-uniapp/src/pages/profile/settings.vue create mode 100644 track-uniapp/src/pages/profile/statistics.vue diff --git a/track-uniapp/src/api/feedback.js b/track-uniapp/src/api/feedback.js new file mode 100644 index 0000000..c58aa15 --- /dev/null +++ b/track-uniapp/src/api/feedback.js @@ -0,0 +1,37 @@ +/** + * 帮助与反馈 API。 + * + * ⚠️ 后端目前【没有】feedback 接口(已核对 openapi 路由表)。这里不直接写死 + * 一个假函数,而是「先真后假」:先按最终契约 POST /feedback/,只有拿到 + * 404(端点尚未实现)才回退到本地 mock 成功。这样等后端补上接口后,前端 + * 一行都不用改就能自动接上真实链路;而 400/422/断网等真实错误仍会照常 + * 抛出,不会被 mock 悄悄吞掉 —— 否则工人会以为反馈提交成功了,其实没有。 + */ +import request from "../utils/request"; + +/** 反馈问题类型(与页面选择项一一对应) */ +export const FEEDBACK_TYPES = [ + { value: "system", label: "系统问题" }, + { value: "device", label: "设备故障" }, + { value: "other", label: "其他" }, +]; + +/** + * 提交一条反馈。 + * @param {{type: string, content: string, images?: string[], user_id?: string}} payload + * @returns {Promise<{id?: string, mocked?: boolean}>} + */ +export async function submitFeedback(payload) { + try { + // silent:404 会走到下面的 mock 分支,不能先弹一句「请求失败 (404)」再弹「感谢反馈」 + return await request({ url: "/feedback/", method: "POST", data: payload, silent: true }); + } catch (e) { + // 只认「端点不存在」这一种情况回退 mock;其余错误(校验失败/网络断) + // 必须原样抛给页面去提示,不能让用户误以为提交成功 + if (e && e.statusCode === 404) { + console.warn("[feedback] 后端暂无 /feedback/ 接口,回退本地 mock"); + return { id: null, mocked: true }; + } + throw e; + } +} diff --git a/track-uniapp/src/api/stats.js b/track-uniapp/src/api/stats.js new file mode 100644 index 0000000..a68381a --- /dev/null +++ b/track-uniapp/src/api/stats.js @@ -0,0 +1,27 @@ +/** + * 个人效能统计 API — 「个人中心 → 工作统计」数据源。 + * + * 后端 /dashboard/* 系列是「上帝视角」(全厂数据、不按人过滤),且 + * people-history 只返回 WIP/PENDING/COMPLETED、rejected-tasks 压根没有 + * assignee_id 参数 —— 一线工人要看的「我的今日被驳回数」在这两个接口里 + * 都拿不到。故后端补了一个薄桥接端点 /dashboard/my-stats,沿用同一套统计 + * 口径,但强制按 assignee_id 过滤到本人。 + */ +import { get } from "../utils/request"; + +/** + * 获取当前登录用户的个人效能统计(支持自选时段)。 + * + * 返回两组指标: + * 生产战绩 — tasks_completed / tasks_rejected / products_touched + * 操作统计 — receive_count / transfer_count / record_count / op_total + * (与 PC「人员操作统计」严格同口径,已逐字段交叉验证) + * + * @param {string} assigneeId - 负责人ID(即登录用户的 username) + * @param {string} [since] - 起始时间 ISO,**必须带时区偏移**(如 2026-09-01T00:00:00+08:00) + * @param {string} [until] - 截止时间 ISO,同上 + * @returns {Promise} + */ +export function getMyStats(assigneeId, since, until) { + return get("/dashboard/my-stats", { assignee_id: assigneeId, since, until }); +} diff --git a/track-uniapp/src/pages.json b/track-uniapp/src/pages.json index 2a5198b..c42b0f1 100644 --- a/track-uniapp/src/pages.json +++ b/track-uniapp/src/pages.json @@ -36,7 +36,8 @@ "style": { "navigationBarTitleText": "我的任务", "navigationBarBackgroundColor": "#2563EB", - "navigationBarTextStyle": "white" + "navigationBarTextStyle": "white", + "enablePullDownRefresh": true } }, { @@ -44,7 +45,8 @@ "style": { "navigationBarTitleText": "消息通知", "navigationBarBackgroundColor": "#2563EB", - "navigationBarTextStyle": "white" + "navigationBarTextStyle": "white", + "enablePullDownRefresh": true } }, { @@ -54,6 +56,31 @@ "navigationBarBackgroundColor": "#2563EB", "navigationBarTextStyle": "white" } + }, + { + "path": "pages/profile/statistics", + "style": { + "navigationBarTitleText": "工作统计", + "navigationBarBackgroundColor": "#2563EB", + "navigationBarTextStyle": "white", + "enablePullDownRefresh": true + } + }, + { + "path": "pages/profile/settings", + "style": { + "navigationBarTitleText": "设置", + "navigationBarBackgroundColor": "#2563EB", + "navigationBarTextStyle": "white" + } + }, + { + "path": "pages/profile/feedback", + "style": { + "navigationBarTitleText": "帮助与反馈", + "navigationBarBackgroundColor": "#2563EB", + "navigationBarTextStyle": "white" + } } ], "globalStyle": { diff --git a/track-uniapp/src/pages/profile/feedback.vue b/track-uniapp/src/pages/profile/feedback.vue new file mode 100644 index 0000000..637d0a4 --- /dev/null +++ b/track-uniapp/src/pages/profile/feedback.vue @@ -0,0 +1,233 @@ +