You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1655 lines
59 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?php
namespace app\mall\logic;
use app\base\logic\Freight;
use app\base\model\user\User;
use app\base\model\user\UserAddress;
use app\base\model\user\UserInfo;
use app\discount\model\DiscountCouponMy;
use app\discount\service\MyCoupon;
use app\distribution\logic\Commission;
use app\distribution\model\DistributionCommissionIncome;
use app\distribution\model\DistributionConfig;
use app\mall\model\MallCart;
use app\mall\model\MallConfig;
use app\mall\model\MallEvaluate;
use app\mall\model\MallOrder;
use app\mall\model\MallOrderCoupon;
use app\mall\model\MallOrderProduct;
use app\mall\model\MallOrderRefund;
use app\mall\model\MallProduct;
use app\mall\model\MallProductSku;
use app\mall\model\MallRefundCause;
use app\mall\model\MallSpikeProduct;
use app\mall\model\MallSpikeProductSku;
use app\money\logic\Money;
use Godruoyi\Snowflake\Snowflake;
use kdniao\Logistics;
use think\facade\Db;
use think\facade\Request;
class Order extends Base
{
/**
* 获取下单数据(通过产品 地址 优惠券 整合各类价钱)
* @param int $buy_type 购买类型 1--购物车 2--立即购买
* @param int $my_address_id 我的地址ID
* @param int $product_id buy_type=2时产品ID
* @param string $product_sku buy_type=2时产品SKU
* @param int $number buy_type=2时购买数量
* @param int $is_choose_default_coupon 是否选择默认的最大可选优惠券
* @param int $my_coupon_id 我的优惠券ID
* @param int $type 下单类型 1--商城 2--秒杀商城
* @param int $spike_product_id type=2时秒杀产品ID
* @date 2022-10-13
*/
public function getOrderReady($buy_type, $my_address_id, $product_id, $product_sku, $number, $is_choose_default_coupon, $my_coupon_id, $type, $spike_product_id)
{
$address_model = new UserAddress();
$config_model = new MallConfig();
$coupon_my_model = new DiscountCouponMy();
$freight_logic = new Freight();
$order_service = new \app\mall\service\Order();
$my_coupon_service = new MyCoupon();
// 获取我的地址 如果前台传了地址ID则获取选中地址否则获取默认地址
if (!empty($my_address_id)) {
// 获取指定地址
$my_address = $address_model->getAddress($my_address_id);
} else {
// 获取默认地址
$my_address = $address_model->getDefaultAddress();
}
// 获取购买的商品
$order_product = $order_service->getOrderProduct($buy_type, $product_id, $product_sku, $number, $type, $spike_product_id);
if (empty($order_product)) {
return sendErrorArray(3001, '无有效商品');
}
// 商品总价钱
$total_price = 0;
// 运费
$freight = 0;
foreach ($order_product as $k => $v) {
// 总价钱 = 总价钱 + 产品价钱 * 数量
$total_price += $v['product_price'] * $v['number'];
// 如果有地址,计算运费
if (!empty($my_address)) {
// 运费类型 1--统一运费 2--运费模板
if ($v['freight_type'] == 2) {
$freight += $freight_logic->getFreight($v['freight_id'], $v['weight'], $v['number'], $v['product_price'],
isset($my_address['province_id']) ? $my_address['province_id'] : '',
isset($my_address['city_id']) ? $my_address['city_id'] : '',
isset($my_address['area_id']) ? $my_address['area_id'] : '');
} else {
$freight += $v['freight_money'] * $v['number'];
}
}
unset($order_product[$k]['product_stock']);
unset($order_product[$k]['freight_type']);
unset($order_product[$k]['freight_id']);
unset($order_product[$k]['freight_money']);
unset($order_product[$k]['weight']);
}
// 是否满足整单免运费满足运费置0
$free_freight_limit = $config_model->getField('free_freight_limit');
if ($total_price >= $free_freight_limit) {
$freight = 0;
}
// 优惠券抵用价钱
$my_coupon_price = 0;
// 定义选中优惠券信息
$choose_my_coupon = [];
// 可以使用的优惠券数量
$result = $my_coupon_service->listChooseCoupon($total_price);
$can_choose_coupon_number = count($result['data']['able_list']);
// 如果有选中优惠券
if (!empty($my_coupon_id)) {
$choose_my_coupon = $coupon_my_model->getOneData([
['id', '=', $my_coupon_id]
], 'id,user_id,price,limit_price,name');
// 价钱根据情况显示整数或1位小数
if ($choose_my_coupon['price'] == round($choose_my_coupon['price'])) {
$choose_my_coupon['price'] = (string)round($choose_my_coupon['price']);
}
$my_coupon_price = $choose_my_coupon['price'];
// 没有选中优惠券时,默认选取最大面值优惠券
} else if (!$my_coupon_id && $is_choose_default_coupon == 1) {
if (!empty($result['data']['able_list'])) {
$choose_my_coupon_first = $result['data']['able_list'][0];
$choose_my_coupon = [
'id' => $choose_my_coupon_first['id'],
'user_id' => $choose_my_coupon_first['user_id'],
'price' => $choose_my_coupon_first['price'],
'limit_price' => $choose_my_coupon_first['limit_price'],
'name' => $choose_my_coupon_first['name']
];
$my_coupon_price = $choose_my_coupon_first['price'];
}
}
// 支付价钱
$pay_money = ($total_price - (double)$my_coupon_price >= 0 ? $total_price - (double)$my_coupon_price : 0) + $freight;
$r_data = [
// 选中优惠券
'choose_my_coupon' => $choose_my_coupon,
// 可使用优惠券数量
'can_choose_coupon_number' => $can_choose_coupon_number,
// 选中地址
'my_address' => $my_address,
// 购买产品
'order_product' => $order_product,
// 总价钱
'total_price' => $total_price,
// 运费
'freight' => $freight,
// 实际付款
'pay_money' => round($pay_money, 2)
];
return sendSuccessArray($r_data);
}
/**
* 获取下单数据(通过产品 地址 优惠券 整合各类价钱)
* @param int $buy_type 购买类型 1--购物车 2--立即购买
* @param int $my_address_id 我的地址ID
* @param int $product_id buy_type=2时产品ID
* @param string $product_sku buy_type=2时产品SKU
* @param int $number buy_type=2时购买数量
* @param int $my_coupon_id 我的优惠券ID
* @param int $type 下单类型 1--商城 2--秒杀商城
* @param int $spike_product_id type=2时秒杀产品ID
* @param int $pay_type 支付方式 0--不用支付 1--微信支付 2--支付宝支付 3--余额支付
* @param string $remark 备注
* @date 2022-10-21
*/
public function insertOrder($buy_type, $my_address_id, $product_id, $product_sku, $number, $my_coupon_id, $type, $spike_product_id, $pay_type, $remark)
{
$order_model = new MallOrder();
$order_product_model = new MallOrderProduct();
$cart_model = new MallCart();
$address_model = new UserAddress();
$product_model = new MallProduct();
$freight_logic = new Freight();
$config_model = new MallConfig();
$coupon_my_model = new DiscountCouponMy();
$snow_flake_class = new Snowflake();
$order_coupon_model = new MallOrderCoupon();
$order_service = new \app\mall\service\Order();
// 获取指定地址
$my_address = $address_model->getAddress($my_address_id);
// 获取购买的商品
$order_product = $order_service->getOrderProduct($buy_type, $product_id, $product_sku, $number, $type, $spike_product_id);
if (empty($order_product)) {
return sendErrorArray(3001, '无有效商品');
}
// 商品总价钱
$total_price = 0;
// 总数量
$total_number = 0;
// 运费
$freight = 0;
foreach ($order_product as $k => $v) {
if ($v['number'] > $v['product_stock']) {
return sendErrorArray(3002, $v['product_name'] . '商品' . $v['product_sku_name'] . '库存不足');
}
// 商品快照
$product_snapshot = $product_model->getOneData([
['id', '=', $v['product_id']]
])->toArray();
$order_product_data[] = [
'id' => $snow_flake_class->id(),
'uid' => $this->mid,
'spike_product_id' => isset($v['spike_product_id']) ? $v['spike_product_id'] : '',
'product_id' => $v['product_id'],
'product_name' => $v['product_name'],
'product_cover_img' => $v['product_cover_img'],
'is_product_spec_open' => $v['is_product_spec_open'],
'product_sku' => $v['product_sku'],
'product_sku_name' => $v['product_sku_name'],
'product_price' => $v['product_price'],
'number' => $v['number'],
'total_price' => $v['number'] * $v['product_price'],
'product_snapshot' => serialize($product_snapshot)
];
// 总价钱 = 总价钱 + 产品价钱 * 数量
$total_price += $v['product_price'] * $v['number'];
// 总数量 = 总数量 + 数量
$total_number += $v['number'];
// 如果有地址,计算运费
if (!empty($my_address)) {
// 运费类型 1--统一运费 2--运费模板
if ($v['freight_type'] == 2) {
$freight += $freight_logic->getFreight($v['freight_id'], $v['weight'], $v['number'], $v['product_price'],
$my_address['province_id'], $my_address['city_id'], $my_address['area_id']);
} else {
$freight += $v['freight_money'] * $v['number'];
}
}
}
// 是否满足整单免运费满足运费置0
$free_freight_limit = $config_model->getField('free_freight_limit');
if ($total_price >= $free_freight_limit) {
$freight = 0;
}
//生成订单数据
$data = [
'uid' => $this->mid,
'user_agent' => $this->userAgent,
'user_id' => $this->userId,
'type' => $type,
'order_number' => $order_model->createOrderNumber('M'),
// 如果是三方支付,需要下面一行存储请求三方单号
// 'fubei_order_number' => $order_model->createOrderNumber('FM'),
'remark' => $remark,
'total_number' => $total_number,
'total_price' => $total_price,
'freight' => $freight,
'pay_type' => $pay_type,
'linkman' => $my_address['linkman'],
'mobile_phone' => $my_address['mobile_phone'],
'province' => $my_address['province'],
'city' => $my_address['city'],
'area' => $my_address['area'],
'address' => $my_address['address'],
'is_pay' => 0,
'status' => 1
];
// 优惠券抵用价钱
$my_coupon_price = 0;
// 优惠券
$my_coupon = [];
// 如果有选中优惠券
if (!empty($my_coupon_id)) {
// 优惠券信息
$my_coupon = $coupon_my_model->getOneData([
['id', '=', $my_coupon_id]
], 'id,user_id,price,limit_price,name,status,is_forever,end_time')->toArray();
$my_coupon_price = $my_coupon['price'];
if ($my_coupon['limit_price'] > $total_price) {
return sendErrorArray(3003, '优惠券不符合使用要求');
}
if ($my_coupon['status'] != 1) {
return sendErrorArray(3004, '该优惠券已使用');
}
if ($my_coupon['is_forever'] == 0 && $my_coupon['end_time'] <= time()) {
return sendErrorArray(3005, '您选择的优惠券已过期');
}
}
// 优惠券抵扣金额
$data['coupon_money'] = $my_coupon_price;
// 实际支付金额 = (产品总价 - 优惠券抵扣金额) + 运费
$data['pay_money'] = ($total_price - $my_coupon_price >= 0 ? $total_price - $my_coupon_price : 0) + $freight;
// 特殊情况支付金额小于0时修改为0
if ($data['pay_money'] < 0) {
$data['pay_money'] = 0;
}
Db::startTrans();
// 存入订单总表
$order_id = $order_model->dataUpdate($data);
if (!$order_id) {
Db::rollback();
return sendErrorArray(3006, '生成总订单失败');
}
// 批量存入订单商品表
foreach ($order_product_data as $k => $v) {
$order_product_data[$k]['order_id'] = $order_id;
$order_product_data[$k]['create_time'] = time();
$order_product_data[$k]['update_time'] = time();
}
$res = $order_product_model->insertAll($order_product_data);
if (!$res) {
Db::rollback();
return sendErrorArray(3007, '生成订单商品失败');
}
// 存入订单优惠券关联表
if (!empty($my_coupon)) {
$order_coupon_data[] = [
'id' => $snow_flake_class->id(),
'uid' => $this->mid,
'order_id' => $order_id,
'coupon_my_id' => $my_coupon['id'],
'coupon_money' => $my_coupon['price'],
'create_time' => time(),
'update_time' => time()
];
$res = $order_coupon_model->insertAll($order_coupon_data);
if (!$res) {
Db::rollback();
return sendErrorArray(3008, '生成订单优惠券失败');
}
// 将优惠券改为已使用
$where = [
['id', '=', $my_coupon_id]
];
$res = $coupon_my_model
->update([
'status' => 2,
'use_time' => time()
], $where);
if (!$res !== false) {
Db::rollback();
return sendErrorArray(3009, '优惠券状态更改失败');
}
}
// 购物车方式清空购物车
if ($buy_type == 1) {
$res = $cart_model->deleteChooseCart($this->userId);
if (!$res) {
Db::rollback();
return sendErrorArray(3010, '清空购物车失败');
}
}
// 下单减少库存
foreach ($order_product as $k => $v) {
$res = $order_service->productStockChange($v['product_id'], -$v['number'], $v['product_sku'], $type, $spike_product_id);
if ($res['code'] != 0) {
Db::rollback();
return $res;
}
}
Db::commit();
// 订单支付金额为0即不用支付
if ($data['pay_money'] == 0) {
$res = $order_service->afterOrderPaySuccess($order_id);
if ($res['code'] != 0) {
return $res;
}
return sendSuccessArray([
// 是否需要支付
'need_pay' => 0
]);
}
// 调起支付
$res = $order_service->createPayOrder($order_id);
if ($res['code'] != 0) {
return $res;
}
return $res;
}
/**
* 获取订单数量
* @date 2022-12-28
*/
public function countOrderNumber()
{
$order_model = new MallOrder();
$where1 = [
['uid', '=', $this->mid],
['user_id', '=', $this->userId],
['is_user_delete', '=', 0],
['status', '=', 1]
];
$where2 = [
['uid', '=', $this->mid],
['user_id', '=', $this->userId],
['is_user_delete', '=', 0],
['status', '=', 2]
];
$where3 = [
['uid', '=', $this->mid],
['user_id', '=', $this->userId],
['is_user_delete', '=', 0],
['status', '=', 3]
];
$where4 = [
['uid', '=', $this->mid],
['user_id', '=', $this->userId],
['is_user_delete', '=', 0],
['status', '=', 4]
];
$number['wait_pay'] = $order_model->getNumber($where1);
$number['wait_deliver'] = $order_model->getNumber($where2);
$number['wait_finish'] = $order_model->getNumber($where3);
$number['wait_evaluate'] = $order_model->getNumber($where4);
return sendSuccessArray([
// 数量
'number' => $number
]);
}
/**
* 订单再支付
* @param int $order_id 订单ID
* @param int $pay_type 支付方式 1--微信支付 2--支付宝支付 3--余额支付
* @date 2022-10-21
*/
public function rePayOrder($order_id, $pay_type)
{
$order_model = new MallOrder();
$order_service = new \app\mall\service\Order();
#TODO 秒杀订单判断秒杀时间
// 生成订单数据
$data_update = [
'id' => $order_id,
'pay_type' => $pay_type
];
$order = $order_model->getOneData([
['id', '=', $order_id]
], 'id,user_agent,status,order_number');
// 非待支付状态
if ($order['status'] != 1) {
return sendErrorArray(3001, '订单状态不支持支付');
}
// 查询单号是否支付
if ($pay_type == 1) {
$wxpay_param = get_wxpay_config_with_weixin($order['user_agent']);
$wxpay_class = new \tencent\wechat\pay\Wxpay($wxpay_param);
// 查询订单
$result = $wxpay_class->queryByOutTradeNumber($order['order_number']);
if ($result['return_code'] === 'SUCCESS' && $result['result_code'] === 'SUCCESS') {
if ($result['trade_state'] == 'SUCCESS') {
return sendErrorArray(3002, '订单已支付');
}
}
}
Db::startTrans();
// 存入订单总表
$order_id = $order_model->dataUpdate($data_update);
if (!$order_id) {
Db::rollback();
return sendErrorArray(3003, '生成总订单失败');
}
Db::commit();
// 调起支付
$res = $order_service->createPayOrder($order_id);
if ($res['code'] != 0) {
return $res;
}
return $res;
}
/**
* 订单取消
* @param int $order_id 订单ID
* @param int $user_id 操作用户ID
* @param int $type 操作类型 1--用户操作 2--后台操作 3--定时
* @date 2022-10-31
*/
public function cancelOrder($order_id, $user_id = '', $type = 1)
{
$order_model = new MallOrder();
$order_product_model = new MallOrderProduct();
$coupon_my_model = new DiscountCouponMy();
$order_coupon_model = new MallOrderCoupon();
$order_service = new \app\mall\service\Order();
// 获取订单信息
$order = $order_model->getOneData([
['id', '=', $order_id]
], 'id,user_id,type,status');
// 订单不存在
if (empty($order)) {
return sendErrorArray(3001, '订单不存在');
}
// 用户取消验证是否是本人取消
if ($type == 1 && $order['user_id'] != $user_id) {
return sendErrorArray(3002, '非本人操作');
}
// 订单状态是否支持取消
if ($order['status'] != 1) {
return sendErrorArray(3003, '订单状态已改变,请刷新页面');
}
Db::startTrans();
// 更改订单状态
$data_update = [
'id' => $order_id,
'status' => 8,
'cancel_time' => time()
];
$res = $order_model->dataUpdate($data_update);
if (!$res) {
Db::rollback();
return sendErrorArray(3004, '取消失败');
}
// 订单产品依次增加库存
$order_product = $order_product_model->getAllData([
['order_id', '=', $order_id]
], 'id,product_id,product_sku,number,spike_product_id');
foreach ($order_product as $k => $v) {
// 产品增加库存
$res = $order_service->productStockChange($v['product_id'], $v['number'], $v['product_sku'], $order['type'], $v['spike_product_id']);
if ($res['code'] != 0) {
Db::rollback();
return $res;
}
}
// 下单如果有优惠券将优惠券改为未使用
$order_coupon_id = $order_coupon_model->where([
['order_id', '=', $order['id']]
])->column('coupon_my_id');
if (!empty($order_coupon_id)) {
$where = [
['id', 'in', $order_coupon_id],
];
$res = $coupon_my_model->where($where)->update([
'status' => 1,
'use_time' => '',
'update_time' => time()
]);
if (!$res) {
Db::rollback();
return sendErrorArray(3005, '优惠券状态更改失败');
}
}
Db::commit();
return sendSuccessArray();
}
/**
* 我的订单列表
* @param int $last_id 列表的最后一条数据ID
* @param int $index 订单状态 0--所有 1--待支付 2--待发货 3--待收货 4--待评价
* @param string $keyword 订单关键字
* @date 2022-09-28
*/
public function listMyOrder($last_id = '', $index = 0, $keyword = '')
{
$order_model = new MallOrder();
$where = [
['user_id', '=', $this->userId],
// 用户未删除
['is_user_delete', '=', 0]
];
// 在最后一条数据ID之前的订单
if (!empty($last_id)) {
$where[] = ['mall_order.id', '<', $last_id];
}
// index 0--所有 1--待支付 2--待发货 3--待收货 4--待评价
if (!empty($index)) {
$where[] = ['status', '=', $index];
}
// 关联订单产品表查询条件
$where_order_product = [];
if (!empty($keyword)) {
$where_order_product[] = ['product_name', 'like', '%' . $keyword . '%'];
}
$filed = 'id,order_number,status,total_number,pay_money,is_evaluate_add,create_time';
$data_list = $order_model->listMyOrderByLastId($where, $where_order_product, $filed);
return sendSuccessArray([
'list' => $data_list
]);
}
/**
* 获取我的订单详情
* @param int $order_id 订单ID
* @date 2022-09-28
*/
public function getMyOrderDetail($order_id)
{
$order_model = new MallOrder();
$config_model = new MallConfig();
$refund_model = new MallOrderRefund();
$where = [
['uid', '=', $this->mid],
['user_id', '=', $this->userId],
// 用户未删除
['is_user_delete', '=', 0],
['id', '=', $order_id]
];
$field = 'id,order_number,status,pay_type,total_price,freight,coupon_money,pay_money,remark,create_time,pay_time,express_time,confirm_time,cancel_time,is_evaluate_add,linkman,mobile_phone,province,city,area,address';
// 获取我的订单详情
$order = $order_model->getMyOrder($where, $field);
// 订单不存在
if (empty($order)) {
return sendErrorArray(3001, '订单不存在');
}
// 未付款状态下,获取自动取消订单倒计时
$order['cancel_rest_second'] = 0;
if ($order['status'] == 1) {
// 获取商城配置-X分钟自动取消订单
$order_cancel_minute = $config_model->getOneData([
['uid', '=', $this->mid]
], 'order_cancel_minute');
// 剩余X秒自动取消订单
$order['cancel_rest_second'] = strtotime($order['create_time']) + $order_cancel_minute * 60 - time();
}
// 订单产品退款详情
foreach ($order['mallOrderProduct'] as $k => &$v) {
// 是否有退款记录
$refund_number = $refund_model->getNumber([
['user_id', '=', $order['user_id']],
['id', '=', $order['id']],
['order_product_id', '=', $v['id']]
]);
// 是否有退款记录
$v['is_has_refund'] = empty($refund_number) ? 0 : 1;
// 已退款数量 = 该产品下单总数量,文案显示已退款
if ($v['refund_total_number'] == $v['number']) {
$v['refund_status'] = 3;
$v['refund_status_text'] = '已退款';
// 退款中数量 > 0文案显示退款中
} else if ($v['refund_cur_number'] > 0) {
$v['refund_status'] = 2;
$v['refund_status_text'] = '退款中';
// 其他,显示退款
} else {
$v['refund_status'] = 1;
$v['refund_status_text'] = '退款';
}
}
return sendSuccessArray([
'data' => $order
]);
}
/**
* 订单删除
* @param int $order_id 订单ID
* @param int $user_id 操作用户ID
* @param integer $type 操作类型 1--用户操作 2--后台操作
* @date 2021-03-01
*/
public function orderDel($order_id, $user_id = '', $type = 1)
{
$order_model = new MallOrder();
//获取订单信息
$order = $order_model->getOneData([
['id', '=', $order_id]
]);
if (empty($order)) {
return sendErrorArray(3001, '订单不存在');
}
if ($type == 1 && $order['user_id'] != $user_id) {
return sendErrorArray(3002, '非本人操作');
}
if (!($order['status'] == 8 || $order['status'] == 7 || $order['status'] == 5 || $order['status'] == 4)) {
return sendErrorArray(3003, '订单状态不支持删除');
}
//更改订单状态
$data_update = [
'is_user_delete' => 1,
'user_delete_time' => time()
];
$res = $order_model->dataUpdate($data_update, [
['id', '=', $order_id]
]);
if (!$res) {
return sendErrorArray(3004, '删除失败');
}
return sendSuccessArray();
}
/**
* 订单再次购买
* @param int $order_id 订单ID
* @param int $user_id 操作用户ID
* @param integer $type 操作类型 1--用户操作 2--后台操作
* @date 2021-03-01
*/
public function orderReBuy($order_id, $user_id = '', $type = 1)
{
$order_model = new MallOrder();
$cart_model = new MallCart();
$product_logic = new \app\mall\logic\Product();
// 获取订单信息
$order = $order_model->getMyOrder([
['id', '=', $order_id]
]);
if (empty($order)) {
return sendErrorArray(3001, '订单不存在');
}
if ($type == 1 && $order['user_id'] != $user_id) {
return sendErrorArray(3002, '非本人操作');
}
if ($order['status'] != 8) {
return sendErrorArray(3003, '订单状态不支持再次购买');
}
//获取商品详情
foreach ($order['mallOrderProduct'] as $k => $v) {
//判断库存是否足够mallOrderProduct
$cart_number = $cart_model->getOneData([
['user_id', '=', $order['user_id']],
['product_id', '=', $v['product_id']],
['product_sku', '=', $v['product_sku']],
], 'number');
$cart_number = $cart_number ?? 0;
$number = $v['number'] + $cart_number;//购物车本身的数量+新增数量
$res = $product_logic->isStockEnough($v['product_id'], $v['product_sku'], $number);
if ($res['code'] != 0) {
continue;
// return $res;
}
//加入购物车
$data = [
'uid' => $order['uid'],
'user_agent' => $this->userAgent,
'user_id' => $order['user_id'],
'product_id' => $v['product_id'],
'is_product_spec_open' => $v['is_product_spec_open'],
'product_sku' => $v['product_sku'],
'number' => $v['number'],
'is_select' => 1
];
$res = $cart_model->updateCart($data);
if (!$res) {
return sendErrorArray(4001, '更新购物车失败');
}
}
return sendSuccessArray();
}
/**
* 订单提醒发货
* @param int $order_id 订单ID
* @param int $user_id 操作用户ID
* @date 2021-03-01
*/
public function orderRemind($order_id, $user_id = '')
{
$order_model = new MallOrder();
$cart_model = new MallCart();
$product_logic = new \app\mall\logic\Product();
//获取订单信息
$order = $order_model->getOneData([
['id', '=', $order_id]
]);
if (empty($order)) {
return sendErrorArray(3001, '订单不存在');
}
if ($order['user_id'] != $user_id) {
return sendErrorArray(3002, '非本人操作');
}
if ($order['status'] != 2) {
return sendErrorArray(3003, '订单状态不支持提醒发货');
}
//更改订单状态
$data_update = [
'remind_time' => time()
];
$res = $order_model->dataUpdate($data_update, [
['id', '=', $order_id]
]);
if (!$res) {
return sendErrorArray(3004, '提醒发货失败');
}
return sendSuccessArray();
}
/**
* 订单确认发货
* @param int $order_id 订单ID
* @param int $user_id 操作用户ID
* @param integer $type 1--用户操作 2--后台操作 3--定时操作
* @date 2021-03-01
*/
public function orderFinish($order_id, $user_id = '', $type = 1)
{
$order_model = new MallOrder();
$info_model = new UserInfo();
$income_model = new DistributionCommissionIncome();
$commission_service = new \app\distribution\service\Commission();
//获取订单信息
$order = $order_model->getOneData([
['id', '=', $order_id]
]);
if (empty($order)) {
return sendErrorArray(3001, '订单不存在');
}
if ($order['user_id'] != $user_id) {
return sendErrorArray(3002, '非本人操作');
}
if ($order['status'] != 3) {
return sendErrorArray(3003, '订单状态不支持确认收货');
}
//更改订单状态
$data_update = [
'status' => 4,
'confirm_time' => time()
];
$res = $order_model->dataUpdate($data_update, [
['id', '=', $order_id]
]);
if (!$res) {
return sendErrorArray(3004, '确认收货失败');
}
//更改佣金记录表为已入账
$where = [
['remark', '=', serialize([
'mall_order_id' => $order['id']
])]
];
$income_data = $income_model->getOneData($where);
if (!empty($income_data)) {
$res = $income_model->where($where)->save([
'status' => 2
]);
if (!$res) {
return sendErrorArray(3005, '更新佣金记录失败');
}
//获取用户昵称
$nickname = $info_model->getOneData([
['user_id', '=', $order['user_id']]
], 'nick_name');
//记录佣金明细表并更新总佣金
//获取佣金
$income = $income_model->getAllData($where);
foreach ($income as $k => $v) {
$res = $commission_service->change($v['distributor_user_id'], 2, $v['commission'], $nickname . '带来的佣金', $order['order_number'], [
'mall_order_id' => $order['id']
]);
if (!$res) {
return sendErrorArray(3006, '更新佣金失败');
}
}
}
return sendSuccessArray();
}
/**
* 订单评价
* @param int $order_id 订单ID
* @param array $order_product 订单产品带评价数据数组
* @param int $user_id 操作用户ID
* @date 2021-03-01
*/
public function orderEvaluate($order_id, $order_product, $user_id = '')
{
$order_model = new MallOrder();
$evaluate_model = new MallEvaluate();
$snow_flake_class = new Snowflake();
//获取订单信息
$order = $order_model->getOneData([
['id', '=', $order_id]
], 'uid,user_id,status');
if (empty($order)) {
return sendErrorArray(3001, '订单不存在');
}
if ($order['user_id'] != $user_id) {
return sendErrorArray(3002, '非本人操作');
}
if ($order['status'] != 4) {
return sendErrorArray(3003, '订单状态不支持评论');
}
//存入评价表
$star_rank = ['1' => 1, '2' => 1, '3' => 2, '4' => 3, '5' => 3];
$evaluate_data = [];
foreach ($order_product as $k => $v) {
$evaluate_data[] = [
'id' => $snow_flake_class->id(),
'uid' => $order['uid'],
'user_agent' => $this->userAgent,
'user_id' => $order['user_id'],
'order_id' => $order_id,
'order_product_id' => $v['id'],
'product_id' => $v['product_id'],
'product_name' => $v['product_name'],
'product_cover_img' => $v['product_cover_img'],
'product_price' => $v['product_price'],
'is_product_spec_open' => $v['is_product_spec_open'],
'product_sku' => $v['product_sku'],
'product_sku_name' => strtr($v['product_sku_name'], ' ', ','),
'star' => $v['star'],
'star_rank' => $star_rank[$v['star']],
'content' => $v['content'],
'has_video' => empty($v['video_path']) ? 1 : 2,
'video_path' => serialize($v['video_path']),
// 'video_cover_img' => $v['video_cover_img'],
'has_img' => empty($v['img_path']) ? 1 : 2,
'img_path' => serialize($v['img_path']),
'create_time' => time(),
'update_time' => time(),
];
}
$res = $evaluate_model->insertAll($evaluate_data);
if (!$res) {
return sendErrorArray(3004, '存入评论失败');
}
//更改订单状态
$data_update = [
'status' => 5,
'evaluate_time' => time()
];
$res = $order_model->dataUpdate($data_update, [
['id', '=', $order_id]
]);
if (!$res) {
return sendErrorArray(3005, '评论失败');
}
return sendSuccessArray();
}
/**
* 订单追加评价
* @param int $order_id 订单ID
* @param array $order_product 订单产品带评价数据数组
* @param int $user_id 操作用户ID
* @date 2021-03-01
*/
public function orderEvaluateAdd($order_id, $order_product, $user_id = '')
{
$order_model = new MallOrder();
$evaluate_model = new MallEvaluate();
$snow_flake_class = new Snowflake();
//获取订单信息
$order = $order_model->getOneData([
['id', '=', $order_id]
]);
if (empty($order)) {
return sendErrorArray(3001, '订单不存在');
}
if ($order['user_id'] != $user_id) {
return sendErrorArray(3002, '非本人操作');
}
if ($order['status'] != 5) {
return sendErrorArray(3003, '订单状态不支持评论');
}
//获取评论信息
$evaluate = $evaluate_model->getOneData([
['evaluate_id', '=', 0],
['order_id', '=', $order_id]
]);
if (empty($evaluate)) {
return sendErrorArray(3001, '订单初评不存在');
}
//存入评价表
$evaluate_data = [];
foreach ($order_product as $k => $v) {
// $video = [];
// foreach($v['video_path'] as $k1=>$v1){
// $result = getVideoScreenshot($v1);
// $video[$k1]['video_path'] = $v1;
// $video[$k1]['video_cover_img'] = $result['url'];
// }
$evaluate_data[] = [
'id' => $snow_flake_class->id(),
'uid' => $order['uid'],
'user_agent' => $this->userAgent,
'user_id' => $order['user_id'],
'evaluate_id' => $evaluate['id'],
'order_id' => $order_id,
'order_product_id' => $v['id'],
'product_id' => $v['product_id'],
'product_name' => $v['product_name'],
'product_cover_img' => $v['product_cover_img'],
'product_price' => $v['product_price'],
'is_product_spec_open' => $v['is_product_spec_open'],
'product_sku' => $v['product_sku'],
'product_sku_name' => strtr($v['product_sku_name'], ' ', ','),
'content' => $v['content'],
'has_video' => empty($v['video_path']) ? 1 : 2,
'video_path' => serialize($v['video_path']),
'has_img' => empty($v['img_path']) ? 1 : 2,
'img_path' => serialize($v['img_path']),
'create_time' => time(),
'update_time' => time(),
];
}
$res = $evaluate_model->insertAll($evaluate_data);
if (!$res) {
return sendErrorArray(3004, '存入评论失败');
}
//修改评论表
$evaluate_data_update = [
'id' => $evaluate['id'],
'is_add' => 1
];
$res = $evaluate_model->dataUpdate($evaluate_data_update);
if (!$res) {
return sendErrorArray(3005, '追加评论失败');
}
//更改订单状态
$data_update = [
'is_evaluate_add' => 1,
'evaluate_time' => time()
];
$res = $order_model->dataUpdate($data_update, [
['id', '=', $order_id]
]);
if (!$res) {
return sendErrorArray(3006, '追加评论失败');
}
return sendSuccessArray();
}
/*
* 订单退款
* @param int $order_product_id order_product主键ID
* @param int $number 退款数量
* @param int $refund_id 退款原因主键ID
* @param array $refund_images 退款原因图片
* @param string $remark 退款备注
* @date 2021-06-01
*/
public function orderRefund($order_product_id, $number, $refund_id, $refund_images, $remark)
{
$order_model = new MallOrder();
$order_product_model = new MallOrderProduct();
$refund_model = new MallOrderRefund();
$cause_model = new MallRefundCause();
//获取退款金额
$res = $this->getOrderRefundMoney($order_product_id, $number);
if ($res['code'] != 0) {
return $res;
}
$refund_money = $res['data']['refund_money'];
$order = $res['data']['order'];
//获取退款原因
$cause = $cause_model->getOneData(['id' => $refund_id]);
if (empty($cause)) {
return sendErrorArray(4001, '退款原因不存在');
}
//存入退款表
$refund_data = [
'uid' => $this->mid,
'user_agent' => $this->userAgent,
'user_id' => $order['user_id'],
'order_number' => $refund_model->createOrderNumber('MR'),
'order_id' => $order['id'],
'order_product_id' => $order_product_id,
'refund_money' => $refund_money,
'refund_number' => $number,
'refund_type' => $order['pay_type'],
'cause_id' => $cause['id'],
'cause_content' => $cause['content'],
'cause_img' => $refund_images,
'remark' => $remark,
'status' => 1
];
$res = $refund_model->dataUpdate($refund_data);
if (!$res) {
return sendErrorArray(4002, '存入退款表失败');
}
//更新订单产品表数量
$update_data = [
'id' => $order_product_id,
'refund_cur_number' => Db::raw('refund_cur_number + ' . $number) // 退款中数量增加
];
$res = $order_product_model->dataUpdate($update_data);
if (!$res) {
return sendErrorArray(4003, '更新订单产品表失败');
}
//更新订单状态
//获取已退总数量
$total_refund_number = $refund_model->getSum('refund_number', [
['order_id', '=', $order['id']],
['status', 'in', [1, 2]] //待审核和已退款状态
]);
if ($total_refund_number == $order['total_number']) {
$order_update_data = [
'id' => $order['id'],
'status' => 6
];
$res = $order_model->dataUpdate($order_update_data);
if (!$res) {
return sendErrorArray(4003, '更新订单表失败');
}
}
return sendSuccessArray();
}
/*
* 订单退款被拒绝
* @param int $order_refund_id order_refund主键ID
* @param string $refuse_text 拒绝原因
* @date 2021-06-01
*/
public function orderRefundFail($order_refund_id, $refuse_text = '')
{
$refund_model = new MallOrderRefund();
$order_model = new MallOrder();
$order_product_model = new MallOrderProduct();
//查找退款数据
$where = [
['uid', '=', $this->mid],
['id', '=', $order_refund_id],
];
$refund = $refund_model->getOneData($where);
if ($refund['status'] != 1) {
return sendErrorArray(3001, '审核状态发生变化,请刷新重试');
}
//退款订单数据变更
$update_data = [
'id' => $order_refund_id,
'status' => 3,
'refuse_text' => $refuse_text
];
$res = $refund_model->dataUpdate($update_data);
if (!$res) {
return sendErrorArray(3002, '修改退款状态失败');
}
//修改订单商品退款中数量
$order_product_updata_data = [
'id' => $refund['order_product_id'],
'refund_cur_number' => Db::raw('refund_cur_number - ' . $refund['refund_number'])
];
$res = $order_product_model->dataUpdate($order_product_updata_data);
if (!$res) {
return sendErrorArray(3003, '修改订单产品表失败');
}
//更新订单状态为退款前状态
//获取已退总数量
$total_refund_number = $refund_model->getSum('refund_number', [
['order_id', '=', $refund['order_id']],
['status', 'in', [1, 2]] //待审核和已退款状态
]);
$order = $order_model->getOneData([
['id', '=', $refund['order_id']]
], 'total_number,express_time');
if ($total_refund_number < $order['total_number']) { //没有全部退款
$order_update_data = [
'id' => $refund['order_id'],
'status' => empty($order['express_time']) ? 2 : 3 //没有发货时间更改为2--待发货 否则更改为3--待收货
];
$res = $order_model->dataUpdate($order_update_data);
if (!$res) {
return sendErrorArray(3004, '更新订单表失败');
}
}
return sendSuccessArray();
}
/*
* 订单退款审核通过
* @param int $order_refund_id order_refund主键ID
* @date 2021-06-01
*/
public function orderRefundSuccess($order_refund_id)
{
$refund_model = new MallOrderRefund();
$order_model = new MallOrder();
$order_product_model = new MallOrderProduct();
$coupon_my_model = new DiscountCouponMy();
$order_coupon_model = new MallOrderCoupon();
$order_service = new \app\mall\service\Order();
//查找退款数据
$where = [
['uid', '=', $this->mid],
['id', '=', $order_refund_id],
];
$refund = $refund_model->getOneData($where);
if ($refund['status'] != 1) {
return sendErrorArray(3001, '审核状态发生变化,请刷新重试');
}
//退款订单数据变更
$update_data = [
'id' => $order_refund_id,
'status' => 2, // 已退款
];
$res = $refund_model->dataUpdate($update_data);
if (!$res) {
return sendErrorArray(3002, '修改退款状态失败');
}
//修改订单商品退款中和退款总数量
$order_product_updata_data = [
'id' => $refund['order_product_id'],
'refund_cur_number' => Db::raw('refund_cur_number - ' . $refund['refund_number']),
'refund_total_number' => Db::raw('refund_total_number + ' . $refund['refund_number']),
];
$res = $order_product_model->dataUpdate($order_product_updata_data);
if (!$res) {
return sendErrorArray(3003, '修改订单产品表失败');
}
$total_refund_number = $refund_model->getSum('refund_number', [
['order_id', '=', $refund['order_id']],
['status', 'in', [2]] //已退款状态
]);
$order = $order_model->getOneData([
['id', '=', $refund['order_id']]
], 'uid,user_agent,user_id,order_number,type,pay_type,total_number,pay_money');
if ($total_refund_number == $order['total_number']) { //全部产品退款
//更改订单表为已退款
$order_update_data = [
'id' => $refund['order_id'],
'status' => 7
];
$res = $order_model->dataUpdate($order_update_data);
if (!$res) {
return sendErrorArray(3004, '更新订单表失败');
}
//优惠券退回
$order_coupon_id = $order_coupon_model->where([
['order_id', '=', $order['id']]
])->column('coupon_my_id');
if (!empty($order_coupon_id)) {
$where = [
['id', 'in', $order_coupon_id],
];
#TODO 修改寫法為saveALl 自動更新update_time
$res = $coupon_my_model->where($where)->update([
'status' => 1,
'use_time' => '',
'update_time' => time()
]);
if (!$res) {
return sendErrorArray(3005, '优惠券状态更改失败');
}
}
}
//产品库存退回
$order_product = $order_product_model->getOneData([
['id', '=', $refund['order_product_id']]
]);//获取订单产品数据
$res = $order_service->productStockChange($order_product['product_id'], $refund['refund_number'], $order_product['product_sku'], $order['type'], $order_product['spike_product_id']);
if ($res['code'] != 0) {
return $res;
}
//产品销量减少(该版本为付款成功加销量)
$res = $order_service->productSalesChange($order_product['product_id'], -$refund['refund_number'], $order['type'], $order_product['spike_product_id']);
if ($res['code'] != 0) {
return $res;
}
//退款
switch ($order['pay_type']) {
// 微信退款
case 1:
$wxpay_param = get_wxpay_config_with_weixin($order['user_agent']);
$wxpay_class = new \tencent\wechat\pay\Wxpay($wxpay_param);
//退款
$result = $wxpay_class->refund($order['order_number'], $refund['order_number'], $order['pay_money'], $refund['refund_money']);
//记录日志
platformLog([
'order_number' => $order['order_number'],
'refund_order_number' => $refund['order_number'],
'pay_money' => $order['pay_money'],
'refund_money' => $refund['refund_money']
], $result, 'easywechat_wxpay_refund_' . $this->mid);
if ($result['return_code'] != 'SUCCESS' || $result['result_code'] != 'SUCCESS') {
return sendErrorArray(3006, $result['return_msg'] != 'OK' ? $result['return_msg'] : $result['err_code_des']);
}
//返回状态码和业务结果均为成功,退款成功修改退款表状态
$update_data = [
'id' => $order_refund_id,
'is_arrival' => 1,
'arrival_time' => time(),
'transaction_id' => $result['transaction_id']
];
$res = $refund_model->dataUpdate($update_data);
// 统计系统 - 新增交易流水(退款)
$statistics_class = new \jucheng\tongji\Statistics();
$result = $statistics_class->updateTurnoverMoney(-$refund['refund_money']);
// 统计系统 - 新增订单信息(退款)
$statistics_class = new \jucheng\tongji\Statistics();
$result = $statistics_class->updateOrderInfo(-$refund['refund_money'], 0);
break;
// 支付宝退款
case 2:
switch ($order['user_agent']) {
// APP项目
case 'app':
$ali_pay_param = get_app_alipay_config();
break;
// 小程序项目
case 'mp_alipay':
$ali_pay_param = get_mp_alipay_config();
break;
// H5项目
case 'h5':
$ali_pay_param = get_h5_alipay_config();
break;
// 其他
default:
$ali_pay_param = [];
break;
}
$ali_pay_class = new \ali\alipay\pay\AliPay($ali_pay_param);
//退款
$result = $ali_pay_class->refund($order['order_number'], $refund['order_number'], $refund['refund_money']);
if ($result['code'] !== '10000') {
return sendErrorArray($result['code'], $result['sub_msg']);
}
//退款成功修改退款表状态
$update_data = [
'id' => $order_refund_id,
'is_arrival' => 1,
'arrival_time' => time(),
'transaction_id' => $result['trade_no']
];
$res = $refund_model->dataUpdate($update_data);
// 统计系统 - 新增交易流水(退款)
$statistics_class = new \jucheng\tongji\Statistics();
$result = $statistics_class->updateTurnoverMoney(-$refund['refund_money']);
// 统计系统 - 新增订单信息(退款)
$statistics_class = new \jucheng\tongji\Statistics();
$result = $statistics_class->updateOrderInfo(-$refund['refund_money'], 0);
break;
case 3://余额退款
$money_service = new \app\money\service\Money();
//退款
$result = $money_service->change($order['user_id'], 5, $refund['refund_money'], "退款-商城订单", $order['order_number'], [
'mall_order_refund_id' => $order_refund_id
]);
if ($result['code'] == 0) {
$update_data = [
'id' => $order_refund_id,
'is_arrival' => 1,
'arrival_time' => time()
];
$res = $refund_model->dataUpdate($update_data);
if (!$res) {
return sendErrorArray(3008, '余额到账失败');
}
}
break;
default:
break;
}
return sendSuccessArray();
}
/*
* 订单退款取消
* @param int $refund_id 订单退款表ID
* @date 2021-06-01
*/
public function orderRefundCancel($refund_id)
{
$order_model = new MallOrder();
$order_product_model = new MallOrderProduct();
$refund_model = new MallOrderRefund();
//获取退款数据
$refund = $refund_model->getOneData([
['id', '=', $refund_id]
]);
//获取订单产品数据
$order_product = $order_product_model->getOneData([
['id', '=', $refund['order_product_id']]
]);
//获取订单数据
$order = $order_model->getOneData([
['id', '=', $refund['order_id']]
]);
// 存入退款表
$refund_data = [
'id' => $refund['id'],
'cancel_time' => time(),
'status' => 4
];
$res = $refund_model->dataUpdate($refund_data);
if (!$res) {
return sendErrorArray(4002, '更新退款表失败');
}
// 更新订单产品表数量
$update_data = [
'id' => $refund['order_product_id'],
'refund_status' => ($order_product['refund_cur_number'] - $refund['refund_number'] == 0) ? 1 : 2,
'refund_cur_number' => Db::raw('refund_cur_number - ' . $refund['refund_number'])
];
$res = $order_product_model->dataUpdate($update_data);
if (!$res) {
return sendErrorArray(4003, '更新订单产品表失败');
}
$order_update_data = [
'id' => $refund['order_id'],
'status' => empty($order['express_time']) ? 2 : 3
];
$res = $order_model->dataUpdate($order_update_data);
if (!$res) {
return sendErrorArray(4004, '更新订单表失败');
}
return sendSuccessArray();
}
/*
* 获取订单退款金额
* @param int $order_product_id 订单产品表ID
* @param int $number 退款数量
* @date 2021-06-01
*/
public function getOrderRefundMoney($order_product_id, $number = 1)
{
$order_model = new MallOrder();
$order_product_model = new MallOrderProduct();
$refund_model = new MallOrderRefund();
$order_product = $order_product_model->getOneData([
['id', '=', $order_product_id]
]);
if (empty($order_product)) {
return sendErrorArray(3001, '订单不存在');
}
if ($number > $order_product['number'] - $order_product['refund_total_number'] - $order_product['refund_cur_number']) {
return sendErrorArray(3002, '申请退款数量不能多于购买数量');
}
$order = $order_model->getOneData(['id' => $order_product['order_id']]);
if (!$order) {
return sendErrorArray(3003, '订单不存在');
}
$total_number = $order_product_model->getOneData(['order_id' => $order['id']], 'SUM(number - refund_total_number - refund_cur_number) as actual_number');
if (empty($order['pay_money'])) {
$refund_money = 0;
} else {
if ($total_number == $number) { //退最后1个
// 获取已退金额
$total_refund_money = $refund_model->getSum('refund_money', [
['order_id', '=', $order['id']],
['status', 'in', [1, 2]]
]);
$refund_money = $order['pay_money'] - $total_refund_money;
} else { //不是退最后1个
$refund_money = round($order_product['product_price'] * $number - $order['coupon_money'] * $order_product['product_price'] * $number / $order['total_price'], 2);
}
}
return sendSuccessArray(['refund_money' => $refund_money, 'order' => $order, 'order_product' => $order_product]);
}
/**
* 订单物流
* @param int $order_id 订单ID
* @date 2022-11-22
*/
public function getLogistics($order_id)
{
$order_model = new MallOrder();
$kdniao_param = get_kdniao_config();
$logistic_class = new Logistics($kdniao_param);
$where = [
['uid', '=', $this->mid],
['user_id', '=', $this->userId],
['is_user_delete', '=', 0],
['id', '=', $order_id]
];
// 查找订单
$field = 'id,order_number,total_number,express_name,express_number,express_code,province,city,area,address';
$order = $order_model->getMyOrder($where,$field);
if (empty($order)) {
return sendErrorArray(3001, '订单不存在');
}
$order = $order->toArray();
foreach ($order['mallOrderProduct'] as $k=>$v){
unset($order['mallOrderProduct'][$k]['is_product_spec_open']);
unset($order['mallOrderProduct'][$k]['product_sku']);
unset($order['mallOrderProduct'][$k]['product_sku_name']);
unset($order['mallOrderProduct'][$k]['refund_total_number']);
unset($order['mallOrderProduct'][$k]['refund_cur_number']);
unset($order['mallOrderProduct'][$k]['total_price']);
}
// 查看物流
$result = $logistic_class->getLogistics($order['express_number'], $order['express_code']);
// 有错误
if ($result['Success'] != 'true') {
// 物流状态
$logistics['logistics_status'] = 0;
// 物流状态显示文本
$logistics['logistics_text'] = $result['Reason'];
// 物流轨迹
$logistics['logistics'] = [
[
'accept_date' => '',
'accept_time' => '',
'content' => '该订单编号暂时无法获取物流轨迹'
]
];
} else {
// 物流状态
$logistics['logistics_status'] = $result['State'];
// 物流状态显示文本
$logistics['logistics_text'] = $result['logistics_text'];
// 物流轨迹
$result['Traces'] = array_reverse($result['Traces']);
foreach ($result['Traces'] as $k => $v) {
$logistics['logistics'][$k]['accept_date'] = date('Y-m-d', strtotime($v['AcceptTime']));
$logistics['logistics'][$k]['accept_time'] = date('H:i:s', strtotime($v['AcceptTime']));
$logistics['logistics'][$k]['content'] = $v['AcceptStation'];
}
}
return sendSuccessArray([
// 订单信息
'order' => $order,
// 物流信息
'logistics' => $logistics
]);
}
}