Commit c1117586 authored by 霍传世's avatar 霍传世

HaiNa---接口

parent b8dbfb9f
......@@ -34,38 +34,54 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20250107</version> <!-- 使用最新版本 -->
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.qcloud</groupId>
<artifactId>cos_api</artifactId>
<version>5.6.97</version>
</dependency>
<dependency>
<groupId>com.qcloud</groupId>
<artifactId>cos-sts_api</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.3</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
......@@ -94,5 +110,4 @@
</releases>
</pluginRepository>
</pluginRepositories>
</project>
......@@ -2,8 +2,10 @@ package com.yuda.hainafacetofaceai;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
@SpringBootApplication
@EnableAsync
public class HaiNaFaceToFaceAiApplication {
public static void main(String[] args) {
......
......@@ -12,15 +12,14 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@Component
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {
@Autowired
private StringRedisTemplate redisTemplate;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
log.info("登录拦截认证");
......@@ -29,8 +28,10 @@ public class LoginInterceptor implements HandlerInterceptor {
String value = redisTemplate.opsForValue().get(key);
JSONObject jsonObject = new JSONObject(value);
String zkzNum = jsonObject.get("zkzNum").toString();
log.info("学号"+zkzNum+"->"+"登录");
redisTemplate.opsForValue().set(key,value);
String idCard = jsonObject.get("idCard").toString();
String examConnectionCode = jsonObject.get("examConnectionCode").toString();
log.info("准考证号:"+zkzNum+"_身份证号:"+idCard+"_参加面试编号:"+examConnectionCode+"_登入");
redisTemplate.opsForValue().set(key,value,60*60*2, TimeUnit.SECONDS);
return true;
}else{
response.setContentType("application/json");
......@@ -44,12 +45,9 @@ public class LoginInterceptor implements HandlerInterceptor {
return false;
}
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
......
package com.yuda.hainafacetofaceai.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ExcelColumn {
String headerName(); // 表头名称,用于匹配Excel表头
}
package com.yuda.hainafacetofaceai.config;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.http.HttpProtocol;
import com.qcloud.cos.region.Region;
import com.yuda.hainafacetofaceai.constant.CosConstant;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class CosConfig {
@Bean("cosClient")
public COSClient cosClient() {
COSCredentials cred = new BasicCOSCredentials(CosConstant.COS_AccesskeyID, CosConstant.COS_AccesskeySECRET);
Region region = new Region(CosConstant.COS_ENDPOINT);
ClientConfig clientConfig = new ClientConfig(region);
clientConfig.setHttpProtocol(HttpProtocol.https);
return new COSClient(cred, clientConfig);
}
}
package com.yuda.hainafacetofaceai.constant;
public class CosConstant {
public static final String COS_ENDPOINT = "ap-beijing";
public static final String COS_AccesskeyID = "AKID61zliQDpBOgqALHvLl25sRmvnV9cohPt";
public static final String COS_AccesskeySECRET = "TkqtgCUaYJhx1rTpztY2LQRO9h2pPmun";
public static final String COS_BUCKET = "schoolreportpdf-1317275686";
}
package com.yuda.hainafacetofaceai.controller;
import lombok.extern.slf4j.Slf4j;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/commitmentLetterApi")
@Slf4j
public class CommitmentLetterController {
@Autowired
private JdbcTemplate DBOperator;
@PostMapping("/uploadLetter/{examConnectionCode}/{zkzNum}")
public ResponseEntity upLoadCommitmentLetter(@PathVariable String examConnectionCode,@PathVariable String zkzNum,@RequestBody String url){
try{
DBOperator.update("UPDATE candidate_exam \n" +
"SET image_commitment = ? \n" +
"AND status_commitment = 1 \n" +
"WHERE\n" +
"\tzkz_num = ? \n" +
"\tAND exam_connection_code = ?",new Object[]{url,zkzNum,examConnectionCode});
log.info("准考证:"+zkzNum+"参加面试编号:"+examConnectionCode+"上传承诺书成功");
JSONObject responseBody = new JSONObject();
responseBody.put("code",200);
responseBody.put("message","承诺书上传成功");
return ResponseEntity.ok(responseBody.toString());
}catch (Exception e){
log.info("准考证:"+zkzNum+"参加面试编号:"+examConnectionCode+"上传承诺书失败");
JSONObject responseBody = new JSONObject();
responseBody.put("code",500);
responseBody.put("message","承诺书上传失败");
return ResponseEntity.badRequest().body(responseBody);
}
}
}
package com.yuda.hainafacetofaceai.controller;
import com.yuda.hainafacetofaceai.util.BaiDuFaceMatchUtil;
import lombok.extern.slf4j.Slf4j;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/faceMatchApi")
@Slf4j
public class FaceMatchController {
@Autowired
private JdbcTemplate DBOperator;
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Autowired
private BaiDuFaceMatchUtil faceMatch;
@PostMapping("/uploadFacePic/{examConnectionCode}/{zkzNum}")
public ResponseEntity examFacePicUpload(@PathVariable String examConnectionCode, @PathVariable String zkzNum, @RequestBody String images){
JSONObject object = new JSONObject(images);
String faceImage = object.getString("zjImage");
try{
DBOperator.update("update candidate_exam set exam_image_face = ? where zkz_num = ? and exam_connection_code = ?",new Object[]{faceImage,zkzNum,examConnectionCode});
log.info("准考证:"+zkzNum+"参加面试编号:"+examConnectionCode+"上传实时人脸照片成功");
JSONObject responseBody = new JSONObject();
responseBody.put("code",200);
responseBody.put("message","上传成功");
return ResponseEntity.ok(responseBody);
}catch (Exception e){
log.info("准考证:"+zkzNum+"参加面试编号:"+examConnectionCode+"上传实时人脸照片失败");
JSONObject responseBody = new JSONObject();
responseBody.put("code",500);
responseBody.put("message","上传人脸照片失败");
return ResponseEntity.badRequest().body(new JSONObject().toString());
}
}
@PostMapping("/faceMatch/{examConnectionCode}/{idCard}/{zkzNum}")
public ResponseEntity faceMatch(@PathVariable String idCard,@PathVariable String examConnectionCode,@PathVariable String zkzNum,@RequestParam("picName") String picName){
log.info("faceMatch正在校验-》身份证号:"+idCard+"参加面试编号:"+examConnectionCode+"_人脸照片");
String message = "";
if(check(examConnectionCode,idCard,message)){
JSONObject responseBody = new JSONObject();
responseBody.put("code",500);
responseBody.put("message",message);
return ResponseEntity.badRequest().body(responseBody);
}
String[] result = faceMatch.faceMatchBaidu(idCard,picName);
if(result[0].equals("1")){
stringRedisTemplate.opsForValue().increment("face_success:" + examConnectionCode + "_" + idCard);
DBOperator.update("update candidate_exam set status_face = 1 where exam_connection_code = ? and zkz_num = ?",new Object[]{examConnectionCode,zkzNum});
log.info("身份证:"+idCard+"参加面试编号:"+examConnectionCode+"人脸验证成功");
}else{
stringRedisTemplate.opsForValue().increment("face_error:" + examConnectionCode + "_" + idCard);
log.info("身份证:"+idCard+"参加面试编号:"+examConnectionCode+"人脸验证失败");
}
JSONObject responseBody = new JSONObject();
responseBody.put("code",200);
responseBody.put("message","校验成功");
return ResponseEntity.ok(responseBody.toString());
}
private boolean check(String examConnectionCode, String idCard,String message) {
String success = stringRedisTemplate.opsForValue().get("face_success:" + examConnectionCode + "_" + idCard);
if (!StringUtils.isEmpty(success)) {
if (Integer.parseInt(success) >= 1) {
message = "请勿重复提交";
return true;
}
}
String s = stringRedisTemplate.opsForValue().get("face_error:" + examConnectionCode + "_" + idCard);
if (!StringUtils.isEmpty(s)) {
if (Integer.parseInt(s) >=3) {
message = "失败次数超3次";
return true;
}
}
return false;
}
}
package com.yuda.hainafacetofaceai.controller;
import com.yuda.hainafacetofaceai.entity.ExamStudent;
import com.yuda.hainafacetofaceai.util.AppUtil;
import com.yuda.hainafacetofaceai.entity.CandidateExam;
import lombok.extern.slf4j.Slf4j;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
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 java.util.concurrent.TimeUnit;
@RestController
@RequestMapping("/login")
@Slf4j
public class LoginController {
@Autowired
private StringRedisTemplate redisTemplate;
@Autowired
private AppUtil appUtil;
private JdbcTemplate DBOperator;
@PostMapping
public ResponseEntity LoginGo(@RequestBody ExamStudent examStudent){
if(examStudent.getZkzNum().equals("111")&&examStudent.getIdCard().equals("111")){
redisTemplate.opsForValue().set("51096606163",new JSONObject(examStudent).toString(),2*60*60, TimeUnit.SECONDS);
JSONObject jsonObject = new JSONObject();
jsonObject.put("Token","51096606163");
jsonObject.put("code",200);
jsonObject.put("message","登录成功");
return ResponseEntity.ok(jsonObject.toString());
}
if(examStudent.getZkzNum().equals("222")&&examStudent.getIdCard().equals("222")){
redisTemplate.opsForValue().set("51069292339",new JSONObject(examStudent).toString(),2*60*60, TimeUnit.SECONDS);
JSONObject jsonObject = new JSONObject();
jsonObject.put("Token","51069292339");
jsonObject.put("code",200);
jsonObject.put("message","登录成功");
return ResponseEntity.ok(jsonObject.toString());
}
if(examStudent.getZkzNum().equals("333")&&examStudent.getIdCard().equals("333")){
redisTemplate.opsForValue().set("51027367515",new JSONObject(examStudent).toString(),2*60*60, TimeUnit.SECONDS);
JSONObject jsonObject = new JSONObject();
jsonObject.put("Token","51027367515");
jsonObject.put("code",200);
jsonObject.put("message","登录成功");
return ResponseEntity.ok(jsonObject.toString());
}
if(examStudent.getZkzNum().equals("444")&&examStudent.getIdCard().equals("444")){
redisTemplate.opsForValue().set("51010817155",new JSONObject(examStudent).toString(),2*60*60, TimeUnit.SECONDS);
JSONObject jsonObject = new JSONObject();
jsonObject.put("Token","51010817155");
jsonObject.put("code",200);
jsonObject.put("message","登录成功");
return ResponseEntity.ok(jsonObject.toString());
}
if(examStudent.getZkzNum().equals("555")&&examStudent.getIdCard().equals("555")){
redisTemplate.opsForValue().set("51021560057",new JSONObject(examStudent).toString(),2*60*60, TimeUnit.SECONDS);
JSONObject jsonObject = new JSONObject();
jsonObject.put("Token","51021560057");
jsonObject.put("code",200);
jsonObject.put("message","登录成功");
return ResponseEntity.ok(jsonObject.toString());
}
if(examStudent.getZkzNum().equals("666")&&examStudent.getIdCard().equals("666")){
redisTemplate.opsForValue().set("51007580358",new JSONObject(examStudent).toString(),2*60*60, TimeUnit.SECONDS);
JSONObject jsonObject = new JSONObject();
jsonObject.put("Token","51007580358");
jsonObject.put("code",200);
jsonObject.put("message","登录成功");
return ResponseEntity.ok(jsonObject.toString());
public ResponseEntity LoginGo(@RequestBody CandidateExam candidate){
try{
CandidateExam candidateExam = DBOperator.queryForObject("SELECT \n" +
"\ta.uuid, \n" +
"\tb.NAME, \n" +
"\ta.zkz_num, \n" +
"\tb.id_card, \n" +
"\ta.exam_connection_code, \n" +
"\ta.candidate_connect_code \n" +
"FROM\n" +
"\tcandidate_exam a join \n" +
"\tcandidate b on a.id_card = b.id_card \n" +
"WHERE\n" +
"\tb.id_card = ? \n" +
"\tAND a.zkz_num = ? ",new Object[]{candidate.getIdCard(),candidate.getZkzNum()},new BeanPropertyRowMapper<>(CandidateExam.class));
redisTemplate.opsForValue().set(candidateExam.getCandidateConnectCode(),new JSONObject(candidateExam).toString());
JSONObject responseData = new JSONObject();
responseData.put("Token",candidateExam.getCandidateConnectCode());
responseData.put("code",200);
responseData.put("message","登录成功");
return ResponseEntity.ok(responseData.toString());
}catch (EmptyResultDataAccessException e){
log.info("准考证号:"+candidate.getZkzNum()+"_身份证号:"+candidate.getIdCard()+"_参加面试编号:"+candidate.getExamConnectionCode()+"_查询结果=>无面试者记录");
}
JSONObject jsonObject = new JSONObject();
jsonObject.put("code",500);
......
package com.yuda.hainafacetofaceai.controller;
import com.yuda.hainafacetofaceai.constant.CosConstant;
import com.yuda.hainafacetofaceai.util.CosUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/publicApi")
public class PublicFunctionController {
@Autowired
private CosUtil cosUtil;
@RequestMapping("/getWebCosSign")
public ResponseEntity getWebCosTempSign() throws Exception {
String tempSignBody = cosUtil.getSignatureForWeb(CosConstant.COS_BUCKET,CosConstant.COS_ENDPOINT);
return ResponseEntity.ok(tempSignBody);
}
}
package com.yuda.hainafacetofaceai.controller;
import com.yuda.hainafacetofaceai.constant.AppThirdPartUrls;
import com.yuda.hainafacetofaceai.entity.CandidateCreateQuery;
import com.yuda.hainafacetofaceai.entity.CandidateExam;
import com.yuda.hainafacetofaceai.service.impl.ScriptInterfaceServiceImpl;
import com.yuda.hainafacetofaceai.util.AppUtil;
import com.yuda.hainafacetofaceai.util.ExcelUtil;
import com.yuda.hainafacetofaceai.util.RandomNumberUtil;
import lombok.extern.slf4j.Slf4j;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
import java.util.UUID;
@RestController
@RequestMapping("/scripts")
@Slf4j
public class ScriptInterfaceController {
@Autowired
private RandomNumberUtil randomNumberUtil;
@Autowired
private RestTemplate restTemplate;
@Autowired
private AppUtil appUtil;
@Autowired
private ScriptInterfaceServiceImpl scriptInterfaceService;
@Autowired
private JdbcTemplate DBOperator;
@PostMapping("/batchGenCandidatesOftest")
@Transactional
public ResponseEntity batchGenTest(@RequestParam("examConnectionCode")String examConnectionCode){
for (int i = 0; i < 10; i++) {
String uuid = UUID.randomUUID().toString().replace("-","");
HttpHeaders headers = new HttpHeaders();
headers.set("Content-Type","application/json");
CandidateCreateQuery candidateCreateQuery = new CandidateCreateQuery();
candidateCreateQuery.setOutId(uuid);
candidateCreateQuery.setRepeatVersion("0");
candidateCreateQuery.setExamConnectCode(examConnectionCode);
candidateCreateQuery.setPhone(randomNumberUtil.generateRandomPhoneNumber());
candidateCreateQuery.setShowName(randomNumberUtil.generateRandomChineseNickname());
JSONObject requestBodyObject = new JSONObject(candidateCreateQuery);
HttpEntity<String> entity = new HttpEntity<>(requestBodyObject.toString(),headers);
ResponseEntity<String> response = restTemplate.exchange(
appUtil.ApiUrlGen(AppThirdPartUrls.candidateCreate),
HttpMethod.POST,
entity,
String.class
);
JSONObject object = new JSONObject(response.getBody());
//操作库
log.info("添加成功");
}
return ResponseEntity.ok("");
}
@PostMapping("/{examConnectionCode}")
public ResponseEntity importCandidates(@PathVariable String examConnectionCode, @RequestParam(value = "file") MultipartFile file) {
ExcelUtil<CandidateExam> excelUtil = new ExcelUtil<>();
List<CandidateExam> candidateExamList = null ;
try{
candidateExamList = (excelUtil).parseExcel(file.getInputStream(),CandidateExam.class);
}catch (Exception e){
log.info("候选导表解析失败");
JSONObject bodyResponse = new JSONObject();
bodyResponse.put("code",500);
bodyResponse.put("message","导入失败");
return ResponseEntity.ok(bodyResponse);
}
if(candidateExamList!=null&&candidateExamList.size()>0){
boolean success = scriptInterfaceService.BatchInsert(candidateExamList,examConnectionCode);
if(!success){
JSONObject bodyResponse = new JSONObject();
bodyResponse.put("code",500);
bodyResponse.put("message","导入失败");
return ResponseEntity.ok(bodyResponse);
}
}
JSONObject bodyResponse = new JSONObject();
bodyResponse.put("code",200);
bodyResponse.put("message","导入成功");
return ResponseEntity.ok("");
}
@PostMapping("/genCandidateConnectionCode")
public ResponseEntity genCandidateCode(@RequestParam("candidateConnectionCode")String candidateConnectionCode){
try{
List<CandidateExam> candidateExamList = DBOperator.queryForList("select\n" +
"a.phone, \n" +
"b.uuid,\n" +
"b.exam_connection_code\n" +
"from \n" +
"candidate_exam a \n" +
"left join\n" +
"candidate b on a.id_card = b.id_card\n" +
"where\n" +
"a.exam_connection_code = ?\n" +
"and \n" +
"a.candidate_connect_code is not null",new Object[]{candidateConnectionCode},CandidateExam.class);
if(candidateExamList.size()!=0){
for (CandidateExam candidateExam : candidateExamList) {
scriptInterfaceService.sendRequestAndSaveDB(candidateExam);
}
}
}catch (EmptyResultDataAccessException e){
log.info("面试编号"+candidateConnectionCode+"暂无候选者");
}
JSONObject requestData = new JSONObject();
requestData.put("code",200);
requestData.put("message","指令发送成功");
return ResponseEntity.ok(requestData);
}
}
......@@ -48,12 +48,12 @@ public class businessController {
HttpHeaders headers = new HttpHeaders();
headers.set("Content-Type","application/json");
JSONObject requestBodyObject = new JSONObject(candidateCreateQuery);
HttpEntity<JSONObject> entity = new HttpEntity<>(requestBodyObject,headers);
ResponseEntity<JSONObject> response = restTemplate.exchange(
HttpEntity<String> entity = new HttpEntity<>(requestBodyObject.toString(),headers);
ResponseEntity<String> response = restTemplate.exchange(
appUtil.ApiUrlGen(AppThirdPartUrls.candidateCreate),
HttpMethod.POST,
entity,
JSONObject.class
String.class
);
return ResponseEntity.ok(response.getBody());
}
......@@ -103,7 +103,4 @@ public class businessController {
);
return ResponseEntity.ok(response.getBody());
}
}
package com.yuda.hainafacetofaceai.entity;
import com.yuda.hainafacetofaceai.annotations.ExcelColumn;
import lombok.Data;
@Data
public class CandidateExam {
private String uuid;
@ExcelColumn(headerName = "姓名")
private String name;
@ExcelColumn(headerName = "准考证")
private String zkzNum;
@ExcelColumn(headerName = "身份证")
private String idCard;
@ExcelColumn(headerName = "手机号")
private String phone;
private String candidateConnectCode;
private String examConnectionCode;
private String imageCommitment;
private String examImageFace;
private Integer statusFace;
private Integer statusCommitment;
}
package com.yuda.hainafacetofaceai.entity;
import lombok.Data;
@Data
public class ExamStudent {
private String zkzNum;
private String idCard;
}
package com.yuda.hainafacetofaceai.service;
import com.yuda.hainafacetofaceai.entity.CandidateExam;
import java.util.List;
import java.util.concurrent.ExecutionException;
public interface ScriptInterfaceService {
boolean BatchInsert(List<CandidateExam> candidateExamList,String examConnectionCode) throws ExecutionException, InterruptedException;
void sendRequestAndSaveDB(CandidateExam candidateExam);
}
package com.yuda.hainafacetofaceai.service.impl;
import com.yuda.hainafacetofaceai.constant.AppThirdPartUrls;
import com.yuda.hainafacetofaceai.entity.CandidateExam;
import com.yuda.hainafacetofaceai.service.ScriptInterfaceService;
import com.yuda.hainafacetofaceai.util.AppUtil;
import lombok.extern.slf4j.Slf4j;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.stream.Collectors;
@Service
@Slf4j
public class ScriptInterfaceServiceImpl implements ScriptInterfaceService {
@Autowired
private JdbcTemplate DBOperator;
private static final ExecutorService executor = Executors.newFixedThreadPool(10);
@Autowired
private RestTemplate restTemplate;
@Autowired
private AppUtil appUtil;
@Override
public boolean BatchInsert(List<CandidateExam> candidateExamList,String examConnectionCode){
List<String> idCards = new ArrayList<>();
try{
idCards = checkIdCardsExistence(candidateExamList.stream().map(CandidateExam::getIdCard).collect(Collectors.toList()));
log.info("查询候选者是否参加笔试成功:"+idCards.size()+"(笔试)/"+candidateExamList.size()+"(面试)");
}catch (Exception e){
log.info("查询候选者是否参加笔试失败");
return false;
}
List<String> finalIdCards = idCards;
List<CandidateExam> paperExamStudents = candidateExamList.stream().filter(x-> finalIdCards.contains(x.getIdCard())).collect(Collectors.toList());
List<String> alreadyExistStudentIdCards = DBOperator.queryForList("select id_card from candidate_exam where exam_connection_code = ?",new Object[]{examConnectionCode},String.class);
if(!alreadyExistStudentIdCards.isEmpty()){
paperExamStudents = paperExamStudents.stream().filter(x->!alreadyExistStudentIdCards.contains(x.getIdCard())).collect(Collectors.toList());
}
if(!paperExamStudents.isEmpty()){
int chunkSize = 1000; // 每批插入1000条记录
int total = paperExamStudents.size();
for (int i = 0; i < total; i += chunkSize) {
int end = Math.min(i + chunkSize, total);
List<CandidateExam> chunk = candidateExamList.subList(i, end);
try{
batchInsert(chunk);
}catch (Exception e){
log.info("候选者批量插入失败:(已插入)"+i+"/"+"(全部)"+total);
return false;
}
}
}
return true;
}
@Override
@Async
public void sendRequestAndSaveDB(CandidateExam candidateExam) {
try{
HttpHeaders headers = new HttpHeaders();
headers.set("Content-Type","application/json");
JSONObject requestBodyObject = new JSONObject(candidateExam);
HttpEntity<String> entity = new HttpEntity<>(requestBodyObject.toString(),headers);
ResponseEntity<String> response = restTemplate.exchange(
appUtil.ApiUrlGen(AppThirdPartUrls.candidateCreate),
HttpMethod.POST,
entity,
String.class
);
JSONObject body = new JSONObject(response.getBody());
if(body.get("code").equals(0)&&body.get("message").equals("ok")){
JSONObject data = new JSONObject(body.getString("data"));
DBOperator.update("update candidate_exam set candidate_connect_code = ? where id_card = ? and exam_connection_code = ?",new Object[]{data.get("candidateConnectCode").toString(),candidateExam.getIdCard(),candidateExam.getExamConnectionCode()});
log.info("面试编号:"+candidateExam.getExamConnectionCode()+"候选者:"+candidateExam.getIdCard()+"面试码申请成功");
}else{
log.info("面试编号:"+candidateExam.getExamConnectionCode()+"候选者:"+candidateExam.getIdCard()+"面试码申请失败,失败原因"+body.getString("message"));
}
}catch (Exception e){
e.printStackTrace();
log.info("面试编号:"+candidateExam.getExamConnectionCode()+"候选者:"+candidateExam.getIdCard()+"请求发送失败");
}
}
@Transactional // 开启事务,确保操作的一致性
public void batchInsert(List<CandidateExam> candidateExamList) {
// 批量插入 SQL 语句
String sql = "INSERT INTO candidate_exam (id_card,zkz_num,exam_connection_code) VALUES (?,?,?)";
// 将 idCards 转换为批量操作所需的参数数组
List<Object[]> batchArgs = new ArrayList<>();
for (CandidateExam candidateExam : candidateExamList) {
batchArgs.add(new Object[]{candidateExam.getIdCard(),candidateExam.getZkzNum(),candidateExam.getExamConnectionCode()});
}
// 使用 batchUpdate 方法执行批量插入
DBOperator.batchUpdate(sql,batchArgs);
}
public List<String> checkIdCardsExistence(List<String> idCards) throws InterruptedException, ExecutionException {
List<String> existingIdCards = Collections.synchronizedList(new ArrayList<>());
List<Future<List<String>>> futures = new ArrayList<>();
// 分批处理 idCard
int batchSize = 100;
for (int i = 0; i < idCards.size(); i += batchSize) {
int end = Math.min(i + batchSize, idCards.size());
List<String> batch = idCards.subList(i, end);
// 使用线程池异步查询数据库
futures.add(executor.submit(() -> queryDatabaseForIdCards(batch)));
}
// 获取所有线程的结果
for (Future<List<String>> future : futures) {
existingIdCards.addAll(future.get());
}
return existingIdCards;
}
private List<String> queryDatabaseForIdCards(List<String> idCards) {
List<String> existingIdCards = new ArrayList<>();
String query = "SELECT idCard FROM users WHERE idCard IN (?)";
// 使用参数化查询防止 SQL 注入
String ids = String.join(",", Collections.nCopies(idCards.size(), "?"));
existingIdCards = DBOperator.queryForList(query,new Object[]{ids},String.class);
return existingIdCards;
}
public JSONObject senGenCandidateConnectionCode(CandidateExam candidateExam) {
HttpHeaders headers = new HttpHeaders();
headers.set("Content-Type", "application/json");
JSONObject requestBodyObject = new JSONObject(candidateExam);
HttpEntity<String> entity = new HttpEntity<>(requestBodyObject.toString(), headers);
ResponseEntity<String> response = restTemplate.exchange(
appUtil.ApiUrlGen(AppThirdPartUrls.candidateCreate),
HttpMethod.POST,
entity,
String.class
);
return new JSONObject(response.getBody());
}
}
package com.yuda.hainafacetofaceai.util;
import com.yuda.hainafacetofaceai.constant.AppStaticParams;
import jdk.nashorn.internal.runtime.logging.Logger;
import com.yuda.hainafacetofaceai.constant.AppThirdPartUrls;
import com.yuda.hainafacetofaceai.entity.CandidateExam;
import lombok.extern.slf4j.Slf4j;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
......@@ -12,31 +20,29 @@ import java.security.NoSuchAlgorithmException;
@Slf4j
public class AppUtil {
@Autowired
private RestTemplate restTemplate;
public String ApiUrlGen(String url){
String timestamp = String.valueOf(System.currentTimeMillis());
timestamp = timestamp.substring(0, 10);
String str = AppStaticParams.appKey + timestamp + AppStaticParams.appSecret;
String md5Str = md5(str);
String suffixParams = "?appKey="+ AppStaticParams.appKey+"&sign="+md5Str+"&timestamp="+timestamp;
return url+suffixParams;
}
public String md5(String input) {
try {
// 创建 MD5 摘要实例
MessageDigest md = MessageDigest.getInstance("MD5");
// 计算 MD5 值
byte[] hashBytes = md.digest(input.getBytes());
// 转换为 32 位小写字符串
StringBuilder sb = new StringBuilder();
for (byte b : hashBytes) {
sb.append(String.format("%02x", b)); // 格式化成 16 进制
}
return sb.toString(); // 返回 32 位 MD5 字符串
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
......@@ -44,4 +50,7 @@ public class AppUtil {
return null;
}
}
package com.yuda.hainafacetofaceai.util;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import java.util.Map;
/**
* 获取token类
*/
public class AuthUtil {
/**
* 获取权限token
* @return 返回示例:
* {
* "access_token": "24.460da4889caad24cccdb1fea17221975.2592000.1491995545.282335-1234567",
* "expires_in": 2592000
* }
*/
public static String getAuth() {
// 官网获取的 API Key 更新为你注册的
String clientId = "h0qbnymceTZa2b2VZ60iOL43";
// 官网获取的 Secret Key 更新为你注册的
String clientSecret = "Q3IC4eF4PDlqVCwZIyGVSfI8dyD5Xpla";
return getAuth(clientId, clientSecret);
}
/**
* 获取API访问token
* 该token有一定的有效期,需要自行管理,当失效时需重新获取.
* @param ak - 百度云官网获取的 API Key
* @param sk - 百度云官网获取的 Securet Key
* @return assess_token 示例:
* "24.460da4889caad24cccdb1fea17221975.2592000.1491995545.282335-1234567"
*/
public static String getAuth(String ak, String sk) {
// 获取token地址
String authHost = "https://aip.baidubce.com/oauth/2.0/token?";
String getAccessTokenUrl = authHost
// 1. grant_type为固定参数
+ "grant_type=client_credentials"
// 2. 官网获取的 API Key
+ "&client_id=" + ak
// 3. 官网获取的 Secret Key
+ "&client_secret=" + sk;
try {
URL realUrl = new URL(getAccessTokenUrl);
// 打开和URL之间的连接
HttpURLConnection connection = (HttpURLConnection) realUrl.openConnection();
connection.setRequestMethod("GET");
connection.connect();
// 获取所有响应头字段
Map<String, List<String>> map = connection.getHeaderFields();
// 遍历所有的响应头字段
for (String key : map.keySet()) {
System.err.println(key + "--->" + map.get(key));
}
// 定义 BufferedReader输入流来读取URL的响应
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String result = "";
String line;
while ((line = in.readLine()) != null) {
result += line;
}
/**
* 返回结果示例
*/
System.err.println("result:" + result);
JSONObject jsonObject = new JSONObject(result);
String access_token = jsonObject.getString("access_token");
return access_token;
} catch (Exception e) {
System.err.printf("获取token失败!");
e.printStackTrace(System.err);
}
return null;
}
}
package com.yuda.hainafacetofaceai.util;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.http.HttpMethodName;
import com.yuda.hainafacetofaceai.constant.CosConstant;
import lombok.extern.slf4j.Slf4j;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import java.net.URL;
import java.util.*;
import java.util.concurrent.TimeUnit;
@Component
@Slf4j
public class BaiDuFaceMatchUtil {
private static final Object lock = new Object();
@Autowired
private COSClient cosClient;
@Autowired
private StringRedisTemplate stringRedisTemplate;
private String getToken() {
String auth = stringRedisTemplate.opsForValue().get("mirror:baiduToken");
if (auth == null) {
synchronized (lock) {
auth = stringRedisTemplate.opsForValue().get("mirror:baiduToken");
if (auth == null) {
auth = AuthUtil.getAuth();
stringRedisTemplate.opsForValue().set("mirror:baiduToken", auth, 25, TimeUnit.DAYS);
}
}
}
return auth;
}
/**
* 百度的人脸检测.
* @return
*/
public String[] faceMatchBaidu(String idCard,String picName) {
// 请求url
String url = "https://aip.baidubce.com/rest/2.0/face/v3/match";
try {
//idCard 和 picName 获取
Date expiration = new Date(new Date().getTime() + 3600 * 1000);
com.qcloud.cos.model.GeneratePresignedUrlRequest req = new com.qcloud.cos.model.GeneratePresignedUrlRequest(CosConstant.COS_BUCKET, "info_image/" + idCard + ".jpg", HttpMethodName.GET);
req.setExpiration(expiration);
URL stuUrl = cosClient.generatePresignedUrl(req);
com.qcloud.cos.model.GeneratePresignedUrlRequest req2 = new com.qcloud.cos.model.GeneratePresignedUrlRequest(CosConstant.COS_BUCKET, "face_image/" + picName, HttpMethodName.GET);
req2.setExpiration(expiration);
URL camImgUrl = cosClient.generatePresignedUrl(req2);
//从redis 中获取auth
String accessToken = getToken();
List<Map<String, String>> list = new ArrayList<>();
Map<String, String> map1 = new HashMap<>();
Map<String, String> map2 = new HashMap<>();
map1.put("image_type", "URL");
map1.put("face_type", "HYBRID");
map1.put("image", stuUrl.toString() + "&imageMogr2/thumbnail/500x");
map1.put("quality_control", "LOW");
map2.put("image_type", "URL");
map2.put("face_type", "HYBRID");
map2.put("image", camImgUrl.toString() + "&imageMogr2/thumbnail/500x");
map2.put("quality_control", "NORMAL");
map2.put("liveness_control", "NORMAL");
list.add(map1);
list.add(map2);
String param = GsonUtils.toJson(list);
String result = HttpUtil.post(url, accessToken, "application/json", param);
JSONObject jsonObject = new JSONObject(result);
log.info("人脸认证--验证结果---->" + jsonObject.toString());
if (jsonObject != null) {
if (jsonObject.getString("error_msg").equals("SUCCESS")) {
JSONObject result1 = jsonObject.getJSONObject("result");
Float score = result1.getFloat("score");
if (score != null && score >= 80) {
return new String[]{"1", "认证成功"};
}
} else {
return new String[]{"0", "认证失败"};
}
}
} catch (Exception e) {
e.printStackTrace();
}
return new String[]{"0", "认证失败"};
}
}
package com.yuda.hainafacetofaceai.util;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.Headers;
import com.qcloud.cos.http.HttpMethodName;
import com.qcloud.cos.model.GeneratePresignedUrlRequest;
import com.tencent.cloud.CosStsClient;
import com.tencent.cloud.Response;
import com.yuda.hainafacetofaceai.constant.CosConstant;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.net.URL;
import java.util.Date;
import java.util.TreeMap;
@Component
public class CosUtil {
@Autowired
private COSClient cosClient;
private String createTempCosSignUrl(String bucketName, String key){
GeneratePresignedUrlRequest req =
new GeneratePresignedUrlRequest(bucketName, key, HttpMethodName.GET);
// 设置签名过期时间(可选), 若未进行设置则默认使用ClientConfig中的签名过期时间(30分钟)
// 这里设置签名在一分钟后过期
Date expirationDate = new Date(System.currentTimeMillis() + 6000 * 1000 * 60 * 24);
req.setExpiration(expirationDate);
req.addRequestParameter("x-cos-traffic-limit", "8388608");
// 填写本次请求的头部。Host 必填
String name = cosClient.getClientConfig().getEndpointBuilder().buildGeneralApiEndpoint(bucketName);
req.putCustomRequestHeader(Headers.HOST, name);
//req.putCustomRequestHeader("header1", "value1");
URL url = cosClient.generatePresignedUrl(req);
return url.toString();
}
public String getSignatureForWeb(String bucket, String region) throws Exception {
TreeMap<String, Object> config = new TreeMap<>();
config.put("SecretId",CosConstant.COS_AccesskeyID);
config.put("SecretKey",CosConstant.COS_AccesskeySECRET);
config.put("durationSeconds", 7200);
config.put("bucket",bucket);
config.put("region",region);
config.put("allowPrefix", "*");
String[] allowActions = new String[]{
"name/cos:PutObject",
"name/cos:PostObject",
"name/cos:InitiateMultipartUpload",
"name/cos:ListMultipartUploads",
"name/cos:ListParts",
"name/cos:UploadPart",
"name/cos:CompleteMultipartUpload"
};
config.put("allowActions", allowActions);
Response response = CosStsClient.getCredential(config);
return new JSONObject(response).toString();
}
}
package com.yuda.hainafacetofaceai.util;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import com.yuda.hainafacetofaceai.annotations.ExcelColumn;
public class ExcelUtil<T> {
public List<T> parseExcel(InputStream inputStream, Class<T> clazz) throws IOException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
List<T> resultList = new ArrayList<>();
// 读取 Excel 文件
Workbook workbook = new XSSFWorkbook(inputStream);
Sheet sheet = workbook.getSheetAt(0); // 假设只读取第一个 sheet
Row headerRow = sheet.getRow(0); // 第一行是表头
// 获取列名
List<String> columnNames = new ArrayList<>();
Iterator<Cell> headerCells = headerRow.iterator();
while (headerCells.hasNext()) {
columnNames.add(headerCells.next().getStringCellValue());
}
// 解析数据
Iterator<Row> rowIterator = sheet.iterator();
rowIterator.next(); // 跳过表头
while (rowIterator.hasNext()) {
Row row = rowIterator.next();
T entity = clazz.getDeclaredConstructor().newInstance();
// 通过反射匹配表头与字段
for (Field field : clazz.getDeclaredFields()) {
if (field.isAnnotationPresent(ExcelColumn.class)) {
ExcelColumn excelColumn = field.getAnnotation(ExcelColumn.class);
String columnName = excelColumn.headerName();
// 找到表头列名匹配的索引
int columnIndex = columnNames.indexOf(columnName);
if (columnIndex != -1) {
// 获取对应列的数据
Cell cell = row.getCell(columnIndex);
String cellValue = getCellValue(cell);
// 设置字段值
field.setAccessible(true);
setFieldValue(entity, field, cellValue);
}
}
}
resultList.add(entity);
}
workbook.close();
return resultList;
}
private String getCellValue(Cell cell) {
if (cell == null) {
return "";
}
switch (cell.getCellType()) {
case STRING:
return cell.getStringCellValue();
case NUMERIC:
return String.valueOf(cell.getNumericCellValue());
case BOOLEAN:
return String.valueOf(cell.getBooleanCellValue());
default:
return "";
}
}
private void setFieldValue(T entity, Field field, String value) throws IllegalAccessException {
if (field.getType() == String.class) {
field.set(entity, value);
} else if (field.getType() == Integer.class) {
field.set(entity, Integer.parseInt(value));
}
// 其他类型可以继续添加支持
}
}
package com.yuda.hainafacetofaceai.util;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonParseException;
import java.lang.reflect.Type;
public class GsonUtils {
private static Gson gson = new GsonBuilder().create();
public static String toJson(Object value) {
return gson.toJson(value);
}
public static <T> T fromJson(String json, Class<T> classOfT) throws JsonParseException {
return gson.fromJson(json, classOfT);
}
public static <T> T fromJson(String json, Type typeOfT) throws JsonParseException {
return (T) gson.fromJson(json, typeOfT);
}
}
\ No newline at end of file
package com.yuda.hainafacetofaceai.util;
import org.springframework.stereotype.Component;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import java.util.Map;
@Component
public class HttpUtil {
public static String post(String requestUrl, String accessToken, String params)
throws Exception {
String contentType = "application/x-www-form-urlencoded";
return HttpUtil.post(requestUrl, accessToken, contentType, params);
}
public static String post(String requestUrl, String accessToken, String contentType, String params)
throws Exception {
String encoding = "UTF-8";
if (requestUrl.contains("nlp")) {
encoding = "GBK";
}
return HttpUtil.post(requestUrl, accessToken, contentType, params, encoding);
}
public static String post(String requestUrl, String accessToken, String contentType, String params, String encoding)
throws Exception {
String url = requestUrl + "?access_token=" + accessToken;
return HttpUtil.postGeneralUrl(url, contentType, params, encoding);
}
public static String postGeneralUrl(String generalUrl, String contentType, String params, String encoding)
throws Exception {
URL url = new URL(generalUrl);
// 打开和URL之间的连接
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
// 设置通用的请求属性
connection.setRequestProperty("Content-Type", contentType);
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setUseCaches(false);
connection.setDoOutput(true);
connection.setDoInput(true);
// 得到请求的输出流对象
DataOutputStream out = new DataOutputStream(connection.getOutputStream());
out.write(params.getBytes(encoding));
out.flush();
out.close();
// 建立实际的连接
connection.connect();
// 获取所有响应头字段
Map<String, List<String>> headers = connection.getHeaderFields();
// 定义 BufferedReader输入流来读取URL的响应
BufferedReader in = null;
in = new BufferedReader(
new InputStreamReader(connection.getInputStream(), encoding));
String result = "";
String getLine;
while ((getLine = in.readLine()) != null) {
result += getLine;
}
in.close();
return result;
}
}
\ No newline at end of file
package com.yuda.hainafacetofaceai.util;
import org.springframework.stereotype.Component;
import java.util.Random;
@Component
public class RandomNumberUtil {
// 扩展后的常见姓氏数组
private static final String[] SURNAMES = {
"张", "李", "王", "赵", "刘", "陈", "杨", "黄", "周", "吴",
"徐", "孙", "马", "朱", "胡", "林", "何", "高", "郭", "罗",
"梁", "宋", "郑", "谢", "唐", "许", "邓", "冯", "程", "曹",
"邱", "毛", "邹", "谢", "潘", "蒋", "谭", "魏", "戴", "阮",
"任", "潘", "彭", "黎", "蒋", "尤", "史", "孔", "汪", "余"
};
// 扩展后的名字部分数组
private static final String[] FIRST_NAMES = {
"伟", "娜", "婷", "敏", "丽", "芳", "杰", "鹏", "军", "洋",
"超", "静", "琳", "彬", "刚", "磊", "媛", "华", "明", "燕",
"娟", "强", "立", "磊", "佳", "琪", "冰", "婷", "欣", "晨",
"露", "云", "媛", "琴", "雪", "涵", "洁", "梅", "颖", "霞",
"雨", "华", "婧", "舒", "丹", "彤", "珊", "娴", "睿", "宇",
"泽", "博", "欣", "淼", "蓉", "明", "露", "雯", "思思", "佳怡",
"子怡", "思琪", "欣妍", "晓琳", "悦琳", "心怡", "晓彤", "美玲"
};
public String generateRandomPhoneNumber() {
Random random = new Random();
// 中国手机号通常以 1 开头,第二位是 3-9 中的某个数字
int secondDigit = random.nextInt(7) + 3; // 3-9
StringBuilder phoneNumber = new StringBuilder();
// 构建手机号
phoneNumber.append("1"); // 第一位是 1
phoneNumber.append(secondDigit); // 第二位是 3-9 中的数字
for (int i = 0; i < 8; i++) {
phoneNumber.append(random.nextInt(10)); // 随机生成接下来的 8 位数字
}
return phoneNumber.toString();
}
// 随机生成中文昵称的方法
public String generateRandomChineseNickname() {
Random random = new Random();
// 随机选择姓氏
String surname = SURNAMES[random.nextInt(SURNAMES.length)];
// 随机选择名字部分(可以选择一个或两个字)
String firstName = FIRST_NAMES[random.nextInt(FIRST_NAMES.length)];
// 拼接姓氏和名字
return surname + firstName;
}
}
spring.application.name=HaiNaFaceToFaceAI
server.port=8081
spring.redis.host=192.168.0.4
spring.redis.port=6379
spring.redis.password=Thussat@2023
spring.redis.database=60
#spring.redis.host=127.0.0.1
#Redis ?????
#spring.redis.host=192.168.0.4
#spring.redis.port=6379
#spring.redis.password=
#spring.redis.database=1
#spring.redis.password=Thussat@2023
#spring.redis.database=60
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=
spring.redis.database=1
spring.redis.timeout=2000
# MySQL ?????
spring.datasource.url=jdbc:mysql://192.168.0.11:3306/haina_ai_face?useSSL=false&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=Thu#DSS#0419
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# ?????????
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.maximum-pool-size=10
spring.datasource.hikari.idle-timeout=30000
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment