|
@@ -0,0 +1,284 @@
|
|
|
+<script setup lang="tsx">
|
|
|
+import { ContentWrap } from '@/components/ContentWrap'
|
|
|
+import { useI18n } from '@/hooks/web/useI18n'
|
|
|
+import { Table } from '@/components/Table'
|
|
|
+import { ref, unref, PropType, reactive } from 'vue'
|
|
|
+import { ElButton, ElButtonGroup, ElTooltip } from 'element-plus'
|
|
|
+import { getTree, saveTableApi, delTableListApi, updateTableApi } from '@/api/manage/dict'
|
|
|
+import type { DictData, DictRowData } from '@/api/manage/types'
|
|
|
+import { useTable } from '@/hooks/web/useTable'
|
|
|
+import { Search } from '@/components/Search'
|
|
|
+import Write from './Write.vue'
|
|
|
+// import Detail from './components/Detail.vue'
|
|
|
+import { Dialog } from '@/components/Dialog'
|
|
|
+import { CrudSchema, useCrudSchemas } from '@/hooks/web/useCrudSchemas'
|
|
|
+import { useIcon } from '@/hooks/web/useIcon'
|
|
|
+const EditIcon = useIcon({ icon: 'ep:edit' })
|
|
|
+// const DetailIcon = useIcon({ icon: 'ep:document' })
|
|
|
+const DeleteIcon = useIcon({ icon: 'ep:delete' })
|
|
|
+
|
|
|
+const props = defineProps({
|
|
|
+ rowData: {
|
|
|
+ type: Object as PropType<DictData>
|
|
|
+ }
|
|
|
+})
|
|
|
+
|
|
|
+const { t } = useI18n()
|
|
|
+
|
|
|
+const { tableRegister, tableState, tableMethods } = useTable({
|
|
|
+ fetchDataApi: async () => {
|
|
|
+ const res = await getTree({
|
|
|
+ pid: props.rowData?.id,
|
|
|
+ ...unref(searchParams)
|
|
|
+ })
|
|
|
+ return {
|
|
|
+ list:
|
|
|
+ res.data.map((e: DictRowData) => {
|
|
|
+ return {
|
|
|
+ ...e,
|
|
|
+ hasChildren: true
|
|
|
+ }
|
|
|
+ }) || []
|
|
|
+ }
|
|
|
+ },
|
|
|
+ fetchDelApi: async () => {
|
|
|
+ const res = await delTableListApi(unref(id))
|
|
|
+ return !!res
|
|
|
+ }
|
|
|
+})
|
|
|
+const { loading, dataList, pageSize, currentPage } = tableState
|
|
|
+const { getList, delList } = tableMethods
|
|
|
+const crudSchemas = reactive<CrudSchema[]>([
|
|
|
+ {
|
|
|
+ field: 'name',
|
|
|
+ label: '名称'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ field: 'code',
|
|
|
+ label: '编码',
|
|
|
+ search: {
|
|
|
+ hidden: true
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ field: 'showText',
|
|
|
+ label: '显示文字',
|
|
|
+ search: {
|
|
|
+ hidden: true
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ field: 'value',
|
|
|
+ label: '值',
|
|
|
+ search: {
|
|
|
+ hidden: true
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ field: 'isActive',
|
|
|
+ label: '是否启用',
|
|
|
+ minWidth: 100,
|
|
|
+ table: {
|
|
|
+ hidden: false
|
|
|
+ },
|
|
|
+ search: {
|
|
|
+ hidden: true
|
|
|
+ },
|
|
|
+ form: {
|
|
|
+ component: 'Switch',
|
|
|
+ value: '1',
|
|
|
+ componentProps: {
|
|
|
+ activeText: '启用',
|
|
|
+ inactiveText: '禁用',
|
|
|
+ activeValue: '1',
|
|
|
+ inactiveValue: '0'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ field: 'description',
|
|
|
+ label: '备注',
|
|
|
+ form: {
|
|
|
+ componentProps: {
|
|
|
+ type: 'textarea'
|
|
|
+ },
|
|
|
+ colProps: {
|
|
|
+ span: 24
|
|
|
+ }
|
|
|
+ },
|
|
|
+ search: {
|
|
|
+ hidden: true
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ {
|
|
|
+ field: 'action',
|
|
|
+ label: t('userDemo.action'),
|
|
|
+ form: {
|
|
|
+ hidden: true
|
|
|
+ },
|
|
|
+ detail: {
|
|
|
+ hidden: true
|
|
|
+ },
|
|
|
+ search: {
|
|
|
+ hidden: true
|
|
|
+ },
|
|
|
+ table: {
|
|
|
+ width: 160,
|
|
|
+ fixed: 'right',
|
|
|
+ slots: {
|
|
|
+ default: (data: any) => {
|
|
|
+ const row = data.row as DictRowData
|
|
|
+ return (
|
|
|
+ <>
|
|
|
+ <ElButtonGroup>
|
|
|
+ <ElTooltip content="编辑">
|
|
|
+ <ElButton text icon={EditIcon} onClick={() => action(row, 'edit')} />
|
|
|
+ </ElTooltip>
|
|
|
+ <ElTooltip content="删除">
|
|
|
+ <ElButton
|
|
|
+ text
|
|
|
+ icon={DeleteIcon}
|
|
|
+ type="danger"
|
|
|
+ onClick={() => delData(data.row)}
|
|
|
+ />
|
|
|
+ </ElTooltip>
|
|
|
+ </ElButtonGroup>
|
|
|
+ </>
|
|
|
+ )
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+])
|
|
|
+
|
|
|
+const { allSchemas } = useCrudSchemas(crudSchemas)
|
|
|
+const searchParams = ref({})
|
|
|
+const setSearchParams = (params: any) => {
|
|
|
+ currentPage.value = 1
|
|
|
+ searchParams.value = params
|
|
|
+ getList()
|
|
|
+}
|
|
|
+
|
|
|
+const dialogVisible = ref(false)
|
|
|
+const dialogTitle = ref('')
|
|
|
+
|
|
|
+const currentRow = ref<DictData>()
|
|
|
+const actionType = ref('')
|
|
|
+
|
|
|
+const AddAction = (key: string) => {
|
|
|
+ dialogTitle.value = '新增'
|
|
|
+ currentRow.value = undefined
|
|
|
+ if (key) {
|
|
|
+ currentRow.value = {
|
|
|
+ pid: key
|
|
|
+ }
|
|
|
+ }
|
|
|
+ dialogVisible.value = true
|
|
|
+ actionType.value = 'add'
|
|
|
+}
|
|
|
+const delLoading = ref(false)
|
|
|
+const id = ref<string>('')
|
|
|
+const delData = async (row: DictRowData) => {
|
|
|
+ id.value = row.id
|
|
|
+ delLoading.value = true
|
|
|
+
|
|
|
+ await delList(unref(id).length).finally(() => {
|
|
|
+ delLoading.value = false
|
|
|
+ })
|
|
|
+}
|
|
|
+const action = (row: DictData, type: string) => {
|
|
|
+ dialogTitle.value = type === 'edit' ? '编辑' : '子项列表'
|
|
|
+ actionType.value = type
|
|
|
+ currentRow.value = row
|
|
|
+ dialogVisible.value = true
|
|
|
+}
|
|
|
+const writeRef = ref<ComponentRef<typeof Write>>()
|
|
|
+const tableRef = ref<ComponentRef<typeof Table>>()
|
|
|
+const saveLoading = ref(false)
|
|
|
+const save = async () => {
|
|
|
+ const write = unref(writeRef)
|
|
|
+ const formData = await write?.submit()
|
|
|
+ if (formData) {
|
|
|
+ saveLoading.value = true
|
|
|
+ try {
|
|
|
+ if (actionType.value == 'add') {
|
|
|
+ const res = await saveTableApi(formData)
|
|
|
+ if (res) {
|
|
|
+ getList()
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ const res = await updateTableApi(formData)
|
|
|
+ if (res) {
|
|
|
+ getList()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.log(error)
|
|
|
+ } finally {
|
|
|
+ saveLoading.value = false
|
|
|
+ dialogVisible.value = false
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+defineExpose({
|
|
|
+ getList
|
|
|
+})
|
|
|
+</script>
|
|
|
+
|
|
|
+<template>
|
|
|
+ <div>
|
|
|
+ <ContentWrap>
|
|
|
+ <Search
|
|
|
+ :schema="allSchemas.searchSchema"
|
|
|
+ @reset="setSearchParams"
|
|
|
+ @search="setSearchParams"
|
|
|
+ />
|
|
|
+
|
|
|
+ <div class="mb-10px">
|
|
|
+ <ElButton type="primary" @click="AddAction(props.rowData?.id || '')">{{
|
|
|
+ t('exampleDemo.add')
|
|
|
+ }}</ElButton>
|
|
|
+ </div>
|
|
|
+ <Table
|
|
|
+ ref="tableRef"
|
|
|
+ v-model:current-page="currentPage"
|
|
|
+ v-model:page-size="pageSize"
|
|
|
+ :columns="allSchemas.tableColumns"
|
|
|
+ :data="dataList"
|
|
|
+ :loading="loading"
|
|
|
+ row-key="id"
|
|
|
+ @register="tableRegister"
|
|
|
+ />
|
|
|
+ </ContentWrap>
|
|
|
+
|
|
|
+ <Dialog v-model="dialogVisible" :title="dialogTitle">
|
|
|
+ <Write
|
|
|
+ v-if="actionType !== 'detail'"
|
|
|
+ ref="writeRef"
|
|
|
+ :form-schema="allSchemas.formSchema"
|
|
|
+ :current-row="currentRow"
|
|
|
+ />
|
|
|
+
|
|
|
+ <!-- <Detail
|
|
|
+ v-if="actionType === 'detail'"
|
|
|
+ :columns="props.allSchemas.tableColumns"
|
|
|
+ :current-row="currentRow"
|
|
|
+ /> -->
|
|
|
+
|
|
|
+ <template #footer>
|
|
|
+ <ElButton
|
|
|
+ v-if="actionType !== 'detail'"
|
|
|
+ type="primary"
|
|
|
+ :loading="saveLoading"
|
|
|
+ @click="save"
|
|
|
+ >
|
|
|
+ {{ t('exampleDemo.save') }}
|
|
|
+ </ElButton>
|
|
|
+
|
|
|
+ <ElButton @click="dialogVisible = false">{{ t('dialogDemo.close') }}</ElButton>
|
|
|
+ </template>
|
|
|
+ </Dialog>
|
|
|
+ </div>
|
|
|
+</template>
|