1445 lines
182 KiB
HTML
1445 lines
182 KiB
HTML
<!DOCTYPE html>
|
||
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<meta name="generator" content="pandoc" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
|
||
<meta name="author" content="系统设计团队" />
|
||
<title>福建水务营收系统-接口设计</title>
|
||
<style>
|
||
code{white-space: pre-wrap;}
|
||
span.smallcaps{font-variant: small-caps;}
|
||
div.columns{display: flex; gap: min(4vw, 1.5em);}
|
||
div.column{flex: auto; overflow-x: auto;}
|
||
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
|
||
/* The extra [class] is a hack that increases specificity enough to
|
||
override a similar rule in reveal.js */
|
||
ul.task-list[class]{list-style: none;}
|
||
ul.task-list li input[type="checkbox"] {
|
||
font-size: inherit;
|
||
width: 0.8em;
|
||
margin: 0 0.8em 0.2em -1.6em;
|
||
vertical-align: middle;
|
||
}
|
||
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
|
||
/* CSS for syntax highlighting */
|
||
pre > code.sourceCode { white-space: pre; position: relative; }
|
||
pre > code.sourceCode > span { line-height: 1.25; }
|
||
pre > code.sourceCode > span:empty { height: 1.2em; }
|
||
.sourceCode { overflow: visible; }
|
||
code.sourceCode > span { color: inherit; text-decoration: inherit; }
|
||
div.sourceCode { margin: 1em 0; }
|
||
pre.sourceCode { margin: 0; }
|
||
@media screen {
|
||
div.sourceCode { overflow: auto; }
|
||
}
|
||
@media print {
|
||
pre > code.sourceCode { white-space: pre-wrap; }
|
||
pre > code.sourceCode > span { display: inline-block; text-indent: -5em; padding-left: 5em; }
|
||
}
|
||
pre.numberSource code
|
||
{ counter-reset: source-line 0; }
|
||
pre.numberSource code > span
|
||
{ position: relative; left: -4em; counter-increment: source-line; }
|
||
pre.numberSource code > span > a:first-child::before
|
||
{ content: counter(source-line);
|
||
position: relative; left: -1em; text-align: right; vertical-align: baseline;
|
||
border: none; display: inline-block;
|
||
-webkit-touch-callout: none; -webkit-user-select: none;
|
||
-khtml-user-select: none; -moz-user-select: none;
|
||
-ms-user-select: none; user-select: none;
|
||
padding: 0 4px; width: 4em;
|
||
color: #aaaaaa;
|
||
}
|
||
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa; padding-left: 4px; }
|
||
div.sourceCode
|
||
{ background-color: #f8f8f8; }
|
||
@media screen {
|
||
pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
|
||
}
|
||
code span.al { color: #ef2929; } /* Alert */
|
||
code span.an { color: #8f5902; font-weight: bold; font-style: italic; } /* Annotation */
|
||
code span.at { color: #204a87; } /* Attribute */
|
||
code span.bn { color: #0000cf; } /* BaseN */
|
||
code span.cf { color: #204a87; font-weight: bold; } /* ControlFlow */
|
||
code span.ch { color: #4e9a06; } /* Char */
|
||
code span.cn { color: #8f5902; } /* Constant */
|
||
code span.co { color: #8f5902; font-style: italic; } /* Comment */
|
||
code span.cv { color: #8f5902; font-weight: bold; font-style: italic; } /* CommentVar */
|
||
code span.do { color: #8f5902; font-weight: bold; font-style: italic; } /* Documentation */
|
||
code span.dt { color: #204a87; } /* DataType */
|
||
code span.dv { color: #0000cf; } /* DecVal */
|
||
code span.er { color: #a40000; font-weight: bold; } /* Error */
|
||
code span.ex { } /* Extension */
|
||
code span.fl { color: #0000cf; } /* Float */
|
||
code span.fu { color: #204a87; font-weight: bold; } /* Function */
|
||
code span.im { } /* Import */
|
||
code span.in { color: #8f5902; font-weight: bold; font-style: italic; } /* Information */
|
||
code span.kw { color: #204a87; font-weight: bold; } /* Keyword */
|
||
code span.op { color: #ce5c00; font-weight: bold; } /* Operator */
|
||
code span.ot { color: #8f5902; } /* Other */
|
||
code span.pp { color: #8f5902; font-style: italic; } /* Preprocessor */
|
||
code span.sc { color: #ce5c00; font-weight: bold; } /* SpecialChar */
|
||
code span.ss { color: #4e9a06; } /* SpecialString */
|
||
code span.st { color: #4e9a06; } /* String */
|
||
code span.va { color: #000000; } /* Variable */
|
||
code span.vs { color: #4e9a06; } /* VerbatimString */
|
||
code span.wa { color: #8f5902; font-weight: bold; font-style: italic; } /* Warning */
|
||
</style>
|
||
<link rel="stylesheet" href="output/document_style.css" />
|
||
<meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
</head>
|
||
<body>
|
||
<header id="title-block-header">
|
||
<h1 class="title">福建水务营收系统-接口设计</h1>
|
||
<p class="author">系统设计团队</p>
|
||
<p class="date">2024年12月19日</p>
|
||
</header>
|
||
<nav id="TOC" role="doc-toc">
|
||
<ul>
|
||
<li><a href="#福建水务营收系统接口设计文档"
|
||
id="toc-福建水务营收系统接口设计文档"><span
|
||
class="toc-section-number">1</span> 福建水务营收系统接口设计文档</a>
|
||
<ul>
|
||
<li><a href="#文档信息" id="toc-文档信息"><span
|
||
class="toc-section-number">1.1</span> 文档信息</a></li>
|
||
<li><a href="#目录" id="toc-目录"><span
|
||
class="toc-section-number">1.2</span> 目录</a></li>
|
||
<li><a href="#接口概述" id="toc-接口概述"><span
|
||
class="toc-section-number">1.3</span> 1. 接口概述</a>
|
||
<ul>
|
||
<li><a href="#接口设计原则" id="toc-接口设计原则"><span
|
||
class="toc-section-number">1.3.1</span> 1.1 接口设计原则</a></li>
|
||
<li><a href="#restful-api规范" id="toc-restful-api规范"><span
|
||
class="toc-section-number">1.3.2</span> 1.2 RESTful API规范</a>
|
||
<ul>
|
||
<li><a href="#资源命名" id="toc-资源命名"><span
|
||
class="toc-section-number">1.3.2.1</span> 1.2.1 资源命名</a></li>
|
||
<li><a href="#http方法" id="toc-http方法"><span
|
||
class="toc-section-number">1.3.2.2</span> 1.2.2 HTTP方法</a></li>
|
||
<li><a href="#状态码" id="toc-状态码"><span
|
||
class="toc-section-number">1.3.2.3</span> 1.2.3 状态码</a></li>
|
||
<li><a href="#响应格式" id="toc-响应格式"><span
|
||
class="toc-section-number">1.3.2.4</span> 1.2.4 响应格式</a></li>
|
||
</ul></li>
|
||
<li><a href="#接口文档" id="toc-接口文档"><span
|
||
class="toc-section-number">1.3.3</span> 1.3 接口文档</a></li>
|
||
</ul></li>
|
||
<li><a href="#外部接口" id="toc-外部接口"><span
|
||
class="toc-section-number">1.4</span> 2. 外部接口</a>
|
||
<ul>
|
||
<li><a href="#银行接口对接" id="toc-银行接口对接"><span
|
||
class="toc-section-number">1.4.1</span> 2.1 银行接口对接</a>
|
||
<ul>
|
||
<li><a href="#银行代扣接口" id="toc-银行代扣接口"><span
|
||
class="toc-section-number">1.4.1.1</span> 2.1.1 银行代扣接口</a></li>
|
||
<li><a href="#银行实时缴费接口" id="toc-银行实时缴费接口"><span
|
||
class="toc-section-number">1.4.1.2</span> 2.1.2
|
||
银行实时缴费接口</a></li>
|
||
</ul></li>
|
||
<li><a href="#支付宝接口对接" id="toc-支付宝接口对接"><span
|
||
class="toc-section-number">1.4.2</span> 2.2 支付宝接口对接</a></li>
|
||
<li><a href="#微信支付接口对接" id="toc-微信支付接口对接"><span
|
||
class="toc-section-number">1.4.3</span> 2.3 微信支付接口对接</a></li>
|
||
<li><a href="#短信接口" id="toc-短信接口"><span
|
||
class="toc-section-number">1.4.4</span> 2.4 短信接口</a></li>
|
||
<li><a href="#物联网集抄平台接口" id="toc-物联网集抄平台接口"><span
|
||
class="toc-section-number">1.4.5</span> 2.5 物联网集抄平台接口</a></li>
|
||
</ul></li>
|
||
<li><a href="#内部接口" id="toc-内部接口"><span
|
||
class="toc-section-number">1.5</span> 3. 内部接口</a>
|
||
<ul>
|
||
<li><a href="#客户管理api接口" id="toc-客户管理api接口"><span
|
||
class="toc-section-number">1.5.1</span> 3.1 客户管理API接口</a>
|
||
<ul>
|
||
<li><a href="#客户信息查询接口" id="toc-客户信息查询接口"><span
|
||
class="toc-section-number">1.5.1.1</span> 3.1.1
|
||
客户信息查询接口</a></li>
|
||
<li><a href="#客户分页查询接口" id="toc-客户分页查询接口"><span
|
||
class="toc-section-number">1.5.1.2</span> 3.1.2
|
||
客户分页查询接口</a></li>
|
||
<li><a href="#客户创建接口" id="toc-客户创建接口"><span
|
||
class="toc-section-number">1.5.1.3</span> 3.1.3 客户创建接口</a></li>
|
||
</ul></li>
|
||
<li><a href="#水表管理api接口" id="toc-水表管理api接口"><span
|
||
class="toc-section-number">1.5.2</span> 3.2 水表管理API接口</a>
|
||
<ul>
|
||
<li><a href="#水表信息查询接口" id="toc-水表信息查询接口"><span
|
||
class="toc-section-number">1.5.2.1</span> 3.2.1
|
||
水表信息查询接口</a></li>
|
||
<li><a href="#抄表记录创建接口" id="toc-抄表记录创建接口"><span
|
||
class="toc-section-number">1.5.2.2</span> 3.2.2
|
||
抄表记录创建接口</a></li>
|
||
<li><a href="#抄表数据批量导入接口" id="toc-抄表数据批量导入接口"><span
|
||
class="toc-section-number">1.5.2.3</span> 3.2.3
|
||
抄表数据批量导入接口</a></li>
|
||
</ul></li>
|
||
<li><a href="#账单管理api接口" id="toc-账单管理api接口"><span
|
||
class="toc-section-number">1.5.3</span> 3.3 账单管理API接口</a>
|
||
<ul>
|
||
<li><a href="#账单查询接口" id="toc-账单查询接口"><span
|
||
class="toc-section-number">1.5.3.1</span> 3.3.1 账单查询接口</a></li>
|
||
<li><a href="#账单生成接口" id="toc-账单生成接口"><span
|
||
class="toc-section-number">1.5.3.2</span> 3.3.2 账单生成接口</a></li>
|
||
</ul></li>
|
||
<li><a href="#缴费管理api接口" id="toc-缴费管理api接口"><span
|
||
class="toc-section-number">1.5.4</span> 3.4 缴费管理API接口</a>
|
||
<ul>
|
||
<li><a href="#缴费处理接口" id="toc-缴费处理接口"><span
|
||
class="toc-section-number">1.5.4.1</span> 3.4.1 缴费处理接口</a></li>
|
||
<li><a href="#在线支付接口" id="toc-在线支付接口"><span
|
||
class="toc-section-number">1.5.4.2</span> 3.4.2 在线支付接口</a></li>
|
||
</ul></li>
|
||
<li><a href="#工单接口" id="toc-工单接口"><span
|
||
class="toc-section-number">1.5.5</span> 3.4 工单接口</a>
|
||
<ul>
|
||
<li><a href="#工单创建接口" id="toc-工单创建接口"><span
|
||
class="toc-section-number">1.5.5.1</span> 3.4.1 工单创建接口</a></li>
|
||
<li><a href="#工单状态更新接口" id="toc-工单状态更新接口"><span
|
||
class="toc-section-number">1.5.5.2</span> 3.4.2
|
||
工单状态更新接口</a></li>
|
||
</ul></li>
|
||
</ul></li>
|
||
<li><a href="#接口标准" id="toc-接口标准"><span
|
||
class="toc-section-number">1.6</span> 4. 接口标准</a>
|
||
<ul>
|
||
<li><a href="#接口协议" id="toc-接口协议"><span
|
||
class="toc-section-number">1.6.1</span> 4.1 接口协议</a></li>
|
||
<li><a href="#数据格式" id="toc-数据格式"><span
|
||
class="toc-section-number">1.6.2</span> 4.2 数据格式</a></li>
|
||
<li><a href="#接口安全设计" id="toc-接口安全设计"><span
|
||
class="toc-section-number">1.6.3</span> 4.3 接口安全设计</a>
|
||
<ul>
|
||
<li><a href="#认证机制" id="toc-认证机制"><span
|
||
class="toc-section-number">1.6.3.1</span> 4.3.1 认证机制</a></li>
|
||
<li><a href="#数据加密" id="toc-数据加密"><span
|
||
class="toc-section-number">1.6.3.2</span> 4.3.2 数据加密</a></li>
|
||
<li><a href="#访问控制" id="toc-访问控制"><span
|
||
class="toc-section-number">1.6.3.3</span> 4.3.3 访问控制</a></li>
|
||
<li><a href="#接口限流" id="toc-接口限流"><span
|
||
class="toc-section-number">1.6.3.4</span> 4.3.4 接口限流</a></li>
|
||
</ul></li>
|
||
<li><a href="#错误处理机制" id="toc-错误处理机制"><span
|
||
class="toc-section-number">1.6.4</span> 4.4 错误处理机制</a>
|
||
<ul>
|
||
<li><a href="#统一异常处理" id="toc-统一异常处理"><span
|
||
class="toc-section-number">1.6.4.1</span> 4.4.1 统一异常处理</a></li>
|
||
<li><a href="#错误码定义" id="toc-错误码定义"><span
|
||
class="toc-section-number">1.6.4.2</span> 4.4.2 错误码定义</a></li>
|
||
<li><a href="#接口调用示例" id="toc-接口调用示例"><span
|
||
class="toc-section-number">1.6.4.3</span> 4.4.3 接口调用示例</a></li>
|
||
</ul></li>
|
||
<li><a href="#前端接口调用示例" id="toc-前端接口调用示例"><span
|
||
class="toc-section-number">1.6.5</span> 4.5 前端接口调用示例</a>
|
||
<ul>
|
||
<li><a href="#vue3-typescript接口封装"
|
||
id="toc-vue3-typescript接口封装"><span
|
||
class="toc-section-number">1.6.5.1</span> 4.5.1 Vue3 +
|
||
TypeScript接口封装</a></li>
|
||
<li><a href="#vue组件使用示例" id="toc-vue组件使用示例"><span
|
||
class="toc-section-number">1.6.5.2</span> 4.5.2 Vue组件使用示例</a></li>
|
||
</ul></li>
|
||
</ul></li>
|
||
</ul></li>
|
||
</ul>
|
||
</nav>
|
||
<h1 data-number="1" id="福建水务营收系统接口设计文档"><span
|
||
class="header-section-number">1</span> 福建水务营收系统接口设计文档</h1>
|
||
<h2 data-number="1.1" id="文档信息"><span
|
||
class="header-section-number">1.1</span> 文档信息</h2>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>项目信息</th>
|
||
<th>详情</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><strong>项目名称</strong></td>
|
||
<td>福建水务营收系统</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>文档类型</strong></td>
|
||
<td>概要设计文档</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>技术框架</strong></td>
|
||
<td>RuoYi-Vue-Pro + yudao-ui-admin-vue3</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>文档版本</strong></td>
|
||
<td>v1.0</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>编写日期</strong></td>
|
||
<td>2024-12-19</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>文档状态</strong></td>
|
||
<td>🟡 进行中</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<h2 data-number="1.2" id="目录"><span
|
||
class="header-section-number">1.2</span> 目录</h2>
|
||
<ul>
|
||
<li><a href="#1-接口概述">1. 接口概述</a></li>
|
||
<li><a href="#2-外部接口">2. 外部接口</a></li>
|
||
<li><a href="#3-内部接口">3. 内部接口</a></li>
|
||
<li><a href="#4-接口标准">4. 接口标准</a></li>
|
||
</ul>
|
||
<h2 data-number="1.3" id="接口概述"><span
|
||
class="header-section-number">1.3</span> 1. 接口概述</h2>
|
||
<p>福建水务业务系统提供丰富的接口,用于与外部系统集成以及系统内部各模块间的数据交换。接口设计遵循标准化、安全性、可扩展性的原则,基于RuoYi-Vue-Pro框架采用RESTful风格设计,支持JSON数据格式。</p>
|
||
<h3 data-number="1.3.1" id="接口设计原则"><span
|
||
class="header-section-number">1.3.1</span> 1.1 接口设计原则</h3>
|
||
<ul>
|
||
<li><strong>统一性</strong>:所有接口遵循统一的设计规范和数据格式</li>
|
||
<li><strong>安全性</strong>:接口通过认证授权、参数校验等机制保障安全</li>
|
||
<li><strong>可维护性</strong>:接口文档完善,便于维护和升级</li>
|
||
<li><strong>兼容性</strong>:接口设计考虑版本兼容,支持平滑升级</li>
|
||
<li><strong>性能优化</strong>:接口设计考虑性能,支持缓存、分页等机制</li>
|
||
</ul>
|
||
<h3 data-number="1.3.2" id="restful-api规范"><span
|
||
class="header-section-number">1.3.2</span> 1.2 RESTful API规范</h3>
|
||
<p>系统API接口采用RESTful风格设计,主要规范如下:</p>
|
||
<h4 data-number="1.3.2.1" id="资源命名"><span
|
||
class="header-section-number">1.3.2.1</span> 1.2.1 资源命名</h4>
|
||
<ul>
|
||
<li>使用名词复数表示资源集合,如<code>/users</code>、<code>/meters</code></li>
|
||
<li>使用资源ID标识特定资源,如<code>/users/1</code>、<code>/meters/123</code></li>
|
||
<li>资源层级关系通过路径嵌套表示,如<code>/users/1/meters</code></li>
|
||
</ul>
|
||
<h4 data-number="1.3.2.2" id="http方法"><span
|
||
class="header-section-number">1.3.2.2</span> 1.2.2 HTTP方法</h4>
|
||
<ul>
|
||
<li>GET:获取资源</li>
|
||
<li>POST:创建资源</li>
|
||
<li>PUT:更新资源(全量更新)</li>
|
||
<li>PATCH:部分更新资源</li>
|
||
<li>DELETE:删除资源</li>
|
||
</ul>
|
||
<h4 data-number="1.3.2.3" id="状态码"><span
|
||
class="header-section-number">1.3.2.3</span> 1.2.3 状态码</h4>
|
||
<ul>
|
||
<li>200 OK:请求成功</li>
|
||
<li>201 Created:资源创建成功</li>
|
||
<li>400 Bad Request:请求参数错误</li>
|
||
<li>401 Unauthorized:未授权</li>
|
||
<li>403 Forbidden:权限不足</li>
|
||
<li>404 Not Found:资源不存在</li>
|
||
<li>500 Internal Server Error:服务器内部错误</li>
|
||
</ul>
|
||
<h4 data-number="1.3.2.4" id="响应格式"><span
|
||
class="header-section-number">1.3.2.4</span> 1.2.4 响应格式</h4>
|
||
<p>系统统一采用以下JSON格式响应:</p>
|
||
<div class="sourceCode" id="cb1"><pre
|
||
class="sourceCode json"><code class="sourceCode json"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
|
||
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">"code"</span><span class="fu">:</span> <span class="dv">0</span><span class="fu">,</span> <span class="er">//</span> <span class="er">业务状态码,0表示成功,非0表示失败</span></span>
|
||
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">"data"</span><span class="fu">:</span> <span class="fu">{},</span> <span class="er">//</span> <span class="er">响应数据</span></span>
|
||
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">"msg"</span><span class="fu">:</span> <span class="st">"success"</span> <span class="er">//</span> <span class="er">响应消息</span></span>
|
||
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
|
||
<p>分页查询响应格式:</p>
|
||
<div class="sourceCode" id="cb2"><pre
|
||
class="sourceCode json"><code class="sourceCode json"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
|
||
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">"code"</span><span class="fu">:</span> <span class="dv">0</span><span class="fu">,</span></span>
|
||
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">"data"</span><span class="fu">:</span> <span class="fu">{</span></span>
|
||
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">"list"</span><span class="fu">:</span> <span class="ot">[]</span><span class="fu">,</span> <span class="er">//</span> <span class="er">数据列表</span></span>
|
||
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a> <span class="dt">"total"</span><span class="fu">:</span> <span class="dv">100</span><span class="fu">,</span> <span class="er">//</span> <span class="er">总记录数</span></span>
|
||
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a> <span class="dt">"pageNum"</span><span class="fu">:</span> <span class="dv">1</span><span class="fu">,</span> <span class="er">//</span> <span class="er">当前页码</span></span>
|
||
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a> <span class="dt">"pageSize"</span><span class="fu">:</span> <span class="dv">10</span> <span class="er">//</span> <span class="er">每页记录数</span></span>
|
||
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a> <span class="fu">},</span></span>
|
||
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a> <span class="dt">"msg"</span><span class="fu">:</span> <span class="st">"success"</span></span>
|
||
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
|
||
<h3 data-number="1.3.3" id="接口文档"><span
|
||
class="header-section-number">1.3.3</span> 1.3 接口文档</h3>
|
||
<p>系统使用Knife4j(基于Swagger)自动生成API文档,文档地址为:<code>http://{系统地址}/doc.html</code>。</p>
|
||
<p>主要特点: - 在线接口文档:支持在线查看接口定义 -
|
||
接口调试:支持在线调试接口 - 文档导出:支持导出OpenAPI规范文档 -
|
||
权限控制:支持对接口文档的访问控制</p>
|
||
<h2 data-number="1.4" id="外部接口"><span
|
||
class="header-section-number">1.4</span> 2. 外部接口</h2>
|
||
<h3 data-number="1.4.1" id="银行接口对接"><span
|
||
class="header-section-number">1.4.1</span> 2.1 银行接口对接</h3>
|
||
<h4 data-number="1.4.1.1" id="银行代扣接口"><span
|
||
class="header-section-number">1.4.1.1</span> 2.1.1 银行代扣接口</h4>
|
||
<p><strong>功能描述</strong>:通过银行系统自动从用户账户中扣除水费。</p>
|
||
<p><strong>接口详情</strong>: -
|
||
<strong>接口方式</strong>:文件交换(FTP/SFTP) -
|
||
<strong>数据格式</strong>:定长文本文件 -
|
||
<strong>交换频率</strong>:每日凌晨2:00 -
|
||
<strong>文件编码</strong>:GBK</p>
|
||
<p><strong>代扣文件格式</strong>:</p>
|
||
<pre class="text"><code>记录类型(1位) + 客户号(12位) + 户名(30位) + 银行账号(20位) + 扣款金额(12位,含2位小数) + 账期(6位) + 保留字段(19位)</code></pre>
|
||
<p><strong>代扣文件示例</strong>:</p>
|
||
<pre class="text"><code>1C00000000001张三 62172511001234567890000009180202412
|
||
1C00000000002李四 62172511001234567891000015460202412 </code></pre>
|
||
<p><strong>回盘文件格式</strong>:</p>
|
||
<pre class="text"><code>记录类型(1位) + 客户号(12位) + 银行账号(20位) + 扣款金额(12位) + 处理状态(1位) + 银行流水号(20位) + 处理时间(14位) + 失败原因(20位)</code></pre>
|
||
<p><strong>Java实现示例</strong>:</p>
|
||
<div class="sourceCode" id="cb6"><pre
|
||
class="sourceCode java"><code class="sourceCode java"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="at">@Service</span></span>
|
||
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> <span class="kw">class</span> BankDeductServiceImpl <span class="kw">implements</span> BankDeductService <span class="op">{</span></span>
|
||
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a> <span class="at">@Resource</span></span>
|
||
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a> <span class="kw">private</span> SftpTemplate sftpTemplate<span class="op">;</span></span>
|
||
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a> <span class="at">@Resource</span></span>
|
||
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a> <span class="kw">private</span> BillService billService<span class="op">;</span></span>
|
||
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true" tabindex="-1"></a> <span class="at">@Scheduled</span><span class="op">(</span>cron <span class="op">=</span> <span class="st">"0 0 2 * * ?"</span><span class="op">)</span></span>
|
||
<span id="cb6-10"><a href="#cb6-10" aria-hidden="true" tabindex="-1"></a> <span class="kw">public</span> <span class="dt">void</span> <span class="fu">generateDeductFile</span><span class="op">()</span> <span class="op">{</span></span>
|
||
<span id="cb6-11"><a href="#cb6-11" aria-hidden="true" tabindex="-1"></a> LocalDate deductDate <span class="op">=</span> LocalDate<span class="op">.</span><span class="fu">now</span><span class="op">();</span></span>
|
||
<span id="cb6-12"><a href="#cb6-12" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb6-13"><a href="#cb6-13" aria-hidden="true" tabindex="-1"></a> <span class="co">// 获取待代扣账单</span></span>
|
||
<span id="cb6-14"><a href="#cb6-14" aria-hidden="true" tabindex="-1"></a> <span class="bu">List</span><span class="op"><</span>BillDO<span class="op">></span> deductBills <span class="op">=</span> billService<span class="op">.</span><span class="fu">getDeductBills</span><span class="op">(</span>deductDate<span class="op">);</span></span>
|
||
<span id="cb6-15"><a href="#cb6-15" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb6-16"><a href="#cb6-16" aria-hidden="true" tabindex="-1"></a> <span class="co">// 生成代扣文件</span></span>
|
||
<span id="cb6-17"><a href="#cb6-17" aria-hidden="true" tabindex="-1"></a> <span class="bu">String</span> fileName <span class="op">=</span> <span class="st">"DEDUCT_"</span> <span class="op">+</span> deductDate<span class="op">.</span><span class="fu">format</span><span class="op">(</span>DateTimeFormatter<span class="op">.</span><span class="fu">ofPattern</span><span class="op">(</span><span class="st">"yyyyMMdd"</span><span class="op">))</span> <span class="op">+</span> <span class="st">".txt"</span><span class="op">;</span></span>
|
||
<span id="cb6-18"><a href="#cb6-18" aria-hidden="true" tabindex="-1"></a> <span class="bu">String</span> fileContent <span class="op">=</span> <span class="fu">buildDeductFileContent</span><span class="op">(</span>deductBills<span class="op">);</span></span>
|
||
<span id="cb6-19"><a href="#cb6-19" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb6-20"><a href="#cb6-20" aria-hidden="true" tabindex="-1"></a> <span class="co">// 上传至银行SFTP</span></span>
|
||
<span id="cb6-21"><a href="#cb6-21" aria-hidden="true" tabindex="-1"></a> sftpTemplate<span class="op">.</span><span class="fu">put</span><span class="op">(</span>fileName<span class="op">,</span> fileContent<span class="op">.</span><span class="fu">getBytes</span><span class="op">(</span>StandardCharsets<span class="op">.</span><span class="fu">UTF_8</span><span class="op">),</span> <span class="st">"/upload/"</span><span class="op">);</span></span>
|
||
<span id="cb6-22"><a href="#cb6-22" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb6-23"><a href="#cb6-23" aria-hidden="true" tabindex="-1"></a> <span class="co">// 记录代扣文件日志</span></span>
|
||
<span id="cb6-24"><a href="#cb6-24" aria-hidden="true" tabindex="-1"></a> DeductFileLogDO log <span class="op">=</span> <span class="kw">new</span> <span class="fu">DeductFileLogDO</span><span class="op">();</span></span>
|
||
<span id="cb6-25"><a href="#cb6-25" aria-hidden="true" tabindex="-1"></a> log<span class="op">.</span><span class="fu">setFileName</span><span class="op">(</span>fileName<span class="op">);</span></span>
|
||
<span id="cb6-26"><a href="#cb6-26" aria-hidden="true" tabindex="-1"></a> log<span class="op">.</span><span class="fu">setFileStatus</span><span class="op">(</span><span class="st">"UPLOADED"</span><span class="op">);</span></span>
|
||
<span id="cb6-27"><a href="#cb6-27" aria-hidden="true" tabindex="-1"></a> log<span class="op">.</span><span class="fu">setRecordCount</span><span class="op">(</span>deductBills<span class="op">.</span><span class="fu">size</span><span class="op">());</span></span>
|
||
<span id="cb6-28"><a href="#cb6-28" aria-hidden="true" tabindex="-1"></a> deductFileLogMapper<span class="op">.</span><span class="fu">insert</span><span class="op">(</span>log<span class="op">);</span></span>
|
||
<span id="cb6-29"><a href="#cb6-29" aria-hidden="true" tabindex="-1"></a> <span class="op">}</span></span>
|
||
<span id="cb6-30"><a href="#cb6-30" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb6-31"><a href="#cb6-31" aria-hidden="true" tabindex="-1"></a> <span class="kw">private</span> <span class="bu">String</span> <span class="fu">buildDeductFileContent</span><span class="op">(</span><span class="bu">List</span><span class="op"><</span>BillDO<span class="op">></span> bills<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb6-32"><a href="#cb6-32" aria-hidden="true" tabindex="-1"></a> <span class="bu">StringBuilder</span> content <span class="op">=</span> <span class="kw">new</span> <span class="bu">StringBuilder</span><span class="op">();</span></span>
|
||
<span id="cb6-33"><a href="#cb6-33" aria-hidden="true" tabindex="-1"></a> <span class="cf">for</span> <span class="op">(</span>BillDO bill <span class="op">:</span> bills<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb6-34"><a href="#cb6-34" aria-hidden="true" tabindex="-1"></a> content<span class="op">.</span><span class="fu">append</span><span class="op">(</span><span class="st">"1"</span><span class="op">)</span> <span class="co">// 记录类型</span></span>
|
||
<span id="cb6-35"><a href="#cb6-35" aria-hidden="true" tabindex="-1"></a> <span class="op">.</span><span class="fu">append</span><span class="op">(</span>StringUtils<span class="op">.</span><span class="fu">rightPad</span><span class="op">(</span>bill<span class="op">.</span><span class="fu">getCustomerCode</span><span class="op">(),</span> <span class="dv">12</span><span class="op">))</span> <span class="co">// 客户号</span></span>
|
||
<span id="cb6-36"><a href="#cb6-36" aria-hidden="true" tabindex="-1"></a> <span class="op">.</span><span class="fu">append</span><span class="op">(</span>StringUtils<span class="op">.</span><span class="fu">rightPad</span><span class="op">(</span>bill<span class="op">.</span><span class="fu">getCustomerName</span><span class="op">(),</span> <span class="dv">30</span><span class="op">))</span> <span class="co">// 户名</span></span>
|
||
<span id="cb6-37"><a href="#cb6-37" aria-hidden="true" tabindex="-1"></a> <span class="op">.</span><span class="fu">append</span><span class="op">(</span>StringUtils<span class="op">.</span><span class="fu">rightPad</span><span class="op">(</span>bill<span class="op">.</span><span class="fu">getBankAccount</span><span class="op">(),</span> <span class="dv">20</span><span class="op">))</span> <span class="co">// 银行账号</span></span>
|
||
<span id="cb6-38"><a href="#cb6-38" aria-hidden="true" tabindex="-1"></a> <span class="op">.</span><span class="fu">append</span><span class="op">(</span><span class="bu">String</span><span class="op">.</span><span class="fu">format</span><span class="op">(</span><span class="st">"</span><span class="sc">%012d</span><span class="st">"</span><span class="op">,</span> bill<span class="op">.</span><span class="fu">getTotalAmount</span><span class="op">().</span><span class="fu">multiply</span><span class="op">(</span><span class="kw">new</span> <span class="bu">BigDecimal</span><span class="op">(</span><span class="dv">100</span><span class="op">)).</span><span class="fu">intValue</span><span class="op">()))</span> <span class="co">// 金额(分)</span></span>
|
||
<span id="cb6-39"><a href="#cb6-39" aria-hidden="true" tabindex="-1"></a> <span class="op">.</span><span class="fu">append</span><span class="op">(</span>bill<span class="op">.</span><span class="fu">getBillMonth</span><span class="op">().</span><span class="fu">replace</span><span class="op">(</span><span class="st">"-"</span><span class="op">,</span> <span class="st">""</span><span class="op">))</span> <span class="co">// 账期</span></span>
|
||
<span id="cb6-40"><a href="#cb6-40" aria-hidden="true" tabindex="-1"></a> <span class="op">.</span><span class="fu">append</span><span class="op">(</span>StringUtils<span class="op">.</span><span class="fu">repeat</span><span class="op">(</span><span class="st">" "</span><span class="op">,</span> <span class="dv">19</span><span class="op">))</span> <span class="co">// 保留字段</span></span>
|
||
<span id="cb6-41"><a href="#cb6-41" aria-hidden="true" tabindex="-1"></a> <span class="op">.</span><span class="fu">append</span><span class="op">(</span><span class="st">"</span></span>
|
||
<span id="cb6-42"><a href="#cb6-42" aria-hidden="true" tabindex="-1"></a><span class="st">");</span></span>
|
||
<span id="cb6-43"><a href="#cb6-43" aria-hidden="true" tabindex="-1"></a> <span class="op">}</span></span>
|
||
<span id="cb6-44"><a href="#cb6-44" aria-hidden="true" tabindex="-1"></a> <span class="cf">return</span> content<span class="op">.</span><span class="fu">toString</span><span class="op">();</span></span>
|
||
<span id="cb6-45"><a href="#cb6-45" aria-hidden="true" tabindex="-1"></a> <span class="op">}</span></span>
|
||
<span id="cb6-46"><a href="#cb6-46" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
|
||
<h4 data-number="1.4.1.2" id="银行实时缴费接口"><span
|
||
class="header-section-number">1.4.1.2</span> 2.1.2 银行实时缴费接口</h4>
|
||
<p><strong>功能描述</strong>:用户在银行柜台、网上银行或手机银行实时缴纳水费。</p>
|
||
<p><strong>接口详情</strong>: - <strong>接口方式</strong>:HTTP POST -
|
||
<strong>请求URL</strong>:<code>https://bank.api.com/payment/water-fee</code>
|
||
- <strong>数据格式</strong>:JSON - <strong>认证方式</strong>:API Key +
|
||
签名</p>
|
||
<p><strong>请求参数</strong>:</p>
|
||
<div class="sourceCode" id="cb7"><pre
|
||
class="sourceCode json"><code class="sourceCode json"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
|
||
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">"merchantId"</span><span class="fu">:</span> <span class="st">"WATER001"</span><span class="fu">,</span></span>
|
||
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">"customerCode"</span><span class="fu">:</span> <span class="st">"C001"</span><span class="fu">,</span></span>
|
||
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">"billCodes"</span><span class="fu">:</span> <span class="ot">[</span><span class="st">"B202412190001"</span><span class="ot">]</span><span class="fu">,</span></span>
|
||
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a> <span class="dt">"totalAmount"</span><span class="fu">:</span> <span class="fl">91.80</span><span class="fu">,</span></span>
|
||
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a> <span class="dt">"bankAccount"</span><span class="fu">:</span> <span class="st">"6217251100123456789"</span><span class="fu">,</span></span>
|
||
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a> <span class="dt">"customerName"</span><span class="fu">:</span> <span class="st">"张三"</span><span class="fu">,</span></span>
|
||
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a> <span class="dt">"timestamp"</span><span class="fu">:</span> <span class="st">"20241219103000"</span><span class="fu">,</span></span>
|
||
<span id="cb7-9"><a href="#cb7-9" aria-hidden="true" tabindex="-1"></a> <span class="dt">"signature"</span><span class="fu">:</span> <span class="st">"ABC123DEF456..."</span></span>
|
||
<span id="cb7-10"><a href="#cb7-10" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
|
||
<p><strong>响应参数</strong>:</p>
|
||
<div class="sourceCode" id="cb8"><pre
|
||
class="sourceCode json"><code class="sourceCode json"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
|
||
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">"resultCode"</span><span class="fu">:</span> <span class="st">"0000"</span><span class="fu">,</span></span>
|
||
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">"resultMsg"</span><span class="fu">:</span> <span class="st">"交易成功"</span><span class="fu">,</span></span>
|
||
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">"data"</span><span class="fu">:</span> <span class="fu">{</span></span>
|
||
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a> <span class="dt">"transactionId"</span><span class="fu">:</span> <span class="st">"TXN20241219001"</span><span class="fu">,</span></span>
|
||
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a> <span class="dt">"paymentTime"</span><span class="fu">:</span> <span class="st">"20241219103001"</span><span class="fu">,</span></span>
|
||
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a> <span class="dt">"bankSerial"</span><span class="fu">:</span> <span class="st">"BNK20241219001234"</span></span>
|
||
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a> <span class="fu">}</span></span>
|
||
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
|
||
<h3 data-number="1.4.2" id="支付宝接口对接"><span
|
||
class="header-section-number">1.4.2</span> 2.2 支付宝接口对接</h3>
|
||
<p><strong>功能描述</strong>:用户通过支付宝缴纳水费,支持扫码支付和H5支付。</p>
|
||
<p><strong>接口详情</strong>: - <strong>接口方式</strong>:HTTP POST -
|
||
<strong>支付方式</strong>:统一收单交易预创建(alipay.trade.precreate)
|
||
- <strong>数据格式</strong>:JSON -
|
||
<strong>认证方式</strong>:RSA2签名</p>
|
||
<p><strong>预创建支付请求参数</strong>:</p>
|
||
<div class="sourceCode" id="cb9"><pre
|
||
class="sourceCode json"><code class="sourceCode json"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
|
||
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">"app_id"</span><span class="fu">:</span> <span class="st">"2021001234567890"</span><span class="fu">,</span></span>
|
||
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">"method"</span><span class="fu">:</span> <span class="st">"alipay.trade.precreate"</span><span class="fu">,</span> </span>
|
||
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">"charset"</span><span class="fu">:</span> <span class="st">"UTF-8"</span><span class="fu">,</span></span>
|
||
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a> <span class="dt">"sign_type"</span><span class="fu">:</span> <span class="st">"RSA2"</span><span class="fu">,</span></span>
|
||
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a> <span class="dt">"timestamp"</span><span class="fu">:</span> <span class="st">"2024-12-19 10:30:00"</span><span class="fu">,</span></span>
|
||
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a> <span class="dt">"version"</span><span class="fu">:</span> <span class="st">"1.0"</span><span class="fu">,</span></span>
|
||
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true" tabindex="-1"></a> <span class="dt">"notify_url"</span><span class="fu">:</span> <span class="st">"https://water.example.com/api/payment/alipay/notify"</span><span class="fu">,</span></span>
|
||
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true" tabindex="-1"></a> <span class="dt">"biz_content"</span><span class="fu">:</span> <span class="fu">{</span></span>
|
||
<span id="cb9-10"><a href="#cb9-10" aria-hidden="true" tabindex="-1"></a> <span class="dt">"out_trade_no"</span><span class="fu">:</span> <span class="st">"P202412190002"</span><span class="fu">,</span></span>
|
||
<span id="cb9-11"><a href="#cb9-11" aria-hidden="true" tabindex="-1"></a> <span class="dt">"total_amount"</span><span class="fu">:</span> <span class="st">"91.80"</span><span class="fu">,</span></span>
|
||
<span id="cb9-12"><a href="#cb9-12" aria-hidden="true" tabindex="-1"></a> <span class="dt">"subject"</span><span class="fu">:</span> <span class="st">"水费缴费"</span><span class="fu">,</span></span>
|
||
<span id="cb9-13"><a href="#cb9-13" aria-hidden="true" tabindex="-1"></a> <span class="dt">"body"</span><span class="fu">:</span> <span class="st">"2024年12月水费-客户编号:C001"</span><span class="fu">,</span></span>
|
||
<span id="cb9-14"><a href="#cb9-14" aria-hidden="true" tabindex="-1"></a> <span class="dt">"store_id"</span><span class="fu">:</span> <span class="st">"WATER_STORE_001"</span><span class="fu">,</span></span>
|
||
<span id="cb9-15"><a href="#cb9-15" aria-hidden="true" tabindex="-1"></a> <span class="dt">"timeout_express"</span><span class="fu">:</span> <span class="st">"30m"</span></span>
|
||
<span id="cb9-16"><a href="#cb9-16" aria-hidden="true" tabindex="-1"></a> <span class="fu">}</span></span>
|
||
<span id="cb9-17"><a href="#cb9-17" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
|
||
<p><strong>支付宝响应参数</strong>:</p>
|
||
<div class="sourceCode" id="cb10"><pre
|
||
class="sourceCode json"><code class="sourceCode json"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
|
||
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">"alipay_trade_precreate_response"</span><span class="fu">:</span> <span class="fu">{</span></span>
|
||
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">"code"</span><span class="fu">:</span> <span class="st">"10000"</span><span class="fu">,</span></span>
|
||
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">"msg"</span><span class="fu">:</span> <span class="st">"Success"</span><span class="fu">,</span></span>
|
||
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a> <span class="dt">"out_trade_no"</span><span class="fu">:</span> <span class="st">"P202412190002"</span><span class="fu">,</span></span>
|
||
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a> <span class="dt">"qr_code"</span><span class="fu">:</span> <span class="st">"https://qr.alipay.com/bax08945xtdnfwgqmwi200b4"</span></span>
|
||
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a> <span class="fu">},</span></span>
|
||
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true" tabindex="-1"></a> <span class="dt">"sign"</span><span class="fu">:</span> <span class="st">"ERITJKEIJKJHKKKKKKKHJEREEEEEEEEEEE"</span></span>
|
||
<span id="cb10-9"><a href="#cb10-9" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
|
||
<p><strong>Java实现示例</strong>:</p>
|
||
<div class="sourceCode" id="cb11"><pre
|
||
class="sourceCode java"><code class="sourceCode java"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="at">@Service</span></span>
|
||
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> <span class="kw">class</span> AlipayServiceImpl <span class="kw">implements</span> AlipayService <span class="op">{</span></span>
|
||
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a> <span class="at">@Resource</span></span>
|
||
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a> <span class="kw">private</span> AlipayClient alipayClient<span class="op">;</span></span>
|
||
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb11-7"><a href="#cb11-7" aria-hidden="true" tabindex="-1"></a> <span class="at">@Override</span></span>
|
||
<span id="cb11-8"><a href="#cb11-8" aria-hidden="true" tabindex="-1"></a> <span class="kw">public</span> AlipayPaymentRespVO <span class="fu">createPayment</span><span class="op">(</span>AlipayPaymentReqVO request<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb11-9"><a href="#cb11-9" aria-hidden="true" tabindex="-1"></a> AlipayTradePrecreateRequest alipayRequest <span class="op">=</span> <span class="kw">new</span> <span class="fu">AlipayTradePrecreateRequest</span><span class="op">();</span></span>
|
||
<span id="cb11-10"><a href="#cb11-10" aria-hidden="true" tabindex="-1"></a> alipayRequest<span class="op">.</span><span class="fu">setNotifyUrl</span><span class="op">(</span><span class="st">"https://water.example.com/api/payment/alipay/notify"</span><span class="op">);</span></span>
|
||
<span id="cb11-11"><a href="#cb11-11" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb11-12"><a href="#cb11-12" aria-hidden="true" tabindex="-1"></a> AlipayTradePrecreateModel model <span class="op">=</span> <span class="kw">new</span> <span class="fu">AlipayTradePrecreateModel</span><span class="op">();</span></span>
|
||
<span id="cb11-13"><a href="#cb11-13" aria-hidden="true" tabindex="-1"></a> model<span class="op">.</span><span class="fu">setOutTradeNo</span><span class="op">(</span>request<span class="op">.</span><span class="fu">getPaymentCode</span><span class="op">());</span></span>
|
||
<span id="cb11-14"><a href="#cb11-14" aria-hidden="true" tabindex="-1"></a> model<span class="op">.</span><span class="fu">setTotalAmount</span><span class="op">(</span>request<span class="op">.</span><span class="fu">getTotalAmount</span><span class="op">().</span><span class="fu">toString</span><span class="op">());</span></span>
|
||
<span id="cb11-15"><a href="#cb11-15" aria-hidden="true" tabindex="-1"></a> model<span class="op">.</span><span class="fu">setSubject</span><span class="op">(</span><span class="st">"水费缴费"</span><span class="op">);</span></span>
|
||
<span id="cb11-16"><a href="#cb11-16" aria-hidden="true" tabindex="-1"></a> model<span class="op">.</span><span class="fu">setBody</span><span class="op">(</span><span class="st">"账单号:"</span> <span class="op">+</span> <span class="bu">String</span><span class="op">.</span><span class="fu">join</span><span class="op">(</span><span class="st">","</span><span class="op">,</span> request<span class="op">.</span><span class="fu">getBillCodes</span><span class="op">()));</span></span>
|
||
<span id="cb11-17"><a href="#cb11-17" aria-hidden="true" tabindex="-1"></a> model<span class="op">.</span><span class="fu">setTimeoutExpress</span><span class="op">(</span><span class="st">"30m"</span><span class="op">);</span></span>
|
||
<span id="cb11-18"><a href="#cb11-18" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb11-19"><a href="#cb11-19" aria-hidden="true" tabindex="-1"></a> alipayRequest<span class="op">.</span><span class="fu">setBizModel</span><span class="op">(</span>model<span class="op">);</span></span>
|
||
<span id="cb11-20"><a href="#cb11-20" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb11-21"><a href="#cb11-21" aria-hidden="true" tabindex="-1"></a> <span class="cf">try</span> <span class="op">{</span></span>
|
||
<span id="cb11-22"><a href="#cb11-22" aria-hidden="true" tabindex="-1"></a> AlipayTradePrecreateResponse response <span class="op">=</span> alipayClient<span class="op">.</span><span class="fu">execute</span><span class="op">(</span>alipayRequest<span class="op">);</span></span>
|
||
<span id="cb11-23"><a href="#cb11-23" aria-hidden="true" tabindex="-1"></a> <span class="cf">if</span> <span class="op">(</span>response<span class="op">.</span><span class="fu">isSuccess</span><span class="op">())</span> <span class="op">{</span></span>
|
||
<span id="cb11-24"><a href="#cb11-24" aria-hidden="true" tabindex="-1"></a> <span class="cf">return</span> AlipayPaymentRespVO<span class="op">.</span><span class="fu">builder</span><span class="op">()</span></span>
|
||
<span id="cb11-25"><a href="#cb11-25" aria-hidden="true" tabindex="-1"></a> <span class="op">.</span><span class="fu">paymentCode</span><span class="op">(</span>request<span class="op">.</span><span class="fu">getPaymentCode</span><span class="op">())</span></span>
|
||
<span id="cb11-26"><a href="#cb11-26" aria-hidden="true" tabindex="-1"></a> <span class="op">.</span><span class="fu">qrCode</span><span class="op">(</span>response<span class="op">.</span><span class="fu">getQrCode</span><span class="op">())</span></span>
|
||
<span id="cb11-27"><a href="#cb11-27" aria-hidden="true" tabindex="-1"></a> <span class="op">.</span><span class="fu">outTradeNo</span><span class="op">(</span>response<span class="op">.</span><span class="fu">getOutTradeNo</span><span class="op">())</span></span>
|
||
<span id="cb11-28"><a href="#cb11-28" aria-hidden="true" tabindex="-1"></a> <span class="op">.</span><span class="fu">build</span><span class="op">();</span></span>
|
||
<span id="cb11-29"><a href="#cb11-29" aria-hidden="true" tabindex="-1"></a> <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></span>
|
||
<span id="cb11-30"><a href="#cb11-30" aria-hidden="true" tabindex="-1"></a> <span class="cf">throw</span> <span class="kw">new</span> <span class="fu">BizException</span><span class="op">(</span>ALIPAY_PAY_FAILED<span class="op">,</span> response<span class="op">.</span><span class="fu">getSubMsg</span><span class="op">());</span></span>
|
||
<span id="cb11-31"><a href="#cb11-31" aria-hidden="true" tabindex="-1"></a> <span class="op">}</span></span>
|
||
<span id="cb11-32"><a href="#cb11-32" aria-hidden="true" tabindex="-1"></a> <span class="op">}</span> <span class="cf">catch</span> <span class="op">(</span>AlipayApiException e<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb11-33"><a href="#cb11-33" aria-hidden="true" tabindex="-1"></a> <span class="cf">throw</span> <span class="kw">new</span> <span class="fu">BizException</span><span class="op">(</span>ALIPAY_PAY_ERROR<span class="op">,</span> e<span class="op">.</span><span class="fu">getErrMsg</span><span class="op">());</span></span>
|
||
<span id="cb11-34"><a href="#cb11-34" aria-hidden="true" tabindex="-1"></a> <span class="op">}</span></span>
|
||
<span id="cb11-35"><a href="#cb11-35" aria-hidden="true" tabindex="-1"></a> <span class="op">}</span></span>
|
||
<span id="cb11-36"><a href="#cb11-36" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
|
||
<h3 data-number="1.4.3" id="微信支付接口对接"><span
|
||
class="header-section-number">1.4.3</span> 2.3 微信支付接口对接</h3>
|
||
<p><strong>功能描述</strong>:用户通过微信支付缴纳水费,支持扫码支付和小程序支付。</p>
|
||
<p><strong>接口详情</strong>: - <strong>接口方式</strong>:HTTP POST -
|
||
<strong>支付方式</strong>:Native支付(扫码)/ JSAPI支付(小程序) -
|
||
<strong>请求URL</strong>:<code>https://api.mch.weixin.qq.com/v3/pay/transactions/native</code>
|
||
- <strong>数据格式</strong>:JSON -
|
||
<strong>认证方式</strong>:微信支付V3签名</p>
|
||
<p><strong>统一下单请求参数</strong>:</p>
|
||
<div class="sourceCode" id="cb12"><pre
|
||
class="sourceCode json"><code class="sourceCode json"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
|
||
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">"appid"</span><span class="fu">:</span> <span class="st">"wx8888888888888888"</span><span class="fu">,</span></span>
|
||
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">"mchid"</span><span class="fu">:</span> <span class="st">"1900000109"</span><span class="fu">,</span> </span>
|
||
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">"description"</span><span class="fu">:</span> <span class="st">"水费缴费-2024年12月"</span><span class="fu">,</span></span>
|
||
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a> <span class="dt">"out_trade_no"</span><span class="fu">:</span> <span class="st">"P202412190003"</span><span class="fu">,</span></span>
|
||
<span id="cb12-6"><a href="#cb12-6" aria-hidden="true" tabindex="-1"></a> <span class="dt">"notify_url"</span><span class="fu">:</span> <span class="st">"https://water.example.com/api/payment/wechat/notify"</span><span class="fu">,</span></span>
|
||
<span id="cb12-7"><a href="#cb12-7" aria-hidden="true" tabindex="-1"></a> <span class="dt">"amount"</span><span class="fu">:</span> <span class="fu">{</span></span>
|
||
<span id="cb12-8"><a href="#cb12-8" aria-hidden="true" tabindex="-1"></a> <span class="dt">"total"</span><span class="fu">:</span> <span class="dv">9180</span><span class="fu">,</span></span>
|
||
<span id="cb12-9"><a href="#cb12-9" aria-hidden="true" tabindex="-1"></a> <span class="dt">"currency"</span><span class="fu">:</span> <span class="st">"CNY"</span></span>
|
||
<span id="cb12-10"><a href="#cb12-10" aria-hidden="true" tabindex="-1"></a> <span class="fu">},</span></span>
|
||
<span id="cb12-11"><a href="#cb12-11" aria-hidden="true" tabindex="-1"></a> <span class="dt">"attach"</span><span class="fu">:</span> <span class="st">"客户编号:C001,账单号:B202412190001"</span><span class="fu">,</span></span>
|
||
<span id="cb12-12"><a href="#cb12-12" aria-hidden="true" tabindex="-1"></a> <span class="dt">"goods_tag"</span><span class="fu">:</span> <span class="st">"WATER_FEE"</span><span class="fu">,</span></span>
|
||
<span id="cb12-13"><a href="#cb12-13" aria-hidden="true" tabindex="-1"></a> <span class="dt">"time_expire"</span><span class="fu">:</span> <span class="st">"2024-12-19T11:00:00+08:00"</span></span>
|
||
<span id="cb12-14"><a href="#cb12-14" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
|
||
<p><strong>微信支付响应参数</strong>:</p>
|
||
<div class="sourceCode" id="cb13"><pre
|
||
class="sourceCode json"><code class="sourceCode json"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
|
||
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">"code_url"</span><span class="fu">:</span> <span class="st">"weixin://wxpay/bizpayurl?pr=HuaLcAKwa"</span></span>
|
||
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
|
||
<p><strong>支付结果通知参数</strong>:</p>
|
||
<div class="sourceCode" id="cb14"><pre
|
||
class="sourceCode json"><code class="sourceCode json"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
|
||
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">"id"</span><span class="fu">:</span> <span class="st">"EV-2018022511223320873"</span><span class="fu">,</span></span>
|
||
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">"create_time"</span><span class="fu">:</span> <span class="st">"2024-12-19T10:30:00+08:00"</span><span class="fu">,</span></span>
|
||
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">"resource_type"</span><span class="fu">:</span> <span class="st">"encrypt-resource"</span><span class="fu">,</span></span>
|
||
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a> <span class="dt">"event_type"</span><span class="fu">:</span> <span class="st">"TRANSACTION.SUCCESS"</span><span class="fu">,</span></span>
|
||
<span id="cb14-6"><a href="#cb14-6" aria-hidden="true" tabindex="-1"></a> <span class="dt">"summary"</span><span class="fu">:</span> <span class="st">"支付成功"</span><span class="fu">,</span></span>
|
||
<span id="cb14-7"><a href="#cb14-7" aria-hidden="true" tabindex="-1"></a> <span class="dt">"resource"</span><span class="fu">:</span> <span class="fu">{</span></span>
|
||
<span id="cb14-8"><a href="#cb14-8" aria-hidden="true" tabindex="-1"></a> <span class="dt">"original_type"</span><span class="fu">:</span> <span class="st">"transaction"</span><span class="fu">,</span></span>
|
||
<span id="cb14-9"><a href="#cb14-9" aria-hidden="true" tabindex="-1"></a> <span class="dt">"algorithm"</span><span class="fu">:</span> <span class="st">"AEAD_AES_256_GCM"</span><span class="fu">,</span></span>
|
||
<span id="cb14-10"><a href="#cb14-10" aria-hidden="true" tabindex="-1"></a> <span class="dt">"ciphertext"</span><span class="fu">:</span> <span class="st">"..."</span><span class="fu">,</span></span>
|
||
<span id="cb14-11"><a href="#cb14-11" aria-hidden="true" tabindex="-1"></a> <span class="dt">"associated_data"</span><span class="fu">:</span> <span class="st">"transaction"</span><span class="fu">,</span></span>
|
||
<span id="cb14-12"><a href="#cb14-12" aria-hidden="true" tabindex="-1"></a> <span class="dt">"nonce"</span><span class="fu">:</span> <span class="st">"..."</span></span>
|
||
<span id="cb14-13"><a href="#cb14-13" aria-hidden="true" tabindex="-1"></a> <span class="fu">}</span></span>
|
||
<span id="cb14-14"><a href="#cb14-14" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
|
||
<h3 data-number="1.4.4" id="短信接口"><span
|
||
class="header-section-number">1.4.4</span> 2.4 短信接口</h3>
|
||
<p><strong>功能描述</strong>:向用户发送各类业务通知短信。</p>
|
||
<p><strong>接口规范</strong>: - 接口方式:HTTP接口 - 数据格式:JSON -
|
||
交换频率:实时</p>
|
||
<h3 data-number="1.4.5" id="物联网集抄平台接口"><span
|
||
class="header-section-number">1.4.5</span> 2.5 物联网集抄平台接口</h3>
|
||
<p><strong>功能描述</strong>:与物联网集抄平台交互,获取智能水表数据。</p>
|
||
<p><strong>接口规范</strong>: - 接口方式:HTTP接口或WebService -
|
||
数据格式:JSON或XML - 交换频率:定时或实时</p>
|
||
<h2 data-number="1.5" id="内部接口"><span
|
||
class="header-section-number">1.5</span> 3. 内部接口</h2>
|
||
<h3 data-number="1.5.1" id="客户管理api接口"><span
|
||
class="header-section-number">1.5.1</span> 3.1 客户管理API接口</h3>
|
||
<h4 data-number="1.5.1.1" id="客户信息查询接口"><span
|
||
class="header-section-number">1.5.1.1</span> 3.1.1 客户信息查询接口</h4>
|
||
<p><strong>功能描述</strong>:根据客户ID查询客户详细信息。</p>
|
||
<p><strong>接口详情</strong>: - <strong>请求方式</strong>:GET -
|
||
<strong>请求路径</strong>:<code>/admin-api/water/customer/{id}</code> -
|
||
<strong>请求头</strong>:<code>Authorization: Bearer {token}</code></p>
|
||
<p><strong>请求参数</strong>: | 参数名 | 类型 | 必填 | 说明 | 示例 |
|
||
|——-|——|——|——|——| | id | Long | 是 | 客户ID | 1 |</p>
|
||
<p><strong>响应参数</strong>:</p>
|
||
<div class="sourceCode" id="cb15"><pre
|
||
class="sourceCode json"><code class="sourceCode json"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
|
||
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">"code"</span><span class="fu">:</span> <span class="dv">0</span><span class="fu">,</span></span>
|
||
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">"msg"</span><span class="fu">:</span> <span class="st">"操作成功"</span><span class="fu">,</span></span>
|
||
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">"data"</span><span class="fu">:</span> <span class="fu">{</span></span>
|
||
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a> <span class="dt">"id"</span><span class="fu">:</span> <span class="dv">1</span><span class="fu">,</span></span>
|
||
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a> <span class="dt">"customerCode"</span><span class="fu">:</span> <span class="st">"C001"</span><span class="fu">,</span></span>
|
||
<span id="cb15-7"><a href="#cb15-7" aria-hidden="true" tabindex="-1"></a> <span class="dt">"customerName"</span><span class="fu">:</span> <span class="st">"张三"</span><span class="fu">,</span></span>
|
||
<span id="cb15-8"><a href="#cb15-8" aria-hidden="true" tabindex="-1"></a> <span class="dt">"customerType"</span><span class="fu">:</span> <span class="st">"RESIDENT"</span><span class="fu">,</span></span>
|
||
<span id="cb15-9"><a href="#cb15-9" aria-hidden="true" tabindex="-1"></a> <span class="dt">"phone"</span><span class="fu">:</span> <span class="st">"13800138000"</span><span class="fu">,</span></span>
|
||
<span id="cb15-10"><a href="#cb15-10" aria-hidden="true" tabindex="-1"></a> <span class="dt">"address"</span><span class="fu">:</span> <span class="st">"福建省福州市台江区XX街道XX号"</span><span class="fu">,</span></span>
|
||
<span id="cb15-11"><a href="#cb15-11" aria-hidden="true" tabindex="-1"></a> <span class="dt">"status"</span><span class="fu">:</span> <span class="dv">1</span><span class="fu">,</span></span>
|
||
<span id="cb15-12"><a href="#cb15-12" aria-hidden="true" tabindex="-1"></a> <span class="dt">"createTime"</span><span class="fu">:</span> <span class="st">"2024-12-19 10:00:00"</span></span>
|
||
<span id="cb15-13"><a href="#cb15-13" aria-hidden="true" tabindex="-1"></a> <span class="fu">}</span></span>
|
||
<span id="cb15-14"><a href="#cb15-14" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
|
||
<p><strong>RuoYi-Vue-Pro代码示例</strong>:</p>
|
||
<div class="sourceCode" id="cb16"><pre
|
||
class="sourceCode java"><code class="sourceCode java"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="at">@RestController</span></span>
|
||
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a><span class="at">@RequestMapping</span><span class="op">(</span><span class="st">"/admin-api/water/customer"</span><span class="op">)</span></span>
|
||
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a><span class="at">@Tag</span><span class="op">(</span>name <span class="op">=</span> <span class="st">"管理后台 - 客户管理"</span><span class="op">)</span></span>
|
||
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a><span class="at">@Validated</span></span>
|
||
<span id="cb16-5"><a href="#cb16-5" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> <span class="kw">class</span> CustomerController <span class="op">{</span></span>
|
||
<span id="cb16-6"><a href="#cb16-6" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb16-7"><a href="#cb16-7" aria-hidden="true" tabindex="-1"></a> <span class="at">@Resource</span></span>
|
||
<span id="cb16-8"><a href="#cb16-8" aria-hidden="true" tabindex="-1"></a> <span class="kw">private</span> CustomerService customerService<span class="op">;</span></span>
|
||
<span id="cb16-9"><a href="#cb16-9" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb16-10"><a href="#cb16-10" aria-hidden="true" tabindex="-1"></a> <span class="at">@GetMapping</span><span class="op">(</span><span class="st">"/{id}"</span><span class="op">)</span></span>
|
||
<span id="cb16-11"><a href="#cb16-11" aria-hidden="true" tabindex="-1"></a> <span class="at">@Operation</span><span class="op">(</span>summary <span class="op">=</span> <span class="st">"获得客户"</span><span class="op">)</span></span>
|
||
<span id="cb16-12"><a href="#cb16-12" aria-hidden="true" tabindex="-1"></a> <span class="at">@Parameter</span><span class="op">(</span>name <span class="op">=</span> <span class="st">"id"</span><span class="op">,</span> description <span class="op">=</span> <span class="st">"编号"</span><span class="op">,</span> required <span class="op">=</span> <span class="kw">true</span><span class="op">,</span> example <span class="op">=</span> <span class="st">"1024"</span><span class="op">)</span></span>
|
||
<span id="cb16-13"><a href="#cb16-13" aria-hidden="true" tabindex="-1"></a> <span class="at">@PreAuthorize</span><span class="op">(</span><span class="st">"@ss.hasPermission('water:customer:query')"</span><span class="op">)</span></span>
|
||
<span id="cb16-14"><a href="#cb16-14" aria-hidden="true" tabindex="-1"></a> <span class="kw">public</span> CommonResult<span class="op"><</span>CustomerRespVO<span class="op">></span> <span class="fu">getCustomer</span><span class="op">(</span><span class="at">@PathVariable</span><span class="op">(</span><span class="st">"id"</span><span class="op">)</span> <span class="bu">Long</span> id<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb16-15"><a href="#cb16-15" aria-hidden="true" tabindex="-1"></a> CustomerDO customer <span class="op">=</span> customerService<span class="op">.</span><span class="fu">getCustomer</span><span class="op">(</span>id<span class="op">);</span></span>
|
||
<span id="cb16-16"><a href="#cb16-16" aria-hidden="true" tabindex="-1"></a> <span class="cf">return</span> <span class="fu">success</span><span class="op">(</span>BeanUtils<span class="op">.</span><span class="fu">toBean</span><span class="op">(</span>customer<span class="op">,</span> CustomerRespVO<span class="op">.</span><span class="fu">class</span><span class="op">));</span></span>
|
||
<span id="cb16-17"><a href="#cb16-17" aria-hidden="true" tabindex="-1"></a> <span class="op">}</span></span>
|
||
<span id="cb16-18"><a href="#cb16-18" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
|
||
<h4 data-number="1.5.1.2" id="客户分页查询接口"><span
|
||
class="header-section-number">1.5.1.2</span> 3.1.2 客户分页查询接口</h4>
|
||
<p><strong>功能描述</strong>:分页查询客户列表信息。</p>
|
||
<p><strong>接口详情</strong>: - <strong>请求方式</strong>:GET -
|
||
<strong>请求路径</strong>:<code>/admin-api/water/customer/page</code></p>
|
||
<p><strong>请求参数</strong>: | 参数名 | 类型 | 必填 | 说明 | 示例 |
|
||
|——-|——|——|——|——| | pageNo | Integer | 否 | 页码,默认1 | 1 | | pageSize
|
||
| Integer | 否 | 每页条数,默认10 | 10 | | customerName | String | 否 |
|
||
客户名称 | 张三 | | customerCode | String | 否 | 客户编号 | C001 | |
|
||
customerType | String | 否 | 客户类型 | RESIDENT | | phone | String | 否
|
||
| 联系电话 | 138 |</p>
|
||
<p><strong>响应参数</strong>:</p>
|
||
<div class="sourceCode" id="cb17"><pre
|
||
class="sourceCode json"><code class="sourceCode json"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
|
||
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">"code"</span><span class="fu">:</span> <span class="dv">0</span><span class="fu">,</span></span>
|
||
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">"msg"</span><span class="fu">:</span> <span class="st">"操作成功"</span><span class="fu">,</span></span>
|
||
<span id="cb17-4"><a href="#cb17-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">"data"</span><span class="fu">:</span> <span class="fu">{</span></span>
|
||
<span id="cb17-5"><a href="#cb17-5" aria-hidden="true" tabindex="-1"></a> <span class="dt">"list"</span><span class="fu">:</span> <span class="ot">[</span></span>
|
||
<span id="cb17-6"><a href="#cb17-6" aria-hidden="true" tabindex="-1"></a> <span class="fu">{</span></span>
|
||
<span id="cb17-7"><a href="#cb17-7" aria-hidden="true" tabindex="-1"></a> <span class="dt">"id"</span><span class="fu">:</span> <span class="dv">1</span><span class="fu">,</span></span>
|
||
<span id="cb17-8"><a href="#cb17-8" aria-hidden="true" tabindex="-1"></a> <span class="dt">"customerCode"</span><span class="fu">:</span> <span class="st">"C001"</span><span class="fu">,</span></span>
|
||
<span id="cb17-9"><a href="#cb17-9" aria-hidden="true" tabindex="-1"></a> <span class="dt">"customerName"</span><span class="fu">:</span> <span class="st">"张三"</span><span class="fu">,</span></span>
|
||
<span id="cb17-10"><a href="#cb17-10" aria-hidden="true" tabindex="-1"></a> <span class="dt">"customerType"</span><span class="fu">:</span> <span class="st">"RESIDENT"</span><span class="fu">,</span></span>
|
||
<span id="cb17-11"><a href="#cb17-11" aria-hidden="true" tabindex="-1"></a> <span class="dt">"phone"</span><span class="fu">:</span> <span class="st">"13800138000"</span><span class="fu">,</span></span>
|
||
<span id="cb17-12"><a href="#cb17-12" aria-hidden="true" tabindex="-1"></a> <span class="dt">"address"</span><span class="fu">:</span> <span class="st">"福建省福州市台江区XX街道XX号"</span><span class="fu">,</span></span>
|
||
<span id="cb17-13"><a href="#cb17-13" aria-hidden="true" tabindex="-1"></a> <span class="dt">"status"</span><span class="fu">:</span> <span class="dv">1</span><span class="fu">,</span></span>
|
||
<span id="cb17-14"><a href="#cb17-14" aria-hidden="true" tabindex="-1"></a> <span class="dt">"createTime"</span><span class="fu">:</span> <span class="st">"2024-12-19 10:00:00"</span></span>
|
||
<span id="cb17-15"><a href="#cb17-15" aria-hidden="true" tabindex="-1"></a> <span class="fu">}</span></span>
|
||
<span id="cb17-16"><a href="#cb17-16" aria-hidden="true" tabindex="-1"></a> <span class="ot">]</span><span class="fu">,</span></span>
|
||
<span id="cb17-17"><a href="#cb17-17" aria-hidden="true" tabindex="-1"></a> <span class="dt">"total"</span><span class="fu">:</span> <span class="dv">1</span></span>
|
||
<span id="cb17-18"><a href="#cb17-18" aria-hidden="true" tabindex="-1"></a> <span class="fu">}</span></span>
|
||
<span id="cb17-19"><a href="#cb17-19" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
|
||
<h4 data-number="1.5.1.3" id="客户创建接口"><span
|
||
class="header-section-number">1.5.1.3</span> 3.1.3 客户创建接口</h4>
|
||
<p><strong>功能描述</strong>:创建新客户记录。</p>
|
||
<p><strong>接口详情</strong>: - <strong>请求方式</strong>:POST -
|
||
<strong>请求路径</strong>:<code>/admin-api/water/customer/create</code></p>
|
||
<p><strong>请求参数</strong>:</p>
|
||
<div class="sourceCode" id="cb18"><pre
|
||
class="sourceCode json"><code class="sourceCode json"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
|
||
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">"customerCode"</span><span class="fu">:</span> <span class="st">"C002"</span><span class="fu">,</span></span>
|
||
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">"customerName"</span><span class="fu">:</span> <span class="st">"李四"</span><span class="fu">,</span></span>
|
||
<span id="cb18-4"><a href="#cb18-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">"customerType"</span><span class="fu">:</span> <span class="st">"RESIDENT"</span><span class="fu">,</span></span>
|
||
<span id="cb18-5"><a href="#cb18-5" aria-hidden="true" tabindex="-1"></a> <span class="dt">"idType"</span><span class="fu">:</span> <span class="st">"ID_CARD"</span><span class="fu">,</span></span>
|
||
<span id="cb18-6"><a href="#cb18-6" aria-hidden="true" tabindex="-1"></a> <span class="dt">"idNumber"</span><span class="fu">:</span> <span class="st">"350103199001011234"</span><span class="fu">,</span></span>
|
||
<span id="cb18-7"><a href="#cb18-7" aria-hidden="true" tabindex="-1"></a> <span class="dt">"phone"</span><span class="fu">:</span> <span class="st">"13900139000"</span><span class="fu">,</span></span>
|
||
<span id="cb18-8"><a href="#cb18-8" aria-hidden="true" tabindex="-1"></a> <span class="dt">"address"</span><span class="fu">:</span> <span class="st">"福建省福州市鼓楼区XX街道XX号"</span></span>
|
||
<span id="cb18-9"><a href="#cb18-9" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
|
||
<p><strong>响应参数</strong>:</p>
|
||
<div class="sourceCode" id="cb19"><pre
|
||
class="sourceCode json"><code class="sourceCode json"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
|
||
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">"code"</span><span class="fu">:</span> <span class="dv">0</span><span class="fu">,</span></span>
|
||
<span id="cb19-3"><a href="#cb19-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">"msg"</span><span class="fu">:</span> <span class="st">"操作成功"</span><span class="fu">,</span></span>
|
||
<span id="cb19-4"><a href="#cb19-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">"data"</span><span class="fu">:</span> <span class="dv">2</span></span>
|
||
<span id="cb19-5"><a href="#cb19-5" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
|
||
<p><strong>Service层代码示例</strong>:</p>
|
||
<div class="sourceCode" id="cb20"><pre
|
||
class="sourceCode java"><code class="sourceCode java"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a><span class="at">@Service</span></span>
|
||
<span id="cb20-2"><a href="#cb20-2" aria-hidden="true" tabindex="-1"></a><span class="at">@Validated</span></span>
|
||
<span id="cb20-3"><a href="#cb20-3" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> <span class="kw">class</span> CustomerServiceImpl <span class="kw">implements</span> CustomerService <span class="op">{</span></span>
|
||
<span id="cb20-4"><a href="#cb20-4" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb20-5"><a href="#cb20-5" aria-hidden="true" tabindex="-1"></a> <span class="at">@Resource</span></span>
|
||
<span id="cb20-6"><a href="#cb20-6" aria-hidden="true" tabindex="-1"></a> <span class="kw">private</span> CustomerMapper customerMapper<span class="op">;</span></span>
|
||
<span id="cb20-7"><a href="#cb20-7" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb20-8"><a href="#cb20-8" aria-hidden="true" tabindex="-1"></a> <span class="at">@Override</span></span>
|
||
<span id="cb20-9"><a href="#cb20-9" aria-hidden="true" tabindex="-1"></a> <span class="kw">public</span> <span class="bu">Long</span> <span class="fu">createCustomer</span><span class="op">(</span>CustomerSaveReqVO createReqVO<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb20-10"><a href="#cb20-10" aria-hidden="true" tabindex="-1"></a> <span class="co">// 校验客户编号唯一性</span></span>
|
||
<span id="cb20-11"><a href="#cb20-11" aria-hidden="true" tabindex="-1"></a> <span class="fu">validateCustomerCodeUnique</span><span class="op">(</span>createReqVO<span class="op">.</span><span class="fu">getCustomerCode</span><span class="op">());</span></span>
|
||
<span id="cb20-12"><a href="#cb20-12" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb20-13"><a href="#cb20-13" aria-hidden="true" tabindex="-1"></a> <span class="co">// 创建客户</span></span>
|
||
<span id="cb20-14"><a href="#cb20-14" aria-hidden="true" tabindex="-1"></a> CustomerDO customer <span class="op">=</span> BeanUtils<span class="op">.</span><span class="fu">toBean</span><span class="op">(</span>createReqVO<span class="op">,</span> CustomerDO<span class="op">.</span><span class="fu">class</span><span class="op">);</span></span>
|
||
<span id="cb20-15"><a href="#cb20-15" aria-hidden="true" tabindex="-1"></a> customerMapper<span class="op">.</span><span class="fu">insert</span><span class="op">(</span>customer<span class="op">);</span></span>
|
||
<span id="cb20-16"><a href="#cb20-16" aria-hidden="true" tabindex="-1"></a> <span class="cf">return</span> customer<span class="op">.</span><span class="fu">getId</span><span class="op">();</span></span>
|
||
<span id="cb20-17"><a href="#cb20-17" aria-hidden="true" tabindex="-1"></a> <span class="op">}</span></span>
|
||
<span id="cb20-18"><a href="#cb20-18" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb20-19"><a href="#cb20-19" aria-hidden="true" tabindex="-1"></a> <span class="kw">private</span> <span class="dt">void</span> <span class="fu">validateCustomerCodeUnique</span><span class="op">(</span><span class="bu">String</span> customerCode<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb20-20"><a href="#cb20-20" aria-hidden="true" tabindex="-1"></a> CustomerDO existCustomer <span class="op">=</span> customerMapper<span class="op">.</span><span class="fu">selectByCustomerCode</span><span class="op">(</span>customerCode<span class="op">);</span></span>
|
||
<span id="cb20-21"><a href="#cb20-21" aria-hidden="true" tabindex="-1"></a> <span class="cf">if</span> <span class="op">(</span>existCustomer <span class="op">!=</span> <span class="kw">null</span><span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb20-22"><a href="#cb20-22" aria-hidden="true" tabindex="-1"></a> <span class="cf">throw</span> <span class="fu">exception</span><span class="op">(</span>CUSTOMER_CODE_DUPLICATE<span class="op">);</span></span>
|
||
<span id="cb20-23"><a href="#cb20-23" aria-hidden="true" tabindex="-1"></a> <span class="op">}</span></span>
|
||
<span id="cb20-24"><a href="#cb20-24" aria-hidden="true" tabindex="-1"></a> <span class="op">}</span></span>
|
||
<span id="cb20-25"><a href="#cb20-25" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
|
||
<h3 data-number="1.5.2" id="水表管理api接口"><span
|
||
class="header-section-number">1.5.2</span> 3.2 水表管理API接口</h3>
|
||
<h4 data-number="1.5.2.1" id="水表信息查询接口"><span
|
||
class="header-section-number">1.5.2.1</span> 3.2.1 水表信息查询接口</h4>
|
||
<p><strong>功能描述</strong>:根据水表ID查询水表详细信息。</p>
|
||
<p><strong>接口详情</strong>: - <strong>请求方式</strong>:GET -
|
||
<strong>请求路径</strong>:<code>/admin-api/water/meter/{id}</code> -
|
||
<strong>请求头</strong>:<code>Authorization: Bearer {token}</code></p>
|
||
<p><strong>请求参数</strong>: | 参数名 | 类型 | 必填 | 说明 | 示例 |
|
||
|——-|——|——|——|——| | id | Long | 是 | 水表ID | 1 |</p>
|
||
<p><strong>响应参数</strong>:</p>
|
||
<div class="sourceCode" id="cb21"><pre
|
||
class="sourceCode json"><code class="sourceCode json"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
|
||
<span id="cb21-2"><a href="#cb21-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">"code"</span><span class="fu">:</span> <span class="dv">0</span><span class="fu">,</span></span>
|
||
<span id="cb21-3"><a href="#cb21-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">"msg"</span><span class="fu">:</span> <span class="st">"操作成功"</span><span class="fu">,</span></span>
|
||
<span id="cb21-4"><a href="#cb21-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">"data"</span><span class="fu">:</span> <span class="fu">{</span></span>
|
||
<span id="cb21-5"><a href="#cb21-5" aria-hidden="true" tabindex="-1"></a> <span class="dt">"id"</span><span class="fu">:</span> <span class="dv">1</span><span class="fu">,</span></span>
|
||
<span id="cb21-6"><a href="#cb21-6" aria-hidden="true" tabindex="-1"></a> <span class="dt">"meterCode"</span><span class="fu">:</span> <span class="st">"M001"</span><span class="fu">,</span></span>
|
||
<span id="cb21-7"><a href="#cb21-7" aria-hidden="true" tabindex="-1"></a> <span class="dt">"meterNo"</span><span class="fu">:</span> <span class="st">"20241219001"</span><span class="fu">,</span></span>
|
||
<span id="cb21-8"><a href="#cb21-8" aria-hidden="true" tabindex="-1"></a> <span class="dt">"meterType"</span><span class="fu">:</span> <span class="st">"SMART"</span><span class="fu">,</span></span>
|
||
<span id="cb21-9"><a href="#cb21-9" aria-hidden="true" tabindex="-1"></a> <span class="dt">"meterModel"</span><span class="fu">:</span> <span class="st">"LXSY-15E"</span><span class="fu">,</span></span>
|
||
<span id="cb21-10"><a href="#cb21-10" aria-hidden="true" tabindex="-1"></a> <span class="dt">"meterCaliber"</span><span class="fu">:</span> <span class="st">"15mm"</span><span class="fu">,</span></span>
|
||
<span id="cb21-11"><a href="#cb21-11" aria-hidden="true" tabindex="-1"></a> <span class="dt">"installDate"</span><span class="fu">:</span> <span class="st">"2024-01-15"</span><span class="fu">,</span></span>
|
||
<span id="cb21-12"><a href="#cb21-12" aria-hidden="true" tabindex="-1"></a> <span class="dt">"installPosition"</span><span class="fu">:</span> <span class="st">"1层水表井"</span><span class="fu">,</span></span>
|
||
<span id="cb21-13"><a href="#cb21-13" aria-hidden="true" tabindex="-1"></a> <span class="dt">"initialReading"</span><span class="fu">:</span> <span class="dv">0</span><span class="er">.00</span><span class="fu">,</span></span>
|
||
<span id="cb21-14"><a href="#cb21-14" aria-hidden="true" tabindex="-1"></a> <span class="dt">"currentReading"</span><span class="fu">:</span> <span class="fl">156.32</span><span class="fu">,</span></span>
|
||
<span id="cb21-15"><a href="#cb21-15" aria-hidden="true" tabindex="-1"></a> <span class="dt">"readingCycle"</span><span class="fu">:</span> <span class="st">"MONTHLY"</span><span class="fu">,</span></span>
|
||
<span id="cb21-16"><a href="#cb21-16" aria-hidden="true" tabindex="-1"></a> <span class="dt">"meterStatus"</span><span class="fu">:</span> <span class="dv">1</span><span class="fu">,</span></span>
|
||
<span id="cb21-17"><a href="#cb21-17" aria-hidden="true" tabindex="-1"></a> <span class="dt">"customerId"</span><span class="fu">:</span> <span class="dv">1</span><span class="fu">,</span></span>
|
||
<span id="cb21-18"><a href="#cb21-18" aria-hidden="true" tabindex="-1"></a> <span class="dt">"customerName"</span><span class="fu">:</span> <span class="st">"张三"</span></span>
|
||
<span id="cb21-19"><a href="#cb21-19" aria-hidden="true" tabindex="-1"></a> <span class="fu">}</span></span>
|
||
<span id="cb21-20"><a href="#cb21-20" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
|
||
<p><strong>Controller代码示例</strong>:</p>
|
||
<div class="sourceCode" id="cb22"><pre
|
||
class="sourceCode java"><code class="sourceCode java"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true" tabindex="-1"></a><span class="at">@RestController</span></span>
|
||
<span id="cb22-2"><a href="#cb22-2" aria-hidden="true" tabindex="-1"></a><span class="at">@RequestMapping</span><span class="op">(</span><span class="st">"/admin-api/water/meter"</span><span class="op">)</span></span>
|
||
<span id="cb22-3"><a href="#cb22-3" aria-hidden="true" tabindex="-1"></a><span class="at">@Tag</span><span class="op">(</span>name <span class="op">=</span> <span class="st">"管理后台 - 水表管理"</span><span class="op">)</span></span>
|
||
<span id="cb22-4"><a href="#cb22-4" aria-hidden="true" tabindex="-1"></a><span class="at">@Validated</span></span>
|
||
<span id="cb22-5"><a href="#cb22-5" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> <span class="kw">class</span> MeterController <span class="op">{</span></span>
|
||
<span id="cb22-6"><a href="#cb22-6" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb22-7"><a href="#cb22-7" aria-hidden="true" tabindex="-1"></a> <span class="at">@Resource</span></span>
|
||
<span id="cb22-8"><a href="#cb22-8" aria-hidden="true" tabindex="-1"></a> <span class="kw">private</span> MeterService meterService<span class="op">;</span></span>
|
||
<span id="cb22-9"><a href="#cb22-9" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb22-10"><a href="#cb22-10" aria-hidden="true" tabindex="-1"></a> <span class="at">@GetMapping</span><span class="op">(</span><span class="st">"/{id}"</span><span class="op">)</span></span>
|
||
<span id="cb22-11"><a href="#cb22-11" aria-hidden="true" tabindex="-1"></a> <span class="at">@Operation</span><span class="op">(</span>summary <span class="op">=</span> <span class="st">"获得水表"</span><span class="op">)</span></span>
|
||
<span id="cb22-12"><a href="#cb22-12" aria-hidden="true" tabindex="-1"></a> <span class="at">@Parameter</span><span class="op">(</span>name <span class="op">=</span> <span class="st">"id"</span><span class="op">,</span> description <span class="op">=</span> <span class="st">"编号"</span><span class="op">,</span> required <span class="op">=</span> <span class="kw">true</span><span class="op">)</span></span>
|
||
<span id="cb22-13"><a href="#cb22-13" aria-hidden="true" tabindex="-1"></a> <span class="at">@PreAuthorize</span><span class="op">(</span><span class="st">"@ss.hasPermission('water:meter:query')"</span><span class="op">)</span></span>
|
||
<span id="cb22-14"><a href="#cb22-14" aria-hidden="true" tabindex="-1"></a> <span class="kw">public</span> CommonResult<span class="op"><</span>MeterRespVO<span class="op">></span> <span class="fu">getMeter</span><span class="op">(</span><span class="at">@PathVariable</span><span class="op">(</span><span class="st">"id"</span><span class="op">)</span> <span class="bu">Long</span> id<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb22-15"><a href="#cb22-15" aria-hidden="true" tabindex="-1"></a> MeterDO meter <span class="op">=</span> meterService<span class="op">.</span><span class="fu">getMeter</span><span class="op">(</span>id<span class="op">);</span></span>
|
||
<span id="cb22-16"><a href="#cb22-16" aria-hidden="true" tabindex="-1"></a> <span class="cf">return</span> <span class="fu">success</span><span class="op">(</span>BeanUtils<span class="op">.</span><span class="fu">toBean</span><span class="op">(</span>meter<span class="op">,</span> MeterRespVO<span class="op">.</span><span class="fu">class</span><span class="op">));</span></span>
|
||
<span id="cb22-17"><a href="#cb22-17" aria-hidden="true" tabindex="-1"></a> <span class="op">}</span></span>
|
||
<span id="cb22-18"><a href="#cb22-18" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
|
||
<h4 data-number="1.5.2.2" id="抄表记录创建接口"><span
|
||
class="header-section-number">1.5.2.2</span> 3.2.2 抄表记录创建接口</h4>
|
||
<p><strong>功能描述</strong>:创建新的抄表记录。</p>
|
||
<p><strong>接口详情</strong>: - <strong>请求方式</strong>:POST -
|
||
<strong>请求路径</strong>:<code>/admin-api/water/reading/create</code></p>
|
||
<p><strong>请求参数</strong>:</p>
|
||
<div class="sourceCode" id="cb23"><pre
|
||
class="sourceCode json"><code class="sourceCode json"><span id="cb23-1"><a href="#cb23-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
|
||
<span id="cb23-2"><a href="#cb23-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">"meterId"</span><span class="fu">:</span> <span class="dv">1</span><span class="fu">,</span></span>
|
||
<span id="cb23-3"><a href="#cb23-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">"readingDate"</span><span class="fu">:</span> <span class="st">"2024-12-19"</span><span class="fu">,</span></span>
|
||
<span id="cb23-4"><a href="#cb23-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">"readingValue"</span><span class="fu">:</span> <span class="fl">156.32</span><span class="fu">,</span></span>
|
||
<span id="cb23-5"><a href="#cb23-5" aria-hidden="true" tabindex="-1"></a> <span class="dt">"readingType"</span><span class="fu">:</span> <span class="st">"MANUAL"</span><span class="fu">,</span></span>
|
||
<span id="cb23-6"><a href="#cb23-6" aria-hidden="true" tabindex="-1"></a> <span class="dt">"readerId"</span><span class="fu">:</span> <span class="st">"R001"</span><span class="fu">,</span></span>
|
||
<span id="cb23-7"><a href="#cb23-7" aria-hidden="true" tabindex="-1"></a> <span class="dt">"photoUrl"</span><span class="fu">:</span> <span class="st">"https://example.com/photos/reading001.jpg"</span><span class="fu">,</span></span>
|
||
<span id="cb23-8"><a href="#cb23-8" aria-hidden="true" tabindex="-1"></a> <span class="dt">"remark"</span><span class="fu">:</span> <span class="st">"正常抄表"</span></span>
|
||
<span id="cb23-9"><a href="#cb23-9" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
|
||
<p><strong>响应参数</strong>:</p>
|
||
<div class="sourceCode" id="cb24"><pre
|
||
class="sourceCode json"><code class="sourceCode json"><span id="cb24-1"><a href="#cb24-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
|
||
<span id="cb24-2"><a href="#cb24-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">"code"</span><span class="fu">:</span> <span class="dv">0</span><span class="fu">,</span></span>
|
||
<span id="cb24-3"><a href="#cb24-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">"msg"</span><span class="fu">:</span> <span class="st">"操作成功"</span><span class="fu">,</span> </span>
|
||
<span id="cb24-4"><a href="#cb24-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">"data"</span><span class="fu">:</span> <span class="dv">1</span></span>
|
||
<span id="cb24-5"><a href="#cb24-5" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
|
||
<p><strong>Service层实现示例</strong>:</p>
|
||
<div class="sourceCode" id="cb25"><pre
|
||
class="sourceCode java"><code class="sourceCode java"><span id="cb25-1"><a href="#cb25-1" aria-hidden="true" tabindex="-1"></a><span class="at">@Service</span></span>
|
||
<span id="cb25-2"><a href="#cb25-2" aria-hidden="true" tabindex="-1"></a><span class="at">@Validated</span></span>
|
||
<span id="cb25-3"><a href="#cb25-3" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> <span class="kw">class</span> MeterReadingServiceImpl <span class="kw">implements</span> MeterReadingService <span class="op">{</span></span>
|
||
<span id="cb25-4"><a href="#cb25-4" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb25-5"><a href="#cb25-5" aria-hidden="true" tabindex="-1"></a> <span class="at">@Resource</span></span>
|
||
<span id="cb25-6"><a href="#cb25-6" aria-hidden="true" tabindex="-1"></a> <span class="kw">private</span> MeterReadingMapper readingMapper<span class="op">;</span></span>
|
||
<span id="cb25-7"><a href="#cb25-7" aria-hidden="true" tabindex="-1"></a> <span class="at">@Resource</span></span>
|
||
<span id="cb25-8"><a href="#cb25-8" aria-hidden="true" tabindex="-1"></a> <span class="kw">private</span> MeterService meterService<span class="op">;</span></span>
|
||
<span id="cb25-9"><a href="#cb25-9" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb25-10"><a href="#cb25-10" aria-hidden="true" tabindex="-1"></a> <span class="at">@Override</span></span>
|
||
<span id="cb25-11"><a href="#cb25-11" aria-hidden="true" tabindex="-1"></a> <span class="at">@Transactional</span><span class="op">(</span>rollbackFor <span class="op">=</span> <span class="bu">Exception</span><span class="op">.</span><span class="fu">class</span><span class="op">)</span></span>
|
||
<span id="cb25-12"><a href="#cb25-12" aria-hidden="true" tabindex="-1"></a> <span class="kw">public</span> <span class="bu">Long</span> <span class="fu">createReading</span><span class="op">(</span>MeterReadingSaveReqVO createReqVO<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb25-13"><a href="#cb25-13" aria-hidden="true" tabindex="-1"></a> <span class="co">// 校验水表存在性</span></span>
|
||
<span id="cb25-14"><a href="#cb25-14" aria-hidden="true" tabindex="-1"></a> MeterDO meter <span class="op">=</span> meterService<span class="op">.</span><span class="fu">validateMeterExists</span><span class="op">(</span>createReqVO<span class="op">.</span><span class="fu">getMeterId</span><span class="op">());</span></span>
|
||
<span id="cb25-15"><a href="#cb25-15" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb25-16"><a href="#cb25-16" aria-hidden="true" tabindex="-1"></a> <span class="co">// 校验读数合理性</span></span>
|
||
<span id="cb25-17"><a href="#cb25-17" aria-hidden="true" tabindex="-1"></a> <span class="fu">validateReadingValue</span><span class="op">(</span>createReqVO<span class="op">.</span><span class="fu">getMeterId</span><span class="op">(),</span> createReqVO<span class="op">.</span><span class="fu">getReadingValue</span><span class="op">());</span></span>
|
||
<span id="cb25-18"><a href="#cb25-18" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb25-19"><a href="#cb25-19" aria-hidden="true" tabindex="-1"></a> <span class="co">// 创建抄表记录</span></span>
|
||
<span id="cb25-20"><a href="#cb25-20" aria-hidden="true" tabindex="-1"></a> MeterReadingDO reading <span class="op">=</span> BeanUtils<span class="op">.</span><span class="fu">toBean</span><span class="op">(</span>createReqVO<span class="op">,</span> MeterReadingDO<span class="op">.</span><span class="fu">class</span><span class="op">);</span></span>
|
||
<span id="cb25-21"><a href="#cb25-21" aria-hidden="true" tabindex="-1"></a> reading<span class="op">.</span><span class="fu">setReadingCode</span><span class="op">(</span><span class="fu">generateReadingCode</span><span class="op">());</span></span>
|
||
<span id="cb25-22"><a href="#cb25-22" aria-hidden="true" tabindex="-1"></a> reading<span class="op">.</span><span class="fu">setCustomerId</span><span class="op">(</span>meter<span class="op">.</span><span class="fu">getCustomerId</span><span class="op">());</span></span>
|
||
<span id="cb25-23"><a href="#cb25-23" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb25-24"><a href="#cb25-24" aria-hidden="true" tabindex="-1"></a> <span class="co">// 计算用水量</span></span>
|
||
<span id="cb25-25"><a href="#cb25-25" aria-hidden="true" tabindex="-1"></a> <span class="bu">BigDecimal</span> waterUsage <span class="op">=</span> <span class="fu">calculateWaterUsage</span><span class="op">(</span>meter<span class="op">.</span><span class="fu">getCurrentReading</span><span class="op">(),</span> </span>
|
||
<span id="cb25-26"><a href="#cb25-26" aria-hidden="true" tabindex="-1"></a> createReqVO<span class="op">.</span><span class="fu">getReadingValue</span><span class="op">());</span></span>
|
||
<span id="cb25-27"><a href="#cb25-27" aria-hidden="true" tabindex="-1"></a> reading<span class="op">.</span><span class="fu">setWaterUsage</span><span class="op">(</span>waterUsage<span class="op">);</span></span>
|
||
<span id="cb25-28"><a href="#cb25-28" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb25-29"><a href="#cb25-29" aria-hidden="true" tabindex="-1"></a> readingMapper<span class="op">.</span><span class="fu">insert</span><span class="op">(</span>reading<span class="op">);</span></span>
|
||
<span id="cb25-30"><a href="#cb25-30" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb25-31"><a href="#cb25-31" aria-hidden="true" tabindex="-1"></a> <span class="co">// 更新水表当前读数</span></span>
|
||
<span id="cb25-32"><a href="#cb25-32" aria-hidden="true" tabindex="-1"></a> meterService<span class="op">.</span><span class="fu">updateCurrentReading</span><span class="op">(</span>createReqVO<span class="op">.</span><span class="fu">getMeterId</span><span class="op">(),</span> </span>
|
||
<span id="cb25-33"><a href="#cb25-33" aria-hidden="true" tabindex="-1"></a> createReqVO<span class="op">.</span><span class="fu">getReadingValue</span><span class="op">());</span></span>
|
||
<span id="cb25-34"><a href="#cb25-34" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb25-35"><a href="#cb25-35" aria-hidden="true" tabindex="-1"></a> <span class="cf">return</span> reading<span class="op">.</span><span class="fu">getId</span><span class="op">();</span></span>
|
||
<span id="cb25-36"><a href="#cb25-36" aria-hidden="true" tabindex="-1"></a> <span class="op">}</span></span>
|
||
<span id="cb25-37"><a href="#cb25-37" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
|
||
<h4 data-number="1.5.2.3" id="抄表数据批量导入接口"><span
|
||
class="header-section-number">1.5.2.3</span> 3.2.3
|
||
抄表数据批量导入接口</h4>
|
||
<p><strong>功能描述</strong>:批量导入抄表数据,支持Excel文件上传。</p>
|
||
<p><strong>接口详情</strong>: - <strong>请求方式</strong>:POST -
|
||
<strong>请求路径</strong>:<code>/admin-api/water/reading/import</code>
|
||
- <strong>Content-Type</strong>:<code>multipart/form-data</code></p>
|
||
<p><strong>请求参数</strong>: | 参数名 | 类型 | 必填 | 说明 | 示例 |
|
||
|——-|——|——|——|——| | file | MultipartFile | 是 | Excel文件 |
|
||
reading_data.xlsx | | updateSupport | Boolean | 否 | 是否更新已有数据 |
|
||
false |</p>
|
||
<p><strong>响应参数</strong>:</p>
|
||
<div class="sourceCode" id="cb26"><pre
|
||
class="sourceCode json"><code class="sourceCode json"><span id="cb26-1"><a href="#cb26-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
|
||
<span id="cb26-2"><a href="#cb26-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">"code"</span><span class="fu">:</span> <span class="dv">0</span><span class="fu">,</span></span>
|
||
<span id="cb26-3"><a href="#cb26-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">"msg"</span><span class="fu">:</span> <span class="st">"操作成功"</span><span class="fu">,</span></span>
|
||
<span id="cb26-4"><a href="#cb26-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">"data"</span><span class="fu">:</span> <span class="fu">{</span></span>
|
||
<span id="cb26-5"><a href="#cb26-5" aria-hidden="true" tabindex="-1"></a> <span class="dt">"successCount"</span><span class="fu">:</span> <span class="dv">95</span><span class="fu">,</span></span>
|
||
<span id="cb26-6"><a href="#cb26-6" aria-hidden="true" tabindex="-1"></a> <span class="dt">"failureCount"</span><span class="fu">:</span> <span class="dv">5</span><span class="fu">,</span></span>
|
||
<span id="cb26-7"><a href="#cb26-7" aria-hidden="true" tabindex="-1"></a> <span class="dt">"failureList"</span><span class="fu">:</span> <span class="ot">[</span></span>
|
||
<span id="cb26-8"><a href="#cb26-8" aria-hidden="true" tabindex="-1"></a> <span class="fu">{</span></span>
|
||
<span id="cb26-9"><a href="#cb26-9" aria-hidden="true" tabindex="-1"></a> <span class="dt">"lineNumber"</span><span class="fu">:</span> <span class="dv">3</span><span class="fu">,</span></span>
|
||
<span id="cb26-10"><a href="#cb26-10" aria-hidden="true" tabindex="-1"></a> <span class="dt">"meterCode"</span><span class="fu">:</span> <span class="st">"M003"</span><span class="fu">,</span> </span>
|
||
<span id="cb26-11"><a href="#cb26-11" aria-hidden="true" tabindex="-1"></a> <span class="dt">"errorMsg"</span><span class="fu">:</span> <span class="st">"水表不存在"</span></span>
|
||
<span id="cb26-12"><a href="#cb26-12" aria-hidden="true" tabindex="-1"></a> <span class="fu">}</span></span>
|
||
<span id="cb26-13"><a href="#cb26-13" aria-hidden="true" tabindex="-1"></a> <span class="ot">]</span></span>
|
||
<span id="cb26-14"><a href="#cb26-14" aria-hidden="true" tabindex="-1"></a> <span class="fu">}</span></span>
|
||
<span id="cb26-15"><a href="#cb26-15" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
|
||
<h3 data-number="1.5.3" id="账单管理api接口"><span
|
||
class="header-section-number">1.5.3</span> 3.3 账单管理API接口</h3>
|
||
<h4 data-number="1.5.3.1" id="账单查询接口"><span
|
||
class="header-section-number">1.5.3.1</span> 3.3.1 账单查询接口</h4>
|
||
<p><strong>功能描述</strong>:根据客户ID和查询条件查询账单信息。</p>
|
||
<p><strong>接口详情</strong>: - <strong>请求方式</strong>:GET -
|
||
<strong>请求路径</strong>:<code>/admin-api/water/bill/page</code></p>
|
||
<p><strong>请求参数</strong>: | 参数名 | 类型 | 必填 | 说明 | 示例 |
|
||
|——-|——|——|——|——| | pageNo | Integer | 否 | 页码,默认1 | 1 | | pageSize
|
||
| Integer | 否 | 每页条数,默认10 | 10 | | customerId | Long | 否 |
|
||
客户ID | 1 | | billMonth | String | 否 | 账期 | 2024-12 | | billStatus |
|
||
Integer | 否 | 账单状态 | 0 |</p>
|
||
<p><strong>响应参数</strong>:</p>
|
||
<div class="sourceCode" id="cb27"><pre
|
||
class="sourceCode json"><code class="sourceCode json"><span id="cb27-1"><a href="#cb27-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
|
||
<span id="cb27-2"><a href="#cb27-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">"code"</span><span class="fu">:</span> <span class="dv">0</span><span class="fu">,</span></span>
|
||
<span id="cb27-3"><a href="#cb27-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">"msg"</span><span class="fu">:</span> <span class="st">"操作成功"</span><span class="fu">,</span></span>
|
||
<span id="cb27-4"><a href="#cb27-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">"data"</span><span class="fu">:</span> <span class="fu">{</span></span>
|
||
<span id="cb27-5"><a href="#cb27-5" aria-hidden="true" tabindex="-1"></a> <span class="dt">"list"</span><span class="fu">:</span> <span class="ot">[</span></span>
|
||
<span id="cb27-6"><a href="#cb27-6" aria-hidden="true" tabindex="-1"></a> <span class="fu">{</span></span>
|
||
<span id="cb27-7"><a href="#cb27-7" aria-hidden="true" tabindex="-1"></a> <span class="dt">"id"</span><span class="fu">:</span> <span class="dv">1</span><span class="fu">,</span></span>
|
||
<span id="cb27-8"><a href="#cb27-8" aria-hidden="true" tabindex="-1"></a> <span class="dt">"billCode"</span><span class="fu">:</span> <span class="st">"B202412190001"</span><span class="fu">,</span></span>
|
||
<span id="cb27-9"><a href="#cb27-9" aria-hidden="true" tabindex="-1"></a> <span class="dt">"billMonth"</span><span class="fu">:</span> <span class="st">"2024-12"</span><span class="fu">,</span></span>
|
||
<span id="cb27-10"><a href="#cb27-10" aria-hidden="true" tabindex="-1"></a> <span class="dt">"billDate"</span><span class="fu">:</span> <span class="st">"2024-12-19"</span><span class="fu">,</span></span>
|
||
<span id="cb27-11"><a href="#cb27-11" aria-hidden="true" tabindex="-1"></a> <span class="dt">"waterUsage"</span><span class="fu">:</span> <span class="fl">25.50</span><span class="fu">,</span></span>
|
||
<span id="cb27-12"><a href="#cb27-12" aria-hidden="true" tabindex="-1"></a> <span class="dt">"waterFee"</span><span class="fu">:</span> <span class="fl">76.50</span><span class="fu">,</span></span>
|
||
<span id="cb27-13"><a href="#cb27-13" aria-hidden="true" tabindex="-1"></a> <span class="dt">"sewageFee"</span><span class="fu">:</span> <span class="fl">15.30</span><span class="fu">,</span></span>
|
||
<span id="cb27-14"><a href="#cb27-14" aria-hidden="true" tabindex="-1"></a> <span class="dt">"totalAmount"</span><span class="fu">:</span> <span class="fl">91.80</span><span class="fu">,</span></span>
|
||
<span id="cb27-15"><a href="#cb27-15" aria-hidden="true" tabindex="-1"></a> <span class="dt">"paidAmount"</span><span class="fu">:</span> <span class="dv">0</span><span class="er">.00</span><span class="fu">,</span></span>
|
||
<span id="cb27-16"><a href="#cb27-16" aria-hidden="true" tabindex="-1"></a> <span class="dt">"balanceAmount"</span><span class="fu">:</span> <span class="fl">91.80</span><span class="fu">,</span></span>
|
||
<span id="cb27-17"><a href="#cb27-17" aria-hidden="true" tabindex="-1"></a> <span class="dt">"dueDate"</span><span class="fu">:</span> <span class="st">"2025-01-19"</span><span class="fu">,</span></span>
|
||
<span id="cb27-18"><a href="#cb27-18" aria-hidden="true" tabindex="-1"></a> <span class="dt">"billStatus"</span><span class="fu">:</span> <span class="dv">0</span><span class="fu">,</span></span>
|
||
<span id="cb27-19"><a href="#cb27-19" aria-hidden="true" tabindex="-1"></a> <span class="dt">"customerName"</span><span class="fu">:</span> <span class="st">"张三"</span><span class="fu">,</span></span>
|
||
<span id="cb27-20"><a href="#cb27-20" aria-hidden="true" tabindex="-1"></a> <span class="dt">"meterCode"</span><span class="fu">:</span> <span class="st">"M001"</span></span>
|
||
<span id="cb27-21"><a href="#cb27-21" aria-hidden="true" tabindex="-1"></a> <span class="fu">}</span></span>
|
||
<span id="cb27-22"><a href="#cb27-22" aria-hidden="true" tabindex="-1"></a> <span class="ot">]</span><span class="fu">,</span></span>
|
||
<span id="cb27-23"><a href="#cb27-23" aria-hidden="true" tabindex="-1"></a> <span class="dt">"total"</span><span class="fu">:</span> <span class="dv">1</span></span>
|
||
<span id="cb27-24"><a href="#cb27-24" aria-hidden="true" tabindex="-1"></a> <span class="fu">}</span></span>
|
||
<span id="cb27-25"><a href="#cb27-25" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
|
||
<h4 data-number="1.5.3.2" id="账单生成接口"><span
|
||
class="header-section-number">1.5.3.2</span> 3.3.2 账单生成接口</h4>
|
||
<p><strong>功能描述</strong>:根据抄表记录生成水费账单。</p>
|
||
<p><strong>接口详情</strong>: - <strong>请求方式</strong>:POST -
|
||
<strong>请求路径</strong>:<code>/admin-api/water/bill/generate</code></p>
|
||
<p><strong>请求参数</strong>:</p>
|
||
<div class="sourceCode" id="cb28"><pre
|
||
class="sourceCode json"><code class="sourceCode json"><span id="cb28-1"><a href="#cb28-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
|
||
<span id="cb28-2"><a href="#cb28-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">"billMonth"</span><span class="fu">:</span> <span class="st">"2024-12"</span><span class="fu">,</span></span>
|
||
<span id="cb28-3"><a href="#cb28-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">"customerIds"</span><span class="fu">:</span> <span class="ot">[</span><span class="dv">1</span><span class="ot">,</span> <span class="dv">2</span><span class="ot">,</span> <span class="dv">3</span><span class="ot">]</span><span class="fu">,</span></span>
|
||
<span id="cb28-4"><a href="#cb28-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">"readingIds"</span><span class="fu">:</span> <span class="ot">[</span><span class="dv">1</span><span class="ot">,</span> <span class="dv">2</span><span class="ot">,</span> <span class="dv">3</span><span class="ot">]</span><span class="fu">,</span></span>
|
||
<span id="cb28-5"><a href="#cb28-5" aria-hidden="true" tabindex="-1"></a> <span class="dt">"dueDate"</span><span class="fu">:</span> <span class="st">"2025-01-19"</span></span>
|
||
<span id="cb28-6"><a href="#cb28-6" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
|
||
<p><strong>响应参数</strong>:</p>
|
||
<div class="sourceCode" id="cb29"><pre
|
||
class="sourceCode json"><code class="sourceCode json"><span id="cb29-1"><a href="#cb29-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
|
||
<span id="cb29-2"><a href="#cb29-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">"code"</span><span class="fu">:</span> <span class="dv">0</span><span class="fu">,</span></span>
|
||
<span id="cb29-3"><a href="#cb29-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">"msg"</span><span class="fu">:</span> <span class="st">"操作成功"</span><span class="fu">,</span></span>
|
||
<span id="cb29-4"><a href="#cb29-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">"data"</span><span class="fu">:</span> <span class="fu">{</span></span>
|
||
<span id="cb29-5"><a href="#cb29-5" aria-hidden="true" tabindex="-1"></a> <span class="dt">"generateCount"</span><span class="fu">:</span> <span class="dv">3</span><span class="fu">,</span></span>
|
||
<span id="cb29-6"><a href="#cb29-6" aria-hidden="true" tabindex="-1"></a> <span class="dt">"successList"</span><span class="fu">:</span> <span class="ot">[</span></span>
|
||
<span id="cb29-7"><a href="#cb29-7" aria-hidden="true" tabindex="-1"></a> <span class="fu">{</span></span>
|
||
<span id="cb29-8"><a href="#cb29-8" aria-hidden="true" tabindex="-1"></a> <span class="dt">"customerId"</span><span class="fu">:</span> <span class="dv">1</span><span class="fu">,</span></span>
|
||
<span id="cb29-9"><a href="#cb29-9" aria-hidden="true" tabindex="-1"></a> <span class="dt">"billId"</span><span class="fu">:</span> <span class="dv">1</span><span class="fu">,</span></span>
|
||
<span id="cb29-10"><a href="#cb29-10" aria-hidden="true" tabindex="-1"></a> <span class="dt">"totalAmount"</span><span class="fu">:</span> <span class="fl">91.80</span></span>
|
||
<span id="cb29-11"><a href="#cb29-11" aria-hidden="true" tabindex="-1"></a> <span class="fu">}</span></span>
|
||
<span id="cb29-12"><a href="#cb29-12" aria-hidden="true" tabindex="-1"></a> <span class="ot">]</span><span class="fu">,</span></span>
|
||
<span id="cb29-13"><a href="#cb29-13" aria-hidden="true" tabindex="-1"></a> <span class="dt">"failureList"</span><span class="fu">:</span> <span class="ot">[]</span></span>
|
||
<span id="cb29-14"><a href="#cb29-14" aria-hidden="true" tabindex="-1"></a> <span class="fu">}</span></span>
|
||
<span id="cb29-15"><a href="#cb29-15" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
|
||
<p><strong>Service层代码示例</strong>:</p>
|
||
<div class="sourceCode" id="cb30"><pre
|
||
class="sourceCode java"><code class="sourceCode java"><span id="cb30-1"><a href="#cb30-1" aria-hidden="true" tabindex="-1"></a><span class="at">@Service</span></span>
|
||
<span id="cb30-2"><a href="#cb30-2" aria-hidden="true" tabindex="-1"></a><span class="at">@Validated</span></span>
|
||
<span id="cb30-3"><a href="#cb30-3" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> <span class="kw">class</span> BillServiceImpl <span class="kw">implements</span> BillService <span class="op">{</span></span>
|
||
<span id="cb30-4"><a href="#cb30-4" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb30-5"><a href="#cb30-5" aria-hidden="true" tabindex="-1"></a> <span class="at">@Resource</span></span>
|
||
<span id="cb30-6"><a href="#cb30-6" aria-hidden="true" tabindex="-1"></a> <span class="kw">private</span> BillMapper billMapper<span class="op">;</span></span>
|
||
<span id="cb30-7"><a href="#cb30-7" aria-hidden="true" tabindex="-1"></a> <span class="at">@Resource</span></span>
|
||
<span id="cb30-8"><a href="#cb30-8" aria-hidden="true" tabindex="-1"></a> <span class="kw">private</span> MeterReadingService readingService<span class="op">;</span></span>
|
||
<span id="cb30-9"><a href="#cb30-9" aria-hidden="true" tabindex="-1"></a> <span class="at">@Resource</span></span>
|
||
<span id="cb30-10"><a href="#cb30-10" aria-hidden="true" tabindex="-1"></a> <span class="kw">private</span> WaterPriceService priceService<span class="op">;</span></span>
|
||
<span id="cb30-11"><a href="#cb30-11" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb30-12"><a href="#cb30-12" aria-hidden="true" tabindex="-1"></a> <span class="at">@Override</span></span>
|
||
<span id="cb30-13"><a href="#cb30-13" aria-hidden="true" tabindex="-1"></a> <span class="at">@Transactional</span><span class="op">(</span>rollbackFor <span class="op">=</span> <span class="bu">Exception</span><span class="op">.</span><span class="fu">class</span><span class="op">)</span></span>
|
||
<span id="cb30-14"><a href="#cb30-14" aria-hidden="true" tabindex="-1"></a> <span class="kw">public</span> BillGenerateRespVO <span class="fu">generateBills</span><span class="op">(</span>BillGenerateReqVO generateReqVO<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb30-15"><a href="#cb30-15" aria-hidden="true" tabindex="-1"></a> BillGenerateRespVO result <span class="op">=</span> <span class="kw">new</span> <span class="fu">BillGenerateRespVO</span><span class="op">();</span></span>
|
||
<span id="cb30-16"><a href="#cb30-16" aria-hidden="true" tabindex="-1"></a> <span class="bu">List</span><span class="op"><</span>BillGenerateDetailVO<span class="op">></span> successList <span class="op">=</span> <span class="kw">new</span> <span class="bu">ArrayList</span><span class="op"><>();</span></span>
|
||
<span id="cb30-17"><a href="#cb30-17" aria-hidden="true" tabindex="-1"></a> <span class="bu">List</span><span class="op"><</span>BillGenerateDetailVO<span class="op">></span> failureList <span class="op">=</span> <span class="kw">new</span> <span class="bu">ArrayList</span><span class="op"><>();</span></span>
|
||
<span id="cb30-18"><a href="#cb30-18" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb30-19"><a href="#cb30-19" aria-hidden="true" tabindex="-1"></a> <span class="cf">for</span> <span class="op">(</span><span class="bu">Long</span> readingId <span class="op">:</span> generateReqVO<span class="op">.</span><span class="fu">getReadingIds</span><span class="op">())</span> <span class="op">{</span></span>
|
||
<span id="cb30-20"><a href="#cb30-20" aria-hidden="true" tabindex="-1"></a> <span class="cf">try</span> <span class="op">{</span></span>
|
||
<span id="cb30-21"><a href="#cb30-21" aria-hidden="true" tabindex="-1"></a> <span class="co">// 获取抄表记录</span></span>
|
||
<span id="cb30-22"><a href="#cb30-22" aria-hidden="true" tabindex="-1"></a> MeterReadingDO reading <span class="op">=</span> readingService<span class="op">.</span><span class="fu">getReading</span><span class="op">(</span>readingId<span class="op">);</span></span>
|
||
<span id="cb30-23"><a href="#cb30-23" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb30-24"><a href="#cb30-24" aria-hidden="true" tabindex="-1"></a> <span class="co">// 计算水费</span></span>
|
||
<span id="cb30-25"><a href="#cb30-25" aria-hidden="true" tabindex="-1"></a> WaterFeeCalculateDTO feeResult <span class="op">=</span> priceService<span class="op">.</span><span class="fu">calculateWaterFee</span><span class="op">(</span></span>
|
||
<span id="cb30-26"><a href="#cb30-26" aria-hidden="true" tabindex="-1"></a> reading<span class="op">.</span><span class="fu">getCustomerId</span><span class="op">(),</span> reading<span class="op">.</span><span class="fu">getWaterUsage</span><span class="op">());</span></span>
|
||
<span id="cb30-27"><a href="#cb30-27" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb30-28"><a href="#cb30-28" aria-hidden="true" tabindex="-1"></a> <span class="co">// 创建账单</span></span>
|
||
<span id="cb30-29"><a href="#cb30-29" aria-hidden="true" tabindex="-1"></a> BillDO bill <span class="op">=</span> <span class="kw">new</span> <span class="fu">BillDO</span><span class="op">();</span></span>
|
||
<span id="cb30-30"><a href="#cb30-30" aria-hidden="true" tabindex="-1"></a> bill<span class="op">.</span><span class="fu">setBillCode</span><span class="op">(</span><span class="fu">generateBillCode</span><span class="op">());</span></span>
|
||
<span id="cb30-31"><a href="#cb30-31" aria-hidden="true" tabindex="-1"></a> bill<span class="op">.</span><span class="fu">setBillMonth</span><span class="op">(</span>generateReqVO<span class="op">.</span><span class="fu">getBillMonth</span><span class="op">());</span></span>
|
||
<span id="cb30-32"><a href="#cb30-32" aria-hidden="true" tabindex="-1"></a> bill<span class="op">.</span><span class="fu">setCustomerId</span><span class="op">(</span>reading<span class="op">.</span><span class="fu">getCustomerId</span><span class="op">());</span></span>
|
||
<span id="cb30-33"><a href="#cb30-33" aria-hidden="true" tabindex="-1"></a> bill<span class="op">.</span><span class="fu">setMeterId</span><span class="op">(</span>reading<span class="op">.</span><span class="fu">getMeterId</span><span class="op">());</span></span>
|
||
<span id="cb30-34"><a href="#cb30-34" aria-hidden="true" tabindex="-1"></a> bill<span class="op">.</span><span class="fu">setReadingId</span><span class="op">(</span>readingId<span class="op">);</span></span>
|
||
<span id="cb30-35"><a href="#cb30-35" aria-hidden="true" tabindex="-1"></a> bill<span class="op">.</span><span class="fu">setWaterUsage</span><span class="op">(</span>reading<span class="op">.</span><span class="fu">getWaterUsage</span><span class="op">());</span></span>
|
||
<span id="cb30-36"><a href="#cb30-36" aria-hidden="true" tabindex="-1"></a> bill<span class="op">.</span><span class="fu">setWaterFee</span><span class="op">(</span>feeResult<span class="op">.</span><span class="fu">getWaterFee</span><span class="op">());</span></span>
|
||
<span id="cb30-37"><a href="#cb30-37" aria-hidden="true" tabindex="-1"></a> bill<span class="op">.</span><span class="fu">setSewageFee</span><span class="op">(</span>feeResult<span class="op">.</span><span class="fu">getSewageFee</span><span class="op">());</span></span>
|
||
<span id="cb30-38"><a href="#cb30-38" aria-hidden="true" tabindex="-1"></a> bill<span class="op">.</span><span class="fu">setTotalAmount</span><span class="op">(</span>feeResult<span class="op">.</span><span class="fu">getTotalAmount</span><span class="op">());</span></span>
|
||
<span id="cb30-39"><a href="#cb30-39" aria-hidden="true" tabindex="-1"></a> bill<span class="op">.</span><span class="fu">setDueDate</span><span class="op">(</span>generateReqVO<span class="op">.</span><span class="fu">getDueDate</span><span class="op">());</span></span>
|
||
<span id="cb30-40"><a href="#cb30-40" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb30-41"><a href="#cb30-41" aria-hidden="true" tabindex="-1"></a> billMapper<span class="op">.</span><span class="fu">insert</span><span class="op">(</span>bill<span class="op">);</span></span>
|
||
<span id="cb30-42"><a href="#cb30-42" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb30-43"><a href="#cb30-43" aria-hidden="true" tabindex="-1"></a> successList<span class="op">.</span><span class="fu">add</span><span class="op">(</span><span class="fu">buildSuccessDetail</span><span class="op">(</span>reading<span class="op">.</span><span class="fu">getCustomerId</span><span class="op">(),</span> </span>
|
||
<span id="cb30-44"><a href="#cb30-44" aria-hidden="true" tabindex="-1"></a> bill<span class="op">.</span><span class="fu">getId</span><span class="op">(),</span> feeResult<span class="op">.</span><span class="fu">getTotalAmount</span><span class="op">()));</span></span>
|
||
<span id="cb30-45"><a href="#cb30-45" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb30-46"><a href="#cb30-46" aria-hidden="true" tabindex="-1"></a> <span class="op">}</span> <span class="cf">catch</span> <span class="op">(</span><span class="bu">Exception</span> e<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb30-47"><a href="#cb30-47" aria-hidden="true" tabindex="-1"></a> failureList<span class="op">.</span><span class="fu">add</span><span class="op">(</span><span class="fu">buildFailureDetail</span><span class="op">(</span>readingId<span class="op">,</span> e<span class="op">.</span><span class="fu">getMessage</span><span class="op">()));</span></span>
|
||
<span id="cb30-48"><a href="#cb30-48" aria-hidden="true" tabindex="-1"></a> <span class="op">}</span></span>
|
||
<span id="cb30-49"><a href="#cb30-49" aria-hidden="true" tabindex="-1"></a> <span class="op">}</span></span>
|
||
<span id="cb30-50"><a href="#cb30-50" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb30-51"><a href="#cb30-51" aria-hidden="true" tabindex="-1"></a> result<span class="op">.</span><span class="fu">setGenerateCount</span><span class="op">(</span>successList<span class="op">.</span><span class="fu">size</span><span class="op">());</span></span>
|
||
<span id="cb30-52"><a href="#cb30-52" aria-hidden="true" tabindex="-1"></a> result<span class="op">.</span><span class="fu">setSuccessList</span><span class="op">(</span>successList<span class="op">);</span></span>
|
||
<span id="cb30-53"><a href="#cb30-53" aria-hidden="true" tabindex="-1"></a> result<span class="op">.</span><span class="fu">setFailureList</span><span class="op">(</span>failureList<span class="op">);</span></span>
|
||
<span id="cb30-54"><a href="#cb30-54" aria-hidden="true" tabindex="-1"></a> <span class="cf">return</span> result<span class="op">;</span></span>
|
||
<span id="cb30-55"><a href="#cb30-55" aria-hidden="true" tabindex="-1"></a> <span class="op">}</span></span>
|
||
<span id="cb30-56"><a href="#cb30-56" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
|
||
<h3 data-number="1.5.4" id="缴费管理api接口"><span
|
||
class="header-section-number">1.5.4</span> 3.4 缴费管理API接口</h3>
|
||
<h4 data-number="1.5.4.1" id="缴费处理接口"><span
|
||
class="header-section-number">1.5.4.1</span> 3.4.1 缴费处理接口</h4>
|
||
<p><strong>功能描述</strong>:处理客户缴费操作。</p>
|
||
<p><strong>接口详情</strong>: - <strong>请求方式</strong>:POST -
|
||
<strong>请求路径</strong>:<code>/admin-api/water/payment/create</code></p>
|
||
<p><strong>请求参数</strong>:</p>
|
||
<div class="sourceCode" id="cb31"><pre
|
||
class="sourceCode json"><code class="sourceCode json"><span id="cb31-1"><a href="#cb31-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
|
||
<span id="cb31-2"><a href="#cb31-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">"customerId"</span><span class="fu">:</span> <span class="dv">1</span><span class="fu">,</span></span>
|
||
<span id="cb31-3"><a href="#cb31-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">"billIds"</span><span class="fu">:</span> <span class="ot">[</span><span class="dv">1</span><span class="ot">,</span> <span class="dv">2</span><span class="ot">]</span><span class="fu">,</span></span>
|
||
<span id="cb31-4"><a href="#cb31-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">"paymentType"</span><span class="fu">:</span> <span class="st">"NORMAL"</span><span class="fu">,</span></span>
|
||
<span id="cb31-5"><a href="#cb31-5" aria-hidden="true" tabindex="-1"></a> <span class="dt">"paymentChannel"</span><span class="fu">:</span> <span class="st">"CASH"</span><span class="fu">,</span></span>
|
||
<span id="cb31-6"><a href="#cb31-6" aria-hidden="true" tabindex="-1"></a> <span class="dt">"paymentAmount"</span><span class="fu">:</span> <span class="fl">183.60</span><span class="fu">,</span></span>
|
||
<span id="cb31-7"><a href="#cb31-7" aria-hidden="true" tabindex="-1"></a> <span class="dt">"actualAmount"</span><span class="fu">:</span> <span class="fl">200.00</span><span class="fu">,</span></span>
|
||
<span id="cb31-8"><a href="#cb31-8" aria-hidden="true" tabindex="-1"></a> <span class="dt">"operatorId"</span><span class="fu">:</span> <span class="st">"OP001"</span><span class="fu">,</span></span>
|
||
<span id="cb31-9"><a href="#cb31-9" aria-hidden="true" tabindex="-1"></a> <span class="dt">"outletCode"</span><span class="fu">:</span> <span class="st">"OUT001"</span><span class="fu">,</span></span>
|
||
<span id="cb31-10"><a href="#cb31-10" aria-hidden="true" tabindex="-1"></a> <span class="dt">"remark"</span><span class="fu">:</span> <span class="st">"现金缴费"</span></span>
|
||
<span id="cb31-11"><a href="#cb31-11" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
|
||
<p><strong>响应参数</strong>:</p>
|
||
<div class="sourceCode" id="cb32"><pre
|
||
class="sourceCode json"><code class="sourceCode json"><span id="cb32-1"><a href="#cb32-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
|
||
<span id="cb32-2"><a href="#cb32-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">"code"</span><span class="fu">:</span> <span class="dv">0</span><span class="fu">,</span></span>
|
||
<span id="cb32-3"><a href="#cb32-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">"msg"</span><span class="fu">:</span> <span class="st">"操作成功"</span><span class="fu">,</span></span>
|
||
<span id="cb32-4"><a href="#cb32-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">"data"</span><span class="fu">:</span> <span class="fu">{</span></span>
|
||
<span id="cb32-5"><a href="#cb32-5" aria-hidden="true" tabindex="-1"></a> <span class="dt">"paymentId"</span><span class="fu">:</span> <span class="dv">1</span><span class="fu">,</span></span>
|
||
<span id="cb32-6"><a href="#cb32-6" aria-hidden="true" tabindex="-1"></a> <span class="dt">"paymentCode"</span><span class="fu">:</span> <span class="st">"P202412190001"</span><span class="fu">,</span></span>
|
||
<span id="cb32-7"><a href="#cb32-7" aria-hidden="true" tabindex="-1"></a> <span class="dt">"changeAmount"</span><span class="fu">:</span> <span class="fl">16.40</span><span class="fu">,</span></span>
|
||
<span id="cb32-8"><a href="#cb32-8" aria-hidden="true" tabindex="-1"></a> <span class="dt">"invoiceNo"</span><span class="fu">:</span> <span class="st">"INV20241219001"</span></span>
|
||
<span id="cb32-9"><a href="#cb32-9" aria-hidden="true" tabindex="-1"></a> <span class="fu">}</span></span>
|
||
<span id="cb32-10"><a href="#cb32-10" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
|
||
<h4 data-number="1.5.4.2" id="在线支付接口"><span
|
||
class="header-section-number">1.5.4.2</span> 3.4.2 在线支付接口</h4>
|
||
<p><strong>功能描述</strong>:处理在线支付(微信、支付宝等)。</p>
|
||
<p><strong>接口详情</strong>: - <strong>请求方式</strong>:POST -
|
||
<strong>请求路径</strong>:<code>/admin-api/water/payment/online-pay</code></p>
|
||
<p><strong>请求参数</strong>:</p>
|
||
<div class="sourceCode" id="cb33"><pre
|
||
class="sourceCode json"><code class="sourceCode json"><span id="cb33-1"><a href="#cb33-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
|
||
<span id="cb33-2"><a href="#cb33-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">"customerId"</span><span class="fu">:</span> <span class="dv">1</span><span class="fu">,</span></span>
|
||
<span id="cb33-3"><a href="#cb33-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">"billIds"</span><span class="fu">:</span> <span class="ot">[</span><span class="dv">1</span><span class="ot">]</span><span class="fu">,</span></span>
|
||
<span id="cb33-4"><a href="#cb33-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">"paymentChannel"</span><span class="fu">:</span> <span class="st">"WECHAT"</span><span class="fu">,</span></span>
|
||
<span id="cb33-5"><a href="#cb33-5" aria-hidden="true" tabindex="-1"></a> <span class="dt">"paymentAmount"</span><span class="fu">:</span> <span class="fl">91.80</span><span class="fu">,</span></span>
|
||
<span id="cb33-6"><a href="#cb33-6" aria-hidden="true" tabindex="-1"></a> <span class="dt">"returnUrl"</span><span class="fu">:</span> <span class="st">"https://water.example.com/payment/callback"</span><span class="fu">,</span></span>
|
||
<span id="cb33-7"><a href="#cb33-7" aria-hidden="true" tabindex="-1"></a> <span class="dt">"notifyUrl"</span><span class="fu">:</span> <span class="st">"https://water.example.com/api/payment/notify"</span></span>
|
||
<span id="cb33-8"><a href="#cb33-8" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
|
||
<p><strong>响应参数</strong>:</p>
|
||
<div class="sourceCode" id="cb34"><pre
|
||
class="sourceCode json"><code class="sourceCode json"><span id="cb34-1"><a href="#cb34-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
|
||
<span id="cb34-2"><a href="#cb34-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">"code"</span><span class="fu">:</span> <span class="dv">0</span><span class="fu">,</span></span>
|
||
<span id="cb34-3"><a href="#cb34-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">"msg"</span><span class="fu">:</span> <span class="st">"操作成功"</span><span class="fu">,</span></span>
|
||
<span id="cb34-4"><a href="#cb34-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">"data"</span><span class="fu">:</span> <span class="fu">{</span></span>
|
||
<span id="cb34-5"><a href="#cb34-5" aria-hidden="true" tabindex="-1"></a> <span class="dt">"paymentCode"</span><span class="fu">:</span> <span class="st">"P202412190002"</span><span class="fu">,</span></span>
|
||
<span id="cb34-6"><a href="#cb34-6" aria-hidden="true" tabindex="-1"></a> <span class="dt">"prepayId"</span><span class="fu">:</span> <span class="st">"wx20241219001234567890"</span><span class="fu">,</span></span>
|
||
<span id="cb34-7"><a href="#cb34-7" aria-hidden="true" tabindex="-1"></a> <span class="dt">"payUrl"</span><span class="fu">:</span> <span class="st">"weixin://wxpay/bizpayurl?pr=abc123"</span><span class="fu">,</span></span>
|
||
<span id="cb34-8"><a href="#cb34-8" aria-hidden="true" tabindex="-1"></a> <span class="dt">"qrCode"</span><span class="fu">:</span> <span class="st">"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..."</span></span>
|
||
<span id="cb34-9"><a href="#cb34-9" aria-hidden="true" tabindex="-1"></a> <span class="fu">}</span></span>
|
||
<span id="cb34-10"><a href="#cb34-10" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
|
||
<h3 data-number="1.5.5" id="工单接口"><span
|
||
class="header-section-number">1.5.5</span> 3.4 工单接口</h3>
|
||
<h4 data-number="1.5.5.1" id="工单创建接口"><span
|
||
class="header-section-number">1.5.5.1</span> 3.4.1 工单创建接口</h4>
|
||
<p><strong>功能描述</strong>:创建业务工单。</p>
|
||
<p><strong>接口规范</strong>: - 请求方式:POST -
|
||
请求路径:/api/workorders - 请求/返回格式:JSON</p>
|
||
<h4 data-number="1.5.5.2" id="工单状态更新接口"><span
|
||
class="header-section-number">1.5.5.2</span> 3.4.2 工单状态更新接口</h4>
|
||
<p><strong>功能描述</strong>:更新工单处理状态。</p>
|
||
<p><strong>接口规范</strong>: - 请求方式:PUT -
|
||
请求路径:/api/workorders/{workorderId}/status - 请求/返回格式:JSON</p>
|
||
<h2 data-number="1.6" id="接口标准"><span
|
||
class="header-section-number">1.6</span> 4. 接口标准</h2>
|
||
<h3 data-number="1.6.1" id="接口协议"><span
|
||
class="header-section-number">1.6.1</span> 4.1 接口协议</h3>
|
||
<p>系统接口主要采用以下协议:</p>
|
||
<ul>
|
||
<li><strong>RESTful
|
||
API</strong>:适用于系统内部模块间的交互以及移动应用等轻量级客户端</li>
|
||
<li><strong>WebService</strong>:适用于与外部系统的集成,特别是银行等传统机构</li>
|
||
<li><strong>消息队列</strong>:适用于异步处理的场景,如批量数据处理、通知推送等</li>
|
||
</ul>
|
||
<h3 data-number="1.6.2" id="数据格式"><span
|
||
class="header-section-number">1.6.2</span> 4.2 数据格式</h3>
|
||
<p>接口数据主要采用以下格式:</p>
|
||
<ul>
|
||
<li><strong>JSON</strong>:主要用于RESTful
|
||
API接口,结构简单清晰,适合Web应用</li>
|
||
<li><strong>XML</strong>:主要用于WebService接口,兼容性好,适合与传统系统对接</li>
|
||
<li><strong>文本文件</strong>:主要用于批量数据交换,如银行代扣文件等</li>
|
||
</ul>
|
||
<h3 data-number="1.6.3" id="接口安全设计"><span
|
||
class="header-section-number">1.6.3</span> 4.3 接口安全设计</h3>
|
||
<p>接口安全采用多层防护机制:</p>
|
||
<h4 data-number="1.6.3.1" id="认证机制"><span
|
||
class="header-section-number">1.6.3.1</span> 4.3.1 认证机制</h4>
|
||
<p><strong>JWT令牌认证</strong>:</p>
|
||
<div class="sourceCode" id="cb35"><pre
|
||
class="sourceCode java"><code class="sourceCode java"><span id="cb35-1"><a href="#cb35-1" aria-hidden="true" tabindex="-1"></a><span class="at">@RestController</span></span>
|
||
<span id="cb35-2"><a href="#cb35-2" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> <span class="kw">class</span> AuthController <span class="op">{</span></span>
|
||
<span id="cb35-3"><a href="#cb35-3" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb35-4"><a href="#cb35-4" aria-hidden="true" tabindex="-1"></a> <span class="at">@Resource</span></span>
|
||
<span id="cb35-5"><a href="#cb35-5" aria-hidden="true" tabindex="-1"></a> <span class="kw">private</span> AuthService authService<span class="op">;</span></span>
|
||
<span id="cb35-6"><a href="#cb35-6" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb35-7"><a href="#cb35-7" aria-hidden="true" tabindex="-1"></a> <span class="at">@PostMapping</span><span class="op">(</span><span class="st">"/admin-api/system/auth/login"</span><span class="op">)</span></span>
|
||
<span id="cb35-8"><a href="#cb35-8" aria-hidden="true" tabindex="-1"></a> <span class="kw">public</span> CommonResult<span class="op"><</span>AuthLoginRespVO<span class="op">></span> <span class="fu">login</span><span class="op">(</span><span class="at">@Valid</span> <span class="at">@RequestBody</span> AuthLoginReqVO reqVO<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb35-9"><a href="#cb35-9" aria-hidden="true" tabindex="-1"></a> <span class="co">// 验证用户名密码</span></span>
|
||
<span id="cb35-10"><a href="#cb35-10" aria-hidden="true" tabindex="-1"></a> AdminUserDO user <span class="op">=</span> authService<span class="op">.</span><span class="fu">authenticate</span><span class="op">(</span>reqVO<span class="op">.</span><span class="fu">getUsername</span><span class="op">(),</span> reqVO<span class="op">.</span><span class="fu">getPassword</span><span class="op">());</span></span>
|
||
<span id="cb35-11"><a href="#cb35-11" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb35-12"><a href="#cb35-12" aria-hidden="true" tabindex="-1"></a> <span class="co">// 生成JWT Token</span></span>
|
||
<span id="cb35-13"><a href="#cb35-13" aria-hidden="true" tabindex="-1"></a> <span class="bu">String</span> token <span class="op">=</span> authService<span class="op">.</span><span class="fu">createToken</span><span class="op">(</span>user<span class="op">.</span><span class="fu">getId</span><span class="op">(),</span> user<span class="op">.</span><span class="fu">getTenantId</span><span class="op">());</span></span>
|
||
<span id="cb35-14"><a href="#cb35-14" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb35-15"><a href="#cb35-15" aria-hidden="true" tabindex="-1"></a> <span class="cf">return</span> <span class="fu">success</span><span class="op">(</span>AuthLoginRespVO<span class="op">.</span><span class="fu">builder</span><span class="op">()</span></span>
|
||
<span id="cb35-16"><a href="#cb35-16" aria-hidden="true" tabindex="-1"></a> <span class="op">.</span><span class="fu">userId</span><span class="op">(</span>user<span class="op">.</span><span class="fu">getId</span><span class="op">())</span></span>
|
||
<span id="cb35-17"><a href="#cb35-17" aria-hidden="true" tabindex="-1"></a> <span class="op">.</span><span class="fu">accessToken</span><span class="op">(</span>token<span class="op">)</span></span>
|
||
<span id="cb35-18"><a href="#cb35-18" aria-hidden="true" tabindex="-1"></a> <span class="op">.</span><span class="fu">refreshToken</span><span class="op">(</span>authService<span class="op">.</span><span class="fu">createRefreshToken</span><span class="op">(</span>user<span class="op">.</span><span class="fu">getId</span><span class="op">()))</span></span>
|
||
<span id="cb35-19"><a href="#cb35-19" aria-hidden="true" tabindex="-1"></a> <span class="op">.</span><span class="fu">expiresTime</span><span class="op">(</span>LocalDateTime<span class="op">.</span><span class="fu">now</span><span class="op">().</span><span class="fu">plusHours</span><span class="op">(</span><span class="dv">2</span><span class="op">))</span></span>
|
||
<span id="cb35-20"><a href="#cb35-20" aria-hidden="true" tabindex="-1"></a> <span class="op">.</span><span class="fu">build</span><span class="op">());</span></span>
|
||
<span id="cb35-21"><a href="#cb35-21" aria-hidden="true" tabindex="-1"></a> <span class="op">}</span></span>
|
||
<span id="cb35-22"><a href="#cb35-22" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
|
||
<p><strong>API Key认证</strong>(外部系统):</p>
|
||
<div class="sourceCode" id="cb36"><pre
|
||
class="sourceCode java"><code class="sourceCode java"><span id="cb36-1"><a href="#cb36-1" aria-hidden="true" tabindex="-1"></a><span class="at">@Component</span></span>
|
||
<span id="cb36-2"><a href="#cb36-2" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> <span class="kw">class</span> ApiKeyAuthenticationFilter <span class="kw">extends</span> OncePerRequestFilter <span class="op">{</span></span>
|
||
<span id="cb36-3"><a href="#cb36-3" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb36-4"><a href="#cb36-4" aria-hidden="true" tabindex="-1"></a> <span class="at">@Override</span></span>
|
||
<span id="cb36-5"><a href="#cb36-5" aria-hidden="true" tabindex="-1"></a> <span class="kw">protected</span> <span class="dt">void</span> <span class="fu">doFilterInternal</span><span class="op">(</span>HttpServletRequest request<span class="op">,</span> </span>
|
||
<span id="cb36-6"><a href="#cb36-6" aria-hidden="true" tabindex="-1"></a> HttpServletResponse response<span class="op">,</span> </span>
|
||
<span id="cb36-7"><a href="#cb36-7" aria-hidden="true" tabindex="-1"></a> FilterChain filterChain<span class="op">)</span> <span class="kw">throws</span> ServletException<span class="op">,</span> <span class="bu">IOException</span> <span class="op">{</span></span>
|
||
<span id="cb36-8"><a href="#cb36-8" aria-hidden="true" tabindex="-1"></a> <span class="bu">String</span> apiKey <span class="op">=</span> request<span class="op">.</span><span class="fu">getHeader</span><span class="op">(</span><span class="st">"X-API-KEY"</span><span class="op">);</span></span>
|
||
<span id="cb36-9"><a href="#cb36-9" aria-hidden="true" tabindex="-1"></a> <span class="bu">String</span> timestamp <span class="op">=</span> request<span class="op">.</span><span class="fu">getHeader</span><span class="op">(</span><span class="st">"X-TIMESTAMP"</span><span class="op">);</span></span>
|
||
<span id="cb36-10"><a href="#cb36-10" aria-hidden="true" tabindex="-1"></a> <span class="bu">String</span> signature <span class="op">=</span> request<span class="op">.</span><span class="fu">getHeader</span><span class="op">(</span><span class="st">"X-SIGNATURE"</span><span class="op">);</span></span>
|
||
<span id="cb36-11"><a href="#cb36-11" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb36-12"><a href="#cb36-12" aria-hidden="true" tabindex="-1"></a> <span class="co">// 验证API Key</span></span>
|
||
<span id="cb36-13"><a href="#cb36-13" aria-hidden="true" tabindex="-1"></a> <span class="cf">if</span> <span class="op">(!</span>apiKeyService<span class="op">.</span><span class="fu">validateApiKey</span><span class="op">(</span>apiKey<span class="op">))</span> <span class="op">{</span></span>
|
||
<span id="cb36-14"><a href="#cb36-14" aria-hidden="true" tabindex="-1"></a> <span class="fu">writeErrorResponse</span><span class="op">(</span>response<span class="op">,</span> <span class="st">"Invalid API Key"</span><span class="op">);</span></span>
|
||
<span id="cb36-15"><a href="#cb36-15" aria-hidden="true" tabindex="-1"></a> <span class="cf">return</span><span class="op">;</span></span>
|
||
<span id="cb36-16"><a href="#cb36-16" aria-hidden="true" tabindex="-1"></a> <span class="op">}</span></span>
|
||
<span id="cb36-17"><a href="#cb36-17" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb36-18"><a href="#cb36-18" aria-hidden="true" tabindex="-1"></a> <span class="co">// 验证时间戳(防重放攻击)</span></span>
|
||
<span id="cb36-19"><a href="#cb36-19" aria-hidden="true" tabindex="-1"></a> <span class="cf">if</span> <span class="op">(!</span><span class="fu">validateTimestamp</span><span class="op">(</span>timestamp<span class="op">))</span> <span class="op">{</span></span>
|
||
<span id="cb36-20"><a href="#cb36-20" aria-hidden="true" tabindex="-1"></a> <span class="fu">writeErrorResponse</span><span class="op">(</span>response<span class="op">,</span> <span class="st">"Request expired"</span><span class="op">);</span></span>
|
||
<span id="cb36-21"><a href="#cb36-21" aria-hidden="true" tabindex="-1"></a> <span class="cf">return</span><span class="op">;</span></span>
|
||
<span id="cb36-22"><a href="#cb36-22" aria-hidden="true" tabindex="-1"></a> <span class="op">}</span></span>
|
||
<span id="cb36-23"><a href="#cb36-23" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb36-24"><a href="#cb36-24" aria-hidden="true" tabindex="-1"></a> <span class="co">// 验证签名</span></span>
|
||
<span id="cb36-25"><a href="#cb36-25" aria-hidden="true" tabindex="-1"></a> <span class="cf">if</span> <span class="op">(!</span><span class="fu">validateSignature</span><span class="op">(</span>request<span class="op">,</span> signature<span class="op">))</span> <span class="op">{</span></span>
|
||
<span id="cb36-26"><a href="#cb36-26" aria-hidden="true" tabindex="-1"></a> <span class="fu">writeErrorResponse</span><span class="op">(</span>response<span class="op">,</span> <span class="st">"Invalid signature"</span><span class="op">);</span></span>
|
||
<span id="cb36-27"><a href="#cb36-27" aria-hidden="true" tabindex="-1"></a> <span class="cf">return</span><span class="op">;</span></span>
|
||
<span id="cb36-28"><a href="#cb36-28" aria-hidden="true" tabindex="-1"></a> <span class="op">}</span></span>
|
||
<span id="cb36-29"><a href="#cb36-29" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb36-30"><a href="#cb36-30" aria-hidden="true" tabindex="-1"></a> filterChain<span class="op">.</span><span class="fu">doFilter</span><span class="op">(</span>request<span class="op">,</span> response<span class="op">);</span></span>
|
||
<span id="cb36-31"><a href="#cb36-31" aria-hidden="true" tabindex="-1"></a> <span class="op">}</span></span>
|
||
<span id="cb36-32"><a href="#cb36-32" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
|
||
<h4 data-number="1.6.3.2" id="数据加密"><span
|
||
class="header-section-number">1.6.3.2</span> 4.3.2 数据加密</h4>
|
||
<p><strong>敏感数据加密</strong>:</p>
|
||
<div class="sourceCode" id="cb37"><pre
|
||
class="sourceCode java"><code class="sourceCode java"><span id="cb37-1"><a href="#cb37-1" aria-hidden="true" tabindex="-1"></a><span class="at">@Component</span></span>
|
||
<span id="cb37-2"><a href="#cb37-2" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> <span class="kw">class</span> DataEncryptionService <span class="op">{</span></span>
|
||
<span id="cb37-3"><a href="#cb37-3" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb37-4"><a href="#cb37-4" aria-hidden="true" tabindex="-1"></a> <span class="kw">private</span> <span class="dt">final</span> AESUtil aesUtil<span class="op">;</span></span>
|
||
<span id="cb37-5"><a href="#cb37-5" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb37-6"><a href="#cb37-6" aria-hidden="true" tabindex="-1"></a> <span class="kw">public</span> <span class="bu">String</span> <span class="fu">encryptPersonalInfo</span><span class="op">(</span><span class="bu">String</span> plainText<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb37-7"><a href="#cb37-7" aria-hidden="true" tabindex="-1"></a> <span class="cf">if</span> <span class="op">(</span>StrUtil<span class="op">.</span><span class="fu">isBlank</span><span class="op">(</span>plainText<span class="op">))</span> <span class="op">{</span></span>
|
||
<span id="cb37-8"><a href="#cb37-8" aria-hidden="true" tabindex="-1"></a> <span class="cf">return</span> plainText<span class="op">;</span></span>
|
||
<span id="cb37-9"><a href="#cb37-9" aria-hidden="true" tabindex="-1"></a> <span class="op">}</span></span>
|
||
<span id="cb37-10"><a href="#cb37-10" aria-hidden="true" tabindex="-1"></a> <span class="cf">return</span> aesUtil<span class="op">.</span><span class="fu">encrypt</span><span class="op">(</span>plainText<span class="op">);</span></span>
|
||
<span id="cb37-11"><a href="#cb37-11" aria-hidden="true" tabindex="-1"></a> <span class="op">}</span></span>
|
||
<span id="cb37-12"><a href="#cb37-12" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb37-13"><a href="#cb37-13" aria-hidden="true" tabindex="-1"></a> <span class="kw">public</span> <span class="bu">String</span> <span class="fu">decryptPersonalInfo</span><span class="op">(</span><span class="bu">String</span> cipherText<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb37-14"><a href="#cb37-14" aria-hidden="true" tabindex="-1"></a> <span class="cf">if</span> <span class="op">(</span>StrUtil<span class="op">.</span><span class="fu">isBlank</span><span class="op">(</span>cipherText<span class="op">))</span> <span class="op">{</span></span>
|
||
<span id="cb37-15"><a href="#cb37-15" aria-hidden="true" tabindex="-1"></a> <span class="cf">return</span> cipherText<span class="op">;</span></span>
|
||
<span id="cb37-16"><a href="#cb37-16" aria-hidden="true" tabindex="-1"></a> <span class="op">}</span></span>
|
||
<span id="cb37-17"><a href="#cb37-17" aria-hidden="true" tabindex="-1"></a> <span class="cf">return</span> aesUtil<span class="op">.</span><span class="fu">decrypt</span><span class="op">(</span>cipherText<span class="op">);</span></span>
|
||
<span id="cb37-18"><a href="#cb37-18" aria-hidden="true" tabindex="-1"></a> <span class="op">}</span></span>
|
||
<span id="cb37-19"><a href="#cb37-19" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
|
||
<h4 data-number="1.6.3.3" id="访问控制"><span
|
||
class="header-section-number">1.6.3.3</span> 4.3.3 访问控制</h4>
|
||
<p><strong>IP白名单控制</strong>:</p>
|
||
<div class="sourceCode" id="cb38"><pre
|
||
class="sourceCode java"><code class="sourceCode java"><span id="cb38-1"><a href="#cb38-1" aria-hidden="true" tabindex="-1"></a><span class="at">@Component</span></span>
|
||
<span id="cb38-2"><a href="#cb38-2" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> <span class="kw">class</span> IpWhitelistFilter <span class="kw">extends</span> OncePerRequestFilter <span class="op">{</span></span>
|
||
<span id="cb38-3"><a href="#cb38-3" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb38-4"><a href="#cb38-4" aria-hidden="true" tabindex="-1"></a> <span class="at">@Value</span><span class="op">(</span><span class="st">"${water.security.ip-whitelist}"</span><span class="op">)</span></span>
|
||
<span id="cb38-5"><a href="#cb38-5" aria-hidden="true" tabindex="-1"></a> <span class="kw">private</span> <span class="bu">List</span><span class="op"><</span><span class="bu">String</span><span class="op">></span> ipWhitelist<span class="op">;</span></span>
|
||
<span id="cb38-6"><a href="#cb38-6" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb38-7"><a href="#cb38-7" aria-hidden="true" tabindex="-1"></a> <span class="at">@Override</span></span>
|
||
<span id="cb38-8"><a href="#cb38-8" aria-hidden="true" tabindex="-1"></a> <span class="kw">protected</span> <span class="dt">void</span> <span class="fu">doFilterInternal</span><span class="op">(</span>HttpServletRequest request<span class="op">,</span> </span>
|
||
<span id="cb38-9"><a href="#cb38-9" aria-hidden="true" tabindex="-1"></a> HttpServletResponse response<span class="op">,</span> </span>
|
||
<span id="cb38-10"><a href="#cb38-10" aria-hidden="true" tabindex="-1"></a> FilterChain filterChain<span class="op">)</span> <span class="kw">throws</span> ServletException<span class="op">,</span> <span class="bu">IOException</span> <span class="op">{</span></span>
|
||
<span id="cb38-11"><a href="#cb38-11" aria-hidden="true" tabindex="-1"></a> <span class="bu">String</span> clientIp <span class="op">=</span> <span class="fu">getClientIpAddress</span><span class="op">(</span>request<span class="op">);</span></span>
|
||
<span id="cb38-12"><a href="#cb38-12" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb38-13"><a href="#cb38-13" aria-hidden="true" tabindex="-1"></a> <span class="cf">if</span> <span class="op">(!</span><span class="fu">isIpAllowed</span><span class="op">(</span>clientIp<span class="op">))</span> <span class="op">{</span></span>
|
||
<span id="cb38-14"><a href="#cb38-14" aria-hidden="true" tabindex="-1"></a> response<span class="op">.</span><span class="fu">setStatus</span><span class="op">(</span>HttpStatus<span class="op">.</span><span class="fu">FORBIDDEN</span><span class="op">.</span><span class="fu">value</span><span class="op">());</span></span>
|
||
<span id="cb38-15"><a href="#cb38-15" aria-hidden="true" tabindex="-1"></a> response<span class="op">.</span><span class="fu">getWriter</span><span class="op">().</span><span class="fu">write</span><span class="op">(</span><span class="st">"{</span><span class="sc">\"</span><span class="st">code</span><span class="sc">\"</span><span class="st">:403,</span><span class="sc">\"</span><span class="st">msg</span><span class="sc">\"</span><span class="st">:</span><span class="sc">\"</span><span class="st">IP access denied</span><span class="sc">\"</span><span class="st">}"</span><span class="op">);</span></span>
|
||
<span id="cb38-16"><a href="#cb38-16" aria-hidden="true" tabindex="-1"></a> <span class="cf">return</span><span class="op">;</span></span>
|
||
<span id="cb38-17"><a href="#cb38-17" aria-hidden="true" tabindex="-1"></a> <span class="op">}</span></span>
|
||
<span id="cb38-18"><a href="#cb38-18" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb38-19"><a href="#cb38-19" aria-hidden="true" tabindex="-1"></a> filterChain<span class="op">.</span><span class="fu">doFilter</span><span class="op">(</span>request<span class="op">,</span> response<span class="op">);</span></span>
|
||
<span id="cb38-20"><a href="#cb38-20" aria-hidden="true" tabindex="-1"></a> <span class="op">}</span></span>
|
||
<span id="cb38-21"><a href="#cb38-21" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
|
||
<h4 data-number="1.6.3.4" id="接口限流"><span
|
||
class="header-section-number">1.6.3.4</span> 4.3.4 接口限流</h4>
|
||
<p><strong>基于Redis的令牌桶限流</strong>:</p>
|
||
<div class="sourceCode" id="cb39"><pre
|
||
class="sourceCode java"><code class="sourceCode java"><span id="cb39-1"><a href="#cb39-1" aria-hidden="true" tabindex="-1"></a><span class="at">@Component</span></span>
|
||
<span id="cb39-2"><a href="#cb39-2" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> <span class="kw">class</span> RateLimitService <span class="op">{</span></span>
|
||
<span id="cb39-3"><a href="#cb39-3" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb39-4"><a href="#cb39-4" aria-hidden="true" tabindex="-1"></a> <span class="at">@Resource</span></span>
|
||
<span id="cb39-5"><a href="#cb39-5" aria-hidden="true" tabindex="-1"></a> <span class="kw">private</span> StringRedisTemplate redisTemplate<span class="op">;</span></span>
|
||
<span id="cb39-6"><a href="#cb39-6" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb39-7"><a href="#cb39-7" aria-hidden="true" tabindex="-1"></a> <span class="kw">public</span> <span class="dt">boolean</span> <span class="fu">allowRequest</span><span class="op">(</span><span class="bu">String</span> key<span class="op">,</span> <span class="dt">int</span> maxRequests<span class="op">,</span> <span class="bu">Duration</span> window<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb39-8"><a href="#cb39-8" aria-hidden="true" tabindex="-1"></a> <span class="bu">String</span> redisKey <span class="op">=</span> <span class="st">"rate_limit:"</span> <span class="op">+</span> key<span class="op">;</span></span>
|
||
<span id="cb39-9"><a href="#cb39-9" aria-hidden="true" tabindex="-1"></a> <span class="bu">String</span> script <span class="op">=</span> <span class="st">"""</span></span>
|
||
<span id="cb39-10"><a href="#cb39-10" aria-hidden="true" tabindex="-1"></a><span class="st"> local key = KEYS[1]</span></span>
|
||
<span id="cb39-11"><a href="#cb39-11" aria-hidden="true" tabindex="-1"></a><span class="st"> local window = tonumber(ARGV[1])</span></span>
|
||
<span id="cb39-12"><a href="#cb39-12" aria-hidden="true" tabindex="-1"></a><span class="st"> local limit = tonumber(ARGV[2])</span></span>
|
||
<span id="cb39-13"><a href="#cb39-13" aria-hidden="true" tabindex="-1"></a><span class="st"> local current = redis.call('get', key)</span></span>
|
||
<span id="cb39-14"><a href="#cb39-14" aria-hidden="true" tabindex="-1"></a><span class="st"> if current == false then</span></span>
|
||
<span id="cb39-15"><a href="#cb39-15" aria-hidden="true" tabindex="-1"></a><span class="st"> redis.call('setex', key, window, 1)</span></span>
|
||
<span id="cb39-16"><a href="#cb39-16" aria-hidden="true" tabindex="-1"></a><span class="st"> return 1</span></span>
|
||
<span id="cb39-17"><a href="#cb39-17" aria-hidden="true" tabindex="-1"></a><span class="st"> end</span></span>
|
||
<span id="cb39-18"><a href="#cb39-18" aria-hidden="true" tabindex="-1"></a><span class="st"> if tonumber(current) < limit then</span></span>
|
||
<span id="cb39-19"><a href="#cb39-19" aria-hidden="true" tabindex="-1"></a><span class="st"> return redis.call('incr', key)</span></span>
|
||
<span id="cb39-20"><a href="#cb39-20" aria-hidden="true" tabindex="-1"></a><span class="st"> else</span></span>
|
||
<span id="cb39-21"><a href="#cb39-21" aria-hidden="true" tabindex="-1"></a><span class="st"> return 0</span></span>
|
||
<span id="cb39-22"><a href="#cb39-22" aria-hidden="true" tabindex="-1"></a><span class="st"> end</span></span>
|
||
<span id="cb39-23"><a href="#cb39-23" aria-hidden="true" tabindex="-1"></a><span class="st"> """</span><span class="op">;</span></span>
|
||
<span id="cb39-24"><a href="#cb39-24" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb39-25"><a href="#cb39-25" aria-hidden="true" tabindex="-1"></a> DefaultRedisScript<span class="op"><</span><span class="bu">Long</span><span class="op">></span> redisScript <span class="op">=</span> <span class="kw">new</span> DefaultRedisScript<span class="op"><>(</span>script<span class="op">,</span> <span class="bu">Long</span><span class="op">.</span><span class="fu">class</span><span class="op">);</span></span>
|
||
<span id="cb39-26"><a href="#cb39-26" aria-hidden="true" tabindex="-1"></a> <span class="bu">Long</span> result <span class="op">=</span> redisTemplate<span class="op">.</span><span class="fu">execute</span><span class="op">(</span>redisScript<span class="op">,</span> </span>
|
||
<span id="cb39-27"><a href="#cb39-27" aria-hidden="true" tabindex="-1"></a> <span class="bu">Collections</span><span class="op">.</span><span class="fu">singletonList</span><span class="op">(</span>redisKey<span class="op">),</span> </span>
|
||
<span id="cb39-28"><a href="#cb39-28" aria-hidden="true" tabindex="-1"></a> <span class="bu">String</span><span class="op">.</span><span class="fu">valueOf</span><span class="op">(</span>window<span class="op">.</span><span class="fu">getSeconds</span><span class="op">()),</span></span>
|
||
<span id="cb39-29"><a href="#cb39-29" aria-hidden="true" tabindex="-1"></a> <span class="bu">String</span><span class="op">.</span><span class="fu">valueOf</span><span class="op">(</span>maxRequests<span class="op">));</span></span>
|
||
<span id="cb39-30"><a href="#cb39-30" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb39-31"><a href="#cb39-31" aria-hidden="true" tabindex="-1"></a> <span class="cf">return</span> result <span class="op">!=</span> <span class="kw">null</span> <span class="op">&&</span> result <span class="op">></span> <span class="dv">0</span><span class="op">;</span></span>
|
||
<span id="cb39-32"><a href="#cb39-32" aria-hidden="true" tabindex="-1"></a> <span class="op">}</span></span>
|
||
<span id="cb39-33"><a href="#cb39-33" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
|
||
<h3 data-number="1.6.4" id="错误处理机制"><span
|
||
class="header-section-number">1.6.4</span> 4.4 错误处理机制</h3>
|
||
<h4 data-number="1.6.4.1" id="统一异常处理"><span
|
||
class="header-section-number">1.6.4.1</span> 4.4.1 统一异常处理</h4>
|
||
<div class="sourceCode" id="cb40"><pre
|
||
class="sourceCode java"><code class="sourceCode java"><span id="cb40-1"><a href="#cb40-1" aria-hidden="true" tabindex="-1"></a><span class="at">@RestControllerAdvice</span></span>
|
||
<span id="cb40-2"><a href="#cb40-2" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> <span class="kw">class</span> GlobalExceptionHandler <span class="op">{</span></span>
|
||
<span id="cb40-3"><a href="#cb40-3" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb40-4"><a href="#cb40-4" aria-hidden="true" tabindex="-1"></a> <span class="at">@ExceptionHandler</span><span class="op">(</span>ServiceException<span class="op">.</span><span class="fu">class</span><span class="op">)</span></span>
|
||
<span id="cb40-5"><a href="#cb40-5" aria-hidden="true" tabindex="-1"></a> <span class="kw">public</span> CommonResult<span class="op"><?></span> <span class="fu">serviceExceptionHandler</span><span class="op">(</span>ServiceException ex<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb40-6"><a href="#cb40-6" aria-hidden="true" tabindex="-1"></a> log<span class="op">.</span><span class="fu">info</span><span class="op">(</span><span class="st">"[serviceExceptionHandler]"</span><span class="op">,</span> ex<span class="op">);</span></span>
|
||
<span id="cb40-7"><a href="#cb40-7" aria-hidden="true" tabindex="-1"></a> <span class="cf">return</span> CommonResult<span class="op">.</span><span class="fu">error</span><span class="op">(</span>ex<span class="op">.</span><span class="fu">getCode</span><span class="op">(),</span> ex<span class="op">.</span><span class="fu">getMessage</span><span class="op">());</span></span>
|
||
<span id="cb40-8"><a href="#cb40-8" aria-hidden="true" tabindex="-1"></a> <span class="op">}</span></span>
|
||
<span id="cb40-9"><a href="#cb40-9" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb40-10"><a href="#cb40-10" aria-hidden="true" tabindex="-1"></a> <span class="at">@ExceptionHandler</span><span class="op">(</span>ConstraintViolationException<span class="op">.</span><span class="fu">class</span><span class="op">)</span></span>
|
||
<span id="cb40-11"><a href="#cb40-11" aria-hidden="true" tabindex="-1"></a> <span class="kw">public</span> CommonResult<span class="op"><?></span> <span class="fu">constraintViolationExceptionHandler</span><span class="op">(</span>ConstraintViolationException ex<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb40-12"><a href="#cb40-12" aria-hidden="true" tabindex="-1"></a> log<span class="op">.</span><span class="fu">info</span><span class="op">(</span><span class="st">"[constraintViolationExceptionHandler]"</span><span class="op">,</span> ex<span class="op">);</span></span>
|
||
<span id="cb40-13"><a href="#cb40-13" aria-hidden="true" tabindex="-1"></a> <span class="cf">return</span> CommonResult<span class="op">.</span><span class="fu">error</span><span class="op">(</span>BAD_REQUEST<span class="op">.</span><span class="fu">getCode</span><span class="op">(),</span> <span class="st">"请求参数不正确:"</span> <span class="op">+</span> ex<span class="op">.</span><span class="fu">getMessage</span><span class="op">());</span></span>
|
||
<span id="cb40-14"><a href="#cb40-14" aria-hidden="true" tabindex="-1"></a> <span class="op">}</span></span>
|
||
<span id="cb40-15"><a href="#cb40-15" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb40-16"><a href="#cb40-16" aria-hidden="true" tabindex="-1"></a> <span class="at">@ExceptionHandler</span><span class="op">(</span>MethodArgumentNotValidException<span class="op">.</span><span class="fu">class</span><span class="op">)</span></span>
|
||
<span id="cb40-17"><a href="#cb40-17" aria-hidden="true" tabindex="-1"></a> <span class="kw">public</span> CommonResult<span class="op"><?></span> <span class="fu">methodArgumentNotValidExceptionHandler</span><span class="op">(</span>MethodArgumentNotValidException ex<span class="op">)</span> <span class="op">{</span></span>
|
||
<span id="cb40-18"><a href="#cb40-18" aria-hidden="true" tabindex="-1"></a> log<span class="op">.</span><span class="fu">info</span><span class="op">(</span><span class="st">"[methodArgumentNotValidExceptionHandler]"</span><span class="op">,</span> ex<span class="op">);</span></span>
|
||
<span id="cb40-19"><a href="#cb40-19" aria-hidden="true" tabindex="-1"></a> FieldError fieldError <span class="op">=</span> ex<span class="op">.</span><span class="fu">getBindingResult</span><span class="op">().</span><span class="fu">getFieldError</span><span class="op">();</span></span>
|
||
<span id="cb40-20"><a href="#cb40-20" aria-hidden="true" tabindex="-1"></a> <span class="cf">assert</span> fieldError <span class="op">!=</span> <span class="kw">null</span><span class="op">;</span></span>
|
||
<span id="cb40-21"><a href="#cb40-21" aria-hidden="true" tabindex="-1"></a> <span class="cf">return</span> CommonResult<span class="op">.</span><span class="fu">error</span><span class="op">(</span>BAD_REQUEST<span class="op">.</span><span class="fu">getCode</span><span class="op">(),</span> <span class="st">"请求参数不正确:"</span> <span class="op">+</span> fieldError<span class="op">.</span><span class="fu">getDefaultMessage</span><span class="op">());</span></span>
|
||
<span id="cb40-22"><a href="#cb40-22" aria-hidden="true" tabindex="-1"></a> <span class="op">}</span></span>
|
||
<span id="cb40-23"><a href="#cb40-23" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
|
||
<h4 data-number="1.6.4.2" id="错误码定义"><span
|
||
class="header-section-number">1.6.4.2</span> 4.4.2 错误码定义</h4>
|
||
<div class="sourceCode" id="cb41"><pre
|
||
class="sourceCode java"><code class="sourceCode java"><span id="cb41-1"><a href="#cb41-1" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> <span class="kw">interface</span> ErrorCodeConstants <span class="op">{</span></span>
|
||
<span id="cb41-2"><a href="#cb41-2" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb41-3"><a href="#cb41-3" aria-hidden="true" tabindex="-1"></a> <span class="co">// ========== 通用错误码 1-000-000-000 ==========</span></span>
|
||
<span id="cb41-4"><a href="#cb41-4" aria-hidden="true" tabindex="-1"></a> ErrorCode SUCCESS <span class="op">=</span> <span class="kw">new</span> <span class="fu">ErrorCode</span><span class="op">(</span><span class="dv">0</span><span class="op">,</span> <span class="st">"成功"</span><span class="op">);</span></span>
|
||
<span id="cb41-5"><a href="#cb41-5" aria-hidden="true" tabindex="-1"></a> ErrorCode BAD_REQUEST <span class="op">=</span> <span class="kw">new</span> <span class="fu">ErrorCode</span><span class="op">(</span><span class="dv">400</span><span class="op">,</span> <span class="st">"请求参数不正确"</span><span class="op">);</span></span>
|
||
<span id="cb41-6"><a href="#cb41-6" aria-hidden="true" tabindex="-1"></a> ErrorCode UNAUTHORIZED <span class="op">=</span> <span class="kw">new</span> <span class="fu">ErrorCode</span><span class="op">(</span><span class="dv">401</span><span class="op">,</span> <span class="st">"账号未登录"</span><span class="op">);</span></span>
|
||
<span id="cb41-7"><a href="#cb41-7" aria-hidden="true" tabindex="-1"></a> ErrorCode FORBIDDEN <span class="op">=</span> <span class="kw">new</span> <span class="fu">ErrorCode</span><span class="op">(</span><span class="dv">403</span><span class="op">,</span> <span class="st">"没有该操作权限"</span><span class="op">);</span></span>
|
||
<span id="cb41-8"><a href="#cb41-8" aria-hidden="true" tabindex="-1"></a> ErrorCode NOT_FOUND <span class="op">=</span> <span class="kw">new</span> <span class="fu">ErrorCode</span><span class="op">(</span><span class="dv">404</span><span class="op">,</span> <span class="st">"请求未找到"</span><span class="op">);</span></span>
|
||
<span id="cb41-9"><a href="#cb41-9" aria-hidden="true" tabindex="-1"></a> ErrorCode METHOD_NOT_ALLOWED <span class="op">=</span> <span class="kw">new</span> <span class="fu">ErrorCode</span><span class="op">(</span><span class="dv">405</span><span class="op">,</span> <span class="st">"请求方法不正确"</span><span class="op">);</span></span>
|
||
<span id="cb41-10"><a href="#cb41-10" aria-hidden="true" tabindex="-1"></a> ErrorCode INTERNAL_SERVER_ERROR <span class="op">=</span> <span class="kw">new</span> <span class="fu">ErrorCode</span><span class="op">(</span><span class="dv">500</span><span class="op">,</span> <span class="st">"系统异常"</span><span class="op">);</span></span>
|
||
<span id="cb41-11"><a href="#cb41-11" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb41-12"><a href="#cb41-12" aria-hidden="true" tabindex="-1"></a> <span class="co">// ========== 客户管理错误码 1-001-000-000 ==========</span></span>
|
||
<span id="cb41-13"><a href="#cb41-13" aria-hidden="true" tabindex="-1"></a> ErrorCode CUSTOMER_NOT_EXISTS <span class="op">=</span> <span class="kw">new</span> <span class="fu">ErrorCode</span><span class="op">(</span><span class="dv">1_001_000_001</span><span class="op">,</span> <span class="st">"客户不存在"</span><span class="op">);</span></span>
|
||
<span id="cb41-14"><a href="#cb41-14" aria-hidden="true" tabindex="-1"></a> ErrorCode CUSTOMER_CODE_DUPLICATE <span class="op">=</span> <span class="kw">new</span> <span class="fu">ErrorCode</span><span class="op">(</span><span class="dv">1_001_000_002</span><span class="op">,</span> <span class="st">"客户编号已存在"</span><span class="op">);</span></span>
|
||
<span id="cb41-15"><a href="#cb41-15" aria-hidden="true" tabindex="-1"></a> ErrorCode CUSTOMER_STATUS_INVALID <span class="op">=</span> <span class="kw">new</span> <span class="fu">ErrorCode</span><span class="op">(</span><span class="dv">1_001_000_003</span><span class="op">,</span> <span class="st">"客户状态不正确"</span><span class="op">);</span></span>
|
||
<span id="cb41-16"><a href="#cb41-16" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb41-17"><a href="#cb41-17" aria-hidden="true" tabindex="-1"></a> <span class="co">// ========== 水表管理错误码 1-002-000-000 ==========</span></span>
|
||
<span id="cb41-18"><a href="#cb41-18" aria-hidden="true" tabindex="-1"></a> ErrorCode METER_NOT_EXISTS <span class="op">=</span> <span class="kw">new</span> <span class="fu">ErrorCode</span><span class="op">(</span><span class="dv">1_002_000_001</span><span class="op">,</span> <span class="st">"水表不存在"</span><span class="op">);</span></span>
|
||
<span id="cb41-19"><a href="#cb41-19" aria-hidden="true" tabindex="-1"></a> ErrorCode METER_CODE_DUPLICATE <span class="op">=</span> <span class="kw">new</span> <span class="fu">ErrorCode</span><span class="op">(</span><span class="dv">1_002_000_002</span><span class="op">,</span> <span class="st">"水表编号已存在"</span><span class="op">);</span></span>
|
||
<span id="cb41-20"><a href="#cb41-20" aria-hidden="true" tabindex="-1"></a> ErrorCode METER_READING_INVALID <span class="op">=</span> <span class="kw">new</span> <span class="fu">ErrorCode</span><span class="op">(</span><span class="dv">1_002_000_003</span><span class="op">,</span> <span class="st">"水表读数不正确"</span><span class="op">);</span></span>
|
||
<span id="cb41-21"><a href="#cb41-21" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb41-22"><a href="#cb41-22" aria-hidden="true" tabindex="-1"></a> <span class="co">// ========== 账单管理错误码 1-003-000-000 ==========</span></span>
|
||
<span id="cb41-23"><a href="#cb41-23" aria-hidden="true" tabindex="-1"></a> ErrorCode BILL_NOT_EXISTS <span class="op">=</span> <span class="kw">new</span> <span class="fu">ErrorCode</span><span class="op">(</span><span class="dv">1_003_000_001</span><span class="op">,</span> <span class="st">"账单不存在"</span><span class="op">);</span></span>
|
||
<span id="cb41-24"><a href="#cb41-24" aria-hidden="true" tabindex="-1"></a> ErrorCode BILL_ALREADY_PAID <span class="op">=</span> <span class="kw">new</span> <span class="fu">ErrorCode</span><span class="op">(</span><span class="dv">1_003_000_002</span><span class="op">,</span> <span class="st">"账单已缴费"</span><span class="op">);</span></span>
|
||
<span id="cb41-25"><a href="#cb41-25" aria-hidden="true" tabindex="-1"></a> ErrorCode BILL_AMOUNT_INVALID <span class="op">=</span> <span class="kw">new</span> <span class="fu">ErrorCode</span><span class="op">(</span><span class="dv">1_003_000_003</span><span class="op">,</span> <span class="st">"账单金额不正确"</span><span class="op">);</span></span>
|
||
<span id="cb41-26"><a href="#cb41-26" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb41-27"><a href="#cb41-27" aria-hidden="true" tabindex="-1"></a> <span class="co">// ========== 缴费管理错误码 1-004-000-000 ==========</span></span>
|
||
<span id="cb41-28"><a href="#cb41-28" aria-hidden="true" tabindex="-1"></a> ErrorCode PAYMENT_FAILED <span class="op">=</span> <span class="kw">new</span> <span class="fu">ErrorCode</span><span class="op">(</span><span class="dv">1_004_000_001</span><span class="op">,</span> <span class="st">"缴费失败"</span><span class="op">);</span></span>
|
||
<span id="cb41-29"><a href="#cb41-29" aria-hidden="true" tabindex="-1"></a> ErrorCode PAYMENT_AMOUNT_INSUFFICIENT <span class="op">=</span> <span class="kw">new</span> <span class="fu">ErrorCode</span><span class="op">(</span><span class="dv">1_004_000_002</span><span class="op">,</span> <span class="st">"缴费金额不足"</span><span class="op">);</span></span>
|
||
<span id="cb41-30"><a href="#cb41-30" aria-hidden="true" tabindex="-1"></a> ErrorCode PAYMENT_CHANNEL_UNAVAILABLE <span class="op">=</span> <span class="kw">new</span> <span class="fu">ErrorCode</span><span class="op">(</span><span class="dv">1_004_000_003</span><span class="op">,</span> <span class="st">"缴费渠道不可用"</span><span class="op">);</span></span>
|
||
<span id="cb41-31"><a href="#cb41-31" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
|
||
<h4 data-number="1.6.4.3" id="接口调用示例"><span
|
||
class="header-section-number">1.6.4.3</span> 4.4.3 接口调用示例</h4>
|
||
<p><strong>成功响应示例</strong>:</p>
|
||
<div class="sourceCode" id="cb42"><pre
|
||
class="sourceCode json"><code class="sourceCode json"><span id="cb42-1"><a href="#cb42-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
|
||
<span id="cb42-2"><a href="#cb42-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">"code"</span><span class="fu">:</span> <span class="dv">0</span><span class="fu">,</span></span>
|
||
<span id="cb42-3"><a href="#cb42-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">"msg"</span><span class="fu">:</span> <span class="st">"操作成功"</span><span class="fu">,</span></span>
|
||
<span id="cb42-4"><a href="#cb42-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">"data"</span><span class="fu">:</span> <span class="fu">{</span></span>
|
||
<span id="cb42-5"><a href="#cb42-5" aria-hidden="true" tabindex="-1"></a> <span class="dt">"id"</span><span class="fu">:</span> <span class="dv">1</span><span class="fu">,</span></span>
|
||
<span id="cb42-6"><a href="#cb42-6" aria-hidden="true" tabindex="-1"></a> <span class="dt">"customerName"</span><span class="fu">:</span> <span class="st">"张三"</span></span>
|
||
<span id="cb42-7"><a href="#cb42-7" aria-hidden="true" tabindex="-1"></a> <span class="fu">}</span></span>
|
||
<span id="cb42-8"><a href="#cb42-8" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
|
||
<p><strong>失败响应示例</strong>:</p>
|
||
<div class="sourceCode" id="cb43"><pre
|
||
class="sourceCode json"><code class="sourceCode json"><span id="cb43-1"><a href="#cb43-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
|
||
<span id="cb43-2"><a href="#cb43-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">"code"</span><span class="fu">:</span> <span class="dv">1001000001</span><span class="fu">,</span></span>
|
||
<span id="cb43-3"><a href="#cb43-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">"msg"</span><span class="fu">:</span> <span class="st">"客户不存在"</span><span class="fu">,</span></span>
|
||
<span id="cb43-4"><a href="#cb43-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">"data"</span><span class="fu">:</span> <span class="kw">null</span></span>
|
||
<span id="cb43-5"><a href="#cb43-5" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
|
||
<h3 data-number="1.6.5" id="前端接口调用示例"><span
|
||
class="header-section-number">1.6.5</span> 4.5 前端接口调用示例</h3>
|
||
<h4 data-number="1.6.5.1" id="vue3-typescript接口封装"><span
|
||
class="header-section-number">1.6.5.1</span> 4.5.1 Vue3 +
|
||
TypeScript接口封装</h4>
|
||
<div class="sourceCode" id="cb44"><pre
|
||
class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb44-1"><a href="#cb44-1" aria-hidden="true" tabindex="-1"></a><span class="co">// api/water/customer.ts</span></span>
|
||
<span id="cb44-2"><a href="#cb44-2" aria-hidden="true" tabindex="-1"></a><span class="im">import</span> { request } <span class="im">from</span> <span class="st">'@/utils/request'</span></span>
|
||
<span id="cb44-3"><a href="#cb44-3" aria-hidden="true" tabindex="-1"></a></span>
|
||
<span id="cb44-4"><a href="#cb44-4" aria-hidden="true" tabindex="-1"></a><span class="im">export</span> <span class="kw">interface</span> CustomerVO {</span>
|
||
<span id="cb44-5"><a href="#cb44-5" aria-hidden="true" tabindex="-1"></a> id<span class="op">:</span> <span class="dt">number</span></span>
|
||
<span id="cb44-6"><a href="#cb44-6" aria-hidden="true" tabindex="-1"></a> customerCode<span class="op">:</span> <span class="dt">string</span></span>
|
||
<span id="cb44-7"><a href="#cb44-7" aria-hidden="true" tabindex="-1"></a> customerName<span class="op">:</span> <span class="dt">string</span></span>
|
||
<span id="cb44-8"><a href="#cb44-8" aria-hidden="true" tabindex="-1"></a> customerType<span class="op">:</span> <span class="dt">string</span></span>
|
||
<span id="cb44-9"><a href="#cb44-9" aria-hidden="true" tabindex="-1"></a> phone<span class="op">:</span> <span class="dt">string</span></span>
|
||
<span id="cb44-10"><a href="#cb44-10" aria-hidden="true" tabindex="-1"></a> address<span class="op">:</span> <span class="dt">string</span></span>
|
||
<span id="cb44-11"><a href="#cb44-11" aria-hidden="true" tabindex="-1"></a> status<span class="op">:</span> <span class="dt">number</span></span>
|
||
<span id="cb44-12"><a href="#cb44-12" aria-hidden="true" tabindex="-1"></a> createTime<span class="op">:</span> <span class="dt">string</span></span>
|
||
<span id="cb44-13"><a href="#cb44-13" aria-hidden="true" tabindex="-1"></a>}</span>
|
||
<span id="cb44-14"><a href="#cb44-14" aria-hidden="true" tabindex="-1"></a></span>
|
||
<span id="cb44-15"><a href="#cb44-15" aria-hidden="true" tabindex="-1"></a><span class="im">export</span> <span class="kw">interface</span> CustomerPageReqVO <span class="kw">extends</span> PageParam {</span>
|
||
<span id="cb44-16"><a href="#cb44-16" aria-hidden="true" tabindex="-1"></a> customerName<span class="op">?:</span> <span class="dt">string</span></span>
|
||
<span id="cb44-17"><a href="#cb44-17" aria-hidden="true" tabindex="-1"></a> customerCode<span class="op">?:</span> <span class="dt">string</span></span>
|
||
<span id="cb44-18"><a href="#cb44-18" aria-hidden="true" tabindex="-1"></a> customerType<span class="op">?:</span> <span class="dt">string</span></span>
|
||
<span id="cb44-19"><a href="#cb44-19" aria-hidden="true" tabindex="-1"></a> phone<span class="op">?:</span> <span class="dt">string</span></span>
|
||
<span id="cb44-20"><a href="#cb44-20" aria-hidden="true" tabindex="-1"></a>}</span>
|
||
<span id="cb44-21"><a href="#cb44-21" aria-hidden="true" tabindex="-1"></a></span>
|
||
<span id="cb44-22"><a href="#cb44-22" aria-hidden="true" tabindex="-1"></a><span class="im">export</span> <span class="kw">const</span> CustomerApi <span class="op">=</span> {</span>
|
||
<span id="cb44-23"><a href="#cb44-23" aria-hidden="true" tabindex="-1"></a> <span class="co">// 获取客户分页</span></span>
|
||
<span id="cb44-24"><a href="#cb44-24" aria-hidden="true" tabindex="-1"></a> getCustomerPage<span class="op">:</span> (params<span class="op">:</span> CustomerPageReqVO) <span class="kw">=></span> {</span>
|
||
<span id="cb44-25"><a href="#cb44-25" aria-hidden="true" tabindex="-1"></a> <span class="cf">return</span> request<span class="op">.</span><span class="fu">get</span><span class="op"><</span>PageResult<span class="op"><</span>CustomerVO<span class="op">>></span>({ url<span class="op">:</span> <span class="st">'/water/customer/page'</span><span class="op">,</span> params })</span>
|
||
<span id="cb44-26"><a href="#cb44-26" aria-hidden="true" tabindex="-1"></a> }<span class="op">,</span></span>
|
||
<span id="cb44-27"><a href="#cb44-27" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb44-28"><a href="#cb44-28" aria-hidden="true" tabindex="-1"></a> <span class="co">// 获取客户详情</span></span>
|
||
<span id="cb44-29"><a href="#cb44-29" aria-hidden="true" tabindex="-1"></a> getCustomer<span class="op">:</span> (id<span class="op">:</span> <span class="dt">number</span>) <span class="kw">=></span> {</span>
|
||
<span id="cb44-30"><a href="#cb44-30" aria-hidden="true" tabindex="-1"></a> <span class="cf">return</span> request<span class="op">.</span><span class="fu">get</span><span class="op"><</span>CustomerVO<span class="op">></span>({ url<span class="op">:</span> <span class="vs">`/water/customer/</span><span class="sc">${</span>id<span class="sc">}</span><span class="vs">`</span> })</span>
|
||
<span id="cb44-31"><a href="#cb44-31" aria-hidden="true" tabindex="-1"></a> }<span class="op">,</span></span>
|
||
<span id="cb44-32"><a href="#cb44-32" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb44-33"><a href="#cb44-33" aria-hidden="true" tabindex="-1"></a> <span class="co">// 创建客户</span></span>
|
||
<span id="cb44-34"><a href="#cb44-34" aria-hidden="true" tabindex="-1"></a> createCustomer<span class="op">:</span> (data<span class="op">:</span> CustomerSaveReqVO) <span class="kw">=></span> {</span>
|
||
<span id="cb44-35"><a href="#cb44-35" aria-hidden="true" tabindex="-1"></a> <span class="cf">return</span> request<span class="op">.</span><span class="fu">post</span><span class="op"><</span><span class="dt">number</span><span class="op">></span>({ url<span class="op">:</span> <span class="st">'/water/customer/create'</span><span class="op">,</span> data })</span>
|
||
<span id="cb44-36"><a href="#cb44-36" aria-hidden="true" tabindex="-1"></a> }<span class="op">,</span></span>
|
||
<span id="cb44-37"><a href="#cb44-37" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb44-38"><a href="#cb44-38" aria-hidden="true" tabindex="-1"></a> <span class="co">// 更新客户</span></span>
|
||
<span id="cb44-39"><a href="#cb44-39" aria-hidden="true" tabindex="-1"></a> updateCustomer<span class="op">:</span> (data<span class="op">:</span> CustomerSaveReqVO) <span class="kw">=></span> {</span>
|
||
<span id="cb44-40"><a href="#cb44-40" aria-hidden="true" tabindex="-1"></a> <span class="cf">return</span> request<span class="op">.</span><span class="fu">put</span><span class="op"><</span><span class="dt">void</span><span class="op">></span>({ url<span class="op">:</span> <span class="st">'/water/customer/update'</span><span class="op">,</span> data })</span>
|
||
<span id="cb44-41"><a href="#cb44-41" aria-hidden="true" tabindex="-1"></a> }<span class="op">,</span></span>
|
||
<span id="cb44-42"><a href="#cb44-42" aria-hidden="true" tabindex="-1"></a> </span>
|
||
<span id="cb44-43"><a href="#cb44-43" aria-hidden="true" tabindex="-1"></a> <span class="co">// 删除客户</span></span>
|
||
<span id="cb44-44"><a href="#cb44-44" aria-hidden="true" tabindex="-1"></a> deleteCustomer<span class="op">:</span> (id<span class="op">:</span> <span class="dt">number</span>) <span class="kw">=></span> {</span>
|
||
<span id="cb44-45"><a href="#cb44-45" aria-hidden="true" tabindex="-1"></a> <span class="cf">return</span> request<span class="op">.</span><span class="fu">delete</span><span class="op"><</span><span class="dt">void</span><span class="op">></span>({ url<span class="op">:</span> <span class="vs">`/water/customer/delete?id=</span><span class="sc">${</span>id<span class="sc">}</span><span class="vs">`</span> })</span>
|
||
<span id="cb44-46"><a href="#cb44-46" aria-hidden="true" tabindex="-1"></a> }</span>
|
||
<span id="cb44-47"><a href="#cb44-47" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
|
||
<h4 data-number="1.6.5.2" id="vue组件使用示例"><span
|
||
class="header-section-number">1.6.5.2</span> 4.5.2 Vue组件使用示例</h4>
|
||
```vue
|
||
<script setup lang="ts">
|
||
import { ref, onMounted } from 'vue'
|
||
import { CustomerApi, CustomerVO } from '@/api/water/customer'
|
||
import { formatDate } from '@/utils/formatTime'
|
||
|
||
const customerList = ref<CustomerVO[]>([])
|
||
const loading = ref(true)
|
||
const total = ref(0)
|
||
const queryParams = ref({
|
||
pageNo: 1,
|
||
pageSize: 10,
|
||
customerName: '',
|
||
customerCode: ''
|
||
})
|
||
|
||
const getCustomerList = async () => {
|
||
loading.value = true
|
||
try {
|
||
const data = await CustomerApi.getCustomerPage(queryParams.value)
|
||
customerList.value = data.list
|
||
total.value = data.total
|
||
} catch (error) {
|
||
console.error('获取客户列表失败:', error)
|
||
} finally {
|
||
loading.value = false
|
||
}
|
||
}
|
||
|
||
const handleQuery = () => {
|
||
queryParams.value.pageNo = 1
|
||
getCustomerList()
|
||
}
|
||
|
||
const handleReset = () => {
|
||
queryParams.value = {
|
||
pageNo: 1,
|
||
pageSize: 10,
|
||
customerName: '',
|
||
customerCode: ''
|
||
}
|
||
getCustomerList()
|
||
}
|
||
|
||
onMounted(() => {
|
||
getCustomerList()
|
||
})
|
||
</script>
|
||
<template>
|
||
<div class="app-container">
|
||
<pre><code><!-- 查询表单 -->
|
||
<el-form :model="queryParams" ref="queryFormRef" inline>
|
||
<el-form-item label="客户名称" prop="customerName">
|
||
<el-input v-model="queryParams.customerName" placeholder="请输入客户名称" />
|
||
</el-form-item>
|
||
<el-form-item label="客户编号" prop="customerCode">
|
||
<el-input v-model="queryParams.customerCode" placeholder="请输入客户编号" />
|
||
</el-form-item>
|
||
<el-form-item>
|
||
<el-button type="primary" @click="handleQuery">搜索</el-button>
|
||
<el-button @click="handleReset">重置</el-button>
|
||
</el-form-item>
|
||
</el-form>
|
||
|
||
<!-- 数据表格 -->
|
||
<el-table v-loading="loading" :data="customerList">
|
||
<el-table-column label="客户编号" prop="customerCode" />
|
||
<el-table-column label="客户名称" prop="customerName" />
|
||
<el-table-column label="联系电话" prop="phone" />
|
||
<el-table-column label="创建时间" prop="createTime" :formatter="formatDate" />
|
||
</el-table>
|
||
|
||
<!-- 分页组件 -->
|
||
<Pagination
|
||
:total="total"
|
||
v-model:page="queryParams.pageNo"
|
||
v-model:limit="queryParams.pageSize"
|
||
@pagination="getCustomerList"
|
||
/></code></pre>
|
||
</div>
|
||
<p></template></p>
|
||
</body>
|
||
</html>
|