✨ 完成实验部分功能
This commit is contained in:
@@ -1,5 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
import type { TableProps, TableRowData } from 'tdesign-vue-next';
|
||||
import type {
|
||||
TableProps,
|
||||
TableRowData,
|
||||
RowEventContext,
|
||||
} from 'tdesign-vue-next';
|
||||
|
||||
const emit = defineEmits(['pageChange', 'onRowClick']);
|
||||
|
||||
@@ -13,7 +17,7 @@
|
||||
console.log(pageInfo);
|
||||
emit('pageChange', pageInfo);
|
||||
}
|
||||
function onRowClick(x: any) {
|
||||
function onRowClick(x: RowEventContext<TableRowData>) {
|
||||
emit('onRowClick', x);
|
||||
}
|
||||
function onSelectChange() {
|
||||
|
||||
+42
-21
@@ -10,6 +10,7 @@
|
||||
const lg = parseFloat(
|
||||
config.theme.screens.lg.substring(0, config.theme.screens.lg.length - 2),
|
||||
);
|
||||
const store = useUserStore();
|
||||
const modeName = ref('sunny');
|
||||
// watch()
|
||||
// computed(())
|
||||
@@ -65,9 +66,23 @@
|
||||
}
|
||||
}
|
||||
|
||||
function backToLogin() {
|
||||
let lastPage = '';
|
||||
|
||||
function toCalendar() {
|
||||
const router = useRouter();
|
||||
router.push('/login');
|
||||
lastPage = currentPage.value;
|
||||
currentPage.value = 'calendar';
|
||||
router.push('/base/calendar');
|
||||
}
|
||||
|
||||
function backToLastPage() {
|
||||
const router = useRouter();
|
||||
currentPage.value = lastPage;
|
||||
router.back();
|
||||
}
|
||||
|
||||
function backToLogin() {
|
||||
useLoginStore().logout();
|
||||
}
|
||||
|
||||
watch(currentPage, (val) => {
|
||||
@@ -76,36 +91,36 @@
|
||||
});
|
||||
|
||||
async function sendTest() {
|
||||
await useLoginStore().login();
|
||||
try {
|
||||
// const response = await $fetch('/api/login/test', {
|
||||
// method: 'GET',
|
||||
// });
|
||||
$fetch('/api/file/test', { method: 'GET' }).catch(() => {
|
||||
const { $http } = useNuxtApp();
|
||||
useNuxtApp().$http.GET('/test');
|
||||
console.log($http); // 检查是否为 undefined
|
||||
console.log($fetch);
|
||||
$http.GET('/file/test').catch(() => {
|
||||
console.log('error');
|
||||
$fetch('/api/login/login', {
|
||||
method: 'POST',
|
||||
body: {
|
||||
$http
|
||||
.POST('/login/login', {
|
||||
username: 'admin',
|
||||
password: 'password',
|
||||
},
|
||||
}).then(async () => {
|
||||
const result = await $fetch('/api/file/test', { method: 'GET' });
|
||||
console.log(result);
|
||||
});
|
||||
})
|
||||
.then(async () => {
|
||||
const result = await $http.GET('/api/file/test');
|
||||
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));
|
||||
onMounted(async () => {
|
||||
await store.getUserInfo();
|
||||
await store.getAvatarURL();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -120,9 +135,15 @@
|
||||
<a @click="changeTheme">
|
||||
<t-icon class="t-menu__operations-icon" name="fill-color" />
|
||||
</a>
|
||||
<a @click="backToLogin">
|
||||
<a v-if="currentPage != 'calendar'" @click="toCalendar">
|
||||
<t-icon class="t-menu__operations-icon" name="calendar" />
|
||||
</a>
|
||||
<a v-else @click="backToLastPage">
|
||||
<t-icon class="t-menu__operations-icon" name="rollback" />
|
||||
</a>
|
||||
<a @click="backToLogin">
|
||||
<t-icon class="t-menu__operations-icon" name="logout" />
|
||||
</a>
|
||||
<t-button @click="sendTest" />
|
||||
</template>
|
||||
<!-- <template #logo>-->
|
||||
@@ -248,7 +269,7 @@
|
||||
<style scoped lang="less">
|
||||
.collapsed {
|
||||
:deep(.t-layout__sider) {
|
||||
@apply w-20;
|
||||
@apply w-16;
|
||||
}
|
||||
}
|
||||
.non-collapsed {
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
<script setup lang="ts">
|
||||
const avatarURL = ref('');
|
||||
useSystemStore().currentPage = 'calendar';
|
||||
onMounted(async () => {
|
||||
try {
|
||||
avatarURL.value = (await useUserStore().getAvatarURL())!;
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
console.log(avatarURL.value);
|
||||
});
|
||||
</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="avatarURL"
|
||||
alt="头像"
|
||||
: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>
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
const x = ref();
|
||||
useSystemStore().currentPage = 'home';
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -21,7 +21,9 @@
|
||||
</div>
|
||||
|
||||
<div class="flex-[2] m-2">
|
||||
<t-calendar> </t-calendar>
|
||||
<t-card>
|
||||
<t-table> </t-table>
|
||||
</t-card>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
<script setup lang="ts">
|
||||
import cityData from 'public/city.json';
|
||||
import cityZip from 'public/zipcode_district_data.json';
|
||||
import type {
|
||||
FormInstanceFunctions,
|
||||
FormProps,
|
||||
SelectValue,
|
||||
} from 'tdesign-vue-next';
|
||||
|
||||
const cityDataTyped = cityData as Record<string, Record<string, string>>;
|
||||
const cityZipTyped = cityZip as Record<string, string | number>;
|
||||
|
||||
function getZipCode(city: string): string {
|
||||
for (const cityName of [
|
||||
city,
|
||||
city.substring(0, city.length - 1),
|
||||
city.substring(0, city.length - 3),
|
||||
])
|
||||
if (cityZipTyped[cityName] !== undefined) {
|
||||
return '' + cityZipTyped[cityName];
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
const store = usePeopleStore();
|
||||
const { currentForm } = storeToRefs(store);
|
||||
|
||||
const form = ref<FormInstanceFunctions>();
|
||||
const provinceIndex = ref('');
|
||||
async function submit() {
|
||||
// 执行提交逻辑
|
||||
if (!form.value) return;
|
||||
const result = await form.value.validate();
|
||||
if (typeof result === 'boolean' && result) form.value.submit();
|
||||
}
|
||||
function resetForm() {
|
||||
if (form.value) form.value.reset();
|
||||
}
|
||||
function changeProvince(val: SelectValue) {
|
||||
setProvinceIndexByName(val as string);
|
||||
currentForm.value.city = '';
|
||||
currentForm.value.zip = '';
|
||||
}
|
||||
function setProvinceIndexByName(name: string) {
|
||||
for (const [key, value] of Object.entries(cityDataTyped['00']!)) {
|
||||
if (value === name) {
|
||||
provinceIndex.value = key;
|
||||
console.log('finish');
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
submit,
|
||||
resetForm,
|
||||
setProvinceIndexByName,
|
||||
});
|
||||
|
||||
const rules: FormProps['rules'] = {
|
||||
date: [{ required: true, message: '请输入日期', trigger: 'blur' }],
|
||||
name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
|
||||
province: [
|
||||
{ required: true, message: '请输入省份', trigger: 'submit' },
|
||||
{ required: true, message: '请输入省份', trigger: 'change' },
|
||||
],
|
||||
city: [{ required: true, message: '请输入城市', trigger: 'submit' }],
|
||||
address: [{ required: true, message: '请输入地址', trigger: 'blur' }],
|
||||
zip: [{ required: true, message: '请输入邮编', trigger: 'blur' }],
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<t-form
|
||||
ref="form"
|
||||
:rules="rules"
|
||||
:data="currentForm"
|
||||
@submit="
|
||||
() => {
|
||||
if (store.showAddPeople) store.addPeople();
|
||||
else if (store.showEditPeople) store.updatePeople();
|
||||
}
|
||||
"
|
||||
>
|
||||
<t-form-item name="date" label="日期">
|
||||
<t-date-picker
|
||||
v-model="currentForm.date"
|
||||
class="w-80"
|
||||
placeholder="请输入日期"
|
||||
/>
|
||||
</t-form-item>
|
||||
<t-form-item name="name" label="姓名">
|
||||
<t-input v-model="currentForm.name" placeholder="请输入姓名" />
|
||||
</t-form-item>
|
||||
<t-form-item name="province" label="省份">
|
||||
<t-select
|
||||
v-model="currentForm.province"
|
||||
placeholder="请输入省份"
|
||||
@change="changeProvince"
|
||||
>
|
||||
<t-option
|
||||
v-for="item of cityDataTyped['00']"
|
||||
:key="item"
|
||||
:label="item"
|
||||
:value="item"
|
||||
>
|
||||
{{ item }}
|
||||
</t-option>
|
||||
</t-select>
|
||||
</t-form-item>
|
||||
<t-form-item name="city" label="城市">
|
||||
<t-select
|
||||
v-model="currentForm.city"
|
||||
placeholder="请输入城市"
|
||||
:disabled="currentForm.province === ''"
|
||||
@change="
|
||||
(x: SelectValue) => {
|
||||
currentForm.zip = getZipCode(x as string);
|
||||
}
|
||||
"
|
||||
>
|
||||
<t-option
|
||||
v-for="item of cityDataTyped[provinceIndex]"
|
||||
:key="item"
|
||||
:label="item"
|
||||
:value="item"
|
||||
>
|
||||
{{ item }}
|
||||
</t-option>
|
||||
</t-select>
|
||||
</t-form-item>
|
||||
<t-form-item name="address" label="地址">
|
||||
<t-input v-model="currentForm.address" placeholder="请输入地址" />
|
||||
</t-form-item>
|
||||
<t-form-item name="zip" label="邮编">
|
||||
<t-input v-model="currentForm.zip" placeholder="请输入邮编" />
|
||||
</t-form-item>
|
||||
</t-form>
|
||||
</template>
|
||||
|
||||
<style scoped lang="less"></style>
|
||||
@@ -1,16 +1,23 @@
|
||||
<script setup lang="tsx">
|
||||
import SuperTable from '~/components/SuperTable.vue';
|
||||
import type { TableProps } from 'tdesign-vue-next';
|
||||
import type { TableProps, TableRowData } from 'tdesign-vue-next';
|
||||
import PeopleForm from '~/pages/base/index/peopleManage/components/PeopleForm.vue';
|
||||
|
||||
const store = usePeopleStore();
|
||||
|
||||
const { peopleList, pagination, situation } = storeToRefs(usePeopleStore());
|
||||
|
||||
const pagination = ref<TableProps['pagination']>({
|
||||
defaultPageSize: 10,
|
||||
total: 100,
|
||||
defaultCurrent: 1,
|
||||
});
|
||||
const columns = ref<TableProps['columns']>([
|
||||
{
|
||||
colKey: 'index',
|
||||
title: '序号',
|
||||
cell: (_, { rowIndex }: { rowIndex: number }) => (
|
||||
<div>
|
||||
{(pagination.value!.current! - 1) * pagination.value!.pageSize! +
|
||||
rowIndex +
|
||||
1}
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
colKey: 'date',
|
||||
@@ -33,54 +40,113 @@
|
||||
title: '地址',
|
||||
},
|
||||
{
|
||||
colKey: '',
|
||||
colKey: 'zip',
|
||||
title: '邮编',
|
||||
},
|
||||
{
|
||||
colKey: 'operator',
|
||||
title: '操作',
|
||||
cell: (_, { row }) => (
|
||||
<div>
|
||||
<div class="w-40 flex flex-row justify-evenly">
|
||||
<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);
|
||||
|
||||
onMounted(async () => {
|
||||
await store.getPeopleList();
|
||||
});
|
||||
|
||||
onMounted(async () => {
|
||||
await store.getTotal();
|
||||
});
|
||||
|
||||
function editUser(_row: TableRowData) {
|
||||
if (form.value) form.value.resetForm();
|
||||
store.currentForm = {
|
||||
...peopleList.value.find((e) => e.id === _row.id)!,
|
||||
} as PeopleInfo;
|
||||
console.log(store.currentForm.province);
|
||||
form.value?.setProvinceIndexByName(store.currentForm.province);
|
||||
console.log(store.currentForm);
|
||||
store.showEditPeople = true;
|
||||
}
|
||||
|
||||
function editUser(row: never) {}
|
||||
function deleteUser(_row: TableRowData) {
|
||||
store.deletePeople(_row.id);
|
||||
console.log(_row);
|
||||
}
|
||||
|
||||
function deleteUser(row: never) {}
|
||||
function pageChange(x: { current: number; pageSize: number }) {
|
||||
if (pagination.value) {
|
||||
pagination.value.current = x.current;
|
||||
pagination.value.pageSize = x.pageSize;
|
||||
store.getPeopleList();
|
||||
}
|
||||
console.log(store.pagination);
|
||||
}
|
||||
|
||||
async function doSearch() {
|
||||
await usePeopleStore().getTotal();
|
||||
await usePeopleStore().getPeopleList();
|
||||
}
|
||||
|
||||
const form: Ref<typeof PeopleForm | null> = ref(null);
|
||||
</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">
|
||||
<t-button
|
||||
@click="
|
||||
() => {
|
||||
if (form) form.resetForm();
|
||||
store.showAddPeople = true;
|
||||
}
|
||||
"
|
||||
>添加新人员</t-button
|
||||
>
|
||||
<t-input
|
||||
v-model="situation"
|
||||
placeholder="搜索"
|
||||
clearable
|
||||
class="max-w-60"
|
||||
@change="doSearch"
|
||||
>
|
||||
<template #suffixIcon>
|
||||
<search-icon :style="{ cursor: 'pointer' }" />
|
||||
</template>
|
||||
</t-input>
|
||||
</div>
|
||||
<super-table
|
||||
:data="data"
|
||||
v-model:pagination="pagination"
|
||||
:data="peopleList"
|
||||
:columns="columns"
|
||||
:loading="false"
|
||||
:pagination="pagination"
|
||||
@page-change="pageChange"
|
||||
></super-table>
|
||||
<t-dialog
|
||||
:visible="store.showAddPeople || store.showEditPeople"
|
||||
:close-btn="true"
|
||||
:confirm-btn="store.showAddPeople ? '添加' : '修改'"
|
||||
cancel-btn="取消"
|
||||
@confirm="form?.submit"
|
||||
@close="
|
||||
() => {
|
||||
store.showAddPeople = false;
|
||||
store.showEditPeople = false;
|
||||
}
|
||||
"
|
||||
>
|
||||
<template #header>{{
|
||||
store.showAddPeople ? '添加新人员' : '修改人员信息'
|
||||
}}</template>
|
||||
<template #body>
|
||||
<people-form ref="form" />
|
||||
</template>
|
||||
</t-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -3,6 +3,13 @@
|
||||
|
||||
const store = useLoginStore();
|
||||
const { currentType, loginForm } = storeToRefs(store);
|
||||
async function login() {
|
||||
if (await store.login()) {
|
||||
useUserStore().usernameOrEmail = loginForm.value.usernameOrEmail;
|
||||
const router = useRouter();
|
||||
await router.push('/base/home');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -47,17 +54,18 @@
|
||||
</div>
|
||||
<div class="flex flex-col items-center gap-4 mt-3 md:mt-0">
|
||||
<TInput
|
||||
v-model="loginForm.username"
|
||||
v-model="loginForm.usernameOrEmail"
|
||||
class="w-56"
|
||||
placeholder="请输入用户名"
|
||||
placeholder="请输入用户名 / 邮箱"
|
||||
/>
|
||||
<TInput
|
||||
v-model="loginForm.password"
|
||||
class="w-56"
|
||||
type="password"
|
||||
placeholder="请输入密码"
|
||||
@enter="login"
|
||||
/>
|
||||
<TButton class="w-56" @click="store.login">登录</TButton>
|
||||
<TButton class="w-56" @click="login">登录</TButton>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
{ required: true, message: '请输入邮箱', trigger: 'blur' },
|
||||
{ email: true, message: '请输入邮箱', trigger: 'change' },
|
||||
],
|
||||
identifyingCode: [
|
||||
{ required: true, message: '请输入验证码', trigger: 'blur' },
|
||||
],
|
||||
username: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
|
||||
password: [{ required: true, message: '请输入密码', trigger: 'blur' }],
|
||||
passwordRepeat: [
|
||||
@@ -25,14 +28,36 @@
|
||||
birth: [{ required: true, message: '请输入出生日期', trigger: 'change' }],
|
||||
};
|
||||
const uploadImage = ref<UploadInstanceFunctions>();
|
||||
const formInstance = ref<FormInstanceFunctions>();
|
||||
const form = ref<FormInstanceFunctions>();
|
||||
const coldTime = ref(0);
|
||||
const avatarURL = ref('');
|
||||
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();
|
||||
if (!form.value) return;
|
||||
const result = await form.value.validate();
|
||||
if (registerForm.value.avatarFile === '') {
|
||||
await MessagePlugin.error('请上传头像');
|
||||
return;
|
||||
}
|
||||
if (typeof result === 'boolean' && result) {
|
||||
form.value.submit();
|
||||
}
|
||||
}
|
||||
async function sendIdentifyingCode() {
|
||||
if (await store.sendRegisterIdentifyingCode()) {
|
||||
coldTime.value = 60;
|
||||
const timer: NodeJS.Timeout = setInterval(() => {
|
||||
if (coldTime.value > 0) coldTime.value--;
|
||||
else {
|
||||
clearInterval(timer);
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
function backToLogin() {
|
||||
form.value?.reset();
|
||||
registerForm.value.avatarFile = '';
|
||||
currentType.value = PageType.login;
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -41,14 +66,25 @@
|
||||
<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"
|
||||
ref="form"
|
||||
:label-width="10"
|
||||
:data="registerForm"
|
||||
:rules="rules"
|
||||
@submit="() => store.register()"
|
||||
>
|
||||
<t-form-item name="email">
|
||||
<TInput v-model="registerForm.email" placeholder="请输入邮箱" />
|
||||
<div class="flex flex-row items-center gap-2">
|
||||
<TInput v-model="registerForm.email" placeholder="请输入邮箱" />
|
||||
<TButton :disabled="coldTime > 0" @click="sendIdentifyingCode">{{
|
||||
coldTime > 0 ? coldTime : '发送验证码'
|
||||
}}</TButton>
|
||||
</div>
|
||||
</t-form-item>
|
||||
<t-form-item name="identifyingCode">
|
||||
<TInput
|
||||
v-model="registerForm.identifyingCode"
|
||||
placeholder="请输入验证码"
|
||||
/>
|
||||
</t-form-item>
|
||||
<t-form-item name="username">
|
||||
<TInput
|
||||
@@ -88,24 +124,28 @@
|
||||
:draggable="true"
|
||||
:format-response="
|
||||
(res) => {
|
||||
res = res as IAPIResponse<string>;
|
||||
res = res as IAPIResponse<{
|
||||
avatarFilePath: string;
|
||||
avatarFileURL: string;
|
||||
}>;
|
||||
if (res.code === 200) {
|
||||
registerForm.avatarURL = res.data;
|
||||
return { url: res.data };
|
||||
registerForm.avatarFile = res.data.avatarFilePath;
|
||||
avatarURL = res.data.avatarFileURL;
|
||||
return { url: res.data.avatarFileURL };
|
||||
}
|
||||
return { fail: res.message };
|
||||
}
|
||||
"
|
||||
>
|
||||
<div v-if="registerForm.avatarURL" class="aspect-square h-full">
|
||||
<div v-if="registerForm.avatarFile" class="aspect-square h-full">
|
||||
<t-image
|
||||
:src="registerForm.avatarURL"
|
||||
:src="avatarURL"
|
||||
class="w-40 h-40 object-cover rounded-md"
|
||||
fit="contain"
|
||||
/>
|
||||
</div>
|
||||
<div v-else>
|
||||
<span class="text-blue-400"> 点击上传头像</span>
|
||||
<span class="text-blue-400">点击上传头像</span>
|
||||
<span> / 拖拽到此区域 </span>
|
||||
</div>
|
||||
</TUpload>
|
||||
@@ -115,9 +155,7 @@
|
||||
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>
|
||||
<button class="text-white" @click="backToLogin">返回登录 </button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,47 +1,117 @@
|
||||
<script setup lang="ts">
|
||||
import type { FormInstanceFunctions, FormProps } from 'tdesign-vue-next';
|
||||
const store = useLoginStore();
|
||||
const { currentType } = storeToRefs(store);
|
||||
const { currentType, resetForm } = storeToRefs(store);
|
||||
const form = ref<FormInstanceFunctions>();
|
||||
const rules: FormProps['rules'] = {
|
||||
usernameOrEmail: [
|
||||
{ required: true, message: '请输入邮箱或用户名', trigger: 'blur' },
|
||||
],
|
||||
identifyingCode: [
|
||||
{ required: true, message: '请输入验证码', trigger: 'blur' },
|
||||
],
|
||||
password: [{ required: true, message: '请输入新密码', trigger: 'blur' }],
|
||||
passwordRepeat: [
|
||||
{ required: true, message: '请再次输入密码', trigger: 'blur' },
|
||||
{
|
||||
validator: (val) => val === resetForm.value.password,
|
||||
message: '两次输入密码不一致',
|
||||
trigger: 'change',
|
||||
},
|
||||
],
|
||||
};
|
||||
async function submit() {
|
||||
if (!form.value) return;
|
||||
const result = await form.value.validate();
|
||||
if (typeof result === 'boolean' && result) form.value.submit();
|
||||
}
|
||||
const coldTime = ref(0);
|
||||
async function sendIdentifyingCode() {
|
||||
if (await store.sendResetIdentifyingCode()) {
|
||||
coldTime.value = 60;
|
||||
const timer: NodeJS.Timeout = setInterval(() => {
|
||||
if (coldTime.value > 0) coldTime.value--;
|
||||
else {
|
||||
clearInterval(timer);
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
function backToLogin() {
|
||||
form.value?.reset();
|
||||
currentType.value = PageType.login;
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="w-full">
|
||||
<div
|
||||
class="flex md:flex-row items-center md:justify-center w-full flex-col gap-4"
|
||||
<t-form
|
||||
ref="form"
|
||||
:label-width="10"
|
||||
:data="resetForm"
|
||||
:rules="rules"
|
||||
class="flex flex-col items-center gap-4"
|
||||
@submit="store.reset()"
|
||||
>
|
||||
<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"
|
||||
class="flex md:flex-row items-center md:justify-center w-full flex-col gap-4 md:gap-0"
|
||||
>
|
||||
<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 class="flex flex-col items-center gap-4 w-full">
|
||||
<!-- <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>-->
|
||||
<t-form-item name="usernameOrEmail" class="w-64 md:w-60">
|
||||
<div class="flex flex-row items-center gap-2 w-full">
|
||||
<TInput
|
||||
v-model="resetForm.usernameOrEmail"
|
||||
placeholder="邮箱 / 用户名"
|
||||
class="max-w-32 md:max-w-28"
|
||||
/>
|
||||
<TButton
|
||||
:disabled="coldTime > 0"
|
||||
class="w-32"
|
||||
@click="sendIdentifyingCode"
|
||||
>{{ coldTime > 0 ? coldTime : '发送验证码' }}</TButton
|
||||
>
|
||||
</div>
|
||||
</t-form-item>
|
||||
<t-form-item name="identifyingCode" class="w-64 md:w-60">
|
||||
<TInput v-model="resetForm.identifyingCode" placeholder="验证码" />
|
||||
</t-form-item>
|
||||
</div>
|
||||
<div
|
||||
class="hidden md:flex flex-col items-center gap-4 w-2/5 max-w-16 select-none"
|
||||
>
|
||||
<div class="w-1 h-44 bg-gray-200"></div>
|
||||
</div>
|
||||
<div class="flex flex-col items-center gap-4 w-full">
|
||||
<t-form-item name="password" class="w-64 md:w-60">
|
||||
<TInput v-model="resetForm.password" placeholder="新密码" />
|
||||
</t-form-item>
|
||||
<t-form-item name="passwordRepeat" class="w-64 md:w-60">
|
||||
<TInput
|
||||
v-model="resetForm.passwordRepeat"
|
||||
class="w-56"
|
||||
placeholder="确认新密码"
|
||||
/>
|
||||
</t-form-item>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col items-center gap-4">
|
||||
<TInput class="w-56" placeholder="新密码" />
|
||||
<TInput class="w-56" placeholder="确认新密码" />
|
||||
</div>
|
||||
</div>
|
||||
</t-form>
|
||||
|
||||
<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>
|
||||
<button class="text-white" @click="submit">修改密码</button>
|
||||
<button class="text-white" @click="backToLogin">返回登录 </button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<style scoped lang="less">
|
||||
:deep(.t-form__item) {
|
||||
@apply mb-0;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -6,14 +6,6 @@
|
||||
|
||||
const store = useLoginStore();
|
||||
const { currentType } = storeToRefs(store);
|
||||
// watch(currentType, (val) => {
|
||||
// console.log(val);
|
||||
// });
|
||||
|
||||
onMounted(() => {
|
||||
// useThemeStore().setTheme('test');
|
||||
// useThemeStore().setTheme('self');
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
import { APIResponseErrorException } from '~/utils/APIResponse';
|
||||
|
||||
const fetch = $fetch.create({
|
||||
onRequest(config) {
|
||||
console.log('request config', config);
|
||||
},
|
||||
onResponse(context) {
|
||||
const response = context.response;
|
||||
console.log('响应数据:', response);
|
||||
console.log('data:', response._data);
|
||||
const data = response._data as APIResponse<unknown>;
|
||||
if (data.code !== 200) {
|
||||
if (data.code === 301 || data.code === 302) {
|
||||
useRouter()
|
||||
.push(
|
||||
data.message && data.message.length > 0 ? data.message : '/login',
|
||||
)
|
||||
.then();
|
||||
throw new APIResponseErrorException(data);
|
||||
}
|
||||
if (response.status === 401) {
|
||||
useRouter().push('/login').then();
|
||||
throw new APIResponseErrorException(data);
|
||||
}
|
||||
if (data.message && data.message.length > 0)
|
||||
MessagePlugin.error(data.message).then();
|
||||
throw new APIResponseErrorException(data);
|
||||
}
|
||||
if (data.message && data.message.length > 0)
|
||||
MessagePlugin.success(data.message).then();
|
||||
},
|
||||
onResponseError({ response }) {
|
||||
console.error('响应错误:', response);
|
||||
// eslint-disable-next-line no-debugger
|
||||
debugger;
|
||||
// 在这里可以处理错误,例如跳转到登录页面或显示错误提示
|
||||
},
|
||||
});
|
||||
export type HTTP = {
|
||||
GET: <ReturnType>(
|
||||
url: string,
|
||||
records?: Record<string, string>,
|
||||
) => Promise<APIResponse<ReturnType>>;
|
||||
POST: <ReturnType>(
|
||||
url: string,
|
||||
body?: object,
|
||||
) => Promise<APIResponse<ReturnType>>;
|
||||
};
|
||||
const baseURL = '/api';
|
||||
export const $http: HTTP = {
|
||||
GET: async <ReturnType>(url: string, records?: Record<string, string>) => {
|
||||
url = baseURL + url;
|
||||
const result: APIResponse<ReturnType> = await fetch(url, {
|
||||
method: 'GET',
|
||||
params: records,
|
||||
});
|
||||
return result;
|
||||
},
|
||||
POST: async <ReturnType>(url: string, body?: object) => {
|
||||
url = baseURL + url;
|
||||
const result: APIResponse<ReturnType> = await fetch(url, {
|
||||
method: 'POST',
|
||||
body: body,
|
||||
});
|
||||
return result;
|
||||
},
|
||||
};
|
||||
|
||||
export default defineNuxtPlugin((nuxtApp) => {
|
||||
console.log('$http', $http);
|
||||
nuxtApp.provide('http', $http);
|
||||
});
|
||||
+82
-12
@@ -1,20 +1,21 @@
|
||||
interface RegisterData {
|
||||
email: string;
|
||||
username: string;
|
||||
identifyingCode: string;
|
||||
password: string;
|
||||
passwordRepeat: string;
|
||||
birth: string;
|
||||
avatarURL: string;
|
||||
avatarFile: string;
|
||||
}
|
||||
|
||||
interface LoginData {
|
||||
username: string;
|
||||
usernameOrEmail: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
interface resetData {
|
||||
username: string;
|
||||
oldPassword: string;
|
||||
usernameOrEmail: string;
|
||||
identifyingCode: string;
|
||||
password: string;
|
||||
passwordRepeat: string;
|
||||
}
|
||||
@@ -34,18 +35,19 @@ export interface LoginStore {
|
||||
|
||||
export const useLoginStore = defineStore('Login', {
|
||||
state: (): LoginStore => ({
|
||||
loginForm: { username: '', password: '' },
|
||||
loginForm: { usernameOrEmail: '', password: '' },
|
||||
registerForm: {
|
||||
email: '',
|
||||
identifyingCode: '',
|
||||
username: '',
|
||||
password: '',
|
||||
passwordRepeat: '',
|
||||
birth: '',
|
||||
avatarURL: '',
|
||||
avatarFile: '',
|
||||
},
|
||||
resetForm: {
|
||||
username: '',
|
||||
oldPassword: '',
|
||||
usernameOrEmail: '',
|
||||
identifyingCode: '',
|
||||
password: '',
|
||||
passwordRepeat: '',
|
||||
},
|
||||
@@ -53,15 +55,83 @@ export const useLoginStore = defineStore('Login', {
|
||||
}),
|
||||
actions: {
|
||||
async login() {
|
||||
console.log(this.loginForm);
|
||||
const router = useRouter();
|
||||
await router.push('/base/home');
|
||||
const { $http } = useNuxtApp();
|
||||
try {
|
||||
await $http.POST('/login/', this.loginForm);
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
async sendRegisterIdentifyingCode(): Promise<boolean> {
|
||||
const email = this.registerForm.email;
|
||||
if (email === '') {
|
||||
await MessagePlugin.error('请输入邮箱');
|
||||
return false;
|
||||
} else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
|
||||
await MessagePlugin.error('请输入正确的邮箱');
|
||||
return false;
|
||||
}
|
||||
const { $http } = useNuxtApp();
|
||||
let result: APIResponse<unknown>;
|
||||
try {
|
||||
result = await $http.GET('/login/register/identifyingCode', {
|
||||
email: email,
|
||||
});
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
return false;
|
||||
}
|
||||
if (result.code === 200) {
|
||||
return true;
|
||||
} else {
|
||||
await MessagePlugin.error(result.message);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
async sendResetIdentifyingCode(): Promise<boolean> {
|
||||
const { $http } = useNuxtApp();
|
||||
const usernameOrEmail = this.resetForm.usernameOrEmail;
|
||||
if (usernameOrEmail === '') {
|
||||
await MessagePlugin.error('请输入用户名或邮箱');
|
||||
return false;
|
||||
}
|
||||
const result = await $http.GET('/login/passwordReset/identifyingCode', {
|
||||
usernameOrEmail: usernameOrEmail,
|
||||
});
|
||||
if (result.code === 200) {
|
||||
return true;
|
||||
} else {
|
||||
await MessagePlugin.error(result.message);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
async register() {
|
||||
console.log(this.registerForm);
|
||||
const { $http } = useNuxtApp();
|
||||
try {
|
||||
await $http.POST('/login/register', this.registerForm);
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
},
|
||||
async reset() {
|
||||
console.log(this.resetForm);
|
||||
const { $http } = useNuxtApp();
|
||||
try {
|
||||
await $http.POST('/login/passwordReset', this.resetForm);
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
},
|
||||
async logout() {
|
||||
const { $http } = useNuxtApp();
|
||||
try {
|
||||
await $http.GET('/login/logout');
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
const router = useRouter();
|
||||
await router.push('/login');
|
||||
},
|
||||
},
|
||||
getters: {
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
export interface PeopleInfo {
|
||||
id: number;
|
||||
date: string;
|
||||
name: string;
|
||||
province: string;
|
||||
city: string;
|
||||
address: string;
|
||||
zip: string;
|
||||
}
|
||||
export interface BasicPagination {
|
||||
current: number;
|
||||
pageSize: number;
|
||||
defaultPageSize: number;
|
||||
total: number;
|
||||
defaultCurrent: number;
|
||||
}
|
||||
export interface PeopleState {
|
||||
peopleList: PeopleInfo[];
|
||||
showAddPeople: boolean;
|
||||
showEditPeople: boolean;
|
||||
situation: string;
|
||||
pagination: BasicPagination;
|
||||
currentForm: PeopleInfo;
|
||||
}
|
||||
export const usePeopleStore = defineStore('People', {
|
||||
state: (): PeopleState => ({
|
||||
peopleList: [],
|
||||
showAddPeople: false,
|
||||
showEditPeople: false,
|
||||
situation: '',
|
||||
pagination: {
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
defaultPageSize: 10,
|
||||
total: 0,
|
||||
defaultCurrent: 1,
|
||||
},
|
||||
currentForm: {
|
||||
id: 0,
|
||||
date: '',
|
||||
name: '',
|
||||
province: '',
|
||||
city: '',
|
||||
address: '',
|
||||
zip: '',
|
||||
},
|
||||
}),
|
||||
actions: {
|
||||
async getPeopleList() {
|
||||
const { $http } = useNuxtApp();
|
||||
try {
|
||||
const res = await $http.GET<{ records: PeopleInfo[] }>(
|
||||
'/userManager/page',
|
||||
{
|
||||
page: '' + this.pagination!.current,
|
||||
size: '' + this.pagination!.pageSize,
|
||||
situation: this.situation,
|
||||
},
|
||||
);
|
||||
this.peopleList = res.data.records;
|
||||
console.log(this.peopleList);
|
||||
} catch (error) {
|
||||
console.error('Error fetching people list:', error);
|
||||
}
|
||||
},
|
||||
async getTotal() {
|
||||
const { $http } = useNuxtApp();
|
||||
try {
|
||||
const res = await $http.GET<number>('/userManager/total', {
|
||||
situation: this.situation,
|
||||
});
|
||||
this.pagination!.total = res.data;
|
||||
if (
|
||||
(this.pagination!.current - 1) * this.pagination!.pageSize >
|
||||
this.pagination!.total
|
||||
) {
|
||||
this.pagination!.current = Math.ceil(
|
||||
this.pagination!.total / this.pagination!.pageSize,
|
||||
);
|
||||
this.getPeopleList();
|
||||
}
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
},
|
||||
async addPeople() {
|
||||
console.log('add');
|
||||
const { $http } = useNuxtApp();
|
||||
try {
|
||||
await $http.POST('/userManager/addUser', this.currentForm);
|
||||
this.getTotal();
|
||||
this.getPeopleList();
|
||||
} catch (error) {
|
||||
await MessagePlugin.error('Error adding people:' + error);
|
||||
}
|
||||
this.showEditPeople = false;
|
||||
this.showAddPeople = false;
|
||||
},
|
||||
|
||||
async updatePeople() {
|
||||
const { $http } = useNuxtApp();
|
||||
try {
|
||||
await $http.POST('/userManager/updateUser', this.currentForm);
|
||||
this.getTotal();
|
||||
this.getPeopleList();
|
||||
} catch (error) {
|
||||
await MessagePlugin.error('Error updating people:' + error);
|
||||
}
|
||||
this.showEditPeople = false;
|
||||
this.showAddPeople = false;
|
||||
},
|
||||
|
||||
async deletePeople(peopleId: number) {
|
||||
const { $http } = useNuxtApp();
|
||||
try {
|
||||
await $http.GET('/userManager/deleteUser', { id: '' + peopleId });
|
||||
this.getTotal();
|
||||
this.getPeopleList();
|
||||
} catch (error) {
|
||||
await MessagePlugin.error('Error deleting people:' + error);
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
+41
-2
@@ -1,14 +1,53 @@
|
||||
export interface UserState {
|
||||
export interface UserInfo {
|
||||
userId: string;
|
||||
userName: string;
|
||||
userEmail: string;
|
||||
userAvatar: string;
|
||||
userAmount: string;
|
||||
lastGetTime: Date;
|
||||
}
|
||||
export interface UserState extends UserInfo {
|
||||
usernameOrEmail: string;
|
||||
}
|
||||
export const useUserStore = defineStore('User', {
|
||||
state: (): UserState => ({
|
||||
usernameOrEmail: '',
|
||||
userId: '',
|
||||
userName: '李晨鑫',
|
||||
userName: '',
|
||||
userEmail: '',
|
||||
userAvatar: '',
|
||||
userAmount: '',
|
||||
lastGetTime: new Date(),
|
||||
}),
|
||||
actions: {
|
||||
async getUserInfo() {
|
||||
const { $http } = useNuxtApp();
|
||||
try {
|
||||
const res = await $http.GET<UserInfo>('/user/info');
|
||||
console.log(res.data);
|
||||
this.userId = res.data.userId;
|
||||
this.userName = res.data.userName;
|
||||
this.userEmail = res.data.userEmail;
|
||||
this.userAvatar = res.data.userAvatar;
|
||||
this.userAmount = '500';
|
||||
this.lastGetTime = new Date();
|
||||
} catch (error) {
|
||||
console.error('Error fetching user info:', error);
|
||||
}
|
||||
},
|
||||
async getAvatarURL() {
|
||||
const now = new Date();
|
||||
if (now.getTime() - this.lastGetTime.getTime() < 1000 * 60 * 9) {
|
||||
return this.userAvatar;
|
||||
}
|
||||
this.lastGetTime = now;
|
||||
const { $http } = useNuxtApp();
|
||||
try {
|
||||
const res = await $http.GET<string>('/user/avatar');
|
||||
this.userAvatar = res.data;
|
||||
} catch (error) {
|
||||
console.error('Error fetching user avatar:', error);
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
Vendored
+9
-85
@@ -7,106 +7,25 @@
|
||||
export {}
|
||||
declare global {
|
||||
const APIResponse: typeof import('../utils/APIResponse')['APIResponse']
|
||||
const ApolloError: (typeof import('@apollo/client/core'))['ApolloError']
|
||||
const EffectScope: (typeof import('vue'))['EffectScope']
|
||||
const NetworkStatus: (typeof import('@apollo/client/core'))['NetworkStatus']
|
||||
const APIResponseErrorException: typeof import('../utils/APIResponse')['APIResponseErrorException']
|
||||
const PageType: typeof import('../stores/login')['PageType']
|
||||
const acceptHMRUpdate: typeof import('pinia')['acceptHMRUpdate']
|
||||
const computed: (typeof import('vue'))['computed']
|
||||
const createApp: (typeof import('vue'))['createApp']
|
||||
const createPinia: typeof import('pinia')['createPinia']
|
||||
const customRef: (typeof import('vue'))['customRef']
|
||||
const defineAsyncComponent: (typeof import('vue'))['defineAsyncComponent']
|
||||
const defineComponent: (typeof import('vue'))['defineComponent']
|
||||
const defineStore: typeof import('pinia')['defineStore']
|
||||
const effectScope: (typeof import('vue'))['effectScope']
|
||||
const getActivePinia: typeof import('pinia')['getActivePinia']
|
||||
const getCurrentInstance: (typeof import('vue'))['getCurrentInstance']
|
||||
const getCurrentScope: (typeof import('vue'))['getCurrentScope']
|
||||
const h: (typeof import('vue'))['h']
|
||||
const inject: (typeof import('vue'))['inject']
|
||||
const isProxy: (typeof import('vue'))['isProxy']
|
||||
const isReactive: (typeof import('vue'))['isReactive']
|
||||
const isReadonly: (typeof import('vue'))['isReadonly']
|
||||
const isRef: (typeof import('vue'))['isRef']
|
||||
const mapActions: typeof import('pinia')['mapActions']
|
||||
const mapGetters: typeof import('pinia')['mapGetters']
|
||||
const mapState: typeof import('pinia')['mapState']
|
||||
const mapStores: typeof import('pinia')['mapStores']
|
||||
const mapWritableState: typeof import('pinia')['mapWritableState']
|
||||
const markRaw: (typeof import('vue'))['markRaw']
|
||||
const nextTick: (typeof import('vue'))['nextTick']
|
||||
const onActivated: (typeof import('vue'))['onActivated']
|
||||
const onAddToFavorites: (typeof import('@dcloudio/uni-app'))['onAddToFavorites']
|
||||
const onBackPress: (typeof import('@dcloudio/uni-app'))['onBackPress']
|
||||
const onBeforeMount: (typeof import('vue'))['onBeforeMount']
|
||||
const onBeforeUnmount: (typeof import('vue'))['onBeforeUnmount']
|
||||
const onBeforeUpdate: (typeof import('vue'))['onBeforeUpdate']
|
||||
const onDeactivated: (typeof import('vue'))['onDeactivated']
|
||||
const onError: (typeof import('@dcloudio/uni-app'))['onError']
|
||||
const onErrorCaptured: (typeof import('vue'))['onErrorCaptured']
|
||||
const onHide: (typeof import('@dcloudio/uni-app'))['onHide']
|
||||
const onLaunch: (typeof import('@dcloudio/uni-app'))['onLaunch']
|
||||
const onLoad: (typeof import('@dcloudio/uni-app'))['onLoad']
|
||||
const onMounted: (typeof import('vue'))['onMounted']
|
||||
const onNavigationBarButtonTap: (typeof import('@dcloudio/uni-app'))['onNavigationBarButtonTap']
|
||||
const onNavigationBarSearchInputChanged: (typeof import('@dcloudio/uni-app'))['onNavigationBarSearchInputChanged']
|
||||
const onNavigationBarSearchInputClicked: (typeof import('@dcloudio/uni-app'))['onNavigationBarSearchInputClicked']
|
||||
const onNavigationBarSearchInputConfirmed: (typeof import('@dcloudio/uni-app'))['onNavigationBarSearchInputConfirmed']
|
||||
const onNavigationBarSearchInputFocusChanged: (typeof import('@dcloudio/uni-app'))['onNavigationBarSearchInputFocusChanged']
|
||||
const onPageNotFound: (typeof import('@dcloudio/uni-app'))['onPageNotFound']
|
||||
const onPageScroll: (typeof import('@dcloudio/uni-app'))['onPageScroll']
|
||||
const onPullDownRefresh: (typeof import('@dcloudio/uni-app'))['onPullDownRefresh']
|
||||
const onReachBottom: (typeof import('@dcloudio/uni-app'))['onReachBottom']
|
||||
const onReady: (typeof import('@dcloudio/uni-app'))['onReady']
|
||||
const onRenderTracked: (typeof import('vue'))['onRenderTracked']
|
||||
const onRenderTriggered: (typeof import('vue'))['onRenderTriggered']
|
||||
const onResize: (typeof import('@dcloudio/uni-app'))['onResize']
|
||||
const onScopeDispose: (typeof import('vue'))['onScopeDispose']
|
||||
const onServerPrefetch: (typeof import('vue'))['onServerPrefetch']
|
||||
const onShareAppMessage: (typeof import('@dcloudio/uni-app'))['onShareAppMessage']
|
||||
const onShareTimeline: (typeof import('@dcloudio/uni-app'))['onShareTimeline']
|
||||
const onShow: (typeof import('@dcloudio/uni-app'))['onShow']
|
||||
const onTabItemTap: (typeof import('@dcloudio/uni-app'))['onTabItemTap']
|
||||
const onThemeChange: (typeof import('@dcloudio/uni-app'))['onThemeChange']
|
||||
const onUnhandledRejection: (typeof import('@dcloudio/uni-app'))['onUnhandledRejection']
|
||||
const onUnload: (typeof import('@dcloudio/uni-app'))['onUnload']
|
||||
const onUnmounted: (typeof import('vue'))['onUnmounted']
|
||||
const onUpdated: (typeof import('vue'))['onUpdated']
|
||||
const produce: (typeof import('immer'))['produce']
|
||||
const provide: (typeof import('vue'))['provide']
|
||||
const reactive: (typeof import('vue'))['reactive']
|
||||
const readonly: (typeof import('vue'))['readonly']
|
||||
const ref: (typeof import('vue'))['ref']
|
||||
const resolveComponent: (typeof import('vue'))['resolveComponent']
|
||||
const setActivePinia: typeof import('pinia')['setActivePinia']
|
||||
const setMapStoreSuffix: typeof import('pinia')['setMapStoreSuffix']
|
||||
const shallowReactive: (typeof import('vue'))['shallowReactive']
|
||||
const shallowReadonly: (typeof import('vue'))['shallowReadonly']
|
||||
const shallowRef: (typeof import('vue'))['shallowRef']
|
||||
const storeToRefs: typeof import('pinia')['storeToRefs']
|
||||
const toRaw: (typeof import('vue'))['toRaw']
|
||||
const toRef: (typeof import('vue'))['toRef']
|
||||
const toRefs: (typeof import('vue'))['toRefs']
|
||||
const toValue: (typeof import('vue'))['toValue']
|
||||
const triggerRef: (typeof import('vue'))['triggerRef']
|
||||
const unref: (typeof import('vue'))['unref']
|
||||
const useApolloClient: (typeof import('@vue/apollo-composable'))['useApolloClient']
|
||||
const useAttrs: (typeof import('vue'))['useAttrs']
|
||||
const useCssModule: (typeof import('vue'))['useCssModule']
|
||||
const useCssVars: (typeof import('vue'))['useCssVars']
|
||||
const useLazyQuery: (typeof import('@vue/apollo-composable'))['useLazyQuery']
|
||||
const useLoginStore: typeof import('../stores/login')['useLoginStore']
|
||||
const useMutation: (typeof import('@vue/apollo-composable'))['useMutation']
|
||||
const useQuery: (typeof import('@vue/apollo-composable'))['useQuery']
|
||||
const useSlots: (typeof import('vue'))['useSlots']
|
||||
const usePeopleStore: typeof import('../stores/people')['usePeopleStore']
|
||||
const useSystemStore: typeof import('../stores/system')['useSystemStore']
|
||||
const useThemeStore: typeof import('../hooks/useTheme')['useThemeStore']
|
||||
const useUserStore: typeof import('../stores/user')['useUserStore']
|
||||
const watch: (typeof import('vue'))['watch']
|
||||
const watchEffect: (typeof import('vue'))['watchEffect']
|
||||
const watchPostEffect: (typeof import('vue'))['watchPostEffect']
|
||||
const watchSyncEffect: (typeof import('vue'))['watchSyncEffect']
|
||||
}
|
||||
// for type re-export
|
||||
declare global {
|
||||
@@ -114,13 +33,16 @@ declare global {
|
||||
export type { PageType, LoginStore } from '../stores/login'
|
||||
import('../stores/login')
|
||||
// @ts-ignore
|
||||
export type { PeopleInfo, BasicPagination, PeopleState } from '../stores/people'
|
||||
import('../stores/people')
|
||||
// @ts-ignore
|
||||
export type { SystemStore } from '../stores/system'
|
||||
import('../stores/system')
|
||||
// @ts-ignore
|
||||
export type { UserState } from '../stores/user'
|
||||
export type { UserInfo, UserState } from '../stores/user'
|
||||
import('../stores/user')
|
||||
// @ts-ignore
|
||||
export type { APIResponse, IAPIResponse } from '../utils/APIResponse'
|
||||
export type { APIResponse, APIResponseErrorException, IAPIResponse } from '../utils/APIResponse'
|
||||
import('../utils/APIResponse')
|
||||
}
|
||||
|
||||
@@ -130,6 +52,7 @@ declare module 'vue' {
|
||||
interface GlobalComponents {}
|
||||
interface ComponentCustomProperties {
|
||||
readonly APIResponse: UnwrapRef<typeof import('../utils/APIResponse')['APIResponse']>
|
||||
readonly APIResponseErrorException: UnwrapRef<typeof import('../utils/APIResponse')['APIResponseErrorException']>
|
||||
readonly PageType: UnwrapRef<typeof import('../stores/login')['PageType']>
|
||||
readonly acceptHMRUpdate: UnwrapRef<typeof import('pinia')['acceptHMRUpdate']>
|
||||
readonly createPinia: UnwrapRef<typeof import('pinia')['createPinia']>
|
||||
@@ -144,6 +67,7 @@ declare module 'vue' {
|
||||
readonly setMapStoreSuffix: UnwrapRef<typeof import('pinia')['setMapStoreSuffix']>
|
||||
readonly storeToRefs: UnwrapRef<typeof import('pinia')['storeToRefs']>
|
||||
readonly useLoginStore: UnwrapRef<typeof import('../stores/login')['useLoginStore']>
|
||||
readonly usePeopleStore: UnwrapRef<typeof import('../stores/people')['usePeopleStore']>
|
||||
readonly useSystemStore: UnwrapRef<typeof import('../stores/system')['useSystemStore']>
|
||||
readonly useThemeStore: UnwrapRef<typeof import('../hooks/useTheme')['useThemeStore']>
|
||||
readonly useUserStore: UnwrapRef<typeof import('../stores/user')['useUserStore']>
|
||||
|
||||
Vendored
+14
@@ -0,0 +1,14 @@
|
||||
// 文件:types/nuxt.d.ts
|
||||
import type { HTTP } from '~/plugins/http';
|
||||
|
||||
declare module '#app' {
|
||||
interface NuxtApp {
|
||||
$http: HTTP;
|
||||
}
|
||||
}
|
||||
|
||||
declare module 'vue' {
|
||||
interface ComponentCustomProperties {
|
||||
$http: HTTP;
|
||||
}
|
||||
}
|
||||
@@ -8,3 +8,18 @@ export class APIResponse<T> implements IAPIResponse<T> {
|
||||
message: string = '';
|
||||
data: T = undefined as T;
|
||||
}
|
||||
|
||||
export class APIResponseErrorException<T>
|
||||
extends Error
|
||||
implements IAPIResponse<T>
|
||||
{
|
||||
code: number;
|
||||
override message: string;
|
||||
data: T = undefined as T;
|
||||
constructor(apiResponse: APIResponse<T>) {
|
||||
super();
|
||||
this.code = apiResponse.code;
|
||||
this.message = apiResponse.message;
|
||||
this.data = apiResponse.data;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user