feat: 更新API基础URL并重构登录流程
- 将API基础URL从http更新为https并添加shop-api路径 - 移除订单相关页面和代码 - 重构登录流程,使用微信openId登录 - 删除人脸识别登录功能及相关代码 - 更新token工具函数,移除测试token
This commit is contained in:
parent
71993d9a77
commit
148cfdcf2d
|
|
@ -11,7 +11,7 @@ VITE_APP_PUBLIC_BASE=/
|
|||
|
||||
# 后台请求地址
|
||||
# VITE_SERVER_BASEURL = 'http://localhost:8090/api/'
|
||||
VITE_SERVER_BASEURL = 'http://wxshop.ab98.cn'
|
||||
VITE_SERVER_BASEURL = 'https://wxshop.ab98.cn/shop-api/api/'
|
||||
# 后台上传地址
|
||||
VITE_UPLOAD_BASEURL = 'http://localhost:8081/upload'
|
||||
# 汇邦云token请求地址
|
||||
|
|
@ -22,7 +22,7 @@ VITE_APP_PROXY_ENABLE = true
|
|||
VITE_APP_PROXY_PREFIX = '/api/'
|
||||
|
||||
# 第二个请求地址 (目前alova中可以使用)
|
||||
VITE_API_SECONDARY_URL = 'http://wxshop.ab98.cn'
|
||||
VITE_API_SECONDARY_URL = 'https://wxshop.ab98.cn/shop-api/api/'
|
||||
|
||||
# 认证模式,'single' | 'double' ==> 单token | 双token
|
||||
VITE_AUTH_MODE = 'single'
|
||||
|
|
|
|||
|
|
@ -11,4 +11,4 @@ VITE_SHOW_SOURCEMAP = false
|
|||
#VITE_HUIBANG_BASEURL = 'https://www.ab98.cn'
|
||||
|
||||
# VITE_SERVER_BASEURL = 'http://localhost:8090/api/'
|
||||
VITE_SERVER_BASEURL = 'http://wxshop.ab98.cn'
|
||||
VITE_SERVER_BASEURL = 'https://wxshop.ab98.cn/shop-api/api/'
|
||||
|
|
|
|||
|
|
@ -6,5 +6,5 @@ VITE_DELETE_CONSOLE = true
|
|||
VITE_SHOW_SOURCEMAP = false
|
||||
|
||||
# 后台请求地址
|
||||
VITE_SERVER_BASEURL = 'http://wxshop.ab98.cn'
|
||||
VITE_SERVER_BASEURL = 'https://wxshop.ab98.cn/shop-api/api/'
|
||||
VITE_HUIBANG_BASEURL = 'https://www.ab98.cn'
|
||||
|
|
|
|||
|
|
@ -5,3 +5,7 @@ import type { CurrentUserResponseData } from './types';
|
|||
export async function getCurrentUserApi() {
|
||||
return await http.get<CurrentUserResponseData>("users/me");
|
||||
}
|
||||
|
||||
export async function mpCodeToOpenId(code: string) {
|
||||
return await http.get<string>("wx/mpCodeToOpenId", { code });
|
||||
}
|
||||
|
|
@ -31,12 +31,6 @@
|
|||
"pagePath": "pages/index/index",
|
||||
"text": "首页"
|
||||
},
|
||||
{
|
||||
"iconPath": "/static/tabbar/order.png",
|
||||
"selectedIconPath": "/static/tabbar/orderHL.png",
|
||||
"pagePath": "pages/order/index",
|
||||
"text": "订单"
|
||||
},
|
||||
{
|
||||
"iconPath": "/static/tabbar/personal.png",
|
||||
"selectedIconPath": "/static/tabbar/personalHL.png",
|
||||
|
|
@ -65,14 +59,6 @@
|
|||
"path": "pages/index/checkout",
|
||||
"type": "page"
|
||||
},
|
||||
{
|
||||
"path": "pages/login/faceLogin",
|
||||
"type": "page",
|
||||
"style": {
|
||||
"navigationBarTitleText": "人脸识别",
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/login/login",
|
||||
"type": "page",
|
||||
|
|
|
|||
|
|
@ -1,360 +0,0 @@
|
|||
<script setup lang="ts">
|
||||
import { doGetToken } from "@/api/login/HuiBang";
|
||||
import { loginFaceLogin } from "@/api/login";
|
||||
definePage({
|
||||
style: {
|
||||
navigationBarTitleText: '人脸识别',
|
||||
navigationStyle: 'custom',
|
||||
},
|
||||
})
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { HUIBANG_BASE_URL } from '@/config/setting';
|
||||
import {ensureDecodeURIComponent, parseUrlToObj} from "@/utils";
|
||||
import {isPageTabbar} from "@/tabbar/store";
|
||||
import {setToken} from "@/utils/token-util";
|
||||
import {loginPublic} from "@/utils/login-util";
|
||||
import {tabbarList} from "@/tabbar/config";
|
||||
const code = ref<string>('');//用于辅助验证人脸的code
|
||||
const showFace = ref<boolean>(false);
|
||||
const facingMode = ref<string>("user");//摄像头类型
|
||||
const mediaStreamTrack = ref();// 媒体流,用于关闭摄像头
|
||||
const videoStyle = ref(
|
||||
{
|
||||
width: '250px',
|
||||
height: '250px',
|
||||
transform: 'rotate(0deg)',
|
||||
borderRadius: '50%',
|
||||
}
|
||||
)
|
||||
const videoStyle2 = ref(
|
||||
{
|
||||
width: '250px',
|
||||
height: '250px',
|
||||
borderRadius: '50%',
|
||||
}
|
||||
)
|
||||
const ssoToken = ref<string>('');
|
||||
const userFaceImage = ref<string>(''); //人脸图片
|
||||
|
||||
onMounted(() => {
|
||||
code.value = uni.getStorageSync("u-code");
|
||||
})
|
||||
|
||||
const onCodeConfirm = () => {
|
||||
if (code.value.length < 4) {
|
||||
uni.showToast({ title: "请填写完整信息", icon: 'none'})
|
||||
return;
|
||||
}
|
||||
showFace.value = true;
|
||||
init();
|
||||
}
|
||||
|
||||
const init = () => {
|
||||
getToken();
|
||||
invokingCamera();
|
||||
}
|
||||
|
||||
//初始化镜头
|
||||
const invokingCamera = () => {
|
||||
showFace.value = true;
|
||||
// 检查浏览器对摄像头的支持情况
|
||||
|
||||
console.log(navigator,'参数数据')
|
||||
|
||||
if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
|
||||
uni.showToast({ title: "您的设备不支持打开摄像头功能", icon: 'none'})
|
||||
return;
|
||||
}
|
||||
const constraints = {
|
||||
audio: false,
|
||||
video: {
|
||||
// 前置摄像头
|
||||
facingMode: {
|
||||
exact: facingMode.value
|
||||
},
|
||||
// 手机端相当于高
|
||||
width: 200,
|
||||
// 手机端相当于宽
|
||||
height: 200,
|
||||
},
|
||||
};
|
||||
// 请求摄像头权限并获取视频流
|
||||
navigator.mediaDevices.getUserMedia(constraints)
|
||||
.then((stream) => {
|
||||
mediaStreamTrack.value = stream;
|
||||
// 成功获取到视频流,这里可以对视频流进行处理
|
||||
// 例如,将视频流显示在页面上的某个元素中
|
||||
const videoElement = document.querySelector("video");
|
||||
videoElement!.srcObject = stream;
|
||||
videoElement!.play();
|
||||
setTimeout(() => {
|
||||
handlePhotographClick();
|
||||
}, 1000);
|
||||
})
|
||||
.catch((err) => {
|
||||
// 获取视频流失败,进行相应提示
|
||||
console.log('获取摄像头视频流失败:', err);
|
||||
})
|
||||
}
|
||||
//关闭镜头
|
||||
const handlePhotographCloseClick = () => {
|
||||
if (mediaStreamTrack.value) {
|
||||
// 关闭摄像头
|
||||
mediaStreamTrack.value.getTracks().forEach(function (track: any) {
|
||||
track.stop();
|
||||
});
|
||||
mediaStreamTrack.value = null;
|
||||
}
|
||||
}
|
||||
//拍照
|
||||
const handlePhotographClick = () => {
|
||||
const canvas = document.createElement("canvas");
|
||||
const ctx = canvas.getContext("2d");
|
||||
const video = document.querySelector("video");
|
||||
canvas.width = Math.min(video!.videoWidth, video!.videoHeight);
|
||||
canvas.height = Math.max(video!.videoWidth, video!.videoHeight);
|
||||
// canvas.width = Math.max(video.videoWidth, video.videoHeight);
|
||||
// canvas.height = Math.min(video.videoWidth, video.videoHeight);
|
||||
//console.log(canvas.width);
|
||||
//console.log(canvas.height);
|
||||
ctx!.drawImage(video!, 0, 0, canvas.width, canvas.height);
|
||||
|
||||
// ****** 镜像处理 ******
|
||||
function getPixel(imageData: any, row: any, column: any) {
|
||||
const uint8ClampedArray = imageData.data;
|
||||
const width = imageData.width;
|
||||
const height = imageData.height;
|
||||
const pixel = [];
|
||||
for (let i = 0; i < 4; i++) {
|
||||
pixel.push(uint8ClampedArray[row * width * 4 + column * 4 + i]);
|
||||
}
|
||||
return pixel;
|
||||
}
|
||||
|
||||
function setPixel(imageData: any, row: any, column: any, pixel: any) {
|
||||
const uint8ClampedArray = imageData.data;
|
||||
const width = imageData.width;
|
||||
const height = imageData.height;
|
||||
for (let i = 0; i < 4; i++) {
|
||||
uint8ClampedArray[row * width * 4 + column * 4 + i] = pixel[i];
|
||||
}
|
||||
}
|
||||
|
||||
const mirrorImageData = ctx!.createImageData(canvas.width, canvas.height);
|
||||
const imageData = ctx!.getImageData(0, 0, canvas.width, canvas.height);
|
||||
for (let h = 0; h < canvas.height; h++) {
|
||||
for (let w = 0; w < canvas.width; w++) {
|
||||
const pixel = getPixel(imageData, h, canvas.width - w - 1);
|
||||
setPixel(mirrorImageData, h, w, pixel);
|
||||
}
|
||||
}
|
||||
ctx!.putImageData(mirrorImageData, 0, 0);
|
||||
// ****** 镜像处理 ******
|
||||
const base64 = canvas.toDataURL("image/jpeg");
|
||||
userFaceImage.value = base64;
|
||||
//console.log(self.userFaceImage);
|
||||
faceLogin();
|
||||
}
|
||||
//切换镜头
|
||||
const handleChangeFacingMode = () => {
|
||||
facingMode.value = facingMode.value === 'user' ? 'environment' : 'user';
|
||||
handlePhotographCloseClick();
|
||||
invokingCamera();
|
||||
}
|
||||
//获取token
|
||||
const getToken = () => {
|
||||
doGetToken().then((token: string) => {
|
||||
ssoToken.value = token
|
||||
})
|
||||
}
|
||||
//人脸登录
|
||||
const faceLogin = () => {
|
||||
uni.request({
|
||||
url: HUIBANG_BASE_URL + '/api/doInterface?code=doStrongFaceLogin',
|
||||
data: {
|
||||
token: ssoToken.value,
|
||||
check_code: code.value,
|
||||
imgBase64: userFaceImage.value.split(',')[1]
|
||||
},
|
||||
method: 'POST',
|
||||
header: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
success: (res: any) => {
|
||||
if (res.data.state === 'ok') {
|
||||
uni.setStorageSync("u-code", code.value);
|
||||
loginFaceLogin({ token: res.data.token }).then((res) => {
|
||||
setToken(res.token)
|
||||
doLogin()
|
||||
handlePhotographCloseClick();
|
||||
})
|
||||
} else {
|
||||
handlePhotographClick();
|
||||
}
|
||||
},
|
||||
fail: (res) => {
|
||||
uni.showToast({ title: JSON.stringify(res), icon: 'none'})
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
const back = () => {
|
||||
uni.navigateBack({
|
||||
delta: 1
|
||||
})
|
||||
}
|
||||
|
||||
const showKeyboard = ref(false);
|
||||
const redirectUrl = ref('')
|
||||
|
||||
|
||||
onLoad((options) => {
|
||||
console.log('login options: ', options)
|
||||
if (options.redirect) {
|
||||
redirectUrl.value = ensureDecodeURIComponent(options.redirect)
|
||||
}
|
||||
else {
|
||||
redirectUrl.value = tabbarList[0].pagePath
|
||||
}
|
||||
console.log('redirectUrl.value: ', redirectUrl.value)
|
||||
})
|
||||
|
||||
function doLogin() {
|
||||
console.log(redirectUrl.value)
|
||||
let path = redirectUrl.value
|
||||
if (!path.startsWith('/')) {
|
||||
path = `/${path}`
|
||||
}
|
||||
const { path: _path, query } = parseUrlToObj(path)
|
||||
console.log('_path:', _path, 'query:', query, 'path:', path)
|
||||
console.log('isPageTabbar(_path):', isPageTabbar(_path))
|
||||
if (isPageTabbar(_path)) {
|
||||
// 经过我的测试 switchTab 不能带 query 参数, 不管是放到 url 还是放到 query ,
|
||||
// 最后跳转过去的时候都会丢失 query 信息
|
||||
uni.switchTab({
|
||||
url: path,
|
||||
})
|
||||
}
|
||||
else {
|
||||
console.log('redirectTo:', path)
|
||||
uni.redirectTo({
|
||||
url: path,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
<template>
|
||||
<view class="content">
|
||||
<wd-navbar title="人脸识别" left-text="返回" placeholder fixed left-arrow right-text="按钮" @click-left="back">
|
||||
<template #right>
|
||||
<wd-icon v-if="showFace" name="camera" size="22px" @click="handleChangeFacingMode"></wd-icon>
|
||||
</template>
|
||||
</wd-navbar>
|
||||
<view class="body">
|
||||
<view v-if="!showFace" class="code">
|
||||
<view class="des">
|
||||
<h3>填写您的手机/身份证后四位</h3>
|
||||
<p style="margin-top: 15px;color:#909399 ;">请在此处输入</p>
|
||||
</view>
|
||||
<view class="code-input">
|
||||
<!-- 密码输入框 -->
|
||||
<wd-password-input :length="4" v-model="code" :mask="false" :focused="showKeyboard" @focus="showKeyboard = true" />
|
||||
<!-- 数字键盘 -->
|
||||
<wd-number-keyboard v-model="code" extra-key="X" v-model:visible="showKeyboard" :maxlength="4" @blur="showKeyboard = false" />
|
||||
</view>
|
||||
<view class="submit">
|
||||
<view @click="onCodeConfirm" >确定</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-else class="face">
|
||||
<view class="face-box">
|
||||
<video id="video" autoplay :style="facingMode === 'user' ? videoStyle2 : videoStyle" object-fit="fill">
|
||||
</video>
|
||||
</view>
|
||||
<view class="face-tip">
|
||||
<p>请平视摄像头,并保持光线充足</p>
|
||||
</view>
|
||||
<!-- <view class="face-button">
|
||||
<u-button type="primary" text="开始识别" @click="init()"></u-button>
|
||||
</view> -->
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.content {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.body {
|
||||
height: calc(100% - 85px);
|
||||
background-color: #ffffff;
|
||||
padding: 20px;
|
||||
|
||||
.code {
|
||||
height: calc(100%);
|
||||
//display: flex;
|
||||
//flex-direction: column;
|
||||
//align-items: center;
|
||||
|
||||
.des {
|
||||
width: 100%;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.code-input {
|
||||
margin-top: 40px;
|
||||
margin-bottom: 80px;
|
||||
}
|
||||
|
||||
.submit {
|
||||
width: 100%;
|
||||
div {
|
||||
line-height: 96rpx;
|
||||
border-radius: 20rpx;
|
||||
text-align: center;
|
||||
font-size: 32rpx;
|
||||
color: #ffffff;
|
||||
background-color: #409EFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.face {
|
||||
height: calc(100%);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
.face-tip {
|
||||
color: #909399;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.face-button {
|
||||
width: 100%;
|
||||
margin-top: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
video {
|
||||
transform: rotateY(180deg);
|
||||
-webkit-transform: rotateY(180deg);
|
||||
/* Safari 和 Chrome */
|
||||
-moz-transform: rotateY(180deg);
|
||||
border: 1px solid;
|
||||
}
|
||||
|
||||
/* 移除:deep()选择器,直接使用类名 */
|
||||
.uni-video-bar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.uni-video-cover {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,17 +1,15 @@
|
|||
<script lang="ts" setup>
|
||||
// import { useTokenStore } from '@/store/token'
|
||||
import { useUserStore } from '@/store/user'
|
||||
import { tabbarList } from '@/tabbar/config'
|
||||
import { isPageTabbar } from '@/tabbar/store'
|
||||
import { ensureDecodeURIComponent } from '@/utils'
|
||||
import { parseUrlToObj } from '@/utils'
|
||||
// import { loginPublic } from "@/utils/login-util";
|
||||
import { ICOFaceRecognition } from '@/components/icons'
|
||||
import { doGetToken,sendMsgCode } from '@/api/login/HuiBang'
|
||||
import {loginByMsgCode, smallLogin} from '@/api/login'
|
||||
import { setToken } from '@/utils/token-util'
|
||||
import { useMessage } from 'wot-design-uni'
|
||||
import {API_BASE_URL} from "@/config/setting";
|
||||
import { mpCodeToOpenId } from '@/api/users'
|
||||
const message = useMessage('wd-message-box-slot')
|
||||
|
||||
definePage({
|
||||
|
|
@ -34,8 +32,6 @@ onLoad((options) => {
|
|||
console.log('redirectUrl.value: ', redirectUrl.value)
|
||||
})
|
||||
|
||||
const userStore = useUserStore()
|
||||
// const tokenStore = useTokenStore()
|
||||
function doLogin() {
|
||||
console.log(redirectUrl.value)
|
||||
let path = redirectUrl.value
|
||||
|
|
@ -77,21 +73,11 @@ const login = () => {
|
|||
uni.login({
|
||||
provider: 'weixin', //使用微信登录
|
||||
success: function (loginRes) {
|
||||
|
||||
smallLogin({
|
||||
code: loginRes.code,
|
||||
}).then((res) => {
|
||||
console.log(res);
|
||||
setToken(res.token)
|
||||
doLogin()
|
||||
|
||||
mpCodeToOpenId(loginRes.code).then((openId) => {
|
||||
console.log('openId:', openId)
|
||||
loading.value = false
|
||||
}).catch((e)=>{
|
||||
}).catch((e) => {
|
||||
loading.value = false
|
||||
// uni.showToast({
|
||||
// title: API_BASE_URL + JSON.stringify(e),
|
||||
// icon: 'none'
|
||||
// })
|
||||
})
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -34,12 +34,12 @@ export const nativeTabbarList: NativeTabBarItem[] = [
|
|||
pagePath: 'pages/index/index',
|
||||
text: '首页',
|
||||
},
|
||||
{
|
||||
/* {
|
||||
iconPath: '/static/tabbar/order.png',
|
||||
selectedIconPath: '/static/tabbar/orderHL.png',
|
||||
pagePath: 'pages/order/index',
|
||||
text: '订单',
|
||||
},
|
||||
}, */
|
||||
{
|
||||
iconPath: '/static/tabbar/personal.png',
|
||||
selectedIconPath: '/static/tabbar/personalHL.png',
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import { TOKEN_CACHE_NAME,TOKEN_CACHE_NAME_UNIFY } from '@/config/setting';
|
|||
* 获取缓存的token
|
||||
*/
|
||||
export function getToken(): string | null {
|
||||
return 'test';
|
||||
return null;
|
||||
const token = uni.getStorageSync(TOKEN_CACHE_NAME)
|
||||
return token;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue