feat: 微信告警配置管理功能完整实现 v1.3.5
This commit is contained in:
@@ -140,7 +140,7 @@ services:
|
||||
VITE_APP_TITLE: ${VITE_APP_TITLE:-穿戴管理演示系统}
|
||||
TZ: Asia/Shanghai
|
||||
ports:
|
||||
- "8080:80"
|
||||
- "8088:80"
|
||||
volumes:
|
||||
- ./logs/ljwx-admin:/var/log/nginx
|
||||
- ./custom-admin-config.js:/tmp/custom-admin-config.js:ro
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
# Netscape HTTP Cookie File
|
||||
# https://curl.se/docs/http-cookies.html
|
||||
# This file was generated by libcurl! Edit at your own risk.
|
||||
|
||||
@@ -400,8 +400,95 @@ Content-Type: application/json
|
||||
}
|
||||
```
|
||||
|
||||
### 🔧 微信告警配置管理 (最新)
|
||||
|
||||
#### 功能概述
|
||||
- 支持企业微信和微信公众号两种类型的告警配置管理
|
||||
- 动态表格列显示,根据配置类型自适应显示相应字段
|
||||
- 完整的CRUD操作支持,包含新增、编辑、删除和批量删除功能
|
||||
- 智能数据过滤和状态管理
|
||||
|
||||
#### 功能特点
|
||||
1. **双类型支持**:
|
||||
- **企业微信配置**:显示企业ID、应用ID、应用Secret等企业微信专属字段
|
||||
- **微信公众号配置**:显示AppID、AppSecret、微信ID等公众号专属字段
|
||||
|
||||
2. **智能表格**:
|
||||
- 标签页切换时动态调整表格列
|
||||
- 自适应字段显示,避免冗余列
|
||||
- 统一的通用字段:模板ID、启用状态、创建时间、操作等
|
||||
|
||||
3. **数据管理**:
|
||||
- 实时数据同步和状态更新
|
||||
- 完整的权限控制和操作验证
|
||||
- 敏感信息脱敏显示(Secret字段只显示后4位)
|
||||
|
||||
#### 使用方法
|
||||
1. **查看配置**:
|
||||
- 点击"企业微信配置"标签查看企业微信告警配置
|
||||
- 点击"微信公众号配置"标签查看公众号告警配置
|
||||
- 支持按类型、启用状态等条件搜索过滤
|
||||
|
||||
2. **新增配置**:
|
||||
- 点击"新增"按钮打开配置表单
|
||||
- 根据当前标签页自动设置配置类型
|
||||
- 填写对应类型的必要字段信息
|
||||
|
||||
3. **编辑配置**:
|
||||
- 点击表格中的"编辑"按钮修改配置
|
||||
- 支持修改除ID和类型外的所有字段
|
||||
- 实时保存并更新表格显示
|
||||
|
||||
#### 技术实现
|
||||
- **动态列定义**:基于 `activeTab` 值动态生成表格列配置
|
||||
- **状态管理**:使用 Vue 3 的响应式系统实现状态同步
|
||||
- **API集成**:与后端 `/t_wechat_alarm_config/page` 接口完整对接
|
||||
- **类型安全**:完整的 TypeScript 类型定义和验证
|
||||
|
||||
#### 数据字段映射
|
||||
```typescript
|
||||
// 企业微信配置
|
||||
{
|
||||
corpId: string; // 企业ID
|
||||
agentId: string; // 应用ID
|
||||
secret: string; // 应用Secret
|
||||
}
|
||||
|
||||
// 微信公众号配置
|
||||
{
|
||||
appid: string; // AppID
|
||||
appsecret: string; // AppSecret
|
||||
wechatId: string; // 微信ID (映射自appid)
|
||||
}
|
||||
|
||||
// 通用字段
|
||||
{
|
||||
templateId: string; // 模板ID
|
||||
enabled: boolean; // 启用状态
|
||||
createTime: string; // 创建时间
|
||||
}
|
||||
```
|
||||
|
||||
## 📝 更新日志
|
||||
|
||||
### v1.3.5 (2025-08-27)
|
||||
- ✨ **新增微信告警配置管理功能**
|
||||
- 支持企业微信和微信公众号两种配置类型
|
||||
- 动态表格列显示,根据类型自适应字段
|
||||
- 完整的CRUD操作和批量管理
|
||||
- 敏感信息安全脱敏显示
|
||||
- 智能数据过滤和实时状态同步
|
||||
- 🔧 **修复表格组件显示问题**
|
||||
- 解决NDataTable组件数据绑定问题
|
||||
- 修复TableHeaderOperation组件导入缺失
|
||||
- 优化标签页切换时的数据加载逻辑
|
||||
- 完善列定义动态更新机制
|
||||
- 🐛 **修复数据过滤和状态管理**
|
||||
- 修复标签切换时数据不更新的问题
|
||||
- 优化searchParams参数传递机制
|
||||
- 改进API参数验证和错误处理
|
||||
- 增强前后端数据同步稳定性
|
||||
|
||||
### v1.3.4 (2025-08-25)
|
||||
- ✨ **新增健康数据源过滤功能**
|
||||
- 健康数据查看时自动过滤通用事件上传的数据
|
||||
|
||||
@@ -31,7 +31,9 @@ export function useTable<A extends NaiveUI.TableApiFn>(config: NaiveUI.NaiveTabl
|
||||
apiParams,
|
||||
columns: config.columns,
|
||||
transformer: res => {
|
||||
console.log('[DEBUG] API Raw Response:', res);
|
||||
const { records = [], page = 1, pageSize = 20, total = 0 } = res.data || {};
|
||||
console.log('[DEBUG] Extracted:', { records, page, pageSize, total });
|
||||
// Ensure that the size is greater than 0, If it is less than 0, it will cause paging calculation errors.
|
||||
const rPageSize = pageSize <= 0 ? 20 : pageSize;
|
||||
const recordsWithIndex = records.map((item, index) => {
|
||||
@@ -40,6 +42,7 @@ export function useTable<A extends NaiveUI.TableApiFn>(config: NaiveUI.NaiveTabl
|
||||
index: (page - 1) * rPageSize + index + 1
|
||||
};
|
||||
});
|
||||
console.log('[DEBUG] Final data with index:', recordsWithIndex);
|
||||
|
||||
return {
|
||||
data: recordsWithIndex,
|
||||
|
||||
+16
-8
@@ -31,14 +31,22 @@ declare namespace Api {
|
||||
|
||||
type AlertConfigWechat = Common.CommonRecord<{
|
||||
customerId: number;
|
||||
/** WeChat App ID */
|
||||
appId: string;
|
||||
/** WeChat App Secret */
|
||||
appSecret: string;
|
||||
/** WeChat Type: enterprise/official */
|
||||
type: string;
|
||||
/** Enterprise WeChat Corp ID */
|
||||
corpId: string;
|
||||
/** Enterprise WeChat Agent ID */
|
||||
agentId: string;
|
||||
/** Enterprise WeChat Secret */
|
||||
secret: string;
|
||||
/** Official WeChat App ID */
|
||||
appid: string;
|
||||
/** Official WeChat App Secret */
|
||||
appsecret: string;
|
||||
/** WeChat Template ID */
|
||||
templateId: string;
|
||||
/** WeChat User OpenID */
|
||||
userOpenid: string;
|
||||
/** Whether enabled */
|
||||
enabled: boolean;
|
||||
/** User who created the record */
|
||||
createUser: string;
|
||||
/** Creation timestamp */
|
||||
@@ -47,13 +55,13 @@ declare namespace Api {
|
||||
|
||||
/** Wechaalerconfig search params */
|
||||
type AlertConfigWechatSearchParams = CommonType.RecordNullable<
|
||||
Pick<Api.Health.AlertConfigWechat, 'appId' | 'appSecret' | 'templateId' | 'userOpenid'> & Api.Common.CommonSearchParams
|
||||
Pick<Api.Health.AlertConfigWechat, 'type' | 'corpId' | 'agentId' | 'appid' | 'templateId' | 'enabled'> & Api.Common.CommonSearchParams
|
||||
>;
|
||||
|
||||
/** Wechaalerconfig edit model */
|
||||
type AlertConfigWechatEdit = Pick<
|
||||
Api.Health.AlertConfigWechat,
|
||||
'id' | 'appId' | 'appSecret' | 'templateId' | 'userOpenid' | 'createUser' | 'createTime'
|
||||
'id' | 'customerId' | 'type' | 'corpId' | 'agentId' | 'secret' | 'appid' | 'appsecret' | 'templateId' | 'enabled' | 'createUser' | 'createTime'
|
||||
>;
|
||||
|
||||
/** Wechaalerconfig list */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script setup lang="tsx">
|
||||
import { NButton, NTabs, NTabPane, NCard, NPopconfirm, NDataTable } from 'naive-ui';
|
||||
import type { Ref } from 'vue';
|
||||
import { ref } from 'vue';
|
||||
import { ref, computed, watch, onMounted } from 'vue';
|
||||
import { useAppStore } from '@/store/modules/app';
|
||||
import { convertToBeijingTime } from '@/utils/date';
|
||||
import { useAuth } from '@/hooks/business/auth';
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
} from '@/service/api/health/alert-config-wechat';
|
||||
import AlertConfigWechatSearch from './modules/alertconfigwechat-search.vue';
|
||||
import AlertConfigWechatOperateDrawer from './modules/alert-config-wechat-operate-drawer.vue';
|
||||
import TableHeaderOperation from '@/components/advanced/table-header-operation.vue';
|
||||
|
||||
defineOptions({
|
||||
name: 'AlertConfigPage'
|
||||
@@ -23,275 +24,218 @@ defineOptions({
|
||||
// 当前激活的tab
|
||||
const activeTab = ref('enterprise');
|
||||
|
||||
// 企业微信配置
|
||||
const enterpriseOperateType = ref<NaiveUI.TableOperateType>('add');
|
||||
const enterpriseEditingData: Ref<Api.Health.AlertConfigWechat | null> = ref(null);
|
||||
|
||||
// 微信公众号配置
|
||||
const officialOperateType = ref<NaiveUI.TableOperateType>('add');
|
||||
const officialEditingData: Ref<Api.Health.AlertConfigWechat | null> = ref(null);
|
||||
const operateType = ref<NaiveUI.TableOperateType>('add');
|
||||
const editingData: Ref<Api.Health.AlertConfigWechat | null> = ref(null);
|
||||
|
||||
const appStore = useAppStore();
|
||||
const { hasAuth } = useAuth();
|
||||
const authStore = useAuthStore();
|
||||
const customerId = authStore.userInfo?.customerId;
|
||||
|
||||
// 企业微信表格配置
|
||||
const {
|
||||
columns: enterpriseColumns,
|
||||
columnChecks: enterpriseColumnChecks,
|
||||
data: enterpriseData,
|
||||
loading: enterpriseLoading,
|
||||
getData: getEnterpriseData,
|
||||
getDataByPage: getEnterpriseDataByPage,
|
||||
mobilePagination: enterpriseMobilePagination,
|
||||
searchParams: enterpriseSearchParams,
|
||||
resetSearchParams: resetEnterpriseSearchParams
|
||||
// 使用单个useTable
|
||||
const {
|
||||
columns,
|
||||
columnChecks,
|
||||
data,
|
||||
loading,
|
||||
getData,
|
||||
getDataByPage,
|
||||
mobilePagination,
|
||||
searchParams,
|
||||
updateSearchParams,
|
||||
resetSearchParams,
|
||||
reloadColumns
|
||||
} = useTable({
|
||||
apiFn: fetchGetAlertConfigWechatList,
|
||||
apiParams: {
|
||||
page: 1,
|
||||
pageSize: 20,
|
||||
customerId,
|
||||
type: 'enterprise',
|
||||
type: activeTab.value,
|
||||
enabled: null
|
||||
},
|
||||
columns: () => [
|
||||
{
|
||||
key: 'index',
|
||||
title: $t('common.index'),
|
||||
width: 64,
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
key: 'corpId',
|
||||
title: '企业ID',
|
||||
align: 'center',
|
||||
width: 150,
|
||||
render: row => row.corpId || '-'
|
||||
},
|
||||
{
|
||||
key: 'agentId',
|
||||
title: '应用ID',
|
||||
align: 'center',
|
||||
width: 100,
|
||||
render: row => row.agentId || '-'
|
||||
},
|
||||
{
|
||||
key: 'templateId',
|
||||
title: '模板ID',
|
||||
align: 'center',
|
||||
width: 200,
|
||||
render: row => row.templateId || '-'
|
||||
},
|
||||
{
|
||||
key: 'enabled',
|
||||
title: '启用状态',
|
||||
align: 'center',
|
||||
width: 100,
|
||||
render: row => row.enabled ? '启用' : '禁用'
|
||||
},
|
||||
{
|
||||
key: 'createTime',
|
||||
title: $t('page.health.alert.config.wechat.createTime'),
|
||||
align: 'center',
|
||||
width: 150,
|
||||
render: row => convertToBeijingTime(row.createTime)
|
||||
},
|
||||
{
|
||||
key: 'operate',
|
||||
title: $t('common.operate'),
|
||||
align: 'center',
|
||||
width: 120,
|
||||
minWidth: 120,
|
||||
render: row => (
|
||||
<div class="flex-center gap-8px">
|
||||
{hasAuth('t:wechat:alarm:config:update') && (
|
||||
<NButton type="primary" quaternary size="small" onClick={() => editEnterprise(row)}>
|
||||
{$t('common.edit')}
|
||||
</NButton>
|
||||
)}
|
||||
{hasAuth('t:wechat:alarm:config:delete') && (
|
||||
<NPopconfirm onPositiveClick={() => handleDeleteEnterprise(row.id)}>
|
||||
{{
|
||||
default: () => $t('common.confirmDelete'),
|
||||
trigger: () => (
|
||||
<NButton type="error" quaternary size="small">
|
||||
{$t('common.delete')}
|
||||
</NButton>
|
||||
)
|
||||
}}
|
||||
</NPopconfirm>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
]
|
||||
});
|
||||
columns: () => {
|
||||
// 基础列
|
||||
const baseColumns = [
|
||||
{
|
||||
key: 'index',
|
||||
title: $t('common.index'),
|
||||
width: 64,
|
||||
align: 'center'
|
||||
}
|
||||
];
|
||||
|
||||
// 微信公众号表格配置
|
||||
const {
|
||||
columns: officialColumns,
|
||||
columnChecks: officialColumnChecks,
|
||||
data: officialData,
|
||||
loading: officialLoading,
|
||||
getData: getOfficialData,
|
||||
getDataByPage: getOfficialDataByPage,
|
||||
mobilePagination: officialMobilePagination,
|
||||
searchParams: officialSearchParams,
|
||||
resetSearchParams: resetOfficialSearchParams
|
||||
} = useTable({
|
||||
apiFn: fetchGetAlertConfigWechatList,
|
||||
apiParams: {
|
||||
page: 1,
|
||||
pageSize: 20,
|
||||
customerId,
|
||||
type: 'official',
|
||||
enabled: null
|
||||
},
|
||||
columns: () => [
|
||||
{
|
||||
key: 'index',
|
||||
title: $t('common.index'),
|
||||
width: 64,
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
key: 'appid',
|
||||
title: 'AppID',
|
||||
align: 'center',
|
||||
width: 150,
|
||||
render: row => row.appid || '-'
|
||||
},
|
||||
{
|
||||
key: 'templateId',
|
||||
title: '模板ID',
|
||||
align: 'center',
|
||||
width: 200,
|
||||
render: row => row.templateId || '-'
|
||||
},
|
||||
{
|
||||
key: 'enabled',
|
||||
title: '启用状态',
|
||||
align: 'center',
|
||||
width: 100,
|
||||
render: row => row.enabled ? '启用' : '禁用'
|
||||
},
|
||||
{
|
||||
key: 'createTime',
|
||||
title: $t('page.health.alert.config.wechat.createTime'),
|
||||
align: 'center',
|
||||
width: 150,
|
||||
render: row => convertToBeijingTime(row.createTime)
|
||||
},
|
||||
{
|
||||
key: 'operate',
|
||||
title: $t('common.operate'),
|
||||
align: 'center',
|
||||
width: 120,
|
||||
minWidth: 120,
|
||||
render: row => (
|
||||
<div class="flex-center gap-8px">
|
||||
{hasAuth('t:wechat:alarm:config:update') && (
|
||||
<NButton type="primary" quaternary size="small" onClick={() => editOfficial(row)}>
|
||||
{$t('common.edit')}
|
||||
</NButton>
|
||||
)}
|
||||
{hasAuth('t:wechat:alarm:config:delete') && (
|
||||
<NPopconfirm onPositiveClick={() => handleDeleteOfficial(row.id)}>
|
||||
{{
|
||||
default: () => $t('common.confirmDelete'),
|
||||
trigger: () => (
|
||||
<NButton type="error" quaternary size="small">
|
||||
{$t('common.delete')}
|
||||
</NButton>
|
||||
)
|
||||
}}
|
||||
</NPopconfirm>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
]
|
||||
// 根据当前选中的类型显示不同的列
|
||||
const typeSpecificColumns = activeTab.value === 'enterprise'
|
||||
? [
|
||||
// 企业微信专属字段
|
||||
{
|
||||
key: 'corpId',
|
||||
title: '企业ID',
|
||||
align: 'center',
|
||||
width: 150,
|
||||
render: (row: any) => row.corpId || '-'
|
||||
},
|
||||
{
|
||||
key: 'agentId',
|
||||
title: '应用ID',
|
||||
align: 'center',
|
||||
width: 100,
|
||||
render: (row: any) => row.agentId || '-'
|
||||
},
|
||||
{
|
||||
key: 'secret',
|
||||
title: '应用Secret',
|
||||
align: 'center',
|
||||
width: 120,
|
||||
render: (row: any) => row.secret ? '***' + row.secret.slice(-4) : '-'
|
||||
}
|
||||
]
|
||||
: [
|
||||
// 微信公众号专属字段
|
||||
{
|
||||
key: 'appid',
|
||||
title: 'AppID',
|
||||
align: 'center',
|
||||
width: 150,
|
||||
render: (row: any) => row.appid || '-'
|
||||
},
|
||||
{
|
||||
key: 'appsecret',
|
||||
title: 'AppSecret',
|
||||
align: 'center',
|
||||
width: 120,
|
||||
render: (row: any) => row.appsecret ? '***' + row.appsecret.slice(-4) : '-'
|
||||
},
|
||||
{
|
||||
key: 'wechatId',
|
||||
title: '微信ID',
|
||||
align: 'center',
|
||||
width: 120,
|
||||
render: (row: any) => row.appid || '-' // 临时使用appid作为微信ID
|
||||
}
|
||||
];
|
||||
|
||||
// 通用列
|
||||
const commonColumns = [
|
||||
{
|
||||
key: 'templateId',
|
||||
title: '模板ID',
|
||||
align: 'center',
|
||||
width: 200,
|
||||
render: (row: any) => row.templateId || '-'
|
||||
},
|
||||
{
|
||||
key: 'enabled',
|
||||
title: '启用状态',
|
||||
align: 'center',
|
||||
width: 100,
|
||||
render: (row: any) => row.enabled ? '启用' : '禁用'
|
||||
},
|
||||
{
|
||||
key: 'createTime',
|
||||
title: $t('page.health.alert.config.wechat.createTime'),
|
||||
align: 'center',
|
||||
width: 150,
|
||||
render: (row: any) => convertToBeijingTime(row.createTime)
|
||||
},
|
||||
{
|
||||
key: 'operate',
|
||||
title: $t('common.operate'),
|
||||
align: 'center',
|
||||
width: 120,
|
||||
minWidth: 120,
|
||||
render: (row: any) => (
|
||||
<div class="flex-center gap-8px">
|
||||
{hasAuth('t:wechat:alarm:config:update') && (
|
||||
<NButton type="primary" quaternary size="small" onClick={() => edit(row)}>
|
||||
{$t('common.edit')}
|
||||
</NButton>
|
||||
)}
|
||||
{hasAuth('t:wechat:alarm:config:delete') && (
|
||||
<NPopconfirm onPositiveClick={() => handleDelete(row.id)}>
|
||||
{{
|
||||
default: () => $t('common.confirmDelete'),
|
||||
trigger: () => (
|
||||
<NButton type="error" quaternary size="small">
|
||||
{$t('common.delete')}
|
||||
</NButton>
|
||||
)
|
||||
}}
|
||||
</NPopconfirm>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
];
|
||||
|
||||
return [...baseColumns, ...typeSpecificColumns, ...commonColumns];
|
||||
}
|
||||
});
|
||||
|
||||
const {
|
||||
drawerVisible: enterpriseDrawerVisible,
|
||||
openDrawer: openEnterpriseDrawer,
|
||||
checkedRowKeys: enterpriseCheckedRowKeys,
|
||||
onDeleted: onEnterpriseDeleted,
|
||||
onBatchDeleted: onEnterpriseBatchDeleted
|
||||
} = useTableOperate(enterpriseData, getEnterpriseData);
|
||||
drawerVisible,
|
||||
openDrawer,
|
||||
checkedRowKeys,
|
||||
onDeleted,
|
||||
onBatchDeleted
|
||||
} = useTableOperate(data, getData);
|
||||
|
||||
const {
|
||||
drawerVisible: officialDrawerVisible,
|
||||
openDrawer: openOfficialDrawer,
|
||||
checkedRowKeys: officialCheckedRowKeys,
|
||||
onDeleted: onOfficialDeleted,
|
||||
onBatchDeleted: onOfficialBatchDeleted
|
||||
} = useTableOperate(officialData, getOfficialData);
|
||||
|
||||
// 企业微信操作
|
||||
function handleAddEnterprise() {
|
||||
enterpriseOperateType.value = 'add';
|
||||
openEnterpriseDrawer();
|
||||
// 操作函数
|
||||
function handleAdd() {
|
||||
operateType.value = 'add';
|
||||
openDrawer();
|
||||
}
|
||||
|
||||
function editEnterprise(item: Api.Health.AlertConfigWechat) {
|
||||
enterpriseOperateType.value = 'edit';
|
||||
enterpriseEditingData.value = { ...item };
|
||||
openEnterpriseDrawer();
|
||||
function edit(item: Api.Health.AlertConfigWechat) {
|
||||
operateType.value = 'edit';
|
||||
editingData.value = { ...item };
|
||||
openDrawer();
|
||||
}
|
||||
|
||||
async function handleDeleteEnterprise(id: string) {
|
||||
async function handleDelete(id: string) {
|
||||
const { error, data: result } = await fetchDeleteAlertConfigWechat(transDeleteParams([id]));
|
||||
if (!error && result) {
|
||||
await onEnterpriseDeleted();
|
||||
await onDeleted();
|
||||
}
|
||||
}
|
||||
|
||||
async function handleEnterpriseBatchDelete() {
|
||||
const { error, data: result } = await fetchDeleteAlertConfigWechat(transDeleteParams(enterpriseCheckedRowKeys.value));
|
||||
async function handleBatchDelete() {
|
||||
const { error, data: result } = await fetchDeleteAlertConfigWechat(transDeleteParams(checkedRowKeys.value));
|
||||
if (!error && result) {
|
||||
await onEnterpriseBatchDeleted();
|
||||
await onBatchDeleted();
|
||||
}
|
||||
}
|
||||
|
||||
// 微信公众号操作
|
||||
function handleAddOfficial() {
|
||||
officialOperateType.value = 'add';
|
||||
openOfficialDrawer();
|
||||
}
|
||||
|
||||
function editOfficial(item: Api.Health.AlertConfigWechat) {
|
||||
officialOperateType.value = 'edit';
|
||||
officialEditingData.value = { ...item };
|
||||
openOfficialDrawer();
|
||||
}
|
||||
|
||||
async function handleDeleteOfficial(id: string) {
|
||||
const { error, data: result } = await fetchDeleteAlertConfigWechat(transDeleteParams([id]));
|
||||
if (!error && result) {
|
||||
await onOfficialDeleted();
|
||||
}
|
||||
}
|
||||
|
||||
async function handleOfficialBatchDelete() {
|
||||
const { error, data: result } = await fetchDeleteAlertConfigWechat(transDeleteParams(officialCheckedRowKeys.value));
|
||||
if (!error && result) {
|
||||
await onOfficialBatchDeleted();
|
||||
}
|
||||
}
|
||||
|
||||
// Tab切换时重新加载数据
|
||||
function handleTabChange(value: string) {
|
||||
activeTab.value = value;
|
||||
if (value === 'enterprise') {
|
||||
getEnterpriseData();
|
||||
} else if (value === 'official') {
|
||||
getOfficialData();
|
||||
}
|
||||
|
||||
// 使用updateSearchParams方法来确保参数正确更新
|
||||
updateSearchParams({
|
||||
type: value,
|
||||
page: 1,
|
||||
pageSize: searchParams.pageSize || 20,
|
||||
customerId
|
||||
});
|
||||
|
||||
// 强制重新计算列定义
|
||||
reloadColumns();
|
||||
|
||||
// 重新加载数据
|
||||
getData();
|
||||
}
|
||||
|
||||
// 确保初始数据加载时使用正确的type
|
||||
onMounted(() => {
|
||||
// 如果当前searchParams.type与activeTab.value不一致,更新searchParams
|
||||
if (searchParams.type !== activeTab.value) {
|
||||
searchParams.type = activeTab.value;
|
||||
getData();
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -302,36 +246,37 @@ function handleTabChange(value: string) {
|
||||
<NTabPane name="enterprise" tab="企业微信配置">
|
||||
<div class="flex-col-stretch gap-8px">
|
||||
<AlertConfigWechatSearch
|
||||
v-model:model="enterpriseSearchParams"
|
||||
v-model:model="searchParams"
|
||||
type="enterprise"
|
||||
@reset="resetEnterpriseSearchParams"
|
||||
@search="getEnterpriseDataByPage"
|
||||
@reset="resetSearchParams"
|
||||
@search="getDataByPage"
|
||||
/>
|
||||
<NCard :bordered="false" class="sm:flex-1-hidden card-wrapper" content-class="flex-col">
|
||||
<TableHeaderOperation
|
||||
v-model:columns="enterpriseColumnChecks"
|
||||
:checked-row-keys="enterpriseCheckedRowKeys"
|
||||
:loading="enterpriseLoading"
|
||||
v-model:columns="columnChecks"
|
||||
:checked-row-keys="checkedRowKeys"
|
||||
:loading="loading"
|
||||
add-auth="t:wechat:alarm:config:add"
|
||||
delete-auth="t:wechat:alarm:config:delete"
|
||||
@add="handleAddEnterprise"
|
||||
@delete="handleEnterpriseBatchDelete"
|
||||
@refresh="getEnterpriseData"
|
||||
@add="handleAdd"
|
||||
@delete="handleBatchDelete"
|
||||
@refresh="getData"
|
||||
/>
|
||||
|
||||
<NDataTable
|
||||
v-model:checked-row-keys="enterpriseCheckedRowKeys"
|
||||
v-model:checked-row-keys="checkedRowKeys"
|
||||
remote
|
||||
striped
|
||||
size="small"
|
||||
class="sm:h-full"
|
||||
:data="enterpriseData"
|
||||
:data="data"
|
||||
:scroll-x="962"
|
||||
:columns="enterpriseColumns"
|
||||
:columns="columns"
|
||||
:flex-height="!appStore.isMobile"
|
||||
:loading="enterpriseLoading"
|
||||
:loading="loading"
|
||||
:single-line="false"
|
||||
:row-key="row => row.id"
|
||||
:pagination="enterpriseMobilePagination"
|
||||
:row-key="(row: any) => row.id"
|
||||
:pagination="mobilePagination"
|
||||
/>
|
||||
</NCard>
|
||||
</div>
|
||||
@@ -341,36 +286,37 @@ function handleTabChange(value: string) {
|
||||
<NTabPane name="official" tab="微信公众号配置">
|
||||
<div class="flex-col-stretch gap-8px">
|
||||
<AlertConfigWechatSearch
|
||||
v-model:model="officialSearchParams"
|
||||
v-model:model="searchParams"
|
||||
type="official"
|
||||
@reset="resetOfficialSearchParams"
|
||||
@search="getOfficialDataByPage"
|
||||
@reset="resetSearchParams"
|
||||
@search="getDataByPage"
|
||||
/>
|
||||
<NCard :bordered="false" class="sm:flex-1-hidden card-wrapper" content-class="flex-col">
|
||||
<TableHeaderOperation
|
||||
v-model:columns="officialColumnChecks"
|
||||
:checked-row-keys="officialCheckedRowKeys"
|
||||
:loading="officialLoading"
|
||||
v-model:columns="columnChecks"
|
||||
:checked-row-keys="checkedRowKeys"
|
||||
:loading="loading"
|
||||
add-auth="t:wechat:alarm:config:add"
|
||||
delete-auth="t:wechat:alarm:config:delete"
|
||||
@add="handleAddOfficial"
|
||||
@delete="handleOfficialBatchDelete"
|
||||
@refresh="getOfficialData"
|
||||
@add="handleAdd"
|
||||
@delete="handleBatchDelete"
|
||||
@refresh="getData"
|
||||
/>
|
||||
|
||||
<NDataTable
|
||||
v-model:checked-row-keys="officialCheckedRowKeys"
|
||||
v-model:checked-row-keys="checkedRowKeys"
|
||||
remote
|
||||
striped
|
||||
size="small"
|
||||
class="sm:h-full"
|
||||
:data="officialData"
|
||||
:data="data"
|
||||
:scroll-x="962"
|
||||
:columns="officialColumns"
|
||||
:columns="columns"
|
||||
:flex-height="!appStore.isMobile"
|
||||
:loading="officialLoading"
|
||||
:loading="loading"
|
||||
:single-line="false"
|
||||
:row-key="row => row.id"
|
||||
:pagination="officialMobilePagination"
|
||||
:row-key="(row: any) => row.id"
|
||||
:pagination="mobilePagination"
|
||||
/>
|
||||
</NCard>
|
||||
</div>
|
||||
@@ -380,19 +326,11 @@ function handleTabChange(value: string) {
|
||||
|
||||
<!-- 弹窗 -->
|
||||
<AlertConfigWechatOperateDrawer
|
||||
v-model:visible="enterpriseDrawerVisible"
|
||||
:operate-type="enterpriseOperateType"
|
||||
:row-data="enterpriseEditingData"
|
||||
type="enterprise"
|
||||
@submitted="getEnterpriseDataByPage"
|
||||
/>
|
||||
|
||||
<AlertConfigWechatOperateDrawer
|
||||
v-model:visible="officialDrawerVisible"
|
||||
:operate-type="officialOperateType"
|
||||
:row-data="officialEditingData"
|
||||
type="official"
|
||||
@submitted="getOfficialDataByPage"
|
||||
v-model:visible="drawerVisible"
|
||||
:operate-type="operateType"
|
||||
:row-data="editingData"
|
||||
:type="activeTab"
|
||||
@submitted="getDataByPage"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,116 +1,2 @@
|
||||
# ================================
|
||||
# BigScreen 项目 .gitignore
|
||||
# ================================
|
||||
|
||||
# 配置文件
|
||||
uploader_config.ini
|
||||
|
||||
# Python 环境和缓存
|
||||
./myenv/
|
||||
__pycache__/
|
||||
*.pyc
|
||||
*.pyo
|
||||
*.pyd
|
||||
|
||||
# ================================
|
||||
# 日志文件 (所有日志)
|
||||
# ================================
|
||||
*.log
|
||||
*.log.*
|
||||
logs/
|
||||
log/
|
||||
|
||||
# ================================
|
||||
# 大文件和数据
|
||||
# ================================
|
||||
# SQL 文件 (通常很大)
|
||||
*.sql
|
||||
!*_schema.sql
|
||||
!migration*.sql
|
||||
|
||||
# 数据库文件
|
||||
*.db
|
||||
*.sqlite
|
||||
*.sqlite3
|
||||
|
||||
# Excel 数据文件
|
||||
*.xlsx
|
||||
*.xls
|
||||
|
||||
# CSV 数据文件 (大于1MB的)
|
||||
worker_health_*.csv
|
||||
|
||||
# ================================
|
||||
# 缓存和临时文件
|
||||
# ================================
|
||||
cache/
|
||||
.cache/
|
||||
uploads/
|
||||
temp/
|
||||
tmp/
|
||||
|
||||
# 性能测试数据
|
||||
performance_*.json
|
||||
*_report.json
|
||||
*_report.log
|
||||
|
||||
# ================================
|
||||
# 静态资源构建输出
|
||||
# ================================
|
||||
static/
|
||||
dist/
|
||||
build/
|
||||
|
||||
# ================================
|
||||
# HTML 大文件
|
||||
# ================================
|
||||
# 交互式地图文件 (通常很大)
|
||||
interactive_*.html
|
||||
mine_topology_map.html
|
||||
map.html
|
||||
|
||||
# 模板文件 (如果是临时的)
|
||||
templates/personal_cool.html
|
||||
templates/index.html
|
||||
./bigScreen/template/index.html
|
||||
|
||||
# ================================
|
||||
# 证书和密钥
|
||||
# ================================
|
||||
*.pem
|
||||
*.key
|
||||
*.crt
|
||||
|
||||
# ================================
|
||||
# 运行时文件
|
||||
# ================================
|
||||
# 进程ID文件
|
||||
*.pid
|
||||
|
||||
# 备份文件
|
||||
*.backup
|
||||
*.bak
|
||||
|
||||
# 测试输出
|
||||
test_*.json
|
||||
test_*.html
|
||||
test_progress.json
|
||||
|
||||
# ================================
|
||||
# Docker 和部署相关
|
||||
# ================================
|
||||
.dockerignore
|
||||
|
||||
# ================================
|
||||
# IDE 和编辑器
|
||||
# ================================
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# ================================
|
||||
# OS 生成文件
|
||||
# ================================
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
# Created by venv; see https://docs.python.org/3/library/venv.html
|
||||
*
|
||||
|
||||
+21
-6
@@ -44,17 +44,32 @@ import java.time.LocalDateTime;
|
||||
@Schema(name = "TWechatAlertConfigVO", description = "Table to store WeChat alert configuration VO 对象")
|
||||
public class TWechatAlertConfigVO extends BaseVO {
|
||||
|
||||
@Schema(description = "WeChat App ID")
|
||||
private String appId;
|
||||
@Schema(description = "Client ID")
|
||||
private Long customerId;
|
||||
|
||||
@Schema(description = "WeChat App Secret")
|
||||
private String appSecret;
|
||||
@Schema(description = "WeChat Type: enterprise/official")
|
||||
private String type;
|
||||
|
||||
@Schema(description = "Enterprise WeChat Corp ID")
|
||||
private String corpId;
|
||||
|
||||
@Schema(description = "Enterprise WeChat Agent ID")
|
||||
private String agentId;
|
||||
|
||||
@Schema(description = "Enterprise WeChat Secret")
|
||||
private String secret;
|
||||
|
||||
@Schema(description = "Official WeChat App ID")
|
||||
private String appid;
|
||||
|
||||
@Schema(description = "Official WeChat App Secret")
|
||||
private String appsecret;
|
||||
|
||||
@Schema(description = "WeChat Template ID")
|
||||
private String templateId;
|
||||
|
||||
@Schema(description = "WeChat User OpenID")
|
||||
private String userOpenid;
|
||||
@Schema(description = "Whether enabled")
|
||||
private Boolean enabled;
|
||||
|
||||
@Schema(description = "User who created the record")
|
||||
private String createUser;
|
||||
|
||||
Binary file not shown.
@@ -1,2 +1,2 @@
|
||||
#Sun Aug 24 15:47:42 IRKT 2025
|
||||
gradle.version=7.3
|
||||
#Wed Aug 27 19:09:11 CST 2025
|
||||
gradle.version=8.9
|
||||
|
||||
Binary file not shown.
@@ -1,11 +1,11 @@
|
||||
arguments=--init-script /var/folders/9_/swlb2qbs6qxctt1zx7cq4m3h0000gn/T/db3b08fc4a9ef609cb16b96b200fa13e563f396e9bb1ed0905fdab7bc3bc513b.gradle --init-script /var/folders/9_/swlb2qbs6qxctt1zx7cq4m3h0000gn/T/52cde0cfcf3e28b8b7510e992210d9614505e0911af0c190bd590d7158574963.gradle
|
||||
arguments=--init-script /var/folders/mm/vmpdh9394f764qzjhxshxd0m0000gn/T/db3b08fc4a9ef609cb16b96b200fa13e563f396e9bb1ed0905fdab7bc3bc513b.gradle --init-script /var/folders/mm/vmpdh9394f764qzjhxshxd0m0000gn/T/52cde0cfcf3e28b8b7510e992210d9614505e0911af0c190bd590d7158574963.gradle
|
||||
auto.sync=true
|
||||
build.scans.enabled=false
|
||||
connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER)
|
||||
connection.project.dir=
|
||||
eclipse.preferences.version=1
|
||||
gradle.user.home=
|
||||
java.home=/Library/Java/JavaVirtualMachines/jdk-17.jdk/Contents/Home
|
||||
java.home=/opt/homebrew/Cellar/openjdk@21/21.0.7/libexec/openjdk.jdk/Contents/Home
|
||||
jvm.arguments=
|
||||
offline.mode=false
|
||||
override.workspace.settings=true
|
||||
|
||||
Reference in New Issue
Block a user