Compare commits

..

No commits in common. "e12b7cedfabddef8c0e8f4af35a2563587e210fd" and "8cbd9cc530beebe6bd12fe919e53af8da5dd27a5" have entirely different histories.

5 changed files with 52 additions and 201 deletions

View File

@ -111,7 +111,6 @@ export type ComponentType =
| 'CheckboxGroup'
| 'DatePicker'
| 'DefaultButton'
| 'DeviceSelect'
| 'Divider'
| 'IconPicker'
| 'Input'
@ -169,10 +168,6 @@ async function initComponentAdapter() {
Checkbox,
CheckboxGroup,
DatePicker,
// 自定义设备选择组件
DeviceSelect: defineAsyncComponent(() =>
import('../../views/dataManger/deviceData/DeviceSelect.vue')
),
// 自定义默认按钮
DefaultButton: (props, { attrs, slots }) => {
return h(Button, { ...props, attrs, type: 'default' }, slots);

View File

@ -1,9 +1,4 @@
/*
* @Description:
* @Author:
* @Date: 2025-06-19 15:33:54
* @LastEditors:
*/
export * from './auth';
export * from './menu';
export * from './onenet';
export * from './user';

View File

@ -1,160 +0,0 @@
<script setup lang="ts">
import { ref, computed } from 'vue';
import { Select, Divider, Row } from 'ant-design-vue';
import { ChevronLeft, ChevronRight } from '@vben/icons';
import { postMetersPage } from '#/api-client';
import { $t } from '#/locales';
import { useDebounceFn } from '@vueuse/core';
interface Props {
value?: string;
placeholder?: string;
disabled?: boolean;
allowClear?: boolean;
}
const props = withDefaults(defineProps<Props>(), {
placeholder: $t('common.pleaseSelect') + $t('abp.log.deviceInfo'),
disabled: false,
allowClear: true,
});
const emit = defineEmits<{
'update:value': [string];
change: [string];
'device-change': [any]; //
}>();
const VNodes = (_, { attrs }: any) => {
return attrs.vnodes;
};
const options = ref<any[]>([]);
const query = ref({
pageIndex: 1,
pageSize: 10,
SearchKeyword: '',
});
const total = ref(0);
const loading = ref<boolean>(false);
//
const maxPage = computed(() => {
return Math.ceil(total.value / query.value.pageSize);
});
/**
* 获取设备列表数据
*/
const fetchData = async () => {
loading.value = true;
try {
const { data } = await postMetersPage({
body: {
pageIndex: query.value.pageIndex,
pageSize: query.value.pageSize,
SearchKeyword: query.value.SearchKeyword,
},
});
if (data?.items) {
options.value = data.items.map((item) => ({
label: item.meterName,
value: item.id,
...item, //
}));
total.value = data.totalCount || 0;
}
loading.value = false;
} catch (error) {
console.error('获取设备列表失败:', error);
loading.value = false;
}
};
/**
* 上下页
* @param type 1: 下一页, 0: 上一页
*/
const changePage = (type: number) => {
if (type === 1) {
if (query.value.pageIndex >= maxPage.value) return;
query.value.pageIndex += 1;
fetchData();
} else {
if (query.value.pageIndex <= 1) return;
query.value.pageIndex -= 1;
fetchData();
}
};
/**
* 设备搜索
*/
const fetchDevice = useDebounceFn((value: string) => {
query.value.pageIndex = 1;
query.value.SearchKeyword = value;
fetchData();
}, 500);
//
const handleValueChange = (value: string) => {
emit('update:value', value);
emit('change', value);
//
if (value) {
const selectedDevice = options.value.find(option => option.value === value);
if (selectedDevice) {
emit('device-change', selectedDevice);
}
} else {
emit('device-change', null);
}
};
//
fetchData();
</script>
<template>
<Select
:value="value"
:showSearch="true"
@search="fetchDevice"
:options="options"
:placeholder="placeholder"
:filter-option="false"
:disabled="disabled"
:allowClear="allowClear"
:loading="loading"
@change="handleValueChange"
>
<template #dropdownRender="{ menuNode: menu }">
<v-nodes :vnodes="menu" />
<Divider style="margin: 4px 0" />
<div @mousedown="(e) => e.preventDefault()">
<Row type="flex" justify="space-around" align="middle">
<ChevronLeft
@click="changePage(0)"
:class="{ 'text-gray-400': query.pageIndex <= 1 }"
style="cursor: pointer; width: 16px; height: 16px;"
/>
<div>{{ `${query.pageIndex}/${maxPage}` }}</div>
<ChevronRight
@click="changePage(1)"
:class="{ 'text-gray-400': query.pageIndex >= maxPage }"
style="cursor: pointer; width: 16px; height: 16px;"
/>
</Row>
</div>
</template>
</Select>
</template>
<style lang="less" scoped>
.text-gray-400 {
color: #9ca3af;
cursor: not-allowed !important;
}
</style>

View File

@ -20,10 +20,8 @@ defineOptions({
//
const deviceOptions = ref<any[]>([]);
//
const selectedDeviceInfo = ref<any>(null);
// ID
//
const fetchDeviceOptions = async () => {
try {
const { data } = await postMetersPage({
@ -47,12 +45,6 @@ const getDeviceInfoById = (deviceId: string) => {
return deviceOptions.value.find((device) => device.id === deviceId);
};
//
const handleDeviceChange = (deviceInfo: any) => {
selectedDeviceInfo.value = deviceInfo;
console.log('设备选择变化:', deviceInfo);
};
const route = useRoute();
const { DeviceType, DeviceId, FocusAddress, SystemName } = route.query;
@ -130,10 +122,6 @@ const formOptions: VbenFormProps = {
}, 0);
}
},
//
events: {
handleDeviceChange,
},
};
const gridOptions: VxeGridProps<any> = {
@ -185,20 +173,20 @@ const gridOptions: VxeGridProps<any> = {
// DeviceId(10)使focusId
let finalDeviceId = formValues.DeviceId || DeviceId;
let finalFocusAddress = formValues.FocusAddress;
// 使
const deviceInfo = selectedDeviceInfo.value || (formValues.DeviceId ? getDeviceInfoById(formValues.DeviceId) : null);
if (deviceInfo) {
finalFocusAddress = deviceInfo.focusAddress;
if (deviceTypeNumber === 10) {
// 使focusId
if (deviceInfo.focusId) {
finalDeviceId = deviceInfo.focusId;
}
} else {
// 使meterId
if (deviceInfo.meterId) {
finalDeviceId = deviceInfo.meterId;
if (formValues.DeviceId) {
const deviceInfo = getDeviceInfoById(formValues.DeviceId);
if (deviceInfo) {
finalFocusAddress = deviceInfo.focusAddress;
if (deviceTypeNumber === 10) {
// 使focusId
if (deviceInfo.focusId) {
finalDeviceId = deviceInfo.focusId;
}
} else {
// 使meterId
if (deviceInfo.meterId) {
finalDeviceId = deviceInfo.meterId;
}
}
}
}

View File

@ -106,13 +106,46 @@ export const querySchema = computed(() => [
},
},
{
component: 'DeviceSelect',
component: 'ApiSelect',
fieldName: 'DeviceId',
label: $t('abp.log.deviceInfo'),
componentProps: {
placeholder: $t('common.pleaseSelect') + $t('abp.log.deviceInfo'),
api: postMetersPage,
params: {
body: {
pageIndex: 1,
pageSize: 1000, // 获取足够多的数据用于下拉选择
},
},
labelField: 'meterName',
valueField: 'id', // 使用id作为值这样可以获取完整的对象
optionsPropName: 'options',
immediate: true,
showSearch: true,
allowClear: true,
onDeviceChange: 'handleDeviceChange',
placeholder: $t('common.pleaseSelect') + $t('abp.log.deviceInfo'),
filterOption: false, // 禁用本地过滤,使用服务端搜索
optionFilterProp: 'label', // 根据 label 进行过滤
afterFetch: (res: any) => {
// 确保返回的是数组格式
if (Array.isArray(res)) {
return res;
}
// 如果是包装在 items 中的,提取出来
if (res && Array.isArray(res.items)) {
return res.items;
}
// 如果是包装在 data 中的,提取出来
if (res && Array.isArray(res.data)) {
return res.data;
}
// 如果是包装在 data.items 中的,提取出来
if (res && res.data && Array.isArray(res.data.items)) {
return res.data.items;
}
// 如果都不是,返回空数组
return [];
},
},
},
]);