feat(project): 优化业务代码语法格式

This commit is contained in:
xlsea
2025-12-16 16:40:20 +08:00
parent f6dcded877
commit 7f04b119a7
52 changed files with 264 additions and 311 deletions
+2 -2
View File
@@ -290,11 +290,11 @@ public class VelocityUtils {
for (GenTableColumn column : columns) {
if (!column.isSuperColumn() && StringUtils.isNotEmpty(column.getDictType()) && StringUtils.equalsAny(
column.getHtmlType(),
new String[]{GenConstants.HTML_SELECT, GenConstants.HTML_RADIO, GenConstants.HTML_CHECKBOX})) {
GenConstants.HTML_SELECT, GenConstants.HTML_RADIO, GenConstants.HTML_CHECKBOX)) {
Map<String, Object> dict = new HashMap<>();
dict.put("type", column.getDictType());
dict.put("name", StringUtils.toCamelCase(column.getDictType()));
dict.put("immediate", !column.isList());
dict.put("immediate", column.isList());
dicts.add(dict);
}
}
+12 -2
View File
@@ -11,11 +11,19 @@ import { $t } from '@/locales';
import ButtonIcon from '@/components/custom/button-icon.vue';
import ${BusinessName}OperateDrawer from './modules/${business__name}-operate-drawer.vue';
import ${BusinessName}Search from './modules/${business__name}-search.vue';
#if($dictList && $dictList.size() > 0)
import { useDict } from '@/hooks/business/dict';
#end
defineOptions({
name: '${BusinessName}List'
});
#if($dictList && $dictList.size() > 0)
#foreach($dict in $dictList)
useDict('${dict.type}'#if(!$dict.immediate), false#end);
#end#end
const appStore = useAppStore();
const { download } = useDownload();
const { hasAuth } = useAuth();
@@ -64,7 +72,10 @@ const {
key: '$column.javaField',
title: '$column.columnComment',
align: 'center',
minWidth: 120
minWidth: 120#if($column.dictType),
render(row) {
return <DictTag value={row.$column.javaField} dictCode="$column.dictType" />;
}#end
},
#end
#end
@@ -213,7 +224,6 @@ function handleExport() {
v-model:visible="drawerVisible"
:operate-type="operateType"
:row-data="editingData"
:tree-list="data"
@submitted="getData"
/>
</NCard>
+12 -1
View File
@@ -10,11 +10,19 @@ import { $t } from '@/locales';
import ButtonIcon from '@/components/custom/button-icon.vue';
import ${BusinessName}OperateDrawer from './modules/${business__name}-operate-drawer.vue';
import ${BusinessName}Search from './modules/${business__name}-search.vue';
#if($dictList && $dictList.size() > 0)
import { useDict } from '@/hooks/business/dict';
#end
defineOptions({
name: '${BusinessName}List'
});
#if($dictList && $dictList.size() > 0)
#foreach($dict in $dictList)
useDict('${dict.type}'#if(!$dict.immediate), false#end);
#end#end
const appStore = useAppStore();
const { download } = useDownload();
const { hasAuth } = useAuth();
@@ -57,7 +65,10 @@ const { columns, columnChecks, data, getData, getDataByPage, loading, mobilePagi
key: '$column.javaField',
title: '$column.columnComment',
align: 'center',
minWidth: 120
minWidth: 120#if($column.dictType),
render(row) {
return <DictTag value={row.$column.javaField} dictCode="$column.dictType" />;
}#end
},
#end
#end
+55 -50
View File
@@ -1,9 +1,11 @@
<script setup lang="ts">
import { computed, ref, watch } from 'vue';
import { jsonClone } from '@sa/utils';
import { fetchCreate${BusinessName}, fetchUpdate${BusinessName} } from '@/service/api/${moduleName}/${business__name}';
import { fetchCreate${BusinessName}, fetchUpdate${BusinessName}#if($tplCategory == 'tree'), fetchGet${BusinessName}List#end } from '@/service/api/${moduleName}/${business__name}';
import { useFormRules, useNaiveForm } from '@/hooks/common/form';
#if($dictList && $dictList.size() > 0)import { useDict } from '@/hooks/business/dict';#end
#if($tplCategory == 'tree')
import { handleTree } from '@/utils/common';
#end
import { $t } from '@/locales';
defineOptions({
@@ -15,10 +17,6 @@ interface Props {
operateType: NaiveUI.TableOperateType;
/** the edit row data */
rowData?: Api.$ModuleName.${BusinessName} | null;
#if($tplCategory == 'tree')
/** the tree data */
treeList?: Api.$ModuleName.${BusinessName}[] | null;
#end
}
const props = defineProps<Props>();
@@ -32,13 +30,12 @@ const emit = defineEmits<Emits>();
const visible = defineModel<boolean>('visible', {
default: false
});
#if($tplCategory == 'tree')
#if($dictList && $dictList.size() > 0)
#foreach($dict in $dictList)
const { options: ${dict.name}Options } = useDict('${dict.type}'#if($dict.immediate), false#end);
#end#end
const treeList = ref<Api.Demo.Tree[]>([]);
#end
const { formRef, validate, restoreValidation } = useNaiveForm();
const { validate, restoreValidation } = useNaiveForm();
const { createRequiredRule } = useFormRules();
const title = computed(() => {
@@ -56,7 +53,7 @@ const model = ref<Model>(createDefaultModel());
function createDefaultModel(): Model {
return {
#foreach($column in $columns)
#if($column.insert || $column.isEdit)
#if($column.insert() || $column.isEdit())
${column.javaField}:#if($column.javaType == 'String' || ($!column.dictType && $column.dictType != '')) ''#else null#end#if($foreach.hasNext),#end
#end
#end
@@ -119,11 +116,23 @@ async function handleSubmit() {
closeDrawer();
emit('submitted');
}
#if($tplCategory == 'tree')
async function getTreeList() {
const { data, error } = await fetchGet${BusinessName}List();
if (error) {
return;
}
const { tree } = handleTree(data);
treeList.value = tree;
}
#end
watch(visible, () => {
if (visible.value) {
handleUpdateModelWhenEdit();
restoreValidation();
getTreeList();
}
});
#if($tplCategory == 'tree')
@@ -133,7 +142,7 @@ const treeOptions = computed(() => {
{
id: 0,
treeName: '顶级节点',
children: props.treeList!
children: treeList.value
}
];
});
@@ -143,17 +152,12 @@ const treeOptions = computed(() => {
<template>
<NDrawer v-model:show="visible" :title="title" display-directive="show" :width="800" class="max-w-90%">
<NDrawerContent :title="title" :native-scrollbar="false" closable>
<NForm ref="formRef" :model="model" :rules="rules">
<NForm :model="model" :rules="rules">
#set($immediateDictList = [])
#foreach($column in $columns)
#set($field=$column.javaField)
#if(($column.insert || $column.edit) && !$column.pk)
#set($parentheseIndex=$column.columnComment.indexOf("("))
#if($parentheseIndex != -1)
#set($comment=$column.columnComment.substring(0, $parentheseIndex))
#else
#set($comment=$column.columnComment)
#end
#set($dictType=$!StrUtil.toCamelCase($column.dictType))
#set($isImmediate = !$column.isList() && !$column.isQuery() && !$immediateDictList.contains($column.dictType))
<NFormItem label="$column.columnComment" path="$column.javaField">
#if($tplCategory == 'tree' && $column.javaField == $treeParentCode)
<NTreeSelect
@@ -172,49 +176,50 @@ const treeOptions = computed(() => {
type="textarea"
placeholder="请输入$column.columnComment"
/>
#elseif($column.htmlType == "select" && "" != $dictType)
#elseif($column.htmlType == "select" && $column.dictType)
<DictSelect
v-model:value="model.$column.javaField"
placeholder="请选择$column.columnComment"
dict-code="$column.dictType"
clearable
#if($isImmediate)#set($void = $immediateDictList.add($column.dictType))
immediate
#end
/>
#elseif($column.htmlType == "select" && !$column.dictType)
<NSelect
v-model:value="model.$column.javaField"
placeholder="请选择$column.columnComment"
:options="${dictType}Options"
:options="[{ value: '0', label: '请选择字典生成' }]"
clearable
/>
#elseif($column.htmlType == "select" && $dictType)
<NSelect
#elseif($column.htmlType == "radio" && $column.dictType)
<DictRadio
v-model:value="model.$column.javaField"
placeholder="请选择$column.columnComment"
:options="[]"
dict-code="$column.dictType"
clearable
#if($isImmediate)#set($void = $immediateDictList.add($column.dictType))
immediate
#end
/>
#elseif($column.htmlType == "radio" && "" != $dictType)
<NRadioGroup v-model:value="model.$column.javaField">
<NSpace>
<NRadio
v-for="option in ${dictType}Options"
:key="option.value"
:value="option.value"
:label="option.label"
/>
</NSpace>
</NRadioGroup>
#elseif($column.htmlType == "radio" && $dictType)
#elseif($column.htmlType == "radio" && !$column.dictType)
<NRadioGroup v-model:value="model.$column.javaField">
<NSpace>
<NRadio value="0" label="请选择字典生成" />
</NSpace>
</NRadioGroup>
#elseif($column.htmlType == "checkbox" && "" != $dictType)
<NCheckboxGroup v-model:value="model.$column.javaField">
<NSpace>
<NCheckbox
v-for="option in ${dictType}Options"
:key="option.value"
:value="option.value"
:label="option.label"
/>
</NSpace>
</NCheckboxGroup>
#elseif($column.htmlType == "checkbox" && $dictType)
#elseif($column.htmlType == "checkbox" && $column.dictType)
<DictCheckbox
v-model:value="model.$column.javaField"
placeholder="请选择$column.columnComment"
dict-code="$column.dictType"
clearable
#if($isImmediate)#set($void = $immediateDictList.add($column.dictType))
immediate
#end
/>
#elseif($column.htmlType == "checkbox" && $column.dictType)
<NCheckboxGroup v-model:value="model.$column.javaField">
<NSpace>
<NCheckbox value="0" label="请选择字典生成" />
+9 -48
View File
@@ -4,28 +4,18 @@ import { toRaw } from 'vue';
import { jsonClone } from '@sa/utils';
import { useNaiveForm } from '@/hooks/common/form';
import { $t } from '@/locales';
#if($dictList && $dictList.size() > 0)import { useDict } from '@/hooks/business/dict';#end
defineOptions({
name: '${BusinessName}Search'
});
#if($tplCategory == 'tree')
interface Props {
/** the tree list */
treeList?: Api.$ModuleName.${BusinessName}[] | null;
}
defineProps<Props>();
#end
interface Emits {
(e: 'search'): void;
}
const emit = defineEmits<Emits>();
const { formRef, validate, restoreValidation } = useNaiveForm();
const { validate, restoreValidation } = useNaiveForm();
#foreach ($column in $columns)
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
@@ -33,10 +23,6 @@ const { formRef, validate, restoreValidation } = useNaiveForm();
const dateRange${AttrName} = ref<[string, string] | null>(null);
#end#end
const model = defineModel<Api.$ModuleName.${BusinessName}SearchParams>('model', { required: true });
#if($dictList && $dictList.size() > 0)
#foreach($dict in $dictList)
const { options: ${dict.name}Options } = useDict('${dict.type}'#if($dict.immediate), false#end);
#end#end
const defaultModel = jsonClone(toRaw(model.value));
@@ -69,53 +55,28 @@ async function search() {
#end
emit('search');
}
#if($tplCategory == 'tree')
const treeOptions = computed(() => {
return [
{
id: 0,
treeName: '顶级节点',
children: props.treeList!
}
];
});
#end
</script>
<template>
<NCard :bordered="false" size="small" class="card-wrapper">
<NCollapse>
<NCollapseItem :title="$t('common.search')" name="$moduleName-${business__name}-search">
<NForm ref="formRef" :model="model" label-placement="left" :label-width="80">
<NForm :model="model" label-placement="left" :label-width="80">
<NGrid responsive="screen" item-responsive>
#set($immediateDictList = [])
#foreach($column in $columns)
#if($column.query)
#set($dictType=$!StrUtil.toCamelCase($column.dictType))
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
#set($parentheseIndex=$column.columnComment.indexOf("("))
#if($parentheseIndex != -1)
#set($comment=$column.columnComment.substring(0, $parentheseIndex))
#else
#set($comment=$column.columnComment)
#end
<NFormItemGi span="24 s:12 m:6" label="$column.columnComment" label-width="auto" path="$column.javaField" class="pr-24px">
#if($tplCategory == 'tree' && $column.javaField == $treeParentCode)
<NTreeSelect
v-model:value="model.$treeParentCode"
filterable
class="h-full"
key-field="$treeCode"
label-field="$treeName"
:options="treeOptions"
:default-expanded-keys="[0]"
/>
#elseif($!StrUtil.contains("select, radio, checkbox", $column.htmlType) && $dictType && "" != $dictType)
<NSelect
#if($!StrUtil.contains("select, radio, checkbox", $column.htmlType) && $column.dictType)
<DictSelect
v-model:value="model.$column.javaField"
placeholder="请选择$column.columnComment"
:options="${dictType}Options"
dict-code="$column.dictType"
clearable
#if(!$column.isList() && !$immediateDictList.contains($column.dictType))#set($void = $immediateDictList.add($column.dictType))
immediate
#end
/>
#elseif($!StrUtil.contains("select, radio, checkbox", $column.htmlType))
<NSelect
+28
View File
@@ -0,0 +1,28 @@
<script setup lang="ts">
import { useDict } from '@/hooks/business/dict';
defineOptions({ name: 'DictCheckbox' });
interface Props {
dictCode: string;
immediate?: boolean;
}
const props = withDefaults(defineProps<Props>(), {
immediate: false
});
const value = defineModel<string[]>('value', { required: false });
const { options } = useDict(props.dictCode, props.immediate);
</script>
<template>
<NCheckboxGroup v-model:value="value">
<NSpace>
<NCheckbox v-for="option in options" :key="option.value" :value="option.value" :label="option.label" />
</NSpace>
</NCheckboxGroup>
</template>
<style scoped></style>
+2 -1
View File
@@ -28,12 +28,13 @@ async function getMenuList() {
startLoading();
const { error, data } = await fetchGetMenuList();
if (error) return;
const { tree } = handleTree(data, { idField: 'menuId', filterFn: item => item.menuType !== 'F' });
options.value = [
{
menuId: 0,
menuName: '根目录',
icon: 'material-symbols:home-outline-rounded',
children: handleTree(data, { idField: 'menuId', filterFn: item => item.menuType !== 'F' })
children: tree
}
] as Api.System.MenuList;
endLoading();
+6 -72
View File
@@ -6,6 +6,7 @@ import type { PaginationData, TableColumnCheck, UseTableOptions } from '@sa/hook
import type { FlatResponseData } from '@sa/axios';
import { jsonClone } from '@sa/utils';
import { useAppStore } from '@/store/modules/app';
import { handleTree } from '@/utils/common';
import { $t } from '@/locales';
export type UseNaiveTableOptions<ResponseData, ApiData, Pagination extends boolean> = Omit<
@@ -399,86 +400,19 @@ export function useTreeTableOperate<ApiData>(data: Ref<ApiData[]>, idKey: keyof
};
}
type TreeTableOptions<ApiData> = {
/** id field name */
idField?: keyof ApiData;
/** parent id field name */
parentIdField?: keyof ApiData;
/** children field name */
childrenField?: keyof ApiData;
/** filter function */
filterFn?: (node: ApiData) => boolean;
};
export function treeTransform<ApiData>(
response: FlatResponseData<any, ApiData[]>,
options: TreeTableOptions<ApiData>
options: CommonType.TreeConfig<ApiData> = {}
): TreeTableTransformResult<ApiData> {
const { data, error } = response;
if (error || !data.length) {
return {
tree: [],
flatData: []
};
}
const { idField = 'id', parentIdField = 'parentId', childrenField = 'children', filterFn = () => true } = options;
// filter flat data
const flatData = data.filter(filterFn);
// 使用 Map 替代普通对象,提高性能
const childrenMap = new Map<ApiData[keyof ApiData], ApiData[]>();
const nodeMap = new Map<ApiData[keyof ApiData], ApiData>();
const tree: ApiData[] = [];
// 第一遍遍历:构建节点映射
for (const item of flatData) {
const id = item[idField as keyof ApiData];
const parentId = item[parentIdField as keyof ApiData];
nodeMap.set(id, item);
if (!childrenMap.has(parentId)) {
childrenMap.set(parentId, []);
}
childrenMap.get(parentId)!.push(item);
}
// 第二遍遍历:找出根节点
for (const item of flatData) {
const parentId = item[parentIdField as keyof ApiData];
if (!nodeMap.has(parentId)) {
tree.push(item);
}
}
// 递归构建树形结构
const buildTree = (node: ApiData) => {
const id = node[idField as keyof ApiData];
const children = childrenMap.get(id);
if (children?.length) {
// 使用类型断言确保类型安全
(node as any)[childrenField] = children;
for (const child of children) {
buildTree(child);
}
} else {
// 如果没有子节点,设置为 undefined
(node as any)[childrenField] = undefined;
}
};
// 从根节点开始构建树
for (const root of tree) {
buildTree(root);
if (!error) {
return handleTree(data, options);
}
return {
tree,
flatData
tree: [],
flatData: []
};
}
+4 -4
View File
@@ -33,13 +33,13 @@ declare namespace CommonType {
type ErrorCode = '401' | '403' | '404' | 'default';
/** The configuration options for constructing tree structure data */
type TreeConfig = {
type TreeConfig<T> = {
/** id field name */
idField: string;
idField?: keyof T;
/** parent id field name */
parentIdField?: string;
parentIdField?: keyof T;
/** children field name */
childrenField?: string;
childrenField?: keyof T;
/** filter function */
filterFn?: (node: any) => boolean;
};
+4
View File
@@ -16,11 +16,13 @@ declare module 'vue' {
BetterScroll: typeof import('./../components/custom/better-scroll.vue')['default']
BooleanTag: typeof import('./../components/custom/boolean-tag.vue')['default']
ButtonIcon: typeof import('./../components/custom/button-icon.vue')['default']
copy: typeof import('./../components/custom/dict-radio copy.vue')['default']
CountTo: typeof import('./../components/custom/count-to.vue')['default']
DarkModeContainer: typeof import('./../components/common/dark-mode-container.vue')['default']
DataTable: typeof import('./../components/common/data-table.vue')['default']
DeptTree: typeof import('./../components/custom/dept-tree.vue')['default']
DeptTreeSelect: typeof import('./../components/custom/dept-tree-select.vue')['default']
DictCheckbox: typeof import('./../components/custom/dict-checkbox.vue')['default']
DictRadio: typeof import('./../components/custom/dict-radio.vue')['default']
DictSelect: typeof import('./../components/custom/dict-select.vue')['default']
DictTag: typeof import('./../components/custom/dict-tag.vue')['default']
@@ -164,11 +166,13 @@ declare global {
const BetterScroll: typeof import('./../components/custom/better-scroll.vue')['default']
const BooleanTag: typeof import('./../components/custom/boolean-tag.vue')['default']
const ButtonIcon: typeof import('./../components/custom/button-icon.vue')['default']
const copy: typeof import('./../components/custom/dict-radio copy.vue')['default']
const CountTo: typeof import('./../components/custom/count-to.vue')['default']
const DarkModeContainer: typeof import('./../components/common/dark-mode-container.vue')['default']
const DataTable: typeof import('./../components/common/data-table.vue')['default']
const DeptTree: typeof import('./../components/custom/dept-tree.vue')['default']
const DeptTreeSelect: typeof import('./../components/custom/dept-tree-select.vue')['default']
const DictCheckbox: typeof import('./../components/custom/dict-checkbox.vue')['default']
const DictRadio: typeof import('./../components/custom/dict-radio.vue')['default']
const DictSelect: typeof import('./../components/custom/dict-select.vue')['default']
const DictTag: typeof import('./../components/custom/dict-tag.vue')['default']
+25 -18
View File
@@ -98,50 +98,54 @@ export function isImage(suffix: string) {
* @param {TreeConfig} config 配置选项
* @returns {T[]} 树形结构数据
*/
export const handleTree = <T extends Record<string, any>>(data: T[], config: CommonType.TreeConfig): T[] => {
export const handleTree = <T>(data: T[], config: CommonType.TreeConfig<T> = {}): { tree: T[]; flatData: T[] } => {
if (!data?.length) {
return [];
return {
tree: [],
flatData: []
};
}
const {
idField,
idField = 'id',
parentIdField = 'parentId',
childrenField = 'children',
filterFn = () => true // 添加过滤函数,默认为不过滤
// 添加过滤函数,默认为不过滤
filterFn = () => true
} = config;
// filter flat data
const flatData = data.filter(filterFn) || [];
// 使用 Map 替代普通对象,提高性能
const childrenMap = new Map<string | number, T[]>();
const nodeMap = new Map<string | number, T>();
const childrenMap = new Map<T[keyof T], T[]>();
const nodeMap = new Map<T[keyof T], T>();
const tree: T[] = [];
// 第一遍遍历:构建节点映射
for (const item of data) {
const id = item[idField];
const parentId = item[parentIdField];
for (const item of flatData) {
const id = item[idField as keyof T];
const parentId = item[parentIdField as keyof T];
nodeMap.set(id, item);
if (!childrenMap.has(parentId)) {
childrenMap.set(parentId, []);
}
// 应用过滤函数
if (filterFn(item)) {
childrenMap.get(parentId)!.push(item);
}
childrenMap.get(parentId)!.push(item);
}
// 第二遍遍历:找出根节点
for (const item of data) {
const parentId = item[parentIdField];
if (!nodeMap.has(parentId) && filterFn(item)) {
for (const item of flatData) {
const parentId = item[parentIdField as keyof T];
if (!nodeMap.has(parentId)) {
tree.push(item);
}
}
// 递归构建树形结构
const buildTree = (node: T) => {
const id = node[idField];
const id = node[idField as keyof T];
const children = childrenMap.get(id);
if (children?.length) {
@@ -161,7 +165,10 @@ export const handleTree = <T extends Record<string, any>>(data: T[], config: Com
buildTree(root);
}
return tree;
return {
tree: tree || [],
flatData
};
};
/**
@@ -10,7 +10,7 @@ defineOptions({
});
const { toggleLoginModule } = useRouterPush();
const { formRef, validate } = useNaiveForm();
const { validate } = useNaiveForm();
const { label, isCounting, loading, getCaptcha } = useCaptcha();
interface FormModel {
@@ -44,7 +44,7 @@ async function handleSubmit() {
{{ $t('page.login.codeLogin.title') }}
</div>
<div class="pb-18px text-16px text-#858585">请输入您的手机号,我们将发送验证码到您的手机</div>
<NForm ref="formRef" :model="model" :rules="rules" size="large" :show-label="false" @keyup.enter="handleSubmit">
<NForm :model="model" :rules="rules" size="large" :show-label="false" @keyup.enter="handleSubmit">
<NFormItem path="phone">
<NInput v-model:value="model.phone" :placeholder="$t('page.login.common.phonePlaceholder')" />
</NFormItem>
@@ -9,7 +9,7 @@ defineOptions({
});
const { toggleLoginModule } = useRouterPush();
const { formRef, validate } = useNaiveForm();
const { validate } = useNaiveForm();
interface FormModel {
phone: string;
@@ -50,7 +50,7 @@ async function handleSubmit() {
{{ $t('page.login.resetPwd.title') }}
</div>
<div class="pb-18px text-16px text-#858585">请输入您的手机号,我们将发送验证码到您的手机</div>
<NForm ref="formRef" :model="model" :rules="rules" size="large" :show-label="false" @keyup.enter="handleSubmit">
<NForm :model="model" :rules="rules" size="large" :show-label="false" @keyup.enter="handleSubmit">
<NFormItem path="phone">
<NInput v-model:value="model.phone" :placeholder="$t('page.login.common.phonePlaceholder')" />
</NFormItem>
@@ -28,7 +28,7 @@ const visible = defineModel<boolean>('visible', {
default: false
});
const { formRef, validate, restoreValidation } = useNaiveForm();
const { validate, restoreValidation } = useNaiveForm();
const { createRequiredRule } = useFormRules();
const title = computed(() => {
@@ -110,7 +110,7 @@ watch(visible, () => {
<template>
<NDrawer v-model:show="visible" :title="title" display-directive="show" :width="800" class="max-w-90%">
<NDrawerContent :title="title" :native-scrollbar="false" closable>
<NForm ref="formRef" :model="model" :rules="rules">
<NForm :model="model" :rules="rules">
<NFormItem label="部门" path="deptId">
<DeptTreeSelect v-model:value="model.deptId" placeholder="请选择部门" />
</NFormItem>
+2 -2
View File
@@ -14,7 +14,7 @@ interface Emits {
const emit = defineEmits<Emits>();
const { formRef, validate, restoreValidation } = useNaiveForm();
const { validate, restoreValidation } = useNaiveForm();
const model = defineModel<Api.Demo.DemoSearchParams>('model', { required: true });
@@ -40,7 +40,7 @@ async function search() {
<NCard :bordered="false" size="small" class="card-wrapper">
<NCollapse>
<NCollapseItem :title="$t('common.search')" name="demo-demo-search">
<NForm ref="formRef" :model="model" label-placement="left" :label-width="80">
<NForm :model="model" label-placement="left" :label-width="80">
<NGrid responsive="screen" item-responsive>
<NFormItemGi span="24 s:12 m:6" label="部门 ID" label-width="auto" path="deptId" class="pr-24px">
<DeptTreeSelect v-model:value="model.deptId" placeholder="请选择部门" />
+4 -4
View File
@@ -43,7 +43,7 @@ const {
} = useNaiveTreeTable({
keyField: 'id',
api: () => fetchGetTreeList(searchParams.value),
transform: response => treeTransform(response, { idField: 'id' }),
transform: response => treeTransform(response),
columns: () => [
{
type: 'selection',
@@ -76,7 +76,7 @@ const {
},
{
key: 'treeName',
title: '值',
title: '树节点名',
align: 'center',
minWidth: 120
},
@@ -84,7 +84,7 @@ const {
key: 'operate',
title: $t('common.operate'),
align: 'center',
width: 130,
width: 150,
render: row => {
const addBtn = () => {
return (
@@ -176,7 +176,7 @@ function handleExport() {
<template>
<div class="min-h-500px flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto">
<TreeSearch v-model:model="searchParams" @search="getData" />
<TreeSearch v-model:model="searchParams" :tree-list="data" @search="getData" />
<NCard title="测试树表列表" :bordered="false" size="small" class="card-wrapper sm:flex-1-hidden">
<template #header-extra>
<TableHeaderOperation
@@ -1,8 +1,9 @@
<script setup lang="ts">
import { computed, ref, watch } from 'vue';
import { jsonClone } from '@sa/utils';
import { fetchCreateTree, fetchUpdateTree } from '@/service/api/demo/tree';
import { fetchCreateTree, fetchGetTreeList, fetchUpdateTree } from '@/service/api/demo/tree';
import { useFormRules, useNaiveForm } from '@/hooks/common/form';
import { handleTree } from '@/utils/common';
import { $t } from '@/locales';
defineOptions({
@@ -14,8 +15,6 @@ interface Props {
operateType: NaiveUI.TableOperateType;
/** the edit row data */
rowData?: Api.Demo.Tree | null;
/** the tree data */
treeList?: Api.Demo.Tree[] | null;
}
const props = defineProps<Props>();
@@ -30,7 +29,9 @@ const visible = defineModel<boolean>('visible', {
default: false
});
const { formRef, validate, restoreValidation } = useNaiveForm();
const treeList = ref<Api.Demo.Tree[]>([]);
const { validate, restoreValidation } = useNaiveForm();
const { createRequiredRule } = useFormRules();
const title = computed(() => {
@@ -62,7 +63,7 @@ const rules: Record<RuleKey, App.Global.FormRule> = {
parentId: createRequiredRule('父 ID 不能为空'),
deptId: createRequiredRule('部门不能为空'),
userId: createRequiredRule('用户不能为空'),
treeName: createRequiredRule('值不能为空')
treeName: createRequiredRule('树节点名不能为空')
};
function handleUpdateModelWhenEdit() {
@@ -99,10 +100,20 @@ async function handleSubmit() {
emit('submitted');
}
async function getTreeList() {
const { data, error } = await fetchGetTreeList();
if (error) {
return;
}
const { tree } = handleTree(data);
treeList.value = tree;
}
watch(visible, () => {
if (visible.value) {
handleUpdateModelWhenEdit();
restoreValidation();
getTreeList();
}
});
@@ -111,7 +122,7 @@ const treeOptions = computed(() => {
{
id: 0,
treeName: '顶级节点',
children: props.treeList!
children: treeList.value
}
];
});
@@ -120,7 +131,7 @@ const treeOptions = computed(() => {
<template>
<NDrawer v-model:show="visible" :title="title" display-directive="show" :width="800" class="max-w-90%">
<NDrawerContent :title="title" :native-scrollbar="false" closable>
<NForm ref="formRef" :model="model" :rules="rules">
<NForm :model="model" :rules="rules">
<NFormItem label="父 ID" path="parentId">
<NTreeSelect
v-model:value="model.parentId"
@@ -138,7 +149,7 @@ const treeOptions = computed(() => {
<NFormItem label="用户" path="userId">
<UserSelect v-model:value="model.userId" placeholder="请选择用户" />
</NFormItem>
<NFormItem label="值" path="treeName">
<NFormItem label="树节点名" path="treeName">
<NInput v-model:value="model.treeName" placeholder="请输入值" />
</NFormItem>
</NForm>
+4 -22
View File
@@ -8,20 +8,13 @@ defineOptions({
name: 'TreeSearch'
});
interface Props {
/** the tree list */
treeList?: Api.Demo.Tree[] | null;
}
defineProps<Props>();
interface Emits {
(e: 'search'): void;
}
const emit = defineEmits<Emits>();
const { formRef, validate, restoreValidation } = useNaiveForm();
const { validate, restoreValidation } = useNaiveForm();
const model = defineModel<Api.Demo.TreeSearchParams>('model', { required: true });
@@ -47,18 +40,10 @@ async function search() {
<NCard :bordered="false" size="small" class="card-wrapper">
<NCollapse>
<NCollapseItem :title="$t('common.search')" name="demo-tree-search">
<NForm ref="formRef" :model="model" label-placement="left" :label-width="80">
<NForm :model="model" label-placement="left" :label-width="80">
<NGrid responsive="screen" item-responsive>
<NFormItemGi span="24 s:12 m:6" label="父 ID" label-width="auto" path="parentId" class="pr-24px">
<NTreeSelect
v-model:value="model.parentId"
filterable
class="h-full"
key-field="id"
label-field="treeName"
:options="treeList!"
:default-expanded-keys="[0]"
/>
<NFormItemGi span="24 s:12 m:6" label="树节点名" label-width="auto" path="treeName" class="pr-24px">
<NInput v-model:value="model.treeName" placeholder="请输入树节点名" />
</NFormItemGi>
<NFormItemGi span="24 s:12 m:6" label="部门" label-width="auto" path="deptId" class="pr-24px">
<DeptTreeSelect v-model:value="model.deptId" placeholder="请选择部门" />
@@ -66,9 +51,6 @@ async function search() {
<NFormItemGi span="24 s:12 m:6" label="用户" label-width="auto" path="userId" class="pr-24px">
<UserSelect v-model:value="model.userId" placeholder="请选择用户" />
</NFormItemGi>
<NFormItemGi span="24 s:12 m:6" label="值" label-width="auto" path="treeName" class="pr-24px">
<NInput v-model:value="model.treeName" placeholder="请输入值" />
</NFormItemGi>
<NFormItemGi :show-feedback="false" span="24" class="pr-24px">
<NSpace class="w-full" justify="end">
<NButton @click="reset">
@@ -14,7 +14,7 @@ interface Emits {
const emit = defineEmits<Emits>();
const { formRef, validate, restoreValidation } = useNaiveForm();
const { validate, restoreValidation } = useNaiveForm();
const dateRangeLoginTime = ref<[string, string] | null>(null);
@@ -50,7 +50,7 @@ async function search() {
<NCard :bordered="false" size="small" class="card-wrapper">
<NCollapse>
<NCollapseItem :title="$t('common.search')" name="user-search">
<NForm ref="formRef" :model="model" label-placement="left" :label-width="80">
<NForm :model="model" label-placement="left" :label-width="80">
<NGrid responsive="screen" item-responsive>
<NFormItemGi span="24 s:12 m:6" label="IP地址" path="ipaddr" class="pr-24px">
<NInput v-model:value="model.ipaddr" placeholder="请输入登录IP地址" />
@@ -14,7 +14,7 @@ interface Emits {
const emit = defineEmits<Emits>();
const { formRef, validate, restoreValidation } = useNaiveForm();
const { validate, restoreValidation } = useNaiveForm();
const model = defineModel<Api.Monitor.OnlineUserSearchParams>('model', { required: true });
@@ -40,7 +40,7 @@ async function search() {
<NCard :bordered="false" size="small" class="card-wrapper">
<NCollapse>
<NCollapseItem :title="$t('common.search')" name="user-search">
<NForm ref="formRef" :model="model" label-placement="left" :label-width="80">
<NForm :model="model" label-placement="left" :label-width="80">
<NGrid responsive="screen" item-responsive>
<NFormItemGi span="24 s:12 m:8" label="IP地址" path="ipaddr" class="pr-24px">
<NInput v-model:value="model.ipaddr" placeholder="请输入IP地址" />
@@ -14,7 +14,7 @@ interface Emits {
const emit = defineEmits<Emits>();
const { formRef, validate, restoreValidation } = useNaiveForm();
const { validate, restoreValidation } = useNaiveForm();
const dateRangeOperTime = ref<[string, string] | null>(null);
@@ -50,7 +50,7 @@ async function search() {
<NCard :bordered="false" size="small" class="card-wrapper">
<NCollapse>
<NCollapseItem :title="$t('common.search')" name="user-search">
<NForm ref="formRef" :model="model" label-placement="left" :label-width="80">
<NForm :model="model" label-placement="left" :label-width="80">
<NGrid responsive="screen" item-responsive>
<NFormItemGi span="24 s:12 m:6" label="系统模块" path="title" class="pr-24px">
<NInput v-model:value="model.title" placeholder="请输入系统模块" />
@@ -28,7 +28,7 @@ const visible = defineModel<boolean>('visible', {
default: false
});
const { formRef, validate, restoreValidation } = useNaiveForm();
const { validate, restoreValidation } = useNaiveForm();
const { createRequiredRule } = useFormRules();
const title = computed(() => {
@@ -133,7 +133,7 @@ watch(visible, () => {
<template>
<NDrawer v-model:show="visible" :title="title" display-directive="show" :width="800" class="max-w-90%">
<NDrawerContent :title="title" :native-scrollbar="false" closable>
<NForm ref="formRef" :model="model" :rules="rules">
<NForm :model="model" :rules="rules">
<NFormItem v-if="operateType === 'edit'" :label="$t('page.system.client.clientId')" path="clientId">
<NInput
v-model:value="model.clientId"
@@ -14,7 +14,7 @@ interface Emits {
const emit = defineEmits<Emits>();
const { formRef, validate, restoreValidation } = useNaiveForm();
const { validate, restoreValidation } = useNaiveForm();
const model = defineModel<Api.System.ClientSearchParams>('model', { required: true });
@@ -40,7 +40,7 @@ async function search() {
<NCard :bordered="false" size="small" class="card-wrapper">
<NCollapse>
<NCollapseItem :title="$t('common.search')" name="user-search">
<NForm ref="formRef" :model="model" label-placement="left" :label-width="90">
<NForm :model="model" label-placement="left" :label-width="90">
<NGrid responsive="screen" item-responsive>
<NFormItemGi
span="24 s:12 m:6"
@@ -28,7 +28,7 @@ const visible = defineModel<boolean>('visible', {
default: false
});
const { formRef, validate, restoreValidation } = useNaiveForm();
const { validate, restoreValidation } = useNaiveForm();
const { createRequiredRule } = useFormRules();
const title = computed(() => {
@@ -106,7 +106,7 @@ watch(visible, () => {
<template>
<NDrawer v-model:show="visible" :title="title" display-directive="show" :width="800" class="max-w-90%">
<NDrawerContent :title="title" :native-scrollbar="false" closable>
<NForm ref="formRef" :model="model" :rules="rules">
<NForm :model="model" :rules="rules">
<NFormItem :label="$t('page.system.config.configName')" path="configName">
<NInput v-model:value="model.configName" :placeholder="$t('page.system.config.form.configName.required')" />
</NFormItem>
@@ -14,7 +14,7 @@ interface Emits {
const emit = defineEmits<Emits>();
const { formRef, validate, restoreValidation } = useNaiveForm();
const { validate, restoreValidation } = useNaiveForm();
const dateRangeCreateTime = ref<[string, string] | null>(null);
@@ -53,7 +53,7 @@ async function search() {
<NCard :bordered="false" size="small" class="card-wrapper">
<NCollapse>
<NCollapseItem :title="$t('common.search')" name="user-search">
<NForm ref="formRef" :model="model" label-placement="left" :label-width="80">
<NForm :model="model" label-placement="left" :label-width="80">
<NGrid responsive="screen" item-responsive>
<NFormItemGi
span="24 s:12 m:6"
@@ -32,7 +32,7 @@ const visible = defineModel<boolean>('visible', {
default: false
});
const { formRef, validate, restoreValidation } = useNaiveForm();
const { validate, restoreValidation } = useNaiveForm();
const { createRequiredRule, patternRules } = useFormRules();
const { loading: deptLoading, startLoading: startDeptLoading, endLoading: endDeptLoading } = useLoading();
@@ -142,7 +142,8 @@ async function getDeptData() {
}
if (data) {
deptData.value = handleTree(data, { idField: 'deptId' });
const { tree } = handleTree(data, { idField: 'deptId' });
deptData.value = tree;
if (deptData.value?.length) {
expandedKeys.value = [deptData.value[0].deptId];
}
@@ -187,7 +188,7 @@ watch(visible, () => {
<template>
<NDrawer v-model:show="visible" :title="title" display-directive="show" :width="800" class="max-w-90%">
<NDrawerContent :title="title" :native-scrollbar="false" closable>
<NForm ref="formRef" :model="model" :rules="rules">
<NForm :model="model" :rules="rules">
<NFormItem v-if="model.parentId !== 0" :label="$t('page.system.dept.parentId')" path="parentId">
<NTreeSelect
v-model:value="model.parentId"
@@ -15,7 +15,7 @@ interface Emits {
const emit = defineEmits<Emits>();
const { formRef, validate, restoreValidation } = useNaiveForm();
const { validate, restoreValidation } = useNaiveForm();
const { options: sysNormalDisableOptions } = useDict('sys_normal_disable', false);
@@ -43,7 +43,7 @@ async function search() {
<NCard :bordered="false" size="small" class="card-wrapper">
<NCollapse>
<NCollapseItem :title="$t('common.search')" name="user-search">
<NForm ref="formRef" :model="model" label-placement="left" :label-width="80">
<NForm :model="model" label-placement="left" :label-width="80">
<NGrid responsive="screen" item-responsive>
<NFormItemGi span="24 s:12 m:8" :label="$t('page.system.dept.deptName')" path="deptName" class="pr-24px">
<NInput v-model:value="model.deptName" :placeholder="$t('page.system.dept.form.deptName.required')" />
@@ -31,7 +31,7 @@ const visible = defineModel<boolean>('visible', {
default: false
});
const { formRef, validate, restoreValidation } = useNaiveForm();
const { validate, restoreValidation } = useNaiveForm();
const { createRequiredRule } = useFormRules();
const title = computed(() => {
@@ -152,7 +152,7 @@ function renderTagLabel(option: { label: string; value: string }) {
<template>
<NDrawer v-model:show="visible" :title="title" display-directive="show" :width="800" class="max-w-90%">
<NDrawerContent :title="title" :native-scrollbar="false" closable>
<NForm ref="formRef" :model="model" :rules="rules">
<NForm :model="model" :rules="rules">
<NFormItem :label="$t('page.system.dict.dictType')" path="dictType">
<NInput
v-model:value="model.dictType"
@@ -15,7 +15,7 @@ interface Emits {
const emit = defineEmits<Emits>();
const { formRef, validate, restoreValidation } = useNaiveForm();
const { validate, restoreValidation } = useNaiveForm();
const model = defineModel<Api.System.DictDataSearchParams>('model', { required: true });
@@ -41,7 +41,7 @@ async function search() {
<NCard :bordered="false" size="small" class="card-wrapper">
<NCollapse>
<NCollapseItem :title="$t('common.search')" name="user-search">
<NForm ref="formRef" :model="model" label-placement="left" :label-width="80">
<NForm :model="model" label-placement="left" :label-width="80">
<NGrid responsive="screen" item-responsive>
<NFormItemGi
span="24 s:12 m:12"
@@ -28,7 +28,7 @@ const visible = defineModel<boolean>('visible', {
default: false
});
const { formRef, validate, restoreValidation } = useNaiveForm();
const { validate, restoreValidation } = useNaiveForm();
const { createRequiredRule } = useFormRules();
const title = computed(() => {
@@ -103,7 +103,7 @@ watch(visible, () => {
<template>
<NDrawer v-model:show="visible" :title="title" display-directive="show" :width="800" class="max-w-90%">
<NDrawerContent :title="title" :native-scrollbar="false" closable>
<NForm ref="formRef" :model="model" :rules="rules">
<NForm :model="model" :rules="rules">
<NFormItem :label="$t('page.system.dict.dictName')" path="dictName">
<NInput v-model:value="model.dictName" :placeholder="$t('page.system.dict.form.dictName.required')" />
</NFormItem>
+2 -1
View File
@@ -57,12 +57,13 @@ const getMeunTree = async () => {
startLoading();
const { data, error } = await fetchGetMenuList();
if (error) return;
const { tree } = handleTree(data, { idField: 'menuId', filterFn: item => item.menuType !== 'F' });
treeData.value = [
{
menuId: 0,
menuName: $t('page.system.menu.rootName'),
icon: 'material-symbols:home-outline-rounded',
children: handleTree(data, { idField: 'menuId', filterFn: item => item.menuType !== 'F' })
children: tree
}
] as Api.System.Menu[];
endLoading();
@@ -24,7 +24,7 @@ const menuTreeRef = ref<InstanceType<typeof MenuTree> | null>(null);
const menuOptions = ref<Api.System.MenuList>([]);
const { loading: menuLoading } = useLoading();
const { formRef, validate, restoreValidation } = useNaiveForm();
const { validate, restoreValidation } = useNaiveForm();
const { createRequiredRule } = useFormRules();
type Model = {
@@ -92,7 +92,7 @@ watch(visible, () => {
class="max-w-90% w-500px"
@close="closeDrawer"
>
<NForm ref="formRef" :model="model" :rules="rules">
<NForm :model="model" :rules="rules">
<NFormItem :show-label="false" path="menuIds">
<MenuTree
v-if="visible"
@@ -43,7 +43,7 @@ const defaultIcon = import.meta.env.VITE_MENU_ICON;
const layoutType = ref<string>('0');
const iconType = ref<Api.System.IconType>('1');
const { formRef, validate, restoreValidation } = useNaiveForm();
const { validate, restoreValidation } = useNaiveForm();
const { createRequiredRule, createNumberRequiredRule } = useFormRules();
const queryList = ref<{ key: string; value: string }[]>([]);
@@ -294,7 +294,7 @@ function onCreate() {
<template>
<NDrawer v-model:show="visible" display-directive="show" :width="600" class="max-w-90%">
<NDrawerContent :title="drawerTitle" :native-scrollbar="false" closable>
<NForm ref="formRef" :model="model" :rules="rules">
<NForm :model="model" :rules="rules">
<NGrid responsive="screen" item-responsive>
<NFormItemGi :span="24" :label="$t('page.system.menu.parentId')" path="pid">
<MenuTreeSelect
@@ -30,7 +30,7 @@ const visible = defineModel<boolean>('visible', {
});
const umoEditorRef = ref<InstanceType<typeof UmoEditor>>();
const { formRef, validate, restoreValidation } = useNaiveForm();
const { validate, restoreValidation } = useNaiveForm();
const { createRequiredRule } = useFormRules();
const title = computed(() => {
@@ -116,7 +116,7 @@ watch(visible, () => {
class="max-w-90%"
>
<NDrawerContent :title="title" :native-scrollbar="false" closable>
<NForm ref="formRef" :model="model" :rules="rules">
<NForm :model="model" :rules="rules">
<div class="grid grid-cols-1 gap-16px md:grid-cols-4">
<NFormItem class="col-span-2" label="公告标题" path="noticeTitle">
<NInput v-model:value="model.noticeTitle" placeholder="请输入公告标题" />
@@ -14,7 +14,7 @@ interface Emits {
const emit = defineEmits<Emits>();
const { formRef, validate, restoreValidation } = useNaiveForm();
const { validate, restoreValidation } = useNaiveForm();
const model = defineModel<Api.System.NoticeSearchParams>('model', { required: true });
@@ -40,7 +40,7 @@ async function search() {
<NCard :bordered="false" size="small" class="card-wrapper">
<NCollapse>
<NCollapseItem :title="$t('common.search')" name="user-search">
<NForm ref="formRef" :model="model" label-placement="left" :label-width="80">
<NForm :model="model" label-placement="left" :label-width="80">
<NGrid responsive="screen" item-responsive>
<NFormItemGi span="24 s:12 m:8" label="公告标题" path="noticeTitle" class="pr-24px">
<NInput v-model:value="model.noticeTitle" placeholder="请输入公告标题" />
@@ -29,7 +29,7 @@ const visible = defineModel<boolean>('visible', {
default: false
});
const { formRef, validate, restoreValidation } = useNaiveForm();
const { validate, restoreValidation } = useNaiveForm();
const { createRequiredRule } = useFormRules();
const title = computed(() => {
@@ -157,7 +157,7 @@ watch(visible, () => {
<template>
<NDrawer v-model:show="visible" :title="title" display-directive="show" :width="800" class="max-w-90%">
<NDrawerContent :title="title" :native-scrollbar="false" closable>
<NForm ref="formRef" :model="model" :rules="rules">
<NForm :model="model" :rules="rules">
<NDivider>基本信息</NDivider>
<NFormItem label="配置名称" path="configKey">
<NInput v-model:value="model.configKey" placeholder="请输入配置名称" />
@@ -15,7 +15,7 @@ interface Emits {
const emit = defineEmits<Emits>();
const { formRef, validate, restoreValidation } = useNaiveForm();
const { validate, restoreValidation } = useNaiveForm();
const isDefaltOptions = ref<SelectOption[]>([
{
@@ -52,7 +52,7 @@ async function search() {
<NCard :bordered="false" size="small" class="card-wrapper">
<NCollapse>
<NCollapseItem :title="$t('common.search')" name="user-search">
<NForm ref="formRef" :model="model" label-placement="left" :label-width="80">
<NForm :model="model" label-placement="left" :label-width="80">
<NGrid responsive="screen" item-responsive>
<NFormItemGi span="24 s:12 m:6" label="配置名称" path="configKey" class="pr-24px">
<NInput v-model:value="model.configKey" placeholder="请输入配置名称" />
+2 -2
View File
@@ -14,7 +14,7 @@ interface Emits {
const emit = defineEmits<Emits>();
const { formRef, validate, restoreValidation } = useNaiveForm();
const { validate, restoreValidation } = useNaiveForm();
const dateRangeCreateTime = ref<[string, string] | null>(null);
@@ -53,7 +53,7 @@ async function search() {
<NCard :bordered="false" size="small" class="card-wrapper">
<NCollapse>
<NCollapseItem :title="$t('common.search')" name="user-search">
<NForm ref="formRef" :model="model" label-placement="left" :label-width="100">
<NForm :model="model" label-placement="left" :label-width="100">
<NGrid responsive="screen" item-responsive>
<NFormItemGi span="24 s:12 m:6" label="文件名" path="fileName" class="pr-24px">
<NInput v-model:value="model.fileName" placeholder="请输入文件名" />
@@ -31,7 +31,7 @@ const visible = defineModel<boolean>('visible', {
default: false
});
const { formRef, validate, restoreValidation } = useNaiveForm();
const { validate, restoreValidation } = useNaiveForm();
const { createRequiredRule } = useFormRules();
const { loading: deptLoading, startLoading: startDeptLoading, endLoading: endDeptLoading } = useLoading();
const title = computed(() => {
@@ -124,7 +124,7 @@ watch(visible, () => {
<template>
<NDrawer v-model:show="visible" :title="title" display-directive="show" :width="800" class="max-w-90%">
<NDrawerContent :title="title" :native-scrollbar="false" closable>
<NForm ref="formRef" :model="model" :rules="rules">
<NForm :model="model" :rules="rules">
<NFormItem label="归属部门" path="deptId">
<NTreeSelect
v-model:value="model.deptId"
@@ -16,7 +16,7 @@ interface Emits {
const emit = defineEmits<Emits>();
const { formRef, validate, restoreValidation } = useNaiveForm();
const { validate, restoreValidation } = useNaiveForm();
const model = defineModel<Api.System.PostSearchParams>('model', { required: true });
@@ -44,7 +44,7 @@ async function search() {
<NCard :bordered="false" size="small" class="card-wrapper">
<NCollapse>
<NCollapseItem :title="$t('common.search')" name="user-search">
<NForm ref="formRef" :model="model" label-placement="left" :label-width="80">
<NForm :model="model" label-placement="left" :label-width="80">
<NGrid responsive="screen" item-responsive>
<NFormItemGi span="24 s:12 m:6" label="岗位编码" path="postCode" class="pr-24px">
<NInput v-model:value="model.postCode" placeholder="请输入岗位编码" />
@@ -34,7 +34,7 @@ const deptOptions = ref<Api.System.Dept[]>([]);
const { loading: deptLoading, startLoading: startDeptLoading, endLoading: endDeptLoading } = useLoading();
const { formRef, validate, restoreValidation } = useNaiveForm();
const { validate, restoreValidation } = useNaiveForm();
const { createRequiredRule } = useFormRules();
const title = computed(() => '分配数据权限');
@@ -113,7 +113,7 @@ watch(visible, () => {
<template>
<NDrawer v-model:show="visible" :title="title" display-directive="show" :width="800" class="max-w-90%">
<NDrawerContent :title="title" :native-scrollbar="false" closable>
<NForm ref="formRef" :model="model" :rules="rules">
<NForm :model="model" :rules="rules">
<NFormItem label="角色名称" path="roleName">
<NInput v-model:value="model.roleName" disabled placeholder="请输入角色名称" />
</NFormItem>
@@ -40,7 +40,7 @@ const menuOptions = ref<Api.System.MenuList>([]);
const { loading: menuLoading, startLoading: startMenuLoading, endLoading: stopMenuLoading } = useLoading();
const { formRef, validate, restoreValidation } = useNaiveForm();
const { validate, restoreValidation } = useNaiveForm();
const { createRequiredRule } = useFormRules();
const title = computed(() => {
@@ -149,7 +149,7 @@ watch(visible, () => {
<template>
<NDrawer v-model:show="visible" :title="title" display-directive="show" :width="800" class="max-w-90%">
<NDrawerContent :title="title" :native-scrollbar="false" closable>
<NForm ref="formRef" :model="model" :rules="rules">
<NForm :model="model" :rules="rules">
<NFormItem label="角色名称" path="roleName">
<NInput v-model:value="model.roleName" placeholder="请输入角色名称" />
</NFormItem>
@@ -15,7 +15,7 @@ interface Emits {
const emit = defineEmits<Emits>();
const { formRef, validate, restoreValidation } = useNaiveForm();
const { validate, restoreValidation } = useNaiveForm();
const dateRangeCreateTime = ref<[string, string] | null>(null);
@@ -56,7 +56,7 @@ async function search() {
<NCard :bordered="false" size="small" class="card-wrapper">
<NCollapse>
<NCollapseItem :title="$t('common.search')" name="user-search">
<NForm ref="formRef" :model="model" label-placement="left" :label-width="80">
<NForm :model="model" label-placement="left" :label-width="80">
<NGrid responsive="screen" item-responsive>
<NFormItemGi span="24 s:12 m:6" label="角色名称" path="roleName" class="pr-24px">
<NInput v-model:value="model.roleName" placeholder="请输入角色名称" />
@@ -37,7 +37,7 @@ const visible = defineModel<boolean>('visible', {
default: false
});
const { formRef, validate, restoreValidation } = useNaiveForm();
const { validate, restoreValidation } = useNaiveForm();
const { createRequiredRule } = useFormRules();
const title = computed(() => {
@@ -135,7 +135,7 @@ watch(visible, () => {
<template>
<NDrawer v-model:show="visible" :title="title" display-directive="show" :width="800" class="max-w-90%">
<NDrawerContent :title="title" :native-scrollbar="false" closable>
<NForm ref="formRef" :model="model" :rules="rules">
<NForm :model="model" :rules="rules">
<NFormItem :label="$t('page.system.tenantPackage.packageName')" path="packageName">
<NInput
v-model:value="model.packageName"
@@ -15,7 +15,7 @@ interface Emits {
const emit = defineEmits<Emits>();
const { formRef, validate, restoreValidation } = useNaiveForm();
const { validate, restoreValidation } = useNaiveForm();
const { options: sysNormalDisableOptions } = useDict('sys_normal_disable', false);
@@ -43,7 +43,7 @@ async function search() {
<NCard :bordered="false" size="small" class="card-wrapper">
<NCollapse>
<NCollapseItem :title="$t('common.search')" name="user-search">
<NForm ref="formRef" :model="model" label-placement="left" :label-width="80">
<NForm :model="model" label-placement="left" :label-width="80">
<NGrid responsive="screen" item-responsive>
<NFormItemGi
span="24 s:12 m:8"
@@ -30,7 +30,7 @@ const visible = defineModel<boolean>('visible', {
default: false
});
const { formRef, validate, restoreValidation } = useNaiveForm();
const { validate, restoreValidation } = useNaiveForm();
const { createRequiredRule, patternRules } = useFormRules();
const { loading: packageLoading, startLoading: startPackageLoading, endLoading: endPackageLoading } = useLoading();
const title = computed(() => {
@@ -203,7 +203,7 @@ watch(visible, () => {
<template>
<NDrawer v-model:show="visible" :title="title" display-directive="show" :width="800" class="max-w-90%">
<NDrawerContent :title="title" :native-scrollbar="false" closable>
<NForm ref="formRef" :model="model" :rules="rules">
<NForm :model="model" :rules="rules">
<NDivider>基本信息</NDivider>
<NFormItem label="企业名称" path="companyName">
<NInput v-model:value="model.companyName" placeholder="请输入企业名称" />
@@ -14,7 +14,7 @@ interface Emits {
const emit = defineEmits<Emits>();
const { formRef, validate, restoreValidation } = useNaiveForm();
const { validate, restoreValidation } = useNaiveForm();
const model = defineModel<Api.System.TenantSearchParams>('model', { required: true });
@@ -40,7 +40,7 @@ async function search() {
<NCard :bordered="false" size="small" class="card-wrapper">
<NCollapse>
<NCollapseItem :title="$t('common.search')" name="user-search">
<NForm ref="formRef" :model="model" label-placement="left" :label-width="80">
<NForm :model="model" label-placement="left" :label-width="80">
<NGrid responsive="screen" item-responsive>
<NFormItemGi span="24 s:12 m:6" label="租户编号" path="tenantId" class="pr-24px">
<NInput v-model:value="model.tenantId as string" placeholder="请输入租户编号" />
@@ -35,7 +35,7 @@ const visible = defineModel<boolean>('visible', {
const { loading, startLoading, endLoading } = useLoading();
const { loading: deptLoading, startLoading: startDeptLoading, endLoading: endDeptLoading } = useLoading();
const { formRef, validate, restoreValidation } = useNaiveForm();
const { validate, restoreValidation } = useNaiveForm();
const { createRequiredRule, patternRules } = useFormRules();
const title = computed(() => {
@@ -173,7 +173,7 @@ watch(visible, () => {
<NDrawer v-model:show="visible" display-directive="show" :width="800" class="max-w-90%">
<NDrawerContent :title="title" :native-scrollbar="false" closable>
<NSpin :show="loading">
<NForm ref="formRef" :model="model" :rules="rules">
<NForm :model="model" :rules="rules">
<NFormItem :label="$t('page.system.user.nickName')" path="nickName">
<NInput v-model:value="model.nickName" :placeholder="$t('page.system.user.form.nickName.required')" />
</NFormItem>
@@ -25,7 +25,7 @@ const visible = defineModel<boolean>('visible', {
default: false
});
const { formRef, validate, restoreValidation } = useNaiveForm();
const { validate, restoreValidation } = useNaiveForm();
const { patternRules } = useFormRules();
type Model = Api.System.UserOperateParams & { deptName: string };
@@ -82,7 +82,7 @@ watch(visible, () => {
<template>
<NDrawer v-model:show="visible" display-directive="show" :width="800" class="max-w-90%">
<NDrawerContent title="重置密码" :native-scrollbar="false" closable>
<NForm ref="formRef" :model="model" :rules="rules">
<NForm :model="model" :rules="rules">
<NFormItem :label="$t('page.system.user.nickName')" path="nickName">
<NInput v-model:value="model.nickName" disabled />
</NFormItem>
@@ -16,12 +16,10 @@ interface Emits {
const emit = defineEmits<Emits>();
const { formRef, validate, restoreValidation } = useNaiveForm();
const { validate, restoreValidation } = useNaiveForm();
const dateRangeCreateTime = ref<[string, string] | null>(null);
const datePickerRef = ref<InstanceType<typeof NDatePicker>>();
const model = defineModel<Api.System.UserSearchParams>('model', { required: true });
const defaultModel = jsonClone(toRaw(model.value));
@@ -57,7 +55,7 @@ async function search() {
<NCard :bordered="false" size="small" class="table-search card-wrapper">
<NCollapse>
<NCollapseItem :title="$t('common.search')" name="user-search">
<NForm ref="formRef" :model="model" label-placement="left" :label-width="80">
<NForm :model="model" label-placement="left" :label-width="80">
<NGrid responsive="screen" item-responsive>
<NFormItemGi span="24 s:12 m:6" :label="$t('page.system.user.userName')" path="userName" class="pr-24px">
<NInput v-model:value="model.userName" :placeholder="$t('page.system.user.form.userName.required')" />
@@ -91,7 +89,6 @@ async function search() {
class="pr-24px"
>
<NDatePicker
ref="datePickerRef"
v-model:formatted-value="dateRangeCreateTime"
type="datetimerange"
value-format="yyyy-MM-dd HH:mm:ss"
@@ -20,7 +20,7 @@ interface Emits {
const emit = defineEmits<Emits>();
const { formRef, validate, restoreValidation } = useNaiveForm();
const { validate, restoreValidation } = useNaiveForm();
const model = defineModel<Api.Tool.GenTableDbSearchParams>('model', { required: true });
@@ -42,7 +42,7 @@ async function search() {
</script>
<template>
<NForm ref="formRef" :model="model" label-placement="left" :label-width="80">
<NForm :model="model" label-placement="left" :label-width="80">
<NGrid responsive="screen" item-responsive>
<NFormItemGi span="24 s:12" label="数据源" label-width="auto" path="dataName" class="pr-24px">
<NSelect v-model:value="model.dataName" :options="options" placeholder="请选择数据源" />
@@ -20,7 +20,7 @@ interface Emits {
const emit = defineEmits<Emits>();
const { formRef, validate, restoreValidation } = useNaiveForm();
const { validate, restoreValidation } = useNaiveForm();
const model = defineModel<Api.Tool.GenTableSearchParams>('model', { required: true });
@@ -57,7 +57,7 @@ async function search() {
<NCard :bordered="false" size="small" class="card-wrapper">
<NCollapse>
<NCollapseItem :title="$t('common.search')" name="user-search">
<NForm ref="formRef" :model="model" label-placement="left" :label-width="80">
<NForm :model="model" label-placement="left" :label-width="80">
<NGrid responsive="screen" item-responsive>
<NFormItemGi span="24 s:12 m:6" label="数据源" label-width="auto" path="dataName" class="pr-24px">
<NSelect v-model:value="model.dataName" :options="options" placeholder="请选择数据源" />