|
|
@@ -0,0 +1,599 @@
|
|
|
+package shop.alien.store.controller;
|
|
|
+
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import com.baomidou.mybatisplus.core.metadata.IPage;
|
|
|
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
+import io.swagger.annotations.*;
|
|
|
+import lombok.RequiredArgsConstructor;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+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.StorePaymentConfigService;
|
|
|
+import shop.alien.store.service.StoreUserService;
|
|
|
+import shop.alien.util.common.JwtUtil;
|
|
|
+
|
|
|
+import java.nio.file.Files;
|
|
|
+import java.nio.file.Path;
|
|
|
+import java.nio.file.Paths;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.List;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 支付配置 前端控制器
|
|
|
+ *
|
|
|
+ * @author system
|
|
|
+ */
|
|
|
+@Slf4j
|
|
|
+@Api(tags = {"支付配置"})
|
|
|
+@ApiSort(18)
|
|
|
+@CrossOrigin
|
|
|
+@RestController
|
|
|
+@RequestMapping("/store/payment/config")
|
|
|
+@RequiredArgsConstructor
|
|
|
+public class StorePaymentConfigController {
|
|
|
+
|
|
|
+ private final StorePaymentConfigService storePaymentConfigService;
|
|
|
+ private final StoreUserService storeUserService;
|
|
|
+
|
|
|
+ @ApiOperationSupport(order = 1)
|
|
|
+ @ApiOperation("新增支付配置(JSON body)")
|
|
|
+ @PostMapping("/add")
|
|
|
+ public R<Boolean> add(@RequestBody StorePaymentConfig config) {
|
|
|
+ log.info("StorePaymentConfigController.add?config.storeId={}, appId={}", config.getStoreId(), config.getAppId());
|
|
|
+ if (config.getStoreId() == null) {
|
|
|
+ return R.fail("店铺ID不能为空");
|
|
|
+ }
|
|
|
+ if (config.getAppId() == null || config.getAppId().trim().isEmpty()) {
|
|
|
+ return R.fail("应用ID不能为空");
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ fillCreatedUser(config);
|
|
|
+ boolean ok = storePaymentConfigService.save(config);
|
|
|
+ return ok ? R.success("新增成功") : R.fail("新增失败");
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("新增支付配置失败", e);
|
|
|
+ return R.fail("新增失败:" + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @ApiOperationSupport(order = 2)
|
|
|
+ @ApiOperation("修改支付配置(JSON body)")
|
|
|
+ @PostMapping("/update")
|
|
|
+ public R<Boolean> update(@RequestBody StorePaymentConfig config) {
|
|
|
+ log.info("StorePaymentConfigController.update?id={}", config.getId());
|
|
|
+ if (config.getId() == null) {
|
|
|
+ return R.fail("配置ID不能为空");
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ fillUpdatedUser(config);
|
|
|
+ boolean ok = storePaymentConfigService.updateById(config);
|
|
|
+ return ok ? R.success("修改成功") : R.fail("修改失败");
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("修改支付配置失败", e);
|
|
|
+ return R.fail("修改失败:" + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @ApiOperationSupport(order = 2)
|
|
|
+ @ApiOperation(value = "新增支付配置(带三个证书文件,证书内容直接存入表 store_payment_config)", notes = "multipart:storeId、appId 必填;appSecretCert、*CertPath 选填;三个文件:appPublicCert、alipayPublicCert、alipayRootCert(.crt/.pem/.cer)")
|
|
|
+ @ApiImplicitParams({
|
|
|
+ @ApiImplicitParam(name = "storeId", value = "店铺ID", dataType = "int", paramType = "form", required = true),
|
|
|
+ @ApiImplicitParam(name = "appId", value = "应用ID", dataType = "string", paramType = "form", required = true),
|
|
|
+ @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("/addWithCerts")
|
|
|
+ public R<Boolean> addWithCerts(
|
|
|
+ @RequestParam Integer storeId,
|
|
|
+ @RequestParam String appId,
|
|
|
+ @RequestParam(required = false) String appSecretCert,
|
|
|
+ @RequestParam(required = false) String appPublicCertPath,
|
|
|
+ @RequestParam(required = false) String alipayPublicCertPath,
|
|
|
+ @RequestParam(required = false) String alipayRootCertPath,
|
|
|
+ @RequestParam(value = "appPublicCert", required = false) MultipartFile appPublicCertFile,
|
|
|
+ @RequestParam(value = "alipayPublicCert", required = false) MultipartFile alipayPublicCertFile,
|
|
|
+ @RequestParam(value = "alipayRootCert", required = false) MultipartFile alipayRootCertFile) {
|
|
|
+ log.info("StorePaymentConfigController.addWithCerts storeId={}, appId={}", storeId, appId);
|
|
|
+ if (storeId == null) {
|
|
|
+ return R.fail("店铺ID不能为空");
|
|
|
+ }
|
|
|
+ if (appId == null || appId.trim().isEmpty()) {
|
|
|
+ return R.fail("应用ID不能为空");
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ StorePaymentConfig config = new StorePaymentConfig();
|
|
|
+ config.setStoreId(storeId);
|
|
|
+ config.setAppId(appId.trim());
|
|
|
+ config.setAppSecretCert(appSecretCert);
|
|
|
+ config.setAppPublicCertPath(appPublicCertPath);
|
|
|
+ config.setAlipayPublicCertPath(alipayPublicCertPath);
|
|
|
+ config.setAlipayRootCertPath(alipayRootCertPath);
|
|
|
+ fillCertContent(config, appPublicCertFile, alipayPublicCertFile, alipayRootCertFile);
|
|
|
+ fillCreatedUser(config);
|
|
|
+ boolean ok = storePaymentConfigService.save(config);
|
|
|
+ return ok ? R.success("新增成功") : R.fail("新增失败");
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("新增支付配置(带证书)失败", e);
|
|
|
+ return R.fail("新增失败:" + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @ApiOperationSupport(order = 3)
|
|
|
+ @ApiOperation(value = "为已有配置上传/覆盖三个证书文件(内容存入表)", notes = "multipart:id 必填;三个文件:appPublicCert、alipayPublicCert、alipayRootCert,传哪个更新哪个")
|
|
|
+ @ApiImplicitParams({
|
|
|
+ @ApiImplicitParam(name = "id", value = "配置ID", dataType = "int", paramType = "form", required = true),
|
|
|
+ @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("/uploadCerts")
|
|
|
+ public R<Boolean> uploadCerts(
|
|
|
+ @RequestParam Integer id,
|
|
|
+ @RequestParam(value = "appPublicCert", required = false) MultipartFile appPublicCertFile,
|
|
|
+ @RequestParam(value = "alipayPublicCert", required = false) MultipartFile alipayPublicCertFile,
|
|
|
+ @RequestParam(value = "alipayRootCert", required = false) MultipartFile alipayRootCertFile) {
|
|
|
+ log.info("StorePaymentConfigController.uploadCerts id={}", id);
|
|
|
+ if (id == null) {
|
|
|
+ return R.fail("配置ID不能为空");
|
|
|
+ }
|
|
|
+ StorePaymentConfig existing = storePaymentConfigService.getById(id);
|
|
|
+ if (existing == null) {
|
|
|
+ return R.fail("配置不存在");
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ fillCertContent(existing, appPublicCertFile, alipayPublicCertFile, alipayRootCertFile);
|
|
|
+ fillUpdatedUser(existing);
|
|
|
+ boolean ok = storePaymentConfigService.updateById(existing);
|
|
|
+ return ok ? R.success("证书已更新") : R.fail("更新失败");
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("上传证书失败", e);
|
|
|
+ return R.fail("上传失败:" + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @ApiOperationSupport(order = 3)
|
|
|
+ @ApiOperation(value = "将三个证书文件写入指定路径", notes = "从表读出证书内容,写入 targetPath 目录;文件名优先使用表中的 *_cert_name,未设置则用默认 app_public.crt、alipay_public.crt、alipay_root.crt。")
|
|
|
+ @ApiImplicitParams({
|
|
|
+ @ApiImplicitParam(name = "id", value = "配置ID", dataType = "int", paramType = "query", required = true),
|
|
|
+ @ApiImplicitParam(name = "targetPath", value = "目标目录(绝对路径或相对路径),如 D:/certs/export 或 /opt/certs", dataType = "string", paramType = "query", required = true)
|
|
|
+ })
|
|
|
+ @GetMapping("/downloadCerts")
|
|
|
+ public R<List<String>> downloadCerts(@RequestParam Integer id, @RequestParam String targetPath) {
|
|
|
+ log.info("StorePaymentConfigController.downloadCerts id={}, targetPath={}", id, targetPath);
|
|
|
+ if (id == null) {
|
|
|
+ return R.fail("配置ID不能为空");
|
|
|
+ }
|
|
|
+ if (targetPath == null || targetPath.trim().isEmpty()) {
|
|
|
+ return R.fail("目标路径不能为空");
|
|
|
+ }
|
|
|
+ if (targetPath.contains("..")) {
|
|
|
+ return R.fail("目标路径不允许包含 ..");
|
|
|
+ }
|
|
|
+ StorePaymentConfig config = storePaymentConfigService.getById(id);
|
|
|
+ if (config == null) {
|
|
|
+ return R.fail("配置不存在");
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ List<String> writtenPaths = writeCertsToPath(config, targetPath.trim());
|
|
|
+ if (writtenPaths.isEmpty()) {
|
|
|
+ return R.fail("该配置下暂无证书内容可写入");
|
|
|
+ }
|
|
|
+ return R.data(writtenPaths);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("写入证书文件失败", e);
|
|
|
+ return R.fail("写入失败:" + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 将表中三个证书内容(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().length > 0) {
|
|
|
+ String name = safeCertFileName(config.getAppPublicCertName(), "app_public.crt");
|
|
|
+ Path file = dir.resolve(name);
|
|
|
+ Files.write(file, config.getAppPublicCert());
|
|
|
+ written.add(file.toAbsolutePath().toString());
|
|
|
+ }
|
|
|
+ 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());
|
|
|
+ written.add(file.toAbsolutePath().toString());
|
|
|
+ }
|
|
|
+ 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());
|
|
|
+ written.add(file.toAbsolutePath().toString());
|
|
|
+ }
|
|
|
+ return written;
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 使用表存的文件名(仅取最后一段且不含路径),非法则用默认名 */
|
|
|
+ private String safeCertFileName(String storedName, String defaultName) {
|
|
|
+ if (storedName == null || storedName.trim().isEmpty()) {
|
|
|
+ return defaultName;
|
|
|
+ }
|
|
|
+ String name = storedName.trim();
|
|
|
+ int last = Math.max(name.lastIndexOf('/'), name.lastIndexOf('\\'));
|
|
|
+ if (last >= 0 && last < name.length() - 1) {
|
|
|
+ name = name.substring(last + 1);
|
|
|
+ }
|
|
|
+ if (name.isEmpty() || name.contains("..")) {
|
|
|
+ return defaultName;
|
|
|
+ }
|
|
|
+ return name;
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 将三个证书文件内容原样(byte[])读入实体存入表,不经过字符编码,保证存取一致 */
|
|
|
+ private void fillCertContent(StorePaymentConfig config,
|
|
|
+ MultipartFile appPublicCertFile,
|
|
|
+ MultipartFile alipayPublicCertFile,
|
|
|
+ MultipartFile alipayRootCertFile) throws Exception {
|
|
|
+ if (appPublicCertFile != null && !appPublicCertFile.isEmpty()) {
|
|
|
+ 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(alipayPublicCertFile.getBytes());
|
|
|
+ String fn = alipayPublicCertFile.getOriginalFilename();
|
|
|
+ if (fn != null && !fn.trim().isEmpty()) {
|
|
|
+ config.setAlipayPublicCertName(fn.trim());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (alipayRootCertFile != null && !alipayRootCertFile.isEmpty()) {
|
|
|
+ config.setAlipayRootCert(alipayRootCertFile.getBytes());
|
|
|
+ String fn = alipayRootCertFile.getOriginalFilename();
|
|
|
+ if (fn != null && !fn.trim().isEmpty()) {
|
|
|
+ config.setAlipayRootCertName(fn.trim());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @ApiOperationSupport(order = 4)
|
|
|
+ @ApiOperation("删除支付配置")
|
|
|
+ @ApiImplicitParams({
|
|
|
+ @ApiImplicitParam(name = "id", value = "配置ID", dataType = "Integer", paramType = "query", required = true)
|
|
|
+ })
|
|
|
+ @PostMapping("/delete")
|
|
|
+ public R<Boolean> delete(@RequestParam Integer id) {
|
|
|
+ log.info("StorePaymentConfigController.delete?id={}", id);
|
|
|
+ if (id == null) {
|
|
|
+ return R.fail("配置ID不能为空");
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ boolean ok = storePaymentConfigService.removeById(id);
|
|
|
+ return ok ? R.success("删除成功") : R.fail("删除失败");
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("删除支付配置失败", e);
|
|
|
+ return R.fail("删除失败:" + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @ApiOperationSupport(order = 5)
|
|
|
+ @ApiOperation("根据ID查询支付配置详情")
|
|
|
+ @ApiImplicitParams({
|
|
|
+ @ApiImplicitParam(name = "id", value = "配置ID", dataType = "Integer", paramType = "query", required = true)
|
|
|
+ })
|
|
|
+ @GetMapping("/detail")
|
|
|
+ public R<StorePaymentConfig> detail(@RequestParam Integer id) {
|
|
|
+ log.info("StorePaymentConfigController.detail?id={}", id);
|
|
|
+ if (id == null) {
|
|
|
+ return R.fail("配置ID不能为空");
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ StorePaymentConfig config = storePaymentConfigService.getById(id);
|
|
|
+ if (config == null) {
|
|
|
+ return R.fail("配置不存在");
|
|
|
+ }
|
|
|
+ return R.data(config);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("查询支付配置详情失败", e);
|
|
|
+ return R.fail("查询失败:" + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @ApiOperationSupport(order = 7)
|
|
|
+ @ApiOperation("根据店铺ID查询支付配置")
|
|
|
+ @ApiImplicitParams({
|
|
|
+ @ApiImplicitParam(name = "storeId", value = "店铺ID", dataType = "Integer", paramType = "query", required = true)
|
|
|
+ })
|
|
|
+ @GetMapping("/getByStoreId")
|
|
|
+ public R<StorePaymentConfig> getByStoreId(@RequestParam Integer storeId) {
|
|
|
+ log.info("StorePaymentConfigController.getByStoreId?storeId={}", storeId);
|
|
|
+ if (storeId == null) {
|
|
|
+ return R.fail("店铺ID不能为空");
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ StorePaymentConfig config = storePaymentConfigService.getByStoreId(storeId);
|
|
|
+ if (config == null) {
|
|
|
+ return R.fail("该店铺暂无支付配置");
|
|
|
+ }
|
|
|
+ return R.data(config);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("根据店铺ID查询支付配置失败", e);
|
|
|
+ return R.fail("查询失败:" + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @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"),
|
|
|
+ @ApiImplicitParam(name = "size", value = "每页条数", dataType = "Integer", paramType = "query", defaultValue = "10"),
|
|
|
+ @ApiImplicitParam(name = "storeId", value = "店铺ID", dataType = "Integer", paramType = "query"),
|
|
|
+ @ApiImplicitParam(name = "appId", value = "应用ID(模糊)", dataType = "String", paramType = "query")
|
|
|
+ })
|
|
|
+ @GetMapping("/page")
|
|
|
+ public R<IPage<StorePaymentConfig>> page(
|
|
|
+ @RequestParam(defaultValue = "1") Integer page,
|
|
|
+ @RequestParam(defaultValue = "10") Integer size,
|
|
|
+ @RequestParam(required = false) Integer storeId,
|
|
|
+ @RequestParam(required = false) String appId) {
|
|
|
+ log.info("StorePaymentConfigController.page?page={}, size={}, storeId={}, appId={}", page, size, storeId, appId);
|
|
|
+ try {
|
|
|
+ Page<StorePaymentConfig> pageParam = new Page<>(page, size);
|
|
|
+ IPage<StorePaymentConfig> result = storePaymentConfigService.pageList(pageParam, storeId, appId);
|
|
|
+ return R.data(result);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("分页查询支付配置失败", e);
|
|
|
+ return R.fail("查询失败:" + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @ApiOperationSupport(order = 13)
|
|
|
+ @ApiOperation(value = "新增/更新微信支付配置信息", notes = "按 storeId 查找配置,存在则更新微信字段;不存在则新建一条仅含 storeId 与微信信息的配置。可传表单+两个证书文件(内容存入表)。")
|
|
|
+ @ApiImplicitParams({
|
|
|
+ @ApiImplicitParam(name = "storeId", value = "店铺ID", dataType = "int", paramType = "form", required = true),
|
|
|
+ @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 = "wechatPrivateKeyPath", value = "微信私钥路径", dataType = "string", paramType = "form"),
|
|
|
+ @ApiImplicitParam(name = "wechatPrivateKeyName", value = "微信私钥文件名", dataType = "string", paramType = "form"),
|
|
|
+ @ApiImplicitParam(name = "wechatPayPublicKeyFilePath", value = "微信公钥路径", dataType = "string", paramType = "form"),
|
|
|
+ @ApiImplicitParam(name = "wechatPayPublicKeyFileName", value = "微信公钥文件名", dataType = "string", paramType = "form"),
|
|
|
+ @ApiImplicitParam(name = "wechatPrivateKeyFile", value = "微信私钥文件(内容存入表)", dataType = "file", paramType = "form"),
|
|
|
+ @ApiImplicitParam(name = "wechatPayPublicKeyFile", value = "微信公钥文件(内容存入表)", dataType = "file", paramType = "form")
|
|
|
+ })
|
|
|
+ @PostMapping("/saveWechat")
|
|
|
+ public R<Boolean> saveWechat(
|
|
|
+ @RequestParam Integer storeId,
|
|
|
+ @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(required = false) String wechatPrivateKeyPath,
|
|
|
+ @RequestParam(required = false) String wechatPrivateKeyName,
|
|
|
+ @RequestParam(required = false) String wechatPayPublicKeyFilePath,
|
|
|
+ @RequestParam(required = false) String wechatPayPublicKeyFileName,
|
|
|
+ @RequestParam(value = "wechatPrivateKeyFile", required = false) MultipartFile wechatPrivateKeyFile,
|
|
|
+ @RequestParam(value = "wechatPayPublicKeyFile", required = false) MultipartFile wechatPayPublicKeyFile) {
|
|
|
+ log.info("StorePaymentConfigController.saveWechat storeId={}", storeId);
|
|
|
+ if (storeId == null) {
|
|
|
+ return R.fail("店铺ID不能为空");
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ StorePaymentConfig config = storePaymentConfigService.getByStoreId(storeId);
|
|
|
+ if (config == null) {
|
|
|
+ config = new StorePaymentConfig();
|
|
|
+ config.setStoreId(storeId);
|
|
|
+ config.setAppId(wechatAppId != null ? wechatAppId : "");
|
|
|
+ fillCreatedUser(config);
|
|
|
+ } else {
|
|
|
+ fillUpdatedUser(config);
|
|
|
+ }
|
|
|
+ config.setWechatAppId(wechatAppId);
|
|
|
+ config.setWechatMchId(wechatMchId);
|
|
|
+ config.setMerchantSerialNumber(merchantSerialNumber);
|
|
|
+ config.setApiV3Key(apiV3Key);
|
|
|
+ config.setWechatPayPublicKeyId(wechatPayPublicKeyId);
|
|
|
+ config.setWechatPrivateKeyPath(wechatPrivateKeyPath);
|
|
|
+ config.setWechatPrivateKeyName(wechatPrivateKeyName);
|
|
|
+ config.setWechatPayPublicKeyFilePath(wechatPayPublicKeyFilePath);
|
|
|
+ config.setWechatPayPublicKeyFileName(wechatPayPublicKeyFileName);
|
|
|
+ if (wechatPrivateKeyFile != null && !wechatPrivateKeyFile.isEmpty()) {
|
|
|
+ config.setWechatPrivateKeyFile(wechatPrivateKeyFile.getBytes());
|
|
|
+ if (wechatPrivateKeyName == null || wechatPrivateKeyName.trim().isEmpty()) {
|
|
|
+ String fn = wechatPrivateKeyFile.getOriginalFilename();
|
|
|
+ if (fn != null && !fn.trim().isEmpty()) {
|
|
|
+ config.setWechatPrivateKeyName(fn.trim());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (wechatPayPublicKeyFile != null && !wechatPayPublicKeyFile.isEmpty()) {
|
|
|
+ config.setWechatPayPublicKeyFile(wechatPayPublicKeyFile.getBytes());
|
|
|
+ if (wechatPayPublicKeyFileName == null || wechatPayPublicKeyFileName.trim().isEmpty()) {
|
|
|
+ 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);
|
|
|
+ return ok ? R.success("微信配置保存成功") : R.fail("保存失败");
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("保存微信支付配置失败", e);
|
|
|
+ return R.fail("保存失败:" + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void fillCreatedUser(StorePaymentConfig config) {
|
|
|
+ try {
|
|
|
+ JSONObject userInfo = JwtUtil.getCurrentUserInfo();
|
|
|
+ if (userInfo != null) {
|
|
|
+ config.setCreatedUserId(userInfo.getInteger("userId"));
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("获取当前用户失败: {}", e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void fillUpdatedUser(StorePaymentConfig config) {
|
|
|
+ try {
|
|
|
+ JSONObject userInfo = JwtUtil.getCurrentUserInfo();
|
|
|
+ if (userInfo != null) {
|
|
|
+ config.setUpdatedUserId(userInfo.getInteger("userId"));
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("获取当前用户失败: {}", e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|