18 Commits

Author SHA1 Message Date
caozehui
4189eea278 默认模式为模拟式 2026-05-11 20:37:44 +08:00
caozehui
d3fef49af2 微调 2026-05-11 20:17:11 +08:00
caozehui
12d40a5c6e 打包 2026-05-09 09:53:10 +08:00
caozehui
6748490c3f 隐藏非必要的页面 2026-05-09 08:43:33 +08:00
caozehui
2c19fc43de 微调 2026-05-08 13:16:19 +08:00
caozehui
2ba5ebaddb Merge remote-tracking branch 'origin/hainan' into hainan
# Conflicts:
#	frontend/src/views/machine/freqConverter/components/freqConverterDipChart.vue
2026-05-08 11:36:53 +08:00
caozehui
448687115c 实施测试特性曲线与结果展示特性曲线不一致问题 2026-05-08 11:32:45 +08:00
caozehui
0d4dc2d2bf 特性点连线顺序 2026-05-08 10:40:05 +08:00
caozehui
121829a4bd 特性点顺序问题 2026-05-07 19:18:05 +08:00
caozehui
3f6952612d 调整绘制特性点 2026-05-07 08:52:47 +08:00
caozehui
5ca5d73f98 实时推送&绘制特性点 2026-05-06 10:53:30 +08:00
caozehui
71d80e67f1 替换标题 2026-04-30 09:32:02 +08:00
caozehui
0e0969c50f 耐受实验调整为首页、替换标题 2026-04-30 09:31:01 +08:00
caozehui
8ab1a35f3b 耐受图调整、屏蔽非必要的菜单、登录后跳转到变频器页面 2026-04-27 08:39:30 +08:00
caozehui
8744dfb0d8 变频器耐受表X轴改用对数刻度、补充错误码 2026-04-22 19:32:28 +08:00
caozehui
b826f505ac 变频器功能页面 2026-04-17 09:15:58 +08:00
caozehui
465ad81069 微调 2026-04-14 15:06:09 +08:00
caozehui
c73bf05d41 变频器台账信息 2026-04-14 14:50:07 +08:00
127 changed files with 2657 additions and 1415 deletions

1
.gitignore vendored
View File

@@ -9,4 +9,3 @@ public/electron/
pnpm-lock.yaml pnpm-lock.yaml
CLAUDE.md CLAUDE.md
/public/dist/ /public/dist/
/docs/

View File

