From 5f00696dfb25bc90034448ceb634ed1ef256681a Mon Sep 17 00:00:00 2001
From: qiyunfeng-create <1940665526@qq.com>
Date: 星期四, 21 八月 2025 21:13:35 +0800
Subject: [PATCH] Merge branch 'master' of http://182.92.203.7:2001/r/xiehe_website

---
 src/views/classManage/studentManage.vue |  475 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 475 insertions(+), 0 deletions(-)

diff --git a/src/views/classManage/studentManage.vue b/src/views/classManage/studentManage.vue
new file mode 100644
index 0000000..f773819
--- /dev/null
+++ b/src/views/classManage/studentManage.vue
@@ -0,0 +1,475 @@
+<template>
+  <div class="classManagePage-box">
+    <div class="classManagePage-nav">
+      <el-breadcrumb :separator-icon="ArrowRight">
+        <el-breadcrumb-item>鎴戠殑鐝骇</el-breadcrumb-item>
+        <el-breadcrumb-item>{{ classInfo?.name }}</el-breadcrumb-item>
+        <el-breadcrumb-item>鐝骇绠$悊</el-breadcrumb-item>
+      </el-breadcrumb>
+    </div>
+    <div class="classManagePage-content">
+      <div class="headerBox">
+        <div class="btnBox">
+          <!-- 鎵归噺閫氳繃鎸夐挳 -->
+          <el-button
+            v-if="multipleSelection.length > 0"
+            type="success"
+            size="small"
+            @click="updateStateNormalDatas"
+            >鎵归噺閫氳繃</el-button
+          >
+          <!-- 鎵归噺绉婚櫎鎸夐挳 -->
+          <el-button
+            v-if="multipleSelection.length > 0"
+            type="danger"
+            size="small"
+            @click="removeStudentDatas"
+            >鎵归噺绉婚櫎</el-button
+          >
+          <!-- 鎵归噺鎷掔粷 -->
+          <el-button
+            v-if="multipleSelection.length > 0"
+            type="warning"
+            size="small"
+            @click="updateStateRejectDatas"
+            >鎵归噺鎷掔粷</el-button
+          >
+        </div>
+        <!-- <div class="searchBox">
+          <el-input v-model="searchKey" clearable @clear="searchData()" placeholder="璇疯緭鍏ュ叧閿瓧">
+            <template #append>
+              <el-button type="primary" @click="searchData()" class="searchBtn" :icon="Search" />
+            </template>
+          </el-input>
+        </div> -->
+      </div>
+      <div class="listBox">
+        <el-table
+          :header-cell-style="{ background: '#eee' }"
+          :data="dataList"
+          max-height="600px"
+          style="width: 100%"
+          v-loading="pages.loading"
+          @selection-change="handleSelectionChange"
+        >
+          <el-table-column type="selection" :selectable="selectable" width="55" />
+          <el-table-column prop="index" label="搴忓彿" width="70" />
+          <el-table-column label="濮撳悕" width="400">
+            <template #default="scope">
+              <div class="userBox">
+                <el-avatar
+                  style="margin-right: 10px"
+                  v-if="scope.row.appUser.icon"
+                  :size="35"
+                  :src="scope.row.appUser.icon"
+                />
+                <el-avatar
+                  style="margin-right: 10px"
+                  :size="35"
+                  v-if="!scope.row.appUser.icon"
+                  :icon="UserFilled"
+                />
+                <span v-if="scope.row.appUser.name">{{ scope.row.appUser.name }}</span>
+              </div>
+            </template>
+          </el-table-column>
+          <el-table-column prop="createDate" label="鍔犲叆鐝骇鏃堕棿" />
+          <el-table-column label="鐘舵��">
+            <template #default="scope">
+              <span v-if="scope.row.state == 'WaitValid'" style="color: #ef9f29"> 瀹℃牳涓� </span>
+              <span v-if="scope.row.state == 'Normal'" style="color: #1dbd11"> 宸查�氳繃 </span>
+              <span v-if="scope.row.state == 'Reject'" style="color: #fc425d"> 鏈�氳繃 </span>
+            </template>
+          </el-table-column>
+          <el-table-column label="鐝骇鎴愬憳韬唤">
+            <template #default="scope">
+              <span v-if="scope.row.linkType == 'RefCode'"> 瀛︾敓 </span>
+              <span v-if="scope.row.linkType == 'Teacher'"> 鍔╂暀 </span>
+              <span v-if="scope.row.linkType == 'Creator'"> 鍒涘缓浜� </span>
+            </template>
+          </el-table-column>
+          <el-table-column label="鎿嶄綔" width="200">
+            <template #default="scope">
+              <el-button
+                link
+                v-if="scope.row.linkType != 'Creator' && scope.row.state == 'Normal'"
+                type="danger"
+                size="small"
+                @click="removeStudent(scope.row)"
+              >
+                绉婚櫎
+              </el-button>
+              <el-button link v-if="scope.row.linkType == 'Creator'" type="info" size="small">
+                ---
+              </el-button>
+              <el-button
+                link
+                v-if="scope.row.state != 'Normal'"
+                type="success"
+                size="small"
+                @click="selectIdentity(scope.row)"
+              >
+                閫氳繃
+              </el-button>
+              <el-button
+                link
+                v-if="scope.row.state != 'Normal' && scope.row.state != 'Reject'"
+                type="warning"
+                size="small"
+                @click="updateStateReject(scope.row)"
+              >
+                鎷掔粷
+              </el-button>
+            </template>
+          </el-table-column>
+        </el-table>
+        <el-pagination
+          style="float: right"
+          v-model:current-page="pages.page"
+          :page-size="pages.pageSize"
+          layout="total, prev, pager, next"
+          :total="pages.count"
+          @size-change="handleSizeChange"
+          @current-change="handleCurrentChange"
+        />
+        <el-dialog v-model="visible" title="閫夋嫨褰撳墠鎴愬憳韬唤" width="500" align-center>
+          <el-radio-group v-model="currentLinkType">
+            <el-radio label="RefCode" size="large" border>瀛︾敓</el-radio>
+            <el-radio label="Teacher" size="large" border>鍔╂暀</el-radio>
+          </el-radio-group>
+          <template #footer>
+            <div class="dialog-footer">
+              <el-button @click="cancleLinkType"> 鍙栨秷 </el-button>
+              <el-button type="primary" @click="updateStateNormal"> 纭 </el-button>
+            </div>
+          </template>
+        </el-dialog>
+        <el-dialog v-model="visibleReject" title="鎷掔粷鍘熷洜" width="500" align-center>
+          <div class="reasonStr">
+            <span style="width: 100px">鎷掔粷鍘熷洜锛�</span>
+            <el-input type="textarea" :rows="2" maxlength="100" v-model="reasonStr"></el-input>
+          </div>
+          <template #footer>
+            <div class="dialog-footer">
+              <el-button @click="cancleReject"> 鍙栨秷 </el-button>
+              <el-button type="primary" @click="updateStateReject"> 纭 </el-button>
+            </div>
+          </template>
+        </el-dialog>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { reactive, ref, onMounted, inject, watch } from 'vue'
+import type { TableInstance } from 'element-plus'
+import { useRoute } from 'vue-router'
+import { Search, ArrowRight, UserFilled } from '@element-plus/icons-vue'
+import { ElMessage, ElMessageBox } from 'element-plus'
+import { getPublicImage } from '@/assets/js/middleGround/tool.js'
+import moment from 'moment'
+
+const route: any = useRoute()
+const MG: any = inject('MG')
+const classInfo = JSON.parse(route.query.classInfo)
+
+const searchKey = ref('')
+const reasonStr = ref('')
+const dataList = ref([])
+const visible = ref(false)
+const currentIdentity = ref()
+const currentLinkType = ref('RefCode')
+const visibleReject = ref(false)
+const rejectData: any = ref()
+let pages = reactive({
+  page: 1,
+  pageSize: 10,
+  count: 0,
+  loading: false
+})
+
+const multipleSelection = ref<any[]>([])
+
+const selectable = (row: any) => ![1].includes(row.index)
+
+onMounted(() => {
+  getStudentList() 
+})
+
+const handleSelectionChange = (val: any) => {
+  multipleSelection.value = val
+}
+
+const handleSizeChange = (val: number) => {
+  pages.pageSize = val
+  getStudentList()
+}
+
+const handleCurrentChange = (val: number) => {
+  pages.page = val
+  getStudentList()
+}
+
+const searchData = () => {
+  pages.page = 1
+  pages.pageSize = 10
+  getStudentList()
+}
+
+// 鑾峰彇瀛︾敓鍒楄〃
+const getStudentList = () => {
+  pages.loading = true
+  const data = {
+    start: (pages.page - 1) * pages.pageSize,
+    size: pages.pageSize,
+    groupId: classInfo.id
+  }
+  MG.identity.getGroupUserList(data).then((res: any) => {
+    const { datas } = res
+    pages.loading = false
+    if (datas.length > 0) {
+      dataList.value = datas.map((item: any, index: number) => {
+        if (item.linkType == 'Creator') {
+          const userInfo = item.appUser?.infoList?.find((citem: any) => citem.type == 'teacherInfo')
+          item.appUser.name = userInfo.name
+          item.appUser.icon = userInfo.icon
+          if (userInfo?.data) {
+            const iconData = JSON.parse(userInfo.data)
+            item.appUser.icon = getPublicImage(iconData?.relevantCertificates[0]?.md5, 100) ?? ''
+          }
+        }
+        if (item.linkType == 'RefCode' || item.linkType == 'Teacher') {
+          let userInfo = null
+          const wechatData = item.appUser?.infoList?.find((citem: any) => citem.type == 'WeChat')
+          const defaultData = item.appUser?.infoList?.find((citem: any) => citem.type == 'Default')
+          userInfo = defaultData
+          if (wechatData?.name) {
+            userInfo = wechatData
+          }
+          item.appUser.name = userInfo.name
+          item.appUser.icon = userInfo.icon
+        }
+        return {
+          ...item,
+          index: index + 1,
+          createDate: moment(item.createDate).format('YYYY-MM-DD')
+        }
+      })
+      pages.count = dataList.value.length
+    }
+  })
+}
+
+// 绉婚櫎瀛︾敓
+const removeStudent = (item: any) => {
+  ElMessageBox.confirm('鏄惁绉婚櫎閫変腑鎴愬憳?')
+    .then(() => {
+      const data = {
+        groupId: classInfo.id,
+        appUserIds: [item.appUser.id]
+      }
+      MG.identity.removeAppUserFromGroup(data).then((res: any) => {
+        if (res) {
+          ElMessage({
+            message: '宸茬Щ闄�',
+            type: 'success'
+          })
+          getStudentList()
+        }
+      })
+    })
+    .catch(() => {
+      // catch error
+    })
+}
+
+// 鎵归噺绉婚櫎瀛︾敓
+const removeStudentDatas = () => {
+  ElMessageBox.confirm('鏄惁鎵归噺绉婚櫎閫変腑鎴愬憳?')
+    .then(() => {
+      const data = {
+        groupId: classInfo.id,
+        appUserIds: multipleSelection.value.map((item) => item.appUser.id)
+      }
+      MG.identity.removeAppUserFromGroup(data).then((res: any) => {
+        if (res) {
+          ElMessage({
+            message: '宸茬Щ闄�',
+            type: 'success'
+          })
+          getStudentList()
+        }
+      })
+    })
+    .catch(() => {
+      // catch error
+    })
+}
+
+const selectIdentity = (item: any) => {
+  visible.value = true
+  currentIdentity.value = item
+}
+
+const cancleLinkType = () => {
+  visible.value = false
+  currentIdentity.value = null
+  currentLinkType.value = 'RefCode'
+}
+
+// 鏇存柊鐘舵��
+const updateStateNormal = () => {
+  const data = {
+    groupId: classInfo.id,
+    requests: [
+      {
+        linkId: currentIdentity.value.linkId,
+        linkType: currentLinkType.value,
+        state: 'Normal',
+        groupState: 'Normal'
+      }
+    ]
+  }
+  MG.identity.updateAppUserGroupLink(data).then((res: any) => {
+    if (res) {
+      visible.value = false
+      ElMessage({
+        message: '宸查�氳繃',
+        type: 'success'
+      })
+      getStudentList()
+    }
+  })
+}
+
+// 鎵归噺閫氳繃
+const updateStateNormalDatas = () => {
+  const data = {
+    groupId: classInfo.id,
+    requests: multipleSelection.value.map((item) => {
+      return {
+        linkId: item.linkId,
+        linkType: item.linkType,
+        state: 'Normal',
+        groupState: 'Normal'
+      }
+    })
+  }
+  MG.identity.updateAppUserGroupLink(data).then((res: any) => {
+    if (res) {
+      ElMessage({
+        message: '宸查�氳繃',
+        type: 'success'
+      })
+      getStudentList()
+    }
+  })
+}
+
+// 鎵归噺鎷掔粷
+const updateStateRejectDatas = () => {
+  const data = {
+    groupId: classInfo.id,
+    requests:multipleSelection.value.map((item) => {
+      return {
+        linkId: item.linkId,
+        linkType: item.linkType,
+        state: 'Reject',
+        groupState: 'Reject'
+      }
+    })
+  }
+  MG.identity.updateAppUserGroupLink(data).then((res:any) => {
+    if (res) {
+      ElMessage({
+        message: '宸叉嫆缁�',
+        type: 'success'
+      })
+      getStudentList()
+    }
+  })
+}
+
+const rejectInfo = (item: any) => {
+  visibleReject.value = true
+  rejectData.value = item
+}
+
+const cancleReject = () => {
+  visibleReject.value = false
+  reasonStr.value = ''
+}
+
+// 鏇存柊鐘舵�� 鎷掔粷
+const updateStateReject = (item:any) => {
+  const data = {
+    groupId: classInfo.id,
+    requests: [
+      {
+        linkId: item.linkId,
+        linkType: item.linkType,
+        state: 'Reject',
+        groupState: 'Reject'
+      }
+    ]
+  }
+  MG.identity.updateAppUserGroupLink(data).then((res: any) => {
+    if (res) {
+      ElMessage({
+        message: '宸叉嫆缁�',
+        type: 'warning'
+      })
+      cancleReject()
+      getStudentList()
+    }
+  })
+}
+</script>
+
+<style lang="less" scoped>
+.classManagePage-box {
+  padding: 20px;
+  .classManagePage-nav {
+    padding-bottom: 20px;
+    border-bottom: 1px solid #e6e8ed;
+  }
+  .classManagePage-content {
+    .headerBox {
+      height: 50px;
+      line-height: 50px;
+      overflow: hidden;
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      .btnBox {
+        flex: 1;
+      }
+      .searchBox {
+        width: 300px;
+        float: right;
+        .searchBtn {
+          background-color: var(--el-color-primary);
+          color: #fff;
+          border-top-left-radius: 0;
+          border-bottom-left-radius: 0;
+        }
+      }
+    }
+    .listBox {
+      .el-radio.is-bordered.el-radio--large {
+        padding: 0px 100px 0 11px;
+      }
+      .userBox {
+        display: flex;
+        align-items: center;
+      }
+    }
+  }
+  .reasonStr {
+    display: flex;
+    justify-content: flex-start;
+    align-items: center;
+  }
+}
+</style>

--
Gitblit v1.9.1