// +---------------------------------------------------------------------- declare (strict_types=1); namespace app\services\activity\combination; use app\dao\activity\combination\StorePinkDao; use app\jobs\PinkJob; use app\services\BaseServices; use app\services\order\StoreOrderDeliveryServices; use app\services\order\StoreOrderRefundServices; use app\services\order\StoreOrderServices; use app\services\other\PosterServices; use app\services\other\QrcodeServices; use app\services\system\attachment\SystemAttachmentServices; use app\services\user\UserServices; use crmeb\exceptions\ApiException; use crmeb\services\CacheService; use crmeb\services\app\MiniProgramService; use app\services\other\UploadService; use Guzzle\Http\EntityBody; /** * * Class StorePinkServices * @package app\services\activity * @method getPinkCount(array $where) * @method int count(array $where = []) 获取指定条件下的条数 * @method getPinkOkSumTotalNum() * @method isPink(int $id, int $uid) 是否能继续拼团 * @method getPinkUserOne(int $id) 拼团 * @method getCount(array $where) 获取某些条件总数 * @method value(array $where, string $field) * @method getColumn(array $where, string $field, ?string $key) * @method update(array $where, array $data) */ class StorePinkServices extends BaseServices { /** * StorePinkServices constructor. * @param StorePinkDao $dao */ public function __construct(StorePinkDao $dao) { $this->dao = $dao; } /** * @param array $where * @return array * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException */ public function systemPage(array $where) { $where['k_id'] = 0; [$page, $limit] = $this->getPageValue(); $list = $this->dao->getList($where, $page, $limit); foreach ($list as &$item) { $item['count_people'] = $this->dao->count(['k_id' => $item['id']]) + 1; $item['_add_time'] = $item['add_time'] ? date('Y-m-d H:i:s', (int)$item['add_time']) : ''; $item['_stop_time'] = $item['stop_time'] ? date('Y-m-d H:i:s', (int)$item['stop_time']) : ''; } $count = $this->dao->count($where); return compact('list', 'count'); } /** * 拼团列表头部 * @return array */ public function getStatistics() { $res = [ ['col' => 6, 'count' => $this->dao->count(), 'name' => '参与人数(人)', 'className' => 'ios-speedometer-outline'], ['col' => 6, 'count' => $this->dao->count(['k_id' => 0, 'status' => 2]), 'name' => '成团数量(个)', 'className' => 'md-rose'], ]; return compact('res'); } /** * 参团人员 * @param int $id * @return array * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException */ public function getPinkMember(int $id) { return $this->dao->getList(['k_id' => $id]); } /** * 拼团退款 * @param $order * @return bool * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException */ public function setRefundPink($order) { $res = true; if ($order['pink_id']) { $id = $order['pink_id']; } else { return true; } //正在拼团 团长 $count = $this->dao->getOne(['id' => $id, 'uid' => $order['uid']]); //正在拼团 团员 $countY = $this->dao->getOne(['k_id' => $id, 'uid' => $order['uid']]); if (!$count && !$countY) { return $res; } if ($count) {//团长 //判断团内是否还有其他人 如果有 团长为第二个进团的人 $kCount = $this->dao->getPinking(['k_id' => $id]); if ($kCount) { $res11 = $this->dao->update($id, ['k_id' => $kCount['id']], 'k_id'); $res12 = $this->dao->update($kCount['id'], ['stop_time' => $count['add_time'] + 86400, 'k_id' => 0]); $res1 = $res11 && $res12; $res2 = $this->dao->update($id, ['stop_time' => time() - 1, 'k_id' => $kCount['id'], 'is_refund' => $kCount['id'], 'status' => 3]); $res3 = app()->make(StoreOrderServices::class)->update(['pink_id' => $id], ['pink_id' => $kCount['id']]); } else { $res1 = $res3 = true; $res2 = $this->dao->update($id, ['stop_time' => time() - 1, 'is_refund' => $id, 'status' => 3]); } //修改结束时间为前一秒 团长ID为0 $res = $res1 && $res2 && $res3; } else if ($countY) {//团员 $res = $this->dao->update($countY['id'], ['stop_time' => time() - 1, 'is_refund' => $id, 'status' => 3]); } return $res; } /** * 拼团详情查看拼团列表 * @param int $id * @param bool $type * @return array * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException */ public function getPinkList(int $id, bool $type) { $where['cid'] = $id; $where['k_id'] = 0; $where['is_refund'] = 0; $where['status'] = 1; $pinkList = $this->dao->pinkList($where); $ids = array_column($pinkList, 'id'); $orderIdKey = array_column($pinkList, 'order_id_key'); $refunList = []; if ($orderIdKey) { $refunList = app()->make(StoreOrderRefundServices::class)->getColumn([['store_order_id', 'in', $orderIdKey]], 'id', 'store_order_id'); } if ($refunList) { $list = []; foreach ($pinkList as $item) { if (!isset($refunList[$item['order_id_key']])) { $list[] = $item; } } } else { $list = $pinkList; } $counts = $this->dao->getPinkPeopleCount($ids); if ($type) { $pinkAll = []; foreach ($list as &$v) { $v['count'] = $v['people'] - $counts[$v['id']]; $v['h'] = date('H', (int)$v['stop_time']); $v['i'] = date('i', (int)$v['stop_time']); $v['s'] = date('s', (int)$v['stop_time']); $pinkAll[] = $v['id'];//开团团长ID $v['stop_time'] = (int)$v['stop_time']; $v['avatar'] = set_file_url($v['avatar']); } return [$list, $pinkAll]; } return $list; } /** * 获取成团列表信息 * @param int $uid * @return array * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException */ public function getPinkOkList(int $uid) { $list = $this->dao->successList($uid); $msg = []; foreach ($list as &$item) { if (isset($item['nickname'])) $msg[] = $item['nickname'] .= '拼团成功'; } return $msg; } /** * 查找拼团信息 * @param $pink * @return array * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException */ public function getPinkMemberAndPinkK($pink) { //查找拼团团员和团长 if ($pink['k_id']) { $pinkAll = $this->dao->getPinkUserList(['k_id' => $pink['k_id']]); $pinkT = $this->dao->getPinkUserOne($pink['k_id']); } else { $pinkAll = $this->dao->getPinkUserList(['k_id' => $pink['id']]); $pinkT = $pink; } $count = count($pinkAll) + 1; $count = $pinkT['people'] - $count; $idAll = []; $uidAll = []; //收集拼团用户id和拼团id foreach ($pinkAll as $k => $v) { $idAll[$k] = $v['id']; $uidAll[$k] = $v['uid']; } $idAll[] = $pinkT['id']; $uidAll[] = $pinkT['uid']; return [$pinkAll, $pinkT, $count, $idAll, $uidAll]; } /** * 拼团失败 * @param $pinkAll * @param $pinkT * @param $pinkBool * @param bool $isRunErr * @param bool $isIds * @return array|int */ public function pinkFail($pinkAll, $pinkT, $pinkBool, $isRunErr = true, $isIds = false) { /** @var StoreOrderServices $orderService */ $orderService = app()->make(StoreOrderServices::class); /** @var StoreOrderRefundServices $orderRefundService */ $orderRefundService = app()->make(StoreOrderRefundServices::class); $pinkIds = []; try { if ($pinkT['stop_time'] < time()) {//拼团时间超时 退款 $virtual = $this->virtualCombination($pinkT['id']); if ($virtual) return 1; $pinkBool = -1; array_push($pinkAll, $pinkT); $oids = array_column($pinkAll, 'order_id_key'); $orders = $orderService->getColumn([['id', 'in', $oids]], '*', 'id'); $refundData = [ 'refund_reason' => '拼团时间超时', 'refund_explain' => '拼团时间超时', 'refund_img' => json_encode([]), ]; foreach ($pinkAll as $v) { if (isset($orders[$v['order_id_key']]) && $order = $orders[$v['order_id_key']]) { $res1 = $res2 = true; if (!in_array($order['refund_status'], [1, 2])) { $res1 = $orderRefundService->applyRefund((int)$order['id'], (int)$order['uid'], $order, [], 1, (float)$order['pay_price'], $refundData, 1); } $res2 = $this->dao->getCount([['uid', '=', $v['uid']], ['is_tpl', '=', 0], ['k_id|id', '=', $pinkT['id']]]); if ($res1 && $res2) { if ($isIds) array_push($pinkIds, $v['id']); $this->orderPinkAfterNo($pinkT['uid'], $pinkT['id'], false, $orders[$v['order_id_key']]['is_channel']); } else { if ($isRunErr) return $pinkBool; } } } } if ($isIds) return $pinkIds; return $pinkBool; } catch (\Exception $e) { return $pinkBool; } } /** * 失败发送消息和修改状态 * @param $uid * @param $pid * @param bool $isRemove * @param $channel * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException */ public function orderPinkAfterNo($uid, $pid, $isRemove = false, $channel) { $pink = $this->dao->getOne([['id|k_id', '=', $pid], ['uid', '=', $uid]], '*', ['getProduct']); if ($isRemove) { event('NoticeListener', [['uid' => $uid, 'pink' => $pink, 'user_type' => $channel], 'send_order_pink_clone']); } else { event('NoticeListener', [['uid' => $uid, 'pink' => $pink, 'user_type' => $channel], 'send_order_pink_fial']); } $this->dao->update([['id|k_id', '=', $pid]], ['status' => 3, 'stop_time' => time()]); } /** * 判断拼团状态 * @param $pinkId * @return bool */ public function isPinkStatus($pinkId) { if (!$pinkId) return false; $stopTime = $this->dao->value(['id' => $pinkId], 'stop_time'); if ($stopTime < time()) return true; //拼团结束 else return false;//拼团未结束 } /** * 获取拼团order_id * @param int $id * @param int $uid * @return mixed */ public function getCurrentPink(int $id, int $uid) { $oid = $this->dao->value(['id' => $id, 'uid' => $uid], 'order_id_key'); if (!$oid) $oid = $this->dao->value(['k_id' => $id, 'uid' => $uid], 'order_id_key'); /** @var StoreOrderServices $orderService */ $orderService = app()->make(StoreOrderServices::class); return $orderService->value(['id' => $oid], 'order_id'); } /** * 拼团成功 * @param $uidAll * @param $idAll * @param $uid * @param $pinkT * @return int */ public function pinkComplete($uidAll, $idAll, $uid, $pinkT) { $pinkBool = 6; try { if (!$this->dao->getCount([['id', 'in', $idAll], ['is_refund', '=', 1]])) { $this->dao->update([['id', 'in', $idAll]], ['stop_time' => time(), 'status' => 2]); if (in_array($uid, $uidAll)) { if ($this->dao->getCount([['uid', 'in', $uidAll], ['is_tpl', '=', 0], ['k_id|id', '=', $pinkT['id']]])) $this->orderPinkAfter($uidAll, $pinkT['id']); $pinkBool = 1; } else $pinkBool = 3; } return $pinkBool; } catch (\Exception $e) { return $pinkBool; } } /** * 拼团成功修改 * @param $uidAll * @param $pid * @return bool * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException */ public function orderPinkAfter($uidAll, $pid) { //发送消息之前去除虚拟用户 foreach ($uidAll as $key => $uid) { if ($uid == 0) unset($uidAll[$key]); } /** @var StoreCombinationServices $storeCombinationServices */ $storeCombinationServices = app()->make(StoreCombinationServices::class); $title = $storeCombinationServices->value(['id' => $this->dao->value(['id' => $pid], 'cid')], 'title'); $pinkList = $this->dao->getColumn([['id|k_id', '=', $pid], ['uid', '<>', 0]], '*', 'uid'); $pinkT_name = $this->dao->value(['id' => $pid], 'nickname'); $order_ids = array_column($pinkList, 'order_id'); /** @var StoreOrderServices $orderService */ $orderService = app()->make(StoreOrderServices::class); $order_channels = $orderService->getColumn([['order_id', 'in', $order_ids]], 'is_channel', 'order_id'); if (!$pinkList) return false; foreach ($pinkList as $item) { $item['nickname'] = $pinkT_name; //用户发送消息 event('NoticeListener', [ [ 'list' => $item, 'title' => $title, 'user_type' => $order_channels[$item['order_id']], 'url' => '/pages/users/order_details/index?order_id=' . $item['order_id'] ], 'order_user_groups_success']); } $this->dao->update([['uid', 'in', $uidAll], ['id|k_id', '=', $pid]], ['is_tpl' => 1]); //拼团卡密和优惠券商品,成团后发放 $orderInfos = $orderService->getColumn([['order_id', 'in', $order_ids]], '*', 'order_id'); foreach ($orderInfos as $orderInfo) { if ($orderInfo['virtual_type'] > 0) { $orderInfo['cart_id'] = json_decode($orderInfo['cart_id'], true); /** @var StoreOrderDeliveryServices $orderDeliveryServices */ $orderDeliveryServices = app()->make(StoreOrderDeliveryServices::class); $orderDeliveryServices->virtualSend($orderInfo); } } return true; } /** * 创建拼团 * @param $order * @return mixed */ public function createPink(array $orderInfo) { /** @var StoreCombinationServices $services */ $services = app()->make(StoreCombinationServices::class); $product = $services->getOne(['id' => $orderInfo['combination_id']], 'effective_time,title,people'); if (!$product) { return false; } /** @var UserServices $userServices */ $userServices = app()->make(UserServices::class); $userInfo = $userServices->get($orderInfo['uid']); if ($orderInfo['pink_id']) { //拼团存在 $res = false; $pink['uid'] = $orderInfo['uid'];//用户id $pink['nickname'] = $userInfo['nickname']; $pink['avatar'] = $userInfo['avatar']; if ($this->isPinkBe($pink, $orderInfo['pink_id'])) return false; $pink['order_id'] = $orderInfo['order_id'];//订单id 生成 $pink['order_id_key'] = $orderInfo['id'];//订单id 数据库id $pink['total_num'] = $orderInfo['total_num'];//购买个数 $pink['total_price'] = $orderInfo['pay_price'];//总金额 $pink['k_id'] = $orderInfo['pink_id'];//拼团id foreach ($orderInfo['cartInfo'] as $v) { $pink['cid'] = $v['combination_id'];//拼团商品id $pink['pid'] = $v['product_id'];//商品id $pink['people'] = $product['people'];//几人拼团 $pink['price'] = $v['productInfo']['price'];//单价 $pink['stop_time'] = 0;//结束时间 $pink['add_time'] = time();//开团时间 $res = $this->save($pink); } // 拼团团成功发送模板消息 event('NoticeListener', [['orderInfo' => $orderInfo, 'title' => $product['title'], 'pink' => $pink], 'can_pink_success']); //处理拼团完成 list($pinkAll, $pinkT, $count, $idAll, $uidAll) = $this->getPinkMemberAndPinkK($pink); if ($pinkT['status'] == 1) { if (!$count)//组团完成 $this->pinkComplete($uidAll, $idAll, $pink['uid'], $pinkT); else $this->pinkFail($pinkAll, $pinkT, 0); } if ($res) return true; else return false; } else { //创建拼团 $res = false; $pink['uid'] = $orderInfo['uid'];//用户id $pink['nickname'] = $userInfo['nickname']; $pink['avatar'] = $userInfo['avatar']; $pink['order_id'] = $orderInfo['order_id'];//订单id 生成 $pink['order_id_key'] = $orderInfo['id'];//订单id 数据库id $pink['total_num'] = $orderInfo['total_num'];//购买个数 $pink['total_price'] = $orderInfo['pay_price'];//总金额 $pink['k_id'] = 0;//拼团id /** @var StoreOrderServices $orderServices */ $orderServices = app()->make(StoreOrderServices::class); foreach ($orderInfo['cartInfo'] as $v) { $pink['cid'] = $v['combination_id'];//拼团商品id $pink['pid'] = $v['product_id'];//商品id $pink['people'] = $product['people'];//几人拼团 $pink['price'] = $v['productInfo']['price'];//单价 $pink['stop_time'] = time() + $product->effective_time * 3600;//结束时间 $pink['add_time'] = time();//开团时间 $res1 = $this->dao->save($pink); $res2 = $orderServices->update($orderInfo['id'], ['pink_id' => $res1['id']]); $res = $res1 && $res2; $pink['id'] = $res1['id']; } PinkJob::dispatchSecs((int)(($product->effective_time * 3600) + 60), [$pink['id']]); // 开团成功发送模板消息 event('NoticeListener', [['orderInfo' => $orderInfo, 'title' => $product['title'], 'pink' => $pink], 'open_pink_success']); if ($res) return true; else return false; } } /** * 是否拼团 * @param array $data * @param int $id * @return int */ public function isPinkBe(array $data, int $id) { $data['id'] = $id; $count = $this->dao->getCount($data); if ($count) return $count; $data['k_id'] = $id; $count = $this->dao->getCount($data); if ($count) return $count; else return 0; } /** * 取消拼团 * @param int $uid * @param int $cid * @param int $pink_id * @param null $nextPinkT * @return bool * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException */ public function removePink(int $uid, int $cid, int $pink_id, $nextPinkT = null) { $pinkT = $this->dao->getOne([ ['uid', '=', $uid], ['id', '=', $pink_id], ['cid', '=', $cid], ['k_id', '=', 0], ['is_refund', '=', 0], ['status', '=', 1], ['stop_time', '>', time()], ]); if (!$pinkT) throw new ApiException(410314); list($pinkAll, $pinkT, $count, $idAll, $uidAll) = $this->getPinkMemberAndPinkK($pinkT); if (count($pinkAll)) { $count = $pinkT['people'] - ($this->dao->count(['k_id' => $pink_id, 'is_refund' => 0]) + 1); if ($count) { //拼团未完成,拼团有成员取消开团取 紧跟团长后拼团的人 if (isset($pinkAll[0])) $nextPinkT = $pinkAll[0]; } else { //拼团完成 $this->PinkComplete($uidAll, $idAll, $uid, $pinkT); throw new ApiException(410316); } } /** @var StoreOrderServices $orderService */ $orderService = app()->make(StoreOrderServices::class); /** @var StoreOrderRefundServices $orderRefundService */ $orderRefundService = app()->make(StoreOrderRefundServices::class); //取消开团 $order = $orderService->get($pinkT['order_id_key']); $refundData = [ 'refund_reason' => '用户手动取消拼团', 'refund_explain' => '用户手动取消拼团', 'refund_img' => json_encode([]), ]; $res1 = $orderRefundService->applyRefund((int)$order['id'], (int)$order['uid'], $order, [], 1, (float)$order['pay_price'], $refundData, 1); $res2 = $this->dao->getCount([['uid', '=', $pinkT['uid']], ['k_id|id', '=', $pinkT['id']]]); if ($res1 && $res2) { $this->orderPinkAfterNo($pinkT['uid'], $pinkT['id'], true, $order->is_channel); } //当前团有人的时候 if (is_array($nextPinkT)) { $this->dao->update($nextPinkT['id'], ['k_id' => 0, 'status' => 1, 'stop_time' => $pinkT['stop_time']]); $this->dao->update($pinkT['id'], ['k_id' => $nextPinkT['id']], 'k_id'); $orderService->update($nextPinkT['order_id'], ['pink_id' => $nextPinkT['id']], 'order_id'); } return true; } /** * 获取拼团海报 * @param $pinkId * @param $from * @param $user * @return string */ public function getPinkPoster($pinkId, $from, $user) { $pinkInfo = $this->dao->get((int)$pinkId); /** @var StoreCombinationServices $combinationService */ $combinationService = app()->make(StoreCombinationServices::class); $storeCombinationInfo = $combinationService->getOne(['id' => $pinkInfo['cid']], '*', ['getPrice']); $data['title'] = $storeCombinationInfo['title']; $data['image'] = $storeCombinationInfo['image']; $data['price'] = $pinkInfo['price']; $data['label'] = $pinkInfo['people'] . '人团'; if ($pinkInfo['k_id']) $pinkAll = $this->getPinkMember($pinkInfo['k_id']); else $pinkAll = $this->getPinkMember($pinkInfo['id']); $count = count($pinkAll); $data['msg'] = '原价¥' . $storeCombinationInfo['product_price'] . ' 还差' . ($pinkInfo['people'] - $count) . '人拼团成功'; /** @var SystemAttachmentServices $systemAttachmentServices */ $systemAttachmentServices = app()->make(SystemAttachmentServices::class); try { $siteUrl = sys_config('site_url'); if ($from == 'routine') { //小程序 $name = $pinkId . '_' . $user['uid'] . '_' . $user['is_promoter'] . '_pink_share_routine.jpg'; $imageInfo = $systemAttachmentServices->getInfo(['name' => $name]); if (!$imageInfo) { $valueData = 'id=' . $pinkId; /** @var UserServices $userServices */ $userServices = app()->make(UserServices::class); if ($userServices->checkUserPromoter((int)$user['uid'], $user)) { $valueData .= '&pid=' . $user['uid']; } $res = MiniProgramService::appCodeUnlimitService($valueData, 'pages/activity/goods_combination_status/index', 280); if (!$res) throw new ApiException(410167); $uploadType = (int)sys_config('upload_type', 1); $upload = UploadService::init(); $res = (string)EntityBody::factory($res); $res = $upload->to('routine/activity/pink/code')->validate()->setAuthThumb(false)->stream($res, $name); if ($res === false) { throw new ApiException($upload->getError()); } $imageInfo = $upload->getUploadInfo(); $imageInfo['image_type'] = $uploadType; if ($imageInfo['image_type'] == 1) $remoteImage = PosterServices::remoteImage($siteUrl . $imageInfo['dir']); else $remoteImage = PosterServices::remoteImage($imageInfo['dir']); if (!$remoteImage['status']) throw new ApiException($remoteImage['msg']); $systemAttachmentServices->save([ 'name' => $imageInfo['name'], 'att_dir' => $imageInfo['dir'], 'satt_dir' => $imageInfo['thumb_path'], 'att_size' => $imageInfo['size'], 'att_type' => $imageInfo['type'], 'image_type' => $imageInfo['image_type'], 'module_type' => 2, 'time' => time(), 'pid' => 1, 'type' => 1 ]); $url = $imageInfo['dir']; } else $url = $imageInfo['att_dir']; $data['url'] = $url; if ($imageInfo['image_type'] == 1) $data['url'] = $siteUrl . $url; $posterImage = PosterServices::setShareMarketingPoster($data, 'routine/activity/pink/poster'); if (!is_array($posterImage)) throw new ApiException(410172); $systemAttachmentServices->save([ 'name' => $posterImage['name'], 'att_dir' => $posterImage['dir'], 'satt_dir' => $posterImage['thumb_path'], 'att_size' => $posterImage['size'], 'att_type' => $posterImage['type'], 'image_type' => $posterImage['image_type'], 'module_type' => 2, 'time' => $posterImage['time'], 'pid' => 1, 'type' => 1 ]); if ($posterImage['image_type'] == 1) $posterImage['dir'] = $siteUrl . $posterImage['dir']; $routinePosterImage = set_http_type($posterImage['dir'], 0);//小程序推广海报 return $routinePosterImage; } else if ($from == 'wechat') { //公众号 $name = $pinkId . '_' . $user['uid'] . '_' . $user['is_promoter'] . '_pink_share_wap.jpg'; $imageInfo = $systemAttachmentServices->getInfo(['name' => $name]); if (!$imageInfo) { $codeUrl = set_http_type($siteUrl . '/pages/activity/goods_combination_status/index?id=' . $pinkId . '&spread=' . $user['uid'], 1);//二维码链接 $imageInfo = PosterServices::getQRCodePath($codeUrl, $name); if (is_string($imageInfo)) { throw new ApiException(410167); } $systemAttachmentServices->save([ 'name' => $imageInfo['name'], 'att_dir' => $imageInfo['dir'], 'satt_dir' => $imageInfo['thumb_path'], 'att_size' => $imageInfo['size'], 'att_type' => $imageInfo['type'], 'image_type' => $imageInfo['image_type'], 'module_type' => 2, 'time' => $imageInfo['time'], 'pid' => 1, 'type' => 1 ]); $url = $imageInfo['dir']; } else $url = $imageInfo['att_dir']; $data['url'] = $url; if ($imageInfo['image_type'] == 1) $data['url'] = $siteUrl . $url; $posterImage = PosterServices::setShareMarketingPoster($data, 'wap/activity/pink/poster'); if (!is_array($posterImage)) throw new ApiException(410172); $systemAttachmentServices->save([ 'name' => $posterImage['name'], 'att_dir' => $posterImage['dir'], 'satt_dir' => $posterImage['thumb_path'], 'att_size' => $posterImage['size'], 'att_type' => $posterImage['type'], 'image_type' => $posterImage['image_type'], 'module_type' => 2, 'time' => $posterImage['time'], 'pid' => 1, 'type' => 1 ]); if ($posterImage['image_type'] == 1) $posterImage['dir'] = $siteUrl . $posterImage['dir']; $wapPosterImage = set_http_type($posterImage['dir'], 1);//公众号推广海报 return $wapPosterImage; } throw new ApiException(100100); } catch (\Exception $e) { throw new ApiException($e->getMessage()); } } /** * 修改到期的拼团状态 * @return bool * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\ModelNotFoundException * @throws \think\exception\DbException */ public function statusPink() { $pinkListEnd = $this->dao->pinkListEnd(); foreach ($pinkListEnd as $key => $pink) { [$pinkAll, $pinkT, $count, $idAll, $uidAll] = $this->getPinkMemberAndPinkK($pink); $this->pinkFail($pinkAll, $pinkT, 0); } return true; } /** * 拼团成功 * @param array $pinkRegimental 成功的团长编号 * @return bool * @throws \Exception */ public function successPinkEdit(array $pinkRegimental) { if (!count($pinkRegimental)) return true; foreach ($pinkRegimental as $key => &$item) { $pinkList = $this->dao->getColumn(['k_id' => $item], 'id', 'id'); $pinkList[] = $item; $pinkList = implode(',', $pinkList); $this->dao->update([['id', 'in', $pinkList]], ['stop_time' => time(), 'status' => 2]); $pinkUidList = $this->dao->getColumn([['id', 'in', $pinkList], ['is_tpl', '=', 0]], 'uid', 'uid'); if (count($pinkUidList)) $this->orderPinkAfter($pinkUidList, $item);//发送模板消息 } return true; } /** * 拼团失败 * @param array $pinkRegimental 失败的团长编号 * @return bool * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\ModelNotFoundException * @throws \think\exception\DbException */ public function failPinkEdit(array $pinkRegimental) { if (!count($pinkRegimental)) return true; foreach ($pinkRegimental as $key => &$item) { $pinkList = $this->dao->getColumn(['k_id' => $item], 'id', 'id'); $pinkList[] = $item; $pinkList = implode(',', $pinkList); $refundPinkList = $this->dao->getColumn([['id', 'in', $pinkList]], 'order_id,uid', 'id'); if ($refundPinkList) { /** @var StoreOrderRefundServices $orderRefundService */ $orderRefundService = app()->make(StoreOrderRefundServices::class); $refundData = [ 'refund_reason' => '拼团时间超时', 'refund_explain' => '拼团时间超时', 'refund_img' => json_encode([]), ]; foreach ($refundPinkList as &$items) { $orderRefundService->applyRefund((int)$items['id'], (int)$items['uid'], $items, [], 1, (float)$items['pay_price'], $refundData, 1);//申请退款 } } $this->dao->update([['id', 'in', $pinkList]], ['status' => 3]); } return true; } /** * 虚拟拼团 * @param $pinkId * @return bool * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException */ public function virtualCombination($pinkId) { $pinkInfo = $this->dao->get($pinkId); $people = $pinkInfo['people']; $count = $this->dao->count(['k_id' => $pinkId]) + 1; $percent1 = bcdiv((string)$count, (string)$people, 2) * 100; /** @var StoreCombinationServices $services */ $services = app()->make(StoreCombinationServices::class); $percent2 = $services->value(['id' => $pinkInfo['cid']], 'virtual'); if ($percent1 >= $percent2) { $time = time(); $num = $people - $count; $data = []; for ($i = 0; $i < $num; $i++) { $data[$i]['uid'] = 0; $data[$i]['nickname'] = substr(md5(time() . rand(1000, 9999)), 0, 12); $data[$i]['avatar'] = sys_config('h5_avatar'); $data[$i]['order_id'] = 0; $data[$i]['order_id_key'] = 0; $data[$i]['total_num'] = 0; $data[$i]['total_price'] = 0; $data[$i]['cid'] = $pinkInfo['cid']; $data[$i]['pid'] = $pinkInfo['pid']; $data[$i]['people'] = $people; $data[$i]['price'] = 0; $data[$i]['add_time'] = $time; $data[$i]['stop_time'] = $time; $data[$i]['k_id'] = $pinkInfo['id']; $data[$i]['is_tpl'] = 1; $data[$i]['is_refund'] = 0; $data[$i]['status'] = 2; $data[$i]['is_virtual'] = 1; } //添加虚拟团员 $this->dao->saveAll($data); //更改团员状态为拼团成功 $this->dao->update($pinkId, ['stop_time' => $time, 'status' => 2], 'k_id'); //更改团长为拼团成功 $this->dao->update($pinkId, ['stop_time' => $time, 'status' => 2]); $uidAll = $this->dao->getColumn([['id|k_id', '=', $pinkId]], 'uid'); $this->orderPinkAfter($uidAll, $pinkId); return true; } else { return false; } } /** * 获取拼团海报详情信息 * @param int $id * @param $user * @return mixed * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException */ public function posterInfo(int $id, $user) { $pinkInfo = $this->dao->get($id); /** @var StoreCombinationServices $combinationService */ $combinationService = app()->make(StoreCombinationServices::class); $storeCombinationInfo = $combinationService->getOne(['id' => $pinkInfo['cid']], '*', ['getPrice']); $data['title'] = $storeCombinationInfo['title']; $data['url'] = ''; $data['image'] = $storeCombinationInfo['image']; $data['price'] = $pinkInfo['price']; $data['label'] = $pinkInfo['people'] . '人团'; if ($pinkInfo['k_id']) $pinkAll = $this->getPinkMember($pinkInfo['k_id']); else $pinkAll = $this->getPinkMember($pinkInfo['id']); $count = count($pinkAll); $data['msg'] = '原价¥' . $storeCombinationInfo['product_price'] . ' 还差' . ($pinkInfo['people'] - $count) . '人拼团成功'; /** @var SystemAttachmentServices $systemAttachmentServices */ $systemAttachmentServices = app()->make(SystemAttachmentServices::class); try { $siteUrl = sys_config('site_url'); if (request()->isRoutine()) { //小程序 $name = $id . '_' . $user['uid'] . '_' . $user['is_promoter'] . '_pink_share_routine.jpg'; $imageInfo = $systemAttachmentServices->getInfo(['name' => $name]); if (!$imageInfo) { $valueData = 'id=' . $id; /** @var UserServices $userServices */ $userServices = app()->make(UserServices::class); if ($userServices->checkUserPromoter((int)$user['uid'], $user)) { $valueData .= '&pid=' . $user['uid']; } $res = MiniProgramService::appCodeUnlimitService($valueData, 'pages/activity/goods_combination_status/index', 280); if (!$res) throw new ApiException(410167); $uploadType = (int)sys_config('upload_type', 1); $upload = UploadService::init(); $res = $upload->to('routine/activity/pink/code')->validate()->setAuthThumb(false)->stream($res, $name); if ($res === false) { throw new ApiException($upload->getError()); } $imageInfo = $upload->getUploadInfo(); $imageInfo['image_type'] = $uploadType; if ($imageInfo['image_type'] == 1) $remoteImage = PosterServices::remoteImage($siteUrl . $imageInfo['dir']); else $remoteImage = PosterServices::remoteImage($imageInfo['dir']); if (!$remoteImage['status']) throw new ApiException($remoteImage['msg']); $systemAttachmentServices->save([ 'name' => $imageInfo['name'], 'att_dir' => $imageInfo['dir'], 'satt_dir' => $imageInfo['thumb_path'], 'att_size' => $imageInfo['size'], 'att_type' => $imageInfo['type'], 'image_type' => $imageInfo['image_type'], 'module_type' => 2, 'time' => time(), 'pid' => 1, 'type' => 1 ]); $url = $imageInfo['dir']; } else $url = $imageInfo['att_dir']; $data['url'] = $url; if ($imageInfo['image_type'] == 1) $data['url'] = $siteUrl . $url; } else { if (sys_config('share_qrcode', 0) && request()->isWechat()) { /** @var QrcodeServices $qrcodeService */ $qrcodeService = app()->make(QrcodeServices::class); $data['url'] = $qrcodeService->getTemporaryQrcode('pink-' . $id, $user['uid'])->url; } } } catch (\Throwable $e) { } return $data; } }