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
32d1f7d7
Commit
32d1f7d7
authored
Feb 25, 2025
by
lijin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
优化素材上传
parent
011cb0f5
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
461 additions
and
394 deletions
+461
-394
report.js
src/api/report.js
+18
-0
index.vue
src/components/DesignerSelect/index.vue
+84
-0
index.vue
src/components/FileUpload/index.vue
+4
-5
index.vue
src/components/MaterialTagSelect/index.vue
+240
-0
index.js
src/router/index.js
+13
-12
MaterialUpload.vue
src/views/createMaterial/MaterialUpload.vue
+102
-31
CascaderSelect.vue
src/views/materialTag/components/CascaderSelect.vue
+0
-346
No files found.
src/api/report.js
View file @
32d1f7d7
...
...
@@ -621,5 +621,23 @@ export function deleteYouTubeAccountById(params) {
params
})
}
export
function
fetchMaterialTags
()
{
return
request
({
url
:
process
.
env
.
PUTIN_API
+
'/material_tags/'
,
method
:
'get'
})
}
export
function
addMaterial
(
data
)
{
return
request
({
url
:
process
.
env
.
PUTIN_API
+
'/material/youtube/addMaterial'
,
method
:
'post'
,
data
})
}
// ----------------------------------------
src/components/DesignerSelect/index.vue
0 → 100644
View file @
32d1f7d7
<
template
>
<div>
<slot></slot>
<el-select
:value=
"value"
filterable
clearable
placeholder=
"请选择"
@
change=
"handleChange"
>
<el-option
v-for=
"item in list"
:key=
"item.id"
:label=
"item.realName"
:value=
"item.id"
/>
</el-select>
</div>
</
template
>
<
script
>
import
{
getMaterialDesigners
,
}
from
'@/api/report'
;
export
default
{
name
:
"DesignerSelect"
,
model
:
{
prop
:
"value"
,
event
:
"change"
,
},
props
:
{
defaultValue
:
{
type
:
String
,
required
:
false
,
},
addAllOption
:
{
type
:
[
Boolean
,
String
],
required
:
false
,
},
value
:
{
type
:
[
String
,
Number
],
},
},
data
()
{
return
{
selectValue
:
parseInt
(
localStorage
.
getItem
(
'uid'
))
||
''
,
list
:
[],
};
},
created
()
{
this
.
init
();
},
// 子组件监控日期组件的值发生变化的时候,通过emit传给父组件,父组件用v-model接收。这样就把子组件的v-model功能,传给了父组件
watch
:
{
value
(
val
)
{
this
.
$emit
(
"input"
,
val
);
},
},
methods
:
{
// 获取App名称配置列表
init
:
function
()
{
// this.selectValue = this.defaultValue;
getMaterialDesigners
({
}).
then
((
res
)
=>
{
this
.
list
=
res
.
result
.
data
this
.
$emit
(
"list"
,
this
.
list
);
if
(
this
.
addAllOption
==
"true"
)
{
this
.
list
.
unshift
({
lable
:
"全部"
,
value
:
""
,
});
}
});
},
handleChange
(
value
)
{
this
.
$emit
(
"change"
,
value
);
this
.
$emit
(
'input'
,
value
);
},
},
};
</
script
>
src/components/FileUpload/index.vue
View file @
32d1f7d7
...
...
@@ -218,11 +218,10 @@ export default {
// 构建成功文件的信息对象
const
successFileInfo
=
{
name
:
file
.
name
,
url
:
response
.
data
.
url
||
file
.
url
,
cdnUrl
:
response
.
data
.
result
.
data
.
url
,
type
:
file
.
type
,
size
:
file
.
size
,
response
:
response
.
data
cdnUrl
:
response
.
data
.
result
.
data
.
cdnUrl
,
fileMd5
:
response
.
data
.
result
.
data
.
fileMd5
,
type
:
response
.
data
.
result
.
data
.
type
,
size
:
file
.
size
}
console
.
log
(
"successFileInfo: "
,
successFileInfo
)
// 更新成功文件列表
...
...
src/components/MaterialTagSelect/index.vue
0 → 100644
View file @
32d1f7d7
<
template
>
<div
class=
"cascader-select"
>
<el-cascader
v-model=
"selectedValues"
:options=
"treeData"
:props=
"cascaderProps"
:placeholder=
"placeholder"
:show-all-levels=
"true"
:collapse-tags=
"true"
filterable
clearable
multiple
@
change=
"handleChange"
>
<template
slot-scope=
"
{ node, data }">
<span>
{{
data
.
name
}}
</span>
<span
v-if=
"!node.isLeaf"
class=
"custom-label"
>
(
{{
getChildLeafCount
(
data
)
}}
个选项)
</span>
</
template
>
</el-cascader>
<!-- 选中标签的详细展示 -->
<div
class=
"selected-tags"
v-if=
"value.length"
>
<el-tag
v-for=
"id in value"
:key=
"id"
closable
size=
"small"
class=
"tag-item"
@
close=
"handleRemoveTag(id)"
>
{{ getNodeFullPath(id) }}
</el-tag>
</div>
</div>
</template>
<
script
>
import
{
fetchMaterialTags
}
from
'@/api/report'
;
export
default
{
name
:
'MaterialTagSelect'
,
props
:
{
value
:
{
type
:
Array
,
default
:
()
=>
[]
},
placeholder
:
{
type
:
String
,
default
:
'请选择标签...'
}
},
data
()
{
return
{
selectedValues
:
[],
// 用于el-cascader的选中值(包含完整路径)
cascaderProps
:
{
multiple
:
true
,
checkStrictly
:
true
,
// 可以选择任意一级节点
value
:
'id'
,
label
:
'name'
,
children
:
'children'
,
emitPath
:
true
,
// 返回完整路径
leaf
:
'isLeaf'
},
tagData
:
[]
}
},
computed
:
{
// 转换为树形结构
treeData
()
{
return
this
.
buildTree
(
this
.
tagData
)
}
},
created
()
{
this
.
fetchTags
()
},
watch
:
{
// 监听外部value变化,更新内部选中状态
value
:
{
immediate
:
true
,
handler
(
newVal
)
{
this
.
updateSelectedValues
(
newVal
)
}
}
},
methods
:
{
fetchTags
()
{
fetchMaterialTags
().
then
(
res
=>
{
if
(
res
.
status
===
200
)
{
this
.
tagData
=
res
.
result
.
data
.
map
(
item
=>
({
id
:
item
.
id
,
name
:
item
.
name
,
parentId
:
item
.
parentId
||
null
// 确保null值标准化处理
}));
}
else
{
this
.
$message
.
error
(
'获取素材标签失败'
);
}
}).
catch
(
error
=>
{
console
.
error
(
"请求失败:"
,
error
);
this
.
$message
.
error
(
'请求异常'
);
});
},
// 构建树形数据
buildTree
(
items
)
{
const
itemMap
=
new
Map
()
const
result
=
[]
// 创建所有节点
items
.
forEach
(
item
=>
{
const
node
=
{
id
:
item
.
id
,
name
:
item
.
name
,
parentId
:
item
.
parentId
,
children
:
[],
isLeaf
:
true
// 默认为叶子节点,后面会更新
}
itemMap
.
set
(
item
.
id
,
node
)
})
// 建立父子关系
items
.
forEach
(
item
=>
{
const
node
=
itemMap
.
get
(
item
.
id
)
if
(
item
.
parentId
===
null
)
{
result
.
push
(
node
)
}
else
{
const
parent
=
itemMap
.
get
(
item
.
parentId
)
if
(
parent
)
{
parent
.
children
.
push
(
node
)
parent
.
isLeaf
=
false
// 有子节点,不是叶子节点
}
}
})
return
result
},
// 获取节点的所有叶子节点数量
getChildLeafCount
(
node
)
{
let
count
=
0
const
countLeaves
=
(
n
)
=>
{
if
(
n
.
isLeaf
)
{
count
++
}
else
if
(
n
.
children
)
{
n
.
children
.
forEach
(
countLeaves
)
}
}
countLeaves
(
node
)
return
count
},
// 处理选择变化
handleChange
(
values
)
{
// values 是一个数组,每个元素都是一个路径数组
const
selectedIds
=
values
.
map
(
path
=>
path
[
path
.
length
-
1
])
// 获取每个路径的最后一个节点ID
.
filter
(
id
=>
this
.
isLeafNode
(
id
))
// 只保留叶子节点
this
.
$emit
(
'input'
,
selectedIds
)
this
.
$emit
(
'change'
,
selectedIds
)
},
// 判断是否为叶子节点
isLeafNode
(
id
)
{
const
findNode
=
(
nodes
)
=>
{
for
(
const
node
of
nodes
)
{
if
(
node
.
id
===
id
)
{
return
node
.
isLeaf
}
if
(
node
.
children
)
{
const
found
=
findNode
(
node
.
children
)
if
(
found
!==
undefined
)
{
return
found
}
}
}
}
return
findNode
(
this
.
treeData
)
},
// 获取节点完整路径名称
getNodeFullPath
(
id
)
{
const
path
=
[]
const
findPath
=
(
nodes
)
=>
{
for
(
const
node
of
nodes
)
{
path
.
push
(
node
.
name
)
if
(
node
.
id
===
id
)
{
return
true
}
if
(
node
.
children
&&
findPath
(
node
.
children
))
{
return
true
}
path
.
pop
()
}
return
false
}
findPath
(
this
.
treeData
)
return
path
.
join
(
' / '
)
},
// 处理标签移除
handleRemoveTag
(
id
)
{
const
newValue
=
this
.
value
.
filter
(
v
=>
v
!==
id
)
this
.
$emit
(
'input'
,
newValue
)
this
.
$emit
(
'change'
,
newValue
)
},
// 更新内部选中状态
updateSelectedValues
(
selectedIds
)
{
const
values
=
[]
const
findPaths
=
(
nodes
,
currentPath
=
[])
=>
{
for
(
const
node
of
nodes
)
{
const
path
=
[...
currentPath
,
node
.
id
]
if
(
selectedIds
.
includes
(
node
.
id
)
&&
node
.
isLeaf
)
{
values
.
push
(
path
)
}
if
(
node
.
children
)
{
findPaths
(
node
.
children
,
path
)
}
}
}
findPaths
(
this
.
treeData
)
this
.
selectedValues
=
values
}
}
}
</
script
>
<
style
scoped
>
</
style
>
src/router/index.js
View file @
32d1f7d7
...
...
@@ -120,6 +120,19 @@ export const constantRouterMap = [
name
:
"tools.Youtube"
,
component
:
()
=>
import
(
"@/views/createMaterial/AdMaterialManager"
),
meta
:
{
title
:
"Youtube管理"
,
icon
:
"chart"
}
},
{
path
:
"/materialUpload"
,
// 资产上传
name
:
"materialUpload"
,
component
:
()
=>
import
(
'@/views/createMaterial/MaterialUpload'
),
hidden
:
true
},
{
path
:
"/materialTag"
,
// 素材标签管理
name
:
"materialTag"
,
component
:
()
=>
import
(
'@/views/materialTag'
),
hidden
:
true
}
]
},
...
...
@@ -134,19 +147,7 @@ export const constantRouterMap = [
}]
},
{
path
:
"/materialUpload"
,
// 资产上传
name
:
"materialUpload"
,
component
:
()
=>
import
(
'@/views/createMaterial/MaterialUpload'
),
hidden
:
true
},
{
path
:
"/materialTag"
,
// 素材标签管理
name
:
"materialTag"
,
component
:
()
=>
import
(
'@/views/materialTag'
),
hidden
:
true
}
];
Vue
.
use
(
Router
);
...
...
src/views/createMaterial/MaterialUpload.vue
View file @
32d1f7d7
<
template
>
<div
class=
"upload-page"
>
<h2>
文件上传
</h2>
<!-- 使用上传组件 -->
<file-upload
:upload-url=
"uploadUrl"
:extra-data=
"extraData"
:headers=
"headers"
@
update:files=
"handleFilesUpdate"
@
upload-success=
"handleUploadSuccess"
@
upload-error=
"handleUploadError"
@
upload-complete=
"handleUploadComplete"
ref=
"uploadComponent"
>
<!-- 自定义上传按钮 -->
<template
#
trigger
>
<el-button
type=
"primary"
icon=
"el-icon-upload"
>
选择图片或视频
</el-button>
</
template
>
</file-upload>
<el-form
ref=
"uploadForm"
:model=
"uploadForm"
label-width=
"120px"
>
<el-form-item
label=
"素材上传"
>
<!-- 使用上传组件 -->
<file-upload
:upload-url=
"uploadUrl"
:extra-data=
"extraData"
:headers=
"headers"
@
update:files=
"handleFilesUpdate"
@
upload-success=
"handleUploadSuccess"
@
upload-error=
"handleUploadError"
@
upload-complete=
"handleUploadComplete"
ref=
"uploadComponent"
>
<!-- 自定义上传按钮 -->
<template
#
trigger
>
<el-button
type=
"primary"
icon=
"el-icon-upload"
>
选择图片或视频
</el-button>
</
template
>
</file-upload>
</el-form-item>
<el-form-item
label=
"选择标签"
>
<material-tag-select
v-model=
"uploadForm.tags"
placeholder=
"请选择标签..."
@
change=
"handleChange"
/>
</el-form-item>
<el-form-item
label=
"设计师"
>
<desigher-select
v-model=
"uploadForm.designer"
/>
</el-form-item>
<el-form-item
label=
"目录"
prop=
"directoryId"
:rules=
"[{ required: true, message: '请选择目录', trigger: 'change' }]"
>
<el-cascader
v-model=
"selectedDirectoryIds"
:options=
"directories"
:props=
"{ expandTrigger: 'hover', value:'id',label:'name', children:'children' }"
clearable
@
change=
"handleDirectoryChange"
placeholder=
"请选择目录"
style=
"width: 30%;"
></el-cascader>
</el-form-item>
<el-button
@
click=
"saveMaterial"
>
提交
</el-button>
</el-form>
<!-- 显示上传成功的文件列表 -->
<!-- <div class="success-files" v-if="successFiles.length > 0">-->
<!-- <div class="success-files" v-if="
uploadForm.
successFiles.length > 0">-->
<!-- <h3>已上传文件列表:</h3>-->
<!-- <el-table :data="successFiles" style="width: 100%">-->
<!-- <el-table :data="
uploadForm.
successFiles" style="width: 100%">-->
<!-- <el-table-column prop="name" label="文件名"></el-table-column>-->
<!-- <el-table-column prop="type" label="类型"></el-table-column>-->
<!-- <el-table-column prop="size" label="大小">-->
...
...
@@ -51,34 +80,50 @@
<
script
>
import
FileUpload
from
'../../components/FileUpload/index.vue'
import
MaterialTagSelect
from
'../../components/MaterialTagSelect/index.vue'
import
DesigherSelect
from
'../../components/DesignerSelect/index.vue'
import
{
getMaterialDirectoriesTree
,
addMaterial
,
}
from
'@/api/report'
;
export
default
{
name
:
'UploadPage'
,
components
:
{
FileUpload
FileUpload
,
MaterialTagSelect
,
DesigherSelect
},
data
()
{
return
{
uploadUrl
:
'http://localhost:8567/material/business/youtube/upload
Video
'
,
successFiles
:
[],
uploadUrl
:
'http://localhost:8567/material/business/youtube/upload
ToCDN
'
,
extraData
:
{
tags
:
"abc, def"
,
director
:
'1'
,
resType
:
'1'
,
directoryId
:
'1'
},
headers
:
{
'Authorization'
:
'Bearer '
+
localStorage
.
getItem
(
'token'
)
}
},
selectedDirectoryIds
:
[],
directories
:
[],
uploadForm
:
{
// 上传视频表单数据
// file: null,
successFiles
:
[],
tags
:
[],
designer
:
null
,
directoryId
:
null
},
}
},
created
()
{
this
.
fetchDirectories
();
},
methods
:
{
// 处理文件列表更新
handleFilesUpdate
(
files
)
{
this
.
successFiles
=
files
this
.
uploadForm
.
successFiles
=
files
console
.
log
(
"parent receive upload success"
,
files
)
},
...
...
@@ -139,6 +184,32 @@ export default {
}
},
handleChange
(
value
)
{
console
.
log
(
'选中的标签ID:'
,
value
)
},
fetchDirectories
()
{
getMaterialDirectoriesTree
().
then
(
res
=>
{
if
(
res
.
status
===
200
)
{
this
.
directories
=
res
.
result
.
data
;
}
else
{
this
.
$message
.
error
(
'获取目录失败'
);
}
});
},
handleDirectoryChange
(
value
)
{
this
.
uploadForm
.
directoryId
=
value
[
value
.
length
-
1
];
},
saveMaterial
(){
addMaterial
(
this
.
uploadForm
).
then
(
res
=>
{
if
(
res
.
status
===
200
)
{
this
.
$message
.
success
(
'保存成功'
);
}
else
{
this
.
$message
.
error
(
'保存失败'
);
}
});
},
}
}
</
script
>
...
...
src/views/materialTag/components/CascaderSelect.vue
deleted
100644 → 0
View file @
011cb0f5
<
template
>
<div
class=
"cascader-select"
>
<!-- 触发器按钮 -->
<el-popover
v-model=
"visible"
placement=
"bottom-start"
trigger=
"click"
:width=
"300"
>
<el-input
v-model=
"searchQuery"
size=
"small"
placeholder=
"搜索标签..."
prefix-icon=
"el-icon-search"
clearable
@
clear=
"handleSearchClear"
class=
"mb-2"
/>
<!-- 面包屑导航 -->
<div
v-if=
"currentPath.length"
class=
"mb-2"
>
<el-breadcrumb
separator=
"/"
>
<el-breadcrumb-item
v-for=
"(item, index) in currentPath"
:key=
"item.id"
:class=
"
{ 'is-link': index !== currentPath.length - 1 }"
@click.native="handlePathClick(index)"
>
{{
item
.
name
}}
</el-breadcrumb-item>
</el-breadcrumb>
</div>
<!-- 树形选择器 -->
<el-tree
ref=
"tree"
:data=
"currentLevelData"
:props=
"defaultProps"
:filter-node-method=
"filterNode"
node-key=
"id"
:expand-on-click-node=
"false"
@
node-click=
"handleNodeClick"
>
<span
slot-scope=
"
{ node, data }" class="custom-tree-node">
<span>
{{
node
.
label
}}
</span>
<span
v-if=
"isLeaf(data)"
>
<el-checkbox
v-model=
"checkedMap[data.id]"
@
change=
"(val) => handleCheck(data, val)"
@
click
.
native
.
stop
/>
</span>
<i
v-else
class=
"el-icon-arrow-right"
/>
</span>
</el-tree>
<el-button
slot=
"reference"
:class=
"
{ 'is-selected': selectedNodes.length }"
>
<span
v-if=
"selectedNodes.length"
>
已选择
{{
selectedNodes
.
length
}}
项
</span>
<span
v-else
>
{{
placeholder
}}
</span>
<i
class=
"el-icon-arrow-down el-icon--right"
/>
</el-button>
</el-popover>
<!-- 已选择标签展示区域 -->
<div
class=
"selected-tags"
>
<el-tag
v-for=
"node in selectedNodes"
:key=
"node.id"
closable
size=
"small"
class=
"tag-item"
@
close=
"handleRemoveTag(node)"
>
{{
getNodePath
(
node
)
}}
</el-tag>
</div>
</div>
</
template
>
<
script
>
export
default
{
name
:
'CascaderSelect'
,
props
:
{
data
:
{
type
:
Array
,
required
:
true
,
default
:
()
=>
[]
},
value
:
{
type
:
Array
,
default
:
()
=>
[]
},
placeholder
:
{
type
:
String
,
default
:
'请选择标签...'
}
},
data
()
{
return
{
visible
:
false
,
searchQuery
:
''
,
currentPath
:
[],
checkedMap
:
{},
defaultProps
:
{
children
:
'children'
,
label
:
'name'
}
}
},
computed
:
{
// 构建树形数据
treeData
()
{
return
this
.
buildTree
(
this
.
data
)
},
// 当前层级数据
currentLevelData
()
{
if
(
this
.
searchQuery
)
{
return
this
.
filterTreeData
(
this
.
treeData
,
this
.
searchQuery
)
}
if
(
this
.
currentPath
.
length
===
0
)
{
return
this
.
treeData
}
const
current
=
this
.
currentPath
[
this
.
currentPath
.
length
-
1
]
return
current
.
children
||
[]
},
// 选中的节点
selectedNodes
()
{
return
this
.
value
.
map
(
id
=>
this
.
findNodeById
(
this
.
treeData
,
id
)).
filter
(
Boolean
)
}
},
watch
:
{
value
:
{
immediate
:
true
,
handler
(
val
)
{
// 更新选中状态
const
checkedMap
=
{}
val
.
forEach
(
id
=>
{
checkedMap
[
id
]
=
true
})
this
.
checkedMap
=
checkedMap
}
},
searchQuery
(
val
)
{
this
.
$refs
.
tree
&&
this
.
$refs
.
tree
.
filter
(
val
)
}
},
methods
:
{
// 构建树形数据
buildTree
(
items
)
{
const
itemMap
=
new
Map
()
const
result
=
[]
// 创建所有节点
items
.
forEach
(
item
=>
{
itemMap
.
set
(
item
.
id
,
{
...
item
,
children
:
[]
})
})
// 建立父子关系
items
.
forEach
(
item
=>
{
const
node
=
itemMap
.
get
(
item
.
id
)
if
(
item
.
parentId
===
null
)
{
result
.
push
(
node
)
}
else
{
const
parent
=
itemMap
.
get
(
item
.
parentId
)
if
(
parent
)
{
parent
.
children
.
push
(
node
)
}
}
})
return
result
},
// 判断是否为叶子节点
isLeaf
(
node
)
{
return
!
node
.
children
||
node
.
children
.
length
===
0
},
// 处理节点点击
handleNodeClick
(
data
)
{
if
(
!
this
.
isLeaf
(
data
))
{
this
.
currentPath
.
push
(
data
)
}
},
// 处理路径点击
handlePathClick
(
index
)
{
this
.
currentPath
=
this
.
currentPath
.
slice
(
0
,
index
+
1
)
},
// 处理复选框变化
handleCheck
(
node
,
checked
)
{
const
newValue
=
[...
this
.
value
]
if
(
checked
)
{
if
(
!
newValue
.
includes
(
node
.
id
))
{
newValue
.
push
(
node
.
id
)
}
}
else
{
const
index
=
newValue
.
indexOf
(
node
.
id
)
if
(
index
>
-
1
)
{
newValue
.
splice
(
index
,
1
)
}
}
this
.
$emit
(
'input'
,
newValue
)
this
.
$emit
(
'change'
,
newValue
)
},
// 处理标签移除
handleRemoveTag
(
node
)
{
const
newValue
=
this
.
value
.
filter
(
id
=>
id
!==
node
.
id
)
this
.
$emit
(
'input'
,
newValue
)
this
.
$emit
(
'change'
,
newValue
)
},
// 获取节点完整路径
getNodePath
(
node
)
{
const
path
=
this
.
findNodePath
(
this
.
treeData
,
node
.
id
)
return
path
?
path
.
map
(
n
=>
n
.
name
).
join
(
' / '
)
:
''
},
// 查找节点路径
findNodePath
(
nodes
,
targetId
,
path
=
[])
{
for
(
const
node
of
nodes
)
{
const
newPath
=
[...
path
,
node
]
if
(
node
.
id
===
targetId
)
{
return
newPath
}
if
(
node
.
children
)
{
const
found
=
this
.
findNodePath
(
node
.
children
,
targetId
,
newPath
)
if
(
found
)
{
return
found
}
}
}
return
null
},
// 根据ID查找节点
findNodeById
(
nodes
,
targetId
)
{
for
(
const
node
of
nodes
)
{
if
(
node
.
id
===
targetId
)
{
return
node
}
if
(
node
.
children
)
{
const
found
=
this
.
findNodeById
(
node
.
children
,
targetId
)
if
(
found
)
{
return
found
}
}
}
return
null
},
// 搜索过滤
filterNode
(
value
,
data
)
{
if
(
!
value
)
return
true
return
data
.
name
.
indexOf
(
value
)
!==
-
1
},
// 过滤树数据
filterTreeData
(
nodes
,
query
)
{
return
nodes
.
filter
(
node
=>
{
if
(
node
.
name
.
indexOf
(
query
)
!==
-
1
)
{
return
true
}
if
(
node
.
children
)
{
const
filteredChildren
=
this
.
filterTreeData
(
node
.
children
,
query
)
if
(
filteredChildren
.
length
)
{
node
.
children
=
filteredChildren
return
true
}
}
return
false
})
},
// 处理搜索清除
handleSearchClear
()
{
this
.
searchQuery
=
''
this
.
currentPath
=
[]
}
}
}
</
script
>
<
style
scoped
>
.cascader-select
{
display
:
flex
;
flex-direction
:
column
;
gap
:
8px
;
}
.custom-tree-node
{
display
:
flex
;
align-items
:
center
;
justify-content
:
space-between
;
width
:
100%
;
}
.selected-tags
{
display
:
flex
;
flex-wrap
:
wrap
;
gap
:
8px
;
}
.tag-item
{
max-width
:
100%
;
overflow
:
hidden
;
text-overflow
:
ellipsis
;
white-space
:
nowrap
;
}
.mb-2
{
margin-bottom
:
8px
;
}
.el-button.is-selected
{
color
:
#409EFF
;
border-color
:
#409EFF
;
}
.el-breadcrumb__item.is-link
{
cursor
:
pointer
;
color
:
#409EFF
;
}
.el-tree
{
max-height
:
300px
;
overflow-y
:
auto
;
}
</
style
>
\ No newline at end of file
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