This commit is contained in:
wkc
2026-02-26 14:51:13 +08:00
commit acd6c38ae2
2102 changed files with 320452 additions and 0 deletions

View File

@@ -0,0 +1,3 @@
<template>
<router-view />
</template>

View File

@@ -0,0 +1,237 @@
<template>
<section class="list-header">
<p class="common-title">{{ ruleTitle }}</p>
<section class="main-wrap">
<span class="rule-name-label">分配规则</span>
<ul class="list-main">
<li class="formObj-form-item" v-for="(item, ind) in listData" :key="item.key">
<section class="form-vl">
<span>{{ ind + 1 }}优先级</span>
<el-select v-model="item.ruleKey" placeholder="请选择" size="small" clearable>
<el-option v-for="(ot, oInd) in ruleArr" :disabled="isChose(ot, oInd)||ot.disabled" :key="ot.value" :label="ot.label" :value="ot.value"></el-option>
</el-select>
</section>
<section class="operate-areas">
<el-button
:disabled="customShow||listData.length==1"
type="text"
icon="el-icon-remove-outline"
class="gray-color"
ref="del"
@click.prevent="onDel(ind)"
></el-button>
<el-button
type="text"
:disabled="customShow||listData.length>=2"
ref="add"
icon="el-icon-circle-plus-outline"
class="gray-color"
@click.prevent="onAdd(ind)"
:class="specialType?'specialClass':''"
></el-button>
</section>
</li>
</ul>
</section>
</section>
</template>
<script>
import {} from '@/api/grid/address/tree.js'
import { uid } from '@/utils'
import { isEmpty, cloneDeep, omit } from 'lodash'
const relateTypeMap = {
personal: '个人',
company: '企业',
merchant: '商户'
}
export default {
props: {
ruleTitle: {
type: String,
default: ''
},
ruleArr: {
type: Array,
default: () => []
},
ruleName: {
type: String,
default: ''
},
defaultListData: {
type: Array,
default: () => []
},
customShow: {
type: Boolean,
default: false
},
specialType: {
type: Boolean,
default: false
},
},
watch: {
listData: {
handler(arr) {
this.$emit('getRuleArr', {
arr: arr?.map((ot, oInd) =>
omit(
cloneDeep({
...ot,
ruleOrder: oInd + 1
}),
'key'
)
),
ruleName: this.ruleName
})
},
deep: true
},
defaultListData: {
handler(arr) {
if (!isEmpty(arr)) {
// alert(this.customShow)
this.listData = arr?.map((it) => ({
...it,
ruleKey: `${it.ruleKey}`,
key: uid()
}))
console.log(this.listData,'this.listDatathis.listData')
}
},
deep: true,
immediate: true
}
},
data() {
return {
iscustomShow:false,
listData: [
{
ruleKey: '',
key: uid(),
relateType: relateTypeMap[this.ruleName]
}
]
}
},
methods: {
onAdd(tag) {
const newItems = {
ruleKey: '',
key: uid(),
relateType: relateTypeMap[this.ruleName]
}
this.listData.splice(tag + 1, 0, newItems)
},
onDel(index) {
this.listData.splice(index, 1)
},
isChose(row, tag) {
const listArr = this.listData?.filter((ot) => ot.ruleKey === row.value)
return !isEmpty(listArr)
}
}
}
</script>
<style lang="scss" scoped>
.common-title {
position: relative;
color: #222222;
line-height: 16px;
font-weight: 600;
font-size: 16px;
padding-left: 10px;
margin: 0 auto;
&::before {
position: absolute;
top: 50%;
transform: translatey(-50%);
left: 0;
content: '';
width: 3px;
background-color: #4886f8;
height: 16px;
border-radius: 2px;
}
}
.formObj-form-item {
display: flex;
align-items: center;
.operate-areas {
margin-left: 16px;
::v-deep .el-icon-circle-plus-outline {
color: #4886f8;
font-size: 20px;
}
::v-deep .el-icon-remove-outline {
font-size: 20px;
}
::v-deep .gray-color {
color: #999999;
}
}
.form-vl {
display: flex;
align-items: center;
span {
margin-right: 10px;
font-size: 14px;
color: #606266;
}
}
}
.main-wrap {
display: flex;
align-items: flex-start;
margin-bottom: 16px;
margin-top: 20px;
.rule-name-label {
width: 18%;
text-align: right;
padding-right: 24px;
line-height: 36px;
font-size: 14px;
font-weight: 400;
color: #3d3d3d;
&::after {
content: '*';
left: 5px;
color: #ff4d42;
position: relative;
top: 2px;
}
}
ul {
li {
margin-bottom: 10px;
&:last-child {
margin-bottom: 0;
}
}
}
}
.list-main{
position: relative;
.specialClass{
position: absolute;
left: -14px;
bottom: -51px;
color: #4886f8 !important;
display: flex;
align-items: center;
}
}
</style>

View File

@@ -0,0 +1,178 @@
<template>
<div>
<el-drawer
title=""
:visible.sync="drawerVisible"
direction="rtl"
size="45%"
:with-header="false"
:wrapperClosable="false"
>
<ImportCreateComponent ref="myRef"
:groupId="groupId"
:groupName="groupName"
:custType="custType"
@handOk="handOk"
/>
<section class="form-operate">
<el-button type="plain" size="small" @click="handleClose" style="margin-right:15px">取消</el-button>
<el-button type="primary" size="small" @click="handleSubmit">确定</el-button>
</section>
<el-drawer
title=""
:visible.sync="showTask"
width="30%"
:with-header="false"
direction="rtl"
:append-to-body="true"
:wrapperClosable="false"
>
<div class="child-main">
<p class="title">是否添加到已有任务?</p>
<el-form :model="formObj" :rules="formRules" ref="formObj" class="my-form">
<el-form-item label="" prop="task">
<el-select style="width: 300px" v-model="formObj.task" placeholder="请选择任务">
<el-option v-for="(item, index) in taskOptions" :key="index" :label="item.label"
:value="item.value"></el-option>
</el-select>
</el-form-item>
</el-form>
<span class="dialog-footer">
<el-button @click="onCancel" class="handle-btn">取消</el-button>
<!-- <el-button type="primary" @click="goToCreateTask" class="handle-btn">创建新任务</el-button> -->
<el-button type="primary" @click="onSubmit">确定</el-button>
</span>
</div>
</el-drawer>
</el-drawer>
</div>
</template>
<script>
import ImportCreateComponent from '../importCreateComponent/importCreate2.vue'
import { addToCurrentExistTask } from "@/api/system/grouplist";
import { Message } from 'element-ui'
export default {
props: ['drawerVisible','groupId','groupName','custType','taskOptions'],
// watch:{
// drawerVisible(value){
// this.showDrawer=value
// },
// },
data() {
return {
// showDrawer:false,
showTask:false,
// taskOptions:[
// {lable:'任务1',value:'1'},
// {lable:'任务2',value:'2'},
// {lable:'任务3',value:'3'},
// ],
formObj:{
task:''
},
formRules: {
task: [
{ required: true, message: '任务不能为空' },
]
},
custIds:[]
}
},
components: {
ImportCreateComponent
},
mounted() {
},
methods: {
// 添加客群到已选任务
addGroupsToExistTask(){
addToCurrentExistTask(params).then(res=>{
if(res.code == 200){
}
})
},
handleClose(){
this.$refs.myRef.handleMessageCancel2();
this.$emit('closeDrawer');
},
handleSubmit(){
this.$refs.myRef.handleSubmit();
},
handOk(arr){
this.showTask=true;
this.custIds = arr.map(item=>item.custId)
},
// 确定添加到任务
onSubmit() {
const that = this;
const params={
campaignIds:[this.formObj.task],
groupId:[this.groupId],
custIds:this.custIds
}
this.$refs.formObj.validate((valid) => {
if (valid) {
that.addGroupsToExistTask(params);
}
})
},
// 添加客群到已选任务
addGroupsToExistTask(params){
addToCurrentExistTask(params).then(res=>{
if(res.code == 200){
Message.success('添加成功');
this.closeTaskDialog();
}
})
},
// 取消添加到任务
closeTaskDialog(){
this.showTask=false;
this.formObj.task='';
this.$emit('closeDrawer','refresh');
this.handleClose();
},
// 取消添加到任务
onCancel(){
this.closeTaskDialog();
},
// 创建新任务
goToCreateTask(){
this.$router.push({
path: "/taskManage/taskCreation",
query: {
groupId:JSON.stringify([this.groupId]),
custType:this.custType
},
});
}
}
}
</script>
<style lang="scss" scoped>
.form-operate{
text-align: center;
margin-top: 30px;
}
.child-main{
padding: 40px 40px;
.my-form{
margin: 10px 0 30px 0;
}
.title{
font-size: 20px;
}
.dialog-footer{
text-align: center;
.handle-btn{
margin-right: 20px;
}
}
::v-deep .el-form-item__error{
margin-left: 70px;
}
}
</style>

View File

@@ -0,0 +1,84 @@
.common-wrap-cnt {
background-color: #ffffff;
overflow: hidden;
box-shadow: 0 3px 8px 0 #00000017;
border-radius: 16px 16px 0 0;
height: calc(100vh - 135px);
overflow-y: auto;
}
.tree-border {
max-height: 300px;
width: 100%;
overflow-y: auto;
}
.create-form-header {
display: flex;
justify-content: space-between;
height: 44px;
align-items: center;
border-bottom: 1px solid #ebebeb;
padding: 0 30px;
.form-title {
font-weight: 600;
font-size: 18px;
color: #222222;
letter-spacing: 0.5px;
line-height: 25px;
}
.form-operate {
}
}
.common-title {
position: relative;
color: #222222;
line-height: 16px;
font-weight: 600;
font-size: 16px;
padding-left: 10px;
margin: 0;
&::before {
position: absolute;
top: 50%;
transform: translatey(-50%);
left: 0;
content: '';
width: 3px;
background-color: #4886f8;
height: 16px;
border-radius: 2px;
}
}
.common-create-main {
padding: 24px 30px;
::v-deep .el-form {
width: 70%;
margin: 24px auto 0 auto;
.el-form-item {
margin-bottom: 16px;
.el-input__inner {
border: 1px solid #ebebeb;
color: #3d3d3d;
}
}
.el-form-item__label {
font-weight: 400;
line-height: 38px;
font-size: 14px;
color: #3d3d3d;
padding-right: 24px;
}
.is-required .el-form-item__label {
&::after {
content: '*';
left: 5px;
color: #ff4d42;
position: relative;
top: 2px;
}
&::before {
content: '';
}
}
}
}

View File

@@ -0,0 +1,56 @@
<template>
<div>
<!-- 个人 -->
<customerDetail-C v-if="isShowCompC" :rowC="rowC" :createRoleC="createRole" ></customerDetail-C>
<!-- 企业 -->
<customerDetail-B v-if="isShowCompB" :rowB="rowB" :createRoleB="createRole"></customerDetail-B>
<!-- 商户 -->
<customerDetail-M v-if="isShowCompM" :rowM="rowM" :createRoleM="createRole"></customerDetail-M>
</div>
</template>
<script>
import customerDetailC from './components/customerDetailC.vue'
import customerDetailB from './components/customerDetailB.vue'
import customerDetailM from './components/customerDetailM.vue'
export default {
data() {
return {
isShowCompB: false,
isShowCompM: false,
isShowCompC: false,
rowB: {},
rowC: {},
rowM: {},
createRole:''
}
},
components: {
customerDetailC,
customerDetailB,
customerDetailM
},
mounted() {
// console.log(this.$route.query.row,'this.$route.query.row')
this.createRole=this.$route.query.createRole;
// alert(this.createRole)
this.rowB = this.$route.query.row;
this.rowC = this.$route.query.row;
this.rowM = this.$route.query.row;
// console.log(row);
// this.row = row;
const custType =this.$route.query.custType;
if (custType == '0') {
this.isShowCompC = true;
} else if (custType == '1') {
this.isShowCompM = true;
}
else if(custType == '2') {
this.isShowCompB = true
}
},
methods: {
}
}
</script>

View File

@@ -0,0 +1,784 @@
<template>
<div class="app-container">
<!-- 筛选框 -->
<el-row :gutter="24" style="display: flex; align-items: center">
<el-col :span="4">
<!-- 客户号查询 -->
<el-input
v-model="custId"
placeholder="请输入客户号"
clearable
size="small"
@keyup.enter.native="getSelectCustomerData"
@clear="getSelectCustomerData"
prefix-icon="el-icon-search"
/>
</el-col>
<el-col :span="4">
<!-- 客户号查询 -->
<el-input
v-model="custName"
placeholder="请输入客户名称"
@clear="getSelectCustomerData"
@keyup.enter.native="getSelectCustomerData"
clearable
size="small"
prefix-icon="el-icon-search"
/>
</el-col>
<el-col :span="4">
<!-- 推送状态 -->
<el-select
v-model="pushStatus"
placeholder="请选择推送状态"
clearable
@clear="getSelectCustomerData"
@change="getSelectCustomerData"
style="width: 180px"
>
<el-option label="未推送" value="0"></el-option>
<el-option label="推送成功" value="1"></el-option>
<el-option label="推送失败" value="2"></el-option>
</el-select>
</el-col>
<el-col :span="12">
<el-button type="primary" @click="getSelectCustomerData"
>查询</el-button
>
<el-button type="info" @click="handleFilterClear">重置</el-button>
<el-button type="success" @click="handleCustAppoint"
>批量指定</el-button
>
<el-button type="warning" @click="exportDataByCustIds">导出</el-button>
<el-button @click="returnLastPage">返回上一级</el-button>
</el-col>
</el-row>
<!-- 表格区域 -->
<right-toolbar
:getSelectCustomerData.sync="getSelectCustomerData"
@queryTable="getSelectCustomerData"
:columns="columns"
></right-toolbar>
<el-table
:data="paginatedData"
style="width: 100%; margin-top: 20px"
ref="groupCustomerDetail"
@selection-change="handleSelectionChange"
>
<el-table-column
prop="groupId"
type="selection"
label="全选"
></el-table-column>
<el-table-column
prop="groupName"
align="center"
label="分群名称"
sortable
v-if="columns[0].visible"
></el-table-column>
<el-table-column
prop="custName"
align="center"
label="客户姓名"
sortable
v-if="columns[1].visible"
></el-table-column>
<el-table-column
prop="custId"
align="center"
label="客户号"
sortable
v-if="columns[2].visible"
></el-table-column>
<el-table-column
prop="custIdc"
align="center"
label="身份证号"
sortable
v-if="columns[3].visible"
></el-table-column>
<el-table-column
prop="pushStatus"
align="center"
label="推送状态"
sortable
v-if="columns[4].visible"
>
<template slot-scope="scope">
<span>
{{ handleStatus(scope.row.pushStatus) }}
</span>
</template>
</el-table-column>
<el-table-column
sortable
prop="deptName"
align="center"
label="归属机构"
v-if="isorgName&&columns[5].visible"
></el-table-column>
<el-table-column
sortable
prop="gridName"
align="center"
label="所属网格"
v-if="isgridName&&columns[6].visible"
></el-table-column>
<el-table-column
sortable
prop="userName"
align="center"
label="归属执行人"
v-if="isuserName&&columns[7].visible"
></el-table-column>
<!-- 其他列 -->
<el-table-column fixed="right" align="center" label="操作" width="100">
<template slot-scope="scope">
<el-button type="text" size="small" @click="handleCustAppointOne(scope.row.custId)"
>指定推送</el-button
>
</template>
</el-table-column>
</el-table>
<!-- 分页区域 -->
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:page-sizes="[10, 20, 30, 40]"
:page-size="pageSize"
layout="total,sizes,prev,pager,next,jumper"
:total="custTableData.length"
:current-page="currentPage"
></el-pagination>
<el-dialog title="选择机构/个人" :visible.sync="dialogVisible" width="30%">
<el-input
placeholder="请输入机构名称"
v-model="searchParams"
@keyup.enter.native="handleTreeSearch"
>
<template slot="append">
<el-button icon="el-icon-refresh" @click="resetSearch"></el-button>
</template>
</el-input>
<div class="roll-dialog">
<el-tree
class="tree-border"
:data="deptOptions"
show-checkbox
:check-strictly="true"
@check="handleCheckChange"
ref="deptTree"
node-key="id"
empty-text="加载中请稍候"
:props="defaultDeptProps"
:style="{ width: '100%' }"
></el-tree>
</div>
<span slot="footer">
<el-button @click="handleDialogCancle">取消</el-button>
<el-button type="primary" @click="handleConfigeInfo">确定</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import {
isHead,
findCustListByGroupId,
campaignDetail,
customerAppoint,
} from "@/api/system/findCustByGroupId.js";
import { getDeptTree, getDeptUserTree } from "@/api/grid/address/tree.js";
import { Message } from "element-ui";
export default {
data() {
return {
columns: [
{ key: 0, label: `分群名称`, visible: true },
{ key: 1, label: `客户姓名`, visible: true },
{ key: 2, label: `客户号`, visible: true },
{ key: 3, label: `身份证号`, visible: true },
{ key: 4, label: `推送状态`, visible: true },
{ key: 5, label: `归属机构`, visible: true },
{ key: 6, label: `归属网格`, visible: true },
{ key: 7, label: `归属执行人`, visible: true },
// { key: 7, label: `分群名称`, visible: true },
],
currentPage: 1,
userIds: [],
hasCheck: false,
userIds: [],
deptid: 0,
campaignId: "",
checkedDeptIds: [],
deptOptions: [],
filteredTreeData: [],
filterTreeData: [],
searchParams: "",
dialogVisible: false,
selectedRows: [],
custId: "",
groupId: "",
custTableData: [],
groupName: "",
custName: "",
pushStatus: "",
pageSize: 10,
pageNum: 1,
total: 0,
type:0,
deptName: "801000",
selectedIds: [],
executer: "",
children: [],
distributeType:0,
groupType: "",
isorgName: true,
isgridName: false,
isuserName: false,
isbranch: false,
isHead: false,
defaultDeptProps: {
children: "children",
label: "label",
disabled: (data) =>
!["head", "branch", "outlet", "user"].includes(data.level),
},
};
},
computed: {
paginatedData() {
const start = (this.pageNum - 1) * this.pageSize;
const end = start + this.pageSize;
return this.custTableData.slice(start, end);
},
},
mounted() {
const type = this.$route.query.type;
this.type=type;
const distributeType = this.$route.query.distributeType;
this.distributeType= distributeType;
isHead().then(res=> {
if (Object.keys(res)[0].startsWith("b")) {
this.createRole='1'
this.isbranch=true;
this.isHead=false;
}
if(Object.keys(res)[0].startsWith("h")) {
this.createRole='0'
this.isbranch=false;
this.isHead=true;
}
})
// this.handleLoadTreeData({deptid:'801010'})
const id = this.$route.query.groupId;
this.groupId = id;
const groupType = this.$route.query.groupType;
this.groupType = groupType;
const campaignId = this.$route.query.campaignId;
// console.log(groupType);
this.campaignId = campaignId;
campaignDetail({ campaignId }).then((res) => {
this.executer = res.executer;
if (this.executer == "0") {
this.isorgName = true;
this.isgridName = false;
this.isuserName = false;
}
if (this.executer == "1") {
this.isorgName = false;
this.isgridName = true;
this.isuserName = true;
}
if (this.executer == "2") {
this.isorgName = true;
this.isgridName = true;
this.isuserName = true;
}
});
const groupName = this.$route.query.groupName;
this.groupName = groupName;
this.getCustomerDetail(id, this.pageNum, this.pageSize, this.groupType);
},
methods: {
// //判断当前用户登录身份
// isUserType() {
// isHead().then((res) => {
// // console.log(Object.keys(res)[0].startsWith('h'));
// if (Object.keys(res)[0].startsWith("h")) {
// this.radiosButonIsDisableFromMe = false;
// this.radiosButonIsDisableToMe = true;
// this.createRole = "0";
// } else if (Object.keys(res)[0].startsWith("b")) {
// this.radiosButonIsDisableFromMe = false;
// this.radiosButonIsDisableToMe = false;
// this.createRole = "1";
// } else if (
// Object.keys(res)[0].startsWith("m") ||
// this.$store.getters.roles[0] == "admin"
// ) {
// this.radiosButonIsDisableFromMe = false;
// this.radiosButonIsDisableToMe = false;
// this.createRole = "2";
// } else {
// this.radiosButonIsDisableFromMe = false;
// this.radiosButonIsDisableToMe = false;
// }
// });
// },
handleDialogCancle() {
this.$refs.groupCustomerDetail.clearSelection();
this.dialogVisible = false;
this.dialogVisible = false;
},
handlenodeClick(data) {
console.log(data);
},
handleoneSend(row) {
this.$refs.groupCustomerDetail.toggleRowSelection(row, true);
},
handleConfigeInfo() {
if (this.isHead&&this.executer == 0) {
customerAppoint({
custIds: this.selectedIds.join(",")||this.custIds,
deptIds: this.checkedKeys.join(","),
groupId: this.groupId,
campaignId: this.campaignId,
createRole: this.createRole,
}).then((res) => {
// console.log(res);
if (res.code == "200") {
Message.success("推送成功");
// alert(1)
this.dialogVisible = false;
this.selectedRows.map((item) => {
return (item.pushStatus = "1");
});
this.$refs.groupCustomerDetail.clearSelection();
}
});
}
//推送到个人的情况
else if (this.isHead&&this.executer == 1) {
customerAppoint({
custIds: this.selectedIds.join(",")||this.custIds,
deptIds: "",
userIds: this.userIds.join(","),
groupId: this.groupId,
campaignId: this.campaignId,
createRole:this.createRole,
}).then((res) => {
// console.log(res);
if (res.code == "200") {
Message.success("推送成功");
// alert(2)
this.dialogVisible = false;
this.selectedRows.map((item) => {
return (item.pushStatus = "1");
});
this.$refs.groupCustomerDetail.clearSelection();
}
});
}else if(this.isbranch==true) {
customerAppoint({
custIds: this.selectedIds.join(",")||this.custIds,
deptIds: "",
userIds: this.userIds.join(","),
groupId: this.groupId,
campaignId: this.campaignId,
createRole: this.createRole,
}).then((res) => {
// console.log(res);
if (res.code == "200") {
Message.success("推送成功");
// alert(3)
this.dialogVisible = false;
this.selectedRows.map((item) => {
return (item.pushStatus = "1");
});
this.$refs.groupCustomerDetail.clearSelection();
}
});
}
else {
customerAppoint({
custIds: this.selectedIds.join(",")||this.custIds,
deptIds: this.checkedKeys.join(","),
userIds: this.userIds.join(","),
groupId: this.groupId,
campaignId: this.campaignId,
createRole: this.createRole,
}).then((res) => {
// console.log(res);
if (res.code == "200") {
Message.success("推送成功");
// alert(4)
this.dialogVisible = false;
this.selectedRows.map((item) => {
return (item.pushStatus = "1");
});
this.$refs.groupCustomerDetail.clearSelection();
}
});
}
},
exportDataByCustIds() {
// console.log(this.selectedRows);
if (this.selectedIds.length == 0) {
Message.warning("请先选择导出客户");
return;
}
const custIds = this.selectedRows.map((item) => {
return (item = item.custId);
});
this.download(
`/system/group/exportDataByCustIds/?groupId=${
this.groupId
}&custIds=${custIds.join(",")}`,
{},
`group_custIds_${new Date().getTime()}.xlsx`
);
this.$refs.groupCustomerDetail.clearSelection();
Message.success('导出成功')
},
handleCheckChange(data) {
console.log("this.executer======", this.executer,this.isbranch);
//判断身份
if(this.isbranch===true){
// this.hasCheck = true;
getDeptUserTree({ deptid: data.id }).then((res) => {
// this.hasCheck = true;
console.log("this.hasCheck======2", this.hasCheck);
this.children = res;
const tmp = this.children.map((item) => {
return {
key: item.userId,
id: item.userId,
label: item.userName,
children: [],
disabled: false,
level: "user",
};
});
data.children = tmp;
this.$refs.deptTree.updateKeyChildren(data.id, tmp);
// tmp.map(item => {
// const node = this.$refs.deptTree.getNode(item.key);
this.$refs.deptTree.$on("check", (node, checked) => {
// 在这里编写你的逻辑
if (checked) {
this.userIds.push(node.id);
// this.checkedKeys = this.checkedKeys.map((item) => {
// return item != node.id;
// });
// console.log(this.checkedKeys);
}
});
// })
// this.hasCheck = true;
});
console.log('43234234');
console.log("this.hasCheck======2", this.hasCheck);
this.children = res;
const tmp = this.children.map((item) => {
return {
key: item.userId,
id: item.userId,
label: item.userName,
children: [],
disabled: false,
level: "user",
};
});
data.children = tmp;
this.$refs.deptTree.updateKeyChildren(data.id, tmp);
// tmp.map(item => {
// const node = this.$refs.deptTree.getNode(item.key);
this.$refs.deptTree.$on("check", (node, checked) => {
// 在这里编写你的逻辑
if (checked) {
this.userIds.push(node.id);
// this.checkedKeys = this.checkedKeys.map((item) => {
// return item != node.id;
// });
// console.log(this.checkedKeys);
}
});
// })
// this.hasCheck = true;
}
if (this.executer == "0") {
this.checkedKeys = this.$refs.deptTree.getCheckedKeys();
}
// console.log(this.checkedKeys);
if(this.isbranch&&this.executer) {
// console.log("this.hasCheck======1", this.hasCheck);
// // if (this.hasCheck) return;
// console.log("1111111111111======");
getDeptUserTree({ deptid: data.id }).then((res) => {
// this.hasCheck = true;
console.log("this.hasCheck======2", this.hasCheck);
this.children = res;
const tmp = this.children.map((item) => {
return {
key: item.userId,
id: item.userId,
label: item.userName,
children: [],
disabled: false,
level: "user",
};
});
data.children = tmp;
this.$refs.deptTree.updateKeyChildren(data.id, tmp);
// tmp.map(item => {
// const node = this.$refs.deptTree.getNode(item.key);
this.$refs.deptTree.$on("check", (node, checked) => {
// 在这里编写你的逻辑
if (checked) {
this.userIds.push(node.id);
// this.checkedKeys = this.checkedKeys.map((item) => {
// return item != node.id;
// });
// console.log(this.checkedKeys);
}
});
// })
// this.hasCheck = true;
});
}
if (this.executer == "1") {
// console.log("this.hasCheck======1", this.hasCheck);
// // if (this.hasCheck) return;
// console.log("1111111111111======");
getDeptUserTree({ deptid: data.id }).then((res) => {
// this.hasCheck = true;
console.log("this.hasCheck======2", this.hasCheck);
this.children = res;
const tmp = this.children.map((item) => {
return {
key: item.userId,
id: item.userId,
label: item.userName,
children: [],
disabled: false,
level: "user",
};
});
data.children = tmp;
this.$refs.deptTree.updateKeyChildren(data.id, tmp);
// tmp.map(item => {
// const node = this.$refs.deptTree.getNode(item.key);
this.$refs.deptTree.$on("check", (node, checked) => {
// 在这里编写你的逻辑
if (checked) {
this.userIds.push(node.id);
// this.checkedKeys = this.checkedKeys.map((item) => {
// return item != node.id;
// });
// console.log(this.checkedKeys);
}
});
// })
// this.hasCheck = true;
});
}
if (this.executer == "2") {
this.checkedKeys = this.$refs.deptTree.getCheckedKeys();
console.log("this.checkkeys============", this.checkedKeys);
getDeptUserTree({ deptid: data.id }).then((res) => {
// this.hasCheck = true;
this.children = res;
const tmp = this.children.map((item) => {
return {
key: item.userId,
id: item.userId,
label: item.userName,
children: [],
disabled: false,
level: "user",
};
});
data.children = tmp;
this.$refs.deptTree.updateKeyChildren(data.id, tmp);
// tmp.map(item => {
// const node = this.$refs.deptTree.getNode(item.key);
this.$refs.deptTree.$on("check", (node, checked) => {
// 在这里编写你的逻辑
if (checked) {
this.userIds.push(node.id);
this.checkedKeys = this.checkedKeys.filter((item) => {
return item != node.id && item != undefined;
});
console.log(this.checkedKeys);
}
});
// })
// this.hasCheck = true;
});
}
},
resetSearch() {
this.searchParams = "";
this.getDeptTreeSelect();
},
handleTreeSearch() {
this.filterTreeData = this.filterTree(
this.deptOptions,
this.searchParams
);
if (this.searchParams) {
console.log(this.filterTreeData[0]);
this.deptOptions = this.filterTreeData[0].children;
}
getDeptTree();
},
filterTree(data, searchQuery) {
if (!searchQuery) {
return data;
}
const filteredData = data.filter((node) => {
// 检查当前节点的label是否包含搜索关键字
if (node.label.toLowerCase().includes(searchQuery.toLowerCase())) {
return true;
}
// 如果当前节点有子节点,则递归检查子节点
if (node.children && node.children.length > 0) {
const filteredChildren = this.filterTree(node.children, searchQuery);
// 如果子节点被过滤出来了,保留当前节点
if (filteredChildren.length > 0) {
node.children = filteredChildren;
return true;
}
}
// 如果当前节点不符合条件且没有符合条件的子节点,则不包含当前节点
return false;
});
return filteredData;
},
getDeptTreeSelect() {
getDeptTree().then((response) => {
// console.log(response)
this.deptOptions = response.data;
});
},
handleCustAppointOne(custId) {
// if(this.isbranch&& this.distributeType==null){
// Message.warning('请返回上一级,新建活动成功后才可指定推送!')
// this.$refs.groupCustomerDetail.clearSelection();
// return;
// }
// if(this.executer==null&&this.isHead==true&&!this.isbranch){
// Message.warning('请返回上一级,新建活动成功后才可指定推送!')
// this.$refs.groupCustomerDetail.clearSelection();
// return;
// }
this.dialogVisible = true;
this.custIds=custId
this.getDeptTreeSelect();
},
handleCustAppoint() {
if (this.selectedIds.length == 0) {
Message.warning("请先选择指定客户");
return;
}
if(this.executer==null&&!isHead){
Message.warning('请返回上一级,新建活动成功后才可指定推送!')
this.$refs.groupCustomerDetail.clearSelection();
return;
}
this.dialogVisible = true;
this.getDeptTreeSelect();
},
handleSelectionChange(selection) {
this.selectedRows = selection;
const selectedCustIds = this.selectedRows.map((item) => item.custId);
this.selectedIds = selectedCustIds;
},
returnLastPage() {
this.type==0?
this.$router.push({path:'/customer/customerbase/segmentation'}): this.$router.push({path:'/grid/visit/checklist'});
},
handleFilterClear() {
this.pushStatus = "";
this.custName = "";
this.custId = "";
this.getSelectCustomerData();
},
handleStatus(status) {
switch (status) {
case "0":
return "未推送";
case "1":
return "推送成功";
case "2":
return "推送失败";
}
},
// 分页
handleSizeChange(newSize) {
this.pageSize = newSize;
const id = this.$route.query.groupId;
const groupType = this.$route.query.groupType;
this.getCustomerDetail(id, groupType, this.currentPage, this.pageSize);
},
handleCurrentChange(newPage) {
this.pageNum = newPage;
const id = this.$route.query.groupId;
this.getCustomerDetail(
id,
this.currentPage,
this.pageSize,
this.groupType
);
},
getCustomerDetail(id, pageNum, pageSize, groupType) {
findCustListByGroupId({
groupId: id,
currentPage: pageNum,
pageSize: pageSize,
groupType: groupType,
}).then((res) => {
this.custTableData = res.rows;
this.total = res.total;
});
},
//筛选查询
getSelectCustomerData() {
findCustListByGroupId({
groupId: this.groupId,
custName: this.custName,
pushStatus: this.pushStatus[0],
custId: this.custId,
groupType: this.groupType,
}).then((res) => {
this.custTableData = res.rows;
this.total = res.total;
});
},
},
};
</script>
<style scoped>
.roll-dialog {
overflow: auto;
height: 600px;
}
</style>

