Browse Source

feat: "创建项目、删除项目、刷新页面数据清空问题"

master
xuesinan 4 years ago
parent
commit
2939c62083
  1. 25
      src/apis/index.js
  2. 112
      src/components/tall/center/ProjectDetail.vue
  3. 129
      src/components/tall/left/Index.vue
  4. 64
      src/components/tall/left/Projects.vue
  5. 18
      src/components/tall/top/Navbar.vue
  6. 8
      src/store/tall/projects/index.js
  7. 18
      src/views/detail/Test.vue

25
src/apis/index.js

@ -17,6 +17,12 @@ export const signIn = params => http.post(`${users}/signin`, params);
// 获取项目列表 // 获取项目列表
export const getProjects = (startTime, endTime) => http.post(`${tall}/project/query`, { param: { startTime, endTime } }); export const getProjects = (startTime, endTime) => http.post(`${tall}/project/query`, { param: { startTime, endTime } });
// 根据id获取项目信息
export const findProjectById = projectId => http.post(`${experiment}/project/findProjectById`, { param: { projectId } });
// 删除项目
export const delProject = projectId => http.post(`${tall}/project/deleteProject`, { param: { projectId } });
// 根据项目id查找角色 // 根据项目id查找角色
export const findShowRole = projectId => http.post(`${experiment}/role/show`, { param: { projectId } }); export const findShowRole = projectId => http.post(`${experiment}/role/show`, { param: { projectId } });
@ -37,3 +43,22 @@ export const saveTask = params => http.post(`${experiment}/task/save`, params);
// 查询子任务 // 查询子任务
export const findSonTask = params => http.post(`${experiment}/task/findSonTask`, params); export const findSonTask = params => http.post(`${experiment}/task/findSonTask`, params);
/**
* 导入wbs
* @param {object} e
*/
export const importWbs = async e => {
console.log('importWbs', e);
const file = e.target.files[0];
const param = new FormData();
param.append('file', file);
const config = { headers: { 'Content-Type': 'multipart/form-data' } };
// const result = await axios.post(`${projects}/wbs`, param, config);
console.log('importWbs11111', file, param);
const result = await http.post(`${experiment}/wbs`, param, config);
return result;
};
// 新建课题 -- 根据模板新建课题
export const create = param => http.post(`${experiment}/experiment/create`, { params: { param } });

112
src/components/tall/center/ProjectDetail.vue

