ljw 2026-03-04 14:36:17 +08:00
commit 4bddd5b24f
11 changed files with 379 additions and 540 deletions

View File

@ -225,6 +225,7 @@ const displayData = computed(() => {
<style lang="stylus" scoped>
.drop-table {
width 100%;
display inline-block
}
.clear-btn {

View File

@ -55,7 +55,7 @@ interface TableActionType<T> {
tooltip: string | ((data: ColumnScopeType<T>) => string)
loading?: boolean
show?: (data: ColumnScopeType<T>) => boolean
action: (data: ColumnScopeType<T>) => Promise<boolean> | void
action?: (data: ColumnScopeType<T>) => Promise<boolean> | void
confirm?: {
title: string | ((data: ColumnScopeType<T>) => string)
width?: string
@ -81,6 +81,7 @@ interface ToolType {
type?: 'text' | 'default' | 'primary' | 'success' | 'warning' | 'info' | 'danger'
label?: string
action: () => void
disabled: boolean
}
interface ToolBarType {
@ -94,6 +95,7 @@ interface TablePropsType<T extends DefaultRow, F extends object> extends Omit<Ta
*
*/
actionColumn: ActionColumnType<T>
rowClickHandle?: (row: T) => void
}
interface FormPropsType<P, T extends DefaultRow> {
@ -103,6 +105,7 @@ interface FormPropsType<P, T extends DefaultRow> {
*/
paging: (param: P) => Promise<R<G.PageResult<T>>>
list?: (param: P) => Promise<R<T[]>>
resetForm?: (param?: P) => P | null | undefined
/**
*
* @param param
@ -289,9 +292,12 @@ function buildToolBar(toolBar: DeepPartial<ToolBarType> = {}) {
if (leftTool.type == null) {
leftTool.type = 'primary'
}
if (leftTool.disabled == null) leftTool.disabled = false
}
if (toolBar.rightTools == null) toolBar.rightTools = []
for (let rightTool of toolBar.rightTools) {
if (rightTool.disabled == null) rightTool.disabled = false
}
return toolBar
}
@ -342,7 +348,7 @@ const component = defineComponent(
return
}
}
expose({doSearch, tableData})
expose({doSearch, tableData, formData})
const showHighFormHandle = () => {
showHighForm.value = !showHighForm.value
formData.$reset()
@ -361,7 +367,7 @@ const component = defineComponent(
if (action.loading != null) {
action.loading = true
}
const result = action.action(data)
const result = action.action?.(data)
if (result instanceof Promise) {
result
.then(reload => {
@ -378,7 +384,9 @@ const component = defineComponent(
}
function doReset() {
formData.$reset()
const resetFormData = props.searchForm.resetForm?.()
if (resetFormData == null) formData.$reset()
else formData.$reset(resetFormData as any)
doSearch()
}
@ -567,6 +575,7 @@ const component = defineComponent(
{
props.toolBar.leftTools.map((tool, i) => (
<ElButton key={'tool-bar-left-' + i}
disabled={tool.disabled}
icon={Strings.isBlank(tool.icon) ? undefined : elIcons[tool.icon!]}
type={tool.type}
onClick={tool.action}>
@ -604,6 +613,7 @@ const component = defineComponent(
props.toolBar.rightTools.map((tool, i) => (
<ElButton key={'tool-bar-right-' + i}
icon={elIcons[tool.icon]}
disabled={tool.disabled}
onClick={tool.action}/>
))
}
@ -636,6 +646,9 @@ const component = defineComponent(
onSort-change={sortChangeHandler}
summary-method={props.table.summaryMethod}
show-summary={props.table.summaryMethod != null}
highlightCurrentRow={props.table.highlightCurrentRow}
currentRowKey={props.table.currentRowKey}
onRow-click={props.table.rowClickHandle}
>
{
slots.columns?.()
@ -669,9 +682,10 @@ const component = defineComponent(
},
)
export interface ATablePageInstance<T extends DefaultRow = DefaultRow> extends InstanceType<typeof component> {
export interface ATablePageInstance<P extends G.PageParam = any, T extends DefaultRow = DefaultRow> extends InstanceType<typeof component> {
doSearch: () => void
tableData: T[]
formData: ResetAble<P>
}
export default component

View File

@ -15,7 +15,7 @@
</ElFormItem>
<ElFormItem v-if="formData.expenseItemCategory === 'ChanPin'" label="产品" prop="goodsId">
<GoodsDropTable v-model="formData.goodsId"/>
<GoodsDropTable v-model="formData.goodsId" :placeholder="formData.goodsName"/>
</ElFormItem>
<ElFormItem v-else label="项目名称" prop="expenseItemName">
<ElInput v-model="formData.expenseItemName" placeholder="项目名称"/>

View File

@ -5,6 +5,7 @@ import { bizType } from '@/pages/gds/goods-category/constants.ts'
const props = defineProps<{
defaultBizType?: typeof bizType[number]['val']
placeholder?: string
}>()
const model = defineModel<string | undefined | null>()
@ -29,5 +30,6 @@ const dropTableLoader = (param: GoodsTypes.SearchGoodsParam) => {
<ADropTable v-model="model"
:columns="dropTableColumns"
:loader="dropTableLoader"
:placeholder="placeholder"
display-field="goodsName"/>
</template>

View File

@ -1,10 +1,7 @@
<template>
<APage>
<div class="dict-page">
<DictCategory @search-dict="searchDict"/>
<ElDivider direction="vertical"/>
<APage class="dict-page">
<DictCategory :current-dict @search-dict="searchDict"/>
<DictItem ref="dictItem"/>
</div>
</APage>
</template>
<script lang="ts" setup>
@ -13,8 +10,10 @@ import DictCategory from '@/pages/sys/dict/DictCategory.vue'
import DictItem from '@/pages/sys/dict/DictItem.vue'
const dictItemIns = useTemplateRef<InstanceType<typeof DictItem>>('dictItem')
const currentDict = ref<string | undefined>(undefined)
function searchDict(data: DictTypes.SearchDictResult) {
currentDict.value = data.id
dictItemIns.value?.reload(data)
}
@ -24,15 +23,10 @@ function searchDict(data: DictTypes.SearchDictResult) {
display flex
justify-content space-between
flex-direction: row;
gap: 50px;
& > div:not(:nth-child(2)) {
& > div {
width 50%
box-sizing border-box
}
& > div:nth-child(2) {
height: 100%;
}
}
</style>

View File

@ -1,193 +1,109 @@
<template>
<div>
<div class="tool-bar">
<ElForm inline @submit.prevent="paging">
<ATablePage
ref="tablePage"
v-bind="tablePageProps">
<template #simpleFormItem="formData">
<ElFormItem>
<ElInput
v-model="searchForm.dictName"
v-model="formData.dictName"
clearable
placeholder="请输入要搜索的文字"
@clear="reset"/>
@clear="research"/>
</ElFormItem>
<ElFormItem>
<ElButton :icon="elIcons.Search" :loading="searching" native-type="submit" type="primary">搜索</ElButton>
<ElButton :icon="elIcons.Plus" type="primary" @click="addHandler"></ElButton>
</ElFormItem>
</ElForm>
</div>
<ElTable v-loading="searching" :data="tableData"
cell-class-name="table-cell"
class="table-list"
empty-text="暂无数据"
header-row-class-name="table-header"
row-key="id">
</template>
<template #columns>
<ElTableColumn label="字典标识" prop="dictKey" width="180"/>
<ElTableColumn label="字典名称" prop="dictName"/>
<ElTableColumn label="备注" prop="memo"/>
<ElTableColumn label="操作" width="180">
<template #default="scope">
<div class="action-btn">
<ElPopconfirm
cancel-button-text="否"
cancel-button-type="primary"
confirm-button-text="是"
confirm-button-type="danger"
placement="top"
title="是否删除当前数据?"
width="180"
@confirm="delHandler(scope)">
<template #reference>
<ElButton :loading="deling" text type="danger">删除</ElButton>
<!-- <ElTableColumn label="备注" prop="memo"/> -->
</template>
</ElPopconfirm>
<ElButton text type="primary" @click="modifyHandler(scope)"></ElButton>
<ElButton text type="primary" @click="selectDictHandle(scope)"></ElButton>
</div>
</template>
</ElTableColumn>
</ElTable>
<ElPagination
v-model:current-page="searchForm.current"
v-model:page-size="searchForm.size"
:hide-on-single-page="false"
:page-sizes="[10, 20, 50, 100, 500]"
:teleported="false"
:total="totalCount"
background layout="total, prev, pager, next, sizes, jumper"
@change="paging"/>
<DictForm ref="dictForm" @edit-succ="paging"/>
</div>
<DictForm ref="dictForm" :research="research"/>
</ATablePage>
</template>
<script lang="ts" setup>
import DictApi from '@/pages/sys/dict/dict-api.ts'
import { elIcons } from '@/common/element/element.ts'
import DictForm from '@/pages/sys/dict/DictForm.vue'
import ATablePage, {
type ATablePageInstance,
buildTablePageProps,
} from '@/components/a-page/a-table-page/ATablePage.tsx'
const totalCount = ref(0)
const tableData = ref<DictTypes.SearchDictResult[]>([])
const searchForm = ref<DictTypes.SearchDictParam>({
orders: 'dict_key,id',
current: 1,
size: 20,
})
const searching = ref(false)
const deling = ref(false)
const props = defineProps<{
currentDict?: string
}>()
const emits = defineEmits([ 'searchDict' ])
const dictFormIns = useTemplateRef<InstanceType<typeof DictForm>>('dictForm')
const tablePageIns = useTemplateRef<ATablePageInstance>('tablePage')
function showDialog(data?: DictTypes.SearchDictResult) {
dictFormIns.value?.open(data)
function research() {
tablePageIns.value?.doSearch()
}
function delHandler({row}: { row: DictTypes.SearchDictResult }) {
deling.value = true
DictApi.del([ row.id! ])
const tablePageProps = buildTablePageProps<DictTypes.SearchDictParam, DictTypes.SearchDictResult>({
pageLayout: {
enableHighForm: false,
},
searchForm: {
paging: DictApi.paging,
},
toolBar: {
leftTools: [
{
icon: 'Plus',
label: '新建',
action() {
dictFormIns.value?.open()
},
},
],
},
table: {
highlightCurrentRow: true,
actionColumn: {
tableActions: [
{
tooltip: '字典项',
icon: 'Postcard',
type: 'primary',
action() {
// emits('searchDict', row)
},
},
{
tooltip: '编辑',
icon: 'Edit',
type: 'success',
action({row}) {
dictFormIns.value?.open(row)
},
},
{
icon: 'Delete',
loading: false,
type: 'danger',
tooltip: '删除',
confirm: {
title: '是否删除当前数据',
},
action({row}) {
return DictApi.del([ row.id! ])
.then(() => {
ElMessage.success('删除成功')
paging()
return true
})
.finally(() => {
deling.value = false
})
}
function modifyHandler({row}: { row: DictTypes.SearchDictResult }) {
showDialog(row)
}
function addHandler() {
showDialog()
}
const emits = defineEmits([ 'searchDict' ])
function selectDictHandle({row}: { row: DictTypes.SearchDictResult }) {
},
},
],
},
rowClickHandle(row) {
emits('searchDict', row)
}
function reset() {
searchForm.value = {
orders: 'dict_key,id',
current: 1,
size: 20,
}
paging()
}
function paging() {
searching.value = true
DictApi.paging(searchForm.value)
.then(res => {
totalCount.value = res.data?.total ?? 0
tableData.value = res.data?.records ?? []
})
.finally(() => {
searching.value = false
},
},
})
watchEffect(() => {
if (props.currentDict != null) {
tablePageProps.table.currentRowKey = props.currentDict
}
onMounted(() => {
paging()
})
</script>
<style lang="stylus" scoped>
.table-list {
flex 1;
margin 0 0 20px 0
width 100%
:deep(.table-header) {
color #454C59
th {
background-color #EDF1F7
font-weight 500
position relative
& > div {
display flex
gap 5px
align-items center
}
&:not(:first-child) > div::before {
position: absolute;
top: 50%;
left: 1px;
width: 1px;
background-color: #D3D7DE;
transform: translateY(-50%);
content: "";
height 50%
}
}
}
:deep(.table-cell) {
color #2F3540
}
.action-btn {
width 100%
display flex
flex-wrap wrap
& > button {
margin 0
}
}
}
.tool-bar {
display flex
justify-content space-between
margin 0 0 20px 0
}
.pagination {
justify-content: end;
margin: 8px;
}
</style>

View File

@ -1,93 +1,81 @@
<template>
<ElDialog v-model="showDialog"
:close-on-click-modal="false"
destroy-on-close
@close="dialogCloseHandler"
width="25vw">
<ElForm :model="dictFormData"
class="sys_dict-form"
>
<ElFormItem label="字典标识">
<AFormPanel
ref="formPanel"
v-bind="formPanelProps">
<template #default="formData">
<div class="form-items">
<ElFormItem label="字典标识" prop="dictKey">
<ElInput
v-model="dictFormData.dictKey"
v-model="formData.dictKey"
placeholder="字典标识"/>
</ElFormItem>
<ElFormItem label="字典名称">
<ElFormItem label="字典名称" prop="dictName">
<ElInput
v-model="dictFormData.dictName"
v-model="formData.dictName"
placeholder="字典名称"/>
</ElFormItem>
<ElFormItem label="备注">
<ElInput
v-model="dictFormData.memo"
v-model="formData.memo"
placeholder="备注"/>
</ElFormItem>
</ElForm>
<template #footer>
<ElButton @click="showDialog = false">{{ status === 'view' ? '关闭' : '取消' }}</ElButton>
<ElButton v-if="status !== 'view'" :loading="submiting" type="primary" @click="submitHandler"></ElButton>
</div>
</template>
</ElDialog>
</AFormPanel>
</template>
<script lang="ts" setup>
import DictApi from '@/pages/sys/dict/dict-api.ts'
import Strings from '@/common/utils/strings.ts'
import { ElMessage } from 'element-plus'
import AFormPanel, {
type AFormPanelInstance,
buildFormPanelProps,
} from '@/components/a-form-panel/AFormPanel.tsx'
const emits = defineEmits([ 'editSucc' ])
const showDialog = ref(false)
const submiting = ref(false)
const status = ref<'add' | 'view' | 'modify'>('add')
const dictFormData = ref<DictTypes.SearchDictResult>({})
function dialogCloseHandler() {
dictFormData.value = {}
}
function submitHandler() {
if (status.value === 'view') return
submiting.value = true
if (dictFormData.value.id != null) {
DictApi.modify(dictFormData.value)
.then(() => {
ElMessage.success('修改成功')
emits('editSucc')
showDialog.value = false
const props = withDefaults(defineProps<{
research?: () => void
}>(), {
research: () => {
},
})
.finally(() => {
submiting.value = false
})
} else {
DictApi.add(dictFormData.value)
.then(() => {
ElMessage.success('添加成功')
emits('editSucc')
showDialog.value = false
})
.finally(() => {
submiting.value = false
})
}
}
defineExpose({
open(data: DictTypes.SearchDictResult = {}) {
showDialog.value = true
if (!Strings.isBlank(data.id)) {
status.value = 'modify'
DictApi.detail(data.id!)
.then(res => {
dictFormData.value = res.data
})
} else {
const formPanelIns = useTemplateRef<AFormPanelInstance>('formPanel')
const status = ref<'add' | 'modify'>('add')
const formPanelProps = buildFormPanelProps<DictTypes.SearchDictResult>({
detailsLoader(id?: string) {
if (Strings.isBlank(id)) {
status.value = 'add'
dictFormData.value = data
return Promise.resolve({})
} else {
status.value = 'modify'
return DictApi
.detail(id!)
.then((res) => {
return res.data
})
}
},
doSubmit(data) {
if (status.value === 'add') {
return DictApi.add(data)
.then(props.research)
} else {
return DictApi.modify(data)
.then(props.research)
}
},
rules: {
dictName: [ {required: true, message: '请填写字典名称', trigger: 'blur'} ],
dictKey: [ {required: true, message: '请填写字典标识', trigger: 'blur'} ],
},
})
watchEffect(() => {
formPanelProps.title = status.value === 'add' ? '新建字典分类' : '修改字典分类'
})
defineExpose({
open(data?: DictTypes.SearchDictResult) {
formPanelIns.value?.open(data?.id)
},
})
</script>
<style lang="stylus" scoped>
.sys_dict-form {
padding 20px
}
</style>

View File

@ -1,35 +1,24 @@
<template>
<div>
<div class="tool-bar">
<ElForm inline @submit.prevent="paging">
<ATablePage
ref="tablePage"
v-bind="tablePageProps">
<template #simpleFormItem="formData">
<ElFormItem>
<ElInput
v-model="searchForm.dictKey"
v-model="formData.dictKey"
placeholder="请选择左侧的字典"
readonly/>
</ElFormItem>
<ElFormItem>
<ElInput
v-model="searchForm.txt"
v-model="formData.txt"
clearable
placeholder="请输入要搜索的文字"
@clear="reset"/>
@clear="research"/>
</ElFormItem>
<ElFormItem>
<ElButton :disabled="Strings.isBlank(currentDict.dictKey)" :icon="elIcons.Search" :loading="searching" native-type="submit" type="primary">搜索</ElButton>
<ElButton :disabled="Strings.isBlank(currentDict.dictKey)" :icon="elIcons.Plus" type="primary" @click="addHandler"></ElButton>
</ElFormItem>
</ElForm>
</div>
<ElTable v-loading="searching" :data="tableData"
cell-class-name="table-cell"
class="table-list"
empty-text="暂无数据"
header-row-class-name="table-header"
row-key="id">
<!-- <ElTableColumn label="字典 Id" prop="dictId"/> -->
<ElTableColumn label="字典标识" prop="dictKey" width="180"/>
</template>
<template #columns>
<!-- <ElTableColumn label="字典标识" prop="dictKey" width="180"/> -->
<ElTableColumn label="值" prop="val"/>
@ -37,155 +26,104 @@
<ElTableColumn label="排序" prop="sort"/>
<ElTableColumn label="备注" prop="memo"/>
<ElTableColumn label="操作" width="180">
<template #default="scope">
<div class="action-btn">
<ElPopconfirm
cancel-button-text="否"
cancel-button-type="primary"
confirm-button-text="是"
confirm-button-type="danger"
placement="top"
title="是否删除当前数据?"
width="180"
@confirm="delHandler(scope)">
<template #reference>
<ElButton :loading="deling" text type="danger">删除</ElButton>
<!-- <ElTableColumn label="备注" prop="memo"/> -->
</template>
</ElPopconfirm>
<ElButton text type="primary" @click="modifyHandler(scope)"></ElButton>
</div>
</template>
</ElTableColumn>
</ElTable>
<DictItemForm ref="dictItemForm" @edit-succ="paging"/>
</div>
<DictItemForm ref="dictItemForm" :dict-id="currentDict.id" :dict-key="currentDict.dictKey" :research="research"/>
</ATablePage>
</template>
<script lang="ts" setup>
import DictApi from '@/pages/sys/dict/dict-api.ts'
import DictItemApi from '@/pages/sys/dict/dict-item-api.ts'
import { elIcons } from '@/common/element/element.ts'
import DictItemForm from '@/pages/sys/dict/DictItemForm.vue'
import Strings from '@/common/utils/strings.ts'
import ATablePage, {
type ATablePageInstance,
buildTablePageProps,
} from '@/components/a-page/a-table-page/ATablePage.tsx'
const tableData = ref<DictItemTypes.SearchDictItemResult[]>([])
const searchForm = reactive<DictItemTypes.SearchDictItemParam>({
current: 1,
size: 20,
})
const searching = ref(false)
const deling = ref(false)
const currentDict = reactive<DictTypes.SearchDictResult>({})
const dictItemFormIns = useTemplateRef<InstanceType<typeof DictItemForm>>('dictItemForm')
const tablePageIns = useTemplateRef<ATablePageInstance<DictItemTypes.SearchDictItemParam, DictItemTypes.SearchDictItemResult>>('tablePage')
const currentDict = reactive<DictTypes.SearchDictResult>({})
function showDialog(data?: any) {
dictItemFormIns.value?.open(data)
function research() {
tablePageIns.value?.doSearch()
}
function delHandler({row}: { row: DictItemTypes.SearchDictItemResult }) {
deling.value = true
DictItemApi.del([ row.id! ])
const tablePageProps = buildTablePageProps<DictItemTypes.SearchDictItemParam, DictItemTypes.SearchDictItemResult>({
pageLayout: {
enableHighForm: false,
},
searchForm: {
list(param) {
if (currentDict.dictKey == null) {
return Promise.resolve({
code: 0, msg: '',
message: '',
success: false,
data: [],
})
}
return DictApi.obtainDictData({...param, dictKey: currentDict.dictKey})
},
resetForm() {
return {dictId: currentDict.id, dictKey: currentDict.dictKey}
},
simpleForm: {
colCount: 2,
},
},
toolBar: {
leftTools: [
{
icon: 'Plus',
label: '新建',
action() {
dictItemFormIns.value?.open({dictId: currentDict.id, dictKey: currentDict.dictKey})
},
},
],
},
table: {
actionColumn: {
tableActions: [
{
tooltip: '编辑',
icon: 'Edit',
type: 'success',
action({row}) {
dictItemFormIns.value?.open(row)
},
},
{
icon: 'Delete',
loading: false,
type: 'danger',
tooltip: '删除',
confirm: {
title: '是否删除当前数据',
},
action({row}) {
return DictItemApi.del([ row.id! ])
.then(() => {
ElMessage.success('删除成功')
paging()
return true
})
.finally(() => {
deling.value = false
},
},
],
},
},
})
}
function modifyHandler({row}: { row: DictItemTypes.SearchDictItemResult }) {
showDialog(row)
}
function addHandler() {
if (Strings.isBlank(searchForm.dictKey)) {
ElMessage.error('请选择左侧的字典')
return
}
showDialog({dictId: currentDict.id, dictKey: currentDict.dictKey})
}
function reset() {
searchForm.txt = ''
paging()
}
function paging() {
if (Strings.isBlank(searchForm.dictKey)) {
ElMessage.error('请选择左侧的字典')
return
}
searching.value = true
DictApi.obtainDictData(searchForm)
.then(res => {
tableData.value = res.data ?? []
watchEffect(() => {
tablePageProps.toolBar.leftTools![0].disabled = currentDict.dictKey == null
})
.finally(() => {
searching.value = false
})
}
defineExpose({
reload(data: DictTypes.SearchDictResult) {
searchForm.dictKey = data.dictKey
Object.assign(currentDict, data)
paging()
tablePageIns.value?.formData.$reset({dictId: currentDict.id, dictKey: currentDict.dictKey})
research()
},
})
</script>
<style lang="stylus" scoped>
.table-list {
flex 1;
width 100%
:deep(.table-header) {
color #454C59
th {
background-color #EDF1F7
font-weight 500
position relative
& > div {
display flex
gap 5px
align-items center
}
&:not(:first-child) > div::before {
position: absolute;
top: 50%;
left: 1px;
width: 1px;
background-color: #D3D7DE;
transform: translateY(-50%);
content: "";
height 50%
}
}
}
:deep(.table-cell) {
color #2F3540
}
.action-btn {
width 100%
display flex
flex-wrap wrap
& > button {
margin 0
}
}
}
.tool-bar {
display flex
justify-content space-between
margin 0 0 20px 0
}
</style>

View File

@ -1,110 +1,95 @@
<template>
<ElDialog v-model="showDialog"
:close-on-click-modal="false"
destroy-on-close
@close="dialogCloseHandler"
width="25vw">
<ElForm :model="dictItemFormData"
class="sys_dict_item-form"
>
<ElFormItem label="值">
<AFormPanel
ref="formPanel"
v-bind="formPanelProps">
<template #default="formData">
<div class="form-items">
<ElFormItem label="值" prop="val">
<ElInput
v-model="dictItemFormData.val"
v-model="formData.val"
placeholder="值"/>
</ElFormItem>
<ElFormItem label="文本">
<ElFormItem label="文本" prop="txt">
<ElInput
v-model="dictItemFormData.txt"
v-model="formData.txt"
placeholder="文本"/>
</ElFormItem>
<ElFormItem label="排序">
<ElFormItem label="排序" prop="sort">
<ElInputNumber
v-model="dictItemFormData.sort"
v-model="formData.sort"
:min="1"
placeholder="排序"
style="width: 100%"/>
</ElFormItem>
<ElFormItem label="备注">
<!-- <ElFormItem label="备注">
<ElInput
v-model="dictItemFormData.memo"
v-model="formData.memo"
placeholder="备注"/>
</ElFormItem>
</ElForm>
<template #footer>
<ElButton @click="showDialog = false">{{ status === 'view' ? '关闭' : '取消' }}</ElButton>
<ElButton v-if="status !== 'view'" :loading="submiting" type="primary" @click="submitHandler"></ElButton>
</ElFormItem> -->
</div>
</template>
</ElDialog>
</AFormPanel>
</template>
<script lang="ts" setup>
import DictItemApi from '@/pages/sys/dict/dict-item-api.ts'
import Strings from '@/common/utils/strings.ts'
import { ElMessage } from 'element-plus'
import AFormPanel, {
type AFormPanelInstance,
buildFormPanelProps,
} from '@/components/a-form-panel/AFormPanel.tsx'
const emits = defineEmits([ 'editSucc' ])
const showDialog = ref(false)
const submiting = ref(false)
const status = ref<'add' | 'view' | 'modify'>('add')
// const dictItemFormData = ref<DictItemTypes.SearchDictItemResult>({})
const dictItemFormData = ref<any>({})
function dialogCloseHandler() {
dictItemFormData.value = {}
}
function submitHandler() {
if (status.value === 'view') return
submiting.value = true
if (dictItemFormData.value.id != null) {
DictItemApi.modify(dictItemFormData.value)
.then(() => {
ElMessage.success('修改成功')
emits('editSucc')
showDialog.value = false
const props = withDefaults(defineProps<{
research?: () => void
// Id
dictId?: string
//
dictKey?: string
}>(), {
research: () => {
},
})
.finally(() => {
submiting.value = false
})
} else {
if (Strings.isBlank(dictItemFormData.value.dictId) || Strings.isBlank(dictItemFormData.value.dictKey)) {
ElMessage.error('未指定字典')
return
}
DictItemApi.add(dictItemFormData.value)
.then(() => {
ElMessage.success('添加成功')
emits('editSucc')
showDialog.value = false
})
.finally(() => {
submiting.value = false
})
}
}
defineExpose({
// open(data: DictItemTypes.SearchDictItemResult = {}) {
open(data: any = {}) {
showDialog.value = true
if (!Strings.isBlank(data.id)) {
status.value = 'modify'
DictItemApi.detail(data.id!)
.then(res => {
dictItemFormData.value = res.data
})
} else {
const status = ref<'add' | 'modify'>('add')
const formPanelIns = useTemplateRef<AFormPanelInstance>('formPanel')
const formPanelProps = buildFormPanelProps<DictItemTypes.SearchDictItemResult>({
detailsLoader(id?: string) {
if (Strings.isBlank(id)) {
status.value = 'add'
dictItemFormData.value = data
return Promise.resolve()
} else {
status.value = 'modify'
return DictItemApi
.detail(id!)
.then((res) => {
return res.data
})
}
},
doSubmit(data) {
if (status.value === 'add') {
if (Strings.isBlank(props.dictId) || Strings.isBlank(props.dictKey)) {
ElMessage.error('未指定字典')
return Promise.reject()
}
return DictItemApi.add({...data, dictKey: props.dictKey, dictId: props.dictId})
.then(props.research)
} else {
return DictItemApi.modify(data)
.then(props.research)
}
},
rules: {
val: [ {required: true, message: '请填写值', trigger: 'blur'} ],
txt: [ {required: true, message: '请填写文本', trigger: 'blur'} ],
sort: [ {required: true, message: '请填写排序', trigger: 'blur'} ],
},
})
watchEffect(() => {
formPanelProps.title = status.value === 'add' ? '新建字典项' : '修改字典项'
})
defineExpose({
open(data: any = {}) {
formPanelIns.value?.open(data?.id)
},
})
</script>
<style lang="stylus" scoped>
.sys_dict_item-form {
padding 20px
}
</style>

View File

@ -8,9 +8,9 @@
<ElTreeSelect v-model="formData.pid" v-loading="loadingMenus" :data="menuTreeDataSource" :default-expanded-keys="['0']" :render-after-expand="false" check-strictly placeholder="选择上级菜单"/>
</ElFormItem>
<ElFormItem label="客户端" prop="clients">
<ElCheckboxGroup v-model="formData.clients">
<ElCheckbox v-for="client in ClientUtil.clients" :key="client.val" :label="client.txt" :value="client.val"/>
</ElCheckboxGroup>
<ElRadioGroup v-model="formData.clientCode">
<ElRadio v-for="client in ClientUtil.clients" :key="client.val" :label="client.txt" :value="client.val"/>
</ElRadioGroup>
</ElFormItem>
<ElFormItem label="类型">
<ElSelect v-model="formData.menuCategory" :data="menuCategoryData" placeholder="选择类型">
@ -87,7 +87,7 @@ const formPanelProps = buildFormPanelProps<MenuTypes.MenuForm>({
return Promise.resolve({
icon: 'dianzixiaopiao',
pid: '0',
clients: [ 1 ],
clientCode: 1,
menuCategory: MenuCategory.Catalog,
sn: nanoid(10),
} as MenuTypes.MenuForm)
@ -98,7 +98,6 @@ const formPanelProps = buildFormPanelProps<MenuTypes.MenuForm>({
.then((res) => {
return {
...res.data,
clients: ClientUtil.getClients(res.data.clientCode!).map(it => it.val),
} as MenuTypes.MenuForm
})
}

View File

@ -72,6 +72,7 @@ declare global {
// 路由名称
routeName?: string
routePath?: string
clientCode?: number
menuCategory?: MenuCategory
}
@ -89,6 +90,7 @@ declare global {
// 路由名称
routeName?: string
routePath?: string
clientCode?: number
menuCategory?: MenuCategory
}
}