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); }, };