View File

@@ -0,0 +1,484 @@
<template>
<div class="common-wrap-cnt">
<section class="create-form-header">
<p class="form-title">导入创建</p>
<section class="form-operate">
<el-button type="plain" size="small" @click="handleMessageCancel">重置</el-button>
<el-button type="primary" size="small" @click="handleSubmit">提交</el-button>
</section>
</section>
<section class="common-create-main">
<p class="common-title">文件上传</p>
<section class="file-upload">
<div class="file-upload-bg">
<div style=" display: flex;align-items: center;justify-content: center; height:50px;margin-top:25px">
<i class="el-icon-upload"></i>
</div>
<div class="file-upload-desc">仅允许导入xlsxlsx格式文件文件大小不超过10m</div>
<div class="file-upload-btn">
<el-upload class="custom-el-upload" style="display:inline-block" ref="upload" :on-change="handleFileChange"
:file-list="fileList" :auto-upload="false" :on-remove="handleRemove" action="#" accept=".xlsx, .xls">
<el-button type="primary" :disabled="iscustomType">上传文件</el-button>
</el-upload>
<el-button class="template" icon="el-icon-download" type='text' @click="handleCsvDownload">模板样例.xlsx</el-button>
</div>
<!-- <div class="file-upload-download">
<el-button icon="el-icon-download" type='text' @click="handleCsvDownload(2)" :disabled="isPrivate">企业模板下载</el-button>
<el-button icon="el-icon-download" type='text' @click="handleCsvDownload(1)" :disabled="isPublic">商户模板下载</el-button>
<el-button icon="el-icon-download" type='text' @click="handleCsvDownload(0)" :disabled="isPublic">个人模板下载</el-button>
</div> -->
<div class="file-upload-progress">
<el-progress v-show="progressFlag" style="width:70%" :percentage="loadProgress"></el-progress>
<el-button v-show="progressFlag" type="text" style="margin-left:20" @click="handleCsvPrase">预览</el-button>
</div>
</div>
<div class="group-input">
<span style="font-weight: 500">分群名称</span>
<el-input placeholder="请输入客群名称" style="width: 612px;margin-left:20px" v-model="groupName" clearable></el-input>
</div>
<div class="group-select">
<span style="font-weight: 400">客户类型</span>
<el-select v-model="custType" style="width: 612px;margin-left:20px" change="handSelect" clearable>
<el-option v-for="item in clientTypeOptions" :key="item.value" :label="item.label"
:value="item.value" :disabled="item.disabled"></el-option>
</el-select>
</div>
</section>
<section class="preview-cnt">
<p class="common-title">预览</p>
<section class="table-wrap preview-table">
<el-table :data="paginatedData" class="common-table-cnt">
<el-table-column v-for="(column, index) in columns" :key="index" :prop="column"
:label="column"></el-table-column>
<!-- <el-table-column prop="客户号" label="客户号" align="center"></el-table-column>
<el-table-column prop="客户内码" label="客户内码" align="center"></el-table-column>
<el-table-column prop="客户姓名*" label="客户姓名*" align="center"></el-table-column>
<el-table-column prop="证件号*" label="证件号*" align="center"></el-table-column>
<el-table-column prop="推送客户经理" label="推送客户经理" align="center"></el-table-column>
<el-table-column prop="推送网点" label="推送网点" align="center"></el-table-column> -->
</el-table>
<!-- 分页 -->
<el-pagination v-if="isPagination" @size-change="handleSizeChange" @current-change="handleCurrentChange"
:page-sizes="[10, 20, 30, 40]" :page-size="pageSize" layout="->,total,prev,pager,next,sizes"
:total="tableData.length" :current-page="currentPage"></el-pagination>
</section>
</section>
</section>
<!-- <div class="dialog-container">
<el-dialog :visible.sync="importVisible" title="" width="25%" class="dialog-header" center>
<div class="dialog-content">
<div class="group-text err-text">
<p>
这是一段报错信息...
</p>
</div>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="handleImportCancle"> </el-button>
<el-button type="primary" @click="exportErrData">
导出
</el-button>
</span>
</el-dialog>
</div> -->
</div>
</template>
<script>
import * as XLSX from "xlsx";
import { Message } from 'element-ui'
import { importData,downloadFile } from '@/api/system/importdata.js'
import { downloadFiles } from '@/utils'
import { mapGetters } from 'vuex'
// import axios from 'axios'
export default {
created() {
},
data() {
return {
isPagination: false,
columns: ["客户类型*", "客户名称", "客户号*", "推送机构号", "联系方式", "推送柜员号"],
iscustomType: false,
progressFlag: false,
loadProgress: 0,
file: null,
groupName: '',
jsonData: [],
tablekey: 0,
fileList: [],
tableData: [],
tableHeaders: [],
total: 0,
currentPage: 1,
pageSize: 10,
custType: "",
clientTypeOptions: [
{ value: "0", label: "个人" },
{ value: "1", label: "商户" },
{ value: "2", label: "企业" },
],
importVisible:false,
groupId:''
};
},
computed: {
...mapGetters(['roles']),
//对公
isPublic() {
return this.roles.includes('headPublic');
},
//对私
isPrivate() {
return this.roles.includes('headPrivate')
},
paginatedData() {
const start = (this.currentPage - 1) * this.pageSize;
const end = start + this.pageSize;
return this.tableData.slice(start, end);
},
},
created(){
if(this.isPrivate){
this.clientTypeOptions = this.clientTypeOptions.map(item=>{
return {
...item,
disabled:item.value == '2'
}
})
}
if(this.isPublic){
this.clientTypeOptions = this.clientTypeOptions.map(item=>{
return {
...item,
disabled:item.value != '2'
}
})
}
},
methods: {
handleMessageCancel() {
this.custType = '';
this.groupName = '';
this.tableData = [];
this.$refs.upload.clearFiles();
this.loadProgress = 0;
this.progressFlag = false;
Message.warning('取消提交!')
},
handleSubmit() {
const formData = new FormData();
if (this.groupName == '') {
Message.error('分群名称不能为空')
return;
}
if (this.custType == '') {
Message.error('客户类型未选择')
return;
}
if (this.$refs.upload.uploadFiles[0]?.raw == null) {
Message.error('请上传文件侯提交')
return;
}
formData.append('groupName', this.groupName.trim())
formData.append('file', this.$refs.upload.uploadFiles[0]?.raw)
formData.append('custType', this.custType)
formData.append('importType ','0')
importData(formData).then(res => {
if (res.code == 200) {
const {warningStr,notEmptyList} = res.data;
if(warningStr){
// const groupId = notEmptyList[0].groupId;
// this.goBackToCreateType(warningStr,groupId,this.groupName.trim())
Message.success(`导入成功,${warningStr}`)
}else{
Message.success('导入成功')
this.goBackToCreateType()
}
}
})
},
// 导入报错弹框取消
handleImportCancle() {
this.importVisible = false;
},
// 导出失败数据
exportErrData(){
this.download(
`/system/group/exportDataError/?groupId=${this.groupId
}`,
{},
`导入失败_${new Date().getTime()}.xlsx`
);
},
handleFileChange(file, fileList) {
//判断客户类型
if(file.size>10*1024*1000){
Message.warning('文件大小不能超过10m');
return;
}
this.file = file;
if (fileList.length > 0) {
this.fileList = [fileList[fileList.length - 1]]
}
if (file.status === 'ready') {
// alert(file.status)
this.progressFlag = true;
this.loadProgress = 0;
const interval = setInterval(() => {
if (this.loadProgress >= 100) {
// alert(this.subCustType)
clearInterval(interval)
return;
}
this.loadProgress += 1;
}, 20)
}
if (file.status == 'success') {
this.progressFlag = false;
this.loadProgress = 100;
}
},
handleSizeChange(newSize) {
this.pageSize = newSize;
},
handleCurrentChange(newPage) {
this.currentPage = newPage;
},
handleCsvColumns() {
if (!this.file) return;
const reader = new FileReader();
reader.onload = (e) => {
const data = e.target.result;
const workbook = XLSX.read(data, { type: "binary" });
const sheetName = workbook.SheetNames[0];
const worksheet = workbook.Sheets[sheetName];
const json_data = XLSX.utils.sheet_to_json(worksheet);
// this.columns = Object.keys(json_data[0]).map(item => {
// if (item.includes('商户')) {
// this.subCustType = 1
// return;
// }
// else if (item.includes('企业')) {
// this.subCustType = 2
// return;
// } else {
// this.subCustType = 0
// }
// })
};
reader.readAsBinaryString(this.file.raw);
},
handleCsvPrase() {
if (!this.file) return;
const reader = new FileReader();
reader.onload = (e) => {
const data = e.target.result;
const workbook = XLSX.read(data, { type: "binary" });
const sheetName = workbook.SheetNames[0];
const worksheet = workbook.Sheets[sheetName];
const json_data = XLSX.utils.sheet_to_json(worksheet);
// console.log(json_data,'json_data')
// this.columns = Object.keys(json_data[0]).map(item => {
// if (item.includes('证件类型(居民二代身份证/居民身份证/港澳居民来往内地通行证/台湾居民来往大陆通行证/外国人永久居留身份证)')) {
// return item = '证件类型'
// }
// return item;
// })
this.tableData = json_data.map(obj => {
// if (obj['证件类型(居民二代身份证/居民身份证/港澳居民来往内地通行证/台湾居民来往大陆通行证/外国人永久居留身份证)']) {
// obj['证件类型'] = obj['证件类型(居民二代身份证/居民身份证/港澳居民来往内地通行证/台湾居民来往大陆通行证/外国人永久居留身份证)']
// delete obj['证件类型(居民二代身份证/居民身份证/港澳居民来往内地通行证/台湾居民来往大陆通行证/外国人永久居留身份证)']
// }
let keys = Object.keys(obj);
let key1 = keys.find(i=>i.includes('客户类型'));
let key2 = keys.find(i=>i.includes('客户名称'));
let key3 = keys.find(i=>i.includes('推送机构号'));
return {
...obj,
'客户类型*':obj[key1],
'客户名称':obj[key2],
'推送机构号':obj[key3],
}
// for (let key in obj) {
// debugger
// if (key == '证件类型(居民二代身份证/居民身份证/港澳居民来往内地通行证/台湾居民来往大陆通行证/外国人永久居留身份证)') {
// obj['证件类型'] = obj[key];
// delete obj.key;
// }
// return obj
// }
}) || [];
this.isPagination = true
};
// console.log(this.columns,this.tableData)
reader.readAsBinaryString(this.file.raw);
},
goBackToCreateType(warningStr,groupId,groupName) {
this.$router.replace({
path:'/grid/create/segmentation',
// query: {
// refresh: true,
// warningStr,
// groupId
// }
})
if(warningStr){
this.$store.commit("SET_IMPORT_ERROR", {
warningStr,
groupId,
groupName
});
}
},
handleCsvDownload() {
let resultName = `模板_${new Date().getTime()}.xlsx`;
// if (type == 0) {
// // this.custType='0'
// resultName = `个人模板_${new Date().getTime()}.xlsx`
// }
// else if (type == 2) {
// // this.custType='2'
// resultName = `企业模板_${new Date().getTime()}.xlsx`
// }
// else {
// // this.custType='1'
// resultName = `商户模板_${new Date().getTime()}.xlsx`
// }
downloadFile('').then(res=>{
downloadFiles(res, resultName)
})
},
handleRemove() {
this.tableData = []
this.loadProgress = 0;
this.progressFlag = false
}
},
};
</script>
<style lang="scss" scoped>
@import './../create-style.scss';
.file-upload {
display: flex;
align-items: center;
flex-direction: column;
justify-content: space-between;
height: 320px;
.group-input {
width: 702px;
height: 288px;
margin-top: 25px;
}
.group-select {
width: 702px;
height: 288px;
margin-top: 25px;
}
.file-upload-bg {
width: 702px;
height: 288px;
background: #F7F8FA;
// display: flex;
// align-items: center;
// justify-content: center;
}
.el-icon-upload {
text-align: center;
font-size: 47.36px;
color: #CCCCCC;
}
.file-upload-desc {
font-weight: 400;
font-size: 14px;
color: #666666;
letter-spacing: 0;
text-align: center;
line-height: 12px;
margin-top: 8px;
}
.file-upload-btn {
display: flex;
align-items: center;
justify-content: center;
height: 50px;
margin-top: 20px;
::v-deep .el-upload-list{
display: none;
}
.template{
margin-left: 5px;
}
}
.file-upload-download {
display: flex;
align-items: center;
justify-content: center;
height: 20px;
margin-top: 15px;
font-size: 14px;
}
.file-upload-progress {
display: flex;
align-items: center;
justify-content: center;
height: 20px;
margin-top: 15px;
font-size: 14px;
}
}
.preview-table {
width: 100%;
margin-top: 16px;
}
.preview-cnt {
margin-top: 40px;
}
.chose-cnt {
::v-deep .el-form-item__content {
display: flex;
justify-content: space-between;
.el-button {
width: 88px;
margin-left: 24px;
}
.el-select {
flex: 1;
}
}
}
</style>

