✨ 完成大作业部分及其打磨
This commit is contained in:
@@ -12,12 +12,7 @@
|
||||
);
|
||||
const store = useUserStore();
|
||||
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) {
|
||||
@@ -42,8 +37,6 @@
|
||||
|
||||
function changeMode() {
|
||||
const x = useColorMode();
|
||||
console.log(x.preference);
|
||||
console.log(x.value);
|
||||
if (x.preference === 'light') {
|
||||
x.preference = 'dark';
|
||||
modeName.value = 'moon';
|
||||
@@ -56,7 +49,6 @@
|
||||
}
|
||||
}
|
||||
function changeTheme() {
|
||||
console.log(theme.theme);
|
||||
if (theme.theme === 'default') {
|
||||
theme.setTheme('test');
|
||||
} else if (theme.theme === 'test') {
|
||||
@@ -98,7 +90,7 @@
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<t-layout class="h-full">
|
||||
<t-layout class="h-screen w-screen">
|
||||
<t-header>
|
||||
<t-head-menu value="item1" height="120px">
|
||||
<span class="text-xl">李晨鑫 的 Web 实验</span>
|
||||
@@ -203,8 +195,8 @@
|
||||
</template>
|
||||
</t-menu>
|
||||
</t-aside>
|
||||
<t-layout>
|
||||
<t-content class="overflow-auto">
|
||||
<t-layout class="overflow-auto">
|
||||
<t-content>
|
||||
<NuxtPage />
|
||||
</t-content>
|
||||
<t-footer class="m-auto">
|
||||
@@ -221,10 +213,12 @@
|
||||
:deep(.t-layout__sider) {
|
||||
@apply w-16;
|
||||
}
|
||||
height: calc(100vh - 56px);
|
||||
}
|
||||
.non-collapsed {
|
||||
:deep(.t-layout__sider) {
|
||||
@apply w-60;
|
||||
}
|
||||
height: calc(100vh - 56px);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
<script setup lang="ts">
|
||||
import { MdPreview } from 'md-editor-v3';
|
||||
import 'md-editor-v3/lib/style.css';
|
||||
import BackButton from '~/components/BackButton.vue';
|
||||
const store = useArticleStore();
|
||||
const content = store.currentArticle.content;
|
||||
const title = store.currentArticle.title;
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="p-6">
|
||||
<back-button class="ml-3" />
|
||||
<div
|
||||
class="m-2 bg-white rounded-xl p-6 border-gray-200 border-2 min-h-[300px] dark:bg-black dark:border-zinc-600"
|
||||
>
|
||||
<span class="text-4xl">{{ title }}</span>
|
||||
<MdPreview
|
||||
v-model="content"
|
||||
:theme="useColorMode().preference"
|
||||
class="mt-6"
|
||||
></MdPreview>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,23 @@
|
||||
<script setup lang="ts">
|
||||
const store = useArticleStore();
|
||||
const content = ref(store.currentArticle.content);
|
||||
const title = ref(store.currentArticle.title);
|
||||
|
||||
async function saveArticle(data: { title: string; content: string }) {
|
||||
store.currentArticle.title = data.title;
|
||||
store.currentArticle.content = data.content;
|
||||
await store.modifyArticle();
|
||||
useRouter().back();
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ArticleEditor
|
||||
:base-content="content"
|
||||
:base-title="title"
|
||||
:save-button="'更改文章'"
|
||||
@article-edit-finish="saveArticle"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<style scoped lang="less"></style>
|
||||
@@ -1,11 +1,125 @@
|
||||
<script setup lang="ts">
|
||||
<script setup lang="tsx">
|
||||
import SuperTable from '~/components/SuperTable.vue';
|
||||
import * as echarts from 'echarts';
|
||||
import type { TableProps, TableRowData } from 'tdesign-vue-next';
|
||||
import { useWindowSize } from '@vueuse/core';
|
||||
|
||||
const store = useArticleStore();
|
||||
const { pagination, articleList } = storeToRefs(store);
|
||||
|
||||
const columns = ref<TableProps['columns']>([
|
||||
{
|
||||
colKey: 'index',
|
||||
title: '序号',
|
||||
cell: (_, { rowIndex }: { rowIndex: number }) => (
|
||||
<div>
|
||||
{(pagination.value!.current! - 1) * pagination.value!.pageSize! +
|
||||
rowIndex +
|
||||
1}
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
colKey: 'name',
|
||||
title: '作者姓名',
|
||||
},
|
||||
{
|
||||
colKey: 'amount',
|
||||
title: '文章数量',
|
||||
},
|
||||
{
|
||||
colKey: 'operator',
|
||||
title: '操作',
|
||||
cell: (_, { row }) => (
|
||||
<div class="w-40 flex flex-row justify-evenly">
|
||||
<t-button onClick={() => manageArticle(row)}>进入文章管理</t-button>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
]);
|
||||
|
||||
function pageChange(x: { current: number; pageSize: number }) {
|
||||
if (pagination.value) {
|
||||
pagination.value.current = x.current;
|
||||
pagination.value.pageSize = x.pageSize;
|
||||
store.getArticleList();
|
||||
}
|
||||
}
|
||||
|
||||
function manageArticle(row: TableRowData) {
|
||||
const router = useRouter();
|
||||
router.push(`/base/articleManage/${row.id}`);
|
||||
// router.push()
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await store.getTotal();
|
||||
await store.getArticleList();
|
||||
const chartDom = document.getElementById('echarts')!;
|
||||
const chart = echarts.init(chartDom);
|
||||
|
||||
const option = {
|
||||
title: {
|
||||
text: '柱状图示例',
|
||||
left: 'center',
|
||||
},
|
||||
tooltip: {},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: articleList.value.map((item: ArticleUser) => item.name),
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
},
|
||||
series: [
|
||||
{
|
||||
data: articleList.value.map((item: ArticleUser) => item.amount),
|
||||
type: 'bar',
|
||||
itemStyle: {
|
||||
color: (params: { dataIndex: number }) => {
|
||||
const colors = [
|
||||
'#f1dbc3',
|
||||
'#7493a8',
|
||||
'#edc5ac',
|
||||
'#cdaba2',
|
||||
'#abb0b3',
|
||||
'#cfc2b9',
|
||||
'#a2979f',
|
||||
];
|
||||
return colors[params.dataIndex % colors.length];
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
chart.setOption(option);
|
||||
watch(useWindowSize().width, (_val) => {
|
||||
chart.resize();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
<div class="p-6">
|
||||
<div class="flex md:flex-row flex-col">
|
||||
<div
|
||||
class="flex-[1] m-2 p-6 bg-white rounded-xl dark:bg-zinc-800 border-2 dark:border-zinc-600"
|
||||
>
|
||||
<SuperTable
|
||||
v-model:pagination="pagination"
|
||||
:data="articleList"
|
||||
:columns="columns"
|
||||
:loading="false"
|
||||
@page-change="pageChange"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="m-2 flex-[1] p-6 bg-white dark:bg-zinc-800 border-2 dark:border-zinc-600 rounded-xl"
|
||||
>
|
||||
<div id="echarts" class="w-full h-96"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="less">
|
||||
|
||||
</style>
|
||||
<style scoped lang="less"></style>
|
||||
|
||||
@@ -5,9 +5,8 @@
|
||||
try {
|
||||
avatarURL.value = (await useUserStore().getAvatarURL())!;
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
await MessagePlugin.error(e as string);
|
||||
}
|
||||
console.log(avatarURL.value);
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -37,5 +36,3 @@
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="less"></style>
|
||||
|
||||
@@ -1,99 +1,15 @@
|
||||
<script setup lang="tsx">
|
||||
useSystemStore().currentPage = 'home';
|
||||
<script setup lang="ts">
|
||||
import BasicInfo from '~/components/BasicInfo.vue';
|
||||
const avatarURL = ref('');
|
||||
useSystemStore().currentPage = 'home';
|
||||
onMounted(async () => {
|
||||
try {
|
||||
avatarURL.value = (await useUserStore().getAvatarURL())!;
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
await MessagePlugin.error(e as string);
|
||||
}
|
||||
console.log(avatarURL.value);
|
||||
});
|
||||
function doShow(x: string) {
|
||||
const notShow = ['userAvatar', 'userId', 'usernameOrEmail', 'lastGetTime'];
|
||||
for (const i of notShow) {
|
||||
if (x === i) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
function toChinese(x: string) {
|
||||
const map = {
|
||||
userName: '用户名',
|
||||
userId: '用户ID',
|
||||
userEmail: '邮箱',
|
||||
phone: '手机号',
|
||||
lastGetTime: '最后登录时间',
|
||||
userAvatar: '头像',
|
||||
userAmount: '余额',
|
||||
userBirthday: '生日',
|
||||
};
|
||||
return map[x as keyof typeof map];
|
||||
}
|
||||
function getIcon(key: string) {
|
||||
const map = {
|
||||
userName: 'user',
|
||||
userEmail: 'mail',
|
||||
userAmount: 'money',
|
||||
userBirthday: 'cake',
|
||||
};
|
||||
const val = map[key as keyof typeof map];
|
||||
return <t-icon v-if="" class="t-menu__operations-icon" name={val} />;
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="p-6">
|
||||
<div class="flex md:flex-row flex-col">
|
||||
<div
|
||||
class="flex-[1] m-2 h-full bg-white rounded-xl border-gray-200 border-2 min-h-[300px] min-w-48"
|
||||
>
|
||||
<div class="flex flex-row md:flex-col justify-center p-4">
|
||||
<t-image
|
||||
:src="avatarURL"
|
||||
alt="头像"
|
||||
:fit="'contain'"
|
||||
shape="circle"
|
||||
class="max-h-72 max-w-72 m-auto"
|
||||
/>
|
||||
<span class="text-2xl ml-auto mr-auto md:mt-6 mt-20 mb-6"
|
||||
>欢迎 {{ useUserStore().userName }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="flex-[2] m-2 bg-white rounded-xl border-gray-200 border-2 flex justify-center pt-8 min-w-[558px]"
|
||||
>
|
||||
<t-card
|
||||
title="个人信息"
|
||||
class="w-10/12 max-w-[700px]"
|
||||
:bordered="false"
|
||||
>
|
||||
<t-row
|
||||
v-for="(value, key) of useUserStore().$state"
|
||||
:key="key"
|
||||
class="w-full"
|
||||
>
|
||||
<div
|
||||
v-if="doShow(key)"
|
||||
class="border-collapse flex flex-row w-full h-10"
|
||||
>
|
||||
<t-col
|
||||
class="flex-[1] flex justify-center border-2 items-center"
|
||||
>{{ toChinese(key) }}</t-col
|
||||
>
|
||||
<t-col class="flex-[2] border-2 flex items-center">
|
||||
<span class="ml-4">
|
||||
<component :is="getIcon(key)" />
|
||||
{{ value }}
|
||||
</span>
|
||||
</t-col>
|
||||
</div>
|
||||
</t-row>
|
||||
</t-card>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<BasicInfo :avatar-url="avatarURL" :data="useUserStore().$state" />
|
||||
</template>
|
||||
|
||||
<style scoped lang="less"></style>
|
||||
|
||||
@@ -45,7 +45,6 @@
|
||||
for (const [key, value] of Object.entries(cityDataTyped['00']!)) {
|
||||
if (value === name) {
|
||||
provinceIndex.value = key;
|
||||
console.log('finish');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import SuperTable from '~/components/SuperTable.vue';
|
||||
import type { TableProps, TableRowData } from 'tdesign-vue-next';
|
||||
import PeopleForm from '~/pages/base/index/peopleManage/components/PeopleForm.vue';
|
||||
|
||||
import { TButton } from '#components';
|
||||
const store = usePeopleStore();
|
||||
|
||||
const { peopleList, pagination, situation } = storeToRefs(usePeopleStore());
|
||||
@@ -46,12 +46,23 @@
|
||||
{
|
||||
colKey: 'operator',
|
||||
title: '操作',
|
||||
cell: (_, { row }) => (
|
||||
<div class="w-40 flex flex-row justify-evenly">
|
||||
<t-button onClick={() => editUser(row)}>编辑</t-button>
|
||||
<t-button onClick={() => deleteUser(row)}>删除</t-button>
|
||||
</div>
|
||||
),
|
||||
cell: (_, { row }) =>
|
||||
h('div', { class: 'w-40 flex flex-row justify-evenly' }, [
|
||||
h(
|
||||
TButton,
|
||||
{
|
||||
onClick: () => editUser(row),
|
||||
},
|
||||
{ default: () => '编辑' },
|
||||
),
|
||||
h(
|
||||
TButton,
|
||||
{
|
||||
onClick: () => showDeleteUserDialog(row),
|
||||
},
|
||||
{ default: () => '删除' },
|
||||
),
|
||||
]),
|
||||
},
|
||||
]);
|
||||
|
||||
@@ -63,29 +74,34 @@
|
||||
await store.getTotal();
|
||||
});
|
||||
|
||||
function editUser(_row: TableRowData) {
|
||||
function editUser(row: TableRowData) {
|
||||
if (form.value) form.value.resetForm();
|
||||
store.currentForm = {
|
||||
...peopleList.value.find((e) => e.id === _row.id)!,
|
||||
...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 deleteUser(_row: TableRowData) {
|
||||
store.deletePeople(_row.id);
|
||||
console.log(_row);
|
||||
const showDeleteDialog = ref(false);
|
||||
let deleteRowId = 0;
|
||||
|
||||
function showDeleteUserDialog(row: TableRowData) {
|
||||
deleteRowId = row.id;
|
||||
showDeleteDialog.value = true;
|
||||
}
|
||||
|
||||
function pageChange(x: { current: number; pageSize: number }) {
|
||||
function deleteUser() {
|
||||
showDeleteDialog.value = false;
|
||||
store.deletePeople(deleteRowId);
|
||||
}
|
||||
|
||||
async function pageChange(x: { current: number; pageSize: number }) {
|
||||
if (pagination.value) {
|
||||
pagination.value.current = x.current;
|
||||
pagination.value.pageSize = x.pageSize;
|
||||
store.getPeopleList();
|
||||
await store.getPeopleList();
|
||||
}
|
||||
console.log(store.pagination);
|
||||
}
|
||||
|
||||
async function doSearch() {
|
||||
@@ -147,6 +163,15 @@
|
||||
<people-form ref="form" />
|
||||
</template>
|
||||
</t-dialog>
|
||||
<t-dialog
|
||||
v-model:visible="showDeleteDialog"
|
||||
header="你确定吗?"
|
||||
width="40%"
|
||||
:confirm-on-enter="true"
|
||||
:on-confirm="deleteUser"
|
||||
>
|
||||
此操作将永久删除该人员,确定吗?
|
||||
</t-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -10,6 +10,10 @@
|
||||
await router.push('/base/home');
|
||||
}
|
||||
}
|
||||
onMounted(() => {
|
||||
loginForm.value.usernameOrEmail = '';
|
||||
loginForm.value.password = '';
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -47,7 +51,7 @@
|
||||
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"
|
||||
class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 z-1 dark:text-black"
|
||||
>or
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
:label-width="10"
|
||||
:data="registerForm"
|
||||
:rules="rules"
|
||||
@submit="() => store.register()"
|
||||
@submit="() => store.register(backToLogin)"
|
||||
>
|
||||
<t-form-item name="email">
|
||||
<div class="flex flex-row items-center gap-2">
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
:data="resetForm"
|
||||
:rules="rules"
|
||||
class="flex flex-col items-center gap-4"
|
||||
@submit="store.reset()"
|
||||
@submit="store.reset(backToLogin)"
|
||||
>
|
||||
<div
|
||||
class="flex md:flex-row items-center md:justify-center w-full flex-col gap-4 md:gap-0"
|
||||
|
||||
Reference in New Issue
Block a user