h5
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

466 lines
14 KiB

<template>
<div class="new-projects-box">
<div class="form">
<!-- 项目名称 -->
<view class="mb-3 font-bold text-base flex justify-center text-black">新建任务</view>
<div class="flex items-center mb-2">
<div>名称<span class="text-red-500">*</span></div>
<u-input max-length="5" v-model="name" :type="type" :border="border" />
</div>
<!-- 起止时间 -->
<div class="mb-2">
<div>起止时间:</div>
<u-input placeholder="请选择起止时间" v-model="timeValue" :type="type" :border="border" @click="$emit('showTime')" />
</div>
<!-- 多选框 -->
<div class="flex justify-between items-center">
<div>负责人<span class="text-red-500">*</span>:</div>
<div class="flex-1" v-if="hasRole">{{ roleName }}</div>
<div label="负责人" class="flex-1" v-else>
<u-dropdown disabled ref="uDropdown" placeholder="请选择负责人">
<u-dropdown-item :title="roleList">
<view class="slot-content bg-white">
<div
class="flex flex-row justify-between mb-1 drop-item"
v-for="(role, roleIndex) in roleOptions"
:key="roleIndex"
@click="change(roleIndex)"
>
<view v-model="role.id">{{ role.name }}</view>
<u-icon v-if="role.dropdownShow" name="checkbox-mark" color="#2979ff" size="28"></u-icon>
</div>
</view>
</u-dropdown-item>
</u-dropdown>
</div>
</div>
<!-- 下拉图标 -->
<div class="flex justify-center my-6">
<u-icon v-if="arrow" name="arrow-down" size="28" @click="openDropdown"></u-icon>
<u-icon v-else name="arrow-up" size="28" @click="closeSecondDropdown"></u-icon>
</div>
<!-- 下拉框的内容 -->
<div v-if="show" class="mb-6">
<!-- 描述 -->
<div class="flex items-center mb-2">
<div>描述:</div>
<u-input v-model="description" max-length="48" type="textarea" height="36" auto-height :border="border" />
</div>
<!-- 所属项目 -->
<div class="w flex items-center mb-2">
<div>所属项目<span class="text-red-500">*</span>:</div>
<div>{{ project.name }}</div>
</div>
<!-- 所属任务 -->
<div class="w flex items-center mb-2" v-if="task && task.id">
<div>所属任务:</div>
<div>{{ task.name }}</div>
</div>
<!-- 上道工序 -->
<div class="flex items-center mb-2">
<div>上道工序:</div>
<InputSearch
@searchPrevTask="searchPrevTask"
:dataSource="allTasks"
@select="handleChange"
@clearAllTasks="clearAllTasks"
placeholder="请输入上道工序"
/>
</div>
<!-- 检查人多选框 -->
<div class="flex justify-between items-center">
<div>检查人<span class="text-red-500">*</span>:</div>
<div label="检查人" class="flex-1">
<u-dropdown ref="dropdown">
<u-dropdown-item :title="checkerList">
<view class="slot-content bg-white">
<div
class="flex flex-row justify-between mb-1 drop-item"
v-for="(checkoutOption, Index) in checkoutOptions"
:key="Index"
@click="choose(Index)"
>
<view v-model="checkoutOption.value">{{ checkoutOption.name }}</view>
<u-icon v-if="checkoutOption.dropdownShow" name="checkbox-mark" color="#2979ff" size="28"></u-icon>
</div>
</view>
</u-dropdown-item>
</u-dropdown>
</div>
</div>
<!-- 是否是日常任务 -->
<div class="flex justify-between items-center mt-6">
是否是日常任务:
<u-switch v-model="isGlobal" size="28"></u-switch>
</div>
<div class="mt-6">
<div>交付物:</div>
<div v-for="(sort, sortIndex) in deliverSort" :key="sortIndex">
<u-input
@blur="addDeliverInput"
v-model="sort.name"
:placeholder="`交付物名称${sortIndex + 1}`"
:type="type"
:border="border"
/>
</div>
</div>
</div>
<div class="flex items-center mb-6">
<u-button type="primary" size="medium" @click="setParameters">提交</u-button>
</div>
</div>
</div>
</template>
<script>
import { mapState, mapGetters, mapMutations, mapActions } from 'vuex';
export default {
props: {
startTime: {
type: String,
default: '',
},
endTime: {
type: String,
default: '',
},
task: {
type: Object,
default: null,
},
},
data() {
return {
arrow: true,
show: false,
isGlobal: false, //是否日常任务
name: '', //名称
showChooseTime: false,
timeValue: '', //起止时间
description: '', //描述
projectShow: false, //所属项目模糊搜索展示
processTaskId: '', //上道工序
type: 'text',
border: true,
roleList: undefined, //负责人默认多选
checkerList: undefined, //检查人默认多选
roleOptions: [], // 负责人下拉多选列表
checkoutOptions: [], // 检查人下拉多选列表
roleIdList: [], // 选中的负责人id
checkerIdList: [], // 选中的检查人id
deliverables: [], // 交付物
deliverSort: [{ name: '' }], // 交付物排序
allTasks: [],
roleName: '', // 负责人名字
hasRole: false, // 有没有负责人
};
},
computed: {
...mapState('role', ['visibleRoles', 'roleId']),
...mapState('project', ['project']),
...mapState('task', ['tasks']),
...mapGetters('project', ['projectId']),
},
watch: {
endTime(val) {
if (val) {
this.timeValue = this.startTime + ' 至 ' + val;
}
},
},
mounted() {
// 获取负责人和检查人列表
if (this.visibleRoles.length) {
this.visibleRoles.forEach(role => {
role.dropdownShow = false;
role.status = false;
});
}
this.roleOptions = this.$u.deepClone(this.visibleRoles);
this.checkoutOptions = this.$u.deepClone(this.visibleRoles);
// 判断有没有负责人 是不是添加子任务
if (this.roleId) {
const item = this.visibleRoles.find(r => r.id === this.roleId);
if (item) {
this.roleName = item.name;
this.hasRole = true;
}
}
},
methods: {
...mapMutations('task', ['updateTasks']),
...mapActions('task', ['getPermanent']),
// 负责人下拉多选选中
change(index) {
let arr = [...this.roleOptions];
// 选择多选项图标的展示
arr[index].dropdownShow = !arr[index].dropdownShow;
// 多选展示的改变
this.roleList = arr[index].name;
let shows = '';
// 遍历arr,如果选中,添加到多选展示框上
arr.map(val => {
if (val.dropdownShow === true) {
shows += val.name + ',';
this.roleIdList.push(val.id);
}
});
this.roleOptions = [...arr];
// 删除最后的','
this.roleList = shows.slice(0, shows.length - 1);
},
// 检查人下拉多选选中
choose(index) {
let arr = [...this.checkoutOptions];
// 选择多选项图标的展示
arr[index].dropdownShow = !arr[index].dropdownShow;
// 多选展示的改变
this.checkerList = arr[index].name;
let shows = '';
// 遍历arr,如果选中,添加到多选展示框上
arr.map(val => {
if (val.dropdownShow === true) {
shows += val.name + ',';
this.checkerIdList.push(val.id);
}
});
this.checkoutOptions = [...arr];
// 删除最后的','
this.checkerList = shows.slice(0, shows.length - 1);
// this.roleList = arr[value - 1].name;
},
// 打开下拉框
openDropdown() {
this.arrow = !this.arrow;
this.show = true;
},
// 关闭下拉框
closeSecondDropdown() {
this.arrow = !this.arrow;
this.show = false;
},
/**
* 模糊查询 查找项目下的任务
* @param name 任务名
* @param projectId 项目id
*/
async searchPrevTask(val) {
try {
const params = { name: val, projectId: this.projectId };
const data = await this.$u.api.queryTaskOfProject(params);
this.allTasks = data;
return data;
} catch (error) {
console.error('error: ', error);
}
},
//用户点击获取的数据
handleChange(data) {
console.log('data', data);
this.processTaskId = data.detailId;
},
// 清空模糊查询信息
clearAllTasks() {
this.allTasks = [];
},
// 数组最后一项有值 添加一条交付物输入框
addDeliverInput() {
if (this.deliverSort[this.deliverSort.length - 1].name) {
this.deliverSort.push({ name: '' });
}
},
// 设置提交参数
async setParameters() {
const {
projectId,
task,
name,
startTime,
endTime,
hasRole,
roleIdList,
roleId,
description,
processTaskId,
checkerIdList,
isGlobal,
} = this;
if (!name) {
uni.$uiowToast('请输入名称');
return;
}
if ((!roleIdList || !roleIdList.length) && !hasRole) {
uni.$uiowToast('请选择负责人');
return;
}
if (!checkerIdList || !checkerIdList.length) {
uni.$uiowToast('请选择检查人');
return;
}
const deliverList = [];
this.deliverSort.forEach(item => {
if (item.name) {
deliverList.push(item.name);
}
});
const params = {
name,
startTime: startTime ? this.$moment(startTime).format('x') - 0 : '',
endTime: endTime ? this.$moment(endTime).format('x') - 0 : '',
roleIdList: hasRole ? [roleId] : roleIdList,
description,
projectId,
parentTaskId: task && task.id ? task.id : '', // 父任务
processTaskId, // 上道工序 TODO
checkerIdList,
global: isGlobal ? 1 : 0,
deliverList,
};
await this.handleSubmit(params);
},
/**
* 新建任务
* @param name 任务名
* @param startTime 开始时间
* @param endTime 结束时间
* @param roleIdList 负责人id(数组)
* @param description 描述
* @param projectId 所属项目id
* @param parentTaskId 所属任务id
* @param processTaskId 上道工序(任务id)
* @param checkerIdList 检查人id(数组)
* @param global 是否日常任务 0否 1是
* @param deliverList 交付物名字(数组)
*/
async handleSubmit(params) {
try {
const data = await this.$u.api.saveTask(params);
// TODO 任务新建成功 继续 or 取消
this.$emit('closeMask');
const newTasks = {
data: data[0],
processTaskId: params.processTaskId,
};
// 将新加的任务加到store
// 判断不是子任务
if (!this.task || !this.task.id) {
this.addNewTasks(newTasks);
}
} catch (error) {
this.$emit('closeMask');
console.error('error: ', error);
}
},
// 添加任务后更新tasks
addNewTasks(data) {
const oldTasks = this.$u.deepClone(this.tasks);
let res = data.data;
console.log('添加任务后更新tasks', data);
// 判断有没有选择上道工序
if (data.processTaskId) {
const index = oldTasks.find(item => item.detailId === data.processTaskId);
if (index) {
oldTasks.splice(index + 1, 0, res);
}
} else {
this.setAddPosition(res, oldTasks);
}
},
// 设置添加位置
setAddPosition(res, oldTasks) {
console.log('设置添加位置', res, oldTasks);
if (res.planStart - 0 < oldTasks[0].planStart - 0) {
// 开始时间小于列表的第一个 插入最前面
oldTasks.splice(0, 0, res);
} else if (res.planStart - 0 === oldTasks[0].planStart - 0) {
// 开始时间等于列表的第一个 插入第二
oldTasks.splice(1, 0, res);
} else if (res.planStart - 0 >= oldTasks[oldTasks.length - 1].planStart - 0) {
// 开始时间大等于列表的最后一个 插入最后
oldTasks.splice(-1, 0, res);
} else {
// 判断开始时间在列表中间的哪个位置
for (let i = 0; i < oldTasks.length; i++) {
const item = oldTasks[i];
if (res.planStart - 0 > item.planStart - 0) {
if (res.planStart - 0 <= oldTasks[i + 1].planStart - 0) {
oldTasks.splice(i + 1, 0, res);
// console.log('res: ', res);
// return;
}
}
}
}
// TODO: 不能全更新
console.log('oldTasks: ', oldTasks);
this.updateTasks([...oldTasks]);
const params = { roleId: this.roleId, projectId: this.projectId };
this.getPermanent(params);
},
},
};
</script>
<style lang="scss" scoped>
.form {
display: flex;
flex-direction: column;
width: 100%;
max-height: 400px;
overflow-y: scroll;
}
.drop-item {
border-bottom: 1px solid #f1f1f1;
padding: 16rpx;
}
::v-deep.u-input--border {
border: none;
border-radius: 0;
}
::v-deep.u-dropdown__menu__item > uni-view {
border: none !important;
padding: 5px;
}
.u-input {
border-bottom: 1px solid #dcdfe6;
}
.new-projects-box {
margin-top: 20px;
padding: 15px;
width: 100%;
overflow: hidden;
}
.w {
width: 300px;
height: 39px;
}
::v-deep .u-dropdown__menu__item .u-flex {
border: 0 !important;
border-bottom: 1px solid #dcdfe6 !important;
padding: 0 20rpx;
}
</style>