pull/2/head
perry 2023-05-15 23:40:57 +08:00
parent b18828d86d
commit ca7f62f924
29 changed files with 1658 additions and 45 deletions

View File

@ -70,7 +70,7 @@
<justauth.version>1.4.0</justauth.version>
<jimureport.version>1.5.6</jimureport.version>
<xercesImpl.version>2.12.2</xercesImpl.version>
<wx-java-mp.version>4.3.0</wx-java-mp.version>
<wx-java-mp.version>4.5.0</wx-java-mp.version>
</properties>
<dependencyManagement>
@ -624,6 +624,11 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>wx-java-mp-spring-boot-starter</artifactId>
<version>${wx-java-mp.version}</version>
</dependency>
</dependencies>
</dependencyManagement>

View File

@ -0,0 +1,64 @@
package cn.iocoder.yudao.framework.pay.config;
import cn.iocoder.yudao.framework.pay.properties.WxPayProperties;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* <pre>
*
* Created by BinaryWang on 2019/4/17.
* </pre>
*
* @author <a href="https://github.com/binarywang">Binary Wang</a>
*/
@Configuration
@EnableConfigurationProperties(WxPayProperties.class)
@ConditionalOnClass(WxPayService.class)
@ConditionalOnProperty(prefix = "wx.pay.one", value = "enabled", matchIfMissing = true)
public class WxPayOneAutoConfiguration {
private WxPayProperties properties;
@Autowired
public WxPayOneAutoConfiguration(WxPayProperties properties) {
this.properties = properties;
}
/**
* .
*
* @return service
*/
@Bean
@ConditionalOnMissingBean(WxPayService.class)
public WxPayService wxPayOneService() {
final WxPayServiceImpl wxPayService = new WxPayServiceImpl();
WxPayConfig payConfig = new WxPayConfig();
payConfig.setAppId(StringUtils.trimToNull(this.properties.getAppId()));
payConfig.setMchId(StringUtils.trimToNull(this.properties.getMchId()));
payConfig.setMchKey(StringUtils.trimToNull(this.properties.getMchKey()));
payConfig.setSubAppId(StringUtils.trimToNull(this.properties.getSubAppId()));
payConfig.setSubMchId(StringUtils.trimToNull(this.properties.getSubMchId()));
payConfig.setKeyPath(StringUtils.trimToNull(this.properties.getKeyPath()));
payConfig.setNotifyUrl(StringUtils.trimToNull(this.properties.getNotifyUrl()));
//以下是apiv3以及支付分相关
payConfig.setServiceId(StringUtils.trimToNull(this.properties.getServiceId()));
payConfig.setPayScoreNotifyUrl(StringUtils.trimToNull(this.properties.getPayScoreNotifyUrl()));
payConfig.setPrivateKeyPath(StringUtils.trimToNull(this.properties.getPrivateKeyPath()));
payConfig.setPrivateCertPath(StringUtils.trimToNull(this.properties.getPrivateCertPath()));
payConfig.setCertSerialNo(StringUtils.trimToNull(this.properties.getCertSerialNo()));
payConfig.setApiV3Key(StringUtils.trimToNull(this.properties.getApiv3Key()));
wxPayService.setConfig(payConfig);
return wxPayService;
}
}

View File

@ -0,0 +1,65 @@
package cn.iocoder.yudao.framework.pay.config;
import cn.iocoder.yudao.framework.pay.properties.WxPayTwoProperties;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* <pre>
*
* Created by BinaryWang on 2019/4/17.
* </pre>
*
* @author <a href="https://github.com/binarywang">Binary Wang</a>
*/
@Configuration
@EnableConfigurationProperties(WxPayTwoProperties.class)
@ConditionalOnClass(WxPayService.class)
@ConditionalOnProperty(prefix = "wx.pay.two", value = "enabled", matchIfMissing = true)
public class WxPayTwoAutoConfiguration {
private WxPayTwoProperties wxPayTwoProperties;
@Autowired
public WxPayTwoAutoConfiguration(WxPayTwoProperties wxPayTwoProperties) {
this.wxPayTwoProperties = wxPayTwoProperties;
}
/**
* .
*
* @return service
*/
@Bean
@ConditionalOnMissingBean(WxPayService.class)
public WxPayService wxPayTwoService() {
final WxPayServiceImpl wxPayService = new WxPayServiceImpl();
WxPayConfig payConfig = new WxPayConfig();
payConfig.setAppId(StringUtils.trimToNull(this.wxPayTwoProperties.getAppId()));
payConfig.setMchId(StringUtils.trimToNull(this.wxPayTwoProperties.getMchId()));
payConfig.setMchKey(StringUtils.trimToNull(this.wxPayTwoProperties.getMchKey()));
payConfig.setSubAppId(StringUtils.trimToNull(this.wxPayTwoProperties.getSubAppId()));
payConfig.setSubMchId(StringUtils.trimToNull(this.wxPayTwoProperties.getSubMchId()));
payConfig.setKeyPath(StringUtils.trimToNull(this.wxPayTwoProperties.getKeyPath()));
payConfig.setNotifyUrl(StringUtils.trimToNull(this.wxPayTwoProperties.getNotifyUrl()));
//以下是apiv3以及支付分相关
payConfig.setServiceId(StringUtils.trimToNull(this.wxPayTwoProperties.getServiceId()));
payConfig.setPayScoreNotifyUrl(StringUtils.trimToNull(this.wxPayTwoProperties.getPayScoreNotifyUrl()));
payConfig.setPrivateKeyPath(StringUtils.trimToNull(this.wxPayTwoProperties.getPrivateKeyPath()));
payConfig.setPrivateCertPath(StringUtils.trimToNull(this.wxPayTwoProperties.getPrivateCertPath()));
payConfig.setCertSerialNo(StringUtils.trimToNull(this.wxPayTwoProperties.getCertSerialNo()));
payConfig.setApiV3Key(StringUtils.trimToNull(this.wxPayTwoProperties.getApiv3Key()));
wxPayService.setConfig(payConfig);
return wxPayService;
}
}

View File

@ -0,0 +1,86 @@
package cn.iocoder.yudao.framework.pay.properties;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* <pre>
*
* Created by Binary Wang on 2019/4/17.
* </pre>
*
* @author <a href="https://github.com/binarywang">Binary Wang</a>
*/
@Data
@ConfigurationProperties(prefix = "wx.pay.one")
public class WxPayProperties {
/**
* appid.
*/
private String appId;
/**
* .
*/
private String mchId;
/**
* .
*/
private String mchKey;
/**
* ID.
*/
private String subAppId;
/**
* .
*/
private String subMchId;
/**
* apiclient_cert.p12classpath:.
*/
private String keyPath;
/**
* serviceId
*/
private String serviceId;
/**
* url访url.
*/
private String notifyUrl;
/**
* 退url访url.
*/
private String refundNotifyUrl;
/**
*
*/
private String certSerialNo;
/**
* apiV3
*/
private String apiv3Key;
/**
*
*/
private String payScoreNotifyUrl;
/**
* apiv3 apiclient_key.pem
*/
private String privateKeyPath;
/**
* apiv3 apiclient_cert.pem
*/
private String privateCertPath;
}

View File

@ -0,0 +1,86 @@
package cn.iocoder.yudao.framework.pay.properties;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* <pre>
*
* Created by Binary Wang on 2019/4/17.
* </pre>
*
* @author <a href="https://github.com/binarywang">Binary Wang</a>
*/
@Data
@ConfigurationProperties(prefix = "wx.pay.two")
public class WxPayTwoProperties {
/**
* appid.
*/
private String appId;
/**
* .
*/
private String mchId;
/**
* .
*/
private String mchKey;
/**
* ID.
*/
private String subAppId;
/**
* .
*/
private String subMchId;
/**
* apiclient_cert.p12classpath:.
*/
private String keyPath;
/**
* serviceId
*/
private String serviceId;
/**
* url访url.
*/
private String notifyUrl;
/**
* 退url访url.
*/
private String refundNotifyUrl;
/**
*
*/
private String certSerialNo;
/**
* apiV3
*/
private String apiv3Key;
/**
*
*/
private String payScoreNotifyUrl;
/**
* apiv3 apiclient_key.pem
*/
private String privateKeyPath;
/**
* apiv3 apiclient_cert.pem
*/
private String privateCertPath;
}

View File

@ -1 +1,3 @@
cn.iocoder.yudao.framework.pay.config.YudaoPayAutoConfiguration
cn.iocoder.yudao.framework.pay.config.YudaoPayAutoConfiguration
cn.iocoder.yudao.framework.pay.config.WxPayOneAutoConfiguration
cn.iocoder.yudao.framework.pay.config.WxPayTwoAutoConfiguration

View File

