🎉 项目基础架构完成
This commit is contained in:
@@ -0,0 +1,259 @@
|
||||
<script setup lang="ts">
|
||||
import resolveConfig from 'tailwindcss/resolveConfig';
|
||||
import tailwindConfig from '~/tailwind.config';
|
||||
import type { Config } from 'tailwindcss';
|
||||
import { useWindowSize } from '@vueuse/core';
|
||||
|
||||
const theme = useThemeStore();
|
||||
const config = resolveConfig(tailwindConfig as Config);
|
||||
const { collapsed, manualCollapsed } = storeToRefs(useSystemStore());
|
||||
const lg = parseFloat(
|
||||
config.theme.screens.lg.substring(0, config.theme.screens.lg.length - 2),
|
||||
);
|
||||
const modeName = ref('sunny');
|
||||
// watch()
|
||||
// computed(())
|
||||
watch(useWindowSize().width, (val) => {
|
||||
console.log(val);
|
||||
console.log(collapsed.value);
|
||||
console.log(manualCollapsed.value);
|
||||
setCollapsed(val);
|
||||
});
|
||||
function setCollapsed(val: number) {
|
||||
if ((val > lg && !collapsed.value) || (val < lg && collapsed.value)) {
|
||||
manualCollapsed.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (val > lg && collapsed.value) {
|
||||
if (manualCollapsed.value) return;
|
||||
collapsed.value = false;
|
||||
} else if (val < lg && !collapsed.value) {
|
||||
if (manualCollapsed.value) return;
|
||||
collapsed.value = true;
|
||||
}
|
||||
}
|
||||
function changeCollapsed() {
|
||||
collapsed.value = !collapsed.value;
|
||||
manualCollapsed.value = true;
|
||||
}
|
||||
const { currentPage } = storeToRefs(useSystemStore());
|
||||
|
||||
function changeMode() {
|
||||
const x = useColorMode();
|
||||
console.log(x.preference);
|
||||
console.log(x.value);
|
||||
if (x.preference === 'light') {
|
||||
x.preference = 'dark';
|
||||
modeName.value = 'moon';
|
||||
} else if (x.preference === 'dark') {
|
||||
x.preference = 'sepia';
|
||||
modeName.value = 'tea';
|
||||
} else {
|
||||
x.preference = 'light';
|
||||
modeName.value = 'sunny';
|
||||
}
|
||||
}
|
||||
function changeTheme() {
|
||||
console.log(theme.theme);
|
||||
if (theme.theme === 'default') {
|
||||
theme.setTheme('test');
|
||||
} else if (theme.theme === 'test') {
|
||||
theme.setTheme('self');
|
||||
} else if (theme.theme === 'self') {
|
||||
theme.setTheme('default');
|
||||
}
|
||||
}
|
||||
|
||||
function backToLogin() {
|
||||
const router = useRouter();
|
||||
router.push('/login');
|
||||
}
|
||||
|
||||
watch(currentPage, (val) => {
|
||||
const router = useRouter();
|
||||
router.push('/base/' + val);
|
||||
});
|
||||
|
||||
async function sendTest() {
|
||||
try {
|
||||
// const response = await $fetch('/api/login/test', {
|
||||
// method: 'GET',
|
||||
// });
|
||||
$fetch('/api/file/test', { method: 'GET' }).catch(() => {
|
||||
console.log('error');
|
||||
$fetch('/api/login/login', {
|
||||
method: 'POST',
|
||||
body: {
|
||||
username: 'admin',
|
||||
password: 'password',
|
||||
},
|
||||
}).then(async () => {
|
||||
const result = await $fetch('/api/file/test', { method: 'GET' });
|
||||
console.log(result);
|
||||
});
|
||||
});
|
||||
// const response = await $fetch('/api/login/login', {
|
||||
// method: 'POST',
|
||||
// body: {
|
||||
// username: 'admin',
|
||||
// password: 'password',
|
||||
// },
|
||||
// });
|
||||
// console.log(response);
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
}
|
||||
onMounted(() => setCollapsed(useWindowSize().width.value));
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<t-layout class="h-full">
|
||||
<t-header>
|
||||
<t-head-menu value="item1" height="120px">
|
||||
<span class="text-xl">李晨鑫 的 Web 实验</span>
|
||||
<template #operations>
|
||||
<a @click="changeMode">
|
||||
<t-icon class="t-menu__operations-icon" :name="modeName" />
|
||||
</a>
|
||||
<a @click="changeTheme">
|
||||
<t-icon class="t-menu__operations-icon" name="fill-color" />
|
||||
</a>
|
||||
<a @click="backToLogin">
|
||||
<t-icon class="t-menu__operations-icon" name="rollback" />
|
||||
</a>
|
||||
<t-button @click="sendTest" />
|
||||
</template>
|
||||
<!-- <template #logo>-->
|
||||
<!-- <img-->
|
||||
<!-- width="136"-->
|
||||
<!-- class="logo"-->
|
||||
<!-- src="https://www.tencent.com/img/index/menu_logo_hover.png"-->
|
||||
<!-- alt="logo"-->
|
||||
<!-- />-->
|
||||
<!-- </template>-->
|
||||
<!-- <t-menu-item value="item1"> 已选内容 </t-menu-item>-->
|
||||
<!-- <t-menu-item value="item2"> 菜单内容一 </t-menu-item>-->
|
||||
<!-- <t-menu-item value="item3"> 菜单内容二 </t-menu-item>-->
|
||||
<!-- <t-menu-item value="item4" :disabled="true"> 菜单内容三 </t-menu-item>-->
|
||||
<!-- <template #operations>-->
|
||||
<!-- <a href="javascript:;"-->
|
||||
<!-- ><t-icon class="t-menu__operations-icon" name="search"-->
|
||||
<!-- /></a>-->
|
||||
<!-- <a href="javascript:;"-->
|
||||
<!-- ><t-icon class="t-menu__operations-icon" name="notification-filled"-->
|
||||
<!-- /></a>-->
|
||||
<!-- <a href="javascript:;"-->
|
||||
<!-- ><t-icon class="t-menu__operations-icon" name="index"-->
|
||||
<!-- /></a>-->
|
||||
<!-- </template>-->
|
||||
</t-head-menu>
|
||||
</t-header>
|
||||
<t-layout :class="{ collapsed: collapsed, 'non-collapsed': !collapsed }">
|
||||
<t-aside class="border-t border-gray-100 dark:border-gray-700">
|
||||
<t-menu
|
||||
v-model="currentPage"
|
||||
theme="light"
|
||||
value="dashboard"
|
||||
height="550px"
|
||||
:collapsed="collapsed"
|
||||
>
|
||||
<t-menu-item value="home">
|
||||
<template #icon>
|
||||
<t-icon name="home" />
|
||||
</template>
|
||||
首页
|
||||
</t-menu-item>
|
||||
<t-submenu value="resource" title="功能菜单">
|
||||
<template #icon>
|
||||
<t-icon name="server" />
|
||||
</template>
|
||||
<t-menu-item value="peopleManage">
|
||||
<span>用户管理</span>
|
||||
</t-menu-item>
|
||||
<t-menu-item value="fileManage">
|
||||
<span>文件管理</span>
|
||||
</t-menu-item>
|
||||
</t-submenu>
|
||||
<t-menu-item value="root">
|
||||
<template #icon>
|
||||
<t-icon name="root-list" />
|
||||
</template>
|
||||
导航三
|
||||
</t-menu-item>
|
||||
<t-menu-item value="control-platform">
|
||||
<template #icon>
|
||||
<t-icon name="control-platform" />
|
||||
</template>
|
||||
导航四
|
||||
</t-menu-item>
|
||||
<t-menu-item value="precise-monitor">
|
||||
<template #icon>
|
||||
<t-icon name="precise-monitor" />
|
||||
</template>
|
||||
导航五
|
||||
</t-menu-item>
|
||||
<t-menu-item value="mail">
|
||||
<template #icon>
|
||||
<t-icon name="mail" />
|
||||
</template>
|
||||
导航六
|
||||
</t-menu-item>
|
||||
<t-menu-item value="user-circle">
|
||||
<template #icon>
|
||||
<t-icon name="user-circle" />
|
||||
</template>
|
||||
导航七
|
||||
</t-menu-item>
|
||||
<t-menu-item value="play-circle">
|
||||
<template #icon>
|
||||
<t-icon name="play-circle" />
|
||||
</template>
|
||||
导航八
|
||||
</t-menu-item>
|
||||
<t-menu-item value="edit1">
|
||||
<template #icon>
|
||||
<t-icon name="edit-1" />
|
||||
</template>
|
||||
导航九
|
||||
</t-menu-item>
|
||||
<template #operations>
|
||||
<t-button
|
||||
class="t-demo-collapse-btn"
|
||||
variant="text"
|
||||
shape="square"
|
||||
@click="changeCollapsed"
|
||||
>
|
||||
<template #icon>
|
||||
<t-icon name="view-list" />
|
||||
</template>
|
||||
</t-button>
|
||||
</template>
|
||||
</t-menu>
|
||||
</t-aside>
|
||||
<t-layout>
|
||||
<t-content class="overflow-auto">
|
||||
<NuxtPage />
|
||||
</t-content>
|
||||
<t-footer class="m-auto">
|
||||
Copyright @ 2019-{{ new Date().getFullYear() }} Tencent. All Rights
|
||||
Reserved
|
||||
</t-footer>
|
||||
</t-layout>
|
||||
</t-layout>
|
||||
</t-layout>
|
||||
</template>
|
||||
|
||||
<style scoped lang="less">
|
||||
.collapsed {
|
||||
:deep(.t-layout__sider) {
|
||||
@apply w-20;
|
||||
}
|
||||
}
|
||||
.non-collapsed {
|
||||
:deep(.t-layout__sider) {
|
||||
@apply w-60;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,30 @@
|
||||
<script setup lang="ts">
|
||||
const x = ref();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="p-6">
|
||||
<div class="flex md:flex-row flex-col">
|
||||
<div class="flex-[1] m-2 max-h-80">
|
||||
<div class="flex flex-row md:flex-col justify-center">
|
||||
<span class="text-2xl ml-auto mr-auto md:mt-6 mt-20 mb-6"
|
||||
>欢迎 {{ useUserStore().userName }}
|
||||
</span>
|
||||
<t-image
|
||||
src="/avatar.jpg"
|
||||
alt="头像"
|
||||
shape="circle"
|
||||
:fit="'contain'"
|
||||
class="max-h-80 max-w-80 m-auto"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex-[2] m-2">
|
||||
<t-calendar> </t-calendar>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="less"></style>
|
||||
@@ -0,0 +1,87 @@
|
||||
<script setup lang="tsx">
|
||||
import SuperTable from '~/components/SuperTable.vue';
|
||||
import type { TableProps } from 'tdesign-vue-next';
|
||||
|
||||
const pagination = ref<TableProps['pagination']>({
|
||||
defaultPageSize: 10,
|
||||
total: 100,
|
||||
defaultCurrent: 1,
|
||||
});
|
||||
const columns = ref<TableProps['columns']>([
|
||||
{
|
||||
colKey: 'index',
|
||||
title: '序号',
|
||||
},
|
||||
{
|
||||
colKey: 'date',
|
||||
title: '日期',
|
||||
},
|
||||
{
|
||||
colKey: 'name',
|
||||
title: '姓名',
|
||||
},
|
||||
{
|
||||
colKey: 'province',
|
||||
title: '省份',
|
||||
},
|
||||
{
|
||||
colKey: 'city',
|
||||
title: '市区',
|
||||
},
|
||||
{
|
||||
colKey: 'address',
|
||||
title: '地址',
|
||||
},
|
||||
{
|
||||
colKey: '',
|
||||
title: '邮编',
|
||||
},
|
||||
{
|
||||
colKey: 'operator',
|
||||
title: '操作',
|
||||
cell: (_, { row }) => (
|
||||
<div>
|
||||
<t-button onClick={() => editUser(row)}>编辑</t-button>
|
||||
<t-button onClick={() => deleteUser(row)}>删除</t-button>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
]);
|
||||
const data = ref([]);
|
||||
for (let i = 0; i < 30; i++) {
|
||||
data.value.push({
|
||||
index: i + 1,
|
||||
date: '2023-10-01',
|
||||
name: 'John Doe',
|
||||
province: 'Province A',
|
||||
city: 'City A',
|
||||
address: 'Address A',
|
||||
postalCode: '123456',
|
||||
} as never);
|
||||
}
|
||||
|
||||
function editUser(row: never) {}
|
||||
|
||||
function deleteUser(row: never) {}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="p-6">
|
||||
<div class="flex justify-between p-4">
|
||||
<t-button>新增</t-button>
|
||||
<t-input placeholder="搜索" clearable class="max-w-60">
|
||||
<template #suffixIcon>
|
||||
<search-icon :style="{ cursor: 'pointer' }" />
|
||||
</template>
|
||||
</t-input>
|
||||
</div>
|
||||
<super-table
|
||||
:data="data"
|
||||
:columns="columns"
|
||||
:loading="false"
|
||||
:pagination="pagination"
|
||||
></super-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="less"></style>
|
||||
@@ -0,0 +1,69 @@
|
||||
<template>
|
||||
<div class="flex flex-col items-center px-4 py-10 gap-y-8 h-full">
|
||||
<h1 class="text-[26px]">Nuxt & TDesign Vue Next</h1>
|
||||
<div class="space-x-2">
|
||||
<TButton
|
||||
ghost
|
||||
@click="
|
||||
$colorMode.preference =
|
||||
$colorMode.preference === 'light' ? 'dark' : 'light'
|
||||
"
|
||||
>
|
||||
<template #icon>
|
||||
<TIcon
|
||||
class="mr-1"
|
||||
:name="$colorMode.preference === 'light' ? 'heart' : 'heart-filled'"
|
||||
/>
|
||||
当前主题:{{ $colorMode.preference === 'light' ? 'Light' : 'Dark' }}
|
||||
</template>
|
||||
</TButton>
|
||||
</div>
|
||||
<div class="flex items-center gap-x-4">
|
||||
<TButton @click="theme.setTheme('default')">默认主题</TButton>
|
||||
<TButton @click="theme.setTheme('test')">主题 1</TButton>
|
||||
<TButton @click="theme.setTheme('self')">主题 2</TButton>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 sm:flex flex-row items-center gap-2">
|
||||
<TButton>按钮示例</TButton>
|
||||
<TButton theme="warning" loading>按钮示例</TButton>
|
||||
<TButton theme="danger" disabled>按钮示例</TButton>
|
||||
<TButton theme="success" variant="outline">按钮示例</TButton>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col sm:flex-row items-center gap-4">
|
||||
<!-- tag-name 和 TagName 写法都可以 -->
|
||||
<t-switch v-model="isLoading" class="flex-none" size="large">
|
||||
<template #label> 加载中 </template>
|
||||
</t-switch>
|
||||
<TTagInput v-model="tags" drag-sort clearable>
|
||||
<template #label> 你喜欢的前端框架: </template>
|
||||
</TTagInput>
|
||||
</div>
|
||||
<TAlert :theme="alertTheme" close>{{ date }}</TAlert>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const theme = useThemeStore();
|
||||
|
||||
const tags = ref(['Vue', 'React', 'Angular']);
|
||||
const isLoading = ref(true);
|
||||
const alertTheme = ref<'success' | 'warning' | 'error' | 'info'>('success');
|
||||
let date: Date;
|
||||
|
||||
onMounted(() => {
|
||||
date = new Date();
|
||||
setInterval(() => {
|
||||
isLoading.value = !isLoading.value;
|
||||
if (alertTheme.value === 'success') {
|
||||
alertTheme.value = 'warning';
|
||||
} else if (alertTheme.value === 'warning') {
|
||||
alertTheme.value = 'error';
|
||||
} else if (alertTheme.value === 'error') {
|
||||
alertTheme.value = 'info';
|
||||
} else {
|
||||
alertTheme.value = 'success';
|
||||
}
|
||||
}, 2000);
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,74 @@
|
||||
<script setup lang="ts">
|
||||
import { PageType } from '~/stores/login';
|
||||
|
||||
const store = useLoginStore();
|
||||
const { currentType, loginForm } = storeToRefs(store);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="w-full">
|
||||
<div
|
||||
class="flex md:flex-row items-center md:justify-center w-full flex-col gap-4"
|
||||
>
|
||||
<div class="flex flex-col items-center gap-4">
|
||||
<button class="w-56 h-10 bg-qqColor text-white rounded-md"
|
||||
><img class="max-h-7 inline" src="/QQ.png" alt="QQ logo" />
|
||||
<span class="text-white">QQ登录</span>
|
||||
</button>
|
||||
<button class="w-56 h-10 bg-wechatColor rounded-md"
|
||||
><img
|
||||
class="max-h-7 inline"
|
||||
src="public/微信.png"
|
||||
alt="wechat logo"
|
||||
/>
|
||||
<span class="text-white">微信登录</span>
|
||||
</button>
|
||||
<button class="w-56 h-10 bg-alipayColor rounded-md"
|
||||
><img
|
||||
class="max-h-7 inline"
|
||||
src="public/支付,支付宝.png"
|
||||
alt="alipay logo"
|
||||
/>
|
||||
<span class="text-black">支付宝登录</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="relative hidden md:flex flex-col items-center gap-4 w-2/5 max-w-24 select-none"
|
||||
>
|
||||
<div class="w-1 h-44 bg-gray-200"></div>
|
||||
<div
|
||||
class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 rounded-full border-4 border-gray-200 w-10 h-10 bg-loginBG"
|
||||
>
|
||||
<span
|
||||
class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 z-1"
|
||||
>or
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col items-center gap-4 mt-3 md:mt-0">
|
||||
<TInput
|
||||
v-model="loginForm.username"
|
||||
class="w-56"
|
||||
placeholder="请输入用户名"
|
||||
/>
|
||||
<TInput
|
||||
v-model="loginForm.password"
|
||||
class="w-56"
|
||||
type="password"
|
||||
placeholder="请输入密码"
|
||||
/>
|
||||
<TButton class="w-56" @click="store.login">登录</TButton>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="flex flex-row items-center bg-gray-600 w-full h-10 justify-around rounded-b-md mt-4"
|
||||
>
|
||||
<button class="text-white" @click="currentType = PageType.register"
|
||||
>注册
|
||||
</button>
|
||||
<button class="text-white" @click="currentType = PageType.reset"
|
||||
>忘记密码
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,140 @@
|
||||
<script setup lang="ts">
|
||||
import type {
|
||||
FormProps,
|
||||
UploadInstanceFunctions,
|
||||
FormInstanceFunctions,
|
||||
} from 'tdesign-vue-next';
|
||||
import type { IAPIResponse } from '~/utils/APIResponse';
|
||||
const store = useLoginStore();
|
||||
const { registerForm, currentType } = storeToRefs(store);
|
||||
const rules: FormProps['rules'] = {
|
||||
email: [
|
||||
{ required: true, message: '请输入邮箱', trigger: 'blur' },
|
||||
{ email: true, message: '请输入邮箱', trigger: 'change' },
|
||||
],
|
||||
username: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
|
||||
password: [{ required: true, message: '请输入密码', trigger: 'blur' }],
|
||||
passwordRepeat: [
|
||||
{ required: true, message: '请再次输入密码', trigger: 'blur' },
|
||||
{
|
||||
validator: (val) => val === registerForm.value.password,
|
||||
message: '两次输入密码不一致',
|
||||
trigger: 'change',
|
||||
},
|
||||
],
|
||||
birth: [{ required: true, message: '请输入出生日期', trigger: 'change' }],
|
||||
};
|
||||
const uploadImage = ref<UploadInstanceFunctions>();
|
||||
const formInstance = ref<FormInstanceFunctions>();
|
||||
async function submitForm() {
|
||||
console.log(formInstance.value);
|
||||
if (!formInstance.value) return;
|
||||
const result = await formInstance.value.validate();
|
||||
if (typeof result === 'boolean' && result) {
|
||||
formInstance.value.submit();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="w-full">
|
||||
<div class="flex md:flex-row flex-col items-center gap-4 justify-around">
|
||||
<div class="flex flex-col items-center gap-4 max-w-96">
|
||||
<t-form
|
||||
ref="formInstance"
|
||||
:label-width="10"
|
||||
:data="registerForm"
|
||||
:rules="rules"
|
||||
@submit="() => store.register()"
|
||||
>
|
||||
<t-form-item name="email">
|
||||
<TInput v-model="registerForm.email" placeholder="请输入邮箱" />
|
||||
</t-form-item>
|
||||
<t-form-item name="username">
|
||||
<TInput
|
||||
v-model="registerForm.username"
|
||||
placeholder="请输入用户名"
|
||||
/>
|
||||
</t-form-item>
|
||||
<t-form-item name="password">
|
||||
<TInput
|
||||
v-model="registerForm.password"
|
||||
placeholder="请输入密码"
|
||||
type="password"
|
||||
/>
|
||||
</t-form-item>
|
||||
<t-form-item name="passwordRepeat">
|
||||
<TInput
|
||||
v-model="registerForm.passwordRepeat"
|
||||
placeholder="请再次输入密码"
|
||||
type="password"
|
||||
/>
|
||||
</t-form-item>
|
||||
<t-form-item name="birth">
|
||||
<TDatePicker
|
||||
v-model="registerForm.birth"
|
||||
placeholder="请输入出生日期"
|
||||
/>
|
||||
</t-form-item>
|
||||
</t-form>
|
||||
</div>
|
||||
|
||||
<TUpload
|
||||
ref="uploadImage"
|
||||
action="/api/file/uploadAvatar"
|
||||
class="set-width-length bg-white bg-opacity-70"
|
||||
theme="custom"
|
||||
accept="image/*"
|
||||
:draggable="true"
|
||||
:format-response="
|
||||
(res) => {
|
||||
res = res as IAPIResponse<string>;
|
||||
if (res.code === 200) {
|
||||
registerForm.avatarURL = res.data;
|
||||
return { url: res.data };
|
||||
}
|
||||
return { fail: res.message };
|
||||
}
|
||||
"
|
||||
>
|
||||
<div v-if="registerForm.avatarURL" class="aspect-square h-full">
|
||||
<t-image
|
||||
:src="registerForm.avatarURL"
|
||||
class="w-40 h-40 object-cover rounded-md"
|
||||
fit="contain"
|
||||
/>
|
||||
</div>
|
||||
<div v-else>
|
||||
<span class="text-blue-400"> 点击上传头像</span>
|
||||
<span> / 拖拽到此区域 </span>
|
||||
</div>
|
||||
</TUpload>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="flex flex-row items-center bg-gray-600 w-full h-10 justify-around rounded-b-md mt-4"
|
||||
>
|
||||
<button class="text-white" @click="submitForm">注册用户</button>
|
||||
<button class="text-white" @click="currentType = PageType.login"
|
||||
>返回登录
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="less">
|
||||
:deep(.t-upload__dragger),
|
||||
.set-width-length {
|
||||
@apply w-64;
|
||||
@apply h-40;
|
||||
@apply p-0;
|
||||
@apply border-0;
|
||||
}
|
||||
// {
|
||||
// @apply w-40;
|
||||
// @apply h-40;
|
||||
//}
|
||||
:deep(.t-date-picker) {
|
||||
@apply w-full;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,47 @@
|
||||
<script setup lang="ts">
|
||||
const store = useLoginStore();
|
||||
const { currentType } = storeToRefs(store);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="w-full">
|
||||
<div
|
||||
class="flex md:flex-row items-center md:justify-center w-full flex-col gap-4"
|
||||
>
|
||||
<div class="flex flex-col items-center gap-4">
|
||||
<!-- <TInput class="w-56" placeholder="请输入邮箱" />-->
|
||||
<!-- <TButton class="w-56">发送验证码</TButton>-->
|
||||
<!-- <TInput class="w-56" placeholder="请输入验证码" />-->
|
||||
<!-- <TInput class="w-56" type="password" placeholder="请输入新密码" />-->
|
||||
<!-- <TButton class="w-56">确认</TButton>-->
|
||||
<TInput class="w-56" placeholder="用户名" />
|
||||
<TInput class="w-56" placeholder="旧密码" />
|
||||
</div>
|
||||
<div
|
||||
class="hidden md:flex flex-col items-center gap-4 w-2/5 max-w-24 select-none"
|
||||
>
|
||||
<div class="w-1 h-44 bg-gray-200"></div>
|
||||
<!-- <div-->
|
||||
<!-- class="hidden absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 rounded-full border-4 border-gray-200 w-10 h-10 bg-loginBG"-->
|
||||
<!-- >-->
|
||||
<!--<!– <span–>-->
|
||||
<!--<!– class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 z-1"–>-->
|
||||
<!--<!– >or–>-->
|
||||
<!--<!– </span>–>-->
|
||||
<!-- </div>-->
|
||||
</div>
|
||||
<div class="flex flex-col items-center gap-4">
|
||||
<TInput class="w-56" placeholder="新密码" />
|
||||
<TInput class="w-56" placeholder="确认新密码" />
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="flex flex-row items-center bg-gray-600 w-full h-10 justify-around rounded-b-md mt-4"
|
||||
>
|
||||
<button class="text-white" @click="store.register()">修改密码</button>
|
||||
<button class="text-white" @click="currentType = PageType.login"
|
||||
>返回登录
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,32 @@
|
||||
<script setup lang="ts">
|
||||
import LoginPart from '~/pages/login/components/LoginPart.vue';
|
||||
import RegisterPart from '~/pages/login/components/RegisterPart.vue';
|
||||
import ResetPart from '~/pages/login/components/ResetPart.vue';
|
||||
import { PageType } from '~/stores/login';
|
||||
|
||||
const store = useLoginStore();
|
||||
const { currentType } = storeToRefs(store);
|
||||
// watch(currentType, (val) => {
|
||||
// console.log(val);
|
||||
// });
|
||||
|
||||
onMounted(() => {
|
||||
// useThemeStore().setTheme('test');
|
||||
// useThemeStore().setTheme('self');
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="flex justify-center items-center min-h-screen bg-[url('public/fll.jpg')] bg-cover bg-no-repeat bg-fixed bg-center"
|
||||
>
|
||||
<div
|
||||
class="flex flex-col items-center justify-center gap-4 w-3/5 md:w-4/5 max-w-2xl bg-loginBG pt-4 rounded-md bg-opacity-30 dark:bg-darkLoginBG dark:bg-opacity-40"
|
||||
>
|
||||
<h1 class="text-3xl font-bold">{{ store.getTypeName }}</h1>
|
||||
<LoginPart v-if="currentType === PageType.login" />
|
||||
<register-part v-else-if="currentType === PageType.register" />
|
||||
<reset-part v-else-if="currentType === PageType.reset" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
Reference in New Issue
Block a user