feat(项目看板): 新增项目综合看板功能
新增项目综合看板功能,聚合展示项目、任务、进度主表和步骤数据
- 新增后端聚合接口 GET /oa/project/dashboard/{projectId}
- 新增前端看板页面,包含项目列表、任务表格和进度导图
- 优化思维导图组件,支持看板模式下的紧凑展示
- 新增进度明细表格视图和状态图例
- 实现任务与进度步骤的关联展示
- 添加项目模糊搜索功能
This commit is contained in:
121
ruoyi-ui/src/store/modules/oaProjectDashboard2.js
Normal file
121
ruoyi-ui/src/store/modules/oaProjectDashboard2.js
Normal file
@@ -0,0 +1,121 @@
|
||||
import { listProject, getProjectDashboard } from '@/api/oa/project'
|
||||
|
||||
function sleep (ms) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms))
|
||||
}
|
||||
|
||||
async function retry (fn, times, delayMs) {
|
||||
let lastErr
|
||||
for (let i = 0; i < times; i++) {
|
||||
try {
|
||||
return await fn()
|
||||
} catch (e) {
|
||||
lastErr = e
|
||||
if (i < times - 1) {
|
||||
await sleep(delayMs)
|
||||
}
|
||||
}
|
||||
}
|
||||
throw lastErr
|
||||
}
|
||||
|
||||
const state = {
|
||||
currentProjectId: '',
|
||||
|
||||
projectQuery: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
keyword: ''
|
||||
},
|
||||
projectList: [],
|
||||
projectTotal: 0,
|
||||
|
||||
projectDetail: null,
|
||||
taskList: [],
|
||||
scheduleList: [],
|
||||
stepList: [],
|
||||
|
||||
taskQuery: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
projectCode: '',
|
||||
taskKeyword: ''
|
||||
},
|
||||
|
||||
loading: false
|
||||
}
|
||||
|
||||
const mutations = {
|
||||
SET_LOADING (state, val) {
|
||||
state.loading = !!val
|
||||
},
|
||||
SET_CURRENT_PROJECT (state, projectId) {
|
||||
state.currentProjectId = projectId || ''
|
||||
},
|
||||
|
||||
SET_PROJECT_QUERY (state, payload) {
|
||||
state.projectQuery = { ...state.projectQuery, ...(payload || {}) }
|
||||
},
|
||||
SET_PROJECT_LIST (state, payload) {
|
||||
state.projectList = payload.rows || []
|
||||
state.projectTotal = payload.total || 0
|
||||
},
|
||||
|
||||
SET_DASHBOARD (state, payload) {
|
||||
const p = payload || {}
|
||||
state.projectDetail = p.project || null
|
||||
state.taskList = p.tasks || []
|
||||
state.scheduleList = p.schedules || []
|
||||
state.stepList = p.steps || []
|
||||
},
|
||||
|
||||
CLEAR_RIGHT (state) {
|
||||
state.projectDetail = null
|
||||
state.taskList = []
|
||||
state.scheduleList = []
|
||||
state.stepList = []
|
||||
},
|
||||
|
||||
SET_TASK_QUERY (state, payload) {
|
||||
state.taskQuery = { ...state.taskQuery, ...(payload || {}) }
|
||||
}
|
||||
}
|
||||
|
||||
const actions = {
|
||||
async fetchProjectList ({ commit, state }, payload) {
|
||||
const merged = { ...state.projectQuery, ...(payload || {}) }
|
||||
const query = {
|
||||
pageNum: merged.pageNum,
|
||||
pageSize: merged.pageSize,
|
||||
keyword: (merged.keyword != null ? String(merged.keyword) : '').trim()
|
||||
}
|
||||
commit('SET_PROJECT_QUERY', query)
|
||||
commit('SET_LOADING', true)
|
||||
try {
|
||||
const res = await retry(() => listProject(query), 2, 600)
|
||||
commit('SET_PROJECT_LIST', { rows: res.rows || [], total: res.total || 0 })
|
||||
return res
|
||||
} finally {
|
||||
commit('SET_LOADING', false)
|
||||
}
|
||||
},
|
||||
|
||||
async selectProject ({ commit }, projectId) {
|
||||
commit('SET_CURRENT_PROJECT', projectId)
|
||||
if (!projectId) {
|
||||
commit('CLEAR_RIGHT')
|
||||
return
|
||||
}
|
||||
const res = await retry(() => getProjectDashboard(projectId), 2, 600)
|
||||
const data = res.data || {}
|
||||
commit('SET_DASHBOARD', data)
|
||||
return res
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state,
|
||||
mutations,
|
||||
actions
|
||||
}
|
||||
Reference in New Issue
Block a user