Browse Source

富士接口

魏熙美 6 years ago
parent
commit
9a501b35a7

+ 268
- 0
CODE/smart-community/community-common/src/main/java/com/community/commom/fushi/Base64.java View File

@@ -0,0 +1,268 @@
1
+package com.community.commom.fushi;
2
+
3
+public final class Base64 {
4
+
5
+	private static final int BASELENGTH = 128;
6
+	private static final int LOOKUPLENGTH = 64;
7
+	private static final int TWENTYFOURBITGROUP = 24;
8
+	private static final int EIGHTBIT = 8;
9
+	private static final int SIXTEENBIT = 16;
10
+	private static final int FOURBYTE = 4;
11
+	private static final int SIGN = -128;
12
+	private static char PAD = '=';
13
+	private static byte[] base64Alphabet = new byte[BASELENGTH];
14
+	private static char[] lookUpBase64Alphabet = new char[LOOKUPLENGTH];
15
+
16
+	static {
17
+		for (int i = 0; i < BASELENGTH; ++i) {
18
+			base64Alphabet[i] = -1;
19
+		}
20
+		for (int i = 'Z'; i >= 'A'; i--) {
21
+			base64Alphabet[i] = (byte) (i - 'A');
22
+		}
23
+		for (int i = 'z'; i >= 'a'; i--) {
24
+			base64Alphabet[i] = (byte) (i - 'a' + 26);
25
+		}
26
+
27
+		for (int i = '9'; i >= '0'; i--) {
28
+			base64Alphabet[i] = (byte) (i - '0' + 52);
29
+		}
30
+
31
+		base64Alphabet['+'] = 62;
32
+		base64Alphabet['/'] = 63;
33
+
34
+		for (int i = 0; i <= 25; i++) {
35
+			lookUpBase64Alphabet[i] = (char) ('A' + i);
36
+		}
37
+
38
+		for (int i = 26, j = 0; i <= 51; i++, j++) {
39
+			lookUpBase64Alphabet[i] = (char) ('a' + j);
40
+		}
41
+
42
+		for (int i = 52, j = 0; i <= 61; i++, j++) {
43
+			lookUpBase64Alphabet[i] = (char) ('0' + j);
44
+		}
45
+		lookUpBase64Alphabet[62] = (char) '+';
46
+		lookUpBase64Alphabet[63] = (char) '/';
47
+
48
+	}
49
+
50
+	private static boolean isWhiteSpace(char octect) {
51
+		return (octect == 0x20 || octect == 0xd || octect == 0xa || octect == 0x9);
52
+	}
53
+
54
+	private static boolean isPad(char octect) {
55
+		return (octect == PAD);
56
+	}
57
+
58
+	private static boolean isData(char octect) {
59
+		return (octect < BASELENGTH && base64Alphabet[octect] != -1);
60
+	}
61
+
62
+	/**
63
+	 * Encodes hex octects into Base64
64
+	 * 
65
+	 * @param binaryData
66
+	 *            Array containing binaryData
67
+	 * @return Encoded Base64 array
68
+	 */
69
+	public static String encode(byte[] binaryData) {
70
+
71
+		if (binaryData == null) {
72
+			return null;
73
+		}
74
+
75
+		int lengthDataBits = binaryData.length * EIGHTBIT;
76
+		if (lengthDataBits == 0) {
77
+			return "";
78
+		}
79
+
80
+		int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP;
81
+		int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP;
82
+		int numberQuartet = fewerThan24bits != 0 ? numberTriplets + 1
83
+				: numberTriplets;
84
+		char encodedData[] = null;
85
+
86
+		encodedData = new char[numberQuartet * 4];
87
+
88
+		byte k = 0, l = 0, b1 = 0, b2 = 0, b3 = 0;
89
+
90
+		int encodedIndex = 0;
91
+		int dataIndex = 0;
92
+
93
+		for (int i = 0; i < numberTriplets; i++) {
94
+			b1 = binaryData[dataIndex++];
95
+			b2 = binaryData[dataIndex++];
96
+			b3 = binaryData[dataIndex++];
97
+
98
+			l = (byte) (b2 & 0x0f);
99
+			k = (byte) (b1 & 0x03);
100
+
101
+			byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2)
102
+					: (byte) ((b1) >> 2 ^ 0xc0);
103
+			byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4)
104
+					: (byte) ((b2) >> 4 ^ 0xf0);
105
+			byte val3 = ((b3 & SIGN) == 0) ? (byte) (b3 >> 6)
106
+					: (byte) ((b3) >> 6 ^ 0xfc);
107
+
108
+			encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
109
+			encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];
110
+			encodedData[encodedIndex++] = lookUpBase64Alphabet[(l << 2) | val3];
111
+			encodedData[encodedIndex++] = lookUpBase64Alphabet[b3 & 0x3f];
112
+		}
113
+
114
+		// form integral number of 6-bit groups
115
+		if (fewerThan24bits == EIGHTBIT) {
116
+			b1 = binaryData[dataIndex];
117
+			k = (byte) (b1 & 0x03);
118
+			
119
+			byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2)
120
+					: (byte) ((b1) >> 2 ^ 0xc0);
121
+			encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
122
+			encodedData[encodedIndex++] = lookUpBase64Alphabet[k << 4];
123
+			encodedData[encodedIndex++] = PAD;
124
+			encodedData[encodedIndex++] = PAD;
125
+		} else if (fewerThan24bits == SIXTEENBIT) {
126
+			b1 = binaryData[dataIndex];
127
+			b2 = binaryData[dataIndex + 1];
128
+			l = (byte) (b2 & 0x0f);
129
+			k = (byte) (b1 & 0x03);
130
+
131
+			byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2)
132
+					: (byte) ((b1) >> 2 ^ 0xc0);
133
+			byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4)
134
+					: (byte) ((b2) >> 4 ^ 0xf0);
135
+
136
+			encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
137
+			encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];
138
+			encodedData[encodedIndex++] = lookUpBase64Alphabet[l << 2];
139
+			encodedData[encodedIndex++] = PAD;
140
+		}
141
+
142
+		return new String(encodedData);
143
+	}
144
+
145
+	/**
146
+	 * Decodes Base64 data into octects
147
+	 * 
148
+	 * @param encoded
149
+	 *            string containing Base64 data
150
+	 * @return Array containind decoded data.
151
+	 */
152
+	public static byte[] decode(String encoded) {
153
+
154
+		if (encoded == null) {
155
+			return null;
156
+		}
157
+
158
+		char[] base64Data = encoded.toCharArray();
159
+		// remove white spaces
160
+		int len = removeWhiteSpace(base64Data);
161
+
162
+		if (len % FOURBYTE != 0) {
163
+			return null;// should be divisible by four
164
+		}
165
+
166
+		int numberQuadruple = (len / FOURBYTE);
167
+
168
+		if (numberQuadruple == 0) {
169
+			return new byte[0];
170
+		}
171
+
172
+		byte decodedData[] = null;
173
+		byte b1 = 0, b2 = 0, b3 = 0, b4 = 0;
174
+		char d1 = 0, d2 = 0, d3 = 0, d4 = 0;
175
+
176
+		int i = 0;
177
+		int encodedIndex = 0;
178
+		int dataIndex = 0;
179
+		decodedData = new byte[(numberQuadruple) * 3];
180
+
181
+		for (; i < numberQuadruple - 1; i++) {
182
+
183
+			if (!isData((d1 = base64Data[dataIndex++]))
184
+					|| !isData((d2 = base64Data[dataIndex++]))
185
+					|| !isData((d3 = base64Data[dataIndex++]))
186
+					|| !isData((d4 = base64Data[dataIndex++]))) {
187
+				return null;
188
+			}// if found "no data" just return null
189
+
190
+			b1 = base64Alphabet[d1];
191
+			b2 = base64Alphabet[d2];
192
+			b3 = base64Alphabet[d3];
193
+			b4 = base64Alphabet[d4];
194
+
195
+			decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
196
+			decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
197
+			decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);
198
+		}
199
+
200
+		if (!isData((d1 = base64Data[dataIndex++]))
201
+				|| !isData((d2 = base64Data[dataIndex++]))) {
202
+			return null;// if found "no data" just return null
203
+		}
204
+
205
+		b1 = base64Alphabet[d1];
206
+		b2 = base64Alphabet[d2];
207
+
208
+		d3 = base64Data[dataIndex++];
209
+		d4 = base64Data[dataIndex++];
210
+		if (!isData((d3)) || !isData((d4))) {// Check if they are PAD characters
211
+			if (isPad(d3) && isPad(d4)) {
212
+				if ((b2 & 0xf) != 0)// last 4 bits should be zero
213
+				{
214
+					return null;
215
+				}
216
+				byte[] tmp = new byte[i * 3 + 1];
217
+				System.arraycopy(decodedData, 0, tmp, 0, i * 3);
218
+				tmp[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
219
+				return tmp;
220
+			} else if (!isPad(d3) && isPad(d4)) {
221
+				b3 = base64Alphabet[d3];
222
+				if ((b3 & 0x3) != 0)// last 2 bits should be zero
223
+				{
224
+					return null;
225
+				}
226
+				byte[] tmp = new byte[i * 3 + 2];
227
+				System.arraycopy(decodedData, 0, tmp, 0, i * 3);
228
+				tmp[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
229
+				tmp[encodedIndex] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
230
+				return tmp;
231
+			} else {
232
+				return null;
233
+			}
234
+		} else { // No PAD e.g 3cQl
235
+			b3 = base64Alphabet[d3];
236
+			b4 = base64Alphabet[d4];
237
+			decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
238
+			decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
239
+			decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);
240
+
241
+		}
242
+
243
+		return decodedData;
244
+	}
245
+
246
+	/**
247
+	 * remove WhiteSpace from MIME containing encoded Base64 data.
248
+	 * 
249
+	 * @param data
250
+	 *            the byte array of base64 data (with WS)
251
+	 * @return the new length
252
+	 */
253
+	private static int removeWhiteSpace(char[] data) {
254
+		if (data == null) {
255
+			return 0;
256
+		}
257
+
258
+		// count characters that's not whitespace
259
+		int newSize = 0;
260
+		int len = data.length;
261
+		for (int i = 0; i < len; i++) {
262
+			if (!isWhiteSpace(data[i])) {
263
+				data[newSize++] = data[i];
264
+			}
265
+		}
266
+		return newSize;
267
+	}
268
+}

