Merge branch 'main' of https://git.brother7.cn/zoujing/YGChatCS
This commit is contained in:
17
App.vue
17
App.vue
@@ -1,8 +1,21 @@
|
||||
<script setup>
|
||||
import { onLaunch, onShow, onHide } from "@dcloudio/uni-app";
|
||||
import { checkPhone } from "@/manager/LoginManager";
|
||||
import { goHome } from "@/hooks/useGoHome";
|
||||
|
||||
onLaunch(() => {
|
||||
onLaunch(async () => {
|
||||
console.log("App Launch");
|
||||
|
||||
const token = uni.getStorageSync("token");
|
||||
|
||||
// 检测是否绑定手机号和token
|
||||
if (token) {
|
||||
const res = await checkPhone();
|
||||
|
||||
if (res.data) {
|
||||
goHome();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
onShow(() => {
|
||||
@@ -20,7 +33,7 @@ page,
|
||||
body,
|
||||
#app {
|
||||
font-family: PingFang SC, PingFang SC;
|
||||
background-color: #E9F3F7;
|
||||
background-color: #e9f3f7;
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
}
|
||||
|
||||
BIN
components/CheckBox/images/checked.png
Normal file
BIN
components/CheckBox/images/checked.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 805 B |
BIN
components/CheckBox/images/unchecked.png
Normal file
BIN
components/CheckBox/images/unchecked.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
35
components/CheckBox/index.vue
Normal file
35
components/CheckBox/index.vue
Normal file
@@ -0,0 +1,35 @@
|
||||
<template>
|
||||
<view class="checkbox-wrapper" @click="onChange">
|
||||
<image class="checkbox-icon" :src="isChecked" mode="aspectFit" />
|
||||
<slot></slot>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, defineEmits } from "vue";
|
||||
import uncheckedIcon from "./images/unchecked.png";
|
||||
import checkedIcon from "./images/checked.png";
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(["update:modelValue"]);
|
||||
|
||||
// 计算属性,确定当前是否选中
|
||||
const isChecked = computed(() => {
|
||||
return props.modelValue ? checkedIcon : uncheckedIcon;
|
||||
});
|
||||
|
||||
// 切换选中状态
|
||||
const onChange = () => {
|
||||
emit("update:modelValue", !props.modelValue);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "./styles/index.scss";
|
||||
</style>
|
||||
12
components/CheckBox/propmt.md
Normal file
12
components/CheckBox/propmt.md
Normal file
@@ -0,0 +1,12 @@
|
||||
## 复选框组件
|
||||
|
||||
## 提示词:
|
||||
|
||||
使用 uniapp + vue3 组合式 api 开发微信小程序,要求如下:
|
||||
1、按照提供的图片高度还原交互设计
|
||||
2、要求布局样式结构简洁明了,class 命名请按照模块名称来命名,例如:.checkbox-wrapper
|
||||
3、可以使用 uniapp 内置的组件
|
||||
|
||||
## 备注
|
||||
|
||||
仅供学习、交流使用,请勿用于商业用途。
|
||||
10
components/CheckBox/styles/index.scss
Normal file
10
components/CheckBox/styles/index.scss
Normal file
@@ -0,0 +1,10 @@
|
||||
.checkbox-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.checkbox-icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
1
hooks/useGoHome.js
Normal file
1
hooks/useGoHome.js
Normal file
@@ -0,0 +1 @@
|
||||
export const goHome = () => uni.reLaunch({ url: "/pages/index/index" });
|
||||
@@ -1,13 +1,10 @@
|
||||
export function getWeChatAuthCode() {
|
||||
export const getWeChatAuthCode = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.login({
|
||||
provider: 'weixin',
|
||||
onlyAuthorize: true,
|
||||
success: (res) => {
|
||||
if (res.code) {
|
||||
resolve(res.code);
|
||||
} else {
|
||||
reject(new Error('未获取到微信授权code'));
|
||||
}
|
||||
resolve(res.code);
|
||||
},
|
||||
fail: (err) => {
|
||||
reject(err);
|
||||
|
||||
@@ -1,20 +1,18 @@
|
||||
import { login } from "../request/api/LoginApi";
|
||||
|
||||
import { wxLogin, bindUserPhone, checkUserPhone } from "../request/api/LoginApi";
|
||||
import { getWeChatAuthCode } from "./AuthManager";
|
||||
|
||||
export async function loginAuth() {
|
||||
const loginAuth = async () => {
|
||||
try {
|
||||
const openIdCode = 'brother7'// await getWeChatAuthCode();
|
||||
const openIdCode = await getWeChatAuthCode();
|
||||
console.log('获取到的微信授权code:', openIdCode);
|
||||
const response = await login({
|
||||
const response = await wxLogin({
|
||||
openIdCode: [openIdCode],
|
||||
grant_type: 'password',
|
||||
grant_type: 'wechat',
|
||||
scope: 'server',
|
||||
//clientId: '1',
|
||||
username: 'admin',
|
||||
password: 'YehdBPev',
|
||||
|
||||
clientId: '2'
|
||||
});
|
||||
console.log('获取到的微信授权response:', response);
|
||||
|
||||
if (response.access_token) {
|
||||
uni.setStorageSync('token', response.access_token)
|
||||
return response;
|
||||
@@ -25,3 +23,23 @@ export async function loginAuth() {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
const bindPhone = async (params) => {
|
||||
try {
|
||||
const response = await bindUserPhone(params)
|
||||
return response;
|
||||
} catch (error) {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
const checkPhone = async (phone) => {
|
||||
try {
|
||||
const response = await checkUserPhone(phone)
|
||||
return response;
|
||||
} catch (error) {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
export { loginAuth, bindPhone, checkPhone }
|
||||
|
||||
@@ -48,14 +48,16 @@
|
||||
/* ios打包配置 */
|
||||
"ios" : {},
|
||||
/* SDK配置 */
|
||||
"sdkConfigs" : {}
|
||||
"sdkConfigs" : {
|
||||
"oauth" : {}
|
||||
}
|
||||
}
|
||||
},
|
||||
/* 快应用特有相关 */
|
||||
"quickapp" : {},
|
||||
/* 小程序特有相关 */
|
||||
"mp-weixin" : {
|
||||
"appid" : "wx6d8bb61f9480d79f",
|
||||
"appid" : "wx5e79df5996572539",
|
||||
"setting" : {
|
||||
"urlCheck" : false
|
||||
},
|
||||
|
||||
77
pages.json
77
pages.json
@@ -1,39 +1,42 @@
|
||||
{
|
||||
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
|
||||
{
|
||||
"path": "pages/index/index",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
|
||||
},
|
||||
{
|
||||
"path" : "pages/chat/ChatQuickAccess",
|
||||
"style" :
|
||||
{
|
||||
"navigationBarTitleText" : ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/order/list",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
|
||||
},
|
||||
{
|
||||
"path": "pages/order/detail",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
|
||||
}
|
||||
],
|
||||
"globalStyle": {
|
||||
// "navigationBarTextStyle": "black",
|
||||
// // "navigationBarTitleText": "小沐",
|
||||
// "navigationBarBackgroundColor": "#F8F8F8",
|
||||
// "backgroundColor": "#F8F8F8"
|
||||
},
|
||||
"uniIdRouter": {}
|
||||
"pages": [
|
||||
//pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
|
||||
{
|
||||
"path": "pages/login/index",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/index/index",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/chat/ChatQuickAccess",
|
||||
"style": {
|
||||
"navigationBarTitleText": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/order/list",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/order/detail",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
}
|
||||
],
|
||||
"globalStyle": {
|
||||
// "navigationBarTextStyle": "black",
|
||||
// // "navigationBarTitleText": "小沐",
|
||||
// "navigationBarBackgroundColor": "#F8F8F8",
|
||||
// "backgroundColor": "#F8F8F8"
|
||||
},
|
||||
"uniIdRouter": {}
|
||||
}
|
||||
|
||||
@@ -1,44 +1,42 @@
|
||||
<template>
|
||||
<ex-drawer ref='drawer' width="488">
|
||||
<!-- 抽屉页面 -->
|
||||
<view class="mian-drawer" slot="drawerContent">
|
||||
<drawer-home @closeDrawer="closeDrawer" ></drawer-home>
|
||||
</view>
|
||||
|
||||
<!-- 主页面 -->
|
||||
<view class="mian-container" slot="containerContent">
|
||||
<chat-main-list @openDrawer="openDrawer"></chat-main-list>
|
||||
</view>
|
||||
</ex-drawer>
|
||||
<ex-drawer ref="drawer" width="488">
|
||||
<!-- 抽屉页面 -->
|
||||
<view class="mian-drawer" slot="drawerContent">
|
||||
<drawer-home @closeDrawer="closeDrawer"></drawer-home>
|
||||
</view>
|
||||
|
||||
<!-- 主页面 -->
|
||||
<view class="mian-container" slot="containerContent">
|
||||
<chat-main-list @openDrawer="openDrawer"></chat-main-list>
|
||||
</view>
|
||||
</ex-drawer>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import exDrawer from '@/third/ex-drawer/ex-drawer.vue'
|
||||
import DrawerHome from '@/pages/drawer/DrawerHome.vue'
|
||||
import ChatMainList from '../chat/ChatMainList.vue'
|
||||
import { ref, onMounted } from "vue";
|
||||
import exDrawer from "@/third/ex-drawer/ex-drawer.vue";
|
||||
import DrawerHome from "@/pages/drawer/DrawerHome.vue";
|
||||
import ChatMainList from "../chat/ChatMainList.vue";
|
||||
|
||||
const drawer = ref()
|
||||
const drawer = ref();
|
||||
|
||||
const openDrawer = () => {
|
||||
drawer.value.open()
|
||||
}
|
||||
|
||||
const closeDrawer = () => {
|
||||
drawer.value.close()
|
||||
}
|
||||
const openDrawer = () => {
|
||||
drawer.value.open();
|
||||
};
|
||||
|
||||
const closeDrawer = () => {
|
||||
drawer.value.close();
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.mian-drawer{
|
||||
height: 100vh;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
.mian-container{
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
.mian-drawer {
|
||||
height: 100vh;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
.mian-container {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
</style>
|
||||
BIN
pages/login/images/bg.png
Normal file
BIN
pages/login/images/bg.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 139 KiB |
BIN
pages/login/images/dh.png
Normal file
BIN
pages/login/images/dh.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 37 KiB |
BIN
pages/login/images/dhwq.png
Normal file
BIN
pages/login/images/dhwq.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
110
pages/login/index.vue
Normal file
110
pages/login/index.vue
Normal file
@@ -0,0 +1,110 @@
|
||||
<template>
|
||||
<view class="login-wrapper">
|
||||
<image class="bg" src="./images/bg.png"></image>
|
||||
<!-- 头部内容 -->
|
||||
<view class="login-header">
|
||||
<!-- 卡通形象 -->
|
||||
<image class="login-avatar" src="./images/dh.png" mode="widthFix"></image>
|
||||
<image
|
||||
class="login-title"
|
||||
src="./images/dhwq.png"
|
||||
mode="widthFix"
|
||||
></image>
|
||||
|
||||
<!-- 描述 -->
|
||||
<view class="login-desc">您好,欢迎来到朵花温泉!</view>
|
||||
</view>
|
||||
|
||||
<!-- 按钮区域 -->
|
||||
<view class="login-btn-area">
|
||||
<!-- 同意隐私协议并获取手机号按钮 -->
|
||||
|
||||
<button
|
||||
v-if="!isAgree"
|
||||
class="login-btn"
|
||||
type="primary"
|
||||
@click="handleAgreeAndGetPhone"
|
||||
>
|
||||
微信一键登录
|
||||
</button>
|
||||
<button
|
||||
v-if="isAgree"
|
||||
class="login-btn"
|
||||
open-type="getPhoneNumber"
|
||||
type="primary"
|
||||
@getphonenumber="onLogin"
|
||||
>
|
||||
微信一键登录
|
||||
</button>
|
||||
</view>
|
||||
|
||||
<!-- 协议勾选 -->
|
||||
<view class="login-agreement">
|
||||
<CheckBox v-model="isAgree">
|
||||
<text class="login-agreement-text">阅读并同意</text>
|
||||
<navigator
|
||||
url="/pages/service-agreement/service-agreement"
|
||||
class="login-agreement-link"
|
||||
>《服务协议》</navigator
|
||||
>
|
||||
<text class="login-agreement-text">和</text>
|
||||
<navigator
|
||||
url="/pages/privacy-policy/privacy-policy"
|
||||
class="login-agreement-link"
|
||||
>《隐私协议》</navigator
|
||||
>
|
||||
</CheckBox>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import CheckBox from "@/components/CheckBox/index.vue";
|
||||
import { loginAuth, bindPhone, checkPhone } from "@/manager/LoginManager";
|
||||
import { goHome } from "@/hooks/useGoHome";
|
||||
|
||||
const isAgree = ref(false);
|
||||
|
||||
// 同意隐私协议并获取手机号
|
||||
const handleAgreeAndGetPhone = () => {
|
||||
if (!isAgree.value) {
|
||||
uni.showToast({
|
||||
title: "请先同意服务协议和隐私协议",
|
||||
icon: "none",
|
||||
});
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
const onLogin = (e) => {
|
||||
const { code } = e.detail;
|
||||
console.error("onLogin code", code);
|
||||
|
||||
loginAuth()
|
||||
.then(async () => {
|
||||
// 检测是否绑定手机号,已绑定则直接跳转首页,未绑定则获取手机号并绑定
|
||||
const res = await checkPhone();
|
||||
|
||||
if (res.data) {
|
||||
return goHome();
|
||||
}
|
||||
|
||||
const { data } = await bindPhone({
|
||||
wechatPhoneCode: code,
|
||||
clientId: "2",
|
||||
});
|
||||
|
||||
if (data) {
|
||||
goHome();
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error("登录失败", err);
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "./styles/index.scss";
|
||||
</style>
|
||||
12
pages/login/prompt.md
Normal file
12
pages/login/prompt.md
Normal file
@@ -0,0 +1,12 @@
|
||||
## 登录页面
|
||||
|
||||
## 提示词:
|
||||
|
||||
使用 uniapp + vue3 组合式 api 开发微信小程序,要求如下:
|
||||
1、按照提供的图片高度还原交互设计
|
||||
2、要求布局样式结构简洁明了,class 命名请按照模块名称来命名,例如:.login-wrapper
|
||||
3、可以使用 uniapp 内置的组件
|
||||
|
||||
## 备注
|
||||
|
||||
仅供学习、交流使用,请勿用于商业用途。
|
||||
70
pages/login/styles/index.scss
Normal file
70
pages/login/styles/index.scss
Normal file
@@ -0,0 +1,70 @@
|
||||
.login-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
font-family: PingFang SC, PingFang SC;
|
||||
height: 100vh;
|
||||
padding-top: 168px;
|
||||
position: relative;
|
||||
|
||||
.bg {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: -1;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
|
||||
.login-header {
|
||||
text-align: center;
|
||||
|
||||
.login-avatar {
|
||||
width: 150px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.login-title {
|
||||
width: 137px;
|
||||
margin: 6px auto;
|
||||
}
|
||||
|
||||
.login-desc {
|
||||
font-size: 12px;
|
||||
color: #1E4C69;
|
||||
line-height: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
.login-btn-area {
|
||||
margin-top: 46px;
|
||||
width: 297px;
|
||||
|
||||
.login-btn {
|
||||
background: linear-gradient( 246deg, #22A7FF 0%, #2567FF 100%);
|
||||
width: 100%;
|
||||
border-radius: 50px;
|
||||
}
|
||||
}
|
||||
|
||||
.login-agreement {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.login-agreement-text {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.login-agreement-link {
|
||||
font-size: 14px;
|
||||
color: #007aff;
|
||||
margin: 0 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"appid": "wx6d8bb61f9480d79f",
|
||||
"appid": "wx5e79df5996572539",
|
||||
"compileType": "miniprogram",
|
||||
"libVersion": "3.8.10",
|
||||
"packOptions": {
|
||||
|
||||
@@ -1,14 +1,26 @@
|
||||
import request from "../base/request";
|
||||
|
||||
function login(args) {
|
||||
const wxLogin = (args) => {
|
||||
const config = {
|
||||
header: {
|
||||
Authorization: 'Basic Y3VzdG9tOmN1c3RvbQ==', // 可在此动态设置 token
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
},
|
||||
header: {
|
||||
'Authorization': 'Basic Y3VzdG9tOmN1c3RvbQ==', // 可在此动态设置 token
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
},
|
||||
};
|
||||
|
||||
uni.setStorageSync('token', '')
|
||||
return request.post('/auth/oauth2/token', args, config);
|
||||
|
||||
return request.post('/auth/oauth2/token', args, config);
|
||||
}
|
||||
|
||||
export { login }
|
||||
// 绑定用户手机号
|
||||
const bindUserPhone = (args) => {
|
||||
return request.post('/hotelBiz/user/bindUserPhone', args);
|
||||
}
|
||||
|
||||
// 检测用户是否绑定手机号
|
||||
const checkUserPhone = (args) => {
|
||||
return request.get('/hotelBiz/user/checkUserHasBindPhone', args);
|
||||
}
|
||||
|
||||
export { wxLogin, bindUserPhone, checkUserPhone }
|
||||
Reference in New Issue
Block a user