diff --git a/apps/web-antd/src/router/routes/modules/iot.ts b/apps/web-antd/src/router/routes/modules/iot.ts index 3e7f87caf..1c885a4c6 100644 --- a/apps/web-antd/src/router/routes/modules/iot.ts +++ b/apps/web-antd/src/router/routes/modules/iot.ts @@ -19,7 +19,7 @@ const routes: RouteRecordRaw[] = [ activePath: '/iot/device/product', }, component: () => - import('#/views/iot/product/product/modules/detail/index.vue'), + import('#/views/iot/product/product/detail/index.vue'), }, { path: 'device/detail/:id', diff --git a/apps/web-antd/src/views/iot/product/product/data.ts b/apps/web-antd/src/views/iot/product/product/data.ts index e9e7809bf..6d21d05b2 100644 --- a/apps/web-antd/src/views/iot/product/product/data.ts +++ b/apps/web-antd/src/views/iot/product/product/data.ts @@ -14,18 +14,13 @@ import { getSimpleProductCategoryList } from '#/api/iot/product/category'; /** 产品分类列表缓存 */ let categoryList: IotProductCategoryApi.ProductCategory[] = []; - -/** 加载产品分类数据 */ -async function loadCategoryData() { - categoryList = await getSimpleProductCategoryList(); -} - -// 初始化加载分类数据 -// TODO @haohao:可以参考 /Users/yunai/Java/yudao-ui-admin-vben-v5/apps/web-antd/src/views/system/tenant/data.ts 简洁一点。 -loadCategoryData(); +getSimpleProductCategoryList().then((data) => (categoryList = data)); /** 新增/修改产品的表单 */ -export function useFormSchema(formApi?: any): VbenFormSchema[] { +export function useFormSchema( + formApi?: any, + generateProductKey?: () => string, +): VbenFormSchema[] { return [ { component: 'Input', @@ -59,7 +54,9 @@ export function useFormSchema(formApi?: any): VbenFormSchema[] { { type: 'default', onClick: () => { - formApi?.setFieldValue('productKey', generateProductKey()); + if (generateProductKey) { + formApi?.setFieldValue('productKey', generateProductKey()); + } }, }, { default: () => '重新生成' }, @@ -175,7 +172,10 @@ export function useFormSchema(formApi?: any): VbenFormSchema[] { } /** 基础表单字段(不含图标、图片、描述) */ -export function useBasicFormSchema(formApi?: any): VbenFormSchema[] { +export function useBasicFormSchema( + formApi?: any, + generateProductKey?: () => string, +): VbenFormSchema[] { return [ { component: 'Input', @@ -208,7 +208,9 @@ export function useBasicFormSchema(formApi?: any): VbenFormSchema[] { { type: 'default', onClick: () => { - formApi?.setFieldValue('productKey', generateProductKey()); + if (generateProductKey) { + formApi?.setFieldValue('productKey', generateProductKey()); + } }, }, { default: () => '重新生成' }, @@ -299,6 +301,7 @@ export function useBasicFormSchema(formApi?: any): VbenFormSchema[] { buttonStyle: 'solid', optionType: 'button', }, + defaultValue: 0, rules: 'required', }, { @@ -339,7 +342,6 @@ export function useAdvancedFormSchema(): VbenFormSchema[] { placeholder: '请输入产品描述', rows: 3, }, - formItemClass: 'col-span-2', // 让描述占满两列 }, ]; } @@ -404,13 +406,3 @@ export function useGridColumns(): VxeTableGridOptions['columns'] { ]; } -/** 生成 ProductKey(包含大小写字母和数字) */ -export function generateProductKey(): string { - const chars = - 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; - let result = ''; - for (let i = 0; i < 16; i++) { - result += chars.charAt(Math.floor(Math.random() * chars.length)); - } - return result; -} diff --git a/apps/web-antd/src/views/iot/product/product/modules/detail/index.vue b/apps/web-antd/src/views/iot/product/product/detail/index.vue similarity index 93% rename from apps/web-antd/src/views/iot/product/product/modules/detail/index.vue rename to apps/web-antd/src/views/iot/product/product/detail/index.vue index 1769c8017..3ca0daee1 100644 --- a/apps/web-antd/src/views/iot/product/product/modules/detail/index.vue +++ b/apps/web-antd/src/views/iot/product/product/detail/index.vue @@ -28,7 +28,6 @@ const activeTab = ref('info'); provide('product', product); // 提供产品信息给子组件 /** 获取产品详情 */ -// TODO @haohao:因为 detail 是独立界面,所以不放在 modules 里,应该放在 web-antd/src/views/iot/product/product/detail/index.vue 里,更合理一些哈。 async function getProductData(productId: number) { loading.value = true; try { @@ -91,3 +90,4 @@ onMounted(async () => { + diff --git a/apps/web-antd/src/views/iot/product/product/modules/detail/modules/header.vue b/apps/web-antd/src/views/iot/product/product/detail/modules/header.vue similarity index 98% rename from apps/web-antd/src/views/iot/product/product/modules/detail/modules/header.vue rename to apps/web-antd/src/views/iot/product/product/detail/modules/header.vue index e298afe1d..52ae5ee85 100644 --- a/apps/web-antd/src/views/iot/product/product/modules/detail/modules/header.vue +++ b/apps/web-antd/src/views/iot/product/product/detail/modules/header.vue @@ -10,7 +10,7 @@ import { Button, Card, Descriptions, message, Modal } from 'ant-design-vue'; import { updateProductStatus } from '#/api/iot/product/product'; -import Form from '../../form.vue'; +import Form from '../../modules/form.vue'; interface Props { product: IotProductApi.Product; diff --git a/apps/web-antd/src/views/iot/product/product/modules/detail/modules/info.vue b/apps/web-antd/src/views/iot/product/product/detail/modules/info.vue similarity index 100% rename from apps/web-antd/src/views/iot/product/product/modules/detail/modules/info.vue rename to apps/web-antd/src/views/iot/product/product/detail/modules/info.vue diff --git a/apps/web-antd/src/views/iot/product/product/index.vue b/apps/web-antd/src/views/iot/product/product/index.vue index da7930c82..302fc1f1c 100644 --- a/apps/web-antd/src/views/iot/product/product/index.vue +++ b/apps/web-antd/src/views/iot/product/product/index.vue @@ -51,11 +51,8 @@ async function loadCategories() { function handleSearch() { if (viewMode.value === 'list') { gridApi.formApi.setValues(queryParams.value); - gridApi.query(); - } else { - // TODO @haohao:要不 search 也改成 query 方法,更统一一点哈。 - cardViewRef.value?.search(queryParams.value); } + gridApi.query(); } /** 重置搜索 */ @@ -67,11 +64,7 @@ function handleReset() { /** 刷新表格 */ function handleRefresh() { - if (viewMode.value === 'list') { - gridApi.query(); - } else { - cardViewRef.value?.reload(); - } + gridApi.query(); } /** 导出表格 */ @@ -149,6 +142,17 @@ const [Grid, gridApi] = useVbenVxeGrid({ } as VxeTableGridOptions, }); +// 包装 gridApi.query() 方法,统一列表视图和卡片视图的查询接口 +const originalQuery = gridApi.query.bind(gridApi); +gridApi.query = async (params?: Record) => { + if (viewMode.value === 'list') { + return await originalQuery(params); + } else { + // 卡片视图:调用卡片组件的 query 方法 + cardViewRef.value?.query(); + } +}; + /** 初始化 */ onMounted(() => { loadCategories(); diff --git a/apps/web-antd/src/views/iot/product/product/modules/card-view.vue b/apps/web-antd/src/views/iot/product/product/modules/card-view.vue index ac297355f..49150ae99 100644 --- a/apps/web-antd/src/views/iot/product/product/modules/card-view.vue +++ b/apps/web-antd/src/views/iot/product/product/modules/card-view.vue @@ -85,7 +85,7 @@ function getDeviceTypeColor(deviceType: number) { defineExpose({ reload: getList, - search: () => { + query: () => { queryParams.value.pageNo = 1; getList(); }, diff --git a/apps/web-antd/src/views/iot/product/product/modules/form.vue b/apps/web-antd/src/views/iot/product/product/modules/form.vue index 1ead43b64..6f7fdb26f 100644 --- a/apps/web-antd/src/views/iot/product/product/modules/form.vue +++ b/apps/web-antd/src/views/iot/product/product/modules/form.vue @@ -1,7 +1,7 @@