+ 191
- 0
CODE/smart-community/community-common/src/main/java/com/community/commom/fushi/FuShiHttpClient.java View File

@@ -0,0 +1,191 @@
1
+package com.community.commom.fushi;
2
+
3
+import java.io.BufferedReader;
4
+import java.io.IOException;
5
+import java.io.InputStreamReader;
6
+import java.io.OutputStream;
7
+import java.net.HttpURLConnection;
8
+import java.net.URL;
9
+import java.security.KeyFactory;
10
+import java.security.PrivateKey;
11
+import java.security.spec.PKCS8EncodedKeySpec;
12
+
13
+import java.util.Map;
14
+import java.util.SortedMap;
15
+import java.util.TreeMap;
16
+
17
+import lombok.AllArgsConstructor;
18
+import lombok.Data;
19
+import lombok.NoArgsConstructor;
20
+import org.omg.CORBA.Request;
21
+
22
+/**
23
+ * 富士HTTP请求
24
+ * @author weiximei
25
+ */
26
+@Data
27
+public class FuShiHttpClient {
28
+//	private static String url = "http://mops-test.fujica.com.cn:8021/Api/Park/GetParkInfoByCarNo";
29
+	private String url;
30
+	private String appid;
31
+	private String appSecret;
32
+	private String privateKey;
33
+//	private String sign = "";
34
+//	private String time;
35
+
36
+    public FuShiHttpClient(String url, String appid, String appSecret, String privateKey) {
37
+        this.url = url;
38
+        this.appid = appid;
39
+        this.appSecret = appSecret;
40
+        this.privateKey = privateKey;
41
+    }
42
+
43
+    public static void main(String[] args) {
44
+//		time = getTimestamp();
45
+//		String jsonString = "{'ParkingCode':'19000100250504','CarNo':'苏A8M6B2'}";
46
+//
47
+//		TreeMap<String, String> map = new TreeMap();
48
+//		map.put("param", jsonString);
49
+//		map.put("secret", appSecret);
50
+//		map.put("timestamp", time);
51
+//		sign = signWithoutMD5(map);
52
+//		sign = sign(sign, privateKey);
53
+//
54
+//		doJsonPost(url, jsonString);
55
+	}
56
+
57
+	/**
58
+	 * POST 请求
59
+	 * @param urlPath
60
+	 * @param Json
61
+	 * @return
62
+	 */
63
+	public String doJsonPost(String urlPath, String Json, String sign, String time) {
64
+		urlPath = url + urlPath;
65
+		String result = "";
66
+		BufferedReader reader = null;
67
+		try {
68
+			URL url = new URL(urlPath);
69
+			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
70
+			conn.setRequestMethod("POST");
71
+			conn.setDoOutput(true);
72
+			conn.setDoInput(true);
73
+			conn.setUseCaches(false);
74
+			conn.setRequestProperty("Connection", "Keep-Alive");
75
+			conn.setRequestProperty("Charset", "UTF-8");
76
+			conn.setRequestProperty("appid", appid);
77
+			conn.setRequestProperty("appSecret", appSecret);
78
+			conn.setRequestProperty("sign", sign);
79
+			conn.setRequestProperty("timestamp", time);
80
+			// 设置文件类型:
81
+			conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
82
+			// 设置接收类型否则返回415错误
83
+			conn.setRequestProperty("accept", "*/*");// 此处为暴力方法设置接受所有类型,以此来防范返回415;
84
+			conn.setRequestProperty("accept", "application/json");
85
+			// 往服务器里面发送数据
86
+			if (Json != null && !("").equals(Json)) {
87
+				byte[] writebytes = Json.getBytes();
88
+				// 设置文件长度
89
+				conn.setRequestProperty("Content-Length", String.valueOf(writebytes.length));
90
+				OutputStream outwritestream = (OutputStream) conn.getOutputStream();
91
+				outwritestream.write(Json.getBytes());
92
+				outwritestream.flush();
93
+				outwritestream.close();
94
+
95
+			}
96
+			if (conn.getResponseCode() == 200) {
97
+				reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
98
+				result = reader.readLine();
99
+				// System.out.println(result);
100
+			}
101
+		} catch (Exception e) {
102
+			e.printStackTrace();
103
+		} finally {
104
+			if (reader != null) {
105
+				try {
106
+					reader.close();
107
+				} catch (IOException e) {
108
+					e.printStackTrace();
109
+				}
110
+			}
111
+		}
112
+		return result;
113
+	}
114
+
115
+    /**
116
+     * 时间戳, 取前十位
117
+     * @return
118
+     */
119
+	public String getTimestamp() {
120
+		String time = "";
121
+		long timestamp = System.currentTimeMillis();
122
+		time = String.valueOf(timestamp);
123
+		time = time.substring(0, 10);
124
+		return time;
125
+	}
126
+
127
+    /**
128
+     * MD5
129
+     * @param params
130
+     * @return
131
+     */
132
+	public String signWithoutMD5(SortedMap<String, String> params) {
133
+		String restul = "";
134
+		if (params == null) {
135
+			return restul;
136
+		}
137
+
138
+		StringBuilder sb = new StringBuilder();
139
+		for (Map.Entry<String, String> me : params.entrySet()) {
140
+
141
+			sb.append(me.getKey());
142
+			sb.append('=');
143
+			sb.append(me.getValue());
144
+			sb.append('&');
145
+
146
+		}
147
+		int lastIndexOf = sb.lastIndexOf("&");
148
+		if (lastIndexOf != -1) {
149
+			sb.deleteCharAt(lastIndexOf);
150
+		}
151
+		restul = new String(sb);
152
+
153
+		return restul;
154
+	}
155
+
156
+	private final String ALGORITHM = "RSA";
157
+	private final String SIGN_ALGORITHMS = "SHA1WithRSA";
158
+
159
+	private final String DEFAULT_CHARSET = "UTF-8";
160
+
161
+    /**
162
+     * 开始签名
163
+     * @param content
164
+     * @param privateKey
165
+     * @return
166
+     */
167
+	public String sign(String content, String privateKey) {
168
+		try {
169
+			PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64.decode(privateKey));
170
+			KeyFactory keyf = KeyFactory.getInstance(ALGORITHM);
171
+
172
+			PrivateKey priKey = keyf.generatePrivate(priPKCS8);
173
+
174
+			java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);
175
+
176
+			signature.initSign(priKey);
177
+			signature.update(content.getBytes(DEFAULT_CHARSET));
178
+
179
+			byte[] signed = signature.sign();
180
+
181
+			return Base64.encode(signed);
182
+		} catch (Exception e) {
183
+			e.printStackTrace();
184
+		}
185
+
186
+		return null;
187
+	}
188
+
189
+
190
+
191
+}