View File

@@ -0,0 +1,254 @@
<template>
<div>
<el-row>
<el-button
icon="el-icon-arrow-left"
@click="goBackToCreateType"
type="text"
style="margin: 20px 0 0 20px"
></el-button>
</el-row>
<el-row class="inputcontext">
<div>
<!-- 文件选择按钮 -->
<el-row :gutter="24">
<el-col :span="8">
<el-upload
class="custom-el-upload"
ref="upload"
:on-change="handleFileChange"
:file-list="fileList"
:auto-upload="false"
:on-remove="handleRemove"
action="#"
accept=".xlsx"
>
<el-button
icon="el-icon-upload"
type="primary"
style="margin-right: 20; margin-left: 20"
>上传文件</el-button
>
<!-- <input type="file" name="csvfile" ref="csvData" /> -->
<div slot="tip" class="el-upload-tip;" style="color: orange">
只支持xlsx文件上传限制10M
</div>
</el-upload>
</el-col>
<el-col :span="5"> <el-button
icon="el-icon-download"
@click="handleCsvDownload"
>模板下载</el-button
></el-col>
<el-col :span="4">
<el-button icon="el-icon-eye" style="margin-rignt:20" @click="handleCsvPrase"
>预览</el-button
></el-col
>
<el-col :span="3">
<el-button type="primary" @click="handleSubmit">提交</el-button>
</el-col>
<el-col :span="3"> <el-button @click="handleMessageCancel">重置</el-button></el-col>
</el-row>
</div>
</el-row>
<el-row class="inputcontext">
<!-- <el-col :span="2">
<span style="font-weight: bold">分群名称</span>
</el-col> -->
<el-col :span="8">
<span style="font-weight: bold">分群名称</span>
<el-input placeholder="请输入客群名称" style="width: 300px;margin-left:20px" v-model="groupName"></el-input>
</el-col>
</el-row>
<el-row class="inputcontext">
<!-- <el-col :span="2">
<span style="font-weight: bold">客户类型</span>
</el-col> -->
<el-col :span="8">
<span style="font-weight: bold">客户类型</span>
<el-select v-model="custType" style="width: 300px;margin-left:20px">
<el-option
v-for="item in clientTypeOptions"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-col>
</el-row>
<!-- <div>
<el-row class="inputcontext">
<el-button type="primary" @click="handleSubmit">提交</el-button>
<el-button @click="handleMessageCancel">重置</el-button>
</el-row>
</div> -->
<div style="margin-top: 50px">
<el-row class="yulan">预览</el-row>
<hr style="border-color: rgba(128, 128, 128, 0.2)" />
<el-row class="inputcontext">
<el-table :data="paginatedData" style="width: 80%" align="center">
<el-table-column prop="客户号" label="客户号" align="center"></el-table-column>
<el-table-column prop="客户内码" label="客户内码" align="center"></el-table-column>
<el-table-column prop="客户姓名" label="客户姓名" align="center"></el-table-column>
<el-table-column prop="证件号" label="证件号" align="center"></el-table-column>
<el-table-column prop="归属客户经理姓名" label="归属客户经理姓名" align="center"></el-table-column>
<el-table-column prop="归属网格名称" label="归属网格名称" align="center"></el-table-column>
</el-table>
</el-row>
<el-row>
<!-- 分页 -->
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:page-sizes="[10, 20, 30, 40]"
:page-size="pageSize"
layout="total,sizes,prev,pager,next,jumper"
:total="tableData.length"
:current-page="currentPage"
></el-pagination>
</el-row>
</div>
<!-- 分页 -->
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:page-sizes="[10, 20, 30, 40]"
:page-size="pageSize"
layout="total,sizes,prev,pager,next,jumper"
:total="tableData.length"
:current-page="currentPage"
></el-pagination>
</div>
</template>
<script>
import * as XLSX from "xlsx";
import {Message} from 'element-ui'
import {importData} from '@/api/system/importdata.js'
// import axios from 'axios'
export default {
data() {
return {
file: null,
groupName:'',
jsonData: [],
tablekey: 0,
fileList: [],
tableData: [],
tableHeaders: [],
total: 0,
currentPage: 1,
pageSize: 10,
custType: "",
clientTypeOptions: [
{ value: "0", label: "个人" },
{ value: "1", label: "商户" },
{ value: "2", label: "企业" },
],
};
},
computed: {
paginatedData() {
const start = (this.currentPage - 1) * this.pageSize;
const end = start + this.pageSize;
return this.tableData.slice(start, end);
},
},
methods: {
handleMessageCancel() {
this.custType='';
this.groupName='';
this.tableData=[];
this.$refs.upload.clearFiles();
Message.warning('取消提交!')
},
handleSubmit() {
const formData = new FormData();
if(this.groupName=='') {
Message.error('分群名称不能为空')
return;
}
if(this.custType=='') {
Message.error('客户类型未选择')
return;
}
if(this.$refs.upload.uploadFiles[0]?.raw==null) {
Message.error('请上传文件侯提交')
return;
}
formData.append('groupName',this.groupName)
formData.append('file',this.$refs.upload.uploadFiles[0]?.raw)
formData.append('custType',this.custType)
importData(formData).then(res => {
if(res.msg=='导入客群创建成功'){
Message.success('添加成功')
this.goBackToCreateType()
}
})
},
handleFileChange(file) {
this.file = file;
},
handleSizeChange(newSize) {
this.pageSize = newSize;
},
handleCurrentChange(newPage) {
this.currentPage = newPage;
},
handleCsvPrase() {
if (!this.file) return;
const reader = new FileReader();
reader.onload = (e) => {
const data = e.target.result;
const workbook = XLSX.read(data, { type: "binary" });
const sheetName = workbook.SheetNames[0];
const worksheet = workbook.Sheets[sheetName];
const json_data = XLSX.utils.sheet_to_json(worksheet);
this.tableData = json_data;
};
reader.readAsBinaryString(this.file.raw);
},
goBackToCreateType() {
this.$router.replace({
path: this.$router.go(-1),
query: {
refresh:true
}
})
},
handleCsvDownload() {
this.download(
"/system/group/download",
{},
`customer_template_${new Date().getTime()}.xlsx`
);
},
handleRemove() {
this.tableData=[]
}
},
};
</script>
<style scoped>
.inputcontext {
display: flex;
align-items: center;
justify-content: center;
padding: 10px;
}
.yulan {
margin-left: 20px;
font-weight: bold;
}
.custom-el-upload {
margin-right: 20px;
}
</style>

