Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ab0f59a
commit 00d947e
Showing
11 changed files
with
468 additions
and
162 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import { config } from '@/config/axios/config' | ||
import { MockMethod } from 'vite-plugin-mock' | ||
|
||
const { result_code } = config | ||
|
||
const timeout = 1000 | ||
|
||
const dictObj: Recordable = { | ||
importance: [ | ||
{ | ||
value: 0, | ||
label: 'tableDemo.commonly' | ||
}, | ||
{ | ||
value: 1, | ||
label: 'tableDemo.good' | ||
}, | ||
{ | ||
value: 2, | ||
label: 'tableDemo.important' | ||
} | ||
] | ||
} | ||
|
||
export default [ | ||
// 字典接口 | ||
{ | ||
url: '/dict/list', | ||
method: 'get', | ||
timeout, | ||
response: () => { | ||
return { | ||
code: result_code, | ||
data: dictObj | ||
} | ||
} | ||
}, | ||
// 获取某个字典 | ||
{ | ||
url: '/dict/one', | ||
method: 'get', | ||
timeout, | ||
response: () => { | ||
return { | ||
code: result_code, | ||
data: [ | ||
{ | ||
label: 'test1', | ||
value: 0 | ||
}, | ||
{ | ||
label: 'test2', | ||
value: 1 | ||
}, | ||
{ | ||
label: 'test3', | ||
value: 2 | ||
} | ||
] | ||
} | ||
} | ||
} | ||
] as MockMethod[] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { useAxios } from '@/hooks/web/useAxios' | ||
|
||
const request = useAxios() | ||
|
||
// 获取所有字典 | ||
export const getDictApi = () => { | ||
return request.get({ url: '/dict/list' }) | ||
} | ||
|
||
// 模拟获取某个字典 | ||
export const getDictOneApi = () => { | ||
return request.get({ url: '/dict/one' }) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,217 @@ | ||
import { reactive } from 'vue' | ||
import { eachTree, treeMap, filter } from '@/utils/tree' | ||
import { findIndex } from '@/utils' | ||
import { useDictStoreWithOut } from '@/store/modules/dict' | ||
import { useI18n } from '@/hooks/web/useI18n' | ||
import type { AxiosPromise } from 'axios' | ||
|
||
export type CrudSchema = Omit<TableColumn, 'children'> & { | ||
search?: CrudSearchParams | ||
table?: CrudTableParams | ||
form?: CrudFormParams | ||
detail?: CrudDescriptionsParams | ||
children?: CrudSchema[] | ||
} | ||
|
||
type CrudSearchParams = { | ||
// 是否显示在查询项 | ||
show?: boolean | ||
// 字典名称,会去取全局的字典 | ||
dictName?: string | ||
// 接口路径 | ||
dictUrl?: string | ||
} & Omit<FormSchema, 'field'> | ||
|
||
type CrudTableParams = { | ||
// 是否显示表头 | ||
show?: boolean | ||
} & Omit<FormSchema, 'field'> | ||
|
||
type CrudFormParams = { | ||
// 是否显示表单项 | ||
show?: boolean | ||
} & Omit<FormSchema, 'field'> | ||
|
||
type CrudDescriptionsParams = { | ||
// 是否显示表单项 | ||
show?: boolean | ||
} & Omit<DescriptionsSchema, 'field'> | ||
|
||
const dictStore = useDictStoreWithOut() | ||
|
||
const { t } = useI18n() | ||
|
||
interface AllSchemas { | ||
searchSchema: FormSchema[] | ||
tableColumns: TableColumn[] | ||
formSchema: FormSchema[] | ||
detailSchema: DescriptionsSchema[] | ||
} | ||
|
||
// 过滤所有结构 | ||
export const useCrudSchemas = ( | ||
crudSchema: CrudSchema[] | ||
): { | ||
allSchemas: AllSchemas | ||
} => { | ||
// 所有结构数据 | ||
const allSchemas = reactive<AllSchemas>({ | ||
searchSchema: [], | ||
tableColumns: [], | ||
formSchema: [], | ||
detailSchema: [] | ||
}) | ||
|
||
const searchSchema = filterSearchSchema(crudSchema, allSchemas) | ||
allSchemas.searchSchema = searchSchema || [] | ||
|
||
const tableColumns = filterTableSchema(crudSchema) | ||
allSchemas.tableColumns = tableColumns || [] | ||
|
||
const formSchema = filterFormSchema(crudSchema) | ||
allSchemas.formSchema = formSchema | ||
|
||
const detailSchema = filterDescriptionsSchema(crudSchema) | ||
allSchemas.detailSchema = detailSchema | ||
|
||
return { | ||
allSchemas | ||
} | ||
} | ||
|
||
// 过滤 Search 结构 | ||
const filterSearchSchema = (crudSchema: CrudSchema[], allSchemas: AllSchemas): FormSchema[] => { | ||
const searchSchema: FormSchema[] = [] | ||
|
||
// 获取字典列表队列 | ||
const searchRequestTask: Array<() => Promise<void>> = [] | ||
|
||
eachTree(crudSchema, (schemaItem: CrudSchema) => { | ||
// 判断是否显示 | ||
if (schemaItem?.search?.show) { | ||
const searchSchemaItem = { | ||
// 默认为 input | ||
component: schemaItem.search.component || 'Input', | ||
componentProps: {}, | ||
...schemaItem.search, | ||
field: schemaItem.field, | ||
label: schemaItem.label | ||
} | ||
|
||
if (searchSchemaItem.dictName) { | ||
// 如果有 dictName 则证明是从字典中获取数据 | ||
const dictArr = dictStore.getDictObj[searchSchemaItem.dictName] | ||
searchSchemaItem.componentProps!.options = filterOptions(dictArr) | ||
} else if (searchSchemaItem.api) { | ||
searchRequestTask.push(async () => { | ||
const res = await (searchSchemaItem.api as () => AxiosPromise)() | ||
if (res) { | ||
const index = findIndex(allSchemas.searchSchema, (v: FormSchema) => { | ||
return v.field === searchSchemaItem.field | ||
}) | ||
if (index !== -1) { | ||
allSchemas.searchSchema[index]!.componentProps!.options = filterOptions( | ||
res.data, | ||
searchSchemaItem.componentProps.optionsAlias?.labelField | ||
) | ||
} | ||
} | ||
}) | ||
} | ||
|
||
// 删除不必要的字段 | ||
delete searchSchemaItem.show | ||
delete searchSchemaItem.dictName | ||
|
||
searchSchema.push(searchSchemaItem) | ||
} | ||
}) | ||
|
||
for (const task of searchRequestTask) { | ||
task() | ||
} | ||
|
||
return searchSchema | ||
} | ||
|
||
// 过滤 table 结构 | ||
const filterTableSchema = (crudSchema: CrudSchema[]): TableColumn[] => { | ||
const tableColumns = treeMap<CrudSchema>(crudSchema, { | ||
conversion: (schema: CrudSchema) => { | ||
if (schema?.table?.show !== false) { | ||
return { | ||
...schema.table, | ||
...schema | ||
} | ||
} | ||
} | ||
}) | ||
|
||
// 第一次过滤会有 undefined 所以需要二次过滤 | ||
return filter<TableColumn>(tableColumns as TableColumn[], (data) => { | ||
if (data.children === void 0) { | ||
delete data.children | ||
} | ||
return !!data.field | ||
}) | ||
} | ||
|
||
// 过滤 form 结构 | ||
const filterFormSchema = (crudSchema: CrudSchema[]): FormSchema[] => { | ||
const formSchema: FormSchema[] = [] | ||
|
||
eachTree(crudSchema, (schemaItem: CrudSchema) => { | ||
// 判断是否显示 | ||
if (schemaItem?.form?.show !== false) { | ||
const formSchemaItem = { | ||
// 默认为 input | ||
component: (schemaItem.form && schemaItem.form.component) || 'Input', | ||
...schemaItem.form, | ||
field: schemaItem.field, | ||
label: schemaItem.label | ||
} | ||
|
||
// 删除不必要的字段 | ||
delete formSchemaItem.show | ||
|
||
formSchema.push(formSchemaItem) | ||
} | ||
}) | ||
|
||
return formSchema | ||
} | ||
|
||
// 过滤 descriptions 结构 | ||
const filterDescriptionsSchema = (crudSchema: CrudSchema[]): DescriptionsSchema[] => { | ||
const descriptionsSchema: FormSchema[] = [] | ||
|
||
eachTree(crudSchema, (schemaItem: CrudSchema) => { | ||
// 判断是否显示 | ||
if (schemaItem?.detail?.show !== false) { | ||
const descriptionsSchemaItem = { | ||
...schemaItem.detail, | ||
field: schemaItem.field, | ||
label: schemaItem.label | ||
} | ||
|
||
// 删除不必要的字段 | ||
delete descriptionsSchemaItem.show | ||
|
||
descriptionsSchema.push(descriptionsSchemaItem) | ||
} | ||
}) | ||
|
||
return descriptionsSchema | ||
} | ||
|
||
// 给options添加国际化 | ||
const filterOptions = (options: Recordable, labelField?: string) => { | ||
return options.map((v: Recordable) => { | ||
if (labelField) { | ||
v['labelField'] = t(v.labelField) | ||
} else { | ||
v['label'] = t(v.label) | ||
} | ||
return v | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import { defineStore } from 'pinia' | ||
import { store } from '../index' | ||
|
||
export interface DictState { | ||
isSetDict: boolean | ||
dictObj: Recordable | ||
} | ||
|
||
export const useDictStore = defineStore({ | ||
id: 'dict', | ||
state: (): DictState => ({ | ||
isSetDict: false, | ||
dictObj: {} | ||
}), | ||
persist: { | ||
enabled: true | ||
}, | ||
getters: { | ||
getDictObj(): Recordable { | ||
return this.dictObj | ||
}, | ||
getIsSetDict(): boolean { | ||
return this.isSetDict | ||
} | ||
}, | ||
actions: { | ||
setDictObj(dictObj: Recordable) { | ||
this.dictObj = dictObj | ||
}, | ||
setIsSetDict(isSetDict: boolean) { | ||
this.isSetDict = isSetDict | ||
} | ||
} | ||
}) | ||
|
||
export const useDictStoreWithOut = () => { | ||
return useDictStore(store) | ||
} |
Oops, something went wrong.