| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269 |
- <template>
- <el-row style="display: flex;flex-direction: row;align-items: center;margin-bottom: 10px;color: #333333">
- <h4>项目概览</h4>
- </el-row>
- <el-card shadow="never" class='description-card'>
- <el-row>
- <el-col :span="12">
- <div class="description-card-text" style="font-size: 18px;font-weight: bold">{{selectedProject.name}}</div>
- <div class="description-card-text">项目地址:
- <span>
- <el-link
- target="_blank"
- type="primary"
- @click.prevent="copy(selectedProject.gitRemoteUrl)"
- >
- {{selectedProject.gitRemoteUrl}}
- </el-link>
- </span>
- </div>
- <div class="description-card-text">项目介绍:
- <span>{{selectedProject.description}}</span>
- </div>
- <div class="description-card-text">项目成员:
- <span>
- <el-tag v-for="item in projectMembers" :key="item.id" style="margin: 0 5px;">
- {{item.username}}
- </el-tag>
- </span>
- </div>
- </el-col>
- <el-col :span="6">
- <div style="height: 140px;width: 140px" id="requirement_pie"></div>
- </el-col>
- <el-col :span="6">
- <div style="height: 140px;width: 140px" id="bug_pie"></div>
- </el-col>
- </el-row>
- </el-card>
- <el-row style="display: flex;flex-direction: row;align-items: center;margin-bottom: 10px;color: #333333">
- <h4>项目规划</h4>
- </el-row>
- <Tree
- :data="requirements"
- v-loading="loading"
- @change="handleTreeChange"
- @nodeClick="handleNodeClick"
- ref="tree"
- ></Tree>
- <RequirementDrawer
- ref="drawer"
- v-bind="requirementInDrawer"
- @change="handleDrawerContentChange"
- @requirement-update="getTreeData"
- ></RequirementDrawer>
- </template>
- <script>
- import Tree from '@/components/Tree.vue';
- import * as echarts from 'echarts';
- import { BugListAPI, RequirementAPI } from '@/api';
- import RequirementDrawer from '@/components/RequirementDrawer.vue';
- import { copy } from '@/utils/clipboard';
- import { useProjectList } from '../../composable/useProject';
- export default {
- name: 'Schedule',
- components: { RequirementDrawer, Tree },
- setup() {
- const { selectedProject } = useProjectList();
- return {
- selectedProject,
- };
- },
- data() {
- return {
- loading: false,
- requirements: [],
- showRequirementDrawer: false,
- addRequirementDrawer: false,
- parentOfAddingRequirement: null,
- requirementInDrawer: {},
- projectMembers: [],
- };
- },
- computed: {
- projectId() {
- return this.$route.params.projectId;
- },
- },
- watch: {
- $route: {
- async handler() {
- this.projectMembers = this.$store.state.workspace.currentProjectMembers;
- await this.getTreeData();
- this.drawChart();
- },
- immediate: true,
- },
- },
- methods: {
- copy,
- async getTreeData() {
- this.loading = true;
- try {
- this.requirements = this.addChild2Node(await RequirementAPI.getTreeNodesByProjectId(this.projectId));
- } catch (e) {
- console.error(e);
- }
- this.loading = false;
- },
- addChild2Node(array) {
- const nodeMap = new Map();
- array.forEach((item) => nodeMap.set(item.id, item));
- array.forEach((item) => {
- if (item.parentId) {
- const tempParent = nodeMap.get(item.parentId);
- if (!tempParent.childs) {
- tempParent.childs = [];
- }
- tempParent.childs.push(item);
- }
- });
- // 返回前序遍历的列表
- const newArr = [];
- const preOrder = (node) => {
- newArr.push(node);
- if (!node.childs || node.childs.length === 0) return;
- node.childs.sort((node1, node2) => node1.id - node2.id);
- newArr.concat(node.childs);
- node.childs.forEach((_node) => preOrder(_node));
- };
- const root = array.find((item) => !item.parentId);
- preOrder(root);
- return newArr;
- },
- async handleTreeChange(msg) {
- const { type, id } = msg;
- await RequirementAPI[type](id);
- await this.getTreeData();
- },
- handleNodeClick(id) {
- this.$refs.drawer.show();
- this.requirementInDrawer = Array.prototype.find.call(this.requirements, (requirement) => requirement.id === id);
- },
- handleDrawerContentChange(id) {
- this.requirementInDrawer = Array.prototype.find.call(this.requirements, (requirement) => requirement.id === id);
- },
- async drawChart() {
- const bugList = await BugListAPI.getBugListByProjectId(this.projectId);
- const requirementsValuesMap = new Map();
- const requirementsValues = [];
- const bugListValuesMap = new Map();
- const bugListValues = [];
- this.requirements.forEach((item) => {
- if (item.type === '任务') {
- if (!requirementsValuesMap.get(item.state)) requirementsValuesMap.set(item.state, 0);
- requirementsValuesMap.set(item.state, requirementsValuesMap.get(item.state) + 1);
- }
- });
- requirementsValuesMap.forEach((value, key) => {
- requirementsValues.push(
- { value, name: key },
- );
- });
- bugList.forEach((item) => {
- if (!bugListValuesMap.get(item.state)) bugListValuesMap.set(item.state, 0);
- bugListValuesMap.set(item.state, bugListValuesMap.get(item.state) + 1);
- });
- bugListValuesMap.forEach((value, key) => {
- bugListValues.push(
- { value, name: key },
- );
- });
- if (bugListValues.length === 0) {
- bugListValues.push({
- name: '无记录', value: 0,
- });
- }
- if (requirementsValues.length === 0) {
- requirementsValues.push({
- name: '无记录', value: 0,
- });
- }
- const requirementPie = echarts.init(document.getElementById('requirement_pie'));
- requirementPie.setOption({
- title: {
- text: '任务完成情况',
- left: 'center',
- textStyle: {
- fontSize: 12,
- },
- },
- tooltip: {
- trigger: 'item',
- },
- series: [
- {
- name: '任务情况',
- type: 'pie',
- radius: ['40%', '70%'],
- avoidLabelOverlap: false,
- label: {
- show: false,
- position: 'center',
- },
- emphasis: {
- label: {
- show: true,
- fontSize: '10',
- fontWeight: 'bold',
- },
- },
- labelLine: {
- show: false,
- },
- data: requirementsValues,
- },
- ],
- });
- const bugPie = echarts.init(document.getElementById('bug_pie'));
- bugPie.setOption({
- title: {
- text: 'Bug处理情况',
- left: 'center',
- textStyle: {
- fontSize: 12,
- },
- },
- tooltip: {
- trigger: 'item',
- },
- series: [
- {
- name: 'Bug情况',
- type: 'pie',
- radius: ['40%', '70%'],
- avoidLabelOverlap: false,
- label: {
- show: false,
- position: 'center',
- },
- emphasis: {
- label: {
- show: true,
- fontSize: '10',
- fontWeight: 'bold',
- },
- },
- labelLine: {
- show: false,
- },
- data: bugListValues,
- },
- ],
- });
- },
- },
- };
- </script>
- <style>
- .description-card{
- margin: 10px 0;
- }
- .description-card-text{
- margin: 5px 0;
- }
- </style>
|