From e8db9d37e2ef39e75bb49288e9e2c091df6b01d2 Mon Sep 17 00:00:00 2001 From: spring <2396852758@qq.com> Date: 星期五, 29 八月 2025 17:48:02 +0800 Subject: [PATCH] 微信扫码看设备详情 --- src/permission.js | 95 +++++---- src/views/equipmentManagement/deviceInfo/index.vue | 190 +++++++++++++++++++++ src/api/equipmentManagement/deviceInfo.js | 10 + src/views/equipmentManagement/ledger/index.vue | 4 src/router/index.js | 187 ++++++++++---------- 5 files changed, 350 insertions(+), 136 deletions(-) diff --git a/src/api/equipmentManagement/deviceInfo.js b/src/api/equipmentManagement/deviceInfo.js new file mode 100644 index 0000000..d71b713 --- /dev/null +++ b/src/api/equipmentManagement/deviceInfo.js @@ -0,0 +1,10 @@ +import request from "@/utils/request"; + +// 鑾峰彇璁惧鍩烘湰淇℃伅 +export function getDeviceInfo(params) { + return request({ + url: "/device/ledger/scanDevice", + method: "get", + params, + }); +} diff --git a/src/permission.js b/src/permission.js index a7d9f87..5b2566b 100644 --- a/src/permission.js +++ b/src/permission.js @@ -1,69 +1,76 @@ -import router from './router' -import { ElMessage } from 'element-plus' -import NProgress from 'nprogress' -import 'nprogress/nprogress.css' -import { getToken } from '@/utils/auth' -import { isHttp, isPathMatch } from '@/utils/validate' -import { isRelogin } from '@/utils/request' -import useUserStore from '@/store/modules/user' -import useSettingsStore from '@/store/modules/settings' -import usePermissionStore from '@/store/modules/permission' +import router from "./router"; +import { ElMessage } from "element-plus"; +import NProgress from "nprogress"; +import "nprogress/nprogress.css"; +import { getToken } from "@/utils/auth"; +import { isHttp, isPathMatch } from "@/utils/validate"; +import { isRelogin } from "@/utils/request"; +import useUserStore from "@/store/modules/user"; +import useSettingsStore from "@/store/modules/settings"; +import usePermissionStore from "@/store/modules/permission"; -NProgress.configure({ showSpinner: false }) +NProgress.configure({ showSpinner: false }); -const whiteList = ['/login', '/register'] +const whiteList = ["/login", "/register", "/device-info"]; const isWhiteList = (path) => { - return whiteList.some(pattern => isPathMatch(pattern, path)) -} + return whiteList.some((pattern) => isPathMatch(pattern, path)); +}; router.beforeEach((to, from, next) => { - NProgress.start() + NProgress.start(); if (getToken()) { - to.meta.title && useSettingsStore().setTitle(to.meta.title) + to.meta.title && useSettingsStore().setTitle(to.meta.title); /* has token*/ - if (to.path === '/login') { - next({ path: '/' }) - NProgress.done() + if (to.path === "/login") { + next({ path: "/" }); + NProgress.done(); } else if (isWhiteList(to.path)) { - next() + next(); } else { if (useUserStore().roles.length === 0) { - isRelogin.show = true + isRelogin.show = true; // 鍒ゆ柇褰撳墠鐢ㄦ埛鏄惁宸叉媺鍙栧畬user_info淇℃伅 - useUserStore().getInfo().then(() => { - isRelogin.show = false - usePermissionStore().generateRoutes().then(accessRoutes => { - // 鏍规嵁roles鏉冮檺鐢熸垚鍙闂殑璺敱琛� - accessRoutes.forEach(route => { - if (!isHttp(route.path)) { - router.addRoute(route) // 鍔ㄦ�佹坊鍔犲彲璁块棶璺敱琛� - } - }) - next({ ...to, replace: true }) // hack鏂规硶 纭繚addRoutes宸插畬鎴� + useUserStore() + .getInfo() + .then(() => { + isRelogin.show = false; + usePermissionStore() + .generateRoutes() + .then((accessRoutes) => { + // 鏍规嵁roles鏉冮檺鐢熸垚鍙闂殑璺敱琛� + accessRoutes.forEach((route) => { + if (!isHttp(route.path)) { + router.addRoute(route); // 鍔ㄦ�佹坊鍔犲彲璁块棶璺敱琛� + } + }); + next({ ...to, replace: true }); // hack鏂规硶 纭繚addRoutes宸插畬鎴� + }); }) - }).catch(err => { - useUserStore().logOut().then(() => { - ElMessage.error(err) - next({ path: '/' }) - }) - }) + .catch((err) => { + useUserStore() + .logOut() + .then(() => { + ElMessage.error(err); + next({ path: "/" }); + }); + }); } else { - next() + next(); } } } else { // 娌℃湁token if (isWhiteList(to.path)) { // 鍦ㄥ厤鐧诲綍鐧藉悕鍗曪紝鐩存帴杩涘叆 - next() + next(); } else { - next(`/login?redirect=${to.fullPath}`) // 鍚﹀垯鍏ㄩ儴閲嶅畾鍚戝埌鐧诲綍椤� - NProgress.done() + next(`/login?redirect=${to.fullPath}`); // 鍚﹀垯鍏ㄩ儴閲嶅畾鍚戝埌鐧诲綍椤� + NProgress.done(); } } -}) +}); router.afterEach(() => { - NProgress.done() -}) + NProgress.done(); +}); diff --git a/src/router/index.js b/src/router/index.js index 10adf72..340409e 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -1,6 +1,6 @@ -import { createWebHistory, createRouter } from 'vue-router' +import { createWebHistory, createRouter } from "vue-router"; /* Layout */ -import Layout from '@/layout' +import Layout from "@/layout"; /** * Note: 璺敱閰嶇疆椤� @@ -27,163 +27,170 @@ // 鍏叡璺敱 export const constantRoutes = [ { - path: '/redirect', + path: "/redirect", component: Layout, hidden: true, children: [ { - path: '/redirect/:path(.*)', - component: () => import('@/views/redirect/index.vue') - } - ] + path: "/redirect/:path(.*)", + component: () => import("@/views/redirect/index.vue"), + }, + ], }, { - path: '/login', - component: () => import('@/views/login'), - hidden: true + path: "/login", + component: () => import("@/views/login"), + hidden: true, }, { - path: '/register', - component: () => import('@/views/register'), - hidden: true + path: "/register", + component: () => import("@/views/register"), + hidden: true, }, { path: "/:pathMatch(.*)*", - component: () => import('@/views/error/404'), - hidden: true + component: () => import("@/views/error/404"), + hidden: true, }, { - path: '/401', - component: () => import('@/views/error/401'), - hidden: true + path: "/401", + component: () => import("@/views/error/401"), + hidden: true, }, { - path: '', + path: "", component: Layout, - redirect: '/index', + redirect: "/index", children: [ { - path: '/index', - component: () => import('@/views/index'), - name: 'Index', - meta: { title: '棣栭〉', icon: 'dashboard', affix: true } - } - ] + path: "/index", + component: () => import("@/views/index"), + name: "Index", + meta: { title: "棣栭〉", icon: "dashboard", affix: true }, + }, + ], }, { - path: '/main/MobileChat', + path: "/main/MobileChat", component: Layout, - redirect: '', + redirect: "", hidden: true, children: [ { - path: '', - component: () => import('@/views/chatHome/chatHomeIndex/MobileChat'), - name: 'MobileChat', - meta: { title: 'AI瀵硅瘽', icon: 'dashboard', affix: true} - } - ] + path: "", + component: () => import("@/views/chatHome/chatHomeIndex/MobileChat"), + name: "MobileChat", + meta: { title: "AI瀵硅瘽", icon: "dashboard", affix: true }, + }, + ], }, { - path: '/user', + path: "/user", component: Layout, hidden: true, - redirect: 'noredirect', + redirect: "noredirect", children: [ { - path: 'profile', - component: () => import('@/views/system/user/profile/index'), - name: 'Profile', - meta: { title: '涓汉涓績', icon: 'user' } - } - ] - } -] + path: "profile", + component: () => import("@/views/system/user/profile/index"), + name: "Profile", + meta: { title: "涓汉涓績", icon: "user" }, + }, + ], + }, + { + path: "/device-info", + component: () => import("@/views/equipmentManagement/deviceInfo/index.vue"), + hidden: true, + name: "DeviceInfo", + meta: { title: "璁惧淇℃伅", icon: "monitor" }, + }, +]; // 鍔ㄦ�佽矾鐢憋紝鍩轰簬鐢ㄦ埛鏉冮檺鍔ㄦ�佸幓鍔犺浇 export const dynamicRoutes = [ { - path: '/system/user-auth', + path: "/system/user-auth", component: Layout, hidden: true, - permissions: ['system:user:edit'], + permissions: ["system:user:edit"], children: [ { - path: 'role/:userId(\\d+)', - component: () => import('@/views/system/user/authRole'), - name: 'AuthRole', - meta: { title: '鍒嗛厤瑙掕壊', activeMenu: '/system/user' } - } - ] + path: "role/:userId(\\d+)", + component: () => import("@/views/system/user/authRole"), + name: "AuthRole", + meta: { title: "鍒嗛厤瑙掕壊", activeMenu: "/system/user" }, + }, + ], }, { - path: '/system/role-auth', + path: "/system/role-auth", component: Layout, hidden: true, - permissions: ['system:role:edit'], + permissions: ["system:role:edit"], children: [ { - path: 'user/:roleId(\\d+)', - component: () => import('@/views/system/role/authUser'), - name: 'AuthUser', - meta: { title: '鍒嗛厤鐢ㄦ埛', activeMenu: '/system/role' } - } - ] + path: "user/:roleId(\\d+)", + component: () => import("@/views/system/role/authUser"), + name: "AuthUser", + meta: { title: "鍒嗛厤鐢ㄦ埛", activeMenu: "/system/role" }, + }, + ], }, { - path: '/system/dict-data', + path: "/system/dict-data", component: Layout, hidden: true, - permissions: ['system:dict:list'], + permissions: ["system:dict:list"], children: [ { - path: 'index/:dictId(\\d+)', - component: () => import('@/views/system/dict/data'), - name: 'Data', - meta: { title: '瀛楀吀鏁版嵁', activeMenu: '/system/dict' } - } - ] + path: "index/:dictId(\\d+)", + component: () => import("@/views/system/dict/data"), + name: "Data", + meta: { title: "瀛楀吀鏁版嵁", activeMenu: "/system/dict" }, + }, + ], }, { - path: '/monitor/job-log', + path: "/monitor/job-log", component: Layout, hidden: true, - permissions: ['monitor:job:list'], + permissions: ["monitor:job:list"], children: [ { - path: 'index/:jobId(\\d+)', - component: () => import('@/views/monitor/job/log'), - name: 'JobLog', - meta: { title: '璋冨害鏃ュ織', activeMenu: '/monitor/job' } - } - ] + path: "index/:jobId(\\d+)", + component: () => import("@/views/monitor/job/log"), + name: "JobLog", + meta: { title: "璋冨害鏃ュ織", activeMenu: "/monitor/job" }, + }, + ], }, { - path: '/tool/gen-edit', + path: "/tool/gen-edit", component: Layout, hidden: true, - permissions: ['tool:gen:edit'], + permissions: ["tool:gen:edit"], children: [ { - path: 'index/:tableId(\\d+)', - component: () => import('@/views/tool/gen/editTable'), - name: 'GenEdit', - meta: { title: '淇敼鐢熸垚閰嶇疆', activeMenu: '/tool/gen' } - } - ] - } -] + path: "index/:tableId(\\d+)", + component: () => import("@/views/tool/gen/editTable"), + name: "GenEdit", + meta: { title: "淇敼鐢熸垚閰嶇疆", activeMenu: "/tool/gen" }, + }, + ], + }, +]; const router = createRouter({ history: createWebHistory(), routes: constantRoutes, scrollBehavior(to, from, savedPosition) { if (savedPosition) { - return savedPosition + return savedPosition; } - return { top: 0 } + return { top: 0 }; }, -}) +}); -export default router +export default router; diff --git a/src/views/equipmentManagement/deviceInfo/index.vue b/src/views/equipmentManagement/deviceInfo/index.vue new file mode 100644 index 0000000..de162cc --- /dev/null +++ b/src/views/equipmentManagement/deviceInfo/index.vue @@ -0,0 +1,190 @@ +<template> + <div class="device-info-container"> + <div class="page-header"> + <h1>璁惧淇℃伅</h1> + <div class="device-status" :class="deviceStatusClass"> + {{ deviceStatusText }} + </div> + </div> + + <div class="info-card"> + <div class="card-header">鍩烘湰淇℃伅</div> + <div class="card-content"> + <div class="info-row"> + <span class="label">璁惧鍚嶇О锛�</span> + <span class="value">{{ deviceInfo.deviceName }}</span> + </div> + <div class="info-row"> + <span class="label">瑙勬牸鍨嬪彿锛�</span> + <span class="value">{{ deviceInfo.deviceModel }}</span> + </div> + <div class="info-row"> + <span class="label">鐢熶骇鍘傚锛�</span> + <span class="value">{{ deviceInfo.supplierName }}</span> + </div> + <div class="info-row"> + <span class="label">鍗曚綅锛�</span> + <span class="value">{{ deviceInfo.unit }}</span> + </div> + </div> + </div> + + <div class="info-card"> + <div class="card-header">缁存姢淇℃伅</div> + <div class="card-content"> + <div class="maintenance-info"> + <div class="maintenance-item"> + <span class="label">鏈�鍚庣淮鎶わ細</span> + <span class="value">{{ deviceInfo.updateTime }}</span> + </div> + <div class="maintenance-item"> + <span class="label">涓嬫缁存姢锛�</span> + <span class="value">{{ deviceInfo.createTime }}</span> + </div> + <div class="maintenance-item"> + <span class="label">缁存姢鐘舵�侊細</span> + <span class="value status-normal">{{ deviceInfo.statusText }}</span> + </div> + </div> + </div> + </div> + </div> +</template> + +<script setup> +import { ref, reactive, onMounted, computed } from 'vue' +import { useRoute } from 'vue-router' +import { ElMessage } from 'element-plus' +import { + getDeviceInfo, +} from '@/api/equipmentManagement/deviceInfo' + +const route = useRoute() + +const deviceInfo = reactive({ + deviceName: '', + deviceModel: '', + supplierName: '', + unit: '', + statusText:'姝e父', + updateTime:'', + createTime:'' +}) + +const deviceStatusClass = computed(() => { + return 'status-normal' +}) + +const deviceStatusText = computed(() => { + return '姝e父' +}) + +const fetchDeviceInfo = async (deviceId) => { + try { + // 鑾峰彇璁惧淇℃伅 + const deviceResponse = await getDeviceInfo({id:deviceId}) + if (deviceResponse.code === 200) { + Object.assign(deviceInfo, deviceResponse.data) + } + + + } catch (error) { + + ElMessage.warning('浣跨敤妯℃嫙鏁版嵁锛屽疄闄匒PI璋冪敤澶辫触') + } +} + +onMounted(() => { + const deviceId = route.query.deviceId || route.params.deviceId || '' + fetchDeviceInfo(deviceId) +}) +</script> + +<style scoped> +.device-info-container { + min-height: 100vh; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + padding: 20px; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; +} + +.page-header { + background: rgba(255, 255, 255, 0.95); + border-radius: 16px; + padding: 20px; + margin-bottom: 20px; + display: flex; + justify-content: space-between; + align-items: center; +} + +.page-header h1 { + margin: 0; + color: #2c3e50; + font-size: 24px; +} + +.device-status { + padding: 8px 16px; + border-radius: 20px; + font-size: 14px; + color: white; + background: #52c41a; +} + +.info-card { + background: rgba(255, 255, 255, 0.95); + border-radius: 16px; + margin-bottom: 20px; + overflow: hidden; +} + +.card-header { + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + color: white; + padding: 16px 20px; + font-weight: 500; +} + +.card-content { + padding: 20px; +} + +.info-row, .maintenance-item { + display: flex; + margin-bottom: 12px; + align-items: center; +} + +.label { + width: 100px; + color: #666; + font-size: 14px; +} + +.value { + flex: 1; + color: #2c3e50; + font-weight: 500; +} + +.status-normal { + color: #52c41a; +} + + + +@media (max-width: 768px) { + .device-info-container { + padding: 16px; + } + + .page-header h1 { + font-size: 20px; + } + + .label { + width: 80px; + } +} +</style> diff --git a/src/views/equipmentManagement/ledger/index.vue b/src/views/equipmentManagement/ledger/index.vue index 16fbbc6..9b4f802 100644 --- a/src/views/equipmentManagement/ledger/index.vue +++ b/src/views/equipmentManagement/ledger/index.vue @@ -270,8 +270,8 @@ }; const showQRCode = async (row) => { - // 浣犲彲浠ヨ嚜瀹氫箟浜岀淮鐮佸唴瀹癸紝姣斿 row.id 鎴� row.deviceName - const qrContent = JSON.stringify(row); // 鎴� `${row.id}` + // 鐩存帴浣跨敤URL锛屼笉瑕佺敤JSON.stringify鍖呰 + const qrContent = proxy.javaApi + '/device-info?deviceId=' + row.id; qrCodeUrl.value = await QRCode.toDataURL(qrContent); qrRowData.value = row; qrDialogVisible.value = true; -- Gitblit v1.9.3