@@ -33,9 +33,9 @@ mybatis-plus:
#驼峰命名 #驼峰命名
map-underscore-to-camel-case: true map-underscore-to-camel-case: true
#配置sql日志输出 #配置sql日志输出
# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
#关闭日志输出 #关闭日志输出
log-impl: org.apache.ibatis.logging.nologging.NoLoggingImpl # log-impl: org.apache.ibatis.logging.nologging.NoLoggingImpl
global-config: global-config:
db-config: db-config:
#指定主键生成策略 #指定主键生成策略
@@ -55,32 +55,30 @@ webSocket:
#源参数下发,暂态数据默认值 #源参数下发,暂态数据默认值
Dip: Dip:
# 暂态前时间s #暂态前时间s
# fPreTime: 2f fPreTime: 2f
#写入时间s #写入时间s
fRampIn: 0.001f fRampIn: 0.001f
#写出时间s #写出时间s
fRampOut: 0.001f fRampOut: 0.001f
# 暂态后时间s #暂态后时间s
# fAfterTime: 3f fAfterTime: 3f
#Flicker: Flicker:
# waveFluType: CPM waveFluType: CPM
# waveType: SQU waveType: SQU
# fDutyCycle: 50f fDutyCycle: 50f
#log: log:
# homeDir: D:\logs homeDir: {{APP_DATA_PATH}}\logs
# commonLevel: info commonLevel: info
report: report:
# template: D:\template template: {{APP_DATA_PATH}}\template
# reportDir: D:\report reportDir: {{APP_DATA_PATH}}\report
dateFormat: yyyy年MM月dd日 dateFormat: yyyy年MM月dd日
#data: data:
# homeDir: D:\data homeDir: {{APP_DATA_PATH}}\data
#resource:
# videoDir: ${data.homeDir}\resources\videos
qr: qr:
cloud: http://pqmcc.com:18082/api/file cloud: http://pqmcc.com:18082/api/file
dev: dev:
@@ -117,4 +115,10 @@ activate:
private-key: "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCcUyYhVqczGxblL+o/xZzF/8nf+LjrfUE/dS1aRHM7uMDD0cgCArhjtfneFePrMxt+Z7W8yNBzSarub8qsfhaVNikV7Es7oaeTygfjQXTi2n4AFkir3fM07J08RpWhl5M8f8uWTCuvFUYAw00gq55typqmnbkmJa2VIUy/iQf+cMCP7abz4/jNhUzUR3qA7TV4oMRgTdIEDUp63YF8dOC+JH8XxYrCVeHXV6fLCwmesdMzl0lB2VTEKMfLbXhOmF5g7P9y/16VCcN8UBuZlbyYfn+GAxJOSbeHi5HshOKfoSuD7Jz+3WQZpNavOWjIFExKIU38/CvnJCOP7XBCqpSTAgMBAAECggEAYeWokWRE3TpvwiOZnUpR/aVMdVi75a3ROL5XIpqPV61B+t/bU3cEpl0GF9C5pUeiRi0IoStZb3mI9D1KPW/REKyUWkhabQO1gFYbTnRlkNOn6MILzKX4cwJjDaZeeo4EBPU7N+qHyOOXrU6hdH5FfxhMdV983ajm5eeuupxER1C2kAcIklTeVpTX6EKOgZb5LBp5ssOVm2P42pOauvcRozRcvZmqnErXmukv0H4l3EVNt4rHpTn9riHUC63e8JfiYzVaF6zuNUxv6nHEft0/SRMw11XSTnNfDzcKqgjz6ksFBS/6eQQYKESk+ONC53HUuYHFAknkwsPupDCT2W8FIQKBgQDLHT/xCU3nxGr4vFKBDNaO2D5oK20ECbBO4oDvLWWmQG7f+6TsMy8PgVdMnoL4RfqGlwFAKEpS6KVFHnBVqnNEhcdy9uCI7x7Xx8UnyUtxj1EDTm76uta9Ki9OrlqB6tImDM9+Ya3vGktW37ht4WOx2OsJRhG1dbf6RLwFlH7DWwKBgQDFBxvi5I1BR6hg6Tj7xd2SqOT2Y+BED3xuSYENhWbmMhLJDResaB7mjztbxlYaY2mOE0holWm2uDmVFFhMh4jYXik4hYH8nmDzq9mDpZCZ9pyjYqnAP8THoAa8EbgrUWB8A6BPH4iL3KbMnBfBKY0pIr2xrvnjQjNBAgta7KDRKQKBgCe6oe4wxrdF2TKsC2tIqpMoQxS3Icy/ZGgZr+SYuaBKTCWtoDW/UT40K3JGMxIDBhzbXphBCUCsVt9tM8Xd4EwP6tJW7dZ7B0pnve2pVwNwaAVAiz6p2yUHIle+jN+Koe5lZRSwYIg7WW81tWpwwsJfzqFyvjYDP6hJV4mz4ROvAoGAaRcdnKvjXApomShMqJ4lTPChD3q+SA8qg3jZSOj6tZXHx00gb2kp8jg7pPvpOTIFPy6x1Ha9aCRjMk0ju84fA6lVuzwa1S907wOehUVuF3Eeo1cgy9Y3k3KbpPyeixxgpkUY4JslLdSHc2NemD0dee951qhJyRmqVOZOQDUuoeECgYEAqBw2cAFk3vM97WY06TSldGA8ajVHx3BYRjj+zl62NTQthy8fw3tqxb3c5e8toOmZWKjZvDhg2TRLhsDDQWEYg3LZG87REqVIjgEPcpjNLidjygGX8n3JF2o0O5I/EMvl0s/+LVQONfduOBvhwDqr8QNisbLsyneiAq7umewMolo=" private-key: "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCcUyYhVqczGxblL+o/xZzF/8nf+LjrfUE/dS1aRHM7uMDD0cgCArhjtfneFePrMxt+Z7W8yNBzSarub8qsfhaVNikV7Es7oaeTygfjQXTi2n4AFkir3fM07J08RpWhl5M8f8uWTCuvFUYAw00gq55typqmnbkmJa2VIUy/iQf+cMCP7abz4/jNhUzUR3qA7TV4oMRgTdIEDUp63YF8dOC+JH8XxYrCVeHXV6fLCwmesdMzl0lB2VTEKMfLbXhOmF5g7P9y/16VCcN8UBuZlbyYfn+GAxJOSbeHi5HshOKfoSuD7Jz+3WQZpNavOWjIFExKIU38/CvnJCOP7XBCqpSTAgMBAAECggEAYeWokWRE3TpvwiOZnUpR/aVMdVi75a3ROL5XIpqPV61B+t/bU3cEpl0GF9C5pUeiRi0IoStZb3mI9D1KPW/REKyUWkhabQO1gFYbTnRlkNOn6MILzKX4cwJjDaZeeo4EBPU7N+qHyOOXrU6hdH5FfxhMdV983ajm5eeuupxER1C2kAcIklTeVpTX6EKOgZb5LBp5ssOVm2P42pOauvcRozRcvZmqnErXmukv0H4l3EVNt4rHpTn9riHUC63e8JfiYzVaF6zuNUxv6nHEft0/SRMw11XSTnNfDzcKqgjz6ksFBS/6eQQYKESk+ONC53HUuYHFAknkwsPupDCT2W8FIQKBgQDLHT/xCU3nxGr4vFKBDNaO2D5oK20ECbBO4oDvLWWmQG7f+6TsMy8PgVdMnoL4RfqGlwFAKEpS6KVFHnBVqnNEhcdy9uCI7x7Xx8UnyUtxj1EDTm76uta9Ki9OrlqB6tImDM9+Ya3vGktW37ht4WOx2OsJRhG1dbf6RLwFlH7DWwKBgQDFBxvi5I1BR6hg6Tj7xd2SqOT2Y+BED3xuSYENhWbmMhLJDResaB7mjztbxlYaY2mOE0holWm2uDmVFFhMh4jYXik4hYH8nmDzq9mDpZCZ9pyjYqnAP8THoAa8EbgrUWB8A6BPH4iL3KbMnBfBKY0pIr2xrvnjQjNBAgta7KDRKQKBgCe6oe4wxrdF2TKsC2tIqpMoQxS3Icy/ZGgZr+SYuaBKTCWtoDW/UT40K3JGMxIDBhzbXphBCUCsVt9tM8Xd4EwP6tJW7dZ7B0pnve2pVwNwaAVAiz6p2yUHIle+jN+Koe5lZRSwYIg7WW81tWpwwsJfzqFyvjYDP6hJV4mz4ROvAoGAaRcdnKvjXApomShMqJ4lTPChD3q+SA8qg3jZSOj6tZXHx00gb2kp8jg7pPvpOTIFPy6x1Ha9aCRjMk0ju84fA6lVuzwa1S907wOehUVuF3Eeo1cgy9Y3k3KbpPyeixxgpkUY4JslLdSHc2NemD0dee951qhJyRmqVOZOQDUuoeECgYEAqBw2cAFk3vM97WY06TSldGA8ajVHx3BYRjj+zl62NTQthy8fw3tqxb3c5e8toOmZWKjZvDhg2TRLhsDDQWEYg3LZG87REqVIjgEPcpjNLidjygGX8n3JF2o0O5I/EMvl0s/+LVQONfduOBvhwDqr8QNisbLsyneiAq7umewMolo="
public-key: "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnFMmIVanMxsW5S/qP8Wcxf/J3/i4631BP3UtWkRzO7jAw9HIAgK4Y7X53hXj6zMbfme1vMjQc0mq7m/KrH4WlTYpFexLO6Gnk8oH40F04tp+ABZIq93zNOydPEaVoZeTPH/LlkwrrxVGAMNNIKuebcqapp25JiWtlSFMv4kH/nDAj+2m8+P4zYVM1Ed6gO01eKDEYE3SBA1Ket2BfHTgviR/F8WKwlXh11enywsJnrHTM5dJQdlUxCjHy214TpheYOz/cv9elQnDfFAbmZW8mH5/hgMSTkm3h4uR7ITin6Erg+yc/t1kGaTWrzloyBRMSiFN/Pwr5yQjj+1wQqqUkwIDAQAB" public-key: "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnFMmIVanMxsW5S/qP8Wcxf/J3/i4631BP3UtWkRzO7jAw9HIAgK4Y7X53hXj6zMbfme1vMjQc0mq7m/KrH4WlTYpFexLO6Gnk8oH40F04tp+ABZIq93zNOydPEaVoZeTPH/LlkwrrxVGAMNNIKuebcqapp25JiWtlSFMv4kH/nDAj+2m8+P4zYVM1Ed6gO01eKDEYE3SBA1Ket2BfHTgviR/F8WKwlXh11enywsJnrHTM5dJQdlUxCjHy214TpheYOz/cv9elQnDfFAbmZW8mH5/hgMSTkm3h4uR7ITin6Erg+yc/t1kGaTWrzloyBRMSiFN/Pwr5yQjj+1wQqqUkwIDAQAB"
freq-converter:
schedule-period: 200 #定时器运行间隔
tolerant: 1 #耐受状态
dt: 200 #延迟时间ms
direction: 0 #0为横向1为纵向
allow-error-duration: 6 #暂态持续时间允许最大误差ms
allow-error-residual-voltage: 2.0 #暂态幅值允许最多误差%

View File

@@ -1 +1 @@
95428 42428

View File

@@ -1,16 +1,3 @@
.\binlog.000023
.\binlog.000024
.\binlog.000025
.\binlog.000026
.\binlog.000027
.\binlog.000028
.\binlog.000029
.\binlog.000030
.\binlog.000031
.\binlog.000032
.\binlog.000033
.\binlog.000034 .\binlog.000034
.\binlog.000035 .\binlog.000035
.\binlog.000036 .\binlog.000036
.\binlog.000037
.\binlog.000038

View File

@@ -42,7 +42,7 @@ function createTray() {
tray = new Tray(iconPath); tray = new Tray(iconPath);
} }
tray.setToolTip('NPQS-9100自动检测平台'); tray.setToolTip('变频器暂降耐受实验平台');
console.log('[Tray] Tray created successfully'); console.log('[Tray] Tray created successfully');
// 创建托盘菜单 // 创建托盘菜单

View File

@@ -1,5 +1,5 @@
# title # title
VITE_GLOB_APP_TITLE=NPQS-9100自动检测平台 VITE_GLOB_APP_TITLE=变频器暂降耐受实验平台
# 本地运行端口号 # 本地运行端口号
VITE_PORT=18091 VITE_PORT=18091

View File

@@ -19,7 +19,7 @@ VITE_API_URL=/api
# 开发环境跨域代理,支持配置多个 # 开发环境跨域代理,支持配置多个
VITE_PROXY=[["/api","http://127.0.0.1:18093/"]] VITE_PROXY=[["/api","http://127.0.0.1:18092/"]]
#VITE_PROXY=[["/api","http://192.168.1.124:18092/"]] #VITE_PROXY=[["/api","http://192.168.1.124:18092/"]]
#VITE_PROXY=[["/api","http://192.168.2.125:18092/"]] #VITE_PROXY=[["/api","http://192.168.2.125:18092/"]]
# VITE_PROXY=[["/api","http://192.168.1.138:8080/"]]张文 # VITE_PROXY=[["/api","http://192.168.1.138:8080/"]]张文

View File

@@ -23,6 +23,6 @@ VITE_PWA=true
# 线上环境接口地址 # 线上环境接口地址
#VITE_API_URL="/api" # 打包时用 #VITE_API_URL="/api" # 打包时用
VITE_API_URL="http://127.0.0.1:18093/" VITE_API_URL="http://127.0.0.1:18092/"
# 开启激活验证 # 开启激活验证
VITE_ACTIVATE_OPEN=false VITE_ACTIVATE_OPEN=false

View File

@@ -4,8 +4,7 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, maximum-scale=1.0, minimum-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, maximum-scale=1.0, minimum-scale=1.0" />
<link rel="icon" type="image/x-icon" href="/favicon.ico"> <title></title>
<title>NPQS-9100</title>
<!-- 优化vue渲染未完成之前先加一个css动画 --> <!-- 优化vue渲染未完成之前先加一个css动画 -->
<style> <style>
#loadingPage { #loadingPage {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

View File

@@ -1,15 +0,0 @@
import http from '@/api'
import type { DetectionLockHolder } from '@/stores/modules/detectionLock'
/**
* 查询当前检测锁持有状态
* - data 为 null → 锁空闲
* - data 非 null → 锁被某账号持有
*
* 本接口只读,不抢锁、不会返回 DETECTION_BUSY
*/
export const getCurrentLock = () => {
return http.get<DetectionLockHolder | null>('/detection/lock/current', undefined, {
loading: false
})
}

View File

@@ -1,7 +1,6 @@
import type { controlSource } from '@/api/device/interface/controlSource' import type { controlSource } from '@/api/device/interface/controlSource'
import http from '@/api' import http from '@/api'
import { useDetectionLockStore } from '@/stores/modules/detectionLock'
/** /**
* @name 程控源管理模块 * @name 程控源管理模块
@@ -18,11 +17,8 @@ export const startSimulateTest = (params: controlSource.ResControl) => {
} }
//停止 //停止
export const closeSimulateTest = async (params: controlSource.ResControl) => { export const closeSimulateTest = (params: controlSource.ResControl) => {
const result = await http.post(`/prepare/closeSimulateTest`,params,{loading:false}) return http.post(`/prepare/closeSimulateTest`,params,{loading:false})
// 主动终止 → 释放本地持锁标记
useDetectionLockStore().clearHolder()
return result
} }

View File

@@ -1,6 +1,10 @@
import type {Device} from '@/api/device/interface/device' import type {Device} from '@/api/device/interface/device'
import http from '@/api' import http from '@/api'
export const getPqDevListAll = () => {
return http.get<Device.ResPqDev[]>(`/pqDev/listAll`)
}
/** /**
* @name 被检设备管理模块 * @name 被检设备管理模块
*/ */

View File

@@ -0,0 +1,52 @@
import type {FreqConverter} from '@/api/device/interface/freqConverter'
import http from '@/api'
/**
* @name 变频器管理模块
*/
//获取设备类型
export const getFreqConverterList = (params: FreqConverter.ReqFreqConverterParams) => {
return http.post(`/freqConverter/list`, params)
}
//添加设备类型
export const addFreqConverter = (params: FreqConverter.ResFreqConverter) => {
return http.post(`/freqConverter/add`, params)
}
//编辑设备类型
export const updateFreqConverter = (params: FreqConverter.ResFreqConverter) => {
return http.post(`/freqConverter/update`, params)
}
//删除设备类型
export const deleteFreqConverter = (params: string[]) => {
return http.post(`/freqConverter/delete`, params)
}
export const getFreqConverterResult = (params: { converterId?: string }) => {
return http.get(`/freqConverter/result?converterId=${params.converterId || ''}`)
}
export const startFreqConverterDetect = (params: {
converterId?: string;
monitorId?: string;
userId?: string | null;
reset?: boolean;
}) => {
return http.get(`/prepare/startFreqConverter`, params, {loading: false})
}
export const stopFreqConverterDetect = (params: {
userId?: string | null;
}) => {
return http.get(`/prepare/stopFreqConverter`, params, {loading: false})
}
export const getFreqConverterSCurve = (params: FreqConverter.ReqFreqConverterSCurveParams) => {
return http.get(`/freqConverter/scurve?converterId=${params.converterId || ''}`)
}

View File

