diff --git a/src/views/device/apdevice/index.vue b/src/views/device/apdevice/index.vue
index 193d0f4..f8dc096 100644
--- a/src/views/device/apdevice/index.vue
+++ b/src/views/device/apdevice/index.vue
@@ -14,13 +14,32 @@
class="flex-col-stretch sm:flex-1-hidden card-wrapper"
>
-
+
+
+ {{ site.name }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ t('page.apdevice.useSiteSettings') }}
+ {{ t('page.apdevice.on') }}
+ {{ t('page.apdevice.off') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -63,10 +229,12 @@ import { useTable } from '@/hooks/common/table';
import { SimpleScrollbar } from '~/packages/materials/src';
import { computed, shallowRef } from 'vue';
import { useElementSize } from '@vueuse/core';
-import { fetchApDeviceList } from '@/service/api/auth';
-import { Card as ACard, Table as ATable, Tag as ATag } from 'ant-design-vue';
+import { fetchApDeviceList,forgetApDevice, addApDevice } from '@/service/api/auth';
+import {Card as ACard, Table as ATable, Tag as ATag, Modal, message } from 'ant-design-vue';
import DeviceSearch from './modules/device-search.vue';
import { useI18n } from 'vue-i18n';
+import { SettingOutlined, DeleteOutlined, ReloadOutlined,PlusOutlined } from '@ant-design/icons-vue';
+import {Rule} from "ant-design-vue/es/form";
const { t } = useI18n();
const wrapperEl = shallowRef(null);
@@ -77,6 +245,42 @@ const scrollConfig = computed(() => ({
x: 800
}));
+// 添加站点相关的状态
+const siteList = ref([]);
+const selectedSiteId = ref('');
+const siteLoading = ref(false);
+
+// 获取站点列表
+const getSiteList = async () => {
+ try {
+ siteLoading.value = true;
+ const response = await fetchSiteList({
+ pageNum: 1,
+ pageSize: 100
+ });
+
+ // 适配新的响应格式
+ siteList.value = response.data.rows || [];
+
+ // 如果有站点数据,默认选择第一个
+ if (siteList.value.length > 0) {
+ selectedSiteId.value = siteList.value[0].siteId; // 使用 siteId 而不是 id
+ await getData();
+ }
+ } catch (error) {
+ console.error('Get site list error:', error);
+ message.error(t('page.apdevice.getSiteError'));
+ } finally {
+ siteLoading.value = false;
+ }
+};
+
+// 处理站点变更
+const handleSiteChange = async (value: string) => {
+ selectedSiteId.value = value;
+ await getData();
+};
+
const {
columns,
columnChecks,
@@ -86,15 +290,22 @@ const {
mobilePagination,
searchParams,
} = useTable({
- apiFn: async (params: Api.Device.ApDeviceParams) => {
- try {
- console.log('Fetching with params:', JSON.stringify(params, null, 2));
- const response = await fetchApDeviceList(params);
- console.log('API Response:', response);
+ apiFn: async (params: { searchKey?: string; pageNum: number; pageSize: number }) => {
+ if (!selectedSiteId.value) {
return {
data: {
- rows: response.data || [],
- total: Array.isArray(response.data) ? response.data.length : 0
+ rows: [],
+ total: 0
+ }
+ };
+ }
+
+ try {
+ const response = await fetchApDeviceList(selectedSiteId.value, params);
+ return {
+ data: {
+ rows: response.data.rows,
+ total: response.data.total
}
};
} catch (error) {
@@ -108,7 +319,7 @@ const {
};
}
},
- immediate: true,
+ immediate: false,
apiParams: {
pageNum: 1,
pageSize: 10,
@@ -159,6 +370,13 @@ const {
title: t('page.apdevice.status'),
align: 'center',
width: 100
+ },
+ {
+ key: 'operate',
+ title: t('common.operate'),
+ align: 'center',
+ width: 100,
+ fixed: 'right'
}
]
});
@@ -184,14 +402,312 @@ const handleReset = () => {
const currentPageSize = searchParams.pageSize;
// 重置搜索参数
- searchParams.name = '';
- searchParams.mac = '';
+ searchParams.searchKey = '';
searchParams.pageNum = 1;
searchParams.pageSize = currentPageSize;
// 重新获取数据
getData();
};
+
+
+// 添加相关的处理函数
+// 处理打开配置对话框
+const handleEditConfig = async (record: Api.Device.ApDevice) => {
+ try {
+ if (!selectedSiteId.value) {
+ throw new Error('No site selected');
+ }
+
+ const hide = message.loading(t('common.loading'), 0);
+
+ // 先获取设备当前的配置
+ const response = await getApDeviceConfig(selectedSiteId.value, record.mac);
+
+ hide();
+
+ // 保存当前编辑的设备信息
+ currentDevice.value = record;
+
+ // 使用获取到的配置更新表单,处理 null 和嵌套对象
+ configForm.value = {
+ name: response.data?.name || record.name,
+ ledSetting: response.data?.ledSetting ?? 2, // 如果没有设置,默认使用站点设置
+ // tagIds: response.data?.tagIds || [], // 暂时注释掉
+ longitude: response.data?.location?.longitude,
+ latitude: response.data?.location?.latitude,
+ address: response.data?.location?.address || ''
+ };
+
+ // 显示配置对话框
+ configVisible.value = true;
+ } catch (error) {
+ console.error('Get device config error:', error);
+ message.error(t('page.apdevice.getConfigError'));
+ }
+};
+
+const handleForgetDevice = (record: Api.Device.ApDevice) => {
+ Modal.confirm({
+ title: t('common.confirm'),
+ content: t('page.apdevice.forgetConfirm'),
+ onOk: async () => {
+ try {
+ const hide = message.loading(t('common.loading'), 0);
+ console.log('Forgetting device:', record);
+
+ if (!selectedSiteId.value || !record.mac) {
+ throw new Error('Missing required parameters: siteId or mac');
+ }
+
+ // 使用当前选中的 siteId
+ const response = await forgetApDevice(selectedSiteId.value, record.mac);
+ console.log('Forget device response:', response);
+
+ hide();
+ message.success(t('page.apdevice.forgetSuccess'));
+
+ // 重新获取列表数据
+ getData();
+ } catch (error) {
+ console.error('Forget device error:', error);
+ message.error(t('page.apdevice.forgetError'));
+ throw error;
+ }
+ }
+ });
+};
+
+const handleRestart = (record: Api.Device.ApDevice) => {
+ // 处理重启设备
+ Modal.confirm({
+ title: t('common.confirm'),
+ content: t('page.apdevice.restartConfirm'),
+ onOk: async () => {
+ // 调用重启设备 API
+ console.log('Restart device:', record);
+ }
+ });
+};
+
+// 纳管表单数据
+const adoptForm = ref({
+ username: '',
+ password: ''
+});
+
+// 纳管对话框可见性
+const adoptVisible = ref(false);
+
+// 当前要纳管的设备
+const adoptingDevice = ref(null);
+
+// 处理纳管按钮点击
+const handleAdopt = (record: Api.Device.ApDevice) => {
+ adoptingDevice.value = record;
+ adoptForm.value = {
+ username: '',
+ password: ''
+ };
+ adoptVisible.value = true;
+};
+
+// 处理纳管确认
+const handleAdoptConfirm = async () => {
+ try {
+ if (!adoptingDevice.value || !selectedSiteId.value) {
+ throw new Error('Missing device or site information');
+ }
+
+ const hide = message.loading(t('common.loading'), 0);
+
+ // 构造请求参数,只有在有值时才包含
+ const params: { username?: string; password?: string } = {};
+ if (adoptForm.value.username) {
+ params.username = adoptForm.value.username;
+ }
+ if (adoptForm.value.password) {
+ params.password = adoptForm.value.password;
+ }
+
+ await adoptApDevice(selectedSiteId.value, adoptingDevice.value.mac, params);
+
+ hide();
+ message.success(t('page.apdevice.adoptSuccess'));
+ adoptVisible.value = false;
+
+ // 重新获取列表数据
+ getData();
+ } catch (error) {
+ console.error('Adopt device error:', error);
+ message.error(t('page.apdevice.adoptError'));
+ }
+};
+
+
+// 修改表单验证规则的定义
+const addDeviceRules = {
+ sn: [
+ { required: true, message: t('page.apdevice.snRequired'), trigger: 'blur' },
+ {
+ pattern: /^[A-Z0-9]{13}$/,
+ message: t('page.apdevice.snFormatError'),
+ trigger: 'blur'
+ }
+ ] as Rule[],
+ name: [
+ {
+ pattern: /^[^ \+\-\@\=]$|^[^ \+\-\@\=].{0,126}[^ ]$/,
+ message: t('page.apdevice.nameFormatError'),
+ trigger: 'blur'
+ }
+ ] as Rule[]
+};
+
+// 添加设备的表单数据
+const addDeviceForm = ref({
+ sn: '',
+ name: '',
+ username: '',
+ password: ''
+});
+
+// 添加设备对话框的可见性
+const addDeviceVisible = ref(false);
+
+// 处理添加设备
+const handleAdd = () => {
+ addDeviceVisible.value = true;
+};
+
+// 处理添加设备的确认
+const handleAddConfirm = async () => {
+ try {
+ // 先验证表单
+ await formRef.value?.validate();
+
+ const hide = message.loading(t('common.loading'), 0);
+
+ // 构造请求参数,即使所有字段都为空也要发送一个空对象
+ // 构造请求参数,确保 sn 字段存在
+ const deviceParams: Api.Device.AddApDeviceItem = {
+ sn: addDeviceForm.value.sn // sn 是必填的
+ };
+
+ // 只添加其他有值的字段
+ if (addDeviceForm.value.name) {
+ deviceParams.name = addDeviceForm.value.name;
+ }
+ if (addDeviceForm.value.username) {
+ deviceParams.username = addDeviceForm.value.username;
+ }
+ if (addDeviceForm.value.password) {
+ deviceParams.password = addDeviceForm.value.password;
+ }
+
+ await addApDevice(selectedSiteId.value, deviceParams);
+
+ hide();
+ message.success(t('page.apdevice.addSuccess'));
+ addDeviceVisible.value = false;
+
+ // 清空表单
+ addDeviceForm.value = {
+ sn: '',
+ name: '',
+ username: '',
+ password: ''
+ };
+
+ // 重新获取列表数据
+ getData();
+ } catch (error) {
+ console.error('Add device error:', error);
+ message.error(t('page.apdevice.addError'));
+ }
+};
+// 添加表单引用
+const formRef = ref();
+// 配置表单的数据
+const configForm = ref({
+ name: '',
+ ledSetting: 2,
+ // tagIds: [],
+ longitude: undefined,
+ latitude: undefined,
+ address: ''
+});
+
+// 配置对话框的可见性
+const configVisible = ref(false);
+
+// 配置表单的验证规则
+const configRules = {
+ name: [
+ {
+ pattern: /^[^ \+\-\@\=]$|^[^ \+\-\@\=].{0,126}[^ ]$/,
+ message: t('page.apdevice.nameFormatError'),
+ trigger: 'blur'
+ }
+ ] as Rule[],
+ longitude: [
+ {
+ type: 'number',
+ min: -180,
+ max: 180,
+ message: t('page.apdevice.longitudeError'),
+ trigger: 'change'
+ }
+ ] as Rule[],
+ latitude: [
+ {
+ type: 'number',
+ min: -90,
+ max: 90,
+ message: t('page.apdevice.latitudeError'),
+ trigger: 'change'
+ }
+ ] as Rule[]
+};
+
+// 当前编辑的设备
+const currentDevice = ref(null);
+
+// 处理配置确认
+const handleConfigConfirm = async () => {
+ try {
+ await configFormRef.value?.validate();
+
+ if (!currentDevice.value || !selectedSiteId.value) {
+ throw new Error('Missing device or site information');
+ }
+
+ const hide = message.loading(t('common.loading'), 0);
+
+ await updateApDeviceConfig(
+ selectedSiteId.value,
+ currentDevice.value.mac,
+ configForm.value
+ );
+
+ hide();
+ message.success(t('page.apdevice.configSuccess'));
+ configVisible.value = false;
+
+ // 重新获取列表数据
+ getData();
+ } catch (error) {
+ console.error('Update config error:', error);
+ message.error(t('page.apdevice.configError'));
+ }
+};
+
+// 配置表单引用
+const configFormRef = ref();
+// 在组件挂载时获取站点列表
+onMounted(() => {
+ getSiteList();
+});