EDRI OA

OA小助手

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

// ==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);
})();