@ -79,5 +79,13 @@
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-biz-ip</artifactId>
</dependency>
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>wx-java-mp-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-biz-pay</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,126 @@
package cn.iocoder.yudao.module.shop.controller;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
import cn.iocoder.yudao.framework.pay.properties.WxPayProperties;
import cn.iocoder.yudao.framework.pay.properties.WxPayTwoProperties;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderV3Request;
import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderV3Result;
import com.github.binarywang.wxpay.bean.result.enums.TradeTypeEnum;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import me.chanjar.weixin.common.bean.WxJsapiSignature;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
/**
* @author perry
*/
@RequestMapping("test")
@RestController
public class TestPayController {
@Autowired
private WxPayTwoProperties wxPayTwoProperties;
@Autowired
private WxPayProperties payProperties;
@Autowired
private WxMpService wxMpService;
@GetMapping("getjsApiToken")
public CommonResult getjsApiToken() throws WxErrorException {
WxJsapiSignature wxJsapiSignature = wxMpService.createJsapiSignature("http://yuxy.perrymake.com/login");
return CommonResult.success(wxJsapiSignature);
}
public WxPayService wxPayService() {
final WxPayServiceImpl wxPayService = new WxPayServiceImpl();
WxPayConfig payConfig = new WxPayConfig();
payConfig.setAppId(StringUtils.trimToNull(payProperties.getAppId()));
payConfig.setMchId(StringUtils.trimToNull(payProperties.getMchId()));
payConfig.setMchKey(StringUtils.trimToNull(payProperties.getMchKey()));
payConfig.setSubAppId(StringUtils.trimToNull(payProperties.getSubAppId()));
payConfig.setSubMchId(StringUtils.trimToNull(payProperties.getSubMchId()));
payConfig.setKeyPath(StringUtils.trimToNull(payProperties.getKeyPath()));
payConfig.setNotifyUrl(StringUtils.trimToNull(payProperties.getNotifyUrl()));
//以下是apiv3以及支付分相关
payConfig.setServiceId(StringUtils.trimToNull(payProperties.getServiceId()));
payConfig.setPayScoreNotifyUrl(StringUtils.trimToNull(payProperties.getPayScoreNotifyUrl()));
payConfig.setPrivateKeyPath(StringUtils.trimToNull(payProperties.getPrivateKeyPath()));
payConfig.setPrivateCertPath(StringUtils.trimToNull(payProperties.getPrivateCertPath()));
payConfig.setCertSerialNo(StringUtils.trimToNull(payProperties.getCertSerialNo()));
payConfig.setApiV3Key(StringUtils.trimToNull(payProperties.getApiv3Key()));
wxPayService.setConfig(payConfig);
return wxPayService;
}
public WxPayService wxPay1Service() {
final WxPayServiceImpl wxPayService = new WxPayServiceImpl();
WxPayConfig payConfig = new WxPayConfig();
payConfig.setAppId(StringUtils.trimToNull(wxPayTwoProperties.getAppId()));
payConfig.setMchId(StringUtils.trimToNull(wxPayTwoProperties.getMchId()));
payConfig.setMchKey(StringUtils.trimToNull(wxPayTwoProperties.getMchKey()));
payConfig.setSubAppId(StringUtils.trimToNull(wxPayTwoProperties.getSubAppId()));
payConfig.setSubMchId(StringUtils.trimToNull(wxPayTwoProperties.getSubMchId()));
payConfig.setKeyPath(StringUtils.trimToNull(wxPayTwoProperties.getKeyPath()));
payConfig.setNotifyUrl(StringUtils.trimToNull(wxPayTwoProperties.getNotifyUrl()));
//以下是apiv3以及支付分相关
payConfig.setServiceId(StringUtils.trimToNull(wxPayTwoProperties.getServiceId()));
payConfig.setPayScoreNotifyUrl(StringUtils.trimToNull(wxPayTwoProperties.getPayScoreNotifyUrl()));
payConfig.setPrivateKeyPath(StringUtils.trimToNull(wxPayTwoProperties.getPrivateKeyPath()));
payConfig.setPrivateCertPath(StringUtils.trimToNull(wxPayTwoProperties.getPrivateCertPath()));
payConfig.setCertSerialNo(StringUtils.trimToNull(wxPayTwoProperties.getCertSerialNo()));
payConfig.setApiV3Key(StringUtils.trimToNull(wxPayTwoProperties.getApiv3Key()));
wxPayService.setConfig(payConfig);
return wxPayService;
}
@PostMapping("pay")
public CommonResult pay(@RequestBody JSONObject jsonObject , HttpServletRequest request) throws WxPayException {
WxPayUnifiedOrderV3Result.JsapiResult jsapiResult=null;
if(jsonObject.getInteger("type")==1){
WxPayService wxPayService = wxPayService();
WxPayUnifiedOrderV3Request wxPayUnifiedOrderV3Request = new WxPayUnifiedOrderV3Request();
wxPayUnifiedOrderV3Request.setAmount(new WxPayUnifiedOrderV3Request.Amount().setTotal(1));
wxPayUnifiedOrderV3Request.setDescription("测试支付");
wxPayUnifiedOrderV3Request.setOutTradeNo(IdWorker.getIdStr());
wxPayUnifiedOrderV3Request.setNotifyUrl(payProperties.getNotifyUrl());
wxPayUnifiedOrderV3Request.setPayer(new WxPayUnifiedOrderV3Request.Payer().setOpenid(jsonObject.getString("openid")));
wxPayUnifiedOrderV3Request.setSceneInfo(new WxPayUnifiedOrderV3Request.SceneInfo().setPayerClientIp(ServletUtils.getClientIP(request)));
wxPayUnifiedOrderV3Request.setAppid(payProperties.getAppId());
wxPayUnifiedOrderV3Request.setMchid(payProperties.getMchId());
WxPayUnifiedOrderV3Result wxPayUnifiedOrderV3Result = wxPayService.unifiedOrderV3(TradeTypeEnum.JSAPI, wxPayUnifiedOrderV3Request);
// 以下字段在return_code 和result_code都为SUCCESS的时候有返回
jsapiResult = wxPayUnifiedOrderV3Result.getPayInfo(TradeTypeEnum.JSAPI, payProperties.getAppId(), payProperties.getMchId(), wxPayService.getConfig().getPrivateKey());
}
if(jsonObject.getInteger("type")==2){
WxPayService wxPay1Service = wxPay1Service();
WxPayUnifiedOrderV3Request wxPayUnifiedOrderV3Request = new WxPayUnifiedOrderV3Request();
wxPayUnifiedOrderV3Request.setAmount(new WxPayUnifiedOrderV3Request.Amount().setTotal(2));
wxPayUnifiedOrderV3Request.setDescription("测试支付");
wxPayUnifiedOrderV3Request.setOutTradeNo(IdWorker.getIdStr());
wxPayUnifiedOrderV3Request.setNotifyUrl(wxPayTwoProperties.getNotifyUrl());
wxPayUnifiedOrderV3Request.setPayer(new WxPayUnifiedOrderV3Request.Payer().setOpenid(jsonObject.getString("openid")));
wxPayUnifiedOrderV3Request.setSceneInfo(new WxPayUnifiedOrderV3Request.SceneInfo().setPayerClientIp(ServletUtils.getClientIP(request)));
WxPayUnifiedOrderV3Result wxPayUnifiedOrderV3Result = wxPay1Service.unifiedOrderV3(TradeTypeEnum.JSAPI, wxPayUnifiedOrderV3Request);
// 以下字段在return_code 和result_code都为SUCCESS的时候有返回
jsapiResult = wxPayUnifiedOrderV3Result.getPayInfo(TradeTypeEnum.JSAPI, wxPayTwoProperties.getAppId(), wxPayTwoProperties.getMchId(), wxPay1Service.getConfig().getPrivateKey());
}
return CommonResult.success(jsapiResult);
}
}

View File

