feat(wm-revenue): #48 报装核心流程(预受理→工程申请→派单→竣工)
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
package com.water.revenue.controller;
|
||||
|
||||
import com.water.common.core.result.R;
|
||||
import com.water.revenue.service.InstallationService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Tag(name = "报装管理")
|
||||
@RestController
|
||||
@RequestMapping("/revenue/installation")
|
||||
@RequiredArgsConstructor
|
||||
public class InstallationController {
|
||||
|
||||
private final InstallationService installationService;
|
||||
|
||||
@Operation(summary = "预受理")
|
||||
@PostMapping("/pre-accept")
|
||||
public R<Map<String, Object>> preAccept(@RequestBody Map<String, Object> request) {
|
||||
return R.ok(installationService.preAccept(request));
|
||||
}
|
||||
|
||||
@Operation(summary = "工程申请")
|
||||
@PutMapping("/engineering-apply")
|
||||
public R<Map<String, Object>> engineeringApply(@RequestBody Map<String, Object> request) {
|
||||
String applyNo = (String) request.get("applyNo");
|
||||
return R.ok(installationService.engineeringApply(applyNo, request));
|
||||
}
|
||||
|
||||
@Operation(summary = "派单")
|
||||
@PutMapping("/dispatch")
|
||||
public R<Map<String, Object>> dispatch(@RequestBody Map<String, Object> request) {
|
||||
String applyNo = (String) request.get("applyNo");
|
||||
Long assigneeId = Long.parseLong(String.valueOf(request.get("assigneeId")));
|
||||
String assigneeName = (String) request.get("assigneeName");
|
||||
return R.ok(installationService.dispatch(applyNo, assigneeId, assigneeName));
|
||||
}
|
||||
|
||||
@Operation(summary = "竣工确认")
|
||||
@PutMapping("/complete")
|
||||
public R<Map<String, Object>> complete(@RequestBody Map<String, Object> request) {
|
||||
String applyNo = (String) request.get("applyNo");
|
||||
return R.ok(installationService.complete(applyNo, request));
|
||||
}
|
||||
|
||||
@Operation(summary = "查询详情")
|
||||
@GetMapping("/detail")
|
||||
public R<Map<String, Object>> getDetail(@RequestParam String applyNo) {
|
||||
return R.ok(installationService.getDetail(applyNo));
|
||||
}
|
||||
|
||||
@Operation(summary = "分页列表")
|
||||
@GetMapping("/list")
|
||||
public R<Map<String, Object>> list(@RequestParam(required = false) String area,
|
||||
@RequestParam(required = false) String status,
|
||||
@RequestParam(required = false) String keyword,
|
||||
@RequestParam(defaultValue = "1") Integer page,
|
||||
@RequestParam(defaultValue = "10") Integer size) {
|
||||
Map<String, Object> query = Map.of(
|
||||
"page", page, "size", size,
|
||||
"area", area != null ? area : "",
|
||||
"status", status != null ? status : "",
|
||||
"keyword", keyword != null ? keyword : ""
|
||||
);
|
||||
return R.ok(installationService.list(query));
|
||||
}
|
||||
|
||||
@Operation(summary = "统计")
|
||||
@GetMapping("/stats")
|
||||
public R<Map<String, Object>> stats(@RequestParam(required = false) String area) {
|
||||
return R.ok(installationService.stats(area));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.water.revenue.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.water.revenue.enums.InstallationStatus;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Data
|
||||
@TableName("installation_apply")
|
||||
public class InstallationApply {
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private String applyNo;
|
||||
|
||||
private String applicantName;
|
||||
|
||||
private String applicantPhone;
|
||||
|
||||
private String applicantIdCard;
|
||||
|
||||
private String address;
|
||||
|
||||
private String area;
|
||||
|
||||
private String waterUseType;
|
||||
|
||||
private BigDecimal pipeDiameter;
|
||||
|
||||
private InstallationStatus status;
|
||||
|
||||
private LocalDateTime applyTime;
|
||||
|
||||
private LocalDateTime engineeringApplyTime;
|
||||
|
||||
private LocalDateTime dispatchTime;
|
||||
|
||||
private LocalDateTime completedTime;
|
||||
|
||||
private Long assigneeId;
|
||||
|
||||
private String assigneeName;
|
||||
|
||||
private String remarks;
|
||||
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
private LocalDateTime updatedAt;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.water.revenue.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public enum InstallationStatus {
|
||||
|
||||
PRE_ACCEPT("预受理"),
|
||||
ENGINEERING_APPLY("工程申请"),
|
||||
DISPATCHED("已派单"),
|
||||
COMPLETED("竣工确认"),
|
||||
REJECTED("已驳回");
|
||||
|
||||
private final String description;
|
||||
|
||||
InstallationStatus(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,214 @@
|
||||
package com.water.revenue.service;
|
||||
|
||||
import com.water.revenue.enums.InstallationStatus;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class InstallationService {
|
||||
|
||||
private final JdbcTemplate jdbcTemplate;
|
||||
|
||||
/**
|
||||
* 预受理 - 生成申请编号,状态→PRE_ACCEPT
|
||||
*/
|
||||
public Map<String, Object> preAccept(Map<String, Object> request) {
|
||||
String applyNo = "IZA-" + System.currentTimeMillis();
|
||||
String applicantName = (String) request.get("applicantName");
|
||||
String applicantPhone = (String) request.get("applicantPhone");
|
||||
String applicantIdCard = (String) request.get("applicantIdCard");
|
||||
String address = (String) request.get("address");
|
||||
String area = (String) request.get("area");
|
||||
String waterUseType = (String) request.get("waterUseType");
|
||||
Object pipeDiameter = request.get("pipeDiameter");
|
||||
String remarks = (String) request.get("remarks");
|
||||
|
||||
jdbcTemplate.update(
|
||||
"INSERT INTO installation_apply (apply_no, applicant_name, applicant_phone, applicant_id_card, " +
|
||||
"address, area, water_use_type, pipe_diameter, status, apply_time, remarks, created_at, updated_at) " +
|
||||
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NOW(), ?, NOW(), NOW())",
|
||||
applyNo, applicantName, applicantPhone, applicantIdCard,
|
||||
address, area, waterUseType, pipeDiameter,
|
||||
InstallationStatus.PRE_ACCEPT.name(), remarks);
|
||||
|
||||
log.info("Installation pre-accepted: applyNo={}, applicant={}", applyNo, applicantName);
|
||||
|
||||
Map<String, Object> result = new LinkedHashMap<>();
|
||||
result.put("applyNo", applyNo);
|
||||
result.put("status", InstallationStatus.PRE_ACCEPT.name());
|
||||
result.put("applicantName", applicantName);
|
||||
result.put("applyTime", LocalDateTime.now().toString());
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 工程申请 - 状态→ENGINEERING_APPLY
|
||||
*/
|
||||
public Map<String, Object> engineeringApply(String applyNo, Map<String, Object> engineeringInfo) {
|
||||
String remarks = (String) engineeringInfo.get("remarks");
|
||||
int rows = jdbcTemplate.update(
|
||||
"UPDATE installation_apply SET status = ?, engineering_apply_time = NOW(), " +
|
||||
"remarks = COALESCE(?, remarks), updated_at = NOW() WHERE apply_no = ?",
|
||||
InstallationStatus.ENGINEERING_APPLY.name(), remarks, applyNo);
|
||||
|
||||
if (rows == 0) {
|
||||
throw new RuntimeException("申请不存在: " + applyNo);
|
||||
}
|
||||
log.info("Engineering applied: applyNo={}", applyNo);
|
||||
|
||||
Map<String, Object> result = new LinkedHashMap<>();
|
||||
result.put("applyNo", applyNo);
|
||||
result.put("status", InstallationStatus.ENGINEERING_APPLY.name());
|
||||
result.put("engineeringApplyTime", LocalDateTime.now().toString());
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 派单 - 状态→DISPATCHED
|
||||
*/
|
||||
public Map<String, Object> dispatch(String applyNo, Long assigneeId, String assigneeName) {
|
||||
int rows = jdbcTemplate.update(
|
||||
"UPDATE installation_apply SET status = ?, assignee_id = ?, assignee_name = ?, " +
|
||||
"dispatch_time = NOW(), updated_at = NOW() WHERE apply_no = ?",
|
||||
InstallationStatus.DISPATCHED.name(), assigneeId, assigneeName, applyNo);
|
||||
|
||||
if (rows == 0) {
|
||||
throw new RuntimeException("申请不存在: " + applyNo);
|
||||
}
|
||||
log.info("Installation dispatched: applyNo={}, assignee={}", applyNo, assigneeName);
|
||||
|
||||
Map<String, Object> result = new LinkedHashMap<>();
|
||||
result.put("applyNo", applyNo);
|
||||
result.put("status", InstallationStatus.DISPATCHED.name());
|
||||
result.put("assigneeId", assigneeId);
|
||||
result.put("assigneeName", assigneeName);
|
||||
result.put("dispatchTime", LocalDateTime.now().toString());
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 竣工确认 - 状态→COMPLETED
|
||||
*/
|
||||
public Map<String, Object> complete(String applyNo, Map<String, Object> completionInfo) {
|
||||
String remarks = (String) completionInfo.get("remarks");
|
||||
int rows = jdbcTemplate.update(
|
||||
"UPDATE installation_apply SET status = ?, completed_time = NOW(), " +
|
||||
"remarks = COALESCE(?, remarks), updated_at = NOW() WHERE apply_no = ?",
|
||||
InstallationStatus.COMPLETED.name(), remarks, applyNo);
|
||||
|
||||
if (rows == 0) {
|
||||
throw new RuntimeException("申请不存在: " + applyNo);
|
||||
}
|
||||
log.info("Installation completed: applyNo={}", applyNo);
|
||||
|
||||
Map<String, Object> result = new LinkedHashMap<>();
|
||||
result.put("applyNo", applyNo);
|
||||
result.put("status", InstallationStatus.COMPLETED.name());
|
||||
result.put("completedTime", LocalDateTime.now().toString());
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询详情
|
||||
*/
|
||||
public Map<String, Object> getDetail(String applyNo) {
|
||||
return jdbcTemplate.queryForMap(
|
||||
"SELECT id, apply_no, applicant_name, applicant_phone, applicant_id_card, " +
|
||||
"address, area, water_use_type, pipe_diameter, status, apply_time, " +
|
||||
"engineering_apply_time, dispatch_time, completed_time, assignee_id, " +
|
||||
"assignee_name, remarks, created_at, updated_at " +
|
||||
"FROM installation_apply WHERE apply_no = ?",
|
||||
applyNo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询
|
||||
*/
|
||||
public Map<String, Object> list(Map<String, Object> query) {
|
||||
int page = query.get("page") != null ? Integer.parseInt(String.valueOf(query.get("page"))) : 1;
|
||||
int size = query.get("size") != null ? Integer.parseInt(String.valueOf(query.get("size"))) : 10;
|
||||
int offset = (page - 1) * size;
|
||||
|
||||
String area = (String) query.get("area");
|
||||
String status = (String) query.get("status");
|
||||
String keyword = (String) query.get("keyword");
|
||||
|
||||
StringBuilder sql = new StringBuilder("SELECT * FROM installation_apply WHERE 1=1");
|
||||
List<Object> params = new ArrayList<>();
|
||||
|
||||
if (area != null && !area.isEmpty()) {
|
||||
sql.append(" AND area = ?");
|
||||
params.add(area);
|
||||
}
|
||||
if (status != null && !status.isEmpty()) {
|
||||
sql.append(" AND status = ?");
|
||||
params.add(status);
|
||||
}
|
||||
if (keyword != null && !keyword.isEmpty()) {
|
||||
sql.append(" AND (applicant_name LIKE ? OR apply_no LIKE ?)");
|
||||
params.add("%" + keyword + "%");
|
||||
params.add("%" + keyword + "%");
|
||||
}
|
||||
|
||||
sql.append(" ORDER BY created_at DESC LIMIT ? OFFSET ?");
|
||||
params.add(size);
|
||||
params.add(offset);
|
||||
|
||||
List<Map<String, Object>> records = jdbcTemplate.queryForList(sql.toString(), params.toArray());
|
||||
|
||||
// Total count
|
||||
StringBuilder countSql = new StringBuilder("SELECT COUNT(*) FROM installation_apply WHERE 1=1");
|
||||
List<Object> countParams = new ArrayList<>();
|
||||
if (area != null && !area.isEmpty()) {
|
||||
countSql.append(" AND area = ?");
|
||||
countParams.add(area);
|
||||
}
|
||||
if (status != null && !status.isEmpty()) {
|
||||
countSql.append(" AND status = ?");
|
||||
countParams.add(status);
|
||||
}
|
||||
if (keyword != null && !keyword.isEmpty()) {
|
||||
countSql.append(" AND (applicant_name LIKE ? OR apply_no LIKE ?)");
|
||||
countParams.add("%" + keyword + "%");
|
||||
countParams.add("%" + keyword + "%");
|
||||
}
|
||||
|
||||
Long total = jdbcTemplate.queryForObject(countSql.toString(), Long.class, countParams.toArray());
|
||||
|
||||
Map<String, Object> result = new LinkedHashMap<>();
|
||||
result.put("records", records);
|
||||
result.put("total", total);
|
||||
result.put("page", page);
|
||||
result.put("size", size);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 统计
|
||||
*/
|
||||
public Map<String, Object> stats(String area) {
|
||||
StringBuilder sql = new StringBuilder(
|
||||
"SELECT status, COUNT(*) as count FROM installation_apply WHERE 1=1");
|
||||
List<Object> params = new ArrayList<>();
|
||||
|
||||
if (area != null && !area.isEmpty()) {
|
||||
sql.append(" AND area = ?");
|
||||
params.add(area);
|
||||
}
|
||||
sql.append(" GROUP BY status");
|
||||
|
||||
List<Map<String, Object>> statusStats = jdbcTemplate.queryForList(sql.toString(), params.toArray());
|
||||
|
||||
Map<String, Object> result = new LinkedHashMap<>();
|
||||
result.put("byStatus", statusStats);
|
||||
result.put("area", area);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
-- 报装申请表
|
||||
CREATE TABLE IF NOT EXISTS installation_apply (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
|
||||
apply_no VARCHAR(64) NOT NULL COMMENT '申请编号',
|
||||
applicant_name VARCHAR(64) NOT NULL COMMENT '申请人姓名',
|
||||
applicant_phone VARCHAR(20) NOT NULL COMMENT '申请人电话',
|
||||
applicant_id_card VARCHAR(20) DEFAULT NULL COMMENT '申请人身份证号',
|
||||
address VARCHAR(256) NOT NULL COMMENT '用水地址',
|
||||
area VARCHAR(64) NOT NULL COMMENT '所属区域',
|
||||
water_use_type VARCHAR(32) DEFAULT NULL COMMENT '用水类型(居民/商业/工业/其他)',
|
||||
pipe_diameter DECIMAL(10,2) DEFAULT NULL COMMENT '管径(mm)',
|
||||
status VARCHAR(32) NOT NULL DEFAULT 'PRE_ACCEPT' COMMENT '状态: PRE_ACCEPT/ENGINEERING_APPLY/DISPATCHED/COMPLETED/REJECTED',
|
||||
apply_time DATETIME NOT NULL COMMENT '申请时间',
|
||||
engineering_apply_time DATETIME DEFAULT NULL COMMENT '工程申请时间',
|
||||
dispatch_time DATETIME DEFAULT NULL COMMENT '派单时间',
|
||||
completed_time DATETIME DEFAULT NULL COMMENT '竣工时间',
|
||||
assignee_id BIGINT DEFAULT NULL COMMENT '指派人ID',
|
||||
assignee_name VARCHAR(64) DEFAULT NULL COMMENT '指派人姓名',
|
||||
remarks VARCHAR(512) DEFAULT NULL COMMENT '备注',
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
UNIQUE KEY uk_apply_no (apply_no),
|
||||
KEY idx_area (area),
|
||||
KEY idx_status (status),
|
||||
KEY idx_created_at (created_at)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='报装申请表';
|
||||
Reference in New Issue
Block a user