订单退款

feat/task1-c-wallet
devil_gong 2019-05-28 18:40:01 +08:00
parent 5f33322c5b
commit 68cff17e97
9 changed files with 256 additions and 164 deletions

View File

@ -75,8 +75,8 @@
<table class="am-table am-table-striped am-table-hover am-text-middle m-t-10">
<thead>
<tr>
<th class="row-user-info am-hide-md-down">用户信息</th>
<th class="row-goods am-hide-sm-only">商品信息</th>
<th class="row-user-info am-hide-md-down">用户信息</th>
<th class="row-apply">申请信息</th>
<th class="am-hide-sm-only">凭证</th>
<th class="am-hide-sm-only">状态</th>
@ -89,19 +89,6 @@
{{if !empty($data_list)}}
{{foreach $data_list as $v}}
<tr id="data-list-{{$v.id}}">
<td class="user-info am-hide-md-down">
{{if !empty($v['user'])}}
<img src="{{$v.user.avatar}}" alt="{{$v.user.user_name_view}}" class="am-img-thumbnail am-radius am-align-left" />
<ul class="user-base">
<li>名称:{{if empty($v['user']['username'])}}<span class="cr-ccc">未填写</span>{{else /}}{{$v.user.username}}{{/if}}</li>
<li>昵称:{{if empty($v['user']['nickname'])}}<span class="cr-ccc">未填写</span>{{else /}}{{$v.user.nickname}}{{/if}}</li>
<li>手机:{{if empty($v['user']['mobile'])}}<span class="cr-ccc">未填写</span>{{else /}}{{$v.user.mobile}}{{/if}}</li>
<li>邮箱:{{if empty($v['user']['email'])}}<span class="cr-ccc">未填写</span>{{else /}}{{$v.user.email}}{{/if}}</li>
</ul>
{{else /}}
用户信息异常
{{/if}}
</td>
<td class="am-hide-sm-only">
<div class="goods-detail">
<a href="{{$v.order_data.items.goods_url}}" target="_blank">
@ -123,6 +110,19 @@
{{/if}}
<p class="line-price">¥{{$v.order_data.items.price}} x {{$v.order_data.items.buy_number}}</p>
</td>
<td class="user-info am-hide-md-down">
{{if !empty($v['user'])}}
<img src="{{$v.user.avatar}}" alt="{{$v.user.user_name_view}}" class="am-img-thumbnail am-radius am-align-left" />
<ul class="user-base">
<li>名称:{{if empty($v['user']['username'])}}<span class="cr-ccc">未填写</span>{{else /}}{{$v.user.username}}{{/if}}</li>
<li>昵称:{{if empty($v['user']['nickname'])}}<span class="cr-ccc">未填写</span>{{else /}}{{$v.user.nickname}}{{/if}}</li>
<li>手机:{{if empty($v['user']['mobile'])}}<span class="cr-ccc">未填写</span>{{else /}}{{$v.user.mobile}}{{/if}}</li>
<li>邮箱:{{if empty($v['user']['email'])}}<span class="cr-ccc">未填写</span>{{else /}}{{$v.user.email}}{{/if}}</li>
</ul>
{{else /}}
用户信息异常
{{/if}}
</td>
<td>
类型:{{$v.type_text}}<br />
原因:{{$v.reason}}<br />
@ -171,21 +171,6 @@
</div>
<div class="am-popup-bd">
<dl class="dl-content">
<dt>用户信息</dt>
<dd class="user-info">
{{if !empty($v['user'])}}
<img src="{{$v.user.avatar}}" alt="{{$v.user.user_name_view}}" class="am-img-thumbnail am-radius am-align-left" />
<ul class="user-base">
<li>名称:{{if empty($v['user']['username'])}}<span class="cr-ccc">未填写</span>{{else /}}{{$v.user.username}}{{/if}}</li>
<li>昵称:{{if empty($v['user']['nickname'])}}<span class="cr-ccc">未填写</span>{{else /}}{{$v.user.nickname}}{{/if}}</li>
<li>手机:{{if empty($v['user']['mobile'])}}<span class="cr-ccc">未填写</span>{{else /}}{{$v.user.mobile}}{{/if}}</li>
<li>邮箱:{{if empty($v['user']['email'])}}<span class="cr-ccc">未填写</span>{{else /}}{{$v.user.email}}{{/if}}</li>
</ul>
{{else /}}
用户信息异常
{{/if}}
</dd>
<dt>商品信息</dt>
<dd>
<div class="goods-detail">
@ -209,6 +194,21 @@
<p class="line-price">¥{{$v.order_data.items.price}} x {{$v.order_data.items.buy_number}}</p>
</dd>
<dt>用户信息</dt>
<dd class="user-info">
{{if !empty($v['user'])}}
<img src="{{$v.user.avatar}}" alt="{{$v.user.user_name_view}}" class="am-img-thumbnail am-radius am-align-left" />
<ul class="user-base">
<li>名称:{{if empty($v['user']['username'])}}<span class="cr-ccc">未填写</span>{{else /}}{{$v.user.username}}{{/if}}</li>
<li>昵称:{{if empty($v['user']['nickname'])}}<span class="cr-ccc">未填写</span>{{else /}}{{$v.user.nickname}}{{/if}}</li>
<li>手机:{{if empty($v['user']['mobile'])}}<span class="cr-ccc">未填写</span>{{else /}}{{$v.user.mobile}}{{/if}}</li>
<li>邮箱:{{if empty($v['user']['email'])}}<span class="cr-ccc">未填写</span>{{else /}}{{$v.user.email}}{{/if}}</li>
</ul>
{{else /}}
用户信息异常
{{/if}}
</dd>
<dt>申请信息</dt>
<dd>
类型:{{$v.type_text}}<br />

