整合前端
This commit is contained in:
919
ruoyi-ui/src/views/oa/task/allocation/index.vue
Normal file
919
ruoyi-ui/src/views/oa/task/allocation/index.vue
Normal file
@@ -0,0 +1,919 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-form :model="queryParams" ref="queryFormProject" size="small" :inline="true" label-width="90px">
|
||||
<el-form-item label="项目名称" prop="projectName">
|
||||
<el-input v-model="queryParams.projectName" placeholder="请输入项目名称" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="项目编号" prop="projectNum">
|
||||
<el-input v-model="queryParams.projectNum" placeholder="请输入项目编号" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="项目代号" prop="projectCode">
|
||||
<el-input v-model="queryParams.projectCode" placeholder="请输入项目代号" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="发起人姓名" prop="createUserNickName">
|
||||
<el-input v-model="queryParams.createUserNickName" placeholder="请输入发起人姓名" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="执行人姓名" prop="createUserNickName">
|
||||
<el-input v-model="queryParams.workerNickName" placeholder="请输入执行人姓名" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="日期范围">
|
||||
<el-date-picker v-model="queryParams.searchTime" type="daterange" value-format="yyyy-MM-dd"
|
||||
start-placeholder="开始日期" end-placeholder="结束日期" :default-time="['00:00:00', '23:59:59']">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd">新增任务
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple" @click="handleDelete">删除
|
||||
</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-alert type="info">
|
||||
<span @click="gotoPurchase" style="cursor: pointer;">如要发放采购相关需求请移步采购需求管理(点击此处快速跳转)</span>
|
||||
</el-alert>
|
||||
|
||||
<el-row :gutter="20" v-loading="loading">
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="6" v-for="item in taskList" :key="item.taskId">
|
||||
<el-card class="task-card" shadow="hover" @click.native="handleLookTask(item)">
|
||||
<!-- 卡片头部 -->
|
||||
<template slot="header">
|
||||
<div class="card-header">
|
||||
<!-- 第一行:任务标题和优先级 -->
|
||||
<div class="header-row">
|
||||
<div class="task-title">{{ item.taskTitle }}</div>
|
||||
<div class="task-priority">
|
||||
<el-tag v-if="item.taskGrade === '2'" type="danger">紧急</el-tag>
|
||||
<el-tag v-else-if="item.taskGrade === '1'" type="warning">中等</el-tag>
|
||||
<el-tag v-else-if="item.taskGrade === '0'" type="info">一般</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 第二行:任务状态和任务时间 -->
|
||||
<div class="header-row">
|
||||
<div class="task-status">
|
||||
<el-tag v-if="item.state === 2" type="success">执行完成</el-tag>
|
||||
<el-tag v-else-if="item.state === 1" type="warning">待验收</el-tag>
|
||||
<el-tag v-else-if="item.overDays > 0" type="danger">逾期{{ Math.abs(item.overDays) }}天</el-tag>
|
||||
<el-tag v-else type="info">剩余{{ Math.abs(item.overDays) }}天</el-tag>
|
||||
</div>
|
||||
<div class="task-time">
|
||||
<el-tag type="info" size="small">{{ parseTime(item.beginTime, '{y}-{m}-{d}') }} 至 {{
|
||||
parseTime(item.finishTime, '{y}-{m}-{d}') }}</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 卡片内容 -->
|
||||
<div class="card-content">
|
||||
<!-- 项目信息 -->
|
||||
<div class="info-item">
|
||||
<span class="info-label">项目名称:</span>
|
||||
<el-tag v-if="item.projectName === null" type="info">未关联项目</el-tag>
|
||||
<span v-else>{{ item.projectName }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">项目代号:</span>
|
||||
<el-tag v-if="item.projectCode == null" type="info">无</el-tag>
|
||||
<el-tag v-else type="primary">{{ item.projectCode }}</el-tag>
|
||||
</div>
|
||||
|
||||
<!-- 任务信息 -->
|
||||
<div class="info-item">
|
||||
<span class="info-label">发起人:</span>
|
||||
<span>{{ item.createUserNickName }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">执行人:</span>
|
||||
<div v-if="item.workerId === null">
|
||||
<el-button type="text" size="mini" @click="visible = true">点击发放任务</el-button>
|
||||
</div>
|
||||
<span v-else>{{ item.workerNickName }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 卡片底部操作按钮 -->
|
||||
<div class="card-footer">
|
||||
<el-button size="mini" type="text" v-if="item.taskRank === 0" icon="el-icon-copy-document"
|
||||
@click.stop="handleRank(item, 1)">置顶</el-button>
|
||||
<el-button size="mini" type="text" v-if="item.taskRank === 1" icon="el-icon-copy-document"
|
||||
@click.stop="handleRank(item, 0)">取消置顶</el-button>
|
||||
<el-button size="mini" type="text" icon="el-icon-copy-document"
|
||||
@click.stop="handleUpdate(item)">修改</el-button>
|
||||
<el-button size="mini" type="text" icon="el-icon-delete" @click.stop="handleDelete(item)">删除</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
|
||||
@pagination="getList" />
|
||||
|
||||
<!-- 添加或修改任务管理对话框 -->
|
||||
<el-dialog :title="title" :visible.sync="open" width="70%" append-to-body>
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="110px">
|
||||
<el-row>
|
||||
<el-row>
|
||||
<el-col :span="16">
|
||||
<el-form-item label="任务主题" prop="taskTitle">
|
||||
<el-input v-model="form.taskTitle" placeholder="请输入任务主题" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="工作类型" prop="taskType">
|
||||
<el-select v-model="form.taskType" placeholder="请选择工作类型">
|
||||
<el-option v-for="dict in dict.type.sys_work_type" :key="dict.value" :label="dict.label"
|
||||
:value="dict.value"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-col :span="16">
|
||||
<el-form-item label="任务时间">
|
||||
<el-col :span="11">
|
||||
<el-form-item prop="beginTime">
|
||||
<el-date-picker clearable v-model="form.beginTime" type="datetime" value-format="yyyy-MM-dd hh:mm:ss"
|
||||
placeholder="请选择开始时间">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="2" v-if="form.status === 0">至</el-col>
|
||||
<el-col :span="11">
|
||||
<el-form-item prop="finishTime" v-if="form.status === 0">
|
||||
<el-date-picker clearable v-model="form.finishTime" type="datetime" value-format="yyyy-MM-dd hh:mm:ss"
|
||||
placeholder="请选择结束时间">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="优先级" prop="taskGrade">
|
||||
<el-radio-group v-model="form.taskGrade">
|
||||
<el-radio v-for="dict in dict.type.sys_sort_grade" :key="dict.value" :label="dict.value">{{ dict.label
|
||||
}}
|
||||
</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="关联项目" prop="projectId">
|
||||
<project-select v-model="form.projectId" style="width: 100%;" adjustable />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="12" v-loading="trackLoading">
|
||||
<el-form-item label="项目进度" prop="trackId">
|
||||
<el-cascader v-if="trackOptions" v-model="form.trackId" :options="trackOptions" :props="cascaderProps"
|
||||
style="width: 100%;" placeholder="请选择" clearable></el-cascader>
|
||||
<div v-else>该项目未设置项目进度或未选择项目</div>
|
||||
<!-- <track-select v-model="form.trackId" style="width: 100%;" /> -->
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="14">
|
||||
<el-form-item label="执行人" prop="workerIds">
|
||||
<div style="display: flex; align-items: center;">
|
||||
<el-tooltip content="请选择执行人, 多选执行人后第一个指定人会作为负责人,其他被选中的人员作为协助者" placement="top">
|
||||
<el-icon class="el-icon-question"></el-icon>
|
||||
</el-tooltip>
|
||||
<user-select v-model="form.workerIds" :disabled="!!form.taskId" />
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="详细描述">
|
||||
<editor v-model="form.content" :min-height="192" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="附件" prop="accessory">
|
||||
<file-upload v-model="form.accessory" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<!--查看弹出层-->
|
||||
<el-dialog title="任务详情" :visible.sync="openLook" width="70%" center>
|
||||
<div class="task-detail-container">
|
||||
<el-descriptions class="task-descriptions" :column="2" border>
|
||||
<!-- 基本信息 -->
|
||||
<el-descriptions-item :labelStyle="lableBg">
|
||||
<template slot="label">
|
||||
<i class="el-icon-user"></i>
|
||||
任务主题
|
||||
</template>
|
||||
<span class="task-title">{{ form.taskTitle }}</span>
|
||||
</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item :labelStyle="lableBg">
|
||||
<template slot="label">
|
||||
<i class="el-icon-s-unfold"></i>
|
||||
工作类型
|
||||
</template>
|
||||
<dict-tag :options="dict.type.sys_work_type" :value="form.taskType" />
|
||||
</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item :labelStyle="lableBg">
|
||||
<template slot="label">
|
||||
<i class="el-icon-s-unfold"></i>
|
||||
优先级
|
||||
</template>
|
||||
<dict-tag :options="dict.type.sys_sort_grade" :value="form.taskGrade" />
|
||||
</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item :labelStyle="lableBg">
|
||||
<template slot="label">
|
||||
<i class="el-icon-s-unfold"></i>
|
||||
任务状态
|
||||
</template>
|
||||
<el-tag v-if="form.state === 2" type="success">执行完成</el-tag>
|
||||
<el-tag v-else-if="form.state === 1" type="warning">待验收</el-tag>
|
||||
<el-tag v-else-if="form.overDays > 0" type="danger">逾期{{ Math.abs(form.overDays) }}天</el-tag>
|
||||
<el-tag v-else type="info">剩余{{ Math.abs(form.overDays) }}天</el-tag>
|
||||
</el-descriptions-item>
|
||||
|
||||
<!-- 项目信息 -->
|
||||
<el-descriptions-item :labelStyle="lableBg">
|
||||
<template slot="label">
|
||||
<i class="el-icon-s-unfold"></i>
|
||||
项目名称
|
||||
</template>
|
||||
<span>{{ form.projectName || '未关联项目' }}</span>
|
||||
</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item :labelStyle="lableBg">
|
||||
<template slot="label">
|
||||
<i class="el-icon-s-unfold"></i>
|
||||
项目代号
|
||||
</template>
|
||||
<el-tag v-if="form.projectCode" type="primary">{{ form.projectCode }}</el-tag>
|
||||
<el-tag v-else type="info">无</el-tag>
|
||||
</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item :labelStyle="lableBg">
|
||||
<template slot="label">
|
||||
<i class="el-icon-s-unfold"></i>
|
||||
项目进度
|
||||
</template>
|
||||
<span>{{ form.secondLevelNode ? form.tabNode + ' / ' + form.firstLevelNode + ' / ' + form.secondLevelNode :
|
||||
'-'
|
||||
}}</span>
|
||||
</el-descriptions-item>
|
||||
|
||||
<!-- 人员信息 -->
|
||||
<el-descriptions-item :labelStyle="lableBg">
|
||||
<template slot="label">
|
||||
<i class="el-icon-s-unfold"></i>
|
||||
发起人
|
||||
</template>
|
||||
<span>{{ form.createUserNickName }}</span>
|
||||
</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item :labelStyle="lableBg">
|
||||
<template slot="label">
|
||||
<i class="el-icon-s-unfold"></i>
|
||||
执行人
|
||||
</template>
|
||||
<span>{{ form.workerNickName || '未分配' }}</span>
|
||||
</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item :labelStyle="lableBg">
|
||||
<template slot="label">
|
||||
<i class="el-icon-s-unfold"></i>
|
||||
协同人员
|
||||
</template>
|
||||
<span>{{ form.collaborator || '无' }}</span>
|
||||
</el-descriptions-item>
|
||||
|
||||
<!-- 时间信息 -->
|
||||
<el-descriptions-item :labelStyle="lableBg">
|
||||
<template slot="label">
|
||||
<i class="el-icon-s-unfold"></i>
|
||||
任务时间
|
||||
</template>
|
||||
<span>{{ parseTime(form.beginTime, '{y}-{m}-{d}') }} 至 {{ parseTime(form.finishTime, '{y}-{m}-{d}')
|
||||
}}</span>
|
||||
</el-descriptions-item>
|
||||
|
||||
<!-- 详细内容 -->
|
||||
<el-descriptions-item span="2" :labelStyle="lableBg">
|
||||
<template slot="label">
|
||||
<i class="el-icon-s-unfold"></i>
|
||||
工作内容
|
||||
</template>
|
||||
<div class="content-box">
|
||||
<div v-if="form.content" v-html="form.content"></div>
|
||||
<div v-else class="empty-content">暂无工作内容</div>
|
||||
</div>
|
||||
</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item span="2" :labelStyle="lableBg">
|
||||
<template slot="label">
|
||||
<i class="el-icon-s-unfold"></i>
|
||||
备注
|
||||
</template>
|
||||
<div class="content-box">
|
||||
<div v-if="form.remark" v-html="form.remark"></div>
|
||||
<div v-else class="empty-content">暂无备注</div>
|
||||
</div>
|
||||
</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item span="2" :labelStyle="lableBg">
|
||||
<template slot="label">
|
||||
<i class="el-icon-s-unfold"></i>
|
||||
附件
|
||||
</template>
|
||||
<div class="attachment-box">
|
||||
<div v-if="form.accessory" class="attachment-item">
|
||||
<el-link :href="form.accessory" :underline="false" target="_blank">
|
||||
<i class="el-icon-document"></i> 查看附件
|
||||
</el-link>
|
||||
</div>
|
||||
<div v-else class="no-attachment">暂无附件...</div>
|
||||
</div>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listProjectSchedule } from "@/api/oa/projectSchedule";
|
||||
import { listPage } from "@/api/oa/projectScheduleStep";
|
||||
import { addTask, delTask, getTask, listTask, updateTask } from "@/api/oa/task";
|
||||
import { deptTreeSelect, selectUser } from "@/api/system/user";
|
||||
import UserSelect from "@/components/UserSelect";
|
||||
import ProjectSelect from "@/components/fad-service/ProjectSelect";
|
||||
|
||||
|
||||
export default {
|
||||
name: "Task",
|
||||
components: {
|
||||
UserSelect,
|
||||
ProjectSelect
|
||||
},
|
||||
dicts: ['sys_project_type', 'sys_project_status', 'sys_work_type', 'sys_sort_grade'],
|
||||
data () {
|
||||
return {
|
||||
//项目id
|
||||
projectId: '',
|
||||
projectName: '',
|
||||
// 项目总条数
|
||||
total: 0,
|
||||
taskTotal: 0,
|
||||
deptName: null,
|
||||
// 遮罩层
|
||||
loading: true,
|
||||
//搜索日期范围
|
||||
searchTime: [],
|
||||
//任务弹出层标题
|
||||
titleDialog: '',
|
||||
//任务管理弹出层
|
||||
taskDialog: false,
|
||||
visible: false,
|
||||
// 任务管理表格数据
|
||||
taskList: [],
|
||||
deptProps: {
|
||||
children: "children",
|
||||
label: "label"
|
||||
},
|
||||
//任务表单
|
||||
form: {},
|
||||
// 按钮loading
|
||||
buttonLoading: false,
|
||||
// 任务修改弹出层
|
||||
open: false,
|
||||
//查看弹出层
|
||||
openLook: false,
|
||||
//附件
|
||||
fileList: [],
|
||||
//详情lable背景
|
||||
lableBg: "background: #f0f9eb; width:150px; text-align: center;",
|
||||
//任务弹出层标题
|
||||
title: '',
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
searchTime: [],
|
||||
},
|
||||
userList: [],
|
||||
// 非多个禁用
|
||||
multiple: true,
|
||||
userMultipleSelection: [],
|
||||
deptOptions: [],
|
||||
userParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
},
|
||||
userLoading: false,
|
||||
copyUser: [],
|
||||
rules: {
|
||||
workerIds: [
|
||||
{ required: true, message: "任务执行者不能为空", trigger: "blur" },
|
||||
],
|
||||
},
|
||||
trackOptions: null,
|
||||
cascaderProps: {
|
||||
checkStrictly: false, // 严格检查模式(父子节点不关联)
|
||||
label: 'label', // 显示的文本字段
|
||||
value: 'value', // 实际的值字段
|
||||
children: 'children', // 子节点字段
|
||||
// 判断是否禁用(前两级禁用,第三级启用)
|
||||
disabled: (data) => {
|
||||
// 第三级没有children,以此判断层级
|
||||
return !!data.children;
|
||||
}
|
||||
},
|
||||
trackLoading: false,
|
||||
};
|
||||
|
||||
},
|
||||
created () {
|
||||
this.getList();
|
||||
this.getTreeSelect();
|
||||
this.getUserList();
|
||||
},
|
||||
watch: {
|
||||
'form.projectId': {
|
||||
handler (val) {
|
||||
this.form.trackId = undefined;
|
||||
if (val) {
|
||||
this.trackLoading = true;
|
||||
listProjectSchedule({ projectId: val })
|
||||
.then(res => {
|
||||
if (res.rows && res.rows.length > 0) {
|
||||
// 有数据,返回scheduleId继续执行
|
||||
return res.rows[0].scheduleId;
|
||||
} else {
|
||||
// 无数据,设置trackOptions并返回拒绝状态的Promise,阻止后续执行
|
||||
this.trackOptions = null;
|
||||
this.trackLoading = false; // 这里也要停止加载状态
|
||||
return Promise.reject('无项目计划数据'); // 关键:拒绝后续执行
|
||||
}
|
||||
})
|
||||
.then(scheduleId => {
|
||||
if (scheduleId) {
|
||||
// 有scheduleId,继续调用listPage
|
||||
return listPage({ scheduleId: scheduleId, pageSize: 9999, pageNum: 1 });
|
||||
} else {
|
||||
// 无scheduleId,返回拒绝状态的Promise
|
||||
this.trackLoading = false;
|
||||
return Promise.reject('无有效的scheduleId');
|
||||
}
|
||||
})
|
||||
.then(res => {
|
||||
// 只有前面都成功,才会执行到这里
|
||||
this.trackOptions = this.convertToCascader(res.rows);
|
||||
this.trackLoading = false;
|
||||
})
|
||||
.catch(err => {
|
||||
// 捕获前面所有的拒绝状态,避免控制台报错(可选,根据需要处理错误)
|
||||
console.log('流程终止:', err);
|
||||
// 确保加载状态关闭(兜底)
|
||||
this.trackLoading = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 转换数据为级联选择器格式
|
||||
convertToCascader (rows) {
|
||||
if (!rows || !rows.length) return [];
|
||||
|
||||
// 第一级分组:按tabNode
|
||||
const firstLevelMap = new Map();
|
||||
rows.forEach(item => {
|
||||
const tabNode = item.tabNode;
|
||||
if (!firstLevelMap.has(tabNode)) {
|
||||
firstLevelMap.set(tabNode, {
|
||||
label: tabNode,
|
||||
value: tabNode, // 第一级值可用tabNode(非必须,因不可选)
|
||||
children: []
|
||||
});
|
||||
}
|
||||
|
||||
// 第二级分组:按firstLevelNode
|
||||
const firstLevelItem = firstLevelMap.get(tabNode);
|
||||
const secondLevelMap = new Map();
|
||||
firstLevelItem.children.forEach(secondItem => {
|
||||
secondLevelMap.set(secondItem.label, secondItem);
|
||||
});
|
||||
|
||||
const firstLevelNode = item.firstLevelNode;
|
||||
if (!secondLevelMap.has(firstLevelNode)) {
|
||||
const secondLevelItem = {
|
||||
label: firstLevelNode,
|
||||
value: firstLevelNode, // 第二级值可用firstLevelNode(非必须,因不可选)
|
||||
children: []
|
||||
};
|
||||
firstLevelItem.children.push(secondLevelItem);
|
||||
secondLevelMap.set(firstLevelNode, secondLevelItem);
|
||||
}
|
||||
|
||||
// 第三级:secondLevelNode(可选项)
|
||||
const secondLevelItem = secondLevelMap.get(firstLevelNode);
|
||||
secondLevelItem.children.push({
|
||||
label: item.secondLevelNode,
|
||||
value: item.trackId, // 第三级值为trackId
|
||||
children: null // 标记为第三级(无children)
|
||||
});
|
||||
});
|
||||
|
||||
// 转换为数组格式
|
||||
return Array.from(firstLevelMap.values());
|
||||
},
|
||||
gotoPurchase () {
|
||||
this.$router.push({ path: '/hint/requirement' });
|
||||
},
|
||||
// 单选矿变化
|
||||
handChange () {
|
||||
if (this.form.status === 1) {
|
||||
this.form.timeGap = 3
|
||||
} else {
|
||||
this.form.timeGap = null;
|
||||
}
|
||||
},
|
||||
|
||||
handleClose (tag) {
|
||||
let userObj = this.userMultipleSelection.find(item => item.userId === tag.id);
|
||||
this.userMultipleSelection.splice(this.userMultipleSelection.indexOf(userObj), 1);
|
||||
this.copyUser = this.userMultipleSelection;
|
||||
// 设置抄送人ID
|
||||
if (this.copyUser && this.copyUser.length > 0) {
|
||||
const val = this.copyUser.map(item => item.id);
|
||||
this.form.workerIds = val instanceof Array ? val.join(',') : val;
|
||||
} else {
|
||||
this.form.workerIds = '';
|
||||
}
|
||||
},
|
||||
|
||||
submitUserData () {
|
||||
this.visible = false;
|
||||
if (!this.userMultipleSelection || this.userMultipleSelection.length <= 0) {
|
||||
this.$modal.msgError("请选择用户");
|
||||
return false;
|
||||
}
|
||||
let userIds = this.userMultipleSelection.map(k => k.userId);
|
||||
this.copyUser = this.userMultipleSelection;
|
||||
this.form.workerIds = userIds instanceof Array ? userIds.join(',') : userIds;
|
||||
this.form.workerId = userIds instanceof Array ? userIds.join(',') : userIds;
|
||||
},
|
||||
|
||||
changeCurrentUser (val) {
|
||||
this.currentUserId = val.userId
|
||||
},
|
||||
|
||||
handleSelectionChange (selection) {
|
||||
this.userMultipleSelection = selection
|
||||
},
|
||||
|
||||
// 节点单击事件
|
||||
handleNodeClick (data) {
|
||||
this.userParams.deptId = data.id;
|
||||
this.getUserList();
|
||||
},
|
||||
filterNode (value, data) {
|
||||
if (!value) return true;
|
||||
return data.label.indexOf(value) !== -1;
|
||||
},
|
||||
/** 查询部门下拉树结构 */
|
||||
getTreeSelect () {
|
||||
deptTreeSelect().then(response => {
|
||||
this.deptOptions = response.data;
|
||||
});
|
||||
},
|
||||
getUserList () {
|
||||
this.userLoading = true
|
||||
selectUser(this.userParams).then(response => {
|
||||
this.userList = response.rows;
|
||||
this.userLoading = false;
|
||||
});
|
||||
},
|
||||
/** 查询项目管理列表 */
|
||||
getList () {
|
||||
this.loading = true;
|
||||
const payload = {
|
||||
...this.queryParams,
|
||||
beginTime: this.queryParams.searchTime[0] ? this.queryParams.searchTime[0] + ' 00:00:00' : undefined,
|
||||
finishTime: this.queryParams.searchTime[1] ? this.queryParams.searchTime[1] + ' 23:59:59' : undefined
|
||||
}
|
||||
console.log(payload, this.queryParams, 'payload');
|
||||
listTask(payload).then(response => {
|
||||
this.taskList = response.rows;
|
||||
this.total = response.total;
|
||||
this.loading = false;
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
/** 任务搜索按钮操作 */
|
||||
handleQuery () {
|
||||
this.queryParams.pageNum = 1;
|
||||
this.getList();
|
||||
},
|
||||
|
||||
/**查看任务**/
|
||||
handleLookTask (row) {
|
||||
this.loading = true;
|
||||
this.reset();
|
||||
const taskId = row.taskId || this.ids
|
||||
getTask(taskId).then(response => {
|
||||
this.loading = false;
|
||||
this.form = response.data;
|
||||
// this.getFile(response.data.accessory)
|
||||
this.openLook = true;
|
||||
this.title = "查看任务";
|
||||
});
|
||||
},
|
||||
|
||||
/** 处理置顶 */
|
||||
handleRank (row, rank) {
|
||||
this.loading = true;
|
||||
row.taskRank = rank;
|
||||
updateTask(row).then(response => {
|
||||
this.$modal.msgSuccess("操作成功")
|
||||
this.getList();
|
||||
})
|
||||
},
|
||||
/** 修改按钮操作 */
|
||||
handleUpdate (row) {
|
||||
this.loading = true;
|
||||
this.reset();
|
||||
const taskId = row.taskId || this.ids
|
||||
getTask(taskId).then(response => {
|
||||
this.loading = false;
|
||||
this.form = response.data;
|
||||
this.open = true;
|
||||
this.title = "修改任务";
|
||||
});
|
||||
},
|
||||
|
||||
handleAdd () {
|
||||
this.reset();
|
||||
this.open = true;
|
||||
this.title = "新增任务";
|
||||
|
||||
},
|
||||
|
||||
// 取消按钮
|
||||
cancel () {
|
||||
this.open = false;
|
||||
this.reset();
|
||||
},
|
||||
submitForm () {
|
||||
const payload = {
|
||||
...this.form,
|
||||
trackId: this.form.trackId ? this.form.trackId[2] : undefined,
|
||||
}
|
||||
if (!this.form.taskId) {
|
||||
const workers = this.form.workerIds.split(',')
|
||||
payload.workerIds = workers[0]
|
||||
payload.collaborator = workers.slice(1).length > 0 ? workers.slice(1).join(',') : ''
|
||||
}
|
||||
if (this.form.taskId) {
|
||||
updateTask(payload).then(response => {
|
||||
this.open = false;
|
||||
this.getList();
|
||||
this.$modal.msgSuccess("修改成功")
|
||||
})
|
||||
} else {
|
||||
this.$refs["form"].validate(valid => {
|
||||
if (valid) {
|
||||
addTask(payload).then(response => {
|
||||
this.open = false;
|
||||
this.getList();
|
||||
this.$modal.msgSuccess("添加成功")
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
// 表单重置
|
||||
reset () {
|
||||
this.form = {
|
||||
status: 0
|
||||
};
|
||||
this.resetForm("form");
|
||||
this.fileList = [];
|
||||
},
|
||||
/** 删除按钮操作 */
|
||||
handleDelete (row) {
|
||||
const taskIds = row.taskId || this.ids;
|
||||
this.$modal.confirm('是否确认删除任务管理编号为"' + taskIds + '"的数据项?').then(() => {
|
||||
this.loading = true;
|
||||
return delTask(taskIds);
|
||||
}).then(() => {
|
||||
this.loading = false;
|
||||
this.getList();
|
||||
this.$modal.msgSuccess("删除成功");
|
||||
}).catch(() => {
|
||||
}).finally(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
|
||||
},
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.task-card {
|
||||
margin-bottom: 20px;
|
||||
height: 320px;
|
||||
/* 固定卡片高度 */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.header-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.task-title {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
flex: 1;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.task-priority {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.task-status {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.task-time {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.card-content {
|
||||
padding: 10px 0;
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.info-item {
|
||||
margin-bottom: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: nowrap;
|
||||
/* 禁止换行 */
|
||||
}
|
||||
|
||||
.info-label {
|
||||
color: #606266;
|
||||
font-size: 14px;
|
||||
margin-right: 5px;
|
||||
min-width: 80px;
|
||||
white-space: nowrap;
|
||||
/* 禁止换行 */
|
||||
}
|
||||
|
||||
.info-item span:not(.info-label) {
|
||||
white-space: nowrap;
|
||||
/* 禁止项目名称等内容换行 */
|
||||
overflow: hidden;
|
||||
/* 超出部分隐藏 */
|
||||
text-overflow: ellipsis;
|
||||
/* 显示省略号 */
|
||||
flex: 1;
|
||||
/* 占据剩余空间 */
|
||||
}
|
||||
|
||||
.card-footer {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
/* 按钮左对齐 */
|
||||
align-items: center;
|
||||
border-top: 1px solid #ebeef5;
|
||||
padding-top: 10px;
|
||||
margin-top: 10px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.card-footer .el-button {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
/* 响应式调整 */
|
||||
@media (max-width: 768px) {
|
||||
.task-card {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.header-row {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.info-item {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.info-label {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 任务详情弹窗样式 */
|
||||
.task-detail-container {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.task-descriptions {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.task-descriptions .el-descriptions__label {
|
||||
font-weight: bold;
|
||||
background-color: #f0f9eb;
|
||||
text-align: center;
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
.task-title {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.content-box {
|
||||
padding: 10px;
|
||||
background-color: #fafafa;
|
||||
border-radius: 4px;
|
||||
min-height: 100px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.attachment-box {
|
||||
padding: 10px;
|
||||
background-color: #fafafa;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.attachment-item {
|
||||
margin-bottom: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.attachment-item i {
|
||||
margin-right: 5px;
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
.no-attachment {
|
||||
color: #909399;
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.dialog-footer {
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user