index.vue 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639
  1. <template>
  2. <view>
  3. <uni-nav-bar fixed="true" statusBar="true" title="工作台" right-icon="scan"
  4. @clickRight="HandlScanCode"></uni-nav-bar>
  5. <!-- 顶部横向导航 -->
  6. <view class="top-nav-wrapper" v-if="moduleNavList.length > 0">
  7. <scroll-view class="top-nav" scroll-x enable-flex :scroll-into-view="scrollIntoViewId" scroll-with-animation
  8. @scroll="handleNavScroll">
  9. <view class="nav-tab" v-for="(item, index) in moduleNavList" :key="index" :id="'nav-' + item.id"
  10. :class="{ active: currentNavIndex === index }" @click="goToModule(item, index)">
  11. {{ item.name }}
  12. </view>
  13. </scroll-view>
  14. </view>
  15. <view class="content-wrapper">
  16. <view v-if="internalManagementList.length > 0" :id="'module-xietong'" :data-index="0">
  17. <CellTip title="协同办公"></CellTip>
  18. <view class="nav">
  19. <view class="nav-content">
  20. <view class="nav-item" v-for="(item, index) in internalManagementList"
  21. @click="toNav(item.path)">
  22. <MenuIcon :name="item.name || item.title"></MenuIcon>
  23. <i class="badge" v-if="item.badge">{{ item.badge }}</i>
  24. <label>{{ item.name }}</label>
  25. </view>
  26. </view>
  27. </view>
  28. </view>
  29. <view v-if="hrList.length > 0" :id="'module-renli'" :data-index="1">
  30. <CellTip title="人力资源"></CellTip>
  31. <view class="nav">
  32. <view class="nav-content">
  33. <view class="nav-item" v-for="item in hrList" :key="item.link_url"
  34. @click="toNav(item.path)">
  35. <MenuIcon :name="item.name || item.title"></MenuIcon>
  36. <i class="badge" v-if="item.badge">{{ item.badge }}</i>
  37. <label>{{ item.title }}</label>
  38. <label>{{ item.num }}</label>
  39. </view>
  40. </view>
  41. </view>
  42. </view>
  43. <view v-if="productionList.length > 0" :id="'module-shengchan'" :data-index="1">
  44. <CellTip title="生产管理"></CellTip>
  45. <view class="nav">
  46. <view class="nav-content">
  47. <view class="nav-item" v-for="item in productionList" :key="item.link_url"
  48. @click="toNav(item.path)">
  49. <MenuIcon :name="item.name || item.title"></MenuIcon>
  50. <i class="badge" v-if="item.badge">{{ item.badge }}</i>
  51. <label>{{ item.title }}</label>
  52. <label>{{ item.num }}</label>
  53. </view>
  54. </view>
  55. </view>
  56. </view>
  57. <view v-if="operationsList.length > 0" :id="'module-yunwei'" :data-index="2">
  58. <CellTip title="运维管理"></CellTip>
  59. <view class="nav">
  60. <view class="nav-content">
  61. <view class="nav-item" v-for="(item, index) in operationsList" @click="toNav(item.path)">
  62. <MenuIcon :name="item.name || item.title"></MenuIcon>
  63. <i class="badge" v-if="item.badge">{{ item.badge }}</i>
  64. <label>{{ item.name }}</label>
  65. </view>
  66. </view>
  67. </view>
  68. </view>
  69. <view v-if="serviceList.length > 0" :id="'module-shouhou'" :data-index="3">
  70. <CellTip title="售后服务管理"></CellTip>
  71. <view class="nav">
  72. <view class="nav-content">
  73. <view class="nav-item" v-for="(item, index) in serviceList" @click="toNav(item.path)">
  74. <MenuIcon :name="item.name || item.title"></MenuIcon>
  75. <i class="badge" v-if="item.badge">{{ item.badge }}</i>
  76. <label>{{ item.name }}</label>
  77. </view>
  78. </view>
  79. </view>
  80. </view>
  81. <view v-if="warehousingList.length > 0" :id="'module-cangchu'" :data-index="4">
  82. <CellTip title="仓储管理"></CellTip>
  83. <view class="nav">
  84. <view class="nav-content">
  85. <view class="nav-item" v-for="(item, index) in warehousingList" @click="toNav(item.path)">
  86. <MenuIcon :name="item.name || item.title"></MenuIcon>
  87. <i class="badge" v-if="item.badge">{{ item.badge }}</i>
  88. <label>{{ item.title }}</label>
  89. </view>
  90. </view>
  91. </view>
  92. </view>
  93. <view v-if="dispatchList.length > 0" :id="'module-yunshu'" :data-index="5">
  94. <CellTip title="运输管理"></CellTip>
  95. <view class="nav">
  96. <view class="nav-content">
  97. <view class="nav-item" v-for="(item, index) in dispatchList" @click="toNav(item.path)">
  98. <MenuIcon :name="item.name || item.title"></MenuIcon>
  99. <i class="badge" v-if="item.badge">{{ item.badge }}</i>
  100. <label>{{ item.name }}</label>
  101. </view>
  102. </view>
  103. </view>
  104. </view>
  105. <view v-if="saleManageList.length > 0" :id="'module-yingxiao'" :data-index="6">
  106. <CellTip title="营销管理"></CellTip>
  107. <view class="nav">
  108. <view class="nav-content">
  109. <view class="nav-item" v-for="(item, index) in saleManageList" @click="toNav(item.path)">
  110. <MenuIcon :name="item.name || item.title"></MenuIcon>
  111. <i class="badge" v-if="item.badge">{{ item.badge }}</i>
  112. <label>{{ item.name }}</label>
  113. </view>
  114. </view>
  115. </view>
  116. </view>
  117. <view v-if="purchaseManageList.length > 0" :id="'module-caigou'" :data-index="7">
  118. <CellTip title="采购管理"></CellTip>
  119. <view class="nav">
  120. <view class="nav-content">
  121. <view class="nav-item" v-for="(item, index) in purchaseManageList" @click="toNav(item.path)">
  122. <MenuIcon :name="item.name || item.title"></MenuIcon>
  123. <i class="badge" v-if="item.badge">{{ item.badge }}</i>
  124. <label>{{ item.name }}</label>
  125. </view>
  126. </view>
  127. </view>
  128. </view>
  129. <view v-if="pcsList.length > 0" :id="'module-shengchanguanli'" :data-index="8">
  130. <CellTip title="生产管控"></CellTip>
  131. <view class="nav">
  132. <view class="nav-content">
  133. <view class="nav-item" v-for="(item, index) in pcsList" @click="toNav(item.path)">
  134. <MenuIcon :name="item.name || item.title"></MenuIcon>
  135. <i class="badge" v-if="item.badge">{{ item.badge }}</i>
  136. <label>{{ item.name }}</label>
  137. </view>
  138. </view>
  139. </view>
  140. </view>
  141. <view v-if="qmsList.length > 0" :id="'module-zhiliang'" :data-index="9">
  142. <CellTip title="质量管理"></CellTip>
  143. <view class="nav">
  144. <view class="nav-content">
  145. <view class="nav-item" v-for="(item, index) in qmsList" @click="toNav(item.path)">
  146. <MenuIcon :name="item.name || item.title"></MenuIcon>
  147. <i class="badge" v-if="item.badge">{{ item.badge }}</i>
  148. <label>{{ item.name }}</label>
  149. </view>
  150. </view>
  151. </view>
  152. </view>
  153. <view v-if="energyManagement.length > 0" :id="'module-nengyuan'" :data-index="10">
  154. <CellTip title="能源管理"></CellTip>
  155. <view class="nav">
  156. <view class="nav-content">
  157. <view class="nav-item" v-for="(item, index) in energyManagement" @click="toNav(item.path)">
  158. <MenuIcon :name="item.name || item.title"></MenuIcon>
  159. <i class="badge" v-if="item.badge">{{ item.badge }}</i>
  160. <label>{{ item.name }}</label>
  161. </view>
  162. </view>
  163. </view>
  164. </view>
  165. <view v-if="productionSafetyManagement.length > 0" :id="'module-anquan'" :data-index="11">
  166. <CellTip title="生产安全"></CellTip>
  167. <view class="nav">
  168. <view class="nav-content">
  169. <view class="nav-item" v-for="(item, index) in productionSafetyManagement"
  170. @click="toNav(item.path)">
  171. <MenuIcon :name="item.name || item.title"></MenuIcon>
  172. <i class="badge" v-if="item.badge">{{ item.badge }}</i>
  173. <label>{{ item.name }}</label>
  174. </view>
  175. </view>
  176. </view>
  177. </view>
  178. <view v-if="traceabilityList.length > 0" :id="'module-suyuan'" :data-index="12">
  179. <CellTip title="溯源管理"></CellTip>
  180. <view class="nav">
  181. <view class="nav-content">
  182. <view class="nav-item" v-for="(item, index) in traceabilityList" @click="toNav(item.path)">
  183. <MenuIcon :name="item.name || item.title"></MenuIcon>
  184. <i class="badge" v-if="item.badge">{{ item.badge }}</i>
  185. <label>{{ item.name }}</label>
  186. </view>
  187. </view>
  188. </view>
  189. </view>
  190. </view>
  191. </view>
  192. </template>
  193. <script>
  194. import CellTip from "./CellTip.vue";
  195. import MenuIcon from "./MenuIcon.vue";
  196. import {
  197. statistics,
  198. qualityTodoByPda
  199. } from "@/api/myTicket";
  200. import { getResourcesTree } from "@/api/pda/common.js";
  201. // 已下线的 HR 列表页 → 直达发起页(菜单 path 由后台配置,此处兜底兼容旧配置,
  202. // 避免菜单仍然指向已删除的页面导致「页面不存在」;后台改好后这里自然不再命中)
  203. const LEGACY_ENTRY = {
  204. // 入职列表(2026-10-15 下线)
  205. "/pages/hr/manage/onboard-list": "/pages/hr/manage/onboard-create",
  206. // 转正办理列表(2026-10-16 下线)
  207. "/pages/hr/manage/regular-list": "/pages/hr/manage/regular-create",
  208. // 人事异动列表(2026-10-16 下线)→ 发起调岗
  209. "/pages/hr/manage/transfer-list": "/pages/hr/manage/transfer-create",
  210. // 离职管理列表(2026-10-16 下线)→ 发起离职申请
  211. "/pages/hr/manage/resign-list": "/pages/hr/apply/form?type=resign",
  212. // 单据详情页(2026-10-16 下线):详情统一走「发起页的 detail 模式」,
  213. // 旧 path 兜底到「我的申请」,用户可再从列表点进具体单据
  214. "/pages/hr/manage/transfer-detail": "/pages/hr/apply/list",
  215. "/pages/hr/manage/resign-detail": "/pages/hr/apply/list",
  216. "/pages/hr/manage/regular-detail": "/pages/hr/apply/list",
  217. "/pages/hr/manage/onboard-detail": "/pages/hr/manage/onboard-create",
  218. };
  219. export default {
  220. components: {
  221. CellTip,
  222. MenuIcon,
  223. },
  224. data() {
  225. return {
  226. timer: null,
  227. src1: "https://cdn.uviewui.com/uview/album/1.jpg",
  228. workOrder: {}, // 工单统计数据
  229. qmsList: [],
  230. //生产类
  231. productionList: [],
  232. // 人力资源
  233. hrList:[],
  234. //仓储管理
  235. warehousingList: [],
  236. //运维类
  237. operationsList: [],
  238. dispatchList: [],
  239. internalManagementList: [],
  240. treeList: [],
  241. saleManageList: [],
  242. // 售后服务
  243. serviceList: [],
  244. // 溯源管理
  245. traceabilityList: [],
  246. // 采购管理
  247. purchaseManageList: [],
  248. pcsList: [],
  249. // 导航相关
  250. moduleNavList: [],
  251. energyManagement: [],
  252. //安全生产
  253. productionSafetyManagement: [],
  254. scrollIntoViewId: "",
  255. currentNavIndex: 0,
  256. moduleObserver: null,
  257. // 顶部固定区域高度(状态栏 + nav-bar + 横向导航)
  258. topNavHeight: 0,
  259. };
  260. },
  261. created() {
  262. this.getTree();
  263. },
  264. onShow() {
  265. // this.getStatistics();
  266. this.$nextTick(() => {
  267. this.calculateTopNavHeight();
  268. });
  269. },
  270. onReady() {
  271. // 页面准备完成后,滚动到第一个模块
  272. this.$nextTick(() => {
  273. if (this.moduleNavList.length > 0) {
  274. this.goToModule(this.moduleNavList[0], 0);
  275. }
  276. });
  277. },
  278. onHide() {
  279. clearTimeout(this.timer);
  280. },
  281. onUnload() {
  282. clearTimeout(this.timer);
  283. },
  284. methods: {
  285. // 计算顶部固定区域高度(动态获取实际高度)
  286. calculateTopNavHeight() {
  287. const query = uni.createSelectorQuery().in(this);
  288. query
  289. .select(".top-nav-wrapper")
  290. .boundingClientRect((rect) => {
  291. if (rect) {
  292. this.topNavHeight = rect.bottom;
  293. }
  294. })
  295. .exec();
  296. },
  297. // getStatistics() {
  298. // // 获取工单统计数
  299. // statistics()
  300. // .then((res) => {
  301. // this.workOrder = res;
  302. // this.operationsList.forEach((item) => {
  303. // if (item.name == "保养工单") item.badge = res.maintenanceNum;
  304. // if (item.name == "巡点检工单") item.badge = res.patrolInspection;
  305. // if (item.name == "维修工单") item.badge = res.repairsNum;
  306. // if (item.name == "检修工单") item.badge = res.serviceNum;
  307. // });
  308. // })
  309. // .finally(() => {
  310. // this.timer = setTimeout(() => {
  311. // this.getStatistics();
  312. // }, 12000);
  313. // });
  314. // },
  315. getBrages() {
  316. qualityTodoByPda().then((res) => {
  317. console.log(2)
  318. this.qmsList.forEach((item) => {
  319. if (item.name == "质检工单") item.badge = res.workOrderNum;
  320. if (item.name == "我的质检工单")
  321. item.badge = res.myWorkOrderNum;
  322. if (item.name == "我的任务单") item.badge = res.myTaskMonadNum;
  323. if (item.name == "我的受托单")
  324. item.badge = res.myRequestEntrustNum;
  325. });
  326. // this.qmsList = f.children;
  327. });
  328. statistics()
  329. .then((res) => {
  330. this.workOrder = res;
  331. this.operationsList.forEach((item) => {
  332. if (item.name == "保养工单") item.badge = res.maintenanceNum;
  333. if (item.name == "巡点检工单") item.badge = res.patrolInspection;
  334. if (item.name == "维修工单") item.badge = res.repairsNum;
  335. if (item.name == "检修工单") item.badge = res.serviceNum;
  336. });
  337. })
  338. },
  339. getTree() {
  340. // 菜单缓存必须容错读取:不能写成 JSON.parse(uni.getStorageSync("treeList"))。
  341. // 缓存为空时(首次进入 / 退出登录、token 过期被 removeStorageSync 清掉)
  342. // getStorageSync 返回 "",JSON.parse("") 抛
  343. // SyntaxError: Unexpected end of JSON input,直接打断 created 钩子 → 整页白屏。
  344. let list = [];
  345. try {
  346. const raw = uni.getStorageSync("treeList");
  347. if (raw) list = typeof raw === "string" ? JSON.parse(raw) : raw;
  348. } catch (e) {
  349. console.log("[工作中心] 菜单缓存解析失败,已按空菜单处理:", (e && e.message) || e);
  350. }
  351. if (!Array.isArray(list)) list = [];
  352. this.treeList = list;
  353. console.log("-----------list--------------");
  354. console.log(list);
  355. this.renderMenuTree(list);
  356. this.buildNavList();
  357. this.getBrages();
  358. // 缓存缺失时自愈:重新拉一次菜单树并回写缓存,避免工作中心一直是空白
  359. if (list.length === 0) {
  360. if (uni.getStorageSync("token")) {
  361. this.reloadMenuTree();
  362. } else {
  363. uni.reLaunch({ url: "/pages/login/login" });
  364. }
  365. }
  366. },
  367. // 把菜单树铺到各模块列表(树为空时什么都不做)
  368. renderMenuTree(list) {
  369. // children 也要判断:缓存里可能是 [{...}] 这种没有 children 的残缺结构
  370. if (list[0] && Array.isArray(list[0].children) && list[0].children.length > 0) {
  371. // console.log(list[0].children, "list[0].children ----");
  372. list[0].children.forEach((f) => {
  373. if (f.path == "productionManage") {
  374. this.productionList = f.children;
  375. } else if (f.path == "hr") {
  376. this.hrList = f.children;
  377. } else if (f.path == "operationsList") {
  378. // const promise = statistics().then((res) => {
  379. // console.log(3)
  380. // this.workOrder = res;
  381. // f.children.forEach((item) => {
  382. // if (item.name == "保养工单") item.badge = res.maintenanceNum;
  383. // if (item.name == "巡点检工单")
  384. // item.badge = res.patrolInspection;
  385. // if (item.name == "维修工单") item.badge = res.repairsNum;
  386. // });
  387. this.operationsList = f.children;
  388. // });
  389. // asyncPromises.push(promise);
  390. } else if (f.path == "warehouseManagement") {
  391. this.warehousingList = f.children;
  392. } else if (f.path == "saleManageList") {
  393. this.saleManageList = f.children;
  394. this.saleManageList.forEach((item) => {
  395. item.name = item.name.replace("员工", "");
  396. item.name = item.name.replace("管理员", "");
  397. });
  398. } else if (f.path == "internalManagement") {
  399. // console.log(f, "f");
  400. this.internalManagementList = f.children;
  401. } else if (f.path == "serviceList") {
  402. this.serviceList = f.children;
  403. } else if (f.path == "traceability") {
  404. this.traceabilityList = f.children;
  405. } else if (f.path == "purchasingManage") {
  406. this.purchaseManageList = f.children;
  407. } else if (f.path == "qualityManage") {
  408. // const promise = qualityTodoByPda().then((res) => {
  409. // console.log(2)
  410. // f.children.forEach((item) => {
  411. // if (item.name == "质检工单") item.badge = res.workOrderNum;
  412. // if (item.name == "我的质检工单")
  413. // item.badge = res.myWorkOrderNum;
  414. // if (item.name == "我的任务单") item.badge = res.myTaskMonadNum;
  415. // if (item.name == "我的受托单")
  416. // item.badge = res.myRequestEntrustNum;
  417. // });
  418. this.qmsList = f.children;
  419. // });
  420. // asyncPromises.push(promise);
  421. } else if (f.path == "productionControlManagement") {
  422. this.pcsList = f.children;
  423. } else if (f.path == "dispatchManage") {
  424. this.dispatchList = f.children;
  425. } else if (f.path == 'energyManagement') {
  426. this.energyManagement = f.children
  427. } else if (f.path == 'productionSafetyManagement') {
  428. this.productionSafetyManagement = f.children
  429. }
  430. });
  431. }
  432. },
  433. // 菜单缓存缺失时的自愈:重新获取菜单树 → 回写缓存 → 重新渲染
  434. async reloadMenuTree() {
  435. try {
  436. const res = await Promise.race([
  437. getResourcesTree(),
  438. new Promise((_, reject) =>
  439. setTimeout(() => reject(new Error("菜单树请求超时")), 10000)
  440. ),
  441. ]);
  442. if (!Array.isArray(res) || res.length === 0) {
  443. console.log("[工作中心] 菜单树为空,可能未配置权限");
  444. return;
  445. }
  446. uni.setStorageSync("treeList", JSON.stringify(res));
  447. this.treeList = res;
  448. this.renderMenuTree(res);
  449. this.buildNavList();
  450. this.getBrages();
  451. console.log("[工作中心] 菜单缓存已自动重建");
  452. } catch (e) {
  453. // utils/request 在响应非 JSON 时 Promise 不会 settle,这里用超时兜底,避免一直白屏
  454. console.log("[工作中心] 菜单树自动重建失败:", (e && e.message) || e);
  455. }
  456. },
  457. // 构建导航列表
  458. buildNavList() {
  459. const navMap = {
  460. internalManagementList: {
  461. name: "协同办公",
  462. id: "xietong"
  463. },
  464. hrList: {
  465. name: "人力资源",
  466. id: "renli"
  467. },
  468. productionList: {
  469. name: "生产管理",
  470. id: "shengchan"
  471. },
  472. operationsList: {
  473. name: "运维管理",
  474. id: "yunwei"
  475. },
  476. serviceList: {
  477. name: "售后服务",
  478. id: "shouhou"
  479. },
  480. warehousingList: {
  481. name: "仓储管理",
  482. id: "cangchu"
  483. },
  484. dispatchList: {
  485. name: "运输管理",
  486. id: "yunshu"
  487. },
  488. saleManageList: {
  489. name: "营销管理",
  490. id: "yingxiao"
  491. },
  492. purchaseManageList: {
  493. name: "采购管理",
  494. id: "caigou"
  495. },
  496. pcsList: {
  497. name: "生产管控",
  498. id: "shengchanguanli"
  499. },
  500. qmsList: {
  501. name: "质量管理",
  502. id: "zhiliang"
  503. },
  504. energyManagement: {
  505. name: "能源管理",
  506. id: "nengyuan"
  507. },
  508. productionSafetyManagement: {
  509. name: "生产安全",
  510. id: "anquan"
  511. },
  512. traceabilityList: {
  513. name: "溯源管理",
  514. id: "suyuan"
  515. },
  516. };
  517. this.moduleNavList = Object.entries(navMap)
  518. .filter(([key]) => this[key]?.length > 0)
  519. .map(([, value]) => value);
  520. },
  521. // 点击导航跳转 - 使用动态获取的顶部高度进行精确定位
  522. goToModule(item, index) {
  523. this.currentNavIndex = index;
  524. this.scrollIntoViewId = "nav-" + item.id;
  525. setTimeout(() => {
  526. this.scrollIntoViewId = "";
  527. const query = uni.createSelectorQuery().in(this);
  528. query.select("#module-" + item.id).boundingClientRect();
  529. query.select(".top-nav-wrapper").boundingClientRect();
  530. query.selectViewport().scrollOffset();
  531. query.exec((res) => {
  532. if (res[0] && res[1] && res[2]) {
  533. const targetTop = res[0].top;
  534. const fixedBottom = res[1].bottom;
  535. const currentScrollTop = res[2].scrollTop;
  536. const scrollTop = currentScrollTop + targetTop - fixedBottom - 10;
  537. uni.pageScrollTo({
  538. scrollTop: Math.max(0, scrollTop),
  539. duration: 300,
  540. });
  541. }
  542. });
  543. }, 200);
  544. },
  545. // 监听导航滚动
  546. handleNavScroll(e) {
  547. // 可以在这里添加滚动时的逻辑
  548. },
  549. onUnload() {
  550. if (this.moduleObserver) {
  551. this.moduleObserver.disconnect();
  552. }
  553. clearTimeout(this.timer);
  554. },
  555. toNav(url) {
  556. console.log(url);
  557. // 只按路径匹配(后台 path 可能带 query);命中已下线的旧列表页时改走直达发起页
  558. const path = String(url || "").split("?")[0].split("#")[0];
  559. uni.navigateTo({
  560. url: LEGACY_ENTRY[path] || url,
  561. // 跳转失败不能静默:真机上「点击没反应」多数是菜单 path 指向
  562. // 已删除/未注册的页面,这里把目标路径直接报出来便于定位
  563. fail: (err) => {
  564. console.log("[工作中心] 跳转失败:", path, err);
  565. // 失败路径直接进剪贴板,方便把配置错误发给开发定位
  566. uni.setClipboardData({
  567. data: path,
  568. success: () => {
  569. uni.showToast({
  570. title: `页面未注册:${path}(路径已复制)`,
  571. icon: "none",
  572. duration: 3000,
  573. });
  574. },
  575. });
  576. },
  577. });
  578. },
  579. HandlScanCode() {
  580. let _this = this;
  581. uni.scanCode({
  582. success: function(res) {
  583. console.log(res);
  584. // 获取扫描结果中的URL
  585. const scanResult = res.result;
  586. // 检查URL是否包含traceability
  587. if (scanResult && scanResult.includes("/traceability")) {
  588. // 从扫描结果中提取id参数
  589. let id = "";
  590. if (scanResult.includes("id=")) {
  591. // 分割URL获取id参数值
  592. const idPart = scanResult.split("id=")[1];
  593. // 如果id后面还有其他参数,只取到第一个&之前的部分
  594. if (idPart.includes("&")) {
  595. id = idPart.split("&")[0];
  596. } else {
  597. id = idPart;
  598. }
  599. }
  600. // 跳转到溯源页面并传递id
  601. uni.navigateTo({
  602. url: `/pages/traceability/scanCode/index?id=${id}`,
  603. });
  604. return;
  605. } else if (scanResult && scanResult.includes("/pages/warehouse/hwQrcode/index")) {
  606. uni.navigateTo({
  607. url: `${scanResult}`,
  608. });
  609. return
  610. }
  611. _this.scantoRouter(scanResult);
  612. },
  613. });
  614. },
  615. scantoRouter(result) {
  616. uni.navigateTo({
  617. url: `/pages/pda/workOrder/extrusionMolding/index?id=${result}`,
  618. });
  619. },
  620. },
  621. };
  622. </script>
  623. <style lang="scss" scoped>
  624. @import "index.scss";
  625. </style>