车辆维保记录查询(备份)
<h3>接入说明</h3>
<ul>
<li>接入商先调用请求接口,报告生成之后,聚美智数通过接入商提供的接收报告接口,将报告推送给接入商</li>
</ul>
<h3>请求接口说明</h3>
<h4>请求地址</h4>
<p><code>https://api.jumdata.com/vehicle/maintenance</code></p>
<h4>请求方式</h4>
<ul>
<li>POST</li>
</ul>
<h4>请求格式</h4>
<ul>
<li>application/x-www-form-urlencoded</li>
</ul>
<h4>请求参数</h4>
<table>
<thead>
<tr>
<th>名称</th>
<th>类型</th>
<th>是否必填</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>appId</td>
<td>String</td>
<td>是</td>
<td>服务商分配的唯一标识</td>
</tr>
<tr>
<td>timestamp</td>
<td>Long</td>
<td>是</td>
<td>当前时间的毫秒数</td>
</tr>
<tr>
<td>sign</td>
<td>String</td>
<td>是</td>
<td>签名,详见签名算法说明</td>
</tr>
<tr>
<td>vin</td>
<td>String</td>
<td>是</td>
<td>车架号</td>
</tr>
<tr>
<td>licenseImgUrl</td>
<td>String</td>
<td>否</td>
<td>行驶证图片地址</td>
</tr>
<tr>
<td>registerImgUrl</td>
<td>String</td>
<td>否</td>
<td>⻋辆登记证照⽚URL地址</td>
</tr>
<tr>
<td>engineNo</td>
<td>String</td>
<td>否</td>
<td>发动机号</td>
</tr>
<tr>
<td>licensePlate</td>
<td>String</td>
<td>否</td>
<td>车牌号</td>
</tr>
<tr>
<td>plateType</td>
<td>String</td>
<td>否</td>
<td>车辆类型</td>
</tr>
<tr>
<td>notifyUrl</td>
<td>String</td>
<td>是</td>
<td>接收报告通知地址</td>
</tr>
</tbody>
</table>
<h4>签名算法</h4>
<pre><code>sign = sha256(appId + appSecret + timestamp)</code></pre>
<p>用服务商分配的 <strong>appId</strong>、服务商分配的 <strong>appSecret</strong>,当前时间毫秒数 <strong>timestamp</strong>,按上述顺序拼接成字符串,再进行 <strong>sha256</strong> 哈希得到。如下:</p>
<pre><code class="language-java">String appId = "xyzxy2121zxyz";
String timestamp = "1555378976238";
String appSecret = "efcefcef1121cefcefc1212121";
String str = appId + appSecret + timestamp;
String sign = sha256(str);</code></pre>
<h4>正确返回</h4>
<pre><code class="language-json">{
"code": 202, // 详见code返回码说明
"msg": "报告正在生成中",
"taskNo": "12113389406452748034", // 本次请求号
"charge": true // 计费标志
}</code></pre>
<h4>错误返回</h4>
<pre><code class="language-json">{
"code": 400,
"msg": "通知地址格式不正确",
}</code></pre>
<h4>code返回码说明</h4>
<table>
<thead>
<tr>
<th>code</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>200</td>
<td>成功(计费)</td>
</tr>
<tr>
<td>201</td>
<td>查无数据</td>
</tr>
<tr>
<td>202</td>
<td>报告正在生成中(计费)</td>
</tr>
<tr>
<td>203</td>
<td>品牌不⽀持/品牌维护中</td>
</tr>
<tr>
<td>400</td>
<td>参数错误</td>
</tr>
<tr>
<td>404</td>
<td>请求地址不正确</td>
</tr>
<tr>
<td>500</td>
<td>服务商维护,请稍候再试</td>
</tr>
<tr>
<td>601</td>
<td>接口未开通</td>
</tr>
<tr>
<td>602</td>
<td>账号停用</td>
</tr>
<tr>
<td>603</td>
<td>余额不足请充值</td>
</tr>
<tr>
<td>604</td>
<td>接口停用</td>
</tr>
<tr>
<td>606</td>
<td>调用超限,请稍候再试</td>
</tr>
<tr>
<td>607</td>
<td>ip不在白名单</td>
</tr>
<tr>
<td>609</td>
<td>请求过于频繁,请稍候再试</td>
</tr>
<tr>
<td>610</td>
<td>请求超时</td>
</tr>
<tr>
<td>999</td>
<td>其他,以实际返回为准</td>
</tr>
</tbody>
</table>
<h3>报告通知说明</h3>
<ul>
<li>报告生成之后,聚美智数将报告推送至接入商提供地址为<strong>notifyUrl</strong>的接口</li>
</ul>
<h4>请求方式</h4>
<ul>
<li>POST</li>
</ul>
<h4>请求格式</h4>
<ul>
<li>application/json</li>
</ul>
<h4>签名验证</h4>
<p>为了防止推动过程中数据被篡改,聚美智数将推送数据进行签名,将签名和数据一并推送,具体步骤如下:</p>
<p>1、在推送数据前拼接appSecret和timestamp,对拼接后的数据做SHA256哈希,得到sign,格式如下:</p>
<pre><code class="language-java">sign = sha256(appSecret + timestamp + 推送数据)</code></pre>
<p>例如:
appSecret:312aadadas3123ddadas
timestamp: 345432434343
推送数据: {"taskNo": "12123123123", ...}
则拼接后数据为:312aadadas3123ddadas345432434343 {"taskNo": "12123123123", ...}
再将拼接后的数据进行SHA256哈希,得到sign:trtret31212aa2312312dadas3123ddadas</p>
<p>2、sign和timestamp放置在请求header中推送至接入商,headerName为:sign、timestamp
3、接入商接收到推送数据后,根据步骤1生成sign,与header中的sign进行比较是否一致,一致说明数据没有被篡改</p>
<h4>返回接收结果</h4>
<p>接入商需要返回接收处理结果返回给聚美智数,格式如下:</p>
<pre><code class="language-json">{
"success": true,
"msg": "" // 失败时返回msg,成功时无需返回
}</code></pre>
<p>如果是接收失败,聚美智能会再次推送,最多推送5次</p>
<h4>接收示例(java)</h4>
<pre><code class="language-java">@PostMapping("notify")
public Map<String,Object> receive(@RequestBody String data, HttpServletRequest request) {
log.info("接收到聚美智数机动车维修保养推送数据: {}", data);
String signInHeader = request.getHeader("sign");
String timestamp = request.getHeader("timestamp");
String signText = appSecret + timestamp + data;
String sign = DigestUtils.sha256Hex(signText);
log.info("sign: {}", sign);
log.info("signInHeader: {}", signInHeader);
Map<String,Object> map = new HashMap<>();
if (StringUtils.equals(sign, signInHeader)) {
// 处理自己的业务逻辑
...
if (处理成功) {
map.put("success",true);
} else {
map.put("success",false);
map.put("msg","接收失败, xxx");
}
} else {
map.put("success",false);
map.put("msg","接收失败,签名不正确");
}
return map;
}</code></pre>
<h4>数据结构</h4>
<pre><code class="language-json">{
"taskNo": "09522434433117405247",
"code": 200, // 详见code返回码说明
"data": {
"records": [ // 维修保养记录
{
"last_time": "2016-05-01",
"repair_type": "定期维护",
"vin": "LSVWL2188F2190755",
"mileage": "9636",
"details": [
{
"type": "工时",
"content": "建议每公里(更换发动机机油和滤清器)"
},
{
"type": "工时",
"content": "月末活动漆30%折扣"
},
{
"type": "工时",
"content": "活动免费提供玻璃水"
},
{
"type": "工时",
"content": "右前门抛光"
},
{
"type": "工时",
"content": "右后门喷漆费用自理"
},
{
"type": "工时",
"content": "右后车门金属板"
}
],
"materials": [
{
"type": "正常",
"content": "机油滤清器(新桑)同A:1.00"
},
{
"type": "正常",
"content": "消音件(朗前):1.00"
},
{
"type": "正常",
"content": "车窗用清洁浓缩剂:1.00"
},
{
"type": "正常",
"content": "优选机油:1.00"
},
{
"type": "正常",
"content": "油底壳螺丝:1.00"
},
{
"type": "正常",
"content": "发动机润滑系统清洗养护套餐:1.00"
}
]
},
...
],
"report": { // 报告
"air_bag_safety_belt": false,
"air_bag_safety_belt_details": {
"center_seat_belt": false,
"seat_belt": false,
"driver_seat_belt": false,
"rear_seat_belt": false,
"airbag_abnormal": false
},
"air_conditioning_system": false,
"appliances_and_controller": false,
"brake_system": true,
"bumper": false,
"bumper_details": {
"bumper": false,
"rear_bumper": false,
"front_bumper": false
},
"car_body": false,
"car_door": false,
"car_door_details": {
"front_shell_left": false,
"front_shell": false,
"left_door_casing": false,
"back_shell_right": false,
"back_shell_left": false,
"right_door_casing": false,
"door_shell": false,
"back_shell": false,
"front_shell_right": false
},
"car_roof": false,
"car_roof_details": {
"skylight_assembly": false,
"roof_plate": false,
"car_roof_beam_left": false,
"roof_cross_beam": false,
"skylight_frame": false,
"car_roof_beam_right": false,
"car_roof_beam": false
},
"car_shell": false,
"chassis": false,
"chassis_details": {
"trunk_floor": false,
"front_floor_right": false,
"front_longeron_right": false,
"bottom_edge_left": false,
"bottom_edge": false,
"back_longeron": false,
"longeron": false,
"front_rail_cover_plate_left": false,
"front_floor_left": false,
"back_longeron_left": false,
"front_longeron_head_right": false,
"front_longeron_left": false,
"back_longeron_head_right": false,
"back_longeron_head_left": false,
"front_rail_cover_plate": false,
"front_longeron": false,
"front_longeron_head": false,
"back_longeron_head": false,
"back_longeron_right": false,
"bottom_edge_right": false,
"floor_girder": false,
"front_longeron_head_left": false,
"floor": false,
"front_rail_cover_plate_right": false
},
"drive_system": false,
"engine_abnormal": false,
"engine_support": false,
"exhaust_system": false,
"front_rear_axle": true,
"front_rear_axle_details": {
"front_axle": false,
"rear_axle": true
},
"spray_paint": false,
"steering_system": false,
"structure_abnormal": false,
"structure_abnormal_details": {
"door_check": false,
"b_pillar_right": false,
"side_panel_assembly": false,
"d_pillar": false,
"c_pillar": false,
"b_pillar": false,
"c_pillar_right": false,
"a_pillar_left": false,
"a_pillar_right": false,
"a_pillar": false,
"b_pillar_left": false,
"c_pillar_left": false,
"side_panel_assembly_left": false,
"side_panel_assembly_right": false,
"d_pillar_right": false,
"d_pillar_left": false
},
"suspension_system": false,
"transmission": false,
"transmission_support": false,
"wheel_fender": false,
"wheel_fender_details": {
"front_fender": false,
"right_front_fender": false,
"rear_fender": false,
"left_front_fender": false,
"right_fender": false,
"left_fender": false
},
"burned": false,
"flooded": false,
"recall": false,
"total_loss": false
}
}
}</code></pre>