View File

@ -146,9 +146,9 @@ class Orderaftersale extends Common
{
// 参数
$params = input();
$order_id = isset($params['id']) ? intval($params['id']) : 0;
$goods_id = isset($params['gid']) ? intval($params['gid']) : 0;
$ret = OrderAftersaleService::OrdferGoodsRow($order_id, $goods_id, $this->user['id']);
$order_id = isset($params['oid']) ? intval($params['oid']) : 0;
$order_detail_id = isset($params['did']) ? intval($params['did']) : 0;
$ret = OrderAftersaleService::OrdferGoodsRow($order_id, $order_detail_id, $this->user['id']);
if($ret['code'] == 0)
{
$this->assign('goods', $ret['data']['items']);
@ -167,8 +167,7 @@ class Orderaftersale extends Common
'm' => 0,
'n' => 1,
'where' => [
['order_id', '=', $order_id],
['goods_id', '=', $goods_id],
['order_detail_id', '=', $order_detail_id],
['user_id', '=', $this->user['id']],
],
];

View File

@ -187,7 +187,7 @@
</td>
<td class="row-number">
{{if in_array($order['status'], [2,3,4])}}
<a href="{{:MyUrl('index/orderaftersale/aftersale', ['id'=>$order['id'], 'gid'=>$goods['goods_id']])}}" target="_blank">
<a href="{{:MyUrl('index/orderaftersale/aftersale', ['oid'=>$order['id'], 'did'=>$goods['id']])}}" target="_blank">
{{switch $order.status}}
{{case 2|3}}
退款/退货

View File

@ -32,8 +32,8 @@
</div>
<div class="am-form-group am-form-group-refreshing">
<input type="hidden" name="order_id" value="{{$params.id}}" />
<input type="hidden" name="goods_id" value="{{$params.gid}}" />
<input type="hidden" name="order_id" value="{{$params.oid}}" />
<input type="hidden" name="order_detail_id" value="{{$params.did}}" />
<input type="hidden" name="type" value="" />
<button type="submit" class="am-btn am-btn-primary am-radius btn-loading-example am-btn-sm am-btn-block" data-am-loading="{loadingText:'处理中...'}">提交</button>
</div>

View File

@ -1049,8 +1049,16 @@ class BuyService
return DataReturn('当前订单状态不允许回滚库存['.$params['order_id'].'-'.$params['order_data']['status'].']', 0);
}
// 是否指定商品和数量
$appoint_buy_number = empty($params['appoint_buy_number']) ? 0 : intval($params['appoint_buy_number']);
$detail_where = ['order_id' => $params['order_id']];
if(!empty($params['appoint_order_detail_id']))
{
$detail_where['id'] = intval($params['appoint_order_detail_id']);
}
// 获取订单商品
$order_detail = Db::name('OrderDetail')->field('goods_id,buy_number,spec')->where(['order_id'=>$params['order_id']])->select();
$order_detail = Db::name('OrderDetail')->field('goods_id,buy_number,spec')->where($detail_where)->select();
if(!empty($order_detail))
{
foreach($order_detail as $v)
@ -1059,19 +1067,22 @@ class BuyService
$temp = Db::name('OrderGoodsInventoryLog')->where(['order_id'=>$params['order_id'], 'goods_id'=>$v['goods_id'], 'is_rollback'=>0])->find();
if(!empty($temp))
{
// 数量
$buy_number = ($appoint_buy_number == 0) ? $v['buy_number'] : $appoint_buy_number;
// 回滚操作
if(!Db::name('Goods')->where(['id'=>$v['goods_id']])->setInc('inventory', $v['buy_number']))
if(!Db::name('Goods')->where(['id'=>$v['goods_id']])->setInc('inventory', $buy_number))
{
return DataReturn('商品库存回滚失败['.$params['order_id'].'-'.$v['goods_id'].']', -10);
}
// 扣除规格库存
// 回滚规格库存
$spec = empty($v['spec']) ? '' : json_decode($v['spec'], true);
$base = GoodsService::GoodsSpecDetail(['id'=>$v['goods_id'], 'spec'=>$spec]);
if($base['code'] == 0)
{
// 扣除规格操作
if(!Db::name('GoodsSpecBase')->where(['id'=>$base['data']['id'], 'goods_id'=>$v['goods_id']])->setInc('inventory', $v['buy_number']))
// 回滚规格操作
if(!Db::name('GoodsSpecBase')->where(['id'=>$base['data']['id'], 'goods_id'=>$v['goods_id']])->setInc('inventory', $buy_number))
{
return DataReturn('规格库存回滚失败['.$params['order_id'].'-'.$v['goods_id'].']', -10);
}

View File

@ -17,6 +17,7 @@ use app\service\ResourcesService;
use app\service\RefundLogService;
use app\service\OrderService;
use app\service\MessageService;
use app\plugins\wallet\service\WalletService;
/**
* 订单售后服务层
@ -34,11 +35,11 @@ class OrderAftersaleService
* @version 1.0.0
* @date 2019-05-23
* @desc description
* @param [int] $order_id [订单id]
* @param [int] $goods_id [商品id]
* @param [int] $user_id [用户id]
* @param [int] $order_id [订单id]
* @param [int] $order_detail_id [订单详情id]
* @param [int] $user_id [用户id]
*/
public static function OrdferGoodsRow($order_id, $goods_id, $user_id)
public static function OrdferGoodsRow($order_id, $order_detail_id, $user_id)
{
// 获取列表
$data_params = array(
@ -59,7 +60,7 @@ class OrderAftersaleService
{
foreach($ret['data'][0]['items'] as $v)
{
if($goods_id == $v['goods_id'])
if($order_detail_id == $v['id'])
{
$goods = $v;
break;
@ -94,8 +95,8 @@ class OrderAftersaleService
],
[
'checked_type' => 'empty',
'key_name' => 'goods_id',
'error_msg' => '商品id有误',
'key_name' => 'order_detail_id',
'error_msg' => '订单详情id有误',
],
[
'checked_type' => 'in',
@ -142,7 +143,7 @@ class OrderAftersaleService
}
// 获取订单数据
$order = self::OrdferGoodsRow($params['order_id'], $params['goods_id'], $params['user']['id']);
$order = self::OrdferGoodsRow($params['order_id'], $params['order_detail_id'], $params['user']['id']);
if($order['code'] != 0)
{
return $order;
@ -151,7 +152,7 @@ class OrderAftersaleService
// 当前是否存在进行中
$where = [
['order_id', '=', intval($params['order_id'])],
['goods_id', '=', intval($params['goods_id'])],
['order_detail_id', '=', intval($params['order_detail_id'])],
['user_id', '=', $params['user']['id']],
['status', '<=', 2],
];
@ -182,7 +183,7 @@ class OrderAftersaleService
$number = isset($params['number']) ? intval($params['number']) : 0;
// 历史退货数量
$where[] = ['goods_id', '=', intval($params['goods_id'])];
$where[] = ['order_detail_id', '=', intval($params['order_detail_id'])];
$history_number = (int) Db::name('OrderAftersale')->where($where)->sum('number');
if($params['type'] == 1)
{
@ -204,19 +205,20 @@ class OrderAftersaleService
// 数据
$data = [
'order_no' => $order['data']['order_no'],
'type' => intval($params['type']),
'order_id' => intval($params['order_id']),
'goods_id' => intval($params['goods_id']),
'user_id' => $params['user']['id'],
'number' => ($params['type'] == 0) ? 0 : $number,
'price' => $price,
'reason' => $params['reason'],
'msg' => $params['msg'],
'images' => json_encode($images),
'status' => ($params['type'] == 0) ? 2 : 0,
'add_time' => time(),
'apply_time' => time(),
'order_no' => $order['data']['order_no'],
'type' => intval($params['type']),
'order_detail_id' => intval($params['order_detail_id']),
'order_id' => intval($params['order_id']),
'goods_id' => $order['data']['items']['goods_id'],
'user_id' => $params['user']['id'],
'number' => ($params['type'] == 0) ? 0 : $number,
'price' => $price,
'reason' => $params['reason'],
'msg' => $params['msg'],
'images' => json_encode($images),
'status' => ($params['type'] == 0) ? 2 : 0,
'add_time' => time(),
'apply_time' => time(),
];
if(Db::name('OrderAftersale')->insertGetId($data) > 0)
{
@ -331,7 +333,7 @@ class OrderAftersaleService
foreach($data as &$v)
{
// 订单商品
$order = self::OrdferGoodsRow($v['order_id'], $v['goods_id'], $v['user_id']);
$order = self::OrdferGoodsRow($v['order_id'], $v['order_detail_id'], $v['user_id']);
$v['order_data'] = $order['data'];
// 用户信息
@ -664,7 +666,7 @@ class OrderAftersaleService
}
// 获取订单数据
$order = self::OrdferGoodsRow($aftersale['order_id'], $aftersale['goods_id'], $aftersale['user_id']);
$order = self::OrdferGoodsRow($aftersale['order_id'], $aftersale['order_detail_id'], $aftersale['user_id']);
if($order['code'] != 0)
{
return $order;
@ -737,31 +739,35 @@ class OrderAftersaleService
}
}
// 退款方式
$ret = DataReturn('退款方式未定义', -100);
switch($params['refundment'])
// 原路退回
if($params['refundment'] == 0)
{
// 原路退回
case 0 :
$ret = self::OriginalRoadRefundment($params, $aftersale, $order['data'], $pay_log);
break;
$refund = self::OriginalRoadRefundment($params, $aftersale, $order['data'], $pay_log);
// 退至钱包
case 1 :
$ret = self::WalletRefundment($params, $aftersale, $order['data'], $pay_log);
break;
// 手动处理
case 2 :
$ret = DataReturn('退款成功', 0);
break;
// 钱包走事务处理, 手动处理不涉及金额
} else {
$refund = DataReturn('退款成功', 0);
}
// 退款成功
if($ret['code'] == 0)
if($refund['code'] == 0)
{
// 开启事务
Db::startTrans();
// 钱包操作 - 退至钱包
if($params['refundment'] == 1)
{
$ret = self::WalletRefundment($params, $aftersale, $order['data'], $pay_log);
if($ret['code'] != 0)
{
// 事务回滚
Db::rollback();
return $ret;
}
}
// 更新主订单
$upd_data = [
'status' => 6,
'pay_status' => 2,
@ -771,7 +777,7 @@ class OrderAftersaleService
if(Db::name('Order')->where(['id'=>$order['data']['id']])->update($upd_data))
{
// 库存回滚
$ret = BuyService::OrderInventoryRollback(['order_id'=>$order['data']['id'], 'order_data'=>$upd_data]);
$ret = BuyService::OrderInventoryRollback(['order_id'=>$order['data']['id'], 'order_data'=>$upd_data, 'appoint_order_detail_id'=>$aftersale['order_detail_id'], 'appoint_buy_number'=>$aftersale['number']]);
if($ret['code'] != 0)
{
// 事务回滚
@ -791,6 +797,7 @@ class OrderAftersaleService
// 更新退款状态
$upd_data = [
'status' => 3,
'refundment' => $params['refundment'],
'audit_time' => time(),
'upd_time' => time(),
];
@ -808,7 +815,7 @@ class OrderAftersaleService
Db::rollback();
return DataReturn('退款失败', -1);
}
return $ret;
return $refund;
}
/**
@ -882,7 +889,61 @@ class OrderAftersaleService
*/
private static function WalletRefundment($params, $aftersale, $order, $pay_log)
{
return DataReturn('开发中', -10);
// 获取用户钱包校验
$user_wallet = WalletService::UserWallet($order['user_id']);
if($user_wallet['code'] != 0)
{
return $user_wallet;
}
// 钱包更新数据
$data = [
'normal_money' => PriceNumberFormat($user_wallet['data']['normal_money']+$aftersale['price']),
'upd_time' => time(),
];
if(!Db::name('PluginsWallet')->where(['id'=>$user_wallet['data']['id']])->update($data))
{
return DataReturn('钱包更新失败', -10);
}
// 钱包变更日志
$msg = $order['order_no'].'订单退款'.$aftersale['price'].'元';
$log_data = [
'user_id' => $user_wallet['data']['user_id'],
'wallet_id' => $user_wallet['data']['id'],
'business_type' => 0,
'operation_type' => 1,
'money_type' => 0,
'operation_money' => $aftersale['price'],
'original_money' => $user_wallet['data']['normal_money'],
'latest_money' => $data['normal_money'],
'msg' => $msg,
];
if(!WalletService::WalletLogInsert($log_data))
{
return DataReturn('钱包日志添加失败', -101);
}
// 写入退款日志
$refund_log = [
'user_id' => $order['user_id'],
'order_id' => $order['id'],
'total_price' => $order['total_price'],
'trade_no' => '',
'buyer_user' => '',
'refund_price' => $aftersale['price'],
'msg' => $msg,
'payment' => $pay_log['payment'],
'payment_name' => $pay_log['payment_name'],
'business_type' => 1,
'return_params' => '',
];
RefundLogService::RefundLogInsert($refund_log);
// 消息通知
MessageService::MessageAdd($order['user_id'], '账户余额变动', $msg, 1, $order['id']);
return DataReturn('退款成功', 0);
}
/**

View File

@ -88,11 +88,11 @@ class RefundLogService
$where = empty($params['where']) ? [] : $params['where'];
$m = isset($params['m']) ? intval($params['m']) : 0;
$n = isset($params['n']) ? intval($params['n']) : 10;
$field = 'p.*,u.username,u.nickname,u.mobile,u.gender';
$order_by = empty($params['order_by']) ? 'p.id desc' : $params['order_by'];
$field = 'r.*,u.username,u.nickname,u.mobile,u.gender';
$order_by = empty($params['order_by']) ? 'r.id desc' : $params['order_by'];
// 获取数据列表
$data = Db::name('RefundLog')->alias('p')->join(['__USER__'=>'u'], 'u.id=p.user_id')->where($where)->field($field)->limit($m, $n)->order($order_by)->select();
$data = Db::name('RefundLog')->alias('r')->join(['__USER__'=>'u'], 'u.id=r.user_id')->where($where)->field($field)->limit($m, $n)->order($order_by)->select();
if(!empty($data))
{
$common_business_type_list = lang('common_business_type_list');
@ -124,7 +124,7 @@ class RefundLogService
*/
public static function AdminRefundLogTotal($where = [])
{
return (int) Db::name('RefundLog')->alias('p')->join(['__USER__'=>'u'], 'u.id=p.user_id')->where($where)->count();
return (int) Db::name('RefundLog')->alias('r')->join(['__USER__'=>'u'], 'u.id=r.user_id')->where($where)->count();
}
/**
@ -143,7 +143,7 @@ class RefundLogService
// 关键字
if(!empty($params['keywords']))
{
$where[] = ['p.trade_no|u.username|u.nickname|u.mobile', 'like', '%'.$params['keywords'].'%'];
$where[] = ['r.trade_no|u.username|u.nickname|u.mobile', 'like', '%'.$params['keywords'].'%'];
}
// 是否更多条件
@ -152,11 +152,11 @@ class RefundLogService
// 等值
if(isset($params['business_type']) && $params['business_type'] > -1)
{
$where[] = ['p.business_type', '=', intval($params['business_type'])];
$where[] = ['r.business_type', '=', intval($params['business_type'])];
}
if(!empty($params['pay_type']))
{
$where[] = ['p.payment', '=', $params['pay_type']];
$where[] = ['r.payment', '=', $params['pay_type']];
}
if(isset($params['gender']) && $params['gender'] > -1)
{
@ -165,20 +165,20 @@ class RefundLogService
if(!empty($params['price_start']))
{
$where[] = ['p.pay_price', '>', PriceNumberFormat($params['price_start'])];
$where[] = ['r.pay_price', '>', PriceNumberFormat($params['price_start'])];
}
if(!empty($params['price_end']))
{
$where[] = ['p.pay_price', '<', PriceNumberFormat($params['price_end'])];
$where[] = ['r.pay_price', '<', PriceNumberFormat($params['price_end'])];
}
if(!empty($params['time_start']))
{
$where[] = ['p.add_time', '>', strtotime($params['time_start'])];
$where[] = ['r.add_time', '>', strtotime($params['time_start'])];
}
if(!empty($params['time_end']))
{
$where[] = ['p.add_time', '<', strtotime($params['time_end'])];
$where[] = ['r.add_time', '<', strtotime($params['time_end'])];
}
}

File diff suppressed because one or more lines are too long

View File

@ -20,7 +20,7 @@ $(function()
$popup.find('.apply-info .reason span').html(data.reason || '<span class="cr-ddd">未填写</span>');
$popup.find('.apply-info .number span').html(data.number || '<span class="cr-ddd">未填写</span>');
$popup.find('.apply-info .price span').html('¥'+data.price || '<span class="cr-ddd">未填写</span>');
$popup.find('.apply-info .msg span').html(data.price || '<span class="cr-ddd">未填写</span>');
$popup.find('.apply-info .msg span').html(data.msg || '<span class="cr-ddd">未填写</span>');
$popup.modal();
}