刘翔宇-旅管家 4 years ago
parent f6c3cf7af9
commit 665b8dc8d0

@ -63,3 +63,12 @@ export function getItemLogs(params){
params params
}) })
} }
export function save(data){
return request({
method:'post',
url:'/api/admin/order/save',
data
})
}

@ -210,6 +210,7 @@ export default {
{tableItem && tableItem.length > 0 ? {tableItem && tableItem.length > 0 ?
(<el-table (<el-table
ref="table" ref="table"
fit="false"
show-summary={showSummary} show-summary={showSummary}
show-header={showHeader} show-header={showHeader}
summary-method={summaryMethod} summary-method={summaryMethod}

@ -98,11 +98,15 @@ div:focus {
} }
.v-table .el-table__body td { .v-table .el-table__body td {
padding: 9px 0 !important; padding: 3px 0 !important;
}
.el-table__row td div.cell{
padding: 0 2px !important;
} }
.v-table .el-table__footer td { .v-table .el-table__footer td {
padding: 7px 0 !important; padding: 2px 0 !important;
} }
/* 2021.01.30修复火狐checkbox错位问题 */ /* 2021.01.30修复火狐checkbox错位问题 */
@ -190,4 +194,3 @@ top: 41px !important;
#nprogress .bar{ #nprogress .bar{
background: $primaryColor !important; background: $primaryColor !important;
} }

@ -1,9 +1,13 @@
<template> <template>
<div class="dashboard-editor-container"> <div class="dashboard-editor-container">
<div class="block" style="margin-bottom: 10px;display: flex;justify-content: flex-end;">
<el-date-picker @change="changeDate" v-model="search.date" value-format="yyyy-MM-dd" type="daterange"
:picker-options="pickerOptions" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期"
align="right">
</el-date-picker>
</div>
<panel-group :totaldata="totaldata" /> <panel-group :totaldata="totaldata" />
<el-row :gutter="32"> <el-row :gutter="32">
<el-col :xs="24" :sm="24" :lg="24"> <el-col :xs="24" :sm="24" :lg="24">
<div class="chart-wrapper"> <div class="chart-wrapper">
@ -41,6 +45,38 @@
}, },
data() { data() {
return { return {
search: {
sdate: "",
edate: "",
date: []
},
pickerOptions: {
shortcuts: [{
text: '最近一周',
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
picker.$emit('pick', [start, end]);
}
}, {
text: '最近一个月',
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
picker.$emit('pick', [start, end]);
}
}, {
text: '最近三个月',
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
picker.$emit('pick', [start, end]);
}
}]
},
totaldata: { totaldata: {
customer: {}, customer: {},
order: {} order: {}
@ -70,22 +106,49 @@
} }
} }
}, },
created: function() {}, created: function() {
this.search.date = this.getCurrMonthDays()
that.search.sdate = this.search.date[0]
that.search.edate = this.search.date[1]
},
mounted() { mounted() {
this.$nextTick(() => { this.$nextTick(() => {
this.load(); this.load();
this.loadItemData(); this.loadItemData();
}) })
}, },
methods: { methods: {
changeDate(e) {
var that = this;
this.search.date = e;
that.search.sdate = e[0];
that.search.edate = e[1];
this.load();
},
getCurrMonthDays() {
let date = []
let start = this.$moment().add('month', 0).format('YYYY-MM') + '-01'
let start_1 = this.$moment(start).format('YYYY-MM-DD')
let end = this.$moment(start).add('month', 1).format('YYYY-MM-DD') //
date.push(start_1)
date.push(end)
return date
},
async load() { async load() {
var that = this; var that = this;
await getcustomerData().then(res => { await getcustomerData({
start_date: that.search.sdate,
end_date: that.search.edate,
}).then(res => {
that.totaldata.customer = res; that.totaldata.customer = res;
}) })
await getorderData().then(res => { await getorderData({
start_date: that.search.sdate,
end_date: that.search.edate,
}).then(res => {
that.totaldata.order = res; that.totaldata.order = res;
}) })
}, },
@ -98,15 +161,15 @@
that.lineArr.xArr.push(m.date.split('-')[1] + "-" + m.date.split('-')[2]); that.lineArr.xArr.push(m.date.split('-')[1] + "-" + m.date.split('-')[2]);
that.lineArr.series[0].data.push(m.customer_total); that.lineArr.series[0].data.push(m.customer_total);
} }
}).catch((res) => {}) }).catch((res) => {})
getorderitemData().then((res) => { getorderitemData().then((res) => {
for (var m of res) { for (var m of res) {
that.lineArr.series[1].data.push(m.order_total); that.lineArr.series[1].data.push(m.order_total);
that.lineArr.series[2].data.push(m.paid_money_total); that.lineArr.series[2].data.push(m.paid_money_total);
} }
}).catch((res) => {}) }).catch((res) => {})
} }
} }

