Compare commits

..

No commits in common. "9bfc033b41b9e0ae23baf4de0487a7823f2cdfc4" and "6685ba8d3ab92013dc2646a338f4bfc1bba61908" have entirely different histories.

5 changed files with 92 additions and 128 deletions

View File

@ -167,7 +167,7 @@ export const systemRoutes: RouteRecordRaw[] = [
component: () => import('@/views/task/task-gantt/TaskGantt.vue'),
meta: {
title: '人力甘特图',
icon: 'eye', // 进度相关图标
icon: 'workload', // 进度相关图标
hidden: false,
sort: 3.6
}

View File

@ -194,7 +194,7 @@ const initChart = (personIndex: number) => {
const categoryIndex = api.value(3);
const startCoord = api.coord([api.value(0), categoryIndex]);
const endCoord = api.coord([api.value(1), categoryIndex]);
const barHeight = 40;
const barHeight = 20;
return {
type: "rect",
shape: {
@ -220,7 +220,7 @@ const initChart = (personIndex: number) => {
const categoryIndex = api.value(3);
const startCoord = api.coord([api.value(0), categoryIndex]);
const endCoord = api.coord([api.value(1), categoryIndex]);
const barHeight = 40;
const barHeight = 12;
return {
type: "rect",
shape: {

View File

@ -19,7 +19,7 @@
@click="handleStatClick('low')"
:class="{ 'active': searchForm.priority === 'low' }"
>
<div class="stat-text">不重要不紧急</div>
<div class="stat-text">低优先级</div>
<div class="stat-number">{{ priorityStats.low }}</div>
</div>
<div
@ -27,7 +27,7 @@
@click="handleStatClick('medium')"
:class="{ 'active': searchForm.priority === 'medium' }"
>
<div class="stat-text">重要不紧急</div>
<div class="stat-text">中优先级</div>
<div class="stat-number">{{ priorityStats.medium }}</div>
</div>
<div
@ -35,7 +35,7 @@
@click="handleStatClick('high')"
:class="{ 'active': searchForm.priority === 'high' }"
>
<div class="stat-text">紧急不重要</div>
<div class="stat-text">高优先级</div>
<div class="stat-number">{{ priorityStats.high }}</div>
</div>
<div
@ -43,7 +43,7 @@
@click="handleStatClick('urgent')"
:class="{ 'active': searchForm.priority === 'urgent' }"
>
<div class="stat-text">重要紧急</div>
<div class="stat-text">紧急</div>
<div class="stat-number">{{ priorityStats.urgent }}</div>
</div>
</div>
@ -52,6 +52,10 @@
<div class="history-tasks">
<div class="table-controls">
<h3>历史任务</h3>
<!-- <div class="table-actions">
<button class="refresh-btn" @click="resetSearch">刷新</button>
<button class="export-btn">导出</button>
</div> -->
</div>
<!-- 搜索区域 -->
@ -70,10 +74,10 @@
<label>优先级:</label>
<select v-model="searchForm.priority" class="search-select">
<option value="">全部</option>
<option value="low">不重要不紧急</option>
<option value="medium">重要不紧急</option>
<option value="high">紧急不重要</option>
<option value="urgent">重要紧急</option>
<option value="low"></option>
<option value="medium"></option>
<option value="high"></option>
<option value="urgent">紧急</option>
</select>
</div>
<div class="search-item">
@ -130,9 +134,8 @@
<td><span class="priority-tag" :class="task.priority">{{ getPriorityText(task.priority) }}</span></td>
<td><span class="task-status" :class="task.status">{{ task.statusText }}</span></td>
<td class="operation-btns">
<button class="operate-btn" @click="handleView(task)">查看</button>
<button class="operate-btn" @click="handleEdit(task)">编辑</button>
<button class="operate-btn" @click="handleDelete(task.id)">删除</button>
<button class="operate-btn">查看</button>
<button class="operate-btn">编辑</button>
</td>
</tr>
<tr v-if="filteredTasks.length === 0">
@ -163,34 +166,6 @@
</div>
</div>
</div>
<!-- 查看/编辑任务弹窗居中表单只读/可编辑 -->
<div class="modal-overlay" v-if="showTaskModal" @click.self="showTaskModal = false">
<div class="publish-modal">
<button class="modal-close" @click="showTaskModal = false">
<i class="icon-close"></i>
</button>
<h3>{{ taskModalMode === 'view' ? '查看任务' : '编辑任务' }}</h3>
<div class="modal-content" style="display: block;">
<div style="margin-bottom: 10px;">
<label>任务名称:</label>
<input type="text" v-model="currentTask.title" :disabled="taskModalMode === 'view'" class="search-input">
</div>
<div style="margin-bottom: 10px;">
<label>任务描述:</label>
<textarea v-model="currentTask.description" :disabled="taskModalMode === 'view'" class="search-input" style="width: 100%; height: 80px;"></textarea>
</div>
<div style="margin-bottom: 10px;">
<label>截止日期:</label>
<input type="date" v-model="currentTask.dueDate" :disabled="taskModalMode === 'view'" class="search-input">
</div>
</div>
<div class="modal-actions">
<button class="cancel-btn" @click="showTaskModal = false">关闭</button>
<button v-if="taskModalMode === 'edit'" class="submit-btn" @click="handleSaveTask">保存</button>
</div>
</div>
</div>
</div>
</GiPageLayout>
</template>
@ -198,20 +173,14 @@
<script setup lang="ts">
import { ref, computed } from 'vue';
import { useRouter } from 'vue-router';
import { Message, Modal } from '@arco-design/web-vue';
import { Message } from '@arco-design/web-vue';
import TaskForm from './components/TaskForm.vue';
import AssigneeSelector from './components/AssigneeSelector.vue';
const taskFormRef = ref<InstanceType<typeof TaskForm> | null>(null);
const assigneeRef = ref<InstanceType<typeof AssigneeSelector> | null>(null);
const router = useRouter();
const showPublishModal = ref(false);
// /
const showTaskModal = ref(false);
const taskModalMode = ref<'view' | 'edit'>('view');
const currentTask = ref<any>({});
//
const historyTasks = ref([
{
@ -265,39 +234,62 @@ const searchForm = ref({
//
const filteredTasks = computed(() => {
return historyTasks.value.filter(task => {
if (searchForm.value.name && !task.title.includes(searchForm.value.name)) return false;
if (searchForm.value.priority && task.priority !== searchForm.value.priority) return false;
if (searchForm.value.publisher && task.publisher !== searchForm.value.publisher) return false;
if (searchForm.value.assignee && task.assignee !== searchForm.value.assignee) return false;
if (searchForm.value.startDate && task.publishDate < searchForm.value.startDate) return false;
if (searchForm.value.endDate && task.publishDate > searchForm.value.endDate) return false;
//
if (searchForm.value.name && !task.title.includes(searchForm.value.name)) {
return false;
}
//
if (searchForm.value.priority && task.priority !== searchForm.value.priority) {
return false;
}
//
if (searchForm.value.publisher && task.publisher !== searchForm.value.publisher) {
return false;
}
//
if (searchForm.value.assignee && task.assignee !== searchForm.value.assignee) {
return false;
}
//
if (searchForm.value.startDate && task.publishDate < searchForm.value.startDate) {
return false;
}
//
if (searchForm.value.endDate && task.publishDate > searchForm.value.endDate) {
return false;
}
return true;
});
});
//
const handleStatClick = (priority: string) => {
//
if (searchForm.value.priority === priority) {
searchForm.value.priority = '';
} else {
//
searchForm.value.priority = priority;
}
//
handleSearch();
};
// /
//
const allPublishers = computed(() => {
const publishers = new Set<string>();
historyTasks.value.forEach(task => publishers.add(task.publisher));
return Array.from(publishers);
});
//
const allAssignees = computed(() => {
const assignees = new Set<string>();
historyTasks.value.forEach(task => assignees.add(task.assignee));
return Array.from(assignees);
});
//
//
const priorityStats = computed(() => {
return {
low: historyTasks.value.filter(task => task.priority === 'low').length,
@ -307,22 +299,25 @@ const priorityStats = computed(() => {
};
});
//
//
const getPriorityText = (priority: string) => {
const map: Record<string, string> = {
low: '不重要不紧急',
medium: '重要不紧急',
high: '紧急不重要',
urgent: '重要紧急'
low: '',
medium: '',
high: '',
urgent: '紧急'
};
return map[priority] || '';
};
//
//
const handleSearch = () => {
console.log('搜索条件:', searchForm.value);
//
document.querySelector('.task-table')?.scrollIntoView({ behavior: 'smooth' });
};
//
const resetSearch = () => {
searchForm.value = {
name: '',
@ -334,7 +329,6 @@ const resetSearch = () => {
};
};
//
const handleSubmit = () => {
if (!taskFormRef.value?.form.taskName) {
Message.error('请填写任务名称');
@ -371,53 +365,6 @@ const handleSubmit = () => {
Message.success('任务发布成功!');
showPublishModal.value = false;
};
//
const handleView = (task: any) => {
currentTask.value = { ...task };
taskModalMode.value = 'view';
showTaskModal.value = true;
};
//
const handleEdit = (task: any) => {
currentTask.value = { ...task };
taskModalMode.value = 'edit';
showTaskModal.value = true;
};
// 使 Arco Modal.confirm
const handleDelete = (taskId: string) => {
Modal.confirm({
title: '确认删除',
content: '删除后将无法恢复,是否确认删除该任务?',
okText: '确认删除',
cancelText: '取消',
closable: true,
maskClosable: true,
onOk: () => {
historyTasks.value = historyTasks.value.filter(t => t.id !== taskId);
Message.success('任务已删除');
},
onCancel: () => {
Message.info('已取消删除');
}
});
};
//
const handleSaveTask = () => {
if (!currentTask.value.title) {
Message.error('任务名称不能为空');
return;
}
const index = historyTasks.value.findIndex(t => t.id === currentTask.value.id);
if (index !== -1) {
historyTasks.value[index] = { ...currentTask.value };
Message.success('任务更新成功');
showTaskModal.value = false;
}
};
</script>
<style scoped>
@ -638,6 +585,24 @@ h3 {
margin: 0;
}
/* .table-actions {
display: flex;
gap: 8px;
}
.refresh-btn, .export-btn {
padding: 4px 10px;
background-color: #fff;
border: 1px solid #d1d5db;
border-radius: 3px;
cursor: pointer;
font-size: 13px;
}
.refresh-btn:hover, .export-btn:hover {
background-color: #f3f4f6;
} */
.task-table {
width: 100%;
border-collapse: collapse;
@ -671,29 +636,26 @@ h3 {
padding: 2px 6px;
font-size: 12px;
border-radius: 2px;
font-weight: 500;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
color: #fff;
}
.priority-tag.low {
background-color: #4ade80;
background-image: linear-gradient(135deg, #4ade80 0%, #22c55e 100%);
background-color: #e2e8f0;
color: #475569;
}
.priority-tag.medium {
background-color: #3b82f6;
background-image: linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%);
background-color: #dbeafe;
color: #1e40af;
}
.priority-tag.high {
background-color: #f59e0b;
background-image: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);
background-color: #fef3c7;
color: #92400e;
}
.priority-tag.urgent {
background-color: #ef4444;
background-image: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
background-color: #fee2e2;
color: #b91c1c;
}
/* 状态标签样式 */
@ -826,4 +788,4 @@ h3 {
.submit-btn:hover {
background-color: #0663f8;
}
</style>
</style>

View File

@ -33,7 +33,9 @@
{{ user.name }}
</option>
</select>
</div>
</div>
</div>
</template>

View File

@ -60,10 +60,10 @@
<div class="form-group">
<label for="priority">优先级</label>
<select id="priority" v-model="form.priority">
<option value="low">不重要不紧急</option>
<option value="medium" selected>重要不紧急</option>
<option value="high">紧急不重要</option>
<option value="urgent">重要紧急</option>
<option value="low"></option>
<option value="medium" selected></option>
<option value="high"></option>
<option value="urgent">紧急</option>
</select>
</div>
</div>