diff --git a/pages.json b/pages.json index 243ba61..9f24204 100644 --- a/pages.json +++ b/pages.json @@ -98,6 +98,10 @@ "path": "pages/merchant/workbench", "style": { "navigationBarTitleText": "商家工作台" } }, + { + "path": "pages/merchant/orders", + "style": { "navigationBarTitleText": "企业订单" } + }, { "path": "pages/merchant/batch", "style": { "navigationBarTitleText": "批量下单" } diff --git a/pages/merchant/orders.vue b/pages/merchant/orders.vue new file mode 100644 index 0000000..74ce3ca --- /dev/null +++ b/pages/merchant/orders.vue @@ -0,0 +1,106 @@ + + + + + diff --git a/pages/merchant/workbench.vue b/pages/merchant/workbench.vue index 10e7225..a4e760d 100644 --- a/pages/merchant/workbench.vue +++ b/pages/merchant/workbench.vue @@ -55,7 +55,7 @@ 近期订单全部 › - + {{ o.service_name }} {{ o.order_no }} · {{ o.time_text }} @@ -106,7 +106,7 @@ const entries = [ { key: 'batch', name: '批量下单', icon: '批', bg: '#FFF1E0', color: '#E07A2E', action: () => go('/pages/merchant/batch') }, - { key: 'orders', name: '企业订单', icon: '单', bg: '#EAF2FF', color: '#4A7CFF', action: () => go('/pages/order/list') }, + { key: 'orders', name: '企业订单', icon: '单', bg: '#EAF2FF', color: '#4A7CFF', action: () => go('/pages/merchant/orders') }, { key: 'invoice', name: '开具发票', icon: '票', bg: '#E8F7EE', color: '#2FA84F', action: () => go('/pages/merchant/invoice') }, { key: 'profile', name: '企业资料', icon: '档', bg: '#F0EBFF', color: '#7A5AF8', action: () => go('/pages/merchant/apply') }, { key: 'address', name: '服务地址', icon: '址', bg: '#FFF0F0', color: '#E8331B', action: () => go('/pages/address/list') }, @@ -114,6 +114,7 @@ ]; function go(url) { uni.navigateTo({ url: url }); } + function goOrder(id) { uni.navigateTo({ url: '/pages/order/detail?id=' + id }); } async function load() { if (!isLogin()) { toLogin(); return; } diff --git a/pages/order/detail.vue b/pages/order/detail.vue index 7a151d7..3a49aba 100644 --- a/pages/order/detail.vue +++ b/pages/order/detail.vue @@ -3,6 +3,7 @@ {{ order.status_text }} {{ statusTip }} + 商家账号查看 · 仅查看,操作请由下单账号完成 @@ -86,10 +87,10 @@ - 取消订单 - 去支付 - 确认验收 - 去评价 + 取消订单 + 去支付 + 确认验收 + 去评价 返回首页 @@ -115,6 +116,7 @@ const canChoose = computed(() => { return !!(order.value && order.value.price_type === 'quote' && Number(order.value.status) === 2 && Number(order.value.master_id) === 0 + && order.value.is_order_owner !== false && quotes.value.some(q => q.status === 'wait')); }); diff --git a/server/application/api/controller/Merchant.php b/server/application/api/controller/Merchant.php index 52384ba..7c8a244 100644 --- a/server/application/api/controller/Merchant.php +++ b/server/application/api/controller/Merchant.php @@ -171,6 +171,58 @@ class Merchant extends Base $this->success('', ['months' => $months, 'orders' => $orders]); } + /** + * 企业订单:主账号 + 关联账号的全部订单 + */ + public function orders() + { + $merchant = $this->requireMerchant(); + $uids = $this->merchantUserIds($merchant); + $status = $this->request->param('status', 'all'); + $page = max(1, (int)$this->request->param('page', 1)); + $limit = min(50, max(1, (int)$this->request->param('limit', 20))); + + $build = function () use ($uids, $status) { + $q = Db::name('order')->where('user_id', 'in', $uids); + if ($status === 'active') { + $q->where('status', 'in', \app\common\library\OrderStatus::activeValues()); + } elseif ($status === 'completed') { + $q->where('status', \app\common\library\OrderStatus::COMPLETED); + } elseif ($status === 'cancelled') { + $q->where('status', \app\common\library\OrderStatus::CANCELLED); + } elseif ($status !== 'all' && $status !== '') { + $q->where('status', (int)$status); + } + return $q; + }; + + $total = $build()->count(); + $rows = $build()->order('id desc')->page($page, $limit)->select(); + $userMap = Db::name('user')->where('id', 'in', $uids)->column('id,nickname,mobile', 'id'); + + foreach ($rows as &$row) { + $ownerUser = (int)$row['user_id'] === (int)$merchant['user_id']; + $u = isset($userMap[(int)$row['user_id']]) ? $userMap[(int)$row['user_id']] : null; + $mobile = $u ? (string)$u['mobile'] : ''; + $row['pay_amount'] = (float)$row['pay_amount']; + $row['urgent'] = (int)$row['urgent']; + $row['status_text'] = \app\common\library\OrderStatus::label((int)$row['status']); + $row['appoint_text'] = $row['appoint_time'] ? date('m-d H:i', (int)$row['appoint_time']) : '尽快上门'; + $row['create_text'] = date('Y-m-d H:i', (int)$row['createtime']); + $row['address_text'] = $row['province'] . $row['city'] . $row['district'] . $row['address']; + $row['account_name'] = $u && $u['nickname'] ? $u['nickname'] : ('用户' . substr($mobile, -4)); + $row['account_role'] = $ownerUser ? 'owner' : 'member'; + $row['account_role_text'] = $ownerUser ? '主账号' : '关联账号'; + } + unset($row); + + $this->success('', [ + 'list' => $rows, + 'total' => (int)$total, + 'page' => $page, + ]); + } + /** * 开票记录 */ diff --git a/server/application/api/controller/Order.php b/server/application/api/controller/Order.php index fa66ff5..14a0e98 100644 --- a/server/application/api/controller/Order.php +++ b/server/application/api/controller/Order.php @@ -216,7 +216,20 @@ class Order extends Base public function detail() { $orderId = (int)$this->request->param('id'); - $order = $this->ownOrder($orderId, 'user'); + if ($orderId <= 0) { + $this->error('订单参数错误'); + } + $order = Db::name('order')->where('id', $orderId)->find(); + if (!$order) { + $this->error('订单不存在'); + } + // 本人订单,或同一商家(主账号 + 关联账号)的订单 + if ((int)$order['user_id'] !== $this->uid()) { + $uids = $this->currentMerchantUserIds(); + if (!in_array((int)$order['user_id'], $uids, true)) { + $this->error('无权操作该订单', null, 403); + } + } $logs = Db::name('order_log')->where('order_id', $orderId)->order('id asc')->select(); foreach ($logs as &$log) { @@ -531,9 +544,36 @@ class Order extends Base 'create_text' => date('Y-m-d H:i', (int)$row['createtime']), 'urgent' => (int)$row['urgent'], 'price_type_text' => $this->priceTypeText($row['price_type']), + 'is_order_owner' => (int)$row['user_id'] === $this->uid(), ]); } + /** + * 当前用户所属商家的全部账号(主账号 + 关联账号) + */ + protected function currentMerchantUserIds() + { + $merchant = Db::name('merchant')->where('user_id', $this->uid())->find(); + if (!$merchant) { + $bind = Db::name('merchant_member')->where('user_id', $this->uid())->find(); + if ($bind) { + $merchant = Db::name('merchant')->where('id', (int)$bind['merchant_id'])->find(); + } + } + if (!$merchant) { + return []; + } + $ids = [(int)$merchant['user_id']]; + $rows = Db::name('merchant_member')->where('merchant_id', (int)$merchant['id'])->column('user_id'); + foreach ($rows as $id) { + $id = (int)$id; + if ($id > 0 && !in_array($id, $ids, true)) { + $ids[] = $id; + } + } + return $ids; + } + /** * 计价方式文案(前后端与后台统一口径) */ diff --git a/utils/api.js b/utils/api.js index 50628f2..5549198 100644 --- a/utils/api.js +++ b/utils/api.js @@ -74,6 +74,7 @@ export default { merchantInfo: () => get('/merchant/info'), merchantUpdate: (data) => post('/merchant/update', data), merchantBills: () => get('/merchant/bills'), + merchantOrders: (data) => get('/merchant/orders', data), merchantInvoices: () => get('/merchant/invoices'), merchantInvoice: (data) => post('/merchant/invoice', data), merchantMembers: () => get('/merchant/members'),