This commit is contained in:
2025-03-26 19:10:41 +08:00
parent 9463635e03
commit 3c85d9e0e7
28 changed files with 907 additions and 147 deletions

View File

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

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

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

View File

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

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

View File

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

View File

@@ -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": {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View 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']
}
});

View File

@@ -2,3 +2,7 @@
border: 1px solid red;
@apply box-border;
}
.tui-btn {
border-radius: 12rpx !important;
}

View File

@@ -1,3 +1,6 @@
Page {
--primary-color: #2D5CF6;
}
page {
background-color: #F2F3F5;
}

BIN
src/static/icons/close.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 904 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 792 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 858 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 854 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 KiB

View File

@@ -13,3 +13,9 @@ export const isWXWeb = () => {
const userAgent = navigator.userAgent;
return userAgent.includes('MicroMessenger');
}
export const toPage = (url) => {
uni.reLaunch({
url: url,
}).then();
}