review-report.html 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>绿水青山 · 移动端审查报告</title>
  7. <script src="https://cdn.tailwindcss.com"></script>
  8. <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css">
  9. <style>
  10. body {
  11. background: #e8f0ec;
  12. font-family: -apple-system, "PingFang SC", "Microsoft YaHei", sans-serif;
  13. }
  14. .glass {
  15. background: rgba(255, 255, 255, 0.9);
  16. border: 1px solid rgba(164, 216, 152, 0.4);
  17. box-shadow: 0 14px 40px -14px rgba(54, 143, 111, 0.35);
  18. }
  19. .bar-green { background: linear-gradient(180deg, #368f6f 0%, #5ab8d0 100%); }
  20. .chip-p0 { color: #dc2626; background: rgba(220,38,38,0.08); border: 1px solid rgba(220,38,38,0.25); }
  21. .chip-p1 { color: #b7791f; background: rgba(251,211,141,0.25); border: 1px solid rgba(251,211,141,0.6); }
  22. .chip-p2 { color: #2563eb; background: rgba(37,99,235,0.07); border: 1px solid rgba(37,99,235,0.25); }
  23. .severity-row + .severity-row { border-top: 1px solid rgba(164, 216, 152, 0.25); }
  24. .file-tag {
  25. font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  26. font-size: 11px;
  27. color: #368f6f;
  28. background: rgba(164, 216, 152, 0.18);
  29. border-radius: 6px;
  30. padding: 1px 6px;
  31. word-break: break-all;
  32. }
  33. .num-badge {
  34. width: 22px; height: 22px;
  35. border-radius: 8px;
  36. display: inline-flex; align-items: center; justify-content: center;
  37. color: #fff; font-size: 12px; font-weight: 700;
  38. flex-shrink: 0;
  39. }
  40. </style>
  41. </head>
  42. <body class="min-h-screen py-8 px-4">
  43. <div class="max-w-5xl mx-auto">
  44. <!-- 标题 -->
  45. <header class="text-center mb-6">
  46. <h1 class="text-2xl font-extrabold text-gray-800">绿水青山 · 移动端审查报告</h1>
  47. <p class="text-sm text-gray-500 mt-1">全量页面与逻辑盘点 · 2026-07-13 · 共 50+ 页面 / API / Store / Utils</p>
  48. </header>
  49. <!-- 概览数字 -->
  50. <div class="grid grid-cols-2 md:grid-cols-4 gap-3 mb-5">
  51. <div class="glass rounded-2xl p-4 text-center">
  52. <p class="text-2xl font-extrabold" style="color:#dc2626;">2 类</p>
  53. <p class="text-xs text-gray-500 mt-1">严重:假数据 / 假操作</p>
  54. </div>
  55. <div class="glass rounded-2xl p-4 text-center">
  56. <p class="text-2xl font-extrabold" style="color:#b7791f;">10 项</p>
  57. <p class="text-xs text-gray-500 mt-1">结构性缺陷</p>
  58. </div>
  59. <div class="glass rounded-2xl p-4 text-center">
  60. <p class="text-2xl font-extrabold" style="color:#368f6f;">3 批</p>
  61. <p class="text-xs text-gray-500 mt-1">P0 / P1 / P2 修复计划</p>
  62. </div>
  63. <div class="glass rounded-2xl p-4 text-center">
  64. <p class="text-2xl font-extrabold" style="color:#2563eb;">~2.5 天</p>
  65. <p class="text-xs text-gray-500 mt-1">预估总工作量</p>
  66. </div>
  67. </div>
  68. <!-- ============ 一、假数据 ============ -->
  69. <section class="glass rounded-3xl p-5 mb-4">
  70. <div class="flex items-center mb-4">
  71. <div class="w-9 h-9 rounded-xl flex items-center justify-center mr-2.5" style="background: rgba(220,38,38,0.1);">
  72. <i class="fa fa-exclamation-triangle" style="color:#dc2626;"></i>
  73. </div>
  74. <div>
  75. <h2 class="text-base font-bold text-gray-800">一、严重:整块假数据<span class="text-xs font-normal text-gray-400 ml-2">演示会露馅</span></h2>
  76. </div>
  77. <span class="chip-p0 ml-auto text-[11px] font-semibold px-2.5 py-1 rounded-full">P0</span>
  78. </div>
  79. <div class="severity-row py-2.5 flex items-start">
  80. <span class="num-badge mr-2.5" style="background:#dc2626;">1</span>
  81. <div class="flex-1 min-w-0">
  82. <p class="text-sm font-semibold text-gray-700">调度端发布任务是假的</p>
  83. <p class="text-xs text-gray-500 mt-0.5">项目/车辆下拉写死数组,"提交"只 toast 不调 createTask,照片未上传</p>
  84. <p class="mt-1"><span class="file-tag">pages-dispatch/publishTask.vue:173-223</span></p>
  85. </div>
  86. </div>
  87. <div class="severity-row py-2.5 flex items-start">
  88. <span class="num-badge mr-2.5" style="background:#dc2626;">2</span>
  89. <div class="flex-1 min-w-0">
  90. <p class="text-sm font-semibold text-gray-700">排班日历失效 + 新增排班未实现</p>
  91. <p class="text-xs text-gray-500 mt-0.5">日期字段用错(scheduleDate vs 后端 workDate),日历圆点全空;新增仅 toast"开发中"</p>
  92. <p class="mt-1"><span class="file-tag">pages-dispatch/schedule.vue:143-226</span></p>
  93. </div>
  94. </div>
  95. <div class="severity-row py-2.5 flex items-start">
  96. <span class="num-badge mr-2.5" style="background:#dc2626;">3</span>
  97. <div class="flex-1 min-w-0">
  98. <p class="text-sm font-semibold text-gray-700">数据看板图表写死</p>
  99. <p class="text-xs text-gray-500 mt-0.5">饼图/趋势图为固定数组,与上方真实统计数字互相矛盾</p>
  100. <p class="mt-1"><span class="file-tag">pages-dispatch/visualization.vue:145-160</span></p>
  101. </div>
  102. </div>
  103. <div class="severity-row py-2.5 flex items-start">
  104. <span class="num-badge mr-2.5" style="background:#dc2626;">4</span>
  105. <div class="flex-1 min-w-0">
  106. <p class="text-sm font-semibold text-gray-700">车辆 / 人员 / 应急待命全走 mock</p>
  107. <p class="text-xs text-gray-500 mt-0.5">vehicle / personnel store 直接展开 mock 数组,loading 用 setTimeout 假装;真实接口在 api/staff.ts 已存在但没接</p>
  108. <p class="mt-1"><span class="file-tag">stores/vehicle.ts</span> <span class="file-tag">stores/personnel.ts</span> <span class="file-tag">vehicleList / availableVehicles / emergencyStandby / onDutyStaff.vue</span></p>
  109. </div>
  110. </div>
  111. <div class="severity-row py-2.5 flex items-start">
  112. <span class="num-badge mr-2.5" style="background:#dc2626;">5</span>
  113. <div class="flex-1 min-w-0">
  114. <p class="text-sm font-semibold text-gray-700">通知详情点进去必显示"公告不存在"</p>
  115. <p class="text-xs text-gray-500 mt-0.5">写死假公告,id 字符串 'n1' 与列表传入的数字不匹配;且与 pages-common 版重复</p>
  116. <p class="mt-1"><span class="file-tag">pages-dispatch/noticeDetail.vue</span> <span class="file-tag">pages-construction/noticeDetail.vue</span></p>
  117. </div>
  118. </div>
  119. <div class="severity-row py-2.5 flex items-start">
  120. <span class="num-badge mr-2.5" style="background:#dc2626;">6</span>
  121. <div class="flex-1 min-w-0">
  122. <p class="text-sm font-semibold text-gray-700">任务处理记录时间线是假数据</p>
  123. <p class="text-xs text-gray-500 mt-0.5">固定 3 条(销售-李明/调度-王调度/施工-张师傅),未调任务日志接口</p>
  124. <p class="mt-1"><span class="file-tag">pages-common/taskDetail.vue:109-131</span></p>
  125. </div>
  126. </div>
  127. <div class="severity-row py-2.5 flex items-start">
  128. <span class="num-badge mr-2.5" style="background:#dc2626;">7</span>
  129. <div class="flex-1 min-w-0">
  130. <p class="text-sm font-semibold text-gray-700">首页统计数字写死</p>
  131. <p class="text-xs text-gray-500 mt-0.5">三个 Home 的 notificationCount、tomorrowCount 为固定值;统计卡未接 dashboard 接口</p>
  132. <p class="mt-1"><span class="file-tag">SalesHome / DispatchHome / ConstructionHome.vue</span> <span class="file-tag">stores/task.ts:31</span></p>
  133. </div>
  134. </div>
  135. <div class="severity-row py-2.5 flex items-start">
  136. <span class="num-badge mr-2.5" style="background:#dc2626;">8</span>
  137. <div class="flex-1 min-w-0">
  138. <p class="text-sm font-semibold text-gray-700">销售端 6 个子页面全是写死数组</p>
  139. <p class="text-xs text-gray-500 mt-0.5">知识库 / 消息 / 任务提醒均为硬编码数据,确认/拒绝按钮只 toast 不调接口</p>
  140. <p class="mt-1"><span class="file-tag">pages-sales/*(6 个文件)</span></p>
  141. </div>
  142. </div>
  143. </section>
  144. <!-- ============ 二、假操作 ============ -->
  145. <section class="glass rounded-3xl p-5 mb-4">
  146. <div class="flex items-center mb-4">
  147. <div class="w-9 h-9 rounded-xl flex items-center justify-center mr-2.5" style="background: rgba(220,38,38,0.1);">
  148. <i class="fa fa-hand-paper-o" style="color:#dc2626;"></i>
  149. </div>
  150. <h2 class="text-base font-bold text-gray-800">二、严重:假操作<span class="text-xs font-normal text-gray-400 ml-2">点了以为成功实际没生效</span></h2>
  151. <span class="chip-p0 ml-auto text-[11px] font-semibold px-2.5 py-1 rounded-full">P0</span>
  152. </div>
  153. <div class="severity-row py-2.5 flex items-start">
  154. <span class="num-badge mr-2.5" style="background:#dc2626;">1</span>
  155. <div class="flex-1 min-w-0">
  156. <p class="text-sm font-semibold text-gray-700">修改密码完全没调接口</p>
  157. <p class="text-xs text-gray-500 mt-0.5">仅本地校验后 toast 成功;api/auth.ts 也无 changePassword 接口(需后端补)</p>
  158. <p class="mt-1"><span class="file-tag">pages-common/changePassword.vue:85</span></p>
  159. </div>
  160. </div>
  161. <div class="severity-row py-2.5 flex items-start">
  162. <span class="num-badge mr-2.5" style="background:#dc2626;">2</span>
  163. <div class="flex-1 min-w-0">
  164. <p class="text-sm font-semibold text-gray-700">应急任务列表大概率是空的</p>
  165. <p class="text-xs text-gray-500 mt-0.5">筛选字段 t.type==='emergency' 与任务实际字段(taskType/urgencyLevel)不符</p>
  166. <p class="mt-1"><span class="file-tag">pages-dispatch/emergencyTeam.vue:83</span></p>
  167. </div>
  168. </div>
  169. <div class="severity-row py-2.5 flex items-start">
  170. <span class="num-badge mr-2.5" style="background:#dc2626;">3</span>
  171. <div class="flex-1 min-w-0">
  172. <p class="text-sm font-semibold text-gray-700">施工端问题反馈只 toast 不上报</p>
  173. <p class="text-xs text-gray-500 mt-0.5">onReject 误用 updateTask 改状态,应使用已有的 cancelTask 接口</p>
  174. <p class="mt-1"><span class="file-tag">pages-construction/taskDetail.vue:591-636</span></p>
  175. </div>
  176. </div>
  177. <div class="severity-row py-2.5 flex items-start">
  178. <span class="num-badge mr-2.5" style="background:#dc2626;">4</span>
  179. <div class="flex-1 min-w-0">
  180. <p class="text-sm font-semibold text-gray-700">车辆检查只写本地 storage</p>
  181. <p class="text-xs text-gray-500 mt-0.5">出车前检查未提交后端,刷新/换设备即丢失</p>
  182. <p class="mt-1"><span class="file-tag">pages-construction/dailyTask.vue:194-221</span></p>
  183. </div>
  184. </div>
  185. <div class="severity-row py-2.5 flex items-start">
  186. <span class="num-badge mr-2.5" style="background:#dc2626;">5</span>
  187. <div class="flex-1 min-w-0">
  188. <p class="text-sm font-semibold text-gray-700">多处"标记已读 / 删除"只改本地数组</p>
  189. <p class="text-xs text-gray-500 mt-0.5">noticeList、messageList 的滑动操作未调后端接口</p>
  190. <p class="mt-1"><span class="file-tag">noticeList.vue:110</span> <span class="file-tag">messageList.vue</span></p>
  191. </div>
  192. </div>
  193. </section>
  194. <!-- ============ 三、结构性缺陷 ============ -->
  195. <section class="glass rounded-3xl p-5 mb-4">
  196. <div class="flex items-center mb-4">
  197. <div class="w-9 h-9 rounded-xl flex items-center justify-center mr-2.5" style="background: rgba(183,121,31,0.12);">
  198. <i class="fa fa-sitemap" style="color:#b7791f;"></i>
  199. </div>
  200. <h2 class="text-base font-bold text-gray-800">三、结构性缺陷</h2>
  201. <span class="chip-p1 ml-auto text-[11px] font-semibold px-2.5 py-1 rounded-full">P1 / P2</span>
  202. </div>
  203. <div class="grid grid-cols-1 md:grid-cols-2 gap-2.5 text-xs text-gray-600">
  204. <div class="rounded-2xl p-3 bg-white border border-gray-100">
  205. <p class="font-semibold text-gray-800 mb-1"><i class="fa fa-database mr-1" style="color:#b7791f;"></i>storage 传参反模式</p>
  206. knowledge / message / notice 详情页用 setStorageSync 传整对象,无 id 入参兜底,刷新/分享即空白
  207. </div>
  208. <div class="rounded-2xl p-3 bg-white border border-gray-100">
  209. <p class="font-semibold text-gray-800 mb-1"><i class="fa fa-list mr-1" style="color:#b7791f;"></i>列表无分页加载更多</p>
  210. 任务/客户/合同/通知只拉首屏 10 条;搜索筛选为前端内存过滤,数据多了就漏
  211. </div>
  212. <div class="rounded-2xl p-3 bg-white border border-gray-100">
  213. <p class="font-semibold text-gray-800 mb-1"><i class="fa fa-th-large mr-1" style="color:#b7791f;"></i>tab 索引错位</p>
  214. task.vue dispatch 端 setSelected(2)、schedule.vue setSelected(1),与 pages.json 实际索引相反,高亮错位
  215. </div>
  216. <div class="rounded-2xl p-3 bg-white border border-gray-100">
  217. <p class="font-semibold text-gray-800 mb-1"><i class="fa fa-refresh mr-1" style="color:#b7791f;"></i>返回不刷新</p>
  218. contract.vue / customer.vue 用 onMounted 而非 onShow,编辑后返回列表数据陈旧
  219. </div>
  220. <div class="rounded-2xl p-3 bg-white border border-gray-100">
  221. <p class="font-semibold text-gray-800 mb-1"><i class="fa fa-flask mr-1" style="color:#b7791f;"></i>mock 残留会崩</p>
  222. mock/index.ts 仍被 5 个 store 引用;mockProjects 用旧字段 type:'包年'(后端为 cooperationType:'annual'),切真实后端会崩
  223. </div>
  224. <div class="rounded-2xl p-3 bg-white border border-gray-100">
  225. <p class="font-semibold text-gray-800 mb-1"><i class="fa fa-shield mr-1" style="color:#b7791f;"></i>request.ts 缺陷</p>
  226. 错误 toast 无静默开关(权限 toast bug 根源);401 不清 roleInfo;无 token 刷新;BASE_URL 硬编码 localhost
  227. </div>
  228. <div class="rounded-2xl p-3 bg-white border border-gray-100">
  229. <p class="font-semibold text-gray-800 mb-1"><i class="fa fa-trash-o mr-1" style="color:#b7791f;"></i>死代码</p>
  230. dispatch/construction 下重复的 notification/noticeList/noticeDetail;stores/schedule.ts 未使用
  231. </div>
  232. <div class="rounded-2xl p-3 bg-white border border-gray-100">
  233. <p class="font-semibold text-gray-800 mb-1"><i class="fa fa-file-o mr-1" style="color:#b7791f;"></i>占位页面</p>
  234. paymentRecord / followUpList 整页空态;合同付款记录、客户关联项目为占位文案
  235. </div>
  236. <div class="rounded-2xl p-3 bg-white border border-gray-100">
  237. <p class="font-semibold text-gray-800 mb-1"><i class="fa fa-download mr-1" style="color:#b7791f;"></i>一次性拉 1000 条</p>
  238. contractForm.vue:268 拉 1000 条客户、addProject.vue:600 拉 1000 条合同,客户多时会卡
  239. </div>
  240. <div class="rounded-2xl p-3 bg-white border border-gray-100">
  241. <p class="font-semibold text-gray-800 mb-1"><i class="fa fa-tasks mr-1" style="color:#b7791f;"></i>其他零散</p>
  242. taskNo 前端用 Date.now() 生成(应后端生成);地理位置占位仅 toast;checklist 3 项与点检 12 项不一致
  243. </div>
  244. </div>
  245. </section>
  246. <!-- ============ 四、解决方案 ============ -->
  247. <section class="glass rounded-3xl p-5 mb-4">
  248. <div class="flex items-center mb-4">
  249. <div class="w-9 h-9 rounded-xl flex items-center justify-center mr-2.5" style="background: rgba(54,143,111,0.12);">
  250. <i class="fa fa-check-square-o" style="color:#368f6f;"></i>
  251. </div>
  252. <h2 class="text-base font-bold text-gray-800">四、解决方案(按优先级分批)</h2>
  253. </div>
  254. <!-- P0 -->
  255. <div class="rounded-2xl p-4 mb-3" style="background: rgba(220,38,38,0.04); border: 1px solid rgba(220,38,38,0.2);">
  256. <div class="flex items-center mb-2.5">
  257. <span class="chip-p0 text-[11px] font-bold px-2.5 py-1 rounded-full mr-2">P0</span>
  258. <span class="text-sm font-bold text-gray-800">演示前必修 — 消灭假数据 / 假操作</span>
  259. <span class="text-[11px] text-gray-400 ml-auto">约 1 ~ 1.5 天 · 前端为主 + 后端 3~4 个小接口</span>
  260. </div>
  261. <ol class="text-xs text-gray-600 space-y-1.5 pl-1">
  262. <li><b class="text-gray-700">1.</b> 调度端发布任务接真实接口:项目/车辆下拉 + createTask + 照片上传</li>
  263. <li><b class="text-gray-700">2.</b> 排班页字段修正为 workDate;新增排班接 createSchedule</li>
  264. <li><b class="text-gray-700">3.</b> 删除 noticeDetail 死代码文件(列表本就跳 pages-common 版);统一 id 数字传参</li>
  265. <li><b class="text-gray-700">4.</b> 车辆/人员/应急页面 store 接 api/vehicle.ts、api/staff.ts(接口已存在,纯前端)</li>
  266. <li><b class="text-gray-700">5.</b> 后端补缺口接口:修改密码、任务反馈、消息已读、付款/跟进记录——或演示版先隐藏入口</li>
  267. <li><b class="text-gray-700">6.</b> visualization 图表接 dashboard 接口</li>
  268. </ol>
  269. </div>
  270. <!-- P1 -->
  271. <div class="rounded-2xl p-4 mb-3" style="background: rgba(251,211,141,0.12); border: 1px solid rgba(251,211,141,0.5);">
  272. <div class="flex items-center mb-2.5">
  273. <span class="chip-p1 text-[11px] font-bold px-2.5 py-1 rounded-full mr-2">P1</span>
  274. <span class="text-sm font-bold text-gray-800">交互正确性</span>
  275. <span class="text-[11px] text-gray-400 ml-auto">约半天</span>
  276. </div>
  277. <ol class="text-xs text-gray-600 space-y-1.5 pl-1" start="7">
  278. <li><b class="text-gray-700">7.</b> tab 索引修正(task/schedule 互换);列表页统一 onShow 刷新 + 触底加载 + 搜索传后端</li>
  279. <li><b class="text-gray-700">8.</b> 详情页统一改为 onLoad(options.id) + 接口拉取,废弃 storage 传参</li>
  280. <li><b class="text-gray-700">9.</b> request.ts 加 silent 选项;401 清全 store;BASE_URL 走环境变量</li>
  281. </ol>
  282. </div>
  283. <!-- P2 -->
  284. <div class="rounded-2xl p-4" style="background: rgba(37,99,235,0.04); border: 1px solid rgba(37,99,235,0.2);">
  285. <div class="flex items-center mb-2.5">
  286. <span class="chip-p2 text-[11px] font-bold px-2.5 py-1 rounded-full mr-2">P2</span>
  287. <span class="text-sm font-bold text-gray-800">清理与规范化</span>
  288. <span class="text-[11px] text-gray-400 ml-auto">约半天</span>
  289. </div>
  290. <ol class="text-xs text-gray-600 space-y-1.5 pl-1" start="10">
  291. <li><b class="text-gray-700">10.</b> 删除 mock 引用(5 个 store)、重复子包页面、未用 store;统一类型定义(SimpleOption 重复、API 返回值无类型)</li>
  292. </ol>
  293. </div>
  294. <!-- 建议执行顺序 -->
  295. <div class="mt-4 rounded-2xl p-3 flex items-start" style="background: rgba(54,143,111,0.06); border: 1px solid rgba(164,216,152,0.4);">
  296. <i class="fa fa-lightbulb-o mr-2 mt-0.5" style="color:#368f6f;"></i>
  297. <span class="text-xs text-gray-600"><b style="color:#368f6f;">建议顺序:</b>先做 P0 的 1-4(纯前端、风险低、演示收益最大),后端缺口接口并行补;P1/P2 随后跟进。</span>
  298. </div>
  299. </section>
  300. <p class="text-center text-[10px] text-gray-400 mt-2">青道夫管道疏通管理平台 · 移动端审查报告 | 外围架构已固定,本报告聚焦内部完善项</p>
  301. </div>
  302. </body>
  303. </html>