|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+package com.water.revenue.service;
|
|
|
2
|
+
|
|
|
3
|
+import lombok.RequiredArgsConstructor;
|
|
|
4
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
5
|
+import org.springframework.jdbc.core.JdbcTemplate;
|
|
|
6
|
+import org.springframework.stereotype.Service;
|
|
|
7
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
8
|
+
|
|
|
9
|
+import java.time.LocalDateTime;
|
|
|
10
|
+import java.util.*;
|
|
|
11
|
+
|
|
|
12
|
+@Slf4j
|
|
|
13
|
+@Service
|
|
|
14
|
+@RequiredArgsConstructor
|
|
|
15
|
+public class CustomerArchiveService {
|
|
|
16
|
+
|
|
|
17
|
+ private final JdbcTemplate jdbcTemplate;
|
|
|
18
|
+
|
|
|
19
|
+ @Transactional
|
|
|
20
|
+ public Map<String, Object> create(String name, String type, String area, String address,
|
|
|
21
|
+ String phone, String idCard) {
|
|
|
22
|
+ String customerNo = "CUS-" + System.currentTimeMillis();
|
|
|
23
|
+ LocalDateTime now = LocalDateTime.now();
|
|
|
24
|
+ jdbcTemplate.update(
|
|
|
25
|
+ "INSERT INTO rev_customer (customer_no, name, type, area, address, phone, id_card, status, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, 'active', ?, ?)",
|
|
|
26
|
+ customerNo, name, type, area, address, phone, idCard, now, now);
|
|
|
27
|
+ Long id = jdbcTemplate.queryForObject("SELECT id FROM rev_customer WHERE customer_no = ?", Long.class, customerNo);
|
|
|
28
|
+ log.info("创建用户档案: customerNo={}", customerNo);
|
|
|
29
|
+ Map<String, Object> r = new LinkedHashMap<>();
|
|
|
30
|
+ r.put("id", id); r.put("customerNo", customerNo); r.put("name", name);
|
|
|
31
|
+ r.put("type", type); r.put("area", area); r.put("address", address);
|
|
|
32
|
+ r.put("phone", phone); r.put("status", "active"); r.put("createdAt", now);
|
|
|
33
|
+ return r;
|
|
|
34
|
+ }
|
|
|
35
|
+
|
|
|
36
|
+ @Transactional
|
|
|
37
|
+ public void update(Long id, Map<String, Object> fields) {
|
|
|
38
|
+ List<String> set = new ArrayList<>(); List<Object> params = new ArrayList<>();
|
|
|
39
|
+ for (String f : new String[]{"name","type","area","address","phone","id_card","status"}) {
|
|
|
40
|
+ if (fields.containsKey(f)) { set.add(f + " = ?"); params.add(fields.get(f)); }
|
|
|
41
|
+ }
|
|
|
42
|
+ if (set.isEmpty()) throw new RuntimeException("没有可更新的字段");
|
|
|
43
|
+ set.add("updated_at = ?"); params.add(LocalDateTime.now()); params.add(id);
|
|
|
44
|
+ jdbcTemplate.update("UPDATE rev_customer SET " + String.join(", ", set) + " WHERE id = ?", params.toArray());
|
|
|
45
|
+ }
|
|
|
46
|
+
|
|
|
47
|
+ public Map<String, Object> getById(Long id) {
|
|
|
48
|
+ Map<String, Object> c = jdbcTemplate.queryForMap("SELECT * FROM rev_customer WHERE id = ?", id);
|
|
|
49
|
+ c.put("meters", jdbcTemplate.queryForList("SELECT * FROM rev_water_meter WHERE customer_no = ? ORDER BY install_date DESC", c.get("customer_no")));
|
|
|
50
|
+ c.put("recentBills", jdbcTemplate.queryForList("SELECT * FROM rev_bill WHERE customer_no = ? ORDER BY bill_period DESC LIMIT 5", c.get("customer_no")));
|
|
|
51
|
+ return c;
|
|
|
52
|
+ }
|
|
|
53
|
+
|
|
|
54
|
+ public Map<String, Object> list(String type, String area, String status, String keyword, int page, int size) {
|
|
|
55
|
+ StringBuilder w = new StringBuilder("WHERE 1=1"); List<Object> p = new ArrayList<>();
|
|
|
56
|
+ if (type != null && !type.isEmpty()) { w.append(" AND type = ?"); p.add(type); }
|
|
|
57
|
+ if (area != null && !area.isEmpty()) { w.append(" AND area = ?"); p.add(area); }
|
|
|
58
|
+ if (status != null && !status.isEmpty()) { w.append(" AND status = ?"); p.add(status); }
|
|
|
59
|
+ if (keyword != null && !keyword.isEmpty()) {
|
|
|
60
|
+ w.append(" AND (name LIKE ? OR customer_no LIKE ? OR phone LIKE ?)");
|
|
|
61
|
+ String kw = "%" + keyword + "%"; p.add(kw); p.add(kw); p.add(kw);
|
|
|
62
|
+ }
|
|
|
63
|
+ Long total = jdbcTemplate.queryForObject("SELECT COUNT(*) FROM rev_customer " + w, Long.class, p.toArray());
|
|
|
64
|
+ List<Object> qp = new ArrayList<>(p); qp.add(size); qp.add((page - 1) * size);
|
|
|
65
|
+ List<Map<String, Object>> records = jdbcTemplate.queryForList(
|
|
|
66
|
+ "SELECT * FROM rev_customer " + w + " ORDER BY created_at DESC LIMIT ? OFFSET ?", qp.toArray());
|
|
|
67
|
+ Map<String, Object> r = new LinkedHashMap<>();
|
|
|
68
|
+ r.put("records", records); r.put("total", total); r.put("page", page);
|
|
|
69
|
+ r.put("size", size); r.put("pages", (int) Math.ceil((double) total / size));
|
|
|
70
|
+ return r;
|
|
|
71
|
+ }
|
|
|
72
|
+
|
|
|
73
|
+ @Transactional
|
|
|
74
|
+ public void cancel(Long id) {
|
|
|
75
|
+ int rows = jdbcTemplate.update("UPDATE rev_customer SET status = 'cancelled', updated_at = ? WHERE id = ? AND status = 'active'", LocalDateTime.now(), id);
|
|
|
76
|
+ if (rows == 0) throw new RuntimeException("用户不存在或已销户: " + id);
|
|
|
77
|
+ }
|
|
|
78
|
+
|
|
|
79
|
+ public Map<String, Object> stats(String area) {
|
|
|
80
|
+ StringBuilder w = new StringBuilder("WHERE 1=1"); List<Object> p = new ArrayList<>();
|
|
|
81
|
+ if (area != null && !area.isEmpty()) { w.append(" AND area = ?"); p.add(area); }
|
|
|
82
|
+ Map<String, Object> r = new LinkedHashMap<>();
|
|
|
83
|
+ r.put("total", jdbcTemplate.queryForObject("SELECT COUNT(*) FROM rev_customer " + w, Long.class, p.toArray()));
|
|
|
84
|
+ r.put("byType", jdbcTemplate.queryForList("SELECT type, COUNT(*) as count FROM rev_customer " + w + " GROUP BY type", p.toArray()));
|
|
|
85
|
+ r.put("byArea", jdbcTemplate.queryForList("SELECT area, COUNT(*) as count FROM rev_customer " + w + " GROUP BY area", p.toArray()));
|
|
|
86
|
+ r.put("byStatus", jdbcTemplate.queryForList("SELECT status, COUNT(*) as count FROM rev_customer " + w + " GROUP BY status", p.toArray()));
|
|
|
87
|
+ return r;
|
|
|
88
|
+ }
|
|
|
89
|
+}
|