model = new \app\admin\model\Merchant; $this->view->assign("settleTypeList", $this->model->getSettleTypeList()); $this->view->assign("verifyStatusList", $this->model->getVerifyStatusList()); } public function index() { $this->request->filter(['strip_tags', 'trim']); if (false === $this->request->isAjax()) { return $this->view->fetch(); } if ($this->request->request('keyField')) { return $this->selectpage(); } [$where, $sort, $order, $offset, $limit] = $this->buildparams(); $list = $this->model ->with(['user']) ->where($where) ->order($sort, $order) ->paginate($limit); $rows = $list->items(); if (!empty($rows)) { $mIds = array_column($rows, 'id'); // 1. 查询子账号归属映射 $members = Db::name('merchant_member')->where('merchant_id', 'in', $mIds)->select(); $mUidsMap = []; $memberCntMap = []; foreach ($rows as $r) { $mid = (int)$r['id']; $mUidsMap[$mid] = (int)$r['user_id'] > 0 ? [(int)$r['user_id']] : []; $memberCntMap[$mid] = 0; } foreach ($members as $mb) { $mid = (int)$mb['merchant_id']; $uid = (int)$mb['user_id']; $memberCntMap[$mid] = ($memberCntMap[$mid] ?? 0) + 1; if ($uid > 0 && !in_array($uid, $mUidsMap[$mid], true)) { $mUidsMap[$mid][] = $uid; } } // 2. 汇总所有可能关联订单(通过 merchant_order 或商户主/子账号下单) $allUids = []; foreach ($mUidsMap as $uArr) { foreach ($uArr as $u) { $allUids[$u] = $u; } } $moRows = Db::name('merchant_order')->where('merchant_id', 'in', $mIds)->select(); $moOrderIds = array_column($moRows, 'order_id'); $orderToMid = []; foreach ($moRows as $mo) { $orderToMid[(int)$mo['order_id']] = (int)$mo['merchant_id']; } $uidToMid = []; foreach ($mUidsMap as $mid => $uArr) { foreach ($uArr as $u) { $uidToMid[$u] = $mid; } } $orderQuery = Db::name('order')->field('id,user_id,pay_amount,pay_status,status'); if (!empty($allUids) && !empty($moOrderIds)) { $orderQuery->where(function ($q) use ($allUids, $moOrderIds) { $q->where('user_id', 'in', array_values($allUids)) ->whereOr('id', 'in', $moOrderIds); }); $relOrders = $orderQuery->select(); } elseif (!empty($allUids)) { $relOrders = $orderQuery->where('user_id', 'in', array_values($allUids))->select(); } elseif (!empty($moOrderIds)) { $relOrders = $orderQuery->where('id', 'in', $moOrderIds)->select(); } else { $relOrders = []; } $statCnt = []; $statAmt = []; foreach ($relOrders as $ord) { $oid = (int)$ord['id']; $mid = $orderToMid[$oid] ?? ($uidToMid[(int)$ord['user_id']] ?? 0); if ($mid <= 0) continue; $statCnt[$mid] = ($statCnt[$mid] ?? 0) + 1; if ((int)$ord['pay_status'] === 1 && (int)$ord['status'] !== 9) { $statAmt[$mid] = round(($statAmt[$mid] ?? 0) + (float)$ord['pay_amount'], 2); } } foreach ($rows as &$r) { $mid = (int)$r['id']; $r['order_count'] = $statCnt[$mid] ?? (int)$r['order_count']; $r['total_amount'] = isset($statAmt[$mid]) ? number_format($statAmt[$mid], 2, '.', '') : number_format((float)$r['total_amount'], 2, '.', ''); $r['member_count'] = $memberCntMap[$mid] ?? 0; } unset($r); } return json(['total' => $list->total(), 'rows' => $rows]); } /** * 新增合作企业档案(防重复绑定同一用户,审核通过自动同步默认企业发票抬头) */ public function add() { if (false === $this->request->isPost()) { return $this->view->fetch(); } $params = $this->request->post('row/a', []); if (!$params) { $this->error(__('Parameter %s can not be empty', '')); } $params = $this->preExcludeFields($params); $uid = (int)($params['user_id'] ?? 0); if ($uid <= 0) { $this->error('请选择关联的平台注册用户账号'); } if (Db::name('merchant')->where('user_id', $uid)->count() > 0) { $this->error('该用户账号已绑定企业商家主体,请勿重复创建'); } $params['order_count'] = 0; $params['total_amount'] = 0.00; if (($params['verify_status'] ?? '') === 'reject' && empty(trim((string)($params['audit_msg'] ?? '')))) { $this->error('驳回企业入驻时请填写审核驳回原因'); } $result = false; Db::startTrans(); try { $result = $this->model->allowField(true)->save($params); if (($params['verify_status'] ?? '') === 'pass' && $uid > 0) { $ctx = InvoiceService::resolveContext($uid); InvoiceService::ensureMerchantDefaultTitle($ctx); } Db::commit(); } catch (Exception $e) { Db::rollback(); $this->error($e->getMessage()); } if ($result !== false) { $this->success(); } $this->error($this->model->getError() ?: __('No rows were inserted')); } /** * 删除保护:已产生企业批次订单或开票记录的商户禁止物理删除 */ public function del($ids = null) { if (false === $this->request->isPost()) { $this->error(__('Invalid parameters')); } $ids = $ids ?: $this->request->post('ids'); $idArr = array_values(array_filter(array_map('intval', explode(',', (string)$ids)))); if (!$idArr) { $this->error(__('Parameter %s can not be empty', 'ids')); } $hasOrder = Db::name('merchant_order')->where('merchant_id', 'in', $idArr)->count(); $hasInvoice = Db::name('invoice')->where('merchant_id', 'in', $idArr)->count(); if ($hasOrder > 0 || $hasInvoice > 0) { $this->error('所选企业已关联历史发包订单或开票记录,禁止物理删除'); } Db::startTrans(); try { Db::name('merchant_member')->where('merchant_id', 'in', $idArr)->delete(); $deleted = Db::name('merchant')->where('id', 'in', $idArr)->delete(); Db::commit(); } catch (Exception $e) { Db::rollback(); $this->error($e->getMessage()); } if ($deleted) { $this->success(); } $this->error(__('No rows were deleted')); } /** * 编辑企业档案与入驻审核(审核通过自动同步企业默认发票抬头并发送通知) */ public function edit($ids = null) { $row = $this->model->get($ids); if (!$row) { $this->error(__('No Results were found')); } $oldVerify = (string)$row['verify_status']; if ($this->request->isPost()) { $params = $this->request->post("row/a"); if ($params) { $params = $this->preExcludeFields($params); unset($params['order_count'], $params['total_amount']); if (isset($params['city']) && trim((string)$params['city']) === '' && !empty($row['city'])) { unset($params['city']); } if (isset($params['verify_status']) && $params['verify_status'] === 'reject' && empty(trim((string)($params['audit_msg'] ?? '')))) { $this->error('驳回企业入驻时请填写审核驳回原因'); } $result = false; Db::startTrans(); try { $result = $row->allowField(true)->save($params); $newVerify = isset($params['verify_status']) ? (string)$params['verify_status'] : $oldVerify; if ($newVerify !== $oldVerify && in_array($newVerify, ['pass', 'reject'], true)) { if ($newVerify === 'pass' && (int)$row['user_id'] > 0) { $ctx = InvoiceService::resolveContext((int)$row['user_id']); InvoiceService::ensureMerchantDefaultTitle($ctx); } if ((int)$row['user_id'] > 0) { Db::name('message')->insert([ 'receive_type' => 'user', 'receive_id' => (int)$row['user_id'], 'type' => 'audit', 'title' => $newVerify === 'pass' ? '企业商家认证已通过' : '企业商家认证未通过', 'content' => $newVerify === 'pass' ? ('您提交的企业【' . $row['name'] . '】资质审核已通过,现可使用商家工作台批量派单与开票服务。') : ('企业【' . $row['name'] . '】资质审核未通过,原因:' . (trim((string)($params['audit_msg'] ?? '')) ?: '请核对营业执照信息后重新提交')), 'order_id' => 0, 'is_read' => 0, 'createtime' => time(), ]); } } Db::commit(); } catch (Exception $e) { Db::rollback(); $this->error($e->getMessage()); } if ($result !== false) { $this->success(); } $this->error(__('No rows were updated')); } $this->error(__('Parameter %s can not be empty', '')); } $this->view->assign("row", $row); return $this->view->fetch(); } /** * 商户企业全景资质与业务协同看板 */ public function detail($ids = null) { $row = $this->model->with(['user'])->where('merchant.id', (int)$ids)->find(); if (!$row) { $this->error(__('No Results were found')); } $mid = (int)$row['id']; $uids = (int)$row['user_id'] > 0 ? [(int)$row['user_id']] : []; // 1. 企业员工协同子账号 $members = Db::name('merchant_member') ->alias('mm') ->join('user u', 'u.id = mm.user_id', 'LEFT') ->where('mm.merchant_id', $mid) ->field('mm.*, u.nickname, u.username, u.mobile') ->order('mm.id desc') ->select(); foreach ($members as $mb) { if ((int)$mb['user_id'] > 0 && !in_array((int)$mb['user_id'], $uids, true)) { $uids[] = (int)$mb['user_id']; } } // 2. 商户关联工单统计与最近列表(兼容 merchant_order 与账号下单) $moOrderIds = Db::name('merchant_order')->where('merchant_id', $mid)->column('order_id'); $buildOrderScope = function ($q) use ($uids, $moOrderIds) { if (!empty($uids) && !empty($moOrderIds)) { $q->where('o.user_id', 'in', $uids)->whereOr('o.id', 'in', $moOrderIds); } elseif (!empty($uids)) { $q->where('o.user_id', 'in', $uids); } elseif (!empty($moOrderIds)) { $q->where('o.id', 'in', $moOrderIds); } else { $q->where('o.id', 0); } }; $orderAgg = Db::name('order')->alias('o') ->field('COUNT(*) AS total_cnt, SUM(CASE WHEN o.pay_status = 1 AND o.status <> 9 THEN o.pay_amount ELSE 0 END) AS total_gmv') ->where($buildOrderScope) ->find(); $statusMap = (new \app\admin\model\Order)->getStatusList(); $recentOrders = Db::name('order')->alias('o') ->join('master m', 'm.id = o.master_id', 'LEFT') ->join('merchant_order mo', 'mo.order_id = o.id', 'LEFT') ->where($buildOrderScope) ->field('o.*, m.realname as master_name, mo.batch_no') ->order('o.id desc') ->limit(8) ->select(); foreach ($recentOrders as &$o) { $o['status_label'] = $statusMap[(int)$o['status']] ?? ('状态' . $o['status']); } unset($o); // 3. 关联发票抬头与历史开票记录 $titleList = Db::name('invoice_title') ->where(function ($q) use ($mid, $uids) { $q->where('merchant_id', $mid); if (!empty($uids)) { $q->whereOr('user_id', 'in', $uids); } }) ->order('is_default desc, id desc') ->select(); $invoiceList = Db::name('invoice') ->where(function ($q) use ($mid, $uids) { $q->where('merchant_id', $mid); if (!empty($uids)) { $q->whereOr('user_id', 'in', $uids); } }) ->order('id desc') ->limit(6) ->select(); $this->view->assign([ 'row' => $row, 'members' => $members, 'recentOrders' => $recentOrders, 'titleList' => $titleList, 'invoiceList' => $invoiceList, 'orderCount' => (int)($orderAgg['total_cnt'] ?? 0), 'orderGmv' => number_format((float)($orderAgg['total_gmv'] ?? 0), 2, '.', ''), ]); return $this->view->fetch(); } }