From 45d3003987b45e1f5ac6f44050c43fdf14003b9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A1=BE=E6=8C=BD?= Date: Mon, 11 Nov 2024 14:37:13 +0800 Subject: [PATCH] =?UTF-8?q?=E9=A1=BE=E6=8C=BD11.11?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ArcFacePro64.dat | 1 + login/pom.xml | 74 ++++++++++++-- .../main/java/com/guwan/LoginApplication.java | 15 +++ login/src/main/java/com/guwan/common/R.java | 2 +- .../java/com/guwan/config/GlobalValue.java | 6 ++ .../main/java/com/guwan/config/WebConfig.java | 10 ++ .../controller/login/EasyScanController.java | 64 +++++++++++++ .../controller/login/MockScanMapper.java | 21 ++++ .../controller/login/MockScanServiceImpl.java | 22 +++++ .../controller/login/ScanCodeController.java | 4 +- .../controller/login/UploadController.java | 2 +- .../controller/login/UserController.java | 52 +++++++++- .../main/java/com/guwan/domain/MockScan.java | 74 ++++++++++++++ .../com/guwan/mapdemo/SimpleDestination.java | 10 ++ .../java/com/guwan/mapdemo/SimpleSource.java | 16 ++++ .../SimpleSourceDestinationMapper.java | 10 ++ .../com/guwan/service/MockScanService.java | 14 +++ login/src/main/java/com/guwan/test/Test1.java | 9 ++ .../com/guwan/util/ConvertBase64Util.java | 21 ++++ .../java/com/guwan/util/EncodeUrlExample.java | 24 +++++ .../main/java/com/guwan/util/FileUtil.java | 14 +++ .../main/java/com/guwan/util/RecognizeVo.java | 12 +++ .../java/com/guwan/util/SimpleAudioSaver.java | 58 +++++++++++ .../java/com/guwan/util/ToTextExample.java | 66 +++++++++++++ .../java/com/guwan/util/ToTextExample2.java | 70 ++++++++++++++ .../main/java/com/guwan/util/UploadUtil.java | 64 +++++++++++++ .../com/guwan/util/VoiceServiceClient.java | 16 ++++ login/src/main/resources/application.yml | 23 ++++- old-face/pom.xml | 4 +- old-nacos/pom.xml | 4 +- output.mp3 | Bin 0 -> 14256 bytes pom.xml | 60 ++++++++---- qrcode.png | Bin 0 -> 5002 bytes readme.md | 12 ++- ss-Demo/pom.xml | 21 +++- .../java/com/guwan/SsDemoApplication.java | 1 + .../com/guwan/controller/OrderController.java | 30 +++--- .../java/com/guwan/dal/dataobject/Order.java | 23 ++++- .../java/com/guwan/dal/mysql/OrderMapper.java | 11 +-- .../java/com/guwan/service/IOrderService.java | 9 ++ .../java/com/guwan/service/OrderService.java | 23 ----- .../com/guwan/service/OrderServiceImpl.java | 13 +++ ss-Demo/src/main/resources/application.yml | 90 ++++++++++++------ .../com/guwan/dal/mysql/OrderMapper.xml | 15 +-- 44 files changed, 965 insertions(+), 125 deletions(-) create mode 100644 ArcFacePro64.dat create mode 100644 login/src/main/java/com/guwan/controller/login/EasyScanController.java create mode 100644 login/src/main/java/com/guwan/controller/login/MockScanMapper.java create mode 100644 login/src/main/java/com/guwan/controller/login/MockScanServiceImpl.java create mode 100644 login/src/main/java/com/guwan/domain/MockScan.java create mode 100644 login/src/main/java/com/guwan/mapdemo/SimpleDestination.java create mode 100644 login/src/main/java/com/guwan/mapdemo/SimpleSource.java create mode 100644 login/src/main/java/com/guwan/mapdemo/SimpleSourceDestinationMapper.java create mode 100644 login/src/main/java/com/guwan/service/MockScanService.java create mode 100644 login/src/main/java/com/guwan/test/Test1.java create mode 100644 login/src/main/java/com/guwan/util/ConvertBase64Util.java create mode 100644 login/src/main/java/com/guwan/util/EncodeUrlExample.java create mode 100644 login/src/main/java/com/guwan/util/FileUtil.java create mode 100644 login/src/main/java/com/guwan/util/RecognizeVo.java create mode 100644 login/src/main/java/com/guwan/util/SimpleAudioSaver.java create mode 100644 login/src/main/java/com/guwan/util/ToTextExample.java create mode 100644 login/src/main/java/com/guwan/util/ToTextExample2.java create mode 100644 login/src/main/java/com/guwan/util/UploadUtil.java create mode 100644 login/src/main/java/com/guwan/util/VoiceServiceClient.java create mode 100644 output.mp3 create mode 100644 qrcode.png create mode 100644 ss-Demo/src/main/java/com/guwan/service/IOrderService.java delete mode 100644 ss-Demo/src/main/java/com/guwan/service/OrderService.java create mode 100644 ss-Demo/src/main/java/com/guwan/service/OrderServiceImpl.java diff --git a/ArcFacePro64.dat b/ArcFacePro64.dat new file mode 100644 index 0000000..d9bdb0e --- /dev/null +++ b/ArcFacePro64.dat @@ -0,0 +1 @@ +EWEPEPEOGMGTELIZJUGECKIUJDBCJTCNISGPBNHLJTJUBHEWGNAKGEGAIOHJDQAJGNCFDRFZJEDMJTICAYHPJFJEJCFEBTARCUDPDEEJESDSBAEXAFJCCJCGANIQEQBUJGGEGGDNAVBQHVDCFADNAIEXAMFSDLDAAJEVCIDRDEFBDWJGBOCCHIDQBAIIICCOBMEPBHFTETGTGHHCHEDHFIDACHAVINAKGYBNDREKGCDJJJARFFDHHIEXIHCZEFJLIDEVIVAHDADHBZBBHBFCBYCGDXBPALBIEWJCGPHFESJDEGHLCFDGDXEDFEHJHNAIEYINIVGTCYGBIZGSCICDBCJIFWICDBGXISETIIETHTBNIBJNHVCXGLGFHKAVDGIWFHIRBFBVAHEZHSACJSGYHMISGJFYBQALFBDFENFVHHDJIVGJFKDGCOJDCQIVGBGBIGFFEAAEAHCJFHAMDDAQBREQCXASHAFKCOBDIGABFVGMIBHTIBHEHQCVDEDVGXEOIXJCBIERFDCIJBCZAKEACHEBELIXDVDHHMEQFEHXELCLIFJDDMJGJCALDGGMHXBWBAHUBTJPFJIVEJGCIOBMDICHGLEDCCGWBWJTAWENBUGGDNCFEHEFBUJMBOIYEFCGAOALGZFHBHGIALHEIWGNFUHKGAHXHMIMDADAJHESHYIPHOFUBKENAUINDNDXGJEIHACOAGJDAJDEGWGCBDGYGOFRARCMHCFQFRENJHFVDGDTIBELAJFCHHGZFFECFECCAGHPGUIXIWANCJESHUHNEGGUAVJGBUHWFFCOCCJFJJDAINECGRAGHMEFFHHCCBAJCSFRFUACCYIAAVILFCAXIMFZGSBKGRBHEOFKJREFITCGFGEBFGGYJAGYHWDADDCQGUJAJCHUFPIPCRFSJVJFIIBRAYISITIFDUBOABGGIQCRDRDVEDBJIMCSBKFTFKBSJVJOJGIGDGETEVELDBFVHICHECHEFVFSDYFMINIPITECJGEXACCZEWGGIYDRDMAQFUJEIEJCJAHCCJEOCEGQGSIXHBDXEIHLCTADGWDDGGIHBLHOEAIMFHHGAAFWDWGGGGDJGVFFBWCMHBHCBVCUGJIGDRDKBMBYJVHPISGZFUFREPAOBDDOJJBNEGFMIYEZEYDUAVBMDJDRBKDQJLJJBHCLEQCJILFGHAHCDHHWIUGRCQ \ No newline at end of file diff --git a/login/pom.xml b/login/pom.xml index 18bd519..c83be31 100644 --- a/login/pom.xml +++ b/login/pom.xml @@ -14,18 +14,28 @@ - 21 - 21 + 17 + 17 UTF-8 + + + + + com.xingyuv spring-boot-starter-captcha-plus 2.0.1 + org.lionsoul ip2region @@ -82,20 +92,72 @@ com.alibaba - druid-spring-boot-starter - 1.1.10 + druid-spring-boot-3-starter + 1.2.20 + + + + org.mapstruct + mapstruct + 1.6.0.Beta1 + + + + org.springframework.boot + spring-boot-starter-webflux + + + + org.springframework.cloud + spring-cloud-starter-openfeign + 4.0.4 + + + + + + com.github.liuyueyi.media + qrcode-plugin + 3.0.0 + + + + org.apache.commons + commons-lang3 + 3.12.0 + + + + + ${project.artifactId} - org.springframework.boot - spring-boot-maven-plugin + org.apache.maven.plugins + maven-compiler-plugin + 3.11.0 + + + + org.mapstruct + mapstruct-processor + 1.6.0.Beta1 + + + org.projectlombok + lombok + 1.18.34 + + + + diff --git a/login/src/main/java/com/guwan/LoginApplication.java b/login/src/main/java/com/guwan/LoginApplication.java index e6f6294..252b7ce 100644 --- a/login/src/main/java/com/guwan/LoginApplication.java +++ b/login/src/main/java/com/guwan/LoginApplication.java @@ -1,11 +1,17 @@ package com.guwan; import cn.dev33.satoken.SaManager; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.cloud.openfeign.EnableFeignClients; +import org.springframework.context.annotation.Bean; +import org.springframework.web.client.RestTemplate; @SpringBootApplication +@EnableFeignClients public class LoginApplication { public static void main(String[] args) { @@ -13,4 +19,13 @@ public class LoginApplication { System.out.println("启动成功,Sa-Token 配置如下:" + SaManager.getConfig()); } + @Autowired + //RestTemplateBuilder + private RestTemplateBuilder builder; + // 使用RestTemplateBuilder来实例化RestTemplate对象,spring默认已经注入了RestTemplateBuilder实例 + @Bean + public RestTemplate restTemplate() { + return builder.build(); + } + } diff --git a/login/src/main/java/com/guwan/common/R.java b/login/src/main/java/com/guwan/common/R.java index 8b3da38..202b04b 100644 --- a/login/src/main/java/com/guwan/common/R.java +++ b/login/src/main/java/com/guwan/common/R.java @@ -14,7 +14,7 @@ public class R extends HashMap { private static final long serialVersionUID = 1L; public R() { - put("code", 0); + put("status", 200); put("msg", "success"); put("data", new HashMap<>()); } diff --git a/login/src/main/java/com/guwan/config/GlobalValue.java b/login/src/main/java/com/guwan/config/GlobalValue.java index ffbe08c..1d16d9a 100644 --- a/login/src/main/java/com/guwan/config/GlobalValue.java +++ b/login/src/main/java/com/guwan/config/GlobalValue.java @@ -61,4 +61,10 @@ public class GlobalValue { @Value("${global.file_path.static-locations}") private String staticLocations; + @Value("${global.faster-whisper.model}") + private String model; + + @Value("${global.faster-whisper.transitionApi}") + private String transitionApi; + } diff --git a/login/src/main/java/com/guwan/config/WebConfig.java b/login/src/main/java/com/guwan/config/WebConfig.java index c6d41ad..a0c066d 100644 --- a/login/src/main/java/com/guwan/config/WebConfig.java +++ b/login/src/main/java/com/guwan/config/WebConfig.java @@ -3,6 +3,7 @@ package com.guwan.config; import com.guwan.Interceptor.TokenInterceptor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @@ -18,4 +19,13 @@ public class WebConfig implements WebMvcConfigurer { .addPathPatterns("/user/**") // 拦截 /User/** 路径 .excludePathPatterns("/user/login"); // 不拦截 /User/login 路径 } + + @Override + public void addCorsMappings(CorsRegistry registry) { + registry.addMapping("/**") + .allowedOrigins("*") // 允许指定的源 + .allowedMethods("GET", "POST", "PUT", "DELETE") // 允许的方法 + .allowedHeaders("*"); // 允许的请求头 + } + } diff --git a/login/src/main/java/com/guwan/controller/login/EasyScanController.java b/login/src/main/java/com/guwan/controller/login/EasyScanController.java new file mode 100644 index 0000000..c852981 --- /dev/null +++ b/login/src/main/java/com/guwan/controller/login/EasyScanController.java @@ -0,0 +1,64 @@ +package com.guwan.controller.login; + +import com.github.hui.quick.plugin.qrcode.wrapper.QrCodeGenWrapper; +import com.guwan.common.R; +import com.guwan.domain.MockScan; +import com.guwan.service.MockScanService; +import com.guwan.util.ConvertBase64Util; +import com.guwan.util.UUIDUtil; +import jakarta.annotation.Resource; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.File; +import java.nio.file.Path; + +@RestController +@RequestMapping("/easyScan") +public class EasyScanController { + + @Resource + MockScanService mockScanService; + + @GetMapping("/11") + public R QrCode(String content) { + BufferedImage image = null; + try { + image = QrCodeGenWrapper.of(content).asBufferedImage(); + Path file = new File("qrcode.png").toPath(); + ImageIO.write(image, "png", file.toFile()); + } catch (Exception e) { + e.printStackTrace(); + } + mockScanService.save(new MockScan(ConvertBase64Util.imageToString(image), UUIDUtil.uuid())); + + return R.ok().put("data", ConvertBase64Util.imageToString(image)).put("uuid", UUIDUtil.uuid()); + } + + @GetMapping("/no") + public R QrCodeBySearch() { + BufferedImage image = null; + + String content = null; + //查询封装成content + // content = (); + + try { + image = QrCodeGenWrapper.of(content).asBufferedImage(); + Path file = new File("qrcode.png").toPath(); + ImageIO.write(image, "png", file.toFile()); + } catch (Exception e) { + e.printStackTrace(); + } + mockScanService.save(new MockScan(ConvertBase64Util.imageToString(image), UUIDUtil.uuid())); + + return R.ok().put("data", ConvertBase64Util.imageToString(image)).put("uuid", UUIDUtil.uuid()); + } + + + + +} diff --git a/login/src/main/java/com/guwan/controller/login/MockScanMapper.java b/login/src/main/java/com/guwan/controller/login/MockScanMapper.java new file mode 100644 index 0000000..c441802 --- /dev/null +++ b/login/src/main/java/com/guwan/controller/login/MockScanMapper.java @@ -0,0 +1,21 @@ +package com.guwan.controller.login; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.guwan.domain.MockScan; +import org.apache.ibatis.annotations.Mapper; + +/** +* @author 12455 +* @description 针对表【mock_scan】的数据库操作Mapper +* @createDate 2024-11-11 12:32:00 +* @Entity generator.domain.MockScan +*/ +@Mapper +public interface MockScanMapper extends BaseMapper { + +} + + + + diff --git a/login/src/main/java/com/guwan/controller/login/MockScanServiceImpl.java b/login/src/main/java/com/guwan/controller/login/MockScanServiceImpl.java new file mode 100644 index 0000000..85e3088 --- /dev/null +++ b/login/src/main/java/com/guwan/controller/login/MockScanServiceImpl.java @@ -0,0 +1,22 @@ +package com.guwan.controller.login; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; + +import com.guwan.domain.MockScan; +import com.guwan.service.MockScanService; +import org.springframework.stereotype.Service; + +/** +* @author 12455 +* @description 针对表【mock_scan】的数据库操作Service实现 +* @createDate 2024-11-11 12:32:00 +*/ +@Service +public class MockScanServiceImpl extends ServiceImpl + implements MockScanService { + +} + + + + diff --git a/login/src/main/java/com/guwan/controller/login/ScanCodeController.java b/login/src/main/java/com/guwan/controller/login/ScanCodeController.java index 8b5cfb9..9a3789d 100644 --- a/login/src/main/java/com/guwan/controller/login/ScanCodeController.java +++ b/login/src/main/java/com/guwan/controller/login/ScanCodeController.java @@ -3,6 +3,7 @@ package com.guwan.controller.login; import cn.hutool.http.HttpUtil; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; +import com.guwan.common.R; import com.guwan.controller.login.info.UserRequest; import com.guwan.controller.login.info.WxMaUserInfo; import com.guwan.controller.login.request.ScanResult; @@ -15,7 +16,7 @@ public class ScanCodeController { @Operation(summary = "获取微信登录二维码信息") @RequestMapping("/wxQr") @ResponseBody - public void wxQr(String secret) { + public R wxQr(String secret) { // 请求易登获取二维码接口 String s = HttpUtil.get("https://yd.jylt.cc/api/wxLogin/tempUserId?secret=" + secret); JSONObject jsonObject = JSONUtil.parseObj(s); @@ -26,6 +27,7 @@ public class ScanCodeController { System.out.println(jsonObject.getJSONObject("data"). getStr("qrUrl")); } + return R.ok().put("data", jsonObject.getJSONObject("data")); } diff --git a/login/src/main/java/com/guwan/controller/login/UploadController.java b/login/src/main/java/com/guwan/controller/login/UploadController.java index dfa9f4c..2f3803b 100644 --- a/login/src/main/java/com/guwan/controller/login/UploadController.java +++ b/login/src/main/java/com/guwan/controller/login/UploadController.java @@ -46,7 +46,7 @@ public class UploadController { }else if (extension.equals("mp4")){ catalogue = "video/"; }else { - return R.error().put("info", "不允许上传此类型!"); + catalogue = "file/"; } fileName = catalogue + "t_" + diff --git a/login/src/main/java/com/guwan/controller/login/UserController.java b/login/src/main/java/com/guwan/controller/login/UserController.java index f43af0c..1a2e9cc 100644 --- a/login/src/main/java/com/guwan/controller/login/UserController.java +++ b/login/src/main/java/com/guwan/controller/login/UserController.java @@ -1,12 +1,19 @@ package com.guwan.controller.login; +import cn.hutool.json.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.guwan.common.R; import com.guwan.config.GlobalValue; +import com.guwan.mapdemo.SimpleDestination; +import com.guwan.mapdemo.SimpleSource; +import com.guwan.mapdemo.SimpleSourceDestinationMapper; +import com.guwan.mapdemo.SimpleSourceDestinationMapperImpl; import com.guwan.service.TokenService; -import com.guwan.util.IPUtils; -import com.guwan.util.PathUtil; +import com.guwan.util.*; import io.swagger.v3.oas.annotations.Operation; import jakarta.annotation.security.PermitAll; import jakarta.servlet.http.HttpServletRequest; +import org.checkerframework.checker.units.qual.A; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; @@ -17,6 +24,7 @@ import org.springframework.web.multipart.MultipartFile; import java.io.File; import java.io.IOException; import java.nio.file.Path; +import java.util.List; @RestController @RequestMapping("/user") @@ -27,12 +35,25 @@ public class UserController { @Autowired private GlobalValue globalValue; + @Autowired + private UserMapper userMapper; + + @Autowired + private SimpleSourceDestinationMapper simpleSourceDestinationMapper; + + @Autowired + private VoiceServiceClient voiceServiceClient; + @GetMapping("/login") @PermitAll @Operation(summary = "使用账号密码登录") public String login(String userId, HttpServletRequest request) { + List users = userMapper.selectList(new QueryWrapper<>()); + System.out.println("users = " + users); + + String test = PathUtil.path(); @@ -92,4 +113,31 @@ public class UserController { } + @GetMapping("/test") + public void test1(){ + SimpleDestination sourceName = simpleSourceDestinationMapper.sourceToDestination(new SimpleSource("sourceName", "2")); + System.out.println("sourceName = " + sourceName); + } + + @GetMapping("/test123") + private R test2(String fileUrl){ + System.out.println("fileUrl = " + fileUrl); + return R.ok().put("data", ToTextExample.voiceToText(fileUrl)); + } + + + @GetMapping("/test123456") + private R test3(String fileUrl){ + System.out.println("fileUrl = " + fileUrl); + return R.ok().put("data", ToTextExample2.voiceToText(fileUrl)); + } + + @PostMapping("/demo888") + public JSONObject convertVoiceToText(MultipartFile file, String model) { + System.out.println(voiceServiceClient.voiceToText(file, model)); + return voiceServiceClient.voiceToText(file, model); + } + + + } diff --git a/login/src/main/java/com/guwan/domain/MockScan.java b/login/src/main/java/com/guwan/domain/MockScan.java new file mode 100644 index 0000000..38cc205 --- /dev/null +++ b/login/src/main/java/com/guwan/domain/MockScan.java @@ -0,0 +1,74 @@ +package com.guwan.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import lombok.Data; + +/** + * + * @TableName mock_scan + */ +@TableName(value ="mock_scan") +@Data +public class MockScan implements Serializable { + /** + * + */ + @TableField(value = "info") + private String info; + + /** + * + */ + @TableField(value = "uuid") + private String uuid; + + @TableField(exist = false) + private static final long serialVersionUID = 1L; + + public MockScan(String info, String uuid) { + this.info = info; + this.uuid = uuid; + } + + @Override + public boolean equals(Object that) { + if (this == that) { + return true; + } + if (that == null) { + return false; + } + if (getClass() != that.getClass()) { + return false; + } + MockScan other = (MockScan) that; + return (this.getInfo() == null ? other.getInfo() == null : this.getInfo().equals(other.getInfo())) + && (this.getUuid() == null ? other.getUuid() == null : this.getUuid().equals(other.getUuid())); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((getInfo() == null) ? 0 : getInfo().hashCode()); + result = prime * result + ((getUuid() == null) ? 0 : getUuid().hashCode()); + return result; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(getClass().getSimpleName()); + sb.append(" ["); + sb.append("Hash = ").append(hashCode()); + sb.append(", info=").append(info); + sb.append(", uuid=").append(uuid); + sb.append(", serialVersionUID=").append(serialVersionUID); + sb.append("]"); + return sb.toString(); + } +} \ No newline at end of file diff --git a/login/src/main/java/com/guwan/mapdemo/SimpleDestination.java b/login/src/main/java/com/guwan/mapdemo/SimpleDestination.java new file mode 100644 index 0000000..9438e1b --- /dev/null +++ b/login/src/main/java/com/guwan/mapdemo/SimpleDestination.java @@ -0,0 +1,10 @@ +package com.guwan.mapdemo; + +import lombok.Data; + +@Data +public class SimpleDestination { + private String name; + private String description; + // getters and setters +} \ No newline at end of file diff --git a/login/src/main/java/com/guwan/mapdemo/SimpleSource.java b/login/src/main/java/com/guwan/mapdemo/SimpleSource.java new file mode 100644 index 0000000..fc4222a --- /dev/null +++ b/login/src/main/java/com/guwan/mapdemo/SimpleSource.java @@ -0,0 +1,16 @@ +package com.guwan.mapdemo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class SimpleSource { + private String name; + private String description; + + + // getters and setters +} \ No newline at end of file diff --git a/login/src/main/java/com/guwan/mapdemo/SimpleSourceDestinationMapper.java b/login/src/main/java/com/guwan/mapdemo/SimpleSourceDestinationMapper.java new file mode 100644 index 0000000..b8d952f --- /dev/null +++ b/login/src/main/java/com/guwan/mapdemo/SimpleSourceDestinationMapper.java @@ -0,0 +1,10 @@ +package com.guwan.mapdemo; + + +import org.mapstruct.Mapper; + +@Mapper(componentModel = "spring") +public interface SimpleSourceDestinationMapper { + SimpleDestination sourceToDestination(SimpleSource source); + SimpleSource destinationToSource(SimpleDestination destination); +} diff --git a/login/src/main/java/com/guwan/service/MockScanService.java b/login/src/main/java/com/guwan/service/MockScanService.java new file mode 100644 index 0000000..269fc85 --- /dev/null +++ b/login/src/main/java/com/guwan/service/MockScanService.java @@ -0,0 +1,14 @@ +package com.guwan.service; + + +import com.baomidou.mybatisplus.extension.service.IService; +import com.guwan.domain.MockScan; + +/** +* @author 12455 +* @description 针对表【mock_scan】的数据库操作Service +* @createDate 2024-11-11 12:32:00 +*/ +public interface MockScanService extends IService { + +} diff --git a/login/src/main/java/com/guwan/test/Test1.java b/login/src/main/java/com/guwan/test/Test1.java new file mode 100644 index 0000000..790a062 --- /dev/null +++ b/login/src/main/java/com/guwan/test/Test1.java @@ -0,0 +1,9 @@ +package com.guwan.test; + +import cn.hutool.core.io.resource.ResourceUtil; +//获取resource下文件 +public class Test1 { + public static void main(String[] args) { + System.out.println(ResourceUtil.getResource("banner.txt")); + } +} diff --git a/login/src/main/java/com/guwan/util/ConvertBase64Util.java b/login/src/main/java/com/guwan/util/ConvertBase64Util.java new file mode 100644 index 0000000..a851f34 --- /dev/null +++ b/login/src/main/java/com/guwan/util/ConvertBase64Util.java @@ -0,0 +1,21 @@ +package com.guwan.util; + +import org.apache.commons.codec.binary.Base64; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +public class ConvertBase64Util { + public static String imageToString(BufferedImage image) { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + try { + ImageIO.write(image, "png", os); + } catch (IOException e) { + e.printStackTrace(); + } + //转base64的字符串 + return Base64.encodeBase64String(os.toByteArray()); + } +} diff --git a/login/src/main/java/com/guwan/util/EncodeUrlExample.java b/login/src/main/java/com/guwan/util/EncodeUrlExample.java new file mode 100644 index 0000000..5de3291 --- /dev/null +++ b/login/src/main/java/com/guwan/util/EncodeUrlExample.java @@ -0,0 +1,24 @@ +package com.guwan.util; + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.util.Base64; + +public class EncodeUrlExample { + public static void main(String[] args) { + String url = "http://127.0.0.1:9000/yunnni/2023最新版Node.js下载安装及环境配置教程.pdf"; // 要预览文件的访问地址 + try { + // 对URL进行Base64编码 + String base64EncodedUrl = Base64.getEncoder().encodeToString(url.getBytes()); + // 对Base64编码后的字符串进行URL编码 + String encodedUrl = URLEncoder.encode(base64EncodedUrl, "UTF-8"); + // 构建预览文件的URL + String previewUrl = "http://127.0.0.1:8012/onlinePreview?url=" + encodedUrl; + System.out.println("预览文件的URL: " + previewUrl); + // 这里可以打开预览文件的URL,例如使用Desktop类的browse方法 + // Desktop.getDesktop().browse(new URI(previewUrl)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/login/src/main/java/com/guwan/util/FileUtil.java b/login/src/main/java/com/guwan/util/FileUtil.java new file mode 100644 index 0000000..b09c5a4 --- /dev/null +++ b/login/src/main/java/com/guwan/util/FileUtil.java @@ -0,0 +1,14 @@ +package com.guwan.util; + +import org.springframework.core.io.ByteArrayResource; + +public class FileUtil { + public static ByteArrayResource createByteArrayResource(byte[] content, String filename) { + return new ByteArrayResource(content) { + @Override + public String getFilename() { + return filename; + } + }; + } +} diff --git a/login/src/main/java/com/guwan/util/RecognizeVo.java b/login/src/main/java/com/guwan/util/RecognizeVo.java new file mode 100644 index 0000000..fc12bf9 --- /dev/null +++ b/login/src/main/java/com/guwan/util/RecognizeVo.java @@ -0,0 +1,12 @@ +package com.guwan.util; + +import lombok.Data; +import org.springframework.core.io.ByteArrayResource; + +@Data +public class RecognizeVo { + + private ByteArrayResource fileResource; + + private String model; +} diff --git a/login/src/main/java/com/guwan/util/SimpleAudioSaver.java b/login/src/main/java/com/guwan/util/SimpleAudioSaver.java new file mode 100644 index 0000000..bd70691 --- /dev/null +++ b/login/src/main/java/com/guwan/util/SimpleAudioSaver.java @@ -0,0 +1,58 @@ +package com.guwan.util; + +import java.io.BufferedInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.URL; + + +/* +文本转语音 + */ +public class SimpleAudioSaver { + + public static void main(String[] args) { + String urlString = "http://localhost:8534/v1/audio/speech"; // API URL + String jsonInputString = "{\"input\": \"想听个啥123\", \"voice\": \"zh-CN-XiaoxiaoNeural\", \"style\": \"\", \"rate\": 0, \"pitch\": 0}"; + + saveAudio(urlString, jsonInputString); + } + + public static void saveAudio(String urlString, String jsonInputString) { + try { + // 创建 URL 对象 + URL url = new URL(urlString); + // 打开连接 + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + // 设置请求方式为 POST + connection.setRequestMethod("POST"); + connection.setDoOutput(true); + connection.setRequestProperty("Content-Type", "application/json"); + connection.setRequestProperty("Accept", "audio/mpeg"); + + // 发送请求体 + connection.getOutputStream().write(jsonInputString.getBytes("UTF-8")); + + // 处理响应 + if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) { + // 获取输入流 + InputStream inputStream = new BufferedInputStream(connection.getInputStream()); + // 保存文件 + try (FileOutputStream outputStream = new FileOutputStream("output.mp3")) { + byte[] buffer = new byte[1024]; + int bytesRead; + while ((bytesRead = inputStream.read(buffer)) != -1) { + outputStream.write(buffer, 0, bytesRead); + } + } + System.out.println("Audio saved as output.mp3"); + } else { + System.err.println("Failed to get audio. Response code: " + connection.getResponseCode()); + } + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/login/src/main/java/com/guwan/util/ToTextExample.java b/login/src/main/java/com/guwan/util/ToTextExample.java new file mode 100644 index 0000000..d053b22 --- /dev/null +++ b/login/src/main/java/com/guwan/util/ToTextExample.java @@ -0,0 +1,66 @@ +package com.guwan.util; + +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; + +import com.guwan.config.GlobalValue; +import io.minio.MinioClient; +import org.apache.commons.io.IOUtils; +import org.springframework.core.io.ByteArrayResource; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Component; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; + +import java.io.InputStream; + +@Component + +public class ToTextExample { + private static MinioClient minioClient; + private static RestTemplate restTemplate; + private static GlobalValue globalValue; + + public ToTextExample(MinioClient minioClient, RestTemplate restTemplate, GlobalValue globalValue) { + ToTextExample.minioClient = minioClient; + ToTextExample.restTemplate = restTemplate; + ToTextExample.globalValue = globalValue; + } + + public static String voiceToText(String fileUrl) { + try { + // 从 MinIO 获取文件 + InputStream inputStream = minioClient.getObject(globalValue.getMinioBucketName(), + fileUrl); + ByteArrayResource fileResource = FileUtil + .createByteArrayResource(IOUtils.toByteArray(inputStream), + fileUrl); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.MULTIPART_FORM_DATA); + MultiValueMap body = new LinkedMultiValueMap<>(); + body.add("file", fileResource); + body.add("model", globalValue.getModel()); + HttpEntity> requestEntity = new HttpEntity<>(body, headers); + ResponseEntity response = restTemplate + .postForEntity(globalValue.getTransitionApi(), + requestEntity, String.class); + + JSONObject result = JSONUtil.parseObj(response.getBody()); + if (result.containsKey("text")) { + String text = result.get("text").toString(); + System.out.println(text); + return text; + } else { + System.out.println("1111"); + } + } catch (Exception e) { + System.out.println("2222"); + } + return "识别发生错误!"; + } + +} \ No newline at end of file diff --git a/login/src/main/java/com/guwan/util/ToTextExample2.java b/login/src/main/java/com/guwan/util/ToTextExample2.java new file mode 100644 index 0000000..971d804 --- /dev/null +++ b/login/src/main/java/com/guwan/util/ToTextExample2.java @@ -0,0 +1,70 @@ +package com.guwan.util; + +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import com.guwan.config.GlobalValue; +import io.minio.MinioClient; +import org.apache.commons.io.IOUtils; +import org.springframework.core.io.ByteArrayResource; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.reactive.function.BodyInserters; +import org.springframework.web.reactive.function.client.WebClient; + +import java.io.InputStream; + +@Component +public class ToTextExample2 { + private static MinioClient minioClient; + private static GlobalValue globalValue; + private static WebClient webClient; + + public ToTextExample2(MinioClient minioClient, GlobalValue globalValue) { + ToTextExample2.minioClient = minioClient; + ToTextExample2.globalValue = globalValue; + + // 初始化 WebClient + ToTextExample2.webClient = WebClient.builder() + .baseUrl(globalValue.getTransitionApi()) + .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE) + .build(); + } + + public static String voiceToText(String fileUrl) { + try { + // 从 MinIO 获取文件 + InputStream inputStream = minioClient.getObject(globalValue.getMinioBucketName(), fileUrl); + ByteArrayResource fileResource = FileUtil.createByteArrayResource(IOUtils.toByteArray(inputStream), fileUrl); + + // 设置请求体 + MultiValueMap body = new LinkedMultiValueMap<>(); + body.add("file", fileResource); + body.add("model", globalValue.getModel()); + + // 发送请求并处理响应 + String response = webClient.post() + .uri("") // 这里假设是 POST 请求到基础 URL + .body(BodyInserters.fromMultipartData(body)) + .retrieve() + .bodyToMono(String.class) + .block(); // 同步调用,若需要异步处理,可以去掉 block() + + // 解析响应 JSON + JSONObject result = JSONUtil.parseObj(response); + if (result.containsKey("text")) { + String text = result.get("text").toString(); + System.out.println(text); + return text; + } else { + System.out.println("1111"); + } + } catch (Exception e) { + e.printStackTrace(); // 输出异常信息 + System.out.println("2222"); + } + return "识别发生错误!"; + } +} diff --git a/login/src/main/java/com/guwan/util/UploadUtil.java b/login/src/main/java/com/guwan/util/UploadUtil.java new file mode 100644 index 0000000..225c372 --- /dev/null +++ b/login/src/main/java/com/guwan/util/UploadUtil.java @@ -0,0 +1,64 @@ +package com.guwan.util; + +import com.guwan.common.R; +import com.guwan.config.GlobalValue; +import com.guwan.config.MinioConfig; +import io.minio.MinioClient; +import io.minio.PutObjectOptions; +import org.apache.commons.io.FilenameUtils; +import org.springframework.stereotype.Component; +import org.springframework.web.multipart.MultipartFile; + +import java.io.InputStream; +import java.util.UUID; + +@Component +public class UploadUtil { + private static MinioClient minioClient; + + private static MinioConfig minioConfig; + + public UploadUtil(MinioClient minioClient, + MinioConfig minioConfig) { + UploadUtil.minioClient = minioClient; + UploadUtil.minioConfig = minioConfig; + } + + public static String gbUpload(MultipartFile file) { + if (file.isEmpty() || file.getSize() == 0) { + System.out.println("文件不能为空"); + } + String fileName = null; + + String catalogue; + + try { + String extension = FilenameUtils.getExtension(file.getOriginalFilename()); //后缀名 + if (extension.equals("png") || extension.equals("jpg")){ + catalogue = "photo/"; + }else if (extension.equals("mp4")){ + catalogue = "video/"; + }else { + catalogue = "files/"; + } + + fileName = catalogue + "t_" + + UUID.randomUUID().toString().replace("-","") + + "." + extension; + InputStream inputStream = file.getInputStream(); + PutObjectOptions putObjectOptions = new PutObjectOptions(inputStream.available(), -1); + putObjectOptions.setContentType(file.getContentType()); + minioClient.putObject( + minioConfig.getBucketName(), fileName, inputStream, putObjectOptions); + inputStream.close(); + } catch (Exception e) { + System.out.println(e.getMessage()); + } + System.out.println("方法结束"); + + return minioConfig.getMinioEndpoint() + "/" + + minioConfig.getBucketName() + "/" + fileName; + } + + +} diff --git a/login/src/main/java/com/guwan/util/VoiceServiceClient.java b/login/src/main/java/com/guwan/util/VoiceServiceClient.java new file mode 100644 index 0000000..593f481 --- /dev/null +++ b/login/src/main/java/com/guwan/util/VoiceServiceClient.java @@ -0,0 +1,16 @@ +package com.guwan.util; + +import cn.hutool.json.JSONObject; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestPart; +import org.springframework.web.multipart.MultipartFile; + +@FeignClient(name = "voiceService", url = "http://127.0.0.1:8532") +public interface VoiceServiceClient { + + @PostMapping(value = "/v1/audio/transcriptions", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + JSONObject voiceToText(@RequestPart("file") MultipartFile file, + @RequestPart("model") String model); +} diff --git a/login/src/main/resources/application.yml b/login/src/main/resources/application.yml index ad1fe7e..c6a7c5d 100644 --- a/login/src/main/resources/application.yml +++ b/login/src/main/resources/application.yml @@ -9,12 +9,22 @@ spring: password: aliredis666 database: 1 datasource: + url: jdbc:mysql://127.0.0.1:3306/studb?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai + driver-class-name: com.mysql.cj.jdbc.Driver + username: root + password: oB54oq8cIH2SyRTFWDPc2U4g70P2Jit/E1CxoShgWBSJGqQt6vCcz0mjEO6+oPHEwQ7XH2vkMApmrHOgMv07LA== # 修改为控制台输出的password + #druid数据源配置 druid: - driver-class-name: com.mysql.cj.jdbc.Driver - url: jdbc:mysql://127.0.0.1:3306/studb - username: root - password: X1p6x5irECRCLpqsOAIjh1w4VBPK0x3AP1WNNz8xVmhGx98BANEsw2KQKmBIagzCVo6aBrveoHwWa6FA9gXcwQ== - connection-properties: config.decrypt=true;config.decrypt.key=MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAIQ/kwu9OapBDTOTUzM7CGWbbo2+qfCybUDctQcKeGptz8nhQYAzsU9JyfaDQE9RhFj7pwwD8JgB4qJWycicdXcCAwEAAQ== + filter: + # 启用Druid的过滤器配置 + config: + enabled: true + connect-properties: + # 启用Druid的连接属性解密功能 + config.decrypt: true + config.decrypt.key: MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKEHrmL+L+Q8yRUA8BKnZVsxXHnVw2b/Y80f0U4r4P9YkQs+gJjtP0AjMpXpW9muJq+mxzwKHqRUJeO0JKfpF/ECAwEAAQ== # 控制台输出的publicKey + + servlet: multipart: @@ -53,6 +63,9 @@ global: accessKey: admin secretKey: admin123456 bucketName: cuwan + faster-whisper: + model: "/model/faster-whisper-small/" + transitionApi: "http://127.0.0.1:8532/v1/audio/transcriptions" file_path: static-locations: \Guwan\ diff --git a/old-face/pom.xml b/old-face/pom.xml index 5cdd500..af36ca9 100644 --- a/old-face/pom.xml +++ b/old-face/pom.xml @@ -12,8 +12,8 @@ old-face - 21 - 21 + 17 + 17 UTF-8 diff --git a/old-nacos/pom.xml b/old-nacos/pom.xml index d7fa62b..3f5a028 100644 --- a/old-nacos/pom.xml +++ b/old-nacos/pom.xml @@ -12,8 +12,8 @@ old-nacos - 21 - 21 + 17 + 17 UTF-8 diff --git a/output.mp3 b/output.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..e41875ec4808bac914f2c8e941f35a7dfdf539f6 GIT binary patch literal 14256 zcmeI2Wl&sA+n@&x5Zq;u!98ejx53>dI0SbML4rdF?!k3}1a~I{cL+{^;1&Xb1evoT z@9tJT_3q#Oem$pZ&P?~2s=4Os?z`{qYT(j(5Cj4tLI2!9DpIO)y1Kf5-$FvW%rbt3 zph@*2Lj*}FdbtF)+~|NJ#^{JB-`A}zqkVShS7;CnLM3nT_n6j3&ZuC8SKHQYAW%Ft z_t5WF)bBJbAdJwq;{3z+cwan2(eaRa2rfg=W#aOJeUYEM1K~hHlWrg~94=8Yx-9B@ zoDe#$UhJr2;1AEM|HHGBXDtB&;Uc_!)7>wnIc-vrDh~t6LY36WkrJEvX+N2XYh?YH zivfd6g*9F~qQmx`JRq&=!gD_(wmoL+PVhSq7T(T@UH|(R=xtv6*qqcSt9z|ptKmAQTFP`5&;}90K2we8tQgKLZjCtg_r4E?6x*}Eh zv;&P7o@)Ef{J`)_O-@j(0Uet;>XVyzlV+$pLJPCoQbLptAH)dVf?oao9qQ$$P^?Rj zEiPX{OOegRdY`sNVqmdx$0iur8NV3XJp!K4y!u;t}f_q;v78>YVQSIWCe3Av|IQ zX%7_c&tU-32C%!EZJOQ%-Cir zi7PUx1!$TWEp(~16N8QPp#1FK>xS^hkVstIQfc5C{eAw}SV!m6d?KE6o4B~BVbP#B z-yYhOfpg%`bzf#ap$x2Np$+?HyjXtu$U_P#;mHKyE^om;93&uzt)=uF=38|gW;|4{ z+MS#lxRd*&F)J812EMjT+&r(l$F2=~H?$jv!fOF>eD>=pMaq+~>WtK>bW--w6JCxD zqydx@b|EuSW~I*Nf{W4hdtcIGrW5Zk%YZ52vz<7Ry6T{W;cEVqAcv~fSl_4+STa`# z&%C`XODA?k1muy25JJz>1D4V@bveQtD)M%9Wcl2+P_l6Y0P}lxzAt%dOZ21Sy?Y}k>oO>s$s2kO~?}b+g>zJ zR~GO6!{@N0tR5zYeC(6*I7tRE#aB;WzSF!BA=Zqj!p>|w%TujbP}^F9^~>S=^B0Q7 z`l8`R1o~gmQ7@;(4_a8R%^Ek|2A_7zdoCTF*#Hk8igm|$yP^ka!SSo7g>1!*B^IH? zo7x<$Ylj#2jGOs23z07~HiN4hB2$|6C^0Jp3y>rs9RKknwEg3LRDR=3aElB2{3#Nq z8y~t4RlLel#wDn}xWEWA)knFV89#{(oEd{!4{q0a6`gZ{_@~c_+w1o?=5KzY>N#d?eHf=M7*8*dQv;3JG@3d&R2lT zXQL45$1tj_I2=KEZOe}T`Bxc#jG3`koA}&BH+(jMi12+?N=R<5o0|a(`E4^h5-*8) z|2_k`GO)cxgux5czh`F9Yi!$e&dD(Uyc^#tiH6PRz~YcuLT*xi=qic}iE?vEk3ui- zN!xn#!vuz~Zoub;rg;nO>uV7zC~T8A+C+^SQOtAdjoBTZL#I!+KiI_J3C7t3^N12u zVBY1k{?ZKLu{Gi%zxqP#R97%! z!xJNpipz4+I-EZ~KZ}>e!`O0&jr*q7S$s(GFr~w$SFiGEp1qfTwfT$9j$gnUf>x0i zZwT{G!fbZRKrC#^4c0kQ=wy{*sS>-6qS@bgs6>%;v~Big)JXir?^jik@d|IGzuZ?S z)9S?a0Dy6-9LWa9)$Lu%8=Ke&9Mq!;UpAK)HPttU{um$17vjS4BW#Jva9+KmJ8r$u zK`@6prAg<)2;m{=eUi=Qy$UDO*N8&9f^Lh?U-V%lC`*ett-kut2lqMCiB*Jhqn^g^}$<_W-KiXnC-Lw9J5O>pbn*oVAmEqG5%o&Lxpz!8#LN;xihLCXs_MWz?g5gkxFnIzCKYs0Y1c?0jld~idxM22I=KO^|1(# zJf2{~{+M86Qc%%WjnOx?H<>fG(g1xbl%8rEr2;Gj-aX1-U9ck&$QeJv*n#dd+j>tC%-cVhIhJv#KhIG6dA3zepMK z1vE1K97PAbVj|zq`75!{s>IlRo!(&%mY6Ba+6^eLsaoAQl+b+S3Fp%hhP}u%0AWW} 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 - 21 - 21 + 17 + 17 UTF-8 @@ -32,6 +32,7 @@ + org.projectlombok lombok @@ -48,11 +49,22 @@ spring-boot-starter-data-redis - + org.springframework.boot spring-boot-starter-test - test + 3.1.1 + + + org.slf4j + slf4j-api + + + + + junit + junit + ${junit.version} @@ -62,41 +74,52 @@ 2.5.0 - cn.hutool hutool-all 5.8.32 - + mysql mysql-connector-java 8.0.33 - + + + + com.baomidou mybatis-plus-spring-boot3-starter 3.5.7 - - - org.apache.shardingsphere - shardingsphere-jdbc-core - 5.4.1 + com.github.pagehelper + pagehelper + 6.1.0 - - - com.zaxxer - HikariCP - 5.0.1 - @@ -105,4 +128,5 @@ + \ No newline at end of file diff --git a/qrcode.png b/qrcode.png new file mode 100644 index 0000000000000000000000000000000000000000..970739f08acc5faffbf9b7350c0cb17de95c9b9f GIT binary patch literal 5002 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 literal 0 HcmV?d00001 diff --git a/readme.md b/readme.md index 1d773c2..97392d0 100644 --- a/readme.md +++ b/readme.md @@ -6,4 +6,14 @@ public class Hello { System.out.println("Hello World!"); } } -``` \ No newline at end of file +``` + + +基于token的分布式登录 + +分库分表 + +虹软人脸 + + + diff --git a/ss-Demo/pom.xml b/ss-Demo/pom.xml index a4e574b..a2366b2 100644 --- a/ss-Demo/pom.xml +++ b/ss-Demo/pom.xml @@ -11,9 +11,26 @@ ss-Demo + + + + + org.apache.shardingsphere + shardingsphere-jdbc-core-spring-boot-starter + 5.2.1 + + + org.slf4j + slf4j-api + + + + + + - 21 - 21 + 17 + 17 UTF-8 diff --git a/ss-Demo/src/main/java/com/guwan/SsDemoApplication.java b/ss-Demo/src/main/java/com/guwan/SsDemoApplication.java index ea72d63..3dea195 100644 --- a/ss-Demo/src/main/java/com/guwan/SsDemoApplication.java +++ b/ss-Demo/src/main/java/com/guwan/SsDemoApplication.java @@ -10,6 +10,7 @@ import org.springframework.transaction.annotation.EnableTransactionManagement; @SpringBootApplication @EnableAsync @EnableTransactionManagement + public class SsDemoApplication { public static void main(String[] args) { diff --git a/ss-Demo/src/main/java/com/guwan/controller/OrderController.java b/ss-Demo/src/main/java/com/guwan/controller/OrderController.java index 2dfebe3..8e57ac4 100644 --- a/ss-Demo/src/main/java/com/guwan/controller/OrderController.java +++ b/ss-Demo/src/main/java/com/guwan/controller/OrderController.java @@ -2,25 +2,31 @@ package com.guwan.controller; import com.guwan.dal.dataobject.Order; -import com.guwan.service.OrderService; +import com.guwan.dal.mysql.OrderMapper; +import com.guwan.service.IOrderService; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.*; - -import java.util.List; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/orders") public class OrderController { @Autowired - private OrderService orderService; + private IOrderService orderService; - @PostMapping - public void createOrder(@RequestBody Order order) { - orderService.createOrder(order); + @Autowired + private OrderMapper orderMapper; + + @GetMapping + public void createOrder() { + System.out.println("orderService = "); + + for (int i = 1; i < 100; i++) { + Order order = new Order(i, i, i); + orderMapper.insert(order); + //orderService.save(order); + } } - @GetMapping("/{userId}") - public List getOrders(@PathVariable Long userId) { - return orderService.getOrdersByUserId(userId); - } } diff --git a/ss-Demo/src/main/java/com/guwan/dal/dataobject/Order.java b/ss-Demo/src/main/java/com/guwan/dal/dataobject/Order.java index be9db25..9107dd4 100644 --- a/ss-Demo/src/main/java/com/guwan/dal/dataobject/Order.java +++ b/ss-Demo/src/main/java/com/guwan/dal/dataobject/Order.java @@ -1,10 +1,25 @@ package com.guwan.dal.dataobject; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.ToString; +@NoArgsConstructor +@AllArgsConstructor @Data + +@TableName("tb_order") public class Order { - private Long orderId; - private Long userId; - private String orderContent; -} + + + private Integer orderId; + + private Integer sellerId; + + private Integer buyerId; + +} \ No newline at end of file diff --git a/ss-Demo/src/main/java/com/guwan/dal/mysql/OrderMapper.java b/ss-Demo/src/main/java/com/guwan/dal/mysql/OrderMapper.java index 4c03984..f50db9c 100644 --- a/ss-Demo/src/main/java/com/guwan/dal/mysql/OrderMapper.java +++ b/ss-Demo/src/main/java/com/guwan/dal/mysql/OrderMapper.java @@ -1,15 +1,14 @@ package com.guwan.dal.mysql; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.guwan.dal.dataobject.Order; import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; - -import java.util.List; @Mapper -public interface OrderMapper { - void insertOrder(Order order); +public interface OrderMapper extends BaseMapper { + + + - List selectOrdersByUserId(@Param("userId") Long userId); } diff --git a/ss-Demo/src/main/java/com/guwan/service/IOrderService.java b/ss-Demo/src/main/java/com/guwan/service/IOrderService.java new file mode 100644 index 0000000..50382db --- /dev/null +++ b/ss-Demo/src/main/java/com/guwan/service/IOrderService.java @@ -0,0 +1,9 @@ +package com.guwan.service; + + +import com.baomidou.mybatisplus.extension.service.IService; +import com.guwan.dal.dataobject.Order; + +public interface IOrderService extends IService { + +} diff --git a/ss-Demo/src/main/java/com/guwan/service/OrderService.java b/ss-Demo/src/main/java/com/guwan/service/OrderService.java deleted file mode 100644 index a0fffc9..0000000 --- a/ss-Demo/src/main/java/com/guwan/service/OrderService.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.guwan.service; - - -import com.guwan.dal.dataobject.Order; -import com.guwan.dal.mysql.OrderMapper; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import java.util.List; - -@Service -public class OrderService { - @Autowired - private OrderMapper orderMapper; - - public void createOrder(Order order) { - orderMapper.insertOrder(order); - } - - public List getOrdersByUserId(Long userId) { - return orderMapper.selectOrdersByUserId(userId); - } -} diff --git a/ss-Demo/src/main/java/com/guwan/service/OrderServiceImpl.java b/ss-Demo/src/main/java/com/guwan/service/OrderServiceImpl.java new file mode 100644 index 0000000..80c6938 --- /dev/null +++ b/ss-Demo/src/main/java/com/guwan/service/OrderServiceImpl.java @@ -0,0 +1,13 @@ +package com.guwan.service; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.guwan.dal.dataobject.Order; +import com.guwan.dal.mysql.OrderMapper; +import org.springframework.stereotype.Service; + +@Service +public class OrderServiceImpl extends ServiceImpl implements IOrderService{ + + + +} diff --git a/ss-Demo/src/main/resources/application.yml b/ss-Demo/src/main/resources/application.yml index 29e1a89..3c1997a 100644 --- a/ss-Demo/src/main/resources/application.yml +++ b/ss-Demo/src/main/resources/application.yml @@ -1,36 +1,68 @@ +server: + port: 8080 + tomcat: + uri-encoding: UTF-8 + spring: - profiles: - active: dev application: - name: sharging-jdbc-demo + name: boot-shard + # 分库分表配置 shardingsphere: datasource: - names: master,slave1 - master: - type: com.zaxxer.hikari.HikariDataSource # 数据源类型 - url: jdbc:mysql://localhost:3306/course_master_db # 数据库连接地址 - username: root # 用户名 - password: 123456 # 密码 - driver-class-name: com.mysql.jdbc.Driver # 数据库驱动 - slave1: - type: com.zaxxer.hikari.HikariDataSource # 数据源类型 - url: jdbc:mysql://localhost:3306/course_db # 数据库连接地址 - username: root # 用户名 - password: 123456 # 密码 - driver-class-name: com.mysql.jdbc.Driver # 数据库驱动 + # 默认数据源 + sharding: + default-data-source-name: db_master + names: db_master,db_0,db_1 + db_master: + type: com.zaxxer.hikari.HikariDataSource + driver-class-name: com.mysql.cj.jdbc.Driver + jdbc-url: jdbc:mysql://localhost:3306/shard_db?useUnicode=true&characterEncoding=UTF8&zeroDateTimeBehavior=convertToNull&useSSL=true + username: root + password: 123456 + db_0: + type: com.zaxxer.hikari.HikariDataSource + driver-class-name: com.mysql.cj.jdbc.Driver + jdbc-url: jdbc:mysql://localhost:3306/shard_db_0?useUnicode=true&characterEncoding=UTF8&zeroDateTimeBehavior=convertToNull&useSSL=true + username: root + password: 123456 + db_1: + type: com.zaxxer.hikari.HikariDataSource + driver-class-name: com.mysql.cj.jdbc.Driver + jdbc-url: jdbc:mysql://localhost:3306/shard_db_1?useUnicode=true&characterEncoding=UTF8&zeroDateTimeBehavior=convertToNull&useSSL=true + username: root + password: 123456 rules: - readwrite-splitting: - data-sources: - mds: #名字自定义 - type: static #类型 静态获取 + sharding: + tables: + # tb_order逻辑 + tb_order: + actual-data-nodes: db_${0..1}.tb_order_${0..2} + # tb_order库路由 + database-strategy: + standard: + sharding-column: order_id + sharding-algorithm-name: database_inline + # tb_order表路由 + table-strategy: + standard: + sharding-column: order_id + sharding-algorithm-name: table_inline + sharding-algorithms: + # tb_order库路由算法 + database_inline: + type: INLINE props: - auto-aware-data-source-name: master - write-data-source-name: master - read-data-source-names: slave1 - load-balancer-name: read-random #读写分离规则自定义命名 - load-balancers: - read-random: - type: ROUND_ROBIN # 轮询负载均衡 + algorithm-expression: db_${order_id % 2} + # tb_order表路由算法 + table_inline: + type: INLINE + props: + algorithm-expression: tb_order_${order_id % 3} props: - sql-show: true # 是否打印sql - sql-simple: true # 打印简单的sql + sql-show: true + sql-comment-parse-enabled: true + +# mybatis 配置 +mybatis-plus: + configuration: + map-underscore-to-camel-case: true diff --git a/ss-Demo/src/main/resources/com/guwan/dal/mysql/OrderMapper.xml b/ss-Demo/src/main/resources/com/guwan/dal/mysql/OrderMapper.xml index db1fd38..6ea1b9c 100644 --- a/ss-Demo/src/main/resources/com/guwan/dal/mysql/OrderMapper.xml +++ b/ss-Demo/src/main/resources/com/guwan/dal/mysql/OrderMapper.xml @@ -1,12 +1,7 @@ - - - - INSERT INTO t_order (order_id, user_id, order_content) VALUES (#{orderId}, #{userId}, #{orderContent}) - + + - - + + + \ No newline at end of file