@@ -0,0 +1,51 @@
import type {ReqPage, ResPage} from '@/api/interface'
// 变频器模块
export namespace FreqConverter {
/**
* 变频器数据表格分页查询参数
*/
export interface ReqFreqConverterParams extends ReqPage {
name?: string; // 名称
}
/**
* 变频器新增、修改、根据id查询返回的对象
*/
export interface ResFreqConverter {
id?: string; //变频器ID
name: string;//变频器名称
portName: string; //串口名称
slaveAddress: number; //从机地址
baudRate: number; //波特率
parity: string; //奇偶校验类型
dataBits: number; //数据位
stopBits: number; //停止位
timeoutMs: number; //超时时间(毫秒)
suffix?: number; //数据表后缀
state?: number;
testStatus?: number; //测试状态 0未测试 1测试完成
createBy?: string | null; //创建用户
createTime?: string | null; //创建时间
updateBy?: string | null; //更新用户
updateTime?: string | null; //更新时间
}
/**
* 变频器表格查询分页返回的对象;
*/
export interface ResFreqConverterPage extends ResPage<ResFreqConverter> {
}
export interface ReqFreqConverterSCurveParams {
converterId?: string;
}
export interface ResTolerantPoint {
durationMs?: number | null;
residualVoltage?: number | null;
tolerant?: number | null;
}
}

View File

