EDRI OA

OA小助手

// ==UserScript==
// @name         EDRI OA
// @namespace    bsn
// @version      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.gf.qytechs.cn/scripts/520145/1544039/bsn-libs.js
// @match        https://oac.edri.cn:8085/spa/workflow/static4form/index.html?*
// @grant        unsafeWindow
// @grant        GM_addStyle
// @license      GPL version 3
// ==/UserScript==

(function() {
if (!window.location.href.includes('iscreate=1')) return;
GM_addStyle(``);
window.initVue3({
  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="fillInvoice">填写开票申请</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 fillInvoice() {
        data.contractInvoice = testing
          ? `开票申请资料
  开票信息
  合同编号\t2025-03设-001
  合同名称\txx项目
  项目负责人\t朱圣杰
  本次开票金额\t1000000
  发票内容\t设计费
  发票类型\t专用发票(正数)
  我司开票资料
  开户行\t中国银行成都猛追湾支行
  账号\t125254886708
  客户开票资料
  客户开票名称\txx有限公司
  税号\t1234567890W
  单位地址\txx市xx路xx号
  电话号码\t0510-12345678
  开户银行\t中国银行xx支行
  银行账号\t1234567890
  备注\tPO12345678
  `
          : '';
        let isOk =
          testing ||
          (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: {
            contractNo: { title: '合同编号', value: '' },
            contractName: { title: '合同名称', value: '' },
            projectLeader: { title: '项目负责人', value: '' },
            invoiceAmount: { title: '本次开票金额', includes: true, value: '' },
            invoiceContent: { title: '发票内容', value: '' },
            invoiceType: { title: '发票类型', value: '' }
          },
          company: {
            bankOfDeposit: { title: '开户行', value: '' },
            accounts: { title: '账号', value: '' }
          },
          customer: {
            customerName: { title: '客户开票名称', value: '' },
            dutyParagraph: { title: '税号', value: '' },
            customerAddress: { title: '单位地址', value: '' },
            telephone: { title: '电话号码', value: '' },
            customerbank: { title: '开户银行', value: '' },
            bankAccounts: { title: '银行账号', value: '' },
            remarks: { title: '备注', value: '' }
          }
        };
        const patterns = [];
        Object.keys(infos).forEach(key => {
          const o = infos[key];
          Object.keys(o).forEach(key2 => {
            const o2 = o[key2];
            const matches = new RegExp(`(${o2.title}\\s{0,})\\t(.{0,})`).exec(data.contractInvoice);
            if (matches) {
              const [_, head, content] = matches;
              const v = content.trim();
              o2.value = v;
              patterns.push(head + '\t');
              if (v) patterns.push(v);
            }
          });
        });
        await sleep(300);
        isOk =
          testing ||
          (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 table = window.find({ selectors: 'table' });
        window.simulateOperate([
          {
            type: 'click',
            parent: table,
            selectors: 'td',
            findTarget: els => {
              const el = els.find(x => x.innerText.trim().includes('合同编号'));
              if (!el) return;
              return window.find({ parent: el.nextElementSibling, selectors: 'button' });
            },
            nextSteps: [
              {
                type: 'input',
                selectors: '.ant-modal-body .ant-row',
                waiting: 1000,
                value: infos.basic.contractNo.value,
                findTarget: els => {
                  const el = els.find(
                    x => x.innerText.trim() === '合同编号' && !x.className.includes(' ')
                  );
                  if (!el) return;
                  return window.find({ parent: el.nextElementSibling, selectors: 'input' });
                }
              },
              {
                type: 'click',
                selectors: '.ant-modal-body button',
                findTarget: els => {
                  return els.find(x => x.innerText.trim() === '搜 索');
                }
              },
              {
                type: 'click',
                selectors: '.ant-modal-body .ant-table-body tr',
                waiting: 1500
              }
            ]
          },
          {
            type: 'click',
            parent: table,
            selectors: 'td',
            waiting: 1000,
            findTarget: els => {
              const el = els.find(x => x.innerText.trim().includes('项目负责人'));
              if (!el) return;
              const td = el.nextElementSibling;
              const name = window.find({ parent: td, selectors: 'ul a' })?.innerText?.trim();
              if (!name) return window.find({ parent: td, selectors: 'button' });
              if (name === infos.basic.projectLeader.value) return;
              message.error('项目负责人不一致');
            },
            nextSteps: [
              {
                type: 'input',
                selectors: '.ant-modal-body .wea-search-tab input',
                waiting: 1000,
                value: infos.basic.projectLeader.value
              },
              {
                type: 'click',
                selectors: '.ant-modal-body .wea-search-tab button'
              },
              {
                type: 'click',
                selectors: '.ant-modal-body .wea-crm-list li',
                waiting: 1500,
                findTarget: els => {
                  return els.find(x => x.innerText.includes('华东分院')) || els[0];
                }
              }
            ]
          },
          {
            type: 'click',
            selectors: 'td',
            waiting: 500,
            findTarget: els => {
              const el = els.find(x => x.innerText.trim() === '发票类型');
              if (!el) return;
              return window.find({ parent: el.nextElementSibling, selectors: '.ant-select' });
            }
          },
          {
            type: 'click',
            selectors: '.ant-select-dropdown-menu-item',
            waiting: 500,
            findTarget: els => {
              return els.find(x => x.innerText.trim() === infos.basic.invoiceType.value);
            }
          },
          {
            type: 'click',
            selectors: 'td .ant-radio-wrapper',
            findTarget: els => {
              return els.find(x => x.innerText.trim() === 'PDF文件');
            }
          },
          ...[
            infos.basic.invoiceAmount,
            infos.basic.invoiceContent,
            infos.company.bankOfDeposit,
            infos.company.accounts,
            infos.customer.customerName,
            infos.customer.dutyParagraph,
            infos.customer.customerAddress,
            infos.customer.telephone,
            infos.customer.customerbank,
            infos.customer.bankAccounts,
            infos.customer.remarks
          ].map(x => ({
            type: 'input',
            selectors: 'td',
            value: x.value,
            focusable: true,
            findTarget: els => {
              const key = x.key || x.title;
              const el = els.find(y => {
                const txt = y.innerText.trim();
                return (x.includes && txt.includes(key)) || (!x.includes && txt === key);
              });
              if (!el) return;
              return window.find({ parent: el.nextElementSibling, selectors: 'input, textarea' });
            }
          }))
        ]);
      }
    });
    return data;
  }
});
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址