@ -0,0 +1,49 @@
<template>
<div>
<xy-dialog :is-show.sync="isShow" title="商户简介" ok-text="" @on-ok="submit">
</xy-dialog>
</div>
</template>
<script>
import {
save
} from "@/api/order"
import {
parseTime
} from '@/utils'
export default {
props: {
id: Number,
isShow: {
type: Boolean,
default: false
}
},
data() {
return {
}
},
methods: {
submit() {
}
},
watch: {
isShow(newVal) {
if (newVal) {
}
}
}
}
</script>
<style scoped lang="scss">
</style>

@ -1,325 +1,459 @@
<template> <template>
<div style="padding: 0 20px"> <div style="padding: 0 20px">
<div ref="lxHeader"> <div ref="lxHeader">
<lx-header icon="md-apps" text="订单管理" style="margin-bottom: 10px; border: 0px; margin-top: 15px"> <lx-header icon="md-apps" text="订单管理" style="margin-bottom: 10px; border: 0px; margin-top: 15px">
<slot> <slot>
<div style="display: flex"> <div style="display: flex">
<Input v-model="select.keyword" class="select" style="width: 200px; margin-right: 10px" placeholder="关键字搜索" /> <Input v-model="select.keyword" class="select" style="width: 200px; margin-right: 10px"
<Button class="select" type="primary" style="margin-right: 10px;" @click="getOrders"></Button> placeholder="关键字搜索" />
<xy-selectors @search="getOrders"> <Button class="select" type="primary" style="margin-right: 10px;" @click="searchOrder"></Button>
<template> <xy-selectors @search="searchOrder">
<div class="select-content-item"> <template>
<div class="select-content-item-label">所属商户</div> <el-row>
<div> <el-col :span="12">
<el-select size="small" :value="select.merchant ? select.merchant.name : ''" placeholder="所属商户" @change="e => select.merchant = e"> <div class="select-content-item">
<el-option v-for="item in merchants" :key="item.id" :value="item" :label="item.name"></el-option> <div class="select-content-item-label">所属商户</div>
</el-select> <div>
</div> <el-select size="small" :value="select.merchant ? select.merchant.name : ''" placeholder="所属商户"
</div> @change="e => select.merchant = e">
<el-option v-for="item in merchants" :key="item.id" :value="item" :label="item.name">
<div class="select-content-item"> </el-option>
<div class="select-content-item-label">产品类别</div> </el-select>
<div> <el-checkbox style="margin-left: 10px;" v-model="select.is_merchant"></el-checkbox>
<el-cascader </div>
ref="cascader" </div>
:value="select.productTypeName" </el-col>
clearable
:show-all-levels="false" <el-col :span="12">
size="small" <div class="select-content-item">
:options="productTypes" <div class="select-content-item-label">产品类别</div>
:props="{checkStrictly:true,label:'name',value:'id'}" <div>
@change="productTypeChange"></el-cascader> <el-cascader ref="cascader" :value="select.productTypeName" clearable :show-all-levels="false"
</div> size="small" :options="productTypes" :props="{checkStrictly:true,label:'name',value:'id'}"
</div> @change="productTypeChange"></el-cascader>
</div>
<div class="select-content-item"> </div>
<div class="select-content-item-label">订单状态</div> </el-col>
<div> <el-col :span="12">
<template v-for="(value,key) of orderStates"> <div class="select-content-item">
<el-tag size="small" :effect="select.orderStates.key === key ? 'dark' : 'plain'" @click="select.orderStates = {key,value}" style="margin-right: 6px;">{{value}}</el-tag> <div class="select-content-item-label">订单状态</div>
</template> <div>
</div> <template v-for="(value,key) of orderStates">
</div> <el-tag size="small" :effect="select.orderStates.key === key ? 'dark' : 'plain'"
</template> @click="select.orderStates = {key,value}" style="margin-right: 6px;">{{value}}</el-tag>
<template v-slot:selected> </template>
<div style="display: flex;padding: 0 0 10px 20px;"> </div>
<span style="padding-right: 6px">当前搜索条件</span> </div>
<div v-if="select.keyword"> </el-col>
<el-tag effect="light" size="small" closable @close="select.keyword = ''"> <el-col :span="12">
{{select.keyword}} <div class="select-content-item">
</el-tag>, <div class="select-content-item-label">下单日期</div>
</div> <div>
<div v-if="select.productType"> <el-date-picker @change="changeCreatedDate" v-model="select.createdDate" type="daterange"
<el-tag effect="light" size="small" closable @close="select.productType = ''"> :picker-options="pickerOptions" value-format="yyyy-MM-dd" range-separator="至"
{{select.productTypeName}} start-placeholder="开始日期" end-placeholder="结束日期" align="right">
</el-tag>, </el-date-picker>
</div> </div>
<div v-if="select.merchant"> </div>
<el-tag effect="light" size="small" closable @close="select.merchant = ''"> </el-col>
{{select.merchant.name}} <el-col :span="12"></el-col>
</el-tag>, <el-col :span="12">
</div> <div class="select-content-item">
<div v-if="select.orderStates"> <div class="select-content-item-label">支付日期</div>
<el-tag effect="light" size="small" closable @close="select.orderStates = ''"> <div>
{{select.orderStates.value}} <el-date-picker @change="changePayDate" v-model="select.payDate" type="daterange"
</el-tag> :picker-options="pickerOptions" value-format="yyyy-MM-dd" range-separator="至"
</div> start-placeholder="开始日期" end-placeholder="结束日期" align="right">
</div> </el-date-picker>
</template> </div>
</xy-selectors> </div>
<Button class="select" type="primary" style="margin-right: 10px;" @click="downloadExel"></Button> </el-col>
</div> </el-row>
</slot>
</lx-header>
</div> </template>
<template v-slot:selected>
<xy-table :list="list" :table-item="table" :total="total" @pageSizeChange="e => select.pageSize = e" @pageIndexChange="pageChange"> <div style="display: flex;padding: 0 0 10px 20px;">
<template v-slot:btns> <span style="padding-right: 6px">当前搜索条件</span>
<el-table-column fixed="right" label="操作" width="400" header-align="center"> <div v-if="select.keyword">
<template slot-scope="scope"> <el-tag effect="light" size="small" closable @close="select.keyword = ''">
<actions :row="scope.row" @log="showLog(scope.row)" @refresh="getOrders"></actions> {{select.keyword}}
<!-- <Button icon="ios-chatbubbles-outline" type="primary" style="margin-left: 10px;margin-bottom: 6px;" size="small" ghost>跟进</Button>--> </el-tag>,
<!-- <Button v-show="scope.row.state_name == ''" icon="ios-paper-plane-outline" type="primary" style="margin-left: 10px;margin-bottom: 6px;" size="small" ghost>分发</Button>--> </div>
<!-- <Button v-show="scope.row.state_name == ''" icon="ios-close" type="primary" style="margin-left: 10px;margin-bottom: 6px;" size="small" ghost>取消</Button>--> <div v-if="select.productType">
<!-- <Button v-show="scope.row.state_name == ''" icon="ios-redo" type="primary" style="margin-left: 10px;margin-bottom: 6px;" size="small" ghost>收回</Button>--> <el-tag effect="light" size="small" closable @close="select.productType = ''">
<!-- <Button icon="ios-clipboard-outline" type="primary" style="margin-left: 10px;margin-bottom: 6px;" size="small" ghost @click="selectId = scope.row.id,isShowLog = true">日志</Button>--> {{select.productTypeName}}
</template> </el-tag>,
</el-table-column> </div>
</template> <div v-if="select.merchant">
</xy-table> <el-tag effect="light" size="small" closable @close="select.merchant = ''">
{{select.merchant.name}}
<orderLog :id="selectId" :is-show.sync="isShowLog" @refresh="getOrders"></orderLog> </el-tag>,
</div> </div>
</template> <div v-if="select.orderStates">
<el-tag effect="light" size="small" closable @close="select.orderStates = ''">
<script> {{select.orderStates.value}}
import {getList,index as getTypes} from "@/api/order" </el-tag>
import {parseTime} from "@/utils" </div>
import {download} from '@/utils/downloadRequest' </div>
</template>
import orderLog from '@/views/order/component/orderLog' </xy-selectors>
import actions from '@/views/order/component/actions' <Button class="select" type="primary" style="margin-right: 10px;" @click="downloadExel"></Button>
export default { </div>
components:{ </slot>
orderLog, </lx-header>
actions </div>
},
data() { <xy-table :list="list" :table-item="table" :total="total" @pageSizeChange="e => select.pageSize = e"
return { @pageIndexChange="pageChange">
selectId:null, <template v-slot:btns>
isShowLog:false, <el-table-column fixed="right" label="操作" width="400" header-align="center">
<template slot-scope="scope">
merchants:[], <actions :row="scope.row" @log="showLog(scope.row)" @refresh="getOrders"></actions>
orderItemStates:[], <!-- <Button icon="ios-chatbubbles-outline" type="primary" style="margin-left: 10px;margin-bottom: 6px;" size="small" ghost>跟进</Button>-->
orderStates:[], <!-- <Button v-show="scope.row.state_name == ''" icon="ios-paper-plane-outline" type="primary" style="margin-left: 10px;margin-bottom: 6px;" size="small" ghost>分发</Button>-->
productTypes:[], <!-- <Button v-show="scope.row.state_name == ''" icon="ios-close" type="primary" style="margin-left: 10px;margin-bottom: 6px;" size="small" ghost>取消</Button>-->
select:{ <!-- <Button v-show="scope.row.state_name == ''" icon="ios-redo" type="primary" style="margin-left: 10px;margin-bottom: 6px;" size="small" ghost>收回</Button>-->
page:1, <!-- <Button icon="ios-clipboard-outline" type="primary" style="margin-left: 10px;margin-bottom: 6px;" size="small" ghost @click="selectId = scope.row.id,isShowLog = true">日志</Button>-->
pageSize:10, </template>
merchant:'', </el-table-column>
keyword:'', </template>
productType:'', </xy-table>
orderStates:'',
productTypeName:"" <orderLog :id="selectId" :is-show.sync="isShowLog" @refresh="getOrders"></orderLog>
}, </div>
</template>
total:0,
list:[], <script>
table:[ import {
{ getList,
prop: "order.serial", index as getTypes
label:"订单编号", } from "@/api/order"
width:150, import {
align:'center', parseTime
fixed:'left' } from "@/utils"
}, import {
{ download
prop: "order_name", } from '@/utils/downloadRequest'
label:"订单名称",
width:340, import orderLog from '@/views/order/component/orderLog'
align:'left' import actions from '@/views/order/component/actions'
}, export default {
{ components: {
prop:'bookable_name', orderLog,
label:"订购类型", actions
width:110 },
}, data() {
{ return {
prop:"order_total", selectId: null,
label:"金额", isShowLog: false,
width: 140,
align:'right' merchants: [],
}, orderItemStates: [],
{ orderStates: [],
prop:"created_at", productTypes: [],
label:"下单时间", select: {
width: 200, page: 1,
formatter:(cell,data,value,index)=>{ pageSize: 10,
return parseTime(new Date(value)) merchant: '',
} keyword: '',
}, productType: '',
{ orderStates: '',
prop:"paid_at", productTypeName: "",
label:"支付时间", is_merchant: false,
width: 200, createdDate: [],
formatter:(cell,data,value,index)=>{ paidDate: [],
if(value) start_created: "",
return parseTime(new Date(value)) end_created: "",
} start_paid: "",
}, end_paid: "",
{ },
prop:"updated_at", pickerOptions: {
label:"更新时间", shortcuts: [{
width: 200, text: '最近一周',
formatter:(cell,data,value,index)=>{ onClick(picker) {
return parseTime(new Date(value),"{y}-{m}-{d}") const end = new Date();
} const start = new Date();
}, start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
{ picker.$emit('pick', [start, end]);
prop:"memberPromotion.name", }
label:"推广渠道", }, {
width: 110 text: '最近一个月',
}, onClick(picker) {
{ const end = new Date();
label:"用户信息", const start = new Date();
Fprop:'member', start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
multiHd:[ picker.$emit('pick', [start, end]);
{ }
prop:"name", }, {
label:"姓名", text: '最近三个月',
width:110 onClick(picker) {
}, const end = new Date();
{ const start = new Date();
label:"头像", start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
width:80, picker.$emit('pick', [start, end]);
customFn:(row)=>{ }
return (<div style={{display:'flex',alignItems:'center',justifyContent:'center'}}><el-avatar src={row.member?.avatar}></el-avatar></div>) }]
} },
total: 0,
list: [],
table: [{
prop: "order.serial",
label: "订单编号",
width: 150,
align: 'center',
fixed: 'left'
},
{
prop: "order_name",
label: "订单名称",
width: 220,
align: 'left'
},
{
prop: 'bookable_name',
label: "订购类型",
width: 80
},
{
prop: "order_total",
label: "金额",
width: 80,
align: 'right'
},
{
prop: "created_at",
label: "下单时间",
width: 180,
formatter: (cell, data, value, index) => {
return parseTime(new Date(value))
}
},
{
prop: "paid_at",
label: "支付时间",
width: 180,
formatter: (cell, data, value, index) => {
if (value)
return parseTime(new Date(value))
}
},
{
prop: "updated_at",
label: "更新时间",
width: 180,
formatter: (cell, data, value, index) => {
return parseTime(new Date(value))
}
},
{
prop: "memberPromotion.name",
label: "推广渠道",
width: 110
},
{
label: "客户服务地址",
width: 220,
align:"left",
customFn: (row) => {
return ( <div style = {
{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
cursor:'pointer',
color:"blue"
}
} > {row.order.member_address?row.order.member_address:"修改服务地址"}</div > )
}
},
{
label: "用户信息",
Fprop: 'member',
multiHd: [{
prop: "name",
label: "姓名",
width: 110
},
{
prop: "wechat_nickname",
label: "微信昵称",
width: 110
},
{
label: "头像",
width: 80,
customFn: (row) => {
return ( < div style = {
{
display: 'flex',
alignItems: 'center',
justifyContent: 'center'
}
} > <el-avatar src = {
row.member?.avatar
} > </el-avatar></div > )
}
},
{
prop: "phone",
label: "联系电话",
width: 120
},
{
prop: "area",
label: "区域",
width: 110
},
{
prop: "due_date",
label: "预产期",
width: 120
}
],
},
{
label: '订单明细',
multiHd: [{
prop: "product_type.name",
label: "产品类型",
width: 100
},
{
prop: "merchant.name",
label: "服务商家",
align: "left",
width: 220
},
{
label: "历史商家",
width: 220,
align: "left",
customFn: (row) => {
return row.assign_merchant.map(item => {
return ( < div > {
item.name
} < /div>)
})
}
},
{
prop: "state_name",
label: "状态",
width: 80
}
]
}, },
{ {
prop:"phone", prop: "order.remark",
label:"联系电话", label: "备注"
width: 190 }
},
{
prop:"area",
label:"区域",
width: 110
},
{
prop:"due_date",
label:"预产期",
width: 145
}
], ],
}, }
{ },
label:'订单明细', methods: {
multiHd: [ changePayDate(e) {
{ this.select.start_paid = e[0];
prop:"product_type.name", this.select.end_paid = e[1];
label:"产品类型", },
width: 200 changeCreatedDate(e) {
}, this.select.start_created = e[0];
{ this.select.end_created = e[1];
prop:"merchant.name", },
label:"服务商家", productTypeChange(e) {
width: 220 this.select.productType = this.$refs['cascader'].getCheckedNodes()[0].data.id;
}, this.select.productTypeName = this.$refs['cascader'].getCheckedNodes()[0].data.name;
{ },
prop:"state_name", searchOrder(){
label:"状态",
width: 140 this.select.page = 1
} this.getOrders()
] },
} pageChange(e) {
], this.select.page = e
} this.getOrders()
}, },
methods: {
productTypeChange(e){ async getTypes() {
this.select.productType = this.$refs['cascader'].getCheckedNodes()[0].data.id; const res = await getTypes()
this.select.productTypeName = this.$refs['cascader'].getCheckedNodes()[0].data.name; this.merchants = res.merchants
}, this.orderItemStates = res.order_item_states
this.orderStates = res.order_states
pageChange(e){ this.productTypes = res.product_types
this.select.page = e },
this.getOrders()
}, async getOrders() {
let is_merchant = this.select.is_merchant
async getTypes(){
const res = await getTypes()
this.merchants = res.merchants
this.orderItemStates = res.order_item_states
this.orderStates = res.order_states
this.productTypes = res.product_types
},
async getOrders(){
const res = await getList({
page:this.select.page,
page_size:this.select.pageSize,
keyword:this.select.keyword,
product_type_id:this.select.productType,
merchant_id:this.select.merchant.id,
order_state:this.select.orderStates.key
})
this.total = res.total
this.list = res.rows
},
showLog(row){
this.selectId = row.id
this.isShowLog = true
},
downloadExel(){
download(
'/api/admin/order/get-list',
'get',
{
order_state:this.select.orderStates.key,
keyword:this.select.keyword,
product_type_id:this.select.productType,
merchant_id:this.select.merchant.id,
is_export:1
},
'订单列表.xlsx')
}
},
mounted() {
this.getTypes()
this.getOrders()
}
}
</script>
<style scoped lang="scss">
.select-content-item{
display: flex;
align-items: center;
margin-bottom: 10px;
&-label{
padding: 0 20px;
}
}
$primaryColor: #bf617c;
::v-deep .ivu-alert-success{
color:#fff;
border-color: $primaryColor !important;
background: rgba(213, 120, 145, 0.8) !important;
margin: auto 0; this.select.is_merchant= is_merchant ? 1 : 0;
margin-right: 10px; const res = await getList({
} page_size: this.select.pageSize,
::v-deep .ivu-icon-ios-close:before{ product_type_id: this.select.productType,
//color: #fff; merchant_id: this.select.merchant.id,
} order_state: this.select.orderStates.key,
...this.select
})
this.select.is_merchant=is_merchant;
this.total = res.total
this.list = res.rows
},
showLog(row) {
this.selectId = row.id
this.isShowLog = true
},
downloadExel() {
download(
'/api/admin/order/get-list',
'get', {
order_state: this.select.orderStates.key,
keyword: this.select.keyword,
product_type_id: this.select.productType,
merchant_id: this.select.merchant.id,
is_export: 1
},
'订单列表.xlsx')
}
},
mounted() {
this.getTypes()
this.getOrders()
}
}
</script>
<style scoped lang="scss">
.select-content-item {
display: flex;
align-items: center;
margin-bottom: 10px;
&-label {
padding: 0 20px;
}
}
$primaryColor: #bf617c;
::v-deep .ivu-alert-success {
color: #fff;
border-color: $primaryColor !important;
background: rgba(213, 120, 145, 0.8) !important;
margin: auto 0;
margin-right: 10px;
}
::v-deep .ivu-icon-ios-close:before {
//color: #fff;
}
</style> </style>

Loading…
Cancel
Save