山东大学项目实训Web实验室(WebLab)(十三)更新学生端主页面

山东大学项目实训Web实验室(WebLab)(十三)学生端主页面

前言

项目仓库
本项目是为开发一套容器化的开发、运行、测试环境,用以支持Web开发、程序设计等课程的实验教学。
代码内容均为我和肖同学共同完成。

任务目标

设计并且编写主界面
主界面内容:

  • 学生界面
    • 项目中心
      • 课程任务
      • 课程通知
      • 我的项目
    • 上传中心
    • 编辑中心
    • 组织中心
  • 老师界面
    • 组织中心
    • 发布中心
    • 学生课程作业

我的任务

  • 页面外观与布局设计
  • 页面交互设计
  • 页面编写

展示内容

  • 学生端主页面项目布置功能
  • 学生端主页面市场中心
  • 删除学生端主页面上传中心及项目编辑按钮

代码

view/coding.vue

import { FileType } from "../fileziper";
<!--login-student-home-page-->
<template>
  <el-header>
    <topmenu ref="tmRef" :activeIndex="activeIndex" :avatar-url="avatarUrl" @on-index-change="onIndexChange"></topmenu>
  </el-header>
  <el-main v-show="activeIndex == '5'">
    <el-header>
      <el-row :gutter="20">
        <el-col :span="3">
          <el-input v-model="invitationCode" placeholder="组织邀请码" :style="{ width: '200px' }" />
        </el-col>
        <el-col :span="2" />
        <el-col :span="6">
          <el-button text @click="addOrganization()">添加组织</el-button>
        </el-col>
        <el-col :span="12" />


      </el-row>

    </el-header>
    <el-main>
      <el-table :data="organizationData" border style="width: 100%">
        <el-table-column prop="lesson" label="课程" width="510px" />
        <el-table-column prop="teacher" label="教师" width="510px" />
        <el-table-column width="110px">
          <template #default="scope">
            <el-button text size="small" @click="deleteOrganization(scope.row)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-main>

  </el-main>
  <el-main v-show="activeIndex == '4'">
    <el-tabs
        v-model="activeMarketName"
        tab-position="left"
        class="demo-tabs"
        @tab-click="handleClick"
    >
      <el-tab-pane label="数据库" name="first">
        <el-header>
          <div class="tag-group my-2 flex flex-wrap gap-1 items-center">
            <el-row>
              <el-col :span="2">
                <span class="tag-group__title m-1 line-height-2" style="font-size: medium">所选数据库:</span>

              </el-col>
              <el-col :span="1"/>
              <el-col :span="21">
                <el-tag
                  size="large"
                  effect="plain"
              >
                MySQL
              </el-tag>
              </el-col>
            </el-row>
          </div>
        </el-header>
        <el-main>
          <el-tabs type="border-card">
            <el-tab-pane label="关系型数据库">
              <el-row >
                <el-col :span="24">
                  <el-radio v-model="radio1" label="1" size="large" border >MySQL</el-radio>
                  <el-radio v-model="radio1" label="2" size="large" border  >MariaDB</el-radio>
                  <el-radio v-model="radio1" label="3" size="large" border  >Oracle数据库</el-radio>
                </el-col>
                <el-col :span="24"/>
                <el-col :span="24">
                  <el-radio v-model="radio1" label="4" size="large" border  >Microsoft Access</el-radio>
                  <el-radio v-model="radio1" label="5" size="large" border  >Microsoft SQL Server</el-radio>
                </el-col>

              </el-row>

            </el-tab-pane>
            <el-tab-pane label="非关系型数据库">

              <el-row >
                <el-col :span="24">
                  <el-radio v-model="radio1" label="6" size="large" border  >MongoDB</el-radio>
                  <el-radio v-model="radio1" label="7" size="large" border  >Cassandra</el-radio>
                  <el-radio v-model="radio1" label="8" size="large" border  >CouchDB</el-radio>
                </el-col>
                <el-col :span="24"/>
              </el-row>

            </el-tab-pane>
<!--            <el-tab-pane label="键值数据库">-->

<!--            </el-tab-pane>-->
          </el-tabs>

        </el-main>
        <el-footer>
          <el-button size="large" type="primary" plain>
            确定
          </el-button>
        </el-footer>
      </el-tab-pane>
      <el-tab-pane label="test" name="second">
      </el-tab-pane>

    </el-tabs>

  </el-main>

