@@ -0,0 +1,50 @@ | |||
package com.ruoyi.web.controller.agentcenter; | |||
import java.util.List; | |||
import javax.servlet.http.HttpServletResponse; | |||
import com.ruoyi.common.utils.DateUtils; | |||
import org.springframework.security.access.prepost.PreAuthorize; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import org.springframework.web.bind.annotation.GetMapping; | |||
import org.springframework.web.bind.annotation.PostMapping; | |||
import org.springframework.web.bind.annotation.PutMapping; | |||
import org.springframework.web.bind.annotation.DeleteMapping; | |||
import org.springframework.web.bind.annotation.PathVariable; | |||
import org.springframework.web.bind.annotation.RequestBody; | |||
import org.springframework.web.bind.annotation.RequestMapping; | |||
import org.springframework.web.bind.annotation.RestController; | |||
import com.ruoyi.common.annotation.Log; | |||
import com.ruoyi.common.core.controller.BaseController; | |||
import com.ruoyi.common.core.domain.AjaxResult; | |||
import com.ruoyi.common.enums.BusinessType; | |||
import com.ruoyi.agentcenter.domain.TAgentTask; | |||
import com.ruoyi.agentcenter.service.ITAgentTaskService; | |||
import com.ruoyi.common.utils.poi.ExcelUtil; | |||
import com.ruoyi.common.core.page.TableDataInfo; | |||
/** | |||
* 任务清单Controller | |||
* | |||
* @author zhao | |||
* @date 2023-05-06 | |||
*/ | |||
@RestController | |||
@RequestMapping("/agentcenter/task") | |||
public class AgentTaskController extends BaseController | |||
{ | |||
@Autowired | |||
private ITAgentTaskService tAgentTaskService; | |||
/** | |||
* 获取任务清单列表(按镇村分组) | |||
*/ | |||
@PreAuthorize("@ss.hasPermi('agentcenter:task:list')") | |||
@GetMapping(value = "/taskList") | |||
public TableDataInfo taskList(TAgentTask task) | |||
{ | |||
startPage(); | |||
task.setEndAt(DateUtils.getDate()); | |||
return getDataTable(tAgentTaskService.getTownTaskList(task)); | |||
} | |||
} |
@@ -1,106 +0,0 @@ | |||
package com.ruoyi.web.controller.agentcenter; | |||
import java.util.List; | |||
import javax.servlet.http.HttpServletResponse; | |||
import org.springframework.security.access.prepost.PreAuthorize; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import org.springframework.web.bind.annotation.GetMapping; | |||
import org.springframework.web.bind.annotation.PostMapping; | |||
import org.springframework.web.bind.annotation.PutMapping; | |||
import org.springframework.web.bind.annotation.DeleteMapping; | |||
import org.springframework.web.bind.annotation.PathVariable; | |||
import org.springframework.web.bind.annotation.RequestBody; | |||
import org.springframework.web.bind.annotation.RequestMapping; | |||
import org.springframework.web.bind.annotation.RestController; | |||
import com.ruoyi.common.annotation.Log; | |||
import com.ruoyi.common.core.controller.BaseController; | |||
import com.ruoyi.common.core.domain.AjaxResult; | |||
import com.ruoyi.common.enums.BusinessType; | |||
import com.ruoyi.agentcenter.domain.TAgentTask; | |||
import com.ruoyi.agentcenter.service.ITAgentTaskService; | |||
import com.ruoyi.common.utils.poi.ExcelUtil; | |||
import com.ruoyi.common.core.page.TableDataInfo; | |||
/** | |||
* 任务清单Controller | |||
* | |||
* @author zhao | |||
* @date 2023-05-06 | |||
*/ | |||
@RestController | |||
@RequestMapping("/agentcenter/task") | |||
public class TAgentTaskController extends BaseController | |||
{ | |||
@Autowired | |||
private ITAgentTaskService tAgentTaskService; | |||
/** | |||
* 查询任务清单列表 | |||
*/ | |||
@PreAuthorize("@ss.hasPermi('agentcenter:task:list')") | |||
@GetMapping("/list") | |||
public TableDataInfo list(TAgentTask tAgentTask) | |||
{ | |||
startPage(); | |||
List<TAgentTask> list = tAgentTaskService.selectTAgentTaskList(tAgentTask); | |||
return getDataTable(list); | |||
} | |||
/** | |||
* 导出任务清单列表 | |||
*/ | |||
@PreAuthorize("@ss.hasPermi('agentcenter:task:export')") | |||
@Log(title = "任务清单", businessType = BusinessType.EXPORT) | |||
@PostMapping("/export") | |||
public void export(HttpServletResponse response, TAgentTask tAgentTask) | |||
{ | |||
List<TAgentTask> list = tAgentTaskService.selectTAgentTaskList(tAgentTask); | |||
ExcelUtil<TAgentTask> util = new ExcelUtil<TAgentTask>(TAgentTask.class); | |||
util.exportExcel(response, list, "任务清单数据"); | |||
} | |||
/** | |||
* 获取任务清单详细信息 | |||
*/ | |||
@PreAuthorize("@ss.hasPermi('agentcenter:task:query')") | |||
@GetMapping(value = "/get/{id}") | |||
public AjaxResult getInfo(@PathVariable("id") Long id) | |||
{ | |||
return success(tAgentTaskService.selectTAgentTaskById(id)); | |||
} | |||
/** | |||
* 新增任务清单 | |||
*/ | |||
@PreAuthorize("@ss.hasPermi('agentcenter:task:add')") | |||
@Log(title = "任务清单", businessType = BusinessType.INSERT) | |||
@PostMapping(value = "/add") | |||
public AjaxResult add(@RequestBody TAgentTask tAgentTask) | |||
{ | |||
tAgentTask.setCreateBy(getUsername()); | |||
return toAjax(tAgentTaskService.insertTAgentTask(tAgentTask)); | |||
} | |||
/** | |||
* 修改任务清单 | |||
*/ | |||
@PreAuthorize("@ss.hasPermi('agentcenter:task:edit')") | |||
@Log(title = "任务清单", businessType = BusinessType.UPDATE) | |||
@PutMapping(value = "/edit") | |||
public AjaxResult edit(@RequestBody TAgentTask tAgentTask) | |||
{ | |||
tAgentTask.setUpdateBy(getUsername()); | |||
return toAjax(tAgentTaskService.updateTAgentTask(tAgentTask)); | |||
} | |||
/** | |||
* 删除任务清单 | |||
*/ | |||
@PreAuthorize("@ss.hasPermi('agentcenter:task:remove')") | |||
@Log(title = "任务清单", businessType = BusinessType.DELETE) | |||
@DeleteMapping(value = "/remove/{id}") | |||
public AjaxResult remove(@PathVariable Long id) | |||
{ | |||
return toAjax(tAgentTaskService.deleteTAgentTaskById(id)); | |||
} | |||
} |
@@ -1,12 +1,12 @@ | |||
package com.ruoyi.web.controller.agentcenter; | |||
package com.ruoyi.web.controller.api; | |||
import com.nsgk.agentcentersdk.api.NSApiResult; | |||
import com.nsgk.agentcentersdk.api.NSSDK; | |||
import com.nsgk.agentcentersdk.api.NSSDKServer; | |||
import com.nsgk.agentcentersdk.core.NSReportObject; | |||
import com.nsgk.agentcentersdk.message.NSContractionMessage; | |||
import com.nsgk.agentcentersdk.err.NSErrno; | |||
import com.nsgk.agentcentersdk.err.NSException; | |||
import com.nsgk.agentcentersdk.message.NSContractionMessage; | |||
import com.ruoyi.agentcenter.object.Session; | |||
import com.ruoyi.agentcenter.service.IAgentCenter; | |||
import com.ruoyi.common.config.RuoYiConfig; |
@@ -0,0 +1,45 @@ | |||
package com.ruoyi.web.controller.misc; | |||
import com.ruoyi.common.core.controller.BaseController; | |||
import com.ruoyi.common.core.domain.AjaxResult; | |||
import com.ruoyi.common.core.domain.entity.SysDept; | |||
import com.ruoyi.system.service.ISysDeptService; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import org.springframework.security.access.prepost.PreAuthorize; | |||
import org.springframework.web.bind.annotation.GetMapping; | |||
import org.springframework.web.bind.annotation.RequestMapping; | |||
import org.springframework.web.bind.annotation.RestController; | |||
import java.util.List; | |||
/** | |||
* 杂项::部门 | |||
* | |||
* @author zhao | |||
*/ | |||
@RestController | |||
@RequestMapping("/misc/dept") | |||
public class DeptController extends BaseController | |||
{ | |||
@Autowired | |||
private ISysDeptService deptService; | |||
/** | |||
* 获取部门树 | |||
*/ | |||
@GetMapping("/tree") | |||
public AjaxResult list(SysDept dept) | |||
{ | |||
return success(deptService.getDeptTree(dept)); | |||
} | |||
/** | |||
* 获取市级树 | |||
*/ | |||
@GetMapping("/cityTree") | |||
public AjaxResult cityTree(SysDept dept) | |||
{ | |||
return success(deptService.getCityTree(dept)); | |||
} | |||
} |
@@ -30,7 +30,7 @@ public class TAgentTask extends BaseEntity | |||
private Long id; | |||
/** 所属中心 字典 agent_center */ | |||
@Excel(name = "所属中心 字典 agent_center") | |||
@Excel(name = "所属中心", dictType = "agent_center") | |||
private String agentCenter; | |||
/** 县代码 */ | |||
@@ -94,15 +94,15 @@ public class TAgentTask extends BaseEntity | |||
private Integer finishCount; | |||
/** 任务状态 字典 agent_status */ | |||
@Excel(name = "任务状态 字典 agent_status") | |||
@Excel(name = "任务状态", dictType = "agent_status") | |||
private String agentStatus; | |||
/** 分配用户(用user_name) */ | |||
@Excel(name = "分配用户(用user_name)") | |||
@Excel(name = "分配用户") | |||
private String distriUser; | |||
/** 分配人(用nick_name) */ | |||
@Excel(name = "分配人(用nick_name)") | |||
@Excel(name = "分配人") | |||
private String distriNick; | |||
/** 分配时间 */ | |||
@@ -115,11 +115,11 @@ public class TAgentTask extends BaseEntity | |||
private String endAt; | |||
/** 记账用户(用user_name) */ | |||
@Excel(name = "记账用户(用user_name)") | |||
@Excel(name = "记账用户") | |||
private String handleUser; | |||
/** 记账会计(用nick_name) */ | |||
@Excel(name = "记账会计(用nick_name)") | |||
@Excel(name = "记账会计") | |||
private String handleNick; | |||
/** 记账备注 */ | |||
@@ -132,11 +132,11 @@ public class TAgentTask extends BaseEntity | |||
private Date handleDate; | |||
/** 审核用户(用user_name) */ | |||
@Excel(name = "审核用户(用user_name)") | |||
@Excel(name = "审核用户") | |||
private String auditUser; | |||
/** 审核人(用nick_name) */ | |||
@Excel(name = "审核人(用nick_name)") | |||
@Excel(name = "审核人") | |||
private String auditNick; | |||
/** 审核时间 */ | |||
@@ -145,11 +145,11 @@ public class TAgentTask extends BaseEntity | |||
private Date auditDate; | |||
/** 评价用户(用user_name) */ | |||
@Excel(name = "评价用户(用user_name)") | |||
@Excel(name = "评价用户") | |||
private String appraiseUser; | |||
/** 评价人(用nick_name) */ | |||
@Excel(name = "评价人(用nick_name)") | |||
@Excel(name = "评价人") | |||
private String appraiseNick; | |||
/** 任务评分 */ | |||
@@ -160,5 +160,12 @@ public class TAgentTask extends BaseEntity | |||
@Excel(name = "评价备注") | |||
private String appraiseRemark; | |||
/** 是否审核 */ | |||
@Excel(name = "是否审核", dictType = "sys_yes_no") | |||
private String isAudit; | |||
/** 是否评价 */ | |||
@Excel(name = "是否评价", dictType = "sys_yes_no") | |||
private String isAppraise; | |||
} |
@@ -2,6 +2,8 @@ package com.ruoyi.agentcenter.mapper; | |||
import java.util.List; | |||
import com.ruoyi.agentcenter.domain.TAgentTask; | |||
import com.ruoyi.agentcenter.vo.AgentTaskTownGroup; | |||
import com.ruoyi.agentcenter.vo.AgentTaskVillageGroup; | |||
/** | |||
* 任务清单Mapper接口 | |||
@@ -101,4 +103,7 @@ public interface TAgentTaskMapper | |||
public int selectTAgentTaskExists(TAgentTask tAgentTask); | |||
public int updateTAgentTaskCount(TAgentTask tAgentTask); | |||
public List<AgentTaskTownGroup> getAgentTaskGroupByTown(TAgentTask tAgentTask); | |||
public List<AgentTaskVillageGroup> getAgentTaskGroupByVillage(TAgentTask tAgentTask); | |||
} |
@@ -4,6 +4,7 @@ import java.util.List; | |||
import java.util.function.Consumer; | |||
import com.ruoyi.agentcenter.domain.TAgentTask; | |||
import com.ruoyi.agentcenter.vo.AgentTaskTownGroup; | |||
/** | |||
* 任务清单Service接口 | |||
@@ -111,4 +112,6 @@ public interface ITAgentTaskService | |||
public TAgentTask getTAgentTask(String orgCode, String year, String month); | |||
public int syncTAgentTaskCount(TAgentTask tAgentTask); | |||
public List<AgentTaskTownGroup> getTownTaskList(TAgentTask tAgentTask); | |||
} |
@@ -1,10 +1,16 @@ | |||
package com.ruoyi.agentcenter.service.impl; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import java.util.Map; | |||
import java.util.function.Consumer; | |||
import cn.hutool.core.collection.CollectionUtil; | |||
import cn.hutool.core.lang.Assert; | |||
import com.ruoyi.agentcenter.vo.AgentTaskTownGroup; | |||
import com.ruoyi.agentcenter.vo.AgentTaskVillageGroup; | |||
import com.ruoyi.common.core.domain.entity.SysDept; | |||
import com.ruoyi.common.utils.ContainerUtils; | |||
import com.ruoyi.common.utils.DateUtils; | |||
import com.ruoyi.common.utils.DeptUtils; | |||
import com.ruoyi.system.mapper.SysDeptMapper; | |||
@@ -273,4 +279,32 @@ public class TAgentTaskServiceImpl implements ITAgentTaskService | |||
; | |||
return updateTAgentTaskCount(updateTask); | |||
} | |||
@Override | |||
public List<AgentTaskTownGroup> getTownTaskList(TAgentTask tAgentTask) | |||
{ | |||
List<AgentTaskTownGroup> agentTaskGroupByTown = tAgentTaskMapper.getAgentTaskGroupByTown(tAgentTask); | |||
if(CollectionUtil.isNotEmpty(agentTaskGroupByTown)) | |||
{ | |||
List<String> townCodeList = ContainerUtils.mapToList(agentTaskGroupByTown, AgentTaskTownGroup::getTownCode); | |||
List<AgentTaskVillageGroup> villageGroups = tAgentTaskMapper.getAgentTaskGroupByVillage(new TAgentTask().putParam("townCodeList", townCodeList)); | |||
Map<String, List<AgentTaskVillageGroup>> villageMap = ContainerUtils.groupingBy(villageGroups, AgentTaskVillageGroup::getTownCode); | |||
List<String> orgCodeList = ContainerUtils.mapToList(villageGroups, AgentTaskVillageGroup::getOrgCode); | |||
TAgentTask agentTaskCond = new TAgentTask(); | |||
agentTaskCond.putParam("orgCodeList", orgCodeList); | |||
List<TAgentTask> tAgentTasks = tAgentTaskMapper.selectTAgentTaskList(agentTaskCond); | |||
Map<String, List<TAgentTask>> bookGroup = ContainerUtils.groupingBy(tAgentTasks, TAgentTask::getOrgCode); | |||
agentTaskGroupByTown.forEach((town) -> { | |||
town.setVillageList(villageMap.getOrDefault(town.getTownCode(), new ArrayList<>())); | |||
town.getVillageList().forEach((village) -> { | |||
village.setTaskList(bookGroup.getOrDefault(village.getOrgCode(), new ArrayList<>())); | |||
}); | |||
}); | |||
} | |||
return agentTaskGroupByTown; | |||
} | |||
} |
@@ -0,0 +1,22 @@ | |||
package com.ruoyi.agentcenter.vo; | |||
import lombok.Data; | |||
import lombok.experimental.Accessors; | |||
import java.util.List; | |||
@Data | |||
@Accessors(chain = true) | |||
public class AgentTaskTownGroup | |||
{ | |||
private Long num; | |||
private Long numProcessFinish; | |||
private Long numApprovalFinish; | |||
private Long numExcept; | |||
private String townName; | |||
private String townCode; | |||
private String orderYear; | |||
private String orderMonth; | |||
private List<AgentTaskVillageGroup> villageList; | |||
} |
@@ -0,0 +1,30 @@ | |||
package com.ruoyi.agentcenter.vo; | |||
import com.ruoyi.agentcenter.domain.TAgentTask; | |||
import lombok.Data; | |||
import lombok.experimental.Accessors; | |||
import java.util.Date; | |||
import java.util.List; | |||
@Data | |||
@Accessors(chain = true) | |||
public class AgentTaskVillageGroup | |||
{ | |||
private Long num; | |||
private Long numProcessFinish; | |||
private Long numApprovalFinish; | |||
private Long numExcept; | |||
private String townCode; | |||
private String orgName; | |||
private String orgCode; | |||
private Long bookId; | |||
private String bookName; | |||
private Date distriDate; | |||
private Date handleDate; | |||
private String endAt; | |||
private String handleNick; | |||
private List<TAgentTask> taskList; | |||
} |
@@ -1,9 +1,9 @@ | |||
<?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"> | |||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" | |||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | |||
<mapper namespace="com.ruoyi.agentcenter.mapper.TAgentTaskMapper"> | |||
<resultMap type="TAgentTask" id="TAgentTaskResult"> | |||
<result property="id" column="id" /> | |||
<result property="agentCenter" column="agent_center" /> | |||
@@ -34,10 +34,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" | |||
<result property="auditUser" column="audit_user" /> | |||
<result property="auditNick" column="audit_nick" /> | |||
<result property="auditDate" column="audit_date" /> | |||
<result property="isAudit" column="is_audit" /> | |||
<result property="appraiseUser" column="appraise_user" /> | |||
<result property="appraiseNick" column="appraise_nick" /> | |||
<result property="appraiseScore" column="appraise_score" /> | |||
<result property="appraiseRemark" column="appraise_remark" /> | |||
<result property="isAppraise" column="is_appraise" /> | |||
<result property="createBy" column="create_by" /> | |||
<result property="createTime" column="create_time" /> | |||
<result property="updateBy" column="update_by" /> | |||
@@ -45,13 +47,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" | |||
</resultMap> | |||
<sql id="selectTAgentTaskVo"> | |||
select id, agent_center, county_code, county_name, town_code, town_name, org_code, org_name, book_id, book_name, order_year, order_month, voucher_count, contrac_count, asset_count, all_count, finish_count, agent_status, distri_user, distri_nick, distri_date, end_at, handle_user, handle_nick, handle_remark, handle_date, audit_user, audit_nick, audit_date, appraise_user, appraise_nick, appraise_score, appraise_remark, create_by, create_time, update_by, update_time from t_agent_task | |||
select id, agent_center, county_code, county_name, town_code, town_name, org_code, org_name, book_id, book_name, order_year, order_month, voucher_count, contrac_count, asset_count, all_count, finish_count, agent_status, distri_user, distri_nick, distri_date, end_at, handle_user, handle_nick, handle_remark, handle_date, audit_user, audit_nick, audit_date, is_audit, appraise_user, appraise_nick, appraise_score, appraise_remark, is_appraise, create_by, create_time, update_by, update_time from t_agent_task | |||
</sql> | |||
<!--条件查询--> | |||
<select id="selectTAgentTaskList" parameterType="TAgentTask" resultMap="TAgentTaskResult"> | |||
<include refid="selectTAgentTaskVo"/> | |||
<where> | |||
<where> | |||
<if test="agentCenter != null and agentCenter != ''"> and agent_center = #{agentCenter}</if> | |||
<if test="countyCode != null and countyCode != ''"> and county_code = #{countyCode}</if> | |||
<if test="countyName != null and countyName != ''"> and county_name like concat('%', #{countyName}, '%')</if> | |||
@@ -80,20 +81,25 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" | |||
<if test="auditUser != null and auditUser != ''"> and audit_user = #{auditUser}</if> | |||
<if test="auditNick != null and auditNick != ''"> and audit_nick = #{auditNick}</if> | |||
<if test="auditDate != null "> and audit_date = #{auditDate}</if> | |||
<if test="isAudit != null and isAudit != ''"> and is_audit = #{isAudit}</if> | |||
<if test="appraiseUser != null and appraiseUser != ''"> and appraise_user = #{appraiseUser}</if> | |||
<if test="appraiseNick != null and appraiseNick != ''"> and appraise_nick = #{appraiseNick}</if> | |||
<if test="appraiseScore != null "> and appraise_score = #{appraiseScore}</if> | |||
<if test="appraiseRemark != null and appraiseRemark != ''"> and appraise_remark = #{appraiseRemark}</if> | |||
<if test="isAppraise != null and isAppraise != ''"> and is_appraise = #{isAppraise}</if> | |||
<if test="params != null"> | |||
<if test="params.orgCodeList != null"> | |||
AND org_code IN (null <foreach collection="params.orgCodeList" item="i">,#{i}</foreach> ) | |||
</if> | |||
</if> | |||
</where> | |||
</select> | |||
<!--主键查询--> | |||
<select id="selectTAgentTaskById" parameterType="Long" resultMap="TAgentTaskResult"> | |||
<include refid="selectTAgentTaskVo"/> | |||
where id = #{id} | |||
</select> | |||
<!--新增--> | |||
<insert id="insertTAgentTask" parameterType="TAgentTask" useGeneratedKeys="true" keyProperty="id"> | |||
insert into t_agent_task | |||
<trim prefix="(" suffix=")" suffixOverrides=","> | |||
@@ -125,15 +131,17 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" | |||
<if test="auditUser != null">audit_user,</if> | |||
<if test="auditNick != null">audit_nick,</if> | |||
<if test="auditDate != null">audit_date,</if> | |||
<if test="isAudit != null">is_audit,</if> | |||
<if test="appraiseUser != null">appraise_user,</if> | |||
<if test="appraiseNick != null">appraise_nick,</if> | |||
<if test="appraiseScore != null">appraise_score,</if> | |||
<if test="appraiseRemark != null">appraise_remark,</if> | |||
<if test="isAppraise != null">is_appraise,</if> | |||
<if test="createBy != null">create_by,</if> | |||
<if test="createTime != null">create_time,</if> | |||
<if test="updateBy != null">update_by,</if> | |||
<if test="updateTime != null">update_time,</if> | |||
</trim> | |||
</trim> | |||
<trim prefix="values (" suffix=")" suffixOverrides=","> | |||
<if test="agentCenter != null and agentCenter != ''">#{agentCenter},</if> | |||
<if test="countyCode != null and countyCode != ''">#{countyCode},</if> | |||
@@ -163,15 +171,17 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" | |||
<if test="auditUser != null">#{auditUser},</if> | |||
<if test="auditNick != null">#{auditNick},</if> | |||
<if test="auditDate != null">#{auditDate},</if> | |||
<if test="isAudit != null">#{isAudit},</if> | |||
<if test="appraiseUser != null">#{appraiseUser},</if> | |||
<if test="appraiseNick != null">#{appraiseNick},</if> | |||
<if test="appraiseScore != null">#{appraiseScore},</if> | |||
<if test="appraiseRemark != null">#{appraiseRemark},</if> | |||
<if test="isAppraise != null">#{isAppraise},</if> | |||
<if test="createBy != null">#{createBy},</if> | |||
<if test="createTime != null">#{createTime},</if> | |||
<if test="updateBy != null">#{updateBy},</if> | |||
<if test="updateTime != null">#{updateTime},</if> | |||
</trim> | |||
</trim> | |||
</insert> | |||
<!--批量新增--> | |||
@@ -206,10 +216,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" | |||
audit_user, | |||
audit_nick, | |||
audit_date, | |||
is_audit, | |||
appraise_user, | |||
appraise_nick, | |||
appraise_score, | |||
appraise_remark, | |||
is_appraise, | |||
create_by, | |||
create_time, | |||
update_by, | |||
@@ -246,10 +258,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" | |||
#{item.auditUser}, | |||
#{item.auditNick}, | |||
#{item.auditDate}, | |||
#{item.isAudit}, | |||
#{item.appraiseUser}, | |||
#{item.appraiseNick}, | |||
#{item.appraiseScore}, | |||
#{item.appraiseRemark}, | |||
#{item.isAppraise}, | |||
#{item.createBy}, | |||
#{item.createTime}, | |||
#{item.updateBy}, | |||
@@ -258,7 +272,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" | |||
</foreach> | |||
</insert> | |||
<!--更新--> | |||
<update id="updateTAgentTask" parameterType="TAgentTask"> | |||
update t_agent_task | |||
<trim prefix="SET" suffixOverrides=","> | |||
@@ -290,15 +303,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" | |||
<if test="auditUser != null">audit_user = #{auditUser},</if> | |||
<if test="auditNick != null">audit_nick = #{auditNick},</if> | |||
<if test="auditDate != null">audit_date = #{auditDate},</if> | |||
<if test="isAudit != null">is_audit = #{isAudit},</if> | |||
<if test="appraiseUser != null">appraise_user = #{appraiseUser},</if> | |||
<if test="appraiseNick != null">appraise_nick = #{appraiseNick},</if> | |||
<if test="appraiseScore != null">appraise_score = #{appraiseScore},</if> | |||
<if test="appraiseRemark != null">appraise_remark = #{appraiseRemark},</if> | |||
<if test="isAppraise != null">is_appraise = #{isAppraise},</if> | |||
<if test="createBy != null">create_by = #{createBy},</if> | |||
<if test="createTime != null">create_time = #{createTime},</if> | |||
<if test="updateBy != null">update_by = #{updateBy},</if> | |||
<if test="updateTime != null">update_time = #{updateTime},</if> | |||
<if test="params != null and params.__UPDATE != null"><foreach collection="params.__UPDATE" item="val" index="col">`${col}` = #{val},</foreach></if> | |||
</trim> | |||
where id = #{id} | |||
</update> | |||
@@ -336,34 +350,32 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" | |||
<if test="item.auditUser != null">audit_user = #{item.auditUser},</if> | |||
<if test="item.auditNick != null">audit_nick = #{item.auditNick},</if> | |||
<if test="item.auditDate != null">audit_date = #{item.auditDate},</if> | |||
<if test="item.isAudit != null">is_audit = #{item.isAudit},</if> | |||
<if test="item.appraiseUser != null">appraise_user = #{item.appraiseUser},</if> | |||
<if test="item.appraiseNick != null">appraise_nick = #{item.appraiseNick},</if> | |||
<if test="item.appraiseScore != null">appraise_score = #{item.appraiseScore},</if> | |||
<if test="item.appraiseRemark != null">appraise_remark = #{item.appraiseRemark},</if> | |||
<if test="item.isAppraise != null">is_appraise = #{item.isAppraise},</if> | |||
<if test="item.createBy != null">create_by = #{item.createBy},</if> | |||
<if test="item.createTime != null">create_time = #{item.createTime},</if> | |||
<if test="item.updateBy != null">update_by = #{item.updateBy},</if> | |||
<if test="item.updateTime != null">update_time = #{item.updateTime},</if> | |||
<if test="item.params != null and item.params.__UPDATE != null"><foreach collection="item.params.__UPDATE" item="val" index="col">`${col}` = #{val},</foreach></if> | |||
</set> | |||
where id = #{item.id} | |||
</foreach> | |||
</update> | |||
<!--主键删除--> | |||
<delete id="deleteTAgentTaskById" parameterType="Long"> | |||
delete from t_agent_task where id = #{id} | |||
</delete> | |||
<!--主键批量删除--> | |||
<delete id="deleteTAgentTaskByIds" parameterType="String"> | |||
delete from t_agent_task where id in | |||
delete from t_agent_task where id in | |||
<foreach item="id" collection="array" open="(" separator="," close=")"> | |||
#{id} | |||
</foreach> | |||
</delete> | |||
<!-- Harm --> | |||
<!--单条条件查询--> | |||
<select id="selectTAgentTask" parameterType="TAgentTask" resultMap="TAgentTaskResult"> | |||
<include refid="selectTAgentTaskVo"/> | |||
@@ -396,17 +408,19 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" | |||
<if test="auditUser != null and auditUser != ''"> and audit_user = #{auditUser}</if> | |||
<if test="auditNick != null and auditNick != ''"> and audit_nick = #{auditNick}</if> | |||
<if test="auditDate != null "> and audit_date = #{auditDate}</if> | |||
<if test="isAudit != null and isAudit != ''"> and is_audit = #{isAudit}</if> | |||
<if test="appraiseUser != null and appraiseUser != ''"> and appraise_user = #{appraiseUser}</if> | |||
<if test="appraiseNick != null and appraiseNick != ''"> and appraise_nick = #{appraiseNick}</if> | |||
<if test="appraiseScore != null "> and appraise_score = #{appraiseScore}</if> | |||
<if test="appraiseRemark != null and appraiseRemark != ''"> and appraise_remark = #{appraiseRemark}</if> | |||
<if test="isAppraise != null and isAppraise != ''"> and is_appraise = #{isAppraise}</if> | |||
</where> | |||
limit 1 | |||
</select> | |||
<!--条件查询数量--> | |||
<select id="selectTAgentTaskCount" parameterType="TAgentTask" resultType="Long"> | |||
select count(*) from t_agent_task | |||
select count(*) from t_agent_task | |||
<where> | |||
<if test="agentCenter != null and agentCenter != ''"> and agent_center = #{agentCenter}</if> | |||
<if test="countyCode != null and countyCode != ''"> and county_code = #{countyCode}</if> | |||
@@ -436,17 +450,19 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" | |||
<if test="auditUser != null and auditUser != ''"> and audit_user = #{auditUser}</if> | |||
<if test="auditNick != null and auditNick != ''"> and audit_nick = #{auditNick}</if> | |||
<if test="auditDate != null "> and audit_date = #{auditDate}</if> | |||
<if test="isAudit != null and isAudit != ''"> and is_audit = #{isAudit}</if> | |||
<if test="appraiseUser != null and appraiseUser != ''"> and appraise_user = #{appraiseUser}</if> | |||
<if test="appraiseNick != null and appraiseNick != ''"> and appraise_nick = #{appraiseNick}</if> | |||
<if test="appraiseScore != null "> and appraise_score = #{appraiseScore}</if> | |||
<if test="appraiseRemark != null and appraiseRemark != ''"> and appraise_remark = #{appraiseRemark}</if> | |||
<if test="isAppraise != null and isAppraise != ''"> and is_appraise = #{isAppraise}</if> | |||
</where> | |||
</select> | |||
<!--条件查询是否存在--> | |||
<select id="selectTAgentTaskExists" parameterType="TAgentTask" resultType="int"> | |||
select exists ( | |||
select 1 from t_agent_task | |||
select 1 from t_agent_task | |||
<where> | |||
<if test="agentCenter != null and agentCenter != ''"> and agent_center = #{agentCenter}</if> | |||
<if test="countyCode != null and countyCode != ''"> and county_code = #{countyCode}</if> | |||
@@ -476,10 +492,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" | |||
<if test="auditUser != null and auditUser != ''"> and audit_user = #{auditUser}</if> | |||
<if test="auditNick != null and auditNick != ''"> and audit_nick = #{auditNick}</if> | |||
<if test="auditDate != null "> and audit_date = #{auditDate}</if> | |||
<if test="isAudit != null and isAudit != ''"> and is_audit = #{isAudit}</if> | |||
<if test="appraiseUser != null and appraiseUser != ''"> and appraise_user = #{appraiseUser}</if> | |||
<if test="appraiseNick != null and appraiseNick != ''"> and appraise_nick = #{appraiseNick}</if> | |||
<if test="appraiseScore != null "> and appraise_score = #{appraiseScore}</if> | |||
<if test="appraiseRemark != null and appraiseRemark != ''"> and appraise_remark = #{appraiseRemark}</if> | |||
<if test="isAppraise != null and isAppraise != ''"> and is_appraise = #{isAppraise}</if> | |||
</where> | |||
limit 1 | |||
) | |||
@@ -503,4 +521,76 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" | |||
</trim> | |||
where id = #{id} | |||
</update> | |||
<resultMap id="AgentTaskTownGroupResultMap" type="com.ruoyi.agentcenter.vo.AgentTaskTownGroup"> | |||
<result property="num" column="num"/> | |||
<result property="numProcessFinish" column="num_process_finish"/> | |||
<result property="numApprovalFinish" column="num_approval_finish"/> | |||
<result property="numExcept" column="num_except"/> | |||
<result property="townName" column="town_name"/> | |||
<result property="townCode" column="town_code"/> | |||
<result property="orderYear" column="order_year"/> | |||
<result property="orderMonth" column="order_month"/> | |||
</resultMap> | |||
<select id="getAgentTaskGroupByTown" parameterType="TAgentTask" resultMap="AgentTaskTownGroupResultMap"> | |||
SELECT | |||
COUNT(*) as num, | |||
IFNULL(SUM(IF(agent_status = '3', 1, 0)), 0) as num_process_finish, | |||
IFNULL(SUM(IF(is_audit = 'Y', 1, 0)), 0) as num_approval_finish, | |||
IFNULL(SUM(IF(agent_status != '3' AND end_at < #{endAt}, 1, 0)), 0) as num_except, | |||
town_name, town_code, | |||
order_year, order_month | |||
FROM | |||
t_agent_task | |||
<where> | |||
<if test="agentCenter != null and agentCenter != ''"> and agent_center = #{agentCenter}</if> | |||
<if test="countyCode != null and countyCode != ''"> and county_code = #{countyCode}</if> | |||
<if test="orderYear != null and orderYear != ''"> and order_year = #{orderYear}</if> | |||
<if test="orderMonth != null and orderMonth != ''"> and order_month = #{orderMonth}</if> | |||
</where> | |||
GROUP BY town_code | |||
ORDER BY town_code | |||
</select> | |||
<resultMap id="AgentTaskVillageGroupResultMap" type="com.ruoyi.agentcenter.vo.AgentTaskVillageGroup"> | |||
<result property="num" column="num"/> | |||
<result property="numProcessFinish" column="num_process_finish"/> | |||
<result property="numApprovalFinish" column="num_approval_finish"/> | |||
<result property="numExcept" column="num_except"/> | |||
<result property="orgName" column="org_name"/> | |||
<result property="orgCode" column="org_code"/> | |||
<result property="townCode" column="town_code"/> | |||
<result property="bookId" column="book_id"/> | |||
<result property="bookName" column="book_name"/> | |||
<result property="distriDate" column="distri_date"/> | |||
<result property="handleDate" column="handle_date"/> | |||
<result property="endAt" column="end_at"/> | |||
<result property="handleNick" column="handle_nick"/> | |||
</resultMap> | |||
<select id="getAgentTaskGroupByVillage" parameterType="TAgentTask" resultMap="AgentTaskVillageGroupResultMap"> | |||
SELECT | |||
COUNT(*) as num, | |||
IFNULL(SUM(IF(agent_status = '3', 1, 0)), 0) as num_process_finish, | |||
IFNULL(SUM(IF(is_audit = 'Y', 1, 0)), 0) as num_approval_finish, | |||
IFNULL(SUM(IF(agent_status != '3' AND end_at < #{endAt}, 1, 0)), 0) as num_except, | |||
org_name, org_code, town_code, | |||
MAX(end_at) as end_at, MAX(handle_date) as handle_date, MAX(end_at) as end_at, handle_nick | |||
FROM | |||
t_agent_task | |||
<where> | |||
<if test="agentCenter != null and agentCenter != ''"> and agent_center = #{agentCenter}</if> | |||
<if test="townCode != null and townCode != ''"> and town_code = #{townCode}</if> | |||
<if test="orderYear != null and orderYear != ''"> and order_year = #{orderYear}</if> | |||
<if test="orderMonth != null and orderMonth != ''"> and order_month = #{orderMonth}</if> | |||
<if test="params != null"> | |||
<if test="params.townCodeList != null"> | |||
AND town_code IN (null <foreach collection="params.townCodeList" item="i">,#{i}</foreach> ) | |||
</if> | |||
</if> | |||
</where> | |||
GROUP BY org_code | |||
ORDER BY org_code | |||
</select> | |||
</mapper> |
@@ -7,6 +7,7 @@ import java.util.Map; | |||
import com.fasterxml.jackson.annotation.JsonFormat; | |||
import com.fasterxml.jackson.annotation.JsonIgnore; | |||
import com.fasterxml.jackson.annotation.JsonInclude; | |||
import com.ruoyi.common.utils.translation.TranslateUtils; | |||
/** | |||
* Entity基类 | |||
@@ -115,4 +116,76 @@ public class BaseEntity implements Serializable | |||
{ | |||
this.params = params; | |||
} | |||
/* | |||
* keepRawField为true, 保存原值到params | |||
* */ | |||
public void translate(boolean... keepRawField) { | |||
boolean b = null != keepRawField && keepRawField.length > 0 && keepRawField[0]; | |||
TranslateUtils.translateEntity(this, b); | |||
} | |||
@SuppressWarnings("unchecked") | |||
public <T extends BaseEntity> T putParam(String name, Object value) { | |||
getParams().put(name, value); | |||
return (T) this; | |||
} | |||
@SuppressWarnings("unchecked") | |||
public <T extends BaseEntity> T putParams(Object... args) { | |||
for (int i = 0; i < args.length; i += 2) { | |||
String name = (String) args[i]; | |||
Object value = args[i + 1]; | |||
getParams().put(name, value); | |||
} | |||
return (T) this; | |||
} | |||
@SuppressWarnings("unchecked") | |||
public <T extends BaseEntity> T removeParam(String... name) { | |||
if (params != null && null != name && name.length > 0) { | |||
for (String s : name) { | |||
params.remove(s); | |||
} | |||
} | |||
return (T) this; | |||
} | |||
@SuppressWarnings("unchecked") | |||
public <T extends BaseEntity> T removeParams() { | |||
if (params != null) | |||
params.clear(); | |||
return (T) this; | |||
} | |||
public Object obtainParam(String name) { | |||
if (params == null) | |||
return null; | |||
return params.get(name); | |||
} | |||
public Object obtainParam(String name, Object defValue) { | |||
if (params == null) | |||
return defValue; | |||
return params.getOrDefault(name, defValue); | |||
} | |||
@SuppressWarnings("unchecked") | |||
public <T> T obtainParamT(String name) { | |||
if (params == null) | |||
return null; | |||
return (T) params.get(name); | |||
} | |||
@SuppressWarnings("unchecked") | |||
public <T> T obtainParamT(String name, T defValue) { | |||
if (params == null) | |||
return defValue; | |||
return (T) params.getOrDefault(name, defValue); | |||
} | |||
public boolean containsParam(String name) { | |||
if (params == null) | |||
return false; | |||
return params.containsKey(name); | |||
} | |||
} |
@@ -24,6 +24,8 @@ public class SysDept extends BaseEntity | |||
{ | |||
private static final long serialVersionUID = 1L; | |||
public static final long ROOT_DEPT_ID = 100; | |||
/** 部门ID */ | |||
private Long deptId; | |||
@@ -69,6 +71,10 @@ public class SysDept extends BaseEntity | |||
/** 账套数 */ | |||
private Integer bookCount; | |||
// 级联递归查询 | |||
private Long rootId; | |||
private Integer orgCodeLength; | |||
public String getRemoteUrl() | |||
{ | |||
return remoteUrl; | |||
@@ -275,4 +281,24 @@ public class SysDept extends BaseEntity | |||
return 0; | |||
return orgCode.length(); | |||
} | |||
public Long getRootId() | |||
{ | |||
return rootId; | |||
} | |||
public void setRootId(Long rootId) | |||
{ | |||
this.rootId = rootId; | |||
} | |||
public Integer getOrgCodeLength() | |||
{ | |||
return orgCodeLength; | |||
} | |||
public void setOrgCodeLength(Integer orgCodeLength) | |||
{ | |||
this.orgCodeLength = orgCodeLength; | |||
} | |||
} |
@@ -0,0 +1,240 @@ | |||
package com.ruoyi.common.utils; | |||
import cn.hutool.core.collection.CollectionUtil; | |||
import cn.hutool.core.util.NumberUtil; | |||
import java.math.BigDecimal; | |||
import java.util.ArrayList; | |||
import java.util.Arrays; | |||
import java.util.Collection; | |||
import java.util.Iterator; | |||
import java.util.LinkedHashMap; | |||
import java.util.List; | |||
import java.util.Map; | |||
import java.util.Objects; | |||
import java.util.function.Function; | |||
import java.util.function.Predicate; | |||
import java.util.stream.Collectors; | |||
import java.util.stream.Stream; | |||
public final class ContainerUtils | |||
{ | |||
public static <T, R> List<T> unique(Function<T, R> getIdFunc, Collection<T>...args) | |||
{ | |||
List<T> list = new ArrayList<>(); | |||
Arrays.stream(args).filter(CollectionUtil::isNotEmpty).forEach(list::addAll); | |||
return unique(list, getIdFunc); | |||
} | |||
public static <T, R> List<T> unique_override(Function<T, R> getIdFunc, Collection<T>...args) | |||
{ | |||
List<T> list = new ArrayList<>(); | |||
Arrays.stream(args).filter(CollectionUtil::isNotEmpty).forEach(list::addAll); | |||
return unique_override(list, getIdFunc); | |||
} | |||
// keep | |||
public static <T, R> List<T> unique(Collection<T> collection, Function<T, R> getIdFunc) | |||
{ | |||
return new ArrayList<>(collection.stream().collect(Collectors.toMap(getIdFunc, x -> x, (a, b) -> a, LinkedHashMap::new)).values()); | |||
} | |||
public static <T, R> List<T> unique_override(Collection<T> collection, Function<T, R> getIdFunc) | |||
{ | |||
return new ArrayList<>(collection.stream().collect(Collectors.toMap(getIdFunc, x -> x, (a, b) -> b, LinkedHashMap::new)).values()); | |||
} | |||
public static <T, R> List<R> mapToList(Collection<T> collection, Function<T, R> mapFunc, boolean...unique) | |||
{ | |||
Stream<R> rStream = collection.stream().map(mapFunc); | |||
if(null != unique && unique.length > 0 && ConvertUtils.FALSE(unique[0])) | |||
rStream = rStream.distinct(); | |||
return rStream.collect(Collectors.toList()); | |||
} | |||
public static <T> List<T> subList(List<T> list, int start, Integer...end) | |||
{ | |||
int num = list.size(); | |||
if(num == 0) | |||
return new ArrayList<>(); | |||
if(start < 0) | |||
start = num + start; | |||
if(start < 0 || start >= num) | |||
return new ArrayList<>(); | |||
int e = list.size(); | |||
if(null != end && end.length > 0) | |||
e = end[0]; | |||
if(e < 0) | |||
e = list.size() + e; | |||
if(e < 0 || e > num) | |||
return new ArrayList<>(); | |||
return list.subList(start, e); | |||
} | |||
public static <T> List<T> filterToList(Collection<T> collection, Predicate<T> filterFunc) | |||
{ | |||
return collection.stream().filter(filterFunc).collect(Collectors.toList()); | |||
} | |||
public static <T, R> List<R> mapToUniqueList(Collection<T> collection, Function<T, R> mapFunc) | |||
{ | |||
return collection.stream().map(mapFunc).distinct().collect(Collectors.toList()); | |||
} | |||
public static <T, R> Map<R, List<T>> groupingBy(Collection<T> collection, Function<T, R> mapFunc) | |||
{ | |||
return collection.stream().collect(Collectors.groupingBy(mapFunc)); | |||
} | |||
public static <T, R, U> Map<R, List<U>> groupingBy(Collection<T> collection, Function<T, R> mapFunc, Function<T, U> mapValueFunc) | |||
{ | |||
return collection.stream().collect(Collectors.groupingBy(mapFunc, Collectors.mapping(mapValueFunc, Collectors.toList()))); | |||
} | |||
// keep | |||
public static <T, R> Map<R, T> toMap(Collection<T> collection, Function<T, R> mapFunc) | |||
{ | |||
return collection.stream().collect(Collectors.toMap(mapFunc, x -> x, (a, b) -> a)); | |||
} | |||
public static <T, R> Map<R, T> toMap_override(Collection<T> collection, Function<T, R> mapFunc) | |||
{ | |||
return collection.stream().collect(Collectors.toMap(mapFunc, x -> x, (a, b) -> b)); | |||
} | |||
// keep | |||
public static <T, R, U> Map<R, U> toMap(Collection<T> collection, Function<T, R> mapFunc, Function<T, U> valFunc) | |||
{ | |||
return collection.stream().collect(Collectors.toMap(mapFunc, valFunc, (a, b) -> a)); | |||
} | |||
public static <T, R, U> Map<R, U> toMap_override(Collection<T> collection, Function<T, R> mapFunc, Function<T, U> valFunc) | |||
{ | |||
return collection.stream().collect(Collectors.toMap(mapFunc, valFunc, (a, b) -> b)); | |||
} | |||
// keep | |||
public static <T, R> Map<R, T> toLinkedMap(Collection<T> collection, Function<T, R> mapFunc) | |||
{ | |||
return collection.stream().collect(Collectors.toMap(mapFunc, x -> x, (a, b) -> a, LinkedHashMap::new)); | |||
} | |||
public static <T, R> Map<R, T> toLinkedMap_override(Collection<T> collection, Function<T, R> mapFunc) | |||
{ | |||
return collection.stream().collect(Collectors.toMap(mapFunc, x -> x, (a, b) -> b, LinkedHashMap::new)); | |||
} | |||
/* | |||
*//** | |||
* ListTriple::negativeList -> 集合a独有的差集 | |||
* ListTriple::zeroList -> 集合a和集合b共有的交集 | |||
* ListTriple::positiveList -> 集合b独有的差集 | |||
*//* | |||
public static <T> ListTriple<T> intersection_difference(List<T> a, List<T> b, boolean...distinct *//* = false: 差集去重 *//*) | |||
{ | |||
if(CollectionUtil.isEmpty(a) && CollectionUtil.isEmpty(b)) | |||
return ListTriple.empty_triple(); | |||
if(CollectionUtil.isEmpty(a) && CollectionUtil.isNotEmpty(b)) | |||
return ListTriple.make_triple(b, (x) -> 1); | |||
if(CollectionUtil.isNotEmpty(a) && CollectionUtil.isEmpty(b)) | |||
return ListTriple.make_triple(a, (x) -> -1); | |||
ListTriple<T> triple = ListTriple.empty_triple(); | |||
List<T> intersection = a.stream().filter(b::contains).distinct().collect(Collectors.toList()); | |||
triple.zeroList.addAll(intersection); | |||
if(null != distinct && distinct.length > 0 && distinct[0]) | |||
{ | |||
triple.negativeList.addAll(a.stream().filter((x) -> !intersection.contains(x)).distinct().collect(Collectors.toList())); | |||
triple.positiveList.addAll(b.stream().filter((x) -> !intersection.contains(x)).distinct().collect(Collectors.toList())); | |||
} | |||
else | |||
{ | |||
triple.negativeList.addAll(a.stream().filter((x) -> !intersection.contains(x)).collect(Collectors.toList())); | |||
triple.positiveList.addAll(b.stream().filter((x) -> !intersection.contains(x)).collect(Collectors.toList())); | |||
} | |||
return triple; | |||
}*/ | |||
public static <T> T get(Collection<T> list, int index) | |||
{ | |||
if(CollectionUtil.isEmpty(list)) | |||
return null; | |||
int size = list.size(); | |||
int i = index < 0 ? size + index : index; | |||
if(i < 0 || i >= size) | |||
return null; | |||
if(list instanceof List) | |||
return ((List<T>) list).get(i); | |||
else | |||
{ | |||
Iterator<T> itor = list.iterator(); | |||
int c = 0; | |||
while(itor.hasNext()) | |||
{ | |||
T val = itor.next(); | |||
if(c == i) | |||
return val; | |||
c++; | |||
} | |||
} | |||
return null; | |||
} | |||
public static <T> boolean contains_ptr(Collection<T> list, T target) | |||
{ | |||
if(CollectionUtil.isEmpty(list)) | |||
return false; | |||
return list.stream().anyMatch((x) -> x == target); | |||
} | |||
public static <T> int indexOf_ptr(List<T> list, T target) | |||
{ | |||
if(CollectionUtil.isEmpty(list)) | |||
return -1; | |||
for(int i = 0; i < list.size(); i++) | |||
{ | |||
if(list.get(i) == target) | |||
return i; | |||
} | |||
return -1; | |||
} | |||
public static <T> List<T> combine(Collection<T>...src) | |||
{ | |||
if(null != src && src.length > 0) | |||
{ | |||
return Arrays.stream(src) | |||
.filter(Objects::nonNull) | |||
.flatMap(Collection::stream) | |||
.collect(Collectors.toList()); | |||
} | |||
return new ArrayList<>(); | |||
} | |||
public static <T> List<T> combine(List<List<T>> src) | |||
{ | |||
if(CollectionUtil.isNotEmpty(src)) | |||
{ | |||
return src.stream() | |||
.filter(Objects::nonNull) | |||
.flatMap(Collection::stream) | |||
.collect(Collectors.toList()); | |||
} | |||
return new ArrayList<>(); | |||
} | |||
public static <T> BigDecimal reduce_s(Collection<T> list, Function<T, BigDecimal> getDecimalFunc, BigDecimal initValue) | |||
{ | |||
BigDecimal init = null != initValue ? initValue : BigDecimal.ZERO; | |||
if(CollectionUtil.isEmpty(list)) | |||
return init; | |||
return list.stream().map(getDecimalFunc).reduce(init, NumberUtil::add); | |||
} | |||
public static <T> BigDecimal reduce_s(Collection<T> list, Function<T, BigDecimal> getDecimalFunc) | |||
{ | |||
return reduce_s(list, getDecimalFunc, BigDecimal.ZERO); | |||
} | |||
private ContainerUtils() {} | |||
} |
@@ -0,0 +1,30 @@ | |||
package com.ruoyi.common.utils; | |||
public final class ConvertUtils | |||
{ | |||
// null = true | |||
public static boolean TRUE(Boolean b) | |||
{ | |||
return null == b || b; | |||
} | |||
// null = false | |||
public static boolean FALSE(Boolean b) | |||
{ | |||
if(null == b) | |||
return false; | |||
return b; | |||
} | |||
public static String toString_s(Object obj) | |||
{ | |||
if(null == obj) | |||
return ""; | |||
if(obj instanceof String) | |||
return (String)obj; | |||
else | |||
return obj.toString(); | |||
} | |||
private ConvertUtils() {} | |||
} |
@@ -0,0 +1,143 @@ | |||
package com.ruoyi.common.utils; | |||
import cn.hutool.core.collection.CollectionUtil; | |||
import lombok.Builder; | |||
import lombok.Data; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import java.util.function.BiConsumer; | |||
import java.util.function.BiPredicate; | |||
import java.util.function.Consumer; | |||
import java.util.function.Function; | |||
import java.util.stream.Collectors; | |||
// zhao: 此TreeUtils不需要外部的容器包装类, 只需要配置`id`, `parentId`的getter和`children`的setter等 | |||
public final class TreeUtils | |||
{ | |||
// 从列表构建树 | |||
public static <T> List<T>/* 树 */ makeTree(List<T> list/* = 列表 */, ConfigInterface<T> config, Object...parentIdArgs) | |||
{ | |||
Object parentId = parentIdArgs.length > 0 ? parentIdArgs[0] : null; | |||
return list.stream() | |||
.filter((x) -> config.idEquals(parentId, config.getParentId(x))) | |||
.peek((x) -> config.setChildren(x, makeTree(list, config, config.getId(x)))) | |||
.collect(Collectors.toList()); | |||
} | |||
// 获取列表的所有叶子节点 | |||
public static <T> List<T>/* 列表 */ treeLeafs(List<T> list/* = 列表 */, ConfigInterface<T> config) | |||
{ | |||
return list.stream().filter((x) -> list.stream() | |||
.filter((y) -> !config.idEquals(config.getId(x), config.getId(y))) | |||
.noneMatch((y) -> config.idEquals(config.getId(x), config.getParentId(y))) | |||
) | |||
.collect(Collectors.toList()); | |||
} | |||
// 获取树的所有节点 | |||
public static <T> List<T>/* 列表 */ makeList(List<T> tree/* = 树 */, ConfigInterface<T> config) | |||
{ | |||
List<T> res = new ArrayList<>(); | |||
foreach(tree, res::add, config); | |||
return res; | |||
} | |||
// 从上到下遍历树节点 | |||
public static <T> void recursion(T node/* = 树节点 */, Consumer<T> func, ConfigInterface<T> config) | |||
{ | |||
if(null == node) | |||
return; | |||
func.accept(node); | |||
foreach(config.getChildren(node), func, config); | |||
} | |||
// 从上到下遍历树节点列表 | |||
public static <T> void foreach(List<T> tree/* = 树 */, Consumer<T> func, ConfigInterface<T> config) | |||
{ | |||
if(CollectionUtil.isEmpty(tree)) | |||
return; | |||
for(T child : tree) | |||
recursion(child, func, config); | |||
} | |||
// 从下到上遍历树节点 | |||
public static <T> void recursionReverse(T node/* = 树节点 */, Consumer<T> func, ConfigInterface<T> config) | |||
{ | |||
if(null == node) | |||
return; | |||
foreachReverse(config.getChildren(node), func, config); | |||
func.accept(node); | |||
} | |||
// 从下到上遍历树节点列表 | |||
public static <T> void foreachReverse(List<T> tree/* = 树 */, Consumer<T> func, ConfigInterface<T> config) | |||
{ | |||
if(CollectionUtil.isEmpty(tree)) | |||
return; | |||
for(T child : tree) | |||
recursionReverse(child, func, config); | |||
} | |||
public static interface ConfigInterface<T> | |||
{ | |||
public default boolean idEquals(Object a, Object b) // 比较ID/父ID是否想的, 默认Object::equals | |||
{ | |||
if(null == a && null == b) | |||
return true; | |||
if(null == a || null == b) | |||
return false; | |||
return a.equals(b); | |||
} | |||
public Object getId(T item); // 获取T的ID | |||
public Object getParentId(T item); // 获取T的父ID | |||
public void setChildren(T item, List<T> children); // 设置T的children列表 | |||
public List<T> getChildren(T object); // 获取T的children列表 | |||
} | |||
@Data | |||
@Builder | |||
public static class Config<T> implements ConfigInterface<T> // 简单的可实例化的T的配置类 | |||
{ | |||
public Function<T, Object> getIdFunc; // makeTree必需, 返回I的ID | |||
public Function<T, Object> getParentIdFunc; // makeTree必需, 返回I的父ID | |||
public BiConsumer<T, List<T>> setChildrenFunc; // makeTree必需, 设置T的children | |||
public BiPredicate<Object, Object> idEqualsFunc; // 非必需, 比较ID/父ID是否想的, 默认使用Object::equals | |||
public Function<T, List<T>> getChildrenFunc; // 遍历时必需, 返回T的children列表 | |||
public boolean idEquals(Object a, Object b) | |||
{ | |||
if(null != idEqualsFunc) | |||
return idEqualsFunc.test(a, b); | |||
if(null == a && null == b) | |||
return true; | |||
if(null == a || null == b) | |||
return false; | |||
return a.equals(b); | |||
} | |||
public Object getId(T item) | |||
{ | |||
return getIdFunc.apply(item); | |||
} | |||
public Object getParentId(T item) | |||
{ | |||
return getParentIdFunc.apply(item); | |||
} | |||
public void setChildren(T item, List<T> children) | |||
{ | |||
if(CollectionUtil.isNotEmpty(children)) | |||
setChildrenFunc.accept(item, children); | |||
} | |||
public List<T> getChildren(T object) | |||
{ | |||
return getChildrenFunc.apply(object); | |||
} | |||
} | |||
private TreeUtils() {} | |||
} |
@@ -0,0 +1,360 @@ | |||
package com.ruoyi.common.utils.dev; | |||
import cn.hutool.core.collection.CollectionUtil; | |||
import cn.hutool.core.io.FileUtil; | |||
import cn.hutool.core.io.IoUtil; | |||
import com.ruoyi.common.utils.StringUtils; | |||
import lombok.Data; | |||
import lombok.experimental.Accessors; | |||
import java.io.File; | |||
import java.io.InputStream; | |||
import java.util.LinkedHashMap; | |||
import java.util.List; | |||
import java.util.Map; | |||
import java.util.function.BiFunction; | |||
import java.util.function.Function; | |||
import java.util.regex.Pattern; | |||
import java.util.stream.Collectors; | |||
import java.util.zip.ZipEntry; | |||
import java.util.zip.ZipFile; | |||
@Data | |||
@Accessors(chain = true) | |||
public class ExtractGeneratedSource | |||
{ | |||
private String zipPath; | |||
private String javaProjectPath; | |||
private String webProjectPath; | |||
private String module; | |||
private Map<String, String> fileMap = new LinkedHashMap<>(); | |||
private ZipFile zipFile; | |||
public void Set(String zipPath, String javaProjectPath, String webProjectPath, String module) | |||
{ | |||
this.zipPath = zipPath; | |||
this.javaProjectPath = javaProjectPath; | |||
this.webProjectPath = webProjectPath; | |||
this.module = module; | |||
} | |||
public void Reset() | |||
{ | |||
if(null != zipFile) | |||
{ | |||
IoUtil.close(zipFile); | |||
zipFile = null; | |||
} | |||
fileMap.clear(); | |||
Set(null, null, null, null); | |||
} | |||
public boolean Test(String[] res) | |||
{ | |||
StringBuilder sb = new StringBuilder(); | |||
boolean r = true; | |||
List<String> files; | |||
Map<String, String> map = new LinkedHashMap<>(); | |||
Function<String, String> f = (x) -> { | |||
String str = GetExtractPath(x); | |||
map.put(x, str); | |||
return x + " -> " + str; | |||
}; | |||
files = ListFileInZip("main/java/com/ruoyi/.*/domain/.*\\.java"); | |||
r = r && CollectionUtil.isNotEmpty(files); | |||
sb.append("domain.java:\n") | |||
.append("\t"); | |||
if(CollectionUtil.isNotEmpty(files)) | |||
sb.append(files.stream().map(f).collect(Collectors.joining("\n\t"))); | |||
else | |||
sb.append("缺失!"); | |||
sb.append("\n\n"); | |||
files = ListFileInZip("main/java/com/ruoyi/.*/service/.*\\.java"); | |||
r = r && CollectionUtil.isNotEmpty(files); | |||
sb.append("service.java:\n") | |||
.append("\t"); | |||
if(CollectionUtil.isNotEmpty(files)) | |||
sb.append(files.stream().map(f).collect(Collectors.joining("\n\t"))); | |||
else | |||
sb.append("缺失!"); | |||
sb.append("\n\n"); | |||
// files = ListFileInZip("main/java/com/ruoyi/.*/service/impl/.*\\.java"); | |||
// r = r && CollectionUtil.isNotEmpty(files); | |||
// sb.append("service_impl.java:\n") | |||
// .append("\t") | |||
// .append(files.stream().map(f).collect(Collectors.joining("\n\t"))) | |||
// ; | |||
// sb.append("\n\n"); | |||
files = ListFileInZip("main/java/com/ruoyi/.*/mapper/.*\\.java"); | |||
r = r && CollectionUtil.isNotEmpty(files); | |||
sb.append("mapper.java:\n") | |||
.append("\t"); | |||
if(CollectionUtil.isNotEmpty(files)) | |||
sb.append(files.stream().map(f).collect(Collectors.joining("\n\t"))); | |||
else | |||
sb.append("缺失!"); | |||
sb.append("\n\n"); | |||
files = ListFileInZip("main/java/com/ruoyi/.*/controller/.*\\.java"); | |||
r = r && CollectionUtil.isNotEmpty(files); | |||
sb.append("controller.java:\n") | |||
.append("\t"); | |||
if(CollectionUtil.isNotEmpty(files)) | |||
sb.append(files.stream().map(f).collect(Collectors.joining("\n\t"))); | |||
else | |||
sb.append("缺失!"); | |||
sb.append("\n\n"); | |||
files = ListFileInZip("main/resources/mapper/.*/.*\\.xml"); | |||
r = r && CollectionUtil.isNotEmpty(files); | |||
sb.append("MyBatis.xml:\n") | |||
.append("\t"); | |||
if(CollectionUtil.isNotEmpty(files)) | |||
sb.append(files.stream().map(f).collect(Collectors.joining("\n\t"))); | |||
else | |||
sb.append("缺失!"); | |||
sb.append("\n\n"); | |||
files = ListFileInZip("vue/.*\\.vue"); | |||
r = r && CollectionUtil.isNotEmpty(files); | |||
sb.append("Vue:\n") | |||
.append("\t"); | |||
if(CollectionUtil.isNotEmpty(files)) | |||
sb.append(files.stream().map(f).collect(Collectors.joining("\n\t"))); | |||
else | |||
sb.append("缺失!"); | |||
sb.append("\n\n"); | |||
files = ListFileInZip("vue/.*\\.js"); | |||
r = r && CollectionUtil.isNotEmpty(files); | |||
sb.append("JavaScript:\n") | |||
.append("\t"); | |||
if(CollectionUtil.isNotEmpty(files)) | |||
sb.append(files.stream().map(f).collect(Collectors.joining("\n\t"))); | |||
else | |||
sb.append("缺失!"); | |||
sb.append("\n"); | |||
if(null != res && res.length > 0) | |||
res[0] = sb.toString(); | |||
fileMap.clear(); | |||
if(r) | |||
fileMap.putAll(map); | |||
return r; | |||
} | |||
public boolean IsValid() | |||
{ | |||
return StringUtils.isNotEmpty(zipPath) | |||
&& StringUtils.isNotEmpty(javaProjectPath) | |||
&& StringUtils.isNotEmpty(webProjectPath) | |||
; | |||
} | |||
public boolean Begin() | |||
{ | |||
try | |||
{ | |||
zipFile = new ZipFile(zipPath); | |||
return true; | |||
} | |||
catch(Exception e) | |||
{ | |||
e.printStackTrace(); | |||
return false; | |||
} | |||
} | |||
public boolean Extract(BiFunction<String, String, Integer> ifExists) | |||
{ | |||
if(CollectionUtil.isEmpty(fileMap)) | |||
return false; | |||
for(Map.Entry<String, String> entry : fileMap.entrySet()) | |||
{ | |||
String src = entry.getKey(); | |||
String dst = entry.getValue(); | |||
File d = new File(dst); | |||
if(d.exists()) | |||
{ | |||
if(null != ifExists) | |||
{ | |||
int ife = ifExists.apply(src, dst); | |||
if(ife == 0) | |||
continue; | |||
if(ife < 0) | |||
return false; | |||
} | |||
} | |||
if(!Copy(src, dst)) | |||
return false; | |||
} | |||
return true; | |||
} | |||
private boolean Copy(String src, String dst) | |||
{ | |||
File d = new File(dst); | |||
d.deleteOnExit(); | |||
if(mkdirs(d.getParent()) < 0) | |||
return false; | |||
byte[] source = ReadFileInZip(src); | |||
if(null == source) | |||
return false; | |||
return null != FileUtil.writeBytes(source, d); | |||
} | |||
public void End() | |||
{ | |||
} | |||
private String GuessModuleName(String zipPath) | |||
{ | |||
if(IsJava(zipPath)) | |||
{ | |||
int i = "main/java/com/ruoyi/".length(); | |||
int e = zipPath.indexOf("/", i); | |||
return zipPath.substring(i, e); | |||
} | |||
else if(IsMybatis(zipPath)) | |||
{ | |||
int i = "main/resources/mapper/".length(); | |||
int e = zipPath.indexOf("/", i); | |||
return zipPath.substring(i, e); | |||
} | |||
return null; | |||
} | |||
private String GetModuleName(String zipPath) | |||
{ | |||
if(StringUtils.isNotEmpty(module)) | |||
return module; | |||
return GuessModuleName(zipPath); | |||
} | |||
private String GetExtractPath(String zipPath) | |||
{ | |||
File file = new File(zipPath); | |||
String fileName = file.getName(); | |||
if(IsJava(zipPath)) | |||
{ | |||
if(IsController(zipPath)) | |||
{ | |||
String name = GuessModuleName(zipPath); | |||
return getJavaProjectPath() + "/ruoyi-admin/src/main/java/com/ruoyi/web/controller/" + name + "/" + fileName; | |||
} | |||
else | |||
{ | |||
String moduleName = GetModuleName(zipPath); | |||
return getJavaProjectPath() + "/ruoyi-" + moduleName + "/src/" + zipPath; | |||
} | |||
} | |||
else if(IsMybatis(zipPath)) | |||
{ | |||
String moduleName = GetModuleName(zipPath); | |||
return getJavaProjectPath() + "/ruoyi-" + moduleName + "/src/" + zipPath; | |||
} | |||
else if(IsVue(zipPath) || IsJavaScript(zipPath)) | |||
{ | |||
return webProjectPath + "/ruoyi-ui/src" + zipPath.substring("vue".length()); | |||
} | |||
return null; | |||
} | |||
private boolean IsJava(String zipPath) | |||
{ | |||
return zipPath.endsWith(".java"); | |||
} | |||
private boolean IsController(String zipPath) | |||
{ | |||
return zipPath.endsWith("Controller.java"); | |||
} | |||
private boolean IsMybatis(String zipPath) | |||
{ | |||
return zipPath.endsWith(".xml"); | |||
} | |||
private boolean IsVue(String zipPath) | |||
{ | |||
return zipPath.endsWith(".vue"); | |||
} | |||
private boolean IsJavaScript(String zipPath) | |||
{ | |||
return zipPath.endsWith(".js"); | |||
} | |||
private List<String> ListFileInZip(String regexp) | |||
{ | |||
return zipFile.stream() | |||
.map(ZipEntry::getName) | |||
.filter((x) -> { | |||
return (Pattern.matches(regexp, x)); | |||
}).collect(Collectors.toList()); | |||
} | |||
private byte[] ReadFileInZip(String path) | |||
{ | |||
ZipEntry entry = zipFile.getEntry(path); | |||
if(null == entry) | |||
return null; | |||
InputStream is = null; | |||
try | |||
{ | |||
is = zipFile.getInputStream(entry); | |||
return IoUtil.readBytes(is); | |||
} | |||
catch(Exception e) | |||
{ | |||
e.printStackTrace(); | |||
return null; | |||
} | |||
finally | |||
{ | |||
IoUtil.close(is); | |||
} | |||
} | |||
private int mkdirs(String path) | |||
{ | |||
File file = new File(path); | |||
if(file.exists()) | |||
{ | |||
if(file.isDirectory()) | |||
return 0; | |||
else | |||
return -1; | |||
} | |||
return file.mkdirs() ? 1 : -2; | |||
} | |||
private String AppendPath(String basePath, String filePath) | |||
{ | |||
String path = basePath + File.separator + filePath; | |||
File file = new File(path); | |||
try | |||
{ | |||
return file.getCanonicalPath(); | |||
} | |||
catch(Exception e) | |||
{ | |||
e.printStackTrace(); | |||
return path; | |||
} | |||
} | |||
public static void main(String[] args) | |||
{ | |||
ExtractGeneratedSourceGUI program = new ExtractGeneratedSourceGUI(); | |||
program.setVisible(true); | |||
} | |||
} |
@@ -0,0 +1,143 @@ | |||
package com.ruoyi.common.utils.dev; | |||
import com.ruoyi.common.utils.StringUtils; | |||
import com.ruoyi.common.utils.dev.gui.FileField; | |||
import com.ruoyi.common.utils.dev.gui.InputField; | |||
import javax.swing.*; | |||
import java.awt.*; | |||
public class ExtractGeneratedSourceGUI extends JFrame | |||
{ | |||
private ExtractGeneratedSource engine; | |||
private FileField zipPath; | |||
private FileField javaProjectPath; | |||
private FileField webProjectPath; | |||
private InputField module; | |||
private JTextPane result; | |||
private JButton writeBtn; | |||
private boolean canWrite; | |||
public ExtractGeneratedSourceGUI() | |||
{ | |||
super(); | |||
engine = new ExtractGeneratedSource(); | |||
Setup(); | |||
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); | |||
setTitle("代码解压器"); | |||
pack(); | |||
} | |||
private void Reset() | |||
{ | |||
engine.Reset(); | |||
zipPath.Reset(); | |||
javaProjectPath.Reset(); | |||
module.Reset(); | |||
webProjectPath.Reset(); | |||
canWrite = false; | |||
writeBtn.setEnabled(false); | |||
} | |||
private void Setup() | |||
{ | |||
JMenuBar menuBar = new JMenuBar(); | |||
setJMenuBar(menuBar); | |||
JMenu fileMenu = new JMenu("文件"); | |||
JMenuItem menuItem = new JMenuItem("清空"); | |||
menuItem.addActionListener(x -> Reset()); | |||
fileMenu.add(menuItem); | |||
menuItem = new JMenuItem("退出"); | |||
menuItem.addActionListener(x -> System.exit(0)); | |||
fileMenu.add(menuItem); | |||
JMenu otherMenu = new JMenu("其他"); | |||
menuItem = new JMenuItem("关于"); | |||
menuItem.addActionListener(x -> JOptionPane.showMessageDialog(this, "解压生成的代码压缩包", "关于", JOptionPane.INFORMATION_MESSAGE)); | |||
otherMenu.add(menuItem); | |||
menuBar.add(fileMenu); | |||
menuBar.add(otherMenu); | |||
zipPath = new FileField("源码zip文件(可拖拽)"); | |||
javaProjectPath = new FileField("后端项目根目录(可拖拽)"); | |||
webProjectPath = new FileField("前端项目根目录(可拖拽)"); | |||
String path; | |||
path = System.getenv("RUOYI_SOURCE_DIRECTORY_PATH"); | |||
if(StringUtils.isNotEmpty(path)) | |||
zipPath.SetLastPath(path); | |||
path = System.getenv("RUOYI_JAVA_PROJECT_PATH"); | |||
if(StringUtils.isNotEmpty(path)) | |||
javaProjectPath.SetPath(path); | |||
path = System.getenv("RUOYI_WEB_PROJECT_PATH"); | |||
if(StringUtils.isNotEmpty(path)) | |||
webProjectPath.SetPath(path); | |||
module = new InputField("模块"); | |||
module.SetToolTipText("例如. home(为空则自动从zip中获取)"); | |||
zipPath.SetFilter(".zip"); | |||
javaProjectPath.SetMode(JFileChooser.DIRECTORIES_ONLY); | |||
webProjectPath.SetMode(JFileChooser.DIRECTORIES_ONLY); | |||
Box formPanel = Box.createVerticalBox(); | |||
formPanel.setAutoscrolls(true); | |||
formPanel.add(zipPath); | |||
formPanel.add(javaProjectPath); | |||
formPanel.add(webProjectPath); | |||
formPanel.add(module); | |||
result = new JTextPane(); | |||
JScrollPane scrollPane = new JScrollPane(result); | |||
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); | |||
result.setFont(Font.getFont(Font.MONOSPACED)); | |||
formPanel.add(scrollPane); | |||
BorderLayout mainLayout = new BorderLayout(); | |||
JPanel panel = new JPanel(); | |||
panel.setLayout(mainLayout); | |||
panel.add(formPanel, BorderLayout.CENTER); | |||
Box toolbar = Box.createHorizontalBox(); | |||
toolbar.add(Box.createHorizontalGlue()); | |||
writeBtn = new JButton("复制"); | |||
writeBtn.addActionListener(e -> Copy()); | |||
writeBtn.setEnabled(false); | |||
toolbar.add(writeBtn); | |||
JButton startBtn = new JButton("测试"); | |||
startBtn.addActionListener(e -> Test()); | |||
toolbar.add(startBtn); | |||
JButton clearBtn = new JButton("清空"); | |||
clearBtn.addActionListener(e -> Reset()); | |||
toolbar.add(clearBtn); | |||
panel.add(toolbar, BorderLayout.SOUTH); | |||
setContentPane(panel); | |||
} | |||
private void Test() | |||
{ | |||
engine.Set(zipPath.Path(), javaProjectPath.Path(), webProjectPath.Path(), module.Text()); | |||
if(!engine.IsValid()) | |||
{ | |||
JOptionPane.showMessageDialog(this, "必须设置源码zip和后端/前端项目目录", "警告", JOptionPane.ERROR_MESSAGE); | |||
return; | |||
} | |||
engine.Begin(); | |||
String[] res = {null}; | |||
canWrite = engine.Test(res); | |||
result.setText(res[0]); | |||
writeBtn.setEnabled(canWrite); | |||
} | |||
private void Copy() | |||
{ | |||
if(canWrite) | |||
{ | |||
boolean r = engine.Extract((src, dst) -> { | |||
int res = JOptionPane.showConfirmDialog(this, "是否覆盖已存在文件: " + dst + "(原文件: " + src + ")", "警告", JOptionPane.YES_NO_CANCEL_OPTION); | |||
if(res == JOptionPane.YES_OPTION) | |||
return 1; | |||
else if(res == JOptionPane.NO_OPTION) | |||
return 0; | |||
else// if(res == JOptionPane.CANCEL_OPTION) | |||
return -1; | |||
}); | |||
if(r) | |||
JOptionPane.showMessageDialog(this, "复制文件成功!", "成功", JOptionPane.INFORMATION_MESSAGE); | |||
else | |||
JOptionPane.showMessageDialog(this, "复制文件失败!", "错误", JOptionPane.ERROR_MESSAGE); | |||
} | |||
engine.End(); | |||
} | |||
} |
@@ -0,0 +1,301 @@ | |||
package com.ruoyi.common.utils.dev; | |||
import java.util.Objects; | |||
// Unix \033[字背景颜色;字体颜色m字符串\033[0m | |||
// 高亮+闪烁+红色前景+蓝色背景 | |||
// 32位 |设置8位 0 0 0 0 0 启用背景色 背景高亮 字体高亮|字体风格8位|字体色8位|背景色8位 | |||
public class Konsole { | |||
private static final String RESET = "\033[0m"; // Text Reset | |||
private static final int COLOR_OFFSET = 8; | |||
private static final int COLOR_MASK = 0xFF00; | |||
private static final int BG_COLOR_OFFSET = 0; | |||
private static final int BG_COLOR_MASK = 0xFF; | |||
private static final int FONT_STYLE_OFFSET = 16; | |||
private static final int FONT_STYLE_MASK = 0xFF0000; | |||
private static final int STYLE_OFFSET = 24; | |||
private static final int STYLE_MASK = 0x7F000000; | |||
// 1. 原始值: 需要SetXXX(值)设置, MakeStyle | |||
public static final int FONT_BRIGHT = 1; | |||
public static final int BG_BRIGHT = 1 << 1; | |||
public static final int BG_ENABLED = 1 << 2; | |||
public static final int NORMAL = 0; // 3:斜体 4:下划线 5:闪烁 6:默认 7:白底 8:透明 9:删除线 | |||
public static final int BOLD = 1; | |||
public static final int FAINT = 2; | |||
public static final int ITALIC = 3; | |||
public static final int UNDERLINE = 4; | |||
public static final int FLASH = 5; | |||
public static final int DEFAULT = 6; | |||
public static final int WHITE_BACKGROUND = 7; | |||
public static final int TRANSLUCENT = 8; | |||
public static final int STRIKETHROUGH = 9; | |||
public static final int DOUBLE_UNDER_LINE = 21; | |||
public static final int BLACK = 30; // BLACK | |||
public static final int RED = 31; // RED | |||
public static final int GREEN = 32; // GREEN | |||
public static final int YELLOW = 33; // YELLOW | |||
public static final int BLUE = 34; // BLUE | |||
public static final int PURPLE = 35; // PURPLE | |||
public static final int CYAN = 36; // CYAN | |||
public static final int WHITE = 37; // WHITE | |||
// 2. 预置值: 可以 | 或拼接 | |||
public static final int S_FONT_BRIGHT = FONT_BRIGHT << STYLE_OFFSET; | |||
public static final int S_BG_BRIGHT = BG_BRIGHT << STYLE_OFFSET; | |||
public static final int S_BG_ENABLED = BG_BRIGHT << STYLE_OFFSET; | |||
public static final int FS_NORMAL = NORMAL; | |||
public static final int FS_BOLD = BOLD << FONT_STYLE_OFFSET; | |||
public static final int FS_FAINT = FAINT << FONT_STYLE_OFFSET; | |||
public static final int FS_ITALIC = ITALIC << FONT_STYLE_OFFSET; | |||
public static final int FS_UNDERLINE = UNDERLINE << FONT_STYLE_OFFSET; | |||
public static final int FS_FLASH = FLASH << FONT_STYLE_OFFSET; | |||
public static final int FS_DEFAULT = DEFAULT << FONT_STYLE_OFFSET; | |||
public static final int FS_WHITE_BACKGROUND = WHITE_BACKGROUND << FONT_STYLE_OFFSET; | |||
public static final int FS_TRANSLUCENT = TRANSLUCENT << FONT_STYLE_OFFSET; | |||
public static final int FS_STRIKETHROUGH = STRIKETHROUGH << FONT_STYLE_OFFSET; | |||
public static final int FS_DOUBLE_UNDER_LINE = DOUBLE_UNDER_LINE << STYLE_OFFSET; | |||
public static final int FC_BLACK = BLACK << COLOR_OFFSET; | |||
public static final int FC_RED = RED << COLOR_OFFSET; | |||
public static final int FC_GREEN = GREEN << COLOR_OFFSET; | |||
public static final int FC_YELLOW = YELLOW << COLOR_OFFSET; | |||
public static final int FC_BLUE = BLUE << COLOR_OFFSET; | |||
public static final int FC_PURPLE = PURPLE << COLOR_OFFSET; | |||
public static final int FC_CYAN = CYAN << COLOR_OFFSET; | |||
public static final int FC_WHITE = WHITE << COLOR_OFFSET; | |||
public static final int BC_BLACK = BLACK; | |||
public static final int BC_RED = RED; | |||
public static final int BC_GREEN = GREEN; | |||
public static final int BC_YELLOW = YELLOW; | |||
public static final int BC_BLUE = BLUE; | |||
public static final int BC_PURPLE = PURPLE; | |||
public static final int BC_CYAN = CYAN; | |||
public static final int BC_WHITE = WHITE; | |||
public static final int FC_BRIGHT_BLACK = (BLACK + 60) << COLOR_OFFSET; | |||
public static final int FC_BRIGHT_RED = (RED + 60) << COLOR_OFFSET; | |||
public static final int FC_BRIGHT_GREEN = (GREEN + 60) << COLOR_OFFSET; | |||
public static final int FC_BRIGHT_YELLOW = (YELLOW + 60) << COLOR_OFFSET; | |||
public static final int FC_BRIGHT_BLUE = (BLUE + 60) << COLOR_OFFSET; | |||
public static final int FC_BRIGHT_PURPLE = (PURPLE + 60) << COLOR_OFFSET; | |||
public static final int FC_BRIGHT_CYAN = (CYAN + 60) << COLOR_OFFSET; | |||
public static final int FC_BRIGHT_WHITE = (WHITE + 60) << COLOR_OFFSET; | |||
public static final int BC_BRIGHT_BLACK = BLACK + 70; | |||
public static final int BC_BRIGHT_RED = RED + 70; | |||
public static final int BC_BRIGHT_GREEN = GREEN + 70; | |||
public static final int BC_BRIGHT_YELLOW = YELLOW + 70; | |||
public static final int BC_BRIGHT_BLUE = BLUE + 70; | |||
public static final int BC_BRIGHT_PURPLE = PURPLE + 70; | |||
public static final int BC_BRIGHT_CYAN = CYAN + 70; | |||
public static final int BC_BRIGHT_WHITE = WHITE + 70; | |||
public int style; | |||
public Konsole(int style) { | |||
this.style = style; | |||
} | |||
public Konsole SetFontColor(int color) { | |||
this.style = SetAttribute(color, COLOR_OFFSET, COLOR_MASK); | |||
return this; | |||
} | |||
public Konsole SetFontStyle(int style) { | |||
this.style = SetAttribute(style, FONT_STYLE_OFFSET, FONT_STYLE_MASK); | |||
return this; | |||
} | |||
public Konsole SetBGColor(int color) { | |||
this.style = SetAttribute(color, BG_COLOR_OFFSET, BG_COLOR_MASK); | |||
return this; | |||
} | |||
public Konsole SetStyleConfig(int style, boolean enabled) { | |||
if(enabled) | |||
this.style = style << STYLE_OFFSET | (this.style & ~STYLE_MASK); | |||
else | |||
this.style = (this.style & ~STYLE_MASK) & ~(style << STYLE_OFFSET); | |||
return this; | |||
} | |||
public int Style() { | |||
return style; | |||
} | |||
public Konsole Style(int style) { | |||
this.style = style; | |||
return this; | |||
} | |||
private int SetAttribute(int color, int offset, int mask) { | |||
int newColor = color << offset; | |||
return (this.style & ~mask) | newColor; | |||
} | |||
private static int GetAttribute(int style, int offset, int mask) { | |||
return (style & mask) >> offset; | |||
} | |||
@Override | |||
public String toString() { | |||
return GetEscString(this.style); | |||
} | |||
public String Output(String str) | |||
{ | |||
StringBuilder sb = new StringBuilder(); | |||
sb.append(GetEscString(style)); | |||
sb.append(str); | |||
sb.append(RESET); | |||
return sb.toString(); | |||
} | |||
public static String MakeText(String str, int style) | |||
{ | |||
StringBuilder sb = new StringBuilder(); | |||
sb.append(GetEscString(style)); | |||
sb.append(str); | |||
sb.append(RESET); | |||
return sb.toString(); | |||
} | |||
public static int MakeStyle(int fontColor, int fontStyle, int bgColor, int style) | |||
{ | |||
return (fontColor << COLOR_OFFSET) | (fontStyle << FONT_STYLE_OFFSET) | (bgColor << BG_COLOR_OFFSET) << (style << STYLE_OFFSET); | |||
} | |||
public static int GenStyle(int... mask) | |||
{ | |||
int style = 0; | |||
for (int j : mask) style |= j; | |||
return style; | |||
} | |||
private static String GetEscString(int style) { | |||
if (style == 0) return RESET; | |||
StringBuilder sb = new StringBuilder(); | |||
sb.append("\033["); | |||
sb.append(GenStyleStr(style)); | |||
sb.append("m"); | |||
return sb.toString(); | |||
} | |||
private static String GenStyleStr(int style) { | |||
int enableBG = GetAttribute(style, 2, STYLE_MASK); | |||
int fontColor = GetAttribute(style, COLOR_OFFSET, COLOR_MASK); | |||
int fontStyle = GetAttribute(style, FONT_STYLE_OFFSET, FONT_STYLE_MASK); | |||
StringBuilder sb = new StringBuilder(); | |||
if(fontStyle != 0) | |||
sb.append(fontStyle).append(";"); | |||
if(fontColor != 0) | |||
{ | |||
int hlFont = GetAttribute(style, 0, STYLE_MASK); | |||
fontColor = GenColor(fontColor, hlFont != 0 ? 90 - 30 : 0); | |||
sb.append(fontColor).append(";"); | |||
} | |||
if(enableBG != 0) | |||
{ | |||
int bgColor = GetAttribute(style, BG_COLOR_OFFSET, BG_COLOR_MASK); | |||
if(bgColor != 0) | |||
{ | |||
int hlBG = GetAttribute(style, 1, STYLE_MASK); | |||
bgColor = GenColor(bgColor, hlBG != 0 ? 100 - 30 : 40 - 30); | |||
sb.append(bgColor).append(";"); | |||
} | |||
} | |||
if(sb.length() > 0 && sb.lastIndexOf(";") == sb.length() - 1) | |||
sb.deleteCharAt(sb.length() - 1); | |||
return sb.toString(); | |||
} | |||
private static int GenColor(int color, int base) | |||
{ | |||
return color + base; | |||
} | |||
public static final int STDOUT = 1; | |||
public static final int STDERR = 2; | |||
public static class out | |||
{ | |||
public static void println(int style, Object obj) | |||
{ | |||
System.out.println(MakeText(Objects.toString(obj), style)); | |||
} | |||
public static void print(int style, Object obj) | |||
{ | |||
System.out.print(MakeText(Objects.toString(obj), style)); | |||
} | |||
public static void printf(int style, String fmt, Object...args) | |||
{ | |||
if(null == fmt) | |||
println(style, fmt); | |||
else | |||
println(style, String.format(fmt, args)); | |||
} | |||
} | |||
public static class err | |||
{ | |||
public static void println(int style, Object obj) | |||
{ | |||
System.err.println(MakeText(Objects.toString(obj), style)); | |||
} | |||
public static void print(int style, Object obj) | |||
{ | |||
System.err.print(MakeText(Objects.toString(obj), style)); | |||
} | |||
public static void printf(int style, String fmt, Object...args) | |||
{ | |||
if(null == fmt) | |||
println(style, fmt); | |||
else | |||
println(style, String.format(fmt, args)); | |||
} | |||
} | |||
public static void cout(int style, Object obj) | |||
{ | |||
out.println(style, obj); | |||
} | |||
public static void cerr(int style, Object obj) | |||
{ | |||
err.println(style, obj); | |||
} | |||
public static void printf(int style, String fmt, Object...args) | |||
{ | |||
out.printf(style, fmt, args); | |||
} | |||
public static void fprintf(int file, int style, String fmt, Object...args) | |||
{ | |||
if(file == STDERR) | |||
err.printf(style, fmt, args); | |||
else | |||
out.printf(style, fmt, args); | |||
} | |||
public static String sprintf(int style, String fmt, Object...args) | |||
{ | |||
return MakeText(null != fmt ? String.format(fmt, args) : "null", style); | |||
} | |||
public static void main(String[] args) { | |||
System.out.println("\033[0;7;31;44m TEXT \033[0m"); | |||
System.out.println(MakeText("TEXT", FS_UNDERLINE | FC_BLUE | S_BG_BRIGHT | S_BG_ENABLED | BC_CYAN | S_FONT_BRIGHT)); | |||
} | |||
} |
@@ -0,0 +1,394 @@ | |||
package com.ruoyi.common.utils.dev; | |||
import cn.hutool.core.collection.CollectionUtil; | |||
import cn.hutool.core.io.FileUtil; | |||
import cn.hutool.core.util.StrUtil; | |||
import com.ruoyi.common.utils.StringUtils; | |||
import lombok.Data; | |||
import lombok.experimental.Accessors; | |||
import java.io.File; | |||
import java.util.ArrayList; | |||
import java.util.LinkedHashMap; | |||
import java.util.List; | |||
import java.util.Map; | |||
import java.util.Scanner; | |||
@Data | |||
@Accessors(chain = true) | |||
public class SQLQueryFuncGen | |||
{ | |||
private String workPath; | |||
private String queryId; | |||
private String entity; | |||
private String module; | |||
private String packageName; | |||
private String comment; | |||
private Map<String, String> parameterType; | |||
private String returnType; | |||
private String mapper_java; | |||
private String service_java; | |||
private String serviceImpl_java; | |||
private final static String PARAM_DEFAULT_NAME = "cond"; | |||
public String GetParameterType() | |||
{ | |||
return GenParameterStr(1); | |||
} | |||
public void SetParameterType(String type) | |||
{ | |||
parameterType = ParseParameterType(type); | |||
} | |||
public String GetReturnType() | |||
{ | |||
return returnType; | |||
} | |||
public void SetReturnType(String type) | |||
{ | |||
this.returnType = ParseReturnType(type); | |||
} | |||
public SQLQueryFuncGen() | |||
{ | |||
workPath = System.getProperty("user.dir").replaceAll(File.pathSeparator, "/"); | |||
} | |||
private String In(String label) | |||
{ | |||
Konsole.out.print(Konsole.FC_BLUE, label); | |||
Scanner scanner = new Scanner(System.in); | |||
String str = scanner.nextLine(); | |||
if(StrUtil.isEmpty(str)) | |||
return ""; | |||
return str.trim(); | |||
} | |||
private String WaitIn(String label) | |||
{ | |||
String str; | |||
do | |||
{ | |||
str = In(label); | |||
} | |||
while(StrUtil.isEmpty(str)); | |||
return str; | |||
} | |||
private String ParseReturnType(String type) | |||
{ | |||
if(StrUtil.isEmpty(type)) | |||
return "void" ; // entity; | |||
if(type.equalsIgnoreCase("List")) | |||
return String.format("List<%s>", entity); | |||
if(type.equalsIgnoreCase("Map")) | |||
return "Map<String, Object>"; | |||
if(type.equalsIgnoreCase("List<Map>")) | |||
return "List<Map<String, Object>>"; | |||
return type; | |||
} | |||
private String ReadReturnType(String label) | |||
{ | |||
String type = In(label); | |||
return ParseReturnType(type); | |||
} | |||
private void GuessType(String type, Map<String, String> res) | |||
{ | |||
String name = null; | |||
String newType = null; | |||
if(type.equalsIgnoreCase("List")) | |||
{ | |||
name = StrUtil.lowerFirst(entity) + "List"; | |||
newType = String.format("List<%s>", entity); | |||
} | |||
else if(type.equalsIgnoreCase("Map")) | |||
{ | |||
name = "map"; | |||
newType = "Map<String, Object>"; | |||
} | |||
else if(type.equalsIgnoreCase("ID")) | |||
{ | |||
name = "id"; | |||
newType = "Long"; | |||
} | |||
else if(type.equalsIgnoreCase("Long")) | |||
{ | |||
name = "num"; | |||
newType = "Long"; | |||
} | |||
else if(type.equalsIgnoreCase("int")) | |||
{ | |||
name = "i"; | |||
newType = "int"; | |||
} | |||
else if(type.equalsIgnoreCase("BigDecimal")) | |||
{ | |||
name = "num"; | |||
newType = "BigDecimal"; | |||
} | |||
else if(type.equalsIgnoreCase("String")) | |||
{ | |||
name = "name"; | |||
newType = "String"; | |||
} | |||
else if(type.equalsIgnoreCase("List<Map>")) | |||
{ | |||
name = "mapList"; | |||
newType = "List<Map<String, Object>>"; | |||
} | |||
else if(type.equalsIgnoreCase("void")) | |||
{ | |||
name = ""; | |||
newType = ""; | |||
} | |||
else | |||
{ | |||
if(!type.contains(" ")) | |||
{ | |||
name = StrUtil.lowerFirst(type); | |||
newType = type; | |||
} | |||
else | |||
{ | |||
String[] arr = type.split(" "); | |||
for(String s : arr) | |||
{ | |||
GuessType(s.trim(), res); | |||
} | |||
} | |||
} | |||
if(StrUtil.isNotEmpty(name)) | |||
{ | |||
int i = 0; | |||
String newName = name; | |||
while(res.containsKey(newName)) | |||
newName = name + (++i); | |||
res.put(newName, newType); | |||
} | |||
} | |||
private Map<String, String> ReadParameterType(String label) | |||
{ | |||
String type = In(label); | |||
return ParseParameterType(type); | |||
} | |||
private Map<String, String> ParseParameterType(String type) | |||
{ | |||
Map<String, String> res = new LinkedHashMap<>(); | |||
if(StrUtil.isEmpty(type)) | |||
{ | |||
/*res.put(PARAM_DEFAULT_NAME, entity); | |||
return res;*/ | |||
return null; | |||
} | |||
GuessType(type, res); | |||
return res; | |||
} | |||
private String GenParameterStr(int type) | |||
{ | |||
if(null == parameterType) | |||
return ""; | |||
List<String> list = new ArrayList<>(); | |||
parameterType.forEach((k, v) -> { | |||
String str = ""; | |||
if((type & 1) != 0) | |||
str += v; | |||
if((type & 2) != 0) | |||
str += (str.isEmpty() ? k : (" " + k)); | |||
list.add(str); | |||
}); | |||
return CollectionUtil.join(list, ", "); | |||
} | |||
public void ScanFilePath() | |||
{ | |||
String modulePath = String.format("%s/ruoyi-%s/src/main/java/com/ruoyi/%s", workPath, module, StringUtils.isNotEmpty(packageName) ? packageName : module); | |||
String mapperPath = modulePath + "/" + "mapper"; | |||
String servicePath = modulePath + "/" + "service"; | |||
String serviceImplPath = modulePath + "/" + "service/impl"; | |||
String mapperName = entity + "Mapper"; | |||
String serviceName = "I" + entity + "Service"; | |||
String serviceImplName = entity + "ServiceImpl"; | |||
mapper_java = mapperPath + "/" + mapperName + ".java"; | |||
service_java = servicePath + "/" + serviceName + ".java"; | |||
serviceImpl_java = serviceImplPath + "/" + serviceImplName + ".java"; | |||
} | |||
private void PrintSummary() | |||
{ | |||
Konsole.cout(Konsole.FC_GREEN, "Configure: "); | |||
Konsole.cout(Konsole.FC_CYAN, "Mybatis query ID: " + queryId); | |||
Konsole.cout(Konsole.FC_CYAN, "Entity class: " + entity); | |||
Konsole.cout(Konsole.FC_CYAN, "Module name: " + module); | |||
Konsole.cout(Konsole.FC_CYAN, "Package name: " + packageName); | |||
Konsole.cout(Konsole.FC_CYAN, "Return type: " + returnType); | |||
Konsole.cout(Konsole.FC_CYAN, "Parameter type: " + parameterType); | |||
Konsole.cout(Konsole.FC_CYAN, "Parameter type string: " + GenParameterStr(1 | 2)); | |||
Konsole.cout(Konsole.FC_CYAN, "Mapper file: " + mapper_java); | |||
Konsole.cout(Konsole.FC_CYAN, "Service type: " + service_java); | |||
Konsole.cout(Konsole.FC_CYAN, "Service implement type: " + serviceImpl_java); | |||
Konsole.cout(Konsole.FC_CYAN, "Comment: \n" + GenComment()); | |||
Konsole.cout(Konsole.FC_CYAN, "Function define: \n" + GenFuncDef()); | |||
Konsole.cout(Konsole.FC_CYAN, "Function declare: \n" + GenFuncDecl()); | |||
} | |||
public boolean IsValid() | |||
{ | |||
return StrUtil.isNotEmpty(queryId) | |||
&& StrUtil.isNotEmpty(entity) | |||
&& StrUtil.isNotEmpty(module) | |||
&& StrUtil.isNotEmpty(queryId) | |||
// && StrUtil.isNotEmpty(returnType) | |||
// && CollectionUtil.isNotEmpty(parameterType) | |||
; | |||
} | |||
private boolean CheckFile() | |||
{ | |||
File file = new File(mapper_java); | |||
if(!file.isFile()) return false; | |||
file = new File(service_java); | |||
if(!file.isFile()) return false; | |||
file = new File(serviceImpl_java); | |||
if(!file.isFile()) return false; | |||
return true; | |||
} | |||
private String GenFuncDef() | |||
{ | |||
String str = String.format("\tpublic %s %s(%s);", returnType, queryId, GenParameterStr(1 | 2)); | |||
return str; | |||
} | |||
private String GenFuncDecl() | |||
{ | |||
String mapperProp = StrUtil.lowerFirst(entity) + "Mapper"; | |||
String str = String.format("\t@Override\n\tpublic %s %s(%s)\n\t{\n\t\treturn %s.%s(%s);\n\t}" | |||
, returnType, queryId, GenParameterStr(1 | 2), mapperProp, queryId, GenParameterStr(2)); | |||
return str; | |||
} | |||
public String GenMapperCode() | |||
{ | |||
StringBuilder sb = new StringBuilder(); | |||
String commentStr = GenComment(); | |||
if(StrUtil.isNotEmpty(commentStr)) | |||
commentStr += "\n"; | |||
String funcDef = commentStr + GenFuncDef(); | |||
sb.append(funcDef); | |||
return sb.toString(); | |||
} | |||
public String GenServiceCode() | |||
{ | |||
return GenMapperCode(); | |||
} | |||
public String GenServiceImplCode() | |||
{ | |||
StringBuilder sb = new StringBuilder(); | |||
String commentStr = GenComment(); | |||
if(StrUtil.isNotEmpty(commentStr)) | |||
commentStr += "\n"; | |||
String funcDecl = commentStr + GenFuncDecl(); | |||
sb.append(funcDecl); | |||
return sb.toString(); | |||
} | |||
private boolean AppendFile(String content, String path) | |||
{ | |||
File file = new File(path); | |||
String source = FileUtil.readUtf8String(file); | |||
StringBuilder sb = new StringBuilder(source); | |||
int index = sb.lastIndexOf("}"); | |||
if(index == -1) | |||
return false; | |||
sb.insert(index, "\n" + content + "\n"); | |||
String newSource = sb.toString(); | |||
FileUtil.writeUtf8String(newSource, file); | |||
return true; | |||
} | |||
public String GenComment() | |||
{ | |||
if(StrUtil.isEmpty(comment)) | |||
return ""; | |||
StringBuilder sb = new StringBuilder(); | |||
sb.append("\t/**\n") | |||
.append("\t * ").append(comment).append("\n") | |||
.append("\t *\n"); | |||
if(null != parameterType) | |||
{ | |||
parameterType.forEach((k, v) -> { | |||
sb.append("\t * @param ").append(k).append(" ").append(v).append("\n"); | |||
}); | |||
} | |||
sb.append("\t * @return 结果 ").append(returnType).append("\n") | |||
.append("\t */"); | |||
return sb.toString(); | |||
} | |||
public boolean Write() | |||
{ | |||
Konsole.cout(Konsole.FC_GREEN, "Start......"); | |||
if(!CheckFile()) | |||
{ | |||
Konsole.cerr(Konsole.BC_YELLOW | Konsole.S_BG_ENABLED, "File not exists!"); | |||
return false; | |||
} | |||
Konsole.cout(Konsole.FC_GREEN, String.format("Handle mapper(%s)......", mapper_java)); | |||
AppendFile(GenMapperCode(), mapper_java); | |||
Konsole.cout(Konsole.FC_GREEN, String.format("Handle service(%s)......", service_java)); | |||
AppendFile(GenServiceCode(), service_java); | |||
Konsole.cout(Konsole.FC_GREEN, String.format("Handle serviceImpl(%s)......", serviceImpl_java)); | |||
AppendFile(GenServiceImplCode(), serviceImpl_java); | |||
Konsole.cout(Konsole.FC_GREEN, "Done!"); | |||
return true; | |||
} | |||
public void Reset() | |||
{ | |||
queryId = ""; | |||
entity = ""; | |||
module = ""; | |||
packageName = ""; | |||
comment = ""; | |||
parameterType = null; | |||
returnType = ""; | |||
mapper_java = ""; | |||
service_java = ""; | |||
serviceImpl_java = ""; | |||
} | |||
private boolean Run() | |||
{ | |||
queryId = WaitIn("Please input Mybatis query id: "); | |||
entity = WaitIn("Please input entity class: "); | |||
module = WaitIn("Please input module: "); | |||
packageName = WaitIn("Please input package name(If empty, using `module`): "); | |||
returnType = ReadReturnType("Please input return type: "); | |||
parameterType = ReadParameterType("Please input parameter type: "); | |||
comment = In("Please input comment: "); | |||
ScanFilePath(); | |||
PrintSummary(); | |||
return Write(); | |||
} | |||
public static void main(String[] args) | |||
{ | |||
SQLQueryFuncGenGUI frame = new SQLQueryFuncGenGUI(); | |||
frame.setVisible(true); | |||
/*SQLQueryFuncGen gen = new SQLQueryFuncGen(); | |||
gen.Run();*/ | |||
} | |||
} |
@@ -0,0 +1,173 @@ | |||
package com.ruoyi.common.utils.dev; | |||
import cn.hutool.core.util.StrUtil; | |||
import com.ruoyi.common.utils.dev.gui.InputField; | |||
import javax.swing.*; | |||
import java.awt.*; | |||
import java.awt.event.ActionEvent; | |||
import java.awt.event.ActionListener; | |||
public class SQLQueryFuncGenGUI extends JFrame | |||
{ | |||
private SQLQueryFuncGen engine; | |||
private InputField queryId; | |||
private InputField entity; | |||
private InputField module; | |||
private InputField packageName; | |||
private InputField comment; | |||
private InputField parameterType; | |||
private InputField returnType; | |||
private JTextPane result; | |||
private JButton writeBtn; | |||
private ActionListener inputListener = new ActionListener() | |||
{ | |||
@Override | |||
public void actionPerformed(ActionEvent e) | |||
{ | |||
writeBtn.setEnabled(false); | |||
result.setText(""); | |||
} | |||
}; | |||
public SQLQueryFuncGenGUI() | |||
{ | |||
super(); | |||
engine = new SQLQueryFuncGen(); | |||
Setup(); | |||
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); | |||
setTitle("Mybatis查询代码生成器"); | |||
pack(); | |||
} | |||
private void Setup() | |||
{ | |||
JMenuBar menuBar = new JMenuBar(); | |||
setJMenuBar(menuBar); | |||
JMenu fileMenu = new JMenu("文件"); | |||
JMenuItem menuItem = new JMenuItem("清空"); | |||
menuItem.addActionListener(x -> Reset()); | |||
fileMenu.add(menuItem); | |||
menuItem = new JMenuItem("退出"); | |||
menuItem.addActionListener(x -> System.exit(0)); | |||
fileMenu.add(menuItem); | |||
JMenu otherMenu = new JMenu("其他"); | |||
menuItem = new JMenuItem("关于"); | |||
menuItem.addActionListener(x -> JOptionPane.showMessageDialog(this, "通过Mybatis查询ID自动生成mapper/service/serviceImpl源码", "关于", JOptionPane.INFORMATION_MESSAGE)); | |||
otherMenu.add(menuItem); | |||
menuBar.add(fileMenu); | |||
menuBar.add(otherMenu); | |||
queryId = new InputField("Mybatis查询ID: "); | |||
entity = new InputField("实体类名(短): "); | |||
module = new InputField("模块: "); | |||
packageName = new InputField("包名: "); | |||
parameterType = new InputField("参数类型: "); | |||
returnType = new InputField("返回类型: "); | |||
comment = new InputField("注释: "); | |||
queryId.AddActionListener(inputListener); | |||
entity.AddActionListener(inputListener); | |||
module.AddActionListener(inputListener); | |||
packageName.AddActionListener(inputListener); | |||
comment.AddActionListener(inputListener); | |||
parameterType.AddActionListener(inputListener); | |||
returnType.AddActionListener(inputListener); | |||
queryId.SetToolTipText("例如. selectTHomeapplyYdjfsqList"); | |||
entity.SetToolTipText("例如. THomeapplyYdjfsq"); | |||
module.SetToolTipText("例如. house"); | |||
packageName.SetToolTipText("例如. home(如果和模块名称相同则可为空)"); | |||
comment.SetToolTipText("例如. 查询宅基地申请列表"); | |||
parameterType.SetToolTipText("例如. THomeapplyYdjfsq"); | |||
returnType.SetToolTipText("例如. List<THomeapplyYdjfsq>"); | |||
Box formPanel = Box.createVerticalBox(); | |||
formPanel.setAutoscrolls(true); | |||
formPanel.add(queryId); | |||
formPanel.add(entity); | |||
formPanel.add(module); | |||
formPanel.add(packageName); | |||
formPanel.add(parameterType); | |||
formPanel.add(returnType); | |||
formPanel.add(comment); | |||
result = new JTextPane(); | |||
JScrollPane scrollPane = new JScrollPane(result); | |||
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); | |||
result.setFont(Font.getFont(Font.MONOSPACED)); | |||
formPanel.add(scrollPane); | |||
BorderLayout mainLayout = new BorderLayout(); | |||
JPanel panel = new JPanel(); | |||
panel.setLayout(mainLayout); | |||
panel.add(formPanel, BorderLayout.CENTER); | |||
Box toolbar = Box.createHorizontalBox(); | |||
toolbar.add(Box.createHorizontalGlue()); | |||
writeBtn = new JButton("写入"); | |||
writeBtn.addActionListener(e -> Write()); | |||
writeBtn.setEnabled(false); | |||
toolbar.add(writeBtn); | |||
JButton startBtn = new JButton("生成"); | |||
startBtn.addActionListener(e -> Gen()); | |||
toolbar.add(startBtn); | |||
JButton clearBtn = new JButton("清空"); | |||
clearBtn.addActionListener(e -> Reset()); | |||
toolbar.add(clearBtn); | |||
panel.add(toolbar, BorderLayout.SOUTH); | |||
setContentPane(panel); | |||
} | |||
public String PreviewSourceCode() | |||
{ | |||
engine.ScanFilePath(); | |||
if(!engine.IsValid()) | |||
{ | |||
JOptionPane.showMessageDialog(this, "缺失必要的信息!", "错误", JOptionPane.ERROR_MESSAGE); | |||
return ""; | |||
} | |||
StringBuilder sb = new StringBuilder(); | |||
sb.append(engine.getMapper_java()).append(": \n"); | |||
sb.append(engine.GenMapperCode()).append("\n\n"); | |||
sb.append(engine.getService_java()).append(": \n"); | |||
sb.append(engine.GenServiceCode()).append("\n\n"); | |||
sb.append(engine.getServiceImpl_java()).append(": \n"); | |||
sb.append(engine.GenServiceImplCode()).append("\n\n"); | |||
return sb.toString(); | |||
} | |||
private void Reset() | |||
{ | |||
engine.Reset(); | |||
queryId.Reset(); | |||
entity.Reset(); | |||
module.Reset(); | |||
packageName.Reset(); | |||
comment.Reset(); | |||
parameterType.Reset(); | |||
returnType.Reset(); | |||
result.setText(""); | |||
writeBtn.setEnabled(false); | |||
} | |||
private void Write() | |||
{ | |||
if(engine.Write()) | |||
{ | |||
JOptionPane.showMessageDialog(this, "写入源码文件成功!", "成功", JOptionPane.INFORMATION_MESSAGE); | |||
} | |||
else | |||
{ | |||
JOptionPane.showMessageDialog(this, "写入源码文件失败!", "错误", JOptionPane.ERROR_MESSAGE); | |||
} | |||
} | |||
private void Gen() | |||
{ | |||
engine.setQueryId(queryId.Text()); | |||
engine.setEntity(entity.Text()); | |||
engine.setModule(module.Text()); | |||
engine.setPackageName(packageName.Text()); | |||
engine.setComment(comment.Text()); | |||
engine.SetParameterType(parameterType.Text()); | |||
engine.SetReturnType(returnType.Text()); | |||
String code = PreviewSourceCode(); | |||
result.setText(code); | |||
writeBtn.setEnabled(StrUtil.isNotEmpty(code)); | |||
} | |||
} | |||
@@ -0,0 +1,220 @@ | |||
package com.ruoyi.common.utils.dev.gui; | |||
import com.ruoyi.common.utils.StringUtils; | |||
import javax.swing.*; | |||
import javax.swing.filechooser.FileFilter; | |||
import java.awt.*; | |||
import java.awt.datatransfer.DataFlavor; | |||
import java.awt.dnd.DnDConstants; | |||
import java.awt.dnd.DropTarget; | |||
import java.awt.dnd.DropTargetAdapter; | |||
import java.awt.dnd.DropTargetDropEvent; | |||
import java.io.File; | |||
import java.util.List; | |||
public class FileField extends Box | |||
{ | |||
private String lastPath; | |||
private String path; | |||
private final JTextField textField; | |||
private String filter; | |||
private String name; | |||
private int mode = JFileChooser.FILES_ONLY; | |||
private FileFilter fileFilter = new FileFilter() | |||
{ | |||
@Override | |||
public boolean accept(File f) | |||
{ | |||
if(f.isFile()) | |||
{ | |||
if(StringUtils.isNotEmpty(filter)) | |||
{ | |||
return f.getName().endsWith(filter); | |||
} | |||
} | |||
return true; | |||
} | |||
@Override | |||
public String getDescription() | |||
{ | |||
if(StringUtils.isNotEmpty(filter)) | |||
{ | |||
return "*" + filter; | |||
} | |||
return null; | |||
} | |||
}; | |||
public FileField(String name) | |||
{ | |||
super(BoxLayout.X_AXIS); | |||
this.name = name; | |||
textField = new JTextField(); | |||
lastPath = System.getProperty("user.dir"); | |||
Setup(); | |||
} | |||
private void Setup() | |||
{ | |||
JLabel l = new JLabel(name); | |||
JButton button = new JButton("选择"); | |||
Dimension labelMinimumSize = l.getMinimumSize(); | |||
Dimension compMinimumSize = textField.getMinimumSize(); | |||
Dimension buttonMinimumSize = button.getMinimumSize(); | |||
labelMinimumSize.width = 128; | |||
l.setHorizontalAlignment(SwingConstants.RIGHT); | |||
l.setMinimumSize(labelMinimumSize); | |||
l.setPreferredSize(labelMinimumSize); | |||
l.setMaximumSize(labelMinimumSize); | |||
compMinimumSize.width = 256; | |||
textField.setMinimumSize(compMinimumSize); | |||
Dimension compPreferredSize = textField.getPreferredSize(); | |||
compPreferredSize.width = 256; | |||
textField.setPreferredSize(compPreferredSize); | |||
buttonMinimumSize.width = 64; | |||
button.setHorizontalAlignment(SwingConstants.CENTER); | |||
button.setMinimumSize(buttonMinimumSize); | |||
button.setPreferredSize(buttonMinimumSize); | |||
button.setMaximumSize(buttonMinimumSize); | |||
this.add(l); | |||
this.add(textField); | |||
this.add(button); | |||
this.setMinimumSize(new Dimension(labelMinimumSize.width + compMinimumSize.width, Math.max(labelMinimumSize.height, compMinimumSize.height))); | |||
this.setMaximumSize(new Dimension(Integer.MAX_VALUE, Math.max(labelMinimumSize.height, compMinimumSize.height))); | |||
button.addActionListener((x) -> OpenFileChooser()); | |||
textField.setDragEnabled(true); | |||
new DropTarget(textField, DnDConstants.ACTION_COPY_OR_MOVE, new DropTargetAdapter() | |||
{ | |||
@Override | |||
public void drop(DropTargetDropEvent dt) | |||
{ | |||
try | |||
{ | |||
if(dt.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) | |||
{ | |||
dt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE); | |||
List<File> files = (List<File>)dt.getTransferable().getTransferData(DataFlavor.javaFileListFlavor); | |||
File first = files.get(0); | |||
switch(mode) | |||
{ | |||
case JFileChooser.FILES_ONLY: | |||
if(first.isFile()) | |||
{ | |||
if(fileFilter.accept(first)) | |||
SetPath(first); | |||
return; | |||
} | |||
break; | |||
case JFileChooser.DIRECTORIES_ONLY: | |||
if(!first.isFile()) | |||
{ | |||
SetPath(first); | |||
return; | |||
} | |||
break; | |||
case JFileChooser.FILES_AND_DIRECTORIES: | |||
if(!first.isFile() || fileFilter.accept(first)) | |||
SetPath(first); | |||
return; | |||
} | |||
return; | |||
} | |||
} | |||
catch(Exception e) | |||
{ | |||
e.printStackTrace(); | |||
} | |||
dt.rejectDrop(); | |||
} | |||
}); | |||
} | |||
private void OpenFileChooser() | |||
{ | |||
JFileChooser jFileChooser = new JFileChooser(lastPath); | |||
jFileChooser.setDialogTitle("选择" + name); | |||
jFileChooser.addActionListener((x) -> { | |||
File currentDirectory = jFileChooser.getCurrentDirectory(); | |||
if(null != currentDirectory) | |||
lastPath = currentDirectory.getAbsolutePath(); | |||
if(JFileChooser.APPROVE_SELECTION.equals(x.getActionCommand())) | |||
{ | |||
File selectedFile = jFileChooser.getSelectedFile(); | |||
SetPath(selectedFile); | |||
} | |||
}); | |||
jFileChooser.setFileSelectionMode(mode); | |||
jFileChooser.setFileFilter(fileFilter); | |||
jFileChooser.showOpenDialog(this); | |||
} | |||
public void SetLastPath(String path) | |||
{ | |||
if(StringUtils.isEmpty(path)) | |||
lastPath = System.getProperty("user.dir"); | |||
else | |||
{ | |||
File file = new File(path); | |||
if(file.exists()) | |||
{ | |||
if(!file.isDirectory()) | |||
file = file.getParentFile(); | |||
try | |||
{ | |||
lastPath = file.getCanonicalPath(); | |||
} | |||
catch(Exception e) | |||
{ | |||
e.printStackTrace(); | |||
lastPath = file.getAbsolutePath(); | |||
} | |||
} | |||
else | |||
lastPath = System.getProperty("user.dir"); | |||
} | |||
} | |||
private void SetPath(File selectedFile) | |||
{ | |||
if(null != selectedFile) | |||
{ | |||
path = selectedFile.getAbsolutePath(); | |||
lastPath = selectedFile.getParent(); | |||
} | |||
else | |||
{ | |||
path = null; | |||
} | |||
textField.setText(null != path ? path : ""); | |||
} | |||
public void SetPath(String path) | |||
{ | |||
SetPath(StringUtils.isNotEmpty(path) ? new File(path) : null); | |||
} | |||
public void Reset() | |||
{ | |||
path = null; | |||
textField.setText(""); | |||
} | |||
public String Path() | |||
{ | |||
return textField.getText(); | |||
} | |||
public void SetFilter(String filter) | |||
{ | |||
this.filter = filter; | |||
} | |||
public void SetMode(int mode) | |||
{ | |||
this.mode = mode; | |||
} | |||
} |
@@ -0,0 +1,69 @@ | |||
package com.ruoyi.common.utils.dev.gui; | |||
import javax.swing.*; | |||
import java.awt.*; | |||
import java.awt.dnd.DnDConstants; | |||
import java.awt.dnd.DropTarget; | |||
import java.awt.dnd.DropTargetAdapter; | |||
import java.awt.dnd.DropTargetDropEvent; | |||
import java.awt.event.ActionListener; | |||
public class InputField extends Box | |||
{ | |||
private final JTextField textField; | |||
private final JLabel label; | |||
public InputField(String text) | |||
{ | |||
super(BoxLayout.X_AXIS); | |||
textField = new JTextField(); | |||
label = new JLabel(text); | |||
Setup(); | |||
} | |||
private void Setup() | |||
{ | |||
Dimension labelMinimumSize = label.getMinimumSize(); | |||
Dimension compMinimumSize = textField.getMinimumSize(); | |||
labelMinimumSize.width = 128; | |||
label.setHorizontalAlignment(SwingConstants.RIGHT); | |||
label.setMinimumSize(labelMinimumSize); | |||
label.setPreferredSize(labelMinimumSize); | |||
label.setMaximumSize(labelMinimumSize); | |||
compMinimumSize.width = 256; | |||
textField.setMinimumSize(compMinimumSize); | |||
Dimension compPreferredSize = textField.getPreferredSize(); | |||
compPreferredSize.width = 256; | |||
textField.setPreferredSize(compPreferredSize); | |||
this.add(label); | |||
this.add(textField); | |||
this.setMinimumSize(new Dimension(labelMinimumSize.width + compMinimumSize.width, Math.max(labelMinimumSize.height, compMinimumSize.height))); | |||
this.setMaximumSize(new Dimension(Integer.MAX_VALUE, Math.max(labelMinimumSize.height, compMinimumSize.height))); | |||
} | |||
public void SetToolTipText(String str) | |||
{ | |||
label.setToolTipText(str); | |||
textField.setToolTipText(str); | |||
} | |||
public void AddActionListener(ActionListener l) | |||
{ | |||
textField.addActionListener(l); | |||
} | |||
public void Reset() | |||
{ | |||
textField.setText(""); | |||
} | |||
public String Text() | |||
{ | |||
return textField.getText(); | |||
} | |||
public JTextField TextField() | |||
{ | |||
return textField; | |||
} | |||
} |
@@ -0,0 +1,113 @@ | |||
package com.ruoyi.common.utils.dev.mybatis; | |||
import com.ruoyi.common.utils.dev.Konsole; | |||
import org.apache.ibatis.logging.Log; | |||
import static java.lang.System.out; | |||
import static java.lang.System.err; | |||
public class MybatisStdOutputLog implements Log { | |||
private String mapperStatement; | |||
private boolean disable = false; | |||
private final static boolean ENABLE_OUTPUT = true; | |||
static final int SQL_START_STYLE = Konsole.GenStyle(Konsole.FC_BLACK, Konsole.FS_BOLD, Konsole.BC_YELLOW, Konsole.S_BG_ENABLED); | |||
static final int SQL_STATEMENT_STYLE = Konsole.GenStyle(Konsole.FC_BLUE, Konsole.FS_BOLD); | |||
static final int SQL_PARAMETER_STYLE = Konsole.GenStyle(Konsole.FC_CYAN, Konsole.FS_BOLD); | |||
static final int SQL_RESULT_STYLE = Konsole.GenStyle(Konsole.FC_PURPLE, Konsole.FS_BOLD, Konsole.BC_YELLOW, Konsole.S_BG_ENABLED); | |||
static final int SQL_ROWS_STYLE = Konsole.GenStyle(Konsole.FC_GREEN); | |||
static final int SQL_COLUMNS_STYLE = Konsole.GenStyle(Konsole.FC_YELLOW, Konsole.FS_BOLD); | |||
static final int SQL_STYLE = Konsole.GenStyle(Konsole.FC_RED); | |||
// 不输出的查询 | |||
private static final String[] UnhandleClass = { | |||
"org.activiti.engine.impl.persistence.entity.JobEntityImpl.selectJobsToExecute", | |||
"org.activiti.engine.impl.persistence.entity.TimerJobEntityImpl.selectTimerJobsToExecute", | |||
"org.activiti.engine.impl.persistence.entity.JobEntityImpl.selectExpiredJobs", | |||
}; | |||
public MybatisStdOutputLog(String clazz) { | |||
SetMapperStatement(clazz); | |||
} | |||
private void SetMapperStatement(String clazz) | |||
{ | |||
mapperStatement = clazz; | |||
for(String unhandleClass : UnhandleClass) | |||
{ | |||
if(unhandleClass.equals(mapperStatement)) | |||
disable = true; | |||
} | |||
} | |||
public boolean isDebugEnabled() { | |||
return ENABLE_OUTPUT && !disable; | |||
} | |||
public boolean isTraceEnabled() { | |||
return ENABLE_OUTPUT && !disable; | |||
} | |||
public void error(String s, Throwable e) { | |||
SQLQueue.Exception(mapperStatement, s, e); | |||
} | |||
public void error(String s) { | |||
SQLQueue.Error(mapperStatement, s); | |||
} | |||
public void debug(String s) { | |||
SQLQueue.Debug(mapperStatement, s); | |||
} | |||
public void trace(String s) { | |||
SQLQueue.Trace(mapperStatement, s); | |||
} | |||
public void warn(String s) { | |||
SQLQueue.Warning(mapperStatement, s); | |||
} | |||
static void cout(String str) | |||
{ | |||
out.println(str); | |||
} | |||
static void cerr(String str) | |||
{ | |||
err.println(str); | |||
} | |||
static void clog(String str) | |||
{ | |||
} | |||
static void cout() | |||
{ | |||
out.println(); | |||
} | |||
static void cerr() | |||
{ | |||
err.println(); | |||
} | |||
static void clog() | |||
{ | |||
} | |||
static void cout(String str, int style) | |||
{ | |||
out.println(Konsole.MakeText(str, style)); | |||
} | |||
static void cerr(String str, int style) | |||
{ | |||
err.println(Konsole.MakeText(str, style)); | |||
} | |||
static void clog(String str, int style) | |||
{ | |||
} | |||
} |
@@ -0,0 +1,275 @@ | |||
package com.ruoyi.common.utils.dev.mybatis; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import static java.lang.System.out; | |||
public class SQLQuery | |||
{ | |||
private static class Error | |||
{ | |||
public final String log; | |||
public final Throwable e; | |||
public Error(String log, Throwable e) | |||
{ | |||
this.log = log; | |||
this.e = e; | |||
} | |||
} | |||
private String mapper; | |||
private String sql; | |||
private String parms; | |||
private String columns; | |||
private long result; | |||
private final List<String> warnings; | |||
private final List<String> rows; | |||
private final List<Error> errors; | |||
private long counter; | |||
private long takeTime; | |||
private long readRows; | |||
private long startTime; | |||
private long effect; | |||
private static final int OUTPUT_ROWS = 5; // -1: not limit, 0: disable, positive number: max | |||
private static final Object LOCK = new Object(); | |||
public SQLQuery() | |||
{ | |||
warnings = new ArrayList<>(); | |||
rows = new ArrayList<>(); | |||
errors = new ArrayList<>(); | |||
Clear(); | |||
} | |||
public void Clear() | |||
{ | |||
sql = ""; | |||
parms = ""; | |||
columns = ""; | |||
result = -1; | |||
readRows = 0; | |||
takeTime = 0; | |||
effect = -1; | |||
startTime = System.currentTimeMillis(); | |||
warnings.clear(); | |||
rows.clear(); | |||
errors.clear(); | |||
} | |||
public void Mapper(String mapper) | |||
{ | |||
this.mapper = mapper; | |||
} | |||
public void Debug(String mapper, String log) | |||
{ | |||
Add(mapper, log); | |||
} | |||
public void Trace(String mapper, String log) | |||
{ | |||
Add(mapper, log); | |||
} | |||
public void Warning(String mapper, String log) | |||
{ | |||
warnings.add(log); | |||
Mapper(mapper); | |||
} | |||
public void Error(String mapper, String log) | |||
{ | |||
AddError(log, null); | |||
Mapper(mapper); | |||
} | |||
public void Exception(String mapper, String log, Throwable e) | |||
{ | |||
AddError(log, e); | |||
Mapper(mapper); | |||
} | |||
private void AddError(String log, Throwable e) | |||
{ | |||
errors.add(new Error(log, e)); | |||
} | |||
private void AddOther(String log) | |||
{ | |||
// other.add(log); | |||
} | |||
private void SetResult(String log) | |||
{ | |||
String s = log.substring("<== Total: ".length()); | |||
int index = s.lastIndexOf("<-- ["); | |||
if(index >= 0) | |||
s = s.substring(0, index); | |||
s = s.trim(); | |||
try | |||
{ | |||
result = Long.parseLong(s); | |||
} | |||
catch(Exception e) | |||
{ | |||
e.printStackTrace(); | |||
} | |||
if(result <= 0 || result == readRows) | |||
EndQuery(); | |||
} | |||
private void SetEffect(String log) | |||
{ | |||
String s = log.substring("<== Updates: ".length()); | |||
try | |||
{ | |||
effect = Long.parseLong(s); | |||
} | |||
catch(Exception e) | |||
{ | |||
e.printStackTrace(); | |||
} | |||
EndQuery(); | |||
} | |||
private void EndQuery() | |||
{ | |||
long l = System.currentTimeMillis(); | |||
takeTime = l - startTime; | |||
Output(); | |||
} | |||
private void AddRow(String log) | |||
{ | |||
if(OUTPUT_ROWS < 0 || readRows < OUTPUT_ROWS) | |||
rows.add(log.substring("<== Row: ".length())); | |||
readRows++; | |||
if(readRows == result) | |||
EndQuery(); | |||
} | |||
public void Output() | |||
{ | |||
if(null == sql || sql.isEmpty()) | |||
return; | |||
synchronized(LOCK) { | |||
MybatisStdOutputLog.cout(); | |||
String action = "查询"; | |||
if(effect >= 0) | |||
action = "更新"; | |||
// SQL | |||
MybatisStdOutputLog.cout("[Mybatis " + action + " ] " + Thread.currentThread().getName() + ": " + counter + " -> " + mapper, MybatisStdOutputLog.SQL_START_STYLE); | |||
MybatisStdOutputLog.cout(sql, MybatisStdOutputLog.SQL_STATEMENT_STYLE); | |||
if(null != parms && !parms.isEmpty()) | |||
MybatisStdOutputLog.cout(parms, MybatisStdOutputLog.SQL_PARAMETER_STYLE); | |||
SQLStatement sqlStatement = new SQLStatement(sql, parms); | |||
String parsedSql = sqlStatement.Parse(); | |||
if(null != parsedSql) | |||
MybatisStdOutputLog.cout(/*"编译SQL: \n" + */parsedSql, MybatisStdOutputLog.SQL_STYLE); | |||
// Select query | |||
if(result >= 0) | |||
{ | |||
MybatisStdOutputLog.cout("结果行数: " + result, MybatisStdOutputLog.SQL_RESULT_STYLE); | |||
MybatisStdOutputLog.cout(columns, MybatisStdOutputLog.SQL_COLUMNS_STYLE); | |||
int size = rows.size(); | |||
if(OUTPUT_ROWS != 0 && size > 0) | |||
{ | |||
for(int i = 0; i < size; i++) | |||
{ | |||
MybatisStdOutputLog.cout(String.format("%5d", i) + ": " + rows.get(i), MybatisStdOutputLog.SQL_ROWS_STYLE); | |||
} | |||
long remain = readRows - size; | |||
if(remain > 0) | |||
MybatisStdOutputLog.cout("更多 : " + remain + "条数据......", MybatisStdOutputLog.SQL_ROWS_STYLE); | |||
} | |||
} | |||
// Update | |||
if(effect >= 0) | |||
{ | |||
MybatisStdOutputLog.cout("影响行数: " + effect, MybatisStdOutputLog.SQL_RESULT_STYLE); | |||
} | |||
// Warning | |||
if(!warnings.isEmpty()) | |||
{ | |||
MybatisStdOutputLog.cout("警告: " + warnings.size(), MybatisStdOutputLog.SQL_RESULT_STYLE); | |||
for(int i = 0; i < warnings.size(); i++) | |||
{ | |||
MybatisStdOutputLog.cout(String.format("%2d", i) + ": " + warnings.get(i), MybatisStdOutputLog.SQL_ROWS_STYLE); | |||
} | |||
} | |||
// Error / Exception | |||
if(!errors.isEmpty()) | |||
{ | |||
MybatisStdOutputLog.cout("错误: " + errors.size(), MybatisStdOutputLog.SQL_RESULT_STYLE); | |||
for(int i = 0; i < errors.size(); i++) | |||
{ | |||
Error error = errors.get(i); | |||
MybatisStdOutputLog.cout(String.format("%2d", i) + ": " + error.log, MybatisStdOutputLog.SQL_ROWS_STYLE); | |||
error.e.printStackTrace(out); | |||
} | |||
} | |||
//MybatisStdOutputLog.cout("[Mybatis 结束 ] " + Thread.currentThread().getName() + ": " + counter + " -> Time(" + takeTime + " ms) " + mapper + " ---------------------------------------------------------", MybatisStdOutputLog.SQL_START_STYLE); | |||
MybatisStdOutputLog.cout(""); | |||
} | |||
Clear(); | |||
} | |||
private void Add(String mapper, String log) | |||
{ | |||
if(log.startsWith("==>")) { | |||
if(log.startsWith("==> Preparing: ")) | |||
{ | |||
counter++; | |||
Mapper(mapper); | |||
sql = log.substring("==> Preparing: ".length()); | |||
} | |||
else if(log.startsWith("==> Parameters: ")) | |||
{ | |||
parms = log.substring("==> Parameters: ".length()); | |||
int index = parms.lastIndexOf("<-- ["); | |||
if(index >= 0) | |||
parms = parms.substring(0, index); | |||
parms = parms.trim(); | |||
} | |||
else | |||
{ | |||
AddOther(log); | |||
} | |||
} | |||
else if(log.startsWith("<==")) { | |||
if(log.startsWith("<== Columns: ")) | |||
{ | |||
columns = log.substring("<== Columns: ".length()); | |||
} | |||
else if(log.startsWith("<== Total: ")) | |||
{ | |||
SetResult(log); | |||
} | |||
else if(log.startsWith("<== Row: ")) | |||
{ | |||
AddRow(log); | |||
} | |||
else if(log.startsWith("<== Updates: ")) | |||
{ | |||
SetEffect(log); | |||
} | |||
else | |||
{ | |||
AddOther(log); | |||
} | |||
} | |||
else | |||
{ | |||
AddOther(log); | |||
} | |||
} | |||
} |
@@ -0,0 +1,55 @@ | |||
package com.ruoyi.common.utils.dev.mybatis; | |||
public class SQLQueue | |||
{ | |||
private static final ThreadLocal<SQLQuery> _state = new ThreadLocal<>(); | |||
private static SQLQuery SQLQUERY() | |||
{ | |||
SQLQuery sqlQuery = _state.get(); | |||
if(null == sqlQuery) | |||
{ | |||
sqlQuery = new SQLQuery(); | |||
_state.set(sqlQuery); | |||
} | |||
return sqlQuery; | |||
} | |||
public static void Error(String mapper, String log) | |||
{ | |||
if(log == null || log.isEmpty()) | |||
return; | |||
SQLQUERY().Error(mapper, log); | |||
} | |||
public static void Debug(String mapper, String log) | |||
{ | |||
if(log == null || log.isEmpty()) | |||
return; | |||
SQLQUERY().Debug(mapper, log); | |||
} | |||
public static void Trace(String mapper, String log) | |||
{ | |||
if(log == null || log.isEmpty()) | |||
return; | |||
SQLQUERY().Trace(mapper, log); | |||
} | |||
public static void Warning(String mapper, String log) | |||
{ | |||
if(log == null || log.isEmpty()) | |||
return; | |||
SQLQUERY().Warning(mapper, log); | |||
} | |||
public static void Exception(String mapper, String log, Throwable e) | |||
{ | |||
if(log == null || log.isEmpty()) | |||
return; | |||
if(null != e) | |||
SQLQUERY().Exception(mapper, log, e); | |||
else | |||
SQLQUERY().Error(mapper, log); | |||
} | |||
} |
@@ -0,0 +1,143 @@ | |||
package com.ruoyi.common.utils.dev.mybatis; | |||
import java.math.BigDecimal; | |||
import java.text.NumberFormat; | |||
public class SQLStatement | |||
{ | |||
public final String sql; | |||
public final String arguments; | |||
public SQLStatement(String sql, String arguments) | |||
{ | |||
this.sql = sql; | |||
this.arguments = arguments; | |||
} | |||
public String Parse() | |||
{ | |||
String str; | |||
if(null == arguments || arguments.isEmpty()) | |||
str = sql; | |||
else | |||
{ | |||
String[] args = ParseArguments(); | |||
str = ReplacePlaceholder(args); | |||
} | |||
return Format(str); | |||
} | |||
private String[] ParseArguments() | |||
{ | |||
String[] split = (arguments + ", ").split("\\(\\w+\\), "); | |||
return split; | |||
} | |||
private String ReplacePlaceholder(String[] args) | |||
{ | |||
try | |||
{ | |||
int lastIndex = 0; | |||
int i = 0; | |||
StringBuilder sb = new StringBuilder(); | |||
int length = sql.length(); | |||
while(lastIndex < length) | |||
{ | |||
int index = sql.indexOf('?', lastIndex); | |||
if(i < args.length && index >= 0) | |||
{ | |||
String str = sql.substring(lastIndex, index); | |||
sb.append(str); | |||
sb.append(ToStr(args[i++])); | |||
lastIndex = index + 1; | |||
} | |||
else | |||
{ | |||
String str = sql.substring(lastIndex); | |||
sb.append(str); | |||
lastIndex = length; | |||
} | |||
} | |||
return sb.toString(); | |||
} | |||
catch(Exception e) | |||
{ | |||
e.printStackTrace(); | |||
return null; | |||
} | |||
} | |||
private String ReplacePlaceholder_rev(String[] args) | |||
{ | |||
try | |||
{ | |||
int lastIndex = sql.length() - 1; | |||
int i = args.length - 1; | |||
StringBuilder sb = new StringBuilder(); | |||
while(lastIndex >= 0) | |||
{ | |||
int index = sql.lastIndexOf('?', lastIndex); | |||
if(i >= 0 && index >= 0) | |||
{ | |||
String str = sql.substring(index + 1, lastIndex + 1); | |||
sb.insert(0, str); | |||
sb.insert(0, "'" + args[i--] + "'"); | |||
lastIndex = index - 1; | |||
} | |||
else | |||
{ | |||
String str = sql.substring(0, lastIndex + 1); | |||
sb.insert(0, str); | |||
lastIndex = -1; | |||
} | |||
} | |||
return sb.toString(); | |||
} | |||
catch(Exception e) | |||
{ | |||
e.printStackTrace(); | |||
return null; | |||
} | |||
} | |||
private String Format(String sql) | |||
{ | |||
if(null == sql) | |||
return null; | |||
sql = sql.trim(); | |||
if(!sql.endsWith(";")) | |||
sql = sql + ";"; | |||
return sql; | |||
} | |||
private static String ToStr(String arg) | |||
{ | |||
if(arg == null) | |||
return "null"; | |||
else if(arg.isEmpty()) | |||
return "''"; | |||
else if(IsNum(arg)) | |||
return arg; | |||
else | |||
return "'" + arg + "'"; | |||
} | |||
// 10 | |||
private static boolean IsNum(String str) | |||
{ | |||
if(null == str || str.isEmpty()) | |||
return false; | |||
try | |||
{ | |||
boolean matches = str.matches("^[\\d.-]*$"); | |||
if(!matches) | |||
return false; | |||
Double.parseDouble(str); | |||
return true; | |||
} | |||
catch(Exception e) | |||
{ | |||
return false; | |||
} | |||
} | |||
} |
@@ -0,0 +1,62 @@ | |||
package com.ruoyi.common.utils.translation; | |||
import java.lang.annotation.ElementType; | |||
import java.lang.annotation.Retention; | |||
import java.lang.annotation.RetentionPolicy; | |||
import java.lang.annotation.Target; | |||
/** | |||
* 额外字典翻译字段注解, 用来代替无法使用Excel注解的情况, 优先级大于Excel注解 | |||
* 优先级(5种): | |||
* sql [+ referenceProperty]: 单条SQL语句: 建议加上LIMIT 1, 多条时取第一条, 必须指定占位符?. 例如: @Translate(sql = "SELECT * FROM t_finance_book WHERE id = ? LIMIT 1") | |||
* table + tableKeyColumn + tableValueColumn [+ referenceProperty]: 拼接为 SELECT `tableValueColumn` FROM `table` WHERE `tableKeyColumn` = ? LIMIT 1. 例如: @Translate(table = "t_finance_book", tableValueColumn = "book_name", tableKeyColumn = "id") | |||
* | |||
* dictSql + tableKeyColumn + tableValueColumn: 执行查询SQL后, 取tableKeyColumn(), tableValueColumn()作为字典键值. 例如: @Translate(dictSql = "SELECT * FROM t_finance_book", tableValueColumn = "book_name", tableKeyColumn = "id") | |||
* readConverterExp | |||
* dictType | |||
* | |||
* 前两种方式使用待翻译字段值直查 | |||
* 后三种都是加载对应键值字典, 然后用待翻译字段值匹配. 如果都指定了, 会按优先级混合在一起, 优先级高的覆盖优先级低的 | |||
* | |||
* 关于referenceProperty | |||
* 如果带翻译字段为Long的其他表ID, 如: | |||
* private Long bookId; | |||
* 如果需要翻译bookId | |||
* 一种方法是将bookId设为String类型 | |||
* 还有一种方法是声明String类型的属性辅助翻译bookId, 该新属性不需要原来本身就有bookId的值, 如 | |||
* @Translate(table = "t_finance_book", tableKeyColumn = "id", tableValueColumn = "book_name", referenceProperty = "bookId") // 引用bookId属性的值 | |||
* // @Translate(sql = "SELECT * FROM t_finance_book WHERE id = ? LIMIT 1", referenceProperty = "bookId") // 也可以写成这样 | |||
* private String bookName; // bookName的值不需要读取, 只写入 | |||
* private Long typeId; | |||
* @Translate(dictType = "dict_xxx_type", referenceProperty = "typeId") // 引用typeId属性的值 | |||
* private String typeName; // typeName的值不需要读取, 只写入 | |||
* | |||
* @author zhao | |||
*/ | |||
@Retention(RetentionPolicy.RUNTIME) | |||
@Target(ElementType.FIELD) | |||
public @interface Translate | |||
{ | |||
/** | |||
* 如果是字典类型,请设置字典的type值 (如: sys_user_sex) | |||
*/ | |||
public String dictType() default ""; | |||
/** | |||
* 读取内容转表达式 (如: 0=男,1=女,2=未知) | |||
*/ | |||
public String readConverterExp() default ""; | |||
// 查询数据库字典, 字段必须为String, 不能为Long/Integer等数字型 | |||
// 方式1: SQL, ?号占位 | |||
public String sql() default ""; | |||
// 方式2: 表名 + 对应列名 + 名称列 | |||
// 拼接为 SELECT tableValueColumn() FROM table() WHERE tableKeyColumn() = ? LIMIT 1 | |||
public String table() default ""; // 表名 | |||
public String tableKeyColumn() default "id"; // 键的列名 | |||
public String tableValueColumn() default "name"; // 值的列名 | |||
public String referenceProperty() default ""; // 引用其他类成员属性 | |||
// 方式3: SQL + 对应列名 + 名称列: 无占位符, 从数据库加载键值对 | |||
// 执行查询SQL后, 取tableKeyColumn(), tableValueColumn()作为字典键值 | |||
public String dictSql() default ""; | |||
} |
@@ -0,0 +1,66 @@ | |||
package com.ruoyi.common.utils.translation; | |||
import com.ruoyi.common.core.domain.BaseEntity; | |||
import java.util.List; | |||
import java.util.Map; | |||
/** | |||
* zhao: 字段自动字典翻译 | |||
* 需要翻译的字段必须使用Translate注解或Excel注解标记 | |||
* 优先级: | |||
* 注解: Translate优先级大于Excel. 只会使用Translate或Excel其中的一种, 不会混合 | |||
* 注解属性: readConverterExp优先级大于dictType. readConverterExp和dictType的键值对最终会混合在一起 | |||
* 字段类型: | |||
* 如果是String类型, 必须赋值注解的dictType或readConverterExp | |||
* 如果是其他复合类型/List, 无需赋值dictType或readConverterExp, 仅标记注解即可, 此时将递归翻译(注意不要循环嵌套对象) | |||
* | |||
* 数据库表数据字典: 仅Translate注解支持 | |||
* 字段必须为String类型 | |||
*/ | |||
public final class TranslateUtils | |||
{ | |||
private TranslateUtils() {} | |||
public static void translateList(List<?> list, Object...args) | |||
{ | |||
new Translator().translateList(list, args); | |||
} | |||
public static void translate(Object obj, Object...args) | |||
{ | |||
new Translator().translate(obj, args); | |||
} | |||
public static void translateMapList(List<Map<String, Object>> list, Map<String, String> dictMap) | |||
{ | |||
new Translator().translateMapList(list, dictMap); | |||
} | |||
public static void translateMap(Map<String, Object> map, Map<String, String> dictMap) | |||
{ | |||
new Translator().translateMap(map, dictMap); | |||
} | |||
public static <T> void translateObjectList(List<T> list) | |||
{ | |||
new Translator().translateObjectList(list); | |||
} | |||
public static <T> void translateObject(T object) | |||
{ | |||
new Translator().translateObject(object); | |||
} | |||
public static <T extends BaseEntity> void translateEntityList(List<T> list, boolean...keepRawField) | |||
{ | |||
boolean b = null != keepRawField && keepRawField.length > 0 ? keepRawField[0] : false; | |||
new Translator().translateEntityList(list, b); | |||
} | |||
public static <T extends BaseEntity> void translateEntity(T object, boolean...keepRawField) | |||
{ | |||
boolean b = null != keepRawField && keepRawField.length > 0 ? keepRawField[0] : false; | |||
new Translator().translateEntity(object, b); | |||
} | |||
} |
@@ -0,0 +1,578 @@ | |||
package com.ruoyi.common.utils.translation; | |||
import cn.hutool.core.collection.CollectionUtil; | |||
import cn.hutool.core.util.StrUtil; | |||
import com.ruoyi.common.annotation.Excel; | |||
import com.ruoyi.common.core.domain.BaseEntity; | |||
import com.ruoyi.common.core.domain.entity.SysDictData; | |||
import com.ruoyi.common.utils.DictUtils; | |||
import com.ruoyi.common.utils.StringUtils; | |||
import com.ruoyi.common.utils.reflect.ReflectUtils; | |||
import com.ruoyi.common.utils.spring.SpringUtils; | |||
import org.springframework.jdbc.core.JdbcTemplate; | |||
import java.lang.reflect.Field; | |||
import java.lang.reflect.Modifier; | |||
import java.util.ArrayList; | |||
import java.util.Collection; | |||
import java.util.LinkedHashMap; | |||
import java.util.List; | |||
import java.util.Map; | |||
import java.util.stream.Collectors; | |||
public final class Translator | |||
{ | |||
private static final String KEY_SQL_KEY = "$__SQL__"; | |||
private final List<Object> handledObjects = new ArrayList<>(); | |||
public Translator() {} | |||
public void translateList(List<?> list, Object...args) | |||
{ | |||
if(CollectionUtil.isEmpty(list)) | |||
return; | |||
if(startTranslate(list)) | |||
list.forEach((x) -> translate(x, args)); | |||
} | |||
@SuppressWarnings("unchecked") | |||
public void translate(Object obj, Object...args) | |||
{ | |||
if(null == obj) | |||
return; | |||
if(obj instanceof BaseEntity) | |||
{ | |||
Object o = DEF_PARM(args); | |||
boolean b = o instanceof Boolean ? (Boolean)o : false; | |||
translateEntity((BaseEntity)obj, b); | |||
} | |||
else if(obj instanceof Map) | |||
{ | |||
Object o = DEF_PARM(args); | |||
Map<String, String> dictMap = o instanceof Map ? (Map<String, String>)args[0] : null; | |||
translateMap((Map<String, Object>)obj, dictMap); | |||
} | |||
else if(obj instanceof List) | |||
{ | |||
translateList((List<?>)obj, args); | |||
} | |||
else | |||
{ | |||
translateObject(obj); | |||
} | |||
} | |||
public <T extends BaseEntity> void translateEntityList(List<T> list, boolean keepRawField) | |||
{ | |||
if(CollectionUtil.isEmpty(list)) | |||
return; | |||
list.forEach((x) -> translateEntity(x, keepRawField)); | |||
} | |||
public <T extends BaseEntity> void translateEntity(T object, boolean keepRawField) | |||
{ | |||
if(null == object) | |||
return; | |||
translateEntity_r(object, object.getClass(), keepRawField); | |||
} | |||
public void translateMapList(List<Map<String, Object>> list, Map<String, String> dictMap) | |||
{ | |||
if(CollectionUtil.isEmpty(list)) | |||
return; | |||
list.forEach((x) -> translateMap(x, dictMap)); | |||
} | |||
public void translateMap(Map<String, Object> map, Map<String, String> dictMap) | |||
{ | |||
if(CollectionUtil.isEmpty(map) || CollectionUtil.isEmpty(dictMap)) | |||
return; | |||
if(!startTranslate(map)) | |||
return; | |||
dictMap.forEach((k, v) -> { | |||
if(!map.containsKey(k)) | |||
return; | |||
Object o = map.get(k); | |||
if(null == o) | |||
return; | |||
Class<?> clazz = o.getClass(); | |||
if(clazz.equals(String.class)) | |||
{ | |||
String str = (String)o; | |||
if(StringUtils.isEmpty(str)) | |||
return; | |||
map.put(k, getDictLabelElseOriginValue(v, str)); | |||
} | |||
else if(canRecursionClassObjectField(clazz)) | |||
translate(o, dictMap); | |||
}); | |||
} | |||
// 判断是否翻译对象属性 | |||
private boolean canRecursionClassObjectField(Class<?> clazz) | |||
{ | |||
/* if(Object.class.equals(clazz)) // is Object class | |||
return false; | |||
if(!Object.class.isAssignableFrom(clazz)) // is internal class, e.g. int long boolean | |||
return false; | |||
if(clazz.getPackage().getName().startsWith("java.lang")) // class in java.lang.**, e.g. Long Integer | |||
return false; | |||
return true;*/ | |||
return BaseEntity.class.isAssignableFrom(clazz) // BaseEntity | |||
|| List.class.isAssignableFrom(clazz) // List | |||
|| Map.class.isAssignableFrom(clazz) // Map | |||
; | |||
} | |||
public <T> void translateObjectList(List<T> list) | |||
{ | |||
if(CollectionUtil.isEmpty(list)) | |||
return; | |||
list.forEach(this::translateObject); | |||
} | |||
public <T> void translateObject(T object) | |||
{ | |||
if(null == object) | |||
return; | |||
translateObject_r(object, object.getClass()); | |||
} | |||
private <T> void translateObject_r(T object, Class<?> clazz) | |||
{ | |||
if(!startTranslate(object)) | |||
return; | |||
Field[] declaredFields = clazz.getDeclaredFields(); | |||
for(Field field : declaredFields) | |||
{ | |||
boolean trans = hasTranslateFlag(field); // check translate flag | |||
if(!trans) | |||
continue; | |||
translateField(field, object); | |||
} | |||
Class<?> superclass = getSuperClass(clazz); | |||
if(null != superclass) | |||
translateObject_r(object, superclass); | |||
} | |||
private <T extends BaseEntity> void translateEntity_r(T object, Class<?> clazz, boolean keepRawField) | |||
{ | |||
if(!startTranslate(object)) | |||
return; | |||
Field[] declaredFields = clazz.getDeclaredFields(); | |||
for(Field field : declaredFields) | |||
{ | |||
boolean trans = hasTranslateFlag(field); // check translate flag | |||
if(!trans) | |||
continue; | |||
translateField(field, object, keepRawField); | |||
} | |||
Class<?> superclass = getSuperClass(clazz); | |||
if(null != superclass) | |||
translateEntity_r(object, superclass, keepRawField); | |||
} | |||
// 解析readConverterExp | |||
private Map<String, String> parseReadConverterExp(String str) | |||
{ | |||
Map<String, String> dict = new LinkedHashMap<>(); | |||
if(StringUtils.isNotEmpty(str)) | |||
{ | |||
List<String> split = StrUtil.split(str, ',', true, true); | |||
split.forEach((x) -> { | |||
List<String> arr = StrUtil.split(x, '=', 2, true, true); | |||
if(CollectionUtil.isEmpty(arr)) | |||
return; | |||
dict.put(arr.get(0), arr.size() > 1 ? arr.get(1) : null); | |||
}); | |||
} | |||
return dict; | |||
} | |||
// 读取数据库数据作为字典 | |||
private Map<String, String> loadDBDict(String sql, String keyColumn, String nameColumn) | |||
{ | |||
Map<String, String> dict = new LinkedHashMap<>(); | |||
if(StringUtils.isNotEmpty(sql) && StringUtils.isNotEmpty(keyColumn) && StringUtils.isNotEmpty(nameColumn)) | |||
{ | |||
JdbcTemplate jdbcTemplate = SpringUtils.getBean(JdbcTemplate.class); | |||
try | |||
{ | |||
List<Map<String, Object>> list = jdbcTemplate.queryForList(sql); | |||
if(CollectionUtil.isNotEmpty(list)) | |||
{ | |||
for(Map<String, Object> map : list) | |||
{ | |||
String key = toString_s(map.get(keyColumn)); | |||
if(StringUtils.isEmpty(key)) | |||
continue; | |||
dict.put(key, toString_s(map.get(nameColumn))); | |||
} | |||
} | |||
} | |||
catch(Exception e) | |||
{ | |||
e.printStackTrace(); | |||
} | |||
} | |||
return dict; | |||
} | |||
// 生成查询SQL | |||
private String genRelationSQL(String table, String keyColumn, String nameColumn) | |||
{ | |||
if(StringUtils.isNotEmpty(table) && StringUtils.isNotEmpty(keyColumn) && StringUtils.isNotEmpty(nameColumn)) | |||
{ | |||
return String.format("SELECT `%s` FROM `%s` WHERE `%s` = ? LIMIT 1", nameColumn, table, keyColumn); | |||
} | |||
return null; | |||
} | |||
// 直接取SQL值 | |||
private String readDBValue(String sql, String id) | |||
{ | |||
if(StringUtils.isNotEmpty(sql) && StringUtils.isNotEmpty(id)) | |||
{ | |||
JdbcTemplate jdbcTemplate = SpringUtils.getBean(JdbcTemplate.class); | |||
try | |||
{ | |||
List<Map<String, Object>> list = jdbcTemplate.queryForList(sql, id); | |||
if(CollectionUtil.isNotEmpty(list)) | |||
{ | |||
Map<String, Object> map = list.get(0); | |||
return toString_s(map.get(map.keySet().iterator().next())); | |||
} | |||
} | |||
catch(Exception e) | |||
{ | |||
e.printStackTrace(); | |||
} | |||
} | |||
return null; | |||
} | |||
// 检查是否需要翻译 | |||
private boolean hasTranslateFlag(Field field) | |||
{ | |||
// 静态/不可重赋值 不翻译 | |||
int modifiers = field.getModifiers(); | |||
if(Modifier.isStatic(modifiers) || Modifier.isFinal(modifiers)) | |||
return false; | |||
return null != field.getAnnotation(Translate.class) || null != field.getAnnotation(Excel.class); | |||
} | |||
// 获取翻译来源 | |||
// 返回: dictType对应的字典键值对和readConverterExp解析后的键值对的组合 | |||
// 优先级: Translate > Excel | readConverterExp > dictType | |||
private Map<String, String> getTranslateDict(Field field) | |||
{ | |||
Map<String, String> dict = new LinkedHashMap<>(); | |||
String str; | |||
Translate translate = field.getAnnotation(Translate.class); // First check Translate annotation | |||
if(null != translate) | |||
{ | |||
// 1. SQL 直查 | |||
str = translate.sql(); | |||
if(StringUtils.isNotEmpty(str)) | |||
{ | |||
dict.put(KEY_SQL_KEY, str); | |||
} | |||
// 2. table + tableKeyColumn + tableValueColumn 直查 | |||
str = translate.table(); | |||
if(StringUtils.isNotEmpty(str)) | |||
{ | |||
str = genRelationSQL(str, translate.tableKeyColumn(), translate.tableValueColumn()); | |||
dict.put(KEY_SQL_KEY, str); | |||
} | |||
// 3. dict缓存 | |||
str = translate.dictType(); | |||
if(StringUtils.isNotEmpty(str)) | |||
{ | |||
dict.putAll(dictCacheValueLabelMap(str)); | |||
} | |||
// 4. readConverterExp配置 | |||
str = translate.readConverterExp(); | |||
if(StringUtils.isNotEmpty(str)) | |||
{ | |||
dict.putAll(parseReadConverterExp(str)); | |||
} | |||
// 5. 数据库任意表数据 | |||
str = translate.dictSql(); | |||
if(StringUtils.isNotEmpty(str)) | |||
{ | |||
dict.putAll(loadDBDict(str, translate.tableKeyColumn(), translate.tableValueColumn())); | |||
} | |||
} | |||
if(StringUtils.isNotEmpty(dict)) | |||
return dict; | |||
Excel excel = field.getAnnotation(Excel.class); // And then check Excel annotation | |||
if(null != excel) | |||
{ | |||
str = excel.dictType(); | |||
if(StringUtils.isNotEmpty(str)) | |||
{ | |||
dict.putAll(dictCacheValueLabelMap(str)); | |||
} | |||
str = excel.readConverterExp(); | |||
if(StringUtils.isNotEmpty(str)) | |||
{ | |||
dict.putAll(parseReadConverterExp(str)); | |||
} | |||
} | |||
return dict; | |||
} | |||
private boolean translateField(Field field, Object object) | |||
{ | |||
if(field.getType().equals(String.class)) | |||
return translateField_String(field, object); | |||
else | |||
return translateField_Object(field, object); | |||
} | |||
private boolean translateField_Object(Field field, Object object) | |||
{ | |||
if(field.getType().equals(String.class)) | |||
return false; | |||
if(!canRecursionClassObjectField(field.getType())) | |||
return false; | |||
Object val = null; | |||
if(!field.isAccessible()) | |||
field.setAccessible(true); | |||
try | |||
{ | |||
val = field.get(object); | |||
} | |||
catch(IllegalAccessException e) | |||
{ | |||
e.printStackTrace(); | |||
} | |||
if(null != val) | |||
{ | |||
translate(val); | |||
return true; | |||
} | |||
return false; | |||
} | |||
private boolean translateField_String(Field field, Object object) | |||
{ | |||
boolean trans = false; | |||
if(!field.getType().equals(String.class)) | |||
return false; | |||
Map<String, String> dict = getTranslateDict(field); | |||
if(CollectionUtil.isEmpty(dict)) | |||
return false; | |||
if(!field.isAccessible()) | |||
field.setAccessible(true); | |||
try | |||
{ | |||
Object val = getField(object, field); | |||
if(null != val) | |||
{ | |||
String str = (String)val; | |||
if(StringUtils.isNotEmpty(str)) | |||
{ | |||
if(dict.containsKey(KEY_SQL_KEY)) | |||
{ | |||
String dbVal = readDBValue(dict.get(KEY_SQL_KEY), str); | |||
if(StringUtils.isNotEmpty(dbVal)) | |||
{ | |||
field.set(object, dbVal); | |||
trans = true; | |||
} | |||
} | |||
if(!trans && dict.containsKey(str)) | |||
{ | |||
field.set(object, dict.get(str)); | |||
trans = true; | |||
} | |||
} | |||
} | |||
} | |||
catch(IllegalAccessException e) | |||
{ | |||
e.printStackTrace(); | |||
return false; | |||
} | |||
return trans; | |||
} | |||
private <T extends BaseEntity> boolean translateField(Field field, T entity, boolean keepRawField) | |||
{ | |||
if(field.getType().equals(String.class)) | |||
return translateField_String(field, entity, keepRawField); | |||
else | |||
return translateField_Object(field, entity, keepRawField); | |||
} | |||
private <T extends BaseEntity> boolean translateField_Object(Field field, T entity, boolean keepRawField) | |||
{ | |||
if(field.getType().equals(String.class)) | |||
return false; | |||
if(!canRecursionClassObjectField(field.getType())) | |||
return false; | |||
Object val = null; | |||
try | |||
{ | |||
val = getField(entity, field); | |||
} | |||
catch(IllegalAccessException e) | |||
{ | |||
e.printStackTrace(); | |||
} | |||
if(null != val) | |||
{ | |||
translate(val, keepRawField); | |||
return true; | |||
} | |||
return false; | |||
} | |||
private <T extends BaseEntity> boolean translateField_String(Field field, T entity, boolean keepRawField) | |||
{ | |||
boolean trans = false; | |||
if(!field.getType().equals(String.class)) | |||
return false; | |||
Map<String, String> dict = getTranslateDict(field); | |||
if(CollectionUtil.isEmpty(dict)) | |||
return false; | |||
try | |||
{ | |||
Object val = getField(entity, field); | |||
if(keepRawField) | |||
entity.getParams().put(field.getName(), val); // backup raw value to params | |||
if(null != val) | |||
{ | |||
String str = (String)val; | |||
if(StringUtils.isNotEmpty(str)) | |||
{ | |||
if(dict.containsKey(KEY_SQL_KEY)) | |||
{ | |||
String dbVal = readDBValue(dict.get(KEY_SQL_KEY), str); | |||
if(StringUtils.isNotEmpty(dbVal)) | |||
{ | |||
field.set(entity, dbVal); | |||
trans = true; | |||
} | |||
} | |||
if(!trans && dict.containsKey(str)) | |||
{ | |||
field.set(entity, dict.get(str)); | |||
trans = true; | |||
} | |||
} | |||
} | |||
} | |||
catch(IllegalAccessException e) | |||
{ | |||
e.printStackTrace(); | |||
return false; | |||
} | |||
return trans; | |||
} | |||
private Object getField(Object obj, Field field) throws IllegalAccessException | |||
{ | |||
if(!field.isAccessible()) | |||
field.setAccessible(true); | |||
Translate annotation = field.getAnnotation(Translate.class); | |||
if(null != annotation) | |||
{ | |||
String refProp = annotation.referenceProperty(); | |||
if(StringUtils.isNotEmpty(refProp)) | |||
{ | |||
Field refField = ReflectUtils.getAccessibleField(obj, refProp); | |||
if(null != refField) | |||
return toString_s(refField.get(obj)); // 转换为String | |||
} | |||
} | |||
return field.get(obj); | |||
} | |||
private Class<?> getSuperClass(Class<?> clazz) | |||
{ | |||
if(null == clazz) | |||
return null; | |||
Class<?> superclass = clazz.getSuperclass(); // translate parent class | |||
if(null != superclass && !superclass.equals(Object.class)) // check is top or is Object | |||
return superclass; | |||
return null; | |||
} | |||
// 允许翻译则返回true | |||
private boolean startTranslate(Object o) | |||
{ | |||
if(null == o) | |||
return false; | |||
if(o instanceof String) // String类型总是重新翻译 | |||
return true; | |||
if(contains_ptr(handledObjects, o)) // 其他类型防止循环递归 | |||
{ | |||
return false; | |||
} | |||
handledObjects.add(o); | |||
return true; | |||
} | |||
public void Reset() | |||
{ | |||
handledObjects.clear(); | |||
} | |||
public static <T> boolean contains_ptr(Collection<T> list, T target) | |||
{ | |||
if(CollectionUtil.isEmpty(list)) | |||
return false; | |||
return list.stream().anyMatch((x) -> x == target); | |||
} | |||
public static String toString_s(Object obj) | |||
{ | |||
if(null == obj) | |||
return ""; | |||
if(obj instanceof String) | |||
return (String)obj; | |||
else | |||
return obj.toString(); | |||
} | |||
public static <T> T DEF_PARM(T...args) | |||
{ | |||
return null != args && args.length > 0 ? args[0] : null; | |||
} | |||
public static Map<String, String> dictCacheValueLabelMap(String key) | |||
{ | |||
List<SysDictData> dictCache = DictUtils.getDictCache(key); | |||
if(CollectionUtil.isEmpty(dictCache)) | |||
return new LinkedHashMap<>(); // safety | |||
return dictCache.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel, (a, b) -> a, LinkedHashMap::new)); | |||
} | |||
public static String getDictLabelElseOriginValue(String dictType, String dictValue) | |||
{ | |||
if(StringUtils.isEmpty(dictValue)) | |||
return dictValue; | |||
String res = DictUtils.getDictLabel(dictType, dictValue); | |||
return StringUtils.isEmpty(res) ? dictValue : res; | |||
} | |||
} |
@@ -16,6 +16,8 @@ import com.ruoyi.common.annotation.Log; | |||
import com.ruoyi.common.core.controller.BaseController; | |||
import com.ruoyi.common.core.domain.AjaxResult; | |||
import com.ruoyi.common.enums.BusinessType; | |||
import io.swagger.annotations.Api; | |||
import io.swagger.annotations.ApiOperation; | |||
import ${packageName}.domain.${ClassName}; | |||
import ${packageName}.service.I${ClassName}Service; | |||
import com.ruoyi.common.utils.poi.ExcelUtil; | |||
@@ -30,6 +32,7 @@ import com.ruoyi.common.core.page.TableDataInfo; | |||
* @author ${author} | |||
* @date ${datetime} | |||
*/ | |||
@Api(tags = "${functionName}") | |||
@RestController | |||
@RequestMapping("/${moduleName}/${businessName}") | |||
public class ${ClassName}Controller extends BaseController | |||
@@ -40,6 +43,7 @@ public class ${ClassName}Controller extends BaseController | |||
/** | |||
* 查询${functionName}列表 | |||
*/ | |||
@ApiOperation("查询${functionName}列表") | |||
@PreAuthorize("@ss.hasPermi('${permissionPrefix}:list')") | |||
@GetMapping("/list") | |||
#if($table.crud || $table.sub) | |||
@@ -60,6 +64,7 @@ public class ${ClassName}Controller extends BaseController | |||
/** | |||
* 导出${functionName}列表 | |||
*/ | |||
@ApiOperation("导出${functionName}列表") | |||
@PreAuthorize("@ss.hasPermi('${permissionPrefix}:export')") | |||
@Log(title = "${functionName}", businessType = BusinessType.EXPORT) | |||
@PostMapping("/export") | |||
@@ -73,6 +78,7 @@ public class ${ClassName}Controller extends BaseController | |||
/** | |||
* 获取${functionName}详细信息 | |||
*/ | |||
@ApiOperation("获取${functionName}详细信息") | |||
@PreAuthorize("@ss.hasPermi('${permissionPrefix}:query')") | |||
@GetMapping(value = "/get/{${pkColumn.javaField}}") | |||
public AjaxResult getInfo(@PathVariable("${pkColumn.javaField}") ${pkColumn.javaType} ${pkColumn.javaField}) | |||
@@ -83,9 +89,10 @@ public class ${ClassName}Controller extends BaseController | |||
/** | |||
* 新增${functionName} | |||
*/ | |||
@ApiOperation("新增${functionName}") | |||
@PreAuthorize("@ss.hasPermi('${permissionPrefix}:add')") | |||
@Log(title = "${functionName}", businessType = BusinessType.INSERT) | |||
@PostMapping(value = "/add") | |||
@PostMapping("/add") | |||
public AjaxResult add(@RequestBody ${ClassName} ${className}) | |||
{ | |||
${className}.setCreateBy(getUsername()); | |||
@@ -95,9 +102,10 @@ public class ${ClassName}Controller extends BaseController | |||
/** | |||
* 修改${functionName} | |||
*/ | |||
@ApiOperation("修改${functionName}") | |||
@PreAuthorize("@ss.hasPermi('${permissionPrefix}:edit')") | |||
@Log(title = "${functionName}", businessType = BusinessType.UPDATE) | |||
@PutMapping(value = "/edit") | |||
@PostMapping("/edit") | |||
public AjaxResult edit(@RequestBody ${ClassName} ${className}) | |||
{ | |||
${className}.setUpdateBy(getUsername()); | |||
@@ -107,11 +115,12 @@ public class ${ClassName}Controller extends BaseController | |||
/** | |||
* 删除${functionName} | |||
*/ | |||
@ApiOperation("删除${functionName}") | |||
@PreAuthorize("@ss.hasPermi('${permissionPrefix}:remove')") | |||
@Log(title = "${functionName}", businessType = BusinessType.DELETE) | |||
@DeleteMapping(value = "/remove/{${pkColumn.javaField}}") | |||
public AjaxResult remove(@PathVariable ${pkColumn.javaType} ${pkColumn.javaField}) | |||
@PostMapping("/remove/{${pkColumn.javaField}s}") | |||
public AjaxResult remove(@PathVariable ${pkColumn.javaType}[] ${pkColumn.javaField}s) | |||
{ | |||
return toAjax(${className}Service.delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaField})); | |||
return toAjax(${className}Service.delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaField}s)); | |||
} | |||
} |
@@ -3,8 +3,6 @@ package ${packageName}.domain; | |||
#foreach ($import in $importList) | |||
import ${import}; | |||
#end | |||
import lombok.Data; | |||
import lombok.experimental.Accessors; | |||
import org.apache.commons.lang3.builder.ToStringBuilder; | |||
import org.apache.commons.lang3.builder.ToStringStyle; | |||
import com.ruoyi.common.annotation.Excel; | |||
@@ -25,8 +23,6 @@ import com.ruoyi.common.core.domain.TreeEntity; | |||
#elseif($table.tree) | |||
#set($Entity="TreeEntity") | |||
#end | |||
@Data | |||
@Accessors(chain = true) | |||
public class ${ClassName} extends ${Entity} | |||
{ | |||
private static final long serialVersionUID = 1L; | |||
@@ -59,6 +55,24 @@ public class ${ClassName} extends ${Entity} | |||
private List<${subClassName}> ${subclassName}List; | |||
#end | |||
#foreach ($column in $columns) | |||
#if(!$table.isSuperColumn($column.javaField)) | |||
#if($column.javaField.length() > 2 && $column.javaField.substring(1,2).matches("[A-Z]")) | |||
#set($AttrName=$column.javaField) | |||
#else | |||
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) | |||
#end | |||
public void set${AttrName}($column.javaType $column.javaField) | |||
{ | |||
this.$column.javaField = $column.javaField; | |||
} | |||
public $column.javaType get${AttrName}() | |||
{ | |||
return $column.javaField; | |||
} | |||
#end | |||
#end | |||
#if($table.sub) | |||
public List<${subClassName}> get${subClassName}List() | |||
@@ -72,4 +86,20 @@ public class ${ClassName} extends ${Entity} | |||
} | |||
#end | |||
@Override | |||
public String toString() { | |||
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) | |||
#foreach ($column in $columns) | |||
#if($column.javaField.length() > 2 && $column.javaField.substring(1,2).matches("[A-Z]")) | |||
#set($AttrName=$column.javaField) | |||
#else | |||
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) | |||
#end | |||
.append("${column.javaField}", get${AttrName}()) | |||
#end | |||
#if($table.sub) | |||
.append("${subclassName}List", get${subClassName}List()) | |||
#end | |||
.toString(); | |||
} | |||
} |
@@ -46,14 +46,6 @@ public interface ${ClassName}Mapper | |||
*/ | |||
public int insert${ClassName}Batch(List<${ClassName}> list); | |||
/** | |||
* 批量修改 ${functionName} | |||
* | |||
* @param list ${functionName} | |||
* @return 结果 | |||
*/ | |||
public int update${ClassName}Batch(List<${ClassName}> list); | |||
/** | |||
* 修改${functionName} | |||
* | |||
@@ -62,6 +54,14 @@ public interface ${ClassName}Mapper | |||
*/ | |||
public int update${ClassName}(${ClassName} ${className}); | |||
/** | |||
* 批量修改 ${functionName} | |||
* | |||
* @param list ${functionName} | |||
* @return 结果 | |||
*/ | |||
public int update${ClassName}Batch(List<${ClassName}> list); | |||
/** | |||
* 删除${functionName} | |||
* | |||
@@ -105,7 +105,6 @@ public interface ${ClassName}Mapper | |||
public int delete${subClassName}By${subTableFkClassName}(${pkColumn.javaType} ${pkColumn.javaField}); | |||
#end | |||
// Harm | |||
/** | |||
* 条件单条查询${functionName} | |||
* | |||
@@ -74,8 +74,7 @@ public interface I${ClassName}Service | |||
* @return 结果 | |||
*/ | |||
public int delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}); | |||
// Harm | |||
/** | |||
* 条件单条查询${functionName} | |||
* | |||
@@ -9,8 +9,6 @@ import com.ruoyi.common.utils.DateUtils; | |||
#end | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import org.springframework.stereotype.Service; | |||
import org.springframework.transaction.annotation.Transactional; | |||
import org.apache.commons.collections4.ListUtils; | |||
#if($table.sub) | |||
import java.util.ArrayList; | |||
import com.ruoyi.common.utils.StringUtils; | |||
@@ -19,6 +17,8 @@ import ${packageName}.domain.${subClassName}; | |||
import ${packageName}.mapper.${ClassName}Mapper; | |||
import ${packageName}.domain.${ClassName}; | |||
import ${packageName}.service.I${ClassName}Service; | |||
import org.springframework.transaction.annotation.Transactional; | |||
import org.apache.commons.collections4.ListUtils; | |||
/** | |||
* ${functionName}Service业务层处理 | |||
@@ -93,7 +93,7 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service | |||
public int insert${ClassName}Batch(List<${ClassName}> list){ | |||
List<List<${ClassName}>> splists = ListUtils.partition(list, 50); | |||
splists.forEach(splist->{ | |||
${className}Mapper.insert${ClassName}Batch(splist); | |||
${className}Mapper.insert${ClassName}Batch(splist); | |||
}); | |||
return 1; | |||
} | |||
@@ -133,7 +133,7 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service | |||
public int update${ClassName}Batch(List<${ClassName}> list) { | |||
List<List<${ClassName}>> splists = ListUtils.partition(list, 50); | |||
splists.forEach(splist->{ | |||
${className}Mapper.update${ClassName}Batch(splist); | |||
${className}Mapper.update${ClassName}Batch(splist); | |||
}); | |||
return 1; | |||
} | |||
@@ -200,7 +200,6 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service | |||
} | |||
#end | |||
// Harm | |||
/** | |||
* 单条条件查询${functionName} | |||
* | |||
@@ -1,13 +1,5 @@ | |||
import request from '@/utils/request' | |||
/* ${functionName} JSON | |||
{ | |||
#foreach ($column in $columns) | |||
"${column.javaField}": "${column.columnComment}"#if($velocityCount != $columns.size()),#end // ${column.javaType} | |||
#end | |||
} | |||
*/ | |||
// 查询${functionName}列表 | |||
export function list${BusinessName}(query) { | |||
return request({ | |||
@@ -20,7 +12,7 @@ export function list${BusinessName}(query) { | |||
// 查询${functionName}详细 | |||
export function get${BusinessName}(${pkColumn.javaField}) { | |||
return request({ | |||
url: '/${moduleName}/${businessName}/' + ${pkColumn.javaField}, | |||
url: '/${moduleName}/${businessName}/get/' + ${pkColumn.javaField}, | |||
method: 'get' | |||
}) | |||
} | |||
@@ -28,7 +20,7 @@ export function get${BusinessName}(${pkColumn.javaField}) { | |||
// 新增${functionName} | |||
export function add${BusinessName}(data) { | |||
return request({ | |||
url: '/${moduleName}/${businessName}', | |||
url: '/${moduleName}/${businessName}/add', | |||
method: 'post', | |||
data: data | |||
}) | |||
@@ -37,8 +29,8 @@ export function add${BusinessName}(data) { | |||
// 修改${functionName} | |||
export function update${BusinessName}(data) { | |||
return request({ | |||
url: '/${moduleName}/${businessName}', | |||
method: 'put', | |||
url: '/${moduleName}/${businessName}/edit', | |||
method: 'post', | |||
data: data | |||
}) | |||
} | |||
@@ -46,7 +38,7 @@ export function update${BusinessName}(data) { | |||
// 删除${functionName} | |||
export function del${BusinessName}(${pkColumn.javaField}) { | |||
return request({ | |||
url: '/${moduleName}/${businessName}/' + ${pkColumn.javaField}, | |||
method: 'delete' | |||
url: '/${moduleName}/${businessName}/remove/' + ${pkColumn.javaField}, | |||
method: 'post' | |||
}) | |||
} |
@@ -453,7 +453,7 @@ export default { | |||
this.reset(); | |||
this.getTreeselect(); | |||
if (row != null) { | |||
this.form.${treeParentCode} = row.${treeCode}; | |||
this.form.${treeParentCode} = row.${treeParentCode}; | |||
} | |||
get${BusinessName}(row.${pkColumn.javaField}).then(response => { | |||
this.form = response.data; | |||
@@ -1,3 +1,39 @@ | |||
#macro(GET_CHAR_COLUMN_LENGTH $column)## * 如果表列是char/varchar, 获取其最大字符长度, 否则为空字符串 * 参数: 列 * 结果保存在变量名为 $_char_column_length 字符串型 | |||
#set($_char_column_length="") | |||
#if($column.columnType.startsWith("char") || $column.columnType.startsWith("varchar")) | |||
#set($startLeft=$column.columnType.indexOf("(")) | |||
#if($startLeft != -1) | |||
#set($endRight=$column.columnType.indexOf(")", $startLeft)) | |||
#if($endRight != -1) | |||
#set($startLeft=$startLeft+1) | |||
#set($_char_column_length=$column.columnType.substring($startLeft, $endRight)) | |||
#end | |||
#end | |||
#end | |||
#end## GET_CHAR_COLUMN_LENGTH | |||
#macro(COLUMN_IS_NUMBER $column)## * 检查表列是否是数字型 * 参数: 列 * 结果保存在变量名为 $_column_is_number bool型 | |||
#set($_column_is_number=$column.columnType.startsWith("decimal") || $column.columnType.startsWith("tinyint") || $column.columnType.startsWith("mediumint") || $column.columnType.startsWith("int") || $column.columnType.startsWith("bigint") || $column.columnType.startsWith("smallint")) | |||
#end## COLUMN_IS_NUMBER | |||
#macro(GET_NUMBER_COLUMN_MIN_AND_PRECISION $column)## * 如果表列是数字型, 获取其最小值和浮点数部分精度, 否则为空字符串 * 参数: 列 * 最小值结果保存在变量名为 $_number_column_min 字符串型 * 浮点数部分精度结果保存在变量名为 $_number_column_precision 字符串型 | |||
#set($_number_column_min="") | |||
#set($_number_column_precision="") | |||
#if($column.columnType.contains("unsigned")) | |||
#set($_number_column_min="0") | |||
#end | |||
#set($startLeft=$column.columnType.indexOf("(")) | |||
#if($startLeft != -1) | |||
#set($endRight=$column.columnType.indexOf(")", $startLeft)) | |||
#if($endRight != -1) | |||
#set($startLeft=$startLeft+1) | |||
#set($internalText=$column.columnType.substring($startLeft, $endRight)) | |||
#set($splitIndex=$internalText.indexOf(",")) | |||
#if($splitIndex != -1) | |||
#set($splitIndex=$splitIndex+1) | |||
#set($_number_column_precision=$internalText.substring($splitIndex)) | |||
#end | |||
#end | |||
#end | |||
#end## GET_NUMBER_COLUMN_MIN_AND_PRECISION | |||
<template> | |||
<div class="app-container"> | |||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px"> | |||
@@ -13,22 +49,12 @@ | |||
#end | |||
#if($column.htmlType == "input") | |||
<el-form-item label="${comment}" prop="${column.javaField}"> | |||
<el-input | |||
v-model="queryParams.${column.javaField}" | |||
placeholder="请输入${comment}" | |||
clearable | |||
@keyup.enter.native="handleQuery" | |||
/> | |||
<el-input v-model="queryParams.${column.javaField}" placeholder="请输入${comment}" clearable @keyup.enter.native="handleQuery"/> | |||
</el-form-item> | |||
#elseif(($column.htmlType == "select" || $column.htmlType == "radio") && "" != $dictType) | |||
<el-form-item label="${comment}" prop="${column.javaField}"> | |||
<el-select v-model="queryParams.${column.javaField}" placeholder="请选择${comment}" clearable> | |||
<el-option | |||
v-for="dict in dict.type.${dictType}" | |||
:key="dict.value" | |||
:label="dict.label" | |||
:value="dict.value" | |||
/> | |||
<el-option v-for="dict in dict.type.${dictType}" :key="dict.value" :label="dict.label" :value="dict.value"/> | |||
</el-select> | |||
</el-form-item> | |||
#elseif(($column.htmlType == "select" || $column.htmlType == "radio") && $dictType) | |||
@@ -39,24 +65,11 @@ | |||
</el-form-item> | |||
#elseif($column.htmlType == "datetime" && $column.queryType != "BETWEEN") | |||
<el-form-item label="${comment}" prop="${column.javaField}"> | |||
<el-date-picker clearable | |||
v-model="queryParams.${column.javaField}" | |||
type="date" | |||
value-format="yyyy-MM-dd" | |||
placeholder="请选择${comment}"> | |||
</el-date-picker> | |||
<el-date-picker clearable v-model="queryParams.${column.javaField}" type="date" value-format="yyyy-MM-dd" placeholder="请选择${comment}"/> | |||
</el-form-item> | |||
#elseif($column.htmlType == "datetime" && $column.queryType == "BETWEEN") | |||
<el-form-item label="${comment}"> | |||
<el-date-picker | |||
v-model="daterange${AttrName}" | |||
style="width: 240px" | |||
value-format="yyyy-MM-dd" | |||
type="daterange" | |||
range-separator="-" | |||
start-placeholder="开始日期" | |||
end-placeholder="结束日期" | |||
></el-date-picker> | |||
<el-date-picker v-model="daterange${AttrName}" style="width: 240px" value-format="yyyy-MM-dd" type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"/> | |||
</el-form-item> | |||
#end | |||
#end | |||
@@ -69,52 +82,25 @@ | |||
<el-row :gutter="10" class="mb8"> | |||
<el-col :span="1.5"> | |||
<el-button | |||
type="primary" | |||
plain | |||
icon="el-icon-plus" | |||
size="mini" | |||
@click="handleAdd" | |||
v-hasPermi="['${moduleName}:${businessName}:add']" | |||
>新增</el-button> | |||
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd" v-hasPermi="['${moduleName}:${businessName}:add']">新增</el-button> | |||
</el-col> | |||
<!-- | |||
<el-col :span="1.5"> | |||
<el-button | |||
type="success" | |||
plain | |||
icon="el-icon-edit" | |||
size="mini" | |||
:disabled="single" | |||
@click="handleUpdate" | |||
v-hasPermi="['${moduleName}:${businessName}:edit']" | |||
>修改</el-button> | |||
<el-button type="success" plain icon="el-icon-edit" size="mini" :disabled="single" @click="handleUpdate" v-hasPermi="['${moduleName}:${businessName}:edit']">修改</el-button> | |||
</el-col> | |||
<el-col :span="1.5"> | |||
<el-button | |||
type="danger" | |||
plain | |||
icon="el-icon-delete" | |||
size="mini" | |||
:disabled="multiple" | |||
@click="handleDelete" | |||
v-hasPermi="['${moduleName}:${businessName}:remove']" | |||
>删除</el-button> | |||
<el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple" @click="handleDelete" v-hasPermi="['${moduleName}:${businessName}:remove']">删除</el-button> | |||
</el-col> | |||
--> | |||
<el-col :span="1.5"> | |||
<el-button | |||
type="warning" | |||
plain | |||
icon="el-icon-download" | |||
size="mini" | |||
@click="handleExport" | |||
v-hasPermi="['${moduleName}:${businessName}:export']" | |||
>导出</el-button> | |||
<el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport" v-hasPermi="['${moduleName}:${businessName}:export']" :loading="exportLoading">导出</el-button> | |||
</el-col> | |||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> | |||
</el-row> | |||
<el-table v-loading="loading" :data="${businessName}List" @selection-change="handleSelectionChange"> | |||
<el-table-column type="selection" width="55" align="center" /> | |||
<!--<el-table-column type="selection" width="55" align="center" />--> | |||
<el-table-column type="index" label="序号" width="50" align="center" /> | |||
#foreach($column in $columns) | |||
#set($javaField=$column.javaField) | |||
#set($parentheseIndex=$column.columnComment.indexOf("(")) | |||
@@ -124,13 +110,18 @@ | |||
#set($comment=$column.columnComment) | |||
#end | |||
#if($column.pk) | |||
<el-table-column label="${comment}" align="center" prop="${javaField}" /> | |||
<!--<el-table-column label="${comment}" align="center" prop="${javaField}" min-width="60" />--> | |||
#elseif($column.list && $column.htmlType == "datetime") | |||
#GET_CHAR_COLUMN_LENGTH($column) | |||
#if($_char_column_length == "4" || $_char_column_length == "6" || $_char_column_length == "7") | |||
<el-table-column label="${comment}" align="center" prop="${javaField}" /> | |||
#else | |||
<el-table-column label="${comment}" align="center" prop="${javaField}" width="180"> | |||
<template slot-scope="scope"> | |||
<span>{{ parseTime(scope.row.${javaField}, '{y}-{m}-{d}') }}</span> | |||
</template> | |||
</el-table-column> | |||
#end | |||
#elseif($column.list && $column.htmlType == "imageUpload") | |||
<el-table-column label="${comment}" align="center" prop="${javaField}" width="100"> | |||
<template slot-scope="scope"> | |||
@@ -153,24 +144,18 @@ | |||
#end | |||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width"> | |||
<template slot-scope="scope"> | |||
<el-button | |||
size="mini" | |||
type="text" | |||
icon="el-icon-edit" | |||
@click="handleUpdate(scope.row)" | |||
v-hasPermi="['${moduleName}:${businessName}:edit']" | |||
>修改</el-button> | |||
<el-button | |||
size="mini" | |||
type="text" | |||
icon="el-icon-delete" | |||
@click="handleDelete(scope.row)" | |||
v-hasPermi="['${moduleName}:${businessName}:remove']" | |||
>删除</el-button> | |||
<el-button size="mini" type="text" icon="el-icon-view" @click="handleLook(scope.row)" v-hasPermi="['${moduleName}:${businessName}:query']">查看</el-button> | |||
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" v-hasPermi="['${moduleName}:${businessName}:edit']">修改</el-button> | |||
<el-dropdown :split-button="false" type="text" class="dropdown el-dropdown-link"> | |||
<span style="cursor: pointer; font-size: 10px; color:#1890FF"><!--更多--><i class="el-icon-arrow-down el-icon--right"></i></span> | |||
<el-dropdown-menu slot="dropdown" style="padding: 10px"> | |||
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" v-hasPermi="['${moduleName}:${businessName}:remove']">删除</el-button> | |||
</el-dropdown-menu> | |||
</el-dropdown> | |||
</template> | |||
</el-table-column> | |||
</el-table> | |||
<pagination | |||
v-show="total>0" | |||
:total="total" | |||
@@ -179,9 +164,35 @@ | |||
@pagination="getList" | |||
/> | |||
<!-- 查看${functionName}对话框 --> | |||
<el-dialog :title="title" :visible.sync="viewOpen" width="800px" append-to-body> | |||
<el-descriptions :column="descColumn" border :labelStyle="{width: `${descLabelWidth}%`}" :contentStyle="{width: `${(100 / descColumn) - descLabelWidth}%`}"> | |||
#foreach($column in $columns) | |||
#set($field=$column.javaField) | |||
#if($column.insert && !$column.pk) | |||
#if(($column.usableColumn) || (!$column.superColumn)) | |||
#set($parentheseIndex=$column.columnComment.indexOf("(")) | |||
#if($parentheseIndex != -1) | |||
#set($comment=$column.columnComment.substring(0, $parentheseIndex)) | |||
#else | |||
#set($comment=$column.columnComment) | |||
#end | |||
#set($dictType=$column.dictType) | |||
<el-descriptions-item label="${comment}">#if(($column.htmlType == "select" || $column.htmlType == "checkbox" || $column.htmlType == "radio") && "" != $dictType)<el-tooltip effect="light" :content="form.${field}" placement="right"><dict-tag :options="dict.type.${dictType}" :value="form.${field}"/></el-tooltip>#elseif($column.htmlType == "imageUpload")<div v-if="!!form.${field}"><el-tooltip effect="light" :content="item" placement="bottom" v-for="(item, index) in form.${field}.split(',')" :key="index"><el-image style="height: 64px; width: 64px; margin: 2px; display: inline-block;" fit="scale-down" :src="$store.getters.baseRoutingUrl + item" :preview-src-list="form.${field}.split(',').map((x) => $store.getters.baseRoutingUrl + x)"/></el-tooltip></div>#elseif($column.htmlType == "editor")<el-tooltip placement="bottom" effect="light"><div slot="content" v-html="form.${field}"/><div style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 230px;">{{ form.${field} }}</div></el-tooltip>#elseif($column.htmlType == "fileUpload")<div v-if="!!form.${field}"><el-tooltip effect="light" :content="item.substr(item.lastIndexOf('/') + 1)" placement="bottom" v-for="(item, index) in form.${field}.split(',')" :key="index"><a :href="$store.getters.baseRoutingUrl + item" target="_blank" style="height: 48px; width: 48px; margin: 2px; display: inline-block; text-align: center;"><img :src="getFileIcon(item)" style="height: 100%;"/></a></el-tooltip></div>#else{{ form.${field} }}#end</el-descriptions-item> | |||
#end | |||
#end | |||
#end | |||
</el-descriptions> | |||
<!-- 弹框操作按钮 --> | |||
<div slot="footer" class="dialog-footer"> | |||
<el-button @click="cancel">关 闭</el-button> | |||
</div> | |||
</el-dialog> | |||
<!-- 添加或修改${functionName}对话框 --> | |||
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body> | |||
<el-form ref="form" :model="form" :rules="rules" label-width="80px"> | |||
<el-dialog :title="title" :visible.sync="open" width="800px" append-to-body> | |||
<el-form ref="form" :model="form" :rules="rules" label-width="110px"> | |||
#foreach($column in $columns) | |||
#set($field=$column.javaField) | |||
#if($column.insert && !$column.pk) | |||
@@ -194,9 +205,18 @@ | |||
#end | |||
#set($dictType=$column.dictType) | |||
#if($column.htmlType == "input") | |||
#COLUMN_IS_NUMBER($column) | |||
#if($_column_is_number) | |||
#GET_NUMBER_COLUMN_MIN_AND_PRECISION($column) | |||
<el-form-item label="${comment}" prop="${field}"> | |||
<el-input-number v-model="form.${field}" placeholder="请输入${comment}" controls-position="right" #if($_number_column_min != "") :min="${_number_column_min}"#end #if($_number_column_precision != "") :precision="${_number_column_precision}"#end/> | |||
</el-form-item> | |||
#else | |||
#GET_CHAR_COLUMN_LENGTH($column) | |||
<el-form-item label="${comment}" prop="${field}"> | |||
<el-input v-model="form.${field}" placeholder="请输入${comment}" /> | |||
<el-input v-model="form.${field}" placeholder="请输入${comment}" #if($_char_column_length != "") show-word-limit :maxlength="${_char_column_length}"#end/> | |||
</el-form-item> | |||
#end | |||
#elseif($column.htmlType == "imageUpload") | |||
<el-form-item label="${comment}" prop="${field}"> | |||
<image-upload v-model="form.${field}"/> | |||
@@ -206,22 +226,19 @@ | |||
<file-upload v-model="form.${field}"/> | |||
</el-form-item> | |||
#elseif($column.htmlType == "editor") | |||
<el-form-item label="${comment}"> | |||
<el-form-item label="${comment}" prop="${field}"> | |||
<editor v-model="form.${field}" :min-height="192"/> | |||
</el-form-item> | |||
#elseif($column.htmlType == "select" && "" != $dictType) | |||
<el-form-item label="${comment}" prop="${field}"> | |||
<el-select v-model="form.${field}" placeholder="请选择${comment}"> | |||
<el-option | |||
v-for="dict in dict.type.${dictType}" | |||
:key="dict.value" | |||
:label="dict.label" | |||
<el-option v-for="dict in dict.type.${dictType}" :key="dict.value" :label="dict.label" | |||
#if($column.javaType == "Integer" || $column.javaType == "Long") | |||
:value="parseInt(dict.value)" | |||
#else | |||
:value="dict.value" | |||
#end | |||
></el-option> | |||
/> | |||
</el-select> | |||
</el-form-item> | |||
#elseif($column.htmlType == "select" && $dictType) | |||
@@ -233,12 +250,7 @@ | |||
#elseif($column.htmlType == "checkbox" && "" != $dictType) | |||
<el-form-item label="${comment}" prop="${field}"> | |||
<el-checkbox-group v-model="form.${field}"> | |||
<el-checkbox | |||
v-for="dict in dict.type.${dictType}" | |||
:key="dict.value" | |||
:label="dict.value"> | |||
{{dict.label}} | |||
</el-checkbox> | |||
<el-checkbox v-for="dict in dict.type.${dictType}" :key="dict.value" :label="dict.value">{{dict.label}}</el-checkbox> | |||
</el-checkbox-group> | |||
</el-form-item> | |||
#elseif($column.htmlType == "checkbox" && $dictType) | |||
@@ -250,9 +262,7 @@ | |||
#elseif($column.htmlType == "radio" && "" != $dictType) | |||
<el-form-item label="${comment}" prop="${field}"> | |||
<el-radio-group v-model="form.${field}"> | |||
<el-radio | |||
v-for="dict in dict.type.${dictType}" | |||
:key="dict.value" | |||
<el-radio v-for="dict in dict.type.${dictType}" :key="dict.value" | |||
#if($column.javaType == "Integer" || $column.javaType == "Long") | |||
:label="parseInt(dict.value)" | |||
#else | |||
@@ -268,17 +278,18 @@ | |||
</el-radio-group> | |||
</el-form-item> | |||
#elseif($column.htmlType == "datetime") | |||
#GET_CHAR_COLUMN_LENGTH($column) | |||
<el-form-item label="${comment}" prop="${field}"> | |||
<el-date-picker clearable | |||
v-model="form.${field}" | |||
type="date" | |||
value-format="yyyy-MM-dd" | |||
#if($_char_column_length == "4")type="year" value-format="yyyy" #elseif($_char_column_length == "6")type="yearmonth" value-format="yyyyMM" #elseif($_char_column_length == "7")type="yearmonth" value-format="yyyy-MM" #else type="date" value-format="yyyy-MM-dd" #end | |||
placeholder="请选择${comment}"> | |||
</el-date-picker> | |||
</el-form-item> | |||
#elseif($column.htmlType == "textarea") | |||
#GET_CHAR_COLUMN_LENGTH($column) | |||
<el-form-item label="${comment}" prop="${field}"> | |||
<el-input v-model="form.${field}" type="textarea" placeholder="请输入内容" /> | |||
<el-input v-model="form.${field}" type="textarea" :autosize="{ minRows: 2, maxRows: 3}" #if($_char_column_length != "") :maxlength="${_char_column_length}"#end show-word-limit placeholder="请输入${comment}" /> | |||
</el-form-item> | |||
#end | |||
#end | |||
@@ -322,12 +333,7 @@ | |||
<el-table-column label="$comment" prop="${javaField}" width="150"> | |||
<template slot-scope="scope"> | |||
<el-select v-model="scope.row.$javaField" placeholder="请选择$comment"> | |||
<el-option | |||
v-for="dict in dict.type.$column.dictType" | |||
:key="dict.value" | |||
:label="dict.label" | |||
:value="dict.value" | |||
></el-option> | |||
<el-option v-for="dict in dict.type.$column.dictType" :key="dict.value" :label="dict.label" :value="dict.value"/> | |||
</el-select> | |||
</template> | |||
</el-table-column> | |||
@@ -345,8 +351,8 @@ | |||
#end | |||
</el-form> | |||
<div slot="footer" class="dialog-footer"> | |||
<el-button type="primary" @click="submitForm">确 定</el-button> | |||
<el-button @click="cancel">取 消</el-button> | |||
<el-button type="primary" v-if="diglogStatus" @click="submitForm">保 存</el-button> | |||
<el-button @click="cancel">关 闭</el-button> | |||
</div> | |||
</el-dialog> | |||
</div> | |||
@@ -355,15 +361,58 @@ | |||
<script> | |||
import { list${BusinessName}, get${BusinessName}, del${BusinessName}, add${BusinessName}, update${BusinessName} } from "@/api/${moduleName}/${businessName}"; | |||
#foreach($column in $columns) | |||
#if($column.insert && !$column.superColumn && !$column.pk && $column.htmlType == "imageUpload") | |||
import ImageUpload from '@/components/ImageUpload'; | |||
#break | |||
#end | |||
#end | |||
#foreach($column in $columns) | |||
#if($column.insert && !$column.superColumn && !$column.pk && $column.htmlType == "fileUpload") | |||
import FileUpload from '@/components/FileUpload'; | |||
#break | |||
#end | |||
#end | |||
#foreach($column in $columns) | |||
#if($column.insert && !$column.superColumn && !$column.pk && $column.htmlType == "editor") | |||
import Editor from '@/components/Editor'; | |||
#break | |||
#end | |||
#end | |||
export default { | |||
name: "${BusinessName}", | |||
components: { | |||
#foreach($column in $columns) | |||
#if($column.insert && !$column.superColumn && !$column.pk && $column.htmlType == "imageUpload") | |||
ImageUpload, | |||
#break | |||
#end | |||
#end | |||
#foreach($column in $columns) | |||
#if($column.insert && !$column.superColumn && !$column.pk && $column.htmlType == "fileUpload") | |||
FileUpload, | |||
#break | |||
#end | |||
#end | |||
#foreach($column in $columns) | |||
#if($column.insert && !$column.superColumn && !$column.pk && $column.htmlType == "editor") | |||
Editor, | |||
#break | |||
#end | |||
#end | |||
}, | |||
#if(${dicts} != '') | |||
dicts: [${dicts}], | |||
#end | |||
data() { | |||
return { | |||
// 遮罩层 | |||
loading: true, | |||
loading: false, | |||
// 遮罩按钮新增点击状态 | |||
diglogStatus: true, | |||
// 导出遮罩层 | |||
exportLoading: false, | |||
// 选中数组 | |||
ids: [], | |||
#if($table.sub) | |||
@@ -374,8 +423,8 @@ export default { | |||
single: true, | |||
// 非多个禁用 | |||
multiple: true, | |||
// 显示搜索条件 | |||
showSearch: true, | |||
// 默认隐藏搜索条件 | |||
showSearch: false, | |||
// 总条数 | |||
total: 0, | |||
// ${functionName}表格数据 | |||
@@ -389,7 +438,16 @@ export default { | |||
// 是否显示弹出层 | |||
open: false, | |||
#foreach ($column in $columns) | |||
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN") | |||
#set($parentheseIndex=$column.columnComment.indexOf("(")) | |||
#if($parentheseIndex != -1) | |||
#set($comment=$column.columnComment.substring(0, $parentheseIndex)) | |||
#else | |||
#set($comment=$column.columnComment) | |||
#end | |||
#if(${column.dictType} != '') | |||
// $comment字典 | |||
${column.javaField}Options: [], | |||
#elseif($column.htmlType == "datetime" && $column.queryType == "BETWEEN") | |||
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) | |||
// $comment时间范围 | |||
daterange${AttrName}: [], | |||
@@ -397,11 +455,17 @@ export default { | |||
#end | |||
// 查询参数 | |||
queryParams: { | |||
// 分页 | |||
pageNum: 1, | |||
pageSize: 10, | |||
// 查询排序 | |||
//orderByColumn: "id", | |||
//isAsc: "desc", | |||
// 翻译字典 | |||
//translate_dict: "1", | |||
#foreach ($column in $columns) | |||
#if($column.query) | |||
$column.javaField: null#if($foreach.count != $columns.size()),#end | |||
$column.javaField: null, | |||
#end | |||
#end | |||
}, | |||
@@ -418,11 +482,17 @@ export default { | |||
#set($comment=$column.columnComment) | |||
#end | |||
$column.javaField: [ | |||
{ required: true, message: "$comment不能为空", trigger: #if($column.htmlType == "select" || $column.htmlType == "radio")"change"#else"blur"#end } | |||
]#if($foreach.count != $columns.size()),#end | |||
{ required: true, message: "$comment不能为空", trigger: #if($column.htmlType == "select" || $column.htmlType == "imageUpload" || $column.htmlType == "fileUpload" || $column.htmlType == "editor" || $column.htmlType == "radio")"change"#else"blur"#end }, | |||
], | |||
#end | |||
#end | |||
} | |||
}, | |||
// 详情组件列数 | |||
descColumn: 2, | |||
// 详情组件Label所占百分比, 最大={100 / descColumn}. 内容所占百分比={100 / descColumn - descLabelWidth} | |||
descLabelWidth: 15, | |||
// 对话框显示只读的详情 | |||
viewOpen: false, | |||
}; | |||
}, | |||
created() { | |||
@@ -450,12 +520,26 @@ export default { | |||
list${BusinessName}(this.queryParams).then(response => { | |||
this.${businessName}List = response.rows; | |||
this.total = response.total; | |||
this.loading = false; | |||
}); | |||
}).finally(() => this.loading = false ); | |||
}, | |||
#foreach ($column in $columns) | |||
#if(${column.dictType} != '') | |||
#set($parentheseIndex=$column.columnComment.indexOf("(")) | |||
#if($parentheseIndex != -1) | |||
#set($comment=$column.columnComment.substring(0, $parentheseIndex)) | |||
#else | |||
#set($comment=$column.columnComment) | |||
#end | |||
// $comment字典翻译 | |||
${column.javaField}Format(row, column) { | |||
return this.selectDictLabel#if($column.htmlType == "checkbox")s#end(this.dict.type.${column.dictType}, row.${column.javaField}); | |||
}, | |||
#end | |||
#end | |||
// 取消按钮 | |||
cancel() { | |||
this.open = false; | |||
this.viewOpen = false; | |||
this.reset(); | |||
}, | |||
// 表单重置 | |||
@@ -473,6 +557,8 @@ export default { | |||
this.${subclassName}List = []; | |||
#end | |||
this.resetForm("form"); | |||
// 防止表单提交失败再次打开按钮隐藏 | |||
this.diglogStatus = true; | |||
}, | |||
/** 搜索按钮操作 */ | |||
handleQuery() { | |||
@@ -499,6 +585,7 @@ export default { | |||
/** 新增按钮操作 */ | |||
handleAdd() { | |||
this.reset(); | |||
this.viewOpen = false; | |||
this.open = true; | |||
this.title = "添加${functionName}"; | |||
}, | |||
@@ -516,14 +603,37 @@ export default { | |||
#if($table.sub) | |||
this.${subclassName}List = response.data.${subclassName}List; | |||
#end | |||
this.viewOpen = false; | |||
this.open = true; | |||
this.title = "修改${functionName}"; | |||
}); | |||
}, | |||
/** 查看按钮操作 */ | |||
handleLook(row) { | |||
this.reset(); | |||
// 查看时不允许提交 | |||
this.diglogStatus = false; | |||
const ${pkColumn.javaField} = row.${pkColumn.javaField} || this.ids | |||
get${BusinessName}(${pkColumn.javaField}).then(response => { | |||
this.form = response.data; | |||
#foreach ($column in $columns) | |||
#if($column.htmlType == "checkbox") | |||
this.form.$column.javaField = this.form.${column.javaField}.split(","); | |||
#end | |||
#end | |||
#if($table.sub) | |||
this.${subclassName}List = response.data.${subclassName}List; | |||
#end | |||
this.viewOpen = true; | |||
this.open = false; | |||
this.title = "查看${functionName}"; | |||
}); | |||
}, | |||
/** 提交按钮 */ | |||
submitForm() { | |||
this.#[[$]]#refs["form"].validate(valid => { | |||
if (valid) { | |||
this.diglogStatus = false; | |||
#foreach ($column in $columns) | |||
#if($column.htmlType == "checkbox") | |||
this.form.$column.javaField = this.form.${column.javaField}.join(","); | |||
@@ -534,16 +644,20 @@ export default { | |||
#end | |||
if (this.form.${pkColumn.javaField} != null) { | |||
update${BusinessName}(this.form).then(response => { | |||
if(response.code != 200) throw response.msg; | |||
this.#[[$modal]]#.msgSuccess("修改成功"); | |||
this.open = false; | |||
this.getList(); | |||
}); | |||
this.diglogStatus = true; | |||
}).catch(() => this.diglogStatus = true); | |||
} else { | |||
add${BusinessName}(this.form).then(response => { | |||
if(response.code != 200) throw response.msg; | |||
this.#[[$modal]]#.msgSuccess("新增成功"); | |||
this.open = false; | |||
this.getList(); | |||
}); | |||
this.diglogStatus = true; | |||
}).catch(() => this.diglogStatus = true); | |||
} | |||
} | |||
}); | |||
@@ -593,10 +707,19 @@ export default { | |||
#end | |||
/** 导出按钮操作 */ | |||
handleExport() { | |||
this.download('${moduleName}/${businessName}/export', { | |||
...this.queryParams | |||
}, `${businessName}_#[[${new Date().getTime()}]]#.xlsx`) | |||
} | |||
} | |||
const queryParams = this.queryParams; | |||
var _this = this; | |||
this.#[[$modal]]#.confirm('是否确认导出所有${functionName}数据项?', "警告", { | |||
confirmButtonText: "确定", | |||
cancelButtonText: "取消", | |||
type: "warning" | |||
}).then(function() { | |||
_this.exportLoading = true; | |||
_this.download('${moduleName}/${businessName}/export', { | |||
..._this.queryParams | |||
}, `${businessName}_#[[${new Date().getTime()}]]#.xlsx`).then(() => _this.exportLoading = false); | |||
}).catch(() => { _this.exportLoading = false }); | |||
}, | |||
}, | |||
}; | |||
</script> |
@@ -420,7 +420,7 @@ async function handleUpdate(row) { | |||
reset(); | |||
await getTreeselect(); | |||
if (row != null) { | |||
form.value.${treeParentCode} = row.${treeCode}; | |||
form.value.${treeParentCode} = row.${treeParentCode}; | |||
} | |||
get${BusinessName}(row.${pkColumn.javaField}).then(response => { | |||
form.value = response.data; | |||
@@ -26,7 +26,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" | |||
select#foreach($column in $columns) $column.columnName#if($foreach.count != $columns.size()),#end#end from ${tableName} | |||
</sql> | |||
<!--条件查询--> | |||
<select id="select${ClassName}List" parameterType="${ClassName}" resultMap="${ClassName}Result"> | |||
<include refid="select${ClassName}Vo"/> | |||
<where> | |||
@@ -59,7 +58,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" | |||
</where> | |||
</select> | |||
<!--主键查询--> | |||
<select id="select${ClassName}By${pkColumn.capJavaField}" parameterType="${pkColumn.javaType}" resultMap="#if($table.sub)${ClassName}${subClassName}Result#else${ClassName}Result#end"> | |||
#if($table.crud || $table.tree) | |||
<include refid="select${ClassName}Vo"/> | |||
@@ -74,7 +72,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" | |||
#end | |||
</select> | |||
<!--新增--> | |||
<insert id="insert${ClassName}" parameterType="${ClassName}"#if($pkColumn.increment) useGeneratedKeys="true" keyProperty="$pkColumn.javaField"#end> | |||
insert into ${tableName} | |||
<trim prefix="(" suffix=")" suffixOverrides=","> | |||
@@ -115,7 +112,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" | |||
</foreach> | |||
</insert> | |||
<!--更新--> | |||
<update id="update${ClassName}" parameterType="${ClassName}"> | |||
update ${tableName} | |||
<trim prefix="SET" suffixOverrides=","> | |||
@@ -124,7 +120,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" | |||
<if test="$column.javaField != null#if($column.javaType == 'String' && $column.required) and $column.javaField != ''#end">$column.columnName = #{$column.javaField},</if> | |||
#end | |||
#end | |||
<if test="params != null and params.__UPDATE != null"><foreach collection="params.__UPDATE" item="val" index="col">`${col}` = #{val},</foreach></if> | |||
</trim> | |||
where ${pkColumn.columnName} = #{${pkColumn.javaField}} | |||
</update> | |||
@@ -139,18 +134,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" | |||
<if test="item.$column.javaField != null#if($column.javaType == 'String' && $column.required) and item.$column.javaField != ''#end">$column.columnName = #{item.$column.javaField},</if> | |||
#end | |||
#end | |||
<if test="item.params != null and item.params.__UPDATE != null"><foreach collection="item.params.__UPDATE" item="val" index="col">`${col}` = #{val},</foreach></if> | |||
</set> | |||
where ${pkColumn.columnName} = #{item.${pkColumn.javaField}} | |||
</foreach> | |||
</update> | |||
<!--主键删除--> | |||
<delete id="delete${ClassName}By${pkColumn.capJavaField}" parameterType="${pkColumn.javaType}"> | |||
delete from ${tableName} where ${pkColumn.columnName} = #{${pkColumn.javaField}} | |||
</delete> | |||
<!--主键批量删除--> | |||
<delete id="delete${ClassName}By${pkColumn.capJavaField}s" parameterType="String"> | |||
delete from ${tableName} where ${pkColumn.columnName} in | |||
<foreach item="${pkColumn.javaField}" collection="array" open="(" separator="," close=")"> | |||
@@ -159,8 +151,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" | |||
</delete> | |||
#if($table.sub) | |||
<!--按主表N个主键批量删除子表--> | |||
<delete id="delete${subClassName}By${subTableFkClassName}s" parameterType="String"> | |||
delete from ${subTableName} where ${subTableFkName} in | |||
<foreach item="${subTableFkclassName}" collection="array" open="(" separator="," close=")"> | |||
@@ -168,13 +158,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" | |||
</foreach> | |||
</delete> | |||
<!--按主表主键删除子表--> | |||
<delete id="delete${subClassName}By${subTableFkClassName}" parameterType="${pkColumn.javaType}"> | |||
delete from ${subTableName} where ${subTableFkName} = #{${subTableFkclassName}} | |||
</delete> | |||
<!--子表语法 (要求主表、子表关联主键字段名称相同)--> | |||
<!--批量新增子表--> | |||
<insert id="batch${subClassName}"> | |||
insert into ${subTableName}(#foreach($column in $subTable.columns) $column.columnName#if($foreach.count != $subTable.columns.size()),#end#end) values | |||
<foreach item="item" index="index" collection="list" separator=","> | |||
@@ -183,7 +170,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" | |||
</insert> | |||
#end | |||
<!-- Harm --> | |||
<!--单条条件查询--> | |||
<select id="select${ClassName}" parameterType="${ClassName}" resultMap="${ClassName}Result"> | |||
<include refid="select${ClassName}Vo"/> | |||
@@ -220,7 +206,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" | |||
<!--条件查询数量--> | |||
<select id="select${ClassName}Count" parameterType="${ClassName}" resultType="Long"> | |||
select count(*) from ${tableName} | |||
select count(*) from ${tableName} | |||
<where> | |||
#foreach($column in $columns) | |||
#set($queryType=$column.queryType) | |||
@@ -123,4 +123,6 @@ public interface SysDeptMapper | |||
*/ | |||
public SysDept selectSysDept(SysDept sysDept); | |||
public SysDept selectSysDeptByOrgCode(String orgCode); | |||
public List<SysDept> getDeptList(SysDept cond); | |||
} |
@@ -128,4 +128,15 @@ public interface ISysDeptService | |||
* @return 部门条目 | |||
*/ | |||
public SysDept selectSysDept(SysDept sysDept); | |||
/** | |||
* 查询部门列表, 不受当前用户影响 | |||
* | |||
* @param sysDept 部门 | |||
* @return 部门条目 | |||
*/ | |||
public List<SysDept> getDeptList(SysDept sysDept); | |||
public List<SysDept> getDeptTree(SysDept dept); | |||
public List<SysDept> getCityTree(SysDept dept); | |||
} |
@@ -4,6 +4,8 @@ import java.util.ArrayList; | |||
import java.util.Iterator; | |||
import java.util.List; | |||
import java.util.stream.Collectors; | |||
import com.ruoyi.common.utils.TreeUtils; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import org.springframework.stereotype.Service; | |||
import com.ruoyi.common.annotation.DataScope; | |||
@@ -345,4 +347,39 @@ public class SysDeptServiceImpl implements ISysDeptService | |||
public SysDept selectSysDept(SysDept sysDept) { | |||
return deptMapper.selectSysDept(sysDept); | |||
} | |||
@Override | |||
public List<SysDept> getDeptList(SysDept sysDept) | |||
{ | |||
return deptMapper.getDeptList(sysDept); | |||
} | |||
@Override | |||
public List<SysDept> getDeptTree(SysDept dept) | |||
{ | |||
List<SysDept> deptList = getDeptList(dept); | |||
return TreeUtils.makeTree(deptList, TreeUtils.Config.<SysDept>builder() | |||
.getParentIdFunc(SysDept::getParentId) | |||
.setChildrenFunc(SysDept::setChildren) | |||
.getIdFunc(SysDept::getDeptId) | |||
.getChildrenFunc(SysDept::getChildren) | |||
.build(), | |||
SysDept.ROOT_DEPT_ID | |||
); | |||
} | |||
@Override | |||
public List<SysDept> getCityTree(SysDept dept) | |||
{ | |||
List<SysDept> deptTree = getDeptTree(dept); | |||
List<SysDept> depts = TreeUtils.makeList(deptTree, TreeUtils.Config.<SysDept>builder() | |||
.getParentIdFunc(SysDept::getParentId) | |||
.setChildrenFunc(SysDept::setChildren) | |||
.getIdFunc(SysDept::getDeptId) | |||
.getChildrenFunc(SysDept::getChildren) | |||
.build()); | |||
depts.removeIf((x) -> x.orgCodeLength() != 6); | |||
return depts; | |||
} | |||
} |
@@ -187,4 +187,28 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" | |||
AND `status` = '0' | |||
limit 1 | |||
</select> | |||
<select id="getDeptList" parameterType="SysDept" resultMap="SysDeptResult"> | |||
<include refid="selectDeptVo"/> | |||
where d.del_flag = '0' | |||
<if test="deptId != null and deptId != 0"> | |||
AND dept_id = #{deptId} | |||
</if> | |||
<if test="parentId != null and parentId != 0"> | |||
AND parent_id = #{parentId} | |||
</if> | |||
<if test="deptName != null and deptName != ''"> | |||
AND dept_name like concat('%', #{deptName}, '%') | |||
</if> | |||
<if test="status != null and status != ''"> | |||
AND status = #{status} | |||
</if> | |||
<if test="rootId != null and rootId != 0"> | |||
AND (dept_id = #{rootId} OR dept_id IN (SELECT dept_id FROM sys_dept WHERE FIND_IN_SET(#{rootId}, ancestors))) | |||
</if> | |||
<if test="orgCodeLength != null and orgCodeLength != ''"> | |||
AND LENGTH(org_code) = #{orgCodeLength} | |||
</if> | |||
order by d.parent_id, d.order_num | |||
</select> | |||
</mapper> |