فهرست منبع

Merge branch 'master' of ssh://101.43.129.26:10022/nancetide/teacherTeam-Frontend

Linhanmic 1 ماه پیش
والد
کامیت
f42d0438cd

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 525 - 46
package-lock.json


+ 6 - 0
package.json

@@ -10,19 +10,25 @@
   },
   "dependencies": {
     "axios": "^0.27.2",
+    "element-plus": "^2.8.5",
     "joi": "^17.13.3",
     "joi-browser": "^13.4.0",
     "lucide-vue-next": "^0.445.0",
     "pinia": "^2.2.2",
+    "teacher-management-system": "file:",
     "vue": "^3.2.37",
     "vue-router": "^4.4.5",
     "vuex": "^4.1.0"
   },
   "devDependencies": {
     "@vitejs/plugin-vue": "^3.0.1",
+    "autoprefixer": "^10.4.20",
     "eslint": "^8.20.0",
     "eslint-plugin-vue": "^9.2.0",
+    "postcss": "^8.4.47",
     "tailwindcss": "^3.4.13",
+    "unplugin-auto-import": "^0.18.3",
+    "unplugin-vue-components": "^0.27.4",
     "vite": "^3.0.1"
   }
 }

+ 7 - 0
postcss.config.js

@@ -0,0 +1,7 @@
+module.exports = {
+    plugins: {
+      tailwindcss: {},
+      autoprefixer: {},
+    },
+  };
+  

+ 9 - 6
src/api/Open.js

@@ -5,7 +5,7 @@ class OpenApi {
     this.basePath = '/open';
   }
 
-  async getAwards(page, pageSize = 12, name) {
+  async getAwards(page, pageSize = 12, name, teacherId) {
     return request({
       url: `${this.basePath}/awards/page`,
       method: 'GET',
@@ -13,6 +13,7 @@ class OpenApi {
         page,
         pageSize,
         ...(name && { name }),
+        ...(teacherId && { teacherId })
       },
     });
   }
@@ -31,7 +32,7 @@ class OpenApi {
     });
   }
 
