From 56bc0990597bf3d9667b97b98bcfbb9092ad9df6 Mon Sep 17 00:00:00 2001
From: 黄何裕 <1053952480@qq.com>
Date: 星期一, 15 七月 2024 16:46:35 +0800
Subject: [PATCH] 教学资源页面开发,分页,音频,类型图,下载,个人中心资料修改,密码修改,校验

---
 src/views/folder/index.vue              |  328 ++++++++++++++++++++++----------
 public/static/icons/file_type_ppt.png   |    0 
 src/views/personal-center/index.vue     |  171 +++++++++++++++-
 src/api/modules/file.js                 |    2 
 src/main.js                             |   33 +-
 components.d.ts                         |    6 
 public/static/icons/file_type_audio.png |    0 
 src/api/modules/personalCenter.js       |    6 
 public/static/icons/file_type_excel.png |    0 
 9 files changed, 411 insertions(+), 135 deletions(-)

diff --git a/components.d.ts b/components.d.ts
index 4bfb9be..cb68d0d 100644
--- a/components.d.ts
+++ b/components.d.ts
@@ -11,7 +11,11 @@
     ElButton: typeof import('element-plus/es')['ElButton']
     ElCard: typeof import('element-plus/es')['ElCard']
     ElCol: typeof import('element-plus/es')['ElCol']
+    ElCollapse: typeof import('element-plus/es')['ElCollapse']
+    ElCollapseItem: typeof import('element-plus/es')['ElCollapseItem']
+    ElCountdown: typeof import('element-plus/es')['ElCountdown']
     ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
+    ElDialog: typeof import('element-plus/es')['ElDialog']
     ElDrawer: typeof import('element-plus/es')['ElDrawer']
     ElDropdown: typeof import('element-plus/es')['ElDropdown']
     ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem']
@@ -23,9 +27,11 @@
     ElInput: typeof import('element-plus/es')['ElInput']
     ElOption: typeof import('element-plus/es')['ElOption']
     ElPagination: typeof import('element-plus/es')['ElPagination']
+    ElProgress: typeof import('element-plus/es')['ElProgress']
     ElRow: typeof import('element-plus/es')['ElRow']
     ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
     ElSelect: typeof import('element-plus/es')['ElSelect']
+    ElSlider: typeof import('element-plus/es')['ElSlider']
     ElTable: typeof import('element-plus/es')['ElTable']
     ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
     ElTabPane: typeof import('element-plus/es')['ElTabPane']
diff --git a/public/static/icons/file_type_audio.png b/public/static/icons/file_type_audio.png
new file mode 100644
index 0000000..fee0a6f
--- /dev/null
+++ b/public/static/icons/file_type_audio.png
Binary files differ
diff --git a/public/static/icons/file_type_excel.png b/public/static/icons/file_type_excel.png
new file mode 100644
index 0000000..54cae41
--- /dev/null
+++ b/public/static/icons/file_type_excel.png
Binary files differ
diff --git a/public/static/icons/file_type_ppt.png b/public/static/icons/file_type_ppt.png
new file mode 100644
index 0000000..da94f09
--- /dev/null
+++ b/public/static/icons/file_type_ppt.png
Binary files differ
diff --git a/src/api/modules/file.js b/src/api/modules/file.js
index bce9bbd..e21bf40 100644
--- a/src/api/modules/file.js
+++ b/src/api/modules/file.js
@@ -1,5 +1,5 @@
 import service from "@/api";
 
-export const getFileList = (getData = {introduction: '', subjectId: '', contentType: ''}) => {
+export const getFileList = (getData) => {
   return service.get('/api/student/education/resource/page', {params: getData});
 };
diff --git a/src/api/modules/personalCenter.js b/src/api/modules/personalCenter.js
index 6380f6e..337ee8b 100644
--- a/src/api/modules/personalCenter.js
+++ b/src/api/modules/personalCenter.js
@@ -7,3 +7,9 @@
     },
   });
 };
