<template> <div class="order"> <el-form ref="searchFrom" :model="searchFrom" label-width="100px" inline size="small"> <el-form-item label="用户ID"> <el-input v-model="searchFrom.user_id" style="width: 80px"></el-input> </el-form-item> <el-form-item label="用户昵称"> <el-input v-model="searchFrom.nickname" style="width: 110px"></el-input> </el-form-item> <el-form-item label="收件人手机号"> <el-input v-model="searchFrom.receive_mobile" style="width: 120px"></el-input> </el-form-item> <el-form-item label="商品名称"> <el-select v-model="searchFrom.goods_id" filterable placeholder="请选择" style="width: 150px" @change="getOrderList" clearable> <el-option v-for="(data,index) in goodList" :key="index" :label="data | filterGoods" :value="data.id"> </el-option> </el-select> </el-form-item> <el-form-item label="来源" class="test"> <el-input v-model="searchFrom.invite_type " :placeholder="inviteSearchPlaceholder" style="width: 150px"> <template slot="prepend">CC -</template> </el-input> </el-form-item> <el-form-item label="推广人ID"> <el-input v-model="searchFrom.invite_id" :placeholder="inviteSearchPlaceholder" style="width: 80px"></el-input> </el-form-item> <!-- <el-form-item label="团ID"> <el-input v-model="searchFrom.order_group_id" ></el-input> </el-form-item> --> <el-form-item label="购买方式"> <el-select v-model="searchFrom.buy_type" placeholder="请选择" @change="getOrderList" clearable style="width: 100px"> <el-option v-for="item in buyTypeOption" :key="item.id" :label="item.value" :value="item.id"> </el-option> </el-select> </el-form-item> <el-form-item label="支付类型"> <el-select v-model="searchFrom.order_type" placeholder="请选择" @change="getOrderList" clearable style="width: 120px"> <el-option v-for="item in buyWay" :key="item.id" :label="item.value" :value="item.id"> </el-option> </el-select> </el-form-item> <el-form-item label="订单状态"> <el-select multiple v-model="searchFrom.status" placeholder="请选择" @change="getOrderList" clearable> <el-option v-for="item in orderStatusOption" :key="item.id" :label="item.value" :value="item.id"> </el-option> </el-select> </el-form-item> <el-form-item label="是否入课"> <el-select v-model="searchFrom.wait_into_course" placeholder="请选择" @change="getOrderList" clearable style="width: 120px"> <el-option label="已入课" value="0"> </el-option> <el-option label="未入课" value="1"> </el-option> </el-select> </el-form-item> <el-form-item label="交易订单号"> <el-input v-model="searchFrom.out_trade_no"></el-input> </el-form-item> <el-form-item label="购买时间"> <el-date-picker v-model="searchFrom.payTime" type="datetimerange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" value-format="yyyy-MM-dd HH:mm:ss" :picker-options="{shortcuts:[today,yesterday,last7Day,last30Day]}" :default-time="['00:00:00','23:59:59']" @change="getOrderList"> </el-date-picker> </el-form-item> <el-form-item > <el-button type="primary" plain @click="getOrderList">搜索</el-button> <el-button type="primary" plain @click="exportTable" v-if="$store.state.export">导出</el-button> </el-form-item> <el-form-item style="float:right"> <el-button type="success" plain @click="add" v-if="!$store.state.readonly">新增订单</el-button> </el-form-item> </el-form> <el-table size="small" :data="tableData" @expand-change="changeRow" style="width: 100%" fixed > <el-table-column prop="out_trade_no" label="订单号" > </el-table-column> <el-table-column label="购买人" className="f-c" width="150"> <template slot-scope="scope"> <img class="avatar" :src="scope.row.user_avatar"/> {{scope.row.user_nickname}}<br>(ID:{{scope.row.user_id}})<br>手机:{{scope.row.user_mobile}} </template> </el-table-column> <el-table-column prop="periods_title" label="期数标题"> </el-table-column> <el-table-column prop="goods_name" label="商品名称"> </el-table-column> <el-table-column width="250" prop="invite_id" className="f-c" label="推广人"> <template slot-scope="scope"> <div @click="showSource(scope.row)" v-if="scope.row.invite_earnings > 0 && scope.row.invite_id !== 0" style="width:100%;display: flex;color: #409eff;cursor: pointer"> <img :src="scope.row.invite_avatar" class="avatar"/> 类型:{{scope.row.invite_type}} ({{scope.row.invite_name}}) <br> 收益:{{scope.row.invite_earnings / 100}} <br> 用户ID:{{scope.row.invite_id}} <br> 昵称:{{scope.row.invite_nickname}} <br> 手机:{{scope.row.invite_mobile}} </div> <div v-if="scope.row.invite_earnings === 0 && scope.row.invite_id !== 0" style="display: flex;"> <img :src="scope.row.invite_avatar" class="avatar"/> 类型:{{scope.row.invite_type}} ({{scope.row.invite_name}}) <br> 收益:{{scope.row.invite_earnings / 100}} <br> 用户ID:{{scope.row.invite_id}} <br> 昵称:{{scope.row.invite_nickname}} <br> 手机:{{scope.row.invite_mobile}} </div> <div v-if="scope.row.invite_id === 0"> 无 </div> </template> </el-table-column> <el-table-column label="优惠活动"> <template slot-scope="scope"> <span v-if="scope.row.order_coupon_id === 0"> 无 </span> <el-button type="text" v-if="scope.row.order_coupon_id !== 0" @click="showCoupon(scope.row)"> 优惠券 </el-button> </template> </el-table-column> <el-table-column label="付款状态" width="80"> <template slot-scope="scope"> <el-button type="text" v-if="scope.row.status === 5 || scope.row.status === 3" @click="showRef(scope.row)">{{scope.row.status|status}}</el-button> <div v-if="scope.row.status !== 5 && scope.row.status !== 3">{{scope.row.status|status}}</div> </template> </el-table-column> <el-table-column label="实付金额" width="80"> <template slot-scope="scope"> {{scope.row.money|moneytFilter}} </template> </el-table-column> <el-table-column label="支付类型" width="80"> <template slot-scope="scope"> {{scope.row.order_type | buyTypeWay}} </template> </el-table-column> <el-table-column label="收货地址"> <template slot-scope="scope"> <div v-if="scope.row.user_address_id && scope.row.address_info"> {{scope.row.address_info.receive_name}}<br> {{scope.row.address_info.receive_mobile}}<br> {{scope.row.address_info.province_name}}{{scope.row.address_info.city}}{{scope.row.address_info.area}}{{scope.row.address_info.address}} </div> </template> </el-table-column> <el-table-column prop="pay_at" label="购买时间" sortable> </el-table-column> <el-table-column prop="created_at" label="下单时间" sortable> </el-table-column> <el-table-column prop="desc" label="备注"> </el-table-column> <el-table-column width="50" label="操作" v-if="!$store.state.readonly" fixed="right" > <template slot-scope="scope"> <el-popover placement="top" width="400"> <div style="text-align: center"> <!--v-if="(scope.row.status == 1 || scope.row.status == 4|| scope.row.status == 5) && $store.state.orderRefund"--> <el-button @click="onRefund(scope.row.id, scope.row.money)" type="warning" v-if="(scope.row.status == 1 || scope.row.status == 4 || scope.row.status == 5 ) && $store.state.orderRefund && scope.row.order_type != 3 " plain size="mini"> 退款 </el-button> <el-button @click="editComment(scope.row.id, scope.row.desc)" type="info" plain size="mini"> 编辑备注 </el-button> <el-button v-if="scope.row.user_address_id" @click="editAddress(scope.row)" plain type="info" size="mini"> 编辑收货地址 </el-button> <el-button @click="updateTeacher(scope.row)" type="warning" plain size="mini"> 编辑推广人 </el-button> </div> <el-button slot="reference" size="mini" type="text" >操作</el-button> </el-popover> </template> </el-table-column> </el-table> <address-dialog :dialogObj="dialogObj" @reflash="onUpdateAddress"></address-dialog> <order-dialog :newdialogObj="newdialogObj" @reflash="getOrderList"></order-dialog> <refund-dialog :dialogObj="refundDialogObj" @reflash="onAfterRefund" @changeShow="changeShow"></refund-dialog> <detail-dialog :dialogObj="dialogDetailObj" @changeShow="changeDetailShow"/> <source-dialog :dialogObj="sourceDialog"/> <refund-detail :dialogObj="refundDetail"/> <coupon-dialog :dialogObj="couponDetail"/> <el-dialog title="修改推广人" center append-to-body :visible.sync="promoterDialog.show" width="600"> <el-form ref="form" label-width="120px"> <el-form-item label="老师"> <el-select v-model="promoterDialog.teacher_id" filterable remote clearable placeholder="请输入名称" :remote-method="remoteMethod" :loading="loading"> <el-option v-for="item in teacherList" :key="item.id" :label="item.name" :value="item.user_id"> </el-option> </el-select> </el-form-item> </el-form> <span slot="footer" class="dialog-footer"> <el-button @click="promoterDialog.show = false">取 消</el-button> <el-button type="primary" @click="saveTeacher">确 定</el-button> </span> </el-dialog> <page :nowPage="nowPage" :total="total" :limit="limit" @pageChange="onPageChange" @sizeChange="onSizeChange"/> </div> </template> <script> import {getOrderListApi,editOrderDescApi,getGoodsListApi,getRefundListApi,exportExcelApi,getTeacherListApi,updateOrderTeacherApi,setOrderApi} from "../../service/api"; import page from '../framework/page' import addressDialog from './dialog' import orderDialog from './newDialog' import sourceDialog from './sourceDialog' import refundDialog from './refundDialog' import couponDialog from './couponDialog' import detailDialog from './detail' import refundDetail from './refundDetail' import AddressArray from '../framework/address-picker/addr' import {INVITETYPE,ORDERSTATUS,BUYTYPE,BUYTYPEOPTION,ORDERSTATUSOPTION,INVITETYPEOPTION,GOODSTYPE,BUYWay,BUYTYPEWAY} from "../../util/wordbook"; import CommonJs from '../../util/common'; export default { name: 'index', data(){ return { nowPage: 1, total: 0, sourceDialog:{ show:false, out_trade_no:'' }, today:{ text:'今天', onClick:()=>{ this.searchFrom.payTime = [this.formatTime(new Date())+' 00:00:00',this.formatTime(new Date())+' 23:59:59']; } }, yesterday:{ text:'昨天', onClick:()=>{ let preDate = this.formatTime(new Date(new Date().getTime() - 24*60*60*1000)); this.searchFrom.payTime = [preDate+' 00:00:00',preDate+' 23:59:59']; } }, last30Day:{ text:'过去30天', onClick:()=>{ let preDate = this.formatTime(new Date(new Date().getTime() - 30*24*60*60*1000)); this.searchFrom.payTime = [preDate+' 00:00:00',this.formatTime(new Date())+' 23:59:59']; } }, last7Day:{ text:'过去7天', onClick:()=>{ let preDate = this.formatTime(new Date(new Date().getTime() - 7*24*60*60*1000)); this.searchFrom.payTime = [preDate+' 00:00:00',this.formatTime(new Date())+' 23:59:59']; } }, couponDetail:{ show:false, order_coupon_id:'' }, refundDetail:{ show:false, out_trade_no:'' }, limit: 10, searchFrom: { nickname: '', wait_into_course:'', user_id: '', invite_type: '', invite_id: '', buy_type: '', order_type: '', status: [1,4,5], goods_id: '', out_trade_no: '', payTime: [], order_group_id:"", }, tableData: [], dialogObj: { show: false }, newdialogObj: { show: false }, refundDialogObj: { show: false, id: '', money: 0 }, dialogDetailObj: { show: false, detail: {} }, goodList: [], inviteTypeOption: INVITETYPEOPTION, orderStatusOption: ORDERSTATUSOPTION, buyTypeOption: BUYTYPEOPTION, buyWay:BUYWay, inviteSearchPlaceholder: '', rules:{ value:[ { required: true, message: '请输入备注', trigger: 'change' } ] }, promoterDialog: { show: false, nowPage: 1, total: 0, limit: 100, teacher_id: '' }, teacherList: [], loading: false } }, methods: { formatTime(date){ let year = date.getFullYear(); let Month = date.getMonth()+1; if(Month < 10){ Month = `0${Month}` } let Day = date.getDate(); if(Day<10)Day = `0${Day}`; return `${year}-${Month}-${Day}`; }, showRef(data){ this.refundDetail.show = true; this.refundDetail.out_trade_no = data.out_trade_no; }, showCoupon(data){ this.couponDetail.show = true; this.couponDetail.order_coupon_id = data.order_coupon_id; }, showSource(data){ this.sourceDialog.show = true; this.sourceDialog.out_trade_no = data.out_trade_no; }, changeRow(data,b){ if(b.indexOf(data)>-1){ getRefundListApi({out_trade_no:data.out_trade_no}).then(res=>{ data.refundList = res.list }) } }, exportTable(){ let json = {}; if (this.searchFrom.nickname) { json.nickname = this.searchFrom.nickname } if (this.searchFrom.user_id) { json.user_id = this.searchFrom.user_id } if (this.searchFrom.invite_type) { json.invite_type = this.searchFrom.invite_type } if (this.searchFrom.invite_id) { json.invite_id = this.searchFrom.invite_id } if (this.searchFrom.order_group_id) { json.order_group_id = this.searchFrom.order_group_id } if (this.searchFrom.buy_type) { json.buy_type = this.searchFrom.buy_type } if (this.searchFrom.order_type) { json.order_type = this.searchFrom.order_type } if (this.searchFrom.status) { json.status = this.searchFrom.status.toString() } if (this.searchFrom.goods_id) { json.goods_id = this.searchFrom.goods_id } if (this.searchFrom.out_trade_no) { json.out_trade_no = this.searchFrom.out_trade_no } if (this.searchFrom.receive_mobile) { json.receive_mobile = this.searchFrom.receive_mobile } if(this.searchFrom.payTime && this.searchFrom.payTime.length > 0){ json.pay_start_at = this.searchFrom.payTime[0] json.pay_end_at = this.searchFrom.payTime[1] } if (this.searchFrom.wait_into_course) { json.wait_into_course = this.searchFrom.wait_into_course } json.course_type=0 //月课 exportExcelApi('/api/admin/order/export',json) }, getGoodsOption(){ let json = { page: 1, limit: 100, course_type:0, }; getGoodsListApi(json).then(res=>{ this.goodList = res.list; }) }, onInviteTypeChange(val){ if (val === 0) { this.inviteSearchPlaceholder = '用户ID' } else if (val === 1) { this.inviteSearchPlaceholder = '老师ID' } else if (val === 2) { this.inviteSearchPlaceholder = '推广人ID' } this.getOrderList(); }, detail(row){ let _detail = row; this.dialogDetailObj = { show: true, detail: _detail } }, editComment(id, desc) { this.$prompt('', '编辑备注', { confirmButtonText: '确定', cancelButtonText: '取消', inputType:'textarea', inputValue: desc || '' }).then(({ value }) => { this.$confirm('确定保存?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(()=>{ editOrderDescApi(id,'order',{desc: value}).then(res=>{ this.$message({ type: 'success', message: '编辑备注成功' }); this.getOrderList(); }); }); }) }, onPageChange(val){ this.nowPage = val this.getOrderList() }, onSizeChange(val){ this.limit = val; this.nowPage = 1; this.getOrderList() }, getOrderList(){ let json = { limit: this.limit, page: this.nowPage }; if (this.searchFrom.nickname) { json.nickname = this.searchFrom.nickname } if (this.searchFrom.user_id) { json.user_id = this.searchFrom.user_id } if (this.searchFrom.invite_type) { json.invite_type = this.searchFrom.invite_type } if (this.searchFrom.invite_id) { json.invite_id = this.searchFrom.invite_id } if (this.searchFrom.order_group_id) { json.order_group_id = this.searchFrom.order_group_id } if (this.searchFrom.buy_type) { json.buy_type = this.searchFrom.buy_type } if (this.searchFrom.order_type) { json.order_type = this.searchFrom.order_type } if (this.searchFrom.status) { json.status = this.searchFrom.status.toString() } if (this.searchFrom.goods_id) { json.goods_id = this.searchFrom.goods_id } if (this.searchFrom.out_trade_no) { json.out_trade_no = this.searchFrom.out_trade_no } if (this.searchFrom.receive_mobile) { json.receive_mobile = this.searchFrom.receive_mobile } if(this.searchFrom.payTime && this.searchFrom.payTime.length > 0){ json.pay_start_at = this.searchFrom.payTime[0] json.pay_end_at = this.searchFrom.payTime[1] } if (this.searchFrom.wait_into_course) { json.wait_into_course = this.searchFrom.wait_into_course } json.course_type=0 //月课 getOrderListApi(json).then((res)=>{ res.list.forEach(i=>{ i.refundList=[] }); this.tableData = res.list; this.total = res.total }) }, changeDetailShow(data){ this.dialogDetailObj.show=data }, changeShow(data){ this.refundDialogObj.show=data }, onRefund(id, money){ this.refundDialogObj.id= id; this.refundDialogObj.money= money; this.refundDialogObj.show = true; }, onAfterRefund(){ this.refundDialogObj.show = false; this.getOrderList() }, onUpdateAddress(){ this.dialogObj.show = false; this.getOrderList(); }, editAddress(row){ if( !row.address_info || !row.address_info.province_name ){ this.dialogObj.province = '' this.dialogObj.city = '' this.dialogObj.district = '' } else { let provinceObj = AddressArray.filter((item) => { return item.label === row.address_info.province_name }) if(provinceObj && provinceObj.length > 0){ this.dialogObj.province = row.address_info.province_id ? row.address_info.province_id : provinceObj[0].value if(!row.address_info.city){ this.dialogObj.city = '' } else { let cityObj = provinceObj[0].children.filter((city) => { return city.label === row.address_info.city }) this.dialogObj.city = row.address_info.city_id ? row.address_info.city_id : cityObj[0].value if(!row.address_info.area){ this.dialogObj.district = '' }else { let districtObj = cityObj[0].children.filter((district) => { return district.label === row.address_info.area }); this.dialogObj.district = row.address_info.area_id ? row.address_info.area_id : districtObj[0].value } } } else { this.dialogObj.province = ''; this.dialogObj.district = ''; this.dialogObj.city = '' } } this.dialogObj.detail = row.address_info ? row.address_info.address : ''; this.dialogObj.receive_mobile = row.address_info ? row.address_info.receive_mobile : ''; this.dialogObj.receive_name = row.address_info ? row.address_info.receive_name : ''; this.dialogObj.province_name = row.address_info ? row.address_info.province_name : ''; this.dialogObj.city_name = row.address_info ? row.address_info.city : ''; this.dialogObj.district_name = row.address_info ? row.address_info.area : ''; this.dialogObj.id = row.id; this.dialogObj.show=true; }, getTeacherList(name){ this.loading = true let json = { limit: this.promoterDialog.limit, page: this.promoterDialog.nowPage }; if(name) { json.name = name } getTeacherListApi(json).then(res=>{ this.teacherList = res.list this.loading = false }); }, handleCurrentTeacherChange(val){ console.log('handleCurrentTeacherChange', val) }, updateTeacher(val){ this.promoterDialog.show = true; this.promoterDialog.id = val.id; this.promoterDialog.teacher_id = val.invite_id; this.getTeacherList() }, remoteMethod(query) { if (query !== '') { this.getTeacherList(query); } else { this.getTeacherList(); } }, saveTeacher(){ this.$confirm('此操作将修改推广人?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => { console.log('this.promoterDialog.teacher_id', this.promoterDialog) updateOrderTeacherApi(this.promoterDialog.id,this.promoterDialog.teacher_id).then(res=>{ this.promoterDialog.id=''; this.promoterDialog.teacher_id = ''; this.promoterDialog.show = false; this.$message({ type: 'success', message: '修改成功!' }); this.getOrderList(); }); }); }, add(){ this.newdialogObj.show=true; }, }, components: { addressDialog, orderDialog, refundDialog, detailDialog, refundDetail, sourceDialog, couponDialog, page }, mounted(){ if (this.$route.query.code) { this.searchFrom.invite_type = this.$route.query.code } this.getOrderList(); this.getGoodsOption(); }, watch:{ "newdialogObj.show":function(val){ if(!val){ this.getOrderList(); } } }, filters:{ payMentFilter(val){ return val=='1'?'已付款':'未付款' }, courseTypeFilter(val){ return val.type=='1'?`正式课(${val.duration}个月)`:`试听课(${val.duration}天)` }, inviteType(value){ return INVITETYPE[value] }, status(value){ return ORDERSTATUS[value] }, buyType(value){ return BUYTYPE[value] }, moneytFilter(val){ return val = val / 100 + '元' }, filterGoods(val){ return '[' +val.id + ']' + '[' + GOODSTYPE[val.goods_type] + ']' + '[' +val.current_price / 100 + '元]' + val.name }, buyTypeWay(value){ return BUYTYPEWAY[value] }, } } </script> <style scoped> .avatar{ width: 50px; min-width: 50px; height: 50px; margin-right: 5px; border-radius: 50%; } .order { padding: 20px 0; } </style> <style> .f-c > .cell { display: flex !important; flex-flow: row; justify-content: flex-start; align-items: center; } </style>