| @@ -37,11 +37,11 @@ public class AgentTaskUserController extends BaseController | |||
| * 分配用户列表 | |||
| */ | |||
| @PreAuthorize("@ss.hasPermi('agentcenter:task:list')") | |||
| @GetMapping(value = "/distribUserList") | |||
| public TableDataInfo distribUserList(AgentTaskUser agentTaskUser) | |||
| @GetMapping(value = "/userList") | |||
| public TableDataInfo userList(AgentTaskUser agentTaskUser) | |||
| { | |||
| startPage(); | |||
| agentTaskUser.setAgentCenter(getUserAgentCenter()); | |||
| return getDataTable(agentTaskService.distribUserList(agentTaskUser)); | |||
| return getDataTable(agentTaskService.userList(agentTaskUser)); | |||
| } | |||
| } | |||
| @@ -2,12 +2,14 @@ package com.ruoyi.web.controller.agentcenter; | |||
| import com.ruoyi.agentcenter.dto.AgentTaskTownNumGroup; | |||
| import com.ruoyi.agentcenter.vo.TaskDistrib; | |||
| import com.ruoyi.agentcenter.vo.TaskRevoke; | |||
| import com.ruoyi.common.core.domain.AjaxResult; | |||
| import org.springframework.security.access.prepost.PreAuthorize; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.validation.annotation.Validated; | |||
| import org.springframework.web.bind.annotation.GetMapping; | |||
| import org.springframework.web.bind.annotation.PathVariable; | |||
| import org.springframework.web.bind.annotation.PostMapping; | |||
| import org.springframework.web.bind.annotation.RequestBody; | |||
| import org.springframework.web.bind.annotation.RequestMapping; | |||
| import org.springframework.web.bind.annotation.RestController; | |||
| @@ -80,24 +82,21 @@ public class ManagerAgentTaskController extends BaseController | |||
| * 分配 | |||
| */ | |||
| @PreAuthorize("@ss.hasPermi('manager:task:distrib')") | |||
| @GetMapping(value = "/distrib/{id}") | |||
| public AjaxResult distrib(@PathVariable Long id, @Validated @RequestBody TaskDistrib taskDistrib) | |||
| @PostMapping(value = "/distrib") | |||
| public AjaxResult distrib(@Validated @RequestBody TaskDistrib taskDistrib) | |||
| { | |||
| TAgentTask task = taskDistrib.toAgentTask(); | |||
| task.setId(id); | |||
| task.setAuditUser(getUsername()); | |||
| return toAjax(tAgentTaskService.distrib(task)); | |||
| taskDistrib.setDistriUser(getUsername()); | |||
| return toAjax(tAgentTaskService.distrib(taskDistrib)); | |||
| } | |||
| /** | |||
| * 撤回 | |||
| */ | |||
| @PreAuthorize("@ss.hasPermi('manager:task:revoke')") | |||
| @GetMapping(value = "/revoke/{id}") | |||
| public AjaxResult revoke(@PathVariable Long id, TAgentTask task) | |||
| @PostMapping(value = "/revoke") | |||
| public AjaxResult revoke(@Validated @RequestBody TaskRevoke taskRevoke) | |||
| { | |||
| task.setId(id); | |||
| return toAjax(tAgentTaskService.revoke(task)); | |||
| return toAjax(tAgentTaskService.revoke(taskRevoke)); | |||
| } | |||
| /** | |||
| @@ -113,4 +112,28 @@ public class ManagerAgentTaskController extends BaseController | |||
| return toAjax(tAgentTaskService.audit(task)); | |||
| } | |||
| /** | |||
| * 处理中任务列表 | |||
| */ | |||
| @PreAuthorize("@ss.hasPermi('agentcenter:task:list')") | |||
| @GetMapping(value = "/processingTaskList") | |||
| public TableDataInfo processingTaskList(TAgentTask task) | |||
| { | |||
| startPage(); | |||
| task.setAgentCenter(getUserAgentCenter()); | |||
| return getDataTable(tAgentTaskService.getProcessingTaskList(task)); | |||
| } | |||
| /** | |||
| * 全部任务列表 | |||
| */ | |||
| @PreAuthorize("@ss.hasPermi('agentcenter:task:list')") | |||
| @GetMapping(value = "/countyProcessingTaskSummary") | |||
| public AjaxResult countyProcessingTaskSummary(TAgentTask task) | |||
| { | |||
| task.setAgentCenter(getUserAgentCenter()); | |||
| task.setTownCode(null); | |||
| return AjaxResult.success(tAgentTaskService.countyProcessingTaskSummary(task)); | |||
| } | |||
| } | |||
| @@ -22,6 +22,8 @@ public class AgentTaskTownNumGroup | |||
| private String orgCode; | |||
| private String endAt; | |||
| private String handleUser; | |||
| private List<AgentTaskTownNumGroup> villageList; | |||
| public void calcOtherCount() | |||
| @@ -18,6 +18,8 @@ public class AgentTaskVillageGroup | |||
| private Long numExcept; | |||
| private String townCode; | |||
| private Long numNotApproval; | |||
| private Long allCount; | |||
| private Long finishCount; | |||
| private String orgName; | |||
| private String orgCode; | |||
| @@ -27,6 +29,8 @@ public class AgentTaskVillageGroup | |||
| private String handleDate; | |||
| private String endAt; | |||
| private String handleNick; | |||
| private String orderYear; | |||
| private String orderMonth; | |||
| private Boolean approvalFinish; | |||
| @@ -114,4 +114,6 @@ public interface TAgentTaskMapper | |||
| public List<TAgentTask> getTaskHandleUserListGroup(TAgentTask tAgentTask); | |||
| public List<AgentTaskTownNumGroup> getAgentTaskNumTownGroup(TAgentTask tAgentTask); | |||
| public List<AgentTaskTownNumGroup> getAgentTaskNumVillageGroup(TAgentTask tAgentTask); | |||
| public int revokeAgentTaskByOrgCode(TAgentTask task); | |||
| } | |||
| @@ -9,6 +9,8 @@ import com.ruoyi.agentcenter.dto.AgentTaskTownNumGroup; | |||
| import com.ruoyi.agentcenter.dto.AgentTaskVillageGroup; | |||
| import com.ruoyi.agentcenter.vo.AgentTaskUser; | |||
| import com.ruoyi.agentcenter.vo.CountyTaskSummary; | |||
| import com.ruoyi.agentcenter.vo.TaskDistrib; | |||
| import com.ruoyi.agentcenter.vo.TaskRevoke; | |||
| /** | |||
| * 任务清单Service接口 | |||
| @@ -118,16 +120,18 @@ public interface ITAgentTaskService | |||
| public int syncTAgentTaskCount(TAgentTask tAgentTask); | |||
| public List<AgentTaskTownGroup> getTownTaskList(TAgentTask tAgentTask); | |||
| public List<AgentTaskTownGroup> getProcessingTaskList(TAgentTask tAgentTask); | |||
| public List<TAgentTask> getTodoTaskList(TAgentTask tAgentTask); | |||
| public List<AgentTaskVillageGroup> getProcessedTaskList(TAgentTask tAgentTask); | |||
| public Long getAgentTaskOverdueFinishVillageCount(TAgentTask tAgentTask); | |||
| public int distrib(TAgentTask task); | |||
| public int revoke(TAgentTask task); | |||
| public int distrib(TaskDistrib task); | |||
| public int revoke(TaskRevoke task); | |||
| public int audit(TAgentTask task); | |||
| public List<AgentTaskUser> distribUserList(AgentTaskUser user); | |||
| public List<AgentTaskUser> userList(AgentTaskUser user); | |||
| public List<AgentTaskTownNumGroup> getUndistribTaskList(TAgentTask tAgentTask, AgentTaskTownNumGroup summary); | |||
| public CountyTaskSummary countyTaskSummary(TAgentTask task); | |||
| public CountyTaskSummary countyProcessingTaskSummary(TAgentTask task); | |||
| } | |||
| @@ -2,11 +2,14 @@ package com.ruoyi.agentcenter.service.impl; | |||
| import java.util.ArrayList; | |||
| import java.util.Arrays; | |||
| import java.util.Date; | |||
| import java.util.List; | |||
| import java.util.Map; | |||
| import java.util.function.Consumer; | |||
| import cn.hutool.core.collection.CollectionUtil; | |||
| import cn.hutool.core.date.DateTime; | |||
| import cn.hutool.core.date.DateUtil; | |||
| import cn.hutool.core.lang.Assert; | |||
| import com.github.pagehelper.Page; | |||
| import com.github.pagehelper.PageInfo; | |||
| @@ -15,6 +18,8 @@ import com.ruoyi.agentcenter.dto.AgentTaskTownNumGroup; | |||
| import com.ruoyi.agentcenter.dto.AgentTaskVillageGroup; | |||
| import com.ruoyi.agentcenter.vo.AgentTaskUser; | |||
| import com.ruoyi.agentcenter.vo.CountyTaskSummary; | |||
| import com.ruoyi.agentcenter.vo.TaskDistrib; | |||
| import com.ruoyi.agentcenter.vo.TaskRevoke; | |||
| import com.ruoyi.common.core.domain.entity.SysDept; | |||
| import com.ruoyi.common.core.domain.entity.SysUser; | |||
| import com.ruoyi.common.exception.ASSERT; | |||
| @@ -320,6 +325,9 @@ public class TAgentTaskServiceImpl implements ITAgentTaskService | |||
| villageList.forEach((village) -> { | |||
| village.setApprovalFinish(village.getNum().equals(village.getNumApprovalFinish())); | |||
| village.setTaskList(bookGroup.getOrDefault(village.getOrgCode(), new ArrayList<>())); | |||
| village.getTaskList().forEach((x) -> { | |||
| x.setOtherCount(x.getAllCount() - x.getVoucherCount() - x.getContracCount()); | |||
| }); | |||
| }); | |||
| }); | |||
| } | |||
| @@ -365,24 +373,39 @@ public class TAgentTaskServiceImpl implements ITAgentTaskService | |||
| } | |||
| @Override | |||
| public int distrib(TAgentTask task) | |||
| public int distrib(TaskDistrib task) | |||
| { | |||
| TAgentTask dbTask = tAgentTaskMapper.selectTAgentTaskById(task.getId()); | |||
| ASSERT.EXP(TAgentTask.AGENT_STATUS_READY.equals(dbTask.getAgentStatus())); | |||
| dbTask.setAgentStatus(TAgentTask.AGENT_STATUS_PROCESSING) | |||
| .setDistriDate(DateUtils.getNowDate()) | |||
| .setDistriUser(sysUserMapper.selectUserByUserName(task.getDistriUser()).getNickName()) | |||
| .setEndAt(task.getEndAt()) | |||
| ; | |||
| List<String> orgCodeList = ContainerUtils.mapToList(task.getItems(), TaskDistrib.TaskDistribItem::getOrgCode); | |||
| TAgentTask cond = new TAgentTask(); | |||
| cond.setOrderYear(task.getOrderYear()) | |||
| .setOrderMonth(task.getOrderMonth()) | |||
| .setAgentStatus(TAgentTask.AGENT_STATUS_READY) | |||
| .putParam("orgCodeList", orgCodeList) | |||
| ; | |||
| List<TAgentTask> dbTask = tAgentTaskMapper.selectTAgentTaskList(cond); | |||
| Map<String, TaskDistrib.TaskDistribItem> map = ContainerUtils.toMap(task.getItems(), TaskDistrib.TaskDistribItem::getOrgCode); | |||
| Date now = DateUtils.getNowDate(); | |||
| dbTask.forEach((x) -> { | |||
| TaskDistrib.TaskDistribItem taskDistribItem = map.get(x.getOrgCode()); | |||
| DateTime dateTime = DateUtil.offsetDay(now, taskDistribItem.getDays()); | |||
| x.setAgentStatus(TAgentTask.AGENT_STATUS_PROCESSING) | |||
| .setDistriDate(DateUtils.getNowDate()) | |||
| .setDistriUser(taskDistribItem.getHandleUser()) | |||
| .setDistriNick(sysUserMapper.selectUserByUserName(taskDistribItem.getHandleUser()).getNickName()) | |||
| .setEndAt(DateUtil.format(dateTime, "yyyy-MM-dd")) | |||
| ; | |||
| }); | |||
| return tAgentTaskMapper.updateTAgentTask(dbTask); | |||
| return updateTAgentTaskBatch(dbTask); | |||
| } | |||
| @Override | |||
| public int revoke(TAgentTask task) | |||
| public int revoke(TaskRevoke taskRevoke) | |||
| { | |||
| TAgentTask task = taskRevoke.toAgentTask(); | |||
| tAgentTaskMapper.revokeAgentTaskByOrgCode(task); | |||
| return 1; | |||
| } | |||
| @@ -404,7 +427,7 @@ public class TAgentTaskServiceImpl implements ITAgentTaskService | |||
| } | |||
| @Override | |||
| public List<AgentTaskUser> distribUserList(AgentTaskUser agentTaskUser) | |||
| public List<AgentTaskUser> userList(AgentTaskUser agentTaskUser) | |||
| { | |||
| SysUser user = new SysUser(); | |||
| user.setAgentCenter(agentTaskUser.getAgentCenter()); | |||
| @@ -424,6 +447,8 @@ public class TAgentTaskServiceImpl implements ITAgentTaskService | |||
| AgentTaskUser u = new AgentTaskUser(); | |||
| u.setNum(map.getOrDefault(x.getUserName(), 0L)) | |||
| .setUserName(x.getUserName()) | |||
| .setNickName(x.getNickName()) | |||
| .setUserId(x.getUserId()) | |||
| ; | |||
| tAgentTasks.add(u); | |||
| }); | |||
| @@ -482,4 +507,59 @@ public class TAgentTaskServiceImpl implements ITAgentTaskService | |||
| return res; | |||
| } | |||
| @Override | |||
| public List<AgentTaskTownGroup> getProcessingTaskList(TAgentTask tAgentTask) | |||
| { | |||
| tAgentTask.setAgentStatus(TAgentTask.AGENT_STATUS_PROCESSING); | |||
| List<AgentTaskTownGroup> agentTaskGroupByTown = tAgentTaskMapper.getAgentTaskGroupByTown(tAgentTask); | |||
| if(CollectionUtil.isNotEmpty(agentTaskGroupByTown)) | |||
| { | |||
| List<String> townCodeList = ContainerUtils.mapToList(agentTaskGroupByTown, AgentTaskTownGroup::getTownCode); | |||
| TAgentTask villageTaskCond = new TAgentTask(); | |||
| villageTaskCond.setAgentStatus(TAgentTask.AGENT_STATUS_PROCESSING); | |||
| villageTaskCond.putParam("townCodeList", townCodeList); | |||
| List<AgentTaskVillageGroup> villageGroups = tAgentTaskMapper.getAgentTaskGroupByVillage(villageTaskCond); | |||
| Map<String, List<AgentTaskVillageGroup>> villageMap = ContainerUtils.groupingBy(villageGroups, AgentTaskVillageGroup::getTownCode); | |||
| List<String> orgCodeList = ContainerUtils.mapToList(villageGroups, AgentTaskVillageGroup::getOrgCode); | |||
| TAgentTask agentTaskCond = new TAgentTask(); | |||
| agentTaskCond.setAgentStatus(TAgentTask.AGENT_STATUS_PROCESSING); | |||
| agentTaskCond.putParam("orgCodeList", orgCodeList); | |||
| List<TAgentTask> tAgentTasks = tAgentTaskMapper.selectTAgentTaskList(agentTaskCond); | |||
| Map<String, List<TAgentTask>> bookGroup = ContainerUtils.groupingBy(tAgentTasks, TAgentTask::getOrgCode); | |||
| agentTaskGroupByTown.forEach((town) -> { | |||
| List<AgentTaskVillageGroup> villageList = villageMap.getOrDefault(town.getTownCode(), new ArrayList<>()); | |||
| town.setVillageList(villageList); | |||
| villageList.forEach((village) -> { | |||
| village.setApprovalFinish(village.getNum().equals(village.getNumApprovalFinish())); | |||
| village.setTaskList(bookGroup.getOrDefault(village.getOrgCode(), new ArrayList<>())); | |||
| village.getTaskList().forEach((x) -> { | |||
| x.setOtherCount(x.getAllCount() - x.getVoucherCount() - x.getContracCount()); | |||
| }); | |||
| }); | |||
| }); | |||
| } | |||
| return agentTaskGroupByTown; | |||
| } | |||
| @Override | |||
| public CountyTaskSummary countyProcessingTaskSummary(TAgentTask task) | |||
| { | |||
| CountyTaskSummary res = new CountyTaskSummary(); | |||
| task.setAgentStatus(TAgentTask.AGENT_STATUS_PROCESSING); | |||
| List<AgentTaskTownGroup> agentTaskNumTownGroup = tAgentTaskMapper.getAgentTaskGroupByTown(task); | |||
| res.setNumTown((long)agentTaskNumTownGroup.size()); | |||
| res.setNumBook(agentTaskNumTownGroup.stream().map(AgentTaskTownGroup::getNum).reduce(0L, Long::sum)); | |||
| res.setNumVillage(agentTaskNumTownGroup.stream().map(AgentTaskTownGroup::getNumVillage).reduce(0L, Long::sum)); | |||
| AgentTaskVillageGroup agentTaskVillageSummary = tAgentTaskMapper.getAgentTaskVillageSummary(task); | |||
| res.setAbnormalCount(agentTaskVillageSummary.getNumExcept()); | |||
| return res; | |||
| } | |||
| } | |||
| @@ -7,8 +7,10 @@ import lombok.experimental.Accessors; | |||
| @Accessors(chain = true) | |||
| public class AgentTaskUser | |||
| { | |||
| private Long userId; | |||
| private String nickName; | |||
| private String userName; | |||
| private String orgCode; | |||
| private String agentCenter; | |||
| private Long num; | |||
| private Long num; | |||
| } | |||
| @@ -14,4 +14,5 @@ public class CountyTaskSummary | |||
| private Long numTownApprovalTask; | |||
| private Long numBookProcessedTask; | |||
| private Long numBookApprovalTask; | |||
| private Long numVillage; | |||
| } | |||
| @@ -2,16 +2,41 @@ package com.ruoyi.agentcenter.vo; | |||
| import cn.hutool.core.bean.BeanUtil; | |||
| import com.ruoyi.agentcenter.domain.TAgentTask; | |||
| import lombok.Data; | |||
| import lombok.experimental.Accessors; | |||
| import org.springframework.validation.annotation.Validated; | |||
| import javax.validation.Valid; | |||
| import javax.validation.constraints.NotBlank; | |||
| import javax.validation.constraints.NotEmpty; | |||
| import javax.validation.constraints.NotNull; | |||
| import javax.validation.constraints.Positive; | |||
| import java.util.List; | |||
| @Data | |||
| @Accessors(chain = true) | |||
| public class TaskDistrib | |||
| { | |||
| @NotBlank(message = "处理人不能为空") | |||
| public String handleUser; | |||
| @NotEmpty(message = "处理村庄不能为空") | |||
| @Valid | |||
| private List<TaskDistribItem> items; | |||
| @NotEmpty(message = "年不能为空") | |||
| private String orderYear; | |||
| @NotEmpty(message = "月不能为空") | |||
| private String orderMonth; | |||
| public TAgentTask toAgentTask() | |||
| private String distriUser; | |||
| @Data | |||
| @Accessors(chain = true) | |||
| public static class TaskDistribItem | |||
| { | |||
| return BeanUtil.toBean(this, TAgentTask.class); | |||
| @NotBlank(message = "村不能为空") | |||
| private String orgCode; | |||
| @NotBlank(message = "处理人不能为空") | |||
| private String handleUser; | |||
| @NotNull(message = "处理天数不能为空") | |||
| @Positive(message = "处理天数必须大于0") | |||
| private Integer days; | |||
| } | |||
| } | |||
| @@ -0,0 +1,26 @@ | |||
| package com.ruoyi.agentcenter.vo; | |||
| import cn.hutool.core.bean.BeanUtil; | |||
| import com.ruoyi.agentcenter.domain.TAgentTask; | |||
| import lombok.Data; | |||
| import lombok.experimental.Accessors; | |||
| import javax.validation.constraints.NotBlank; | |||
| import javax.validation.constraints.NotEmpty; | |||
| @Data | |||
| @Accessors(chain = true) | |||
| public class TaskRevoke | |||
| { | |||
| @NotEmpty(message = "年不能为空") | |||
| private String orderYear; | |||
| @NotEmpty(message = "月不能为空") | |||
| private String orderMonth; | |||
| @NotBlank(message = "村不能为空") | |||
| private String orgCode; | |||
| public TAgentTask toAgentTask() | |||
| { | |||
| return BeanUtil.copyProperties(this, TAgentTask.class); | |||
| } | |||
| } | |||
| @@ -563,6 +563,7 @@ | |||
| <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="agentStatus != null and agentStatus != ''"> and agent_status = #{agentStatus}</if> | |||
| </where> | |||
| GROUP BY town_code | |||
| ORDER BY town_code | |||
| @@ -583,6 +584,10 @@ | |||
| <result property="endAt" column="end_at"/> | |||
| <result property="handleNick" column="handle_nick"/> | |||
| <result property="numNotApproval" column="num_not_approval"/> | |||
| <result property="allCount" column="all_count"/> | |||
| <result property="finishCount" column="finish_count"/> | |||
| <result property="orderYear" column="order_year"/> | |||
| <result property="orderMonth" column="order_month"/> | |||
| </resultMap> | |||
| <select id="getAgentTaskGroupByVillage" parameterType="TAgentTask" resultMap="AgentTaskVillageGroupResultMap"> | |||
| @@ -592,7 +597,10 @@ | |||
| IFNULL(SUM(IF(is_audit = 'Y', 1, 0)), 0) as num_approval_finish, | |||
| org_name, org_code, town_code, | |||
| MAX(end_at) as end_at, MAX(handle_date) as handle_date, MAX(distri_date) as distri_date, handle_nick, | |||
| IFNULL(SUM(abnormal_count), 0) as num_except | |||
| IFNULL(SUM(abnormal_count), 0) as num_except, | |||
| IFNULL(SUM(all_count), 0) as all_count, | |||
| IFNULL(SUM(finish_count), 0) as finish_count, | |||
| order_year, order_month | |||
| FROM | |||
| t_agent_task | |||
| <where> | |||
| @@ -600,6 +608,7 @@ | |||
| <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="agentStatus != null and agentStatus != ''"> and agent_status = #{agentStatus}</if> | |||
| <if test="params != null"> | |||
| <if test="params.townCodeList != null"> | |||
| AND town_code IN (null <foreach collection="params.townCodeList" item="i">,#{i}</foreach> ) | |||
| @@ -625,6 +634,7 @@ | |||
| <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="agentStatus != null and agentStatus != ''"> and agent_status = #{agentStatus}</if> | |||
| <if test="params != null"> | |||
| <if test="params.townCodeList != null"> | |||
| AND town_code IN (null <foreach collection="params.townCodeList" item="i">,#{i}</foreach> ) | |||
| @@ -786,4 +796,26 @@ | |||
| ORDER BY org_code | |||
| </select> | |||
| <update id="revokeAgentTaskByOrgCode" parameterType="TAgentTask"> | |||
| update t_agent_task | |||
| <trim prefix="SET" suffixOverrides=","> | |||
| agent_status = '1', | |||
| distri_user = NULL, | |||
| distri_nick = NULL, | |||
| distri_date = NULL, | |||
| end_at = NULL, | |||
| handle_user = NULL, | |||
| handle_nick = NULL, | |||
| handle_remark = NULL, | |||
| handle_date = NULL, | |||
| <if test="updateBy != null">update_by = #{updateBy},</if> | |||
| <if test="updateTime != null">update_time = #{updateTime},</if> | |||
| </trim> | |||
| where | |||
| org_code = #{orgCode} | |||
| and order_year = #{orderYear} | |||
| and order_month = #{orderMonth} | |||
| and agent_status = '2' | |||
| </update> | |||
| </mapper> | |||