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
Commit
5e14298e
authored
Jan 10, 2025
by
mingyard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat:翻译:列表和功能
parent
1f953a2c
Show 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 @@
...
@@ -7,6 +7,7 @@
],
],
"words"
:
[
"words"
:
[
"activerecords"
,
"activerecords"
,
"DEEPL"
,
"dotenv"
,
"dotenv"
,
"healthz"
,
"healthz"
,
"hset"
,
"hset"
,
...
...
src/app.module.ts
View file @
5e14298e
...
@@ -10,6 +10,7 @@ import { SystemController } from './controller/system.controller';
...
@@ -10,6 +10,7 @@ import { SystemController } from './controller/system.controller';
import
{
UserModule
}
from
'./controller/user/user.module'
;
import
{
UserModule
}
from
'./controller/user/user.module'
;
import
{
AuthModule
}
from
'./controller/auth/auth.module'
;
import
{
AuthModule
}
from
'./controller/auth/auth.module'
;
import
{
RedisModule
}
from
'@nestjs-modules/ioredis'
;
import
{
RedisModule
}
from
'@nestjs-modules/ioredis'
;
import
{
TranslateModule
}
from
'./controller/translate/translate.module'
;
@
Module
({
@
Module
({
imports
:
[
imports
:
[
...
@@ -28,6 +29,7 @@ import { RedisModule } from '@nestjs-modules/ioredis';
...
@@ -28,6 +29,7 @@ import { RedisModule } from '@nestjs-modules/ioredis';
}),
}),
UserModule
,
UserModule
,
AuthModule
,
AuthModule
,
TranslateModule
,
],
],
controllers
:
[
SystemController
],
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
{
app
}
from
'./app'
;
import
{
cache
}
from
'./cache'
;
import
{
cache
}
from
'./cache'
;
import
{
database
}
from
'./database'
;
import
{
database
}
from
'./database'
;
import
{
deepl
}
from
'./deepl'
;
export
const
config
=
{
export
const
config
=
{
...
app
,
...
app
,
cache
,
cache
,
database
,
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