diff --git a/docs/government.md b/docs/government.md index 3aa08f8c7..48d6af543 100644 --- a/docs/government.md +++ b/docs/government.md @@ -406,6 +406,12 @@ pageClass: routes +## 德阳市人民政府 + +### 德阳市政府公开信息 + + + ## 中国工业和信息化部 ### 政策解读 diff --git a/lib/v2/gov/maintainer.js b/lib/v2/gov/maintainer.js index 3c8b3f0b1..7c09586eb 100644 --- a/lib/v2/gov/maintainer.js +++ b/lib/v2/gov/maintainer.js @@ -6,4 +6,5 @@ module.exports = { '/guangdong/tqyb/tfxtq': ['Fatpandac'], '/guangdong/tqyb/sncsyjxh': ['Fatpandac'], '/huizhou/zwgk/:category?': ['Fatpandac'], + '/sichuan/deyang/govpulicinfo/:countyName/:institutionName?': ['zytomorrow'], }; diff --git a/lib/v2/gov/radar.js b/lib/v2/gov/radar.js index 1ffc68813..fd778aa54 100644 --- a/lib/v2/gov/radar.js +++ b/lib/v2/gov/radar.js @@ -365,4 +365,15 @@ module.exports = { }, ], }, + 'deyang.gov.cn': { + _name: '德阳市人民政府', + '.': [ + { + title: '德阳市政府公开信息', + docs: 'https://docs.rsshub.app/government.html#de-yang-shi-fu-ren-min-zheng-zheng-fu', + source: ['/*'], + target: '/sichuan/deyang/govpulicinfo/:countyName/:institutionName?', + }, + ], + }, }; diff --git a/lib/v2/gov/router.js b/lib/v2/gov/router.js index 7e6639c26..892355701 100644 --- a/lib/v2/gov/router.js +++ b/lib/v2/gov/router.js @@ -7,4 +7,5 @@ module.exports = function (router) { router.get('/guangdong/tqyb/tfxtq', require('./guangdong/tqyb/tfxtq')); router.get('/guangdong/tqyb/sncsyjxh', require('./guangdong/tqyb/sncsyjxh')); router.get('/huizhou/zwgk/:category?', require('./huizhou/zwgk/index')); + router.get('/sichuan/deyang/govpulicinfo/:countyName/:institutionName?', require('./sichuan/deyang/govpulicinfo')); }; diff --git a/lib/v2/gov/sichuan/deyang/govpulicinfo.js b/lib/v2/gov/sichuan/deyang/govpulicinfo.js new file mode 100644 index 000000000..84db4fcf2 --- /dev/null +++ b/lib/v2/gov/sichuan/deyang/govpulicinfo.js @@ -0,0 +1,115 @@ +const got = require('@/utils/got'); +const cheerio = require('cheerio'); +const { parseDate } = require('@/utils/parse-date'); +const { art } = require('@/utils/render'); +const path = require('path'); + +const rootUrl = 'http://xxgk.deyang.gov.cn/xxgkml2020'; + +// 地区名称对照表 +const nameDict = { + 德阳市: 'dys', + 绵竹市: 'mzs', + 什邡市: 'sfs', + 旌阳区: 'jyq', + 罗江区: 'ljx', + 广汉市: 'ghs', + 中江县: 'zjx', + 高新区: 'gxq', +}; + +const getInstitutionId = async (ctx, county) => { + const url = `${rootUrl}/ptlj.jsp?regionName=${county}`; + + return await ctx.cache.tryGet(`${county}InstitutionId`, async () => { + const response = await got.get(url); + const $ = cheerio.load(response.data); + const dataList = $('#details_content > div > div > div > div:nth-child(4) > ul > li > a'); + const _tmp = {}; + for (let i = 0; i < dataList.length; i++) { + _tmp[$(dataList[i]).html()] = parseInt($(dataList[i]).attr('href').split('deptId=')[1]); + } + return _tmp; + }); +}; + +const getInfoUrlList = async (county, institutionId) => { + const url = `${rootUrl}/gklist_iframe.jsp?deptId=${institutionId}®ionName=${county}&pageSize=15`; + const response = await got.get(url); + const $ = cheerio.load(response.data); + const pageNum = parseInt($('#list_content > div > span:nth-child(3)').html().match(/\d*/g)[1]); + const pageUrlList = []; + + // 此处建议限制最大pageNum,最大5页,单页15条 + for (let i = 1; i <= Math.min(pageNum, 5); i++) { + pageUrlList.push(`${rootUrl}/gklist_iframe.jsp?deptId=${institutionId}®ionName=${county}&pageSize=15$pageIndex=${i}`); + } + const _tmpList = await Promise.all( + pageUrlList.map(async (url) => { + const response = await got.get(url); + const $ = cheerio.load(response.data); + const InfoList = $('#list_content > ul > li > a'); + return InfoList.map((item) => `${rootUrl}/${$(InfoList[item]).attr('href')}`); + }) + ); + let infoUrlList = []; + for (let i = 0; i < _tmpList.length; i++) { + infoUrlList = infoUrlList.concat(_tmpList[i].toArray()); + } + return infoUrlList; +}; + +const getInfoContent = async (ctx, url) => { + const infoId = url.split('id=')[1].split('&type')[0]; + return await ctx.cache.tryGet(`govPublicInfo${infoId}`, async () => { + const response = await got.get(url); + const $ = cheerio.load(response.data); + const fileNodes = $('#symbol > div:nth-child(3) > div > a'); + const fileList = []; + for (let i = 0; i < fileNodes.length; i++) { + fileList.push({ + name: $(fileNodes[i]).text(), + url: `${rootUrl}/${$(fileNodes[i]).attr('href')}`, + }); + } + const rawDate = $('#symbol > div:nth-child(1) > div:nth-child(3)').text().split('\n')[1].trim(); + return { + title: $('#headline').text(), + id: infoId, + infoNum: $('#symbol > div:nth-child(1) > div:nth-child(2) > span').text().split('\n')[1].trim(), + pubDate: parseDate(rawDate), + date: rawDate, + keyWord: $('#symbol > div:nth-child(2) > div:nth-child(1)').text().slice(8), + source: $('#symbol > div:nth-child(2) > div:nth-child(3)').text().slice(5), + content: $('#details_content > div.content').html(), + file: fileList, + link: url, + }; + }); +}; + +module.exports = async (ctx) => { + const countyName = ctx.params.countyName; + const county = nameDict[countyName]; + const institutionName = ctx.params.institutionName || ''; + let institutionId = 0; + if (institutionName) { + const institutionDict = await getInstitutionId(ctx, county); + institutionId = institutionDict[institutionName]; + } + + const infoUrlList = await getInfoUrlList(county, institutionId); + const items = await Promise.all(infoUrlList.map(async (item) => await getInfoContent(ctx, item))); + + ctx.state.data = { + title: `政府公开信息 - ${countyName} ${institutionName}`, + link: `${rootUrl}/gklist_iframe.jsp?deptId=${institutionId}®ionName=${county}`, + item: items.map((item) => ({ + title: item.title, + description: art(path.resolve(__dirname, './templates/govPublicInfo.art'), { item }), + link: item.link, + guid: item.id, + pubDate: item.pubDate, + })), + }; +}; diff --git a/lib/v2/gov/sichuan/deyang/templates/govPublicInfo.art b/lib/v2/gov/sichuan/deyang/templates/govPublicInfo.art new file mode 100644 index 000000000..e8b9284b6 --- /dev/null +++ b/lib/v2/gov/sichuan/deyang/templates/govPublicInfo.art @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + {{if item.file.length}} + + + + + {{/if}} + +
索引号{{item.id}}
文号{{item.infoNum}}
发文日期{{item.date}}
关键词{{item.keyWord}}
信息来源{{item.source}}
附件 + {{each item.file}} + {{$value.name}}
+ {{/each}} +
+ +
+ {{@ item.content}} +
+ + +