songguoqiang
6 months ago
7 changed files with 218 additions and 1 deletions
@ -0,0 +1,59 @@ |
|||
package com.win.module.eam.controller.licences; |
|||
|
|||
import cn.hutool.extra.qrcode.QrCodeUtil; |
|||
import com.win.framework.common.pojo.CommonResult; |
|||
import com.win.module.eam.controller.licences.vo.GenerateLicenceReqVO; |
|||
import com.win.module.eam.service.licences.LicencesService; |
|||
import io.swagger.v3.oas.annotations.Operation; |
|||
import io.swagger.v3.oas.annotations.Parameter; |
|||
import io.swagger.v3.oas.annotations.Parameters; |
|||
import io.swagger.v3.oas.annotations.tags.Tag; |
|||
import org.springframework.security.access.prepost.PreAuthorize; |
|||
import org.springframework.validation.annotation.Validated; |
|||
import org.springframework.web.bind.annotation.*; |
|||
import org.springframework.web.multipart.MultipartFile; |
|||
|
|||
import javax.annotation.Resource; |
|||
import javax.servlet.http.HttpServletResponse; |
|||
import javax.validation.Valid; |
|||
import javax.validation.constraints.NotNull; |
|||
import java.io.IOException; |
|||
|
|||
import static com.win.framework.common.pojo.CommonResult.success; |
|||
|
|||
@Tag(name = "接口-续期许可") |
|||
@RestController |
|||
@RequestMapping("/eam/basic/licences") |
|||
@Validated |
|||
public class LicencesController { |
|||
@Resource |
|||
private LicencesService licencesService; |
|||
|
|||
@PostMapping("/licenceDiscernByCodeFile") |
|||
@Operation(summary = "识别续期许可(二维码图片)") |
|||
@Parameters({ |
|||
@Parameter(name = "file", description = "续期二维码图片", required = true) |
|||
}) |
|||
@PreAuthorize("@ss.hasPermission('basic:licences:licenceDiscern')") |
|||
public CommonResult<Boolean> licenceDiscernByCodeFile(@Valid @NotNull @RequestParam("file") MultipartFile file) throws IOException { |
|||
licencesService.licencesDiscern(QrCodeUtil.decode(file.getInputStream())); |
|||
return success(true); |
|||
} |
|||
|
|||
@PostMapping("/licenceDiscernByCodeStr") |
|||
@Operation(summary = "识别续期许可(二维码字符串)") |
|||
@Parameters({ |
|||
@Parameter(name = "code", description = "续期二维码识别出来的字符串", required = true) |
|||
}) |
|||
@PreAuthorize("@ss.hasPermission('basic:licences:licenceDiscern')") |
|||
public CommonResult<Boolean> licenceDiscernByCodeStr(@RequestBody String code) { |
|||
licencesService.licencesDiscern(code); |
|||
return success(true); |
|||
} |
|||
@PostMapping("/generateLicence") |
|||
@Operation(summary = "生成续期二维码") |
|||
@PreAuthorize("@ss.hasPermission('basic:licences:licenceDiscern')") |
|||
public void generateLicence(@Valid @RequestBody GenerateLicenceReqVO req,HttpServletResponse response) throws Exception { |
|||
licencesService.generateLicence(req,response); |
|||
} |
|||
} |
@ -0,0 +1,20 @@ |
|||
package com.win.module.eam.controller.licences.vo; |
|||
|
|||
import io.swagger.v3.oas.annotations.media.Schema; |
|||
import lombok.Data; |
|||
import lombok.ToString; |
|||
|
|||
import javax.validation.constraints.NotNull; |
|||
|
|||
@Schema(description = "管理后台 - 生成续期码 Request VO") |
|||
@Data |
|||
@ToString(callSuper = true) |
|||
public class GenerateLicenceReqVO { |
|||
@NotNull(message = "公司编码不能为空") |
|||
@Schema(description = "公司编码") |
|||
private String companyCode; |
|||
|
|||
@NotNull(message = "到期时间不能为空") |
|||
@Schema(description = "到期时间") |
|||
private String endTime; |
|||
} |
@ -0,0 +1,13 @@ |
|||
package com.win.module.eam.mq.message; |
|||
|
|||
import lombok.Data; |
|||
import lombok.ToString; |
|||
|
|||
import java.util.List; |
|||
|
|||
@Data |
|||
@ToString(callSuper = true) |
|||
public class LicencesMessage { |
|||
private String secretKey; |
|||
private String data; |
|||
} |
@ -0,0 +1,11 @@ |
|||
package com.win.module.eam.service.licences; |
|||
|
|||
import com.win.module.eam.controller.licences.vo.GenerateLicenceReqVO; |
|||
|
|||
import javax.servlet.http.HttpServletResponse; |
|||
import javax.validation.Valid; |
|||
|
|||
public interface LicencesService { |
|||
void licencesDiscern(String encryptionStr); |
|||
void generateLicence(@Valid GenerateLicenceReqVO req, HttpServletResponse response) throws Exception; |
|||
} |
@ -0,0 +1,108 @@ |
|||
package com.win.module.eam.service.licences; |
|||
|
|||
import cn.hutool.core.codec.Base64; |
|||
import cn.hutool.crypto.digest.MD5; |
|||
import cn.hutool.extra.qrcode.QrCodeUtil; |
|||
import cn.hutool.extra.qrcode.QrConfig; |
|||
import com.alibaba.excel.metadata.data.ImageData; |
|||
import com.alibaba.fastjson.JSONArray; |
|||
import com.alibaba.fastjson.JSONObject; |
|||
import com.win.module.eam.controller.licences.vo.GenerateLicenceReqVO; |
|||
import com.win.module.eam.mq.message.LicencesMessage; |
|||
import org.apache.calcite.util.Util; |
|||
import org.springframework.data.redis.core.RedisTemplate; |
|||
import org.springframework.stereotype.Service; |
|||
|
|||
import javax.annotation.Resource; |
|||
import javax.crypto.Cipher; |
|||
import javax.crypto.KeyGenerator; |
|||
import javax.crypto.SecretKey; |
|||
import javax.crypto.spec.SecretKeySpec; |
|||
import javax.servlet.http.HttpServletResponse; |
|||
import java.nio.charset.StandardCharsets; |
|||
import java.util.ArrayList; |
|||
import java.util.List; |
|||
|
|||
import static com.win.framework.common.exception.util.ServiceExceptionUtil.exception; |
|||
import static com.win.module.eam.enums.ErrorCodeConstants.ENCRYPTION_STR_FORMAT_IS_ERROR; |
|||
|
|||
@Service |
|||
public class LicencesServiceImpl implements LicencesService { |
|||
private static final String ALGORITHM = "AES"; |
|||
private static final int KEY_SIZE = 128; |
|||
private static final String LICENCES_UPDATE = "LICENCES"; |
|||
@Resource |
|||
private RedisTemplate<String, String> redisTemplate; |
|||
|
|||
private static String generateKey() throws Exception { |
|||
KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM); |
|||
keyGenerator.init(KEY_SIZE); |
|||
SecretKey secretKey = keyGenerator.generateKey(); |
|||
return Base64.encode(secretKey.getEncoded()); |
|||
} |
|||
|
|||
private static String encrypt(String data, String key) throws Exception { |
|||
SecretKeySpec secretKeySpec = new SecretKeySpec(Base64.decode(key), ALGORITHM); |
|||
Cipher cipher = Cipher.getInstance(ALGORITHM); |
|||
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec); |
|||
byte[] encryptedBytes = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8)); |
|||
return Base64.encode(encryptedBytes); |
|||
} |
|||
|
|||
private static String decrypt(String encryptedData, String key) throws Exception { |
|||
SecretKeySpec secretKeySpec = new SecretKeySpec(Base64.decode(key), ALGORITHM); |
|||
Cipher cipher = Cipher.getInstance(ALGORITHM); |
|||
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec); |
|||
byte[] decryptedBytes = cipher.doFinal(Base64.decode(encryptedData)); |
|||
return new String(decryptedBytes, StandardCharsets.UTF_8); |
|||
} |
|||
|
|||
@Override |
|||
public void licencesDiscern(String encryptionStr) { |
|||
if (Util.isNullOrEmpty(encryptionStr)) { |
|||
throw exception(ENCRYPTION_STR_FORMAT_IS_ERROR); |
|||
} |
|||
try { |
|||
//todo 数据校验
|
|||
JSONObject codeJson = JSONObject.parseObject(encryptionStr); |
|||
String secretKey = codeJson.getString("secretKey"); |
|||
if (Util.isNullOrEmpty(secretKey)) { |
|||
throw exception(ENCRYPTION_STR_FORMAT_IS_ERROR); |
|||
} |
|||
String dataStr = codeJson.getString("data"); |
|||
if (Util.isNullOrEmpty(dataStr)) { |
|||
throw exception(ENCRYPTION_STR_FORMAT_IS_ERROR); |
|||
} |
|||
JSONArray dataJson = JSONArray.parseArray(decrypt(dataStr, secretKey)); |
|||
if (dataJson.isEmpty()) { |
|||
throw exception(ENCRYPTION_STR_FORMAT_IS_ERROR); |
|||
} |
|||
//todo 更新到redis并使用发布订阅通知其他pods
|
|||
redisTemplate.opsForValue().set(LICENCES_UPDATE, dataJson.toJSONString()); |
|||
redisTemplate.convertAndSend(LICENCES_UPDATE, 1); |
|||
} catch (Exception e) { |
|||
throw exception(500, e); |
|||
} |
|||
} |
|||
|
|||
@Override |
|||
public void generateLicence(GenerateLicenceReqVO req, HttpServletResponse response) throws Exception { |
|||
LicencesMessage licencesMessage = new LicencesMessage() {{ |
|||
String secretKey = generateKey(); |
|||
setSecretKey(secretKey); |
|||
List data = new ArrayList(); |
|||
MD5 md5 = MD5.create(); |
|||
data.add(new JSONObject(){{ |
|||
put(md5.digestHex("/MES"),encrypt("2025-10-10 00:00:00",secretKey)); |
|||
}}.toJSONString()); |
|||
data.add(new JSONObject(){{ |
|||
put(md5.digestHex("/WMS"),encrypt("2025-10-10 00:00:00",secretKey)); |
|||
}}.toJSONString()); |
|||
setData(encrypt(JSONObject.toJSONString(data),secretKey)); |
|||
}}; |
|||
QrConfig config = new QrConfig(300, 300); |
|||
config.setErrorCorrection(com.google.zxing.qrcode.decoder.ErrorCorrectionLevel.M); // 设置纠错级别
|
|||
// 或者直接输出到流
|
|||
QrCodeUtil.generate(JSONObject.toJSONString(licencesMessage), config, ImageData.ImageType.PICTURE_TYPE_DIB.name(), response.getOutputStream()); |
|||
} |
|||
} |
Loading…
Reference in new issue