Ver código fonte

我的页面实现

wangcc 2 anos atrás
pai
commit
96c45f68fb

+ 62 - 20
src/api/AdaptiveTraining/index.js

@@ -3,11 +3,11 @@
  * @Author: 空白格
  * @Date: 2022-08-12 17:34:57
  * @LastEditors: 空白格
- * @LastEditTime: 2022-08-24 13:41:03
+ * @LastEditTime: 2022-08-25 11:39:24
  * @FilePath: \veterans_client_web\src\api\AdaptiveTraining\index.js
  * @Copyright: Copyright (c) 2016~2022 by 空白格, All Rights Reserved.
  */
-import request from '@/utils/request'
+import request from "@/utils/request";
 /**
  * 获取适应性培训列表
  * @param {*} params
@@ -15,13 +15,13 @@ import request from '@/utils/request'
  */
 export function getTrainingList(params) {
   return request({
-    url: '/app/adaptTrainOnline/queryList',
-    method: 'get',
+    url: "/app/adaptTrainOnline/queryList",
+    method: "get",
     headers: {
-      noLoginFlag: true
+      noLoginFlag: true,
     },
-    params
-  })
+    params,
+  });
 }
 
 /**
@@ -31,10 +31,52 @@ export function getTrainingList(params) {
  */
 export function getOnlineCourseDetails(params) {
   return request({
-    url: '/app/adaptTrainOnline/' + params.id,
-    method: 'get',
-    params
-  })
+    url: "/app/adaptTrainOnline/" + params.id,
+    method: "get",
+    params,
+  });
+}
+
+/**
+ * 获取课程评论
+ * @param {*} params
+ * @returns
+ */
+export function getCommentList(params) {
+  return request({
+    url: "/app/coursecomment",
+    method: "get",
+    headers: {
+      noLoginFlag: true,
+    },
+    params,
+  });
+}
+
+/**
+ * 添加课程评论
+ * @param {*} data
+ * @returns
+ */
+export function addComment(data) {
+  return request({
+    url: "/app/coursecomment",
+    method: "post",
+    data,
+  });
+}
+
+/**
+ * 视频播放时长记录
+ * @param {*} data
+ * @returns
+ */
+export function submitClassesDuration(data) {
+  return request({
+    url: "/app/record/duration/",
+    method: "post",
+    data,
+  });
 }
 
 /**
@@ -44,10 +86,10 @@ export function getOnlineCourseDetails(params) {
  */
 export function getTrainingTotal(params) {
   return request({
-    url: '/app/adaptTrainOnline/queryStatus',
-    method: 'get',
-    params
-  })
+    url: "/app/adaptTrainOnline/queryStatus",
+    method: "get",
+    params,
+  });
 }
 
 /**
@@ -57,11 +99,11 @@ export function getTrainingTotal(params) {
  */
 export function getOfflineTrainingList(params) {
   return request({
-    url: '/app/adaptTrainOffline/queryList',
-    method: 'get',
+    url: "/app/adaptTrainOffline/queryList",
+    method: "get",
     headers: {
-      noLoginFlag: true
+      noLoginFlag: true,
     },
-    params
-  })
+    params,
+  });
 }

+ 31 - 1
src/api/PersonalCenter/index.js

@@ -2,8 +2,13 @@
  * @Description: 个人中心
  * @Author: 空白格
  * @Date: 2022-08-15 14:26:14
+<<<<<<< HEAD
  * @LastEditors: wangcc
- * @LastEditTime: 2022-08-25 11:02:34
+ * @LastEditTime: 2022-08-25 14:48:47
+=======
+ * @LastEditors: gcz
+ * @LastEditTime: 2022-08-25 11:41:09
+>>>>>>> 0c9615cb02a537af385bac65148d2842864ac07c
  * @FilePath: \veterans_client_web\src\api\PersonalCenter\index.js
  * @Copyright: Copyright (c) 2016~2022 by 空白格, All Rights Reserved.
  */
@@ -85,4 +90,29 @@ export function getIdInfo(params) {
     method: 'get',
     params
   })
+}
+/** 
+ * 保存求职意向
+ * @param {*} params
+ * @returns
+ */
+export function saveJobIntention(data) {
+  return request({
+    url: '/app/memberinfo/saveJobIntention',
+    method: 'put',
+    data
+  })
+}
+
+/**
+ * 保存自我评价
+ * @param {*} params
+ * @returns
+ */
+export function saveSelfAssessment(data) {
+  return request({
+    url: '/app/memberinfo/saveSelfAssessment',
+    method: 'put',
+    data
+  })
 }