<!--  <el-main v-show="activeIndex == '4'">-->
<!--    <el-row class="tac">-->
<!--      <el-col :span="5">-->
<!--        <side ref="sideRef" @set-file-context="setFileContext" @detele-file="removeTab" @rename="rename" />-->
<!--      </el-col>-->
<!--      <el-col :span="1"></el-col>-->
<!--      <el-col :span="18">-->
<!--        <div v-show="editableTabsValue != '-1'">-->
<!--          <el-tabs v-model="editableTabsValue" type="card" class="demo-tabs" closable @tab-remove="removeTab"-->
<!--            @tab-click="clickTab">-->
<!--            <el-tab-pane v-for="item in editableTabs" :key="item.name" :label="item.title" :name="item.name">-->
<!--            </el-tab-pane>-->
<!--          </el-tabs>-->
<!--          <code-editor-vue ref="cmRef" @on-change="onCodeChange"></code-editor-vue>-->
<!--        </div>-->
<!--        <div v-show="editableTabsValue == '-1'">-->
<!--          <el-result title="点击打开文件">-->
<!--            <template #icon>-->
<!--              <el-icon :size="280">-->
<!--                <files />-->
<!--              </el-icon>-->
<!--            </template>-->
<!--          </el-result>-->
<!--        </div>-->

