提交 5e027871 authored 作者: 王鹏飞's avatar 王鹏飞

chore: 新增用户旅程数据生成

上级 13df73f3
import httpRequest from '@/utils/axios'
// 旅程生成用户事件数据列表(搜索条件)
export function getGenerateListFilter() {
return httpRequest.get('/api/lab/v1/experiment/member/itinerary-generate-data-condition')
}
// 旅程生成用户事件数据列表
export function getGenerateList(params: any) {
return httpRequest.get('/api/lab/v1/experiment/member/itinerary-generate-data', { params })
}
<script setup>
import AppList from '@/components/base/AppList.vue'
import { getGenerateListFilter, getGenerateList } from '@/api/generateEvent'
const ViewEvent = defineAsyncComponent(() => import('@/components/ViewEvent.vue'))
import { useUserStore } from '@/stores/user'
const userStore = useUserStore()
const filter = reactive({ students: [], connections: [], events: [] })
async function fetchListFilters() {
const { data } = await getGenerateListFilter()
Object.assign(filter, data)
}
onMounted(() => {
fetchListFilters()
})
const students = computed(() => {
return filter.students.map((item) => {
return { ...item, name: `${item.name}/${item.mobile}` }
})
})
// 列表配置
const listOptions = computed(() => {
const userId = userStore.role.id == 1 ? userStore.user?.id : ''
return {
remote: {
httpRequest: getGenerateList,
params: { created_operator: userId, name: '', connection_id: '', experiment_meta_event_id: '', created_time_start: '', created_time_end: '' }
},
filters: [
{
type: 'select',
prop: 'created_operator',
placeholder: '请选择学生姓名',
options: students.value,
labelKey: 'name',
valueKey: 'sso_id',
disabled: !!userId
},
{ type: 'input', prop: 'name', placeholder: '请输入用户姓名' },
{ type: 'select', prop: 'connection_id', placeholder: '请选择来源连接', options: filter.connections, labelKey: 'type_name', valueKey: 'id' },
{ type: 'select', prop: 'experiment_meta_event_id', placeholder: '请选择事件', options: filter.events, labelKey: 'name', valueKey: 'id' },
{ type: 'input', prop: 'created_time_start', slots: 'filter-start' },
{ type: 'input', prop: 'created_time_end', slots: 'filter-end' }
],
columns: [
{ label: '序号', type: 'index', width: 60 },
{ label: '连接', prop: 'connection_name' },
{ label: '事件名称', prop: 'event_name' },
{ label: '用户名称', prop: 'member.name' },
{ label: '手机号', prop: 'member.mobile' },
{ label: '事件发生时间', prop: 'created_time' },
{ label: '操作', slots: 'table-x', width: 220 }
]
}
})
const viewEventVisible = ref(false)
const currentViewEvent = ref()
function handleViewEvent(item) {
viewEventVisible.value = true
currentViewEvent.value = item
}
</script>
<template>
<el-dialog title="用户事件数据" width="1000px">
<AppList v-bind="listOptions" ref="appList">
<template #filter-start="{ params }">
<el-date-picker v-model="params.created_time_start" type="datetime" placeholder="请选择事件发生起始时间" value-format="YYYY-MM-DD HH:mm:ss" />
</template>
<template #filter-end="{ params }">
<el-date-picker v-model="params.created_time_end" type="datetime" placeholder="请选择事件发生截止时间" value-format="YYYY-MM-DD HH:mm:ss" />
</template>
<template #table-x="{ row }">
<el-button type="primary" plain @click="handleViewEvent(row)">事件详情</el-button>
<el-button type="primary" plain>
<router-link target="_blank" :to="{ path: '/user/image', query: { user_id: row.member.id, experiment_id: row.experiment_id } }">用户详情</router-link>
</el-button>
</template>
</AppList>
<!-- 事件详情 -->
<ViewEvent v-model="viewEventVisible" :event="currentViewEvent" :user="currentViewEvent.member" v-if="viewEventVisible && currentViewEvent"></ViewEvent>
</el-dialog>
</template>
......@@ -26,12 +26,13 @@ const addField = function () {
}
// 删除字段
const deleteField = function (scope: { $index: number; row: { id: string } }) {
const deleteField = function (scope: { $index: number; row: EventAttributesProp }) {
if (scope.row.isDefault) return
if (tableData[scope.$index]?.id === '') {
tableData.splice(scope.$index, 1)
} else {
// 判断当前属性是否可以删除
getIsDeleteAttribute({ id: scope.row.id }).then(res => {
getIsDeleteAttribute({ id: scope.row.id }).then((res) => {
res.data?.can_delete ? tableData.splice(scope.$index, 1) : ElMessage({ message: '不能删除', type: 'warning' })
})
}
......@@ -41,12 +42,19 @@ const deleteField = function (scope: { $index: number; row: { id: string } }) {
let eventDetail = $ref<EventDetailProp>()
onBeforeMount(() => {
getMetaEventDetail({ id: props.data?.id || '' }).then(res => {
getMetaEventDetail({ id: props.data?.id || '' }).then((res) => {
eventDetail = res.data
tableData = res.data.attributes
tableData = defaultFields.concat(res.data.attributes)
})
})
// 默认字段
const defaultFields = [
{ id: '1', name: '事件ID', english_name: 'action_id', type: '1', format: '25', isDefault: true },
{ id: '2', name: '事件发生时间', english_name: 'action_time', type: '5', format: 'yyyy-mm-dd hh:mm:ss', isDefault: true },
{ id: '3', name: '用户ID', english_name: 'user_id', type: '1', format: '25', isDefault: true }
]
// 字段
let tableData = $ref<EventAttributesProp[]>([])
......@@ -58,7 +66,7 @@ function handleSubmit() {
function handleUpdate() {
const params = {
id: eventDetail?.id || '',
attributes: JSON.stringify(tableData)
attributes: JSON.stringify(tableData.filter((item) => !item.isDefault))
}
updateAttributes(params).then(() => {
ElMessage({ message: '保存成功', type: 'success' })
......@@ -111,12 +119,7 @@ const popoverText = function (row: any) {
</script>
<template>
<el-dialog
title="事件属性"
:close-on-click-modal="false"
width="800px"
@update:modelValue="value => $emit('update:modelValue', value)"
>
<el-dialog title="事件属性" :close-on-click-modal="false" width="800px" @update:modelValue="(value) => $emit('update:modelValue', value)">
<div style="display: flex; justify-content: space-around">
<el-form label-width="120px">
<el-form-item label="事件英文名称:">{{ eventDetail?.english_name }}</el-form-item>
......@@ -136,71 +139,51 @@ const popoverText = function (row: any) {
</template>
<el-table :data="tableData" style="width: 100%">
<el-table-column label="属性英文名">
<template #default="scope">
<el-input v-model="scope.row.english_name" placeholder="请输入"></el-input>
<template #default="{ row }">
<el-input v-model="row.english_name" placeholder="请输入" :disabled="row.isDefault"></el-input>
</template>
</el-table-column>
<el-table-column label="属性名称">
<template #default="scope">
<el-input v-model="scope.row.name" placeholder="请输入"></el-input>
<template #default="{ row }">
<el-input v-model="row.name" placeholder="请输入" :disabled="row.isDefault"></el-input>
</template>
</el-table-column>
<el-table-column label="字段类型">
<template #default="scope">
<el-select
@change="changeFormatType(scope.row)"
:disabled="scope.row.id !== ''"
v-model="scope.row.type"
placeholder="请选择"
>
<el-option
:label="item.label"
:value="item.value"
:key="item.id"
v-for="item in experimentAttributeOptions"
></el-option>
<template #default="{ row }">
<el-select @change="changeFormatType(row)" :disabled="row.id !== ''" v-model="row.type" placeholder="请选择">
<el-option :label="item.label" :value="item.value" :key="item.id" v-for="item in experimentAttributeOptions"></el-option>
</el-select>
</template>
</el-table-column>
<el-table-column label="字段格式">
<template #default="scope">
<el-select
:disabled="scope.row.id !== ''"
v-if="scope.row.type === '4' || scope.row.type === '5'"
v-model="scope.row.format"
placeholder="请选择"
>
<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"
value="yyyy-mm-dd hh:mm:ss"
></el-option>
<template #default="{ row }">
<el-select :disabled="row.id !== ''" v-if="row.type === '4' || row.type === '5'" v-model="row.format" placeholder="请选择">
<el-option v-if="row.type !== '5'" label="yyyy-mm-dd" value="yyyy-mm-dd"></el-option>
<el-option v-if="row.type !== '4'" label="yyyy-mm-dd hh:mm:ss" value="yyyy-mm-dd hh:mm:ss"></el-option>
</el-select>
<el-input
v-else
:disabled="scope.row.id !== ''"
:disabled="row.id !== ''"
type="number"
v-model="scope.row.format"
:placeholder="scope.row.type === '1' ? '请输入字符串长度' : '请输入长度'"
></el-input>
v-model="row.format"
:placeholder="row.type === '1' ? '请输入字符串长度' : '请输入长度'"></el-input>
</template>
</el-table-column>
<el-table-column width="30">
<template #default="scope">
<el-popover placement="top-start" :width="300" trigger="hover" :title="scope?.row.type_name">
<template #default="{ row }">
<el-popover placement="top-start" :width="300" trigger="hover" :title="row.type_name">
<template #reference>
<div style="display: flex; justify-content: center; cursor: pointer">
<el-icon size="20"><QuestionFilled /></el-icon>
</div>
</template>
<div v-html="popoverText(scope.row)"></div>
<div v-html="popoverText(row)"></div>
</el-popover>
</template>
</el-table-column>
<el-table-column width="30" v-if="props.data?.can_edit !== '0'">
<template #default="scope">
<div @click="deleteField(scope)" style="display: flex; justify-content: center; cursor: pointer">
<div @click="deleteField(scope)" style="display: flex; justify-content: center; cursor: pointer" v-if="!scope.row.isDefault">
<el-icon size="20"><Close /></el-icon>
</div>
</template>
......@@ -210,13 +193,12 @@ const popoverText = function (row: any) {
<template #footer>
<el-row justify="center">
<el-button round auto-insert-space @click="$emit('update:modelValue', false)">关闭</el-button>
<el-button type="primary" round auto-insert-space @click="handleSubmit" v-if="props.data?.can_edit !== '0'"
>保存</el-button
>
<el-button type="primary" round auto-insert-space @click="handleSubmit" v-if="props.data?.can_edit !== '0'">保存</el-button>
</el-row>
</template>
</el-dialog>
</template>
<style lang="scss">
.card-header {
display: flex;
......
......@@ -11,7 +11,10 @@ export interface EventProp {
can_edit: string
}
export interface ConnectionOptionProp { type_name: string; id: string }
export interface ConnectionOptionProp {
type_name: string
id: string
}
export interface EventDetailProp {
id: string
......@@ -27,4 +30,5 @@ export interface EventAttributesProp {
english_name: string
type: string
format: string
isDefault?: boolean
}
......@@ -19,3 +19,8 @@ export function bindTripConnections(data: { itinerary_id: string; connections_id
export function getTripTemplateDemo(params: { itinerary_id?: string }) {
return httpRequest.get('/api/lab/v1/experiment/itinerary/get-itinerary-demo', { params })
}
// 一键生成旅程数据
export function studentGenerateData(data: { itinerary_id: string; type: number }) {
return httpRequest.post('/api/lab/v1/experiment/itinerary/student-generate-data', data)
}
<script setup lang="ts">
import type { Trip } from '../types'
import { studentGenerateData } from '../api'
import { ElMessage } from 'element-plus'
const props = defineProps<{
data: Trip
}>()
const emit = defineEmits<{
(e: 'update'): void
}>()
const dialogVisible = ref(false)
const generateVisible = ref(false)
const generateLoading = ref(false)
const params = reactive({
type: 1,
itinerary_id: props.data.id
})
async function handleGenerate() {
dialogVisible.value = false
generateLoading.value = true
generateVisible.value = true
try {
await studentGenerateData(params)
emit('update')
ElMessage.success('生成数据成功')
} catch (error) {
console.error(error)
} finally {
generateLoading.value = false
generateVisible.value = false
}
}
</script>
<template>
<el-button type="primary" :disabled="generateLoading" @click="dialogVisible = true">一键生成旅程数据</el-button>
<el-dialog v-model="dialogVisible" width="400" title="生成旅程数据">
<p class="dialog-text" v-if="data.has_itinerary_generate_data">
系统检测到您正在重复生成用户旅程事件数据!<br />
该操作将会覆盖您之前生成的数据且无法恢复,请确认!
</p>
<p class="dialog-text" v-else>
即将生成用户旅程相关事件数据,<br />
请确认您的用户旅程的每一个节点已经完成配置!
</p>
<el-radio-group v-model="params.type" class="dialog-radio-group">
<el-radio label="今日" :value="1"></el-radio>
<el-radio label="前7日" :value="2"></el-radio>
<el-radio label="前30日" :value="3"></el-radio>
</el-radio-group>
<template #footer>
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="handleGenerate">生成数据</el-button>
</template>
</el-dialog>
<el-dialog v-model="generateVisible" title="提示" width="400">
<p class="dialog-text">正在生成数据中,请耐心等待</p>
<template #footer>
<el-button @click="generateVisible = false">关闭</el-button>
</template>
</el-dialog>
</template>
<style lang="scss">
.dialog-text {
line-height: 24px;
text-align: center;
}
.dialog-radio-group {
margin: 10px;
display: flex;
align-items: center;
justify-content: center;
}
</style>
......@@ -22,4 +22,5 @@ export interface Trip {
experiment_itinerary_name: string
experiment_itinerary_type: string
experiment_itinerary_type_name: string
has_itinerary_generate_data: boolean
}
......@@ -6,6 +6,8 @@ import { ElMessage } from 'element-plus'
import { getStudentTrip, getTripTemplateDemo, updateTrip } from '../api'
const BindConnection = defineAsyncComponent(() => import('../components/BindConnection.vue'))
const ViewGenerateEventData = defineAsyncComponent(() => import('@/components/ViewGenerateEventData.vue'))
const GenerateData = defineAsyncComponent(() => import('../components/GenerateData.vue'))
const detail = ref<Trip>()
const elements = ref([])
......@@ -61,16 +63,22 @@ function handleConnectionUpdate(value: string[]) {
if (!detail.value) return
detail.value.connect_ids = value
}
const generateEventVisible = ref(false)
</script>
<template>
<AppCard :title="detail?.experiment_itinerary_type_name" v-if="detail">
<el-card shadow="never" style="margin-bottom: 20px" v-if="detail">
<el-descriptions class="info">
<div style="display: flex; align-items: center">
<el-descriptions class="info" style="flex: 1">
<el-descriptions-item label="课程名称:">{{ detail.course_name }}</el-descriptions-item>
<el-descriptions-item label="实验名称:">{{ detail.experiment_name }}</el-descriptions-item>
<el-descriptions-item label="旅程类型:">{{ detail.experiment_itinerary_type_name }}</el-descriptions-item>
</el-descriptions>
<GenerateData :data="detail" @update="fetchInfo"></GenerateData>
<el-button type="primary" @click="generateEventVisible = true" v-if="detail.has_itinerary_generate_data">查看用户旅程数据</el-button>
</div>
</el-card>
<TripFlow
v-model="elements"
......@@ -84,9 +92,7 @@ function handleConnectionUpdate(value: string[]) {
</template>
<template #header>
<el-row align="middle">
<el-button type="primary" size="large" @click="handleConfig" style="margin-right: 20px" v-if="false"
>配置连接</el-button
>
<el-button type="primary" size="large" @click="handleConfig" style="margin-right: 20px" v-if="false">配置连接</el-button>
<el-alert center style="flex: 1">
<p style="text-align: center">
<template v-if="isFree">
......@@ -107,9 +113,7 @@ function handleConnectionUpdate(value: string[]) {
</AppCard>
<!-- 配置连接 -->
<BindConnection
v-model="configVisible"
:data="detail"
@update="handleConnectionUpdate"
v-if="configVisible && detail"></BindConnection>
<BindConnection v-model="configVisible" :data="detail" @update="handleConnectionUpdate" v-if="configVisible && detail"></BindConnection>
<!-- 用户事件数据 -->
<ViewGenerateEventData v-model="generateEventVisible" v-if="generateEventVisible"></ViewGenerateEventData>
</template>
......@@ -52,7 +52,13 @@ export function ruleQuery(data: { experiment_id: string; filters: string }) {
}
// 保存实验旅程数据规则
export function saveRule(data: { itinerary_id: string; data_generate_mode: string; data_generate_frequency: string; auto_generate_rule: string; graph: string }) {
export function saveRule(data: {
itinerary_id: string
data_generate_mode: string
data_generate_frequency: string
auto_generate_rule: string
graph: string
}) {
return httpRequest.post('/api/resource/v1/backend/experiment-itinerary/save-data-config', data)
}
......@@ -60,3 +66,13 @@ export function saveRule(data: { itinerary_id: string; data_generate_mode: strin
export function updateTriggerStatus(data: { itinerary_id: string; trigger_status: 0 | 1 }) {
return httpRequest.post('/api/lab/v1/experiment/itinerary/trigger', data)
}
// 获取配置旅程数据规则
export function getGenerateDataRule(params: { itinerary_id: string }) {
return httpRequest.get('/api/lab/v1/experiment/itinerary/generate-data-config', { params })
}
// 保存配置旅程数据规则
export function updateGenerateDataRule(data: { itinerary_id: string; config: any }) {
return httpRequest.post('/api/lab/v1/experiment/itinerary/generate-data-config', data)
}
<script setup lang="ts">
import type { TripTemplate } from '../types'
import { getGenerateDataRule, updateGenerateDataRule } from '../api'
import { ElMessage } from 'element-plus'
const props = defineProps<{ data: TripTemplate }>()
const emit = defineEmits<{
(e: 'update:modelValue', visible: boolean): void
}>()
const dataset: any = reactive({ events: [], list: [] })
async function fetchGenerateDataRule() {
const { data } = await getGenerateDataRule({ itinerary_id: props.data.id })
data.list = data.list.map((item: any) => {
return { ...item, ratio: parseFloat(item.ratio) }
})
Object.assign(dataset, data)
}
onMounted(() => {
fetchGenerateDataRule()
})
const listOptions = computed(() => {
return {
data: dataset.list,
columns: [
{ label: '连接名称', prop: 'connection_name', width: 100 },
{ label: '动作类型', prop: 'action', width: 100 },
{ label: '旅程动作', prop: 'itinerary', width: 100 },
{ label: '旅程事件', prop: 'event' },
{ label: '对应用户事件', prop: 'user_event_id', slots: 'table-event' },
{ label: '生成数据比例规则', prop: 'ratio', slots: 'table-ratio', width: 140 }
]
}
})
function isDisabled(connectionType: string) {
if (connectionType === '15') return true
return false
}
function getConnection(connectionType: string) {
return dataset.events.filter((item: any) => item.connection_type === connectionType)
}
async function handleSubmit() {
const config = dataset.list.reduce((result: any, item: any) => {
const { ratio, user_event_id } = item
result[item.id] = { ratio, user_event_id }
return result
}, {})
await updateGenerateDataRule({ itinerary_id: props.data.id, config: JSON.stringify(config) })
ElMessage.success('保存成功')
emit('update:modelValue', false)
}
</script>
<template>
<el-dialog title="旅程数据规则" width="900" @update:modelValue="(value) => $emit('update:modelValue', value)">
<AppList v-bind="listOptions" ref="appList">
<template #table-event="{ row }">
<el-select v-model="row.user_event_id" :disabled="isDisabled(row.connection_type)">
<el-option v-for="item in getConnection(row.connection_type)" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
</template>
<template #table-ratio="{ row }">
<div class="table-ratio">
<el-input-number v-model="row.ratio" :controls="false" :max="100" :min="0" :disabled="isDisabled(row.connection_type)"></el-input-number>%
</div>
</template>
</AppList>
<template #footer>
<el-row justify="center">
<el-button plain auto-insert-space @click="$emit('update:modelValue', false)">关闭</el-button>
<el-button type="primary" auto-insert-space @click="handleSubmit">保存</el-button>
</el-row>
</template>
</el-dialog>
</template>
<style lang="scss">
.table-ratio {
display: flex;
align-items: center;
gap: 5px;
.el-input__inner {
text-align: center;
}
}
</style>
......@@ -9,6 +9,7 @@ import { getNameByValue, tripTemplateTypeList } from '@/utils/dictionary'
const FormDialog = defineAsyncComponent(() => import('../components/FormDialog.vue'))
const ViewDialog = defineAsyncComponent(() => import('../components/ViewDialog.vue'))
const BindConnection = defineAsyncComponent(() => import('../components/BindConnection.vue'))
const GenerateRule = defineAsyncComponent(() => import('../components/GenerateRule.vue'))
const statusList = useMapStore().getMapValuesByKey('system_status')
......@@ -53,7 +54,7 @@ const listOptions = computed(() => {
},
{ label: '更新人', prop: 'updated_operator.real_name' },
{ label: '更新时间', prop: 'updated_time' },
{ label: '操作', slots: 'table-x', width: 300 }
{ label: '操作', slots: 'table-x', width: 360 }
]
}
})
......@@ -95,6 +96,12 @@ function handleConfig(row: TripTemplate) {
configVisible = true
}
}
let ruleVisible = $ref(true)
function handleRule(row: TripTemplate) {
currentRow = row
ruleVisible = true
}
</script>
<template>
......@@ -110,6 +117,7 @@ function handleConfig(row: TripTemplate) {
<el-button type="primary" plain @click="handleConfig(row)">配置</el-button>
<el-button type="primary" plain @click="handleView(row)">查看</el-button>
<el-button type="primary" plain @click="handleUpdate(row)">编辑</el-button>
<el-button type="primary" plain @click="handleRule(row)">旅程数据规则</el-button>
</template>
</AppList>
</AppCard>
......@@ -119,4 +127,6 @@ function handleConfig(row: TripTemplate) {
<ViewDialog v-model="viewVisible" :data="currentRow" v-if="viewVisible && currentRow"></ViewDialog>
<!-- 配置 -->
<BindConnection v-model="configVisible" :data="currentRow" v-if="configVisible && currentRow"></BindConnection>
<!-- 旅程数据规则 -->
<GenerateRule v-model="ruleVisible" :data="currentRow" v-if="ruleVisible && currentRow"></GenerateRule>
</template>
......@@ -12,6 +12,7 @@ const UpdateDialog = defineAsyncComponent(() => import('../components/UpdateDial
const UploadEventsDialog = defineAsyncComponent(() => import('../components/UploadEventsDialog.vue'))
const UploadUserDialog = defineAsyncComponent(() => import('../components/UploadUserDialog.vue'))
const ViewProgressDialog = defineAsyncComponent(() => import('../components/ViewProgressDialog.vue'))
const ViewGenerateEventData = defineAsyncComponent(() => import('@/components/ViewGenerateEventData.vue'))
const router = useRouter()
......@@ -117,7 +118,7 @@ const handleRemove = function (row: { id: string; have_event: boolean }) {
}
}
const handleRemoves = function (isAll?: boolean) {
const ids = multipleSelection.map(item => item.id).join(',')
const ids = multipleSelection.map((item) => item.id).join(',')
if (isAll) {
ElMessageBox.confirm('确定要删除全部用户数据吗?', '提示', {
confirmButtonText: '确认',
......@@ -202,6 +203,8 @@ const downloadMember = function (isAll?: boolean) {
window.open(`/api/lab/v1/experiment/member/download?experiment_id=${route.query.experiment_id}&ids=${ids}`)
}
}
const generateEventVisible = ref(false)
</script>
<template>
......@@ -210,12 +213,7 @@ const downloadMember = function (isAll?: boolean) {
<template #header-buttons>
<el-row justify="space-between">
<el-space>
<el-button
v-if="!userStore.status.status"
type="primary"
:icon="Plus"
@click="handleAdd"
v-permission="'v1-experiment-member-create'"
<el-button v-if="!userStore.status.status" type="primary" :icon="Plus" @click="handleAdd" v-permission="'v1-experiment-member-create'"
>新建</el-button
>
<el-dropdown v-permission="'v1-experiment-member-download'">
......@@ -223,9 +221,7 @@ const downloadMember = function (isAll?: boolean) {
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="downloadMember(true)">全部用户数据</el-dropdown-item>
<el-dropdown-item :disabled="!multipleSelection.length" @click="downloadMember(false)"
>勾选用户数据</el-dropdown-item
>
<el-dropdown-item :disabled="!multipleSelection.length" @click="downloadMember(false)">勾选用户数据</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
......@@ -239,9 +235,7 @@ const downloadMember = function (isAll?: boolean) {
</el-dropdown-menu>
</template>
</el-dropdown>
<el-button type="primary" @click="progressVisible = true" v-permission="'v1-experiment-member-tasks'"
>数据导入进度</el-button
>
<el-button type="primary" @click="progressVisible = true" v-permission="'v1-experiment-member-tasks'">数据导入进度</el-button>
<!-- <el-button type="danger" plain :icon="Delete" :disabled="!multipleSelection.length" @click="handleRemoves()" v-permission="'v1-experiment-member-delete'">删除</el-button> -->
<!-- v-permission="'v1-experiment-member-delete'" -->
<el-dropdown>
......@@ -249,25 +243,22 @@ const downloadMember = function (isAll?: boolean) {
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="handleRemoves(true)">删除全部用户</el-dropdown-item>
<el-dropdown-item :disabled="!multipleSelection.length" @click="handleRemoves(false)"
>删除勾选用户</el-dropdown-item
>
<el-dropdown-item :disabled="!multipleSelection.length" @click="handleRemoves(false)">删除勾选用户</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</el-space>
<el-space>
<router-link to="/analyze/user"><el-button type="primary">用户分析</el-button></router-link>
<el-button type="primary" @click="generateEventVisible = true">用户事件数据</el-button>
</el-space>
</el-row>
</template>
<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)" v-permission="'v1-experiment-member-update'"
>编辑</el-button
>
<el-button type="primary" plain @click="handleRemove(row)" v-permission="'v1-experiment-member-delete'"
>删除</el-button
>
<el-button type="primary" plain @click="handleEdit(row)" v-permission="'v1-experiment-member-update'">编辑</el-button>
<el-button type="primary" plain @click="handleRemove(row)" v-permission="'v1-experiment-member-delete'">删除</el-button>
<el-button type="primary" plain @click="goPage(row)">事件</el-button>
</template>
</AppList>
......@@ -280,4 +271,6 @@ const downloadMember = function (isAll?: boolean) {
<UpdateDialog v-if="updateVisible" :data="currentRow" v-model="updateVisible" @update="handleRefresh"></UpdateDialog>
<!-- 查看上传 -->
<ViewProgressDialog v-if="progressVisible" v-model="progressVisible"></ViewProgressDialog>
<!-- 用户事件数据 -->
<ViewGenerateEventData v-model="generateEventVisible" v-if="generateEventVisible"></ViewGenerateEventData>
</template>
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论