+export const userUpdate = (postData) => {
+  return service.post("/api/student/user/update", postData);
+};
+export const passwordUpdate = (postData) => {
+  return service.post("/api/student/user/update/password", postData);
+};
\ No newline at end of file
diff --git a/src/main.js b/src/main.js
index 9fc3d94..fbf6a81 100644
--- a/src/main.js
+++ b/src/main.js
@@ -1,23 +1,26 @@
-import { createApp } from 'vue';
-import './style.css';
-import App from './App.vue';
-import ElementPlus from 'element-plus';
-import 'element-plus/dist/index.css';
-import 'xgplayer/dist/index.min.css'; // 寮曞叆瑗跨摐瑙嗛鏍峰紡
-import router from '@/router/index.js';
-import pinia from './store';
-import VueUeditorWrap from 'vue-ueditor-wrap';
+import { createApp } from "vue";
+import "./style.css";
+import App from "./App.vue";
+import ElementPlus from "element-plus";
+import "element-plus/dist/index.css";
+import "xgplayer/dist/index.min.css"; // 寮曞叆瑗跨摐瑙嗛鏍峰紡
+import router from "@/router/index.js";
+import pinia from "./store";
+import VueUeditorWrap from "vue-ueditor-wrap";
+import ZhLocale from "element-plus/es/locale/lang/zh-cn"; // 涓枃
 
 const app = createApp(App);
 app.use(router);
 app.use(pinia);
-app.use(ElementPlus);
+app.use(ElementPlus, {
+  locale: ZhLocale,
+});
 app.use(VueUeditorWrap);
-app.mount('#app');
+app.mount("#app");
 
 // 鍏ㄥ眬vue寮傚父鎹曡幏
 app.config.errorHandler = (error, vm, info) => {
-  console.error('Vue 鍙戠敓閿欒:', error);
-  console.error('閿欒淇℃伅:', info);
-  router.replace('/index');
-};
\ No newline at end of file
+  console.error("Vue 鍙戠敓閿欒:", error);
+  console.error("閿欒淇℃伅:", info);
+  router.replace("/index");
+};
diff --git a/src/views/folder/index.vue b/src/views/folder/index.vue
index 69536e8..ebe262e 100644
--- a/src/views/folder/index.vue
+++ b/src/views/folder/index.vue
@@ -1,63 +1,129 @@
 <template>
-  <div class="train-container w-screen h-screen bg-slate-50 flex flex-col items-center">
+  <div
+    class="train-container w-screen h-screen bg-slate-50 flex flex-col items-center"
+  >
     <NormalHeader class="shrink-0"></NormalHeader>
 
     <div class="list-container container grow relative">
       <div class="list-content absolute top-0 bottom-0 left-0 right-0 py-4">
         <div class="list-wrapper w-full h-full">
           <el-card class="h-full" :body-style="{ height: '100%' }">
-            <div class="card-wrapper w-full h-full flex flex-col px-8 box-border">
-              <div class="card-header flex justify-between items-center shrink-0">
+            <div
+              class="card-wrapper w-full h-full flex flex-col px-8 box-border"
+            >
+              <div
+                class="card-header flex justify-between items-center shrink-0"
+              >
                 <div class="header-search flex items-center">
-                  <el-input v-model="searchText" placeholder="璇疯緭鍏ユ悳绱㈠唴瀹�" class="long-input" :prefix-icon="Search"/>
-                  <el-select v-model="searchSubject" placeholder="璇烽�夋嫨绉戠洰" class="ml-4 long-select" clearable>
-                    <el-option v-for="item in subjectList" :key="item.id" :label="item.name" :value="item.id"/>
-                  </el-select>
-                  <el-select v-model="searchContentType" placeholder="璇烽�夋嫨鏂囦欢绫诲瀷" class="ml-4 long-select" clearable>
+                  <el-input
+                    v-model="searchText"
+                    placeholder="璇疯緭鍏ユ悳绱㈠唴瀹�"
+                    class="long-input"
+                    :prefix-icon="Search"
+                  />
+                  <el-select
+                    v-model="searchSubject"
+                    placeholder="璇烽�夋嫨绉戠洰"
+                    class="ml-4 long-select"
+                    clearable
+                  >
                     <el-option
