This commit is contained in:
parent
38a6f53380
commit
bc0e6ba142
|
@ -161,7 +161,16 @@ export const asyncRoutes = [
|
|||
title: '流转订单',
|
||||
roles: ['order_back', 'editor']
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'product',
|
||||
component: () => import('@/views/order/product'),
|
||||
name: 'productNameList',
|
||||
meta: {
|
||||
title: '产品统计列表',
|
||||
roles: ['order_pub', 'editor']
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
|
@ -52,6 +52,58 @@
|
|||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
|
||||
<div class="card-panel">
|
||||
<div class="card-panel-icon-wrapper icon-shopping">
|
||||
<svg-icon icon-class="shopping" class-name="card-panel-icon" />
|
||||
</div>
|
||||
<div class="card-panel-description">
|
||||
<div class="card-panel-text">
|
||||
核销订单数
|
||||
</div>
|
||||
<count-to :start-val="0" :end-val="asset" :duration="1" class="card-panel-num" />
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
|
||||
<div class="card-panel">
|
||||
<div class="card-panel-icon-wrapper icon-shopping">
|
||||
<svg-icon icon-class="shopping" class-name="card-panel-icon" />
|
||||
</div>
|
||||
<div class="card-panel-description">
|
||||
<div class="card-panel-text">
|
||||
核销订单金额
|
||||
</div>
|
||||
<count-to :start-val="0" :end-val="asset_price" :duration="10" class="card-panel-num" />
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
|
||||
<div class="card-panel">
|
||||
<div class="card-panel-icon-wrapper icon-shopping">
|
||||
<svg-icon icon-class="shopping" class-name="card-panel-icon" />
|
||||
</div>
|
||||
<div class="card-panel-description">
|
||||
<div class="card-panel-text">
|
||||
退款订单数
|
||||
</div>
|
||||
<count-to :start-val="0" :end-val="refund" :duration="10" class="card-panel-num" />
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
|
||||
<div class="card-panel">
|
||||
<div class="card-panel-icon-wrapper icon-shopping">
|
||||
<svg-icon icon-class="shopping" class-name="card-panel-icon" />
|
||||
</div>
|
||||
<div class="card-panel-description">
|
||||
<div class="card-panel-text">
|
||||
退款订单金额
|
||||
</div>
|
||||
<count-to :start-val="0" :end-val="refund_price" :duration="10" class="card-panel-num" />
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
|
@ -67,7 +119,11 @@ export default {
|
|||
wait:0,
|
||||
doing:0,
|
||||
all:0,
|
||||
total:0
|
||||
total:0,
|
||||
asset:0,
|
||||
asset_price:0,
|
||||
refund:0,
|
||||
refund_price:0
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
@ -77,8 +133,12 @@ export default {
|
|||
this.doing = parseFloat(res.data.doing)
|
||||
this.all = parseFloat(res.data.all)
|
||||
this.total = parseFloat(res.data.total)/100
|
||||
this.asset = parseFloat(res.data.asset)
|
||||
this.asset_price = parseFloat(res.data.asset_price)/100
|
||||
this.refund = parseFloat(res.data.refund)
|
||||
this.refund_price = parseFloat(res.data.refund_price)/100
|
||||
}).catch(err=>{
|
||||
console.log(err)
|
||||
console.log(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
|
|
@ -0,0 +1,125 @@
|
|||
<template>
|
||||
|
||||
<div class="app-container">
|
||||
<div class="filter-container">
|
||||
<el-input v-model="listQuery.product_name" placeholder="产品名称" style="width: 200px;" class="filter-item" />
|
||||
|
||||
<el-cascader
|
||||
v-model="listQuery.os_status"
|
||||
placeholder="平台状态"
|
||||
:options="os_arr"
|
||||
class="filter-item"
|
||||
@change="handleChange"
|
||||
/>
|
||||
|
||||
<el-button class="filter-item" type="primary" icon="el-icon-search" @click="getList">
|
||||
搜索
|
||||
</el-button>
|
||||
|
||||
</div>
|
||||
|
||||
<el-table v-loading="listLoading" :data="list" border fit highlight-current-row style="width: 100%">
|
||||
|
||||
<el-table-column align="center" fixed label="产品名称" width="220" prop="product_name" />
|
||||
|
||||
<el-table-column align="center" fixed label="平台" width="80" prop="os" />
|
||||
|
||||
<el-table-column align="center" fixed label="订单数" width="80" prop="all" />
|
||||
|
||||
<el-table-column align="center" label="订单金额" width="180" prop="total" />
|
||||
|
||||
<el-table-column align="center" width="500px" label="待跟进" prop="wait" />
|
||||
|
||||
<el-table-column width="138px" align="center" label="跟进中" prop="doing" />
|
||||
|
||||
<el-table-column align="center" width="500px" label="核销数" prop="asset" />
|
||||
|
||||
<el-table-column width="138px" align="center" label="核销金额" prop="asset_price" />
|
||||
|
||||
<el-table-column align="center" width="500px" label="退款数" prop="asset" />
|
||||
|
||||
<el-table-column width="138px" align="center" label="退款金额" prop="asset_price" />
|
||||
|
||||
</el-table>
|
||||
|
||||
<pagination
|
||||
v-show="total>0"
|
||||
:total="total"
|
||||
:page.sync="listQuery.page"
|
||||
:limit.sync="listQuery.limit"
|
||||
@pagination="getList"
|
||||
/>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// import Pagination from '@/components/Pagination'
|
||||
import Pagination from '@/components/PaginationFixed'
|
||||
|
||||
export default {
|
||||
name: 'productNameList',
|
||||
components: { Pagination },
|
||||
data() {
|
||||
return {
|
||||
active: 'follow',
|
||||
types: { 0: '', 1: '', 2: '', 3: 'primary', 4: 'success', 5: 'warning' },
|
||||
types2: { 1: 'primary', 2: 'success', 3: 'warning' },
|
||||
status_arr: ['待跟进', '跟进中', '已核销', '核销失败', '放弃跟单'],
|
||||
type_arr: ['-', '收益', '支出'],
|
||||
timetype_arr: {},
|
||||
order_status: ['#9e9f9c', '#04bcd9', '#fc9904', '#1193f4', '#48b14b', '#eb1662', '#9d1cb5'],
|
||||
follow_status: ['#9e9f9c', '#04bcd9', '#fc9904', '#1193f4', '#48b14b', '#eb1662'],
|
||||
options: [],
|
||||
list: [],
|
||||
total: 0,
|
||||
listLoading: true,
|
||||
listQuery: {
|
||||
page: 1,
|
||||
limit: 10,
|
||||
product_name: ''
|
||||
},
|
||||
os_arr: { 1: '美团', 2: '快手', 3: '抖音' },
|
||||
form: {},
|
||||
rules:{
|
||||
flowObj: [
|
||||
{ required: true, message: '请选择活动区域', trigger: 'change' }
|
||||
],
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.listQuery.status = this.$route.query.status || null
|
||||
this.listQuery.zhubo = this.$route.query.zhubo || null
|
||||
if (this.$route.query.start && this.$route.query.end) {
|
||||
this.listQuery.times = [this.$route.query.start, this.$route.query.end]
|
||||
}
|
||||
|
||||
this.getList()
|
||||
},
|
||||
methods: {
|
||||
getList() {
|
||||
this.$axios.get('/admin/index/productNameList', { params: this.listQuery }).then(response => {
|
||||
this.list = response.data.data
|
||||
this.total = response.data.total
|
||||
this.timetype_arr = response.ext.timetype
|
||||
this.oss = response.ext.oss
|
||||
this.listLoading = false
|
||||
}).catch(() => {
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.app-container {
|
||||
position: relative;
|
||||
padding-bottom: 60px; /* 分页条的高度 */
|
||||
}
|
||||
|
||||
.filter-container,
|
||||
.el-table {
|
||||
padding-bottom: 52px; /* 分页条的高度,以避免内容重叠 */
|
||||
}
|
||||
</style>
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
use app\model\Admins;
|
||||
|
@ -7,22 +8,24 @@ use app\model\Finances;
|
|||
use app\model\Onlines;
|
||||
use app\model\Orders;
|
||||
use Qiniu\Auth;
|
||||
use support\Log;
|
||||
use support\Redis;
|
||||
use support\Request;
|
||||
|
||||
class IndexController extends base
|
||||
{
|
||||
|
||||
public function isWork(Request $request) {
|
||||
public function isWork(Request $request)
|
||||
{
|
||||
|
||||
$lastTime = Redis::get('CRM:USER:ONLINE:'.$request->admin->id);
|
||||
$lastTime = Redis::get('CRM:USER:ONLINE:' . $request->admin->id);
|
||||
$end = Redis::hGet('CRM:USER:ONLINE:END', $request->admin->id);
|
||||
if(!empty($lastTime) && time() - $lastTime <= 5 * 60) {
|
||||
} elseif(empty($lastTime) && $end) {
|
||||
$has = Onlines::where("admin_id", $request->admin->id)->order('id desc')->find();
|
||||
if($has && empty($has->end)) {
|
||||
Onlines::where("id", $has->id)->update(['end' => $end]);
|
||||
}else{
|
||||
if (!empty($lastTime) && time() - $lastTime <= 5 * 60) {
|
||||
} elseif (empty($lastTime) && $end) {
|
||||
$has = Onlines::where("admin_id", $request->admin->id)->order('id desc')->find();
|
||||
if ($has && empty($has->end)) {
|
||||
Onlines::where("id", $has->id)->update(['end' => $end]);
|
||||
} else {
|
||||
$start = Redis::hGet('CRM:USER:ONLINE', $request->admin->id);
|
||||
//创建一个新的
|
||||
Onlines::create([
|
||||
|
@ -31,77 +34,105 @@ class IndexController extends base
|
|||
'end' => $end
|
||||
]);
|
||||
}
|
||||
//创建一个新的
|
||||
Onlines::create([
|
||||
'admin_id' => $request->admin->id,
|
||||
'start' => time(),
|
||||
'end' => 0
|
||||
]);
|
||||
} else {
|
||||
//第一次,给建个新的
|
||||
Onlines::create([
|
||||
'admin_id' => $request->admin->id,
|
||||
'start' => time(),
|
||||
'end' => 0
|
||||
]);
|
||||
}
|
||||
//创建一个新的
|
||||
Onlines::create([
|
||||
'admin_id' => $request->admin->id,
|
||||
'start' => time(),
|
||||
'end' => 0
|
||||
]);
|
||||
} else {
|
||||
//第一次,给建个新的
|
||||
Onlines::create([
|
||||
'admin_id' => $request->admin->id,
|
||||
'start' => time(),
|
||||
'end' => 0
|
||||
]);
|
||||
}
|
||||
|
||||
Redis::Set('CRM:USER:ONLINE:'.$request->admin->id, time(), 'ex', 10 *60);
|
||||
Redis::Set('CRM:USER:ONLINE:' . $request->admin->id, time(), 'ex', 10 * 60);
|
||||
Redis::hSet('CRM:USER:ONLINE:END', $request->admin->id, time() + 60);
|
||||
|
||||
|
||||
|
||||
$new = Redis::get('CRM:USER:ONLINE:NEW:'.$request->admin->id);
|
||||
Redis::del('CRM:USER:ONLINE:NEW:'.$request->admin->id);
|
||||
$back = Redis::set('CRM:USER:ONLINE:FOLLOW:LOCK:'. $request->admin->id, time(), 'EX', 60, 'nx');
|
||||
$new = Redis::get('CRM:USER:ONLINE:NEW:' . $request->admin->id);
|
||||
Redis::del('CRM:USER:ONLINE:NEW:' . $request->admin->id);
|
||||
$back = Redis::set('CRM:USER:ONLINE:FOLLOW:LOCK:' . $request->admin->id, time(), 'EX', 60, 'nx');
|
||||
$follow = $backs = 0;
|
||||
if($back) {
|
||||
$follow = Orders::where('admin_id', $request->admin->id)->whereBetween('next_follow',[1,(time()-60)*1000])->count();
|
||||
if ($back) {
|
||||
$follow = Orders::where('admin_id', $request->admin->id)->whereBetween('next_follow', [1, (time() - 60) * 1000])->count();
|
||||
$backs = Backs::where('admin', $request->admin->id)->where('status', 0)->count();
|
||||
}
|
||||
|
||||
return $this->success(['new'=> $new ??0, 'follow'=> $follow,'back' => $backs]);
|
||||
}
|
||||
return $this->success(['new' => $new ?? 0, 'follow' => $follow, 'back' => $backs]);
|
||||
}
|
||||
|
||||
public function line() {
|
||||
public function line()
|
||||
{
|
||||
$time = strtotime(date('Y-m-d'));
|
||||
$data = [];
|
||||
for($i=10; $i>0; $i--) {
|
||||
$_time = $time - 3600*24*$i;
|
||||
$d = Finances::whereBetween('create_time', [$_time, $_time + 24*3600-1])
|
||||
->where('status',1)
|
||||
for ($i = 10; $i > 0; $i--) {
|
||||
$_time = $time - 3600 * 24 * $i;
|
||||
$d = Finances::whereBetween('create_time', [$_time, $_time + 24 * 3600 - 1])
|
||||
->where('status', 1)
|
||||
->fieldRaw('SUM(IF(type=1,`total`,0))/100 as total, SUM(IF(type=2,`total`,0))/100 as refund')
|
||||
->find();
|
||||
$d->date = date("m-d", $_time);
|
||||
$data[] = $d;
|
||||
}
|
||||
$_data = [];
|
||||
foreach($data as $d) {
|
||||
foreach ($data as $d) {
|
||||
$_data['title'][] = trim($d->date);
|
||||
$_data['total'][] = $d->total ??0;
|
||||
$_data['refund'][] = abs($d->refund ??0);
|
||||
$_data['total'][] = $d->total ?? 0;
|
||||
$_data['refund'][] = abs($d->refund ?? 0);
|
||||
}
|
||||
return $this->success($_data);
|
||||
}
|
||||
|
||||
public function orders(Request $request) {
|
||||
|
||||
$order = Orders::where('admin_id', $request->admin->id)->fieldRaw('SUM(IF(status=0,1,0)) as wait, SUM(IF(status=1,1,0)) as doing, SUM(total_price) as total,count(id) as `all`')->find();
|
||||
public function orders(Request $request)
|
||||
{
|
||||
|
||||
return $this->success(['wait' => $order->wait ?? 0,'doing' => $order->doing ?? 0,'total' => $order->total ?? 0,'all' => $order->all ?? 0 ]);
|
||||
$order = Orders::where('admin_id', $request->admin->id)->fieldRaw('
|
||||
SUM(IF(status=0,1,0)) as wait,
|
||||
SUM(IF(status=1,1,0)) as doing,
|
||||
SUM(total_price) as total,
|
||||
count(id) as `all`,
|
||||
SUM(IF(asset_price>0 AND status=2,1,0)) as asset,
|
||||
SUM(IF(asset_price>0 AND status=2,asset_price,0)) as asset_price,
|
||||
SUM(CASE
|
||||
WHEN (os = 1 AND STATUS = 5) OR (os = 3 AND STATUS = 4) OR (os = 2 AND STATUS = 1) THEN 1
|
||||
ELSE 0
|
||||
END) AS refund,
|
||||
SUM(CASE
|
||||
WHEN (os = 1 AND STATUS = 5) OR (os = 3 AND STATUS = 4) OR (os = 2 AND STATUS = 1) THEN actual_price
|
||||
ELSE 0
|
||||
END) AS refund_price
|
||||
')->find();
|
||||
|
||||
// Log::warning("=====",['sql'=>$order]);
|
||||
|
||||
return $this->success([
|
||||
'wait' => $order->wait ?? 0,
|
||||
'doing' => $order->doing ?? 0,
|
||||
'total' => $order->total ?? 0,
|
||||
'all' => $order->all ?? 0,
|
||||
'asset' => $order->asset ?? 0,
|
||||
'asset_price' => $order->asset_price ?? 0,
|
||||
'refund' => $order->refund ?? 0,
|
||||
'refund_price' => $order->refund_price ?? 0
|
||||
]);
|
||||
}
|
||||
|
||||
public function pie() {
|
||||
public function pie()
|
||||
{
|
||||
$time = strtotime(date('Y-m-d'));
|
||||
$_time = $time - 3600*24*10;
|
||||
$_time = $time - 3600 * 24 * 10;
|
||||
$data = Orders::whereBetween('create_time', [$_time, time()])->fieldRaw('sum(total_price) as value, status')->group('status')->select();
|
||||
$ddd = [];
|
||||
foreach(Orders::StatusName as $k=>$d) {
|
||||
foreach (Orders::StatusName as $k => $d) {
|
||||
$item['name'] = $d;
|
||||
$item['value'] = 0;
|
||||
foreach($data as $dd) {
|
||||
if($dd->status == $k) {
|
||||
$item['value'] = $dd->value/100;
|
||||
foreach ($data as $dd) {
|
||||
if ($dd->status == $k) {
|
||||
$item['value'] = $dd->value / 100;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -111,21 +142,23 @@ class IndexController extends base
|
|||
return $this->success($ddd);
|
||||
}
|
||||
|
||||
public function Info(Request $request) {
|
||||
public function Info(Request $request)
|
||||
{
|
||||
|
||||
$info = Admins::where('id', $request->admin->id)->find();
|
||||
|
||||
return $this->success([
|
||||
'roles'=> [$info->is_super ? 'admin': 'editor'],
|
||||
'avatar'=> $info->avatar ?? '/avatar.webp',
|
||||
'name'=> $info->name,
|
||||
'is_anchor'=> $info->is_anchor ?1:0,
|
||||
'oss'=> Orders::OSS
|
||||
'roles' => [$info->is_super ? 'admin' : 'editor'],
|
||||
'avatar' => $info->avatar ?? '/avatar.webp',
|
||||
'name' => $info->name,
|
||||
'is_anchor' => $info->is_anchor ? 1 : 0,
|
||||
'oss' => Orders::OSS
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
public function qiniu() {
|
||||
public function qiniu()
|
||||
{
|
||||
// 用于签名的公钥和私钥
|
||||
$accessKey = config('qiniu.accessKey');
|
||||
$secretKey = config('qiniu.secretKey');
|
||||
|
@ -134,20 +167,52 @@ class IndexController extends base
|
|||
$auth = new Auth($accessKey, $secretKey);
|
||||
|
||||
$bucket = 'tt-api';
|
||||
$key = 'imgs/'.Date('Ym/d-His').'.jpg';
|
||||
$key = 'imgs/' . Date('Ym/d-His') . '.jpg';
|
||||
// 生成上传Token
|
||||
$token = $auth->uploadToken($bucket);
|
||||
|
||||
return $this->success(['qiniu_key'=> $key, 'qiniu_token' => $token,'qiniu_url' => 'http://up-z2.qiniup.com']);
|
||||
return $this->success(['qiniu_key' => $key, 'qiniu_token' => $token, 'qiniu_url' => 'http://up-z2.qiniup.com']);
|
||||
}
|
||||
|
||||
public function avatar(Request $request) {
|
||||
public function avatar(Request $request)
|
||||
{
|
||||
$file = $request->file("file");
|
||||
$filename = '/uploads/avatar/'.$request->admin->id.'.'.$file->getUploadExtension();
|
||||
$file->move(public_path().$filename);
|
||||
$filename = '/uploads/avatar/' . $request->admin->id . '.' . $file->getUploadExtension();
|
||||
$file->move(public_path() . $filename);
|
||||
$item = Admins::where('id', $request->admin->id)->find();
|
||||
$item->avatar = $filename;
|
||||
$item->save();
|
||||
return $this->success($filename);
|
||||
}
|
||||
|
||||
public function productNameList(Request $request)
|
||||
{
|
||||
$limit = $request->get('limit', 10);
|
||||
$product_name = $request->get('product_name');
|
||||
$list = Orders::where('admin_id',$request->admin->id)
|
||||
->fieldRaw('
|
||||
os,product_name,
|
||||
SUM(IF(status=0,1,0)) as wait,
|
||||
SUM(IF(status=1,1,0)) as doing,
|
||||
SUM(total_price) as total,
|
||||
count(id) as `all`,
|
||||
SUM(IF(asset_price>0 AND status=2,1,0)) as asset,
|
||||
SUM(IF(asset_price>0 AND status=2,asset_price,0)) as asset_price,
|
||||
SUM(CASE
|
||||
WHEN (os = 1 AND STATUS = 5) OR (os = 3 AND STATUS = 4) OR (os = 2 AND STATUS = 1) THEN 1
|
||||
ELSE 0
|
||||
END) AS refund,
|
||||
SUM(CASE
|
||||
WHEN (os = 1 AND STATUS = 5) OR (os = 3 AND STATUS = 4) OR (os = 2 AND STATUS = 1) THEN actual_price
|
||||
ELSE 0
|
||||
END) AS refund_price
|
||||
')
|
||||
->group('os,product_name')
|
||||
->order('total desc');
|
||||
if (!empty($product_name)){
|
||||
$list = $list->where('product_name','like','%'.$product_name.'%');
|
||||
}
|
||||
$list = $list->paginate($limit);
|
||||
return $this->success($list);
|
||||
}
|
||||
}
|
|
@ -104,7 +104,7 @@ class Orders extends base{
|
|||
}
|
||||
|
||||
public function backs() {
|
||||
return $this->hasOne(Backs::class, 'order_id')->visible(['status']);
|
||||
return $this->hasOne(Backs::class, 'order_id')->where('status',0)->visible(['status','admin_id']);
|
||||
}
|
||||
|
||||
public function follow() {
|
||||
|
|
Loading…
Reference in New Issue