首页接口调试

This commit is contained in:
2026-01-06 20:19:31 +08:00
parent dfd02c4eb4
commit 20d18d4146
13 changed files with 341 additions and 220 deletions

View File

@@ -2290,5 +2290,7 @@
"spdm.taskMessage.title": "Task Message",
"spdm.taskMessage.des": "Task Message List",
"spdm.taskList.title": "Task List",
"spdm.taskList.des": "List of tasks I perform"
"spdm.taskList.des": "List of tasks I perform",
"spdm.todoCalendar.title": "Todo Calendar",
"spdm.todoCalendar.des": "To-do task calendar"
}

View File

@@ -2290,5 +2290,7 @@
"spdm.taskMessage.title": "任务消息",
"spdm.taskMessage.des": "任务消息列表",
"spdm.taskList.title": "任务列表",
"spdm.taskList.des": "我执行的任务列表_spdm"
"spdm.taskList.des": "我执行的任务列表_spdm",
"spdm.todoCalendar.title": "待办日历",
"spdm.todoCalendar.des": "待办任务日历_spdm"
}

View File

@@ -2,16 +2,23 @@ import axios from 'axios';
import { ElMessage } from 'element-plus';
import { BASE_URL } from '../config';
let userId = localStorage.getItem('USER_ID') || '';
let token = localStorage.getItem('TOKEN') || '';
let tenantId = localStorage.getItem('TENANT_ID') || '';
const service = axios.create({
baseURL: BASE_URL,
timeout: 60000,
headers: {
'Content-Type': 'application/json;application/xml;charset=utf-8;',
'Content-Type': 'application/json;application/xml;charset=utf-8;'
},
});
service.interceptors.request.use(
(config) => {
config.headers['token'] = token;
config.headers['userId'] = userId;
config.headers['tenantId'] = tenantId;
return config;
},
(error) => {

View File

@@ -1,4 +1,4 @@
import { post } from './request';
import { post, get } from './request';
/**
*
@@ -9,3 +9,18 @@ import { post } from './request';
export const queryTaskListApi = (params: any) => {
return post(`/api/simulation/project/task/list`, params);
};
// 我执行的 各类状态统计
export const getTaskCountApi = (params: any) => {
return post(`/api/simulation/project/task/count`, params);
};
// 消息列表
export const getUserMsgPageList = (data: any) => {
return get(`/spdm-msg/getUserMsgPageList`, data);
};
// 修改消息状态
export const setMsgReadStatus = (params: any) => {
return post(`/spdm-msg/setMsgReadStatus`, params);
};

View File

@@ -25,14 +25,14 @@ export default {
:columns="tableColumns">
</TableRender>
</div>
<el-pagination layout="prev, pager, next" :total="100" @current-change="currentPageChangeFun"/>
<el-pagination layout="total, prev, pager, next" :pager-count="5" :total="total" @current-change="currentPageChangeFun"/>
</div>
<el-empty v-else class="empty" :image-size="48" :description="'暂无任务'" />
</el-card>
</template>
<script setup lang="ts" name="TaskMessageDashboard">
// import {getMessageUserPage} from '/@/api/message';
import {queryTaskListApi} from '/@/spdm/api/spdm-task';
import { ref, onMounted } from 'vue';
import { useI18n } from 'vue-i18n';
import TableRender from '/@/components/TableRender/index.vue';
@@ -40,129 +40,20 @@ import TableRender from '/@/components/TableRender/index.vue';
const router = useRouter();
const { t } = useI18n();
const taskList1 = ref([]);
const taskList = ref<any[]>([
{
"id": 1,
"taskName": "搭建用户登录模块数据库表结构",
"taskStatus": "进行中",
"taskRisk": "低(技术方案已确认,无明确风险)",
"taskProgress": "70%(已完成核心字段设计,待优化索引)",
"beginTime": "2025-10-28",
"endTime": "2025-11-01",
"project": "XX用户管理系统开发",
"phase": "开发阶段",
"person": "张三"
},
{
"id": 2,
"taskName": "设计双11促销活动海报",
"taskStatus": "待开始",
"taskRisk": "中(需与运营确认活动主题,可能影响设计进度)",
"taskProgress": "0%",
"beginTime": "2025-11-02",
"endTime": "2025-11-05",
"project": "2025双11电商促销项目",
"phase": "策划设计阶段",
"person": "张三"
},
{
"id": 3,
"taskName": "测试APP订单支付异常场景",
"taskStatus": "已完成",
"taskRisk": "低(测试用例覆盖全面)",
"taskProgress": "100%发现2个bug已修复",
"beginTime": "2025-10-25",
"endTime": "2025-10-27",
"project": "XX电商APP V3.5迭代",
"phase": "测试阶段",
"person": "张三"
},
{
"id": 4,
"taskName": "整理Q3用户运营数据报告",
"taskStatus": "进行中",
"taskRisk": "低(数据已收集完毕,仅需汇总分析)",
"taskProgress": "80%(已完成数据清洗,待生成可视化图表)",
"beginTime": "2025-10-30",
"endTime": "2025-11-03",
"project": "Q3用户运营复盘项目",
"phase": "数据复盘阶段",
"person": "张三"
},
{
"id": 5,
"taskName": "开发商品分类筛选功能前端页面",
"taskStatus": "已暂停",
"taskRisk": "高UI设计稿临时变更需重新调整布局",
"taskProgress": "40%(已完成基础框架,待对接新设计资源)",
"beginTime": "2025-10-26",
"endTime": "2025-11-01",
"project": "XX电商小程序优化",
"phase": "开发阶段",
"person": "张三"
},
{
"id": 6,
"taskName": "撰写新品上市推广软文",
"taskStatus": "待开始",
"taskRisk": "中(需等待产品部提供核心卖点,可能延期)",
"taskProgress": "0%",
"beginTime": "2025-11-04",
"endTime": "2025-11-06",
"project": "XX新品上市推广项目",
"phase": "内容准备阶段",
"person": "张三"
},
{
"id": 7,
"taskName": "修复用户反馈的APP闪退问题",
"taskStatus": "进行中",
"taskRisk": "低(已定位问题原因,正在编写修复代码)",
"taskProgress": "60%(修复方案已确定,待测试验证)",
"beginTime": "2025-10-29",
"endTime": "2025-11-02",
"project": "XXAPP紧急bug修复项目",
"phase": "紧急修复阶段",
"person": "张三"
},
{
"id": 8,
"taskName": "统计双11预热期用户点击量",
"taskStatus": "已完成",
"taskRisk": "低(数据统计工具正常,无异常)",
"taskProgress": "100%(数据已同步给运营团队)",
"beginTime": "2025-10-24",
"endTime": "2025-10-26",
"project": "2025双11电商促销项目",
"phase": "预热数据监控阶段",
"person": "张三"
},
{
"id": 9,
"taskName": "设计用户个人中心新版界面",
"taskStatus": "进行中",
"taskRisk": "中(用户调研反馈未完全收集,可能需调整设计)",
"taskProgress": "50%(已完成初稿设计,待收集反馈)",
"beginTime": "2025-10-31",
"endTime": "2025-11-04",
"project": "XX用户管理系统开发",
"phase": "UI设计阶段",
"person": "张三"
},
{
"id": 10,
"taskName": "编写APP版本更新说明文档",
"taskStatus": "待开始",
"taskRisk": "低(功能变更清单已确认,无不确定因素)",
"taskProgress": "0%",
"beginTime": "2025-11-05",
"endTime": "2025-11-07",
"project": "XX电商APP V3.5迭代",
"phase": "上线准备阶段",
"person": "张三"
},
]);
const taskList = ref<any[]>([]);
interface TaskStatus {
[key: number]: string;
}
const status: TaskStatus = {
1: '未开始',
2: '进行中',
3: '已驳回',
4: '已完成',
5: '已暂停',
6: '已关闭',
7: '已延期',
}
const tableColumns = ref([
{
// t('hooks.requirement.09115201-21')
@@ -172,39 +63,64 @@ const tableColumns = ref([
},
{
label: '状态',
prop: 'taskStatus',
prop: 'status',
width: 100,
},
{
label: '负责人',
prop: 'person',
prop: 'pMember',
width: 100,
},
{
label: '计划完成时间',
prop: 'endTime',
width: 140,
width: 170,
},
])
const current = ref(1)
const total = ref(0)
const currentPageChangeFun = (val: number) => {
console.log(val, '------------------');
current.value = val
getTableList()
}
// 更多按钮
const goMoreFun = () => {
router.push('spdm/task/execute'); // 跳转到我执行的页面
}
const getTableList = () => {
let idMap = [
{"key": null, "value": "tag1"},
{"key": null, "value": "tag2"},
{"key": null, "value": "tag3"},
{"key": null, "value": "tag4"},
{"key": null, "value": "tag5"},
{"key": null, "value": "tag6"},
{"key": null, "value": "tag7"},
{"key": null, "value": "tag8"},
{"key": null, "value": "tag9"},
{"key": null, "value": "tag10"}
]
const params = {
current: current.value,
idMap: idMap,
size: 10,
sortOrder: 1,
type: 0
}
queryTaskListApi(params).then((res) => {
const list = res.data.data;
list.forEach((item: any) => {
item.pMember = item?.pMemberList?.map((v: any) => v.nickname).join(',') || '--',
item.status = status[item.exeStatus]
})
taskList.value = list
total.value = res.data.total
});
}
onMounted(() => {
// const params = {
// size: 10,
// current: 1,
// msgCategory: 99,
// msgTitle: '任务通知'
// }
// getMessageUserPage(params).then((res) => {
// console.log(res, '------------------------');
// taskMessageList.value = res.data.records;
// });
getTableList()
})
</script>

View File

@@ -25,14 +25,15 @@ export default {
:columns="tableColumns">
</TableRender>
</div>
<el-pagination layout="prev, pager, next" :total="1" @current-change="currentPageChangeFun"/>
<el-pagination layout="total, prev, pager, next" :pager-count="5" :total="total" @current-change="currentPageChangeFun"/>
</div>
<el-empty v-else class="empty" :image-size="48" :description="'暂无任务消息'" />
</el-card>
</template>
<script setup lang="ts" name="TaskMessageDashboard">
import {getMessageUserPage} from '/@/api/message';
import {getUserMsgPageList} from '/@/spdm/api/spdm-task';
import { ref, onMounted } from 'vue';
import { useI18n } from 'vue-i18n';
const router = useRouter();
@@ -58,24 +59,30 @@ const tableColumns = ref([
])
// 更多按钮
const goMoreFun = () => {
router.push('/message/records?type=task'); // 跳转到消息记录页面 todo 带参数跳转
// router.push({name: 'moduleRoutes.messageRecords', params: {type: 'task'}})
localStorage.setItem('SPDM_JUMP_TYPE', 'task');
router.push('/message/records'); // 跳转到消息记录页面 todo 带参数跳转
}
const current = ref(1);
const total = ref(0)
const currentPageChangeFun = (val: number) => {
console.log(val, '------------------');
current.value = val;
getTableList()
}
onMounted(() => {
const getTableList = () => {
const params = {
size: 10,
current: 1,
current: current.value,
msgCategory: 99,
msgTitle: '任务通知'
}
getMessageUserPage(params).then((res) => {
// console.log(res, '------------------------');
taskMessageList.value = res.data.records;
getUserMsgPageList(params).then((res) => {
taskMessageList.value = res.data.data;
total.value = res.data.total;
});
}
onMounted(() => {
getTableList()
})
</script>

View File

@@ -0,0 +1,186 @@
<script lang="ts">
export default {
title: 'spdm.todoCalendar.title', // 日程管理
icon: 'Calendar',
description: 'spdm.todoCalendar.des', // 日历组件展示
};
</script>
<template>
<el-card class="h-[400px] box-card">
<Calendar
ref="calendar"
view="weekly"
:locale="locale"
:attributes="reminders"
title-position="center"
:masks="masks"
transparent
borderless
expanded
@did-move="weeknumberClick"
/>
<div v-if="calendar" class="py-4 px-6 w-full h-[18rem] overflow-y-auto">
<template v-for="{day, cells} in Object.values(dayCells)">
<ul v-if="cells.length > 0" :key="day" class="py-2 space-y-2">
<li v-for="cell in cells" :key="cell">
<div class="flex items-center space-x-4">
<!--Icon-->
<div class="flex-grow-0 flex-shrink-0">
<div :class="`flex justify-center items-center w-10 h-10 rounded-lg bg-blue-100 text-blue-500 dark:bg-blue-400 dark:text-white`">
<el-icon><CircleCheck /></el-icon>
</div>
</div>
<div class="flex items-center justify-between flex-grow">
<div>
<p class="font-medium cell-title">
{{ cell.data.customData.msgTitle }}
</p>
<div class="font-small" :title="cell.data.customData.msgBody">
{{ cell.data.customData.msgBody }}
</div>
<p class="text-xs font-medium text-gray-400 dark:text-gray-400 leading-2">
{{ cell.data.customData.receiveTime }}
</p>
</div>
</div>
<el-switch :title="'已读消息'" @change="changeSwitch(cell.data.customData.id)"></el-switch>
</div>
</li>
</ul>
</template>
<el-empty v-if="reminders.length === 0" :image-size="120" class="text-center" />
</div>
</el-card>
</template>
<script setup lang="ts" name="scheduleCalendar">
import {Calendar} from 'v-calendar';
import 'v-calendar/style.css';
import {useThemeConfig} from '/@/stores/themeConfig';
import {parseDate} from '/@/utils/formatTime';
import {getUserMsgPageList, setMsgReadStatus} from '/@/spdm/api/spdm-task';
import {ElMessage} from 'element-plus';
// 获取当前国际化方言
const storesThemeConfig = useThemeConfig();
const {themeConfig} = storeToRefs(storesThemeConfig);
const locale = computed(() => {
return themeConfig.value.globalI18n;
});
const masks = ref({
weekdays: 'WWW',
});
const reminders = ref([]);
const calendar = ref(null);
const dayCells = computed(() => {
if (!calendar.value) return [];
return calendar.value.dayCells;
});
// 日期范围的开始日期引用
const startDateRef = ref();
// 日期范围的结束日期引用
const endDateRef = ref();
// 点击周数的回调函数
const weeknumberClick = (page: any) => {
// 获取当前周的第一天和最后一天的日期
const startDate = page[0].viewDays[0].id;
const endDate = page[0].viewDays[6].id;
// 更新开始日期引用和结束日期引用
startDateRef.value = startDate;
endDateRef.value = endDate;
// 初始化日程列表
initscheduleList();
};
// 修改开关状态
const changeSwitch = async (id: string) => {
setMsgReadStatus({id: id, isRead: 1}).then(() => {
ElMessage.success('操作成功');
// 初始化调度列表
initscheduleList();
});
};
// 封装方法获取本周第一天和最后一天的日期格式为yyyy-mm-dd
const getCurrentWeekDates = () => {
const now = new Date();
const dayOfWeek = now.getDay(); // 获取今天是星期几0表示星期日1表示星期一以此类推
const diff = now.getDate() - dayOfWeek + (dayOfWeek === 0 ? -6 : 1); // 计算本周第一天是星期几
const startDate = new Date(now.setDate(diff));
const endDate = new Date(now.setDate(diff + 6));
return {
startDate: parseDate(startDate.getTime(), '{y}-{m}-{d}'),
endDate: parseDate(endDate.getTime(), '{y}-{m}-{d}'),
};
};
const initscheduleList = () => {
let params = {
size: 100,
current: 1,
msgCategory: 99,
isRead: 0,
beginTime: startDateRef.value || getCurrentWeekDates().startDate,
endTime: endDateRef.value || getCurrentWeekDates().endDate
}
getUserMsgPageList(params).then((res) => {
const list = res.data.data;
reminders.value = list.map((item: any) => {
return {
key: item.id,
highlight: {
color: 'primary',
fillMode: 'outline',
},
dates: item.receiveTime,
customData: item,
};
});
});
};
// 过滤日历中选中的单元格是否有日程
const filterCellSelected = (day: string) => {
return (
reminders.value.filter((item: any) => {
return item.dates.includes(day);
}).length > 0
);
};
onMounted(() => {
initscheduleList();
});
</script>
<style scoped lang="scss">
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
}
.cell-title {
font-size: 12px;
font-weight: bold;
}
.font-small {
font-size: 12px;
// 文字超过两行展示省略号
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
text-overflow: ellipsis;
margin: 6px 0;
}
</style>

View File

@@ -1,8 +1,5 @@
<script lang="ts" setup name="TopNav">
import { color } from 'echarts';
import {getTaskCountApi} from '/@/api/admin/tenant';
import {queryTaskListApi} from '/@/spdm/api/spdm-task';
import {queryTaskListApi, getTaskCountApi} from '/@/spdm/api/spdm-task';
import {getTenantAssignmentsListByUsername} from '/@/api/admin/user';
import {useUserInfo} from '/@/stores/userInfo';
@@ -11,34 +8,35 @@ const {userInfos, userId} = useUserInfo();
const tenantInfo = ref<any>(null);
const taskCountMap = ref<Record<string, number>>({});
const list = computed(() => [
{
const list = ref([
{
label:'我关注的',
prop: 'createCount',
count: 0,
color: 'rgb(221, 221, 9)',
path: '/spdm/task/attention',
},
{
label: '今明任务',
prop: 'backlogCount',
count: 0,
key: 'todayTmrTasks',
color: '#FF9900',
path: '/spdm/task/execute',
},
{
label: '进行中任务',
prop: 'finishCount',
count: 0,
key: 'inProgress',
color: '#1890ff',
path: '/spdm/task/execute',
},
{
label: '逾期任务',
prop: 'allCount',
count: 0,
key: 'postponed',
color: '#FF0000',
path: '/spdm/task/execute',
},
]);
])
const getTenantList = () => {
return getTenantAssignmentsListByUsername(userId).then((response) => {
@@ -47,39 +45,54 @@ const getTenantList = () => {
});
};
const getTaskCount = async () => {
const res = await getTaskCountApi();
taskCountMap.value = res.data;
taskCountMap.value.allCount = Number(taskCountMap.value.backlogCount) + Number(taskCountMap.value.createCount) + Number(taskCountMap.value.finishCount)
console.log(taskCountMap.value,'taskCountMap.value');
};
const getFocusCount = () => {
let idMap = [
{"key": null, "value": "tag1"},
{"key": null, "value": "tag2"},
{"key": null, "value": "tag3"},
{"key": null, "value": "tag4"},
{"key": null, "value": "tag5"},
{"key": null, "value": "tag6"},
{"key": null, "value": "tag7"},
{"key": null, "value": "tag8"},
{"key": null, "value": "tag9"},
{"key": null, "value": "tag10"}
]
const params = {
current: 1,
size: 10,
sortOrder: 1,
type: 1
type: 1,
idMap: idMap
}
// queryTaskListApi(params).then((res) => {})
queryTaskListApi(params).then((res) => {
list.value[0].count = res.data.total;
})
getTaskCountApi({ idMap, type: 0 }).then((res) => {
const data = res.data;
list.value[1].count = data.todayTmrTasks || 0;
list.value[2].count = data.inProgress || 0;
list.value[3].count = data.postponed || 0;
})
}
onActivated(() => {
getTenantList();
getTaskCount();
getFocusCount();
});
watchEffect(() => {
getTenantList();
getTaskCount();
getFocusCount();
});
const router = useRouter();
const handleClick = (path: string) => {
router.push(path);
const handleClick = (item: any) => {
// if(['todayTmrTasks', 'inProgress', 'postponed'].includes(item.key)) {
// localStorage.setItem('SPDM_JUMP_TASK_TYPE', item.key);
// }
router.push(item.path);
};
</script>
@@ -97,10 +110,9 @@ const handleClick = (path: string) => {
</div>
</div>
<div class="col-span-2 grid grid-cols-4 h-[40px] justify-between">
<div v-for="item in list" :key="item.prop" class="flex flex-col justify-between cursor-pointer" @click="handleClick(item.path)">
<div v-for="item in list" :key="item.label" class="flex flex-col justify-between cursor-pointer" @click="handleClick(item)">
<div class="text-sm text-[#000000A6]">{{ item.label }}</div>
<div class="text-xl" :style="{ color: item.color }" >{{
taskCountMap[item.prop] ?? 0 }}</div>
<div class="text-xl" :style="{ color: item.color }" >{{ item.count ?? 0 }}</div>
</div>
</div>
</div>

View File

@@ -39,25 +39,6 @@ const defaultFavoriteRoutes = [
meta: { icon: 'ele-Cellphone' },
url: '/spdm/simulation/application',
},
// {
// contextMenuClickId: 5,
// path: '/project/list',
// name: 'moduleRoutes.projectList',
// meta: { icon: 'iconfont icon-diannao1', code: 'project_view' },
// query: {},
// url: '/project/list',
// commonUrl: '',
// },
// {
// contextMenuClickId: 5,
// path: '/task/pending',
// name: 'moduleRoutes.taskPending',
// meta: { icon: 'fa fa-flag-checkered', code: 'task_view' },
// query: {},
// url: '/task/pending',
// transUrl: '',
// commonUrl: '',
// },
]
/**

View File

@@ -5,7 +5,8 @@
<span>{{ props.title }}</span>
</div>
</template>
<el-row v-if="showRoutes.length > 0" :gutter="10">
<!-- SPDM CODE :class -->
<el-row v-if="showRoutes.length > 0" :gutter="10" :class="type === 'menu' ? 'menu-list' : ''">
<el-col v-for="shortcut in showRoutes" :key="shortcut.id" class="shortcutCard" :xs="12" :sm="8" :md="8" :xl="6">
<SvgIcon name="ele-Close" :size="12" class="shortcutCardClose" @click="handleCloseFavorite(shortcut)" />
<shortcutCard :icon="shortcut.meta?.icon" :label="shortcut.name" @click="handleRoute(shortcut.path)" />
@@ -73,7 +74,6 @@ const showRoutes = computed(() => {
<style lang="scss" scoped>
.shortcutCard {
position: relative;
.shortcutCardClose {
position: absolute;
top: 0;
@@ -84,4 +84,8 @@ const showRoutes = computed(() => {
color: var(--el-color-danger);
}
}
// SPDM CODE
.menu-list {
height: 300px;
}
</style>

View File

@@ -108,7 +108,6 @@ const weeknumberClick = (page: any) => {
//处理日程安排事件,若当前日期下没有日程则打开表单对话框,否则打开日程详情页面
const dayClick = (day: any) => {
// SPDM CODE 不需要新增待办,注释掉
if (filterCellSelected(day.id)) {
scheduleRef.value.open({date: parseDate(day.id, null)});
} else {

View File

@@ -127,7 +127,7 @@ import {cloneDeep, flatten} from 'lodash';
const defaultGrid = ref({
layout: [8, 8, 8],
// SPDM CODE
copmsList: [['calendar', 'favorite-menu'], ['TaskMessage'], ['TaskList']],
copmsList: [['ToDoCalendar', 'favorite-menu'], ['TaskMessage'], ['TaskList']],
});
const customizing = ref(false);
const widgets = ref();
@@ -171,7 +171,8 @@ const myCompsList = computed(() => {
'task-compare-chart',
'task-trend-chart',
'TaskMessage',
'TaskList'
'TaskList',
'ToDoCalendar'
];
return allComponentList.value.filter((item) => !item.disabled && myGrid.includes(item.key));
});

View File

@@ -31,17 +31,6 @@ import RecordItem from './components/RecordItem.vue';
import { useRoute } from 'vue-router';
const activeName = ref<string>('');
// SPDM CODE 封装一个方法,从当前地址栏取出某个参数的值
const getQueryVariable = (variable: string) => {
const query = window.location.search.substring(1);
const vars = query.split("&");
for (let i = 0; i < vars.length; i++) {
const pair = vars[i].split("=");
if (pair[0] === variable) {
return pair[1];
}
}
}
const messageList = ref<MessageUserVo[]>([]);
const current = ref<number>(1);
@@ -52,11 +41,11 @@ const route = useRoute();
onMounted(() => {
// SPDM CODE
// const type = route.params.type;
const type = getQueryVariable('type');
const type = localStorage.getItem('SPDM_JUMP_TYPE');
if (type ==='task') {
activeName.value = '任务通知';
spdmMsgType.value = true
localStorage.removeItem('SPDM_JUMP_TYPE');
}
getUserMessage();
});