-                        v-for="item in contentTypeList"
-                        :key="item.value"
-                        :label="item.name"
-                        :value="item.value">
+                      v-for="item in subjectList"
+                      :key="item.id"
+                      :label="item.name"
+                      :value="item.id"
+                    />
+                  </el-select>
+                  <el-select
+                    v-model="searchContentType"
+                    placeholder="璇烽�夋嫨鏂囦欢绫诲瀷"
+                    class="ml-4 long-select"
+                    clearable
+                  >
+                    <el-option
+                      v-for="item in contentTypeList"
+                      :key="item.value"
+                      :label="item.name"
+                      :value="item.value"
+                    >
                     </el-option>
                   </el-select>
-                  <el-button type="primary" class="ml-4" @click="searchFile">鎼滅储</el-button>
+                  <el-button type="primary" class="ml-4" @click="searchFile"
+                    >鎼滅储</el-button
+                  >
                 </div>
               </div>
 
               <div class="card-main flex-1 my-5 relative">
-                <div class="main-content absolute top-0 bottom-0 left-0 right-0">
+                <div
+                  class="main-content absolute top-0 bottom-0 left-0 right-0"
+                >
                   <el-table :data="fileList" height="100%" v-loading="loading">
                     <el-table-column label="鏂囦欢鍚嶇О">
                       <template #default="scope">
                         <div class="row-info">
                           <div class="icon">
-                            <img :src="getIcon(scope.row.contentType)" class="width-img"/>
+                            <img
+                              :src="getIcon(scope.row.contentType)"
+                              class="width-img"
+                            />
                           </div>
                           <div class="label">{{ scope.row.introduction }}</div>
                         </div>
                       </template>
                     </el-table-column>
-                    <el-table-column prop="className" label="鐝骇" align="center"/>
-                    <el-table-column prop="typeName" label="绉戠洰" align="center"/>
-                    <el-table-column prop="updateTime" label="涓婁紶鏃堕棿" align="center"/>
+                    <el-table-column
+                      prop="className"
+                      label="鐝骇"
+                      align="center"
+                    />
+                    <el-table-column
+                      prop="typeName"
+                      label="绉戠洰"
+                      align="center"
+                    />
+                    <el-table-column
+                      prop="updateTime"
+                      label="涓婁紶鏃堕棿"
+                      align="center"
+                    />
                     <el-table-column>
                       <template #default="scope">
-                        <el-button link type="primary" @click.prevent="checkRow(scope.row)">
+                        <el-button
+                          link
+                          type="primary"
+                          @click.prevent="checkRow(scope.row)"
+                          v-if="
+                            scope.row.contentType == 'video' ||
+                            scope.row.contentType == 'audio'
+                          "
+                        >
                           鏌ョ湅
+                        </el-button>
+                        <el-button
+                          link
+                          type="primary"
+                          @click.prevent="download(scope.row)"
+                          v-else
+                        >
+                          涓嬭浇
                         </el-button>
                       </template>
                     </el-table-column>
                   </el-table>
                 </div>
               </div>
-
               <div class="card-footer flex justify-center mb-7 shrink-0">
-                <el-pagination background layout="prev, pager, next" :total="fileList.length"
-                               :default-page-size="20"
-                               :currentPage="currentIndex"
-                               :hide-on-single-page="true"
-                               @current-change="handleCurrentChange"/>
+                <el-pagination
+                  background
+                  layout="total, sizes, prev, pager, next, jumper"
+                  :total="total"
+                  :page-sizes="[10, 20, 50]"
+                  :page-size="pageSize"
+                  :currentPage="currentIndex"
+                  @size-change="handleSizeChange"
+                  @current-change="handleCurrentChange"
+                />
               </div>
             </div>
           </el-card>
