-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.name }}
+
+
+
+
+
+
+
+ {{ item.name }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/admin/src/app/views/venue/venue.vue b/admin/src/app/views/venue/venue.vue
index a02b843b..9cdc60de 100644
--- a/admin/src/app/views/venue/venue.vue
+++ b/admin/src/app/views/venue/venue.vue
@@ -1,293 +1,251 @@
-
-
-
-
- {{ pageName }}
-
- {{ t('addVenue') }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{
- t('search')
- }}
- {{
- t('reset')
- }}
-
-
-
-
-
-
-
- {{ !venueTable.loading ? t('emptyData') : '' }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{
- t('edit')
- }}
- {{
- t('delete')
- }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+ {{pageName}}
+
+ {{ t('addVenue') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ t('search') }}
+ {{ t('reset') }}
+
+
+
+
+
+
+
+ {{ !venueTable.loading ? t('emptyData') : '' }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ t('edit') }}
+ {{ t('delete') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/admin/src/components/TencentMapPicker.vue b/admin/src/components/TencentMapPicker.vue
index cb6719bd..41341f31 100644
--- a/admin/src/components/TencentMapPicker.vue
+++ b/admin/src/components/TencentMapPicker.vue
@@ -12,9 +12,7 @@
- {{ props.placeholder }}
-
+ >
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 可用
+ 不可用
+
+
+
+
+
+
+ {{ item.name }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/admin/src/components/TencentMapPicker.vue b/admin/src/components/TencentMapPicker.vue
index 41341f31..89894672 100644
--- a/admin/src/components/TencentMapPicker.vue
+++ b/admin/src/components/TencentMapPicker.vue
@@ -1,7 +1,7 @@
{
}
const TMap = (window as any).TMap
- const center = new TMap.LatLng(39.90403, 116.407526)
+ const center = new TMap.LatLng(20.029077, 110.366367)
map = new TMap.Map('container', {
center,
@@ -499,5 +499,6 @@ onBeforeUnmount(() => {
.address-search {
display: flex;
gap: 8px;
+ margin-top: 20px;
}
diff --git a/niucloud/app/adminapi/controller/venue/Venue.php b/niucloud/app/adminapi/controller/venue/Venue.php
index 9db487d8..695807cd 100644
--- a/niucloud/app/adminapi/controller/venue/Venue.php
+++ b/niucloud/app/adminapi/controller/venue/Venue.php
@@ -59,8 +59,6 @@ class Venue extends BaseAdminController
["capacity",0],
["availability_status",0],
["time_range_type",""],
- ["time_range_start",""],
- ["time_range_end",""],
["fixed_time_ranges",""],
]);
@@ -81,8 +79,6 @@ class Venue extends BaseAdminController
["capacity",0],
["availability_status",0],
["time_range_type",""],
- ["time_range_start",""],
- ["time_range_end",""],
["fixed_time_ranges",""],
]);
diff --git a/niucloud/app/adminapi/route/venue.php b/niucloud/app/adminapi/route/venue.php
index 35faef3e..6234ac7e 100644
--- a/niucloud/app/adminapi/route/venue.php
+++ b/niucloud/app/adminapi/route/venue.php
@@ -15,6 +15,8 @@ use app\adminapi\middleware\AdminCheckRole;
use app\adminapi\middleware\AdminCheckToken;
use app\adminapi\middleware\AdminLog;
+
+
// USER_CODE_BEGIN -- venue
Route::group('venue', function () {
diff --git a/niucloud/app/validate/venue/Venue.php b/niucloud/app/validate/venue/Venue.php
index d4e25396..01b6d678 100644
--- a/niucloud/app/validate/venue/Venue.php
+++ b/niucloud/app/validate/venue/Venue.php
@@ -37,8 +37,8 @@ class Venue extends BaseValidate
];
protected $scene = [
- "add" => ['campus_id', 'venue_name', 'capacity', 'availability_status', 'time_range_type', 'time_range_start', 'time_range_end', 'fixed_time_ranges'],
- "edit" => ['campus_id', 'venue_name', 'capacity', 'availability_status', 'time_range_type', 'time_range_start', 'time_range_end', 'fixed_time_ranges']
+ "add" => ['campus_id', 'venue_name', 'capacity', 'availability_status', 'time_range_type', 'fixed_time_ranges'],
+ "edit" => ['campus_id', 'venue_name', 'capacity', 'availability_status', 'time_range_type', 'fixed_time_ranges']
];
}
From ac4a8225363f7252d91a072a28f7e3b4f554562a Mon Sep 17 00:00:00 2001
From: liutong <836164388@qq.com>
Date: Sun, 18 May 2025 14:10:58 +0800
Subject: [PATCH 5/5] =?UTF-8?q?feat(api):=20=E6=96=B0=E5=A2=9E=E5=91=98?=
=?UTF-8?q?=E5=B7=A5=E7=AB=AF=E7=9B=B8=E5=85=B3=E6=8E=A5=E5=8F=A3=E5=92=8C?=
=?UTF-8?q?=E5=8A=9F=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 添加员工端登录、信息获取等接口
- 实现员工端token验证和权限检查
- 新增员工端相关的服务层逻辑
- 更新路由配置,支持员工端相关请求
---
.../controller/apiController/Personnel.php | 155 ++++++++++++++++++
niucloud/app/api/controller/login/Login.php | 14 +-
.../api/middleware/ApiPersonnelCheckToken.php | 58 +++++++
niucloud/app/api/route/route.php | 62 ++++++-
.../api/apiService/PersonnelService.php | 91 ++++++++++
.../app/service/api/login/AuthService.php | 15 ++
.../app/service/api/login/LoginService.php | 53 +++++-
7 files changed, 441 insertions(+), 7 deletions(-)
create mode 100644 niucloud/app/api/controller/apiController/Personnel.php
create mode 100644 niucloud/app/api/middleware/ApiPersonnelCheckToken.php
create mode 100644 niucloud/app/service/api/apiService/PersonnelService.php
diff --git a/niucloud/app/api/controller/apiController/Personnel.php b/niucloud/app/api/controller/apiController/Personnel.php
new file mode 100644
index 00000000..add513ac
--- /dev/null
+++ b/niucloud/app/api/controller/apiController/Personnel.php
@@ -0,0 +1,155 @@
+$this->member_id,
+ ];
+ $res = (new PersonnelService())->info($where);
+ if(!$res){
+ return fail('账户信息有误');
+ }
+ return success($result);
+ }
+
+ /**
+ * 登录
+ * @return Response
+ */
+ public function login()
+ {
+ $data = $this->request->params([
+ ['username', ''],
+ ['password', ''],
+ ]);
+ //校验登录注册配置
+ (new ConfigService())->checkLoginConfig(MemberLoginTypeDict::USERNAME);
+ //参数验证
+ //验证码验证
+ $result = (new LoginService())->account($data['username'], $data['password']);
+ if (!$result) {
+ //账号密码错误, 重置验证码
+ return fail('ACCOUNT_OR_PASSWORD_ERROR');
+ }
+ return success($result);
+ }
+
+ /**
+ * 登出
+ * @return Response
+ */
+ public function logout()
+ {
+ (new LoginService)->logout();
+ return success('MEMBER_LOGOUT');
+ }
+
+ /**
+ * 创建验证码
+ * @return Response
+ */
+ public function captcha()
+ {
+ return success((new CaptchaService())->create());
+ }
+
+ /**
+ * 发送手机验证码
+ * @param $type
+ * @return Response
+ * @throws Exception
+ */
+ public function sendMobileCode($type)
+ {
+ $data = $this->request->params([
+ ['mobile', ''],
+ ]);
+ return success((new LoginService())->sendMobileCode($data['mobile'], $type));
+ }
+
+ /**
+ * 手机号登录
+ * @return Response
+ */
+ public function mobile()
+ {
+ $data = $this->request->params([
+ ['mobile', ''],
+ ['nickname', ''],
+ ['headimg', ''],
+ ['mobile', '']
+ ]);
+ //校验登录注册配置
+ (new ConfigService())->checkLoginConfig(MemberLoginTypeDict::MOBILE);
+ return success((new LoginService())->mobile($data));
+ }
+
+ /**
+ * 重置密码
+ * @return Response
+ */
+ public function resetPassword()
+ {
+ $data = $this->request->params([
+ ['mobile', ''],
+ ['password', '']
+ ]);
+ //参数验证
+ $this->validate($data, 'app\validate\member\Member.reset_password');
+ (new LoginService())->resetPassword($data['mobile'], $data['password']);
+ return success('PASSWORD_RESET_SUCCESS');
+ }
+
+ //销售教师人员登陆
+ public function personnelLogin()
+ {
+ $data = $this->request->params([
+ ['phone', ''],
+ ['password', ''],
+ ['login_type', ''],//登陆类型|1=教练,2=销售
+ ]);
+ //验证码验证
+ $result = (new LoginService())->loginByPersonnel($data);
+
+ if(!$result['user_type']){
+ if($data['login_type'] == 1){
+ $msg = '暂无教练权限';
+ }else{
+ $msg = '暂无销售权限';
+ }
+ return fail($msg);//code|0错误
+ }
+
+ return success($result);//code|1正确
+ }
+}
diff --git a/niucloud/app/api/controller/login/Login.php b/niucloud/app/api/controller/login/Login.php
index a454d941..4a5b2b83 100644
--- a/niucloud/app/api/controller/login/Login.php
+++ b/niucloud/app/api/controller/login/Login.php
@@ -109,14 +109,26 @@ class Login extends BaseController
return success('PASSWORD_RESET_SUCCESS');
}
+ //销售教师人员登陆
public function personnelLogin()
{
$data = $this->request->params([
['phone', ''],
['password', ''],
+ ['login_type', ''],//登陆类型|1=教练,2=销售
]);
//验证码验证
$result = (new LoginService())->loginByPersonnel($data);
- return success($result);
+
+ if(!$result['user_type']){
+ if($data['login_type'] == 1){
+ $msg = '暂无教练权限';
+ }else{
+ $msg = '暂无销售权限';
+ }
+ return fail($msg);//code|0错误
+ }
+
+ return success($result);//code|1正确
}
}
diff --git a/niucloud/app/api/middleware/ApiPersonnelCheckToken.php b/niucloud/app/api/middleware/ApiPersonnelCheckToken.php
new file mode 100644
index 00000000..dd8ee824
--- /dev/null
+++ b/niucloud/app/api/middleware/ApiPersonnelCheckToken.php
@@ -0,0 +1,58 @@
+appType(AppTypeDict::PERSONNEL);
+ // 校验渠道
+ ( new AuthService() )->checkChannel($request);
+ //通过配置来设置系统header参数
+ try {
+ $token = $request->apiToken();
+ $token_info = ( new LoginService() )->parsePersonnelToken($token);
+ if (!empty($token_info)) {
+ $request->memberId($token_info[ 'member_id' ]);
+ }
+ //校验会员和站点
+ $a= ( new AuthService() )->checkPersonnelMember($request);
+ } catch (AuthException $e) {
+ //是否将登录错误抛出
+ if ($is_throw_exception)
+ return fail($e->getMessage(), [], $e->getCode());
+ }
+ return $next($request);
+ }
+}
diff --git a/niucloud/app/api/route/route.php b/niucloud/app/api/route/route.php
index 217081ae..c8fcfbde 100644
--- a/niucloud/app/api/route/route.php
+++ b/niucloud/app/api/route/route.php
@@ -11,6 +11,7 @@
use app\api\middleware\ApiChannel;
use app\api\middleware\ApiCheckToken;
+use app\api\middleware\ApiPersonnelCheckToken;
use app\api\middleware\ApiLog;
use app\api\route\dispatch\BindDispatch;
use core\dict\DictLoader;
@@ -74,8 +75,7 @@ Route::group(function() {
//登录
Route::get('login', 'login.Login/login');
- //员工登录
- Route::post('personnelLogin', 'login.Login/personnelLogin');
+
//第三方绑定
Route::post('bind', BindDispatch::class);
@@ -162,5 +162,63 @@ Route::group(function() {
})->middleware(ApiChannel::class)
->middleware(ApiCheckToken::class, true)
->middleware(ApiLog::class);
+
+
+
+
+
+
+
+//↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓-----员工端相关-----↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
+//无需token验证的
+Route::group(function() {
+ //员工登录
+ Route::post('personnelLogin', 'login.Login/personnelLogin');
+})->middleware(ApiChannel::class)
+ ->middleware(ApiPersonnelCheckToken::class)
+ ->middleware(ApiLog::class);
+
+
+//需要token验证的
+Route::group(function() {
+ //员工端详情
+ Route::get('personnel/info', 'apiController.Personnel/info');
+
+})->middleware(ApiChannel::class)
+ ->middleware(ApiPersonnelCheckToken::class, true)
+ ->middleware(ApiLog::class);
+//↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑-----员工端相关-----↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
+
+
+
+
+
+
+//↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓-----用户端相关-----↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
+//无需token验证的
+Route::group(function() {
+ //员工登录
+ Route::post('personnelLogin', 'login.Login/personnelLogin');
+})->middleware(ApiChannel::class)
+ ->middleware(ApiCheckToken::class)
+ ->middleware(ApiLog::class);
+
+
+//需要token验证的
+Route::group(function() {
+
+ Route::get('personnel/info', 'apiController.Personnel/info');
+
+})->middleware(ApiChannel::class)
+ ->middleware(ApiCheckToken::class, true)
+ ->middleware(ApiLog::class);
+//↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑-----用户端相关-----↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
+
+
+
+
+
+
+
//加载插件路由
( new DictLoader("Route") )->load([ 'app_type' => 'api' ]);
diff --git a/niucloud/app/service/api/apiService/PersonnelService.php b/niucloud/app/service/api/apiService/PersonnelService.php
new file mode 100644
index 00000000..659cc20f
--- /dev/null
+++ b/niucloud/app/service/api/apiService/PersonnelService.php
@@ -0,0 +1,91 @@
+model = new Personnel();
+ }
+
+ //获取员工信息
+ public function info(array $where,string $field = '*'){
+ $model = $this->model;
+ if(!empty($where['id'])){
+ $model = $model->where('id',$where['id']);
+ }
+ $res = $model->field($field)->find();//员工信息
+
+ //查询部门信息
+ $campus_person_role = CampusPersonRole::where('person_id',$where['id'])->select()->toArray();
+ $role_id = array_column($campus_person_role, 'role_id');
+ $dept_id = array_column($campus_person_role, 'dept_id');
+
+
+ if($res){
+ $res = $res->toArray();
+ }else{
+ $res = [];
+ return $res;
+ }
+
+ }
+
+
+ /**
+ * 获取会员的模型对象(todo 慎用!!! 现主要用于登录)
+ * @param array $data
+ * @return Member|array|mixed|Model !!! 仔细看,返回值是模型对象 如果想要判断是否为空 请用 $member->isEmpty()
+ */
+ public function findMemberInfo(array $data){
+ //会员账号
+ if(!empty($data['username']))
+ $where[] = ['username', '=', $data['username']];
+ //会员手机号
+ if(!empty($data['mobile']))
+ $where[] = ['mobile', '=', $data['mobile']];
+ //会员id
+ if(!empty($data['id']))
+ $where[] = ['id', '=', $data['id']];
+ //微信公众号openid
+ if(!empty($data['wx_openid']))
+ $where[] = ['wx_openid', '=', $data['wx_openid']];
+ //微信小程序openid
+ if(!empty($data['weapp_openid']))
+ $where[] = ['weapp_openid', '=', $data['weapp_openid']];
+ // 微信unionid
+ if(!empty($data['wx_unionid']))
+ $where[] = ['wx_unionid', '=', $data['wx_unionid']];
+ if(!empty($data['username|mobile']))
+ $where[] = ['username|mobile', '=', $data['username|mobile']];
+ if(empty($where)){
+ $where[] = ['member_id', '=', -1];
+ }
+ return $this->model->where($where)->findOrEmpty();
+ }
+}
diff --git a/niucloud/app/service/api/login/AuthService.php b/niucloud/app/service/api/login/AuthService.php
index 4dca4543..6f66ad4e 100644
--- a/niucloud/app/service/api/login/AuthService.php
+++ b/niucloud/app/service/api/login/AuthService.php
@@ -14,6 +14,7 @@ namespace app\service\api\login;
use app\dict\common\ChannelDict;
use app\model\member\Member;
use app\Request;
+use app\service\api\apiService\PersonnelService;
use app\service\api\member\MemberService;
use app\service\core\channel\CoreH5Service;
use app\service\core\channel\CorePcService;
@@ -49,6 +50,20 @@ class AuthService extends BaseApiService
return true;
}
+ //检测员工用户是否存在
+ public function checkPersonnelMember(Request $request)
+ {
+ //如果登录信息非法就报错
+ if ($this->member_id > 0) {
+ $member_service = new PersonnelService();
+ $member_info = $member_service->findMemberInfo([ 'id' => $this->member_id ]);
+ if ($member_info->isEmpty()) {
+ throw new AuthException('MEMBER_NOT_EXIST', 401);
+ }
+ }
+ return true;
+ }
+
/**
* 校验渠道
* @param Request $request
diff --git a/niucloud/app/service/api/login/LoginService.php b/niucloud/app/service/api/login/LoginService.php
index b556f2a0..141f1aca 100644
--- a/niucloud/app/service/api/login/LoginService.php
+++ b/niucloud/app/service/api/login/LoginService.php
@@ -15,6 +15,7 @@ use app\dict\member\MemberLoginTypeDict;
use app\dict\member\MemberRegisterTypeDict;
use app\dict\sys\AppTypeDict;
use app\dict\sys\SmsDict;
+use app\model\campus_person_role\CampusPersonRole;
use app\model\member\Member;
use app\model\personnel\Personnel;
use app\model\sys\SysUser;
@@ -163,7 +164,7 @@ class LoginService extends BaseApiService
}
/**
- * 解析token
+ * 解析客户端token
* @param string|null $token
* @return array
*/
@@ -190,6 +191,34 @@ class LoginService extends BaseApiService
return $token_info;
}
+ /**
+ * 解析员工端token
+ * @param string|null $token
+ * @return array
+ */
+ public function parsePersonnelToken(?string $token)
+ {
+ if (empty($token)) {
+ //定义专属于授权认证机制的错误响应, 定义专属语言包
+ throw new AuthException('MUST_LOGIN', 401);
+ }
+
+ try {
+ $token_info = TokenAuth::parseToken($token, AppTypeDict::PERSONNEL);
+ } catch (Throwable $e) {
+// if(env('app_debug', false)){
+// throw new AuthException($e->getMessage(), 401);
+// }else{
+ throw new AuthException('LOGIN_EXPIRE', 401);
+// }
+ }
+ if (!$token_info) {
+ throw new AuthException('MUST_LOGIN', 401);
+ }
+ //验证有效次数或过期时间
+ return $token_info;
+ }
+
/**
* 手机发送验证码
* @param $mobile
@@ -326,6 +355,7 @@ class LoginService extends BaseApiService
if ($member_info->status != 2) throw new ApiException('账号状态异常禁止登录');
$user = (new SysUser())->where('username', $params['phone'])->find();
+ //create_password($params['password'])//创建密码
if (!check_password($params['password'], $user->password)) throw new ApiException('账号或密码错误');
$user->login_time = time();
$user->last_ip = $this->request->ip();
@@ -334,11 +364,26 @@ class LoginService extends BaseApiService
$user->last_time = time();
$user->save();
$expire_time = env('system.api_token_expire_time') ?? 3600;
- $token_info = TokenAuth::createToken($member_info->id, AppTypeDict::PERSONNEL, ['id' => $member_info->id, 'phone' => $member_info->phone], $expire_time);;
+ //生成token
+ $token_info = TokenAuth::createToken($member_info->id, AppTypeDict::PERSONNEL, ['id' => $member_info->id, 'member_id'=>$member_info->id, 'phone' => $member_info->phone, 'user_type' => $params['login_type']], $expire_time);
event("PersonnelLogin", $member_info);
+
+ $role = CampusPersonRole::where('person_id',$member_info['id'])->column('role_id');
+
+ //login_type|1=教练,2=销售
+ $user_type = '';//1=教练,2=销售
+ if(in_array(2,$role) && $params['login_type'] == 2){
+ //销售登陆
+ $user_type = 2;
+ }elseif(in_array(3,$role) && $params['login_type'] == 1){
+ //教师登陆
+ $user_type = 1;
+ }
+
return [
- 'token' => $token_info['token'],
- 'expires_time' => $token_info['params']['exp']
+ 'token' => $token_info['token'],//token
+ 'expires_time' => $token_info['params']['exp'],//过期时间
+ 'user_type' => $user_type//用户类型
];
}
}