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
83007dea
Commit
83007dea
authored
Mar 05, 2025
by
lijin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
增加素材组管理功能
parent
2b9434c0
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
829 additions
and
1 deletion
+829
-1
materialGroup.js
src/api/materialGroup.js
+43
-0
index.vue
src/components/TagTransfer/index.vue
+327
-0
index.js
src/router/index.js
+6
-0
Layout.vue
src/views/layout/Layout.vue
+1
-1
index.vue
src/views/materialGroup/index.vue
+452
-0
No files found.
src/api/materialGroup.js
0 → 100644
View file @
83007dea
import
request
from
'@/utils/request'
// 获取所有素材组
export
function
getAllMaterialGroups
()
{
return
request
({
url
:
`
${
process
.
env
.
PUTIN_API
}
/material-groups`
,
method
:
'get'
})
}
// 根据ID获取素材组
export
function
getMaterialGroupById
(
id
)
{
return
request
({
url
:
`
${
process
.
env
.
PUTIN_API
}
/material-groups/
${
id
}
`
,
method
:
'get'
})
}
// 创建素材组
export
function
createMaterialGroup
(
data
)
{
return
request
({
url
:
`
${
process
.
env
.
PUTIN_API
}
/material-groups`
,
method
:
'post'
,
data
})
}
// 更新素材组
export
function
updateMaterialGroup
(
id
,
data
)
{
return
request
({
url
:
`
${
process
.
env
.
PUTIN_API
}
/material-groups/
${
id
}
`
,
method
:
'put'
,
data
})
}
// 删除素材组
export
function
deleteMaterialGroup
(
id
)
{
return
request
({
url
:
`
${
process
.
env
.
PUTIN_API
}
/material-groups/
${
id
}
`
,
method
:
'delete'
})
}
src/components/TagTransfer/index.vue
0 → 100644
View file @
83007dea
<
template
>
<div
class=
"tag-transfer-container"
>
<el-row
:gutter=
"20"
>
<!-- 左侧树形结构 -->
<el-col
:span=
"10"
>
<el-card
class=
"tree-card"
>
<div
slot=
"header"
class=
"card-header"
>
<span>
可选标签
</span>
<div
class=
"search-input"
>
<el-input
v-model=
"searchQuery"
placeholder=
"搜索标签"
prefix-icon=
"el-icon-search"
clearable
@
input=
"filterTree"
></el-input>
</div>
</div>
<!-- 使用v-if强制重新渲染树组件 -->
<el-tree
v-if=
"treeKey"
ref=
"tree"
:key=
"treeKey"
:data=
"treeData"
:props=
"defaultProps"
node-key=
"id"
show-checkbox
:filter-node-method=
"filterNode"
:default-checked-keys=
"selectedKeys"
@
check=
"handleCheck"
>
</el-tree>
</el-card>
</el-col>
<!-- 右侧已选标签 -->
<el-col
:span=
"10"
>
<el-card
class=
"selected-card"
>
<div
slot=
"header"
class=
"card-header"
>
<span>
已选标签
</span>
<el-button
type=
"text"
@
click=
"clearSelected"
>
清空
</el-button>
</div>
<div
class=
"selected-tags"
v-if=
"selectedTags.length > 0"
>
<el-tag
v-for=
"tag in selectedTags"
:key=
"tag.id"
closable
@
close=
"removeTag(tag.id)"
class=
"tag-item"
>
{{
getTagPath
(
tag
)
}}
</el-tag>
</div>
<div
v-else
class=
"no-data"
>
暂无选中标签
</div>
</el-card>
</el-col>
</el-row>
</div>
</
template
>
<
script
>
import
{
getAllMaterialTags
}
from
'@/api/materialTag'
export
default
{
name
:
'TagTransfer'
,
props
:
{
value
:
{
type
:
Array
,
default
:
()
=>
[]
}
},
// 强制组件重新渲染
beforeUpdate
()
{
console
.
log
(
'TagTransfer beforeUpdate, value:'
,
this
.
value
)
},
// 添加updated钩子检测值变化
updated
()
{
console
.
log
(
'TagTransfer updated, value:'
,
this
.
value
,
'selectedKeys:'
,
this
.
selectedKeys
)
},
data
()
{
return
{
allTags
:
[],
searchQuery
:
''
,
defaultProps
:
{
children
:
'children'
,
label
:
'name'
},
selectedKeys
:
[],
tagsMap
:
{},
treeKey
:
1
// 树组件的key,用于强制重新渲染
}
},
computed
:
{
treeData
()
{
return
this
.
buildTreeData
()
},
selectedTags
()
{
return
this
.
selectedKeys
.
map
(
id
=>
this
.
tagsMap
[
id
]).
filter
(
Boolean
)
}
},
watch
:
{
value
:
{
immediate
:
true
,
deep
:
true
,
handler
(
newVal
)
{
console
.
log
(
'TagTransfer value changed:'
,
newVal
)
if
(
!
Array
.
isArray
(
newVal
))
{
console
.
warn
(
'TagTransfer received non-array value:'
,
newVal
)
this
.
selectedKeys
=
[]
}
else
{
// 使用JSON序列化确保引用断开
this
.
selectedKeys
=
JSON
.
parse
(
JSON
.
stringify
(
newVal
))
}
// 增加treeKey强制树组件重新渲染
this
.
treeKey
++
console
.
log
(
'强制重新渲染树组件, treeKey:'
,
this
.
treeKey
)
// 等待树组件重新渲染后再设置选中状态
this
.
$nextTick
(()
=>
{
if
(
this
.
$refs
.
tree
)
{
console
.
log
(
'Setting checked keys in watcher:'
,
this
.
selectedKeys
)
this
.
$refs
.
tree
.
setCheckedKeys
(
this
.
selectedKeys
)
}
})
}
}
},
created
()
{
this
.
fetchTags
()
},
// 组件更新时的生命周期钩子
updated
()
{
console
.
log
(
'TagTransfer updated, selectedKeys:'
,
this
.
selectedKeys
)
},
methods
:
{
// 获取标签数据
fetchTags
()
{
getAllMaterialTags
().
then
(
response
=>
{
if
(
response
.
status
===
200
&&
response
.
result
&&
response
.
result
.
data
)
{
this
.
allTags
=
response
.
result
.
data
// 创建标签映射关系
this
.
tagsMap
=
{}
this
.
allTags
.
forEach
(
tag
=>
{
this
.
tagsMap
[
tag
.
id
]
=
tag
})
// 增加treeKey强制树组件重新渲染
this
.
treeKey
++
console
.
log
(
'标签加载完成,强制重新渲染树组件, treeKey:'
,
this
.
treeKey
)
// 等待树组件重新渲染后再设置选中状态
this
.
$nextTick
(()
=>
{
if
(
this
.
$refs
.
tree
)
{
console
.
log
(
'设置选中标签:'
,
this
.
selectedKeys
)
this
.
$refs
.
tree
.
setCheckedKeys
(
this
.
selectedKeys
)
}
})
}
}).
catch
(
error
=>
{
console
.
error
(
'获取标签失败:'
,
error
)
this
.
$message
.
error
(
'获取标签失败'
)
})
},
// 构建树形数据
buildTreeData
()
{
// 根据父子关系构建树
const
rootNodes
=
this
.
allTags
.
filter
(
tag
=>
!
tag
.
parentId
)
return
this
.
buildTree
(
rootNodes
)
},
// 递归构建树
buildTree
(
nodes
)
{
return
nodes
.
map
(
node
=>
{
const
children
=
this
.
allTags
.
filter
(
tag
=>
tag
.
parentId
===
node
.
id
)
const
treeNode
=
{
id
:
node
.
id
,
name
:
node
.
name
,
parentId
:
node
.
parentId
}
if
(
children
.
length
>
0
)
{
treeNode
.
children
=
this
.
buildTree
(
children
)
}
return
treeNode
})
},
// 过滤节点
filterNode
(
value
,
data
)
{
if
(
!
value
)
return
true
return
data
.
name
.
toLowerCase
().
includes
(
value
.
toLowerCase
())
},
// 过滤树
filterTree
()
{
this
.
$refs
.
tree
.
filter
(
this
.
searchQuery
)
},
// 处理选中变化
handleCheck
(
data
,
checked
)
{
console
.
log
(
'树选中变化:'
,
checked
)
// 使用JSON序列化确保断开引用
this
.
selectedKeys
=
JSON
.
parse
(
JSON
.
stringify
(
checked
.
checkedKeys
))
// 使用setTimeout确保在当前事件循环结束后触发事件
setTimeout
(()
=>
{
this
.
$emit
(
'input'
,
this
.
selectedKeys
)
this
.
$emit
(
'change'
,
this
.
selectedKeys
)
},
0
)
},
// 移除标签
removeTag
(
tagId
)
{
this
.
selectedKeys
=
this
.
selectedKeys
.
filter
(
id
=>
id
!==
tagId
)
// 增加treeKey强制树组件重新渲染
this
.
treeKey
++
// 等待树组件重新渲染后再设置选中状态
this
.
$nextTick
(()
=>
{
if
(
this
.
$refs
.
tree
)
{
this
.
$refs
.
tree
.
setCheckedKeys
(
this
.
selectedKeys
)
}
// 使用setTimeout确保在当前事件循环结束后触发事件
setTimeout
(()
=>
{
const
selectedKeysToEmit
=
JSON
.
parse
(
JSON
.
stringify
(
this
.
selectedKeys
))
this
.
$emit
(
'input'
,
selectedKeysToEmit
)
this
.
$emit
(
'change'
,
selectedKeysToEmit
)
},
0
)
})
},
// 清空选中
clearSelected
()
{
this
.
selectedKeys
=
[]
// 增加treeKey强制树组件重新渲染
this
.
treeKey
++
// 等待树组件重新渲染后再设置选中状态
this
.
$nextTick
(()
=>
{
if
(
this
.
$refs
.
tree
)
{
this
.
$refs
.
tree
.
setCheckedKeys
([])
}
// 使用setTimeout确保在当前事件循环结束后触发事件
setTimeout
(()
=>
{
this
.
$emit
(
'input'
,
[])
this
.
$emit
(
'change'
,
[])
},
0
)
})
},
// 获取标签路径
getTagPath
(
tag
)
{
if
(
!
tag
)
return
''
const
path
=
[]
let
currentTag
=
tag
while
(
currentTag
)
{
path
.
unshift
(
currentTag
.
name
)
if
(
currentTag
.
parentId
)
{
currentTag
=
this
.
tagsMap
[
currentTag
.
parentId
]
}
else
{
break
}
}
return
path
.
join
(
' / '
)
}
}
}
</
script
>
<
style
scoped
>
.tag-transfer-container
{
margin-bottom
:
20px
;
}
.card-header
{
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
}
.search-input
{
width
:
150px
;
}
.tree-card
,
.selected-card
{
height
:
400px
;
overflow-y
:
auto
;
}
.selected-tags
{
display
:
flex
;
flex-wrap
:
wrap
;
gap
:
8px
;
}
.tag-item
{
margin-right
:
8px
;
margin-bottom
:
8px
;
}
.no-data
{
color
:
#909399
;
text-align
:
center
;
margin-top
:
20px
;
}
</
style
>
src/router/index.js
View file @
83007dea
...
@@ -156,6 +156,12 @@ export const constantRouterMap = [
...
@@ -156,6 +156,12 @@ export const constantRouterMap = [
component
:
()
=>
import
(
'@/views/materialTag'
),
component
:
()
=>
import
(
'@/views/materialTag'
),
meta
:
{
title
:
'标签管理'
}
meta
:
{
title
:
'标签管理'
}
},
},
{
path
:
'/assetManagement/material-group'
,
name
:
'assetManagement.material-group'
,
component
:
()
=>
import
(
'@/views/materialGroup'
),
meta
:
{
title
:
'素材组管理'
}
},
]
]
},
},
...
...
src/views/layout/Layout.vue
View file @
83007dea
...
@@ -26,10 +26,10 @@
...
@@ -26,10 +26,10 @@
<!-- 带子菜单的导航项 -->
<!-- 带子菜单的导航项 -->
<el-submenu
index=
"4"
>
<el-submenu
index=
"4"
>
<
template
slot=
"title"
>
资产管理
</
template
>
<
template
slot=
"title"
>
资产管理
</
template
>
<el-menu-item
index=
"/assetManagement/material-group"
>
素材组管理
</el-menu-item>
<el-menu-item
index=
"/assetManagement/copywritingLibrary"
>
文案管理
</el-menu-item>
<el-menu-item
index=
"/assetManagement/copywritingLibrary"
>
文案管理
</el-menu-item>
<el-menu-item
index=
"/assetManagement/app-group"
>
产品组管理
</el-menu-item>
<el-menu-item
index=
"/assetManagement/app-group"
>
产品组管理
</el-menu-item>
<el-menu-item
index=
"/assetManagement/location-group"
>
地域组管理
</el-menu-item>
<el-menu-item
index=
"/assetManagement/location-group"
>
地域组管理
</el-menu-item>
<el-menu-item
index=
"/assetManagement/createDelivery"
>
素材组
</el-menu-item>
<el-menu-item
index=
"/assetManagement/title-group"
>
标题组管理
</el-menu-item>
<el-menu-item
index=
"/assetManagement/title-group"
>
标题组管理
</el-menu-item>
<el-menu-item
index=
"/assetManagement/description-group"
>
描述组管理
</el-menu-item>
<el-menu-item
index=
"/assetManagement/description-group"
>
描述组管理
</el-menu-item>
<el-menu-item
index=
"/assetManagement/material-tag"
>
标签管理
</el-menu-item>
<el-menu-item
index=
"/assetManagement/material-tag"
>
标签管理
</el-menu-item>
...
...
src/views/materialGroup/index.vue
0 → 100644
View file @
83007dea
<
template
>
<div
class=
"material-group-container"
>
<!-- 过滤条件 -->
<div
class=
"filter-section"
>
<el-form
:inline=
"true"
:model=
"condition"
class=
"filter-form"
>
<el-form-item
label=
"标签"
>
<material-tag-select
v-model=
"condition.tags"
@
change=
"handleTagChange"
/>
</el-form-item>
</el-form>
</div>
<el-divider></el-divider>
<!-- 表格头部操作 -->
<div
class=
"header-actions"
>
<el-button
type=
"primary"
@
click=
"showAddDialog"
>
新增素材组
</el-button>
<div
class=
"header-right"
>
<el-button
icon=
"el-icon-refresh"
@
click=
"fetchData"
>
刷新
</el-button>
</div>
</div>
<!-- 主表格 -->
<el-table
:data=
"tableData"
border
style=
"width: 100%;"
v-loading=
"loading"
>
<el-table-column
prop=
"id"
label=
"ID"
width=
"80"
></el-table-column>
<el-table-column
prop=
"name"
label=
"名称"
width=
"250"
></el-table-column>
<el-table-column
label=
"标签"
min-width=
"300"
>
<template
slot-scope=
"scope"
>
<el-tag
v-for=
"tagId in scope.row.tags || []"
:key=
"tagId"
size=
"small"
style=
"margin: 2px"
>
{{
getTagName
(
tagId
)
}}
</el-tag>
<span
v-if=
"!scope.row.tags || scope.row.tags.length === 0"
class=
"no-tags"
>
暂无标签
</span>
</
template
>
</el-table-column>
<el-table-column
label=
"操作"
align=
"center"
width=
"180"
>
<
template
slot-scope=
"scope"
>
<el-button
size=
"mini"
type=
"primary"
@
click=
"handleEdit(scope.row)"
>
编辑
</el-button>
<el-button
size=
"mini"
type=
"danger"
@
click=
"handleDelete(scope.row)"
>
删除
</el-button>
</
template
>
</el-table-column>
</el-table>
<!-- 分页 -->
<div
class=
"pagination-container"
>
<el-pagination
@
size-change=
"handleSizeChange"
@
current-change=
"handleCurrentChange"
:current-page=
"pagination.currentPage"
:page-sizes=
"[10, 20, 50, 100]"
:page-size=
"pagination.pageSize"
:total=
"pagination.total"
layout=
"total, prev, pager, next, sizes"
>
</el-pagination>
</div>
<!-- 新增/编辑对话框 -->
<el-dialog
:title=
"dialogTitle"
:visible
.
sync=
"dialogVisible"
width=
"60%"
>
<el-form
:model=
"form"
:rules=
"rules"
ref=
"form"
label-width=
"120px"
>
<el-form-item
label=
"素材组名称"
prop=
"name"
>
<el-input
v-model=
"form.name"
></el-input>
</el-form-item>
<el-form-item
label=
"选择标签"
prop=
"tags"
>
<tag-transfer
:key=
"dialogVisible + '-' + form.id + '-' + JSON.stringify(form.tags)"
v-model=
"form.tags"
@
change=
"handleFormTagChange"
>
</tag-transfer>
</el-form-item>
<el-form-item
label=
"备注"
prop=
"remark"
>
<el-input
type=
"textarea"
v-model=
"form.remark"
:rows=
"3"
></el-input>
</el-form-item>
</el-form>
<div
slot=
"footer"
class=
"dialog-footer"
>
<el-button
@
click=
"dialogVisible = false"
>
取消
</el-button>
<el-button
type=
"primary"
@
click=
"submitForm"
>
确定
</el-button>
</div>
</el-dialog>
</div>
</template>
<
script
>
import
MaterialTagSelect
from
'@/components/MaterialTagSelect'
import
TagTransfer
from
'@/components/TagTransfer'
import
{
getAllMaterialGroups
,
getMaterialGroupById
,
createMaterialGroup
,
updateMaterialGroup
,
deleteMaterialGroup
}
from
'@/api/materialGroup'
import
{
getAllMaterialTags
}
from
'@/api/materialTag'
export
default
{
name
:
'MaterialGroupManage'
,
components
:
{
MaterialTagSelect
,
TagTransfer
},
data
()
{
return
{
// 表格数据
tableData
:
[],
originalData
:
[],
// 原始完整数据
loading
:
false
,
// 分页
pagination
:
{
currentPage
:
1
,
pageSize
:
10
,
total
:
0
},
// 过滤条件
condition
:
{
tags
:
[]
},
// 对话框
dialogVisible
:
false
,
dialogTitle
:
''
,
form
:
{
id
:
null
,
name
:
''
,
tags
:
[],
remark
:
''
},
// 表单验证
rules
:
{
name
:
[
{
required
:
true
,
message
:
'请输入素材组名称'
,
trigger
:
'blur'
},
{
min
:
1
,
max
:
50
,
message
:
'长度在1-50个字符之间'
,
trigger
:
'blur'
}
]
},
// 标签数据
allTags
:
[],
tagsMap
:
{}
}
},
created
()
{
this
.
fetchData
()
this
.
fetchAllTags
()
},
methods
:
{
// 获取素材组数据
fetchData
()
{
this
.
loading
=
true
getAllMaterialGroups
().
then
(
response
=>
{
this
.
loading
=
false
if
(
response
.
status
===
200
&&
response
.
result
&&
response
.
result
.
data
)
{
// 保存原始数据,以便编辑时可以获取完整数据
this
.
originalData
=
response
.
result
.
data
let
filteredData
=
[...
this
.
originalData
]
// 如果有标签过滤条件
if
(
this
.
condition
.
tags
&&
this
.
condition
.
tags
.
length
>
0
)
{
filteredData
=
filteredData
.
filter
(
item
=>
{
if
(
!
item
.
tags
||
item
.
tags
.
length
===
0
)
return
false
return
this
.
condition
.
tags
.
some
(
tagId
=>
item
.
tags
.
includes
(
tagId
))
})
}
this
.
pagination
.
total
=
filteredData
.
length
// 分页处理
const
start
=
(
this
.
pagination
.
currentPage
-
1
)
*
this
.
pagination
.
pageSize
const
end
=
start
+
this
.
pagination
.
pageSize
this
.
tableData
=
filteredData
.
slice
(
start
,
end
)
}
else
{
this
.
$message
.
error
(
'获取素材组数据失败'
)
}
}).
catch
(
error
=>
{
this
.
loading
=
false
console
.
error
(
'获取素材组失败:'
,
error
)
this
.
$message
.
error
(
'获取素材组失败: '
+
error
.
message
)
})
},
// 获取所有标签
fetchAllTags
()
{
getAllMaterialTags
().
then
(
response
=>
{
if
(
response
.
status
===
200
&&
response
.
result
&&
response
.
result
.
data
)
{
this
.
allTags
=
response
.
result
.
data
// 创建标签映射
this
.
tagsMap
=
{}
this
.
allTags
.
forEach
(
tag
=>
{
this
.
tagsMap
[
tag
.
id
]
=
tag
})
}
else
{
this
.
$message
.
error
(
'获取标签数据失败'
)
}
}).
catch
(
error
=>
{
console
.
error
(
'获取标签失败:'
,
error
)
this
.
$message
.
error
(
'获取标签失败: '
+
error
.
message
)
})
},
// 获取标签名称
getTagName
(
tagId
)
{
const
tag
=
this
.
tagsMap
[
tagId
]
return
tag
?
tag
.
name
:
'未知标签'
},
// 获取标签路径
getTagPath
(
tag
)
{
if
(
!
tag
)
return
''
const
path
=
[]
let
currentTag
=
tag
while
(
currentTag
)
{
path
.
unshift
(
currentTag
.
name
)
if
(
currentTag
.
parentId
)
{
currentTag
=
this
.
tagsMap
[
currentTag
.
parentId
]
}
else
{
break
}
}
return
path
.
join
(
' / '
)
},
// 处理标签变化
handleTagChange
()
{
this
.
fetchData
()
},
// 重置过滤条件
resetFilter
()
{
this
.
condition
=
{
tags
:
[]
}
this
.
fetchData
()
},
// 处理分页大小变化
handleSizeChange
(
val
)
{
this
.
pagination
.
pageSize
=
val
this
.
fetchData
()
},
// 处理页码变化
handleCurrentChange
(
val
)
{
this
.
pagination
.
currentPage
=
val
this
.
fetchData
()
},
// 显示新增对话框
showAddDialog
()
{
// 先重置表单
this
.
form
=
{
id
:
null
,
name
:
''
,
tags
:
[],
remark
:
''
}
// 设置对话框标题并显示
this
.
dialogTitle
=
'新增素材组'
this
.
dialogVisible
=
true
// 重置表单验证
this
.
$nextTick
(()
=>
{
if
(
this
.
$refs
.
form
)
{
this
.
$refs
.
form
.
resetFields
()
}
})
},
// 处理编辑
handleEdit
(
row
)
{
// 先重置表单
this
.
form
=
{
id
:
null
,
name
:
''
,
tags
:
[],
remark
:
''
}
// 然后设置对话框标题并显示
this
.
dialogTitle
=
'编辑素材组'
this
.
dialogVisible
=
true
// 从原始数据中获取完整数据
const
fullData
=
this
.
originalData
.
find
(
item
=>
item
.
id
===
row
.
id
)
console
.
log
(
'编辑素材组数据:'
,
fullData
||
row
)
// 设置表单数据
const
dataToUse
=
fullData
||
row
// 先重置form对象
this
.
$set
(
this
,
'form'
,
{
id
:
null
,
name
:
''
,
tags
:
[],
remark
:
''
})
// 使用nextTick确保DOM更新后再设置新值
this
.
$nextTick
(()
=>
{
// 使用Vue.set确保响应式更新
this
.
$set
(
this
,
'form'
,
{
id
:
dataToUse
.
id
,
name
:
dataToUse
.
name
,
tags
:
Array
.
isArray
(
dataToUse
.
tags
)
?
[...
dataToUse
.
tags
]
:
[],
remark
:
dataToUse
.
remark
||
''
})
console
.
log
(
'设置表单数据:'
,
this
.
form
)
})
// 重置表单验证
this
.
$nextTick
(()
=>
{
if
(
this
.
$refs
.
form
)
{
this
.
$refs
.
form
.
resetFields
()
}
})
},
// 处理删除
handleDelete
(
row
)
{
this
.
$confirm
(
'确认删除该素材组吗?'
,
'提示'
,
{
confirmButtonText
:
'确定'
,
cancelButtonText
:
'取消'
,
type
:
'warning'
}).
then
(()
=>
{
deleteMaterialGroup
(
row
.
id
).
then
(
response
=>
{
if
(
response
.
status
===
200
)
{
this
.
$message
.
success
(
'删除成功'
)
this
.
fetchData
()
}
else
{
this
.
$message
.
error
(
'删除失败: '
+
response
.
message
)
}
}).
catch
(
error
=>
{
console
.
error
(
'删除素材组失败:'
,
error
)
this
.
$message
.
error
(
'删除失败: '
+
error
.
message
)
})
}).
catch
(()
=>
{
// 取消删除
})
},
// 处理表单标签变化
handleFormTagChange
(
tags
)
{
console
.
log
(
'标签变化:'
,
tags
)
if
(
Array
.
isArray
(
tags
))
{
// 使用JSON序列化确保断开引用
this
.
form
.
tags
=
JSON
.
parse
(
JSON
.
stringify
(
tags
))
}
else
{
this
.
form
.
tags
=
[]
}
// 强制触发数据更新
this
.
$forceUpdate
()
},
// 提交表单
submitForm
()
{
this
.
$refs
.
form
.
validate
(
valid
=>
{
if
(
valid
)
{
const
formData
=
{
name
:
this
.
form
.
name
,
tags
:
this
.
form
.
tags
,
remark
:
this
.
form
.
remark
}
if
(
this
.
form
.
id
)
{
// 更新
updateMaterialGroup
(
this
.
form
.
id
,
formData
).
then
(
response
=>
{
if
(
response
.
status
===
200
)
{
this
.
$message
.
success
(
'更新成功'
)
this
.
dialogVisible
=
false
this
.
fetchData
()
}
else
{
this
.
$message
.
error
(
'更新失败: '
+
response
.
message
)
}
}).
catch
(
error
=>
{
console
.
error
(
'更新素材组失败:'
,
error
)
this
.
$message
.
error
(
'更新失败: '
+
error
.
message
)
})
}
else
{
// 新增
createMaterialGroup
(
formData
).
then
(
response
=>
{
if
(
response
.
status
===
200
)
{
this
.
$message
.
success
(
'创建成功'
)
this
.
dialogVisible
=
false
this
.
fetchData
()
}
else
{
this
.
$message
.
error
(
'创建失败: '
+
response
.
message
)
}
}).
catch
(
error
=>
{
console
.
error
(
'创建素材组失败:'
,
error
)
this
.
$message
.
error
(
'创建失败: '
+
error
.
message
)
})
}
}
else
{
return
false
}
})
}
}
}
</
script
>
<
style
scoped
>
.material-group-container
{
padding
:
20px
;
}
.filter-section
{
margin-bottom
:
20px
;
}
.header-actions
{
display
:
flex
;
justify-content
:
space-between
;
margin-bottom
:
20px
;
}
.pagination-container
{
margin-top
:
20px
;
text-align
:
right
;
}
.no-tags
{
color
:
#999
;
font-size
:
12px
;
}
.tag-item
{
margin
:
2px
;
}
</
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