新增开票接口及查询接口

This commit is contained in:
2024-07-09 16:45:45 +08:00
parent 7d6bf3b8fa
commit a2fcbd165d
8 changed files with 262 additions and 91 deletions
@@ -3,13 +3,11 @@ package com.gxwebsoft.booking.controller;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.gxwebsoft.booking.entity.NuoNuo; import com.alibaba.fastjson.JSONObject;
import com.gxwebsoft.booking.entity.NuoNuoGoods; import com.gxwebsoft.booking.entity.*;
import com.gxwebsoft.booking.entity.NuoNuoOrder;
import com.gxwebsoft.common.core.utils.JSONUtil; import com.gxwebsoft.common.core.utils.JSONUtil;
import com.gxwebsoft.common.core.web.BaseController; import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.booking.service.UserInvoiceService; import com.gxwebsoft.booking.service.UserInvoiceService;
import com.gxwebsoft.booking.entity.UserInvoice;
import com.gxwebsoft.booking.param.UserInvoiceParam; import com.gxwebsoft.booking.param.UserInvoiceParam;
import com.gxwebsoft.common.core.web.ApiResult; import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.PageResult; import com.gxwebsoft.common.core.web.PageResult;
@@ -17,13 +15,18 @@ import com.gxwebsoft.common.core.web.PageParam;
import com.gxwebsoft.common.core.web.BatchParam; import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.annotation.OperationLog; import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.system.entity.User; import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.shop.entity.Order;
import com.gxwebsoft.shop.service.OrderService;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import io.swagger.models.auth.In;
import nuonuo.open.sdk.NNOpenSDK; import nuonuo.open.sdk.NNOpenSDK;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
@@ -38,124 +41,136 @@ import java.util.UUID;
@RestController @RestController
@RequestMapping("/api/booking/user-invoice") @RequestMapping("/api/booking/user-invoice")
public class UserInvoiceController extends BaseController { public class UserInvoiceController extends BaseController {
@Resource @Resource
private UserInvoiceService userInvoiceService; private UserInvoiceService userInvoiceService;
@Resource
private OrderService orderService;
@ApiOperation("分页查询发票") @ApiOperation("分页查询发票")
@GetMapping("/page") @GetMapping("/page")
public ApiResult<PageResult<UserInvoice>> page(UserInvoiceParam param) { public ApiResult<PageResult<UserInvoice>> page(UserInvoiceParam param) {
// 使用关联查询 // 使用关联查询
return success(userInvoiceService.pageRel(param)); return success(userInvoiceService.pageRel(param));
} }
@ApiOperation("查询全部发票") @ApiOperation("查询全部发票")
@GetMapping() @GetMapping()
public ApiResult<List<UserInvoice>> list(UserInvoiceParam param) { public ApiResult<List<UserInvoice>> list(UserInvoiceParam param) {
// 使用关联查询 // 使用关联查询
return success(userInvoiceService.listRel(param)); return success(userInvoiceService.listRel(param));
} }
@PreAuthorize("hasAuthority('booking:userInvoice:list')") @PreAuthorize("hasAuthority('booking:userInvoice:list')")
@ApiOperation("根据id查询发票") @ApiOperation("根据id查询发票")
@GetMapping("/{id}") @GetMapping("/{id}")
public ApiResult<UserInvoice> get(@PathVariable("id") Integer id) { public ApiResult<UserInvoice> get(@PathVariable("id") Integer id) {
// 使用关联查询 // 使用关联查询
return success(userInvoiceService.getByIdRel(id)); return success(userInvoiceService.getByIdRel(id));
} }
@ApiOperation("添加发票") @ApiOperation("添加发票")
@PostMapping() @PostMapping()
public ApiResult<?> save(@RequestBody UserInvoice userInvoice) { public ApiResult<?> save(@RequestBody UserInvoice userInvoice) {
// 记录当前登录用户id // 记录当前登录用户id
User loginUser = getLoginUser(); User loginUser = getLoginUser();
if (loginUser != null) { if (loginUser != null) {
userInvoice.setUserId(loginUser.getUserId()); userInvoice.setUserId(loginUser.getUserId());
}
if (userInvoiceService.save(userInvoice)) {
return success("添加成功");
}
return fail("添加失败");
} }
if (userInvoiceService.save(userInvoice)) {
return success("添加成功");
}
return fail("添加失败");
}
@ApiOperation("修改发票") @ApiOperation("修改发票")
@PutMapping() @PutMapping()
public ApiResult<?> update(@RequestBody UserInvoice userInvoice) { public ApiResult<?> update(@RequestBody UserInvoice userInvoice) {
if (userInvoiceService.updateById(userInvoice)) { if (userInvoiceService.updateById(userInvoice)) {
return success("修改成功"); return success("修改成功");
}
return fail("修改失败");
} }
return fail("修改失败");
}
@ApiOperation("删除发票") @ApiOperation("删除发票")
@DeleteMapping("/{id}") @DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) { public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (userInvoiceService.removeById(id)) { if (userInvoiceService.removeById(id)) {
return success("删除成功"); return success("删除成功");
}
return fail("删除失败");
} }
return fail("删除失败");
}
@ApiOperation("批量添加发票") @ApiOperation("批量添加发票")
@PostMapping("/batch") @PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<UserInvoice> list) { public ApiResult<?> saveBatch(@RequestBody List<UserInvoice> list) {
if (userInvoiceService.saveBatch(list)) { if (userInvoiceService.saveBatch(list)) {
return success("添加成功"); return success("添加成功");
}
return fail("添加失败");
} }
return fail("添加失败");
}
@ApiOperation("批量修改发票") @ApiOperation("批量修改发票")
@PutMapping("/batch") @PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<UserInvoice> batchParam) { public ApiResult<?> removeBatch(@RequestBody BatchParam<UserInvoice> batchParam) {
if (batchParam.update(userInvoiceService, "id")) { if (batchParam.update(userInvoiceService, "id")) {
return success("修改成功"); return success("修改成功");
}
return fail("修改失败");
} }
return fail("修改失败");
}
@ApiOperation("批量删除发票") @ApiOperation("批量删除发票")
@DeleteMapping("/batch") @DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) { public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (userInvoiceService.removeByIds(ids)) { if (userInvoiceService.removeByIds(ids)) {
return success("删除成功"); return success("删除成功");
}
return fail("删除失败");
} }
return fail("删除失败");
}
@ApiOperation("开具发票") @ApiOperation("开具发票")
@GetMapping("/doInvoice/{id}") @PostMapping("/doInvoice")
public ApiResult<?> doInvoice(@PathVariable("id") Integer id) { public ApiResult<?> doInvoice(@RequestBody UserInvoice userInvoice) {
final UserInvoice userInvoice = userInvoiceService.getByIdRel(id); final Order orderInfo = orderService.getById(userInvoice.getOrderId());
System.out.println("orderInfo = " + orderInfo);
final UserInvoice invoice = userInvoiceService.getByIdRel(userInvoice.getId());
// 开票接口 // 开票接口
NNOpenSDK sdk = NNOpenSDK.getIntance(); NNOpenSDK sdk = NNOpenSDK.getIntance();
String taxnum = "339901999999142";//ISV下授权商户税号,自用型应用置""即可 String taxnum = "339901999999142";//ISV下授权商户税号,自用型应用置""即可
String appKey = "SD56531018"; String appKey = "SD56531018";
String appSecret = "SD3C429B318C485E"; String appSecret = "SD3C429B318C485E";
String method = "nuonuo.OpeMplatform.requestBillingNew";//API方法名 String method = "nuonuo.OpeMplatform.requestBillingNew";//API方法名
String token = NNOpenSDK.getIntance().getMerchantToken("SD56531018","SD3C429B318C485E"); //访问令牌 String token = NNOpenSDK.getIntance().getMerchantToken("SD56531018", "SD3C429B318C485E"); //访问令牌
final NuoNuo nuoNuo = new NuoNuo(); final NuoNuo nuoNuo = new NuoNuo();
final NuoNuoOrder order = new NuoNuoOrder(); final NuoNuoOrder order = new NuoNuoOrder();
order.setBuyerName(userInvoice.getName()); order.setBuyerName(invoice.getName());
// order.setSalerTaxNum(invoice.getInvoiceCode());
// order.setSalerTel(invoice.getPhone());
order.setSalerTaxNum("339901999999142"); order.setSalerTaxNum("339901999999142");
order.setSalerTel("339901999999142"); order.setSalerTel("339901999999142");
order.setOrderNo(Long.toString(IdUtil.getSnowflakeNextId())); order.setOrderNo(orderInfo.getOrderNo());
order.setInvoiceDate(DateUtil.now()); order.setInvoiceDate(DateUtil.now());
order.setClerk("张三"); order.setClerk("张三");
order.setBuyerPhone(userInvoice.getPhone()); order.setBuyerPhone(userInvoice.getPhone());
order.setInvoiceType("1"); order.setInvoiceType("1");
final NuoNuoGoods goods = new NuoNuoGoods(); final NuoNuoGoods goods = new NuoNuoGoods();
goods.setGoodsName(userInvoice.getComments()); goods.setGoodsName(orderInfo.getComments());
goods.setWithTaxFlag("0"); goods.setWithTaxFlag("0");
goods.setDField1("综合馆羽毛球馆 2024-05-16 (星期四) 18:00 - 20:00"); goods.setDField1(orderInfo.getComments());
goods.setDField2("无"); goods.setDField2("无");
goods.setDField3("无"); goods.setDField3("无");
goods.setDField4("无"); goods.setDField4("无");
goods.setDField5("无"); goods.setDField5("无");
goods.setTax("0.12"); final String tax = orderInfo.getTotalPrice().multiply(new BigDecimal("0.06")).toString();
goods.setTaxRate("0.13"); goods.setTax(tax);
goods.setTaxExcludedAmount("0.88"); goods.setTaxRate(new BigDecimal("0.06").toString());
goods.setTaxIncludedAmount("1"); System.out.println("不含税金额 = " + orderInfo.getTotalPrice());
System.out.println("税额 = " + tax);
System.out.println("含税金额 = " + orderInfo.getTotalPrice().add(new BigDecimal(tax)));
goods.setTaxExcludedAmount(orderInfo.getTotalPrice().toString());
goods.setTaxIncludedAmount(orderInfo.getTotalPrice().add(new BigDecimal(tax)).toString());
order.setInvoiceDetail(goods); order.setInvoiceDetail(goods);
System.out.println("order = " + order);
nuoNuo.setOrder(order); nuoNuo.setOrder(order);
String content = JSONUtil.toJSONString(nuoNuo);//API私有请求参数 String content = JSONUtil.toJSONString(nuoNuo);//API私有请求参数
@@ -164,9 +179,94 @@ public class UserInvoiceController extends BaseController {
String json = sdk.sendPostSyncRequest(url, senid, appKey, appSecret, token, taxnum, method, content); // 请求API String json = sdk.sendPostSyncRequest(url, senid, appKey, appSecret, token, taxnum, method, content); // 请求API
System.out.println("json = " + json); System.out.println("json = " + json);
if (StrUtil.isNotBlank(json)) { if (StrUtil.isNotBlank(json)) {
return success("发票开具成功",json); final JSONObject jsonObject = JSONObject.parseObject(json);
final String code = jsonObject.getString("code");
final String result = jsonObject.getString("result");
System.out.println("jsonObject = " + jsonObject);
if (code.equals("E0000")) {
final JSONObject resNo = JSONObject.parseObject(result);
final String invoiceSerialNum = resNo.getString("invoiceSerialNum");
orderInfo.setIsInvoice(1);
orderInfo.setInvoiceNo(invoiceSerialNum);
System.out.println("invoiceSerialNum = " + invoiceSerialNum);
orderService.updateById(orderInfo);
return success("发票开具成功", json);
}
} }
return fail("发票开具失败"); return fail("发票开具失败");
} }
@ApiOperation("根据id查询发票")
@GetMapping("/showInvoice/{orderId}")
public ApiResult<String> showInvoice(@PathVariable("orderId") Integer orderId) {
final Order order = orderService.getById(orderId);
NNOpenSDK sdk = NNOpenSDK.getIntance();
String taxnum = "339901999999142";//ISV下授权商户税号,自用型应用置""即可
String appKey = "SD56531018";
String appSecret = "SD3C429B318C485E";
String method = "nuonuo.OpeMplatform.queryInvoiceResult";//API方法名
String token = NNOpenSDK.getIntance().getMerchantToken("SD56531018", "SD3C429B318C485E"); //访问令牌
HashMap<String, Object> map = new HashMap<>();
// map.put("invoiceCode",invoiceNo);
map.put("serialNos", order.getInvoiceNo());
// map.put("inTaxAmount", order.getPayPrice().subtract(order.getPayPrice().multiply(new BigDecimal("0.06")))); // 含税金额
// map.put("exTaxAmount", order.getPayPrice()); // 不含税金额
System.out.println("map = " + map);
String content = JSONUtil.toJSONString(map);//API私有请求参数
String url = "https://sandbox.nuonuocs.cn/open/v1/services"; //SDK请求地址
String senid = UUID.randomUUID().toString(); // 唯一标识,由企业自己生成32位随机码
String result = sdk.sendPostSyncRequest(url, senid, appKey, appSecret, token, taxnum, method, content);
System.out.println("result = " + result);
return success("查询成功", result);
}
// @ApiOperation("开具发票")
// @GetMapping("/doInvoice/{id}")
// public ApiResult<?> doInvoice(@PathVariable("id") Integer id) {
// final UserInvoice userInvoice = userInvoiceService.getByIdRel(id);
// // 开票接口
// NNOpenSDK sdk = NNOpenSDK.getIntance();
// String taxnum = "339901999999142";//ISV下授权商户税号,自用型应用置""即可
// String appKey = "SD56531018";
// String appSecret = "SD3C429B318C485E";
// String method = "nuonuo.OpeMplatform.requestBillingNew";//API方法名
// String token = NNOpenSDK.getIntance().getMerchantToken("SD56531018","SD3C429B318C485E"); //访问令牌
// final NuoNuo nuoNuo = new NuoNuo();
// final NuoNuoOrder order = new NuoNuoOrder();
// order.setBuyerName(userInvoice.getName());
// order.setSalerTaxNum("339901999999142");
// order.setSalerTel("339901999999142");
// order.setOrderNo(Long.toString(IdUtil.getSnowflakeNextId()));
// order.setInvoiceDate(DateUtil.now());
// order.setClerk("张三");
// order.setBuyerPhone(userInvoice.getPhone());
// order.setInvoiceType("1");
// final NuoNuoGoods goods = new NuoNuoGoods();
// goods.setGoodsName(userInvoice.getComments());
// goods.setWithTaxFlag("0");
// goods.setDField1("综合馆羽毛球馆 2024-05-16 (星期四) 18:00 - 20:00");
// goods.setDField2("无");
// goods.setDField3("无");
// goods.setDField4("无");
// goods.setDField5("无");
// goods.setTax("0.12");
// goods.setTaxRate("0.13");
// goods.setTaxExcludedAmount("0.88");
// goods.setTaxIncludedAmount("1");
// order.setInvoiceDetail(goods);
// nuoNuo.setOrder(order);
//
// String content = JSONUtil.toJSONString(nuoNuo);//API私有请求参数
// String url = "https://sandbox.nuonuocs.cn/open/v1/services"; //SDK请求地址
// String senid = UUID.randomUUID().toString(); // 唯一标识,由企业自己生成32位随机码
// String json = sdk.sendPostSyncRequest(url, senid, appKey, appSecret, token, taxnum, method, content); // 请求API
// System.out.println("json = " + json);
// if (StrUtil.isNotBlank(json)) {
// return success("发票开具成功",json);
// }
// return fail("发票开具失败");
// }
} }
@@ -0,0 +1,34 @@
package com.gxwebsoft.booking.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
/**
* 发票
*
* @author 科技小王子
* @since 2024-05-25 17:20:15
*/
@Data
@EqualsAndHashCode(callSuper = false)
@ApiModel(value = "NuoNuo开票对象", description = "开票对象")
public class NuoNuoResult implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "编码")
@TableField(exist = false)
private String code;
@ApiModelProperty(value = "描述")
@TableField(exist = false)
private String describe;
@ApiModelProperty(value = "返回结果")
@TableField(exist = false)
private String result;
}
@@ -0,0 +1,26 @@
package com.gxwebsoft.booking.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
/**
* 发票
*
* @author 科技小王子
* @since 2024-05-25 17:20:15
*/
@Data
@EqualsAndHashCode(callSuper = false)
@ApiModel(value = "NuoNuo开票对象", description = "开票对象")
public class NuoNuoResultNo implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "发票流水号")
@TableField(exist = false)
private String invoiceSerialNum;
}
@@ -12,6 +12,7 @@ import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.Value;
/** /**
* 发票 * 发票
@@ -63,6 +64,9 @@ public class UserInvoice implements Serializable {
@ApiModelProperty(value = "备注") @ApiModelProperty(value = "备注")
private String comments; private String comments;
@ApiModelProperty(value = "是否启用")
private Integer isCompany;
@ApiModelProperty(value = "排序(数字越小越靠前)") @ApiModelProperty(value = "排序(数字越小越靠前)")
private Integer sortNumber; private Integer sortNumber;
@@ -85,4 +89,7 @@ public class UserInvoice implements Serializable {
@ApiModelProperty(value = "修改时间") @ApiModelProperty(value = "修改时间")
private Date updateTime; private Date updateTime;
@ApiModelProperty(value = "订单号")
private Integer orderId;
} }
@@ -64,12 +64,12 @@ public class WxPayNotifyController extends BaseController {
@PostMapping("/notify/{tenantId}") @PostMapping("/notify/{tenantId}")
public String wxNotify(@RequestHeader Map<String, String> header, @RequestBody String body, @PathVariable("tenantId") Integer tenantId) { public String wxNotify(@RequestHeader Map<String, String> header, @RequestBody String body, @PathVariable("tenantId") Integer tenantId) {
System.out.println("异步通知*************** = "); System.out.println("异步通知*************** = ");
// System.out.println("request header = " + header); System.out.println("request header = " + header);
// System.out.println("request body = " + body); System.out.println("request body = " + body);
// System.out.println("tenantId = " + tenantId); System.out.println("tenantId = " + tenantId);
// 获取支付配置信息用于解密 // 获取支付配置信息用于解密
String key = "Payment:wxPay:".concat(tenantId.toString()); String key = "Payment:1:".concat(tenantId.toString());
final Payment payment = redisUtil.get(key, Payment.class); final Payment payment = redisUtil.get(key, Payment.class);
String privateKey = payment.getApiKey(); String privateKey = payment.getApiKey();
String apiclientCert = conf.getUploadPath().concat("/file").concat(payment.getApiclientCert()); String apiclientCert = conf.getUploadPath().concat("/file").concat(payment.getApiclientCert());
@@ -138,7 +138,10 @@ public class Order implements Serializable {
private String startTime; private String startTime;
@ApiModelProperty(value = "是否已开具发票:0未开发票,1已开发票,2不能开具发票") @ApiModelProperty(value = "是否已开具发票:0未开发票,1已开发票,2不能开具发票")
private Boolean isInvoice; private Integer isInvoice;
@ApiModelProperty(value = "发票流水号")
private String invoiceNo;
@ApiModelProperty(value = "支付时间") @ApiModelProperty(value = "支付时间")
private Date payTime; private Date payTime;
@@ -189,6 +189,7 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
// 微信小程序(微信支付) // 微信小程序(微信支付)
String key = "mp-weixin:".concat(order.getTenantId().toString()); String key = "mp-weixin:".concat(order.getTenantId().toString());
final String string = redisUtil.get(key); final String string = redisUtil.get(key);
System.out.println("string = " + string);
final JSONObject mpWx = JSONObject.parseObject(string); final JSONObject mpWx = JSONObject.parseObject(string);
System.out.println("mpWx = " + mpWx); System.out.println("mpWx = " + mpWx);
String key2 = "Payment:".concat(order.getPayType().toString()).concat(":").concat(order.getTenantId().toString()); String key2 = "Payment:".concat(order.getPayType().toString()).concat(":").concat(order.getTenantId().toString());
@@ -29,7 +29,7 @@ public class OrderTask extends BaseController {
/** /**
* 自动处理过期订单任务 * 自动处理过期订单任务
*/ */
@Scheduled(fixedDelay = 2000, initialDelay = 2000) // @Scheduled(fixedDelay = 2000, initialDelay = 2000)
@Transactional(rollbackFor = {Exception.class}) @Transactional(rollbackFor = {Exception.class})
public void settledExpirationOrder() { public void settledExpirationOrder() {
final OrderParam p = new OrderParam(); final OrderParam p = new OrderParam();