You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
226 lines
8.1 KiB
226 lines
8.1 KiB
1 year ago
|
const request = require('superagent');
|
||
|
const moment = require('moment');
|
||
|
const productExcluded = require('../../config-product-excluded');
|
||
|
|
||
|
module.exports = {
|
||
|
entry(app, router, opts) {
|
||
|
async function auth() {
|
||
|
const session = await request.get('https://pms.anxinyun.cn/api-getSessionID.json');
|
||
|
const sessionData = JSON.parse(session.text).data;
|
||
|
const { sessionName, sessionID } = JSON.parse(sessionData);
|
||
|
|
||
|
const loginInfo = await request
|
||
|
.post('https://pms.anxinyun.cn/user-login.json')
|
||
|
.set({ 'Content-Type': 'application/x-www-form-urlencoded' })
|
||
|
.query({ [`${sessionName}`]: sessionID })
|
||
|
.send({ account: 'admin', password: 'Fashion123' });
|
||
|
|
||
|
app.fs = app.fs || {};
|
||
|
app.fs.session = { sessionName, sessionID };
|
||
|
}
|
||
|
|
||
|
(async function () {
|
||
|
await auth();
|
||
|
setInterval(async () => {
|
||
|
await auth();
|
||
|
}, 1200000); // 每 20分钟 刷新一次
|
||
|
}());
|
||
|
|
||
|
function extractBuildTime(inputString) {
|
||
|
const pattern = /[(\(]构建时间:(.*?)[\))]/;
|
||
|
const match = inputString.match(pattern);
|
||
|
const buildDate = match ? match[1] : null;
|
||
|
return buildDate;
|
||
|
}
|
||
|
|
||
|
async function getExecutionDetail(executionId) {
|
||
|
const { sessionName, sessionID } = app.fs.session;
|
||
|
|
||
|
const executionDetailRes = await request
|
||
|
.get(`https://pms.anxinyun.cn/execution-view-${executionId}.json`)
|
||
|
.set('Cookie', `${sessionName}=${sessionID}`);
|
||
|
const executionDetailText = JSON.parse(executionDetailRes.text);
|
||
|
const executionDetailData = JSON.parse(executionDetailText.data);
|
||
|
|
||
|
const executionTeamRDs = [];
|
||
|
const executionTeamMembers = executionDetailData.teamMembers;
|
||
|
for (const member of Object.values(executionTeamMembers)) {
|
||
|
if (member.role === '研发') executionTeamRDs.push({ name_people: member.realname });
|
||
|
}
|
||
|
|
||
|
const executionProducts = Object.values(executionDetailData.products).map((product) => product.name);
|
||
|
|
||
|
return { executionTeamRDs, executionProducts };
|
||
|
}
|
||
|
|
||
|
async function getExecutionProgress(executionId) {
|
||
|
const { sessionName, sessionID } = app.fs.session;
|
||
|
|
||
|
const testTaskRes = await request
|
||
|
.get(`https://pms.anxinyun.cn/execution-testtask-${executionId}.json`)
|
||
|
.set('Cookie', `${sessionName}=${sessionID}`);
|
||
|
|
||
|
const testTaskText = JSON.parse(testTaskRes.text);
|
||
|
const progress = Object.keys(JSON.parse(testTaskText.data).tasks).length ? '测试中' : '研发中';
|
||
|
|
||
|
return progress;
|
||
|
}
|
||
|
|
||
|
async function getExecutionStats(baseURL, recPerPage) {
|
||
|
const { sessionName, sessionID } = app.fs.session;
|
||
|
|
||
|
const executionRes = await request
|
||
|
.get(baseURL)
|
||
|
.set('Cookie', `${sessionName}=${sessionID}; pagerExecutionAll=${recPerPage || 10}`);
|
||
|
const executionText = JSON.parse(executionRes.text);
|
||
|
const executionData = JSON.parse(executionText.data);
|
||
|
|
||
|
let executionAll = executionData.executionStats;
|
||
|
|
||
|
const pg = executionData.pager;
|
||
|
let pid = pg.pageID;
|
||
|
while (pid < pg.pageTotal) {
|
||
|
const res = await request
|
||
|
.get(baseURL.replace('.json', `-${pg.recTotal}-${pg.recPerPage}-${pid + 1}.json`))
|
||
|
.set('Cookie', `${sessionName}=${sessionID}`);
|
||
|
const resText = JSON.parse(res.text);
|
||
|
const resData = JSON.parse(resText.data);
|
||
|
executionAll = executionAll.concat(resData.executionStats);
|
||
|
pid++;
|
||
|
}
|
||
|
|
||
|
const currentMonth = moment().format('YYYY-MM');
|
||
|
|
||
|
const executionStats = executionAll.filter((item) => item.type === 'sprint' && (
|
||
|
moment(item.begin).format('YYYY-MM') === currentMonth
|
||
|
|| moment(item.end).format('YYYY-MM') === currentMonth
|
||
|
));
|
||
|
|
||
|
return executionStats;
|
||
|
}
|
||
|
|
||
|
async function getOngoingProjects(ctx, next) {
|
||
|
try {
|
||
|
const { sessionName, sessionID } = app.fs.session;
|
||
|
|
||
|
const executions = [];
|
||
|
const currentMonth = moment().format('YYYY-MM');
|
||
|
|
||
|
// 执行(未开始)
|
||
|
const waitExecutionBaseURL = 'https://pms.anxinyun.cn/execution-all-wait-0-order_asc-0.json';
|
||
|
const waitExecutionStats = await getExecutionStats(waitExecutionBaseURL, 200);
|
||
|
for (const item of waitExecutionStats) {
|
||
|
const { id, name, end } = item;
|
||
|
const { executionTeamRDs, executionProducts } = await getExecutionDetail(id);
|
||
|
if (executionProducts.some((p) => productExcluded.includes(p))) continue;
|
||
|
executions.push({
|
||
|
execution_id: id,
|
||
|
name_project: name,
|
||
|
build_time: extractBuildTime(name),
|
||
|
publish_time: end,
|
||
|
part_people: executionTeamRDs,
|
||
|
progress: '需求评审中',
|
||
|
});
|
||
|
}
|
||
|
|
||
|
// 执行(进行中)
|
||
|
const doingExecutionBaseURL = 'https://pms.anxinyun.cn/execution-all-doing-0-order_asc-0.json';
|
||
|
const doingExecutionStats = await getExecutionStats(doingExecutionBaseURL, 200);
|
||
|
for (const item of doingExecutionStats) {
|
||
|
const { id, name, end } = item;
|
||
|
const { executionTeamRDs, executionProducts } = await getExecutionDetail(id);
|
||
|
if (executionProducts.some((p) => productExcluded.includes(p))) continue;
|
||
|
const executionProgress = await getExecutionProgress(id);
|
||
|
executions.push({
|
||
|
execution_id: id,
|
||
|
name_project: name.replace('&', '&'),
|
||
|
build_time: extractBuildTime(name),
|
||
|
publish_time: end,
|
||
|
part_people: executionTeamRDs,
|
||
|
progress: executionProgress,
|
||
|
});
|
||
|
}
|
||
|
|
||
|
ctx.status = 200;
|
||
|
ctx.body = {
|
||
|
total: executions.length,
|
||
|
projects: executions,
|
||
|
};
|
||
|
} catch (e) {
|
||
|
ctx.status = 400;
|
||
|
ctx.body = {
|
||
|
name: 'FindError',
|
||
|
message: `版本计划获取失败${e}`,
|
||
|
};
|
||
|
}
|
||
|
}
|
||
|
|
||
|
async function getOngoingPersons(ctx, next) {
|
||
|
try {
|
||
|
const { sessionName, sessionID } = app.fs.session;
|
||
|
|
||
|
const executions = [];
|
||
|
|
||
|
const currentDate = moment();
|
||
|
// 获取当前周的第一天(周一)
|
||
|
const firstDayOfWeek = currentDate.clone().startOf('isoWeek');
|
||
|
// 获取当前周的最后一天(周日)
|
||
|
const lastDayOfWeek = currentDate.clone().endOf('isoWeek');
|
||
|
|
||
|
// 执行(未开始)
|
||
|
const waitExecutionRes = await request
|
||
|
.get('https://pms.anxinyun.cn/execution-all-wait-0-order_asc-0.json')
|
||
|
.set('Cookie', `${sessionName}=${sessionID}`);
|
||
|
const waitExecutionText = JSON.parse(waitExecutionRes.text);
|
||
|
const waitExecutionStats = JSON.parse(waitExecutionText.data).executionStats
|
||
|
.filter((item) => item.type === 'sprint' && (
|
||
|
moment(item.begin).isBetween(firstDayOfWeek, lastDayOfWeek, undefined, '[]')
|
||
|
|| moment(item.end).isBetween(firstDayOfWeek, lastDayOfWeek, undefined, '[]')
|
||
|
));
|
||
|
|
||
|
for (const item of waitExecutionStats) {
|
||
|
const {
|
||
|
id, name, begin, end,
|
||
|
} = item;
|
||
|
const { executionTeamRDs, executionProducts } = await getExecutionDetail(id);
|
||
|
if (executionProducts.some((p) => productExcluded.includes(p))) continue;
|
||
|
executions.push({
|
||
|
name_project: name,
|
||
|
begin,
|
||
|
build_time: extractBuildTime(name),
|
||
|
end,
|
||
|
part_people: executionTeamRDs,
|
||
|
});
|
||
|
}
|
||
|
|
||
|
const memberExecutions = executions.reduce((p, c) => {
|
||
|
const { part_people, ...rest } = c;
|
||
|
part_people.forEach((member) => {
|
||
|
if (p[member.name_people]) {
|
||
|
p[member.name_people].push(rest);
|
||
|
} else {
|
||
|
p[member.name_people] = [rest];
|
||
|
}
|
||
|
});
|
||
|
return p;
|
||
|
}, {});
|
||
|
|
||
|
ctx.status = 200;
|
||
|
ctx.body = {
|
||
|
total: Object.keys(memberExecutions).length,
|
||
|
projects: memberExecutions,
|
||
|
};
|
||
|
} catch (e) {
|
||
|
ctx.status = 400;
|
||
|
ctx.body = {
|
||
|
name: 'FindError',
|
||
|
message: `人员计划获取失败${e}`,
|
||
|
};
|
||
|
}
|
||
|
}
|
||
|
|
||
|
router.get('/ongoing/projects', getOngoingProjects);
|
||
|
router.get('/ongoing/persons', getOngoingPersons);
|
||
|
},
|
||
|
};
|