审核任务书
// ==UserScript==
// @name 审核任务书
// @namespace https://tampermonkey.net/
// @version 0.8
// @description 完善了比对的信息!
// @author You
// @match https://gkg.kjt.gxzf.gov.cn/egrantweb/ctrapprove/*
// @grant none
// @require https://incaseofstairs.com/jsdiff/diff.js
// ==/UserScript==
(function() {
'use strict';
// 生成按钮
var cmd = document.querySelector("#approve").parentNode;
cmd.innerHTML = ' <input class="button_01" type="button" value="开始审核"> ' + cmd.innerHTML;
cmd.children[0].addEventListener("click", myFunction);
function myFunction(){
//发送请求待审核任务书清单
var httpRequest = new XMLHttpRequest();
httpRequest.open('POST', 'https://gkg.kjt.gxzf.gov.cn/egrantweb/ctrapprove/list-grid?_search=false&rows=20&page=1&sidx=zhTitle&sord=asc&searchString=', true); //第二步:打开连接
httpRequest.send('');
httpRequest.onreadystatechange = function () {
if (httpRequest.readyState == 4 && httpRequest.status == 200) {
var domParser = new DOMParser();
var xmlDoc = domParser.parseFromString(httpRequest.responseText, 'text/xml');
//根据任务书窗口链接地址中的grantCode在任务书清单中查找申报书代码
var grantCode = window.location.href.slice(window.location.href.indexOf("ctrCode=") + 8,window.location.href.indexOf("&grantCode="));
var row = xmlDoc.getElementById(grantCode);
var codes = row.children[6].textContent.match(/\'([^\']*)\'/g);//申报书代码
//下载申报书
var httpRequest1 = new XMLHttpRequest();
var url = 'https://gkg.kjt.gxzf.gov.cn/egrantweb/proposal/view-prp?posCodeStr=';
url = url + codes[0].slice(1,-1) + '&grantCodeStr=';
url = url + codes[1].slice(1,-1) + '&subGrantCodeStr=';
url = url + codes[2].slice(1,-1) + '&';
httpRequest1.open('POST', url, true); //第二步:打开连接
httpRequest1.send('');//发送请求
httpRequest1.onreadystatechange = function () {
if (httpRequest1.readyState == 4 && httpRequest1.status == 200) {
//提取任务书类型,bMajor为true时为重大专项任务书
var bMajor = document.querySelector("body > div > div:nth-child(3) > table:nth-child(89) > tbody > tr:nth-child(3) > td > font > strong").innerText.indexOf("重大专项") > 0;
//解析申报书页面
var htmlPrp = domParser.parseFromString(httpRequest1.responseText, 'text/html');
//比对项目时间
//读取申报书中开始与结束时间(XXXX-XX-XX)
var timePrp = htmlPrp.querySelector("#baseInfo > tbody:nth-child(2) > tr:nth-child(1) > td:nth-child(2)").textContent.trim() + "至" +
htmlPrp.querySelector("#baseInfo > tbody:nth-child(2) > tr:nth-child(1) > td:nth-child(4)").textContent.trim();
//将时间修改为任务书格式(XXXX年XX月XX日)生成。
timePrp = timePrp.replace("-","年").replace("-","月").replace("-","日").replace("-","年").replace("-","月").replace("-","日");
//获取任务书中时间
var nodes = queryXPath(document, "//td[contains(text(),'实施期限:')]/following-sibling::td[1]");
var timeCtr = nodes.textContent.trim();
//比对项目时间
checkText2(timePrp, timeCtr, nodes);
//比对课题组人数
if (bMajor){
checkText(htmlPrp.querySelector("#fragment-tab9 > table:nth-child(7) > tbody:nth-child(2) > tr:nth-child(1) > td:nth-child(2)"),
document.querySelector("table.table01:nth-child(124) > tbody:nth-child(2) > tr:nth-child(2) > td:nth-child(1)"));
}
else{
checkText(queryXPath(htmlPrp, "//td[contains(text(),'项目组总参与人数:')]/following-sibling::td[1]"),
queryXPath(document, "//td[contains(text(),'总人数(含负责人)')]/../following-sibling::tr[1]/td[1]"));
}
//比对课题负责人信息
var zh_persons = document.querySelectorAll("table#zh_persons");
var xs_persons = zh_persons[0].nextElementSibling;//人员列表标题,用于显示删除的人员
zh_persons = Array.from(zh_persons[2].querySelectorAll("tbody > tr > td:nth-child(2)"));
for(var i = 1;i < 13;i++){//比对人员各列信息
checkText(htmlPrp.querySelector("#tab > tr > td:nth-child(3) > a > span").parentNode.parentNode.parentNode.children[[1,2,3,4,5,6,7,8,9,11,12,12,13][i]],
zh_persons[1].parentNode.children[i]);
}
//比对项目组成员信息
var prpPersons = Array.from(htmlPrp.querySelectorAll("#kfpsn > tbody > tr > td:nth-child(3) > a > span"));
zh_persons.splice(0, 2);
for(i = 0; i < prpPersons.length; i++){
for(var j = 0; j < zh_persons.length; j++){
//查找同一人
if (isEquality(prpPersons[i].innerText,zh_persons[j].innerText)){
//比较成员序号
checkText2((parseInt(prpPersons[i].parentNode.parentNode.parentNode.children[1].innerText.trim()) + 1).toString(),
zh_persons[j].parentNode.children[0].innerText.trim(),
zh_persons[j].parentNode.children[0]);
//比较成员其他信息
for(var p = 1;p <= 12;p++){
checkText(prpPersons[i].parentNode.parentNode.parentNode.children[[1,2,3,4,5,6,7,8,10,12,11,13][p-1] + 1],
zh_persons[j].parentNode.children[p]);
}
prpPersons.splice(i, 1);
zh_persons.splice(j, 1);
i--;
break;p
}
}
}
//显示删除的人员
if(prpPersons.length > 0){
var delPerson = "";
for(i = 0; i < prpPersons.length; i++){
delPerson = delPerson + prpPersons[i].innerText.trim() + ";";
}
xs_persons.innerHTML = xs_persons.innerText + '删除了<del style="color: red;">' + delPerson + '</del>';
}
//显示增加的人员
for(i = 0; i < zh_persons.length; i++){
zh_persons[i].innerHTML = '<add style="color: green;">' + zh_persons[i].innerText.trim() +'</add>';
}
//比对总体目标
checkText(queryXPath(htmlPrp, "//td[contains(text(),'项目总体目标:')]/following-sibling::td[1]"),
queryXPath(document, "//div[contains(text(),'(一)总体目标')]/following-sibling::table[1]//td[1]"));
//比对主要研究内容
if (bMajor){//重大专项和重点研发格式不同
//checkText(htmlPrp.querySelector("#baseInfo > tbody > tr:nth-child(9) > td:nth-child(2)"), ztmb[2]);
}
else{
checkText(queryXPath(htmlPrp, "//td[contains(text(),'项目主要内容:')]/following-sibling::td[1]"),
queryXPath(document, "//div[contains(text(),'(二)主要内容')]/following-sibling::table[1]//td[1]"));
}
//比对研究解决的关键技术问题
if (bMajor){//重大专项和重点研发格式不同
//checkText(htmlPrp.querySelector("#baseInfo > tbody:nth-child(2) > tr:nth-child(10) > td:nth-child(2)"), ztmb[4]);
}
//比对考核指标
checkTableByName(htmlPrp, document, '项目完成考核指标','(三)项目完成考核指标');
//比对经济指标中直接经济效益详细说明
checkTableByPath(htmlPrp, document,
"//div[contains(text(),'经济指标中直接经济效益详细说明')]/following-sibling::table[1]//td",
"//td[contains(text(),'经济指标中直接经济效益详细说明')]/../following-sibling::tr[1]//td");
//比对任务进度考核指标
checkTableByPath(htmlPrp, document,
"//div[contains(text(),'项目过程管理考核指标')]/following-sibling::table[1]//td[position()>3]",
"//div[contains(text(),'1.任务进度考核指标')]/following-sibling::table[1]//td[position()>2]");
//比对经费支出进度考核指标
checkTableByPath(htmlPrp, document,
"//div[contains(text(),'经费支出进度考核指标')]/following-sibling::table[1]//td[position()>2]",
"//div[contains(text(),'2.经费支出进度考核指标')]/following-sibling::table[1]//td[position()>2]");
//比较预期成果及直接经济效益
//checkTableByName(htmlPrp, document, '预期成果及直接经济效益','预期成果及直接经济效益');
//比对项目经费来源预算
checkTableByPath(htmlPrp, document,
"//div[contains(text(),'项目经费来源预算')]/following-sibling::table[1]//td",
"//td[contains(text(),'项目经费来源预算')]/../following-sibling::tr[2]//td");
//比较项目经费开支预算
checkTableByPath(htmlPrp, document,
"//div[contains(text(),'(二)项目经费开支预算')]/following-sibling::table[1]//td",
"//div[contains(text(),'(二)项目经费开支预算')]/following-sibling::table[1]//tr[position()>2]//td");
//比较承担单位经费分配及配套方案
checkTableByPath(htmlPrp, document,
"//div[contains(text(),'申报单位经费分配及配套方案')]/following-sibling::table[1]//td",
"//div[contains(text(),'(三)承担单位经费分配及配套方案')]/following-sibling::table[1]/tbody/tr[position()>1]//td");
if (bMajor){
//比对课题任务设置
var ktPrp = htmlPrp.querySelectorAll("#ktrw_table > tbody:nth-child(3) td");
var ktCtr = document.querySelectorAll("#tasks > tbody:nth-child(3) td");
for (row = 0; row < Math.min(ktPrp.length / 8, ktCtr.length / 9); row++){
for(var col = 0; col < 8; col++){
if (col < 2){
checkText(ktPrp[row * 8 + col], ktCtr[row * 9 + col]);
}
else{
checkText(ktPrp[row * 8 + col], ktCtr[row * 9 + col + 1]);
}
}
}
}
alert("检查完毕!");
}
}
}
};
}
//忽略空白比较字符串
function isEquality(text1, text2){
return text1.replace(/\s*/g,"") == text2.replace(/\s*/g,"");
}
//
function queryXPath(doc, path){
var result = doc.evaluate(path, doc, null, XPathResult.ANY_TYPE, null);
var nodes = result.iterateNext(); //枚举第一个元素
return nodes;
}
//比较表格数据
function checkTableByName(prp, ctr, textPrp, textCtr){
var pathPrp = "//div[contains(text(),\'"+textPrp+"\')]/following-sibling::table[1]//td";
var pathCtr = "//div[contains(text(),\'"+textCtr+"\')]/following-sibling::table[1]//td";
checkTableByPath(prp, ctr, pathPrp, pathCtr);
}
//比较表格数据
function checkTableByPath(prp, ctr, pathPrp, pathCtr){
var zbPrp = prp.evaluate(pathPrp, prp, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
var zbCtr = ctr.evaluate(pathCtr, ctr, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
for (var i = 0; i < Math.min(zbPrp.snapshotLength, zbCtr.snapshotLength); i++){
checkText(zbPrp.snapshotItem(i), zbCtr.snapshotItem(i));
}
}
//比对申报书和任务书控件内容,并在任务书中显示不同
function checkText(textPrp, textCtr){
var tPrp = textPrp.innerText.trim();
var tCtr= textCtr.innerText.trim();
checkText2(tPrp, tCtr, textCtr);
}
function checkText2(tPrp, tCtr, textCtr){
//如果太短不用修订模式
if (tPrp.length < 25 && tCtr.length < 25){
if (!isEquality(tPrp,tCtr)){//红色为申报书内容,绿色为任务书内容
textCtr.innerHTML = '<del>' + tPrp + '</del><add style="color: red;">' + tCtr +'</add>';
}
else{
textCtr.style.color = "green";
}
return;
}
//修订形式
var diff = JsDiff["diffChars"](tPrp, tCtr);
var fragment = document.createDocumentFragment();
for (var i=0; i < diff.length; i++) {
if (diff[i].added && diff[i + 1] && diff[i + 1].removed) {
var swap = diff[i];
diff[i] = diff[i + 1];
diff[i + 1] = swap;
}
var node;
if (diff[i].removed) {
node = document.createElement('del');
node.style.color = "black"
node.appendChild(document.createTextNode(diff[i].value));
} else if (diff[i].added) {
node = document.createElement('add');
node.style.color = "red"
node.appendChild(document.createTextNode(diff[i].value));
} else {
node = document.createTextNode(diff[i].value);
}
fragment.appendChild(node);
}
textCtr.textContent = '';
textCtr.appendChild(fragment);
textCtr.style.color = "green";
}
})();