-  async getThesisPage(page, pageSize = 12, name) {
+  async getThesisPage(page, pageSize = 12, name, teacherId) {
     return request({
       url: `${this.basePath}/thesis/page`,
       method: 'GET',
@@ -39,11 +40,12 @@ class OpenApi {
         page,
         pageSize,
         ...(name && { name }),
+        ...(teacherId && { teacherId })
       },
     });
   }
 
-  async getWorksPage(page, pageSize = 12, name) {
+  async getWorksPage(page, pageSize = 12, name, teacherId) {
     return request({
       url: `${this.basePath}/work/page`,
       method: 'GET',
@@ -51,6 +53,7 @@ class OpenApi {
         page,
         pageSize,
         ...(name && { name }),
+        ...(teacherId && { teacherId })
       },
     });
   }
@@ -58,9 +61,9 @@ class OpenApi {
 
 const openApi = new OpenApi();
 
-export const getAwards = (page, pageSize, name) => openApi.getAwards(page, pageSize, name);
+export const getAwards = (page, pageSize = 12, name, teacherId) => openApi.getAwards(page, pageSize, name, teacherId);
 export const getHomepageData = (page, pageSize, name) => openApi.getHomepageData(page, pageSize, name);
-export const getThesisPage = (page, pageSize, name) => openApi.getThesisPage(page, pageSize, name);
-export const getWorksPage = (page, pageSize, name) => openApi.getWorksPage(page, pageSize, name);
+export const getThesisPage = (page, pageSize = 12, name, teacherId) => openApi.getThesisPage(page, pageSize, name, teacherId);
+export const getWorksPage = (page, pageSize = 12, name, teacherId) => openApi.getWorksPage(page, pageSize, name, teacherId);
 
 export default openApi;

+ 3 - 0
src/assets/tailwind.css

@@ -0,0 +1,3 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;

+ 4 - 5
src/components/Pagination.vue

@@ -41,11 +41,10 @@ const props = defineProps({
 
 const emit = defineEmits(['page-change']);
 
-const totalPages = computed(() => {
-  const totalItems = props.totalItems || 0;
-  const itemsPerPage = props.itemsPerPage || 1; // 避免除以零
-  return Math.ceil(totalItems / itemsPerPage);
-});
+const totalPages = computed(() => Math.ceil(props.totalItems / props.itemsPerPage));
+// console.log("This!", totalPages);
+
+const totalPagesDisplay = computed(() => totalPages.value == NaN ? '1' : totalPages.value);
 
 const onPageChange = (page) => {
   if (page >= 1 && page <= totalPages.value) {

+ 12 - 6
src/components/TeacherCard.vue

@@ -1,22 +1,28 @@
 <template>
   <div class="bg-white shadow-lg rounded-lg overflow-hidden transition-all duration-300 hover:shadow-xl transform hover:-translate-y-2">
     <div class="relative pb-2/3">
-      <img :src="teacher.image" :alt="teacher.name" class="absolute h-full w-full object-cover" />
-      <div class="absolute inset-0 bg-gradient-to-t from-black to-transparent opacity-60"></div>
-      <div class="absolute bottom-0 left-0 p-4 text-white">
+      <img :src="teacher.image" :alt="teacher.name" class="h-full w-full object-cover" />
+      <div class="inset-0 bg-gradient-to-t from-black to-transparent opacity-60"></div>
+      <div class="bottom-0 left-0 p-4 text-white">
         <h3 class="text-xl font-semibold mb-1">{{ teacher.name }}</h3>
-        <p class="text-sm opacity-80">{{ teacher.researchField }}</p>
+        <p class="text-sm mb-1 text-gray-500">高性能计算</p>
       </div>
     </div>
-    <div class="p-4">
+    <!-- <div class="p-4">
       <router-link 
         :to="{ name: 'TeacherDetail', params: { id: teacher.id } }" 
         class="block w-full text-center bg-primary text-white px-4 py-2 rounded-md hover:bg-primary-dark transition-colors duration-300"
       >
         查看详情
       </router-link>
-    </div>
+    </div> -->
   </div>
+    <!-- <el-card :header="teacher.name" shadow="hover" style="max-width: 240px; margin-bottom: 12px; margin-top: 12px;">
+      <img
+        :src="teacher.image"
+        style="width: 100%"
+      />
+    </el-card> -->
 </template>
 
 <script setup>

+ 4 - 0
src/main.js

@@ -2,11 +2,15 @@ import { createApp } from 'vue';
 import { createPinia } from 'pinia';
 import App from './App.vue';
 import router from './router'; // 直接从 ./router 导入已经配置好的 router
+import ElementPlus from 'element-plus'
 import './styles/main.css';
+import 'element-plus/theme-chalk/index.css';
+import './assets/tailwind.css';
 
 const app = createApp(App);
 const pinia = createPinia();
 
 app.use(pinia);
 app.use(router); // 直接使用从 ./router 导入的 router
+app.use(ElementPlus)
 app.mount('#app');

+ 0 - 0
src/store/modules/page.js


+ 3 - 3
src/store/modules/teachers.js

@@ -21,7 +21,7 @@ export const useTeachersStore = defineStore('teachers', {
       try {
         const response = await OpenApi.default.getHomepageData(page, pageSize = 12, name)
         this.teachers = response.data.records
-        this.totalPages = response.data.tatal
+        this.total = response.data.total
         this.currentPage = page
       } catch (error) {
         console.error('获取教师列表失败:', error)
@@ -34,8 +34,8 @@ export const useTeachersStore = defineStore('teachers', {
       this.isLoading = true
       this.error = null
       try {
-        const response = await TeacherApi.getTeacherDetails(id)
-        this.currentTeacher = response
+        const response = await TeacherApi.getTeacherById(id)
+        this.currentTeacher = response.data
       } catch (error) {
         console.error('获取教师详情失败:', error)
         this.error = '获取教师详情失败。请重试。'

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 2 - 2478
src/styles/main.css


+ 6 - 2
src/views/Home.vue

@@ -1,10 +1,11 @@
 <template>
+
   <div class="home bg-background-color min-h-screen pb-24">
     <div class="container mx-auto px-4 py-8">
       <h1 class="text-3xl font-bold text-center text-primary mb-8">师资队伍</h1>
 
       <div class="w-full max-w-2xl mx-auto mb-12">
-        <SearchBar @search="handleSearch" />
+        <SearchBar @search="handleSearch"/>
       </div>
 
       <div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-8 mb-16">
@@ -20,7 +21,7 @@
     <div class="fixed bottom-0 left-0 right-0 bg-white shadow-md">
       <div class="container mx-auto px-4 py-4">
         <Pagination
-          :totalItems="teachersStore.totalTeachers"
+          :totalItems="teachersStore.total"
           :currentPage="teachersStore.currentPage"
           :itemsPerPage="pageSize"
           @page-change="handlePageChange"
@@ -68,6 +69,9 @@ const goToTeacherDetail = (teacherId) => {
 watchEffect(() => {
   fetchTeachers();
 });
+
+console.log(teachersStore);
+
 </script>
 
 <style scoped>

+ 7 - 7
src/views/Login.vue

@@ -51,14 +51,14 @@ export default {
       try {
         const response = await userLoginPost({ username: username.value, password: password.value });
         localStorage.setItem('token', response.token);
-        //authStore.setUser(response.user);
-        //authStore.login();
+        authStore.setUser(response.user);
+        authStore.login();
         
-//        if (response.user.role === 'admin') {
-//          router.push('/admin');
-//        } else {
-//          router.push('/');
-        router.push('/');
+        if (response.user.role === 'admin') {
+          router.push('/admin');
+        } else {
+          router.push('/');
+        }
       } catch (error) {
         console.error('Login failed:', error);
         alert('登录失败:' + (error.response?.data?.message || error.message));

+ 3 - 3
src/views/Profile.vue

@@ -115,9 +115,9 @@ export default {
     const thesisPage = ref(1);
     const workPage = ref(1);
 
-    const awardTotal = ref(1);
-    const thesisTotal = ref(1);
-    const workTotal = ref(1);
+    const awardTotal = ref(0);
+    const thesisTotal = ref(0);
+    const workTotal = ref(0);
 
     const teacherId = authStore.user.id;
     const token = authStore.token;

+ 30 - 29
src/views/TeacherDetail.vue

@@ -25,8 +25,8 @@
         </div>
         <Pagination
           :current-page="patentPage"
-          :total="patentTotal"
-          :page-size="pageSize"
+          :total-items="patentTotal"
+          :items-per-page="pageSize"
           @page-change="handlePatentPageChange"
         />
       </CollapsibleSection>
@@ -39,8 +39,8 @@
         </div>
         <Pagination
           :current-page="awardPage"
-          :total="awardTotal"
-          :page-size="pageSize"
+          :total-items="awardTotal"
+          :items-per-page="pageSize"
           @page-change="handleAwardPageChange"
         />
       </CollapsibleSection>
@@ -55,8 +55,8 @@
         </div>
         <Pagination
           :current-page="thesisPage"
-          :total="thesisTotal"
-          :page-size="pageSize"
+          :total-items="thesisTotal"
+          :items-per-page="pageSize"
           @page-change="handleThesisPageChange"
         />
       </CollapsibleSection>
@@ -71,8 +71,8 @@
         </div>
         <Pagination
           :current-page="workPage"
-          :total="workTotal"
-          :page-size="pageSize"
+          :total-items="workTotal"
+          :items-per-page="pageSize"
           @page-change="handleWorkPageChange"
         />
       </CollapsibleSection>
@@ -83,9 +83,10 @@
 <script>
 import { ref, reactive, watch } from 'vue';
 import { useRoute } from 'vue-router';
-import { getTeacherById, getAwardById, getThesisById, getWorkById } from '@/api/Teacher';
+import { useTeachersStore } from '@/store/modules/teachers';
 import CollapsibleSection from '@/components/CollapsibleSection.vue';
 import Pagination from '@/components/Pagination.vue';
+import { getThesisPage, getWorksPage, getAwards } from '@/api/Open'
 
 export default {
   name: 'TeacherDetail',
@@ -94,6 +95,7 @@ export default {
     Pagination
   },
   setup() {
+    const teachersStore = useTeachersStore();
     const route = useRoute();
     const teacherId = ref(route.params.id);
     
@@ -102,15 +104,15 @@ export default {
     const theses = ref([]);
     const works = ref([]);
     
-    const pageSize = ref(10);
+    const pageSize = ref(12);
     const awardPage = ref(1);
-    const awardTotal = ref(0);
+    const awardTotal = ref(1);
     const thesisPage = ref(1);
-    const thesisTotal = ref(0);
+    const thesisTotal = ref(1);
     const workPage = ref(1);
-    const workTotal = ref(0);
+    const workTotal = ref(1);
     const patentPage = ref(1);
-    const patentTotal = ref(0);
+    const patentTotal = ref(1);
 
     const expandedSections = reactive({
       patents: false,
@@ -121,10 +123,9 @@ export default {
 
     const fetchTeacherData = async () => {
       try {
-        const response = await getTeacherById(teacherId.value);
-        teacher.value = response.data;
-        console.log(teacher.value)
-        patentTotal.value = teacher.value.patent ? teacher.value.patent.length : 0;
+        await teachersStore.fetchTeacherDetails(teacherId.value); // 调用 Pinia 方法
+        teacher.value = teachersStore.currentTeacher; // 从 store 获取教师信息
+        patentTotal.value = teacher.value.patent ? teacher.value.patent.length : 0; // 计算专利数量
       } catch (error) {
         console.error('获取教师信息失败:', error);
       }
@@ -132,19 +133,19 @@ export default {
 
     const fetchAwards = async () => {
       try {
-        const response = await getAwardById(teacherId.value, awardPage.value, pageSize.value);
-        awards.value = response.records;
-        awardTotal.value = response.total;
+        const response = await getAwards(awardPage.value, 12, null, teacherId.value);
+        awards.value = response.data.records;
+        awardTotal.value = response.data.total;
       } catch (error) {
         console.error('获取获奖信息失败:', error);
       }
     };
-
+    
     const fetchTheses = async () => {
       try {
-        const response = await getThesisById(teacherId.value, thesisPage.value, pageSize.value);
-        theses.value = response.records;
-        thesisTotal.value = response.total;
+        const response = await getThesisPage(thesisPage.value, 12, null, teacherId.value);
+        theses.value = response.data.records;
+        thesisTotal.value = response.data.total;
       } catch (error) {
         console.error('获取论文信息失败:', error);
       }
@@ -152,9 +153,9 @@ export default {
 
     const fetchWorks = async () => {
       try {
-        const response = await getWorkById(teacherId.value, workPage.value, pageSize.value);
-        works.value = response.records;
-        workTotal.value = response.total;
+        const response = await getWorksPage(workPage.value, 12, null, teacherId.value);
+        works.value = response.data.records;
+        workTotal.value = response.data.total;
       } catch (error) {
         console.error('获取著作信息失败:', error);
       }
@@ -167,7 +168,7 @@ export default {
 
     const handleThesisPageChange = (page) => {
       thesisPage.value = page;
-      fetchTheses();
+      fetchThesis();
     };
 
     const handleWorkPageChange = (page) => {

+ 5 - 3
tailwind.config.js

@@ -1,9 +1,11 @@
 /** @type {import('tailwindcss').Config} */
 module.exports = {
-  content: ["./src/**/*.{html,js,vue}"],
+  content: [
+    './index.html',
+    './src/**/*.{vue,js,ts,jsx,tsx}',
+  ],
   theme: {
     extend: {},
   },
   plugins: [],
-}
-
+};

+ 12 - 3
vite.config.js

@@ -2,23 +2,32 @@ import { defineConfig } from 'vite';
 import vue from '@vitejs/plugin-vue';
 import path from 'path';
 import { fileURLToPath } from 'url';
+import AutoImport from 'unplugin-auto-import/vite'
+import Components from 'unplugin-vue-components/vite'
+// import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
 
 // 获取当前文件的目录名
 const __filename = fileURLToPath(import.meta.url);
 const __dirname = path.dirname(__filename);
 
 export default defineConfig({
-  plugins: [vue()],
+  plugins: [vue(),
+    // AutoImport({
+    //   resolvers: [ElementPlusResolver()],
+    // }),
+    // Components({
+    //   resolvers: [ElementPlusResolver()],
+    // }),
+  ],
   resolve: {
     alias: {
       '@': path.resolve(__dirname, './src'),
-      '@assets': path.resolve(__dirname, './src/assets'),
     },
   },
   server: {
     proxy: {
       '/api': {
-        //target: 'http://10.113.233.180:8080',
+        // target: 'http://10.113.233.180:8080',
         target: 'http://localhost:8080',
         changeOrigin: true,
         rewrite: (path) => path.replace(/^\/api/, '')

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است