feat: 更新API基础URL并重构登录流程

- 将API基础URL从http更新为https并添加shop-api路径
- 移除订单相关页面和代码
- 重构登录流程,使用微信openId登录
- 删除人脸识别登录功能及相关代码
- 更新token工具函数,移除测试token
This commit is contained in:
dzq 2025-11-04 09:15:36 +08:00
parent 71993d9a77
commit 148cfdcf2d
9 changed files with 18 additions and 402 deletions

4
env/.env vendored
View File

@ -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'

View File

@ -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/'

2
env/.env.production vendored
View File

@ -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'

View File

@ -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 });
}

View File

@ -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",

View File

@ -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>

View File

@ -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,22 +73,12 @@ const login = () => {
uni.login({
provider: 'weixin', //使
success: function (loginRes) {
smallLogin({
code: loginRes.code,
}).then((res) => {
console.log(res);
setToken(res.token)
doLogin()
loading.value = false
}).catch((e)=>{
loading.value = false
// uni.showToast({
// title: API_BASE_URL + JSON.stringify(e),
// icon: 'none'
// })
})
mpCodeToOpenId(loginRes.code).then((openId) => {
console.log('openId:', openId)
loading.value = false
}).catch((e) => {
loading.value = false
})
},
});
}

View File

@ -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',

View File

@ -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;
}