@@ -81,87 +147,126 @@
 
     <!-- image鏌ョ湅 -->
     <div class="image-container" v-show="imageViewer">
-      <el-image-viewer :url-list="imageList" @close="closeViewer"></el-image-viewer>
+      <el-image-viewer
+        :url-list="imageList"
+        @close="closeViewer"
+      ></el-image-viewer>
     </div>
 
     <!-- 瑙嗛鏌ョ湅 -->
-    <div class="video-container" v-show="videoViewer">
+    <div class="video-container" v-if="videoViewer">
       <VideoViewer :videoUrl="videoUrl"></VideoViewer>
       <div class="close-btn">
         <el-button type="danger" size="large" circle @click="closeViewer">
           <template #icon>
             <el-icon :size="20">
-              <Close/>
+              <Close />
             </el-icon>
           </template>
         </el-button>
       </div>
     </div>
     <!-- 寮圭獥 -->
-    <el-drawer v-model="fileViewer" direction="btt" size="90%" :before-close="handleClose">
-        <DocumentViewer :fileUrl="fileUrl"></DocumentViewer>
-    </el-drawer>
+    <!-- <el-drawer
+      v-model="fileViewer"
+      direction="btt"
+      size="90%"
+      :before-close="handleClose"
+    >
+      <DocumentViewer :fileUrl="fileUrl"></DocumentViewer>
+    </el-drawer> -->
   </div>
 </template>
 
 <script setup>
-import {ref, onMounted, onBeforeUnmount} from 'vue';
-import {storeToRefs} from 'pinia';
-import {Close} from '@element-plus/icons-vue';
-import NormalHeader from '@/components/NormalHeader/index.vue';
-import {Search} from '@element-plus/icons-vue';
-import {getFileList} from '@/api/modules/file.js';
-import {getSubjectList} from '@/api/modules/subject.js';
+import { ref, onMounted, onBeforeUnmount } from "vue";
+import { storeToRefs } from "pinia";
+import { Close } from "@element-plus/icons-vue";
+import NormalHeader from "@/components/NormalHeader/index.vue";
+import { Search } from "@element-plus/icons-vue";
+import { getFileList } from "@/api/modules/file.js";
+import { getSubjectList } from "@/api/modules/subject.js";
 
-import PDFViewer from '@/components/PDFViewer/index.vue';
-import VideoViewer from '@/components/VideoViewer/index.vue';
+import PDFViewer from "@/components/PDFViewer/index.vue";
+import VideoViewer from "@/components/VideoViewer/index.vue";
 import DocumentViewer from "@/components/DocumentViewer/index.vue";
 
-import {useUserStore} from '@/store/index.js';
-import useWebScoket from '@/hooks/useWebScoket.js';
+import { useUserStore } from "@/store/index.js";
+import useWebScoket from "@/hooks/useWebScoket.js";
 
 const userStore = useUserStore();
-const {userInfo} = storeToRefs(userStore);
-const {status, message, error, connect, disconnect, sendMessage} = useWebScoket({
-  url: 'ws://42.193.1.25:8000/websocket/' + userInfo.value.id,
-  heartBeatData: 'ping'
-});
+const { userInfo } = storeToRefs(userStore);
+const { status, message, error, connect, disconnect, sendMessage } =
+  useWebScoket({
+    url: "ws://42.193.1.25:8000/websocket/" + userInfo.value.id,
+    heartBeatData: "ping",
+  });
 
 const time = ref(null);
 
