Commit 06e498d544c28b192d9fc8d44a493a1543b55e8d

Authored by gesilong
1 parent 33f0225a

commit: 设备台账联调;相关组件开发

  1 +import {defHttp} from "/@/utils/http/axios";
  2 +import {omit} from "lodash-es";
  3 +
  4 +/**
  5 + * 列表
  6 + */
  7 +
  8 +export const getLedgerList = (params) => {
  9 + const { page, pageSize } = params;
  10 + const otherParams = omit(params, ['page', 'pageSize']);
  11 + return defHttp.post<any>({
  12 + url: `/da/pageData?page=${page}&pageSize=${pageSize}`,
  13 + params: otherParams,
  14 + });
  15 +};
  16 +
  17 +
  18 +/**
  19 +*组织
  20 +*/
  21 +export const getOrgList = () => {
  22 + return defHttp.get<any>({
  23 + url: `/organization/me/list`,
  24 + });
  25 +};
  26 +
  27 +/**
  28 +*组织
  29 +*/
  30 +export const getUserListByOrg = (params) => {
  31 + return defHttp.get<any>({
  32 + url: `/user/tenant/page`,
  33 + params,
  34 + });
  35 +};
  36 +
  37 +/**
  38 + * 新增
  39 + */
  40 +export const saveLedger = (params) => {
  41 + return defHttp.post<any>({
  42 + url: `/da/save`,
  43 + params,
  44 + });
  45 +};
  46 +
  47 +/**
  48 + *详情
  49 + */
  50 +export const ledgerEditDetailPage = (params) => {
  51 + return defHttp.get<any>({
  52 + url: `/da/detail`,
  53 + params,
  54 + });
  55 +};
  56 +/**
  57 + *删除
  58 + */
  59 +export const deleteLedger = (params) => {
  60 + return defHttp.get<any>({
  61 + url: `/da/delete`,
  62 + params,
  63 + });
  64 +};
... ...
... ... @@ -132,6 +132,7 @@ export type ComponentType =
132 132 | 'ControlGroup'
133 133 | 'JSONEditor'
134 134 | 'OrgTreeSelect'
  135 + | 'CategoryTreeSelect'
135 136 | 'CreateSpeed'
136 137 | 'ExtendDesc'
137 138 | 'JavaScriptFunctionEditor'
... ...
... ... @@ -51,6 +51,12 @@ export enum DeviceStatusEnum {
51 51 OFFLINE = 'OFFLINE',
52 52 }
53 53
  54 +export enum SbStatusEnum {
  55 + FAULT = 'FAULT',
  56 + NORMAL = 'NORMAL',
  57 + SCRAP = 'SCRAP',
  58 +}
  59 +
