From b15a997e95d715c41df3a76aecbf58ec1141ab53 Mon Sep 17 00:00:00 2001
From: qiyunfeng-create <1940665526@qq.com>
Date: 星期四, 21 八月 2025 18:37:17 +0800
Subject: [PATCH] 个人中心-接口测试

---
 src/views/personalCenter/class.vue |  461 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 458 insertions(+), 3 deletions(-)

diff --git a/src/views/personalCenter/class.vue b/src/views/personalCenter/class.vue
index 7293e29..c991c11 100644
--- a/src/views/personalCenter/class.vue
+++ b/src/views/personalCenter/class.vue
@@ -1,7 +1,462 @@
 <template>
-  <div class="myBook">
-    <div class="myBook_header">
-      <div class="myBook_header_title">鎴戠殑鐝骇</div>
+  <div class="coursePage">
+    <div class="personalPage-title">鎴戠殑鐝骇</div>
+    <div class="tabs">
+      <el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
+        <el-tab-pane
+          :label="'褰撳墠鐝骇锛�' + calssList.length + '锛�'"
+          name="1"
+        ></el-tab-pane>
+        <!-- <el-tab-pane label="鍘嗗彶鐝骇(5)" name="2"></el-tab-pane> -->
+      </el-tabs>
+    </div>
+    <div class="headerBox">
+      <div class="searchBox">
+        <el-input
+          v-model="searchKey"
+          clearable
+          @clear="searchList()"
+          placeholder="璇疯緭鍏ュ叧閿瓧"
+        >
+          <template #append>
+            <el-button
+              type="primary"
+              class="searchBtn"
+              @click="searchList()"
+              :icon="Search"
+            />
+          </template>
+        </el-input>
+      </div>
+      <el-button type="primary" class="applyStartClasses" @click="openJoin()"
+        >鍔犲叆鐝骇</el-button
+      >
+      <el-dialog v-model="dialogVisible" title="鍔犲叆鐝骇" width="500">
+        <div class="codeContent">
+          <span>閭�璇风爜锛�</span>
+          <el-input style="width: 330px" v-model="codeText" placeholder="璇疯緭鍏ラ個璇风爜" />
+          <el-button type="primary" @click="getClassDetail">纭</el-button>
+        </div>
+        <div class="classInfo" v-if="classDetail?.name">
+          <div class="itemCon">
+            <span>鐝骇鍚嶇О锛�</span>
+            <span>{{ classDetail.name }}</span>
+          </div>
+          <div class="itemCon">
+            <span>鐝骇浜烘暟锛�</span>
+            <span>{{ classDetail.memberCount }} / {{ classDetail.maxUserCount }}</span>
+          </div>
+          <div class="itemCon">
+            <span>寮�璇炬椂闂达細</span>
+            <span
+              >{{ moment(classDetail.beginDate).format("YYYY-MM-DD") }} -
+              {{ moment(classDetail.endDate).format("YYYY-MM-DD") }}</span
+            >
+          </div>
+        </div>
+        <template #footer>
+          <div class="dialog-footer">
+            <el-button @click="dialogVisible = false"> 鍙栨秷 </el-button>
+            <el-button type="primary" @click="joinClass()"> 纭 </el-button>
+          </div>
+        </template>
+      </el-dialog>
+    </div>
+    <div class="courseListBox" v-if="calssList.length > 0 && !isLoading">
+      <div class="courseItem" v-for="(item, index) in calssList" :key="index">
+        <div class="itemHeader">
+          <div class="title">{{ item.name }}</div>
+          <div class="courseId">锛圛D锛歿{ item.id }}锛�</div>
+          <!-- <div class="copyIdBtn" @click="copy(item.refCode)">澶嶅埗閭�璇风爜</div> -->
+        </div>
+        <div class="itemInfo" @click="goClassManage(item)">
+          <div class="infoBox">
+            <p>
+              鐘舵�侊細<span v-if="item.userState == 'WaitValid'" style="color: #ef9f29">
+                瀹℃牳涓� </span
+              ><span v-if="item.userState == 'Normal'" style="color: #1dbd11">
+                杩涜涓� </span
+              ><span v-if="item.userState == 'Reject'" style="color: red"> 鏈�氳繃 </span>
+            </p>
+            <p>鐝骇浜烘暟锛歿{ item.memberCount }} / {{ item.maxUserCount }}</p>
+            <p>鏈夋晥鏈燂細{{ item.classTime }}</p>
+          </div>
+        </div>
+      </div>
+    </div>
+    <el-empty description="鏆傛棤鏁版嵁" v-if="calssList.length == 0 && !isLoading" />
+    <div style="min-height: 200px" v-if="isLoading" v-loading="isLoading"></div>
+    <div class="pageBox">
+      <el-pagination
+        v-model:current-page="pages.currentPage"
+        :page-size="pages.pageSize"
+        :size="'small'"
+        :disabled="pages.count <= 1"
+        layout="total, prev, pager, next"
+        :total="pages.count"
+        @size-change="handleSizeChange"
+        @current-change="handleCurrentChange"
+      />
     </div>
   </div>
 </template>
