AI 业务逻辑初始化

This commit is contained in:
wangxiangshun
2025-10-04 13:56:50 +08:00
parent 6ab8d3d252
commit 51c27865f0
20 changed files with 845 additions and 1420 deletions

124
.idea/uiDesigner.xml generated Normal file
View File

@@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>

View File

@@ -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);
}
}

View File

@@ -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

View File

@@ -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:

View File

@@ -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

View File

@@ -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:

View File

@@ -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

View File

@@ -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 = Dont 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 = Cant 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

View File

@@ -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 = 选择日期

View File

@@ -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<String, Object> 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();
}
}
}
}

View File

@@ -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<String, Object> 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();
}
}
}
}

View File

@@ -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<String, String> 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<String, String> 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<String, String> 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());
}
}
}

View File

@@ -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<String, Object> 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;
}
}

View File

@@ -1,5 +1,8 @@
package com.vetti.common.ai;
package com.vetti.common.ai.elevenLabs.vo;
/**
*
*/
public class FineTuning {
private String status;

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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<Map<String, String>> messages = new ArrayList<>();
Map<String, String> 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<Map<String, String>> messages, String model, double temperature,ObjectMapper objectMapper,HttpClient client)
throws IOException, InterruptedException {
// 构建请求体
Map<String, Object> 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<String> 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();
}
}

View File

@@ -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<String, String> 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<String, String> 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<String, String> options = new HashMap<>();
options.put("language", language);
resultText = transcribe(audioFile, options, client);
System.out.println("转写结果: " + resultText);
} catch (Exception e) {
e.printStackTrace();
}
return resultText;
}
}

View File

@@ -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()