Browse Source
- 新增 QUICK_FORM 类型常量和相关数据库字段映射 - 实现快捷表单保存、更新、删除和克隆功能 - 添加在线首页配置模型、控制器、服务和数据访问层 - 修复同表同名列重复插入导致的数据脏问题 - 优化 OnlineColumn 查询避免 TooManyResultsException 异常 - 支持快捷表单组件 JSON 中的列 ID 回填功能 - 增强字段引用解析和过滤规则写入机制 - 优化事务处理确保数据一致性pull/1/head
26 changed files with 1926 additions and 24 deletions
@ -0,0 +1,58 @@
@@ -0,0 +1,58 @@
|
||||
package apelet.common.online.controller; |
||||
|
||||
import apelet.common.core.annotation.MyRequestBody; |
||||
import apelet.common.core.object.ResponseResult; |
||||
import apelet.common.log.annotation.OperationLog; |
||||
import apelet.common.log.model.constant.SysOperationLogType; |
||||
import apelet.common.online.model.OnlineHomepageConfig; |
||||
import apelet.common.online.service.OnlineHomepageConfigService; |
||||
import io.swagger.v3.oas.annotations.tags.Tag; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; |
||||
import org.springframework.web.bind.annotation.PostMapping; |
||||
import org.springframework.web.bind.annotation.RequestMapping; |
||||
import org.springframework.web.bind.annotation.RestController; |
||||
|
||||
/** |
||||
* 功能: 在线首页配置 |
||||
* |
||||
* @author {chenchuchuan} |
||||
* @version 1.0 |
||||
*/ |
||||
@Tag(name = "在线首页配置接口") |
||||
@Slf4j |
||||
@RestController |
||||
@RequestMapping("${common-online.urlPrefix}/onlineHomepageConfig") |
||||
@ConditionalOnProperty(name = "common-online.operationEnabled", havingValue = "true") |
||||
public class OnlineHomepageConfigController { |
||||
|
||||
@Autowired |
||||
private OnlineHomepageConfigService onlineHomepageConfigService; |
||||
|
||||
|
||||
/** |
||||
* 保存或更新在线表单数据。 |
||||
* |
||||
* @param onlineHomepageConfig 更新对象。 |
||||
* @return 应答结果对象。 |
||||
*/ |
||||
@OperationLog(type = SysOperationLogType.UPDATE) |
||||
@PostMapping("/saveOrUpdate") |
||||
public ResponseResult<Void> saveOrUpdate(@MyRequestBody String onlineHomepageConfig) { |
||||
onlineHomepageConfigService.updateOrSave(onlineHomepageConfig); |
||||
return ResponseResult.success(); |
||||
} |
||||
|
||||
/** |
||||
* 根据用户信息查询在线表单数据。 |
||||
* |
||||
* @return 应答结果对象。 |
||||
*/ |
||||
@PostMapping("/queryByUserInfo") |
||||
public ResponseResult<OnlineHomepageConfig> queryByUserInfo() { |
||||
return ResponseResult.success(onlineHomepageConfigService.queryByUser()); |
||||
|
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,13 @@
@@ -0,0 +1,13 @@
|
||||
package apelet.common.online.dao; |
||||
|
||||
import apelet.common.core.base.dao.BaseDaoMapper; |
||||
import apelet.common.online.model.OnlineHomepageConfig; |
||||
|
||||
/** |
||||
* 功能: 在线首页配置数据访问层 |
||||
* |
||||
* @author {chenchuchuan} |
||||
* @version 1.0 |
||||
*/ |
||||
public interface OnlineHomepageConfigMapper extends BaseDaoMapper<OnlineHomepageConfig> { |
||||
} |
||||
@ -0,0 +1,13 @@
@@ -0,0 +1,13 @@
|
||||
package apelet.common.online.dao; |
||||
|
||||
import apelet.common.core.base.dao.BaseDaoMapper; |
||||
import apelet.common.online.model.OnlineQuickFormField; |
||||
|
||||
/** |
||||
* 在线快捷表单字段数据操作访问接口。 |
||||
* |
||||
* @author chenchuchuan |
||||
* @date 2026-08-18 |
||||
*/ |
||||
public interface OnlineQuickFormFieldMapper extends BaseDaoMapper<OnlineQuickFormField> { |
||||
} |
||||
@ -0,0 +1,26 @@
@@ -0,0 +1,26 @@
|
||||
package apelet.common.online.dao; |
||||
|
||||
import apelet.common.core.base.dao.BaseDaoMapper; |
||||
import apelet.common.online.model.OnlineQuickForm; |
||||
import org.apache.ibatis.annotations.Param; |
||||
|
||||
import java.util.List; |
||||
|
||||
/** |
||||
* 在线快捷表单数据操作访问接口。 |
||||
* |
||||
* @author chenchuchuan |
||||
* @date 2026-08-18 |
||||
*/ |
||||
public interface OnlineQuickFormMapper extends BaseDaoMapper<OnlineQuickForm> { |
||||
|
||||
/** |
||||
* 获取过滤后的对象列表。 |
||||
* |
||||
* @param onlineFormFilter 主表过滤对象。 |
||||
* @param orderBy 排序字符串,order by从句的参数。 |
||||
* @return 对象列表。 |
||||
*/ |
||||
List<OnlineQuickForm> getOnlineFormList( |
||||
@Param("onlineFormFilter") OnlineQuickForm onlineFormFilter, @Param("orderBy") String orderBy); |
||||
} |
||||
@ -0,0 +1,59 @@
@@ -0,0 +1,59 @@
|
||||
<?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="apelet.common.online.dao.OnlineQuickFormMapper"> |
||||
<resultMap id="BaseResultMap" type="apelet.common.online.model.OnlineQuickForm"> |
||||
<id column="id" jdbcType="BIGINT" property="id"/> |
||||
<result column="tenant_id" jdbcType="BIGINT" property="tenantId"/> |
||||
<result column="app_code" jdbcType="VARCHAR" property="appCode"/> |
||||
<result column="page_id" jdbcType="BIGINT" property="pageId"/> |
||||
<result column="quick_form_code" jdbcType="VARCHAR" property="quickFormCode"/> |
||||
<result column="quick_form_name" jdbcType="VARCHAR" property="quickFormName"/> |
||||
<result column="layout_type" jdbcType="INTEGER" property="layoutType"/> |
||||
<result column="master_table_id" jdbcType="BIGINT" property="masterTableId"/> |
||||
<result column="create_time" jdbcType="TIMESTAMP" property="createTime"/> |
||||
<result column="create_user_id" jdbcType="BIGINT" property="createUserId"/> |
||||
<result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/> |
||||
<result column="update_user_id" jdbcType="BIGINT" property="updateUserId"/> |
||||
</resultMap> |
||||
|
||||
<!-- 这里仅包含调用接口输入的主表过滤条件 --> |
||||
<sql id="inputFilterRef"> |
||||
<if test="onlineFormFilter != null"> |
||||
<if test="onlineFormFilter.tenantId == null"> |
||||
AND zz_online_quick_form.tenant_id IS NULL |
||||
</if> |
||||
<if test="onlineFormFilter.tenantId != null"> |
||||
AND zz_online_quick_form.tenant_id = #{onlineFormFilter.tenantId} |
||||
</if> |
||||
<if test="onlineFormFilter.appCode == null"> |
||||
AND zz_online_quick_form.app_code IS NULL |
||||
</if> |
||||
<if test="onlineFormFilter.appCode != null"> |
||||
AND zz_online_quick_form.app_code = #{onlineFormFilter.appCode} |
||||
</if> |
||||
<if test="onlineFormFilter.pageId != null"> |
||||
AND zz_online_quick_form.page_id = #{onlineFormFilter.pageId} |
||||
</if> |
||||
<if test="onlineFormFilter.quickFormCode != null and onlineFormFilter.quickFormCode != ''"> |
||||
AND zz_online_quick_form.quick_form_code = #{onlineFormFilter.quickFormCode} |
||||
</if> |
||||
<if test="onlineFormFilter.quickFormName != null and onlineFormFilter.quickFormName != ''"> |
||||
<bind name="safeQuickFormName" value="'%' + onlineFormFilter.quickFormName + '%'"/> |
||||
AND zz_online_quick_form.quick_form_name LIKE #{safeQuickFormName} |
||||
</if> |
||||
<if test="onlineFormFilter.masterTableId != null"> |
||||
AND zz_online_quick_form.master_table_id = #{onlineFormFilter.masterTableId} |
||||
</if> |
||||
</if> |
||||
</sql> |
||||
|
||||
<select id="getOnlineFormList" resultMap="BaseResultMap" parameterType="apelet.common.online.model.OnlineQuickForm"> |
||||
SELECT * FROM zz_online_quick_form |
||||
<where> |
||||
<include refid="inputFilterRef"/> |
||||
</where> |
||||
<if test="orderBy != null and orderBy != ''"> |
||||
ORDER BY ${orderBy} |
||||
</if> |
||||
</select> |
||||
</mapper> |
||||
@ -0,0 +1,66 @@
@@ -0,0 +1,66 @@
|
||||
package apelet.common.online.model; |
||||
|
||||
import com.baomidou.mybatisplus.annotation.*; |
||||
import lombok.Data; |
||||
|
||||
import java.io.Serializable; |
||||
import java.util.Date; |
||||
|
||||
/** |
||||
* 在线自定义首页实体 |
||||
*/ |
||||
@Data |
||||
@TableName("zz_online_homepage_config") |
||||
public class OnlineHomepageConfig implements Serializable { |
||||
|
||||
private static final long serialVersionUID = 1L; |
||||
|
||||
/** |
||||
* 主键Id |
||||
*/ |
||||
@TableId(value = "id", type = IdType.ASSIGN_ID) |
||||
private Long id; |
||||
|
||||
/** |
||||
* 租户id |
||||
*/ |
||||
@TableField("tenant_id") |
||||
private Long tenantId; |
||||
|
||||
/** |
||||
* 应用编码 |
||||
*/ |
||||
@TableField("app_code") |
||||
private String appCode; |
||||
|
||||
/** |
||||
* 首页组件JSON |
||||
*/ |
||||
@TableField("widget_json") |
||||
private String widgetJson; |
||||
|
||||
/** |
||||
* 创建时间 |
||||
*/ |
||||
@TableField(value = "create_time", fill = FieldFill.INSERT) |
||||
private Date createTime; |
||||
|
||||
/** |
||||
* 创建者 |
||||
*/ |
||||
@TableField("create_user_id") |
||||
private Long createUserId; |
||||
|
||||
/** |
||||
* 更新时间 |
||||
*/ |
||||
@TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE) |
||||
private Date updateTime; |
||||
|
||||
/** |
||||
* 更新者 |
||||
*/ |
||||
@TableField("update_user_id") |
||||
private Long updateUserId; |
||||
|
||||
} |
||||
@ -0,0 +1,142 @@
@@ -0,0 +1,142 @@
|
||||
package apelet.common.online.model; |
||||
|
||||
import apelet.common.core.annotation.RelationConstDict; |
||||
import apelet.common.core.annotation.RelationDict; |
||||
import apelet.common.core.annotation.RelationOneToMany; |
||||
import apelet.common.core.annotation.RelationOneToOne; |
||||
import apelet.common.core.base.mapper.BaseModelMapper; |
||||
import apelet.common.online.model.constant.FormType; |
||||
import apelet.common.online.vo.OnlineFormVo; |
||||
import com.baomidou.mybatisplus.annotation.TableField; |
||||
import com.baomidou.mybatisplus.annotation.TableId; |
||||
import com.baomidou.mybatisplus.annotation.TableName; |
||||
import lombok.Data; |
||||
import org.mapstruct.Mapper; |
||||
import org.mapstruct.Mapping; |
||||
import org.mapstruct.factory.Mappers; |
||||
|
||||
import java.util.Date; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* 在线快捷表单实体对象。 |
||||
* |
||||
* @author chenchuchuan |
||||
* @date 2026-08-18 |
||||
*/ |
||||
@Data |
||||
@TableName(value = "zz_online_quick_form") |
||||
public class OnlineQuickForm { |
||||
|
||||
public static final OnlineQuickForm.OnlineFormModelMapper INSTANCE = Mappers.getMapper(OnlineQuickForm.OnlineFormModelMapper.class); |
||||
/** |
||||
* 主键Id。 |
||||
*/ |
||||
@TableId(value = "id") |
||||
private Long id; |
||||
/** |
||||
* 租户Id。 |
||||
*/ |
||||
@TableField(value = "tenant_id") |
||||
private Long tenantId; |
||||
/** |
||||
* 应用编码。 |
||||
*/ |
||||
@TableField(value = "app_code") |
||||
private String appCode; |
||||
/** |
||||
* 页面id。 |
||||
*/ |
||||
@TableField(value = "page_id") |
||||
private Long pageId; |
||||
/** |
||||
* 快捷表单编码。 |
||||
*/ |
||||
@TableField(value = "quick_form_code") |
||||
private String quickFormCode; |
||||
/** |
||||
* 快捷表单名称。 |
||||
*/ |
||||
@TableField(value = "quick_form_name") |
||||
private String quickFormName; |
||||
/** |
||||
* 排版类型。 |
||||
*/ |
||||
@TableField(value = "layout_type") |
||||
private Integer layoutType; |
||||
/** |
||||
* 表单主表id。 |
||||
*/ |
||||
@TableField(value = "master_table_id") |
||||
private Long masterTableId; |
||||
/** |
||||
* 创建时间。 |
||||
*/ |
||||
@TableField(value = "create_time") |
||||
private Date createTime; |
||||
/** |
||||
* 创建者。 |
||||
*/ |
||||
@TableField(value = "create_user_id") |
||||
private Long createUserId; |
||||
/** |
||||
* 更新时间。 |
||||
*/ |
||||
@TableField(value = "update_time") |
||||
private Date updateTime; |
||||
/** |
||||
* 更新者。 |
||||
*/ |
||||
@TableField(value = "update_user_id") |
||||
private Long updateUserId; |
||||
/** |
||||
* 表单类型(快捷表单固定为 FormType.QUICK_FORM,非数据库列)。 |
||||
*/ |
||||
@TableField(exist = false) |
||||
private Integer formType; |
||||
@RelationOneToOne(masterIdField = "masterTableId", slaveModelClass = OnlineTable.class, slaveIdField = "tableId") |
||||
@TableField(exist = false) |
||||
private OnlineTable onlineTable; |
||||
@RelationDict(masterIdField = "masterTableId", equalOneToOneRelationField = "onlineTable", slaveModelClass = OnlineTable.class, slaveIdField = "tableId", slaveNameField = "modelName") |
||||
@TableField(exist = false) |
||||
private Map<String, Object> masterTableIdDictMap; |
||||
@RelationConstDict( |
||||
masterIdField = "formType", |
||||
constantDictClass = FormType.class) |
||||
@TableField(exist = false) |
||||
private Map<String, Object> formTypeDictMap; |
||||
@RelationOneToMany(masterIdField = "id", slaveModelClass = OnlineQuickFormField.class, slaveIdField = "quickFormId") |
||||
@TableField(exist = false) |
||||
private List<OnlineQuickFormField> onlineQuickFormFields; |
||||
|
||||
@Mapper |
||||
public interface OnlineFormModelMapper extends BaseModelMapper<OnlineFormVo, OnlineQuickForm> { |
||||
/** |
||||
* 转换Vo对象到实体对象。 |
||||
* |
||||
* @param onlineFormVo 域对象。 |
||||
* @return 实体对象。 |
||||
*/ |
||||
@Mapping(target = "onlineTable", expression = "java(mapToBean(onlineFormVo.getOnlineTable(), apelet.common.online.model.OnlineTable.class))") |
||||
@Override |
||||
OnlineQuickForm toModel(OnlineFormVo onlineFormVo); |
||||
|
||||
/** |
||||
* 转换实体对象到VO对象。 |
||||
* |
||||
* @param onlineForm 实体对象。 |
||||
* @return 域对象。 |
||||
*/ |
||||
@Mapping(target = "formKind", expression = "java(apelet.common.online.model.constant.FormKind.NEW_PAGE)") |
||||
@Mapping(target = "formType", expression = "java(apelet.common.online.model.constant.FormType.QUICK_FORM)") |
||||
@Mapping(target = "formName", expression = "java(onlineForm.getQuickFormName())") |
||||
@Mapping(target = "formCode", expression = "java(onlineForm.getQuickFormCode())") |
||||
@Mapping(target = "formId", expression = "java(onlineForm.getId())") |
||||
@Mapping(target = "quickFormId", expression = "java(onlineForm.getId())") |
||||
@Mapping(target = "onlineTable", expression = "java(beanToMap(onlineForm.getOnlineTable(), false))") |
||||
@Mapping(target = "onlineQuickFormFields", expression = "java(onlineForm.getOnlineQuickFormFields() == null ? java.util.Collections.emptyList() : onlineForm.getOnlineQuickFormFields())") |
||||
@Override |
||||
OnlineFormVo fromModel(OnlineQuickForm onlineForm); |
||||
} |
||||
} |
||||
@ -0,0 +1,187 @@
@@ -0,0 +1,187 @@
|
||||
package apelet.common.online.model; |
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField; |
||||
import com.baomidou.mybatisplus.annotation.TableId; |
||||
import com.baomidou.mybatisplus.annotation.TableName; |
||||
import lombok.Data; |
||||
|
||||
import java.util.Date; |
||||
|
||||
/** |
||||
* 在线快捷表单字段实体对象。 |
||||
* |
||||
* @author chenchuchuan |
||||
* @date 2026-08-18 |
||||
*/ |
||||
@Data |
||||
@TableName(value = "zz_online_quick_form_field") |
||||
public class OnlineQuickFormField { |
||||
|
||||
/** |
||||
* 主键Id。 |
||||
*/ |
||||
@TableId(value = "id") |
||||
private Long id; |
||||
|
||||
/** |
||||
* 快捷表单id。 |
||||
*/ |
||||
@TableField(value = "quick_form_id") |
||||
private Long quickFormId; |
||||
|
||||
/** |
||||
* 字段名称。 |
||||
*/ |
||||
@TableField(value = "field_name") |
||||
private String fieldName; |
||||
|
||||
/** |
||||
* 字段备注。 |
||||
*/ |
||||
@TableField(value = "field_remark") |
||||
private String fieldRemark; |
||||
|
||||
/** |
||||
* 字段长度。 |
||||
*/ |
||||
@TableField(value = "field_length") |
||||
private Integer fieldLength; |
||||
|
||||
/** |
||||
* 小数点位数。 |
||||
*/ |
||||
@TableField(value = "field_point") |
||||
private Integer fieldPoint; |
||||
|
||||
/** |
||||
* 字段类型(前端展示类型,即组件widgetType)。 |
||||
*/ |
||||
@TableField(value = "field_type") |
||||
private Integer fieldType; |
||||
|
||||
/** |
||||
* 关联 zz_online_column 列ID(前端传入;为空=新增字段待建列,非空=已有字段仅修改)。 |
||||
*/ |
||||
@TableField(value = "column_id") |
||||
private Long columnId; |
||||
|
||||
/** |
||||
* 是否为主键:0-否,1-是。 |
||||
*/ |
||||
@TableField(value = "is_key") |
||||
private Integer isKey; |
||||
|
||||
/** |
||||
* 默认值。 |
||||
*/ |
||||
@TableField(value = "default_value") |
||||
private String defaultValue; |
||||
|
||||
/** |
||||
* 是否允许为空:0-否,1-是。 |
||||
*/ |
||||
@TableField(value = "is_empty") |
||||
private Integer isEmpty; |
||||
|
||||
/** |
||||
* 是否为默认字段:0-否,1-是。 |
||||
*/ |
||||
@TableField(value = "is_default") |
||||
private Integer isDefault; |
||||
|
||||
/** |
||||
* 是否列表展示:0-否,1-是。 |
||||
*/ |
||||
@TableField(value = "is_list") |
||||
private Integer isList; |
||||
|
||||
/** |
||||
* 是否过滤条件:0-否,1-是。 |
||||
*/ |
||||
@TableField(value = "is_filter") |
||||
private Integer isFilter; |
||||
|
||||
/** |
||||
* 过滤方案,参考FieldFilterType常量。 |
||||
*/ |
||||
@TableField(value = "filter_type") |
||||
private Integer filterType; |
||||
|
||||
/** |
||||
* 关联元数据ID。 |
||||
*/ |
||||
@TableField(value = "ref_property") |
||||
private Long refProperty; |
||||
|
||||
/** |
||||
* 关联数据字典ID。 |
||||
*/ |
||||
@TableField(value = "ref_dict") |
||||
private Long refDict; |
||||
|
||||
/** |
||||
* 关联数据字典名称。 |
||||
*/ |
||||
@TableField(value = "ref_dict_name") |
||||
private String refDictName; |
||||
|
||||
/** |
||||
* 关联在线表单id(F7关联字段,前端传入,用于解析关联表,不落库)。 |
||||
*/ |
||||
@TableField(exist = false) |
||||
private Long formId; |
||||
|
||||
/** |
||||
* 关联在线表单显示字段(F7关联字段,前端传入,不落库)。 |
||||
*/ |
||||
@TableField(exist = false) |
||||
private String displayField; |
||||
|
||||
/** |
||||
* 关联表头id(F7关联字段,由关联在线表单解析出 onl_form_head.id,用于 F7 控件 slaveTableId 与 onl_form_field.ref_propert 回写,不落库)。 |
||||
*/ |
||||
@TableField(exist = false) |
||||
private Long refTableId; |
||||
|
||||
/** |
||||
* 关联表名(F7关联字段,由关联在线表单解析,不落库)。 |
||||
*/ |
||||
@TableField(exist = false) |
||||
private String refTableName; |
||||
|
||||
/** |
||||
* 关联在线表单编码(F7关联字段,由关联在线表单解析,用于 relativeFormCode,不落库)。 |
||||
*/ |
||||
@TableField(exist = false) |
||||
private String refFormCode; |
||||
|
||||
/** |
||||
* 租户ID。 |
||||
*/ |
||||
@TableField(value = "tenant_id") |
||||
private Long tenantId; |
||||
|
||||
/** |
||||
* 创建时间。 |
||||
*/ |
||||
@TableField(value = "create_time") |
||||
private Date createTime; |
||||
|
||||
/** |
||||
* 创建人ID。 |
||||
*/ |
||||
@TableField(value = "create_user_id") |
||||
private Long createUserId; |
||||
|
||||
/** |
||||
* 更新时间。 |
||||
*/ |
||||
@TableField(value = "update_time") |
||||
private Date updateTime; |
||||
|
||||
/** |
||||
* 更新人ID。 |
||||
*/ |
||||
@TableField(value = "update_user_id") |
||||
private Long updateUserId; |
||||
} |
||||
@ -0,0 +1,30 @@
@@ -0,0 +1,30 @@
|
||||
package apelet.common.online.service; |
||||
|
||||
import apelet.common.core.base.service.IBaseService; |
||||
import apelet.common.online.model.OnlineHomepageConfig; |
||||
|
||||
/** |
||||
* 功能: 在线首页配置 |
||||
* |
||||
* @author {chenchuchuan} |
||||
* @version 1.0 |
||||
*/ |
||||
public interface OnlineHomepageConfigService extends IBaseService<OnlineHomepageConfig, Long> { |
||||
|
||||
|
||||
/** |
||||
* 修改在线首页配置 |
||||
* |
||||
* @param onlineHomepageConfig 在线首页配置 |
||||
* @return 是否修改成功 |
||||
*/ |
||||
boolean updateOrSave(String onlineHomepageConfig); |
||||
|
||||
/** |
||||
* 根据用户查询在线首页配置 |
||||
* |
||||
* @return 在线首页配置 |
||||
*/ |
||||
OnlineHomepageConfig queryByUser(); |
||||
|
||||
} |
||||
@ -0,0 +1,13 @@
@@ -0,0 +1,13 @@
|
||||
package apelet.common.online.service; |
||||
|
||||
import apelet.common.core.base.service.IBaseService; |
||||
import apelet.common.online.model.OnlineQuickFormField; |
||||
|
||||
/** |
||||
* 在线快捷表单字段数据操作服务接口。 |
||||
* |
||||
* @author chenchuchuan |
||||
* @date 2026-08-18 |
||||
*/ |
||||
public interface OnlineQuickFormFieldService extends IBaseService<OnlineQuickFormField, Long> { |
||||
} |
||||
@ -0,0 +1,36 @@
@@ -0,0 +1,36 @@
|
||||
package apelet.common.online.service; |
||||
|
||||
import apelet.common.core.base.service.IBaseService; |
||||
import apelet.common.online.model.OnlineQuickForm; |
||||
|
||||
import java.util.List; |
||||
|
||||
/** |
||||
* 在线快捷表单数据操作服务接口。 |
||||
* |
||||
* @author chenchuchuan |
||||
* @date 2026-08-18 |
||||
*/ |
||||
public interface OnlineQuickFormService extends IBaseService<OnlineQuickForm, Long> { |
||||
|
||||
/** |
||||
* 获取单表查询结果。由于没有关联数据查询,因此在仅仅获取单表数据的场景下,效率更高。 |
||||
* 如果需要同时获取关联数据,请移步(getOnlineFormListWithRelation)方法。 |
||||
* |
||||
* @param filter 过滤对象。 |
||||
* @param orderBy 排序参数。 |
||||
* @return 查询结果集。 |
||||
*/ |
||||
List<OnlineQuickForm> getOnlineFormList(OnlineQuickForm filter, String orderBy); |
||||
|
||||
/** |
||||
* 获取主表的查询结果,以及主表关联的字典数据和一对一从表数据,以及一对一从表的字典数据。 |
||||
* 该查询会涉及到一对一从表的关联过滤,或一对多从表的嵌套关联过滤,因此性能不如单表过滤。 |
||||
* 如果仅仅需要获取主表数据,请移步(getOnlineFormList),以便获取更好的查询性能。 |
||||
* |
||||
* @param filter 主表过滤对象。 |
||||
* @param orderBy 排序参数。 |
||||
* @return 查询结果集。 |
||||
*/ |
||||
List<OnlineQuickForm> getOnlineFormListWithRelation(OnlineQuickForm filter, String orderBy); |
||||
} |
||||
@ -0,0 +1,73 @@
@@ -0,0 +1,73 @@
|
||||
package apelet.common.online.service.impl; |
||||
|
||||
import apelet.common.core.annotation.MyDataSourceResolver; |
||||
import apelet.common.core.base.service.BaseService; |
||||
import apelet.common.core.constant.ApplicationConstant; |
||||
import apelet.common.core.object.TokenData; |
||||
import apelet.common.core.util.DefaultDataSourceResolver; |
||||
import apelet.common.online.dao.OnlineHomepageConfigMapper; |
||||
import apelet.common.online.model.OnlineHomepageConfig; |
||||
import apelet.common.online.service.OnlineHomepageConfigService; |
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.apache.commons.lang3.StringUtils; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.stereotype.Service; |
||||
|
||||
import java.util.Date; |
||||
|
||||
/** |
||||
* 功能: 在线首页配置服务实现类 |
||||
* |
||||
* @author {chenchuchuan} |
||||
* @version 1.0 |
||||
*/ |
||||
@Slf4j |
||||
@MyDataSourceResolver(resolver = DefaultDataSourceResolver.class, intArg = ApplicationConstant.COMMON_FLOW_AND_ONLINE_DATASOURCE_TYPE) |
||||
@Service("OnlineHomepageConfigService") |
||||
public class OnlineHomepageConfigServiceImpl extends BaseService<OnlineHomepageConfig, Long> implements OnlineHomepageConfigService { |
||||
|
||||
@Autowired |
||||
private OnlineHomepageConfigMapper onlineHomepageConfigMapper; |
||||
|
||||
@Override |
||||
public OnlineHomepageConfigMapper mapper() { |
||||
return onlineHomepageConfigMapper; |
||||
} |
||||
|
||||
@Override |
||||
public boolean updateOrSave(String onlineHomepageConfig) { |
||||
if (StringUtils.isBlank(onlineHomepageConfig)) { |
||||
return false; |
||||
} |
||||
OnlineHomepageConfig homepageConfig = this.queryByUser(); |
||||
homepageConfig.setWidgetJson(onlineHomepageConfig); |
||||
Date date = new Date(); |
||||
TokenData tokenData = TokenData.takeFromRequest(); |
||||
homepageConfig.setAppCode(tokenData.getAppCode()); |
||||
homepageConfig.setTenantId(tokenData.getTenantId()); |
||||
homepageConfig.setUpdateUserId(tokenData.getUserId()); |
||||
homepageConfig.setUpdateTime(date); |
||||
if (homepageConfig.getId() == null) { |
||||
homepageConfig.setCreateTime(date); |
||||
homepageConfig.setCreateUserId(tokenData.getUserId()); |
||||
return onlineHomepageConfigMapper.insert(homepageConfig) >= 0; |
||||
} |
||||
return onlineHomepageConfigMapper.updateById(homepageConfig) >= 0; |
||||
} |
||||
|
||||
@Override |
||||
public OnlineHomepageConfig queryByUser() { |
||||
TokenData tokenData = TokenData.takeFromRequest(); |
||||
LambdaQueryWrapper<OnlineHomepageConfig> lambdaQueryWrapper = new LambdaQueryWrapper<>(); |
||||
lambdaQueryWrapper.eq(StringUtils.isNotBlank(tokenData.getAppCode()), OnlineHomepageConfig::getAppCode, tokenData.getAppCode()); |
||||
lambdaQueryWrapper.eq(tokenData.getTenantId() != null, OnlineHomepageConfig::getTenantId, tokenData.getTenantId()); |
||||
lambdaQueryWrapper.eq(OnlineHomepageConfig::getCreateUserId, tokenData.getUserId()); |
||||
OnlineHomepageConfig homepageConfig = onlineHomepageConfigMapper.selectOne(lambdaQueryWrapper); |
||||
if (homepageConfig == null) { |
||||
homepageConfig = new OnlineHomepageConfig(); |
||||
} |
||||
return homepageConfig; |
||||
|
||||
} |
||||
} |
||||
@ -0,0 +1,35 @@
@@ -0,0 +1,35 @@
|
||||
package apelet.common.online.service.impl; |
||||
|
||||
import apelet.common.core.annotation.MyDataSourceResolver; |
||||
import apelet.common.core.base.dao.BaseDaoMapper; |
||||
import apelet.common.core.base.service.BaseService; |
||||
import apelet.common.core.constant.ApplicationConstant; |
||||
import apelet.common.core.util.DefaultDataSourceResolver; |
||||
import apelet.common.online.dao.OnlineQuickFormFieldMapper; |
||||
import apelet.common.online.model.OnlineQuickFormField; |
||||
import apelet.common.online.service.OnlineQuickFormFieldService; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.stereotype.Service; |
||||
|
||||
/** |
||||
* 在线快捷表单字段数据操作服务类。 |
||||
* |
||||
* @author chenchuchuan |
||||
* @date 2026-08-18 |
||||
*/ |
||||
@Slf4j |
||||
@MyDataSourceResolver( |
||||
resolver = DefaultDataSourceResolver.class, |
||||
intArg = ApplicationConstant.COMMON_FLOW_AND_ONLINE_DATASOURCE_TYPE) |
||||
@Service("onlineQuickFormFieldService") |
||||
public class OnlineQuickFormFieldServiceImpl extends BaseService<OnlineQuickFormField, Long> implements OnlineQuickFormFieldService { |
||||
|
||||
@Autowired |
||||
private OnlineQuickFormFieldMapper onlineQuickFormFieldMapper; |
||||
|
||||
@Override |
||||
protected BaseDaoMapper<OnlineQuickFormField> mapper() { |
||||
return onlineQuickFormFieldMapper; |
||||
} |
||||
} |
||||
@ -0,0 +1,81 @@
@@ -0,0 +1,81 @@
|
||||
package apelet.common.online.service.impl; |
||||
|
||||
import apelet.common.core.annotation.MyDataSourceResolver; |
||||
import apelet.common.core.base.dao.BaseDaoMapper; |
||||
import apelet.common.core.base.service.BaseService; |
||||
import apelet.common.core.constant.ApplicationConstant; |
||||
import apelet.common.core.object.MyRelationParam; |
||||
import apelet.common.core.object.TokenData; |
||||
import apelet.common.core.util.DefaultDataSourceResolver; |
||||
import apelet.common.online.dao.OnlineQuickFormMapper; |
||||
import apelet.common.online.model.OnlineQuickForm; |
||||
import apelet.common.online.model.constant.FormType; |
||||
import apelet.common.online.service.OnlineQuickFormService; |
||||
import com.github.pagehelper.Page; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.stereotype.Service; |
||||
|
||||
import java.util.List; |
||||
|
||||
/** |
||||
* 在线快捷表单数据操作服务类。 |
||||
* |
||||
* @author chenchuchuan |
||||
* @date 2026-08-18 |
||||
*/ |
||||
@Slf4j |
||||
@MyDataSourceResolver(resolver = DefaultDataSourceResolver.class, intArg = ApplicationConstant.COMMON_FLOW_AND_ONLINE_DATASOURCE_TYPE) |
||||
@Service("onlineQuickFormService") |
||||
public class OnlineQuickFormServiceImpl extends BaseService<OnlineQuickForm, Long> implements OnlineQuickFormService { |
||||
|
||||
@Autowired |
||||
private OnlineQuickFormMapper onlineQuickFormMapper; |
||||
|
||||
@Override |
||||
protected BaseDaoMapper<OnlineQuickForm> mapper() { |
||||
return onlineQuickFormMapper; |
||||
} |
||||
|
||||
/** |
||||
* 获取单表查询结果。由于没有关联数据查询,因此在仅仅获取单表数据的场景下,效率更高。 |
||||
* 如果需要同时获取关联数据,请移步(getOnlineFormListWithRelation)方法。 |
||||
* |
||||
* @param filter 过滤对象。 |
||||
* @param orderBy 排序参数。 |
||||
* @return 查询结果集。 |
||||
*/ |
||||
@Override |
||||
public List<OnlineQuickForm> getOnlineFormList(OnlineQuickForm filter, String orderBy) { |
||||
if (filter == null) { |
||||
filter = new OnlineQuickForm(); |
||||
} |
||||
TokenData tokenData = TokenData.takeFromRequest(); |
||||
filter.setTenantId(tokenData.getTenantId()); |
||||
filter.setAppCode(tokenData.getAppCode()); |
||||
List<OnlineQuickForm> resultList = onlineQuickFormMapper.getOnlineFormList(filter, orderBy); |
||||
// 快捷表单固定为快捷表单类型,回填用于 formTypeDictMap 关联展示
|
||||
resultList.forEach(qf -> qf.setFormType(FormType.QUICK_FORM)); |
||||
return resultList; |
||||
} |
||||
|
||||
/** |
||||
* 获取主表的查询结果,以及主表关联的字典数据和一对一从表数据,以及一对一从表的字典数据。 |
||||
* 该查询会涉及到一对一从表的关联过滤,或一对多从表的嵌套关联过滤,因此性能不如单表过滤。 |
||||
* 如果仅仅需要获取主表数据,请移步(getOnlineFormList),以便获取更好的查询性能。 |
||||
* |
||||
* @param filter 主表过滤对象。 |
||||
* @param orderBy 排序参数。 |
||||
* @return 查询结果集。 |
||||
*/ |
||||
@Override |
||||
public List<OnlineQuickForm> getOnlineFormListWithRelation(OnlineQuickForm filter, String orderBy) { |
||||
List<OnlineQuickForm> resultList = this.getOnlineFormList(filter, orderBy); |
||||
// 在缺省生成的代码中,如果查询结果resultList不是Page对象,说明没有分页,那么就很可能是数据导出接口调用了当前方法。
|
||||
// 为了避免一次性的大量数据关联,规避因此而造成的系统运行性能冲击,这里手动进行了分批次读取,开发者可按需修改该值。
|
||||
int batchSize = resultList instanceof Page ? 0 : 1000; |
||||
// 用 full() 加载 @RelationOneToMany 的 onlineQuickFormFields 等全部关联
|
||||
this.buildRelationForDataList(resultList, MyRelationParam.full(), batchSize); |
||||
return resultList; |
||||
} |
||||
} |
||||
@ -0,0 +1,584 @@
@@ -0,0 +1,584 @@
|
||||
package apelet.common.online.util; |
||||
|
||||
import apelet.common.online.model.OnlineQuickFormField; |
||||
import cn.hutool.core.io.IoUtil; |
||||
import cn.hutool.core.util.StrUtil; |
||||
import com.alibaba.fastjson.JSON; |
||||
import com.alibaba.fastjson.JSONArray; |
||||
import com.alibaba.fastjson.JSONObject; |
||||
import org.apache.commons.lang3.StringUtils; |
||||
|
||||
import java.io.IOException; |
||||
import java.io.InputStream; |
||||
import java.nio.charset.StandardCharsets; |
||||
import java.util.*; |
||||
import java.util.stream.Collectors; |
||||
|
||||
/** |
||||
* 快捷表单 widgetJson 生成工具类。 |
||||
* <p> |
||||
* 基于参考 json 模板(列表页/编辑页),根据快捷表单字段生成 pc/mobile 两套组件json。 |
||||
* 模板只提供结构外壳(operationList、tableWidget、listCard、leftWidget 等), |
||||
* 字段控件、绑定关系、按钮 formId 由字段数据重新生成。 |
||||
* |
||||
* @author chenchuchuan |
||||
* @date 2026-08-18 |
||||
*/ |
||||
public class QuickFormWidgetUtil { |
||||
|
||||
private static final String LIST_TEMPLATE = "quick-form/quick-form-list.json"; |
||||
private static final String EDIT_TEMPLATE = "quick-form/quick-form-edit.json"; |
||||
|
||||
private static final JSONObject LIST_TEMPLATE_JSON = load(LIST_TEMPLATE); |
||||
private static final JSONObject EDIT_TEMPLATE_JSON = load(EDIT_TEMPLATE); |
||||
|
||||
private QuickFormWidgetUtil() { |
||||
} |
||||
|
||||
private static JSONObject load(String path) { |
||||
try (InputStream in = QuickFormWidgetUtil.class.getClassLoader().getResourceAsStream(path)) { |
||||
if (in == null) { |
||||
throw new IllegalStateException("快捷表单模板不存在: " + path); |
||||
} |
||||
return JSON.parseObject(new String(IoUtil.readBytes(in), StandardCharsets.UTF_8)); |
||||
} catch (IOException e) { |
||||
throw new IllegalStateException("加载快捷表单模板失败: " + path, e); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 生成编辑页 widgetJson(pc + mobile)。 |
||||
* |
||||
* @param fields 快捷表单字段 |
||||
* @param bindId 控件绑定的数据id(参考json中编辑页/列表页为同一个快捷表单id) |
||||
* @param masterTableId 关联主表id |
||||
* @param masterTableName 关联主表名 |
||||
* @return widgetJson 根对象 |
||||
*/ |
||||
public static JSONObject buildEditWidgetJson(List<OnlineQuickFormField> fields, Long bindId, Long masterTableId, String masterTableName) { |
||||
JSONObject json = JSON.parseObject(EDIT_TEMPLATE_JSON.toJSONString()); |
||||
for (String device : new String[]{"pc", "mobile"}) { |
||||
JSONObject deviceObj = json.getJSONObject(device); |
||||
JSONArray widgetList = buildWidgetList(fields, device, bindId, masterTableId); |
||||
// 编辑页控件固定 supportOperation=false,与参考json一致
|
||||
for (int i = 0; i < widgetList.size(); i++) { |
||||
widgetList.getJSONObject(i).put("supportOperation", false); |
||||
} |
||||
deviceObj.put("widgetList", widgetList); |
||||
setSaveButtonEnabled(deviceObj); |
||||
rebuildMeta(deviceObj, fields, device, masterTableName, null); |
||||
} |
||||
return json; |
||||
} |
||||
|
||||
/** |
||||
* 生成列表页 widgetJson(pc + mobile)。 |
||||
* <p> |
||||
* 列表页结构(文档补充逻辑): |
||||
* <ul> |
||||
* <li>tableWidget 恒存在:pc 的 widgetType=100 表格,列来自 isList 字段的 tableColumnList;mobile 的 widgetType=103 列表卡片只放 isList 字段;</li> |
||||
* <li>查询区:pc 的 widgetList、mobile 的 tableWidget.childWidgetList(listCard 之后)只放 isFilter 的字段;</li> |
||||
* <li>其余字段只进编辑页,不进列表页。</li> |
||||
* </ul> |
||||
* |
||||
* @param fields 快捷表单字段 |
||||
* @param listFormId 列表页 zz_online_form 主键(用于 tableWidget variableName) |
||||
* @param editFormId 编辑页 zz_online_form 主键(关联到新建/编辑按钮) |
||||
* @param bindId 控件绑定的数据id(参考json中编辑页/列表页为同一个快捷表单id) |
||||
* @param masterTableId 关联主表id |
||||
* @param masterTableName 关联主表名 |
||||
* @param columnIdMap 字段名(小写) → zz_online_column.column_id,用于 tableColumnList 回填 |
||||
* @return widgetJson 根对象 |
||||
*/ |
||||
public static JSONObject buildListWidgetJson(List<OnlineQuickFormField> fields, Long listFormId, Long editFormId, Long bindId, Long masterTableId, String masterTableName, Map<String, Long> columnIdMap) { |
||||
JSONObject json = JSON.parseObject(LIST_TEMPLATE_JSON.toJSONString()); |
||||
String tableVar = "table" + listFormId; |
||||
List<OnlineQuickFormField> listFields = fields == null ? Collections.emptyList() : fields.stream().filter(QuickFormWidgetUtil::isListField).collect(Collectors.toList()); |
||||
List<OnlineQuickFormField> filterFields = fields == null ? Collections.emptyList() : fields.stream().filter(QuickFormWidgetUtil::isFilterField).collect(Collectors.toList()); |
||||
for (String device : new String[]{"pc", "mobile"}) { |
||||
JSONObject deviceObj = json.getJSONObject(device); |
||||
setButtonFormId(deviceObj, editFormId); |
||||
JSONObject tableWidget = deviceObj.getJSONObject("tableWidget"); |
||||
if (tableWidget != null) { |
||||
tableWidget.put("variableName", tableVar); |
||||
JSONObject bindData = tableWidget.getJSONObject("bindData"); |
||||
if (bindData == null) { |
||||
bindData = new JSONObject(); |
||||
tableWidget.put("bindData", bindData); |
||||
} |
||||
if ("pc".equals(device)) { |
||||
// 参考:pc tableWidget 才有 id/tableId,mobile 只有 defaultValue/dataType
|
||||
bindData.put("id", bindId); |
||||
bindData.put("tableId", masterTableId); |
||||
} |
||||
} |
||||
if ("pc".equals(device)) { |
||||
deviceObj.put("widgetList", buildWidgetList(filterFields, device, bindId, masterTableId)); |
||||
if (tableWidget != null) { |
||||
JSONObject props = tableWidget.getJSONObject("props"); |
||||
if (props != null) { |
||||
props.put("tableColumnList", buildTableColumnList(listFields, masterTableId, columnIdMap)); |
||||
} |
||||
} |
||||
rebuildMeta(deviceObj, filterFields, device, masterTableName, tableVar); |
||||
} else { |
||||
rebuildMobileList(deviceObj, listFields, filterFields, bindId, listFormId, masterTableId); |
||||
rebuildMeta(deviceObj, mergeFields(listFields, filterFields), device, masterTableName, tableVar); |
||||
} |
||||
} |
||||
return json; |
||||
} |
||||
|
||||
/** |
||||
* 是否列表展示字段。 |
||||
*/ |
||||
private static boolean isListField(OnlineQuickFormField field) { |
||||
return field != null && field.getIsList() != null && field.getIsList() == 1; |
||||
} |
||||
|
||||
/** |
||||
* 是否过滤字段:是过滤条件即进查询区;filterType 决定数据过滤方式,不影响控件展示。 |
||||
*/ |
||||
private static boolean isFilterField(OnlineQuickFormField field) { |
||||
return field != null && field.getIsFilter() != null && field.getIsFilter() == 1; |
||||
} |
||||
|
||||
/** |
||||
* 合并列表展示字段与过滤字段(按字段名去重,列表展示优先)。 |
||||
*/ |
||||
private static List<OnlineQuickFormField> mergeFields(List<OnlineQuickFormField> listFields, List<OnlineQuickFormField> filterFields) { |
||||
Map<String, OnlineQuickFormField> merged = new LinkedHashMap<>(); |
||||
if (listFields != null) { |
||||
for (OnlineQuickFormField field : listFields) { |
||||
merged.put(field.getFieldName(), field); |
||||
} |
||||
} |
||||
if (filterFields != null) { |
||||
for (OnlineQuickFormField field : filterFields) { |
||||
merged.putIfAbsent(field.getFieldName(), field); |
||||
} |
||||
} |
||||
return new ArrayList<>(merged.values()); |
||||
} |
||||
|
||||
/** |
||||
* 构建 pc 列表表格列(tableColumnList),仅含列表展示字段。 |
||||
*/ |
||||
private static JSONArray buildTableColumnList(List<OnlineQuickFormField> listFields, Long masterTableId, Map<String, Long> columnIdMap) { |
||||
JSONArray columnList = new JSONArray(); |
||||
if (listFields == null) { |
||||
return columnList; |
||||
} |
||||
for (int i = 0; i < listFields.size(); i++) { |
||||
OnlineQuickFormField field = listFields.get(i); |
||||
String fieldName = field.getFieldName(); |
||||
Long columnId = columnIdMap == null ? null : columnIdMap.get(fieldName.toLowerCase()); |
||||
JSONObject column = new JSONObject(); |
||||
column.put("columnId", columnId == null ? "" : String.valueOf(columnId)); |
||||
column.put("tableId", String.valueOf(masterTableId)); |
||||
column.put("showName", StringUtils.isNotBlank(field.getFieldRemark()) ? field.getFieldRemark() : fieldName); |
||||
column.put("sortable", false); |
||||
// 列表表格列固定 fieldType=0,与参考json一致;按真实字段类型映射会导致日期等列无法展示
|
||||
column.put("fieldType", 0); |
||||
column.put("comType", 41); |
||||
column.put("switchClose", "false"); |
||||
column.put("selectCode", 1); |
||||
column.put("switchOpen", "true"); |
||||
column.put("showColumn", true); |
||||
column.put("showRequired", false); |
||||
column.put("F7Info", ""); |
||||
column.put("f7ShowName", StringUtils.isNotBlank(field.getDisplayField()) ? field.getDisplayField() : ""); |
||||
column.put("id", columnId == null ? "column_" + i : "column_" + columnId); |
||||
column.put("soleId", (columnId == null ? String.valueOf(i) : columnId + "") + i); |
||||
String showFieldName = fieldName; |
||||
if (StringUtils.isNotBlank(field.getDisplayField())) { |
||||
showFieldName = showFieldName + "." + field.getDisplayField(); |
||||
} |
||||
column.put("showFieldName", showFieldName); |
||||
columnList.add(column); |
||||
} |
||||
return columnList; |
||||
} |
||||
|
||||
/** |
||||
* 移动端过滤控件类型:模板专用类型映射,未映射的类型复用字段控件本身类型。 |
||||
*/ |
||||
private static int resolveMobileFilterType(Integer fieldType) { |
||||
if (fieldType == null) { |
||||
return 502; |
||||
} |
||||
switch (fieldType) { |
||||
case 1: |
||||
return 502; // 文本 → 移动端文本过滤框
|
||||
case 7: |
||||
return 500; // 开关/单选 → 移动端字典过滤
|
||||
default: |
||||
return fieldType; // 下拉(10)、F7(402) 等保持原类型
|
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 生成移动端过滤控件(查询区),放在列表卡片之后的独立过滤组件。 |
||||
*/ |
||||
private static JSONObject buildMobileFilterWidget(OnlineQuickFormField field, Long formId, Long masterTableId) { |
||||
return buildFieldWidget(field, resolveMobileFilterType(field.getFieldType()), "mobile", formId, masterTableId); |
||||
} |
||||
|
||||
// ============ 字段控件生成 ============
|
||||
|
||||
private static JSONArray buildWidgetList(List<OnlineQuickFormField> fields, String device, Long formId, Long masterTableId) { |
||||
JSONArray widgetList = new JSONArray(); |
||||
if (fields == null) { |
||||
return widgetList; |
||||
} |
||||
for (OnlineQuickFormField field : fields) { |
||||
widgetList.add(buildFieldWidget(field, device, formId, masterTableId)); |
||||
} |
||||
return widgetList; |
||||
} |
||||
|
||||
private static JSONObject buildFieldWidget(OnlineQuickFormField field, String device, Long formId, Long masterTableId) { |
||||
return buildFieldWidget(field, resolveWidgetType(field.getFieldType(), device), device, formId, masterTableId); |
||||
} |
||||
|
||||
private static JSONObject buildFieldWidget(OnlineQuickFormField field, int wt, String device, Long formId, Long masterTableId) { |
||||
String varName = StrUtil.toCamelCase(field.getFieldName()); |
||||
String showName = StringUtils.isNotBlank(field.getFieldRemark()) ? field.getFieldRemark() : field.getFieldName(); |
||||
|
||||
JSONObject bindData = new JSONObject(); |
||||
JSONObject defaultValue = new JSONObject(); |
||||
defaultValue.put("valueType", 20); |
||||
bindData.put("defaultValue", defaultValue); |
||||
bindData.put("dataType", 0); |
||||
bindData.put("columnFieldName", field.getFieldName()); |
||||
bindData.put("tableId", masterTableId); |
||||
bindData.put("id", formId); |
||||
if (wt == 402 && field.getRefTableId() != null) { |
||||
bindData.put("slaveTableId", field.getRefTableId()); |
||||
if (StrUtil.isNotBlank(field.getRefTableName())) { |
||||
bindData.put("slaveTableName", field.getRefTableName()); |
||||
} |
||||
} |
||||
|
||||
JSONObject widget = new JSONObject(); |
||||
widget.put("widgetType", wt); |
||||
widget.put("bindData", bindData); |
||||
widget.put("showName", showName); |
||||
widget.put("variableName", varName); |
||||
widget.put("props", buildProps(wt, field, device)); |
||||
widget.put("eventList", new JSONArray()); |
||||
widget.put("childWidgetList", new JSONArray()); |
||||
widget.put("style", new JSONObject()); |
||||
if ("mobile".equals(device)) { |
||||
widget.put("supportOperation", false); |
||||
} |
||||
return widget; |
||||
} |
||||
|
||||
private static int resolveWidgetType(Integer fieldType, String device) { |
||||
int wt = fieldType == null ? 1 : fieldType; |
||||
if ("mobile".equals(device) && wt == 3) { |
||||
return 15; |
||||
} |
||||
return wt; |
||||
} |
||||
|
||||
/** |
||||
* 元数据(widgetListMapData)里的控件类型:移动端纯过滤字段用过滤控件类型,其余用字段控件类型。 |
||||
*/ |
||||
private static int resolveMetaWidgetType(OnlineQuickFormField field, String device) { |
||||
if ("mobile".equals(device) && !isListField(field) && isFilterField(field)) { |
||||
return resolveMobileFilterType(field.getFieldType()); |
||||
} |
||||
return resolveWidgetType(field.getFieldType(), device); |
||||
} |
||||
|
||||
private static JSONObject buildProps(int wt, OnlineQuickFormField field, String device) { |
||||
int span = "mobile".equals(device) ? 24 : 12; |
||||
boolean required = field.getIsEmpty() != null && field.getIsEmpty() == 0; |
||||
JSONObject props = new JSONObject(); |
||||
props.put("span", span); |
||||
props.put("required", required); |
||||
props.put("disabled", false); |
||||
props.put("hide", false); |
||||
props.put("styleCssText", ""); |
||||
props.put("actions", new JSONObject()); |
||||
JSONObject dictInfo = new JSONObject(); |
||||
dictInfo.put("paramList", new JSONArray()); |
||||
if (field.getRefDict() != null && wt != 402) { |
||||
dictInfo.put("dictId", field.getRefDict()); |
||||
} |
||||
props.put("dictInfo", dictInfo); |
||||
if (StringUtils.isNotBlank(field.getDefaultValue())) { |
||||
props.put("placeholder", field.getDefaultValue()); |
||||
} |
||||
switch (wt) { |
||||
case 1: // 文本输入框
|
||||
props.put("type", "text"); |
||||
props.put("inputHight", 40); |
||||
props.put("textLineTb", false); |
||||
props.put("inputNumMin", 0); |
||||
props.put("inputNumMax", 0); |
||||
props.put("plarceColor", ""); |
||||
props.put("inputWidth", ""); |
||||
props.put("transparentTitle", 0); |
||||
props.put("inputWidthBlan", false); |
||||
props.put("colorTitle", ""); |
||||
props.put("colorInput", ""); |
||||
props.put("labelWight", 2); |
||||
props.put("inputHeight", 2); |
||||
if (!props.containsKey("placeholder")) props.put("placeholder", ""); |
||||
props.put("show-password", false); |
||||
props.put("show-word-limit", false); |
||||
props.put("inCopy", false); |
||||
props.put("inCopyImg", false); |
||||
props.put("readonly", false); |
||||
props.put("teartextMore", false); |
||||
props.put("borderBottom", false); |
||||
props.put("textRedBd", false); |
||||
props.put("readyModeHiddenEmpty", false); |
||||
props.put("tooltipText", ""); |
||||
break; |
||||
case 3: // 数字输入框
|
||||
props.put("step", 1); |
||||
props.put("controls", true); |
||||
if (!props.containsKey("placeholder")) props.put("placeholder", ""); |
||||
props.put("tooltipText", ""); |
||||
break; |
||||
case 15: // 移动端数字输入框
|
||||
props.put("labelWight", 2); |
||||
props.put("step", 1); |
||||
props.put("input-width", "32px"); |
||||
props.put("button-size", "28px"); |
||||
props.put("integer", false); |
||||
break; |
||||
case 7: // 开关/单选
|
||||
props.put("inputHight", 40); |
||||
props.put("inputWidth", ""); |
||||
props.put("transparentTitle", 0); |
||||
props.put("colorTitle", ""); |
||||
props.put("labelWight", 2); |
||||
props.put("direction", "horizontal"); |
||||
props.put("borderBottom", false); |
||||
props.put("icon-size", "20px"); |
||||
props.put("tooltipText", ""); |
||||
break; |
||||
case 10: // 下拉选择框
|
||||
if (!props.containsKey("placeholder")) props.put("placeholder", ""); |
||||
props.put("inputHight", "44"); |
||||
props.put("inputWidth", ""); |
||||
props.put("transparentTitle", 0); |
||||
props.put("colorTitle", ""); |
||||
props.put("colorInput", ""); |
||||
props.put("labelWight", 2); |
||||
props.put("borderBottom", false); |
||||
props.put("multiple", false); |
||||
props.put("fiterSaicn", false); |
||||
props.put("inputSeletUr", false); |
||||
props.put("readyModeHiddenEmpty", false); |
||||
props.put("tooltipText", ""); |
||||
break; |
||||
case 20: // 日期选择框
|
||||
if (!props.containsKey("placeholder")) props.put("placeholder", ""); |
||||
props.put("type", "date"); |
||||
props.put("tooltipText", ""); |
||||
break; |
||||
case 402: // 用户/关联选择
|
||||
props.put("inCopy", false); |
||||
props.put("plarceColor", ""); |
||||
props.put("transparentTitle", 0); |
||||
props.put("inputHight", 40); |
||||
props.put("inputWidth", ""); |
||||
if (!props.containsKey("placeholder")) props.put("placeholder", ""); |
||||
props.put("colorTitle", ""); |
||||
props.put("colorInput", ""); |
||||
props.put("wightInput", 0); |
||||
props.put("borderBottom", false); |
||||
props.put("fiterSaicn", false); |
||||
props.put("relativeTable", buildRelativeTable(field)); |
||||
props.put("isMultiple", false); |
||||
props.put("readyModeHiddenEmpty", false); |
||||
props.put("tooltipText", ""); |
||||
break; |
||||
default: |
||||
props.put("type", "text"); |
||||
props.put("inputHight", 40); |
||||
if (!props.containsKey("placeholder")) props.put("placeholder", ""); |
||||
break; |
||||
} |
||||
return props; |
||||
} |
||||
|
||||
private static JSONObject buildRelativeTable(OnlineQuickFormField field) { |
||||
JSONObject relativeTable = new JSONObject(); |
||||
relativeTable.put("relativeFormId", ""); |
||||
relativeTable.put("relativeTableName", StrUtil.isNotBlank(field.getRefTableName()) ? field.getRefTableName() : ""); |
||||
relativeTable.put("relativeColumn", "id"); |
||||
relativeTable.put("relationId", ""); |
||||
relativeTable.put("datasourceId", ""); |
||||
relativeTable.put("variableName", ""); |
||||
relativeTable.put("displayField", StringUtils.isNotBlank(field.getDisplayField()) ? field.getDisplayField() : "fname"); |
||||
relativeTable.put("FieldFormId", ""); |
||||
relativeTable.put("fieldAddSwich", ""); |
||||
relativeTable.put("relativeFormType", 2); |
||||
relativeTable.put("relativeFormCode", StrUtil.isNotBlank(field.getRefFormCode()) ? field.getRefFormCode() : "query_all_pm_user"); |
||||
relativeTable.put("onlineFormId", ""); |
||||
relativeTable.put("onlineFormName", ""); |
||||
return relativeTable; |
||||
} |
||||
|
||||
// ============ 移动端列表页结构 ============
|
||||
|
||||
private static void rebuildMobileList(JSONObject deviceObj, List<OnlineQuickFormField> listFields, List<OnlineQuickFormField> filterFields, Long bindId, Long listFormId, Long masterTableId) { |
||||
JSONObject tableWidget = deviceObj.getJSONObject("tableWidget"); |
||||
if (tableWidget == null) { |
||||
return; |
||||
} |
||||
JSONArray childList = tableWidget.getJSONArray("childWidgetList"); |
||||
if (childList == null) { |
||||
childList = new JSONArray(); |
||||
tableWidget.put("childWidgetList", childList); |
||||
} |
||||
// 找到 listCard(widgetType=303),保留 image(42) 子控件,其余字段重新生成
|
||||
JSONObject listCard = null; |
||||
for (int i = 0; i < childList.size(); i++) { |
||||
JSONObject child = childList.getJSONObject(i); |
||||
if (child != null && 303 == child.getIntValue("widgetType")) { |
||||
listCard = child; |
||||
break; |
||||
} |
||||
} |
||||
if (listCard == null) { |
||||
listCard = new JSONObject(); |
||||
listCard.put("widgetType", 303); |
||||
listCard.put("bindData", baseBindData()); |
||||
listCard.put("showName", "listCard"); |
||||
listCard.put("variableName", "listCard" + listFormId); |
||||
JSONObject props = new JSONObject(); |
||||
props.put("imagePosition", "left"); |
||||
props.put("imageAlign", "center"); |
||||
props.put("hide", false); |
||||
props.put("styleCssText", ""); |
||||
props.put("actions", new JSONObject()); |
||||
listCard.put("props", props); |
||||
listCard.put("eventList", new JSONArray()); |
||||
listCard.put("style", new JSONObject()); |
||||
listCard.put("supportOperation", false); |
||||
} |
||||
JSONArray cardChildren = listCard.getJSONArray("childWidgetList"); |
||||
if (cardChildren == null) { |
||||
cardChildren = new JSONArray(); |
||||
} |
||||
JSONArray newCardChildren = new JSONArray(); |
||||
for (int i = 0; i < cardChildren.size(); i++) { |
||||
JSONObject child = cardChildren.getJSONObject(i); |
||||
if (child != null && 42 == child.getIntValue("widgetType")) { |
||||
newCardChildren.add(child); |
||||
break; |
||||
} |
||||
} |
||||
if (listFields != null) { |
||||
for (OnlineQuickFormField field : listFields) { |
||||
newCardChildren.add(buildFieldWidget(field, "mobile", bindId, masterTableId)); |
||||
} |
||||
} |
||||
listCard.put("childWidgetList", newCardChildren); |
||||
// 列表卡片 + 过滤控件:过滤字段作为独立查询组件放在 listCard 之后
|
||||
JSONArray newChildList = new JSONArray(); |
||||
newChildList.add(listCard); |
||||
if (filterFields != null) { |
||||
for (OnlineQuickFormField field : filterFields) { |
||||
newChildList.add(buildMobileFilterWidget(field, bindId, masterTableId)); |
||||
} |
||||
} |
||||
tableWidget.put("childWidgetList", newChildList); |
||||
} |
||||
|
||||
private static JSONObject baseBindData() { |
||||
JSONObject defaultValue = new JSONObject(); |
||||
defaultValue.put("valueType", 20); |
||||
JSONObject bindData = new JSONObject(); |
||||
bindData.put("defaultValue", defaultValue); |
||||
bindData.put("dataType", 0); |
||||
return bindData; |
||||
} |
||||
|
||||
// ============ 按钮 formId ============
|
||||
|
||||
private static void setButtonFormId(JSONObject deviceObj, Long editFormId) { |
||||
JSONArray opList = deviceObj.getJSONArray("operationList"); |
||||
if (opList == null) { |
||||
return; |
||||
} |
||||
for (int i = 0; i < opList.size(); i++) { |
||||
JSONObject op = opList.getJSONObject(i); |
||||
Integer type = op.getInteger("type"); |
||||
if ((type != null && (type == 0 || type == 1)) && Boolean.TRUE.equals(op.getBoolean("enabled"))) { |
||||
op.put("formId", editFormId); |
||||
} |
||||
} |
||||
} |
||||
|
||||
private static void setSaveButtonEnabled(JSONObject deviceObj) { |
||||
JSONArray opList = deviceObj.getJSONArray("operationList"); |
||||
if (opList == null) { |
||||
return; |
||||
} |
||||
for (int i = 0; i < opList.size(); i++) { |
||||
JSONObject op = opList.getJSONObject(i); |
||||
if (30 == op.getIntValue("type")) { |
||||
op.put("enabled", true); |
||||
JSONArray pluginList = new JSONArray(); |
||||
JSONObject plugin = new JSONObject(); |
||||
plugin.put("name", "保存"); |
||||
plugin.put("class", "apelet.common.online.plugin.pre.SaveOperationServicePlugIn"); |
||||
plugin.put("order", "1"); |
||||
plugin.put("describe", "保存"); |
||||
plugin.put("isEnable", true); |
||||
plugin.put("_disabled", true); |
||||
plugin.put("_X_ROW_KEY", "row_" + i); |
||||
pluginList.add(plugin); |
||||
op.put("pluginList", pluginList); |
||||
} |
||||
} |
||||
} |
||||
|
||||
// ============ 元数据(mapData/keyNameObj) ============
|
||||
|
||||
private static void rebuildMeta(JSONObject deviceObj, List<OnlineQuickFormField> fields, String device, String masterTableName, String tableVar) { |
||||
JSONObject widgetListMapData = new JSONObject(); |
||||
if (fields != null) { |
||||
for (OnlineQuickFormField field : fields) { |
||||
String var = StrUtil.toCamelCase(field.getFieldName()); |
||||
JSONObject m = new JSONObject(); |
||||
m.put("widgetType", resolveMetaWidgetType(field, device)); |
||||
m.put("variableName", var); |
||||
widgetListMapData.put(var, m); |
||||
} |
||||
} |
||||
JSONObject otherWidgetListMapData = new JSONObject(); |
||||
if (StringUtils.isNotBlank(tableVar)) { |
||||
JSONObject tableMap = new JSONObject(); |
||||
tableMap.put("widgetType", 100); |
||||
tableMap.put("variableName", tableVar); |
||||
widgetListMapData.put(tableVar, tableMap); |
||||
otherWidgetListMapData.put(tableVar, tableMap); |
||||
} |
||||
deviceObj.put("widgetListMapData", widgetListMapData); |
||||
deviceObj.put("otherWidgetListMapData", otherWidgetListMapData); |
||||
deviceObj.put("keyNameObj", buildKeyNameObj(fields, masterTableName)); |
||||
} |
||||
|
||||
private static JSONObject buildKeyNameObj(List<OnlineQuickFormField> fields, String masterTableName) { |
||||
JSONObject keyNameObj = new JSONObject(); |
||||
if (fields == null) { |
||||
return keyNameObj; |
||||
} |
||||
for (OnlineQuickFormField field : fields) { |
||||
JSONArray arr = new JSONArray(); |
||||
arr.add(masterTableName + "." + StrUtil.toCamelCase(field.getFieldName())); |
||||
keyNameObj.put(field.getFieldName(), arr); |
||||
} |
||||
return keyNameObj; |
||||
} |
||||
} |
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
Reference in new issue