您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
OA小助手
当前为
// ==UserScript== // @name EDRI OA // @namespace bsn // @version 1.1.5 // @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/1500083/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="fillContractInvoice">填写合同发票</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({ contractInvoice: '', async fillContractInvoice() { data.contractInvoice = testing ? `发票开票申请资料填写 序号 类别 内容 备注 一、基本信息 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 ` : ''; let isOk = await dialog.successAsync({ title: '合同发票', showIcon: false, content: () => Vue.h(naive.NInputGroup, {}, () => [ Vue.h(naive.NInput, { value: data.contractInvoice, type: 'textarea', placeholder: '请输入合同发票信息', rows: 15, ['onUpdate:value']: v => { data.contractInvoice = v; } }), Vue.h( naive.NButton, { type: 'info', onclick: async () => (data.contractInvoice = 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.contractInvoice ); 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.contractInvoice, 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 } ]); } }); return data; } }; window.initVue3(COM); })();