first commit
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
package top.ysoft.admin.controller.${subPackageName};
|
||||
|
||||
import top.continew.starter.extension.crud.enums.Api;
|
||||
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import top.continew.starter.extension.crud.annotation.CrudRequestMapping;
|
||||
import top.ysoft.admin.common.controller.BaseController;
|
||||
import ${packageName}.model.query.${classNamePrefix}Query;
|
||||
import ${packageName}.model.req.${classNamePrefix}Req;
|
||||
import ${packageName}.model.resp.${classNamePrefix}DetailResp;
|
||||
import ${packageName}.model.resp.${classNamePrefix}Resp;
|
||||
import ${packageName}.service.${classNamePrefix}Service;
|
||||
|
||||
/**
|
||||
* ${businessName}管理 API
|
||||
*
|
||||
* @author ${author}
|
||||
* @since ${datetime}
|
||||
*/
|
||||
@Tag(name = "${businessName}管理 API")
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@CrudRequestMapping(value = "/${apiModuleName}/${apiName}", api = {Api.PAGE, Api.DETAIL, Api.ADD, Api.UPDATE, Api.DELETE, Api.EXPORT})
|
||||
public class ${className} extends BaseController<${classNamePrefix}Service, ${classNamePrefix}Resp, ${classNamePrefix}Resp, ${classNamePrefix}Query, ${classNamePrefix}Req> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package ${packageName}.${subPackageName};
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
|
||||
import top.ysoft.admin.common.model.resp.BaseDetailResp;
|
||||
|
||||
import java.io.Serial;
|
||||
<#if hasTimeField>
|
||||
import java.time.*;
|
||||
</#if>
|
||||
<#if hasBigDecimalField>
|
||||
import java.math.BigDecimal;
|
||||
</#if>
|
||||
|
||||
/**
|
||||
* ${businessName}详情信息
|
||||
*
|
||||
* @author ${author}
|
||||
* @since ${datetime}
|
||||
*/
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
@Schema(description = "${businessName}详情信息")
|
||||
public class ${className} extends BaseDetailResp {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
<#if fieldConfigs??>
|
||||
<#list fieldConfigs as fieldConfig>
|
||||
|
||||
/**
|
||||
* ${fieldConfig.comment}
|
||||
*/
|
||||
@Schema(description = "${fieldConfig.comment}")
|
||||
@ExcelProperty(value = "${fieldConfig.comment}")
|
||||
private ${fieldConfig.fieldType} ${fieldConfig.fieldName};
|
||||
</#list>
|
||||
</#if>
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package ${packageName}.${subPackageName};
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
|
||||
import top.ysoft.admin.common.model.entity.BaseDO;
|
||||
|
||||
import java.io.Serial;
|
||||
<#if hasTimeField>
|
||||
import java.time.*;
|
||||
</#if>
|
||||
<#if hasBigDecimalField>
|
||||
import java.math.BigDecimal;
|
||||
</#if>
|
||||
|
||||
/**
|
||||
* ${businessName}实体
|
||||
*
|
||||
* @author ${author}
|
||||
* @since ${datetime}
|
||||
*/
|
||||
@Data
|
||||
@TableName("${tableName}")
|
||||
public class ${className} extends BaseDO {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
<#if fieldConfigs??>
|
||||
<#list fieldConfigs as fieldConfig>
|
||||
|
||||
/**
|
||||
* ${fieldConfig.comment}
|
||||
*/
|
||||
private ${fieldConfig.fieldType} ${fieldConfig.fieldName};
|
||||
</#list>
|
||||
</#if>
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package ${packageName}.${subPackageName};
|
||||
|
||||
import top.continew.starter.data.mp.base.BaseMapper;
|
||||
import ${packageName}.model.entity.${classNamePrefix}DO;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
/**
|
||||
* ${businessName} Mapper
|
||||
*
|
||||
* @author ${author}
|
||||
* @since ${datetime}
|
||||
*/
|
||||
@Repository
|
||||
public interface ${className} extends BaseMapper<${classNamePrefix}DO> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
|
||||
<mapper namespace="${packageName}.mapper.${classNamePrefix}Mapper">
|
||||
</mapper>
|
||||
@@ -0,0 +1,41 @@
|
||||
SET @parentId = ${statics["cn.hutool.core.util.IdUtil"].getSnowflakeNextId()?c};
|
||||
-- ${businessName}管理菜单
|
||||
INSERT INTO `sys_menu`
|
||||
(`id`, `title`, `parent_id`, `type`, `path`, `name`, `component`, `redirect`, `icon`, `is_external`, `is_cache`, `is_hidden`, `permission`, `sort`, `status`, `create_user`, `create_time`)
|
||||
VALUES
|
||||
(@parentId, '${businessName}管理', 1000, 2, '/${apiModuleName}/${apiName}', '${classNamePrefix}', '${apiModuleName}/${apiName}/index', NULL, NULL, b'0', b'0', b'0', NULL, 1, 1, 1, NOW());
|
||||
|
||||
-- ${businessName}管理按钮
|
||||
INSERT INTO `sys_menu`
|
||||
(`id`, `title`, `parent_id`, `type`, `permission`, `sort`, `status`, `create_user`, `create_time`)
|
||||
VALUES
|
||||
(${statics["cn.hutool.core.util.IdUtil"].getSnowflakeNextId()?c}, '列表', @parentId, 3, '${apiModuleName}:${apiName}:list', 1, 1, 1, NOW()),
|
||||
(${statics["cn.hutool.core.util.IdUtil"].getSnowflakeNextId()?c}, '详情', @parentId, 3, '${apiModuleName}:${apiName}:detail', 2, 1, 1, NOW()),
|
||||
(${statics["cn.hutool.core.util.IdUtil"].getSnowflakeNextId()?c}, '新增', @parentId, 3, '${apiModuleName}:${apiName}:add', 3, 1, 1, NOW()),
|
||||
(${statics["cn.hutool.core.util.IdUtil"].getSnowflakeNextId()?c}, '修改', @parentId, 3, '${apiModuleName}:${apiName}:update', 4, 1, 1, NOW()),
|
||||
(${statics["cn.hutool.core.util.IdUtil"].getSnowflakeNextId()?c}, '删除', @parentId, 3, '${apiModuleName}:${apiName}:delete', 5, 1, 1, NOW()),
|
||||
(${statics["cn.hutool.core.util.IdUtil"].getSnowflakeNextId()?c}, '导出', @parentId, 3, '${apiModuleName}:${apiName}:export', 6, 1, 1, NOW());
|
||||
|
||||
<#---- PostgreSQL(切换 PostgreSQL 数据库时请注释掉其他数据库脚本,并解开此段注释)-->
|
||||
<#--DO $$-->
|
||||
<#-- DECLARE sys_menu_id_seq INT8 := ${statics["cn.hutool.core.util.IdUtil"].getSnowflakeNextId()?c};-->
|
||||
<#--BEGIN-->
|
||||
|
||||
<#-- -- ${businessName}管理菜单-->
|
||||
<#-- INSERT INTO "sys_menu"-->
|
||||
<#-- ("id", "title", "parent_id", "type", "path", "name", "component", "redirect", "icon", "is_external", "is_cache", "is_hidden", "permission", "sort", "status", "create_user", "create_time")-->
|
||||
<#-- VALUES-->
|
||||
<#-- (sys_menu_id_seq, '${businessName}管理', 1000, 2, '/${apiModuleName}/${apiName}', '${classNamePrefix}', '${apiModuleName}/${apiName}/index', NULL, NULL, false, false, false, NULL, 1, 1, 1, NOW());-->
|
||||
|
||||
<#-- -- ${businessName}管理按钮-->
|
||||
<#-- INSERT INTO "sys_menu"-->
|
||||
<#-- ("id", "title", "parent_id", "type", "permission", "sort", "status", "create_user", "create_time")-->
|
||||
<#-- VALUES-->
|
||||
<#-- (${statics["cn.hutool.core.util.IdUtil"].getSnowflakeNextId()?c}, '列表', sys_menu_id_seq, 3, '${apiModuleName}:${apiName}:list', 1, 1, 1, NOW()),-->
|
||||
<#-- (${statics["cn.hutool.core.util.IdUtil"].getSnowflakeNextId()?c}, '详情', sys_menu_id_seq, 3, '${apiModuleName}:${apiName}:detail', 2, 1, 1, NOW()),-->
|
||||
<#-- (${statics["cn.hutool.core.util.IdUtil"].getSnowflakeNextId()?c}, '新增', sys_menu_id_seq, 3, '${apiModuleName}:${apiName}:add', 3, 1, 1, NOW()),-->
|
||||
<#-- (${statics["cn.hutool.core.util.IdUtil"].getSnowflakeNextId()?c}, '修改', sys_menu_id_seq, 3, '${apiModuleName}:${apiName}:update', 4, 1, 1, NOW()),-->
|
||||
<#-- (${statics["cn.hutool.core.util.IdUtil"].getSnowflakeNextId()?c}, '删除', sys_menu_id_seq, 3, '${apiModuleName}:${apiName}:delete', 5, 1, 1, NOW()),-->
|
||||
<#-- (${statics["cn.hutool.core.util.IdUtil"].getSnowflakeNextId()?c}, '导出', sys_menu_id_seq, 3, '${apiModuleName}:${apiName}:export', 6, 1, 1, NOW());-->
|
||||
|
||||
<#--END $$;-->
|
||||
@@ -0,0 +1,48 @@
|
||||
package ${packageName}.${subPackageName};
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
import top.continew.starter.data.core.annotation.Query;
|
||||
import top.continew.starter.data.core.enums.QueryType;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
<#if hasTimeField>
|
||||
import java.time.*;
|
||||
</#if>
|
||||
<#if hasBigDecimalField>
|
||||
import java.math.BigDecimal;
|
||||
</#if>
|
||||
|
||||
/**
|
||||
* ${businessName}查询条件
|
||||
*
|
||||
* @author ${author}
|
||||
* @since ${datetime}
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "${businessName}查询条件")
|
||||
public class ${className} implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
<#if fieldConfigs??>
|
||||
<#list fieldConfigs as fieldConfig>
|
||||
<#if fieldConfig.showInQuery>
|
||||
|
||||
/**
|
||||
* ${fieldConfig.comment}
|
||||
*/
|
||||
@Schema(description = "${fieldConfig.comment}")
|
||||
@Query(type = QueryType.${fieldConfig.queryType})
|
||||
<#if fieldConfig.queryType = 'IN' || fieldConfig.queryType = 'NOT_IN' || fieldConfig.queryType = 'BETWEEN'>
|
||||
private ${fieldConfig.fieldType}[] ${fieldConfig.fieldName};
|
||||
<#else>
|
||||
private ${fieldConfig.fieldType} ${fieldConfig.fieldName};
|
||||
</#if>
|
||||
</#if>
|
||||
</#list>
|
||||
</#if>
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package ${packageName}.${subPackageName};
|
||||
|
||||
<#if hasRequiredField>
|
||||
import jakarta.validation.constraints.*;
|
||||
</#if>
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
import org.hibernate.validator.constraints.Length;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
<#if hasTimeField>
|
||||
import java.time.*;
|
||||
</#if>
|
||||
<#if hasBigDecimalField>
|
||||
import java.math.BigDecimal;
|
||||
</#if>
|
||||
|
||||
/**
|
||||
* 创建或修改${businessName}参数
|
||||
*
|
||||
* @author ${author}
|
||||
* @since ${datetime}
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "创建或修改${businessName}参数")
|
||||
public class ${className} implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
<#if fieldConfigs??>
|
||||
<#list fieldConfigs as fieldConfig>
|
||||
<#if fieldConfig.showInForm>
|
||||
|
||||
/**
|
||||
* ${fieldConfig.comment}
|
||||
*/
|
||||
@Schema(description = "${fieldConfig.comment}")
|
||||
<#if fieldConfig.isRequired>
|
||||
<#if fieldConfig.fieldType = 'String'>
|
||||
@NotBlank(message = "${fieldConfig.comment}不能为空")
|
||||
<#else>
|
||||
@NotNull(message = "${fieldConfig.comment}不能为空")
|
||||
</#if>
|
||||
</#if>
|
||||
<#if fieldConfig.fieldType = 'String' && fieldConfig.columnSize??>
|
||||
@Length(max = ${fieldConfig.columnSize?c}, message = "${fieldConfig.comment}长度不能超过 {max} 个字符")
|
||||
</#if>
|
||||
private ${fieldConfig.fieldType} ${fieldConfig.fieldName};
|
||||
</#if>
|
||||
</#list>
|
||||
</#if>
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package ${packageName}.${subPackageName};
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
import top.ysoft.admin.common.model.resp.BaseDetailResp;
|
||||
|
||||
import java.io.Serial;
|
||||
<#if hasTimeField>
|
||||
import java.time.*;
|
||||
</#if>
|
||||
<#if hasBigDecimalField>
|
||||
import java.math.BigDecimal;
|
||||
</#if>
|
||||
|
||||
/**
|
||||
* ${businessName}信息
|
||||
*
|
||||
* @author ${author}
|
||||
* @since ${datetime}
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "${businessName}信息")
|
||||
public class ${className} extends BaseDetailResp {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
<#if fieldConfigs??>
|
||||
<#list fieldConfigs as fieldConfig>
|
||||
<#if fieldConfig.showInList>
|
||||
|
||||
/**
|
||||
* ${fieldConfig.comment}
|
||||
*/
|
||||
@Schema(description = "${fieldConfig.comment}")
|
||||
private ${fieldConfig.fieldType} ${fieldConfig.fieldName};
|
||||
</#if>
|
||||
</#list>
|
||||
</#if>
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package ${packageName}.${subPackageName};
|
||||
|
||||
import top.continew.starter.extension.crud.service.BaseService;
|
||||
import ${packageName}.model.query.${classNamePrefix}Query;
|
||||
import ${packageName}.model.req.${classNamePrefix}Req;
|
||||
import ${packageName}.model.resp.${classNamePrefix}DetailResp;
|
||||
import ${packageName}.model.resp.${classNamePrefix}Resp;
|
||||
|
||||
/**
|
||||
* ${businessName}业务接口
|
||||
*
|
||||
* @author ${author}
|
||||
* @since ${datetime}
|
||||
*/
|
||||
public interface ${className} extends BaseService<${classNamePrefix}Resp, ${classNamePrefix}Resp, ${classNamePrefix}Query, ${classNamePrefix}Req> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package ${packageName}.${subPackageName};
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import top.continew.starter.extension.crud.service.BaseServiceImpl;
|
||||
import ${packageName}.mapper.${classNamePrefix}Mapper;
|
||||
import ${packageName}.model.entity.${classNamePrefix}DO;
|
||||
import ${packageName}.model.query.${classNamePrefix}Query;
|
||||
import ${packageName}.model.req.${classNamePrefix}Req;
|
||||
import ${packageName}.model.resp.${classNamePrefix}DetailResp;
|
||||
import ${packageName}.model.resp.${classNamePrefix}Resp;
|
||||
import ${packageName}.service.${classNamePrefix}Service;
|
||||
|
||||
/**
|
||||
* ${businessName}业务实现
|
||||
*
|
||||
* @author ${author}
|
||||
* @since ${datetime}
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class ${className} extends BaseServiceImpl<${classNamePrefix}Mapper, ${classNamePrefix}DO, ${classNamePrefix}Resp, ${classNamePrefix}Resp, ${classNamePrefix}Query, ${classNamePrefix}Req> implements ${classNamePrefix}Service {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
<template>
|
||||
<a-modal
|
||||
v-model:visible="visible"
|
||||
:title="title"
|
||||
:mask-closable="false"
|
||||
:esc-to-close="false"
|
||||
:width="width >= 600 ? 600 : '100%'"
|
||||
draggable
|
||||
@before-ok="save"
|
||||
@close="reset"
|
||||
>
|
||||
<GiForm ref="formRef" v-model="form" :columns="columns" />
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Message } from '@arco-design/web-vue'
|
||||
import { useWindowSize } from '@vueuse/core'
|
||||
import { get${classNamePrefix}, add${classNamePrefix}, update${classNamePrefix} } from '@/apis/${apiModuleName}/${apiName}'
|
||||
import { type ColumnItem, GiForm } from '@/components/GiForm'
|
||||
import { useResetReactive } from '@/hooks'
|
||||
import { useDict } from '@/hooks/app'
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'save-success'): void
|
||||
}>()
|
||||
|
||||
const { width } = useWindowSize()
|
||||
|
||||
const dataId = ref('')
|
||||
const visible = ref(false)
|
||||
const isUpdate = computed(() => !!dataId.value)
|
||||
const title = computed(() => (isUpdate.value ? '修改${businessName}' : '新增${businessName}'))
|
||||
const formRef = ref<InstanceType<typeof GiForm>>()
|
||||
<#if hasDictField>
|
||||
const { <#list dictCodes as dictCode>${dictCode}<#if dictCode_has_next>,</#if></#list> } = useDict(<#list dictCodes as dictCode>'${dictCode}'<#if dictCode_has_next>,</#if></#list>)
|
||||
</#if>
|
||||
|
||||
const [form, resetForm] = useResetReactive({
|
||||
// todo 待补充
|
||||
})
|
||||
|
||||
const columns: ColumnItem[] = reactive([
|
||||
<#list fieldConfigs as fieldConfig>
|
||||
<#if fieldConfig.showInForm>
|
||||
{
|
||||
label: '${fieldConfig.comment}',
|
||||
field: '${fieldConfig.fieldName}',
|
||||
<#if fieldConfig.formType = 'INPUT'>
|
||||
type: 'input',
|
||||
<#elseif fieldConfig.formType = 'TEXT_AREA'>
|
||||
type: 'textarea',
|
||||
props: {
|
||||
autoSize: true
|
||||
},
|
||||
<#elseif fieldConfig.formType = 'DATE'>
|
||||
type: 'date-picker',
|
||||
<#elseif fieldConfig.formType = 'DATE_TIME'>
|
||||
type: 'date-picker',
|
||||
props: {
|
||||
<#if fieldConfig.dictCode?? && fieldConfig.dictCode != ''>
|
||||
options: ${fieldConfig.dictCode},
|
||||
</#if>
|
||||
showTime: true,
|
||||
},
|
||||
<#elseif fieldConfig.formType = 'TIME'>
|
||||
type: 'time-picker',
|
||||
<#elseif fieldConfig.formType = 'INPUT_NUMBER'>
|
||||
type: 'input-number',
|
||||
<#elseif fieldConfig.formType = 'INPUT_PASSWORD'>
|
||||
type: 'input-password',
|
||||
<#elseif fieldConfig.formType = 'SWITCH'>
|
||||
type: 'switch',
|
||||
<#elseif fieldConfig.formType = 'CHECK_BOX'>
|
||||
type: 'checkbox-group',
|
||||
<#elseif fieldConfig.formType = 'TREE_SELECT'>
|
||||
type: 'tree-select',
|
||||
<#elseif fieldConfig.formType = 'SELECT'>
|
||||
type: 'select',
|
||||
<#elseif fieldConfig.formType = 'RADIO'>
|
||||
type: 'radio-group',
|
||||
</#if>
|
||||
span: 24,
|
||||
<#if fieldConfig.isRequired>
|
||||
required: true,
|
||||
</#if>
|
||||
<#if fieldConfig.dictCode?? && fieldConfig.dictCode != ''>
|
||||
props: {
|
||||
options: ${fieldConfig.dictCode},
|
||||
},
|
||||
</#if>
|
||||
},
|
||||
</#if>
|
||||
</#list>
|
||||
])
|
||||
|
||||
// 重置
|
||||
const reset = () => {
|
||||
formRef.value?.formRef?.resetFields()
|
||||
resetForm()
|
||||
}
|
||||
|
||||
// 保存
|
||||
const save = async () => {
|
||||
try {
|
||||
const isInvalid = await formRef.value?.formRef?.validate()
|
||||
if (isInvalid) return false
|
||||
if (isUpdate.value) {
|
||||
await update${classNamePrefix}(form, dataId.value)
|
||||
Message.success('修改成功')
|
||||
} else {
|
||||
await add${classNamePrefix}(form)
|
||||
Message.success('新增成功')
|
||||
}
|
||||
emit('save-success')
|
||||
return true
|
||||
} catch (error) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 新增
|
||||
const onAdd = async () => {
|
||||
reset()
|
||||
dataId.value = ''
|
||||
visible.value = true
|
||||
}
|
||||
|
||||
// 修改
|
||||
const onUpdate = async (id: string) => {
|
||||
reset()
|
||||
dataId.value = id
|
||||
const { data } = await get${classNamePrefix}(id)
|
||||
Object.assign(form, data)
|
||||
visible.value = true
|
||||
}
|
||||
|
||||
defineExpose({ onAdd, onUpdate })
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
@@ -0,0 +1,42 @@
|
||||
<template>
|
||||
<a-drawer v-model:visible="visible" title="${businessName}详情" :width="width >= 600 ? 600 : '100%'" :footer="false">
|
||||
<a-descriptions :column="2" size="large" class="general-description">
|
||||
<#list fieldConfigs as fieldConfig>
|
||||
<a-descriptions-item label="${fieldConfig.comment}">{{ dataDetail?.${fieldConfig.fieldName} }}</a-descriptions-item>
|
||||
<#if fieldConfig.fieldName = 'createUser'>
|
||||
<a-descriptions-item label="创建人">{{ dataDetail?.createUserString }}</a-descriptions-item>
|
||||
<#elseif fieldConfig.fieldName = 'updateUser'>
|
||||
<a-descriptions-item label="修改人">{{ dataDetail?.updateUserString }}</a-descriptions-item>
|
||||
</#if>
|
||||
</#list>
|
||||
</a-descriptions>
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useWindowSize } from '@vueuse/core'
|
||||
import { type ${classNamePrefix}DetailResp, get${classNamePrefix} as getDetail } from '@/apis/${apiModuleName}/${apiName}'
|
||||
|
||||
const { width } = useWindowSize()
|
||||
|
||||
const dataId = ref('')
|
||||
const dataDetail = ref<${classNamePrefix}DetailResp>()
|
||||
const visible = ref(false)
|
||||
|
||||
// 查询详情
|
||||
const getDataDetail = async () => {
|
||||
const { data } = await getDetail(dataId.value)
|
||||
dataDetail.value = data
|
||||
}
|
||||
|
||||
// 打开
|
||||
const onOpen = async (id: string) => {
|
||||
dataId.value = id
|
||||
await getDataDetail()
|
||||
visible.value = true
|
||||
}
|
||||
|
||||
defineExpose({ onOpen })
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
@@ -0,0 +1,57 @@
|
||||
import http from '@/utils/http'
|
||||
|
||||
const BASE_URL = '/${apiModuleName}/${apiName}'
|
||||
|
||||
export interface ${classNamePrefix}Resp {
|
||||
<#if fieldConfigs??>
|
||||
<#list fieldConfigs as fieldConfig>
|
||||
<#if fieldConfig.showInList>
|
||||
${fieldConfig.fieldName}: string
|
||||
</#if>
|
||||
</#list>
|
||||
createUserString: string
|
||||
updateUserString: string
|
||||
disabled: boolean
|
||||
</#if>
|
||||
}
|
||||
export interface ${classNamePrefix}Query {
|
||||
<#if fieldConfigs??>
|
||||
<#list fieldConfigs as fieldConfig>
|
||||
<#if fieldConfig.showInQuery>
|
||||
${fieldConfig.fieldName}: string | undefined
|
||||
</#if>
|
||||
</#list>
|
||||
</#if>
|
||||
sort: Array<string>
|
||||
}
|
||||
export interface ${classNamePrefix}PageQuery extends ${classNamePrefix}Query, PageQuery {}
|
||||
|
||||
/** @desc 查询${businessName}列表 */
|
||||
export function list${classNamePrefix}(query: ${classNamePrefix}PageQuery) {
|
||||
return http.get<PageRes<${classNamePrefix}Resp[]>>(`${'$'}{BASE_URL}`, query)
|
||||
}
|
||||
|
||||
/** @desc 查询${businessName}详情 */
|
||||
export function get${classNamePrefix}(id: string) {
|
||||
return http.get<${classNamePrefix}DetailResp>(`${'$'}{BASE_URL}/${'$'}{id}`)
|
||||
}
|
||||
|
||||
/** @desc 新增${businessName} */
|
||||
export function add${classNamePrefix}(data: any) {
|
||||
return http.post(`${'$'}{BASE_URL}`, data)
|
||||
}
|
||||
|
||||
/** @desc 修改${businessName} */
|
||||
export function update${classNamePrefix}(data: any, id: string) {
|
||||
return http.put(`${'$'}{BASE_URL}/${'$'}{id}`, data)
|
||||
}
|
||||
|
||||
/** @desc 删除${businessName} */
|
||||
export function delete${classNamePrefix}(id: string) {
|
||||
return http.del(`${'$'}{BASE_URL}/${'$'}{id}`)
|
||||
}
|
||||
|
||||
/** @desc 导出${businessName} */
|
||||
export function export${classNamePrefix}(query: ${classNamePrefix}Query) {
|
||||
return http.download(`${'$'}{BASE_URL}/export`, query)
|
||||
}
|
||||
@@ -0,0 +1,202 @@
|
||||
<template>
|
||||
<div class="gi_table_page">
|
||||
<GiTable
|
||||
title="${businessName}管理"
|
||||
row-key="id"
|
||||
:data="dataList"
|
||||
:columns="columns"
|
||||
:loading="loading"
|
||||
:scroll="{ x: '100%', y: '100%', minWidth: 1000 }"
|
||||
:pagination="pagination"
|
||||
:disabled-tools="['size']"
|
||||
:disabled-column-keys="['name']"
|
||||
@refresh="search"
|
||||
>
|
||||
<#-- 查询字段配置 -->
|
||||
<template #toolbar-left>
|
||||
<#list fieldConfigs as fieldConfig>
|
||||
<#if fieldConfig.showInQuery>
|
||||
<#if fieldConfig.formType == "SELECT"><#-- 下拉框 -->
|
||||
<a-select
|
||||
v-model="queryForm.${fieldConfig.fieldName}"
|
||||
:options="${fieldConfig.dictCode}"
|
||||
placeholder="请选择${fieldConfig.comment}"
|
||||
allow-clear
|
||||
style="width: 150px"
|
||||
@change="search"
|
||||
/>
|
||||
<#elseif fieldConfig.formType == "RADIO"><#-- 单选框 -->
|
||||
<a-radio-group v-model="queryForm.${fieldConfig.fieldName}" :options="${fieldConfig.dictCode!'dictKey 或者自定义数组'}" @change="search"/>
|
||||
<#elseif fieldConfig.formType == "DATE"><#-- 日期框 -->
|
||||
<#if fieldConfig.queryType == "BETWEEN">
|
||||
<DateRangePicker v-model="queryForm.${fieldConfig.fieldName}" format="YYYY-MM-DD" @change="search" />
|
||||
<#else>
|
||||
<a-date-picker
|
||||
v-model="queryForm.${fieldConfig.fieldName}"
|
||||
placeholder="请选择${fieldConfig.comment}"
|
||||
format="YYYY-MM-DD"
|
||||
style="height: 32px"
|
||||
/>
|
||||
</#if>
|
||||
<#elseif fieldConfig.formType == "DATE_TIME"><#-- 日期时间框 -->
|
||||
<#if fieldConfig.queryType == "BETWEEN">
|
||||
<DateRangePicker v-model="queryForm.${fieldConfig.fieldName}" @change="search" />
|
||||
<#else>
|
||||
<a-date-picker
|
||||
v-model="queryForm.${fieldConfig.fieldName}"
|
||||
placeholder="请选择${fieldConfig.comment}"
|
||||
show-time
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
style="height: 32px"
|
||||
/>
|
||||
</#if>
|
||||
<#else>
|
||||
<a-input-search v-model="queryForm.${fieldConfig.fieldName}" placeholder="请输入${fieldConfig.comment}" allow-clear @search="search" />
|
||||
</#if>
|
||||
</#if>
|
||||
</#list>
|
||||
<a-button @click="reset">
|
||||
<template #icon><icon-refresh /></template>
|
||||
<template #default>重置</template>
|
||||
</a-button>
|
||||
</template>
|
||||
<template #toolbar-right>
|
||||
<a-button v-permission="['${apiModuleName}:${apiName}:add']" type="primary" @click="onAdd">
|
||||
<template #icon><icon-plus /></template>
|
||||
<template #default>新增</template>
|
||||
</a-button>
|
||||
<a-button v-permission="['${apiModuleName}:${apiName}:export']" @click="onExport">
|
||||
<template #icon><icon-download /></template>
|
||||
<template #default>导出</template>
|
||||
</a-button>
|
||||
</template>
|
||||
<#list fieldConfigs as fieldConfig>
|
||||
<#if fieldConfig.showInList>
|
||||
<#if fieldConfig.dictCode?? && fieldConfig.dictCode != "">
|
||||
<template #${fieldConfig.fieldName}="{ record }">
|
||||
<GiCellTag :value="record.${fieldConfig.fieldName}" :dict="${fieldConfig.dictCode}" />
|
||||
</template>
|
||||
</#if>
|
||||
</#if>
|
||||
</#list>
|
||||
<template #action="{ record }">
|
||||
<a-space>
|
||||
<a-link v-permission="['${apiModuleName}:${apiName}:detail']" title="详情" @click="onDetail(record)">详情</a-link>
|
||||
<a-link v-permission="['${apiModuleName}:${apiName}:update']" title="修改" @click="onUpdate(record)">修改</a-link>
|
||||
<a-link
|
||||
v-permission="['${apiModuleName}:${apiName}:delete']"
|
||||
status="danger"
|
||||
:disabled="record.disabled"
|
||||
:title="record.disabled ? '不可删除' : '删除'"
|
||||
@click="onDelete(record)"
|
||||
>
|
||||
删除
|
||||
</a-link>
|
||||
</a-space>
|
||||
</template>
|
||||
</GiTable>
|
||||
|
||||
<${classNamePrefix}AddModal ref="${classNamePrefix}AddModalRef" @save-success="search" />
|
||||
<${classNamePrefix}DetailDrawer ref="${classNamePrefix}DetailDrawerRef" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import ${classNamePrefix}AddModal from './${classNamePrefix}AddModal.vue'
|
||||
import ${classNamePrefix}DetailDrawer from './${classNamePrefix}DetailDrawer.vue'
|
||||
import { type ${classNamePrefix}Resp, type ${classNamePrefix}Query, delete${classNamePrefix}, export${classNamePrefix}, list${classNamePrefix} } from '@/apis/${apiModuleName}/${apiName}'
|
||||
import type { TableInstanceColumns } from '@/components/GiTable/type'
|
||||
import { useDownload, useTable } from '@/hooks'
|
||||
import { useDict } from '@/hooks/app'
|
||||
import { isMobile } from '@/utils'
|
||||
import has from '@/utils/has'
|
||||
|
||||
defineOptions({ name: '${classNamePrefix}' })
|
||||
|
||||
<#if hasDictField>
|
||||
const { <#list dictCodes as dictCode>${dictCode}<#if dictCode_has_next>,</#if></#list> } = useDict(<#list dictCodes as dictCode>'${dictCode}'<#if dictCode_has_next>,</#if></#list>)
|
||||
</#if>
|
||||
|
||||
const queryForm = reactive<${classNamePrefix}Query>({
|
||||
<#list fieldConfigs as fieldConfig>
|
||||
<#if fieldConfig.showInQuery>
|
||||
${fieldConfig.fieldName}: undefined,
|
||||
</#if>
|
||||
</#list>
|
||||
sort: ['id,desc']
|
||||
})
|
||||
|
||||
const {
|
||||
tableData: dataList,
|
||||
loading,
|
||||
pagination,
|
||||
search,
|
||||
handleDelete
|
||||
} = useTable((page) => list${classNamePrefix}({ ...queryForm, ...page }), { immediate: true })
|
||||
const columns = ref<TableInstanceColumns[]>([
|
||||
<#if fieldConfigs??>
|
||||
<#list fieldConfigs as fieldConfig>
|
||||
<#if fieldConfig.showInList>
|
||||
<#if fieldConfig.fieldName=="createUser" >
|
||||
{ title: '${fieldConfig.comment}', dataIndex: 'createUserString', slotName: '${fieldConfig.fieldName}' },
|
||||
<#elseif fieldConfig.fieldName=="updateUser" >
|
||||
{ title: '${fieldConfig.comment}', dataIndex: 'updateUserString', slotName: '${fieldConfig.fieldName}' },
|
||||
<#else>
|
||||
{ title: '${fieldConfig.comment}', dataIndex: '${fieldConfig.fieldName}', slotName: '${fieldConfig.fieldName}' },
|
||||
</#if>
|
||||
</#if>
|
||||
</#list>
|
||||
</#if>
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'action',
|
||||
slotName: 'action',
|
||||
width: 160,
|
||||
align: 'center',
|
||||
fixed: !isMobile() ? 'right' : undefined,
|
||||
show: has.hasPermOr(['${apiModuleName}:${apiName}:detail', '${apiModuleName}:${apiName}:update', '${apiModuleName}:${apiName}:delete'])
|
||||
}
|
||||
]);
|
||||
|
||||
// 重置
|
||||
const reset = () => {
|
||||
<#list fieldConfigs as fieldConfig>
|
||||
<#if fieldConfig.showInQuery>
|
||||
queryForm.${fieldConfig.fieldName} = undefined
|
||||
</#if>
|
||||
</#list>
|
||||
search()
|
||||
}
|
||||
|
||||
// 删除
|
||||
const onDelete = (record: ${classNamePrefix}Resp) => {
|
||||
return handleDelete(() => delete${classNamePrefix}(record.id), {
|
||||
content: `是否确定删除该条数据?`,
|
||||
showModal: true
|
||||
})
|
||||
}
|
||||
|
||||
// 导出
|
||||
const onExport = () => {
|
||||
useDownload(() => export${classNamePrefix}(queryForm))
|
||||
}
|
||||
|
||||
const ${classNamePrefix}AddModalRef = ref<InstanceType<typeof ${classNamePrefix}AddModal>>()
|
||||
// 新增
|
||||
const onAdd = () => {
|
||||
${classNamePrefix}AddModalRef.value?.onAdd()
|
||||
}
|
||||
|
||||
// 修改
|
||||
const onUpdate = (record: ${classNamePrefix}Resp) => {
|
||||
${classNamePrefix}AddModalRef.value?.onUpdate(record.id)
|
||||
}
|
||||
|
||||
const ${classNamePrefix}DetailDrawerRef = ref<InstanceType<typeof ${classNamePrefix}DetailDrawer>>()
|
||||
// 详情
|
||||
const onDetail = (record: ${classNamePrefix}Resp) => {
|
||||
${classNamePrefix}DetailDrawerRef.value?.onOpen(record.id)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
Reference in New Issue
Block a user