@ -0,0 +1,127 @@
package cn.iocoder.yudao.module.shop.controller.admin.notify;
import cn.hutool.json.JSONUtil;
import com.github.binarywang.wxpay.bean.notify.OriginNotifyResponse;
import com.github.binarywang.wxpay.bean.notify.SignatureHeader;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyV3Result;
import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyV3Result;
import com.github.binarywang.wxpay.service.WxPayService;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author Javen
* @Email javen205@126.com
*/
@Slf4j
@RequestMapping("notify/wxpay")
@RestController
@Tag(name = "微信支付回调 - 订单支付")
public class WxPayNotifyController {
@Autowired
private WxPayService wxPayService;
/**
* Description:
*
* @author: perry
* @date: 2019/8/15 20:05
* @param:
* @return:
*/
@PostMapping("/pay_notify")
public String wxPayNotify(@RequestBody String jsonData, HttpServletRequest request, HttpServletResponse response) {
// 支付结果通用通知文档: https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_7
// 支付成功结果通知
log.info("支付原始通知=" + jsonData);
OriginNotifyResponse notifyResponse = JSONUtil.toBean(jsonData, OriginNotifyResponse.class);
log.info("支付原始通知=" + JSONUtil.toJsonPrettyStr(notifyResponse));
WxPayOrderNotifyV3Result v3Result = null;
try {
//解密后的数据
v3Result = wxPayService.parseOrderNotifyV3Result(jsonData, this.getRequestHeader(request));
WxPayOrderNotifyV3Result.DecryptNotifyResult result = v3Result.getResult();
log.info("支付通知=" + JSONUtil.toJsonPrettyStr(result));
} catch (Exception e) {
log.error(e.getMessage(), e);
}
// 通知应答码HTTP应答状态码需返回5XX或4XX同时需返回应答报文
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return "";
}
/**
*
*
* @param request HttpServletRequest
* @return SignatureHeader
*/
public SignatureHeader getRequestHeader(HttpServletRequest request) {
// 获取通知签名
String signature = request.getHeader("wechatpay-signature");
String nonce = request.getHeader("wechatpay-nonce");
String serial = request.getHeader("wechatpay-serial");
String timestamp = request.getHeader("wechatpay-timestamp");
SignatureHeader signatureHeader = new SignatureHeader();
signatureHeader.setSignature(signature);
signatureHeader.setNonce(nonce);
signatureHeader.setSerial(serial);
signatureHeader.setTimeStamp(timestamp);
return signatureHeader;
}
/**
* Description: 退
*
* @author: perry
* @date: 2019/8/15 20:05
* @param:
* @return:
*/
@PostMapping("/refund_notify")
public String wxPayRefundNotify(@RequestBody String jsonData, HttpServletRequest request, HttpServletResponse response) throws Exception {
// 支付结果通用通知文档: https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_7
// 支付成功结果通知
OriginNotifyResponse notifyResponse = JSONUtil.toBean(jsonData, OriginNotifyResponse.class);
WxPayRefundNotifyV3Result v3Result = null;
log.info("退款原始通知=" + JSONUtil.toJsonPrettyStr(jsonData));
try {
//解密后的数据
v3Result = wxPayService.parseRefundNotifyV3Result(JSONUtil.toJsonPrettyStr(notifyResponse), this.getRequestHeader(request));
WxPayRefundNotifyV3Result.DecryptNotifyResult result = v3Result.getResult();
log.info("退款通知=" + JSONUtil.toJsonPrettyStr(result));
//退款状态
} catch (Exception e) {
log.error(e.getMessage(), e);
}
// 通知应答码HTTP应答状态码需返回5XX或4XX同时需返回应答报文
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return "";
}
}

View File

