// ==UserScript==
// @name EDRI OA
// @namespace bsn
// @version 1.1.2
// @description OA小助手
// @author 不死鸟
// @require https://unpkg.com/[email protected]/dist/vue.global.prod.js
// @require data:application/javascript,unsafeWindow.Vue%3DVue%2Cthis.Vue%3DVue%3B
// @require https://unpkg.com/[email protected]/dist/index.js
// @require https://unpkg.com/[email protected]/lscache.js
// @require https://unpkg.com/[email protected]/moment.js
// @require https://unpkg.com/[email protected]/locale/zh-cn.js
// @require https://unpkg.com/[email protected]/dist/html2canvas.js
// @require https://update.greasyfork.org/scripts/520145/1500045/bsn-libs.js
// @match https://oa.edri.cn/Portal/Main/Index*
// @grant unsafeWindow
// @grant GM_addStyle
// @license GPL version 3
// ==/UserScript==
(function() {
GM_addStyle(``);
const COM = {
template: `
<n-form label-placement="left" label-width="auto" size="small" :show-feedback="false">
<n-form-item>
<n-button type="info" style="width: 100%" @click="fill">填写合同发票</n-button>
</n-form-item>
</n-form>
`,
props: {},
emits: ['closeDrawer'],
setup(props, { emit }) {
const message = naive.useMessage();
const dialog = window.createNaiveDialog();
const testing = false;
const data = Vue.reactive({
info: '',
async fill() {
let isOk = await dialog.successAsync({
title: '合同发票',
showIcon: false,
content: () =>
Vue.h(naive.NInputGroup, {}, () => [
Vue.h(naive.NInput, {
value: data.info,
type: 'textarea',
placeholder: '请输入合同发票信息',
rows: 15,
['onUpdate:value']: v => {
data.info = v;
}
}),
Vue.h(
naive.NButton,
{
type: 'info',
onclick: async () => (data.info = await window.getClipboardText())
},
() => '粘贴板'
)
]),
positiveText: '下一步',
negativeText: '取消'
});
if (!isOk) return;
const infos = {
basic: {
contractName: { titles: ['合同名称'], value: '', remark: '' },
contractNo: { titles: ['合同编号'], value: '', remark: '' },
invoiceContent: { titles: ['发票内容'], value: '', remark: '' },
invoiceAmount: { titles: ['发票金额'], value: '', remark: '' },
invoiceType: { titles: ['发票类型'], value: '', remark: '' },
estimatedCollectionDate: { titles: ['预计收款日期'], value: '', remark: '' },
projectLeader: { titles: ['项目负责人'], value: '', remark: '' }
},
company: {
baseAccounts: { titles: ['是否为基本户'], value: '', remark: '' },
bankOfDeposit: { titles: ['开户行'], value: '', remark: '' },
accounts: { titles: ['账号'], value: '', remark: '' }
},
customer: {
customerName: { titles: ['客户开票名称'], value: '', remark: '' },
dutyParagraph: { titles: ['税号'], value: '', remark: '' },
customerAddress: { titles: ['单位地址'], value: '', remark: '' },
telephone: { titles: ['电话号码'], value: '', remark: '' },
customerbank: { titles: ['开户银行'], value: '', remark: '' },
bankAccounts: { titles: ['银行账户'], value: '', remark: '' }
},
other: {
remarks: { titles: ['备注'], value: '', remark: '' }
}
};
const patterns = [];
Object.keys(infos).forEach(key => {
const o = infos[key];
Object.keys(o).forEach(key2 => {
const o2 = o[key2];
o2.titles.forEach(title => {
const matches = new RegExp(`(${title}\\s{0,})\\t(.{0,})\\t(.{0,})`).exec(data.info);
if (matches) {
const [_, head, content, remark] = matches;
const v = content.trim();
const r = remark.trim();
o2.value = v;
o2.remark = r;
patterns.push(head + '\t');
if (v) patterns.push(v);
if (r) patterns.push('\t' + remark);
}
});
});
});
await sleep(300);
isOk = await dialog.successAsync({
title: '匹配结果',
showIcon: false,
content: () =>
Vue.h(naive.NScrollbar, { style: 'max-height: calc(100vh - 200px)' }, () =>
Vue.h(naive.NHighlight, {
text: data.info,
patterns: patterns,
style: 'word-break: normal;white-space: pre-wrap'
})
),
positiveText: '下一步',
negativeText: '取消'
});
if (!isOk) return;
emit('closeDrawer');
const iframe = window.findAll({ selectors: 'iframe' }).find(el => {
const srcAttr = Array.from(el.attributes).find(x => x.name === 'src');
return srcAttr && srcAttr.nodeValue.startsWith('/MvcConfig/UI/Form');
});
window.simulateOperate([
{
type: 'input',
parent: iframe,
selectors: '[name="ContractName"]',
value: infos.basic.contractName.value
},
{
type: 'input',
parent: iframe,
selectors: '[name="ContractNo"]',
value: infos.basic.contractNo.value
},
{
type: 'input',
parent: iframe,
selectors: '[name="InvoiceContent"]',
value: infos.basic.invoiceContent.value
},
{
type: 'input',
parent: iframe,
selectors: '[name="InvoiceAmount"]',
value: infos.basic.invoiceAmount.value,
findTarget: el => {
const parentEl = el.parentElement;
return parentEl.getElementsByClassName('mini-buttonedit-input')[0];
}
},
{
type: 'click',
parent: iframe,
selectors: '[name="InvoiceType"]',
focusable: true,
waiting: 500,
findTarget: el => {
return el.parentElement.querySelector('.mini-buttonedit-input');
}
},
{
type: 'click',
parent: iframe,
selectors: '.mini-popup table tr',
focusable: true,
waiting: 1000,
findTarget: el => {
return el.innerText.includes(infos.basic.invoiceType.value) &&
el.innerText.includes('电子')
? el
: undefined;
}
},
{
type: 'input',
parent: iframe,
selectors: '[name="EstimatedCollectionDate"]',
value: infos.basic.estimatedCollectionDate.value,
waiting: 500,
findTarget: el => {
const parentEl = el.parentElement;
return parentEl.getElementsByClassName('mini-buttonedit-input')[0];
}
},
{
type: 'input',
parent: iframe,
selectors: '[name="ProjectLeaderName"]',
value: infos.basic.projectLeader.value,
focusable: true,
waiting: 500
},
{
type: 'click',
parent: iframe,
selectors: '[name="BaseAccounts"]',
findTarget: el => {
const parentEl = el.parentElement;
return Array.from(parentEl.querySelectorAll('label')).find(
x => x.innerText === infos.company.baseAccounts.value
);
}
},
{
type: 'input',
parent: iframe,
selectors: '[name="BankOfDeposit"]',
value: infos.company.bankOfDeposit.value
},
{
type: 'input',
parent: iframe,
selectors: '[name="Accounts"]',
value: infos.company.accounts.value
},
{
type: 'input',
parent: iframe,
selectors: '[name="CustomerName"]',
value: infos.customer.customerName.value
},
{
type: 'input',
parent: iframe,
selectors: '[name="Dutyparagraph"]',
value: infos.customer.dutyParagraph.value
},
{
type: 'input',
parent: iframe,
selectors: '[name="CustomerAddress"]',
value: infos.customer.customerAddress.value
},
{
type: 'input',
parent: iframe,
selectors: '[name="Telephone"]',
value: infos.customer.telephone.value
},
{
type: 'input',
parent: iframe,
selectors: '[name="Customerbank"]',
value: infos.customer.customerbank.value
},
{
type: 'input',
parent: iframe,
selectors: '[name="BankAccounts"]',
value: infos.customer.bankAccounts.value
},
{
type: 'input',
parent: iframe,
selectors: '[name="Remarks"]',
value: infos.other.remarks.value
}
]);
}
});
if (testing) {
data.info = `发票开票申请资料填写
序号 类别 内容 备注
一、基本信息
1 合同名称\t苏州xx公司疫苗项目\t
2 合同编号\t2025-xx-xxx\t
3 发票内容\t设计费\t
4 发票金额\t10000\t
5 发票类型\t专用发票\t
6 预计收款日期\t2025/1/1\t
7 项目负责人\t李洪群\t
二、我公司开票资料(如果选择基本户,不用填写开户行及帐号)
1 是否为基本户\t是\t
2 开户行\t\t
3 账号\t\t
三、客户开票资料
1 客户开票名称\t苏州xx公司\t
2 税号\t123456789012345678\t
3 单位地址\t江苏苏州工业园区\t
4 电话号码\t0512-12345678\t
5 开户银行\t中国银行\t
6 银行账户\t123456789012\t
四、其他信息
1 备注\t\t
`;
}
return data;
}
};
window.initVue3(COM);
})();