<!--        <div class="grid-content"></div>-->
<!--        <el-divider content-position="center">-->
<!--          <btns @save-z-i-p="saveZIP"></btns>-->
<!--        </el-divider>-->
<!--        <div class="grid-content"></div>-->
<!--        <ResultsDisplay></ResultsDisplay>-->
<!--      </el-col>-->
<!--    </el-row>-->
<!--  </el-main>-->
  <el-main v-show="activeIndex == '3'">
    <div class="login-wrap">
      <el-form class="login-container">
        <el-upload class="upload-demo" drag action="#" multiple accept=".zip" :http-request="handleUpload">
          <el-icon class="el-icon--upload">
            <upload-filled />
          </el-icon>
          <div class="el-upload__text">
            拖拽文件或
            <em>点击上传</em>
          </div>
          <template #tip>
            <div class="el-upload__tip">只支持zip压缩包</div>
          </template>
        </el-upload>
      </el-form>
    </div>
  </el-main>
  <el-main v-show="activeIndex == '2'">
    <el-tabs v-model="activeProjectTabName" class="demo-tabs" @tab-click="handleProjectTabClick">
      <el-tab-pane label="课程任务" name="1">
        <div v-show="!showHWDetail">
          <el-main>
            <el-dialog v-model="choseProjectFormVisible" title="选择项目" width="30%">
              <el-form>
                <el-form-item label="项目名称" label-width="100px">
                  <el-cascader v-model="choseProject" placeholder="项目搜索" :options="projectData" filterable
                    :props="choseProjectProps" />
                </el-form-item>
              </el-form>
              <template #footer>
                <span class="dialog-footer">
                  <el-button @click="choseProjectFormVisible = false">取消</el-button>
                  <el-button type="primary" @click="submitProject">确认</el-button>
                </span>
              </template>
            </el-dialog>
            <el-table :data="homeworkTableData" border style="width: 100%">
              <el-table-column prop="lesson" label="课程" width="180" />
              <el-table-column prop="date" label="截止日期" sortable width="180">
                <template #default="scope">
                  <div style="display: flex; align-items: center">
                    <el-icon>
                      <timer />
                    </el-icon>
                    <span style="margin-left: 10px">{{ scope.row.date }}</span>
                  </div>
                </template>
              </el-table-column>
              <el-table-column prop="mission" label="任务简介" />
              <!-- <el-table-column prop="finish" label="任务进度" width="100" /> -->
              <el-table-column fixed="right" width="200">
                <template #default="scope">
                  <el-button text size="small" @click="checkHWDetail(scope.row)">查看详情</el-button>
                  <el-button text size="small" @click="choseProjectFormVisible = true; choseLab = scope.row">提交作业
                  </el-button>
                </template>
              </el-table-column>
            </el-table>
          </el-main>
        </div>
        <div v-show="showHWDetail">
          <el-page-header content="作业详情" @back="showHWDetail = false;" />
          <el-container>
            <el-main>
              <el-row>
                <el-col :span="22">
                  <el-form label-width="120px">
                    <el-form-item label="任务具体内容">
                      <el-input v-model="choseLab.mission" type="textarea" readonly :rows="10"
                        class="example-demonstration" resize="none">
                      </el-input>
                    </el-form-item>

                    <el-form-item label="已提交的作业">
                      <el-table :data="choseLab.project" border style="width: 100%">
                        <el-table-column prop="projectName" label="项目" />
                        <el-table-column prop="date" label="日期" />
                      </el-table>
                    </el-form-item>
                  </el-form>
                </el-col>
              </el-row>
            </el-main>
          </el-container>
        </div>


      </el-tab-pane>
      <el-tab-pane label="课程通知" name="2">
        <el-table :data="noticeTableData" border style="width: 100%">
          <el-table-column prop="className" label="课程" width="180" />
          <el-table-column prop="date" label="发布日期" sortable width="180">
            <template #default="scope">
              <div style="display: flex; align-items: center">
                <el-icon>
                  <timer />
                </el-icon>
                <span style="margin-left: 10px">{{ scope.row.date }}</span>
              </div>
            </template>
          </el-table-column>
          <el-table-column prop="detail" label="通知内容" />
          <el-table-column fixed="right" width="180">
            <template #default="scope">
              <el-button text size="small" @click="checkNoticeDetail(scope.row.title, scope.row.detail)">查看详情
              </el-button>
            </template>
          </el-table-column>
        </el-table>

      </el-tab-pane>
      <el-tab-pane label="我的项目" name="3">
        <div v-show="!showDetail">
          <el-header>
            <el-button @click="addProject()">
              添加<el-icon class="el-icon--right">
                <Plus />
              </el-icon>
            </el-button>
            <el-button @click="deleteProject()">
              删除<el-icon class="el-icon--right">
                <Delete />
              </el-icon>
            </el-button>
            <el-button @click="downloadProject()">
              下载<el-icon class="el-icon--right">
                <Bottom />
              </el-icon>
            </el-button>
          </el-header>
          <el-main>
            <el-dialog v-model="createProjectFormVisible" title="添加项目" width="30%">
              <el-form :model="createProjectForm">
                <el-form-item label="项目名称" label-width="100px">
                  <el-input v-model="createProjectForm.name" autocomplete="off" />
                </el-form-item>
                <el-form-item label="项目简介" label-width="100px">
                  <el-input type="textarea" v-model="createProjectForm.description" />
                </el-form-item>
              </el-form>
              <template #footer>
                <span class="dialog-footer">
                  <el-button @click="createProjectFormVisible = false">取消</el-button>
                  <el-button type="primary" @click="confirmAddProject">确认</el-button>
                </span>
              </template>
            </el-dialog>

            <el-drawer
                v-model="setProjectFormVisible"
                :with-header="false"
                :before-close="handleClose"
                direction="rtl"
                size='60%'

            >
              <el-form :model="setProjectForm" label-width="120px">
                <el-form-item label="PSM 服务">
                  <el-select v-model="setProjectForm.psm" placeholder="请选择PSM 服务">
                    <el-option label="Zone one" value="shanghai" />
                    <el-option label="Zone two" value="beijing" />
                  </el-select>
                </el-form-item>
                <el-form-item label="SCM 依赖">
                  <el-space direction="vertical" alignment="start" :size="10">
                    <el-row>
                    <el-select v-model="setProjectForm.scm" placeholder="请选择SCM 依赖">
                      <el-option label="Zone one" value="shanghai" />
                      <el-option label="Zone two" value="beijing" />
                    </el-select>
                  </el-row>
                  </el-space>
                  <el-space direction="vertical" alignment="start" :size="10">
                    <el-row :gutter="10">
                    <el-col :span="6">
                      <el-input v-model="setProjectForm.rout" disabled placeholder="motor/motor/qaq" />
                    </el-col>
                    <el-col :span="6">
                      <el-select v-model="setProjectForm.git" placeholder="请选择Git分支">
                        <el-option label="Zone one" value="shanghai" />
                        <el-option label="Zone two" value="beijing" />
                      </el-select>
                    </el-col>
                    <el-col :span="12">
                      <el-select v-model="setProjectForm.gitr" placeholder="master">
                        <el-option label="Zone one" value="shanghai" />
                        <el-option label="Zone two" value="beijing" />
                      </el-select>

                    </el-col>
                  </el-row>
                  </el-space>
                  <el-space direction="vertical" alignment="start" :size="10">
                    <el-row :gutter="10">
                    <el-col :span="6">
                      <el-input v-model="setProjectForm.scmrout" disabled placeholder="toutiao/load" />
                    </el-col>
                    <el-col :span="6">
                      <el-select v-model="setProjectForm.scmver" placeholder="SCM版本">
                        <el-option label="Zone one" value="shanghai" />
                        <el-option label="Zone two" value="beijing" />
                      </el-select>
                    </el-col>
                    <el-col :span="12">
                      <el-select v-model="setProjectForm.scmverdet" placeholder="版本1.1.1.1">
                        <el-option label="Zone one" value="shanghai" />
                        <el-option label="Zone two" value="beijing" />
                      </el-select>
                    </el-col>
                  </el-row>
                  </el-space>
                  <el-space direction="vertical" alignment="start" :size="10">
                    <el-row :gutter="10">
                    <el-col :span="6">
                      <el-input v-model="setProjectForm.scmrout1" disabled placeholder="toutiao/runtime" />
                    </el-col>
                    <el-col :span="6">
                      <el-select v-model="setProjectForm.scmver1" placeholder="SCM版本">
                        <el-option label="Zone one" value="shanghai" />
                        <el-option label="Zone two" value="beijing" />
                      </el-select>
                    </el-col>
                    <el-col :span="12">
                      <el-select v-model="setProjectForm.scmverdet1" placeholder="版本1.1.1.1(master)">
                        <el-option label="Zone one" value="shanghai" />
                        <el-option label="Zone two" value="beijing" />
                      </el-select>

                    </el-col>
                  </el-row>
                  </el-space>
                </el-form-item>
                <el-form-item label="实例配置">
                  <el-row :gutter="10">
                    <el-col :span="9">
                      <el-input-number
                          v-model="setProjectForm.ch"
                          class="mx-4"
                          :min="1"
                          :max="10"
                          controls-position="right"
                          @change="handleChange"
                      />
                    </el-col>
                    <el-col :span="3">
                      <span>
                        C()
                      </span>
                    </el-col>
                    <el-col :span="9">
                      <el-input-number
                          v-model="setProjectForm.mg"
                          class="mx-4"
                          :min="1"
                          :max="10"
                          controls-position="right"
                          @change="handleChange"
                      />
                    </el-col>
                    <el-col :span="3">
                      <span>
                        M(G)
                      </span>
                    </el-col>
                  </el-row>
                </el-form-item>
                <el-form-item>
                  <el-button type="primary" @click="">提交</el-button>
                  <el-button>取消</el-button>
                </el-form-item>
              </el-form>
            </el-drawer>

            <el-table ref="projectTableRef" :data="projectData1" border style="width: 100%"
              @selection-change="handleProjectSelectionChange">
              <el-table-column type="selection" width="55" />
              <el-table-column prop="projectName" label="项目名字" width="180">
                <template #default="scope">
                  <div style="display: flex; align-items: center">
                    <el-icon>
                      <folder />
                    </el-icon>
                    <span style="margin-left: 10px">{{ scope.row.projectName }}</span>
                    <span style="margin-left: 10px">project</span>
                  </div>
                </template>
              </el-table-column>
              <el-table-column prop="date" label="上次更新" width="180" />
              <el-table-column prop="introduction" label="项目简介" />
              <el-table-column prop="url" label="项目地址" />
              <el-table-column fixed="right" width="220">
                <template #default="scope">
                  <el-row>
                    <el-col :span="24">
                      <el-button text size="small" @click="showProjectDetail(scope.row)">项目详情</el-button>
                    </el-col>
                  </el-row>
