结对第二次作业——编程实现

042201126杨世铭 2024-09-30 22:51:43

 

这个作业属于哪个课程https://bbs.csdn.net/forums/2401_CS_SE_FZU
这个作业要求在哪里https://bbs.csdn.net/topics/619333839
结对学号052207115 042201126
这个作业的目标基于 Web 技术的原型实现、Git 协作、项目部署
其他参考文献

 

目录

 

 

1. 项目地址

2. PSP表格

3. 部署地址

4. 成果展示

4.1 首页

4.2 奖牌榜

4.3 每日赛程

4.4 对阵图

4.5 了解更多

5. 讨论过程

6. 设计与实现

6.1功能结构图

6.2分析过程

7. 关键代码与思路说明

7.0代码说明

7.1首页

7.2奖牌榜

7.3每日赛程

7.4对阵图

 7.5了解更多

8.组队的学习与反思

8.1 收获

8.2 队友评价

8.3 贡献度


 

1. 项目地址

项目地址

codestyle文档地址

2. PSP表格

PSPPersonal Software Process Stages预估耗时(分钟)实际耗时(分钟)
Planning计划3030
• Estimate• 估计这个任务需要多少时间3030
Development开发900960
• Analysis• 需求分析(包括学习新技术)6080
• Design Spec• 生成设计文档6070
• Design Review• 设计复审3020
• Coding Standard• 代码规范(为目前的开发制定合适的规范)6080
• Design• 具体设计160160
• Coding• 具体编码400500
• Code Review• 代码复审3030
• Test• 测试(自我测试,修改代码,提交修改)140140
Reporting报告180210
• Test Report• 测试报告6070
• Size Measurement• 计算工作量3040
• Postmortem & Process Improvement Plan• 事后总结, 并提出过程改进计划60100
 合计11201320

3. 部署地址

项目地址

4. 成果展示

4.1 首页

四个主要页面在父组件,以切换页面,首页展示主题,链接了解更多模块

 

img

 

4.2 奖牌榜

展示国家、排名、奖牌数

 

img

 

 

img

 

4.3 每日赛程

选择日期部分可以选择奥运会时间之内的日期,下面是静态数据

 

img

 

 

img

 

4.4 对阵图

提供了button可以选择男女的比赛对阵表,同时做好高亮显示

 

img

 

 

img

 

 

img

 

 

img

 

 

img

 

4.5 了解更多

展示巴黎奥运会愿景

 

img

 

5. 讨论过程

​ 在为期三天的工作过程中,我们主要采取线上讨论的方式,由于时间紧迫,虽然我们组能做后端,但是我们刚刚接触vue的使用,所以我们花了大量时间在学习前端三件套基础和Vue代码框架上,

内容分配:

​ 欧阳开源负责项目框架确立、基本的代码设计,首页、每日赛程、对阵表等页面的前端实现

​ 杨世铭同学负责功能设计、项目部署、对阵表页面的前端实现、细节优化等

 

img

 

 

img

 

 

img

 

 

img

 

6. 设计与实现

6.1功能结构图

 

img

 

6.2分析过程

​ 要求我们对在上次的原型设计进行实现和扩充,通过前端代码实现网页。与上一次结对任务相比,我们缺少了ui界面,必须通过代码,借助Go-Live不断调整代码。需要处理大量的数据的同时,还要尽可能考虑用户体验,保证用户能够在不同的平台浏览网页。在交互友好性方面,我们需要为每个页面设计足够多的跳转入口,防止用户对于网页功能的使用有迷惑的地方。我们决定使用vue-cli来构建代码框架,保证目录结构清晰,是我们的任务专注于逻辑开发和视图设计上。

7. 关键代码与思路说明

7.0代码说明

​ 本次项目采用Vue2框架,辅助的工具有element-ui,vue router3

7.1首页

<template>
  <div class="background">
    <div class="content">
      <h1>2024 夏季巴黎奥运会</h1>
      <router-link to="/GetMore">
        <p>了解更多</p>
      </router-link>
 
 
    </div>
  </div>
</template>
 
<style scoped>
/* 背景容器 */
.background {
  background-image: url('../assets/more-background-pic.jpg');
  background-size: cover;
  background-position: center;
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
  background-repeat: no-repeat;
  width: 100vw;
  height: 100vh;
}
 
