diff --git a/{{cookiecutter.project_slug}}/ManagerUI/package.json b/{{cookiecutter.project_slug}}/ManagerUI/package.json
index b73bade..0c33a1b 100644
--- a/{{cookiecutter.project_slug}}/ManagerUI/package.json
+++ b/{{cookiecutter.project_slug}}/ManagerUI/package.json
@@ -14,6 +14,15 @@
},
"dependencies": {
"@ant-design/icons-vue": "^7.0.1",
+ "@fortawesome/fontawesome-free": "6.7.2",
+ "amis": "6.12.0",
+ "amis-core": "6.12.0",
+ "amis-editor": "6.12.0",
+ "amis-editor-core": "6.12.0",
+ "amis-formula": "6.12.0",
+ "amis-theme-editor": "2.0.10",
+ "amis-theme-editor-helper": "2.0.27",
+ "amis-ui": "6.12.0",
"ant-design-vue": "^4.2.6",
"axios": "^1.8.4",
"dayjs": "^1.11.13",
@@ -21,10 +30,16 @@
"jsencrypt": "^3.3.2",
"jwt-decode": "^4.0.0",
"lodash": "^4.17.21",
+ "mobx": "^4.15.7",
+ "mobx-react": "^6.3.1",
+ "mobx-state-tree": "3.17.3",
"pinia": "^3.0.2",
"pinia-plugin-persistedstate": "^4.2.0",
"qs": "^6.14.0",
+ "react": "^16.14.0",
+ "react-dom": "^16.14.0",
"tree-lodash": "^0.4.0",
+ "veaury": "^2.6.2",
"vue": "^3.5.13",
"vue-request": "^2.0.4",
"vue-router": "^4.5.0"
@@ -46,6 +61,7 @@
"vite": "^6.3.2",
"vite-plugin-compression": "^0.5.1",
"vite-plugin-html": "^3.2.2",
+ "vite-plugin-static-copy": "^3.0.0",
"vite-plugin-vue-devtools": "^7.7.5"
}
}
diff --git a/{{cookiecutter.project_slug}}/ManagerUI/src/components/Layout/LayoutIndex.vue b/{{cookiecutter.project_slug}}/ManagerUI/src/components/Layout/LayoutIndex.vue
index 79e6c2f..90b15ed 100644
--- a/{{cookiecutter.project_slug}}/ManagerUI/src/components/Layout/LayoutIndex.vue
+++ b/{{cookiecutter.project_slug}}/ManagerUI/src/components/Layout/LayoutIndex.vue
@@ -174,7 +174,6 @@ const { data: messages } = useRequest(fetchMessage, {
.content {
height: calc(100vh - 64px - 20px);
margin: 10px;
- padding: 24px;
background-color: white;
overflow-y: auto;
}
diff --git a/{{cookiecutter.project_slug}}/ManagerUI/src/router/index.js b/{{cookiecutter.project_slug}}/ManagerUI/src/router/index.js
index 1793cd0..a5e5b7e 100644
--- a/{{cookiecutter.project_slug}}/ManagerUI/src/router/index.js
+++ b/{{cookiecutter.project_slug}}/ManagerUI/src/router/index.js
@@ -42,6 +42,11 @@ const router = createRouter({
meta: { needLogin: true, needMenu: true },
component: () => import('@/views/TenantView.vue'),
},
+ {
+ path: '/system/page',
+ meta: {needLogin: true, needMenu: true},
+ component: () => import('@/views/PageView.vue'),
+ },
{
path: '/system/logger',
meta: { needLogin: true, needMenu: true },
@@ -74,6 +79,14 @@ const router = createRouter({
},
],
},
+ {
+ path: '/page/designer',
+ component: () => import('@/views/lowcode/AmisDesignerView.vue'),
+ },
+ {
+ path: '/page/render',
+ component: () => import('@/views/lowcode/AmisRenderView.vue'),
+ },
],
})
diff --git a/{{cookiecutter.project_slug}}/ManagerUI/src/views/AccountView.vue b/{{cookiecutter.project_slug}}/ManagerUI/src/views/AccountView.vue
index 2dedf36..91e8c9f 100644
--- a/{{cookiecutter.project_slug}}/ManagerUI/src/views/AccountView.vue
+++ b/{{cookiecutter.project_slug}}/ManagerUI/src/views/AccountView.vue
@@ -552,6 +552,8 @@ const roleOpt = computed({
diff --git a/{{cookiecutter.project_slug}}/ManagerUI/src/views/RoleView.vue b/{{cookiecutter.project_slug}}/ManagerUI/src/views/RoleView.vue
index 428217b..f486017 100644
--- a/{{cookiecutter.project_slug}}/ManagerUI/src/views/RoleView.vue
+++ b/{{cookiecutter.project_slug}}/ManagerUI/src/views/RoleView.vue
@@ -501,6 +501,8 @@ const treeAuth = computed(() => fromArray(authorityOpts.value, { parentKey: 'par
diff --git a/{{cookiecutter.project_slug}}/ManagerUI/src/views/lowcode/AmisRenderView.vue b/{{cookiecutter.project_slug}}/ManagerUI/src/views/lowcode/AmisRenderView.vue
new file mode 100644
index 0000000..384f879
--- /dev/null
+++ b/{{cookiecutter.project_slug}}/ManagerUI/src/views/lowcode/AmisRenderView.vue
@@ -0,0 +1,81 @@
+
+
+
+
+
+
+
+
+
diff --git a/{{cookiecutter.project_slug}}/ManagerUI/vite.config.js b/{{cookiecutter.project_slug}}/ManagerUI/vite.config.js
index c4fc1f8..7e4f942 100644
--- a/{{cookiecutter.project_slug}}/ManagerUI/vite.config.js
+++ b/{{cookiecutter.project_slug}}/ManagerUI/vite.config.js
@@ -10,11 +10,18 @@ import { AntDesignVueResolver } from 'unplugin-vue-components/resolvers'
import { createHtmlPlugin } from 'vite-plugin-html'
import viteCompression from 'vite-plugin-compression'
+import { viteStaticCopy } from 'vite-plugin-static-copy'
+
// https://vite.dev/config/
export default defineConfig(({ mode }) => {
// eslint-disable-next-line no-undef
const env = loadEnv(mode, process.cwd())
+ // 生产环境复制 Amis 的 SDK,开发环境按需引用
+ let copes = [{ src: 'node_modules/amis/sdk/*', dest: 'assets' }]
+ if (mode === 'development')
+ copes.push({ src: 'node_modules/amis/sdk/*', dest: 'node_modules/.vite/deps' })
+
return {
base: './',
build: {
@@ -70,6 +77,7 @@ export default defineConfig(({ mode }) => {
},
},
}),
+ viteStaticCopy({ targets: copes }),
],
server: {
proxy: {
diff --git a/{{cookiecutter.project_slug}}/pom.xml b/{{cookiecutter.project_slug}}/pom.xml
index dee4126..761c75c 100644
--- a/{{cookiecutter.project_slug}}/pom.xml
+++ b/{{cookiecutter.project_slug}}/pom.xml
@@ -27,6 +27,10 @@
org.springframework.boot
spring-boot-starter-cache
+
+ org.springframework.boot
+ spring-boot-starter-json
+
@@ -111,7 +115,7 @@
ltd.llvy
handler
- 1.0-SNAPSHOT
+ 1.0.2
{% elif cookiecutter.platform == "mysql" -%}
diff --git a/{{cookiecutter.project_slug}}/src/main/java/{{cookiecutter.__mvn_package}}/rest/controller/PageController.java b/{{cookiecutter.project_slug}}/src/main/java/{{cookiecutter.__mvn_package}}/rest/controller/PageController.java
new file mode 100644
index 0000000..2c9c41c
--- /dev/null
+++ b/{{cookiecutter.project_slug}}/src/main/java/{{cookiecutter.__mvn_package}}/rest/controller/PageController.java
@@ -0,0 +1,165 @@
+package {{ cookiecutter.__mvn_package }}.rest.controller;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO;
+import java.io.Serializable;
+import java.util.List;
+
+import {{ cookiecutter.__mvn_package }}.rest.api.ApiController;
+import {{ cookiecutter.__mvn_package }}.rest.api.R;
+import {{ cookiecutter.__mvn_package }}.rest.entity.Page;
+import {{ cookiecutter.__mvn_package }}.rest.service.PageService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.lang.Nullable;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * 页面表(Page)表控制层.
+ *
+ * @author zweiandlen
+ * @since 2025-05-26 14:08:36
+ */
+@Tag(name = "标准接口", description = "由表结构自动生成")
+@RestController
+@RequestMapping("db/tPage")
+public class PageController extends ApiController {
+ /** 服务对象. */
+ private final PageService tPageService;
+
+ public PageController(PageService tPageService) {
+ this.tPageService = tPageService;
+ }
+
+ /**
+ * 分页查询所有数据.
+ *
+ * @param page 分页对象
+ * @param tPage 查询实体
+ * @return 分页数据
+ */
+ @Operation(
+ summary = "页面表 - 分页查询所有数据",
+ parameters = {
+ @Parameter(name = "page", description = "分页对象"),
+ @Parameter(name = "tPage", description = "查询实体"),
+ },
+ responses = @ApiResponse(description = "分页数据"),
+ description = "size=-1时查询所有数据,orders配合asc排序")
+ @GetMapping
+ @SaCheckPermission("db:rest:get")
+ public R selectAll(@Nullable PageDTO page, @Nullable Page tPage) {
+ return success(this.tPageService.page(page, new QueryWrapper<>(tPage)));
+ }
+
+ /**
+ * 通过主键查询单条数据.
+ *
+ * @param id 主键
+ * @return 单条数据
+ */
+ @Operation(
+ summary = "页面表 - 通过主键查询单条数据",
+ parameters = {
+ @Parameter(name = "id", description = "主键", schema = @Schema(type = "string")),
+ },
+ responses = @ApiResponse(description = "单条数据"))
+ @GetMapping("{id}")
+ @SaCheckPermission("db:rest:get")
+ public R selectOne(@PathVariable Serializable id) {
+ return success(this.tPageService.getById(id));
+ }
+
+ /**
+ * 新增数据.
+ *
+ * @param page 实体对象
+ * @return 新增结果
+ */
+ @Operation(
+ summary = "页面表 - 新增数据",
+ parameters = {
+ @Parameter(name = "page", description = "实体对象"),
+ },
+ responses = @ApiResponse(description = "新增结果"))
+ @PostMapping
+ @SaCheckPermission("db:rest:post")
+ public R insert(@RequestBody Page page) {
+ return success(this.tPageService.save(page));
+ }
+
+ /**
+ * 批量新增数据.
+ *
+ * @param pages 实体对象
+ * @return 新增结果
+ */
+ @Operation(
+ summary = "页面表 - 批量新增数据",
+ parameters = {
+ @Parameter(name = "pages", description = "实体对象"),
+ },
+ responses = @ApiResponse(description = "新增结果"))
+ @PostMapping("s")
+ @SaCheckPermission("db:rest:post")
+ public R inserts(@RequestBody List pages) {
+ return success(this.tPageService.saveBatch(pages));
+ }
+
+ /**
+ * 修改数据.
+ *
+ * @param page 实体对象
+ * @return 修改结果
+ */
+ @Operation(
+ summary = "页面表 - 修改数据",
+ parameters = {@Parameter(name = "page", description = "实体对象")},
+ responses = @ApiResponse(description = "修改结果"),
+ description = "不存在的对象会新增")
+ @PutMapping
+ @SaCheckPermission("db:rest:put")
+ public R update(@RequestBody Page page) {
+ return success(this.tPageService.saveOrUpdate(page));
+ }
+
+ /**
+ * 批量修改数据.
+ *
+ * @param pages 实体对象
+ * @return 修改结果
+ */
+ @Operation(
+ summary = "页面表 - 批量修改数据",
+ parameters = {@Parameter(name = "pages", description = "实体对象")},
+ responses = @ApiResponse(description = "修改结果"),
+ description = "不存在的对象会新增")
+ @PutMapping("s")
+ @SaCheckPermission("db:rest:put")
+ public R updates(@RequestBody List pages) {
+ return success(this.tPageService.saveOrUpdateBatch(pages));
+ }
+
+ /**
+ * 删除数据.
+ *
+ * @param idList 主键结合
+ * @return 删除结果
+ */
+ @Operation(
+ summary = "页面表 - 删除数据",
+ parameters = {
+ @Parameter(name = "idList", description = "主键结合", schema = @Schema(type = "string"))
+ },
+ responses = @ApiResponse(description = "删除结果"),
+ description = "主键用逗号拼接")
+ @DeleteMapping
+ @SaCheckPermission("db:rest:del")
+ public R delete(@RequestParam("idList") List idList) {
+ return success(this.tPageService.removeByIds(idList));
+ }
+}
diff --git a/{{cookiecutter.project_slug}}/src/main/java/{{cookiecutter.__mvn_package}}/rest/controller/PageDataController.java b/{{cookiecutter.project_slug}}/src/main/java/{{cookiecutter.__mvn_package}}/rest/controller/PageDataController.java
new file mode 100644
index 0000000..5866dc6
--- /dev/null
+++ b/{{cookiecutter.project_slug}}/src/main/java/{{cookiecutter.__mvn_package}}/rest/controller/PageDataController.java
@@ -0,0 +1,164 @@
+package {{ cookiecutter.__mvn_package }}.rest.controller;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO;
+import {{ cookiecutter.__mvn_package }}.rest.api.ApiController;
+import {{ cookiecutter.__mvn_package }}.rest.api.R;
+import {{ cookiecutter.__mvn_package }}.rest.entity.PageData;
+import {{ cookiecutter.__mvn_package }}.rest.service.PageDataService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import java.io.Serializable;
+import java.util.List;
+import org.springframework.lang.Nullable;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * 页面取值表(PageData)表控制层.
+ *
+ * @author zweiandlen
+ * @since 2025-05-26 14:08:35
+ */
+@Tag(name = "标准接口", description = "由表结构自动生成")
+@RestController
+@RequestMapping("db/tPageData")
+public class PageDataController extends ApiController {
+ /** 服务对象. */
+ private final PageDataService tPageDataService;
+
+ public PageDataController(PageDataService tPageDataService) {
+ this.tPageDataService = tPageDataService;
+ }
+
+ /**
+ * 分页查询所有数据.
+ *
+ * @param page 分页对象
+ * @param pageData 查询实体
+ * @return 分页数据
+ */
+ @Operation(
+ summary = "页面取值表 - 分页查询所有数据",
+ parameters = {
+ @Parameter(name = "page", description = "分页对象"),
+ @Parameter(name = "pageData", description = "查询实体"),
+ },
+ responses = @ApiResponse(description = "分页数据"),
+ description = "size=-1时查询所有数据,orders配合asc排序")
+ @GetMapping
+ @SaCheckPermission("db:rest:get")
+ public R selectAll(@Nullable PageDTO page, @Nullable PageData pageData) {
+ return success(this.tPageDataService.page(page, new QueryWrapper<>(pageData)));
+ }
+
+ /**
+ * 通过主键查询单条数据.
+ *
+ * @param id 主键
+ * @return 单条数据
+ */
+ @Operation(
+ summary = "页面取值表 - 通过主键查询单条数据",
+ parameters = {
+ @Parameter(name = "id", description = "主键", schema = @Schema(type = "string")),
+ },
+ responses = @ApiResponse(description = "单条数据"))
+ @GetMapping("{id}")
+ @SaCheckPermission("db:rest:get")
+ public R selectOne(@PathVariable Serializable id) {
+ return success(this.tPageDataService.getById(id));
+ }
+
+ /**
+ * 新增数据.
+ *
+ * @param pageData 实体对象
+ * @return 新增结果
+ */
+ @Operation(
+ summary = "页面取值表 - 新增数据",
+ parameters = {
+ @Parameter(name = "pageData", description = "实体对象"),
+ },
+ responses = @ApiResponse(description = "新增结果"))
+ @PostMapping
+ @SaCheckPermission("db:rest:post")
+ public R insert(@RequestBody PageData pageData) {
+ return success(this.tPageDataService.save(pageData));
+ }
+
+ /**
+ * 批量新增数据.
+ *
+ * @param pageData 实体对象
+ * @return 新增结果
+ */
+ @Operation(
+ summary = "页面取值表 - 批量新增数据",
+ parameters = {
+ @Parameter(name = "pageData", description = "实体对象"),
+ },
+ responses = @ApiResponse(description = "新增结果"))
+ @PostMapping("s")
+ @SaCheckPermission("db:rest:post")
+ public R inserts(@RequestBody List pageData) {
+ return success(this.tPageDataService.saveBatch(pageData));
+ }
+
+ /**
+ * 修改数据.
+ *
+ * @param pageData 实体对象
+ * @return 修改结果
+ */
+ @Operation(
+ summary = "页面取值表 - 修改数据",
+ parameters = {@Parameter(name = "pageData", description = "实体对象")},
+ responses = @ApiResponse(description = "修改结果"),
+ description = "不存在的对象会新增")
+ @PutMapping
+ @SaCheckPermission("db:rest:put")
+ public R update(@RequestBody PageData pageData) {
+ return success(this.tPageDataService.saveOrUpdate(pageData));
+ }
+
+ /**
+ * 批量修改数据.
+ *
+ * @param pageData 实体对象
+ * @return 修改结果
+ */
+ @Operation(
+ summary = "页面取值表 - 批量修改数据",
+ parameters = {@Parameter(name = "pageData", description = "实体对象")},
+ responses = @ApiResponse(description = "修改结果"),
+ description = "不存在的对象会新增")
+ @PutMapping("s")
+ @SaCheckPermission("db:rest:put")
+ public R updates(@RequestBody List pageData) {
+ return success(this.tPageDataService.saveOrUpdateBatch(pageData));
+ }
+
+ /**
+ * 删除数据.
+ *
+ * @param idList 主键结合
+ * @return 删除结果
+ */
+ @Operation(
+ summary = "页面取值表 - 删除数据",
+ parameters = {
+ @Parameter(name = "idList", description = "主键结合", schema = @Schema(type = "string"))
+ },
+ responses = @ApiResponse(description = "删除结果"),
+ description = "主键用逗号拼接")
+ @DeleteMapping
+ @SaCheckPermission("db:rest:del")
+ public R delete(@RequestParam("idList") List idList) {
+ return success(this.tPageDataService.removeByIds(idList));
+ }
+}
diff --git a/{{cookiecutter.project_slug}}/src/main/java/{{cookiecutter.__mvn_package}}/rest/dao/PageDao.java b/{{cookiecutter.project_slug}}/src/main/java/{{cookiecutter.__mvn_package}}/rest/dao/PageDao.java
new file mode 100644
index 0000000..74e7ac1
--- /dev/null
+++ b/{{cookiecutter.project_slug}}/src/main/java/{{cookiecutter.__mvn_package}}/rest/dao/PageDao.java
@@ -0,0 +1,15 @@
+package {{ cookiecutter.__mvn_package }}.rest.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import {{ cookiecutter.__mvn_package }}.rest.entity.Page;
+import {{ cookiecutter.__mvn_package }}.web.MybatisCache;
+import org.apache.ibatis.annotations.CacheNamespace;
+
+/**
+ * 页面表(Page)表数据库访问层.
+ *
+ * @author zweiandlen
+ * @since 2025-05-26 14:08:36
+ */
+@CacheNamespace(implementation = MybatisCache.class, eviction = MybatisCache.class)
+public interface PageDao extends BaseMapper {}
diff --git a/{{cookiecutter.project_slug}}/src/main/java/{{cookiecutter.__mvn_package}}/rest/dao/PageDataDao.java b/{{cookiecutter.project_slug}}/src/main/java/{{cookiecutter.__mvn_package}}/rest/dao/PageDataDao.java
new file mode 100644
index 0000000..9d2d527
--- /dev/null
+++ b/{{cookiecutter.project_slug}}/src/main/java/{{cookiecutter.__mvn_package}}/rest/dao/PageDataDao.java
@@ -0,0 +1,12 @@
+package {{ cookiecutter.__mvn_package }}.rest.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import {{ cookiecutter.__mvn_package }}.rest.entity.PageData;
+
+/**
+ * 页面取值表(PageData)表数据库访问层.
+ *
+ * @author zweiandlen
+ * @since 2025-05-26 14:08:35
+ */
+public interface PageDataDao extends BaseMapper {}
diff --git a/{{cookiecutter.project_slug}}/src/main/java/{{cookiecutter.__mvn_package}}/rest/entity/Page.java b/{{cookiecutter.project_slug}}/src/main/java/{{cookiecutter.__mvn_package}}/rest/entity/Page.java
new file mode 100644
index 0000000..7e2fc3a
--- /dev/null
+++ b/{{cookiecutter.project_slug}}/src/main/java/{{cookiecutter.__mvn_package}}/rest/entity/Page.java
@@ -0,0 +1,100 @@
+package {{ cookiecutter.__mvn_package }}.rest.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import io.swagger.v3.oas.annotations.media.Schema;
+import java.io.Serializable;
+import java.time.OffsetDateTime;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+{% if cookiecutter.platform == "postgis" -%}
+import ltd.llvy.postgis.handler.JsonbTypeHandler;
+{% endif %}
+import org.apache.ibatis.type.JdbcType;
+
+/**
+ * 页面表(Page)表实体类.
+ *
+ * @author zweiandlen
+ * @since 2025-05-26 14:08:36
+ */
+@Schema(description = "页面表")
+@EqualsAndHashCode(callSuper = true)
+@TableName(autoResultMap = true)
+@Data
+public class Page extends Model {
+ // ID
+ @Schema(description = "ID", type = "string")
+ @JsonSerialize(using = ToStringSerializer.class)
+ private Long id;
+
+ // 内容
+ @Schema(description = "内容")
+ {% if cookiecutter.platform == "postgis" -%}
+ @TableField(typeHandler = JsonbTypeHandler.class)
+ {% else %}
+ @TableField(typeHandler = JacksonTypeHandler.class)
+ {% endif %}
+ private JsonNode content;
+
+ // 描述
+ @Schema(description = "描述")
+ private String description;
+
+ // 乐观锁
+ @Schema(description = "乐观锁")
+ @Version
+ private Integer version;
+
+ // 逻辑删除
+ @Schema(description = "逻辑删除")
+ @TableLogic
+ private Long deleteTime;
+
+ // 创建时间
+ @Schema(description = "创建时间")
+ @JsonProperty(access = JsonProperty.Access.READ_ONLY)
+ {% if cookiecutter.platform == "postgis" -%}
+ @TableField(fill = FieldFill.INSERT_UPDATE, jdbcType = JdbcType.OTHER)
+ {% else %}
+ @TableField(fill = FieldFill.INSERT_UPDATE, jdbcType = JdbcType.DATETIMEOFFSET)
+ {% endif %}
+ private OffsetDateTime createTime;
+
+ // 修改时间
+ @Schema(description = "修改时间")
+ @JsonProperty(access = JsonProperty.Access.READ_ONLY)
+ {% if cookiecutter.platform == "postgis" -%}
+ @TableField(fill = FieldFill.INSERT_UPDATE, jdbcType = JdbcType.OTHER)
+ {% else %}
+ @TableField(fill = FieldFill.INSERT_UPDATE, jdbcType = JdbcType.DATETIMEOFFSET)
+ {% endif %}
+ private OffsetDateTime updateTime;
+
+ // 创建人
+ @Schema(description = "创建人")
+ @JsonProperty(access = JsonProperty.Access.READ_ONLY)
+ @TableField(fill = FieldFill.INSERT)
+ private String createBy;
+
+ // 修改人
+ @Schema(description = "修改人")
+ @JsonProperty(access = JsonProperty.Access.READ_ONLY)
+ @TableField(fill = FieldFill.INSERT_UPDATE)
+ private String updateBy;
+
+ /**
+ * 获取主键值.
+ *
+ * @return 主键值
+ */
+ @Override
+ public Serializable pkVal() {
+ return this.id;
+ }
+}
diff --git a/{{cookiecutter.project_slug}}/src/main/java/{{cookiecutter.__mvn_package}}/rest/entity/PageData.java b/{{cookiecutter.project_slug}}/src/main/java/{{cookiecutter.__mvn_package}}/rest/entity/PageData.java
new file mode 100644
index 0000000..f9c59e8
--- /dev/null
+++ b/{{cookiecutter.project_slug}}/src/main/java/{{cookiecutter.__mvn_package}}/rest/entity/PageData.java
@@ -0,0 +1,105 @@
+package {{ cookiecutter.__mvn_package }}.rest.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import io.swagger.v3.oas.annotations.media.Schema;
+import java.io.Serializable;
+import java.time.OffsetDateTime;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+{% if cookiecutter.platform == "postgis" -%}
+import ltd.llvy.postgis.handler.JsonbTypeHandler;
+{% endif %}
+import org.apache.ibatis.type.JdbcType;
+
+/**
+ * 页面取值表(PageData)表实体类.
+ *
+ * @author zweiandlen
+ * @since 2025-05-26 14:08:35
+ */
+@Schema(description = "页面取值表")
+@EqualsAndHashCode(callSuper = true)
+@TableName(autoResultMap = true)
+@Data
+public class PageData extends Model {
+ // ID
+ @Schema(description = "ID", type = "string")
+ @JsonSerialize(using = ToStringSerializer.class)
+ private Long id;
+
+ // 页面ID
+ @Schema(description = "页面ID", type = "string")
+ @JsonSerialize(using = ToStringSerializer.class)
+ private Long pageId;
+
+ // 内容
+ @Schema(description = "内容")
+ {% if cookiecutter.platform == "postgis" -%}
+ @TableField(typeHandler = JsonbTypeHandler.class)
+ {% else %}
+ @TableField(typeHandler = JacksonTypeHandler.class)
+ {% endif %}
+ private JsonNode content;
+
+ // 描述
+ @Schema(description = "描述")
+ private String description;
+
+ // 乐观锁
+ @Schema(description = "乐观锁")
+ @Version
+ private Integer version;
+
+ // 逻辑删除
+ @Schema(description = "逻辑删除")
+ @TableLogic
+ private Long deleteTime;
+
+ // 创建时间
+ @Schema(description = "创建时间")
+ @JsonProperty(access = JsonProperty.Access.READ_ONLY)
+ {% if cookiecutter.platform == "postgis" -%}
+ @TableField(fill = FieldFill.INSERT_UPDATE, jdbcType = JdbcType.OTHER)
+ {% else %}
+ @TableField(fill = FieldFill.INSERT_UPDATE, jdbcType = JdbcType.DATETIMEOFFSET)
+ {% endif %}
+ private OffsetDateTime createTime;
+
+ // 修改时间
+ @Schema(description = "修改时间")
+ @JsonProperty(access = JsonProperty.Access.READ_ONLY)
+ {% if cookiecutter.platform == "postgis" -%}
+ @TableField(fill = FieldFill.INSERT_UPDATE, jdbcType = JdbcType.OTHER)
+ {% else %}
+ @TableField(fill = FieldFill.INSERT_UPDATE, jdbcType = JdbcType.DATETIMEOFFSET)
+ {% endif %}
+ private OffsetDateTime updateTime;
+
+ // 创建人
+ @Schema(description = "创建人")
+ @JsonProperty(access = JsonProperty.Access.READ_ONLY)
+ @TableField(fill = FieldFill.INSERT)
+ private String createBy;
+
+ // 修改人
+ @Schema(description = "修改人")
+ @JsonProperty(access = JsonProperty.Access.READ_ONLY)
+ @TableField(fill = FieldFill.INSERT_UPDATE)
+ private String updateBy;
+
+ /**
+ * 获取主键值.
+ *
+ * @return 主键值
+ */
+ @Override
+ public Serializable pkVal() {
+ return this.id;
+ }
+}
diff --git a/{{cookiecutter.project_slug}}/src/main/java/{{cookiecutter.__mvn_package}}/rest/service/PageDataService.java b/{{cookiecutter.project_slug}}/src/main/java/{{cookiecutter.__mvn_package}}/rest/service/PageDataService.java
new file mode 100644
index 0000000..460e955
--- /dev/null
+++ b/{{cookiecutter.project_slug}}/src/main/java/{{cookiecutter.__mvn_package}}/rest/service/PageDataService.java
@@ -0,0 +1,12 @@
+package {{ cookiecutter.__mvn_package }}.rest.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import {{ cookiecutter.__mvn_package }}.rest.entity.PageData;
+
+/**
+ * 页面取值表(PageData)表服务接口.
+ *
+ * @author zweiandlen
+ * @since 2025-05-26 14:08:35
+ */
+public interface PageDataService extends IService {}
diff --git a/{{cookiecutter.project_slug}}/src/main/java/{{cookiecutter.__mvn_package}}/rest/service/PageService.java b/{{cookiecutter.project_slug}}/src/main/java/{{cookiecutter.__mvn_package}}/rest/service/PageService.java
new file mode 100644
index 0000000..eb96f7d
--- /dev/null
+++ b/{{cookiecutter.project_slug}}/src/main/java/{{cookiecutter.__mvn_package}}/rest/service/PageService.java
@@ -0,0 +1,12 @@
+package {{ cookiecutter.__mvn_package }}.rest.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import {{ cookiecutter.__mvn_package }}.rest.entity.Page;
+
+/**
+ * 页面表(Page)表服务接口.
+ *
+ * @author zweiandlen
+ * @since 2025-05-26 14:08:36
+ */
+public interface PageService extends IService {}
diff --git a/{{cookiecutter.project_slug}}/src/main/java/{{cookiecutter.__mvn_package}}/rest/service/impl/PageDataServiceImpl.java b/{{cookiecutter.project_slug}}/src/main/java/{{cookiecutter.__mvn_package}}/rest/service/impl/PageDataServiceImpl.java
new file mode 100644
index 0000000..99c76a9
--- /dev/null
+++ b/{{cookiecutter.project_slug}}/src/main/java/{{cookiecutter.__mvn_package}}/rest/service/impl/PageDataServiceImpl.java
@@ -0,0 +1,17 @@
+package {{ cookiecutter.__mvn_package }}.rest.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import {{ cookiecutter.__mvn_package }}.rest.dao.PageDataDao;
+import {{ cookiecutter.__mvn_package }}.rest.entity.PageData;
+import {{ cookiecutter.__mvn_package }}.rest.service.PageDataService;
+import org.springframework.stereotype.Service;
+
+/**
+ * 页面取值表(PageData)表服务实现类.
+ *
+ * @author zweiandlen
+ * @since 2025-05-26 14:08:35
+ */
+@Service("tPageDataService")
+public class PageDataServiceImpl extends ServiceImpl
+ implements PageDataService {}
diff --git a/{{cookiecutter.project_slug}}/src/main/java/{{cookiecutter.__mvn_package}}/rest/service/impl/PageServiceImpl.java b/{{cookiecutter.project_slug}}/src/main/java/{{cookiecutter.__mvn_package}}/rest/service/impl/PageServiceImpl.java
new file mode 100644
index 0000000..b530de7
--- /dev/null
+++ b/{{cookiecutter.project_slug}}/src/main/java/{{cookiecutter.__mvn_package}}/rest/service/impl/PageServiceImpl.java
@@ -0,0 +1,16 @@
+package {{ cookiecutter.__mvn_package }}.rest.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import {{ cookiecutter.__mvn_package }}.rest.dao.PageDao;
+import {{ cookiecutter.__mvn_package }}.rest.entity.Page;
+import {{ cookiecutter.__mvn_package }}.rest.service.PageService;
+import org.springframework.stereotype.Service;
+
+/**
+ * 页面表(Page)表服务实现类.
+ *
+ * @author zweiandlen
+ * @since 2025-05-26 14:08:36
+ */
+@Service("tPageService")
+public class PageServiceImpl extends ServiceImpl implements PageService {}
diff --git a/{{cookiecutter.project_slug}}/src/main/resources/schema-mysql.sql b/{{cookiecutter.project_slug}}/src/main/resources/schema-mysql.sql
index c963cac..7b861ce 100644
--- a/{{cookiecutter.project_slug}}/src/main/resources/schema-mysql.sql
+++ b/{{cookiecutter.project_slug}}/src/main/resources/schema-mysql.sql
@@ -172,6 +172,10 @@ INSERT INTO authority (id, parent_id, name, value, `path`, link, `type`, status,
create_time, update_time, create_by, update_by, tenant)
VALUES (29, 0, '导出表格', 'export:excel', '', '', 0, 0, '表格导出', 0, 0, '1970-01-01 00:00:00', NULL, '超级管理员',
NULL, '');
+INSERT INTO authority (id, parent_id, name, value, `path`, link, `type`, status, description, version, delete_time,
+ create_time, update_time, create_by, update_by, tenant)
+VALUES (30, 6, '动态页', 'system:page', '/system/page', NULL, 1, 0, '系统管理 / 动态页', 1, 0, '1970-01-01 00:00:00',
+ NULL, '超级管理员', NULL, '');
-- logger definition
@@ -281,4 +285,41 @@ CREATE TABLE `tenant`
UNIQUE KEY `tenant_unique_name` (`name`, `delete_time`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
- COLLATE = utf8mb4_general_ci COMMENT ='租户表';
\ No newline at end of file
+ COLLATE = utf8mb4_general_ci COMMENT ='租户表';
+
+-- design.page definition
+
+CREATE TABLE `page`
+(
+ `id` bigint NOT NULL COMMENT 'ID',
+ `content` json DEFAULT NULL COMMENT '内容',
+ `description` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT '描述',
+ `version` int NOT NULL DEFAULT '0' COMMENT '乐观锁',
+ `delete_time` bigint NOT NULL DEFAULT '0' COMMENT '逻辑删除',
+ `create_time` datetime DEFAULT NULL COMMENT '创建时间',
+ `update_time` datetime DEFAULT NULL COMMENT '修改时间',
+ `create_by` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '创建人',
+ `update_by` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '修改人',
+ PRIMARY KEY (`id`)
+) ENGINE = InnoDB
+ DEFAULT CHARSET = utf8mb4
+ COLLATE = utf8mb4_general_ci COMMENT ='页面表';
+
+-- design.page_data definition
+
+CREATE TABLE `page_data`
+(
+ `id` bigint NOT NULL COMMENT 'ID',
+ `page_id` bigint NOT NULL COMMENT '页面ID',
+ `content` json DEFAULT NULL COMMENT '内容',
+ `description` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT '描述',
+ `version` int NOT NULL DEFAULT '0' COMMENT '乐观锁',
+ `delete_time` bigint NOT NULL DEFAULT '0' COMMENT '逻辑删除',
+ `create_time` datetime DEFAULT NULL COMMENT '创建时间',
+ `update_time` datetime DEFAULT NULL COMMENT '修改时间',
+ `create_by` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '创建人',
+ `update_by` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '修改人',
+ PRIMARY KEY (`id`)
+) ENGINE = InnoDB
+ DEFAULT CHARSET = utf8mb4
+ COLLATE = utf8mb4_general_ci COMMENT ='页面取值表';
\ No newline at end of file
diff --git a/{{cookiecutter.project_slug}}/src/main/resources/schema-postgresql.sql b/{{cookiecutter.project_slug}}/src/main/resources/schema-postgresql.sql
index 3e1ac2a..6136faa 100644
--- a/{{cookiecutter.project_slug}}/src/main/resources/schema-postgresql.sql
+++ b/{{cookiecutter.project_slug}}/src/main/resources/schema-postgresql.sql
@@ -176,7 +176,10 @@ INSERT INTO authority (id, parent_id, "name", value, "path", link, "type", statu
create_time, update_time, create_by, update_by, tenant)
VALUES (29, 0, '导出表格', 'export:excel', '', '', 0, 0, '表格导出', 0, 0, '1970-01-01 00:00:00.000', NULL,
'超级管理员', '', '');
-
+INSERT INTO authority (id, parent_id, "name", value, "path", link, "type", status, description, "version", delete_time,
+ create_time, update_time, create_by, update_by, tenant)
+VALUES (30, 6, '动态页', 'system:page', '/system/page', NULL, 1, 0, '系统管理 / 动态页', 0, 0,
+ '1970-01-01 00:00:00.000', NULL, '超级管理员', NULL, '');
-- public.logger definition
@@ -297,4 +300,46 @@ CREATE TABLE tenant
update_by varchar(100) NULL,
CONSTRAINT t_organization_pk PRIMARY KEY (id),
CONSTRAINT t_organization_unique_name UNIQUE (name)
+);
+
+-- public.page definition
+
+-- Drop table
+
+-- DROP TABLE page;
+
+CREATE TABLE page
+(
+ id int8 NOT NULL,
+ "content" jsonb NULL,
+ description text NULL,
+ "version" int4 DEFAULT 0 NOT NULL,
+ delete_time int8 DEFAULT 0 NOT NULL,
+ create_time timestamptz NULL,
+ update_time timestamptz NULL,
+ create_by varchar(100) NULL,
+ update_by varchar(100) NULL,
+ CONSTRAINT page_pk PRIMARY KEY (id)
+);
+
+
+-- public.page_data definition
+
+-- Drop table
+
+-- DROP TABLE page_data;
+
+CREATE TABLE page_data
+(
+ id int8 NOT NULL,
+ page_id int8 NOT NULL,
+ "content" jsonb NULL,
+ description text NULL,
+ "version" int4 DEFAULT 0 NOT NULL,
+ delete_time int8 DEFAULT 0 NOT NULL,
+ create_time timestamptz NULL,
+ update_time timestamptz NULL,
+ create_by varchar(100) NULL,
+ update_by varchar(100) NULL,
+ CONSTRAINT page_data_pk PRIMARY KEY (id)
);
\ No newline at end of file