Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Sign in / Register
Toggle navigation
Z
zxn-adputin
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
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lijin
zxn-adputin
Commits
5972c447
Commit
5972c447
authored
Mar 23, 2025
by
lijin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
描述组增加多语言支持
parent
0d6de65a
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
90 additions
and
13 deletions
+90
-13
DescriptionGroupManage.vue
src/views/descriptionGroup/DescriptionGroupManage.vue
+90
-13
No files found.
src/views/descriptionGroup/DescriptionGroupManage.vue
View file @
5972c447
...
@@ -18,8 +18,9 @@
...
@@ -18,8 +18,9 @@
<el-table-column
prop=
"name"
label=
"名称"
width=
"250"
></el-table-column>
<el-table-column
prop=
"name"
label=
"名称"
width=
"250"
></el-table-column>
<el-table-column
label=
"描述"
min-width=
"300"
>
<el-table-column
label=
"描述"
min-width=
"300"
>
<template
slot-scope=
"scope"
>
<template
slot-scope=
"scope"
>
<div
v-for=
"(description, index) in scope.row.descriptions"
:key=
"index"
class=
"description-item"
>
<div
v-for=
"(descObj, index) in scope.row.descriptions"
:key=
"index"
class=
"description-item"
>
{{
description
}}
<span
class=
"description-text"
>
{{
descObj
.
text
}}
</span>
<el-tag
size=
"mini"
type=
"info"
class=
"language-tag"
>
{{
getLanguageName
(
descObj
.
language
)
}}
</el-tag>
</div>
</div>
<div
v-if=
"!scope.row.descriptions || scope.row.descriptions.length === 0"
class=
"no-descriptions"
>
<div
v-if=
"!scope.row.descriptions || scope.row.descriptions.length === 0"
class=
"no-descriptions"
>
暂无描述
暂无描述
...
@@ -68,12 +69,13 @@
...
@@ -68,12 +69,13 @@
<el-button
type=
"text"
@
click=
"form.descriptions = []"
>
清空
</el-button>
<el-button
type=
"text"
@
click=
"form.descriptions = []"
>
清空
</el-button>
</div>
</div>
<el-tag
<el-tag
v-for=
"(desc
ription
, index) in form.descriptions"
v-for=
"(desc
Obj
, index) in form.descriptions"
:key=
"index"
:key=
"index"
closable
closable
@
close=
"removeDescription(index)"
@
close=
"removeDescription(index)"
class=
"description-tag"
>
class=
"description-tag"
>
{{ description }}
{{ descObj.text }}
<span
class=
"description-language"
>
({{ getLanguageName(descObj.language) }})
</span>
</el-tag>
</el-tag>
</div>
</div>
<el-button
type=
"primary"
size=
"small"
@
click=
"showDescriptionSelectorDialog"
>
添加描述
</el-button>
<el-button
type=
"primary"
size=
"small"
@
click=
"showDescriptionSelectorDialog"
>
添加描述
</el-button>
...
@@ -111,6 +113,7 @@
...
@@ -111,6 +113,7 @@
<
script
>
<
script
>
import
TextTableSelecter
from
'@/components/TextTableSelecter'
import
TextTableSelecter
from
'@/components/TextTableSelecter'
import
{
getDescriptionGroupList
,
createDescriptionGroup
,
updateDescriptionGroup
,
deleteDescriptionGroup
}
from
'@/api/descriptionGroup'
import
{
getDescriptionGroupList
,
createDescriptionGroup
,
updateDescriptionGroup
,
deleteDescriptionGroup
}
from
'@/api/descriptionGroup'
import
{
getLanguageName
}
from
'@/const/language'
export
default
{
export
default
{
name
:
'DescriptionGroupManage'
,
name
:
'DescriptionGroupManage'
,
...
@@ -145,6 +148,21 @@ export default {
...
@@ -145,6 +148,21 @@ export default {
this
.
fetchData
()
this
.
fetchData
()
},
},
methods
:
{
methods
:
{
// 获取语言名称
getLanguageName
,
// 处理描述内容显示格式
formatDescriptionDisplay
(
descObj
)
{
if
(
typeof
descObj
===
'string'
)
{
// 兼容旧格式:字符串
return
{
text
:
descObj
,
language
:
'en'
};
}
else
if
(
descObj
&&
typeof
descObj
===
'object'
)
{
// 新格式:对象
return
descObj
;
}
return
null
;
},
// 获取描述组列表
// 获取描述组列表
fetchData
()
{
fetchData
()
{
this
.
loading
=
true
this
.
loading
=
true
...
@@ -152,8 +170,18 @@ export default {
...
@@ -152,8 +170,18 @@ export default {
.
then
(
response
=>
{
.
then
(
response
=>
{
this
.
loading
=
false
this
.
loading
=
false
if
(
response
.
status
===
200
)
{
if
(
response
.
status
===
200
)
{
this
.
tableData
=
response
.
result
.
data
||
[]
// 处理从后端返回的数据
this
.
total
=
this
.
tableData
.
length
const
data
=
response
.
result
.
data
||
[];
// 转换descriptions字段格式
data
.
forEach
(
item
=>
{
if
(
item
.
descriptions
&&
Array
.
isArray
(
item
.
descriptions
))
{
item
.
descriptions
=
item
.
descriptions
.
map
(
this
.
formatDescriptionDisplay
).
filter
(
Boolean
);
}
});
this
.
tableData
=
data
;
this
.
total
=
this
.
tableData
.
length
;
}
else
{
}
else
{
this
.
$message
.
error
(
'获取描述组列表失败'
)
this
.
$message
.
error
(
'获取描述组列表失败'
)
}
}
...
@@ -203,7 +231,14 @@ export default {
...
@@ -203,7 +231,14 @@ export default {
handleEdit
(
row
)
{
handleEdit
(
row
)
{
this
.
dialogTitle
=
'编辑描述组'
this
.
dialogTitle
=
'编辑描述组'
// 深拷贝避免直接修改表格数据
// 深拷贝避免直接修改表格数据
this
.
form
=
JSON
.
parse
(
JSON
.
stringify
(
row
))
const
formData
=
JSON
.
parse
(
JSON
.
stringify
(
row
));
// 处理descriptions字段,确保为新格式
if
(
formData
.
descriptions
&&
Array
.
isArray
(
formData
.
descriptions
))
{
formData
.
descriptions
=
formData
.
descriptions
.
map
(
this
.
formatDescriptionDisplay
).
filter
(
Boolean
);
}
this
.
form
=
formData
;
this
.
dialogVisible
=
true
this
.
dialogVisible
=
true
// 重置表单验证
// 重置表单验证
this
.
$nextTick
(()
=>
{
this
.
$nextTick
(()
=>
{
...
@@ -246,7 +281,23 @@ export default {
...
@@ -246,7 +281,23 @@ export default {
this
.
$refs
.
form
.
validate
(
valid
=>
{
this
.
$refs
.
form
.
validate
(
valid
=>
{
if
(
valid
)
{
if
(
valid
)
{
const
isEdit
=
!!
this
.
form
.
id
const
isEdit
=
!!
this
.
form
.
id
const
formData
=
{
...
this
.
form
}
// 深拷贝表单数据,避免直接修改
const
formData
=
JSON
.
parse
(
JSON
.
stringify
(
this
.
form
))
// 确保descriptions数组中的每个对象都有text和language属性
if
(
formData
.
descriptions
&&
Array
.
isArray
(
formData
.
descriptions
))
{
formData
.
descriptions
=
formData
.
descriptions
.
map
(
description
=>
{
// 如果是字符串,转换为对象格式
if
(
typeof
description
===
'string'
)
{
return
{
text
:
description
,
language
:
'en'
};
}
// 如果已经是对象但缺少language属性
if
(
typeof
description
===
'object'
&&
description
.
text
&&
!
description
.
language
)
{
return
{
...
description
,
language
:
'en'
};
}
return
description
;
});
}
const
apiCall
=
isEdit
const
apiCall
=
isEdit
?
updateDescriptionGroup
(
formData
.
id
,
formData
)
?
updateDescriptionGroup
(
formData
.
id
,
formData
)
...
@@ -280,13 +331,25 @@ export default {
...
@@ -280,13 +331,25 @@ export default {
// 确认描述选择
// 确认描述选择
confirmDescriptionSelection
()
{
confirmDescriptionSelection
()
{
// 提取文本内容并添加到描述列表
// 从TextTableSelecter获取的是完整的文案对象,已包含text和language属性
const
newDescriptions
=
this
.
selectedDescriptions
.
map
(
item
=>
item
.
text
)
const
newDescriptions
=
this
.
selectedDescriptions
.
map
(
item
=>
({
text
:
item
.
text
,
language
:
item
.
language
||
'en'
// 如果没有语言字段,默认为英语
}))
// 合并,避免重复添加相同的描述+语言组合
const
uniqueDescriptions
=
[...
this
.
form
.
descriptions
]
newDescriptions
.
forEach
(
newDesc
=>
{
const
isDuplicate
=
uniqueDescriptions
.
some
(
existingDesc
=>
existingDesc
.
text
===
newDesc
.
text
&&
existingDesc
.
language
===
newDesc
.
language
)
if
(
!
isDuplicate
)
{
uniqueDescriptions
.
push
(
newDesc
)
}
})
// 合并去重
const
uniqueDescriptions
=
[...
new
Set
([...
this
.
form
.
descriptions
,
...
newDescriptions
])]
this
.
form
.
descriptions
=
uniqueDescriptions
this
.
form
.
descriptions
=
uniqueDescriptions
this
.
descriptionSelectorDialogVisible
=
false
this
.
descriptionSelectorDialogVisible
=
false
},
},
...
@@ -357,4 +420,18 @@ export default {
...
@@ -357,4 +420,18 @@ export default {
text-overflow
:
ellipsis
;
text-overflow
:
ellipsis
;
white-space
:
nowrap
;
white-space
:
nowrap
;
}
}
.description-text
{
margin-right
:
5px
;
}
.language-tag
{
margin-left
:
5px
;
}
.description-language
{
font-size
:
0.8em
;
color
:
#909399
;
margin-left
:
3px
;
}
</
style
>
</
style
>
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