+ 128
- 0
CODE/smart-community/community-common/src/main/java/com/community/commom/fushi/FuShiRequestAPI.java View File

@@ -0,0 +1,128 @@
1
+package com.community.commom.fushi;
2
+
3
+import com.alibaba.fastjson.JSONObject;
4
+import com.community.commom.fushi.error.FuShiException;
5
+import com.google.common.collect.Maps;
6
+import lombok.AllArgsConstructor;
7
+import lombok.Data;
8
+import lombok.extern.slf4j.Slf4j;
9
+
10
+import java.util.Map;
11
+import java.util.TreeMap;
12
+
13
+/**
14
+ * 富士请求 API
15
+ * @author weiximei
16
+ */
17
+@Data
18
+@Slf4j
19
+public class FuShiRequestAPI {
20
+
21
+    private FuShiHttpClient client;
22
+
23
+    public FuShiRequestAPI(FuShiHttpClient client) {
24
+        this.client = client;
25
+    }
26
+
27
+    public FuShiRequestAPI() {
28
+    }
29
+
30
+    // =======================   请求 API   =====================================
31
+
32
+    @Data
33
+    @AllArgsConstructor
34
+    public class SignBuild {
35
+        private String sign;
36
+        private String timestamp;
37
+    }
38
+
39
+    /**
40
+     * 请求签名
41
+     * @param jsonString
42
+     * @return
43
+     */
44
+    private SignBuild requestSign(String jsonString) {
45
+        String sign = "";
46
+        String timestamp = client.getTimestamp();
47
+        TreeMap<String, String> map = new TreeMap();
48
+		map.put("param", jsonString);
49
+		map.put("secret", client.getAppSecret());
50
+		map.put("timestamp", timestamp);
51
+		sign = client.signWithoutMD5(map);
52
+		sign = client.sign(sign, client.getPrivateKey());
53
+
54
+		return new SignBuild(sign, timestamp);
55
+    }
56
+
57
+    /**
58
+     * 校验code
59
+     * @param jsonString
60
+     */
61
+    private void showException(String jsonString) {
62
+        JSONObject jsonObject = JSONObject.parseObject(jsonString);
63
+        Integer messageCode = jsonObject.getInteger("MessageCode");
64
+        if (messageCode != 200) {
65
+            throw new FuShiException("设备还未联网,系统维护中");
66
+        }
67
+
68
+    }
69
+
70
+    /**
71
+     * 获取停车信息(通过车牌号)
72
+     * @return
73
+     */
74
+    public String getParkInfoByCarNo(String parkingCode, String carNo) {
75
+        Map<String, Object> map = Maps.newHashMap();
76
+        map.put("ParkingCode", parkingCode);
77
+        map.put("CarNo", carNo);
78
+        String json = JSONObject.toJSONString(map);
79
+        log.info("获取停车信息(通过车牌号)请求参数:{}", json);
80
+        SignBuild signBuild = requestSign(json);
81
+        String result = client.doJsonPost(FushiConstant.PARK_GETPARKINFOBYCARNO, json, signBuild.getSign(), signBuild.getTimestamp());
82
+        showException(result);
83
+        log.info("获取停车信息(通过车牌号)返回数据:{}", result);
84
+        return result;
85
+    }
86
+
87
+
88
+    /**
89
+     * 第三方月卡上发续费
90
+     * @param renewDayType 续费日期类型: 3:年; 2:月; 1:日;
91
+     * @param renewDay 续费日期数目
92
+     * @param dealNo 交易编码
93
+     * @param payStyle 交易方式(汉字描述),例如:微信、支付宝、银联
94
+     * @param carNo 车牌号
95
+     * @param cardNo 停车卡号
96
+     * @param parkingCode 停车场编码
97
+     * @param rechargeAmt 充值续费金额
98
+     * @param thirdTransactionDate 第三方交易日期
99
+     * @return
100
+     */
101
+    public String apiThirdPartyMonthCardPay(String renewDayType, String renewDay, String dealNo, String payStyle, String carNo, String parkingCode, String cardNo, String rechargeAmt, String thirdTransactionDate) {
102
+        Map<String, Object> map = Maps.newHashMap();
103
+        map.put("RenewDayType", parkingCode);
104
+        map.put("RenewDay", renewDay);
105
+        map.put("DealNo", dealNo);
106
+        map.put("PayStyle", payStyle);
107
+        map.put("CarNo", carNo);
108
+        map.put("ParkingCode", parkingCode);
109
+        map.put("CardNo", cardNo);
110
+        map.put("RechargeAmt", rechargeAmt);
111
+        map.put("ThirdTransactionDate", thirdTransactionDate);
112
+
113
+        String json = JSONObject.toJSONString(map);
114
+        log.info("第三方月卡上发续费请求参数:{}", json);
115
+        SignBuild signBuild = requestSign(json);
116
+        String result = client.doJsonPost(FushiConstant.CALCULATIONCOST_APITHIRDPARTYMONTHCARDPAY, json, signBuild.getSign(), signBuild.getTimestamp());
117
+        showException(result);
118
+        log.info("第三方月卡上发续费返回数据:{}", result);
119
+        return result;
120
+    }
121
+
122
+
123
+
124
+
125
+
126
+
127
+
128
+}

+ 19
- 0
CODE/smart-community/community-common/src/main/java/com/community/commom/fushi/FushiConstant.java View File

@@ -0,0 +1,19 @@
1
+package com.community.commom.fushi;
2
+
3
+/**
4
+ * 富士 API 链接定义
5
+ * @author weiximei
6
+ */
7
+public class FushiConstant {
8
+
9
+    /**
10
+     * 获取停车信息(通过车牌号)
11
+     */
12
+    public static final String PARK_GETPARKINFOBYCARNO = "/Park/GetParkInfoByCarNo";
13
+
14
+    /**
15
+     * 第三方月卡上发续费
16
+     */
17
+    public static final String CALCULATIONCOST_APITHIRDPARTYMONTHCARDPAY = "/CalculationCost/ApiThirdPartyMonthCardPay";
18
+
19
+}

+ 20
- 0
CODE/smart-community/community-common/src/main/java/com/community/commom/fushi/error/FuShiException.java View File

@@ -0,0 +1,20 @@
1
+package com.community.commom.fushi.error;
2
+
3
+/**
4
+ * 富士 业务专用异常
5
+ * @author weiximei
6
+ */
7
+public class FuShiException extends RuntimeException {
8
+
9
+    public FuShiException(String msg, Throwable t) {
10
+        super(msg, t);
11
+    }
12
+
13
+    public FuShiException(String msg) {
14
+        super(msg);
15
+    }
16
+
17
+    public FuShiException(String msg, Object ...args) {
18
+        this(String.format(msg, args));
19
+    }
20
+}

