|
|
@@ -10,11 +10,12 @@ import org.springframework.web.bind.annotation.*;
|
|
|
import org.springframework.web.multipart.MultipartFile;
|
|
|
import shop.alien.entity.result.R;
|
|
|
import shop.alien.entity.store.StorePaymentConfig;
|
|
|
+import shop.alien.entity.store.StoreUser;
|
|
|
import shop.alien.store.service.StorePaymentConfigCertService;
|
|
|
import shop.alien.store.service.StorePaymentConfigService;
|
|
|
+import shop.alien.store.service.StoreUserService;
|
|
|
import shop.alien.util.common.JwtUtil;
|
|
|
|
|
|
-import java.nio.charset.StandardCharsets;
|
|
|
import java.nio.file.Files;
|
|
|
import java.nio.file.Path;
|
|
|
import java.nio.file.Paths;
|
|
|
@@ -37,6 +38,7 @@ public class StorePaymentConfigController {
|
|
|
|
|
|
private final StorePaymentConfigService storePaymentConfigService;
|
|
|
private final StorePaymentConfigCertService storePaymentConfigCertService;
|
|
|
+ private final StoreUserService storeUserService;
|
|
|
|
|
|
@ApiOperationSupport(order = 1)
|
|
|
@ApiOperation("新增支付配置(JSON body)")
|
|
|
@@ -190,27 +192,27 @@ public class StorePaymentConfigController {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- /** 将表中三个证书内容写入指定目录,优先使用表存的文件名;UTF-8,返回已写入文件的绝对路径列表 */
|
|
|
+ /** 将表中三个证书内容(byte[] 原样)写入指定目录,不经过字符编码,返回已写入文件的绝对路径列表 */
|
|
|
private List<String> writeCertsToPath(StorePaymentConfig config, String targetPath) throws Exception {
|
|
|
Path dir = Paths.get(targetPath);
|
|
|
Files.createDirectories(dir);
|
|
|
List<String> written = new ArrayList<>();
|
|
|
- if (config.getAppPublicCert() != null && !config.getAppPublicCert().isEmpty()) {
|
|
|
+ if (config.getAppPublicCert() != null && config.getAppPublicCert().length > 0) {
|
|
|
String name = safeCertFileName(config.getAppPublicCertName(), "app_public.crt");
|
|
|
Path file = dir.resolve(name);
|
|
|
- Files.write(file, config.getAppPublicCert().getBytes(StandardCharsets.UTF_8));
|
|
|
+ Files.write(file, config.getAppPublicCert());
|
|
|
written.add(file.toAbsolutePath().toString());
|
|
|
}
|
|
|
- if (config.getAlipayPublicCert() != null && !config.getAlipayPublicCert().isEmpty()) {
|
|
|
+ if (config.getAlipayPublicCert() != null && config.getAlipayPublicCert().length > 0) {
|
|
|
String name = safeCertFileName(config.getAlipayPublicCertName(), "alipay_public.crt");
|
|
|
Path file = dir.resolve(name);
|
|
|
- Files.write(file, config.getAlipayPublicCert().getBytes(StandardCharsets.UTF_8));
|
|
|
+ Files.write(file, config.getAlipayPublicCert());
|
|
|
written.add(file.toAbsolutePath().toString());
|
|
|
}
|
|
|
- if (config.getAlipayRootCert() != null && !config.getAlipayRootCert().isEmpty()) {
|
|
|
+ if (config.getAlipayRootCert() != null && config.getAlipayRootCert().length > 0) {
|
|
|
String name = safeCertFileName(config.getAlipayRootCertName(), "alipay_root.crt");
|
|
|
Path file = dir.resolve(name);
|
|
|
- Files.write(file, config.getAlipayRootCert().getBytes(StandardCharsets.UTF_8));
|
|
|
+ Files.write(file, config.getAlipayRootCert());
|
|
|
written.add(file.toAbsolutePath().toString());
|
|
|
}
|
|
|
return written;
|
|
|
@@ -232,27 +234,27 @@ public class StorePaymentConfigController {
|
|
|
return name;
|
|
|
}
|
|
|
|
|
|
- /** 将三个证书文件内容及文件名读入实体(存入表) */
|
|
|
+ /** 将三个证书文件内容原样(byte[])读入实体存入表,不经过字符编码,保证存取一致 */
|
|
|
private void fillCertContent(StorePaymentConfig config,
|
|
|
MultipartFile appPublicCertFile,
|
|
|
MultipartFile alipayPublicCertFile,
|
|
|
MultipartFile alipayRootCertFile) throws Exception {
|
|
|
if (appPublicCertFile != null && !appPublicCertFile.isEmpty()) {
|
|
|
- config.setAppPublicCert(new String(appPublicCertFile.getBytes(), StandardCharsets.UTF_8));
|
|
|
+ config.setAppPublicCert(appPublicCertFile.getBytes());
|
|
|
String fn = appPublicCertFile.getOriginalFilename();
|
|
|
if (fn != null && !fn.trim().isEmpty()) {
|
|
|
config.setAppPublicCertName(fn.trim());
|
|
|
}
|
|
|
}
|
|
|
if (alipayPublicCertFile != null && !alipayPublicCertFile.isEmpty()) {
|
|
|
- config.setAlipayPublicCert(new String(alipayPublicCertFile.getBytes(), StandardCharsets.UTF_8));
|
|
|
+ config.setAlipayPublicCert(alipayPublicCertFile.getBytes());
|
|
|
String fn = alipayPublicCertFile.getOriginalFilename();
|
|
|
if (fn != null && !fn.trim().isEmpty()) {
|
|
|
config.setAlipayPublicCertName(fn.trim());
|
|
|
}
|
|
|
}
|
|
|
if (alipayRootCertFile != null && !alipayRootCertFile.isEmpty()) {
|
|
|
- config.setAlipayRootCert(new String(alipayRootCertFile.getBytes(), StandardCharsets.UTF_8));
|
|
|
+ config.setAlipayRootCert(alipayRootCertFile.getBytes());
|
|
|
String fn = alipayRootCertFile.getOriginalFilename();
|
|
|
if (fn != null && !fn.trim().isEmpty()) {
|
|
|
config.setAlipayRootCertName(fn.trim());
|
|
|
@@ -348,6 +350,150 @@ public class StorePaymentConfigController {
|
|
|
}
|
|
|
|
|
|
@ApiOperationSupport(order = 8)
|
|
|
+ @ApiOperation("根据店铺用户ID查询支付配置(设置收款账号)")
|
|
|
+ @ApiImplicitParam(name = "storeUserId", value = "店铺用户ID(store_user.id)", dataType = "int", paramType = "query", required = true)
|
|
|
+ @GetMapping("/getByStoreUserId")
|
|
|
+ public R<StorePaymentConfig> getByStoreUserId(@RequestParam Integer storeUserId) {
|
|
|
+ log.info("StorePaymentConfigController.getByStoreUserId storeUserId={}", storeUserId);
|
|
|
+ if (storeUserId == null) {
|
|
|
+ return R.fail("店铺用户ID不能为空");
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ StorePaymentConfig config = storePaymentConfigService.getByStoreUserId(storeUserId);
|
|
|
+ return R.data(config);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("根据店铺用户ID查询支付配置失败", e);
|
|
|
+ return R.fail("查询失败:" + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @ApiOperationSupport(order = 9)
|
|
|
+ @ApiOperation(value = "设置收款账号-保存微信", notes = "按 store_user_id 新增或更新微信支付参数及证书文件(内容存入表)")
|
|
|
+ @ApiImplicitParams({
|
|
|
+ @ApiImplicitParam(name = "storeUserId", value = "店铺用户ID(store_user.id)", dataType = "int", paramType = "form", required = true),
|
|
|
+ @ApiImplicitParam(name = "wechatMiniAppId", value = "微信支付mini appId", dataType = "string", paramType = "form"),
|
|
|
+ @ApiImplicitParam(name = "wechatAppId", value = "微信appId", dataType = "string", paramType = "form"),
|
|
|
+ @ApiImplicitParam(name = "wechatMchId", value = "微信mchId", dataType = "string", paramType = "form"),
|
|
|
+ @ApiImplicitParam(name = "merchantSerialNumber", value = "API证书序列号", dataType = "string", paramType = "form"),
|
|
|
+ @ApiImplicitParam(name = "apiV3Key", value = "APIv3 Key", dataType = "string", paramType = "form"),
|
|
|
+ @ApiImplicitParam(name = "wechatPayPublicKeyId", value = "支付公钥ID", dataType = "string", paramType = "form"),
|
|
|
+ @ApiImplicitParam(name = "wechatPrivateKeyFile", value = "私钥证书", dataType = "file", paramType = "form"),
|
|
|
+ @ApiImplicitParam(name = "wechatPayPublicKeyFile", value = "公钥证书", dataType = "file", paramType = "form")
|
|
|
+ })
|
|
|
+ @PostMapping("/saveWechatByStoreUserId")
|
|
|
+ public R<Integer> saveWechatByStoreUserId(
|
|
|
+ @RequestParam Integer storeUserId,
|
|
|
+ @RequestParam(required = false) String wechatMiniAppId,
|
|
|
+ @RequestParam(required = false) String wechatAppId,
|
|
|
+ @RequestParam(required = false) String wechatMchId,
|
|
|
+ @RequestParam(required = false) String merchantSerialNumber,
|
|
|
+ @RequestParam(required = false) String apiV3Key,
|
|
|
+ @RequestParam(required = false) String wechatPayPublicKeyId,
|
|
|
+ @RequestParam(value = "wechatPrivateKeyFile", required = false) MultipartFile wechatPrivateKeyFile,
|
|
|
+ @RequestParam(value = "wechatPayPublicKeyFile", required = false) MultipartFile wechatPayPublicKeyFile) {
|
|
|
+
|
|
|
+ log.info("StorePaymentConfigController.saveWechatByStoreUserId storeUserId={}", storeUserId);
|
|
|
+ if (storeUserId == null) {
|
|
|
+ return R.fail("店铺用户ID不能为空");
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ StoreUser storeUser = storeUserService.getById(storeUserId);
|
|
|
+ if (storeUser == null) {
|
|
|
+ return R.fail("店铺用户不存在");
|
|
|
+ }
|
|
|
+ StorePaymentConfig config = storePaymentConfigService.getByStoreUserId(storeUserId);
|
|
|
+ if (config == null) {
|
|
|
+ config = new StorePaymentConfig();
|
|
|
+ config.setStoreId(storeUser.getStoreId());
|
|
|
+ config.setStoreUserId(storeUserId);
|
|
|
+ config.setAppId(wechatAppId != null ? wechatAppId : "");
|
|
|
+ fillCreatedUser(config);
|
|
|
+ } else {
|
|
|
+ fillUpdatedUser(config);
|
|
|
+ }
|
|
|
+ config.setWechatMiniAppId(wechatMiniAppId);
|
|
|
+ config.setWechatAppId(wechatAppId);
|
|
|
+ config.setWechatMchId(wechatMchId);
|
|
|
+ config.setMerchantSerialNumber(merchantSerialNumber);
|
|
|
+ config.setApiV3Key(apiV3Key);
|
|
|
+ config.setWechatPayPublicKeyId(wechatPayPublicKeyId);
|
|
|
+ if (wechatPrivateKeyFile != null && !wechatPrivateKeyFile.isEmpty()) {
|
|
|
+ config.setWechatPrivateKeyFile(wechatPrivateKeyFile.getBytes());
|
|
|
+ String fn = wechatPrivateKeyFile.getOriginalFilename();
|
|
|
+ if (fn != null && !fn.trim().isEmpty()) {
|
|
|
+ config.setWechatPrivateKeyName(fn.trim());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (wechatPayPublicKeyFile != null && !wechatPayPublicKeyFile.isEmpty()) {
|
|
|
+ config.setWechatPayPublicKeyFile(wechatPayPublicKeyFile.getBytes());
|
|
|
+ String fn = wechatPayPublicKeyFile.getOriginalFilename();
|
|
|
+ if (fn != null && !fn.trim().isEmpty()) {
|
|
|
+ config.setWechatPayPublicKeyFileName(fn.trim());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ boolean ok = config.getId() == null ? storePaymentConfigService.save(config) : storePaymentConfigService.updateById(config);
|
|
|
+ if (!ok) {
|
|
|
+ return R.fail("保存失败");
|
|
|
+ }
|
|
|
+ return R.data(config.getId());
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("保存微信收款账号失败 storeUserId={}", storeUserId, e);
|
|
|
+ return R.fail("保存失败:" + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @ApiOperationSupport(order = 10)
|
|
|
+ @ApiOperation(value = "设置收款账号-保存支付宝", notes = "按 store_user_id 新增或更新支付宝支付参数及证书文件(内容存入表)")
|
|
|
+ @ApiImplicitParams({
|
|
|
+ @ApiImplicitParam(name = "storeUserId", value = "店铺用户ID(store_user.id)", dataType = "int", paramType = "form", required = true),
|
|
|
+ @ApiImplicitParam(name = "appId", value = "应用ID", dataType = "string", paramType = "form"),
|
|
|
+ @ApiImplicitParam(name = "appSecretCert", value = "应用私钥", dataType = "string", paramType = "form"),
|
|
|
+ @ApiImplicitParam(name = "appPublicCert", value = "应用公钥证书", dataType = "file", paramType = "form"),
|
|
|
+ @ApiImplicitParam(name = "alipayPublicCert", value = "支付宝公钥证书", dataType = "file", paramType = "form"),
|
|
|
+ @ApiImplicitParam(name = "alipayRootCert", value = "支付宝根证书", dataType = "file", paramType = "form")
|
|
|
+ })
|
|
|
+ @PostMapping("/saveAlipayByStoreUserId")
|
|
|
+ public R<Integer> saveAlipayByStoreUserId(
|
|
|
+ @RequestParam Integer storeUserId,
|
|
|
+ @RequestParam(required = false) String appId,
|
|
|
+ @RequestParam(required = false) String appSecretCert,
|
|
|
+ @RequestParam(value = "appPublicCert", required = false) MultipartFile appPublicCertFile,
|
|
|
+ @RequestParam(value = "alipayPublicCert", required = false) MultipartFile alipayPublicCertFile,
|
|
|
+ @RequestParam(value = "alipayRootCert", required = false) MultipartFile alipayRootCertFile) {
|
|
|
+ log.info("StorePaymentConfigController.saveAlipayByStoreUserId storeUserId={}", storeUserId);
|
|
|
+ if (storeUserId == null) {
|
|
|
+ return R.fail("店铺用户ID不能为空");
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ StoreUser storeUser = storeUserService.getById(storeUserId);
|
|
|
+ if (storeUser == null) {
|
|
|
+ return R.fail("店铺用户不存在");
|
|
|
+ }
|
|
|
+ StorePaymentConfig config = storePaymentConfigService.getByStoreUserId(storeUserId);
|
|
|
+ if (config == null) {
|
|
|
+ config = new StorePaymentConfig();
|
|
|
+ config.setStoreId(storeUser.getStoreId());
|
|
|
+ config.setStoreUserId(storeUserId);
|
|
|
+ config.setAppId(appId != null ? appId : "");
|
|
|
+ fillCreatedUser(config);
|
|
|
+ } else {
|
|
|
+ fillUpdatedUser(config);
|
|
|
+ }
|
|
|
+ config.setAppId(appId);
|
|
|
+ config.setAppSecretCert(appSecretCert);
|
|
|
+ fillCertContent(config, appPublicCertFile, alipayPublicCertFile, alipayRootCertFile);
|
|
|
+ boolean ok = config.getId() == null ? storePaymentConfigService.save(config) : storePaymentConfigService.updateById(config);
|
|
|
+ if (!ok) {
|
|
|
+ return R.fail("保存失败");
|
|
|
+ }
|
|
|
+ return R.data(config.getId());
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("保存支付宝收款账号失败 storeUserId={}", storeUserId, e);
|
|
|
+ return R.fail("保存失败:" + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @ApiOperationSupport(order = 12)
|
|
|
@ApiOperation("分页查询支付配置列表")
|
|
|
@ApiImplicitParams({
|
|
|
@ApiImplicitParam(name = "page", value = "页码", dataType = "Integer", paramType = "query", defaultValue = "1"),
|
|
|
@@ -372,7 +518,7 @@ public class StorePaymentConfigController {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- @ApiOperationSupport(order = 9)
|
|
|
+ @ApiOperationSupport(order = 13)
|
|
|
@ApiOperation(value = "新增/更新微信支付配置信息", notes = "按 storeId 查找配置,存在则更新微信字段;不存在则新建一条仅含 storeId 与微信信息的配置。可传表单+两个证书文件(内容存入表)。")
|
|
|
@ApiImplicitParams({
|
|
|
@ApiImplicitParam(name = "storeId", value = "店铺ID", dataType = "int", paramType = "form", required = true),
|
|
|
@@ -426,7 +572,7 @@ public class StorePaymentConfigController {
|
|
|
config.setWechatPayPublicKeyFilePath(wechatPayPublicKeyFilePath);
|
|
|
config.setWechatPayPublicKeyFileName(wechatPayPublicKeyFileName);
|
|
|
if (wechatPrivateKeyFile != null && !wechatPrivateKeyFile.isEmpty()) {
|
|
|
- config.setWechatPrivateKeyFile(new String(wechatPrivateKeyFile.getBytes(), StandardCharsets.UTF_8));
|
|
|
+ config.setWechatPrivateKeyFile(wechatPrivateKeyFile.getBytes());
|
|
|
if (wechatPrivateKeyName == null || wechatPrivateKeyName.trim().isEmpty()) {
|
|
|
String fn = wechatPrivateKeyFile.getOriginalFilename();
|
|
|
if (fn != null && !fn.trim().isEmpty()) {
|
|
|
@@ -435,7 +581,7 @@ public class StorePaymentConfigController {
|
|
|
}
|
|
|
}
|
|
|
if (wechatPayPublicKeyFile != null && !wechatPayPublicKeyFile.isEmpty()) {
|
|
|
- config.setWechatPayPublicKeyFile(new String(wechatPayPublicKeyFile.getBytes(), StandardCharsets.UTF_8));
|
|
|
+ config.setWechatPayPublicKeyFile(wechatPayPublicKeyFile.getBytes());
|
|
|
if (wechatPayPublicKeyFileName == null || wechatPayPublicKeyFileName.trim().isEmpty()) {
|
|
|
String fn = wechatPayPublicKeyFile.getOriginalFilename();
|
|
|
if (fn != null && !fn.trim().isEmpty()) {
|