Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
S
saas-dml
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
EzijingWeb
saas-dml
Commits
90d00e72
提交
90d00e72
authored
2月 15, 2023
作者:
lihuihui
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
update
上级
fa868381
隐藏空白字符变更
内嵌
并排
正在显示
14 个修改的文件
包含
1079 行增加
和
133 行删除
+1079
-133
.eslintrc-auto-import.json
.eslintrc-auto-import.json
+0
-1
auto-imports.d.ts
auto-imports.d.ts
+0
-1
FieldDialog.vue
src/modules/metadata/event/components/FieldDialog.vue
+1
-1
api.ts
src/modules/user/api.ts
+81
-0
Icon.vue
src/modules/user/components/Icon.vue
+218
-0
UpdateDialog.vue
src/modules/user/components/UpdateDialog.vue
+137
-34
UpdateEventsDialog.vue
src/modules/user/components/UpdateEventsDialog.vue
+111
-24
UploadEventsDialog.vue
src/modules/user/components/UploadEventsDialog.vue
+60
-14
UploadUserDialog.vue
src/modules/user/components/UploadUserDialog.vue
+61
-12
index.ts
src/modules/user/index.ts
+2
-1
types.ts
src/modules/user/types.ts
+64
-0
EventDetails.vue
src/modules/user/views/EventDetails.vue
+68
-17
Image.vue
src/modules/user/views/Image.vue
+145
-0
Index.vue
src/modules/user/views/Index.vue
+131
-28
没有找到文件。
.eslintrc-auto-import.json
浏览文件 @
90d00e72
...
...
@@ -202,7 +202,6 @@
"usePreferredDark"
:
true
,
"usePreferredLanguages"
:
true
,
"usePreferredReducedMotion"
:
true
,
"usePrevious"
:
true
,
"useRafFn"
:
true
,
"useRefHistory"
:
true
,
"useResizeObserver"
:
true
,
...
...
auto-imports.d.ts
浏览文件 @
90d00e72
...
...
@@ -203,7 +203,6 @@ declare global {
const
usePreferredDark
:
typeof
import
(
'@vueuse/core'
)[
'usePreferredDark'
]
const
usePreferredLanguages
:
typeof
import
(
'@vueuse/core'
)[
'usePreferredLanguages'
]
const
usePreferredReducedMotion
:
typeof
import
(
'@vueuse/core'
)[
'usePreferredReducedMotion'
]
const
usePrevious
:
typeof
import
(
'@vueuse/core'
)[
'usePrevious'
]
const
useRafFn
:
typeof
import
(
'@vueuse/core'
)[
'useRafFn'
]
const
useRefHistory
:
typeof
import
(
'@vueuse/core'
)[
'useRefHistory'
]
const
useResizeObserver
:
typeof
import
(
'@vueuse/core'
)[
'useResizeObserver'
]
...
...
src/modules/metadata/event/components/FieldDialog.vue
浏览文件 @
90d00e72
...
...
@@ -123,7 +123,7 @@ function handleUpdate() {
v-model=
"scope.row.format"
placeholder=
"请选择"
>
<el-option
label=
"yyyy-mm-dd"
value=
"yyyy-mm-dd"
></el-option>
<el-option
v-if=
"scope.row.type !== '5'"
label=
"yyyy-mm-dd"
value=
"yyyy-mm-dd"
></el-option>
<el-option
v-if=
"scope.row.type !== '4'"
label=
"yyyy-mm-dd hh:mm:ss"
...
...
src/modules/user/api.ts
0 → 100644
浏览文件 @
90d00e72
import
httpRequest
from
'@/utils/axios'
// 人员列表
export
function
getMemberList
(
params
:
{
name
?:
string
;
id
?:
string
;
mobile
?:
string
;
status
?:
string
;
page
?:
number
;
page_size
?:
number
})
{
return
httpRequest
.
get
(
'/api/experiment/v1/experiment/member/list'
,
{
params
})
}
// 链接列表
export
function
getMemberConnectionsList
()
{
return
httpRequest
.
get
(
'/api/experiment/v1/experiment/member/connections'
)
}
// 用户属性
export
function
getMemberFieldsList
()
{
return
httpRequest
.
get
(
'/api/experiment/v1/experiment/member/member-fields'
)
}
// 新建用户
export
function
createMember
(
data
:
{
name
:
string
;
status
:
string
;
experiment_connection_id
:
string
;
gender
:
string
;
mobile
:
string
;
fields
:
string
})
{
return
httpRequest
.
post
(
'/api/experiment/v1/experiment/member/create'
,
data
)
}
// 删除用户
export
function
deleteMember
(
data
:
{
ids
:
string
;
})
{
return
httpRequest
.
post
(
'/api/experiment/v1/experiment/member/delete'
,
data
)
}
// 新建用户
export
function
updateMember
(
data
:
{
id
?:
string
;
name
:
string
;
status
:
string
;
experiment_connection_id
:
string
;
gender
:
string
;
mobile
:
string
;
fields
:
string
})
{
return
httpRequest
.
post
(
'/api/experiment/v1/experiment/member/update'
,
data
)
}
// 单人员事件列表
export
function
getMemberEventList
(
params
:
{
id
:
string
;
page
?:
number
;
page_size
?:
number
})
{
return
httpRequest
.
get
(
'/api/experiment/v1/experiment/member/member-events'
,
{
params
})
}
// 事件列表
export
function
getEventList
()
{
return
httpRequest
.
get
(
'/api/experiment/v1/experiment/member/events'
)
}
// 新建事件
export
function
createEvent
(
data
:
{
experiment_member_id
:
string
;
experiment_meta_event_id
:
string
;
fields
:
any
})
{
return
httpRequest
.
post
(
'/api/experiment/v1/experiment/member/event-create'
,
data
)
}
// 更新事件
export
function
updateEvent
(
data
:
{
id
:
string
;
fields
:
any
})
{
return
httpRequest
.
post
(
'/api/experiment/v1/experiment/member/event-update'
,
data
)
}
// 删除事件
export
function
deleteEvent
(
data
:
{
id
:
string
})
{
return
httpRequest
.
post
(
'/api/experiment/v1/experiment/member/event-delete'
,
data
)
}
// 用户画像
export
function
getMemberImage
(
params
:
{
id
:
string
})
{
return
httpRequest
.
get
(
'/api/experiment/v1/experiment/member/member-image'
,
{
params
})
}
// 导入事件
export
function
importEvent
(
data
:
{
event_id
:
string
;
file
:
any
})
{
return
httpRequest
.
post
(
'/api/experiment/v1/experiment/member/event-upload'
,
data
,
{
headers
:
{
'Content-Type'
:
'multipart/form-data'
}
})
}
// 导入用户
export
function
importMember
(
data
:
{
groups_id
?:
string
;
connection_id
:
string
;
file
:
any
})
{
return
httpRequest
.
post
(
'/api/experiment/v1/experiment/member/member-upload'
,
data
,
{
headers
:
{
'Content-Type'
:
'multipart/form-data'
}
})
}
// 用户画像
export
function
getMemberGroups
()
{
return
httpRequest
.
get
(
'/api/experiment/v1/experiment/member/groups'
)
}
\ No newline at end of file
src/modules/user/components/Icon.vue
0 → 100644
浏览文件 @
90d00e72
<
script
setup
lang=
"ts"
>
withDefaults
(
defineProps
<
{
name
:
string
;
color
?:
string
;
w
?:
string
;
h
?:
string
}
>
(),
{
color
:
'#000000'
,
w
:
'30'
,
h
:
'30'
})
</
script
>
<
template
>
<div>
<svg
v-if=
"name === '1'"
t=
"1675654500635"
class=
"icon"
viewBox=
"0 0 1024 1024"
version=
"1.1"
xmlns=
"http://www.w3.org/2000/svg"
p-id=
"10798"
:width=
"w"
:height=
"h"
>
<path
d=
"M664.250054 368.541681c10.015098 0 19.892049 0.732687 29.67281 1.795902-26.647917-122.810047-159.358451-214.077703-310.826188-214.077703-169.353083 0-308.085774 114.232694-308.085774 259.274068 0 83.708494 46.165436 152.460344 123.281791 205.78483l-30.80868 91.730191 107.688651-53.455469c38.558178 7.53665 69.459978 15.308661 107.924012 15.308661 9.66308 0 19.230993-0.470721 28.752858-1.225921-6.025227-20.36584-9.521864-41.723264-9.521864-63.862493C402.328693 476.632491 517.908058 368.541681 664.250054 368.541681zM498.62897 285.87389c23.200398 0 38.557154 15.120372 38.557154 38.061874 0 22.846334-15.356756 38.156018-38.557154 38.156018-23.107277 0-46.260603-15.309684-46.260603-38.156018C452.368366 300.994262 475.522716 285.87389 498.62897 285.87389zM283.016307 362.090758c-23.107277 0-46.402843-15.309684-46.402843-38.156018 0-22.941502 23.295566-38.061874 46.402843-38.061874 23.081695 0 38.46301 15.120372 38.46301 38.061874C321.479317 346.782098 306.098002 362.090758 283.016307 362.090758zM945.448458 606.151333c0-121.888048-123.258255-221.236753-261.683954-221.236753-146.57838 0-262.015505 99.348706-262.015505 221.236753 0 122.06508 115.437126 221.200938 262.015505 221.200938 30.66644 0 61.617359-7.609305 92.423993-15.262612l84.513836 45.786813-23.178909-76.17082C899.379213 735.776599 945.448458 674.90216 945.448458 606.151333zM598.803483 567.994292c-15.332197 0-30.807656-15.096836-30.807656-30.501688 0-15.190981 15.47546-30.477129 30.807656-30.477129 23.295566 0 38.558178 15.286148 38.558178 30.477129C637.361661 552.897456 622.099049 567.994292 598.803483 567.994292zM768.25071 567.994292c-15.213493 0-30.594809-15.096836-30.594809-30.501688 0-15.190981 15.381315-30.477129 30.594809-30.477129 23.107277 0 38.558178 15.286148 38.558178 30.477129C806.808888 552.897456 791.357987 567.994292 768.25071 567.994292z"
:fill=
"color"
p-id=
"10799"
></path>
</svg>
<svg
v-if=
"name === '2'"
t=
"1675654004777"
class=
"icon"
viewBox=
"0 0 1024 1024"
version=
"1.1"
xmlns=
"http://www.w3.org/2000/svg"
p-id=
"8908"
:width=
"w"
:height=
"h"
>
<path
d=
"M903.282484 382.828702c-2.999866 10.899512-6.899691 21.499038-11.699476 31.698581h0.099995l-0.599973 1.299942c-34.098474 76.596571-123.194485 226.989839-123.194485 226.989839l-0.399982-0.999955-25.998836 47.597869h125.394386L627.294839 1024l54.397565-227.589812h-98.795578l34.298465-150.493263c-27.798756 6.999687-60.497292 16.699252-99.395551 29.798666 0 0-52.49765 32.298554-151.393222-62.197216 0 0-66.697014-61.597243-27.998747-77.096548 16.399266-6.499709 79.796428-14.799337 129.694194-21.999015 67.296987-9.59957 108.79513-14.699342 108.79513-14.699342s-207.690703 3.299852-256.988496-4.899781c-49.297793-8.099637-111.695-94.49577-125.0944-170.392372 0 0-20.599078-41.698133 44.198021-21.999016 64.897095 19.699118 333.385076 76.796562 333.385076 76.796563S223.312923 266.933891 200.113962 239.535117 131.717024 89.741823 137.616759 14.645184c0 0 2.599884-18.799158 20.899065-13.799382 0 0 258.188442 123.994449 434.680541 191.691419C769.688464 260.434182 923.081598 295.032633 903.282484 382.828702z"
:fill=
"color"
p-id=
"8909"
></path>
</svg>
<svg
v-if=
"name === '3'"
t=
"1675654843770"
class=
"icon"
viewBox=
"0 0 1024 1024"
version=
"1.1"
xmlns=
"http://www.w3.org/2000/svg"
p-id=
"14477"
:width=
"w"
:height=
"h"
>
<path
d=
"M927.100379 675.459361c-1.321995-6.607974-9.439963-4.908981-14.915942-4.90898-32.096875 0-64.193749-2.265991-95.913626 0.377998-61.739759 5.09798-108.185577-26.243897-151.799407-62.683755-24.545904-20.39092-45.879821-44.558826-71.369721-64.00575-42.292835-32.474873-85.717665-62.305757-141.793446-64.759747-15.29294-0.566998-33.22987-1.321995-38.516849-21.524916a124.612513 124.612513 0 0 1-4.530983-28.697888c-0.754997-57.586775-4.530982-114.794552-4.153984-172.380326a397.890446 397.890446 0 0 0-20.012921-138.584459 195.037238 195.037238 0 0 0-49.089809-80.809684C298.563834 4.064984 254.571006-2.353991 207.748188 0.666997a41.631837 41.631837 0 0 0-33.04087 20.389921c-13.216948 17.181933 15.669939 47.768813-36.439858 47.390815-5.475979 0-33.796868-1.320995-41.537838 22.089913-5.285979 15.859938 82.697677 10.006961 100.256609 16.237937a11.913953 11.913953 0 0 0 5.09798-0.376999 94.591631 94.591631 0 0 0 67.780735 30.963879 29.132886 29.132886 0 0 1 28.509888 24.166906 411.692392 411.692392 0 0 1 11.705955 71.179722 447.471252 447.471252 0 0 1-10.19496 155.199394 302.524818 302.524818 0 0 1-33.985868 65.326745 268.70895 268.70895 0 0 0-36.439857 164.828356 191.97925 191.97925 0 0 0 47.201815 108.563576c21.901914 24.355905 52.110796 39.837844 72.124719 65.893742 26.621896 34.928864 52.487795 70.801723 81.186682 104.031594a155.879391 155.879391 0 0 1-1.509994 83.263675 29.887883 29.887883 0 0 1-26.244897 23.411908c-16.047937 1.321995-30.019883 11.139956-46.257819 13.216949 23.789907 2.264991 47.579814 1.320995 71.179721 2.45399 21.524916 1.132996 42.859833-11.705954 64.572748-0.943996a5.928977 5.928977 0 0 0 2.264991-0.754997c-4.530982-3.775985-8.306968-7.551971-12.837949-10.761958a54.319788 54.319788 0 0 1-22.656912-60.039766c2.45399-11.139956 3.586986-22.657911 5.09698-33.985867a419.150363 419.150363 0 0 0 142.549443 17.747931 200.135218 200.135218 0 0 1 7.173972 42.292834 31.359878 31.359878 0 0 1-22.655911 34.362866c-14.915942 4.908981-29.831883 10.005961-45.502822 15.103941a16.218937 16.218937 0 0 0 4.90998 2.076992c20.012922-0.188999 40.025844-0.754997 60.039766-0.565998a35.72186 35.72186 0 0 0 31.907875-12.64995c4.719982-6.608974 9.817962-6.419975 14.726943 0.565997a29.415885 29.415885 0 0 0 30.775879 9.629963 35.060863 35.060863 0 0 0-12.461951-16.615935 65.534744 65.534744 0 0 1-19.635923-27.565893c-3.963985-20.201921-8.117968-40.403842-12.271952-60.795762a92.363639 92.363639 0 0 0 56.830778-30.77488 357.070605 357.070605 0 0 0 59.473767-68.725731 127.500502 127.500502 0 0 1 44.369827-41.914837 228.248108 228.248108 0 0 0 68.347733-61.36176 69.593728 69.593728 0 0 1 42.669833-29.831883c4.531982-0.565998 13.782946 0 12.272953-7.92997zM239.090066 43.52483a9.892961 9.892961 0 0 1-9.062965-12.083953 9.779962 9.779962 0 0 1 9.251964-10.383959 10.081961 10.081961 0 0 1 10.38396 11.327955 10.34696 10.34696 0 0 1-10.572959 11.139957z"
:fill=
"color"
p-id=
"14478"
></path>
</svg>
<svg
v-if=
"name === '4'"
t=
"1675654964339"
class=
"icon"
viewBox=
"0 0 1024 1024"
version=
"1.1"
xmlns=
"http://www.w3.org/2000/svg"
p-id=
"16272"
:width=
"w"
:height=
"h"
>
<path
d=
"M559.22 180.986667a21.333333 21.333333 0 0 1-19.14-11.893334L512 112.206667l-28.08 56.886666a21.333333 21.333333 0 0 1-38.26-18.88L492.866667 54.56a21.333333 21.333333 0 0 1 38.266666 0l47.206667 95.653333a21.333333 21.333333 0 0 1-19.12 30.773334zM784.233333 377.333333a21.333333 21.333333 0 0 0-18.04-24.18l-94.46-13.706666-42.246666-85.593334a21.333333 21.333333 0 1 0-38.26 18.88l47.206666 95.653334a21.333333 21.333333 0 0 0 16.06 11.666666l105.56 15.333334a21.3 21.3 0 0 0 24.18-18.053334z m137.333334 118.62l76.386666-74.453333a21.333333 21.333333 0 0 0-11.826666-36.386667l-105.553334-15.333333a21.333333 21.333333 0 1 0-6.14 42.22l62.786667 9.126667-45.433333 44.28a21.333333 21.333333 0 0 0 29.773333 30.593333z m-152.393334 266a21.333333 21.333333 0 0 0 17.42-24.666666l-16.14-94.073334L838.8 576.666667a21.333333 21.333333 0 1 0-29.78-30.553334L732.666667 620.546667a21.333333 21.333333 0 0 0-6.14 18.886666l18 105.126667a21.333333 21.333333 0 0 0 21 17.733333 21.066667 21.066667 0 0 0 3.64-0.293333z m46.5 215.28a21.333333 21.333333 0 0 0 8.486667-20.866666l-18-105.133334a21.333333 21.333333 0 1 0-42.046667 7.213334l10.72 62.526666-56.166666-29.493333a21.333333 21.333333 0 0 0-19.853334 37.766667l94.413334 49.633333a21.333333 21.333333 0 0 0 22.466666-1.62zM625.333333 866.506667a21.333333 21.333333 0 0 0-8.96-28.806667l-94.413333-49.64a21.333333 21.333333 0 0 0-19.853333 0l-94.413334 49.64a21.333333 21.333333 0 1 0 19.853334 37.766667L512 831.046667l84.486667 44.42a21.333333 21.333333 0 0 0 28.846666-8.96z m-394.533333 112.373333l94.413333-49.633333a21.333333 21.333333 0 0 0-19.88-37.766667l-56.153333 29.52 10.72-62.526667a21.333333 21.333333 0 1 0-42.046667-7.213333l-18.033333 105.133333a21.333333 21.333333 0 0 0 30.953333 22.486667z m48.666667-234.32l18.033333-105.126667a21.333333 21.333333 0 0 0-6.166667-18.886666L214.98 546.093333A21.333333 21.333333 0 0 0 185.2 576.666667l68.353333 66.626666L237.413333 737.333333a21.333333 21.333333 0 0 0 17.42 24.666667 21.066667 21.066667 0 0 0 3.633334 0.313333 21.333333 21.333333 0 0 0 21-17.753333zM132.606667 495.586667a21.333333 21.333333 0 0 0-0.386667-30.166667l-45.433333-44.28L149.573333 412a21.333333 21.333333 0 0 0-6.14-42.22l-105.553333 15.333333a21.333333 21.333333 0 0 0-11.826667 36.386667L102.433333 496a21.333333 21.333333 0 0 0 30.173334-0.386667z m131.333333-100.193334l105.56-15.333333a21.333333 21.333333 0 0 0 16.06-11.666667l47.213333-95.66a21.333333 21.333333 0 1 0-38.26-18.88L352.266667 339.446667l-94.453334 13.726666a21.333333 21.333333 0 1 0 6.133334 42.22z"
:fill=
"color"
p-id=
"16273"
></path>
</svg>
<svg
v-if=
"name === '5'"
t=
"1675655043899"
class=
"icon"
viewBox=
"0 0 1024 1024"
version=
"1.1"
xmlns=
"http://www.w3.org/2000/svg"
p-id=
"17225"
:width=
"w"
:height=
"h"
>
<path
d=
"M832 192v640H192V192h640m32-64H160c-17.6 0-32 14.4-32 32v704c0 17.6 14.4 32 32 32h704c17.6 0 32-14.4 32-32V160c0-17.6-14.4-32-32-32zM768 640H576v64h192v-64zM512 512H256v192h256V512z m256 0H576v64h192v-64z m0-192H256v128h512V320z"
:fill=
"color"
p-id=
"17226"
></path>
</svg>
<svg
v-if=
"name === '6'"
t=
"1675650497733"
class=
"icon"
viewBox=
"0 0 1024 1024"
version=
"1.1"
xmlns=
"http://www.w3.org/2000/svg"
p-id=
"8488"
:width=
"w"
:height=
"h"
>
<path
d=
"M937.4 423.9c-84 0-165.7-27.3-232.9-77.8v352.3c0 179.9-138.6 325.6-309.6 325.6S85.3 878.3 85.3 698.4c0-179.9 138.6-325.6 309.6-325.6 17.1 0 33.7 1.5 49.9 4.3v186.6c-15.5-6.1-32-9.2-48.6-9.2-76.3 0-138.2 65-138.2 145.3 0 80.2 61.9 145.3 138.2 145.3 76.2 0 138.1-65.1 138.1-145.3V0H707c0 134.5 103.7 243.5 231.6 243.5v180.3l-1.2 0.1"
:fill=
"color"
p-id=
"8489"
></path>
</svg>
<svg
v-if=
"name === '7'"
t=
"1675655112200"
class=
"icon"
viewBox=
"0 0 1138 1024"
version=
"1.1"
xmlns=
"http://www.w3.org/2000/svg"
p-id=
"18176"
:width=
"w"
:height=
"h"
>
<path
d=
"M914.432 518.144q27.648 21.504 38.912 51.712t9.216 62.976-14.336 65.536-31.744 59.392q-34.816 48.128-78.848 81.92t-91.136 56.32-94.72 35.328-89.6 18.944-75.264 7.68-51.712 1.536-49.152-2.56-68.096-10.24-78.336-21.504-79.872-36.352-74.24-55.296-59.904-78.848q-16.384-29.696-22.016-63.488t-5.632-86.016q0-22.528 7.68-51.2t27.136-63.488 53.248-75.776 86.016-90.112q51.2-48.128 105.984-85.504t117.248-57.856q28.672-10.24 63.488-11.264t57.344 11.264q10.24 11.264 19.456 23.04t12.288 29.184q3.072 14.336 0.512 27.648t-5.632 26.624-5.12 25.6 2.048 22.528q17.408 2.048 33.792-1.536t31.744-9.216 31.232-11.776 33.28-9.216q27.648-5.12 54.784-4.608t49.152 7.68 36.352 22.016 17.408 38.4q2.048 14.336-2.048 26.624t-8.704 23.04-7.168 22.016 1.536 23.552q3.072 7.168 14.848 13.312t27.136 12.288 32.256 13.312 29.184 16.384zM656.384 836.608q26.624-16.384 53.76-45.056t44.032-64 18.944-75.776-20.48-81.408q-19.456-33.792-47.616-57.344t-62.976-37.376-74.24-19.968-80.384-6.144q-78.848 0-139.776 16.384t-105.472 43.008-72.192 60.416-38.912 68.608q-11.264 33.792-6.656 67.072t20.992 62.976 42.496 53.248 57.856 37.888q58.368 25.6 119.296 32.256t116.224 0.512 100.864-21.504 74.24-33.792zM522.24 513.024q20.48 8.192 38.912 18.432t32.768 27.648q10.24 12.288 17.92 30.72t10.752 39.424 1.536 42.496-9.728 38.912q-8.192 18.432-19.968 37.376t-28.672 35.328-40.448 29.184-57.344 18.944q-61.44 11.264-117.76-11.264t-88.064-74.752q-12.288-39.936-13.312-70.656t16.384-66.56q13.312-27.648 40.448-51.712t62.464-38.912 75.264-17.408 78.848 12.8zM359.424 764.928q37.888 3.072 57.856-18.432t21.504-48.128-15.36-47.616-52.736-16.896q-27.648 3.072-43.008 23.552t-17.408 43.52 9.728 42.496 39.424 21.504zM778.24 6.144q74.752 0 139.776 19.968t113.664 57.856 76.288 92.16 27.648 122.88q0 33.792-16.384 50.688t-35.328 17.408-35.328-14.336-16.384-45.568q0-40.96-22.528-77.824t-59.392-64.512-84.48-43.52-96.768-15.872q-31.744 0-47.104-15.36t-14.336-34.304 18.944-34.304 51.712-15.36zM778.24 169.984q95.232 0 144.384 48.64t49.152 146.944q0 30.72-10.24 43.52t-22.528 11.264-22.528-14.848-10.24-35.84q0-60.416-34.816-96.256t-93.184-35.84q-19.456 0-28.672-10.752t-9.216-23.04 9.728-23.04 28.16-10.752z"
:fill=
"color"
p-id=
"18177"
></path>
</svg>
<svg
v-if=
"name === '8'"
t=
"1675654563546"
class=
"icon"
viewBox=
"0 0 1024 1024"
version=
"1.1"
xmlns=
"http://www.w3.org/2000/svg"
p-id=
"12785"
:width=
"w"
:height=
"h"
>
<path
d=
"M288 64l-128 0C106.88 64 64 106.88 64 160l0 512C64 725.12 106.88 768 160 768l128 0C341.12 768 384 810.88 384 864 384 881.92 398.08 896 416 896S448 881.92 448 864l0-640C448 135.68 376.32 64 288 64zM800 64l-128 0C583.68 64 512 135.68 512 224l0 640C512 881.92 526.08 896 544 896 561.92 896 576 881.92 576 864c0-53.12 42.88-96 96-96l128 0c53.12 0 96-42.88 96-96l0-512C896 106.88 853.12 64 800 64z"
:fill=
"color"
p-id=
"12786"
></path>
</svg>
<svg
v-if=
"name === '9'"
t=
"1675655183921"
class=
"icon"
viewBox=
"0 0 1024 1024"
version=
"1.1"
xmlns=
"http://www.w3.org/2000/svg"
p-id=
"19990"
:width=
"w"
:height=
"h"
>
<path
d=
"M149.6 171.8h691.9c47.2 0 85.9 37.7 86.5 83.9L495.7 493 63.5 256c0.4-46.4 38.8-84.2 86.1-84.2z m-86.1 175l-0.4 419.6c0 46.7 38.9 84.9 86.5 84.9h691.9c47.6 0 86.5-38.2 86.5-84.9V346.6L505.9 572.8c-6.5 3.5-14.3 3.5-20.7 0l-421.7-226z"
:fill=
"color"
p-id=
"19991"
></path>
</svg>
<svg
v-if=
"name === '10'"
t=
"1675655232589"
class=
"icon"
viewBox=
"0 0 1024 1024"
version=
"1.1"
xmlns=
"http://www.w3.org/2000/svg"
p-id=
"20965"
:width=
"w"
:height=
"h"
>
<path
d=
"M850.727 116.266H171.593c-72.728 0-108.108 35.866-108.108 107.608v430.43c0 71.746 33.193 105.653 104.108 105.653h104.112l-12.808 109.564a35.679 35.679 0 0 0 19.029 31.562 35.753 35.753 0 0 0 17.005 4.307c6.988 0 13.982-2.014 19.962-6.028L521.57 759.957h333.156c72.081 0 104.109-33.906 104.109-105.653v-430.43c0-71.742-36.033-107.608-108.108-107.608zM303.159 490.172c-28.658 0-51.949-23.3-51.949-51.873 0-28.57 23.292-51.968 51.949-51.968 28.655 0 51.95 23.304 51.95 51.968-0.005 28.668-23.392 51.873-51.95 51.873z m207.887 0c-28.809 0-52.214-23.3-52.214-51.873 0-28.57 23.41-51.968 52.214-51.968 28.806 0 52.211 23.304 52.211 51.968 0.001 28.668-23.507 51.873-52.21 51.873z m208.21 0c-28.81 0-52.133-23.3-52.133-51.873 0-28.57 23.323-51.968 52.132-51.968 28.797 0 52.207 23.304 52.207 51.968 0 28.668-23.405 51.873-52.207 51.873z m0 0"
:fill=
"color"
p-id=
"20966"
></path>
</svg>
<svg
v-if=
"name === '11'"
t=
"1675660021839"
class=
"icon"
viewBox=
"0 0 1024 1024"
version=
"1.1"
xmlns=
"http://www.w3.org/2000/svg"
p-id=
"24527"
:width=
"w"
:height=
"h"
>
<path
d=
"M512 0C229.2 0 0 229.2 0 512s229.2 512 512 512 512-229.2 512-512S794.8 0 512 0z m-32 769V353c0-17.7 14.3-32 32-32s32 14.3 32 32v416c0 8.8-3.6 16.8-9.4 22.6-5.8 5.8-13.8 9.4-22.6 9.4-17.7 0-32-14.3-32-32z m64-543.5c0 8.8-3.6 16.8-9.4 22.6-5.8 5.8-13.8 9.4-22.6 9.4-17.7 0-32-14.3-32-32v-1c0-17.7 14.3-32 32-32s32 14.3 32 32v1z"
:fill=
"color"
p-id=
"24528"
></path>
</svg>
<svg
v-if=
"name === '12'"
t=
"1675659896272"
class=
"icon"
viewBox=
"0 0 1024 1024"
version=
"1.1"
xmlns=
"http://www.w3.org/2000/svg"
p-id=
"21924"
:width=
"w"
:height=
"h"
>
<path
d=
"M911.275224 233.685939 825.637477 319.323686 704.59016 198.276368 790.227906 112.638622C816.453389 86.413139 859.427341 86.80945 886.152521 113.551861L910.379215 137.761325C937.104395 164.503736 937.500707 207.460456 911.275224 233.685939ZM293.012048 609.888941 414.059366 730.919028 232.479774 791.468533 293.012048 609.888941ZM801.393552 343.567611 438.28606 706.692334 317.238743 585.645016 680.363465 222.520293 801.393552 343.567611ZM179.666958 189.953826C151.166992 189.953826 127.974154 213.146665 127.974154 241.646631L127.974154 844.798277C127.974154 873.298243 151.166992 896.491082 179.666958 896.491082L782.818604 896.491082C811.31857 896.491082 834.511409 873.298243 834.511409 844.798277L834.511409 360.540082 868.973279 326.078212 868.973279 844.798277C868.973279 892.303964 830.324292 930.952951 782.818604 930.952951L179.666958 930.952951C132.161271 930.952951 93.512284 892.303964 93.512284 844.798277L93.512284 241.646631C93.512284 194.140944 132.161271 155.491957 179.666958 155.491957L698.387023 155.491957 663.925153 189.953826 179.666958 189.953826Z"
:fill=
"color"
p-id=
"21925"
></path>
</svg>
</div>
</
template
>
<
style
lang=
"scss"
></
style
>
src/modules/user/components/UpdateDialog.vue
浏览文件 @
90d00e72
<
script
setup
lang=
"ts"
>
import
type
{
FormInstance
,
FormRules
}
from
'element-plus'
import
{
ElMessage
,
ElMessageBox
}
from
'element-plus'
import
{
ElMessage
}
from
'element-plus'
import
{
getMemberConnectionsList
,
getMemberFieldsList
,
createMember
,
updateMember
}
from
'../api'
import
type
{
ConnectionsProp
,
MemberFieldsProp
,
MemberProp
}
from
'../types'
import
{
useMapStore
}
from
'@/stores/map'
// interface Props {
// data?: UserProp
// }
// const props = defineProps
<
Props
>
()
const
store
=
useMapStore
()
defineEmits
<
{
const
ruleFormRef
=
ref
<
FormInstance
>
()
onMounted
(()
=>
{
getConnectionsList
()
getFieldsList
()
})
// 链接列表(所属链接选项)
let
connectionOptions
=
$ref
<
ConnectionsProp
[]
>
()
const
getConnectionsList
=
function
()
{
getMemberConnectionsList
().
then
((
res
:
{
data
:
ConnectionsProp
[]
})
=>
{
connectionOptions
=
res
.
data
})
}
// 用户属性
let
fieldsList
=
$ref
<
MemberFieldsProp
[]
>
([])
const
getFieldsList
=
function
()
{
getMemberFieldsList
().
then
((
res
:
{
data
:
MemberFieldsProp
[]
})
=>
{
fieldsList
=
res
.
data
.
map
(
item
=>
{
item
.
value
=
''
if
(
props
.
data
)
{
item
.
value
=
JSON
.
parse
(
props
.
data
?.
fields
)[
item
.
id
]
}
return
item
})
})
}
interface
Props
{
data
?:
MemberProp
}
const
props
=
defineProps
<
Props
>
()
const
emit
=
defineEmits
<
{
(
e
:
'update'
):
void
(
e
:
'update:modelValue'
,
visible
:
boolean
):
void
}
>
()
const
formRef
=
$ref
<
FormInstance
>
()
const
form
=
reactive
({
id
:
''
,
name
:
''
,
type
:
''
,
value
:
''
,
status
:
''
})
const
form
=
$ref
(
props
.
data
||
{
name
:
''
,
status
:
'0'
,
experiment_connection_id
:
''
,
gender
:
''
,
mobile
:
''
}
)
const
rules
=
ref
<
FormRules
>
({
type
:
[{
required
:
true
,
message
:
'请选择属性字段类型'
}]
name
:
[{
required
:
true
,
message
:
'请输入'
}],
status
:
[{
required
:
true
,
message
:
'请选择'
}],
experiment_connection_id
:
[{
required
:
true
,
message
:
'请选择'
}],
gender
:
[{
required
:
true
,
message
:
'请选择'
}],
mobile
:
[{
required
:
true
,
message
:
'请输入'
}]
})
// 提交
const
submitForm
=
(
formEl
:
FormInstance
|
undefined
)
=>
{
const
fields
=
fieldsList
.
reduce
((
a
:
any
,
b
:
{
id
:
string
;
value
:
string
})
=>
{
a
[
b
.
id
]
=
b
.
value
return
a
},
{})
const
params
=
{
...
form
,
fields
:
fields
}
if
(
!
formEl
)
return
formEl
.
validate
(
valid
=>
{
if
(
valid
)
{
if
(
props
.
data
?.
id
)
{
updateMember
(
params
).
then
(
res
=>
{
emit
(
'update'
)
emit
(
'update:modelValue'
,
false
)
ElMessage
({
message
:
'更新成功'
,
type
:
'success'
})
})
}
else
{
createMember
(
params
).
then
(
res
=>
{
emit
(
'update'
)
emit
(
'update:modelValue'
,
false
)
ElMessage
({
message
:
'添加成功'
,
type
:
'success'
})
})
}
}
else
{
console
.
log
(
'error submit!'
)
return
false
}
})
}
</
script
>
<
template
>
<el-dialog
class=
"connect-form"
title=
"新建用户
"
:title=
"props.data ? (props.data?.isView ? '查看用户' : '编辑用户') : '新建用户'
"
:close-on-click-modal=
"false"
width=
"800px"
@
update:modelValue=
"$emit('update:modelValue')"
>
<el-form
ref=
"formRef"
:model=
"form"
:rules=
"rules"
label-suffix=
":"
label-width=
"142px"
>
<el-form-item
label=
"所属实验"
prop=
"type"
>
<el-select
v-model=
"form.type"
style=
"width: 100%"
></el-select>
<el-form
:disabled=
"props.data?.isView"
ref=
"ruleFormRef"
style=
"width: 400px; margin: 0 auto; padding: 0 30px 30px 0"
:model=
"form"
:rules=
"rules"
label-suffix=
":"
label-width=
"110px"
>
<el-form-item
label=
"来源链接"
prop=
"experiment_connection_id"
>
<el-select
v-model=
"form.experiment_connection_id"
style=
"width: 100%"
>
<el-option
v-for=
"item in connectionOptions"
:label=
"item?.type_name"
:value=
"item?.id"
></el-option>
</el-select>
</el-form-item>
<el-form-item
label=
"姓名"
prop=
"name"
>
<el-input
v-model=
"form.name"
style=
"width: 100%"
></el-input>
</el-form-item>
<el-form-item
label=
"
来源链接
"
>
<el-s
elect
v-model=
"form.id"
style=
"width: 100%"
></el-select
>
<el-form-item
label=
"
状态"
prop=
"status
"
>
<el-s
witch
v-model=
"form.status"
active-text=
"生效"
active-value=
"1"
inactive-text=
"失效"
inactive-value=
"0"
/
>
</el-form-item>
<el-form-item
label=
"姓名"
>
<el-input
v-model=
"form.id"
style=
"width: 100%"
></el-input>
<el-form-item
label=
"性别"
prop=
"gender"
>
<el-select
v-model=
"form.gender"
style=
"width: 100%"
>
<el-option
v-for=
"item in store.getMapValuesByKey('system_gender')"
:label=
"item?.label"
:value=
"item?.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item
label=
"状态"
>
<el-radio-group
v-model=
"form.id"
class=
"ml-4"
>
<el-radio
label=
"1"
size=
"large"
>
生效
</el-radio>
<el-radio
label=
"2"
size=
"large"
>
失效
</el-radio>
</el-radio-group>
<el-form-item
label=
"手机号码"
prop=
"mobile"
>
<el-input
v-model=
"form.mobile"
style=
"width: 100%"
></el-input>
</el-form-item>
<el-form-item
label=
"性别"
>
<el-input
v-model=
"form.id"
style=
"width: 100%"
></el-input>
<el-form-item
:label=
"item.name"
v-for=
"item in fieldsList"
>
<template
v-if=
"item.type === '4' || item.type === '5'"
>
<el-date-picker
v-if=
"item.format === 'yyyy-mm-dd'"
v-model=
"item.value"
type=
"date"
placeholder=
"请选择"
style=
"width: 100%"
value-format=
"YYYY-MM-DD"
/>
<el-date-picker
value-format=
"YYYY-MM-DD HH:mm:ss"
v-else
v-model=
"item.value"
type=
"datetime"
placeholder=
"请选择"
style=
"width: 100%"
/>
</
template
>
<el-input
v-else
v-model=
"item.value"
style=
"width: 100%"
placeholder=
"请输入"
></el-input>
</el-form-item>
<el-form-item
label=
"手机号"
>
<el-input
v-model=
"form.id"
style=
"width: 100%"
></el-input>
<el-form-item>
<el-button
type=
"primary"
@
click=
"submitForm(ruleFormRef)"
>
提交
</el-button>
<el-button
@
click=
"$emit('update:modelValue', false)"
>
关闭
</el-button>
</el-form-item>
</el-form>
<div
class=
"btn-box"
>
<
!-- <
div class="btn-box">
<el-button type="primary">保存</el-button>
<el-button type="primary">关闭</el-button>
</div>
</div>
-->
</el-dialog>
</template>
<
style
lang=
"scss"
>
...
...
src/modules/user/components/UpdateEventsDialog.vue
浏览文件 @
90d00e72
<
script
setup
lang=
"ts"
>
import
type
{
FormInstance
,
FormRules
}
from
'element-plus'
import
{
getEventList
,
createEvent
,
updateEvent
}
from
'../api'
import
{
ElMessage
,
ElMessageBox
}
from
'element-plus'
import
type
{
EventProp
,
MemberProp
,
AttributesProp
}
from
'../types'
// interface Props {
// data?: UserProp
// }
// const props = defineProps
<
Props
>
()
const
route
=
useRoute
()
defineEmits
<
{
interface
Props
{
info
?:
MemberProp
data
?:
AttributesProp
}
const
props
=
defineProps
<
Props
>
()
const
emit
=
defineEmits
<
{
(
e
:
'update'
):
void
(
e
:
'update:modelValue'
,
visible
:
boolean
):
void
}
>
()
const
formRef
=
$ref
<
FormInstance
>
()
const
form
=
reactive
({
id
:
''
,
name
:
''
,
type
:
''
,
value
:
''
,
status
:
''
})
const
form
=
$ref
(
props
.
data
||
{
experiment_meta_event_id
:
''
}
)
const
rules
=
ref
<
FormRules
>
({
type
:
[{
required
:
true
,
message
:
'请选择属性字段类型
'
}]
experiment_meta_event_id
:
[{
required
:
true
,
message
:
'请选择
'
}]
})
let
eventList
=
$ref
<
EventProp
[]
>
()
onMounted
(()
=>
{
getEventList
().
then
(
res
=>
{
eventList
=
res
.
data
.
map
(
(
item
:
any
)
=>
item
.
attributes
.
map
((
cItem
:
any
)
=>
props
.
data
?
(
cItem
.
value
=
JSON
.
parse
(
props
.
data
.
fields
)[
cItem
.
id
])
:
(
cItem
.
value
=
''
)
&&
cItem
)
&&
item
)
})
})
// 属性
const
eventAttributes
=
computed
(()
=>
{
return
eventList
?.
find
(
item
=>
item
.
id
===
form
.
experiment_meta_event_id
)?.
attributes
})
// 提交
const
submitForm
=
(
formEl
:
FormInstance
|
undefined
)
=>
{
if
(
!
formEl
)
return
const
attributes
=
eventAttributes
.
value
?.
reduce
((
a
:
any
,
b
:
any
)
=>
{
a
[
b
.
id
]
=
b
.
value
return
a
},
{})
console
.
log
(
eventList
,
'123attributes'
)
const
[
data
]
=
eventAttributes
.
value
||
[]
formEl
.
validate
(
valid
=>
{
if
(
valid
)
{
if
(
props
.
data
)
{
const
params
=
{
id
:
props
.
data
?.
id
,
fields
:
attributes
}
updateEvent
(
params
).
then
(
res
=>
{
emit
(
'update'
)
emit
(
'update:modelValue'
,
false
)
ElMessage
({
message
:
'更新成功'
,
type
:
'success'
})
})
}
else
{
const
params
=
{
experiment_member_id
:
route
.
query
?.
user_id
as
''
,
experiment_meta_event_id
:
data
.
experiment_meta_event_id
,
fields
:
attributes
}
createEvent
(
params
).
then
(
res
=>
{
emit
(
'update'
)
emit
(
'update:modelValue'
,
false
)
ElMessage
({
message
:
'创建成功'
,
type
:
'success'
})
})
}
}
else
{
return
false
}
})
}
</
script
>
<
template
>
...
...
@@ -34,21 +93,49 @@ const rules = ref<FormRules>({
@
update:modelValue=
"$emit('update:modelValue')"
>
<div
class=
"update-event_info"
>
<span>
姓名:
王小二
</span>
<span>
来源链接:
抖音
</span>
<span>
姓名:
{{
props
.
info
?.
name
}}
</span>
<span>
来源链接:
{{
props
.
info
?.
connection_name
}}
</span>
</div>
<el-form
ref=
"formRef"
:model=
"form"
:rules=
"rules"
label-suffix=
":"
label-width=
"122px"
>
<el-form-item
label=
"请选择事件"
prop=
"type"
>
<el-select
v-model=
"form.type"
style=
"width: 100%"
></el-select>
<el-form
:disabled=
"props.data?.isView"
ref=
"formRef"
:model=
"form"
:rules=
"rules"
label-suffix=
":"
label-width=
"122px"
>
<el-form-item
label=
"请选择事件"
prop=
"experiment_meta_event_id"
>
<el-select
:disabled=
"!!props.data"
v-model=
"form.experiment_meta_event_id"
style=
"width: 100%"
>
<el-option
v-for=
"item in eventList"
:label=
"item.name"
:value=
"item.id"
></el-option>
</el-select>
</el-form-item>
<el-form-item
label=
"订单金额"
prop=
"type"
>
<el-input
v-model=
"form.type"
style=
"width: 100%"
></el-input>
<!-- 属性字段 -->
<el-form-item
:label=
"item.name"
v-for=
"item in eventAttributes"
>
<template
v-if=
"item.type === '4' || item.type === '5'"
>
<el-date-picker
v-if=
"item.format === 'yyyy-mm-dd'"
v-model=
"item.value"
type=
"date"
placeholder=
"请选择"
style=
"width: 100%"
value-format=
"YYYY-MM-DD"
/>
<el-date-picker
value-format=
"YYYY-MM-DD HH:mm:ss"
v-else
v-model=
"item.value"
type=
"datetime"
placeholder=
"请选择"
style=
"width: 100%"
/>
</
template
>
<el-input
v-else
v-model=
"item.value"
style=
"width: 100%"
placeholder=
"请输入"
></el-input>
</el-form-item>
<el-form-item>
<el-button
type=
"primary"
@
click=
"submitForm(formRef)"
>
提交
</el-button>
<el-button
@
click=
"$emit('update:modelValue', false)"
>
关闭
</el-button>
</el-form-item>
</el-form>
<div
class=
"btn-box"
>
<el-button
type=
"primary"
>
关闭
</el-button>
<el-button
type=
"primary"
>
保存
</el-button>
</div>
</el-dialog>
</template>
<
style
lang=
"scss"
>
...
...
src/modules/user/components/UploadEventsDialog.vue
浏览文件 @
90d00e72
<
script
setup
lang=
"ts"
>
import
type
{
FormInstance
,
FormRules
}
from
'element-plus'
import
{
ElMessage
,
ElMessageBox
}
from
'element-plus'
import
{
getEventList
,
importEvent
}
from
'../api'
import
type
{
EventProp
}
from
'../types'
// interface Props {
// data?: UserProp
// }
// const props = defineProps
<
Props
>
()
defineEmits
<
{
const
route
=
useRoute
()
const
emit
=
defineEmits
<
{
(
e
:
'update'
):
void
(
e
:
'update:modelValue'
,
visible
:
boolean
):
void
}
>
()
const
formRef
=
$ref
<
FormInstance
>
()
const
form
=
reactive
({
id
:
''
,
name
:
''
,
type
:
''
,
value
:
''
,
status
:
''
event_id
:
''
})
const
rules
=
ref
<
FormRules
>
({
type
:
[{
required
:
true
,
message
:
'请选择属性字段类型'
}]
event_id
:
[{
required
:
true
,
message
:
'请选择'
}]
})
// 选择事件
let
eventList
=
$ref
<
EventProp
[]
>
()
onMounted
(()
=>
{
getEventList
().
then
(
res
=>
{
eventList
=
res
.
data
})
})
const
connectionName
=
computed
(()
=>
{
return
eventList
?.
find
((
item
:
EventProp
)
=>
item
.
id
===
form
.
event_id
)?.
connection_name
})
// 下载数据模板
const
downloadTemplate
=
function
()
{
if
(
form
.
event_id
!==
''
)
window
.
open
(
`/api/experiment/v1/experiment/member/event-download?event_id=
${
form
.
event_id
}
&experiment_id=
${
route
.
query
.
experiment_id
}
`
)
}
// 上传
const
fetchFileUpload
=
(
option
:
any
)
=>
{
return
new
Promise
(()
=>
{
importEvent
({
event_id
:
form
.
event_id
,
file
:
option
.
file
}).
then
(()
=>
{
ElMessage
.
success
(
'导入数据成功'
)
emit
(
'update'
)
emit
(
'update:modelValue'
,
false
)
// emit('update:isShowImportDialog', false)
// emit('create')
})
})
}
</
script
>
<
template
>
...
...
@@ -35,24 +68,37 @@ const rules = ref<FormRules>({
@
update:modelValue=
"$emit('update:modelValue')"
>
<el-form
ref=
"formRef"
:model=
"form"
:rules=
"rules"
label-suffix=
":"
label-width=
"122px"
>
<el-form-item
label=
"请选择事件"
prop=
"type"
>
<el-select
v-model=
"form.type"
style=
"width: 100%"
></el-select>
<span>
事件所属链接:抖音
</span>
<el-form-item
label=
"请选择事件"
prop=
"event_id"
>
<el-select
v-model=
"form.event_id"
style=
"width: 100%"
>
<el-option
v-for=
"item in eventList"
:label=
"item.name"
:value=
"item.id"
></el-option>
</el-select>
<span
v-if=
"connectionName"
>
事件所属链接:
{{
connectionName
}}
</span>
</el-form-item>
</el-form>
<div
class=
"btn-box"
>
<el-button
type=
"primary"
>
下载事件数据模板
</el-button>
<el-button
type=
"primary"
>
上传事件数据
</el-button>
<el-button
style=
"margin-right: 20px"
type=
"primary"
@
click=
"downloadTemplate"
>
下载事件数据模板
</el-button>
<el-upload
class=
"upload-demo"
action=
"#"
multiple
ref=
"upload"
:auto-upload=
"true"
:limit=
"1"
:http-request=
"fetchFileUpload"
>
<el-button
type=
"primary"
>
上传事件数据
</el-button>
</el-upload>
</div>
<div
class=
"btn-box"
>
<el-button
type=
"primary"
>
关闭
</el-button>
<!--
<el-button
type=
"primary"
>
上传事件数据
</el-button>
-->
<el-button
type=
"primary"
@
click=
"$emit('update:modelValue', false)"
>
关闭
</el-button>
</div>
</el-dialog>
</
template
>
<
style
lang=
"scss"
>
.btn-box
{
display
:
flex
;
text-align
:
center
;
margin-bottom
:
20px
;
justify-content
:
center
;
}
</
style
>
src/modules/user/components/UploadUserDialog.vue
浏览文件 @
90d00e72
<
script
setup
lang=
"ts"
>
import
type
{
FormInstance
,
FormRules
}
from
'element-plus'
import
{
ElMessage
,
ElMessageBox
}
from
'element-plus'
import
{
getMemberConnectionsList
,
getMemberGroups
,
importMember
}
from
'../api'
import
type
{
ConnectionsProp
}
from
'../types'
// interface Props {
// data?: UserProp
// }
// const props = defineProps
<
Props
>
()
defineEmits
<
{
const
route
=
useRoute
()
const
emit
=
defineEmits
<
{
(
e
:
'update'
):
void
(
e
:
'update:modelValue'
,
visible
:
boolean
):
void
}
>
()
const
formRef
=
$ref
<
FormInstance
>
()
const
form
=
reactive
({
id
:
''
,
name
:
''
,
type
:
''
,
value
:
''
,
status
:
''
connection_id
:
''
,
groups_id
:
''
})
const
rules
=
ref
<
FormRules
>
({
type
:
[{
required
:
true
,
message
:
'请选择属性字段类型'
}]
connection_id
:
[{
required
:
true
,
message
:
'请选择'
}]
})
// 链接列表
let
connectionList
=
$ref
<
ConnectionsProp
[]
>
()
// 群组列表
let
groupList
=
$ref
<
{
name
:
string
;
id
:
string
}[]
>
()
onMounted
(()
=>
{
getMemberConnectionsList
().
then
(
res
=>
{
connectionList
=
res
.
data
})
getMemberGroups
().
then
(
res
=>
{
groupList
=
res
.
data
})
})
// 下载数据模板
const
downloadTemplate
=
function
()
{
window
.
open
(
`/api/experiment/v1/experiment/member/member-download?experiment_id=
${
route
.
query
.
experiment_id
}
`
)
}
// 上传
const
fetchFileUpload
=
(
option
:
any
)
=>
{
return
new
Promise
(()
=>
{
const
params
=
Object
.
assign
(
form
,
{
file
:
option
.
file
})
importMember
(
params
).
then
(()
=>
{
ElMessage
.
success
(
'导入数据成功'
)
emit
(
'update'
)
emit
(
'update:modelValue'
,
false
)
// emit('update:isShowImportDialog', false)
// emit('create')
})
})
}
</
script
>
<
template
>
...
...
@@ -35,16 +68,30 @@ const rules = ref<FormRules>({
@
update:modelValue=
"$emit('update:modelValue')"
>
<el-form
ref=
"formRef"
:model=
"form"
:rules=
"rules"
label-suffix=
":"
label-width=
"142px"
>
<el-form-item
label=
"请选择所属链接"
prop=
"type"
>
<el-select
v-model=
"form.type"
style=
"width: 100%"
></el-select>
<el-form-item
label=
"请选择所属链接"
prop=
"connection_id"
>
<el-select
v-model=
"form.connection_id"
style=
"width: 100%"
>
<el-option
v-for=
"item in connectionList"
:label=
"item.type_name"
:value=
"item.id"
></el-option>
</el-select>
</el-form-item>
<el-form-item
label=
"请选择静态群组"
>
<el-select
v-model=
"form.id"
style=
"width: 100%"
></el-select>
<el-select
v-model=
"form.groups_id"
style=
"width: 100%"
>
<el-option
v-for=
"item in groupList"
:label=
"item.name"
:value=
"item.id"
></el-option>
</el-select>
</el-form-item>
</el-form>
<div
class=
"btn-box"
>
<el-button
type=
"primary"
>
下载用户数据模板
</el-button>
<el-button
type=
"primary"
>
上传用户数据
</el-button>
<el-button
style=
"margin-right: 20px"
type=
"primary"
@
click=
"downloadTemplate"
>
下载用户数据模板
</el-button>
<el-upload
class=
"upload-demo"
action=
"#"
multiple
ref=
"upload"
:auto-upload=
"true"
:limit=
"1"
:http-request=
"fetchFileUpload"
>
<el-button
type=
"primary"
>
上传用户数据
</el-button>
</el-upload>
</div>
<div
class=
"btn-box"
>
<el-button
type=
"primary"
>
关闭
</el-button>
...
...
@@ -56,5 +103,7 @@ const rules = ref<FormRules>({
.btn-box
{
text-align
:
center
;
margin-bottom
:
20px
;
display
:
flex
;
justify-content
:
center
;
}
</
style
>
src/modules/user/index.ts
浏览文件 @
90d00e72
...
...
@@ -7,7 +7,8 @@ const routes: RouteRecordRaw[] = [
component
:
Layout
,
children
:
[
{
path
:
''
,
component
:
()
=>
import
(
'./views/Index.vue'
)
},
{
path
:
'eventDetails'
,
component
:
()
=>
import
(
'./views/EventDetails.vue'
)
}
{
path
:
'eventDetails'
,
component
:
()
=>
import
(
'./views/EventDetails.vue'
)
},
{
path
:
'image'
,
component
:
()
=>
import
(
'./views/Image.vue'
)
}
]
}
]
...
...
src/modules/user/types.ts
0 → 100644
浏览文件 @
90d00e72
export
interface
ConnectionsProp
{
id
:
string
type
:
string
type_name
:
string
}
export
interface
MemberFieldsProp
{
id
:
string
name
:
string
english_name
:
string
type
:
string
type_name
:
string
format
:
string
value
:
string
isShow
:
boolean
}
export
interface
MemberProp
{
id
:
string
name
:
string
status
:
string
experiment_connection_id
:
string
gender
:
string
mobile
:
string
fields
:
string
isView
?:
boolean
connection_name
:
string
status_name
:
string
}
export
interface
EventProp
{
name
:
string
id
:
string
attributes
:
AttributesProp
[]
connection_name
:
string
}
export
interface
AttributesProp
{
name
:
string
id
:
string
type
:
string
format
:
string
value
:
string
experiment_meta_event_id
:
string
fields
:
string
connection_id
:
string
isView
:
boolean
}
export
interface
ImageProp
{
tag
:
string
[]
static_groups
:
string
[]
dynamic_groups
:
string
[]
events
:
{
list
:
{
updated_time
:
string
connection_type
:
string
connection_name
:
string
event_name
:
string
}[]
}
}
src/modules/user/views/EventDetails.vue
浏览文件 @
90d00e72
<
script
setup
lang=
"ts"
>
import
{
Plus
,
Download
,
Upload
,
Delete
}
from
'@element-plus/icons-vue'
import
{
ElMessageBox
,
ElMessage
}
from
'element-plus'
import
{
Plus
}
from
'@element-plus/icons-vue'
import
AppList
from
'@/components/base/AppList.vue'
import
UpdateEventsDialog
from
'../components/UpdateEventsDialog.vue'
import
{
getMemberEventList
,
deleteEvent
}
from
'../api'
import
type
{
MemberProp
,
AttributesProp
}
from
'../types'
const
route
=
useRoute
()
const
appList
=
$ref
<
InstanceType
<
typeof
AppList
>
|
null
>
(
null
)
let
userInfo
=
$ref
<
MemberProp
>
()
// 列表配置
const
listOptions
=
computed
(()
=>
{
return
{
remote
:
{
httpRequest
:
getMemberEventList
,
params
:
{
id
:
route
.
query
.
user_id
},
callback
:
(
data
:
any
)
=>
{
userInfo
=
data
return
data
.
events
}
},
columns
:
[
{
label
:
'序号'
,
type
:
'index'
,
width
:
60
},
{
label
:
'事件名称'
,
prop
:
'
id
'
},
{
label
:
'链接名称'
,
prop
:
'name'
},
{
label
:
'事件发生时间'
,
prop
:
'
na
me'
},
{
label
:
'事件名称'
,
prop
:
'
event_name
'
},
{
label
:
'链接名称'
,
prop
:
'
connection_
name'
},
{
label
:
'事件发生时间'
,
prop
:
'
created_ti
me'
},
{
label
:
'操作'
,
slots
:
'table-x'
,
width
:
380
}
],
data
:
[{},
{}]
]
}
})
...
...
@@ -24,32 +38,69 @@ function handleRefresh() {
}
// 事件弹窗
const
eventsVisible
=
$ref
(
false
)
let
eventsVisible
=
$ref
(
false
)
// 编辑
let
currentRow
=
$ref
<
AttributesProp
>
()
const
handleEdit
=
function
(
row
:
AttributesProp
)
{
row
.
isView
=
false
currentRow
=
row
eventsVisible
=
true
}
// 删除
function
handleRemove
(
row
:
AttributesProp
)
{
ElMessageBox
.
confirm
(
'确定要删除该属性吗?'
,
'提示'
).
then
(()
=>
{
deleteEvent
({
id
:
row
.
id
}).
then
(
res
=>
{
ElMessage
({
message
:
'删除成功'
,
type
:
'success'
})
handleRefresh
()
})
})
}
// 新建
const
handleAdd
=
function
()
{
currentRow
=
undefined
eventsVisible
=
true
}
// 查看
const
handleView
=
function
(
row
:
AttributesProp
)
{
row
.
isView
=
true
currentRow
=
row
eventsVisible
=
true
}
</
script
>
<
template
>
<AppCard
title=
"用户事件数据"
>
<div
class=
"event-user_info"
>
<span>
姓名:
王小二
</span>
<span>
id:
11111
</span>
<span>
来源链接:
抖音
</span>
<span>
状态:
生效
</span>
<span>
姓名:
{{
userInfo
?.
name
}}
</span>
<span>
id:
{{
userInfo
?.
id
}}
</span>
<span>
来源链接:
{{
userInfo
?.
connection_name
}}
</span>
<span>
状态:
{{
userInfo
?.
status_name
}}
</span>
</div>
</AppCard>
<AppCard>
<AppList
v-bind=
"listOptions"
ref=
"appList"
>
<template
#
header-buttons
>
<el-button
type=
"primary"
:icon=
"Plus"
@
click=
"
eventsVisible = true
"
>
新建用户事件
</el-button>
<el-button
type=
"primary"
:icon=
"Plus"
@
click=
"
handleAdd
"
>
新建用户事件
</el-button>
</
template
>
<
template
#
table-x
>
<el-button
type=
"primary"
plain
>
查看
</el-button>
<el-button
type=
"primary"
plain
>
编辑
</el-button>
<el-button
type=
"primary"
plain
>
删除
</el-button>
<
template
#
table-x
=
"{ row }"
>
<el-button
type=
"primary"
plain
@
click=
"handleView(row)"
>
查看
</el-button>
<el-button
type=
"primary"
plain
@
click=
"handleEdit(row)"
>
编辑
</el-button>
<el-button
type=
"primary"
plain
@
click=
"handleRemove(row)"
>
删除
</el-button>
</
template
>
</AppList>
</AppCard>
<!-- 新建更新事件 -->
<UpdateEventsDialog
v-model=
"eventsVisible"
></UpdateEventsDialog>
<UpdateEventsDialog
@
update=
"handleRefresh()"
:data=
"currentRow"
v-if=
"eventsVisible"
:info=
"userInfo"
v-model=
"eventsVisible"
></UpdateEventsDialog>
</template>
<
style
lang=
"scss"
>
.event-user_info
{
...
...
src/modules/user/views/Image.vue
0 → 100644
浏览文件 @
90d00e72
<
script
setup
lang=
"ts"
>
import
{
getMemberImage
,
getMemberFieldsList
}
from
'../api'
import
type
{
MemberFieldsProp
,
ImageProp
}
from
'../types'
import
Icon
from
'../components/Icon.vue'
const
route
=
useRoute
()
// 画像数据
let
data
=
$ref
<
ImageProp
>
()
// 属性
let
fieldsList
=
$ref
<
MemberFieldsProp
[]
>
()
onMounted
(()
=>
{
// 画像
getMemberImage
({
id
:
route
.
query
.
user_id
as
''
}).
then
(
res
=>
{
data
=
res
.
data
getFields
(
res
.
data
)
})
// 属性
})
const
getFields
=
function
(
data
:
{
fields
:
any
})
{
getMemberFieldsList
().
then
(
res
=>
{
// fieldsList = res.data
fieldsList
=
res
.
data
.
map
((
item
:
MemberFieldsProp
)
=>
{
if
(
data
.
fields
[
item
.
id
])
{
item
.
value
=
data
.
fields
[
item
.
id
]
item
.
isShow
=
true
}
return
item
})
})
}
// 获取上下午
const
getDate
=
function
(
date
:
string
)
{
return
parseInt
(
date
.
slice
(
date
.
indexOf
(
' '
),
date
.
indexOf
(
' '
)
+
3
))
>
12
?
'下午'
:
'上午'
}
</
script
>
<
template
>
<div
class=
"card-box"
>
<AppCard
class=
"card"
title=
"用户属性"
>
<div
style=
"display: flex; justify-content: center; padding-right: 20px"
>
<el-form
label-suffix=
":"
label-width=
"110px"
>
<template
v-for=
"item in fieldsList"
>
<el-form-item
v-if=
"item?.isShow"
:label=
"item?.name"
><span>
{{
item
?.
value
}}
</span></el-form-item
>
</
template
>
</el-form>
</div>
</AppCard>
<AppCard
class=
"card"
title=
"标签与群组"
>
<el-tabs
class=
"demo-tabs"
>
<el-tab-pane
label=
"用户标签"
>
<div
class=
"scroll"
>
<el-tag
class=
"ml-2"
type=
"success"
v-for=
"item in data?.tag"
>
{{ item }}
</el-tag>
</div>
</el-tab-pane>
</el-tabs>
<el-tabs
class=
"demo-tabs"
>
<el-tab-pane
label=
"静态分组"
>
<div
class=
"scroll"
>
<el-tag
class=
"ml-2"
type=
"success"
v-for=
"item in data?.static_groups"
>
{{ item }}
</el-tag>
</div>
</el-tab-pane>
</el-tabs>
<el-tabs
class=
"demo-tabs"
>
<el-tab-pane
label=
"动态分组"
>
<div
class=
"scroll"
>
<el-tag
class=
"ml-2"
type=
"success"
v-for=
"item in data?.dynamic_groups"
>
{{ item }}
</el-tag>
</div>
</el-tab-pane>
</el-tabs>
</AppCard>
<AppCard
class=
"card"
title=
"用户行为轨迹"
>
<div
class=
"event-box"
v-for=
"item in data?.events?.list"
>
<div
class=
"date"
>
{{ item.updated_time?.slice(0, item.updated_time.indexOf(' ')) }}
</div>
<div
class=
"event-content"
>
<div
class=
"time"
>
{{ item.updated_time?.slice(item.updated_time.indexOf(' '), item.updated_time.length - 3) }}
{{ getDate(item.updated_time) }}
</div>
<Icon
class=
"icon"
:name=
"item.connection_type"
w=
"30"
h=
"30"
></Icon>
<div
class=
"event"
>
在
<span>
"{{ item.connection_name }}"
</span>
上
<span>
"{{ item.event_name }}"
</span>
</div>
</div>
</div>
<div
class=
"event-box"
v-for=
"item in data?.events?.list"
>
<div
class=
"date"
>
{{ item.updated_time?.slice(0, item.updated_time.indexOf(' ')) }}
</div>
<div
class=
"event-content"
>
<div
class=
"time"
>
{{ item.updated_time?.slice(item.updated_time.indexOf(' '), item.updated_time.length - 3) }}
{{ getDate(item.updated_time) }}
</div>
<Icon
class=
"icon"
:name=
"item.connection_type"
w=
"30"
h=
"30"
></Icon>
<div
class=
"event"
>
在
<span>
"{{ item.connection_name }}"
</span>
上
<span>
"{{ item.event_name }}"
</span>
</div>
</div>
</div>
</AppCard>
</div>
</template>
<
style
lang=
"scss"
>
.ml-2
{
margin-right
:
10px
;
}
.card-box
{
display
:
flex
;
.card
{
flex
:
1
;
margin-top
:
0
;
height
:
90vh
;
margin-right
:
10px
;
.demo-tabs
{
height
:
26vh
;
}
}
}
.event-box
{
border-bottom
:
1px
solid
#ccc
;
padding
:
20px
0
5px
;
.date
{
font-size
:
14px
;
}
}
.event-content
{
display
:
flex
;
font-size
:
12px
;
align-items
:
center
;
// margin-bottom: 20px;
flex-wrap
:
wrap
;
.time
{
color
:
#ccc
;
}
.icon
{
margin
:
0
5px
;
}
span
{
color
:
#ba143e
;
font-weight
:
bold
;
}
}
</
style
>
src/modules/user/views/Index.vue
浏览文件 @
90d00e72
<
script
setup
lang=
"ts"
>
import
{
Plus
,
Download
,
Upload
,
Delete
}
from
'@element-plus/icons-vue'
import
AppList
from
'@/components/base/AppList.vue'
import
UploadEventsDialog
from
'../components/UploadEventsDialog.vue'
import
UploadUserDialog
from
'../components/UploadUserDialog.vue'
import
UpdateDialog
from
'../components/UpdateDialog.vue'
// import { getMemberMetaDetail } from '../api'
import
{
getMemberList
,
deleteMember
}
from
'../api'
import
{
ElMessage
}
from
'element-plus'
import
type
{
MemberProp
}
from
'../types'
const
UpdateDialog
=
defineAsyncComponent
(()
=>
import
(
'../components/UpdateDialog.vue'
))
const
UploadEventsDialog
=
defineAsyncComponent
(()
=>
import
(
'../components/UploadEventsDialog.vue'
))
const
UploadUserDialog
=
defineAsyncComponent
(()
=>
import
(
'../components/UploadUserDialog.vue'
))
const
router
=
useRouter
()
const
route
=
useRoute
()
const
appList
=
$ref
<
InstanceType
<
typeof
AppList
>
|
null
>
(
null
)
// 列表配置
const
listOptions
=
computed
(()
=>
{
return
{
filters
:
[{
type
:
'input'
,
prop
:
'name'
,
placeholder
:
'请输入用户姓名'
}],
remote
:
{
httpRequest
:
getMemberList
,
params
:
{
name
:
''
,
id
:
''
,
mobile
:
''
,
status
:
''
}
},
filters
:
[
{
type
:
'input'
,
prop
:
'name'
,
placeholder
:
'请输入用户姓名'
},
{
type
:
'input'
,
prop
:
'id'
,
placeholder
:
'请输入用户ID'
},
{
type
:
'input'
,
prop
:
'mobile'
,
placeholder
:
'请输入用户手机号'
},
{
type
:
'select'
,
prop
:
'status'
,
placeholder
:
'请选择生效状态'
,
options
:
[
{
label
:
'有效'
,
value
:
'1'
},
{
label
:
'失效'
,
value
:
'0'
}
]
}
],
columns
:
[
{
type
:
'selection'
},
{
label
:
'序号'
,
type
:
'index'
,
width
:
60
},
{
label
:
'用户ID'
,
prop
:
'id'
},
{
label
:
'姓名'
,
prop
:
'name'
},
{
label
:
'性别'
,
prop
:
'name'
},
{
label
:
'手机号码'
,
prop
:
'
nam
e'
},
{
label
:
'来源连接'
,
prop
:
'name'
},
{
label
:
'状态'
,
prop
:
'name'
},
{
label
:
'更新人'
,
prop
:
'name'
},
{
label
:
'更新时间'
,
prop
:
'
na
me'
},
{
label
:
'性别'
,
prop
:
'
gender_
name'
},
{
label
:
'手机号码'
,
prop
:
'
mobil
e'
},
{
label
:
'来源连接'
,
prop
:
'
connection_
name'
},
{
label
:
'状态'
,
prop
:
'
status_
name'
},
{
label
:
'更新人'
,
prop
:
'
updated_operator_
name'
},
{
label
:
'更新时间'
,
prop
:
'
updated_ti
me'
},
{
label
:
'操作'
,
slots
:
'table-x'
,
width
:
380
}
],
data
:
[{},
{}]
]
}
})
...
...
@@ -40,21 +63,99 @@ const eventsVisible = $ref(false)
const
userVisible
=
$ref
(
false
)
// 新建、更新、查看
const
updateVisible
=
$ref
(
false
)
let
updateVisible
=
$ref
(
false
)
let
multipleSelection
=
$ref
<
MemberProp
[]
>
([])
function
handleSelectionChange
(
selection
:
MemberProp
[])
{
multipleSelection
=
selection
}
// 删除
const
handleRemove
=
function
(
row
:
{
id
:
string
})
{
deleteMembers
(
row
.
id
)
}
const
handleRemoves
=
function
()
{
const
ids
=
multipleSelection
.
reduce
((
a
:
any
,
b
:
any
)
=>
{
a
.
push
(
b
.
id
)
return
a
},
[])
.
toString
()
deleteMembers
(
ids
)
}
const
deleteMembers
=
function
(
ids
:
string
)
{
deleteMember
({
ids
:
ids
}).
then
(
res
=>
{
ElMessage
({
message
:
'删除成功'
,
type
:
'success'
})
handleRefresh
()
})
}
// 编辑
let
currentRow
=
ref
<
MemberProp
>
()
const
handleEdit
=
function
(
row
:
MemberProp
)
{
currentRow
.
value
=
row
row
.
isView
=
false
updateVisible
=
true
}
// 查看
const
handleView
=
function
(
row
:
MemberProp
)
{
row
.
isView
=
true
currentRow
.
value
=
row
updateVisible
=
true
}
// 新建
const
handleAdd
=
function
()
{
updateVisible
=
true
currentRow
.
value
=
undefined
}
// 事件详情页
const
goPage
=
function
(
row
:
MemberProp
)
{
router
.
push
({
path
:
'/user/eventDetails'
,
query
:
{
user_id
:
row
.
id
}
})
}
// 画像
const
handleImage
=
function
(
row
:
MemberProp
)
{
router
.
push
({
path
:
'/user/image'
,
query
:
{
user_id
:
row
.
id
}
})
}
// 导出用户
const
downloadMember
=
function
(
isAll
?:
boolean
)
{
const
ids
=
multipleSelection
.
reduce
((
a
:
any
,
b
:
any
)
=>
{
a
.
push
(
b
.
id
)
return
a
},
[])
.
toString
()
if
(
isAll
)
{
window
.
open
(
`/api/experiment/v1/experiment/member/download?experiment_id=
${
route
.
query
.
experiment_id
}
`
)
}
else
{
window
.
open
(
`/api/experiment/v1/experiment/member/download?experiment_id=
${
route
.
query
.
experiment_id
}
&ids=
${
ids
}
`
)
}
}
</
script
>
<
template
>
<AppCard>
<AppList
v-bind=
"listOptions"
ref=
"appList"
>
<AppList
v-bind=
"listOptions"
ref=
"appList"
@
selection-change=
"handleSelectionChange"
>
<template
#
header-buttons
>
<el-space>
<el-button
type=
"primary"
:icon=
"Plus"
>
新建
</el-button>
<el-button
type=
"primary"
:icon=
"Plus"
@
click=
"handleAdd"
>
新建
</el-button>
<el-dropdown>
<el-button
type=
"primary"
:icon=
"Download"
>
导出
</el-button>
<template
#
dropdown
>
<el-dropdown-menu>
<el-dropdown-item>
全部用户数据
</el-dropdown-item>
<el-dropdown-item>
勾选用户数据
</el-dropdown-item>
<el-dropdown-item
@
click=
"downloadMember(true)"
>
全部用户数据
</el-dropdown-item>
<el-dropdown-item
@
click=
"downloadMember(false)"
>
勾选用户数据
</el-dropdown-item>
</el-dropdown-menu>
</
template
>
</el-dropdown>
...
...
@@ -67,22 +168,24 @@ const updateVisible = $ref(false)
</el-dropdown-menu>
</
template
>
</el-dropdown>
<el-button
type=
"danger"
plain
:icon=
"Delete"
>
删除
</el-button>
<el-button
type=
"danger"
plain
:icon=
"Delete"
:disabled=
"!multipleSelection.length"
@
click=
"handleRemoves()"
>
删除
</el-button
>
</el-space>
</template>
<
template
#
table-x
>
<el-button
type=
"primary"
plain
>
画像
</el-button>
<el-button
type=
"primary"
plain
>
查看
</el-button>
<el-button
type=
"primary"
plain
>
编辑
</el-button>
<el-button
type=
"primary"
plain
>
删除
</el-button>
<el-button
type=
"primary"
plain
>
事件
</el-button>
<
template
#
table-x
=
"{ row }"
>
<el-button
type=
"primary"
plain
@
click=
"handleImage(row)"
>
画像
</el-button>
<el-button
type=
"primary"
plain
@
click=
"handleView(row)"
>
查看
</el-button>
<el-button
type=
"primary"
plain
@
click=
"handleEdit(row)"
>
编辑
</el-button>
<el-button
type=
"primary"
plain
@
click=
"handleRemove(row)"
>
删除
</el-button>
<el-button
type=
"primary"
plain
@
click=
"goPage(row)"
>
事件
</el-button>
</
template
>
</AppList>
</AppCard>
<!-- 导入事件弹窗 -->
<UploadEventsDialog
v-model=
"eventsVisible"
></UploadEventsDialog>
<UploadEventsDialog
@
update=
"handleRefresh"
v-if=
"eventsVisible"
v-model=
"eventsVisible"
></UploadEventsDialog>
<!-- 导入用户弹窗 -->
<UploadUserDialog
v-model=
"userVisible"
></UploadUserDialog>
<UploadUserDialog
@
update=
"handleRefresh"
v-if=
"userVisible"
v-model=
"userVisible"
></UploadUserDialog>
<!-- 新建、更新、查看 -->
<UpdateDialog
v-
model=
"updateVisible
"
></UpdateDialog>
<UpdateDialog
v-
if=
"updateVisible"
:data=
"currentRow"
v-model=
"updateVisible"
@
update=
"handleRefresh
"
></UpdateDialog>
</template>
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论