+
+<script setup lang="ts">
+import { reactive, ref, onMounted, inject, watch } from "vue";
+import { Search } from "@element-plus/icons-vue";
+import { useRouter } from "vue-router";
+import { ElMessage } from "element-plus";
+import { getPublicImage } from "@/assets/js/middleGround/tool.js";
+import moment from "moment";
+import useClipboard from "vue-clipboard3";
+
+const { toClipboard } = useClipboard();
+const MG: any = inject("MG");
+const config: any = inject("config");
+const router = useRouter();
+const activeName = ref("1");
+
+interface ClassItem {
+  id: string;
+  name: string;
+  memberCount: number;
+  maxUserCount: number;
+  userState: string;
+  beginDate: string;
+  endDate: string;
+  classTime: string;
+  linkProductDto: {
+    product: {
+      name: string;
+      icon: string;
+    };
+  };
+}
+
+const calssList = ref<ClassItem[]>([]);
+const searchKey = ref("");
+const codeText = ref("");
+const dialogVisible = ref(false);
+const classDetail = ref();
+const isLoading = ref(true);
+
+let pages = reactive({
+  currentPage: 1,
+  page: 1,
+  pageSize: 6,
+  count: 0,
+  loading: false,
+});
+
+onMounted(() => {
+  getCurrentClassList();
+});
+
+//  鍒嗛〉
+const handleSizeChange = (val: number) => {
+  pages.pageSize = val;
+  getCurrentClassList();
+};
+
+const handleCurrentChange = (val: number) => {
+  pages.page = val;
+  pages.currentPage = val;
+  getCurrentClassList();
+};
+
+const handleClick = (val: any) => {
+  activeName.value = val;
+};
+
+const openJoin = () => {
+  dialogVisible.value = true;
+  classDetail.value = null;
+  codeText.value = "";
+};
+
+// 鎼滅储
+const searchList = () => {
+  pages.page = 1;
+  pages.currentPage = 1;
+  getCurrentClassList();
+};
+
+// 澶嶅埗
+const copy = async (text: string) => {
+  try {
+    await toClipboard(text);
+    ElMessage({
+      message: "澶嶅埗鎴愬姛",
+      type: "success",
+    });
+  } catch (e) {
+    console.error(e);
+  }
+};
+
+// 鍔犲叆鐝骇
+const joinClass = () => {
+  if (!codeText.value) {
+    ElMessage({
+      message: "鏃犳晥鐨勯個璇风爜",
+      type: "error",
+    });
+    return false;
+  }
+  const data = { refCode: codeText.value };
+  MG.identity.joinGroupByRefCode(data).then((res: any) => {
+    if (res == "缁勪笉瀛樺湪") {
+      ElMessage({
+        message: "鏃犳晥鐨勭彮绾�",
+        type: "error",
+      });
+    }
+    if (res == "缁勬垚鍛樻暟閲忓凡鏈�澶�,涓嶈兘鍔犲叆") {
+      ElMessage({
+        message: "鐝骇鎴愬憳鏁伴噺宸叉渶澶э紝涓嶈兘鍔犲叆",
+        type: "error",
+      });
+    }
+    if (res == "宸茬粡鐢宠杩囧姞鍏ユ缁�") {
+      ElMessage({
+        message: "宸茬粡鐢宠杩囧姞鍏ユ鐝骇",
+        type: "error",
+      });
+    }
+    dialogVisible.value = false;
+    getCurrentClassList();
+  });
+};
+
+// 鑾峰彇褰撳墠鐝骇鍒楄〃
+const getCurrentClassList = () => {
+  isLoading.value = true;
+  const data = {
+    start: (pages.page - 1) * pages.pageSize,
+    size: pages.pageSize,
+    sort: {
+      type: "Desc",
+      field: "CreateDate",
+      subSorts: [],
+    },
+    filterList: [],
+    searchList: searchKey.value
+      ? [
+          {
+            keywords: searchKey.value,
+            field: "Name",
+            compareType: "Contains",
+          },
+        ]
+      : [],
+  };
+  MG.identity.joinedGroupByList(data).then((res: any) => {
+    isLoading.value = false;
+    pages.count = res.totalSize;
+    if (res.datas) {
+      calssList.value = res.datas.map((item: any) => {
+        return {
+          ...item,
+          classTime:
+            moment(item.beginDate).format("YYYY.MM.DD") +
+            "--" +
+            moment(item.endDate).format("YYYY.MM.DD"),
+          bookName: item.linkProductDto.product.name,
+          bookIcon: getPublicImage(item.linkProductDto.product.icon, 100),
+        };
+      });
+    }
+  });
+};
+
+// 璺宠浆鐝骇绠$悊
+const goClassManage = async (item: any) => {
+  if (item.userState == "WaitValid") {
+    ElMessage({
+      message: "姝e湪瀹℃牳涓�....",
+      type: "warning",
+    });
+    return false;
+  }
+  if (item.userState == "Reject") {
+    ElMessage({
+      message: "瀹℃牳鏈�氳繃",
+      type: "warning",
+    });
+    return false;
+  }
+  const bookInfo = await getBookDetail(item.linkProductDto?.product);
+  let info = {
+    id: item.id,
+    name: item.name,
+    icon: bookInfo.icon,
+    rootCmsItemId: bookInfo.rootCmsItemId,
+    bookId: bookInfo.id,
+    author: bookInfo.author,
+    isbn: bookInfo.isbn,
+    bookRefCode: bookInfo.refCode,
+  };
+  let page = router.resolve({
+    path: "/classManage",
+    query: {
+      classInfo: JSON.stringify(info),
+    },
+  });
+  window.open(page.href, "_blank");
+  // router.push({
+  //   path: '/classManage',
+  //   query: {
+  //     classInfo: JSON.stringify(info)
+  //   }
+  // })
+};
+
+// 鑾峰彇鏁欐潗璇︽儏
+const getBookDetail = async (item: any) => {
+  const path = item.refCode ? "jsek_digitalTextbooks" : config.goodsStore;
+  let query = {
+    path,
+    queryType: "*",
+    productId: String(item.id),
+    storeInfo: path,
+    coverSize: {
+      height: 300,
+      width: 210,
+    },
+    fields: {
+      author: [],
+      isbn: [],
+    },
+  };
+  const res = await MG.store.getProductDetail(query);
+  return res.datas ?? null;
+};
+
+// 閫氳繃code鏌ヨ鐝骇
+const getClassDetail = () => {
+  if (codeText.value == "") {
+    ElMessage({
+      message: "璇疯緭鍏ラ個璇风爜",
+      type: "warning",
+    });
+    return false;
+  }
+  const data = {
+    classIdOrRefCode: codeText.value,
+  };
+  MG.edu
+    .getCourseClass(data)
+    .then((res: any) => {
+      classDetail.value = res;
+    })
+    .catch((err: any) => {
+      console.log(err);
+    });
+};
+</script>
+
+<style lang="less" scoped>
+.coursePage {
+  .tabs {
+    padding: 0 20px;
+  }
+  .headerBox {
+    padding: 5px 20px;
+    margin-bottom: 10px;
+    overflow: hidden;
+    .searchBox {
+      width: 300px;
+      float: left;
+      .searchBtn {
+        background-color: var(--el-color-primary);
+        color: #fff;
+        border-top-left-radius: 0;
+        border-bottom-left-radius: 0;
+      }
+    }
+    .applyStartClasses {
+      float: right;
+    }
+  }
+  .courseListBox {
+    overflow: hidden;
+    .courseItem {
+      float: left;
+      width: 46%;
+      margin: 0 2% 20px;
+      border-radius: 8px;
+      border: 1px solid #efefef;
+      overflow: hidden;
+      .itemHeader {
+        height: 40px;
+        line-height: 40px;
+        padding: 0 20px;
+        // color: #fff;
+        background-color: #f8f8f8;
+        .title {
+          font-weight: 600;
+        }
+        div {
+          display: inline-block;
+        }
+        .courseId {
+          margin-left: 6px;
+          font-size: 12px;
+          color: #999;
+        }
+        .copyIdBtn {
+          float: right;
+          height: 20px;
+          line-height: 20px;
+          margin-top: 10px;
+          font-size: 12px;
+          background-color: #fff;
+          color: #3b93fe;
+          padding: 0 6px;
+          border-radius: 50px;
+          overflow: hidden;
+          cursor: pointer;
+        }
+      }
+      .itemInfo {
+        padding: 20px;
+        flex: 1;
+        display: flex;
+        cursor: pointer;
+        .imgBox {
+          width: 90px;
+          height: 120px;
+          margin-right: 20px;
+        }
+        .infoBox {
+          flex: 1;
+          font-size: 12px;
+          p {
+            margin-bottom: 10px;
+          }
+        }
+      }
+    }
+  }
+  .codeContent {
+    width: 100%;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    padding-bottom: 30px;
+  }
+  .classInfo {
+    padding: 30px 0;
+    border-top: 2px dashed #ccc;
+
+    .itemCon {
+      margin-bottom: 20px;
+    }
+  }
+  .pageBox {
+    padding: 10px 0;
+    display: flex;
+    justify-content: center;
+  }
+}
+</style>

--
Gitblit v1.9.1