@@ -12,12 +12,6 @@ import { type ResultData } from '@/api/interface'
import { ResultEnum } from '@/enums/httpEnum' import { ResultEnum } from '@/enums/httpEnum'
import { checkStatus } from './helper/checkStatus' import { checkStatus } from './helper/checkStatus'
import { useUserStore } from '@/stores/modules/user' import { useUserStore } from '@/stores/modules/user'
import { useDetectionLockStore, type DetectionLockHolder } from '@/stores/modules/detectionLock'
import {
showForceReleasedDialog,
showLockBusyDialog,
showLockNotStartedToast
} from '@/utils/detectionLockDialog'
import router from '@/routers' import router from '@/routers'
import { refreshToken } from '@/api/user/login' import { refreshToken } from '@/api/user/login'
import { EventSourcePolyfill } from 'event-source-polyfill' import { EventSourcePolyfill } from 'event-source-polyfill'
@@ -113,32 +107,6 @@ class RequestHttp {
} }
return Promise.reject(data) return Promise.reject(data)
} }
// 单用户检测互斥:命中 DETECTION_BUSY 时根据 data 和本地持锁状态分发到 4 种文案
if (data.code === ResultEnum.DETECTION_BUSY) {
const lockStore = useDetectionLockStore()
const holder = (data.data ?? null) as DetectionLockHolder | null
const currentUserId = userStore.userInfo?.id
const localDetecting = lockStore.iAmHolder
if (!localDetecting && holder) {
// S1:他人持锁
showLockBusyDialog(holder)
} else if (!localDetecting && !holder) {
// S2:未开始检测就调中间接口
showLockNotStartedToast()
} else if (localDetecting && holder && holder.holderUserId !== currentUserId) {
// S4-a:被强释 + 别人接手
showForceReleasedDialog(holder)
lockStore.clearHolder()
} else if (localDetecting && !holder) {
// S4-b:被强释,无人接手
showForceReleasedDialog(null)
lockStore.clearHolder()
}
// 阻断默认错误提示,不再走下面的 ElMessage.error
return Promise.reject(data)
}
// 全局错误信息拦截(防止下载文件的时候返回数据流,没有 code 直接报错) // 全局错误信息拦截(防止下载文件的时候返回数据流,没有 code 直接报错)
if (data.code && data.code !== ResultEnum.SUCCESS) { if (data.code && data.code !== ResultEnum.SUCCESS) {
if (data.message.includes('&')) { if (data.message.includes('&')) {

View File

@@ -69,30 +69,5 @@ export namespace Plan {
maxTime: number; maxTime: number;
} }
export interface PlanStatisticsItem {
itemId: string;
itemName: string;
unqualifiedCount: number;
}
export interface PlanStatistics {
planId: string;
planName: string;
totalCheckCount: number;
checkedDeviceCount: number;
uncheckedDeviceCount: number;
firstQualifiedDeviceCount: number;
secondQualifiedDeviceCount: number;
thirdOrMoreQualifiedDeviceCount: number;
qualifiedDeviceCount: number;
unqualifiedDeviceCount: number;
unqualifiedItemCount: number;
firstPassRate: number;
secondPassRate: number;
thirdOrMorePassRate: number;
unqualifiedRate: number;
itemDistributions: PlanStatisticsItem[];
}
} }

View File

@@ -94,10 +94,6 @@ export const staticsAnalyse = (params: { id: string[] }) => {
return http.download('/adPlan/analyse', params) return http.download('/adPlan/analyse', params)
} }
export const getPlanStatistics = (params: { planId: string; manufacturer?: string; devType?: string }) => {
return http.post<Plan.PlanStatistics>(`/adPlan/statistics`, params)
}
//根据计划id分页查询被检设 //根据计划id分页查询被检设
export const getDevListByPlanId = (params: any) => { export const getDevListByPlanId = (params: any) => {
return http.post(`/adPlan/listDevByPlanId`, params) return http.post(`/adPlan/listDevByPlanId`, params)
@@ -163,4 +159,4 @@ export const importAndMergePlanCheckData = (params: Plan.ResPlan) => {
return http.upload(`/adPlan/importAndMergePlanCheckData`, params, { return http.upload(`/adPlan/importAndMergePlanCheckData`, params, {
timeout: 60000 * 20 timeout: 60000 * 20
}) })
} }

View File

@@ -1,18 +0,0 @@
import http from '@/api'
import type { ResourceManage } from '@/api/resourceManage/interface'
export const getResourceManageList = (params: ResourceManage.ReqResourceManageParams) => {
return http.post<ResourceManage.ResResourceManagePage>('/resourceManage/list', params)
}
export const addResourceManage = (params: FormData) => {
return http.upload('/resourceManage/add', params)
}
export const updateResourceManage = (params: ResourceManage.ReqUpdateResourceManage) => {
return http.post('/resourceManage/update', params)
}
export const getResourceManagePlayUrl = (id: string) => {
return http.get<ResourceManage.PlayVO>(`/resourceManage/play?id=${id}`)
}

View File

@@ -1,34 +0,0 @@
import type { ReqPage, ResPage } from '@/api/interface'
export namespace ResourceManage {
export interface ReqResourceManageParams extends ReqPage {
name?: string
fileName?: string
}
export interface ResResourceManage {
id: string
name: string
fileName: string
fileSize: number
relativePath: string
remark: string
state: number
createBy?: string | null
createTime?: string | null
updateBy?: string | null
updateTime?: string | null
}
export interface ResResourceManagePage extends ResPage<ResResourceManage> {}
export interface ReqUpdateResourceManage {
id: string
name: string
remark: string
}
export interface PlayVO {
url: string
}
}

View File

@@ -1,12 +1,8 @@
import http from '@/api' import http from '@/api'
import { useDetectionLockStore } from '@/stores/modules/detectionLock'
export const startPreTest = async (params) => { export const startPreTest = (params) => {
const result = await http.post(`/prepare/startPreTest`, params, {loading: false}) return http.post(`/prepare/startPreTest`, params, {loading: false})
// 抢锁成功 → 标记本地为持锁者
useDetectionLockStore().setAsHolder()
return result
} }
export const closePreTest = (params) => { export const closePreTest = (params) => {
@@ -41,11 +37,8 @@ export const resumeTest = (params) => {
* 比对式通道配对 * 比对式通道配对
* @param params * @param params
*/ */
export const contrastTest = async (params: any) => { export const contrastTest = (params: any) => {
const result = await http.post(`/prepare/startContrastTest`, params) return http.post(`/prepare/startContrastTest`,params)
// 抢锁成功 → 标记本地为持锁者
useDetectionLockStore().setAsHolder()
return result
} }
export const exportAlignData= () => { export const exportAlignData= () => {

View File

@@ -130,6 +130,7 @@ const initChart = () => {
chart.resize() chart.resize()
}, 0) }, 0)
} }
const getChartInstance = () => chart
const handlerBar = (options: any) => { const handlerBar = (options: any) => {
if (Array.isArray(options.series)) { if (Array.isArray(options.series)) {
options.series.forEach((item: any) => { options.series.forEach((item: any) => {
@@ -253,7 +254,7 @@ onMounted(() => {
initChart() initChart()
resizeObserver.observe(chartRef.value!) resizeObserver.observe(chartRef.value!)
}) })
defineExpose({ initChart }) defineExpose({ initChart, getChartInstance })
onBeforeUnmount(() => { onBeforeUnmount(() => {
resizeObserver.unobserve(chartRef.value!) resizeObserver.unobserve(chartRef.value!)
chart?.dispose() chart?.dispose()

View File

@@ -1,7 +1,7 @@
// ? 全局默认配置项 // ? 全局默认配置项
// 首页地址(默认) // 首页地址(默认)
export const HOME_URL: string = "/home/index"; export const HOME_URL: string = "/machine/freqConverter";
// export const HOME_URL: string = "/machine/controlSource"; // export const HOME_URL: string = "/machine/controlSource";

View File

@@ -6,7 +6,6 @@ export enum ResultEnum {
ERROR = 500, ERROR = 500,
ACCESSTOKEN_EXPIRED = "A0024", ACCESSTOKEN_EXPIRED = "A0024",
OVERDUE = "A0025", OVERDUE = "A0025",
DETECTION_BUSY = "A020042",
TIMEOUT = 30000, TIMEOUT = 30000,
TYPE = "success" TYPE = "success"
} }

View File

@@ -1,31 +1,32 @@
<template> <template>
<div class="footer flx-align-center pl10"> <div class="footer flx-align-center pl10">
<el-dropdown> <el-dropdown>
<div class="change_mode"> <div class="change_mode">
{{ title }} {{ title }}
<el-icon class="el-icon--right change_mode_down"><arrow-down /></el-icon> <el-icon class="el-icon--right change_mode_down"><arrow-down /></el-icon>
<el-icon class="el-icon--right change_mode_up"><arrow-up /></el-icon> <el-icon class="el-icon--right change_mode_up"><arrow-up /></el-icon>
</div> </div>
<template #dropdown> <template #dropdown>
<el-dropdown-menu> <el-dropdown-menu>
<el-dropdown-item <el-dropdown-item
v-for="item in modeList" v-for="item in modeList"
:key="item.key" :key="item.key"
:disabled="!item.activated" :disabled="!item.activated"
@click="handelOpen(item.code, item.key)" @click="handelOpen(item.code, item.key)"
> >
{{ item.name }} {{ item.name }}
</el-dropdown-item> </el-dropdown-item>
</el-dropdown-menu> </el-dropdown-menu>
</template> </template>
</el-dropdown> </el-dropdown>
<p style="margin: 0"> <p style="margin: 0">
<a href="http://www.shining-electric.com/" target="_blank">2024 © 南京灿能电力自动化股份有限公司</a> <a href="http://www.shining-electric.com/" target="_blank">2024 © 南京灿能电力自动化股份有限公司</a>
</p> </p>
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { computed } from 'vue' import { computed } from 'vue'
import { HOME_URL } from '@/config'
import { useAuthStore } from '@/stores/modules/auth' import { useAuthStore } from '@/stores/modules/auth'
import { useModeStore } from '@/stores/modules/mode' // 引入模式 store import { useModeStore } from '@/stores/modules/mode' // 引入模式 store
import { useTabsStore } from '@/stores/modules/tabs' import { useTabsStore } from '@/stores/modules/tabs'
@@ -38,97 +39,97 @@ const modeStore = useModeStore()
const tabsStore = useTabsStore() const tabsStore = useTabsStore()
const title = computed(() => { const title = computed(() => {
return modeStore.currentMode === '' ? '选择模块' : modeStore.currentMode + '模块' return modeStore.currentMode === '' ? '选择模块' : modeStore.currentMode + '模块'
}) })
const activateInfo = authStore.activateInfo const activateInfo = authStore.activateInfo
const isActivateOpen = import.meta.env.VITE_ACTIVATE_OPEN const isActivateOpen = import.meta.env.VITE_ACTIVATE_OPEN
const modeList = [ const modeList = [
{ {
name: '模拟式模块', name: '模拟式模块',
code: '模拟式', code: '模拟式',
key: 'simulate', key: 'simulate',
activated: isActivateOpen === 'true' ? activateInfo.simulate.permanently === 1 : true activated: isActivateOpen === 'true' ? activateInfo.simulate.permanently === 1 : true
}, },
{ {
name: '数字式模块', name: '数字式模块',
code: '数字式', code: '数字式',
key: 'digital', key: 'digital',
activated: isActivateOpen === 'true' ? activateInfo.digital.permanently === 1 : true activated: isActivateOpen === 'true' ? activateInfo.digital.permanently === 1 : true
}, },
{ {
name: '比对式模块', name: '比对式模块',
code: '比对式', code: '比对式',
key: 'contrast', key: 'contrast',
activated: isActivateOpen === 'true' ? activateInfo.contrast.permanently === 1 : true activated: isActivateOpen === 'true' ? activateInfo.contrast.permanently === 1 : true
} }
] ]
const handelOpen = async (item: string, key: string) => { const handelOpen = async (item: string, key: string) => {
if (isActivateOpen === 'true' && activateInfo[key].permanently !== 1) { if (isActivateOpen === 'true' && activateInfo[key].permanently !== 1) {
ElMessage.warning(`${item}模块未激活`) ElMessage.warning(`${item}模块未激活`)
return return
} }
await authStore.setShowMenu() await authStore.setShowMenu()
modeStore.setCurrentMode(item) // 将模式code存入 store modeStore.setCurrentMode(item) // 将模式code存入 store
// 强制刷新页面 // 强制刷新页面
await tabsStore.closeMultipleTab() await tabsStore.closeMultipleTab()
await initDynamicRouter() await initDynamicRouter()
// 只有当目标路径与当前路径不同时才跳转
if (router.currentRoute.value.path !== HOME_URL) {
await router.push({ path: HOME_URL })
} else {
// 如果已在目标页面,手动触发组件更新
window.location.reload() // 或者采用其他方式刷新数据
}
// 只有当目标路径与当前路径不同时才跳转
if (router.currentRoute.value.path !== '/home/index') {
await router.push({ path: '/home/index' })
} else {
// 如果已在目标页面,手动触发组件更新
window.location.reload() // 或者采用其他方式刷新数据
}
} }
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@use './index.scss'; @use './index.scss';
.footer { .footer {
position: relative; position: relative;
background-color: var(--el-color-primary); background-color: var(--el-color-primary);
// .el-button:hover { // .el-button:hover {
// background-color: var(--el-color-primary) !important; // background-color: var(--el-color-primary) !important;
// border: none !important; // border: none !important;
// outline: none !important; // outline: none !important;
// } // }
.change_mode { .change_mode {
color: #fff; color: #fff;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: flex-start; justify-content: flex-start;
height: 100%; height: 100%;
width: auto; width: auto;
font-size: 14px; font-size: 14px;
.change_mode_down { .change_mode_down {
display: block; display: block;
}
.change_mode_up {
display: none;
}
} }
.change_mode:hover { .change_mode_up {
.change_mode_down { display: none;
display: none;
}
.change_mode_up {
display: block;
}
} }
.el-dropdown { }
z-index: 1001; .change_mode:hover {
.change_mode_down {
display: none;
} }
p { .change_mode_up {
position: absolute; display: block;
width: 100%;
height: 100%;
text-align: right;
line-height: 40px;
a {
color: #fff;
margin-right: 25px; // 增加右边距
}
} }
}
.el-dropdown {
z-index: 1001;
}
p {
position: absolute;
width: 100%;
height: 100%;
text-align: right;
line-height: 40px;
a {
color: #fff;
margin-right: 25px; // 增加右边距
}
}
} }
</style> </style>

View File

@@ -22,14 +22,6 @@
<el-icon><Edit /></el-icon> <el-icon><Edit /></el-icon>
{{ t('header.changePassword') }} {{ t('header.changePassword') }}
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item @click="changeMode" v-if="authStore.showMenuFlag">
<el-icon><Switch /></el-icon>
{{ t('header.changeMode') }}
</el-dropdown-item>
<el-dropdown-item @click="openDialog('versionRegisterRef')">
<el-icon><SetUp /></el-icon>
{{ t('header.versionRegister') }}
</el-dropdown-item>
<el-dropdown trigger="hover" placement="left-start" v-if="userStore.userInfo.loginName == 'root'"> <el-dropdown trigger="hover" placement="left-start" v-if="userStore.userInfo.loginName == 'root'">
<div class="custom-dropdown-trigger"> <div class="custom-dropdown-trigger">
<el-icon><Tools /></el-icon> <el-icon><Tools /></el-icon>
@@ -62,8 +54,6 @@
<InfoDialog ref="infoRef"></InfoDialog> <InfoDialog ref="infoRef"></InfoDialog>
<!-- passwordDialog --> <!-- passwordDialog -->
<PasswordDialog ref="passwordRef"></PasswordDialog> <PasswordDialog ref="passwordRef"></PasswordDialog>
<!-- versionRegisterDialog -->
<VersionDialog ref="versionRegisterRef"></VersionDialog>
<!-- ThemeDialog --> <!-- ThemeDialog -->
<ThemeDialog ref="themeRef"></ThemeDialog> <ThemeDialog ref="themeRef"></ThemeDialog>
</template> </template>
@@ -77,9 +67,7 @@ import { ElMessage, ElMessageBox } from 'element-plus'
import InfoDialog from './InfoDialog.vue' import InfoDialog from './InfoDialog.vue'
import PasswordDialog from './PasswordDialog.vue' import PasswordDialog from './PasswordDialog.vue'
import ThemeDialog from './ThemeDialog.vue' import ThemeDialog from './ThemeDialog.vue'
import VersionDialog from '@/views/system/versionRegister/index.vue' import { Avatar, Sunny, Tools } from '@element-plus/icons-vue'
import { Avatar, Sunny, Switch, Tools } from '@element-plus/icons-vue'
import { useAuthStore } from '@/stores/modules/auth'
import { useDictStore } from '@/stores/modules/dict' import { useDictStore } from '@/stores/modules/dict'
import { useAppSceneStore } from '@/stores/modules/mode' import { useAppSceneStore } from '@/stores/modules/mode'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
@@ -90,7 +78,6 @@ const dictStore = useDictStore()
const username = computed(() => userStore.userInfo.name) const username = computed(() => userStore.userInfo.name)
const router = useRouter() const router = useRouter()
const authStore = useAuthStore()
// 初始化 i18n // 初始化 i18n
const { t } = useI18n() // 使用 t 方法替代 $t const { t } = useI18n() // 使用 t 方法替代 $t
@@ -111,12 +98,10 @@ const logout = () => {
// 打开修改密码和个人信息弹窗 // 打开修改密码和个人信息弹窗
const infoRef = ref<InstanceType<typeof InfoDialog> | null>(null) const infoRef = ref<InstanceType<typeof InfoDialog> | null>(null)
const passwordRef = ref<InstanceType<typeof PasswordDialog> | null>(null) const passwordRef = ref<InstanceType<typeof PasswordDialog> | null>(null)
const versionRegisterRef = ref<InstanceType<typeof VersionDialog> | null>(null)
const themeRef = ref<InstanceType<typeof ThemeDialog> | null>(null) const themeRef = ref<InstanceType<typeof ThemeDialog> | null>(null)
const openDialog = (ref: string) => { const openDialog = (ref: string) => {
if (ref == 'infoRef') infoRef.value?.openDialog() if (ref == 'infoRef') infoRef.value?.openDialog()
if (ref == 'passwordRef') passwordRef.value?.openDialog() if (ref == 'passwordRef') passwordRef.value?.openDialog()
if (ref == 'versionRegisterRef') versionRegisterRef.value?.openDialog()
if (ref == 'themeRef') themeRef.value?.openDialog() if (ref == 'themeRef') themeRef.value?.openDialog()
} }
@@ -130,10 +115,6 @@ const changeScene = async (value: string) => {
} }
//模式切换 //模式切换
const changeMode = async () => {
authStore.changeModel()
await router.push('/home/index')
}
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">

Some files were not shown because too many files have changed in this diff Show More