This commit is contained in:
ktianc 2022-10-07 23:33:30 +08:00
parent deaa9de232
commit 35076338be
13 changed files with 213 additions and 40 deletions

View File

@ -20,6 +20,10 @@ export const getDictTypeApi = (dataId: number): Promise<IResponse> => {
return request.get({ url: `/vadmin/system/dict/types/${dataId}/` })
}
export const getDictTypeOptionsApi = (): Promise<IResponse> => {
return request.get({ url: `/vadmin/system/dict/types/options/` })
}
export const getDictDetailsListApi = (params: any): Promise<IResponse> => {
return request.get({ url: '/vadmin/system/dict/details/', params })
}

View File

@ -104,11 +104,11 @@ const setVisible = () => {
>
<template #action>
<div v-if="layout === 'inline'">
<ElButton v-if="showSearch" type="primary" @click="search">
<ElButton v-if="showSearch" type="primary" size="small" @click="search">
<Icon icon="ep:search" class="mr-5px" />
{{ t('common.query') }}
</ElButton>
<ElButton v-if="showReset" @click="reset">
<ElButton v-if="showReset" size="small" @click="reset">
<Icon icon="ep:refresh-right" class="mr-5px" />
{{ t('common.reset') }}
</ElButton>

View File

@ -136,10 +136,9 @@ export const useTable = <T = any>(config?: UseTableConfig<T>) => {
},
// 与Search组件结合
setSearchParams: (data: Recordable) => {
tableObject.page = 1
tableObject.params = Object.assign(tableObject.params, {
limit: tableObject.limit,
pageIndex: tableObject.page,
page: tableObject.page,
...data
})
methods.getList()

View File

@ -1,7 +1,7 @@
import { createRouter, createWebHistory } from 'vue-router'
import type { RouteRecordRaw } from 'vue-router'
import type { App } from 'vue'
import { Layout, getParentLayout } from '@/utils/routerHelper'
import { Layout } from '@/utils/routerHelper'
import { useI18n } from '@/hooks/web/useI18n'
const { t } = useI18n()

View File

@ -0,0 +1,50 @@
<script setup lang="ts">
import { Form } from '@/components/Form'
import { useForm } from '@/hooks/web/useForm'
import { PropType, reactive, watch } from 'vue'
import { useValidator } from '@/hooks/web/useValidator'
import { schema } from './detail.data'
const { required } = useValidator()
const props = defineProps({
currentRow: {
type: Object as PropType<Nullable<any>>,
default: () => null
}
})
const rules = reactive({
label: [required()],
value: [required()],
order: [required()],
is_default: [required()],
disabled: [required()]
})
const { register, methods, elFormRef } = useForm({
schema: schema
})
watch(
() => props.currentRow,
(currentRow) => {
if (!currentRow) return
const { setValues } = methods
setValues(currentRow)
},
{
deep: true,
immediate: true
}
)
defineExpose({
elFormRef,
getFormData: methods.getFormData
})
</script>
<template>
<Form :rules="rules" @register="register" />
</template>

View File

@ -1,4 +1,6 @@
import { reactive } from 'vue'
import { ElTag } from 'element-plus'
import { h, reactive } from 'vue'
import { getDictTypeOptionsApi } from '@/api/vadmin/system/dict'
export const columns = reactive<TableColumn[]>([
{
@ -19,7 +21,16 @@ export const columns = reactive<TableColumn[]>([
},
{
field: 'disabled',
label: '是否禁用'
label: '是否禁用',
formatter: (_: Recordable, __: TableColumn, cellValue: number) => {
return h(
ElTag,
{
type: cellValue ? 'danger' : ''
},
() => (cellValue ? '禁用' : '启用')
)
}
},
{
field: 'remark',
@ -38,21 +49,58 @@ export const columns = reactive<TableColumn[]>([
export const schema = reactive<FormSchema[]>([
{
field: 'dict_name',
label: '字典名称',
field: 'label',
label: '字典标签',
colProps: {
span: 24
},
component: 'Input'
},
{
field: 'dict_type',
label: '字典类型',
field: 'value',
label: '字典键值',
colProps: {
span: 24
},
component: 'Input'
},
{
field: 'order',
label: '排序',
colProps: {
span: 24
},
component: 'InputNumber',
componentProps: {
style: {
width: '50%'
}
}
},
{
field: 'is_default',
label: '是否默认',
colProps: {
span: 24
},
component: 'Radio',
componentProps: {
style: {
width: '100%'
},
options: [
{
label: '是',
value: true
},
{
label: '否',
value: false
}
]
},
value: false
},
{
field: 'disabled',
label: '是否禁用',
@ -86,3 +134,30 @@ export const schema = reactive<FormSchema[]>([
component: 'Input'
}
])
const res = await getDictTypeOptionsApi()
const data = res.data
export const searchSchema = reactive<FormSchema[]>([
{
field: 'label',
label: '字典标签',
component: 'Input',
componentProps: {
clearable: false
}
},
{
field: 'dict_type_id',
label: '字典类型',
component: 'Select',
componentProps: {
options: data,
optionsAlias: {
labelField: 'dict_name',
valueField: 'id'
},
clearable: false
}
}
])

View File

@ -1,4 +1,5 @@
import { reactive } from 'vue'
import { ElTag } from 'element-plus'
import { h, reactive } from 'vue'
export const columns = reactive<TableColumn[]>([
{
@ -15,7 +16,16 @@ export const columns = reactive<TableColumn[]>([
},
{
field: 'disabled',
label: '是否禁用'
label: '是否禁用',
formatter: (_: Recordable, __: TableColumn, cellValue: number) => {
return h(
ElTag,
{
type: cellValue ? 'danger' : ''
},
() => (cellValue ? '禁用' : '启用')
)
}
},
{
field: 'remark',

View File

@ -9,15 +9,21 @@ import {
getDictDetailsApi
} from '@/api/vadmin/system/dict'
import { useTable } from '@/hooks/web/useTable'
import { columns } from './components/detail.data'
import { columns, searchSchema } from './components/detail.data'
import { ref, unref } from 'vue'
import Write from './components/Write.vue'
import Write from './components/DetailWrite.vue'
import { Dialog } from '@/components/Dialog'
import { ElButton, ElMessage } from 'element-plus'
import { useI18n } from '@/hooks/web/useI18n'
import { useRouter } from 'vue-router'
import { Search } from '@/components/Search'
const { currentRoute } = useRouter()
const { t } = useI18n()
let dictType = currentRoute.value.query.dictType
const { register, tableObject, methods } = useTable({
getListApi: getDictDetailsListApi,
delListApi: delDictDetailsListApi,
@ -29,6 +35,7 @@ const { register, tableObject, methods } = useTable({
columns
}
})
tableObject.params = { dict_type_id: dictType }
const dialogVisible = ref(false)
const dialogTitle = ref('')
@ -74,6 +81,7 @@ const save = async () => {
loading.value = false
return ElMessage.error('未获取到数据')
}
data.dict_type_id = dictType
const res = ref({})
if (actionType.value === 'add') {
res.value = await addDictDetailsListApi(data)
@ -89,13 +97,15 @@ const save = async () => {
})
}
const { getList } = methods
const { getList, setSearchParams } = methods
getList()
</script>
<template>
<ContentWrap>
<Search :schema="searchSchema" @search="setSearchParams" @reset="setSearchParams" />
<div class="mb-10px">
<ElButton type="primary" @click="AddAction">{{ t('exampleDemo.add') }}</ElButton>
</div>
@ -121,7 +131,7 @@ getList()
</template>
</Table>
<Dialog v-model="dialogVisible" :title="dialogTitle" width="700px">
<Dialog v-model="dialogVisible" :title="dialogTitle" width="600px">
<Write ref="writeRef" :current-row="tableObject.currentRow" />
<template #footer>

View File

@ -15,6 +15,9 @@ import Write from './components/Write.vue'
import { Dialog } from '@/components/Dialog'
import { ElButton, ElMessage } from 'element-plus'
import { useI18n } from '@/hooks/web/useI18n'
import { useRouter } from 'vue-router'
const { push } = useRouter()
const { t } = useI18n()
@ -62,6 +65,11 @@ const delData = async (row: any) => {
})
}
//
const toDetail = (row: any) => {
push(`/system/dict/detail?dictType=${row.id}`)
}
const writeRef = ref<ComponentRef<typeof Write>>()
const save = async () => {
@ -112,13 +120,19 @@ getList()
@register="register"
>
<template #action="{ row }">
<ElButton type="primary" text size="small" @click="updateAction(row)">
<ElButton type="primary" link size="small" @click="updateAction(row)">
{{ t('exampleDemo.edit') }}
</ElButton>
<ElButton type="danger" text size="small" @click="delData(row)">
<ElButton type="danger" link size="small" @click="delData(row)">
{{ t('exampleDemo.del') }}
</ElButton>
</template>
<template #dict_type="{ row }">
<ElButton type="primary" link @click="toDetail(row)">
{{ row.dict_type }}
</ElButton>
</template>
</Table>
<Dialog v-model="dialogVisible" :title="dialogTitle" width="700px">

View File

@ -10,6 +10,8 @@
# sqlalchemy 关联查询https://www.jianshu.com/p/dfad7c08c57a
# sqlalchemy 关联查询详细https://blog.csdn.net/u012324798/article/details/103940527
from typing import List
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from . import models, schemas
from core.crud import DalBase
@ -35,6 +37,12 @@ class DictTypeDal(DalBase):
data[dict_type] = [schemas.DictDetailsSimpleOut.from_orm(i).dict() for i in dict_data.details]
return data
async def get_select_datas(self):
"""获取选择数据,全部数据"""
sql = select(self.model)
queryset = await self.db.execute(sql)
return [schemas.DictTypeSelectOut.from_orm(i).dict() for i in queryset.scalars().all()]
class DictDetailsDal(DalBase):

View File

@ -1 +1 @@
from .dict import DictType, DictDetails, DictTypeSimpleOut, DictDetailsSimpleOut
from .dict import DictType, DictDetails, DictTypeSimpleOut, DictDetailsSimpleOut, DictTypeSelectOut

View File

@ -20,17 +20,6 @@ class DictType(BaseModel):
disabled: Optional[bool] = False
remark: Optional[str] = None
class Config:
# 示例参数值会默认显示在接口文档中example为固定写法
schema_extra = {
"example": {
"dict_name": "用户性别",
"dict_type": "sys_user_sex",
"disabled": False,
"remark": "性别选择"
}
}
class DictTypeSimpleOut(DictType):
id: int
@ -41,14 +30,23 @@ class DictTypeSimpleOut(DictType):
orm_mode = True
class DictTypeSelectOut(BaseModel):
id: int
dict_name: str
disabled: bool
class Config:
orm_mode = True
class DictDetails(BaseModel):
label: str
value: str
disabled: Optional[bool] = False
is_default: Optional[bool] = False
remark: Optional[str] = None
order: Optional[str] = None
dict_data: int
order: Optional[int] = None
dict_type_id: int
class DictDetailsSimpleOut(DictDetails):

View File

@ -44,6 +44,12 @@ async def post_dicts_details(auth: Auth = Depends(login_auth),
return SuccessResponse(datas)
@app.get("/dict/types/options/", summary="获取字典类型选择项")
async def get_dicts_options(auth: Auth = Depends(login_auth)):
datas = await crud.DictTypeDal(auth.db).get_select_datas()
return SuccessResponse(datas)
@app.put("/dict/types/{data_id}/", summary="更新字典类型")
async def put_dict_types(data_id: int, data: schemas.DictType, auth: Auth = Depends(login_auth)):
return SuccessResponse(await crud.DictTypeDal(auth.db).put_data(data_id, data))
@ -65,14 +71,13 @@ async def create_dict_details(data: schemas.DictDetails, auth: Auth = Depends(lo
@app.get("/dict/details/", summary="获取单个字典类型下的字典元素列表,分页")
async def get_dict_details(params: Params = Depends(paging), auth: Auth = Depends(login_auth),
dict_type_id: Optional[str] = Query(..., title="查询字典类型", description="查询字典类型"),
dict_label: Optional[str] = Query(None, title="查询字典标签", description="查询字典标签")):
type_obj = await crud.DictTypeDal(auth.db).get_data(dict_type_id=dict_type_id, return_none=True)
if not type_obj:
return ErrorResponse(msg="未找到字典类型!")
dict_type_id: Optional[int] = Query(None, title="查询字典类型", description="查询字典类型"),
label: Optional[str] = Query(None, title="查询字典标签", description="查询字典标签")):
if not dict_type_id:
return ErrorResponse(msg="未获取到字典类型!")
datas = await crud.DictDetailsDal(auth.db).\
get_datas(params.page, params.limit, dict_label=dict_label, dict_type_id=type_obj.id)
count = await crud.DictDetailsDal(auth.db).get_count(dict_label=dict_label, dict_type_id=type_obj.id)
get_datas(params.page, params.limit, label=label, dict_type_id=dict_type_id)
count = await crud.DictDetailsDal(auth.db).get_count(label=label, dict_type_id=dict_type_id)
return SuccessResponse(datas, count=count)