Browse Source

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

pull/1/head
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 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); export const saveSubExperiment = params => http.post(`${experiment}/experiment/saveSubExperiment`, params);

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

@ -1,7 +1,7 @@
<template> <template>
<a-divider /> <a-divider />
<div class="list-flex"> <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="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="icon" @click.stop="showActionCard(item)"><img src="https://www.tall.wiki/staticrec/drag.svg" /></div>
<div class="detail"> <div class="detail">
@ -69,24 +69,28 @@
</template> </template>
<script setup> <script setup>
import { reactive, ref, watch, computed } from 'vue'; import { ref, watch, computed } from 'vue';
import { useStore } from 'vuex'; import { useStore } from 'vuex';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import { getProjects, delProject } 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({ projects: [] }); // const projects = reactive({ projects: [] });
const visible = ref(false); const visible = ref(false);
const deleteId = ref(null); const deleteId = ref(null);
const projectId = sessionStorage.getItem('projectId'); const projectId = sessionStorage.getItem('projectId');
const projectInfo = computed(() => store.state.projects.project); //
const newProject = computed(() => store.state.projects.newProject); // const newProject = computed(() => store.state.projects.newProject); //
const projects = computed(() => store.state.projects.projects); //
const startTime = computed(() => store.state.layout.startTime); // const startTime = computed(() => store.state.layout.startTime); //
const endTime = computed(() => store.state.layout.endTime); // const endTime = computed(() => store.state.layout.endTime); //
let start = startTime.value ? startTime.value : dayjs().startOf('day').format('x'); let start = startTime.value ? startTime.value : dayjs().startOf('day').format('x');
let end = endTime.value ? endTime.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'); start = startTime.value ? startTime.value : dayjs().startOf('day').format('x');
end = endTime.value ? endTime.value : dayjs().startOf('day').format('x'); end = endTime.value ? endTime.value : dayjs().startOf('day').format('x');
getProjectsList(start, end); getProjectsList(start, end);
@ -104,7 +108,7 @@ const showActionCard = item => {
async function getProjectsList(startData, endData) { async function getProjectsList(startData, endData) {
try { try {
const data = await getProjects(startData, endData); const data = await getProjects(startData, endData);
projects.projects = []; // projectList.value = [];
data.forEach(item => { data.forEach(item => {
item.show = false; 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); store.commit('projects/setProjects', data);
} catch (error) { } catch (error) {

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

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

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

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

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

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

9
src/views/detail/Test.vue

@ -208,6 +208,15 @@ watch([taskDetail], () => {
height: 38px; 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) { :deep(.ant-upload) {
width: 100%; width: 100%;
} }

Loading…
Cancel
Save