update
22
src/App.vue
@@ -1,14 +1,18 @@
|
||||
<script>
|
||||
import {useUserStore} from "./pinia/UserStore/index.js";
|
||||
import {toPage} from "./utils/uils.js";
|
||||
|
||||
export default {
|
||||
onLaunch: function () {
|
||||
console.log('App Launch')
|
||||
},
|
||||
onShow: function () {
|
||||
console.log('App Show')
|
||||
},
|
||||
onHide: function () {
|
||||
console.log('App Hide')
|
||||
},
|
||||
onLaunch: function () {
|
||||
},
|
||||
onShow: function () {
|
||||
const UserStore = useUserStore();
|
||||
if (!UserStore.isLogin) {
|
||||
toPage('/pages/login/index');
|
||||
}
|
||||
},
|
||||
onHide: function () {
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
18
src/components/SendMsg.vue
Normal file
@@ -0,0 +1,18 @@
|
||||
<script setup>
|
||||
import XLink from "./XLink.vue";
|
||||
import XInput from "./XInput.vue";
|
||||
|
||||
const modalValue = defineModel();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<x-input v-model:model-value="modalValue" placeholder="验证码">
|
||||
<template #suffix>
|
||||
<x-link>发送验证码</x-link>
|
||||
</template>
|
||||
</x-input>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
47
src/components/WXOfficialAccount.vue
Normal file
@@ -0,0 +1,47 @@
|
||||
<script setup>
|
||||
import {onMounted} from "vue";
|
||||
import XModal from "./XModal.vue";
|
||||
import XQrCode from "./XQrCode.vue";
|
||||
|
||||
const show = defineModel('show');
|
||||
|
||||
onMounted(() => {
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<x-modal
|
||||
:show="show">
|
||||
<view class="px-[30rpx] py-[40rpx] relative">
|
||||
<image @click="show=false" class="!w-[52rpx] !h-[52rpx] absolute top-[-110rpx] right-[calc(-100%-10rpx)]" src="/static/icons/close.png"></image>
|
||||
|
||||
<view class="title">关注微信公众号</view>
|
||||
<view class="!mt-[24rpx] w-[320rpx] !mx-auto aspect-square">
|
||||
<x-qr-code size="320rpx" :qrSize="180" content="公众号"></x-qr-code>
|
||||
</view>
|
||||
<view class="desc">截图后扫码,变现快人一步</view>
|
||||
</view>
|
||||
</x-modal>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.title {
|
||||
color: rgb(29, 33, 41);
|
||||
font-size: 34rpx;
|
||||
font-weight: 500;
|
||||
line-height: 48rpx;
|
||||
letter-spacing: 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.desc {
|
||||
margin-top: 24rpx !important;
|
||||
color: rgb(78, 89, 105);
|
||||
font-size: 28rpx;
|
||||
font-weight: 500;
|
||||
line-height: 48rpx;
|
||||
letter-spacing: 0;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
16
src/components/XModal.vue
Normal file
@@ -0,0 +1,16 @@
|
||||
<script setup>
|
||||
const show = defineModel('show');
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<tui-modal
|
||||
padding="0"
|
||||
custom
|
||||
:show="show">
|
||||
<slot></slot>
|
||||
</tui-modal>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -1,19 +1,25 @@
|
||||
<script setup>
|
||||
import {ref} from 'vue';
|
||||
import {isWXWeb} from "../utils/uils.js";
|
||||
|
||||
const {title} = defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
default: document.title || "页面",
|
||||
const {showBack} = defineProps({
|
||||
showBack: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
});
|
||||
|
||||
const title = ref(document.title);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<template v-if="!isWXWeb()">
|
||||
<view class="!flex justify-center items-center h-[100rpx] bg-[#f9f9f9]">
|
||||
<image class="!w-[9px] !h-[17px] cursor-pointer !absolute left-[50rpx]"
|
||||
src="/static/icons/back.png"></image>
|
||||
<image
|
||||
v-if="showBack"
|
||||
class="!w-[9px] !h-[17px] cursor-pointer !absolute left-[50rpx]"
|
||||
src="/static/icons/back.png">
|
||||
</image>
|
||||
|
||||
<view class="title">{{ title }}</view>
|
||||
</view>
|
||||
|
||||
50
src/components/XQrCode.vue
Normal file
@@ -0,0 +1,50 @@
|
||||
<script setup>
|
||||
import {onMounted} from 'vue';
|
||||
import UQRCode from 'uqrcodejs';
|
||||
import {v4} from "uuid";
|
||||
|
||||
const {size, content, qrSize} = defineProps({
|
||||
size: {
|
||||
type: String,
|
||||
default: '160rpx'
|
||||
},
|
||||
qrSize: {
|
||||
type: Number,
|
||||
default: 80
|
||||
},
|
||||
content: {
|
||||
type: String,
|
||||
default: 'https://www.baidu.com'
|
||||
},
|
||||
});
|
||||
|
||||
const ID = v4();
|
||||
|
||||
onMounted(() => {
|
||||
const qr = new UQRCode();
|
||||
qr.data = content;
|
||||
qr.size = qrSize;
|
||||
qr.make();
|
||||
const canvasContext = uni.createCanvasContext(ID, this);
|
||||
qr.canvasContext = canvasContext;
|
||||
qr.drawCanvas();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view id="QRCode">
|
||||
<canvas
|
||||
:id="ID"
|
||||
type="2d"
|
||||
:canvasId="ID"
|
||||
className='!w-full !h-full'>
|
||||
</canvas>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
#QRCode {
|
||||
width: v-bind(size);
|
||||
height: v-bind(size);
|
||||
}
|
||||
</style>
|
||||
@@ -7,11 +7,16 @@ import './scss/index.scss';
|
||||
import './scss/global.scss';
|
||||
import './scss/uni.scss';
|
||||
import propsConfig from "./scss/thorui.config.js";
|
||||
import {createPinia} from "pinia";
|
||||
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate';
|
||||
|
||||
uni.$tui = propsConfig;
|
||||
|
||||
export function createApp() {
|
||||
const app = createSSRApp(App);
|
||||
const pinia = createPinia();
|
||||
pinia.use(piniaPluginPersistedstate);
|
||||
app.use(pinia);
|
||||
return {
|
||||
app,
|
||||
};
|
||||
|
||||
@@ -1,13 +1,5 @@
|
||||
{
|
||||
"pages": [
|
||||
// 其他页面
|
||||
{
|
||||
"path": "pages/login/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "登陆",
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
//pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
|
||||
{
|
||||
"path": "pages/home/index",
|
||||
@@ -36,6 +28,28 @@
|
||||
"navigationBarTitleText": "我的",
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
// 其他页面
|
||||
{
|
||||
"path": "pages/login/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "登陆",
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/register/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "注册",
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/forgotPassword/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "忘记密码",
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
}
|
||||
],
|
||||
"globalStyle": {
|
||||
|
||||
@@ -1,11 +1,57 @@
|
||||
<script setup>
|
||||
import {reactive} from "vue";
|
||||
import XNav from "../../components/XNav.vue";
|
||||
import XLink from "../../components/XLink.vue";
|
||||
import XInput from "../../components/XInput.vue";
|
||||
|
||||
const form = reactive({
|
||||
phone: null,
|
||||
verificationCode: null,
|
||||
password: null,
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!--忘记密码-->
|
||||
<XNav></XNav>
|
||||
|
||||
<view class="relative !px-[36rpx]">
|
||||
<view class="!mt-[56rpx]">
|
||||
<view class="title">修改密码</view>
|
||||
<view class="title-desc">请完成验证后,设置新密码</view>
|
||||
</view>
|
||||
|
||||
<view class="!flex flex-col gap-[56rpx] !mt-[60rpx]">
|
||||
<x-input v-model:model-value="form.phone" placeholder="请输入手机号"></x-input>
|
||||
<x-input v-model:model-value="form.verificationCode" placeholder="验证码">
|
||||
<template #suffix>
|
||||
<x-link>发送验证码</x-link>
|
||||
</template>
|
||||
</x-input>
|
||||
<x-input v-model:model-value="form.phone" placeholder="请输入密码"></x-input>
|
||||
|
||||
<tui-button>确定修改</tui-button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
<style lang="scss" scoped>
|
||||
.title {
|
||||
color: rgb(29, 33, 41);
|
||||
font-size: 26px;
|
||||
font-weight: 700;
|
||||
line-height: 28px;
|
||||
letter-spacing: 0;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.title-desc {
|
||||
margin-top: 16rpx;
|
||||
color: rgb(78, 89, 105);
|
||||
font-size: 28rpx;
|
||||
font-weight: 400;
|
||||
line-height: 56rpx;
|
||||
letter-spacing: 0;
|
||||
text-align: left;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,11 +1,60 @@
|
||||
<script setup>
|
||||
import XNav from "../../components/XNav.vue";
|
||||
import nav1 from '../../static/icons/icon-新手教学.png';
|
||||
import nav2 from '../../static/icons/icon-收益榜单.png';
|
||||
import nav3 from '../../static/icons/icon-邀请好友.png';
|
||||
import nav4 from '../../static/icons/icon-添加客服.png';
|
||||
import nav5 from '../../static/icons/icon-重要消息.png';
|
||||
|
||||
const nav = [
|
||||
{
|
||||
title: '新手教学',
|
||||
icon: nav1,
|
||||
},
|
||||
{
|
||||
title: '收益榜单',
|
||||
icon: nav2,
|
||||
},
|
||||
{
|
||||
title: '邀请好友',
|
||||
icon: nav3,
|
||||
},
|
||||
{
|
||||
title: '添加客服',
|
||||
icon: nav4,
|
||||
},
|
||||
{
|
||||
title: '重要消息',
|
||||
icon: nav5,
|
||||
},
|
||||
];
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!--首页-->
|
||||
<XNav :show-back="false"></XNav>
|
||||
|
||||
<view class="box-border !p-[20rpx]">
|
||||
<swiper class="!h-[240rpx] !w-full overflow-hidden rounded-[8rpx]">
|
||||
<swiper-item class="!w-full !h-full" v-for="i in [1,2,3,4,5]">
|
||||
<image class="!w-full !h-full" mode="widthFix" src="../../static/images/banner占位.png"></image>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
</view>
|
||||
|
||||
<view class="mt-[44rpx] !flex !gap-[50rpx] !mx-[36rpx]">
|
||||
<view v-for="item in nav" :key="item.title" class="!flex flex-col items-center gap-[6rpx]">
|
||||
<view class="!size-[96rpx] rounded-[20rpx] overflow-hidden">
|
||||
<image class="!size-full" :src="item.icon"></image>
|
||||
</view>
|
||||
|
||||
<view class="nav-desc">{{item.title}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.nav-desc {
|
||||
font-size: 20rpx;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import {reactive} from "vue";
|
||||
import XInput from "../../components/XInput.vue";
|
||||
import XLink from "../../components/XLink.vue";
|
||||
import {toPage} from "../../utils/uils.js";
|
||||
|
||||
const form = reactive({
|
||||
phone: null,
|
||||
@@ -14,11 +15,11 @@ const form = reactive({
|
||||
<x-input v-model:model-value="form.phone" placeholder="请输入手机号"></x-input>
|
||||
<x-input v-model:model-value="form.verificationCode" placeholder="密码">
|
||||
<template #suffix>
|
||||
<x-link>忘记密码?</x-link>
|
||||
<x-link @click="toPage('/pages/forgotPassword/index')">忘记密码?</x-link>
|
||||
</template>
|
||||
</x-input>
|
||||
<tui-button class="!mt-[80rpx]">登录</tui-button>
|
||||
<tui-button class="!mt-[40rpx]" plain link>
|
||||
<tui-button @click="toPage('/pages/register/index')" class="!mt-[40rpx]" plain link>
|
||||
<image class="!h-[26rpx]" mode="heightFix" src="../../static/icons/去注册.png"></image>
|
||||
</tui-button>
|
||||
</view>
|
||||
|
||||
@@ -1,24 +1,29 @@
|
||||
<script setup>
|
||||
import {reactive} from "vue";
|
||||
import XInput from "../../components/XInput.vue";
|
||||
import XLink from "../../components/XLink.vue";
|
||||
import {toPage} from "../../utils/uils.js";
|
||||
import SendMsg from "../../components/SendMsg.vue";
|
||||
import {useUserStore} from "../../pinia/UserStore/index.js";
|
||||
|
||||
const {login} = useUserStore();
|
||||
|
||||
const form = reactive({
|
||||
phone: null,
|
||||
verificationCode: null,
|
||||
});
|
||||
|
||||
const success = async () => {
|
||||
login();
|
||||
toPage('/pages/home/index');
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view class="!px-[34rpx] !flex flex-col gap-[40rpx]">
|
||||
<x-input v-model:model-value="form.phone" placeholder="请输入手机号"></x-input>
|
||||
<x-input v-model:model-value="form.verificationCode" placeholder="验证码">
|
||||
<template #suffix>
|
||||
<x-link>发送验证码</x-link>
|
||||
</template>
|
||||
</x-input>
|
||||
<tui-button class="!mt-[80rpx]">登录</tui-button>
|
||||
<tui-button class="!mt-[40rpx]" plain link>
|
||||
<send-msg v-model:model-value="form.verificationCode"></send-msg>
|
||||
<tui-button class="!mt-[80rpx]" @click="success">登录</tui-button>
|
||||
<tui-button @click="toPage('/pages/register/index')" class="!mt-[40rpx]" plain link>
|
||||
<image class="!h-[26rpx]" mode="heightFix" src="../../static/icons/去注册.png"></image>
|
||||
</tui-button>
|
||||
</view>
|
||||
|
||||
@@ -4,8 +4,10 @@ import BulletChat from "./BulletChat.vue";
|
||||
import {ref} from "vue";
|
||||
import AccountLogin from "./AccountLogin.vue";
|
||||
import PhoneLogin from "./PhoneLogin.vue";
|
||||
import WXOfficialAccount from "../../components/WXOfficialAccount.vue";
|
||||
|
||||
const currentTab = ref(0);
|
||||
const showWX = ref(false);
|
||||
const tabs = [
|
||||
{
|
||||
name: '手机号登录',
|
||||
@@ -38,6 +40,8 @@ const tabs = [
|
||||
<PhoneLogin v-if="currentTab === 0"></PhoneLogin>
|
||||
<AccountLogin v-else></AccountLogin>
|
||||
</view>
|
||||
|
||||
<w-x-official-account v-model:show="showWX"></w-x-official-account>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -1,11 +1,59 @@
|
||||
<script setup>
|
||||
import {reactive} from "vue";
|
||||
import XNav from "../../components/XNav.vue";
|
||||
import BulletChat from "../login/BulletChat.vue";
|
||||
import XInput from "../../components/XInput.vue";
|
||||
import SendMsg from "../../components/SendMsg.vue";
|
||||
|
||||
const form = reactive({
|
||||
phone: null,
|
||||
wxCode: null,
|
||||
verificationCode: null,
|
||||
password: null,
|
||||
code: null,
|
||||
});
|
||||
|
||||
const success = () => {
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!--注册-->
|
||||
<XNav></XNav>
|
||||
|
||||
<view class="h-[390rpx] relative overflow-hidden">
|
||||
<image class="!absolute left-1/2 top-1/2 -translate-1/2 !w-[1198rpx] !h-[806rpx] -z-10 !pb-[40rpx]"
|
||||
src="/static/icons/bg.png"></image>
|
||||
|
||||
<view class="!flex gap-[16rpx] items-center !mt-[56rpx] !ml-[16rpx]">
|
||||
<image class="!w-[68rpx] !h-[68rpx]" src="/static/icons/hi.png"></image>
|
||||
<view class="title">欢迎注册</view>
|
||||
</view>
|
||||
|
||||
<BulletChat></BulletChat>
|
||||
</view>
|
||||
|
||||
<view class="h-full bg-white !-mt-[20rpx] rounded-t-[20rpx] !pt-[44rpx]">
|
||||
<view class="!px-[34rpx] !flex flex-col gap-[40rpx]">
|
||||
<x-input v-model:model-value="form.wxCode" placeholder="请输入微信号"></x-input>
|
||||
<x-input v-model:model-value="form.phone" placeholder="请输入手机号"></x-input>
|
||||
<send-msg v-model:model-value="form.verificationCode"></send-msg>
|
||||
<x-input v-model:model-value="form.password" placeholder="请输入登录密码"></x-input>
|
||||
<x-input v-model:model-value="form.code" placeholder="请输入邀请码"></x-input>
|
||||
|
||||
<tui-button class="!mt-[52rpx]" @click="success">确认注册</tui-button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.title {
|
||||
color: rgb(29, 33, 41);
|
||||
font-size: 26px;
|
||||
font-weight: 700;
|
||||
line-height: 28px;
|
||||
letter-spacing: 0;
|
||||
text-align: left;
|
||||
}
|
||||
</style>
|
||||
|
||||
30
src/pinia/UserStore/index.js
Normal file
@@ -0,0 +1,30 @@
|
||||
import {defineStore} from "pinia";
|
||||
import {ref} from "vue";
|
||||
|
||||
export const useUserStore = defineStore('UserStore', () => {
|
||||
const isLogin = ref(false);
|
||||
const userInfo = ref(null);
|
||||
|
||||
const login = () => {
|
||||
isLogin.value = true;
|
||||
}
|
||||
|
||||
return {
|
||||
isLogin,
|
||||
userInfo,
|
||||
login,
|
||||
}
|
||||
}, {
|
||||
persist: {
|
||||
key: 'UserStore',
|
||||
storage: {
|
||||
getItem(key) {
|
||||
return uni.getStorageSync(key);
|
||||
},
|
||||
setItem(key, value) {
|
||||
uni.setStorageSync(key, value);
|
||||
}
|
||||
},
|
||||
pick: ['isLogin', 'userInfo']
|
||||
}
|
||||
});
|
||||
@@ -2,3 +2,7 @@
|
||||
border: 1px solid red;
|
||||
@apply box-border;
|
||||
}
|
||||
|
||||
.tui-btn {
|
||||
border-radius: 12rpx !important;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
Page {
|
||||
--primary-color: #2D5CF6;
|
||||
}
|
||||
page {
|
||||
background-color: #F2F3F5;
|
||||
}
|
||||
|
||||
BIN
src/static/icons/close.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
src/static/icons/icon-收益榜单.png
Executable file
|
After Width: | Height: | Size: 904 B |
BIN
src/static/icons/icon-新手教学.png
Executable file
|
After Width: | Height: | Size: 792 B |
BIN
src/static/icons/icon-添加客服.png
Executable file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
src/static/icons/icon-邀请好友.png
Executable file
|
After Width: | Height: | Size: 858 B |
BIN
src/static/icons/icon-重要消息.png
Executable file
|
After Width: | Height: | Size: 854 B |
BIN
src/static/images/banner占位.png
Normal file
|
After Width: | Height: | Size: 173 KiB |
@@ -13,3 +13,9 @@ export const isWXWeb = () => {
|
||||
const userAgent = navigator.userAgent;
|
||||
return userAgent.includes('MicroMessenger');
|
||||
}
|
||||
|
||||
export const toPage = (url) => {
|
||||
uni.reLaunch({
|
||||
url: url,
|
||||
}).then();
|
||||
}
|
||||
|
||||