| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730 |
- <template>
- <cacp-search-layout>
- <template #search>
- <cacp-search-panel-layout
- :model="state.queryData"
- ref="queryFormRef"
- label-position="left"
- label-width="auto"
- :gutter="30"
- :colSpan="6"
- >
- #foreach($column in $columns)
- #if($column.query)
- #set($parentheseIndex=$column.columnComment.indexOf("("))
- #if($parentheseIndex != -1)
- #set($comment=$column.columnComment.substring(0, $parentheseIndex))
- #else
- #set($comment=$column.columnComment)
- #end
- #set($dictType=$column.dictType)
- #set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
- #if($column.htmlType == "input")
- <el-form-item label="${comment}" prop="${column.javaField}">
- <el-input v-model="state.queryData.${column.javaField}" placeholder="请输入${comment}" clearable />
- </el-form-item>
- #elseif(($column.htmlType == "select" || $column.htmlType == "radio") && "" != $dictType)
- <el-form-item label="${comment}" prop="${column.javaField}">
- <el-select v-model="state.queryData.${column.javaField}" placeholder="请选择${comment}" clearable>
- ## <el-option
- ## v-for="dict in dict.type.${dictType}"
- ## :key="dict.value"
- ## :label="dict.label"
- ## :value="dict.value"
- ## />
- </el-select>
- </el-form-item>
- #elseif($column.htmlType == "datetime" && $column.queryType != "BETWEEN")
- <el-form-item label="${comment}" prop="${column.javaField}">
- <el-date-picker
- clearable
- v-model="state.queryData.${column.javaField}"
- type="date"
- value-format="YYYY-MM-DD"
- placeholder="请选择${comment}"
- />
- </el-form-item>
- #elseif($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
- <el-form-item label="${comment}">
- <el-date-picker
- type="daterange"
- value-format="YYYY-MM-DD"
- v-model="state.queryData.begin${AttrName}"
- placeholder="开始时间"
- />
- </el-form-item>
- <el-form-item label="到">
- <el-date-picker
- type="daterange"
- value-format="YYYY-MM-DD"
- v-model="state.queryData.end${AttrName}"
- placeholder="结束时间"
- />
- </el-form-item>
- #end
- #end
- #end
- <template #buttonGroup>
- <el-button type="primary" @click="onSearch">查询</el-button>
- <el-button type="info" @click="onReset">重置</el-button>
- </template>
- </cacp-search-panel-layout>
- </template>
- <cacp-complex-table
- :actions="actions"
- :data="tableData"
- :pagination="tablePagination"
- :actionsWidth="120"
- @selection-change="handleSelectionChange"
- @on-page-change="onPageChange"
- @on-size-change="onSizeChange"
- :loading="loading"
- >
- <el-table-column type="selection" width="36" fixed="left" />
- #foreach($column in $columns)
- #set($javaField=$column.javaField)
- #set($parentheseIndex=$column.columnComment.indexOf("("))
- #if($parentheseIndex != -1)
- #set($comment=$column.columnComment.substring(0, $parentheseIndex))
- #else
- #set($comment=$column.columnComment)
- #end
- #if($column.pk)
- <el-table-column property="${javaField}" label="${comment}" width="100" :show-overflow-tooltip="true" />
- #elseif($column.list && $column.htmlType == "datetime")
- <el-table-column property="${javaField}" label="${comment}" width="120" sortable>
- <template #default="scope">
- {{ scope.row.${javaField} ? dayjs(scope.row.${javaField}).format('YYYY-MM-DD') : '' }}
- </template>
- </el-table-column>
- #elseif($column.list && $column.htmlType == "datetime" && $column.javaField.toLowerCase().contains('time'))
- <el-table-column property="${javaField}" label="${comment}" width="160" sortable>
- <template #default="scope">
- {{ scope.row.${javaField} ? dayjs(scope.row.${javaField}).format('YYYY-MM-DD HH:mm') : '' }}
- </template>
- </el-table-column>
- #elseif($column.list && "" != $column.dictType)
- <el-table-column property="${javaField}" label="${comment}" width="120">
- <template #default="scope">
- ## <dict-tag :options="dict.type.${column.dictType}" :value="scope.row.${javaField}" />
- {{ scope.row.${javaField} }}
- </template>
- </el-table-column>
- #elseif($column.list && "" != $javaField)
- <el-table-column property="${javaField}" label="${comment}" width="120" :show-overflow-tooltip="true" />
- #end
- #end
- </cacp-complex-table>
- </cacp-search-layout>
- <!--新增、编辑弹框-->
- <cacp-dialog
- v-model="state.dialogVisible"
- :resizable="false"
- :title="state.title"
- width="60%"
- @closed="onDialogClosed"
- >
- <el-form
- :model="state.formData"
- ref="dialogFormRef"
- :rules="infoRules"
- label-width="auto"
- label-position="left"
- :disabled="!state.isEdit"
- >
- <el-row :gutter="20">
- #set($colCount = 0)
- #foreach($column in $columns)
- #if($column.insert && !$column.pk)
- #set($field=$column.javaField)
- #set($parentheseIndex=$column.columnComment.indexOf("("))
- #if($parentheseIndex != -1)
- #set($comment=$column.columnComment.substring(0, $parentheseIndex))
- #else
- #set($comment=$column.columnComment)
- #end
- #set($dictType=$column.dictType)
- #set($colCount = $colCount + 1)
- #if($colCount % 2 == 1)
- <el-col :span="12">
- #else
- <el-col :span="12">
- #end
- #if($column.htmlType == "input")
- <el-form-item label="${comment}" prop="${field}"#if($column.required) required#end>
- <el-input v-model="state.formData.${field}" placeholder="请输入${comment}" />
- </el-form-item>
- #elseif($column.htmlType == "textarea")
- <el-form-item label="${comment}" prop="${field}"#if($column.required) required#end>
- <el-input v-model="state.formData.${field}" type="textarea" placeholder="请输入${comment}" />
- </el-form-item>
- #elseif($column.htmlType == "select" && "" != $dictType)
- <el-form-item label="${comment}" prop="${field}"#if($column.required) required#end>
- <el-select v-model="state.formData.${field}" placeholder="请选择${comment}" clearable>
- ## <el-option
- ## v-for="dict in dict.type.${dictType}"
- ## :key="dict.value"
- ## :label="dict.label"
- ## :value="dict.value"
- ## />
- </el-select>
- </el-form-item>
- #elseif($column.htmlType == "datetime")
- <el-form-item label="${comment}" prop="${field}"#if($column.required) required#end>
- <el-date-picker
- v-model="state.formData.${field}"
- type="date"
- value-format="YYYY-MM-DD"
- placeholder="请选择${comment}"
- style="width: 100%"
- />
- </el-form-item>
- #elseif($column.htmlType == "radio" && "" != $dictType)
- <el-form-item label="${comment}" prop="${field}"#if($column.required) required#end>
- <el-radio-group v-model="state.formData.${field}">
- ## <el-radio
- ## v-for="dict in dict.type.${dictType}"
- ## :key="dict.value"
- ## :label="dict.value"
- ## >{{ dict.label }}</el-radio>
- </el-radio-group>
- </el-form-item>
- #elseif($column.htmlType == "checkbox" && "" != $dictType)
- <el-form-item label="${comment}" prop="${field}"#if($column.required) required#end>
- <el-checkbox-group v-model="state.formData.${field}">
- ## <el-checkbox
- ## v-for="dict in dict.type.${dictType}"
- ## :key="dict.value"
- ## :label="dict.value"
- ## >{{ dict.label }}</el-checkbox>
- </el-checkbox-group>
- </el-form-item>
- #else
- <el-form-item label="${comment}" prop="${field}"#if($column.required) required#end>
- <el-input v-model="state.formData.${field}" placeholder="请输入${comment}" />
- </el-form-item>
- #end
- </el-col>
- #if($colCount % 2 == 0 && $foreach.hasNext)
- </el-row><el-row :gutter="20">
- #end
- #end
- #end
- </el-row>
- #if($table.sub)
- <el-divider content-position="center">${subTable.functionName}信息</el-divider>
- <el-row :gutter="10" class="mb8">
- <el-col :span="1.5">
- <el-button type="primary" icon="el-icon-plus" size="mini" @click="handleAdd${subClassName}">添加</el-button>
- </el-col>
- <el-col :span="1.5">
- <el-button type="danger" icon="el-icon-delete" size="mini" @click="handleDelete${subClassName}">删除</el-button>
- </el-col>
- </el-row>
- <el-table highlight-selection-row :data="state.${subclassName}List" :row-class-name="row${subClassName}Index" @selection-change="handle${subClassName}SelectionChange" ref="${subclassName}">
- <el-table-column type="selection" width="50" align="center" />
- <el-table-column label="序号" align="center" prop="index" width="50"/>
- #foreach($column in $subTable.columns)
- #set($javaField=$column.javaField)
- #set($parentheseIndex=$column.columnComment.indexOf("("))
- #if($parentheseIndex != -1)
- #set($comment=$column.columnComment.substring(0, $parentheseIndex))
- #else
- #set($comment=$column.columnComment)
- #end
- #if($column.pk || $javaField == ${subTableFkclassName})
- #elseif($column.list && $column.htmlType == "input")
- <el-table-column label="$comment" prop="${javaField}" width="150">
- <template #default="scope">
- <el-input v-model="scope.row.$javaField" placeholder="请输入$comment" />
- </template>
- </el-table-column>
- #elseif($column.list && $column.htmlType == "datetime")
- <el-table-column label="$comment" prop="${javaField}" width="240">
- <template #default="scope">
- <el-date-picker clearable v-model="scope.row.$javaField" type="date" value-format="YYYY-MM-DD" placeholder="请选择$comment" style="width: 100%" />
- </template>
- </el-table-column>
- #elseif($column.list && ($column.htmlType == "select" || $column.htmlType == "radio") && "" != $column.dictType)
- <el-table-column label="$comment" prop="${javaField}" width="150">
- <template #default="scope">
- <el-select v-model="scope.row.$javaField" placeholder="请选择$comment">
- ## <el-option
- ## v-for="dict in dict.type.$column.dictType"
- ## :key="dict.value"
- ## :label="dict.label"
- ## :value="dict.value"
- ## ></el-option>
- </el-select>
- </template>
- </el-table-column>
- #end
- #end
- </el-table>
- #end
- </el-form>
- <template #footer v-if="state.isEdit">
- <el-button @click="onDialogClosed">取消</el-button>
- <el-button type="primary" @click="onSubmit">确定</el-button>
- </template>
- </cacp-dialog>
- <!--查看弹框-->
- <cacp-dialog
- v-model="state.viewDialogVisible"
- :resizable="false"
- :title="state.viewTitle"
- width="50%"
- >
- <el-form
- :model="state.viewForm"
- label-width="auto"
- label-position="left"
- :disabled="true"
- >
- <el-row :gutter="20">
- #set($colCount = 0)
- #foreach($column in $columns)
- #if($column.insert && !$column.pk)
- #set($field=$column.javaField)
- #set($parentheseIndex=$column.columnComment.indexOf("("))
- #if($parentheseIndex != -1)
- #set($comment=$column.columnComment.substring(0, $parentheseIndex))
- #else
- #set($comment=$column.columnComment)
- #end
- #set($colCount = $colCount + 1)
- #if($colCount % 2 == 1)
- <el-col :span="12">
- #else
- <el-col :span="12">
- #end
- <el-form-item label="${comment}:" prop="${field}">
- <span>{{ state.viewForm.${field} || '-' }}</span>
- </el-form-item>
- </el-col>
- #if($colCount % 2 == 0 && $foreach.hasNext)
- </el-row><el-row :gutter="20">
- #end
- #end
- #end
- </el-row>
- </el-form>
- </cacp-dialog>
- </template>
- <script lang="ts" setup>
- import { onMounted, reactive, ref } from 'vue'
- import type { FormInstance } from 'element-plus'
- import { ElMessage, ElMessageBox, type FormRules } from 'element-plus'
- import config from '@/config'
- import {
- SuccessResultCode,
- useComplexTable,
- type Result,
- type SearchPanelLayoutInstance,
- type TableAction,
- useLoading
- } from '@cacp/ui'
- import type { ${ClassName}, ${ClassName}Query } from '@/types/${moduleName}/${businessName}'
- import { insert, getList, getDetail, remove, update } from '@/apis/${moduleName}/${businessName}'
- import { permissionStatus } from '@/utils/globalPermission'
- // 表单引用
- const queryFormRef = ref<SearchPanelLayoutInstance>()
- const dialogFormRef = ref<FormInstance>()
- // 加载状态
- const { loading, setLoading } = useLoading()
- // 表格 Hook
- const tableHooks = useComplexTable<${ClassName}>(config)
- const { tableData, tablePagination, setPagination, setPageIndex, setPageSizes } = tableHooks
- // 响应式数据
- interface State {
- queryData: ${ClassName}Query
- formData: ${ClassName}
- viewForm: ${ClassName}
- viewTitle: string
- viewDialogVisible: boolean
- title: string
- isEdit: boolean
- dialogVisible: boolean
- #if($table.sub)
- ${subclassName}List: any[]
- checked${subClassName}: number[]
- #end
- }
- const state = reactive<State>({
- queryData: {
- #foreach($column in $columns)
- #if($column.query)
- $column.javaField: #if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")''#else''#end,
- #if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
- #set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
- begin${AttrName}: '',
- end${AttrName}: '',
- #end
- #end
- #end
- pageIndex: tablePagination.currentPage,
- pageSize: tablePagination.pageSize
- },
- formData: {
- #foreach($column in $columns)
- $column.javaField: #if($column.htmlType == "checkbox")[]#elseif($column.javaType == 'Long' || $column.javaType == 'Integer')null#else''#end,
- #end
- #if($table.sub)
- ${subclassName}List: []
- #end
- } as ${ClassName},
- viewForm: {} as ${ClassName},
- viewTitle: '',
- viewDialogVisible: false,
- title: '',
- isEdit: false,
- dialogVisible: false,
- #if($table.sub)
- ${subclassName}List: [],
- checked${subClassName}: []
- #end
- })
- // 表单验证规则
- const infoRules = reactive<FormRules<${ClassName}>>({
- #foreach($column in $columns)
- #if($column.required)
- #set($parentheseIndex=$column.columnComment.indexOf("("))
- #if($parentheseIndex != -1)
- #set($comment=$column.columnComment.substring(0, $parentheseIndex))
- #else
- #set($comment=$column.columnComment)
- #end
- ${column.javaField}: [
- { required: true, message: '${comment}不能为空', trigger: #if($column.htmlType == "select" || $column.htmlType == "radio")'change'#else'blur'#end }
- ],
- #end
- #end
- })
- // 表格操作按钮配置
- const actions = <Array<TableAction>>[
- {
- key: 'create',
- text: '新增',
- onclick: onCreate,
- limit: permissionStatus('none', '${moduleName.toUpperCase()}_${businessName.toUpperCase()}_ADD_BT'),
- position: 'left',
- type: 'primary',
- },
- {
- key: 'view',
- text: '查看',
- onclick: onView,
- limit: permissionStatus('one', '${moduleName.toUpperCase()}_${businessName.toUpperCase()}_VIEW_BT'),
- type: 'primary'
- },
- {
- key: 'edit',
- text: '修改',
- onclick: onEdit,
- limit: permissionStatus('one', '${moduleName.toUpperCase()}_${businessName.toUpperCase()}_EDIT_BT'),
- type: 'primary'
- },
- {
- key: 'delete',
- text: '删除',
- onclick: onDelete,
- confirm: true,
- limit: permissionStatus('none', '${moduleName.toUpperCase()}_${businessName.toUpperCase()}_DELETE_BT'),
- type: 'primary'
- },
- #if($table.genTable.importTable)
- {
- key: 'import',
- type: 'primary',
- text: '导入',
- onclick: onImport,
- limit: permissionStatus('none', '${moduleName.toUpperCase()}_${businessName.toUpperCase()}_IMPORT_BT'),
- position: 'right',
- plain: true
- },
- {
- key: 'export',
- type: 'primary',
- text: '导出',
- onclick: onExport,
- limit: permissionStatus('none', '${moduleName.toUpperCase()}_${businessName.toUpperCase()}_EXPORT_BT'),
- position: 'right',
- plain: true
- },
- #end
- {
- key: 'refresh',
- type: 'primary',
- text: '刷新',
- onclick: onRefresh,
- limit: 'none',
- position: 'left',
- plain: true
- }
- ]
- // 选中项的 ID 数组
- const ids = ref<string[]>([])
- // 多选框选中数据
- function handleSelectionChange(selection: ${ClassName}[]) {
- ids.value = selection
- .map(item => item.${pkColumn.javaField})
- .filter((id): id is string => id != null && id !== undefined)
- }
- // 搜索方法
- const onSearch = () => {
- setPageIndex(1)
- onLoadData()
- }
- // 重置方法
- const onReset = () => {
- queryFormRef.value?.resetFields()
- #foreach($column in $columns)
- #if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
- #set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
- state.queryData.begin${AttrName} = ''
- state.queryData.end${AttrName} = ''
- #end
- #end
- onPageChange(1)
- }
- // 每页显示条数变化
- const onSizeChange = (size: number) => {
- setPageSizes(size)
- onLoadData()
- }
- // 翻页查询
- const onPageChange = (currentPage: number) => {
- setPageIndex(currentPage)
- onLoadData()
- }
- // 弹框关闭方法
- function onDialogClosed() {
- state.dialogVisible = false
- resetForm()
- }
- // 重置表单
- function resetForm() {
- state.formData = {
- #foreach($column in $columns)
- $column.javaField: #if($column.htmlType == "checkbox")[]#elseif($column.javaType == 'Long' || $column.javaType == 'Integer')null#else''#end,
- #end
- #if($table.sub)
- ${subclassName}List: []
- #end
- } as ${ClassName}
- #if($table.sub)
- state.${subclassName}List = []
- #end
- dialogFormRef.value?.resetFields()
- }
- // 刷新方法
- function onRefresh() {
- onReset()
- }
- // 新增
- function onCreate() {
- resetForm()
- state.dialogVisible = true
- state.isEdit = true
- state.title = '新增${functionName}'
- }
- // 查看
- function onView(row: ${ClassName}) {
- state.viewForm = { ...row }
- state.viewDialogVisible = true
- state.viewTitle = '查看${functionName}详情'
- }
- // 编辑
- async function onEdit(row: ${ClassName}) {
- const res = await getDetail(row.${pkColumn.javaField})
- if (res.code === SuccessResultCode) {
- state.formData = res.data
- #foreach($column in $columns)
- #if($column.htmlType == "checkbox")
- if (state.formData.${column.javaField}) {
- state.formData.${column.javaField} = state.formData.${column.javaField}.split(',')
- } else {
- state.formData.${column.javaField} = []
- }
- #end
- #end
- #if($table.sub)
- state.${subclassName}List = res.data.${subclassName}List || []
- #end
- state.dialogVisible = true
- state.isEdit = true
- state.title = '修改${functionName}'
- } else {
- ElMessage.error(res.message || '数据获取异常')
- }
- }
- // 删除
- async function onDelete(row: ${ClassName}) {
- const deleteIds = row.${pkColumn.javaField} || ids.value
- if (!deleteIds || deleteIds.length === 0) {
- ElMessage.warning('请选择要删除的数据')
- return
- }
- try {
- await ElMessageBox.confirm('确定要删除选中的${functionName}吗?', '提示', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning'
- })
- const res = await remove(deleteIds)
- if (res.code === SuccessResultCode) {
- ElMessage.success('删除成功')
- onPageChange(1)
- } else {
- ElMessage.error(res.message || '删除失败')
- }
- } catch{
- // 用户取消删除
- }
- }
- #if($table.genTable.importTable)
- // 导入
- function onImport() {
- // TODO: 实现导入功能
- ElMessage.info('导入功能待实现')
- }
- // 导出
- function onExport() {
- // TODO: 实现导出功能
- ElMessage.info('导出功能待实现')
- }
- #end
- // 新增/修改提交
- async function onSubmit() {
- if (!dialogFormRef.value) return
- const isValid = await dialogFormRef.value.validate()
- if (!isValid) return
- try {
- #foreach($column in $columns)
- #if($column.htmlType == "checkbox")
- if (Array.isArray(state.formData.${column.javaField})) {
- state.formData.${column.javaField} = state.formData.${column.javaField}.join(',')
- }
- #end
- #end
- #if($table.sub)
- state.formData.${subclassName}List = state.${subclassName}List
- #end
- let res: Result<any>
- if (state.formData.${pkColumn.javaField}) {
- res = await update(state.formData)
- } else {
- res = await insert(state.formData)
- }
- if (res.code === SuccessResultCode) {
- ElMessage.success(state.formData.${pkColumn.javaField} ? '修改成功' : '新增成功')
- state.dialogVisible = false
- onPageChange(1)
- } else {
- ElMessage.error(res.message || '操作失败')
- }
- } catch (error) {
- console.error('提交失败:', error)
- ElMessage.error('操作失败')
- }
- }
- // 数据查询
- async function onLoadData() {
- setLoading(true)
- try {
- const query = {
- ...state.queryData,
- pageIndex: tablePagination.currentPage,
- pageSize: tablePagination.pageSize
- }
- const res = await getList(query)
- if (res.code === SuccessResultCode) {
- setPagination(res.data)
- } else {
- ElMessage.error(res.message || '查询失败')
- }
- } catch (error) {
- console.error('查询失败:', error)
- ElMessage.error('查询失败')
- } finally {
- setLoading(false)
- }
- }
- #if($table.sub)
- // 子表相关方法
- function row${subClassName}Index({ row, rowIndex }: any) {
- row.index = rowIndex + 1
- }
- function handleAdd${subClassName}() {
- const obj: any = {}
- #foreach($column in $subTable.columns)
- #if(!$column.pk && $column.javaField != ${subTableFkclassName})
- obj.${column.javaField} = ''
- #end
- #end
- state.${subclassName}List.push(obj)
- }
- function handleDelete${subClassName}() {
- if (state.checked${subClassName}.length === 0) {
- ElMessage.warning('请先选择要删除的数据')
- return
- }
- state.${subclassName}List = state.${subclassName}List.filter(item =>
- !state.checked${subClassName}.includes(item.index)
- )
- state.checked${subClassName} = []
- }
- function handle${subClassName}SelectionChange(selection: any[]) {
- state.checked${subClassName} = selection.map(item => item.index)
- }
- #end
- // 组件挂载时加载数据
- onMounted(() => {
- onLoadData()
- })
- </script>
- <style scoped>
- /* 自定义样式 */
- </style>
|