diff --git a/talkonlineweb/pom.xml b/talkonlineweb/pom.xml index 8feaaf1..d88c825 100644 --- a/talkonlineweb/pom.xml +++ b/talkonlineweb/pom.xml @@ -63,8 +63,16 @@ druid-spring-boot-starter 1.1.22 - - + + commons-httpclient + commons-httpclient + 3.1 + + + org.apache.httpcomponents + httpclient + 4.5.2 + org.springframework.boot spring-boot-devtools diff --git a/talkonlineweb/src/main/java/com/lyms/talkonlineweb/TalkonlinewebApplication.java b/talkonlineweb/src/main/java/com/lyms/talkonlineweb/TalkonlinewebApplication.java index c322f34..ecc4fdf 100644 --- a/talkonlineweb/src/main/java/com/lyms/talkonlineweb/TalkonlinewebApplication.java +++ b/talkonlineweb/src/main/java/com/lyms/talkonlineweb/TalkonlinewebApplication.java @@ -4,8 +4,10 @@ import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.transaction.annotation.EnableTransactionManagement; @SpringBootApplication +@EnableTransactionManagement @MapperScan("com.lyms.talkonlineweb.mapper") @EnableScheduling public class TalkonlinewebApplication { diff --git a/talkonlineweb/src/main/java/com/lyms/talkonlineweb/aop/ResubmitDataAspect.java b/talkonlineweb/src/main/java/com/lyms/talkonlineweb/aop/ResubmitDataAspect.java index c3adff5..8014cb4 100644 --- a/talkonlineweb/src/main/java/com/lyms/talkonlineweb/aop/ResubmitDataAspect.java +++ b/talkonlineweb/src/main/java/com/lyms/talkonlineweb/aop/ResubmitDataAspect.java @@ -46,10 +46,6 @@ public class ResubmitDataAspect { //生成加密参数 使用了content_MD5的加密方式 key.append(ResubmitLock.handleKey(paramStr)); } - else if (param != null) - { - key.append(ResubmitLock.handleKey(param.toString())); - } } if (StringUtil.isNotEmpty(key.toString())) diff --git a/talkonlineweb/src/main/java/com/lyms/talkonlineweb/controller/OrderController.java b/talkonlineweb/src/main/java/com/lyms/talkonlineweb/controller/OrderController.java new file mode 100644 index 0000000..3e0f348 --- /dev/null +++ b/talkonlineweb/src/main/java/com/lyms/talkonlineweb/controller/OrderController.java @@ -0,0 +1,394 @@ +package com.lyms.talkonlineweb.controller; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.lyms.talkonlineweb.annotation.Resubmit; +import com.lyms.talkonlineweb.domain.LymsGoods; +import com.lyms.talkonlineweb.domain.LymsOrder; +import com.lyms.talkonlineweb.domain.LymsPatient; +import com.lyms.talkonlineweb.enums.PayStatus; +import com.lyms.talkonlineweb.result.BaseResponse; +import com.lyms.talkonlineweb.service.*; +import com.lyms.talkonlineweb.util.*; +import lombok.extern.log4j.Log4j2; +import org.apache.catalina.util.IOTools; +import org.apache.commons.io.IOUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.*; + +/** + * @ProjectName: talkonline + * @Package: com.lyms.talkonlineweb.controller + * @ClassName: OrderController + * @Author: lqy + * @Description: 支付订单类 + * @Date: 2021-09-11 09:57 + * @Version: + */ +@RestController +@RequestMapping("order") +@Log4j2 +public class OrderController { + + @Autowired + private LymsGoodsService lymsGoodsService;//问诊卡信息 + + @Autowired + private LymsPatientService lymsPatientService;//患者 + + @Autowired + private LymsTcardService lymsTcardService;//问诊卡信息 + + @Autowired + private LymsLogsService lymsLogsService;//日志记录 + @Autowired + private LymsOrderService lymsOrderService; + + /** + * 微信回调通知接口 + */ + @Value("${notify.url}") + private String notifyUrl; + + + /** + * 创建支付订单,并把订单提交到微信平台 + * 传入患者id和购买数量 + * https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_1 微信统一下单api文档地址 + * @param lymsOrder + * @param request + * @param response + */ + @PostMapping("createPayOrder") + @Resubmit + public BaseResponse createPayOrder(@RequestBody LymsOrder lymsOrder, + HttpServletRequest request, HttpServletResponse response) { + + log.info("create pay order request info : {}",lymsOrder.toString()); + + BaseResponse baseResponse = new BaseResponse(); + //参数校验 + if (lymsOrder.getPid() == null || lymsOrder.getCnt() == null) + { + baseResponse.setErrorcode(1); + baseResponse.setErrormsg("创建订单参数错误"); + return baseResponse; + } + + LymsPatient patient = lymsPatientService.getById(lymsOrder.getPid()); + if (patient == null) + { + baseResponse.setErrorcode(1); + baseResponse.setErrormsg("用户不存在"); + return baseResponse; + } + + + LambdaQueryWrapper wrapper = new QueryWrapper().lambda(); + wrapper.eq(LymsGoods::getType, "card"); + LymsGoods goods = lymsGoodsService.getOne(wrapper); + if (goods == null || goods.getPrice() <= 0) + { + baseResponse.setErrorcode(1); + baseResponse.setErrormsg("商品价格配置不存在"); + return baseResponse; + } + if (goods.getPrice() != lymsOrder.getPrice() && lymsOrder.getPrice() > 0) + { + baseResponse.setErrorcode(1); + baseResponse.setErrormsg("支付价格不一致!"); + return baseResponse; + } + try + { + //生成系统订单号 + String orderNo = StringUtil.getUniqueNo(); + log.info("create order pid {} ,orderNo {}",lymsOrder.getPid(),orderNo); + lymsOrder.setCreatedtime(new Date()); + lymsOrder.setOrderno(orderNo); + lymsOrder.setStatus(PayStatus.CREATED.getCode()); + lymsOrder.setOpenid(patient.getOpenid()); + lymsOrderService.save(lymsOrder); + //创建微信订单 + Map data = createWxOrder(lymsOrder); + if (data != null) + { + + LymsOrder updateOrder = new LymsOrder(); + updateOrder.setId(lymsOrder.getId()); + updateOrder.setPayorderid(data.get("payId")); + //根据订单号更新支付订单号 + lymsOrderService.updateById(updateOrder); + data.put("orderNo",orderNo); + baseResponse.setObject(data); + return baseResponse; + } + }catch (Exception e) + { + log.error("create order error.",e); + } + baseResponse.setErrorcode(1); + baseResponse.setErrormsg("创建订单失败"); + return baseResponse; + } + + /** + * 创建微信订单 + */ + private Map createWxOrder(LymsOrder lymsOrder) + { + try { + String xml = buildRequestXml(lymsOrder); + log.info("create order pid : {},buildRequestMap xml : {}",lymsOrder.getPid(),xml); + + //调用微信统一下单接口 + String result = HttpUtil.postData(Constant.PAY_URL, xml); + log.info("wx create order result : {}" ,result); + + return parseWxResult(result); + } catch (Exception e) { + log.error("createWxOrder error.",e); + } + return null; + } + + + /** + * 解析微信创建订单的结果 + * @param resultXml + * @throws Exception + */ + private Map parseWxResult(String resultXml) throws Exception{ + try + { + Map data = new HashMap(5); + Map retMap = XmlUtil.xmlToMap(resultXml); + String success = "SUCCESS"; + if (retMap != null && retMap.size() > 0 && success.equals(retMap.get("return_code")) && success.equals(retMap.get("result_code"))) + { + data.put("payId",retMap.get("prepay_id")); + return data; + } + } + catch (Exception e) + { + log.error("parse wx result error.",e); + throw e; + } + return null; + } + + + /** + * 构建微信订单参数 + * @param lymsOrder + * @return + * @throws Exception + */ + public String buildRequestXml(LymsOrder lymsOrder) throws Exception { + Map paramMap = new TreeMap((key1,key2) -> { + return key1.toString().compareTo(key2.toString()); + } + ); + //小程序ID + paramMap.put("appid", Constant.PAT_APP_ID); + //商户号 + paramMap.put("mch_id", Constant.MCHID); + //随机字符串 + paramMap.put("nonce_str", NumberUtil.getRandomString(16)); + //签名类型 + paramMap.put("sign_type", "MD5"); + //商户订单号 + paramMap.put("out_trade_no", lymsOrder.getOrderno()); + //标价金额 + paramMap.put("total_fee", String.valueOf(lymsOrder.getCnt() * lymsOrder.getPrice())); + //终端IP + paramMap.put("spbill_create_ip", "119.90.57.26"); + //通知地址 + paramMap.put("notify_url", notifyUrl); + //交易类型 + paramMap.put("trade_type", "JSAPI"); + //用户标识 + paramMap.put("openid", "o4hf60FZzQ4PE-SXYk-jNaouGG-0"); + //商品描述 + paramMap.put("body", "问诊支付"); + + String reqSign = PayDigestUtil.getSign(paramMap, Constant.REQ_KEY); + // 签名 + paramMap.put("sign", reqSign); + return XmlUtil.mapToXml(paramMap); + } + + + /** + * 微信支付成功后回调接口 + * https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_7&index=8 + * @param request + * @param response + * @return + */ + @PostMapping("payNotify") + public void payNotify(HttpServletRequest request, HttpServletResponse response) { + + Map result = new HashMap<>(2); + result.put("return_code",""); + result.put("return_msg","参数错误"); + try { + Map paramMap = getPayNotifyParamMap(request); + + //验证支付通知的参数合法性 + if (!verifyPayNotify(paramMap)) { + //微信支付订单号 + String payOrderId = paramMap.get("transaction_id"); + //商户订单号 + String mchOrderNo = paramMap.get("out_trade_no"); + lymsOrderService.handleOrder(payOrderId,mchOrderNo); + result.put("return_code",""); + result.put("return_msg",""); + } + outResult(response, XmlUtil.mapToXml(result)); + }catch (Exception e) + { + log.error("pay notify error.",e); + try + { + outResult(response, XmlUtil.mapToXml(result)); + }catch (Exception e1) { + + } + } + } + + + /** + * 回调接口响应微信 + * @param response + * @param content + */ + private void outResult(HttpServletResponse response, String content) { + response.setContentType("text/html"); + PrintWriter pw; + try { + pw = response.getWriter(); + pw.print(content); + log.info("response pay complete."); + } catch (IOException e) { + log.error("response pay write exception.", e); + } + } + + + /** + * 解析支付通知参数为map + * @param request + * @return + * @throws Exception + */ + public Map getPayNotifyParamMap(HttpServletRequest request) throws Exception{ + try + { + String resultXml = IOUtils.toString(request.getInputStream(),"utf-8"); + log.info("pay notify info : {}",resultXml); + if (StringUtil.isNotEmpty(resultXml)) + { + Map retMap = XmlUtil.xmlToMap(resultXml); + String success = "SUCCESS"; + if (retMap != null && retMap.size() > 0 && success.equals(retMap.get("return_code")) && success.equals(retMap.get("result_code"))) + { + return retMap; + } + } + }catch (Exception e) + { + log.error("get pay notify error.",e); + throw e; + } + return null; + } + + /** + * 微信回调参数验证 + * @param map + * @return + */ + public boolean verifyPayNotify(Map map) { + //商户id + String mchId = map.get("mch_id"); + //微信支付订单号 + String payOrderId = map.get("transaction_id"); + //商户订单号 + String mchOrderNo = map.get("out_trade_no"); + //现金支付金额 + String amount = map.get("cash_fee"); + //签名 + String sign = map.get("sign"); + + if (StringUtil.isEmpty(mchId)) { + log.warn("Params error. mchId : {}", mchId); + return false; + } + if (StringUtil.isEmpty(payOrderId)) { + log.warn("Params error. payOrderId : {}", payOrderId); + return false; + } + if (StringUtil.isEmpty(amount)) { + log.warn("Params error. amount : {}", amount); + return false; + } + if (StringUtil.isEmpty(sign)) { + log.warn("Params error. sign : {}", sign); + return false; + } + + // 验证签名 + if (!verifySign(map)) { + log.warn("verify params sign failed. payOrderId={}", payOrderId); + return false; + } + + // 根据payOrderId查询业务订单,验证订单是否存在 + LambdaQueryWrapper wrapper = new QueryWrapper().lambda(); + wrapper.eq(LymsOrder::getOrderno, mchOrderNo); + List lymsOrders = lymsOrderService.list(wrapper); + if (CollectionUtils.isNotEmpty(lymsOrders)) { + log.warn("local orderno not exists,payOrderId : {},orderno : {}", payOrderId, mchOrderNo); + return false; + } + // 核对金额 + if (lymsOrders.get(0).getPrice() != Integer.parseInt(amount)) { + log.warn("Inconsistent payment amount ,dbPayPrice : {},payPrice : {}", lymsOrders.get(0).getPrice(), amount); + return false; + } + return true; + } + + + /** + * 回调参数的签名验证 + * @param map + * @return + */ + public boolean verifySign(Map map) { + String mchId = map.get("mch_id"); + //检查商户id + if (!Constant.MCHID.equals(mchId) ) { + return false; + } + String localSign = PayDigestUtil.getSign(map, Constant.REQ_KEY, "sign"); + String sign = map.get("sign"); + return localSign.equalsIgnoreCase(sign); + } + + +} diff --git a/talkonlineweb/src/main/java/com/lyms/talkonlineweb/domain/LymsGoods.java b/talkonlineweb/src/main/java/com/lyms/talkonlineweb/domain/LymsGoods.java new file mode 100644 index 0000000..2a50086 --- /dev/null +++ b/talkonlineweb/src/main/java/com/lyms/talkonlineweb/domain/LymsGoods.java @@ -0,0 +1,59 @@ +package com.lyms.talkonlineweb.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.ToString; + +import java.io.Serializable; +import java.util.Date; + +/** + * @ProjectName: talkonline + * @Package: com.lyms.talkonlineweb.domain + * @ClassName: LymsAttention + * @Author: lqy + * @Description: 商品表 + * @Date: 2021-09-10 16:08 + * @Version: + */ +@TableName(value ="lyms_good") +@Data +@ToString +public class LymsGoods extends BaseModel implements Serializable { + + /** + * + */ + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + /** + * 价格 + */ + @TableField(value = "price") + private int price; + + /** + * 名称 + */ + @TableField(value = "name") + private String name; + + /** + * 类型 + */ + @TableField(value = "type") + private String type; + + + /** + * 创建时间 + */ + @TableField(value = "createdtime") + private Date createdtime; + + +} diff --git a/talkonlineweb/src/main/java/com/lyms/talkonlineweb/domain/LymsOrder.java b/talkonlineweb/src/main/java/com/lyms/talkonlineweb/domain/LymsOrder.java index 1ee7048..cea414b 100644 --- a/talkonlineweb/src/main/java/com/lyms/talkonlineweb/domain/LymsOrder.java +++ b/talkonlineweb/src/main/java/com/lyms/talkonlineweb/domain/LymsOrder.java @@ -53,13 +53,32 @@ public class LymsOrder extends BaseModel implements Serializable { * 价格 */ @TableField(value = "price") - private Integer price; + private int price; /** * 购买数量 */ @TableField(value = "cnt") private Integer cnt; + /** + * 订单状态 订单生成(0),支付成功(1),处理完成(2),处理失败(-1) + */ + @TableField(value = "status") + private Integer status; + + /** + * 支付订单号 + */ + @TableField(value = "payorderid") + private String payorderid; + + /** + * 用户微信openid + */ + @TableField(value = "openid") + private String openid; + + /** * 创建人 diff --git a/talkonlineweb/src/main/java/com/lyms/talkonlineweb/domain/LymsPatient.java b/talkonlineweb/src/main/java/com/lyms/talkonlineweb/domain/LymsPatient.java index 38e01ed..8294b9b 100644 --- a/talkonlineweb/src/main/java/com/lyms/talkonlineweb/domain/LymsPatient.java +++ b/talkonlineweb/src/main/java/com/lyms/talkonlineweb/domain/LymsPatient.java @@ -47,6 +47,12 @@ public class LymsPatient implements Serializable { /** + * 用户openid + */ + @TableField(value = "openid") + private String openid; + + /** * 性别 */ @TableField(value = "sex") diff --git a/talkonlineweb/src/main/java/com/lyms/talkonlineweb/enums/PayStatus.java b/talkonlineweb/src/main/java/com/lyms/talkonlineweb/enums/PayStatus.java new file mode 100644 index 0000000..be8aa8c --- /dev/null +++ b/talkonlineweb/src/main/java/com/lyms/talkonlineweb/enums/PayStatus.java @@ -0,0 +1,39 @@ +package com.lyms.talkonlineweb.enums; + +import lombok.Getter; + +/** + * @ProjectName: talkonline + * @Package: com.lyms.talkonlineweb.enums + * @ClassName: PayStatus + * @Author: lqy + * @Description: 订单支付状态 + * @Date: 2021-09-11 10:23 + * @Version: + */ +@Getter +public enum PayStatus { +//订单生成(0),支付成功(1),处理完成(2),处理失败(-1) + CREATED(0, "订单生成"), + SUCCESS(1, "支付成功"), + COMPLITE(2, "处理完成"), + FAIL(-1, "处理失败"); + + private Integer code; + private String name; + + PayStatus(Integer code, String name){ + this.code = code; + this.name = name; + } + + public static String getName(Integer code) { + PayStatus[] values = PayStatus.values(); + for (PayStatus value : values) { + if (value.getCode().equals(code)) { + return value.getName(); + } + } + return ""; + } +} diff --git a/talkonlineweb/src/main/java/com/lyms/talkonlineweb/mapper/LymsGoodsMapper.java b/talkonlineweb/src/main/java/com/lyms/talkonlineweb/mapper/LymsGoodsMapper.java new file mode 100644 index 0000000..cf7ddaa --- /dev/null +++ b/talkonlineweb/src/main/java/com/lyms/talkonlineweb/mapper/LymsGoodsMapper.java @@ -0,0 +1,15 @@ +package com.lyms.talkonlineweb.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.lyms.talkonlineweb.domain.LymsGoods; + +/** + * @Entity com.lyms.talkonlineweb.domain.LymsGoods + */ +public interface LymsGoodsMapper extends BaseMapper { + +} + + + + diff --git a/talkonlineweb/src/main/java/com/lyms/talkonlineweb/mapper/LymsPatientMapper.java b/talkonlineweb/src/main/java/com/lyms/talkonlineweb/mapper/LymsPatientMapper.java index bc5fb95..06e7e5e 100644 --- a/talkonlineweb/src/main/java/com/lyms/talkonlineweb/mapper/LymsPatientMapper.java +++ b/talkonlineweb/src/main/java/com/lyms/talkonlineweb/mapper/LymsPatientMapper.java @@ -2,12 +2,16 @@ package com.lyms.talkonlineweb.mapper; import com.lyms.talkonlineweb.domain.LymsPatient; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Update; /** * @Entity com.lyms.talkonlineweb.domain.LymsPatient */ public interface LymsPatientMapper extends BaseMapper { + @Update(" UPDATE lyms_patient SET ccnt = ccnt+#{cnt} WHERE id = #{id}") + int updatePatientCcnt(@Param("cnt") Integer cnt, @Param("id") Integer id); } diff --git a/talkonlineweb/src/main/java/com/lyms/talkonlineweb/service/LymsGoodsService.java b/talkonlineweb/src/main/java/com/lyms/talkonlineweb/service/LymsGoodsService.java new file mode 100644 index 0000000..b7e0742 --- /dev/null +++ b/talkonlineweb/src/main/java/com/lyms/talkonlineweb/service/LymsGoodsService.java @@ -0,0 +1,12 @@ +package com.lyms.talkonlineweb.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.lyms.talkonlineweb.domain.LymsGoods; +import com.lyms.talkonlineweb.domain.LymsOrder; + +/** + * + */ +public interface LymsGoodsService extends IService { + +} diff --git a/talkonlineweb/src/main/java/com/lyms/talkonlineweb/service/LymsOrderService.java b/talkonlineweb/src/main/java/com/lyms/talkonlineweb/service/LymsOrderService.java index 53c3ff6..b33e996 100644 --- a/talkonlineweb/src/main/java/com/lyms/talkonlineweb/service/LymsOrderService.java +++ b/talkonlineweb/src/main/java/com/lyms/talkonlineweb/service/LymsOrderService.java @@ -9,4 +9,5 @@ import com.lyms.talkonlineweb.domain.LymsOrder; */ public interface LymsOrderService extends IService { + boolean handleOrder(String payOrderId, String mchOrderNo); } diff --git a/talkonlineweb/src/main/java/com/lyms/talkonlineweb/service/impl/LymsGoodsServiceImpl.java b/talkonlineweb/src/main/java/com/lyms/talkonlineweb/service/impl/LymsGoodsServiceImpl.java new file mode 100644 index 0000000..4e09b99 --- /dev/null +++ b/talkonlineweb/src/main/java/com/lyms/talkonlineweb/service/impl/LymsGoodsServiceImpl.java @@ -0,0 +1,20 @@ +package com.lyms.talkonlineweb.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.lyms.talkonlineweb.domain.LymsGoods; +import com.lyms.talkonlineweb.mapper.LymsGoodsMapper; +import com.lyms.talkonlineweb.service.LymsGoodsService; +import org.springframework.stereotype.Service; + + +/** + * + */ +@Service +public class LymsGoodsServiceImpl extends ServiceImpl + implements LymsGoodsService { +} + + + + diff --git a/talkonlineweb/src/main/java/com/lyms/talkonlineweb/service/impl/LymsOrderServiceImpl.java b/talkonlineweb/src/main/java/com/lyms/talkonlineweb/service/impl/LymsOrderServiceImpl.java index ff0e679..2c513dc 100644 --- a/talkonlineweb/src/main/java/com/lyms/talkonlineweb/service/impl/LymsOrderServiceImpl.java +++ b/talkonlineweb/src/main/java/com/lyms/talkonlineweb/service/impl/LymsOrderServiceImpl.java @@ -1,13 +1,24 @@ package com.lyms.talkonlineweb.service.impl; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.lyms.talkonlineweb.domain.LymsAttention; import com.lyms.talkonlineweb.domain.LymsOrder; +import com.lyms.talkonlineweb.domain.LymsPatient; +import com.lyms.talkonlineweb.domain.LymsTcard; +import com.lyms.talkonlineweb.enums.PayStatus; import com.lyms.talkonlineweb.mapper.LymsAttentionMapper; import com.lyms.talkonlineweb.mapper.LymsOrderMapper; +import com.lyms.talkonlineweb.mapper.LymsPatientMapper; +import com.lyms.talkonlineweb.mapper.LymsTcardMapper; import com.lyms.talkonlineweb.service.LymsAttentionService; import com.lyms.talkonlineweb.service.LymsOrderService; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Date; /** * @@ -16,6 +27,43 @@ import org.springframework.stereotype.Service; public class LymsOrderServiceImpl extends ServiceImpl implements LymsOrderService { + @Autowired + private LymsPatientMapper lymsPatientMapper; + + @Autowired + private LymsTcardMapper lymsTcardMapper; + + @Override + @Transactional(rollbackFor = Exception.class) + public boolean handleOrder(String payOrderId, String mchOrderNo) { + + //处理业务逻辑 + LambdaQueryWrapper wrapper = new QueryWrapper().lambda(); + wrapper.eq(LymsOrder::getOrderno, mchOrderNo); + wrapper.eq(LymsOrder::getPayorderid, payOrderId); + LymsOrder lymsOrders = getOne(wrapper); + if (lymsOrders != null) { + + LymsPatient patient = lymsPatientMapper.selectById(lymsOrders.getPid()); + if (patient == null) + { + return false; + } + + //TODO +// LymsTcard tcard = new LymsTcard(); +// lymsTcardMapper.insert(); + + //更新患者的卡的数量 + lymsPatientMapper.updatePatientCcnt(lymsOrders.getCnt(),patient.getId()); + + lymsOrders.setStatus(PayStatus.SUCCESS.getCode()); + lymsOrders.setUpdatedtime(new Date()); + updateById(lymsOrders); + } + + return false; + } } diff --git a/talkonlineweb/src/main/java/com/lyms/talkonlineweb/util/Constant.java b/talkonlineweb/src/main/java/com/lyms/talkonlineweb/util/Constant.java index c829c8d..187c70f 100644 --- a/talkonlineweb/src/main/java/com/lyms/talkonlineweb/util/Constant.java +++ b/talkonlineweb/src/main/java/com/lyms/talkonlineweb/util/Constant.java @@ -8,4 +8,42 @@ public class Constant { public static final int ROOT_MENU = 0;//一级菜单 public static final String CUR_USER = "cur_user";//当前用户 public static final String COMMON_PASSWD = "123456";//通用密码 + + /** + * 患者端商户id + */ + public static final String MCHID = "1426009502"; + + /** + * 患者小程序appid + */ + public static final String PAT_APP_ID = "wxe3b5c34317a0f85b"; + + /** + * 签名加密 key + */ + public static final String REQ_KEY = "5fddsw5e7bfdeb99327435d125aebcs9"; + + /** + * 微信服务器的域名 + */ + public static final String WEIXIN_SERVER = "https://api.weixin.qq.com"; + + /** + * 微信支付订单url + */ + public static final String PAY_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder"; + + + /** + * 认证类型填写为 authorization_code + */ + public static final String GRANT_TYPE = "authorization_code"; + + + /** + * 小程序的 app secret + */ + public static final String WX_SECRET = "005ab68859ca2504b7217dac4c903cd2"; + } diff --git a/talkonlineweb/src/main/java/com/lyms/talkonlineweb/util/DateUtil.java b/talkonlineweb/src/main/java/com/lyms/talkonlineweb/util/DateUtil.java index b9ddce0..646c126 100644 --- a/talkonlineweb/src/main/java/com/lyms/talkonlineweb/util/DateUtil.java +++ b/talkonlineweb/src/main/java/com/lyms/talkonlineweb/util/DateUtil.java @@ -70,4 +70,9 @@ public class DateUtil { } return null; } + + public static String getSeqString() { + SimpleDateFormat fm = new SimpleDateFormat("yyMMddHHmmss"); + return fm.format(new Date()); + } } diff --git a/talkonlineweb/src/main/java/com/lyms/talkonlineweb/util/HttpUtil.java b/talkonlineweb/src/main/java/com/lyms/talkonlineweb/util/HttpUtil.java new file mode 100644 index 0000000..9d1e67c --- /dev/null +++ b/talkonlineweb/src/main/java/com/lyms/talkonlineweb/util/HttpUtil.java @@ -0,0 +1,92 @@ +package com.lyms.talkonlineweb.util; + +import java.io.IOException; + + +import lombok.extern.log4j.Log4j2; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.HttpGet; +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; +/** + * @ProjectName: talkonline + * @Package: com.lyms.talkonlineweb.util + * @ClassName: HttpUtil + * @Author: lqy + * @Description: + * @Date: 2021-09-11 16:24 + * @Version: + */ +@Log4j2 +public class HttpUtil { + + // 连接超时时间,默认10秒 + private static int socketTimeout = 10000; + // 传输超时时间,默认30秒 + private static int connectTimeout = 30000; + // 请求器的配置 + private static RequestConfig requestConfig; + // HTTP请求器 + private static CloseableHttpClient httpClient; + static { + httpClient = HttpClients.custom().build(); + // 根据默认超时限制初始化requestConfig + requestConfig = RequestConfig.custom().setSocketTimeout(socketTimeout).setConnectTimeout(connectTimeout).build(); + } + + + /** + * post 请求 + * @param url + * @param content + * @return + */ + public static String postData(String url, String content) { + + String result = null; + HttpPost httpPost = new HttpPost(url); + StringEntity postEntity = new StringEntity(content, "UTF-8"); + httpPost.addHeader("Content-Type", "text/xml"); + httpPost.setEntity(postEntity); + // 设置请求器的配置 + httpPost.setConfig(requestConfig); + try { + HttpResponse response = httpClient.execute(httpPost); + HttpEntity entity = response.getEntity(); + result = EntityUtils.toString(entity, "UTF-8"); + }catch (Exception e){ + log.error("post execute error,url : {}",url,e); + } finally { + httpPost.abort(); + } + return result; + } + + + /** + * get请求 + * @param url + * @return + */ + public static String getData(String url) { + String result = null; + HttpGet httpGet = new HttpGet(url); + httpGet.setConfig(requestConfig); + try { + HttpResponse response = httpClient.execute(httpGet); + HttpEntity entity = response.getEntity(); + result = EntityUtils.toString(entity, "UTF-8"); + }catch (Exception e){ + log.error("get execute error,url : {}",url,e); + } finally { + httpGet.abort(); + } + return result; + } + +} diff --git a/talkonlineweb/src/main/java/com/lyms/talkonlineweb/util/IdWorker.java b/talkonlineweb/src/main/java/com/lyms/talkonlineweb/util/IdWorker.java new file mode 100644 index 0000000..e35c328 --- /dev/null +++ b/talkonlineweb/src/main/java/com/lyms/talkonlineweb/util/IdWorker.java @@ -0,0 +1,62 @@ +package com.lyms.talkonlineweb.util; + + +public class IdWorker { + + private final long workerId; + private final long epoch = 1403854494756L; + private final long workerIdBits = 10L; + private final long maxWorkerId = -1L ^ -1L << this.workerIdBits; + private long sequence = 0L; + private final long sequenceBits = 12L; + + private final long workerIdShift = this.sequenceBits; + private final long timestampLeftShift = this.sequenceBits + this.workerIdBits; + private final long sequenceMask = -1L ^ -1L << this.sequenceBits; + private long lastTimestamp = -1L; + + private IdWorker(long workerId) { + if (workerId > this.maxWorkerId || workerId < 0) { + throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", this.maxWorkerId)); + } + this.workerId = workerId; + } + + public synchronized long nextId() throws Exception { + long timestamp = this.timeGen(); + if (this.lastTimestamp == timestamp) { + this.sequence = this.sequence + 1 & this.sequenceMask; + if (this.sequence == 0) { + timestamp = this.tilNextMillis(this.lastTimestamp); + } + } else { + this.sequence = 0; + } + + if (timestamp < this.lastTimestamp) { + throw new Exception(String.format("clock moved backwards.Refusing to generate id for %d milliseconds", (this.lastTimestamp - timestamp))); + } + + this.lastTimestamp = timestamp; + return timestamp - this.epoch << this.timestampLeftShift | this.workerId << this.workerIdShift | this.sequence; + } + + private static IdWorker flowIdWorker = new IdWorker(1); + public static IdWorker getFlowIdWorkerInstance() { + return flowIdWorker; + } + + private long tilNextMillis(long lastTimestamp) { + long timestamp = this.timeGen(); + while (timestamp <= lastTimestamp) { + timestamp = this.timeGen(); + } + return timestamp; + } + + private long timeGen() { + return System.currentTimeMillis(); + } + + +} \ No newline at end of file diff --git a/talkonlineweb/src/main/java/com/lyms/talkonlineweb/util/JsonUtil.java b/talkonlineweb/src/main/java/com/lyms/talkonlineweb/util/JsonUtil.java index 921804b..970a549 100644 --- a/talkonlineweb/src/main/java/com/lyms/talkonlineweb/util/JsonUtil.java +++ b/talkonlineweb/src/main/java/com/lyms/talkonlineweb/util/JsonUtil.java @@ -2,6 +2,9 @@ package com.lyms.talkonlineweb.util; import com.fasterxml.jackson.databind.ObjectMapper; +import java.util.HashMap; +import java.util.Map; + /** * Created by Administrator on 2019-09-06. @@ -27,4 +30,36 @@ public class JsonUtil { return null; } + /** + * json转换为map + * @param json + * @param hashMapClass + * @return + */ + public static Map str2Map(String json, Class hashMapClass) { + try { + ObjectMapper objectMapper = new ObjectMapper(); + return objectMapper.readValue(json,hashMapClass); + } catch (Exception e) { + + } + return null; + } + + /** + * 接送转换为对象 + * @param json + * @param clzz + * @param + * @return + */ + public static T str2Obj(String json, Class clzz) { + try { + ObjectMapper objectMapper = new ObjectMapper(); + return objectMapper.readValue(json,clzz); + } catch (Exception e) { + + } + return null; + } } diff --git a/talkonlineweb/src/main/java/com/lyms/talkonlineweb/util/NumberUtil.java b/talkonlineweb/src/main/java/com/lyms/talkonlineweb/util/NumberUtil.java new file mode 100644 index 0000000..67b2ae4 --- /dev/null +++ b/talkonlineweb/src/main/java/com/lyms/talkonlineweb/util/NumberUtil.java @@ -0,0 +1,30 @@ +package com.lyms.talkonlineweb.util; + +import java.util.Random; + +/** + * @ProjectName: talkonline + * @Package: com.lyms.talkonlineweb.util + * @ClassName: NumberUtil + * @Author: lqy + * @Description: 返回指定长度的随机数字字符串 + * @Date: 2021-09-11 11:29 + * @Version: + */ + +public class NumberUtil { + + private static final String RANDSTRING = "0123456789"; + /** + * 获取随机的字符 + */ + public static String getRandomString(int length){ + StringBuilder builder = new StringBuilder(length); + Random random = new Random(); + for(int i=0;i map, String key){ + ArrayList list = new ArrayList(); + for(Map.Entry entry:map.entrySet()){ + if(!"".equals(entry.getValue())){ + list.add(entry.getKey() + "=" + entry.getValue() + "&"); + } + } + int size = list.size(); + String[] arrayToSort = list.toArray(new String[size]); + Arrays.sort(arrayToSort, String.CASE_INSENSITIVE_ORDER); + StringBuilder sb = new StringBuilder(); + for(int i = 0; i < size; i ++) { + sb.append(arrayToSort[i]); + } + String result = sb.toString(); + result += "key=" + key; + result = md5(result, encodingCharset).toUpperCase(); + return result; + } + + /** + * + * @param map + * @param key + * @param notContains 不包含的签名字段 + * @return + */ + public static String getSign(Map map, String key, String... notContains){ + Map newMap = new HashMap(); + for(Map.Entry entry:map.entrySet()){ + boolean isContain = false; + for(int i=0; i result = JsonUtil.str2Map(response, HashMap.class); + if (result.containsKey(OPEN_ID_KEY)) + { + return result.get(OPEN_ID_KEY).toString(); + } + } + } catch (Exception e) { + log.error("getWxOpenId by code: {}", code, e); + } + return null; + } + +} diff --git a/talkonlineweb/src/main/java/com/lyms/talkonlineweb/util/XmlUtil.java b/talkonlineweb/src/main/java/com/lyms/talkonlineweb/util/XmlUtil.java new file mode 100644 index 0000000..c855437 --- /dev/null +++ b/talkonlineweb/src/main/java/com/lyms/talkonlineweb/util/XmlUtil.java @@ -0,0 +1,100 @@ +package com.lyms.talkonlineweb.util; + +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.io.StringWriter; +import java.util.HashMap; +import java.util.Map; + +/** + * @ProjectName: talkonline + * @Package: com.lyms.talkonlineweb.util + * @ClassName: XmlUtil + * @Author: lqy + * @Description: xml转换 + * @Date: 2021-09-11 14:40 + * @Version: + */ + +public class XmlUtil { + + /** + * 将Map转换为XML格式的字符串 + * + * @param data Map类型数据 + * @return XML格式的字符串 + * @throws Exception + */ + public static String mapToXml(Map data) throws Exception{ + try { + DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder documentBuilder= documentBuilderFactory.newDocumentBuilder(); + org.w3c.dom.Document document = documentBuilder.newDocument(); + org.w3c.dom.Element root = document.createElement("xml"); + document.appendChild(root); + for (String key: data.keySet()) { + String value = data.get(key); + if (value == null) { + value = ""; + } + value = value.trim(); + org.w3c.dom.Element filed = document.createElement(String.valueOf(key)); + filed.appendChild(document.createTextNode(value)); + root.appendChild(filed); + } + TransformerFactory tf = TransformerFactory.newInstance(); + Transformer transformer = tf.newTransformer(); + DOMSource source = new DOMSource(document); + transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + StringWriter writer = new StringWriter(); + StreamResult result = new StreamResult(writer); + transformer.transform(source, result); + String output = writer.getBuffer().toString(); + writer.close(); + return output; + } catch (Exception e) { + throw e; + } + } + + + public static Map xmlToMap(String strXML) throws Exception{ + InputStream stream = null; + try { + Map data = new HashMap(); + DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); + stream = new ByteArrayInputStream(strXML.getBytes("UTF-8")); + org.w3c.dom.Document doc = documentBuilder.parse(stream); + doc.getDocumentElement().normalize(); + NodeList nodeList = doc.getDocumentElement().getChildNodes(); + for (int idx = 0; idx < nodeList.getLength(); ++idx) { + Node node = nodeList.item(idx); + if (node.getNodeType() == Node.ELEMENT_NODE) { + org.w3c.dom.Element element = (org.w3c.dom.Element) node; + data.put(element.getNodeName(), element.getTextContent()); + } + } + return data; + } catch (Exception ex) { + throw ex; + }finally { + try { + stream.close(); + } catch (Exception ex) { + } + } + } + +} diff --git a/talkonlineweb/src/main/resources/application.yml b/talkonlineweb/src/main/resources/application.yml index c9425c0..70fbac8 100644 --- a/talkonlineweb/src/main/resources/application.yml +++ b/talkonlineweb/src/main/resources/application.yml @@ -31,4 +31,7 @@ hx.ClientSecret: YXA6RZaIr68MPPLcvqUnYxpqEkAEj6w hx.org_name: 1135210903239178 hx.app_name: demo hx.hxuser: test -hx.hxpasswd: passwd \ No newline at end of file +hx.hxpasswd: passwd + +#微信支付通知地址 +notify.url: https://dev-talk-api.healthbaby.com.cn/order/payNotify \ No newline at end of file diff --git a/talkonlineweb/src/main/resources/logback-spring.xml b/talkonlineweb/src/main/resources/logback-spring.xml index 7093c1c..46228a1 100644 --- a/talkonlineweb/src/main/resources/logback-spring.xml +++ b/talkonlineweb/src/main/resources/logback-spring.xml @@ -79,7 +79,7 @@ - +