|
@@ -0,0 +1,400 @@
|
|
|
+package com.rf.psychological.douyin.service.impl;
|
|
|
+
|
|
|
+import cn.hutool.core.date.DateUtil;
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import com.rf.psychological.douyin.config.DouYinConfig;
|
|
|
+import com.rf.psychological.douyin.model.DouYinOrderEntity;
|
|
|
+import com.rf.psychological.douyin.service.DouYinOrderService;
|
|
|
+import com.rf.psychological.douyin.service.DouYinService;
|
|
|
+import com.rf.psychological.douyin.util.SignUtil;
|
|
|
+import com.rf.psychological.enums.OrderStatus;
|
|
|
+import com.rf.psychological.enums.UserRole;
|
|
|
+import com.rf.psychological.group.service.GroupInfoService;
|
|
|
+import com.rf.psychological.user.dao.model.UserEntity;
|
|
|
+import com.rf.psychological.user.service.UserService;
|
|
|
+import com.rf.psychological.utils.Constant;
|
|
|
+import com.rf.psychological.utils.JWTUtil;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.apache.commons.collections4.CollectionUtils;
|
|
|
+import org.apache.commons.lang.StringUtils;
|
|
|
+import org.apache.http.client.methods.CloseableHttpResponse;
|
|
|
+import org.apache.http.client.methods.HttpPost;
|
|
|
+import org.apache.http.entity.StringEntity;
|
|
|
+import org.apache.http.impl.client.CloseableHttpClient;
|
|
|
+import org.apache.http.impl.client.HttpClients;
|
|
|
+import org.apache.http.util.EntityUtils;
|
|
|
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+
|
|
|
+import javax.annotation.Resource;
|
|
|
+import java.io.ByteArrayOutputStream;
|
|
|
+import java.io.InputStream;
|
|
|
+import java.util.*;
|
|
|
+
|
|
|
+
|
|
|
+ * @Description:
|
|
|
+ * @Author: mimang
|
|
|
+ * @Date: 2023/8/15
|
|
|
+ */
|
|
|
+@Slf4j
|
|
|
+@Service
|
|
|
+@ConditionalOnProperty(prefix="douyin",name = "isDouYin", havingValue = "true")
|
|
|
+public class DouYinServiceImpl implements DouYinService {
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private DouYinConfig douYinConfig;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private UserService userService;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private GroupInfoService groupInfoService;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private DouYinOrderService orderInfoService;
|
|
|
+
|
|
|
+
|
|
|
+ * 获取到openid
|
|
|
+ * @param code login 接口返回的登录凭证
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public String jscode2session(String code) throws Exception {
|
|
|
+ String url = douYinConfig.getSessionUrl();
|
|
|
+
|
|
|
+ Map<String,Object> paramsMap = new HashMap<>();
|
|
|
+ paramsMap.put("code",code);
|
|
|
+ paramsMap.put("appid",douYinConfig.getAppid());
|
|
|
+ paramsMap.put("secret",douYinConfig.getSecret());
|
|
|
+ JSONObject data = generateReq(url,paramsMap,"err_no").getObject("data",JSONObject.class);
|
|
|
+ return data.getString("openid");
|
|
|
+ }
|
|
|
+
|
|
|
+ private JSONObject generateReq(String url,Map<String, Object> params,String errCode) throws Exception{
|
|
|
+
|
|
|
+ CloseableHttpClient client = HttpClients.createDefault();
|
|
|
+ HttpPost httpPost = new HttpPost(url);
|
|
|
+ httpPost.setHeader("Accept", "application/json");
|
|
|
+ String jsonParams = JSONObject.toJSONString(params);
|
|
|
+ StringEntity entity = new StringEntity(jsonParams,"utf-8");
|
|
|
+ entity.setContentType("application/json");
|
|
|
+ httpPost.setEntity(entity);
|
|
|
+ httpPost.setHeader("Accept","application/json");
|
|
|
+
|
|
|
+ CloseableHttpResponse response = client.execute(httpPost);
|
|
|
+ JSONObject bodyJson =JSONObject.parseObject( EntityUtils.toString(response.getEntity()));
|
|
|
+ int errNo = bodyJson.getInteger(errCode);
|
|
|
+ if (errNo != 0){
|
|
|
+ throw new Exception(errNo+"---------"+bodyJson.toString());
|
|
|
+ }
|
|
|
+ log.info(url+"------------"+bodyJson.toString());
|
|
|
+ return bodyJson;
|
|
|
+ }
|
|
|
+
|
|
|
+ private InputStream generateCode(String url, Map<String, Object> params) throws Exception{
|
|
|
+
|
|
|
+ CloseableHttpClient client = HttpClients.createDefault();
|
|
|
+ HttpPost httpPost = new HttpPost(url);
|
|
|
+ httpPost.setHeader("Accept", "application/json");
|
|
|
+ String jsonParams = JSONObject.toJSONString(params);
|
|
|
+ StringEntity entity = new StringEntity(jsonParams,"utf-8");
|
|
|
+ entity.setContentType("application/json");
|
|
|
+ httpPost.setEntity(entity);
|
|
|
+ httpPost.setHeader("Accept","application/json");
|
|
|
+
|
|
|
+ CloseableHttpResponse response = client.execute(httpPost);
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ return response.getEntity().getContent();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public JSONObject douyinLogin(String openid, JSONObject resultJson) {
|
|
|
+ UserEntity userEntity = this.userService.findPhoneAndInstitutionNoAndRoleType(openid, Constant.WEB_INSTITUTION_CODE, UserRole.COMMON.getType());
|
|
|
+ if(userEntity != null){
|
|
|
+ userEntity.setPassword("-");
|
|
|
+ resultJson.put("user", userEntity);
|
|
|
+ resultJson.put("type", userEntity.getRoleType());
|
|
|
+ resultJson.put("improve",false);
|
|
|
+ }else{
|
|
|
+
|
|
|
+ userEntity = new UserEntity();
|
|
|
+ userEntity.setPassword("-");
|
|
|
+ userEntity.setGId(this.groupInfoService.findGroupByInstitutionNoAndName(Constant.WEB_INSTITUTION_CODE,Constant.DEFAULT_GROUP_NAME).getId());
|
|
|
+ userEntity.setInstitutionName(Constant.WEB_INSTITUTION_NAME);
|
|
|
+ userEntity.setInstitutionNo(Constant.WEB_INSTITUTION_CODE);
|
|
|
+ userEntity.setUserStatus(Constant.USER_STATUS_NORMAL);
|
|
|
+ userEntity.setBirthday("-");
|
|
|
+ userEntity.setGender("-");
|
|
|
+ userEntity.setPetName("抖音用户");
|
|
|
+ userEntity.setProfession("-");
|
|
|
+ userEntity.setAdditionInfo("抖音小程序注册用户");
|
|
|
+ userEntity.setPhone(openid);
|
|
|
+ userEntity.setRoleType(UserRole.COMMON.getType());
|
|
|
+ userEntity = this.userService.save(userEntity);
|
|
|
+ resultJson.put("improve",true);
|
|
|
+ }
|
|
|
+
|
|
|
+ resultJson.put("token", JWTUtil.getTokenByUserInfo(userEntity));
|
|
|
+ resultJson.put("user",userEntity);
|
|
|
+ resultJson.put("type",userEntity.getRoleType());
|
|
|
+ return resultJson;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ * 获取accessToken
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public String getAccessToken() throws Exception {
|
|
|
+ String url = douYinConfig.getTokenUrl();
|
|
|
+ Map<String,Object> paramsMap = new HashMap<>();
|
|
|
+ paramsMap.put("appid",douYinConfig.getAppid());
|
|
|
+ paramsMap.put("secret",douYinConfig.getSecret());
|
|
|
+ paramsMap.put("grant_type","client_credential");
|
|
|
+ JSONObject data = generateReq(url,paramsMap,"err_no").getObject("data",JSONObject.class);
|
|
|
+ return data.getString("access_token");
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String getRQCode(String appname, String path) throws Exception {
|
|
|
+ String url = douYinConfig.getCodeUrl();
|
|
|
+ String token = this.getAccessToken();
|
|
|
+ Map<String,Object> paramsMap = new HashMap<>();
|
|
|
+ paramsMap.put("access_token",token);
|
|
|
+ paramsMap.put("appname",appname);
|
|
|
+ paramsMap.put("path",path);
|
|
|
+ InputStream inputStream = this.generateCode(url,paramsMap);
|
|
|
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|
|
+ byte[] buffer = new byte[1024];
|
|
|
+ int len = -1;
|
|
|
+ while ((len = inputStream.read(buffer)) != -1) {
|
|
|
+ baos.write(buffer, 0, len);
|
|
|
+ }
|
|
|
+ return Base64.getEncoder().encodeToString(baos.toByteArray());
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ * 预下单
|
|
|
+ * @param totalAmount 金额
|
|
|
+ * @param subject 主题
|
|
|
+ * @param body 介绍
|
|
|
+ * @param resultId 结果Id
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public Map<String, Object> createOrder(int totalAmount, String subject, String body, String resultId, String path) throws Exception {
|
|
|
+ Map<String, Object> map = new HashMap<>();
|
|
|
+
|
|
|
+ DouYinOrderEntity orderInfo = orderInfoService.findByResultIdAndStatus(resultId, OrderStatus.PROCESSING.name());
|
|
|
+ if (orderInfo != null) {
|
|
|
+ if (StringUtils.isNotEmpty(orderInfo.getOrderId())) {
|
|
|
+ map.put("orderId", orderInfo.getOrderId());
|
|
|
+ map.put("orderToken", orderInfo.getOrderToken());
|
|
|
+ map.put("orderNo", orderInfo.getOutOrderNo());
|
|
|
+ return map;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+
|
|
|
+ orderInfo = orderInfoService.createNewOrder(totalAmount, subject, body, resultId);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ Map<String, Object> paramMap = new HashMap<>();
|
|
|
+ paramMap.put("app_id", douYinConfig.getAppid());
|
|
|
+ paramMap.put("out_order_no", orderInfo.getOutOrderNo());
|
|
|
+ paramMap.put("total_amount", totalAmount);
|
|
|
+ paramMap.put("subject", subject);
|
|
|
+ paramMap.put("body", body);
|
|
|
+ paramMap.put("valid_time", 900);
|
|
|
+ paramMap.put("notify_url", douYinConfig.getNotifyUrl());
|
|
|
+ if (StringUtils.isNotEmpty(path)) {
|
|
|
+ paramMap.put("msg_page", path);
|
|
|
+ }
|
|
|
+ paramMap.put("sign", SignUtil.requestSign(paramMap));
|
|
|
+ JSONObject jsonObject = null;
|
|
|
+ try {
|
|
|
+ jsonObject = this.generateReq(douYinConfig.getCreateOrderUrl(), paramMap,"err_no").getObject("data", JSONObject.class);
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error(e.getMessage());
|
|
|
+ e.printStackTrace();
|
|
|
+ orderInfoService.deleteByNo(orderInfo.getOutOrderNo());
|
|
|
+ return map;
|
|
|
+ }
|
|
|
+
|
|
|
+ orderInfo.setOrderId(jsonObject.getString("order_id"));
|
|
|
+ orderInfo.setOrderToken(jsonObject.getString("order_token"));
|
|
|
+ orderInfoService.updateOrder(orderInfo);
|
|
|
+ map.put("orderId", jsonObject.getString("order_id"));
|
|
|
+ map.put("orderToken", jsonObject.getString("order_token"));
|
|
|
+ map.put("orderNo", orderInfo.getOutOrderNo());
|
|
|
+ return map;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Map<String, Object> queryOrder(String orderNo) throws Exception {
|
|
|
+
|
|
|
+ Map<String,Object> resultMap = new HashMap();
|
|
|
+
|
|
|
+ DouYinOrderEntity order = orderInfoService.findByOutOrderNo(orderNo);
|
|
|
+ if (order==null){
|
|
|
+ throw new Exception("订单号不存在");
|
|
|
+ }
|
|
|
+ if (OrderStatus.SUCCESS.equals(order.getOrderStatus())){
|
|
|
+ resultMap.put("statusCode",order.getOrderStatus());
|
|
|
+ return resultMap;
|
|
|
+ }
|
|
|
+
|
|
|
+ JSONObject resultJson = this.queryOrderByOutOrderNo(orderNo);
|
|
|
+ String status = resultJson.getString("order_status");
|
|
|
+ order.setOrderStatus(status);
|
|
|
+ orderInfoService.updateOrder(order);
|
|
|
+ resultMap.put("statusCode",status);
|
|
|
+ return resultMap;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ private JSONObject queryOrderByOutOrderNo(String order) throws Exception {
|
|
|
+ Map<String,Object> paramMap = new HashMap<>();
|
|
|
+ paramMap.put("app_id",douYinConfig.getAppid());
|
|
|
+ paramMap.put("out_order_no",order);
|
|
|
+ paramMap.put("sign",SignUtil.requestSign(paramMap));
|
|
|
+ JSONObject result = this.generateReq(douYinConfig.getQueryOrderUrl(), paramMap,"err_no").getObject("payment_info",JSONObject.class);
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ * 检测订单状态,是否超时
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public void checkOrderStatus() {
|
|
|
+ List<DouYinOrderEntity> list = orderInfoService.findAllByStatus(OrderStatus.PROCESSING);
|
|
|
+ if (CollectionUtils.isEmpty(list)){
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ list.forEach(item->{
|
|
|
+
|
|
|
+ JSONObject resultJson = null;
|
|
|
+ try {
|
|
|
+ resultJson = this.queryOrderByOutOrderNo(item.getOutOrderNo());
|
|
|
+ String status = resultJson.getString("order_status");
|
|
|
+ item.setOrderStatus(status);
|
|
|
+ orderInfoService.updateOrder(item);
|
|
|
+ } catch (Exception e) {
|
|
|
+
|
|
|
+ log.error(e.getMessage());
|
|
|
+ String msg = e.getMessage();
|
|
|
+ if (msg.contains("2000")){
|
|
|
+ orderInfoService.deleteByNo(item.getOutOrderNo());
|
|
|
+ }
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ * 回调信息处理
|
|
|
+ * @param msgJson 信息
|
|
|
+ * @param resultCode 返回code
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public JSONObject notifyOrder(JSONObject jsonObject, JSONObject msgJson, String resultCode) {
|
|
|
+ JSONObject resultJson = new JSONObject();
|
|
|
+
|
|
|
+ String outTradeNo = msgJson.getString("cp_orderno");
|
|
|
+ DouYinOrderEntity entity = orderInfoService.findByOutOrderNo(outTradeNo);
|
|
|
+ if ("payment".equalsIgnoreCase(resultCode)) {
|
|
|
+ List<String> sortedString = new ArrayList<>();
|
|
|
+
|
|
|
+ sortedString.add(SignUtil.TOKEN);
|
|
|
+
|
|
|
+ sortedString.add(jsonObject.getString("timestamp"));
|
|
|
+
|
|
|
+ sortedString.add(jsonObject.getString("nonce"));
|
|
|
+
|
|
|
+ sortedString.add(jsonObject.getString("msg"));
|
|
|
+ Collections.sort(sortedString);
|
|
|
+
|
|
|
+
|
|
|
+ String msg_signature = jsonObject.getString("msg_signature");
|
|
|
+ String sign = SignUtil.callbackSign(sortedString);
|
|
|
+ log.info("支付回调接口密钥签名:{}",sign);
|
|
|
+ if(!sign.equals(msg_signature)) {
|
|
|
+ resultJson.put("err_no",8);
|
|
|
+ resultJson.put("err_tips","error");
|
|
|
+ entity.setOrderStatus(OrderStatus.SUCCESS.name());
|
|
|
+ }
|
|
|
+ resultJson.put("err_no",0);
|
|
|
+ resultJson.put("err_tips","success");
|
|
|
+ } else {
|
|
|
+ log.error("订单" + outTradeNo + "支付失败");
|
|
|
+ resultJson.put("err_no",0);
|
|
|
+ resultJson.put("err_tips","error");
|
|
|
+ entity.setOrderStatus(OrderStatus.FAIL.name());
|
|
|
+ }
|
|
|
+ orderInfoService.updateOrder(entity);
|
|
|
+ return resultJson;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public DouYinOrderEntity queryOrderByResultId(String resultId) {
|
|
|
+ return orderInfoService.findByResultIdAndStatus(resultId,OrderStatus.SUCCESS.name());
|
|
|
+ }
|
|
|
+
|
|
|
+ public JSONObject pushOrder(String orderNo,String resultId,String title,String openId,int totalAmount, String path,int orderStatus,String imgPath) throws Exception {
|
|
|
+ JSONObject jsonObject = null;
|
|
|
+ try {
|
|
|
+ List<Map<String,Object>> itemList = new ArrayList<>();
|
|
|
+ Map<String,Object> item = new HashMap<>();
|
|
|
+ item.put("item_code", resultId);
|
|
|
+ item.put("img", imgPath);
|
|
|
+ item.put("title", title);
|
|
|
+ item.put("amount", 1);
|
|
|
+ item.put("price", totalAmount);
|
|
|
+ itemList.add(item);
|
|
|
+
|
|
|
+
|
|
|
+ Map<String,Object> detailMap = new HashMap<>();
|
|
|
+ detailMap.put("order_id", orderNo);
|
|
|
+ detailMap.put("create_time", DateUtil.current());
|
|
|
+ switch (orderStatus){
|
|
|
+ case 0:
|
|
|
+ detailMap.put("status", "待支付");
|
|
|
+ case 1:
|
|
|
+ detailMap.put("status", "已支付");
|
|
|
+ case 2:
|
|
|
+ detailMap.put("status", "已取消");
|
|
|
+ }
|
|
|
+ detailMap.put("amount", 1);
|
|
|
+ detailMap.put("total_price", totalAmount);
|
|
|
+ detailMap.put("detail_url", path);
|
|
|
+ detailMap.put("item_list", itemList);
|
|
|
+
|
|
|
+ Map<String, Object> paramMap = new HashMap<>();
|
|
|
+ paramMap.put("access_token", getAccessToken());
|
|
|
+ paramMap.put("app_name", douYinConfig.getAppName());
|
|
|
+ paramMap.put("app_id", douYinConfig.getAppid());
|
|
|
+ paramMap.put("open_id", openId);
|
|
|
+ paramMap.put("order_detail", JSONObject.toJSONString(detailMap));
|
|
|
+ paramMap.put("order_status", orderStatus);
|
|
|
+ paramMap.put("order_type", 0);
|
|
|
+ paramMap.put("update_time", DateUtil.currentSeconds());
|
|
|
+ jsonObject = this.generateReq(douYinConfig.getPushOrderUrl(), paramMap,"err_code");
|
|
|
+ log.info(jsonObject.toJSONString());
|
|
|
+ }catch (Exception e){
|
|
|
+ e.printStackTrace();
|
|
|
+ log.error(e.getMessage());
|
|
|
+ throw e;
|
|
|
+ }
|
|
|
+ return jsonObject;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+}
|