-
 const fileType = {
-  'img': {
-    iconPath: '/static/icons/file_type_image.png',
+  img: {
+    iconPath: "/static/icons/file_type_image.png",
     handle: (item) => {
-      console.log(item);
       imageViewer.value = true;
-      imageList.value = ['/api/files/' + item.contentUrl.url];
+      imageList.value = ["/api/files/" + item.contentUrl.url];
       resendMessage();
-    }
+    },
   },
-  'video': {
-    iconPath: '/static/icons/file_type_video.png',
+  video: {
+    iconPath: "/static/icons/file_type_video.png",
+    handle: (item) => {
+      videoViewer.value = true;
+      videoUrl.value = ["/api/files/" + item.contentUrl.url];
+      resendMessage();
+    },
+  },
+  pdf: {
+    iconPath: "/static/icons/file_type_pdf.png",
+    handle: (item) => {
+      pdfViewer.value = true;
+      pdfFile.value = "/api/files/" + item.contentUrl.url;
+      resendMessage();
+    },
+  },
+  word: {
+    iconPath: "/static/icons/file_type_word.png",
+    handle: (item) => {
+      pdfViewer.value = true;
+      pdfFile.value = "/api/files/" + item.contentUrl.url;
+      resendMessage();
+    },
+  },
+  ppt: {
+    iconPath: "/static/icons/file_type_ppt.png",
+    handle: (item) => {
+      pdfViewer.value = true;
+      pdfFile.value = "/api/files/" + item.contentUrl.url;
+      resendMessage();
+    },
+  },
+  audio: {
+    iconPath: "/static/icons/file_type_audio.png",
     handle: (item) => {
       console.log(item);
       videoViewer.value = true;
-      videoUrl.value = ['/api/files/' + item.contentUrl.url];
+      videoUrl.value = "/api/files/" + item.contentUrl.url;
       resendMessage();
-    }
+    },
   },
-  'pdf': {
-    iconPath: '/static/icons/file_type_pdf.png',
+  excel: {
+    iconPath: "/static/icons/file_type_excel.png",
     handle: (item) => {
       console.log(item);
       pdfViewer.value = true;
-      pdfFile.value = '/api/files/' + item.contentUrl.url;
+      pdfFile.value = "/api/files/" + item.contentUrl.url;
       resendMessage();
-    }
+    },
   },
 };
-const searchText = ref('');
-const searchSubject = ref('')
-const searchContentType = ref('')
+const searchText = ref("");
+const searchSubject = ref("");
+const searchContentType = ref("");
 
 const loading = ref(false);
 
@@ -170,33 +275,35 @@
 const videoViewer = ref(false);
 
 const imageList = ref([]);
-const pdfFile = ref('');
-const videoUrl = ref('');
+const pdfFile = ref("");
+const videoUrl = ref("");
 
 const fileList = ref([]);
 const subjectList = ref([]);
-const contentTypeList = ref([{ name: '瑙嗛', value: 'video' },
-  { name: '鍥剧墖', value: 'img' },
-  { name: '闊抽', value: 'audio' },
-  { name: 'PDF', value: 'pdf' },
-  { name: 'EXCEL', value: 'excel' },
-  { name: 'WORD', value: 'word' },
-  { name: 'PPT', value: 'ppt' }]);
+const contentTypeList = ref([
+  { name: "瑙嗛", value: "video" },
+  { name: "鍥剧墖", value: "img" },
+  { name: "闊抽", value: "audio" },
+  { name: "PDF", value: "pdf" },
+  { name: "EXCEL", value: "excel" },
+  { name: "WORD", value: "word" },
+  { name: "PPT", value: "ppt" },
+]);
 const currentIndex = ref(1);
-
-const fileUrl = ref("");
+const pageSize = ref(10);
+const total = ref(0);
+// const fileUrl = ref("");
 const fileViewer = ref(false);
 const checkRow = (item) => {
-    fileUrl.value = item.contentUrl.url;
+  // fileUrl.value = item.contentUrl.url;
   fileType[item.contentType] && fileType[item.contentType].handle(item);
-  fileViewer.value = true
 };
 