54 60 export enum CommandStatusEnum {
55 61 QUEUED = 'QUEUED',
56 62 SENT = 'SENT',
... ...
1 1 export default {
2 2 productText: '产品',
3 3 deviceText: '设备',
  4 + codeText: '设备编码',
  5 + brandText: '设备品牌',
4 6 attributeText: '属性',
5 7 organizationText: '组织',
6 8 tenantText: '租户',
... ... @@ -29,4 +31,5 @@ export default {
29 31 commandDeliveryText: '命令下发',
30 32 serviceText: '服务',
31 33 dateRangeText: '时间范围',
  34 + directorName: '负责人',
32 35 };
... ...
... ... @@ -85,6 +85,12 @@ export default {
85 85 ONLINE: '在线',
86 86 OFFLINE: '离线',
87 87 },
  88 + sbStatus: {
  89 + ALL: '全部',
  90 + FAULT: '故障',
  91 + NORMAL: '正常',
  92 + SCRAP: '报废',
  93 + },
88 94 commandStatus: {
89 95 QUEUED: '队列中',
90 96 SENT: '已发送',
... ...
... ... @@ -6,4 +6,5 @@ export default {
6 6 orderText: '排序',
7 7 description: '描述',
8 8 operationSuccessText: '操作成功',
  9 + categoryPlaceholderText: '请选择设备类别',
9 10 };
... ...
1 1 export default {
2 2 ledgerListText: '台账列表',
  3 + nameCode: '设备编码',
  4 + brandText: '设备编码',
  5 + modelNumText: '型号',
  6 + buyDate: '购买时间',
  7 + productDate: '出厂日期',
  8 + registeDate: '登记日期',
  9 + receiveDate: '验收日期',
  10 + priceText: '价格',
  11 + specificationsText: '规格',
  12 + manufacturerText: '生产厂家',
  13 + description: '备注',
3 14 createLedgerText: '创建台账',
  15 + editLedgerText: '编辑台账',
4 16 importLedgerText: '导入台账',
5 17 deviceName: '设备名称',
6 18 deviceCode: '设备编码',
7 19 deviceType: '设备类型',
8 20 status: '状态',
9   - description: '负责人',
10 21 operationSuccessText: '操作成功',
11 22 editProductText: '编辑台账',
12 23 updateOrganization: '修改组织',
13 24 batchActionText: '批量操作',
  25 + FAULT: '故障',
  26 + NORMAL: '正常',
  27 + SCRAP: '报废',
14 28 }
... ...
  1 +export { default as CategoryTreeSelect } from './index.vue';
... ...
  1 +<template>
  2 + <section class="!flex">
  3 + <ApiTreeSelect v-bind="getBindProps" class="flex-auto" />
  4 + <Button v-if="getShowCreate" type="link" @click="handleOpenCreate" :disabled="disabled">
  5 + {{ t('component.orgSelect.createOrganizationText') }}
  6 + </Button>
  7 + <OrganizationDrawer v-if="getShowCreate" @register="registerDrawer" @success="handleReload" />
  8 + </section>
  9 +</template>
  10 +<script setup lang="ts">
  11 +import { ApiTreeSelect } from '/@/components/Form';
  12 +import { Button } from 'ant-design-vue';
  13 +import {computed, ref, unref} from "vue";
  14 +import {getAllCategory} from "/@/api/equipment/category";
  15 +import {useI18n} from "/@/hooks/web/useI18n";
  16 +const { t } = useI18n();
  17 +const emit = defineEmits(['change', 'optionsChange']);
  18 +
  19 +const props = withDefaults(
  20 + defineProps<{
  21 + value?: string | string[];
  22 + apiTreeSelectProps?: Recordable;
  23 + showCreate?: boolean;
  24 + disabled?: boolean;
  25 + }>(),
  26 + {
  27 + showCreate: true,
  28 + disabled: false,
  29 + }
  30 +);
  31 +const timespan = ref(Date.now());
  32 +const needReload = ref(true);
  33 +const cateList = ref<Recordable[]>([]);
  34 +const getBindProps = computed<Recordable>(() => {
  35 + const { value, apiTreeSelectProps = {}, disabled } = props;
  36 + const { params = {} } = apiTreeSelectProps;
  37 + return {
  38 + replaceFields: { children: 'children', key: 'id', title: 'name', value: 'id' },
  39 + getPopupContainer: () => document.body,
  40 + placeholder: t('equipment.category.categoryPlaceholderText'),
  41 + maxLength: 250,
  42 + disabled,
  43 + ...apiTreeSelectProps,
  44 + value,
  45 + dropdownStyle: { maxHeight: '300px' },
  46 + api: async (params: any) => {
  47 + try {
  48 + if (!unref(needReload)) return unref(cateList);
  49 + const result = ((await getAllCategory(params)) as unknown as Recordable[]) || [];
  50 + cateList.value = result;
  51 + needReload.value = false;
  52 + return result;
  53 + } catch (error) {
  54 + return unref(cateList);
  55 + }
  56 + },
  57 + params: {
  58 + ...params,
  59 + _t: unref(timespan),
  60 + },
  61 + onChange: (...args: any[]) => {
  62 + emit('change', ...args);
  63 + },
  64 + onOptionsChange: (...args: any[]) => emit('optionsChange', ...args),
  65 + };
  66 +});
  67 +
  68 +</script>
... ...
... ... @@ -8,11 +8,15 @@
8 8
9 9 import { ref } from 'vue';
10 10 import organizationIdTree from '../OrganizationIdTree.vue';
11   -export const useResetOrganizationTree = (searchInfo: Recordable) => {
  11 +export const useResetOrganizationTree = (searchInfo: Recordable, type?: string) => {
12 12 const organizationIdTreeRef = ref<InstanceType<typeof organizationIdTree>>();
13 13 async function resetFn() {
14 14 organizationIdTreeRef.value.resetOrganization();
15   - searchInfo.organizationId = null;
  15 + if (type === 'equipment') {
  16 + searchInfo.categoryId = null;
  17 + }else {
  18 + searchInfo.organizationId = null;
  19 + }
16 20 }
17 21 return { organizationIdTreeRef, resetFn };
18 22 };
... ...
... ... @@ -25,6 +25,7 @@
25 25 import { computed, onMounted, ref, unref, useAttrs } from 'vue';
26 26 import { BasicTree, TreeItem } from '/@/components/Tree';
27 27 import { getOrganizationList } from '/@/api/system/system';
  28 + import { getAllCategory } from '/@/api/equipment/category';
28 29 import { CaretRightOutlined } from '@ant-design/icons-vue';
29 30 import { getBoundingClientRect } from '/@/utils/domUtils';
30 31 import { BasicTreePropsType, OrganizationTreeActionType } from './types';
... ... @@ -34,7 +35,6 @@
34 35 const props = defineProps<OrganizationTreePropsType>();
35 36
36 37 const attrs = useAttrs();
37   -
38 38 const tree = ref<Nullable<HTMLDivElement>>();
39 39 const emit = defineEmits(['select', 'register']);
40 40 const treeData = ref<TreeItem[]>([]);
... ... @@ -75,7 +75,14 @@
75 75 };
76 76
77 77 onMounted(async () => {
78   - treeData.value = (await getOrganizationList()) as unknown as TreeItem[];
  78 + let api:any;
  79 + if (attrs?.listType === 'equipment') {
  80 + api = getAllCategory()
  81 + }else {
  82 + api = getOrganizationList()
  83 + }
  84 +
  85 + treeData.value = (await api) as unknown as TreeItem[];
79 86 const getAllIds = findForAllId(treeData.value as any, []);
80 87 //设置要展开的id
81 88 treeExpandData.value = getAllIds;
... ... @@ -88,12 +95,11 @@
88 95 });
89 96
90 97 const getProps = computed<OrganizationTreePropsType>(() => ({ ...props, ...unref(innerProps) }));
91   -
92 98 const { t } = useI18n();
93 99
94 100 const getBindData = computed(() => {
95 101 return {
96   - title: t('common.organizationList'),
  102 + title: attrs?.listType === 'equipment' ? t('equipment.category.categoryText') : t('common.organizationList'),
97 103 toolbar: true,
98 104 search: true,
99 105 clickRowToExpand: false,
... ...
1 1 export interface OrganizationTreePropsType {
2 2 onSelect?: (selectKeys: string) => any;
  3 + listType?: string;
3 4 }
... ...
  1 +<template>
  2 + <BasicDrawer
  3 + destroyOnClose
  4 + v-bind="$attrs"
  5 + showFooter
  6 + width="35%"
  7 + :maskClosable="true"
  8 + :title="businessText"
  9 + @register="registerDrawer"
  10 + wrapClassName="report-drawer"
  11 + @ok="handleSubmit"
  12 + @close="handleClose"
  13 + >
  14 + <BasicForm @register="registerForm">
  15 +
  16 + </BasicForm>
  17 + </BasicDrawer>
  18 +</template>
  19 +<script setup lang="ts">
  20 +import {nextTick, reactive, ref} from "vue";
  21 +import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
  22 +import { SchemaFiled} from "../../config/enum";
  23 +import {BasicForm,useForm} from "/@/components/Form";
  24 +import {formSchema} from "../../config/data";
  25 +import {useHooks} from "/@/views/report/config/hooks/index.hooks";
  26 +import {getUserListByOrg,ledgerEditDetailPage,saveLedger } from "/@/api/equipment/ledger"
  27 +import {useUserStore} from "/@/store/modules/user";
  28 +import {useThrottleFn} from "@vueuse/shared/index";
  29 +import {useMessage} from "/@/hooks/web/useMessage";
  30 +import {useI18n} from "/@/hooks/web/useI18n";
  31 +const {
  32 + setDefaultTime,
  33 + disableCustomWeekly,
  34 + setPropsForModal,
  35 + removeFields,
  36 +} = useHooks();
  37 +const userInfo = useUserStore();
  38 +const restData = reactive({
  39 + data: {},
  40 +});
  41 +const { createMessage } = useMessage();
  42 +const { t } = useI18n();
  43 +const emits = defineEmits(['success', 'register']);
  44 +const [registerForm, { validate, resetFields, setFieldsValue, updateSchema, setProps }] = useForm(
  45 + {
  46 + labelWidth: 140,
  47 + schemas: formSchema,
  48 + showActionButtonGroup: false,
  49 + fieldMapToTime: [[SchemaFiled.DATE_RANGE, [SchemaFiled.START_TS, SchemaFiled.END_TS]]],
  50 + }
  51 +);
  52 +// 定义人员选项
  53 +const userOptions = ref<any[]>([]);
  54 +
  55 +// 监听 org 字段的变化
  56 +const handleOrgChange = async (orgId: string) => {
  57 + if (!orgId) {
  58 + userOptions.value = []; // 清空人员选项
  59 + updateSchema({
  60 + field: 'directorId',
  61 + componentProps: { options: [] },
  62 + });
  63 + return;
  64 + }
  65 + const _data = {
  66 + page: '1',
  67 + pageSize: '999',
  68 + tenantId: userInfo.getUserInfo.tenantId!,
  69 + organizationId: orgId
  70 + }
  71 + // 调用接口 B 获取人员数据
  72 + const userList = await getUserListByOrg(_data);
  73 + console.log(userList,'userList')
  74 + userOptions.value = userList?.items.map(user => ({
  75 + label: user.username,
  76 + value: user.id,
  77 + }));
  78 +
  79 + // 更新 user 字段的选项
  80 + updateSchema({
  81 + field: 'directorId',
  82 + componentProps: { options: userOptions.value },
  83 + });
  84 +};
  85 +
  86 +
  87 +
  88 +
  89 +const businessText = ref('');
  90 +const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
  91 + try {
  92 + await nextTick();
  93 + handleClose();
  94 + businessText.value = data.text;
  95 + // 更新 formSchema 中的 org 字段,绑定 change 事件
  96 + updateSchema({
  97 + field: 'org',
  98 + componentProps: {
  99 + onChange: handleOrgChange,
  100 + },
  101 + });
  102 + setFieldsValue(setDefaultTime());
  103 + updateSchema(disableCustomWeekly(0));
  104 + setDrawerProps(setPropsForModal(businessText.value));
  105 + if (businessText.value === 'add') return;
  106 + const rest = await ledgerEditDetailPage({id: data.record?.id});
  107 + restData.data = rest ?? {};
  108 +
  109 + await setFieldsValue({
  110 + ...restData.data,
  111 + });
  112 +
  113 + } finally {
  114 + setDrawerProps({ loading: false });
  115 + }
  116 +});
  117 +const handleClose = () => {
  118 + resetValue();
  119 +}
  120 +//重置表单
  121 +const resetValue = () => {
  122 + resetFields();
  123 +};
  124 +
  125 +const handleSubmit = () => {
  126 + useThrottle();
  127 +};
  128 +
  129 +const useThrottle = useThrottleFn(() => {
  130 + getValue();
  131 +}, 2000);
  132 +
  133 +const getValue = async () => {
  134 + try {
  135 + setDrawerProps({ confirmLoading: true });
  136 + const values = await validate();
  137 + if (!values) return;
  138 + const data = {
  139 + ...values,
  140 + buyDate: values.buyDate?.format('YYYY-MM-DD hh:mm:ss'),
  141 + productDate: values.productDate?.format('YYYY-MM-DD hh:mm:ss'),
  142 + receiveDate: values.receiveDate?.format('YYYY-MM-DD hh:mm:ss'),
  143 + registeDate: values.registeDate?.format('YYYY-MM-DD hh:mm:ss'),
  144 + };
  145 + removeFields.forEach((item) => {
  146 + Reflect.deleteProperty(data, item);
  147 + });
  148 + businessText.value === 'add'
  149 + ? await saveLedger(data)
  150 + : saveLedger({ ...restData.data, ...data });
  151 + createMessage.success(
  152 + t(businessText.value !== 'add' ? 'common.editSuccessText' : 'common.createSuccessText')
  153 + );
  154 + closeDrawer();
  155 + handleClose();
  156 + setTimeout(() => {
  157 + emits('success');
  158 + }, 500);
  159 + } finally {
  160 + setDrawerProps({ confirmLoading: false });
  161 + }
  162 +};
  163 +
  164 +</script>
... ...
  1 +import LedgerDrawer from './LedgerDrawer.vue';
  2 +
  3 +export { LedgerDrawer };
... ...
1   -import { FormSchema, useComponentRegister } from '/@/components/Form';
2   -import { findDictItemByCode } from '/@/api/system/dict';
3   -import { getGatewayDevice, queryDeviceProfileBy } from '/@/api/device/deviceManager';
4   -import { JSONEditor } from '/@/components/CodeEditor';
5   -import { DeviceRecord, DeviceTypeEnum } from '/@/api/device/model/deviceModel';
6   -import { h } from 'vue';
7   -import { TaskTypeEnum } from '/@/views/task/center/config';
8   -import { createImgPreview } from '/@/components/Preview';
9   -import { uploadThumbnail } from '/@/api/configuration/center/configurationCenter';
10   -import LockControlGroup from '/@/components/Form/src/components/LockControlGroup.vue';
11   -import { OrgTreeSelect } from '/@/views/common/OrgTreeSelect';
12   -import { TCPProtocolTypeEnum, TransportTypeEnum } from '/@/enums/deviceEnum';
13   -import { HexInput, InputTypeEnum } from '../../profiles/components/ObjectModelForm/HexInput';
14   -import { DeviceProfileDetail } from '/@/api/device/model/deviceConfigModel';
15   -import { getDeviceProfileOtaPackages, getOtaPackageInfo } from '/@/api/ota';
16   -import { QueryDeviceProfileOtaPackagesType } from '/@/api/ota/model';
17   -import { OTAPackageType } from '/@/enums/otaEnum';
18   -import { createPickerSearch } from '/@/utils/pickerSearch';
19   -import { useI18n } from '/@/hooks/web/useI18n';
20   -
21   -useComponentRegister('JSONEditor', JSONEditor);
22   -useComponentRegister('LockControlGroup', LockControlGroup);
23   -useComponentRegister('OrgTreeSelect', OrgTreeSelect);
24   -useComponentRegister('HexInput', HexInput);
25   -
  1 +import {FormSchema as BFormSchema, useComponentRegister} from "../../../../components/Form";
  2 +import {useI18n} from "../../../../hooks/web/useI18n";
26 3 const { t } = useI18n();
27   -
28   -export enum TypeEnum {
29   - IS_GATEWAY = 'GATEWAY',
30   - SENSOR = 'SENSOR',
31   -}
32   -
33   -export const isGateWay = (type: string) => {
34   - return type === TypeEnum.IS_GATEWAY;
35   -};
36   -
37   -const updateProductHelpMessage = [
38   - t('deviceManagement.device.updateProductHelpMessage.text1'),
39   - t('deviceManagement.device.updateProductHelpMessage.text2'),
40   -];
41   -
42   -export const updateOrgHelpMessage = [
43   - t('deviceManagement.device.updateOrgHelpMessage.text1'),
44   - t('deviceManagement.device.updateOrgHelpMessage.text2'),
45   - t('deviceManagement.device.updateOrgHelpMessage.text3'),
  4 +import { CategoryTreeSelect } from '../../../common/CategoryTreeSelect';
  5 +import { OrgTreeSelect } from '../../../common/OrgTreeSelect';
  6 +useComponentRegister('OrgTreeSelect', OrgTreeSelect);
  7 +useComponentRegister('CategoryTreeSelect', CategoryTreeSelect);
  8 +const statusOptions = [
  9 + { label: t('equipment.ledger.NORMAL'), value: 'NORMAL' },
  10 + { label: t('equipment.ledger.FAULT'), value: 'FAULT' },
  11 + { label: t('equipment.ledger.SCRAP'), value: 'SCRAP' },
46 12 ];
47   -// 第一步的表单
48   -export const step1Schemas: FormSchema[] = [
49   - {
50   - field: 'icon',
51   - label: t('business.deviceImageText'),
52   - component: 'ApiUpload',
53   - changeEvent: 'update:fileList',
54   - valueField: 'fileList',
55   - componentProps: ({ formModel }) => {
56   - return {
57   - listType: 'picture-card',
58   - maxFileLimit: 1,
59   - accept: '.png,.jpg,.jpeg,.gif',
60   - api: async (file: File) => {
61   - try {
62   - const formData = new FormData();
63   - formData.set('file', file);
64   - const { fileStaticUri, fileName } = await uploadThumbnail(formData);
65   - return {
66   - uid: fileStaticUri,
67   - name: fileName,
68   - url: fileStaticUri,
69   - };
70   - } catch (error) {
71   - return {};
72   - }
73   - },
74   - onPreview: (fileList) => {
75   - createImgPreview({ imageList: [fileList.url!] });
76   - },
77   - onDelete(url: string) {
78   - formModel.deleteUrl = url!;
79   - },
80   - };
81   - },
82   - },
  13 +export const formSchema: BFormSchema[] = [
83 14 {
84   - field: 'deleteUrl',
85   - label: '',
86   - component: 'Input',
87   - show: false,
88   - },
89   - {
90   - field: 'alias',
91   - label: t('business.aliasText'),
  15 + field: 'code',
  16 + label: t('equipment.ledger.nameCode'),
92 17 component: 'Input',
  18 + colProps: { span: 24 },
  19 + required: true,
93 20 componentProps: {
94   - maxLength: 32,
  21 + maxLength: 20,
95 22 },
96 23 },
97 24 {
98 25 field: 'name',
99   - label: t('business.deviceNameText'),
  26 + label: t('equipment.ledger.deviceName'),
100 27 component: 'Input',
  28 + colProps: { span: 24 },
  29 + required: true,
101 30 componentProps: {
102   - maxLength: 32,
  31 + maxLength: 20,
103 32 },
104   - required: true,
105   - slot: 'snCode',
106 33 },
107 34 {
108   - field: 'transportType',
109   - label: '类型',
110   - component: 'Input',
111   - show: false,
112   - },
113   - {
114   - field: 'deviceProfileId',
115   - label: '',
116   - component: 'Input',
117   - show: false,
118   - },
119   - {
120   - field: 'isUpdate',
121   - label: '编辑模式',
122   - component: 'Switch',
123   - show: false,
124   - },
125   - {
126   - field: 'tcpDeviceProtocol',
127   - label: 'TCP设备协议类型',
128   - component: 'Input',
129   - show: false,
130   - },
131   -
132   - {
133   - field: 'profileId',
134   - label: t('business.affiliatedProductText'),
  35 + field: 'categoryId',
  36 + label: t('equipment.category.categoryText'),
  37 + colProps: { span: 24 },
  38 + component: 'CategoryTreeSelect',
135 39 required: true,
136   - component: 'LockControlGroup',
137   - helpMessage: updateProductHelpMessage,
138   - renderComponentContent: () => ({
139   - popconfirmTitle: () =>
140   - updateProductHelpMessage.map((text) => h('div', { style: { maxWidth: '200px' } }, text)),
141   - }),
142   - componentProps: ({ formActionType, formModel }) => {
143   - const { setFieldsValue } = formActionType;
144   - return {
145   - component: 'ApiSelect',
146   - defaultLockStatus: !!formModel?.isUpdate,
147   - componentProps: {
148   - api: async () => {
149   - const options = await queryDeviceProfileBy({
150   - deviceType: formModel?.isUpdate ? formModel?.deviceType : null,
151   - });
152   -
153   - return options;
154   - },
155   - labelField: 'name',
156   - valueField: 'tbProfileId',
157   - onChange(_value: string, option: DeviceProfileDetail) {
158   - const { deviceType, transportType, id } = option;
159   - setFieldsValue({
160   - deviceType: deviceType,
161   - transportType,
162   - deviceProfileId: id,
163   - gatewayId: null,
164   - code: null,
165   - addressCode: null,
166   - tcpDeviceProtocol: option?.profileData?.transportConfiguration?.protocol,
167   - });
168   - },
169   - onOptionsChange(options: (DeviceProfileDetail & Record<'value', string>)[]) {
170   - const { profileId } = formModel;
171   - if (profileId) {
172   - const selectRecord = options.find((item) => item.value === profileId);
173   - selectRecord &&
174   - setFieldsValue({
175   - transportType: selectRecord!.transportType,
176   - tcpDeviceProtocol: selectRecord?.profileData?.transportConfiguration?.protocol,
177   - });
178   - }
179   - },
180   - placeholder: t('deviceManagement.device.productPlaceholderText'),
181   - ...createPickerSearch(),
182   - },
183   - };
184   - },
185 40 },
186 41 {
187   - field: 'deviceType',
188   - label: t('business.deviceTypeText'),
  42 + field: 'status',
  43 + component: 'Select',
  44 + label: t('equipment.ledger.status'),
189 45 required: true,
190   - component: 'ApiSelect',
191   - dynamicDisabled: true,
192   - helpMessage: t('deviceManagement.device.deviceTypeHelpText'),
  46 + colProps: { span: 24 },
  47 + defaultValue: 'NORMAL',
193 48 componentProps: {
194   - api: findDictItemByCode,
195   - params: {
196   - dictCode: 'device_type',
197   - },
198   - labelField: 'itemText',
199   - valueField: 'itemValue',
200   - },
201   - },
202   - {
203   - field: 'addressType',
204   - label: '',
205   - component: 'Input',
206   - show: false,
207   - defaultValue: 'HEX',
208   - },
209   - {
210   - field: 'deviceState',
211   - label: '',
212   - component: 'Input',
213   - show: false,
214   - },
215   - {
216   - field: 'addressCode',
217   - label: t('deviceManagement.device.addressCodeText'),
218   - dynamicDisabled({ values }) {
219   - return (
220   - values.isUpdate &&
221   - values.deviceType === DeviceTypeEnum.SENSOR &&
222   - values.deviceState === 'ONLINE' &&
223   - values.transportType === TransportTypeEnum.TCP
224   - );
225   - },
226   - dynamicRules({ values }) {
227   - return [
228   - {
229   - required:
230   - values?.transportType === TransportTypeEnum.TCP &&
231   - values?.tcpDeviceProtocol === TCPProtocolTypeEnum.MODBUS_RTU,
232   - message: t('deviceManagement.device.addressCodeHelpText'),
233   - pattern: values?.addressType === 'HEX' ? /^[0-9A-Fa-f]{2}$/ : /^[0-9A-Fa-f]{1,2}$/,
234   - },
235   - ];
236   - },
237   - helpMessage({ values }) {
238   - return [
239   - t('deviceManagement.device.addressCodeHelpText'),
240   - values.transportType === TransportTypeEnum.TCP &&
241   - values.deviceType === DeviceTypeEnum.SENSOR
242   - ? t('deviceManagement.device.tcpAddressCodeHelpText')
243   - : '',
244   - ];
245   - },
246   - component: 'HexInput',
247   - changeEvent: 'update:value',
248   - valueField: 'value',
249   - componentProps: ({ formModel }) => {
250   - return {
251   - type: InputTypeEnum.HEX,
252   - maxValue: parseInt('FF', 16),
253   - onHexChange: (e) => {
254   - formModel.addressType = e;
255   - },
256   - };
257   - },
258   - ifShow: ({ values }) => {
259   - return (
260   - values?.transportType === TransportTypeEnum.TCP &&
261   - values?.tcpDeviceProtocol === TCPProtocolTypeEnum.MODBUS_RTU
262   - );
263   - },
264   - },
265   - {
266   - field: 'code',
267   - label: t('deviceManagement.device.codeText'),
268   - dynamicRules({ values }) {
269   - return [
270   - {
271   - required:
272   - values?.transportType === TransportTypeEnum.TCP &&
273   - values.deviceType === DeviceTypeEnum.SENSOR,
274   - },
275   - ];
276   - },
277   - dynamicDisabled({ values }) {
278   - return (
279   - values.isUpdate &&
280   - values.deviceType === DeviceTypeEnum.SENSOR &&
281   - values.deviceState === 'ONLINE' &&
282   - values.transportType === TransportTypeEnum.TCP
283   - );
284   - },
285   - helpMessage({ values }) {
286   - return (
287   - values.transportType === TransportTypeEnum.TCP &&
288   - values.deviceType === DeviceTypeEnum.SENSOR
289   - ? ['tcp网关子设备在线时,不能修改设备标识或地址码']
290   - : false
291   - ) as any;
292   - },
293   - component: 'Input',
294   - componentProps: () => {
295   - return {
296   - maxLength: 255,
297   - placeholder: t('deviceManagement.device.codePlaceholderText'),
298   - };
299   - },
300   - ifShow: ({ values }) => {
301   - return (
302   - values?.transportType === TransportTypeEnum.TCP &&
303   - values?.tcpDeviceProtocol === TaskTypeEnum.CUSTOM
304   - );
  49 + options: statusOptions,
305 50 },
306 51 },
307   -
308 52 {
309   - field: 'brand',
310   - component: 'ApiRadioGroup',
311   - label: t('deviceManagement.device.brandText'),
  53 + field: 'org',
  54 + component: 'OrgTreeSelect',
  55 + label: '负责人组织',
312 56 required: true,
313   - defaultValue: 'DIY_',
  57 + colProps: { span: 24 },
314 58 componentProps: {
315   - api: findDictItemByCode,
316   - params: {
317   - dictCode: 'device_brand_gateway',
  59 + // 添加 change 事件
  60 + onChange: (value: string) => {
  61 + // 这里需要触发加载人员数据的逻辑
  62 + console.log(value,'value')
318 63 },
319   - labelField: 'itemText',
320   - valueField: 'itemValue',
321   - },
322   - ifShow: ({ values }) => isGateWay(values.deviceType),
323   - },
324   - {
325   - field: 'gatewayId',
326   - label: t('enum.deviceType.GATEWAY'),
327   - required: true,
328   - component: 'ApiSelect',
329   - ifShow: ({ values }) => values.deviceType === 'SENSOR',
330   - componentProps: ({ formModel, formActionType }) => {
331   - const { transportType, deviceType, gatewayId } = formModel;
332   - const { setFieldsValue } = formActionType;
333   - if (!transportType) return {};
334   - return {
335   - api: async (params: Recordable) => {
336   - try {
337   - const result = await getGatewayDevice(params as any);
338   - return result.map((item) => ({ ...item, alias: item.alias || item.name }));
339   - } catch (e) {
340   - return [];
341   - }
342   - },
343   - params: {
344   - transportType,
345   - gatewayId: deviceType === DeviceTypeEnum.SENSOR && gatewayId ? gatewayId : null,
346   - },
347   - valueField: 'tbDeviceId',
348   - labelField: 'alias',
349   - onChange: async (_value: string, option: DeviceRecord) => {
350   - setFieldsValue({ sensorOrganizationId: option?.organizationId, organizationId: null });
351   - },
352   - onOptionsChange(options: (DeviceRecord & Record<'value', string>)[]) {
353   - if (formModel?.deviceType === DeviceTypeEnum.SENSOR && formModel?.gatewayId) {
354   - const result = options.find((item) => item.value === formModel?.gatewayId);
355   - result && setFieldsValue({ sensorOrganizationId: result?.organizationId });
356   - }
357   - },
358   - ...createPickerSearch(),
359   - };
360   - },
361   - },
362   - {
363   - field: 'sensorOrganizationId',
364   - label: '依据网关设备请求的组织数组',
365   - component: 'Input',
366   - ifShow: false,
367   - },
368   - {
369   - field: 'customerId',
370   - label: '用来判断编辑时禁用组织修改',
371   - component: 'Input',
372   - ifShow: false,
373   - },
374   - {
375   - field: 'organizationId',
376   - label: t('business.affiliatedOrganizationText'),
377   - component: 'LockControlGroup',
378   - required: true,
379   - helpMessage: updateOrgHelpMessage,
380   - renderComponentContent: () => ({
381   - popconfirmTitle: () =>
382   - updateOrgHelpMessage.map((text) => h('div', { style: { maxWidth: '240px' } }, text)),
383   - }),
384   - componentProps: ({ formModel, formActionType }) => {
385   - return {
386   - component: 'OrgTreeSelect',
387   - defaultLockStatus: !!formModel?.isUpdate,
388   - disabled: !!formModel?.customerId,
389   - componentProps: {
390   - apiTreeSelectProps: {
391   - params: {
392   - organizationId: formModel?.sensorOrganizationId,
393   - },
394   - },
395   - onOptionsChange: (options: Recordable[]) => {
396   - if (!formModel?.organizationId && formModel?.deviceType === DeviceTypeEnum.SENSOR) {
397   - const firstItem = options?.[0];
398   -
399   - if (firstItem && firstItem?.id) {
400   - const { setFieldsValue, clearValidate } = formActionType;
401   - setFieldsValue({ organizationId: firstItem.id });
402   - clearValidate('organizationId');
403   - }
404   - }
405   - },
406   - placeholder: t('deviceManagement.device.organizationPlaceholderText'),
407   - },
408   - };
409 64 },
410 65 },
411 66 {
412 67 field: 'directorId',
413   - label: t('deviceManagement.device.directorName'),
414   - component: 'Input',
415   - componentProps: {
416   - maxLength: 255,
417   - },
418   - },
419   - {
420   - field: 'label',
421   - label: t('deviceManagement.device.deviceLabelText'),
422   - component: 'Input',
423   - componentProps: {
424   - maxLength: 255,
425   - },
426   - },
427   - {
428   - field: 'deviceAddress',
429   - label: t('business.deviceLocationText'),
430   - component: 'Input',
431   - slot: 'deviceAddress',
432   - },
433   -
434   - {
435   - field: 'firmwareId',
436   - label: t('deviceManagement.product.assignHardwareText'),
437   - component: 'ApiSearchSelect',
438   - ifShow: ({ model }) => model?.isUpdate,
439   - componentProps: ({ formModel }) => {
440   - return {
441   - api: async (params: QueryDeviceProfileOtaPackagesType) => {
442   - if (!params.deviceProfileId) return [];
443   - const result = await getDeviceProfileOtaPackages(params);
444   - return result.data.map((item) => ({
445   - label: `${item.title}(${item.version})`,
446   - value: item.id.id,
447   - }));
448   - },
449   - params: (textSearch: string) => {
450   - return {
451   - textSearch,
452   - page: 0,
453   - type: OTAPackageType.FIRMWARE,
454   - pageSize: 10,
455   - deviceProfileId: formModel?.profileId,
456   - };
457   - },
458   - queryApi: async (id: string) => {
459   - const result = await getOtaPackageInfo(id);
460   - return { label: `${result.title}(${result.version})`, value: result.id.id };
461   - },
462   - };
463   - },
464   - },
465   - {
466   - field: 'softwareId',
467   - label: t('deviceManagement.product.assignSoftwareText'),
468   - component: 'ApiSearchSelect',
469   - ifShow: ({ model }) => model?.isUpdate,
470   - componentProps: ({ formModel }) => {
471   - return {
472   - api: async (params: QueryDeviceProfileOtaPackagesType) => {
473   - if (!params.deviceProfileId) return [];
474   - const result = await getDeviceProfileOtaPackages(params);
475   - return result.data.map((item) => ({
476   - label: `${item.title}(${item.version})`,
477   - value: item.id.id,
478   - }));
479   - },
480   - params: (textSearch: string) => {
481   - return {
482   - textSearch,
483   - page: 0,
484   - type: OTAPackageType.SOFTWARE,
485   - pageSize: 10,
486   - deviceProfileId: formModel?.profileId,
487   - };
488   - },
489   - queryApi: async (id: string) => {
490   - const result = await getOtaPackageInfo(id);
491   - return { label: `${result.title}(${result.version})`, value: result.id.id };
492   - },
493   - };
494   - },
495   - },
496   - {
497   - field: 'description',
498   - label: t('common.remarkText'),
499   - component: 'InputTextArea',
500   - componentProps: {
501   - maxLength: 500,
502   - },
503   - },
504   - {
505   - field: 'id',
506   - label: 'id',
507   - component: 'Input',
508   - show: false,
509   - componentProps: {
510   - maxLength: 36,
511   - placeholder: '请输入id',
512   - },
513   - },
514   - {
515   - field: 'tenantId',
516   - label: '租户Code',
517   - component: 'Input',
518   - show: false,
519   - componentProps: {
520   - maxLength: 36,
521   - placeholder: '请输入租户Code',
522   - },
523   - },
524   - {
525   - field: 'tbDeviceId',
526   - label: 'tbDeviceId',
527   - component: 'Input',
528   - show: false,
  68 + component: 'Select',
  69 + label: '负责人',
  70 + required: true,
  71 + colProps: { span: 24 },
529 72 componentProps: {
530   - maxLength: 36,
531   - placeholder: '请输入tbDeviceId',
  73 + // 动态加载的选项
  74 + options: [], // 初始为空,后续动态加载
532 75 },
533 76 },
534   -];
535   -
536   -export enum credentialTypeEnum {
537   - ACCESS_TOKEN = 'ACCESS_TOKEN',
538   - X_509 = 'X509_CERTIFICATE',
539   - MQTT_BASIC = 'MQTT_BASIC',
540   -}
541   -// 第二步的表单
542   -export const step2Schemas: FormSchema[] = [
543   - {
544   - label: '',
545   - component: 'Checkbox',
546   - field: 'addAgree',
547   - slot: 'addAgree',
548   - },
549 77 {
550   - label: t('deviceManagement.device.certificateTypeText'),
  78 + field: 'isOnline',
551 79 component: 'Select',
552   - field: 'credentialType',
  80 + label: '是否联网',
553 81 required: true,
554   - componentProps({ formActionType }) {
555   - const { updateSchema, setFieldsValue } = formActionType;
556   - return {
557   - options: [
558   - {
559   - value: credentialTypeEnum.ACCESS_TOKEN,
560   - label: 'Access Token',
561   - },
562   - {
563   - value: credentialTypeEnum.X_509,
564   - label: 'X.509',
565   - },
566   - {
567   - value: credentialTypeEnum.MQTT_BASIC,
568   - label: 'MQTT Basic',
569   - },
570   - ],
571   - onChange(value) {
572   - setFieldsValue({
573   - publicKey: '',
574   - credentialsId: '',
575   - clientId: '',
576   - username: '',
577   - password: '',
578   - });
579   - if (value === credentialTypeEnum.ACCESS_TOKEN) {
580   - updateSchema([
581   - {
582   - field: 'credentialsId',
583   - ifShow: true,
584   - },
585   - {
586   - field: 'clientId',
587   - ifShow: false,
588   - },
589   - {
590   - field: 'username',
591   - ifShow: false,
592   - },
593   - {
594   - field: 'password',
595   - ifShow: false,
596   - },
597   - {
598   - field: 'publicKey',
599   - ifShow: false,
600   - },
601   - ]);
602   - } else if (value === credentialTypeEnum.X_509) {
603   - updateSchema([
604   - {
605   - field: 'publicKey',
606   - ifShow: true,
607   - },
608   - {
609   - field: 'credentialsId',
610   - ifShow: false,
611   - },
612   - {
613   - field: 'clientId',
614   - ifShow: false,
615   - },
616   - {
617   - field: 'username',
618   - ifShow: false,
619   - },
620   - {
621   - field: 'password',
622   - ifShow: false,
623   - },
624   - ]);
625   - } else if (value === credentialTypeEnum.MQTT_BASIC) {
626   - updateSchema([
627   - {
628   - field: 'clientId',
629   - ifShow: true,
630   - },
631   - {
632   - field: 'username',
633   - ifShow: true,
634   - },
635   - {
636   - field: 'password',
637   - ifShow: true,
638   - },
639   - {
640   - field: 'publicKey',
641   - ifShow: false,
642   - },
643   - {
644   - field: 'credentialsId',
645   - ifShow: false,
646   - },
647   - ]);
648   - } else {
649   - updateSchema([
650   - {
651   - field: 'clientId',
652   - ifShow: false,
653   - },
654   - {
655   - field: 'username',
656   - ifShow: false,
657   - },
658   - {
659   - field: 'password',
660   - ifShow: false,
661   - },
662   - {
663   - field: 'publicKey',
664   - ifShow: false,
665   - },
666   - {
667   - field: 'credentialsId',
668   - ifShow: false,
669   - },
670   - ]);
671   - }
  82 + colProps: { span: 24 },
  83 + componentProps: {
  84 + options: [
  85 + {
  86 + label: '是',
  87 + value: true,
672 88 },
673   - };
  89 + {
  90 + label: '否',
  91 + value: false,
  92 + }
  93 + ],
674 94 },
675   - ifShow: ({ values }) => values.addAgree,
676 95 },
677 96 {
678   - label: t('deviceManagement.device.accessTokenText'),
  97 + field: 'brand',
  98 + label: t('equipment.ledger.brandText'),
679 99 component: 'Input',
680   - field: 'credentialsId',
681   - required: true,
682   - ifShow: false,
683   - slot: 'credentialsId',
  100 + colProps: { span: 24 },
684 101 componentProps: {
685   - maxLength: 36,
  102 + maxLength: 20,
686 103 },
687 104 },
688 105 {
689   - label: t('deviceManagement.device.rsaPublicKeyText'),
690   - component: 'InputTextArea',
691   - field: 'publicKey',
692   - required: true,
693   - ifShow: false,
  106 + field: 'modelNum',
  107 + label: t('equipment.ledger.modelNumText'),
  108 + component: 'Input',
  109 + colProps: { span: 24 },
694 110 componentProps: {
695   - rows: 8,
  111 + maxLength: 20,
696 112 },
697 113 },
698 114 {
699   - label: t('deviceManagement.device.clientIdText'),
  115 + field: 'specifications',
  116 + label: t('equipment.ledger.specificationsText'),
700 117 component: 'Input',
701   - field: 'clientId',
702   - ifShow: false,
703   - slot: 'clientId',
  118 + colProps: { span: 24 },
704 119 componentProps: {
705   - maxLength: 36,
  120 + maxLength: 20,
706 121 },
707 122 },
708 123 {
709   - label: t('deviceManagement.device.usernameText'),
  124 + field: 'specifications',
  125 + label: t('equipment.ledger.manufacturerText'),
710 126 component: 'Input',
711   - field: 'username',
712   - required: true,
713   - ifShow: false,
  127 + colProps: { span: 24 },
714 128 componentProps: {
715   - maxLength: 255,
  129 + maxLength: 20,
716 130 },
717 131 },
718 132 {
719   - label: t('deviceManagement.device.passwordText'),
720   - component: 'InputPassword',
721   - field: 'password',
  133 + field: 'buyDate',
  134 + label: t('equipment.ledger.buyDate'),
  135 + component: 'DatePicker',
  136 + colProps: { span: 24 },
722 137 componentProps: {
723   - maxLength: 36,
724   - },
725   - ifShow: false,
726   - },
727   -];
728   -
729   -// 管理凭证的表单配置项
730   -export const TokenSchemas: FormSchema[] = [
731   - {
732   - label: t('deviceManagement.device.certificateTypeText'),
733   - component: 'Select',
734   - field: 'credentialType',
735   - required: true,
736   - componentProps({ formActionType }) {
737   - const { updateSchema, setFieldsValue } = formActionType;
738   - return {
739   - options: [
740   - {
741   - value: credentialTypeEnum.ACCESS_TOKEN,
742   - label: 'Access Token',
743   - },
744   - {
745   - value: credentialTypeEnum.X_509,
746   - label: 'X.509',
747   - },
748   - {
749   - value: credentialTypeEnum.MQTT_BASIC,
750   - label: 'MQTT Basic',
751   - },
752   - ],
753   - onChange(value) {
754   - setFieldsValue({
755   - publicKey: '',
756   - credentialsId: '',
757   - clientId: '',
758   - username: '',
759   - password: '',
760   - });
761   - if (value === credentialTypeEnum.ACCESS_TOKEN) {
762   - updateSchema([
763   - {
764   - field: 'credentialsId',
765   - ifShow: true,
766   - },
767   - {
768   - field: 'clientId',
769   - ifShow: false,
770   - },
771   - {
772   - field: 'username',
773   - ifShow: false,
774   - },
775   - {
776   - field: 'password',
777   - ifShow: false,
778   - },
779   - {
780   - field: 'publicKey',
781   - ifShow: false,
782   - },
783   - ]);
784   - } else if (value === credentialTypeEnum.X_509) {
785   - updateSchema([
786   - {
787   - field: 'publicKey',
788   - ifShow: true,
789   - },
790   - {
791   - field: 'credentialsId',
792   - ifShow: false,
793   - },
794   - {
795   - field: 'clientId',
796   - ifShow: false,
797   - },
798   - {
799   - field: 'username',
800   - ifShow: false,
801   - },
802   - {
803   - field: 'password',
804   - ifShow: false,
805   - },
806   - ]);
807   - } else if (value === credentialTypeEnum.MQTT_BASIC) {
808   - updateSchema([
809   - {
810   - field: 'clientId',
811   - ifShow: true,
812   - },
813   - {
814   - field: 'username',
815   - ifShow: true,
816   - },
817   - {
818   - field: 'password',
819   - ifShow: true,
820   - },
821   - {
822   - field: 'publicKey',
823   - ifShow: false,
824   - },
825   - {
826   - field: 'credentialsId',
827   - ifShow: false,
828   - },
829   - ]);
830   - } else {
831   - updateSchema([
832   - {
833   - field: 'clientId',
834   - ifShow: false,
835   - },
836   - {
837   - field: 'username',
838   - ifShow: false,
839   - },
840   - {
841   - field: 'password',
842   - ifShow: false,
843   - },
844   - {
845   - field: 'publicKey',
846   - ifShow: false,
847   - },
848   - {
849   - field: 'credentialsId',
850   - ifShow: false,
851   - },
852   - ]);
853   - }
854   - },
855   - };
  138 + format: 'YYYY-MM-DD hh:mm:ss', // 设置日期格式
  139 + showTime: true, // 显示时间选择器
856 140 },
857 141 },
858   - {
859   - label: t('deviceManagement.device.accessTokenText'),
860   - component: 'Input',
861   - field: 'credentialsId',
862   - required: true,
863   - ifShow: false,
864   - slot: 'credentialsId',
  142 +{
  143 + field: 'price',
  144 + label: t('equipment.ledger.priceText'),
  145 + component: 'InputNumber',
  146 + colProps: { span: 24 },
865 147 componentProps: {
866   - maxLength: 36,
867 148 },
868 149 },
869 150 {
870   - label: t('deviceManagement.device.rsaPublicKeyText'),
871   - component: 'InputTextArea',
872   - field: 'publicKey',
873   - required: true,
874   - ifShow: false,
  151 + field: 'productDate',
  152 + label: t('equipment.ledger.productDate'),
  153 + component: 'DatePicker',
  154 + colProps: { span: 24 },
875 155 componentProps: {
876   - rows: 8,
  156 + format: 'YYYY-MM-DD hh:mm:ss', // 设置日期格式
  157 + showTime: true, // 显示时间选择器
877 158 },
878 159 },
879 160 {
880   - label: t('deviceManagement.device.clientIdText'),
881   - component: 'Input',
882   - field: 'clientId',
883   - ifShow: false,
884   - slot: 'clientId',
  161 + field: 'receiveDate',
  162 + label: t('equipment.ledger.receiveDate'),
  163 + component: 'DatePicker',
  164 + colProps: { span: 24 },
885 165 componentProps: {
886   - maxLength: 36,
  166 + format: 'YYYY-MM-DD hh:mm:ss', // 设置日期格式
  167 + showTime: true, // 显示时间选择器
887 168 },
888 169 },
889 170 {
890   - label: t('deviceManagement.device.usernameText'),
891   - component: 'Input',
892   - field: 'username',
893   - required: true,
894   - ifShow: false,
  171 + field: 'registeDate',
  172 + label: t('equipment.ledger.registeDate'),
  173 + component: 'DatePicker',
  174 + colProps: { span: 24 },
895 175 componentProps: {
896   - maxLength: 255,
  176 + format: 'YYYY-MM-DD hh:mm:ss', // 设置日期格式
  177 + showTime: true, // 显示时间选择器
897 178 },
898 179 },
899 180 {
900   - label: t('deviceManagement.device.passwordText'),
901   - component: 'InputPassword',
902   - field: 'password',
903   - ifShow: false,
  181 + field: 'supplierId',
  182 + component: 'OrgTreeSelect',
  183 + label: '供应商',
  184 + colProps: { span: 24 },
904 185 componentProps: {
905   - maxLength: 36,
906   - },
907   - },
908   - {
909   - label: 'id',
910   - component: 'Input',
911   - field: 'id',
912   - show: false,
913   - componentProps: {
914   - maxLength: 36,
915   - placeholder: '请输入id',
  186 + // 添加 change 事件
  187 + onChange: (value: string) => {
  188 + // 这里需要触发加载人员数据的逻辑
  189 + console.log(value,'value')
  190 + },
916 191 },
917 192 },
918 193 {
919   - label: 'tbDeviceId',
920   - component: 'Input',
921   - field: 'tbDeviceId',
922   - show: false,
  194 + field: 'description',
  195 + label: t('equipment.ledger.description'),
  196 + component: 'InputTextArea',
  197 + colProps: { span: 24 },
923 198 componentProps: {
924   - maxLength: 36,
925   - placeholder: '请输入tbDeviceId',
926   - },
927   - dynamicRules: () => {
928   - return [
929   - {
930   - required: false,
931   - validator: (_, value) => {
932   - if (String(value).length > 36) {
933   - return Promise.reject('字数不超过36个字');
934   - }
935   - return Promise.resolve();
936   - },
937   - },
938   - ];
  199 + maxLength: 200,
939 200 },
940 201 },
  202 +
941 203 ];
... ...
  1 +export enum SchemaFiled {
  2 + WAY = 'queryMode',
  3 + TIME_PERIOD = 'timePeriod',
  4 + KEYS = 'keys',
  5 + DATE_RANGE = 'dataRange',
  6 + START_TS = 'startTs',
  7 + END_TS = 'endTs',
  8 + INTERVAL = 'interval',
  9 + LIMIT = 'limit',
  10 + AGG = 'agg',
  11 + ORDER_BY = 'orderBy',
  12 + DATA_TYPE = 'dataType',
  13 +}
... ...
1   -import { formatToDate } from '/@/utils/dateUtil';
2 1 import { BasicColumn } from '/@/components/Table';
3 2 import { FormSchema } from '/@/components/Table';
4   -import { DeviceRecord } from '/@/api/device/model/deviceModel';
5   -// import { deviceProfile } from '/@/api/device/deviceManager';
6 3 import { h } from 'vue';
7   -import { Tag, Tooltip } from 'ant-design-vue';
  4 +import { Tooltip } from 'ant-design-vue';
8 5 import { handeleCopy } from '../../../device/profiles/step/topic';
9 6 import { useI18n } from '/@/hooks/web/useI18n';
10   -import { DeviceStatusEnum, DeviceTypeEnum } from '/@/enums/deviceEnum';
  7 +import { SbStatusEnum } from '/@/enums/deviceEnum';
11 8
12 9 const { t } = useI18n();
13 10 import edgefornt from '/@/assets/icons/edgefornt.svg';
... ... @@ -73,16 +70,15 @@ export enum DeviceListAuthEnum {
73 70 export const columns: BasicColumn[] = [
74 71 {
75 72 title: t('business.deviceStatusText'),
76   - dataIndex: 'deviceState',
  73 + dataIndex: 'status',
77 74 width: 110,
78 75 className: 'device-status',
79   - slots: { customRender: 'deviceState' },
  76 + slots: { customRender: 'status' },
80 77 },
81 78 {
82   - title: t('business.deviceImageText'),
83   - dataIndex: 'deviceInfo.avatar',
84   - width: 70,
85   - slots: { customRender: 'img' },
  79 + title: t('business.codeText'),
  80 + dataIndex: 'code',
  81 + width: 100,
86 82 },
87 83 {
88 84 dataIndex: 'name',
... ... @@ -142,53 +138,18 @@ export const columns: BasicColumn[] = [
142 138 },
143 139 {
144 140 title: t('business.deviceTypeText'),
145   - dataIndex: 'deviceType',
146   - width: 130,
147   - customRender({ text }) {
148   - return h(Tag, { color: 'success' }, () => t(`enum.deviceType.${text}`));
149   - },
150   - },
151   - {
152   - title: t('business.affiliatedProductText'),
153   - dataIndex: 'deviceProfile.name',
154   - width: 180,
155   - slots: { customRender: 'deviceProfile' },
156   - ellipsis: true,
157   - },
158   - {
159   - title: t('business.affiliatedOrganizationText'),
160   - dataIndex: 'organizationDTO.name',
161   - width: 100,
162   - },
163   - // {
164   - // title: '客户',
165   - // dataIndex: 'customerName',
166   - // width: 100,
167   - // },
168   - {
169   - title: t('business.publicText'),
170   - dataIndex: 'public',
171   - width: 100,
172   - customRender({ record }: { record: DeviceRecord }) {
173   - const flag = record?.customerAdditionalInfo?.isPublic;
174   - return h(Tag, { color: flag ? 'blue' : 'orange' }, () =>
175   - flag ? t('business.publicText') : t('business.privateText')
176   - );
177   - },
  141 + dataIndex: 'categoryName',
  142 + width: 120,
178 143 },
179 144 {
180   - title: t('deviceManagement.device.lastOnlineTimeText'),
181   - dataIndex: 'lastOnlineTime',
182   - format: (text) => text && formatToDate(text, 'YYYY-MM-DD HH:mm:ss'),
183   - width: 160,
  145 + title: t('business.directorName'),
  146 + dataIndex: 'directorName',
  147 + width: 120,
184 148 },
185 149 {
186   - title: t('deviceManagement.device.lastOfflineTimeText'),
187   - dataIndex: 'lastOfflineTime',
188   - format: (text) => {
189   - return text ? formatToDate(text, 'YYYY-MM-DD HH:mm:ss') : '';
190   - },
191   - width: 160,
  150 + title: t('business.brandText'),
  151 + dataIndex: 'brand',
  152 + width: 120,
192 153 },
193 154 ];
194 155
... ... @@ -204,24 +165,12 @@ export const searchFormSchema: FormSchema[] = [
204 165 },
205 166 },
206 167 {
207   - field: 'deviceType',
208   - label: t('equipment.ledger.deviceType'),
209   - component: 'Select',
210   - componentProps: {
211   - options: Object.values(DeviceTypeEnum).map((value) => ({
212   - label: t(`enum.deviceType.${value}`),
213   - value,
214   - })),
215   - },
216   - colProps: { span: 6 },
217   - },
218   - {
219   - field: 'deviceState',
  168 + field: 'status',
220 169 label: t('business.deviceStatusText'),
221 170 component: 'Select',
222 171 componentProps: {
223   - options: Object.values(DeviceStatusEnum).map((value) => ({
224   - label: t(`enum.deviceStatus.${value}`),
  172 + options: Object.values(SbStatusEnum).map((value) => ({
  173 + label: t(`enum.sbStatus.${value}`),
225 174 value,
226 175 })),
227 176 },
... ...
1 1 <template>
2 2 <div>
3 3 <PageWrapper dense contentFullHeight contentClass="flex">
4   - <OrganizationIdTree @select="handleSelect" ref="organizationIdTreeRef" />
  4 + <OrganizationIdTree @select="handleSelect" ref="organizationIdTreeRef" listType="equipment"/>
5 5 <BasicTable style="flex: auto" @register="registerTable" class="w-5/6 xl:w-4/5 device-table">
6 6 <template #toolbar>
7 7 <Authority :value="DeviceListAuthEnum.CREATE">
8   - <a-button type="primary" @click="handleCreate" v-if="authBtn(role)">
  8 + <a-button type="primary" @click="handleBussinessDrawer('add', null)" v-if="authBtn(role)">
9 9 {{ t('equipment.ledger.createLedgerText') }}
10 10 </a-button>
11 11 </Authority>
12   -
13   - <Authority :value="DeviceListAuthEnum.IMPORT">
14   - <Button type="primary" >
15   - {{ t('equipment.ledger.importLedgerText') }}
16   - </Button>
17   - </Authority>
18   -
19   - <Authority
20   - :value="[
21   - DeviceListAuthEnum.DELETE,
22   - DeviceListAuthEnum.ASSIGN,
23   - DeviceListAuthEnum.UPDATE_PRODUCT,
24   - ]"
25   - >
26   - <AuthDropDown
27   - v-if="authBtn(role)"
28   - :disabled="isPublicAndPrivateFlag || !isExistOption"
29   - :dropMenuList="[
30   - {
31   - text: t('common.delText'),
32   - auth: DeviceListAuthEnum.DELETE,
33   - icon: 'ant-design:delete-outlined',
34   - event: '',
35   - disabled: !batchPrivateFlag,
36   - popconfirm: {
37   - title: t('common.deleteConfirmText'),
38   - onConfirm: () => handleDelete(),
39   - },
40   - },
41   - {
42   - text: t('equipment.ledger.editProductText'),
43   - auth: DeviceListAuthEnum.UPDATE_PRODUCT,
44   - icon: 'clarity:note-edit-line',
45   - event: '',
46   - disabled: !batchPrivateFlag || batchUpdateProductFlag,
47   - onClick: handelOpenBatchUpdateProductModal,
48   - },
49   - {
50   - text: t('business.publicText'),
51   - icon: 'ant-design:wallet-outlined',
52   - event: '',
53   - disabled: !batchPrivateFlag,
54   - onClick: handleBatchPublic.bind(null),
55   - },
56   - {
57   - text: t('business.privateText'),
58   - icon: 'ant-design:wallet-outlined',
59   - event: '',
60   - disabled: batchPrivateFlag,
61   - onClick: handleBatchPrivate.bind(null),
62   - },
63   - {
64   - text: t('equipment.ledger.updateOrganization'),
65   - icon: 'ant-design:wallet-outlined',
66   - event: '',
67   - disabled: !batchPrivateFlag || batchSensorFlag || diffBatchSensorFlag,
68   - onClick: handleBatchOrg.bind(null),
69   - },
70   - ]"
71   - >
72   - <Button type="primary" :disabled="isPublicAndPrivateFlag || !isExistOption">
73   - {{ t('equipment.ledger.batchActionText') }}
74   - </Button>
75   - </AuthDropDown>
76   - </Authority>
77   - </template>
78   - <template #img="{ record }">
79   - <TableImg
80   - :size="30"
81   - :showBadge="false"
82   - :simpleShow="true"
83   - :imgList="
84   - typeof record?.deviceInfo?.avatar !== 'undefined' &&
85   - record?.deviceInfo?.avatar !== '' &&
86   - record?.deviceInfo?.avatar != null
87   - ? [record.deviceInfo.avatar]
88   - : null
89   - "
90   - />
91 12 </template>
92   - <template #deviceProfile="{ record }">
93   - <Button
94   - @click="!isCustomer ? goDeviceProfile(record.deviceProfile.name) : null"
95   - type="link"
96   - >
97   - {{ record.deviceProfile.name }}
98   - </Button>
99   - </template>
100   - <template #deviceState="{ record }">
101   - <div v-if="record.isCollect">
102   - <div class="absolute top-0 left-0 device-collect"> </div>
103   - <Icon
104   - icon="ph:star-fill"
105   - class="fill-light-50 absolute top-0.5 left-0.5"
106   - color="#fff"
107   - :size="12"
108   - />
109   - </div>
110   -
  13 + <template #status="{ record }">
111 14 <Tag
112 15 :color="
113   - record.deviceState == DeviceState.INACTIVE
  16 + record.status == SbStatusEnum.SCRAP
114 17 ? 'warning'
115   - : record.deviceState == DeviceState.ONLINE
116   - ? 'success'
117   - : record.deviceState == DeviceState.ACTIVE
  18 + : record.status == SbStatusEnum.NORMAL
118 19 ? 'success'
  20 + : record.status == SbStatusEnum.FAULT
  21 + ? 'error'
119 22 : 'error'
120 23 "
121 24 class="ml-2"
122 25 >
123   - {{ t(`enum.deviceStatus.${record.deviceState}`) }}
  26 + {{ t(`enum.sbStatus.${record.status}`) }}
124 27 </Tag>
125 28 </template>
126 29 <template #action="{ record }">
127 30 <TableAction
128 31 :actions="[
129   - {
130   - label: AlarmDetailActionButton({ hasAlarm: !!record.alarmStatus }),
131   - icon: 'ant-design:eye-outlined',
132   - auth: DeviceListAuthEnum.DETAIL,
133   - // onClick: handleDetail.bind(null, record),
134   - },
135   - {
136   - label: t('common.editText'),
137   - auth: DeviceListAuthEnum.UPDATE,
138   - icon: 'clarity:note-edit-line',
139   - ifShow: authBtn(role),
140   - // onClick: handleEdit.bind(null, record),
141   - },
142   - ]"
143   - :dropDownActions="[
144   - // record.customerId
145   - // ? {
146   - // label: t('deviceManagement.device.cancelAssignText'),
147   - // icon: 'mdi:account-arrow-left',
148   - // ifShow: authBtn(role) && !record?.customerAdditionalInfo?.isPublic,
149   - // auth: DeviceListAuthEnum.ASSIGN,
150   - // popConfirm: {
151   - // title: t('deviceManagement.device.cancelAssignConfirmText'),
152   - // confirm: handleCancelDispatchCustomer.bind(null, record),
153   - // },
154   - // }
155   - // : {
156   - // label: t('deviceManagement.device.assignCustomerText'),
157   - // icon: 'mdi:account-arrow-right',
158   - // ifShow: authBtn(role),
159   - // auth: DeviceListAuthEnum.ASSIGN,
160   - // onClick: handleDispatchCustomer.bind(null, record),
161   - // },
162   - {
163   - label: record?.customerAdditionalInfo?.isPublic
164   - ? t('business.privateText')
165   - : t('business.publicText'),
166   - auth: DeviceListAuthEnum.PUBLIC,
167   - icon: record?.customerAdditionalInfo?.isPublic
168   - ? 'ant-design:lock-outlined'
169   - : 'ant-design:unlock-outlined',
170   - // onClick: handlePublicDevice.bind(null, record),
171   - },
172   - {
173   - label: t('deviceManagement.device.onlineRecordText'),
174   - auth: DeviceListAuthEnum.ONLINE,
175   - icon: 'ant-design:rise-outlined',
176   - // onClick: handleUpAndDownRecord.bind(null, record),
  32 + {
  33 + label: t('common.viewText'),
  34 + icon: 'ant-design:eye-outlined',
  35 + onClick: handleBussinessDrawer.bind(null, 'view', record),
  36 + },
  37 + {
  38 + label: t('common.editText'),
  39 + icon: 'clarity:note-edit-line',
  40 + onClick: handleBussinessDrawer.bind(null, 'edit', record),
  41 + },
  42 + {
  43 + label: t('common.delText'),
  44 + icon: 'ant-design:delete-outlined',
  45 + color: 'error',
  46 + popConfirm: {
  47 + title: t('common.isDelete'),
  48 + confirm: handleDelete.bind(null, record),
177 49 },
178   - !record.isCollect
179   - ? {
180   - label: t('deviceManagement.device.collectText'),
181   - icon: 'ant-design:heart-outlined',
182   - // onClick: handelCollect.bind(null, record),
183   - }
184   - : {
185   - label: t('deviceManagement.device.cancelCollectText'),
186   - icon: 'ant-design:heart-outlined',
187   - popConfirm: {
188   - title: t('deviceManagement.device.cancelCollectConfirmText'),
189   - // confirm: handelCollect.bind(null, record),
190   - },
191   - },
192   - {
193   - label: t('common.delText'),
194   - auth: DeviceListAuthEnum.DELETE,
195   - icon: 'ant-design:delete-outlined',
196   - ifShow: authBtn(role) && record.customerId === undefined,
197   - color: 'error',
198   - popConfirm: {
199   - title: !!record.isEdge
200   - ? t('common.edgeDeviceOperationConfirm')
201   - : t('common.deleteConfirmText'),
202   - confirm: handleDelete.bind(null, record),
203   - },
204   - },
205   - ]"
206   - />
  50 + },
  51 + ]"
  52 + >
  53 + </TableAction>
207 54 </template>
208 55 </BasicTable>
209   -<!-- <LedgerDetailDrawer-->
210   -<!-- @register="registerDetailDrawer"-->
211   -<!-- @open-tb-device-detail="handleOpenTbDeviceDetail"-->
212   -<!-- @open-gateway-device-detail="handleOpenGatewayDetail"-->
213   -<!-- />-->
  56 + <LedgerDrawer @register="registerDrawer" @success="handleSuccess" @reload="handleSuccess" />
214 57 </PageWrapper>
215 58 </div>
216 59 </template>
217 60 <script setup lang="ts">
218   -import {CSSProperties, h, reactive, ref} from "vue";
  61 +import { reactive} from "vue";
219 62 import { PageWrapper } from '/@/components/Page';
  63 +import { LedgerDrawer } from "./components/modal/index"
220 64 const searchInfo = reactive<Recordable>({});
221   -const { organizationIdTreeRef, resetFn } = useResetOrganizationTree(searchInfo);
222   -import {BasicTable, TableAction, TableImg, useTable} from "/@/components/Table";
  65 +const { organizationIdTreeRef, resetFn } = useResetOrganizationTree(searchInfo,'equipment');
  66 +import {BasicTable, TableAction, useTable} from "/@/components/Table";
223 67 import {OrganizationIdTree, useResetOrganizationTree} from "/@/views/common/organizationIdTree";
224   -import {
225   - deleteDevice,
226   - devicePage,
227   - doBatchPrivateDevice,
228   - doBatchPublicDevice
229   -} from "/@/api/device/deviceManager";
  68 +import { getLedgerList, deleteLedger } from "/@/api/equipment/ledger"
230 69 import {
231 70 columns,
232 71 DeviceListAuthEnum,
233 72 searchFormSchema
234 73 } from "/@/views/equipment/ledger/config/ledger.data";
235   -import {DeviceModel, DeviceRecord, DeviceState} from "/@/api/device/model/deviceModel";
  74 +import { SbStatusEnum } from '/@/enums/deviceEnum';
  75 +
236 76 import {useI18n} from "/@/hooks/web/useI18n";
237 77 import {authBtn} from "/@/enums/roleEnum";
238   -import {Badge, Button, Tag} from "ant-design-vue";
  78 +import {Button, Tag} from "ant-design-vue";
239 79 import {Authority} from "/@/components/Authority";
240   -import {AuthDropDown} from "/@/components/Widget";
241 80 import {getAuthCache} from "/@/utils/auth";
242 81 import {USER_INFO_KEY} from "/@/enums/cacheEnum";
243   -import {useBatchOperation} from "/@/utils/useBatchOperation";
244 82 import {useMessage} from "/@/hooks/web/useMessage";
245   -import {DataActionModeEnum} from "/@/enums/toolEnum";
246   -import {
247   - BatchUpdateProductModalParamsType
248   -} from "/@/views/device/list/cpns/modal/BatchUpdateProductModal/index";
249   -import {useModal} from "/@/components/Modal";
250   -import Icon from "/@/components/Icon";
251   -// import LedgerDetailDrawer from "./cpns/modal/LedgerDetailDrawer.vue";
  83 +
  84 +import {useDrawer} from "/@/components/Drawer";
  85 +
  86 +// 业务弹窗
  87 +const [registerDrawer, { openDrawer }] = useDrawer();
252 88 const { t } = useI18n();
253 89 const userInfo: any = getAuthCache(USER_INFO_KEY);
254 90 const role: string = userInfo.roles[0];
255   -const isPublicAndPrivateFlag = ref(false);
256   -const batchPrivateFlag = ref(true);
257   -const batchUpdateProductFlag = ref(true);
258   -const batchSensorFlag = ref(false);
259   -const { createMessage } = useMessage();
260   -const diffBatchSensorFlag = ref(false);
261   -const [registerOrgModal, { openModal: openOrgodal }] = useModal();
262   -const [registerBatchUpdateProductModal, { openModal: openBatchUpdateProductModal }] = useModal();
263 91
264   -const AlarmDetailActionButton = ({ hasAlarm }: { hasAlarm?: boolean }) =>
265   - h(
266   - Badge,
267   - { offset: [0, -5] },
268   - {
269   - default: () => h('span', { style: { color: '#377dff' } }, t('common.detailText')),
270   - count: () =>
271   - h(
272   - 'div',
273   - {
274   - style: {
275   - visibility: hasAlarm ? 'visible' : 'hidden',
276   - width: '14px',
277   - height: '14px',
278   - display: 'flex',
279   - justifyContent: 'center',
280   - alignItems: 'center',
281   - border: '1px solid #f46161',
282   - borderRadius: '50%',
283   - } as CSSProperties,
284   - },
285   - h(Icon, { icon: 'mdi:bell-warning', color: '#f46161', size: 12 })
286   - ),
287   - }
288   - );
  92 +const { createMessage } = useMessage();
289 93
290 94 const [
291 95 registerTable,
... ... @@ -295,13 +99,13 @@ const [
295 99 setSelectedRowKeys,
296 100 getForm,
297 101 getSelectRowKeys,
298   - getSelectRows,
  102 + setProps,
299 103 getRowSelection,
300 104 clearSelectedRowKeys,
301 105 },
302 106 ] = useTable({
303 107 title: t('equipment.ledger.ledgerListText'),
304   - api: devicePage,
  108 + api: getLedgerList,
305 109 columns,
306 110 beforeFetch: (params) => {
307 111 const { deviceProfileId } = params;
... ... @@ -327,7 +131,7 @@ const [
327 131 rowKey: 'id',
328 132 searchInfo: searchInfo,
329 133 clickToRowSelect: false,
330   - rowClassName: (record) => ((record as DeviceRecord).alarmStatus ? 'device-alarm-badge' : ''),
  134 + rowClassName: (record) => ((record as any).alarmStatus ? 'device-alarm-badge' : ''),
331 135 actionColumn: {
332 136 width: 200,
333 137 title: t('common.actionText'),
... ... @@ -336,126 +140,27 @@ const [
336 140 },
337 141 rowSelection: {
338 142 type: 'checkbox',
339   - getCheckboxProps: (record: DeviceModel) => {
340   - return { disabled: !!record.customerId && record.customerName !== 'Public' };
341   - },
342   - onSelect(_record, _selected, selectedRows) {
343   - const [firstItem] = selectedRows as DeviceRecord[];
344   - const { deviceType } = firstItem || {};
345   - batchUpdateProductFlag.value =
346   - !selectedRows.length ||
347   - !selectedRows.every((item) => (item as DeviceRecord).deviceType === deviceType);
348   -
349   - batchPrivateFlag.value = selectedRows.some((item: DeviceRecord) => !item?.customerId);
350   - const filterSensor = selectedRows.map((filterItem: DeviceRecord) => filterItem.deviceType);
351   - batchSensorFlag.value =
352   - filterSensor.includes('SENSOR') &&
353   - (filterSensor.includes('DIRECT_CONNECTION') || filterSensor.includes('GATEWAY')); // 网关子和直连设备或者网关设备,则禁用组织修改
354   - const filterGatewayId = selectedRows
355   - .filter((filterItem: DeviceRecord) => filterItem.deviceType === 'SENSOR')
356   - .map((mapItem: DeviceRecord) => mapItem.gatewayId);
357   - diffBatchSensorFlag.value = [...new Set(filterGatewayId)].length > 1; // 数组长度大于1,说明选择的网关子设备所属网关为多个,则禁用组织修改
358   - isPublicAndPrivateFlag.value =
359   - selectedRows.some((item: DeviceRecord) => !item?.customerId) &&
360   - selectedRows.some((item: DeviceRecord) => item?.customerAdditionalInfo?.isPublic);
361   - },
362   - onSelectAll(_selected, selectedRows) {
363   - const [firstItem] = selectedRows as DeviceRecord[];
364   - const { deviceType } = firstItem || {};
365   - batchUpdateProductFlag.value =
366   - !selectedRows.length ||
367   - !selectedRows.every((item) => (item as DeviceRecord).deviceType === deviceType);
368   -
369   - batchPrivateFlag.value = selectedRows.some((item) => !item?.customerId);
370   - const filterSensor = selectedRows.map((filterItem) => filterItem.deviceType);
371   - batchSensorFlag.value =
372   - filterSensor.includes('SENSOR') &&
373   - (filterSensor.includes('DIRECT_CONNECTION') || filterSensor.includes('GATEWAY')); // 网关子和直连设备或者网关设备,则禁用组织修改
374   - const filterGatewayId = selectedRows
375   - .filter((filterItem: DeviceRecord) => filterItem.deviceType === 'SENSOR')
376   - .map((mapItem: DeviceRecord) => mapItem.gatewayId);
377   - diffBatchSensorFlag.value = [...new Set(filterGatewayId)].length > 1; // 数组长度大于1,说明选择的网关子设备所属网关为多个,则禁用组织修改
378   - isPublicAndPrivateFlag.value =
379   - selectedRows.some((item) => !item?.customerId) &&
380   - selectedRows.some((item) => item?.customerAdditionalInfo?.isPublic);
381   - },
  143 + getCheckboxProps: (record: any) => {},
382 144 },
383 145 });
384 146
385   -const { isExistOption } = useBatchOperation(getRowSelection, setSelectedRowKeys);
386   -function handleCreate() {
387   - // openModal(true, {
388   - // isUpdate: false,
389   - // });
390   -}
391 147
392   -// 批量公开设备
393   -const handleBatchPublic = async () => {
394   - setLoading(true);
395   - try {
396   - const options = getSelectRows();
397   - const tbDeviceIdJoinStr = options.map((item) => item.tbDeviceId).join(',');
398   - const res = await doBatchPublicDevice(tbDeviceIdJoinStr);
399   - createMessage.success(
400   - res === '公开成功' ? t('common.publicSuccess') : t('common.publicError')
401   - );
402   - } finally {
403   - handleReload();
404   - setLoading(false);
405   - }
  148 +// 业务弹窗
  149 +const handleBussinessDrawer = (text, record) => {
  150 + const modalParams = {
  151 + text,
  152 + record,
  153 + };
  154 + openDrawer(true, modalParams);
406 155 };
407 156
408   -function handleReload() {
409   - setSelectedRowKeys([]);
410   - handleSuccess();
411   -}
412 157
413   -// 批量私有设备
414   -const handleBatchPrivate = async () => {
415   - setLoading(true);
416   - try {
417   - const options = getSelectRows();
418   - const tbDeviceIdJoinStr = options.map((item) => item.tbDeviceId).join(',');
419   - const res = await doBatchPrivateDevice(tbDeviceIdJoinStr);
420   - createMessage.success(
421   - res === '私有成功' ? t('common.privateSuccess') : t('common.privateError')
422   - );
423   - } finally {
424   - handleReload();
425   - setLoading(false);
426   - }
427   -};
  158 +const handleDelete = async (record?: any) => {
  159 + let _id: string = record.id;
428 160
429   -const handleBatchOrg = () => {
430   - const options = getSelectRows();
431   - openOrgodal(true, options);
432   -};
433   -
434   -const handelOpenBatchUpdateProductModal = () => {
435   - const rows: DeviceRecord[] = getSelectRows();
436   - const [firstItem] = rows;
437   -
438   - openBatchUpdateProductModal(true, {
439   - mode: DataActionModeEnum.UPDATE,
440   - record: {
441   - sourceDeviceProfileName: firstItem.deviceProfile.name,
442   - deviceType: firstItem.deviceType,
443   - deviceIds: rows.map((item) => item.tbDeviceId),
444   - deviceProfile: firstItem.deviceProfile,
445   - },
446   - } as BatchUpdateProductModalParamsType);
447   -};
448   -
449   -const handleDelete = async (record?: DeviceRecord) => {
450   - let ids: string[] = [];
451   - if (record) {
452   - ids.push(record.id);
453   - } else {
454   - ids = getSelectRowKeys();
455   - }
456 161 try {
457 162 setLoading(true);
458   - await deleteDevice(ids);
  163 + await deleteLedger({id: _id});
459 164 createMessage.success(t('common.deleteSuccessText'));
460 165 handleReload();
461 166 } catch (error) {
... ... @@ -465,12 +170,19 @@ const handleDelete = async (record?: DeviceRecord) => {
465 170 }
466 171 };
467 172
  173 +
  174 +function handleReload() {
  175 + setSelectedRowKeys([]);
  176 + handleSuccess();
  177 +}
  178 +
  179 +
468 180 function handleSuccess() {
469 181 reload();
470 182 }
471 183
472 184 function handleSelect(organization) {
473   - searchInfo.organizationId = organization;
  185 + searchInfo.categoryId = organization;
474 186 handleSuccess();
475 187 }
476 188
... ...