19 changed files with 1664 additions and 0 deletions
@ -0,0 +1,105 @@ |
|||
package com.zdxt.enforcementcode.controller; |
|||
|
|||
import java.util.List; |
|||
|
|||
import lombok.RequiredArgsConstructor; |
|||
import jakarta.servlet.http.HttpServletResponse; |
|||
import jakarta.validation.constraints.*; |
|||
import cn.dev33.satoken.annotation.SaCheckPermission; |
|||
import org.springframework.web.bind.annotation.*; |
|||
import org.springframework.validation.annotation.Validated; |
|||
import org.dromara.common.idempotent.annotation.RepeatSubmit; |
|||
import org.dromara.common.log.annotation.Log; |
|||
import org.dromara.common.web.core.BaseController; |
|||
import org.dromara.common.mybatis.core.page.PageQuery; |
|||
import org.dromara.common.core.domain.R; |
|||
import org.dromara.common.core.validate.AddGroup; |
|||
import org.dromara.common.core.validate.EditGroup; |
|||
import org.dromara.common.log.enums.BusinessType; |
|||
import org.dromara.common.excel.utils.ExcelUtil; |
|||
import com.zdxt.enforcementcode.domain.vo.ComplaintStatisticsVo; |
|||
import com.zdxt.enforcementcode.domain.bo.ComplaintStatisticsBo; |
|||
import com.zdxt.enforcementcode.service.IComplaintStatisticsService; |
|||
import org.dromara.common.mybatis.core.page.TableDataInfo; |
|||
|
|||
/** |
|||
* 【请填写功能名称】 |
|||
* |
|||
* @author Lion Li |
|||
* @date 2026-06-13 |
|||
*/ |
|||
@Validated |
|||
@RequiredArgsConstructor |
|||
@RestController |
|||
@RequestMapping("/enforcementcode/statistics") |
|||
public class ComplaintStatisticsController extends BaseController { |
|||
|
|||
private final IComplaintStatisticsService complaintStatisticsService; |
|||
|
|||
/** |
|||
* 查询【请填写功能名称】列表 |
|||
*/ |
|||
@SaCheckPermission("enforcementcode:statistics:list") |
|||
@GetMapping("/list") |
|||
public TableDataInfo<ComplaintStatisticsVo> list(ComplaintStatisticsBo bo, PageQuery pageQuery) { |
|||
return complaintStatisticsService.queryPageList(bo, pageQuery); |
|||
} |
|||
|
|||
/** |
|||
* 导出【请填写功能名称】列表 |
|||
*/ |
|||
@SaCheckPermission("enforcementcode:statistics:export") |
|||
@Log(title = "【请填写功能名称】", businessType = BusinessType.EXPORT) |
|||
@PostMapping("/export") |
|||
public void export(ComplaintStatisticsBo bo, HttpServletResponse response) { |
|||
List<ComplaintStatisticsVo> list = complaintStatisticsService.queryList(bo); |
|||
ExcelUtil.exportExcel(list, "【请填写功能名称】", ComplaintStatisticsVo.class, response); |
|||
} |
|||
|
|||
/** |
|||
* 获取【请填写功能名称】详细信息 |
|||
* |
|||
* @param id 主键 |
|||
*/ |
|||
@SaCheckPermission("enforcementcode:statistics:query") |
|||
@GetMapping("/{id}") |
|||
public R<ComplaintStatisticsVo> getInfo(@NotNull(message = "主键不能为空") |
|||
@PathVariable Long id) { |
|||
return R.ok(complaintStatisticsService.queryById(id)); |
|||
} |
|||
|
|||
/** |
|||
* 新增【请填写功能名称】 |
|||
*/ |
|||
@SaCheckPermission("enforcementcode:statistics:add") |
|||
@Log(title = "【请填写功能名称】", businessType = BusinessType.INSERT) |
|||
@RepeatSubmit() |
|||
@PostMapping() |
|||
public R<Void> add(@Validated(AddGroup.class) @RequestBody ComplaintStatisticsBo bo) { |
|||
return toAjax(complaintStatisticsService.insertByBo(bo)); |
|||
} |
|||
|
|||
/** |
|||
* 修改【请填写功能名称】 |
|||
*/ |
|||
@SaCheckPermission("enforcementcode:statistics:edit") |
|||
@Log(title = "【请填写功能名称】", businessType = BusinessType.UPDATE) |
|||
@RepeatSubmit() |
|||
@PutMapping() |
|||
public R<Void> edit(@Validated(EditGroup.class) @RequestBody ComplaintStatisticsBo bo) { |
|||
return toAjax(complaintStatisticsService.updateByBo(bo)); |
|||
} |
|||
|
|||
/** |
|||
* 删除【请填写功能名称】 |
|||
* |
|||
* @param ids 主键串 |
|||
*/ |
|||
@SaCheckPermission("enforcementcode:statistics:remove") |
|||
@Log(title = "【请填写功能名称】", businessType = BusinessType.DELETE) |
|||
@DeleteMapping("/{ids}") |
|||
public R<Void> remove(@NotEmpty(message = "主键不能为空") |
|||
@PathVariable Long[] ids) { |
|||
return toAjax(complaintStatisticsService.deleteWithValidByIds(List.of(ids), true)); |
|||
} |
|||
} |
|||
@ -0,0 +1,125 @@ |
|||
package com.zdxt.enforcementcode.controller.web.supervision.report; |
|||
|
|||
import com.zdxt.enforcementcode.domain.bo.ComplaintStatisticsBo; |
|||
import com.zdxt.enforcementcode.domain.vo.report.*; |
|||
import com.zdxt.enforcementcode.report.IStatisticsComplaintReport; |
|||
import jakarta.servlet.http.HttpServletResponse; |
|||
import lombok.RequiredArgsConstructor; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.dromara.common.core.domain.R; |
|||
import org.dromara.common.excel.utils.ExcelUtil; |
|||
import org.dromara.common.mybatis.core.page.PageQuery; |
|||
import org.dromara.common.mybatis.core.page.TableDataInfo; |
|||
import org.springframework.validation.annotation.Validated; |
|||
import org.springframework.web.bind.annotation.*; |
|||
|
|||
import java.util.List; |
|||
|
|||
/** |
|||
* 执法投诉情况报表 |
|||
* |
|||
* @author zdxt |
|||
*/ |
|||
@Slf4j |
|||
@Validated |
|||
@RequiredArgsConstructor |
|||
@RestController |
|||
@RequestMapping("/web/supervision/report/statistics-complaint") |
|||
public class StatisticsComplaintController { |
|||
|
|||
private final IStatisticsComplaintReport reportService; |
|||
|
|||
/** Tab1概览 */ |
|||
@GetMapping("/overview") |
|||
public R<ComplaintReportOverviewVo> overview(ComplaintStatisticsBo bo) { |
|||
return R.ok(reportService.overview(bo)); |
|||
} |
|||
|
|||
/** Tab1主表格:按部门分组 */ |
|||
@GetMapping("/groupList") |
|||
public TableDataInfo<ComplaintReportGroupVo> groupList(ComplaintStatisticsBo bo, PageQuery pageQuery) { |
|||
return reportService.groupList(bo, pageQuery); |
|||
} |
|||
|
|||
/** Tab1明细列表 */ |
|||
@GetMapping("/detailList") |
|||
public TableDataInfo<ComplaintReportDetailVo> detailList(ComplaintStatisticsBo bo, PageQuery pageQuery) { |
|||
return reportService.detailList(bo, pageQuery); |
|||
} |
|||
|
|||
/** Tab2-投诉类型统计 */ |
|||
@GetMapping("/typeStatList") |
|||
public R<List<ComplaintReportTypeStatVo>> typeStatList(ComplaintStatisticsBo bo) { |
|||
return R.ok(reportService.typeStatList(bo)); |
|||
} |
|||
|
|||
/** Tab2-区域统计 */ |
|||
@GetMapping("/areaStatList") |
|||
public R<List<ComplaintReportTypeStatVo>> areaStatList(ComplaintStatisticsBo bo) { |
|||
return R.ok(reportService.areaStatList(bo)); |
|||
} |
|||
|
|||
/** Tab2-街道统计 */ |
|||
@GetMapping("/streetStatList") |
|||
public R<List<ComplaintReportTypeStatVo>> streetStatList(ComplaintStatisticsBo bo) { |
|||
return R.ok(reportService.streetStatList(bo)); |
|||
} |
|||
|
|||
/** Tab1导出 */ |
|||
@PostMapping("/exportGroupList") |
|||
public void exportGroupList(ComplaintStatisticsBo bo, HttpServletResponse response) { |
|||
try { |
|||
List<ComplaintReportExportVo> list = reportService.exportGroupList(bo); |
|||
ExcelUtil.exportExcel(list, "执法投诉统计", ComplaintReportExportVo.class, response); |
|||
} catch (Exception e) { |
|||
log.error("导出执法投诉统计Excel异常", e); |
|||
handleExportError(response, e); |
|||
} |
|||
} |
|||
|
|||
/** Tab2投诉类型导出 */ |
|||
@PostMapping("/exportTypeStat") |
|||
public void exportTypeStat(ComplaintStatisticsBo bo, HttpServletResponse response) { |
|||
try { |
|||
List<ComplaintReportTypeExportVo> list = reportService.exportTypeStat(bo, "type"); |
|||
ExcelUtil.exportExcel(list, "投诉类型统计", ComplaintReportTypeExportVo.class, response); |
|||
} catch (Exception e) { |
|||
log.error("导出投诉类型统计Excel异常", e); |
|||
handleExportError(response, e); |
|||
} |
|||
} |
|||
|
|||
/** Tab2区域导出 */ |
|||
@PostMapping("/exportAreaStat") |
|||
public void exportAreaStat(ComplaintStatisticsBo bo, HttpServletResponse response) { |
|||
try { |
|||
List<ComplaintReportTypeExportVo> list = reportService.exportTypeStat(bo, "area"); |
|||
ExcelUtil.exportExcel(list, "区域投诉统计", ComplaintReportTypeExportVo.class, response); |
|||
} catch (Exception e) { |
|||
log.error("导出区域投诉统计Excel异常", e); |
|||
handleExportError(response, e); |
|||
} |
|||
} |
|||
|
|||
/** Tab2街道导出 */ |
|||
@PostMapping("/exportStreetStat") |
|||
public void exportStreetStat(ComplaintStatisticsBo bo, HttpServletResponse response) { |
|||
try { |
|||
List<ComplaintReportTypeExportVo> list = reportService.exportTypeStat(bo, "street"); |
|||
ExcelUtil.exportExcel(list, "街道投诉统计", ComplaintReportTypeExportVo.class, response); |
|||
} catch (Exception e) { |
|||
log.error("导出街道投诉统计Excel异常", e); |
|||
handleExportError(response, e); |
|||
} |
|||
} |
|||
|
|||
private void handleExportError(HttpServletResponse response, Exception e) { |
|||
response.reset(); |
|||
response.setContentType("application/json; charset=utf-8"); |
|||
try { |
|||
response.getWriter().write("{\"code\":500,\"msg\":\"导出失败: " + e.getMessage() + "\"}"); |
|||
} catch (Exception ignored) { |
|||
} |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,98 @@ |
|||
package com.zdxt.enforcementcode.domain; |
|||
|
|||
import org.dromara.common.mybatis.core.domain.BaseEntity; |
|||
import com.baomidou.mybatisplus.annotation.*; |
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
import java.util.Date; |
|||
import com.fasterxml.jackson.annotation.JsonFormat; |
|||
|
|||
import java.io.Serial; |
|||
|
|||
/** |
|||
* 【请填写功能名称】对象 complaint_statistics |
|||
* |
|||
* @author Lion Li |
|||
* @date 2026-06-13 |
|||
*/ |
|||
@Data |
|||
@EqualsAndHashCode(callSuper = true) |
|||
@TableName("complaint_statistics") |
|||
public class ComplaintStatistics extends BaseEntity { |
|||
|
|||
@Serial |
|||
private static final long serialVersionUID = 1L; |
|||
|
|||
/** |
|||
* 主键 |
|||
*/ |
|||
@TableId(value = "id") |
|||
private Long id; |
|||
|
|||
/** |
|||
* 投诉表id |
|||
*/ |
|||
private String cid; |
|||
|
|||
/** |
|||
* 执法表id |
|||
*/ |
|||
private String rid; |
|||
|
|||
/** |
|||
* 投诉时间 |
|||
*/ |
|||
private Date complaintTime; |
|||
|
|||
/** |
|||
* 投诉类型 |
|||
*/ |
|||
private Long complaintType; |
|||
|
|||
/** |
|||
* 被投诉部门 |
|||
*/ |
|||
private String complaintDepartment; |
|||
|
|||
/** |
|||
* 被投诉部门id |
|||
*/ |
|||
private String complaintDepartmentId; |
|||
|
|||
/** |
|||
* 企业名称 |
|||
*/ |
|||
private String enterpriseName; |
|||
|
|||
/** |
|||
* 企业纳税识别号 |
|||
*/ |
|||
private String enterpriseNumber; |
|||
|
|||
/** |
|||
* 投诉类型 |
|||
*/ |
|||
private Long enforceType; |
|||
|
|||
/** |
|||
* 问题描述 |
|||
*/ |
|||
private String problemDescription; |
|||
|
|||
/** |
|||
* 联系人 |
|||
*/ |
|||
private String linkman; |
|||
|
|||
/** |
|||
* 联系方式 |
|||
*/ |
|||
private String linkmanTel; |
|||
|
|||
/** |
|||
* 涉事地址 |
|||
*/ |
|||
private String enterpriseAddress; |
|||
|
|||
|
|||
} |
|||
@ -0,0 +1,138 @@ |
|||
package com.zdxt.enforcementcode.domain.bo; |
|||
|
|||
import com.zdxt.enforcementcode.domain.ComplaintStatistics; |
|||
import org.dromara.common.mybatis.core.domain.BaseEntity; |
|||
import org.dromara.common.core.validate.AddGroup; |
|||
import org.dromara.common.core.validate.EditGroup; |
|||
import io.github.linpeilie.annotations.AutoMapper; |
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
import jakarta.validation.constraints.*; |
|||
import java.util.Date; |
|||
import java.util.List; |
|||
import com.fasterxml.jackson.annotation.JsonFormat; |
|||
|
|||
/** |
|||
* 投诉统计业务对象 complaint_statistics |
|||
* |
|||
* @author zdxt |
|||
*/ |
|||
@Data |
|||
@EqualsAndHashCode(callSuper = true) |
|||
@AutoMapper(target = ComplaintStatistics.class, reverseConvertGenerate = false) |
|||
public class ComplaintStatisticsBo extends BaseEntity { |
|||
|
|||
/** |
|||
* 主键 |
|||
*/ |
|||
@NotNull(message = "主键不能为空", groups = { EditGroup.class }) |
|||
private Long id; |
|||
|
|||
/** |
|||
* 投诉表id |
|||
*/ |
|||
private String cid; |
|||
|
|||
/** |
|||
* 执法表id |
|||
*/ |
|||
private String rid; |
|||
|
|||
/** |
|||
* 投诉时间 |
|||
*/ |
|||
private Date complaintTime; |
|||
|
|||
/** |
|||
* 投诉类型 |
|||
*/ |
|||
private Long complaintType; |
|||
|
|||
/** |
|||
* 被投诉部门 |
|||
*/ |
|||
private String complaintDepartment; |
|||
|
|||
/** |
|||
* 被投诉部门id |
|||
*/ |
|||
private String complaintDepartmentId; |
|||
|
|||
/** |
|||
* 企业名称 |
|||
*/ |
|||
private String enterpriseName; |
|||
|
|||
/** |
|||
* 企业纳税识别号 |
|||
*/ |
|||
private String enterpriseNumber; |
|||
|
|||
/** |
|||
* 投诉类型(字典 caseType) |
|||
*/ |
|||
private Long enforceType; |
|||
|
|||
/** |
|||
* 问题描述 |
|||
*/ |
|||
private String problemDescription; |
|||
|
|||
/** |
|||
* 联系人 |
|||
*/ |
|||
private String linkman; |
|||
|
|||
/** |
|||
* 联系方式 |
|||
*/ |
|||
private String linkmanTel; |
|||
|
|||
/** |
|||
* 涉事地址 |
|||
*/ |
|||
private String enterpriseAddress; |
|||
|
|||
// ===== 报表查询条件字段 =====
|
|||
|
|||
/** |
|||
* 年 |
|||
*/ |
|||
private String year; |
|||
|
|||
/** |
|||
* 季度 |
|||
*/ |
|||
private String quarter; |
|||
|
|||
/** |
|||
* 月 |
|||
*/ |
|||
private String month; |
|||
|
|||
/** |
|||
* 自定义开始时间 |
|||
*/ |
|||
private String beginTime; |
|||
|
|||
/** |
|||
* 自定义结束时间 |
|||
*/ |
|||
private String endTime; |
|||
|
|||
/** |
|||
* 时段类型:year/quarter/month/day |
|||
*/ |
|||
private String timeType; |
|||
|
|||
/** |
|||
* Tab2类型切换:type/空/区域dict_value |
|||
*/ |
|||
private String type; |
|||
|
|||
/** |
|||
* 被投诉对象deptId列表(模糊搜索后填充) |
|||
*/ |
|||
private List<String> complaintDepartmentIdList; |
|||
|
|||
} |
|||
@ -0,0 +1,118 @@ |
|||
package com.zdxt.enforcementcode.domain.vo; |
|||
|
|||
import java.util.Date; |
|||
import com.fasterxml.jackson.annotation.JsonFormat; |
|||
import com.zdxt.enforcementcode.domain.ComplaintStatistics; |
|||
import cn.idev.excel.annotation.ExcelIgnoreUnannotated; |
|||
import cn.idev.excel.annotation.ExcelProperty; |
|||
import org.dromara.common.excel.annotation.ExcelDictFormat; |
|||
import org.dromara.common.excel.convert.ExcelDictConvert; |
|||
import io.github.linpeilie.annotations.AutoMapper; |
|||
import lombok.Data; |
|||
|
|||
import java.io.Serial; |
|||
import java.io.Serializable; |
|||
import java.util.Date; |
|||
|
|||
|
|||
|
|||
/** |
|||
* 【请填写功能名称】视图对象 complaint_statistics |
|||
* |
|||
* @author Lion Li |
|||
* @date 2026-06-13 |
|||
*/ |
|||
@Data |
|||
@ExcelIgnoreUnannotated |
|||
@AutoMapper(target = ComplaintStatistics.class) |
|||
public class ComplaintStatisticsVo implements Serializable { |
|||
|
|||
@Serial |
|||
private static final long serialVersionUID = 1L; |
|||
|
|||
/** |
|||
* 主键 |
|||
*/ |
|||
@ExcelProperty(value = "主键") |
|||
private Long id; |
|||
|
|||
/** |
|||
* 投诉表id |
|||
*/ |
|||
@ExcelProperty(value = "投诉表id") |
|||
private String cid; |
|||
|
|||
/** |
|||
* 执法表id |
|||
*/ |
|||
@ExcelProperty(value = "执法表id") |
|||
private String rid; |
|||
|
|||
/** |
|||
* 投诉时间 |
|||
*/ |
|||
@ExcelProperty(value = "投诉时间") |
|||
private Date complaintTime; |
|||
|
|||
/** |
|||
* 投诉类型 |
|||
*/ |
|||
@ExcelProperty(value = "投诉类型") |
|||
private Long complaintType; |
|||
|
|||
/** |
|||
* 被投诉部门 |
|||
*/ |
|||
@ExcelProperty(value = "被投诉部门") |
|||
private String complaintDepartment; |
|||
|
|||
/** |
|||
* 被投诉部门id |
|||
*/ |
|||
@ExcelProperty(value = "被投诉部门id") |
|||
private String complaintDepartmentId; |
|||
|
|||
/** |
|||
* 企业名称 |
|||
*/ |
|||
@ExcelProperty(value = "企业名称") |
|||
private String enterpriseName; |
|||
|
|||
/** |
|||
* 企业纳税识别号 |
|||
*/ |
|||
@ExcelProperty(value = "企业纳税识别号") |
|||
private String enterpriseNumber; |
|||
|
|||
/** |
|||
* 投诉类型 |
|||
*/ |
|||
@ExcelProperty(value = "投诉类型") |
|||
private Long enforceType; |
|||
|
|||
/** |
|||
* 问题描述 |
|||
*/ |
|||
@ExcelProperty(value = "问题描述") |
|||
private String problemDescription; |
|||
|
|||
/** |
|||
* 联系人 |
|||
*/ |
|||
@ExcelProperty(value = "联系人") |
|||
private String linkman; |
|||
|
|||
/** |
|||
* 联系方式 |
|||
*/ |
|||
@ExcelProperty(value = "联系方式") |
|||
private String linkmanTel; |
|||
|
|||
/** |
|||
* 涉事地址 |
|||
*/ |
|||
@ExcelProperty(value = "涉事地址") |
|||
private String enterpriseAddress; |
|||
|
|||
|
|||
} |
|||
@ -0,0 +1,36 @@ |
|||
package com.zdxt.enforcementcode.domain.vo.report; |
|||
|
|||
import lombok.Data; |
|||
|
|||
import java.io.Serial; |
|||
import java.io.Serializable; |
|||
|
|||
/** |
|||
* 执法投诉情况报表 — Tab1 明细VO |
|||
* |
|||
* @author zdxt |
|||
*/ |
|||
@Data |
|||
public class ComplaintReportDetailVo implements Serializable { |
|||
|
|||
@Serial |
|||
private static final long serialVersionUID = 1L; |
|||
|
|||
/** 主键ID */ |
|||
private Long id; |
|||
|
|||
/** 投诉表ID */ |
|||
private String cid; |
|||
|
|||
/** 被投诉对象 */ |
|||
private String complaintDepartment; |
|||
|
|||
/** 投诉类型值(字典 caseType) */ |
|||
private Long enforceType; |
|||
|
|||
/** 投诉类型翻译 */ |
|||
private String enforceTypeText; |
|||
|
|||
/** 投诉时间(格式化字符串) */ |
|||
private String complaintTime; |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
package com.zdxt.enforcementcode.domain.vo.report; |
|||
|
|||
import cn.idev.excel.annotation.ExcelIgnoreUnannotated; |
|||
import cn.idev.excel.annotation.ExcelProperty; |
|||
import lombok.Data; |
|||
|
|||
import java.io.Serial; |
|||
import java.io.Serializable; |
|||
|
|||
/** |
|||
* 执法投诉情况报表 — Tab1 导出VO |
|||
* |
|||
* @author zdxt |
|||
*/ |
|||
@Data |
|||
@ExcelIgnoreUnannotated |
|||
public class ComplaintReportExportVo implements Serializable { |
|||
|
|||
@Serial |
|||
private static final long serialVersionUID = 1L; |
|||
|
|||
@ExcelProperty(value = "被投诉对象") |
|||
private String complaintDepartment; |
|||
|
|||
@ExcelProperty(value = "投诉数量") |
|||
private int total; |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
package com.zdxt.enforcementcode.domain.vo.report; |
|||
|
|||
import lombok.Data; |
|||
|
|||
import java.io.Serial; |
|||
import java.io.Serializable; |
|||
|
|||
/** |
|||
* 执法投诉情况报表 — Tab1 分组统计VO |
|||
* |
|||
* @author zdxt |
|||
*/ |
|||
@Data |
|||
public class ComplaintReportGroupVo implements Serializable { |
|||
|
|||
@Serial |
|||
private static final long serialVersionUID = 1L; |
|||
|
|||
/** 被投诉对象名称 */ |
|||
private String complaintDepartment; |
|||
|
|||
/** 被投诉部门ID */ |
|||
private String complaintDepartmentId; |
|||
|
|||
/** 投诉数量 */ |
|||
private int total; |
|||
} |
|||
@ -0,0 +1,24 @@ |
|||
package com.zdxt.enforcementcode.domain.vo.report; |
|||
|
|||
import lombok.Data; |
|||
|
|||
import java.io.Serial; |
|||
import java.io.Serializable; |
|||
|
|||
/** |
|||
* 执法投诉情况报表 — Tab1 概览VO |
|||
* |
|||
* @author zdxt |
|||
*/ |
|||
@Data |
|||
public class ComplaintReportOverviewVo implements Serializable { |
|||
|
|||
@Serial |
|||
private static final long serialVersionUID = 1L; |
|||
|
|||
/** 投诉数量 */ |
|||
private int complaintCount; |
|||
|
|||
/** 被投诉对象数 */ |
|||
private int complaintDeptCount; |
|||
} |
|||
@ -0,0 +1,30 @@ |
|||
package com.zdxt.enforcementcode.domain.vo.report; |
|||
|
|||
import cn.idev.excel.annotation.ExcelIgnoreUnannotated; |
|||
import cn.idev.excel.annotation.ExcelProperty; |
|||
import lombok.Data; |
|||
|
|||
import java.io.Serial; |
|||
import java.io.Serializable; |
|||
|
|||
/** |
|||
* 执法投诉情况报表 — Tab2 导出VO(投诉类型/区域/街道 通用) |
|||
* |
|||
* @author zdxt |
|||
*/ |
|||
@Data |
|||
@ExcelIgnoreUnannotated |
|||
public class ComplaintReportTypeExportVo implements Serializable { |
|||
|
|||
@Serial |
|||
private static final long serialVersionUID = 1L; |
|||
|
|||
@ExcelProperty(value = "名称") |
|||
private String name; |
|||
|
|||
@ExcelProperty(value = "数量") |
|||
private int count; |
|||
|
|||
@ExcelProperty(value = "占比") |
|||
private String percentage; |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
package com.zdxt.enforcementcode.domain.vo.report; |
|||
|
|||
import lombok.Data; |
|||
|
|||
import java.io.Serial; |
|||
import java.io.Serializable; |
|||
|
|||
/** |
|||
* 执法投诉情况报表 — Tab2 统计VO(投诉类型/区域/街道 通用) |
|||
* |
|||
* @author zdxt |
|||
*/ |
|||
@Data |
|||
public class ComplaintReportTypeStatVo implements Serializable { |
|||
|
|||
@Serial |
|||
private static final long serialVersionUID = 1L; |
|||
|
|||
/** 名称(类型名/区域名/街道名) */ |
|||
private String name; |
|||
|
|||
/** 数量 */ |
|||
private int count; |
|||
|
|||
/** 占比字符串(如 "12.34%") */ |
|||
private String percentage; |
|||
} |
|||
@ -0,0 +1,38 @@ |
|||
package com.zdxt.enforcementcode.mapper; |
|||
|
|||
import com.zdxt.enforcementcode.domain.ComplaintStatistics; |
|||
import com.zdxt.enforcementcode.domain.bo.ComplaintStatisticsBo; |
|||
import com.zdxt.enforcementcode.domain.vo.ComplaintStatisticsVo; |
|||
import com.zdxt.enforcementcode.domain.vo.report.ComplaintReportDetailVo; |
|||
import com.zdxt.enforcementcode.domain.vo.report.ComplaintReportGroupVo; |
|||
import org.apache.ibatis.annotations.Param; |
|||
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; |
|||
|
|||
import java.util.List; |
|||
|
|||
/** |
|||
* 投诉统计 Mapper接口 |
|||
* |
|||
* @author zdxt |
|||
*/ |
|||
public interface ComplaintStatisticsMapper extends BaseMapperPlus<ComplaintStatistics, ComplaintStatisticsVo> { |
|||
|
|||
/** Tab1:按部门分组统计 */ |
|||
List<ComplaintReportGroupVo> selectComplaintGroupByDept(@Param("bo") ComplaintStatisticsBo bo); |
|||
|
|||
/** Tab1:投诉明细列表 */ |
|||
List<ComplaintReportDetailVo> selectComplaintDetailList(@Param("bo") ComplaintStatisticsBo bo); |
|||
|
|||
/** Tab1概览:投诉总数 */ |
|||
int selectComplaintCount(@Param("bo") ComplaintStatisticsBo bo); |
|||
|
|||
/** Tab1概览:被投诉对象数 */ |
|||
int selectComplaintDeptCount(@Param("bo") ComplaintStatisticsBo bo); |
|||
|
|||
/** Tab2:查全量投诉列表(含enforce_type)用于Java层投诉类型分组 */ |
|||
List<ComplaintStatistics> selectComplaintListForTypeStat(@Param("bo") ComplaintStatisticsBo bo); |
|||
|
|||
/** Tab2:查全量投诉列表(含enterprise_address)用于Java层区域/街道分组 */ |
|||
List<ComplaintStatistics> selectComplaintListForAreaStat(@Param("bo") ComplaintStatisticsBo bo); |
|||
} |
|||
|
|||
@ -0,0 +1,41 @@ |
|||
package com.zdxt.enforcementcode.report; |
|||
|
|||
import com.zdxt.enforcementcode.domain.bo.ComplaintStatisticsBo; |
|||
import com.zdxt.enforcementcode.domain.vo.report.*; |
|||
import org.dromara.common.mybatis.core.page.PageQuery; |
|||
import org.dromara.common.mybatis.core.page.TableDataInfo; |
|||
|
|||
import java.util.List; |
|||
|
|||
/** |
|||
* 执法投诉情况报表 Service接口 |
|||
* |
|||
* @author zdxt |
|||
*/ |
|||
public interface IStatisticsComplaintReport { |
|||
|
|||
/** Tab1概览:投诉数量 + 被投诉对象数 */ |
|||
ComplaintReportOverviewVo overview(ComplaintStatisticsBo bo); |
|||
|
|||
/** Tab1主表格:按部门分组统计(含手动分页) */ |
|||
TableDataInfo<ComplaintReportGroupVo> groupList(ComplaintStatisticsBo bo, PageQuery pageQuery); |
|||
|
|||
/** Tab1明细列表:某部门的投诉明细(含手动分页) */ |
|||
TableDataInfo<ComplaintReportDetailVo> detailList(ComplaintStatisticsBo bo, PageQuery pageQuery); |
|||
|
|||
/** Tab2-投诉类型统计 */ |
|||
List<ComplaintReportTypeStatVo> typeStatList(ComplaintStatisticsBo bo); |
|||
|
|||
/** Tab2-区域统计 */ |
|||
List<ComplaintReportTypeStatVo> areaStatList(ComplaintStatisticsBo bo); |
|||
|
|||
/** Tab2-街道统计 */ |
|||
List<ComplaintReportTypeStatVo> streetStatList(ComplaintStatisticsBo bo); |
|||
|
|||
/** Tab1导出 */ |
|||
List<ComplaintReportExportVo> exportGroupList(ComplaintStatisticsBo bo); |
|||
|
|||
/** Tab2导出(投诉类型/区域/街道 通用) */ |
|||
List<ComplaintReportTypeExportVo> exportTypeStat(ComplaintStatisticsBo bo, String statType); |
|||
} |
|||
|
|||
@ -0,0 +1,313 @@ |
|||
package com.zdxt.enforcementcode.report.impl; |
|||
|
|||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
|||
import com.zdxt.enforcementcode.domain.ComplaintStatistics; |
|||
import com.zdxt.enforcementcode.domain.bo.ComplaintStatisticsBo; |
|||
import com.zdxt.enforcementcode.domain.vo.report.*; |
|||
import com.zdxt.enforcementcode.mapper.ComplaintStatisticsMapper; |
|||
import com.zdxt.enforcementcode.report.IStatisticsComplaintReport; |
|||
import lombok.RequiredArgsConstructor; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.dromara.common.core.domain.dto.DictDataDTO; |
|||
import org.dromara.common.core.service.DictService; |
|||
import org.dromara.common.core.utils.StringUtils; |
|||
import org.dromara.common.mybatis.core.page.PageQuery; |
|||
import org.dromara.common.mybatis.core.page.TableDataInfo; |
|||
import org.dromara.system.service.ISysDeptService; |
|||
import org.dromara.system.domain.vo.SysDeptVo; |
|||
import org.springframework.stereotype.Service; |
|||
|
|||
import java.math.BigDecimal; |
|||
import java.math.RoundingMode; |
|||
import java.util.*; |
|||
import java.util.stream.Collectors; |
|||
|
|||
/** |
|||
* 执法投诉情况报表 Service实现 |
|||
* <p> |
|||
* 复刻旧系统 ComplaintStatisticsImpl 逻辑: |
|||
* - Tab1: 按 complaint_department_id 分组统计 + JOIN sys_dept 翻译名称 |
|||
* - Tab2: Java层按 enforceType/enterprise_address 分组,字典翻译 |
|||
* <p> |
|||
* 不使用 DataFilterUtil 进行数据过滤 |
|||
* |
|||
* @author zdxt |
|||
*/ |
|||
@Slf4j |
|||
@RequiredArgsConstructor |
|||
@Service |
|||
public class StatisticsComplaintReportImpl implements IStatisticsComplaintReport { |
|||
|
|||
private final ComplaintStatisticsMapper complaintStatisticsMapper; |
|||
private final ISysDeptService sysDeptService; |
|||
private final DictService dictService; |
|||
|
|||
@Override |
|||
public ComplaintReportOverviewVo overview(ComplaintStatisticsBo bo) { |
|||
// 处理被投诉对象模糊搜索
|
|||
fillDeptIdListByName(bo); |
|||
|
|||
ComplaintReportOverviewVo vo = new ComplaintReportOverviewVo(); |
|||
vo.setComplaintCount(complaintStatisticsMapper.selectComplaintCount(bo)); |
|||
vo.setComplaintDeptCount(complaintStatisticsMapper.selectComplaintDeptCount(bo)); |
|||
return vo; |
|||
} |
|||
|
|||
@Override |
|||
public TableDataInfo<ComplaintReportGroupVo> groupList(ComplaintStatisticsBo bo, PageQuery pageQuery) { |
|||
// 处理被投诉对象模糊搜索
|
|||
fillDeptIdListByName(bo); |
|||
|
|||
// 全量查询分组数据
|
|||
List<ComplaintReportGroupVo> allList = complaintStatisticsMapper.selectComplaintGroupByDept(bo); |
|||
|
|||
// 手动分页
|
|||
int pageNum = pageQuery.getPageNum(); |
|||
int pageSize = pageQuery.getPageSize(); |
|||
int total = allList.size(); |
|||
int fromIndex = Math.min((pageNum - 1) * pageSize, total); |
|||
int toIndex = Math.min(fromIndex + pageSize, total); |
|||
List<ComplaintReportGroupVo> pageRecords = allList.subList(fromIndex, toIndex); |
|||
|
|||
Page<ComplaintReportGroupVo> page = new Page<>(pageNum, pageSize, total); |
|||
page.setRecords(pageRecords); |
|||
return TableDataInfo.build(page); |
|||
} |
|||
|
|||
@Override |
|||
public TableDataInfo<ComplaintReportDetailVo> detailList(ComplaintStatisticsBo bo, PageQuery pageQuery) { |
|||
// 全量查询明细
|
|||
List<ComplaintReportDetailVo> allList = complaintStatisticsMapper.selectComplaintDetailList(bo); |
|||
|
|||
// 字典翻译 enforceType -> enforceTypeText
|
|||
Map<String, String> caseTypeDict = dictService.getAllDictByDictType("caseType"); |
|||
for (ComplaintReportDetailVo item : allList) { |
|||
if (item.getEnforceType() != null) { |
|||
String label = caseTypeDict.get(String.valueOf(item.getEnforceType())); |
|||
item.setEnforceTypeText(label != null ? label : String.valueOf(item.getEnforceType())); |
|||
} |
|||
} |
|||
|
|||
// 手动分页
|
|||
int pageNum = pageQuery.getPageNum(); |
|||
int pageSize = pageQuery.getPageSize(); |
|||
int total = allList.size(); |
|||
int fromIndex = Math.min((pageNum - 1) * pageSize, total); |
|||
int toIndex = Math.min(fromIndex + pageSize, total); |
|||
List<ComplaintReportDetailVo> pageRecords = allList.subList(fromIndex, toIndex); |
|||
|
|||
Page<ComplaintReportDetailVo> page = new Page<>(pageNum, pageSize, total); |
|||
page.setRecords(pageRecords); |
|||
return TableDataInfo.build(page); |
|||
} |
|||
|
|||
@Override |
|||
public List<ComplaintReportTypeStatVo> typeStatList(ComplaintStatisticsBo bo) { |
|||
// 复刻旧系统 type() 逻辑
|
|||
List<ComplaintStatistics> list = complaintStatisticsMapper.selectComplaintListForTypeStat(bo); |
|||
Map<String, String> caseTypeDict = dictService.getAllDictByDictType("caseType"); |
|||
int totalCount = list.size(); |
|||
|
|||
// 按 enforceType 分组计数
|
|||
Map<Long, Long> groupMap = list.stream() |
|||
.filter(item -> item.getEnforceType() != null) |
|||
.collect(Collectors.groupingBy(ComplaintStatistics::getEnforceType, Collectors.counting())); |
|||
|
|||
List<ComplaintReportTypeStatVo> result = new ArrayList<>(); |
|||
for (Map.Entry<Long, Long> entry : groupMap.entrySet()) { |
|||
ComplaintReportTypeStatVo vo = new ComplaintReportTypeStatVo(); |
|||
String label = caseTypeDict.get(String.valueOf(entry.getKey())); |
|||
vo.setName(label != null ? label : String.valueOf(entry.getKey())); |
|||
vo.setCount(entry.getValue().intValue()); |
|||
vo.setPercentage(calcPercentage(entry.getValue().intValue(), totalCount)); |
|||
result.add(vo); |
|||
} |
|||
// 按数量降序
|
|||
result.sort((a, b) -> b.getCount() - a.getCount()); |
|||
return result; |
|||
} |
|||
|
|||
@Override |
|||
public List<ComplaintReportTypeStatVo> areaStatList(ComplaintStatisticsBo bo) { |
|||
// 复刻旧系统 qyComplaintList() 逻辑
|
|||
List<ComplaintStatistics> list = complaintStatisticsMapper.selectComplaintListForAreaStat(bo); |
|||
int totalCount = list.size(); |
|||
|
|||
// 获取区域字典 address_type
|
|||
List<DictDataDTO> areaDictList = dictService.getDictData("address_type"); |
|||
|
|||
List<ComplaintReportTypeStatVo> result = new ArrayList<>(); |
|||
List<ComplaintStatistics> remaining = new ArrayList<>(list); |
|||
|
|||
for (DictDataDTO dict : areaDictList) { |
|||
String areaLabel = dict.getDictLabel(); // 如 "福田区"
|
|||
// 构建匹配前缀:去掉"区"或"新区"后缀,再加回
|
|||
String prefix = buildAreaPrefix(areaLabel); |
|||
|
|||
List<ComplaintStatistics> matched = remaining.stream() |
|||
.filter(item -> item.getEnterpriseAddress() != null && item.getEnterpriseAddress().startsWith(prefix)) |
|||
.collect(Collectors.toList()); |
|||
|
|||
ComplaintReportTypeStatVo vo = new ComplaintReportTypeStatVo(); |
|||
vo.setName(areaLabel); |
|||
vo.setCount(matched.size()); |
|||
vo.setPercentage(calcPercentage(matched.size(), totalCount)); |
|||
result.add(vo); |
|||
|
|||
remaining.removeAll(matched); |
|||
} |
|||
|
|||
// 剩余归入"其他"
|
|||
if (!remaining.isEmpty()) { |
|||
ComplaintReportTypeStatVo otherVo = new ComplaintReportTypeStatVo(); |
|||
otherVo.setName("其他"); |
|||
otherVo.setCount(remaining.size()); |
|||
otherVo.setPercentage(calcPercentage(remaining.size(), totalCount)); |
|||
result.add(otherVo); |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
|
|||
@Override |
|||
public List<ComplaintReportTypeStatVo> streetStatList(ComplaintStatisticsBo bo) { |
|||
// 复刻旧系统 jdComplaintList() 逻辑
|
|||
// bo.type = 选中区域的 dict_value(作为街道字典的 dict_type)
|
|||
String areaDictValue = bo.getType(); |
|||
if (StringUtils.isBlank(areaDictValue)) { |
|||
return new ArrayList<>(); |
|||
} |
|||
|
|||
// 获取区域名称(通过 address_type 字典查对应 label)
|
|||
String areaLabel = dictService.getDictLabel("address_type", areaDictValue); |
|||
String areaPrefix = buildAreaPrefix(areaLabel); |
|||
|
|||
// 获取全量投诉数据(含地址)
|
|||
List<ComplaintStatistics> allList = complaintStatisticsMapper.selectComplaintListForAreaStat(bo); |
|||
|
|||
// 先过滤出该区的记录
|
|||
List<ComplaintStatistics> areaList = allList.stream() |
|||
.filter(item -> item.getEnterpriseAddress() != null && item.getEnterpriseAddress().startsWith(areaPrefix)) |
|||
.collect(Collectors.toList()); |
|||
|
|||
int totalCount = areaList.size(); |
|||
|
|||
// 获取街道字典(dict_type = areaDictValue)
|
|||
List<DictDataDTO> streetDictList = dictService.getDictData(areaDictValue); |
|||
|
|||
List<ComplaintReportTypeStatVo> result = new ArrayList<>(); |
|||
List<ComplaintStatistics> remaining = new ArrayList<>(areaList); |
|||
|
|||
for (DictDataDTO dict : streetDictList) { |
|||
String streetLabel = dict.getDictLabel(); // 如 "福田街道"
|
|||
String streetPrefix = areaPrefix + streetLabel; |
|||
|
|||
List<ComplaintStatistics> matched = remaining.stream() |
|||
.filter(item -> item.getEnterpriseAddress() != null && item.getEnterpriseAddress().startsWith(streetPrefix)) |
|||
.collect(Collectors.toList()); |
|||
|
|||
ComplaintReportTypeStatVo vo = new ComplaintReportTypeStatVo(); |
|||
vo.setName(streetLabel); |
|||
vo.setCount(matched.size()); |
|||
vo.setPercentage(calcPercentage(matched.size(), totalCount)); |
|||
result.add(vo); |
|||
|
|||
remaining.removeAll(matched); |
|||
} |
|||
|
|||
// 剩余归入"其他"
|
|||
if (!remaining.isEmpty()) { |
|||
ComplaintReportTypeStatVo otherVo = new ComplaintReportTypeStatVo(); |
|||
otherVo.setName("其他"); |
|||
otherVo.setCount(remaining.size()); |
|||
otherVo.setPercentage(calcPercentage(remaining.size(), totalCount)); |
|||
result.add(otherVo); |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
|
|||
@Override |
|||
public List<ComplaintReportExportVo> exportGroupList(ComplaintStatisticsBo bo) { |
|||
fillDeptIdListByName(bo); |
|||
List<ComplaintReportGroupVo> allList = complaintStatisticsMapper.selectComplaintGroupByDept(bo); |
|||
return allList.stream().map(item -> { |
|||
ComplaintReportExportVo exportVo = new ComplaintReportExportVo(); |
|||
exportVo.setComplaintDepartment(item.getComplaintDepartment()); |
|||
exportVo.setTotal(item.getTotal()); |
|||
return exportVo; |
|||
}).collect(Collectors.toList()); |
|||
} |
|||
|
|||
@Override |
|||
public List<ComplaintReportTypeExportVo> exportTypeStat(ComplaintStatisticsBo bo, String statType) { |
|||
List<ComplaintReportTypeStatVo> statList; |
|||
if ("type".equals(statType)) { |
|||
statList = typeStatList(bo); |
|||
} else if ("area".equals(statType)) { |
|||
statList = areaStatList(bo); |
|||
} else { |
|||
statList = streetStatList(bo); |
|||
} |
|||
return statList.stream().map(item -> { |
|||
ComplaintReportTypeExportVo exportVo = new ComplaintReportTypeExportVo(); |
|||
exportVo.setName(item.getName()); |
|||
exportVo.setCount(item.getCount()); |
|||
exportVo.setPercentage(item.getPercentage()); |
|||
return exportVo; |
|||
}).collect(Collectors.toList()); |
|||
} |
|||
|
|||
// ===== 私有方法 =====
|
|||
|
|||
/** |
|||
* 处理被投诉对象模糊搜索:通过 complaintDepartment 查询 sys_dept 获取 deptIdList |
|||
*/ |
|||
private void fillDeptIdListByName(ComplaintStatisticsBo bo) { |
|||
if (StringUtils.isNotBlank(bo.getComplaintDepartment())) { |
|||
List<SysDeptVo> deptList = sysDeptService.selectDeptByDeptName(bo.getComplaintDepartment()); |
|||
if (deptList != null && !deptList.isEmpty()) { |
|||
List<String> idList = deptList.stream() |
|||
.map(SysDeptVo::getDeptId) |
|||
.collect(Collectors.toList()); |
|||
bo.setComplaintDepartmentIdList(idList); |
|||
} else { |
|||
// 如果模糊搜索没有匹配,设为不可能匹配的值,让结果为空
|
|||
bo.setComplaintDepartmentIdList(Collections.singletonList("-1")); |
|||
} |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 构建区域匹配前缀 |
|||
* 复刻旧系统逻辑:enterprise_address.startsWith("深圳市" + 区名去"区"后 + "区") |
|||
* 如 "福田区" -> "深圳市福田区" |
|||
* 如 "光明区" -> "深圳市光明区"(同时尝试"新区") |
|||
*/ |
|||
private String buildAreaPrefix(String areaLabel) { |
|||
if (StringUtils.isBlank(areaLabel)) { |
|||
return "深圳市"; |
|||
} |
|||
// 去掉"区"或"新区"后缀,再拼接回来
|
|||
String name = areaLabel; |
|||
if (name.endsWith("新区")) { |
|||
name = name.substring(0, name.length() - 2); |
|||
} else if (name.endsWith("区")) { |
|||
name = name.substring(0, name.length() - 1); |
|||
} |
|||
return "深圳市" + name + "区"; |
|||
} |
|||
|
|||
/** |
|||
* 计算占比 |
|||
*/ |
|||
private String calcPercentage(int count, int total) { |
|||
if (total == 0) { |
|||
return "0.00%"; |
|||
} |
|||
BigDecimal pct = BigDecimal.valueOf(count) |
|||
.multiply(BigDecimal.valueOf(100)) |
|||
.divide(BigDecimal.valueOf(total), 2, RoundingMode.HALF_UP); |
|||
return pct.toPlainString() + "%"; |
|||
} |
|||
} |
|||
@ -0,0 +1,68 @@ |
|||
package com.zdxt.enforcementcode.service; |
|||
|
|||
import com.zdxt.enforcementcode.domain.vo.ComplaintStatisticsVo; |
|||
import com.zdxt.enforcementcode.domain.bo.ComplaintStatisticsBo; |
|||
import org.dromara.common.mybatis.core.page.TableDataInfo; |
|||
import org.dromara.common.mybatis.core.page.PageQuery; |
|||
|
|||
import java.util.Collection; |
|||
import java.util.List; |
|||
|
|||
/** |
|||
* 【请填写功能名称】Service接口 |
|||
* |
|||
* @author Lion Li |
|||
* @date 2026-06-13 |
|||
*/ |
|||
public interface IComplaintStatisticsService { |
|||
|
|||
/** |
|||
* 查询【请填写功能名称】 |
|||
* |
|||
* @param id 主键 |
|||
* @return 【请填写功能名称】 |
|||
*/ |
|||
ComplaintStatisticsVo queryById(Long id); |
|||
|
|||
/** |
|||
* 分页查询【请填写功能名称】列表 |
|||
* |
|||
* @param bo 查询条件 |
|||
* @param pageQuery 分页参数 |
|||
* @return 【请填写功能名称】分页列表 |
|||
*/ |
|||
TableDataInfo<ComplaintStatisticsVo> queryPageList(ComplaintStatisticsBo bo, PageQuery pageQuery); |
|||
|
|||
/** |
|||
* 查询符合条件的【请填写功能名称】列表 |
|||
* |
|||
* @param bo 查询条件 |
|||
* @return 【请填写功能名称】列表 |
|||
*/ |
|||
List<ComplaintStatisticsVo> queryList(ComplaintStatisticsBo bo); |
|||
|
|||
/** |
|||
* 新增【请填写功能名称】 |
|||
* |
|||
* @param bo 【请填写功能名称】 |
|||
* @return 是否新增成功 |
|||
*/ |
|||
Boolean insertByBo(ComplaintStatisticsBo bo); |
|||
|
|||
/** |
|||
* 修改【请填写功能名称】 |
|||
* |
|||
* @param bo 【请填写功能名称】 |
|||
* @return 是否修改成功 |
|||
*/ |
|||
Boolean updateByBo(ComplaintStatisticsBo bo); |
|||
|
|||
/** |
|||
* 校验并批量删除【请填写功能名称】信息 |
|||
* |
|||
* @param ids 待删除的主键集合 |
|||
* @param isValid 是否进行有效性校验 |
|||
* @return 是否删除成功 |
|||
*/ |
|||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid); |
|||
} |
|||
@ -0,0 +1,144 @@ |
|||
package com.zdxt.enforcementcode.service.impl; |
|||
|
|||
import org.dromara.common.core.utils.MapstructUtils; |
|||
import org.dromara.common.core.utils.StringUtils; |
|||
import org.dromara.common.mybatis.core.page.TableDataInfo; |
|||
import org.dromara.common.mybatis.core.page.PageQuery; |
|||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
|||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
|||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
|||
import lombok.RequiredArgsConstructor; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.stereotype.Service; |
|||
import com.zdxt.enforcementcode.domain.bo.ComplaintStatisticsBo; |
|||
import com.zdxt.enforcementcode.domain.vo.ComplaintStatisticsVo; |
|||
import com.zdxt.enforcementcode.domain.ComplaintStatistics; |
|||
import com.zdxt.enforcementcode.mapper.ComplaintStatisticsMapper; |
|||
import com.zdxt.enforcementcode.service.IComplaintStatisticsService; |
|||
|
|||
import java.util.List; |
|||
import java.util.Map; |
|||
import java.util.Collection; |
|||
|
|||
/** |
|||
* 【请填写功能名称】Service业务层处理 |
|||
* |
|||
* @author Lion Li |
|||
* @date 2026-06-13 |
|||
*/ |
|||
@Slf4j |
|||
@RequiredArgsConstructor |
|||
@Service |
|||
public class ComplaintStatisticsServiceImpl implements IComplaintStatisticsService { |
|||
|
|||
private final ComplaintStatisticsMapper baseMapper; |
|||
|
|||
/** |
|||
* 查询【请填写功能名称】 |
|||
* |
|||
* @param id 主键 |
|||
* @return 【请填写功能名称】 |
|||
*/ |
|||
@Override |
|||
public ComplaintStatisticsVo queryById(Long id){ |
|||
return baseMapper.selectVoById(id); |
|||
} |
|||
|
|||
/** |
|||
* 分页查询【请填写功能名称】列表 |
|||
* |
|||
* @param bo 查询条件 |
|||
* @param pageQuery 分页参数 |
|||
* @return 【请填写功能名称】分页列表 |
|||
*/ |
|||
@Override |
|||
public TableDataInfo<ComplaintStatisticsVo> queryPageList(ComplaintStatisticsBo bo, PageQuery pageQuery) { |
|||
LambdaQueryWrapper<ComplaintStatistics> lqw = buildQueryWrapper(bo); |
|||
Page<ComplaintStatisticsVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw); |
|||
return TableDataInfo.build(result); |
|||
} |
|||
|
|||
/** |
|||
* 查询符合条件的【请填写功能名称】列表 |
|||
* |
|||
* @param bo 查询条件 |
|||
* @return 【请填写功能名称】列表 |
|||
*/ |
|||
@Override |
|||
public List<ComplaintStatisticsVo> queryList(ComplaintStatisticsBo bo) { |
|||
LambdaQueryWrapper<ComplaintStatistics> lqw = buildQueryWrapper(bo); |
|||
return baseMapper.selectVoList(lqw); |
|||
} |
|||
|
|||
private LambdaQueryWrapper<ComplaintStatistics> buildQueryWrapper(ComplaintStatisticsBo bo) { |
|||
Map<String, Object> params = bo.getParams(); |
|||
LambdaQueryWrapper<ComplaintStatistics> lqw = Wrappers.lambdaQuery(); |
|||
lqw.orderByAsc(ComplaintStatistics::getId); |
|||
lqw.eq(StringUtils.isNotBlank(bo.getCid()), ComplaintStatistics::getCid, bo.getCid()); |
|||
lqw.eq(StringUtils.isNotBlank(bo.getRid()), ComplaintStatistics::getRid, bo.getRid()); |
|||
lqw.eq(bo.getComplaintTime() != null, ComplaintStatistics::getComplaintTime, bo.getComplaintTime()); |
|||
lqw.eq(bo.getComplaintType() != null, ComplaintStatistics::getComplaintType, bo.getComplaintType()); |
|||
lqw.eq(StringUtils.isNotBlank(bo.getComplaintDepartment()), ComplaintStatistics::getComplaintDepartment, bo.getComplaintDepartment()); |
|||
lqw.eq(StringUtils.isNotBlank(bo.getComplaintDepartmentId()), ComplaintStatistics::getComplaintDepartmentId, bo.getComplaintDepartmentId()); |
|||
lqw.like(StringUtils.isNotBlank(bo.getEnterpriseName()), ComplaintStatistics::getEnterpriseName, bo.getEnterpriseName()); |
|||
lqw.eq(StringUtils.isNotBlank(bo.getEnterpriseNumber()), ComplaintStatistics::getEnterpriseNumber, bo.getEnterpriseNumber()); |
|||
lqw.eq(bo.getEnforceType() != null, ComplaintStatistics::getEnforceType, bo.getEnforceType()); |
|||
lqw.eq(StringUtils.isNotBlank(bo.getProblemDescription()), ComplaintStatistics::getProblemDescription, bo.getProblemDescription()); |
|||
lqw.eq(StringUtils.isNotBlank(bo.getLinkman()), ComplaintStatistics::getLinkman, bo.getLinkman()); |
|||
lqw.eq(StringUtils.isNotBlank(bo.getLinkmanTel()), ComplaintStatistics::getLinkmanTel, bo.getLinkmanTel()); |
|||
lqw.eq(StringUtils.isNotBlank(bo.getEnterpriseAddress()), ComplaintStatistics::getEnterpriseAddress, bo.getEnterpriseAddress()); |
|||
return lqw; |
|||
} |
|||
|
|||
/** |
|||
* 新增【请填写功能名称】 |
|||
* |
|||
* @param bo 【请填写功能名称】 |
|||
* @return 是否新增成功 |
|||
*/ |
|||
@Override |
|||
public Boolean insertByBo(ComplaintStatisticsBo bo) { |
|||
ComplaintStatistics add = MapstructUtils.convert(bo, ComplaintStatistics.class); |
|||
validEntityBeforeSave(add); |
|||
boolean flag = baseMapper.insert(add) > 0; |
|||
if (flag) { |
|||
bo.setId(add.getId()); |
|||
} |
|||
return flag; |
|||
} |
|||
|
|||
/** |
|||
* 修改【请填写功能名称】 |
|||
* |
|||
* @param bo 【请填写功能名称】 |
|||
* @return 是否修改成功 |
|||
*/ |
|||
@Override |
|||
public Boolean updateByBo(ComplaintStatisticsBo bo) { |
|||
ComplaintStatistics update = MapstructUtils.convert(bo, ComplaintStatistics.class); |
|||
validEntityBeforeSave(update); |
|||
return baseMapper.updateById(update) > 0; |
|||
} |
|||
|
|||
/** |
|||
* 保存前的数据校验 |
|||
*/ |
|||
private void validEntityBeforeSave(ComplaintStatistics entity){ |
|||
//TODO 做一些数据校验,如唯一约束
|
|||
} |
|||
|
|||
/** |
|||
* 校验并批量删除【请填写功能名称】信息 |
|||
* |
|||
* @param ids 待删除的主键集合 |
|||
* @param isValid 是否进行有效性校验 |
|||
* @return 是否删除成功 |
|||
*/ |
|||
@Override |
|||
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) { |
|||
if(isValid){ |
|||
//TODO 做一些业务上的校验,判断是否需要校验
|
|||
} |
|||
return baseMapper.deleteByIds(ids) > 0; |
|||
} |
|||
} |
|||
@ -0,0 +1,6 @@ |
|||
<?xml version="1.0" encoding="UTF-8" ?> |
|||
<!DOCTYPE mapper |
|||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" |
|||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
|||
<mapper namespace="com.zdxt.enforcementcode.mapper.ComplaintStatisticsMapper"> |
|||
</mapper> |
|||
@ -0,0 +1,143 @@ |
|||
<?xml version="1.0" encoding="UTF-8" ?> |
|||
<!DOCTYPE mapper |
|||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" |
|||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
|||
<mapper namespace="com.zdxt.enforcementcode.mapper.ComplaintStatisticsMapper"> |
|||
|
|||
<!-- 通用时间条件片段 --> |
|||
<sql id="reportTimeCondition"> |
|||
<if test="bo.year != null and bo.year != '' and (bo.timeType == null or bo.timeType == '' or bo.timeType == 'year')"> |
|||
AND YEAR(complaint_time) = #{bo.year} |
|||
</if> |
|||
<if test="bo.timeType == 'quarter' and bo.year != null and bo.year != '' and bo.quarter != null and bo.quarter != ''"> |
|||
AND YEAR(complaint_time) = #{bo.year} AND QUARTER(complaint_time) = #{bo.quarter} |
|||
</if> |
|||
<if test="bo.timeType == 'month' and bo.year != null and bo.year != '' and bo.month != null and bo.month != ''"> |
|||
AND YEAR(complaint_time) = #{bo.year} AND MONTH(complaint_time) = #{bo.month} |
|||
</if> |
|||
<if test="bo.timeType == 'day' and bo.beginTime != null and bo.beginTime != ''"> |
|||
AND DATE_FORMAT(complaint_time,'%Y-%m-%d') >= STR_TO_DATE(#{bo.beginTime},'%Y-%m-%d') |
|||
</if> |
|||
<if test="bo.timeType == 'day' and bo.endTime != null and bo.endTime != ''"> |
|||
AND DATE_FORMAT(complaint_time,'%Y-%m-%d') <= STR_TO_DATE(#{bo.endTime},'%Y-%m-%d') |
|||
</if> |
|||
</sql> |
|||
|
|||
<!-- Tab1:分组统计(被投诉对象+数量),JOIN sys_dept翻译名称 --> |
|||
<select id="selectComplaintGroupByDept" resultType="com.zdxt.enforcementcode.domain.vo.report.ComplaintReportGroupVo"> |
|||
SELECT c.complaint_department_id AS complaintDepartmentId, |
|||
d.dept_name AS complaintDepartment, |
|||
COUNT(*) AS total |
|||
FROM complaint_statistics c |
|||
LEFT JOIN sys_dept d ON c.complaint_department_id = d.dept_id |
|||
WHERE c.complaint_department_id IS NOT NULL |
|||
AND c.complaint_department IS NOT NULL |
|||
AND c.enforce_type IS NOT NULL |
|||
<if test="bo.complaintDepartmentIdList != null and bo.complaintDepartmentIdList.size() > 0"> |
|||
AND c.complaint_department_id IN |
|||
<foreach collection="bo.complaintDepartmentIdList" item="deptId" open="(" separator="," close=")"> |
|||
#{deptId} |
|||
</foreach> |
|||
</if> |
|||
<if test="bo.enforceType != null"> |
|||
AND c.enforce_type = #{bo.enforceType} |
|||
</if> |
|||
<if test="bo.enterpriseAddress != null and bo.enterpriseAddress != ''"> |
|||
AND c.enterprise_address LIKE CONCAT('%', #{bo.enterpriseAddress}, '%') |
|||
</if> |
|||
<include refid="reportTimeCondition"/> |
|||
GROUP BY c.complaint_department_id |
|||
ORDER BY total DESC |
|||
</select> |
|||
|
|||
<!-- Tab1:投诉明细列表 --> |
|||
<select id="selectComplaintDetailList" resultType="com.zdxt.enforcementcode.domain.vo.report.ComplaintReportDetailVo"> |
|||
SELECT c.id, c.cid, c.complaint_department AS complaintDepartment, |
|||
c.enforce_type AS enforceType, |
|||
DATE_FORMAT(c.complaint_time, '%Y-%m-%d %H:%i:%s') AS complaintTime |
|||
FROM complaint_statistics c |
|||
WHERE c.complaint_department_id IS NOT NULL |
|||
AND c.complaint_department IS NOT NULL |
|||
AND c.enforce_type IS NOT NULL |
|||
<if test="bo.complaintDepartmentId != null and bo.complaintDepartmentId != ''"> |
|||
AND c.complaint_department_id = #{bo.complaintDepartmentId} |
|||
</if> |
|||
<if test="bo.enforceType != null"> |
|||
AND c.enforce_type = #{bo.enforceType} |
|||
</if> |
|||
<if test="bo.enterpriseAddress != null and bo.enterpriseAddress != ''"> |
|||
AND c.enterprise_address LIKE CONCAT('%', #{bo.enterpriseAddress}, '%') |
|||
</if> |
|||
<include refid="reportTimeCondition"/> |
|||
ORDER BY c.complaint_time DESC |
|||
</select> |
|||
|
|||
<!-- Tab1概览:投诉总数 --> |
|||
<select id="selectComplaintCount" resultType="int"> |
|||
SELECT COUNT(*) FROM complaint_statistics |
|||
WHERE complaint_department_id IS NOT NULL |
|||
AND complaint_department IS NOT NULL |
|||
AND enforce_type IS NOT NULL |
|||
<if test="bo.complaintDepartmentIdList != null and bo.complaintDepartmentIdList.size() > 0"> |
|||
AND complaint_department_id IN |
|||
<foreach collection="bo.complaintDepartmentIdList" item="deptId" open="(" separator="," close=")"> |
|||
#{deptId} |
|||
</foreach> |
|||
</if> |
|||
<if test="bo.enforceType != null"> |
|||
AND enforce_type = #{bo.enforceType} |
|||
</if> |
|||
<if test="bo.enterpriseAddress != null and bo.enterpriseAddress != ''"> |
|||
AND enterprise_address LIKE CONCAT('%', #{bo.enterpriseAddress}, '%') |
|||
</if> |
|||
<include refid="reportTimeCondition"/> |
|||
</select> |
|||
|
|||
<!-- Tab1概览:被投诉对象数 --> |
|||
<select id="selectComplaintDeptCount" resultType="int"> |
|||
SELECT COUNT(DISTINCT complaint_department_id) FROM complaint_statistics |
|||
WHERE complaint_department_id IS NOT NULL |
|||
AND complaint_department IS NOT NULL |
|||
AND enforce_type IS NOT NULL |
|||
<if test="bo.complaintDepartmentIdList != null and bo.complaintDepartmentIdList.size() > 0"> |
|||
AND complaint_department_id IN |
|||
<foreach collection="bo.complaintDepartmentIdList" item="deptId" open="(" separator="," close=")"> |
|||
#{deptId} |
|||
</foreach> |
|||
</if> |
|||
<if test="bo.enforceType != null"> |
|||
AND enforce_type = #{bo.enforceType} |
|||
</if> |
|||
<if test="bo.enterpriseAddress != null and bo.enterpriseAddress != ''"> |
|||
AND enterprise_address LIKE CONCAT('%', #{bo.enterpriseAddress}, '%') |
|||
</if> |
|||
<include refid="reportTimeCondition"/> |
|||
</select> |
|||
|
|||
<!-- Tab2:查全量投诉列表(含enforce_type)用于Java层投诉类型分组 --> |
|||
<select id="selectComplaintListForTypeStat" resultType="com.zdxt.enforcementcode.domain.ComplaintStatistics"> |
|||
SELECT id, enforce_type AS enforceType |
|||
FROM complaint_statistics |
|||
WHERE complaint_department_id IS NOT NULL |
|||
AND complaint_department IS NOT NULL |
|||
AND enforce_type IS NOT NULL |
|||
<include refid="reportTimeCondition"/> |
|||
</select> |
|||
|
|||
<!-- Tab2:查全量投诉列表(含enterprise_address)用于Java层区域/街道分组 --> |
|||
<select id="selectComplaintListForAreaStat" resultType="com.zdxt.enforcementcode.domain.ComplaintStatistics"> |
|||
SELECT c.id, i.enterprise_address AS enterpriseAddress |
|||
FROM complaint_statistics c |
|||
LEFT JOIN ( |
|||
SELECT enterprise_number, enterprise_address |
|||
FROM enterprise_information |
|||
GROUP BY enterprise_number |
|||
) i ON c.enterprise_number = i.enterprise_number |
|||
WHERE c.complaint_department_id IS NOT NULL |
|||
AND c.complaint_department IS NOT NULL |
|||
AND c.enforce_type IS NOT NULL |
|||
<include refid="reportTimeCondition"/> |
|||
</select> |
|||
|
|||
</mapper> |
|||
|
|||
@ -0,0 +1,156 @@ |
|||
import request from '@/utils/request'; |
|||
import { AxiosPromise } from 'axios'; |
|||
|
|||
const BASE_URL = '/web/supervision/report/statistics-complaint'; |
|||
|
|||
/** 查询参数 */ |
|||
export interface ComplaintQuery { |
|||
pageNum?: number; |
|||
pageSize?: number; |
|||
/** 被投诉对象(模糊搜索) */ |
|||
complaintDepartment?: string; |
|||
/** 投诉类型(字典 caseType) */ |
|||
enforceType?: number | string; |
|||
/** 涉事地址(模糊搜索) */ |
|||
enterpriseAddress?: string; |
|||
/** 被投诉部门ID(明细查询用) */ |
|||
complaintDepartmentId?: string; |
|||
/** 年 */ |
|||
year?: string; |
|||
/** 季度 */ |
|||
quarter?: string; |
|||
/** 月 */ |
|||
month?: string; |
|||
/** 自定义开始时间 */ |
|||
beginTime?: string; |
|||
/** 自定义结束时间 */ |
|||
endTime?: string; |
|||
/** 时段类型:year/quarter/month/day */ |
|||
timeType?: string; |
|||
/** Tab2类型切换:type/空/区域dict_value */ |
|||
type?: string; |
|||
} |
|||
|
|||
/** 概览VO */ |
|||
export interface ComplaintOverviewVo { |
|||
complaintCount: number; |
|||
complaintDeptCount: number; |
|||
} |
|||
|
|||
/** 分组统计VO */ |
|||
export interface ComplaintGroupVo { |
|||
complaintDepartment: string; |
|||
complaintDepartmentId: string; |
|||
total: number; |
|||
} |
|||
|
|||
/** 明细VO */ |
|||
export interface ComplaintDetailVo { |
|||
id: number; |
|||
cid: string; |
|||
complaintDepartment: string; |
|||
enforceType: number; |
|||
enforceTypeText: string; |
|||
complaintTime: string; |
|||
} |
|||
|
|||
/** Tab2 类型统计VO */ |
|||
export interface ComplaintTypeStatVo { |
|||
name: string; |
|||
count: number; |
|||
percentage: string; |
|||
} |
|||
|
|||
/** Tab1概览 */ |
|||
export const getOverview = (params: ComplaintQuery): AxiosPromise => { |
|||
return request({ |
|||
url: `${BASE_URL}/overview`, |
|||
method: 'get', |
|||
params |
|||
}); |
|||
}; |
|||
|
|||
/** Tab1分组列表 */ |
|||
export const getGroupList = (params: ComplaintQuery): AxiosPromise => { |
|||
return request({ |
|||
url: `${BASE_URL}/groupList`, |
|||
method: 'get', |
|||
params |
|||
}); |
|||
}; |
|||
|
|||
/** Tab1明细列表 */ |
|||
export const getDetailList = (params: ComplaintQuery): AxiosPromise => { |
|||
return request({ |
|||
url: `${BASE_URL}/detailList`, |
|||
method: 'get', |
|||
params |
|||
}); |
|||
}; |
|||
|
|||
/** Tab2-投诉类型统计 */ |
|||
export const getTypeStatList = (params: ComplaintQuery): AxiosPromise => { |
|||
return request({ |
|||
url: `${BASE_URL}/typeStatList`, |
|||
method: 'get', |
|||
params |
|||
}); |
|||
}; |
|||
|
|||
/** Tab2-区域统计 */ |
|||
export const getAreaStatList = (params: ComplaintQuery): AxiosPromise => { |
|||
return request({ |
|||
url: `${BASE_URL}/areaStatList`, |
|||
method: 'get', |
|||
params |
|||
}); |
|||
}; |
|||
|
|||
/** Tab2-街道统计 */ |
|||
export const getStreetStatList = (params: ComplaintQuery): AxiosPromise => { |
|||
return request({ |
|||
url: `${BASE_URL}/streetStatList`, |
|||
method: 'get', |
|||
params |
|||
}); |
|||
}; |
|||
|
|||
/** Tab1导出 */ |
|||
export const exportGroupList = (data: ComplaintQuery): AxiosPromise<Blob> => { |
|||
return request({ |
|||
url: `${BASE_URL}/exportGroupList`, |
|||
method: 'post', |
|||
data, |
|||
responseType: 'blob' |
|||
}); |
|||
}; |
|||
|
|||
/** Tab2投诉类型导出 */ |
|||
export const exportTypeStat = (data: ComplaintQuery): AxiosPromise<Blob> => { |
|||
return request({ |
|||
url: `${BASE_URL}/exportTypeStat`, |
|||
method: 'post', |
|||
data, |
|||
responseType: 'blob' |
|||
}); |
|||
}; |
|||
|
|||
/** Tab2区域导出 */ |
|||
export const exportAreaStat = (data: ComplaintQuery): AxiosPromise<Blob> => { |
|||
return request({ |
|||
url: `${BASE_URL}/exportAreaStat`, |
|||
method: 'post', |
|||
data, |
|||
responseType: 'blob' |
|||
}); |
|||
}; |
|||
|
|||
/** Tab2街道导出 */ |
|||
export const exportStreetStat = (data: ComplaintQuery): AxiosPromise<Blob> => { |
|||
return request({ |
|||
url: `${BASE_URL}/exportStreetStat`, |
|||
method: 'post', |
|||
data, |
|||
responseType: 'blob' |
|||
}); |
|||
}; |
|||
Loading…
Reference in new issue