@ -82,6 +82,7 @@ public class AdminUserController {
@PostMapping(value = "page")
@Operation(summary = "获取会员列表")
@PreAuthorize("@ss.hasPermission('member:user:query')")
@TenantIgnore
public CommonResult<PageResult<AdminUserInfoRespVO>> findPageList(@RequestBody AdminUserQueryDTO queryDTO) {
// 获得用户分页列表
PageResult<MemberUserDO> pageResult = userService.findPageList(queryDTO);

View File

@ -6,6 +6,7 @@ import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
import cn.iocoder.yudao.framework.security.config.SecurityProperties;
import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
import cn.iocoder.yudao.module.member.controller.app.auth.vo.*;
import cn.iocoder.yudao.module.member.service.auth.MemberAuthService;
import io.swagger.v3.oas.annotations.tags.Tag;
@ -39,6 +40,7 @@ public class AppAuthController {
@PostMapping("/login")
@Operation(summary = "使用手机 + 密码登录")
@TenantIgnore
public CommonResult<AppAuthLoginRespVO> login(@RequestBody @Valid AppAuthLoginReqVO reqVO) {
return success(authService.login(reqVO));
}
@ -66,12 +68,14 @@ public class AppAuthController {
@PostMapping("/sms-login")
@Operation(summary = "使用手机 + 验证码登录")
@TenantIgnore
public CommonResult<AppAuthLoginRespVO> smsLogin(@RequestBody @Valid AppAuthSmsLoginReqVO reqVO) {
return success(authService.smsLogin(reqVO));
}
@PostMapping("/register")
@Operation(summary = "注册")
@TenantIgnore
public CommonResult<Long> register(@RequestBody @Valid AppAuthSmsLoginReqVO reqVO) {
return success(authService.register(reqVO));
}

View File

@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.system.controller.admin.tenant;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
@ -19,6 +20,9 @@ import javax.annotation.security.PermitAll;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalUnit;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@ -45,6 +49,9 @@ public class TenantController {
@Operation(summary = "创建租户")
@PreAuthorize("@ss.hasPermission('system:tenant:create')")
public CommonResult<Long> createTenant(@Valid @RequestBody TenantCreateReqVO createReqVO) {
createReqVO.setAccountCount(99999);
createReqVO.setExpireTime(LocalDateTimeUtil.offset(LocalDateTime.now(),99, ChronoUnit.YEARS));
createReqVO.setPackageId(1L);
return success(tenantService.createTenant(createReqVO));
}

View File

@ -1,7 +1,9 @@
package cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant;
import cn.iocoder.yudao.framework.common.validation.Mobile;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.*;
import java.time.LocalDateTime;
@ -32,15 +34,60 @@ public class TenantBaseVO {
private String domain;
@Schema(description = "租户套餐编号", required = true, example = "1024")
@NotNull(message = "租户套餐编号不能为空")
private Long packageId;
@Schema(description = "过期时间", required = true)
@NotNull(message = "过期时间不能为空")
private LocalDateTime expireTime;
@Schema(description = "账号数量", required = true, example = "1024")
@NotNull(message = "账号数量不能为空")
private Integer accountCount;
/**
*
*/
@Schema(description = "简介", example = "https://www.iocoder.cn")
@NotEmpty(message = "简介不能为空")
@Length( max = 150, message = "简介长度为 {max}位")
private String introduction;
/**
*
*/
@Schema(description = "服务电话", example = "https://www.iocoder.cn")
@NotEmpty(message = "服务电话不能为空")
@Length( max = 13, message = "服务电话长度为 {max}位")
private String serviceMobile;
/**
*
*/
@Schema(description = "服务时间", example = "https://www.iocoder.cn")
@NotEmpty(message = "服务时间不能为空")
@Length( max = 20, message = "服务时间长度为 {max}位")
private String serviceTime;
/**
*
*/
@Schema(description = "销售负责人", example = "https://www.iocoder.cn")
@NotEmpty(message = "销售负责人不能为空")
@Length( max = 10, message = "销售负责人长度为 {max}位")
private String saleContactName;
/**
*
*/
@Schema(description = "销售负责人联系电话", example = "https://www.iocoder.cn")
@NotEmpty(message = "销售负责人不能为空")
@Mobile( message = "销售负责人联系电话不正确")
private String saleContactMobile;
/**
*
*/
@Schema(description = "微信客服地址", example = "https://www.iocoder.cn")
@NotEmpty(message = "微信客服地址不能为空")
@Length( max = 300, message = "微信客服地址长度为 {max}位")
private String wxKfUrl;
}

View File

@ -79,4 +79,36 @@ public class TenantDO extends BaseDO {
*/
private Integer accountCount;
/**
*
*/
private String introduction;
/**
*
*/
private String serviceMobile;
/**
*
*/
private String serviceTime;
/**
*
*/
private String saleContactName;
/**
*
*/
private String saleContactMobile;
/**
*
*/
private String wxKfUrl;
}

View File

@ -54,11 +54,11 @@
<!-- <version>${revision}</version>-->
<!-- </dependency>-->
<!-- 支付服务 -->
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-module-pay-biz</artifactId>
<version>${revision}</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>cn.iocoder.boot</groupId>-->
<!-- <artifactId>yudao-module-pay-biz</artifactId>-->
<!-- <version>${revision}</version>-->
<!-- </dependency>-->
<!-- 微信公众号模块。默认注释,保证编译速度 -->
<!-- <dependency>-->
@ -68,21 +68,21 @@
<!-- </dependency>-->
<!-- 商城相关模块。默认注释,保证编译速度 -->
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-module-promotion-biz</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-module-product-biz</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-module-trade-biz</artifactId>
<version>${revision}</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>cn.iocoder.boot</groupId>-->
<!-- <artifactId>yudao-module-promotion-biz</artifactId>-->
<!-- <version>${revision}</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>cn.iocoder.boot</groupId>-->
<!-- <artifactId>yudao-module-product-biz</artifactId>-->
<!-- <version>${revision}</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>cn.iocoder.boot</groupId>-->
<!-- <artifactId>yudao-module-trade-biz</artifactId>-->
<!-- <version>${revision}</version>-->
<!-- </dependency>-->
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-module-shop-biz</artifactId>

Binary file not shown.

View File

@ -0,0 +1,25 @@
-----BEGIN CERTIFICATE-----
MIIEQDCCAyigAwIBAgIUWP21A/krbA4ljJlAu3JsK/YCLlYwDQYJKoZIhvcNAQEL
BQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsT
FFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3Qg
Q0EwHhcNMjMwNDExMDgwODE3WhcNMjgwNDA5MDgwODE3WjCBmTETMBEGA1UEAwwK
MTY0MTk5MzQxNzEbMBkGA1UECgwS5b6u5L+h5ZWG5oi357O757ufMUUwQwYDVQQL
DDzliJvnm4jkupHnvZHnu5zvvIjph43luobvvInmnInpmZDlhazlj7jmuJ3ljJfn
rKzkuIDliIblhazlj7gxCzAJBgNVBAYMAkNOMREwDwYDVQQHDAhTaGVuWmhlbjCC
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANWSWLmJaVbrJJq3uhbutKC6
1ly6GbAxbnJgq8O9fP/MRLOljUHDSqUleVat1sVmSNwbsJuk0Hr0e1uowxGSJ3NY
iYMXMWj3S7iPxY+9ShkCJXWfvvPPjSTabk1dg3AUM8ukREQOqvlIFRyJfCUoirlj
2CGXfgMvEjtPYUouFWvB0EU9k+5LzynIyXckpVstx1rWZtlSRF/iviW5BaPf2sZk
0DDEbeMM13BsRSNOHS1NWU8DkV5zb1hNBq/T/OQ7glbs3kHqlD+TXEkcrN64Nr1r
ErohctE6Ep0d1iRUMFYjJXFvBq/1qyi62Vp1wwk1XAqoiyuIfqKGrPhl7Z6Z++cC
AwEAAaOBuTCBtjAJBgNVHRMEAjAAMAsGA1UdDwQEAwID+DCBmwYDVR0fBIGTMIGQ
MIGNoIGKoIGHhoGEaHR0cDovL2V2Y2EuaXRydXMuY29tLmNuL3B1YmxpYy9pdHJ1
c2NybD9DQT0xQkQ0MjIwRTUwREJDMDRCMDZBRDM5NzU0OTg0NkMwMUMzRThFQkQy
JnNnPUhBQ0M0NzFCNjU0MjJFMTJCMjdBOUQzM0E4N0FEMUNERjU5MjZFMTQwMzcx
MA0GCSqGSIb3DQEBCwUAA4IBAQBChfNK0TvOcibwW7vK7ClGwolrNbGwjkAJU1MQ
IQuJUfoGnTrOLb68XKEffUqBL9SaUV9ncnkr/yJPRjltZZilbb6kFQXPqDWw6Dd1
ffPYlxrTSofPcWmZVz6LP0Xx7snslcu/qzbPBOth/Dx/nOsexwCuAJkft72tGBww
OeKvQcfUrc5bS7Nq9GtLRgjhMbDb4LVQ+ivXLhbU4stY6v6MttMSNpN90ngpeCV0
ZpRnKi2+fI/Gljyj5xEm8nMUYkg4vrJcsBK2PZVkRdlyNKiZXdrHn7dYwuujH3NS
1Sf46cO6gTquBGvkkAnO1NWPlz558g2EwzP5zOiPZCfKWk/7
-----END CERTIFICATE-----

View File

@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDVkli5iWlW6ySa
t7oW7rSgutZcuhmwMW5yYKvDvXz/zESzpY1Bw0qlJXlWrdbFZkjcG7CbpNB69Htb
qMMRkidzWImDFzFo90u4j8WPvUoZAiV1n77zz40k2m5NXYNwFDPLpEREDqr5SBUc
iXwlKIq5Y9ghl34DLxI7T2FKLhVrwdBFPZPuS88pyMl3JKVbLcda1mbZUkRf4r4l
uQWj39rGZNAwxG3jDNdwbEUjTh0tTVlPA5Fec29YTQav0/zkO4JW7N5B6pQ/k1xJ
HKzeuDa9axK6IXLROhKdHdYkVDBWIyVxbwav9asoutladcMJNVwKqIsriH6ihqz4
Ze2emfvnAgMBAAECggEBAJk92MvH/P2Q20LocW3i+Vgat5TxM11pGoaXNqfMXtRs
DR+ZujFlnznAGcBIG8KoEb9dXutO5whSQ/EQtmb1J7lr3b9h9OIMDxjukCMC/xfS
om4zoR/v3KaE1IBOiPDyjfegdhsfKy6SuhMv0xQWcvNy4LG5sYE3VS2ZV4WSa2xU
5OVCpGCsm0vxK3SVzbsSUnGFEn1zZZabLCh48L1BALHkszCsy575z9g1Hyh2jfuK
50lTrhIw5r4xyITCq6qA7nXSHREStp8ps39+U0qxYwEa9VDNNLPMkZ5iB7q0aJJR
xGdyRoqwbGKI7/DvXPEbM3VtLkdtgdbaap6gvZWnrIECgYEA9LVCRF6jJ5EDjEqg
CN+WahBeOMhiRhaQD0pCBAUqB0g1mq0FdunsKYzjwKWwGJkguCN6nw9AtSRVs2x/
BuCWnL8yYvVEg04WLpV66GbffifImV9qEzRmWbAR0g6uOFNZJDAxk+CLm6NexBIK
UJgJeTzBs+pr4Gm37C4fXTBVm2MCgYEA321F6CZuZ1qvKUhidCYN7Vc7ntpKenFj
CysM8zbJABMaiaDWw7EQDHkm1VY3BnvS5YYmpwTnVVdIuzrosBWxemrd1JBqyxNI
o9o1kYzQMoRmKa1HEN1dUWLhIJXjGSk7o73Zo0G+mb1WwZvenFY2Of4RJ0c7Zw+g
qrQW2f/KPq0CgYAudfe1+W3qxjqxOT33UVRCoQbyqwEVo5UIgiXUk5JuPYSH8I/Y
CwPew7Q+UHcFxJUUwQ+4AXJcsiBfZ5samCugaSDM7xpp/7pwb8sdMuL+FdmdXSNL
sCg6oRZRFp53bUPAfjH7jKeVDkig23f/403xKdrxKPIAcrIL8pnb3KB0VwKBgEBF
CqrxAykv6NsTO17142O2iCv11x7Jpxf7VkpQJBmlZSjZ322DbX5pC0aq+kEfNVdY
851vx6vA4+cX1v9v/hGc1BrlQBMShP69MlOgEfO2Kj0q3xp20vUqYGAjPaRrPACq
CATyUIWg9WfUEoEeO5MLBpwp3WiUEj+IdlpXPjIxAoGBAJSBr2vITajfFfIMsafv
WnF6fB13FXkS/1+ndCWjwu04YDU7eUgiWLetaMntizDb1L303RjLax9wUZI8lBV3
0etV7avvHZQLZmCqeikXgkYj+kbR4O7BgJI/P5OcKK1QfYSs4K9sYIjz/R4mJu6G
mZcrpcHTH5/k9ucLvJ3m/8ga
-----END PRIVATE KEY-----

Binary file not shown.

View File

@ -0,0 +1,25 @@
-----BEGIN CERTIFICATE-----
MIIEQDCCAyigAwIBAgIUR/BNUflY/+9Wpt/CW96Dz4k1PhkwDQYJKoZIhvcNAQEL
BQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsT
FFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3Qg
Q0EwHhcNMjMwNDEyMDYyMzI1WhcNMjgwNDEwMDYyMzI1WjCBmTETMBEGA1UEAwwK
MTY0MjA0MjU4OTEbMBkGA1UECgwS5b6u5L+h5ZWG5oi357O757ufMUUwQwYDVQQL
DDzliJvnm4jkupHnvZHnu5zvvIjph43luobvvInmnInpmZDlhazlj7jmuJ3ljJfn
rKzkuozliIblhazlj7gxCzAJBgNVBAYMAkNOMREwDwYDVQQHDAhTaGVuWmhlbjCC
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANM2lFR09VB7Rbopa5uRUcLH
YugBRTBuh5R+ctf3uW0fZN2iMZdaqj8weJzg8IOC+rDknruKq3y6ofLWDL/qtJtR
m8vHYx5L0tSS1K8ODWVNZ5A6YOkI0Zebnw6vWva2gVlyTi7cKk/UIWEklXkSNFc9
FootaXdQK6xtq0t1c+Cuq4LKDlrCMTXReg4Y/cuWA5/5RubIXe+6UUlY4Il1e/LN
GV0zeTtkT/sw09pd+/fWOoDXDqbUX3yNVUrf0rXAl2SZlCuRfoxzh42LXyEdLlbs
z0CKZIrntQ85zmp0P2AFolR9cBmtchsAIVtjYXFbKtBK6olW9JxKNqdWyyhiAHUC
AwEAAaOBuTCBtjAJBgNVHRMEAjAAMAsGA1UdDwQEAwID+DCBmwYDVR0fBIGTMIGQ
MIGNoIGKoIGHhoGEaHR0cDovL2V2Y2EuaXRydXMuY29tLmNuL3B1YmxpYy9pdHJ1
c2NybD9DQT0xQkQ0MjIwRTUwREJDMDRCMDZBRDM5NzU0OTg0NkMwMUMzRThFQkQy
JnNnPUhBQ0M0NzFCNjU0MjJFMTJCMjdBOUQzM0E4N0FEMUNERjU5MjZFMTQwMzcx
MA0GCSqGSIb3DQEBCwUAA4IBAQB2ClqsShiW9SeWqJA4UGrc9quQUXfldQ827F7G
v64L9umRWSkttCFHxYaN8zfyGnxs3NgpKFKma1zyo3NIhrqMlOtiaYkeLihS3xl6
wGOgOYs6TO/YkWqoO+6jszhAo+jZLRyMwm8GYP4wILGgBXKAyai9gkWbSq36kIHK
xRcGodCsWZzF7jR30Hry3knRuHkSFGEY5sTlAWrh/CoVuQTEuE5PUiu0flsoJUvy
A3bq6jkzpq+Pwcg2WOQMNNa2rJP0ABcfluUZn+WqvgMc771qVNSk0eQTeU4jWmrW
v5GGs8kv/SS50CBQ0RXZvyG9tM1fLiR1wLMTBuGWpeIjsL6S
-----END CERTIFICATE-----

View File

@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDTNpRUdPVQe0W6
KWubkVHCx2LoAUUwboeUfnLX97ltH2TdojGXWqo/MHic4PCDgvqw5J67iqt8uqHy
1gy/6rSbUZvLx2MeS9LUktSvDg1lTWeQOmDpCNGXm58Or1r2toFZck4u3CpP1CFh
JJV5EjRXPRaKLWl3UCusbatLdXPgrquCyg5awjE10XoOGP3LlgOf+UbmyF3vulFJ
WOCJdXvyzRldM3k7ZE/7MNPaXfv31jqA1w6m1F98jVVK39K1wJdkmZQrkX6Mc4eN
i18hHS5W7M9AimSK57UPOc5qdD9gBaJUfXAZrXIbACFbY2FxWyrQSuqJVvScSjan
VssoYgB1AgMBAAECggEBAL9TQ4413DopUIJQHv/u5WdRghCzhd9XYE1tNc7YwglN
VOtHjzCRmoJfAALr6DLZJQm0Lu2nsavsy+LTbv0yOKQxirVPSkQZX0PcNfjU++F1
+og1ua+eo214NN7yja3KqOVDm/rqyRFDEXGT2CqyCOO1nINSm6TO5KDvPym9nVg6
e7DIVE0k0kTh8JKM25NZ6qEOwqu8W9g+mHI4cGnNFbV4uL6jxPBO7L26piNaEsQk
av/0ZThDBizl72qvzbfCiZDGrWseKGI8VyF3KWfKa/666HXh6DpWcE6CsePZLlmn
XWomhdU+xybPyS/eV9X9ET6UDE5fRn6+R/2QIJ8nioECgYEA9BUYF1FzSjLr48zR
axLFCdDLihQRBgUfYGy+PykoXPXp6OxfxOOrWh5+b0wW/fXkq0lfVP+rYzTy4veg
aIsdwyrtzHXDhpqW7gdseB1BEAAWLck0lgmL/DuPLMwjw4lCZmA6YNsfnN9XZ3Gl
QYPmKO9fKsXGrSjq7GxRffhSdnECgYEA3YajFUaoZqeY6vQpfY59WC6/vgl6Iyzb
QleX/RIJUU8nhRnqgDCwUqH1T4MXKRGQ5m8s+wPUNIC/oBNGWNeFXujeCuvoXI5b
rxX+Jswp7eqfk1ybO65tR1Mj8y+vCqFuH5TtaPlq7ZKzp0bumqb7j5jrFMg2x39+
sEABUPN7VEUCgYBP3HMEdib1uRGLeGFw2jRUENf39rbXNGfewdXBjrLhL6j4CBcR
sbhIBUAzJD9FmuXV0Wz6v6iRDisGbiUy74muaOZjhoiSCxSlDxLDfjbiiFS5aGLn
UHpX7hjbfHObL9bk7klLlYaTalQLyZhbhk+RRzjpIsrtrzymXI6RW+WHUQKBgE9a
T0jryp8bIhfn5oTnadcQx/aXBn1bMB+PqQ4qS9QoeoufQPUye7bd9TXKS52WgUVK
Rd6U/IriI8J/pQ9mBIx+9isLXmzpQcZyJlxXfh2PkiIDZkf2r4aBLbuLNTSlpwEB
JBoaXkdD6b7eFdKoRiymJm+HWLgV35fbFZ2d2mvRAoGBAJl6nSvzCeRzWe27pVAv
iqQrCfDTVQHpleCeHOUUQ9oD4H5+ez+ucFHtrf4Ed3PA48v8iQgEf67jdGFsl1F7
W+o3fXruRlSjyUdoMDt3GiDxRhloxMs+1cS7seKV13HS5GJZ301vCgX7XuSLEjNu
mwEvp8boEFCZZphDYoaE2kG8
-----END PRIVATE KEY-----

View File

@ -162,8 +162,8 @@ debug: false
--- #################### 微信公众号、小程序相关配置 ####################
wx:
mp: # 公众号配置(必填),参见 https://github.com/Wechat-Group/WxJava/blob/develop/spring-boot-starters/wx-java-mp-spring-boot-starter/README.md 文档
app-id: wx041349c6f39b268b
secret: 5abee519483bc9f8cb37ce280e814bd0
app-id: wxb1826c88da21d81e
secret: 1960c9cc785b094040a4fd4b2955c0cb
# 存储配置,解决 AccessToken 的跨节点的共享
config-storage:
type: RedisTemplate # 采用 RedisTemplate 操作 Redis会自动从 Spring 中获取
@ -176,7 +176,31 @@ wx:
type: RedisTemplate # 采用 RedisTemplate 操作 Redis会自动从 Spring 中获取
key-prefix: wa # Redis Key 的前缀 TODO 芋艿:解决下 Redis key 管理的配置
http-client-type: HttpClient # 采用 HttpClient 请求微信公众号平台
pay:
one:
enabled: true
app-id: wxb1826c88da21d81e
mch-id: 1641993417
mch-key: qdn2I7Cmx4JeiKOt2CDjiu6UHgLTsOsM
apiv3-key: cyywl666666cyywl888888cyywl66666
private-cert-path: classpath:/1/apiclient_cert.pem
private-key-path: classpath:/1/apiclient_key.pem
key-path: classpath:/1/apiclient_cert.p12
cert-serial-no: 58FDB503F92B6C0E258C9940BB726C2BF6022E56
notify-url: http://yuxy.perrymake.com/app-api/pay/wxpay/pay_notify
refund-notify-url: http://yuxy.perrymake.com/app-api/pay/wxpay/refund_notify
two:
enabled: true
app-id: wxb1826c88da21d81e
mch-id: 1642042589
mch-key: qdn2I7Cmx4JeiKOt2CDjiu6UHgLTsOsM
apiv3-key: cyywl666666cyywl888888cyywl66666
private-cert-path: classpath:/2/apiclient_cert.pem
private-key-path: classpath:/2/apiclient_key.pem
key-path: classpath:/2/apiclient_cert.p12
cert-serial-no: 47F04D51F958FFEF56A6DFC25BDE83CF89353E19
notify-url: http://yuxy.perrymake.com/app-api/pay/wxpay/pay_notify
refund-notify-url: http://yuxy.perrymake.com/app-api/pay/wxpay/refund_notify
--- #################### 芋道相关配置 ####################
# 芋道配置项,设置当前项目所有自定义的配置

View File

@ -107,6 +107,7 @@ yudao:
security:
permit-all_urls:
- /admin-api/mp/open/** # 微信公众号开放平台,微信回调接口,不需要登录
- /admin-api/notice/wxpay/**
websocket:
enable: true # websocket的开关
path: /websocket/message # 路径
@ -145,6 +146,7 @@ yudao:
- /admin-api/pay/notify/callback/* # 支付回调通知,不携带租户编号
- /jmreport/* # 积木报表,无法携带租户编号
- /admin-api/mp/open/** # 微信公众号开放平台,微信回调接口,无法携带租户编号
- /admin-api/notify/wxpay/**
ignore-tables:
- system_tenant
- system_tenant_package

View File

@ -20,4 +20,4 @@ VUE_APP_CAPTCHA_ENABLE = true
VUE_APP_DOC_ENABLE = true
# 百度统计
VUE_APP_BAIDU_CODE = fadc1bd5db1a1d6f581df60a1807f8ab
VUE_APP_BAIDU_CODE =

View File

@ -0,0 +1,54 @@
import request from '@/utils/request'
// 创建充值档位记录
export function createPhoneRecord(data) {
return request({
url: '/shop/phone-record/create',
method: 'post',
data: data
})
}
// 更新充值档位记录
export function updatePhoneRecord(data) {
return request({
url: '/shop/phone-record/update',
method: 'put',
data: data
})
}
// 删除充值档位记录
export function deletePhoneRecord(id) {
return request({
url: '/shop/phone-record/delete?id=' + id,
method: 'delete'
})
}
// 获得充值档位记录
export function getPhoneRecord(id) {
return request({
url: '/shop/phone-record/get?id=' + id,
method: 'get'
})
}
// 获得充值档位记录分页
export function getPhoneRecordPage(query) {
return request({
url: '/shop/phone-record/page',
method: 'get',
params: query
})
}
// 导出充值档位记录 Excel
export function exportPhoneRecordExcel(query) {
return request({
url: '/shop/phone-record/export-excel',
method: 'get',
params: query,
responseType: 'blob'
})
}

View File

@ -0,0 +1,54 @@
import request from '@/utils/request'
// 创建订单
export function createRechargeOrder(data) {
return request({
url: '/shop/recharge-order/create',
method: 'post',
data: data
})
}
// 更新订单
export function updateRechargeOrder(data) {
return request({
url: '/shop/recharge-order/update',
method: 'put',
data: data
})
}
// 删除订单
export function deleteRechargeOrder(id) {
return request({
url: '/shop/recharge-order/delete?id=' + id,
method: 'delete'
})
}
// 获得订单
export function getRechargeOrder(id) {
return request({
url: '/shop/recharge-order/get?id=' + id,
method: 'get'
})
}
// 获得订单分页
export function getRechargeOrderPage(query) {
return request({
url: '/shop/recharge-order/page',
method: 'get',
params: query
})
}
// 导出订单 Excel
export function exportRechargeOrderExcel(query) {
return request({
url: '/shop/recharge-order/export-excel',
method: 'get',
params: query,
responseType: 'blob'
})
}

View File

@ -0,0 +1,272 @@
<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="用户id" prop="userId">
<el-input v-model="queryParams.userId" placeholder="请输入用户id" clearable @keyup.enter.native="handleQuery"/>
</el-form-item>
<el-form-item label="充值订单id" prop="rechargeOrderId">
<el-input v-model="queryParams.rechargeOrderId" placeholder="请输入充值订单id" clearable @keyup.enter.native="handleQuery"/>
</el-form-item>
<el-form-item label="充值号码" prop="phone">
<el-input v-model="queryParams.phone" placeholder="请输入充值号码" clearable @keyup.enter.native="handleQuery"/>
</el-form-item>
<el-form-item label="返费金额" prop="refundFeeAmount">
<el-input v-model="queryParams.refundFeeAmount" placeholder="请输入返费金额" clearable @keyup.enter.native="handleQuery"/>
</el-form-item>
<el-form-item label="充值档位" prop="rechargeGearId">
<el-input v-model="queryParams.rechargeGearId" placeholder="请输入充值档位" clearable @keyup.enter.native="handleQuery"/>
</el-form-item>
<el-form-item label="返费结束日期" prop="refundFeeEndDate">
<el-date-picker v-model="queryParams.refundFeeEndDate" style="width: 240px" value-format="yyyy-MM-dd HH:mm:ss" type="daterange"
range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" :default-time="['00:00:00', '23:59:59']" />
</el-form-item>
<el-form-item label="返费期数" prop="refundFeeNumber">
<el-input v-model="queryParams.refundFeeNumber" placeholder="请输入返费期数" clearable @keyup.enter.native="handleQuery"/>
</el-form-item>
<el-form-item label="创建时间" prop="createTime">
<el-date-picker v-model="queryParams.createTime" style="width: 240px" value-format="yyyy-MM-dd HH:mm:ss" type="daterange"
range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" :default-time="['00:00:00', '23:59:59']" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="handleQuery"></el-button>
<el-button icon="el-icon-refresh" @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="['shop:phone-record:create']">新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport" :loading="exportLoading"
v-hasPermi="['shop:phone-record:export']">导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<!-- 列表 -->
<el-table v-loading="loading" :data="list">
<el-table-column label="主键" align="center" prop="id" />
<el-table-column label="用户id" align="center" prop="userId" />
<el-table-column label="充值订单id" align="center" prop="rechargeOrderId" />
<el-table-column label="充值号码" align="center" prop="phone" />
<el-table-column label="返费金额" align="center" prop="refundFeeAmount" />
<el-table-column label="充值档位" align="center" prop="rechargeGearId" />
<el-table-column label="返费结束日期" align="center" prop="refundFeeEndDate" width="180">
<template v-slot="scope">
<span>{{ parseTime(scope.row.refundFeeEndDate) }}</span>
</template>
</el-table-column>
<el-table-column label="返费期数" align="center" prop="refundFeeNumber" />
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
<template v-slot="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template v-slot="scope">
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
v-hasPermi="['shop:phone-record:update']">修改</el-button>
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
v-hasPermi="['shop:phone-record:delete']">删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页组件 -->
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
@pagination="getList"/>
<!-- 对话框(添加 / 修改) -->
<el-dialog :title="title" :visible.sync="open" width="500px" v-dialogDrag append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="用户id" prop="userId">
<el-input v-model="form.userId" placeholder="请输入用户id" />
</el-form-item>
<el-form-item label="充值订单id" prop="rechargeOrderId">
<el-input v-model="form.rechargeOrderId" placeholder="请输入充值订单id" />
</el-form-item>
<el-form-item label="充值号码" prop="phone">
<el-input v-model="form.phone" placeholder="请输入充值号码" />
</el-form-item>
<el-form-item label="返费金额" prop="refundFeeAmount">
<el-input v-model="form.refundFeeAmount" placeholder="请输入返费金额" />
</el-form-item>
<el-form-item label="充值档位" prop="rechargeGearId">
<el-input v-model="form.rechargeGearId" placeholder="请输入充值档位" />
</el-form-item>
<el-form-item label="返费结束日期" prop="refundFeeEndDate">
<el-date-picker clearable v-model="form.refundFeeEndDate" type="date" value-format="timestamp" placeholder="选择返费结束日期" />
</el-form-item>
<el-form-item label="返费期数" prop="refundFeeNumber">
<el-input v-model="form.refundFeeNumber" 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 { createPhoneRecord, updatePhoneRecord, deletePhoneRecord, getPhoneRecord, getPhoneRecordPage, exportPhoneRecordExcel } from "@/api/shop/phoneRecord";
export default {
name: "PhoneRecord",
components: {
},
data() {
return {
//
loading: true,
//
exportLoading: false,
//
showSearch: true,
//
total: 0,
//
list: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNo: 1,
pageSize: 10,
userId: null,
rechargeOrderId: null,
phone: null,
refundFeeAmount: null,
rechargeGearId: null,
refundFeeEndDate: [],
refundFeeNumber: null,
createTime: [],
},
//
form: {},
//
rules: {
phone: [{ required: true, message: "充值号码不能为空", trigger: "blur" }],
refundFeeAmount: [{ required: true, message: "返费金额不能为空", trigger: "blur" }],
rechargeGearId: [{ required: true, message: "充值档位不能为空", trigger: "blur" }],
refundFeeEndDate: [{ required: true, message: "返费结束日期不能为空", trigger: "blur" }],
refundFeeNumber: [{ required: true, message: "返费期数不能为空", trigger: "blur" }],
}
};
},
created() {
this.getList();
},
methods: {
/** 查询列表 */
getList() {
this.loading = true;
//
getPhoneRecordPage(this.queryParams).then(response => {
this.list = response.data.list;
this.total = response.data.total;
this.loading = false;
});
},
/** 取消按钮 */
cancel() {
this.open = false;
this.reset();
},
/** 表单重置 */
reset() {
this.form = {
id: undefined,
userId: undefined,
rechargeOrderId: undefined,
phone: undefined,
refundFeeAmount: undefined,
rechargeGearId: undefined,
refundFeeEndDate: undefined,
refundFeeNumber: undefined,
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNo = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加充值档位记录";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id;
getPhoneRecord(id).then(response => {
this.form = response.data;
this.open = true;
this.title = "修改充值档位记录";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (!valid) {
return;
}
//
if (this.form.id != null) {
updatePhoneRecord(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
return;
}
//
createPhoneRecord(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
});
},
/** 删除按钮操作 */
handleDelete(row) {
const id = row.id;
this.$modal.confirm('是否确认删除充值档位记录编号为"' + id + '"的数据项?').then(function() {
return deletePhoneRecord(id);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
//
let params = {...this.queryParams};
params.pageNo = undefined;
params.pageSize = undefined;
this.$modal.confirm('是否确认导出所有充值档位记录数据项?').then(() => {
this.exportLoading = true;
return exportPhoneRecordExcel(params);
}).then(response => {
this.$download.excel(response, '充值档位记录.xls');
this.exportLoading = false;
}).catch(() => {});
}
}
};
</script>

View File

@ -0,0 +1,441 @@
<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="orderId">
<el-input v-model="queryParams.orderId" placeholder="请输入订单号" clearable @keyup.enter.native="handleQuery"/>
</el-form-item>
<el-form-item label="用户姓名" prop="realName">
<el-input v-model="queryParams.realName" placeholder="请输入用户姓名" clearable @keyup.enter.native="handleQuery"/>
</el-form-item>
<el-form-item label="用户电话" prop="userPhone">
<el-input v-model="queryParams.userPhone" placeholder="请输入用户电话" clearable @keyup.enter.native="handleQuery"/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="handleQuery"></el-button>
<el-button icon="el-icon-refresh" @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="['shop:recharge-order:create']">新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport" :loading="exportLoading"
v-hasPermi="['shop:recharge-order:export']">导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<!-- 列表 -->
<el-table v-loading="loading" :data="list">
<el-table-column label="订单ID" align="center" prop="id" />
<el-table-column label="订单号" align="center" prop="orderId" />
<el-table-column label="用户id" align="center" prop="uid" />
<el-table-column label="用户姓名" align="center" prop="realName" />
<el-table-column label="用户电话" align="center" prop="userPhone" />
<el-table-column label="确认手机号" align="center" prop="confirmPhone" />
<el-table-column label="订单商品总数" align="center" prop="totalNum" />
<el-table-column label="订单总价" align="center" prop="totalPrice" />
<el-table-column label="实际支付金额" align="center" prop="payPrice" />
<el-table-column label="支付状态" align="center" prop="paid" />
<el-table-column label="支付截止时间" align="center" prop="payTime" width="180">
<template v-slot="scope">
<span>{{ parseTime(scope.row.payTime) }}</span>
</template>
</el-table-column>
<el-table-column label="支付截止时间" align="center" prop="payEndTime" width="180">
<template v-slot="scope">
<span>{{ parseTime(scope.row.payEndTime) }}</span>
</template>
</el-table-column>
<el-table-column label="支付方式" align="center" prop="payType" />
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
<template v-slot="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column label="订单状态0待发货1待收货2已收货待评价3已完成" align="center" prop="status" />
<el-table-column label="0 未退款 1 申请中 2 已退款 3 退款中" align="center" prop="refundStatus" />
<el-table-column label="退款图片" align="center" prop="refundReasonWapImg" />
<el-table-column label="退款用户说明" align="center" prop="refundReasonWapExplain" />
<el-table-column label="前台退款原因" align="center" prop="refundReasonWap" />
<el-table-column label="不退款的理由" align="center" prop="refundReason" />
<el-table-column label="退款时间" align="center" prop="refundReasonTime" width="180">
<template v-slot="scope">
<span>{{ parseTime(scope.row.refundReasonTime) }}</span>
</template>
</el-table-column>
<el-table-column label="退款金额" align="center" prop="refundPrice" />
<el-table-column label="备注" align="center" prop="mark" />
<el-table-column label="管理员备注" align="center" prop="remark" />
<el-table-column label="成本价" align="center" prop="cost" />
<el-table-column label="支付渠道(0微信公众号1微信小程序2余额)" align="center" prop="isChannel" />
<el-table-column label="消息提醒" align="center" prop="isRemind" />
<el-table-column label="后台是否删除" align="center" prop="isSystemDel" />
<el-table-column label="订单类型:0-普通订单1-视频号订单" align="center" prop="type" />
<el-table-column label="商品总价" align="center" prop="proTotalPrice" />
<el-table-column label="改价前支付金额" align="center" prop="beforePayPrice" />
<el-table-column label="是否改价,0-否1-是" align="center" prop="isAlterPrice" />
<el-table-column label="商户系统内部的订单号,32个字符内、可包含字母, 其他说明见商户订单号" align="center" prop="outTradeNo" />
<el-table-column label="第三方支付流水号" align="center" prop="paySerialNumber" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template v-slot="scope">
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
v-hasPermi="['shop:recharge-order:update']">修改</el-button>
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
v-hasPermi="['shop:recharge-order:delete']">删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页组件 -->
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
@pagination="getList"/>
<!-- 对话框(添加 / 修改) -->
<el-dialog :title="title" :visible.sync="open" width="500px" v-dialogDrag append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="订单号" prop="orderId">
<el-input v-model="form.orderId" placeholder="请输入订单号" />
</el-form-item>
<el-form-item label="用户id" prop="uid">
<el-input v-model="form.uid" placeholder="请输入用户id" />
</el-form-item>
<el-form-item label="用户姓名" prop="realName">
<el-input v-model="form.realName" placeholder="请输入用户姓名" />
</el-form-item>
<el-form-item label="用户电话" prop="userPhone">
<el-input v-model="form.userPhone" placeholder="请输入用户电话" />
</el-form-item>
<el-form-item label="确认手机号" prop="confirmPhone">
<el-input v-model="form.confirmPhone" placeholder="请输入确认手机号" />
</el-form-item>
<el-form-item label="订单商品总数" prop="totalNum">
<el-input v-model="form.totalNum" placeholder="请输入订单商品总数" />
</el-form-item>
<el-form-item label="订单总价" prop="totalPrice">
<el-input v-model="form.totalPrice" placeholder="请输入订单总价" />
</el-form-item>
<el-form-item label="实际支付金额" prop="payPrice">
<el-input v-model="form.payPrice" placeholder="请输入实际支付金额" />
</el-form-item>
<el-form-item label="支付状态" prop="paid">
<el-input v-model="form.paid" placeholder="请输入支付状态" />
</el-form-item>
<el-form-item label="支付截止时间" prop="payTime">
<el-date-picker clearable v-model="form.payTime" type="date" value-format="timestamp" placeholder="选择支付截止时间" />
</el-form-item>
<el-form-item label="支付截止时间" prop="payEndTime">
<el-date-picker clearable v-model="form.payEndTime" type="date" value-format="timestamp" placeholder="选择支付截止时间" />
</el-form-item>
<el-form-item label="支付方式" prop="payType">
<el-select v-model="form.payType" placeholder="请选择支付方式">
<el-option label="请选择字典生成" value="" />
</el-select>
</el-form-item>
<el-form-item label="订单状态0待发货1待收货2已收货待评价3已完成" prop="status">
<el-radio-group v-model="form.status">
<el-radio label="1">请选择字典生成</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="0 未退款 1 申请中 2 已退款 3 退款中" prop="refundStatus">
<el-radio-group v-model="form.refundStatus">
<el-radio label="1">请选择字典生成</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="退款图片" prop="refundReasonWapImg">
<el-input v-model="form.refundReasonWapImg" placeholder="请输入退款图片" />
</el-form-item>
<el-form-item label="退款用户说明" prop="refundReasonWapExplain">
<el-input v-model="form.refundReasonWapExplain" placeholder="请输入退款用户说明" />
</el-form-item>
<el-form-item label="前台退款原因" prop="refundReasonWap">
<el-input v-model="form.refundReasonWap" placeholder="请输入前台退款原因" />
</el-form-item>
<el-form-item label="不退款的理由" prop="refundReason">
<el-input v-model="form.refundReason" placeholder="请输入不退款的理由" />
</el-form-item>
<el-form-item label="退款时间" prop="refundReasonTime">
<el-date-picker clearable v-model="form.refundReasonTime" type="date" value-format="timestamp" placeholder="选择退款时间" />
</el-form-item>
<el-form-item label="退款金额" prop="refundPrice">
<el-input v-model="form.refundPrice" placeholder="请输入退款金额" />
</el-form-item>
<el-form-item label="备注" prop="mark">
<el-input v-model="form.mark" placeholder="请输入备注" />
</el-form-item>
<el-form-item label="管理员备注" prop="remark">
<el-input v-model="form.remark" placeholder="请输入管理员备注" />
</el-form-item>
<el-form-item label="成本价" prop="cost">
<el-input v-model="form.cost" placeholder="请输入成本价" />
</el-form-item>
<el-form-item label="支付渠道(0微信公众号1微信小程序2余额)" prop="isChannel">
<el-input v-model="form.isChannel" placeholder="请输入支付渠道(0微信公众号1微信小程序2余额)" />
</el-form-item>
<el-form-item label="消息提醒" prop="isRemind">
<el-input v-model="form.isRemind" placeholder="请输入消息提醒" />
</el-form-item>
<el-form-item label="后台是否删除" prop="isSystemDel">
<el-radio-group v-model="form.isSystemDel">
<el-radio label="1">请选择字典生成</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="订单类型:0-普通订单1-视频号订单" prop="type">
<el-select v-model="form.type" placeholder="请选择订单类型:0-普通订单1-视频号订单">
<el-option label="请选择字典生成" value="" />
</el-select>
</el-form-item>
<el-form-item label="商品总价" prop="proTotalPrice">
<el-input v-model="form.proTotalPrice" placeholder="请输入商品总价" />
</el-form-item>
<el-form-item label="改价前支付金额" prop="beforePayPrice">
<el-input v-model="form.beforePayPrice" placeholder="请输入改价前支付金额" />
</el-form-item>
<el-form-item label="是否改价,0-否1-是" prop="isAlterPrice">
<el-radio-group v-model="form.isAlterPrice">
<el-radio label="1">请选择字典生成</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="商户系统内部的订单号,32个字符内、可包含字母, 其他说明见商户订单号" prop="outTradeNo">
<el-input v-model="form.outTradeNo" placeholder="请输入商户系统内部的订单号,32个字符内、可包含字母, 其他说明见商户订单号" />
</el-form-item>
<el-form-item label="第三方支付流水号" prop="paySerialNumber">
<el-input v-model="form.paySerialNumber" 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 { createRechargeOrder, updateRechargeOrder, deleteRechargeOrder, getRechargeOrder, getRechargeOrderPage, exportRechargeOrderExcel } from "@/api/shop/rechargeOrder";
export default {
name: "RechargeOrder",
components: {
},
data() {
return {
//
loading: true,
//
exportLoading: false,
//
showSearch: true,
//
total: 0,
//
list: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNo: 1,
pageSize: 10,
orderId: null,
uid: null,
realName: null,
userPhone: null,
confirmPhone: null,
totalNum: null,
totalPrice: null,
payPrice: null,
paid: null,
payTime: [],
payEndTime: [],
payType: null,
createTime: [],
status: null,
refundStatus: null,
refundReasonWapImg: null,
refundReasonWapExplain: null,
refundReasonWap: null,
refundReason: null,
refundReasonTime: [],
refundPrice: null,
mark: null,
remark: null,
cost: null,
isChannel: null,
isRemind: null,
isSystemDel: null,
type: null,
proTotalPrice: null,
beforePayPrice: null,
isAlterPrice: null,
outTradeNo: null,
paySerialNumber: null,
},
//
form: {},
//
rules: {
orderId: [{ required: true, message: "订单号不能为空", trigger: "blur" }],
uid: [{ required: true, message: "用户id不能为空", trigger: "blur" }],
realName: [{ required: true, message: "用户姓名不能为空", trigger: "blur" }],
userPhone: [{ required: true, message: "用户电话不能为空", trigger: "blur" }],
confirmPhone: [{ required: true, message: "确认手机号不能为空", trigger: "blur" }],
totalNum: [{ required: true, message: "订单商品总数不能为空", trigger: "blur" }],
totalPrice: [{ required: true, message: "订单总价不能为空", trigger: "blur" }],
payPrice: [{ required: true, message: "实际支付金额不能为空", trigger: "blur" }],
paid: [{ required: true, message: "支付状态不能为空", trigger: "blur" }],
payTime: [{ required: true, message: "支付截止时间不能为空", trigger: "blur" }],
payType: [{ required: true, message: "支付方式不能为空", trigger: "change" }],
status: [{ required: true, message: "订单状态0待发货1待收货2已收货待评价3已完成不能为空", trigger: "blur" }],
refundStatus: [{ required: true, message: "0 未退款 1 申请中 2 已退款 3 退款中不能为空", trigger: "blur" }],
refundPrice: [{ required: true, message: "退款金额不能为空", trigger: "blur" }],
mark: [{ required: true, message: "备注不能为空", trigger: "blur" }],
cost: [{ required: true, message: "成本价不能为空", trigger: "blur" }],
type: [{ required: true, message: "订单类型:0-普通订单1-视频号订单不能为空", trigger: "change" }],
proTotalPrice: [{ required: true, message: "商品总价不能为空", trigger: "blur" }],
beforePayPrice: [{ required: true, message: "改价前支付金额不能为空", trigger: "blur" }],
isAlterPrice: [{ required: true, message: "是否改价,0-否1-是不能为空", trigger: "blur" }],
}
};
},
created() {
this.getList();
},
methods: {
/** 查询列表 */
getList() {
this.loading = true;
//
getRechargeOrderPage(this.queryParams).then(response => {
this.list = response.data.list;
this.total = response.data.total;
this.loading = false;
});
},
/** 取消按钮 */
cancel() {
this.open = false;
this.reset();
},
/** 表单重置 */
reset() {
this.form = {
id: undefined,
orderId: undefined,
uid: undefined,
realName: undefined,
userPhone: undefined,
confirmPhone: undefined,
totalNum: undefined,
totalPrice: undefined,
payPrice: undefined,
paid: undefined,
payTime: undefined,
payEndTime: undefined,
payType: undefined,
status: undefined,
refundStatus: undefined,
refundReasonWapImg: undefined,
refundReasonWapExplain: undefined,
refundReasonWap: undefined,
refundReason: undefined,
refundReasonTime: undefined,
refundPrice: undefined,
mark: undefined,
remark: undefined,
cost: undefined,
isChannel: undefined,
isRemind: undefined,
isSystemDel: undefined,
type: undefined,
proTotalPrice: undefined,
beforePayPrice: undefined,
isAlterPrice: undefined,
outTradeNo: undefined,
paySerialNumber: undefined,
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNo = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加订单";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id;
getRechargeOrder(id).then(response => {
this.form = response.data;
this.open = true;
this.title = "修改订单";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (!valid) {
return;
}
//
if (this.form.id != null) {
updateRechargeOrder(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
return;
}
//
createRechargeOrder(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
});
},
/** 删除按钮操作 */
handleDelete(row) {
const id = row.id;
this.$modal.confirm('是否确认删除订单编号为"' + id + '"的数据项?').then(function() {
return deleteRechargeOrder(id);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
//
let params = {...this.queryParams};
params.pageNo = undefined;
params.pageSize = undefined;
this.$modal.confirm('是否确认导出所有订单数据项?').then(() => {
this.exportLoading = true;
return exportRechargeOrderExcel(params);
}).then(response => {
this.$download.excel(response, '订单.xls');
this.exportLoading = false;
}).catch(() => {});
}
}
};
</script>

View File

@ -1,8 +1,8 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch">
<el-form-item label="部门名称" prop="name">
<el-input v-model="queryParams.name" placeholder="请输入部门名称" clearable @keyup.enter.native="handleQuery"/>
<el-form-item label="组织名称" prop="name">
<el-input v-model="queryParams.name" placeholder="请输入组织名称" clearable @keyup.enter.native="handleQuery"/>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="菜单状态" clearable>
@ -28,7 +28,7 @@
<el-table v-if="refreshTable" v-loading="loading" :data="deptList" row-key="id" :default-expand-all="isExpandAll"
:tree-props="{children: 'children', hasChildren: 'hasChildren'}">
<el-table-column prop="name" label="部门名称" width="260"></el-table-column>
<el-table-column prop="name" label="组织名称" width="260"></el-table-column>
<el-table-column prop="leader" label="负责人" :formatter="userNicknameFormat" width="120"/>
<el-table-column prop="sort" label="排序" width="200"></el-table-column>
<el-table-column prop="status" label="状态" width="100">
@ -53,18 +53,18 @@
</el-table-column>
</el-table>
<!-- 添加或修改部门对话框 -->
<!-- 添加或修改组织对话框 -->
<el-dialog :title="title" :visible.sync="open" width="600px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-row>
<el-col :span="24">
<el-form-item label="上级部门" prop="parentId">
<treeselect v-model="form.parentId" :options="deptOptions" :normalizer="normalizer" placeholder="选择上级部门" />
<el-form-item label="上级组织" prop="parentId">
<treeselect v-model="form.parentId" :options="deptOptions" :normalizer="normalizer" placeholder="选择上级组织" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="部门名称" prop="name">
<el-input v-model="form.name" placeholder="请输入部门名称" />
<el-form-item label="组织名称" prop="name">
<el-input v-model="form.name" placeholder="请输入组织名称" />
</el-form-item>
</el-col>
<el-col :span="12">
@ -90,7 +90,7 @@
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="部门状态" prop="status">
<el-form-item label="组织状态" prop="status">
<el-radio-group v-model="form.status">
<el-radio v-for="dict in statusDictDatas" :key="parseInt(dict.value)" :label="parseInt(dict.value)">
{{dict.label}}</el-radio>
@ -127,7 +127,7 @@ export default {
showSearch: true,
//
deptList: [],
//
//
deptOptions: [],
//
users: [],
@ -151,7 +151,7 @@ export default {
//
rules: {
name: [
{ required: true, message: "部门名称不能为空", trigger: "blur" }
{ required: true, message: "组织名称不能为空", trigger: "blur" }
],
sort: [
{ required: true, message: "显示排序不能为空", trigger: "blur" }
@ -189,7 +189,7 @@ export default {
});
},
methods: {
/** 查询部门列表 */
/** 查询组织列表 */
getList() {
this.loading = true;
listDept(this.queryParams).then(response => {
@ -197,7 +197,7 @@ export default {
this.loading = false;
});
},
/** 转换部门数据结构 */
/** 转换组织数据结构 */
normalizer(node) {
if (node.children && !node.children.length) {
delete node.children;
@ -255,7 +255,7 @@ export default {
this.form.parentId = row.id;
}
this.open = true;
this.title = "添加部门";
this.title = "添加组织";
listDept().then(response => {
this.deptOptions = this.handleTree(response.data, "id");
});
@ -273,11 +273,11 @@ export default {
this.reset();
getDept(row.id).then(response => {
this.form = response.data;
if (this.form.parentId === 0) { // undefined Unknown
if (this.form.parentId === 0) { // undefined Unknown
this.form.parentId = undefined;
}
this.open = true;
this.title = "修改部门";
this.title = "修改组织";
});
listDept(row.id).then(response => {
this.deptOptions = this.handleTree(response.data, "id");