+ 44
- 0
CODE/smart-community/property-api/src/main/java/com/community/huiju/common/perproties/FuShiProperties.java View File

@@ -0,0 +1,44 @@
1
+package com.community.huiju.common.perproties;
2
+
3
+import lombok.AllArgsConstructor;
4
+import lombok.Data;
5
+import lombok.NoArgsConstructor;
6
+import org.springframework.boot.context.properties.ConfigurationProperties;
7
+import org.springframework.stereotype.Component;
8
+
9
+/**
10
+ * 富士配置类
11
+ * @author weiximei
12
+ */
13
+@AllArgsConstructor
14
+@NoArgsConstructor
15
+@Data
16
+@Component
17
+@ConfigurationProperties(prefix = "fu-shi")
18
+public class FuShiProperties {
19
+
20
+    /**
21
+     * 富士云 请求地址
22
+     */
23
+    private String url;
24
+
25
+    /**
26
+     * 富士云 appid
27
+     */
28
+    private String appid;
29
+
30
+    /**
31
+     * 富士云 appSecret
32
+     */
33
+    private String appSecret;
34
+
35
+    /**
36
+     * 富士云 私钥 privateKey
37
+     */
38
+    private String privateKey;
39
+
40
+    /**
41
+     * 停车场编码
42
+     */
43
+    private String parkingCode;
44
+}

