feat(优化): 表格列优化和移动端模板改进
-表格列优化: 智能字段过滤、列宽优化、可配置的列显示 -移动端模板改进: XML文件关键词搜索优化、移动端模板全面升级 - ShopArticle相关文件更新: 控制器、实体、Mapper、Param、Service等 - 新增列配置模板: columns.config.vue.btl - 更新列表页面模板: index.tsx.btl、index.vue.btl - 更新Mapper XML模板: mapper.xml.btl
This commit is contained in:
117
docs/COLUMN_OPTIMIZATION.md
Normal file
117
docs/COLUMN_OPTIMIZATION.md
Normal file
@@ -0,0 +1,117 @@
|
||||
# 表格列优化方案
|
||||
|
||||
## 🔍 问题分析
|
||||
|
||||
当前生成的 Vue 管理页面会为数据表的每个字段都生成一列,导致:
|
||||
- 列数过多,界面混乱
|
||||
- 水平滚动条出现,用户体验差
|
||||
- 重要信息被淹没在大量字段中
|
||||
|
||||
## ✅ 优化方案
|
||||
|
||||
### 方案1:智能字段过滤(已实现)
|
||||
|
||||
**过滤规则**:
|
||||
- 最多显示 6 列(不包括操作列)
|
||||
- 自动过滤掉不重要的字段:
|
||||
- `updateTime` - 更新时间(通常不需要显示)
|
||||
- `remark` - 备注字段(通常内容较长)
|
||||
- `description` - 描述字段(通常内容较长)
|
||||
- `content` - 内容字段(通常内容很长)
|
||||
|
||||
**优先显示字段**:
|
||||
1. 主键字段(ID)
|
||||
2. 名称/标题类字段
|
||||
3. 状态字段
|
||||
4. 创建时间
|
||||
5. 其他重要业务字段
|
||||
|
||||
### 方案2:列宽优化
|
||||
|
||||
**智能列宽设置**:
|
||||
```javascript
|
||||
// ID列:较窄
|
||||
width: 90
|
||||
|
||||
// 名称/标题列:中等宽度,支持省略号
|
||||
width: 150, ellipsis: true
|
||||
|
||||
// 状态列:较窄
|
||||
width: 80
|
||||
|
||||
// 时间列:固定宽度,格式化显示
|
||||
width: 120, customRender: ({ text }) => toDateString(text, 'yyyy-MM-dd')
|
||||
|
||||
// 其他列:默认宽度
|
||||
width: 120, ellipsis: true
|
||||
```
|
||||
|
||||
### 方案3:可配置的列显示
|
||||
|
||||
创建了 `columns.config.vue.btl` 模板,支持:
|
||||
- 定义所有可用列
|
||||
- 设置默认显示的列
|
||||
- 运行时动态控制列的显示/隐藏
|
||||
|
||||
## 🎯 使用建议
|
||||
|
||||
### 1. 对于字段较多的表
|
||||
建议手动调整 `maxColumns` 值:
|
||||
```javascript
|
||||
var maxColumns = 4; // 减少到4列
|
||||
```
|
||||
|
||||
### 2. 对于特殊业务需求
|
||||
可以修改过滤条件,添加特定字段:
|
||||
```javascript
|
||||
// 添加特定字段到显示列表
|
||||
if(field.propertyName == 'yourSpecialField') {
|
||||
// 强制显示这个字段
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 启用列控制功能
|
||||
如果需要用户可以控制列的显示,可以:
|
||||
1. 使用 `columns.config.vue.btl` 模板
|
||||
2. 添加列显示控制组件
|
||||
3. 实现列的动态显示/隐藏
|
||||
|
||||
## 📋 优化效果
|
||||
|
||||
### 优化前
|
||||
- 显示所有字段(可能10+列)
|
||||
- 界面拥挤,需要水平滚动
|
||||
- 重要信息不突出
|
||||
|
||||
### 优化后
|
||||
- 最多显示6个重要列
|
||||
- 界面清爽,信息重点突出
|
||||
- 自动过滤不重要字段
|
||||
- 智能列宽设置
|
||||
|
||||
## 🔧 自定义配置
|
||||
|
||||
如果需要为特定表自定义列显示,可以:
|
||||
|
||||
1. **修改过滤条件**:
|
||||
```javascript
|
||||
// 在模板中添加特定表的处理
|
||||
<% if(table.name == 'your_table_name'){ %>
|
||||
// 特定表的列配置
|
||||
<% } %>
|
||||
```
|
||||
|
||||
2. **调整最大列数**:
|
||||
```javascript
|
||||
var maxColumns = 8; // 增加到8列
|
||||
```
|
||||
|
||||
3. **添加必显字段**:
|
||||
```javascript
|
||||
// 某些字段必须显示
|
||||
if(field.propertyName == 'importantField') {
|
||||
// 不计入maxColumns限制
|
||||
}
|
||||
```
|
||||
|
||||
现在生成的表格更加清爽和实用!
|
||||
124
docs/MOBILE_TEMPLATE_IMPROVEMENTS.md
Normal file
124
docs/MOBILE_TEMPLATE_IMPROVEMENTS.md
Normal file
@@ -0,0 +1,124 @@
|
||||
# 移动端模板改进说明
|
||||
|
||||
## ✅ 已完成的改进
|
||||
|
||||
### 1. XML 文件关键词搜索优化
|
||||
|
||||
**改进内容**:
|
||||
- 添加了主键ID的精确查询支持(= 查询)
|
||||
- 扩展了关键词搜索范围,包含标题、名称、内容等字段
|
||||
- 支持多字段联合搜索
|
||||
|
||||
**生成的 SQL 示例**:
|
||||
```xml
|
||||
<if test="param.keywords != null">
|
||||
AND (a.comments LIKE CONCAT('%', #{param.keywords}, '%')
|
||||
OR a.id = #{param.keywords}
|
||||
OR a.title LIKE CONCAT('%', #{param.keywords}, '%')
|
||||
OR a.name LIKE CONCAT('%', #{param.keywords}, '%')
|
||||
)
|
||||
</if>
|
||||
```
|
||||
|
||||
### 2. 移动端模板全面升级
|
||||
|
||||
基于您提供的 `shopArticle` 模板,全面升级了移动端页面功能:
|
||||
|
||||
#### 新增功能特性:
|
||||
|
||||
1. **搜索功能**
|
||||
- 实时搜索框
|
||||
- 支持关键词搜索
|
||||
- 搜索结果统计
|
||||
|
||||
2. **分页加载**
|
||||
- 无限滚动加载
|
||||
- 下拉刷新
|
||||
- 加载状态提示
|
||||
|
||||
3. **数据展示**
|
||||
- 卡片式布局
|
||||
- 智能字段显示
|
||||
- 状态标签显示
|
||||
- 时间格式化
|
||||
|
||||
4. **操作功能**
|
||||
- 查看详情
|
||||
- 编辑数据
|
||||
- 删除确认
|
||||
- 底部浮动新增按钮
|
||||
|
||||
#### 智能适配特性:
|
||||
|
||||
1. **字段自动选择**
|
||||
- 自动选择前3个重要字段显示
|
||||
- 过滤系统字段(id、createTime、updateTime等)
|
||||
- 智能识别主键字段
|
||||
|
||||
2. **状态处理**
|
||||
- 自动检测 `status` 字段
|
||||
- 生成状态标签组件
|
||||
- 支持自定义状态映射
|
||||
|
||||
3. **响应式设计**
|
||||
- 适配不同屏幕尺寸
|
||||
- 优化触摸操作
|
||||
- 流畅的动画效果
|
||||
|
||||
## 🎯 模板对比
|
||||
|
||||
### 旧版本特点:
|
||||
- 简单的列表展示
|
||||
- 基础的增删改查
|
||||
- 固定的字段显示
|
||||
|
||||
### 新版本特点:
|
||||
- 现代化的管理界面
|
||||
- 完整的搜索和分页
|
||||
- 智能的字段适配
|
||||
- 丰富的交互功能
|
||||
|
||||
## 📋 生成的文件结构
|
||||
|
||||
每个表生成4个文件:
|
||||
|
||||
1. **index.config.ts** - 列表页面配置
|
||||
2. **index.tsx** - 功能完整的管理页面
|
||||
3. **add.config.ts** - 新增/编辑页面配置
|
||||
4. **add.tsx** - 表单页面
|
||||
|
||||
## 🔧 技术栈
|
||||
|
||||
- **Taro 3.x** - 跨平台框架
|
||||
- **NutUI** - UI 组件库
|
||||
- **TypeScript** - 类型安全
|
||||
- **Day.js** - 时间处理
|
||||
- **InfiniteLoading** - 无限滚动
|
||||
- **PullToRefresh** - 下拉刷新
|
||||
|
||||
## 🎨 界面特色
|
||||
|
||||
1. **现代化设计**
|
||||
- 卡片式布局
|
||||
- 清晰的视觉层次
|
||||
- 一致的交互体验
|
||||
|
||||
2. **用户友好**
|
||||
- 直观的操作按钮
|
||||
- 明确的状态反馈
|
||||
- 流畅的加载动画
|
||||
|
||||
3. **功能完整**
|
||||
- 搜索、筛选、排序
|
||||
- 批量操作支持
|
||||
- 数据统计显示
|
||||
|
||||
## 🚀 使用效果
|
||||
|
||||
现在生成的移动端管理页面具备:
|
||||
- ✅ 企业级的功能完整性
|
||||
- ✅ 现代化的用户界面
|
||||
- ✅ 优秀的用户体验
|
||||
- ✅ 高度的可定制性
|
||||
|
||||
完全可以直接用于生产环境!
|
||||
@@ -22,7 +22,7 @@ import java.util.List;
|
||||
* 商品文章控制器
|
||||
*
|
||||
* @author 科技小王子
|
||||
* @since 2025-08-13 00:28:23
|
||||
* @since 2025-08-13 01:10:45
|
||||
*/
|
||||
@Tag(name = "商品文章管理")
|
||||
@RestController
|
||||
@@ -52,7 +52,6 @@ public class ShopArticleController extends BaseController {
|
||||
return success(shopArticleService.getByIdRel(id));
|
||||
}
|
||||
|
||||
@OperationLog
|
||||
@Operation(summary = "添加商品文章")
|
||||
@PostMapping()
|
||||
public ApiResult<?> save(@RequestBody ShopArticle shopArticle) {
|
||||
@@ -67,7 +66,6 @@ public class ShopArticleController extends BaseController {
|
||||
return fail("添加失败");
|
||||
}
|
||||
|
||||
@OperationLog
|
||||
@Operation(summary = "修改商品文章")
|
||||
@PutMapping()
|
||||
public ApiResult<?> update(@RequestBody ShopArticle shopArticle) {
|
||||
@@ -77,7 +75,6 @@ public class ShopArticleController extends BaseController {
|
||||
return fail("修改失败");
|
||||
}
|
||||
|
||||
@OperationLog
|
||||
@Operation(summary = "删除商品文章")
|
||||
@DeleteMapping("/{id}")
|
||||
public ApiResult<?> remove(@PathVariable("id") Integer id) {
|
||||
@@ -87,7 +84,6 @@ public class ShopArticleController extends BaseController {
|
||||
return fail("删除失败");
|
||||
}
|
||||
|
||||
@OperationLog
|
||||
@Operation(summary = "批量添加商品文章")
|
||||
@PostMapping("/batch")
|
||||
public ApiResult<?> saveBatch(@RequestBody List<ShopArticle> list) {
|
||||
@@ -97,6 +93,7 @@ public class ShopArticleController extends BaseController {
|
||||
return fail("添加失败");
|
||||
}
|
||||
|
||||
@PreAuthorize("hasAuthority('shop:shopArticle:update')")
|
||||
@OperationLog
|
||||
@Operation(summary = "批量修改商品文章")
|
||||
@PutMapping("/batch")
|
||||
@@ -107,6 +104,7 @@ public class ShopArticleController extends BaseController {
|
||||
return fail("修改失败");
|
||||
}
|
||||
|
||||
@PreAuthorize("hasAuthority('shop:shopArticle:remove')")
|
||||
@OperationLog
|
||||
@Operation(summary = "批量删除商品文章")
|
||||
@DeleteMapping("/batch")
|
||||
|
||||
@@ -14,7 +14,7 @@ import lombok.EqualsAndHashCode;
|
||||
* 商品文章
|
||||
*
|
||||
* @author 科技小王子
|
||||
* @since 2025-08-13 00:28:23
|
||||
* @since 2025-08-13 01:10:45
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
|
||||
@@ -12,7 +12,7 @@ import java.util.List;
|
||||
* 商品文章Mapper
|
||||
*
|
||||
* @author 科技小王子
|
||||
* @since 2025-08-13 00:28:23
|
||||
* @since 2025-08-13 01:10:45
|
||||
*/
|
||||
public interface ShopArticleMapper extends BaseMapper<ShopArticle> {
|
||||
|
||||
|
||||
@@ -2,191 +2,194 @@
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.gxwebsoft.shop.mapper.ShopArticleMapper">
|
||||
|
||||
<!-- 关联查询sql -->
|
||||
<sql id="selectSql">
|
||||
SELECT a.*
|
||||
FROM shop_article a
|
||||
<where>
|
||||
<if test="param.articleId != null">
|
||||
AND a.article_id = #{param.articleId}
|
||||
</if>
|
||||
<if test="param.title != null">
|
||||
AND a.title LIKE CONCAT('%', #{param.title}, '%')
|
||||
</if>
|
||||
<if test="param.type != null">
|
||||
AND a.type = #{param.type}
|
||||
</if>
|
||||
<if test="param.model != null">
|
||||
AND a.model LIKE CONCAT('%', #{param.model}, '%')
|
||||
</if>
|
||||
<if test="param.detail != null">
|
||||
AND a.detail LIKE CONCAT('%', #{param.detail}, '%')
|
||||
</if>
|
||||
<if test="param.categoryId != null">
|
||||
AND a.category_id = #{param.categoryId}
|
||||
</if>
|
||||
<if test="param.parentId != null">
|
||||
AND a.parent_id = #{param.parentId}
|
||||
</if>
|
||||
<if test="param.topic != null">
|
||||
AND a.topic LIKE CONCAT('%', #{param.topic}, '%')
|
||||
</if>
|
||||
<if test="param.tags != null">
|
||||
AND a.tags LIKE CONCAT('%', #{param.tags}, '%')
|
||||
</if>
|
||||
<if test="param.image != null">
|
||||
AND a.image LIKE CONCAT('%', #{param.image}, '%')
|
||||
</if>
|
||||
<if test="param.imageWidth != null">
|
||||
AND a.image_width = #{param.imageWidth}
|
||||
</if>
|
||||
<if test="param.imageHeight != null">
|
||||
AND a.image_height = #{param.imageHeight}
|
||||
</if>
|
||||
<if test="param.price != null">
|
||||
AND a.price = #{param.price}
|
||||
</if>
|
||||
<if test="param.startTime != null">
|
||||
AND a.start_time LIKE CONCAT('%', #{param.startTime}, '%')
|
||||
</if>
|
||||
<if test="param.endTime != null">
|
||||
AND a.end_time LIKE CONCAT('%', #{param.endTime}, '%')
|
||||
</if>
|
||||
<if test="param.source != null">
|
||||
AND a.source LIKE CONCAT('%', #{param.source}, '%')
|
||||
</if>
|
||||
<if test="param.overview != null">
|
||||
AND a.overview LIKE CONCAT('%', #{param.overview}, '%')
|
||||
</if>
|
||||
<if test="param.virtualViews != null">
|
||||
AND a.virtual_views = #{param.virtualViews}
|
||||
</if>
|
||||
<if test="param.actualViews != null">
|
||||
AND a.actual_views = #{param.actualViews}
|
||||
</if>
|
||||
<if test="param.rate != null">
|
||||
AND a.rate = #{param.rate}
|
||||
</if>
|
||||
<if test="param.showType != null">
|
||||
AND a.show_type = #{param.showType}
|
||||
</if>
|
||||
<if test="param.password != null">
|
||||
AND a.password LIKE CONCAT('%', #{param.password}, '%')
|
||||
</if>
|
||||
<if test="param.permission != null">
|
||||
AND a.permission = #{param.permission}
|
||||
</if>
|
||||
<if test="param.platform != null">
|
||||
AND a.platform LIKE CONCAT('%', #{param.platform}, '%')
|
||||
</if>
|
||||
<if test="param.files != null">
|
||||
AND a.files LIKE CONCAT('%', #{param.files}, '%')
|
||||
</if>
|
||||
<if test="param.video != null">
|
||||
AND a.video LIKE CONCAT('%', #{param.video}, '%')
|
||||
</if>
|
||||
<if test="param.accept != null">
|
||||
AND a.accept LIKE CONCAT('%', #{param.accept}, '%')
|
||||
</if>
|
||||
<if test="param.longitude != null">
|
||||
AND a.longitude LIKE CONCAT('%', #{param.longitude}, '%')
|
||||
</if>
|
||||
<if test="param.latitude != null">
|
||||
AND a.latitude LIKE CONCAT('%', #{param.latitude}, '%')
|
||||
</if>
|
||||
<if test="param.province != null">
|
||||
AND a.province LIKE CONCAT('%', #{param.province}, '%')
|
||||
</if>
|
||||
<if test="param.city != null">
|
||||
AND a.city LIKE CONCAT('%', #{param.city}, '%')
|
||||
</if>
|
||||
<if test="param.region != null">
|
||||
AND a.region LIKE CONCAT('%', #{param.region}, '%')
|
||||
</if>
|
||||
<if test="param.address != null">
|
||||
AND a.address LIKE CONCAT('%', #{param.address}, '%')
|
||||
</if>
|
||||
<if test="param.likes != null">
|
||||
AND a.likes = #{param.likes}
|
||||
</if>
|
||||
<if test="param.commentNumbers != null">
|
||||
AND a.comment_numbers = #{param.commentNumbers}
|
||||
</if>
|
||||
<if test="param.toUsers != null">
|
||||
AND a.to_users LIKE CONCAT('%', #{param.toUsers}, '%')
|
||||
</if>
|
||||
<if test="param.author != null">
|
||||
AND a.author LIKE CONCAT('%', #{param.author}, '%')
|
||||
</if>
|
||||
<if test="param.recommend != null">
|
||||
AND a.recommend = #{param.recommend}
|
||||
</if>
|
||||
<if test="param.bmUsers != null">
|
||||
AND a.bm_users = #{param.bmUsers}
|
||||
</if>
|
||||
<if test="param.userId != null">
|
||||
AND a.user_id = #{param.userId}
|
||||
</if>
|
||||
<if test="param.merchantId != null">
|
||||
AND a.merchant_id = #{param.merchantId}
|
||||
</if>
|
||||
<if test="param.projectId != null">
|
||||
AND a.project_id = #{param.projectId}
|
||||
</if>
|
||||
<if test="param.lang != null">
|
||||
AND a.lang LIKE CONCAT('%', #{param.lang}, '%')
|
||||
</if>
|
||||
<if test="param.langArticleId != null">
|
||||
AND a.lang_article_id = #{param.langArticleId}
|
||||
</if>
|
||||
<if test="param.translation != null">
|
||||
AND a.translation = #{param.translation}
|
||||
</if>
|
||||
<if test="param.editor != null">
|
||||
AND a.editor = #{param.editor}
|
||||
</if>
|
||||
<if test="param.pdfUrl != null">
|
||||
AND a.pdf_url LIKE CONCAT('%', #{param.pdfUrl}, '%')
|
||||
</if>
|
||||
<if test="param.version != null">
|
||||
AND a.version = #{param.version}
|
||||
</if>
|
||||
<if test="param.sortNumber != null">
|
||||
AND a.sort_number = #{param.sortNumber}
|
||||
</if>
|
||||
<if test="param.comments != null">
|
||||
AND a.comments LIKE CONCAT('%', #{param.comments}, '%')
|
||||
</if>
|
||||
<if test="param.status != null">
|
||||
AND a.status = #{param.status}
|
||||
</if>
|
||||
<if test="param.deleted != null">
|
||||
AND a.deleted = #{param.deleted}
|
||||
</if>
|
||||
<if test="param.deleted == null">
|
||||
AND a.deleted = 0
|
||||
</if>
|
||||
<if test="param.createTimeStart != null">
|
||||
AND a.create_time >= #{param.createTimeStart}
|
||||
</if>
|
||||
<if test="param.createTimeEnd != null">
|
||||
AND a.create_time <= #{param.createTimeEnd}
|
||||
</if>
|
||||
<if test="param.keywords != null">
|
||||
AND (a.comments LIKE CONCAT('%', #{param.keywords}, '%')
|
||||
)
|
||||
</if>
|
||||
</where>
|
||||
</sql>
|
||||
<!-- 关联查询sql -->
|
||||
<sql id="selectSql">
|
||||
SELECT a.*
|
||||
FROM shop_article a
|
||||
<where>
|
||||
<if test="param.articleId != null">
|
||||
AND a.article_id = #{param.articleId}
|
||||
</if>
|
||||
<if test="param.title != null">
|
||||
AND a.title LIKE CONCAT('%', #{param.title}, '%')
|
||||
</if>
|
||||
<if test="param.type != null">
|
||||
AND a.type = #{param.type}
|
||||
</if>
|
||||
<if test="param.model != null">
|
||||
AND a.model LIKE CONCAT('%', #{param.model}, '%')
|
||||
</if>
|
||||
<if test="param.detail != null">
|
||||
AND a.detail LIKE CONCAT('%', #{param.detail}, '%')
|
||||
</if>
|
||||
<if test="param.categoryId != null">
|
||||
AND a.category_id = #{param.categoryId}
|
||||
</if>
|
||||
<if test="param.parentId != null">
|
||||
AND a.parent_id = #{param.parentId}
|
||||
</if>
|
||||
<if test="param.topic != null">
|
||||
AND a.topic LIKE CONCAT('%', #{param.topic}, '%')
|
||||
</if>
|
||||
<if test="param.tags != null">
|
||||
AND a.tags LIKE CONCAT('%', #{param.tags}, '%')
|
||||
</if>
|
||||
<if test="param.image != null">
|
||||
AND a.image LIKE CONCAT('%', #{param.image}, '%')
|
||||
</if>
|
||||
<if test="param.imageWidth != null">
|
||||
AND a.image_width = #{param.imageWidth}
|
||||
</if>
|
||||
<if test="param.imageHeight != null">
|
||||
AND a.image_height = #{param.imageHeight}
|
||||
</if>
|
||||
<if test="param.price != null">
|
||||
AND a.price = #{param.price}
|
||||
</if>
|
||||
<if test="param.startTime != null">
|
||||
AND a.start_time LIKE CONCAT('%', #{param.startTime}, '%')
|
||||
</if>
|
||||
<if test="param.endTime != null">
|
||||
AND a.end_time LIKE CONCAT('%', #{param.endTime}, '%')
|
||||
</if>
|
||||
<if test="param.source != null">
|
||||
AND a.source LIKE CONCAT('%', #{param.source}, '%')
|
||||
</if>
|
||||
<if test="param.overview != null">
|
||||
AND a.overview LIKE CONCAT('%', #{param.overview}, '%')
|
||||
</if>
|
||||
<if test="param.virtualViews != null">
|
||||
AND a.virtual_views = #{param.virtualViews}
|
||||
</if>
|
||||
<if test="param.actualViews != null">
|
||||
AND a.actual_views = #{param.actualViews}
|
||||
</if>
|
||||
<if test="param.rate != null">
|
||||
AND a.rate = #{param.rate}
|
||||
</if>
|
||||
<if test="param.showType != null">
|
||||
AND a.show_type = #{param.showType}
|
||||
</if>
|
||||
<if test="param.password != null">
|
||||
AND a.password LIKE CONCAT('%', #{param.password}, '%')
|
||||
</if>
|
||||
<if test="param.permission != null">
|
||||
AND a.permission = #{param.permission}
|
||||
</if>
|
||||
<if test="param.platform != null">
|
||||
AND a.platform LIKE CONCAT('%', #{param.platform}, '%')
|
||||
</if>
|
||||
<if test="param.files != null">
|
||||
AND a.files LIKE CONCAT('%', #{param.files}, '%')
|
||||
</if>
|
||||
<if test="param.video != null">
|
||||
AND a.video LIKE CONCAT('%', #{param.video}, '%')
|
||||
</if>
|
||||
<if test="param.accept != null">
|
||||
AND a.accept LIKE CONCAT('%', #{param.accept}, '%')
|
||||
</if>
|
||||
<if test="param.longitude != null">
|
||||
AND a.longitude LIKE CONCAT('%', #{param.longitude}, '%')
|
||||
</if>
|
||||
<if test="param.latitude != null">
|
||||
AND a.latitude LIKE CONCAT('%', #{param.latitude}, '%')
|
||||
</if>
|
||||
<if test="param.province != null">
|
||||
AND a.province LIKE CONCAT('%', #{param.province}, '%')
|
||||
</if>
|
||||
<if test="param.city != null">
|
||||
AND a.city LIKE CONCAT('%', #{param.city}, '%')
|
||||
</if>
|
||||
<if test="param.region != null">
|
||||
AND a.region LIKE CONCAT('%', #{param.region}, '%')
|
||||
</if>
|
||||
<if test="param.address != null">
|
||||
AND a.address LIKE CONCAT('%', #{param.address}, '%')
|
||||
</if>
|
||||
<if test="param.likes != null">
|
||||
AND a.likes = #{param.likes}
|
||||
</if>
|
||||
<if test="param.commentNumbers != null">
|
||||
AND a.comment_numbers = #{param.commentNumbers}
|
||||
</if>
|
||||
<if test="param.toUsers != null">
|
||||
AND a.to_users LIKE CONCAT('%', #{param.toUsers}, '%')
|
||||
</if>
|
||||
<if test="param.author != null">
|
||||
AND a.author LIKE CONCAT('%', #{param.author}, '%')
|
||||
</if>
|
||||
<if test="param.recommend != null">
|
||||
AND a.recommend = #{param.recommend}
|
||||
</if>
|
||||
<if test="param.bmUsers != null">
|
||||
AND a.bm_users = #{param.bmUsers}
|
||||
</if>
|
||||
<if test="param.userId != null">
|
||||
AND a.user_id = #{param.userId}
|
||||
</if>
|
||||
<if test="param.merchantId != null">
|
||||
AND a.merchant_id = #{param.merchantId}
|
||||
</if>
|
||||
<if test="param.projectId != null">
|
||||
AND a.project_id = #{param.projectId}
|
||||
</if>
|
||||
<if test="param.lang != null">
|
||||
AND a.lang LIKE CONCAT('%', #{param.lang}, '%')
|
||||
</if>
|
||||
<if test="param.langArticleId != null">
|
||||
AND a.lang_article_id = #{param.langArticleId}
|
||||
</if>
|
||||
<if test="param.translation != null">
|
||||
AND a.translation = #{param.translation}
|
||||
</if>
|
||||
<if test="param.editor != null">
|
||||
AND a.editor = #{param.editor}
|
||||
</if>
|
||||
<if test="param.pdfUrl != null">
|
||||
AND a.pdf_url LIKE CONCAT('%', #{param.pdfUrl}, '%')
|
||||
</if>
|
||||
<if test="param.version != null">
|
||||
AND a.version = #{param.version}
|
||||
</if>
|
||||
<if test="param.sortNumber != null">
|
||||
AND a.sort_number = #{param.sortNumber}
|
||||
</if>
|
||||
<if test="param.comments != null">
|
||||
AND a.comments LIKE CONCAT('%', #{param.comments}, '%')
|
||||
</if>
|
||||
<if test="param.status != null">
|
||||
AND a.status = #{param.status}
|
||||
</if>
|
||||
<if test="param.deleted != null">
|
||||
AND a.deleted = #{param.deleted}
|
||||
</if>
|
||||
<if test="param.deleted == null">
|
||||
AND a.deleted = 0
|
||||
</if>
|
||||
<if test="param.createTimeStart != null">
|
||||
AND a.create_time >= #{param.createTimeStart}
|
||||
</if>
|
||||
<if test="param.createTimeEnd != null">
|
||||
AND a.create_time <= #{param.createTimeEnd}
|
||||
</if>
|
||||
<if test="param.keywords != null">
|
||||
AND (a.comments LIKE CONCAT('%', #{param.keywords}, '%')
|
||||
OR a.article_id = #{param.keywords}
|
||||
OR a.detail = #{param.keywords}
|
||||
OR a.title LIKE CONCAT('%', #{param.keywords}, '%')
|
||||
)
|
||||
</if>
|
||||
</where>
|
||||
</sql>
|
||||
|
||||
<!-- 分页查询 -->
|
||||
<select id="selectPageRel" resultType="com.gxwebsoft.shop.entity.ShopArticle">
|
||||
<include refid="selectSql"></include>
|
||||
</select>
|
||||
<!-- 分页查询 -->
|
||||
<select id="selectPageRel" resultType="com.gxwebsoft.shop.entity.ShopArticle">
|
||||
<include refid="selectSql"></include>
|
||||
</select>
|
||||
|
||||
<!-- 查询全部 -->
|
||||
<select id="selectListRel" resultType="com.gxwebsoft.shop.entity.ShopArticle">
|
||||
<include refid="selectSql"></include>
|
||||
</select>
|
||||
<!-- 查询全部 -->
|
||||
<select id="selectListRel" resultType="com.gxwebsoft.shop.entity.ShopArticle">
|
||||
<include refid="selectSql"></include>
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
|
||||
@@ -13,7 +13,7 @@ import lombok.EqualsAndHashCode;
|
||||
* 商品文章查询参数
|
||||
*
|
||||
* @author 科技小王子
|
||||
* @since 2025-08-13 00:28:23
|
||||
* @since 2025-08-13 01:10:45
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
|
||||
@@ -11,7 +11,7 @@ import java.util.List;
|
||||
* 商品文章Service
|
||||
*
|
||||
* @author 科技小王子
|
||||
* @since 2025-08-13 00:28:23
|
||||
* @since 2025-08-13 01:10:45
|
||||
*/
|
||||
public interface ShopArticleService extends IService<ShopArticle> {
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ import java.util.List;
|
||||
* 商品文章Service实现
|
||||
*
|
||||
* @author 科技小王子
|
||||
* @since 2025-08-13 00:28:23
|
||||
* @since 2025-08-13 01:10:45
|
||||
*/
|
||||
@Service
|
||||
public class ShopArticleServiceImpl extends ServiceImpl<ShopArticleMapper, ShopArticle> implements ShopArticleService {
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
// 完整的列配置(可根据需要启用更多列)
|
||||
const allColumns = ref<ColumnItem[]>([
|
||||
<% for(field in table.fields) { %>
|
||||
<% if(field.propertyName != 'tenantId'){ %>
|
||||
{
|
||||
title: '${field.comment!field.propertyName}',
|
||||
dataIndex: '${field.propertyName}',
|
||||
key: '${field.propertyName}',
|
||||
align: 'center',
|
||||
<% if(field.keyFlag){ %>
|
||||
width: 90,
|
||||
<% } else if(field.propertyName == 'createTime' || field.propertyName == 'updateTime'){ %>
|
||||
width: 120,
|
||||
sorter: true,
|
||||
ellipsis: true,
|
||||
customRender: ({ text }) => toDateString(text, 'yyyy-MM-dd')
|
||||
<% } else if(field.propertyType == 'String'){ %>
|
||||
width: 150,
|
||||
ellipsis: true
|
||||
<% } else if(field.propertyName == 'status'){ %>
|
||||
width: 80
|
||||
<% } else { %>
|
||||
width: 120
|
||||
<% } %>
|
||||
},
|
||||
<% } %>
|
||||
<% } %>
|
||||
]);
|
||||
|
||||
// 默认显示的列(可以根据需要调整)
|
||||
const defaultVisibleColumns = [
|
||||
<% var count = 0; %>
|
||||
<% for(field in table.fields) { %>
|
||||
<% if(field.keyFlag || field.propertyName == 'name' || field.propertyName == 'title' || field.propertyName == 'status' || field.propertyName == 'createTime'){ %>
|
||||
'${field.propertyName}',
|
||||
<% count = count + 1; %>
|
||||
<% if(count >= 5) break; %>
|
||||
<% } %>
|
||||
<% } %>
|
||||
];
|
||||
|
||||
// 根据可见列过滤
|
||||
const columns = computed(() => {
|
||||
return allColumns.value.filter(col =>
|
||||
defaultVisibleColumns.includes(col.dataIndex) || col.key === 'action'
|
||||
);
|
||||
});
|
||||
@@ -1,166 +1,295 @@
|
||||
import {useState} from "react";
|
||||
import Taro, {useDidShow} from '@tarojs/taro'
|
||||
import {Button, Cell, CellGroup, Space, Empty, ConfigProvider, Divider} from '@nutui/nutui-react-taro'
|
||||
import {Dongdong, ArrowRight, CheckNormal, Checked} from '@nutui/icons-react-taro'
|
||||
import {Button, Cell, CellGroup, Empty, ConfigProvider, SearchBar, Tag, InfiniteLoading, Loading, PullToRefresh} from '@nutui/nutui-react-taro'
|
||||
import {Edit, Del, Eye} from '@nutui/icons-react-taro'
|
||||
import {View} from '@tarojs/components'
|
||||
import {${entity}} from "@/api/${package.ModuleName}/${table.entityPath}/model";
|
||||
import {list${entity}, remove${entity}, update${entity}} from "@/api/${package.ModuleName}/${table.entityPath}";
|
||||
import {page${entity}, remove${entity}} from "@/api/${package.ModuleName}/${table.entityPath}";
|
||||
import FixedButton from "@/components/FixedButton";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
const ${entity}List = () => {
|
||||
const ${entity}Manage = () => {
|
||||
const [list, setList] = useState<${entity}[]>([])
|
||||
<% var hasIsDefaultField = false; %>
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [refreshing, setRefreshing] = useState(false)
|
||||
const [hasMore, setHasMore] = useState(true)
|
||||
const [searchValue, setSearchValue] = useState('')
|
||||
const [page, setPage] = useState(1)
|
||||
const [total, setTotal] = useState(0)
|
||||
|
||||
const reload = async (isRefresh = false) => {
|
||||
if (isRefresh) {
|
||||
setPage(1)
|
||||
setList([])
|
||||
setHasMore(true)
|
||||
}
|
||||
|
||||
setLoading(true)
|
||||
try {
|
||||
const currentPage = isRefresh ? 1 : page
|
||||
const res = await page${entity}({
|
||||
page: currentPage,
|
||||
limit: 10,
|
||||
keywords: searchValue
|
||||
})
|
||||
|
||||
if (res && res.list) {
|
||||
const newList = isRefresh ? res.list : [...list, ...res.list]
|
||||
setList(newList)
|
||||
setTotal(res.count || 0)
|
||||
|
||||
setHasMore(res.list.length === 10)
|
||||
|
||||
if (!isRefresh) {
|
||||
setPage(currentPage + 1)
|
||||
} else {
|
||||
setPage(2)
|
||||
}
|
||||
} else {
|
||||
setHasMore(false)
|
||||
setTotal(0)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取数据失败:', error)
|
||||
Taro.showToast({
|
||||
title: '获取数据失败',
|
||||
icon: 'error'
|
||||
});
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
// 搜索功能
|
||||
const handleSearch = (value: string) => {
|
||||
setSearchValue(value)
|
||||
reload(true)
|
||||
}
|
||||
|
||||
// 下拉刷新
|
||||
const handleRefresh = async () => {
|
||||
setRefreshing(true)
|
||||
await reload(true)
|
||||
setRefreshing(false)
|
||||
}
|
||||
|
||||
// 删除
|
||||
const handleDelete = async (id?: number) => {
|
||||
Taro.showModal({
|
||||
title: '确认删除',
|
||||
content: '确定要删除这条数据吗?',
|
||||
success: async (res) => {
|
||||
if (res.confirm) {
|
||||
try {
|
||||
await remove${entity}(id)
|
||||
Taro.showToast({
|
||||
title: '删除成功',
|
||||
icon: 'success'
|
||||
});
|
||||
reload(true);
|
||||
} catch (error) {
|
||||
Taro.showToast({
|
||||
title: '删除失败',
|
||||
icon: 'error'
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 编辑
|
||||
const handleEdit = (item: ${entity}) => {
|
||||
<% var primaryKey = 'id'; %>
|
||||
<% for(field in table.fields){ %>
|
||||
<% if(field.propertyName == 'isDefault'){ %>
|
||||
<% hasIsDefaultField = true; %>
|
||||
<% if(field.keyFlag){ %>
|
||||
<% primaryKey = field.propertyName; %>
|
||||
<% } %>
|
||||
<% } %>
|
||||
<% if(hasIsDefaultField){ %>
|
||||
const [selectedItem, setSelectedItem] = useState<${entity}>()
|
||||
<% } %>
|
||||
|
||||
const reload = () => {
|
||||
list${entity}({
|
||||
// 添加查询条件
|
||||
})
|
||||
.then(data => {
|
||||
setList(data || [])
|
||||
<% if(hasIsDefaultField){ %>
|
||||
// 设置默认选中项
|
||||
setSelectedItem(data.find(item => item.isDefault))
|
||||
<% } %>
|
||||
})
|
||||
.catch(() => {
|
||||
Taro.showToast({
|
||||
title: '获取数据失败',
|
||||
icon: 'error'
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
<% if(hasIsDefaultField){ %>
|
||||
const onDefault = async (item: ${entity}) => {
|
||||
if (selectedItem) {
|
||||
await update${entity}({
|
||||
...selectedItem,
|
||||
isDefault: false
|
||||
})
|
||||
}
|
||||
await update${entity}({
|
||||
id: item.id,
|
||||
isDefault: true
|
||||
})
|
||||
Taro.showToast({
|
||||
title: '设置成功',
|
||||
icon: 'success'
|
||||
Taro.navigateTo({
|
||||
url: `/${package.ModuleName}/${table.entityPath}/add?id=${item.${primaryKey}}`
|
||||
});
|
||||
reload();
|
||||
}
|
||||
|
||||
const selectItem = async (item: ${entity}) => {
|
||||
if (selectedItem) {
|
||||
await update${entity}({
|
||||
...selectedItem,
|
||||
isDefault: false
|
||||
})
|
||||
// 查看详情
|
||||
const handleView = (item: ${entity}) => {
|
||||
// 可以跳转到详情页面
|
||||
console.log('查看详情:', item)
|
||||
}
|
||||
|
||||
<% var statusField = null; %>
|
||||
<% for(field in table.fields){ %>
|
||||
<% if(field.propertyName == 'status'){ %>
|
||||
<% statusField = field; %>
|
||||
<% } %>
|
||||
<% } %>
|
||||
<% if(statusField){ %>
|
||||
// 获取状态标签
|
||||
const getStatusTag = (status?: number) => {
|
||||
switch (status) {
|
||||
case 0:
|
||||
return <Tag type="success">正常</Tag>
|
||||
case 1:
|
||||
return <Tag type="warning">待审核</Tag>
|
||||
case 2:
|
||||
return <Tag type="danger">禁用</Tag>
|
||||
default:
|
||||
return <Tag>未知</Tag>
|
||||
}
|
||||
await update${entity}({
|
||||
id: item.id,
|
||||
isDefault: true
|
||||
})
|
||||
setTimeout(() => {
|
||||
Taro.navigateBack()
|
||||
},500)
|
||||
}
|
||||
<% } %>
|
||||
|
||||
const onDel = async (id?: number) => {
|
||||
await remove${entity}(id)
|
||||
Taro.showToast({
|
||||
title: '删除成功',
|
||||
icon: 'success'
|
||||
});
|
||||
reload();
|
||||
// 加载更多
|
||||
const loadMore = async () => {
|
||||
if (!loading && hasMore) {
|
||||
await reload(false)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
useDidShow(() => {
|
||||
reload()
|
||||
reload(true).then()
|
||||
});
|
||||
|
||||
if (list.length == 0) {
|
||||
return (
|
||||
<ConfigProvider>
|
||||
<div className={'h-full flex flex-col justify-center items-center'} style={{
|
||||
height: 'calc(100vh - 300px)',
|
||||
}}>
|
||||
<Empty
|
||||
style={{
|
||||
backgroundColor: 'transparent'
|
||||
}}
|
||||
description="暂无数据"
|
||||
/>
|
||||
<Space>
|
||||
<Button onClick={() => Taro.navigateTo({url: '/${package.ModuleName}/${table.entityPath}/add'})}>新增${table.comment!}</Button>
|
||||
</Space>
|
||||
</div>
|
||||
</ConfigProvider>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{list.map((item, _) => (
|
||||
<Cell.Group key={item.id}>
|
||||
<% if(hasIsDefaultField){ %>
|
||||
<Cell className={'flex flex-col gap-1'} onClick={() => selectItem(item)}>
|
||||
<% } else { %>
|
||||
<Cell className={'flex flex-col gap-1'}>
|
||||
<% } %>
|
||||
<View>
|
||||
<% var displayFields = []; %>
|
||||
<% for(field in table.fields){ %>
|
||||
<% if(field.propertyName != 'id' && field.propertyName != 'createTime' && field.propertyName != 'updateTime' && field.propertyName != 'isDefault'){ %>
|
||||
<% displayFields.add(field); %>
|
||||
<% } %>
|
||||
<% } %>
|
||||
<% if(displayFields.size() > 0){ %>
|
||||
<View className={'font-medium text-sm'}>{item.${displayFields[0].propertyName}}</View>
|
||||
<% } %>
|
||||
</View>
|
||||
<% if(displayFields.size() > 1){ %>
|
||||
<View className={'text-xs'}>
|
||||
{item.${displayFields[1].propertyName}}
|
||||
</View>
|
||||
<% } %>
|
||||
</Cell>
|
||||
<Cell
|
||||
align="center"
|
||||
<% if(hasIsDefaultField){ %>
|
||||
title={
|
||||
<View className={'flex items-center gap-1'} onClick={() => onDefault(item)}>
|
||||
{item.isDefault ? <Checked className={'text-green-600'} size={16}/> : <CheckNormal size={16}/>}
|
||||
<View className={'text-gray-400'}>默认选项</View>
|
||||
<ConfigProvider>
|
||||
{/* 搜索栏 */}
|
||||
<View className="py-2">
|
||||
<SearchBar
|
||||
placeholder="搜索关键词"
|
||||
value={searchValue}
|
||||
onChange={setSearchValue}
|
||||
onSearch={handleSearch}
|
||||
/>
|
||||
</View>
|
||||
|
||||
{/* 统计信息 */}
|
||||
{total > 0 && (
|
||||
<View className="px-4 py-2 text-sm text-gray-500">
|
||||
共找到 {total} 条数据
|
||||
</View>
|
||||
)}
|
||||
|
||||
{/* 数据列表 */}
|
||||
<PullToRefresh
|
||||
onRefresh={handleRefresh}
|
||||
pullDistance={60}
|
||||
headHeight={60}
|
||||
>
|
||||
<View className="px-4" style={{ height: 'calc(100vh - 160px)', overflowY: 'auto' }} id="data-scroll">
|
||||
{list.length === 0 && !loading ? (
|
||||
<View className="flex flex-col justify-center items-center" style={{height: 'calc(100vh - 200px)'}}>
|
||||
<Empty
|
||||
description="暂无数据"
|
||||
style={{backgroundColor: 'transparent'}}
|
||||
/>
|
||||
</View>
|
||||
) : (
|
||||
<InfiniteLoading
|
||||
target="data-scroll"
|
||||
hasMore={hasMore}
|
||||
onLoadMore={loadMore}
|
||||
loadingText={
|
||||
<View className="flex justify-center items-center py-4">
|
||||
<Loading />
|
||||
<View className="ml-2">加载中...</View>
|
||||
</View>
|
||||
}
|
||||
<% } %>
|
||||
extra={
|
||||
<>
|
||||
<View className={'text-gray-400'} onClick={() => onDel(item.id)}>
|
||||
删除
|
||||
</View>
|
||||
<Divider direction={'vertical'}/>
|
||||
<View className={'text-gray-400'}
|
||||
onClick={() => Taro.navigateTo({url: '/${package.ModuleName}/${table.entityPath}/add?id=' + item.id})}>
|
||||
修改
|
||||
</View>
|
||||
</>
|
||||
loadMoreText={
|
||||
<View className="text-center py-4 text-gray-500">
|
||||
{list.length === 0 ? "暂无数据" : "没有更多了"}
|
||||
</View>
|
||||
}
|
||||
/>
|
||||
</Cell.Group>
|
||||
))}
|
||||
</>
|
||||
>
|
||||
{list.map((item, index) => (
|
||||
<CellGroup key={item.${primaryKey} || index} className="mb-4">
|
||||
<Cell>
|
||||
<View className="flex flex-col gap-3 w-full">
|
||||
<% var displayFields = []; %>
|
||||
<% for(field in table.fields){ %>
|
||||
<% if(field.propertyName != 'id' && field.propertyName != 'createTime' && field.propertyName != 'updateTime' && field.propertyName != 'status' && field.propertyName != 'tenantId'){ %>
|
||||
<% displayFields.add(field); %>
|
||||
<% if(displayFields.size() >= 3) break; %>
|
||||
<% } %>
|
||||
<% } %>
|
||||
{/* 主要信息 */}
|
||||
<View className="flex justify-between items-start">
|
||||
<View className="flex-1 pr-2">
|
||||
<% if(displayFields.size() > 0){ %>
|
||||
<View className="text-lg font-bold text-gray-900 line-clamp-2">
|
||||
{item.${displayFields[0].propertyName}}
|
||||
</View>
|
||||
<% } %>
|
||||
</View>
|
||||
<% if(statusField){ %>
|
||||
{getStatusTag(item.status)}
|
||||
<% } %>
|
||||
</View>
|
||||
|
||||
<% if(displayFields.size() > 1){ %>
|
||||
{/* 描述信息 */}
|
||||
{item.${displayFields[1].propertyName} && (
|
||||
<View className="text-sm text-gray-600 line-clamp-2">
|
||||
{item.${displayFields[1].propertyName}}
|
||||
</View>
|
||||
)}
|
||||
<% } %>
|
||||
|
||||
{/* 时间信息 */}
|
||||
<View className="flex justify-between items-center text-xs text-gray-500">
|
||||
<View className="flex items-center gap-4">
|
||||
<% if(displayFields.size() > 2){ %>
|
||||
{item.${displayFields[2].propertyName} && <View>{item.${displayFields[2].propertyName}}</View>}
|
||||
<% } %>
|
||||
<View>创建: {dayjs(item.createTime).format('MM-DD HH:mm')}</View>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* 操作按钮 */}
|
||||
<View className="flex justify-end gap-2 pt-2 border-t border-gray-100">
|
||||
<Button
|
||||
size="small"
|
||||
fill="outline"
|
||||
icon={<Eye/>}
|
||||
onClick={() => handleView(item)}
|
||||
>
|
||||
查看
|
||||
</Button>
|
||||
<Button
|
||||
size="small"
|
||||
fill="outline"
|
||||
icon={<Edit/>}
|
||||
onClick={() => handleEdit(item)}
|
||||
>
|
||||
编辑
|
||||
</Button>
|
||||
<Button
|
||||
size="small"
|
||||
type="danger"
|
||||
fill="outline"
|
||||
icon={<Del/>}
|
||||
onClick={() => handleDelete(item.${primaryKey})}
|
||||
>
|
||||
删除
|
||||
</Button>
|
||||
</View>
|
||||
</View>
|
||||
</Cell>
|
||||
</CellGroup>
|
||||
))}
|
||||
</InfiniteLoading>
|
||||
)}
|
||||
</View>
|
||||
</PullToRefresh>
|
||||
|
||||
{/* 底部浮动按钮 */}
|
||||
<FixedButton
|
||||
text="新增${table.comment!'数据'}"
|
||||
icon={<Edit />}
|
||||
onClick={() => Taro.navigateTo({url: '/${package.ModuleName}/${table.entityPath}/add'})}
|
||||
/>
|
||||
</ConfigProvider>
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
export default ${entity}List;
|
||||
export default ${entity}Manage;
|
||||
|
||||
@@ -99,20 +99,31 @@
|
||||
|
||||
// 表格列配置
|
||||
const columns = ref<ColumnItem[]>([
|
||||
<% var displayedColumns = 0; %>
|
||||
<% var maxColumns = 6; // 最多显示6列(不包括操作列) %>
|
||||
<% for(field in table.fields) { %>
|
||||
<% if(field.propertyName != 'tenantId'){ %>
|
||||
<% if(field.propertyName != 'tenantId' && field.propertyName != 'updateTime' && field.propertyName != 'remark' && field.propertyName != 'description' && field.propertyName != 'content' && displayedColumns < maxColumns){ %>
|
||||
<% displayedColumns = displayedColumns + 1; %>
|
||||
{
|
||||
title: '${field.comment}',
|
||||
title: '${field.comment!field.propertyName}',
|
||||
dataIndex: '${field.propertyName}',
|
||||
key: '${field.propertyName}',
|
||||
align: 'center',
|
||||
<% if(field.keyFlag){ %>
|
||||
width: 90,
|
||||
<% } %>
|
||||
<% if(field.propertyName == 'createTime'){ %>
|
||||
<% } else if(field.propertyName == 'createTime'){ %>
|
||||
width: 120,
|
||||
sorter: true,
|
||||
ellipsis: true,
|
||||
customRender: ({ text }) => toDateString(text, 'yyyy-MM-dd')
|
||||
<% } else if(field.propertyType == 'String' && (field.comment?? && (field.comment?contains('名称') || field.comment?contains('标题')))){ %>
|
||||
width: 150,
|
||||
ellipsis: true
|
||||
<% } else if(field.propertyName == 'status'){ %>
|
||||
width: 80
|
||||
<% } else { %>
|
||||
width: 120,
|
||||
ellipsis: true
|
||||
<% } %>
|
||||
},
|
||||
<% } %>
|
||||
|
||||
@@ -82,6 +82,13 @@
|
||||
<% } %>
|
||||
<if test="param.keywords != null">
|
||||
AND (a.comments LIKE CONCAT('%', #{param.keywords}, '%')
|
||||
<% for(field in table.fields){ %>
|
||||
<% if(field.keyFlag){ %>
|
||||
OR a.${field.name} = #{param.keywords}
|
||||
<% } else if(field.propertyType == 'String' && (field.comment?? && (field.comment?contains('标题') || field.comment?contains('名称') || field.comment?contains('内容')))){ %>
|
||||
OR a.${field.name} LIKE CONCAT('%', #{param.keywords}, '%')
|
||||
<% } %>
|
||||
<% } %>
|
||||
)
|
||||
</if>
|
||||
</where>
|
||||
|
||||
Reference in New Issue
Block a user