智慧水务管理系统 - 精河县供水工程综合管理平台

revenue_service.dart 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452
  1. /// 营收管理相关 API 调用服务
  2. /// 当前使用 mock 数据,后端 API 就绪后替换为真实请求
  3. class RevenueService {
  4. RevenueService._internal();
  5. static final RevenueService instance = RevenueService._internal();
  6. factory RevenueService() => instance;
  7. // ==================== Mock 数据 ====================
  8. /// 获取月度账单列表
  9. Future<List<BillItem>> getBillList({String? period, BillStatus? status}) async {
  10. await Future.delayed(const Duration(milliseconds: 800));
  11. final bills = [
  12. BillItem(
  13. id: 'B202405-001',
  14. customerName: '张三',
  15. customerAddress: '阳光小区3-501',
  16. meterId: 'S001-501',
  17. period: '2024-05',
  18. previousReading: 1250.0,
  19. currentReading: 1285.5,
  20. usage: 35.5,
  21. unitPrice: 2.41,
  22. amount: 85.50,
  23. status: BillStatus.paid,
  24. dueDate: DateTime(2024, 6, 15),
  25. payTime: DateTime(2024, 6, 10, 14, 30),
  26. payMethod: PayMethod.wechat,
  27. ),
  28. BillItem(
  29. id: 'B202405-002',
  30. customerName: '李四',
  31. customerAddress: '翠湖花园2-302',
  32. meterId: 'S002-302',
  33. period: '2024-05',
  34. previousReading: 890.0,
  35. currentReading: 940.0,
  36. usage: 50.0,
  37. unitPrice: 2.41,
  38. amount: 120.00,
  39. status: BillStatus.unpaid,
  40. dueDate: DateTime(2024, 6, 15),
  41. ),
  42. BillItem(
  43. id: 'B202405-003',
  44. customerName: '王五',
  45. customerAddress: '东方名城8-101',
  46. meterId: 'S003-101',
  47. period: '2024-05',
  48. previousReading: 2100.0,
  49. currentReading: 2127.0,
  50. usage: 27.0,
  51. unitPrice: 2.41,
  52. amount: 65.20,
  53. status: BillStatus.paid,
  54. dueDate: DateTime(2024, 6, 15),
  55. payTime: DateTime(2024, 6, 8, 9, 15),
  56. payMethod: PayMethod.alipay,
  57. ),
  58. BillItem(
  59. id: 'B202405-004',
  60. customerName: '赵六',
  61. customerAddress: '锦绣家园5-601',
  62. meterId: 'S004-601',
  63. period: '2024-05',
  64. previousReading: 1560.0,
  65. currentReading: 1601.0,
  66. usage: 41.0,
  67. unitPrice: 2.41,
  68. amount: 98.80,
  69. status: BillStatus.overdue,
  70. dueDate: DateTime(2024, 6, 15),
  71. ),
  72. BillItem(
  73. id: 'B202405-005',
  74. customerName: '孙七',
  75. customerAddress: '阳光小区1-203',
  76. meterId: 'S001-203',
  77. period: '2024-05',
  78. previousReading: 780.0,
  79. currentReading: 810.0,
  80. usage: 30.0,
  81. unitPrice: 2.41,
  82. amount: 72.30,
  83. status: BillStatus.unpaid,
  84. dueDate: DateTime(2024, 6, 15),
  85. ),
  86. BillItem(
  87. id: 'B202405-006',
  88. customerName: '周八',
  89. customerAddress: '城东商铺A-12',
  90. meterId: 'S005-A12',
  91. period: '2024-05',
  92. previousReading: 3200.0,
  93. currentReading: 3450.0,
  94. usage: 250.0,
  95. unitPrice: 3.85,
  96. amount: 962.50,
  97. status: BillStatus.paid,
  98. dueDate: DateTime(2024, 6, 15),
  99. payTime: DateTime(2024, 6, 5, 10, 0),
  100. payMethod: PayMethod.bankTransfer,
  101. ),
  102. BillItem(
  103. id: 'B202405-007',
  104. customerName: '吴九',
  105. customerAddress: '翠湖花园5-102',
  106. meterId: 'S002-102',
  107. period: '2024-05',
  108. previousReading: 450.0,
  109. currentReading: 478.0,
  110. usage: 28.0,
  111. unitPrice: 2.41,
  112. amount: 67.48,
  113. status: BillStatus.paid,
  114. dueDate: DateTime(2024, 6, 15),
  115. payTime: DateTime(2024, 6, 12, 16, 45),
  116. payMethod: PayMethod.cash,
  117. ),
  118. BillItem(
  119. id: 'B202405-008',
  120. customerName: '郑十',
  121. customerAddress: '东方名城3-802',
  122. meterId: 'S003-802',
  123. period: '2024-05',
  124. previousReading: 1100.0,
  125. currentReading: 1155.0,
  126. usage: 55.0,
  127. unitPrice: 2.41,
  128. amount: 132.55,
  129. status: BillStatus.overdue,
  130. dueDate: DateTime(2024, 6, 15),
  131. ),
  132. ];
  133. var result = bills;
  134. if (status != null) {
  135. result = result.where((b) => b.status == status).toList();
  136. }
  137. if (period != null) {
  138. result = result.where((b) => b.period == period).toList();
  139. }
  140. return result;
  141. }
  142. /// 搜索用户(抄表录入用)
  143. Future<List<CustomerInfo>> searchCustomers(String keyword) async {
  144. await Future.delayed(const Duration(milliseconds: 500));
  145. final customers = [
  146. CustomerInfo(id: 'C001', name: '张三', address: '阳光小区3-501', meterId: 'S001-501', meterModel: 'LXS-20E', phone: '13800138001'),
  147. CustomerInfo(id: 'C002', name: '李四', address: '翠湖花园2-302', meterId: 'S002-302', meterModel: 'LXS-25E', phone: '13800138002'),
  148. CustomerInfo(id: 'C003', name: '王五', address: '东方名城8-101', meterId: 'S003-101', meterModel: 'LXS-20E', phone: '13800138003'),
  149. CustomerInfo(id: 'C004', name: '赵六', address: '锦绣家园5-601', meterId: 'S004-601', meterModel: 'LXS-32E', phone: '13800138004'),
  150. CustomerInfo(id: 'C005', name: '孙七', address: '阳光小区1-203', meterId: 'S001-203', meterModel: 'LXS-20E', phone: '13800138005'),
  151. CustomerInfo(id: 'C006', name: '周八', address: '城东商铺A-12', meterId: 'S005-A12', meterModel: 'LXS-50E', phone: '13800138006'),
  152. CustomerInfo(id: 'C007', name: '吴九', address: '翠湖花园5-102', meterId: 'S002-102', meterModel: 'LXS-20E', phone: '13800138007'),
  153. CustomerInfo(id: 'C008', name: '郑十', address: '东方名城3-802', meterId: 'S003-802', meterModel: 'LXS-25E', phone: '13800138008'),
  154. ];
  155. if (keyword.isEmpty) return customers;
  156. return customers
  157. .where((c) =>
  158. c.name.contains(keyword) ||
  159. c.meterId.contains(keyword) ||
  160. c.address.contains(keyword))
  161. .toList();
  162. }
  163. /// 提交抄表读数
  164. Future<bool> submitMeterReading({
  165. required String meterId,
  166. required double reading,
  167. String? photoPath,
  168. String? remark,
  169. }) async {
  170. await Future.delayed(const Duration(milliseconds: 700));
  171. return true;
  172. }
  173. /// 获取缴费记录
  174. Future<List<PaymentRecord>> getPaymentRecords({PaymentStatus? status}) async {
  175. await Future.delayed(const Duration(milliseconds: 700));
  176. final records = [
  177. PaymentRecord(
  178. id: 'P2024-001',
  179. customerName: '张三',
  180. customerAddress: '阳光小区3-501',
  181. meterId: 'S001-501',
  182. amount: 85.50,
  183. period: '2024-05',
  184. payTime: DateTime(2024, 6, 10, 14, 30),
  185. method: PayMethod.wechat,
  186. status: PaymentStatus.success,
  187. operator: '系统',
  188. ),
  189. PaymentRecord(
  190. id: 'P2024-002',
  191. customerName: '王五',
  192. customerAddress: '东方名城8-101',
  193. meterId: 'S003-101',
  194. amount: 65.20,
  195. period: '2024-05',
  196. payTime: DateTime(2024, 6, 8, 9, 15),
  197. method: PayMethod.alipay,
  198. status: PaymentStatus.success,
  199. operator: '系统',
  200. ),
  201. PaymentRecord(
  202. id: 'P2024-003',
  203. customerName: '周八',
  204. customerAddress: '城东商铺A-12',
  205. meterId: 'S005-A12',
  206. amount: 962.50,
  207. period: '2024-05',
  208. payTime: DateTime(2024, 6, 5, 10, 0),
  209. method: PayMethod.bankTransfer,
  210. status: PaymentStatus.success,
  211. operator: '柜台-李芳',
  212. ),
  213. PaymentRecord(
  214. id: 'P2024-004',
  215. customerName: '吴九',
  216. customerAddress: '翠湖花园5-102',
  217. meterId: 'S002-102',
  218. amount: 67.48,
  219. period: '2024-05',
  220. payTime: DateTime(2024, 6, 12, 16, 45),
  221. method: PayMethod.cash,
  222. status: PaymentStatus.success,
  223. operator: '柜台-李芳',
  224. ),
  225. PaymentRecord(
  226. id: 'P2024-005',
  227. customerName: '赵六',
  228. customerAddress: '锦绣家园5-601',
  229. meterId: 'S004-601',
  230. amount: 98.80,
  231. period: '2024-05',
  232. payTime: null,
  233. method: null,
  234. status: PaymentStatus.pending,
  235. operator: null,
  236. ),
  237. PaymentRecord(
  238. id: 'P2024-006',
  239. customerName: '郑十',
  240. customerAddress: '东方名城3-802',
  241. meterId: 'S003-802',
  242. amount: 132.55,
  243. period: '2024-05',
  244. payTime: null,
  245. method: null,
  246. status: PaymentStatus.overdue,
  247. operator: null,
  248. ),
  249. ];
  250. if (status != null) {
  251. return records.where((r) => r.status == status).toList();
  252. }
  253. return records;
  254. }
  255. /// 执行缴费操作
  256. Future<PaymentResult> payBill({
  257. required String billId,
  258. required PayMethod method,
  259. }) async {
  260. await Future.delayed(const Duration(milliseconds: 1000));
  261. return PaymentResult(
  262. success: true,
  263. transactionId: 'TXN${DateTime.now().millisecondsSinceEpoch}',
  264. message: '缴费成功',
  265. );
  266. }
  267. /// 获取营收概览
  268. Future<RevenueSummary> getRevenueSummary() async {
  269. await Future.delayed(const Duration(milliseconds: 600));
  270. return const RevenueSummary(
  271. totalAmount: 358620,
  272. paidAmount: 312450,
  273. unpaidAmount: 46170,
  274. overdueAmount: 12800,
  275. totalCustomers: 1280,
  276. paidCustomers: 1050,
  277. unpaidCustomers: 180,
  278. overdueCustomers: 50,
  279. collectionRate: 87.1,
  280. monthOverMonth: 5.8,
  281. );
  282. }
  283. }
  284. // ==================== 数据模型 ====================
  285. /// 账单状态
  286. enum BillStatus {
  287. paid('已缴费'),
  288. unpaid('待缴费'),
  289. overdue('欠费');
  290. final String label;
  291. const BillStatus(this.label);
  292. }
  293. /// 支付方式
  294. enum PayMethod {
  295. wechat('微信支付'),
  296. alipay('支付宝'),
  297. bankTransfer('银行转账'),
  298. cash('现金'),
  299. other('其他');
  300. final String label;
  301. const PayMethod(this.label);
  302. }
  303. /// 缴费状态
  304. enum PaymentStatus {
  305. success('已缴'),
  306. pending('待缴'),
  307. overdue('欠费');
  308. final String label;
  309. const PaymentStatus(this.label);
  310. }
  311. /// 账单
  312. class BillItem {
  313. final String id;
  314. final String customerName;
  315. final String customerAddress;
  316. final String meterId;
  317. final String period;
  318. final double previousReading;
  319. final double currentReading;
  320. final double usage;
  321. final double unitPrice;
  322. final double amount;
  323. final BillStatus status;
  324. final DateTime dueDate;
  325. final DateTime? payTime;
  326. final PayMethod? payMethod;
  327. const BillItem({
  328. required this.id,
  329. required this.customerName,
  330. required this.customerAddress,
  331. required this.meterId,
  332. required this.period,
  333. required this.previousReading,
  334. required this.currentReading,
  335. required this.usage,
  336. required this.unitPrice,
  337. required this.amount,
  338. required this.status,
  339. required this.dueDate,
  340. this.payTime,
  341. this.payMethod,
  342. });
  343. }
  344. /// 客户信息
  345. class CustomerInfo {
  346. final String id;
  347. final String name;
  348. final String address;
  349. final String meterId;
  350. final String meterModel;
  351. final String phone;
  352. const CustomerInfo({
  353. required this.id,
  354. required this.name,
  355. required this.address,
  356. required this.meterId,
  357. required this.meterModel,
  358. required this.phone,
  359. });
  360. }
  361. /// 缴费记录
  362. class PaymentRecord {
  363. final String id;
  364. final String customerName;
  365. final String customerAddress;
  366. final String meterId;
  367. final double amount;
  368. final String period;
  369. final DateTime? payTime;
  370. final PayMethod? method;
  371. final PaymentStatus status;
  372. final String? operator;
  373. const PaymentRecord({
  374. required this.id,
  375. required this.customerName,
  376. required this.customerAddress,
  377. required this.meterId,
  378. required this.amount,
  379. required this.period,
  380. this.payTime,
  381. this.method,
  382. required this.status,
  383. this.operator,
  384. });
  385. String get payTimeStr {
  386. if (payTime == null) return '-';
  387. return '${payTime!.year}-${payTime!.month.toString().padLeft(2, '0')}-${payTime!.day.toString().padLeft(2, '0')} '
  388. '${payTime!.hour.toString().padLeft(2, '0')}:${payTime!.minute.toString().padLeft(2, '0')}';
  389. }
  390. }
  391. /// 缴费结果
  392. class PaymentResult {
  393. final bool success;
  394. final String transactionId;
  395. final String message;
  396. const PaymentResult({
  397. required this.success,
  398. required this.transactionId,
  399. required this.message,
  400. });
  401. }
  402. /// 营收概览
  403. class RevenueSummary {
  404. final double totalAmount;
  405. final double paidAmount;
  406. final double unpaidAmount;
  407. final double overdueAmount;
  408. final int totalCustomers;
  409. final int paidCustomers;
  410. final int unpaidCustomers;
  411. final int overdueCustomers;
  412. final double collectionRate;
  413. final double monthOverMonth;
  414. const RevenueSummary({
  415. required this.totalAmount,
  416. required this.paidAmount,
  417. required this.unpaidAmount,
  418. required this.overdueAmount,
  419. required this.totalCustomers,
  420. required this.paidCustomers,
  421. required this.unpaidCustomers,
  422. required this.overdueCustomers,
  423. required this.collectionRate,
  424. required this.monthOverMonth,
  425. });
  426. }