+ 40
- 0
CODE/smart-community/property-api/src/main/java/com/community/huiju/config/FuShiConfig.java View File

@@ -0,0 +1,40 @@
1
+package com.community.huiju.config;
2
+
3
+import com.community.commom.fushi.FuShiHttpClient;
4
+import com.community.commom.fushi.FuShiRequestAPI;
5
+import com.community.huiju.common.perproties.FuShiProperties;
6
+import org.springframework.beans.factory.annotation.Autowired;
7
+import org.springframework.context.annotation.Bean;
8
+import org.springframework.context.annotation.Configuration;
9
+
10
+/**
11
+ * 富士配置类
12
+ * @author weiximei
13
+ */
14
+@Configuration
15
+public class FuShiConfig {
16
+
17
+    @Autowired
18
+    private FuShiProperties fuShiProperties;
19
+
20
+
21
+    /**
22
+     * 初始化富士HTTP客户端
23
+     * @return FuShiHttpClient
24
+     */
25
+    @Bean
26
+    public FuShiHttpClient fuShiHttpClient() {
27
+        return new FuShiHttpClient(fuShiProperties.getUrl(), fuShiProperties.getAppid(), fuShiProperties.getAppSecret(), fuShiProperties.getPrivateKey());
28
+    }
29
+
30
+    /**
31
+     * 初始化富士请求 API
32
+     * @param fuShiHttpClient
33
+     * @return
34
+     */
35
+    @Bean
36
+    public FuShiRequestAPI fuShiRequestAPI(FuShiHttpClient fuShiHttpClient) {
37
+        return new FuShiRequestAPI(fuShiHttpClient);
38
+    }
39
+
40
+}

+ 38
- 0
CODE/smart-community/property-api/src/main/java/com/community/huiju/controller/FSController.java View File

@@ -0,0 +1,38 @@
1
+package com.community.huiju.controller;
2
+
3
+import com.community.commom.mode.ResponseBean;
4
+import com.community.huiju.common.base.BaseController;
5
+import com.community.huiju.service.IFuShiService;
6
+import io.swagger.annotations.Api;
7
+import io.swagger.annotations.ApiImplicitParam;
8
+import io.swagger.annotations.ApiImplicitParams;
9
+import io.swagger.annotations.ApiOperation;
10
+import org.springframework.beans.factory.annotation.Autowired;
11
+import org.springframework.cloud.context.config.annotation.RefreshScope;
12
+import org.springframework.web.bind.annotation.PathVariable;
13
+import org.springframework.web.bind.annotation.RequestMapping;
14
+import org.springframework.web.bind.annotation.RequestMethod;
15
+import org.springframework.web.bind.annotation.RestController;
16
+
17
+@RestController
18
+@RefreshScope
19
+@RequestMapping("/")
20
+@Api(value = "车辆操作API", description = "车辆操作API")
21
+public class FSController extends BaseController {
22
+
23
+    @Autowired
24
+    private IFuShiService iFuShiService;
25
+
26
+    @RequestMapping(value = "/car/getParkInfoByCarNo/{carNo}", method = RequestMethod.GET)
27
+    @ApiOperation(value = "获取停车信息(通过车牌号)", notes = "获取停车信息(通过车牌号)")
28
+    @ApiImplicitParams({
29
+            @ApiImplicitParam(dataTypeClass = String.class, paramType = "path", name = "carNo", value = "车牌号")
30
+    })
31
+    public ResponseBean getParkInfoByCarNo(@PathVariable("carNo") String carNo) {
32
+        ResponseBean responseBean = new ResponseBean();
33
+        responseBean = iFuShiService.getParkInfoByCarNo(carNo);
34
+        return responseBean;
35
+    }
36
+
37
+
38
+}