-const handleClose = () => {
-  fileViewer.value = false;
-  fileUrl.value = "";
-  console.log("鎴戞槸鍚﹀叧闂細",fileUrl.value);
-};
+// const handleClose = () => {
+//   fileViewer.value = false;
+//   fileUrl.value = "";
+//   console.log("鎴戞槸鍚﹀叧闂細", fileUrl.value);
+// };
 
 const closeViewer = () => {
   pdfViewer.value = false;
@@ -207,32 +314,43 @@
 
 const getData = () => {
   loading.value = true;
-  getFileList({introduction: searchText.value, subjectId: searchSubject.value, contentType:searchContentType.value}).then(res => {
-    loading.value = false;
-    fileList.value = res.data;
-  }).catch(() => {
-    loading.value = false;
-  });
+  getFileList({
+    introduction: searchText.value,
+    subjectId: searchSubject.value,
+    contentType: searchContentType.value,
+    pageSize: pageSize.value,
+    pageNum: currentIndex.value,
+  })
+    .then((res) => {
+      loading.value = false;
+      fileList.value = res.data;
+      total.value = res.total;
+    })
+    .catch(() => {
+      loading.value = false;
+    });
 };
 getData();
 
 const getSubject = () => {
   loading.value = true;
-  getSubjectList().then(res => {
-    loading.value = false;
-    subjectList.value = res.data;
-  }).catch(() => {
-    loading.value = false;
-  });
+  getSubjectList()
+    .then((res) => {
+      loading.value = false;
+      subjectList.value = res.data;
+    })
+    .catch(() => {
+      loading.value = false;
+    });
 };
 getSubject();
 const resendMessage = () => {
   if (time.value) {
     clearInterval(time.value);
   }
-  sendMessage({id: userInfo.value.id, command: 'recordStudyTime'});
+  sendMessage({ id: userInfo.value.id, command: "recordStudyTime" });
   time.value = setInterval(() => {
-    sendMessage({id: userInfo.value.id, command: 'recordStudyTime'});
+    sendMessage({ id: userInfo.value.id, command: "recordStudyTime" });
   }, 5000);
 };
 
@@ -241,15 +359,23 @@
     return fileType[type].iconPath;
   }
 };
