|
|
@@ -1,154 +0,0 @@
|
|
|
-package shop.alien.store.config;
|
|
|
-
|
|
|
-import lombok.RequiredArgsConstructor;
|
|
|
-import lombok.extern.slf4j.Slf4j;
|
|
|
-import org.springframework.beans.factory.annotation.Value;
|
|
|
-import org.springframework.boot.ApplicationArguments;
|
|
|
-import org.springframework.boot.ApplicationRunner;
|
|
|
-import org.springframework.core.annotation.Order;
|
|
|
-import org.springframework.stereotype.Component;
|
|
|
-import org.springframework.util.StringUtils;
|
|
|
-import shop.alien.entity.store.StoreInfo;
|
|
|
-import shop.alien.entity.store.StorePaymentConfig;
|
|
|
-import shop.alien.store.service.StoreInfoService;
|
|
|
-import shop.alien.store.service.StorePaymentConfigService;
|
|
|
-
|
|
|
-import java.nio.file.Files;
|
|
|
-import java.nio.file.Path;
|
|
|
-import java.nio.file.Paths;
|
|
|
-import java.util.List;
|
|
|
-import java.util.regex.Pattern;
|
|
|
-
|
|
|
-/**
|
|
|
- * 项目启动时将 store_payment_config 中的证书内容写入本地目录,路径按店铺ID和店铺手机号区分。
|
|
|
- * 目录结构:{basePath}/{storeId}_{storeTel}/ 下存放各证书文件。
|
|
|
- *
|
|
|
- * @author system
|
|
|
- */
|
|
|
-@Slf4j
|
|
|
-@Component
|
|
|
-@Order(100)
|
|
|
-@RequiredArgsConstructor
|
|
|
-public class StorePaymentConfigCertInitRunner implements ApplicationRunner {
|
|
|
-
|
|
|
- private static final Pattern NON_ALNUM = Pattern.compile("[^0-9a-zA-Z]");
|
|
|
-
|
|
|
- /** 证书根目录,默认当前工作目录下的 payment-certs */
|
|
|
- @Value("${payment.cert.base-path:${user.dir}/payment-certs}")
|
|
|
- private String certBasePath;
|
|
|
-
|
|
|
- private final StorePaymentConfigService storePaymentConfigService;
|
|
|
- private final StoreInfoService storeInfoService;
|
|
|
-
|
|
|
- @Override
|
|
|
- public void run(ApplicationArguments args) {
|
|
|
- try {
|
|
|
- List<StorePaymentConfig> list = storePaymentConfigService.list();
|
|
|
- if (list == null || list.isEmpty()) {
|
|
|
- log.debug("store_payment_config 无配置,跳过证书落盘");
|
|
|
- return;
|
|
|
- }
|
|
|
- for (StorePaymentConfig config : list) {
|
|
|
- try {
|
|
|
- //todo 暂时注销掉
|
|
|
- //writeCertFilesForConfig(config);
|
|
|
- } catch (Exception e) {
|
|
|
- log.warn("店铺支付配置证书落盘失败 storeId={}", config.getStoreId(), e);
|
|
|
- }
|
|
|
- }
|
|
|
- } catch (Exception e) {
|
|
|
- log.error("支付配置证书初始化失败", e);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 为单条配置按 storeId + storeTel 建目录并写入证书文件,并将各证书的完整文件路径回写到 config 的路径字段。
|
|
|
- */
|
|
|
- protected void writeCertFilesForConfig(StorePaymentConfig config) throws Exception {
|
|
|
- Integer storeId = config.getStoreId();
|
|
|
- if (storeId == null) {
|
|
|
- return;
|
|
|
- }
|
|
|
- String storeTel = null;
|
|
|
- try {
|
|
|
- StoreInfo store = storeInfoService.getById(storeId);
|
|
|
- if (store != null && StringUtils.hasText(store.getStoreTel())) {
|
|
|
- storeTel = store.getStoreTel();
|
|
|
- }
|
|
|
- } catch (Exception e) {
|
|
|
- log.debug("获取店铺手机号失败 storeId={}", storeId, e);
|
|
|
- }
|
|
|
- String dirSegment = sanitizeDirSegment(storeTel);
|
|
|
- String storeDirName = storeId + "_" + dirSegment;
|
|
|
- Path baseDir = Paths.get(certBasePath).resolve(storeDirName);
|
|
|
- if (!Files.exists(baseDir)) {
|
|
|
- Files.createDirectories(baseDir);
|
|
|
- }
|
|
|
- String dirPath = baseDir.toAbsolutePath().toString();
|
|
|
-
|
|
|
- // 支付宝:应用公钥证书、支付宝公钥证书、根证书
|
|
|
- writeIfPresent(baseDir, config.getAppPublicCert(),
|
|
|
- defaultName(config.getAppPublicCertName(), "app_public_cert.crt"),
|
|
|
- (path, name) -> {
|
|
|
- config.setAppPublicCertPath(path);
|
|
|
- config.setAppPublicCertName(name);
|
|
|
- });
|
|
|
- writeIfPresent(baseDir, config.getAlipayPublicCert(),
|
|
|
- defaultName(config.getAlipayPublicCertName(), "alipay_public_cert.crt"),
|
|
|
- (path, name) -> {
|
|
|
- config.setAlipayPublicCertPath(path);
|
|
|
- config.setAlipayPublicCertName(name);
|
|
|
- });
|
|
|
- writeIfPresent(baseDir, config.getAlipayRootCert(),
|
|
|
- defaultName(config.getAlipayRootCertName(), "alipay_root_cert.crt"),
|
|
|
- (path, name) -> {
|
|
|
- config.setAlipayRootCertPath(path);
|
|
|
- config.setAlipayRootCertName(name);
|
|
|
- });
|
|
|
-
|
|
|
- // 微信:商户私钥、微信支付公钥
|
|
|
- writeIfPresent(baseDir, config.getWechatPrivateKeyFile(),
|
|
|
- defaultName(config.getWechatPrivateKeyName(), "wechat_private_key.pem"),
|
|
|
- (path, name) -> {
|
|
|
- config.setWechatPrivateKeyPath(path);
|
|
|
- config.setWechatPrivateKeyName(name);
|
|
|
- });
|
|
|
- writeIfPresent(baseDir, config.getWechatPayPublicKeyFile(),
|
|
|
- defaultName(config.getWechatPayPublicKeyFileName(), "wechat_public_key.pem"),
|
|
|
- (path, name) -> {
|
|
|
- config.setWechatPayPublicKeyFilePath(path);
|
|
|
- config.setWechatPayPublicKeyFileName(name);
|
|
|
- });
|
|
|
-
|
|
|
- storePaymentConfigService.updateById(config);
|
|
|
- log.info("店铺支付证书已落盘 storeId={}, dir={}", storeId, dirPath);
|
|
|
- }
|
|
|
-
|
|
|
- private static String sanitizeDirSegment(String storeTel) {
|
|
|
- if (!StringUtils.hasText(storeTel)) {
|
|
|
- return "no_tel";
|
|
|
- }
|
|
|
- return NON_ALNUM.matcher(storeTel.trim()).replaceAll("_");
|
|
|
- }
|
|
|
-
|
|
|
- private static String defaultName(String name, String defaultName) {
|
|
|
- return StringUtils.hasText(name) ? name.trim() : defaultName;
|
|
|
- }
|
|
|
-
|
|
|
- private interface PathUpdater {
|
|
|
- /** @param certFilePath 证书完整文件路径;@param fileName 文件名 */
|
|
|
- void set(String certFilePath, String fileName);
|
|
|
- }
|
|
|
-
|
|
|
- private void writeIfPresent(Path baseDir, byte[] content, String fileName, PathUpdater updater) throws Exception {
|
|
|
- if (content == null || content.length == 0) {
|
|
|
- return;
|
|
|
- }
|
|
|
- Path file = baseDir.resolve(fileName);
|
|
|
- Files.write(file, content);
|
|
|
- if (updater != null) {
|
|
|
- String certFilePath = file.toAbsolutePath().toString();
|
|
|
- updater.set(certFilePath, fileName);
|
|
|
- }
|
|
|
- }
|
|
|
-}
|