+ 9
- 1
CODE/smart-community/property-api/src/main/java/com/community/huiju/exception/ExceptionHandleAdice.java View File

@@ -1,6 +1,7 @@
1 1
 package com.community.huiju.exception;
2 2
 
3 3
 import com.community.commom.constant.Constant;
4
+import com.community.commom.fushi.error.FuShiException;
4 5
 import com.community.commom.mode.ResponseBean;
5 6
 import lombok.extern.slf4j.Slf4j;
6 7
 import org.springframework.validation.ObjectError;
@@ -25,7 +26,7 @@ public class ExceptionHandleAdice {
25 26
     public ResponseBean handleException(Exception e){
26 27
         log.error(e.getMessage(),e);
27 28
         ResponseBean response = new ResponseBean();
28
-        response.addError(Constant.REQUEST_ERROR,"系统异常,请稍后重试!");
29
+        response.addError(Constant.REQUEST_ERROR,"设备还未联网,系统维护中");
29 30
         return response;
30 31
     }
31 32
 
@@ -54,5 +55,12 @@ public class ExceptionHandleAdice {
54 55
         return response;
55 56
     }
56 57
 
58
+    @ExceptionHandler(FuShiException.class)
59
+    public ResponseBean handleException(FuShiException e) {
60
+        log.error(e.getMessage(),e);
61
+        ResponseBean response = new ResponseBean();
62
+        response.addError(e.getMessage());
63
+        return response;
64
+    }
57 65
 
58 66
 }

+ 30
- 0
CODE/smart-community/property-api/src/main/java/com/community/huiju/service/IFuShiService.java View File

@@ -0,0 +1,30 @@
1
+package com.community.huiju.service;
2
+
3
+import com.community.commom.mode.ResponseBean;
4
+
5
+/**
6
+ * 富士 业务接口
7
+ */
8
+public interface IFuShiService {
9
+
10
+    /**
11
+     * 获取停车信息(通过车牌号)
12
+     *
13
+     * @param carNo
14
+     * @return
15
+     */
16
+    ResponseBean getParkInfoByCarNo(String carNo);
17
+
18
+    /**
19
+     * 第三方月卡上发续费
20
+     * @param renewDayType 续费日期类型: 3:年; 2:月; 1:日;
21
+     * @param renewDay 续费日期数目
22
+     * @param payStyle 交易方式,例如:1 微信、 2 支付宝、 3 银联
23
+     * @param carNo 车牌号
24
+     * @param cardNo 停车卡号
25
+     * @param rechargeAmt 充值续费金额
26
+     * @return
27
+     */
28
+    ResponseBean apiThirdPartyMonthCardPay(String renewDayType, String renewDay, String payStyle, String carNo, String cardNo,String rechargeAmt);
29
+
30
+}

+ 73
- 0
CODE/smart-community/property-api/src/main/java/com/community/huiju/service/impl/FuShiServiceImpl.java View File

