EDRI-OA

EDRI OA助手

目前為 2024-12-10 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 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);
})();