refactor:【antd】【iot】产品详情修改路径到 detail

This commit is contained in:
haohao
2025-12-15 22:48:09 +08:00
parent 5cb412a4da
commit 3744069aa2
6 changed files with 55 additions and 69 deletions

View File

@@ -19,7 +19,7 @@ const routes: RouteRecordRaw[] = [
activePath: '/iot/device/product', activePath: '/iot/device/product',
}, },
component: () => component: () =>
import('#/views/iot/product/product/modules/detail/index.vue'), import('#/views/iot/product/product/detail/index.vue'),
}, },
{ {
path: 'device/detail/:id', path: 'device/detail/:id',

View File

@@ -14,18 +14,13 @@ import { getSimpleProductCategoryList } from '#/api/iot/product/category';
/** 产品分类列表缓存 */ /** 产品分类列表缓存 */
let categoryList: IotProductCategoryApi.ProductCategory[] = []; let categoryList: IotProductCategoryApi.ProductCategory[] = [];
getSimpleProductCategoryList().then((data) => (categoryList = data));
/** 加载产品分类数据 */
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();
/** 新增/修改产品的表单 */ /** 新增/修改产品的表单 */
export function useFormSchema(formApi?: any): VbenFormSchema[] { export function useFormSchema(
formApi?: any,
generateProductKey?: () => string,
): VbenFormSchema[] {
return [ return [
{ {
component: 'Input', component: 'Input',
@@ -59,7 +54,9 @@ export function useFormSchema(formApi?: any): VbenFormSchema[] {
{ {
type: 'default', type: 'default',
onClick: () => { onClick: () => {
formApi?.setFieldValue('productKey', generateProductKey()); if (generateProductKey) {
formApi?.setFieldValue('productKey', generateProductKey());
}
}, },
}, },
{ default: () => '重新生成' }, { 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 [ return [
{ {
component: 'Input', component: 'Input',
@@ -208,7 +208,9 @@ export function useBasicFormSchema(formApi?: any): VbenFormSchema[] {
{ {
type: 'default', type: 'default',
onClick: () => { onClick: () => {
formApi?.setFieldValue('productKey', generateProductKey()); if (generateProductKey) {
formApi?.setFieldValue('productKey', generateProductKey());
}
}, },
}, },
{ default: () => '重新生成' }, { default: () => '重新生成' },
@@ -299,6 +301,7 @@ export function useBasicFormSchema(formApi?: any): VbenFormSchema[] {
buttonStyle: 'solid', buttonStyle: 'solid',
optionType: 'button', optionType: 'button',
}, },
defaultValue: 0,
rules: 'required', rules: 'required',
}, },
{ {
@@ -339,7 +342,6 @@ export function useAdvancedFormSchema(): VbenFormSchema[] {
placeholder: '请输入产品描述', placeholder: '请输入产品描述',
rows: 3, 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;
}

View File

@@ -28,7 +28,6 @@ const activeTab = ref('info');
provide('product', product); // provide('product', product); //
/** 获取产品详情 */ /** 获取产品详情 */
// TODO @haohao detail modules web-antd/src/views/iot/product/product/detail/index.vue
async function getProductData(productId: number) { async function getProductData(productId: number) {
loading.value = true; loading.value = true;
try { try {
@@ -91,3 +90,4 @@ onMounted(async () => {
</Tabs> </Tabs>
</Page> </Page>
</template> </template>

View File

@@ -10,7 +10,7 @@ import { Button, Card, Descriptions, message, Modal } from 'ant-design-vue';
import { updateProductStatus } from '#/api/iot/product/product'; import { updateProductStatus } from '#/api/iot/product/product';
import Form from '../../form.vue'; import Form from '../../modules/form.vue';
interface Props { interface Props {
product: IotProductApi.Product; product: IotProductApi.Product;

View File

@@ -1,7 +1,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { IotProductApi } from '#/api/iot/product/product'; import type { IotProductApi } from '#/api/iot/product/product';
import { computed, ref } from 'vue'; import { computed, nextTick, ref } from 'vue';
import { useVbenModal } from '@vben/common-ui'; import { useVbenModal } from '@vben/common-ui';
@@ -15,11 +15,18 @@ import {
} from '#/api/iot/product/product'; } from '#/api/iot/product/product';
import { $t } from '#/locales'; import { $t } from '#/locales';
import { import { useAdvancedFormSchema, useBasicFormSchema } from '../data';
generateProductKey,
useAdvancedFormSchema, /** 生成 ProductKey包含大小写字母和数字 */
useBasicFormSchema, function generateProductKey(): string {
} from '../data'; const chars =
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
let result = '';
for (let i = 0; i < 16; i++) {
result += chars.charAt(Math.floor(Math.random() * chars.length));
}
return result;
}
const emit = defineEmits(['success']); const emit = defineEmits(['success']);
const formData = ref<IotProductApi.Product>(); const formData = ref<IotProductApi.Product>();
@@ -37,10 +44,9 @@ const [Form, formApi] = useVbenForm({
layout: 'horizontal', layout: 'horizontal',
schema: [], schema: [],
showDefaultActions: false, showDefaultActions: false,
wrapperClass: 'grid-cols-2', wrapperClass: 'grid-cols-1',
}); });
// TODO @haohao这个要不还是一行一个这样样式好看点哈。
const [AdvancedForm, advancedFormApi] = useVbenForm({ const [AdvancedForm, advancedFormApi] = useVbenForm({
commonConfig: { commonConfig: {
componentProps: { class: 'w-full' }, componentProps: { class: 'w-full' },
@@ -48,12 +54,24 @@ const [AdvancedForm, advancedFormApi] = useVbenForm({
layout: 'horizontal', layout: 'horizontal',
schema: useAdvancedFormSchema(), schema: useAdvancedFormSchema(),
showDefaultActions: false, showDefaultActions: false,
wrapperClass: 'grid-cols-2', wrapperClass: 'grid-cols-1',
}); });
/** 基础表单需要 formApi 引用,所以通过 setState 设置 schema */ /** 基础表单需要 formApi 引用,所以通过 setState 设置 schema */
// TODO haohao@haohao要不要把 generateProductKey 拿到这个 vue 里,作为参数传递到 useBasicFormSchema 里? formApi.setState({ schema: useBasicFormSchema(formApi, generateProductKey) });
formApi.setState({ schema: useBasicFormSchema(formApi) });
/** 获取高级表单的值(如果表单未挂载,则从 formData 中获取) */
async function getAdvancedFormValues() {
if (advancedFormApi.isMounted) {
return await advancedFormApi.getValues();
}
// 表单未挂载(折叠状态),从 formData 中获取
return {
icon: formData.value?.icon,
picUrl: formData.value?.picUrl,
description: formData.value?.description,
};
}
const [Modal, modalApi] = useVbenModal({ const [Modal, modalApi] = useVbenModal({
async onConfirm() { async onConfirm() {
@@ -62,18 +80,9 @@ const [Modal, modalApi] = useVbenModal({
return; return;
} }
modalApi.lock(); modalApi.lock();
// 合并两个表单的值 // 合并两个表单的值(字段不冲突,可直接合并)
const basicValues = await formApi.getValues(); const basicValues = await formApi.getValues();
// TODO @haohao有 linter 修复下“formData.value?.id”另外这里直接两个表单合并是不是就可以了呀因为 2 个 schema 本身不同,字段就不同,不会冲突。 const advancedValues = await getAdvancedFormValues();
const advancedValues = activeKey.value.includes('advanced')
? await advancedFormApi.getValues()
: formData.value?.id
? {
icon: formData.value.icon,
picUrl: formData.value.picUrl,
description: formData.value.description,
}
: {};
const data = { const data = {
...basicValues, ...basicValues,
...advancedValues, ...advancedValues,
@@ -96,12 +105,9 @@ const [Modal, modalApi] = useVbenModal({
// 加载数据 // 加载数据
const data = modalApi.getData<IotProductApi.Product>(); const data = modalApi.getData<IotProductApi.Product>();
if (!data || !data.id) { if (!data || !data.id) {
// 新增:设置默认值 // 新增:设置默认值status 通过 schema 中的 defaultValue 自动设置为 0
// TODO @AI
await formApi.setValues({ await formApi.setValues({
// TODO @haohao要不要把 generateProductKey 拿到这个 vue 里,作为参数传递到 useBasicFormSchema 里?
productKey: generateProductKey(), productKey: generateProductKey(),
status: 0, // TODO @haohao通过 defaultValue 即可;
}); });
return; return;
} }
@@ -110,22 +116,10 @@ const [Modal, modalApi] = useVbenModal({
try { try {
formData.value = await getProduct(data.id); formData.value = await getProduct(data.id);
await formApi.setValues(formData.value); await formApi.setValues(formData.value);
// 设置高级表单(不等待 // 设置高级表单(如果已挂载
// TODO @haohao直接把 formData 传过去?没关系的哈。因为会 filter 掉不存在的值,可以试试哈。 await nextTick();
// TODO @haohao这里是不是要 await 下呀?有黄色的告警; if (advancedFormApi.isMounted) {
advancedFormApi.setValues({ await advancedFormApi.setValues(formData.value);
icon: formData.value.icon,
picUrl: formData.value.picUrl,
description: formData.value.description,
});
// 有高级字段时自动展开
// TODO @haohao默认不用展开哈。
if (
formData.value.icon ||
formData.value.picUrl ||
formData.value.description
) {
activeKey.value = ['advanced'];
} }
} finally { } finally {
modalApi.unlock(); modalApi.unlock();