订单统计会员

master
lion 2 years ago
parent bc0b740f82
commit 21649936f7

@ -0,0 +1,49 @@
import request from '@/utils/request'
export function index(params){
return request({
method:'get',
url:'/api/admin/course/index',
params
})
}
export function show(params){
return request({
method:'get',
url:'/api/admin/course/show',
params
})
}
export function save(data){
return request({
method:'post',
url:'/api/admin/course/save',
data
})
}
export function store(data){
return request({
method:'post',
url:'/api/admin/course/store',
data
})
}
export function destroy(data){
return request({
method:'post',
url:'/api/admin/course/destroy',
data
})
}
export function delCourseItem(params){
return request({
method:'post',
url:'/api/admin/course/destroy-item',
params
})
}

@ -171,6 +171,10 @@ export default {
type: Boolean,
default: true,
},
showIndex:{
type: Boolean,
default: true,
}
},
data() {
return {
@ -663,10 +667,15 @@ export default {
["expand-change"]: this.expandChange,
}}
>
<el-table-column
type="index"
width="50" fixed="left" align="center" >
</el-table-column>
{
(this.showIndex? <el-table-column
type="index"
width="50" fixed="left" align="center" >
</el-table-column>:""
)
}
{this.tableFormat.map((item, index) => {
if ($scopedSlots[item.prop]) {
return $scopedSlots[item.prop](item, index);

@ -0,0 +1,345 @@
<template>
<div>
<xy-dialog ref="dialog" :is-show.sync="isShow" type="form" :title="type === 'add' ? '新增课程' : '编辑课程'" :form="form"
:rules="rules" @submit="submit">
<template v-slot:title>
<div class="xy-table-item">
<div class="xy-table-item-label">
<span style="color: red;font-weight: 600;padding-right: 4px;">*</span>课程名称
</div>
<div class="xy-table-item-content">
<el-input v-model="form.title" placeholder="请输入课程名称" clearable style="width: 300px;"></el-input>
</div>
</div>
</template>
<template v-slot:course_list>
<div class="xy-table-item">
<div class="xy-table-item-label">课程表</div>
<div class="xy-table-item-content">
<Button type="primary" icon="md-add" style="margin-bottom: 10px"
@click="form.course_list.push({ sortnumber:0,name: '',time:'', address: '',speaker:'',link:'' })">新增</Button>
<xy-table style="width: 100%" :height="560" :is-page="false" :showIndex='false' :list="form.course_list"
:table-item="contentTable">
<template v-slot:btns>
<el-table-column label="操作" width="90" header-align="center" align="center">
<template v-slot:default="scope">
<Poptip transfer confirm title="确认要删除吗?" @on-ok="delItem(scope.row.id,scope.$index)">
<Button size="small" type="primary" ghost>删除</Button>
</Poptip>
</template>
</el-table-column>
</template>
</xy-table>
</div>
</div>
</template>
</xy-dialog>
</div>
</template>
<script>
import {
store,
show,
save,
delCourseItem
} from "@/api/course"
import {
Message
} from 'element-ui'
import {
index
} from "@/api/activity"
export default {
data() {
return {
isShow: false,
type: 'add',
id: '',
form: {
title: '',
course_list: []
},
rules: {
title: [{
required: true,
message: '请输入课程名称'
}]
},
activeList: [],
contentTable: [{
label: "序号",
minWidth: 80,
customFn: (row, scope) => {
return ( <el-input placeholder = "请填写序号"
type = "text"
v-model = {
row.sortnumber
} >
</el-input>
);
},
},
{
label: "课程名称",
width: 240,
customFn: (row) => {
return ( <el-select placeholder = "请选择课程"
style = "width: 240px"
v-model = {
row.name
}
clearable filterable on = {
{
["change"]: (e) => this.changeActive(e, row),
}
} >
{
this.activeList.map((item, index) => {
return ( <el-option
// v-for={item in activeList}
value = {item}
key = {item.id}
label = {item.active_name} >
</el-option>
)
})
} </el-select>
);
},
},
{
label: "课程时间",
minWidth: 180,
customFn: (row, scope) => {
return ( <el-input placeholder = "请填写课程时间"
type = "text"
v-model = {
row.time
}>
</el-input>
);
},
},
{
label: "课程地址",
minWidth: 240,
customFn: (row, scope) => {
return ( <el-input placeholder = "请填写课程地址"
type = "text"
v-model = {
row.address
} >
</el-input>
);
},
},
{
label: "主讲人",
minWidth: 180,
customFn: (row, scope) => {
return ( <el-input placeholder = "请填写主讲人"
type = "text"
v-model = {
row.speaker
} >
</el-input>
);
},
},
{
label: "链接",
minWidth: 180,
customFn: (row, scope) => {
return ( <el-input placeholder = "请填写链接"
type = "text"
v-model = {
row.link
} >
</el-input>
);
},
}
],
}
},
created() {
this.getActivity()
},
methods: {
delItem(id, index) {
if (id) {
delCourseItem({
id: id
}).then(res=>{
Message({
type: 'success',
message: '删除成功'
})
this.form.course_list.splice(index, 1)
})
} else {
this.form.course_list.splice(index, 1)
}
},
async getActivity() {
const res = await index({
page_size: 99,
page: 1,
});
this.activeList = res?.data;
},
changeActive(e, row) {
row.name = e.active_name
row.time = e.start_date + ' ' + e.start_time
//
row.address = e.address
row.speaker = ''
row.link = '/pages/active/detail?id=' + e.id
console.log("e", e)
},
returnDate(date, time) {
let str = ''
let dates = date.split('-')
let md = parseInt(dates[1]) + '月' + parseInt(dates[2]) + '日'
str = md + '/' + time
},
async getDetail() {
const res = await show({
id: this.id
})
this.form = {
title: res?.title,
course_list: res?.item
}
},
submit() {
if (this.type === 'add') {
console.log(this.form)
// return
store({
title: this.form.title,
course_list: this.form.course_list
}).then(res => {
Message({
type: 'success',
message: '新增课程成功'
})
this.isShow = false
this.$emit('refresh')
})
return
}
if (this.type === 'editor') {
save({
id: this.id,
title: this.form.title,
course_list: this.form.course_list
}).then(res => {
Message({
type: 'success',
message: '编辑课程成功'
})
this.isShow = false
this.$emit('refresh')
})
}
}
},
watch: {
isShow(newVal) {
if (newVal) {
if (this.type === 'editor' || this.type === 'copy') {
this.getDetail()
}
} else {
this.id = ''
this.type = ''
this.$refs['dialog'].reset()
}
}
}
}
</script>
<style scoped lang="scss">
.xy-table-item-label {
width: 160px;
}
.img__delete {
transform: scale(0.8, 0.8);
position: absolute;
top: 4px;
right: 4px;
}
::v-deep .avatar-uploader .el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
}
::v-deep .avatar-uploader .el-upload:hover {
border-color: #409EFF;
}
::v-deep .el-upload--picture-card {
font-size: 28px;
color: #8c939d;
width: 80px !important;
height: 80px !important;
line-height: 80px !important;
text-align: center;
}
::v-deep .avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 80px !important;
height: 80px !important;
line-height: 80px !important;
text-align: center;
}
::v-deep .avatar {
width: 80px !important;
display: block;
border-radius: 6px;
}
::v-deep .xy-table-item-label {
width: 160px !important;
}
::v-deep .el-date-editor .el-range-separator {
width: auto !important;
}
::v-deep .el-input-number .el-input__inner {
text-align: left !important;
}
.searchCompanys {
display: flex;
justify-content: space-between;
margin-bottom: 16px;
.el-input {
width: 80%
}
}
</style>

@ -0,0 +1,115 @@
<template>
<div style="padding: 0 20px">
<div ref="lxHeader">
<lx-header icon="md-apps" text="课程表列表" style="margin-bottom: 10px; border: 0px; margin-top: 15px">
<slot>
<div style="display: flex;justify-content: flex-start;flex-wrap: wrap;">
<Input v-model="select.title" style="width: 200px;margin-right: 10px;" placeholder="关键字搜索" />
<Button type="primary" @click="getCourse"></Button>
<Button icon="ios-add" type="primary" style="margin-left: 10px;" @click="$refs['addCourse'].isShow = true,$refs['addCourse'].type = 'add'">添加</Button>
</div>
</slot>
</lx-header>
</div>
<xy-table
:list="list"
:total="total"
@pageSizeChange="e => select.pageSize = e"
@pageIndexChange="pageChange"
:table-item="table">
<template v-slot:btns>
<el-table-column fixed="right" label="操作" width="260" header-align="center">
<template slot-scope="scope">
<Button type="primary" size="small" @click="editorActivity(scope.row.id,'editor')"></Button>
<Poptip
transfer
confirm
title="确认要删除吗?"
@on-ok="deleteActivity(scope.row)">
<Button type="primary" style="margin-left: 10px;" size="small" ghost>删除</Button>
</Poptip>
</template>
</el-table-column>
</template>
</xy-table>
<addCourse ref="addCourse" @refresh="getCourse"></addCourse>
</div>
</template>
<script>
import {index,destroy} from "@/api/course"
import addCourse from '@/views/course/component/addCourse'
import { Message } from 'element-ui'
export default {
components:{
addCourse
},
data() {
return {
select:{
pageSize:10,
pageIndex:1,
title:""
},
total:0,
list:[],
table:[
{
label:"课程名称",
prop:'title',
align:'left',
},
{
label:"链接",
prop:'link',
align:'left',
formatter: (cell, data, value, index) => {
return '/pages/active/course?id='+cell.id
}
}
]
}
},
methods: {
async getCourse(){
const res = await index({
page_size:this.select.pageSize,
page:this.select.pageIndex,
title:this.select.title
})
this.list = res.data
this.total = res.total
},
pageChange(e){
this.select.pageIndex = e
this.getCourse()
},
deleteActivity(row){
destroy({id:row.id}).then(res => {
Message({
type:'success',
message:'删除课程成功'
})
this.getCourse()
})
},
editorActivity(id,type){
this.$refs['addCourse'].id = id
this.$refs['addCourse'].type = type
this.$refs['addCourse'].isShow = true
},
},
mounted() {
this.getCourse()
}
}
</script>
<style scoped lang="scss">
</style>

@ -236,7 +236,7 @@
label: "订单名称",
width: 220,
align: 'left',
fixed: 'left'
// fixed: 'left'
},
{
prop: 'bookable_name',

@ -68,10 +68,29 @@
{
prop: 'max_order',
label: '多次下单人数',
width: 180,
formatter: (cell, data, value) => {
return value ? value : 0
}
width: 180,
customFn: (row) => {
return ( <div style = {
{
textDecoration:'underline',
cursor: 'pointer',
color: "#bf617c"
}
}
on = {
{
['click']: (e) => {
this.toReturnUser(row.id)
}
}
}>
{
row.max_order?row.max_order:0
} </div> )
}
// formatter: (cell, data, value) => {
// return value ? value : 0
// }
},
{
prop: 'max_product.name',
@ -81,7 +100,11 @@
]
}
},
methods: {
methods: {
toReturnUser(id){
let url =`/admin/#/reports/userOrder?total_related_person=5&product_pid=`+id+`&start_date=`+this.select.start_date+`&end_date=`+this.select.end_date
let seeBuy = window.open(url, 'seeBuy','location=0')
},
summaryMethod(param) {
console.log("para", param)
const {

@ -18,9 +18,9 @@
</el-date-picker>
</div>
<div class="totals">
<p><span>总退单人数</span><span>{{list.total_return_order_person}}</span></p>
<p><span>退单后仍会下单人数</span><span>{{list.total_return_order_once_more_person}}</span></p>
<p><span>退单后不再下单人数</span><span>{{list.total_return_order_no_person}}</span></p>
<p><span>总退单人数</span><span @click='toReturnUser(1)'>{{list.total_return_order_person}}</span></p>
<p><span>退单后仍会下单人数</span><span @click='toReturnUser(2)'>{{list.total_return_order_once_more_person}}</span></p>
<p><span>退单后不再下单人数</span><span @click='toReturnUser(3)'>{{list.total_return_order_no_person}}</span></p>
<p><span>不再下单人数占退单总退单人数比例</span><span>{{returnPer(list.percentage)}}</span></p>
</div>
@ -77,6 +77,10 @@
returnPer(val){
return val?val.toFixed(4)*100 + "%":0
},
toReturnUser(id){
let url =`/admin/#/reports/userOrder?total_related_person=`+id+`&start_date=`+this.select.start_date+`&end_date=`+this.select.end_date
let seeBuy = window.open(url, 'seeBuy','location=0')
}
},
mounted() {
@ -106,5 +110,10 @@
width:50%;
display: inline-block;
border-right: 1px solid #ddd;
}
.totals p span:last-child{
color:#bf617c;
cursor:pointer;
text-decoration: underline;
}
</style>

@ -10,8 +10,9 @@
<el-date-picker style="margin-left:10px" v-model="dateRange" type="daterange" value-format="yyyy-MM-dd"
range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" @change="dateChange">
</el-date-picker>
<el-cascader ref="typeCas" style="margin-left:10px" v-model="typeCas" :options="options"
:props="props" collapse-tags @change="changeType" @remove-tag="removeType" clearable></el-cascader>
<el-cascader ref="typeCas" style="margin-left:10px;width:400px" v-model="typeCas" :options="options"
:props="props" @change="changeType" @remove-tag="removeType" clearable></el-cascader>
<!-- collapse-tags -->
<el-button style="margin-left:10px" type="primary" @click="getTotal"></el-button>
</div>
<div class="totals">
@ -19,7 +20,7 @@
<p><span>下单订单数</span><span>{{list.add_total_order}}</span></p>
<p><span>下单取消数</span><span>{{list.add_total_order_canceled}}</span></p>
<p><span>下单完成数</span><span>{{list.add_total_order_finished}}</span></p>
<p><span>多板块下单人数</span><span>{{list.total_order_more_type_person}}</span></p>
<p><span>多板块下单人数</span><span style=' color:#bf617c;cursor:pointer;text-decoration: underline;' @click='toReturnUser(4)'>{{list.total_order_more_type_person}}</span></p>
</div>
</div>
@ -96,6 +97,21 @@
this.select.end_date = this.today
}
this.getTotal()
},
toReturnUser(id){
// return
let product_type_list = ''
if(this.select.product_type_list.length<1){
product_type_list = ''
}else{
product_type_list = this.select.product_type_list.join(",")
}
console.log("this.select.product_type_list",this.select.product_type_list)
console.log("product_type_list",product_type_list)
// return
let url =`/admin/#/reports/userOrder?product_type_list=`+product_type_list+`&total_related_person=`+id+`&start_date=`+this.select.start_date+`&end_date=`+this.select.end_date
let seeBuy = window.open(url, 'seeBuy','location=0')
}
},

@ -95,7 +95,12 @@
create_time:'',
over_time:'',
order_count:'',
write_off:''
write_off:'',
total_related_person:'',
start_date:'',
end_date:'',
product_pid:'',
product_type_list:[]
},
dateRange:[],
areas: ["吴中区", "吴江区", "姑苏区", "工业园区", "高新区", "相城区", "昆山", "常熟", "张家港", "太仓"],
@ -180,7 +185,7 @@
}
}>
<div>
<span style={{'color':k.state=='finished'?'red':'#000'}}>{index+1}{k.state_name}</span>-
<span style={{'color':k.state=='finished'?'red':'#000'}}>{index+1}{k.items?.state_name}</span>-
<span>{k.created_at}</span>-
<span>{ k.order_name}</span>
</div>
@ -270,7 +275,12 @@
create_time:this.select.create_time,
over_time:this.select.over_time,
write_off:this.select.write_off,
order_count:this.select.order_count
order_count:this.select.order_count,
total_related_person:this.select.total_related_person,
start_date:this.select.start_date,
end_date:this.select.end_date,
product_pid:this.select.product_pid,
product_type_list:this.select.product_type_list
})
this.total = res.total
this.list = res.data
@ -284,10 +294,61 @@
area: this.select.area,
is_phone: this.select.is_phone ? 1 : ""
}, '用户列表.xlsx')
}
},
reloadUser(){
console.log("this.$route",this.$route)
// return
if(this.$route.query?.total_related_person){
this.select.total_related_person = this.$route.query.total_related_person
}
if(this.$route.query?.start_date){
this.select.start_date = this.$route.query.start_date
}
if(this.$route.query?.end_date){
this.select.end_date = this.$route.query.end_date
}
if(this.$route.query?.product_pid){
this.select.product_pid = this.$route.query.product_pid
}
if(this.$route.query?.product_type_list){
this.select.product_type_list = this.$route.query.product_type_list.split(',')
}
this.getMembers()
}
},
mounted() {
this.getMembers()
mounted() {
this.reloadUser()
},
watch:{
'$route.query.total_related_person'(newval){
if(newval){
this.reloadUser()
}
},
'$route.query.start_date'(newval){
if(newval){
this.reloadUser()
}
},
'$route.query.end_date'(newval){
if(newval){
this.reloadUser()
}
},
'$route.query.product_pid'(newval){
if(newval){
this.reloadUser()
}
},
'$route.query.product_type_list'(newval){
if(newval){
console.log("newval",newval)
this.reloadUser()
}
}
}
}

Loading…
Cancel
Save