feat: 解决冲突

main
wangqiujuan0808 2025-05-13 08:08:32 +08:00
commit 6a477c778b
15 changed files with 948 additions and 14 deletions

View File

@ -1,5 +1,22 @@
import { cdcmRequestClient } from './request'; import { cdcmRequestClient } from './request';
export async function cdcmCDCMAPI(params, key) {
return cdcmRequestClient.post('/cdcm', params, {
responseReturn: 'data',
headers: {
action: key.code,
},
});
}
export async function cdcmRuleAPI(params, key) {
return cdcmRequestClient.post('/rule', params, {
responseReturn: 'data',
headers: {
action: key.code,
},
});
}
export async function cdcmTemplateAPI(params, key) { export async function cdcmTemplateAPI(params, key) {
return cdcmRequestClient.post('/template', params, { return cdcmRequestClient.post('/template', params, {
headers: { headers: {

View File

@ -0,0 +1,39 @@
import { cdcmRequestClient } from './request';
export interface action {
code: number;
}
export async function cdcmCDCMAPI(params: any, key: action) {
return cdcmRequestClient.post('/cdcm', params, {
responseReturn: 'data',
headers: {
action: key.code,
},
});
}
export async function cdcmRuleAPI(params: any, key: action) {
return cdcmRequestClient.post('/rule', params, {
responseReturn: 'data',
headers: {
action: key.code,
},
});
}
export async function cdcmTemplateAPI(params: any, key: action) {
return cdcmRequestClient.post('/template', params, {
headers: {
action: key.code,
},
});
}
export async function cdcmDriverAPI(params: any, key: action) {
return cdcmRequestClient.post('/driver', params, {
headers: {
action: key.code,
},
});
}

View File

@ -1,5 +1,57 @@
// 请求码 // 请求码
export default { export default {
CDCMGetNetworkInfo: {
code: 51_002,
desc: '获取网络信息',
},
CDCMGetSystemInfo: {
code: 51_001,
desc: '获取系统信息',
},
CDCMSetNetworkInfo: {
code: 51_003,
desc: '设置网络信息',
},
CruleAddFlow: {
code: 52_608,
desc: '添加规则引擎流程',
},
CruleDeleteFlow: {
code: 52_609,
desc: '删除规则引擎流程',
},
CruleGetFlows: {
code: 52_610,
desc: '获取规则引擎流程',
},
CruleGetVersion: {
code: 52_605,
desc: '获取规则引擎版本',
},
CruleInstall: {
code: 52_603,
desc: '安装规则引擎',
},
CruleStart: {
code: 52_601,
desc: '启动规则引擎',
},
CruleStartFlow: {
code: 52_606,
desc: '启动规则引擎流程',
},
CruleStop: {
code: 52_602,
desc: '停止规则引擎',
},
CruleStopFlow: {
code: 52_607,
desc: '停止规则引擎流程',
},
CruleUninstall: {
code: 52_604,
desc: '卸载规则引擎',
},
DeviceCreate: { DeviceCreate: {
code: 52_302, code: 52_302,
desc: '创建设备', desc: '创建设备',
@ -84,6 +136,14 @@ export default {
code: 52_024, code: 52_024,
desc: '删除模板点位', desc: '删除模板点位',
}, },
PointExport: {
code: 52_025,
desc: '导出模板点位',
},
PointImport: {
code: 52_026,
desc: '导入模板点位',
},
PointQueryAll: { PointQueryAll: {
code: 52_021, code: 52_021,
desc: '查询所有模板点位', desc: '查询所有模板点位',

View File

@ -0,0 +1,66 @@
import type { RequestClientOptions } from '@vben/request';
import { useAppConfig } from '@vben/hooks';
import { defaultResponseInterceptor, RequestClient } from '@vben/request';
import { useTokenStore } from '#/store';
const { apiURL } = useAppConfig(import.meta.env, import.meta.env.PROD);
function createCDCMRequestClient(
baseURL: string,
options?: RequestClientOptions,
) {
const client = new RequestClient({
...options,
baseURL,
});
client.addResponseInterceptor(
defaultResponseInterceptor({
codeField: 'code',
dataField: 'data',
successCode: 0,
}),
);
// 响应拦截器:自动更新 token
client.addResponseInterceptor({
fulfilled: (response) => {
const token = response.headers?.token;
if (token) {
// 如果响应头中有新 token自动更新 store
useTokenStore().setToken(token);
}
return response;
},
rejected: (error) => {
// 统一错误处理(如 token 过期)
if (error.response?.status === 401) {
useTokenStore().deleteToken();
// 这里要跳登录页面
}
return Promise.reject(error);
},
});
// 请求拦截器:自动添加 token
client.addRequestInterceptor({
fulfilled: (config) => {
const token = useTokenStore().token;
if (token) {
// 添加 CDCM 自定义头部
config.headers.set('cdcm', token, true);
}
return config;
},
rejected: (error) => {
// 请求错误处理
return Promise.reject(error);
},
});
return client;
}
export const cdcmRequestClient = createCDCMRequestClient(apiURL, {
responseReturn: 'data',
});

View File

@ -1,6 +1,32 @@
export default { import type { VxeGridProps } from '#/adapter/vxe-table';
const base: VxeGridProps['columns'] = [
{ field: 'name', title: '名称', width: 200 },
{ field: 'point_type', title: '类型', width: 150 },
{ field: 'access', title: '权限', width: 80 },
{ field: 'calculation', title: '公式', width: 100 },
{ field: 'unit', title: '单位', width: 150 },
{ field: 'description', title: '描述' },
];
export const point_table = {
modbus: [ modbus: [
{ field: 'register_type', title: '寄存器类型' }, { title: '序号', type: 'seq', width: 80 },
{ field: 'register_address', title: '寄存器地址' }, {
title: '扩展配置',
children: [
{
field: 'protocol_ext.register_type',
title: '寄存器类型',
width: 100,
},
{
field: 'protocol_ext.register_address',
title: '寄存器地址',
width: 100,
},
],
},
...base,
], ],
}; };

View File

@ -50,7 +50,7 @@ const routes: RouteRecordRaw[] = [
meta: { meta: {
badgeType: 'dot', badgeType: 'dot',
icon: 'logos:naiveui', icon: 'logos:naiveui',
link: VBEN_NAIVE_PREVIEW_URL, iframeSrc: VBEN_NAIVE_PREVIEW_URL,
title: $t('demos.vben.naive-ui'), title: $t('demos.vben.naive-ui'),
}, },
}, },

View File

@ -11,13 +11,13 @@ import { defineStore } from 'pinia';
import { getUserInfoApi, loginApi, logoutApi } from '#/api'; import { getUserInfoApi, loginApi, logoutApi } from '#/api';
import { $t } from '#/locales'; import { $t } from '#/locales';
import { useStaticConfigStore } from '#/store'; // import { useStaticConfigStore } from '#/store';
export const useAuthStore = defineStore('auth', () => { export const useAuthStore = defineStore('auth', () => {
const accessStore = useAccessStore(); const accessStore = useAccessStore();
const userStore = useUserStore(); const userStore = useUserStore();
const staticConfigStore = useStaticConfigStore(); // const staticConfigStore = useStaticConfigStore();
const router = useRouter(); const router = useRouter();
const loginLoading = ref(false); const loginLoading = ref(false);
@ -38,9 +38,9 @@ export const useAuthStore = defineStore('auth', () => {
userInfo.roles = ['admin']; userInfo.roles = ['admin'];
try { try {
loginLoading.value = true; loginLoading.value = true;
const { data } = await loginApi(params); await loginApi(params);
// 保存静态配置 // 保存静态配置
staticConfigStore.setConfig(data); // staticConfigStore.setConfig(data);
// console.log('staticConfigStore', staticConfigStore.support_driver_types); // console.log('staticConfigStore', staticConfigStore.support_driver_types);
// const { accessToken } = await loginApi(params); // const { accessToken } = await loginApi(params);

View File

@ -1,3 +1,299 @@
<script setup lang="js">
import { onMounted, onUnmounted, ref } from 'vue';
import {
ElCard,
ElCol,
ElDescriptions,
ElDescriptionsItem,
ElProgress,
ElRow,
} from 'element-plus';
import { cdcmCDCMAPI } from '#/cdcm/api/api.js';
import req from '#/cdcm/api/req_code';
const ret = ref();
const get_system_info = async () => {
const b = await cdcmCDCMAPI(null, req.CDCMGetSystemInfo);
ret.value = b;
};
onMounted(() => {
get_system_info();
});
const timer = setInterval(() => {
get_system_info();
}, 1000);
onUnmounted(() => {
clearInterval(timer);
});
//
const toInt = (value) => {
return value ? Math.round(value) : 0;
};
</script>
<template> <template>
<page> 设备详情 </page> <div class="monitor-container">
<!-- 上半部分 - 设备信息 -->
<ElRow :gutter="20" class="top-row">
<ElCol :span="24">
<ElCard class="device-card">
<template #header>
<div class="card-header">
<span class="device-title">设备信息</span>
</div>
</template>
<ElDescriptions :column="1" border :size="Large">
<ElDescriptionsItem label="型号" class="device-info">
CDCM2024
</ElDescriptionsItem>
<ElDescriptionsItem label="开机时间" class="device-info">
{{ ret?.running_information?.hostinfo.boottime || '-' }}
</ElDescriptionsItem>
<ElDescriptionsItem label="运行时长" class="device-info">
{{ ret?.running_information?.hostinfo.uptime || '-' }}
</ElDescriptionsItem>
</ElDescriptions>
</ElCard>
</ElCol>
</ElRow>
<!-- 下半部分 - 三栏图表 -->
<ElRow :gutter="20" class="bottom-row">
<!-- 内存信息 -->
<ElCol :span="8" class="chart-col">
<ElCard class="chart-card">
<template #header>
<div class="card-header">
<span>内存使用情况</span>
</div>
</template>
<div v-if="ret?.running_information?.meminfo" class="chart-content">
<ElProgress
type="dashboard"
:percentage="toInt(ret.running_information.meminfo.used_percent)"
:color="
ret.running_information.meminfo.used_percent > 80
? '#f56c6c'
: '#67c23a'
"
:width="120"
/>
<div class="memory-stats">
<div>
总内存:
{{ toInt(ret.running_information.meminfo.total) }}
MB
</div>
<div>
已用:
{{ toInt(ret.running_information.meminfo.used) }}
MB
</div>
<div>
可用:
{{ toInt(ret.running_information.meminfo.available) }}
MB
</div>
<div>
使用率:
{{ toInt(ret.running_information.meminfo.used_percent) }}%
</div>
</div>
</div>
</ElCard>
</ElCol>
<!-- 磁盘信息 -->
<ElCol :span="8" class="chart-col">
<ElCard class="chart-card">
<template #header>
<div class="card-header">
<span>磁盘使用情况</span>
</div>
</template>
<div v-if="ret?.running_information?.diskinfo" class="disk-chart">
<div
v-for="(disk, index) in ret.running_information.diskinfo"
:key="index"
class="disk-item"
>
<div class="disk-name">{{ disk.name }} ({{ disk.path }})</div>
<ElProgress
:percentage="toInt(disk.used_percent)"
:color="disk.used_percent > 80 ? '#f56c6c' : '#67c23a'"
:stroke-width="16"
/>
<div class="disk-stats">
<span>总空间: {{ toInt(disk.total) }} MB</span>
<span>已用: {{ toInt(disk.used) }} MB</span>
<span>剩余: {{ toInt(disk.free) }} MB</span>
</div>
</div>
</div>
</ElCard>
</ElCol>
<!-- 网络信息 -->
<ElCol :span="8" class="chart-col">
<ElCard class="chart-card">
<template #header>
<div class="card-header">
<span>网络流量</span>
</div>
</template>
<div v-if="ret?.running_information?.netinfo" class="network-chart">
<div
v-for="(net, index) in ret.running_information.netinfo"
:key="index"
class="network-item"
>
<div class="network-name">{{ net.name }}</div>
<div class="network-stats">
<div>上传: {{ toInt(net.bytesSent / 1024) }} KB</div>
<div>下载: {{ toInt(net.bytesRecv / 1024) }} KB</div>
<div>上传包: {{ toInt(net.packetsSent) }}</div>
<div>下载包: {{ toInt(net.packetsRecv) }}</div>
</div>
</div>
</div>
</ElCard>
</ElCol>
</ElRow>
</div>
</template> </template>
<style scoped>
.monitor-container {
box-sizing: border-box;
display: flex;
flex-direction: column;
height: 100vh;
padding: 20px;
}
.top-row {
height: 50%;
margin-bottom: 20px;
}
.bottom-row {
height: 50%;
}
.device-card {
height: 100%;
}
.device-title {
font-size: 32px;
font-weight: bold;
}
.device-info {
font-size: 24px;
}
.chart-col {
height: 100%;
}
.chart-card {
display: flex;
flex-direction: column;
height: 100%;
}
.chart-content {
display: flex;
flex: 1;
flex-direction: column;
align-items: center;
justify-content: center;
}
.memory-stats {
margin-top: 20px;
font-size: 18px;
text-align: center;
}
.memory-stats div {
margin: 16px 0;
}
.disk-chart {
display: flex;
flex: 1;
flex-direction: column;
justify-content: center;
padding: 0 10px;
overflow-y: auto;
}
.disk-item {
margin-bottom: 36px;
}
.disk-name {
margin-bottom: 16px;
font-size: 20px;
font-weight: bold;
}
.disk-stats {
display: flex;
justify-content: space-between;
margin-top: 16px;
font-size: 18px;
}
.network-chart {
display: flex;
flex: 1;
flex-direction: column;
justify-content: center;
padding: 0 10px;
overflow-y: auto;
}
.network-item {
padding-bottom: 16px;
margin-bottom: 32px;
border-bottom: 1px solid #eee;
}
.network-name {
margin-bottom: 16px;
font-size: 20px;
font-weight: bold;
}
.network-stats {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 16px;
font-size: 18px;
}
/* 调整Element UI组件样式 */
:deep(.el-descriptions__header) {
margin-bottom: 20px;
}
:deep(.el-descriptions__title) {
font-size: 18px;
}
:deep(.el-card__header) {
padding: 15px 20px;
font-size: 32px;
font-weight: bold;
}
</style>

View File

@ -0,0 +1,52 @@
<script lang="ts" setup>
import { useVbenModal } from '@vben/common-ui';
import { ElMessage } from 'element-plus';
import { useVbenForm } from '#/adapter/form';
import { cdcmRuleAPI } from '#/cdcm/api/api';
import req from '#/cdcm/api/req_code';
const [Modal, modalApi] = useVbenModal();
const [BaseForm] = useVbenForm({
commonConfig: {
componentProps: {
class: 'w-full',
},
},
handleSubmit: onSubmit,
layout: 'horizontal',
schema: [
{
component: 'Input',
componentProps: {
placeholder: '请输入规则名称',
},
fieldName: 'label',
label: '规则名称',
},
{
component: 'Input',
componentProps: {
placeholder: '请输入规则描述',
},
fieldName: 'info',
label: '规则描述',
},
],
wrapperClass: 'grid-cols-1',
});
async function onSubmit(values: Record<string, any>) {
const res = await cdcmRuleAPI(values, req.CruleAddFlow);
ElMessage.success(res);
modalApi.close();
}
</script>
<template>
<Modal title="新增规则" :footer="false">
<BaseForm />
</Modal>
</template>

View File

@ -1,3 +1,186 @@
<script lang="ts" setup>
import type { VxeGridProps } from '#/adapter/vxe-table';
import { ref } from 'vue';
import { useVbenModal } from '@vben/common-ui';
import { ElButton, ElMessage, ElMessageBox, ElTag } from 'element-plus';
import { useVbenVxeGrid } from '#/adapter/vxe-table';
import { cdcmRuleAPI } from '#/cdcm/api/api';
import req from '#/cdcm/api/req_code';
import Add from './add.vue';
const [Modal, modalApi] = useVbenModal({
footer: false,
fullscreen: true,
fullscreenButton: false,
closeOnPressEscape: false,
});
const [addModal, addApi] = useVbenModal({
connectedComponent: Add,
onOpenChange: (isOpen: boolean) => {
if (!isOpen) {
gridApi.reload();
}
},
});
interface RowType {
id: string;
label: string;
info: string;
disabled: boolean;
}
const gridOptions: VxeGridProps<RowType> = {
checkboxConfig: {
highlight: true,
labelField: 'name',
},
columns: [
{ title: '序号', type: 'seq', width: 50 },
// { field: 'id', title: 'ID' },
{ field: 'label', title: '名称' },
{ field: 'info', title: '描述' },
{ field: 'disabled', title: '状态', slots: { default: 'disabled' } },
{
field: 'action',
fixed: 'right',
slots: { default: 'action' },
title: '管理',
width: 240,
},
],
exportConfig: {},
keepSource: true,
proxyConfig: {
ajax: {
query: async () => {
return {
items: await cdcmRuleAPI(null, req.CruleGetFlows),
};
},
},
},
pagerConfig: {
enabled: false,
},
};
const [Grid, gridApi] = useVbenVxeGrid({
gridOptions,
});
//
const btn_add = () => {
addApi.open();
};
const iframeUrl = ref('');
const btn_open = (row: RowType) => {
modalApi.open();
let fullUrl = window.location.host;
fullUrl = 'http://10.10.10.123';
iframeUrl.value = `${fullUrl}/rule/#flow/${row.id}`;
ElMessage.success(`${fullUrl}/rule/#flow/${row.id}`);
};
// const btn_edit = (row: RowType) => {
// // console.log('', row);
// };
//
const btn_delete = async (row: RowType) => {
try {
ElMessageBox.confirm('确定要删除这条记录吗?', '删除确认', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
});
await cdcmRuleAPI({ id: row.id }, req.CruleDeleteFlow);
gridApi.reload();
ElMessage.success('删除成功');
} catch (error) {
if (error === 'cancel') {
ElMessage.info('已取消删除');
} else {
ElMessage.error('删除失败');
}
}
};
const btn_start = async (row: RowType) => {
try {
await cdcmRuleAPI({ id: row.id }, req.CruleStartFlow);
gridApi.reload();
ElMessage.success('启用成功');
} catch {
ElMessage.error('启用失败');
}
};
const btn_stop = async (row: RowType) => {
try {
await cdcmRuleAPI({ id: row.id }, req.CruleStopFlow);
gridApi.reload();
ElMessage.success('停用成功');
} catch {
ElMessage.error('停用失败');
}
};
</script>
<template> <template>
<page> 逻辑编程 </page> <div class="vp-raw w-full">
<Grid>
<template #toolbar-tools>
<ElButton class="mr-2" type="success" @click="btn_add"> </ElButton>
</template>
<template #disabled="{ row }">
<ElTag :type="row.disabled ? 'info' : 'success'">
{{ row.disabled ? '停用' : '运行' }}
</ElTag>
</template>
<template #action="{ row }">
<!-- <ElButton size="small" type="primary" round @click="btn_edit(row)">
编辑
</ElButton> -->
<ElButton size="small" type="primary" round @click="btn_open(row)">
打开
</ElButton>
<ElButton
size="small"
type="success"
round
@click="btn_start(row)"
v-show="row.disabled ? true : false"
>
启用
</ElButton>
<ElButton
size="small"
type="info"
round
@click="btn_stop(row)"
v-show="row.disabled ? false : true"
>
停用
</ElButton>
<ElButton size="small" type="danger" round @click="btn_delete(row)">
删除
</ElButton>
</template>
</Grid>
<Modal title="逻辑编程">
<iframe
:src="iframeUrl"
style="width: 100%; height: 100%; border: none"
></iframe>
</Modal>
<addModal />
</div>
</template> </template>

View File

@ -1,3 +1,195 @@
<script setup lang="ts">
import { onMounted, onUnmounted, ref } from 'vue';
import { ElButton, ElCard, ElCol, ElMessage, ElRow } from 'element-plus';
import { useVbenForm } from '#/adapter/form';
import { cdcmCDCMAPI } from '#/cdcm/api/api';
import req from '#/cdcm/api/req_code';
const ret = ref();
const get_system_info = async () => {
const b = await cdcmCDCMAPI(null, req.CDCMGetNetworkInfo);
ret.value = b;
netAAPI.setValues(ret.value.ip[0]);
netBAPI.setValues(ret.value.ip[1]);
dnsAPI.setValues(ret.value.dns);
};
onMounted(() => {
get_system_info();
});
onUnmounted(() => {});
const netConfig = {
commonConfig: {
componentProps: {
class: 'w-full',
},
},
showDefaultActions: false,
schema: [
{
component: 'Select',
componentProps: {
allowClear: true,
filterOption: true,
options: [
{
label: '静态IP',
value: 'STATIC',
},
{
label: '动态IP',
value: 'DHCP',
},
{
label: '动态IP及DNS',
value: 'DHCP_DNS',
},
],
placeholder: '请选择',
showSearch: true,
defaultValue: 'STATIC',
},
fieldName: 'mode',
label: 'IP模式',
},
{
component: 'Input',
fieldName: 'ip',
label: 'IP地址',
defaultValue: 'aa',
},
{
component: 'Input',
fieldName: 'mk',
label: '子网掩码',
defaultValue: 'aa',
},
{
component: 'Input',
fieldName: 'gw',
label: '网关地址',
defaultValue: 'aa',
},
],
wrapperClass: 'grid-cols-1',
};
const dnsConfig = {
commonConfig: {
componentProps: {
class: 'w-full',
},
},
showDefaultActions: false,
schema: [
{
component: 'Input',
fieldName: 'dns1',
label: '首选地址',
},
{
component: 'Input',
fieldName: 'dns2',
label: '备用地址',
},
],
wrapperClass: 'grid-cols-1',
};
const [netA, netAAPI] = useVbenForm(netConfig);
const [netB, netBAPI] = useVbenForm(netConfig);
const [dns, dnsAPI] = useVbenForm(dnsConfig);
const set_network_info = async () => {
//
const values = await netAAPI.getValues();
const values2 = await netBAPI.getValues();
const values3 = await dnsAPI.getValues();
ElMessage.success(JSON.stringify(values));
ElMessage.success(JSON.stringify(values2));
ElMessage.success(JSON.stringify(values3));
};
</script>
<template> <template>
<page> 网络配置 </page> <page>
<ElRow :gutter="20" class="equal-height-row">
<ElCol :span="8">
<ElCard class="equal-height-card">
<template #header>
<div class="card-header">
<span>网卡A</span>
</div>
</template>
<netA />
</ElCard>
</ElCol>
<ElCol :span="8">
<ElCard class="equal-height-card">
<template #header>
<div class="card-header">
<span>网卡B</span>
</div>
</template>
<netB />
</ElCard>
</ElCol>
<ElCol :span="8">
<ElCard class="equal-height-card">
<template #header>
<div class="card-header">
<span>DNS</span>
</div>
</template>
<dns />
</ElCard>
</ElCol>
<ElCol :span="24" class="mt-4 text-center">
<ElButton @click="set_network_info" type="primary" class="large-button">
设定
</ElButton>
</ElCol>
</ElRow>
</page>
</template> </template>
<style scoped>
.card-header {
font-size: 32px;
font-weight: bold;
}
.equal-height-row {
display: flex;
flex-wrap: wrap;
}
.equal-height-card {
display: flex;
flex-direction: column;
height: 100%;
}
.equal-height-card :deep(.el-card__body) {
flex: 1;
padding: 20px;
font-size: 20px;
}
.equal-height-card :deep(.el-form-item__label) {
font-size: 20px;
}
.equal-height-card :deep(.el-input__inner),
.equal-height-card :deep(.el-select__input) {
height: 40px;
font-size: 20px;
line-height: 40px;
}
.large-button {
padding: 12px 24px;
font-size: 20px;
}
</style>

View File

@ -40,7 +40,7 @@ const gridOptions: VxeGridProps<TemplateType> = {
labelField: 'name', labelField: 'name',
}, },
columns: [ columns: [
{ title: '序号', type: 'seq', width: 100 }, { title: '序号', type: 'seq', width: 80 },
{ field: 'name', title: '模板名称', width: 300 }, { field: 'name', title: '模板名称', width: 300 },
{ field: 'type', title: '模板类型', width: 200 }, { field: 'type', title: '模板类型', width: 200 },
{ field: 'description', title: '模板描述' }, { field: 'description', title: '模板描述' },

View File

@ -90,7 +90,6 @@ const [Drawer, drawerApi] = useVbenDrawer({
} }
}, },
}); });
const [addPointModal, addApi] = useVbenModal({ const [addPointModal, addApi] = useVbenModal({
connectedComponent: AddPoint, connectedComponent: AddPoint,
}); });

View File

@ -18,7 +18,7 @@ export default defineConfig(async () => {
rewrite: (path) => path.replace(/^\/api/, ''), rewrite: (path) => path.replace(/^\/api/, ''),
// mock代理目标地址 // mock代理目标地址
// target: 'http://10.10.10.41:5566/api', // target: 'http://10.10.10.41:5566/api',
target: 'http://api.shikicc.com:8900/api', target: 'http://10.10.10.123/api',
ws: true, ws: true,
}, },
}, },

View File

@ -4,13 +4,17 @@
"language": "en,en-US", "language": "en,en-US",
"allowCompoundWords": true, "allowCompoundWords": true,
"words": [ "words": [
"AAPI",
"acmr", "acmr",
"antd", "antd",
"antdv", "antdv",
"astro", "astro",
"BAPI",
"brotli", "brotli",
"CDCM", "CDCM",
"CDCMAPI",
"clsx", "clsx",
"Crule",
"defu", "defu",
"demi", "demi",
"echarts", "echarts",