Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
M
marketing
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
marketing-web
marketing
Commits
b8eae1e3
Commit
b8eae1e3
authored
Mar 24, 2022
by
crushh
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
udpate: dist
parent
0465c6db
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
252 additions
and
65 deletions
+252
-65
index.vue
src/components/dm-new-member-group/index.vue
+20
-19
ai.js
src/router/modules/ai.js
+0
-5
form.vue
src/views/ai/form.vue
+41
-24
ruleFilter.vue
src/views/ai/ruleFilter.vue
+184
-10
task.vue
src/views/ai/task.vue
+7
-7
No files found.
src/components/dm-new-member-group/index.vue
View file @
b8eae1e3
<
template
>
<div>
<div
class=
"echo-member-group"
v-if=
"
e
cho"
>
<div
class=
"echo-member-group"
v-if=
"
showE
cho"
>
<div
class=
"subTitle"
>
<div
class=
"line"
></div>
<div
class=
"text"
>
...
...
@@ -17,7 +17,7 @@
<span
class=
"groupName"
>
{{
item
.
groupName
}}
</span>
</div>
</div>
<el-dialog
title=
"选择客户分组"
:visible
.
sync=
"visiable"
width=
"1000px"
>
<el-dialog
title=
"选择客户分组"
:visible
.
sync=
"visiable"
width=
"1000px"
:before-close=
"close"
>
<div
class=
"member-group"
>
<div
class=
"left"
>
<el-tabs
v-model=
"activeName"
>
...
...
@@ -51,7 +51,7 @@
</div>
</div>
<div
slot=
"footer"
class=
"dialog-footer"
>
<el-button
@
click=
"
visiable = fal
se"
>
取消
</el-button>
<el-button
@
click=
"
clo
se"
>
取消
</el-button>
<el-button
type=
"primary"
@
click=
"confirm"
>
确定
</el-button>
</div>
</el-dialog>
...
...
@@ -140,20 +140,6 @@ export default {
this
.
activeName
=
'1'
;
}
},
watch
:
{
selected
(
val
)
{
console
.
log
(
val
);
let
arr
=
[];
Object
.
keys
(
val
).
forEach
(
key
=>
{
arr
.
push
(
val
[
key
]);
});
this
.
$emit
(
'change'
,
arr
);
},
echo
(
val
)
{
console
.
log
(
'echo-->'
,
val
);
this
.
showEcho
=
val
;
}
},
computed
:
{
selectedArray
()
{
let
arr
=
[];
...
...
@@ -170,11 +156,26 @@ export default {
arr
.
push
(
this
.
selected
[
key
]);
});
const
str
=
arr
.
map
(
item
=>
item
.
memberTagGroupId
).
join
(
','
);
if
(
arr
.
length
)
{
this
.
showEcho
=
true
;
}
else
{
this
.
showEcho
=
false
;
}
this
.
$emit
(
'update:visiable'
,
false
);
this
.
$emit
(
'change'
,
arr
,
str
);
// 被选中数组,数组id的字符串
},
close
()
{
Object
.
keys
(
this
.
selected
).
forEach
(
key
=>
{
this
.
deleteRow
(
this
.
selected
[
key
]);
});
this
.
$emit
(
'update:visiable'
,
false
);
this
.
$emit
(
'confirm'
,
str
);
},
del
()
{
this
.
selected
=
{};
Object
.
keys
(
this
.
selected
).
forEach
(
key
=>
{
this
.
deleteRow
(
this
.
selected
[
key
]);
});
this
.
$emit
(
'change'
,
[],
''
);
this
.
showEcho
=
false
;
},
edit
()
{
this
.
$emit
(
'update:visiable'
,
true
);
...
...
src/router/modules/ai.js
View file @
b8eae1e3
...
...
@@ -34,11 +34,6 @@ export default {
meta
:
{
type
:
'info'
}
},
{
path
:
'rule'
,
name
:
'规则筛选器'
,
component
:
()
=>
import
(
'../../views/ai/ruleFilter.vue'
)
}
]
};
src/views/ai/form.vue
View file @
b8eae1e3
...
...
@@ -28,16 +28,28 @@
<el-radio
v-model=
"form.memberType"
:label=
"0"
>
客户筛选
</el-radio>
<el-radio
v-model=
"form.memberType"
:label=
"1"
>
客户分组
</el-radio>
<div>
<el-button
v-if=
"form.memberType == 0"
size=
"small"
>
添加其他条件
</el-button>
<el-button
v-if=
"form.memberType == 1 && !selectedGroup.length"
size=
"small"
@
click=
"groupVisible = true"
>
添加分组
</el-button>
<gic-new-member-group
:visiable
.
sync=
"groupVisible"
:defaltSelected=
"selectedGroup"
@
change=
"handleDataTransferred"
@
confirm=
"confirmGroupDialog"
:echo=
"echoData"
/>
<div
class=
"tips"
v-if=
"form.scene == 4"
>
默认为权限范围内的全部客户
</div>
<el-button
v-if=
"form.memberType == 0 && form.scene != 4"
size=
"small"
@
click=
"ruleVisible = true"
>
添加其他条件
</el-button>
<ruleFilter
:visiable
.
sync=
"ruleVisible"
/>
<el-button
v-if=
"form.memberType == 1 && !selectedGroup.length && form.scene != 4"
size=
"small"
@
click=
"groupVisible = true"
>
添加分组
</el-button>
<gic-new-member-group
:visiable
.
sync=
"groupVisible"
:defaltSelected=
"selectedGroup"
@
change=
"confirmGroupDialog"
/>
</div>
</el-form-item>
<el-form-item
label=
"消费条件"
v-if=
"form.scene == 4"
>
<div><el-checkbox
v-model=
"form.consume_days_flag"
:true-label=
"1"
:false-label=
"0"
>
最近消费间隔
</el-checkbox>
<el-input-number
v-model=
"form.consume_days"
controls-position=
"right"
:max=
"730"
:min=
"30"
size=
"small"
/>
天
</div>
<div><el-checkbox
v-model=
"form.consume_times_flag"
:true-label=
"1"
:false-label=
"0"
>
最近消费次数
</el-checkbox>
<el-input-number
v-model=
"form.consume_times"
controls-position=
"right"
:max=
"100"
:min=
"1"
size=
"small"
/>
次
</div>
<div><el-checkbox
v-model=
"form.consume_amount_flag"
:true-label=
"1"
:false-label=
"0"
>
累计消费金额
</el-checkbox>
<el-input-number
v-model=
"form.consume_amount"
controls-position=
"right"
:max=
"100000"
:min=
"1"
size=
"small"
/>
元
</div>
<div
class=
"consumeLine"
>
<el-checkbox
v-model=
"form.consume_days_flag"
:true-label=
"1"
:false-label=
"0"
>
最近消费间隔
</el-checkbox>
<el-input-number
v-model=
"form.consume_days"
controls-position=
"right"
:max=
"730"
:min=
"30"
size=
"small"
style=
"margin:0 10px;"
/>
天
</div>
<div
class=
"consumeLine"
>
<el-checkbox
v-model=
"form.consume_times_flag"
:true-label=
"1"
:false-label=
"0"
>
最近消费次数
</el-checkbox>
<el-input-number
v-model=
"form.consume_times"
controls-position=
"right"
:max=
"100"
:min=
"1"
size=
"small"
style=
"margin:0 10px;"
/>
次
</div>
<div
class=
"consumeLine"
>
<el-checkbox
v-model=
"form.consume_amount_flag"
:true-label=
"1"
:false-label=
"0"
>
累计消费金额
</el-checkbox>
<el-input-number
v-model=
"form.consume_amount"
controls-position=
"right"
:max=
"100000"
:min=
"1"
size=
"small"
style=
"margin:0 10px;"
/>
元
</div>
<el-button
size=
"small"
>
添加其它条件
</el-button>
<span
class=
"tips"
>
勾选消费条件后,添加规则不支持选择【金字塔分层】
</span>
</el-form-item>
<el-form-item
label=
"预计覆盖人数"
>
<span
class=
"bold"
>
{{
form
.
planMemberCount
}}
</span>
...
...
@@ -194,14 +206,16 @@
开启后,可用于统计活动的触达转化收益情况
</div>
</el-form-item>
<el-form-item
label=
"分析天数"
prop=
"analyseDays"
v-if=
"form.scene != 3"
>
触达日期起
<el-input
class=
"w100"
style=
"margin:0 5px;"
v-model=
"form.analyseDays"
/>
天之内
<div
class=
"analyseTips"
>
设置从客户被成功触达的日期计算,14 天以内的转化会被被作为此营销活动的转化收益;
<br
/>
注:最短 1 天,最长 31 天 (以自然日计算),时长越长,会员的转化与此次营销的相关度越低,请酌情填写分析天数
</div>
</el-form-item>
<el-form-item
label=
"活动目标"
prop=
"analyseAmount"
v-if=
"form.scene != 3"
>
销售额
<el-input
style=
"width:128px;margin:0 5px;"
placeholder=
"1-99999"
v-model=
"form.analyseAmount"
/>
万元
</el-form-item>
<div
v-if=
"form.analyseFlag == 1"
>
<el-form-item
label=
"分析天数"
prop=
"analyseDays"
>
触达日期起
<el-input
class=
"w100"
style=
"margin:0 5px;"
v-model=
"form.analyseDays"
/>
天之内
<div
class=
"analyseTips"
>
设置从客户被成功触达的日期计算,14 天以内的转化会被被作为此营销活动的转化收益;
<br
/>
注:最短 1 天,最长 31 天 (以自然日计算),时长越长,会员的转化与此次营销的相关度越低,请酌情填写分析天数
</div>
</el-form-item>
<el-form-item
label=
"活动目标"
prop=
"analyseAmount"
>
销售额
<el-input
style=
"width:128px;margin:0 5px;"
placeholder=
"1-99999"
v-model=
"form.analyseAmount"
/>
万元
</el-form-item>
</div>
</div>
<dm-form-bottom>
<el-button
type=
"primary"
@
click=
"submit"
>
保 存
</el-button>
...
...
@@ -233,6 +247,7 @@ import LibMessage from '@/views/ecm/marketing-event/components/lib-message.vue';
import
activeTime
from
'./activeTime.vue'
;
import
{
formatDateTimeByType
}
from
'@/utils/index'
;
import
gicNewMemberGroup
from
'@/components/dm-new-member-group/index.vue'
;
import
ruleFilter
from
'./ruleFilter.vue'
;
export
default
{
mixins
:
[
filterAvater
],
data
()
{
...
...
@@ -285,6 +300,7 @@ export default {
isAdd
:
this
.
$route
.
meta
.
type
===
'add'
,
isInfo
:
this
.
$route
.
meta
.
type
===
'info'
,
groupVisible
:
false
,
//客户分组弹窗
ruleVisible
:
false
,
// 客户筛选弹窗
tagsDialogVisible
:
false
,
//选择标签弹窗
smsDialogVisible
:
false
,
//短信模板弹窗
gradeOptions
:
[],
//客户意向等级下拉
...
...
@@ -349,7 +365,8 @@ export default {
holidaySense
,
activeTime
,
LibMessage
,
gicNewMemberGroup
gicNewMemberGroup
,
ruleFilter
},
methods
:
{
async
getActivityDetail
(
activityId
)
{
...
...
@@ -466,8 +483,8 @@ export default {
startDate
,
endDate
,
analyseFlag
,
analyseDays
,
analyseAmount
,
analyseDays
:
analyseFlag
==
1
?
analyseDays
:
undefined
,
analyseAmount
:
analyseFlag
==
1
?
analyseAmount
:
undefined
,
activityPlanList
:
[
{
planId
,
...
...
@@ -549,15 +566,12 @@ export default {
this
.
form
.
planMemberCount
=
result
;
},
/**客户分组 */
handleDataTransferred
(
data
)
{
this
.
selectedGroup
=
data
;
},
confirmGroupDialog
(
idStr
)
{
this
.
groupVisible
=
false
;
confirmGroupDialog
(
arr
,
idStr
)
{
this
.
selectedGroup
=
arr
;
this
.
form
.
filterJson
=
idStr
;
this
.
echoData
=
true
;
console
.
log
(
idStr
);
this
.
getMemberCount
();
console
.
log
(
this
.
groupVisible
);
// this.getMemberCount();
},
/** 根据客户意向发送挂机短信 */
delSmslist
(
index
)
{
...
...
@@ -735,4 +749,7 @@ export default {
color
:
#909399
;
line-height
:
17px
;
}
.consumeLine
{
margin-bottom
:
20px
;
}
</
style
>
src/views/ai/ruleFilter.vue
View file @
b8eae1e3
<
template
>
<el-dialog
title=
"设置规则"
:visible
.
sync=
"
tagsDialogVisible"
width=
"900px
"
>
<el-dialog
title=
"设置规则"
:visible
.
sync=
"
visiable"
width=
"900px"
:before-close=
"close
"
>
<div
class=
"ruleContainer"
>
<el-tabs
tab-position=
"left"
style=
"height: 200px;"
@
tab-click=
"onTabsClick"
>
<el-tab-pane
:label=
"item.chainNodeName"
v-for=
"item in conditionTypeList"
:key=
"item.esScreeningWidgetChainId"
:name=
"item.esScreeningWidgetChainId"
>
{{
item
.
chainNodeName
}}
</el-tab-pane>
</el-tabs>
<div
class=
"left"
>
<el-tabs
tab-position=
"left"
@
tab-click=
"onTabsClick"
v-model=
"activeName"
>
<el-tab-pane
:label=
"item.chainNodeName"
v-for=
"item in conditionTypeList"
:key=
"item.esScreeningWidgetChainId"
:name=
"item.esScreeningWidgetChainId"
>
<div
v-if=
"templateCode == 'tag001'"
class=
"leftContent"
>
<el-checkbox-group
v-model=
"selectData[item.chainNodeName]"
@
change=
"handleChange"
class=
"checkBoxContainer"
>
<el-checkbox
v-for=
"row in checkboxList"
:key=
"row.key"
:label=
"row.key"
>
{{
row
.
value
}}
</el-checkbox>
</el-checkbox-group>
</div>
<div
v-if=
"templateCode == 'com026'"
class=
"leftContent"
>
<div
class=
"line"
v-for=
"(value, index) in checkboxList"
:key=
"index"
>
<h3>
{{
value
.
title
}}
</h3>
<el-checkbox-group
v-model=
"selectData[item.chainNodeName]"
@
change=
"handleChange"
class=
"checkBoxContainer"
>
<el-checkbox
v-for=
"row in value.data"
:key=
"row.key"
:label=
"row.value"
>
{{
row
.
key
}}
</el-checkbox>
</el-checkbox-group>
</div>
</div>
<div
v-if=
"templateCode == 'com020'"
class=
"leftContent"
>
<dm-store-selector
style=
"margin-top: 20px;"
ref=
"newStoreCard"
:uuid
.
sync=
"uuid"
></dm-store-selector>
</div>
</el-tab-pane>
</el-tabs>
</div>
<div
class=
"right"
>
<div
class=
"right-top"
>
已选条件
</div>
<ul
class=
"right-content"
>
<li
class=
"contact-li"
v-for=
"(value, name) in selectData"
:key=
"name"
>
{{
name
}}
<div
class=
"li-cell cursor-pointer"
>
<div>
<span
v-for=
"item in value"
:key=
"item"
>
{{
item
}}
</span>
</div>
<i
v-if=
"!readonly"
class=
"el-icon-close"
@
click=
"deleteRow(item)"
></i>
</div>
</li>
</ul>
</div>
</div>
<div
slot=
"footer"
class=
"dialog-footer"
>
<el-button
@
click=
"
tagsDialogVisible = fal
se"
>
取消
</el-button>
<el-button
@
click=
"
clo
se"
>
取消
</el-button>
<el-button
type=
"primary"
@
click=
"confirmTagsDialog"
>
确定
</el-button>
</div>
</el-dialog>
...
...
@@ -17,19 +52,37 @@ import qs from 'qs';
export
default
{
data
()
{
return
{
conditionTypeList
:
[],
tagsDialogVisible
:
true
activeName
:
''
,
conditionTypeList
:
[],
// 第一层级
checkboxList
:
[],
selectData
:
{},
arr
:
[],
uuid
:
''
,
templateCode
:
''
//当前控件类型
};
},
props
:
{
visiable
:
{
type
:
Boolean
,
default
:
false
}
},
mounted
()
{
this
.
getDataList
();
},
methods
:
{
handleChange
(
val
)
{
console
.
log
(
val
);
this
.
selectData
=
Object
.
assign
({},
this
.
selectData
);
},
onTabsClick
(
val
)
{
console
.
log
(
val
);
const
{
name
}
=
val
;
this
.
getNode
(
name
);
},
close
()
{
this
.
$emit
(
'update:visiable'
,
false
);
},
// 获取列表
getDataList
()
{
let
para
=
{
...
...
@@ -42,6 +95,12 @@ export default {
let
resData
=
res
.
data
;
if
(
resData
.
errorCode
==
0
)
{
this
.
conditionTypeList
=
resData
.
result
;
this
.
activeName
=
this
.
conditionTypeList
.
length
&&
this
.
conditionTypeList
[
0
].
esScreeningWidgetChainId
;
this
.
conditionTypeList
.
forEach
(
item
=>
{
this
.
selectData
[
item
.
chainNodeName
]
=
[];
});
this
.
getNode
(
this
.
activeName
);
return
;
}
this
.
$message
.
error
({
...
...
@@ -58,12 +117,127 @@ export default {
},
getNode
(
widgetChainId
)
{
this
.
axios
.
get
(
`/api-plug/get-screening-widget-chain-detail?requestProject=gic-web&widgetChainId=
${
widgetChainId
}
`
).
then
(
res
=>
{
const
result
=
res
.
data
.
result
;
// 返回的结果 从第一层开始
console
.
log
(
result
);
const
{
widget
:
{
sourceFlag
,
templateCode
,
widgetParam
,
widgetValues
},
widgetFieldKey
}
=
res
.
data
.
result
;
// 返回的结果 从第一层开始
this
.
templateCode
=
templateCode
;
console
.
log
(
res
.
data
.
result
);
if
(
sourceFlag
==
1
)
{
const
url
=
JSON
.
parse
(
widgetParam
)[
0
].
value
;
this
.
getChildNode
(
url
,
widgetFieldKey
);
}
else
{
if
(
templateCode
==
'tag001'
)
{
this
.
checkboxList
=
JSON
.
parse
(
widgetValues
);
}
}
});
},
// 获取下一层控件
getChildNode
(
url
,
key
)
{
const
param
=
{
requestProject
:
'gic-web'
,
key
};
this
.
axios
.
post
(
`
${
url
}
`
,
qs
.
stringify
(
param
)).
then
(
res
=>
{
let
resData
=
res
.
data
;
console
.
log
(
resData
.
result
);
if
(
resData
.
errorCode
==
0
)
{
this
.
checkboxList
=
resData
.
result
;
}
});
}
}
};
</
script
>
<
style
></
style
>
<
style
lang=
"scss"
scoped
>
.ruleContainer
{
background
:
#ffffff
;
display
:
flex
;
}
.left
{
width
:
566px
;
height
:
550px
;
background
:
#ffffff
;
border-radius
:
4px
;
padding
:
10px
0
;
box-sizing
:
border-box
;
border
:
1px
solid
#dcdfe6
;
.leftContent
{
width
:
100%
;
padding
:
0
15px
0
5px
;
box-sizing
:
border-box
;
height
:
550px
;
overflow-y
:
auto
;
}
}
.right
{
width
:
274px
;
height
:
550px
;
border-radius
:
4px
;
border
:
1px
solid
#dcdfe6
;
margin-left
:
12px
;
.right-top
{
padding
:
20px
15px
;
display
:
flex
;
justify-content
:
space-between
;
color
:
#303133
;
box-sizing
:
border-box
;
line-height
:
20px
;
background
:
#fff
;
}
.right-content
{
color
:
#303133
;
overflow-y
:
auto
;
height
:
89%
;
}
.contact-li
{
padding
:
0
12px
0
16px
;
margin-top
:
4px
;
&:hover
{
background
:
#f7f8fa
;
}
&
:first-child
{
margin-top
:
0
;
}
.li-cell
{
border-radius
:
2px
;
line-height
:
32px
;
display
:
inline-flex
;
width
:
100%
;
justify-content
:
space-between
;
padding
:
0
4px
;
align-items
:
center
;
box-sizing
:
border-box
;
i
{
width
:
20px
;
height
:
20px
;
border-radius
:
10px
;
cursor
:
pointer
;
font-size
:
12px
;
display
:
inline-flex
;
justify-content
:
center
;
align-items
:
center
;
&:hover
{
background
:
#e5e6eb
;
}
}
}
}
.contact-li
+
.contact-li
{
margin-top
:
4px
;
}
}
.checkBoxContainer
{
display
:
flex
;
flex-wrap
:
wrap
;
gap
:
10px
;
.el-checkbox
+
.el-checkbox
{
margin
:
0
;
}
}
</
style
>
src/views/ai/task.vue
View file @
b8eae1e3
...
...
@@ -123,7 +123,7 @@ export default {
limitCode
:
''
},
visible
:
row
=>
{
return
row
.
activityPlanStatus
===
0
||
row
.
activityPlanStatus
==
1
;
return
row
.
activityPlanStatus
===
1
;
},
handler
:
row
=>
this
.
editPlan
(
row
)
},
...
...
@@ -133,7 +133,7 @@ export default {
limitCode
:
''
},
visible
:
row
=>
{
return
row
.
activityPlanStatus
===
0
||
row
.
activityPlanStatus
==
1
;
return
row
.
activityPlanStatus
===
1
||
row
.
activityPlanStatus
==
2
;
},
handler
:
row
=>
this
.
stopTask
(
row
)
},
...
...
@@ -267,19 +267,19 @@ export default {
activePlanStatusFilter
(
val
)
{
let
str
=
'- -'
;
switch
(
val
)
{
case
0
:
case
1
:
str
=
'未开始'
;
break
;
case
1
:
case
2
:
str
=
'进行中'
;
break
;
case
2
:
case
3
:
str
=
'已终止'
;
break
;
case
3
:
case
4
:
str
=
'已结束'
;
break
;
case
4
:
case
5
:
str
=
'欠费暂停'
;
break
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment