From 51c27865f0a5707a8a81ffd59ba77478ac67957b Mon Sep 17 00:00:00 2001 From: wangxiangshun Date: Sat, 4 Oct 2025 13:56:50 +0800 Subject: [PATCH] =?UTF-8?q?AI=20=E4=B8=9A=E5=8A=A1=E9=80=BB=E8=BE=91?= =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/uiDesigner.xml | 124 +++++ .../web/controller/ai/AiCommonController.java | 56 +++ .../src/main/resources/application-dev.yml | 167 +++++++ .../src/main/resources/application-druid.yml | 24 +- .../src/main/resources/application.yml | 14 - .../target/classes/application-druid.yml | 34 +- vetti-admin/target/classes/application.yml | 14 - .../classes/i18n/messages_en_US.properties | 450 ----------------- .../classes/i18n/messages_zh_CN.properties | 451 ------------------ .../com/vetti/common/ai/ElevenLabsClient.java | 199 -------- .../com/vetti/common/ai/WapiAiClient.java | 159 ------ .../com/vetti/common/ai/WhisperClient.java | 116 ----- .../ai/elevenLabs/ElevenLabsClient.java | 124 +++++ .../ai/{ => elevenLabs/vo}/FineTuning.java | 5 +- .../vetti/common/ai/elevenLabs/vo/Voice.java | 45 ++ .../ai/elevenLabs/vo/VoiceSettings.java | 25 + .../ai/elevenLabs/vo/VoicesResponse.java | 18 + .../vetti/common/ai/gpt/ChatGPTClient.java | 138 ++++++ .../common/ai/whisper/WhisperClient.java | 100 ++++ .../framework/config/SecurityConfig.java | 2 +- 20 files changed, 845 insertions(+), 1420 deletions(-) create mode 100644 .idea/uiDesigner.xml create mode 100644 vetti-admin/src/main/java/com/vetti/web/controller/ai/AiCommonController.java create mode 100644 vetti-admin/src/main/resources/application-dev.yml delete mode 100644 vetti-common/src/main/java/com/vetti/common/ai/ElevenLabsClient.java delete mode 100644 vetti-common/src/main/java/com/vetti/common/ai/WapiAiClient.java delete mode 100644 vetti-common/src/main/java/com/vetti/common/ai/WhisperClient.java create mode 100644 vetti-common/src/main/java/com/vetti/common/ai/elevenLabs/ElevenLabsClient.java rename vetti-common/src/main/java/com/vetti/common/ai/{ => elevenLabs/vo}/FineTuning.java (87%) create mode 100644 vetti-common/src/main/java/com/vetti/common/ai/elevenLabs/vo/Voice.java create mode 100644 vetti-common/src/main/java/com/vetti/common/ai/elevenLabs/vo/VoiceSettings.java create mode 100644 vetti-common/src/main/java/com/vetti/common/ai/elevenLabs/vo/VoicesResponse.java create mode 100644 vetti-common/src/main/java/com/vetti/common/ai/gpt/ChatGPTClient.java create mode 100644 vetti-common/src/main/java/com/vetti/common/ai/whisper/WhisperClient.java diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml new file mode 100644 index 0000000..2b63946 --- /dev/null +++ b/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/vetti-admin/src/main/java/com/vetti/web/controller/ai/AiCommonController.java b/vetti-admin/src/main/java/com/vetti/web/controller/ai/AiCommonController.java new file mode 100644 index 0000000..e2c090a --- /dev/null +++ b/vetti-admin/src/main/java/com/vetti/web/controller/ai/AiCommonController.java @@ -0,0 +1,56 @@ +package com.vetti.web.controller.ai; + +import com.vetti.common.ai.elevenLabs.ElevenLabsClient; +import com.vetti.common.ai.gpt.ChatGPTClient; +import com.vetti.common.core.controller.BaseController; +import com.vetti.common.core.domain.AjaxResult; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * AI 共通测试接口处理 + * + * @author wangxiangshun + */ +@Api(tags ="AI 共通测试接口处理") +@RestController +@RequestMapping("/aiCommon") +public class AiCommonController extends BaseController +{ + @Autowired + private ElevenLabsClient elevenLabsClient; + + + @Autowired + private ChatGPTClient chatGPTClient; + + /** + * 进行文本转语音处理 + */ + @ApiOperation("进行文本转语音处理") + @GetMapping("/handleTextToVice") + public AjaxResult handleTextToVice() + { + elevenLabsClient.handleTextToVoice("我只是测试的文本转换成语音","/Users/wangxiangshun/Desktop/临时文件/output.mp3"); + return success(); + } + + /** + * AI 聊天 + */ + @ApiOperation("AI 聊天") + @GetMapping("/handleAiChat") + public AjaxResult handleAiChat() + { + String resultMsg = chatGPTClient.handleAiChat("你好,我叫wangxiangshun"); + return AjaxResult.success(resultMsg); + } + + + + +} diff --git a/vetti-admin/src/main/resources/application-dev.yml b/vetti-admin/src/main/resources/application-dev.yml new file mode 100644 index 0000000..df0fd10 --- /dev/null +++ b/vetti-admin/src/main/resources/application-dev.yml @@ -0,0 +1,167 @@ + +# 开发环境配置 +server: + # 服务器的HTTP端口,默认为8080 + port: 8080 + servlet: + # 应用的访问路径 + context-path: / + tomcat: + # tomcat的URI编码 + uri-encoding: UTF-8 + # 连接数满后的排队数,默认为100 + accept-count: 1000 + threads: + # tomcat最大线程数,默认为200 + max: 800 + # Tomcat启动初始化的线程数,默认值10 + min-spare: 100 + +# 日志配置 +logging: + level: + com.vetti: debug + org.springframework: warn + pathUrl: ./logs/ + +# 用户配置 +user: + password: + # 密码最大错误次数 + maxRetryCount: 5 + # 密码锁定时间(默认10分钟) + lockTime: 10 + +# 数据源配置 +spring: + datasource: + type: com.alibaba.druid.pool.DruidDataSource + driverClassName: com.mysql.cj.jdbc.Driver + druid: + # 主库数据源 + master: + url: jdbc:mysql://13.211.168.80:3306/vetti_service?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 + username: vetti_service + password: Hotake@2025 + # 从库数据源 + slave: + # 从数据源开关/默认关闭 + enabled: false + url: + username: + password: + # 初始连接数 + initialSize: 5 + # 最小连接池数量 + minIdle: 10 + # 最大连接池数量 + maxActive: 20 + # 配置获取连接等待超时的时间 + maxWait: 60000 + # 配置连接超时时间 + connectTimeout: 30000 + # 配置网络超时时间 + socketTimeout: 60000 + # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 + timeBetweenEvictionRunsMillis: 60000 + # 配置一个连接在池中最小生存的时间,单位是毫秒 + minEvictableIdleTimeMillis: 300000 + # 配置一个连接在池中最大生存的时间,单位是毫秒 + maxEvictableIdleTimeMillis: 900000 + # 配置检测连接是否有效 + validationQuery: SELECT 1 FROM DUAL + testWhileIdle: true + testOnBorrow: false + testOnReturn: false + webStatFilter: + enabled: true + statViewServlet: + enabled: true + # 设置白名单,不填则允许所有访问 + allow: + url-pattern: /druid/* + # 控制台管理用户名和密码 + login-username: ruoyi + login-password: 123456 + filter: + stat: + enabled: true + # 慢SQL记录 + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: true + wall: + config: + multi-statement-allow: true + # redis 配置 + redis: + # 地址 + host: localhost + # 端口,默认为6379 + port: 6379 + # 数据库索引 + database: 0 + # 密码 + password: Hamkke@2021 + # 连接超时时间 + timeout: 10s + lettuce: + pool: + # 连接池中的最小空闲连接 + min-idle: 0 + # 连接池中的最大空闲连接 + max-idle: 8 + # 连接池的最大数据库连接数 + max-active: 8 + # #连接池最大阻塞等待时间(使用负值表示没有限制) + max-wait: -1ms +fs: + minio: + endpoint: http://test.hotake.cn:19000 # MinIO 服务地址 + access-key: minioadmin # 访问密钥(替换为你的 Access Key) + secret-key: minioadmin # 密钥(替换为你的 Secret Key) + max-file-size: 104857600 #字节(Byte) + bucket-name.: # 存储桶名称(提前在 MinIO 控制台创建) + system-fs: system-fs + +# Twilio SendGrid 配置 +twilio: + sendgrid: + #你的SendGrid API Key + api-key: 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 + #已验证的发送邮箱地址 + from-email: noreply@routez.app + #你的应用名称 + from-name: RouteZ + template-ids: + routez-verification-code: d-321fee8a85704983849eb1f69313ae24 +verification: + code: + email: + # 验证码长度 + length: 5 + # 验证码过期时间(分钟) + expiration-minutes: 10 +# 文本转语音 +elevenLabs: + baseUrl: https://api.elevenlabs.io/v1 + apiKey: sk_5240d8f56cb1eb5225fffcf903f62479884d1af5b3de6812 + modelId: eleven_monolingual_v1 +# 语音转文本 +whisper: + apiUrl: https://api.openai.com/v1/audio/transcriptions + model: whisper-1 + apiKey: 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 + language: zh + +# AI 聊天 +chatGpt: + apiKey: + apiUrl: https://api.openai.com/v1/chat/completions + model: gpt-3.5-turbo + role: user + + +http: + client: + connect-timeout-seconds: 10 diff --git a/vetti-admin/src/main/resources/application-druid.yml b/vetti-admin/src/main/resources/application-druid.yml index 7973379..5006265 100644 --- a/vetti-admin/src/main/resources/application-druid.yml +++ b/vetti-admin/src/main/resources/application-druid.yml @@ -123,6 +123,7 @@ fs: max-file-size: 104857600 #字节(Byte) bucket-name.: # 存储桶名称(提前在 MinIO 控制台创建) system-fs: system-fs + # Twilio SendGrid 配置 twilio: sendgrid: @@ -141,12 +142,25 @@ verification: length: 5 # 验证码过期时间(分钟) expiration-minutes: 10 +# 文本转语音 +elevenLabs: + baseUrl: https://api.elevenlabs.io/v1 + apiKey: sk_5240d8f56cb1eb5225fffcf903f62479884d1af5b3de6812 + modelId: eleven_monolingual_v1 +# 语音转文本 +whisper: + apiUrl: https://api.openai.com/v1/audio/transcriptions + model: whisper-1 + apiKey: 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 + language: zh + +# AI 聊天 +chatGpt: + apiKey: + apiUrl: https://api.openai.com/v1/chat/completions + model: gpt-3.5-turbo + role: user -here-map: - api-key: q1gsOSZ899P8dVaoW2HZXq40W-AqCwB6iON5tw7-sqI - geocoding-api-url: https://geocode.search.hereapi.com/v1/geocode - reverse-geocoding-api-url: https://revgeocode.search.hereapi.com/v1/revgeocode - router-api-url: https://router.hereapi.com/v8/routes http: client: diff --git a/vetti-admin/src/main/resources/application.yml b/vetti-admin/src/main/resources/application.yml index fdaa0b9..7f2213d 100644 --- a/vetti-admin/src/main/resources/application.yml +++ b/vetti-admin/src/main/resources/application.yml @@ -78,17 +78,3 @@ xss: excludes: /system/notice # 匹配链接 urlPatterns: /system/*,/monitor/*,/tool/* - -# 安全配置 -security: - # 不校验白名单 - ignore: - whites: - - /v1/app/system/i18nGain/getInfo - - /v1/app/verificationEmail/send - - /v1/app/verificationEmail/verify - - /v1/app/auth/appLogin - - /v1/app/auth/appRegister - - /v1/app/auth/appResetPassword - - /v1/app/auth/getUserInfoByEmail - - /v1/app/verificationEmail/register/send \ No newline at end of file diff --git a/vetti-admin/target/classes/application-druid.yml b/vetti-admin/target/classes/application-druid.yml index 6da9a04..5006265 100644 --- a/vetti-admin/target/classes/application-druid.yml +++ b/vetti-admin/target/classes/application-druid.yml @@ -40,9 +40,9 @@ spring: druid: # 主库数据源 master: - url: jdbc:mysql://test.hotake.cn:13306/htk-vetti?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 - username: root - password: Hamkke@2021 + url: jdbc:mysql://13.211.168.80:3306/vetti_service?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 + username: vetti_service + password: Hotake@2025 # 从库数据源 slave: # 从数据源开关/默认关闭 @@ -96,13 +96,13 @@ spring: # redis 配置 redis: # 地址 - host: localhost + host: 127.0.0.1 # 端口,默认为6379 port: 6379 # 数据库索引 database: 0 # 密码 - password: Hamkke@2021 + password: # 连接超时时间 timeout: 10s lettuce: @@ -123,6 +123,7 @@ fs: max-file-size: 104857600 #字节(Byte) bucket-name.: # 存储桶名称(提前在 MinIO 控制台创建) system-fs: system-fs + # Twilio SendGrid 配置 twilio: sendgrid: @@ -141,12 +142,25 @@ verification: length: 5 # 验证码过期时间(分钟) expiration-minutes: 10 +# 文本转语音 +elevenLabs: + baseUrl: https://api.elevenlabs.io/v1 + apiKey: sk_5240d8f56cb1eb5225fffcf903f62479884d1af5b3de6812 + modelId: eleven_monolingual_v1 +# 语音转文本 +whisper: + apiUrl: https://api.openai.com/v1/audio/transcriptions + model: whisper-1 + apiKey: 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 + language: zh + +# AI 聊天 +chatGpt: + apiKey: + apiUrl: https://api.openai.com/v1/chat/completions + model: gpt-3.5-turbo + role: user -here-map: - api-key: q1gsOSZ899P8dVaoW2HZXq40W-AqCwB6iON5tw7-sqI - geocoding-api-url: https://geocode.search.hereapi.com/v1/geocode - reverse-geocoding-api-url: https://revgeocode.search.hereapi.com/v1/revgeocode - router-api-url: https://router.hereapi.com/v8/routes http: client: diff --git a/vetti-admin/target/classes/application.yml b/vetti-admin/target/classes/application.yml index fdaa0b9..7f2213d 100644 --- a/vetti-admin/target/classes/application.yml +++ b/vetti-admin/target/classes/application.yml @@ -78,17 +78,3 @@ xss: excludes: /system/notice # 匹配链接 urlPatterns: /system/*,/monitor/*,/tool/* - -# 安全配置 -security: - # 不校验白名单 - ignore: - whites: - - /v1/app/system/i18nGain/getInfo - - /v1/app/verificationEmail/send - - /v1/app/verificationEmail/verify - - /v1/app/auth/appLogin - - /v1/app/auth/appRegister - - /v1/app/auth/appResetPassword - - /v1/app/auth/getUserInfoByEmail - - /v1/app/verificationEmail/register/send \ No newline at end of file diff --git a/vetti-admin/target/classes/i18n/messages_en_US.properties b/vetti-admin/target/classes/i18n/messages_en_US.properties index 35f2dbf..da788d5 100644 --- a/vetti-admin/target/classes/i18n/messages_en_US.properties +++ b/vetti-admin/target/classes/i18n/messages_en_US.properties @@ -44,453 +44,3 @@ systemR10001 = Operation Successful # manager.页面,字段 = User Manager VerificationEmailTiTle = Your verification code VerificationEmailContent = Your verification code is: {0}, valid for {1} minutes. - -#APP端 -AppSystemPassWordTip10001 = Two Inputs Are Inconsistent -AppSystemPassWordTip10002 = Cannot Include Your Name Or Email -AppSystemPassWordTip10003 = Contains At Least 8 Characters -AppSystemPassWordTip10004 = Contains Symbols Or Numbers - -OnboardingOnboarding2ActionSkip = Skip -OnboardingOnboarding2TitleOne = Smart, fast routes every time. -OnboardingOnboarding2InfoOne = Optimised Navigation to get you there faster and safer. -OnboardingOnboarding2ButtonGetStarted = Get Started -OnboardingOnboarding3ActionSkip = Skip -OnboardingOnboarding3TitleOne = Stay compliant, drive easy. -OnboardingOnboarding3InfoOne = Seamless EWD & CoR compliance to keep you on track. -OnboardingOnboarding3ButtonGetStarted = Get Started -OnboardingGetStartedTitleOne = Maximise earnings, minimise hassle. -OnboardingGetStartedInfoOne = Sign up or login to see what happening near you -OnboardingGetStartedButtonEamil = Continue with Email -OnboardingGetStartedButtonGoogle = Continue with Google -OnboardingGetStartedButtonApple = Continue with Apple -AuthenticationLoginEmptyStateTitleOne = Sign in to Routez -AuthenticationLoginEmptyStateInfoOne = Welcome back! Please enter yout details. -AuthenticationLoginEmptyStatePlaceholderEamil = Email -AuthenticationLoginEmptyStatePlaceholderPassword = Password -AuthenticationLoginEmptyStateInfoTwo = Forgot password? -AuthenticationLoginEmptyStateActionReset = Reset it -AuthenticationLoginEmptyStateButtonSignin = Sign in -AuthenticationLoginEmptyStateButtonGoogle = Sign in with Google -AuthenticationLoginEmptyStateButtonApple = Sign in with Apple -AuthenticationLoginEmptyStateInfoThree = Don’t have and account? -AuthenticationLoginEmptyStateActionSignup = Sign Up -AuthenticationSignUpEmptyStateTitleOne = Sign Up -AuthenticationSignUpEmptyStatePlaceholderFullname = Fullname -AuthenticationSignUpEmptyStatePlaceholderEamil = Email -AuthenticationSignUpEmptyStatePlaceholderPassword = Password -AuthenticationSignUpEmptyStatePlaceholderFullnameTips = Please Check Fullname -AuthenticationSignUpEmptyStatePlaceholderEamilTips = Please Check Email -AuthenticationSignUpEmptyStatePlaceholderPasswordTips = Please Check Password -AuthenticationSignUpEmptyStateInfoOne = By signing up, you agree to our -AuthenticationSignUpEmptyStateLegalService = Terms of Service -AuthenticationSignUpEmptyStateInfoTwo = and -AuthenticationSignUpEmptyStateLegalpolicy = Privacy Policy. -AuthenticationSignUpEmptyStateButtonSignup = Sign Up -AuthenticationSignUpEmptyStateButtonGoogle = Sign in with Google -AuthenticationSignUpEmptyStateButtonApple = Sign in with Apple -AuthenticationSignUpEmptyStateInfoThree = Already have and account? -AuthenticationSignUpEmptyStateActionSignin = Sign in -AuthenticationEnterVerificationCodeTitleOne = Almost there! -AuthenticationEnterVerificationCodeInfoOne = Check your email inbox and input the verification code to verify your account. -AuthenticationEnterVerificationCodeButtonContinue = Continue -AuthenticationEnterVerificationCodeButtonResend = Resend Code -AuthenticationForgotPasswordTitleOne = Can’t sign in? -AuthenticationForgotPasswordInfoOne = Enter the email associated with your account, and Carline will send you a link to reset your password. -AuthenticationForgotPasswordPlaceholderEamil = Email -AuthenticationForgotPasswordButtonReset = Reset Password -AuthenticationForgotPasswordButtonReturn = Return to Sign In -AuthenticationEnterNewPasswordTitleOne = Create your new password -AuthenticationEnterNewPasswordInfoOne = Your new password must be different from previous password. -AuthenticationEnterNewPasswordPlaceholderPassword = Password -AuthenticationEnterNewPasswordPlaceholderRepeat = Password -AuthenticationEnterNewPasswordAlertOne = Must not contain your name or email -AuthenticationEnterNewPasswordAlertTwo = At least 8 characters -AuthenticationEnterNewPasswordAlertThree = Contains a symbol or a number -AuthenticationEnterNewPasswordButtonCreate = Create New Password -DriverMyProfileTitleOne = Profile -DriverMyProfileButtonMyProfile = My Profile -DriverMyProfileTitleTwo = General -DriverMyProfileActionOne = Appointment -DriverMyProfileActionTwo = Test Drive -DriverMyProfileActionThree = My vouchers -DriverMyProfileTitleThree = Browse history -DriverMyProfileNavMome = Home -DriverMyProfileNavFavourite = Map -DriverMyProfileNavMessage = Fleet -DriverMyProfileNavProfile = Profile -DriverPreTripCheckTitleOne = Pre-Trip Check -DriverPreTripCheckTitleTwo = Next Service -DriverPreTripCheckButtonStart = Start Check -DriverPreTripCheckButtonOne = Check DOne -DriverPreTripCheckButtonFinish = Finish Check -DriverPreTripCheckButtonStartfull = Start Full Inspection -DriverPreTripCheckListTitleOne = Pre-Trip Inspection -DriverPreTripCheckListInfoOne = Complete -DriverPreTripCheckDetailInfoOne = Inspection Point -DriverPreTripCheckDetailTitleOne = Required Specifications -DriverPreTripCheckDetailButtonFail = Fail -DriverPreTripCheckDetailButtonPass = Pass -DriverPreTripCheckDetailLabelOne = Issue Details -DriverPreTripCheckDetailTitleTwo = Photos -DriverPreTripCheckDetailButtonAdd = Add Photo -DriverPreTripCheckDetailButtonSubmit = Submit -DriverPreTripCheckHistoryTitleOne = Hours of Service -DriverPreTripCheckHistoryInfoOne = Last Break -DriverPreTripCheckHistoryInfoTwo = Next Required -DriverPreTripCheckHistoryTitleTwo = Current Route -DriverPreTripCheckHistoryTitleThree = Current Vehicle -DriverPreTripCheckHistoryButtonStartInspection = Start Inspection -DriverPreTripCheckHistoryButtonViewDetails = View Details -DriverPreTripCheckHistoryTitleFour = Recent Inspections -DriverPreTripCheckHistoryStatusIssues = issues found -DriverPreTripCheckHistoryButtonView = View -DriverJobCenterTitleOne = Truck -DriverJobCenterStatusCompleted = Completed -DriverJobCenterStatusReamining = Remaining -DriverJobCenterTitleTwo = Next Job -DriverJobCenterInfoPackages = packages -DriverJobCenterButtonDeliverTo = Deliver to Main Dock -DriverJobCenterTitleThree = Upcoming Stops -DriverJobCenterButtonSelect = Select Job -DriverCurrentDeliveryTitleOne = Current Delivery -DriverCurrentDeliveryTitleTwo = Packages -DriverCurrentDeliveryTitleThree = Delivery Notes -DriverCurrentDeliveryButtonStartNav = Start Navigation -DriverCurrentDeliveryCompleteTitleOne = Current Delivery -DriverCurrentDeliveryCompleteTitleTwo = Packages -DriverCurrentDeliveryCompleteTitleThree = Delivery Notes -DriverCurrentDeliveryCompleteButtonComplete = Complete Delivery -TruckTruckParameterTitleOne = Truck details -TruckTruckParameterTitleTwo = Load Capacity -TruckTruckParameterTitleThree = Condition -TruckTruckParameterButtonAdd = Add to Fleet -TruckVehicleProfileTitleOne = Add My Vehicles -TruckVehicleProfileInfoOne = The selected vehicles will be used for route calculation and guidance. -TruckVehicleProfileTitleTwo = Trucks -TruckVehicleProfileTitleThree = Passenger Cars -TruckVehicleProfileButtonAdd = Add Vehicle -# 新增加 -NavigationReferenceNavHomePlaceholderSearch = Where to? -NavigationReferenceNavHomeButtonHome = home -NavigationReferenceNavHomeButtonDepo = depo -NavigationReferenceNavHomeButtonSaved = saved - -NavigationReferenceNavDockUpPlaceholderSearch = Where to? -NavigationReferenceNavDockUpButtonHome = home -NavigationReferenceNavDockUpButtonDepo = depo -NavigationReferenceNavDockUpButtonAddPlace = add place -NavigationReferenceNavDockUpTitleSaved = Saved Location -NavigationReferenceNavDockUpActionSeeAll = See all -NavigationReferenceNavDockUpButtonAddJobLocation = Add Job Location - -NavigationReferenceNavSearchNormalPlaceholderSearch = Where to? -NavigationReferenceNavSearchNormalActionCancel = Cancel -NavigationReferenceNavSearchNormalButtonRestaurant = Restaurant -NavigationReferenceNavSearchNormalButtonCoffee = Coffee -NavigationReferenceNavSearchNormalButtonATM = ATM -NavigationReferenceNavSearchNormalButtonShopping = Shopping -NavigationReferenceNavSearchNormalButtonFuel = Fuel -NavigationReferenceNavSearchNormalTitleRecentSearches = RECENT SEARCHES -NavigationReferenceNavSearchNormalActionClear = Clear - -NavigationReferenceNavSearchSelectPlaceholderYourLocation = Your Location -NavigationReferenceNavSearchSelectButtonTruck = Truck -NavigationReferenceNavSearchSelectButtonVan = Van -NavigationReferenceNavSearchSelectButtonCar = Car -NavigationReferenceNavSearchSelectTitleLeavingNow = Leaving Now -NavigationReferenceNavSearchSelectActionRoutePreferences = Route Preferences - -NavigationReferenceNavRoutePreferenceTitleRoutePreferences = Route Preferences -NavigationReferenceNavRoutePreferenceinfoCar = Car -NavigationReferenceNavRoutePreferenceToggleSetMaxVehicleSpeed = Set max vehicle speed -NavigationReferenceNavRoutePreferenceInfoOne = This speed will be used to calculate travel time and alert you in case of over speeding -NavigationReferenceNavRoutePreferenceTitleZoneRegulations = ZONE REGULATIONS -NavigationReferenceNavRoutePreferenceMenuLicensePlateNumber = License plate number -NavigationReferenceNavRoutePreferenceInfoTwo = Indonesia and the Philippines -NavigationReferenceNavRoutePreferenceTitleAVOID = AVOID -NavigationReferenceNavRoutePreferenceCheckboxAvoidUTurns = Avoid U-turns -NavigationReferenceNavRoutePreferenceCheckboxAvoidFerries = Avoid ferries -NavigationReferenceNavRoutePreferenceCheckboxAvoidHighways = Avoid highways -NavigationReferenceNavRoutePreferenceCheckboxAvoidTunnels = Avoid tunnels -NavigationReferenceNavRoutePreferenceCheckboxAvoidTollRoads = Avoid toll roads -NavigationReferenceNavRoutePreferenceCheckboxAvoidUnpavedRoads = Avoid unpaved roads - -NavigationReferenceNavigatingTitleArrival = arrival -NavigationReferenceNavigatingTitleRemaining = remaining -NavigationReferenceNavigatingTitleDistance = distance - -NavigationReferenceNavOverviewTitleArrival = arrival -NavigationReferenceNavOverviewTitleAddAStop = ADD A STOP -NavigationReferenceNavSearchSelectButtonSearch = Search -NavigationReferenceNavSearchSelectButtonGas = Gas -NavigationReferenceNavSearchSelectButtonParking = Parking -NavigationReferenceNavSearchSelectButtonRestaurants = Restaurants -NavigationReferenceNavOverviewTitleQuickSettings = QUICK SETTINGS -NavigationReferenceNavOverviewToggleSpeedAlert = Speed alert -NavigationReferenceNavOverviewToggleOffline = Offline -NavigationReferenceNavOverviewToggleTheme = Theme -NavigationReferenceNavOverviewButtonMoreSetting = More setting -NavigationReferenceNavOverviewTitleOverview = OVERVIEW - -NavigationReferenceHomePageMenuStartDailyRoute = Start Daily Route -NavigationReferenceHomePageMenuCurrentRoute = Current Route -NavigationReferenceHomePageInfoNoActiveRoute = No active route -NavigationReferenceHomePageMenuMyDiary = My Diary / Log -NavigationReferenceHomePageInfoElectronicWorkDiary = Electronic work diary -NavigationReferenceHomePageMenuTripsReports = Trips & Reports -NavigationReferenceHomePageInfoViewTripHistory = View trip history -NavigationReferenceHomePageMenuDefectsMaintenance = Defects & Maintenance -NavigationReferenceHomePageInfoVehicleIssues = Vehicle issues - -NavigationReferenceSetVehicleInfoTitleDimensionsWeight = Dimensions & Weight -NavigationReferenceSetVehicleInfoTitleVehicleSpecifications = Vehicle Specifications -NavigationReferenceSetVehicleInfoinfoOne = Enter total size and weight including trailersand load -NavigationReferenceSetVehicleInfoTitlePhysicalDimensions = Physical Dimensions -NavigationReferenceSetVehicleInfoTitleUnitM = m -NavigationReferenceSetVehicleInfoTitleUnitCM = cm -NavigationReferenceSetVehicleInfoTitleHeight = Height -NavigationReferenceSetVehicleInfoTitleWidth = Width -NavigationReferenceSetVehicleInfoTitleLength = Length -NavigationReferenceSetVehicleInfoTitleWeightSpecifications = Weight Specifications -NavigationReferenceSetVehicleInfoTitleTotalWeight = Total Weight -NavigationReferenceSetVehicleInfoTitleUnitTonnes = tonnes -NavigationReferenceSetVehicleInfoInfoTwo = 15 metric tons =33,069 lbs -NavigationReferenceSetVehicleInfoButtonNext = Next: Hazardous Materials - -NavigationReferenceHazardousMaterialsTitleHazardousMaterials = Hazardous Materials -NavigationReferenceHazardousMaterialsTitleCargoClassification = Cargo Classification -NavigationReferenceHazardousMaterialsInfoOne = Select any hazardous materials you will betransporting -NavigationReferenceHazardousMaterialsTitleHazmatCategories = Hazmat Categories -NavigationReferenceHazardousMaterialsToggleExplosives = Explosives -NavigationReferenceHazardousMaterialsToggleGas = Gas -NavigationReferenceHazardousMaterialsToggleFlammable = Flammable -NavigationReferenceHazardousMaterialsTogglePoison = Poison -NavigationReferenceHazardousMaterialsToggleRadioactive = Radioactive -NavigationReferenceHazardousMaterialsToggleCorrosive = Corrosive -NavigationReferenceHazardousMaterialsToggleMiscellaneous = Miscellaneous -NavigationReferenceHazardousMaterialsButtonNext = Next: Tunnel Category - -NavigationReferenceTripSummaryTitleTripSummary = Trip Summary -NavigationReferenceTripSummaryTitleTripCompletedSuccessfully = Trip Completed Successfully -NavigationReferenceTripSummaryInfoOne = All compliance requirements met -NavigationReferenceTripSummaryTitleTripStatistics = Trip Statistics -NavigationReferenceTripSummaryTitleStartTime = START TIME -NavigationReferenceTripSummaryTitleEndTime = END TIME -NavigationReferenceTripSummaryTitleDistance = DISTANCE -NavigationReferenceTripSummaryTitleDuration = DURATION -NavigationReferenceTripSummaryTitleComplianceStatus = Compliance Status -NavigationReferenceTripSummaryStatusOne = Pre-trip inspection completed -NavigationReferenceTripSummaryStatusTwo = Route configured properly -NavigationReferenceTripSummaryStatusThree = Break requirements met -NavigationReferenceTripSummaryStatusFour = No incidents reported -NavigationReferenceTripSummaryButtonPDF = PDF -NavigationReferenceTripSummaryButtonDone = Done - -TripReportAndProfileDefectsMaintenanceButtonBack = Back -TripReportAndProfileDefectsMaintenanceTitleDefectsMaintenance = Defects & Maintenance -TripReportAndProfileDefectsMaintenanceTabOpen = Open -TripReportAndProfileDefectsMaintenanceTabResolved = Resolved -TripReportAndProfileDefectsMaintenanceTitleReported = Reported -TripReportAndProfileDefectsMaintenanceTitleLoaction = Loaction -TripReportAndProfileDefectsMaintenanceTitleReporter = Reporter -TripReportAndProfileDefectsMaintenanceButtonAddNewDefect = Add New Defect - -TripReportAndProfileMyDiaryLogButtonBack = Back -TripReportAndProfileMyDiaryLogTitleMyDiaryLog = My Diary / Log -TripReportAndProfileMyDiaryLogTabToday = Today -TripReportAndProfileMyDiaryLogTabWeek = Week -TripReportAndProfileMyDiaryLogTab28Days = 28Days -TripReportAndProfileMyDiaryLogTitleDailyTotals = Daily Totals -TripReportAndProfileMyDiaryLogTitleDrivingTime = Driving Time -TripReportAndProfileMyDiaryLogTitleOnDutyTime = On Duty Time -TripReportAndProfileMyDiaryLogTitleOffDutyTime = Off Duty Time -TripReportAndProfileMyDiaryLogTitleTotalBreaks = Total Breaks -TripReportAndProfileMyDiaryLogStatusRestDay = Rest Day -TripReportAndProfileMyDiaryLogTitleOffDuty = Off Duty -TripReportAndProfileMyDiaryLogTitleDriving = Driving -TripReportAndProfileMyDiaryLogTitleOnDuty = OnDuty -TripReportAndProfileMyDiaryLogStatusCompliant = Compliant -TripReportAndProfileMyDiaryLogStatusViolation = Violation -TripReportAndProfileMyDiaryLogTitle28DayComplianceOverview = 28-Day Compliance Overview -TripReportAndProfileMyDiaryLogStatusOff = Off -TripReportAndProfileMyDiaryLogButtonExport = Export -TripReportAndProfileMyDiaryLogButtonEmailReport = Email Report - -TripReportAndProfileTripsReportsButtonBack = Back -TripReportAndProfileTripsReportsTitleTripsReports = Trips & Reports -TripReportAndProfileTripsReportsTabRecent = Recent -TripReportAndProfileTripsReportsTabThisWeek = This Week -TripReportAndProfileTripsReportsTabThisMonth = This Month -TripReportAndProfileTripsReportsTitleTotalTrips = TOTAL TRIPS -TripReportAndProfileTripsReportsTitleCompliance = COMPLIANCE -TripReportAndProfileTripsReportsTitleDistance = Distance -TripReportAndProfileTripsReportsTitleDuration = Duration -TripReportAndProfileTripsReportsTitleLoadType = Load Type -TripReportAndProfileTripsReportsActionViewDetails = View Details -TripReportAndProfileTripsReportsButtonExportAl = Export Al -TripReportAndProfileTripsReportsButtonFilter = Filter - -TripReportAndProfileMyProfileDetailButtonBack = Back -TripReportAndProfileMyProfileDetailTitleProfile = Profile -TripReportAndProfileMyProfileDetailActionEdit = Edit -TripReportAndProfileMyProfileDetailTitleDriverInformation = Driver Information -TripReportAndProfileMyProfileDetailTitleLicenceNumber = Licence Number -TripReportAndProfileMyProfileDetailTitleState = State -TripReportAndProfileMyProfileDetailTitleExpiryDate = Expiry Date -TripReportAndProfileMyProfileDetailTitleABN = ABN -TripReportAndProfileMyProfileDetailTitleMyVehicles = My Vehicles -TripReportAndProfileMyProfileDetailTitleAccountSettings = Account Settings -TripReportAndProfileMyProfileDetailTitlePushNotifications = Push Notifications -TripReportAndProfileMyProfileDetailTitleLocationServices = Location Services -TripReportAndProfileMyProfileDetailTitleAutoBackup = Auto Backup -TripReportAndProfileMyProfileDetailButtonSettings = Settings -TripReportAndProfileMyProfileDetailButtonSign Out = Sign Out - -TripReportAndProfileTripInProgressTitleTripInProgress = Trip in Progress -TripReportAndProfileTripInProgressActionActive = Active -TripReportAndProfileTripInProgressTitleCurrentLocation = Current Location -TripReportAndProfileTripInProgressTitleDestination = Destination -TripReportAndProfileTripInProgressTitleTripDuration = Trip Duration -TripReportAndProfileTripInProgressTitleWorkTime = Work Time -TripReportAndProfileTripInProgressTitleDriveTime = Drive Time -TripReportAndProfileTripInProgressTitleRestTaken = Rest Taken -TripReportAndProfileTripInProgressTitleQuickActions = Quick Actions -TripReportAndProfileTripInProgressButtonTakeBreak = Take Break -TripReportAndProfileTripInProgressButtonReportlssue = Report lssue -TripReportAndProfileTripInProgressButtonFuelStop = Fuel Stop -TripReportAndProfileTripInProgressButtonAddNote = Add Note -TripReportAndProfileTripInProgressButtonEndTrip = End Trip - -TripReportAndProfileEndTripButtonBack = Back -TripReportAndProfileEndTripTitleEndTrip = End Trip -TripReportAndProfileEndTripTitleTripSummary = Trip Summary -TripReportAndProfileEndTripTitleStartLocation = Start Location -TripReportAndProfileEndTripTitleEndLocation = End Location -TripReportAndProfileEndTripTitleTotalDistance = Total Distance -TripReportAndProfileEndTripTitleTripDuration = Trip Duration -TripReportAndProfileEndTripTitleFuelUsed = Fuel Used (Est.) -TripReportAndProfileEndTripTitleFinalOdometerLu = Final OdometerLu -TripReportAndProfileEndTripTitleStartOdometer = Start Odometer -TripReportAndProfileEndTripTitleEndOdometer = End Odometer -TripReportAndProfileEndTripTitleDeliveryConfirmation = Delivery Confirmation -TripReportAndProfileEndTripTitleCargoDeliveredSuccessfully = Cargo delivered successfully -TripReportAndProfileEndTripTitleDeliveryDocumentationComplete = Delivery documentation complete -TripReportAndProfileEndTripTitleVehicleParkedSafely = Vehicle parked safely -TripReportAndProfileEndTripPlaceholderAddTripNotes = Add trip notes (optional) -TripReportAndProfileEndTripButtonCompleteTrip = Complete Trip - -TripReportAndProfileBreakRestButtonBack = Back -TripReportAndProfileBreakRestTitleBreakRest = Break & Rest -TripReportAndProfileBreakRestTitleBreakTimer = Break Timer -TripReportAndProfileBreakRestInfoOne = Minimum -TripReportAndProfileBreakRestInfoTwo = required -TripReportAndProfileBreakRestTitleWorkTimeSummary = Work Time Summary -TripReportAndProfileBreakRestTitleTotalWorkTime = Total Work Time -TripReportAndProfileBreakRestTitleContinuousDriving = Continuous Driving -TripReportAndProfileBreakRestTitleLastBreak = Last Break -TripReportAndProfileBreakRestTitleTotalBreaksToday = Total Breaks Today -TripReportAndProfileBreakRestTitleComplianceStatus = Compliance Status -TripReportAndProfileBreakRestTitleDailyWorkLimit = Daily Work Limit -TripReportAndProfileBreakRestTitleWeeklyHours = Weekly Hours -TripReportAndProfileBreakRestButtonEndBreakResume = End Break & Resume - - -TripReportAndProfileTripCompleteTitleTripComplete = Trip Complete! -TripReportAndProfileTripCompleteInfoOne = Your trip has been successfully logged and saved to your electronic work diary. -TripReportAndProfileTripCompleteTitleTripStatistics = Trip Statistics -TripReportAndProfileTripCompleteTitleDistance = Distance -TripReportAndProfileTripCompleteTitleDuration = Duration -TripReportAndProfileTripCompleteTitleAvgSpeed = Avg Speed -TripReportAndProfileTripCompleteTitleFuelUsed = Fuel Used -TripReportAndProfileTripCompleteTitleAllComplianceMet = All Compliance Met -TripReportAndProfileTripCompleteInfoTwo = Your trip complies with all NHVR regulations -TripReportAndProfileTripCompleteButtonViewSummary = View Summary -TripReportAndProfileTripCompleteButtonBackToDashboard = Back to Dashboard - -TripReportAndProfileReportIncidentButtonBack = Back -TripReportAndProfileReportIncidentTitleReportIncident = Report Incident -TripReportAndProfileReportIncidentStatusUrgent = URGENT -TripReportAndProfileReportIncidentTitleIncidentType = Incident Type -TripReportAndProfileReportIncidentTitleLocationDetails = Location Details -TripReportAndProfileReportIncidentTitleCurrentLocation = Current Location -TripReportAndProfileReportIncidentPlaceholderOne = Nearest landmark or address -TripReportAndProfileReportIncidentTitleIncidentDetails = Incident Details -TripReportAndProfileReportIncidentPlaceholderTwo = Describe what happened.. -TripReportAndProfileReportIncidentTitleAnyInjuries = Any injuries? -TripReportAndProfileReportIncidentButtonYes = Yes -TripReportAndProfileReportIncidentButtonNo = No -TripReportAndProfileReportIncidentTitleEmergencyServicesCalled = Emergency services called? -TripReportAndProfileReportIncidentTitlePhotosEvidence = Photos & Evidence -TripReportAndProfileReportIncidentButtonSubmitReport = Submit Report -TripReportAndProfileReportIncidentButtonSaveDraft = Save Draft - -TripReportAndProfileDailySummaryButtonBack = Back -TripReportAndProfileDailySummaryTitleDailySummary = Daily Summary -TripReportAndProfileDailySummaryInfoOne = Work Day Complete -TripReportAndProfileDailySummaryTitleTodayPerformance = Today's Performance -TripReportAndProfileDailySummaryTitleTotalDistance = Total Distance -TripReportAndProfileDailySummaryTitleTotalWorkTime = Total work Time -TripReportAndProfileDailySummaryTitleTripsCompleted = Trips Completed -TripReportAndProfileDailySummaryTitleTotalBreaks = Total Breaks -TripReportAndProfileDailySummaryTitleTripDetails = Trip Details -TripReportAndProfileDailySummaryTitleTrip = Trip -TripReportAndProfileDailySummaryTitleComplianceSummary = Compliance Summary -TripReportAndProfileDailySummaryTitleWorkTimeLimits = Work Time Limits -TripReportAndProfileDailySummaryTitleRestBreaks = Rest Breaks -TripReportAndProfileDailySummaryTitleElectronicWorkDiary = Electronic Work Diary -TripReportAndProfileDailySummaryButtonExportReport = Export Report -TripReportAndProfileDailySummaryButtonSignOffDay = Sign Off Day - -AuthenticationAddDriverTitleAddVehicle = Add Vehicle -AuthenticationAddDriverTitleVehicleInformation = Vehicle Information -AuthenticationAddDriverTagRegistration = REGISTRATION -AuthenticationAddDriverTagVIN = VIN(VEHICLEIDENTIFICATIONNUMBER) -AuthenticationAddDriverTagRegistrationExpiry = REGISTRATION EXPIRY -AuthenticationAddDriverTagInsuranceExpiry = INSURANCE EXPIRY -AuthenticationAddDriverTagVehicleType = VEHICLE TYPE -AuthenticationAddDriverOptionSelectType = Select type -AuthenticationAddDriverTagMake = MAKE -AuthenticationAddDriverTagModel = MODEL -AuthenticationAddDriverTagYear = YEAR -AuthenticationAddDriverTagColor = COLOR -AuthenticationAddDriverTagDimensionsCapacity = Dimensions & Capacity -AuthenticationAddDriverTagVehicleHeight = Vehicle Height -AuthenticationAddDriverTagVehicleWidth = Vehicle Width -AuthenticationAddDriverTagVehicleLength = Vehicle Length -AuthenticationAddDriverTagGrossWeight = Gross Weight -AuthenticationAddDriverTitleAdditionalSpecifications = Additional Specifications -AuthenticationAddDriverTagAxles = AXLES -AuthenticationAddDriverTagTrailers = TRAILERS -AuthenticationAddDriverTagWeightPerAxle = WEIGHT PER AXLE -AuthenticationAddDriverTagTruckType = TRUCK TYPE -AuthenticationAddDriverTitleHazardousMaterials = Hazardous Materials -AuthenticationAddDriverTagCarryingHazardousGoods = CARRYING HAZARDOUS GOODS? -AuthenticationAddDriverButtonNo = No -AuthenticationAddDriverButtonYes = Yes -AuthenticationAddDriverButtonAddVehicle = Add Vehicle - -AuthenticationAddVehicleTitleDriverProfile = Driver Profile -AuthenticationAddVehicleTitlePersonalInformation = Personal Information -AuthenticationAddVehicleTagFirstName = FIRST NAME -AuthenticationAddVehicleTagLastName = LAST NAME -AuthenticationAddVehicleTagPhoneNumber = PHONE NUMBER -AuthenticationAddVehicleTitleLicenseCertification = License & Certification -AuthenticationAddVehicleTagDriverLicenseNumber = DRIVER'S LICENSE NUMBER -AuthenticationAddVehicleTagLicenseClass = LICENSE CLASS -AuthenticationAddVehicleTagLicenseState = LICENSE STATE -AuthenticationAddVehicleOptionSelect = Select -AuthenticationAddVehicleTagLicenseExpiry = LICENSE EXPIRY -AuthenticationAddVehicleTagMedicalCert = MEDICAL CERT -AuthenticationAddVehicleTitleHazmatCertification = Hazmat Certification -AuthenticationAddVehicleTagHazmatCertified = HAZMAT CERTIFIED? -AuthenticationAddVehicleButtonNo = No -AuthenticationAddVehicleButtonYes = Yes -AuthenticationAddVehicleButtonSave = Save - -AuthenticationHazmatDialogTitleHazmatCertification = Hazmat Certification -AuthenticationHazmatDialogTagHazmatCertified = HAZMAT CERTIFIED? -AuthenticationHazmatDialogButtonNo = No -AuthenticationHazmatDialogButtonYes = Yes -AuthenticationHazmatDialogTagHazmatExpiryDate = HAZMAT EXPIRY DATE -AuthenticationHazmatDialogOptionSelect = Select date \ No newline at end of file diff --git a/vetti-admin/target/classes/i18n/messages_zh_CN.properties b/vetti-admin/target/classes/i18n/messages_zh_CN.properties index 4cf3dd6..38c9487 100644 --- a/vetti-admin/target/classes/i18n/messages_zh_CN.properties +++ b/vetti-admin/target/classes/i18n/messages_zh_CN.properties @@ -45,454 +45,3 @@ systemR10001 = 操作成功 VerificationEmailTiTle = 你的验证码 VerificationEmailContent = 你的验证码是: {0},有效期为 {1} 分钟。 - -#APP端 - -AppSystemPassWordTip10001 = 两次输入不一致 -AppSystemPassWordTip10002 = 不得包含您的姓名或电子邮件 -AppSystemPassWordTip10003 = 至少包含8个字符 -AppSystemPassWordTip10004 = 包含符号或数字 - -OnboardingOnboarding2ActionSkip = 跳过 -OnboardingOnboarding2TitleOne = 每次都能智能、快速地规划路线。 -OnboardingOnboarding2InfoOne = 优化后的导航将帮助您更快、更安全地到达目的地。 -OnboardingOnboarding2ButtonGetStarted = 开始 -OnboardingOnboarding3ActionSkip = 跳过 -OnboardingOnboarding3TitleOne = 保持合规,驾驶平稳。 -OnboardingOnboarding3InfoOne = 无缝的 EWD 和 CoR 合规性设计,助您保持行稳致远。 -OnboardingOnboarding3ButtonGetStarted = 开始 -OnboardingGetStartedTitleOne = 实现收益最大化,减少麻烦事。 -OnboardingGetStartedInfoOne = 点击“注册”或“登录”以查看您附近正在发生的事情 -OnboardingGetStartedButtonEamil = 继续使用电子邮件 -OnboardingGetStartedButtonGoogle = 继续使用 Google -OnboardingGetStartedButtonApple = 继续使用 AppleID -AuthenticationLoginEmptyStateTitleOne = 登录至 Routez -AuthenticationLoginEmptyStateInfoOne = 欢迎回来!请填写您的详细信息。 -AuthenticationLoginEmptyStatePlaceholderEamil = 邮箱 -AuthenticationLoginEmptyStatePlaceholderPassword = 密码 -AuthenticationLoginEmptyStateInfoTwo = 忘记了密码? -AuthenticationLoginEmptyStateActionReset = 重置 -AuthenticationLoginEmptyStateButtonSignin = 登录 -AuthenticationLoginEmptyStateButtonGoogle = 使用 Google 注册 -AuthenticationLoginEmptyStateButtonApple = 使用 AppleID 注册 -AuthenticationLoginEmptyStateInfoThree = 还没有账户吗? -AuthenticationLoginEmptyStateActionSignup = 注册 -AuthenticationSignUpEmptyStateTitleOne = 注册 -AuthenticationSignUpEmptyStatePlaceholderFullname = 全名 -AuthenticationSignUpEmptyStatePlaceholderEamil = 邮箱 -AuthenticationSignUpEmptyStatePlaceholderPassword = 密码 -AuthenticationSignUpEmptyStatePlaceholderFullnameTips = 请检查全名 -AuthenticationSignUpEmptyStatePlaceholderEamilTips = 请检查邮箱 -AuthenticationSignUpEmptyStatePlaceholderPasswordTips = 请检查密码 -AuthenticationSignUpEmptyStateInfoOne = 通过注册,您即表示同意我们的条款。 -AuthenticationSignUpEmptyStateLegalService = 服务条款 -AuthenticationSignUpEmptyStateInfoTwo = 和 -AuthenticationSignUpEmptyStateLegalpolicy = 隐私协议。 -AuthenticationSignUpEmptyStateButtonSignup = 注册 -AuthenticationSignUpEmptyStateButtonGoogle = 使用 Google 注册 -AuthenticationSignUpEmptyStateButtonApple = 使用 AppleID 注册 -AuthenticationSignUpEmptyStateInfoThree = 已经有账号了吗? -AuthenticationSignUpEmptyStateActionSignin = 登录 -AuthenticationEnterVerificationCodeTitleOne = 即将完成! -AuthenticationEnterVerificationCodeInfoOne = 请查看您的电子邮件收件箱,并输入验证码以验证您的账户。 -AuthenticationEnterVerificationCodeButtonContinue = 继续 -AuthenticationEnterVerificationCodeButtonResend = 重新发送验证码 -AuthenticationForgotPasswordTitleOne = 无法登录? -AuthenticationForgotPasswordInfoOne = 输入你账号绑定的邮箱,Carline 就会给你发个链接,直接重置密码! -AuthenticationForgotPasswordPlaceholderEamil = 邮箱 -AuthenticationForgotPasswordButtonReset = 重置密码 -AuthenticationForgotPasswordButtonReturn = 返回登录页面 -AuthenticationEnterNewPasswordTitleOne = 创建您的新密码 -AuthenticationEnterNewPasswordInfoOne = 您的新密码必须与之前的密码不同。 -AuthenticationEnterNewPasswordPlaceholderPassword = 密码 -AuthenticationEnterNewPasswordPlaceholderRepeat = 密码 -AuthenticationEnterNewPasswordAlertOne = 不得包含您的姓名或电子邮件。 -AuthenticationEnterNewPasswordAlertTwo = 至少 8 个字符 -AuthenticationEnterNewPasswordAlertThree = 包含一个符号或一个数字 -AuthenticationEnterNewPasswordButtonCreate = 创建新密码 -DriverMyProfileTitleOne = 资料 -DriverMyProfileButtonMyProfile = 我的资料 -DriverMyProfileTitleTwo = 通用 -DriverMyProfileActionOne = 职务 -DriverMyProfileActionTwo = 试驾 -DriverMyProfileActionThree = 我的订单 -DriverMyProfileTitleThree = 浏览历史 -DriverMyProfileNavMome = 主页 -DriverMyProfileNavFavourite = 地图 -DriverMyProfileNavMessage = 车队 -DriverMyProfileNavProfile = 资料 -DriverPreTripCheckTitleOne = 行车前检查 -DriverPreTripCheckTitleTwo = 下一站 -DriverPreTripCheckButtonStart = 开始检查 -DriverPreTripCheckButtonOne = 检查完成 -DriverPreTripCheckButtonFinish = 结束检查 -DriverPreTripCheckButtonStartfull = 开始全部检查 -DriverPreTripCheckListTitleOne = 行车前检查 -DriverPreTripCheckListInfoOne = 完成 -DriverPreTripCheckDetailInfoOne = 检查点 -DriverPreTripCheckDetailTitleOne = 所需规格 -DriverPreTripCheckDetailButtonFail = 失败 -DriverPreTripCheckDetailButtonPass = 通过 -DriverPreTripCheckDetailLabelOne = 问题详情 -DriverPreTripCheckDetailTitleTwo = 照片 -DriverPreTripCheckDetailButtonAdd = 添加照片 -DriverPreTripCheckDetailButtonSubmit = 提交 -DriverPreTripCheckHistoryTitleOne = 服务时间 -DriverPreTripCheckHistoryInfoOne = 上次休息 -DriverPreTripCheckHistoryInfoTwo = 下次需要 -DriverPreTripCheckHistoryTitleTwo = 当前路线 -DriverPreTripCheckHistoryTitleThree = 当前车辆 -DriverPreTripCheckHistoryButtonStartInspection = 开始检查 -DriverPreTripCheckHistoryButtonViewDetails = 查看详情 -DriverPreTripCheckHistoryTitleFour = 最近检查 -DriverPreTripCheckHistoryStatusIssues = 发现问题 -DriverPreTripCheckHistoryButtonView = 查看 -DriverJobCenterTitleOne = 卡车 -DriverJobCenterStatusCompleted = 已完成 -DriverJobCenterStatusReamining = 剩余 -DriverJobCenterTitleTwo = 下一个任务 -DriverJobCenterInfoPackages = 个包裹 -DriverJobCenterButtonDeliverTo = 送至主码头 -DriverJobCenterTitleThree = 即将到达的站点 -DriverJobCenterButtonSelect = 选择任务 -DriverCurrentDeliveryTitleOne = 当前配送 -DriverCurrentDeliveryTitleTwo = 包裹 -DriverCurrentDeliveryTitleThree = 配送备注 -DriverCurrentDeliveryButtonStartNav = 开始导航 -DriverCurrentDeliveryCompleteTitleOne = 当前配送 -DriverCurrentDeliveryCompleteTitleTwo = 包裹 -DriverCurrentDeliveryCompleteTitleThree = 配送备注 -DriverCurrentDeliveryCompleteButtonComplete = 完成配送 -TruckTruckParameterTitleOne = 卡车详情 -TruckTruckParameterTitleTwo = 载重能力 -TruckTruckParameterTitleThree = 状态 -TruckTruckParameterButtonAdd = 添加到车队 -TruckVehicleProfileTitleOne = 添加我的车辆 -TruckVehicleProfileInfoOne = 所选车辆将用于路线计算和导航。 -TruckVehicleProfileTitleTwo = 卡车 -TruckVehicleProfileTitleThree = 乘用车 -TruckVehicleProfileButtonAdd = 添加车辆 - -# 新增 -NavigationReferenceNavHomePlaceholderSearch = 去哪里? -NavigationReferenceNavHomeButtonHome = 家 -NavigationReferenceNavHomeButtonDepo = 仓库 -NavigationReferenceNavHomeButtonSaved = 已保存 - -NavigationReferenceNavDockUpPlaceholderSearch = 去哪里? -NavigationReferenceNavDockUpButtonHome = 家 -NavigationReferenceNavDockUpButtonDepo = 仓库 -NavigationReferenceNavDockUpButtonAddPlace = 添加地点 -NavigationReferenceNavDockUpTitleSaved = 已保存的位置 -NavigationReferenceNavDockUpActionSeeAll = 查看全部 -NavigationReferenceNavDockUpButtonAddJobLocation = 添加工作地点 - -NavigationReferenceNavSearchNormalPlaceholderSearch = 去哪里? -NavigationReferenceNavSearchNormalActionCancel = 取消 -NavigationReferenceNavSearchNormalButtonRestaurant = 餐厅 -NavigationReferenceNavSearchNormalButtonCoffee = 咖啡厅 -NavigationReferenceNavSearchNormalButtonATM = ATM取款机 -NavigationReferenceNavSearchNormalButtonShopping = 购物 -NavigationReferenceNavSearchNormalButtonFuel = 加油 -NavigationReferenceNavSearchNormalTitleRecentSearches = 最近 -NavigationReferenceNavSearchNormalActionClear = 清除 - -NavigationReferenceNavSearchSelectPlaceholderYourLocation = 你的位置 -NavigationReferenceNavSearchSelectButtonTruck = 卡车 -NavigationReferenceNavSearchSelectButtonVan = 货车 -NavigationReferenceNavSearchSelectButtonCar = 汽车 -NavigationReferenceNavSearchSelectTitleLeavingNow = 立即出发 -NavigationReferenceNavSearchSelectActionRoutePreferences = 路线偏好 - -NavigationReferenceNavRoutePreferenceTitleRoutePreferences = 路线偏好 -NavigationReferenceNavRoutePreferenceinfoCar = 汽车 -NavigationReferenceNavRoutePreferenceToggleSetMaxVehicleSpeed = 设置最大车速 -NavigationReferenceNavRoutePreferenceInfoOne = 次速度将用于计算旅程时间,并在超速时提醒您 -NavigationReferenceNavRoutePreferenceTitleZoneRegulations = 区域规定 -NavigationReferenceNavRoutePreferenceMenuLicensePlateNumber = 车牌号码 -NavigationReferenceNavRoutePreferenceInfoTwo = 印度尼西亚和菲律宾 -NavigationReferenceNavRoutePreferenceTitleAVOID = 避免 -NavigationReferenceNavRoutePreferenceCheckboxAvoidUTurns = 避免U型转弯 -NavigationReferenceNavRoutePreferenceCheckboxAvoidFerries = 避免杜伦 -NavigationReferenceNavRoutePreferenceCheckboxAvoidHighways = 避免高速公路 -NavigationReferenceNavRoutePreferenceCheckboxAvoidTunnels = 避免隧道 -NavigationReferenceNavRoutePreferenceCheckboxAvoidTollRoads = 避免收费公路 -NavigationReferenceNavRoutePreferenceCheckboxAvoidUnpavedRoads = 避免未铺装道路 - -NavigationReferenceNavigatingTitleArrival = 到达 -NavigationReferenceNavigatingTitleRemaining = 剩余 -NavigationReferenceNavigatingTitleDistance = 距离 - -NavigationReferenceNavOverviewTitleArrival = 到达 -NavigationReferenceNavOverviewTitleAddAStop = 添加站点 -NavigationReferenceNavSearchSelectButtonSearch = 搜索 -NavigationReferenceNavSearchSelectButtonGas = 加油站 -NavigationReferenceNavSearchSelectButtonParking = 停车场 -NavigationReferenceNavSearchSelectButtonRestaurants = 餐厅 -NavigationReferenceNavOverviewTitleQuickSettings = 快速设置 -NavigationReferenceNavOverviewToggleSpeedAlert = 超速报警 -NavigationReferenceNavOverviewToggleOffline = 离线模式 -NavigationReferenceNavOverviewToggleTheme = 主题 -NavigationReferenceNavOverviewButtonMoreSetting = 更多设置 -NavigationReferenceNavOverviewTitleOverview = 概览 - -NavigationReferenceHomePageMenuStartDailyRoute = 开始每日路线 -NavigationReferenceHomePageMenuCurrentRoute = 当前路线 -NavigationReferenceHomePageInfoNoActiveRoute = 无活动路线 -NavigationReferenceHomePageMenuMyDiary = 我的日记 / 日志 -NavigationReferenceHomePageInfoElectronicWorkDiary = 电子工作日记 -NavigationReferenceHomePageMenuTripsReports = 行程和报告 -NavigationReferenceHomePageInfoViewTripHistory = 查看历史行程 -NavigationReferenceHomePageMenuDefectsMaintenance = 缺陷与维护 -NavigationReferenceHomePageInfoVehicleIssues = 车辆问题 - -NavigationReferenceSetVehicleInfoTitleDimensionsWeight = 尺寸和重量 -NavigationReferenceSetVehicleInfoTitleVehicleSpecifications = 车辆规格 -NavigationReferenceSetVehicleInfoinfoOne = 输入包括拖车和负载在内的总尺寸和重量 -NavigationReferenceSetVehicleInfoTitlePhysicalDimensions = 物理尺寸 -NavigationReferenceSetVehicleInfoTitleUnitM = 米 -NavigationReferenceSetVehicleInfoTitleUnitCM = 厘米 -NavigationReferenceSetVehicleInfoTitleHeight = 高度 -NavigationReferenceSetVehicleInfoTitleWidth = 宽度 -NavigationReferenceSetVehicleInfoTitleLength = 长度 -NavigationReferenceSetVehicleInfoTitleWeightSpecifications = 重量规格 -NavigationReferenceSetVehicleInfoTitleTotalWeight = 总重量 -NavigationReferenceSetVehicleInfoTitleUnitTonnes = 吨 -NavigationReferenceSetVehicleInfoInfoTwo = 15吨 = 33,069 磅 -NavigationReferenceSetVehicleInfoButtonNext = 下一项:危险品 - -NavigationReferenceHazardousMaterialsTitleHazardousMaterials = 危险材料 -NavigationReferenceHazardousMaterialsTitleCargoClassification = 货物分类 -NavigationReferenceHazardousMaterialsInfoOne = 选择您将要运输的任何危险材料 -NavigationReferenceHazardousMaterialsTitleHazmatCategories = 危险品类别 -NavigationReferenceHazardousMaterialsToggleExplosives = 爆炸物 -NavigationReferenceHazardousMaterialsToggleGas = 气体 -NavigationReferenceHazardousMaterialsToggleFlammable = 易燃物 -NavigationReferenceHazardousMaterialsTogglePoison = 毒物 -NavigationReferenceHazardousMaterialsToggleRadioactive = 放射性物质 -NavigationReferenceHazardousMaterialsToggleCorrosive = 腐蚀性物质 -NavigationReferenceHazardousMaterialsToggleMiscellaneous = 杂项 -NavigationReferenceHazardousMaterialsButtonNext = 下一项:隧道类别 - -NavigationReferenceTripSummaryTitleTripSummary = 行程摘要 -NavigationReferenceTripSummaryTitleTripCompletedSuccessfully = 行程成功完成 -NavigationReferenceTripSummaryInfoOne = 所有合规要求已满足 -NavigationReferenceTripSummaryTitleTripStatistics = 行程统计 -NavigationReferenceTripSummaryTitleStartTime = 开始时间 -NavigationReferenceTripSummaryTitleEndTime = 结束时间 -NavigationReferenceTripSummaryTitleDistance = 距离 -NavigationReferenceTripSummaryTitleDuration = 持续时间 -NavigationReferenceTripSummaryTitleComplianceStatus = 合规状态 -NavigationReferenceTripSummaryStatusOne = 行程前检查已完成 -NavigationReferenceTripSummaryStatusTwo = 路线配置正确 -NavigationReferenceTripSummaryStatusThree = 休息要求已满足 -NavigationReferenceTripSummaryStatusFour = 未报告任何事件 -NavigationReferenceTripSummaryButtonPDF = PDF -NavigationReferenceTripSummaryButtonDone = 完成 - -TripReportAndProfileDefectsMaintenanceButtonBack = 返回 -TripReportAndProfileDefectsMaintenanceTitleDefectsMaintenance = 缺陷与维护 -TripReportAndProfileDefectsMaintenanceTabOpen = 打开 -TripReportAndProfileDefectsMaintenanceTabResolved = 已解决 -TripReportAndProfileDefectsMaintenanceTitleReported = 已报告 -TripReportAndProfileDefectsMaintenanceTitleLoaction = 位置 -TripReportAndProfileDefectsMaintenanceTitleReporter = 报告人 -TripReportAndProfileDefectsMaintenanceButtonAddNewDefect = 添加新缺陷 - -TripReportAndProfileMyDiaryLogButtonBack = 返回 -TripReportAndProfileMyDiaryLogTitleMyDiaryLog = 我的日记 / 日志 -TripReportAndProfileMyDiaryLogTabToday = 今天 -TripReportAndProfileMyDiaryLogTabWeek = 周 -TripReportAndProfileMyDiaryLogTab28Days = 28天 -TripReportAndProfileMyDiaryLogTitleDailyTotals = 每日总计 -TripReportAndProfileMyDiaryLogTitleDrivingTime = 驾驶时间 -TripReportAndProfileMyDiaryLogTitleOnDutyTime = 值班时间 -TripReportAndProfileMyDiaryLogTitleOffDutyTime = 下班时间 -TripReportAndProfileMyDiaryLogTitleTotalBreaks = 总休息时间 -TripReportAndProfileMyDiaryLogStatusRestDay = 休息日 -TripReportAndProfileMyDiaryLogTitleOffDuty = 下班时间 -TripReportAndProfileMyDiaryLogTitleDriving = 驾驶时间 -TripReportAndProfileMyDiaryLogTitleOnDuty = 在岗时间 -TripReportAndProfileMyDiaryLogStatusCompliant = 合规 -TripReportAndProfileMyDiaryLogStatusViolation = 违规 -TripReportAndProfileMyDiaryLogTitle28DayComplianceOverview = 28天合规概览 -TripReportAndProfileMyDiaryLogStatusOff = 下班 -TripReportAndProfileMyDiaryLogButtonExport = 导出 -TripReportAndProfileMyDiaryLogButtonEmailReport = 电子邮件报告 - -TripReportAndProfileTripsReportsButtonBack = 返回 -TripReportAndProfileTripsReportsTitleTripsReports = 行程 & 报告 -TripReportAndProfileTripsReportsTabRecent = 最近 -TripReportAndProfileTripsReportsTabThisWeek = 本周 -TripReportAndProfileTripsReportsTabThisMonth = 本月 -TripReportAndProfileTripsReportsTitleTotalTrips = 总行程数 -TripReportAndProfileTripsReportsTitleDistance = 距离 -TripReportAndProfileTripsReportsTitleCompliance = 合规性 -TripReportAndProfileTripsReportsTitleDuration = 持续时间 -TripReportAndProfileTripsReportsTitleLoadType = 负载类型 -TripReportAndProfileTripsReportsActionViewDetails = 查看详情 -TripReportAndProfileTripsReportsButtonExportAl = 导出 AI -TripReportAndProfileTripsReportsButtonFilter = 筛选 - -TripReportAndProfileMyProfileDetailButtonBack = 返回 -TripReportAndProfileMyProfileDetailTitleProfile = 个人资料 -TripReportAndProfileMyProfileDetailActionEdit = 编辑 -TripReportAndProfileMyProfileDetailTitleDriverInformation = 驾驶员信息 -TripReportAndProfileMyProfileDetailTitleLicenceNumber = 驾照号码 -TripReportAndProfileMyProfileDetailTitleState = 州 -TripReportAndProfileMyProfileDetailTitleExpiryDate = 过期日期 -TripReportAndProfileMyProfileDetailTitleABN = ABN -TripReportAndProfileMyProfileDetailTitleMyVehicles = 我的车辆 -TripReportAndProfileMyProfileDetailTitleAccountSettings = 账户设置 -TripReportAndProfileMyProfileDetailTitlePushNotifications = 推送通知 -TripReportAndProfileMyProfileDetailTitleLocationServices = 位置服务 -TripReportAndProfileMyProfileDetailTitleAutoBackup = 自动备份 -TripReportAndProfileMyProfileDetailButtonSettings = 设置 -TripReportAndProfileMyProfileDetailButtonSign Out = 退出登录 - -TripReportAndProfileTripInProgressTitleTripInProgress = 行程进行中 -TripReportAndProfileTripInProgressActionActive = 活动 -TripReportAndProfileTripInProgressTitleCurrentLocation = 当前位置 -TripReportAndProfileTripInProgressTitleDestination = 目的地 -TripReportAndProfileTripInProgressTitleTripDuration = 行程时长 -TripReportAndProfileTripInProgressTitleWorkTime = 工作时间 -TripReportAndProfileTripInProgressTitleDriveTime = 驾驶时间 -TripReportAndProfileTripInProgressTitleRestTaken = 休息时间 -TripReportAndProfileTripInProgressTitleQuickActions = 快捷操作 -TripReportAndProfileTripInProgressButtonTakeBreak = 休息 -TripReportAndProfileTripInProgressButtonReportlssue = 报告问题 -TripReportAndProfileTripInProgressButtonFuelStop = 加油 -TripReportAndProfileTripInProgressButtonAddNote = 添加备注 -TripReportAndProfileTripInProgressButtonEndTrip = 结束行程 - -TripReportAndProfileEndTripButtonBack = 返回 -TripReportAndProfileEndTripTitleEndTrip = 结束行程 -TripReportAndProfileEndTripTitleTripSummary = 行程摘要 -TripReportAndProfileEndTripTitleStartLocation = 起点位置 -TripReportAndProfileEndTripTitleEndLocation = 结束位置 -TripReportAndProfileEndTripTitleTotalDistance = 总距离 -TripReportAndProfileEndTripTitleTripDuration = 行程时长 -TripReportAndProfileEndTripTitleFuelUsed = 已用燃油(估计) -TripReportAndProfileEndTripTitleFinalOdometerLu = 最终里程表读数 -TripReportAndProfileEndTripTitleStartOdometer = 开始里程表读数 -TripReportAndProfileEndTripTitleEndOdometer = 结束里程表读数 -TripReportAndProfileEndTripTitleDeliveryConfirmation = 交付确认 -TripReportAndProfileEndTripTitleCargoDeliveredSuccessfully = 货物成功交付 -TripReportAndProfileEndTripTitleDeliveryDocumentationComplete = 交付文件完成 -TripReportAndProfileEndTripTitleVehicleParkedSafely = 车辆安全停放 -TripReportAndProfileEndTripPlaceholderAddTripNotes = 添加行程备注(可选) -TripReportAndProfileEndTripButtonCompleteTrip = 完成行程 - -TripReportAndProfileBreakRestButtonBack = 返回 -TripReportAndProfileBreakRestTitleBreakRest = 休息与恢复 -TripReportAndProfileBreakRestTitleBreakTimer = 休息计时器 -TripReportAndProfileBreakRestInfoOne = 至少 -TripReportAndProfileBreakRestInfoTwo = 所需 -TripReportAndProfileBreakRestTitleWorkTimeSummary = 工作时间总结 -TripReportAndProfileBreakRestTitleTotalWorkTime = 总工作时间 -TripReportAndProfileBreakRestTitleContinuousDriving = 连续驾驶时间 -TripReportAndProfileBreakRestTitleLastBreak = 上次休息时间 -TripReportAndProfileBreakRestTitleTotalBreaksToday = 今天总休息时间 -TripReportAndProfileBreakRestTitleComplianceStatus = 合规状态 -TripReportAndProfileBreakRestTitleDailyWorkLimit = 每日工作限制 -TripReportAndProfileBreakRestTitleWeeklyHours = 每周工时 -TripReportAndProfileBreakRestButtonEndBreakResume = 结束休息并恢复工作 - -TripReportAndProfileTripCompleteTitleTripComplete = 行程完成! -TripReportAndProfileTripCompleteInfoOne = 您的行程已成功记录并保存到您的电子工作日记中。 -TripReportAndProfileTripCompleteTitleTripStatistics = 行程统计 -TripReportAndProfileTripCompleteTitleDistance = 距离 -TripReportAndProfileTripCompleteTitleDuration = 持续时间 -TripReportAndProfileTripCompleteTitleAvgSpeed = 平均速度 -TripReportAndProfileTripCompleteTitleFuelUsed = 燃油消耗 -TripReportAndProfileTripCompleteTitleAllComplianceMet = 所有合规要求已满足 -TripReportAndProfileTripCompleteInfoTwo = 您的行程符合所有NHVR规定 -TripReportAndProfileTripCompleteButtonViewSummary = 查看摘要 -TripReportAndProfileTripCompleteButtonBackToDashboard = 返回仪表板 - -TripReportAndProfileReportIncidentButtonBack = 返回 -TripReportAndProfileReportIncidentTitleReportIncident = 报告事件 -TripReportAndProfileReportIncidentStatusUrgent = 紧急 -TripReportAndProfileReportIncidentTitleIncidentType = 事件类型 -TripReportAndProfileReportIncidentTitleLocationDetails = 位置详情 -TripReportAndProfileReportIncidentTitleCurrentLocation = 当前位置 -TripReportAndProfileReportIncidentPlaceholderOne = 最近的地标或地址 -TripReportAndProfileReportIncidentTitleIncidentDetails = 事件详情 -TripReportAndProfileReportIncidentPlaceholderTwo = 描述发生了什么。 -TripReportAndProfileReportIncidentTitleAnyInjuries = 是否有受伤? -TripReportAndProfileReportIncidentButtonYes = 是 -TripReportAndProfileReportIncidentButtonNo = 否 -TripReportAndProfileReportIncidentTitleEmergencyServicesCalled = 是否呼叫了紧急服务? -TripReportAndProfileReportIncidentTitlePhotosEvidence = 照片和证据 -TripReportAndProfileReportIncidentButtonSubmitReport = 提交报告 -TripReportAndProfileReportIncidentButtonSaveDraft = 保存草稿 - -TripReportAndProfileDailySummaryButtonBack = 返回 -TripReportAndProfileDailySummaryTitleDailySummary = 每日总结 -TripReportAndProfileDailySummaryInfoOne = 工作日完成情况 -TripReportAndProfileDailySummaryTitleTodayPerformance = 今日表现 -TripReportAndProfileDailySummaryTitleTotalDistance = 总距离 -TripReportAndProfileDailySummaryTitleTotalWorkTime = 总工作时间 -TripReportAndProfileDailySummaryTitleTripsCompleted = 完成的行程次数 -TripReportAndProfileDailySummaryTitleTotalBreaks = 总休息时间 -TripReportAndProfileDailySummaryTitleTripDetails = 行程详情 -TripReportAndProfileDailySummaryTitleTrip = 行程 -TripReportAndProfileDailySummaryTitleComplianceSummary = 合规总结 -TripReportAndProfileDailySummaryTitleWorkTimeLimits = 工作时间限制 -TripReportAndProfileDailySummaryTitleRestBreaks = 休息时间 -TripReportAndProfileDailySummaryTitleElectronicWorkDiary = 电子工作日记 -TripReportAndProfileDailySummaryButtonExportReport = 导出报告 -TripReportAndProfileDailySummaryButtonSignOffDay = 签退日 - -AuthenticationAddDriverTitleAddVehicle = 添加车辆 -AuthenticationAddDriverTitleVehicleInformation = 车辆信息 -AuthenticationAddDriverTagRegistration = 车牌号码 -AuthenticationAddDriverTagVIN = 车辆识别号(VIN) -AuthenticationAddDriverTagRegistrationExpiry = 注册到期日志 -AuthenticationAddDriverTagInsuranceExpiry = 保险到期日期 -AuthenticationAddDriverTagVehicleType = 车辆类型 -AuthenticationAddDriverOptionSelectType = 选择类型 -AuthenticationAddDriverTagMake = 品牌 -AuthenticationAddDriverTagModel = 型号 -AuthenticationAddDriverTagYear = 年份 -AuthenticationAddDriverTagColor = 颜色 -AuthenticationAddDriverTagDimensionsCapacity = 尺寸和容量 -AuthenticationAddDriverTagVehicleHeight = 车辆高度 -AuthenticationAddDriverTagVehicleWidth = 车辆宽度 -AuthenticationAddDriverTagVehicleLength = 车辆长度 -AuthenticationAddDriverTagGrossWeight = 总载重 -AuthenticationAddDriverTitleAdditionalSpecifications = 附加规格 -AuthenticationAddDriverTagAxles = 轴数 -AuthenticationAddDriverTagTrailers = 拖车 -AuthenticationAddDriverTagWeightPerAxle = 每轴重量 -AuthenticationAddDriverTagTruckType = 卡车类型 -AuthenticationAddDriverTitleHazardousMaterials = 危险品 -AuthenticationAddDriverTagCarryingHazardousGoods = 运输危险品? -AuthenticationAddDriverButtonNo = 否 -AuthenticationAddDriverButtonYes = 是 -AuthenticationAddDriverButtonAddVehicle = 添加车辆 - -AuthenticationAddVehicleTitleDriverProfile = 驾驶员资料 -AuthenticationAddVehicleTitlePersonalInformation = 个人信息 -AuthenticationAddVehicleTagFirstName = 名 -AuthenticationAddVehicleTagLastName = 姓氏 -AuthenticationAddVehicleTagPhoneNumber = 电话号码 -AuthenticationAddVehicleTitleLicenseCertification = 驾照和认证 -AuthenticationAddVehicleTagDriverLicenseNumber = 驾照号码 -AuthenticationAddVehicleTagLicenseClass = 驾照类别 -AuthenticationAddVehicleTagLicenseState = 驾照状态 -AuthenticationAddVehicleOptionSelect = 选择 -AuthenticationAddVehicleTagLicenseExpiry = 驾照到期日期 -AuthenticationAddVehicleTagMedicalCert = 医疗证明 -AuthenticationAddVehicleTitleHazmatCertification = 危险品认证 -AuthenticationAddVehicleTagHazmatCertified = 是否获得危险品认证? -AuthenticationAddVehicleButtonNo = 否 -AuthenticationAddVehicleButtonYes = 是 -AuthenticationAddVehicleButtonSave = 保存 - -AuthenticationHazmatDialogTitleHazmatCertification = 危险品认证 -AuthenticationHazmatDialogTagHazmatCertified = 是否通过危险品认证? -AuthenticationHazmatDialogButtonNo = 否 -AuthenticationHazmatDialogButtonYes = 是 -AuthenticationHazmatDialogTagHazmatExpiryDate = 危险品有效期 -AuthenticationHazmatDialogOptionSelect = 选择日期 \ No newline at end of file diff --git a/vetti-common/src/main/java/com/vetti/common/ai/ElevenLabsClient.java b/vetti-common/src/main/java/com/vetti/common/ai/ElevenLabsClient.java deleted file mode 100644 index 6a64d12..0000000 --- a/vetti-common/src/main/java/com/vetti/common/ai/ElevenLabsClient.java +++ /dev/null @@ -1,199 +0,0 @@ -package com.vetti.common.ai; - -import org.apache.http.HttpEntity; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.entity.ContentType; -import org.apache.http.entity.StringEntity; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.util.EntityUtils; -import com.google.gson.Gson; - -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.Map; - -/** - * 文本转换为语音 - */ -public class ElevenLabsClient { - - private static final String BASE_URL = "https://api.elevenlabs.io/v1"; - private final String apiKey; - private final CloseableHttpClient httpClient; - private final Gson gson; - - public ElevenLabsClient(String apiKey) { - this.apiKey = apiKey; - this.httpClient = HttpClients.createDefault(); - this.gson = new Gson(); - } - - /** - * 将文本转换为语音并保存到文件 - * - * @param text 要转换的文本 - * @param voiceId 语音ID (可从ElevenLabs网站获取) - * @param outputFilePath 输出文件路径 - * @throws IOException 网络请求或文件操作异常 - */ - public void textToSpeech(String text, String voiceId, String outputFilePath) throws IOException { - HttpPost httpPost = new HttpPost(BASE_URL + "/text-to-speech/" + voiceId); - httpPost.setHeader("xi-api-key", apiKey); - httpPost.setHeader("Content-Type", "application/json"); - - Map payload = new HashMap<>(); - payload.put("text", text); - payload.put("model_id", "eleven_monolingual_v1"); - payload.put("voice_settings", new VoiceSettings(0.7, 0.5)); - - StringEntity entity = new StringEntity(gson.toJson(payload), ContentType.APPLICATION_JSON); - httpPost.setEntity(entity); - - try (CloseableHttpResponse response = httpClient.execute(httpPost)) { - HttpEntity responseEntity = response.getEntity(); - if (responseEntity != null) { - try (InputStream inputStream = responseEntity.getContent(); - FileOutputStream outputStream = new FileOutputStream(outputFilePath)) { - - byte[] buffer = new byte[4096]; - int bytesRead; - while ((bytesRead = inputStream.read(buffer)) != -1) { - outputStream.write(buffer, 0, bytesRead); - } - } - } - } - } - - /** - * 获取可用的语音列表 - * - * @return 语音列表响应 - * @throws IOException 网络请求异常 - */ - public VoicesResponse getVoices() throws IOException { - HttpGet httpGet = new HttpGet(BASE_URL + "/voices"); - httpGet.setHeader("xi-api-key", apiKey); - - try (CloseableHttpResponse response = httpClient.execute(httpGet)) { - HttpEntity responseEntity = response.getEntity(); - String responseBody = EntityUtils.toString(responseEntity); - return gson.fromJson(responseBody, VoicesResponse.class); - } - } - - // 关闭HTTP客户端 - public void close() throws IOException { - httpClient.close(); - } - - // 语音设置内部类 - private static class VoiceSettings { - private double stability; - private double similarity_boost; - - public VoiceSettings(double stability, double similarity_boost) { - this.stability = stability; - this.similarity_boost = similarity_boost; - } - - // getter方法 - public double getStability() { - return stability; - } - - public double getSimilarity_boost() { - return similarity_boost; - } - } - - // 语音列表响应模型 - public static class VoicesResponse { - private Voice[] voices; - - public Voice[] getVoices() { - return voices; - } - - public void setVoices(Voice[] voices) { - this.voices = voices; - } - - public static class Voice { - private String voice_id; - private String name; - private String category; - private FineTuning fine_tuning; - - public String getVoice_id() { - return voice_id; - } - - public void setVoice_id(String voice_id) { - this.voice_id = voice_id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getCategory() { - return category; - } - - public void setCategory(String category) { - this.category = category; - } - - public FineTuning getFine_tuning() { - return fine_tuning; - } - - public void setFine_tuning(FineTuning fine_tuning) { - this.fine_tuning = fine_tuning; - } - } - } - - // 使用示例 - public static void main(String[] args) { - String apiKey = "sk_5240d8f56cb1eb5225fffcf903f62479884d1af5b3de6812"; - ElevenLabsClient client = new ElevenLabsClient(apiKey); - - try { - // 获取可用语音 - VoicesResponse voicesResponse = client.getVoices(); - if (voicesResponse != null && voicesResponse.getVoices() != null && voicesResponse.getVoices().length > 0) { - System.out.println("Available voices:"); - for (VoicesResponse.Voice voice : voicesResponse.getVoices()) { - System.out.println(voice.getName() + " (ID: " + voice.getVoice_id() + ")"); - } - - // 使用第一个可用语音进行文本转语音 - String firstVoiceId = voicesResponse.getVoices()[0].getVoice_id(); - String text = "Come on, Baby,Come on, Baby,Come on, Baby,Come on, Baby"; - String outputFile = "output.mp3"; - - client.textToSpeech(text, firstVoiceId, outputFile); - System.out.println("Audio saved to: " + outputFile); - } - } catch (IOException e) { - e.printStackTrace(); - } finally { - try { - client.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } -} diff --git a/vetti-common/src/main/java/com/vetti/common/ai/WapiAiClient.java b/vetti-common/src/main/java/com/vetti/common/ai/WapiAiClient.java deleted file mode 100644 index b6da4e3..0000000 --- a/vetti-common/src/main/java/com/vetti/common/ai/WapiAiClient.java +++ /dev/null @@ -1,159 +0,0 @@ -package com.vetti.common.ai; - -import org.apache.http.HttpEntity; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.entity.ContentType; -import org.apache.http.entity.StringEntity; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.util.EntityUtils; -import com.google.gson.Gson; - -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; - -/** - * 发送文本消息到指定的WhatsApp - */ -public class WapiAiClient { - - private static final String BASE_URL = "https://wapi.ai/api"; - private final String apiKey; - private final CloseableHttpClient httpClient; - private final Gson gson; - - public WapiAiClient(String apiKey) { - this.apiKey = apiKey; - this.httpClient = HttpClients.createDefault(); - this.gson = new Gson(); - } - - /** - * 发送文本消息到指定的WhatsApp号码 - * @param phoneNumber 目标电话号码(带国家代码,如:+1234567890) - * @param message 要发送的消息内容 - * @return API响应 - * @throws IOException 网络请求异常 - */ - public WapiResponse sendTextMessage(String phoneNumber, String message) throws IOException { - HttpPost httpPost = new HttpPost(BASE_URL + "/sendMessage"); - httpPost.setHeader("Authorization", "Bearer " + apiKey); - httpPost.setHeader("Content-Type", "application/json"); - - Map payload = new HashMap<>(); - payload.put("phone", phoneNumber); - payload.put("body", message); - - StringEntity entity = new StringEntity(gson.toJson(payload), ContentType.APPLICATION_JSON); - httpPost.setEntity(entity); - - try (CloseableHttpResponse response = httpClient.execute(httpPost)) { - HttpEntity responseEntity = response.getEntity(); - String responseBody = EntityUtils.toString(responseEntity); - return gson.fromJson(responseBody, WapiResponse.class); - } - } - - /** - * 获取最近的消息 - * @param limit 消息数量限制 - * @return 消息列表 - * @throws IOException 网络请求异常 - */ - public WapiMessagesResponse getRecentMessages(int limit) throws IOException { - HttpGet httpGet = new HttpGet(BASE_URL + "/messages?limit=" + limit); - httpGet.setHeader("Authorization", "Bearer " + apiKey); - - try (CloseableHttpResponse response = httpClient.execute(httpGet)) { - HttpEntity responseEntity = response.getEntity(); - String responseBody = EntityUtils.toString(responseEntity); - return gson.fromJson(responseBody, WapiMessagesResponse.class); - } - } - - // 关闭HTTP客户端 - public void close() throws IOException { - httpClient.close(); - } - - // 响应模型类 - public static class WapiResponse { - - private boolean success; - private String message; - private Object data; - - // getter和setter方法 - public boolean isSuccess() { return success; } - public void setSuccess(boolean success) { this.success = success; } - public String getMessage() { return message; } - public void setMessage(String message) { this.message = message; } - public Object getData() { return data; } - public void setData(Object data) { this.data = data; } - } - - // 消息响应模型类 - public static class WapiMessagesResponse { - private boolean success; - private Message[] messages; - - // getter和setter方法 - public boolean isSuccess() { return success; } - public void setSuccess(boolean success) { this.success = success; } - public Message[] getMessages() { return messages; } - public void setMessages(Message[] messages) { this.messages = messages; } - - public static class Message { - private String id; - private String phone; - private String body; - private String type; - private String timestamp; - - // getter和setter方法 - public String getId() { return id; } - public void setId(String id) { this.id = id; } - public String getPhone() { return phone; } - public void setPhone(String phone) { this.phone = phone; } - public String getBody() { return body; } - public void setBody(String body) { this.body = body; } - public String getType() { return type; } - public void setType(String type) { this.type = type; } - public String getTimestamp() { return timestamp; } - public void setTimestamp(String timestamp) { this.timestamp = timestamp; } - } - } - - // 使用示例 - public static void main(String[] args) { - String apiKey = "your_wapi_ai_api_key"; - WapiAiClient client = new WapiAiClient(apiKey); - - try { - // 发送消息 - WapiResponse response = client.sendTextMessage("+1234567890", "Hello from Wapi.ai Java Client!"); - System.out.println("Message sent: " + response.isSuccess()); - - // 获取最近消息 - WapiMessagesResponse messagesResponse = client.getRecentMessages(5); - if (messagesResponse.isSuccess() && messagesResponse.getMessages() != null) { - System.out.println("Recent messages:"); - for (WapiMessagesResponse.Message msg : messagesResponse.getMessages()) { - System.out.println(msg.getPhone() + ": " + msg.getBody()); - } - } - } catch (IOException e) { - e.printStackTrace(); - } finally { - try { - client.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } -} - diff --git a/vetti-common/src/main/java/com/vetti/common/ai/WhisperClient.java b/vetti-common/src/main/java/com/vetti/common/ai/WhisperClient.java deleted file mode 100644 index abc9aed..0000000 --- a/vetti-common/src/main/java/com/vetti/common/ai/WhisperClient.java +++ /dev/null @@ -1,116 +0,0 @@ -package com.vetti.common.ai; - -import cn.hutool.json.JSONObject; -import okhttp3.*; -import java.io.File; -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; - -/** - * 语音转换文本 - */ -public class WhisperClient { - private static final String API_URL = "https://api.openai.com/v1/audio/transcriptions"; - private static final String MODEL = "whisper-1"; - private final String apiKey; - private final OkHttpClient client; - - // 构造函数,传入API密钥 - public WhisperClient(String apiKey) { - this.apiKey = apiKey; - this.client = new OkHttpClient(); - } - - /** - * 将音频文件转换为文本 - * @param audioFile 音频文件 - * @param options 可选参数 (language, response_format等) - * @return 转换后的文本 - * @throws IOException 网络或文件操作异常 - * @throws WhisperException API返回错误 - */ - public String transcribe(File audioFile, Map options) throws IOException, WhisperException { - // 验证文件是否存在 - if (!audioFile.exists()) { - throw new IllegalArgumentException("音频文件不存在: " + audioFile.getAbsolutePath()); - } - - // 构建请求体 - MultipartBody.Builder bodyBuilder = new MultipartBody.Builder() - .setType(MultipartBody.FORM) - .addFormDataPart("model", MODEL) - .addFormDataPart("file", audioFile.getName(), - RequestBody.create(audioFile, MediaType.parse("audio/*"))); - - // 添加可选参数 - if (options != null) { - for (Map.Entry entry : options.entrySet()) { - bodyBuilder.addFormDataPart(entry.getKey(), entry.getValue()); - } - } - - // 构建请求 - Request request = new Request.Builder() - .url(API_URL) - .header("Authorization", "Bearer " + apiKey) - .post(bodyBuilder.build()) - .build(); - - // 发送请求并处理响应 - try (Response response = client.newCall(request).execute()) { - String responseBody = response.body().string(); - - if (!response.isSuccessful()) { - throw new WhisperException( - "API请求失败: " + response.code() + - ", 详情: " + responseBody - ); - } - - // 解析JSON响应 - JSONObject json = new JSONObject(responseBody); - return ""; - } - } - - /** - * 简化的转写方法,使用默认参数 - */ - public String transcribe(File audioFile) throws IOException, WhisperException { - return transcribe(audioFile, null); - } - - // 自定义异常类,用于处理Whisper API相关错误 - public static class WhisperException extends Exception { - public WhisperException(String message) { - super(message); - } - } - - // 使用示例 - public static void main(String[] args) { - // 替换为你的API密钥 - String apiKey = "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"; - WhisperClient client = new WhisperClient(apiKey); - - // 音频文件路径 - File audioFile = new File("/Users/wangxiangshun/Public/project-aio/vetti/vetti-service/output.mp3"); - - try { - // 添加可选参数,例如指定语言为中文 - Map options = new HashMap<>(); - options.put("language", "zh"); - - String result = client.transcribe(audioFile, options); - System.out.println("转写结果: " + result); - } catch (IOException e) { - System.err.println("IO错误: " + e.getMessage()); - e.printStackTrace(); - } catch (WhisperException e) { - System.err.println("Whisper API错误: " + e.getMessage()); - } catch (IllegalArgumentException e) { - System.err.println("参数错误: " + e.getMessage()); - } - } -} \ No newline at end of file diff --git a/vetti-common/src/main/java/com/vetti/common/ai/elevenLabs/ElevenLabsClient.java b/vetti-common/src/main/java/com/vetti/common/ai/elevenLabs/ElevenLabsClient.java new file mode 100644 index 0000000..7440435 --- /dev/null +++ b/vetti-common/src/main/java/com/vetti/common/ai/elevenLabs/ElevenLabsClient.java @@ -0,0 +1,124 @@ +package com.vetti.common.ai.elevenLabs; + +import com.google.gson.Gson; +import com.vetti.common.ai.elevenLabs.vo.VoiceSettings; +import com.vetti.common.ai.elevenLabs.vo.VoicesResponse; +import org.apache.http.HttpEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; + +/** + * 文本转换为语音 + */ +@Component +public class ElevenLabsClient { + + @Value("${elevenLabs.baseUrl}") + private String BASE_URL; + + @Value("${elevenLabs.apiKey}") + private String apiKey; + + @Value("${elevenLabs.modelId}") + private String modelId; + + + /** + * 将文本转换为语音并保存到文件 + * + * @param text 要转换的文本 + * @param voiceId 语音ID (可从ElevenLabs网站获取) + * @param outputFilePath 输出文件路径 + * @throws IOException 网络请求或文件操作异常 + */ + private void textToSpeech(String text, String voiceId, String outputFilePath,CloseableHttpClient httpClient) throws IOException { + HttpPost httpPost = new HttpPost(BASE_URL + "/text-to-speech/" + voiceId); + httpPost.setHeader("xi-api-key", apiKey); + httpPost.setHeader("Content-Type", "application/json"); + + Map payload = new HashMap<>(); + payload.put("text", text); + payload.put("model_id", modelId); + payload.put("voice_settings", new VoiceSettings(0.7, 0.5)); + Gson gson = new Gson(); + StringEntity entity = new StringEntity(gson.toJson(payload), ContentType.APPLICATION_JSON); + httpPost.setEntity(entity); + + try (CloseableHttpResponse response = httpClient.execute(httpPost)) { + HttpEntity responseEntity = response.getEntity(); + if (responseEntity != null) { + try (InputStream inputStream = responseEntity.getContent(); + FileOutputStream outputStream = new FileOutputStream(outputFilePath)) { + + byte[] buffer = new byte[4096]; + int bytesRead; + while ((bytesRead = inputStream.read(buffer)) != -1) { + outputStream.write(buffer, 0, bytesRead); + } + } + } + } + } + + /** + * 获取可用的语音列表 + * + * @return 语音列表响应 + * @throws IOException 网络请求异常 + */ + private VoicesResponse getVoices(CloseableHttpClient httpClient){ + HttpGet httpGet = new HttpGet(BASE_URL + "/voices"); + httpGet.setHeader("xi-api-key", apiKey); + Gson gson = new Gson(); + try (CloseableHttpResponse response = httpClient.execute(httpGet)) { + HttpEntity responseEntity = response.getEntity(); + String responseBody = EntityUtils.toString(responseEntity); + return gson.fromJson(responseBody, VoicesResponse.class); + }catch (Exception e){ + throw new RuntimeException("获取可用的语音列表异常"); + } + } + + /** + * 处理文本转换成语音文件 + * @param inputText + * @param outputFile + * @return + */ + public String handleTextToVoice(String inputText,String outputFile){ + CloseableHttpClient httpClient = HttpClients.createDefault(); + try { + // 获取可用语音 + VoicesResponse voicesResponse = getVoices(httpClient); + if (voicesResponse != null && voicesResponse.getVoices() != null + && voicesResponse.getVoices().length > 0) { + // 使用第一个可用语音进行文本转语音 + String firstVoiceId = voicesResponse.getVoices()[0].getVoice_id(); + textToSpeech(inputText, firstVoiceId, outputFile,httpClient); + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + httpClient.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return outputFile; + } +} diff --git a/vetti-common/src/main/java/com/vetti/common/ai/FineTuning.java b/vetti-common/src/main/java/com/vetti/common/ai/elevenLabs/vo/FineTuning.java similarity index 87% rename from vetti-common/src/main/java/com/vetti/common/ai/FineTuning.java rename to vetti-common/src/main/java/com/vetti/common/ai/elevenLabs/vo/FineTuning.java index 6c845f0..97fccbc 100644 --- a/vetti-common/src/main/java/com/vetti/common/ai/FineTuning.java +++ b/vetti-common/src/main/java/com/vetti/common/ai/elevenLabs/vo/FineTuning.java @@ -1,5 +1,8 @@ -package com.vetti.common.ai; +package com.vetti.common.ai.elevenLabs.vo; +/** + * + */ public class FineTuning { private String status; diff --git a/vetti-common/src/main/java/com/vetti/common/ai/elevenLabs/vo/Voice.java b/vetti-common/src/main/java/com/vetti/common/ai/elevenLabs/vo/Voice.java new file mode 100644 index 0000000..7494337 --- /dev/null +++ b/vetti-common/src/main/java/com/vetti/common/ai/elevenLabs/vo/Voice.java @@ -0,0 +1,45 @@ +package com.vetti.common.ai.elevenLabs.vo; + +/** + * 语音实体类对象 + */ +public class Voice { + + private String voice_id; + private String name; + private String category; + private FineTuning fine_tuning; + + public String getVoice_id() { + return voice_id; + } + + public void setVoice_id(String voice_id) { + this.voice_id = voice_id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getCategory() { + return category; + } + + public void setCategory(String category) { + this.category = category; + } + + public FineTuning getFine_tuning() { + return fine_tuning; + } + + public void setFine_tuning(FineTuning fine_tuning) { + this.fine_tuning = fine_tuning; + } + +} diff --git a/vetti-common/src/main/java/com/vetti/common/ai/elevenLabs/vo/VoiceSettings.java b/vetti-common/src/main/java/com/vetti/common/ai/elevenLabs/vo/VoiceSettings.java new file mode 100644 index 0000000..5eae529 --- /dev/null +++ b/vetti-common/src/main/java/com/vetti/common/ai/elevenLabs/vo/VoiceSettings.java @@ -0,0 +1,25 @@ +package com.vetti.common.ai.elevenLabs.vo; + +/** + * 语音设置 + */ +public class VoiceSettings { + + private double stability; + private double similarity_boost; + + public VoiceSettings(double stability, double similarity_boost) { + this.stability = stability; + this.similarity_boost = similarity_boost; + } + + // getter方法 + public double getStability() { + return stability; + } + + public double getSimilarity_boost() { + return similarity_boost; + } + +} diff --git a/vetti-common/src/main/java/com/vetti/common/ai/elevenLabs/vo/VoicesResponse.java b/vetti-common/src/main/java/com/vetti/common/ai/elevenLabs/vo/VoicesResponse.java new file mode 100644 index 0000000..50d30c2 --- /dev/null +++ b/vetti-common/src/main/java/com/vetti/common/ai/elevenLabs/vo/VoicesResponse.java @@ -0,0 +1,18 @@ +package com.vetti.common.ai.elevenLabs.vo; + +/** + * 语音列表响应模型 + */ +public class VoicesResponse { + + private Voice[] voices; + + public Voice[] getVoices() { + return voices; + } + + public void setVoices(Voice[] voices) { + this.voices = voices; + } + +} diff --git a/vetti-common/src/main/java/com/vetti/common/ai/gpt/ChatGPTClient.java b/vetti-common/src/main/java/com/vetti/common/ai/gpt/ChatGPTClient.java new file mode 100644 index 0000000..dc439ed --- /dev/null +++ b/vetti-common/src/main/java/com/vetti/common/ai/gpt/ChatGPTClient.java @@ -0,0 +1,138 @@ +package com.vetti.common.ai.gpt; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import java.io.IOException; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.time.Duration; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * AI ChatGPT 对话 + */ +@Component +public class ChatGPTClient { + + // OpenAI API密钥,需要替换为你自己的密钥 + @Value("${chatGpt.apiKey}") + private String apiKey; + // API端点URL + @Value("${chatGpt.apiUrl}") + private String apiUrl; + + @Value("${chatGpt.model}") + private String model; + + @Value("${chatGpt.role}") + private String role; + + /** + * 处理 AI 聊天 + * + * @param promptText 文字提示信息 + * @return + */ + public String handleAiChat(String promptText) { + String resultText = ""; + // 创建ChatGPT客户端 + // HTTP客户端 + HttpClient client = HttpClient.newBuilder() + .version(HttpClient.Version.HTTP_2) + .connectTimeout(Duration.ofSeconds(30)) + .build(); + // JSON处理工具 + ObjectMapper objectMapper = new ObjectMapper();; + // 单轮对话返回结果 + try { + resultText = sendMessage(promptText, model,objectMapper,client,role); + } catch (IOException | InterruptedException e) { + System.err.println("单轮对话出错: " + e.getMessage()); + } + return resultText; + } + + + /** + * 发送单轮对话请求 + * @param prompt 用户输入的提示词 + * @param model 使用的模型,例如"gpt-3.5-turbo"或"gpt-4" + * @return 模型返回的响应 + * @throws IOException 网络或IO异常 + * @throws InterruptedException 线程中断异常 + */ + private String sendMessage(String prompt, String model,ObjectMapper objectMapper,HttpClient client,String role) throws IOException, InterruptedException { + // 创建消息列表 + List> messages = new ArrayList<>(); + Map message = new HashMap<>(); + message.put("role", role); + message.put("content", prompt); + messages.add(message); + + return sendChatRequest(messages, model, 0.7,objectMapper,client); + } + + /** + * 发送多轮对话请求 + * @param messages 消息列表,包含历史对话 + * @param model 使用的模型 + * @param temperature 创造性参数,0-1之间 + * @return 模型返回的响应 + * @throws IOException 网络或IO异常 + * @throws InterruptedException 线程中断异常 + */ + private String sendChatRequest(List> messages, String model, double temperature,ObjectMapper objectMapper,HttpClient client) + throws IOException, InterruptedException { + // 构建请求体 + Map requestBody = new HashMap<>(); + requestBody.put("model", model); + requestBody.put("messages", messages); + requestBody.put("temperature", temperature); + // 转换为JSON字符串 + String jsonBody = objectMapper.writeValueAsString(requestBody); + // 构建HTTP请求 + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(apiUrl)) + .header("Content-Type", "application/json") + .header("Authorization", "Bearer " + apiKey) + .POST(HttpRequest.BodyPublishers.ofString(jsonBody)) + .build(); + // 发送请求并获取响应 + HttpResponse response = client.send( + request, + HttpResponse.BodyHandlers.ofString() + ); + // 解析响应 + return parseResponse(response.body(),objectMapper); + } + + /** + * 解析API响应,提取回复内容 + * @param responseBody 响应体字符串 + * @return 提取的回复内容 + * @throws IOException JSON解析异常 + */ + private String parseResponse(String responseBody,ObjectMapper objectMapper) throws IOException { + JsonNode rootNode = objectMapper.readTree(responseBody); + // 检查是否有错误 + if (rootNode.has("error")) { + String errorMessage = rootNode.get("error").get("message").asText(); + throw new IOException("API Error: " + errorMessage); + } + // 提取回复内容 + return rootNode.get("choices") + .get(0) + .get("message") + .get("content") + .asText(); + } + +} diff --git a/vetti-common/src/main/java/com/vetti/common/ai/whisper/WhisperClient.java b/vetti-common/src/main/java/com/vetti/common/ai/whisper/WhisperClient.java new file mode 100644 index 0000000..4cfafd7 --- /dev/null +++ b/vetti-common/src/main/java/com/vetti/common/ai/whisper/WhisperClient.java @@ -0,0 +1,100 @@ +package com.vetti.common.ai.whisper; + +import cn.hutool.json.JSONObject; +import okhttp3.*; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +/** + * 语音转换文本 + */ +@Component +public class WhisperClient { + + @Value("${whisper.apiUrl}") + private String API_URL; + + @Value("${whisper.model}") + private String MODEL; + + @Value("${whisper.apiKey}") + private String apiKey; + + @Value("${whisper.language}") + private String language; + + /** + * 将音频文件转换为文本 + * + * @param audioFile 音频文件 + * @param options 可选参数 (language, response_format等) + * @return 转换后的文本 + * @throws IOException 网络或文件操作异常 + */ + private String transcribe(File audioFile, Map options, OkHttpClient client) throws IOException { + // 验证文件是否存在 + if (!audioFile.exists()) { + throw new IllegalArgumentException("音频文件不存在: " + audioFile.getAbsolutePath()); + } + // 构建请求体 + MultipartBody.Builder bodyBuilder = new MultipartBody.Builder() + .setType(MultipartBody.FORM) + .addFormDataPart("model", MODEL) + .addFormDataPart("file", audioFile.getName(), + RequestBody.create(audioFile, MediaType.parse("audio/*"))); + // 添加可选参数 + if (options != null) { + for (Map.Entry entry : options.entrySet()) { + bodyBuilder.addFormDataPart(entry.getKey(), entry.getValue()); + } + } + // 构建请求 + Request request = new Request.Builder() + .url(API_URL) + .header("Authorization", "Bearer " + apiKey) + .post(bodyBuilder.build()) + .build(); + + // 发送请求并处理响应 + try (Response response = client.newCall(request).execute()) { + String responseBody = response.body().string(); + if (!response.isSuccessful()) { + throw new RuntimeException( + "API请求失败: " + response.code() + + ", 详情: " + responseBody + ); + } + // 解析JSON响应 + JSONObject json = new JSONObject(responseBody); + return responseBody; + } + } + + /** + * 处理语音转换成文字 + * + * @param audioFileUrl 要进行转换的语音逻辑 + * @return + */ + public String handleVoiceToText(String audioFileUrl) { + String resultText = ""; + OkHttpClient client = new OkHttpClient(); + // 音频文件路径 + File audioFile = new File(audioFileUrl); + try { + // 添加可选参数,例如指定语言为中文 + Map options = new HashMap<>(); + options.put("language", language); + resultText = transcribe(audioFile, options, client); + System.out.println("转写结果: " + resultText); + } catch (Exception e) { + e.printStackTrace(); + } + return resultText; + } +} \ No newline at end of file diff --git a/vetti-framework/src/main/java/com/vetti/framework/config/SecurityConfig.java b/vetti-framework/src/main/java/com/vetti/framework/config/SecurityConfig.java index d92da99..25de107 100644 --- a/vetti-framework/src/main/java/com/vetti/framework/config/SecurityConfig.java +++ b/vetti-framework/src/main/java/com/vetti/framework/config/SecurityConfig.java @@ -111,7 +111,7 @@ public class SecurityConfig .authorizeHttpRequests((requests) -> { permitAllUrl.getUrls().forEach(url -> requests.antMatchers(url).permitAll()); // 对于登录login 注册register 验证码captchaImage 允许匿名访问 - requests.antMatchers("/login", "/register", "/captchaImage","/v1/app/**").permitAll() + requests.antMatchers("/login", "/register", "/captchaImage","/aiCommon/**").permitAll() // 静态资源,可匿名访问 .antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll() .antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()