Browse Source

feat: "任务计划书增删改"

master
xuesinan 4 years ago
parent
commit
1de6f3d85c
  1. 3
      src/apis/index.js
  2. 17
      src/components/tall/left/Projects.vue
  3. 47
      src/components/tall/task/MemberManagement.vue
  4. 151
      src/components/tall/task/PlanAssignment.vue
  5. 8
      src/store/tall/task/index.js
  6. 9
      src/views/detail/Test.vue

3
src/apis/index.js

@ -70,6 +70,9 @@ export const uploadImg = `${filedeal}/file/upload/multiple`;
// 添加/编辑计划任务书
export const savePlanTask = params => http.post(`${experiment}/experiment/savePlanTask`, params);
// 查看任务计划书
export const getPlanTask = params => http.post(`${experiment}/experiment/getPlanTask`, params);
// 分配子课题
export const saveSubExperiment = params => http.post(`${experiment}/experiment/saveSubExperiment`, params);

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

@ -1,7 +1,7 @@
<template>
<a-divider />
<div class="list-flex">
<div class="item-box" v-for="(item, index) in projects.projects" :key="index">
<div class="item-box" v-for="(item, index) in projectList" :key="index">
<div class="one-level h-70 cursor-pointer flex items-center" @click="toDetail(item)">
<div class="icon" @click.stop="showActionCard(item)"><img src="https://www.tall.wiki/staticrec/drag.svg" /></div>
<div class="detail">
@ -69,24 +69,28 @@
</template>
<script setup>
import { reactive, ref, watch, computed } from 'vue';
import { ref, watch, computed } from 'vue';
import { useStore } from 'vuex';
import dayjs from 'dayjs';
import { getProjects, delProject } from 'apis';
import { RightOutlined, DownOutlined } from '@ant-design/icons-vue';
const store = useStore();
const projects = reactive({ projects: [] });
// const projects = reactive({ projects: [] });
const visible = ref(false);
const deleteId = ref(null);
const projectId = sessionStorage.getItem('projectId');
const projectInfo = computed(() => store.state.projects.project); //
const newProject = computed(() => store.state.projects.newProject); //
const projects = computed(() => store.state.projects.projects); //
const startTime = computed(() => store.state.layout.startTime); //
const endTime = computed(() => store.state.layout.endTime); //
let start = startTime.value ? startTime.value : dayjs().startOf('day').format('x');
let end = endTime.value ? endTime.value : dayjs().startOf('day').format('x');
const projectList = ref([]);
projectList.value = [...projects.value];
watch([newProject, startTime, endTime], () => {
watch([newProject, startTime, endTime, projectInfo], () => {
start = startTime.value ? startTime.value : dayjs().startOf('day').format('x');
end = endTime.value ? endTime.value : dayjs().startOf('day').format('x');
getProjectsList(start, end);
@ -104,7 +108,7 @@ const showActionCard = item => {
async function getProjectsList(startData, endData) {
try {
const data = await getProjects(startData, endData);
projects.projects = [];
// projectList.value = [];
data.forEach(item => {
item.show = false;
@ -123,8 +127,9 @@ async function getProjectsList(startData, endData) {
});
}
projects.projects.push(item);
// projectList.value.push(item);
});
projectList.value = [...data];
store.commit('projects/setProjects', data);
} catch (error) {

47
src/components/tall/task/MemberManagement.vue

@ -1,6 +1,11 @@
<template>
<div>
<a-table :columns="columns" :data-source="dataList">
<a-table
class="member-list"
:columns="columns"
:data-source="dataList"
:row-class-name="(_record, index) => (index % 2 === 1 ? null : 'table-striped')"
>
<template #bodyCell="{ column, text, record }">
<template v-if="column.key === 'action'">
<template v-if="record.isEdit === 0">
@ -38,6 +43,7 @@ import { memberQuery, saveMember, updateMember, delMember } from 'apis';
const store = useStore();
const projectId = computed(() => store.getters['projects/projectId']);
const sessionProject = sessionStorage.getItem('project');
const isAdd = ref(false);
if (sessionProject) {
const project = JSON.parse(sessionProject);
@ -58,7 +64,12 @@ const columns = ref([
{
title: '手机号',
dataIndex: 'phone',
key: 'account',
key: 'phone',
},
{
title: '角色',
dataIndex: 'roles',
key: 'roles',
},
{
title: '操作',
@ -75,6 +86,7 @@ async function getList() {
try {
const params = { param: { projectId: projectId.value } };
const data = await memberQuery(params);
store.commit('task/setMembers', data);
dataList.value = [];
data.forEach((item, index) => {
@ -84,6 +96,7 @@ async function getList() {
memberId: item.memberId,
memberName: item.memberName,
phone: item.phone,
roles: item.experimentNameList.toString(),
isEdit: 0,
};
@ -98,9 +111,12 @@ const addMember = () => {
const num = dataList.value.length + 1;
const obj = { key: num, indexId: num, memberName: '', phone: '', isEdit: 1 };
dataList.value.push(obj);
isAdd.value = true;
};
function toEdit(key) {
isAdd.value = false;
dataList.value.forEach(item => {
if (item.key === key) {
item.isEdit = 1;
@ -109,14 +125,28 @@ function toEdit(key) {
}
function cancel(key) {
dataList.value.filter(item => {
console.log(isAdd.value);
let ind = -1;
dataList.value.filter((item, index) => {
if (item.key === key) {
item.isEdit = 0;
if (isAdd.value) {
ind = index;
} else {
item.isEdit = 0;
}
}
});
if (ind > -1) {
dataList.value.splice(ind, 1);
}
isAdd.value = false;
}
async function save(key) {
isAdd.value = false;
const params = {
param: {
projectId: projectId.value,
@ -166,6 +196,15 @@ async function toDelete(key) {
</script>
<style scoped>
.member-list {
border-radius: 10px 10px 0 0;
overflow: hidden;
}
:deep(.table-striped) td {
background-color: #fafafa;
}
.action-btn {
width: 50px !important;
height: 28px !important;

151
src/components/tall/task/PlanAssignment.vue

@ -15,11 +15,20 @@
<a-form-item>
<label class="color-3">负责人</label>
<a-select v-model:value="topicMeetFormData.memberId">
<a-select-option value="jack">Jack</a-select-option>
<a-select-option value="lucy">Lucy</a-select-option>
<a-select-option value="Yiminghe">yiminghe</a-select-option>
</a-select>
<a-select
v-model:value="topicMeetFormData.memberId"
show-search
optionFilterProp="label"
placeholder="负责人"
:options="options"
:filter-option="filterOption"
@search="handleSearch"
:getPopupContainer="
triggerNode => {
return triggerNode.parentNode || document.body;
}
"
></a-select>
</a-form-item>
<a-form-item class="form-item-dad">
@ -31,7 +40,7 @@
<div class="form-item-son" style="padding-left: 16px">
<div v-for="(item, index) in planTaskStageList" :key="index">
<a-form-item>
<label class="color-3">{{ index === 0 ? '一' : index === 1 ? '二' : '三' }}阶段</label>
<label class="color-3">{{ index + 1 }}阶段</label>
<a-space direction="vertical" :size="12">
<a-range-picker v-model:value="item.date" />
</a-space>
@ -62,7 +71,7 @@
<a-form-item>
<label class="color-3">验收内容</label>
<a-checkbox-group v-model:value="topicMeetFormData.checkContent">
<a-checkbox-group v-model:value="topicMeetFormData.checkContentList">
<a-row>
<a-col :span="5">
<a-checkbox value="1"><span class="color-6">1工作报告</span></a-checkbox>
@ -138,20 +147,23 @@
</template>
<script setup>
import { ref, computed, toRaw } from 'vue';
import { ref, computed } from 'vue';
import { useStore } from 'vuex';
import { InboxOutlined, PlusCircleOutlined } from '@ant-design/icons-vue';
import { uploadImg } from 'apis';
import { uploadImg, memberQuery, savePlanTask, getPlanTask } from 'apis';
import dayjs from 'dayjs';
const store = useStore();
const formRef = ref(null);
const projectInfo = computed(() => store.state.projects.project); //
const sessionProject = sessionStorage.getItem('project');
const projectId = computed(() => store.getters['projects/projectId']);
const token = computed(() => store.getters['user/token']);
const headers = { Authorization: `Bearer ${token.value}` };
const action = uploadImg;
const fileList = ref([]);
// const members = computed(() => store.state.task.members);
// console.log('members', members.value)
if (sessionProject) {
const project = JSON.parse(sessionProject);
@ -159,7 +171,7 @@ if (sessionProject) {
}
const topicMeetFormData = ref({
projectId: projectId.value,
projectId: projectInfo.value.id,
name: '',
date: [],
startTime: '',
@ -168,16 +180,30 @@ const topicMeetFormData = ref({
technicalIndicator: '',
economicIndicators: '',
socialBenefit: '',
checkContent: [],
fileIdList: [],
// fileList: [],
checkContentList: [],
fileList: [],
planTaskStageList: [],
planTaskDefinedList: [],
});
const planTaskStageList = ref([]);
const options = ref([]);
const planTaskStageList = ref([{ date: [], stageStartTime: '', stageEndTime: '', remark: '' }]);
const planTaskDefinedList = ref([]);
checkPlanTask(); //
getList(); //
const handleSearch = async value => {
console.log('handleSearch', options.value, value);
// await getList(value); //
};
const filterOption = (input, option) => {
return option.value.toLowerCase().indexOf(input.toLowerCase()) >= 0;
};
const handleChange = info => {
const resFileList = [...info.fileList];
@ -211,39 +237,98 @@ const handleChange = info => {
fileList.value = arr.value;
};
//
async function checkPlanTask() {
try {
const params = { param: { projectId: projectId.value } };
const data = await getPlanTask(params);
data.checkContentList = data.checkContent.split(',');
const start = dayjs(Number(data.startTime));
const end = dayjs(Number(data.endTime));
const arr = [start, end];
data.date = arr;
data.projectId = data.id;
topicMeetFormData.value = data;
planTaskDefinedList.value = data.planTaskDefinedList;
data.planTaskStageList.forEach(item => {
const planStart = dayjs(Number(item.stageStartTime));
const planEnd = dayjs(Number(item.stageEndTime));
item.date = [planStart, planEnd];
});
planTaskStageList.value = data.planTaskStageList;
const fileArr = [];
data.fileList.forEach(item => {
const fileInfo = {
id: item.fileId,
name: item.fileName,
url: item.filePath,
status: 'done',
};
fileArr.push(fileInfo);
});
fileList.value = fileArr;
} catch (error) {
console.log('error', error);
}
}
//
async function getList(name) {
try {
const params = { param: { projectId: projectId.value, name } };
const data = await memberQuery(params);
store.commit('task/setMembers', data);
options.value = [];
data.forEach(item => {
const obj = {
label: item.memberName,
value: item.memberId,
};
options.value.push(obj);
});
} catch (error) {
console.log('error', error);
}
}
//
function addMilestones() {
planTaskStageList.value.push({ date: [], startTime: '', endTime: '', remark: '' });
planTaskStageList.value.push({ date: [], stageStartTime: '', stageEndTime: '', remark: '' });
}
function addDefined() {
planTaskDefinedList.value.push({ key: [], value: '' });
planTaskDefinedList.value.push({ key: '', value: '' });
}
const onSubmit = () => {
const onSubmit = async () => {
fileList.value.forEach(item => {
// let obj = {
// fileId: item.id,
// fileName: item.name,
// filePathL: item.url
// }
// topicMeetFormData.value.fileList.push(obj);
topicMeetFormData.value.fileIdList.push(item.id);
const obj = {
fileId: item.id,
fileName: item.name,
filePath: item.url,
};
topicMeetFormData.value.fileList.push(obj);
});
topicMeetFormData.value.planTaskStageList = [];
planTaskStageList.value.forEach(item => {
const obj = {
startTime: '',
endTime: '',
stageStartTime: '',
stageEndTime: '',
remark: item.remark,
};
item.date.forEach((val, key) => {
if (key === 0) {
obj.startTime = dayjs(val).format('x');
obj.stageStartTime = dayjs(val).format('x');
} else {
obj.endTime = dayjs(val).format('x');
obj.stageEndTime = dayjs(val).format('x');
}
});
@ -260,10 +345,12 @@ const onSubmit = () => {
}
});
// const params = { param: topicMeetFormData.value };
const params = { param: topicMeetFormData.value };
// savePlanTask(params);
console.log('submit!', toRaw(topicMeetFormData.value), planTaskStageList.value, planTaskDefinedList.value);
await savePlanTask(params);
projectInfo.value.name = topicMeetFormData.value.name;
store.commit('projects/setProject', projectInfo.value);
checkPlanTask();
};
</script>

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

@ -27,6 +27,7 @@ export default {
showScrollTo: false, // 是否可以设置时间轴自动滚动的位置
taskDetail: {}, // 当前点击任务信息
label: '', // 任务code
members: [], // 成员列表
},
getters: {
@ -312,6 +313,13 @@ export default {
sessionStorage.removeItem('label');
}
},
/**
* 设置成员列表
*/
setMembers(state, data) {
state.members = data || [];
},
},
actions: {

9
src/views/detail/Test.vue

@ -208,6 +208,15 @@ watch([taskDetail], () => {
height: 38px;
}
:deep(.ant-select-single:not(.ant-select-customize-input) .ant-select-selector .ant-select-selection-search-input) {
height: 38px;
}
:deep(.ant-select-single .ant-select-selector .ant-select-selection-item),
:deep(.ant-select-single .ant-select-selector .ant-select-selection-placeholder) {
line-height: 36px;
}
:deep(.ant-upload) {
width: 100%;
}

Loading…
Cancel
Save