整合前端

This commit is contained in:
砂糖
2026-04-13 17:04:38 +08:00
parent 69609a2cb1
commit 5d4794c9bd
915 changed files with 144259 additions and 0 deletions

View 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>