/* 页面内容的样式 */
.content {
  background-color: rgba(255, 255, 255, 0.7);
  padding: 20px;
  border-radius: 10px;
  text-align: center;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
 
h1 {
  font-size: 36px;
  color: #333;
}
 
p {
  font-size: 18px;
  color: #555;
  text-decoration: none;
  cursor: pointer;
}
 
/* 鼠标悬停时添加下划线 */
p:hover {
  text-decoration: underline;
}
</style>
 
<script>
// import router from '@/router';
 
export default {
  name: "OlympicPage",
};
</script>

 

7.2奖牌榜

读取json里的奖牌榜数据,获取数据

<template>
    <div class="Total">
        <div class="myDiv">
            <div class="medaltext">
                奖牌榜
            </div>
            <img src="../assets/olympicpic.png" alt="">
        </div>
        <!-- 将表格容器设为居中对齐 -->
        <div class="table-container">
            <el-table :data="tableData" style="width: 100%">
                <el-table-column prop="rank" label="排名" width="180"></el-table-column>
                <el-table-column prop="countryname" label="国家" width="180"></el-table-column>
                <el-table-column prop="gold" label="金牌"></el-table-column>
                <el-table-column prop="silver" label="银牌"></el-table-column>
                <el-table-column prop="bronze" label="铜牌"></el-table-column>
                <el-table-column prop="count" label="总牌数"></el-table-column>
            </el-table>
        </div>
    </div>
</template>
 
<style>
.medaltext {
    font-size: 50px;
    font-weight: 1000;
    color: white;
    text-align: center;
    /* 文本居中 */
}
 
.Total {
    background-color: #cfcfd3;
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
}
 
.myDiv {
    background: linear-gradient(to bottom, #5BC2F5, #1F5895);
    /* 设置背景颜色 */
    width: 100%;
    height: 300px;
    min-height: calc(100% - 100px);
    /* 父元素的高度至少为视窗高度减去100px */
    position: relative;
}
 
/* 表格容器居中 */
.table-container {
    display: flex;
    justify-content: center;
    width: 60%;
    margin: 0 auto;
}
</style>
 
 
 
 
<script>
import totalData from '../data/total.json';
 
export default {
    data() {
        return {
            tableData: []
        };
    },
    mounted() {
        this.loadTableData();
    },
    methods: {
        loadTableData() {
            // 直接使用引入的 JSON 数据
            this.tableData = totalData.data.medalsList;
        }
    },
}
</script>

7.3每日赛程

<template>
    <div>
        <div class="myDiv">
            <div class="medaltext">每日赛程</div>
            <img src="../assets/olympicpic.png" alt="">
 
            <!-- 显示从 DateTimePicker 子组件中传递过来的 selectedDate -->
            <h1>{{ selectedDate }}</h1>
        </div>
        <br><br>
 
        <!-- 监听子组件传递的日期变化 -->
        <DateTimePicker @date-changed="handleDateChange" />
 
        <br><br>
        <DayMatch></DayMatch>
 
    </div>
</template>
 
<style scoped>
.myDiv {
    background: linear-gradient(to bottom, #5BC2F5, #1F5895);
    /* 设置背景颜色 */
    width: 100%;
    height: 300px;
    min-height: calc(100% - 100px);
    /* 父元素的高度至少为视窗高度减去100px */
    position: relative;
}
</style>
 
 
<script>
import DateTimePicker from './DateTimePicker.vue';
import DayMatch from './DayMatch.vue';
 
export default {
    components: {
        DateTimePicker,
        DayMatch
    },
    data() {
        return {
            selectedDate: '' // 用于存储从 DateTimePicker 接收的日期
        };
    },
    methods: {
        handleDateChange(date) {
            // 将日期 "09-11" 拆解为月和日
            const [month, day] = date.split('-').map(Number);
 
            // 创建合法日期范围
            const startDate = new Date(2024, 6, 24); // 7月24日
            const endDate = new Date(2024, 7, 11); // 8月11日
 
            // 当前选择的日期
            const selectedDate = new Date(2024, month - 1, day); // 注意 month-1 因为 JavaScript 中的月份从0开始
 
            // 检查选择的日期是否在有效范围内
            if (selectedDate >= startDate && selectedDate <= endDate) {
                this.selectedDate = date; // 更新 selectedDate 的值
            } else {
                alert("请输入正确时间"); // 提示用户输入正确时间
            }
        }
    }
};
</script>

7.4对阵图

父组件

<template>
    <div>
        <div class="myDiv">
            <div class="medaltext">
                对阵表
            </div>
            <img src="../assets/olympicpic.png" alt="Olympic Image">
        </div>
        <br><br>
 
        <!-- 选择性别的按钮 -->
        <el-row>
            <el-button type="warning" round @click="selectGender('male')"
                :plain="selectedGender !== 'male'">男</el-button>
 
            <el-button type="warning" round @click="selectGender('female')"
                :plain="selectedGender !== 'female'">女</el-button>
        </el-row>
 
        <br><br>
 
        <!-- 根据性别显示不同的组件 -->
        <vs-list-component1 v-if="selectedGender === 'male'"></vs-list-component1>
        <vs-list-component2 v-if="selectedGender === 'female'"></vs-list-component2>
    </div>
</template>
 
<script>
import VsListComponent1 from './vsListComponent1.vue';
import VsListComponent2 from './vsListComponent2.vue';
 
export default {
    components: {
        VsListComponent1,
        VsListComponent2
    },
    data() {
        return {
            selectedGender: 'male' // 默认显示男性的对阵表
        };
    },
    methods: {
        // 切换性别,显示不同的组件
        selectGender(gender) {
            this.selectedGender = gender;
        }
    }
};
</script>
 
<style scoped>
.myDiv {
    background: linear-gradient(to bottom, #5BC2F5, #1F5895);
    width: 100%;
    height: 300px;
    min-height: calc(100% - 100px);
    position: relative;
}
 
.medaltext {
    font-size: 50px;
    color: white;
    text-align: center;
}
</style>

子组件

<template>
  <div class="container">
    <div class="duizhenp">
      <p>1/4决赛</p>
      <p>半决赛</p>
      <p>决赛</p>
    </div>
    <div class="bracket">
      <div class="round quarterfinals">
        <div class="match-container" v-for="(match, index) in quarterFinals" :key="'qf' + index">
          <div class="match">
            <div class="team" :class="{ highlighted: isHighlighted(match.team1) }"
              @mouseover="highlightTeam(match.team1)" @mouseleave="clearHighlight">
              <span>{{ match.team1 }}</span>
              <span class="score">{{ match.score1 }}</span>
            </div>
            <div class="team" :class="{ highlighted: isHighlighted(match.team2) }"
              @mouseover="highlightTeam(match.team2)" @mouseleave="clearHighlight">
              <span>{{ match.team2 }}</span>
              <span class="score">{{ match.score2 }}</span>
            </div>
          </div>
          <img v-if="index % 2 === 0" class="connector quarter-connector" src="@/assets/线条.png" alt="线条" />
        </div>
      </div>
      <div class="round semifinals">
        <div class="match-container" v-for="(match, index) in semiFinals" :key="'sf' + index">
          <div class="match">
            <div class="team" :class="{ highlighted: isHighlighted(match.team1) }"
              @mouseover="highlightTeam(match.team1)" @mouseleave="clearHighlight">
              <span>{{ match.team1 }}</span>
              <span class="score">{{ match.score1 }}</span>
            </div>
            <div class="team" :class="{ highlighted: isHighlighted(match.team2) }"
              @mouseover="highlightTeam(match.team2)" @mouseleave="clearHighlight">
              <span>{{ match.team2 }}</span>
              <span class="score">{{ match.score2 }}</span>
            </div>
          </div>
          <img v-if="index % 2 === 0" class="connector semi-connector" src="@/assets/线条.png" alt="线条" />
        </div>
      </div>
      <div class="round finals">
        <div class="match-container">
          <div class="match">
            <div class="team" :class="{ highlighted: isHighlighted(finalMatch.team1) }"
              @mouseover="highlightTeam(finalMatch.team1)" @mouseleave="clearHighlight">
              <span>{{ finalMatch.team1 }}</span>
              <span class="score">{{ finalMatch.score1 }}</span>
            </div>
            <div class="team" :class="{ highlighted: isHighlighted(finalMatch.team2) }"
              @mouseover="highlightTeam(finalMatch.team2)" @mouseleave="clearHighlight">
              <span>{{ finalMatch.team2 }}</span>
              <span class="score">{{ finalMatch.score2 }}</span>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
 
<script>
export default {
  data() {
    return {
      highlightedTeam: '', // 存储当前高亮的国家
      // 对阵数据
      quarterFinals: [
        { team1: '法国', score1: 1, team2: '阿根廷', score2: 0 },
        { team1: '埃及', score1: 1, team2: '巴拉圭', score2: 4 },
        { team1: '摩洛哥', score1: 3, team2: '美国', score2: 1 },
        { team1: '日本', score1: 0, team2: '西班牙', score2: 3 },
      ],
      semiFinals: [
        { team1: '法国', score1: 3, team2: '巴拉圭', score2: 1 },
        { team1: '摩洛哥', score1: 1, team2: '西班牙', score2: 2 },
      ],
      finalMatch: {
        team1: '法国',
        score1: 3,
        team2: '西班牙',
        score2: 5,
      },
    };
  },
  methods: {
    // 判断是否高亮
    isHighlighted(team) {
      return this.highlightedTeam === team;
    },
    // 鼠标悬停时高亮指定队伍
    highlightTeam(team) {
      this.highlightedTeam = team;
    },
    // 清除高亮
    clearHighlight() {
      this.highlightedTeam = '';
    },
  },
};
</script>
 
<style scoped>
.container {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 2vw;
  background-color: #f2f2f2;
  width: 100%;
  box-sizing: border-box;
}
 
.duizhenp {
  display: flex;
  justify-content: space-around;
  width: 100%;
  background-color: #444;
  color: white;
  padding: 1vw;
  margin-bottom: 2vw;
}
 
.bracket {
  display: flex;
  justify-content: space-between;
  width: 100%;
  position: relative;
}
 
.round {
  display: flex;
  flex-direction: column;
  justify-content: space-around;
  flex: 1;
}
 
.match-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin: 1vw 0;
  position: relative;
}
 
.match {
  background-color: white;
  border: 1px solid #444;
  padding: 1vw;
  width: 90%;
  max-width: 200px;
  z-index: 1;
}
 
.team {
  display: flex;
  justify-content: space-between;
  padding: 0.5vw;
}
 
.score {
  font-weight: bold;
}
 
.highlighted {
  background-color: #f5d04c;
  color: #000;
}
 
.connector {
  position: absolute;
  z-index: 0;
}
 
.quarter-connector {
  width: 10%;
  height: auto;
  top: 125%;
  left: 100%;
  transform: translateY(-50%);
}
 
.semi-connector {
  width: 10%;
  height: auto;
  top: 185%;
  left: 100%;
  transform: translateY(-50%);
}
 
@media (max-width: 768px) {
  .bracket {
    flex-direction: column;
  }
 
  .connector {
    display: none;
  }
 
  .round {
    width: 100%;
  }
}
</style>

 7.5了解更多

<template>
    <div class="background">
 
 
        <div class="content">
 
            <h1>巴黎2024愿景</h1>
 
            <p>2024年巴黎奥运会将会以一种独特的国际庆典精神展现奥林匹克主义的新愿景。</p>
            <p>我们将会把世界上最具灵感城市之一的巴黎打造成对运动员而言的一个难忘舞台、一个真正的全球平台来宣传他们以及他们身上那些令人难以置信的故事。</p>
            <p>我们将与整个奥林匹克大家庭合作,证明在经历了一个极具挑战的时期之后,体育比以往任何时候都更有助于创造一个更美好的世界。</p>
            <p>我们的办赛规划中一大特色就是办赛场馆的95%为现有场馆和临时场馆。每一个场馆都有各自明确的传承意义,与城市的长期发展规划相一致。</p>
            <p>运动庆典将会沿塞纳河延伸开来。让庆典氛围从距离巴黎市中心只需15分钟车程的全新奥运村蔓延至巴黎市中心地标,如埃菲尔铁塔以及大皇宫。</p>
            <p>几百年来,巴黎一直对来自世界各地的人们敞开大门,其中包括包括奥林匹克运动的先驱们。双方相互合作、相互激励、塑造理念、开创未来。</p>
            <p>2024年,我们将在皮埃尔·德·顾拜旦第一次设想体育团结世界可能性的城市举办一场盛大而有意义的体育盛会,这将在体育史上树立一个新的里程碑。</p>
 
        </div>
    </div>
</template>
 
<style scoped>
/* 背景容器 */
.background {
    background-image: url('../assets/background-pic.png');
    background-size: cover;
    background-position: center;
    position: relative;
    display: flex;
    justify-content: center;
    align-items: center;
    background-repeat: no-repeat;
    width: 100vw;
    height: 100vh;
}
 
/* 页面内容的样式 */
 
.content {
    background-color: rgba(255, 255, 255, 0.7);
    padding: 20px;
    border-radius: 10px;
    text-align: center;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
 
h1 {
    font-size: 36px;
    color: #333;
}
</style>
 
<script>
export default {
    name: "OlympicPage",
};
</script>

8.组队的学习与反思

8.1 收获

  • Vue 的组件化开发
    Vue 的组件化开发模式让我对代码的可维护性和复用性有了更深的理解。将页面拆分成独立的组件,不仅简化了开发流程,也使得团队协作更加高效。特别是当我在多个页面重复使用同一个组件时,能感受到组件复用的好处。

  • Element-UI 提供的便捷性
    Element-UI 作为一个开源的 UI 组件库,极大地提高了开发效率。它提供了丰富的表单、表格、弹窗等常用组件,使得 UI 界面的开发更加简单直接。不需要从零开始设计 UI,大大减少了样式和交互上的工作量。

  • Vue-Router 的应用
    在项目中,我使用 Vue-Router 实现了页面间的导航功能。通过路由跳转管理不同页面之间的逻辑,让整个应用的逻辑结构更加清晰。同时,利用路由守卫可以轻松实现权限控制,这在实际项目中非常实用。

8.2 队友评价

  • 052207115欧阳开源对042201126杨世铭的评价

跟杨世铭同学协作能和我很好地互补,例如我还不是很熟悉的项目部署,有java后端经验的世铭同学能够非常熟练地部署在服务器上,能够快速理解项目需求,并高效完成任务。在团队协作方面,他非常乐于沟通,善于分享自己的见解和经验。在代码开发中,他保持了很高的代码质量,注重细节,特别是在处理复杂功能时,他总能找到简洁有效的解决方案。

  • 042201126杨世铭对052207115欧阳开源的评价

欧阳开源同学在此次合作中展现了出色的团队协作能力。他在项目中的细致和严谨确保了每个阶段的任务都能够高效、准时地完成。 尤其是在页面开发方面,他不仅完成了高质量的编码工作,还积极参与设计讨论,为项目提出了许多有建设性的优化建议。在结对作 业期间,他始终保持着开放的心态和积极的态度,持续推动项目向更高标准迈进。欧阳同学的出色表现与专业能力使他成为我们团 队中不可或缺的重要成员。

8.3 贡献度

052207115欧阳开源:50%
042201126杨世铭:50%

...全文
47 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复
AJAX——新手快车道 前言 AJAX是什么? 首先、AJAX是一种很酷的技术,一旦采用了AJAX,就能让你的Web页面, 你的网站,甚至连同你们公司,都变得很酷。在Web2.0的时代里,不使用一点 AJAX技术的网站,就会显得很老土,很落伍。 但是,这样的理解,其实是很肤浅的。仅仅是从一个外行,从一个使用者的 角度出发,来理解AJAX,就像我在本书的第一章AJAX我也行中那样,开发 出很愚蠢,甚至都没有资格被称之为AJAX应用的纯IE、XMLHTTP应用。 AJAX更酷的一点在于,对于传统的Web开发人员来说,AJAX所运用的, 是更加先进的,更加标准化的,更加和谐高效的,完整的Web开发技术体系。 遵循这样的体系开发Web应用,能让你的开发过程变得更加轻松,也能使你们 的开发团队,显得很酷。在Web2.0 的时代里,还在采用过时的技术来开发 Web,会显得很老土,很落伍。 AJAX的相关组成技术,每一个都已经出现了N年以上了,对这些技术的 组合运用,也远远早于AJAX这个名词出现之前。所以,我真正敬佩的,并非提 出 AJAX这个缩写的Jesse James Garrett。而是那些早在N年以前,就已经在探索、 实践的先行者,他们始终在追求的:是更好的用户体验,以及更好的开发体验。 这样的精神,才是最可宝贵的,也是最值得我们学习的。许多年过去以后,当我 们再回头来看当年的这些热门技术,也许早已经变得老土,变得落伍了。在这样 的历程中,哪些人会成长为高手?会成长为大师呢?就是那些永不满足,永远 在追求更好的用户体验,永远在追求更好的开发体验的人! 新手如何上路 软件开发这个领域,永远都在飞速发展,大家都必须不断的学习新的知识、 技能、框架、IDE、甚至新的语言。传说中的骨灰级高手们,就像传说中的大侠, 任何武器、哪怕是一块木头到了他们手里,也能发挥惊人的威力,人家练了几十 年的看家本领,他们随手使来,也竟然像是打娘胎里就开始练了一样。为什么? 就算不吹那么玄的,平常我们能够碰到的那些老手,在学新东西的时候, 也比那些新手学得更快,理解得更深,运用得更熟练。而新手们呢?往往就会漫 无头绪,焦头烂额,以一副张着茫然的大眼睛的经典表情,出现在各大论坛的 新手求助区里。他们欠缺的,究竟是什么呢?为什么老手学新东西,就没遇到那 么多困难呢? 泛泛地说,自然是经验上的欠缺。仔细地说来,又可以分为三个方面: 一、本质,一种技术与另一种技术之间,往往会有本质上的相通之处,当你 对一种技术的理解与思考越来越深入时,学习一种新技术也会更加容易。触类旁 通,举一反三的能力,就是来自于对于技术本质的追寻。 二、地图,本质上或多或少的相通,也提示着我们技术之间的相互关联,当 你了解的技术越多,了解得越是深入,在你的内心,就能建立起越发清晰的技 术地图。各种知识都有一个自然、合理的位置。那么当一个老手要学习一门新技术 的时候,他其实并非在探索一个全新的、未知的领域,而是有很多脉络可寻,也 很多已知可以帮助他们快速了解未知。 三、技巧,面对同样的未知,面对同样的难题,新手们一筹莫展,而老手们 却掌握着更多的技巧和手段,帮助他们试探可能性、缩小问题的范围、迅速定位 问题、不犯明显愚蠢的错误、甚至能够列举出更具命中力的搜索关键词,而这些 技巧,都帮助老手在前进的道路上,更少跌倒,即使跌倒,也能更快的爬起来。 作为一本写给新手的入门书籍,我们希望展现给读者的,是一个老手如何 学习新技术的过程。我们相信,这样的一个学习过程,对于新手来说,是更具有 价值的。 何谓快车道 必须老老实实的承认,我吹牛了!老手虽然会比新手学习得更快一些,但 是也同样会碰到麻烦,遇到障碍,感觉头痛。如果没有真正的专家的指导,我不 可能如此迅速地将AJAX掌握到目前这样的程度,要真是让我自学三个月,然 后就写出书来的话,那真是在骗钱了。 老手能够快速学习的另一个重要的诀窍是:认识很多牛人朋友 如果没有李锟与赵泽欣的专家级指导与帮助,如果没有与李锟AJAX结对 编程的体验,如果没有三个人在MSN上无数次的长聊,我想要在短期内建立起: 对于AJAX本质的理解; 对于整个AJAX以及相关技术地图的理解; 对于AJAX编程开发所需要的很多技巧、手段的掌握; 几乎是不可能的。 如果没有(N多需要感谢的人)的(N多方面的帮助),我们这本书,也 不可能以现在这样的深度,以(N个月)内完成的速度,送到读者的面前。 希望这本书,能够对大家快速学习AJAX,有所帮助。

109

社区成员

发帖
与我相关
我的任务
社区描述
202401_CS_SE_FZU
软件工程 高校
社区管理员
  • FZU_SE_TeacherL
  • 032002124林日臻
  • 助教姜词杰
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