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
b5334e6d
Commit
b5334e6d
authored
Mar 05, 2025
by
lijin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
增加标题组管理页面
parent
77df13d1
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
823 additions
and
6 deletions
+823
-6
titleGroup.js
src/api/titleGroup.js
+41
-0
LocationGroupSelector.vue
src/components/GroupSelectors/LocationGroupSelector.vue
+6
-1
TitleGroupSelector.vue
src/components/GroupSelectors/TitleGroupSelector.vue
+5
-1
index.vue
src/components/TextTableSelecter/index.vue
+399
-0
index.js
src/router/index.js
+6
-0
CampaignTemplateManage.vue
src/views/campaignTemplate/CampaignTemplateManage.vue
+2
-2
index.vue
src/views/copywritingLibrary/index.vue
+2
-1
Layout.vue
src/views/layout/Layout.vue
+1
-1
TitleGroupManage.vue
src/views/titleGroup/TitleGroupManage.vue
+361
-0
No files found.
src/api/titleGroup.js
0 → 100644
View file @
b5334e6d
import
axios
from
'axios'
// 获取所有标题组
export
function
getTitleGroupList
()
{
return
axios
.
get
(
process
.
env
.
PUTIN_API
+
'/title-groups'
)
.
then
(
response
=>
{
return
response
.
data
})
}
// 获取单个标题组
export
function
getTitleGroupById
(
id
)
{
return
axios
.
get
(
`
${
process
.
env
.
PUTIN_API
}
/title-groups/
${
id
}
`
)
.
then
(
response
=>
{
return
response
.
data
})
}
// 创建标题组
export
function
createTitleGroup
(
data
)
{
return
axios
.
post
(
`
${
process
.
env
.
PUTIN_API
}
/title-groups`
,
data
)
.
then
(
response
=>
{
return
response
.
data
})
}
// 更新标题组
export
function
updateTitleGroup
(
id
,
data
)
{
return
axios
.
put
(
`
${
process
.
env
.
PUTIN_API
}
/title-groups/
${
id
}
`
,
data
)
.
then
(
response
=>
{
return
response
.
data
})
}
// 删除标题组
export
function
deleteTitleGroup
(
id
)
{
return
axios
.
delete
(
`
${
process
.
env
.
PUTIN_API
}
/title-groups/
${
id
}
`
)
.
then
(
response
=>
{
return
response
.
data
})
}
src/components/GroupSelectors/LocationGroupSelector.vue
View file @
b5334e6d
...
...
@@ -48,9 +48,14 @@ export default {
async
fetchOptions
()
{
try
{
const
response
=
await
axios
.
get
(
process
.
env
.
PUTIN_API
+
'/location-groups'
)
this
.
options
=
response
.
data
if
(
response
.
data
.
status
===
200
)
{
this
.
options
=
response
.
data
.
result
.
data
}
else
{
this
.
$message
.
error
(
'获取地域组失败'
)
}
}
catch
(
error
)
{
console
.
error
(
'Failed to fetch location groups:'
,
error
)
this
.
$message
.
error
(
'获取地域组失败:'
+
error
.
message
)
}
},
handleChange
(
values
)
{
...
...
src/components/GroupSelectors/TitleGroupSelector.vue
View file @
b5334e6d
...
...
@@ -48,7 +48,11 @@ export default {
async
fetchOptions
()
{
try
{
const
response
=
await
axios
.
get
(
process
.
env
.
PUTIN_API
+
'/title-groups'
)
this
.
options
=
response
.
data
if
(
response
.
data
.
status
===
200
)
{
this
.
options
=
response
.
data
.
result
.
data
||
[]
}
else
{
console
.
error
(
'Failed to fetch title groups: API returned non-200 status'
)
}
}
catch
(
error
)
{
console
.
error
(
'Failed to fetch title groups:'
,
error
)
}
...
...
src/components/TextTableSelecter/index.vue
0 → 100644
View file @
b5334e6d
<
template
>
<div
class=
"text-table-selecter-container"
>
<!-- Filter section -->
<div
class=
"filter-section"
>
<el-form
:inline=
"true"
:model=
"condition"
class=
"filter-form"
>
<el-form-item
label=
"关联应用"
>
<el-select
v-model=
"condition.appId"
placeholder=
"关联应用"
@
change=
"fetchData"
filterable
clearable
>
<el-option
v-for=
"item in selectApps"
:key=
"item.id"
:label=
"item.label"
:value=
"item.id"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item
label=
"日期范围"
>
<zx-date-picker
end-date=
"today"
interval-days=
"7"
v-model=
"dateTime"
@
change=
"fetchData"
clearable
></zx-date-picker>
</el-form-item>
<el-form-item
label=
"文案类型"
>
<el-select
v-model=
"condition.type"
placeholder=
"文案类型"
@
change=
"fetchData"
clearable
:disabled=
"!!fixedType"
>
<el-option
label=
"标题"
value=
"1"
></el-option>
<el-option
label=
"描述"
value=
"2"
></el-option>
</el-select>
</el-form-item>
<el-form-item
label=
"分类"
>
<app-category-selector
v-model=
"condition.category"
@
change=
"fetchData"
/>
</el-form-item>
</el-form>
</div>
<el-divider></el-divider>
<!-- Table Header actions -->
<div
class=
"header-actions"
>
<div
class=
"selected-info"
v-if=
"selectedRows.length > 0"
>
已选择
<span
class=
"selected-count"
>
{{
selectedRows
.
length
}}
</span>
条文案
<el-button
size=
"mini"
type=
"text"
@
click=
"clearSelection"
>
清空选择
</el-button>
</div>
<div
class=
"header-right"
>
<el-button
icon=
"el-icon-refresh"
@
click=
"fetchData"
>
刷新
</el-button>
</div>
</div>
<!-- Main table -->
<el-table
ref=
"multipleTable"
:data=
"tableData"
border
style=
"width: 100%;"
v-loading=
"loading"
row-key=
"id"
@
selection-change=
"handleSelectionChange"
>
<el-table-column
type=
"selection"
width=
"55"
>
</el-table-column>
<el-table-column
prop=
"id"
label=
"ID"
width=
"80"
></el-table-column>
<el-table-column
prop=
"text"
label=
"文案内容"
min-width=
"350"
>
<template
slot-scope=
"scope"
>
<div
class=
"text-content"
>
{{
scope
.
row
.
text
}}
</div>
</
template
>
</el-table-column>
<el-table-column
prop=
"type"
label=
"文案类型"
width=
"120"
>
<
template
slot-scope=
"scope"
>
<el-tag
:type=
"scope.row.type === 1 ? 'primary' : 'success'"
>
{{
scope
.
row
.
type
===
1
?
'标题'
:
'描述'
}}
</el-tag>
</
template
>
</el-table-column>
<el-table-column
prop=
"datadate"
label=
"创建时间"
width=
"180"
></el-table-column>
</el-table>
<!-- Pagination -->
<div
class=
"pagination-container"
>
<el-pagination
@
size-change=
"handleSizeChange"
@
current-change=
"handleCurrentChange"
:current-page=
"currentPage"
:page-sizes=
"[10, 20, 50, 100]"
:page-size=
"pageSize"
:total=
"total"
layout=
"total, prev, pager, next, sizes"
>
</el-pagination>
</div>
</div>
</template>
<
script
>
import
{
getBusinText
,
getSelectApps
}
from
"@/api/cloud"
;
import
AppCategorySelector
from
"@/components/Selectors/AppCategorySelector"
;
export
default
{
name
:
'TextTableSelecter'
,
components
:
{
AppCategorySelector
},
props
:
{
// 双向绑定的选中文案数组
value
:
{
type
:
Array
,
default
:
()
=>
[]
},
// 固定的文案类型,如果传入则不可更改
type
:
{
type
:
String
,
default
:
""
}
},
data
()
{
return
{
// 表格数据
tableData
:
[],
loading
:
false
,
total
:
0
,
currentPage
:
1
,
pageSize
:
20
,
// 筛选条件
condition
:
{
appId
:
""
,
type
:
""
,
startDate
:
""
,
endDate
:
""
,
category
:
""
},
// 应用选择器数据
selectApps
:
[],
// 选中的行数据
selectedRows
:
[],
// 已选中的行ID映射,用于保存跨页选择
selectedRowMap
:
{}
};
},
computed
:
{
dateTime
:
{
get
()
{
if
(
this
.
condition
.
startDate
&&
this
.
condition
.
endDate
)
{
return
[
this
.
condition
.
startDate
,
this
.
condition
.
endDate
];
}
else
{
return
[];
}
},
set
(
v
)
{
if
(
v
&&
v
.
length
===
2
)
{
this
.
condition
.
startDate
=
v
[
0
];
this
.
condition
.
endDate
=
v
[
1
];
}
else
{
this
.
condition
.
startDate
=
""
;
this
.
condition
.
endDate
=
""
;
}
}
},
// 固定的文案类型
fixedType
()
{
return
this
.
type
||
""
;
}
},
watch
:
{
// 监听外部value变化,更新内部选中状态
value
:
{
handler
(
newVal
)
{
console
.
log
(
'Value changed:'
,
newVal
);
// 更新选中的行ID映射
this
.
selectedRowMap
=
{};
if
(
Array
.
isArray
(
newVal
))
{
newVal
.
forEach
(
item
=>
{
if
(
item
&&
item
.
id
)
{
this
.
selectedRowMap
[
item
.
id
]
=
item
;
}
});
}
// 如果表格已加载,更新表格选中状态
this
.
$nextTick
(()
=>
{
this
.
updateTableSelection
();
});
// 同步更新selectedRows
this
.
selectedRows
=
Object
.
values
(
this
.
selectedRowMap
);
},
immediate
:
true
,
deep
:
true
},
// 监听固定类型变化
type
:
{
handler
(
newVal
)
{
if
(
newVal
)
{
this
.
condition
.
type
=
newVal
;
this
.
fetchData
();
}
},
immediate
:
true
}
},
created
()
{
this
.
fetchApps
();
this
.
fetchData
();
// 确保初始化时选中状态正确
if
(
Array
.
isArray
(
this
.
value
)
&&
this
.
value
.
length
>
0
)
{
console
.
log
(
'Initial value in created:'
,
this
.
value
);
this
.
value
.
forEach
(
item
=>
{
if
(
item
&&
item
.
id
)
{
this
.
selectedRowMap
[
item
.
id
]
=
item
;
}
});
this
.
selectedRows
=
Object
.
values
(
this
.
selectedRowMap
);
}
},
mounted
()
{
// 确保表格渲染后选中状态正确
this
.
$nextTick
(()
=>
{
this
.
updateTableSelection
();
console
.
log
(
'Table mounted, selection updated'
);
});
},
methods
:
{
// 获取应用列表
async
fetchApps
()
{
try
{
const
params
=
{
platformId
:
5
,
menuCode
:
"game.Overview,android"
,
};
const
response
=
await
getSelectApps
(
params
);
console
.
log
(
"相应"
,
response
)
if
(
response
.
status
===
200
)
{
this
.
selectApps
=
response
.
result
.
data
||
[];
}
}
catch
(
error
)
{
console
.
error
(
"获取应用列表失败:"
,
error
);
this
.
$message
.
error
(
"获取应用列表失败"
);
}
},
// 获取文案列表
async
fetchData
()
{
this
.
loading
=
true
;
try
{
const
params
=
{
page
:
this
.
currentPage
,
size
:
this
.
pageSize
,
appId
:
this
.
condition
.
appId
||
''
,
type
:
this
.
condition
.
type
||
''
,
startDate
:
this
.
condition
.
startDate
||
''
,
endDate
:
this
.
condition
.
endDate
||
''
,
category
:
this
.
condition
.
category
||
''
};
const
response
=
await
getBusinText
(
params
);
if
(
response
&&
response
.
result
)
{
this
.
tableData
=
response
.
result
.
data
.
content
||
[];
this
.
total
=
response
.
result
.
data
.
total
||
0
;
// 更新表格选中状态
this
.
$nextTick
(()
=>
{
this
.
updateTableSelection
();
});
}
}
catch
(
error
)
{
console
.
error
(
"获取文案列表失败:"
,
error
);
this
.
$message
.
error
(
"获取文案列表失败"
);
}
finally
{
this
.
loading
=
false
;
}
},
// 分页处理
handleSizeChange
(
val
)
{
this
.
pageSize
=
val
;
this
.
fetchData
();
},
handleCurrentChange
(
val
)
{
this
.
currentPage
=
val
;
this
.
fetchData
();
},
// 处理表格选择变化
handleSelectionChange
(
rows
)
{
console
.
log
(
'Selection changed:'
,
rows
);
// 更新当前页的选中状态到映射中
rows
.
forEach
(
row
=>
{
this
.
selectedRowMap
[
row
.
id
]
=
row
;
});
// 当前页中未被选中的行,从映射中移除
this
.
tableData
.
forEach
(
row
=>
{
if
(
!
rows
.
some
(
selectedRow
=>
selectedRow
.
id
===
row
.
id
))
{
delete
this
.
selectedRowMap
[
row
.
id
];
}
});
// 更新选中的行数组
this
.
selectedRows
=
Object
.
values
(
this
.
selectedRowMap
);
console
.
log
(
'Updated selectedRows:'
,
this
.
selectedRows
);
// 向父组件发送更新
// this.$emit('input', this.selectedRows);
this
.
$emit
(
'change'
,
this
.
selectedRows
);
},
// 更新表格选中状态
updateTableSelection
()
{
if
(
!
this
.
$refs
.
multipleTable
)
return
;
// 先清空所有选择
this
.
$refs
.
multipleTable
.
clearSelection
();
// 根据selectedRowMap选中对应行
this
.
$nextTick
(()
=>
{
this
.
tableData
.
forEach
(
row
=>
{
if
(
this
.
selectedRowMap
[
row
.
id
])
{
this
.
$refs
.
multipleTable
.
toggleRowSelection
(
row
,
true
);
}
});
});
},
// 清空选择
clearSelection
()
{
this
.
selectedRowMap
=
{};
this
.
selectedRows
=
[];
if
(
this
.
$refs
.
multipleTable
)
{
this
.
$refs
.
multipleTable
.
clearSelection
();
}
this
.
$emit
(
'input'
,
[]);
this
.
$emit
(
'change'
,
[]);
console
.
log
(
'Selection cleared'
);
}
}
};
</
script
>
<
style
scoped
>
.text-table-selecter-container
{
padding
:
10px
;
}
.filter-section
{
margin-bottom
:
10px
;
}
.header-actions
{
display
:
flex
;
justify-content
:
space-between
;
margin-bottom
:
15px
;
}
.selected-info
{
display
:
flex
;
align-items
:
center
;
}
.header-right
{
margin-left
:
auto
;
}
.selected-count
{
color
:
#409EFF
;
font-weight
:
bold
;
margin
:
0
5px
;
}
.text-content
{
white-space
:
pre-wrap
;
word-break
:
break-all
;
}
.pagination-container
{
margin-top
:
15px
;
text-align
:
right
;
}
</
style
>
src/router/index.js
View file @
b5334e6d
...
...
@@ -138,6 +138,12 @@ export const constantRouterMap = [
component
:
()
=>
import
(
'@/views/locationGroup/LocationGroupManage'
),
meta
:
{
title
:
'地域组管理'
}
},
{
path
:
'/assetManagement/title-group'
,
name
:
'assetManagement.title-group'
,
component
:
()
=>
import
(
'@/views/titleGroup/TitleGroupManage'
),
meta
:
{
title
:
'标题组管理'
}
},
]
},
...
...
src/views/campaignTemplate/CampaignTemplateManage.vue
View file @
b5334e6d
...
...
@@ -337,9 +337,9 @@ export default {
])
app
.
data
.
forEach
(
item
=>
this
.
groupNameMaps
.
app
.
set
(
item
.
id
,
item
.
name
))
location
.
data
.
forEach
(
item
=>
this
.
groupNameMaps
.
location
.
set
(
item
.
id
,
item
.
name
))
location
.
data
.
result
.
data
.
forEach
(
item
=>
this
.
groupNameMaps
.
location
.
set
(
item
.
id
,
item
.
name
))
material
.
data
.
forEach
(
item
=>
this
.
groupNameMaps
.
material
.
set
(
item
.
id
,
item
.
name
))
title
.
data
.
forEach
(
item
=>
this
.
groupNameMaps
.
title
.
set
(
item
.
id
,
item
.
name
))
title
.
data
.
result
.
data
.
forEach
(
item
=>
this
.
groupNameMaps
.
title
.
set
(
item
.
id
,
item
.
name
))
description
.
data
.
forEach
(
item
=>
this
.
groupNameMaps
.
description
.
set
(
item
.
id
,
item
.
name
))
}
catch
(
error
)
{
console
.
error
(
'获取组名称失败:'
,
error
)
...
...
src/views/copywritingLibrary/index.vue
View file @
b5334e6d
...
...
@@ -316,7 +316,7 @@ export default {
menuCode
:
"game.Overview,android"
,
};
const
response
=
await
getSelectApps
(
params
);
if
(
response
&&
response
.
result
)
{
if
(
response
.
status
===
200
)
{
this
.
selectApps
=
response
.
result
.
data
||
[];
}
}
catch
(
error
)
{
...
...
@@ -340,6 +340,7 @@ export default {
};
const
response
=
await
getBusinText
(
params
);
if
(
response
&&
response
.
result
)
{
this
.
tableData
=
response
.
result
.
data
.
content
||
[];
this
.
total
=
response
.
result
.
data
.
total
||
0
;
...
...
src/views/layout/Layout.vue
View file @
b5334e6d
...
...
@@ -30,7 +30,7 @@
<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/createDelivery"
>
素材组
</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/createDelivery"
>
描述组
</el-menu-item>
</el-submenu>
...
...
src/views/titleGroup/TitleGroupManage.vue
0 → 100644
View file @
b5334e6d
<
template
>
<div
class=
"title-group-container"
>
<!-- 表格头部操作 -->
<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"
>
<div
v-for=
"(title, index) in scope.row.titles"
:key=
"index"
class=
"title-item"
>
{{
title
}}
</div>
<div
v-if=
"!scope.row.titles || scope.row.titles.length === 0"
class=
"no-titles"
>
暂无标题
</div>
</
template
>
</el-table-column>
<!-- <el-table-column prop="createdAt" label="创建时间" width="180">
<template slot-scope="scope">
{{ formatDate(scope.row.createdAt) }}
</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=
"currentPage"
:page-sizes=
"[10, 20, 50, 100]"
:page-size=
"pageSize"
:total=
"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=
"titles"
>
<div
class=
"title-selector-container"
>
<div
class=
"selected-titles"
v-if=
"form.titles && form.titles.length > 0"
>
<div
class=
"selected-title-header"
>
<span>
已选择 {{ form.titles.length }} 个标题
</span>
<el-button
type=
"text"
@
click=
"form.titles = []"
>
清空
</el-button>
</div>
<el-tag
v-for=
"(title, index) in form.titles"
:key=
"index"
closable
@
close=
"removeTitle(index)"
class=
"title-tag"
>
{{ title }}
</el-tag>
</div>
<el-button
type=
"primary"
size=
"small"
@
click=
"showTitleSelectorDialog"
>
添加标题
</el-button>
</div>
</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>
<!-- 标题选择器对话框 -->
<el-dialog
title=
"选择标题"
:visible
.
sync=
"titleSelectorDialogVisible"
width=
"80%"
append-to-body
>
<text-table-selecter
@
change=
"handleTitleSelectionChange"
type=
"1"
>
</text-table-selecter>
<div
slot=
"footer"
class=
"dialog-footer"
>
<el-button
@
click=
"titleSelectorDialogVisible = false"
>
取 消
</el-button>
<el-button
type=
"primary"
@
click=
"confirmTitleSelection"
>
确 定
</el-button>
</div>
</el-dialog>
</div>
</template>
<
script
>
import
TextTableSelecter
from
'@/components/TextTableSelecter'
import
{
getTitleGroupList
,
createTitleGroup
,
updateTitleGroup
,
deleteTitleGroup
}
from
'@/api/titleGroup'
export
default
{
name
:
'TitleGroupManage'
,
components
:
{
TextTableSelecter
},
data
()
{
return
{
loading
:
false
,
tableData
:
[],
currentPage
:
1
,
pageSize
:
10
,
total
:
0
,
dialogVisible
:
false
,
dialogTitle
:
''
,
titleSelectorDialogVisible
:
false
,
selectedTitles
:
[],
// 用于TextTableSelecter组件的选中项
form
:
{
id
:
null
,
name
:
''
,
titles
:
[],
remark
:
''
},
rules
:
{
name
:
[
{
required
:
true
,
message
:
'请输入标题组名称'
,
trigger
:
'blur'
}
]
}
}
},
created
()
{
this
.
fetchData
()
},
methods
:
{
// 获取标题组列表
fetchData
()
{
this
.
loading
=
true
getTitleGroupList
()
.
then
(
response
=>
{
this
.
loading
=
false
if
(
response
.
status
===
200
)
{
this
.
tableData
=
response
.
result
.
data
||
[]
this
.
total
=
this
.
tableData
.
length
}
else
{
this
.
$message
.
error
(
'获取标题组列表失败'
)
}
})
.
catch
(
error
=>
{
this
.
loading
=
false
console
.
error
(
'获取标题组列表失败:'
,
error
)
this
.
$message
.
error
(
'获取标题组列表失败: '
+
error
.
message
)
})
},
// 格式化日期
formatDate
(
date
)
{
if
(
!
date
)
return
''
const
d
=
new
Date
(
date
)
return
d
.
toLocaleString
()
},
// 分页处理
handleSizeChange
(
val
)
{
this
.
pageSize
=
val
this
.
fetchData
()
},
handleCurrentChange
(
val
)
{
this
.
currentPage
=
val
this
.
fetchData
()
},
// 显示新增对话框
showAddDialog
()
{
this
.
dialogTitle
=
'新增标题组'
this
.
form
=
{
id
:
null
,
name
:
''
,
titles
:
[],
remark
:
''
}
this
.
dialogVisible
=
true
// 重置表单验证
if
(
this
.
$refs
.
form
)
{
this
.
$refs
.
form
.
resetFields
()
}
},
// 处理编辑
handleEdit
(
row
)
{
this
.
dialogTitle
=
'编辑标题组'
// 深拷贝避免直接修改表格数据
this
.
form
=
JSON
.
parse
(
JSON
.
stringify
(
row
))
this
.
dialogVisible
=
true
// 重置表单验证
this
.
$nextTick
(()
=>
{
if
(
this
.
$refs
.
form
)
{
this
.
$refs
.
form
.
clearValidate
()
}
})
},
handleTitleSelectionChange
(
data
){
this
.
selectedTitles
=
data
},
// 处理删除
handleDelete
(
row
)
{
this
.
$confirm
(
'此操作将永久删除该标题组, 是否继续?'
,
'提示'
,
{
confirmButtonText
:
'确定'
,
cancelButtonText
:
'取消'
,
type
:
'warning'
}).
then
(()
=>
{
deleteTitleGroup
(
row
.
id
)
.
then
(
response
=>
{
if
(
response
.
status
===
200
)
{
this
.
$message
.
success
(
'删除成功'
)
this
.
fetchData
()
}
else
{
this
.
$message
.
error
(
'删除失败'
)
}
})
.
catch
(
error
=>
{
console
.
error
(
'删除标题组失败:'
,
error
)
this
.
$message
.
error
(
'删除标题组失败: '
+
error
.
message
)
})
}).
catch
(()
=>
{
})
},
// 提交表单
submitForm
()
{
this
.
$refs
.
form
.
validate
(
valid
=>
{
if
(
valid
)
{
const
isEdit
=
!!
this
.
form
.
id
const
formData
=
{
...
this
.
form
}
const
apiCall
=
isEdit
?
updateTitleGroup
(
formData
.
id
,
formData
)
:
createTitleGroup
(
formData
)
apiCall
.
then
(
response
=>
{
if
(
response
.
status
===
200
)
{
this
.
$message
.
success
(
isEdit
?
'更新成功'
:
'创建成功'
)
this
.
dialogVisible
=
false
this
.
fetchData
()
}
else
{
this
.
$message
.
error
(
isEdit
?
'更新失败'
:
'创建失败'
)
}
})
.
catch
(
error
=>
{
console
.
error
(
isEdit
?
'更新标题组失败:'
:
'创建标题组失败:'
,
error
)
this
.
$message
.
error
((
isEdit
?
'更新'
:
'创建'
)
+
'标题组失败: '
+
error
.
message
)
})
}
else
{
return
false
}
})
},
// 显示标题选择器对话框
showTitleSelectorDialog
()
{
this
.
selectedTitles
=
[]
this
.
titleSelectorDialogVisible
=
true
},
// 确认标题选择
confirmTitleSelection
()
{
// 提取文本内容并添加到标题列表
const
newTitles
=
this
.
selectedTitles
.
map
(
item
=>
item
.
text
)
// 合并去重
const
uniqueTitles
=
[...
new
Set
([...
this
.
form
.
titles
,
...
newTitles
])]
this
.
form
.
titles
=
uniqueTitles
this
.
titleSelectorDialogVisible
=
false
},
// 移除标题
removeTitle
(
index
)
{
this
.
form
.
titles
.
splice
(
index
,
1
)
}
}
}
</
script
>
<
style
scoped
>
.title-group-container
{
padding
:
20px
;
}
.header-actions
{
display
:
flex
;
justify-content
:
space-between
;
margin-bottom
:
20px
;
}
.title-item
{
margin-bottom
:
5px
;
line-height
:
1.5
;
word-break
:
break-all
;
}
.no-titles
{
color
:
#999
;
font-style
:
italic
;
}
.pagination-container
{
margin-top
:
20px
;
text-align
:
right
;
}
.title-selector-container
{
margin-bottom
:
10px
;
}
.selected-titles
{
margin-bottom
:
10px
;
padding
:
10px
;
border
:
1px
solid
#e6e6e6
;
border-radius
:
4px
;
background-color
:
#f9f9f9
;
}
.selected-title-header
{
display
:
flex
;
justify-content
:
space-between
;
margin-bottom
:
10px
;
padding-bottom
:
5px
;
border-bottom
:
1px
solid
#eee
;
}
.title-tag
{
margin-right
:
5px
;
margin-bottom
:
5px
;
max-width
:
100%
;
overflow
:
hidden
;
text-overflow
:
ellipsis
;
white-space
:
nowrap
;
}
</
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