@@ -0,0 +1,73 @@
1
+package com.community.huiju.service.impl;
2
+
3
+import com.alibaba.fastjson.JSONObject;
4
+import com.community.commom.fushi.FuShiRequestAPI;
5
+import com.community.commom.mode.ResponseBean;
6
+import com.community.commom.uuid.IdGen;
7
+import com.community.huiju.common.perproties.FuShiProperties;
8
+import com.community.huiju.service.IFuShiService;
9
+import com.google.common.collect.Maps;
10
+import lombok.extern.slf4j.Slf4j;
11
+import org.springframework.beans.factory.annotation.Autowired;
12
+import org.springframework.stereotype.Service;
13
+
14
+import java.time.LocalDateTime;
15
+import java.time.format.DateTimeFormatter;
16
+import java.util.Map;
17
+
18
+/**
19
+ * 富士业务实现
20
+ * @author weiximei
21
+ */
22
+@Slf4j
23
+@Service
24
+public class FuShiServiceImpl implements IFuShiService {
25
+
26
+    @Autowired
27
+    private FuShiRequestAPI fuShiRequestAPI;
28
+
29
+    @Autowired
30
+    private FuShiProperties fuShiProperties;
31
+
32
+    private IdGen idGen = IdGen.get();
33
+
34
+    /**
35
+     * 获取 富士 json 值
36
+     * @param jsonString
37
+     * @return
38
+     */
39
+    private Map<String,Object> getFuShiInfo(String jsonString) {
40
+        JSONObject jsonObject = JSONObject.parseObject(jsonString);
41
+        Map<String, Object> map = Maps.newHashMap();
42
+        map.put("JsonParam", jsonObject.getJSONObject("JsonParam").getInnerMap());
43
+        map.put("Redirect", jsonObject.getString("Redirect"));
44
+        map.put("DataType", jsonObject.getInteger("DataType"));
45
+        return map;
46
+    }
47
+
48
+    @Override
49
+    public ResponseBean getParkInfoByCarNo(String carNo) {
50
+        ResponseBean responseBean = new ResponseBean();
51
+        String parkInfo = fuShiRequestAPI.getParkInfoByCarNo(fuShiProperties.getParkingCode(), carNo);
52
+        Map<String, Object> fuShiInfo = getFuShiInfo(parkInfo);
53
+        responseBean.addSuccess(fuShiInfo);
54
+        return responseBean;
55
+    }
56
+
57
+    @Override
58
+    public ResponseBean apiThirdPartyMonthCardPay(String renewDayType, String renewDay, String payStyle, String carNo, String cardNo,String rechargeAmt) {
59
+        ResponseBean responseBean = new ResponseBean();
60
+        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
61
+        // 交易编码
62
+        String dealNo = idGen.nextId() + "";
63
+        // 第三方交易日期
64
+        String dateTime = dateTimeFormatter.format(LocalDateTime.now());
65
+        // 富士云请求
66
+        String partyMonthCardPay = fuShiRequestAPI.apiThirdPartyMonthCardPay(renewDayType, renewDay, dealNo, payStyle, carNo, fuShiProperties.getParkingCode(), cardNo, rechargeAmt, dateTime);
67
+        String tradeNo = JSONObject.parseObject(partyMonthCardPay).getString("TradeNo");
68
+        Map<String, Object> map = Maps.newHashMap();
69
+        map.put("TradeNo", tradeNo);
70
+        responseBean.addSuccess(map);
71
+        return responseBean;
72
+    }
73
+}

+ 25
- 1
CODE/smart-community/property-api/src/main/resources/application.yml View File

@@ -14,4 +14,28 @@ mybatis-plus:
14 14
 
15 15
 # 二维码生成地址
16 16
 qr-code:
17
-  url: http://106.14.20.193:8011/#/forum/sign?id=
17
+  url: http://106.14.20.193:8011/#/forum/sign?id=
18
+
19
+# 富士E7+云平台
20
+fu-shi:
21
+  url: http://api.mops.fujica.com.cn/v2/Api
22
+  appid: fujica_a354fedcb214c86b
23
+  app-secret: 0a0897e0bf154169833f709d6693fe84
24
+  private-key: MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAL8wJdXId6Pa6l/O
25
+    d6a+vE0z0RgujUTR2KxRZiRhEWpc4JSi1uyQPS2RS+CleByllAXkgPYCxhxelt6Y
26
+    wtFb3nuUVrQboesUrxv7DuGoRnbOeakMC2Cb83AanQlEC/erXspsTx9x9lecygAt
27
+    yOsEPv6nb8VHu8tTEEhFJIyWSTQBAgMBAAECgYA07AH9HGGptKZd4MwUFwYOpMJD
28
+    XFd0blX41QteFJR6ib0Mx8qQbxjQLUEArS0DWP4RZ4AfGQN3xOMkOMrsou6BcVjR
29
+    oVXvlKate4tIRQy3ay77dabM8LQFNg8uuigD7EWeGh9s4V1E5Jfuw8Y8zfmBKBbz
30
+    Id/Mm7bafgbfd4jCtQJBAPn0ik8Iv3pkJ90V60eQG4l6sVGAaskM0GWzyENpecLP
31
+    6UA7oYmAaqIx9vsY0UyiF4XctgxpMvqG6pM/U0y8LacCQQDDz8h7nhUWF0ZUH1IS
32
+    H+Qj3sUWR3hHel/WCjGPPKWO5iQUTfwVY9+L54IDIanAjisc40ueO3zK573zzlBE
33
+    /VYXAkEA61Qmm356+DovpeErILc2ldsj8r3ay+r6kaYQGBfIAXhJ/KWn0pNK0eYE
34
+    yCd3dpTtXKSN6WVqD6DSXUuzm31X5QJAEDMqlP+ZIwC98su8kH9O8qDFkXhMPS2k
35
+    rCKfwwfzcoUbywpApsxifEKlAPlR//pDGtq7MNYfFvJhRsB056BF9QJBAKHlCCnt
36
+    gtzRlhQxwYRg0th4uoJ99BT03+WM94Kepu6zfh3OmKLvPk2gW30TKSeYC5xmursq
37
+    xGP2TC4KxH2tAn0=
38
+  parking-code: 19000100250504 # 停车场编码
39
+
40
+
41
+