+ 9 - 0
src/assets/images/link-page-icon.svg

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16px" height="16px" viewBox="0 0 16 16" version="1.1">
+  <title>形状</title>
+  <g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+    <g id="我的-简历" transform="translate(-1524.000000, -767.000000)" fill="#999999" fill-rule="nonzero">
+      <path d="M1538.5436,782.999984 L1525.45693,782.999984 C1525.07053,782.999984 1524.69995,782.846518 1524.42673,782.573378 C1524.1535,782.300238 1524,781.92978 1524,781.543501 L1524,768.471193 C1524,768.085482 1524.15327,767.71557 1524.4261,767.442831 C1524.69892,767.170093 1525.06895,767.01687 1525.45479,767.01687 L1534.18218,767.01687 C1534.4518,767.01687 1534.67037,767.235369 1534.67037,767.504902 C1534.67037,767.774435 1534.4518,767.992935 1534.18218,767.992935 L1525.93749,767.992935 C1525.68065,767.99265 1525.43425,768.094519 1525.25264,768.276072 C1525.07103,768.457624 1524.96913,768.703944 1524.96941,768.960698 L1524.96941,781.067117 C1524.96877,781.324078 1525.07052,781.570715 1525.25218,781.752516 C1525.43384,781.934316 1525.68044,782.036309 1525.93749,782.035952 L1538.05582,782.035952 C1538.31284,782.036237 1538.5594,781.934221 1538.74104,781.752437 C1538.92268,781.570652 1539.02446,781.324057 1539.02389,781.067117 L1539.02389,772.348675 C1539.02389,772.174362 1539.11691,772.013289 1539.26791,771.926131 C1539.41892,771.838974 1539.60497,771.838974 1539.75598,771.926131 C1539.90698,772.013289 1540,772.174362 1540,772.348675 L1540,781.552338 C1539.99965,781.937605 1539.84583,782.30687 1539.57254,782.578516 C1539.29925,782.850161 1538.92899,783.001818 1538.5436,782.999984 L1538.5436,782.999984 Z M1530.6324,776.586859 C1530.51006,776.712341 1530.32965,776.762325 1530.16015,776.717699 C1529.99065,776.673073 1529.85828,776.540738 1529.81364,776.371292 C1529.769,776.201846 1529.81899,776.021495 1529.94452,775.899195 L1538.65772,767.150761 C1538.77953,767.02296 1538.96108,766.971236 1539.13199,767.01564 C1539.30289,767.060044 1539.43628,767.193594 1539.48043,767.364515 C1539.52458,767.535435 1539.47256,767.716849 1539.34453,767.838424 L1530.6324,776.586859 Z" id="形状"></path>
+    </g>
+  </g>
+</svg>

+ 144 - 5
src/components/CourseVideo/index.vue

@@ -3,7 +3,7 @@
  * @Author: 空白格
  * @Date: 2022-08-24 13:48:47
  * @LastEditors: 空白格
- * @LastEditTime: 2022-08-24 15:12:30
+ * @LastEditTime: 2022-08-25 13:26:29
  * @FilePath: \veterans_client_web\src\components\CourseVideo\index.vue
  * @Copyright: Copyright (c) 2016~2022 by 空白格, All Rights Reserved.
 -->
@@ -25,8 +25,20 @@
     <div class="course-video-box">
       <el-row>
         <el-col :xs="24" :sm="24" :md="16" :lg="16" :xl="16">
-          <div class="course-video-box-left">
-            <video :src="currentClasses.videoUrl"></video>
+          <div class="course-video-box-left" v-if="isPay">
+            <video
+              ref="video"
+              id="myVideo"
+              @timeupdate="timeUpdate"
+              :src="currentClasses.videoUrl"
+              controls
+              :initial-time="videoInfo.initial_time"
+              object-fit="fill"
+              play-btn-position="center"
+              @ended="ended"
+              @click="videoClick"
+              @loadedmetadata="loadedmetadata"
+            ></video>
           </div>
         </el-col>
         <el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="8">
@@ -45,9 +57,11 @@
                   v-for="(course, index) in courseDetails.chapterList"
                   :key="index"
                   timestamp=""
+                  :color="course.id === currentClasses.id ? '#EF651F' : ''"
                 >
                   <div
                     class="cvbr-bottom-list-item"
+                    :class="{ current: course.id === currentClasses.id }"
                     @click="chooseClasses(course)"
                   >
                     第{{ index + 1 }}课({{ course.finishPercent }}%)
@@ -63,6 +77,7 @@
 </template>
 
 <script>
