Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
T
translation-server
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
qinmingyuan
translation-server
Commits
5e14298e
You need to sign in or sign up before continuing.
Commit
5e14298e
authored
Jan 10, 2025
by
mingyard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat:翻译:列表和功能
parent
1f953a2c
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
312 additions
and
0 deletions
+312
-0
.cspell.json
.cspell.json
+1
-0
app.module.ts
src/app.module.ts
+2
-0
constants.ts
src/common/utils/constants.ts
+103
-0
deepl.ts
src/config/deepl.ts
+11
-0
index.ts
src/config/index.ts
+2
-0
translateReq.dto.ts
src/controller/translate/dto/req/translateReq.dto.ts
+26
-0
translateRes.dto.ts
src/controller/translate/dto/res/translateRes.dto.ts
+20
-0
translate.controller.spec.ts
src/controller/translate/translate.controller.spec.ts
+20
-0
translate.controller.ts
src/controller/translate/translate.controller.ts
+46
-0
translate.module.ts
src/controller/translate/translate.module.ts
+13
-0
translate.service.spec.ts
src/controller/translate/translate.service.spec.ts
+18
-0
translate.service.ts
src/controller/translate/translate.service.ts
+50
-0
No files found.
.cspell.json
View file @
5e14298e
...
...
@@ -7,6 +7,7 @@
],
"words"
:
[
"activerecords"
,
"DEEPL"
,
"dotenv"
,
"healthz"
,
"hset"
,
...
...
src/app.module.ts
View file @
5e14298e
...
...
@@ -10,6 +10,7 @@ import { SystemController } from './controller/system.controller';
import
{
UserModule
}
from
'./controller/user/user.module'
;
import
{
AuthModule
}
from
'./controller/auth/auth.module'
;
import
{
RedisModule
}
from
'@nestjs-modules/ioredis'
;
import
{
TranslateModule
}
from
'./controller/translate/translate.module'
;
@
Module
({
imports
:
[
...
...
@@ -28,6 +29,7 @@ import { RedisModule } from '@nestjs-modules/ioredis';
}),
UserModule
,
AuthModule
,
TranslateModule
,
],
controllers
:
[
SystemController
],
})
...
...
src/common/utils/constants.ts
0 → 100644
View file @
5e14298e
export
const
DEEPL_SOURCE_LANGUAGES
=
[
{
key
:
'AR'
,
language
:
'Arabic'
,
name
:
'阿拉伯语'
},
{
key
:
'BG'
,
language
:
'Bulgarian'
,
name
:
'保加利亚语'
},
{
key
:
'CS'
,
language
:
'Czech'
,
name
:
'捷克语'
},
{
key
:
'DA'
,
language
:
'Danish'
,
name
:
'丹麦语'
},
{
key
:
'DE'
,
language
:
'German'
,
name
:
'德语'
},
{
key
:
'EL'
,
language
:
'Greek'
,
name
:
'希腊语'
},
{
key
:
'EN'
,
language
:
'English'
,
name
:
'英语'
},
{
key
:
'ES'
,
language
:
'Spanish'
,
name
:
'西班牙语'
},
{
key
:
'ET'
,
language
:
'Estonian'
,
name
:
'爱沙尼亚语'
},
{
key
:
'FI'
,
language
:
'Finnish'
,
name
:
'芬兰语'
},
{
key
:
'FR'
,
language
:
'French'
,
name
:
'法语'
},
{
key
:
'HU'
,
language
:
'Hungarian'
,
name
:
'匈牙利语'
},
{
key
:
'ID'
,
language
:
'Indonesian'
,
name
:
'印度尼西亚语'
},
{
key
:
'IT'
,
language
:
'Italian'
,
name
:
'意大利语'
},
{
key
:
'JA'
,
language
:
'Japanese'
,
name
:
'日语'
},
{
key
:
'KO'
,
language
:
'Korean'
,
name
:
'韩语'
},
{
key
:
'LT'
,
language
:
'Lithuanian'
,
name
:
'立陶宛语'
},
{
key
:
'LV'
,
language
:
'Latvian'
,
name
:
'拉脱维亚语'
},
{
key
:
'NB'
,
language
:
'Norwegian Bokmål'
,
name
:
'挪威语'
},
{
key
:
'NL'
,
language
:
'Dutch'
,
name
:
'荷兰语'
},
{
key
:
'PL'
,
language
:
'Polish'
,
name
:
'波兰语'
},
{
key
:
'PT'
,
language
:
'Portuguese'
,
name
:
'葡萄牙语'
},
{
key
:
'RO'
,
language
:
'Romanian'
,
name
:
'罗马尼亚语'
},
{
key
:
'RU'
,
language
:
'Russian'
,
name
:
'俄语'
},
{
key
:
'SK'
,
language
:
'Slovak'
,
name
:
'斯洛伐克语'
},
{
key
:
'SL'
,
language
:
'Slovenian'
,
name
:
'斯洛文尼亚语'
},
{
key
:
'SV'
,
language
:
'Swedish'
,
name
:
'瑞典语'
},
{
key
:
'TR'
,
language
:
'Turkish'
,
name
:
'土耳其语'
},
{
key
:
'UK'
,
language
:
'Ukrainian'
,
name
:
'乌克兰语'
},
{
key
:
'ZH'
,
language
:
'Chinese'
,
name
:
'中文'
},
];
export
const
DEEPL_TARGET_LANGUAGES
=
[
{
key
:
'AR'
,
language
:
'Arabic'
,
name
:
'阿拉伯语'
},
{
key
:
'BG'
,
language
:
'Bulgarian'
,
name
:
'保加利亚语'
},
{
key
:
'CS'
,
language
:
'Czech'
,
name
:
'捷克语'
},
{
key
:
'DA'
,
language
:
'Danish'
,
name
:
'丹麦语'
},
{
key
:
'DE'
,
language
:
'German'
,
name
:
'德语'
},
{
key
:
'EL'
,
language
:
'Greek'
,
name
:
'希腊语'
},
{
key
:
'EN'
,
language
:
'English'
,
name
:
'英语'
},
// { key: 'EN-GB', language: 'English (British)', name: '英语(英式)' },
// { key: 'EN-US', language: 'English (American)', name: '英语(美式)' },
{
key
:
'ES'
,
language
:
'Spanish'
,
name
:
'西班牙语'
},
{
key
:
'ET'
,
language
:
'Estonian'
,
name
:
'爱沙尼亚语'
},
{
key
:
'FI'
,
language
:
'Finnish'
,
name
:
'芬兰语'
},
{
key
:
'FR'
,
language
:
'French'
,
name
:
'法语'
},
{
key
:
'HU'
,
language
:
'Hungarian'
,
name
:
'匈牙利语'
},
{
key
:
'ID'
,
language
:
'Indonesian'
,
name
:
'印度尼西亚语'
},
{
key
:
'IT'
,
language
:
'Italian'
,
name
:
'意大利语'
},
{
key
:
'JA'
,
language
:
'Japanese'
,
name
:
'日语'
},
{
key
:
'KO'
,
language
:
'Korean'
,
name
:
'韩语'
},
{
key
:
'LT'
,
language
:
'Lithuanian'
,
name
:
'立陶宛语'
},
{
key
:
'LV'
,
language
:
'Latvian'
,
name
:
'拉脱维亚语'
},
{
key
:
'NB'
,
language
:
'Norwegian Bokmål'
,
name
:
'挪威语'
},
{
key
:
'NL'
,
language
:
'Dutch'
,
name
:
'荷兰语'
},
{
key
:
'PL'
,
language
:
'Polish'
,
name
:
'波兰语'
},
{
key
:
'PT'
,
language
:
'Portuguese'
,
name
:
'葡萄牙语'
},
{
key
:
'RO'
,
language
:
'Romanian'
,
name
:
'罗马尼亚语'
},
{
key
:
'RU'
,
language
:
'Russian'
,
name
:
'俄语'
},
{
key
:
'SK'
,
language
:
'Slovak'
,
name
:
'斯洛伐克语'
},
{
key
:
'SL'
,
language
:
'Slovenian'
,
name
:
'斯洛文尼亚语'
},
{
key
:
'SV'
,
language
:
'Swedish'
,
name
:
'瑞典语'
},
{
key
:
'TR'
,
language
:
'Turkish'
,
name
:
'土耳其语'
},
{
key
:
'UK'
,
language
:
'Ukrainian'
,
name
:
'乌克兰语'
},
{
key
:
'ZH'
,
language
:
'Chinese'
,
name
:
'中文'
},
// { key: 'ZH-HANS', language: 'Chinese (simplified)', name: '中文(简体)' },
// { key: 'ZH-HANT', language: 'Chinese (traditional)', name: '中文(繁体)' },
];
// 支持的语言
export
enum
SupportLanguages
{
AR
=
'AR'
,
BG
=
'BG'
,
CS
=
'CS'
,
DA
=
'DA'
,
DE
=
'DE'
,
EL
=
'EL'
,
EN
=
'EN'
,
ES
=
'ES'
,
ET
=
'ET'
,
FI
=
'FI'
,
FR
=
'FR'
,
HU
=
'HU'
,
ID
=
'ID'
,
IT
=
'IT'
,
JA
=
'JA'
,
KO
=
'KO'
,
LT
=
'LT'
,
LV
=
'LV'
,
NB
=
'NB'
,
NL
=
'NL'
,
PL
=
'PL'
,
PT
=
'PT'
,
RO
=
'RO'
,
RU
=
'RU'
,
SK
=
'SK'
,
SL
=
'SL'
,
SV
=
'SV'
,
TR
=
'TR'
,
UK
=
'UK'
,
ZH
=
'ZH'
,
}
src/config/deepl.ts
0 → 100644
View file @
5e14298e
import
{
env
}
from
'./env'
;
export
interface
DeeplConfig
{
endpoint
:
string
;
secret
:
string
;
}
export
const
deepl
:
DeeplConfig
=
{
endpoint
:
env
.
DEEPL_ENDPOINT
??
'https://api-free.deepl.com'
,
secret
:
env
.
DEEPL_SECRET
??
''
,
};
src/config/index.ts
View file @
5e14298e
import
{
app
}
from
'./app'
;
import
{
cache
}
from
'./cache'
;
import
{
database
}
from
'./database'
;
import
{
deepl
}
from
'./deepl'
;
export
const
config
=
{
...
app
,
cache
,
database
,
deepl
,
};
src/controller/translate/dto/req/translateReq.dto.ts
0 → 100644
View file @
5e14298e
import
{
SupportLanguages
}
from
'@/common/utils/constants'
;
import
{
ApiProperty
}
from
'@nestjs/swagger'
;
import
{
Expose
}
from
'class-transformer'
;
import
{
IsEnum
,
IsNotEmpty
,
IsString
}
from
'class-validator'
;
export
class
TranslateReqDto
{
@
ApiProperty
({
description
:
'目标语言'
,
enum
:
SupportLanguages
,
example
:
SupportLanguages
.
AR
,
})
@
Expose
()
@
IsNotEmpty
()
@
IsEnum
(
SupportLanguages
)
target
:
SupportLanguages
;
@
ApiProperty
({
description
:
'待翻译文本'
,
type
:
String
,
example
:
'待翻译文本'
,
})
@
Expose
()
@
IsNotEmpty
()
@
IsString
()
text
:
string
;
}
src/controller/translate/dto/res/translateRes.dto.ts
0 → 100644
View file @
5e14298e
import
{
ApiProperty
}
from
'@nestjs/swagger'
;
import
{
Expose
}
from
'class-transformer'
;
export
class
TranslateResDto
{
@
ApiProperty
({
description
:
'要翻译的文本'
,
type
:
'string'
,
example
:
'要翻译的文本'
,
})
@
Expose
()
text
:
string
;
@
ApiProperty
({
description
:
'源语言'
,
type
:
'string'
,
example
:
'EN'
,
})
@
Expose
()
source
:
string
;
}
src/controller/translate/translate.controller.spec.ts
0 → 100644
View file @
5e14298e
import
{
Test
,
TestingModule
}
from
'@nestjs/testing'
;
import
{
TranslateController
}
from
'./translate.controller'
;
import
{
TranslateService
}
from
'./translate.service'
;
describe
(
'TranslateController'
,
()
=>
{
let
controller
:
TranslateController
;
beforeEach
(
async
()
=>
{
const
module
:
TestingModule
=
await
Test
.
createTestingModule
({
controllers
:
[
TranslateController
],
providers
:
[
TranslateService
],
}).
compile
();
controller
=
module
.
get
<
TranslateController
>
(
TranslateController
);
});
it
(
'should be defined'
,
()
=>
{
expect
(
controller
).
toBeDefined
();
});
});
src/controller/translate/translate.controller.ts
0 → 100644
View file @
5e14298e
import
{
Body
,
Controller
,
Get
,
Post
}
from
'@nestjs/common'
;
import
{
TranslateService
}
from
'./translate.service'
;
import
{
Auth
}
from
'@/common/decorators/auth.decorator'
;
import
{
ApiTags
,
ApiOperation
,
ApiResponse
}
from
'@nestjs/swagger'
;
import
{
TranslateReqDto
}
from
'./dto/req/translateReq.dto'
;
import
{
TranslateResDto
}
from
'./dto/res/translateRes.dto'
;
@
ApiTags
(
'translate'
)
@
Controller
(
'translate'
)
export
class
TranslateController
{
constructor
(
private
readonly
translateService
:
TranslateService
)
{}
// 获取翻译支持的语言
@
Get
(
'languages'
)
@
ApiOperation
({
summary
:
'获取翻译支持的语言'
})
@
ApiResponse
({
status
:
200
,
description
:
'成功返回支持的语言列表'
,
example
:
{
source
:
[{
key
:
'AR'
,
language
:
'Arabic'
,
name
:
'阿拉伯语'
}],
target
:
[{
key
:
'AR'
,
language
:
'Arabic'
,
name
:
'阿拉伯语'
}],
},
})
@
Auth
()
async
getLanguages
():
Promise
<
{
source
:
object
[];
target
:
object
[]
}
>
{
return
await
this
.
translateService
.
getLanguages
();
}
// 翻译文本
@
Post
(
'text'
)
@
ApiOperation
({
summary
:
'翻译文本'
})
@
ApiResponse
({
status
:
200
,
description
:
'成功返回翻译结果'
,
example
:
{
source
:
'EN'
,
text
:
'要翻译的文本'
,
},
})
@
Auth
()
async
translateText
(
@
Body
()
translateDto
:
TranslateReqDto
,
):
Promise
<
TranslateResDto
>
{
return
await
this
.
translateService
.
translateText
(
translateDto
);
}
}
src/controller/translate/translate.module.ts
0 → 100644
View file @
5e14298e
import
{
Module
}
from
'@nestjs/common'
;
import
{
TranslateService
}
from
'./translate.service'
;
import
{
TranslateController
}
from
'./translate.controller'
;
import
{
AuthGuard
}
from
'../auth/auth.guard'
;
import
{
AuthModule
}
from
'../auth/auth.module'
;
import
{
UserModule
}
from
'../user/user.module'
;
// 导入 UserModule
@
Module
({
imports
:
[
AuthModule
,
UserModule
],
// 添加 UserModule 到 imports 数组
controllers
:
[
TranslateController
],
providers
:
[
TranslateService
,
AuthGuard
],
})
export
class
TranslateModule
{}
src/controller/translate/translate.service.spec.ts
0 → 100644
View file @
5e14298e
import
{
Test
,
TestingModule
}
from
'@nestjs/testing'
;
import
{
TranslateService
}
from
'./translate.service'
;
describe
(
'TranslateService'
,
()
=>
{
let
service
:
TranslateService
;
beforeEach
(
async
()
=>
{
const
module
:
TestingModule
=
await
Test
.
createTestingModule
({
providers
:
[
TranslateService
],
}).
compile
();
service
=
module
.
get
<
TranslateService
>
(
TranslateService
);
});
it
(
'should be defined'
,
()
=>
{
expect
(
service
).
toBeDefined
();
});
});
src/controller/translate/translate.service.ts
0 → 100644
View file @
5e14298e
import
{
DEEPL_SOURCE_LANGUAGES
,
DEEPL_TARGET_LANGUAGES
,
}
from
'@/common/utils/constants'
;
import
{
Injectable
}
from
'@nestjs/common'
;
import
{
TranslateReqDto
}
from
'./dto/req/translateReq.dto'
;
import
{
TranslateResDto
}
from
'./dto/res/translateRes.dto'
;
import
{
axiosPostRequest
}
from
'@/common/utils/requests/request'
;
import
{
config
}
from
'@/config'
;
import
{
BadRequestError
}
from
'@/common/exception/badRequest/BadRequestError'
;
@
Injectable
()
export
class
TranslateService
{
constructor
()
{}
// 获取翻译支持的语言
async
getLanguages
():
Promise
<
{
source
:
object
[];
target
:
object
[]
}
>
{
return
{
source
:
DEEPL_SOURCE_LANGUAGES
,
target
:
DEEPL_TARGET_LANGUAGES
,
};
}
// 翻译文本
async
translateText
(
translateDto
:
TranslateReqDto
):
Promise
<
TranslateResDto
>
{
const
result
=
await
axiosPostRequest
(
`
${
config
.
deepl
.
endpoint
}
/v2/translate`
,
{
text
:
[
translateDto
.
text
],
target_lang
:
translateDto
.
target
,
},
{
headers
:
{
'Content-Type'
:
'application/json'
,
Authorization
:
`DeepL-Auth-Key
${
config
.
deepl
.
secret
}
`
,
},
},
);
const
{
translations
}
=
result
?.
data
;
if
(
!
translations
?.
length
)
{
throw
BadRequestError
.
default
(
'翻译失败'
);
}
const
[{
detected_source_language
:
source
,
text
}]
=
translations
;
return
{
source
,
text
};
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment