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

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('&amp;', '&'),
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);
},
};