king
2023-02-02 6f817bf3ae4e6f51f982c07b0713adb3caf9fac2
2023-02-02
9个文件已修改
703 ■■■■ 已修改文件
src/menu/components/module/voucher/options.jsx 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/share/actioncomponent/formconfig.jsx 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/module/account/index.jsx 30 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/module/voucher/index.jsx 168 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/module/voucher/index.scss 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/module/voucher/voucherTable/index.jsx 354 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/module/voucher/voucherTable/index.scss 28 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/zshare/actionList/normalbutton/index.jsx 54 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/formconfig.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/module/voucher/options.jsx
@@ -39,6 +39,12 @@
        {value: 'checkVoucher', label: '查看凭证'},
        {value: 'createTemp', label: '新增模板'},
        {value: 'checkTemp', label: '编辑模板'},
      ],
      controlFields: [
        {field: 'businessType', values: ['createVoucher', 'checkVoucher']},
        {field: 'voucherType', values: ['createVoucher', 'checkVoucher']},
        {field: 'voucherTypeText', values: ['createVoucher', 'checkVoucher']},
        {field: 'voucherSign', values: ['createVoucher', 'checkVoucher']},
      ]
    },
    {
@@ -70,6 +76,34 @@
      allowClear: true
    },
    {
      type: 'text',
      field: 'businessType',
      label: '业务类型',
      initval: wrap.businessType || 'fcc01',
      required: true
    },
    {
      type: 'text',
      field: 'voucherType',
      label: '凭证类型',
      initval: wrap.voucherType || 'fcc_keeping',
      required: true
    },
    {
      type: 'text',
      field: 'voucherTypeText',
      label: '凭证类型文本',
      initval: wrap.voucherTypeText || '记账凭证',
      required: true
    },
    {
      type: 'text',
      field: 'voucherSign',
      label: '凭证类型标识',
      initval: wrap.voucherSign || 'fcc_keeping',
      required: true
    },
    {
      type: 'cascader',
      field: 'supModule',
      label: '上级组件',
src/menu/components/share/actioncomponent/formconfig.jsx
@@ -523,7 +523,7 @@
      key: 'execSuccess',
      label: '成功后',
      initVal: card.execSuccess || 'grid',
      tooltip: refresh.length ? '执行刷新源组件时,请在源按钮中设置关闭后刷新那一项,注:此时会同步刷新当前组件和上级组件-行。' : '选择刷新行时,如果选择多条数据会刷新表格。注:上级组件在数据源中添加。',
      tooltip: refresh.length ? '执行刷新源组件时,请在源按钮中设置关闭后刷新那一项,注:此时会同步刷新当前组件和上级组件-行。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。' : '选择刷新行时,如果选择多条数据会刷新表格。注:上级组件在数据源中添加。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。',
      required: true,
      options: [{
        value: 'never',
@@ -546,7 +546,7 @@
      key: 'execError',
      label: '失败后',
      initVal: card.execError || 'never',
      tooltip: refresh.length ? '执行刷新源组件时,请在源按钮中设置关闭后刷新那一项,注:此时会同步刷新当前组件和上级组件-行。' : '选择刷新行时,如果选择多条数据会刷新表格,注:上级组件在数据源中添加。',
      tooltip: refresh.length ? '执行刷新源组件时,请在源按钮中设置关闭后刷新那一项,注:此时会同步刷新当前组件和上级组件-行。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。' : '选择刷新行时,如果选择多条数据会刷新表格,注:上级组件在数据源中添加。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。',
      required: true,
      options: [{
        value: 'never',
@@ -1468,7 +1468,7 @@
      key: 'execSuccess',
      label: '成功后',
      initVal: card.execSuccess || 'grid',
      tooltip: refresh.length ? '执行刷新源组件时,请在源按钮中设置关闭后刷新那一项,注:此时会同步刷新当前组件和上级组件-行。' : '选择刷新行时,如果选择多条数据会刷新表格。注:上级组件在数据源中添加。',
      tooltip: refresh.length ? '执行刷新源组件时,请在源按钮中设置关闭后刷新那一项,注:此时会同步刷新当前组件和上级组件-行。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。' : '选择刷新行时,如果选择多条数据会刷新表格。注:上级组件在数据源中添加。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。',
      required: true,
      options: [{
        value: 'never',
@@ -1490,7 +1490,7 @@
      key: 'execError',
      label: '失败后',
      initVal: card.execError || 'never',
      tooltip: refresh.length ? '执行刷新源组件时,请在源按钮中设置关闭后刷新那一项,注:此时会同步刷新当前组件和上级组件-行。' : '选择刷新行时,如果选择多条数据会刷新表格,注:上级组件在数据源中添加。',
      tooltip: refresh.length ? '执行刷新源组件时,请在源按钮中设置关闭后刷新那一项,注:此时会同步刷新当前组件和上级组件-行。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。' : '选择刷新行时,如果选择多条数据会刷新表格,注:上级组件在数据源中添加。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。',
      required: true,
      options: [{
        value: 'never',
src/tabviews/custom/components/module/account/index.jsx
@@ -3,8 +3,10 @@
import { is, fromJS } from 'immutable'
import { notification, Select, Divider } from 'antd'
import { PlusOutlined } from '@ant-design/icons'
import moment from 'moment'
import Api from '@/api'
import Utils from '@/utils/utils.js'
import MKEmitter from '@/utils/events.js'
import './index.scss'
@@ -39,7 +41,9 @@
  loadData = () => {
    let param = {
      func: 's_get_fcc_book_data'
      func: 's_get_fcc_book_data',
      dataM: sessionStorage.getItem('dataM') === 'true' ? 'Y' : '',
      mk_organization: sessionStorage.getItem('organization') || ''
    }
    Api.genericInterface(param).then(res => {
@@ -69,10 +73,6 @@
        return true
      })
      if (!activeItem && books.length > 0) {
        activeItem = books[0]
      }
      this.setState({books, activeItem})
      if (activeItem) {
@@ -90,6 +90,22 @@
    if (activeItem) {
      MKEmitter.emit('resetSelectLine', this.props.config.uuid, activeItem.id, activeItem)
      let userid = sessionStorage.getItem('UserID') || ''
      let sid = localStorage.getItem('SessionUid') || ''
      let param = {
        func: 'sPC_TableData_InUpDe',
        LText: `delete  tmp_session_show_key where createuserid='${userid}' and createuser='${sid}' and key_type='fcc_years'
          insert into tmp_session_show_key ( key_id,key_type,createuserid,CreateUser,CreateStaff)
          select '${activeItem.id}','fcc_years','${userid}','${sid}','${sessionStorage.getItem('Full_Name') || ''}'`,
        exec_type: 'y'
      }
      param.timestamp = moment().format('YYYY-MM-DD HH:mm:ss')
      param.secretkey = Utils.encrypt('', param.timestamp)
      param.LText = Utils.formatOptions(param.LText)
      Api.genericInterface(param)
    }
  }
@@ -132,11 +148,11 @@
          </div>
        )}>
          {books.map(item => (
            <Option key={item.id}>{item.account_name}</Option>
            <Option disabled={!item.months} key={item.id}>{item.account_name}</Option>
          ))}
        </Select> : <Select value={activeItem ? activeItem.id : ''} placeholder="请选择账套" onChange={this.changeBook}>
          {books.map(item => (
            <Option key={item.id}>{item.account_name}</Option>
            <Option disabled={!item.months} key={item.id}>{item.account_name}</Option>
          ))}
        </Select>}
        {activeItem ? <span className="date">{activeItem.date}</span> : null}
src/tabviews/custom/components/module/voucher/index.jsx
@@ -1,10 +1,11 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Button, Select, Input, Modal, DatePicker, notification } from 'antd'
import { Button, Select, Input, Modal, DatePicker, notification, InputNumber } from 'antd'
import moment from 'moment'
import Api from '@/api'
import Utils from '@/utils/utils.js'
import asyncComponent from '@/utils/asyncComponent'
import MKEmitter from '@/utils/events.js'
import './index.scss'
@@ -27,12 +28,16 @@
    tbdata: [],
    typeOptions: [],
    charType: '',
    charName: '',
    charInt: '',
    vouDate: null,
    book: null,
    username: sessionStorage.getItem('User_Name'),
    remark: '',
    remarkVisible: false,
    attachments: 0,
    title: '',
    delItems: [],
    status: '' // 新建时,empty、change、saved
  }
@@ -116,8 +121,9 @@
    let param = {
      func: 's_get_fcc_account_data',
      account_code: book.account_code || '',
      fcc_date: book.months ? book.months + '-01' : moment().format('YYYY-MM-DD')
      // account_code: book.account_code || '',
      fcc_date: book.months ? book.months + '-01' : moment().format('YYYY-MM-DD'),
      BID: book.id
    }
    Api.genericInterface(param).then(res => {
@@ -135,6 +141,7 @@
      this.setState({
        typeOptions: typeOptions,
        charType: typeOptions[0] ? typeOptions[0].voucher_class : '',
        charName: typeOptions[0] ? typeOptions[0].voucher_char : '',
        charInt: typeOptions[0] ? typeOptions[0].voucher_char_int : '',
      })
@@ -187,8 +194,13 @@
        department: department,
        project: project,
        inventory: inventory,
        currency: res.currency || [],
        employee: employee,
        cash_flow: cash_flow,
        orgcode: res.orgcode,
        orgname: res.orgname,
        account_code: res.account_code,
        account_year_code: res.account_year_code
      }
      window.GLOB.CacheVoucher.set(config.uuid, message)
@@ -230,11 +242,12 @@
  }
  triggersave = (t) => {
    const { tbdata } = this.state
    const { tbdata, delItems } = this.state
    let err = ''
    let tip = ''
    let list = []
    let _Items = [...delItems]
    tbdata.forEach((line, index) => {
      if (err) return
@@ -250,7 +263,10 @@
      if (!line.remark && !line.subjectscode && !line.debtor && line.debtor !== 0 && !line.creditor && line.creditor !== 0) {
        if (_index === 1) {
          err = '第1行不可为空。'
        } else if (line.$origin) {
          _Items.push(line)
        }
        return
      }
@@ -262,6 +278,8 @@
        err = `第${_index}行,请输入金额。`
      } else if (line.debtor === 0 || line.creditor === 0) {
        err = `第${_index}行,金额不能为0。`
      } else if (line.foreign_currency_type === 'Y' && !line.origin) {
        err = `第${_index}行,原币不可为空或为0。`
      } else if (line.sup_accounting) {
        line.sup_accounting.split(',').forEach(item => {
          if (!line[item]) {
@@ -303,17 +321,17 @@
      confirm({
        content: tip + '确认要保存吗?',
        onOk() {
          _this.voucherSave(list, t)
          _this.voucherSave(list, _Items, t)
        },
        onCancel() {}
      })
    } else {
      this.voucherSave(list, t)
      this.voucherSave(list, _Items, t)
    }
  }
  voucherSave = (list, t) => {
    const { BID, config, charInt, charType, vouDate, book, remark } = this.state
  voucherSave = (list, items, t) => {
    const { config, charInt, charType, vouDate, book, remark, charName, attachments, title } = this.state
    if (!book) {
      notification.warning({
@@ -324,59 +342,84 @@
      return
    }
    let message = window.GLOB.CacheVoucher.get(config.uuid) || {}
    let param = {
      func: 's_fcc_voucher_addupt',
      BID: BID,
      BID: book.id,
      ID: Utils.getguid(),
      voucher_code: '',
      voucher_text: '',
      voucher_text: title,
      remark: remark,
      account_year_code: '',
      voucher_type: '',
      voucher_type_text: '',
      orgcode: '',
      orgname: '',
      voucher_class: '',
      account_year_code: book.account_year_code || '',
      voucher_type: config.wrap.voucherType || '',
      voucher_type_text: config.wrap.voucherTypeText || '',
      orgcode: message.orgcode || '',
      orgname: message.orgname || '',
      voucher_class: charType,
      years: book.years,
      business_type: '',
      voucher_sign: '',
      voucher_char: charType,
      business_type: config.wrap.businessType || '',
      voucher_sign: config.wrap.voucherSign || '',
      voucher_char: charName,
      voucher_char_int: charInt,
      account_code: book.account_code || '',
      fibvoucherdate: vouDate,
      fibvoucherdate: moment(vouDate).format('YYYY-MM-DD'),
      UserName: sessionStorage.getItem('User_Name') || '',
      FullName: sessionStorage.getItem('Full_Name') || '',
      attachments_int: attachments,
      sup_data: '',
      subject_data: ''
    }
    console.log(list)
    // subject_id,subject_voucher_code,voucher_lp,subject_code,subject_name
    // ,subject_voucher_text,fcc_count,net_unitprice,unit,net_amount,direction_type
    // ,exratecode,exratename,unitratio,sup_accounting ,direction_type_count,src_amount,deleted,local_exratecode
    let subject_data = list.map(item => {
      let count = item.count_type === 'Y'
      let curr = item.foreign_currency_type === 'Y'
      return `${item.uuid},'','','${item.subjectscode}','${item.subjectsname}','${item.remark}',${count ? item.count || 0 : 0},${count ? item.price || 0 : 0},'${item.unit}',${item.debtor || item.creditor},'${item.debtor ? 'debit' : 'credit'}','${curr ? item.exratecode : '01010001'}','${curr ? item.exratename : 'CNY'}',${curr ? item.unitratio || 0 : 0},'${item.sup_accounting}',${item.debtor ? 1 : -1},${curr ? item.origin || 0 : 0},0,'${item.local_currency || ''}'`
    })
    items.forEach(item => {
      let count = item.count_type === 'Y'
      let curr = item.foreign_currency_type === 'Y'
      subject_data.push(`${item.uuid},'','','${item.subjectscode}','${item.subjectsname}','${item.remark}',${count ? item.count || 0 : 0},${count ? item.price || 0 : 0},'${item.unit}',${item.debtor || item.creditor},'${item.debtor ? 'debit' : 'credit'}','${curr ? item.exratecode : '01010001'}','${curr ? item.exratename : 'CNY'}',${curr ? item.unitratio || 0 : 0},'${item.sup_accounting}',${item.debtor ? 1 : -1},${curr ? item.origin || 0 : 0},1,'${item.local_currency || ''}'`)
    })
    param.subject_data = window.btoa(window.encodeURIComponent(subject_data.join(';un')))
    if (param) {
    console.log(param)
    console.log(config)
      return
    }
    // Api.genericInterface(param).then(res => {
    //   if (!res.status) {
    //     notification.warning({
    //       top: 92,
    //       message: res.message,
    //       duration: 5
    //     })
    //     return
    //   }
    Api.genericInterface(param).then(res => {
      if (!res.status) {
        notification.warning({
          top: 92,
          message: res.message,
          duration: 5
        })
        return
      }
    //   if (t === 'add') {
    //     this.setState({
    //       status: 'empty',
    //       remark: '',
    //       tbdata: [],
    //       charInt: charInt + 1
    //     })
    //     MKEmitter.emit('cleartable', config.uuid)
    //   } else {
    //     this.setState({
    //       status: 'saved'
    //     })
    //   }
    // })
      if (t === 'add') {
        this.setState({
          status: 'empty',
          remark: '',
          tbdata: [],
          delItems: [],
          charInt: charInt + 1
        })
        MKEmitter.emit('cleartable', config.uuid)
      } else {
        this.setState({
          status: 'saved',
          delItems: [],
        })
      }
    })
  }
  triggerprint = () => {
@@ -399,15 +442,35 @@
    this.setState({remark: val, remarkVisible: false})
  }
  dataChange = (data) => {
  dataChange = (data, item) => {
    if (item) {
      this.setState({
        status: 'change',
        tbdata: data,
        delItems: [...this.state.delItems, item]
      })
    } else {
    this.setState({
      status: 'change',
      tbdata: data
    })
  }
  }
  changeAttach = (val) => {
    let _val = val
    if (isNaN(val) || val < 0) {
      _val = 0
    } else {
      _val = parseInt(val)
    }
    this.setState({attachments: _val})
  }
  render() {
    const { type, status, loading, config, typeOptions, charType, charInt, data, vouDate, username, remark, remarkVisible } = this.state
    const { type, status, loading, config, typeOptions, charType, charInt, data, vouDate, username, remark, remarkVisible, attachments, title } = this.state
    return (
      <div className="menu-voucher-wrap" style={config.style}>
@@ -420,18 +483,21 @@
        <div className="voucher-body">
          {type === 'createVoucher' ? <div className="pre-wrap">
            <div className="voucher-code">
              <Select value={charType} dropdownClassName="mk-vcode-dropdown" onChange={(val, option) => this.setState({charType: val, charInt: option.props.charint})}>
              <Select value={charType} dropdownClassName="mk-vcode-dropdown" onChange={(val, option) => this.setState({charType: val, charName: option.props.charName, charInt: option.props.charint})}>
                {typeOptions.map(option =>
                  <Select.Option key={option.voucher_char_int} value={option.voucher_class} charint={option.voucher_char_int}>{option.voucher_char}</Select.Option>
                  <Select.Option key={option.voucher_char_int} value={option.voucher_class} charName={option.voucher_char} charint={option.voucher_char_int}>{option.voucher_char}</Select.Option>
                )}
              </Select>
              <Input value={charInt} autoComplete="off" onChange={(e) => this.setState({charInt: e.target.value})}/> 号
              <InputNumber precision={0} min={1} value={charInt} autoComplete="off" onChange={(val) => this.setState({charInt: val})}/> 号
            </div>
            <div className="voucher-date">
              日期:<DatePicker value={vouDate} onChange={(val) => this.setState({vouDate: val})}/>
            </div>
            <div className="voucher-text">
              <Input value={title} placeholder="凭证文本" autoComplete="off" onChange={(e) => this.setState({title: e.target.value})}/>
            </div>
            <div className="voucher-affix">
              附单据 <Input autoComplete="off" /> 张
              附单据 <InputNumber precision={0} value={attachments || 0} autoComplete="off" onChange={this.changeAttach}/> 张
              <Button type="link" className="" onClick={this.triggerprint}>附件</Button>
              <Button type="link" className="" onClick={this.triggerprint}>备注</Button>
            </div>
src/tabviews/custom/components/module/voucher/index.scss
@@ -33,6 +33,22 @@
      .ant-input {
        width: 60px;
      }
      .ant-input-number {
        display: inline-block;
        width: 60px;
        .ant-input-number-handler-wrap {
          display: none;
        }
      }
    }
    .voucher-affix {
      .ant-input-number {
        display: inline-block;
        width: 50px;
        .ant-input-number-handler-wrap {
          display: none;
        }
      }
    }
    .pre-wrap {
      padding: 10px 0px;
@@ -43,9 +59,14 @@
        width: 120px;
      }
    }
    .voucher-text {
      display: inline-block;
      width: calc(56% - 350px);
      margin-left: 12px;
    }
    .voucher-affix {
      float: right;
      width: 250px;
      width: 240px;
      .ant-input {
        width: 60px;
      }
src/tabviews/custom/components/module/voucher/voucherTable/index.jsx
@@ -120,7 +120,10 @@
    editing: false,
    visible: false,
    counting: false,
    priceing: false
    priceing: false,
    curring: false,
    ratioing: false,
    origining: false,
  }
  componentDidMount () {
@@ -174,6 +177,14 @@
      }
    }
    if (line.foreign_currency_type === 'Y' && line.origin) {
      if (line.debtor) {
        line.unitratio = Math.round(line.debtor / line.origin * 100000) / 100000
      } else if (line.creditor) {
        line.unitratio = Math.round(line.creditor / line.origin * 100000) / 100000
      }
    }
    MKEmitter.emit('changeRecord', col.tableId, line)
    setTimeout(() => {
@@ -195,10 +206,8 @@
    if (col.field === 'subjectscode') {
      this.setState({editing: true}, () => {
        try {
          let node = document.getElementById(col.uuid + record.uuid)
          node.click()
        } catch(e) {}
        node && node.click()
      })
    } else {
      this.setState({editing: true, value: record[col.field]}, () => {
@@ -234,6 +243,14 @@
          line.price = Math.round(line.debtor / line.count * 10000) / 10000
        } else if (line.creditor) {
          line.price = Math.round(line.creditor / line.count * 10000) / 10000
        }
      }
      if (line.foreign_currency_type === 'Y' && line.origin) {
        if (line.debtor) {
          line.unitratio = Math.round(line.debtor / line.origin * 100000) / 100000
        } else if (line.creditor) {
          line.unitratio = Math.round(line.creditor / line.origin * 100000) / 100000
        }
      }
@@ -282,6 +299,16 @@
      })
    }
    if (line.foreign_currency_type === 'Y' && line.foreign_currency) {
      let msg = window.GLOB.CacheVoucher.get(col.tableId)
      let cur = msg ? msg.currency.filter(n => n.exratename === line.foreign_currency)[0] : null
      if (cur) {
        line = {...line, ...cur}
      }
      this.currencyChange(line)
    }
    MKEmitter.emit('changeRecord', col.tableId, line)
    if (line.sup_accounting) {
@@ -292,6 +319,11 @@
      this.setState({counting: true, value: line.count || 0}, () => {
        let node = document.getElementById(col.uuid + record.uuid + 'count')
        node && node.select()
      })
    } else if (line.foreign_currency_type === 'Y') {
      this.setState({curring: true}, () => {
        let node = document.getElementById(col.uuid + record.uuid + 'currency')
        node && node.click()
      })
    } else {
      this.setState({editing: false, visible: false, counting: false, priceing: false})
@@ -371,9 +403,7 @@
      line.count = 0
    }
    if (line.count && line.price) {
      line.debtor = Math.round(line.count * line.price * 100) / 100
    }
    this.countChange(line)
    MKEmitter.emit('changeRecord', col.tableId, line)
@@ -396,9 +426,7 @@
      line.count = 0
    }
    if (line.count && line.price) {
      line.debtor = Math.round(line.count * line.price * 100) / 100
    }
    this.countChange(line)
    
    MKEmitter.emit('changeRecord', col.tableId, line)
  }
@@ -414,9 +442,7 @@
      line.price = 0
    }
    if (line.count && line.price) {
      line.debtor = Math.round(line.count * line.price * 100) / 100
    }
    this.countChange(line)
    MKEmitter.emit('changeRecord', col.tableId, line)
@@ -439,16 +465,181 @@
      line.price = 0
    }
    if (line.count && line.price) {
      line.debtor = Math.round(line.count * line.price * 100) / 100
    }
    this.countChange(line)
    
    MKEmitter.emit('changeRecord', col.tableId, line)
  }
  editCurrency = (e) => {
    const { col, record } = this.props
    e.stopPropagation()
    this.setState({curring: true}, () => {
      let node = document.getElementById(col.uuid + record.uuid + 'currency')
      node && node.click()
    })
  }
  onCurrSelectChange = (val, option) => {
    const { col, record } = this.props
    let line = {...record, ...option.props.extra}
    this.currencyChange(line)
    MKEmitter.emit('changeRecord', col.tableId, line)
    if (line.exratename === 'CNY') {
      this.setState({curring: false, origining: true, value: line.origin || 0}, () => {
        let node = document.getElementById(col.uuid + record.uuid + 'origin')
        node && node.select()
      })
    } else {
      this.setState({curring: false, ratioing: true, value: line.unitratio || 1}, () => {
        let node = document.getElementById(col.uuid + record.uuid + 'ratio')
        node && node.select()
      })
    }
  }
  editRatio = (e) => {
    const { col, record } = this.props
    e.stopPropagation()
    this.setState({ratioing: true, value: record.unitratio || 1}, () => {
      let node = document.getElementById(col.uuid + record.uuid + 'ratio')
      node && node.select()
    })
  }
  ratioPress = () => {
    const { col, record } = this.props
    const { value } = this.state
    let line = {...record}
    line.unitratio = value || 1
    if (isNaN(line.unitratio)) {
      line.unitratio = 1
    }
    this.currencyChange(line)
    MKEmitter.emit('changeRecord', col.tableId, line)
    this.setState({ratioing: false, origining: true, value: line.origin || 0}, () => {
      let node = document.getElementById(col.uuid + record.uuid + 'origin')
        node && node.select()
    })
  }
  ratioBlur = () => {
    const { col, record } = this.props
    const { value } = this.state
    this.setState({ratioing: false})
    let line = {...record}
    line.unitratio = value || 1
    if (isNaN(line.unitratio)) {
      line.unitratio = 1
    }
    this.currencyChange(line)
    MKEmitter.emit('changeRecord', col.tableId, line)
  }
  editOrigin = (e) => {
    const { col, record } = this.props
    e.stopPropagation()
    this.setState({origining: true, value: record.origin || 1}, () => {
      let node = document.getElementById(col.uuid + record.uuid + 'origin')
      node && node.select()
    })
  }
  originPress = () => {
    const { col, record } = this.props
    const { value } = this.state
    let line = {...record}
    line.origin = value || 0
    if (isNaN(line.origin)) {
      line.origin = 0
    }
    this.currencyChange(line)
    MKEmitter.emit('changeRecord', col.tableId, line)
    this.setState({origining: false})
    setTimeout(() => {
      MKEmitter.emit('tdFocus', 'debtor' + record.uuid)
    }, 50)
  }
  originBlur = () => {
    const { col, record } = this.props
    const { value } = this.state
    this.setState({origining: false})
    let line = {...record}
    line.origin = value || 0
    if (isNaN(line.origin)) {
      line.origin = 0
    }
    this.currencyChange(line)
    MKEmitter.emit('changeRecord', col.tableId, line)
  }
  countChange = (line) => {
    if (line.count && line.price) {
      if (line.creditor) {
        line.creditor = Math.round(line.count * line.price * 100) / 100
      } else {
        line.debtor = Math.round(line.count * line.price * 100) / 100
      }
      if (line.foreign_currency_type === 'Y' && line.origin) {
        if (line.debtor) {
          line.unitratio = Math.round(line.debtor / line.origin * 100000) / 100000
        } else if (line.creditor) {
          line.unitratio = Math.round(line.creditor / line.origin * 100000) / 100000
        }
      }
    }
  }
  currencyChange = (line) => {
    if (line.unitratio && line.origin) {
      if (line.creditor) {
        line.creditor = Math.round(line.unitratio * line.origin * 100) / 100
      } else {
        line.debtor = Math.round(line.unitratio * line.origin * 100) / 100
      }
      if (line.count_type === 'Y' && line.count) {
        if (line.debtor) {
          line.price = Math.round(line.debtor / line.count * 10000) / 10000
        } else if (line.creditor) {
          line.price = Math.round(line.creditor / line.count * 10000) / 10000
        }
      }
    }
  }
  render() {
    let { col, record, className } = this.props
    const { editing, visible, counting, priceing } = this.state
    const { editing, visible, counting, priceing, curring, ratioing, origining } = this.state
    let children = null
    let colSpan = 1
@@ -501,7 +692,7 @@
            >
              {subjects.map((item, i) => (<Select.Option key={i} extra={item} value={item.subjectscode}>{item.subjectscode + ' ' + item.subjectsname}</Select.Option>))}
            </Select>
            <Popover overlayClassName="subject-pop-wrap" placement="bottom" title="辅助核算" visible={visible} content={<Accounting confirm={this.confirm} cancel={this.cancel} tableId={col.tableId} data={record}/>}>
            <Popover overlayClassName="subject-pop-wrap" placement="bottom" title="" visible={visible} content={<Accounting confirm={this.confirm} cancel={this.cancel} tableId={col.tableId} data={record}/>}>
              <span className="pop-anchor"></span>
            </Popover>
          </>
@@ -517,39 +708,34 @@
            })
          }
          let countNode = null
          let currencyNode = null
          if (record.count_type === 'Y') {
            if (counting) {
              children = <div className="content-wrap" onClick={this.focus}>
                <div>{val}</div>
                <div className="count-wrap">
                  <span style={{marginRight: '5px'}}>
              countNode = <div className="count-wrap">
                <span style={{marginRight: '5px'}} onClick={(e) => e.stopPropagation()}>
                    <span>数量:</span>
                    <span><InputNumber className="inner-input" id={col.uuid + record.uuid + 'count'} defaultValue={record.count || 0} onChange={(val) => this.onChange(val)} onPressEnter={this.countPress} onBlur={this.countBlur}/></span>
                  <span><InputNumber precision={4} className="inner-input" id={col.uuid + record.uuid + 'count'} defaultValue={record.count || 0} onChange={(val) => this.onChange(val)} onPressEnter={this.countPress} onBlur={this.countBlur}/></span>
                  </span>
                  <span onClick={this.editPrice}>
                    <span>单价:</span>
                    <span>{record.price || 0}</span>
                  </span>
                </div>
              </div>
            } else if (priceing) {
              children = <div className="content-wrap" onClick={this.focus}>
                <div>{val}</div>
                <div className="count-wrap">
              countNode = <div className="count-wrap">
                  <span style={{marginRight: '5px'}} onClick={this.editCount}>
                    <span>数量:</span>
                    <span>{record.count || 0}</span>
                  </span>
                  <span>
                <span onClick={(e) => e.stopPropagation()}>
                    <span>单价:</span>
                    <span><InputNumber className="inner-input" id={col.uuid + record.uuid + 'price'} defaultValue={record.price || 0} onChange={(val) => this.onChange(val)} onPressEnter={this.pricePress} onBlur={this.priceBlur}/></span>
                  <span><InputNumber precision={4} className="inner-input" id={col.uuid + record.uuid + 'price'} defaultValue={record.price || 0} onChange={(val) => this.onChange(val)} onPressEnter={this.pricePress} onBlur={this.priceBlur}/></span>
                  </span>
                </div>
              </div>
            } else {
              children = <div className="content-wrap" onClick={this.focus}>
                <div>{val}</div>
                <div className="count-wrap">
              countNode = <div className="count-wrap">
                  <span style={{marginRight: '5px'}} onClick={this.editCount}>
                    <span>数量:</span>
                    <span>{record.count || 0}</span>
@@ -559,11 +745,92 @@
                    <span>{record.price || 0}</span>
                  </span>
                </div>
            }
          }
          if (record.foreign_currency_type === 'Y') {
            if (curring) {
              let msg = window.GLOB.CacheVoucher.get(col.tableId)
              let currency = msg ? msg.currency : []
              currencyNode = <div className="count-wrap">
                <span style={{marginRight: '5px'}} onClick={(e) => e.stopPropagation()}>
                  <span>货币:</span>
                  <span>
                    <Select
                      className="currency-select"
                      defaultValue={record.exratename || ''}
                      dropdownClassName="edit-table-dropdown"
                      id={col.uuid + record.uuid + 'currency'}
                      onBlur={() => this.setState({curring: false})}
                      onSelect={this.onCurrSelectChange}
                    >
                      {currency.map((item, i) => (<Select.Option key={i} extra={item} value={item.exratename}>{item.exratename}</Select.Option>))}
                    </Select>
                  </span>
                </span>
                <span style={{marginRight: '5px'}} onClick={this.editRatio}>
                  <span>汇率:</span>
                  <span>{record.unitratio || 1}</span>
                </span>
                <span onClick={this.editOrigin}>
                  <span>原币:</span>
                  <span>{record.origin || 0}</span>
                </span>
              </div>
            } else if (ratioing) {
              currencyNode = <div className="count-wrap">
                <span style={{marginRight: '5px'}} onClick={this.editCurrency}>
                  <span>货币:</span>
                  <span>{record.exratename || ''}</span>
                </span>
                <span style={{marginRight: '5px'}} onClick={(e) => e.stopPropagation()}>
                  <span>汇率:</span>
                  <span><InputNumber precision={5} className="inner-input" id={col.uuid + record.uuid + 'ratio'} defaultValue={record.unitratio || 1} onChange={(val) => this.onChange(val)} onPressEnter={this.ratioPress} onBlur={this.ratioBlur}/></span>
                </span>
                <span onClick={this.editOrigin}>
                  <span>原币:</span>
                  <span>{record.origin || 0}</span>
                </span>
              </div>
            } else if (origining) {
              currencyNode = <div className="count-wrap">
                <span style={{marginRight: '5px'}} onClick={this.editCurrency}>
                  <span>货币:</span>
                  <span>{record.exratename || ''}</span>
                </span>
                <span style={{marginRight: '5px'}} onClick={this.editRatio}>
                  <span>汇率:</span>
                  <span>{record.unitratio || 1}</span>
                </span>
                <span onClick={(e) => e.stopPropagation()}>
                  <span>原币:</span>
                  <span><InputNumber precision={2} className="inner-input" id={col.uuid + record.uuid + 'origin'} defaultValue={record.origin || 0} onChange={(val) => this.onChange(val)} onPressEnter={this.originPress} onBlur={this.originBlur}/></span>
                </span>
              </div>
            } else {
              currencyNode = <div className="count-wrap">
                <span style={{marginRight: '5px'}} onClick={this.editCurrency}>
                  <span>货币:</span>
                  <span>{record.exratename || ''}</span>
                </span>
                <span style={{marginRight: '5px'}} onClick={this.editRatio}>
                  <span>汇率:</span>
                  <span>{record.unitratio || 1}</span>
                </span>
                <span onClick={this.editOrigin}>
                  <span>原币:</span>
                  <span>{record.origin || 0}</span>
                </span>
              </div>
            }
          } else {
            children = <div className="content-wrap" onClick={this.focus}>{val}</div>
          }
          children = <div className="content-wrap" onClick={this.focus}>
            {val}
            {countNode}
            {currencyNode}
          </div>
        }
      }
    } else if (col.field === 'debtor') {
@@ -749,22 +1016,23 @@
  initData = (data) => {
    let _data = data.map((item, i) => {
      item.uuid = Utils.getuuid()
      // item.uuid = Utils.getguid()
      item.index = i
      item.$origin = true
      
      return item
    })
    if (_data.length < 4) {
      for (let i = _data.length - 1; i < 4; i++) {
        _data.push({uuid: Utils.getuuid(), index: i + 1, remark: '', subjectscode: '', subjectsname: '', debtor: '', creditor: ''})
        _data.push({uuid: Utils.getguid(), index: i + 1, remark: '', subjectscode: '', subjectsname: '', debtor: '', creditor: ''})
      }
    }
    return _data
  }
  getTotalLine = (data) => {
    let totalLine = {uuid: Utils.getuuid(), type: 'total'}
    let totalLine = {uuid: Utils.getguid(), type: 'total'}
    let debtor = ''
    let creditor = ''
@@ -886,7 +1154,7 @@
      MKEmitter.emit('tdFocus', 'remark' + edData[record.index + 1].uuid)
    } else {
      let _data = fromJS(edData).toJS()
      let line = {uuid: Utils.getuuid(), index: _data.length - 1, remark: record.remark || '', subjectscode: '', subjectsname: '', debtor: '', creditor: ''}
      let line = {uuid: Utils.getguid(), index: _data.length - 1, remark: record.remark || '', subjectscode: '', subjectsname: '', debtor: '', creditor: ''}
      _data.splice(_data.length - 1, 0, line)
@@ -903,7 +1171,7 @@
    if (tid !== tableId) return
    let _data = fromJS(edData).toJS()
    let line = {uuid: Utils.getuuid(), index: 0, remark: '', subjectscode: '', subjectsname: '', debtor: '', creditor: ''}
    let line = {uuid: Utils.getguid(), index: 0, remark: '', subjectscode: '', subjectsname: '', debtor: '', creditor: ''}
    _data.splice(record.index, 0, line)
    _data = _data.map((item, index) => {
@@ -926,7 +1194,7 @@
    if (_data.length < 4) {
      for (let i = _data.length; i < 4; i++) {
        _data.push({uuid: Utils.getuuid(), index: 0, remark: '', subjectscode: '', subjectsname: '', debtor: '', creditor: ''})
        _data.push({uuid: Utils.getguid(), index: 0, remark: '', subjectscode: '', subjectsname: '', debtor: '', creditor: ''})
      }
    }
@@ -938,7 +1206,7 @@
    _data.push(this.getTotalLine(_data))
    this.setState({edData: _data})
    this.props.onChange(_data)
    this.props.onChange(_data, record.$origin ? record : null)
  }
  changeRecord = (tableId, record) => {
@@ -955,7 +1223,7 @@
    _data.pop()
    if (record.index === _data.length - 1) {
      _data.push({uuid: Utils.getuuid(), index: record.index + 1, remark: '', subjectscode: '', subjectsname: '', debtor: '', creditor: ''})
      _data.push({uuid: Utils.getguid(), index: record.index + 1, remark: '', subjectscode: '', subjectsname: '', debtor: '', creditor: ''})
    }
    _data.push(this.getTotalLine(_data))
src/tabviews/custom/components/module/voucher/voucherTable/index.scss
@@ -90,13 +90,29 @@
        vertical-align: top;
        .content-wrap {
          padding: 5px;
          padding: 0px 5px;
          height: 100%;
          font-size: 13px;
          font-weight: bold;
          .count-wrap {
            text-align: right;
            height: 20px;
          }
          .currency-select {
            height: 20px;
            vertical-align: top;
            .ant-select-selection--single {
              height: 20px;
            }
            .ant-select-selection__rendered {
              line-height: 20px;
              margin-left: 8px;
              margin-right: 22px;
            }
            .ant-select-arrow {
              right: 6px;
            }
          }
        }
        .money-uint {
@@ -147,20 +163,20 @@
  }
  .ant-input-number.inner-input {
    display: inline-block;
    width: 40px;
    width: 50px;
    border-radius: 0;
    height: 24px;
    height: 20px;
    .ant-input-number-handler-wrap {
      display: none;
    }
    .ant-input-number-input {
      border-radius: 0;
      height: 22px;
      padding: 0 5px;
      height: 18px;
      padding: 0 3px;
    }
  }
  .ant-select {
  .ant-select:not(.currency-select) {
    padding: 0px;
    position: absolute;
    top: 0px;
src/tabviews/zshare/actionList/normalbutton/index.jsx
@@ -1918,21 +1918,38 @@
   * 4、模态框执行成功后是否关闭
   * 5、通知主列表刷新
   */
  execSuccess = (res) => {
  execSuccess = (res = {}) => {
    const { btn } = this.props
    const { btnconfig, autoMatic } = this.state
    if ((res && (res.ErrCode === 'S' || !res.ErrCode)) || autoMatic) { // 执行成功
    if (res.message && /^@speak@/.test(res.message)) {
      res.message = res.message.replace('@speak@', '')
      let val = res.message.match(/<<.*>>/)
      res.message = res.message.replace(/\s*<<.*>>\s*/g, '')
      val = val ? val[0].replace(/<<|>>/g, '') : ''
      if (/^http/.test(val)) {
        let audio = document.createElement('audio')
        audio.src = val
        audio.play()
      }
      if (!res.message) {
        res.ErrCode = '-1'
      }
    }
    if ((res.ErrCode === 'S' || !res.ErrCode) || autoMatic) { // 执行成功
      notification.success({
        top: 92,
        message: res.ErrMesg || this.state.dict['main.action.confirm.success'],
        message: res.message || '执行成功!',
        duration: btn.verify && btn.verify.stime ? btn.verify.stime : 2
      })
    } else if (res && res.ErrCode === 'Y') { // 执行成功
    } else if (res.ErrCode === 'Y') { // 执行成功
      Modal.success({
        title: res.ErrMesg || this.state.dict['main.action.confirm.success']
        title: res.message || '执行成功!'
      })
    } else if (res && res.ErrCode === '-1') { // 完成后不提示
    } else if (res.ErrCode === '-1') { // 完成后不提示
    }
@@ -2295,25 +2312,42 @@
    const { btn } = this.props
    const { btnconfig, autoMatic } = this.state
    if (res.message && /^@speak@/.test(res.message)) {
      res.message = res.message.replace('@speak@', '')
      let val = res.message.match(/<<.*>>/)
      res.message = res.message.replace(/\s*<<.*>>\s*/g, '')
      val = val ? val[0].replace(/<<|>>/g, '') : ''
      if (/^http/.test(val)) {
        let audio = document.createElement('audio')
        audio.src = val
        audio.play()
      }
      if (!res.message) {
        res.ErrCode = '-1'
      }
    }
    if (res.ErrCode === 'E' && !autoMatic) {
      Modal.error({
        title: res.message || res.ErrMesg,
        title: res.message || '执行失败!',
      })
    } else if (res.ErrCode === 'N' || autoMatic) {
      notification.error({
        top: 92,
        message: res.message || res.ErrMesg,
        message: res.message || '执行失败!',
        duration: btn.verify && btn.verify.ntime ? btn.verify.ntime : 10
      })
    } else if (res.ErrCode === 'F') {
      notification.error({
        className: 'notification-custom-error',
        top: 92,
        message: res.message || res.ErrMesg,
        message: res.message || '执行失败!',
        duration: btn.verify && btn.verify.ftime ? btn.verify.ftime : 10
      })
    } else if (res.ErrCode === 'NM') {
      message.error(res.message || res.ErrMesg)
      message.error(res.message || '执行失败!')
    }
    if (autoMatic) {
src/templates/zshare/formconfig.jsx
@@ -1268,7 +1268,7 @@
      key: 'execSuccess',
      label: '成功后',
      initVal: card.execSuccess || 'grid',
      tooltip: '选择刷新行时,如果选择多条数据会刷新表格。',
      tooltip: '选择刷新行时,如果选择多条数据会刷新表格。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。',
      required: true,
      options: [{
        value: 'never',
@@ -1287,7 +1287,7 @@
      key: 'execError',
      label: '失败后',
      initVal: card.execError || 'never',
      tooltip: '选择刷新行时,如果选择多条数据会刷新表格。',
      tooltip: '选择刷新行时,如果选择多条数据会刷新表格。如需语音播报请以@speak@开头,播报内容或文件放置于<<>>中。',
      required: true,
      options: [{
        value: 'never',