From 375bc7af2052d44e93b0d3be0647853565549ed4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8F=AF=E4=B9=90=E5=8A=A0=E5=86=B0?= <11869599+addie66@user.noreply.gitee.com> Date: Tue, 29 Sep 2026 15:47:22 +0800 Subject: [PATCH] =?UTF-8?q?```=E5=90=8E=E5=8F=B0:=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E6=90=9C=E7=B4=A2=E5=8A=9F=E8=83=BD=E5=B9=B6?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=BF=9B=E4=BB=B6=E9=A1=B5=E9=9D=A2UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在Onboard控制器中添加searchUser方法,支持按昵称、手机号、ID搜索用户 - 修改noNeedRight权限配置,添加searchUser访问权限 - 重构用户选择逻辑,使用新的fetchUserPublic和formatUserOption方法 - 实现用户搜索功能,支持关键词模糊匹配并返回格式化的用户选项 - 优化前端页面样式,采用卡片式布局提升用户体验 - 添加用户头像显示和个人信息展示功能 - 调整页面结构,增加标题栏、底部操作栏等组件 ``` --- .../admin/controller/shopro_huifu/Onboard.php | 19 +- .../admin/view/shopro_huifu/onboard/add.html | 539 ++++++++++++------ .../library/onboard/HuifuOnboardAdminView.php | 108 +++- .../assets/js/backend/shopro_huifu/onboard.js | 42 +- .../admin/controller/shopro_huifu/Onboard.php | 19 +- .../admin/view/shopro_huifu/onboard/add.html | 539 ++++++++++++------ .../assets/js/backend/shopro_huifu/onboard.js | 42 +- 7 files changed, 949 insertions(+), 359 deletions(-) diff --git a/addons/shopro_huifu/application/admin/controller/shopro_huifu/Onboard.php b/addons/shopro_huifu/application/admin/controller/shopro_huifu/Onboard.php index b128ba4..75255c3 100644 --- a/addons/shopro_huifu/application/admin/controller/shopro_huifu/Onboard.php +++ b/addons/shopro_huifu/application/admin/controller/shopro_huifu/Onboard.php @@ -13,7 +13,7 @@ use app\admin\controller\shopro\Base; class Onboard extends Base { - protected $noNeedRight = ['userRoles', 'searchBranch']; + protected $noNeedRight = ['userRoles', 'searchUser', 'searchBranch']; public function index() { @@ -106,17 +106,22 @@ class Onboard extends Base if ($userId <= 0) { $this->error('请选择用户'); } - $user = HuifuOnboardAdminView::enrichListRow(['user_id' => $userId, 'payload' => '']); + $userRow = HuifuOnboardAdminView::fetchUserPublic($userId); $this->success('ok', null, [ - 'user' => [ - 'id' => $userId, - 'nickname' => $user['user_nickname'] ?? '', - 'mobile' => $user['user_mobile'] ?? '', - ], + 'user' => HuifuOnboardAdminView::formatUserOption($userRow), 'roles' => HuifuOnboardAdminView::listRolesForUser($userId), ]); } + public function searchUser() + { + $keyword = trim((string) $this->request->get('keyword', '')); + if ($keyword === '') { + $this->success('ok', null, []); + } + $this->success('ok', null, HuifuOnboardAdminView::searchUsers($keyword, intval($this->request->get('limit', 20)))); + } + public function searchBranch() { $keyword = trim((string) $this->request->get('keyword', '')); diff --git a/addons/shopro_huifu/application/admin/view/shopro_huifu/onboard/add.html b/addons/shopro_huifu/application/admin/view/shopro_huifu/onboard/add.html index 18f46cd..4725a11 100644 --- a/addons/shopro_huifu/application/admin/view/shopro_huifu/onboard/add.html +++ b/addons/shopro_huifu/application/admin/view/shopro_huifu/onboard/add.html @@ -1,180 +1,391 @@
- -
用户与角色
- - - - - - - {{ userLabel }} - - - - - {{ item.role_label }} - {{ item.disabled_reason || (item.onboard_status ? '已有记录:' + item.onboard_status : '新建') }} - - - - - {{ roleLabel }} - - -
账户类型
- - - 个人 - 个体户/企业 - - - - - 对私 - 对公 - - - - - - - -
结算账户信息
- - - - - -
已选:{{ form.branch_name }}({{ form.branch_code }})
-
-
-
{{ item.branch_name }}
-
{{ item.branch_code }}
-
+ + + {{ userLabel }} + + + + + {{ item.role_label }} + {{ item.disabled_reason || (item.onboard_status ? '已有记录:' + item.onboard_status : '新建') }} + + + + + {{ roleLabel }} +
-
- - - - - -
点击上传
-
-
建议上传,可加快审核
-
- - -
点击上传
-
-
- - {{ isEdit ? '保存修改' : '保存进件资料' }} - 取消 - -
+
+
账户类型
+ + + 个人 + 个体户/企业 + + + + + 对私 + 对公 + + +
+ + + + + +
+
结算账户信息
+ + + + + + + + + + + + + + +
已选:{{ form.branch_name }}({{ form.branch_code }})
+
+
+
{{ item.branch_name }}
+
{{ item.branch_code }}
+
+
+
+
+
+ + +
点击上传
+
+
建议上传,可加快审核
+
+ + +
点击上传
+
+
+
+ +
+ diff --git a/addons/shopro_huifu/library/onboard/HuifuOnboardAdminView.php b/addons/shopro_huifu/library/onboard/HuifuOnboardAdminView.php index fa27a94..45e4de5 100644 --- a/addons/shopro_huifu/library/onboard/HuifuOnboardAdminView.php +++ b/addons/shopro_huifu/library/onboard/HuifuOnboardAdminView.php @@ -94,6 +94,11 @@ class HuifuOnboardAdminView ]; } + public static function fetchUserPublic($userId) + { + return self::fetchUser($userId); + } + protected static function fetchUser($userId) { $userId = intval($userId); @@ -101,12 +106,113 @@ class HuifuOnboardAdminView return []; } try { - return Db::name('user')->where('id', $userId)->field('id,nickname,mobile,avatar')->find() ?: []; + return Db::name('user')->where('id', $userId)->field('id,nickname,username,mobile,avatar')->find() ?: []; } catch (\Throwable $e) { return []; } } + /** + * 后台进件:搜索可选用户(下拉展示昵称/实名/手机/ID) + */ + public static function searchUsers($keyword, $limit = 20) + { + $keyword = trim((string) $keyword); + if ($keyword === '') { + return []; + } + $limit = max(1, min(50, intval($limit))); + $idKeyword = is_numeric($keyword) ? intval($keyword) : 0; + $query = Db::name('user')->where(function ($q) use ($keyword, $idKeyword) { + if ($idKeyword > 0) { + $q->whereOr('id', '=', $idKeyword); + } + $q->whereOr('nickname', 'like', "%{$keyword}%") + ->whereOr('mobile', 'like', "%{$keyword}%") + ->whereOr('username', 'like', "%{$keyword}%"); + }); + $list = $query->field('id,nickname,username,mobile,avatar')->order('id desc')->limit($limit)->select(); + $rows = []; + foreach ($list as $user) { + $rows[] = self::formatUserOption($user); + } + return $rows; + } + + public static function formatUserOption($user) + { + $user = is_array($user) ? $user : (method_exists($user, 'toArray') ? $user->toArray() : []); + $id = intval($user['id'] ?? 0); + if ($id <= 0) { + return []; + } + $nickname = trim((string) ($user['nickname'] ?? '')); + $username = trim((string) ($user['username'] ?? '')); + $mobile = trim((string) ($user['mobile'] ?? '')); + $avatar = self::fullUrl($user['avatar'] ?? ''); + $realName = self::fetchUserRealNameHint($id); + $displayName = self::resolveUserDisplayName($id, $nickname, $username, $realName); + + return [ + 'id' => $id, + 'nickname' => $nickname, + 'username' => $username, + 'mobile' => $mobile, + 'avatar' => $avatar, + 'display_name' => $displayName, + 'real_name' => $realName, + 'option_label' => self::buildUserOptionLabel($displayName, $realName, $mobile, $id), + ]; + } + + protected static function resolveUserDisplayName($id, $nickname, $username, $realName = '') + { + if ($nickname !== '' && $nickname !== (string) $id) { + return $nickname; + } + if ($username !== '' && $username !== (string) $id) { + return $username; + } + if ($realName !== '') { + return $realName; + } + if ($nickname !== '') { + return $nickname; + } + return '用户' . $id; + } + + protected static function fetchUserRealNameHint($userId) + { + $userId = intval($userId); + if ($userId <= 0) { + return ''; + } + try { + $row = Db::name('shopro_huifu_onboard')->where('user_id', $userId)->order('id desc')->find(); + if (!$row) { + return ''; + } + $payload = self::parsePayload($row['payload'] ?? ''); + return trim((string) ($payload['name'] ?? $payload['legal_name'] ?? $payload['reg_name'] ?? '')); + } catch (\Throwable $e) { + return ''; + } + } + + protected static function buildUserOptionLabel($displayName, $realName, $mobile, $id) + { + $parts = [$displayName]; + if ($realName !== '' && $realName !== $displayName) { + $parts[] = '实名:' . $realName; + } + if ($mobile !== '') { + $parts[] = $mobile; + } + $parts[] = 'ID:' . $id; + return implode(' · ', $parts); + } + protected static function businessStatus(array $data) { $roleType = $data['role_type'] ?? ''; diff --git a/addons/shopro_huifu/public/assets/js/backend/shopro_huifu/onboard.js b/addons/shopro_huifu/public/assets/js/backend/shopro_huifu/onboard.js index 86f7735..38c710f 100644 --- a/addons/shopro_huifu/public/assets/js/backend/shopro_huifu/onboard.js +++ b/addons/shopro_huifu/public/assets/js/backend/shopro_huifu/onboard.js @@ -82,6 +82,7 @@ define(['jquery', 'bootstrap', 'backend'], function ($, undefined, Backend) { roleLabel: '', userOptions: [], userLoading: false, + selectedUser: null, roleOptions: [], form: defaultForm(), regionPath: [], @@ -160,16 +161,34 @@ define(['jquery', 'bootstrap', 'backend'], function ($, undefined, Backend) { this.form.area_id = this.form.shopro_city_id; this.form.district_id = this.form.shopro_district_id; }, + userAvatarText: function (item) { + if (!item) return '?'; + var name = item.display_name || item.nickname || ''; + return name ? name.slice(0, 1) : '?'; + }, + applySelectedUser: function (user) { + if (!user || !user.id) { + this.selectedUser = null; + this.userLabel = ''; + return; + } + this.selectedUser = user; + this.userLabel = user.option_label || (user.display_name + ' (' + (user.mobile || user.id) + ')'); + }, searchUser: function (keyword) { - if (!keyword) return; + keyword = (keyword || '').trim(); + if (!keyword) { + this.userOptions = []; + return; + } var vm = this; vm.userLoading = true; Fast.api.ajax({ - url: 'shopro/user/user/index', + url: 'shopro_huifu/onboard/searchUser', type: 'GET', - data: { offset: 0, limit: 20, searchWhere: keyword } + data: { keyword: keyword, limit: 20 } }, function (ret, res) { - vm.userOptions = (res.data && res.data.rows) || []; + vm.userOptions = res.data || []; vm.userLoading = false; return false; }, function () { @@ -182,7 +201,14 @@ define(['jquery', 'bootstrap', 'backend'], function ($, undefined, Backend) { vm.roleType = ''; vm.roleRefId = 0; vm.roleOptions = []; - if (!vm.userId) return; + if (!vm.userId) { + vm.applySelectedUser(null); + return; + } + var cached = vm.userOptions.find(function (item) { return item.id === vm.userId; }); + if (cached) { + vm.applySelectedUser(cached); + } Fast.api.ajax({ url: 'shopro_huifu/onboard/userRoles', type: 'GET', @@ -191,7 +217,7 @@ define(['jquery', 'bootstrap', 'backend'], function ($, undefined, Backend) { var data = res.data || {}; vm.roleOptions = data.roles || []; if (data.user) { - vm.userLabel = (data.user.nickname || '') + ' (' + (data.user.mobile || data.user.id) + ')'; + vm.applySelectedUser(data.user); } return false; }); @@ -311,7 +337,7 @@ define(['jquery', 'bootstrap', 'backend'], function ($, undefined, Backend) { openCreate: function () { var vm = this; Backend.api.open('shopro_huifu/onboard/add', '新建汇付进件', { - area: ['900px', '90%'], + area: ['960px', '92%'], callback: function () { vm.getList(); } @@ -320,7 +346,7 @@ define(['jquery', 'bootstrap', 'backend'], function ($, undefined, Backend) { openEdit: function (id) { var vm = this; Backend.api.open('shopro_huifu/onboard/edit/ids/' + id, '编辑汇付进件', { - area: ['900px', '90%'], + area: ['960px', '92%'], callback: function () { vm.getList(); if (vm.detailVisible && vm.detailId === id) { diff --git a/application/admin/controller/shopro_huifu/Onboard.php b/application/admin/controller/shopro_huifu/Onboard.php index ea3d062..8b01b96 100644 --- a/application/admin/controller/shopro_huifu/Onboard.php +++ b/application/admin/controller/shopro_huifu/Onboard.php @@ -13,7 +13,7 @@ use app\admin\controller\shopro\Base; class Onboard extends Base { - protected $noNeedRight = ['userRoles', 'searchBranch']; + protected $noNeedRight = ['userRoles', 'searchUser', 'searchBranch']; public function index() { if ($this->request->isAjax()) { @@ -108,17 +108,22 @@ class Onboard extends Base if ($userId <= 0) { $this->error('请选择用户'); } - $user = HuifuOnboardAdminView::enrichListRow(['user_id' => $userId, 'payload' => '']); + $userRow = HuifuOnboardAdminView::fetchUserPublic($userId); $this->success('ok', null, [ - 'user' => [ - 'id' => $userId, - 'nickname' => $user['user_nickname'] ?? '', - 'mobile' => $user['user_mobile'] ?? '', - ], + 'user' => HuifuOnboardAdminView::formatUserOption($userRow), 'roles' => HuifuOnboardAdminView::listRolesForUser($userId), ]); } + public function searchUser() + { + $keyword = trim((string) $this->request->get('keyword', '')); + if ($keyword === '') { + $this->success('ok', null, []); + } + $this->success('ok', null, HuifuOnboardAdminView::searchUsers($keyword, intval($this->request->get('limit', 20)))); + } + public function searchBranch() { $keyword = trim((string) $this->request->get('keyword', '')); diff --git a/application/admin/view/shopro_huifu/onboard/add.html b/application/admin/view/shopro_huifu/onboard/add.html index 18f46cd..4725a11 100644 --- a/application/admin/view/shopro_huifu/onboard/add.html +++ b/application/admin/view/shopro_huifu/onboard/add.html @@ -1,180 +1,391 @@
- -
用户与角色
- - - - - - - {{ userLabel }} - - - - - {{ item.role_label }} - {{ item.disabled_reason || (item.onboard_status ? '已有记录:' + item.onboard_status : '新建') }} - - - - - {{ roleLabel }} - - -
账户类型
- - - 个人 - 个体户/企业 - - - - - 对私 - 对公 - - - - - - - -
结算账户信息
- - - - - -
已选:{{ form.branch_name }}({{ form.branch_code }})
-
-
-
{{ item.branch_name }}
-
{{ item.branch_code }}
-
+ + + {{ userLabel }} + + + + + {{ item.role_label }} + {{ item.disabled_reason || (item.onboard_status ? '已有记录:' + item.onboard_status : '新建') }} + + + + + {{ roleLabel }} +
-
- - - - - -
点击上传
-
-
建议上传,可加快审核
-
- - -
点击上传
-
-
- - {{ isEdit ? '保存修改' : '保存进件资料' }} - 取消 - -
+
+
账户类型
+ + + 个人 + 个体户/企业 + + + + + 对私 + 对公 + + +
+ + + + + +
+
结算账户信息
+ + + + + + + + + + + + + + +
已选:{{ form.branch_name }}({{ form.branch_code }})
+
+
+
{{ item.branch_name }}
+
{{ item.branch_code }}
+
+
+
+
+
+ + +
点击上传
+
+
建议上传,可加快审核
+
+ + +
点击上传
+
+
+
+ +
+ diff --git a/public/assets/js/backend/shopro_huifu/onboard.js b/public/assets/js/backend/shopro_huifu/onboard.js index 86f7735..38c710f 100644 --- a/public/assets/js/backend/shopro_huifu/onboard.js +++ b/public/assets/js/backend/shopro_huifu/onboard.js @@ -82,6 +82,7 @@ define(['jquery', 'bootstrap', 'backend'], function ($, undefined, Backend) { roleLabel: '', userOptions: [], userLoading: false, + selectedUser: null, roleOptions: [], form: defaultForm(), regionPath: [], @@ -160,16 +161,34 @@ define(['jquery', 'bootstrap', 'backend'], function ($, undefined, Backend) { this.form.area_id = this.form.shopro_city_id; this.form.district_id = this.form.shopro_district_id; }, + userAvatarText: function (item) { + if (!item) return '?'; + var name = item.display_name || item.nickname || ''; + return name ? name.slice(0, 1) : '?'; + }, + applySelectedUser: function (user) { + if (!user || !user.id) { + this.selectedUser = null; + this.userLabel = ''; + return; + } + this.selectedUser = user; + this.userLabel = user.option_label || (user.display_name + ' (' + (user.mobile || user.id) + ')'); + }, searchUser: function (keyword) { - if (!keyword) return; + keyword = (keyword || '').trim(); + if (!keyword) { + this.userOptions = []; + return; + } var vm = this; vm.userLoading = true; Fast.api.ajax({ - url: 'shopro/user/user/index', + url: 'shopro_huifu/onboard/searchUser', type: 'GET', - data: { offset: 0, limit: 20, searchWhere: keyword } + data: { keyword: keyword, limit: 20 } }, function (ret, res) { - vm.userOptions = (res.data && res.data.rows) || []; + vm.userOptions = res.data || []; vm.userLoading = false; return false; }, function () { @@ -182,7 +201,14 @@ define(['jquery', 'bootstrap', 'backend'], function ($, undefined, Backend) { vm.roleType = ''; vm.roleRefId = 0; vm.roleOptions = []; - if (!vm.userId) return; + if (!vm.userId) { + vm.applySelectedUser(null); + return; + } + var cached = vm.userOptions.find(function (item) { return item.id === vm.userId; }); + if (cached) { + vm.applySelectedUser(cached); + } Fast.api.ajax({ url: 'shopro_huifu/onboard/userRoles', type: 'GET', @@ -191,7 +217,7 @@ define(['jquery', 'bootstrap', 'backend'], function ($, undefined, Backend) { var data = res.data || {}; vm.roleOptions = data.roles || []; if (data.user) { - vm.userLabel = (data.user.nickname || '') + ' (' + (data.user.mobile || data.user.id) + ')'; + vm.applySelectedUser(data.user); } return false; }); @@ -311,7 +337,7 @@ define(['jquery', 'bootstrap', 'backend'], function ($, undefined, Backend) { openCreate: function () { var vm = this; Backend.api.open('shopro_huifu/onboard/add', '新建汇付进件', { - area: ['900px', '90%'], + area: ['960px', '92%'], callback: function () { vm.getList(); } @@ -320,7 +346,7 @@ define(['jquery', 'bootstrap', 'backend'], function ($, undefined, Backend) { openEdit: function (id) { var vm = this; Backend.api.open('shopro_huifu/onboard/edit/ids/' + id, '编辑汇付进件', { - area: ['900px', '90%'], + area: ['960px', '92%'], callback: function () { vm.getList(); if (vm.detailVisible && vm.detailId === id) {