king
2022-12-29 836722dd114fa35967a5e96be96ba4503ebf8e1d
2022-12-29
17个文件已修改
4个文件已添加
1236 ■■■■ 已修改文件
src/assets/css/main.scss 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/css/viewstyle.scss 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/mobimg/account.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/mobimg/voucher.png 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/module/account/index.jsx 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/module/account/options.jsx 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/module/voucher/index.jsx 33 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/module/voucher/index.scss 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/module/voucher/options.jsx 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/module/voucher/voucherTable/index.jsx 362 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/module/voucher/voucherTable/index.scss 259 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/modulesource/option.jsx 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/module/account/index.jsx 140 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/module/account/index.scss 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/module/voucher/index.jsx 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/module/voucher/index.scss 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/module/voucher/voucherTable/index.jsx 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/module/voucher/voucherTable/index.scss 100 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/templates/zshare/verifycard/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/menudesign/index.jsx 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mobdesign/index.jsx 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/css/main.scss
@@ -483,4 +483,4 @@
  table td {
    vertical-align: bottom;
  }
}
}
src/assets/css/viewstyle.scss
@@ -444,11 +444,7 @@
  .system-color {
    color: $color6;
  }
  .system-background {
    background: $color6;
    border-color: $color6;
    color: #ffffff;
  }
  .ant-timeline.system {
    .ant-timeline-item-tail {
      border-color: $color2;
src/assets/mobimg/account.png
src/assets/mobimg/voucher.png
src/menu/components/module/account/index.jsx
@@ -96,9 +96,27 @@
  }
  updateWrap = (res) => {
    let _card = {...this.state.card, wrap: res}
    if (res.linkmenu) {
      let list = null
      try {
        list = JSON.parse(sessionStorage.getItem('thdMenuList')) || []
      } catch (e) {
        list = []
      }
    this.updateComponent(_card)
      let id = res.linkmenu[res.linkmenu.length - 1]
      res.MenuID = id
      list.forEach(item => {
        if (item.MenuID === id) {
          res.MenuName = item.MenuName
          res.MenuNo = item.MenuNo
          res.tabType = item.type
        }
      })
    }
    this.updateComponent({...this.state.card, wrap: res})
  }
  render() {
src/menu/components/module/account/options.jsx
@@ -2,6 +2,17 @@
 * @description Wrap表单配置信息
 */
export default function (wrap) {
  let menulist = sessionStorage.getItem('fstMenuList')
  if (menulist) {
    try {
      menulist = JSON.parse(menulist)
    } catch (e) {
      menulist = []
    }
  } else {
    menulist = []
  }
  const wrapForm = [
    {
      type: 'text',
@@ -21,7 +32,29 @@
      max: 24,
      precision: 0,
      required: true
    }
    },
    {
      type: 'radio',
      field: 'addable',
      label: '可新增',
      initval: wrap.addable || 'false',
      required: true,
      options: [
        {value: 'true', label: '是'},
        {value: 'false', label: '否'},
      ],
      controlFields: [
        {field: 'linkmenu', values: ['true']},
      ],
    },
    {
      type: 'cascader',
      field: 'linkmenu',
      label: '关联菜单',
      initVal: wrap.linkmenu || [],
      required: true,
      options: menulist
    },
  ]
  return wrapForm
src/menu/components/module/voucher/index.jsx
@@ -1,12 +1,13 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Popover } from 'antd'
import { EditOutlined, ToolOutlined, DeleteOutlined, FontColorsOutlined } from '@ant-design/icons'
import { Popover, Button } from 'antd'
import { EditOutlined, ToolOutlined, DeleteOutlined, FontColorsOutlined, DownOutlined, CalendarOutlined } from '@ant-design/icons'
import asyncIconComponent from '@/utils/asyncIconComponent'
import MKEmitter from '@/utils/events.js'
import getWrapForm from './options'
import VoucherTable from './voucherTable'
import './index.scss'
@@ -39,7 +40,7 @@
        subtype: card.subtype,
        // setting: { interType: 'system' },
        wrap: { name: '凭证', title: '', width: card.width || 12, type: 'edit' },
        style: { marginLeft: '8px', marginRight: '8px', marginTop: '8px', marginBottom: '8px' },
        style: { marginLeft: '8px', marginRight: '8px', marginTop: '8px', marginBottom: '8px', paddingBottom: '20px' },
        headerStyle: {},
        columns: [],
        scripts: [],
@@ -122,7 +123,31 @@
          <ToolOutlined />
        </Popover>
        <div className="voucher-box">
          凭证
          <div className="voucher-header">
            <Button className="add-background header-btn">新增</Button>
            <Button className="add-background header-btn">保存</Button>
            <Button className="print-background header-btn">打印</Button>
            <Button className="system-background header-btn">导入</Button>
            <Button className="out-background header-btn">导出</Button>
          </div>
          <div className="voucher-body">
          <div className="pre-wrap">
            <div className="voucher-code">
              <div>记<DownOutlined/></div>
              <div>1</div>
              号
            </div>
            <div className="voucher-date">
              日期:<div>请选择日期 <CalendarOutlined /></div>
            </div>
            <div className="voucher-affix">
              附单据 <div>2</div> 张
              <Button type="link" className="">附件</Button>
              <Button type="link" className="">备注</Button>
            </div>
          </div>
          <VoucherTable config={card}/>
        </div>
        </div>
      </div>
    )
