¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from "@/utils/request"; |
| | | |
| | | // è·å设å¤åºæ¬ä¿¡æ¯ |
| | | export function getDeviceInfo(params) { |
| | | return request({ |
| | | url: "/device/ledger/scanDevice", |
| | | method: "get", |
| | | params, |
| | | }); |
| | | } |
| | |
| | | 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();
|
| | | });
|
| | |
| | | import { createWebHistory, createRouter } from 'vue-router'
|
| | | import { createWebHistory, createRouter } from "vue-router";
|
| | | /* Layout */
|
| | | import Layout from '@/layout'
|
| | | import Layout from "@/layout";
|
| | |
|
| | | /**
|
| | | * Note: è·¯ç±é
置项
|
| | |
| | | // å
Œ
±è·¯ç±
|
| | | 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;
|
¶Ô±ÈÐÂÎļþ |
| | |
| | | <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:'æ£å¸¸', |
| | | updateTime:'', |
| | | createTime:'' |
| | | }) |
| | | |
| | | const deviceStatusClass = computed(() => { |
| | | return 'status-normal' |
| | | }) |
| | | |
| | | const deviceStatusText = computed(() => { |
| | | return 'æ£å¸¸' |
| | | }) |
| | | |
| | | const fetchDeviceInfo = async (deviceId) => { |
| | | try { |
| | | // è·å设å¤ä¿¡æ¯ |
| | | const deviceResponse = await getDeviceInfo({id:deviceId}) |
| | | if (deviceResponse.code === 200) { |
| | | Object.assign(deviceInfo, deviceResponse.data) |
| | | } |
| | | |
| | | |
| | | } catch (error) { |
| | | |
| | | ElMessage.warning('ä½¿ç¨æ¨¡ææ°æ®ï¼å®é
APIè°ç¨å¤±è´¥') |
| | | } |
| | | } |
| | | |
| | | 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> |
| | |
| | | }; |
| | | |
| | | 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; |