View File

@@ -0,0 +1,427 @@
<template>
<div class="common-wrap-cnt">
<section class="common-create-main">
<!-- <p class="common-title">文件上传</p> -->
<section class="file-upload">
<div class="file-upload-bg">
<!-- <div style=" display: flex;align-items: center;justify-content: center; height:50px;margin-top:25px">
<i class="el-icon-upload"></i>
</div> -->
<div class="file-upload-btn">
<el-upload class="custom-el-upload" style="display:inline-block" ref="upload" :on-change="handleFileChange"
:file-list="fileList" :auto-upload="false" :on-remove="handleRemove" action="#" accept=".xlsx,.xls">
<el-button type="primary" :disabled="iscustomType">上传文件</el-button>
</el-upload>
<el-button class="template" icon="el-icon-download" type='text' @click="handleCsvDownload">模板样例.xlsx</el-button>
</div>
<div class="file-upload-desc">请上传xlsxlsx文件,大小在10M以内</div>
<!-- <div class="file-upload-download">
<el-button icon="el-icon-download" type='text' @click="handleCsvDownload(2)">企业模板下载</el-button>
<el-button icon="el-icon-download" type='text' @click="handleCsvDownload(1)">商户模板下载</el-button>
<el-button icon="el-icon-download" type='text' @click="handleCsvDownload(0)">个人模板下载</el-button>
</div> -->
<div class="file-upload-progress">
<el-progress v-show="progressFlag" style="width:70%" :percentage="loadProgress"></el-progress>
<el-button v-show="progressFlag" type="text" style="margin-left:20" @click="handleCsvPrase">预览</el-button>
</div>
</div>
<div class="group-input">
<span style="font-weight: 500">分群名称</span>
<el-input placeholder="请输入客群名称" style="width: 612px;margin-left:20px" v-model="groupName" disabled></el-input>
</div>
<div class="group-select">
<span style="font-weight: 400">客户类型</span>
<el-select v-model="custType" style="width: 612px;margin-left:20px" change="handSelect" disabled>
<el-option v-for="item in clientTypeOptions" :key="item.value" :label="item.label"
:value="item.value"></el-option>
</el-select>
</div>
</section>
<section class="preview-cnt">
<p class="common-title">预览</p>
<section class="table-wrap preview-table">
<el-table :data="paginatedData" class="common-table-cnt">
<el-table-column v-for="(column, index) in columns" :key="index" :prop="column"
:label="column" show-overflow-tooltip></el-table-column>
<!-- <el-table-column prop="客户号" label="客户号" align="center"></el-table-column>
<el-table-column prop="客户内码" label="客户内码" align="center"></el-table-column>
<el-table-column prop="客户姓名*" label="客户姓名*" align="center"></el-table-column>
<el-table-column prop="证件号*" label="证件号*" align="center"></el-table-column>
<el-table-column prop="推送客户经理" label="推送客户经理" align="center"></el-table-column>
<el-table-column prop="推送网点" label="推送网点" align="center"></el-table-column> -->
</el-table>
<!-- 分页 -->
<el-pagination v-if="isPagination" @size-change="handleSizeChange" @current-change="handleCurrentChange"
:page-sizes="[10, 20, 30, 40]" :page-size="pageSize" layout="->,total,prev,pager,next,sizes"
:total="tableData.length" :current-page="currentPage"></el-pagination>
</section>
</section>
</section>
</div>
</template>
<script>
import * as XLSX from "xlsx";
import { Message } from 'element-ui'
import { importData,downloadFile } from '@/api/system/importdata.js'
import { downloadFiles } from '@/utils'
// import axios from 'axios'
export default {
props: ['groupId','groupName','custType'],
data() {
return {
isPagination: false,
columns: ["客户类型*", "客户名称", "客户号*", "推送机构号", "联系方式", "推送柜员号"],
iscustomType: false,
progressFlag: false,
loadProgress: 0,
file: null,
// groupName: '',
jsonData: [],
tablekey: 0,
fileList: [],
tableData: [],
tableHeaders: [],
total: 0,
currentPage: 1,
pageSize: 10,
// custType: "",
clientTypeOptions: [
{ value: "0", label: "个人" },
{ value: "1", label: "商户" },
{ value: "2", label: "企业" },
],
};
},
computed: {
paginatedData() {
const start = (this.currentPage - 1) * this.pageSize;
const end = start + this.pageSize;
return this.tableData.slice(start, end);
},
},
created() {
},
methods: {
handleMessageCancel() {
this.custType = '';
this.groupName = '';
this.tableData = [];
this.$refs.upload.clearFiles();
this.loadProgress = 0;
this.progressFlag = false;
Message.warning('取消提交!')
},
handleMessageCancel2() {
// this.custType = '';
// this.groupName = '';
this.tableData = [];
this.$refs.upload.clearFiles();
this.loadProgress = 0;
// this.columns=[];
this.progressFlag = false;
},
handleSubmit() {
const formData = new FormData();
if (this.groupName == '') {
Message.error('分群名称不能为空')
return;
}
if (this.custType == '') {
Message.error('客户类型未选择')
return;
}
if (this.$refs.upload.uploadFiles[0]?.raw == null) {
Message.error('请上传文件侯提交')
return;
}
// formData.append('groupName', this.groupName.trim())
formData.append('file', this.$refs.upload.uploadFiles[0]?.raw)
formData.append('custType', this.custType)
formData.append('importType ','1')
formData.append('groupId ',this.groupId)
importData(formData).then(res => {
if (res.code == 200) {
const {warningStr,notEmptyList} = res.data;
if(warningStr){
const newArr = notEmptyList.filter(item=>item.pushStatus == '1')
// console.log(newArr)
if(!newArr.length){
Message.warning(`导入成功,${warningStr},没有可以进一步添加的客户`);
}else{
Message.warning(`导入成功,${warningStr},存在可以进一步添加的客户`);
setTimeout(()=>{
this.$emit('handOk',newArr || [])
},300)
}
}else{
Message.success('导入成功')
this.$emit('handOk',notEmptyList || [])
}
}
})
},
handleFileChange(file, fileList) {
//判断客户类型
if(file.size>10*1024*1000){
Message.warning('文件大小不能超过10m');
return;
}
this.file = file;
if (fileList.length > 0) {
this.fileList = [fileList[fileList.length - 1]]
}
if (file.status === 'ready') {
// alert(file.status)
this.progressFlag = true;
this.loadProgress = 0;
const interval = setInterval(() => {
if (this.loadProgress >= 100) {
// alert(this.subCustType)
clearInterval(interval)
return;
}
this.loadProgress += 1;
}, 20)
}
if (file.status == 'success') {
this.progressFlag = false;
this.loadProgress = 100;
}
},
handleSizeChange(newSize) {
this.pageSize = newSize;
},
handleCurrentChange(newPage) {
this.currentPage = newPage;
},
handleCsvColumns() {
if (!this.file) return;
const reader = new FileReader();
reader.onload = (e) => {
const data = e.target.result;
const workbook = XLSX.read(data, { type: "binary" });
const sheetName = workbook.SheetNames[0];
const worksheet = workbook.Sheets[sheetName];
const json_data = XLSX.utils.sheet_to_json(worksheet);
// this.columns = Object.keys(json_data[0]).map(item => {
// if (item.includes('商户')) {
// this.subCustType = 1
// return;
// }
// else if (item.includes('企业')) {
// this.subCustType = 2
// return;
// } else {
// this.subCustType = 0
// }
// })
};
reader.readAsBinaryString(this.file.raw);
},
handleCsvPrase() {
if (!this.file) return;
const reader = new FileReader();
reader.onload = (e) => {
const data = e.target.result;
const workbook = XLSX.read(data, { type: "binary" });
const sheetName = workbook.SheetNames[0];
const worksheet = workbook.Sheets[sheetName];
const json_data = XLSX.utils.sheet_to_json(worksheet);
// console.log(json_data,'json_data')
// this.columns = Object.keys(json_data[0]).map(item => {
// if (item.includes('证件类型(居民二代身份证/居民身份证/港澳居民来往内地通行证/台湾居民来往大陆通行证/外国人永久居留身份证)')) {
// return item = '证件类型'
// }
// return item;
// })
this.tableData = json_data.map(obj => {
// if (obj['证件类型(居民二代身份证/居民身份证/港澳居民来往内地通行证/台湾居民来往大陆通行证/外国人永久居留身份证)']) {
// obj['证件类型'] = obj['证件类型(居民二代身份证/居民身份证/港澳居民来往内地通行证/台湾居民来往大陆通行证/外国人永久居留身份证)']
// delete obj['证件类型(居民二代身份证/居民身份证/港澳居民来往内地通行证/台湾居民来往大陆通行证/外国人永久居留身份证)']
// }
let keys = Object.keys(obj);
let key1 = keys.find(i=>i.includes('客户类型'));
let key2 = keys.find(i=>i.includes('客户名称'));
let key3 = keys.find(i=>i.includes('推送机构号'));
return {
...obj,
'客户类型*':obj[key1],
'客户名称':obj[key2],
'推送机构号':obj[key3],
}
// for (let key in obj) {
// debugger
// if (key == '证件类型(居民二代身份证/居民身份证/港澳居民来往内地通行证/台湾居民来往大陆通行证/外国人永久居留身份证)') {
// obj['证件类型'] = obj[key];
// delete obj.key;
// }
// return obj
// }
}) || [];
this.isPagination = true
console.log(this.tableData)
};
reader.readAsBinaryString(this.file.raw);
},
goBackToCreateType() {
this.$router.replace({
path: this.$router.go(-1),
query: {
refresh: true
}
})
},
handleCsvDownload() {
let resultName=`模板_${new Date().getTime()}.xlsx`;
// if (this.custType == '0') {
// // this.custType='0'
// resultName = `个人模板_${new Date().getTime()}.xlsx`
// }
// else if (this.custType == '2') {
// // this.custType='2'
// resultName = `企业模板_${new Date().getTime()}.xlsx`
// }
// else {
// // this.custType='1'
// resultName = `商户模板_${new Date().getTime()}.xlsx`
// }
downloadFile('').then(res=>{
downloadFiles(res, resultName)
})
},
handleRemove() {
this.tableData = []
this.loadProgress = 0;
this.progressFlag = false
}
},
};
</script>
<style lang="scss" scoped>
@import './../create-style.scss';
.file-upload {
display: flex;
align-items: center;
flex-direction: column;
justify-content: space-between;
height: 320px;
.group-input {
width: 702px;
height: 120px;
// margin-top: 25px;
}
.group-select {
width: 702px;
height: 120px;
// margin-top: 25px;
}
.file-upload-bg {
// width: 702px;
height: 288px;
// background: #F7F8FA;
// display: flex;
// align-items: center;
// justify-content: center;
}
.el-icon-upload {
text-align: center;
font-size: 47.36px;
color: #CCCCCC;
}
.file-upload-desc {
font-weight: 400;
font-size: 12px;
color: #666666;
letter-spacing: 0;
// text-align: center;
line-height: 12px;
// margin-top: 8px;
}
.file-upload-btn {
display: flex;
align-items: center;
justify-content: center;
height: 50px;
margin-top: 20px;
::v-deep .el-upload-list{
display: none;
}
.template{
margin-left: 5px;
}
}
.file-upload-download {
display: flex;
align-items: center;
justify-content: center;
height: 20px;
margin-top: 15px;
font-size: 14px;
}
.file-upload-progress {
display: flex;
align-items: center;
justify-content: center;
height: 20px;
margin-top: 15px;
font-size: 14px;
}
}
.preview-table {
width: 100%;
margin-top: 16px;
}
.preview-cnt {
margin-top: 10px;
}
.chose-cnt {
::v-deep .el-form-item__content {
display: flex;
justify-content: space-between;
.el-button {
width: 88px;
margin-left: 24px;
}
.el-select {
flex: 1;
}
}
}
.form-operate{
text-align: center;
}
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,651 @@
<template>
<div>
<el-row class="title">
<el-col>
<el-button
type="primary"
icon="el-icon-plus"
@click="showCreateDialog = true"
>创建分群</el-button
>
</el-col>
<el-col>
<el-radio-group
class="title"
v-model="selectedTab"
@change="handleTabChange"
>
<el-radio-button
label="我创建的"
:disabled="radiosButonIsDisableFromMe"
>我创建的</el-radio-button
>
<el-radio-button
label="推荐给我的"
:disabled="radiosButonIsDisableToMe"
>推荐给我的</el-radio-button
>
</el-radio-group>
</el-col>
<el-col style="display: flex">
<el-input
v-model="searchQuery"
placeholder="输入分群名称"
clearable
@clear="handSearch"
@keyup.enter.native="handSearch"
></el-input>
<el-button icon="el-icon-search" @click="handSearch"></el-button>
</el-col>
</el-row>
<el-dialog
:visible.sync="showCreateDialog"
title="怎样创建分群?"
width="30%"
>
<div class="dialog-content">
<el-row>
<el-button>规则创建</el-button>
<el-button type="primary" @click="handleImport">导入创建</el-button>
</el-row>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="() => {showCreateDialog = false;this.getList();this.campaignId=''}">取消</el-button>
</span>
</el-dialog>
<div v-if="!isCreatePag">
<right-toolbar :handSearch.sync="handSearch" @queryTable="getList" :columns="columns"></right-toolbar>
<el-table :data="paginatedData" style="width: 100%">
<el-table-column prop="groupName" label="分群名称" sortable v-if="columns[0].visible"></el-table-column>
<el-table-column prop="custType" label="客户类型" sortable v-if="columns[1].visible">
<template slot-scope="scope">
<span v-if="scope.row.custType==0">个人</span>
<span v-if="scope.row.custType==1">企业</span>
<span v-if="scope.row.custType==2">商户</span>
</template>
</el-table-column>
<el-table-column prop="customerNum" label="人数" sortable v-if="columns[2].visible"></el-table-column>
<el-table-column prop="createType" label="创建方式" sortable v-if="columns[3].visible"></el-table-column>
<el-table-column prop="createBy" label="创建者" sortable v-if="columns[4].visible"></el-table-column>
<el-table-column prop="updateType" label="更新方法" sortable v-if="columns[5].visible"></el-table-column>
<el-table-column prop="status" label="状态" sortable v-if="columns[6].visible"></el-table-column>
<el-table-column
sortable
prop="updateTime"
label="最近更新时间"
v-if="columns[7].visible"
></el-table-column>
<el-table-column prop="operate" label="操作" align="center">
<template slot-scope="scope">
<el-button
type="text"
@click="
handleCustDetail(
scope.row.groupId,
scope.row.groupName,
scope.row.campaignId,
scope.row.groupType,
'0',
scope.row.distributeType
)
"
>查看</el-button
>
<!-- <a href="#" @click.prevent="importIn">导入</a> -->
<el-button
type="text"
@click="handleGroupCustExport(scope.row.groupId)"
>导出</el-button
>
<!-- <a href="#" @click.prevent="recommend">推荐</a> -->
<el-button
type="text"
:disabled="isHeader&&scope.row.createRole==1?true:false"
@click="
handlePushGroupCustomer(
scope.row.groupName,
scope.row.groupId,
scope.row.campaignId
)
"
>推送</el-button
>
</template>
</el-table-column>
</el-table>
<el-row>
<!-- 分页 -->
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:page-sizes="[10, 20, 30, 40]"
:page-size="pageSize"
layout="total,sizes,prev,pager,next,jumper"
:total="groupTable.length"
:current-page="currentPage"
></el-pagination>
</el-row>
</div>
<el-empty v-if="showmap" description="总行管理员无需推荐..." />
<!-- 添加或修改用户配置对话框 -->
<el-dialog
:title="pushTitle"
:visible.sync="pushOpen"
width="600px"
append-to-body
>
<el-form
ref="pushform"
:model="pushform"
:rules="pushroles"
label-width="80px"
:disabled="ispushformread"
>
<el-row>
<el-col :span="24">
<el-form-item label="分群名称" prop="groupName">
<el-input
v-model="pushform.groupName"
:disabled="true"
maxlength="30"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="活动名称" prop="campaignName">
<el-input
v-model="pushform.campaignName"
placeholder="请输入活动名称"
maxlength="30"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="活动类型" prop="campaignType" style="flex: 1">
<el-select
v-model="pushform.campaignType"
placeholder="请选择活动类型"
width="100%"
>
<el-option label="走访" value="走访"></el-option>
<el-option label="电话" value="电话"></el-option>
<el-option label="短信" value="短信"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item
label="紧急程度"
prop="campaignDegree"
style="flex: 1"
>
<el-select
v-model="pushform.campaignDegree"
placeholder="请选择紧急程度"
>
<el-option label="高" value="高"></el-option>
<el-option label="中" value="中"></el-option>
<el-option label="低" value="低"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="认领类型" prop="claimType" style="flex: 1">
<el-select
v-model="pushform.claimType"
placeholder="请选择认领类型"
width="100%"
>
<el-option label="强制认领" value="0"></el-option>
<el-option label="可选认领" value="1"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<!-- 活动时间 -->
<el-col :span="24">
<el-form-item label="活动时间" prop="dateRange" style="flex: 1">
<el-date-picker
width="100%"
v-model="pushform.dateRange"
type="daterange"
range-separator=""
start-placeholder="开始日期"
end-placeholder="结束日期"
>
</el-date-picker>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item
label="认领时间"
prop="claimdateRange"
style="flex: 1"
>
<el-date-picker
width="100%"
v-model="pushform.claimdateRange"
type="daterange"
range-separator=""
start-placeholder="开始日期"
end-placeholder="结束日期"
>
</el-date-picker>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="执行人" prop="executer" v-if="isHeader" style="flex: 1">
<el-radio-group v-model="pushform.executer" width="100%">
<el-radio label="0">机构</el-radio>
<el-radio label="1">个人</el-radio>
<el-radio label="2">混合分配</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item
label="分配规则"
prop="distributeType"
style="flex: 1"
>
<el-radio-group v-model="pushform.distributeType" width="100%">
<el-radio label="0">手动指定</el-radio>
<el-radio label="1">按照客户归属机构</el-radio>
<el-radio label="2">按照地址归属</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" :disabled="ispushformread" @click="handleInfoSubmit"> </el-button>
<el-button
@click="
() => {
this.pushOpen = false;
this.getList()
}
"
> </el-button
>
</div>
</el-dialog>
</div>
</template>
<script>
import { groupList, exportData } from "@/api/system/grouplist";
import { isHead, campaignDetail } from "@/api/system/findCustByGroupId.js";
import { campaignAdd } from "@/api/system/campaign.js";
import { Message } from "element-ui";
export default {
data() {
return {
isPushBtn:false,
columns: [
{ key: 0, label: `分群名称`, visible: true },
{ key: 1, label: `客户类型`, visible: true },
{ key: 2, label: `人数`, visible: true },
{ key: 3, label: `创建方式`, visible: true },
{ key: 4, label: `创建者`, visible: true },
{ key: 5, label: `更新方法`, visible: true },
{ key: 6, label: `状态`, visible: true },
{ key: 7, label: `最近更新时间`, visible: true },
],
pushOpen: false,
isHeader: false,
pushroles: {
groupName: [
{ required: true, message: "分群名称不能为空" },
{
min: 2,
max: 20,
message: "分群名称长度必须介于 2 和 20 之间",
},
],
campaignName: [
{ required: true, message: "活动名称不能为空"},
{
min: 2,
max: 20,
message: "活动名称长度必须介于 2 和 20 之间",
},
],
campaignType: [{ required: true, message: "请选择活动类型" }],
campaignDegree: [{ required: true, message: "请选择紧急程度" }],
claimType: [{ required: true, message: "请选择认领类型" }],
dateRange: [{ required: true, message: "请选择活动时间" }],
claimdateRange: [{ required: true, message: "请选择认领时间" }],
executer: [{ required: true, message: "请选择执行人" }],
distributeType: [{ required: true, message: "请选择分配规则" }],
},
pushform: {
groupName: "",
claimType: "",
campaignDegree: "",
campaignType: "",
campaignName: "",
executer: {},
distributeType: {},
claimdateRange: [],
dateRange: [],
},
pushOpen: false,
pushTitle: "创建活动",
radiosButonIsDisableFromMe: false,
radiosButonIsDisableToMe: false,
userType: "0",
showmap: false,
total: 0,
pageSize: 10,
currentPage: 1,
isCreatePag: false,
groupFlag: "1",
groupTable: [],
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
selectedTab: "我创建的",
searchQuery: "",
showCreateDialog: false,
selectedCreateType: "",
isCreatePage: false,
tableData: [],
groupId: "",
createRole: "",
campaignId: "",
ispushformread: false,
pushformDetail: {},
};
},
computed: {
filteredTableData() {
if (this.searchQuery) {
return this.groupTable.filter((item) =>
item.groupName.includes(this.searchQuery)
);
}
return this.groupTable;
},
},
created() {
// this.$router.go(0)
this.isUserType();
this.getList();
},
mounted() {
if (this.$router.query.refresh) {
this.$router.go(0);
}
},
computed: {
paginatedData() {
const start = (this.currentPage - 1) * this.pageSize;
const end = start + this.pageSize;
return this.groupTable.slice(start, end);
},
},
methods: {
parseFormattedDate(formattedDateString) {
const isoDateString = formattedDateString.replace(" ", "T");
const date = new Date(isoDateString);
if (isNaN(date.getTime())) {
return null;
}
return date;
},
formatDate(dateString) {
const date = new Date(dateString);
return date.toISOString().slice(0, 19).replace("T", " ");
},
handleInfoSubmit() {
this.isPushBtn = false;
this.$refs["pushform"].validate((valid) => {
if (valid) {
let startTime = this.formatDate(this.pushform.dateRange[0]);
let endTime = this.formatDate(this.pushform.dateRange[1]);
let claimStartTime = this.formatDate(this.pushform.claimdateRange[0]);
let claimEndTime = this.formatDate(this.pushform.claimdateRange[1]);
let queryParams = {};
queryParams.startTime = startTime;
queryParams.endTime = endTime;
queryParams.claimStartTime = claimStartTime;
queryParams.claimEndTime = claimEndTime;
queryParams.groupId = this.groupId;
queryParams.campaignName = this.pushform.campaignName;
queryParams.campaignType = this.pushform.campaignType;
queryParams.campaignDegree = this.pushform.campaignDegree;
queryParams.executer = this.pushform.executer;
queryParams.distributeType = this.pushform.distributeType;
queryParams.claimType = this.pushform.claimType;
queryParams.createRole = this.createRole;
campaignAdd(queryParams).then((res) => {
if (res.code == "200") {
Message.success(`分群${this.pushform.groupName}活动创建成功!`);
this.getList()
this.pushOpen = false;
//将执行人类型传给详情
// this.$router.push({ path: '/groupBase/customerDetail', query: { executer:this.pushform.executer} })
}
});
} else {
console.error("新增失败", error);
}
});
},
handlePushGroupCustomer(groupName, groupId, campaignId) {
// console.log(campaignId);
this.getList()
this.pushOpen = true;
this.pushform.groupName = groupName;
this.groupId = groupId;
// this.campaignId = campaignId;
if( campaignId===null) {
this.$nextTick(()=> {
this.$refs.pushform.resetFields()
})
// this.pushform={};
this.pushform.groupName = groupName;
// this.pushform.pushroles={};
this.ispushformread = false;
// return;
// return;
// this.pushform.campaignName ='';
// this.pushform.campaignDegree = '';
// this.pushform.campaignType ='';
// this.pushform.executer = '';
// this.pushform.distributeType = '';
// this.pushform.claimType = '';
// this.pushform.dateRange = [];
// this.pushform.claimdateRange = [];
}else{
campaignDetail({ campaignId: campaignId}).then((res) => {
this.pushformDetail = res;
if (this.campaignId!=null) {
this.ispushformread = true;
if (this.ispushformread) {
this.pushform.campaignName = this.pushformDetail.campaignName;
this.pushform.campaignDegree = this.pushformDetail.campaignDegree;
this.pushform.campaignType = this.pushformDetail.campaignType;
this.pushform.executer = this.pushformDetail.executer;
this.pushform.distributeType = this.pushformDetail.distributeType;
this.pushform.claimType = this.pushformDetail.claimType;
this.pushform.dateRange = [
this.parseFormattedDate(this.pushformDetail.startTime),
this.parseFormattedDate(this.pushformDetail.endTime),
];
this.pushform.claimdateRange = [
this.parseFormattedDate(this.pushformDetail.claimStartTime),
this.parseFormattedDate(this.pushformDetail.claimEndTime),
];
}
}
});
}
},
handleGroupCustExport(groupId) {
this.download(
`/system/group/exportData/?groupId=${groupId}`,
{},
`group_customer_${new Date().getTime()}.xlsx`
);
},
//判断当前用户登录身份
isUserType() {
isHead().then((res) => {
// console.log(Object.keys(res)[0].startsWith('h'));
if (Object.keys(res)[0].startsWith("h")) {
this.radiosButonIsDisableFromMe = false;
this.radiosButonIsDisableToMe = true;
this.createRole = "0";
this.isHeader=true;
} else if (Object.keys(res)[0].startsWith("b")) {
this.radiosButonIsDisableFromMe = false;
this.radiosButonIsDisableToMe = false;
this.createRole = "1";
this.isHeader=false;
} else if (
Object.keys(res)[0].startsWith("m") ||
this.$store.getters.roles[0] == "admin"
) {
this.radiosButonIsDisableFromMe = false;
this.radiosButonIsDisableToMe = false;
this.createRole = "2";
this.isHeader=false;
} else {
this.radiosButonIsDisableFromMe = false;
this.radiosButonIsDisableToMe = false;
this.isHeader=false;
}
});
},
handleCustDetail(groupId, groupName, campaignId, groupType,type,distributeType) {
if(campaignId==null) {
Message.warning('请先新建活动!')
return;
}
this.$router.push({
path: "/groupBase/customerDetail",
query: { groupId, groupName, campaignId, groupType,type,distributeType },
});
},
//处理搜索
handSearch() {
groupList({
groupType: this.groupFlag,
groupName: this.searchQuery,
}).then((res) => {
this.groupTable = res.rows;
this.total = this.groupTable.length;
});
},
handleSizeChange(newSize) {
this.pageSize = newSize;
},
handleCurrentChange(newPage) {
this.currentPage = newPage;
},
getList() {
groupList({ groupType: this.groupFlag }).then((res) => {
this.groupTable = res.rows;
this.total = this.groupTable.length;
});
},
handleTabChange() {
//根据选中的选项更新表格数据
switch (this.selectedTab) {
case "我创建的":
// this.tableData = this.myTableData;
this.groupFlag = "1";
this.isCreatePag = false;
this.getList();
this.showmap = false;
break;
case "推荐给我的":
// this.tableData = this.recommendedData;
this.groupFlag = "0";
this.getList();
this.isCreatePag = false;
this.showmap = false;
break;
default:
this.groupFlag = "1";
this.getList();
// this.tableData = this.myTableData;
}
this.searchQuery = "";
},
handleQuery() {
this.activeType.page = 1;
this.getList();
},
handelRule() {},
handleImport() {
this.$router.push({ name: "importCreate" });
},
handleDialoClose() {
this.showCreateDialog = false;
},
goBackToCreateType() {
this.isCreatePage = false;
this.showCreateDialog = true;
},
},
mounted() {
//初始化表格数据
this.handleTabChange();
},
};
</script>
<style scoped>
.title {
display: flex;
align-items: center;
padding: 20px;
}
.back-button {
position: absolute;
top: 20px;
left: 20px;
}
a {
color: blue;
margin: 5px;
}
.dialog-content > el-button {
margin-bottom: 20px;
}
</style>

