fix:【iot 物联网】linter 报错
This commit is contained in:
@@ -8,10 +8,10 @@ import { handleTree } from '@vben/utils';
|
||||
import { message } from 'ant-design-vue';
|
||||
|
||||
import { z } from '#/adapter/form';
|
||||
import {
|
||||
deleteProductCategory,
|
||||
import {
|
||||
deleteProductCategory,
|
||||
getProductCategoryPage,
|
||||
getSimpleProductCategoryList
|
||||
getSimpleProductCategoryList,
|
||||
} from '#/api/iot/product/category';
|
||||
import { $t } from '#/locales';
|
||||
|
||||
@@ -162,7 +162,10 @@ export function useGridColumns(): VxeTableGridOptions['columns'] {
|
||||
}
|
||||
|
||||
/** 删除分类 */
|
||||
export async function handleDeleteCategory(row: IotProductCategoryApi.ProductCategory, onSuccess?: () => void) {
|
||||
export async function handleDeleteCategory(
|
||||
row: IotProductCategoryApi.ProductCategory,
|
||||
onSuccess?: () => void,
|
||||
) {
|
||||
const hideLoading = message.loading({
|
||||
content: $t('ui.actionMessage.deleting', [row.name]),
|
||||
duration: 0,
|
||||
|
||||
@@ -7,11 +7,11 @@ import { Page, useVbenModal } from '@vben/common-ui';
|
||||
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||
import { $t } from '#/locales';
|
||||
|
||||
import {
|
||||
handleDeleteCategory,
|
||||
import {
|
||||
handleDeleteCategory,
|
||||
queryProductCategoryList,
|
||||
useGridColumns,
|
||||
useGridFormSchema
|
||||
useGridColumns,
|
||||
useGridFormSchema,
|
||||
} from './data';
|
||||
import Form from './modules/ProductCategoryForm.vue';
|
||||
|
||||
@@ -66,7 +66,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
||||
},
|
||||
toolbarConfig: {
|
||||
refresh: true,
|
||||
search:true,
|
||||
search: true,
|
||||
},
|
||||
treeConfig: {
|
||||
parentField: 'parentId',
|
||||
@@ -95,7 +95,6 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
||||
icon: ACTION_ICON.ADD,
|
||||
onClick: handleCreate,
|
||||
},
|
||||
|
||||
]"
|
||||
/>
|
||||
</template>
|
||||
|
||||
@@ -11,10 +11,10 @@ import { message } from 'ant-design-vue';
|
||||
|
||||
import { z } from '#/adapter/form';
|
||||
import { getSimpleProductCategoryList } from '#/api/iot/product/category';
|
||||
import {
|
||||
deleteProduct,
|
||||
exportProduct,
|
||||
getProductPage
|
||||
import {
|
||||
deleteProduct,
|
||||
exportProduct,
|
||||
getProductPage,
|
||||
} from '#/api/iot/product/product';
|
||||
|
||||
/** 新增/修改产品的表单 */
|
||||
|
||||
@@ -4,17 +4,15 @@ import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
import { Button, Card, Image, Input, Space } from 'ant-design-vue';
|
||||
import { Page, useVbenModal } from '@vben/common-ui';
|
||||
import { IconifyIcon } from '@vben/icons';
|
||||
|
||||
import { Button, Card, Image, Input, Space } from 'ant-design-vue';
|
||||
|
||||
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||
import { $t } from '#/locales';
|
||||
|
||||
import ProductForm from './modules/ProductForm.vue';
|
||||
// @ts-ignore
|
||||
import ProductCardView from './modules/ProductCardView.vue';
|
||||
import {
|
||||
import {
|
||||
getCategoryName,
|
||||
handleDeleteProduct,
|
||||
handleExportProduct,
|
||||
@@ -23,12 +21,15 @@ import {
|
||||
useGridColumns,
|
||||
useImagePreview,
|
||||
} from './data';
|
||||
// @ts-ignore
|
||||
import ProductCardView from './modules/ProductCardView.vue';
|
||||
import ProductForm from './modules/ProductForm.vue';
|
||||
|
||||
defineOptions({ name: 'IoTProduct' });
|
||||
|
||||
const router = useRouter();
|
||||
const categoryList = ref<any[]>([]);
|
||||
const viewMode = ref<'list' | 'card'>('card');
|
||||
const viewMode = ref<'card' | 'list'>('card');
|
||||
const cardViewRef = ref();
|
||||
|
||||
// 搜索参数
|
||||
@@ -150,17 +151,17 @@ onMounted(() => {
|
||||
<template>
|
||||
<Page auto-content-height>
|
||||
<FormModal @success="handleRefresh" />
|
||||
|
||||
|
||||
<!-- 统一搜索工具栏 -->
|
||||
<Card :body-style="{ padding: '16px' }" class="mb-4">
|
||||
<!-- 搜索表单 -->
|
||||
<div class="flex items-center gap-3 mb-3">
|
||||
<div class="mb-3 flex items-center gap-3">
|
||||
<Input
|
||||
v-model:value="searchParams.name"
|
||||
placeholder="请输入产品名称"
|
||||
allow-clear
|
||||
style="width: 200px"
|
||||
@pressEnter="handleSearch"
|
||||
@press-enter="handleSearch"
|
||||
>
|
||||
<template #prefix>
|
||||
<span class="text-gray-400">产品名称</span>
|
||||
@@ -171,7 +172,7 @@ onMounted(() => {
|
||||
placeholder="请输入产品标识"
|
||||
allow-clear
|
||||
style="width: 200px"
|
||||
@pressEnter="handleSearch"
|
||||
@press-enter="handleSearch"
|
||||
>
|
||||
<template #prefix>
|
||||
<span class="text-gray-400">ProductKey</span>
|
||||
@@ -199,7 +200,7 @@ onMounted(() => {
|
||||
导出
|
||||
</Button>
|
||||
</Space>
|
||||
|
||||
|
||||
<!-- 视图切换 -->
|
||||
<Space :size="4">
|
||||
<Button
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref } from 'vue';
|
||||
|
||||
import { DICT_TYPE } from '@vben/constants';
|
||||
import { getDictLabel } from '@vben/hooks';
|
||||
import { IconifyIcon } from '@vben/icons';
|
||||
|
||||
import {
|
||||
Button,
|
||||
Card,
|
||||
@@ -12,14 +16,21 @@ import {
|
||||
Tag,
|
||||
Tooltip,
|
||||
} from 'ant-design-vue';
|
||||
import { DICT_TYPE } from '@vben/constants';
|
||||
import { getDictLabel } from '@vben/hooks';
|
||||
import { IconifyIcon } from '@vben/icons';
|
||||
|
||||
import { getProductPage } from '#/api/iot/product/product';
|
||||
|
||||
defineOptions({ name: 'ProductCardView' });
|
||||
|
||||
const props = defineProps<Props>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
create: [];
|
||||
delete: [row: any];
|
||||
detail: [productId: number];
|
||||
edit: [row: any];
|
||||
thingModel: [productId: number];
|
||||
}>();
|
||||
|
||||
interface Props {
|
||||
categoryList: any[];
|
||||
searchParams?: {
|
||||
@@ -28,16 +39,6 @@ interface Props {
|
||||
};
|
||||
}
|
||||
|
||||
const props = defineProps<Props>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
create: [];
|
||||
edit: [row: any];
|
||||
delete: [row: any];
|
||||
detail: [productId: number];
|
||||
thingModel: [productId: number];
|
||||
}>();
|
||||
|
||||
const loading = ref(false);
|
||||
const list = ref<any[]>([]);
|
||||
const total = ref(0);
|
||||
@@ -88,7 +89,7 @@ onMounted(() => {
|
||||
});
|
||||
|
||||
// 暴露方法供父组件调用
|
||||
defineExpose({
|
||||
defineExpose({
|
||||
reload: getList,
|
||||
search: () => {
|
||||
queryParams.value.pageNo = 1;
|
||||
@@ -111,42 +112,57 @@ defineExpose({
|
||||
:lg="6"
|
||||
class="mb-4"
|
||||
>
|
||||
<Card
|
||||
:body-style="{ padding: '20px' }"
|
||||
class="product-card h-full"
|
||||
>
|
||||
<Card :body-style="{ padding: '20px' }" class="product-card h-full">
|
||||
<!-- 顶部标题区域 -->
|
||||
<div class="flex items-start mb-4">
|
||||
<div class="mb-4 flex items-start">
|
||||
<div class="product-icon">
|
||||
<IconifyIcon icon="ant-design:inbox-outlined" class="text-[32px]" />
|
||||
<IconifyIcon
|
||||
icon="ant-design:inbox-outlined"
|
||||
class="text-[32px]"
|
||||
/>
|
||||
</div>
|
||||
<div class="ml-3 flex-1 min-w-0">
|
||||
<div class="ml-3 min-w-0 flex-1">
|
||||
<div class="product-title">{{ item.name }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 内容区域 -->
|
||||
<div class="flex items-start mb-4">
|
||||
<div class="flex-1 info-list">
|
||||
<div class="mb-4 flex items-start">
|
||||
<div class="info-list flex-1">
|
||||
<div class="info-item">
|
||||
<span class="info-label">产品分类</span>
|
||||
<span class="info-value text-primary">{{ getCategoryName(item.categoryId) }}</span>
|
||||
<span class="info-value text-primary">{{
|
||||
getCategoryName(item.categoryId)
|
||||
}}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">产品类型</span>
|
||||
<Tag :color="getDeviceTypeColor(item.deviceType)" class="m-0 info-tag">
|
||||
{{ getDictLabel(DICT_TYPE.IOT_PRODUCT_DEVICE_TYPE, item.deviceType) }}
|
||||
<Tag
|
||||
:color="getDeviceTypeColor(item.deviceType)"
|
||||
class="info-tag m-0"
|
||||
>
|
||||
{{
|
||||
getDictLabel(
|
||||
DICT_TYPE.IOT_PRODUCT_DEVICE_TYPE,
|
||||
item.deviceType,
|
||||
)
|
||||
}}
|
||||
</Tag>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">产品标识</span>
|
||||
<Tooltip :title="item.productKey || item.id" placement="top">
|
||||
<span class="info-value product-key">{{ item.productKey || item.id }}</span>
|
||||
<span class="info-value product-key">{{
|
||||
item.productKey || item.id
|
||||
}}</span>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
<div class="product-3d-icon">
|
||||
<IconifyIcon icon="ant-design:box-plot-outlined" class="text-[80px]" />
|
||||
<IconifyIcon
|
||||
icon="ant-design:box-plot-outlined"
|
||||
class="text-[80px]"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -173,7 +189,10 @@ defineExpose({
|
||||
class="action-btn action-btn-model"
|
||||
@click="emit('thingModel', item.id)"
|
||||
>
|
||||
<IconifyIcon icon="ant-design:apartment-outlined" class="mr-1" />
|
||||
<IconifyIcon
|
||||
icon="ant-design:apartment-outlined"
|
||||
class="mr-1"
|
||||
/>
|
||||
物模型
|
||||
</Button>
|
||||
<Popconfirm
|
||||
@@ -374,4 +393,3 @@ defineExpose({
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
<script setup lang="ts">
|
||||
import type { IotProductApi } from '#/api/iot/product/product';
|
||||
|
||||
import { computed, ref } from 'vue';
|
||||
|
||||
import { message } from 'ant-design-vue';
|
||||
import { useVbenForm, useVbenModal } from '@vben/common-ui';
|
||||
|
||||
import { createProduct, getProduct, updateProduct, type IotProductApi } from '#/api/iot/product/product';
|
||||
import { message } from 'ant-design-vue';
|
||||
|
||||
import {
|
||||
createProduct,
|
||||
getProduct,
|
||||
updateProduct,
|
||||
} from '#/api/iot/product/product';
|
||||
import { $t } from '#/locales';
|
||||
|
||||
import { useFormSchema } from '../data';
|
||||
|
||||
@@ -1,20 +1,18 @@
|
||||
<!-- IoT 产品选择器,使用弹窗展示 -->
|
||||
<script setup lang="ts">
|
||||
import type { IotProductApi } from '#/api/iot/product/product';
|
||||
|
||||
import { reactive, ref } from 'vue';
|
||||
|
||||
import { message } from 'ant-design-vue';
|
||||
import { useVbenModal } from '@vben/common-ui';
|
||||
|
||||
import { message } from 'ant-design-vue';
|
||||
|
||||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||
import { getProductPage } from '#/api/iot/product/product';
|
||||
import type { IotProductApi } from '#/api/iot/product/product';
|
||||
|
||||
defineOptions({ name: 'IoTProductTableSelect' });
|
||||
|
||||
interface Props {
|
||||
multiple?: boolean;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
multiple: false,
|
||||
});
|
||||
@@ -23,6 +21,10 @@ const emit = defineEmits<{
|
||||
success: [product: IotProductApi.Product | IotProductApi.Product[]];
|
||||
}>();
|
||||
|
||||
interface Props {
|
||||
multiple?: boolean;
|
||||
}
|
||||
|
||||
const [Modal, modalApi] = useVbenModal({
|
||||
title: '产品选择器',
|
||||
onConfirm: handleConfirm,
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
import type { IotProductApi } from '#/api/iot/product/product';
|
||||
|
||||
import { ref } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
import { message } from 'ant-design-vue';
|
||||
|
||||
import { updateProductStatus } from '#/api/iot/product/product';
|
||||
import type { IotProductApi } from '#/api/iot/product/product';
|
||||
|
||||
import ProductForm from '../ProductForm.vue';
|
||||
|
||||
@@ -37,7 +38,10 @@ const copyToClipboard = async (text: string) => {
|
||||
|
||||
/** 跳转到设备管理 */
|
||||
const goToDeviceList = (productId: number) => {
|
||||
router.push({ path: '/iot/device/device', query: { productId: String(productId) } });
|
||||
router.push({
|
||||
path: '/iot/device/device',
|
||||
query: { productId: String(productId) },
|
||||
});
|
||||
};
|
||||
|
||||
/** 打开编辑表单 */
|
||||
@@ -102,12 +106,18 @@ const confirmUnpublish = async (id: number) => {
|
||||
<a-descriptions :column="1">
|
||||
<a-descriptions-item label="ProductKey">
|
||||
{{ product.productKey }}
|
||||
<a-button size="small" class="ml-2" @click="copyToClipboard(product.productKey || '')">
|
||||
<a-button
|
||||
size="small"
|
||||
class="ml-2"
|
||||
@click="copyToClipboard(product.productKey || '')"
|
||||
>
|
||||
复制
|
||||
</a-button>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="设备总数">
|
||||
<span class="ml-5 mr-2">{{ product.deviceCount ?? '加载中...' }}</span>
|
||||
<span class="ml-5 mr-2">{{
|
||||
product.deviceCount ?? '加载中...'
|
||||
}}</span>
|
||||
<a-button size="small" @click="goToDeviceList(product.id!)">
|
||||
前往管理
|
||||
</a-button>
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
<script setup lang="ts">
|
||||
import type { IotProductApi } from '#/api/iot/product/product';
|
||||
|
||||
import { DICT_TYPE } from '@vben/constants';
|
||||
|
||||
import { DictTag } from '#/components/dict-tag';
|
||||
import type { IotProductApi } from '#/api/iot/product/product';
|
||||
import { DeviceTypeEnum } from '#/api/iot/product/product';
|
||||
import { DictTag } from '#/components/dict-tag';
|
||||
|
||||
interface Props {
|
||||
product: IotProductApi.Product;
|
||||
@@ -28,7 +29,10 @@ const formatDate = (date?: Date | string) => {
|
||||
{{ product.categoryName || '-' }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="设备类型">
|
||||
<DictTag :type="DICT_TYPE.IOT_PRODUCT_DEVICE_TYPE" :value="product.deviceType" />
|
||||
<DictTag
|
||||
:type="DICT_TYPE.IOT_PRODUCT_DEVICE_TYPE"
|
||||
:value="product.deviceType"
|
||||
/>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="定位类型">
|
||||
{{ product.locationType ?? '-' }}
|
||||
@@ -43,7 +47,11 @@ const formatDate = (date?: Date | string) => {
|
||||
<DictTag :type="DICT_TYPE.COMMON_STATUS" :value="product.status" />
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item
|
||||
v-if="[DeviceTypeEnum.DEVICE, DeviceTypeEnum.GATEWAY].includes(product.deviceType!)"
|
||||
v-if="
|
||||
[DeviceTypeEnum.DEVICE, DeviceTypeEnum.GATEWAY].includes(
|
||||
product.deviceType!,
|
||||
)
|
||||
"
|
||||
label="联网方式"
|
||||
>
|
||||
<DictTag :type="DICT_TYPE.IOT_NET_TYPE" :value="product.netType" />
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
<script setup lang="ts">
|
||||
import type { IotProductApi } from '#/api/iot/product/product';
|
||||
|
||||
import { onMounted, provide, ref } from 'vue';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
|
||||
import { message } from 'ant-design-vue';
|
||||
import { Page } from '@vben/common-ui';
|
||||
|
||||
import { getProduct } from '#/api/iot/product/product';
|
||||
import type { IotProductApi } from '#/api/iot/product/product';
|
||||
import { message } from 'ant-design-vue';
|
||||
|
||||
import { getDeviceCount } from '#/api/iot/device/device';
|
||||
import { getProduct } from '#/api/iot/product/product';
|
||||
import IoTProductThingModel from '#/views/iot/thingmodel/index.vue';
|
||||
|
||||
import ProductDetailsHeader from './ProductDetailsHeader.vue';
|
||||
import ProductDetailsInfo from './ProductDetailsInfo.vue';
|
||||
import IoTProductThingModel from '#/views/iot/thingmodel/index.vue';
|
||||
|
||||
defineOptions({ name: 'IoTProductDetail' });
|
||||
|
||||
@@ -43,7 +45,12 @@ const getDeviceCountData = async (productId: number) => {
|
||||
try {
|
||||
return await getDeviceCount(productId);
|
||||
} catch (error) {
|
||||
console.error('Error fetching device count:', error, 'productId:', productId);
|
||||
console.error(
|
||||
'Error fetching device count:',
|
||||
error,
|
||||
'productId:',
|
||||
productId,
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
@@ -55,15 +62,15 @@ onMounted(async () => {
|
||||
router.back();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
await getProductData(id);
|
||||
|
||||
|
||||
// 处理 tab 参数
|
||||
const { tab } = route.query;
|
||||
if (tab) {
|
||||
activeTab.value = tab as string;
|
||||
}
|
||||
|
||||
|
||||
// 查询设备数量
|
||||
if (product.value.id) {
|
||||
product.value.deviceCount = await getDeviceCountData(product.value.id);
|
||||
@@ -84,7 +91,10 @@ onMounted(async () => {
|
||||
<ProductDetailsInfo v-if="activeTab === 'info'" :product="product" />
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="thingModel" tab="物模型(功能定义)">
|
||||
<IoTProductThingModel v-if="activeTab === 'thingModel'" :product-id="id" />
|
||||
<IoTProductThingModel
|
||||
v-if="activeTab === 'thingModel'"
|
||||
:product-id="id"
|
||||
/>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</Page>
|
||||
|
||||
Reference in New Issue
Block a user