src/menu/components/module/voucher/index.scss
@@ -18,6 +18,98 @@
    padding: 5px;
    background: rgba(255, 255, 255, 0.55);
  }
  .voucher-header {
    padding: 10px;
    border-bottom: 1px solid #eeeeee;
    .header-btn {
      height: 28px;
      min-width: 80px;
      margin-right: 10px;
    }
  }
  .voucher-body {
    padding: 0 15px;
    .voucher-code {
      display: inline-block;
      width: 160px;
      margin-right: 15px;
      div {
        display: inline-block;
        min-width: 50px;
        margin-right: 10px;
        border: 1px solid #d9d9d9;
        padding: 4px 10px;
        border-radius: 4px;
        .anticon-down {
          position: relative;
          left: 3px;
          color: #c8c8c8;
          font-size: 12px;
          margin-left: 5px;
        }
      }
    }
    .pre-wrap {
      padding: 10px 0px;
    }
    .voucher-date {
      display: inline-block;
      div {
        display: inline-block;
        min-width: 50px;
        margin-right: 10px;
        border: 1px solid #d9d9d9;
        padding: 4px 10px;
        border-radius: 4px;
        color: #c8c8c8;
        .anticon {
          position: relative;
          left: 3px;
          color: #c8c8c8;
          margin-left: 5px;
        }
      }
    }
    .voucher-affix {
      float: right;
      width: 250px;
      div {
        display: inline-block;
        min-width: 50px;
        margin-right: 10px;
        border: 1px solid #d9d9d9;
        padding: 4px 10px;
        border-radius: 4px;
      }
    }
  }
  .add-background {
    background: #26C281;
    border-color: #26C281;
    color: #ffffff;
  }
  .print-background {
    background-color: #8E44AD;
    border-color: #8E44AD;
    color: #ffffff;
  }
  .out-background {
    background-color: rgb(50, 197, 210);
    border-color: rgb(50, 197, 210);
    color: #ffffff;
  }
  .system-background {
    background: #1890ff;
    border-color: #1890ff;
    color: #ffffff;
  }
}
.menu-voucher-box::after {
  display: block;
src/menu/components/module/voucher/options.jsx
@@ -6,6 +6,19 @@
export default function (wrap, id) {
  let menu = window.GLOB.customMenu
  let modules = MenuUtils.getSupModules(menu.components, id, menu.interfaces)
  let books = []
  let bookids = []
  menu.components.forEach(item => {
    if (item.subtype === 'account') {
      books.push({
        value: item.uuid,
        label: item.name
      })
      bookids.push(item.uuid)
    }
  })
  modules = modules.filter(item => !bookids.includes(item.value))
  const wrapForm = [
    // {
@@ -46,6 +59,15 @@
      required: true
    },
    {
      type: 'select',
      field: 'supBook',
      label: '账套',
      initval: wrap.supBook || '',
      required: true,
      options: books,
      allowClear: true
    },
    {
      type: 'cascader',
      field: 'supModule',
      label: '上级组件',
src/menu/components/module/voucher/voucherTable/index.jsx
New file
@@ -0,0 +1,362 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Table } from 'antd'
import Utils from '@/utils/utils.js'
import '@/assets/css/table.scss'
import './index.scss'
class BodyRow extends React.Component {
  render() {
    let { data, ...resProps } = this.props
    let style = {}
    let className = ''
    return <tr {...resProps} className={className} style={style}/>
  }
}
class BodyCell extends React.Component {
  state = {}
  /**
   * @description 组件销毁,清除state更新,清除快捷键设置
   */
  componentWillUnmount () {
    this.setState = () => {
      return
    }
  }
  render() {
    let { col, record, className } = this.props
    let children = null
    let colSpan = 1
    if (col.field === 'remark') {
      let val = record.remark || ''
      if (record.type === 'total') {
        children = <div className="content-wrap" style={{lineHeight: '60px'}}>合计: {val}</div>
        colSpan = 2
      } else {
        children = <div className="content-wrap">{val}</div>
      }
    } else if (col.field === 'subject') {
      if (record.type === 'total') {
        colSpan = 0
      } else {
        let val = record.subject || ''
        children = <div className="content-wrap">{val}</div>
      }
    } else if (col.field === 'debtor') {
      let val = record.debtor
      let down = false
      let vals = []
      if (typeof(val) === 'number') {
        if (val < 0) {
          down = true
          val = Math.abs(val)
        }
        vals = (val * 100).toFixed(0).split('').reverse()
      }
      children = <div className={'money-uint' + (down ? ' down' : '')}>
        <span>{vals[10] || ''}</span> <span>{vals[9] || ''}</span> <span>{vals[8] || ''}</span> <span>{vals[7] || ''}</span> <span>{vals[6] || ''}</span> <span>{vals[5] || ''}</span>
        <span>{vals[4] || ''}</span> <span>{vals[3] || ''}</span> <span>{vals[2] || ''}</span> <span>{vals[1] || ''}</span> <span className="last">{vals[0] || ''}</span>
      </div>
    } else if (col.field === 'creditor') {
      let val = record.creditor
      let down = false
      let vals = []
      if (typeof(val) === 'number') {
        if (val < 0) {
          down = true
          val = Math.abs(val)
        }
        vals = (val * 100).toFixed(0).split('').reverse()
      }
      children = <div className={'money-uint' + (down ? ' down' : '')}>
        <span>{vals[10] || ''}</span> <span>{vals[9] || ''}</span> <span>{vals[8] || ''}</span> <span>{vals[7] || ''}</span> <span>{vals[6] || ''}</span> <span>{vals[5] || ''}</span>
        <span>{vals[4] || ''}</span> <span>{vals[3] || ''}</span> <span>{vals[2] || ''}</span> <span>{vals[1] || ''}</span> <span className="last">{vals[0] || ''}</span>
      </div>
    }
    if (!colSpan) return null
    return (<td colSpan={colSpan} className={className}>{children}</td>)
  }
}
class VoucherTable extends Component {
  static propTpyes = {
    config: PropTypes.object,        // 菜单Id
    BID: PropTypes.any,              // 主表ID
    total: PropTypes.any,            // 总数
    loading: PropTypes.bool,         // 表格加载中
    refreshdata: PropTypes.func,     // 表格中排序列、页码的变化时刷新
  }
  state = {
    data: [],
    edData: [],
    edColumns: [],
    tableId: '',          // 表格ID
    pageSize: 10,         // 每页数据条数
    columns: null,        // 显示列
    loading: false,
  }
  UNSAFE_componentWillMount () {
    const { config } = this.props
    let data = [
      {remark: '提现', subject: '1001 库存现金', debtor: 124, creditor: ''},
      {remark: '购入固定资产', subject: '1001 库存现金', debtor: '', creditor: 124},
      {remark: '转结销售成本', subject: '1001 库存现金', debtor: -524, creditor: ''},
      {remark: '提现', subject: '1001 库存现金', debtor: 34, creditor: ''},
    ]
    data = this.initData(data)
    data.push(this.getTotalLine(data))
    let columns = [
      {
        title: '摘要',
        dataIndex: 'remark',
        key: 'remark',
        width: '22%',
        onCell: record => ({
          record,
          col: {uuid: 'remark', field: 'remark', tableId: config.uuid},
        })
      },
      {
        title: '会计科目',
        dataIndex: 'subject',
        key: 'subject',
        width: '34%',
        onCell: record => ({
          record,
          col: {uuid: 'subject', field: 'subject', tableId: config.uuid},
        })
      },
      {
        title: () => (<>
          <div className="money-title">借方金额</div>
          <div className="money-uint">
            <span>亿</span> <span>千</span> <span>百</span> <span>十</span> <span>万</span> <span>千</span>
            <span>百</span> <span>十</span> <span>元</span> <span>角</span> <span className="last">分</span>
          </div>
        </>),
        dataIndex: 'debtor',
        key: 'debtor',
        width: '22%',
        onCell: record => ({
          record,
          col: {uuid: 'debtor', field: 'debtor', tableId: config.uuid},
        })
      },
      {
        title: () => (<>
          <div className="money-title">贷方金额</div>
          <div className="money-uint">
            <span>亿</span> <span>千</span> <span>百</span> <span>十</span> <span>万</span> <span>千</span>
            <span>百</span> <span>十</span> <span>元</span> <span>角</span> <span className="last">分</span>
          </div>
        </>),
        dataIndex: 'creditor',
        key: 'creditor',
        width: '22%',
        onCell: record => ({
          record,
          col: {uuid: 'creditor', field: 'creditor', tableId: config.uuid},
        })
      }
    ]
    this.setState({
      data: data,
      edData: fromJS(data).toJS(),
      columns,
      tableId: config.uuid
    })
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.props), fromJS(nextProps)) || !is(fromJS(this.state), fromJS(nextState))
  }
  /**
   * @description 组件销毁,清除state更新
   */
  componentWillUnmount () {
    this.setState = () => {
      return
    }
  }
  initData = (data) => {
    let _data = data.map((item, i) => {
      item.uuid = Utils.getuuid()
      item.index = i
      return item
    })
    if (_data.length < 4) {
      for (let i = _data.length - 1; i < 4; i++) {
        _data.push({uuid: Utils.getuuid(), index: i + 1, remark: '', subject: '', debtor: '', creditor: ''})
      }
    }
    return _data
  }
  getTotalLine = (data) => {
    let totalLine = {uuid: Utils.getuuid(), type: 'total'}
    let debtor = ''
    let creditor = ''
    data.forEach(item => {
      if (typeof(item.debtor) === 'number') {
        if (debtor === '') {
          debtor = 0
        }
        debtor += item.debtor
      } else if (typeof(item.creditor) === 'number') {
        if (debtor === '') {
          debtor = 0
        }
        if (creditor === '') {
          creditor = 0
        }
        creditor += item.creditor
      }
    })
    totalLine.debtor = debtor
    totalLine.creditor = creditor
    totalLine.remark = this.changeMoneyToChinese(debtor)
    return totalLine
  }
  changeMoneyToChinese = (money) => {
    let cnNums = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖']
    let cnIntRadice = ['', '拾', '佰', '仟']
    let cnIntUnits = ['', '万', '亿', '兆']
    let cnDecUnits = ['角', '分', '毫', '厘']
    let cnInteger = '整'
    let cnIntLast = '元'
    let maxNum = 999999999999999.9999 // 最大处理的数字
    let IntegerNum = null
    let DecimalNum = null
    let ChineseStr = ''
    let parts = null // 分离金额后用的数组,预定义
    let Symbol = ''  // 正负值标记
    if (money === '') return ''
    if (money >= maxNum) return '超出最大处理数字'
    if (money === 0) {
      ChineseStr = cnNums[0] + cnIntLast + cnInteger;
      return ChineseStr
    }
    if(money < 0) {
      money = -money
      Symbol = '负'
    }
    money = money.toString() // 转换为字符串
    if (money.indexOf('.') === -1) {
      IntegerNum = money
      DecimalNum = ''
    } else {
      parts = money.split('.')
      IntegerNum = parts[0]
      DecimalNum = parts[1].substr(0, 4)
    }
    if (parseInt(IntegerNum, 10) > 0) { // 获取整型部分转换
      let zeroCount = 0
      let IntLen = IntegerNum.length
      for (let i = 0; i < IntLen; i++) {
        let n = IntegerNum.substr(i, 1)
        let p = IntLen - i - 1
        let q = p / 4
        let m = p % 4
        if (n === '0') {
          zeroCount++
        } else {
          if (zeroCount > 0) {
            ChineseStr += cnNums[0]
          }
          zeroCount = 0 // 归零
          ChineseStr += cnNums[parseInt(n)] + cnIntRadice[m]
        }
        if (m === 0 && zeroCount < 4) {
          ChineseStr += cnIntUnits[q]
        }
      }
      ChineseStr += cnIntLast
    }
    if (DecimalNum !== '') { // 小数部分
      let decLen = DecimalNum.length
      for (let i = 0; i < decLen; i++) {
        let n = DecimalNum.substr(i, 1)
        if (n !== '0') {
          ChineseStr += cnNums[Number(n)] + cnDecUnits[i]
        }
      }
    }
    if (ChineseStr === '') {
      ChineseStr += cnNums[0] + cnIntLast + cnInteger
    } else if (DecimalNum === '') {
      ChineseStr += cnInteger
    }
    ChineseStr = Symbol + ChineseStr
    return ChineseStr
  }
  render() {
    const { edData, columns} = this.state
    const components = {
      body: {
        row: BodyRow,
        cell: BodyCell
      }
    }
    return (
      <div className="voucher-table-wrap">
        <Table
          rowKey="uuid"
          components={components}
          columns={columns}
          dataSource={edData}
          bordered={true}
          onRow={(record, index) => {
            return {
              data: record
            }
          }}
          pagination={false}
        />
      </div>
    )
  }
}
export default VoucherTable
src/menu/components/module/voucher/voucherTable/index.scss
New file
@@ -0,0 +1,259 @@
.voucher-table-wrap {
  position: relative;
  padding: 0px;
  .normal-table-footer {
    padding: 10px 0px;
    color: rgba(0, 0, 0, 0.65);
  }
  .normal-table-footer.pagination {
    position: absolute;
    bottom: 10px;
  }
  >.ant-table-wrapper {
    position: relative;
    z-index: 1;
  }
  .ant-table {
    color: inherit;
    font-size: inherit;
  }
  .money-uint {
    display: flex;
    span {
      display: inline-block;
      flex: 1;
      text-align: center;
      font-size: 12px;
    }
    span:not(.last) {
      border-right: 1px solid #e9e9e9;
    }
    span:nth-child(3), span:nth-child(6) {
      border-color: #91d5ff;
    }
    span:nth-child(9) {
      border-color: #ffa39e;
    }
  }
  table {
    max-width: 100%;
    width: 100%;
    .ant-table-thead {
      tr {
        th {
          position: relative;
          background-color: transparent;
          padding: 0;
          height: 60px;
          line-height: 60px;
          text-align: center;
          .ant-table-header-column {
            display: block;
            width: 100%;
            height: 100%;
            .ant-table-column-title {
              display: block;
              width: 100%;
              height: 100%;
              font-weight: bold;
              font-size: 13px;
            }
          }
          .money-title {
            line-height: 30px;
            font-weight: bold;
            font-size: 13px;
          }
          .money-uint {
            line-height: 30px;
            border-top: 1px solid #dadada;
          }
        }
      }
    }
    .ant-table-selection-column {
      width: 60px;
      min-width: 60px;
      max-width: 60px;
    }
    .ant-table-tbody {
      tr td {
        position: relative;
        background-color: transparent;
        padding: 0;
        height: 60px;
        vertical-align: top;
        .content-wrap {
          padding: 5px;
          height: 100%;
          font-size: 13px;
          font-weight: bold;
        }
        .money-uint {
          height: 100%;
          line-height: 60px;
          span {
            font-size: 14px;
            font-weight: bold;
          }
        }
        .money-uint.down {
          span {
            color: #ff4d4f;
          }
        }
      }
    }
  }
  .ant-input {
    height: 60px;
    border-radius: 0;
    resize: none;
  }
  .ant-input-number {
    height: 60px;
    border-radius: 0;
    .ant-input-number-handler-wrap {
      display: none;
    }
    .ant-input-number-input {
      border-radius: 0;
      height: 60px;
    }
  }
  .editing_table_cell {
    .ant-input {
      padding: 0px;
      position: absolute;
      top: 0px;
      left: 0px;
      right: 0px;
      bottom: 0px;
      border: 1px solid #1890ff;
    }
    .ant-input-number-input {
      position: absolute;
      top: 0px;
      left: 0px;
      right: 0px;
      bottom: 0px;
      border: 1px solid #1890ff;
    }
    .anticon {
      color: #ff4d4f;
      position: absolute;
      right: 3px;
      top: calc(50% - 8px);
    }
  }
  td.pointer {
    position: relative;
  }
  td.pointer {
    .mk-mask {
      display: none;
      cursor: pointer;
      position: absolute;
      top: 0;
      left: 0;
      bottom: 0;
      right: 0;
    }
  }
}
.edit-custom-table.editable {
  td {
    background-color: #ffffff!important;
  }
  td.pointer .mk-mask {
    display: block;
  }
  .mk-operation {
    display: none;
  }
  .ant-table-placeholder {
    display: none;
  }
}
.edit-custom-table:not(.fixed-height) {
  .ant-table-body::-webkit-scrollbar {
    width: 8px;
    height: 10px;
  }
  ::-webkit-scrollbar-thumb {
    border-radius: 5px;
    box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.13);
    background: rgba(0, 0, 0, 0.13);
  }
  ::-webkit-scrollbar-track {/*滚动条里面轨道*/
    box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.05);
    border-radius: 3px;
    border: 1px solid rgba(0, 0, 0, 0.07);
    background: rgba(0, 0, 0, 0);
  }
}
.edit-custom-table.fixed-height {
  .ant-table-body {
    border-bottom: 1px solid rgba(0, 0, 0, .05);
    .ant-table-fixed {
      border-bottom: 0;
    }
  }
}
.edit-custom-table.hidden {
  thead {
    display: none;
  }
}
.edit-custom-table.ghost {
  .ant-table-thead > tr {
    > th {
      color: inherit;
      background: transparent;
      .ant-table-column-sorter .ant-table-column-sorter-inner {
        color: inherit;
      }
    }
    > th:hover {
      background: transparent;
    }
  }
  .ant-table-body {
    overflow-x: auto;
    tr {
      td {
        background: transparent!important;
      }
    }
    tr:hover td {
      background: transparent!important;
    }
  }
}
.image-scale-modal {
  width: 70vw;
  min-height: 80vh;
  top: 10vh;
  .ant-modal-body {
    min-height: calc(80vh - 110px);
    line-height: calc(80vh - 160px);
    text-align: center;
  }
  .ant-modal-footer {
    text-align: center;
    span {
      display: inline-block;
      color: #1890ff;
      padding: 5px 15px;
      cursor: pointer;
    }
  }
}
src/menu/modulesource/option.jsx
@@ -30,7 +30,8 @@
import mindmap from '@/assets/mobimg/mindmap.png'
import indent from '@/assets/mobimg/indent.jfif'
import kapmap from '@/assets/mobimg/kapmap.jfif'
// import Voucher from '@/assets/mobimg/voucher.jpg'
import Voucher from '@/assets/mobimg/voucher.png'
import Account from '@/assets/mobimg/account.png'
// 组件配置信息
export const menuOptions = [
@@ -68,6 +69,6 @@
  { type: 'menu', url: SandBox, component: 'code', subtype: 'sandbox', title: '自定义', width: 24 },
  { type: 'menu', url: group, component: 'group', subtype: 'normalgroup', title: '分组', width: 24, forbid: ['billPrint'] },
  { type: 'menu', url: Iframe, component: 'iframe', subtype: 'iframe', title: 'iframe', width: 24, forbid: ['billPrint'] },
  // { type: 'menu', url: Voucher, component: 'module', subtype: 'account', title: '账套', width: 24, forbid: ['billPrint'] },
  // { type: 'menu', url: Voucher, component: 'module', subtype: 'voucher', title: '凭证', width: 24, forbid: ['billPrint'] },
  { type: 'menu', url: Account, component: 'module', subtype: 'account', title: '账套', width: 24, forbid: ['billPrint'] },
  { type: 'menu', url: Voucher, component: 'module', subtype: 'voucher', title: '凭证', width: 24, forbid: ['billPrint'] },
]
src/tabviews/custom/components/module/account/index.jsx
@@ -1,12 +1,14 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
// import { Button, Select, Input, DatePicker } from 'antd'
// import { EditOutlined, ToolOutlined, DeleteOutlined, FontColorsOutlined } from '@ant-design/icons'
import { notification, Select, Divider } from 'antd'
import { PlusOutlined } from '@ant-design/icons'
import Api from '@/api'
// import MKEmitter from '@/utils/events.js'
import MKEmitter from '@/utils/events.js'
import './index.scss'
const { Option } = Select
class AccountModule extends Component {
  static propTpyes = {
@@ -14,37 +16,12 @@
  }
  state = {
    BID: '',
    type: '',
    config: null
  }
  UNSAFE_componentWillMount () {
    const { config } = this.props
    let BID = ''
    let BData = ''
    if (config.wrap.supModule) {
      BData = window.GLOB.CacheData.get(config.wrap.supModule)
    } else {
      BData = window.GLOB.CacheData.get(config.$pageId)
    }
    if (BData) {
      BID = BData.$BID || ''
    }
    this.setState({
      config: fromJS(config).toJS(),
      BID: BID || '',
      type: config.wrap.type
    }, () => {
      this.loadData()
    })
    activeItem: null,
    books: []
  }
  componentDidMount () {
    this.loadData()
  }
  shouldComponentUpdate (nextProps, nextState) {
@@ -62,22 +39,107 @@
  loadData = () => {
    let param = {
      func: 's_get_fcc_account_data'
    }
    Api.genericInterface(param)
    let _param = {
      func: 's_get_fcc_book_data'
    }
    Api.genericInterface(_param)
    Api.genericInterface(param).then(res => {
      if (!res.status) {
        notification.warning({
          top: 92,
          message: res.message,
          duration: 5
        })
        return
      }
      let books = res.book || []
      let activeItem = null
      let map = new Map()
      books = books.filter(item => {
        if (!item.id) return false
        if (map.has(item.id)) return false
        map.set(item.id, true)
        if (item.selected === 'true' && !activeItem) {
          activeItem = item
        }
        if (item.months) {
          item.date = item.months.replace('-', '年') + '月'
        }
        return true
      })
      if (!activeItem && books.length > 0) {
        activeItem = books[0]
      }
      this.setState({books, activeItem})
      if (activeItem) {
        MKEmitter.emit('resetSelectLine', this.props.config.uuid, activeItem.id, activeItem)
      }
    })
  }
  changeBook = (value) => {
    const { books } = this.state
    let activeItem = books.filter(item => item.id === value)[0]
    this.setState({activeItem})
    if (activeItem) {
      MKEmitter.emit('resetSelectLine', this.props.config.uuid, activeItem.id, activeItem)
    }
  }
  addBook = () => {
    const { config } = this.props
    let menuId = config.wrap.MenuID
    let menu = window.GLOB.mkThdMenus.filter(m => m.MenuID === menuId)[0]
    if (!menu && config.wrap.MenuNo) {
      menu = {
        MenuID: menuId,
        MenuName: config.wrap.MenuName,
        MenuNo: config.wrap.MenuNo || '',
        type: config.wrap.tabType
      }
    }
    let newtab = {
      ...menu,
      param: {}
    }
    MKEmitter.emit('modifyTabs', newtab, true)
  }
  render() {
    const { config } = this.state
    const { config } = this.props
    const { activeItem, books } = this.state
    return (
      <div className="menu-account-wrap" style={config.style}>
        {config.wrap.MenuID ? <Select value={activeItem ? activeItem.id : ''} placeholder="请选择账套" onChange={this.changeBook} dropdownRender={menu => (
          <div>
            {menu}
            <Divider style={{ margin: '4px 0' }} />
            <div className="mk-add-book" onMouseDown={this.addBook}>
              <PlusOutlined /> 点击新增账套
            </div>
          </div>
        )}>
          {books.map(item => (
            <Option 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>
          ))}
        </Select>}
        {activeItem ? <span className="date">{activeItem.date}</span> : null}
      </div>
    )
  }
src/tabviews/custom/components/module/account/index.scss
@@ -5,10 +5,23 @@
  background-position: center center;
  background-repeat: no-repeat;
  background-size: cover;
  min-height: 150px;
  overflow-y: auto;
  color: #000000;
  .ant-select {
    min-width: 250px;
    max-width: 300px;
    color: #000000;
  }
  .date {
    margin-left: 15px;
  }
}
.mk-add-book {
  padding: 4px 8px 10px;
  cursor: pointer;
  text-align: center;
  color: var(--mk-sys-color);
}
src/tabviews/custom/components/module/voucher/index.jsx
@@ -1,12 +1,12 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Button, Select, Input, DatePicker } from 'antd'
// import { EditOutlined, ToolOutlined, DeleteOutlined, FontColorsOutlined } from '@ant-design/icons'
import { Button, Select, Input, DatePicker, notification } from 'antd'
import moment from 'moment'
import Api from '@/api'
import asyncComponent from '@/utils/asyncComponent'
// import MKEmitter from '@/utils/events.js'
import MKEmitter from '@/utils/events.js'
import './index.scss'
const VoucherTable = asyncComponent(() => import('./voucherTable'))
@@ -18,14 +18,13 @@
  state = {
    BID: '',
    type: '',
    config: null,
    loading: false,
    data: null,
    searchkey: null,
    disableAdd: true,
    disableSave: true,
    typeOptions: []
    disableAdd: false,
    disableSave: false,
    typeOptions: [],
    book: null
  }
  UNSAFE_componentWillMount () {
@@ -46,14 +45,14 @@
    this.setState({
      config: fromJS(config).toJS(),
      BID: BID || '',
      type: config.wrap.type
      book: window.GLOB.CacheData.get(config.wrap.supBook) || null
    }, () => {
      this.loadData()
    })
  }
  componentDidMount () {
    MKEmitter.addListener('resetSelectLine', this.resetParentParam)
  }
  shouldComponentUpdate (nextProps, nextState) {
@@ -67,18 +66,51 @@
    this.setState = () => {
      return
    }
    MKEmitter.removeListener('resetSelectLine', this.resetParentParam)
  }
  resetParentParam = (MenuID, id, data) => {
    const { config } = this.state
    if (config.wrap.supBook === MenuID) {
      this.setState({ book: data }, () => {
        this.loadData()
      })
      return
    }
    if (!config.wrap.supModule || config.wrap.supModule !== MenuID) return
    if (id !== this.state.BID || id !== '') {
      this.setState({ BID: id, BData: data }, () => {
        this.loadData()
      })
    }
  }
  loadData = () => {
    let param = {
      func: 's_get_fcc_account_data'
    }
    Api.genericInterface(param)
    const { book } = this.state
    let _param = {
      func: 's_get_fcc_book_data'
    if (!book) return
    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')
    }
    Api.genericInterface(_param)
    Api.genericInterface(param).then(res => {
      if (!res.status) {
        notification.warning({
          top: 92,
          message: res.message,
          duration: 5
        })
        return
      }
    })
  }
  triggeradd = () => {
@@ -94,21 +126,21 @@
  }
  render() {
    const { config, disableSave, disableAdd, typeOptions, data, type } = this.state
    const { config, disableSave, disableAdd, typeOptions, data } = this.state
    return (
      <div className="menu-voucher-wrap" style={config.style}>
        <div className="voucher-header">
          <Button className="system-background header-btn" disabled={disableAdd} onClick={this.triggeradd}>新增</Button>
          <Button className="system-background header-btn" disabled={disableSave} onClick={this.triggersave}>保存</Button>
          <Button className="system-background header-btn" disabled={disableSave} onClick={this.triggerprint}>打印</Button>
          <Button className="add-background header-btn" disabled={disableAdd} onClick={this.triggeradd}>新增</Button>
          <Button className="add-background header-btn" disabled={disableSave} onClick={this.triggersave}>保存</Button>
          <Button className="print-background header-btn" disabled={disableSave} onClick={this.triggerprint}>打印</Button>
          <Button className="system-background header-btn" disabled={disableSave} onClick={this.triggerprint}>导入</Button>
          <Button className="system-background header-btn" disabled={disableSave} onClick={this.triggerprint}>导出</Button>
          <Button className="out-background header-btn" disabled={disableSave} onClick={this.triggerprint}>导出</Button>
        </div>
        {type === 'edit' ? <div className="voucher-body">
        {config.wrap.type === 'edit' ? <div className="voucher-body">
          <div className="pre-wrap">
            <div className="voucher-code">
              <Select>
              <Select dropdownClassName="mk-vcode-dropdown">
                {typeOptions.map(option =>
                  <Select.Option value={option.value}>{option.label}</Select.Option>
                )}
@@ -126,7 +158,7 @@
          </div>
          <VoucherTable config={config} data={data}/>
        </div> : null}
        {type === 'check' ? <div className="voucher-body">
        {config.wrap.type === 'check' ? <div className="voucher-body">
          <div className="pre-wrap">
            <div className="voucher-code">
              记 1 号
src/tabviews/custom/components/module/voucher/index.scss
@@ -51,6 +51,35 @@
      }
    }
  }
  .add-background {
    background: #26C281;
    border-color: #26C281;
    color: #ffffff;
  }
  .print-background {
    background-color: #8E44AD;
    border-color: #8E44AD;
    color: #ffffff;
  }
  .out-background {
    background-color: rgb(50, 197, 210);
    border-color: rgb(50, 197, 210);
    color: #ffffff;
  }
  .system-background {
    background: var(--mk-sys-color);
    border-color: var(--mk-sys-color);
    color: #ffffff;
  }
}
.mk-vcode-dropdown {
  .ant-empty-image svg {
    max-width: 100%;
  }
  .ant-empty-description {
    display: none;
  }
}
src/tabviews/custom/components/module/voucher/voucherTable/index.jsx
@@ -1,8 +1,7 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Table, Modal, Input, InputNumber, notification, message } from 'antd'
// import { EditOutlined } from '@ant-design/icons'
import { Table, Modal, Input, InputNumber, notification, message, AutoComplete } from 'antd'
import Api from '@/api'
import Utils from '@/utils/utils.js'
@@ -120,6 +119,10 @@
    this.setState({value: val})
  }
  complete = (key, option) => {
    this.setState({value: option.props.value})
  }
  render() {
    let { col, record, className } = this.props
    const { editing } = this.state
@@ -135,7 +138,18 @@
        colSpan = 2
      } else {
        if (editing) {
          children = <Input.TextArea id={col.uuid + record.uuid} autoSize={false} defaultValue={val} onChange={(e) => this.onChange(e.target.value)} onPressEnter={this.enterPress} onBlur={this.onBlur}/>
          let options = ['现金', '发票']
          children = <AutoComplete
            dataSource={options.map((cell, i) => <AutoComplete.Option value={cell} key={i}>
              {cell}
            </AutoComplete.Option>)}
            filterOption={(input, option) => option.props.children.indexOf(input) > -1}
            onSelect={this.complete}
            defaultValue={val}
            defaultOpen={true}
          >
            <Input.TextArea id={col.uuid + record.uuid} autoSize={false} defaultValue={val} onChange={(e) => this.onChange(e.target.value)} onPressEnter={this.enterPress} onBlur={this.onBlur}/>
          </AutoComplete>
        } else {
          children = <div className="content-wrap" onClick={this.focus}>{val}</div>
        }
src/tabviews/custom/components/module/voucher/voucherTable/index.scss
@@ -112,6 +112,18 @@
      }
    }
  }
  .ant-select-auto-complete {
    width: 100%;
    .ant-input {
      height: 60px;
      border-radius: 0;
      resize: none;
    }
    .ant-select-selection {
      height: 60px;
    }
  }
  .ant-input {
    height: 60px;
    border-radius: 0;
@@ -169,91 +181,3 @@
    }
  }
}
.edit-custom-table.editable {
  td {
    background-color: #ffffff!important;
  }
  td.pointer .mk-mask {
    display: block;
  }
  .mk-operation {
    display: none;
  }
  .ant-table-placeholder {
    display: none;
  }
}
.edit-custom-table:not(.fixed-height) {
  .ant-table-body::-webkit-scrollbar {
    width: 8px;
    height: 10px;
  }
  ::-webkit-scrollbar-thumb {
    border-radius: 5px;
    box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.13);
    background: rgba(0, 0, 0, 0.13);
  }
  ::-webkit-scrollbar-track {/*滚动条里面轨道*/
    box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.05);
    border-radius: 3px;
    border: 1px solid rgba(0, 0, 0, 0.07);
    background: rgba(0, 0, 0, 0);
  }
}
.edit-custom-table.fixed-height {
  .ant-table-body {
    border-bottom: 1px solid rgba(0, 0, 0, .05);
    .ant-table-fixed {
      border-bottom: 0;
    }
  }
}
.edit-custom-table.hidden {
  thead {
    display: none;
  }
}
.edit-custom-table.ghost {
  .ant-table-thead > tr {
    > th {
      color: inherit;
      background: transparent;
      .ant-table-column-sorter .ant-table-column-sorter-inner {
        color: inherit;
      }
    }
    > th:hover {
      background: transparent;
    }
  }
  .ant-table-body {
    overflow-x: auto;
    tr {
      td {
        background: transparent!important;
      }
    }
    tr:hover td {
      background: transparent!important;
    }
  }
}
.image-scale-modal {
  width: 70vw;
  min-height: 80vh;
  top: 10vh;
  .ant-modal-body {
    min-height: calc(80vh - 110px);
    line-height: calc(80vh - 160px);
    text-align: center;
  }
  .ant-modal-footer {
    text-align: center;
    span {
      display: inline-block;
      color: #1890ff;
      padding: 5px 15px;
      cursor: pointer;
    }
  }
}
src/templates/zshare/verifycard/index.jsx
@@ -626,7 +626,7 @@
          _fields.push(...group.sublist)
        })
        resolve(_fields)
      } else if (card.modal && card.OpenType === 'pop') {
      } else if (card.modal && (card.OpenType === 'pop' || !card.OpenType)) {
        _fields = card.modal.fields || []
        resolve(_fields)
      } else if (card.OpenType === 'pop') {
src/views/menudesign/index.jsx
@@ -1043,7 +1043,8 @@
      }
      let subforbid = {
        editable: '可编辑表格',
        voucher: '凭证'
        voucher: '凭证',
        account: '账套'
      }
      config.components.forEach(item => {
src/views/mobdesign/index.jsx
@@ -1872,6 +1872,7 @@
                    {/* 表名添加 */}
                    {config ? <TableComponent config={config} updatetable={this.updateConfig}/> : null}
                    {config ? <Paragraph style={{padding: '15px 0px 0px 18px'}} copyable={{ text: MenuId }}>菜单ID</Paragraph> : null}
                    {config ? <Paragraph style={{padding: '10px 0px 0px 18px'}} copyable={{ text:  `${window.GLOB.baseurl}mob/index.html#/index/${sessionStorage.getItem('kei_no')}/${sessionStorage.getItem('typename')}/${sessionStorage.getItem('lang')}/${MenuId}/@BID@` }}>菜单链接</Paragraph> : null}
                  </Panel>
                  {/* 组件添加 */}
                  <Panel header="组件" className="component" key="component">