EDRI-OA

EDRI OA助手

当前为 2024-12-10 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         EDRI-OA
// @namespace    bsn
// @version      1.1.1
// @description  EDRI 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);
})();