数智员工免密登录
This commit is contained in:
@@ -102,15 +102,27 @@ class PasswordLoginController extends BaseController
|
||||
* @param string $account 账号(手机号)
|
||||
* @param string $password 密码(可能是加密后的)
|
||||
* @param string $typeId 登录IP
|
||||
* @param string $deviceId 本地设备imei
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function doLogin(string $account, string $password, int $typeId): array
|
||||
protected function doLogin(string $account, string $password, int $typeId, string $deviceId): array
|
||||
{
|
||||
// 获取用户信息
|
||||
$member = $this->getUser($account, $password, $typeId);
|
||||
$deviceTotal = Db::name('device')->where(['companyId' => $member['companyId'],'deleteTime' => 0])->count();
|
||||
|
||||
//更新设备imei
|
||||
if ($typeId == 2 && !empty($deviceId)){
|
||||
$deviceUser = Db::name('device_user')->where(['companyId' => $member['companyId'],'userId' => $member['id'],'deleteTime' => 0])->find();
|
||||
if (!empty($deviceUser)){
|
||||
$s2_device = Db::table('s2_device')->where(['companyId' => $member['companyId'],'deleteTime' => 0,'id' => $deviceUser])->find();
|
||||
if (!empty($s2_device) && empty($s2_device['deviceImei'])){
|
||||
Db::table('s2_device')->where(['id' => $s2_device['id']])->update(['deviceImei' => $deviceId,'updateTime' => time()]);
|
||||
Db::name('device')->where(['id' => $s2_device['id']])->update(['deviceImei' => $deviceId,'updateTime' => time()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 生成JWT令牌
|
||||
@@ -126,34 +138,16 @@ class PasswordLoginController extends BaseController
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$params = $this->request->only(['account', 'password', 'typeId']);
|
||||
$params = $this->request->only(['account', 'password', 'typeId','deviceId']);
|
||||
try {
|
||||
$userData = $this->dataValidate($params)->doLogin(
|
||||
$params['account'],
|
||||
$params['password'],
|
||||
$params['typeId']
|
||||
$params['typeId'],
|
||||
$params['deviceId']
|
||||
);
|
||||
//同时登录客服系统
|
||||
/* if (!empty($userData['member']['passwordLocal'])){
|
||||
$params = [
|
||||
'grant_type' => 'password',
|
||||
'username' => $userData['member']['account'],
|
||||
'password' => localDecrypt($userData['member']['passwordLocal'])
|
||||
];
|
||||
// 调用登录接口获取token
|
||||
$headerData = ['client:kefu-client'];
|
||||
$header = setHeader($headerData, '', 'plain');
|
||||
$result = requestCurl('https://s2.siyuguanli.com:9991/token', $params, 'POST', $header);
|
||||
$token = handleApiResponse($result);
|
||||
$userData['kefuData']['token'] = $token;
|
||||
if (isset($token['access_token']) && !empty($token['access_token'])) {
|
||||
$headerData = ['client:kefu-client'];
|
||||
$header = setHeader($headerData, $token['access_token']);
|
||||
$result = requestCurl( 'https://s2.siyuguanli.com:9991/api/account/self', [], 'GET', $header,'json');
|
||||
$self = handleApiResponse($result);
|
||||
$userData['kefuData']['self'] = $self;
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
return ResponseHelper::success($userData, '登录成功');
|
||||
} catch (Exception $e) {
|
||||
return ResponseHelper::error($e->getMessage(), $e->getCode());
|
||||
|
||||
@@ -178,6 +178,15 @@ Route::group('v1/', function () {
|
||||
Route::get('detailType', 'app\cunkebao\controller\AiKnowledgeBaseController@detailType');
|
||||
});
|
||||
|
||||
// 门店端账号管理
|
||||
Route::group('store-accounts', function () {
|
||||
Route::get('', 'app\cunkebao\controller\StoreAccountController@index'); // 获取账号列表
|
||||
Route::post('', 'app\cunkebao\controller\StoreAccountController@create'); // 创建账号
|
||||
Route::put('', 'app\cunkebao\controller\StoreAccountController@update'); // 编辑账号
|
||||
Route::delete('', 'app\cunkebao\controller\StoreAccountController@delete'); // 删除账号
|
||||
Route::post('disable', 'app\cunkebao\controller\StoreAccountController@disable'); // 禁用/启用账号
|
||||
});
|
||||
|
||||
|
||||
|
||||
})->middleware(['jwt']);
|
||||
|
||||
@@ -0,0 +1,404 @@
|
||||
<?php
|
||||
|
||||
namespace app\cunkebao\controller;
|
||||
|
||||
use app\common\model\Device;
|
||||
use app\common\model\DeviceUser;
|
||||
use app\common\model\User;
|
||||
use library\ResponseHelper;
|
||||
use think\Db;
|
||||
|
||||
/**
|
||||
* 门店端账号管理控制器
|
||||
*/
|
||||
class StoreAccountController extends BaseController
|
||||
{
|
||||
/**
|
||||
* 创建账号
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
try {
|
||||
// 获取参数
|
||||
$account = $this->request->param('account', '');
|
||||
$username = $this->request->param('username', '');
|
||||
$phone = $this->request->param('phone', '');
|
||||
$password = $this->request->param('password', '');
|
||||
$deviceId = $this->request->param('deviceId', 0);
|
||||
|
||||
$companyId = $this->getUserInfo('companyId');
|
||||
|
||||
// 参数验证
|
||||
if (empty($account)) {
|
||||
return ResponseHelper::error('账号不能为空');
|
||||
}
|
||||
if (empty($username)) {
|
||||
return ResponseHelper::error('昵称不能为空');
|
||||
}
|
||||
if (empty($phone)) {
|
||||
return ResponseHelper::error('手机号不能为空');
|
||||
}
|
||||
if (!preg_match('/^1[3-9]\d{9}$/', $phone)) {
|
||||
return ResponseHelper::error('手机号格式不正确');
|
||||
}
|
||||
if (empty($password)) {
|
||||
return ResponseHelper::error('密码不能为空');
|
||||
}
|
||||
if (strlen($password) < 6 || strlen($password) > 20) {
|
||||
return ResponseHelper::error('密码长度必须在6-20个字符之间');
|
||||
}
|
||||
if (empty($deviceId)) {
|
||||
return ResponseHelper::error('请选择设备');
|
||||
}
|
||||
|
||||
// 检查账号是否已存在(同一 typeId 和 companyId 下不能重复)
|
||||
$existUser = Db::name('users')->where(['account' => $account, 'companyId' => $companyId, 'typeId' => 2, 'deleteTime' => 0])
|
||||
->find();
|
||||
if ($existUser) {
|
||||
return ResponseHelper::error('账号已存在');
|
||||
}
|
||||
|
||||
// 检查手机号是否已存在(同一 typeId 和 companyId 下不能重复)
|
||||
$existPhone = Db::name('users')->where(['phone' => $phone, 'companyId' => $companyId, 'typeId' => 2, 'deleteTime' => 0])
|
||||
->find();
|
||||
if ($existPhone) {
|
||||
return ResponseHelper::error('手机号已被使用');
|
||||
}
|
||||
|
||||
// 检查设备是否存在且属于当前公司
|
||||
$device = Device::where('id', $deviceId)
|
||||
->where('companyId', $companyId)
|
||||
->find();
|
||||
if (!$device) {
|
||||
return ResponseHelper::error('设备不存在或没有权限');
|
||||
}
|
||||
|
||||
// 开始事务
|
||||
Db::startTrans();
|
||||
try {
|
||||
// 创建用户
|
||||
$userData = [
|
||||
'account' => $account,
|
||||
'username' => $username,
|
||||
'phone' => $phone,
|
||||
'passwordMd5' => md5($password),
|
||||
'passwordLocal' => localEncrypt($password),
|
||||
'avatar' => 'https://img.icons8.com/color/512/circled-user-male-skin-type-7.png',
|
||||
'isAdmin' => 0,
|
||||
'companyId' => $companyId,
|
||||
'typeId' => 2, // 门店端固定为2
|
||||
'status' => 1, // 默认可用
|
||||
'balance' => 0,
|
||||
'tokens' => 0,
|
||||
'createTime' => time(),
|
||||
];
|
||||
|
||||
$userId = Db::name('users')->insertGetId($userData);
|
||||
|
||||
// 绑定设备
|
||||
Db::name('device_user')->insert([
|
||||
'companyId' => $companyId,
|
||||
'userId' => $userId,
|
||||
'deviceId' => $deviceId,
|
||||
'deleteTime' => 0,
|
||||
]);
|
||||
|
||||
// 提交事务
|
||||
Db::commit();
|
||||
|
||||
return ResponseHelper::success('创建账号成功');
|
||||
} catch (\Exception $e) {
|
||||
Db::rollback();
|
||||
throw $e;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
return ResponseHelper::error($e->getMessage(), $e->getCode() ?: 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑账号
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function update()
|
||||
{
|
||||
try {
|
||||
$userId = $this->request->param('userId', 0);
|
||||
$account = $this->request->param('account', '');
|
||||
$username = $this->request->param('username', '');
|
||||
$phone = $this->request->param('phone', '');
|
||||
$password = $this->request->param('password', '');
|
||||
$deviceId = $this->request->param('deviceId', 0);
|
||||
|
||||
$companyId = $this->getUserInfo('companyId');
|
||||
|
||||
// 参数验证
|
||||
if (empty($userId)) {
|
||||
return ResponseHelper::error('用户ID不能为空');
|
||||
}
|
||||
|
||||
// 检查用户是否存在且属于当前公司
|
||||
$user = Db::name('users')->where(['id' => $userId, 'companyId' => $companyId, 'typeId' => 2])->find();
|
||||
if (!$user) {
|
||||
return ResponseHelper::error('用户不存在或没有权限');
|
||||
}
|
||||
|
||||
$updateData = [];
|
||||
|
||||
// 更新账号
|
||||
if (!empty($account)) {
|
||||
// 检查账号是否已被其他用户使用(同一 typeId 下)
|
||||
$existUser = Db::name('users')->where(['account' => $account, 'companyId' => $companyId, 'typeId' => 2, 'deleteTime' => 0])
|
||||
->where('id', '<>', $userId)
|
||||
->find();
|
||||
if ($existUser) {
|
||||
return ResponseHelper::error('账号已被使用');
|
||||
}
|
||||
$updateData['account'] = $account;
|
||||
}
|
||||
|
||||
// 更新昵称
|
||||
if (!empty($username)) {
|
||||
$updateData['username'] = $username;
|
||||
}
|
||||
|
||||
// 更新手机号
|
||||
if (!empty($phone)) {
|
||||
if (!preg_match('/^1[3-9]\d{9}$/', $phone)) {
|
||||
return ResponseHelper::error('手机号格式不正确');
|
||||
}
|
||||
// 检查手机号是否已被其他用户使用(同一 typeId 下)
|
||||
$existPhone = Db::name('users')->where(['phone' => $phone, 'companyId' => $companyId, 'typeId' => 2, 'deleteTime' => 0])
|
||||
->where('id', '<>', $userId)
|
||||
->find();
|
||||
if ($existPhone) {
|
||||
return ResponseHelper::error('手机号已被使用');
|
||||
}
|
||||
$updateData['phone'] = $phone;
|
||||
}
|
||||
|
||||
// 更新密码
|
||||
if (!empty($password)) {
|
||||
if (strlen($password) < 6 || strlen($password) > 20) {
|
||||
return ResponseHelper::error('密码长度必须在6-20个字符之间');
|
||||
}
|
||||
$updateData['passwordMd5'] = md5($password);
|
||||
$updateData['passwordLocal'] = localEncrypt($password);
|
||||
}
|
||||
|
||||
// 更新设备绑定
|
||||
if (!empty($deviceId)) {
|
||||
// 检查设备是否存在且属于当前公司
|
||||
$device = Device::where('id', $deviceId)
|
||||
->where('companyId', $companyId)
|
||||
->find();
|
||||
if (!$device) {
|
||||
return ResponseHelper::error('设备不存在或没有权限');
|
||||
}
|
||||
}
|
||||
|
||||
// 开始事务
|
||||
Db::startTrans();
|
||||
try {
|
||||
// 更新用户信息
|
||||
if (!empty($updateData)) {
|
||||
$updateData['updateTime'] = time();
|
||||
Db::name('users')->where(['id' => $userId])->update($updateData);
|
||||
}
|
||||
|
||||
// 更新设备绑定
|
||||
if (!empty($deviceId)) {
|
||||
// 删除旧的设备绑定
|
||||
Db::name('device_user')->where(['userId' => $userId, 'companyId' => $companyId])->delete();
|
||||
|
||||
// 添加新的设备绑定
|
||||
Db::name('device_user')->insert([
|
||||
'companyId' => $companyId,
|
||||
'userId' => $userId,
|
||||
'deviceId' => $deviceId,
|
||||
'deleteTime' => 0,
|
||||
]);
|
||||
}
|
||||
|
||||
// 提交事务
|
||||
Db::commit();
|
||||
|
||||
return ResponseHelper::success('更新账号成功');
|
||||
} catch (\Exception $e) {
|
||||
Db::rollback();
|
||||
throw $e;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
return ResponseHelper::error($e->getMessage(), $e->getCode() ?: 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除账号
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
try {
|
||||
$userId = $this->request->param('userId', 0);
|
||||
$companyId = $this->getUserInfo('companyId');
|
||||
|
||||
if (empty($userId)) {
|
||||
return ResponseHelper::error('用户ID不能为空');
|
||||
}
|
||||
|
||||
// 检查用户是否存在且属于当前公司
|
||||
$user = Db::name('users')->where(['id' => $userId, 'companyId' => $companyId, 'typeId' => 2])->find();
|
||||
if (!$user) {
|
||||
return ResponseHelper::error('用户不存在或没有权限');
|
||||
}
|
||||
|
||||
// 检查是否是管理账号
|
||||
if ($user['isAdmin'] == 1) {
|
||||
return ResponseHelper::error('管理账号无法删除');
|
||||
}
|
||||
|
||||
// 软删除用户
|
||||
Db::name('users')->where(['id' => $userId])->update([
|
||||
'deleteTime' => time(),
|
||||
'updateTime' => time()
|
||||
]);
|
||||
|
||||
// 软删除设备绑定关系
|
||||
Db::name('device_user')->where(['userId' => $userId, 'companyId' => $companyId])->update([
|
||||
'deleteTime' => time()
|
||||
]);
|
||||
|
||||
return ResponseHelper::success('删除账号成功');
|
||||
} catch (\Exception $e) {
|
||||
return ResponseHelper::error($e->getMessage(), $e->getCode() ?: 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 禁用/启用账号
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function disable()
|
||||
{
|
||||
try {
|
||||
$userId = $this->request->param('userId', 0);
|
||||
$status = $this->request->param('status', -1); // 0-禁用 1-启用
|
||||
$companyId = $this->getUserInfo('companyId');
|
||||
|
||||
if (empty($userId)) {
|
||||
return ResponseHelper::error('用户ID不能为空');
|
||||
}
|
||||
|
||||
if ($status != 0 && $status != 1) {
|
||||
return ResponseHelper::error('状态参数错误');
|
||||
}
|
||||
|
||||
// 检查用户是否存在且属于当前公司
|
||||
$user = Db::name('users')->where(['id' => $userId, 'companyId' => $companyId, 'typeId' => 2])->find();
|
||||
if (!$user) {
|
||||
return ResponseHelper::error('用户不存在或没有权限');
|
||||
}
|
||||
|
||||
// 检查是否是管理账号
|
||||
if ($user['isAdmin'] == 1 && $status == 0) {
|
||||
return ResponseHelper::error('管理账号无法禁用');
|
||||
}
|
||||
|
||||
// 更新状态
|
||||
Db::name('users')->where(['id' => $userId])->update([
|
||||
'status' => $status,
|
||||
'updateTime' => time()
|
||||
]);
|
||||
|
||||
$message = $status == 0 ? '禁用账号成功' : '启用账号成功';
|
||||
return ResponseHelper::success($message);
|
||||
} catch (\Exception $e) {
|
||||
return ResponseHelper::error($e->getMessage(), $e->getCode() ?: 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取账号列表
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
try {
|
||||
$keyword = $this->request->param('keyword', '');
|
||||
$status = $this->request->param('status', '');
|
||||
$page = $this->request->param('page/d', 1);
|
||||
$limit = $this->request->param('limit/d', 10);
|
||||
|
||||
$companyId = $this->getUserInfo('companyId');
|
||||
|
||||
// 构建查询条件
|
||||
$where = [
|
||||
['companyId', '=', $companyId],
|
||||
['typeId', '=', 2], // 只查询门店端账号
|
||||
['deleteTime', '=', 0]
|
||||
];
|
||||
|
||||
// 关键词搜索(账号、昵称、手机号)
|
||||
if (!empty($keyword)) {
|
||||
$where[] = ['account|username|phone', "LIKE", '%'.$keyword.'%'];
|
||||
}
|
||||
|
||||
// 状态筛选
|
||||
if ($status !== '') {
|
||||
$where[] = ['status', '=', $status];
|
||||
}
|
||||
|
||||
// 分页查询
|
||||
$query = Db::name('users')->where($where);
|
||||
$total = $query->count();
|
||||
|
||||
$list = $query->field('id,account,username,phone,avatar,isAdmin,status,balance,tokens,createTime')
|
||||
->order('id desc')
|
||||
->page($page, $limit)
|
||||
->select();
|
||||
|
||||
|
||||
// 获取每个账号绑定的设备(单个设备)
|
||||
if (!empty($list)) {
|
||||
$userIds = array_column($list, 'id');
|
||||
$deviceBindings = Db::name('device_user')
|
||||
->alias('du')
|
||||
->join('device d', 'd.id = du.deviceId', 'left')
|
||||
->where([
|
||||
['du.userId', 'in', $userIds],
|
||||
['du.companyId', '=', $companyId],
|
||||
['du.deleteTime', '=', 0]
|
||||
])
|
||||
->field('du.userId,du.deviceId,d.imei,d.memo')
|
||||
->order('du.id desc')
|
||||
->select();
|
||||
|
||||
// 组织设备数据(单个设备对象)
|
||||
$deviceMap = [];
|
||||
foreach ($deviceBindings as $binding) {
|
||||
$deviceMap[$binding['userId']] = [
|
||||
'deviceId' => $binding['deviceId'],
|
||||
'imei' => $binding['imei'],
|
||||
'memo' => $binding['memo']
|
||||
];
|
||||
}
|
||||
|
||||
// 将设备信息添加到用户数据中
|
||||
foreach ($list as &$item) {
|
||||
$item['device'] = $deviceMap[$item['id']] ?? null;
|
||||
}
|
||||
}
|
||||
|
||||
return ResponseHelper::success([
|
||||
'list' => $list,
|
||||
'total' => $total,
|
||||
'page' => $page,
|
||||
'limit' => $limit
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
return ResponseHelper::error($e->getMessage(), $e->getCode() ?: 500);
|
||||
}
|
||||
}
|
||||
}
|
||||
25
Server/application/store/controller/LoginController.php
Normal file
25
Server/application/store/controller/LoginController.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace app\store\controller;
|
||||
|
||||
use think\Db;
|
||||
|
||||
class LoginController extends BaseController
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$deviceId = $this->request->param('deviceId', '');
|
||||
if (empty($deviceId)) {
|
||||
return errorJson('缺少必要参数');
|
||||
}
|
||||
|
||||
$user = Db::name('user')->alias('u')
|
||||
->join('device_user du','u.id = du.userId and u.companyId = du.companyId')
|
||||
->join('device d','du.deviceId = d.id and u.companyId = du.companyId')
|
||||
->where(['d.deviceImei' => $deviceId,'u.deleteTime' => 0,'du.deleteTime' => 0,'d.deleteTime'=> 0 ])
|
||||
->find();
|
||||
|
||||
exit_data($user);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -3,14 +3,18 @@ import { request, requestWithRetry } from '../config'
|
||||
// 认证相关API
|
||||
export const authApi = {
|
||||
// 用户登录
|
||||
login: (account, password) => {
|
||||
// @param {string} account - 账号
|
||||
// @param {string} password - 密码
|
||||
// @param {string} deviceId - 设备ID(仅APP端传递,H5端为空字符串)
|
||||
login: (account, password, deviceId) => {
|
||||
return request({
|
||||
url: '/v1/auth/login',
|
||||
method: 'POST',
|
||||
data: {
|
||||
account: account,
|
||||
password: password,
|
||||
typeId: 2 // 固定为2
|
||||
typeId: 2, // 固定为2
|
||||
deviceId: deviceId || '' // 设备ID(仅APP端有值)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -8,96 +8,39 @@
|
||||
|
||||
<!-- 内容区域 -->
|
||||
<view class="content-area">
|
||||
<!-- 登录方式选项卡 -->
|
||||
<view class="tab-container" v-if="false">
|
||||
<view
|
||||
class="tab-item"
|
||||
:class="{ active: loginType === 'code' }"
|
||||
@tap="loginType = 'code'"
|
||||
>
|
||||
验证码登录
|
||||
</view>
|
||||
<view
|
||||
class="tab-item"
|
||||
:class="{ active: loginType === 'password' }"
|
||||
@tap="loginType = 'password'"
|
||||
>
|
||||
密码登录
|
||||
<!-- 登录标题 -->
|
||||
<view class="login-title">账号密码登录</view>
|
||||
|
||||
<!-- 账号输入 -->
|
||||
<view class="form-item">
|
||||
<view class="input-item">
|
||||
<u-input
|
||||
v-model="account"
|
||||
placeholder="请输入账号"
|
||||
class="input-field"
|
||||
border="0"
|
||||
prefixIcon="account"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 地区提示 -->
|
||||
<view class="tip-text u-line-1">
|
||||
您所在地区仅支持 手机号 <!-- / 微信 / Apple 登录 -->
|
||||
<!-- 密码输入 -->
|
||||
<view class="form-item">
|
||||
<view class="input-item">
|
||||
<u-input
|
||||
:type="passwordVisible ? 'text' : 'password'"
|
||||
v-model="password"
|
||||
placeholder="请输入密码"
|
||||
class="input-field"
|
||||
border="0"
|
||||
prefixIcon="lock"
|
||||
/>
|
||||
<view class="password-icon" @tap="passwordVisible = !passwordVisible">
|
||||
<u-icon :name="passwordVisible ? 'eye' : 'eye-off'" size="20" color="#999"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 验证码登录 -->
|
||||
<block v-if="loginType === 'code'">
|
||||
<view class="form-item">
|
||||
<view class="input-item">
|
||||
<view class="input-prefix">+86</view>
|
||||
<u-input
|
||||
type="number"
|
||||
v-model="phone"
|
||||
maxlength="11"
|
||||
placeholder="手机号"
|
||||
class="input-field"
|
||||
border="0"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<view class="input-item code-input-box">
|
||||
<u-input
|
||||
type="number"
|
||||
v-model="code"
|
||||
maxlength="6"
|
||||
placeholder="验证码"
|
||||
class="input-field"
|
||||
border="0"
|
||||
/>
|
||||
<view
|
||||
class="send-code-btn"
|
||||
:class="{ disabled: codeSending || !isPhoneValid }"
|
||||
@tap="sendCode"
|
||||
>
|
||||
{{ codeText }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<!-- 密码登录 -->
|
||||
<block v-else>
|
||||
<view class="form-item">
|
||||
<view class="input-item">
|
||||
<view class="input-prefix">+86</view>
|
||||
<u-input
|
||||
type="number"
|
||||
v-model="phone"
|
||||
maxlength="11"
|
||||
placeholder="手机号"
|
||||
class="input-field"
|
||||
border="0"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<view class="input-item">
|
||||
<u-input
|
||||
:type="passwordVisible ? 'text' : 'password'"
|
||||
v-model="password"
|
||||
placeholder="密码"
|
||||
class="input-field"
|
||||
border="0"
|
||||
/>
|
||||
<view class="password-icon" @tap="passwordVisible = !passwordVisible">
|
||||
<u-icon :name="passwordVisible ? 'eye' : 'eye-off'" size="20" color="#999"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<!-- 用户协议 -->
|
||||
<view class="agreement-container">
|
||||
<checkbox-group @change="checkboxChange">
|
||||
@@ -118,40 +61,6 @@
|
||||
登录
|
||||
</view>
|
||||
|
||||
<!-- 分隔线 -->
|
||||
<view class="divider" v-if="false">
|
||||
<view class="divider-line"></view>
|
||||
<text class="divider-text">或</text>
|
||||
<view class="divider-line"></view>
|
||||
</view>
|
||||
|
||||
<!-- 第三方登录 -->
|
||||
<view class="third-party-login" v-if="false">
|
||||
<u-button
|
||||
text="使用微信登录"
|
||||
:custom-style="{backgroundColor: '#07c160', color: '#ffffff', marginBottom: '15px'}"
|
||||
shape="circle"
|
||||
@click="handleThirdLogin('wechat')"
|
||||
:ripple="true"
|
||||
>
|
||||
<template slot="icon">
|
||||
<u-icon name="weixin-fill" color="#ffffff" size="18" style="margin-right: 5px;"></u-icon>
|
||||
</template>
|
||||
</u-button>
|
||||
|
||||
<u-button
|
||||
text="使用 Apple 登录"
|
||||
:custom-style="{backgroundColor: '#000000', color: '#ffffff'}"
|
||||
shape="circle"
|
||||
@click="handleThirdLogin('apple')"
|
||||
:ripple="true"
|
||||
>
|
||||
<template slot="icon">
|
||||
<u-icon name="apple-fill" color="#ffffff" size="18" style="margin-right: 5px;"></u-icon>
|
||||
</template>
|
||||
</u-button>
|
||||
</view>
|
||||
|
||||
<!-- 联系我们 -->
|
||||
<view class="contact-us" @tap="contactUs">
|
||||
联系我们
|
||||
@@ -168,44 +77,63 @@
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
loginType: 'password', // 默认密码登录
|
||||
phone: '', // 手机号
|
||||
code: '', // 验证码
|
||||
account: '', // 账号
|
||||
password: '', // 密码
|
||||
passwordVisible: false, // 密码是否可见
|
||||
agreement: true, // 是否同意协议
|
||||
codeSending: false, // 是否正在发送验证码
|
||||
countdown: 60, // 倒计时
|
||||
codeText: '发送验证码' // 验证码按钮文本
|
||||
deviceId: '' // 设备ID
|
||||
}
|
||||
},
|
||||
// 页面加载时检查token
|
||||
onLoad() {
|
||||
this.checkTokenStatus();
|
||||
this.getDeviceId();
|
||||
},
|
||||
// 页面显示时检查token
|
||||
onShow() {
|
||||
this.checkTokenStatus();
|
||||
},
|
||||
computed: {
|
||||
// 验证手机号是否有效
|
||||
isPhoneValid() {
|
||||
return this.phone && this.phone.length === 11;
|
||||
},
|
||||
// 验证是否可以登录
|
||||
canLogin() {
|
||||
if (!this.phone || !this.agreement) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.loginType === 'code') {
|
||||
return this.isPhoneValid && this.code && this.code.length === 6;
|
||||
} else {
|
||||
return this.password && this.password.length >= 6;
|
||||
}
|
||||
return this.account &&
|
||||
this.password &&
|
||||
this.password.length >= 6 &&
|
||||
this.agreement;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 获取设备ID(仅APP端)
|
||||
getDeviceId() {
|
||||
// #ifdef APP-PLUS
|
||||
try {
|
||||
// 获取设备信息
|
||||
uni.getSystemInfo({
|
||||
success: (res) => {
|
||||
console.log('设备信息:', res);
|
||||
// 优先使用deviceId,如果没有则使用uuid或其他唯一标识
|
||||
this.deviceId = res.deviceId || res.uuid || res.system + '_' + res.model;
|
||||
console.log('APP设备ID:', this.deviceId);
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('获取设备信息失败:', err);
|
||||
// 如果获取失败,使用一个临时ID
|
||||
this.deviceId = 'unknown_device';
|
||||
}
|
||||
});
|
||||
} catch (err) {
|
||||
console.error('获取设备ID异常:', err);
|
||||
this.deviceId = 'unknown_device';
|
||||
}
|
||||
// #endif
|
||||
|
||||
// #ifdef H5
|
||||
// H5端不传设备ID
|
||||
this.deviceId = '';
|
||||
console.log('H5端不传设备ID');
|
||||
// #endif
|
||||
},
|
||||
|
||||
// 检查token状态
|
||||
checkTokenStatus() {
|
||||
// 如果token有效,则跳转到聊天页面
|
||||
@@ -219,37 +147,7 @@
|
||||
uni.navigateBack();
|
||||
},
|
||||
|
||||
// 切换登录类型
|
||||
switchLoginType(type) {
|
||||
this.loginType = type;
|
||||
},
|
||||
|
||||
// 发送验证码
|
||||
sendCode() {
|
||||
if (this.codeSending || !this.isPhoneValid) return;
|
||||
|
||||
this.codeSending = true;
|
||||
this.countdown = 60;
|
||||
this.codeText = `${this.countdown}秒后重发`;
|
||||
|
||||
// 模拟发送验证码
|
||||
uni.showToast({
|
||||
title: '验证码已发送',
|
||||
icon: 'success'
|
||||
});
|
||||
|
||||
const timer = setInterval(() => {
|
||||
this.countdown--;
|
||||
this.codeText = `${this.countdown}秒后重发`;
|
||||
|
||||
if (this.countdown <= 0) {
|
||||
clearInterval(timer);
|
||||
this.codeSending = false;
|
||||
this.codeText = '发送验证码';
|
||||
}
|
||||
}, 1000);
|
||||
},
|
||||
|
||||
// 用户协议复选框变化
|
||||
checkboxChange(){
|
||||
this.agreement = !this.agreement
|
||||
},
|
||||
@@ -258,7 +156,6 @@
|
||||
// 处理登录
|
||||
async handleLogin() {
|
||||
// 检查是否同意协议
|
||||
console.log(this.agreement)
|
||||
if (!this.agreement) {
|
||||
uni.showToast({
|
||||
title: '请阅读并同意用户协议和隐私政策',
|
||||
@@ -268,24 +165,28 @@
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.canLogin) {
|
||||
// 显示错误原因
|
||||
if (!this.isPhoneValid) {
|
||||
uni.showToast({
|
||||
title: '请输入正确的手机号',
|
||||
icon: 'none'
|
||||
});
|
||||
} else if (this.loginType === 'code' && (!this.code || this.code.length !== 6)) {
|
||||
uni.showToast({
|
||||
title: '请输入6位验证码',
|
||||
icon: 'none'
|
||||
});
|
||||
} else if (this.loginType === 'password' && (!this.password || this.password.length < 6)) {
|
||||
uni.showToast({
|
||||
title: '密码不能少于6位',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
// 验证表单
|
||||
if (!this.account) {
|
||||
uni.showToast({
|
||||
title: '请输入账号',
|
||||
icon: 'none'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.password) {
|
||||
uni.showToast({
|
||||
title: '请输入密码',
|
||||
icon: 'none'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.password.length < 6) {
|
||||
uni.showToast({
|
||||
title: '密码不能少于6位',
|
||||
icon: 'none'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -295,11 +196,16 @@
|
||||
});
|
||||
|
||||
try {
|
||||
// 调用登录API
|
||||
const loginPassword = this.loginType === 'password' ? this.password : this.code;
|
||||
const response = await authApi.login(this.phone, loginPassword);
|
||||
// 调用登录API,传递账号、密码和设备ID(仅APP端传递)
|
||||
const response = await authApi.login(this.account, this.password, this.deviceId);
|
||||
|
||||
console.log(response);
|
||||
console.log('登录响应:', response);
|
||||
// #ifdef APP-PLUS
|
||||
console.log('APP端登录 - 设备ID:', this.deviceId);
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
console.log('H5端登录 - 不传设备ID');
|
||||
// #endif
|
||||
|
||||
if (response.code === 200) { // 成功code是200
|
||||
// 登录成功,缓存token信息
|
||||
@@ -337,20 +243,12 @@
|
||||
}
|
||||
},
|
||||
|
||||
// 第三方登录
|
||||
handleThirdLogin(platform) {
|
||||
// uni.showToast({
|
||||
// title: `${platform === 'wechat' ? '微信' : 'Apple'}登录功能暂未实现`,
|
||||
// icon: 'none'
|
||||
// });
|
||||
},
|
||||
|
||||
// 打开协议
|
||||
openAgreement(type) {
|
||||
// uni.showToast({
|
||||
// title: `打开${type === 'user' ? '用户协议' : '隐私政策'}`,
|
||||
// icon: 'none'
|
||||
// });
|
||||
uni.showToast({
|
||||
title: `打开${type === 'user' ? '用户协议' : '隐私政策'}`,
|
||||
icon: 'none'
|
||||
});
|
||||
},
|
||||
|
||||
// 联系我们
|
||||
@@ -404,42 +302,12 @@
|
||||
padding: 0 30px;
|
||||
}
|
||||
|
||||
.tab-container {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 20px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.tab-item {
|
||||
position: relative;
|
||||
text-align: center;
|
||||
padding: 10px 0;
|
||||
font-size: 16px;
|
||||
color: #666;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.tab-item.active {
|
||||
color: #4080ff;
|
||||
.login-title {
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.tab-item.active::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: -2px;
|
||||
left: 25%;
|
||||
width: 50%;
|
||||
height: 3px;
|
||||
background-color: #4080ff;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.tip-text {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
margin-bottom: 20px;
|
||||
color: #333;
|
||||
margin: 30px 0 40px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.input-item {
|
||||
@@ -447,15 +315,8 @@
|
||||
align-items: center;
|
||||
border-bottom: 1px solid #eee;
|
||||
padding: 12px 0;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.input-prefix {
|
||||
color: #333;
|
||||
margin-right: 10px;
|
||||
padding-right: 10px;
|
||||
border-right: 1px solid #eee;
|
||||
font-size: 14px;
|
||||
min-height: 50px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.input-field {
|
||||
@@ -464,25 +325,9 @@
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.code-input-box {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.send-code-btn {
|
||||
.password-icon {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
background-color: #4080ff;
|
||||
color: #fff;
|
||||
padding: 5px 10px;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.send-code-btn.disabled {
|
||||
background-color: #ccc;
|
||||
}
|
||||
|
||||
.password-icon {
|
||||
padding: 0 5px;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
@@ -526,28 +371,6 @@
|
||||
background-color: #4080ff;
|
||||
}
|
||||
|
||||
.divider {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.divider-line {
|
||||
flex: 1;
|
||||
height: 1px;
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
.divider-text {
|
||||
color: #999;
|
||||
padding: 0 15px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.third-party-login {
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.contact-us {
|
||||
text-align: center;
|
||||
color: #999;
|
||||
|
||||
Reference in New Issue
Block a user