作者 lihan

后台我的订单管理,订单确认页面全部完整接口逻辑,提交订单的余额支付和后续处理完整逻辑,以及下单时的完整校验,外加各种判断

... ... @@ -15,6 +15,33 @@ class OrderController extends AdminBaseController
public function index()
{
$where = [];
$order_sn = request()->param('order_sn');
if ($order_sn != null) {
$where['order_sn'] = ['like', "%$order_sn%"];
}
$status = request()->param('status');
if ($status != null) {
$where['status'] = ['eq', $status];
}
$res = Db::name('order_info')->alias('o')
->field('o.order_sn,o.id as oid,a.name,s.start_time,s.end_time,o.status,u.user_nickname')
->join('activity a', 'a.id=o.activity_id')
->join('activity_schedule s', 's.id=o.schedule_id')
->join('user u', 'u.id=o.user_id')
->where($where)
->order('add_time DESC')
->paginate(20, false, ['query' => request()->param()]);
foreach ($res as $k => $v) {
$v['status'] = getOrderStatusText($v['status']);
$res[$k] = $v;
}
return $this->fetch('', [
'posts' => $res,
'page' => $res->render(),
'order_sn' => $order_sn,
'status' => $status
]);
}
}
\ No newline at end of file
... ...
<?php
namespace app\order\controller;
use app\coupons\model\CouponModel;
use app\order\model\OrderModel;
use cmf\controller\HomeBaseController;
use think\Db;
... ... @@ -36,9 +37,10 @@ class OrderController extends HomeBaseController
$coupons = new CouponModel;
$couponsList = $coupons->orderCoupon($post['activity_id'], $post['schedule_id'], $post['num'], session('user.id'));
$schedule = Db::name('activity_schedule')
->field('id as schedule_id,start_time,end_time,maximum,real_join_num,addition_join_num')
->field('id as schedule_id,start_time,end_time,maximum,real_join_num,addition_join_num,price')
->where(['activity_id' => $post['activity_id']])
->select();
$total = 0;
foreach ($schedule as $k => $v) {
$v['start_time'] = date('Y.m.d', $v['start_time']);
$v['end_time'] = date('Y.m.d', $v['end_time']);
... ... @@ -47,12 +49,22 @@ class OrderController extends HomeBaseController
unset($v['real_join_num']);
unset($v['addition_join_num']);
unset($v['maximum']);
if ($v['schedule_id'] == $post['schedule_id']) {
$v['checked'] = 1;
$v['num'] = $post['num'];
$total = $v['price'] * $post['num'];
} else {
$v['checked'] = 0;
}
unset($v['price']);
$schedule[$k] = $v;
}
$result = [
'activity' => Db::name('activity')->field('id as activity,name')->where(['id' => $post['activity_id']])->find(),
'activity' => Db::name('activity')->field('id as activity_id,name, is_down_payment as type')->where(['id' => $post['activity_id']])->find(),
'schedule' => $schedule,
'coupons' => $couponsList
'coupons' => $couponsList,
'down_price' => Db::name('activity')->where(['id' => $post['activity_id']])->value('down_price') * $post['num'],
'total' => $total
];
echo json_encode(['data' => $result]);
exit();
... ... @@ -70,7 +82,7 @@ class OrderController extends HomeBaseController
* @param name:num type:int require:1 default:2 desc:上一页选中的购买数量
* @param name:escort type:char require:1 default:同行人id字符串(逗号分隔) desc:1,2,3
* @param name:payment type:int require:1 default:支付方式 desc:0余额,1微信,2支付宝
* @param name:discount_coupon_id type:int require:1 default:1 desc:优惠券id
* @param name:discount_coupon_id type:int require:1 default:112 desc:优惠券id
* @param name:room type:char require:1 default:1 desc:房间信息
* @param name:desc type:text require:1 default:1 desc:商家备注
*/
... ... @@ -89,12 +101,12 @@ class OrderController extends HomeBaseController
$data['order_type'] = $activity['is_down_payment'];
$data['is_use_discount_coupon'] = (empty($post['discount_coupon_id'])) ? 0 : 1;
$data['discount_coupon_id'] = $post['discount_coupon_id'];
$data['payment'] = $post['payment'];
$data['status'] = 0;
if ($data['order_type'] == 0) {
$data['payment1'] = $post['payment'];
} else {
$post['payment2'] = $post['payment'];
}
$data['room'] = $post['room'];
$data['desc'] = $post['desc'];
$final_price = $this->getFinalPrice($data['activity_id'], $data['schedule_id'], $post['num'], $data['discount_coupon_id']);
$this->checkOrder($data['schedule_id'], $data['payment'], $post['escort'], $post['num'], $final_price);
Db::startTrans();
if (Db::name('order_info')->insert($data)) {
$oid = Db::name('order_info')->getLastInsID();
... ... @@ -110,20 +122,21 @@ class OrderController extends HomeBaseController
];
}
if (Db::name('order_detail')->insertAll($detail)) {
//插入订单记录表(包含订单总价)
$log = [
'oid' => $oid,
'order_amount' => $final_price,
'type' => $data['order_type']
];
if (Db::name('order_log')->insert($log)) {
Db::commit();
//选择支付方式0,1,2
//余额支付
if ($post['payment'] == 0) {
} elseif ($post['payment'] == 1) {
} elseif ($post['payment'] == 2) {
} else {
echo json_encode(['msg' => '请选择支付方式', 'code' => 40000]);
$model = new OrderModel;
if ($model->orderCallBack($oid)) {
echo json_encode(['msg' => '下单成功', 'code' => 20000]);
exit();
}
}
}
} else {
Db::rollback();
echo json_encode(['msg' => '下单失败', 'code' => 40000]);
... ... @@ -136,4 +149,65 @@ class OrderController extends HomeBaseController
}
}
/**
* 计算订单最终价格
* @param $activityId
* @param $scheduleId
* @param $num
* @param null $discountCouponId
* @return float|int|mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
private function getFinalPrice($activityId, $scheduleId, $num, $discountCouponId = null)
{
$info = Db::name('activity')->field('is_down_payment,down_price')->where(['id' => $activityId])->find();
//如果有定金则支付定金*数量
if ($info['is_down_payment'] == 1) {
$sum = $info['down_price'] * $num;
} //如果没有定金则支付批次金额*数量
else {
$price = Db::name('activity_schedule')->where(['activity_id' => $activityId, 'id' => $scheduleId])->value('price');
$sum = $price * $num;
}
//如果有使用优惠券
if (!empty($discountCouponId)) {
//判断该优惠券是否已使用
$coupons = Db::name('discount_coupon')->field('status,reduce,overflow')->where(['id' => $discountCouponId])->find();
if ($coupons['status'] == 1) {
//是否符合满减
if ($sum >= $coupons['overflow']) {
$sum -= $coupons['reduce'];
}
}
}
return $sum;
}
private function checkOrder($scheduleId, $payment = 0, $escort, $num, $finalPrice)
{
//判断支付方式
if ($payment != 0 && $payment != 1 && $payment != 2) {
echo json_encode(['msg' => '请选择支付方式', 'code' => 40000]);
exit();
}
//判断活动是否过期
if (Db::name('activity_schedule')->where(['id' => $scheduleId])->value('deadline') < time()) {
echo json_encode(['msg' => '本次活动已过期,请重新选择', 'code' => 40000]);
exit();
}
//判断用户余额能否支持余额支付
if (Db::name('user')->where(['id' => session('user.id')])->value('balance') < $finalPrice) {
echo json_encode(['msg' => '您的余额不足,请选择其他支付方式', 'code' => 40000]);
exit();
}
//判断出行人与购买数量是否匹配
$escortNum = (strlen($escort) == 1) ? 1 : count(explode(',', $escort));
if ($escortNum != $num) {
echo json_encode(['msg' => '购买数量需与出行人数量一致', 'code' => 40000]);
exit();
}
}
}
\ No newline at end of file
... ...
... ... @@ -11,18 +11,102 @@ use think\Db;
class OrderModel extends Model
{
//暂定
public function orderList($status, $orderSn)
public function getOrderListByUserId($status, $orderSn, $userId)
{
$where = [];
$where['user_id'] = ['eq', $userId];
if ($orderSn != null) {
$where['order_sn'] = ['like', "%$orderSn%"];
}
if ($status !== false) {
if ($status != null) {
$where['status'] = ['eq', $status];
}
return Db::name('order_info')->where($where)->select();
$res = Db::name('order_info')->alias('o')
->field('o.id as oid,o.order_sn,a.name,a.thumb,o.status')
->join('activity a', 'a.id=o.activity_id')
->where($where)
->order('add_time DESC')
->select()
->toArray();
foreach ($res as $k => $v) {
$v['status_text'] = getOrderStatusText($v['status']);
$res[$k] = $v;
}
return $res;
}
//通用订单回调类(未完待续。。。)
//余额扣除(如果余额支付->钱包记录)->优惠券变为已使用(如果使用优惠券)->改变订单状态(必然)->相应批次库存减少(必然)
public function orderCallBack($oid)
{
$orderInfo = Db::name('order_info')->alias('o')
->field('o.user_id,o.is_use_discount_coupon,discount_coupon_id,o.status,o.payment,o.order_type,o.activity_id,o.schedule_id,l.order_amount')
->join('order_log l', 'l.oid=o.id')
->where(['o.id' => $oid])
->find();
Db::startTrans();
$go = 'rollback';
if ($orderInfo['payment'] == 0) {
if (Db::name('user')->where(['id' => $orderInfo['user_id']])->setDec('balance', $orderInfo['order_amount'])) {
$wallet = [
'user_id' => $orderInfo['user_id'],
'type' => 0,
'cost' => $orderInfo['order_amount'],
'create_time' => time()
];
if (Db::name('my_wallet')->insert($wallet)) {
$go = 'commit';
} else {
return false;
}
} else {
return false;
}
}
if ($orderInfo['is_use_discount_coupon'] == 1 && !empty($orderInfo['discount_coupon_id'])) {
$coupons = [
'id' => $orderInfo['discount_coupon_id'],
'use_time' => time(),
'status' => 2
];
if (Db::name('discount_coupon')->update($coupons)) {
$go = 'commit';
} else {
return false;
}
}
//订单状态无定金直接变为3,有定金变为1
if ($orderInfo['status'] == 0) {
if ($orderInfo['order_type'] == 0) {
$status = 3;
} elseif ($orderInfo['order_type'] == 1) {
$status = 1;
} else {
$status = 0;
}
$order = [
'id' => $oid,
'status' => $status
];
if (Db::name('order_info')->update($order)) {
//相应批次报名数增加
$dec = Db::name('order_detail')->where(['oid' => $oid])->count();
if (Db::name('activity_schedule')->where(['id' => $orderInfo['schedule_id']])->setInc('real_join_num', $dec)) {
$go = 'commit';
} else {
return false;
}
} else {
return false;
}
}
if ($go == 'commit') {
Db::commit();
return true;
} else {
Db::rollback();
return false;
}
}
}
\ No newline at end of file
... ...
... ... @@ -11,6 +11,7 @@ use app\coupons\model\CouponModel;
use cmf\controller\HomeBaseController;
use Think\Db;
use app\coupons\model\DiscountCouponModel;
use app\order\model\OrderModel;
/**
* @title 个人中心模块
... ... @@ -27,6 +28,20 @@ class CenterController extends HomeBaseController
}
/**
* @title 个人中心首页
* @description 默认访问接口
* @author sᴏᴜʟ ᴏғ ᴄɪɴᴅᴇʀ
* @url /user/Center/index
* @method GET
*/
public function index()
{
$userInfo = Db::name('user')->field('user_nickname,avatar')->where(['id' => session('user.id')])->find();
echo json_encode(['user_info' => $userInfo, 'code' => 20000]);
exit();
}
/**
* @title 我的资料
* @description 默认访问接口(post方式更改用户信息需要填写参数,post以外是模板渲染用户信息)
* @author sᴏᴜʟ ᴏғ ᴄɪɴᴅᴇʀ
... ... @@ -144,4 +159,33 @@ class CenterController extends HomeBaseController
exit();
}
/**
* @title 订单列表
* @description 默认访问接口
* @author sᴏᴜʟ ᴏғ ᴄɪɴᴅᴇʀ
* @url /user/Center/orderList
* @method POST
*
* @param name:status type:int require:1 default: desc:订单状态
* @param name:order_sn type:char require:1 default:201809091314 desc:订单号
* @return version:版本号
* @return code:错误码
*/
public function orderList()
{
$request = request();
$order['status'] = $request->param('status');
$order['order_sn'] = $request->param('order_sn');
$model = new OrderModel;
$list = $model->getOrderListByUserId($order['status'], $order['order_sn'], session('user.id'));
if (!empty($list)) {
echo json_encode(['order_list' => $list, 'code' => 20000]);
exit();
} else {
echo json_encode(['msg' => '暂无数据', 'code' => 40000]);
exit();
}
}
}
\ No newline at end of file
... ...
<include file="public@header"/>
</head>
<body>
<div class="wrap js-check-wrap">
<ul class="nav nav-tabs">
<li class="active"><a href="javascript:;">全部订单</a></li>
</ul>
<form class="well form-inline margin-top-20" method="post" action="{:url('Order/index')}">
状态:
<select class="form-control" name="status" style="width: 140px;">
<option value='0' <if condition="$status eq '0'">selected</if>>全部</option>
<option value='1' <if condition="$status eq '1'">selected</if>>待付定金</option>
<option value='2' <if condition="$status eq '2'">selected</if>>已付定金</option>
<option value='3' <if condition="$status eq '3'">selected</if>>待付尾款</option>
<option value='4' <if condition="$status eq '4'">selected</if>>已付尾款</option>
<option value='5' <if condition="$status eq '5'">selected</if>>待评价</option>
<option value='6' <if condition="$status eq '6'">selected</if>>已完成</option>
<option value='7' <if condition="$status eq '7'">selected</if>>已取消</option>
</select> &nbsp;&nbsp;
订单号:
<input type="text" class="form-control" name="order_sn" style="width: 200px;"
value="{$order_sn|default=''}" placeholder="请输入关键字...">
<input type="submit" class="btn btn-primary" value="搜索"/>
<a class="btn btn-danger" href="{:url('Order/index')}">清空</a>
</form>
<form class="js-ajax-form" action="" method="post">
<table class="table table-hover table-bordered table-list">
<tr>
<th>序号</th>
<th>订单号</th>
<th>用户昵称</th>
<th>活动名称</th>
<th>批次时间</th>
<th>订单状态</th>
<th>操作</th>
</tr>
<volist name="posts" id="vo" key="k">
<tr>
<td>{$k}</td>
<td>{$vo.order_sn}</td>
<td>{$vo.user_nickname}</td>
<td>{$vo.name}</td>
<td>{$vo.start_time|date='Y.m.d', ###} 至 {$vo.end_time|date='Y.m.d', ###}</td>
<td>{$vo.status}</td>
<td>查看</td>
</tr>
</volist>
</table>
<ul class="pagination">{$page|default=''}</ul>
</form>
</div>
<script src="__STATIC__/js/admin.js"></script>
</body>
</html>
\ No newline at end of file
... ...
... ... @@ -1888,3 +1888,17 @@ function getMonthEnglishWords($index)
return $arr[$index];
}
function getOrderStatusText($status) {
$text=[
0 => '未支付',
1 => '待付定金',
2 => '已付定金',
3 => '待付尾款',
4 => '已付尾款',
5 => '待评价',
6 => '已完成',
7 => '已取消'
];
return $text[$status];
}
... ...