加活动分组
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
import request from '@/utils/request';
|
||||
|
||||
/**
|
||||
* 根据活动id查询分组数据统计
|
||||
* @param id 活动id
|
||||
*/
|
||||
export async function getGroupsStatistics(activityId) {
|
||||
const res = await request.get('/sylive/groupsStatistics/' + activityId);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取漏头数据
|
||||
* @param params 查询条件
|
||||
*/
|
||||
export async function getGroupsStatisticsFunnel(params) {
|
||||
const res = await request.get('/sylive/groupsStatistics/funnel', {
|
||||
params
|
||||
});
|
||||
if (res.data.code === 0) {
|
||||
return res.data.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取分级数据
|
||||
* @param params 查询条件
|
||||
*/
|
||||
export async function getGroupsStatisticsLevel(params) {
|
||||
const res = await request.get('/sylive/groupsStatistics/level', {
|
||||
params
|
||||
});
|
||||
if (res.data.code === 0) {
|
||||
return res.data.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取门店数据
|
||||
* @param params 查询条件
|
||||
*/
|
||||
export async function getGroupsStatisticsBiz(params) {
|
||||
const res = await request.get('/sylive/groupsStatistics/biz', {
|
||||
params
|
||||
});
|
||||
if (res.data.code === 0) {
|
||||
return res.data.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取顾问数据
|
||||
* @param params 查询条件
|
||||
*/
|
||||
export async function getGroupsStatisticsConsultant(params) {
|
||||
const res = await request.get('/sylive/groupsStatistics/consultant', {
|
||||
params
|
||||
});
|
||||
if (res.data.code === 0) {
|
||||
return res.data.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取观看下单统计折线图数据
|
||||
* @param params 查询条件
|
||||
*/
|
||||
export async function getGroupsStatisticsWatchOrder(params) {
|
||||
const res = await request.get('/sylive/groupsStatistics/stacked_watchOrder', {
|
||||
params
|
||||
});
|
||||
if (res.data.code === 0) {
|
||||
return res.data.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
import request from '@/utils/request';
|
||||
|
||||
/**
|
||||
* 分页查询用户
|
||||
* @param params 查询条件
|
||||
*/
|
||||
export async function pageGroupsUser(params) {
|
||||
const res = await request.get('/sylive/groupsUser/page', {
|
||||
params
|
||||
});
|
||||
if (res.data.code === 0) {
|
||||
return res.data.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询用户列表
|
||||
* @param params 查询条件
|
||||
*/
|
||||
export async function listGroupsUser(params) {
|
||||
const res = await request.get('/sylive/groupsUser', {
|
||||
params
|
||||
});
|
||||
if (res.data.code === 0 && res.data.data) {
|
||||
return res.data.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据id查询用户
|
||||
* @param id 用户id
|
||||
*/
|
||||
export async function getGroupsUser(id) {
|
||||
const res = await request.get('/sylive/groupsUser/' + id);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加用户
|
||||
* @param data 用户信息
|
||||
*/
|
||||
export async function addGroupsUser(data) {
|
||||
const res = await request.post('/sylive/groupsUser', data);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改用户
|
||||
* @param data 用户信息
|
||||
*/
|
||||
export async function updateGroupsUser(data) {
|
||||
const res = await request.put('/sylive/groupsUser', data);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除用户
|
||||
* @param id 用户id
|
||||
*/
|
||||
export async function removeGroupsUser(id) {
|
||||
const res = await request.delete('/sylive/groupsUser/' + id);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除用户
|
||||
* @param data 用户id集合
|
||||
*/
|
||||
export async function removeGroupsUsers(data) {
|
||||
const res = await request.delete('/sylive/groupsUser/batch', {
|
||||
data
|
||||
});
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改用户状态
|
||||
* @param groupsUserId 用户id
|
||||
* @param status 状态
|
||||
*/
|
||||
export async function updateGroupsUserStatus(groupsUserId, status) {
|
||||
const res = await request.put('/sylive/groupsUser/status', {
|
||||
groupsUserId,
|
||||
status
|
||||
});
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置用户密码
|
||||
* @param userId 用户id
|
||||
* @param password 密码
|
||||
* @returns {Promise<string>}
|
||||
*/
|
||||
export async function updateGroupsUserPassword(userId, password = '123456') {
|
||||
const res = await request.put('/sylive/groupsUser/password', {
|
||||
userId,
|
||||
password
|
||||
});
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 导入用户
|
||||
* @param file excel文件
|
||||
*/
|
||||
export async function importGroupsUser(file) {
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
const res = await request.post('/sylive/groupsUser/import', formData);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查用户是否存在
|
||||
* @param field 检查的字段
|
||||
* @param value 字段的值
|
||||
* @param id 修改时的id
|
||||
*/
|
||||
export async function checkExistence(field, value, id) {
|
||||
const res = await request.get('/sylive/groupsUser/existence', {
|
||||
params: { field, value, id }
|
||||
});
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
import request from '@/utils/request';
|
||||
|
||||
/**
|
||||
* 分页查询分组
|
||||
* @param params 查询条件
|
||||
*/
|
||||
export async function pageGroups(params) {
|
||||
const res = await request.get('/sylive/groups/page', {
|
||||
params
|
||||
});
|
||||
if (res.data.code === 0) {
|
||||
return res.data.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询分组列表
|
||||
* @param params 查询条件
|
||||
*/
|
||||
export async function listGroups(params) {
|
||||
const res = await request.get('/sylive/groups', {
|
||||
params
|
||||
});
|
||||
if (res.data.code === 0) {
|
||||
return res.data.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询上级分组列表
|
||||
* @param params 查询条件
|
||||
*/
|
||||
export async function listGroupsParent(params) {
|
||||
const res = await request.get('/sylive/groups/parent', {
|
||||
params
|
||||
});
|
||||
if (res.data.code === 0) {
|
||||
return res.data.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加分组
|
||||
* @param data 分组信息
|
||||
*/
|
||||
export async function addGroups(data) {
|
||||
const res = await request.post('/sylive/groups', data);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改分组
|
||||
* @param data 分组信息
|
||||
*/
|
||||
export async function updateGroups(data) {
|
||||
const res = await request.put('/sylive/groups', data);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除分组
|
||||
* @param id 分组id
|
||||
*/
|
||||
export async function removeGroups(id) {
|
||||
const res = await request.delete('/sylive/groups/' + id);
|
||||
if (res.data.code === 0) {
|
||||
return res.data.message;
|
||||
}
|
||||
return Promise.reject(new Error(res.data.message));
|
||||
}
|
||||
@@ -19,9 +19,7 @@ export async function pageTeamUser(params) {
|
||||
* @param params 查询条件
|
||||
*/
|
||||
export async function listTeamUser(params) {
|
||||
const res = await request.get('/sylive/teamUser', {
|
||||
params
|
||||
});
|
||||
const res = await request.post('/sylive/teamUser/list', params);
|
||||
if (res.data.code === 0 && res.data.data) {
|
||||
return res.data.data;
|
||||
}
|
||||
|
||||
@@ -19,9 +19,7 @@ export async function pageUsers(params) {
|
||||
* @param params 查询条件
|
||||
*/
|
||||
export async function listUsers(params) {
|
||||
const res = await request.get('/sylive/user', {
|
||||
params
|
||||
});
|
||||
const res = await request.post('/sylive/user/list', params);
|
||||
if (res.data.code === 0 && res.data.data) {
|
||||
return res.data.data;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<!-- 用户编辑弹窗 -->
|
||||
<template>
|
||||
<ele-modal
|
||||
width="750px"
|
||||
width="800px"
|
||||
:visible="visible"
|
||||
:append-to-body="true"
|
||||
:close-on-click-modal="true"
|
||||
@@ -18,34 +18,6 @@
|
||||
placeholder="请输入活动标题"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="所属门店:">
|
||||
<ele-tree-select
|
||||
:data="organizationList"
|
||||
label-key="organizationName"
|
||||
value-key="organizationId"
|
||||
v-model="form.bizIds"
|
||||
:multiple="true"
|
||||
:clearable="true"
|
||||
placeholder="请选择所属门店"
|
||||
:disabled="false"
|
||||
:default-expand-all="true"
|
||||
:check-strictly="false"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="所属团队:">
|
||||
<ele-tree-select
|
||||
:data="teamList"
|
||||
label-key="teamName"
|
||||
value-key="teamId"
|
||||
v-model="form.teamIds"
|
||||
:multiple="true"
|
||||
:clearable="true"
|
||||
placeholder="请选择所属团队"
|
||||
:disabled="false"
|
||||
:default-expand-all="true"
|
||||
:check-strictly="false"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="背景图片:" prop="bgImg">
|
||||
<ele-image-upload
|
||||
v-model="form.bgImg"
|
||||
@@ -59,6 +31,30 @@
|
||||
建议尺寸1125X2000,主题内容建议做在顶部0~1700像素区域
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="所属机构:" prop="organizationId">
|
||||
<el-select
|
||||
v-model="form.organizationId"
|
||||
placeholder="请选择所属机构"
|
||||
class="ele-fluid"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in organizationList"
|
||||
:key="item.organizationId"
|
||||
:label="item.organizationName"
|
||||
:value="item.organizationId"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="开始时间:" prop="activityStart">
|
||||
<el-date-picker
|
||||
type="datetime"
|
||||
v-model="form.activityStart"
|
||||
placeholder="请选择活动开始时间"
|
||||
format="yyyy-MM-dd HH:mm:ss"
|
||||
value-format="yyyy-MM-dd HH:mm:ss"
|
||||
class="ele-fluid"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="直播频道:" prop="channelId">
|
||||
<el-input
|
||||
clearable
|
||||
@@ -90,7 +86,7 @@
|
||||
<el-form-item label="收款账户:" prop="mchId">
|
||||
<activity-mch-id-select v-model="form.mchId" />
|
||||
</el-form-item>
|
||||
<el-form-item label="支付方式:">
|
||||
<el-form-item label="支付方式:" v-show="false">
|
||||
<el-select
|
||||
clearable
|
||||
v-model="form.pay.way"
|
||||
@@ -101,7 +97,7 @@
|
||||
<el-option label="经销商支付" :value="2" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="支付价格:" v-show="form.pay.way == 1 ? false : true">
|
||||
<el-form-item label="支付价格:" v-show="false">
|
||||
<el-input
|
||||
clearable
|
||||
:maxlength="30"
|
||||
@@ -109,7 +105,7 @@
|
||||
placeholder="请输入支付价格"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="支付图片:" v-show="form.pay.way == 1 ? false : true">
|
||||
<el-form-item label="支付图片:" v-show="false">
|
||||
<ele-image-upload
|
||||
v-model="form.pay.img"
|
||||
:limit="1"
|
||||
@@ -131,14 +127,6 @@
|
||||
/>
|
||||
<div class="ele-text-secondary">建议尺寸690X330</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="活动简介:" prop="introduction" v-show="false">
|
||||
<el-input
|
||||
v-model="form.introduction"
|
||||
placeholder="请输入活动简介"
|
||||
:rows="3"
|
||||
type="textarea"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="banner:">
|
||||
<ele-image-upload
|
||||
v-model="form.banner"
|
||||
@@ -197,6 +185,85 @@
|
||||
新增分享文案
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item label="活动底部:">
|
||||
<el-table :data="form.bottoms" :border="true" style="width: 100%">
|
||||
<el-table-column label="标题">
|
||||
<template v-slot="{ row }">
|
||||
<el-input v-model="row.title" placeholder="标题" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="类型" align="center">
|
||||
<template v-slot="{ row }">
|
||||
<el-select v-model="row.urlType" class="ele-fluid">
|
||||
<el-option label="链接" value="link" />
|
||||
<el-option label="小程序" value="miniProgram" />
|
||||
</el-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="链接" width="180px" align="center">
|
||||
<template v-slot="{ row }">
|
||||
<el-input
|
||||
v-model="row.url"
|
||||
placeholder="请输入链接"
|
||||
:rows="2"
|
||||
type="textarea"
|
||||
/>
|
||||
<el-input
|
||||
v-if="row.urlType == 'miniProgram'"
|
||||
v-model="row.miniProgramId"
|
||||
placeholder="小程序原始id"
|
||||
style="padding-top: 5px"
|
||||
:rows="2"
|
||||
type="textarea"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="图标" width="120px" align="center">
|
||||
<template v-slot="{ row, $index }">
|
||||
<ele-image-upload
|
||||
v-model="row.icon"
|
||||
:limit="1"
|
||||
:drag="true"
|
||||
:multiple="false"
|
||||
:upload-handler="$index == 0 ? uploadHandler0 : uploadHandler1"
|
||||
@upload="onUpload"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="操作"
|
||||
width="70px"
|
||||
align="center"
|
||||
:resizable="false"
|
||||
>
|
||||
<template v-slot="{ row, $index }">
|
||||
<span class="ele-action">
|
||||
<el-popconfirm
|
||||
title="确定要删除此底部吗?"
|
||||
@confirm="removeBottoms(row, $index)"
|
||||
>
|
||||
<template v-slot:reference>
|
||||
<el-link
|
||||
icon="el-icon-delete"
|
||||
type="danger"
|
||||
:underline="false"
|
||||
>
|
||||
删除
|
||||
</el-link>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-button
|
||||
icon="el-icon-plus"
|
||||
style="width: 100%; margin-top: 15px"
|
||||
@click="addBottoms"
|
||||
>
|
||||
新增活动底部菜单
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item label="客服链接:">
|
||||
<el-input
|
||||
clearable
|
||||
@@ -240,37 +307,39 @@
|
||||
import request from '@/utils/request';
|
||||
import { addActivity, updateActivity } from '@/api/sylive/activity';
|
||||
export default {
|
||||
components: { TinymceEditor, ActivityMchIdSelect, EleImageUpload },
|
||||
components: {
|
||||
TinymceEditor,
|
||||
ActivityMchIdSelect,
|
||||
EleImageUpload
|
||||
},
|
||||
props: {
|
||||
// 弹窗是否打开
|
||||
visible: Boolean,
|
||||
// 修改回显的数据
|
||||
data: Object,
|
||||
// 全部机构
|
||||
organizationList: Array,
|
||||
// 全部团队
|
||||
teamList: Array
|
||||
// 修改回显的数据
|
||||
data: Object
|
||||
},
|
||||
data() {
|
||||
const defaultForm = {
|
||||
activityId: null,
|
||||
bizIds: [],
|
||||
teamIds: [],
|
||||
title: '',
|
||||
channelId: '',
|
||||
dateRange: '',
|
||||
introduction: '',
|
||||
shareTitle: [''],
|
||||
shareImg: [],
|
||||
bgImg: [],
|
||||
channelImg: [],
|
||||
banner: [],
|
||||
sharePhoto: [],
|
||||
organizationId: null,
|
||||
drawCode: '',
|
||||
activityStart: '',
|
||||
mchId: '1604032585',
|
||||
protocolTitle: '',
|
||||
protocol: '',
|
||||
serviceLink: '',
|
||||
bottoms: [],
|
||||
pay: { way: 1, price: '', img: [] }
|
||||
};
|
||||
return {
|
||||
@@ -294,6 +363,20 @@
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
organizationId: [
|
||||
{
|
||||
required: true,
|
||||
message: '请选择所属机构',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
activityStart: [
|
||||
{
|
||||
required: true,
|
||||
message: '请选择活动开始时间',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
bgImg: [
|
||||
{
|
||||
required: true,
|
||||
@@ -472,7 +555,6 @@
|
||||
this.form.sharePhoto.push(item);
|
||||
this.onUpload(item);
|
||||
},
|
||||
/* 上传事件 */
|
||||
shareImgHandler(file) {
|
||||
const item = {
|
||||
file,
|
||||
@@ -494,6 +576,66 @@
|
||||
this.form.shareImg.push(item);
|
||||
this.onUpload(item);
|
||||
},
|
||||
/* 添加 */
|
||||
addBottoms() {
|
||||
if (this.form.bottoms.length >= 2) {
|
||||
this.$message.error('最多添加2个活动底部菜单');
|
||||
return;
|
||||
}
|
||||
this.form.bottoms.push({
|
||||
urlType: 'link',
|
||||
title: '',
|
||||
url: '',
|
||||
miniProgramId: '',
|
||||
icon: []
|
||||
});
|
||||
},
|
||||
/* 删除 */
|
||||
removeBottoms(_row, index) {
|
||||
this.form.bottoms.splice(index, 1);
|
||||
},
|
||||
uploadHandler0(file) {
|
||||
const item = {
|
||||
file,
|
||||
uid: file.uid,
|
||||
name: file.name,
|
||||
progress: 0,
|
||||
status: null
|
||||
};
|
||||
if (!file.type.startsWith('image')) {
|
||||
this.$message.error('只能选择图片');
|
||||
return;
|
||||
}
|
||||
if (file.size / 1024 / 1024 > 2) {
|
||||
this.$message.error('大小不能超过 2MB');
|
||||
return;
|
||||
}
|
||||
item.url = window.URL.createObjectURL(file);
|
||||
// 关键就是这里要自己 push 添加数据而不是靠 v-modal 自动更新
|
||||
this.form.bottoms[0]['icon'].push(item);
|
||||
this.onUpload(item);
|
||||
},
|
||||
uploadHandler1(file) {
|
||||
const item = {
|
||||
file,
|
||||
uid: file.uid,
|
||||
name: file.name,
|
||||
progress: 0,
|
||||
status: null
|
||||
};
|
||||
if (!file.type.startsWith('image')) {
|
||||
this.$message.error('只能选择图片');
|
||||
return;
|
||||
}
|
||||
if (file.size / 1024 / 1024 > 2) {
|
||||
this.$message.error('大小不能超过 2MB');
|
||||
return;
|
||||
}
|
||||
item.url = window.URL.createObjectURL(file);
|
||||
// 关键就是这里要自己 push 添加数据而不是靠 v-modal 自动更新
|
||||
this.form.bottoms[1]['icon'].push(item);
|
||||
this.onUpload(item);
|
||||
},
|
||||
/* 上传 item */
|
||||
onUpload(item) {
|
||||
item.status = 'uploading';
|
||||
@@ -535,7 +677,7 @@
|
||||
this.form.shareTitle.push('');
|
||||
}
|
||||
} else {
|
||||
//this.form.organizationId = this.organizationId;
|
||||
this.form.bottoms = [];
|
||||
this.form.bgImg = [];
|
||||
this.form.shareImg = [];
|
||||
this.isUpdate = false;
|
||||
@@ -550,7 +692,7 @@
|
||||
</script>
|
||||
<style>
|
||||
.ele-image-upload-list .ele-image-upload-item {
|
||||
margin-top: 5px;
|
||||
margin-bottom: 5px;
|
||||
margin-top: 2px;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -53,7 +53,10 @@
|
||||
<i class="el-icon-arrow-down"></i>
|
||||
</el-link>
|
||||
<template v-slot:dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-menu v-if="row.groups == 1">
|
||||
<el-dropdown-item command="gro">分组数据统计</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
<el-dropdown-menu v-else>
|
||||
<el-dropdown-item command="org">机构数据统计</el-dropdown-item>
|
||||
<el-dropdown-item command="team">团队数据统计</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
@@ -84,6 +87,7 @@
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item command="activity">修改活动</el-dropdown-item>
|
||||
<el-dropdown-item command="goods">修改商品</el-dropdown-item>
|
||||
<el-dropdown-item command="groups">修改分组</el-dropdown-item>
|
||||
<!--
|
||||
<el-dropdown-item command="item">修改权益商品</el-dropdown-item>
|
||||
<el-dropdown-item command="coupon">修改券</el-dropdown-item>
|
||||
@@ -110,7 +114,6 @@
|
||||
:data="current"
|
||||
:visible.sync="showEdit"
|
||||
:organization-list="organizationList"
|
||||
:team-list="teamList"
|
||||
@done="reload"
|
||||
/>
|
||||
<!-- 编辑商品弹窗 -->
|
||||
@@ -142,8 +145,7 @@
|
||||
removeActivitys,
|
||||
updateActivityStatus
|
||||
} from '@/api/sylive/activity';
|
||||
import { listOrganizations } from '@/api/sylive/organization';
|
||||
import { listTeams } from '@/api/sylive/team';
|
||||
import { listOrganizationParent } from '@/api/sylive/organization';
|
||||
|
||||
export default {
|
||||
name: 'syliveActivity',
|
||||
@@ -156,12 +158,8 @@
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 加载状态
|
||||
loading: true,
|
||||
// 门店数据
|
||||
organizationList: [],
|
||||
// 团队数据
|
||||
teamList: [],
|
||||
// 表格列配置
|
||||
columns: [
|
||||
{
|
||||
@@ -261,50 +259,29 @@
|
||||
this.showEditCoupon = true;
|
||||
} else if (command === 'goods') {
|
||||
this.$router.replace('/sylive/goods?id=' + row.activityId);
|
||||
} else if (command === 'groups') {
|
||||
this.$router.replace('/sylive/groups?id=' + row.activityId);
|
||||
}
|
||||
},
|
||||
/* 打开数据统计页 */
|
||||
dropStatistics(command, row) {
|
||||
var url = '';
|
||||
if (command === 'org') {
|
||||
if (command === 'gro') {
|
||||
url = '/sylive/groups-statistics?id=' + row.activityId;
|
||||
} else if (command === 'org') {
|
||||
url = '/sylive/activity/statistics?id=' + row.activityId;
|
||||
this.$router.replace(url);
|
||||
} else if (command === 'team') {
|
||||
url = '/sylive/activity/statistics-team?id=' + row.activityId;
|
||||
this.$router.replace(url);
|
||||
}
|
||||
this.$router.replace(url);
|
||||
},
|
||||
/* 查询机构 */
|
||||
organizationQuery() {
|
||||
this.loading = true;
|
||||
listOrganizations({ unOrganizationType: 4 })
|
||||
listOrganizationParent({ parentId: 0 })
|
||||
.then((list) => {
|
||||
this.loading = false;
|
||||
this.organizationList = this.$util.toTreeData({
|
||||
data: list,
|
||||
idField: 'organizationId',
|
||||
parentIdField: 'parentId'
|
||||
});
|
||||
this.organizationList = list;
|
||||
})
|
||||
.catch((e) => {
|
||||
this.loading = false;
|
||||
this.$message.error(e.message);
|
||||
});
|
||||
},
|
||||
/* 查询团队 */
|
||||
teamQuery() {
|
||||
this.loading = true;
|
||||
listTeams({ unTeamType: 3 })
|
||||
.then((list) => {
|
||||
this.loading = false;
|
||||
this.teamList = this.$util.toTreeData({
|
||||
data: list,
|
||||
idField: 'teamId',
|
||||
parentIdField: 'parentId'
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
this.loading = false;
|
||||
this.$message.error(e.message);
|
||||
});
|
||||
},
|
||||
@@ -312,7 +289,6 @@
|
||||
datasource({ page, limit, where, order }) {
|
||||
if (page == 1) {
|
||||
this.organizationQuery();
|
||||
this.teamQuery();
|
||||
}
|
||||
return pageActivity({ ...where, ...order, page, limit });
|
||||
},
|
||||
|
||||
@@ -0,0 +1,179 @@
|
||||
<template>
|
||||
<el-card shadow="never">
|
||||
<!-- 数据表格 -->
|
||||
<ele-pro-table
|
||||
ref="table"
|
||||
title="门店统计"
|
||||
:columns="columns"
|
||||
:datasource="datasource"
|
||||
size="mini"
|
||||
>
|
||||
<template v-slot:toolkit>
|
||||
<div class="list-tool-item">
|
||||
<el-select
|
||||
v-model="day"
|
||||
clearable
|
||||
class="ele-fluid"
|
||||
@input="updateValue"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in data.days"
|
||||
:key="item.value"
|
||||
:value="item.value"
|
||||
:label="item.name"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="list-tool-divider">
|
||||
<el-divider direction="vertical" />
|
||||
</div>
|
||||
<div class="list-tool-item">
|
||||
<el-select
|
||||
v-model="itemId"
|
||||
clearable
|
||||
class="ele-fluid"
|
||||
@input="updateValue"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in data.goods"
|
||||
:key="item.value"
|
||||
:value="item.value"
|
||||
:label="item.name"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="list-tool-divider">
|
||||
<el-divider direction="vertical" />
|
||||
</div>
|
||||
</template>
|
||||
</ele-pro-table>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getGroupsStatisticsBiz } from '@/api/sylive/groups-statistics';
|
||||
|
||||
export default {
|
||||
props: { data: Object },
|
||||
data() {
|
||||
return {
|
||||
activityId: null,
|
||||
// 表格选中数据
|
||||
day: '',
|
||||
itemId: '',
|
||||
selection: [],
|
||||
// 表格列配置
|
||||
columns: [
|
||||
{
|
||||
prop: 'bizName',
|
||||
label: '门店名称',
|
||||
align: 'center',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 110
|
||||
},
|
||||
{
|
||||
prop: 'consultant',
|
||||
label: '参与顾问数',
|
||||
align: 'center',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 100
|
||||
},
|
||||
{
|
||||
prop: 'allConsultant',
|
||||
label: '全部顾问数',
|
||||
align: 'center',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 100
|
||||
},
|
||||
{
|
||||
prop: 'browse',
|
||||
label: '浏览数(人)',
|
||||
align: 'center',
|
||||
sortable: 'custom',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 120
|
||||
},
|
||||
{
|
||||
prop: 'subscribe',
|
||||
label: '预约数(人)',
|
||||
align: 'center',
|
||||
sortable: 'custom',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 120
|
||||
},
|
||||
{
|
||||
prop: 'watch',
|
||||
label: '观看数(人)',
|
||||
align: 'center',
|
||||
sortable: 'custom',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 120
|
||||
},
|
||||
{
|
||||
prop: 'order',
|
||||
label: '订单数(单)',
|
||||
align: 'center',
|
||||
sortable: 'custom',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 120
|
||||
},
|
||||
{
|
||||
prop: 'livePV',
|
||||
label: '观看数(人次)',
|
||||
align: 'center',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 100
|
||||
},
|
||||
{
|
||||
prop: 'watchDuration',
|
||||
label: '人均观看(分)',
|
||||
align: 'center',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 100
|
||||
}
|
||||
]
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
/* 表格数据源 */
|
||||
datasource({ page, limit, order }) {
|
||||
return getGroupsStatisticsBiz({
|
||||
...order,
|
||||
page,
|
||||
limit,
|
||||
activityId: this.activityId,
|
||||
day: this.day,
|
||||
itemId: this.itemId
|
||||
});
|
||||
},
|
||||
/* 更新选中数据 */
|
||||
updateValue() {
|
||||
this.$refs.table.reload({ page: 1 });
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
$route: {
|
||||
handler(route) {
|
||||
const { path } = route;
|
||||
if (path !== '/sylive/groups-statistics') {
|
||||
return;
|
||||
}
|
||||
const activityId = this.$route.query.id;
|
||||
if (!activityId || activityId == this.activityId) {
|
||||
return;
|
||||
}
|
||||
this.activityId = activityId;
|
||||
if (this.$refs.table) {
|
||||
this.$refs.table.reload({ page: 1 });
|
||||
}
|
||||
},
|
||||
immediate: true
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.list-tool-divider {
|
||||
padding: 0 12px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,163 @@
|
||||
<template>
|
||||
<el-card shadow="never">
|
||||
<!-- 数据表格 -->
|
||||
<ele-pro-table
|
||||
ref="table"
|
||||
title="顾问统计"
|
||||
:columns="columns"
|
||||
:datasource="datasource"
|
||||
size="mini"
|
||||
>
|
||||
<template v-slot:toolkit>
|
||||
<div class="list-tool-item">
|
||||
<el-select
|
||||
v-model="day"
|
||||
clearable
|
||||
class="ele-fluid"
|
||||
@input="updateValue"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in data.days"
|
||||
:key="item.value"
|
||||
:value="item.value"
|
||||
:label="item.name"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="list-tool-divider">
|
||||
<el-divider direction="vertical" />
|
||||
</div>
|
||||
<div class="list-tool-item">
|
||||
<el-select
|
||||
v-model="itemId"
|
||||
clearable
|
||||
class="ele-fluid"
|
||||
@input="updateValue"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in data.goods"
|
||||
:key="item.value"
|
||||
:value="item.value"
|
||||
:label="item.name"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="list-tool-divider">
|
||||
<el-divider direction="vertical" />
|
||||
</div>
|
||||
</template>
|
||||
</ele-pro-table>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getGroupsStatisticsConsultant } from '@/api/sylive/groups-statistics';
|
||||
|
||||
export default {
|
||||
props: { data: Object },
|
||||
data() {
|
||||
return {
|
||||
activityId: null,
|
||||
day: '',
|
||||
itemId: '',
|
||||
// 表格列配置
|
||||
columns: [
|
||||
{
|
||||
prop: 'consultantName',
|
||||
label: '顾问名称',
|
||||
align: 'center',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 150
|
||||
},
|
||||
{
|
||||
prop: 'browse',
|
||||
label: '浏览数(人)',
|
||||
align: 'center',
|
||||
sortable: 'custom',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 120
|
||||
},
|
||||
{
|
||||
prop: 'subscribe',
|
||||
label: '预约数(人)',
|
||||
align: 'center',
|
||||
sortable: 'custom',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 120
|
||||
},
|
||||
{
|
||||
prop: 'watch',
|
||||
label: '观看数(人)',
|
||||
align: 'center',
|
||||
sortable: 'custom',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 120
|
||||
},
|
||||
{
|
||||
prop: 'order',
|
||||
label: '订单数(单)',
|
||||
align: 'center',
|
||||
sortable: 'custom',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 120
|
||||
},
|
||||
{
|
||||
prop: 'livePV',
|
||||
label: '观看数(人次)',
|
||||
align: 'center',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 100
|
||||
},
|
||||
{
|
||||
prop: 'watchDuration',
|
||||
label: '人均观看(分)',
|
||||
align: 'center',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 100
|
||||
}
|
||||
]
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
/* 表格数据源 */
|
||||
datasource({ page, limit, order }) {
|
||||
return getGroupsStatisticsConsultant({
|
||||
...order,
|
||||
page,
|
||||
limit,
|
||||
activityId: this.activityId,
|
||||
day: this.day,
|
||||
itemId: this.itemId
|
||||
});
|
||||
},
|
||||
/* 更新选中数据 */
|
||||
updateValue() {
|
||||
this.$refs.table.reload({ page: 1 });
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
$route: {
|
||||
handler(route) {
|
||||
const { path } = route;
|
||||
if (path !== '/sylive/groups-statistics') {
|
||||
return;
|
||||
}
|
||||
const activityId = this.$route.query.id;
|
||||
if (!activityId || activityId == this.activityId) {
|
||||
return;
|
||||
}
|
||||
this.activityId = activityId;
|
||||
if (this.$refs.table) {
|
||||
this.$refs.table.reload({ page: 1 });
|
||||
}
|
||||
},
|
||||
immediate: true
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.list-tool-divider {
|
||||
padding: 0 12px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,317 @@
|
||||
<template>
|
||||
<el-card shadow="never">
|
||||
<!-- 数据表格 -->
|
||||
<ele-pro-table
|
||||
ref="table"
|
||||
:title="title"
|
||||
:columns="columns"
|
||||
:datasource="datasource"
|
||||
:need-page="false"
|
||||
size="mini"
|
||||
>
|
||||
<template v-slot:toolkit>
|
||||
<div class="list-tool-item">
|
||||
<el-select
|
||||
v-model="day"
|
||||
clearable
|
||||
class="ele-fluid"
|
||||
@input="updateValue"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in data.days"
|
||||
:key="item.value"
|
||||
:value="item.value"
|
||||
:label="item.name"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="list-tool-divider">
|
||||
<el-divider direction="vertical" />
|
||||
</div>
|
||||
<div class="list-tool-item">
|
||||
<el-select
|
||||
v-model="itemId"
|
||||
clearable
|
||||
class="ele-fluid"
|
||||
@input="updateValue"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in data.goods"
|
||||
:key="item.value"
|
||||
:value="item.value"
|
||||
:label="item.name"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="list-tool-divider">
|
||||
<el-divider direction="vertical" />
|
||||
</div>
|
||||
</template>
|
||||
</ele-pro-table>
|
||||
<div
|
||||
style="position: relative; margin-top: 40px"
|
||||
v-if="areaChartOption.legend.data.length > 0"
|
||||
>
|
||||
<div
|
||||
style="
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 40px;
|
||||
width: 200px;
|
||||
z-index: 1;
|
||||
"
|
||||
>
|
||||
<el-select
|
||||
class="ele-fluid"
|
||||
v-model="tempkpi"
|
||||
placeholder="请选择"
|
||||
@change="changeKpi($event)"
|
||||
>
|
||||
<el-option
|
||||
v-for="(option, index) in kpioption"
|
||||
:key="index"
|
||||
:value="option.kpi"
|
||||
:label="option.title"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
<v-chart
|
||||
ref="areaChart"
|
||||
style="width: 100%; height: 500px"
|
||||
:option="areaChartOption"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getGroupsStatisticsLevel } from '@/api/sylive/groups-statistics';
|
||||
import { getStatisticsStackedArea } from '@/api/sylive/activity';
|
||||
import { use } from 'echarts/core';
|
||||
import { CanvasRenderer } from 'echarts/renderers';
|
||||
import { LineChart } from 'echarts/charts';
|
||||
import {
|
||||
LegendComponent,
|
||||
GridComponent,
|
||||
ToolboxComponent,
|
||||
TooltipComponent
|
||||
} from 'echarts/components';
|
||||
import VChart from 'vue-echarts';
|
||||
import 'echarts-wordcloud';
|
||||
import { echartsMixin } from '@/utils/echarts-mixin';
|
||||
use([
|
||||
CanvasRenderer,
|
||||
GridComponent,
|
||||
TooltipComponent,
|
||||
LegendComponent,
|
||||
ToolboxComponent,
|
||||
LineChart
|
||||
]);
|
||||
|
||||
export default {
|
||||
components: { VChart },
|
||||
mixins: [echartsMixin(['areaChart'])],
|
||||
props: { data: Object, level: Number, title: String },
|
||||
data() {
|
||||
return {
|
||||
activityId: null,
|
||||
// 表格选中数据
|
||||
day: '',
|
||||
itemId: '',
|
||||
selection: [],
|
||||
// 表格列配置
|
||||
columns: [
|
||||
{
|
||||
prop: 'groupsName',
|
||||
label: '分级名称',
|
||||
align: 'center',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 110
|
||||
},
|
||||
{
|
||||
prop: 'biz',
|
||||
label: '参与门店数',
|
||||
align: 'center',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 110
|
||||
},
|
||||
{
|
||||
prop: 'consultant',
|
||||
label: '参与顾问数',
|
||||
align: 'center',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 100
|
||||
},
|
||||
{
|
||||
prop: 'allConsultant',
|
||||
label: '全部顾问数',
|
||||
align: 'center',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 100
|
||||
},
|
||||
{
|
||||
prop: 'browse',
|
||||
label: '浏览数(人)',
|
||||
align: 'center',
|
||||
sortable: 'custom',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 120
|
||||
},
|
||||
{
|
||||
prop: 'subscribe',
|
||||
label: '预约数(人)',
|
||||
align: 'center',
|
||||
sortable: 'custom',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 120
|
||||
},
|
||||
{
|
||||
prop: 'watch',
|
||||
label: '观看数(人)',
|
||||
align: 'center',
|
||||
sortable: 'custom',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 120
|
||||
},
|
||||
{
|
||||
prop: 'order',
|
||||
label: '订单数(单)',
|
||||
align: 'center',
|
||||
sortable: 'custom',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 120
|
||||
},
|
||||
{
|
||||
prop: 'livePV',
|
||||
label: '观看数(人次)',
|
||||
align: 'center',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 100
|
||||
},
|
||||
{
|
||||
prop: 'watchDuration',
|
||||
label: '人均观看(分)',
|
||||
align: 'center',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 100
|
||||
}
|
||||
],
|
||||
kpi: 'browse',
|
||||
tempkpi: 'browse',
|
||||
kpioption: [
|
||||
{
|
||||
kpi: 'browse',
|
||||
title: '浏览数'
|
||||
},
|
||||
{
|
||||
kpi: 'subscribe',
|
||||
title: '预约数'
|
||||
}
|
||||
],
|
||||
areaChartOption: {
|
||||
legend: {
|
||||
data: []
|
||||
}
|
||||
} //折线图
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
/* 表格数据源 */
|
||||
datasource({ page, limit, order }) {
|
||||
return getGroupsStatisticsLevel({
|
||||
...order,
|
||||
page,
|
||||
limit,
|
||||
activityId: this.activityId,
|
||||
day: this.day,
|
||||
itemId: this.itemId,
|
||||
level: this.level
|
||||
});
|
||||
},
|
||||
|
||||
//切换区域统计折线图
|
||||
changeKpi(value) {
|
||||
if (value != this.kpi) {
|
||||
this.kpi = value;
|
||||
this.getStatisticsStackedArea();
|
||||
}
|
||||
},
|
||||
|
||||
//区域统计折线图
|
||||
getStatisticsStackedArea() {
|
||||
if (this.activityId) {
|
||||
//暂时屏蔽
|
||||
return;
|
||||
}
|
||||
this.areaChartOption = { legend: { data: [] } };
|
||||
getStatisticsStackedArea({
|
||||
activityId: this.activityId,
|
||||
kpi: this.kpi
|
||||
}).then((res) => {
|
||||
this.areaChartOption = {
|
||||
tooltip: {
|
||||
trigger: 'axis'
|
||||
},
|
||||
legend: {
|
||||
x: 'left',
|
||||
padding: [13, 260, 0, 40],
|
||||
data: res.legendData
|
||||
},
|
||||
grid: {
|
||||
left: '3%',
|
||||
right: '4%',
|
||||
top: res.legendData.length < 15 ? '14%' : '17%',
|
||||
bottom: '3%',
|
||||
containLabel: true
|
||||
},
|
||||
toolbox: {
|
||||
feature: {
|
||||
saveAsImage: {}
|
||||
}
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
data: res.xAxisData
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value'
|
||||
},
|
||||
series: res.yAxisSeries
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
/* 更新选中数据 */
|
||||
updateValue() {
|
||||
this.$refs.table.reload({ page: 1 });
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
$route: {
|
||||
handler(route) {
|
||||
const { path } = route;
|
||||
if (path !== '/sylive/groups-statistics') {
|
||||
return;
|
||||
}
|
||||
const activityId = this.$route.query.id;
|
||||
if (!activityId || activityId == this.activityId) {
|
||||
return;
|
||||
}
|
||||
this.activityId = activityId;
|
||||
this.getStatisticsStackedArea();
|
||||
if (this.$refs.table) {
|
||||
this.$refs.table.reload({ page: 1 });
|
||||
}
|
||||
},
|
||||
immediate: true
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.list-tool-divider {
|
||||
padding: 0 12px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,107 @@
|
||||
<template>
|
||||
<el-card shadow="never" v-if="watchOrderOption.legend.data.length > 0">
|
||||
<div>
|
||||
<v-chart
|
||||
ref="watchOrder"
|
||||
style="width: 100%; height: 500px"
|
||||
:option="watchOrderOption"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getGroupsStatisticsWatchOrder } from '@/api/sylive/groups-statistics';
|
||||
import { use } from 'echarts/core';
|
||||
import { CanvasRenderer } from 'echarts/renderers';
|
||||
import { LineChart } from 'echarts/charts';
|
||||
import {
|
||||
LegendComponent,
|
||||
GridComponent,
|
||||
ToolboxComponent,
|
||||
TooltipComponent
|
||||
} from 'echarts/components';
|
||||
import VChart from 'vue-echarts';
|
||||
import 'echarts-wordcloud';
|
||||
import { echartsMixin } from '@/utils/echarts-mixin';
|
||||
use([
|
||||
CanvasRenderer,
|
||||
GridComponent,
|
||||
TooltipComponent,
|
||||
LegendComponent,
|
||||
ToolboxComponent,
|
||||
LineChart
|
||||
]);
|
||||
|
||||
export default {
|
||||
components: { VChart },
|
||||
mixins: [echartsMixin(['watchOrder'])],
|
||||
data() {
|
||||
return {
|
||||
activityId: null,
|
||||
watchOrderOption: {
|
||||
legend: {
|
||||
data: []
|
||||
}
|
||||
} //折线图
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
//区域统计折线图
|
||||
query() {
|
||||
this.watchOrderOption = { legend: { data: [] } };
|
||||
getGroupsStatisticsWatchOrder({
|
||||
activityId: this.activityId
|
||||
}).then((res) => {
|
||||
this.watchOrderOption = {
|
||||
tooltip: {
|
||||
trigger: 'axis'
|
||||
},
|
||||
legend: {
|
||||
padding: [13, 260, 0, 40],
|
||||
data: res.legendData
|
||||
},
|
||||
grid: {
|
||||
left: '3%',
|
||||
right: '4%',
|
||||
top: '10%',
|
||||
bottom: '3%',
|
||||
containLabel: true
|
||||
},
|
||||
toolbox: {
|
||||
feature: {
|
||||
saveAsImage: {}
|
||||
}
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
data: res.xAxisData
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value'
|
||||
},
|
||||
series: res.yAxisSeries
|
||||
};
|
||||
});
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
$route: {
|
||||
handler(route) {
|
||||
const { path } = route;
|
||||
if (path !== '/sylive/groups-statistics') {
|
||||
return;
|
||||
}
|
||||
const activityId = this.$route.query.id;
|
||||
if (!activityId || activityId == this.activityId) {
|
||||
return;
|
||||
}
|
||||
this.activityId = activityId;
|
||||
this.query();
|
||||
},
|
||||
immediate: true
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,404 @@
|
||||
<template>
|
||||
<div class="ele-body ele-body-card" v-loading="loading">
|
||||
<el-row :gutter="15">
|
||||
<el-col
|
||||
v-for="(item, index) in statistics.activityData1.list"
|
||||
:key="index"
|
||||
:style="statistics.activityData1.style"
|
||||
>
|
||||
<el-card class="analysis-chart-card" shadow="never">
|
||||
<template v-slot:header>
|
||||
<div class="ele-cell">
|
||||
<div class="ele-cell-content">{{ item.name }}</div>
|
||||
</div>
|
||||
</template>
|
||||
<div class="analysis-chart-card-num ele-text-heading">
|
||||
{{ item.value }}
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="15">
|
||||
<el-col
|
||||
v-for="(item, index) in statistics.activityData2.list"
|
||||
:key="index"
|
||||
:style="statistics.activityData2.style"
|
||||
>
|
||||
<el-card :class="item.url != '' ? 'el-header_add' : ''" shadow="never">
|
||||
<template v-slot:header>
|
||||
<div class="ele-cell" @click="openPiechart(item.url, item.name)">
|
||||
<div class="ele-cell-content">{{ item.name }}</div>
|
||||
<i class="el-icon-arrow-right" v-if="item.url != ''"></i>
|
||||
</div>
|
||||
</template>
|
||||
<div
|
||||
class="analysis-chart-card-num ele-text-heading"
|
||||
@click="openPiechart(item.url, item.name)"
|
||||
>
|
||||
{{ item.value }}
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="15">
|
||||
<el-col
|
||||
v-bind="styleResponsive ? { lg: 3, md: 8 } : { span: 3 }"
|
||||
style="width: 50%"
|
||||
>
|
||||
<el-card shadow="never" body-style="padding: 0px">
|
||||
<div class="ele-table-tool ranking-order-header">
|
||||
<div class="ele-table-tool-title">
|
||||
<div class="ele-table-tool-title-label">
|
||||
<h6 style="font-size: 15px">
|
||||
{{ preheatingChartOption.title }}
|
||||
</h6>
|
||||
</div>
|
||||
</div>
|
||||
<div class="list-tool-item">
|
||||
<el-select
|
||||
v-model="itemIdPreheating"
|
||||
clearable
|
||||
class="ele-fluid"
|
||||
@input="queryFunnel('left')"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in statistics.tableData.goods"
|
||||
:key="item.value"
|
||||
:value="item.value"
|
||||
:label="item.name"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
style="width: 500px; margin: 0 auto; padding-top: 7px"
|
||||
v-if="preheatingChartOption.title"
|
||||
>
|
||||
<v-chart
|
||||
ref="funnelChart"
|
||||
style="width: 500px; height: 303px"
|
||||
:option="preheatingChartOption.chartOption"
|
||||
/>
|
||||
</div>
|
||||
<ele-empty v-else v-show="true"></ele-empty>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col
|
||||
v-bind="styleResponsive ? { lg: 3, md: 8 } : { span: 3 }"
|
||||
style="width: 50%"
|
||||
>
|
||||
<el-card shadow="never" body-style="padding: 0px">
|
||||
<div class="ele-table-tool ranking-order-header">
|
||||
<div class="ele-table-tool-title">
|
||||
<div class="ele-table-tool-title-label">
|
||||
<h6 style="font-size: 15px">{{ liveChartOption.title }}</h6>
|
||||
</div>
|
||||
</div>
|
||||
<div class="list-tool-item">
|
||||
<el-select
|
||||
v-model="itemIdLive"
|
||||
clearable
|
||||
class="ele-fluid"
|
||||
@input="queryFunnel('right')"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in statistics.tableData.goods"
|
||||
:key="item.value"
|
||||
:value="item.value"
|
||||
:label="item.name"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
style="width: 500px; margin: 0 auto; padding-top: 7px"
|
||||
v-if="liveChartOption.title"
|
||||
>
|
||||
<v-chart
|
||||
ref="funnelChart"
|
||||
style="width: 500px; height: 303px"
|
||||
:option="liveChartOption.chartOption"
|
||||
/>
|
||||
</div>
|
||||
<ele-empty v-else v-show="true"></ele-empty>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<watchOrderLinechart />
|
||||
<level-table
|
||||
v-for="(item, index) in statistics.levelData"
|
||||
:key="index"
|
||||
:data="statistics.tableData"
|
||||
:level="item.value"
|
||||
:title="item.title"
|
||||
/>
|
||||
<biz-table :data="statistics.tableData" />
|
||||
<consultant-table :data="statistics.tableData" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { setPageTabTitle } from '@/utils/page-tab-util';
|
||||
import {
|
||||
getGroupsStatistics,
|
||||
getGroupsStatisticsFunnel
|
||||
} from '@/api/sylive/groups-statistics';
|
||||
const ROUTE_PATH = '/sylive/groups-statistics';
|
||||
import { use } from 'echarts/core';
|
||||
import { CanvasRenderer } from 'echarts/renderers';
|
||||
import { FunnelChart } from 'echarts/charts';
|
||||
import { TooltipComponent } from 'echarts/components';
|
||||
import VChart from 'vue-echarts';
|
||||
import 'echarts-wordcloud';
|
||||
import { echartsMixin } from '@/utils/echarts-mixin';
|
||||
import LevelTable from './components/level-table.vue';
|
||||
import BizTable from './components/biz-table.vue';
|
||||
import ConsultantTable from './components/consultant-table.vue';
|
||||
import watchOrderLinechart from './components/watchOrder-linechart.vue';
|
||||
|
||||
use([CanvasRenderer, TooltipComponent, FunnelChart]);
|
||||
|
||||
export default {
|
||||
name: 'SyliveGroupsStatistics',
|
||||
components: {
|
||||
VChart,
|
||||
LevelTable,
|
||||
BizTable,
|
||||
ConsultantTable,
|
||||
watchOrderLinechart
|
||||
},
|
||||
mixins: [echartsMixin(['funnelChart'])],
|
||||
data() {
|
||||
return {
|
||||
activityId: null,
|
||||
itemIdRanking: '',
|
||||
itemIdPreheating: '',
|
||||
itemIdLive: '',
|
||||
statistics: {
|
||||
activityData1: { list: [], style: '' },
|
||||
activityData2: { list: [], style: '' },
|
||||
levelData: [],
|
||||
tableData: { days: [], goods: [] }
|
||||
},
|
||||
loading: true,
|
||||
browseRank: { area: [], biz: [], consultant: [] },
|
||||
subscribeRank: { area: [], biz: [], consultant: [] },
|
||||
watchRank: { area: [], biz: [], consultant: [] },
|
||||
orderRank: { area: [], biz: [], consultant: [] },
|
||||
// 词云图表配置
|
||||
preheatingChartOption: { title: '', chartOption: {} },
|
||||
liveChartOption: { title: '', chartOption: {} }
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
// 是否开启响应式布局
|
||||
styleResponsive() {
|
||||
return this.$store.state.theme.styleResponsive;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/* 打开饼状图 */
|
||||
openPiechart(url, title) {
|
||||
if (url != '') {
|
||||
this.$router.replace(url + '&title=' + title);
|
||||
}
|
||||
},
|
||||
query() {
|
||||
this.loading = true;
|
||||
getGroupsStatistics(Number(this.activityId))
|
||||
.then((data) => {
|
||||
this.loading = false;
|
||||
this.$util.assignObject(this.statistics, {
|
||||
...data
|
||||
});
|
||||
// 修改页签标题
|
||||
if (this.$route.path === ROUTE_PATH) {
|
||||
setPageTabTitle(data.title + '的分组数据统计');
|
||||
}
|
||||
})
|
||||
.catch((e) => {
|
||||
this.loading = false;
|
||||
this.$message.error(e.message);
|
||||
});
|
||||
},
|
||||
queryFunnel(show) {
|
||||
let itemId = '';
|
||||
if (show == 'left') {
|
||||
itemId = this.itemIdPreheating;
|
||||
} else if (show == 'right') {
|
||||
itemId = this.itemIdLive;
|
||||
}
|
||||
getGroupsStatisticsFunnel({
|
||||
activityId: this.activityId,
|
||||
show: show,
|
||||
itemId: itemId
|
||||
}).then((data) => {
|
||||
//浏览转化漏斗((预热阶段)
|
||||
if (data.funnelPreheating.title) {
|
||||
this.preheatingChartOption.title = data.funnelPreheating.title;
|
||||
this.preheatingChartOption.chartOption = {
|
||||
series: [
|
||||
{
|
||||
name: 'Expected',
|
||||
type: 'funnel',
|
||||
top: '1%',
|
||||
bottom: '5%',
|
||||
left: '2%',
|
||||
width: '72%',
|
||||
label: {
|
||||
position: 'right',
|
||||
formatter: '{b}'
|
||||
},
|
||||
labelLine: {
|
||||
show: false
|
||||
},
|
||||
itemStyle: {
|
||||
opacity: 0.7
|
||||
},
|
||||
data: data.funnelPreheating.expectedData
|
||||
},
|
||||
{
|
||||
name: 'Actual',
|
||||
type: 'funnel',
|
||||
top: '1%',
|
||||
bottom: '5%',
|
||||
left: '7%',
|
||||
width: '62%',
|
||||
maxSize: '62%',
|
||||
label: {
|
||||
position: 'inside',
|
||||
formatter: '{c}',
|
||||
color: '#000'
|
||||
},
|
||||
itemStyle: {
|
||||
opacity: 0.4,
|
||||
borderColor: '#fff',
|
||||
borderWidth: 1
|
||||
},
|
||||
data: data.funnelPreheating.actualData,
|
||||
z: 100
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
//浏览转化漏斗(直播阶段)
|
||||
if (data.funnelLive.title) {
|
||||
this.liveChartOption.title = data.funnelLive.title;
|
||||
this.liveChartOption.chartOption = {
|
||||
series: [
|
||||
{
|
||||
name: 'Expected',
|
||||
type: 'funnel',
|
||||
top: '1%',
|
||||
bottom: '5%',
|
||||
left: '2%',
|
||||
width: '72%',
|
||||
label: {
|
||||
position: 'right',
|
||||
formatter: '{b}'
|
||||
},
|
||||
labelLine: {
|
||||
show: false
|
||||
},
|
||||
itemStyle: {
|
||||
opacity: 0.7
|
||||
},
|
||||
data: data.funnelLive.expectedData
|
||||
},
|
||||
{
|
||||
name: 'Actual',
|
||||
type: 'funnel',
|
||||
top: '1%',
|
||||
bottom: '5%',
|
||||
left: '7%',
|
||||
width: '62%',
|
||||
maxSize: '62%',
|
||||
label: {
|
||||
position: 'inside',
|
||||
formatter: '{c}',
|
||||
color: '#000'
|
||||
},
|
||||
itemStyle: {
|
||||
opacity: 0.4,
|
||||
borderColor: '#fff',
|
||||
borderWidth: 1
|
||||
},
|
||||
data: data.funnelLive.actualData,
|
||||
z: 100
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
$route: {
|
||||
handler(route) {
|
||||
const { path } = route;
|
||||
if (path !== ROUTE_PATH) {
|
||||
return;
|
||||
}
|
||||
const activityId = this.$route.query.id;
|
||||
if (!activityId || activityId == this.activityId) {
|
||||
return;
|
||||
}
|
||||
this.activityId = activityId;
|
||||
this.query();
|
||||
this.queryFunnel();
|
||||
},
|
||||
immediate: true
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
/* 人数分布排名 */
|
||||
.monitor-user-count-item {
|
||||
margin-bottom: 8px;
|
||||
:deep(.el-progress-bar__outer) {
|
||||
background: none;
|
||||
}
|
||||
.ele-cell-content {
|
||||
padding-right: 10px;
|
||||
}
|
||||
}
|
||||
.analysis-chart-card-num {
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
.analysis-chart-card-content {
|
||||
height: 40px;
|
||||
box-sizing: border-box;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.analysis-chart-card-text {
|
||||
padding-top: 12px;
|
||||
}
|
||||
|
||||
.workplace-table-card {
|
||||
:deep(.el-table tbody > .el-table__row:last-child td) {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
:deep(.el-table:before) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.el-header_add .ele-cell {
|
||||
color: #409eff;
|
||||
cursor: pointer;
|
||||
}
|
||||
.el-header_add .analysis-chart-card-num {
|
||||
color: #409eff;
|
||||
cursor: pointer;
|
||||
}
|
||||
.ranking-order-header {
|
||||
border-bottom: 1px solid var(--border-color-lighter);
|
||||
box-sizing: border-box;
|
||||
padding: 10px 17px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,196 @@
|
||||
<!-- 分组编辑弹窗 -->
|
||||
<template>
|
||||
<ele-modal
|
||||
width="680px"
|
||||
:visible="visible"
|
||||
:close-on-click-modal="true"
|
||||
custom-class="ele-dialog-form"
|
||||
:title="isUpdate ? '修改分组' : '添加分组'"
|
||||
@update:visible="updateVisible"
|
||||
>
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="82px">
|
||||
<el-row :gutter="15">
|
||||
<el-col v-bind="styleResponsive ? { sm: 12 } : { span: 12 }">
|
||||
<el-form-item label="上级分组:">
|
||||
<gro-select
|
||||
v-model="form.parentId"
|
||||
:data="groupsList"
|
||||
placeholder="请选择上级分组"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="分组名称:" prop="groupsName">
|
||||
<el-input
|
||||
clearable
|
||||
:maxlength="20"
|
||||
v-model="form.groupsName"
|
||||
placeholder="请输入分组名称"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="排序号:">
|
||||
<el-input-number
|
||||
:min="0"
|
||||
:max="99999"
|
||||
v-model="form.sortNumber"
|
||||
controls-position="right"
|
||||
placeholder="请输入排序号"
|
||||
class="ele-fluid ele-text-left"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col v-bind="styleResponsive ? { sm: 12 } : { span: 12 }">
|
||||
<el-form-item label="用户来源:">
|
||||
<el-radio-group v-model="form.userFrom">
|
||||
<el-radio :label="0">机构</el-radio>
|
||||
<el-radio :label="1">团队</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="form.userFrom == 0 ? '是否门店:' : '是否团队:'">
|
||||
<el-radio-group v-model="form.ifBiz">
|
||||
<el-radio :label="0">否</el-radio>
|
||||
<el-radio :label="1">是</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
label="统计类型:"
|
||||
v-if="!form.parentId"
|
||||
prop="statisticsType"
|
||||
>
|
||||
<el-select
|
||||
clearable
|
||||
v-model="form.statisticsType"
|
||||
placeholder="请选择统计类型"
|
||||
class="ele-fluid"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in statisticsTypeList"
|
||||
:key="item.dictId"
|
||||
:value="item.dictId"
|
||||
:label="item.dictName"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template v-slot:footer>
|
||||
<el-button @click="updateVisible(false)">取消</el-button>
|
||||
<el-button type="primary" :loading="loading" @click="save">
|
||||
保存
|
||||
</el-button>
|
||||
</template>
|
||||
</ele-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import GroSelect from './gro-select.vue';
|
||||
import { addGroups, updateGroups } from '@/api/sylive/groups';
|
||||
|
||||
export default {
|
||||
components: { GroSelect },
|
||||
props: {
|
||||
// 弹窗是否打开
|
||||
visible: Boolean,
|
||||
// 修改回显的数据
|
||||
data: Object,
|
||||
// 上级id
|
||||
parentId: Number,
|
||||
// 活动id
|
||||
activityId: Number,
|
||||
// 分组数据
|
||||
groupsList: Array,
|
||||
// 统计类型数据
|
||||
statisticsTypeList: Array
|
||||
},
|
||||
data() {
|
||||
const defaultForm = {
|
||||
groupsId: null,
|
||||
parentId: null,
|
||||
groupsName: '',
|
||||
userFrom: 0,
|
||||
ifBiz: 0,
|
||||
statisticsType: null,
|
||||
sortNumber: null
|
||||
};
|
||||
return {
|
||||
defaultForm,
|
||||
// 表单数据
|
||||
form: { ...defaultForm },
|
||||
// 表单验证规则
|
||||
rules: {
|
||||
groupsName: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入分组名称',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
statisticsType: [
|
||||
{
|
||||
required: true,
|
||||
message: '请选择统计类型',
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
},
|
||||
// 提交状态
|
||||
loading: false,
|
||||
// 是否是修改
|
||||
isUpdate: false
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
// 是否开启响应式布局
|
||||
styleResponsive() {
|
||||
return this.$store.state.theme.styleResponsive;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/* 保存编辑 */
|
||||
save() {
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (!valid) {
|
||||
return false;
|
||||
}
|
||||
this.loading = true;
|
||||
const data = {
|
||||
...this.form,
|
||||
activityId: this.activityId || 0,
|
||||
parentId: this.form.parentId || 0
|
||||
};
|
||||
const saveOrUpdate = this.isUpdate ? updateGroups : addGroups;
|
||||
saveOrUpdate(data)
|
||||
.then((msg) => {
|
||||
this.loading = false;
|
||||
this.$message.success(msg);
|
||||
this.updateVisible(false);
|
||||
this.$emit('done');
|
||||
})
|
||||
.catch((e) => {
|
||||
this.loading = false;
|
||||
this.$message.error(e.message);
|
||||
});
|
||||
});
|
||||
},
|
||||
/* 更新visible */
|
||||
updateVisible(value) {
|
||||
this.$emit('update:visible', value);
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
visible(visible) {
|
||||
if (visible) {
|
||||
if (this.data) {
|
||||
this.$util.assignObject(this.form, this.data);
|
||||
this.isUpdate = true;
|
||||
} else {
|
||||
this.form.parentId = this.parentId;
|
||||
this.isUpdate = false;
|
||||
}
|
||||
} else {
|
||||
this.$refs.form.clearValidate();
|
||||
this.form = { ...this.defaultForm };
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,35 @@
|
||||
<!-- 分组选择下拉框 -->
|
||||
<template>
|
||||
<ele-tree-select
|
||||
clearable
|
||||
:value="value || ''"
|
||||
:data="data"
|
||||
label-key="groupsName"
|
||||
value-key="groupsId"
|
||||
:default-expand-all="true"
|
||||
:placeholder="placeholder"
|
||||
@input="updateValue"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
// 选中的数据(v-model)
|
||||
value: Number,
|
||||
// 提示信息
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: '请选择分组'
|
||||
},
|
||||
// 分组数据
|
||||
data: Array
|
||||
},
|
||||
methods: {
|
||||
/* 更新选中数据 */
|
||||
updateValue(value) {
|
||||
this.$emit('input', value);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,336 @@
|
||||
<template>
|
||||
<ele-modal
|
||||
width="70%"
|
||||
:visible="visible"
|
||||
title="添加用户"
|
||||
@update:visible="updateVisible"
|
||||
>
|
||||
<div class="ele-body" style="padding: 0px">
|
||||
<el-card shadow="never" body-style="padding: 0px;">
|
||||
<el-row :gutter="15">
|
||||
<el-col v-bind="styleResponsive ? { md: 12 } : { span: 12 }">
|
||||
<!-- 未选择的用户数据表格 -->
|
||||
<ele-pro-table
|
||||
:datasource="unChooseUsers"
|
||||
:columns="columns"
|
||||
sub-title=""
|
||||
height="535px"
|
||||
emptyText="无未选用户"
|
||||
:toolkit="[]"
|
||||
layout="total, prev, pager, next, jumper"
|
||||
>
|
||||
<template v-slot:toolkit>
|
||||
<el-row>
|
||||
<el-col style="width: 50%; padding-right: 5px">
|
||||
<ele-tree-select
|
||||
v-show="userFrom == 0 ? true : false"
|
||||
:data="organizationList"
|
||||
label-key="organizationName"
|
||||
value-key="organizationId"
|
||||
v-model="organizationIds"
|
||||
:multiple="true"
|
||||
:clearable="true"
|
||||
placeholder="请选择机构"
|
||||
:disabled="false"
|
||||
size="small"
|
||||
:check-strictly="false"
|
||||
/>
|
||||
<ele-tree-select
|
||||
v-show="userFrom == 1 ? true : false"
|
||||
:data="teamList"
|
||||
label-key="teamName"
|
||||
value-key="teamId"
|
||||
v-model="teamIds"
|
||||
:multiple="true"
|
||||
:clearable="true"
|
||||
placeholder="请选择团队"
|
||||
:disabled="false"
|
||||
size="small"
|
||||
:check-strictly="false"
|
||||
/>
|
||||
</el-col>
|
||||
<el-col style="width: 20%; padding-right: 5px">
|
||||
<el-input
|
||||
:maxlength="20"
|
||||
v-model="keyword"
|
||||
placeholder="请输入姓名"
|
||||
size="small"
|
||||
/>
|
||||
</el-col>
|
||||
<el-col style="width: 15%">
|
||||
<el-button
|
||||
class="ele-btn-icon"
|
||||
size="small"
|
||||
@click="search"
|
||||
>
|
||||
查询用户
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col style="width: 15%">
|
||||
<el-button
|
||||
class="ele-btn-icon"
|
||||
size="small"
|
||||
@click="addAll"
|
||||
>
|
||||
全部添加
|
||||
</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
<template v-slot:action="{ row }">
|
||||
<el-button size="mini" @click="add(row)">添加</el-button>
|
||||
</template>
|
||||
</ele-pro-table>
|
||||
</el-col>
|
||||
<el-col v-bind="styleResponsive ? { md: 12 } : { span: 12 }">
|
||||
<!-- 已选择的用户数据表格 -->
|
||||
<ele-pro-table
|
||||
:datasource="chooseUsers"
|
||||
:columns="columns"
|
||||
sub-title="已选用户:"
|
||||
height="535px"
|
||||
emptyText="未选择用户"
|
||||
:toolkit="[]"
|
||||
:tool-style="{ lineHeight: '40px' }"
|
||||
layout="total, prev, pager, next, jumper"
|
||||
>
|
||||
<template v-slot:toolkit>
|
||||
<el-button
|
||||
type="primary"
|
||||
class="ele-btn-icon"
|
||||
:loading="loading"
|
||||
size="small"
|
||||
@click="save"
|
||||
>
|
||||
保存已选用户
|
||||
</el-button>
|
||||
<el-button
|
||||
size="small"
|
||||
type="danger"
|
||||
plain
|
||||
class="ele-btn-icon"
|
||||
@click="removeAll"
|
||||
>
|
||||
全部移除
|
||||
</el-button>
|
||||
</template>
|
||||
<template v-slot:action="{ row }">
|
||||
<el-button type="danger" plain size="mini" @click="remove(row)">
|
||||
移除
|
||||
</el-button>
|
||||
</template>
|
||||
</ele-pro-table>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
</div>
|
||||
</ele-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listUsers } from '@/api/sylive/user';
|
||||
import { listTeamUser } from '@/api/sylive/team-user';
|
||||
import { addGroupsUser } from '@/api/sylive/groups-user';
|
||||
|
||||
export default {
|
||||
name: 'groupsUserAdd',
|
||||
props: {
|
||||
// 全部机构
|
||||
organizationList: Array,
|
||||
// 全部团队
|
||||
teamList: Array,
|
||||
// 分组id
|
||||
groupsId: Number,
|
||||
// 用户来源
|
||||
userFrom: Number,
|
||||
// 活动id
|
||||
activityId: Number,
|
||||
// 弹窗是否打开
|
||||
visible: Boolean
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
organizationIds: [],
|
||||
teamIds: [],
|
||||
keyword: null,
|
||||
// 加载状态
|
||||
loading: false,
|
||||
// 全部用户
|
||||
classes: [],
|
||||
// 已选择的用户数据
|
||||
chooseUsers: [],
|
||||
// 表格列配置
|
||||
columns: []
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
/* 未选择的用户数据 */
|
||||
unChooseUsers() {
|
||||
return this.classes.filter((d) => this.chooseUsers.indexOf(d) === -1);
|
||||
},
|
||||
// 是否开启响应式布局
|
||||
styleResponsive() {
|
||||
return this.$store.state.theme.styleResponsive;
|
||||
}
|
||||
},
|
||||
created() {},
|
||||
methods: {
|
||||
/* 获取机构用户 */
|
||||
search() {
|
||||
if (this.userFrom == 1) {
|
||||
this.queryTeam();
|
||||
} else {
|
||||
this.query();
|
||||
}
|
||||
},
|
||||
/* 获取机构用户 */
|
||||
query() {
|
||||
if (this.organizationIds.length <= 0 && !this.keyword) {
|
||||
this.$message.error('请选择机构或输入姓名');
|
||||
return;
|
||||
}
|
||||
listUsers({
|
||||
organizationIds: this.organizationIds,
|
||||
keyword: this.keyword
|
||||
})
|
||||
.then((data) => {
|
||||
this.classes = [];
|
||||
if (this.chooseUsers.length > 0) {
|
||||
data.forEach((item) => {
|
||||
let choose = false;
|
||||
this.chooseUsers.forEach((d) => {
|
||||
if (item.userId == d.userId) {
|
||||
choose = true;
|
||||
}
|
||||
});
|
||||
if (!choose) {
|
||||
this.classes.push(item);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.classes = data;
|
||||
}
|
||||
})
|
||||
.catch((e) => {
|
||||
this.$message.error(e.message);
|
||||
});
|
||||
},
|
||||
/* 获取团队用户 */
|
||||
queryTeam() {
|
||||
if (this.teamIds.length <= 0 && !this.keyword) {
|
||||
this.$message.error('请选择团队或输入姓名');
|
||||
return;
|
||||
}
|
||||
listTeamUser({
|
||||
teamIds: this.teamIds,
|
||||
keyword: this.keyword
|
||||
})
|
||||
.then((data) => {
|
||||
this.classes = [];
|
||||
if (this.chooseUsers.length > 0) {
|
||||
data.forEach((item) => {
|
||||
let choose = false;
|
||||
this.chooseUsers.forEach((d) => {
|
||||
if (item.userId == d.userId) {
|
||||
choose = true;
|
||||
}
|
||||
});
|
||||
if (!choose) {
|
||||
this.classes.push(item);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.classes = data;
|
||||
}
|
||||
})
|
||||
.catch((e) => {
|
||||
this.$message.error(e.message);
|
||||
});
|
||||
},
|
||||
/* 添加 */
|
||||
add(row) {
|
||||
this.chooseUsers.push(row);
|
||||
},
|
||||
/* 移除 */
|
||||
remove(row) {
|
||||
this.chooseUsers.splice(this.chooseUsers.indexOf(row), 1);
|
||||
},
|
||||
/* 添加全部 */
|
||||
addAll() {
|
||||
this.unChooseUsers.forEach((d) => {
|
||||
this.chooseUsers.push(d);
|
||||
});
|
||||
},
|
||||
/* 移除所有 */
|
||||
removeAll() {
|
||||
this.chooseUsers.splice(0, this.chooseUsers.length);
|
||||
},
|
||||
save() {
|
||||
if (this.chooseUsers.length <= 0) {
|
||||
this.$message.error('未选择用户');
|
||||
return;
|
||||
}
|
||||
addGroupsUser({
|
||||
groupsId: this.groupsId,
|
||||
userFrom: this.userFrom,
|
||||
activityId: this.activityId,
|
||||
chooseUsers: this.chooseUsers
|
||||
})
|
||||
.then((msg) => {
|
||||
this.loading = false;
|
||||
this.$message.success(msg);
|
||||
this.updateVisible(false);
|
||||
this.$emit('done');
|
||||
})
|
||||
.catch((e) => {
|
||||
this.loading = false;
|
||||
this.$message.error(e.message);
|
||||
});
|
||||
},
|
||||
/* 更新visible */
|
||||
updateVisible(value) {
|
||||
this.$emit('update:visible', value);
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
visible(visible) {
|
||||
this.columns = [
|
||||
{
|
||||
columnKey: 'action',
|
||||
label: '操作',
|
||||
width: 100,
|
||||
align: 'center',
|
||||
slot: 'action'
|
||||
},
|
||||
{
|
||||
prop: 'uname',
|
||||
label: '姓名',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 110
|
||||
},
|
||||
{
|
||||
prop: 'mobile',
|
||||
label: '手机号',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 110
|
||||
},
|
||||
{
|
||||
prop: this.userFrom == 0 ? 'organizationName' : 'teamName',
|
||||
label: this.userFrom == 0 ? '机构' : '团队',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 110
|
||||
}
|
||||
];
|
||||
if (visible) {
|
||||
//
|
||||
} else {
|
||||
this.organizationIds = [];
|
||||
this.teamIds = [];
|
||||
this.keyword = null;
|
||||
this.classes = [];
|
||||
this.chooseUsers = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,180 @@
|
||||
<!-- 用户编辑弹窗 -->
|
||||
<template>
|
||||
<ele-modal
|
||||
width="680px"
|
||||
:visible="visible"
|
||||
:close-on-click-modal="true"
|
||||
custom-class="ele-dialog-form"
|
||||
:title="isUpdate ? '修改用户' : '添加用户'"
|
||||
@update:visible="updateVisible"
|
||||
>
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="82px">
|
||||
<el-row :gutter="15">
|
||||
<el-col v-bind="styleResponsive ? { sm: 12 } : { span: 12 }">
|
||||
<el-form-item label="所属机构:" prop="organizationId">
|
||||
<gro-select
|
||||
:data="organizationList"
|
||||
placeholder="请选择所属机构"
|
||||
v-model="form.organizationId"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="手机号:" prop="mobile">
|
||||
<el-input
|
||||
clearable
|
||||
:maxlength="11"
|
||||
:disabled="isUpdate"
|
||||
v-model="form.mobile"
|
||||
placeholder="请输入手机号"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col v-bind="styleResponsive ? { sm: 12 } : { span: 12 }">
|
||||
<el-form-item label="姓名:" prop="uname">
|
||||
<el-input
|
||||
clearable
|
||||
:maxlength="20"
|
||||
v-model="form.uname"
|
||||
placeholder="请输入姓名"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template v-slot:footer>
|
||||
<el-button @click="updateVisible(false)">取消</el-button>
|
||||
<el-button type="primary" :loading="loading" @click="save">
|
||||
保存
|
||||
</el-button>
|
||||
</template>
|
||||
</ele-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { phoneReg } from 'ele-admin';
|
||||
import GroSelect from './gro-select.vue';
|
||||
import { addUser, updateUser, checkExistence } from '@/api/sylive/user';
|
||||
|
||||
export default {
|
||||
components: { GroSelect },
|
||||
props: {
|
||||
// 弹窗是否打开
|
||||
visible: Boolean,
|
||||
// 修改回显的数据
|
||||
data: Object,
|
||||
// 全部机构
|
||||
organizationList: Array,
|
||||
// 机构id
|
||||
organizationId: Number
|
||||
},
|
||||
data() {
|
||||
const defaultForm = {
|
||||
userId: null,
|
||||
organizationId: null,
|
||||
mobile: '',
|
||||
uname: ''
|
||||
};
|
||||
return {
|
||||
defaultForm,
|
||||
// 表单数据
|
||||
form: { ...defaultForm },
|
||||
// 表单验证规则
|
||||
rules: {
|
||||
mobile: [
|
||||
{
|
||||
required: true,
|
||||
trigger: 'blur',
|
||||
validator: (_rule, value, callback) => {
|
||||
if (!value) {
|
||||
return callback(new Error('请输入手机号'));
|
||||
}
|
||||
const st = new RegExp(phoneReg);
|
||||
if (!st.test(value)) {
|
||||
return callback(new Error('手机号格式不正确'));
|
||||
}
|
||||
checkExistence('mobile', value, this.data?.mobile)
|
||||
.then(() => {
|
||||
callback(new Error('手机号已经存在'));
|
||||
})
|
||||
.catch(() => {
|
||||
callback();
|
||||
});
|
||||
}
|
||||
}
|
||||
],
|
||||
organizationId: [
|
||||
{
|
||||
required: true,
|
||||
message: '请选择所属机构',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
uname: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入姓名',
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
},
|
||||
// 提交状态
|
||||
loading: false,
|
||||
// 是否是修改
|
||||
isUpdate: false
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
// 是否开启响应式布局
|
||||
styleResponsive() {
|
||||
return this.$store.state.theme.styleResponsive;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/* 保存编辑 */
|
||||
save() {
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (!valid) {
|
||||
return false;
|
||||
}
|
||||
this.loading = true;
|
||||
const data = {
|
||||
...this.form
|
||||
};
|
||||
const saveOrUpdate = this.isUpdate ? updateUser : addUser;
|
||||
saveOrUpdate(data)
|
||||
.then((msg) => {
|
||||
this.loading = false;
|
||||
this.$message.success(msg);
|
||||
this.updateVisible(false);
|
||||
this.$emit('done');
|
||||
})
|
||||
.catch((e) => {
|
||||
this.loading = false;
|
||||
this.$message.error(e.message);
|
||||
});
|
||||
});
|
||||
},
|
||||
/* 更新visible */
|
||||
updateVisible(value) {
|
||||
this.$emit('update:visible', value);
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
visible(visible) {
|
||||
if (visible) {
|
||||
if (this.data) {
|
||||
this.$util.assignObject(this.form, {
|
||||
...this.data
|
||||
});
|
||||
this.isUpdate = true;
|
||||
} else {
|
||||
this.form.organizationId = this.organizationId;
|
||||
this.isUpdate = false;
|
||||
}
|
||||
} else {
|
||||
this.$refs.form.clearValidate();
|
||||
this.form = { ...this.defaultForm };
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,223 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- 数据表格 -->
|
||||
<ele-pro-table
|
||||
ref="table"
|
||||
:columns="columns"
|
||||
:datasource="datasource"
|
||||
height="calc(100vh - 265px)"
|
||||
full-height="calc(100vh - 116px)"
|
||||
tool-class="ele-toolbar-form"
|
||||
cache-key="systemOrgUserTable"
|
||||
>
|
||||
<!-- 表头工具栏 -->
|
||||
<template v-slot:toolbar>
|
||||
<gro-user-search @search="reload">
|
||||
<el-button
|
||||
size="small"
|
||||
type="primary"
|
||||
icon="el-icon-plus"
|
||||
class="ele-btn-icon"
|
||||
@click="openAdd()"
|
||||
>
|
||||
添加
|
||||
</el-button>
|
||||
</gro-user-search>
|
||||
</template>
|
||||
<!-- 角色列 -->
|
||||
<template v-slot:roleName="{ row }">
|
||||
<el-tag type="primary" size="mini">
|
||||
{{ row.roleName }}
|
||||
</el-tag>
|
||||
</template>
|
||||
<!-- 状态列 -->
|
||||
<template v-slot:status="{ row }">
|
||||
<el-switch
|
||||
:active-value="0"
|
||||
:inactive-value="1"
|
||||
v-model="row.status"
|
||||
@change="editStatus(row)"
|
||||
/>
|
||||
</template>
|
||||
<!-- 操作列 -->
|
||||
<template v-slot:action="{ row }">
|
||||
<el-popconfirm
|
||||
class="ele-action"
|
||||
title="确定要删除此用户吗?"
|
||||
@confirm="remove(row)"
|
||||
>
|
||||
<template v-slot:reference>
|
||||
<el-link type="danger" :underline="false" icon="el-icon-delete">
|
||||
删除
|
||||
</el-link>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
</template>
|
||||
</ele-pro-table>
|
||||
<!-- 编辑弹窗 -->
|
||||
<gro-user-add
|
||||
:visible.sync="showAdd"
|
||||
:user-from="userFrom"
|
||||
:groups-id="groupsId"
|
||||
:activity-id="activityId"
|
||||
:organization-list="organizationList"
|
||||
:team-list="teamList"
|
||||
@done="reload"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import GroUserSearch from './gro-user-search.vue';
|
||||
import GroUserAdd from './gro-user-add.vue';
|
||||
import {
|
||||
pageGroupsUser,
|
||||
removeGroupsUser,
|
||||
updateGroupsUserStatus
|
||||
} from '@/api/sylive/groups-user';
|
||||
|
||||
export default {
|
||||
components: { GroUserSearch, GroUserAdd },
|
||||
props: {
|
||||
// 分组id
|
||||
groupsId: Number,
|
||||
// 用户来源
|
||||
userFrom: Number,
|
||||
// 活动id
|
||||
activityId: Number,
|
||||
// 全部分组
|
||||
groupsList: Array,
|
||||
// 全部团队
|
||||
teamList: Array,
|
||||
// 全部机构
|
||||
organizationList: Array
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 表格列配置
|
||||
columns: [
|
||||
{
|
||||
columnKey: 'index',
|
||||
type: 'index',
|
||||
width: 45,
|
||||
align: 'center',
|
||||
showOverflowTooltip: true,
|
||||
fixed: 'left'
|
||||
},
|
||||
{
|
||||
prop: 'uname',
|
||||
label: '姓名',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 110
|
||||
},
|
||||
{
|
||||
prop: 'nickname',
|
||||
label: '微信昵称',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 110
|
||||
},
|
||||
{
|
||||
prop: 'mobile',
|
||||
label: '手机号',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 110
|
||||
},
|
||||
{
|
||||
prop: 'roleName',
|
||||
label: '角色',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 70,
|
||||
slot: 'roleName'
|
||||
},
|
||||
{
|
||||
prop: 'createTime',
|
||||
label: '创建时间',
|
||||
showOverflowTooltip: true,
|
||||
minWidth: 120,
|
||||
formatter: (_row, _column, cellValue) => {
|
||||
return this.$util.toDateString(cellValue);
|
||||
}
|
||||
},
|
||||
{
|
||||
prop: 'status',
|
||||
label: '状态',
|
||||
align: 'center',
|
||||
width: 110,
|
||||
resizable: false,
|
||||
slot: 'status'
|
||||
},
|
||||
{
|
||||
columnKey: 'action',
|
||||
label: '操作',
|
||||
width: 120,
|
||||
align: 'center',
|
||||
resizable: false,
|
||||
slot: 'action',
|
||||
showOverflowTooltip: true
|
||||
}
|
||||
],
|
||||
// 当前编辑数据
|
||||
current: null,
|
||||
// 是否显示添加弹窗
|
||||
showAdd: false,
|
||||
// 是否显示编辑弹窗
|
||||
showEdit: false
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
/* 表格数据源 */
|
||||
datasource({ page, limit, where, order }) {
|
||||
return pageGroupsUser({
|
||||
...where,
|
||||
...order,
|
||||
page,
|
||||
limit,
|
||||
groupsId: this.groupsId,
|
||||
activityId: this.activityId
|
||||
});
|
||||
},
|
||||
/* 刷新表格 */
|
||||
reload(where) {
|
||||
this.$refs.table.reload({ page: 1, where: where });
|
||||
},
|
||||
/* 显示添加 */
|
||||
openAdd() {
|
||||
this.showAdd = true;
|
||||
},
|
||||
/* 删除 */
|
||||
remove(row) {
|
||||
const loading = this.$loading({ lock: true });
|
||||
removeGroupsUser(row.groupsUserId)
|
||||
.then((msg) => {
|
||||
loading.close();
|
||||
this.$message.success(msg);
|
||||
this.reload();
|
||||
})
|
||||
.catch((e) => {
|
||||
loading.close();
|
||||
this.$message.error(e.message);
|
||||
});
|
||||
},
|
||||
/* 更改状态 */
|
||||
editStatus(row) {
|
||||
const loading = this.$loading({ lock: true });
|
||||
updateGroupsUserStatus(row.groupsUserId, row.status)
|
||||
.then((msg) => {
|
||||
loading.close();
|
||||
this.$message.success(msg);
|
||||
})
|
||||
.catch((e) => {
|
||||
loading.close();
|
||||
row.status = !row.status ? 1 : 0;
|
||||
this.$message.error(e.message);
|
||||
});
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
// 监听机构id变化
|
||||
groupsId() {
|
||||
this.reload();
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,79 @@
|
||||
<!-- 搜索表单 -->
|
||||
<template>
|
||||
<el-form
|
||||
size="small"
|
||||
class="ele-form-search"
|
||||
@keyup.enter.native="search"
|
||||
@submit.native.prevent
|
||||
>
|
||||
<el-row :gutter="10">
|
||||
<el-col v-bind="styleResponsive ? { md: 8 } : { span: 8 }">
|
||||
<el-form-item>
|
||||
<el-input
|
||||
clearable
|
||||
size="small"
|
||||
v-model="where.uname"
|
||||
placeholder="请输入姓名"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col v-bind="styleResponsive ? { md: 8 } : { span: 8 }">
|
||||
<el-form-item>
|
||||
<el-input
|
||||
clearable
|
||||
size="small"
|
||||
v-model="where.nickname"
|
||||
placeholder="请输入微信昵称"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col v-bind="styleResponsive ? { md: 8 } : { span: 8 }">
|
||||
<el-form-item>
|
||||
<el-button
|
||||
size="small"
|
||||
type="primary"
|
||||
icon="el-icon-search"
|
||||
class="ele-btn-icon"
|
||||
@click="search"
|
||||
>
|
||||
查询
|
||||
</el-button>
|
||||
<slot></slot>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
// 默认表单数据
|
||||
const defaultWhere = {
|
||||
uname: '',
|
||||
nickname: ''
|
||||
};
|
||||
return {
|
||||
// 表单数据
|
||||
where: { ...defaultWhere }
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
// 是否开启响应式布局
|
||||
styleResponsive() {
|
||||
return this.$store.state.theme.styleResponsive;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/* 搜索 */
|
||||
search() {
|
||||
this.$emit('search', this.where);
|
||||
},
|
||||
/* 重置 */
|
||||
reset() {
|
||||
this.where = { ...this.defaultWhere };
|
||||
this.search();
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,258 @@
|
||||
<template>
|
||||
<div class="ele-body">
|
||||
<el-card shadow="never" v-loading="loading">
|
||||
<ele-split-layout
|
||||
width="266px"
|
||||
allow-collapse
|
||||
:right-style="{ overflow: 'hidden' }"
|
||||
>
|
||||
<div>
|
||||
<!-- 操作按钮 -->
|
||||
<ele-toolbar class="ele-toolbar-actions">
|
||||
<div style="margin: 5px 0">
|
||||
<el-button
|
||||
size="small"
|
||||
type="primary"
|
||||
icon="el-icon-plus"
|
||||
class="ele-btn-icon"
|
||||
@click="openEdit()"
|
||||
>
|
||||
添加
|
||||
</el-button>
|
||||
<el-button
|
||||
size="small"
|
||||
type="warning"
|
||||
icon="el-icon-edit"
|
||||
class="ele-btn-icon"
|
||||
:disabled="!current"
|
||||
@click="openEdit(current)"
|
||||
>
|
||||
修改
|
||||
</el-button>
|
||||
<el-button
|
||||
size="small"
|
||||
type="danger"
|
||||
icon="el-icon-delete"
|
||||
class="ele-btn-icon"
|
||||
:disabled="!current"
|
||||
@click="remove"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</div>
|
||||
</ele-toolbar>
|
||||
<div class="ele-border-lighter sys-groups-list">
|
||||
<el-tree
|
||||
ref="tree"
|
||||
:data="data"
|
||||
highlight-current
|
||||
node-key="groupsId"
|
||||
:props="{ label: 'groupsName' }"
|
||||
:expand-on-click-node="false"
|
||||
:default-expand-all="true"
|
||||
@node-click="onNodeClick"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<template v-slot:content>
|
||||
<gro-user-list
|
||||
v-if="current"
|
||||
:user-from="current.userFrom"
|
||||
:groups-id="current.groupsId"
|
||||
:activity-id="activityId"
|
||||
:organization-list="organizationList"
|
||||
:team-list="teamList"
|
||||
/>
|
||||
</template>
|
||||
</ele-split-layout>
|
||||
</el-card>
|
||||
<!-- 编辑弹窗 -->
|
||||
<gro-edit
|
||||
:visible.sync="showEdit"
|
||||
:data="editData"
|
||||
:activity-id="activityId"
|
||||
:parent-id="parentId"
|
||||
:groups-list="data"
|
||||
:statistics-type-list="statisticsTypeList"
|
||||
@done="query"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import GroUserList from './components/gro-user-list.vue';
|
||||
import GroEdit from './components/gro-edit.vue';
|
||||
import { listGroups, removeGroups } from '@/api/sylive/groups';
|
||||
import { listOrganizations } from '@/api/sylive/organization';
|
||||
import { listTeams } from '@/api/sylive/team';
|
||||
import { listDictionaries } from '@/api/system/dictionary';
|
||||
const ROUTE_PATH = '/sylive/groups';
|
||||
|
||||
export default {
|
||||
name: 'SyliveGroups',
|
||||
components: { GroUserList, GroEdit },
|
||||
data() {
|
||||
return {
|
||||
// 加载状态
|
||||
loading: true,
|
||||
// 列表数据
|
||||
data: [],
|
||||
// 选中数据
|
||||
current: null,
|
||||
// 机构数据
|
||||
organizationList: [],
|
||||
// 团队数据
|
||||
teamList: [],
|
||||
// 统计类型数据
|
||||
statisticsTypeList: [],
|
||||
// 是否显示表单弹窗
|
||||
showEdit: false,
|
||||
// 编辑回显数据
|
||||
editData: null,
|
||||
// 上级id
|
||||
parentId: null,
|
||||
// 活动id
|
||||
activityId: null
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.organizationQuery();
|
||||
this.teamQuery();
|
||||
this.statisticsTypeQuery();
|
||||
},
|
||||
methods: {
|
||||
/* 查询 */
|
||||
query() {
|
||||
this.loading = true;
|
||||
listGroups({ activityId: this.activityId })
|
||||
.then((list) => {
|
||||
this.loading = false;
|
||||
this.data = this.$util.toTreeData({
|
||||
data: list,
|
||||
idField: 'groupsId',
|
||||
parentIdField: 'parentId'
|
||||
});
|
||||
this.$nextTick(() => {
|
||||
this.onNodeClick(this.data[0]);
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
this.loading = false;
|
||||
this.$message.error(e.message);
|
||||
});
|
||||
},
|
||||
/* 查询机构 */
|
||||
organizationQuery() {
|
||||
listOrganizations({
|
||||
unOrganizationType: 4,
|
||||
activityId: this.activityId
|
||||
})
|
||||
.then((list) => {
|
||||
this.organizationList = this.$util.toTreeData({
|
||||
data: list,
|
||||
idField: 'organizationId',
|
||||
parentIdField: 'parentId'
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
this.$message.error(e.message);
|
||||
});
|
||||
},
|
||||
/* 查询团队 */
|
||||
teamQuery() {
|
||||
listTeams({ unTeamType: 3 })
|
||||
.then((list) => {
|
||||
this.teamList = this.$util.toTreeData({
|
||||
data: list,
|
||||
idField: 'teamId',
|
||||
parentIdField: 'parentId'
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
this.$message.error(e.message);
|
||||
});
|
||||
},
|
||||
/* 查询统计类型 */
|
||||
statisticsTypeQuery() {
|
||||
listDictionaries({ dictCode: 'groups_level' })
|
||||
.then((list) => {
|
||||
this.statisticsTypeList = list;
|
||||
})
|
||||
.catch((e) => {
|
||||
this.$message.error(e.message);
|
||||
});
|
||||
},
|
||||
/* 选择数据 */
|
||||
onNodeClick(row) {
|
||||
if (row) {
|
||||
this.current = row;
|
||||
this.parentId = row.groupsId;
|
||||
this.$refs.tree.setCurrentKey(row.groupsId);
|
||||
} else {
|
||||
this.current = null;
|
||||
this.parentId = null;
|
||||
}
|
||||
},
|
||||
/* 显示编辑 */
|
||||
openEdit(item) {
|
||||
this.editData = item;
|
||||
this.showEdit = true;
|
||||
},
|
||||
/* 删除 */
|
||||
remove() {
|
||||
this.$confirm('确定要删除选中的分组吗?', '提示', {
|
||||
type: 'warning'
|
||||
})
|
||||
.then(() => {
|
||||
const loading = this.$loading({ lock: true });
|
||||
removeGroups(this.current.groupsId)
|
||||
.then((msg) => {
|
||||
loading.close();
|
||||
this.$message.success(msg);
|
||||
this.query();
|
||||
})
|
||||
.catch((e) => {
|
||||
loading.close();
|
||||
this.$message.error(e.message);
|
||||
});
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
$route: {
|
||||
handler(route) {
|
||||
const { path } = route;
|
||||
if (path !== ROUTE_PATH) {
|
||||
return;
|
||||
}
|
||||
const activityId = this.$route.query.id;
|
||||
if (!activityId || activityId == this.activityId) {
|
||||
return;
|
||||
}
|
||||
this.activityId = Number(activityId);
|
||||
this.query();
|
||||
},
|
||||
immediate: true
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.sys-groups-list {
|
||||
height: calc(100vh - 264px);
|
||||
box-sizing: border-box;
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.sys-groups-list :deep(.el-tree-node__content) {
|
||||
height: 40px;
|
||||
|
||||
& > .el-tree-node__expand-icon {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user