-
-const handleCurrentChange = (val) => {
+const handleSizeChange = (val) => {
+  currentIndex.value = 1;
+  pageSize.value = val;
   getData();
-}
-
+};
+const handleCurrentChange = (val) => {
+  currentIndex.value = val;
+  getData();
+};
 
 const searchFile = () => {
   getData();
-}
+};
+//涓嬭浇
+const download = (row) => {
+  window.open(row.visitUrl, '_blank');
+};
 
 // -----------------------------------鐢熷懡鍛ㄦ湡
 onMounted(() => {
diff --git a/src/views/personal-center/index.vue b/src/views/personal-center/index.vue
index 0995cbf..d601d38 100644
--- a/src/views/personal-center/index.vue
+++ b/src/views/personal-center/index.vue
@@ -40,7 +40,7 @@
                     {{ userData.className.join(",") }}
                   </el-form-item>
                   <el-form-item label="娉ㄥ唽鏃堕棿">
-                    {{ timestampToDate(userData.createTime) }}
+                    {{ userData.createTime }}
                   </el-form-item>
                 </el-form>
               </div>
@@ -56,9 +56,10 @@
                   label-width="auto"
                   style="max-width: 600px"
                   :rules="informationRules"
+                  ref="informationFormRef"
                 >
-                  <el-form-item label="鐪熷疄濮撳悕" prop="name">
-                    <el-input v-model="informationForm.name" />
+                  <el-form-item label="鐪熷疄濮撳悕" prop="realName">
+                    <el-input v-model="informationForm.realName" />
                   </el-form-item>
                   <el-form-item label="骞撮緞">
                     <el-input v-model="informationForm.age" />
@@ -77,14 +78,19 @@
                       v-model="informationForm.birthDay"
                       type="date"
                       placeholder="Pick a day"
-                      :size="size"
                     />
                   </el-form-item>
                   <el-form-item label="鎵嬫満" prop="phone">
                     <el-input v-model="informationForm.phone" />
                   </el-form-item>
                   <el-form-item>
-                    <el-button type="primary" @click="onSubmit">鏇存柊</el-button>
+                    <div class="submit-box">
+                      <el-button
+                        type="primary"
+                        @click="informationSubmit(informationFormRef)"
+                        >鏇存柊</el-button
+                      >
+                    </div>
                   </el-form-item></el-form
                 ></el-tab-pane
               >
@@ -93,15 +99,38 @@
                   :model="passwordForm"
                   label-width="auto"
                   style="max-width: 600px"
+                  :rules="passwordRules"
+                  ref="passwordFormRef"
                 >
-                  <el-form-item label="鏃у瘑鐮�">
-                    <el-input v-model="passwordForm.name" />
+                  <el-form-item label="鏃у瘑鐮�" prop="oldPassword">
+                    <el-input
+                      v-model="passwordForm.oldPassword"
+                      type="password"
+                      show-password
+                    />
                   </el-form-item>
-                  <el-form-item label="鏂板瘑鐮�">
-                    <el-input v-model="passwordForm.name" />
+                  <el-form-item label="鏂板瘑鐮�" prop="newPassword">
+                    <el-input
+                      v-model="passwordForm.newPassword"
+                      type="password"
+                      show-password
+                    />
                   </el-form-item>
-                  <el-form-item label="纭瀵嗙爜">
-                    <el-input v-model="passwordForm.name" />
+                  <el-form-item label="纭瀵嗙爜" prop="newPasswordA">
+                    <el-input
+                      v-model="passwordForm.newPasswordA"
+                      type="password"
+                      show-password
+                    />
+                  </el-form-item>
+                  <el-form-item>
+                    <div class="submit-box">
+                      <el-button
+                        type="primary"
+                        @click="passwordSubmit(passwordFormRef)"
+                        >淇濆瓨</el-button
+                      >
+                    </div>
                   </el-form-item>
                 </el-form>
               </el-tab-pane>
@@ -115,17 +144,24 @@
 
 <script setup>
 import { ref } from "vue";
-import { uploadImg } from "@/api/modules/personalCenter.js";
+import { uploadImg, userUpdate,passwordUpdate } from "@/api/modules/personalCenter.js";
 import { ElMessage } from "element-plus";
 
 const activeName = ref("information");
 const userData = ref(JSON.parse(localStorage.getItem("user")).userInfo);
+const informationFormRef = ref();
+const passwordFormRef = ref();
 const informationForm = ref({
-  name: userData.value.realName,
+  realName: userData.value.realName,
   sex: userData.value.sex,
   age: userData.value.age,
   phone: userData.value.phone,
   birthDay: userData.value.birthDay,
+});
+const passwordForm = ref({
+  oldPassword: "",
+  newPassword: "",
+  newPasswordA: "",
 });
 // 鎵嬫満鍙烽獙璇侀�昏緫
 const validatePhone = (rule, value, callback) => {
@@ -136,15 +172,45 @@
     callback();
   }
 };
-
+const validatePassword = (rule, value, callback) => {
+  if (!/[A-Z]/.test(value)) {
+    callback(new Error("瀵嗙爜蹇呴』鍖呭惈鑷冲皯涓�涓ぇ鍐欏瓧姣�"));
+  } else if (!/[a-z]/.test(value)) {
+    callback(new Error("瀵嗙爜蹇呴』鍖呭惈鑷冲皯涓�涓皬鍐欏瓧姣�"));
+  } else if (!/[0-9]/.test(value)) {
+    callback(new Error("瀵嗙爜蹇呴』鍖呭惈鑷冲皯涓�涓暟瀛�"));
+  } else {
+    callback();
+  }
+};
+const validatePasswordA = (rule, value, callback) => {
+  if (value !== passwordForm.value.newPassword) {
+    callback(new Error("涓ゆ杈撳叆瀵嗙爜涓嶅悓锛�"));
+  } else {
+    callback();
+  }
+};
 const informationRules = {
-  name: [{ required: true, message: "璇峰~鍐欑湡瀹炲鍚�", trigger: "blur" }],
+  realName: [{ required: true, message: "璇峰~鍐欑湡瀹炲鍚�", trigger: "blur" }],
   phone: [
     { validator: validatePhone, trigger: "blur" },
     { required: true, message: "璇疯緭鍏ユ墜鏈哄彿", trigger: "blur" },
   ],
 };
-const passwordForm = ref({ name: "" });
+const passwordRules = {
+  oldPassword: [
+    { validator: validatePassword, trigger: "blur" },
+    { required: true, message: "璇疯緭鍏ユ棫瀵嗙爜", trigger: "blur" },
+  ],
+  newPassword: [
+    { validator: validatePasswordA, trigger: "blur" },
+    { required: true, message: "璇疯緭鍏ユ柊瀵嗙爜", trigger: "blur" },
+  ],
+  newPasswordA: [
+    { validator: validatePasswordA, trigger: "blur" },
+    { required: true, message: "璇疯緭鍏ュ啀娆¤緭鍏ユ柊瀵嗙爜", trigger: "blur" },
+  ],
+};
 //澶村儚涓婁紶
 let formData = new FormData();
 const uploadImage = () => {
@@ -179,10 +245,73 @@
     );
   }
 };