+import { submitClassesDuration } from "@/api/AdaptiveTraining";
 export default {
   name: "CourseVideoIndex",
   props: {
@@ -74,11 +89,27 @@ export default {
   data() {
     return {
       currentClasses: {},
+      videoInfo: {
+        initial_time: 0,
+        duration: 0,
+        playedTime: 0,
+        video_real_time: 0,
+      },
+      isPay: false,
     };
   },
   watch: {
     "courseDetails.id"(val) {
       this.currentClasses = this.courseDetails.chapterList[0];
+      this.videoInfo.playedTime =
+        this.courseDetails.chapterList[0].playDuration;
+      this.isPay = true;
+      this.$nextTick(() => {
+        let video = document.getElementById("myVideo");
+        video.onpause = () => {
+          this.submitVideoDuration();
+        };
+      });
     },
   },
   methods: {
@@ -89,7 +120,100 @@ export default {
      * @returns {any}
      */
     chooseClasses(item) {
-      this.currentClasses = item;
+      this.isPay = false;
+      this.submitVideoDuration(item, true);
+    },
+    /**
+     * 视频播放实时触发
+     * @date 2022-08-24
+     * @param {any} e
+     * @returns {any}
+     */
+    timeUpdate(e) {
+      let detail = e.target;
+      //播放的总时长
+      let duration = detail.duration;
+      //实时播放进度 秒数
+      let jumpTime = parseInt(detail.currentTime);
+      //当前视频进度
+      if (jumpTime - this.videoInfo.playedTime > 3) {
+        // 差别过大,调用seek方法跳转到实际观看时间
+        this.$refs.video.currentTime = this.videoInfo.playedTime;
+        this.$message.warning("未完整看完该视频,不能快进!");
+      } else {
+        this.videoInfo.video_real_time = parseInt(detail.currentTime);
+        if (this.videoInfo.video_real_time > this.videoInfo.playedTime) {
+          this.videoInfo.playedTime = this.videoInfo.video_real_time;
+        }
+      }
+    },
+    /**
+     * 视频结束触发
+     * @date 2022-08-24
+     * @returns {any}
+     */
+    ended() {
+      // this.submitVideoDuration();
+    },
+    /**
+     * 视频点击触发
+     * @date 2022-08-24
+     * @param {any} e
+     * @returns {any}
+     */
+    videoClick(e) {
+      console.log(e);
+    },
+    /**
+     * 视频加载完成触发
+     * @date 2022-08-24
+     * @param {any} details
+     * @returns {any}
+     */
+    loadedmetadata(details) {
+      this.videoInfo.duration = details.target.duration;
+      this.videoInfo.initial_time = this.currentClasses.currentDuration;
+      this.$nextTick(() => {
+        this.$refs.video.currentTime = this.videoInfo.initial_time;
+      });
+    },
+    /**
+     * 提交视频播放进度
+     * @date 2022-08-24
+     * @returns {any}
+     */
+    submitVideoDuration(item, isNeed) {
+      let playDuration = this.videoInfo.video_real_time,
+        currentDuration = this.videoInfo.video_real_time;
+      if (this.videoInfo.playDuration > this.videoInfo.video_real_time) {
+        playDuration = this.videoInfo.playDuration;
+      }
+      // 防止视频未加载完成就提交
+      if (Number(this.videoInfo.duration) > 0 && Number(playDuration) > 0) {
+        submitClassesDuration({
+          tabId: this.currentClasses.id,
+          playDuration: playDuration,
+          currentDuration: currentDuration,
+          duration: this.videoInfo.duration,
+        }).then((res) => {
+          if (res.code === 200) {
+            console.log("已记录播放时长" + JSON.stringify(res.data));
+            if (isNeed) {
+              this.$emit("changeClasses", item);
+              this.currentClasses = item;
+              this.isPay = true;
+              this.videoInfo.playedTime = item.playDuration;
+              this.videoInfo.initial_time = item.currentDuration;
+              this.$nextTick(() => {
+                let video = document.getElementById("myVideo");
+                video.onpause = () => {
+                  this.submitVideoDuration();
+                };
+              });
+            }
+          }
+        });
+      }
     },
   },
 };
@@ -97,7 +221,7 @@ export default {
 
 <style lang="scss" scoped>
 .course-video {
-  padding: 10px 0;
+  padding: 10px 0 40px;
   &-header {
     display: flex;
     justify-content: space-between;
@@ -141,9 +265,24 @@ export default {
         color: #fff;
         &-teacher {
           font-size: 20px;
+          margin-bottom: 10px;
         }
         &-des {
           font-size: 14px;
+          line-height: 25px;
+        }
+      }
+      .cvbr-bottom {
+        padding: 20px 30px;
+        &-list {
+          &-item {
+            color: #fff;
+            cursor: pointer;
+            font-size: 14px;
+          }
+          .current {
+            color: #ef651f;
+          }
         }
       }
     }

+ 9 - 0
src/router/index.js

@@ -168,6 +168,15 @@ const routes = [
           title: '我的简历'
         }
       },
+      {
+        path: 'personalcenter/resumeEdit',
+        name: 'ResumeEdit',
+        component: () =>
+          import('@/views/PersonalCenter/Resume/ResumeEdit.vue'),
+        meta: {
+          title: '编辑简历'
+        }
+      },
       {
         path: 'personalcenter/deliver',
         name: 'DeliverIndex',

+ 1 - 1
src/views/AdaptiveTraining/AdaptiveTrainingIndex.vue

@@ -3,7 +3,7 @@
  * @Author: 空白格
  * @Date: 2022-08-12 15:23:44
  * @LastEditors: 空白格
- * @LastEditTime: 2022-08-24 10:56:08
+ * @LastEditTime: 2022-08-25 09:40:14
  * @FilePath: \veterans_client_web\src\views\AdaptiveTraining\AdaptiveTrainingIndex.vue
  * @Copyright: Copyright (c) 2016~2022 by 空白格, All Rights Reserved.
 -->

+ 282 - 3
src/views/AdaptiveTraining/OnlineCourseDetails/OnlineCourseDetailsIndex.vue

@@ -3,7 +3,7 @@
  * @Author: 空白格
  * @Date: 2022-08-24 10:44:26
  * @LastEditors: 空白格
- * @LastEditTime: 2022-08-24 14:01:39
+ * @LastEditTime: 2022-08-25 11:45:37
  * @FilePath: \veterans_client_web\src\views\AdaptiveTraining\OnlineCourseDetails\OnlineCourseDetailsIndex.vue
  * @Copyright: Copyright (c) 2016~2022 by 空白格, All Rights Reserved.
 -->
@@ -25,15 +25,113 @@
     </div>
     <div class="course-details-video">
       <div class="course-details-video-box">
-        <course-video :courseDetails="detailsInfo"/>
+        <course-video
+          ref="courseVideo"
+          :courseDetails="detailsInfo"
+          @changeClasses="changeClasses"
+        />
       </div>
     </div>
+    <div class="course-details-comment" v-loading="commentObj.loading">
+      <el-row :gutter="11">
+        <el-col :xs="24" :sm="24" :md="16" :lg="16" :xl="16">
+          <div class="course-details-comment-content">
+            <div class="cdcc-header">
+              <div class="cdcc-header-title">课程评论</div>
+              <div class="cdcc-header-total">
+                共{{ commentObj.total || 0 }}条评论
+              </div>
+            </div>
+            <div class="cdcc-list" v-if="commentObj.list.length">
+              <div
+                class="cdcc-list-item"
+                v-for="(item, index) in commentObj.list"
+                :key="index"
+              >
+                <div class="cdcc-list-item-left">
+                  <el-avatar
+                    shape="square"
+                    :size="77"
+                    :src="item.createByAvatar"
+                  ></el-avatar>
+                </div>
+                <div class="cdcc-list-item-right">
+                  <div class="clir-item">{{ item.createBy }}</div>
+                  <div class="clir-item">
+                    <div>
+                      <el-rate
+                        v-model="item.starLevel"
+                        :disabled="true"
+                        :colors="['#C4C4C4', '#C4C4C4', '#C4C4C4']"
+                      ></el-rate>
+                    </div>
+                    <div class="date">{{ item.createTime }}</div>
+                  </div>
+                  <div class="clir-item">{{ item.content }}</div>
+                </div>
+              </div>
+              <div class="pagination" v-if="commentObj.total">
+                <el-pagination
+                  background
+                  layout="prev, pager, next"
+                  :page-size="commentObj.queryParams.pageSize"
+                  :total="commentObj.total"
+                  @current-change="currentChange"
+                />
+              </div>
+            </div>
+            <div class="empty" v-else>
+              <el-empty description="评论数据为空"></el-empty>
+            </div>
+          </div>
+        </el-col>
+        <el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="8">
+          <div class="course-details-comment-submit">
+            <div class="cdcs-title">我的评论</div>
+            <div class="cdcs-form">
+              <el-form
+                ref="form"
+                :model="commentObj.form"
+                :rules="commentObj.rules"
+              >
+                <el-form-item prop="starLevel">
+                  <el-rate v-model="commentObj.form.starLevel"></el-rate>
+                </el-form-item>
+                <el-form-item prop="content">
+                  <el-input
+                    type="textarea"
+                    :rows="6"
+                    placeholder="请输入您的评价"
+                    v-model="commentObj.form.content"
+                  >
+                  </el-input>
+                </el-form-item>
+                <el-form-item>
+                  <div class="cdcs-form-btn">
+                    <el-button
+                      class="cdcs-form-btn-sub"
+                      @click="submitComment"
+                      :loading="commentObj.subLoading"
+                      >提交</el-button
+                    >
+                  </div>
+                </el-form-item>
+              </el-form>
+            </div>
+          </div>
+        </el-col>
+      </el-row>
+    </div>
   </div>
 </template>
 
 <script>
 import CourseVideo from "@/components/CourseVideo";
-import { getOnlineCourseDetails } from "@/api/AdaptiveTraining";
+import {
+  getOnlineCourseDetails,
+  getCommentList,
+  addComment,
+} from "@/api/AdaptiveTraining";
 export default {
   name: "OnlineCourseDetailsIndex",
   components: {
@@ -45,6 +143,28 @@ export default {
       classesId: null,
       detailsInfo: {},
       currentClasses: {},
+      commentObj: {
+        total: 0,
+        list: [],
+        loading: false,
+        subLoading: false,
+        queryParams: {
+          pageNum: 1,
+          pageSize: 10,
+          tabId: undefined,
+        },
+        form: {
+          tabId: "",
+          starLevel: 0,
+          content: "",
+        },
+        rules: {
+          starLevel: [{ required: true, message: "请评分", trigger: "change" }],
+          content: [
+            { required: true, message: "请输入您的评价", trigger: "blur" },
+          ],
+        },
+      },
     };
   },
   created() {
@@ -52,7 +172,10 @@ export default {
     const { id } = this.$route.query;
     if (id) {
       this.classesId = id;
+      this.commentObj.queryParams.tabId = id;
+      this.commentObj.form.tabId = id;
       this.getDetails();
+      this.getCommentList();
     }
   },
   methods: {
@@ -69,6 +192,66 @@ export default {
         }
       });
     },
+    /**
+     * 切换章节触发
+     * @date 2022-08-25
+     * @returns {any}
+     */
+    changeClasses() {
+      this.getDetails();
+    },
+    /**
+     * 获取课程评论
+     * @date 2022-08-25
+     * @returns {any}
+     */
+    getCommentList() {
+      this.commentObj.loading = true
+      getCommentList(this.commentObj.queryParams).then((res) => {
+        if (res.code === 200) {
+          this.commentObj.list = res?.rows;
+          this.commentObj.total = Number(res?.total);
+        }
+        this.commentObj.loading = false
+      }).catch(() => {
+        this.commentObj.loading = false
+      })
+    },
+    /**
+     * 分页切换触发
+     * @date 2022-08-25
+     * @param {any} page
+     * @returns {any}
+     */
+    currentChange(page) {
+      this.commentObj.queryParams.pageNum = page;
+      this.getCommentList();
+    },
+    /**
+     * 提交评论
+     * @date 2022-08-25
+     * @returns {any}
+     */
+    submitComment() {
+      this.$refs["form"].validate((valid) => {
+        if (valid) {
+          this.commentObj.subLoading = true
+          addComment(this.commentObj.form).then((res) => {
+            if (res.code === 200) {
+              this.$message.success("评论成功!");
+              this.$refs["form"].resetFields();
+              this.commentObj.queryParams.pageNum = 1;
+              this.getCommentList();
+            } else {
+              this.$message.error(res.msg || "评论失败!");
+            }
+            this.commentObj.subLoading = false
+          }).catch(() => {
+            this.commentObj.subLoading = false
+          })
+        }
+      });
+    },
     /**
      * 根据路由获取面包屑
      * @date 2022-08-24
@@ -96,6 +279,9 @@ export default {
       }
     },
   },
+  beforeDestroy() {
+    this.$refs["courseVideo"].submitVideoDuration();
+  },
 };
 </script>
 
@@ -125,5 +311,98 @@ export default {
       margin: 0 auto;
     }
   }
+  &-comment {
+    width: 70%;
+    min-width: 600px;
+    margin: 16px auto 0;
+    &-content {
+      background: #fff;
+      padding: 30px 20px;
+      .cdcc-header {
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        border-bottom: solid 1px #cbcbcb;
+        padding-bottom: 10px;
+        &-title {
+          color: #1a1a1a;
+          font-size: 20px;
+          font-weight: 500;
+        }
+        &-total {
+          color: #8d8d8d;
+          font-size: 14px;
+        }
+      }
+      .cdcc-list {
+        padding: 30px 0 0;
+        &-item {
+          display: flex;
+          margin-bottom: 22px;
+          &-left {
+            margin-right: 14px;
+          }
+          &-right {
+            .clir-item {
+              display: flex;
+              font-size: 14px;
+              margin-bottom: 5px;
+              :deep(.el-rate__icon) {
+                margin-right: 2px;
+              }
+              .date {
+                color: #a5a5a5;
+                margin-left: 30px;
+                font-size: 13px;
+              }
+              &:first-child {
+                color: #3d3d3d;
+                font-size: 16px;
+              }
+              &:last-child {
+                color: #6c6c6c;
+              }
+            }
+          }
+        }
+        .pagination {
+          text-align: center;
+          margin-top: 20px;
+          :deep(.el-pager .active) {
+            background-color: #ff3939;
+          }
+          :deep(.el-pagination.is-background
+              .el-pager
+              li:not(.disabled).active) {
+            background-color: #ff3939;
+          }
+        }
+      }
+      .empty {
+        padding: 30px 0;
+      }
+    }
+    &-submit {
+      background: #fff;
+      padding: 30px 20px;
+      .cdcs-title {
+        font-size: 20px;
+        color: #1a1a1a;
+        margin-bottom: 14px;
+      }
+      .cdcs-form {
+        &-btn {
+          width: 100%;
+          text-align: center;
+          &-sub {
+            width: 80%;
+            background-color: #709078;
+            color: #fff;
+            border-radius: 30px;
+          }
+        }
+      }
+    }
+  }
 }
 </style>

+ 20 - 2
src/views/PersonalCenter/PersonalCenterIndex.vue

@@ -2,8 +2,8 @@
  * @Description: 个人中心
  * @Author: 空白格
  * @Date: 2022-08-15 10:09:03
- * @LastEditors: 空白格
- * @LastEditTime: 2022-08-24 10:12:43
+ * @LastEditors: gcz
+ * @LastEditTime: 2022-08-25 14:31:55
  * @FilePath: \veterans_client_web\src\views\PersonalCenter\PersonalCenterIndex.vue
  * @Copyright: Copyright (c) 2016~2022 by 空白格, All Rights Reserved.
 -->
@@ -100,6 +100,7 @@
                 <span class="el-icon-arrow-right"></span>
               </div>
             </div>
+            <div class="logout-btn" @click="logout">退出登录</div>
           </div>
         </el-col>
         <!-- <el-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8">
@@ -287,6 +288,11 @@ export default {
         this.$router.push(path, query);
       }
     },
+    logout(){
+      this.$store.dispatch("Logout", {}).then(res=>{
+            console.log('logout',res);
+      })
+    }
   },
 };
 </script>
@@ -435,6 +441,18 @@ export default {
           color: #333333;
         }
       }
+      .logout-btn{
+        margin: 54px auto 24px;
+        width: 240px;
+        height: 38px;
+        line-height: 38px;
+        text-align: center;
+        border: 1px solid #FF0000;
+        color: #f00;
+        border-radius: 7px;
+        cursor: pointer;
+        letter-spacing: 1.34px;
+      }
     }
     &-right {
       .pcmr-top {

+ 374 - 0
src/views/PersonalCenter/Resume/ResumeEdit.vue

@@ -0,0 +1,374 @@
+<!--
+ * @Description: 
+ * @Author: gcz
+ * @Date: 2022-08-25 09:38:41
+ * @LastEditors: gcz
+ * @LastEditTime: 2022-08-25 11:58:28
+ * @FilePath: \veterans_client_web\src\views\PersonalCenter\Resume\ResumeEdit.vue
+ * @Copyright: Copyright (c) 2016~2022 by gcz, All Rights Reserved. 
+-->
+<template>
+  <div class="app-main">
+    <BannerBreadcrumb title="我的简历" :breadcrumb="false" />
+    <div class="banner-breadcrumb-breadcrumb">
+      <el-breadcrumb separator-class="el-icon-arrow-right">
+        <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
+        <el-breadcrumb-item :to="{ path: '/personalcenter' }"
+          >我的</el-breadcrumb-item
+        >
+        <el-breadcrumb-item>我的简历</el-breadcrumb-item>
+      </el-breadcrumb>
+    </div>
+    <div class="app-main-box">
+      <div class="app-main-box-content resume">
+        <div class="title">我的简历</div>
+        <el-row>
+          <el-col :span="16">
+            <div class="name">{{ memberinfo.name }}</div>
+            <div class="">
+              {{ memberinfo.menSex === 1 ? "女" : "男" }} ·
+              <span class="position" v-if="memberinfo.jobStatus !== 0">
+                · <span class="c-yellow">入职中</span>
+                <span>({{memberinfo.company}})</span>
+              </span>
+              <span class="c-yellow" v-else>未入职</span>
+            </div>
+          </el-col>
+          <el-col :span="8">
+            <div class="avatar hexagon">
+              <div
+                class="avatar-box hexagon-box"
+                :style="{
+                  backgroundImage: `url('${
+                    memberinfo.avatar
+                      ? memberinfo.avatar
+                      : 'https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png'
+                  }')`,
+                }"
+              ></div>
+            </div>
+          </el-col>
+        </el-row>
+        <el-row class="resumm-item">
+          <el-col :span="24">
+            <div class="item-title">基本信息</div>
+            <p>
+              退役军人 ·
+              {{ memberinfo.menBirth ? getAge(memberinfo.menBirth) : "-" }}岁 ·
+              {{ memberinfo.politOutlook || "-" }} ·
+              {{ memberinfo.degrEduc || "-" }}
+            </p>
+            <p>电话:{{ memberinfo.mobile }}</p>
+          </el-col>
+        </el-row>
+        <el-form ref="form" :model="form" label-width="80px">
+          <div class="form-title">求职意向</div>
+          <el-row :gutter="24">
+            <el-col :span="12">
+              <el-form-item
+                label="最低工资"
+                prop="expectedLowestSalary"
+              >
+                <el-col :span="8">
+                  <el-select v-model="form.expectedLowestSalary" placeholder="请选择">
+                    <el-option
+                      v-for="item of 50"
+                      :disabled="item >= form.expectedHighestSalary"
+                      :key="item"
+                      :label="item"
+                      :value="item"
+                    >
+                    </el-option>
+                  </el-select>
+                </el-col>
+                <el-col :span="4">
+                  <div
+                    :style="{
+                      width: '100%',
+                      fontSize: '50px',
+                      textAlign: 'center',
+                    }"
+                  >
+                    ~
+                  </div>
+                </el-col>
+                <el-col :span="8">
+                  <el-select v-model="form.expectedHighestSalary" placeholder="请选择">
+                    <el-option
+                      v-for="item of 50"
+                      :disabled="item <= form.expectedLowestSalary"
+                      :key="item"
+                      :label="item"
+                      :value="item"
+                    >
+                    </el-option>
+                  </el-select>
+                </el-col>
+                <el-col :span="2">
+                  <div
+                    :style="{
+                      width: '100%',
+                      fontSize: '40px',
+                      paddingLeft: '3px',
+                      fontWeight: 1,
+                    }"
+                  >
+                    K
+                  </div>
+                </el-col>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="意向地区" prop="intentionArea">
+                <el-cascader
+                  filterable
+                  size="large"
+                  ref="addressSelect"
+                  :options="addressOptions"
+                  v-model="form.intentionArea"
+                  :leafOnly="true"
+                  @change="addrChange"
+                >
+                </el-cascader>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="期望行业">
+                <el-input v-model="form.expectedIndustry"></el-input>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="期望职位">
+                <el-input v-model="form.expectedPost"></el-input>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <div class="btn-wrap">
+            <span class="btn" @click="saveJobIntention">保存</span>
+          </div>
+        </el-form>
+        <section class="resumm-item self-assessment">
+          <div class="item-title">自我评价</div>
+          <el-input
+            class="textarea"
+            type="textarea"
+            :rows="5"
+            placeholder="请输入自我评价"
+            v-model="selfAssessment">
+          </el-input>
+          <div class="btn-wrap">
+            <span class="btn" @click="saveSelfAssessment">保存</span>
+          </div>
+        </section>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import BannerBreadcrumb from "@/components/BannerBreadcrumb";
+import { getPersonInfoData ,saveJobIntention,saveSelfAssessment} from "@/api/PersonalCenter";
+import { regionDataPlus,regionData, CodeToText,TextToCode  } from "element-china-area-data";
+export default {
+  name: "Resume",
+  components: {
+    BannerBreadcrumb,
+  },
+  data() {
+    return {
+      addressOptions: regionDataPlus,
+      memberinfo: {},
+      form: {
+        intentionArea:[],
+        expectedPost:'',
+        expectedIndustry:'',
+        expectedLowestSalary:null,
+        expectedHighestSalary:null,
+      },
+      selfAssessment:''
+    };
+  },
+  created() {
+    this.getPersonInfo();
+  },
+  methods: {
+    /**
+     * 获取个人信息
+     * @date 2022-08-15
+     * @returns {any}
+     */
+    getPersonInfo() {
+      getPersonInfoData().then((res) => {
+        if (res.code === 200) {
+          this.memberinfo = res?.data;
+          // this.form.provinceId = res?.data?.provinceId;
+          // this.form.provinceName = res?.data?.provinceName;
+          // this.form.cityId = res?.data?.cityId;
+          // this.form.cityName = res?.data?.cityName;
+          // this.form.areaId = res?.data?.areaId;
+          // this.form.areaName  = res?.data?.areaName ;
+          this.form.expectedPost = res?.data?.expectedPost||'';
+          this.form.expectedIndustry = res?.data?.expectedIndustry||'';
+          this.form.expectedLowestSalary = Number( res?.data?.expectedLowestSalary );
+          this.form.expectedHighestSalary = Number( res?.data?.expectedHighestSalary );
+
+          this.form.intentionArea = [];
+          this.form.intentionArea.push(res?.data?.provinceId.toString())
+          this.form.intentionArea.push(res?.data?.cityId.toString())
+          this.form.intentionArea.push(res?.data?.areaId.toString())
+
+          this.selfAssessment = res?.data?.selfAssessment||'';
+          console.log("this.form", this.form);
+        }
+      });
+    },
+    /**
+     * 通过出生年月计算年龄
+     * @param { String } date
+     */
+    getAge(date) {
+      const birth = new Date(date).valueOf();
+      const now = new Date().valueOf();
+      const age = (now - birth) / 1000 / 60 / 60 / 24 / 365;
+      return parseInt(age);
+    },
+    addrChange(value) {
+        this.form.provinceId =value[0];
+        this.form.cityId = value[1];
+        this.form.areaId = value[2];
+        this.form.provinceName = CodeToText[value[0]];
+        this.form.cityName = CodeToText[value[1]];
+        this.form.areaName = CodeToText[value[2]];
+      console.log("this.provinceName", this.provinceName);
+      console.log("addrChange", value);
+    },
+    saveJobIntention(){
+      saveJobIntention(this.form).then(res=>{
+        this.$message.success(res.msg)
+        // console.log('saveJobIntention',res);
+      })
+    },
+    saveSelfAssessment(){
+      saveSelfAssessment({selfAssessment:this.selfAssessment}).then(res=>{
+        this.$message.success(res.msg)
+      })
+    },
+  },
+};
+</script>
+
+<style lang='scss' scoped>
+.c-yellow {
+  color: #ff6901;
+}
+
+.app-main-box-content {
+  min-height: calc(100vh - 73px - 104px - 64px - 100px - 23px - 40px);
+}
+.banner-breadcrumb-breadcrumb {
+  background-color: #fff;
+  :deep(.el-breadcrumb) {
+    width: 70%;
+    height: 64px;
+    line-height: 64px;
+    min-width: 600px;
+    margin: 0 auto;
+    font-size: 20px;
+  }
+  :deep(.el-breadcrumb__inner.is-link) {
+    color: #7e7e7e;
+    font-weight: normal;
+  }
+  :deep(.el-breadcrumb__item:last-child .el-breadcrumb__inner) {
+    color: #ff0000;
+  }
+}
+.resume {
+  color: #666;
+  .title {
+    text-align: center;
+    color: #222;
+    font-weight: 400;
+    font-size: 24px;
+    letter-spacing: 1.55px;
+    padding-bottom: 30px;
+    border-bottom: 1px solid #d7d7d7;
+    margin-bottom: 40px;
+  }
+  .name {
+    color: #222;
+    font-size: 30px;
+    margin-bottom: 10px;
+  }
+  .avatar {
+    width: 138px;
+    height: 138px;
+    background-color: rgba($color: #fff, $alpha: 0.7);
+    padding: 7px;
+    margin-right: 0;
+    margin-left: auto;
+  }
+  .resumm-item {
+    margin-bottom: 50px;
+    .item-title {
+      font-size: 20px;
+      color: #222;
+      margin-bottom: 14px;
+      position: relative;
+      padding-left: 10px;
+      &::before{
+        content:'';
+        width: 5px;
+        height: 5px;
+        border-radius: 50%;
+        position: absolute;
+        left: 0;
+        top: 50%;
+        margin-top: -2.5px;
+        background: #709078;
+      }
+    }
+    p {
+      margin-bottom: 10px;
+    }
+    .link-page {
+      padding-top: 24px;
+      text-align: right;
+      cursor: pointer;
+    }
+  }
+}
+.el-form {
+  background: #f4f4f4;
+  margin-left: -20px;
+  margin-right: -20px;
+  padding: 20px;
+  .form-title {
+    font-size: 20px;
+    color: #222;
+    margin-bottom: 14px;
+  }
+}
+.btn-wrap{
+    text-align: right;
+    .btn{
+      display: inline-block;
+      padding: 0 20px;
+      cursor: pointer;
+      height: 30px;
+      line-height: 30px;
+      background: #709078;
+      color: #fff;
+      font-size: 16px;
+      border-radius: 5px;
+      margin-left: 10px;
+    }
+  }
+.resumm-item.self-assessment{
+  padding-top: 24px;
+  margin-bottom: 0;
+  .textarea{
+    margin-bottom: 24px;
+  }
+}
+</style>

+ 232 - 3
src/views/PersonalCenter/Resume/ResumeIndex.vue

@@ -2,11 +2,240 @@
  * @Description: 我的简历
  * @Author: 空白格
  * @Date: 2022-08-24 09:35:03
- * @LastEditors: 空白格
- * @LastEditTime: 2022-08-24 09:35:03
+ * @LastEditors: gcz
+ * @LastEditTime: 2022-08-25 11:57:52
  * @FilePath: \veterans_client_web\src\views\PersonalCenter\Resume\ResumeIndex.vue
  * @Copyright: Copyright (c) 2016~2022 by 空白格, All Rights Reserved.
 -->
 <template>
-  <div>我的简历</div>
+  <div class="app-main">
+    <BannerBreadcrumb title="我的简历" :breadcrumb="false" />
+    <div class="banner-breadcrumb-breadcrumb">
+      <el-breadcrumb separator-class="el-icon-arrow-right">
+        <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
+        <el-breadcrumb-item :to="{ path: '/personalcenter' }"
+          >我的</el-breadcrumb-item
+        >
+        <el-breadcrumb-item>我的简历</el-breadcrumb-item>
+      </el-breadcrumb>
+    </div>
+    <div class="app-main-box">
+      <div class="app-main-box-content resume">
+        <div class="title">我的简历</div>
+        <el-row>
+          <el-col :span="16">
+            <div class="name">{{ memberinfo.name }}</div>
+            <div class="">
+              {{ memberinfo.menSex === 1 ? "女" : "男" }} ·
+              <span class="position" v-if="memberinfo.jobStatus !== 0">
+                · <span class="c-yellow">入职中</span>
+                <span>(memberinfo.company)</span>
+              </span>
+              <span class="c-yellow" v-else>未入职</span>
+            </div>
+          </el-col>
+          <el-col :span="8">
+            <div class="avatar hexagon">
+              <div
+                class="avatar-box hexagon-box"
+                :style="{
+                  backgroundImage: `url('${
+                    memberinfo.avatar
+                      ? memberinfo.avatar
+                      : 'https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png'
+                  }')`,
+                }"
+              ></div>
+            </div>
+          </el-col>
+        </el-row>
+        <el-row class="resumm-item">
+          <el-col :span="22">
+            <div class="item-title">基本信息</div>
+            <p>
+              退役军人 ·
+              {{ memberinfo.menBirth ? getAge(memberinfo.menBirth) : "-" }}岁 ·
+              {{ memberinfo.politOutlook || "-" }} ·
+              {{ memberinfo.degrEduc || "-" }}
+            </p>
+            <p>电话:{{ memberinfo.mobile }}</p>
+          </el-col>
+          <el-col class="link-page" :span="2">
+            <img @click="goEdit" src="@/assets/images/link-page-icon.svg" alt="">
+          </el-col>
+        </el-row>
+        <el-row class="resumm-item">
+          <el-col :span="22">
+            <div class="item-title">期望薪资</div>
+            <div v-if="memberinfo.cityName && memberinfo.provinceName && memberinfo.areaName">{{ `${memberinfo.provinceName}-${memberinfo.cityName}-${memberinfo.areaName}` }}</div>
+				    <div class="c-yellow" v-if="memberinfo.expectedLowestSalary && memberinfo.expectedHighestSalary">{{ `${memberinfo.expectedLowestSalary}k ~ ${memberinfo.expectedHighestSalary}k` }}</div>
+				    <div class="supple" v-if="!memberinfo.workCity && !memberinfo.expectedLowestSalary && !memberinfo.expectedLowestSalary">暂末补充求职意向… </div>
+          </el-col>
+          <el-col class="link-page" :span="2">
+            <img @click="goEdit" src="@/assets/images/link-page-icon.svg" alt="">
+          </el-col>
+        </el-row>
+        <el-row class="resumm-item">
+          <el-col :span="22">
+            <div class="item-title">自我评价</div>
+            <div v-if="memberinfo.selfAssessment">
+              {{ memberinfo.selfAssessment }}
+            </div>
+            <p v-else>暂末补充自我评价…</p>
+          </el-col>
+          <el-col class="link-page" :span="2">
+            <img @click="goEdit" src="@/assets/images/link-page-icon.svg" alt="">
+          </el-col>
+        </el-row>
+        <el-row class="resumm-item">
+          <el-col :span="22">
+            <div class="item-title">工作经历</div>
+            <el-empty description="暂无工作经历"></el-empty>
+          </el-col>
+          <el-col class="link-page" :span="2">
+            <!-- <img @click="goEdit" src="@/assets/images/link-page-icon.svg" alt=""> -->
+          </el-col>
+        </el-row>
+        <el-row class="resumm-item">
+          <el-col :span="22">
+            <div class="item-title">培训与教育经历</div>
+            <el-empty description="暂无培训与教育经历"></el-empty>
+          </el-col>
+          <el-col class="link-page" :span="2">
+            <!-- <img @click="goEdit" src="@/assets/images/link-page-icon.svg" alt=""> -->
+          </el-col>
+        </el-row>
+      </div>
+    </div>
+  </div>
 </template>
+
+<script>
+import BannerBreadcrumb from "@/components/BannerBreadcrumb";
+import { getPersonInfoData } from "@/api/PersonalCenter";
+export default {
+  name: "Resume",
+  components: {
+    BannerBreadcrumb,
+  },
+  data() {
+    return {
+      memberinfo: {},
+    };
+  },
+  created() {
+    this.getPersonInfo();
+  },
+  methods: {
+    /**
+     * 获取个人信息
+     * @date 2022-08-15
+     * @returns {any}
+     */
+    getPersonInfo() {
+      getPersonInfoData().then((res) => {
+        if (res.code === 200) {
+          this.memberinfo = res?.data;
+          console.log("this.memberinfo", this.memberinfo);
+        }
+      });
+    },
+    /**
+     * 通过出生年月计算年龄
+     * @param { String } date
+     */
+    getAge(date) {
+      const birth = new Date(date).valueOf();
+      const now = new Date().valueOf();
+      const age = (now - birth) / 1000 / 60 / 60 / 24 / 365;
+      return parseInt(age);
+    },
+    goEdit(){
+      this.$router.push({path:'resumeEdit'});
+    }
+  },
+};
+</script>
+
+<style lang='scss' scoped>
+.c-yellow {
+  color: #ff6901;
+}
+
+.app-main-box-content {
+  min-height: calc(100vh - 73px - 104px - 64px - 100px - 23px - 40px);
+}
+.banner-breadcrumb-breadcrumb {
+  background-color: #fff;
+  :deep(.el-breadcrumb) {
+    width: 70%;
+    height: 64px;
+    line-height: 64px;
+    min-width: 600px;
+    margin: 0 auto;
+    font-size: 20px;
+  }
+  :deep(.el-breadcrumb__inner.is-link) {
+    color: #7e7e7e;
+    font-weight: normal;
+  }
+  :deep(.el-breadcrumb__item:last-child .el-breadcrumb__inner) {
+    color: #ff0000;
+  }
+}
+.resume {
+  color: #666;
+  .title {
+    text-align: center;
+    color: #222;
+    font-weight: 400;
+    font-size: 24px;
+    letter-spacing: 1.55px;
+    padding-bottom: 30px;
+    border-bottom: 1px solid #d7d7d7;
+    margin-bottom: 40px;
+  }
+  .name {
+    color: #222;
+    font-size: 30px;
+    margin-bottom: 10px;
+  }
+  .avatar {
+    width: 138px;
+    height: 138px;
+    background-color: rgba($color: #fff, $alpha: 0.7);
+    padding: 7px;
+    margin-right: 0;
+    margin-left: auto;
+  }
+  .resumm-item {
+    margin-bottom: 50px;
+    .item-title {
+      font-size: 20px;
+      color: #222;
+      margin-bottom: 14px;
+      position: relative;
+      padding-left: 10px;
+      &::before{
+        content:'';
+        width: 5px;
+        height: 5px;
+        border-radius: 50%;
+        position: absolute;
+        left: 0;
+        top: 50%;
+        margin-top: -2.5px;
+        background: #709078;
+      }
+    }
+    p {
+      margin-bottom: 10px;
+    }
+    .link-page{
+      padding-top: 24px;
+      text-align: right;
+      cursor: pointer;
+    }
+  }
+}
+</style>