update:新增机构扫码登录页

This commit is contained in:
2026-07-31 09:42:59 +08:00
parent 970a9874b4
commit f34800798d
5 changed files with 200 additions and 9 deletions
+7 -1
View File
@@ -8,7 +8,7 @@ try {
switch (envVersion) {
case "develop": // 开发版
// BASE_URL = "http://192.168.1.2:8000/api/shoot";
// BASE_URL = "http://192.168.1.30:8000/api/shoot";
BASE_URL = "https://apitest.shelingxingqiu.com/api/shoot";
break;
case "trial": // 体验版
@@ -233,6 +233,12 @@ export const checkUserBindAPI = async (code) => {
});
};
export const tempBindOrgAPI = (scene) => {
return request("POST", "/user/org/device/tempBind", {
scene,
});
};
export const bindDeviceAPI = (device) => {
return request("POST", "/user/device/bindDevice", {
device,
+5
View File
@@ -32,6 +32,10 @@ const props = defineProps({
type: Function,
default: () => {},
},
onSuccess: {
type: Function,
default: () => {},
},
});
const agree = ref(false);
const phone = ref("");
@@ -127,6 +131,7 @@ async function doLogin() {
clearDevice();
}
props.onClose();
await props.onSuccess();
} catch (error) {
console.log("login error", error);
} finally {
+3
View File
@@ -3,6 +3,9 @@
{
"path": "pages/index"
},
{
"path": "pages/org-bind"
},
{
"path": "pages/friend-battle"
},
+177
View File
@@ -0,0 +1,177 @@
<script setup>
import { ref } from "vue";
import { onLoad } from "@dcloudio/uni-app";
import Signin from "@/components/Signin.vue";
import SButton from "@/components/SButton.vue";
import { tempBindOrgAPI } from "@/apis";
const scene = ref("");
const status = ref("idle");
const errorMessage = ref("");
const showSignin = ref(false);
const binding = ref(false);
const getToken = () => {
try {
const env = uni.getAccountInfoSync().miniProgram.envVersion;
return uni.getStorageSync(`${env}_token`);
} catch (error) {
return "";
}
};
const openSignin = () => {
showSignin.value = true;
};
const closeSignin = () => {
showSignin.value = false;
};
const bindOrg = async () => {
if (binding.value || !scene.value) return;
if (!getToken()) {
status.value = "login";
return;
}
binding.value = true;
status.value = "binding";
errorMessage.value = "";
try {
await tempBindOrgAPI(scene.value);
status.value = "success";
} catch (error) {
if (error?.type === "AUTH_INVALID") {
status.value = "login";
errorMessage.value = "登录已失效,请重新登录后完成绑定。";
} else {
status.value = "failed";
errorMessage.value = error?.message || "网络异常,请稍后重试。";
}
} finally {
binding.value = false;
}
};
const handleLoginSuccess = async () => {
await bindOrg();
};
onLoad((options) => {
try {
const value = decodeURIComponent(String(options?.scene || ""));
if (!/^org_\d+$/.test(value)) {
status.value = "invalid";
return;
}
scene.value = value;
if (getToken()) {
void bindOrg();
} else {
status.value = "login";
}
} catch (error) {
status.value = "invalid";
}
});
</script>
<template>
<view class="page">
<view class="content">
<text class="title">机构设备绑定</text>
<view v-if="status === 'idle' || status === 'binding'" class="state">
<text class="state-title">正在绑定</text>
<text class="description">正在绑定机构设备请稍候</text>
</view>
<view v-else-if="status === 'login'" class="state">
<text class="state-title">请先登录</text>
<text class="description">
{{
errorMessage ||
"登录后即可绑定当前机构设备。关闭登录窗口后,也可以再次点击下方按钮继续。"
}}
</text>
<SButton width="560rpx" :rounded="20" :onClick="openSignin">
<text>立即登录</text>
</SButton>
</view>
<view v-else-if="status === 'success'" class="state">
<text class="state-title">绑定成功</text>
<text class="description">
您的账号已成功绑定机构设备请返回 iPad 继续操作
</text>
</view>
<view v-else-if="status === 'failed'" class="state">
<text class="state-title">绑定失败</text>
<text class="description">{{ errorMessage }}</text>
<SButton width="560rpx" :rounded="20" :onClick="bindOrg">
<text>重新绑定</text>
</SButton>
</view>
<view v-else class="state">
<text class="state-title">二维码无效</text>
<text class="description">请重新扫描机构设备上的小程序码</text>
</view>
</view>
<Signin
:show="showSignin"
:onClose="closeSignin"
:onSuccess="handleLoginSuccess"
/>
</view>
</template>
<style scoped lang="scss">
.page {
box-sizing: border-box;
width: 100%;
min-height: 100vh;
padding: calc(var(--status-bar-height) + 120rpx) 48rpx 80rpx;
background-color: #000;
color: #fff;
}
.content {
display: flex;
flex-direction: column;
align-items: center;
}
.title {
font-size: 44rpx;
font-weight: 600;
}
.state {
width: 100%;
margin-top: 120rpx;
display: flex;
flex-direction: column;
align-items: center;
}
.state-title {
font-size: 36rpx;
font-weight: 600;
}
.description {
max-width: 600rpx;
margin: 32rpx 0 64rpx;
color: #b8b8b8;
font-size: 28rpx;
line-height: 1.8;
text-align: center;
}
</style>
+2 -2
View File
@@ -24,8 +24,8 @@ function createWebSocket(token, onMessage) {
switch (envVersion) {
case "develop": // 开发版
// url = "ws://192.168.1.2:8000/socket";
url = "wss://apitest.shelingxingqiu.com/socket";
// url = "ws://192.168.1.30:8000/socket";
// url = "wss://apitest.shelingxingqiu.com/socket";
break;
case "trial": // 体验版
url = "wss://apitest.shelingxingqiu.com/socket";