提交 ed5e2611 authored 作者: lihuihui's avatar lihuihui

开发页面,对接接口

上级 76e9baa3
......@@ -1111,6 +1111,16 @@
"to-fast-properties": "^2.0.0"
}
},
"@ckeditor/ckeditor5-build-classic": {
"version": "23.1.0",
"resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-build-classic/-/ckeditor5-build-classic-23.1.0.tgz",
"integrity": "sha512-wqJZ6yuqm48NoiciRcfs+t73YOfIKovJIiLSHf0yB2I3Mc+bL6iNhwwyJ3b6D/22IgYEXTpc6PiwsYFbGFnq2Q=="
},
"@ckeditor/ckeditor5-vue2": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-vue2/-/ckeditor5-vue2-1.0.5.tgz",
"integrity": "sha512-snsNB/2oWfKw0drGJAmMGpTatmt//L1rQsOwkBw+1uKUuOJPKN3xwyUZVWT906VguIMXm4E9OHzquZ3bdkijiA=="
},
"@types/anymatch": {
"version": "1.3.1",
"resolved": "https://registry.npm.taobao.org/@types/anymatch/download/@types/anymatch-1.3.1.tgz",
......
......@@ -72,6 +72,8 @@
"webpack-merge": "^4.2.2"
},
"dependencies": {
"@ckeditor/ckeditor5-build-classic": "^23.1.0",
"@ckeditor/ckeditor5-vue2": "^1.0.5",
"axios": "^0.20.0",
"core-js": "^3.6.5",
"cross-env": "^7.0.2",
......
......@@ -28,3 +28,9 @@ export function logout() {
export function getUser() {
return httpRequest.get('/api/passport/account/get-user-info')
}
/**
* 获取用户等级
*/
export function getUserGrade() {
return httpRequest.get('/api/opera/v1/api/user/level')
}
import httpRequest from '@/utils/axios'
/**
* 上传文件
*/
export function uploadFile(data) {
return httpRequest.post('/api/lms/util/upload-file', data, {
headers: { 'Content-Type': 'multipart/form-data' }
})
}
/**
* 获取用户等级
*/
export function getUserGrade() {
return httpRequest.get('/api/opera/v1/api/user/level')
}
/* 获取案例列表 */
export function getCaseList(params) {
return httpRequest.get('/api/opera/v1/api/cases', { params })
}
/* 选中案例 */
export function confirmCases(data) {
return httpRequest.post('/api/opera/v1/api/case/select', data)
}
/* 用户群列表 */
export function getUserGroup(params) {
return httpRequest.get('/api/opera/v1/api/groups', { params })
}
/* 用户群列表详情 */
export function getUserGroupDetail(params) {
return httpRequest.get(`/api/opera/v1/oprations/${params}/cgroup`)
}
/* 触达列表 */
export function getTriggerList(params) {
return httpRequest.get('/api/opera/v1/api/reach/list', { params })
}
/* 用户触达提交 */
export function submitTrigger(data) {
return httpRequest.post('/api/opera/v1/api/reach/submit', data)
}
/* 用户触达提交文本 */
export function submitContext(data) {
return httpRequest.post('/api/opera/v1/api/reach/submit/context', data)
}
import { uploadFile } from '@/api/common'
export default class MyUploadAdapter {
constructor(loader) {
// The file loader instance to use during the upload.
this.loader = loader
}
// Starts the upload process.
upload() {
return this.loader.file.then(
file =>
new Promise((resolve, reject) => {
this._sendRequest(resolve, reject, file)
})
)
}
_sendRequest(resolve, reject, file) {
uploadFile({ file })
.then(response => {
if (response.success) {
resolve({ default: response.url })
} else {
return reject(response.message)
}
})
.catch(response => {
return reject(response.message)
})
}
}
<template>
<div class="ckeditor">
<ckeditor
:editor="editor"
:value="value"
:disabled="disabled"
:config="editorConfig"
@ready="onEditorReady"
@input="onEditorInput"
></ckeditor>
</div>
</template>
<script>
import CKEditor from '@ckeditor/ckeditor5-vue2'
import ClassicEditor from '@ckeditor/ckeditor5-build-classic'
import '@ckeditor/ckeditor5-build-classic/build/translations/zh-cn'
import MyUploadAdapter from './MyUploadAdapter'
export default {
components: {
ckeditor: CKEditor.component
},
props: {
value: { type: String },
disabled: { type: Boolean, default: false }
},
data() {
return {
editor: ClassicEditor,
editorConfig: {
language: 'ZH'
}
}
},
methods: {
onEditorReady(editor) {
const FileRepository = editor.plugins.get('FileRepository')
// 自定义上传图片插件
FileRepository.createUploadAdapter = loader => {
return new MyUploadAdapter(loader)
}
},
onEditorInput(value) {
this.$emit('input', value)
}
}
}
</script>
<style>
.ck-content {
min-height: 300px;
max-height: 500px;
word-break: break-word;
}
.ck-sticky-panel__content {
position: unset !important;
}
</style>
......@@ -26,18 +26,12 @@ export default {
return {
defaultMenus: [
{
title: '案例背景',
title: '案例背景选择',
icon: '',
path: '/yhfq/albj'
// children: [
// { title: '案例背景', path: '/yhfq/albj' }
// // { title: '案例详情', path: '/yhfq/alfx' },
// // { title: '用户群分析', path: '/yhfq/yhqfx' }
// ]
path: '/caseSelection'
},
{ title: '案例分析', icon: '', path: '/' },
{ title: '用户群分析', icon: '', path: '/' },
{ title: '用户触达', icon: '', path: '/' }
{ title: '用户群分析', icon: '', path: '/groupAnalysis' },
{ title: '用户触达', icon: '', path: '/userTrigger' }
]
}
},
......
......@@ -4,7 +4,6 @@ import store from './store'
import App from './app.vue'
import './style.scss'
import ElementUI from 'element-ui'
import BeforeEnter from './utils/beforeEnter'
const before = new BeforeEnter()
......
<template>
<div>
<div v-if="!isDetail" :class="isSelected == data.id ? 'card-box hover actvie' : 'card-box hover'">
<div class="ban-top" :style="style(data.poster_url)">
<div class="title">{{ data.name }}</div>
</div>
<ul>
<li>
<div class="name">姓名</div>
<div class="val">{{ data.username }}</div>
</li>
<li>
<div class="name">公司</div>
<div class="val">{{ data.company }}</div>
</li>
<li>
<div class="name">部门</div>
<div class="val">{{ data.department }}</div>
</li>
<li>
<div class="name">职位</div>
<div class="val">{{ data.position }}</div>
</li>
<li>
<div class="name">营销产品</div>
<div class="val">{{ data.product }}</div>
</li>
</ul>
</div>
<div class="detail" v-if="isDetail">
<div class="card-box" v-for="(item, index) in detail" :key="index">
<div class="ban-top" :style="style(item.url)">
<div class="title">{{ item.title }}</div>
</div>
<div class="cont">{{ item.content }}</div>
<ul>
</ul>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
data: { type: Object, default: {} },
isSelected: { type: Number, default: 1 },
isDetail: { type: Boolean, default: false }
},
data() {
return {
detail: []
}
},
computed: {
style () {
return (url) => {
return `background:url(${url});background-size:cover;`
}
},
changeIndex() {
return this.isSelected
}
},
mounted() {
console.log(this.isSelected)
this.setDetail()
},
methods: {
setDetail() {
this.detail = [
{
title: '公司信息',
content: this.data.company_detail,
url: 'https://zws-imgs-pub.ezijing.com/static/public/6c2c3dec7a9f30ceb2bb3afafc6eff19.png'
},
{
title: '产品信息',
content: this.product_detail,
url: 'https://zws-imgs-pub.ezijing.com/static/public/ef63f2f3ceff57c68a3b299b9303a0cd.png'
},
{
title: '职位信息',
content: this.data.position_detail,
url: 'https://zws-imgs-pub.ezijing.com/static/public/85eca9ff8c9cd1f0e55ff70b21e5929c.png'
}
]
}
},
watch: {
// 监听题的变化
changeIndex(newV, oldV) {
this.$forceUpdate()
}
}
}
</script>
<style lang="scss" scoped>
.hover{
&:hover{
box-shadow: 0px 8px 16px 0px rgba(88, 111, 174, 0.2);
}
}
.detail{
display: flex;
.card-box{
margin-right: 24px;
min-height: 300px;
}
}
.card-box{
width: 228px;
border-radius: 6px;
overflow: hidden;
background: #FFFFFF;
box-shadow: 0px 2px 10px 0px rgba(88, 111, 174, 0.1);
&.actvie{
box-sizing: border-box;
border: 2px solid #C01540;
box-shadow: 0px 8px 16px 0px rgba(192, 21, 64, 0.2);
}
.cont{
padding: 15px;
color: #222222;
line-height: 22px;
font-size: 14px;
}
}
.ban-top{
width: 100%;
height: 80px;
background: url(https://zws-imgs-pub.ezijing.com/static/public/8118c19f3664355507a68eddd8a059c4.png);
background-size: cover;
.title{
width: 100%;
height: 100%;
background: rgba(0,0,0,0.2);
font-size: 24px;
font-weight: bold;
color: #FFFFFF;
text-align: center;
line-height: 80px;
}
}
ul{
width: 212px;
margin: 0 auto;
padding: 0;
list-style: none;
li{
border-top: 1px solid #eee;
display: flex;
padding: 16px 0;
&:nth-child(1){
border: none;
}
.name{
margin-left: 16px;
width: 94px;
font-size: 14px;
color: #666666;
}
.val{
width: 106px;
font-size: 14px;
font-weight: bold;
color: rgba(0, 0, 0, 0.85);
}
}
}
</style>
<template>
<app-container title="请选择您要进入的案例背景">
<template #header>
<div v-if="!isDetail">请选择您要进入的案例背景</div>
<div v-else class="back" @click="isDetail = false"></div>
</template>
<ul class="cases-box">
<li v-for="(item, index) in cases" :key="index" @click="select(item.id)">
<template v-if="isDetail">
<card v-if="item.id == isSelected" :data="item" :isSelected="isSelected" :isDetail="isDetail" ref="sonMethod"></card>
</template>
<template v-else>
<card :data="item" :isSelected="isSelected" :isDetail="isDetail" ref="sonMethod"></card>
</template>
</li>
</ul>
<template #footer>
<div class="app-container-ft">
<el-button type="primary" size="mini" @click="open">开始实训</el-button>
<el-button type="primary" size="mini" @click="viewDetails" v-if="!isDetail">查看背景详情</el-button>
</div>
</template>
</app-container>
</template>
<script>
import AppContainer from '@/components/AppContainer'
import card from './components/card'
import * as api from '@/api/common.js'
export default {
components: {
AppContainer,
card
},
data() {
return {
cases: [],
isSelected: 1,
isDetail: false
}
},
mounted() {
this.getCaseList()
},
methods: {
// 开始实训
open() {
this.$router.push({
path: '/groupAnalysis'
})
},
// 选择案例
select(id) {
this.isSelected = id
api
.confirmCases({ case_id: this.isSelected })
.then(response => {
})
.finally(() => {
})
},
// 获取案例列表
getCaseList() {
api
.getCaseList({ level: this.$store.state.level })
.then(response => {
this.cases = response.data.cases
const id = parseInt(response.data.selected_case_id)
this.isSelected = id === 0
? response.data.cases[0].id
: id
})
.finally(() => {
})
},
viewDetails() {
this.isDetail = true
}
}
}
</script>
<style scoped lang="scss">
app-container {
overflow: hidden;
// it-em {
// float: left;
// margin-right: 20px;
// }
}
#clk {
box-shadow: 0px 8px 16px 0px rgba(192, 21, 64, 0.4);
border: 1px solid #c01540;
}
.cases-box{
display: flex;
li{
margin-right: 24px;
}
}
.back{
width: 20px;
height: 18px;
background: url(@/assets/images/out.png);
background-size: 100% 100%;
cursor: pointer;
}
</style>
<template>
<div>
<div class="card-pop">
<div class="banner" :style="background(data.poster_url)">
<div class="title">{{ data.name }}</div>
</div>
<ul>
<li>
<div class="name">姓名</div>
<div class="val">{{ data.username }}</div>
</li>
<li>
<div class="name">公司</div>
<div class="val">{{ data.company }}</div>
</li>
<li>
<div class="name">部门</div>
<div class="val">{{ data.department }}</div>
</li>
<li>
<div class="name">职位</div>
<div class="val">{{ data.position }}</div>
</li>
<li>
<div class="name">营销产品</div>
<div class="val">{{ data.product }}</div>
</li>
</ul>
<i class="el-icon-caret-bottom"></i>
</div>
</div>
</template>
<script>
export default {
props: {
data: { type: Object, default: {} }
},
computed: {
background() {
return (url) => {
return `background: url(${url});background-size:cover;`
}
}
}
}
</script>
<style lang="scss" scoped>
.card-pop{
position: relative;
padding: 6px;
width: 240px;
background: #FFFFFF;
box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.1);
border-radius: 5px;
box-sizing: border-box;
i{
position: absolute;
bottom: -15px;
right: 10px;
font-size: 30px;
color: #fff;
}
.banner{
width: 100%;
height: 80px;
background: url(https://zws-imgs-pub.ezijing.com/static/public/8118c19f3664355507a68eddd8a059c4.png);
background-size: cover;
.title{
width: 100%;
height: 100%;
background: rgba(0,0,0,0.2);
font-size: 24px;
font-weight: bold;
color: #FFFFFF;
text-align: center;
line-height: 80px;
}
}
ul{
width: 212px;
margin: 0 auto;
padding: 0;
list-style: none;
li{
border-top: 1px solid #eee;
display: flex;
padding: 16px 0;
&:nth-child(1){
border: none;
}
.name{
margin-left: 16px;
width: 94px;
font-size: 14px;
color: #666666;
}
.val{
width: 106px;
font-size: 14px;
font-weight: bold;
color: rgba(0, 0, 0, 0.85);
}
}
}
}
</style>
<template>
<div class="form-box">
<ul v-if="Object.keys(radioBox).length != 0">
<li v-for="(item, index) in data" :key="index">
<div class="name">{{ item.name }}</div>
<el-radio-group v-model="radioBox[index]">
<el-radio :label="0">不筛选</el-radio>
<template v-for="(btn, btnIndex) in JSON.parse(item.context)">
<el-radio :key="btnIndex + 'a'" :label="btn.options">{{ btn.options_info }}</el-radio>
</template>
</el-radio-group>
</li>
</ul>
</div>
</template>
<script>
export default {
props: {
data: { type: Array, default: [] }
},
data() {
return {
radioBox: {
0: 0,
1: 0,
2: 0,
3: 0,
4: 0,
5: 0,
6: 0,
7: 0,
8: 0,
9: 0,
10: 0
}
}
}
}
</script>
<style lang="scss" scoped>
.form-box{
width: 100%;
li{
display: flex;
align-items: center;
width: 100%;
border-bottom: 1px solid #eee;
height: 60px;
.name{
margin-right: 24px;
font-size: 14px;
font-weight: bold;
color: #222222;
}
}
}
</style>
<template>
<div>
<ul class="item-box">
<template v-for="(item, index) in data">
<li
:key="index"
@click="currentSelect(item.id, index)"
:class="currentIndex == index && 'active'"
:style="background(item.poster_url)">
<div class="cont-m">
<i class="el-icon-success" v-if="item.status == 1"></i>
<span :class="item.status == 1 ? 'text active' : 'text'">{{ item.name }}:{{ item.desc }}</span>
</div>
</li>
</template>
</ul>
</div>
</template>
<script>
export default {
components: {},
props: {
data: { type: Array, default: [] }
},
data() {
return {
currentIndex: 0
}
},
mounted() {},
methods: {
currentSelect(id, index) {
this.currentIndex = index
this.$emit('currentSelect', id)
}
},
computed: {
background() {
return (url) => {
return `background: url(${url});background-size:cover;`
}
}
}
}
</script>
<style scoped lang="scss">
.item-box{
margin: 0;
padding: 0 0 50px 0;
overflow: hidden;
li{
cursor: pointer;
position: relative;
float: left;
width: 400px;
height: 120px;
background: url(https://zws-imgs-pub.ezijing.com/static/public/8118c19f3664355507a68eddd8a059c4.png);
background-size: cover;
box-shadow: 0px 2px 10px 0px rgba(88, 111, 174, 0.1);
border-radius: 5px;
overflow: hidden;
margin-right: 24px;
margin-bottom: 16px;
box-sizing: border-box;
&.active{
box-shadow: 0px 4px 8px 0px rgba(192, 21, 64, 0.4);
border: 2px solid #C01540;
.cont-m{
background: rgba(255, 255, 255, 0.7);
.text{
color: #C01540;
&.active{
color: #C01540;
}
}
i{
color: #C01540;
}
}
}
&:hover{
.cont-m{
background: rgba(255, 255, 255, 0.7);
.text{
color: #C01540;
&.active{
color: #C01540;
}
}
i{
color: #C01540;
}
}
}
.cont-m{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.4);
display: flex;
align-items: center;
justify-content: center;
i{
color: #7FFF30;
font-size: 30px;
margin-right: 20px;
}
.text{
font-size: 24px;
font-weight: bold;
color: #FFFFFF;
text-shadow: 0px 2px 10px rgba(88, 111, 174, 0.1);
&.active{
color: #7FFF30;
}
}
}
}
}
</style>
<template>
<app-container title="用户群分析" class="card-box">
<template #header>
<div v-if="!isFormShow">用户群分析</div>
<div v-else class="back" @click="isFormShow = false"></div>
</template>
<template v-if="!isFormShow">
<div class="tips">请选择您想进行分析的用户群</div>
<item :data="list" @currentSelect="currentSelect"/>
</template>
<template v-else>
<formRadio :data="formData"/>
</template>
<template #footer>
<div class="app-container-ft">
<div class="btn-box">
<div class="bor">
<div class="btn" v-if="isFormShow">确定</div>
<div class="btn" v-else @click="intoForm">进入此用户群</div>
<div class="right-btn">
<div class="btn" @click="isCurrentCardShow = !isCurrentCardShow">当前案例背景</div>
<div class="btn" @click="goPage('/caseSelection')">切换案例背景</div>
<div class="current-card">
<currentCard v-if="isCurrentCardShow" :data="cardData"/>
</div>
</div>
</div>
</div>
</div>
</template>
</app-container>
</template>
<script>
import AppContainer from '@/components/AppContainer'
import item from './components/item.vue'
import currentCard from './components/currentCard.vue'
import formRadio from './components/form.vue'
import * as api from '@/api/common.js'
export default {
components: {
AppContainer,
item,
currentCard,
formRadio
},
data() {
return {
isCurrentCardShow: false,
isFormShow: false,
list: [],
cardData: {},
casesId: 1,
currentCasesId: 1,
formData: []
}
},
mounted() {
this.getCaseList()
},
methods: {
currentSelect(id) {
this.currentCasesId = id
},
// 进入表单
intoForm() {
this.formData = this.list.find(item => {
return item.id === this.currentCasesId
}).characteristics
this.isFormShow = true
},
// 跳转页面
goPage(path) {
this.$router.push({
path: path
})
},
// 获取案例列表
getCaseList() {
api
.getCaseList({ level: this.$store.state.level })
.then(response => {
this.cases = response.data.cases
const id = parseInt(response.data.selected_case_id)
this.casesId = id
this.cardData = response.data.cases.find(item => { return parseInt(item.id) === id })
this.getUserGroup(id)
})
.finally(() => {
})
},
// 获取群组
getUserGroup(id) {
api
.getUserGroup({ case_id: id })
.then(response => {
this.list = response.data
this.currentCasesId = response.data[0].id
})
.finally(() => {
})
}
}
}
</script>
<style scoped lang="scss">
.app-container{
::v-deep .app-container-hd{
margin-bottom: 0;
}
}
.form{
width: 100%;
}
.card-box{
position: relative;
}
.tips{
font-size: 14px;
color: #222222;
margin-bottom: 16px;
}
.btn-box{
width: 100%;
// padding: 0 16px;
background: #fff;
box-sizing: border-box;
position: sticky;
bottom: 0;
left: 0;
.bor{
display: flex;
align-items: center;
width: 100%;
height: 100%;
}
.right-btn{
position: relative;
margin-left: auto;
display: flex;
.btn{
&:nth-child(1){
margin-right: 16px;
}
}
.current-card{
position: absolute;
bottom: 150%;
left: -43%;
}
}
.btn{
cursor: pointer;
font-size: 14px;
color: #F8F8F8;
line-height: 32px;
padding: 0 24px;
height: 32px;
background: linear-gradient(315deg, rgba(225, 47, 116, 0.83) 0%, #C01540 100%);
border-radius: 4px;
}
}
.back{
width: 20px;
height: 18px;
background: url(@/assets/images/out.png);
background-size: 100% 100%;
cursor: pointer;
}
</style>
<template>
<div>
<ul>
<li class="form-item">
<i class="el-icon-s-promotion"></i>
<div class="name">触达方式</div>
<el-select v-model="form.reach_way_id" placeholder="请选择">
<el-option
v-for="item in data.reach_ways"
:key="item.id"
:label="item.context"
:value="item.id">
</el-option>
</el-select>
</li>
<li class="form-item">
<i class="el-icon-s-custom"></i>
<div class="name">用户群</div>
<el-select v-model="form.cgroup_id" placeholder="请选择">
<el-option
v-for="item in data.groups"
:key="item.id"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
</li>
<li class="form-item">
<i class="el-icon-time"></i>
<div class="name">触达时间</div>
<el-select v-model="form.reach_date_id" placeholder="请选择">
<el-option
v-for="item in data.reach_dates"
:key="item.id"
:label="item.context"
:value="item.id">
</el-option>
</el-select>
</li>
</ul>
</div>
</template>
<script>
export default {
props: {
data: { type: Object, default: {} },
form: { type: Object, default: {} }
},
data() {
return {
groups: [],
reachDates: [],
reachWays: []
}
},
created() {
}
}
</script>
<style lang="scss" scoped>
ul{
margin-top: -16px;
.form-item{
display: flex;
height: 73px;
border-top: 1px solid #eee;
align-items: center;
&:nth-child(1){
border: none;
}
i{
font-size: 22px;
color: #999;
}
.name{
width: 76px;
font-size: 14px;
color: #999999;
margin-left: 10px;
}
}
}
</style>
<template>
<div>
<v-editor v-model="essay_description"></v-editor>
</div>
</template>
<script>
import VEditor from '@/components/ckeditor'
export default {
components: {
VEditor
},
data() {
return {
essay_description: ''
}
},
mounted() {
},
watch: {
essay_description() {
this.$emit('getEssay', this.essay_description)
}
}
}
</script>
<style lang="scss" scoped>
</style>
<template>
<div class="trigger-box">
<app-container title="用户触达" class="trigger-top">
<el-steps :space="200" :active="active" process-status="wait">
<el-step title="触达方式"></el-step>
<el-step title="文案编辑"></el-step>
</el-steps>
</app-container>
<app-container class="trigger-mian">
<template v-if="!active">
<step1 :data="stepFormData" :form="formData"/>
</template>
<template v-else>
<step2 @getEssay="getEssay"/>
</template>
<template #footer>
<div class="app-container-ft">
<div class="btn-box">
<div class="bor">
<div class="btn" @click="stepConfirm">确定</div>
<div class="right-btn">
<div class="btn" @click="isCurrentCardShow = !isCurrentCardShow">当前案例背景</div>
<div class="btn" @click="goPage('/caseSelection')">切换案例背景</div>
<div class="current-card">
<currentCard v-if="isCurrentCardShow" :data="cardData"/>
</div>
</div>
</div>
</div>
</div>
</template>
</app-container>
</div>
</template>
<script>
import AppContainer from '@/components/AppContainer'
import currentCard from '../groupAnalysis/components/currentCard'
import step1 from './components/step1'
import step2 from './components/step2'
import * as api from '@/api/common.js'
export default {
components: {
AppContainer,
currentCard,
step1,
step2
},
data() {
return {
isCurrentCardShow: false,
active: 0,
stepShow: true,
stepFormData: {},
essayDescription: '',
formData: {
case_id: '',
cgroup_id: '',
reach_way_id: '',
reach_date_id: ''
}
}
},
mounted() {
this.getCaseList()
},
methods: {
// 跳转页面
goPage(path) {
this.$router.push({
path: path
})
},
getEssay(val) {
this.essayDescription = val
},
stepConfirm() {
if (this.active === 0) {
const isNull = Object.values(this.formData).find(item => { return item === '' })
if (isNull !== undefined) {
this.$message({
message: '请选择',
type: 'warning'
})
} else {
api
.submitTrigger(this.formData)
.then(response => {
this.messageBox(response.data.result)
})
.finally(() => {
})
}
} else {
if (this.essayDescription === '') {
this.$message({
message: '请填写',
type: 'warning'
})
} else {
const newData = Object.assign(this.formData, { context: this.essayDescription })
api
.submitContext(newData)
.then(response => {
this.messageBox2(response.data.result)
})
.finally(() => {
})
}
}
},
messageBox(n) {
if (n) {
this.$confirm('您做得很好,是否要进入文案编辑?', '提示', {
confirmButtonText: '确认进入',
cancelButtonText: '留在此页',
type: 'warning'
}).then(() => {
this.active = 1
}).catch(() => {
})
} else {
this.$alert('您的触达方案有问题,请重新来过。', '提示', {
confirmButtonText: '确定',
callback: action => {
}
})
}
},
messageBox2(n) {
if (n) {
this.$confirm('您做得很好,是否要进入案例选择页面?', '提示', {
confirmButtonText: '确认进入',
cancelButtonText: '留在此页',
type: 'warning'
}).then(() => {
this.$router.push({
path: '/caseSelection'
})
}).catch(() => {
})
} else {
this.$alert('您的触达方案有问题,请重新来过。', '提示', {
confirmButtonText: '确定',
callback: action => {
}
})
}
},
getTriggerList(id) {
api
.getTriggerList({ case_id: id })
.then(response => {
this.stepFormData = response.data
})
.finally(() => {
})
},
// 获取案例列表
getCaseList() {
api
.getCaseList({ level: this.$store.state.level })
.then(response => {
// this.cases = response.data.cases
const id = parseInt(response.data.selected_case_id)
this.casesId = id
this.cardData = response.data.cases.find(item => { return parseInt(item.id) === id })
this.getTriggerList(id)
this.formData.case_id = id
})
.finally(() => {
})
}
}
}
</script>
<style scoped lang="scss">
.trigger-box{
height: 100%;
.trigger-top{
height: auto;
}
.trigger-mian{
margin-top: 20px;
height: 70%;
}
}
::v-deep .el-step__head.is-success{
color: #fff;
border-color: #C01540;
.el-step__icon{
background: #C01540;
}
}
.trigger-mian{
}
.btn-box{
width: 100%;
// padding: 0 16px;
background: #fff;
box-sizing: border-box;
position: sticky;
bottom: 0;
left: 0;
.bor{
display: flex;
align-items: center;
width: 100%;
height: 100%;
}
.right-btn{
position: relative;
margin-left: auto;
display: flex;
.btn{
&:nth-child(1){
margin-right: 16px;
}
}
.current-card{
position: absolute;
bottom: 150%;
left: -43%;
}
}
.btn{
cursor: pointer;
font-size: 14px;
color: #F8F8F8;
line-height: 32px;
padding: 0 24px;
height: 32px;
background: linear-gradient(315deg, rgba(225, 47, 116, 0.83) 0%, #C01540 100%);
border-radius: 4px;
}
}
</style>
<template>
<app-container title="请选择您要进入的案例背景">
<template>
<div class="list" v-for="item in arr" :key="item.index" @click="clk(item.index)" ref="main" :flag="flag">
<it-em :id="activeIndex == item.index ? 'clk' : ''">
<template v-slot:title>
<div>
<img :src="item.imgsrc" alt="" srcset="" />
<p>{{ item.title }}</p>
</div>
</template>
<template v-slot:xm>
<div>姓名</div>
<div>{{ item.name }}</div>
</template>
<template v-slot:gs>
<div>公司</div>
<div>{{ item.gs }}</div>
</template>
<template v-slot:bm>
<div>部门</div>
<div>{{ item.bm }}</div>
</template>
<template v-slot:zw>
<div>职位</div>
<div>{{ item.zw }}</div>
</template>
<template v-slot:cp>
<div>营销产品</div>
<div>{{ item.cp }}</div>
</template>
</it-em>
</div>
</template>
<!-- <it-em>
<template v-slot:title>
<div>
<img src="../../../assets/images/gsxx.png" alt="" srcset="">
<p>案例分析2</p>
</div>
</template>
<template v-slot:xm>
<div>姓名</div>
<div>立马</div>
</template>
<template v-slot:gs>
<div>公司</div>
<div>建国保险公司</div>
</template>
<template v-slot:bm>
<div>部门</div>
<div>市场营销部</div>
</template>
<template v-slot:zw>
<div>职位</div>
<div>市场营销专员</div>
</template>
<template v-slot:cp>
<div>营销产品</div>
<div>建国重疾险</div>
</template>
</it-em>
<it-em>
<template v-slot:title>
<div>
<img src="../../../assets/images/gsxx.png" alt="" srcset="">
<p>案例分析3</p>
</div>
</template>
<template v-slot:xm>
<div>姓名</div>
<div>立马</div>
</template>
<template v-slot:gs>
<div>公司</div>
<div>建国保险公司</div>
</template>
<template v-slot:bm>
<div>部门</div>
<div>市场营销部</div>
</template>
<template v-slot:zw>
<div>职位</div>
<div>市场营销专员</div>
</template>
<template v-slot:cp>
<div>营销产品</div>
<div>建国重疾险</div>
</template>
</it-em> -->
<template #footer>
<div class="app-container-ft">
<el-button type="primary" size="mini" @click="open()">开始实训</el-button>
<el-button type="primary" size="mini" @click="jump()">查看背景详情</el-button>
</div>
</template>
</app-container>
</template>
</app-container>
</template>
<script>
import AppContainer from '@/components/AppContainer'
import ItEm from './item.vue'
export default {
components: { AppContainer, ItEm },
data() {
return {
arr: [
{
imgsrc: require('../../../assets/images/gsxx.png'),
title: '案例分析1',
name: '立马',
gs: '建国保险公司',
bm: '市场营销部',
zw: '市场营销专员',
cp: '建国重疾险',
index: 1
},
{
imgsrc: require('../../../assets/images/gsxx.png'),
title: '案例分析2',
name: '立马',
gs: '建国保险公司',
bm: '市场营销部',
zw: '市场营销专员',
cp: '建国重疾险',
index: 2
},
{
imgsrc: require('../../../assets/images/gsxx.png'),
title: '案例分析3',
name: '立马',
gs: '建国保险公司',
bm: '市场营销部',
zw: '市场营销专员',
cp: '建国重疾险',
index: 3
}
],
activeIndex: -1,
flag: false,
main1: false,
main2: false,
main3: false
}
},
methods: {
clk(index) {
this.activeIndex = index
},
jump() {
if (this.activeIndex !== -1) {
this.$router.push('/yhfq/alfx')
}
},
open() {
window.location.href = 'http://eademo-test.ezijing.com/app.html#/InAppList'
}
}
}
</script>
<style scoped lang="scss">
app-container {
overflow: hidden;
// it-em {
// float: left;
// margin-right: 20px;
// }
}
#clk {
box-shadow: 0px 8px 16px 0px rgba(192, 21, 64, 0.4);
border: 1px solid #c01540;
}
</style>
<template>
<div class="main" ref="main" flag='true'>
<div class="head">
<slot name="title"></slot>
</div>
<slot name="content"></slot>
<ul>
<li>
<slot name="xm"></slot>
</li>
<div class="line"></div>
<li>
<slot name="gs"></slot>
</li>
<div class="line"></div>
<li>
<slot name="bm"></slot>
</li>
<div class="line"></div>
<li>
<slot name="zw"></slot>
</li>
<div class="line"></div>
<li>
<slot name="cp"></slot>
</li>
</ul>
</div>
</template>
<script>
// import $ from 'jquery'
export default {
data() {
return {
flag: false
}
},
methods: {
// clk() {
// this.flag = !this.flag
// if (this.flag) {
// this.$refs.main.id = 'clk'
// // this.$refs.main.id = ''
// // console.log(this.$refs.main.nextSbiling)
// } else {
// this.$refs.main.id = ''
// }
// }
}
}
</script>
<style scoped lang="scss">
.main {
float: left;
margin-right: 20px;
width: 228px;
height: 344px;
background: #ffffff;
box-shadow: 0px 2px 10px 0px rgba(88, 111, 174, 0.1);
border-radius: 6px;
overflow: hidden;
.head {
width: 228px;
height: 81px;
line-height: 81px;
// background: #000000;
opacity: 0.9;
text-align: center;
div {
width: 100%;
height: 100%;
position: relative;
p {
position: absolute;
top: 0px;
left: 50%;
transform: translateX(-50%);
font-size: 24px;
font-family: PingFangSC-Semibold, PingFang SC;
font-weight: 600;
color: #ffffff;
z-index: 999999;
}
}
}
ul {
width: 100%;
height: 263px;
display: flex;
flex-direction: column;
li {
width: 100%;
flex: 1;
display: flex;
div {
flex: 0.7;
display: flex;
align-items: center;
font-size: 14px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #666666;
letter-spacing: 1px;
margin-right: 1px;
padding-left: 10px;
box-sizing: border-box;
}
div:nth-child(2) {
flex: 1;
margin-right: 0px;
}
}
.line {
margin-top: 2px;
margin-left: 50%;
transform: translateX(-50%);
width: 212px;
height: 1px;
background: #eeeeee;
}
}
}
.main:hover {
box-shadow: 0px 8px 16px 0px rgba(88, 111, 174, 0.3);
}
// #clk {
// box-shadow: 0px 8px 16px 0px rgba(192, 21, 64, 0.4);
// border: 1px solid #c01540;
// }
</style>
<template>
<app-container title="案例分析">
<template #header>
<img style="cursor: pointer" src="../../../assets/images/out.png" alt="" srcset="" @click="out()" />
</template>
<it-em>
<template v-slot:title>
<div>
<img src="../../../assets/images/gsxx.png" alt="" srcset="" />
<p>公司信息</p>
</div>
</template>
<template v-slot:content>
们反整造布报该效以约三南真内斯属片理写农基解日应各数备等音史区叫信快林无积立包与法类题方极到结才月中听全三原主干前当百片身相表。完值面经市确验心究知水位本口派究料在使和之思查而压被力没斯该行和要难最酸外品完口走厂形务群按维不济有导适次的报心育采之半正派任主合还。
</template>
</it-em>
<it-em>
<template v-slot:title>
<div>
<img src="../../../assets/images/cpxx.png" alt="" srcset="" />
<p>产品信息</p>
</div>
</template>
<template v-slot:content>
们反整造布报该效以约三南真内斯属片理写农基解日应各数备等音史区叫信快林无积立包与法类题方极到结才月中听全三原主干前当百片身相表。完值面经市确验心究知水位本口派究料在使和之思查而压被力没斯该行和要难最酸外品完口走厂形务群按维不济有导适次的报心育采之半正派任主合还。
</template>
</it-em>
<it-em>
<template v-slot:title>
<div>
<img src="../../../assets/images/zwxx.png" alt="" srcset="" />
<p>职位信息</p>
</div>
</template>
<template v-slot:content>
们反整造布报该效以约三南真内斯属片理写农基解日应各数备等音史区叫信快林无积立包与法类题方极到结才月中听全三原主干前当百片身相表。完值面经市确验心究知水位本口派究料在使和之思查而压被力没斯该行和要难最酸外品完口走厂形务群按维不济有导适次的报心育采之半正派任主合还。
</template>
</it-em>
<template #footer>
<div class="app-container-ft">
<el-button type="primary" size="mini" @click="open()">开始实训</el-button>
</div>
</template>
</app-container>
</template>
<script>
import AppContainer from '@/components/AppContainer'
import ItEm from './item.vue'
export default {
components: { AppContainer, ItEm },
data() {
return {}
},
methods: {
out() {
this.$router.push('/yhfq/albj')
},
open() {
window.location.href = 'http://eademo-test.ezijing.com/app.html#/InAppList'
}
}
}
</script>
<template>
<div class="main" ref="main">
<div class="head">
<slot name="title"></slot>
</div>
<div class="bottom">
<slot name='content'></slot>
</div>
</div>
</template>
<script>
export default {
data() {
return {
flag: false
}
},
methods: {
clk() {
this.flag = !this.flag
if (this.flag) {
this.$refs.main.id = 'clk'
} else {
this.$refs.main.id = ''
}
}
}
}
</script>
<style scoped lang="scss">
.main {
float: left;
margin-right: 20px;
width: 228px;
height: 344px;
background: #ffffff;
box-shadow: 0px 2px 10px 0px rgba(88, 111, 174, 0.1);
border-radius: 6px;
overflow: hidden;
.head {
width: 228px;
height: 81px;
line-height: 81px;
opacity: 0.9;
text-align: center;
overflow: hidden;
div {
width: 100%;
height: 100%;
position: relative;
p {
position: absolute;
top: 0px;
left: 50%;
transform: translateX(-50%);
font-size: 24px;
font-family: PingFangSC-Semibold, PingFang SC;
font-weight: 600;
color: #ffffff;
z-index: 999999;
}
}
}
.bottom {
padding-left: 10px;
padding-top: 10px;
padding-right: 5px;
box-sizing: border-box;
width: 100%;
height: 263px;
font-size: 14px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #666666;
line-height: 22px;
letter-spacing: 1px;
}
}
.main:hover {
box-shadow: 0px 8px 16px 0px rgba(88, 111, 174, 0.3);
}
#clk {
box-shadow: 0px 8px 16px 0px rgba(192, 21, 64, 0.4);
border: 1px solid #C01540;
}
</style>
<template>
<app-container title="用户群分析"> 用户群分析 </app-container>
</template>
<script>
import AppContainer from '@/components/AppContainer'
export default {
components: { AppContainer },
data() {
return {}
}
}
</script>
import Layout from '@/components/layout'
// 用户分群
const userGroup = [
/* 首页 */
{ path: '/yhfq', redirect: '/yhfq/albj' },
{ path: '/yhfq/albj', component: () => import(/* webpackChunkName: "usergroup" */ '@/pages/yhfq/albj') },
{ path: '/albj', component: () => import(/* webpackChunkName: "usergroup" */ '@/pages/yhfq/albj') },
{ path: '/yhfq/alfx', component: () => import(/* webpackChunkName: "usergroup" */ '@/pages/yhfq/alfx') },
{ path: '/yhfq/yhqfx', component: () => import(/* webpackChunkName: "usergroup" */ '@/pages/yhfq/yhqfx') }
]
export default [
{ path: '*', redirect: '/yhfq/albj' },
{ path: '/', redirect: '/yhfq/albj' },
{ path: '*', redirect: '/' },
{
path: '/',
component: Layout,
children: [
{ path: '', redirect: '/caseSelection' },
/* 首页 */
// { path: '/index', component: () => import(/* webpackChunkName: "feedback" */ '@/pages/home') },
/* 修改密码 */
......@@ -24,7 +14,21 @@ export default [
path: '/account/password',
component: () => import(/* webpackChunkName: "account" */ '@/pages/account/password')
},
...userGroup
/* 用户群分析 */
{
path: '/groupAnalysis',
component: () => import(/* webpackChunkName: "groupAnalysis" */ '@/pages/groupAnalysis/index.vue')
},
/* 用户触达 */
{
path: '/userTrigger',
component: () => import(/* webpackChunkName: "userTrigger" */ '@/pages/userTrigger/index.vue')
},
/* 背景选择 */
{
path: '/caseSelection',
component: () => import(/* webpackChunkName: "userTrigger" */ '@/pages/caseSelection/index.vue')
}
]
}
]
import Vue from 'vue'
import Vuex from 'vuex'
import { getUser, logout } from '@/api/account'
import { getUser, logout, getUserGrade } from '@/api/account'
Vue.use(Vuex)
const store = new Vuex.Store({
......@@ -9,7 +9,8 @@ const store = new Vuex.Store({
user: {},
isLogin: false,
isIos: /iphone|ipad|ipod/i.test(navigator.userAgent),
isAndroid: /android/i.test(navigator.userAgent)
isAndroid: /android/i.test(navigator.userAgent),
level: {}
},
mutations: {
setUser(state, user) {
......@@ -17,6 +18,9 @@ const store = new Vuex.Store({
},
setIsLogin(state, isLogin) {
state.isLogin = isLogin
},
setUserGrade(state, level) {
state.level = level
}
},
actions: {
......@@ -25,6 +29,11 @@ const store = new Vuex.Store({
commit('setUser', response)
})
},
getUserGrade({ commit }) {
getUserGrade().then(response => {
commit('setUserGrade', response)
})
},
// 退出登录
logout({ commit }) {
return logout().then(response => {
......@@ -35,6 +44,12 @@ const store = new Vuex.Store({
},
// 检测登录状态
async checkLogin({ commit }) {
await getUserGrade()
.then(response => {
commit('setUserGrade', response.data.level)
})
.catch(() => {
})
const isLogin = await getUser()
.then(response => {
commit('setUser', response.data)
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论