<!--                  <el-row>-->
<!--                    <el-col :span="24">-->
<!--                      <el-button text size="small" @click="editProject(scope.raw)">编辑项目</el-button>-->
<!--                    </el-col>-->
<!--                  </el-row>-->
                  <el-row>
                    <el-col :span="24">
                      <el-button text size="small" @click="setProject()">项目部署</el-button>
                    </el-col>
                  </el-row>

                </template>

              </el-table-column>
            </el-table>

          </el-main>
        </div>
        <div v-show="showDetail">
          <el-main>
            <el-page-header content="项目详情" @back="closeProjectDetail" />
            <el-container>
              <el-main>
                <el-table :data="selectedProjectDetail?.files" style="width: 80%">
                  <el-table-column prop="name" label="文件夹名字" width="180">
                    <template #default="scope">
                      <div style="display: flex; align-items: center">
                        <el-icon>
                          <folder />
                        </el-icon>
                        <el-button type="text" style="margin-left: 10px">{{ scope.row.name }}</el-button>
                      </div>
                    </template>
                  </el-table-column>
                  <el-table-column prop="date" label="上次更新" width="180" />
                  <el-table-column prop="introduction" label="简介" />
                  <el-table-column fixed="right" width="120">
                    <template #default="scope">
                      <el-button text size="small" @click="deleteProjecFolder(scope.$index)">删除</el-button>
                    </template>

                  </el-table-column>
                </el-table>
                <!-- <el-main> -->
                <el-divider />
                <h6>项目输出日志</h6>
                <!-- <div class="demo-radius"> -->
                <el-input v-model="selectedProjectDetail!.outputlog" type="textarea" readonly
                  class="example-demonstration" :rows="20" resize="none">
                </el-input>
                <!-- </div> -->
                <!-- </el-main> -->

              </el-main>

              <el-aside width="250px">
                <el-row>
                  <el-col :span="2">
                    <el-divider direction="vertical" style="height: 800px" />
                  </el-col>
                  <el-col :span="20">
                    <el-form label-width="120px">
                      <el-form-item size="large" label="项目介绍">
                      </el-form-item>
                      <el-input v-model="selectedProjectDetail!.introduction" type="textarea" readonly :rows="30"
                        class="example-demonstration" resize="none">
                      </el-input>
                    </el-form>
                  </el-col>
                </el-row>
              </el-aside>
            </el-container>
          </el-main>
        </div>
      </el-tab-pane>
    </el-tabs>

  </el-main>
</template>

<script lang="ts" setup>
import { ref, watch, reactive } from "vue";
import CodeEditorVue from "../components/CodeEditor.vue";
import ResultsDisplay from "../components/ResultsDisplay.vue"
import btns from "../layout/btns.vue"
import topmenu from "../layout/topmenu.vue";
import side from "../layout/sidecolumn.vue"
import { ziper } from "../fileziper"
import type { FileType } from "../fileziper";
import { useLoginStore } from '@/stores/store';
import { Files, UploadFilled } from '@element-plus/icons-vue';
import { request } from "@/network/request";
import { ElMessage, ElMessageBox } from "element-plus";
import type { TabsPaneContext, ElTable } from 'element-plus';
import { Folder, Timer, Delete, Bottom, Plus } from '@element-plus/icons-vue';
import type { ElTree } from 'element-plus'
import Node from "element-plus/es/components/tree/src/model/node";
import { h } from 'vue';
import { tsParameterProperty } from "@babel/types";
import type { TagProps } from 'element-plus'

const activeName = ref('first')
const radio1 = ref('1')

const handleClick = (tab: TabsPaneContext, event: Event) => {
  console.log(tab, event)
}

const num = ref(1)
const handleChange = (value: number) => {
  console.log(value)
}
const activeIndex = ref('2');
const tmRef=ref();
const store = useLoginStore();
const avatarUrl = ref('');
const onIndexChange = (idx: string) => {
  activeIndex.value = idx;
  if (idx == '5' && organizationData.value.length == 0) {

  }
}
const getFormDate = () => {
  const Dates = new Date();

  //年份
  const Year: number = Dates.getFullYear();

  //月份下标是0-11
  const Months: any = (Dates.getMonth() + 1) < 10 ? '0' + (Dates.getMonth() + 1) : (Dates.getMonth() + 1);

  //具体的天数
  const Day: any = Dates.getDate() < 10 ? '0' + Dates.getDate() : Dates.getDate();
  return Year + '-' + Months + '-' + Day;
}




//上传中心
const upload = (param: FormData) => {
  request('/weblab/submit/submitByZip', param, store.getToken)
    .then(res => {
      if (res.status == 200 && res.data.msg == 'success') {
        console.log(res);
        ElMessage({
          showClose: true,
          message: '上传成功',
          type: 'success',
          center: true,
          grouping: true
        })
      }
    })
    .catch(error => {
      console.log(error);

    })
}
const handleUpload = (file: any) => {
  let param = new FormData();
  param.append('file', file.file);
  upload(param);
}

//编辑中心
const sideRef = ref();
const cmRef = ref();
const editableTabsValue = ref('-1');
interface tab {
  title: string,
  name: string
}
const editableTabs = ref<tab[]>([]);

const addTab = (name: string, id: string) => {
  editableTabs.value.push({
    title: name,
    name: id,
  })
  editableTabsValue.value = id;
}

const removeTab = (id: string) => {
  const tabs = editableTabs.value
  let activeName = editableTabsValue.value
  if (activeName === id) {
    tabs.forEach((tab, index) => {
      if (tab.name === id) {
        const nextTab = tabs[index + 1] || tabs[index - 1]
        if (nextTab) {
          activeName = nextTab.name
          const code = sideRef.value.getCode(activeName);
          cmRef.value.setCode(code.code, code.type);
        }
      }
    })
  }

  editableTabsValue.value = activeName
  editableTabs.value = tabs.filter((tab) => tab.name !== id)
  if (editableTabs.value.length == 0)
    editableTabsValue.value = '-1';
}

const clickTab = (pane: TabsPaneContext, ev: Event) => {
  const code = sideRef.value.getCode(pane.props.name);
  cmRef.value.setCode(code.code, code.type);
}

const rename = (id: string, new_name: string) => {
  const tabs = editableTabs.value
  tabs.forEach((tab, index) => {
    if (tab.name === id) {
      tab.title = new_name;
    }
  })
}
const setFileContext = (name: string, id: string, code: string | undefined, type: FileType) => {
  cmRef.value.setCode(code, type);
  const tabs = editableTabs.value
  let flag = false;
  tabs.forEach((tab, index) => {
    if (tab.name == id) {
      editableTabsValue.value = id;
      flag = true;
    }
  })
  if (!flag) {
    addTab(name, id);
  }
}

const onCodeChange = (value: string) => {
  sideRef.value.setCode(editableTabsValue.value, value);

}

const saveZIP = async () => {
  ziper.setProjectName(sideRef.value.getProjectName());
  ziper.updateProject(sideRef.value.getData());
  const param: any = await ziper.uploadFile();
  if (param != undefined)
    upload(param);
}

//组织中心
const invitationCode = ref('');
interface orgIF {
  id: string,
  lesson: string,
  teacher: string
}
const organizationData = ref<orgIF[]>([])
const addOrganization = () => {
  let param = new FormData();
  param.append('code', invitationCode.value);
  request('weblab/organization/getOrgMessageByCode', param)
    .then(res => {
      console.log(res);
      if (res.data.msg == 'success') {
        const data = res.data.pkg;
        if (data != undefined && data != null) {
          ElMessageBox.alert(`是否加入课程${data.name},教师${data.founderName}`, '加入班级', {
            confirmButtonText: 'OK',
            cancelButtonText: 'Cancel',
          })
            .then(() => {
              let joinParam = new FormData();
              joinParam.append('orgId', data.id);
              request('weblab/organization/confirmJoinOrg', joinParam)
                .then(res => {
                  if (res.data.msg == 'success') {
                    organizationData.value.push({
                      id: data.id,
                      lesson: data.name,
                      teacher: data.founderName
                    })
                  }
                })
            })
        }

      } else if (res.data.msg == 'Organization not found') {

        ElMessage({
          showClose: true,
          message: '未找到该课程',
          type: 'error',
          center: true,
          grouping: true
        })
      }
    })
    .catch((error) => {
      console.log(error)
      ElMessage({
        showClose: true,
        message: '未找到该课程',
        type: 'error',
        center: true,
        grouping: true
      })
    })

}
const deleteOrganization = (val: orgIF) => {
  ElMessageBox.confirm('将删除该课程,继续?', 'Warning',
    {
      confirmButtonText: 'OK',
      cancelButtonText: 'Cancel',
      type: 'warning',
    })
    .then(() => {
      console.log(val);
      let param = new FormData();
      param.append('orgId', val.id);
      request('weblab/organization/confirmQuitOrg', param)
        .then(res => {
          console.log(res);
          if (res.data.msg == 'success') {
            const targetIdx = organizationData.value.findIndex((d) => d == val);
            organizationData.value.splice(targetIdx, 1);
          }
        })

    })
}


//项目中心

//课程任务
const showHWDetail = ref(false);
const choseProjectFormVisible = ref(false);
const choseProjectProps = {
  label: 'projectName',
  value: 'id'
}
const choseProject = ref('');
const choseLab = ref<hwDataIF>({
  id: '',
  lesson: '',
  mission: '',
  date: '',
  project: [],
});
const homeworkTableData = ref<hwDataIF[]>([])
//查看作业详情
const checkHWDetail = (hw: hwDataIF) => {
  if (hw.project.length == 0) {
    let param = new FormData();
    param.append('labId', hw.id);
    param.append('userId',store.getUserId);
    request('weblab/lab/getUserProjectList', param)
      .then(res => {
        console.log(res);
        if (res.data.msg == 'success') {
          const data=res.data.pkg;
          for(let d of data){
            const proIdx=projectData.value.findIndex(x=>x.id==d.id);
            hw.project.push(projectData.value[proIdx]);
          }
        }

      })
  }

  showHWDetail.value = true;
  choseLab.value = hw;
}
//提交项目
const submitProject = () => {
  console.log(choseProject.value);
  let param = new FormData();
  param.append('labId', choseLab.value!.id);
  param.append('projectId', choseProject.value);
  request('weblab/lab/addProjectIntoLab', param)
    .then(res => {
      console.log(res);
      if (res.data.msg == 'success') {
        const proIdx = projectData.value.findIndex(x => x.id == choseProject.value);
        choseLab.value?.project.push(projectData.value[proIdx]);
        console.log(homeworkTableData.value)
        choseProjectFormVisible.value = false
      }
    })

}

//课程通知
interface noticetDataIF {
  className: string,
  date: string,
  detail: string,
  title: string
}
const noticeTableData = ref<noticetDataIF[]>([]);
//查看通知详情
const checkNoticeDetail = (title: string, detail: string) => {
  ElMessageBox.alert(detail, title, {
    confirmButtonText: 'OK',
  })
    .catch(err => {

    })
}

//我的项目
const showDetail = ref(false);
const activeProjectTabName = ref('1');
const createProjectFormVisible = ref(false);
const setProjectFormVisible = ref(false);

const createProjectForm = reactive({
  name: '',
  description: ''
})

const setProjectForm = reactive({
  psm: '',
  scm: '',
  scmver:'',
  scmver1:'',
  scmverdet:'',
  scmverdet1:'',
  mg:'',
  ch:'',
  scmrout:'',
  scmrout1:'',
  rout:'',
  git:'',
  gitr:'',

})

const projectTableRef = ref<InstanceType<typeof ElTable>>()
const selectedProject = ref<projectDataIF[]>();
const selectedProjectDetail = ref<projectDetailIF>({
  outputlog: '',
  ws: undefined,
  wsUrl: '',
  introduction: '',
  files: []
});
//任务数据
interface hwDataIF {
  id: string,
  lesson: string,
  mission: string,
  date: string,
  project: projectDataIF[]
}

//项目数据
//项目详情内容
interface projectFilesIF {
  name: string,
  date: string,
  introduction: string
}
interface projectDetailIF {
  outputlog: string,
  ws: WebSocket | undefined,
  wsUrl: string,
  introduction: string,
  files: projectFilesIF[]
}
interface projectDataIF {
  id: string,
  projectName: string,
  introduction: string,
  date: string,
  detail: projectDetailIF,
  url: string
}
const projectData = ref<projectDataIF[]>([])


//编辑项目
const editProject = (data: projectDataIF) => {
  activeIndex.value = '4'
}
//查看项目详情
const showProjectDetail = (data: projectDataIF) => {
  const idx = projectData.value.findIndex(item => item == data);
  selectedProjectDetail.value = projectData.value[idx].detail;
  let param = new FormData();
  param.append('projectId', data.id);
  request('weblab/project/getProjectLogUrl', param)
    .then(res => {
      console.log(res);
      if (res.data.msg == 'success') {
        // selectedProjectDetail.value!.wsUrl = 'ws://127.0.0.1:8001'
        selectedProjectDetail.value!.wsUrl = res.data.pkg;

        console.log('创建ws')
        selectedProjectDetail.value!.ws = new WebSocket(selectedProjectDetail.value!.wsUrl);
        selectedProjectDetail.value!.ws.onmessage = onMsg;
        selectedProjectDetail.value!.ws.onopen = onOpen;

      }
    })
  showDetail.value = true;
}
const closeProjectDetail = () => {
  showDetail.value = false;
  selectedProjectDetail.value?.ws?.close();
}
//删除项目内容
const deleteProjecFolder = (index: number) => {
  ElMessageBox.confirm('将删除该文件,继续?', 'Warning',
    {
      confirmButtonText: 'OK',
      cancelButtonText: 'Cancel',
      type: 'warning',
    })
    .then(() => {
      selectedProjectDetail.value?.files.splice(index, 1);
    })
}
//添加项目
const addProject = () => {
  createProjectFormVisible.value = true;
}
const setProject = () => {
  setProjectFormVisible.value = true;
}
const confirmAddProject = () => {
  createProjectFormVisible.value = false;
  let param = new FormData();
  param.append('name', createProjectForm.name);
  param.append('description', createProjectForm.description);
  request('weblab/project/createProject', param)
    .then(res => {
      if (res.data.msg == 'success') {
        const data = res.data.pkg;
        projectData.value.push({
          id: data.id,
          projectName: data.name,
          introduction: data.description,
          date: getFormDate(),
          url: data.url,
          detail: {
            ws: undefined,
            wsUrl: '',
            outputlog: '',
            introduction: '',
            files: []
          }
        })
      }
    })
    .catch(error => {
      console.log(error);
    })

}
//删除项目
const deleteProject = () => {
  ElMessageBox.confirm('将删除选中的项目,继续?', 'Warning',
    {
      confirmButtonText: 'OK',
      cancelButtonText: 'Cancel',
      type: 'warning',
    })
    .then(() => {

      // projectData.value = projectData.value.filter((x) => !selectedProject.value!.some((item) => x.projectName === item.projectName));
      for (let data of selectedProject.value!) {
        let param = new FormData();
        param.append('projectId', data.id);
        request('/weblab/project/deleteProjectByProjectId', param)
          .then(res => {
            console.log(res);
            if (res.data.msg == 'success') {
              projectData.value = projectData.value.filter(item => item !== data);
            }
          })
          .catch(error => {
            console.log(error);
          })
      }
      projectTableRef.value!.clearSelection();

    })

}
//下载项目
const downloadProject = () => {

  projectTableRef.value!.clearSelection();
}
const projectData1 = [
  {
    project: '2016-05-03',

  },]

//获取初始信息
request('/weblab/user/getUserWithInfo', undefined, store.getToken)
  .then(async res => {
    if (res.data.msg == 'success') {

      const data = res.data.pkg;
      console.log(data)
      if (data.headImg != null){
        avatarUrl.value = data.headImg;
        tmRef.value.onAvatarUrlChange(avatarUrl.value);
      }
      store.setUserId(data.userId);

      let orgParam = new FormData();
      orgParam.append('userId', store.getUserId);
      const orgRes = await request('weblab/organization/getOrgListByUserId', orgParam)

      console.log(orgRes);
      if (orgRes.data.msg == 'success') {
        const orgData = orgRes.data.pkg;
        for (let d of orgData) {
          organizationData.value.push({
            id: d.id,
            lesson: d.name,
            teacher: d.founderName
          })
          let labParam = new FormData();
          labParam.append('orgId', d.id);
          const labRes = await request('weblab/lab/getOrgLabList', labParam);
          if (labRes.data.msg == 'success') {
            console.log(labRes);
            for (let lab of labRes.data.pkg) {
              homeworkTableData.value.push({
                id: lab.id,
                lesson: d.name,
                mission: lab.description,
                date: lab.endTime,
                project: []
              })
            }

          }
        }

      }

      request('/weblab/project/getProjectList', undefined)
        .then(projectRes => {
          if (projectRes.data.msg == 'success') {
            const proData = projectRes.data.pkg;
            for (let item of proData) {
              projectData.value.push({
                id: item.id,
                projectName: item.name,
                introduction: item.description,
                date: item.lastModifyTime.slice(0, 10),
                url: item.url,
                detail: {
                  ws: undefined,
                  wsUrl: '',
                  outputlog: '',
                  introduction: '',
                  files: []
                }
              })
            }
          }
        })

    }
  })
const handleProjectTabClick = (pane: TabsPaneContext, ev: Event) => {
  if (pane.paneName == '2' && noticeTableData.value.length == 0) {
    for (let org of organizationData.value) {
      let param = new FormData();
      param.append('orgId', org.id);
      request('weblab/message/getOrgMessageList', param)
        .then(res => {
          console.log(res);
          if (res.data.msg == 'success') {
            const msgData = res.data.pkg;
            for (let msg of msgData) {
              noticeTableData.value.push({
                className: org.lesson,
                date: msg.createTime.slice(0, 10),
                detail: msg.description,
                title: msg.name
              })
            }
          }
        })
    }
  } else if (pane.paneName == '3' && projectData.value.length == 0) {


  }
}