+const informationSubmit = async (formEl) => {
+  if (!formEl) return;
+  await formEl.validate((valid, fields) => {
+    if (valid) {
+      informationForm.value.birthDay = timestampToDate(
+        informationForm.value.birthDay
+      );
+      userUpdate(informationForm.value).then(
+        () => {
+          ElMessage({
+            showClose: true,
+            message: "鏇存柊鎴愬姛",
+            type: "success",
+          });
+          const newData = JSON.parse(localStorage.getItem("user"));
+          newData.userInfo.realName = informationForm.value.realName;
+          newData.userInfo.sex = informationForm.value.sex;
+          newData.userInfo.age = informationForm.value.age;
+          newData.userInfo.phone = informationForm.value.phone;
+          newData.userInfo.birthDay = informationForm.value.birthDay;
+          localStorage.setItem("user", JSON.stringify(newData));
+        },
+        (err) => {
+          ElMessage.error(err.data.errorMsg);
+        }
+      );
+    } else {
+      console.log("error submit!", fields);
+    }
+  });
+};
+const passwordSubmit = async (formEl) => {
+  if (!formEl) return;
+  await formEl.validate((valid, fields) => {
+    if (valid) {
+      let data = {
+        userId:userData.value.id,
+        newPassword:passwordForm.value.newPassword,
+        oldPassword:passwordForm.value.oldPassword,
+      }
+      passwordUpdate(data).then(
+        () => {
+          ElMessage({
+            showClose: true,
+            message: "淇敼鎴愬姛",
+            type: "success",
+          });
+        },
+        (err) => {
+          ElMessage.error(err.data.errorMsg);
+        }
+      );
+    } else {
+      console.log("error submit!", fields);
+    }
+  });
+};
 function timestampToDate(timestamp) {
   const date = new Date(timestamp); // 灏嗘椂闂存埑杞崲涓篋ate瀵硅薄
-  const options = { year: "numeric", month: "long", day: "numeric" }; // 瀹氫箟鏃ユ湡鏍煎紡
-  return new Intl.DateTimeFormat("zh-CN", options).format(date); // 浣跨敤Intl.DateTimeFormat杩涜鏍煎紡鍖�
+  const year = date.getFullYear();
+  const month = date.getMonth() + 1; // 鏈堜唤浠�0寮�濮嬶紝鎵�浠ヨ鍔�1
+  const day = date.getDate();
+  const hours = date.getHours();
+  const minutes = date.getMinutes();
+  const seconds = date.getSeconds();
+  const convertedTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
+  return convertedTime; // 浣跨敤Intl.DateTimeFormat杩涜鏍煎紡鍖�
 }
 </script>
 
@@ -213,4 +342,10 @@
   overflow: hidden;
   object-fit: cover;
 }
+.submit-box {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  width: 100%;
+}
 </style>

--
Gitblit v1.8.0