feat: 模板页面逻辑基本框架ok

main
cc 2025-05-10 19:28:00 +08:00
parent 2c10b56c3a
commit 2743f21ddf
10 changed files with 448 additions and 18 deletions

View File

@ -203,7 +203,7 @@
], ],
"i18n-ally.pathMatcher": "{locale}/{namespace}.{ext}", "i18n-ally.pathMatcher": "{locale}/{namespace}.{ext}",
"i18n-ally.enabledParsers": ["json"], "i18n-ally.enabledParsers": ["json"],
"i18n-ally.sourceLanguage": "en", "i18n-ally.sourceLanguage": "zh-CN",
"i18n-ally.displayLanguage": "zh-CN", "i18n-ally.displayLanguage": "zh-CN",
"i18n-ally.enabledFrameworks": ["vue", "react"], "i18n-ally.enabledFrameworks": ["vue", "react"],
"i18n-ally.keystyle": "nested", "i18n-ally.keystyle": "nested",

View File

@ -17,10 +17,14 @@ export namespace AuthApi {
/** 登录接口返回值 */ /** 登录接口返回值 */
export interface LoginResult { export interface LoginResult {
support_driver_types?: string[]; data: {
support_point_access_types?: string[]; data: {
support_point_types?: string[]; support_driver_types?: string[];
support_template_types?: string[]; support_point_access_types?: string[];
support_point_types?: string[];
support_template_types?: string[];
};
};
} }
export interface RefreshTokenResult { export interface RefreshTokenResult {
@ -33,9 +37,7 @@ export namespace AuthApi {
* *
*/ */
export async function loginApi(data: AuthApi.LoginParams) { export async function loginApi(data: AuthApi.LoginParams) {
return cdcmRequestClient.post<AuthApi.LoginResult>('/auth/login', data, { return cdcmRequestClient.post<AuthApi.LoginResult>('/auth/login', data);
responseReturn: 'data',
});
} }
/** /**
@ -44,5 +46,3 @@ export async function loginApi(data: AuthApi.LoginParams) {
export async function logoutApi() { export async function logoutApi() {
return cdcmRequestClient.post('/auth/logout', {}); return cdcmRequestClient.post('/auth/logout', {});
} }
// 通用请求函数

View File

@ -0,0 +1,28 @@
import { cdcmRequestClient } from '#/api/request';
import { useTokenStore } from '#/store';
const token = useTokenStore().token;
export namespace TemplateApi {
/** 分页查询模板请求体 */
export interface TemplateQueryPageRequest {
page_num: number;
page_size: number;
template_type?: string;
}
}
/**
*
*/
export async function TemplateQueryPage(
data: TemplateApi.TemplateQueryPageRequest,
) {
return cdcmRequestClient.post('/template', data, {
responseReturn: 'data',
headers: {
cdcm: token,
action: 52_011,
},
});
}

View File

@ -133,7 +133,7 @@ function createCDCMRequestClient(
// 响应拦截器:自动更新 token // 响应拦截器:自动更新 token
client.addResponseInterceptor({ client.addResponseInterceptor({
fulfilled: async (response) => { fulfilled: (response) => {
const token = response.headers?.token; const token = response.headers?.token;
if (token) { if (token) {
// 如果响应头中有新 token自动更新 store // 如果响应头中有新 token自动更新 store

View File

@ -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);
// 保存静态配置 // 保存静态配置
staticConfigStore.setConfig(await loginApi(params)); 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

@ -25,10 +25,11 @@ export const useStaticConfigStore = defineStore('static_config', {
}), }),
actions: { actions: {
setConfig(data: AuthApi.LoginResult) { setConfig(data: AuthApi.LoginResult) {
this.support_template_types = data.support_template_types ?? []; this.support_template_types = data.data.support_template_types ?? [];
this.support_driver_types = data.support_driver_types ?? []; this.support_driver_types = data.data.support_driver_types ?? [];
this.support_point_types = data.support_point_types ?? []; this.support_point_types = data.data.support_point_types ?? [];
this.support_point_access_types = data.support_point_access_types ?? []; this.support_point_access_types =
data.data.support_point_access_types ?? [];
}, },
}, },
}); });

View File

@ -0,0 +1,80 @@
<script lang="ts" setup>
import { useVbenModal } from '@vben/common-ui';
import { ElMessage } from 'element-plus';
import { useVbenForm } from '#/adapter/form';
import { useStaticConfigStore } from '#/store';
const [Modal] = useVbenModal();
const template_types = useStaticConfigStore().support_template_types;
const get_template_types = () => {
return template_types.map((item) => {
return {
label: item,
value: item,
};
});
};
const [TemplateForm] = useVbenForm({
//
commonConfig: {
//
componentProps: {
class: 'w-full',
},
},
//
handleSubmit: onSubmit,
// labelinputvertical
// labelinput
layout: 'horizontal',
schema: [
{
component: 'Input',
componentProps: {
placeholder: '模板名称',
},
fieldName: 'name',
label: '模板名称',
},
{
component: 'Input',
componentProps: {
placeholder: '模板描述',
},
fieldName: 'description',
label: '模板描述',
},
{
component: 'Select',
componentProps: {
allowClear: true,
filterOption: true,
options: get_template_types(),
placeholder: '请选择',
showSearch: true,
},
fieldName: 'options',
label: '模板类型',
},
],
wrapperClass: 'grid-cols-1',
});
function onSubmit(values: Record<string, any>) {
ElMessage.success(`form values: ${JSON.stringify(values)}`);
}
</script>
<template>
<Modal title="新增模板" :footer="false">
<TemplateForm />
</Modal>
</template>

View File

@ -0,0 +1,77 @@
<script lang="ts" setup>
import { useVbenModal } from '@vben/common-ui';
import { ElMessage } from 'element-plus';
import { useVbenForm } from '#/adapter/form';
interface DataType {
data: {
description: string;
name: string;
};
}
const [TemplateForm, formApi] = useVbenForm({
//
commonConfig: {
//
componentProps: {
class: 'w-full',
},
},
//
handleSubmit: onSubmit,
// labelinputvertical
// labelinput
layout: 'horizontal',
schema: [
{
component: 'Input',
componentProps: {
placeholder: '模板名称',
},
fieldName: 'name',
label: '模板名称',
},
{
component: 'Input',
componentProps: {
placeholder: '模板描述',
},
fieldName: 'description',
label: '模板描述',
},
],
wrapperClass: 'grid-cols-1',
});
function onSubmit(values: Record<string, any>) {
ElMessage.success(`form values: ${JSON.stringify(values)}`);
}
const [Modal, modalApi] = useVbenModal({
onCancel() {
modalApi.close();
},
onOpenChange(isOpen: boolean) {
if (isOpen) {
const data = modalApi.getData<DataType>();
if (data) {
//
formApi.setValues({
name: data.data.name,
description: data.data.description,
});
}
}
},
});
</script>
<template>
<Modal title="编辑模板" :footer="false">
<TemplateForm />
</Modal>
</template>

View File

@ -1,3 +1,146 @@
<script lang="ts" setup>
import type { VxeGridProps } from '#/adapter/vxe-table';
import { useVbenDrawer, useVbenModal } from '@vben/common-ui';
import { ElButton, ElMessage } from 'element-plus';
import { useVbenVxeGrid } from '#/adapter/vxe-table';
import { TemplateQueryPage } from '#/api/core/template';
import Add from './add.vue';
import Edit from './edit.vue';
import Point from './point.vue';
const [addModal, addApi] = useVbenModal({
connectedComponent: Add,
});
const [editModal, editApi] = useVbenModal({
connectedComponent: Edit,
});
const [pointModal, pointApi] = useVbenDrawer({
connectedComponent: Point,
});
interface TemplateType {
id: number;
name: string;
type: string;
description: string;
point_count: number;
points: any[];
}
interface ResponseType {
list: TemplateType[];
total: number;
page: number;
page_size: number;
total_pages: number;
}
const gridOptions: VxeGridProps<TemplateType> = {
checkboxConfig: {
highlight: true,
labelField: 'name',
},
columns: [
{ title: '序号', type: 'seq', width: 100 },
{ field: 'name', title: '模板名称', width: 300 },
{ field: 'type', title: '模板类型', width: 200 },
{ field: 'description', title: '模板描述' },
{ field: 'point_count', title: '点位数量', width: 150 },
{
field: 'action',
fixed: 'right',
slots: { default: 'action' },
title: '管理',
width: 240,
},
],
exportConfig: {},
keepSource: true,
proxyConfig: {
ajax: {
query: async ({ page }) => {
const ret: ResponseType = await TemplateQueryPage({
page_num: page.currentPage,
page_size: page.pageSize,
});
return {
total: ret.total,
items: ret.list,
};
},
},
},
pagerConfig: {
enabled: true,
pageSize: 10,
},
toolbarConfig: {
custom: true,
export: true,
// import: true,
refresh: true,
zoom: true,
},
};
const [TemplateTable, tableApi] = useVbenVxeGrid({
gridOptions,
});
//
const btn_add = () => {
addApi.open();
};
//
const btn_edit = (row: TemplateType) => {
editApi.setData({ data: row }).open();
};
//
const btn_delete = (row: TemplateType) => {
ElMessage.success(`删除 ${row.id}`);
};
//
const btn_point = (row: TemplateType) => {
pointApi.setData({ data: row }).open();
};
</script>
<template> <template>
<page> 数据模板 </page> <div class="vp-raw w-full" style="height: 600px">
<TemplateTable>
<template #toolbar-tools>
<ElButton class="mr-2" type="success" @click="btn_add"> </ElButton>
<ElButton class="mr-2" type="primary" @click="() => tableApi.query()">
刷新当前页面
</ElButton>
<ElButton type="primary" @click="() => tableApi.reload()">
刷新并返回第一页
</ElButton>
</template>
<template #action="{ row }">
<ElButton size="small" type="primary" round @click="btn_edit(row)">
编辑
</ElButton>
<ElButton size="small" type="success" round @click="btn_point(row)">
点位
</ElButton>
<ElButton size="small" type="danger" round @click="btn_delete(row)">
删除
</ElButton>
</template>
</TemplateTable>
<addModal />
<editModal />
<pointModal />
</div>
</template> </template>

View File

@ -0,0 +1,101 @@
<script lang="ts" setup>
import type { VxeGridProps } from '#/adapter/vxe-table';
import { ref } from 'vue';
import { useVbenDrawer } from '@vben/common-ui';
import { ElButton } from 'element-plus';
import { useVbenVxeGrid } from '#/adapter/vxe-table';
interface PointDataType {
id: number;
name: string;
point_type: string;
description: string;
access: string;
calculation: string;
unit: string;
protocol_config: string;
}
interface TemplateDateType {
description: string;
id: number;
name: string;
point_count: number;
points: PointDataType[];
type: string;
}
interface TemplateType {
data: TemplateDateType;
}
const template_data = ref<TemplateDateType>();
const gridOptions: VxeGridProps<PointDataType> = {
checkboxConfig: {
highlight: true,
labelField: 'name', // productName
},
columns: [
{ title: '序号', type: 'seq', width: 100 },
{ field: 'name', title: '点位名称' },
{ field: 'point_type', title: '点位类型' },
{ field: 'description', title: '点位描述' },
{ field: 'access', title: '读写权限' },
{ field: 'calculation', title: '计算公式' },
{ field: 'unit', title: '单位' },
{ field: 'protocol_config', title: '扩展配置' },
],
exportConfig: {},
toolbarConfig: {
custom: true,
export: true,
refresh: true,
zoom: true,
},
};
const [PointTable, tableApi] = useVbenVxeGrid({
gridOptions,
});
const [Drawer, drawerApi] = useVbenDrawer({
onCancel() {
drawerApi.close();
},
onOpenChange(isOpen: boolean) {
if (isOpen) {
const data = drawerApi.getData<TemplateType>();
if (data) {
template_data.value = data.data;
tableApi.setGridOptions({
data: template_data.value.points,
});
}
}
},
});
function btn_add() {
//
// console.log('');
}
</script>
<template>
<Drawer title="模板点位管理" :footer="false" class="w-[1500px]">
<div class="vp-raw w-full" style="height: 600px">
<PointTable>
<template #toolbar-tools>
<ElButton class="mr-2" type="success" @click="btn_add">
新增
</ElButton>
</template>
</PointTable>
</div>
</Drawer>
</template>