Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
S
saas-dml
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
EzijingWeb
saas-dml
Commits
f96316c7
提交
f96316c7
authored
3月 07, 2025
作者:
王鹏飞
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat: 增加AI分析与总结
上级
78ec16fa
隐藏空白字符变更
内嵌
并排
正在显示
9 个修改的文件
包含
262 行增加
和
67 行删除
+262
-67
api.ts
src/modules/analyze/user/api.ts
+5
-0
AISummaryDialog.vue
src/modules/analyze/user/components/AISummaryDialog.vue
+28
-0
Index.vue
src/modules/analyze/user/views/Index.vue
+52
-30
api.ts
src/modules/label/api.ts
+5
-0
AISummaryDialog.vue
src/modules/label/components/AISummaryDialog.vue
+28
-0
Index.vue
src/modules/label/views/Index.vue
+43
-19
api.ts
src/modules/user/api.ts
+5
-0
AISummaryDialog.vue
src/modules/user/components/AISummaryDialog.vue
+30
-0
Image.vue
src/modules/user/views/Image.vue
+66
-18
没有找到文件。
src/modules/analyze/user/api.ts
浏览文件 @
f96316c7
...
...
@@ -34,3 +34,8 @@ export function getMemberMetaAttrs() {
export
function
getUserTags
(
params
:
{
sso_id
:
string
;
limit
:
number
})
{
return
httpRequest
.
get
(
'/api/lab/v1/experiment/analyse/user-tags'
,
{
params
})
}
// AI分析与总结
export
function
getAISummary
()
{
return
httpRequest
.
get
(
'/api/lab/v1/experiment/member/ai-all-person'
)
}
src/modules/analyze/user/components/AISummaryDialog.vue
0 → 100644
浏览文件 @
f96316c7
<
script
setup
>
import
{
getAISummary
}
from
'../api'
const
content
=
ref
(
''
)
const
isLoading
=
ref
(
false
)
async
function
fetchAI
()
{
isLoading
.
value
=
true
const
res
=
await
getAISummary
()
content
.
value
=
res
.
data
.
result
isLoading
.
value
=
false
}
onMounted
(()
=>
{
fetchAI
()
})
</
script
>
<
template
>
<el-dialog
title=
"AI用户整体画像分析与建议"
>
<div
v-loading=
"isLoading"
>
<el-input
type=
"textarea"
:rows=
"15"
:value=
"content"
></el-input>
</div>
<template
#
footer
>
<el-row
justify=
"center"
>
<el-button
round
@
click=
"$emit('update:modelValue', false)"
>
关闭
</el-button>
</el-row>
</
template
>
</el-dialog>
</template>
src/modules/analyze/user/views/Index.vue
浏览文件 @
f96316c7
...
...
@@ -8,6 +8,9 @@ import { useMapStore } from '@/stores/map'
import
{
getNameByValue
}
from
'@/utils/dictionary'
import
*
as
api
from
'../api'
const
AISummaryDialog
=
defineAsyncComponent
(()
=>
import
(
'../components/AISummaryDialog.vue'
))
const
aiDialogVisible
=
ref
(
false
)
const
connectionTypeList
=
useMapStore
().
getMapValuesByKey
(
'experiment_connection_type'
)
const
statusList
=
useMapStore
().
getMapValuesByKey
(
'system_status'
)
...
...
@@ -57,7 +60,7 @@ const genderOption = computed(() => {
return
{
grid
:
{
left
:
'60'
,
right
:
'60'
},
tooltip
:
{
trigger
:
'item'
trigger
:
'item'
,
},
yAxis
:
{
data
:
[
'男性'
,
'女性'
],
...
...
@@ -67,15 +70,20 @@ const genderOption = computed(() => {
axisLabel
:
{
formatter
:
function
(
value
,
index
)
{
const
total
=
parseInt
(
man
.
total
)
+
parseInt
(
woman
.
total
)
return
value
+
'
\
n'
+
(
index
===
0
?
((
man
.
total
/
total
)
*
100
).
toFixed
(
1
)
:
((
woman
.
total
/
total
)
*
100
).
toFixed
(
1
))
+
'%'
}
}
return
(
value
+
'
\
n'
+
(
index
===
0
?
((
man
.
total
/
total
)
*
100
).
toFixed
(
1
)
:
((
woman
.
total
/
total
)
*
100
).
toFixed
(
1
))
+
'%'
)
},
},
},
xAxis
:
{
splitLine
:
{
show
:
false
},
axisLabel
:
{
show
:
false
},
axisTick
:
{
show
:
false
},
axisLine
:
{
show
:
false
}
axisLine
:
{
show
:
false
}
,
},
series
:
[
{
...
...
@@ -86,10 +94,10 @@ const genderOption = computed(() => {
symbolMargin
:
10
,
data
:
[
{
value
:
man
.
total
,
symbol
:
manIcon
,
itemStyle
:
{
color
:
'#767aca'
}
},
{
value
:
woman
.
total
,
symbol
:
womanIcon
,
itemStyle
:
{
color
:
'#d26080'
}
}
]
}
]
{
value
:
woman
.
total
,
symbol
:
womanIcon
,
itemStyle
:
{
color
:
'#d26080'
}
}
,
]
,
}
,
]
,
}
})
...
...
@@ -101,7 +109,7 @@ async function fetchConnections() {
loading2
.
value
=
true
try
{
const
res
=
await
api
.
getMemberConnections
({
sso_id
:
userValue
.
value
})
connection
.
value
=
res
.
data
.
items
.
map
(
item
=>
{
connection
.
value
=
res
.
data
.
items
.
map
(
(
item
)
=>
{
return
{
...
item
,
group_name
:
getNameByValue
(
item
.
group_name
,
connectionTypeList
)
}
})
}
finally
{
...
...
@@ -113,24 +121,24 @@ const connectionOption = computed(() => {
return
{
grid
:
{
left
:
'5%'
,
top
:
'10%'
,
right
:
'5%'
,
bottom
:
'5%'
,
containLabel
:
true
},
tooltip
:
{
trigger
:
'axis'
trigger
:
'axis'
,
},
xAxis
:
{
type
:
'category'
,
axisLabel
:
{
interval
:
0
},
data
:
connection
.
value
.
map
(
item
=>
item
.
group_name
)
data
:
connection
.
value
.
map
(
(
item
)
=>
item
.
group_name
),
},
yAxis
:
{
type
:
'value'
type
:
'value'
,
},
series
:
[
{
name
:
'数据'
,
type
:
'bar'
,
label
:
{
show
:
true
,
position
:
'top'
},
data
:
connection
.
value
.
map
(
item
=>
item
.
total
)
}
]
data
:
connection
.
value
.
map
(
(
item
)
=>
item
.
total
),
}
,
]
,
}
})
...
...
@@ -142,7 +150,7 @@ async function fetchStatus() {
loading3
.
value
=
true
try
{
const
res
=
await
api
.
getMemberStatus
({
sso_id
:
userValue
.
value
})
status
.
value
=
res
.
data
.
items
.
map
(
item
=>
{
status
.
value
=
res
.
data
.
items
.
map
(
(
item
)
=>
{
return
{
name
:
getNameByValue
(
item
.
group_name
,
statusList
),
value
:
item
.
total
}
})
}
finally
{
...
...
@@ -155,7 +163,7 @@ const statusOption = computed(() => {
grid
:
{
left
:
'5%'
,
top
:
'10%'
,
right
:
'5%'
,
bottom
:
'5%'
,
containLabel
:
true
},
tooltip
:
{
trigger
:
'item'
,
formatter
:
'{b}: {c}<br />{d}%'
formatter
:
'{b}: {c}<br />{d}%'
,
},
series
:
[
{
...
...
@@ -163,9 +171,9 @@ const statusOption = computed(() => {
label
:
{
formatter
:
'{b}
\
n{d}%'
},
itemStyle
:
{
borderRadius
:
6
},
radius
:
[
0
,
'70%'
],
data
:
status
.
value
}
]
data
:
status
.
value
,
}
,
]
,
}
})
</
script
>
...
...
@@ -173,15 +181,28 @@ const statusOption = computed(() => {
<
template
>
<AppCard
title=
"用户分析"
>
<el-form
inline
label-suffix=
":"
>
<el-form-item
label=
"实验名称"
>
{{
info
?.
name
}}
</el-form-item>
<el-form-item
label=
"请选择学生/老师"
>
<el-select
v-model=
"userValue"
filterable
>
<el-option
v-for=
"item in userList"
:label=
"item.name"
:value=
"item.sso_id"
:key=
"item.sso_id"
></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button
type=
"primary"
:icon=
"DataLine"
:loading=
"loading"
@
click=
"handleStart"
>
分析
</el-button>
</el-form-item>
<div
style=
"display: flex; justify-content: space-between"
>
<div>
<el-form-item
label=
"实验名称"
>
{{
info
?.
name
}}
</el-form-item>
<el-form-item
label=
"请选择学生/老师"
>
<el-select
v-model=
"userValue"
filterable
>
<el-option
v-for=
"item in userList"
:label=
"item.name"
:value=
"item.sso_id"
:key=
"item.sso_id"
></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button
type=
"primary"
:icon=
"DataLine"
:loading=
"loading"
@
click=
"handleStart"
>
分析
</el-button>
</el-form-item>
</div>
<div>
<el-form-item>
<el-button
type=
"primary"
@
click=
"aiDialogVisible = true"
>
AI分析与总结
</el-button>
</el-form-item>
</div>
</div>
<el-divider
style=
"margin: 10px 0"
/>
<el-form-item
label=
"用户总数"
>
<b
class=
"total"
>
{{
userTotal
}}
</b>
...
...
@@ -199,6 +220,7 @@ const statusOption = computed(() => {
<UserChart
:ssoId=
"userValue"
/>
</div>
</AppCard>
<AISummaryDialog
v-model=
"aiDialogVisible"
v-if=
"aiDialogVisible"
></AISummaryDialog>
</
template
>
<
style
lang=
"scss"
scoped
>
...
...
src/modules/label/api.ts
浏览文件 @
f96316c7
...
...
@@ -70,3 +70,8 @@ export function updateLabelRule(data: { id: string; rules: string }) {
export
function
getLabelMembers
(
params
:
{
tag_id
:
string
})
{
return
httpRequest
.
get
(
'/api/lab/v1/experiment/tag/bda-statistics-users'
,
{
params
})
}
// AI分析与总结
export
function
getAISummary
()
{
return
httpRequest
.
get
(
'/api/lab/v1/experiment/member/ai-tag'
)
}
src/modules/label/components/AISummaryDialog.vue
0 → 100644
浏览文件 @
f96316c7
<
script
setup
>
import
{
getAISummary
}
from
'../api'
const
content
=
ref
(
''
)
const
isLoading
=
ref
(
false
)
async
function
fetchAI
()
{
isLoading
.
value
=
true
const
res
=
await
getAISummary
()
content
.
value
=
res
.
data
.
result
isLoading
.
value
=
false
}
onMounted
(()
=>
{
fetchAI
()
})
</
script
>
<
template
>
<el-dialog
title=
"AI用户整体画像分析与建议"
>
<div
v-loading=
"isLoading"
>
<el-input
type=
"textarea"
:rows=
"15"
:value=
"content"
></el-input>
</div>
<template
#
footer
>
<el-row
justify=
"center"
>
<el-button
round
@
click=
"$emit('update:modelValue', false)"
>
关闭
</el-button>
</el-row>
</
template
>
</el-dialog>
</template>
src/modules/label/views/Index.vue
浏览文件 @
f96316c7
...
...
@@ -16,6 +16,8 @@ const userStore = useUserStore()
const
LabelFormDialog
=
defineAsyncComponent
(()
=>
import
(
'../components/LabelFormDialog.vue'
))
const
LabelViewDialog
=
defineAsyncComponent
(()
=>
import
(
'../components/LabelViewDialog.vue'
))
const
LabelRuleDialog
=
defineAsyncComponent
(()
=>
import
(
'../components/LabelRuleDialog.vue'
))
const
AISummaryDialog
=
defineAsyncComponent
(()
=>
import
(
'../components/AISummaryDialog.vue'
))
const
aiDialogVisible
=
ref
(
false
)
const
statusList
=
useMapStore
().
getMapValuesByKey
(
'system_status'
)
const
{
typeList
}
=
useLabelType
()
...
...
@@ -36,7 +38,7 @@ const listOptions = computed(() => {
params
.
updated_operator
=
listParams
.
updated_operator
}
return
params
}
}
,
},
filters
:
[
{
type
:
'input'
,
prop
:
'name'
,
placeholder
:
'请输入标签名称'
},
...
...
@@ -46,16 +48,16 @@ const listOptions = computed(() => {
placeholder
:
'请选择标签目录'
,
options
:
typeList
.
value
,
labelKey
:
'name'
,
valueKey
:
'id'
valueKey
:
'id'
,
},
{
type
:
'select'
,
prop
:
'label'
,
placeholder
:
'请选择标签类型'
,
options
:
labelList
options
:
labelList
,
},
{
type
:
'select'
,
prop
:
'status'
,
placeholder
:
'请选择标签状态'
,
options
:
statusList
},
{
type
:
'input'
,
prop
:
'updated_operator'
,
placeholder
:
'更新人'
,
slots
:
'filter-user'
}
{
type
:
'input'
,
prop
:
'updated_operator'
,
placeholder
:
'更新人'
,
slots
:
'filter-user'
}
,
],
columns
:
[
{
type
:
'selection'
},
...
...
@@ -67,7 +69,7 @@ const listOptions = computed(() => {
prop
:
'label'
,
computed
({
row
}:
{
row
:
Label
})
{
return
getNameByValue
(
row
.
label
,
labelList
)
||
row
.
label
}
}
,
},
{
label
:
'标签目录'
,
prop
:
'tag_type.name'
},
{
label
:
'标签权重'
,
prop
:
'weight'
},
...
...
@@ -76,7 +78,7 @@ const listOptions = computed(() => {
prop
:
'update_status'
,
computed
({
row
}:
{
row
:
Label
})
{
return
getNameByValue
(
row
.
update_status
,
updateStatusRuleList
)
}
}
,
},
{
label
:
'状态'
,
...
...
@@ -84,18 +86,18 @@ const listOptions = computed(() => {
computed
({
row
}:
{
row
:
Label
})
{
const
color
=
row
.
status
===
'1'
?
'var(--main-success-color)'
:
'var(--main-color)'
return
`<span style="color:
${
color
}
">
${
getNameByValue
(
row
.
status
,
statusList
)}
</span>`
}
}
,
},
{
label
:
'更新人'
,
prop
:
'updated_operator.real_name'
,
computed
({
row
}:
any
)
{
return
row
.
updated_operator
?.
real_name
||
row
.
updated_operator
?.
nickname
}
}
,
},
{
label
:
'更新时间'
,
prop
:
'updated_time'
},
{
label
:
'操作'
,
slots
:
'table-x'
,
width
:
320
}
]
{
label
:
'操作'
,
slots
:
'table-x'
,
width
:
320
}
,
]
,
}
})
// 刷新
...
...
@@ -151,11 +153,11 @@ function handleSelectionChange(selection: Label[]) {
}
const
handleRemoves
=
async
function
()
{
const
ids
=
multipleSelection
.
map
(
item
=>
item
.
id
)
const
ids
=
multipleSelection
.
map
(
(
item
)
=>
item
.
id
)
await
ElMessageBox
.
confirm
(
'确定要删除选中的标签数据吗?'
,
'提示'
,
{
confirmButtonText
:
'确认'
,
cancelButtonText
:
'取消'
,
type
:
'warning'
type
:
'warning'
,
})
await
deleteLabels
({
ids
:
JSON
.
stringify
(
ids
)
})
appList
?.
refetch
(
true
)
...
...
@@ -169,10 +171,23 @@ const handleRemoves = async function () {
<div
class=
"label-left"
><LabelType
:active-id=
"listParams.type_id"
@
select=
"handleSelect"
></LabelType></div>
<AppList
v-bind=
"listOptions"
ref=
"appList"
class=
"label-right"
@
selection-change=
"handleSelectionChange"
>
<template
#
header-buttons
>
<el-button
type=
"primary"
:icon=
"Plus"
@
click=
"handleAdd"
v-if=
"!userStore.status.tag_status"
>
新建
</el-button>
<el-button
type=
"primary"
plain
:icon=
"Delete"
:disabled=
"!multipleSelection.length"
@
click=
"handleRemoves"
v-permission=
"'experiment_tag_delete'"
>
删除
</el-button
>
<div
style=
"display: flex; justify-content: space-between"
>
<div>
<el-button
type=
"primary"
:icon=
"Plus"
@
click=
"handleAdd"
v-if=
"!userStore.status.tag_status"
>
新建
</el-button
>
<el-button
type=
"primary"
plain
:icon=
"Delete"
:disabled=
"!multipleSelection.length"
@
click=
"handleRemoves"
v-permission=
"'experiment_tag_delete'"
>
删除
</el-button
>
</div>
<el-button
type=
"primary"
@
click=
"aiDialogVisible = true"
>
AI建议
</el-button>
</div>
</
template
>
<
template
#
filter-user
>
<SelectUser
v-model=
"listParams.updated_operator"
placeholder=
"更新人"
@
change=
"handleRefresh"
></SelectUser>
...
...
@@ -181,18 +196,27 @@ const handleRemoves = async function () {
<
template
#
table-x=
"{ row }"
>
<el-button
type=
"primary"
plain
@
click=
"handleRule(row)"
>
规则
</el-button>
<el-button
type=
"primary"
plain
@
click=
"handleView(row)"
>
查看
</el-button>
<el-button
type=
"primary"
plain
@
click=
"handleUpdate(row)"
v-permission=
"'experiment_tag_update'"
>
编辑
</el-button>
<el-button
type=
"primary"
plain
@
click=
"handleRemove(row)"
v-permission=
"'experiment_tag_delete'"
>
删除
</el-button>
<el-button
type=
"primary"
plain
@
click=
"handleUpdate(row)"
v-permission=
"'experiment_tag_update'"
>
编辑
</el-button
>
<el-button
type=
"primary"
plain
@
click=
"handleRemove(row)"
v-permission=
"'experiment_tag_delete'"
>
删除
</el-button
>
</
template
>
</AppList>
</div>
</AppCard>
<!-- 新建/修改标签 -->
<LabelFormDialog
v-model=
"formVisible"
:data=
"currentRow"
@
update=
"handleRefresh"
v-if=
"formVisible"
></LabelFormDialog>
<LabelFormDialog
v-model=
"formVisible"
:data=
"currentRow"
@
update=
"handleRefresh"
v-if=
"formVisible"
></LabelFormDialog>
<!-- 查看标签 -->
<LabelViewDialog
v-model=
"viewVisible"
:data=
"currentRow"
v-if=
"viewVisible && currentRow"
></LabelViewDialog>
<!-- 规则 -->
<LabelRuleDialog
v-model=
"ruleVisible"
:data=
"currentRow"
v-if=
"ruleVisible && currentRow"
></LabelRuleDialog>
<AISummaryDialog
v-model=
"aiDialogVisible"
v-if=
"aiDialogVisible"
></AISummaryDialog>
</template>
<
style
lang=
"scss"
>
...
...
src/modules/user/api.ts
浏览文件 @
f96316c7
...
...
@@ -125,3 +125,8 @@ export function syncMember() {
export
function
clearMember
()
{
return
httpRequest
.
get
(
'/api/lab/v1/experiment/member/clear'
)
}
// AI分析与总结
export
function
getAISummary
(
params
:
{
member_id
:
string
})
{
return
httpRequest
.
get
(
'/api/lab/v1/experiment/member/ai-one-person'
,
{
params
})
}
src/modules/user/components/AISummaryDialog.vue
0 → 100644
浏览文件 @
f96316c7
<
script
setup
>
import
{
getAISummary
}
from
'../api'
const
props
=
defineProps
([
'id'
])
const
content
=
ref
(
''
)
const
isLoading
=
ref
(
false
)
async
function
fetchAI
()
{
isLoading
.
value
=
true
const
res
=
await
getAISummary
({
member_id
:
props
.
id
})
content
.
value
=
res
.
data
.
result
isLoading
.
value
=
false
}
onMounted
(()
=>
{
fetchAI
()
})
</
script
>
<
template
>
<el-dialog
title=
"AI用户画像分析与建议"
>
<div
v-loading=
"isLoading"
>
<el-input
type=
"textarea"
:rows=
"15"
:value=
"content"
></el-input>
</div>
<template
#
footer
>
<el-row
justify=
"center"
>
<el-button
round
@
click=
"$emit('update:modelValue', false)"
>
关闭
</el-button>
</el-row>
</
template
>
</el-dialog>
</template>
src/modules/user/views/Image.vue
浏览文件 @
f96316c7
...
...
@@ -7,6 +7,8 @@ import Icon from '@/components/ConnectionIcon.vue'
const
ViewEvent
=
defineAsyncComponent
(()
=>
import
(
'@/components/ViewEvent.vue'
))
const
ViewLabel
=
defineAsyncComponent
(()
=>
import
(
'@/components/ViewLabel.vue'
))
const
ViewGroup
=
defineAsyncComponent
(()
=>
import
(
'@/components/ViewGroup.vue'
))
const
AISummaryDialog
=
defineAsyncComponent
(()
=>
import
(
'../components/AISummaryDialog.vue'
))
const
aiDialogVisible
=
ref
(
false
)
const
route
=
useRoute
()
...
...
@@ -20,7 +22,7 @@ let data = $ref<ImageProp>()
let
fieldsList
=
$ref
<
MemberFieldsProp
[]
>
([])
onMounted
(()
=>
{
// 画像
getMemberImage
({
id
:
userId
.
value
,
'per-page'
:
100
}).
then
(
res
=>
{
getMemberImage
({
id
:
userId
.
value
,
'per-page'
:
100
}).
then
(
(
res
)
=>
{
data
=
res
.
data
getFields
(
res
.
data
)
})
...
...
@@ -28,7 +30,7 @@ onMounted(() => {
})
const
getFields
=
function
(
data
:
{
fields
:
any
})
{
getMemberFieldsList
().
then
(
res
=>
{
getMemberFieldsList
().
then
(
(
res
)
=>
{
fieldsList
=
res
.
data
.
map
((
item
:
MemberFieldsProp
)
=>
{
if
(
data
.
fields
[
item
.
id
])
{
item
.
value
=
data
.
fields
[
item
.
id
]
...
...
@@ -86,7 +88,12 @@ async function fetchEvent(isReset = false) {
if
(
isReset
)
{
Object
.
assign
(
event
,
{
page
:
1
,
total
:
0
,
list
:
[]
})
}
const
{
data
}
=
await
getMemberImage
({
id
:
userId
.
value
,
connection_id
:
currentConnection
.
value
,
page
:
event
.
page
,
'per-page'
:
20
})
const
{
data
}
=
await
getMemberImage
({
id
:
userId
.
value
,
connection_id
:
currentConnection
.
value
,
page
:
event
.
page
,
'per-page'
:
20
,
})
Object
.
assign
(
event
,
{
page
:
event
.
page
+
1
,
total
:
data
.
events
.
total
,
list
:
[...
event
.
list
,
...
data
.
events
.
list
]
})
}
watch
(
currentConnection
,
()
=>
{
...
...
@@ -100,7 +107,11 @@ watch(currentConnection, () => {
<div
class=
"info-name"
style=
"min-width: 300px"
>
<div
class=
"tx"
>
<img
:src=
"data.gender === '1' ? 'https://webapp-pub.ezijing.com/pages/assa/dml_boy.png' : 'https://webapp-pub.ezijing.com/pages/assa/dml_girl.png'"
/>
:src=
"
data.gender === '1'
? 'https://webapp-pub.ezijing.com/pages/assa/dml_boy.png'
: 'https://webapp-pub.ezijing.com/pages/assa/dml_girl.png'
"
/>
<!-- https://webapp-pub.ezijing.com/pages/assa/dml_boy.png -->
<!--
<el-icon
:size=
"50"
color=
"#fff"
><UserFilled
/></el-icon>
-->
</div>
...
...
@@ -117,12 +128,16 @@ watch(currentConnection, () => {
<el-form
label-suffix=
":"
label-width=
"110px"
>
<el-form-item
label=
"用户ID"
>
{{
data
.
id
}}
</el-form-item>
<el-form-item
label=
"状态"
>
<span
:style=
"`color: $
{data.status === '1' ? 'rgba(0,172,39,1)' : '#ba143e'}`">
{{
data
.
status_name
}}
</span>
<span
:style=
"`color: $
{data.status === '1' ? 'rgba(0,172,39,1)' : '#ba143e'}`">
{{
data
.
status_name
}}
</span>
</el-form-item>
</el-form>
<el-form
label-suffix=
":"
label-width=
"110px"
>
<el-form-item
label=
"最近活跃时间"
>
{{
data
.
updated_time
}}
</el-form-item>
<el-form-item
label=
"最近活跃时间"
style=
"opacity: 0"
>
{{
data
.
updated_time
}}
</el-form-item>
<el-form-item
label-width=
"0"
>
<el-button
type=
"primary"
@
click=
"aiDialogVisible = true"
>
AI分析与总结
</el-button>
</el-form-item>
</el-form>
</div>
</div>
...
...
@@ -148,7 +163,14 @@ watch(currentConnection, () => {
<el-tabs
class=
"demo-tabs"
>
<el-tab-pane
label=
"当前标签"
>
<div
class=
"scroll"
v-if=
"data?.tags && data.tags.length"
>
<el-tag
class=
"ml-2"
type=
"success"
v-for=
"(item, index) in data.tag_list"
:key=
"index"
@
click=
"handleViewLabel(item)"
>
{{ item.name }}
</el-tag>
<el-tag
class=
"ml-2"
type=
"success"
v-for=
"(item, index) in data.tag_list"
:key=
"index"
@
click=
"handleViewLabel(item)"
>
{{ item.name }}
</el-tag
>
</div>
<el-empty
description=
"暂无数据"
:image-size=
"80"
v-else
/>
</el-tab-pane>
...
...
@@ -156,7 +178,9 @@ watch(currentConnection, () => {
<el-tabs
class=
"demo-tabs"
>
<el-tab-pane
label=
"历史标签"
>
<div
class=
"scroll"
v-if=
"data?.history_tags && data.history_tags.length"
>
<el-tag
class=
"ml-2"
type=
"success"
v-for=
"(item, index) in data.history_tags"
:key=
"index"
>
{{ item }}
</el-tag>
<el-tag
class=
"ml-2"
type=
"success"
v-for=
"(item, index) in data.history_tags"
:key=
"index"
>
{{
item
}}
</el-tag>
</div>
<el-empty
description=
"暂无数据"
:image-size=
"80"
v-else
/>
</el-tab-pane>
...
...
@@ -166,9 +190,14 @@ watch(currentConnection, () => {
<el-tabs
class=
"demo-tabs"
>
<el-tab-pane
label=
"静态群组"
>
<div
class=
"scroll"
v-if=
"data?.static_groups && data.static_groups.length"
>
<el-tag
class=
"ml-2"
type=
"success"
v-for=
"(item, index) in data.static_group_list"
:key=
"index"
@
click=
"handleViewGroup(item)"
>
{{
item.name
}}
</el-tag>
<el-tag
class=
"ml-2"
type=
"success"
v-for=
"(item, index) in data.static_group_list"
:key=
"index"
@
click=
"handleViewGroup(item)"
>
{{ item.name }}
</el-tag
>
</div>
<el-empty
description=
"暂无数据"
:image-size=
"80"
v-else
/>
</el-tab-pane>
...
...
@@ -176,9 +205,14 @@ watch(currentConnection, () => {
<el-tabs
class=
"demo-tabs"
>
<el-tab-pane
label=
"动态群组"
>
<div
class=
"scroll"
v-if=
"data?.dynamic_groups && data.dynamic_groups.length"
>
<el-tag
class=
"ml-2"
type=
"success"
v-for=
"(item, index) in data.dynamic_group_list"
:key=
"index"
@
click=
"handleViewGroup(item)"
>
{{
item.name
}}
</el-tag>
<el-tag
class=
"ml-2"
type=
"success"
v-for=
"(item, index) in data.dynamic_group_list"
:key=
"index"
@
click=
"handleViewGroup(item)"
>
{{ item.name }}
</el-tag
>
</div>
<el-empty
description=
"暂无数据"
:image-size=
"80"
v-else
/>
</el-tab-pane>
...
...
@@ -187,7 +221,9 @@ watch(currentConnection, () => {
<AppCard
class=
"card"
title=
"用户行为轨迹"
>
<div
style=
"text-align: center"
>
<el-radio-group
v-model=
"currentConnection"
>
<el-radio-button
:value=
"item.id"
v-for=
"item in connectionList"
:key=
"item.id"
>
{{ item.type_name }}
</el-radio-button>
<el-radio-button
:value=
"item.id"
v-for=
"item in connectionList"
:key=
"item.id"
>
{{
item.type_name
}}
</el-radio-button>
</el-radio-group>
</div>
<
template
v-if=
"event.list.length"
>
...
...
@@ -214,11 +250,23 @@ watch(currentConnection, () => {
</AppCard>
</div>
<!-- 事件详情 -->
<ViewEvent
v-model=
"viewEventVisible"
:event=
"currentViewEvent"
:user=
"data"
v-if=
"viewEventVisible && currentViewEvent"
></ViewEvent>
<ViewEvent
v-model=
"viewEventVisible"
:event=
"currentViewEvent"
:user=
"data"
v-if=
"viewEventVisible && currentViewEvent"
></ViewEvent>
<!-- 查看标签 -->
<ViewLabel
v-model=
"viewLabelVisible"
:data=
"currentViewLabel"
v-if=
"viewLabelVisible && currentViewLabel"
></ViewLabel>
<ViewLabel
v-model=
"viewLabelVisible"
:data=
"currentViewLabel"
v-if=
"viewLabelVisible && currentViewLabel"
></ViewLabel>
<!-- 查看群组 -->
<ViewGroup
v-model=
"viewGroupVisible"
:data=
"currentViewGroup"
v-if=
"viewGroupVisible && currentViewGroup"
></ViewGroup>
<ViewGroup
v-model=
"viewGroupVisible"
:data=
"currentViewGroup"
v-if=
"viewGroupVisible && currentViewGroup"
></ViewGroup>
<AISummaryDialog
v-model=
"aiDialogVisible"
:id=
"userId"
v-if=
"aiDialogVisible"
></AISummaryDialog>
</template>
<
style
lang=
"scss"
>
.info-box
{
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论