@ -1,6 +1,6 @@
<template> <template>
<div class="navbar flex items-center justify-between"> <div class="navbar flex items-center justify-between">
<div class="project-name">{{ projectObj.obj.pname }}</div> <div class="project-name">{{ project.name }}</div>
<div class="project-action"> <div class="project-action">
<img /> <img />
<img @click="toShowMask" /> <img @click="toShowMask" />
@ -8,7 +8,7 @@
</div> </div>
<div class="role-list flex items-center"> <div class="role-list flex items-center">
<div class="role-box relative" v-for="(item, index) in roles.arr" :key="index"> <div class="role-box relative" v-for="(item, index) in roles" :key="index">
<div class="role-name" :class="{ mine: item.mine === 1 && currRoleId === item.id }">{{ item.name }}</div> <div class="role-name" :class="{ mine: item.mine === 1 && currRoleId === item.id }">{{ item.name }}</div>
<div class="line-box absolute flex justify-center" v-if="item.mine === 1 && currRoleId === item.id"><div class="line"></div></div> <div class="line-box absolute flex justify-center" v-if="item.mine === 1 && currRoleId === item.id"><div class="line"></div></div>
</div> </div>
@ -38,7 +38,7 @@
<div class="task-con" v-if="item.sonList && item.sonList.length > 0"> <div class="task-con" v-if="item.sonList && item.sonList.length > 0">
<div v-for="(val, key) in item.sonList" :key="key"> <div v-for="(val, key) in item.sonList" :key="key">
<a-checkbox @change="handleChange">{{ val.name }}</a-checkbox> <a-checkbox>{{ val.name }}</a-checkbox>
</div> </div>
</div> </div>
<div class="open-icon" v-if="item.sonList" @click="openCard"> <div class="open-icon" v-if="item.sonList" @click="openCard">
@ -55,33 +55,62 @@
import { computed, watch, reactive, ref } from 'vue'; import { computed, watch, reactive, ref } from 'vue';
import { useStore } from 'vuex'; import { useStore } from 'vuex';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import { findShowRole, getRegularTask, findSonTask } from 'apis'; import { findShowRole, getRegularTask, findSonTask, findProjectById } from 'apis';
const store = useStore(); const store = useStore();
const projectObj = reactive({ obj: { u: '', p: '', pname: '', url: '' } }); const projectId = sessionStorage.getItem('projectId');
const project = computed(() => store.state.projects.project); // const project = computed(() => store.state.projects.project); //
const currRoleId = computed(() => store.state.role.roleId); // const currRoleId = computed(() => store.state.role.roleId); //
const roles = reactive({ const roles = ref([
// { id: 1, name: '项目经理', mine: 1, pm: 1, sequence: 1 },
arr: [ { id: 2, name: '运维', mine: 0, pm: 0, sequence: 2 },
{ id: 1, name: '项目经理', mine: 1, pm: 1, sequence: 1 }, ]);
{ id: 2, name: '运维', mine: 0, pm: 0, sequence: 2 },
],
});
const permanents = computed(() => store.state.role.permanents); // const permanents = computed(() => store.state.role.permanents); //
const permanentObj = reactive({ permanentList: [] }); const permanentObj = reactive({ permanentList: [] });
const tasks = computed(() => store.state.role.tasks); // const tasks = computed(() => store.state.role.tasks); //
const taskObj = reactive({ tasks: [] }); const taskObj = reactive({ tasks: [] });
const globalHeight = ref(0); // const globalHeight = ref(0); //
async function init() {
try {
if (projectId) {
permanentObj.permanentList = permanents.value;
taskObj.tasks = tasks.value;
await getFindProjectById(projectId);
await getRoles(projectId); // id
await getPermanentData(currRoleId.value); //
await getTasks({ roleId: currRoleId.value });
}
} catch (error) {
console.log('error: ', error);
}
}
init();
//
watch(project, async newVal => {
console.log('newVal', newVal);
permanentObj.permanentList = permanents.value;
taskObj.tasks = tasks.value;
await getRoles(project.value.id); // id
await getPermanentData(currRoleId.value); //
await getTasks({ roleId: currRoleId.value });
});
// //
const setInitialRoleId = visibleList => { function setInitialRoleId(visibleList) {
if (!visibleList || !visibleList.length) return; if (!visibleList || !visibleList.length) return;
roles.arr = []; // roles.value = [];
visibleList.forEach(item => { roles.value = [...visibleList];
roles.arr.push(item); // visibleList.forEach(item => {
}); // roles.arr.push(item);
// });
console.log(roles);
const index = visibleList.findIndex(item => +item.mine === 1); const index = visibleList.findIndex(item => +item.mine === 1);
const currentRole = index > 0 ? visibleList[index] : visibleList[0]; const currentRole = index > 0 ? visibleList[index] : visibleList[0];
@ -92,26 +121,40 @@ const setInitialRoleId = visibleList => {
store.commit('role/setRoleId', currentRoleId); store.commit('role/setRoleId', currentRoleId);
// storage // storage
// this.$t.storage.setStorageSync('roleId', ''); // this.$t.storage.setStorageSync('roleId', '');
}; }
/**
* 通过项目id获取项目信息
* @param {string} projectId
* @param {object} params 提交的参数
*/
async function getFindProjectById(params) {
try {
const data = await findProjectById(params);
store.commit('projects/setProject', data);
} catch (error) {
throw new Error(error);
}
}
/** /**
* 通过项目id获取角色信息 * 通过项目id获取角色信息
* @param {string} projectId * @param {string} projectId
* @param {object} params 提交的参数 * @param {object} params 提交的参数
*/ */
const getRoles = async projectId => { async function getRoles(params) {
try { try {
const data = await findShowRole(projectId); const data = await findShowRole(params);
store.commit('role/setInvisibleRoles', data ? data.invisibleList : []); store.commit('role/setInvisibleRoles', data ? data.invisibleList : []);
store.commit('role/setVisibleRoles', data ? data.visibleList : []); store.commit('role/setVisibleRoles', data ? data.visibleList : []);
setInitialRoleId(data ? data.visibleList : []); setInitialRoleId(data ? data.visibleList : []);
} catch (error) { } catch (error) {
throw new Error(error); throw new Error(error);
} }
}; }
// //
const getPermanentData = async roleId => { async function getPermanentData(roleId) {
const params = { param: { roleId } }; const params = { param: { roleId } };
try { try {
const data = await store.dispatch('task/getPermanent', params); const data = await store.dispatch('task/getPermanent', params);
@ -120,10 +163,10 @@ const getPermanentData = async roleId => {
} catch (error) { } catch (error) {
throw new Error(error); throw new Error(error);
} }
}; }
// id // id
const getSonTask = async detailId => { async function getSonTask(detailId) {
const params = { param: { detailId } }; const params = { param: { detailId } };
try { try {
const data = await findSonTask(params); const data = await findSonTask(params);
@ -135,7 +178,7 @@ const getSonTask = async detailId => {
} catch (error) { } catch (error) {
throw new Error(error); throw new Error(error);
} }
}; }
/** /**
* 根据时间基准点和角色查找定期任务 * 根据时间基准点和角色查找定期任务
@ -146,7 +189,7 @@ const getSonTask = async detailId => {
* @param {string} query.queryNum 查找颗粒度数量 默认3个 * @param {string} query.queryNum 查找颗粒度数量 默认3个
* @param {number} query.queryType 0向上查找 1向下查找(默认) 下查包含自己上查不包含 * @param {number} query.queryType 0向上查找 1向下查找(默认) 下查包含自己上查不包含
*/ */
const getTasks = async query => { async function getTasks(query) {
const params = { param: query }; const params = { param: query };
try { try {
const data = await getRegularTask(params); const data = await getRegularTask(params);
@ -160,20 +203,7 @@ const getTasks = async query => {
} catch (error) { } catch (error) {
throw new Error(error); throw new Error(error);
} }
}; }
//
watch(project, async newVal => {
projectObj.obj = newVal;
store.commit('projects/setProject', newVal);
permanentObj.permanentList = permanents.value;
taskObj.tasks = tasks.value;
await getRoles(projectObj.obj.p); // id
await getPermanentData(currRoleId.value); //
await getTasks({ roleId: currRoleId.value });
});
function toDetail(item) { function toDetail(item) {
store.commit('task/setTaskDetail', item); store.commit('task/setTaskDetail', item);
@ -289,7 +319,7 @@ function toDetail(item) {
height: 30px; height: 30px;
} }
::v-deep .ant-checkbox + span { :deep(.ant-checkbox + span) {
color: #607d8b; color: #607d8b;
} }

129
src/components/tall/left/Index.vue

@ -1,15 +1,85 @@
<template> <template>
<Calendar @changeTime="changeTime" /> <div class="relative">
<Projects /> <Calendar @changeTime="changeTime" />
<PlusCircleFilled class="upload-btn absolute cursor-pointer" :style="{ fontSize: 42 + 'px', color: '#1890FF' }" @click="showModal" />
<!-- <div class="upload-card absolute" v-if="isShowCard">
<div class="model-list">
<div class="model-name cursor-pointer">模板项目</div>
<div class="model-name cursor-pointer">模板项目</div>
</div>
<div class="upload-box relative">
<a-button type="primary">导入WBS</a-button>
<input @change="handleUpload" class="btn-file absolute cursor-pointer" name="file" type="file" />
</div>
</div> -->
<a-modal v-model:visible="visible" title="新建课题" @ok="handleOk">
<p>是否新建课题</p>
</a-modal>
<Projects ref="projectsRef" />
</div>
</template> </template>
<script setup> <script setup>
// import { reactive } from 'vue'; import { ref } from 'vue';
// import { useStore } from 'vuex'; // import { useStore } from 'vuex';
// import dayjs from 'dayjs'; import dayjs from 'dayjs';
// import { getProjects } from 'apis'; import { PlusCircleFilled } from '@ant-design/icons-vue';
import { create } from 'apis';
import Calendar from './Calendar.vue'; import Calendar from './Calendar.vue';
import Projects from './Projects.vue'; import Projects from './Projects.vue';
// import { importWbs } from 'apis';
const visible = ref(false);
const projectsRef = ref(null);
const showModal = () => {
visible.value = true;
};
const handleOk = async () => {
visible.value = false;
await createExperiment();
};
//
async function createExperiment() {
try {
const data = await create();
projectsRef.value.getProjectsList(dayjs().startOf('day').format('x'), dayjs().endOf('day').format('x'));
return data;
} catch (error) {
throw new Error(error);
}
}
// const isShowCard = ref(false);
// function showCard() {
// isShowCard.value = !isShowCard.value;
// }
// wbs
// async function handleUpload(e) {
// try {
// const data = await importWbs(e);
// console.log(data);
// setTimeout((data) => {
// const obj = {
// id: data.id,
// name: data.name,
// url: data.url,
// };
// store.commit('projects/setProject', obj);
// }, 2000);
// } catch (error) {
// throw new Error(error);
// }
// }
// const store = useStore(); // const store = useStore();
// const projects = reactive([]); // const projects = reactive([]);
@ -51,3 +121,52 @@ function changeTime() {
<script> <script>
export default { name: 'LeftIndex' }; export default { name: 'LeftIndex' };
</script> </script>
<style scoped>
.upload-btn {
left: 250px;
top: 310px;
z-index: 999;
}
.upload-card {
left: 250px;
top: 352px;
-moz-box-shadow: 1px 1px 5px 0px rgba(0, 0, 0, 0.16);
-webkit-box-shadow: 1px 1px 5px 0px rgba(0, 0, 0, 0.16);
box-shadow: 1px 1px 5px 0px rgba(0, 0, 0, 0.16);
width: 296px;
z-index: 999;
border-radius: 8px;
background: #fff;
}
.model-list {
padding: 16px;
}
.model-name {
height: 32px;
line-height: 32px;
}
.upload-box {
padding: 16px;
border-top: 1px solid #cccccc;
}
.btn-file {
top: 16px;
left: 16px;
width: 264px;
height: 38px;
opacity: 0;
}
.upload-box .ant-btn-primary {
width: 100%;
height: 38px;
border-radius: 6px;
font-size: 16px;
}
</style>

64
src/components/tall/left/Projects.vue

@ -1,9 +1,9 @@
<template> <template>
<a-divider /> <a-divider />
<div class="list-flex"> <div class="list-flex">
<div class="item-box" v-for="(item, index) in projects" :key="index"> <div class="item-box" v-for="(item, index) in projects.projects" :key="index">
<div class="one-level h-70 cursor-pointer flex items-center" @click="toDetail(item)"> <div class="one-level h-70 cursor-pointer flex items-center" @click="toDetail(item)">
<div class="icon"><img src="https://www.tall.wiki/staticrec/drag.svg" /></div> <div class="icon" @click.stop="showActionCard(item)"><img src="https://www.tall.wiki/staticrec/drag.svg" /></div>
<div class="detail"> <div class="detail">
<div class="name-box flex items-center"> <div class="name-box flex items-center">
<div class="name truncate">{{ item.name }}</div> <div class="name truncate">{{ item.name }}</div>
@ -14,12 +14,12 @@
</div> </div>
<div class="right" @click.stop="openMenu"> <div class="right" @click.stop="openMenu">
<RightOutlined v-if="!item.show" /> <RightOutlined v-if="!item.show" @click="changeShow(item)" />
<DownOutlined v-else /> <DownOutlined v-else @click="changeShow(item)" />
</div> </div>
</div> </div>
<div class="two-box"> <div class="two-box" v-if="item.show">
<div class="two-flex" v-for="(sonItem, sonIndex) in item.sonProjectList" :key="sonIndex"> <div class="two-flex" v-for="(sonItem, sonIndex) in item.sonProjectList" :key="sonIndex">
<div class="two-level h-70 cursor-pointer flex items-center" @click="toDetail(sonItem)"> <div class="two-level h-70 cursor-pointer flex items-center" @click="toDetail(sonItem)">
<div class="icon"><img src="https://www.tall.wiki/staticrec/drag.svg" /></div> <div class="icon"><img src="https://www.tall.wiki/staticrec/drag.svg" /></div>
@ -33,12 +33,12 @@
</div> </div>
<div class="right" @click.stop="openMenu"> <div class="right" @click.stop="openMenu">
<RightOutlined v-if="!sonItem.show" /> <RightOutlined v-if="!sonItem.show" @click="changeShow(sonItem)" />
<DownOutlined v-else /> <DownOutlined v-else @click="changeShow(sonItem)" />
</div> </div>
</div> </div>
<div class="three-box"> <div class="three-box" v-if="sonItem.show">
<div <div
class="three-level h-70 cursor-pointer flex items-center" class="three-level h-70 cursor-pointer flex items-center"
v-for="(thirdItem, thirdIndex) in sonItem.sonProjectList" v-for="(thirdItem, thirdIndex) in sonItem.sonProjectList"
@ -61,24 +61,36 @@
</div> </div>
</div> </div>
</div> </div>
<a-modal v-model:visible="visible" title="删除课题" @ok="handleOk">
<p>是否删除课题</p>
</a-modal>
</div> </div>
</template> </template>
<script setup> <script setup>
import { reactive } from 'vue'; import { reactive, ref } from 'vue';
import { useStore } from 'vuex'; import { useStore } from 'vuex';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import { getProjects } from 'apis'; import { getProjects, delProject } from 'apis';
import { RightOutlined, DownOutlined } from '@ant-design/icons-vue'; import { RightOutlined, DownOutlined } from '@ant-design/icons-vue';
const store = useStore(); const store = useStore();
const projects = reactive([]); const projects = reactive({ projects: [] });
const visible = ref(false);
const deleteId = ref(null);
//
const showActionCard = item => {
visible.value = true;
deleteId.value = item.id;
};
// //
const getProjectsList = async (startTime, endTime) => { const getProjectsList = async (startTime, endTime) => {
try { try {
const data = await getProjects(startTime, endTime); const data = await getProjects(startTime, endTime);
projects.projects = [];
data.forEach(item => { data.forEach(item => {
item.show = false; item.show = false;
@ -88,12 +100,12 @@ const getProjectsList = async (startTime, endTime) => {
}); });
} }
projects.push(item); projects.projects.push(item);
}); });
store.commit('projects/setProjects', data); store.commit('projects/setProjects', data);
} catch (error) { } catch (error) {
console.log(error); throw new Error(error);
} }
}; };
@ -101,14 +113,32 @@ getProjectsList(dayjs().startOf('day').format('x'), dayjs().endOf('day').format(
function toDetail(project) { function toDetail(project) {
const obj = { const obj = {
u: project.userId, id: project.id,
p: project.id, name: project.name,
pname: project.name,
url: project.url, url: project.url,
}; };
store.commit('projects/setProject', obj); store.commit('projects/setProject', obj);
} }
function changeShow(item) {
item.show = !item.show;
}
async function handleOk() {
visible.value = false;
await deleteProject(deleteId.value);
getProjectsList(dayjs().startOf('day').format('x'), dayjs().endOf('day').format('x'));
}
//
async function deleteProject(param) {
try {
await delProject(param);
} catch (error) {
throw new Error(error);
}
}
</script> </script>
<script> <script>
export default { name: 'Projects' }; export default { name: 'Projects' };

18
src/components/tall/top/Navbar.vue

@ -1,8 +1,22 @@
<template> <template>
<h1>课题数据库444444444</h1> <h1>{{ taskInfo.name }}</h1>
</template> </template>
<script setup></script> <script setup>
import { computed, watch, ref } from 'vue';
import { useStore } from 'vuex';
// import dayjs from 'dayjs';
const store = useStore();
const taskDetail = computed(() => store.state.task.taskDetail); //
const taskInfo = ref({});
//
watch(taskDetail, newVal => {
taskInfo.value = newVal;
store.commit('task/setTaskDetail', newVal);
});
</script>
<style scoped> <style scoped>
h1 { h1 {

8
src/store/tall/projects/index.js

@ -57,6 +57,14 @@ export default {
*/ */
setProject(state, data) { setProject(state, data) {
state.project = data || { name: '加载中...' }; state.project = data || { name: '加载中...' };
console.log(11111111111, data);
if (data) {
sessionStorage.setItem('projectId', data.id);
sessionStorage.setItem('project', JSON.stringify(data));
} else {
sessionStorage.removeItem('projectId');
sessionStorage.removeItem('project');
}
}, },
/** /**

18
src/views/detail/Test.vue

@ -1,13 +1,26 @@
<template> <template>
<div class="task-detail"> <div class="task-detail">
<div class="task-con">任务详情页</div> <div class="task-con">{{ taskInfo.name }}</div>
<div> <div>
<router-view></router-view> <router-view></router-view>
</div> </div>
</div> </div>
</template> </template>
<script setup></script> <script setup>
import { computed, watch, ref } from 'vue';
import { useStore } from 'vuex';
const store = useStore();
const taskDetail = computed(() => store.state.task.taskDetail); //
const taskInfo = ref({});
//
watch(taskDetail, newVal => {
taskInfo.value = newVal;
store.commit('task/setTaskDetail', newVal);
});
</script>
<style scoped> <style scoped>
.task-detail { .task-detail {
@ -19,6 +32,7 @@
.task-con { .task-con {
width: 100%; width: 100%;
height: 500px; height: 500px;
max-height: 100%;
background-color: #fff; background-color: #fff;
border-radius: 10px; border-radius: 10px;
border: 1px solid #cccccc; border: 1px solid #cccccc;

Loading…
Cancel
Save