Merge branch 'test' of https://codeup.aliyun.com/zsmarter/sac/server/smarterFramework into test
This commit is contained in:
commit
6181876f6c
14
pom.xml
14
pom.xml
@ -174,6 +174,17 @@
|
||||
<version>${sf.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.smarterFramework</groupId>
|
||||
<artifactId>sf-payment</artifactId>
|
||||
<version>${sf.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.smarterFramework</groupId>
|
||||
<artifactId>sf-service</artifactId>
|
||||
<version>${sf.version}</version>
|
||||
</dependency>
|
||||
<!-- 通用工具-->
|
||||
<dependency>
|
||||
<groupId>com.smarterFramework</groupId>
|
||||
@ -214,6 +225,9 @@
|
||||
<module>sf-common</module>
|
||||
<module>sf-apijson</module>
|
||||
<module>sf-oauth</module>
|
||||
<module>sf-payment</module>
|
||||
<module>sf-service</module>
|
||||
<module>sf-order</module>
|
||||
</modules>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
|
@ -66,6 +66,21 @@
|
||||
<artifactId>sf-oauth</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.smarterFramework</groupId>
|
||||
<artifactId>sf-order</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.smarterFramework</groupId>
|
||||
<artifactId>sf-payment</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.smarterFramework</groupId>
|
||||
<artifactId>sf-service</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
@ -7,127 +7,147 @@ import com.sf.common.core.domain.BaseEntity;
|
||||
|
||||
/**
|
||||
* 应用列对象 APPLY_LIST_INFO
|
||||
*
|
||||
*
|
||||
* @author ztzh
|
||||
* @date 2024-04-11
|
||||
*/
|
||||
public class ApplyListInfo extends BaseEntity
|
||||
{
|
||||
public class ApplyListInfo extends BaseEntity {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 主键 */
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/** 应用名称 */
|
||||
/**
|
||||
* 应用code
|
||||
*/
|
||||
@Excel(name = "应用编号")
|
||||
private String appCode;
|
||||
/**
|
||||
* 应用名称
|
||||
*/
|
||||
@Excel(name = "应用名称")
|
||||
private String appName;
|
||||
|
||||
/** 应用描述 */
|
||||
/**
|
||||
* 应用描述
|
||||
*/
|
||||
@Excel(name = "应用描述")
|
||||
private String appDesc;
|
||||
|
||||
/** 图片 */
|
||||
/**
|
||||
* 图片
|
||||
*/
|
||||
@Excel(name = "图片")
|
||||
private String picture;
|
||||
|
||||
/** 排序 */
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
private Long orderNum;
|
||||
|
||||
/** 逻辑删除,0:未删除,1:删除 */
|
||||
/**
|
||||
* 逻辑删除,0:未删除,1:删除
|
||||
*/
|
||||
private Long isDelete;
|
||||
|
||||
/** 创建人 */
|
||||
/**
|
||||
* 创建人
|
||||
*/
|
||||
private String created;
|
||||
|
||||
/** 更新人 */
|
||||
/**
|
||||
* 更新人
|
||||
*/
|
||||
private String modified;
|
||||
|
||||
public void setId(Long id)
|
||||
{
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Long getId()
|
||||
{
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
public void setAppName(String appName)
|
||||
{
|
||||
|
||||
public void setAppName(String appName) {
|
||||
this.appName = appName;
|
||||
}
|
||||
|
||||
public String getAppName()
|
||||
{
|
||||
public String getAppName() {
|
||||
return appName;
|
||||
}
|
||||
public void setAppDesc(String appDesc)
|
||||
{
|
||||
|
||||
public void setAppDesc(String appDesc) {
|
||||
this.appDesc = appDesc;
|
||||
}
|
||||
|
||||
public String getAppDesc()
|
||||
{
|
||||
public String getAppDesc() {
|
||||
return appDesc;
|
||||
}
|
||||
public void setPicture(String picture)
|
||||
{
|
||||
|
||||
public void setPicture(String picture) {
|
||||
this.picture = picture;
|
||||
}
|
||||
|
||||
public String getPicture()
|
||||
{
|
||||
public String getPicture() {
|
||||
return picture;
|
||||
}
|
||||
public void setOrderNum(Long orderNum)
|
||||
{
|
||||
|
||||
public void setOrderNum(Long orderNum) {
|
||||
this.orderNum = orderNum;
|
||||
}
|
||||
|
||||
public Long getOrderNum()
|
||||
{
|
||||
public Long getOrderNum() {
|
||||
return orderNum;
|
||||
}
|
||||
public void setIsDelete(Long isDelete)
|
||||
{
|
||||
|
||||
public void setIsDelete(Long isDelete) {
|
||||
this.isDelete = isDelete;
|
||||
}
|
||||
|
||||
public Long getIsDelete()
|
||||
{
|
||||
public Long getIsDelete() {
|
||||
return isDelete;
|
||||
}
|
||||
public void setCreated(String created)
|
||||
{
|
||||
|
||||
public void setCreated(String created) {
|
||||
this.created = created;
|
||||
}
|
||||
|
||||
public String getCreated()
|
||||
{
|
||||
public String getCreated() {
|
||||
return created;
|
||||
}
|
||||
public void setModified(String modified)
|
||||
{
|
||||
|
||||
public void setModified(String modified) {
|
||||
this.modified = modified;
|
||||
}
|
||||
|
||||
public String getModified()
|
||||
{
|
||||
public String getModified() {
|
||||
return modified;
|
||||
}
|
||||
|
||||
public void setAppCode(String appCode) {
|
||||
this.appCode = appCode;
|
||||
}
|
||||
|
||||
public String getAppCode() {
|
||||
return appCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
||||
.append("id", getId())
|
||||
.append("appName", getAppName())
|
||||
.append("appDesc", getAppDesc())
|
||||
.append("picture", getPicture())
|
||||
.append("orderNum", getOrderNum())
|
||||
.append("isDelete", getIsDelete())
|
||||
.append("created", getCreated())
|
||||
.append("modified", getModified())
|
||||
.append("createTime", getCreateTime())
|
||||
.append("updateTime", getUpdateTime())
|
||||
.toString();
|
||||
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
|
||||
.append("id", getId())
|
||||
.append("appCode",getAppCode())
|
||||
.append("appName", getAppName())
|
||||
.append("appDesc", getAppDesc())
|
||||
.append("picture", getPicture())
|
||||
.append("orderNum", getOrderNum())
|
||||
.append("isDelete", getIsDelete())
|
||||
.append("created", getCreated())
|
||||
.append("modified", getModified())
|
||||
.append("createTime", getCreateTime())
|
||||
.append("updateTime", getUpdateTime())
|
||||
.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package com.sf.index.service.impl;
|
||||
|
||||
import java.util.List;
|
||||
import com.sf.common.utils.DateUtils;
|
||||
import com.sf.common.utils.uuid.IdUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.sf.index.mapper.ApplyListInfoMapper;
|
||||
@ -54,6 +55,7 @@ public class ApplyListInfoServiceImpl implements IApplyListInfoService
|
||||
public int insertApplyListInfo(ApplyListInfo applyListInfo)
|
||||
{
|
||||
applyListInfo.setCreateTime(DateUtils.getNowDate());
|
||||
applyListInfo.setAppCode(IdUtils.randomTime("ZT"));
|
||||
return applyListInfoMapper.insertApplyListInfo(applyListInfo);
|
||||
}
|
||||
|
||||
|
@ -1,367 +0,0 @@
|
||||
package com.sf.order.domain;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.sf.common.annotation.Excel;
|
||||
import com.sf.common.core.domain.BaseEntity;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 订单基础信息对象 ORDER_INFO
|
||||
*
|
||||
* @author ztzh
|
||||
* @date 2024-04-09
|
||||
*/
|
||||
public class OrderInfo extends BaseEntity {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 订单编号
|
||||
*/
|
||||
@Excel(name = "订单编号")
|
||||
private Long orderNo;
|
||||
|
||||
/**
|
||||
* 订单状态:
|
||||
* 0:待支付
|
||||
* 1:已付款
|
||||
* 2:支付超时系统结束
|
||||
* 3:已完成
|
||||
*/
|
||||
@Excel(name = "订单状态: 0:待支付 1:已付款 2:支付超时系统结束 3:已完成 ")
|
||||
private Long orderStatus;
|
||||
|
||||
/**
|
||||
* 支付方式:0-点券 1-现金
|
||||
*/
|
||||
@Excel(name = "支付方式:0-点券 1-现金")
|
||||
private Long payType;
|
||||
|
||||
/**
|
||||
* 支付渠道(支付方式为现金时)
|
||||
* 0:微信
|
||||
* 1:支付宝
|
||||
*/
|
||||
@Excel(name = "支付渠道(支付方式为现金时) 0:微信 1:支付宝")
|
||||
private Long payChannel;
|
||||
|
||||
/**
|
||||
* 订单金额
|
||||
*/
|
||||
@Excel(name = "订单金额")
|
||||
private Long orderAmt;
|
||||
|
||||
/**
|
||||
* 运费
|
||||
*/
|
||||
@Excel(name = "运费")
|
||||
private Long freightAmt;
|
||||
|
||||
/**
|
||||
* 总金额
|
||||
*/
|
||||
@Excel(name = "总金额")
|
||||
private Long payAmt;
|
||||
|
||||
/**
|
||||
* 实际支付金额
|
||||
*/
|
||||
@Excel(name = "实际支付金额")
|
||||
private Long reallyAmt;
|
||||
|
||||
/**
|
||||
* 收件方式
|
||||
* :0-自提
|
||||
* 1-快递 2-配送
|
||||
*/
|
||||
@Excel(name = "收件方式:0-自提 1-快递 2-配送")
|
||||
private Long receiveType;
|
||||
|
||||
/**
|
||||
* 商品Id
|
||||
*/
|
||||
@Excel(name = "商品Id")
|
||||
private Long goodsId;
|
||||
|
||||
/**
|
||||
* 商户Id
|
||||
*/
|
||||
@Excel(name = "商户Id")
|
||||
private Long businessId;
|
||||
|
||||
/**
|
||||
* 收货地址配置Id
|
||||
*/
|
||||
@Excel(name = "收货地址配置Id")
|
||||
private Long receiveAddrId;
|
||||
|
||||
/**
|
||||
* 支付时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
@Excel(name = "支付时间", width = 30, dateFormat = "yyyy-MM-dd")
|
||||
private Date payTime;
|
||||
|
||||
/**
|
||||
* 订单创建人
|
||||
*/
|
||||
@Excel(name = "订单创建人")
|
||||
private Long createUserId;
|
||||
|
||||
/**
|
||||
* 最后一次更新操作人
|
||||
*/
|
||||
@Excel(name = "最后一次更新操作人")
|
||||
private Long updateUserId;
|
||||
|
||||
/**
|
||||
* 逻辑删除标识
|
||||
* 0:未删除
|
||||
* 1:已删除
|
||||
*/
|
||||
@Excel(name = "逻辑删除标识 0:未删除 1:已删除")
|
||||
private Long isDelete;
|
||||
|
||||
/**
|
||||
* 快递单号
|
||||
*/
|
||||
@Excel(name = "快递单号")
|
||||
private String trackNo;
|
||||
|
||||
/**
|
||||
* 订单类型0:自动1:手动
|
||||
*/
|
||||
@Excel(name = "订单类型0:自动1:手动")
|
||||
private Long orderType;
|
||||
|
||||
/**
|
||||
* 平台外部订单号
|
||||
*/
|
||||
@Excel(name = "平台外部订单号")
|
||||
private Long outOrderNo;
|
||||
|
||||
/**
|
||||
* 平台支付返回值
|
||||
*/
|
||||
@Excel(name = "平台支付返回值")
|
||||
private String payData;
|
||||
|
||||
/**
|
||||
* 减免金额(优惠券抵扣)
|
||||
*/
|
||||
@Excel(name = "减免金额(优惠券抵扣)")
|
||||
private Long reductionAmout;
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setOrderNo(Long orderNo) {
|
||||
this.orderNo = orderNo;
|
||||
}
|
||||
|
||||
public Long getOrderNo() {
|
||||
return orderNo;
|
||||
}
|
||||
|
||||
public void setOrderStatus(Long orderStatus) {
|
||||
this.orderStatus = orderStatus;
|
||||
}
|
||||
|
||||
public Long getOrderStatus() {
|
||||
return orderStatus;
|
||||
}
|
||||
|
||||
public void setPayType(Long payType) {
|
||||
this.payType = payType;
|
||||
}
|
||||
|
||||
public Long getPayType() {
|
||||
return payType;
|
||||
}
|
||||
|
||||
public void setPayChannel(Long payChannel) {
|
||||
this.payChannel = payChannel;
|
||||
}
|
||||
|
||||
public Long getPayChannel() {
|
||||
return payChannel;
|
||||
}
|
||||
|
||||
public void setOrderAmt(Long orderAmt) {
|
||||
this.orderAmt = orderAmt;
|
||||
}
|
||||
|
||||
public Long getOrderAmt() {
|
||||
return orderAmt;
|
||||
}
|
||||
|
||||
public void setFreightAmt(Long freightAmt) {
|
||||
this.freightAmt = freightAmt;
|
||||
}
|
||||
|
||||
public Long getFreightAmt() {
|
||||
return freightAmt;
|
||||
}
|
||||
|
||||
public void setPayAmt(Long payAmt) {
|
||||
this.payAmt = payAmt;
|
||||
}
|
||||
|
||||
public Long getPayAmt() {
|
||||
return payAmt;
|
||||
}
|
||||
|
||||
public void setReallyAmt(Long reallyAmt) {
|
||||
this.reallyAmt = reallyAmt;
|
||||
}
|
||||
|
||||
public Long getReallyAmt() {
|
||||
return reallyAmt;
|
||||
}
|
||||
|
||||
public void setReceiveType(Long receiveType) {
|
||||
this.receiveType = receiveType;
|
||||
}
|
||||
|
||||
public Long getReceiveType() {
|
||||
return receiveType;
|
||||
}
|
||||
|
||||
public void setGoodsId(Long goodsId) {
|
||||
this.goodsId = goodsId;
|
||||
}
|
||||
|
||||
public Long getGoodsId() {
|
||||
return goodsId;
|
||||
}
|
||||
|
||||
public void setBusinessId(Long businessId) {
|
||||
this.businessId = businessId;
|
||||
}
|
||||
|
||||
public Long getBusinessId() {
|
||||
return businessId;
|
||||
}
|
||||
|
||||
public void setReceiveAddrId(Long receiveAddrId) {
|
||||
this.receiveAddrId = receiveAddrId;
|
||||
}
|
||||
|
||||
public Long getReceiveAddrId() {
|
||||
return receiveAddrId;
|
||||
}
|
||||
|
||||
public void setPayTime(Date payTime) {
|
||||
this.payTime = payTime;
|
||||
}
|
||||
|
||||
public Date getPayTime() {
|
||||
return payTime;
|
||||
}
|
||||
|
||||
public void setCreateUserId(Long createUserId) {
|
||||
this.createUserId = createUserId;
|
||||
}
|
||||
|
||||
public Long getCreateUserId() {
|
||||
return createUserId;
|
||||
}
|
||||
|
||||
public void setUpdateUserId(Long updateUserId) {
|
||||
this.updateUserId = updateUserId;
|
||||
}
|
||||
|
||||
public Long getUpdateUserId() {
|
||||
return updateUserId;
|
||||
}
|
||||
|
||||
public void setIsDelete(Long isDelete) {
|
||||
this.isDelete = isDelete;
|
||||
}
|
||||
|
||||
public Long getIsDelete() {
|
||||
return isDelete;
|
||||
}
|
||||
|
||||
public void setTrackNo(String trackNo) {
|
||||
this.trackNo = trackNo;
|
||||
}
|
||||
|
||||
public String getTrackNo() {
|
||||
return trackNo;
|
||||
}
|
||||
|
||||
public void setOrderType(Long orderType) {
|
||||
this.orderType = orderType;
|
||||
}
|
||||
|
||||
public Long getOrderType() {
|
||||
return orderType;
|
||||
}
|
||||
|
||||
public void setOutOrderNo(Long outOrderNo) {
|
||||
this.outOrderNo = outOrderNo;
|
||||
}
|
||||
|
||||
public Long getOutOrderNo() {
|
||||
return outOrderNo;
|
||||
}
|
||||
|
||||
public void setPayData(String payData) {
|
||||
this.payData = payData;
|
||||
}
|
||||
|
||||
public String getPayData() {
|
||||
return payData;
|
||||
}
|
||||
|
||||
public void setReductionAmout(Long reductionAmout) {
|
||||
this.reductionAmout = reductionAmout;
|
||||
}
|
||||
|
||||
public Long getReductionAmout() {
|
||||
return reductionAmout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
|
||||
.append("id", getId())
|
||||
.append("orderNo", getOrderNo())
|
||||
.append("orderStatus", getOrderStatus())
|
||||
.append("payType", getPayType())
|
||||
.append("payChannel", getPayChannel())
|
||||
.append("orderAmt", getOrderAmt())
|
||||
.append("freightAmt", getFreightAmt())
|
||||
.append("payAmt", getPayAmt())
|
||||
.append("reallyAmt", getReallyAmt())
|
||||
.append("receiveType", getReceiveType())
|
||||
.append("goodsId", getGoodsId())
|
||||
.append("businessId", getBusinessId())
|
||||
.append("receiveAddrId", getReceiveAddrId())
|
||||
.append("createTime", getCreateTime())
|
||||
.append("payTime", getPayTime())
|
||||
.append("createUserId", getCreateUserId())
|
||||
.append("updateUserId", getUpdateUserId())
|
||||
.append("isDelete", getIsDelete())
|
||||
.append("updateTime", getUpdateTime())
|
||||
.append("trackNo", getTrackNo())
|
||||
.append("orderType", getOrderType())
|
||||
.append("outOrderNo", getOutOrderNo())
|
||||
.append("payData", getPayData())
|
||||
.append("reductionAmout", getReductionAmout())
|
||||
.toString();
|
||||
}
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
package com.sf.order.domain.res;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 活动信息详情
|
||||
*
|
||||
*/
|
||||
@Data
|
||||
@Schema(name = "OrderListResVo", description = "订单列表")
|
||||
public class OrderListResVo {
|
||||
/**
|
||||
* 主键id
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 订单编号
|
||||
*/
|
||||
private String orderNo;
|
||||
|
||||
/**
|
||||
* 订单状态:
|
||||
* 0:待支付
|
||||
* 1:已付款
|
||||
* 2:支付超时系统结束
|
||||
* 3:已完成
|
||||
*/
|
||||
private Long orderStatus;
|
||||
|
||||
/**
|
||||
* 订单金额
|
||||
*/
|
||||
private Long orderAmt;
|
||||
|
||||
/**
|
||||
* 商品标题
|
||||
*/
|
||||
private String productTitle;
|
||||
/**
|
||||
* 图片
|
||||
*/
|
||||
private String productPicture;
|
||||
|
||||
/**
|
||||
* 商品规格
|
||||
*/
|
||||
private String goodsSpec;
|
||||
/**
|
||||
* 商品数量
|
||||
*/
|
||||
private Integer goodsCount = 1;
|
||||
|
||||
}
|
@ -96,7 +96,6 @@ public class CommonController
|
||||
return AjaxResult.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用上传请求(多个)
|
||||
*/
|
||||
|
@ -0,0 +1,117 @@
|
||||
package com.sf.web.controller.system;
|
||||
|
||||
import java.util.List;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.sf.common.utils.SecurityUtils;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.sf.common.annotation.Log;
|
||||
import com.sf.common.core.controller.BaseController;
|
||||
import com.sf.common.core.domain.AjaxResult;
|
||||
import com.sf.common.enums.BusinessType;
|
||||
import com.sf.system.domain.UserMember;
|
||||
import com.sf.system.service.IUserMemberService;
|
||||
import com.sf.common.utils.poi.ExcelUtil;
|
||||
import com.sf.common.core.page.TableDataInfo;
|
||||
|
||||
/**
|
||||
* 会员Controller
|
||||
*
|
||||
* @author ztzh
|
||||
* @date 2024-04-16
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/system/member")
|
||||
public class UserMemberController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private IUserMemberService userMemberService;
|
||||
|
||||
/**
|
||||
* 查询会员列表
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:member:list')")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(UserMember userMember)
|
||||
{
|
||||
startPage();
|
||||
List<UserMember> list = userMemberService.selectUserMemberList(userMember);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出会员列表
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:member:export')")
|
||||
@Log(title = "会员", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(HttpServletResponse response, UserMember userMember)
|
||||
{
|
||||
List<UserMember> list = userMemberService.selectUserMemberList(userMember);
|
||||
ExcelUtil<UserMember> util = new ExcelUtil<UserMember>(UserMember.class);
|
||||
util.exportExcel(response, list, "会员数据");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取会员详细信息
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:member:query')")
|
||||
@GetMapping(value = "/{id}")
|
||||
public AjaxResult getInfo(@PathVariable("id") Long id)
|
||||
{
|
||||
return success(userMemberService.selectUserMemberById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取会员详细信息,通过用户id
|
||||
* 当前用户
|
||||
*/
|
||||
@GetMapping(value = "/currentUser")
|
||||
public AjaxResult getInfoByUser()
|
||||
{
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
return success(userMemberService.selectUserMemberByUserId(userId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增会员
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:member:add')")
|
||||
@Log(title = "会员", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public AjaxResult add(@RequestBody UserMember userMember)
|
||||
{
|
||||
return toAjax(userMemberService.insertUserMember(userMember));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改会员
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:member:edit')")
|
||||
@Log(title = "会员", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public AjaxResult edit(@RequestBody UserMember userMember)
|
||||
{
|
||||
return toAjax(userMemberService.updateUserMember(userMember));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除会员
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:member:remove')")
|
||||
@Log(title = "会员", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{ids}")
|
||||
public AjaxResult remove(@PathVariable Long[] ids)
|
||||
{
|
||||
return toAjax(userMemberService.deleteUserMemberByIds(ids));
|
||||
}
|
||||
}
|
@ -137,10 +137,10 @@ file:
|
||||
defaultMaxSize: 52428800
|
||||
access:
|
||||
#key: iEJhVfZ8ColMeAnooVFx
|
||||
key: UVtE4aBgbzCfYthfCV9P
|
||||
key: CvproVoq7XiXDTK1RLFT
|
||||
secret:
|
||||
#key: SNTORcnq76xiaegoJ7Ap7Clldoq8HJUXqyn484o0
|
||||
key: 5rOuC0FPPrD2qEj2Eux4sGKKDgAKQ6dEatfLJOpZ
|
||||
key: dekJkBHBkO4HccNKsiqAC2mkeNxVKEWSRoll3yqp
|
||||
bucket:
|
||||
#name: ruoyi
|
||||
name: sc-device-manage
|
||||
name: sac
|
||||
|
20
sf-admin/src/main/resources/file/server.crt
Normal file
20
sf-admin/src/main/resources/file/server.crt
Normal file
@ -0,0 +1,20 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDSDCCAjACCQCvqL+z6dKTrjANBgkqhkiG9w0BAQsFADBmMQswCQYDVQQGEwJD
|
||||
TjERMA8GA1UECAwIc2hpY2h1YW4xEDAOBgNVBAcMB2NoZW5nZHUxEjAQBgNVBAoM
|
||||
CXpob25ndGlhbjEKMAgGA1UECwwBQjESMBAGA1UEAwwJemhvbmd0aWFuMB4XDTI0
|
||||
MDQxNzA2MjIxNloXDTI1MDQxNzA2MjIxNlowZjELMAkGA1UEBhMCQ04xETAPBgNV
|
||||
BAgMCHNoaWNodWFuMRAwDgYDVQQHDAdjaGVuZ2R1MRIwEAYDVQQKDAl6aG9uZ3Rp
|
||||
YW4xCjAIBgNVBAsMAUIxEjAQBgNVBAMMCXpob25ndGlhbjCCASIwDQYJKoZIhvcN
|
||||
AQEBBQADggEPADCCAQoCggEBAMIXQc0iVEuN/c8PnryNQYP3WbF6irqnjTbk/kCV
|
||||
552p30ZmdeRDGcFKdkohQLKT06sbqlaBzhGFpnLlb5iz1dG1sGZbw064RFZRlgED
|
||||
P7ROP891dvj9scPxfWC1Moy6/9LXBQLIshD7zTxzOemqxdyJ1jELianrWWm4XFKM
|
||||
jvl7BGcfS/VIEafrJ5WGzuRMKtf6SY8aD5Olu0sN61tnSIgjWwZnKkv4V764UBpN
|
||||
ybTsk1ctefUNMkE5Q+b2gu+0i5qH18B5/H5O7oAEAA+IWIPxIzuINnAYvHRhNQ/W
|
||||
LMaI/GhYpQMhlmXtOmFFFe3fL4fKRMCKa3x2Va/GzfPjwecCAwEAATANBgkqhkiG
|
||||
9w0BAQsFAAOCAQEAZmqK3ZfCA3A99VRfSRmCnpBbAW7SIxNeRqKFa5dunOMb7R6B
|
||||
+bV/ALLJmu8S5D7pSR/wqCGURmnetUnBAEQmYJsjSq3142PeADkr8NmZ9bOXBVNM
|
||||
szfSPOeM8HCUVjG9r+VMuy6yuPXFzp6QcKC13pzdziMdTHyKSu25fbYwE3lYOXk9
|
||||
4nLpnJeT09gecXPdGllrVTKkgkE7L7h4iX/QzsGiZ/JbrCD77nPFqr7fkepsrHjl
|
||||
4U1Pfjc3NStquhT5ZINDr7MBg/JaHNW57ynt1ud0y1lUOu2o5fpmyYVy/4llRl+T
|
||||
VJ6mJYXIWr+i10bVjNv2tGPEylmI1JHelYRqAQ==
|
||||
-----END CERTIFICATE-----
|
@ -6,6 +6,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
|
||||
<resultMap type="ApplyListInfo" id="ApplyListInfoResult">
|
||||
<result property="id" column="id" />
|
||||
<result property="appCode" column="app_code" />
|
||||
<result property="appName" column="app_name" />
|
||||
<result property="appDesc" column="app_desc" />
|
||||
<result property="picture" column="picture" />
|
||||
@ -18,7 +19,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectApplyListInfoVo">
|
||||
select id, app_name, app_desc, picture, order_num, is_delete, created, modified, create_time, update_time from APPLY_LIST_INFO
|
||||
select id, app_code, app_name, app_desc, picture, order_num, is_delete, created, modified, create_time, update_time from APPLY_LIST_INFO
|
||||
</sql>
|
||||
|
||||
<select id="selectApplyListInfoList" parameterType="ApplyListInfo" resultMap="ApplyListInfoResult">
|
||||
@ -36,6 +37,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<insert id="insertApplyListInfo" parameterType="ApplyListInfo" useGeneratedKeys="true" keyProperty="id">
|
||||
insert into APPLY_LIST_INFO
|
||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||
<if test="appCode != null and appCode != ''">app_code,</if>
|
||||
<if test="appName != null and appName != ''">app_name,</if>
|
||||
<if test="appDesc != null and appDesc != ''">app_desc,</if>
|
||||
<if test="picture != null">picture,</if>
|
||||
@ -47,6 +49,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<if test="updateTime != null">update_time,</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="appCode != null and appCode != ''">#{appCode},</if>
|
||||
<if test="appName != null and appName != ''">#{appName},</if>
|
||||
<if test="appDesc != null and appDesc != ''">#{appDesc},</if>
|
||||
<if test="picture != null">#{picture},</if>
|
||||
@ -62,6 +65,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<update id="updateApplyListInfo" parameterType="ApplyListInfo">
|
||||
update APPLY_LIST_INFO
|
||||
<trim prefix="SET" suffixOverrides=",">
|
||||
<if test="appCode != null and appCode != ''">app_code = #{appCode},</if>
|
||||
<if test="appName != null and appName != ''">app_name = #{appName},</if>
|
||||
<if test="appDesc != null and appDesc != ''">app_desc = #{appDesc},</if>
|
||||
<if test="picture != null">picture = #{picture},</if>
|
||||
|
@ -15,6 +15,12 @@
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- Spring框架基本的核心工具 -->
|
||||
<dependency>
|
||||
<groupId>commons-fileupload</groupId>
|
||||
<artifactId>commons-fileupload</artifactId>
|
||||
<version>1.4</version>
|
||||
</dependency>
|
||||
<!-- Spring框架基本的核心工具 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
|
@ -6,25 +6,27 @@ import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.fileupload.FileItem;
|
||||
import org.apache.commons.fileupload.FileItemFactory;
|
||||
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
import com.sf.common.config.SmarterFrameworkConfig;
|
||||
import com.sf.common.exception.ServiceException;
|
||||
import com.sf.common.utils.DateUtils;
|
||||
import com.sf.common.utils.StringUtils;
|
||||
import com.sf.common.utils.uuid.IdUtils;
|
||||
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.multipart.commons.CommonsMultipartFile;
|
||||
|
||||
/**
|
||||
* 文件处理工具类
|
||||
@ -295,5 +297,28 @@ public class FileUtils
|
||||
String baseName = FilenameUtils.getBaseName(fileName);
|
||||
return baseName;
|
||||
}
|
||||
/**
|
||||
* 根据OutputStream,生成文件
|
||||
*/
|
||||
public static MultipartFile outputToFile(ByteArrayOutputStream bos) throws IOException {
|
||||
try {
|
||||
// 文件输出流
|
||||
byte[] bytes = bos.toByteArray();
|
||||
|
||||
FileItemFactory factory = new DiskFileItemFactory(16, null);
|
||||
FileItem item = factory.createItem("file", "application/zip", false, "apk.zip");
|
||||
OutputStream os = item.getOutputStream();
|
||||
os.write(bytes);
|
||||
bos.flush();
|
||||
os.flush();
|
||||
|
||||
// MultipartFile
|
||||
MultipartFile file = new CommonsMultipartFile(item);
|
||||
return file;
|
||||
} catch (Exception e) {
|
||||
System.err.println("加载私钥失败");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
137
sf-common/src/main/java/com/sf/common/utils/file/ZipUtils.java
Normal file
137
sf-common/src/main/java/com/sf/common/utils/file/ZipUtils.java
Normal file
@ -0,0 +1,137 @@
|
||||
package com.sf.common.utils.file;
|
||||
|
||||
|
||||
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Enumeration;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
|
||||
/**
|
||||
* 压缩文件工具类
|
||||
*/
|
||||
public class ZipUtils {
|
||||
private ZipFile zipFile;
|
||||
private ZipOutputStream zipOut; //压缩Zip
|
||||
private ZipEntry zipEntry;
|
||||
private static int bufSize; //size of bytes
|
||||
private byte[] buf;
|
||||
private int readedBytes;
|
||||
|
||||
public ZipUtils() {
|
||||
this(512);
|
||||
}
|
||||
|
||||
public ZipUtils(int bufSize) {
|
||||
this.bufSize = bufSize;
|
||||
this.buf = new byte[this.bufSize];
|
||||
}
|
||||
|
||||
//压缩文件夹内的文件
|
||||
public void doZip(String zipDirectory) {//zipDirectoryPath:需要压缩的文件夹名
|
||||
File file;
|
||||
File zipDir;
|
||||
|
||||
zipDir = new File(zipDirectory);
|
||||
String zipFileName = zipDir.getName() + ".zip";//压缩后生成的zip文件名
|
||||
|
||||
try {
|
||||
this.zipOut = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(zipFileName)));
|
||||
handleDir(zipDir, this.zipOut);
|
||||
this.zipOut.close();
|
||||
} catch (IOException ioe) {
|
||||
ioe.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
//由doZip调用,递归完成目录文件读取
|
||||
public void handleDir(File dir, ZipOutputStream zipOut) throws IOException {
|
||||
FileInputStream fileIn;
|
||||
File[] files;
|
||||
|
||||
files = dir.listFiles();
|
||||
|
||||
if (files.length == 0) {//如果目录为空,则单独创建之.
|
||||
//ZipEntry的isDirectory()方法中,目录以"/"结尾.
|
||||
this.zipOut.putNextEntry(new ZipEntry(dir.toString() + "/"));
|
||||
this.zipOut.closeEntry();
|
||||
} else {//如果目录不为空,则分别处理目录和文件.
|
||||
for (File fileName : files) {
|
||||
//System.out.println(fileName);
|
||||
|
||||
if (fileName.isDirectory()) {
|
||||
handleDir(fileName, this.zipOut);
|
||||
} else {
|
||||
fileIn = new FileInputStream(fileName);
|
||||
this.zipOut.putNextEntry(new ZipEntry(fileName.toString()));
|
||||
|
||||
while ((this.readedBytes = fileIn.read(this.buf)) > 0) {
|
||||
this.zipOut.write(this.buf, 0, this.readedBytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void zip(ZipOutputStream zipOut, InputStream inputStream, String fileName) throws IOException {
|
||||
zipOut.putNextEntry(new ZipEntry(fileName));
|
||||
|
||||
int readBytes = 512;
|
||||
byte[] buf = new byte[readBytes];
|
||||
while ((readBytes = inputStream.read(buf)) > 0) {
|
||||
zipOut.write(buf, 0, readBytes);
|
||||
}
|
||||
zipOut.closeEntry();
|
||||
}
|
||||
|
||||
//解压指定zip文件
|
||||
public void unZip(String unZipfileName) {//unZipfileName需要解压的zip文件名
|
||||
FileOutputStream fileOut;
|
||||
File file;
|
||||
InputStream inputStream;
|
||||
|
||||
try {
|
||||
this.zipFile = new ZipFile(unZipfileName);
|
||||
|
||||
for (Enumeration entries = this.zipFile.entries(); entries.hasMoreElements(); ) {
|
||||
ZipEntry entry = (ZipEntry) entries.nextElement();
|
||||
file = new File(entry.getName());
|
||||
|
||||
if (entry.isDirectory()) {
|
||||
file.mkdirs();
|
||||
} else {
|
||||
//如果指定文件的目录不存在,则创建之.
|
||||
File parent = file.getParentFile();
|
||||
if (!parent.exists()) {
|
||||
parent.mkdirs();
|
||||
}
|
||||
|
||||
inputStream = zipFile.getInputStream(entry);
|
||||
|
||||
fileOut = new FileOutputStream(file);
|
||||
while ((this.readedBytes = inputStream.read(this.buf)) > 0) {
|
||||
fileOut.write(this.buf, 0, this.readedBytes);
|
||||
}
|
||||
fileOut.close();
|
||||
|
||||
inputStream.close();
|
||||
}
|
||||
}
|
||||
this.zipFile.close();
|
||||
} catch (IOException ioe) {
|
||||
ioe.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
//设置缓冲区大小
|
||||
public void setBufSize(int bufSize) {
|
||||
this.bufSize = bufSize;
|
||||
}
|
||||
}
|
@ -0,0 +1,112 @@
|
||||
package com.sf.common.utils.openssl;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
/**
|
||||
* Base64 加密解密工具类
|
||||
* @author XIHONGLEI
|
||||
* @date 2018-03-27
|
||||
*/
|
||||
public class Base64Utils {
|
||||
private static char[] base64EncodeChars = new char[]
|
||||
{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
|
||||
'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
|
||||
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5',
|
||||
'6', '7', '8', '9', '+', '/'};
|
||||
private static byte[] base64DecodeChars = new byte[]
|
||||
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53,
|
||||
54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
|
||||
12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29,
|
||||
30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1,
|
||||
-1, -1, -1};
|
||||
|
||||
public static String encode(byte[] data) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
int len = data.length;
|
||||
int i = 0;
|
||||
int b1, b2, b3;
|
||||
while (i < len) {
|
||||
b1 = data[i++] & 0xff;
|
||||
if (i == len) {
|
||||
sb.append(base64EncodeChars[b1 >>> 2]);
|
||||
sb.append(base64EncodeChars[(b1 & 0x3) << 4]);
|
||||
sb.append("==");
|
||||
break;
|
||||
}
|
||||
b2 = data[i++] & 0xff;
|
||||
if (i == len) {
|
||||
sb.append(base64EncodeChars[b1 >>> 2]);
|
||||
sb.append(base64EncodeChars[((b1 & 0x03) << 4) | ((b2 & 0xf0) >>> 4)]);
|
||||
sb.append(base64EncodeChars[(b2 & 0x0f) << 2]);
|
||||
sb.append("=");
|
||||
break;
|
||||
}
|
||||
b3 = data[i++] & 0xff;
|
||||
sb.append(base64EncodeChars[b1 >>> 2]);
|
||||
sb.append(base64EncodeChars[((b1 & 0x03) << 4) | ((b2 & 0xf0) >>> 4)]);
|
||||
sb.append(base64EncodeChars[((b2 & 0x0f) << 2) | ((b3 & 0xc0) >>> 6)]);
|
||||
sb.append(base64EncodeChars[b3 & 0x3f]);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static byte[] decode(String str) {
|
||||
try {
|
||||
return decodePrivate(str);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return new byte[]
|
||||
{};
|
||||
}
|
||||
|
||||
private static byte[] decodePrivate(String str) throws UnsupportedEncodingException {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
byte[] data = null;
|
||||
data = str.getBytes("US-ASCII");
|
||||
int len = data.length;
|
||||
int i = 0;
|
||||
int b1, b2, b3, b4;
|
||||
while (i < len) {
|
||||
do {
|
||||
b1 = base64DecodeChars[data[i++]];
|
||||
} while (i < len && b1 == -1);
|
||||
if (b1 == -1) {
|
||||
break;
|
||||
|
||||
}
|
||||
do {
|
||||
b2 = base64DecodeChars[data[i++]];
|
||||
} while (i < len && b2 == -1);
|
||||
if (b2 == -1) {
|
||||
break;
|
||||
}
|
||||
sb.append((char) ((b1 << 2) | ((b2 & 0x30) >>> 4)));
|
||||
|
||||
do {
|
||||
b3 = data[i++];
|
||||
if (b3 == 61) {
|
||||
return sb.toString().getBytes("iso8859-1");
|
||||
}
|
||||
b3 = base64DecodeChars[b3];
|
||||
} while (i < len && b3 == -1);
|
||||
if (b3 == -1) {
|
||||
break;
|
||||
}
|
||||
sb.append((char) (((b2 & 0x0f) << 4) | ((b3 & 0x3c) >>> 2)));
|
||||
do {
|
||||
b4 = data[i++];
|
||||
if (b4 == 61) {
|
||||
return sb.toString().getBytes("iso8859-1");
|
||||
}
|
||||
b4 = base64DecodeChars[b4];
|
||||
} while (i < len && b4 == -1);
|
||||
if (b4 == -1) {
|
||||
break;
|
||||
}
|
||||
sb.append((char) (((b3 & 0x03) << 6) | b4));
|
||||
}
|
||||
return sb.toString().getBytes("iso8859-1");
|
||||
}
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
package com.sf.common.utils.openssl;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* byte数组工具类实现byte[]与文件之间的相互转换
|
||||
* @author XIHONGLEI
|
||||
* @Date 2018-03-26
|
||||
*/
|
||||
public class ByteUtil {
|
||||
/**
|
||||
* 获得指定文件的byte数组
|
||||
*/
|
||||
public static byte[] getBytes(String filePath){
|
||||
byte[] buffer = null;
|
||||
try {
|
||||
File file = new File(filePath);
|
||||
FileInputStream fis = new FileInputStream(file);
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream(1000);
|
||||
byte[] b = new byte[1000];
|
||||
int n;
|
||||
while ((n = fis.read(b)) != -1) {
|
||||
bos.write(b, 0, n);
|
||||
}
|
||||
fis.close();
|
||||
bos.close();
|
||||
buffer = bos.toByteArray();
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据byte数组,生成文件
|
||||
*/
|
||||
public static void saveFile(byte[] bfile, String filePath,String fileName) {
|
||||
BufferedOutputStream bos = null;
|
||||
FileOutputStream fos = null;
|
||||
File file = null;
|
||||
try {
|
||||
File dir = new File(filePath);
|
||||
//判断文件目录是否存在
|
||||
if(!dir.exists()&&dir.isDirectory()){
|
||||
dir.mkdirs();
|
||||
}
|
||||
file = new File(filePath+"\\"+fileName);
|
||||
fos = new FileOutputStream(file);
|
||||
bos = new BufferedOutputStream(fos);
|
||||
bos.write(bfile);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (bos != null) {
|
||||
try {
|
||||
bos.close();
|
||||
} catch (IOException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (fos != null) {
|
||||
try {
|
||||
fos.close();
|
||||
} catch (IOException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,447 @@
|
||||
package com.sf.common.utils.openssl;
|
||||
|
||||
import cn.hutool.core.io.resource.ClassPathResource;
|
||||
import com.sf.common.utils.file.FileUtils;
|
||||
import com.sf.common.utils.file.ZipUtils;
|
||||
import com.sf.common.utils.sign.Sha265Utils;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.crypto.BadPaddingException;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.IllegalBlockSizeException;
|
||||
import javax.crypto.NoSuchPaddingException;
|
||||
import java.io.*;
|
||||
import java.security.*;
|
||||
import java.security.interfaces.RSAPrivateKey;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
/**
|
||||
* rsa加密
|
||||
*/
|
||||
@Component
|
||||
public class RsaSignUtil {
|
||||
|
||||
private static final String PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqvm+B2e3shKKN1PGXfTWGc7+gC+XnKvtZX/T9ADWtL7KvAqhAREtxcFRtPC9ONbEqSfHb53mUUJbmKrp5C1rFrWQahBP8mpFOtjoReOkqF/idbwAKtvOq5DIuQT7Wl7wgDdh4OvEWqnUaWvkV0qJNK/Cny1YL8R+DJrnlAiREQwIDAQAB";
|
||||
private static final String PRIVATE_KEY = "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDCF0HNIlRLjf3PD568jUGD91mxeoq6p4025P5Aleedqd9GZnXkQxnBSnZKIUCyk9OrG6pWgc4RhaZy5W+Ys9XRtbBmW8NOuERWUZYBAz+0Tj/PdXb4/bHD8X1gtTKMuv/S1wUCyLIQ+808cznpqsXcidYxC4mp61lpuFxSjI75ewRnH0v1SBGn6yeVhs7kTCrX+kmPGg+TpbtLDetbZ0iII1sGZypL+Fe+uFAaTcm07JNXLXn1DTJBOUPm9oLvtIuah9fAefx+Tu6ABAAPiFiD8SM7iDZwGLx0YTUP1izGiPxoWKUDIZZl7TphRRXt3y+HykTAimt8dlWvxs3z48HnAgMBAAECggEAMnoB7uuCqLOg0nzpd3f1FfD6LqID+k8g9qnPRdS2i9Zl7tUuy9J3nEFVSiojvU2cut9TCXRwtzXe9/qbb0c10HhEDBrJTGu3ugs1y8Wgh6/iAH44FsFDvgXL6Z62KstnRNoOv46aYLhbw+DjqtVy58whHFg30S0X79q2h/FuLYtQgju0I5yDMBVmbTmJKvhKtcATBUKnXxsAIMnc/BWXHNV9dg/Yfx1JDOqZqxFUsYmnMz5CatfGqnyc7AH1S0SFp4hIYsA1iPuEYDtFM8AAyP0PB4Z+buaG12xMF4S35OqDP0uhYpsh8/vQ28xqn0hAGsA1lAb792nZ5Qf/0WQGgQKBgQDuTNJdyIQN9Oa/DrQwDEPpyiurGBqY6ZvJHq1CpDy4AbMkIEYlVBnFPHCjyiWyW61MT80qMXyCQn3DLs5MsbB3rNZYItD9Tqmd5vkxD3B4zRneH1FQUuWR64lqM0fjFiy7+gfpn3tC5169ynn+u1oArwEnA577c93GHmr/P+I5FwKBgQDQgdCW8wTrLYLWrG7pg/VshWJX+J/8vGM8b2WPF52hIX7HhIouQjiwhAcMam0vwg0ZiPJH0Rw67PWrPxz1GOtfBwSXD74j/0QGdo/NwN8HxcXoGRFCb44KbDKj7r9xIwQ7eir93S7wb6FWzfzM4hcgQy6lZQO1wA1ld/n8GkOfsQKBgQDSZJUfJBgjUmQfr1W7TjjvwwWHC8L/2tEmYqVKP0M0mpuVe8Ey1+vgzhoNIj7iGDsLMzHK3OI3B4mNuFeAMynAn6KnMiYeX0M2HGVKwXzlyv/ZswDR0D7L9I7gauI/Rqa8WGaAB8SGL0zgeFH5a2RtUhXMYlANZiEZ+GUzcy3ChQKBgQCRtDV0Vox4X4xPwZ2b9we49xi7CtWaAneCUwHwVXtkjwiOGhOJseL1jr1yMqjsN7l5v5Y3E2ybzNz79xWgPPK1rCzL90dS1l3N+moRSRdR0iWzRFkoSNZEeEmG/x6uy954Ra3nSvozMH7ZLwbakZ/BftEI6ScHihaScp2xSxU4cQKBgQDANT+6d3E6aGT2oAdTxAdimcLEWZOVW9gkbX/UASEpTjEMDdr+MoPuKSPYxuMcWf/HksJF8rAVYJjklcIZHI1TF0Mm7RVrM+Kw3VzHR21jf7RNboBAAH+YeUH9yZg936iqO4Gi5wegUtttXgrxxG5rwi8iUXbbiC/xLVm0ldHW5Q==";
|
||||
public static MultipartFile signZip(MultipartFile file) throws Exception {
|
||||
RsaSignUtil rsaSignUtil = new RsaSignUtil();
|
||||
//初始化密钥
|
||||
try {
|
||||
rsaSignUtil.loadPrivateKey(PRIVATE_KEY);
|
||||
System.out.println("加载私钥成功");
|
||||
} catch (Exception e) {
|
||||
System.err.println(e.getMessage());
|
||||
System.err.println("加载私钥失败");
|
||||
}
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
ZipOutputStream out = new ZipOutputStream(outputStream);
|
||||
//放入文件
|
||||
ZipUtils.zip(out, new ByteArrayInputStream(file.getBytes()), file.getOriginalFilename());
|
||||
//放入签名
|
||||
String encrypt = Sha265Utils.encrypt(file.getBytes());
|
||||
ZipUtils.zip(out, new ByteArrayInputStream(rsaSignUtil.rsaSign(encrypt.getBytes(), rsaSignUtil.getPrivateKey())), "sign.signture");
|
||||
//放入证书
|
||||
ZipUtils.zip(out, new ByteArrayInputStream(new ClassPathResource("file/server.crt").readBytes()), "server.crt");
|
||||
outputStream.close();
|
||||
out.close();
|
||||
return FileUtils.outputToFile(outputStream);
|
||||
}
|
||||
/**
|
||||
* rsa签名
|
||||
* @param data 待签名的字符串
|
||||
* @param priKey rsa私钥字符串
|
||||
* @return 签名结果
|
||||
* @throws Exception 签名失败则抛出异常
|
||||
*/
|
||||
public byte[] rsaSign(byte[] data, RSAPrivateKey priKey) throws SignatureException {
|
||||
try {
|
||||
Signature signature = Signature.getInstance("SHA256withRSA");
|
||||
signature.initSign(priKey);
|
||||
signature.update(data);
|
||||
|
||||
byte[] signed = signature.sign();
|
||||
return signed;
|
||||
} catch (Exception e) {
|
||||
throw new SignatureException("RSAcontent = " + data
|
||||
+ "; charset = ", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* rsa验签
|
||||
*
|
||||
* @param data 被签名的内容
|
||||
* @param sign 签名后的结果
|
||||
* @param pubKey rsa公钥
|
||||
* @return 验签结果
|
||||
* @throws SignatureException 验签失败,则抛异常
|
||||
*/
|
||||
public boolean verify(byte[] data, byte[] sign, RSAPublicKey pubKey)
|
||||
throws SignatureException {
|
||||
try {
|
||||
Signature signature = Signature.getInstance("SHA512withRSA");
|
||||
signature.initVerify(pubKey);
|
||||
signature.update(data);
|
||||
return signature.verify(sign);
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new SignatureException("RSA验证签名[content = " + data
|
||||
+ "; charset = " + "; signature = " + sign + "]发生异常!", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 私钥
|
||||
*/
|
||||
private RSAPrivateKey privateKey;
|
||||
|
||||
/**
|
||||
* 公钥
|
||||
*/
|
||||
private RSAPublicKey publicKey;
|
||||
|
||||
/**
|
||||
* 字节数据转字符串专用集合
|
||||
*/
|
||||
private static final char[] HEX_CHAR = {'0', '1', '2', '3', '4', '5', '6',
|
||||
'7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
|
||||
|
||||
/**
|
||||
* 获取私钥
|
||||
*
|
||||
* @return 当前的私钥对象
|
||||
*/
|
||||
public RSAPrivateKey getPrivateKey() {
|
||||
return privateKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取公钥
|
||||
*
|
||||
* @return 当前的公钥对象
|
||||
*/
|
||||
public RSAPublicKey getPublicKey() {
|
||||
return publicKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* 随机生成密钥对
|
||||
*/
|
||||
public void genKeyPair() {
|
||||
KeyPairGenerator keyPairGen = null;
|
||||
try {
|
||||
keyPairGen = KeyPairGenerator.getInstance("RSA");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
keyPairGen.initialize(1024, new SecureRandom());
|
||||
KeyPair keyPair = keyPairGen.generateKeyPair();
|
||||
this.privateKey = (RSAPrivateKey) keyPair.getPrivate();
|
||||
this.publicKey = (RSAPublicKey) keyPair.getPublic();
|
||||
}
|
||||
|
||||
/**
|
||||
* 从.pem文件中取得私钥
|
||||
*
|
||||
* @param filePath 文件路径
|
||||
* @return 私钥
|
||||
*/
|
||||
public String getPrivateKeyFromFile(String filePath) {
|
||||
String strPrivateKey = "";
|
||||
try {
|
||||
BufferedReader privateKey = new BufferedReader(new FileReader(filePath));
|
||||
String line = "";
|
||||
while ((line = privateKey.readLine()) != null) {
|
||||
strPrivateKey += line;
|
||||
}
|
||||
privateKey.close();
|
||||
strPrivateKey = strPrivateKey.replace("-----BEGIN PRIVATE KEY-----", "").replace("-----END PRIVATE KEY-----", "");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return strPrivateKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从.pem文件中取得公钥
|
||||
*
|
||||
* @param filePath 文件路径
|
||||
* @return 公钥
|
||||
*/
|
||||
public String getPublicKeyFromFile(String filePath) {
|
||||
String strPublicKey = "";
|
||||
try {
|
||||
BufferedReader publicKey = new BufferedReader(new FileReader(filePath));
|
||||
String line = "";
|
||||
while ((line = publicKey.readLine()) != null) {
|
||||
strPublicKey += line;
|
||||
}
|
||||
publicKey.close();
|
||||
strPublicKey = strPublicKey.replace("-----BEGIN PUBLIC KEY-----", "").replace("-----END PUBLIC KEY-----", "");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return strPublicKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从字符串中加载公钥
|
||||
*
|
||||
* @param publicKeyStr 公钥数据字符串
|
||||
* @throws Exception 加载公钥时产生的异常
|
||||
*/
|
||||
public void loadPublicKey(String publicKeyStr) throws Exception {
|
||||
try {
|
||||
byte[] buffer = Base64Utils.decode(publicKeyStr);
|
||||
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
||||
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);
|
||||
this.publicKey = (RSAPublicKey) keyFactory.generatePublic(keySpec);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new Exception("无此算法");
|
||||
} catch (InvalidKeySpecException e) {
|
||||
throw new Exception("公钥非法");
|
||||
} catch (NullPointerException e) {
|
||||
throw new Exception("公钥数据为空");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载私钥
|
||||
*
|
||||
* @param privateKeyStr 私钥文件名
|
||||
* @return 是否成功
|
||||
* @throws Exception
|
||||
*/
|
||||
public void loadPrivateKey(String privateKeyStr) throws Exception {
|
||||
try {
|
||||
byte[] buffer = Base64Utils.decode(privateKeyStr);
|
||||
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer);
|
||||
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
||||
this.privateKey = (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new Exception("无此算法");
|
||||
} catch (InvalidKeySpecException e) {
|
||||
throw new Exception("私钥非法");
|
||||
} catch (NullPointerException e) {
|
||||
throw new Exception("私钥数据为空");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 加密过程
|
||||
*
|
||||
* @param publicKey 公钥
|
||||
* @param plainTextData 明文数据
|
||||
* @return
|
||||
* @throws Exception 加密过程中的异常信息
|
||||
*/
|
||||
public byte[] encrypt(RSAPublicKey publicKey, byte[] plainTextData)
|
||||
throws Exception {
|
||||
if (publicKey == null) {
|
||||
throw new Exception("加密公钥为空, 请设置");
|
||||
}
|
||||
Cipher cipher = null;
|
||||
try {
|
||||
cipher = Cipher.getInstance("RSA");
|
||||
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
|
||||
byte[] output = cipher.doFinal(plainTextData);
|
||||
return output;
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new Exception("无此加密算法");
|
||||
} catch (NoSuchPaddingException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
} catch (InvalidKeyException e) {
|
||||
throw new Exception("加密公钥非法,请检查");
|
||||
} catch (IllegalBlockSizeException e) {
|
||||
throw new Exception("明文长度非法");
|
||||
} catch (BadPaddingException e) {
|
||||
throw new Exception("明文数据已损坏");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解密过程
|
||||
*
|
||||
* @param privateKey 私钥
|
||||
* @param cipherData 密文数据
|
||||
* @return 明文
|
||||
* @throws Exception 解密过程中的异常信息
|
||||
*/
|
||||
public byte[] decrypt(RSAPrivateKey privateKey, byte[] cipherData)
|
||||
throws Exception {
|
||||
if (privateKey == null) {
|
||||
throw new Exception("解密私钥为空, 请设置");
|
||||
}
|
||||
Cipher cipher = null;
|
||||
try {
|
||||
cipher = Cipher.getInstance("RSA");
|
||||
cipher.init(Cipher.DECRYPT_MODE, privateKey);
|
||||
byte[] output = cipher.doFinal(cipherData);
|
||||
return output;
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new Exception("无此解密算法");
|
||||
} catch (NoSuchPaddingException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
} catch (InvalidKeyException e) {
|
||||
throw new Exception("解密私钥非法,请检查");
|
||||
} catch (IllegalBlockSizeException e) {
|
||||
throw new Exception("密文长度非法");
|
||||
} catch (BadPaddingException e) {
|
||||
throw new Exception("密文数据已损坏");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 字节数据转十六进制字符串
|
||||
*
|
||||
* @param data 输入数据
|
||||
* @return 十六进制内容
|
||||
*/
|
||||
public static String byteArrayToString(byte[] data) {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
// 取出字节的高四位 作为索引得到相应的十六进制标识符 注意无符号右移
|
||||
stringBuilder.append(HEX_CHAR[(data[i] & 0xf0) >>> 4]);
|
||||
// 取出字节的低四位 作为索引得到相应的十六进制标识符
|
||||
stringBuilder.append(HEX_CHAR[(data[i] & 0x0f)]);
|
||||
if (i < data.length - 1) {
|
||||
stringBuilder.append(' ');
|
||||
}
|
||||
}
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* btye转换hex函数
|
||||
*
|
||||
* @param byteArray
|
||||
* @return
|
||||
*/
|
||||
public static String byteToHex(byte[] byteArray) {
|
||||
StringBuffer strBuff = new StringBuffer();
|
||||
for (int i = 0; i < byteArray.length; i++) {
|
||||
if (Integer.toHexString(0xFF & byteArray[i]).length() == 1) {
|
||||
strBuff.append("0").append(
|
||||
Integer.toHexString(0xFF & byteArray[i]));
|
||||
} else {
|
||||
strBuff.append(Integer.toHexString(0xFF & byteArray[i]));
|
||||
}
|
||||
}
|
||||
return strBuff.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 以字节为单位读取文件,常用于读二进制文件,如图片、声音、影像等文件。
|
||||
*/
|
||||
public static byte[] readFileByBytes(String fileName) {
|
||||
File file = new File(fileName);
|
||||
InputStream in = null;
|
||||
byte[] txt = new byte[(int) file.length()];
|
||||
try {
|
||||
// 一次读一个字节
|
||||
in = new FileInputStream(file);
|
||||
int tempbyte;
|
||||
int i = 0;
|
||||
while ((tempbyte = in.read()) != -1) {
|
||||
txt[i] = (byte) tempbyte;
|
||||
i++;
|
||||
}
|
||||
in.close();
|
||||
return txt;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return txt;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// /**
|
||||
// * Main 测试方法
|
||||
// * @param args
|
||||
// */
|
||||
// public static void main(String[] args) throws FileNotFoundException, CertificateException {
|
||||
// RsaEncrypt rsaEncrypt = new RsaEncrypt();
|
||||
// try {
|
||||
// String publicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwhdBzSJUS439zw+evI1Bg/dZsXqKuqeNNuT+QJXnnanfRmZ15EMZwUp2SiFAspPTqxuqVoHOEYWmcuVvmLPV0bWwZlvDTrhEVlGWAQM/tE4/z3V2+P2xw/F9YLUyjLr/0tcFAsiyEPvNPHM56arF3InWMQuJqetZabhcUoyO+XsEZx9L9UgRp+snlYbO5Ewq1/pJjxoPk6W7Sw3rW2dIiCNbBmcqS/hXvrhQGk3JtOyTVy159Q0yQTlD5vaC77SLmofXwHn8fk7ugAQAD4hYg/EjO4g2cBi8dGE1D9Ysxoj8aFilAyGWZe06YUUV7d8vh8pEwIprfHZVr8bN8+PB5wIDAQAB";
|
||||
// rsaEncrypt.loadPublicKey(publicKey);
|
||||
// System.out.println("加载公钥成功");
|
||||
// } catch (Exception e) {
|
||||
// System.err.println(e.getMessage());
|
||||
// System.err.println("加载公钥失败");
|
||||
// }
|
||||
//
|
||||
// // 加载私钥
|
||||
// try {
|
||||
// String privateKey = "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDCF0HNIlRLjf3P\n" +
|
||||
// "D568jUGD91mxeoq6p4025P5Aleedqd9GZnXkQxnBSnZKIUCyk9OrG6pWgc4RhaZy\n" +
|
||||
// "5W+Ys9XRtbBmW8NOuERWUZYBAz+0Tj/PdXb4/bHD8X1gtTKMuv/S1wUCyLIQ+808\n" +
|
||||
// "cznpqsXcidYxC4mp61lpuFxSjI75ewRnH0v1SBGn6yeVhs7kTCrX+kmPGg+TpbtL\n" +
|
||||
// "DetbZ0iII1sGZypL+Fe+uFAaTcm07JNXLXn1DTJBOUPm9oLvtIuah9fAefx+Tu6A\n" +
|
||||
// "BAAPiFiD8SM7iDZwGLx0YTUP1izGiPxoWKUDIZZl7TphRRXt3y+HykTAimt8dlWv\n" +
|
||||
// "xs3z48HnAgMBAAECggEAMnoB7uuCqLOg0nzpd3f1FfD6LqID+k8g9qnPRdS2i9Zl\n" +
|
||||
// "7tUuy9J3nEFVSiojvU2cut9TCXRwtzXe9/qbb0c10HhEDBrJTGu3ugs1y8Wgh6/i\n" +
|
||||
// "AH44FsFDvgXL6Z62KstnRNoOv46aYLhbw+DjqtVy58whHFg30S0X79q2h/FuLYtQ\n" +
|
||||
// "gju0I5yDMBVmbTmJKvhKtcATBUKnXxsAIMnc/BWXHNV9dg/Yfx1JDOqZqxFUsYmn\n" +
|
||||
// "Mz5CatfGqnyc7AH1S0SFp4hIYsA1iPuEYDtFM8AAyP0PB4Z+buaG12xMF4S35OqD\n" +
|
||||
// "P0uhYpsh8/vQ28xqn0hAGsA1lAb792nZ5Qf/0WQGgQKBgQDuTNJdyIQN9Oa/DrQw\n" +
|
||||
// "DEPpyiurGBqY6ZvJHq1CpDy4AbMkIEYlVBnFPHCjyiWyW61MT80qMXyCQn3DLs5M\n" +
|
||||
// "sbB3rNZYItD9Tqmd5vkxD3B4zRneH1FQUuWR64lqM0fjFiy7+gfpn3tC5169ynn+\n" +
|
||||
// "u1oArwEnA577c93GHmr/P+I5FwKBgQDQgdCW8wTrLYLWrG7pg/VshWJX+J/8vGM8\n" +
|
||||
// "b2WPF52hIX7HhIouQjiwhAcMam0vwg0ZiPJH0Rw67PWrPxz1GOtfBwSXD74j/0QG\n" +
|
||||
// "do/NwN8HxcXoGRFCb44KbDKj7r9xIwQ7eir93S7wb6FWzfzM4hcgQy6lZQO1wA1l\n" +
|
||||
// "d/n8GkOfsQKBgQDSZJUfJBgjUmQfr1W7TjjvwwWHC8L/2tEmYqVKP0M0mpuVe8Ey\n" +
|
||||
// "1+vgzhoNIj7iGDsLMzHK3OI3B4mNuFeAMynAn6KnMiYeX0M2HGVKwXzlyv/ZswDR\n" +
|
||||
// "0D7L9I7gauI/Rqa8WGaAB8SGL0zgeFH5a2RtUhXMYlANZiEZ+GUzcy3ChQKBgQCR\n" +
|
||||
// "tDV0Vox4X4xPwZ2b9we49xi7CtWaAneCUwHwVXtkjwiOGhOJseL1jr1yMqjsN7l5\n" +
|
||||
// "v5Y3E2ybzNz79xWgPPK1rCzL90dS1l3N+moRSRdR0iWzRFkoSNZEeEmG/x6uy954\n" +
|
||||
// "Ra3nSvozMH7ZLwbakZ/BftEI6ScHihaScp2xSxU4cQKBgQDANT+6d3E6aGT2oAdT\n" +
|
||||
// "xAdimcLEWZOVW9gkbX/UASEpTjEMDdr+MoPuKSPYxuMcWf/HksJF8rAVYJjklcIZ\n" +
|
||||
// "HI1TF0Mm7RVrM+Kw3VzHR21jf7RNboBAAH+YeUH9yZg936iqO4Gi5wegUtttXgrx\n" +
|
||||
// "xG5rwi8iUXbbiC/xLVm0ldHW5Q==";
|
||||
// rsaEncrypt.loadPrivateKey(privateKey);
|
||||
// System.out.println("加载私钥成功");
|
||||
// } catch (Exception e) {
|
||||
// System.err.println(e.getMessage());
|
||||
// System.err.println("加载私钥失败");
|
||||
// }
|
||||
// //测试字符串
|
||||
// String encryptStr = "12321dsfasf1321312fsfdsafsdafasfsadf";
|
||||
// try {
|
||||
// System.out.println(new Date());
|
||||
// System.out.println(new Date());
|
||||
// // 加密
|
||||
// byte[] cipher = rsaEncrypt.encrypt(rsaEncrypt.getPublicKey(),
|
||||
// encryptStr.getBytes());
|
||||
// // 解密
|
||||
// byte[] plainText = rsaEncrypt.decrypt(rsaEncrypt.getPrivateKey(),
|
||||
// cipher);
|
||||
// System.out.println(new Date());
|
||||
// System.out.println(new String(plainText));
|
||||
// byte[] content = readFileByBytes("/Users/a1234/Documents/ca/demo.zip");
|
||||
// // 签名验证
|
||||
// byte[] signbyte = rsaEncrypt.rsaSign(content, rsaEncrypt.getPrivateKey());
|
||||
// System.out.println("签名-----:" + byteToHex(signbyte));
|
||||
// ByteUtil.saveFile(signbyte,"/Users/a1234/Documents/ca/","demo.zip.sign");
|
||||
// Boolean isok = rsaEncrypt.verify(content, signbyte, rsaEncrypt.getPublicKey());
|
||||
// System.out.println("验证:" + isok);
|
||||
//
|
||||
// // 读取验证文件
|
||||
// byte[] read = readFileByBytes("/Users/a1234/Documents/ca/demo.zip.sign");
|
||||
// System.out.println("读取签名文件:" + byteToHex(signbyte));
|
||||
// Boolean isfok = rsaEncrypt.verify(content, read, rsaEncrypt.getPublicKey());
|
||||
// System.out.println("文件验证2:" + isfok);
|
||||
//
|
||||
// } catch (Exception e) {
|
||||
// System.err.println(e.getMessage());
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package com.sf.common.utils.sign;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
|
||||
/**
|
||||
* Sha256加密方法
|
||||
*
|
||||
* @author ztzh
|
||||
*/
|
||||
public class Sha265Utils
|
||||
{
|
||||
private static final String SHA_256_ALGORITHM = "SHA-256";
|
||||
public static String encrypt(byte[] data) throws Exception {
|
||||
//获取SHA-256算法实例
|
||||
MessageDigest messageDigest = MessageDigest.getInstance(SHA_256_ALGORITHM);
|
||||
//计算散列值
|
||||
byte[] digest = messageDigest.digest(data);
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
//将byte数组转换为15进制字符串
|
||||
for (byte b : digest) {
|
||||
stringBuilder.append(Integer.toHexString((b & 0xFF) | 0x100).toUpperCase(), 1, 3);
|
||||
}
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
}
|
@ -2,48 +2,53 @@ package com.sf.common.utils.uuid;
|
||||
|
||||
/**
|
||||
* ID生成器工具类
|
||||
*
|
||||
*
|
||||
* @author ztzh
|
||||
*/
|
||||
public class IdUtils
|
||||
{
|
||||
public class IdUtils {
|
||||
/**
|
||||
* 获取随机UUID
|
||||
*
|
||||
*
|
||||
* @return 随机UUID
|
||||
*/
|
||||
public static String randomUUID()
|
||||
{
|
||||
public static String randomUUID() {
|
||||
return UUID.randomUUID().toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 简化的UUID,去掉了横线
|
||||
*
|
||||
*
|
||||
* @return 简化的UUID,去掉了横线
|
||||
*/
|
||||
public static String simpleUUID()
|
||||
{
|
||||
public static String simpleUUID() {
|
||||
return UUID.randomUUID().toString(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取随机UUID,使用性能更好的ThreadLocalRandom生成UUID
|
||||
*
|
||||
*
|
||||
* @return 随机UUID
|
||||
*/
|
||||
public static String fastUUID()
|
||||
{
|
||||
public static String fastUUID() {
|
||||
return UUID.fastUUID().toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 简化的UUID,去掉了横线,使用性能更好的ThreadLocalRandom生成UUID
|
||||
*
|
||||
*
|
||||
* @return 简化的UUID,去掉了横线
|
||||
*/
|
||||
public static String fastSimpleUUID()
|
||||
{
|
||||
public static String fastSimpleUUID() {
|
||||
return UUID.fastUUID().toString(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成一个由时间错与字母组成的唯一id
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String randomTime(String data) {
|
||||
long uniqueID = System.currentTimeMillis();
|
||||
return data + "_" + uniqueID;
|
||||
}
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ public class SysOssController extends BaseController
|
||||
*
|
||||
* @param file 文件
|
||||
*/
|
||||
//@PreAuthorize("@ss.hasPermi('system:oss:upload')")
|
||||
@PreAuthorize("@ss.hasPermi('system:oss:upload')")
|
||||
@Log(title = "OSS对象存储", businessType = BusinessType.INSERT)
|
||||
@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
||||
public R<SysOss> upload(@RequestPart("file") MultipartFile file) {
|
||||
@ -136,6 +136,23 @@ public class SysOssController extends BaseController
|
||||
throw new FileSizeLimitExceededException(defaultMaxSize / 1024 / 1024);
|
||||
}
|
||||
SysOss oss = sysOssService.upload(file);
|
||||
oss.setSize(file.getSize());
|
||||
return R.ok(oss);
|
||||
}
|
||||
|
||||
|
||||
@Log(title = "OSS对象存储", businessType = BusinessType.INSERT)
|
||||
@PostMapping(value = "/zip/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
||||
public R<SysOss> zipUpload(@RequestPart("file") MultipartFile file) throws Exception {
|
||||
if (ObjectUtil.isNull(file)) {
|
||||
throw new ServiceException("上传文件不能为空");
|
||||
}
|
||||
long size = file.getSize();
|
||||
if (size > defaultMaxSize) {
|
||||
throw new FileSizeLimitExceededException(defaultMaxSize / 1024 / 1024);
|
||||
}
|
||||
SysOss oss = sysOssService.uploadSignZip(file);
|
||||
oss.setSize(file.getSize());
|
||||
return R.ok(oss);
|
||||
}
|
||||
|
||||
|
@ -47,6 +47,10 @@ public class SysOss extends BaseEntity
|
||||
@Excel(name = "服务商")
|
||||
private String service;
|
||||
|
||||
/** 文件大小 */
|
||||
@Excel(name = "文件大小")
|
||||
private Long size;
|
||||
|
||||
public void setId(String id)
|
||||
{
|
||||
this.id = id;
|
||||
@ -119,6 +123,13 @@ public class SysOss extends BaseEntity
|
||||
{
|
||||
return service;
|
||||
}
|
||||
public Long getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public void setSize(Long size) {
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
@ -135,6 +146,7 @@ public class SysOss extends BaseEntity
|
||||
.append("updateTime", getUpdateTime())
|
||||
.append("updateBy", getUpdateBy())
|
||||
.append("service", getService())
|
||||
.append("size",getSize())
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
package com.sf.file.service;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
@ -69,4 +71,6 @@ public interface ISysOssService {
|
||||
SysOss upload(File file);
|
||||
|
||||
void download(String ossId, HttpServletResponse response) throws Exception;
|
||||
|
||||
SysOss uploadSignZip(MultipartFile file) throws Exception;
|
||||
}
|
||||
|
@ -1,13 +1,12 @@
|
||||
package com.sf.file.service.impl;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.io.*;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.sf.common.utils.openssl.RsaSignUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
@ -162,6 +161,10 @@ public class SysOssServiceImpl implements ISysOssService {
|
||||
throw new ServiceException(e.getMessage());
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public SysOss uploadSignZip(MultipartFile file) throws Exception {
|
||||
return upload(RsaSignUtil.signZip(file));
|
||||
}
|
||||
|
||||
public UploadResult uploadSuffix(File file, String suffix) {
|
||||
return upload(file, getPath(null, suffix));
|
||||
|
@ -72,6 +72,18 @@
|
||||
<groupId>com.smarterFramework</groupId>
|
||||
<artifactId>sf-common</artifactId>
|
||||
</dependency>
|
||||
<!-- swagger3-->
|
||||
<dependency>
|
||||
<groupId>io.springfox</groupId>
|
||||
<artifactId>springfox-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 防止进入swagger页面报类型转换错误,排除3.0.0中的引用,手动增加1.6.2版本 -->
|
||||
<dependency>
|
||||
<groupId>io.swagger</groupId>
|
||||
<artifactId>swagger-models</artifactId>
|
||||
<version>1.6.2</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
33
sf-order/pom.xml
Normal file
33
sf-order/pom.xml
Normal file
@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>smarterFramework</artifactId>
|
||||
<groupId>com.smarterFramework</groupId>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>sf-order</artifactId>
|
||||
|
||||
<description>
|
||||
订单模块
|
||||
</description>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- 通用工具-->
|
||||
<dependency>
|
||||
<groupId>com.smarterFramework</groupId>
|
||||
<artifactId>sf-common</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.smarterFramework</groupId>
|
||||
<artifactId>sf-framework</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
@ -3,17 +3,14 @@ package com.sf.order.controller;
|
||||
import com.sf.common.annotation.Log;
|
||||
import com.sf.common.core.controller.BaseController;
|
||||
import com.sf.common.core.domain.AjaxResult;
|
||||
import com.sf.common.core.domain.entity.SysUser;
|
||||
import com.sf.common.core.page.TableDataInfo;
|
||||
import com.sf.common.enums.BusinessType;
|
||||
import com.sf.common.utils.SecurityUtils;
|
||||
import com.sf.common.utils.poi.ExcelUtil;
|
||||
import com.sf.order.domain.OrderInfo;
|
||||
import com.sf.order.domain.dto.OrderCreateDto;
|
||||
import com.sf.order.domain.req.OrderListReqVo;
|
||||
import com.sf.order.domain.res.OrderListResVo;
|
||||
import com.sf.order.service.IOrderInfoService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@ -39,10 +36,7 @@ public class OrderInfoController extends BaseController {
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(OrderListReqVo vo) {
|
||||
startPage();
|
||||
SysUser user = SecurityUtils.getLoginUser().getUser();
|
||||
vo.setUserId(user.getUserId());
|
||||
List<OrderListResVo> list = orderInfoService.queryList(vo);
|
||||
logger.info("prderList"+list);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
@ -72,7 +66,7 @@ public class OrderInfoController extends BaseController {
|
||||
@Log(title = "创建订单基础信息", businessType = BusinessType.INSERT)
|
||||
@PostMapping(value = "/createOrder")
|
||||
public AjaxResult createOrder(@RequestBody OrderCreateDto orderCreateDto) {
|
||||
return toAjax(orderInfoService.createOrder(orderCreateDto));
|
||||
return AjaxResult.success(orderInfoService.createOrder(orderCreateDto));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -87,7 +81,6 @@ public class OrderInfoController extends BaseController {
|
||||
/**
|
||||
* 支付订单
|
||||
*/
|
||||
@Operation(summary = "支付订单")
|
||||
@PostMapping(value = "/pay/{orderId}")
|
||||
private String orderPay(@PathVariable(value = "orderId") Long orderId) {
|
||||
orderInfoService.orderPay(orderId);
|
183
sf-order/src/main/java/com/sf/order/domain/OrderInfo.java
Normal file
183
sf-order/src/main/java/com/sf/order/domain/OrderInfo.java
Normal file
@ -0,0 +1,183 @@
|
||||
package com.sf.order.domain;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.sf.common.annotation.Excel;
|
||||
import com.sf.common.core.domain.BaseEntity;
|
||||
import lombok.Data;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 订单基础信息对象 ORDER_INFO
|
||||
*
|
||||
* @author ztzh
|
||||
* @date 2024-04-09
|
||||
*/
|
||||
@Data
|
||||
public class OrderInfo extends BaseEntity {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 订单编号
|
||||
*/
|
||||
@Excel(name = "订单编号")
|
||||
private Long orderNo;
|
||||
|
||||
/**
|
||||
* 订单状态: 0:待支付 1:已付款待发货 2:配送中 3:待取货 4:支付超时系统结束 5:客户自主取消 6:已完成
|
||||
*/
|
||||
@Excel(name = "订单状态: 0:待支付 1:已付款待发货 2:配送中 3:待取货 4:支付超时系统结束 5:客户自主取消 6:已完成 ")
|
||||
private Long orderStatus;
|
||||
|
||||
/**
|
||||
* 支付方式:0-点券 1-现金
|
||||
*/
|
||||
@Excel(name = "支付方式:0-点券 1-现金")
|
||||
private Long payType;
|
||||
|
||||
/**
|
||||
* 支付渠道(支付方式为现金时)
|
||||
* 0:微信
|
||||
* 1:支付宝
|
||||
*/
|
||||
@Excel(name = "支付渠道(支付方式为现金时) 0:微信 1:支付宝")
|
||||
private Long payChannel;
|
||||
|
||||
/**
|
||||
* 订单金额
|
||||
*/
|
||||
@Excel(name = "订单金额")
|
||||
private Long orderAmt;
|
||||
|
||||
/**
|
||||
* 运费
|
||||
*/
|
||||
@Excel(name = "运费")
|
||||
private Long freightAmt;
|
||||
|
||||
/**
|
||||
* 总金额
|
||||
*/
|
||||
@Excel(name = "总金额")
|
||||
private Long payAmt;
|
||||
|
||||
/**
|
||||
* 实际支付金额
|
||||
*/
|
||||
@Excel(name = "实际支付金额")
|
||||
private Long reallyAmt;
|
||||
|
||||
/**
|
||||
* 收件方式
|
||||
* :0-自提
|
||||
* 1-快递 2-配送
|
||||
*/
|
||||
@Excel(name = "收件方式:0-自提 1-快递 2-配送")
|
||||
private Long receiveType;
|
||||
|
||||
/**
|
||||
* 商品Id
|
||||
*/
|
||||
@Excel(name = "商品Id")
|
||||
private Long goodsId;
|
||||
|
||||
/**
|
||||
* 商户Id
|
||||
*/
|
||||
@Excel(name = "商户Id")
|
||||
private Long businessId;
|
||||
|
||||
/**
|
||||
* 收货地址配置Id
|
||||
*/
|
||||
@Excel(name = "收货地址配置Id")
|
||||
private Long receiveAddrId;
|
||||
|
||||
/**
|
||||
* 支付时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@Excel(name = "支付时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date payTime;
|
||||
|
||||
/**
|
||||
* 订单创建人
|
||||
*/
|
||||
@Excel(name = "订单创建人")
|
||||
private Long createUserId;
|
||||
|
||||
/**
|
||||
* 最后一次更新操作人
|
||||
*/
|
||||
@Excel(name = "最后一次更新操作人")
|
||||
private Long updateUserId;
|
||||
|
||||
/**
|
||||
* 逻辑删除标识
|
||||
* 0:未删除
|
||||
* 1:已删除
|
||||
*/
|
||||
@Excel(name = "逻辑删除标识 0:未删除 1:已删除")
|
||||
private Long isDelete;
|
||||
|
||||
/**
|
||||
* 快递单号
|
||||
*/
|
||||
@Excel(name = "快递单号")
|
||||
private String trackNo;
|
||||
|
||||
/**
|
||||
* 订单类型0:自动1:手动
|
||||
*/
|
||||
@Excel(name = "订单类型0:自动1:手动")
|
||||
private Long orderType;
|
||||
|
||||
/**
|
||||
* 平台外部订单号
|
||||
*/
|
||||
@Excel(name = "平台外部订单号")
|
||||
private String outOrderNo;
|
||||
|
||||
/**
|
||||
* 平台支付返回值
|
||||
*/
|
||||
@Excel(name = "平台支付返回值")
|
||||
private String payData;
|
||||
|
||||
/**
|
||||
* 减免金额(优惠券抵扣)
|
||||
*/
|
||||
@Excel(name = "减免金额(优惠券抵扣)")
|
||||
private Long reductionAmout;
|
||||
|
||||
/**
|
||||
* * 商品数量
|
||||
*/
|
||||
private Integer goodsCount;
|
||||
/**
|
||||
* * 商品类型。
|
||||
* * • 0:消耗型商品
|
||||
* * • 1:非消耗型商品
|
||||
* * • 2:自动续期订阅商品
|
||||
*/
|
||||
private Integer goodsType;
|
||||
|
||||
/**
|
||||
* 商品单价
|
||||
*/
|
||||
private Long goodsPrice;
|
||||
|
||||
/**
|
||||
* 商品编号
|
||||
*/
|
||||
private String goodsCode;
|
||||
|
||||
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package com.sf.order.domain.dto;
|
||||
|
||||
import com.sf.common.annotation.Excel;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
@ -15,12 +16,13 @@ public class OrderCreateDto {
|
||||
@NotNull(message = "商品id不能为空")
|
||||
private Long goodsId;
|
||||
|
||||
@Schema(description = "平台外部订单号")
|
||||
private String outOrderNo;
|
||||
|
||||
@Schema(description = "数量")
|
||||
@NotNull(message = "数量不能唯恐")
|
||||
private Long count;
|
||||
|
||||
@Schema(description = "金额")
|
||||
@NotNull(message = "金额不能为空")
|
||||
private Long amount;
|
||||
|
||||
@Schema(description = "用户id")
|
||||
@ -56,4 +58,12 @@ public class OrderCreateDto {
|
||||
public void setUserId(Long userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public String getOutOrderNo() {
|
||||
return outOrderNo;
|
||||
}
|
||||
|
||||
public void setOutOrderNo(String outOrderNo) {
|
||||
this.outOrderNo = outOrderNo;
|
||||
}
|
||||
}
|
@ -14,7 +14,7 @@ public class OrderListReqVo extends BaseEntity {
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 订单类型
|
||||
* 订单状态
|
||||
*/
|
||||
private Long orderStatus;
|
||||
|
@ -0,0 +1,93 @@
|
||||
package com.sf.order.domain.res;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.sf.common.annotation.Excel;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 活动信息详情
|
||||
*
|
||||
*/
|
||||
@Data
|
||||
@Schema(name = "OrderListResVo", description = "订单列表")
|
||||
public class OrderListResVo {
|
||||
/**
|
||||
* 主键id
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 订单编号
|
||||
*/
|
||||
private String orderNo;
|
||||
|
||||
/**
|
||||
* 订单状态: 0:待支付 1:已付款待发货 2:配送中 3:待取货 4:支付超时系统结束 5:客户自主取消 6:已完成
|
||||
*/
|
||||
private Long orderStatus;
|
||||
|
||||
/**
|
||||
* 订单金额
|
||||
*/
|
||||
private Long orderAmt;
|
||||
|
||||
/**
|
||||
* 支付时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date payTime;
|
||||
|
||||
/**
|
||||
* 订阅订单取消时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date subscriptionCancellationTime;
|
||||
|
||||
/**
|
||||
* 商品标题
|
||||
*/
|
||||
private String productTitle;
|
||||
/**
|
||||
* 图片
|
||||
*/
|
||||
private String productPicture;
|
||||
|
||||
/**
|
||||
* 商品描述
|
||||
*/
|
||||
private String productDesc;
|
||||
|
||||
|
||||
/**
|
||||
* 商品规格
|
||||
*/
|
||||
private String goodsSpec;
|
||||
|
||||
/**
|
||||
* 商品数量
|
||||
*/
|
||||
private Integer goodsCount;
|
||||
|
||||
/**
|
||||
* 商品价格
|
||||
*/
|
||||
private Long goodsPrice;
|
||||
|
||||
/**
|
||||
* * 商品类型。
|
||||
* * • 0:消耗型商品
|
||||
* * • 1:非消耗型商品
|
||||
* * • 2:自动续期订阅商品
|
||||
*/
|
||||
private Integer goodsType;
|
||||
|
||||
/**
|
||||
* 商品编码
|
||||
*/
|
||||
private String goodsCode;
|
||||
|
||||
|
||||
}
|
@ -64,4 +64,6 @@ public interface OrderInfoMapper {
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteOrderInfoByIds(Long[] ids);
|
||||
|
||||
OrderInfo selectOrderInfoByOrderNo(String orderNo);
|
||||
}
|
@ -43,7 +43,7 @@ public interface IOrderInfoService
|
||||
* @param orderInfo 订单基础信息
|
||||
* @return 结果
|
||||
*/
|
||||
public int createOrder(OrderCreateDto orderInfo);
|
||||
public Long createOrder(OrderCreateDto orderInfo);
|
||||
|
||||
/**
|
||||
* 修改订单基础信息
|
||||
@ -70,4 +70,9 @@ public interface IOrderInfoService
|
||||
public int deleteOrderInfoById(Long id);
|
||||
|
||||
void orderPay(Long orderId);
|
||||
|
||||
OrderInfo selectOrderInfoByOrderNo(String orderNo);
|
||||
|
||||
void insertOrder(OrderInfo orderInfo);
|
||||
|
||||
}
|
@ -21,8 +21,7 @@ import java.util.List;
|
||||
* @date 2024-04-09
|
||||
*/
|
||||
@Service
|
||||
public class OrderInfoServiceImpl implements IOrderInfoService
|
||||
{
|
||||
public class OrderInfoServiceImpl implements IOrderInfoService {
|
||||
@Resource
|
||||
private OrderInfoMapper orderInfoMapper;
|
||||
@Resource
|
||||
@ -35,8 +34,7 @@ public class OrderInfoServiceImpl implements IOrderInfoService
|
||||
* @return 订单基础信息
|
||||
*/
|
||||
@Override
|
||||
public OrderInfo selectOrderInfoById(Long id)
|
||||
{
|
||||
public OrderInfo selectOrderInfoById(Long id) {
|
||||
return orderInfoMapper.selectOrderInfoById(id);
|
||||
}
|
||||
|
||||
@ -47,12 +45,11 @@ public class OrderInfoServiceImpl implements IOrderInfoService
|
||||
* @return 订单基础信息
|
||||
*/
|
||||
@Override
|
||||
public List<OrderInfo> selectOrderInfoList(OrderInfo orderInfo)
|
||||
{
|
||||
public List<OrderInfo> selectOrderInfoList(OrderInfo orderInfo) {
|
||||
return orderInfoMapper.selectOrderInfoList(orderInfo);
|
||||
}
|
||||
public List<OrderListResVo> queryList(OrderListReqVo vo)
|
||||
{
|
||||
|
||||
public List<OrderListResVo> queryList(OrderListReqVo vo) {
|
||||
return orderInfoMapper.queryList(vo);
|
||||
}
|
||||
|
||||
@ -63,11 +60,10 @@ public class OrderInfoServiceImpl implements IOrderInfoService
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int createOrder(OrderCreateDto orderCreateDto)
|
||||
{
|
||||
public Long createOrder(OrderCreateDto orderCreateDto) {
|
||||
OrderInfo orderInfo = new OrderInfo();
|
||||
orderInfo.setOrderNo(snowflakeIdWorker.nextId());
|
||||
orderInfo.setPayType(0L);
|
||||
orderInfo.setPayType(1L);
|
||||
orderInfo.setReceiveType(0L);
|
||||
orderInfo.setOrderStatus(0L);
|
||||
orderInfo.setCreateUserId(orderCreateDto.getUserId());
|
||||
@ -77,7 +73,9 @@ public class OrderInfoServiceImpl implements IOrderInfoService
|
||||
orderInfo.setPayAmt(orderCreateDto.getAmount());
|
||||
orderInfo.setCreateTime(DateUtils.getNowDate());
|
||||
orderInfo.setUpdateTime(DateUtils.getNowDate());
|
||||
return orderInfoMapper.insertOrderInfo(orderInfo);
|
||||
orderInfo.setOutOrderNo(orderCreateDto.getOutOrderNo());
|
||||
orderInfoMapper.insertOrderInfo(orderInfo);
|
||||
return snowflakeIdWorker.nextId();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -87,11 +85,11 @@ public class OrderInfoServiceImpl implements IOrderInfoService
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int updateOrderInfo(OrderInfo orderInfo)
|
||||
{
|
||||
public int updateOrderInfo(OrderInfo orderInfo) {
|
||||
orderInfo.setUpdateTime(DateUtils.getNowDate());
|
||||
return orderInfoMapper.updateOrderInfo(orderInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void orderPay(Long orderId) {
|
||||
OrderInfo updateOrder = this.selectOrderInfoById(orderId);
|
||||
@ -104,11 +102,22 @@ public class OrderInfoServiceImpl implements IOrderInfoService
|
||||
updateOrder.setOrderStatus(1L);
|
||||
updateOrder.setPayTime(DateUtils.getNowDate());
|
||||
// 修改订单状态
|
||||
if (1>this.updateOrderInfo(updateOrder)) {
|
||||
if (1 > this.updateOrderInfo(updateOrder)) {
|
||||
throw new ServiceException("支付异常,请联系管理员!");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OrderInfo selectOrderInfoByOrderNo(String orderNo) {
|
||||
|
||||
return orderInfoMapper.selectOrderInfoByOrderNo(orderNo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertOrder(OrderInfo orderInfo) {
|
||||
orderInfoMapper.insertOrderInfo(orderInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除订单基础信息
|
||||
*
|
||||
@ -116,8 +125,7 @@ public class OrderInfoServiceImpl implements IOrderInfoService
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int deleteOrderInfoByIds(Long[] ids)
|
||||
{
|
||||
public int deleteOrderInfoByIds(Long[] ids) {
|
||||
return orderInfoMapper.deleteOrderInfoByIds(ids);
|
||||
}
|
||||
|
||||
@ -128,8 +136,7 @@ public class OrderInfoServiceImpl implements IOrderInfoService
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int deleteOrderInfoById(Long id)
|
||||
{
|
||||
public int deleteOrderInfoById(Long id) {
|
||||
return orderInfoMapper.deleteOrderInfoById(id);
|
||||
}
|
||||
|
@ -35,18 +35,24 @@
|
||||
<result property="orderNo" column="order_no" />
|
||||
<result property="orderStatus" column="order_status" />
|
||||
<result property="orderAmt" column="order_amt" />
|
||||
<result property="payTime" column="pay_time" />
|
||||
<result property="productTitle" column="product_title" />
|
||||
<result property="productPicture" column="product_picture" />
|
||||
<result property="productDesc" column="product_desc" />
|
||||
<result property="goodsSpec" column="goods_spec" />
|
||||
<result property="goodsCount" column="goods_count" />
|
||||
<result property="subscriptionCancellationTime" column="subscription_cancellation_time" />
|
||||
<result property="goodsType" column="goods_type" />
|
||||
<result property="goodsPrice" column="goods_price" />
|
||||
<result property="goodsCode" column="goods_code" />
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectOrderInfoVo">
|
||||
select id, order_no, order_status, pay_type, pay_channel, order_amt, freight_amt, pay_amt, really_amt, receive_type, goods_id, business_id, receive_addr_id, create_time, pay_time, create_user_id, update_user_id, is_delete, update_time, track_no, order_type, out_order_no, pay_data, reduction_amout from ORDER_INFO
|
||||
select id, order_no, order_status, pay_type, pay_channel, order_amt, freight_amt, pay_amt, really_amt, receive_type, goods_id, business_id, receive_addr_id, create_time, pay_time, create_user_id, update_user_id, is_delete, update_time, track_no, order_type, out_order_no, pay_data, reduction_amout from Order_info
|
||||
</sql>
|
||||
<sql id="OrderListInfoVo">
|
||||
SELECT a.order_no,a.order_status,a.order_amt,b.product_title,b.product_picture,b.product_desc,b.goods_spec
|
||||
FROM ORDER_INFO a LEFT JOIN GOODS_MESSAGES b ON a.goods_id = b.id
|
||||
SELECT a.id,a.order_no,a.order_status,a.order_amt,a.pay_time,a.goods_count,a.subscription_cancellation_time,a.goods_type,a.goods_price,a.goods_code,b.product_title,b.product_picture,b.product_desc,b.goods_spec
|
||||
FROM Order_info a LEFT JOIN GOODS_MESSAGES b ON a.goods_id = b.id
|
||||
</sql>
|
||||
|
||||
<select id="selectOrderInfoList" parameterType="OrderInfo" resultMap="OrderInfoResult">
|
||||
@ -88,9 +94,14 @@
|
||||
<include refid="selectOrderInfoVo"/>
|
||||
where id = #{id}
|
||||
</select>
|
||||
|
||||
<select id="selectOrderInfoByOrderNo" resultMap="OrderInfoResult">
|
||||
<include refid="selectOrderInfoVo"/>
|
||||
where order_no = #{orderNo}
|
||||
</select>
|
||||
|
||||
<insert id="insertOrderInfo" parameterType="OrderInfo">
|
||||
insert into ORDER_INFO
|
||||
insert into Order_info
|
||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||
<if test="id != null">id,</if>
|
||||
<if test="orderNo != null">order_no,</if>
|
||||
@ -116,6 +127,10 @@
|
||||
<if test="outOrderNo != null">out_order_no,</if>
|
||||
<if test="payData != null">pay_data,</if>
|
||||
<if test="reductionAmout != null">reduction_amout,</if>
|
||||
<if test="goodsCount != null">goods_count,</if>
|
||||
<if test="goodsType != null">goods_type,</if>
|
||||
<if test="goodsPrice != null">goods_price,</if>
|
||||
<if test="goodsCode != null">goods_code,</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="id != null">#{id},</if>
|
||||
@ -142,11 +157,15 @@
|
||||
<if test="outOrderNo != null">#{outOrderNo},</if>
|
||||
<if test="payData != null">#{payData},</if>
|
||||
<if test="reductionAmout != null">#{reductionAmout},</if>
|
||||
<if test="goodsCount != null">#{goodsCount},</if>
|
||||
<if test="goodsType != null">#{goodsType},</if>
|
||||
<if test="goodsPrice != null">#{goodsPrice},</if>
|
||||
<if test="goodsCode != null">#{goodsCode},</if>
|
||||
</trim>
|
||||
</insert>
|
||||
|
||||
<update id="updateOrderInfo" parameterType="OrderInfo">
|
||||
update ORDER_INFO
|
||||
update Order_info
|
||||
<trim prefix="SET" suffixOverrides=",">
|
||||
<if test="orderNo != null">order_no = #{orderNo},</if>
|
||||
<if test="orderStatus != null">order_status = #{orderStatus},</if>
|
||||
@ -176,11 +195,11 @@
|
||||
</update>
|
||||
|
||||
<delete id="deleteOrderInfoById" parameterType="Long">
|
||||
delete from ORDER_INFO where id = #{id}
|
||||
delete from Order_info where id = #{id}
|
||||
</delete>
|
||||
|
||||
<delete id="deleteOrderInfoByIds" parameterType="String">
|
||||
delete from ORDER_INFO where id in
|
||||
delete from Order_info where id in
|
||||
<foreach item="id" collection="array" open="(" separator="," close=")">
|
||||
#{id}
|
||||
</foreach>
|
50
sf-payment/pom.xml
Normal file
50
sf-payment/pom.xml
Normal file
@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>smarterFramework</artifactId>
|
||||
<groupId>com.smarterFramework</groupId>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>sf-payment</artifactId>
|
||||
|
||||
<description>
|
||||
支付模块
|
||||
</description>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- 通用工具-->
|
||||
<dependency>
|
||||
<groupId>com.smarterFramework</groupId>
|
||||
<artifactId>sf-common</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.smarterFramework</groupId>
|
||||
<artifactId>sf-framework</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.smarterFramework</groupId>
|
||||
<artifactId>sf-order</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.smarterFramework</groupId>
|
||||
<artifactId>sf-service</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcprov-jdk18on</artifactId>
|
||||
<version>1.73</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.auth0</groupId>
|
||||
<artifactId>java-jwt</artifactId>
|
||||
<version>4.4.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
@ -0,0 +1,37 @@
|
||||
package com.sf.payment.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
|
||||
/**
|
||||
* 功能描述:
|
||||
*
|
||||
* @author a_kun
|
||||
* @date 2024/4/17 9:23
|
||||
*/
|
||||
@Data
|
||||
@Configuration
|
||||
public class HuaweiPaymentConfig {
|
||||
|
||||
/**
|
||||
* 客户端id:(oauth用)
|
||||
*/
|
||||
@Value("${huawei.payment.clientId:110693217}")
|
||||
private String clientId;
|
||||
|
||||
/**
|
||||
* 客户端Secret:对应各平台的appSecret
|
||||
*/
|
||||
@Value("${huawei.payment.clientSecret:1410c01bc71c7ba587175ae79e500137c70945acc1416a38127cf98a09a6f8ba}")
|
||||
private String clientSecret;
|
||||
|
||||
/**
|
||||
* 应用id
|
||||
*/
|
||||
@Value("${huawei.payment.appId:5765880207854169373}")
|
||||
private String appId;
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package com.sf.payment.constant;
|
||||
|
||||
import io.jsonwebtoken.Claims;
|
||||
|
||||
/**
|
||||
* 商品信息
|
||||
*
|
||||
* @author zoukun
|
||||
*/
|
||||
public class GoodsConstants {
|
||||
/**
|
||||
* 商品类型。
|
||||
* • 0:消耗型商品
|
||||
*/
|
||||
public static final Integer GOODS_TYPE_CONSUMABLE = 0;
|
||||
|
||||
/**
|
||||
* 商品类型。
|
||||
* • 1:非消耗型商品
|
||||
*/
|
||||
public static final Integer GOODS_TYPE_NON_CONSUMABLE = 1;
|
||||
|
||||
/**
|
||||
* 商品类型。
|
||||
* • 2:自动续期订阅商品
|
||||
*/
|
||||
public static final Integer GOODS_TYPE_AUTOMATIC_RENEWAL_SUBSCRIPTION = 2;
|
||||
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package com.sf.payment.controller;
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.sf.common.core.domain.AjaxResult;
|
||||
import com.sf.payment.constant.GoodsConstants;
|
||||
import com.sf.payment.domain.HuaweiPaymentCallback;
|
||||
import com.sf.payment.domain.HuaweiPurchasesVerifyDTO;
|
||||
import com.sf.payment.service.IHuaweiPaymentService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
/**
|
||||
* @author zoukun
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/payment")
|
||||
public class HuaweiPaymentController {
|
||||
|
||||
@Autowired
|
||||
private IHuaweiPaymentService huaweiPaymentService;
|
||||
|
||||
|
||||
/**
|
||||
* 华为支付回调地址
|
||||
*/
|
||||
@RequestMapping("/callback/huawei")
|
||||
public AjaxResult callback(@RequestBody HuaweiPaymentCallback callback) {
|
||||
log.info("进入callback: params:" + JSONObject.toJSONString(callback));
|
||||
AjaxResult ajax = AjaxResult.success();
|
||||
return ajax;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 华为购买验证
|
||||
*/
|
||||
@PostMapping("/huawei/purchases/verify")
|
||||
public AjaxResult purchasesVerify(@Validated @RequestBody HuaweiPurchasesVerifyDTO verifyDTO) {
|
||||
log.info("进入/huawei/purchases/tokens/verify: params:" + JSONObject.toJSONString(verifyDTO));
|
||||
huaweiPaymentService.purchasesVerify(verifyDTO);
|
||||
return AjaxResult.success();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package com.sf.payment.domain;
|
||||
|
||||
import lombok.*;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 授权回调时的参数类
|
||||
*
|
||||
* @author zk
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class HuaweiPaymentCallback implements Serializable {
|
||||
|
||||
/**
|
||||
* 访问AuthorizeUrl后回调时带的参数code
|
||||
*/
|
||||
private String code;
|
||||
|
||||
/**
|
||||
* 客户端id:对应各平台的appKey
|
||||
*/
|
||||
private String clientId;
|
||||
|
||||
/**
|
||||
* 客户端Secret:对应各平台的appSecret
|
||||
*/
|
||||
private String clientSecret;
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
package com.sf.payment.domain;
|
||||
|
||||
import apijson.NotNull;
|
||||
import lombok.*;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 华为验证购买tokenDTO
|
||||
*
|
||||
* @author zk
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class HuaweiPurchasesVerifyDTO implements Serializable {
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 商品类型。
|
||||
* • 0:消耗型商品
|
||||
* • 1:非消耗型商品
|
||||
* • 2:自动续期订阅商品
|
||||
*/
|
||||
@NotNull
|
||||
private Integer type;
|
||||
|
||||
/**
|
||||
* 包含订单信息的JWS格式数据。
|
||||
* 可参见对返回结果验签
|
||||
* 解码验签获取相关购买数据的JSON字符串,
|
||||
* 其包含的参数请参见PurchaseOrderPayload。
|
||||
*/
|
||||
private String jwsPurchaseOrder;
|
||||
|
||||
/**
|
||||
* 包含订阅状态信息的
|
||||
* JWS格式数据。
|
||||
* 可参见对返回结果验签
|
||||
* 解码验签获取相关订阅状态
|
||||
* 信息的JSON字符串,
|
||||
* 其包含的参数请参见
|
||||
* SubGroupStatusPayload。
|
||||
*/
|
||||
private String jwsSubscriptionStatus;
|
||||
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
package com.sf.payment.domain;
|
||||
|
||||
import apijson.NotNull;
|
||||
import lombok.*;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 华为验证购买tokenD返回
|
||||
*
|
||||
* @author zk
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class HuaweiPurchasesVerifyResponseDTO implements Serializable {
|
||||
|
||||
/**
|
||||
* 返回码。
|
||||
*
|
||||
* 0:成功。
|
||||
* 其他:失败,具体请参见错误码。
|
||||
*/
|
||||
private String responseCode;
|
||||
|
||||
/**
|
||||
* 响应描述。
|
||||
*/
|
||||
private String responseMessage;
|
||||
|
||||
/**
|
||||
*
|
||||
* 包含购买数据的JSON字符串,具体请参见表InappPurchaseDetails。
|
||||
*
|
||||
* 该字段原样参与签名。
|
||||
*/
|
||||
private String purchaseTokenData;
|
||||
|
||||
/**
|
||||
* purchaseTokenData基于应用RSA IAP私钥的签名信息,签名算法为signatureAlgorithm。
|
||||
* 应用请参见对返回结果验签使用IAP公钥对PurchaseTokenData的JSON字符串进行验签。
|
||||
*/
|
||||
private String dataSignature;
|
||||
|
||||
/**
|
||||
*
|
||||
* 签名算法。
|
||||
*/
|
||||
@NotBlank(message = "待下发商品ID不能为空")
|
||||
private String signatureAlgorithm;
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package com.sf.payment.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 功能描述:
|
||||
*
|
||||
* @author a_kun
|
||||
* @date 2024/4/17 14:41
|
||||
*/
|
||||
@Data
|
||||
public class HuaweiQueryResponse {
|
||||
|
||||
/**
|
||||
* 返回码。
|
||||
* • 0:成功。
|
||||
* • 其他:失败,具体请参见错误码
|
||||
*/
|
||||
private String responseCode;
|
||||
|
||||
/**
|
||||
* 响应描述。
|
||||
*/
|
||||
private String responseMessage;
|
||||
|
||||
/**
|
||||
* 包含已购订单相关状态信息的JWS格式数据。可参见对返回结果验签解码验签获取相关订单状态信息的JSON字符串,其包含的参数具体请参见表PurchaseOrderPayload说明。
|
||||
*/
|
||||
private String jwsPurchaseOrder;
|
||||
|
||||
/**
|
||||
* 包含已购订阅相关状态信息的JWS格式数据。可参见对返回结果验签解码验签获取相关订阅状态信息的JSON字符串,其包含的参数请参见SubGroupStatusPayload
|
||||
*/
|
||||
private String jwsSubGroupStatus;
|
||||
}
|
@ -0,0 +1,233 @@
|
||||
package com.sf.payment.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 功能描述:
|
||||
*
|
||||
* @author a_kun
|
||||
* @date 2024/4/16 15:29
|
||||
*/
|
||||
@Data
|
||||
public class InAppPurchaseData {
|
||||
|
||||
/**
|
||||
* 应用ID。
|
||||
*/
|
||||
private Long applicationId;
|
||||
|
||||
/**
|
||||
* 消耗型商品或者非消耗型商品:固定为false。
|
||||
*
|
||||
* 订阅型商品:
|
||||
*
|
||||
* true:订阅处于活动状态并且将在下一个结算日期自动续订。
|
||||
* false:用户已经取消订阅。 用户可以在下一个结算日期之前访问订阅内容,并且在该日期后将无法访问,除非重新启用自动续订。 如果提供了宽限期,只要宽限期未过,此值就会对所有订阅保持设置为true。 下一次结算日期每天都会自动延长,直至宽限期结束,或者用户更改付款方式。
|
||||
*/
|
||||
private Boolean autoRenewing;
|
||||
|
||||
/**
|
||||
* 订单ID,唯一标识一笔需要收费的收据,由华为应用内支付服务器在创建订单以及订阅型商品续费时生成。
|
||||
*
|
||||
* 每一笔新的收据都会使用不同的orderId。
|
||||
*/
|
||||
private String orderId;
|
||||
|
||||
/**
|
||||
* 商品类别,取值包括:
|
||||
*
|
||||
* 0:消耗型商品
|
||||
* 1:非消耗型商品
|
||||
* 2:订阅型商品
|
||||
*/
|
||||
private Integer kind;
|
||||
|
||||
/**
|
||||
* 商品ID。每种商品必须有唯一的ID,由应用在PMS中维护,或者应用发起购买时传入。
|
||||
* 说明
|
||||
* 为避免资金损失,您在对支付结果验签成功后,必须对其进行校验。
|
||||
*/
|
||||
private String productId;
|
||||
|
||||
/**
|
||||
* 商品名称。
|
||||
*/
|
||||
private String productName;
|
||||
|
||||
/**
|
||||
* 商品购买时间,UTC时间戳,以毫秒为单位。
|
||||
*/
|
||||
private Long purchaseTime;
|
||||
|
||||
/**
|
||||
* 订单交易状态。
|
||||
*
|
||||
* -1:初始化
|
||||
* 0:已购买
|
||||
* 1:已取消
|
||||
* 2:已撤销或已退款
|
||||
* 3:待处理
|
||||
*/
|
||||
private Integer purchaseState;
|
||||
|
||||
/**
|
||||
*
|
||||
* 商户侧保留信息,由您在调用支付接口时传入。
|
||||
*/
|
||||
private String developerPayload;
|
||||
|
||||
/**
|
||||
*消耗状态,仅一次性商品存在,取值包括:
|
||||
*
|
||||
* 0:未消耗
|
||||
* 1:已消耗
|
||||
*/
|
||||
private Integer consumptionState;
|
||||
|
||||
/**
|
||||
*确认状态,取值包括:
|
||||
*
|
||||
* 0 :未确认
|
||||
* 1:已确认
|
||||
* 没有值表示不需要确认
|
||||
*/
|
||||
private Integer confirmed;
|
||||
|
||||
/**
|
||||
* 用于唯一标识商品和用户对应关系的购买令牌,在支付完成时由华为应用内支付服务器生成。
|
||||
* 说明
|
||||
* 该字段是唯一标识商品和用户对应关系的,在订阅型商品正常续订时不会改变。
|
||||
* 当前92位,后续存在扩展可能,如要进行存储,建议您预留128位的长度。
|
||||
* 如要进行存储,为保证安全,建议加密存储。
|
||||
*/
|
||||
private String purchaseToken;
|
||||
|
||||
/**
|
||||
* 用定价货币的币种,请参见ISO 4217标准。
|
||||
* 说明
|
||||
* 为避免资金损失,您在对支付结果验签成功后,必须对其进行校验。
|
||||
*/
|
||||
private String currency;
|
||||
|
||||
/**
|
||||
* 商品实际价格*100以后的值。商品实际价格精确到小数点后2位,例如此参数值为501,则表示商品实际价格为5.01。
|
||||
*/
|
||||
private Long price;
|
||||
|
||||
/**
|
||||
* 支付方式,取值请参见payType说明。
|
||||
*/
|
||||
private String payType;
|
||||
|
||||
/**
|
||||
* 交易单号,用户支付成功后生成。
|
||||
*/
|
||||
private String payOrderId;
|
||||
|
||||
// 以下参数只在订阅场景返回
|
||||
|
||||
|
||||
/**
|
||||
* 上次续期收款的订单ID,由支付服务器在续期扣费时生成。首次购买订阅型商品时的lastOrderId与orderId数值相同。
|
||||
*/
|
||||
private String lastOrderId;
|
||||
|
||||
/**
|
||||
* 订阅型商品所属的订阅组ID。
|
||||
*/
|
||||
private String productGroup;
|
||||
|
||||
/**
|
||||
* 原购买的时间,即本订阅型商品首次成功收费的时间,UTC时间戳,以毫秒为单位。。
|
||||
*/
|
||||
private Long oriPurchaseTime;
|
||||
|
||||
/**
|
||||
* 订阅ID。
|
||||
* 说明
|
||||
* subscriptionId是用户与商品之间的一一对应关系,在订阅型商品正常续订时不会改变。
|
||||
*/
|
||||
private String subscriptionId;
|
||||
|
||||
/**
|
||||
* 原订阅ID。有值表示当前订阅是从其他商品切换来的,该值可以关联切换前的商品订阅信息
|
||||
*/
|
||||
private String oriSubscriptionId;
|
||||
|
||||
/**
|
||||
* 购买数量。
|
||||
*/
|
||||
private Integer quantity;
|
||||
|
||||
/**
|
||||
* 已经付费订阅的天数,免费试用和促销期周期除外。。
|
||||
*/
|
||||
private Long daysLasted;
|
||||
|
||||
/**
|
||||
* 成功标准续期(没有设置促销的续期)的期数,为0或者不存在表示还没有成功续期。
|
||||
*/
|
||||
private Long numOfPeriods;
|
||||
|
||||
/**
|
||||
* 成功促销续期期数。
|
||||
*/
|
||||
private Long numOfDiscount;
|
||||
|
||||
/**
|
||||
* 订阅型商品过期时间,UTC时间戳,以毫秒为单位。
|
||||
*
|
||||
* 对于一个成功收费的自动续订收据,该时间表示续期日期或者超期日期。如果商品最近的收据的该时间是一个过去的时间,则订阅已经过期。
|
||||
*/
|
||||
private Long expirationDate;
|
||||
|
||||
/**
|
||||
* 对于已经过期的订阅,表示过期原因,取值包括:
|
||||
*
|
||||
* 1:用户取消
|
||||
* 2:商品不可用
|
||||
* 3:用户签约信息异常
|
||||
* 4:Billing错误
|
||||
* 5:用户未同意涨价
|
||||
* 6:未知错误
|
||||
* 同时有多个异常时,优先级为:1 > 2 > 3…
|
||||
*/
|
||||
private Integer expirationIntent;
|
||||
|
||||
/**
|
||||
* 订阅撤销时间,UTC时间戳,以毫秒为单位,发生退款且服务立即不可用。在顾客投诉,通过客服撤销订阅,或者顾客升级、跨级到同组其他商品并且立即生效场景下,需要撤销原有订阅的上次收据时有值。
|
||||
* 说明
|
||||
* 已经撤销的收据等同于没有完成购买。
|
||||
*/
|
||||
private Long cancelTime;
|
||||
|
||||
/**
|
||||
* 取消原因。
|
||||
*
|
||||
* 3: 应用调用IAP接口取消
|
||||
* 2:顾客升级、跨级等。
|
||||
* 1:顾客因为在App内遇到了问题而取消了订阅。
|
||||
* 0:其他原因取消,比如顾客错误地订阅了商品。
|
||||
* 说明
|
||||
* 如果为空且cancelTime有值,表示是升级等操作导致的取消。
|
||||
*/
|
||||
private Integer cancelReason;
|
||||
|
||||
/**
|
||||
* 续期状态。
|
||||
*
|
||||
* 1:当前周期到期时自动续期
|
||||
* 0:用户停止了续期
|
||||
* 仅针对自动续期订阅,对有效和过期的订阅均有效,并不代表顾客的订阅状态。通常,取值为0时,应用可以给顾客提供其他的订阅选项,
|
||||
* 例如推荐一个同组更低级别的商品。该值为0通常代表着顾客主动取消了该订阅。
|
||||
*/
|
||||
private Integer renewStatus;
|
||||
|
||||
/**
|
||||
* 用户取消订阅的时间,UTC时间戳,以毫秒为单位。在该时间进行了订阅续期停止的设定,商品在有效期内仍然有效,但后续的续期会终止,无退款。
|
||||
*/
|
||||
private Integer cancellationTime;
|
||||
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,165 @@
|
||||
package com.sf.payment.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 功能描述:
|
||||
* 订单信息模型,支持消耗型商品、非消耗型商品和自动续期订阅商品。
|
||||
* @author a_kun
|
||||
* @date 2024/4/16 15:29
|
||||
*/
|
||||
@Data
|
||||
public class PurchaseOrderPayload {
|
||||
|
||||
/**
|
||||
* 具体一笔订单中对应的购买订单号ID。
|
||||
*/
|
||||
private String purchaseOrderId;
|
||||
|
||||
/**
|
||||
* 购买token,
|
||||
* 在购买消耗型/非消耗型商品场景中与具体购买订单一一对应,
|
||||
* 在自动续期订阅商品场景中与订阅ID一一对应。
|
||||
*/
|
||||
private String purchaseToken;
|
||||
|
||||
/**
|
||||
* 应用ID。
|
||||
*/
|
||||
private String applicationId;
|
||||
|
||||
/**
|
||||
* 商品ID。每种商品必须有唯一的ID,由应用在PMS中维护,或者应用发起购买时传入。
|
||||
* 说明
|
||||
* 为避免资金损失,您在对支付结果验签成功后,必须对其进行校验。
|
||||
*/
|
||||
private String productId;
|
||||
|
||||
/**
|
||||
* 商品类型。具体取值如下:
|
||||
* • 0:消耗型商品
|
||||
* • 1:非消耗型商品
|
||||
* • 2:自动续期订阅商品
|
||||
*/
|
||||
private Integer productType;
|
||||
|
||||
/**
|
||||
* 购买时间,UTC时间戳,以毫秒为单位。
|
||||
* 如果没有完成购买,则没有值。
|
||||
*/
|
||||
private Long purchaseTime;
|
||||
|
||||
/**
|
||||
* 发货状态。具体取值如下:
|
||||
* • 1:已发货
|
||||
* • 2:未发货
|
||||
*/
|
||||
private Integer finishStatus;
|
||||
|
||||
/**
|
||||
* 价格,单位:分。
|
||||
* 实际价格*100以后的值。商品实际价格精确到小数点后2位,例如此参数值为501,则表示商品实际价格为5.01。
|
||||
*/
|
||||
private Long price;
|
||||
|
||||
/**
|
||||
* 用定价货币的币种,请参见ISO 4217标准。
|
||||
* 说明
|
||||
* 为避免资金损失,您在对支付结果验签成功后,必须对其进行校验。
|
||||
*/
|
||||
private String currency;
|
||||
|
||||
/**
|
||||
* 商户侧保留信息,由您在调用支付接口时传入。
|
||||
*/
|
||||
private String developerPayload;
|
||||
|
||||
/**
|
||||
* 购买订单撤销原因。
|
||||
* • 0:其他
|
||||
* • 1:用户遇到问题退款
|
||||
*/
|
||||
private Integer purchaseOrderRevocationReasonCode;
|
||||
|
||||
/**
|
||||
* 购买订单撤销时间,
|
||||
* UTC时间戳,以毫秒为单位。
|
||||
*/
|
||||
private Long revocationTime;
|
||||
|
||||
/**
|
||||
* 优惠类型。
|
||||
* • 1:推介促销
|
||||
*/
|
||||
private Integer offerTypeCode;
|
||||
|
||||
/**
|
||||
* 优惠ID。
|
||||
*/
|
||||
private String offerId;
|
||||
|
||||
/**
|
||||
* 国家/地区码,用于区分国家/地区信息,请参见ISO 3166
|
||||
*/
|
||||
private String countryCode;
|
||||
|
||||
/**
|
||||
* 签名时间,UTC时间戳,以毫秒为单位。
|
||||
*/
|
||||
private Long signedTime;
|
||||
|
||||
// 以下参数只在自动续期订阅商品场景返回
|
||||
|
||||
|
||||
/**
|
||||
* 订阅连续购买段的唯一ID,
|
||||
* 当用户切换商品不会重置此ID。
|
||||
*/
|
||||
private String subGroupGenerationId;
|
||||
|
||||
/**
|
||||
* 订阅连续购买段的唯一ID,
|
||||
* 当用户切换订阅商品时
|
||||
* 此订阅ID会发生改变。
|
||||
*/
|
||||
private String subscriptionId;
|
||||
|
||||
/**
|
||||
* 订阅组ID。
|
||||
*/
|
||||
private String subGroupId;
|
||||
|
||||
/**
|
||||
* 此次购买的有效周期,
|
||||
* 采用ISO 8601格式。
|
||||
* 例如:P1W表示一周,
|
||||
* P1M表示一个月。
|
||||
*/
|
||||
private String duration;
|
||||
|
||||
/**
|
||||
* 订阅周期段类型。
|
||||
* • 0:正常周期段
|
||||
* • 1:延期周期段
|
||||
*/
|
||||
private Integer durationTypeCode;
|
||||
|
||||
/*
|
||||
ISO 8601的时间持续期限表示
|
||||
在ISO 8601中,时间持续期限的表示采用了一种简洁而明确的格式,例如 “P10D”,其中 “P” 表示周期(Period),后面的数字表示周期的长度,而末尾的字母表示周期的单位。这种表示法主要用于描述时间段的长度,而不关注具体的时刻。
|
||||
“P” 表示周期(Period): 此字母指示接下来的时间表示将是一个时间段的描述,而非具体的日期或时刻。
|
||||
后面的数字: 这个数字表示时间段的长度,可以是整数或小数。它指示了在时间单位内的周期数量。
|
||||
末尾的字母表示周期的单位: 在 “P10D” 中,末尾的 “D” 表示周期的单位是天(Days)。ISO 8601定义了多种可能的时间单位,包括:
|
||||
Y(年): 表示年份,例如 “P2Y” 表示2年的时间段。
|
||||
M(月): 表示月份,例如 “P3M” 表示3个月的时间段。
|
||||
W(周): 表示周数,例如 “P1W” 表示1周的时间段。
|
||||
D(日): 表示天数,例如 “P10D” 表示10天的时间段。
|
||||
T(时间分隔符): 如果时间段中包含了时间信息,日期和时间之间用 “T” 分隔,例如 “P1DT12H” 表示1天12小时的时间段。
|
||||
H(小时)、M(分钟)、S(秒): 用于表示时、分、秒的时间段长度,例如 “PT2H30M” 表示2小时30分钟的时间段。
|
||||
示例:
|
||||
“P1Y”: 表示1年的时间段。
|
||||
“P3M”: 表示3个月的时间段。
|
||||
“P2W”: 表示2周的时间段。
|
||||
“P4DT6H30M”: 表示4天6小时30分钟的时间段。
|
||||
*/
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package com.sf.payment.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 功能描述:
|
||||
* 已购订阅相关状态信息
|
||||
* @author a_kun
|
||||
* @date 2024/4/16 15:29
|
||||
*/
|
||||
@Data
|
||||
public class SubGroupStatusPayload {
|
||||
|
||||
/**
|
||||
* 应用ID。
|
||||
*/
|
||||
private String applicationId;
|
||||
|
||||
/**
|
||||
* 应用包名。
|
||||
*/
|
||||
private String packageName;
|
||||
|
||||
/**
|
||||
* 订阅组ID。
|
||||
*/
|
||||
private String subGroupId;
|
||||
|
||||
/**
|
||||
* 订阅组中最后生效的
|
||||
* 订阅状态
|
||||
* SubscriptionStatus,
|
||||
* 比如A切换B,B切换C,
|
||||
* 此处是C的订阅状态。
|
||||
*/
|
||||
private SubscriptionStatus lastSubscriptionStatus;
|
||||
|
||||
/**
|
||||
* 订阅组最近生效的
|
||||
* 历史订阅状态
|
||||
* SubscriptionStatus的列表,比如A切换B,B切换C,这里包含C,B,A三个订阅状态信息。
|
||||
*/
|
||||
private List<SubscriptionStatus> historySubscriptionStatusList;
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
package com.sf.payment.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 功能描述:
|
||||
* 当前订阅最新的未来扣费计划
|
||||
* @author a_kun
|
||||
* @date 2024/4/16 15:29
|
||||
*/
|
||||
@Data
|
||||
public class SubRenewalInfo {
|
||||
|
||||
/**
|
||||
* 订阅连续购买段的唯一ID,
|
||||
* 当用户切换商品不会重置此ID。
|
||||
*/
|
||||
private String subGroupGenerationId;
|
||||
|
||||
/**
|
||||
* 下周期生效场景下,下期将续期的商品ID。
|
||||
*/
|
||||
private String nextRenewPeriodProductId;
|
||||
|
||||
/**
|
||||
* 当前生效的商品ID。
|
||||
*/
|
||||
private String productId;
|
||||
|
||||
/**
|
||||
* 自动续期状态。
|
||||
* • 0:关闭
|
||||
* • 1:打开
|
||||
*/
|
||||
private Integer autoRenewStatusCode;
|
||||
|
||||
/**
|
||||
* 系统是否还在尝试扣费。
|
||||
* • true:是
|
||||
* • false:否
|
||||
*/
|
||||
private Boolean hasInBillingRetryPeriod;
|
||||
|
||||
/**
|
||||
* 目前涨价状态码。
|
||||
* • 1:用户暂未同意涨价
|
||||
* • 2:用户已同意涨价
|
||||
*/
|
||||
private Integer priceIncreaseStatusCode;
|
||||
|
||||
/**
|
||||
* 优惠类型。
|
||||
* • 1:推介促销
|
||||
*/
|
||||
private Integer offerTypeCode;
|
||||
|
||||
/**
|
||||
* 优惠ID。
|
||||
*/
|
||||
private String offerId;
|
||||
|
||||
/**
|
||||
* 下期续费价格,单位:分,取消订阅场景下不返回。
|
||||
*/
|
||||
private String renewalPrice;
|
||||
|
||||
/**
|
||||
* 币种。
|
||||
*/
|
||||
private String currency;
|
||||
|
||||
/**
|
||||
* 续期时间,UTC时间戳,以毫秒为单位。。
|
||||
*/
|
||||
private Long renewalTime;
|
||||
|
||||
/**
|
||||
* 订阅续期失败的原因。
|
||||
* • 1:用户取消
|
||||
* • 2:商品无效
|
||||
* • 3:签约无效
|
||||
* • 4:扣费异常
|
||||
* • 5:用户不同意涨价
|
||||
* • 6:未知
|
||||
*/
|
||||
private String expirationIntent;
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
package com.sf.payment.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 功能描述:
|
||||
* 订阅组中最后生效的订阅状态
|
||||
* @author a_kun
|
||||
* @date 2024/4/16 15:29
|
||||
*/
|
||||
@Data
|
||||
public class SubscriptionStatus {
|
||||
|
||||
/**
|
||||
* 订阅连续购买段的唯一ID,
|
||||
* 当用户切换商品不会重置此ID。
|
||||
*/
|
||||
private String subGroupGenerationId;
|
||||
|
||||
/**
|
||||
* 订阅连续购买段的唯一ID,
|
||||
* 当用户切换订阅商品时
|
||||
* 此订阅ID会发生改变。
|
||||
*/
|
||||
private String subscriptionId;
|
||||
|
||||
/**
|
||||
* 购买token,
|
||||
* 在购买消耗型/非消耗型商品场景中与具体购买订单一一对应,
|
||||
* 在自动续期订阅商品场景中与订阅ID一一对应。
|
||||
*/
|
||||
private String purchaseToken;
|
||||
|
||||
/**
|
||||
* 订阅状态。
|
||||
* • 1:生效状态
|
||||
* • 2:已到期
|
||||
* • 3:尝试扣费
|
||||
* • 5:撤销
|
||||
* • 6:暂停
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 自动续期订阅商品的过期时间,UTC时间戳,以毫秒为单位。
|
||||
*/
|
||||
private Long expiresTime;
|
||||
|
||||
/**
|
||||
* 当前订阅最新的一笔购买订单。包含的参数请参见PurchaseOrderPayload。
|
||||
*/
|
||||
private PurchaseOrderPayload lastPurchaseOrder;
|
||||
|
||||
/**
|
||||
* 当前订阅最新的购买订单列表,包含续期、延期、折算等产生的购买订单。
|
||||
* 购买订单包含的参数请参见PurchaseOrderPayload。
|
||||
*/
|
||||
private List<PurchaseOrderPayload> recentPurchaseOrderList;
|
||||
|
||||
/**
|
||||
* 当前订阅最新的未来扣费计划,包含的参数请参见SubRenewalInfo。
|
||||
*/
|
||||
private SubRenewalInfo renewalInfo;
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package com.sf.payment.service;
|
||||
|
||||
|
||||
import com.sf.payment.domain.HuaweiPurchasesVerifyDTO;
|
||||
|
||||
/**
|
||||
* 功能描述:
|
||||
*
|
||||
* @author a_kun
|
||||
* @date 2024/4/12 10:21
|
||||
*/
|
||||
public interface IHuaweiPaymentService {
|
||||
void purchasesVerify(HuaweiPurchasesVerifyDTO verifyDTO);
|
||||
}
|
@ -0,0 +1,395 @@
|
||||
package com.sf.payment.service.impl;
|
||||
|
||||
import cn.hutool.core.date.DateField;
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.auth0.jwt.JWT;
|
||||
import com.auth0.jwt.interfaces.DecodedJWT;
|
||||
import com.sf.common.utils.SecurityUtils;
|
||||
import com.sf.common.utils.SnowflakeIdWorker;
|
||||
import com.sf.order.domain.OrderInfo;
|
||||
import com.sf.order.service.IOrderInfoService;
|
||||
import com.sf.payment.config.HuaweiPaymentConfig;
|
||||
import com.sf.payment.constant.GoodsConstants;
|
||||
import com.sf.payment.domain.*;
|
||||
import com.sf.payment.service.IHuaweiPaymentService;
|
||||
import com.sf.payment.utils.HuaweiTokenGenerator;
|
||||
import com.sf.service.domain.GoodsMessages;
|
||||
import com.sf.service.service.IGoodsMessagesService;
|
||||
import com.sf.system.domain.UserMember;
|
||||
import com.sf.system.service.IUserMemberService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.Base64Utils;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.PublicKey;
|
||||
import java.security.Security;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* 功能描述:
|
||||
*
|
||||
* @author a_kun
|
||||
* @date 2024/4/12 10:21
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class HuaweiPaymentServiceImpl implements IHuaweiPaymentService {
|
||||
|
||||
/**
|
||||
* token url to get the authorization
|
||||
*/
|
||||
private static final String TOKEN_URL = "https://oauth-login.cloud.huawei.com/oauth2/v3/token";
|
||||
|
||||
/**
|
||||
* 查询消耗型/非消耗型商品的订单最新状态。
|
||||
*/
|
||||
private static final String ORDER_STATUS_QUERY_URL = "/order/harmony/v1/application/order/status/query";
|
||||
|
||||
/**
|
||||
* 查询自动续期订阅商品的最新状态。
|
||||
*/
|
||||
private static final String SUBSCRIPTION_STATUS_QUERY_URL = "/subscription/harmony/v1/application/subscription/status/query";
|
||||
|
||||
/**
|
||||
* 站点信息。(中国)
|
||||
*/
|
||||
private static final String ROOT_URL = "https://iap.cloud.huawei.com";
|
||||
|
||||
private static final String PUBLIC_KEY = "PUBLIC_KEY";
|
||||
|
||||
@Resource
|
||||
private IOrderInfoService orderInfoService;
|
||||
|
||||
@Resource
|
||||
private IUserMemberService userMemberService;
|
||||
|
||||
@Resource
|
||||
private IGoodsMessagesService goodsMessagesService;
|
||||
|
||||
@Resource
|
||||
private HuaweiPaymentConfig huaweiPaymentConfig;
|
||||
|
||||
@Resource
|
||||
private SnowflakeIdWorker snowflakeIdWorker;
|
||||
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void purchasesVerify(HuaweiPurchasesVerifyDTO verifyDTO) {
|
||||
// 待发放会员商品
|
||||
PurchaseOrderPayload huaweiQueryResponsePurchaseOrderPayload;
|
||||
// 验证 TODO 证书验签官网未实现
|
||||
if (GoodsConstants.GOODS_TYPE_CONSUMABLE.equals(verifyDTO.getType())
|
||||
|| GoodsConstants.GOODS_TYPE_NON_CONSUMABLE.equals(verifyDTO.getType())) {
|
||||
Assert.hasText(verifyDTO.getJwsPurchaseOrder(), "订单信息不能为空");
|
||||
// 消耗/非消耗商品购买验证
|
||||
consumablePurchasesVerify(verifyDTO.getJwsPurchaseOrder());
|
||||
} else if (GoodsConstants.GOODS_TYPE_AUTOMATIC_RENEWAL_SUBSCRIPTION.equals(verifyDTO.getType())) {
|
||||
Assert.hasText(verifyDTO.getJwsSubscriptionStatus(), "订单信息不能为空");
|
||||
// 订阅商品购买验证
|
||||
subscriptionPurchasesVerify(verifyDTO.getJwsSubscriptionStatus());
|
||||
} else {
|
||||
throw new IllegalArgumentException("商品类型错误!");
|
||||
}
|
||||
}
|
||||
|
||||
private PurchaseOrderPayload subscriptionPurchasesVerify(String jwsSubscriptionStatus) {
|
||||
DecodedJWT decodedJWT = JWT.decode(jwsSubscriptionStatus);
|
||||
//String header = decodedJWT.getHeader();
|
||||
String payload = decodedJWT.getPayload();
|
||||
// 前面应该不是base64编码后的,官网说都是编码后的,但是解码会报错
|
||||
//String signature = decodedJWT.getSignature();
|
||||
String decodeAppPayload = new String(Base64Utils.decode(payload.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8);
|
||||
// String decodeHeader = new String(Base64Utils.decode(header.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8);
|
||||
// String decodeSignature = new String(Base64Utils.decode(signature.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8);
|
||||
SubGroupStatusPayload appSubGroupStatusPayload = JSON.parseObject(decodeAppPayload, SubGroupStatusPayload.class);
|
||||
SubscriptionStatus lastSubscriptionStatus = appSubGroupStatusPayload.getLastSubscriptionStatus();
|
||||
PurchaseOrderPayload lastPurchaseOrder = lastSubscriptionStatus.getLastPurchaseOrder();
|
||||
// pack the request body
|
||||
Map<String, String> bodyMap = new HashMap<>();
|
||||
bodyMap.put("purchaseToken", lastPurchaseOrder.getPurchaseToken());
|
||||
bodyMap.put("purchaseOrderId", lastPurchaseOrder.getPurchaseOrderId());
|
||||
// construct the Authorization in Header
|
||||
Map<String, String> headers = buildAuthorization(huaweiPaymentConfig.getAppId(), bodyMap);
|
||||
|
||||
// 订阅状态查询
|
||||
String response = HttpUtil.createPost(ROOT_URL + SUBSCRIPTION_STATUS_QUERY_URL)
|
||||
.addHeaders(headers)
|
||||
.body(JSON.toJSONString(bodyMap))
|
||||
.execute().body();
|
||||
log.info("订单状态查询返回信息:{}", response);
|
||||
HuaweiQueryResponse huaweiQueryResponse = JSON.parseObject(response, HuaweiQueryResponse.class);
|
||||
if (!"0".equals(huaweiQueryResponse.getResponseCode())) {
|
||||
throw new RuntimeException("订单状态查询失败");
|
||||
}
|
||||
DecodedJWT huaweiQueryResponseDecodedJWT = JWT.decode(huaweiQueryResponse.getJwsSubGroupStatus());
|
||||
String huaweiQueryResponsepayload = huaweiQueryResponseDecodedJWT.getPayload();
|
||||
String decodeHuaweiQueryResponsepayload = new String(Base64Utils.decode(huaweiQueryResponsepayload.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8);
|
||||
SubGroupStatusPayload subGroupStatusPayload = JSON.parseObject(decodeHuaweiQueryResponsepayload, SubGroupStatusPayload.class);
|
||||
PurchaseOrderPayload huaweiQueryResponsePurchaseOrderPayload = subGroupStatusPayload.getLastSubscriptionStatus().getLastPurchaseOrder();
|
||||
// 发货
|
||||
return delivery(lastPurchaseOrder, huaweiQueryResponsePurchaseOrderPayload);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发货
|
||||
* @param purchaseOrder
|
||||
* @param huaweiQueryResponsePurchaseOrderPayload
|
||||
* @return
|
||||
*/
|
||||
private PurchaseOrderPayload delivery(PurchaseOrderPayload purchaseOrder, PurchaseOrderPayload huaweiQueryResponsePurchaseOrderPayload) {
|
||||
Assert.isTrue(purchaseOrder.getPurchaseOrderId().equals(huaweiQueryResponsePurchaseOrderPayload.getPurchaseOrderId()), "订单不一致,发货失败!");
|
||||
if (2 == huaweiQueryResponsePurchaseOrderPayload.getFinishStatus()) {
|
||||
// 还未发货
|
||||
// 查询平台是否配置该商品
|
||||
// 查询平台是否配置该商品
|
||||
GoodsMessages goods = goodsMessagesService.selectGoodsMessagesByCode(huaweiQueryResponsePurchaseOrderPayload.getProductId());
|
||||
Assert.notNull(goods, "未配置此商品,请检查商品配置");
|
||||
Assert.isTrue(goods.getOriginalPrice().equals(huaweiQueryResponsePurchaseOrderPayload.getPrice()), "商品价格与订单价格不一致,请检查价格配置");
|
||||
// 创建完成订单
|
||||
createOrder(huaweiQueryResponsePurchaseOrderPayload, goods);
|
||||
// 发放会员权益
|
||||
distributeMembershipBenefits(huaweiQueryResponsePurchaseOrderPayload);
|
||||
} else {
|
||||
log.info("华为应用内支付订单已发货!{}", JSON.toJSONString(huaweiQueryResponsePurchaseOrderPayload));
|
||||
}
|
||||
return huaweiQueryResponsePurchaseOrderPayload;
|
||||
}
|
||||
|
||||
private PurchaseOrderPayload consumablePurchasesVerify(String jwsPurchaseOrder) {
|
||||
DecodedJWT decodedJWT = JWT.decode(jwsPurchaseOrder);
|
||||
//String header = decodedJWT.getHeader();
|
||||
String payload = decodedJWT.getPayload();
|
||||
// 前面应该不是base64编码后的,官网说都是编码后的,但是解码会报错
|
||||
//String signature = decodedJWT.getSignature();
|
||||
String decodeAppPayload = new String(Base64Utils.decode(payload.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8);
|
||||
// String decodeHeader = new String(Base64Utils.decode(header.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8);
|
||||
// String decodeSignature = new String(Base64Utils.decode(signature.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8);
|
||||
PurchaseOrderPayload appPurchaseOrderPayload = JSON.parseObject(decodeAppPayload, PurchaseOrderPayload.class);
|
||||
// pack the request body
|
||||
Map<String, String> bodyMap = new HashMap<>();
|
||||
bodyMap.put("purchaseToken", appPurchaseOrderPayload.getPurchaseToken());
|
||||
bodyMap.put("purchaseOrderId", appPurchaseOrderPayload.getPurchaseOrderId());
|
||||
// construct the Authorization in Header
|
||||
Map<String, String> headers = buildAuthorization(huaweiPaymentConfig.getAppId(), bodyMap);
|
||||
|
||||
// 订单状态查询
|
||||
String response = HttpUtil.createPost(ROOT_URL + ORDER_STATUS_QUERY_URL)
|
||||
.addHeaders(headers)
|
||||
.body(JSON.toJSONString(bodyMap))
|
||||
.execute().body();
|
||||
log.info("订单状态查询返回信息:{}", response);
|
||||
HuaweiQueryResponse huaweiQueryResponse = JSON.parseObject(response, HuaweiQueryResponse.class);
|
||||
if (!"0".equals(huaweiQueryResponse.getResponseCode())) {
|
||||
throw new RuntimeException("订单状态查询失败");
|
||||
}
|
||||
DecodedJWT huaweiQueryResponseDecodedJWT = JWT.decode(huaweiQueryResponse.getJwsPurchaseOrder());
|
||||
// String huaweiQueryResponseHeader = huaweiQueryResponseDecodedJWT.getHeader();
|
||||
String huaweiQueryResponsepayload = huaweiQueryResponseDecodedJWT.getPayload();
|
||||
// String huaweiQueryResponsesignature = huaweiQueryResponseDecodedJWT.getSignature();
|
||||
|
||||
//String decodehuaweiQueryResponseHeader = new String(Base64Utils.decode(huaweiQueryResponseHeader.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8);
|
||||
String decodehuaweiQueryResponsepayload = new String(Base64Utils.decode(huaweiQueryResponsepayload.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8);
|
||||
// String decodehuaweiQueryResponsesignature = new String(Base64Utils.decode(huaweiQueryResponsesignature.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8);
|
||||
|
||||
PurchaseOrderPayload huaweiQueryResponsePurchaseOrderPayload = JSON.parseObject(decodehuaweiQueryResponsepayload, PurchaseOrderPayload.class);
|
||||
// 暂时只做简单验证
|
||||
return delivery(appPurchaseOrderPayload, huaweiQueryResponsePurchaseOrderPayload);
|
||||
}
|
||||
|
||||
private void createOrder(PurchaseOrderPayload appPurchaseOrderPayload, GoodsMessages goods) {
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
OrderInfo orderInfo = new OrderInfo();
|
||||
orderInfo.setOrderNo(snowflakeIdWorker.nextId());
|
||||
orderInfo.setOrderStatus(6L);
|
||||
orderInfo.setPayType(1L);
|
||||
orderInfo.setPayChannel(2L);
|
||||
orderInfo.setOrderAmt(appPurchaseOrderPayload.getPrice());
|
||||
orderInfo.setPayAmt(appPurchaseOrderPayload.getPrice());
|
||||
orderInfo.setReallyAmt(appPurchaseOrderPayload.getPrice());
|
||||
orderInfo.setReceiveType(0L);
|
||||
orderInfo.setGoodsId(goods.getId());
|
||||
orderInfo.setPayTime(DateUtil.date(appPurchaseOrderPayload.getPurchaseTime()));
|
||||
orderInfo.setCreateUserId(userId);
|
||||
orderInfo.setUpdateUserId(userId);
|
||||
orderInfo.setOutOrderNo(appPurchaseOrderPayload.getPurchaseOrderId());
|
||||
orderInfo.setPayData(JSON.toJSONString(appPurchaseOrderPayload));
|
||||
orderInfo.setGoodsPrice(goods.getOriginalPrice());
|
||||
orderInfo.setGoodsType(goods.getGoodsType());
|
||||
orderInfo.setGoodsCode(goods.getGoodsCode());
|
||||
orderInfoService.insertOrder(orderInfo);
|
||||
|
||||
}
|
||||
|
||||
private void distributeMembershipBenefits(PurchaseOrderPayload purchaseOrderPayload) {
|
||||
// 发放会员权益
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
UserMember userMember = userMemberService.selectUserMemberByUserId(userId);
|
||||
if (userMember == null) {
|
||||
// 添加会员信息
|
||||
boolean isSubscription = GoodsConstants.GOODS_TYPE_AUTOMATIC_RENEWAL_SUBSCRIPTION.equals(purchaseOrderPayload.getProductType());
|
||||
DateTime payTime = DateUtil.date(purchaseOrderPayload.getPurchaseTime());
|
||||
userMember = new UserMember();
|
||||
userMember.setMemberLevel(isSubscription ? 1 : 2);
|
||||
userMember.setSubscriptionStatus(isSubscription ? 1 : 0);
|
||||
userMember.setUserId(userId);
|
||||
userMember.setIntegration(0L);
|
||||
DateTime expirationTime = DateUtil.offset(payTime, DateField.MONTH, 1);
|
||||
userMember.setExpirationTime(expirationTime);
|
||||
userMember.setCreateTime(new Date());
|
||||
userMember.setUpdateTime(new Date());
|
||||
userMemberService.insertUserMember(userMember);
|
||||
} else {
|
||||
// 更新
|
||||
DateTime expirationTime = DateUtil.offset(userMember.getExpirationTime(), DateField.MONTH, 1);
|
||||
userMember.setExpirationTime(expirationTime);
|
||||
userMember.setUpdateTime(new Date());
|
||||
userMemberService.updateUserMember(userMember);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Build Authorization in Header
|
||||
*
|
||||
* @return headers
|
||||
*/
|
||||
public static Map<String, String> buildAuthorization(String appId, Map<String, String> body) {
|
||||
Map<String, Object> jwtHeader = new HashMap<>(8);
|
||||
jwtHeader.put("alg", "ES256");
|
||||
jwtHeader.put("typ", "JWT");
|
||||
jwtHeader.put("kid", "0ae3e1be-374b-43a5-a297-045addbf76eb");
|
||||
Map<String, Object> jwtPayload = new HashMap<>(8);
|
||||
jwtPayload.put("iss", "f59509e6-dd17-4644-b832-ff05233146c8");
|
||||
jwtPayload.put("aud", "iap-v1");
|
||||
jwtPayload.put("iat", DateUtil.currentSeconds());
|
||||
jwtPayload.put("exp", DateUtil.currentSeconds() + 1800L); // 半小时过期
|
||||
jwtPayload.put("aid", appId);
|
||||
jwtPayload.put("digest", getJwtPayloadDigest(body));
|
||||
|
||||
String token = HuaweiTokenGenerator.createToken(jwtHeader, jwtPayload);
|
||||
// String authorization = MessageFormat.format("Basic {0}", Base64.encodeBase64String(oriString.getBytes(StandardCharsets.UTF_8)));
|
||||
String authorization = MessageFormat.format("Bearer {0}", token);
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
headers.put("Authorization", authorization);
|
||||
headers.put("Content-Type", "application/json; charset=UTF-8");
|
||||
return headers;
|
||||
}
|
||||
|
||||
private static String getJwtPayloadDigest(Map<String, String> body) {
|
||||
try {
|
||||
MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
|
||||
messageDigest.update(JSON.toJSONString(body).getBytes(StandardCharsets.UTF_8));
|
||||
byte[] digestByte = messageDigest.digest();
|
||||
StringBuilder stringBuffer = new StringBuilder();
|
||||
String temp;
|
||||
for (byte aByte : digestByte) {
|
||||
temp = Integer.toHexString(aByte & 0xFF);
|
||||
if (temp.length() == 1) {
|
||||
stringBuffer.append("0");
|
||||
}
|
||||
stringBuffer.append(temp);
|
||||
}
|
||||
return stringBuffer.toString();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验签名信息,校验InAppPurchaseData中的productId、price、currency等信息的一致性
|
||||
*
|
||||
* @param content 结果字符串
|
||||
* @param sign 签名字符串
|
||||
* @param publicKey IAP公钥
|
||||
* @return 是否校验通过
|
||||
*/
|
||||
public static boolean checkSuccessOrder(String content, String sign, String publicKey, String signatureAlgorithm, OrderInfo orderInfo) {
|
||||
// 校验签名信息
|
||||
boolean checkRes = checkSign(content, sign, publicKey, StrUtil.blankToDefault(signatureAlgorithm, "SHA256WithRSA"));
|
||||
if (checkRes) {
|
||||
// 校验InAppPurchaseData中的productId、price、currency等信息的一致性
|
||||
checkRes = checkProductIdAndPriceAndCurrency(content, orderInfo);
|
||||
}
|
||||
return checkRes;
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验InAppPurchaseData中的productId、price、currency等信息的一致性
|
||||
*
|
||||
* @param content 结果字符串
|
||||
* @param orderInfo 您的订单信息,包括productId、price、currency
|
||||
* @return 是否校验通过
|
||||
*/
|
||||
public static boolean checkProductIdAndPriceAndCurrency(String content, OrderInfo orderInfo) {
|
||||
InAppPurchaseData inAppPurchaseData = JSON.parseObject(content, InAppPurchaseData.class);
|
||||
// 校验InAppPurchaseData中的productId、price、currency等信息的一致性
|
||||
return inAppPurchaseData.getProductId().equals(orderInfo.getGoodsId())
|
||||
&& inAppPurchaseData.getPrice().equals(orderInfo.getOrderAmt());
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验签名信息
|
||||
*
|
||||
* @param content 结果字符串
|
||||
* @param sign 签名字符串
|
||||
* @param publicKey IAP公钥
|
||||
* @param signatureAlgorithm 签名算法字段,可从接口返回数据中获取,例如:OwnedPurchasesResult.getSignatureAlgorithm()
|
||||
* @return 是否校验通过
|
||||
*/
|
||||
public static boolean checkSign(String content, String sign, String publicKey, String signatureAlgorithm) {
|
||||
if (sign == null) {
|
||||
return false;
|
||||
}
|
||||
if (publicKey == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 当signatureAlgorithm为空时使用默认签名算法
|
||||
if (signatureAlgorithm == null || signatureAlgorithm.length() == 0) {
|
||||
signatureAlgorithm = "SHA256WithRSA";
|
||||
System.out.println("doCheck, algorithm: SHA256WithRSA");
|
||||
}
|
||||
try {
|
||||
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
|
||||
// 生成"RSA"的KeyFactory对象
|
||||
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
||||
byte[] decodedKey = Base64.decodeBase64(publicKey);
|
||||
// 生成公钥
|
||||
PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(decodedKey));
|
||||
java.security.Signature signature = null;
|
||||
// 根据SHA256WithRSA算法获取签名对象实例
|
||||
signature = java.security.Signature.getInstance(signatureAlgorithm);
|
||||
// 初始化验证签名的公钥
|
||||
signature.initVerify(pubKey);
|
||||
// 把原始报文更新到签名对象中
|
||||
signature.update(content.getBytes(StandardCharsets.UTF_8));
|
||||
// 将sign解码
|
||||
byte[] bsign = Base64.decodeBase64(sign);
|
||||
// 进行验签
|
||||
return signature.verify(bsign);
|
||||
} catch (RuntimeException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
package com.sf.payment.utils;
|
||||
import cn.hutool.core.io.resource.ClassPathResource;
|
||||
import com.auth0.jwt.JWT;
|
||||
import com.auth0.jwt.algorithms.Algorithm;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.interfaces.ECPrivateKey;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import java.util.Base64;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class HuaweiTokenGenerator {
|
||||
|
||||
public static String createToken(Map<String, Object> jwtHeader, Map<String, Object> jwtPayload) {
|
||||
try {
|
||||
// AppGallery Connect 华为应用内支付配置密钥,下载私钥文件
|
||||
ClassPathResource classPathResource = new ClassPathResource("IAPKey_0ae3e1be-374b-43a5-a297-045addbf76eb.p8");
|
||||
InputStream IAPKeyStream = classPathResource.getStream();
|
||||
String content = IOUtils.toString(IAPKeyStream, String.valueOf(StandardCharsets.UTF_8));
|
||||
String privateKey = content
|
||||
.replace("-----BEGIN PRIVATE KEY-----", "")
|
||||
.replaceAll("\\R+", "")
|
||||
.replace("-----END PRIVATE KEY-----", "");
|
||||
KeyFactory keyFactory = KeyFactory.getInstance("EC");
|
||||
byte[] privateKeyBytes = Base64.getDecoder().decode(privateKey);
|
||||
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
|
||||
ECPrivateKey ecPrivateKey = (ECPrivateKey) keyFactory.generatePrivate(keySpec);
|
||||
return JWT.create()
|
||||
.withHeader(jwtHeader)
|
||||
.withPayload(jwtPayload)
|
||||
.sign(Algorithm.ECDSA256(ecPrivateKey));
|
||||
} catch (IOException | NoSuchAlgorithmException | InvalidKeySpecException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQggG04243qynU/yWYy
|
||||
XpYVy9ZWMuLKzZiwhXCBWQBCOLigCgYIKoZIzj0DAQehRANCAARNln2/d+TM2pIO
|
||||
LWQzvI77gPAVEvVCSlIuiJ+J7CJSG5KCysBaEeiiD5cc4dZWnUBijF8FBh7nDLaH
|
||||
VwFXfrS+
|
||||
-----END PRIVATE KEY-----
|
33
sf-service/pom.xml
Normal file
33
sf-service/pom.xml
Normal file
@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>smarterFramework</artifactId>
|
||||
<groupId>com.smarterFramework</groupId>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>sf-service</artifactId>
|
||||
|
||||
<description>
|
||||
业务模块
|
||||
</description>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- 通用工具-->
|
||||
<dependency>
|
||||
<groupId>com.smarterFramework</groupId>
|
||||
<artifactId>sf-common</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.smarterFramework</groupId>
|
||||
<artifactId>sf-framework</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
@ -1,7 +1,10 @@
|
||||
package com.sf.goods.controller;
|
||||
package com.sf.service.controller;
|
||||
|
||||
import java.util.List;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.sf.service.domain.GoodsMessages;
|
||||
import com.sf.service.service.IGoodsMessagesService;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
@ -16,19 +19,17 @@ import com.sf.common.annotation.Log;
|
||||
import com.sf.common.core.controller.BaseController;
|
||||
import com.sf.common.core.domain.AjaxResult;
|
||||
import com.sf.common.enums.BusinessType;
|
||||
import com.sf.goods.domain.GoodsMessages;
|
||||
import com.sf.goods.service.IGoodsMessagesService;
|
||||
import com.sf.common.utils.poi.ExcelUtil;
|
||||
import com.sf.common.core.page.TableDataInfo;
|
||||
|
||||
/**
|
||||
* 商品信息Controller
|
||||
*
|
||||
* @author ztzh
|
||||
* @date 2024-04-11
|
||||
*
|
||||
* @author zoukun
|
||||
* @date 2024-04-18
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/goods/goods")
|
||||
@RequestMapping("/service/goods")
|
||||
public class GoodsMessagesController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
@ -37,7 +38,6 @@ public class GoodsMessagesController extends BaseController
|
||||
/**
|
||||
* 查询商品信息列表
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('goods:goods:list')")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(GoodsMessages goodsMessages)
|
||||
{
|
||||
@ -49,7 +49,7 @@ public class GoodsMessagesController extends BaseController
|
||||
/**
|
||||
* 导出商品信息列表
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('goods:goods:export')")
|
||||
@PreAuthorize("@ss.hasPermi('service:goods:export')")
|
||||
@Log(title = "商品信息", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(HttpServletResponse response, GoodsMessages goodsMessages)
|
||||
@ -62,7 +62,7 @@ public class GoodsMessagesController extends BaseController
|
||||
/**
|
||||
* 获取商品信息详细信息
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('goods:goods:query')")
|
||||
@PreAuthorize("@ss.hasPermi('service:goods:query')")
|
||||
@GetMapping(value = "/{id}")
|
||||
public AjaxResult getInfo(@PathVariable("id") Long id)
|
||||
{
|
||||
@ -72,7 +72,7 @@ public class GoodsMessagesController extends BaseController
|
||||
/**
|
||||
* 新增商品信息
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('goods:goods:add')")
|
||||
@PreAuthorize("@ss.hasPermi('service:goods:add')")
|
||||
@Log(title = "商品信息", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public AjaxResult add(@RequestBody GoodsMessages goodsMessages)
|
||||
@ -83,7 +83,7 @@ public class GoodsMessagesController extends BaseController
|
||||
/**
|
||||
* 修改商品信息
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('goods:goods:edit')")
|
||||
@PreAuthorize("@ss.hasPermi('service:goods:edit')")
|
||||
@Log(title = "商品信息", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public AjaxResult edit(@RequestBody GoodsMessages goodsMessages)
|
||||
@ -94,9 +94,9 @@ public class GoodsMessagesController extends BaseController
|
||||
/**
|
||||
* 删除商品信息
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('goods:goods:remove')")
|
||||
@PreAuthorize("@ss.hasPermi('service:goods:remove')")
|
||||
@Log(title = "商品信息", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{ids}")
|
||||
@DeleteMapping("/{ids}")
|
||||
public AjaxResult remove(@PathVariable Long[] ids)
|
||||
{
|
||||
return toAjax(goodsMessagesService.deleteGoodsMessagesByIds(ids));
|
@ -1,4 +1,4 @@
|
||||
package com.sf.goods.domain;
|
||||
package com.sf.service.domain;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
@ -8,8 +8,8 @@ import com.sf.common.core.domain.BaseEntity;
|
||||
/**
|
||||
* 商品信息对象 GOODS_MESSAGES
|
||||
*
|
||||
* @author ztzh
|
||||
* @date 2024-04-11
|
||||
* @author zoukun
|
||||
* @date 2024-04-18
|
||||
*/
|
||||
public class GoodsMessages extends BaseEntity
|
||||
{
|
||||
@ -26,6 +26,7 @@ public class GoodsMessages extends BaseEntity
|
||||
private Long stockId;
|
||||
|
||||
/** 审核状态,1通过,0未通过 */
|
||||
@Excel(name = "审核状态,1通过,0未通过")
|
||||
private Long reviewStatus;
|
||||
|
||||
/** 商品标题 */
|
||||
@ -36,16 +37,23 @@ public class GoodsMessages extends BaseEntity
|
||||
@Excel(name = "商品图片")
|
||||
private String productPicture;
|
||||
|
||||
/** 原价格 */
|
||||
@Excel(name = "原价格")
|
||||
/** 商品原价 */
|
||||
@Excel(name = "商品原价")
|
||||
private Long originalPrice;
|
||||
|
||||
/** 商品描述 */
|
||||
@Excel(name = "商品描述")
|
||||
private String productDesc;
|
||||
|
||||
/** 商品类型。 * • 0:消耗型商品 * • 1:非消耗型商品 * • 2:自动续期订阅商品 */
|
||||
@Excel(name = "商品类型。 * • 0:消耗型商品 * • 1:非消耗型商品 * • 2:自动续期订阅商品")
|
||||
private Integer goodsType;
|
||||
|
||||
/** 商品规格 */
|
||||
@Excel(name = "商品规格")
|
||||
private String goodsSpec;
|
||||
|
||||
/** 排序 */
|
||||
@Excel(name = "排序")
|
||||
private Long orderNum;
|
||||
|
||||
/** 逻辑删除,0:未删除,1:删除 */
|
||||
@ -57,13 +65,12 @@ public class GoodsMessages extends BaseEntity
|
||||
/** 更新人 */
|
||||
private String modified;
|
||||
|
||||
/** 商品类型 */
|
||||
@Excel(name = "商品类型")
|
||||
private String goodsType;
|
||||
/** 商品名称 */
|
||||
private String goodsName;
|
||||
|
||||
/** 商品规格 */
|
||||
@Excel(name = "商品规格")
|
||||
private String goodsSpec;
|
||||
/** 商品型号 */
|
||||
@Excel(name = "商品型号")
|
||||
private String goodsModel;
|
||||
|
||||
public void setId(Long id)
|
||||
{
|
||||
@ -137,6 +144,24 @@ public class GoodsMessages extends BaseEntity
|
||||
{
|
||||
return productDesc;
|
||||
}
|
||||
public void setGoodsType(Integer goodsType)
|
||||
{
|
||||
this.goodsType = goodsType;
|
||||
}
|
||||
|
||||
public Integer getGoodsType()
|
||||
{
|
||||
return goodsType;
|
||||
}
|
||||
public void setGoodsSpec(String goodsSpec)
|
||||
{
|
||||
this.goodsSpec = goodsSpec;
|
||||
}
|
||||
|
||||
public String getGoodsSpec()
|
||||
{
|
||||
return goodsSpec;
|
||||
}
|
||||
public void setOrderNum(Long orderNum)
|
||||
{
|
||||
this.orderNum = orderNum;
|
||||
@ -173,23 +198,23 @@ public class GoodsMessages extends BaseEntity
|
||||
{
|
||||
return modified;
|
||||
}
|
||||
public void setGoodsType(String goodsType)
|
||||
public void setGoodsName(String goodsName)
|
||||
{
|
||||
this.goodsType = goodsType;
|
||||
this.goodsName = goodsName;
|
||||
}
|
||||
|
||||
public String getGoodsType()
|
||||
public String getGoodsName()
|
||||
{
|
||||
return goodsType;
|
||||
return goodsName;
|
||||
}
|
||||
public void setGoodsSpec(String goodsSpec)
|
||||
public void setGoodsModel(String goodsModel)
|
||||
{
|
||||
this.goodsSpec = goodsSpec;
|
||||
this.goodsModel = goodsModel;
|
||||
}
|
||||
|
||||
public String getGoodsSpec()
|
||||
public String getGoodsModel()
|
||||
{
|
||||
return goodsSpec;
|
||||
return goodsModel;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -203,14 +228,16 @@ public class GoodsMessages extends BaseEntity
|
||||
.append("productPicture", getProductPicture())
|
||||
.append("originalPrice", getOriginalPrice())
|
||||
.append("productDesc", getProductDesc())
|
||||
.append("goodsType", getGoodsType())
|
||||
.append("goodsSpec", getGoodsSpec())
|
||||
.append("orderNum", getOrderNum())
|
||||
.append("isDelete", getIsDelete())
|
||||
.append("created", getCreated())
|
||||
.append("modified", getModified())
|
||||
.append("createTime", getCreateTime())
|
||||
.append("updateTime", getUpdateTime())
|
||||
.append("goodsType", getGoodsType())
|
||||
.append("goodsSpec", getGoodsSpec())
|
||||
.append("goodsName", getGoodsName())
|
||||
.append("goodsModel", getGoodsModel())
|
||||
.toString();
|
||||
}
|
||||
}
|
@ -1,13 +1,13 @@
|
||||
package com.sf.goods.mapper;
|
||||
package com.sf.service.mapper;
|
||||
|
||||
import java.util.List;
|
||||
import com.sf.goods.domain.GoodsMessages;
|
||||
import com.sf.service.domain.GoodsMessages;
|
||||
|
||||
/**
|
||||
* 商品信息Mapper接口
|
||||
*
|
||||
* @author ztzh
|
||||
* @date 2024-04-11
|
||||
* @author zoukun
|
||||
* @date 2024-04-18
|
||||
*/
|
||||
public interface GoodsMessagesMapper
|
||||
{
|
||||
@ -58,4 +58,6 @@ public interface GoodsMessagesMapper
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteGoodsMessagesByIds(Long[] ids);
|
||||
|
||||
GoodsMessages selectGoodsMessagesByCode(String goodsCode);
|
||||
}
|
@ -1,13 +1,13 @@
|
||||
package com.sf.goods.service;
|
||||
package com.sf.service.service;
|
||||
|
||||
import java.util.List;
|
||||
import com.sf.goods.domain.GoodsMessages;
|
||||
import com.sf.service.domain.GoodsMessages;
|
||||
|
||||
/**
|
||||
* 商品信息Service接口
|
||||
*
|
||||
* @author ztzh
|
||||
* @date 2024-04-11
|
||||
* @author zoukun
|
||||
* @date 2024-04-18
|
||||
*/
|
||||
public interface IGoodsMessagesService
|
||||
{
|
||||
@ -58,4 +58,6 @@ public interface IGoodsMessagesService
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteGoodsMessagesById(Long id);
|
||||
|
||||
GoodsMessages selectGoodsMessagesByCode(String goodsCode);
|
||||
}
|
@ -1,18 +1,19 @@
|
||||
package com.sf.goods.service.impl;
|
||||
package com.sf.service.service.impl;
|
||||
|
||||
import java.util.List;
|
||||
import com.sf.common.utils.DateUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.sf.goods.mapper.GoodsMessagesMapper;
|
||||
import com.sf.goods.domain.GoodsMessages;
|
||||
import com.sf.goods.service.IGoodsMessagesService;
|
||||
import com.sf.service.mapper.GoodsMessagesMapper;
|
||||
import com.sf.service.domain.GoodsMessages;
|
||||
import com.sf.service.service.IGoodsMessagesService;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* 商品信息Service业务层处理
|
||||
*
|
||||
* @author ztzh
|
||||
* @date 2024-04-11
|
||||
* @author zoukun
|
||||
* @date 2024-04-18
|
||||
*/
|
||||
@Service
|
||||
public class GoodsMessagesServiceImpl implements IGoodsMessagesService
|
||||
@ -93,4 +94,12 @@ public class GoodsMessagesServiceImpl implements IGoodsMessagesService
|
||||
{
|
||||
return goodsMessagesMapper.deleteGoodsMessagesById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GoodsMessages selectGoodsMessagesByCode(String goodsCode) {
|
||||
if (StringUtils.hasText(goodsCode)){
|
||||
return goodsMessagesMapper.selectGoodsMessagesByCode(goodsCode);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -1,118 +1,130 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.sf.goods.mapper.GoodsMessagesMapper">
|
||||
|
||||
<resultMap type="GoodsMessages" id="GoodsMessagesResult">
|
||||
<result property="id" column="id" />
|
||||
<result property="goodsCode" column="goods_code" />
|
||||
<result property="stockId" column="stock_id" />
|
||||
<result property="reviewStatus" column="review_status" />
|
||||
<result property="productTitle" column="product_title" />
|
||||
<result property="productPicture" column="product_picture" />
|
||||
<result property="originalPrice" column="original_price" />
|
||||
<result property="productDesc" column="product_desc" />
|
||||
<result property="orderNum" column="order_num" />
|
||||
<result property="isDelete" column="is_delete" />
|
||||
<result property="created" column="created" />
|
||||
<result property="modified" column="modified" />
|
||||
<result property="createTime" column="create_time" />
|
||||
<result property="updateTime" column="update_time" />
|
||||
<result property="goodsType" column="goods_type" />
|
||||
<result property="goodsSpec" column="goods_spec" />
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectGoodsMessagesVo">
|
||||
select id, goods_code, stock_id, review_status, product_title, product_picture, original_price, product_desc, order_num, is_delete, created, modified, create_time, update_time, goods_type, goods_spec from GOODS_MESSAGES
|
||||
</sql>
|
||||
|
||||
<select id="selectGoodsMessagesList" parameterType="GoodsMessages" resultMap="GoodsMessagesResult">
|
||||
<include refid="selectGoodsMessagesVo"/>
|
||||
<where>
|
||||
<if test="goodsCode != null and goodsCode != ''"> and goods_code = #{goodsCode}</if>
|
||||
<if test="productTitle != null and productTitle != ''"> and product_title like concat('%', #{productTitle}, '%')</if>
|
||||
<if test="goodsType != null and goodsType != ''"> and goods_type = #{goodsType}</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<select id="selectGoodsMessagesById" parameterType="Long" resultMap="GoodsMessagesResult">
|
||||
<include refid="selectGoodsMessagesVo"/>
|
||||
where id = #{id}
|
||||
</select>
|
||||
<select id="selectGoodsMessagesByCode" parameterType="java.lang.String" resultMap="GoodsMessagesResult">
|
||||
<include refid="selectGoodsMessagesVo"/>
|
||||
where goods_code = #{code}
|
||||
</select>
|
||||
|
||||
<insert id="insertGoodsMessages" parameterType="GoodsMessages" useGeneratedKeys="true" keyProperty="id">
|
||||
insert into GOODS_MESSAGES
|
||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||
<if test="goodsCode != null and goodsCode != ''">goods_code,</if>
|
||||
<if test="stockId != null">stock_id,</if>
|
||||
<if test="reviewStatus != null">review_status,</if>
|
||||
<if test="productTitle != null and productTitle != ''">product_title,</if>
|
||||
<if test="productPicture != null and productPicture != ''">product_picture,</if>
|
||||
<if test="originalPrice != null">original_price,</if>
|
||||
<if test="productDesc != null">product_desc,</if>
|
||||
<if test="orderNum != null">order_num,</if>
|
||||
<if test="isDelete != null">is_delete,</if>
|
||||
<if test="created != null">created,</if>
|
||||
<if test="modified != null">modified,</if>
|
||||
<if test="createTime != null">create_time,</if>
|
||||
<if test="updateTime != null">update_time,</if>
|
||||
<if test="goodsType != null and goodsType != ''">goods_type,</if>
|
||||
<if test="goodsSpec != null and goodsSpec != ''">goods_spec,</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="goodsCode != null and goodsCode != ''">#{goodsCode},</if>
|
||||
<if test="stockId != null">#{stockId},</if>
|
||||
<if test="reviewStatus != null">#{reviewStatus},</if>
|
||||
<if test="productTitle != null and productTitle != ''">#{productTitle},</if>
|
||||
<if test="productPicture != null and productPicture != ''">#{productPicture},</if>
|
||||
<if test="originalPrice != null">#{originalPrice},</if>
|
||||
<if test="productDesc != null">#{productDesc},</if>
|
||||
<if test="orderNum != null">#{orderNum},</if>
|
||||
<if test="isDelete != null">#{isDelete},</if>
|
||||
<if test="created != null">#{created},</if>
|
||||
<if test="modified != null">#{modified},</if>
|
||||
<if test="createTime != null">#{createTime},</if>
|
||||
<if test="updateTime != null">#{updateTime},</if>
|
||||
<if test="goodsType != null and goodsType != ''">#{goodsType},</if>
|
||||
<if test="goodsSpec != null and goodsSpec != ''">#{goodsSpec},</if>
|
||||
</trim>
|
||||
</insert>
|
||||
|
||||
<update id="updateGoodsMessages" parameterType="GoodsMessages">
|
||||
update GOODS_MESSAGES
|
||||
<trim prefix="SET" suffixOverrides=",">
|
||||
<if test="goodsCode != null and goodsCode != ''">goods_code = #{goodsCode},</if>
|
||||
<if test="stockId != null">stock_id = #{stockId},</if>
|
||||
<if test="reviewStatus != null">review_status = #{reviewStatus},</if>
|
||||
<if test="productTitle != null and productTitle != ''">product_title = #{productTitle},</if>
|
||||
<if test="productPicture != null and productPicture != ''">product_picture = #{productPicture},</if>
|
||||
<if test="originalPrice != null">original_price = #{originalPrice},</if>
|
||||
<if test="productDesc != null">product_desc = #{productDesc},</if>
|
||||
<if test="orderNum != null">order_num = #{orderNum},</if>
|
||||
<if test="isDelete != null">is_delete = #{isDelete},</if>
|
||||
<if test="created != null">created = #{created},</if>
|
||||
<if test="modified != null">modified = #{modified},</if>
|
||||
<if test="createTime != null">create_time = #{createTime},</if>
|
||||
<if test="updateTime != null">update_time = #{updateTime},</if>
|
||||
<if test="goodsType != null and goodsType != ''">goods_type = #{goodsType},</if>
|
||||
<if test="goodsSpec != null and goodsSpec != ''">goods_spec = #{goodsSpec},</if>
|
||||
</trim>
|
||||
where id = #{id}
|
||||
</update>
|
||||
|
||||
<delete id="deleteGoodsMessagesById" parameterType="Long">
|
||||
delete from GOODS_MESSAGES where id = #{id}
|
||||
</delete>
|
||||
|
||||
<delete id="deleteGoodsMessagesByIds" parameterType="String">
|
||||
delete from GOODS_MESSAGES where id in
|
||||
<foreach item="id" collection="array" open="(" separator="," close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
</delete>
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.sf.service.mapper.GoodsMessagesMapper">
|
||||
|
||||
<resultMap type="GoodsMessages" id="GoodsMessagesResult">
|
||||
<result property="id" column="id" />
|
||||
<result property="goodsCode" column="goods_code" />
|
||||
<result property="stockId" column="stock_id" />
|
||||
<result property="reviewStatus" column="review_status" />
|
||||
<result property="productTitle" column="product_title" />
|
||||
<result property="productPicture" column="product_picture" />
|
||||
<result property="originalPrice" column="original_price" />
|
||||
<result property="productDesc" column="product_desc" />
|
||||
<result property="goodsType" column="goods_type" />
|
||||
<result property="goodsSpec" column="goods_spec" />
|
||||
<result property="orderNum" column="order_num" />
|
||||
<result property="isDelete" column="is_delete" />
|
||||
<result property="created" column="created" />
|
||||
<result property="modified" column="modified" />
|
||||
<result property="createTime" column="create_time" />
|
||||
<result property="updateTime" column="update_time" />
|
||||
<result property="goodsName" column="goods_name" />
|
||||
<result property="goodsModel" column="goods_model" />
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectGoodsMessagesVo">
|
||||
select id, goods_code, stock_id, review_status, product_title, product_picture, original_price, product_desc, goods_type, goods_spec, order_num, is_delete, created, modified, create_time, update_time, goods_name, goods_model from GOODS_MESSAGES
|
||||
</sql>
|
||||
|
||||
<select id="selectGoodsMessagesList" parameterType="GoodsMessages" resultMap="GoodsMessagesResult">
|
||||
<include refid="selectGoodsMessagesVo"/>
|
||||
<where>
|
||||
<if test="goodsCode != null and goodsCode != ''"> and goods_code = #{goodsCode}</if>
|
||||
<if test="reviewStatus != null "> and review_status = #{reviewStatus}</if>
|
||||
<if test="productTitle != null and productTitle != ''"> and product_title like concat('%', #{productTitle}, '%')</if>
|
||||
<if test="params.beginOriginalPrice != null and params.beginOriginalPrice != '' and params.endOriginalPrice != null and params.endOriginalPrice != ''"> and original_price between #{params.beginOriginalPrice} and #{params.endOriginalPrice}</if>
|
||||
<if test="goodsType != null "> and goods_type = #{goodsType}</if>
|
||||
<if test="goodsSpec != null and goodsSpec != ''"> and goods_spec = #{goodsSpec}</if>
|
||||
<if test="goodsModel != null and goodsModel != ''"> and goods_model = #{goodsModel}</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<select id="selectGoodsMessagesById" parameterType="Long" resultMap="GoodsMessagesResult">
|
||||
<include refid="selectGoodsMessagesVo"/>
|
||||
where id = #{id}
|
||||
</select>
|
||||
<select id="selectGoodsMessagesByCode" parameterType="String" resultMap="GoodsMessagesResult">
|
||||
<include refid="selectGoodsMessagesVo"/>
|
||||
where goods_code = #{goodsCode}
|
||||
</select>
|
||||
|
||||
<insert id="insertGoodsMessages" parameterType="GoodsMessages" useGeneratedKeys="true" keyProperty="id">
|
||||
insert into GOODS_MESSAGES
|
||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||
<if test="goodsCode != null and goodsCode != ''">goods_code,</if>
|
||||
<if test="stockId != null">stock_id,</if>
|
||||
<if test="reviewStatus != null">review_status,</if>
|
||||
<if test="productTitle != null and productTitle != ''">product_title,</if>
|
||||
<if test="productPicture != null and productPicture != ''">product_picture,</if>
|
||||
<if test="originalPrice != null">original_price,</if>
|
||||
<if test="productDesc != null">product_desc,</if>
|
||||
<if test="goodsType != null">goods_type,</if>
|
||||
<if test="goodsSpec != null and goodsSpec != ''">goods_spec,</if>
|
||||
<if test="orderNum != null">order_num,</if>
|
||||
<if test="isDelete != null">is_delete,</if>
|
||||
<if test="created != null">created,</if>
|
||||
<if test="modified != null">modified,</if>
|
||||
<if test="createTime != null">create_time,</if>
|
||||
<if test="updateTime != null">update_time,</if>
|
||||
<if test="goodsName != null and goodsName != ''">goods_name,</if>
|
||||
<if test="goodsModel != null">goods_model,</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="goodsCode != null and goodsCode != ''">#{goodsCode},</if>
|
||||
<if test="stockId != null">#{stockId},</if>
|
||||
<if test="reviewStatus != null">#{reviewStatus},</if>
|
||||
<if test="productTitle != null and productTitle != ''">#{productTitle},</if>
|
||||
<if test="productPicture != null and productPicture != ''">#{productPicture},</if>
|
||||
<if test="originalPrice != null">#{originalPrice},</if>
|
||||
<if test="productDesc != null">#{productDesc},</if>
|
||||
<if test="goodsType != null">#{goodsType},</if>
|
||||
<if test="goodsSpec != null and goodsSpec != ''">#{goodsSpec},</if>
|
||||
<if test="orderNum != null">#{orderNum},</if>
|
||||
<if test="isDelete != null">#{isDelete},</if>
|
||||
<if test="created != null">#{created},</if>
|
||||
<if test="modified != null">#{modified},</if>
|
||||
<if test="createTime != null">#{createTime},</if>
|
||||
<if test="updateTime != null">#{updateTime},</if>
|
||||
<if test="goodsName != null and goodsName != ''">#{goodsName},</if>
|
||||
<if test="goodsModel != null">#{goodsModel},</if>
|
||||
</trim>
|
||||
</insert>
|
||||
|
||||
<update id="updateGoodsMessages" parameterType="GoodsMessages">
|
||||
update GOODS_MESSAGES
|
||||
<trim prefix="SET" suffixOverrides=",">
|
||||
<if test="goodsCode != null and goodsCode != ''">goods_code = #{goodsCode},</if>
|
||||
<if test="stockId != null">stock_id = #{stockId},</if>
|
||||
<if test="reviewStatus != null">review_status = #{reviewStatus},</if>
|
||||
<if test="productTitle != null and productTitle != ''">product_title = #{productTitle},</if>
|
||||
<if test="productPicture != null and productPicture != ''">product_picture = #{productPicture},</if>
|
||||
<if test="originalPrice != null">original_price = #{originalPrice},</if>
|
||||
<if test="productDesc != null">product_desc = #{productDesc},</if>
|
||||
<if test="goodsType != null">goods_type = #{goodsType},</if>
|
||||
<if test="goodsSpec != null and goodsSpec != ''">goods_spec = #{goodsSpec},</if>
|
||||
<if test="orderNum != null">order_num = #{orderNum},</if>
|
||||
<if test="isDelete != null">is_delete = #{isDelete},</if>
|
||||
<if test="created != null">created = #{created},</if>
|
||||
<if test="modified != null">modified = #{modified},</if>
|
||||
<if test="createTime != null">create_time = #{createTime},</if>
|
||||
<if test="updateTime != null">update_time = #{updateTime},</if>
|
||||
<if test="goodsName != null and goodsName != ''">goods_name = #{goodsName},</if>
|
||||
<if test="goodsModel != null">goods_model = #{goodsModel},</if>
|
||||
</trim>
|
||||
where id = #{id}
|
||||
</update>
|
||||
|
||||
<delete id="deleteGoodsMessagesById" parameterType="Long">
|
||||
delete from GOODS_MESSAGES where id = #{id}
|
||||
</delete>
|
||||
|
||||
<delete id="deleteGoodsMessagesByIds" parameterType="String">
|
||||
delete from GOODS_MESSAGES where id in
|
||||
<foreach item="id" collection="array" open="(" separator="," close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
</delete>
|
||||
</mapper>
|
110
sf-system/src/main/java/com/sf/system/domain/UserMember.java
Normal file
110
sf-system/src/main/java/com/sf/system/domain/UserMember.java
Normal file
@ -0,0 +1,110 @@
|
||||
package com.sf.system.domain;
|
||||
|
||||
import java.util.Date;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
import com.sf.common.annotation.Excel;
|
||||
import com.sf.common.core.domain.BaseEntity;
|
||||
|
||||
/**
|
||||
* 会员对象 User_member
|
||||
*
|
||||
* @author ztzh
|
||||
* @date 2024-04-16
|
||||
*/
|
||||
public class UserMember extends BaseEntity
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** $column.columnComment */
|
||||
private Long id;
|
||||
|
||||
/** 用户会员等级(0普通会员 1订阅会员 2月度会员) */
|
||||
@Excel(name = "用户会员等级", readConverterExp = "0=普通会员,1=订阅会员,2=月度会员")
|
||||
private Integer memberLevel;
|
||||
|
||||
/** 会员等级为订阅会员时的订阅状态,未订阅就是取消了(0未订阅 1已订阅) */
|
||||
@Excel(name = "会员等级为订阅会员时的订阅状态,未订阅就是取消了", readConverterExp = "0=未订阅,1=已订阅")
|
||||
private Integer subscriptionStatus;
|
||||
|
||||
/** 关联的用户id */
|
||||
@Excel(name = "关联的用户id")
|
||||
private Long userId;
|
||||
|
||||
/** 积分 */
|
||||
@Excel(name = "积分")
|
||||
private Long integration;
|
||||
|
||||
/** 过期时间 */
|
||||
private Date expirationTime;
|
||||
|
||||
public void setId(Long id)
|
||||
{
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Long getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
public void setMemberLevel(Integer memberLevel)
|
||||
{
|
||||
this.memberLevel = memberLevel;
|
||||
}
|
||||
|
||||
public Integer getMemberLevel()
|
||||
{
|
||||
return memberLevel;
|
||||
}
|
||||
public void setSubscriptionStatus(Integer subscriptionStatus)
|
||||
{
|
||||
this.subscriptionStatus = subscriptionStatus;
|
||||
}
|
||||
|
||||
public Integer getSubscriptionStatus()
|
||||
{
|
||||
return subscriptionStatus;
|
||||
}
|
||||
public void setUserId(Long userId)
|
||||
{
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public Long getUserId()
|
||||
{
|
||||
return userId;
|
||||
}
|
||||
public void setIntegration(Long integration)
|
||||
{
|
||||
this.integration = integration;
|
||||
}
|
||||
|
||||
public Long getIntegration()
|
||||
{
|
||||
return integration;
|
||||
}
|
||||
public void setExpirationTime(Date expirationTime)
|
||||
{
|
||||
this.expirationTime = expirationTime;
|
||||
}
|
||||
|
||||
public Date getExpirationTime()
|
||||
{
|
||||
return expirationTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
||||
.append("id", getId())
|
||||
.append("memberLevel", getMemberLevel())
|
||||
.append("subscriptionStatus", getSubscriptionStatus())
|
||||
.append("userId", getUserId())
|
||||
.append("createTime", getCreateTime())
|
||||
.append("updateTime", getUpdateTime())
|
||||
.append("integration", getIntegration())
|
||||
.append("expirationTime", getExpirationTime())
|
||||
.toString();
|
||||
}
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
package com.sf.system.mapper;
|
||||
|
||||
import java.util.List;
|
||||
import com.sf.system.domain.UserMember;
|
||||
|
||||
/**
|
||||
* 会员Mapper接口
|
||||
*
|
||||
* @author ztzh
|
||||
* @date 2024-04-16
|
||||
*/
|
||||
public interface UserMemberMapper
|
||||
{
|
||||
/**
|
||||
* 查询会员
|
||||
*
|
||||
* @param id 会员主键
|
||||
* @return 会员
|
||||
*/
|
||||
public UserMember selectUserMemberById(Long id);
|
||||
|
||||
/**
|
||||
* 查询会员列表
|
||||
*
|
||||
* @param userMember 会员
|
||||
* @return 会员集合
|
||||
*/
|
||||
public List<UserMember> selectUserMemberList(UserMember userMember);
|
||||
|
||||
/**
|
||||
* 新增会员
|
||||
*
|
||||
* @param userMember 会员
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertUserMember(UserMember userMember);
|
||||
|
||||
/**
|
||||
* 修改会员
|
||||
*
|
||||
* @param userMember 会员
|
||||
* @return 结果
|
||||
*/
|
||||
public int updateUserMember(UserMember userMember);
|
||||
|
||||
/**
|
||||
* 删除会员
|
||||
*
|
||||
* @param id 会员主键
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteUserMemberById(Long id);
|
||||
|
||||
/**
|
||||
* 批量删除会员
|
||||
*
|
||||
* @param ids 需要删除的数据主键集合
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteUserMemberByIds(Long[] ids);
|
||||
|
||||
UserMember selectUserMemberByUserId(Long userId);
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
package com.sf.system.service;
|
||||
|
||||
import java.util.List;
|
||||
import com.sf.system.domain.UserMember;
|
||||
|
||||
/**
|
||||
* 会员Service接口
|
||||
*
|
||||
* @author ztzh
|
||||
* @date 2024-04-16
|
||||
*/
|
||||
public interface IUserMemberService
|
||||
{
|
||||
/**
|
||||
* 查询会员
|
||||
*
|
||||
* @param id 会员主键
|
||||
* @return 会员
|
||||
*/
|
||||
public UserMember selectUserMemberById(Long id);
|
||||
|
||||
/**
|
||||
* 查询会员列表
|
||||
*
|
||||
* @param userMember 会员
|
||||
* @return 会员集合
|
||||
*/
|
||||
public List<UserMember> selectUserMemberList(UserMember userMember);
|
||||
|
||||
/**
|
||||
* 新增会员
|
||||
*
|
||||
* @param userMember 会员
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertUserMember(UserMember userMember);
|
||||
|
||||
/**
|
||||
* 修改会员
|
||||
*
|
||||
* @param userMember 会员
|
||||
* @return 结果
|
||||
*/
|
||||
public int updateUserMember(UserMember userMember);
|
||||
|
||||
/**
|
||||
* 批量删除会员
|
||||
*
|
||||
* @param ids 需要删除的会员主键集合
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteUserMemberByIds(Long[] ids);
|
||||
|
||||
/**
|
||||
* 删除会员信息
|
||||
*
|
||||
* @param id 会员主键
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteUserMemberById(Long id);
|
||||
|
||||
UserMember selectUserMemberByUserId(Long userId);
|
||||
}
|
@ -0,0 +1,101 @@
|
||||
package com.sf.system.service.impl;
|
||||
|
||||
import java.util.List;
|
||||
import com.sf.common.utils.DateUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.sf.system.mapper.UserMemberMapper;
|
||||
import com.sf.system.domain.UserMember;
|
||||
import com.sf.system.service.IUserMemberService;
|
||||
|
||||
/**
|
||||
* 会员Service业务层处理
|
||||
*
|
||||
* @author ztzh
|
||||
* @date 2024-04-16
|
||||
*/
|
||||
@Service
|
||||
public class UserMemberServiceImpl implements IUserMemberService
|
||||
{
|
||||
@Autowired
|
||||
private UserMemberMapper userMemberMapper;
|
||||
|
||||
/**
|
||||
* 查询会员
|
||||
*
|
||||
* @param id 会员主键
|
||||
* @return 会员
|
||||
*/
|
||||
@Override
|
||||
public UserMember selectUserMemberById(Long id)
|
||||
{
|
||||
return userMemberMapper.selectUserMemberById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询会员列表
|
||||
*
|
||||
* @param userMember 会员
|
||||
* @return 会员
|
||||
*/
|
||||
@Override
|
||||
public List<UserMember> selectUserMemberList(UserMember userMember)
|
||||
{
|
||||
return userMemberMapper.selectUserMemberList(userMember);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增会员
|
||||
*
|
||||
* @param userMember 会员
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int insertUserMember(UserMember userMember)
|
||||
{
|
||||
userMember.setCreateTime(DateUtils.getNowDate());
|
||||
return userMemberMapper.insertUserMember(userMember);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改会员
|
||||
*
|
||||
* @param userMember 会员
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int updateUserMember(UserMember userMember)
|
||||
{
|
||||
userMember.setUpdateTime(DateUtils.getNowDate());
|
||||
return userMemberMapper.updateUserMember(userMember);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除会员
|
||||
*
|
||||
* @param ids 需要删除的会员主键
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int deleteUserMemberByIds(Long[] ids)
|
||||
{
|
||||
return userMemberMapper.deleteUserMemberByIds(ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除会员信息
|
||||
*
|
||||
* @param id 会员主键
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int deleteUserMemberById(Long id)
|
||||
{
|
||||
return userMemberMapper.deleteUserMemberById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserMember selectUserMemberByUserId(Long userId) {
|
||||
return userMemberMapper.selectUserMemberByUserId(userId);
|
||||
}
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.sf.system.mapper.UserMemberMapper">
|
||||
|
||||
<resultMap type="UserMember" id="UserMemberResult">
|
||||
<result property="id" column="id" />
|
||||
<result property="memberLevel" column="member_level" />
|
||||
<result property="subscriptionStatus" column="subscription_status" />
|
||||
<result property="userId" column="user_id" />
|
||||
<result property="createTime" column="create_time" />
|
||||
<result property="updateTime" column="update_time" />
|
||||
<result property="integration" column="integration" />
|
||||
<result property="expirationTime" column="expiration_time" />
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectUserMemberVo">
|
||||
select id, member_level, subscription_status, user_id, create_time, update_time, integration, expiration_time from User_member
|
||||
</sql>
|
||||
|
||||
<select id="selectUserMemberList" parameterType="UserMember" resultMap="UserMemberResult">
|
||||
<include refid="selectUserMemberVo"/>
|
||||
<where>
|
||||
<if test="memberLevel != null "> and member_level = #{memberLevel}</if>
|
||||
<if test="subscriptionStatus != null "> and subscription_status = #{subscriptionStatus}</if>
|
||||
<if test="userId != null "> and user_id = #{userId}</if>
|
||||
<if test="integration != null "> and integration = #{integration}</if>
|
||||
<if test="expirationTime != null "> and expiration_time = #{expirationTime}</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<select id="selectUserMemberById" parameterType="Long" resultMap="UserMemberResult">
|
||||
<include refid="selectUserMemberVo"/>
|
||||
where id = #{id}
|
||||
</select>
|
||||
|
||||
<select id="selectUserMemberByUserId" resultMap="UserMemberResult">
|
||||
<include refid="selectUserMemberVo"/>
|
||||
where user_id = #{userId}
|
||||
</select>
|
||||
|
||||
<insert id="insertUserMember" parameterType="UserMember" useGeneratedKeys="true" keyProperty="id">
|
||||
insert into User_member
|
||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||
<if test="memberLevel != null">member_level,</if>
|
||||
<if test="subscriptionStatus != null">subscription_status,</if>
|
||||
<if test="userId != null">user_id,</if>
|
||||
<if test="createTime != null">create_time,</if>
|
||||
<if test="updateTime != null">update_time,</if>
|
||||
<if test="integration != null">integration,</if>
|
||||
<if test="expirationTime != null">expiration_time,</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="memberLevel != null">#{memberLevel},</if>
|
||||
<if test="subscriptionStatus != null">#{subscriptionStatus},</if>
|
||||
<if test="userId != null">#{userId},</if>
|
||||
<if test="createTime != null">#{createTime},</if>
|
||||
<if test="updateTime != null">#{updateTime},</if>
|
||||
<if test="integration != null">#{integration},</if>
|
||||
<if test="expirationTime != null">#{expirationTime},</if>
|
||||
</trim>
|
||||
</insert>
|
||||
|
||||
<update id="updateUserMember" parameterType="UserMember">
|
||||
update User_member
|
||||
<trim prefix="SET" suffixOverrides=",">
|
||||
<if test="memberLevel != null">member_level = #{memberLevel},</if>
|
||||
<if test="subscriptionStatus != null">subscription_status = #{subscriptionStatus},</if>
|
||||
<if test="userId != null">user_id = #{userId},</if>
|
||||
<if test="createTime != null">create_time = #{createTime},</if>
|
||||
<if test="updateTime != null">update_time = #{updateTime},</if>
|
||||
<if test="integration != null">integration = #{integration},</if>
|
||||
<if test="expirationTime != null">expiration_time = #{expirationTime},</if>
|
||||
</trim>
|
||||
where id = #{id}
|
||||
</update>
|
||||
|
||||
<delete id="deleteUserMemberById" parameterType="Long">
|
||||
delete from User_member where id = #{id}
|
||||
</delete>
|
||||
|
||||
<delete id="deleteUserMemberByIds" parameterType="String">
|
||||
delete from User_member where id in
|
||||
<foreach item="id" collection="array" open="(" separator="," close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
</delete>
|
||||
</mapper>
|
@ -1,44 +1,44 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 查询商品信息列表
|
||||
export function listGoods(query) {
|
||||
return request({
|
||||
url: '/goods/goods/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询商品信息详细
|
||||
export function getGoods(id) {
|
||||
return request({
|
||||
url: '/goods/goods/' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增商品信息
|
||||
export function addGoods(data) {
|
||||
return request({
|
||||
url: '/goods/goods',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改商品信息
|
||||
export function updateGoods(data) {
|
||||
return request({
|
||||
url: '/goods/goods',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除商品信息
|
||||
export function delGoods(id) {
|
||||
return request({
|
||||
url: '/goods/goods/' + id,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 查询商品信息列表
|
||||
export function listGoods(query) {
|
||||
return request({
|
||||
url: '/service/goods/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询商品信息详细
|
||||
export function getGoods(id) {
|
||||
return request({
|
||||
url: '/service/goods/' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增商品信息
|
||||
export function addGoods(data) {
|
||||
return request({
|
||||
url: '/service/goods',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改商品信息
|
||||
export function updateGoods(data) {
|
||||
return request({
|
||||
url: '/service/goods',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除商品信息
|
||||
export function delGoods(id) {
|
||||
return request({
|
||||
url: '/service/goods/' + id,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
@ -1,348 +1,405 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
|
||||
<el-form-item label="商品编号" prop="goodsCode">
|
||||
<el-input
|
||||
v-model="queryParams.goodsCode"
|
||||
placeholder="请输入商品编号"
|
||||
clearable
|
||||
@keyup.enter.native="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品标题" prop="productTitle">
|
||||
<el-input
|
||||
v-model="queryParams.productTitle"
|
||||
placeholder="请输入商品标题"
|
||||
clearable
|
||||
@keyup.enter.native="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品类型" prop="goodsType">
|
||||
<el-select v-model="queryParams.goodsType" placeholder="请选择商品类型" clearable>
|
||||
<el-option
|
||||
v-for="dict in dict.type.goods_type"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
icon="el-icon-plus"
|
||||
size="mini"
|
||||
@click="handleAdd"
|
||||
v-hasPermi="['goods:goods:add']"
|
||||
>新增</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="success"
|
||||
plain
|
||||
icon="el-icon-edit"
|
||||
size="mini"
|
||||
:disabled="single"
|
||||
@click="handleUpdate"
|
||||
v-hasPermi="['goods:goods:edit']"
|
||||
>修改</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="danger"
|
||||
plain
|
||||
icon="el-icon-delete"
|
||||
size="mini"
|
||||
:disabled="multiple"
|
||||
@click="handleDelete"
|
||||
v-hasPermi="['goods:goods:remove']"
|
||||
>删除</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="warning"
|
||||
plain
|
||||
icon="el-icon-download"
|
||||
size="mini"
|
||||
@click="handleExport"
|
||||
v-hasPermi="['goods:goods:export']"
|
||||
>导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
|
||||
<el-table v-loading="loading" :data="goodsList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="商品id" align="center" prop="id" />
|
||||
<el-table-column label="商品编号" align="center" prop="goodsCode" />
|
||||
<el-table-column label="商品标题" align="center" prop="productTitle" />
|
||||
<el-table-column label="商品图片" align="center" prop="productPicture" width="100">
|
||||
<template slot-scope="scope">
|
||||
<image-preview :src="scope.row.productPicture" :width="50" :height="50"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="价格" align="center" prop="originalPrice" />
|
||||
<el-table-column label="商品描述" align="center" prop="productDesc" />
|
||||
<el-table-column label="排序" align="center" prop="orderNum" />
|
||||
<el-table-column label="商品类型" align="center" prop="goodsType">
|
||||
<template slot-scope="scope">
|
||||
<dict-tag :options="dict.type.goods_type" :value="scope.row.goodsType"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="商品规格" align="center" prop="goodsSpec" />
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template slot-scope="scope">
|
||||
<el-button
|
||||
size="mini"
|
||||
type="text"
|
||||
icon="el-icon-edit"
|
||||
@click="handleUpdate(scope.row)"
|
||||
v-hasPermi="['goods:goods:edit']"
|
||||
>修改</el-button>
|
||||
<el-button
|
||||
size="mini"
|
||||
type="text"
|
||||
icon="el-icon-delete"
|
||||
@click="handleDelete(scope.row)"
|
||||
v-hasPermi="['goods:goods:remove']"
|
||||
>删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination
|
||||
v-show="total>0"
|
||||
:total="total"
|
||||
:page.sync="queryParams.pageNum"
|
||||
:limit.sync="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
|
||||
<!-- 添加或修改商品信息对话框 -->
|
||||
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
|
||||
<el-form-item label="商品编号" prop="goodsCode">
|
||||
<el-input v-model="form.goodsCode" placeholder="请输入商品编号" />
|
||||
</el-form-item>
|
||||
<el-form-item label="商品标题" prop="productTitle">
|
||||
<el-input v-model="form.productTitle" placeholder="请输入商品标题" />
|
||||
</el-form-item>
|
||||
<el-form-item label="商品图片" prop="productPicture">
|
||||
<image-upload v-model="form.productPicture"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="原价格" prop="originalPrice">
|
||||
<el-input v-model="form.originalPrice" placeholder="请输入原价格" />
|
||||
</el-form-item>
|
||||
<el-form-item label="商品描述" prop="productDesc">
|
||||
<el-input v-model="form.productDesc" type="textarea" placeholder="请输入内容" />
|
||||
</el-form-item>
|
||||
<el-form-item label="排序" prop="orderNum">
|
||||
<el-input v-model="form.orderNum" placeholder="请输入排序" />
|
||||
</el-form-item>
|
||||
<el-form-item label="商品类型" prop="goodsType">
|
||||
<el-radio-group v-model="form.goodsType">
|
||||
<el-radio
|
||||
v-for="dict in dict.type.goods_type"
|
||||
:key="dict.value"
|
||||
:label="dict.value"
|
||||
>{{dict.label}}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品规格" prop="goodsSpec">
|
||||
<el-input v-model="form.goodsSpec" placeholder="请输入商品规格" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listGoods, getGoods, delGoods, addGoods, updateGoods } from "@/api/goods/goods";
|
||||
|
||||
export default {
|
||||
name: "Goods",
|
||||
dicts: ['sys_notice_status', 'goods_type'],
|
||||
data() {
|
||||
return {
|
||||
// 遮罩层
|
||||
loading: true,
|
||||
// 选中数组
|
||||
ids: [],
|
||||
// 非单个禁用
|
||||
single: true,
|
||||
// 非多个禁用
|
||||
multiple: true,
|
||||
// 显示搜索条件
|
||||
showSearch: true,
|
||||
// 总条数
|
||||
total: 0,
|
||||
// 商品信息表格数据
|
||||
goodsList: [],
|
||||
// 弹出层标题
|
||||
title: "",
|
||||
// 是否显示弹出层
|
||||
open: false,
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
goodsCode: null,
|
||||
productTitle: null,
|
||||
goodsType: null,
|
||||
},
|
||||
// 表单参数
|
||||
form: {},
|
||||
// 表单校验
|
||||
rules: {
|
||||
goodsCode: [
|
||||
{ required: true, message: "商品编号不能为空", trigger: "blur" }
|
||||
],
|
||||
productTitle: [
|
||||
{ required: true, message: "商品标题不能为空", trigger: "blur" }
|
||||
],
|
||||
productPicture: [
|
||||
{ required: true, message: "商品图片不能为空", trigger: "blur" }
|
||||
],
|
||||
originalPrice: [
|
||||
{ required: true, message: "原价格不能为空", trigger: "blur" }
|
||||
],
|
||||
orderNum: [
|
||||
{ required: true, message: "排序不能为空", trigger: "blur" }
|
||||
],
|
||||
createTime: [
|
||||
{ required: true, message: "创建时间不能为空", trigger: "blur" }
|
||||
],
|
||||
goodsType: [
|
||||
{ required: true, message: "商品类型不能为空", trigger: "change" }
|
||||
],
|
||||
goodsSpec: [
|
||||
{ required: true, message: "商品规格不能为空", trigger: "blur" }
|
||||
]
|
||||
}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getList();
|
||||
},
|
||||
methods: {
|
||||
/** 查询商品信息列表 */
|
||||
getList() {
|
||||
this.loading = true;
|
||||
listGoods(this.queryParams).then(response => {
|
||||
this.goodsList = response.rows;
|
||||
this.total = response.total;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
// 取消按钮
|
||||
cancel() {
|
||||
this.open = false;
|
||||
this.reset();
|
||||
},
|
||||
// 表单重置
|
||||
reset() {
|
||||
this.form = {
|
||||
id: null,
|
||||
goodsCode: null,
|
||||
stockId: null,
|
||||
reviewStatus: null,
|
||||
productTitle: null,
|
||||
productPicture: null,
|
||||
originalPrice: null,
|
||||
productDesc: null,
|
||||
orderNum: null,
|
||||
isDelete: null,
|
||||
created: null,
|
||||
modified: null,
|
||||
createTime: null,
|
||||
updateTime: null,
|
||||
goodsType: null,
|
||||
goodsSpec: null
|
||||
};
|
||||
this.resetForm("form");
|
||||
},
|
||||
/** 搜索按钮操作 */
|
||||
handleQuery() {
|
||||
this.queryParams.pageNum = 1;
|
||||
this.getList();
|
||||
},
|
||||
/** 重置按钮操作 */
|
||||
resetQuery() {
|
||||
this.resetForm("queryForm");
|
||||
this.handleQuery();
|
||||
},
|
||||
// 多选框选中数据
|
||||
handleSelectionChange(selection) {
|
||||
this.ids = selection.map(item => item.id)
|
||||
this.single = selection.length!==1
|
||||
this.multiple = !selection.length
|
||||
},
|
||||
/** 新增按钮操作 */
|
||||
handleAdd() {
|
||||
this.reset();
|
||||
this.open = true;
|
||||
this.title = "添加商品信息";
|
||||
},
|
||||
/** 修改按钮操作 */
|
||||
handleUpdate(row) {
|
||||
this.reset();
|
||||
const id = row.id || this.ids
|
||||
getGoods(id).then(response => {
|
||||
this.form = response.data;
|
||||
this.open = true;
|
||||
this.title = "修改商品信息";
|
||||
});
|
||||
},
|
||||
/** 提交按钮 */
|
||||
submitForm() {
|
||||
this.$refs["form"].validate(valid => {
|
||||
if (valid) {
|
||||
if (this.form.id != null) {
|
||||
let data = Object.assign({},this.form)
|
||||
delete data.explain
|
||||
updateGoods(data).then(response => {
|
||||
this.$modal.msgSuccess("修改成功");
|
||||
this.open = false;
|
||||
this.getList();
|
||||
});
|
||||
} else {
|
||||
addGoods(this.form).then(response => {
|
||||
this.$modal.msgSuccess("新增成功");
|
||||
this.open = false;
|
||||
this.getList();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
/** 删除按钮操作 */
|
||||
handleDelete(row) {
|
||||
const ids = row.id || this.ids;
|
||||
this.$modal.confirm('是否确认删除商品信息编号为"' + ids + '"的数据项?').then(function() {
|
||||
return delGoods(ids);
|
||||
}).then(() => {
|
||||
this.getList();
|
||||
this.$modal.msgSuccess("删除成功");
|
||||
}).catch(() => {});
|
||||
},
|
||||
/** 导出按钮操作 */
|
||||
handleExport() {
|
||||
this.download('goods/goods/export', {
|
||||
...this.queryParams
|
||||
}, `goods_${new Date().getTime()}.xlsx`)
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
|
||||
<el-form-item label="商品编号" prop="goodsCode">
|
||||
<el-input
|
||||
v-model="queryParams.goodsCode"
|
||||
placeholder="请输入商品编号"
|
||||
clearable
|
||||
@keyup.enter.native="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="审核状态" prop="reviewStatus">
|
||||
<el-select v-model="queryParams.reviewStatus" placeholder="请选择审核状态" clearable>
|
||||
<el-option
|
||||
v-for="dict in dict.type.goods_review_status"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品标题" prop="productTitle">
|
||||
<el-input
|
||||
v-model="queryParams.productTitle"
|
||||
placeholder="请输入商品标题"
|
||||
clearable
|
||||
@keyup.enter.native="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品原价" prop="originalPrice">
|
||||
<el-input
|
||||
v-model="queryParams.originalPrice"
|
||||
placeholder="请输入商品原价"
|
||||
clearable
|
||||
@keyup.enter.native="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品类型" prop="goodsType">
|
||||
<el-select v-model="queryParams.goodsType" placeholder="请选择商品类型" clearable>
|
||||
<el-option
|
||||
v-for="dict in dict.type.goods_type"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品规格" prop="goodsSpec">
|
||||
<el-input
|
||||
v-model="queryParams.goodsSpec"
|
||||
placeholder="请输入商品规格"
|
||||
clearable
|
||||
@keyup.enter.native="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品型号" prop="goodsModel">
|
||||
<el-input
|
||||
v-model="queryParams.goodsModel"
|
||||
placeholder="请输入商品型号"
|
||||
clearable
|
||||
@keyup.enter.native="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
icon="el-icon-plus"
|
||||
size="mini"
|
||||
@click="handleAdd"
|
||||
v-hasPermi="['service:goods:add']"
|
||||
>新增</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="success"
|
||||
plain
|
||||
icon="el-icon-edit"
|
||||
size="mini"
|
||||
:disabled="single"
|
||||
@click="handleUpdate"
|
||||
v-hasPermi="['service:goods:edit']"
|
||||
>修改</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="danger"
|
||||
plain
|
||||
icon="el-icon-delete"
|
||||
size="mini"
|
||||
:disabled="multiple"
|
||||
@click="handleDelete"
|
||||
v-hasPermi="['service:goods:remove']"
|
||||
>删除</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="warning"
|
||||
plain
|
||||
icon="el-icon-download"
|
||||
size="mini"
|
||||
@click="handleExport"
|
||||
v-hasPermi="['service:goods:export']"
|
||||
>导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
|
||||
<el-table v-loading="loading" :data="goodsList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="主键" align="center" prop="id" />
|
||||
<el-table-column label="商品编号" align="center" prop="goodsCode" />
|
||||
<el-table-column label="审核状态" align="center" prop="reviewStatus">
|
||||
<template slot-scope="scope">
|
||||
<dict-tag :options="dict.type.goods_review_status" :value="scope.row.reviewStatus"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="商品标题" align="center" prop="productTitle" />
|
||||
<el-table-column label="商品图片" align="center" prop="productPicture" width="100">
|
||||
<template slot-scope="scope">
|
||||
<image-preview :src="scope.row.productPicture" :width="50" :height="50"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="商品原价" align="center" prop="originalPrice" />
|
||||
<el-table-column label="商品描述" align="center" prop="productDesc" />
|
||||
<el-table-column label="商品类型" align="center" prop="goodsType">
|
||||
<template slot-scope="scope">
|
||||
<dict-tag :options="dict.type.goods_type" :value="scope.row.goodsType"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="商品规格" align="center" prop="goodsSpec" />
|
||||
<el-table-column label="商品型号" align="center" prop="goodsModel" />
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template slot-scope="scope">
|
||||
<el-button
|
||||
size="mini"
|
||||
type="text"
|
||||
icon="el-icon-edit"
|
||||
@click="handleUpdate(scope.row)"
|
||||
v-hasPermi="['service:goods:edit']"
|
||||
>修改</el-button>
|
||||
<el-button
|
||||
size="mini"
|
||||
type="text"
|
||||
icon="el-icon-delete"
|
||||
@click="handleDelete(scope.row)"
|
||||
v-hasPermi="['service:goods:remove']"
|
||||
>删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination
|
||||
v-show="total>0"
|
||||
:total="total"
|
||||
:page.sync="queryParams.pageNum"
|
||||
:limit.sync="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
|
||||
<!-- 添加或修改商品信息对话框 -->
|
||||
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
|
||||
<el-form-item label="商品编号" prop="goodsCode">
|
||||
<el-input v-model="form.goodsCode" placeholder="请输入商品编号" />
|
||||
</el-form-item>
|
||||
<el-form-item label="审核状态" prop="reviewStatus">
|
||||
<el-radio-group v-model="form.reviewStatus">
|
||||
<el-radio
|
||||
v-for="dict in dict.type.goods_review_status"
|
||||
:key="dict.value"
|
||||
:label="parseInt(dict.value)"
|
||||
>{{dict.label}}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品标题" prop="productTitle">
|
||||
<el-input v-model="form.productTitle" placeholder="请输入商品标题" />
|
||||
</el-form-item>
|
||||
<el-form-item label="商品图片" prop="productPicture">
|
||||
<image-upload v-model="form.productPicture"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品原价" prop="originalPrice">
|
||||
<el-input v-model="form.originalPrice" placeholder="请输入商品原价" />
|
||||
</el-form-item>
|
||||
<el-form-item label="商品描述" prop="productDesc">
|
||||
<el-input v-model="form.productDesc" type="textarea" placeholder="请输入内容" />
|
||||
</el-form-item>
|
||||
<el-form-item label="商品类型" prop="goodsType">
|
||||
<el-radio-group v-model="form.goodsType">
|
||||
<el-radio
|
||||
v-for="dict in dict.type.goods_type"
|
||||
:key="dict.value"
|
||||
:label="parseInt(dict.value)"
|
||||
>{{dict.label}}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品规格" prop="goodsSpec">
|
||||
<el-input v-model="form.goodsSpec" placeholder="请输入商品规格" />
|
||||
</el-form-item>
|
||||
<el-form-item label="排序" prop="orderNum">
|
||||
<el-input v-model="form.orderNum" placeholder="请输入排序" />
|
||||
</el-form-item>
|
||||
<el-form-item label="商品型号" prop="goodsModel">
|
||||
<el-input v-model="form.goodsModel" placeholder="请输入商品型号" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listGoods, getGoods, delGoods, addGoods, updateGoods } from "@/api/service/goods";
|
||||
|
||||
export default {
|
||||
name: "Goods",
|
||||
dicts: ['goods_review_status', 'goods_type'],
|
||||
data() {
|
||||
return {
|
||||
// 遮罩层
|
||||
loading: true,
|
||||
// 选中数组
|
||||
ids: [],
|
||||
// 非单个禁用
|
||||
single: true,
|
||||
// 非多个禁用
|
||||
multiple: true,
|
||||
// 显示搜索条件
|
||||
showSearch: true,
|
||||
// 总条数
|
||||
total: 0,
|
||||
// 商品信息表格数据
|
||||
goodsList: [],
|
||||
// 弹出层标题
|
||||
title: "",
|
||||
// 是否显示弹出层
|
||||
open: false,
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
goodsCode: null,
|
||||
reviewStatus: null,
|
||||
productTitle: null,
|
||||
originalPrice: null,
|
||||
goodsType: null,
|
||||
goodsSpec: null,
|
||||
goodsModel: null
|
||||
},
|
||||
// 表单参数
|
||||
form: {},
|
||||
// 表单校验
|
||||
rules: {
|
||||
goodsCode: [
|
||||
{ required: true, message: "商品编号不能为空", trigger: "blur" }
|
||||
],
|
||||
reviewStatus: [
|
||||
{ required: true, message: "审核状态不能为空", trigger: "change" }
|
||||
],
|
||||
productTitle: [
|
||||
{ required: true, message: "商品标题不能为空", trigger: "blur" }
|
||||
],
|
||||
productPicture: [
|
||||
{ required: true, message: "商品图片不能为空", trigger: "blur" }
|
||||
],
|
||||
originalPrice: [
|
||||
{ required: true, message: "商品原价不能为空", trigger: "blur" }
|
||||
],
|
||||
goodsType: [
|
||||
{ required: true, message: "商品类型不能为空", trigger: "change" }
|
||||
],
|
||||
goodsSpec: [
|
||||
{ required: true, message: "商品规格不能为空", trigger: "blur" }
|
||||
],
|
||||
goodsModel: [
|
||||
{ required: true, message: "商品型号不能为空", trigger: "blur" }
|
||||
]
|
||||
}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getList();
|
||||
},
|
||||
methods: {
|
||||
/** 查询商品信息列表 */
|
||||
getList() {
|
||||
this.loading = true;
|
||||
listGoods(this.queryParams).then(response => {
|
||||
this.goodsList = response.rows;
|
||||
this.total = response.total;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
// 取消按钮
|
||||
cancel() {
|
||||
this.open = false;
|
||||
this.reset();
|
||||
},
|
||||
// 表单重置
|
||||
reset() {
|
||||
this.form = {
|
||||
id: null,
|
||||
goodsCode: null,
|
||||
stockId: null,
|
||||
reviewStatus: null,
|
||||
productTitle: null,
|
||||
productPicture: null,
|
||||
originalPrice: null,
|
||||
productDesc: null,
|
||||
goodsType: null,
|
||||
goodsSpec: null,
|
||||
orderNum: null,
|
||||
isDelete: null,
|
||||
created: null,
|
||||
modified: null,
|
||||
createTime: null,
|
||||
updateTime: null,
|
||||
goodsName: null,
|
||||
goodsModel: null
|
||||
};
|
||||
this.resetForm("form");
|
||||
},
|
||||
/** 搜索按钮操作 */
|
||||
handleQuery() {
|
||||
this.queryParams.pageNum = 1;
|
||||
this.getList();
|
||||
},
|
||||
/** 重置按钮操作 */
|
||||
resetQuery() {
|
||||
this.resetForm("queryForm");
|
||||
this.handleQuery();
|
||||
},
|
||||
// 多选框选中数据
|
||||
handleSelectionChange(selection) {
|
||||
this.ids = selection.map(item => item.id)
|
||||
this.single = selection.length!==1
|
||||
this.multiple = !selection.length
|
||||
},
|
||||
/** 新增按钮操作 */
|
||||
handleAdd() {
|
||||
this.reset();
|
||||
this.open = true;
|
||||
this.title = "添加商品信息";
|
||||
},
|
||||
/** 修改按钮操作 */
|
||||
handleUpdate(row) {
|
||||
this.reset();
|
||||
const id = row.id || this.ids
|
||||
getGoods(id).then(response => {
|
||||
this.form = response.data;
|
||||
this.open = true;
|
||||
this.title = "修改商品信息";
|
||||
});
|
||||
},
|
||||
/** 提交按钮 */
|
||||
submitForm() {
|
||||
this.$refs["form"].validate(valid => {
|
||||
if (valid) {
|
||||
if (this.form.id != null) {
|
||||
let data = Object.assign({},this.form)
|
||||
delete data.explain
|
||||
updateGoods(data).then(response => {
|
||||
this.$modal.msgSuccess("修改成功");
|
||||
this.open = false;
|
||||
this.getList();
|
||||
});
|
||||
} else {
|
||||
addGoods(this.form).then(response => {
|
||||
this.$modal.msgSuccess("新增成功");
|
||||
this.open = false;
|
||||
this.getList();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
/** 删除按钮操作 */
|
||||
handleDelete(row) {
|
||||
const ids = row.id || this.ids;
|
||||
this.$modal.confirm('是否确认删除商品信息编号为"' + ids + '"的数据项?').then(function() {
|
||||
return delGoods(ids);
|
||||
}).then(() => {
|
||||
this.getList();
|
||||
this.$modal.msgSuccess("删除成功");
|
||||
}).catch(() => {});
|
||||
},
|
||||
/** 导出按钮操作 */
|
||||
handleExport() {
|
||||
this.download('service/goods/export', {
|
||||
...this.queryParams
|
||||
}, `goods_${new Date().getTime()}.xlsx`)
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
Loading…
x
Reference in New Issue
Block a user