View File

@@ -0,0 +1,688 @@
<template>
<div class="main">
<p class="common-title">基础信息</p>
<el-divider></el-divider>
<el-form ref="baseForm" :model="baseForm" :rules="baseFormRules" label-position="top">
<el-row class="baseForm">
<el-col :span="6">
<el-form-item label="新建客群名称" prop="groupName">
<el-input v-model="baseForm.groupName" placeholder="新建客群名称" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="关联客群" prop="groupId">
<el-select v-model="baseForm.groupId" placeholder="请选已有分群" allow-create clearable filterable
@change="handleGroupName">
<el-option v-for="item in groupNameList" :key="item.value" :label="item.label"
:value="item.value"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="分群类型" prop="custType">
<el-select v-model="baseForm.custType" placeholder="请选分群名称" allow-create clearable filterable>
<el-option v-for="item in fqtypeList" :key="item.value" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="描述" prop="description">
<el-input v-model="baseForm.description" placeholder="请输入分群描述,应用场景" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<p class="common-title">分群规则</p>
<el-divider></el-divider>
<div class="ruleBox" v-for="(item, index) in ruleConditionsList" :key="index">
<div class="ruleBox_left">
<div v-if="index == 0">满足条件</div>
</div>
<div class="ruleBox_line_box">
<div class="ruleBox_line_left">
<span v-if="index > 0" @click="handleRelation(item)" class="relation">{{ item.relation }}</span>
</div>
<div class="ruleBox_line"></div>
</div>
<div class="ruleBox_right">
<div class="ruleBtnBox" v-if="index == ruleConditionsList.length - 1">
<el-button round v-for="(el, i) in typeList" :key="i" @click="handleAddRule(el, item)"
:disabled="ruleConditionsList.length > 3">{{ el }}</el-button>
</div>
<div class="ruleTitle" v-if="ruleConditionsList.length == 1">请选择任意条件开始创建一个分群</div>
<div class="ruleSelectBox" v-if="index != ruleConditionsList.length - 1">
<div class="ruleSelect_top">
<div class="ruleSelect_left">-</div>
<div class="ruleSelect_right">{{ item.selectTitle }}</div>
<div class="ruleSelect_right_icon"><i class="el-icon-close" @click="handleDeleteRule(index)"></i></div>
</div>
<div class="ruleSelect_main">
<div class="line_box" v-if="item.ruleList.length > 1">
<div class="ruleSelect_main_left"></div>
<div class="line_text" @click="handleRelationItem(item)">{{ item.relationItem }}</div>
<div class="ruleSelect_main_left"></div>
</div>
<div class="ruleSelect_main_right">
<el-row class="ruleSelect_main_right_item" v-for="(v, vi) in item.ruleList" :key="vi">
<el-col :span="5">
<el-select filterable v-model="v.leftValue" @change="handleChange(vi, index, item.selectTitle)"
@focus="handleFocusLeft(v.leftValue, vi, index, item.selectTitle)">
<el-option v-for="item in rowLeftList" :key="item.value" :label="item.label"
:value="item.value"></el-option>
</el-select>
</el-col>
<el-col :span="5">
<el-select filterable v-model="v.expression" @focus="handleFocusExpress(item.selectTitle)">
<el-option v-for="item in expressionList" :key="item.value" :label="item.label"
:value="item.value"></el-option>
</el-select>
</el-col>
<el-col :span="4">
<el-select filterable v-model="v.rightValue" v-if="v.isShow == 'select'"
@focus="handleFocusRight(v.leftValue)">
<el-option v-for="item in rowRightList" :key="item.value" :label="item.label"
:value="item.value"></el-option>
</el-select>
<el-input :span="4" filterable v-model="v.rightValue" v-if="v.isShow == 'input'"></el-input>
</el-col>
<el-col :span="3" class="addIcon">
<!-- <i class="el-icon-plus ruleIcon" @click="handleAddRules(index)"
v-if="vi == item.ruleList.length - 1 && item.ruleList.length < 3"></i>
<i class="el-icon-close ruleIcon" @click="handleDeleteRules(index, vi)"
v-if="item.ruleList.length > 1"></i> -->
<el-button type="text"
icon="el-icon-remove-outline"
@click="handleDeleteRules(index, vi)"
class="gray-color" v-if="item.ruleList.length > 1"></el-button>
<el-button type="text"
icon="el-icon-circle-plus-outline"
class="gray-color"
@click="handleAddRules(index)"
v-if="vi == item.ruleList.length - 1 && item.ruleList.length < 3"
></el-button>
</el-col>
</el-row>
</div>
</div>
</div>
</div>
</div>
<p class="common-title">更新方式</p>
<el-divider></el-divider>
<el-radio-group v-model="updateType">
<el-radio :label="0">自动更新</el-radio>
<el-radio :label="1">手动更新</el-radio>
</el-radio-group>
<div class="updateType_box" v-if="updateType == '0'">
<div style="margin-right: 15px;"></div>
<div>
<!-- <el-time-picker v-model="updateTypeRelateTime"></el-time-picker> -->
<el-select filterable v-model="updateTypeRelateTime">
<el-option v-for="item in dateList" :key="item.value" :label="item.label" :value="item.value"></el-option>
</el-select>
</div>
<div style="margin-left: 15px;">自动更新</div>
</div>
<el-divider></el-divider>
<div class="footer">
<el-button type="primary" @click="handleCommit">创建</el-button>
<el-button @click="handleClose">取消</el-button>
</div>
<el-dialog title="考核指标" :visible.sync="groupNameVisible" width="300px" append-to-body :close-on-click-modal="false"
:show-close='false'>
<el-input type="textarea" v-model="diaGroupName"></el-input>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="handleGroupNameCommit">确定</el-button>
<el-button @click="handleGroupNameCancle"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { tabDetail, listTab, createGroupByRule } from "@/api/system/createRuler.js";
import { getGroupList } from '@/api/task/taskList.js'
import { Message } from "element-ui";
export default {
data() {
return {
groupNameVisible: false,
diaGroupName: '',
baseForm: {
groupId: '',
groupName: '',
custType: '',
description: ''
},
groupNameList: [
],
fqtypeList: [
{ label: '个人', value: '0' },
{ label: '商户', value: '1' },
{ label: '企业', value: '2' },
],
baseFormRules: {
groupName: [{ required: true, message: "新建客群名称不能为空", trigger: 'blur' }],
custType: [{ required: true, message: "请选择类型", trigger: 'change' }]
},
ruleConditionsList: [{ selectTitle: '属性指标', relation: '且', num: 0, relationItem: '且', itemNum: 0, ruleList: [{ leftValue: '', expression: '', rightValue: '' }] }],
typeList: ['属性指标', '统计指标'],
rowLeftList: [
],
expressionList: [
{ label: '=', value: '3' },
{ label: '!=', value: '6' },
],
rowRightList: [
],
updateType: '',
updateTypeRelateTime: '',
tabType: '',
tabName: '',
dateList: [
{ label: '天', value: '1' },
{ label: '周', value: '2' },
{ label: '月', value: '3' },
{ label: '年', value: '4' },
]
}
},
created() {
this.initGroupList()
},
methods: {
// 取消返回列表页
handleClose(){
this.$router.push({ path: '/grid/create/segmentation' })
},
handleFocusLeft(val, vi, index, title) {
if (title == '属性指标') {
const params = {
custType: this.baseForm.custType,
tabThresholdType: '3',
}
listTab(params).then(res => {
console.log(res, 'ssssssssss')
this.rowLeftList = res.data.map(item => {
return {
label: item.tabName,
value: item.tabId,
id: item.id
}
})
})
} else if (title == '统计指标') {
const params = {
custType: this.baseForm.custType,
tabThresholdType: '1',
}
listTab(params).then(res => {
this.rowLeftList = res.data.map(item => {
return {
label: item.tabName,
value: item.tabId,
id: item.id
}
})
})
}
},
handleFocusExpress(title) {
if (title == '属性指标') {
this.expressionList = [
{ label: '=', value: '3' },
{ label: '!=', value: '6' },
]
} else if (title == '统计指标') {
this.expressionList = [
{ label: '>', value: '1' },
{ label: '>=', value: '2' },
{ label: '=', value: '3' },
{ label: '<=', value: '4' },
{ label: '<', value: '5' },
{ label: '!=', value: '6' },
]
}
},
handleFocusRight(val) {
let arr = this.rowLeftList.filter(item => item.value == val)
let id = arr ? arr[0].id : ''
tabDetail(id).then(res => {
if (res.code == 200) {
this.rowRightList = res.data.tabEnums.map(item => {
return {
label: item.tabName,
value: item.tabName,
}
})
}
})
},
handleChange(vi, index, title) {
if (title == '属性指标') {
this.ruleConditionsList[index].ruleList[vi].isShow = 'select'
} else if (title == '统计指标') {
this.ruleConditionsList[index].ruleList[vi].isShow = 'input'
}
},
initGroupList() {
const params = {
groupType: '1'
}
getGroupList(params).then(res => {
this.groupNameList = res.map(item => {
return {
label: item.groupName,
value: item.groupId,
custType: item.custType
}
})
})
},
handleGroupName(val) {
let arr = this.groupNameList.filter(item => item.value == val)
this.baseForm.custType = arr[0].custType
},
handleGroupNameCommit() {
this.baseForm.groupName = this.diaGroupName
this.groupNameVisible = false
},
handleGroupNameCancle() {
this.baseForm.groupName = ''
this.diaGroupName = ''
this.groupNameVisible = false
},
handleAddRule(el, item) {
if (el == '属性指标') {
this.ruleConditionsList.push({ selectTitle: el, relation: '且', num: 0, relationItem: '或', itemNum: 0, ruleList: [{ leftValue: '', expression: '', rightValue: '', isShow: '' }] })
} else if (el == '统计指标') {
this.ruleConditionsList.push({ selectTitle: el, relation: '且', num: 0, relationItem: '或', itemNum: 0, ruleList: [{ leftValue: '', expression: '', rightValue: '', isShow: '' }] })
}
item.selectTitle = el
},
handleDeleteRule(index) {
this.ruleConditionsList.splice(index, 1)
},
handleRelation(item) {
item.num++
if (item.num % 2 === 0) {
this.$set(item, 'relation', '且')
} else {
this.$set(item, 'relation', '或')
}
},
handleRelationItem(item) {
item.itemNum++
if (item.itemNum % 2 === 0) {
this.$set(item, 'relationItem', '且')
} else {
this.$set(item, 'relationItem', '或')
}
},
handleAddRules(index) {
this.ruleConditionsList[index].ruleList.push({ leftValue: '', expression: '', rightValue: '' })
},
handleDeleteRules(index, vi) {
this.ruleConditionsList[index].ruleList.splice(vi, 1)
},
initPotRelation(arr) {
let strList = []
let data = arr.map(item => { return item.ruleList })
let relationList = arr.map(item => {
if (item.relation == '且') {
return 'and'
} else {
return 'or'
}
})
let relationItemList = arr.map(item => {
if (item.relationItem == '且') {
return 'and'
} else {
return 'or'
}
})
data.pop()
for (let i = 0; i < data.length; i++) {
for (let j = 0; j < data[i].length; j++) {
strList.push(data[i][j].leftValue)
}
}
relationList.shift()
relationItemList.pop()
console.log(relationList, 'relationList')
console.log(relationItemList, 'relationItemList')
let one1 = []
let one2 = []
let one3 = []
if (data[0] && data[0].length > 0) {
one1 = strList.slice(0, data[0].length);
}
if ((data[0] && data[0].length > 0) && (data[1] && data[1].length > 0)) {
one2 = strList.slice(data[0].length, data[0].length + data[1].length);
}
if ((data[0] && data[0].length > 0) && (data[1] && data[1].length > 0) && (data[2] && data[2].length > 0)) {
one3 = strList.slice(data[0].length + data[1].length, data[0].length + data[1].length + data[2].length);
}
let str1 = ''
let str2 = ''
let str3 = ''
for (let i = 0; i < one1.length; i++) {
str1 += `[${one1[i]}]` + relationItemList[0]
}
if (one2.length > 0) {
for (let i = 0; i < one2.length; i++) {
str2 += `[${one2[i]}]` + relationItemList[1]
}
}
if (one3.length > 0) {
for (let i = 0; i < one3.length; i++) {
str3 += `[${one3[i]}]` + relationItemList[2]
}
}
let strOne = []
let strTwo = []
let strTree = []
if (str1[str1.length - 1] == 'd') {
strOne = str1.slice(0, -3)
} else {
strOne = str1.slice(0, -2)
}
if (str2[str2.length - 1] == 'd') {
strTwo = str2.slice(0, -3)
} else {
strTwo = str2.slice(0, -2)
}
if (str3[str3.length - 1] == 'd') {
strTree = str3.slice(0, -3)
} else {
strTree = str3.slice(0, -2)
}
if (strOne.length > 0 && strTwo.length == 0) {
return `(${strOne})`
}
if (strOne.length > 0 && strTwo.length > 0 && strTree.length == 0) {
return `(${strOne})${relationList[0]}(${strTwo})`
}
if (strOne.length > 0 && strTwo.length > 0 && strTree.length > 0) {
return `(${strOne})${relationList[0]}(${strTwo})${relationList[1]}(${strTree})`
}
},
handleCommit() {
this.$refs.baseForm.validate((valid) => {
if (valid) {
let arr = this.ruleConditionsList.map(item => {
return {
ruleList: item.ruleList,
relation: item.relation,
relationItem: item.relationItem,
}
})
console.log(arr, 'arr')
let arr1=arr.map(item=>{return item.ruleList})
let list = (arr1.flat()).filter((el) => el.leftValue != '')
let list1 = list.map(item => {
return {
potId: item.leftValue,
tabThresholdType: '3',
enumVal: item.rightValue,
isUnEquals:item.expression == '6'?'1':'0'
}
})
console.log(list1, 'list1')
let str = this.initPotRelation(arr)
const tabPotAddDTO = {
potDetails: list1,
potRelation: str,
tabName: ''
}
const params = {
groupName: this.baseForm.groupName,
relateGroupId: this.baseForm.groupId,
custType: this.baseForm.custType,
description: this.baseForm.description,
updateType: this.updateType,
updateTypeRelateTime: this.updateTypeRelateTime,
tabPotAddDTO: tabPotAddDTO
}
console.log(params, 'params')
if(params.tabPotAddDTO.potDetails.length<1){
Message.warning('请至少选择一个指标')
}else{
createGroupByRule(params).then(res => {
if (res.code == 200) {
Message.success('创建成功')
this.$router.push({ path: '/grid/create/segmentation' })
}
})
}
} else { return false }
})
},
},
}
</script>
<style lang="scss" scoped>
.main {
background-color: #ffffff;
overflow: hidden;
box-shadow: 0 3px 8px 0 #00000017;
border-radius: 16px 16px 0 0;
padding: 10px 15px;
}
.common-title {
position: relative;
color: #222222;
line-height: 16px;
font-weight: 600;
font-size: 16px;
padding-left: 10px;
margin-top: 10px;
&::before {
position: absolute;
top: 50%;
transform: translatey(-50%);
left: 0;
content: '';
width: 3px;
background-color: #4886f8;
height: 16px;
border-radius: 2px;
}
}
.baseForm {
::v-deep .el-select {
width: 300px;
}
::v-deep .el-input {
width: 300px;
}
}
.ruleBox {
display: flex;
margin-top: 15px;
}
.ruleBox_left {
padding-top: 10px;
width: 80px;
text-align: right;
}
.ruleBox_line_box {
display: flex;
}
.ruleBox_line {
width: 3px;
margin-left: 20px;
background-color: #ccc;
}
.ruleBox_line_left {
width: 16px;
color: rgb(64, 149, 229);
}
.relation {
cursor: pointer;
}
.ruleBox_right {
padding-left: 30px;
width: 100%;
padding-bottom: 30px;
}
.ruleSelect_top:hover .ruleSelect_right_icon {
display: block;
}
.ruleSelect_right_icon {
margin-left: 15px;
cursor: pointer;
display: none;
}
.ruleTitle {
margin-top: 20px;
font-size: 14px;
color: #ccc;
}
.ruleSelect_top {
display: flex;
padding-left: 10px;
align-items: center;
}
.ruleSelect_left {
width: 15px;
height: 15px;
text-align: center;
line-height: 13px;
background-color: rgb(64, 149, 229);
color: #fff;
}
.ruleSelect_right {
margin-left: 15px;
}
.ruleSelect_main {
margin-top: 15px;
display: flex;
}
.line_box {
display: flex;
width: 15px;
flex-direction: column;
}
.line_text {
margin: 5px 0 5px 6px;
color: rgb(64, 149, 229);
cursor: pointer;
width: 22px;
height: 22px;
text-align: center;
line-height: 21px;
border: 1px solid #ccc;
border-radius: 50%;
}
.ruleSelect_main_left {
width: 3px;
margin-left: 15px;
height: 100%;
background-color: #ccc;
}
.ruleSelect_main_right {
width: 100%;
margin-left: 23px;
}
.addIcon {
line-height: 40px;
margin-left: 15px;
::v-deep .el-icon-circle-plus-outline {
color: #4886f8;
font-size: 20px;
}
::v-deep .el-icon-remove-outline {
font-size: 20px;
}
::v-deep .gray-color {
color: #999999;
}
}
.ruleSelect_main_right_item:hover .addIcon {
display: block;
}
::v-deep .el-date-editor {
width: 120px;
}
.ruleSelect_main_right_item {
height: 40px;
margin-top: 10px;
}
.ruleIcon {
font-size: 16px;
cursor: pointer;
}
.updateType_box {
display: flex;
margin-top: 30px;
align-items: center;
::v-deep .el-select {
width: 100px;
margin: 0 10px;
}
}
.footer {
margin-bottom: 30px;
text-align: center;
}
</style>