diff --git a/app/common/dao/store/order/StoreOrderOtherDao.php b/app/common/dao/store/order/StoreOrderOtherDao.php new file mode 100644 index 00000000..c0dec4a6 --- /dev/null +++ b/app/common/dao/store/order/StoreOrderOtherDao.php @@ -0,0 +1,764 @@ + +// +---------------------------------------------------------------------- + + +namespace app\common\dao\store\order; + + +use app\common\dao\BaseDao; +use app\common\model\store\order\StoreOtherGroupOrder; +use app\common\model\store\order\StoreOrderOther; +use app\common\model\store\order\StoreOrderProductOther; +use app\common\model\store\order\StoreOrderStatusOther; +use app\common\repositories\store\order\StoreOrderStatusRepository; +use app\common\repositories\store\product\ProductAssistSetRepository; +use app\common\repositories\store\product\ProductGroupBuyingRepository; + +use think\db\BaseQuery; +use think\db\exception\DataNotFoundException; +use think\db\exception\DbException; +use think\db\exception\ModelNotFoundException; +use think\facade\Db; +use think\Model; + +/** + * Class StoreOrderDao + * @package app\common\dao\store\order + * @author xaboy + * @day 2020/6/8 + */ +class StoreOrderOtherDao extends BaseDao +{ + //订单状态(0:待发货;1:待收货;2:待评价;3:已完成; 9: 拼团中 10: 待付尾款 11:尾款超时未付 -1:已退款) + const ORDER_STATUS_BE_SHIPPED = 0; + const ORDER_STATUS_BE_RECEIVE = 1; + const ORDER_STATUS_REPLY = 2; + const ORDER_STATUS_SUCCESS = 3; + const ORDER_STATUS_SPELL = 9; + const ORDER_STATUS_TAIL = 10; + const ORDER_STATUS_TAIL_FAIL = 11; + const ORDER_STATUS_REFUND = -1; + + + /** + * @return string + * @author xaboy + * @day 2020/6/8 + */ + protected function getModel(): string + { + return StoreOrderOther::class; + } + + /** + * @param array $where + * @param int $sysDel + * @return BaseQuery + * @author xaboyCRMEB + * @day 2020/6/16 + */ + public function search(array $where, $sysDel = 0) + { + $query = StoreOrderOther::hasWhere('merchant', function ($query) use ($where) { + if (isset($where['is_trader']) && $where['is_trader'] !== '') { + $query->where('is_trader', $where['is_trader']); + } + $query->where('is_del', 0); + }); + + $query->when(($sysDel !== null), function ($query) use ($sysDel) { + $query->where('is_system_del', $sysDel); + }) + ->when(isset($where['order_type']) && $where['order_type'] >= 0 && $where['order_type'] !== '', function ($query) use ($where) { + if ($where['order_type'] == 2) { + $query->where('is_virtual', 1); + } else if ($where['order_type'] == 0) { //实体发货订单 + $query->where('order_type', 0)->where('is_virtual', 0); + } else if ($where['order_type'] == 3) { //发货订单 + $query->where('order_type', 0); + } else { + $query->where('order_type', $where['order_type']); + } + }) + ->when(isset($where['activity_type']) && $where['activity_type'] != '', function ($query) use ($where) { + $query->where('activity_type', $where['activity_type']); + }) + ->when(isset($where['product_type']) && $where['product_type'] != '', function ($query) use ($where) { + $query->where('activity_type', $where['product_type']); + }) + ->when(isset($where['status']) && $where['status'] !== '', function ($query) use ($where) { + // 12表示信用购 先货后款 + switch ($where['status']) { + case 0: + $query->whereIn('StoreOrderOther.status', [0, 9, 12]); + break; + case -2: + $query->where('StoreOrderOther.paid', 1)->whereNotIn('StoreOrderOther.status', [10, 11]); + break; + case 10: + $query->where('StoreOrderOther.paid', 1)->whereIn('StoreOrderOther.status', [10, 11]); + break; + case 2: + $query->where('StoreOrderOther.paid', 1)->where('StoreOrderOther.status', $where['status'])->where('pay_type', '<>', StoreGroupOrder::PAY_TYPE_CREDIT_BUY); + break; + case 20: + $query->where('StoreOrderOther.paid', 1)->whereIn('StoreOrderOther.status', [2, 3]); + break; + default: + $query->where('StoreOrderOther.status', $where['status']); + break; + } + }) + ->when(isset($where['uid']) && $where['uid'] !== '', function ($query) use ($where) { + $query->where('StoreOrderOther.uid', $where['uid']); + }) + ->when(isset($where['is_user']) && $where['is_user'] !== 0, function ($query) use ($where) { + $query->where(function ($query) { + $query->where('order_type', 0)->whereOr(function ($query) { + $query->where('order_type', 1)->where('main_id', 0); + }); + }); + }) + //待核销订单 + ->when(isset($where['is_verify']) && $where['is_verify'], function ($query) use ($where) { + $query->where('StoreOrderOther.order_type', 1)->where('StoreOrderOther.status', 0); + }) + ->when(isset($where['pay_type']) && $where['pay_type'] !== '', function ($query) use ($where) { + $query->where('StoreOrderOther.pay_type', $where['pay_type']); + }) + ->when(isset($where['order_ids']) && $where['order_ids'] !== '', function ($query) use ($where) { + $query->whereIn('order_id', $where['order_ids']); + }) + ->when(isset($where['order_id']) && $where['order_id'] !== '', function ($query) use ($where) { + if (is_array($where['order_id'])) { + $query->whereIn('order_id', $where['order_id']); + } else { + $query->where('order_id', $where['order_id']); + } + }) + ->when(isset($where['take_order']) && $where['take_order'] != '', function ($query) use ($where) { + $query->where('order_type', 1)->whereNotNull('verify_time'); + }) + ->when(isset($where['mer_id']) && $where['mer_id'] !== '', function ($query) use ($where) { + $query->where('StoreOrderOther.mer_id', $where['mer_id']); + }) + ->when(isset($where['date']) && $where['date'] !== '', function ($query) use ($where) { + getModelTime($query, $where['date'], 'StoreOrderOther.create_time'); + }) + ->when(isset($where['pay_time']) && $where['pay_time'] !== '', function ($query) use ($where) { + getModelTime($query, $where['pay_time'], 'StoreOrderOther.pay_time'); + }) + ->when(isset($where['verify_date']) && $where['verify_date'] !== '', function ($query) use ($where) { + getModelTime($query, $where['verify_date'], 'verify_time'); + }) + ->when(isset($where['order_sn']) && $where['order_sn'] !== '', function ($query) use ($where) { + $query->where('order_sn', 'like', '%' . $where['order_sn'] . '%'); + }) + ->when(isset($where['paid']) && $where['paid'] !== '', function ($query) use ($where) { + $query->where('StoreOrderOther.paid', $where['paid']); + }) + ->when(isset($where['is_del']) && $where['is_del'] !== '', function ($query) use ($where) { + $query->where('StoreOrderOther.is_del', $where['is_del']); + }) + ->when(isset($where['service_id']) && $where['service_id'] !== '', function ($query) use ($where) { + $query->where('service_id', $where['service_id']); + }) + ->when(isset($where['username']) && $where['username'] !== '', function ($query) use ($where) { + $query->join('User U', 'StoreOrderOther.uid = U.uid') + ->where(function ($query) use ($where) { + $query->where('nickname', 'like', "%{$where['username']}%") + ->whereOr('phone', 'like', "%{$where['username']}%") + ->whereOr('user_phone', 'like', "%{$where['username']}%"); + }); + }) + ->when(isset($where['store_name']) && $where['store_name'] !== '', function ($query) use ($where) { + $orderId = StoreOrderProductOther::alias('op') + ->join('storeProduct sp', 'op.product_id = sp.product_id') + ->whereLike('store_name', "%{$where['store_name']}%") + ->when((isset($where['sp.mer_id']) && $where['mer_id'] !== ''), function ($query) use ($where) { + $query->where('mer_id', $where['mer_id']); + })->column('order_id'); + $query->whereIn('order_id', $orderId ?: ''); + }) + ->when(isset($where['search']) && $where['search'] !== '', function ($query) use ($where) { + $orderId = StoreOrderProductOther::alias('op') + ->join('storeProduct sp', 'op.product_id = sp.product_id') + ->whereLike('store_name', "%{$where['search']}%") + ->when((isset($where['sp.mer_id']) && $where['mer_id'] !== ''), function ($query) use ($where) { + $query->where('mer_id', $where['mer_id']); + })->column('order_id'); + $query->where(function ($query) use ($orderId, $where) { + $query->whereIn('order_id', $orderId ? $orderId : '') + ->whereOr('order_sn', 'like', "%{$where['search']}%") + ->whereOr('user_phone', 'like', "%{$where['search']}%"); + }); + }) + ->when(isset($where['order_search']) && $where['order_search'] !== '', function ($query) use ($where) { + $query->where('order_sn', 'like', '%' . $where['order_search'] . '%')->whereOr('user_phone', $where['order_search']); + }) + ->when(isset($where['group_order_sn']) && $where['group_order_sn'] !== '', function ($query) use ($where) { + $query->join('StoreGroupOrder GO', 'StoreOrderOther.group_order_id = GStoreOrderOther.group_order_id')->where('group_order_sn', $where['group_order_sn']); + }) + ->when(isset($where['keywords']) && $where['keywords'] !== '', function ($query) use ($where) { + $query->where(function ($query) use ($where) { + $query->whereLike('StoreOrderOther.real_name|StoreOrderOther.user_phone|order_sn', "%" . $where['keywords'] . "%"); + }); + }) + ->when(isset($where['reconciliation_type']) && $where['reconciliation_type'] !== '', function ($query) use ($where) { + $query->when($where['reconciliation_type'], function ($query) use ($where) { + $query->where('reconciliation_id', '<>', 0); + }, function ($query) use ($where) { + $query->where('reconciliation_id', 0); + }); + })->order('StoreOrderOther.create_time DESC'); + + return $query; + } + + + /** + * @param $id + * @param $uid + * @return array|Model|null + * @throws DataNotFoundException + * @throws DbException + * @throws ModelNotFoundException + * @author xaboy + * @day 2020/6/11 + */ + public function userOrder($id, $uid) + { + return StoreOrderOther::getDB()->where('order_id', $id)->where('uid', $uid)->where('is_del', 0)->where('paid', 1)->where('is_system_del', 0)->find(); + } + + /** + * @param array $where + * @param $ids + * @return BaseQuery + * @author xaboy + * @day 2020/6/26 + */ + public function usersOrderQuery(array $where, $ids, $uid) + { + return StoreOrderOther::getDB()->where(function ($query) use ($uid, $ids) { + $query->whereIn('uid', $ids)->whereOr(function ($query) use ($uid) { + if ($uid) { + $query->where('uid', $uid)->where('is_selfbuy', 1); + } + }); + })->when(isset($where['date']) && $where['date'] !== '', function ($query) use ($where) { + getModelTime($query, $where['date'], 'pay_time'); + })->when(isset($where['keyword']) && $where['keyword'] !== '', function ($query) use ($where) { + $query->whereLike('order_id|order_sn', "%{$where['keyword']}%"); + })->where('paid', 1)->order('pay_time DESC'); + } + + /** + * @param $field + * @param $value + * @param int|null $except + * @return bool + * @author xaboy + * @day 2020/6/11 + */ + public function fieldExists($field, $value, ?int $except = null): bool + { + return ($this->getModel()::getDB())->when($except, function ($query) use ($field, $except) { + $query->where($field, '<>', $except); + })->where($field, $value)->count() > 0; + } + + /** + * @param $id + * @return mixed + * @author xaboy + * @day 2020/6/12 + */ + public function getMerId($id) + { + return StoreOrderOther::getDB()->where('order_id', $id)->value('mer_id'); + } + + /** + * @param array $where + * @return bool + * @author Qinii + * @day 2020-06-12 + */ + public function merFieldExists(array $where) + { + return ($this->getModel()::getDB())->where($where)->count() > 0; + } + + /** + * TODO + * @param $reconciliation_id + * @return mixed + * @author Qinii + * @day 2020-06-15 + */ + public function reconciliationUpdate($reconciliation_id) + { + return ($this->getModel()::getDB())->whereIn('reconciliation_id', $reconciliation_id)->update(['reconciliation_id' => 0]); + } + + public function dayOrderNum($day, $merId = null) + { + return StoreOrderOther::getDB()->where('paid', 1)->when($merId, function ($query, $merId) { + $query->where('mer_id', $merId); + })->when($day, function ($query, $day) { + getModelTime($query, $day, 'pay_time'); + })->count(); + } + + public function dayOrderPrice($day, $merId = null) + { + return getModelTime(StoreOrderOther::getDB()->where('paid', 1)->when($merId, function ($query, $merId) { + $query->where('mer_id', $merId); + }), $day, 'pay_time')->sum('pay_price'); + } + + public function dateOrderPrice($date, $merId = null) + { + return StoreOrderOther::getDB()->where('paid', 1)->when($merId, function ($query, $merId) { + $query->where('mer_id', $merId); + })->when($date, function ($query, $date) { + getModelTime($query, $date, 'pay_time'); + })->sum('pay_price'); + } + + public function dateOrderNum($date, $merId = null) + { + return StoreOrderOther::getDB()->where('paid', 1)->when($merId, function ($query, $merId) { + $query->where('mer_id', $merId); + })->when($date, function ($query, $date) { + getModelTime($query, $date, 'pay_time'); + })->count(); + } + + public function dayOrderUserNum($day, $merId = null) + { + return StoreOrderOther::getDB()->where('paid', 1)->when($merId, function ($query, $merId) { + $query->where('mer_id', $merId); + })->when($day, function ($query, $day) { + getModelTime($query, $day, 'pay_time'); + })->group('uid')->count(); + } + + public function orderUserNum($date, $paid = null, $merId = null) + { + return StoreOrderOther::getDB()->when($paid, function ($query, $paid) { + $query->where('paid', $paid); + })->when($merId, function ($query, $merId) { + $query->where('mer_id', $merId); + })->when($date, function ($query, $date) use ($paid) { + if (!$paid) { + getModelTime($query, $date); + // $query->where(function ($query) use ($date) { + // $query->where(function ($query) use ($date) { + // $query->where('paid', 1); + // getModelTime($query, $date, 'pay_time'); + // })->whereOr(function ($query) use ($date) { + // $query->where('paid', 0); + // getModelTime($query, $date); + // }); + // }); + } else + getModelTime($query, $date, 'pay_time'); + })->group('uid')->count(); + } + + public function orderUserGroup($date, $paid = null, $merId = null) + { + return StoreOrderOther::getDB()->when($paid, function ($query, $paid) { + $query->where('paid', $paid); + })->when($merId, function ($query, $merId) { + $query->where('mer_id', $merId); + })->when($date, function ($query, $date) { + getModelTime($query, $date, 'pay_time'); + })->group('uid')->field(Db::raw('uid,sum(pay_price) as pay_price,count(order_id) as total'))->select(); + } + + public function oldUserNum(array $ids, $merId = null) + { + return StoreOrderOther::getDB()->when($merId, function ($query, $merId) { + $query->where('mer_id', $merId); + })->whereIn('uid', $ids)->where('paid', 1)->group('uid')->count(); + } + + public function oldUserIds(array $ids, $merId = null) + { + return StoreOrderOther::getDB()->when($merId, function ($query, $merId) { + $query->where('mer_id', $merId); + })->whereIn('uid', $ids)->where('paid', 1)->group('uid')->column('uid'); + } + + public function orderPrice($date, $paid = null, $merId = null) + { + return StoreOrderOther::getDB()->when($paid, function ($query, $paid) { + $query->where('paid', $paid); + })->when($merId, function ($query, $merId) { + $query->where('mer_id', $merId); + })->when($date, function ($query, $date) use ($paid) { + if (!$paid) { + $query->where(function ($query) use ($date) { + $query->where(function ($query) use ($date) { + $query->where('paid', 1); + getModelTime($query, $date, 'pay_time'); + })->whereOr(function ($query) use ($date) { + $query->where('paid', 0); + getModelTime($query, $date); + }); + }); + } else + getModelTime($query, $date, 'pay_time'); + })->sum('pay_price'); + } + + public function orderGroupNum($date, $merId = null) + { + $field = Db::raw('sum(pay_price) as pay_price,count(*) as total,count(distinct uid) as user,pay_time,from_unixtime(unix_timestamp(pay_time),\'%m-%d\') as `day`'); + if ($date == 'year') { + $field = Db::raw('sum(pay_price) as pay_price,count(*) as total,count(distinct uid) as user,pay_time,from_unixtime(unix_timestamp(pay_time),\'%m\') as `day`'); + } + $query = StoreOrderOther::getDB()->field($field) + ->where('paid', 1)->when($date, function ($query, $date) { + getModelTime($query, $date, 'pay_time'); + })->when($merId, function ($query, $merId) { + $query->where('mer_id', $merId); + }); + return $query->order('pay_time ASC')->group('day')->select(); + } + + public function orderGroupNumPage($where, $page, $limit, $merId = null) + { + return StoreOrderOther::getDB()->when(isset($where['dateRange']), function ($query) use ($where) { + getModelTime($query, date('Y/m/d 00:00:00', $where['dateRange']['start']) . '-' . date('Y/m/d 00:00:00', $where['dateRange']['stop']), 'pay_time'); + })->field( + Db::raw('status,sum(pay_price) as pay_price,count(*) as total,count(distinct uid) as user,pay_time,from_unixtime(unix_timestamp(pay_time),\'%m-%d\') as `day`') + ) + ->where('paid', 1)->when($merId, function ($query, $merId) { + $query->where('mer_id', $merId); + })->order('pay_time DESC')->page($page, $limit)->group('day')->select()->each(function ($item) use ($merId) { + $pay_time = explode(' ', $item['pay_time']); + $item->settlement_price = Db::name('store_order') + ->whereIn('status', [2, 3]) + ->where('mer_id', $merId) + ->whereDay('pay_time', $pay_time[0]) + ->sum('pay_price'); + }); + } + + public function dayOrderPriceGroup($date, $merId = null) + { + return StoreOrderOther::getDB()->field(Db::raw('sum(pay_price) as price, from_unixtime(unix_timestamp(pay_time),\'%H:%i\') as time')) + ->where('paid', 1)->when($date, function ($query, $date) { + getModelTime($query, $date, 'pay_time'); + })->when($merId, function ($query, $merId) { + $query->where('mer_id', $merId); + })->group('time')->select(); + } + + public function dayOrderNumGroup($date, $merId = null) + { + return StoreOrderOther::getDB()->field(Db::raw('count(*) as total, from_unixtime(unix_timestamp(pay_time),\'%H:%i\') as time')) + ->where('paid', 1)->when($date, function ($query, $date) { + getModelTime($query, $date, 'pay_time'); + })->when($merId, function ($query, $merId) { + $query->where('mer_id', $merId); + })->group('time')->select(); + } + + public function dayOrderUserGroup($date, $merId = null) + { + return StoreOrderOther::getDB()->field(Db::raw('count(DISTINCT uid) as total, from_unixtime(unix_timestamp(pay_time),\'%H:%i\') as time')) + ->where('paid', 1)->when($date, function ($query, $date) { + getModelTime($query, $date, 'pay_time'); + })->when($merId, function ($query, $merId) { + $query->where('mer_id', $merId); + })->group('time')->select(); + } + + /** + * 获取当前时间到指定时间的支付金额 管理员 + * @param string $start 开始时间 + * @param string $stop 结束时间 + * @return mixed + */ + public function chartTimePrice($start, $stop, $merId = null) + { + return StoreOrderOther::getDB()->where('paid', 1) + ->where('pay_time', '>=', $start) + ->where('pay_time', '<', $stop) + ->when($merId, function ($query, $merId) { + $query->where('mer_id', $merId); + }) + ->field('sum(pay_price) as num,FROM_UNIXTIME(unix_timestamp(pay_time), \'%Y-%m-%d\') as time') + ->group('time') + ->order('pay_time ASC')->select()->toArray(); + } + + /** + * @param $date + * @param null $merId + * @return mixed + */ + public function chartTimeNum($date, $merId = null) + { + return StoreOrderOther::getDB()->where('paid', 1)->when($date, function ($query) use ($date) { + getModelTime($query, $date, 'pay_time'); + })->when($merId, function ($query, $merId) { + $query->where('mer_id', $merId); + })->field('count(order_id) as num,FROM_UNIXTIME(unix_timestamp(pay_time), \'%Y-%m-%d\') as time') + ->group('time') + ->order('pay_time ASC')->select()->toArray(); + } + + /** + * @param $end + * @return mixed + * @author xaboy + * @day 2020/9/16 + */ + public function getFinishTimeoutIds($end) + { + return StoreOrderStatusOther::getDB()->alias('A')->leftJoin('StoreOrderOther B', 'A.order_id = B.order_id') + ->where('A.change_type', 'take') + ->where('A.change_time', '<', $end)->where('B.paid', 1)->where('B.status', 2)->where('B.pay_type', '<>', StoreGroupOrder::PAY_TYPE_CREDIT_BUY) + ->column('A.order_id'); + } + + + /** + * TODO 参与人数 + * @param array $data + * @param int|null $uid + * @return BaseQuery + * @author Qinii + * @day 2020-11-11 + */ + public function getTattendCount(array $data, ?int $uid) + { + $query = StoreOrderOther::hasWhere('orderProduct', function ($query) use ($data, $uid) { + $query->when(isset($data['activity_id']), function ($query) use ($data) { + $query->where('activity_id', $data['activity_id']); + }) + ->when(isset($data['product_sku']), function ($query) use ($data) { + $query->where('product_sku', $data['product_sku']); + }) + ->when(isset($data['product_id']), function ($query) use ($data) { + $query->where('product_id', $data['product_id']); + }) + ->when(isset($data['exsits_id']), function ($query) use ($data) { + switch ($data['product_type']) { + case 3: + $make = app()->make(ProductAssistSetRepository::class); + $id = 'product_assist_id'; + break; + case 4: + $make = app()->make(ProductGroupBuyingRepository::class); + $id = 'product_group_id'; + break; + } + $where = [$id => $data['exsits_id']]; + $activity_id = $make->getSearch($where)->column($make->getPk()); + if ($activity_id) { + $id = array_unique($activity_id); + $query->where('activity_id', 'in', $id); + } else { + $query->where('activity_id', '<', 0); + } + }) + ->where('product_type', $data['product_type']); + if ($uid) $query->where('uid', $uid); + }); + $query->where('activity_type', $data['product_type']); + switch ($data['product_type']) { + case 0: + $query->where(function ($query) { + $query->where(function ($query) { + $query->where('paid', 1); + })->whereOr(function ($query) { + $query->where('paid', 0)->where('is_del', 0); + }); + }); + break; + case 1: //秒杀 + $query->where(function ($query) { + $query->where(function ($query) { + $query->where('paid', 1); + })->whereOr(function ($query) { + $query->where('paid', 0)->where('is_del', 0); + }); + })->when(isset($data['day']), function ($query) use ($data) { + $query->whereDay('StoreOrderOther.create_time', $data['day']); + }); + break; + case 2: //预售 + + /** + * 第一阶段参与人数:所有人 + * 第二阶段参与人数:支付了第一阶段 + */ + //第二阶段 + if ($data['type'] == 1) { + $query->where(function ($query) { + $query->where('paid', 1)->whereOr(function ($query) { + $query->where('paid', 0)->where('is_del', 0); + }); + }); + } + if ($data['type'] == 2) $query->where('paid', 1)->where('status', 'in', [0, 1, 2, 3, -1]); + break; + case 3: //助力 + $query->where(function ($query) { + $query->where('paid', 1)->whereOr(function ($query) { + $query->where('paid', 0)->where('is_del', 0); + }); + }); + break; + case 4: // + $query->where(function ($query) { + $query->where('paid', 1)->whereOr(function ($query) { + $query->where('paid', 0)->where('is_del', 0); + }) + ->where('status', '>', -1); + }); + break; + } + return $query; + } + + /** + * 未使用 + * TODO 成功支付人数 + * @param int $productType + * @param int $activityId + * @param int|null $uid + * @param int|null $status + * @author Qinii + * @day 2020-10-30 + */ + public function getTattendSuccessCount($data, ?int $uid) + { + $query = StoreOrderOther::hasWhere('orderProduct', function ($query) use ($data, $uid) { + $query->when(isset($data['activity_id']), function ($query) use ($data) { + $query->where('activity_id', $data['activity_id']); + }) + ->when(isset($data['product_sku']), function ($query) use ($data) { + $query->where('product_sku', $data['product_sku']); + }) + ->when(isset($data['product_id']), function ($query) use ($data) { + $query->where('product_id', $data['product_id']); + }) + ->when(isset($data['exsits_id']), function ($query) use ($data) { + switch ($data['product_type']) { + case 3: + $make = app()->make(ProductAssistSetRepository::class); + $id = 'product_assist_id'; + break; + case 4: + $make = app()->make(ProductGroupBuyingRepository::class); + $id = 'product_group_id'; + break; + } + $where = [$id => $data['exsits_id']]; + $activity_id = $make->getSearch($where)->column($make->getPk()); + if ($activity_id) { + $id = array_unique($activity_id); + $query->where('activity_id', 'in', $id); + } else { + $query->where('activity_id', '<', 0); + } + }) + ->where('product_type', $data['product_type']); + if ($uid) $query->where('uid', $uid); + }); + $query->where('activity_type', $data['product_type'])->where('paid', 1); + + switch ($data['product_type']) { + case 1: //秒杀 + $query->where(function ($query) { + $query->where(function ($query) { + $query->where('paid', 1); + }); + })->when(isset($data['day']), function ($query) use ($data) { + $query->whereDay('StoreOrderOther.create_time', $data['day']); + }); + break; + case 2: //预售 + if ($data['type'] == 1) { //第一阶段 + $query->where('status', 'in', [0, 1, 2, 3, 10]); + } else { //第二阶段 + $query->where('status', 'in', [0, 1, 2, 3]); + } + break; + case 3: //助力 + break; + case 4: + break; + } + return $query; + } + + + /** + * TODO 获取退款单数量 + * @param $where + * @return mixed + * @author Qinii + * @day 1/4/21 + */ + public function getSeckillRefundCount($where, $type = 1) + { + $query = StoreOrderProductOther::getDB()->alias('P')->join('StoreRefundOrder R', 'P.order_id = R.order_id'); + $query->join('StoreOrder O', 'StoreOrderOther.order_id = P.order_id'); + $query + ->when(isset($where['activity_id']), function ($query) use ($where) { + $query->where('P.activity_id', $where['activity_id']); + }) + ->when(isset($where['product_sku']), function ($query) use ($where) { + $query->where('P.product_sku', $where['product_sku']); + }) + ->when(isset($where['day']), function ($query) use ($where) { + $query->whereDay('P.create_time', $where['day']); + }) + ->when($type == 1, function ($query) use ($where) { + $query->where('StoreOrderOther.verify_time', null)->where('StoreOrderOther.delivery_type', null); + }, function ($query) { + $query->where('R.refund_type', 2); + }) + ->where('P.product_type', 1)->where('R.status', 3); + return $query->count(); + } + + + /** + * TODO 用户的某个商品购买数量 + * @param int $uid + * @param int $productId + * @return int + * @author Qinii + * @day 2022/9/26 + */ + public function getMaxCountNumber(int $uid, int $productId) + { + return StoreOrderOther::hasWhere('orderProduct', function ($query) use ($productId) { + $query->where('product_id', $productId); + }) + ->where(function ($query) { + $query->where('is_del', 0)->whereOr(function ($query) { + $query->where('is_del', 1)->where('paid', 1); + }); + })->where('StoreOrderOther.uid', $uid)->count(); + } +} diff --git a/app/common/model/store/order/StoreGroupOrderOther.php b/app/common/model/store/order/StoreGroupOrderOther.php new file mode 100644 index 00000000..2455f572 --- /dev/null +++ b/app/common/model/store/order/StoreGroupOrderOther.php @@ -0,0 +1,122 @@ + +// +---------------------------------------------------------------------- + + +namespace app\common\model\store\order; + + +use app\common\model\BaseModel; +use app\common\model\user\User; +use app\common\repositories\store\coupon\StoreCouponRepository; + +class StoreGroupOrderOther extends BaseModel +{ + + const PAY_TYPE_BALANCE = 0; //余额支付 + const PAY_TYPE_WECHAT = 1; //微信支付 + const PAY_TYPE_ROUTINE = 2; //小程序支付 + const PAY_TYPE_H5 = 3; //H5支付 + const PAY_TYPE_CREDIT_BUY = 8; //信用购 先货后款 + const ON_LINE_PRODUCT = 9; //线上铺货 + const ENTITY_PRODUCT = 10; //实体铺货 + const ON_CREDIT_PRODUCT = 11; //赊账进货 + + public static function tablePk(): ?string + { + return 'group_order_id'; + } + + public static function tableName(): string + { + return 'store_group_order_other'; + } + + public function orderList() + { + return $this->hasMany(StoreOrderOther::class, 'group_order_id', 'group_order_id'); + } + + public function user() + { + return $this->hasOne(User::class, 'uid', 'uid'); + } + + public function getGiveCouponAttr() + { + if (count($this->give_coupon_ids)) + return app()->make(StoreCouponRepository::class)->getGiveCoupon($this->give_coupon_ids); + return []; + } + + public function getCancelTimeAttr() + { + $timer = ((int)systemConfig('auto_close_order_timer')) ?: 15; + return date('m-d H:i', strtotime("+ $timer minutes", strtotime($this->create_time))); + } + + public function getCancelUnixAttr() + { + $timer = ((int)systemConfig('auto_close_order_timer')) ?: 15; + return strtotime("+ $timer minutes", strtotime($this->create_time)); + } + + public function getGiveCouponIdsAttr($value) + { + return $value ? explode(',', $value) : []; + } + + public function setGiveCouponIdsAttr($value) + { + return $value ? implode(',', $value) : ''; + } + + public function getCombinePayParams($attach = 'order') + { + $params = [ + 'order_sn' => $this->group_order_sn, + 'sub_orders' => [], + 'attach' => $attach, + 'body' => '订单支付', + ]; + foreach ($this->orderList as $order) { + if ($order->pay_price > 0) { + $subOrder = [ + 'pay_price' => $order->pay_price, + 'order_sn' => $order->order_sn, + 'sub_mchid' => $order->merchant->sub_mchid, + ]; + $params['sub_orders'][] = $subOrder; + } + } + return $params; + } + + public function getPayParams($return_url = '', $attach = 'order') + { + $params = [ + 'order_sn' => $this->group_order_sn, + 'pay_price' => $this->pay_price, + 'attach' => $attach, + 'body' => '订单支付' + ]; + if ($return_url) { + $params['return_url'] = $return_url; + } + return $params; + } + + public function interest() + { + return $this->hasOne(StoreOrderInterest::class, 'group_order_id', 'group_order_id'); + } + +} diff --git a/app/common/model/store/order/StoreOrderInterestOther.php b/app/common/model/store/order/StoreOrderInterestOther.php new file mode 100644 index 00000000..fc858d9b --- /dev/null +++ b/app/common/model/store/order/StoreOrderInterestOther.php @@ -0,0 +1,39 @@ +start_time == '0000-00-00 00:00:00') { + return 0; + } + $days = ceil((time() - strtotime($this->start_time)) / 86400); + $days = max($days ,0); + $money = bcmul($this->total_price, ($this->rate / 100), 3); + return bcmul($days, $money, 2); + } + +} diff --git a/app/common/model/store/order/StoreOrderOther.php b/app/common/model/store/order/StoreOrderOther.php new file mode 100644 index 00000000..14a4d96d --- /dev/null +++ b/app/common/model/store/order/StoreOrderOther.php @@ -0,0 +1,196 @@ + +// +---------------------------------------------------------------------- + + +namespace app\common\model\store\order; + + +use app\common\model\BaseModel; +use app\common\model\community\Community; +use app\common\model\store\product\ProductGroupUser; +use app\common\model\store\service\StoreService; +use app\common\model\store\shipping\Express; +use app\common\model\system\merchant\Merchant; +use app\common\model\user\User; +use app\common\repositories\store\MerchantTakeRepository; + +class StoreOrderOther extends BaseModel +{ + + const STATUS_WAIT_CONFIRM = 12; //待确认 + const STATUS_WAIT_PAY = 0; //待支付 + const STATUS_WAIT_COMMENT = 2; //待评价 + const STATUS_FINISH = 3; //已完成 + + public static function tablePk(): ?string + { + return 'order_id'; + } + + public static function tableName(): string + { + return 'store_order_other'; + } + + public function orderProduct() + { + return $this->hasMany(StoreOrderProductOther::class, 'order_id', 'order_id'); + } + + public function refundProduct() + { + return $this->orderProduct()->where('refund_num', '>', 0); + } + + public function refundOrder() + { + return $this->hasMany(StoreRefundOrder::class,'order_id','order_id'); + } + + public function orderStatus() + { + return $this->hasMany(StoreOrderStatusOther::class,'order_id','order_id')->order('change_time DESC'); + } + + public function merchant() + { + return $this->hasOne(Merchant::class, 'mer_id', 'mer_id'); + } + + public function user() + { + return $this->hasOne(User::class, 'uid', 'uid'); + } + public function receipt() + { + return $this->hasOne(StoreOrderReceipt::class, 'order_id', 'order_id'); + } + + public function spread() + { + return $this->hasOne(User::class, 'uid', 'spread_uid'); + } + + public function TopSpread() + { + return $this->hasOne(User::class, 'uid', 'top_uid'); + } + + public function groupOrder() + { + return $this->hasOne(StoreGroupOrderOther::class, 'group_order_id', 'group_order_id'); + } + + public function verifyService() + { + return $this->hasOne(StoreService::class, 'service_id', 'verify_service_id'); + } + + public function getTakeAttr() + { + return app()->make(MerchantTakeRepository::class)->get($this->mer_id); + } + + public function searchDataAttr($query, $value) + { + return getModelTime($query, $value); + } + + public function presellOrder() + { + return $this->hasOne(PresellOrder::class, 'order_id', 'order_id'); + } + + public function finalOrder() + { + return $this->hasOne(PresellOrder::class,'order_id','order_id'); + } + + public function groupUser() + { + return $this->hasOne(ProductGroupUser::class,'order_id','order_id'); + } + + public function profitsharing() + { + return $this->hasMany(StoreOrderProfitsharing::class, 'order_id', 'order_id'); + } + + public function firstProfitsharing() + { + return $this->hasOne(StoreOrderProfitsharing::class, 'order_id', 'order_id')->where('type', 'order'); + } + + public function presellProfitsharing() + { + return $this->hasOne(StoreOrderProfitsharing::class, 'order_id', 'order_id')->where('type', 'presell'); + } + + // 核销订单的自订单列表 + public function takeOrderList() + { + return $this->hasMany(self::class,'main_id','order_id')->order('verify_time DESC'); + } + + public function searchMerIdAttr($query, $value) + { + return $query->where('mer_id', $value); + } + + public function getRefundStatusAttr() + { + $day = (int)systemConfig('sys_refund_timer') ?: 15; + return ($this->verify_time ? strtotime($this->verify_time) > strtotime('-' . $day . ' day') : true); + } + + public function getOrderExtendAttr($val) + { + return $val ? json_decode($val, true) : null; + } + + public function getRefundExtensionOneAttr() + { + if ( $this->refundOrder ){ + return $this->refundOrder()->where('status',3)->sum('extension_one'); + } + return 0; + } + + public function getRefundExtensionTwoAttr() + { + if ( $this->refundOrder ){ + return $this->refundOrder()->where('status',3)->sum('extension_two'); + } + return 0; + } + + public function community() + { + return $this->hasOne(Community::class, 'order_id', 'order_id')->bind(['community_id']); + } + + public function getRefundPriceAttr() + { + return StoreRefundOrder::where('order_id',$this->order_id)->where('status',3)->sum('refund_price'); + } + + public function interest() + { + return $this->hasOne(StoreOrderInterest::class, 'order_id', 'order_id'); + } + + public function allowCreditPay() + { + return $this->pay_type == StoreGroupOrder::PAY_TYPE_CREDIT_BUY && $this->status == self::STATUS_WAIT_PAY; + } + +} diff --git a/app/common/model/store/order/StoreOrderProductOther.php b/app/common/model/store/order/StoreOrderProductOther.php new file mode 100644 index 00000000..25801bb4 --- /dev/null +++ b/app/common/model/store/order/StoreOrderProductOther.php @@ -0,0 +1,80 @@ + +// +---------------------------------------------------------------------- + + +namespace app\common\model\store\order; + + +use app\common\model\BaseModel; +use app\common\model\store\product\Product; +use app\common\model\store\product\Spu; +use app\common\model\user\User; + +class StoreOrderProductOther extends BaseModel +{ + + public static function tablePk(): ?string + { + return 'order_product_id'; + } + + public static function tableName(): string + { + return 'store_order_product_other'; + } + + public function getCartInfoAttr($value) + { + return json_decode($value, true); + } + + public function orderInfo() + { + return $this->hasOne(StoreOrderOther::class, 'order_id', 'order_id'); + } + + public function user() + { + return $this->hasOne(User::class,'uid','uid'); + } + + public function product() + { + return $this->hasOne(Product::class,'product_id','product_id'); + } + + public function spu() + { + return $this->hasOne(Spu::class,'product_id','product_id'); + } + + public function searchUidAttr($query ,$value) + { + $query->where('uid',$value); + } + public function searchActivitIidAttr($query,$value) + { + $query->where('activity_id',$value); + } + public function searchProductTypeAttr($query,$value) + { + $query->where('product_type',$value); + } + public function searchOrderIdAttr($query,$value) + { + $query->where('order_id',$value); + } + public function searchProductIdAttr($query,$value) + { + $query->where('product_id',$value); + } +} diff --git a/app/common/model/store/order/StoreOrderStatusOther.php b/app/common/model/store/order/StoreOrderStatusOther.php new file mode 100644 index 00000000..65fcea99 --- /dev/null +++ b/app/common/model/store/order/StoreOrderStatusOther.php @@ -0,0 +1,47 @@ + +// +---------------------------------------------------------------------- + + +namespace app\common\model\store\order; + + +use app\common\model\BaseModel; + +/** + * Class StoreOrderStatusOther + * @package app\common\model\store\order + * @author xaboy + * @day 2020/6/12 + */ +class StoreOrderStatusOther extends BaseModel +{ + + /** + * @return string|null + * @author xaboy + * @day 2020/6/12 + */ + public static function tablePk(): ?string + { + return null; + } + + /** + * @return string + * @author xaboy + * @day 2020/6/12 + */ + public static function tableName(): string + { + return 'store_order_status_other'; + } +} diff --git a/app/common/repositories/store/order/StoreOtherOrderRepository.php b/app/common/repositories/store/order/StoreOtherOrderRepository.php new file mode 100644 index 00000000..7e8e0f5e --- /dev/null +++ b/app/common/repositories/store/order/StoreOtherOrderRepository.php @@ -0,0 +1,2120 @@ + +// +---------------------------------------------------------------------- +namespace app\common\repositories\store\order; + +use app\common\dao\store\order\StoreCartDao; +use app\common\dao\store\order\StoreOrderOtherDao; +use app\common\model\store\order\StoreGroupOrderOther; +use app\common\model\store\order\StoreOtherOrder; +use app\common\model\store\order\StoreOrderInterestOther; +use app\common\model\store\order\StoreOtherOrderInterest; +use app\common\model\store\order\StoreRefundOrder; +use app\common\model\store\product\PurchaseRecord; +use app\common\model\user\User; +use app\common\model\system\merchant\Merchant; +use app\common\repositories\BaseRepository; +use app\common\repositories\delivery\DeliveryOrderRepository; +use app\common\repositories\store\coupon\StoreCouponRepository; +use app\common\repositories\store\coupon\StoreCouponUserRepository; +use app\common\repositories\store\product\ProductAssistSetRepository; +use app\common\repositories\store\product\ProductCopyRepository; +use app\common\repositories\store\product\ProductGroupBuyingRepository; +use app\common\repositories\store\product\ProductPresellSkuRepository; +use app\common\repositories\store\product\ProductRepository; +use app\common\repositories\store\product\StoreDiscountRepository; +use app\common\repositories\store\shipping\ExpressRepository; +use app\common\repositories\store\StorePrinterRepository; +use app\common\repositories\store\StoreSeckillActiveRepository; +use app\common\repositories\system\attachment\AttachmentRepository; +use app\common\repositories\system\merchant\FinancialRecordRepository; +use app\common\repositories\system\merchant\MerchantRepository; +use app\common\repositories\system\serve\ServeDumpRepository; +use app\common\repositories\user\UserBillRepository; +use app\common\repositories\user\UserBrokerageRepository; +use app\common\repositories\user\UserMerchantRepository; +use app\common\repositories\user\UserRepository; +use crmeb\jobs\PayGiveCouponJob; +use crmeb\jobs\ProductImportJob; +use crmeb\jobs\SendSmsJob; +use crmeb\jobs\SendGoodsCodeJob; +use crmeb\jobs\UserBrokerageLevelJob; +use crmeb\services\CombinePayService; +use crmeb\services\CrmebServeServices; +use crmeb\services\ExpressService; +use crmeb\services\PayService; +use crmeb\services\payTool\PayTool; +use crmeb\services\printer\Printer; +use crmeb\services\QrcodeService; +use crmeb\services\SpreadsheetExcelService; +use crmeb\services\SwooleTaskService; +use Exception; +use FormBuilder\Factory\Elm; +use FormBuilder\Form; +use think\db\exception\DataNotFoundException; +use think\db\exception\DbException; +use think\db\exception\ModelNotFoundException; +use think\exception\ValidateException; +use think\facade\Db; +use think\facade\Log; +use think\facade\Queue; +use think\facade\Route; +use think\Model; +use app\controller\admin\ProductLibrary; + + +/**其他订单 + * Class StoreOrderRepository + * @package app\common\repositories\store\order + * @author xaboy + * @day 2020/6/9 + * @mixin StoreOrderDao + */ +class StoreOtherOrderRepository extends BaseRepository +{ + /** + * 支付类型 + */ + const PAY_TYPE = ['balance', 'weixin', 'routine', 'h5', 'alipay', 'alipayQr', 'weixinQr', 'scrcu', 'creditBuy']; + + const TYPE_SN_ORDER = 'wxo'; + const TYPE_SN_PRESELL = 'wxp'; + const TYPE_SN_USER_ORDER = 'wxs'; + const TYPE_SN_USER_RECHARGE = 'wxu'; + + const TYPE_SN_REFUND = 'rwx'; + /** + * StoreOrderRepository constructor. + * @param StoreOrderDao $dao + */ + public function __construct(StoreOrderOtherDao $dao) + { + $this->dao = $dao; + } + /** + * @param User $user + * @param StoreGroupOrder $groupOrder + * @return mixed + * @author xaboy + * @day 2020/6/9 + */ + public function payBalance(User $user, StoreGroupOrderOther $groupOrder) + { + if (!systemConfig('yue_pay_status')) + throw new ValidateException('未开启余额支付'); + if ($user['now_money'] < $groupOrder['pay_price']) + throw new ValidateException('余额不足,请更换支付方式'); + Db::startTrans(); + try { + $user->now_money = bcsub($user->now_money, $groupOrder['pay_price'], 2); + $user->save(); + $userBillRepository = app()->make(UserBillRepository::class); + $userBillRepository->decBill($user['uid'], 'now_money', 'pay_product', [ + 'link_id' => $groupOrder['group_order_id'], + 'status' => 1, + 'title' => '购买商品', + 'number' => $groupOrder['pay_price'], + 'mark' => '余额支付支付' . floatval($groupOrder['pay_price']) . '元购买商品', + 'balance' => $user->now_money + ]); + $this->paySuccess($groupOrder); + Db::commit(); + } catch (Exception $e) { + Db::rollback(); + throw new ValidateException('余额支付失败'); + } + + return app('json')->status('success', '余额支付成功', ['order_id' => $groupOrder['group_order_id']]); + } + + public function changePayType(StoreGroupOrderOther $groupOrder, int $pay_type) + { + Db::transaction(function () use ($groupOrder, $pay_type) { + $groupOrder->pay_type = $pay_type; + foreach ($groupOrder->orderList as $order) { + $order->pay_type = $pay_type; + $order->save(); + } + $groupOrder->save(); + }); + } + + /** + * @return string + * @author xaboy + * @day 2020/8/3 + */ + public function verifyCode() + { + $code = substr(uniqid('', true), 15) . substr(microtime(), 2, 8); + if ($this->dao->existsWhere(['verify_code' => $code])) + return $this->verifyCode(); + else + return $code; + } + + /** + * //TODO 支付成功后 + * + * @param StoreGroupOrder $groupOrder + * @author xaboy + * @day 2020/6/9 + */ + public function paySuccess(StoreGroupOrderOther $groupOrder, $is_combine = 0, $subOrders = []) + { + $groupOrder->append(['user']); + //修改订单状态 + Db::transaction(function () use ($subOrders, $is_combine, $groupOrder) { + $time = date('Y-m-d H:i:s'); + $groupOrder->paid = 1; + $groupOrder->pay_time = $time; + $groupOrder->is_combine = $is_combine; + $orderStatus = []; + $groupOrder->append(['orderList.orderProduct']); + $flag = true; + $finance = []; + $profitsharing = []; + $financialRecordRepository = app()->make(FinancialRecordRepository::class); + $financeSn = $financialRecordRepository->getSn(); + $userMerchantRepository = app()->make(UserMerchantRepository::class); + $storeOrderProfitsharingRepository = app()->make(StoreOrderProfitsharingRepository::class); + $uid = $groupOrder->uid; + $i = 1; + $isVipCoupon = app()->make(StoreGroupOrderRepository::class)->isVipCoupon($groupOrder); + //订单记录 + $storeOrderStatusRepository = app()->make(StoreOrderStatusRepository::class); + $svipDiscount = 0; + foreach ($groupOrder->orderList as $_k => $order) { + $order->paid = 1; + $order->pay_time = $time; + $svipDiscount = bcadd($order->svip_discount, $svipDiscount, 2); + if (isset($subOrders[$order->order_sn])) { + $order->transaction_id = $subOrders[$order->order_sn]['transaction_id']; + } + $presell = false; + //todo 等待付尾款 + if ($order->activity_type == 2) { + $_make = app()->make(ProductPresellSkuRepository::class); + if ($order->orderProduct[0]['cart_info']['productPresell']['presell_type'] == 2) { + $order->status = 10; + $presell = true; + } else { + $_make->incCount($order->orderProduct[0]['activity_id'], $order->orderProduct[0]['product_sku'], 'two_pay'); + } + $_make->incCount($order->orderProduct[0]['activity_id'], $order->orderProduct[0]['product_sku'], 'one_pay'); + } else if ($order->activity_type == 4) { + $order->status = 9; + $order->save(); + $group_buying_id = app()->make(ProductGroupBuyingRepository::class)->create( + $groupOrder->user, + $order->orderProduct[0]['cart_info']['activeSku']['product_group_id'], + $order->orderProduct[0]['activity_id'], + $order->order_id + ); + $order->orderProduct[0]->activity_id = $group_buying_id; + $order->orderProduct[0]->save(); + } else if ($order->activity_type == 3) { + //更新助力状态 + app()->make(ProductAssistSetRepository::class)->changStatus($order->orderProduct[0]['activity_id']); + } + + //更新委托订单处理 + if ($order->activity_type == 99) { + $cartIdArray = explode(',', $order->cart_id); + $ecartList = Db::name('store_cart')->whereIn('cart_id', $cartIdArray)->select(); + foreach ($ecartList as $ecart) { + if (!empty($ecart['source_id'])) { + Db::name('community')->where('community_id', $ecart['source_id'])->update(['entrust_order_id' => $order->order_id ?? 0]); + } + } + } + // 订单的类型 0 发货 1 自提 + if ($order->order_type == 1 && $order->status != 10) { + $order->verify_code = $this->verifyCode(); + } + $order->save(); + $orderStatus[] = [ + 'order_id' => $order->order_id, + 'order_sn' => $order->order_sn, + 'type' => $storeOrderStatusRepository::TYPE_ORDER, + 'change_message' => '订单支付成功', + 'change_type' => $storeOrderStatusRepository::ORDER_STATUS_PAY_SUCCCESS, + 'uid' => $order->uid, + 'nickname' => $order->user->nickname, + 'user_type' => $storeOrderStatusRepository::U_TYPE_USER, + ]; + + //TODO 成为推广员 + foreach ($order->orderProduct as $product) { + if ($flag && $product['cart_info']['product']['is_gift_bag']) { + app()->make(UserRepository::class)->promoter($order->uid); + $flag = false; + } + } + if ($order->order_type == 0) { + //发起队列物流信息处理 + //event('order.sendGoodsCode', $order); + Queue::push(SendGoodsCodeJob::class, $order); + } + + // 商户流水账单数据 + $finance[] = [ + 'order_id' => $order->order_id, + 'order_sn' => $order->order_sn, + 'user_info' => $groupOrder->user->nickname, + 'user_id' => $uid, + 'financial_type' => $presell ? 'order_presell' : 'order', + 'financial_pm' => 1, + 'type' => $presell ? 2 : 1, + 'number' => $order->pay_price, + 'mer_id' => $order->mer_id, + 'financial_record_sn' => $financeSn . ($i++) + ]; + + $_payPrice = bcsub($order->pay_price, bcadd($order['extension_one'], $order['extension_two'], 3), 2); + if ($presell) { + if (isset($order->orderProduct[0]['cart_info']['presell_extension_one']) && $order->orderProduct[0]['cart_info']['presell_extension_one'] > 0) { + $_payPrice = bcadd($_payPrice, $order->orderProduct[0]['cart_info']['presell_extension_one'], 2); + } + if (isset($order->orderProduct[0]['cart_info']['presell_extension_two']) && $order->orderProduct[0]['cart_info']['presell_extension_two'] > 0) { + $_payPrice = bcadd($_payPrice, $order->orderProduct[0]['cart_info']['presell_extension_two'], 2); + } + } + + $_order_rate = 0; + + //平台手续费 + if ($order['commission_rate'] > 0) { + + $commission_rate = ($order['commission_rate'] / 100); + + $_order_rate = bcmul($_payPrice, $commission_rate, 2); + + $_payPrice = bcsub($_payPrice, $_order_rate, 2); + // 结算各镇 小组佣金 + event('order.paySuccessOrder', compact('order', '_order_rate')); + } + + if (!$presell) { + if ($order['extension_one'] > 0) { + $finance[] = [ + 'order_id' => $order->order_id, + 'order_sn' => $order->order_sn, + 'user_info' => $groupOrder->user->nickname, + 'user_id' => $uid, + 'financial_type' => 'brokerage_one', + 'financial_pm' => 0, + 'type' => 1, + 'number' => $order['extension_one'], + 'mer_id' => $order->mer_id, + 'financial_record_sn' => $financeSn . ($i++) + ]; + } + + if ($order['extension_two'] > 0) { + $finance[] = [ + 'order_id' => $order->order_id, + 'order_sn' => $order->order_sn, + 'user_info' => $groupOrder->user->nickname, + 'user_id' => $uid, + 'financial_type' => 'brokerage_two', + 'financial_pm' => 0, + 'type' => 1, + 'number' => $order['extension_two'], + 'mer_id' => $order->mer_id, + 'financial_record_sn' => $financeSn . ($i++) + ]; + } + + if ($order['commission_rate'] > 0) { + $finance[] = [ + 'order_id' => $order->order_id, + 'order_sn' => $order->order_sn, + 'user_info' => $groupOrder->user->nickname, + 'user_id' => $uid, + 'financial_type' => 'order_charge', + 'financial_pm' => 0, + 'type' => 1, + 'number' => $_order_rate, + 'mer_id' => $order->mer_id, + 'financial_record_sn' => $financeSn . ($i++) + ]; + } + //押金计算 + if ($_payPrice > 0) { + /** @var MerchantRepository $merchantRepo */ + $merchantRepo = app()->make(MerchantRepository::class); + $merchantRepo->merId = $order->mer_id; + $merchantRepo->forceMargin = false; + [$_payPrice, $finance, $increase] = $merchantRepo->autoMargin($_payPrice, $order, $finance, $financeSn, $i++); + } + $finance[] = [ + 'order_id' => $order->order_id, + 'order_sn' => $order->order_sn, + 'user_info' => $groupOrder->user->nickname, + 'user_id' => $uid, + 'financial_type' => 'order_true', + 'financial_pm' => 0, + 'type' => 2, + 'number' => $_payPrice, + 'mer_id' => $order->mer_id, + 'financial_record_sn' => $financeSn . ($i++) + ]; + + if ($order->platform_coupon_price > 0) { + $finance[] = [ + 'order_id' => $order->order_id, + 'order_sn' => $order->order_sn, + 'user_info' => $groupOrder->user->nickname, + 'user_id' => $uid, + 'financial_type' => $isVipCoupon ? 'order_svip_coupon' : 'order_platform_coupon', + 'financial_pm' => 0, + 'type' => 1, + 'number' => $order->platform_coupon_price, + 'mer_id' => $order->mer_id, + 'financial_record_sn' => $financeSn . ($i++) + ]; + $_payPrice = bcadd($_payPrice, $order->platform_coupon_price, 2); + } + if (!$is_combine) { + app()->make(MerchantRepository::class)->addLockMoney($order->mer_id, 'order', $order->order_id, $_payPrice); + } + } + if ($is_combine) { + $profitsharing[] = [ + 'profitsharing_sn' => $storeOrderProfitsharingRepository->getOrderSn(), + 'order_id' => $order->order_id, + 'transaction_id' => $order->transaction_id ?? '', + 'mer_id' => $order->mer_id, + 'profitsharing_price' => $order->pay_price, + 'profitsharing_mer_price' => $_payPrice, + 'type' => $storeOrderProfitsharingRepository::PROFITSHARING_TYPE_ORDER, + ]; + } + $userMerchantRepository->updatePayTime($uid, $order->mer_id, $order->pay_price); + SwooleTaskService::merchant('notice', [ + 'type' => 'new_order', + 'data' => [ + 'title' => '新订单', + 'message' => '您有一个新的订单', + 'id' => $order->order_id + ] + ], $order->mer_id); + //自动打印订单 + $this->autoPrinter($order->order_id, $order->mer_id); + } + //分销判断 + // if ($groupOrder->user->spread_uid) { + // Queue::push(UserBrokerageLevelJob::class, ['uid' => $groupOrder->user->spread_uid, 'type' => 'spread_pay_num', 'inc' => 1]); + // Queue::push(UserBrokerageLevelJob::class, ['uid' => $groupOrder->user->spread_uid, 'type' => 'spread_money', 'inc' => $groupOrder->pay_price]); + // } + app()->make(UserRepository::class)->update($groupOrder->uid, [ + 'pay_count' => Db::raw('pay_count+' . count($groupOrder->orderList)), + 'pay_price' => Db::raw('pay_price+' . $groupOrder->pay_price), + 'svip_save_money' => Db::raw('svip_save_money+' . $svipDiscount), + ]); + $this->giveIntegral($groupOrder); + if (count($profitsharing)) { + $storeOrderProfitsharingRepository->insertAll($profitsharing); + } + $financialRecordRepository->insertAll($finance); + $storeOrderStatusRepository->batchCreateLog($orderStatus); + if (count($groupOrder['give_coupon_ids']) > 0) + $groupOrder['give_coupon_ids'] = app()->make(StoreCouponRepository::class)->getGiveCoupon($groupOrder['give_coupon_ids'])->column('coupon_id'); + $groupOrder->save(); + }); + + if (count($groupOrder['give_coupon_ids']) > 0) { + try { + Queue::push(PayGiveCouponJob::class, ['ids' => $groupOrder['give_coupon_ids'], 'uid' => $groupOrder['uid']]); + } catch (Exception $e) { + } + } + + Queue::push(SendSmsJob::class, ['tempId' => 'ORDER_PAY_SUCCESS', 'id' => $groupOrder->group_order_id]); + Queue::push(SendSmsJob::class, ['tempId' => 'ADMIN_PAY_SUCCESS_CODE', 'id' => $groupOrder->group_order_id]); + Queue::push(UserBrokerageLevelJob::class, ['uid' => $groupOrder->uid, 'type' => 'pay_money', 'inc' => $groupOrder->pay_price]); + Queue::push(UserBrokerageLevelJob::class, ['uid' => $groupOrder->uid, 'type' => 'pay_num', 'inc' => 1]); + app()->make(UserBrokerageRepository::class)->incMemberValue($groupOrder->uid, 'member_pay_num', $groupOrder->group_order_id); + $groupOrder = $groupOrder->toArray(); + event('order.paySuccess', compact('groupOrder')); + //店内扫码支付 + if (isset($groupOrder['micro_pay']) && $groupOrder['micro_pay'] == 1) { + $order = $this->dao->search(['uid' => $groupOrder->uid])->where('group_order_id', $groupOrder->group_order_id)->find(); + $order->status = 2; + $order->verify_time = date('Y-m-d H:i:s'); + $user = $order->user; + event('order.take.before', compact('order')); + Db::transaction(function () use ($order, $user) { + $this->takeAfter($order, $user); + $order->save(); + }); + event('order.take', compact('order')); + } + } + + + + /** + * @return string + * @author xaboy + * @day 2020/6/9 + */ + public function getNewOrderId($type) + { + list($msec, $sec) = explode(' ', microtime()); + $msectime = number_format((floatval($msec) + floatval($sec)) * 1000, 0, '', ''); + $orderId = $type . $msectime . mt_rand(10000, max(intval($msec * 10000) + 10000, 98369)); + return $orderId; + } + + /** + * @param $cart + * @return string + * @author xaboy + * @day 2020/6/9 + */ + public function productByTempNumber($cart) + { + $type = $cart['product']['temp']['type']; + $cartNum = $cart['cart_num']; + if (!$type) + return $cartNum; + else if ($type == 2) { + return bcmul($cartNum, $cart['productAttr']['volume'], 2); + } else { + return bcmul($cartNum, $cart['productAttr']['weight'], 2); + } + } + + public function cartByPrice($cart) + { + if ($cart['product_type'] == '2') { + return $cart['productPresellAttr']['presell_price']; + } else if ($cart['product_type'] == '3') { + return $cart['productAssistAttr']['assist_price']; + } else if ($cart['product_type'] == '4') { + return $cart['activeSku']['active_price']; + // 更新调货价格 + } else if ($cart['product_type'] == '98') { + if ($cart['source'] == StoreCartDao::SOURCE_PROCURE) { + return $cart['productAttr']['procure_price']; + } else { + return $cart['productAttr']['price']; + } + // 更新委托价格 + } else if ($cart['product_type'] == '99') { + if ($cart['source_id'] > 0) { + $price = Db::name('entrust')->where('community_id', $cart['source_id'])->where('product_attr_unique', $cart['product_attr_unique'])->where('status', 0)->value('price'); + if ($price) { + return $price; + } else { + throw new ValidateException('委托商品数据异常'); + } + } else { + return $cart['productAttr']['price']; + } + } else { + return $cart['productAttr']['price']; + } + } + + public function cartByCouponPrice($cart) + { + if ($cart['product_type'] == '2') { + return $cart['productPresellAttr']['final_price']; + } else if ($cart['product_type'] == '1') { + return 0; + } else if ($cart['product_type'] == '3') { + return 0; + } else if ($cart['product_type'] == '4') { + return 0; + // 更新调货价格 + } else if ($cart['product_type'] == '98') { + $price = Db::name('resale')->where('product_attr_unique', $cart['product_attr_unique'])->where('status', 0)->value('price'); + if ($price) { + return $price; + } else { + return $cart['productAttr']['price']; + } + // 更新委托价格 + } else if ($cart['product_type'] == '99') { + $price = Db::name('entrust')->where('product_attr_unique', $cart['product_attr_unique'])->where('status', 0)->value('price'); + if ($price) { + return $price; + } else { + return $cart['productAttr']['price']; + } + } else { + return $cart['productAttr']['price']; + } + } + + public function cartByDownPrice($cart) + { + if ($cart['product_type'] == '2') { + return $cart['productPresellAttr']['down_price']; + } else { + return 0; + } + } + + + /** + * @param int $uid + * @return array + * @author xaboy + * @day 2020/6/10 + */ + public function userOrderNumber(int $uid, $product_type = 0) + { + //activity_type:0普通订单 98采购订单 99委托商品 + //$noPay = app()->make(StoreGroupOrderRepository::class)->orderNumber($uid, $product_type); + $isUser = 1; + if ($product_type == 98 || $product_type == 99) { + $isUser = 0; + } + $noPay = $this->dao->search(['uid' => $uid, 'is_user' => $isUser])->where($this->getOrderType(1))->whereRaw("(StoreOrderOther.paid=0 and StoreOrderOther.pay_type!=8) or (StoreOrderOther.paid=1 and StoreOrderOther.pay_type=8 and StoreOrderOther.status=2)")->where('activity_type', $product_type)->where('StoreOrderOther.is_del', 0)->count(); + $noPostage = $this->dao->search(['uid' => $uid, 'is_user' => $isUser])->where($this->getOrderType(2))->where('activity_type', $product_type)->where('StoreOrderOther.is_del', 0)->fetchSql(false)->count(); + $noDeliver = $this->dao->search(['uid' => $uid, 'is_user' => $isUser])->where($this->getOrderType(3))->where('activity_type', $product_type)->where('StoreOrderOther.is_del', 0)->fetchSql(false)->count(); + $noComment = $this->dao->search(['uid' => $uid, 'is_user' => $isUser])->where($this->getOrderType(4))->where('activity_type', $product_type)->where('StoreOrderOther.is_del', 0)->fetchSql(false)->count(); + $done = $this->dao->search(['uid' => $uid, 'is_user' => $isUser])->where($this->getOrderType(5))->where('activity_type', $product_type)->where('StoreOrderOther.is_del', 0)->fetchSql(false)->count(); + $refund = StoreRefundOrder::alias('t1')->join('store_order t2', 't1.order_id=t2.order_id')->where('t1.uid', $uid)->where('t1.status', 3)->where('t2.activity_type', $product_type)->count(); + $orderPrice = $this->dao->search(['uid' => $uid, 'is_user' => $isUser])->where($this->getOrderType(8))->where('activity_type', $product_type)->where('StoreOrderOther.is_del', 0)->fetchSql(false)->sum('pay_price'); + $orderCount = $this->dao->search(['uid' => $uid, 'is_user' => $isUser])->where('activity_type', $product_type)->where('StoreOrderOther.is_del', 0)->fetchSql(false)->count(); + return compact('noComment', 'done', 'refund', 'noDeliver', 'noPay', 'noPostage', 'orderPrice', 'orderCount'); + } + + /** + * @param $id + * @param null $uid + * @return array|Model|null + * @throws DataNotFoundException + * @throws DbException + * @throws ModelNotFoundException + * @author xaboy + * @day 2020/6/10 + */ + public function getDetail($id, $uid = null) + { + $where = []; + $with = [ + 'orderProduct', + 'merchant' => function ($query) { + return $query->field('mer_id,mer_name,service_phone')->append(['services_type']); + }, + 'receipt' => function ($query) { + return $query->field('order_id,order_receipt_id'); + }, + 'takeOrderList.orderProduct' + ]; + if ($uid) { + $where['uid'] = $uid; + } else if (!$uid) { + $with['user'] = function ($query) { + return $query->field('uid,nickname'); + }; + } + $order = $this->dao->search($where)->where('order_id', $id)->where('StoreOrderOther.is_del', 0)->with($with)->append(['refund_status'])->find(); + if (!$order) { + return null; + } + if ($order->activity_type == 2) { + if ($order->presellOrder) { + $order->presellOrder->append(['activeStatus']); + $order->presell_price = bcadd($order->pay_price, $order->presellOrder->pay_price, 2); + } else { + $order->presell_price = $order->pay_price; + } + } + $order->order_status = $this->getOrderStatusV2($order); + return $order; + } + + public function codeByDetail($code, $uid = null) + { + $where = []; + if ($uid) $where['uid'] = $uid; + $data = $this->dao->search($where)->where('verify_code', $code) + ->where('StoreOrderOther.is_del', 0) + ->with([ + 'orderProduct', + 'merchant' => function ($query) { + return $query->field('mer_id,mer_name'); + } + ]) + ->find(); + if (!$data) + throw new ValidateException('数据不存在'); + if ($data['status']) + throw new ValidateException('该订单已全部核销'); + return $data; + } + + public function giveIntegral($groupOrder) + { + if ($groupOrder->give_integral > 0) { + app()->make(UserBillRepository::class)->incBill($groupOrder->uid, 'integral', 'lock', [ + 'link_id' => $groupOrder['group_order_id'], + 'status' => 0, + 'title' => '下单赠送积分', + 'number' => $groupOrder->give_integral, + 'mark' => '成功消费' . floatval($groupOrder['pay_price']) . '元,赠送积分' . floatval($groupOrder->give_integral), + 'balance' => $groupOrder->user->integral + ]); + } + } + + /** + * @param StoreOrder $order + * @param User $user + * @param string $type + * @author xaboy + * @day 2020/8/3 + */ + public function takeAfter(StoreOrder $order, ?User $user) + { + Db::transaction(function () use ($user, $order) { + if ($user && $order->pay_type != StoreGroupOrder::PAY_TYPE_CREDIT_BUY) $this->computed($order, $user); + Queue::push(SendSmsJob::class, ['tempId' => 'ORDER_TAKE_SUCCESS', 'id' => $order->order_id]); + Queue::push(SendSmsJob::class, ['tempId' => 'ADMIN_TAKE_DELIVERY_CODE', 'id' => $order->order_id]); + if ($order->pay_type != StoreGroupOrder::PAY_TYPE_CREDIT_BUY) { + app()->make(MerchantRepository::class)->computedLockMoney($order); + } + if (!empty($order->interest) && $order->interest->status == StoreOrderInterestOther::STATUS_UNSETTLED) { + $order->interest->start_time = date('Y-m-d H:i:s', strtotime("+{$order->interest->settle_cycle} days")); + $order->interest->save(); + } + $order->save(); + }); + } + + /** + * @param $id + * @param User $user + * @throws DataNotFoundException + * @throws DbException + * @throws ModelNotFoundException + * @author xaboy + * @day 2020/6/17 + */ + public function takeOrder($id, ?User $user = null) + { + $order = $this->dao->search(!$user ? [] : ['uid' => $user->uid], null)->where('order_id', $id)->where('StoreOrderOther.is_del', 0)->find(); + if (!$order) + throw new ValidateException('订单不存在'); + if ($order['status'] != 1 || $order['order_type']) + throw new ValidateException('订单状态有误'); + $func = 'createUserLog'; + if (!$user) { + $func = 'createSysLog'; + $user = $order->user; + } + // if (!$user) { + // + // throw new ValidateException('用户不存在'); + // } + $order->status = 2; + $order->verify_time = date('Y-m-d H:i:s'); + event('order.take.before', compact('order')); + //订单记录 + $storeOrderStatusRepository = app()->make(StoreOrderStatusRepository::class); + $orderStatus = [ + 'order_id' => $order->order_id, + 'order_sn' => $order->order_sn, + 'type' => $storeOrderStatusRepository::TYPE_ORDER, + 'change_message' => '已收货', + 'change_type' => $storeOrderStatusRepository::ORDER_STATUS_TAKE, + ]; + Db::transaction(function () use ($order, $user, $storeOrderStatusRepository, $orderStatus, $func) { + $this->takeAfter($order, $user); + $order->save(); + $storeOrderStatusRepository->{$func}($orderStatus); + }); + event('order.take', compact('order')); + } + + + /** + * 获取订单列表头部统计数据 + * @Author:Qinii + * @Date: 2020/9/12 + * @param int|null $merId + * @param int|null $orderType + * @return array + */ + public function OrderTitleNumber(?int $merId, ?int $orderType, ?int $product_type = 0) + { + $where = []; + $sysDel = $merId ? 0 : null; //商户删除 + if ($merId) $where['mer_id'] = $merId; //商户订单 + if ($orderType === 0) $where['order_type'] = 0; //普通订单 + if ($orderType === 1) $where['take_order'] = 1; //已核销订单 + if ($product_type != 0) $where['product_type'] = $product_type; //商品属性 + //1: 未支付 2: 未发货 3: 待收货 4: 待评价 5: 交易完成 6: 已退款 7: 已删除 8: 已支付 + $all = $this->dao->search($where, $sysDel)->where($this->getOrderType(0))->count(); + $statusAll = $all; + $unpaid = $this->dao->search($where, $sysDel)->where($this->getOrderType(1))->whereRaw("StoreOrderOther.paid=0 or (StoreOrderOther.paid=1 and StoreOrderOther.pay_type=8 and StoreOrderOther.status=2)")->count(); + $unshipped = $this->dao->search($where, $sysDel)->where($this->getOrderType(2))->count(); + $untake = $this->dao->search($where, $sysDel)->where($this->getOrderType(3))->count(); + $unevaluate = $this->dao->search($where, $sysDel)->where($this->getOrderType(4))->where('paid', 1)->where('pay_type', '<>', StoreGroupOrder::PAY_TYPE_CREDIT_BUY)->count(); + $complete = $this->dao->search($where, $sysDel)->where($this->getOrderType(5))->count(); + $refund = $this->dao->search($where, $sysDel)->where($this->getOrderType(6))->count(); + $del = $this->dao->search($where, $sysDel)->where($this->getOrderType(7))->count(); + + return compact('all', 'statusAll', 'unpaid', 'unshipped', 'untake', 'unevaluate', 'complete', 'refund', 'del'); + } + + public function orderType(array $where) + { + return [ + [ + 'count' => $this->dao->search($where)->count(), + 'title' => '全部', + 'order_type' => -1, + ], + [ + 'count' => $this->dao->search($where)->where('order_type', 0)->where('is_virtual', 0)->count(), + 'title' => '普通订单', + 'order_type' => 0, + ], + [ + 'count' => $this->dao->search($where)->where('order_type', 1)->count(), + 'title' => '核销订单', + 'order_type' => 1, + ], + [ + 'count' => $this->dao->search($where)->where('is_virtual', 1)->count(), + 'title' => '虚拟商品订单', + 'order_type' => 2, + ], + ]; + } + + /** + * @param $status + * @return mixed + * @author Qinii + */ + public function getOrderType($status) + { + $param['StoreOrderOther.is_del'] = 0; + switch ($status) { + case 1: + // $param['StoreOrderOther.paid'] = 0; + break; // 未支付 + case 2: + $param['StoreOrderOther.paid'] = 1; + $param['StoreOrderOther.status'] = 0; + break; // 待发货 + case 3: + $param['StoreOrderOther.status'] = 1; + break; // 待收货 + case 4: + $param['StoreOrderOther.status'] = 2; + break; // 待评价 + case 5: + $param['StoreOrderOther.status'] = 3; + break; // 交易完成 + case 6: + $param['StoreOrderOther.status'] = -1; + break; // 已退款 + case 7: + $param['StoreOrderOther.is_del'] = 1; + break; // 待核销 已删除 + case 8: + $param['StoreOrderOther.paid'] = 1; + break; // 已支付 + case 20: + $param['StoreOrderOther.status'] = [2, 3]; + break; // 已收货的商品才可以继续导入 + default: + unset($param['StoreOrderOther.is_del']); + break; // 全部 + } + return $param; + } + + /** + * @param int $id + * @param int|null $merId + * @return array|Model|null + * @author Qinii + */ + public function merDeliveryExists(int $id, ?int $merId, ?int $re = 0) + { + $where = ['order_id' => $id, 'is_del' => 0, 'paid' => 1]; + if ($re) $where['status'] = 0; + if ($merId) $where['mer_id'] = $merId; + return $this->dao->merFieldExists($where); + } + + /** + * TODO + * @param int $id + * @param int|null $merId + * @return bool + * @author Qinii + * @day 2020-06-11 + */ + public function merGetDeliveryExists(int $id, ?int $merId) + { + $where = ['order_id' => $id, 'is_del' => 0, 'paid' => 1, 'status' => 1]; + if ($merId) $where['mer_id'] = $merId; + return $this->dao->merFieldExists($where); + } + + /** + * @param int $id + * @param int|null $merId + * @return array|Model|null + * @author Qinii + */ + public function merStatusExists(int $id, ?int $merId) + { + $where = ['order_id' => $id, 'is_del' => 0, 'paid' => 0, 'status' => 0]; + if ($merId) $where['mer_id'] = $merId; + return $this->dao->merFieldExists($where); + } + + public function userDelExists(int $id, ?int $merId) + { + $where = ['order_id' => $id, 'is_del' => 1]; + if ($merId) $where['mer_id'] = $merId; + return $this->dao->merFieldExists($where); + } + + /** + * @param $id + * @return Form + * @author Qinii + */ + public function form($id) + { + $data = $this->dao->getWhere([$this->dao->getPk() => $id], 'total_price,pay_price,total_postage,pay_postage'); + $form = Elm::createForm(Route::buildUrl('merchantStoreOrderUpdate', ['id' => $id])->build()); + $form->setRule([ + Elm::number('total_price', '订单总价', $data['total_price'])->required(), + Elm::number('total_postage', '订单邮费', $data['total_postage'])->required(), + Elm::number('pay_price', '实际支付金额', $data['pay_price'])->required(), + ]); + return $form->setTitle('修改订单'); + } + + /** + * TODO 修改订单价格 + * @param int $id + * @param array $data + * @author Qinii + * @day 12/15/20 + */ + public function eidt(int $id, array $data, $service_id = 0) + { + + /** + * 1 计算出新的实际支付价格 + * 1.1 计算邮费 + * 1.2 计算商品总价 + * 2 修改订单信息 + * 3 计算总单数据 + * 4 修改总单数据 + * 5 修改订单商品单价 + * + * pay_price = total_price - coupon_price + pay_postage + */ + $order = $this->dao->get($id); + if ($order->activity_type == 2) { + throw new ValidateException('预售订单不支持改价'); + } + $extension_total = (float)bcadd($order->extension_one, $order->extension_two, 2); + $data['pay_price'] = $this->bcmathPrice($data['total_price'], $order['coupon_price'], $data['pay_postage']); + if ($data['pay_price'] < 0) { + throw new ValidateException('实际支付金额不能小于0'); + } else if ($data['pay_price'] < $extension_total) { + throw new ValidateException('实际支付金额不能小于佣金' . $extension_total); + } + $make = app()->make(StoreGroupOrderRepository::class); + $orderGroup = $make->dao->getWhere(['group_order_id' => $order['group_order_id']]); + + //总单总价格 + $_group['total_price'] = $this->bcmathPrice($orderGroup['total_price'], $order['total_price'], $data['total_price']); + //总单实际支付价格 + $_group['pay_price'] = $this->bcmathPrice($orderGroup['pay_price'], $order['pay_price'], $data['pay_price']); + //总单实际支付邮费 + $_group['pay_postage'] = $this->bcmathPrice($orderGroup['pay_postage'], $order['pay_postage'], $data['pay_postage']); + event('order.changePrice.before', compact('order', 'data')); + //订单记录 + $storeOrderStatusRepository = app()->make(StoreOrderStatusRepository::class); + + $orderStatus = [ + 'order_id' => $order->order_id, + 'order_sn' => $order->order_sn, + 'type' => $storeOrderStatusRepository::TYPE_ORDER, + 'change_message' => '订单价格修改', + 'change_type' => $storeOrderStatusRepository::ORDER_STATUS_CHANGE, + ]; + + Db::transaction(function () use ($id, $data, $orderGroup, $order, $_group, $storeOrderStatusRepository, $orderStatus, $service_id) { + $orderGroup->total_price = $_group['total_price']; + $orderGroup->pay_price = $_group['pay_price']; + $orderGroup->pay_postage = $_group['pay_postage']; + $orderGroup->group_order_sn = $this->getNewOrderId(StoreOrderRepository::TYPE_SN_ORDER) . '0'; + $orderGroup->save(); + + $this->dao->update($id, $data); + $this->changOrderProduct($id, $data); + + if ($service_id) { + $storeOrderStatusRepository->createServiceLog($service_id, $orderStatus); + } else { + $storeOrderStatusRepository->createAdminLog($orderStatus); + } + if ($data['pay_price'] != $order['pay_price']) Queue::push(SendSmsJob::class, ['tempId' => 'PRICE_REVISION_CODE', 'id' => $id]); + }); + event('order.changePrice', compact('order', 'data')); + } + + /** + * TODO 改价后重新计算每个商品的单价 + * @param int $orderId + * @param array $data + * @author Qinii + * @day 12/15/20 + */ + public function changOrderProduct(int $orderId, array $data) + { + $make = app()->make(StoreOrderProductRepository::class); + $ret = $make->getSearch(['order_id' => $orderId])->field('order_product_id,product_num,product_price')->select(); + $count = $make->getSearch(['order_id' => $orderId])->sum('product_price'); + $_count = (count($ret->toArray()) - 1); + $pay_price = $data['total_price']; + foreach ($ret as $k => $item) { + $_price = 0; + /** + * 比例 = 单个商品总价 / 订单原总价; + * + * 新的商品总价 = 比例 * 订单修改总价 + * + * 更新数据库 + */ + if ($k == $_count) { + $_price = $pay_price; + } else { + $_reta = bcdiv($item->product_price, $count, 3); + $_price = bcmul($_reta, $data['total_price'], 2); + } + + $item->product_price = $_price; + $item->save(); + + $pay_price = $this->bcmathPrice($pay_price, $_price, 0); + } + } + + /** + * TODO 计算的重复利用 + * @param $total + * @param $old + * @param $new + * @return int|string + * @author Qinii + * @day 12/15/20 + */ + public function bcmathPrice($total, $old, $new) + { + $_bcsub = bcsub($total, $old, 2); + $_count = (bccomp($_bcsub, 0, 2) == -1) ? 0 : $_bcsub; + $count = bcadd($_count, $new, 2); + return (bccomp($count, 0, 2) == -1) ? 0 : $count; + } + + /** + * @param $id + * @param $uid + * @return mixed + * @throws DataNotFoundException + * @throws DbException + * @throws ModelNotFoundException + * @author xaboy + * @day 2020/6/12 + */ + public function refundProduct($id, $uid) + { + $order = $this->dao->userOrder($id, $uid); + if (!$order) + throw new ValidateException('订单不存在'); + if (!count($order->refundProduct)) + throw new ValidateException('没有可退款商品'); + return $order->refundProduct->toArray(); + } + + /** + * TODO + * @param $id + * @param $data + * @return mixed + * @author Qinii + * @day 7/26/21 + */ + public function orderDumpInfo($id, $data, $merId) + { + $where = [ + 'order_id' => $id, + ]; + $ret = $this->dao->getWhere($where); + if ($ret['is_virtual']) throw new ValidateException('虚拟商品只能虚拟发货'); + $cargo = ''; + $count = 0; + foreach ($ret->orderProduct as $item) { + // $cargo .= $item['cart_info']['product']['store_name']. ' ' .$item['cart_info']['productAttr']['sku'] .' * ' .$item['product_num'].$item['cart_info']['product']['unit_name'].PHP_EOL; + $count += $item['product_num']; + } + + $data['to_name'] = $ret['real_name']; + $data['to_tel'] = $ret['user_phone']; + $data['to_addr'] = $ret['user_address']; + $data['cargo'] = $cargo; + $data['count'] = $count; + $data['order_sn'] = $ret['order_sn']; + return $data; + } + + + + + + public function runDelivery($id, $merId, $data, $split, $method, $service_id = 0) + { + return Db::transaction(function () use ($id, $merId, $data, $split, $method, $service_id) { + if ($split['is_split'] && !empty($split['split'])) { + foreach ($split['split'] as $v) { + $splitData[$v['id']] = $v['num']; + } + $order = $this->dao->get($id); + $newOrder = app()->make(StoreOrderSplitRepository::class)->splitOrder($order, $splitData, $service_id); + if ($newOrder) { + $id = $newOrder->order_id; + } else { + throw new ValidateException('商品不能全部拆单'); + } + } + return $this->{$method}($id, $merId, $data, $service_id); + }); + } + + /** + * TODO 发货订单操作 + * @param $id + * @param $data + * @return mixed + * @author Qinii + * @day 7/26/21 + */ + public function delivery($id, $merId, $data, $service_id = 0) + { + $data['status'] = 1; + $order = $this->dao->get($id); + if ($order['is_virtual'] && $data['delivery_type'] != 3) + throw new ValidateException('虚拟商品只能虚拟发货'); + //订单记录 + $statusRepository = app()->make(StoreOrderStatusRepository::class); + switch ($data['delivery_type']) { + case 1: + $exprss = app()->make(ExpressRepository::class)->getWhere(['code' => $data['delivery_name']]); + if (!$exprss) throw new ValidateException('快递公司不存在'); + $data['delivery_name'] = $exprss['name']; + $change_type = $statusRepository::ORDER_DELIVERY_COURIER; + $change_message = '订单已配送【快递名称】:' . $exprss['name'] . '; 【快递单号】:' . $data['delivery_id']; + $temp_code = 'DELIVER_GOODS_CODE'; + break; + case 2: + if (!preg_match("/^1[3456789]{1}\d{9}$/", $data['delivery_id'])) throw new ValidateException('手机号格式错误'); + $change_type = 'delivery_1'; + $change_message = '订单已配送【送货人姓名】:' . $data['delivery_name'] . '; 【手机号】:' . $data['delivery_id']; + $temp_code = 'ORDER_DELIVER_SUCCESS'; + break; + case 3: + $change_type = $statusRepository::ORDER_DELIVERY_NOTHING; + $change_message = '订单已配送【虚拟发货】'; + $data['status'] = 2; + break; + case 4: + $exprss = app()->make(ExpressRepository::class)->getWhere(['code' => $data['delivery_name']]); + if (!$exprss) throw new ValidateException('快递公司不存在'); + $data['delivery_name'] = $exprss['name']; + $change_type = $statusRepository::ORDER_DELIVERY_COURIER; + $change_message = '订单已配送【快递名称】:' . $exprss['name'] . '; 【快递单号】:' . $data['delivery_id']; + $temp_code = 'DELIVER_GOODS_CODE'; + break; + } + + event('order.delivery.before', compact('order', 'data')); + $this->dao->update($id, $data); + + $orderStatus = [ + 'order_id' => $order->order_id, + 'order_sn' => $order->order_sn, + 'type' => $statusRepository::TYPE_ORDER, + 'change_message' => $change_message, + 'change_type' => $change_type, + ]; + if ($service_id) { + $statusRepository->createServiceLog($service_id, $orderStatus); + } else { + $statusRepository->createAdminLog($orderStatus); + } + + + //虚拟发货后用户直接确认收获 + if ($data['status'] == 2) { + $user = app()->make(UserRepository::class)->get($order['uid']); + //订单记录 + $this->takeAfter($order, $user); + $orderStatus = [ + 'order_id' => $order->order_id, + 'order_sn' => $order->order_sn, + 'type' => $statusRepository::TYPE_ORDER, + 'change_message' => '虚拟发货后', + 'change_type' => $statusRepository::ORDER_STATUS_TAKE, + ]; + $statusRepository->createSysLog($orderStatus); + } + if (isset($temp_code)) Queue::push(SendSmsJob::class, ['tempId' => $temp_code, 'id' => $order->order_id]); + + event('order.delivery', compact('order', 'data')); + return $data; + } + + + + + public function getOne($id, ?int $merId) + { + $where = [$this->getPk() => $id]; + if ($merId) { + $whre['mer_id'] = $merId; + $whre['is_system_del'] = 0; + } + $res = $this->dao->getWhere( + $where, + '*', + [ + 'orderProduct', + 'user' => function ($query) { + $query->field('uid,real_name,nickname,is_svip,svip_endtime,phone'); + }, + 'refundOrder' => function ($query) { + $query->field('order_id,extension_one,extension_two,refund_price,integral')->where('status', 3); + }, + 'finalOrder', + 'TopSpread' => function ($query) { + $query->field('uid,nickname,avatar'); + }, + 'spread' => function ($query) { + $query->field('uid,nickname,avatar'); + }, + ] + ); + if (!$res) throw new ValidateException('数据不存在'); + $res['integral'] = (int)$res['integral']; + return $res->append(['refund_extension_one', 'refund_extension_two']); + } + + public function getOrderStatus($where, $page, $limit) + { + $where['type'] = StoreOrderStatusRepository::TYPE_ORDER; + return app()->make(StoreOrderStatusRepository::class)->search($where, $page, $limit); + } + + public function remarkForm($id) + { + $data = $this->dao->get($id); + $form = Elm::createForm(Route::buildUrl('merchantStoreOrderRemark', ['id' => $id])->build()); + $form->setRule([ + Elm::text('remark', '备注', $data['remark'])->required(), + ]); + return $form->setTitle('订单备注'); + } + + public function adminMarkForm($id) + { + $data = $this->dao->get($id); + $form = Elm::createForm(Route::buildUrl('systemMerchantOrderMark', ['id' => $id])->build()); + $form->setRule([ + Elm::text('admin_mark', '备注', $data['admin_mark'])->required(), + ]); + return $form->setTitle('订单备注'); + } + + /** + * TODO 平台每个商户的订单列表 + * @param $where + * @param $page + * @param $limit + * @return array + * @author Qinii + * @day 2020-06-15 + */ + public function adminMerGetList($where, $page, $limit) + { + $where['paid'] = 1; + $query = $this->dao->search($where, null); + $count = $query->count(); + $list = $query->with([ + 'orderProduct', + 'merchant' => function ($query) { + $query->field('mer_id,mer_name,is_trader'); + }, + 'groupOrder' => function ($query) { + $query->field('group_order_id,group_order_sn'); + }, + 'finalOrder', + 'user' => function ($query) { + $query->field('uid,nickname,avatar'); + }, + ])->page($page, $limit)->select()->append(['refund_extension_one', 'refund_extension_two']); + + return compact('count', 'list'); + } + + public function reconList($where, $page, $limit) + { + $ids = app()->make(MerchantReconciliationOrderRepository::class)->getIds($where); + $query = $this->dao->search([], null)->whereIn('order_id', $ids); + $count = $query->count(); + $list = $query->with(['orderProduct'])->page($page, $limit)->select()->each(function ($item) { + //(实付金额 - 一级佣金 - 二级佣金) * 抽成 + $commission_rate = ($item['commission_rate'] / 100); + //佣金 + $_order_extension = bcadd($item['extension_one'], $item['extension_two'], 3); + //手续费 = (实付金额 - 一级佣金 - 二级佣金) * 比例 + $_order_rate = bcmul(bcsub($item['pay_price'], $_order_extension, 3), $commission_rate, 3); + $item['order_extension'] = round($_order_extension, 2); + $item['order_rate'] = round($_order_rate, 2); + return $item; + }); + + return compact('count', 'list'); + } + + /** + * @param array $where + * @param $page + * @param $limit + * @return array + * @author Qinii + */ + public function merchantGetList(array $where, $page, $limit) + { + $status = $where['status']; + unset($where['status']); + $query = $this->dao->search($where)->where($this->getOrderType($status)) + ->when($status == 4, function ($query) { + $query->where('paid', 1)->where('pay_type', '<>', StoreGroupOrderOther::PAY_TYPE_CREDIT_BUY); + }) + ->when($status == 1, function ($query) { + $query->whereRaw("StoreOrderOther.paid=0 or (StoreOrderOther.paid=1 and StoreOrderOther.pay_type=8 and StoreOrderOther.status=2)"); + }) + ->with([ + 'orderProduct', + 'merchant' => function ($query) { + $query->field('mer_id,mer_name'); + }, + 'verifyService' => function ($query) { + $query->field('service_id,nickname'); + }, + 'finalOrder', + 'groupUser.groupBuying', + 'TopSpread' => function ($query) { + $query->field('uid,nickname,avatar'); + }, + 'spread' => function ($query) { + $query->field('uid,nickname,avatar'); + }, + ]); + $count = $query->count(); + $list = $query->page($page, $limit)->select()->append(['refund_extension_one', 'refund_extension_two']) + ->each(function ($item) { + // 1:退款中 2:部分退款 3 = 全退 + $refunding = 0; + if ($item['orderProduct']) { + $is_refund = array_column($item['orderProduct']->toArray(), 'is_refund'); + $is_refund = array_unique($is_refund); + if (in_array(1, $is_refund)) { + $refunding = 1; + } else if (in_array(2, $is_refund)) { + $refunding = 2; + } else if (in_array(3, $is_refund)) { + $refunding = 3; + } + } + $item['refunding'] = $refunding; + }); + + + return compact('count', 'list'); + } + + /** + * TODO 平台总的订单列表 + * @param array $where + * @param $page + * @param $limit + * @return array + * @author Qinii + * @day 2020-06-15 + */ + public function adminGetList(array $where, $page, $limit) + { + $status = $where['status']; + unset($where['status']); + $query = $this->dao->search($where, null)->where($this->getOrderType($status)) + ->with([ + 'orderProduct', + 'merchant' => function ($query) { + return $query->field('mer_id,mer_name,is_trader'); + }, + 'verifyService' => function ($query) { + return $query->field('service_id,nickname'); + }, + 'groupOrder' => function ($query) { + $query->field('group_order_id,group_order_sn'); + }, + 'finalOrder', + 'groupUser.groupBuying', + 'TopSpread' => function ($query) { + $query->field('uid,nickname,avatar'); + }, + 'spread' => function ($query) { + $query->field('uid,nickname,avatar'); + }, + 'user' => function ($query) { + $query->field('uid,nickname,avatar'); + }, + ]); + $count = $query->count(); + $list = $query->page($page, $limit)->select()->append(['refund_extension_one', 'refund_extension_two']); + return compact('count', 'list'); + } + + public function getStat(array $where, $status) + { + unset($where['status']); + $make = app()->make(StoreRefundOrderRepository::class); + $presellOrderRepository = app()->make(PresellOrderRepository::class); + + //退款订单id + $orderId = $this->dao->search($where)->where($this->getOrderType($status))->column('order_id'); + //退款金额 + $orderRefund = $make->refundPirceByOrder($orderId); + //实际支付订单数量 + $all = $this->dao->search($where)->where($this->getOrderType($status))->where('paid', 1)->count(); + //实际支付订单金额 + $countQuery = $this->dao->search($where)->where($this->getOrderType($status))->where('paid', 1); + $countOrderId = $countQuery->column('order_id'); + $countPay1 = $countQuery->sum('StoreOrderOther.pay_price'); + $countPay2 = $presellOrderRepository->search(['paid' => 1, 'order_ids' => $countOrderId])->sum('pay_price'); + $countPay = bcadd($countPay1, $countPay2, 2); + + //余额支付 + $banclQuery = $this->dao->search(array_merge($where, ['paid' => 1, 'pay_type' => 0]))->where($this->getOrderType($status)); + $banclOrderId = $banclQuery->column('order_id'); + $banclPay1 = $banclQuery->sum('StoreOrderOther.pay_price'); + $banclPay2 = $presellOrderRepository->search(['pay_type' => [0], 'paid' => 1, 'order_ids' => $banclOrderId])->sum('pay_price'); + $banclPay = bcadd($banclPay1, $banclPay2, 2); + + //微信金额 + $wechatQuery = $this->dao->search($where)->where($this->getOrderType($status))->where('paid', 1)->where('pay_type', 'in', [1, 2, 3, 6]); + $wechatOrderId = $wechatQuery->column('order_id'); + $wechatPay1 = $wechatQuery->sum('StoreOrderOther.pay_price'); + $wechatPay2 = $presellOrderRepository->search(['pay_type' => [1, 2, 3, 6], 'paid' => 1, 'order_ids' => $wechatOrderId])->sum('pay_price'); + $wechatPay = bcadd($wechatPay1, $wechatPay2, 2); + + //支付宝金额 + $aliQuery = $this->dao->search($where)->where($this->getOrderType($status))->where('paid', 1)->where('pay_type', 'in', [4, 5]); + $aliOrderId = $aliQuery->column('order_id'); + $aliPay1 = $aliQuery->sum('StoreOrderOther.pay_price'); + $aliPay2 = $presellOrderRepository->search(['pay_type' => [4, 5], 'paid' => 1, 'order_ids' => $aliOrderId])->sum('pay_price'); + $aliPay = bcadd($aliPay1, $aliPay2, 2); + + + $stat = [ + [ + 'className' => 'el-icon-s-goods', + 'count' => $all, + 'field' => '件', + 'name' => '已支付订单数量' + ], + [ + 'className' => 'el-icon-s-order', + 'count' => (float)$countPay, + 'field' => '元', + 'name' => '实际支付金额' + ], + [ + 'className' => 'el-icon-s-cooperation', + 'count' => (float)$orderRefund, + 'field' => '元', + 'name' => '已退款金额' + ], + [ + 'className' => 'el-icon-s-cooperation', + 'count' => (float)$wechatPay, + 'field' => '元', + 'name' => '微信支付金额' + ], + [ + 'className' => 'el-icon-s-finance', + 'count' => (float)$banclPay, + 'field' => '元', + 'name' => '余额支付金额' + ], + [ + 'className' => 'el-icon-s-cooperation', + 'count' => (float)$aliPay, + 'field' => '元', + 'name' => '支付宝支付金额' + ], + ]; + return $stat; + } + + /** + * @param array $where + * @param $page + * @param $limit + * @return array + * @throws DataNotFoundException + * @throws DbException + * @throws ModelNotFoundException + * @author xaboy + * @day 2020/6/10 + */ + public function getList(array $where, $page, $limit) + { + $status = $where['status'] ?? ''; + unset($where['status']); + // 未支付订单 + if ($status == 1) { + $query = $this->dao->search($where)->where($this->getOrderType($status))->whereRaw("(StoreOrderOther.paid=0 and StoreOrderOther.pay_type!=8) or (StoreOrderOther.paid=1 and StoreOrderOther.pay_type=8 and StoreOrderOther.status=2)")->where('StoreOrderOther.is_del', 0); + } else { + $arr = $this->getOrderType($status); + $query = $this->dao->search($where)->where($arr)->where('StoreOrderOther.is_del', 0); + } + + $count = $query->count(); + $list = $query->with([ + 'orderProduct', + 'presellOrder', + 'merchant' => function ($query) { + return $query->field('mer_id,mer_name,settle_cycle,interest_rate'); + }, + 'community', + 'receipt' => function ($query) { + return $query->field('order_id,order_receipt_id'); + }, + ])->page($page, $limit)->order('pay_time DESC')->append(['refund_status'])->select(); + + foreach ($list as $order) { + if ($order->activity_type == 2) { + if ($order->presellOrder) { + $order->presellOrder->append(['activeStatus']); + $order->presell_price = bcadd($order->pay_price, $order->presellOrder->pay_price, 2); + } else { + $order->presell_price = $order->pay_price; + } + } + if ($order->pay_type == StoreGroupOrderOther::PAY_TYPE_CREDIT_BUY && $order->interest) { + $order->interest_start_time = $order->interest->start_time; + $order->interest_status = $order->interest->status; + if ($order->interest_status == StoreOrderInterestOther::STATUS_SETTLED) { + $order->interest_money = $order->interest->interest; + } else { + $order->interest_money = $order->interest->calculateInterest(); + } + } + $order->takeOrderCount = count($order['takeOrderList']); + $order->order_status = $this->getOrderStatusV2($order); + unset($order['takeOrderList'], $order->interest); + } + + return compact('count', 'list'); + } + + public function getOrderStatusV2($order) + { + //订单状态 1 未支付 2待发货 3待收货 4待评价 5交易完成 6已退款 7待核销 8先货后款待结算 9待商家确认 + $order->order_status = 0; + if ($order->paid == 0) { + $order->order_status = 1; + } + if ($order->paid == 1 && $order->status == 0) { + $order->order_status = 2; + } + if ($order->status == 1) { + $order->order_status = 3; + } + if ($order->status == 2) { + $order->order_status = 4; + } + if ($order->status == 3) { + $order->order_status = 5; + } + if ($order->status == -1) { + $order->order_status = 6; + } + if ($order->paid == 1 && $order->status == 0 && $order->order_type == 1) { + $order->order_status = 7; + } + //如果是先货后款信用购的状态处理 + if ($order->paid == 1 && $order->status == 2 && $order->pay_type == 8) { + $order->order_status = 8; + } + if ($order->status == 12) { + $order->order_status = 9; + } + return $order->order_status; + } + + public function userList($uid, $page, $limit) + { + $query = $this->dao->search([ + 'uid' => $uid, + 'paid' => 1 + ]); + $count = $query->count(); + $list = $query->page($page, $limit)->select(); + return compact('count', 'list'); + } + + + public function userMerList($uid, $merId, $page, $limit) + { + $query = $this->dao->search([ + 'uid' => $uid, + 'mer_id' => $merId, + 'paid' => 1 + ]); + $count = $query->count(); + $list = $query->with(['presellOrder'])->page($page, $limit)->select(); + foreach ($list as $order) { + if ($order->activity_type == 2 && $order->status >= 0 && $order->status < 10 && $order->presellOrder) { + $order->pay_price = bcadd($order->pay_price, $order->presellOrder->pay_price, 2); + } + } + return compact('count', 'list'); + } + + public function express(int $orderId, ?int $merId) + { + $order = $this->dao->get($orderId); + if ($merId && $order['mer_id'] != $merId) throw new ValidateException('订单信息不存在'); + if (!in_array($order['delivery_type'], [1, 4])) throw new ValidateException('订单状态错误'); + return ExpressService::express($order->delivery_id, $order->delivery_name, $order->user_phone); + } + + + public function batchPrinter(int $id, int $merId) + { + $order = $this->dao->getWhere(['order_id' => $id], '*', ['orderProduct', 'merchant' => function ($query) { + $query->field('mer_id,mer_name'); + }]); + + foreach ($order['orderProduct'] as $item) { + $product[] = [ + 'store_name' => $item['cart_info']['product']['store_name'] . '【' . $item['cart_info']['productAttr']['sku'] . '】', + 'product_num' => $item['product_num'], + 'price' => bcdiv($item['product_price'], $item['product_num'], 2), + 'product_price' => $item['product_price'], + ]; + } + + $data = [ + 'order_sn' => $order['order_sn'], + 'order_type' => $order['order_type'], + 'pay_time' => $order['pay_time'], + 'real_name' => $order['real_name'], + 'user_phone' => $order['user_phone'], + 'user_address' => $order['user_address'], + 'total_price' => $order['total_price'], + 'coupon_price' => $order['coupon_price'], + 'pay_price' => $order['pay_price'], + 'total_postage' => $order['total_postage'], + 'pay_postage' => $order['pay_postage'], + 'mark' => $order['mark'], + ]; + + $printer = app()->make(StorePrinterRepository::class)->getPrinter($merId); + event('order.print.before', compact('order')); + foreach ($printer as $config) { + $printer = new Printer('yi_lian_yun', $config); + $res = $printer->setPrinterContent([ + 'name' => $order['merchant']['mer_name'], + 'orderInfo' => $data, + 'product' => $product + ])->startPrinter(); + } + + event('order.print', compact('order', 'res')); + } + + + public function wxQrcode($orderId, $verify_code) + { + $siteUrl = systemConfig('site_url'); + $name = md5('owx' . $orderId . date('Ymd')) . '.jpg'; + $attachmentRepository = app()->make(AttachmentRepository::class); + $imageInfo = $attachmentRepository->getWhere(['attachment_name' => $name]); + + if (isset($imageInfo['attachment_src']) && strstr($imageInfo['attachment_src'], 'http') !== false && curl_file_exist($imageInfo['attachment_src']) === false) { + $imageInfo->delete(); + $imageInfo = null; + } + if (!$imageInfo) { + // $codeUrl = set_http_type(rtrim($siteUrl, '/') . '/pages/admin/order_cancellation/index?verify_code=' . $verify_code, request()->isSsl() ? 0 : 1);//二维码链接 + $imageInfo = app()->make(QrcodeService::class)->getQRCodePath($verify_code, $name); + if (is_string($imageInfo)) throw new ValidateException('二维码生成失败'); + + $imageInfo['dir'] = tidy_url($imageInfo['dir'], null, $siteUrl); + + $attachmentRepository->create(systemConfig('upload_type') ?: 1, -2, $orderId, [ + 'attachment_category_id' => 0, + 'attachment_name' => $imageInfo['name'], + 'attachment_src' => $imageInfo['dir'] + ]); + $urlCode = $imageInfo['dir']; + } else $urlCode = $imageInfo['attachment_src']; + return $urlCode; + } + + public function logisticsQrcode($orderId, $order_sn) + { + $siteUrl = systemConfig('site_url'); + $name = md5('logi' . $orderId . date('Ymd')) . '.jpg'; + $attachmentRepository = app()->make(AttachmentRepository::class); + $imageInfo = $attachmentRepository->getWhere(['attachment_name' => $name]); + + if (isset($imageInfo['attachment_src']) && strstr($imageInfo['attachment_src'], 'http') !== false && curl_file_exist($imageInfo['attachment_src']) === false) { + $imageInfo->delete(); + $imageInfo = null; + } + if (!$imageInfo) { + $imageInfo = app()->make(QrcodeService::class)->getQRCodePath($order_sn, $name); + if (is_string($imageInfo)) throw new ValidateException('二维码生成失败'); + $imageInfo['dir'] = tidy_url($imageInfo['dir'], null, $siteUrl); + $attachmentRepository->create(systemConfig('upload_type') ?: 1, -2, $orderId, [ + 'attachment_category_id' => 99, + 'attachment_name' => $imageInfo['name'], + 'attachment_src' => $imageInfo['dir'] + ]); + $urlCode = $imageInfo['dir']; + } else $urlCode = $imageInfo['attachment_src']; + return $urlCode; + } + + /** + * TODO 根据商品ID获取订单数 + * @param int $productId + * @return int + * @author Qinii + * @day 2020-08-05 + */ + public function seckillOrderCounut(int $productId) + { + $where = [ + 'activity_id' => $productId, + 'product_type' => 1, + 'day' => date('Y-m-d', time()) + ]; + $count = $this->dao->getTattendCount($where, null)->count(); + $count_ = $this->dao->getSeckillRefundCount($where, 2); + $count__ = $this->dao->getSeckillRefundCount($where, 1); + return $count - $count_ - $count__; + } + + /** + * TODO 根据商品sku获取订单数 + * @param int $productId + * @return int + * @author Qinii + * @day 2020-08-05 + */ + public function seckillSkuOrderCounut(string $sku) + { + $where = [ + 'product_sku' => $sku, + 'product_type' => 1, + 'day' => date('Y-m-d', time()) + ]; + $count = $this->dao->getTattendCount($where, null)->count(); + $count_ = $this->dao->getSeckillRefundCount($where, 2); + $count__ = $this->dao->getSeckillRefundCount($where, 1); + return $count - $count_ - $count__; + } + + /** + * TODO 获取sku的总销量 + * @param string $sku + * @return int|mixed + * @author Qinii + * @day 3/4/21 + */ + public function skuSalesCount(string $sku) + { + $where = [ + 'product_sku' => $sku, + 'product_type' => 1, + ]; + $count = $this->dao->getTattendSuccessCount($where, null)->count(); + $count_ = $this->dao->getSeckillRefundCount($where, 2); + $count__ = $this->dao->getSeckillRefundCount($where, 1); + return $count - $count_ - $count__; + } + + /** + * 根据订单id查看是否全部退款 + * @Author:Qinii + * @Date: 2020/9/11 + * @param int $orderId + * @return bool + */ + public function checkRefundStatusById(int $orderId, int $refundId) + { + return Db::transaction(function () use ($orderId, $refundId) { + $res = $this->dao->search(['order_id' => $orderId])->with(['orderProduct'])->find(); + $refund = app()->make(StoreRefundOrderRepository::class)->getRefundCount($orderId, $refundId); + if ($refund) return false; + foreach ($res['orderProduct'] as $item) { + if ($item['refund_num'] !== 0) return false; + $item->is_refund = 3; + $item->save(); + } + $res->status = -1; + $res->save(); + $this->orderRefundAllAfter($res); + return true; + }); + } + + public function orderRefundAllAfter($order) + { + + if ($order->activity_type == 10) { + app()->make(StoreDiscountRepository::class)->incStock($order->orderProduct[0]['activity_id']); + } + $mainId = $order->main_id ?: $order->order_id; + $count = $this->query([])->where('status', '<>', -1)->where(function ($query) use ($mainId) { + $query->where('order_id', $mainId)->whereOr('main_id', $mainId); + })->count(); + //拆单后完全退完 + if (!$count) { + if ($order->main_id) { + $order = $this->query(['order_id' => $mainId])->find(); + } + $couponId = []; + if ($order->coupon_id) { + $couponId = explode(',', $order->coupon_id); + } + app()->make(MerchantRepository::class)->computedLockMoney($order); + //总单所有订单全部退完 + if (!$this->query([])->where('status', '<>', -1)->where('group_order_id', $order->group_order_id)->count()) { + if ($order->groupOrder->coupon_id) { + $couponId[] = $order->groupOrder->coupon_id; + } + } + if (count($couponId)) { + app()->make(StoreCouponUserRepository::class)->updates($couponId, ['status' => 0]); + } + } + //订单记录 + $storeOrderStatusRepository = app()->make(StoreOrderStatusRepository::class); + $orderStatus = [ + 'order_id' => $order->order_id, + 'order_sn' => $order->order_sn, + 'type' => $storeOrderStatusRepository::TYPE_ORDER, + 'change_message' => '订单已全部退款', + 'change_type' => $storeOrderStatusRepository::ORDER_STATUS_REFUND_ALL, + ]; + $storeOrderStatusRepository->createSysLog($orderStatus); + + event('order.refundAll', compact('order')); + } + + /** + * @param $id + * @param $uid + * @throws DataNotFoundException + * @throws DbException + * @throws ModelNotFoundException + * @author xaboy + * @day 2020/9/17 + */ + public function userDel($id, $uid) + { + $order = $this->dao->getWhere([['status', 'in', [0, 3, -1, 11]], ['order_id', '=', $id], ['uid', '=', $uid], ['is_del', '=', 0]]); + if (!$order || ($order->status == 0 && $order->paid == 1)) + throw new ValidateException('订单状态有误'); + event('order.userDel.before', compact('order')); + $this->delOrder($order, '订单删除'); + event('order.userDel', compact('order')); + } + + public function delOrder($order, $info = '订单删除') + { + //订单记录 + $storeOrderStatusRepository = app()->make(StoreOrderStatusRepository::class); + $orderStatus = [ + 'order_id' => $order->order_id, + 'order_sn' => $order->order_sn, + 'type' => $storeOrderStatusRepository::TYPE_ORDER, + 'change_message' => $info, + 'change_type' => $storeOrderStatusRepository::ORDER_STATUS_DELETE, + ]; + $productRepository = app()->make(ProductRepository::class); + Db::transaction(function () use ($info, $order, $orderStatus, $storeOrderStatusRepository, $productRepository) { + $order->is_del = 1; + $order->save(); + $storeOrderStatusRepository->createUserLog($orderStatus); + foreach ($order->orderProduct as $cart) { + $productRepository->orderProductIncStock($order, $cart); + } + }); + } + + public function merDelete($id) + { + Db::transaction(function () use ($id) { + $data['is_system_del'] = 1; + $this->dao->update($id, $data); + app()->make(StoreOrderReceiptRepository::class)->deleteByOrderId($id); + }); + } + + + /** + * TODO 根据订单查询相关联的自订单 + * @param $id + * @param $merId + * @return \think\Collection + * @author Qinii + * @day 2023/2/22 + */ + public function childrenList($id, $merId) + { + $data = $this->dao->get($id); + $query = $this->dao->getSearch([])->with(['orderProduct'])->where('order_id', '<>', $id); + if ($merId) $query->where('mer_id', $merId); + if ($data['main_id']) { + $query->where(function ($query) use ($data, $id) { + $query->where('main_id', $data['main_id'])->whereOr('order_id', $data['main_id']); + }); + } else { + $query->where('main_id', $id); + } + return $query->select(); + } + + + public function create_product_import_log($data, $status = 1) + { + $data = [ + 'product_id' => $data['product_id'] ?? 0, + 'mer_id' => $data['mer_id'], + 'name' => $data['store_name'], + 'content' => $data['content'] ?? '', + 'status' => $status, + 'create_time' => date('Y-m-d H:i:s'), + ]; + Db::name('store_product_import')->insert($data); + } + + public function create_product_attr_value($find, $datum, $product_type, $attr_values, $merId, $sku) + { + $procure_price = 0; + if (!empty($datum['value']['procure_price'])) { + $procure_price = $datum['value']['procure_price']; + } + $attrValue['stock'] = 1; + $unique = app(ProductRepository::class)->setUnique($find['product_id'], $datum['value']['bar_code'], $product_type); + $attrValue['unique'] = $unique; + $attrValue['detail'] = json_encode($attr_values); + $attrValue['product_id'] = $find['product_id']; + $attrValue['mer_id'] = $merId; + $attrValue['sku'] = $sku; + $attrValue['cost'] = $datum['value']['cost']; + $attrValue['ot_price'] = $datum['value']['price']; + $attrValue['price'] = $datum['value']['price']; + $attrValue['procure_price'] = $procure_price; + $attrValue["image"] = "https://lihai001.oss-cn-chengdu.aliyuncs.com/public/kk/luzhou/static4/oa_app/23565656.png"; + Db::name('store_product')->where('product_id',$find['product_id'])->update(['spec_type'=>1]); + Db::name('store_product_attr_value')->insert($attrValue); + } + /** + * 订单结算 + * @param $id + * @param $payType + * @param $user + * @return array + * @throws Exception + */ + public function settle($id, $payType, $user) + { + /** @var StoreGroupOrderRepository $groupOrderRepository */ + $groupOrderRepository = app()->make(StoreGroupOrderRepository::class); + $groupOrderRepository->getAll = true; + Db::startTrans(); + try { + $groupOrder = $groupOrderRepository->detail($user['uid'], $id, false); + if (!$groupOrder) { + throw new Exception('订单不存在或已支付'); + } + $order = $groupOrder->orderList[0]; + if (!$groupOrder->interest || $groupOrder->interest->status != StoreOrderInterestOther::STATUS_UNSETTLED || $order->status != 2) { + throw new Exception('订单无需结算'); + } + $interest = $groupOrder->interest->calculateInterest(); + $payMoney = bcadd($groupOrder->interest->total_price, $interest, 2); + $result = true; + $type = array_search($payType, StoreOrderRepository::PAY_TYPE); + if (in_array($payType, ['weixin', 'alipay'], true) && request()->isApp()) { + $payType .= 'App'; + } + $data = ['type' => $type, 'order_id' => $groupOrder->group_order_id, 'paid' => true]; + if ($payMoney > 0) { + $groupOrder->pay_price = $payMoney; + if (!in_array($payType, ['balance', 'scrcu'])) { + if (systemConfig('open_wx_combine')) { + $service = new CombinePayService($payType, $groupOrder->getCombinePayParams('order_settle')); + } else { + $service = new PayService($payType, $groupOrder->getPayParams($payType === 'alipay' ? request()->param('return_url') : '', 'order_settle')); + } + $result = $service->pay($user); + $data = array_merge($data, $result, ['paid' => false]); + } else { + $payTool = PayTool::instance($payType); + $result = $payTool->pay($groupOrder); + } + } + $groupOrder->interest->interest = $interest; + if ($result === true) { + //写入用户账单 + /** @var UserBillRepository $userBillRepository */ + $userBillRepository = app()->make(UserBillRepository::class); + $userBillRepository->decBill($user['uid'], 'now_money', 'pay_product', [ + 'link_id' => $groupOrder['group_order_id'], + 'status' => 1, + 'title' => '购买商品', + 'number' => $groupOrder['pay_price'], + 'mark' => '余额支付支付' . floatval($groupOrder['pay_price']) . '元购买商品', + 'balance' => $user->now_money + ]); + + /** @var StoreOrderRepository $storeOrderRepo */ + $storeOrderRepo = app()->make(StoreOrderRepository::class); + $storeOrderRepo->paySuccess($groupOrder); + app()->make(MerchantRepository::class)->computedLockMoney($groupOrder->orderList[0]); + $groupOrder->interest->status = StoreOrderInterestOther::STATUS_SETTLED; + $groupOrder->interest->settle_time = date('Y-m-d H:i:s'); + + //订单结算之后,修改订单支付方式为真实的支付方式 + $groupOrder->pay_type = $type; + $groupOrder->save(); + $order->pay_type = $type; + $order->save(); + } + $groupOrder->interest->save(); + Db::commit(); + return $data; + } catch (\Exception $e) { + Db::rollback(); + throw new Exception($e->getMessage()); + } + } + + /** + * 确认接单 + * @param $user + * @param $id + * @param $type + * @return void + * @throws Exception + */ + public function confirm($id, $type) + { + /** @var StoreGroupOrderRepository $groupOrderRepository */ + $groupOrderRepository = app()->make(StoreGroupOrderRepository::class); + $groupOrderRepository->getAll = true; + Db::startTrans(); + try { + $groupOrder = $groupOrderRepository->get($id); + if ($groupOrder->pay_type != StoreGroupOrder::PAY_TYPE_CREDIT_BUY) { + throw new Exception('订单类型错误'); + } + $order = $groupOrder->orderList[0]; + if ($order->status != StoreOrder::STATUS_WAIT_CONFIRM) { + throw new Exception('订单状态错误'); + } + if ($type == 2) { + $order->is_del = 1; + $groupOrder->is_del = 1; + if (!empty($order->interest) && $order->interest->status == StoreOrderInterestOther::STATUS_UNSETTLED) { + $order->interest->status = StoreOrderInterestOther::STATUS_DELETED; + $order->interest->save(); + } + } else { + if ($groupOrder->pay_type == StoreGroupOrderOther::PAY_TYPE_CREDIT_BUY) { + //如果是先货后款并且选择到店核销、同意时生成核销码 + if (!empty($order->order_type) && $order->order_type == 1) { + $order->verify_code = $this->verifyCode(); + } + } + $order->status = StoreOtherOrder::STATUS_WAIT_PAY; + $groupOrder->paid = 1; + $groupOrder->pay_time = date('Y-m-d H:i:s'); + $order->paid = 1; + $order->pay_time = date('Y-m-d H:i:s'); + } + $groupOrder->save(); + $order->save(); + Db::commit(); + } catch (\Exception $e) { + Db::rollback(); + throw new Exception($e->getMessage()); + } + } + /** + * @param $orderId + * @param $orderSn + * 更新扫描发货状态 + */ + public function deliveryGoods($orderId, $orderSn, $logisticsCode = '') + { + if ($logisticsCode) { + $order = $this->dao->search([], null)->where('order_sn', $orderSn)->where('order_id', $orderId)->where('logistics_code', $logisticsCode)->where('StoreOrderOther.status', 1)->where('StoreOrderOther.is_del', 0)->find(); + } else { + $order = $this->dao->search([], null)->where('order_sn', $orderSn)->where('order_id', $orderId)->where('StoreOrderOther.status', 0)->where('StoreOrderOther.is_del', 0)->find(); + } + if (!$order) + throw new ValidateException('订单不存在或编码code错误'); + if ($order['order_type']) + throw new ValidateException('订单类型错误'); + + if ($logisticsCode) { + $order->status = 2; + $order->mark = '快递员已完成送货'; + } else { + $order->status = 1; + $order->mark = '快递员已扫描取件'; + event('product.delivery', compact('order')); + } + $order->save(); + } +} diff --git a/app/controller/api/store/order/StoreOrder.php b/app/controller/api/store/order/StoreOrder.php index f439e4b1..305b56dd 100644 --- a/app/controller/api/store/order/StoreOrder.php +++ b/app/controller/api/store/order/StoreOrder.php @@ -24,6 +24,7 @@ use crmeb\basic\BaseController; use app\common\repositories\store\order\StoreCartRepository; use app\common\repositories\store\order\StoreGroupOrderRepository; use app\common\repositories\store\order\StoreOrderRepository; +use app\common\repositories\store\order\StoreOtherOrderRepository; use app\common\repositories\user\UserAddressRepository; use think\exception\ValidateException; use crmeb\services\ExpressService; @@ -185,6 +186,24 @@ class StoreOrder extends BaseController return app('json')->success($this->repository->getList($where, $page, $limit)); } + /** + * @return mixed + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\DbException + * @throws \think\db\exception\ModelNotFoundException + * @author xaboy + * @day 2020/6/10 + */ + public function lst_other(StoreOtherOrderRepository $otherOrderRepository) + { + [$page, $limit] = $this->getPage(); + $where['status'] = $this->request->param('status'); + $where['product_type'] = $this->request->param('product_type', 0); + $where['search'] = $this->request->param('store_name'); + $where['uid'] = $this->request->uid(); + $where['is_user'] = 1; + return app('json')->success($otherOrderRepository->getList($where, $page, $limit)); + } /** * @param $id * @return mixed diff --git a/route/api.php b/route/api.php index b11d8aba..5aeff1c3 100644 --- a/route/api.php +++ b/route/api.php @@ -62,7 +62,7 @@ Route::group('api/', function () { Route::group('order', function () { Route::post('check', '/v2CheckOrder'); Route::post('create', '/v2CreateOrder'); - Route::post('other', '/otherOrder');//创建其他订单 + Route::post('other', '/otherOrder'); //创建其他订单 })->prefix('api.store.order.StoreOrder'); @@ -127,7 +127,10 @@ Route::group('api/', function () { Route::post('receipt/:id', '/createReceipt'); Route::get('delivery/:id', '/getOrderDelivery'); })->prefix('api.store.order.StoreOrder'); - + //其他订单 + Route::group('other_order', function () { + Route::get('list', '/lst_other'); + })->prefix('api.store.order.StoreOrder'); // 预售 Route::group('presell', function () { Route::post('pay/:id', '/pay'); @@ -779,9 +782,6 @@ Route::group('api/', function () { Route::post('mechant_login', 'Login/mechantLogin'); /**---------------------数据之眼可视化大屏api-------------------- end */ - - - })->prefix('api.dataview.'); })->middleware(AllowOriginMiddleware::class) ->middleware(InstallMiddleware::class) @@ -800,4 +800,3 @@ Route::group('/open-location', function () { Route::miss('View/h5'); })->middleware(InstallMiddleware::class) ->middleware(CheckSiteOpenMiddleware::class); -