完成大作业部分及其打磨

This commit is contained in:
li-chx
2025-05-11 17:22:21 +08:00
parent 3ab2c26776
commit 0622b15509
23 changed files with 651 additions and 160 deletions
+5 -11
View File
@@ -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>
+119 -5
View File
@@ -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>
+1 -4
View File
@@ -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>
+5 -89
View File
@@ -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;
}
}
+42 -17
View File
@@ -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>