index.vue 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. <template>
  2. <view class="operation-container">
  3. <!-- 直接循环 -->
  4. <view class="section" v-for="item in menuData" :key="item.path">
  5. <view class="section-title">{{ item.meta.title }}</view>
  6. <view class="grid-container">
  7. <view
  8. class="grid-item"
  9. v-for="child in item.children"
  10. :style="{ gridColumn: child.query.span ? 'span 2' : 'span 1' }"
  11. :key="child.path"
  12. :class="child.query.type"
  13. @click="handleNavigation(child.path)"
  14. >
  15. {{ formatName(child.meta.title) }}
  16. </view>
  17. </view>
  18. </view>
  19. </view>
  20. </template>
  21. <script setup>
  22. import { ref, computed, onMounted } from "vue";
  23. import { onLoad } from "@dcloudio/uni-app";
  24. // 菜单数据和加载状态
  25. const menuData = ref([]);
  26. let menuPromise = null;
  27. //获取权限菜单 - 只调用一次
  28. async function getMenuList() {
  29. // 如果已经有数据,直接返回
  30. if (menuData.value && menuData.value.length > 0) {
  31. return menuData.value;
  32. }
  33. // 如果已有一个正在进行的请求,则返回该Promise
  34. if (menuPromise) {
  35. return menuPromise;
  36. }
  37. // 创建新的请求
  38. menuPromise = uni.$u.http
  39. .get("/app/appUser/getRouters")
  40. .then((res) => {
  41. const data = res.data;
  42. menuData.value = data.map((item) => {
  43. item.children = item.children.map((child) => {
  44. child.query = JSON.parse(child.query);
  45. return child;
  46. });
  47. return item;
  48. });
  49. return data;
  50. })
  51. .catch((err) => {
  52. // 处理错误情况
  53. console.error("获取菜单数据失败", err);
  54. return [];
  55. })
  56. .finally(() => {
  57. // 请求完成后,重置Promise
  58. menuPromise = null;
  59. });
  60. return menuPromise;
  61. }
  62. //获取按钮权限
  63. function getButtonList() {
  64. uni.$u.http.get("/app/appUser/getInfo").then((res) => {
  65. if (res.code == 200) {
  66. uni.setStorageSync("buttonList", res.data);
  67. }
  68. });
  69. }
  70. // 页面加载时初始化数据
  71. onLoad(() => {
  72. // 显示加载中提示
  73. uni.showLoading({
  74. title: '加载中...',
  75. mask: true
  76. });
  77. // 初始化菜单和按钮数据
  78. Promise.all([getMenuList(), getButtonList()])
  79. .finally(() => {
  80. // 数据加载完成后,隐藏加载提示
  81. uni.hideLoading();
  82. });
  83. });
  84. const formatName = (name) => {
  85. if (!name) return "";
  86. let result = name;
  87. if (result.includes("\\n\\r")) {
  88. result = result.replace(/\\n\\r/g, "\n");
  89. }
  90. return result;
  91. };
  92. // 快递操作列表
  93. const expressOperations = ref([
  94. {
  95. name: "中转\n\r签收",
  96. path: "/pages/index/express/transfer-sign",
  97. type: "primary",
  98. },
  99. {
  100. name: "到仓\n\r签收",
  101. path: "/pages/index/express/warehouse-sign",
  102. type: "warning",
  103. },
  104. {
  105. name: "重量\n\r修改",
  106. path: "/pages/index/express/weight-modify",
  107. type: "primary",
  108. },
  109. {
  110. name: "快递\n\r验收",
  111. path: "/pages/index/express/quick-check",
  112. type: "warning",
  113. },
  114. {
  115. name: "路由签收\n\r异常",
  116. path: "/pages/index/express/route-exception",
  117. type: "primary",
  118. },
  119. {
  120. name: "快递\n\r拆包",
  121. path: "/pages/index/express/quick-unpack",
  122. type: "warning",
  123. },
  124. ]);
  125. // 审核操作列表
  126. const auditOperations = ref([
  127. {
  128. name: "确认\n\r收货",
  129. path: "/pages/index/audit/confirm-receipt",
  130. type: "primary",
  131. },
  132. {
  133. name: "扫书\n\r查单",
  134. path: "/pages/index/audit/scan-order",
  135. type: "warning",
  136. },
  137. {
  138. name: "根据快递单\n\r或订单",
  139. path: "/pages/index/audit/express-order",
  140. type: "warning",
  141. },
  142. {
  143. name: "根据\n\r发件人",
  144. path: "/pages/index/audit/sender",
  145. type: "primary",
  146. },
  147. ]);
  148. // WMS操作列表
  149. const wmsOperations = ref([
  150. {
  151. name: "中等\n\r入库",
  152. path: "/pages/index/wms/medium-in",
  153. type: "primary",
  154. },
  155. {
  156. name: "良品\n\r入库",
  157. path: "/pages/index/wms/good-in",
  158. type: "warning",
  159. },
  160. {
  161. name: "次品\n\r入库",
  162. path: "/pages/index/wms/secondary-in",
  163. type: "primary",
  164. },
  165. {
  166. name: "不良\n\r入库",
  167. path: "/pages/index/wms/bad-in",
  168. type: "warning",
  169. },
  170. {
  171. name: "不良\n\r出库",
  172. path: "/pages/index/wms/bad-out",
  173. type: "primary",
  174. },
  175. {
  176. name: "不良\n\r下架",
  177. path: "/pages/index/wms/bad-off",
  178. type: "warning",
  179. },
  180. {
  181. name: "订单\n\r查询",
  182. path: "/pages/index/wms/order-query",
  183. type: "primary",
  184. },
  185. {
  186. name: "库位\n\r订单",
  187. path: "/pages/index/wms/location-order",
  188. type: "warning",
  189. },
  190. {
  191. name: "快速盘点",
  192. path: "/pages/index/wms/speedy-check",
  193. type: "primary",
  194. span: 24,
  195. },
  196. ]);
  197. // 统计操作列表
  198. const statisticsOperations = ref([
  199. {
  200. name: "审核统计",
  201. path: "/pages/index/statistic/audit",
  202. type: "warning",
  203. span: 24,
  204. },
  205. {
  206. name: "售后\n\r统计",
  207. path: "/pages/index/statistic/after-sale",
  208. type: "primary",
  209. },
  210. {
  211. name: "打包\n\r统计",
  212. path: "/pages/index/statistic/package",
  213. type: "warning",
  214. },
  215. ]);
  216. //线下核单
  217. const offlineOperations = ref([
  218. {
  219. name: "线下\n\r核单",
  220. path: "/pages/index/offline/check-order",
  221. type: "primary",
  222. },
  223. {
  224. name: "核单\n\r记录",
  225. path: "/pages/index/offline/check-record",
  226. type: "warning",
  227. },
  228. ]);
  229. //录入信息
  230. const entryOperations = ref([
  231. {
  232. name: "扫码\n\r查书",
  233. path: "/pages/index/entry/scan-book",
  234. type: "primary",
  235. },
  236. {
  237. name: "录入\n\r书籍重量",
  238. path: "/pages/index/entry/book-weight",
  239. type: "warning",
  240. },
  241. ]);
  242. // 页面跳转方法
  243. const handleNavigation = (path) => {
  244. uni.navigateTo({
  245. url: path,
  246. fail: () => {
  247. uni.showToast({
  248. title: "页面跳转失败",
  249. icon: "none",
  250. });
  251. },
  252. });
  253. };
  254. </script>
  255. <style lang="scss" scoped>
  256. .operation-container {
  257. padding: 20rpx;
  258. box-sizing: border-box;
  259. /* #ifdef H5 */
  260. padding-bottom: 100rpx;
  261. /* #endif */
  262. }
  263. .section {
  264. margin-bottom: 30rpx;
  265. background: #ffffff;
  266. border-radius: 16rpx;
  267. padding: 20rpx;
  268. padding-right: 0;
  269. box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.05);
  270. .section-title {
  271. font-size: 50rpx;
  272. font-weight: 600;
  273. color: #333;
  274. padding: 20rpx;
  275. padding-top: 0;
  276. border-bottom: 2rpx solid #f0f0f0;
  277. margin-bottom: 20rpx;
  278. }
  279. .grid-container {
  280. display: flex;
  281. flex-wrap: wrap;
  282. padding: 10rpx;
  283. .grid-item {
  284. width: calc(50% - 20rpx);
  285. min-height: 148rpx;
  286. display: flex;
  287. align-items: center;
  288. justify-content: center;
  289. text-align: center;
  290. padding: 20rpx 30rpx;
  291. line-height: 60rpx;
  292. font-size: 50rpx;
  293. border-radius: 12rpx;
  294. color: #ffffff;
  295. transition: all 0.3s;
  296. white-space: pre-wrap;
  297. box-sizing: border-box;
  298. margin-right: 20rpx;
  299. margin-bottom: 20rpx;
  300. &[style*="grid-column: span 2"] {
  301. width: calc(100% - 20rpx);
  302. margin-right: 20rpx;
  303. }
  304. &.primary {
  305. background: linear-gradient(135deg, #4cd964, #3ac555);
  306. &:active {
  307. background: linear-gradient(135deg, #3ac555, #2fb548);
  308. }
  309. }
  310. &.warning {
  311. background: linear-gradient(135deg, #ff9500, #ff8000);
  312. &:active {
  313. background: linear-gradient(135deg, #ff8000, #e67300);
  314. }
  315. }
  316. &:active {
  317. transform: scale(0.98);
  318. }
  319. }
  320. }
  321. }
  322. </style>