完善类型配置,新增L1, L4数据展示界面
This commit is contained in:
2
.env.production
Normal file
2
.env.production
Normal file
@@ -0,0 +1,2 @@
|
||||
# 生产环境
|
||||
VITE_APP_BASE_API = '/prod-api'
|
||||
31
components.d.ts
vendored
31
components.d.ts
vendored
@@ -11,72 +11,53 @@ declare module 'vue' {
|
||||
AButton: typeof import('ant-design-vue/es')['Button']
|
||||
ACol: typeof import('ant-design-vue/es')['Col']
|
||||
AConfigProvider: typeof import('ant-design-vue/es')['ConfigProvider']
|
||||
ActionButton: typeof import('./src/components/common/ActionButton/ActionButton.vue')['default']
|
||||
ActionButtons: typeof import('./src/components/common/ActionButtons/index.vue')['default']
|
||||
ADescriptions: typeof import('ant-design-vue/es')['Descriptions']
|
||||
ADescriptionsItem: typeof import('ant-design-vue/es')['DescriptionsItem']
|
||||
AForm: typeof import('ant-design-vue/es')['Form']
|
||||
AFormItem: typeof import('ant-design-vue/es')['FormItem']
|
||||
AInput: typeof import('ant-design-vue/es')['Input']
|
||||
AInputGroup: typeof import('ant-design-vue/es')['InputGroup']
|
||||
AInputPassword: typeof import('ant-design-vue/es')['InputPassword']
|
||||
AList: typeof import('ant-design-vue/es')['List']
|
||||
AListItem: typeof import('ant-design-vue/es')['ListItem']
|
||||
AModal: typeof import('ant-design-vue/es')['Modal']
|
||||
ARadio: typeof import('ant-design-vue/es')['Radio']
|
||||
ARadioGroup: typeof import('ant-design-vue/es')['RadioGroup']
|
||||
ARangePicker: typeof import('ant-design-vue/es')['RangePicker']
|
||||
ARow: typeof import('ant-design-vue/es')['Row']
|
||||
ASelect: typeof import('ant-design-vue/es')['Select']
|
||||
ASelectOption: typeof import('ant-design-vue/es')['SelectOption']
|
||||
ASpace: typeof import('ant-design-vue/es')['Space']
|
||||
ASwitch: typeof import('ant-design-vue/es')['Switch']
|
||||
ATable: typeof import('ant-design-vue/es')['Table']
|
||||
ATextarea: typeof import('ant-design-vue/es')['Textarea']
|
||||
CameraModal: typeof import('./src/components/CameraModal/index.vue')['default']
|
||||
CameraStatus: typeof import('./src/components/CameraStatus/index.vue')['default']
|
||||
ExecutionResult: typeof import('./src/components/common/ExecutionResult/index.vue')['default']
|
||||
ILucideActivity: typeof import('~icons/lucide/activity')['default']
|
||||
ILucideCamera: typeof import('~icons/lucide/camera')['default']
|
||||
ILucideClock: typeof import('~icons/lucide/clock')['default']
|
||||
ILucideCpu: typeof import('~icons/lucide/cpu')['default']
|
||||
ILucideDatabase: typeof import('~icons/lucide/database')['default']
|
||||
ILucideEdit: typeof import('~icons/lucide/edit')['default']
|
||||
ILucideFileText: typeof import('~icons/lucide/file-text')['default']
|
||||
ILucideInbox: typeof import('~icons/lucide/inbox')['default']
|
||||
ILucideLink: typeof import('~icons/lucide/link')['default']
|
||||
ILucideLinkOff: typeof import('~icons/lucide/link-off')['default']
|
||||
ILucideLinOff: typeof import('~icons/lucide/lin-off')['default']
|
||||
ILucideLoader: typeof import('~icons/lucide/loader')['default']
|
||||
ILucideLock: typeof import('~icons/lucide/lock')['default']
|
||||
ILucideLogIn: typeof import('~icons/lucide/log-in')['default']
|
||||
ILucideLoOff: typeof import('~icons/lucide/lo-off')['default']
|
||||
ILucideLucideDatabase: typeof import('~icons/lucide/lucide-database')['default']
|
||||
ILucideMonitor: typeof import('~icons/lucide/monitor')['default']
|
||||
ILucidePackage: typeof import('~icons/lucide/package')['default']
|
||||
ILucidePlug: typeof import('~icons/lucide/plug')['default']
|
||||
ILucidePlugOff: typeof import('~icons/lucide/plug-off')['default']
|
||||
ILucideRadio: typeof import('~icons/lucide/radio')['default']
|
||||
ILucideRefreshCw: typeof import('~icons/lucide/refresh-cw')['default']
|
||||
ILucideSave: typeof import('~icons/lucide/save')['default']
|
||||
ILucideSearch: typeof import('~icons/lucide/search')['default']
|
||||
ILucideShieldCheck: typeof import('~icons/lucide/shield-check')['default']
|
||||
ILucideSquarePen: typeof import('~icons/lucide/square-pen')['default']
|
||||
ILucideTrash2: typeof import('~icons/lucide/trash2')['default']
|
||||
ILucideUnlink: typeof import('~icons/lucide/unlink')['default']
|
||||
ILucideUnlinkOff: typeof import('~icons/lucide/unlink-off')['default']
|
||||
ILucideUser: typeof import('~icons/lucide/user')['default']
|
||||
ILucideWifi: typeof import('~icons/lucide/wifi')['default']
|
||||
ILucideX: typeof import('~icons/lucide/x')['default']
|
||||
ILucideZap: typeof import('~icons/lucide/zap')['default']
|
||||
MesModal: typeof import('./src/components/MesModal/index.vue')['default']
|
||||
LmsStatus: typeof import('./src/components/LmsStatus/index.vue')['default']
|
||||
MesStatus: typeof import('./src/components/MesStatus/index.vue')['default']
|
||||
NetworkModal: typeof import('./src/components/NetworkModal/index.vue')['default']
|
||||
NetworkStatus: typeof import('./src/components/NetworkStatus/index.vue')['default']
|
||||
PlcModal: typeof import('./src/components/PlcModal/index.vue')['default']
|
||||
PlcStatus: typeof import('./src/components/PlcStatus/index.vue')['default']
|
||||
RouterLink: typeof import('vue-router')['RouterLink']
|
||||
RouterView: typeof import('vue-router')['RouterView']
|
||||
Settings: typeof import('./src/components/Settings/index.vue')['default']
|
||||
SettingsModal: typeof import('./src/components/SettingsModal/index.vue')['default']
|
||||
SSELogs: typeof import('./src/components/SSELogs/index.vue')['default']
|
||||
SseModal: typeof import('./src/components/SseModal/index.vue')['default']
|
||||
SseStatus: typeof import('./src/components/SseStatus/index.vue')['default']
|
||||
XxxModal: typeof import('./src/components/xxxModal/index.vue')['default']
|
||||
}
|
||||
}
|
||||
|
||||
1
global.d.ts
vendored
1
global.d.ts
vendored
@@ -2,3 +2,4 @@
|
||||
declare module '@/components/*';
|
||||
declare module '@/views/*';
|
||||
declare module '@/api/*';
|
||||
declare module '@/App.vue';
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"name": "rd_mes_front_hmi",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"version": "0.0.1",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite --open",
|
||||
"build": "vue-tsc -b && vite build",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
|
||||
@@ -6,4 +6,5 @@
|
||||
|
||||
<script setup>
|
||||
import zhCN from 'ant-design-vue/es/locale/zh_CN';
|
||||
import 'dayjs/locale/zh-cn';
|
||||
</script>
|
||||
7
src/api/common/model.d.ts
vendored
Normal file
7
src/api/common/model.d.ts
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
export interface ApiResponse<T = any> {
|
||||
code?: number;
|
||||
msg?: string;
|
||||
data?: T;
|
||||
rows?: T[];
|
||||
total?: number;
|
||||
}
|
||||
20
src/api/data/index.ts
Normal file
20
src/api/data/index.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import request from '../request';
|
||||
import type { QueryParams } from './model';
|
||||
|
||||
// 获取 L1 数据
|
||||
export function getL1Data(params: QueryParams) {
|
||||
return request({
|
||||
url: '/jinghua/l1Data/list',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// 获取 L4 数据
|
||||
export function getL4Data(params: QueryParams) {
|
||||
return request({
|
||||
url: '/jinghua/l4Data/list',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
9
src/api/data/model.d.ts
vendored
Normal file
9
src/api/data/model.d.ts
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
export interface QueryParams {
|
||||
pageNum?: number;
|
||||
pageSize?: number;
|
||||
orderByColumn?: string;
|
||||
isAsc?: boolean;
|
||||
qrCode?: string;
|
||||
createTimeBegin?: string;
|
||||
createTimeEnd?: string;
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import type { LmsWorkMode } from './model';
|
||||
// 获取 LMS 工作模式
|
||||
export const fetchLmsWorkMode = () => {
|
||||
return request({
|
||||
url: '/jinghua/mes/work-mode',
|
||||
url: '/jinghua/work-mode',
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
@@ -12,7 +12,7 @@ export const fetchLmsWorkMode = () => {
|
||||
// 更新 LMS 工作模式
|
||||
export const updateLmsWorkMode = (workMode: LmsWorkMode) => {
|
||||
return request({
|
||||
url: `/jinghua/mes/work-mode/${workMode}`,
|
||||
url: `/jinghua/work-mode/${workMode}`,
|
||||
method: 'put',
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import axios from 'axios';
|
||||
import { Modal, notification } from 'ant-design-vue';
|
||||
import router from '@/router';
|
||||
import { getToken } from '@/utils/auth';
|
||||
import { Modal, notification } from 'ant-design-vue';
|
||||
import type { AxiosRequestConfig } from "axios";
|
||||
import type { ApiResponse } from "@/api/common/model";
|
||||
|
||||
const errCodeMap: { [key: string]: string } = {
|
||||
'403': '当前操作没有权限',
|
||||
@@ -12,7 +14,7 @@ const errCodeMap: { [key: string]: string } = {
|
||||
// 创建axios实例
|
||||
const service = axios.create({
|
||||
baseURL: import.meta.env.VITE_APP_BASE_API as string,
|
||||
timeout: 10000
|
||||
timeout: 10000,
|
||||
});
|
||||
|
||||
// 请求拦截器
|
||||
@@ -36,12 +38,13 @@ service.interceptors.request.use(
|
||||
service.interceptors.response.use(
|
||||
response => {
|
||||
console.log(response)
|
||||
// 未设置状态码则默认成功状态
|
||||
const code = response.data.code || 200;
|
||||
const data = response.data;
|
||||
|
||||
if (code === 200) {
|
||||
return response.data ?? response;
|
||||
} else if (code === 401) {
|
||||
switch (code) {
|
||||
case 200:
|
||||
return data ?? response;
|
||||
case 401:
|
||||
Modal.error({
|
||||
title: '系统提示',
|
||||
content: '登录状态已过期,请重新登录',
|
||||
@@ -49,24 +52,32 @@ service.interceptors.response.use(
|
||||
router.push('/login')
|
||||
}
|
||||
})
|
||||
} else {
|
||||
const codeStr = String(code);
|
||||
const errMsg = errCodeMap[codeStr] || response.data.msg || errCodeMap['default'];
|
||||
return Promise.reject(data);
|
||||
default:
|
||||
const errMsg = errCodeMap[code] || data.msg || errCodeMap['default'];
|
||||
notification.error({
|
||||
message: '请求错误',
|
||||
description: errMsg,
|
||||
});
|
||||
return Promise.reject(response.data);
|
||||
return Promise.reject(data);
|
||||
}
|
||||
},
|
||||
error => {
|
||||
error.message = error.code === "ECONNABORTED" ? '请求超时,请稍后重试' : error.message;
|
||||
|
||||
// 网络/服务器错误统一处理
|
||||
notification.error({
|
||||
message: '网络错误',
|
||||
description: error.message || '请求失败',
|
||||
message: "网络错误",
|
||||
description: error.message,
|
||||
});
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
export default service;
|
||||
// 类型检查
|
||||
function request<T = any>(config: AxiosRequestConfig): Promise<ApiResponse<T>> {
|
||||
return service(config) as unknown as Promise<ApiResponse<T>>;
|
||||
}
|
||||
|
||||
export default request;
|
||||
// export default service;
|
||||
@@ -1,153 +1,9 @@
|
||||
@use './variables' as *;
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #000;
|
||||
color: #fff;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.info-row {
|
||||
height: 5vh;
|
||||
min-height: 5vh;
|
||||
|
||||
&.title {
|
||||
height: 6vh;
|
||||
min-height: 6vh;
|
||||
}
|
||||
|
||||
.title {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
// 解决外部图标无法居中问题
|
||||
.ant-btn:has(svg) {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
font-size: $title-font-size;
|
||||
}
|
||||
}
|
||||
|
||||
.logList-row {
|
||||
flex: 1 1 auto; // 修改
|
||||
min-height: 0; // 新增
|
||||
|
||||
.logList-col {
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.logList {
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.ant-col {
|
||||
border-right: 2px solid #fff;
|
||||
border-bottom: 2px solid #fff;
|
||||
font-size: $content-font-size;
|
||||
|
||||
&.option {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 5px 3px 3px;
|
||||
}
|
||||
|
||||
&.subtitle,
|
||||
&.text,
|
||||
&.label {
|
||||
text-align: center;
|
||||
padding: 0 1rem;
|
||||
line-height: 5vh;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
&.logList-col {
|
||||
padding: 2px 2px 0 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-btn,
|
||||
.ant-btn.ant-btn-sm {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 0;
|
||||
background-color: #d6d6d6;
|
||||
color: #000;
|
||||
font-size: $content-font-size;
|
||||
overflow: hidden;
|
||||
&:hover {
|
||||
border: 1px solid #000;
|
||||
color: #fff;
|
||||
background-color: #000;
|
||||
font-size: 1vw;
|
||||
}
|
||||
&:active {
|
||||
transform: scale(.9);
|
||||
transition: 100ms;
|
||||
background-color: #252525;
|
||||
}
|
||||
}
|
||||
|
||||
// 隐藏空列表
|
||||
:deep(.ant-list-empty-text) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
// 列表
|
||||
.ant-list {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
padding-right: 0 !important;
|
||||
|
||||
.ant-list-item {
|
||||
padding: 4px 12px;
|
||||
color: #fff;
|
||||
font-size: $log-font-size;
|
||||
}
|
||||
}
|
||||
|
||||
// 下拉框
|
||||
.ant-select {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: block;
|
||||
margin-top: 1px;
|
||||
|
||||
:deep(.ant-select-selector) {
|
||||
height: 100%;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
background-color: unset;
|
||||
}
|
||||
:deep(.ant-select-selection-search-input) {
|
||||
height: 100% !important;
|
||||
}
|
||||
:deep(.ant-select-selection-item) {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: $content-font-size;
|
||||
color: #adff2f;
|
||||
}
|
||||
:deep(.ant-select-selection-placeholder) {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: $content-font-size;
|
||||
color: #888;
|
||||
}
|
||||
|
||||
:deep(.ant-select-suffix svg) {
|
||||
width: 1.5em;
|
||||
height: 1.5em;
|
||||
color: #fff;
|
||||
}
|
||||
gap: 4px;
|
||||
}
|
||||
@@ -1,2 +1,3 @@
|
||||
@forward './base';
|
||||
@forward './variables';
|
||||
@forward './ant-design';
|
||||
@@ -41,7 +41,7 @@ defineExpose({
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import '@/assets/styles/_variables.scss';
|
||||
@use "@/assets/styles/variables" as *;
|
||||
|
||||
.status-item {
|
||||
display: flex;
|
||||
|
||||
161
src/components/LmsStatus/index.vue
Normal file
161
src/components/LmsStatus/index.vue
Normal file
@@ -0,0 +1,161 @@
|
||||
<template>
|
||||
<!-- Status Item -->
|
||||
<div class="status-item status-button" @click="show">
|
||||
<i-lucide-zap class="status-icon" />
|
||||
<span class="status-label">LMS 状态:</span>
|
||||
<span class="status-value" :class="onlineStatusClass">{{ lmsStatus }}</span>
|
||||
</div>
|
||||
|
||||
<a-modal v-model:open="dialogVisible" :title="modalTitle" :footer="null">
|
||||
<a-row :gutter="[0, 12]">
|
||||
<a-col :span="8" class="modal-label">LMS 状态</a-col>
|
||||
<a-col :span="16" class="modal-value">
|
||||
<a-switch v-model:checked="isOnline" checked-children="在线" un-checked-children="离线" @change="handleToggleOnline" />
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="[0, 12]">
|
||||
<template v-for="(item, index) in modalItems" :key="index">
|
||||
<a-col :span="8" class="modal-label">{{ item.label }}</a-col>
|
||||
<a-col :span="16" class="modal-value">{{ item.value }}</a-col>
|
||||
</template>
|
||||
</a-row>
|
||||
<div class="actions">
|
||||
<a-button size="large" @click="redirectTo('L1')">L1 数据</a-button>
|
||||
<a-button size="large" @click="redirectTo('L4')">L4 数据</a-button>
|
||||
</div>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, computed } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { useDialog } from '@/utils/useDialog';
|
||||
import { fetchLmsWorkMode, updateLmsWorkMode } from '@/api/lms';
|
||||
import { message } from 'ant-design-vue';
|
||||
|
||||
// useDialog管理弹窗状态
|
||||
const { visible: dialogVisible, show, hide } = useDialog();
|
||||
|
||||
const isOnline = ref(false);
|
||||
const lmsStatus = computed(() => isOnline.value ? '在线' : '离线');
|
||||
|
||||
const onlineStatusClass = computed(() => {
|
||||
return isOnline.value ? 'success' : 'error';
|
||||
});
|
||||
|
||||
// 当请求发送成功后才切换状态
|
||||
async function handleToggleOnline(checked: boolean | string | number) {
|
||||
await updateLmsWorkMode(checked ? 1 : 0).then(() => {
|
||||
isOnline.value = Boolean(checked);
|
||||
message.success('切换成功');
|
||||
}).catch((error) => {
|
||||
message.error('切换失败');
|
||||
});
|
||||
}
|
||||
|
||||
const modalTitle = ref('LMS 状态');
|
||||
const modalItems = ref<{ label: string; value: string }[]>([]);
|
||||
|
||||
// 初始化 LMS 状态
|
||||
async function initLmsStatus() {
|
||||
try {
|
||||
const { msg } = await fetchLmsWorkMode();
|
||||
isOnline.value = msg === "1";
|
||||
} catch (error) {
|
||||
console.error('获取 LMS 工作模式失败:', error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const router = useRouter();
|
||||
function redirectTo(type: string) {
|
||||
router.push(`/${type}-data`);
|
||||
}
|
||||
|
||||
// 初始化 LMS 状态
|
||||
onMounted(initLmsStatus);
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
show,
|
||||
hide
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@use "@/assets/styles/variables" as *;
|
||||
|
||||
.status-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 8px 12px;
|
||||
border-radius: 6px;
|
||||
transition: all 0.2s ease;
|
||||
|
||||
&.status-button {
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
.status-icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
color: #8395B6;
|
||||
|
||||
&.success {
|
||||
color: $success-color;
|
||||
}
|
||||
|
||||
&.error {
|
||||
color: $error-color;
|
||||
}
|
||||
|
||||
&.warning {
|
||||
color: $warning-color;
|
||||
}
|
||||
}
|
||||
|
||||
.status-label {
|
||||
font-size: 13px;
|
||||
color: #8395B6;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.status-value {
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
|
||||
&.success {
|
||||
color: $success-color;
|
||||
}
|
||||
|
||||
&.error {
|
||||
color: $error-color;
|
||||
}
|
||||
|
||||
&.warning {
|
||||
color: $warning-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.modal-label {
|
||||
font-size: $text-size;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.actions {
|
||||
margin: 20px 0 10px;
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
justify-content: space-between;
|
||||
|
||||
.ant-btn {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -42,7 +42,7 @@ defineExpose({
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import '@/assets/styles/_variables.scss';
|
||||
@use "@/assets/styles/variables" as *;
|
||||
|
||||
.status-item {
|
||||
display: flex;
|
||||
|
||||
@@ -54,7 +54,7 @@ defineExpose({
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import '@/assets/styles/_variables.scss';
|
||||
@use "@/assets/styles/variables" as *;
|
||||
|
||||
.status-item {
|
||||
display: flex;
|
||||
|
||||
@@ -42,7 +42,7 @@ defineExpose({
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import '@/assets/styles/_variables.scss';
|
||||
@use "@/assets/styles/variables" as *;
|
||||
|
||||
.status-item {
|
||||
display: flex;
|
||||
|
||||
@@ -45,7 +45,7 @@ defineExpose({
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import '@/assets/styles/_variables.scss';
|
||||
@use "@/assets/styles/variables" as *;
|
||||
|
||||
.modal-label {
|
||||
font-size: $text-size;
|
||||
|
||||
@@ -27,10 +27,6 @@
|
||||
<i-lucide-trash-2 />
|
||||
清空日志
|
||||
</a-button>
|
||||
<a-button @click="test" class="clear-btn">
|
||||
<i-lucide-trash-2 />
|
||||
测试
|
||||
</a-button>
|
||||
</div>
|
||||
|
||||
<div class="sse-logs" ref="logContainer">
|
||||
@@ -81,16 +77,14 @@ let cooldownTimer: number | null = null;
|
||||
|
||||
// 内部日志管理
|
||||
const logContainer = ref();
|
||||
function test() {
|
||||
addSseLog('测试日志');
|
||||
}
|
||||
|
||||
// 使用SSE工具函数
|
||||
const {
|
||||
clientId,
|
||||
serverUrl,
|
||||
isConnected,
|
||||
isConnecting,
|
||||
sseStatusText,
|
||||
sseStatus,
|
||||
sseStatusClass,
|
||||
logs,
|
||||
connect,
|
||||
@@ -127,12 +121,11 @@ const {
|
||||
}
|
||||
});
|
||||
|
||||
const sseStatus = ref(sseStatusText.value);
|
||||
const modalTitle = ref('SSE 连接状态');
|
||||
const modalItems = ref([
|
||||
{ label: '当前状态', value: sseStatus.value },
|
||||
{ label: '当前状态', value: sseStatus },
|
||||
{ label: '客户端ID', value: clientId || 'hmi-main-client' },
|
||||
{ label: '服务器地址', value: serverUrl.value }
|
||||
{ label: '服务器地址', value: serverUrl }
|
||||
]);
|
||||
|
||||
// 启动连接冷却时间
|
||||
@@ -175,6 +168,7 @@ const handleClearSseLogs = () => {
|
||||
|
||||
// 监听日志变化,自动滚动
|
||||
watch(() => logs.value.length, () => {
|
||||
if (logContainer.value) {
|
||||
const { scrollTop = 0, scrollHeight = 0, clientHeight = 0 } = logContainer.value;
|
||||
const isUserAtBottom = scrollTop + clientHeight >= scrollHeight - 10;
|
||||
nextTick(() => {
|
||||
@@ -182,6 +176,7 @@ watch(() => logs.value.length, () => {
|
||||
logContainer.value.scrollTop = logContainer.value.scrollHeight;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// 暴露方法和数据
|
||||
@@ -207,7 +202,7 @@ onBeforeUnmount(() => {
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import '@/assets/styles/_variables.scss';
|
||||
@use "@/assets/styles/variables" as *;
|
||||
|
||||
.status-item {
|
||||
display: flex;
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
{
|
||||
"id": "主键",
|
||||
"processInfoId": "加工信息ID",
|
||||
"pltNo": "PLT No",
|
||||
"processF1": "加工F1",
|
||||
"processF2": "加工F2",
|
||||
"goodProductF1": "良品F1",
|
||||
"goodProductF2": "良品F2",
|
||||
"electricalResult": "电气检测结果",
|
||||
"engraveResult": "印字检测结果",
|
||||
"qrCode": "二维码",
|
||||
"qrCodeLevel": "二维码等级",
|
||||
"pressure15Riveting": "压力1_5#_铆接",
|
||||
"height15Riveting": "高度1_5#_铆接",
|
||||
"pressure25Magnet1": "压力2_5#_磁石1",
|
||||
"height25Magnet1": "高度2_5#_磁石1",
|
||||
"pressure36Magnet2": "压力3_6#_磁石2",
|
||||
"height36Magnet2": "高度3_6#_磁石2",
|
||||
"torque47AxisInsert": "扭矩4_7#_轴旋入",
|
||||
"height47AxisInsert": "高度4_7#_轴旋入",
|
||||
"pressure58LowerCase": "压力5_8#_下壳装入",
|
||||
"height58LowerCase": "高度5_8#_下壳装入",
|
||||
"pressure69UpperCase": "压力6_9#_上壳装入",
|
||||
"height69UpperCase": "高度6_9#_上壳装入",
|
||||
"height79HeightCheck": "高度7_9#_高度检测",
|
||||
"pressure79Laser": "压力7_9#_激光",
|
||||
"height89Laser": "高度8_9#_激光",
|
||||
"value19DcrUpper": "数値1_9#_DCR(上)",
|
||||
"value29DcrLower": "数値2_9#_DCR(下)",
|
||||
"value39LcrUpperLs": "数値3_9#_LCR(上)LS",
|
||||
"value49LcrLowerQ": "数値4_9#_LCR(下)Q",
|
||||
"value59LcrLowerLs": "数値5_9#_LCR(下)LS",
|
||||
"value69LcrLowerQ": "数値6_9#_LCR(下)Q",
|
||||
"value79IrR": "数値7_9#_IR R",
|
||||
"value89IrI": "数値8_9#_IR I",
|
||||
"createTime": "创建时间"
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
import { createApp } from "vue";
|
||||
// import Antd from "ant-design-vue";
|
||||
import App from "./App.vue";
|
||||
|
||||
// Pinia 状态管理
|
||||
@@ -11,7 +10,7 @@ import router from "./router";
|
||||
|
||||
// 样式文件
|
||||
import "ant-design-vue/dist/reset.css";
|
||||
import "./assets/styles/index.scss";
|
||||
import "@/assets/styles/index.scss";
|
||||
|
||||
const app = createApp(App);
|
||||
app.use(pinia).use(router).mount("#app");
|
||||
|
||||
@@ -15,6 +15,16 @@ const routes = [
|
||||
path: '/package-station',
|
||||
name: 'PackageStation',
|
||||
component: () => import('@/views/package-station/index.vue')
|
||||
},
|
||||
{
|
||||
path: '/L1-data',
|
||||
name: 'L1Data',
|
||||
component: () => import('@/views/L1-data-list/index.vue')
|
||||
},
|
||||
{
|
||||
path: '/L4-data',
|
||||
name: 'L4Data',
|
||||
component: () => import('@/views/L4-data-list/index.vue')
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
5
src/shim-vue.d.ts
vendored
Normal file
5
src/shim-vue.d.ts
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
declare module "*.vue" {
|
||||
import type { DefineComponent } from "vue";
|
||||
const component: DefineComponent<{}, {}, any>;
|
||||
export default component;
|
||||
}
|
||||
@@ -3,7 +3,8 @@ import { EventSourcePolyfill } from 'event-source-polyfill';
|
||||
import { generateUUID } from './uuidUtils';
|
||||
import { getToken } from '@/utils/auth';
|
||||
|
||||
const defaultServerUrl = 'http://192.168.1.38:18081/sse';
|
||||
// const defaultServerUrl = 'http://192.168.1.38:18081/sse';
|
||||
const defaultServerUrl = 'http://127.0.0.1:18081/sse';
|
||||
|
||||
interface EventData {
|
||||
timestamp: string;
|
||||
@@ -66,7 +67,7 @@ export function useSSE(options: SSEOptions) {
|
||||
let connectionTimeout: number | null = null;
|
||||
|
||||
// 计算属性
|
||||
const sseStatusText = computed(() => {
|
||||
const sseStatus = computed(() => {
|
||||
if (isConnecting.value) return '连接中';
|
||||
if (isConnected.value) return '已连接';
|
||||
return '未连接';
|
||||
@@ -234,7 +235,7 @@ export function useSSE(options: SSEOptions) {
|
||||
isConnected,
|
||||
clientId,
|
||||
serverUrl,
|
||||
sseStatusText,
|
||||
sseStatus,
|
||||
sseStatusClass,
|
||||
connect,
|
||||
disconnect,
|
||||
|
||||
48
src/views/L1-data-list/data.ts
Normal file
48
src/views/L1-data-list/data.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import type { TableColumnType, TableColumnsType } from "ant-design-vue";
|
||||
|
||||
const INDEX_COLUMN: TableColumnType = {
|
||||
key: "index",
|
||||
title: "序号",
|
||||
width: 60,
|
||||
fixed: true,
|
||||
align: "center",
|
||||
} as const;
|
||||
|
||||
// 定义操作列配置
|
||||
const ACTION_COLUMN: TableColumnType = {
|
||||
key: "action",
|
||||
title: "操作",
|
||||
width: 120,
|
||||
ellipsis: true,
|
||||
fixed: "right",
|
||||
align: "center",
|
||||
} as const;
|
||||
|
||||
// 使用 Record 类型确保键值对的安全性
|
||||
export const fields: Record<string, string> = {
|
||||
productStatus: "产品状态",
|
||||
goodFlag: "良品标记",
|
||||
processMemory: "加工记忆",
|
||||
functionSw: "功能SW",
|
||||
axisNumber: "轴号",
|
||||
plugTerminalPressure: "插端子压力值",
|
||||
plugTerminalHeight: "插端子高度值",
|
||||
resistance: "电阻值",
|
||||
inductorLs: "电感LS值",
|
||||
inductorQ: "电感Q值",
|
||||
pressureResistanceR: "耐压R值",
|
||||
pressureResistanceI: "耐压I值",
|
||||
visualResult: "视觉结果",
|
||||
createTime: "创建时间",
|
||||
} as const;
|
||||
|
||||
// 导出完整的列配置
|
||||
export const columns: TableColumnsType = [
|
||||
INDEX_COLUMN,
|
||||
...Object.entries(fields).map(([key, title]) => ({
|
||||
key,
|
||||
title,
|
||||
ellipsis: true,
|
||||
})),
|
||||
ACTION_COLUMN,
|
||||
];
|
||||
@@ -0,0 +1,347 @@
|
||||
<template>
|
||||
<div class="l1-data-container">
|
||||
<div class="page-header">
|
||||
<h1 class="page-title">L1数据列表</h1>
|
||||
</div>
|
||||
|
||||
<!-- 筛选区域 -->
|
||||
<div class="filter-section">
|
||||
<a-form layout="inline" :model="formData">
|
||||
<a-form-item label="日期范围">
|
||||
<a-range-picker v-model:value="formData.dateRange" :placeholder="['开始日期', '结束日期']"
|
||||
format="YYYY-MM-DD hh:mm:ss" class="date-range-picker" show-time />
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-space>
|
||||
<a-button type="primary" @click="handleSearch" :loading="loading">
|
||||
<template #icon>
|
||||
<i-lucide-search />
|
||||
</template>
|
||||
搜索
|
||||
</a-button>
|
||||
<a-button @click="handleReset">
|
||||
<template #icon>
|
||||
<i-lucide-refresh-cw />
|
||||
</template>
|
||||
重置
|
||||
</a-button>
|
||||
</a-space>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</div>
|
||||
|
||||
<!-- 数据表格 -->
|
||||
<div class="table-section">
|
||||
<a-table :columns="columns" :data-source="tableData" :loading="loading" :pagination="pagination"
|
||||
@change="handleTableChange" row-key="id" size="middle" :scroll="{ x: 1200 }">
|
||||
<template #bodyCell="{ column, record, index }">
|
||||
<template v-if="column.key === 'index'">{{ index + 1 }}</template>
|
||||
<template v-else-if="column.key === 'createTime'">
|
||||
<span>{{ formatDateTime(record.createTime) }}</span>
|
||||
</template>
|
||||
<!-- <template v-else-if="column.key === 'productStatus'">
|
||||
<a-tag :color="record.productStatus === 1 ? 'success' : 'default'">
|
||||
{{ record.productStatus === 1 ? '有' : '无' }}
|
||||
</a-tag>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'goodFlag'">
|
||||
<a-tag :color="record.goodFlag === 1 ? 'success' : 'error'">
|
||||
{{ record.goodFlag === 1 ? '良品' : '不良品' }}
|
||||
</a-tag>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'processMemory'">
|
||||
<a-tag :color="record.processMemory === 1 ? 'success' : 'default'">
|
||||
{{ record.processMemory === 1 ? '已加工' : '未开工' }}
|
||||
</a-tag>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'functionSw'">
|
||||
<a-tag :color="record.functionSw === 1 ? 'success' : 'default'">
|
||||
{{ record.functionSw === 1 ? '有效' : '无效' }}
|
||||
</a-tag>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'visualResult'">
|
||||
<a-tag :color="record.visualResult === 1 ? 'success' : 'error'">
|
||||
{{ record.visualResult === 1 ? 'OK' : 'NG' }}
|
||||
</a-tag>
|
||||
</template> -->
|
||||
<template v-else-if="column.key === 'action'">
|
||||
<a-button type="link" size="small" @click="handleView(record as L1Data)">
|
||||
查看详情
|
||||
</a-button>
|
||||
</template>
|
||||
<template v-else>
|
||||
{{ record[column.key as string] }}
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
</div>
|
||||
|
||||
<!-- 详情弹窗 -->
|
||||
<a-modal v-model:open="detailVisible" title="详情信息" :footer="null" width="800px">
|
||||
<div v-if="selectedRecord" class="detail-content">
|
||||
<a-descriptions :column="2" bordered>
|
||||
<a-descriptions-item
|
||||
v-for="(value, key) in selectedRecord"
|
||||
:key="key"
|
||||
:label="columns.find((col) => col.key === key)?.title || key"
|
||||
>
|
||||
<template v-if="key === 'createTime'">
|
||||
{{ formatDateTime(value) }}
|
||||
</template>
|
||||
<!-- <template v-else-if="key === 'productStatus'">
|
||||
<a-tag :color="selectedRecord.productStatus === 1 ? 'success' : 'default'">
|
||||
{{ selectedRecord.productStatus === 1 ? '有' : '无' }}
|
||||
</a-tag>
|
||||
</template>
|
||||
<template v-else-if="key === 'goodFlag'">
|
||||
<a-tag :color="selectedRecord.goodFlag === 1 ? 'success' : 'error'">
|
||||
{{ selectedRecord.goodFlag === 1 ? '良品' : '不良品' }}
|
||||
</a-tag>
|
||||
</template>
|
||||
<template v-else-if="key === 'processMemory'">
|
||||
<a-tag :color="selectedRecord.processMemory === 1 ? 'success' : 'default'">
|
||||
{{ selectedRecord.processMemory === 1 ? '已加工' : '未开工' }}
|
||||
</a-tag>
|
||||
</template>
|
||||
<template v-else-if="key === 'functionSw'">
|
||||
<a-tag :color="selectedRecord.functionSw === 1 ? 'success' : 'default'">
|
||||
{{ selectedRecord.functionSw === 1 ? '有效' : '无效' }}
|
||||
</a-tag>
|
||||
</template>
|
||||
<template v-else-if="key === 'visualResult'">
|
||||
<a-tag :color="selectedRecord.visualResult === 1 ? 'success' : 'error'">
|
||||
{{ selectedRecord.visualResult === 1 ? 'OK' : 'NG' }}
|
||||
</a-tag>
|
||||
</template> -->
|
||||
<template v-else>
|
||||
{{ value }}
|
||||
</template>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</div>
|
||||
</a-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted } from "vue";
|
||||
import { message } from "ant-design-vue";
|
||||
import { getL1Data } from "@/api/data";
|
||||
import type { QueryParams } from "@/api/data/model";
|
||||
import type { L1Data } from "./types";
|
||||
import type { Dayjs } from "dayjs";
|
||||
import { columns } from "./data";
|
||||
|
||||
type DateRangeType = [Dayjs, Dayjs] | undefined;
|
||||
|
||||
// 响应式数据
|
||||
const loading = ref(false);
|
||||
const tableData = ref<L1Data[]>([]);
|
||||
const formData = reactive<{ dateRange: DateRangeType }>({
|
||||
dateRange: undefined,
|
||||
});
|
||||
const detailVisible = ref(false);
|
||||
const selectedRecord = ref<L1Data | null>(null);
|
||||
|
||||
// 分页配置
|
||||
const pagination = reactive({
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
showSizeChanger: true,
|
||||
showQuickJumper: true,
|
||||
showTotal: (total: number) => `共 ${total} 条`,
|
||||
pageSizeOptions: ["10", "20", "50", "100"],
|
||||
});
|
||||
|
||||
// 获取数据
|
||||
const fetchData = async () => {
|
||||
loading.value = true;
|
||||
try {
|
||||
const params: QueryParams = {
|
||||
pageNum: pagination.current,
|
||||
pageSize: pagination.pageSize,
|
||||
};
|
||||
|
||||
// 添加日期范围筛选
|
||||
if (formData.dateRange && formData.dateRange.length === 2) {
|
||||
params.createTimeBegin = formData.dateRange[0].format("YYYY-MM-DD hh:mm:ss");
|
||||
params.createTimeEnd = formData.dateRange[1].format("YYYY-MM-DD hh:mm:ss");
|
||||
}
|
||||
|
||||
const res = await getL1Data(params);
|
||||
|
||||
if (res.code === 200) {
|
||||
tableData.value = res.rows || [];
|
||||
pagination.total = res.total || 0;
|
||||
} else {
|
||||
message.error(res.msg || "获取数据失败");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("获取L1数据失败:", error);
|
||||
message.error("获取数据失败,请稍后重试");
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 搜索处理
|
||||
const handleSearch = () => {
|
||||
pagination.current = 1;
|
||||
fetchData();
|
||||
};
|
||||
|
||||
// 重置处理
|
||||
const handleReset = () => {
|
||||
formData.dateRange = undefined;
|
||||
pagination.current = 1;
|
||||
fetchData();
|
||||
};
|
||||
|
||||
// 表格变化处理(分页、排序等)
|
||||
const handleTableChange = (pag: any, filters: any, sorter: any) => {
|
||||
pagination.current = pag.current;
|
||||
pagination.pageSize = pag.pageSize;
|
||||
|
||||
// 处理排序
|
||||
if (sorter.field) {
|
||||
// 这里可以根据需要添加排序逻辑
|
||||
}
|
||||
|
||||
fetchData();
|
||||
};
|
||||
|
||||
// 查看详情
|
||||
const handleView = (record: L1Data) => {
|
||||
selectedRecord.value = record;
|
||||
detailVisible.value = true;
|
||||
};
|
||||
|
||||
// 格式化日期时间
|
||||
const formatDateTime = (dateTime: string | number) => {
|
||||
if (!dateTime) return null;
|
||||
return new Date(dateTime).toLocaleString('zh-CN', {
|
||||
year: 'numeric',
|
||||
month: '2-digit',
|
||||
day: '2-digit',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
second: '2-digit',
|
||||
});
|
||||
};
|
||||
|
||||
// 组件挂载时获取数据
|
||||
onMounted(() => {
|
||||
fetchData();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@use "@/assets/styles/variables" as *;
|
||||
|
||||
.wrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.l1-data-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100vh;
|
||||
padding: $spacing-lg;
|
||||
|
||||
.page-header {
|
||||
margin-bottom: $spacing-lg;
|
||||
flex-shrink: 0;
|
||||
|
||||
.page-title {
|
||||
font-size: $title-font-size;
|
||||
color: $text-dark;
|
||||
margin: 0;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
.filter-section {
|
||||
background: $bg-light;
|
||||
padding: $spacing-lg;
|
||||
border-radius: $border-radius-lg;
|
||||
margin-bottom: $spacing-lg;
|
||||
flex-shrink: 0;
|
||||
|
||||
.filter-label {
|
||||
font-weight: 500;
|
||||
color: $text-dark;
|
||||
font-size: $content-font-size;
|
||||
}
|
||||
}
|
||||
|
||||
.table-section {
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
:deep(.ant-table-wrapper) {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.ant-spin-container,
|
||||
.ant-table {
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.ant-table-container {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.ant-table-body {
|
||||
overflow-y: auto !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.detail-content {
|
||||
.ant-descriptions {
|
||||
margin-top: $spacing-md;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.ant-btn-primary) {
|
||||
background: $primary-color;
|
||||
border-color: $primary-color;
|
||||
|
||||
&:hover {
|
||||
background: $primary-light;
|
||||
border-color: $primary-light;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.l1-data-container {
|
||||
padding: $spacing-md;
|
||||
|
||||
.filter-section {
|
||||
.ant-row {
|
||||
flex-direction: column;
|
||||
gap: $spacing-md;
|
||||
|
||||
.ant-col {
|
||||
width: 100% !important;
|
||||
}
|
||||
}
|
||||
|
||||
.date-range-picker {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
58
src/views/L1-data-list/types.ts
Normal file
58
src/views/L1-data-list/types.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
export interface L1Data {
|
||||
/** 加工信息ID */
|
||||
processInfoId: number;
|
||||
|
||||
/** 产品状态: 0-无, 1-有 */
|
||||
productStatus: 0 | 1;
|
||||
|
||||
/** 良品标记: 0-不良品, 1-良品 */
|
||||
goodFlag: 0 | 1;
|
||||
|
||||
/** 加工记忆: 0-未开工, 1-已加工 */
|
||||
processMemory: 0 | 1;
|
||||
|
||||
/** 功能SW: 0-无效, 1-有效 */
|
||||
functionSw: 0 | 1;
|
||||
|
||||
/** 轴号 */
|
||||
axisNumber: number;
|
||||
|
||||
/** 上骨架时间: 年, 00~99 */
|
||||
loadSkeletonYear: number;
|
||||
|
||||
/** 上骨架时间: 月日, 0101~1231 */
|
||||
loadSkeletonMonthDay: number;
|
||||
|
||||
/** 上骨架时间: 时分, 0000~2459 */
|
||||
loadSkeletonHourMin: number;
|
||||
|
||||
/** 上骨架时间: 秒, 00~59 */
|
||||
loadSkeletonSecond: number;
|
||||
|
||||
/** 插端子压力值 */
|
||||
plugTerminalPressure: number;
|
||||
|
||||
/** 插端子高度值 */
|
||||
plugTerminalHeight: number;
|
||||
|
||||
/** 电阻值 */
|
||||
resistance: number;
|
||||
|
||||
/** 电感LS值 */
|
||||
inductorLs: number;
|
||||
|
||||
/** 电感Q值 */
|
||||
inductorQ: number;
|
||||
|
||||
/** 耐压R值 */
|
||||
pressureResistanceR: number;
|
||||
|
||||
/** 耐压I值 */
|
||||
pressureResistanceI: number;
|
||||
|
||||
/** 视觉结果: 0-NG, 1-OK */
|
||||
visualResult: 0 | 1;
|
||||
|
||||
/** 创建时间 */
|
||||
createTime: string; // ISO 8601 格式,如 "2025-09-23T12:34:56"
|
||||
}
|
||||
69
src/views/L4-data-list/data.ts
Normal file
69
src/views/L4-data-list/data.ts
Normal file
@@ -0,0 +1,69 @@
|
||||
import type { TableColumnType, TableColumnsType } from "ant-design-vue";
|
||||
|
||||
const INDEX_COLUMN: TableColumnType = {
|
||||
key: "index",
|
||||
title: "序号",
|
||||
width: 60,
|
||||
fixed: true,
|
||||
align: "center",
|
||||
} as const;
|
||||
|
||||
// 定义操作列配置
|
||||
const ACTION_COLUMN: TableColumnType = {
|
||||
key: "action",
|
||||
title: "操作",
|
||||
width: 120,
|
||||
ellipsis: true,
|
||||
fixed: "right",
|
||||
align: "center",
|
||||
} as const;
|
||||
|
||||
// 使用 Record 类型确保键值对的安全性
|
||||
export const fields: Record<string, string> = {
|
||||
processInfoId: "加工信息ID",
|
||||
pltNo: "PLT No",
|
||||
processF1: "加工F1",
|
||||
processF2: "加工F2",
|
||||
goodProductF1: "良品F1",
|
||||
goodProductF2: "良品F2",
|
||||
electricalResult: "电气检测结果",
|
||||
engraveResult: "印字检测结果",
|
||||
qrCode: "二维码",
|
||||
qrCodeLevel: "二维码等级",
|
||||
pressure15Riveting: "压力1_5#_铆接",
|
||||
height15Riveting: "高度1_5#_铆接",
|
||||
pressure25Magnet1: "压力2_5#_磁石1",
|
||||
height25Magnet1: "高度2_5#_磁石1",
|
||||
pressure36Magnet2: "压力3_6#_磁石2",
|
||||
height36Magnet2: "高度3_6#_磁石2",
|
||||
torque47AxisInsert: "扭矩4_7#_轴旋入",
|
||||
height47AxisInsert: "高度4_7#_轴旋入",
|
||||
pressure58LowerCase: "压力5_8#_下壳装入",
|
||||
height58LowerCase: "高度5_8#_下壳装入",
|
||||
pressure69UpperCase: "压力6_9#_上壳装入",
|
||||
height69UpperCase: "高度6_9#_上壳装入",
|
||||
height79HeightCheck: "高度7_9#_高度检测",
|
||||
pressure79Laser: "压力7_9#_激光",
|
||||
height89Laser: "高度8_9#_激光",
|
||||
value19DcrUpper: "数値1_9#_DCR(上)",
|
||||
value29DcrLower: "数値2_9#_DCR(下)",
|
||||
value39LcrUpperLs: "数値3_9#_LCR(上)LS",
|
||||
value49LcrLowerQ: "数値4_9#_LCR(下)Q",
|
||||
value59LcrLowerLs: "数値5_9#_LCR(下)LS",
|
||||
value69LcrLowerQ: "数値6_9#_LCR(下)Q",
|
||||
value79IrR: "数値7_9#_IR R",
|
||||
value89IrI: "数値8_9#_IR I",
|
||||
createTime: "创建时间"
|
||||
} as const;
|
||||
|
||||
// 导出完整的列配置
|
||||
export const columns: TableColumnsType = [
|
||||
INDEX_COLUMN,
|
||||
...Object.entries(fields).map(([key, title]) => ({
|
||||
key,
|
||||
title,
|
||||
width: 150,
|
||||
ellipsis: true,
|
||||
})),
|
||||
ACTION_COLUMN,
|
||||
];
|
||||
@@ -0,0 +1,336 @@
|
||||
<template>
|
||||
<div class="l4-data-container">
|
||||
<div class="page-header">
|
||||
<h1 class="page-title">L4数据列表</h1>
|
||||
</div>
|
||||
|
||||
<!-- 筛选区域 -->
|
||||
<div class="filter-section">
|
||||
<a-form layout="inline" :model="formData">
|
||||
<a-form-item label="日期范围">
|
||||
<a-range-picker
|
||||
v-model:value="formData.dateRange"
|
||||
:placeholder="['开始日期', '结束日期']"
|
||||
format="YYYY-MM-DD hh:mm:ss"
|
||||
class="date-range-picker"
|
||||
show-time
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-space>
|
||||
<a-button type="primary" @click="handleSearch" :loading="loading">
|
||||
<template #icon>
|
||||
<i-lucide-search />
|
||||
</template>
|
||||
搜索
|
||||
</a-button>
|
||||
<a-button @click="handleReset">
|
||||
<template #icon>
|
||||
<i-lucide-refresh-cw />
|
||||
</template>
|
||||
重置
|
||||
</a-button>
|
||||
</a-space>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</div>
|
||||
|
||||
<!-- 数据表格 -->
|
||||
<div class="table-section">
|
||||
<a-table
|
||||
:columns="columns"
|
||||
:data-source="tableData"
|
||||
:loading="loading"
|
||||
:pagination="pagination"
|
||||
@change="handleTableChange"
|
||||
row-key="id"
|
||||
size="middle"
|
||||
:scroll="{ x: 1200 }"
|
||||
>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'createTime'">
|
||||
{{ formatDateTime(record.createTime) }}
|
||||
</template>
|
||||
<!-- <template v-else-if="column.key === 'processF1'">
|
||||
<a-tag :color="record.processF1 === 1 ? 'green' : 'red'">
|
||||
{{ record.processF1 === 1 ? '已加工' : '未加工' }}
|
||||
</a-tag>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'processF2'">
|
||||
<a-tag :color="record.processF2 === 1 ? 'green' : 'red'">
|
||||
{{ record.processF2 === 1 ? '已加工' : '未加工' }}
|
||||
</a-tag>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'goodProductF1'">
|
||||
<a-tag :color="record.goodProductF1 === 1 ? 'green' : 'red'">
|
||||
{{ record.goodProductF1 === 1 ? '良品' : '不良品' }}
|
||||
</a-tag>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'goodProductF2'">
|
||||
<a-tag :color="record.goodProductF2 === 1 ? 'green' : 'red'">
|
||||
{{ record.goodProductF2 === 1 ? '良品' : '不良品' }}
|
||||
</a-tag>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'electricalResult'">
|
||||
<a-tag :color="getElectricalResultColor(record.electricalResult)">
|
||||
{{ getElectricalResultText(record.electricalResult) }}
|
||||
</a-tag>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'engraveResult'">
|
||||
<a-tag :color="record.engraveResult === 0 ? 'green' : 'red'">
|
||||
{{ record.engraveResult === 0 ? '良品' : '不良品' }}
|
||||
</a-tag>
|
||||
</template> -->
|
||||
<template v-else-if="column.key === 'action'">
|
||||
<a-button type="link" size="small" @click="handleView(record as L4Data)">
|
||||
查看详情
|
||||
</a-button>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
</div>
|
||||
|
||||
<!-- 详情弹窗 -->
|
||||
<a-modal
|
||||
v-model:open="detailModalVisible"
|
||||
title="L4数据详情"
|
||||
width="800px"
|
||||
:footer="null"
|
||||
>
|
||||
<div v-if="selectedRecord" class="detail-content">
|
||||
<a-descriptions :column="2" bordered>
|
||||
<a-descriptions-item
|
||||
v-for="(value, key) in selectedRecord"
|
||||
:key="key"
|
||||
:label="columns.find((col) => col.key === key)?.title || key"
|
||||
>
|
||||
<template v-if="key === 'createTime'">
|
||||
{{ formatDateTime(value) }}
|
||||
</template>
|
||||
<!-- <template v-else-if="key === 'processF1'">
|
||||
<a-tag :color="value === 1 ? 'green' : 'red'">
|
||||
{{ value === 1 ? '已加工' : '未加工' }}
|
||||
</a-tag>
|
||||
</template>
|
||||
<template v-else-if="key === 'processF2'">
|
||||
<a-tag :color="value === 1 ? 'green' : 'red'">
|
||||
{{ value === 1 ? '已加工' : '未加工' }}
|
||||
</a-tag>
|
||||
</template>
|
||||
<template v-else-if="key === 'goodProductF1'">
|
||||
<a-tag :color="value === 1 ? 'green' : 'red'">
|
||||
{{ value === 1 ? '良品' : '不良品' }}
|
||||
</a-tag>
|
||||
</template>
|
||||
<template v-else-if="key === 'goodProductF2'">
|
||||
<a-tag :color="value === 1 ? 'green' : 'red'">
|
||||
{{ value === 1 ? '良品' : '不良品' }}
|
||||
</a-tag>
|
||||
</template>
|
||||
<template v-else-if="key === 'electricalResult'">
|
||||
<a-tag :color="getElectricalResultColor(value)">
|
||||
{{ getElectricalResultText(value) }}
|
||||
</a-tag>
|
||||
</template>
|
||||
<template v-else-if="key === 'engraveResult'">
|
||||
<a-tag :color="value === 0 ? 'green' : 'red'">
|
||||
{{ value === 0 ? '良品' : '不良品' }}
|
||||
</a-tag>
|
||||
</template> -->
|
||||
<template v-else>
|
||||
{{ value }}
|
||||
</template>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</div>
|
||||
</a-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, computed, onMounted } from 'vue';
|
||||
import { message } from 'ant-design-vue';
|
||||
import { getL4Data } from '@/api/data';
|
||||
import { columns } from './data';
|
||||
import type { QueryParams } from '@/api/data/model';
|
||||
import type { L4Data } from './types';
|
||||
import type { Dayjs } from 'dayjs';
|
||||
|
||||
type DateRangeType = [Dayjs, Dayjs] | undefined;
|
||||
|
||||
// 响应式数据
|
||||
const loading = ref(false);
|
||||
const tableData = ref<L4Data[]>([]);
|
||||
const detailModalVisible = ref(false);
|
||||
const selectedRecord = ref<L4Data | null>(null);
|
||||
|
||||
// 筛选参数
|
||||
const formData = reactive<{ dateRange: DateRangeType }>({
|
||||
dateRange: undefined,
|
||||
});
|
||||
|
||||
// 分页配置
|
||||
const pagination = reactive({
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
showSizeChanger: true,
|
||||
showQuickJumper: true,
|
||||
showTotal: (total: number, range: [number, number]) =>
|
||||
`共 ${total} 条记录,当前显示第 ${range[0]}-${range[1]} 条`,
|
||||
});
|
||||
|
||||
// 电气检测结果颜色
|
||||
const getElectricalResultColor = (result: number) => {
|
||||
switch (result) {
|
||||
case 7: return 'green';
|
||||
case 0: return 'red';
|
||||
case 1: return 'orange';
|
||||
case 3: return 'purple';
|
||||
default: return 'default';
|
||||
}
|
||||
};
|
||||
|
||||
// 电气检测结果文本
|
||||
const getElectricalResultText = (result: number) => {
|
||||
switch (result) {
|
||||
case 0: return 'DCR不良';
|
||||
case 1: return 'LCR不良';
|
||||
case 3: return 'IR不良';
|
||||
case 7: return '良品';
|
||||
default: return '未知';
|
||||
}
|
||||
};
|
||||
|
||||
// 获取数据
|
||||
const fetchData = async () => {
|
||||
loading.value = true;
|
||||
try {
|
||||
const params: QueryParams = {
|
||||
pageNum: pagination.current,
|
||||
pageSize: pagination.pageSize,
|
||||
};
|
||||
|
||||
// 添加日期范围筛选
|
||||
if (formData.dateRange && formData.dateRange.length === 2) {
|
||||
params.createTimeBegin = formData.dateRange[0].format("YYYY-MM-DD hh:mm:ss");
|
||||
params.createTimeEnd = formData.dateRange[1].format("YYYY-MM-DD hh:mm:ss");
|
||||
}
|
||||
|
||||
const response = await getL4Data(params);
|
||||
|
||||
if (response.code === 200) {
|
||||
tableData.value = response.rows || [];
|
||||
pagination.total = response.total || 0;
|
||||
} else {
|
||||
message.error(response.msg || "获取数据失败");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("获取L4数据失败:", error);
|
||||
message.error("获取数据失败,请稍后重试");
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 搜索处理
|
||||
const handleSearch = () => {
|
||||
pagination.current = 1;
|
||||
fetchData();
|
||||
};
|
||||
|
||||
// 重置处理
|
||||
const handleReset = () => {
|
||||
formData.dateRange = undefined;
|
||||
pagination.current = 1;
|
||||
fetchData();
|
||||
};
|
||||
|
||||
// 表格变化处理(分页、排序等)
|
||||
const handleTableChange = (paginationInfo: any) => {
|
||||
pagination.current = paginationInfo.current;
|
||||
pagination.pageSize = paginationInfo.pageSize;
|
||||
fetchData();
|
||||
};
|
||||
|
||||
// 查看详情
|
||||
const handleView = (record: L4Data) => {
|
||||
selectedRecord.value = record;
|
||||
detailModalVisible.value = true;
|
||||
};
|
||||
|
||||
// 日期时间格式化
|
||||
const formatDateTime = (dateTime: string | number) => {
|
||||
if (!dateTime) return '-';
|
||||
return new Date(dateTime).toLocaleString('zh-CN', {
|
||||
year: 'numeric',
|
||||
month: '2-digit',
|
||||
day: '2-digit',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
second: '2-digit',
|
||||
});
|
||||
};
|
||||
|
||||
// 组件挂载时获取数据
|
||||
onMounted(() => {
|
||||
fetchData();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.l4-data-container {
|
||||
padding: 20px;
|
||||
background: #f5f5f5;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.page-header {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
color: #1f2937;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.filter-section {
|
||||
background: white;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.date-range-picker {
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
.table-section {
|
||||
background: white;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.detail-content {
|
||||
max-height: 500px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
:deep(.ant-table-thead > tr > th) {
|
||||
background: #f8fafc;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
:deep(.ant-table-tbody > tr:hover > td) {
|
||||
background: #f0f9ff;
|
||||
}
|
||||
|
||||
:deep(.ant-descriptions-item-label) {
|
||||
font-weight: 600;
|
||||
background: #f8fafc;
|
||||
}
|
||||
</style>
|
||||
106
src/views/L4-data-list/types.ts
Normal file
106
src/views/L4-data-list/types.ts
Normal file
@@ -0,0 +1,106 @@
|
||||
export interface L4Data {
|
||||
/** 加工信息ID */
|
||||
processInfoId: number;
|
||||
|
||||
/** PLT No */
|
||||
pltNo: number;
|
||||
|
||||
/** 加工F1, 0:未加工 */
|
||||
processF1: 0 | 1;
|
||||
|
||||
/** 加工F2, 1:已加工 */
|
||||
processF2: 0 | 1;
|
||||
|
||||
/** 良品F1, 0:不良品 */
|
||||
goodProductF1: 0 | 1;
|
||||
|
||||
/** 良品F2, 1:良品 */
|
||||
goodProductF2: 0 | 1;
|
||||
|
||||
/**
|
||||
* 电气检测结果
|
||||
* 0-DCR不良, 1-LCR不良, 3-IR不良, 7-良品
|
||||
*/
|
||||
electricalResult: 0 | 1 | 3 | 7;
|
||||
|
||||
/** 印字检测结果, 0-良品, 1-不良品 */
|
||||
engraveResult: 0 | 1;
|
||||
|
||||
/** 二维码 */
|
||||
qrCode: string;
|
||||
|
||||
/** 二维码等级 */
|
||||
qrCodeLevel: string;
|
||||
|
||||
/** 压力1_5#_铆接 */
|
||||
pressure15Riveting: number;
|
||||
|
||||
/** 高度1_5#_铆接 */
|
||||
height15Riveting: number;
|
||||
|
||||
/** 压力2_5#_磁石1 */
|
||||
pressure25Magnet1: number;
|
||||
|
||||
/** 高度2_5#_磁石1 */
|
||||
height25Magnet1: number;
|
||||
|
||||
/** 压力3_6#_磁石2 */
|
||||
pressure36Magnet2: number;
|
||||
|
||||
/** 高度3_6#_磁石2 */
|
||||
height36Magnet2: number;
|
||||
|
||||
/** 扭矩4_7#_轴旋入 */
|
||||
torque47AxisInsert: number;
|
||||
|
||||
/** 高度4_7#_轴旋入 */
|
||||
height47AxisInsert: number;
|
||||
|
||||
/** 压力5_8#_下壳装入 */
|
||||
pressure58LowerCase: number;
|
||||
|
||||
/** 高度5_8#_下壳装入 */
|
||||
height58LowerCase: number;
|
||||
|
||||
/** 压力6_9#_上壳装入 */
|
||||
pressure69UpperCase: number;
|
||||
|
||||
/** 高度6_9#_上壳装入 */
|
||||
height69UpperCase: number;
|
||||
|
||||
/** 高度7_9#_高度检测 */
|
||||
height79HeightCheck: number;
|
||||
|
||||
/** 压力7_9#_激光 */
|
||||
pressure79Laser: number;
|
||||
|
||||
/** 高度8_9#_激光 */
|
||||
height89Laser: number;
|
||||
|
||||
/** 数値1_9#_DCR(上) */
|
||||
value19DcrUpper: number;
|
||||
|
||||
/** 数値2_9#_DCR(下) */
|
||||
value29DcrLower: number;
|
||||
|
||||
/** 数値3_9#_LCR(上)LS */
|
||||
value39LcrUpperLs: number;
|
||||
|
||||
/** 数値4_9#_LCR(下)Q */
|
||||
value49LcrLowerQ: number;
|
||||
|
||||
/** 数値5_9#_LCR(下)LS */
|
||||
value59LcrLowerLs: number;
|
||||
|
||||
/** 数値6_9#_LCR(下)Q */
|
||||
value69LcrLowerQ: number;
|
||||
|
||||
/** 数値7_9#_IR R */
|
||||
value79IrR: number;
|
||||
|
||||
/** 数値8_9#_IR I */
|
||||
value89IrI: number;
|
||||
|
||||
/** 创建时间 (ISO 8601) */
|
||||
createTime: string;
|
||||
}
|
||||
@@ -3,6 +3,7 @@ import { ref, onMounted, onBeforeUnmount, reactive, nextTick } from 'vue';
|
||||
import { useRealTime } from '@/utils/dateUtils';
|
||||
import { checkOrderNumberApi, addProcessInfoApi } from '@/api/detect';
|
||||
import type { Rule } from 'ant-design-vue/es/form';
|
||||
import { message } from 'ant-design-vue';
|
||||
|
||||
// 检测设备表单规则
|
||||
const rules: Record<string, Rule[]> = {
|
||||
@@ -44,23 +45,9 @@ const detectFormRef = ref();
|
||||
const packageFormRef = ref();
|
||||
|
||||
// 执行结果日志
|
||||
const executionLogs = ref([
|
||||
'14:25:32 - 开始检测流程 SN-A538-09-2023-00018',
|
||||
'14:25:33 - 读取产品参数完成',
|
||||
'14:25:36 - 尺寸检测: 通过 (0.15mm)',
|
||||
'14:25:36 - 电压检测: 通过 (3.25V)',
|
||||
'14:25:37 - 精度检测: 通过 (98.7%)',
|
||||
'14:25:38 - 检测结果: 合格'
|
||||
]);
|
||||
const executionLogs = ref<string[]>([]);
|
||||
|
||||
const packageLogs = ref([
|
||||
'14:25:45 - 包装流程: SN-A538-09-2023-00018',
|
||||
'14:25:46 - 读取产品标签完成',
|
||||
'14:25:49 - 包装材料准备完成',
|
||||
'14:25:52 - 产品包装完成',
|
||||
'14:25:53 - 更新库存: 已包装 (18/25)',
|
||||
'14:25:54 - 包装结果: 正常'
|
||||
]);
|
||||
const packageLogs = ref<string[]>([]);
|
||||
|
||||
// 滚动到检测设备日志底部的函数
|
||||
const scrollToExecutionBottom = () => {
|
||||
@@ -262,6 +249,7 @@ const saveDetectingEdit = () => {
|
||||
fixtureCode: detectForm.fixtureCode
|
||||
}).then(res => {
|
||||
console.log(res)
|
||||
message.success('保存成功');
|
||||
})
|
||||
}).catch(() => {
|
||||
console.log('检测设备表单验证失败');
|
||||
@@ -350,6 +338,9 @@ onBeforeUnmount(() => {
|
||||
:on-mes-event="handleMESEvent"
|
||||
:on-sse-message="handleSseMessage"
|
||||
/>
|
||||
|
||||
<!-- LMS 状态 -->
|
||||
<LmsStatus />
|
||||
</div>
|
||||
<SettingsModal />
|
||||
<!-- <div class="right-info" @click="showSettings">
|
||||
@@ -569,7 +560,7 @@ onBeforeUnmount(() => {
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import '@/assets/styles/_variables.scss';
|
||||
@use "@/assets/styles/variables" as *;
|
||||
|
||||
.hmi-container {
|
||||
width: 100vw;
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"composite": true,
|
||||
|
||||
/* Bundler mode */
|
||||
"noEmit": true,
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"verbatimModuleSyntax": true,
|
||||
@@ -21,6 +22,7 @@
|
||||
},
|
||||
"include": [
|
||||
"vite.config.ts",
|
||||
"src/**/*.d.ts"
|
||||
"src/**/*.d.ts",
|
||||
"src/shim-vue.d.ts"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { defineConfig, loadEnv } from 'vite';
|
||||
import { defineConfig } from 'vite';
|
||||
import Components from "unplugin-vue-components/vite"; // 按需组件自动导入
|
||||
import { AntDesignVueResolver } from "unplugin-vue-components/resolvers";
|
||||
import vue from '@vitejs/plugin-vue';
|
||||
@@ -8,19 +8,38 @@ import path from 'path';
|
||||
|
||||
// https://vite.dev/config/
|
||||
export default defineConfig({
|
||||
resolve: {
|
||||
alias: {
|
||||
"@": path.resolve(__dirname, "src"),
|
||||
},
|
||||
},
|
||||
server: {
|
||||
proxy: {
|
||||
"/api": {
|
||||
target: "http://192.168.1.38:18081",
|
||||
changeOrigin: true,
|
||||
rewrite: (path) => path.replace(/^\/api/, ""),
|
||||
},
|
||||
"/prod-api": {
|
||||
target: "http://127.0.0.1:18081",
|
||||
changeOrigin: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
vue(),
|
||||
Components({
|
||||
dts: true, //生成components.d.ts 全局定义文件
|
||||
resolvers: [
|
||||
AntDesignVueResolver({ //对使用到的全局ant design vue组件进行类型导入
|
||||
AntDesignVueResolver({
|
||||
//对使用到的全局ant design vue组件进行类型导入
|
||||
importStyle: false, // 不动态引入css,这个不强求
|
||||
}),
|
||||
// 自动导入 lucide 图标
|
||||
IconsResolver({
|
||||
prefix: 'i', // 比如用 <i-a-arrow-down />
|
||||
enabledCollections: ['lucide']
|
||||
})
|
||||
prefix: "i", // 比如用 <i-a-arrow-down />
|
||||
enabledCollections: ["lucide"],
|
||||
}),
|
||||
],
|
||||
include: [/\.vue$/, /\.vue\?vue/, /\.md$/, /\.tsx$/], //包含的文件类型
|
||||
}),
|
||||
@@ -28,18 +47,4 @@ export default defineConfig({
|
||||
autoInstall: true, // 没安装的图标库会自动下载
|
||||
}),
|
||||
],
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': path.resolve(__dirname, 'src'),
|
||||
},
|
||||
},
|
||||
server: {
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: 'http://192.168.1.38:18081',
|
||||
changeOrigin: true,
|
||||
rewrite: path => path.replace(/^\/api/, '')
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user