const handleProjectSelectionChange = (val: projectDataIF[]) => {
  selectedProject.value = val;
}


//websocket
const onMsg = (data: any) => {
  selectedProjectDetail.value!.outputlog += data.data + '\n';
}
const onOpen = () => {
  // selectedProjectDetail.value?.ws?.send("what`s your name?");
  console.log('连接建立');
}
</script>

<style>
.grid-content {
  border-radius: 4px;
  min-height: 10px;
}

.demo-tabs>.el-tabs__content {
  padding: 0px;
  color: #6b778c;
  font-size: 32px;
  font-weight: 600;
}

.title {
  margin: 0px auto 40px auto;
  text-align: center;
  color: #505458;
}

.demo-radius {
  height: 800px;
  width: 90%;
  border: 1px solid #b7b7ba;
  border-radius: 10px;
  margin-top: 20px;
}

.example-demonstration {
  margin: 1rem;
}

.dialog-footer button:first-child {
  margin-right: 10px;
}


</style>

layout/topmenu.vue

<template>
  <el-menu :default-active="$props.activeIndex" class="el-menu-demo" mode="horizontal" @select="handleSelect">
    <el-menu-item index="1" disabled>WebLab</el-menu-item>
    <el-menu-item index="2">项目中心</el-menu-item>
    <el-menu-item index="3">上传中心</el-menu-item>
    <el-menu-item index="4">市场中心</el-menu-item>
<!--    <el-menu-item index="4">编辑中心</el-menu-item>-->
    <!--    <el-sub-menu index="4">-->
    <!--      <template #title>待补充</template>-->
    <!--      <el-menu-item index="4-1">item one</el-menu-item>-->
    <!--      <el-menu-item index="4-2">item two</el-menu-item>-->
    <!--      <el-menu-item index="4-3">item three</el-menu-item>-->
    <!--      <el-sub-menu index="4-4">-->
    <!--        <template #title>item four</template>-->
    <!--        <el-menu-item index="4-4-1">item one</el-menu-item>-->
    <!--        <el-menu-item index="4-4-2">item two</el-menu-item>-->
    <!--        <el-menu-item index="4-4-3">item three</el-menu-item>-->
    <!--      </el-sub-menu>-->
    <!--    </el-sub-menu>-->
    <el-menu-item index="5">组织中心</el-menu-item>
    <el-sub-menu index="6" style="position: absolute;right:15px;">
      <template #title>
        <div class="block">
          <el-avatar :size="45" :icon="UserFilled" fit :src="avatarUrl" />
        </div>
      </template>
      <el-menu-item index="5-1" @click="personal()">个人资料更新</el-menu-item>
      <el-menu-item index="5-2" @click="updatePassword()">更新密码</el-menu-item>
      <!-- <el-menu-item index="5-2">item two</el-menu-item> -->
      <el-menu-item index="5-3" @click="logOut">登出</el-menu-item>
    </el-sub-menu>
  </el-menu>
  <div class="h-6"></div>
</template>

<script lang="ts">

import { UserFilled } from '@element-plus/icons-vue'
import { ref, defineComponent, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { useRouter } from "vue-router"
import { useLoginStore } from '@/stores/store';
import { request } from '@/network/request';

export default defineComponent({
  props: {
    activeIndex: String,
    avatarUrl: String
  },
  emits: ['onIndexChange'],
  setup(props, context) {

    const store = useLoginStore();
    const router = useRouter();
    // const activeIndex = ref(props.activeIndex);
    const activeIndex2 = ref('2');
    const avatarUrl = ref(props.avatarUrl);
    const onAvatarUrlChange = (url: string) => {
      avatarUrl.value = url;
    }
    context.expose({ onAvatarUrlChange })


    const handleSelect = (key: string, keyPath: string[]) => {
      // activeIndex.value = key;
      context.emit('onIndexChange', key);
    }
    function logOut() {
      ElMessageBox.confirm(
        '是否确认退出?',
        '退出提示',
        {
          confirmButtonText: '确认',
          cancelButtonText: '取消',
        }
      )
        .then(() => {
          // store.userLogout();
          // router.push({ path: '/' });


          let param = new FormData();
          request('/weblab/user/logout', param, store.getToken)
            .then(res => {
              store.userLogout();
              router.push({ path: '/' });
              // if (res.status == 200 && res.data.msg == 'success') {

              // }
            })
            .catch(error => {
              console.log(error);
            })

        })
        .catch(() => {
          //点击取消
          // activeIndex.value = '2';
          context.emit('onIndexChange', '2');
        })
    }
    function updatePassword() {
      router.push({ path: '/update_password' });
    }

    function personal() {
      router.push({ path: '/personal' });
    }

    return {
      // activeIndex,
      activeIndex2,
      handleSelect,
      logOut,
      updatePassword,
      UserFilled,
      personal,
      avatarUrl
    }
  },
});

</script>
<style>
</style>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值