From 59002c8182d10c21a1becdff4e566ee11cd1cd91 Mon Sep 17 00:00:00 2001 From: king <18310653075@163.com> Date: 星期二, 23 四月 2024 18:13:08 +0800 Subject: [PATCH] 2024-04-23 --- src/menu/components/module/invoice/verifycard/customscript/index.jsx | 284 ++++++++ src/menu/components/module/invoice/verifycard/customscript/index.scss | 0 src/menu/components/module/invoice/verifycard/baseform/index.jsx | 110 +++ src/menu/components/module/invoice/index.jsx | 72 + src/menu/components/module/invoice/verifycard/callbackcustomscript/index.scss | 0 src/menu/components/module/invoice/verifycard/baseform/index.scss | 0 src/tabviews/custom/components/tree/antd-tree/index.jsx | 12 src/menu/components/share/actioncomponent/index.jsx | 1 src/tabviews/custom/components/module/invoice/index.scss | 10 src/menu/components/share/actioncomponent/actionform/index.jsx | 12 src/tabviews/custom/components/module/invoice/index.jsx | 314 ++++++++ src/menu/components/tree/antd-tree/index.jsx | 1 src/menu/components/module/invoice/verifycard/callbackcustomscript/index.jsx | 294 ++++++++ src/menu/components/module/invoice/verifycard/index.scss | 124 +++ src/menu/components/module/invoice/verifycard/index.jsx | 690 ++++++++++++++++++++ 15 files changed, 1,891 insertions(+), 33 deletions(-) diff --git a/src/menu/components/module/invoice/index.jsx b/src/menu/components/module/invoice/index.jsx index 344641e..6902bb1 100644 --- a/src/menu/components/module/invoice/index.jsx +++ b/src/menu/components/module/invoice/index.jsx @@ -1,7 +1,7 @@ import React, {Component} from 'react' import PropTypes from 'prop-types' import { is, fromJS } from 'immutable' -import { Popover, Button } from 'antd' +import { Popover, Button, Modal } from 'antd' import { EditOutlined, ToolOutlined, DeleteOutlined, FontColorsOutlined, EllipsisOutlined, SettingOutlined } from '@ant-design/icons' import moment from 'moment' @@ -9,6 +9,7 @@ import asyncIconComponent from '@/utils/asyncIconComponent' import { getTables, checkComponent } from '@/utils/utils-custom.js' import MKEmitter from '@/utils/events.js' +import VerifyCard from './verifycard' import getWrapForm from './options' import './index.scss' @@ -25,7 +26,8 @@ state = { card: null, - date: moment().format('YYYY骞碝M鏈�') + date: moment().format('YYYY骞碝M鏈�'), + btn: null } UNSAFE_componentWillMount () { @@ -69,7 +71,9 @@ {field: 'productname', label: '鍟嗗搧鍚嶇О', initval: '', type: 'text', match: 'like', uuid: Utils.getuuid()}, {field: 'productcode', label: '鍟嗗搧缂栫爜', initval: '', type: 'text', match: 'like', uuid: Utils.getuuid()}, ], - } + }, + billSaveBtn: {type: 'billsave', intertype: 'system', label: '淇濆瓨鍗曟嵁'}, + billOutBtn: {type: 'billout', intertype: 'custom', label: '鎻愪氦寮�绁�', procMode: 'system'}, } let buys = [ @@ -149,8 +153,8 @@ } else { let _card = fromJS(card).toJS() - // _card.buyer.format = 'array' - // _card.detail.format = 'array' + // _card.billSaveBtn = _card.billSaveBtn || {type: 'billsave', intertype: 'system', label: '淇濆瓨鍗曟嵁'} + // _card.billOutBtn = _card.billOutBtn || {type: 'billout', intertype: 'custom', label: '鎻愪氦寮�绁�', procMode: 'system'} this.setState({ card: _card @@ -205,6 +209,14 @@ } } + if (!card.billSaveBtn.scripts || card.billSaveBtn.scripts.length === 0) { + card.errors.push({ level: 0, detail: '鏈坊鍔犲崟鎹繚瀛樿剼鏈紒'}) + // } else if (!card.billOutBtn.scripts || card.billOutBtn.scripts.length === 0) { + // card.errors.push({ level: 0, detail: '鏈坊鍔犳彁浜ゅ紑绁ㄥ墠缃剼鏈紒'}) + // } else if (card.billSaveBtn.cbScripts.length === 0) { + // card.errors.push({ level: 0, detail: '鏈坊鍔犳彁浜ゅ紑绁ㄥ洖璋冭剼鏈紒'}) + } + if (card.errors.length === 0) { card.$tables = getTables(card) card.$tables = [...card.$tables, ...getTables(card.buyer)] @@ -240,8 +252,20 @@ this.updateComponent({...this.state.card, wrap: res}) } + verifySubmit = () => { + this.verifyRef.handleConfirm().then(res => { + if (res.type === 'billout') { + this.updateComponent({...this.state.card, billOutBtn: res}) + } else { + this.updateComponent({...this.state.card, billSaveBtn: res}) + } + + this.setState({ btn: null }) + }) + } + render() { - const { card, date } = this.state + const { card, date, btn } = this.state let style = {...card.style} if (card.wrap.invColor) { @@ -263,8 +287,20 @@ <ToolOutlined /> </Popover> <div className="inv-action"> - <Button className="mk-bill">淇濆瓨鍗曟嵁</Button> - <Button className="mk-submit">鎻愪氦寮�绁�</Button> + <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={ + <div className="mk-popover-control"> + <EditOutlined style={{color: '#1890ff'}} onClick={() => this.setState({btn: card.billSaveBtn})} title="缂栬緫"/> + </div> + } trigger="hover"> + <Button className="mk-bill">淇濆瓨鍗曟嵁</Button> + </Popover> + <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={ + <div className="mk-popover-control"> + <EditOutlined style={{color: '#1890ff'}} onClick={() => this.setState({btn: card.billOutBtn})} title="缂栬緫"/> + </div> + } trigger="hover"> + <Button className="mk-submit">鎻愪氦寮�绁�</Button> + </Popover> </div> <div className="inv-header"> <div className="mk-select">璇烽�夋嫨鍙戠エ绉嶇被</div> @@ -413,6 +449,26 @@ <span className="content">寮�绁ㄤ汉</span> </div> </div> + <Modal + wrapClassName="mk-pop-modal" + visible={btn !== null} + width={'90vw'} + maskClosable={false} + okText="鎻愪氦" + onOk={this.verifySubmit} + onCancel={() => { + if (this.verifyRef.handleCancel) { + this.verifyRef.handleCancel().then(() => { + this.setState({ btn: null }) + }) + } else { + this.setState({ btn: null }) + } + }} + destroyOnClose + > + <VerifyCard card={btn} wrappedComponentRef={(inst) => this.verifyRef = inst}/> + </Modal> </div> ) } diff --git a/src/menu/components/module/invoice/verifycard/baseform/index.jsx b/src/menu/components/module/invoice/verifycard/baseform/index.jsx new file mode 100644 index 0000000..e36d470 --- /dev/null +++ b/src/menu/components/module/invoice/verifycard/baseform/index.jsx @@ -0,0 +1,110 @@ +import React, {Component} from 'react' +import PropTypes from 'prop-types' +import { Form, Row, Col, Input } from 'antd' +// import { QuestionCircleOutlined } from '@ant-design/icons' + +// import './index.scss' +const { TextArea } = Input + +class BaseForm extends Component { + static propTpyes = { + verify: PropTypes.object, + onChange: PropTypes.func + } + + state = {} + + handleConfirm = () => { + const { verify } = this.props + + if (verify.type === 'billout') { + return new Promise((resolve, reject) => { + this.props.form.validateFieldsAndScroll((err, values) => { + if (!err) { + resolve(values) + } + }) + }) + } else { + return Promise.resolve() + } + } + + // onOptionChange = (value, key) => { + // const { verify } = this.props + + // let _verify = {...verify, [key]: value} + + // this.props.onChange(_verify) + // } + + render() { + const { getFieldDecorator } = this.props.form + const { verify } = this.props + + return ( + <Form className="base-form"> + <Row gutter={24}> + <Col span={8}> + <Form.Item label="鎸夐挳鍚嶇О"> + <Input value={verify.label} disabled={true}/> + </Form.Item> + </Col> + {/* <Col span={8}> + <Form.Item label={ + <Tooltip placement="bottomLeft" title=""> + <QuestionCircleOutlined className="mk-form-tip" /> + 鎺ュ彛绫诲瀷 + </Tooltip> + }> + <Radio.Group value={verify.intertype} disabled={true}> + <Radio value="system">绯荤粺</Radio> + <Radio value="custom">鑷畾涔�</Radio> + </Radio.Group> + </Form.Item> + </Col> */} + {/* {verify.type === 'billout' ? <Col span={8}> + <Form.Item label={ + <Tooltip placement="bottomLeft" title=""> + <QuestionCircleOutlined className="mk-form-tip" /> + 鍙傛暟澶勭悊 + </Tooltip> + }> + {getFieldDecorator('procMode', { + initialValue: verify.procMode || 'system', + })( + <Radio.Group onChange={(e) => {this.onOptionChange(e.target.value, 'procMode')}}> + <Radio value="system">绯荤粺鍑芥暟</Radio> + <Radio value="none">鏃�</Radio> + </Radio.Group> + )} + </Form.Item> + </Col> : null} */} + {verify.type === 'billout' ? <Col span={24}> + <Form.Item label="娴嬭瘯鍦板潃"> + {getFieldDecorator('interface', { + initialValue: verify.interface || '', + rules: [ + { required: true, message: '璇疯緭鍏ユ祴璇曞湴鍧�!' } + ] + })( + <TextArea rows={2}/> + )} + </Form.Item> + </Col> : null} + {verify.type === 'billout' ? <Col span={24}> + <Form.Item label="姝e紡鍦板潃"> + {getFieldDecorator('proInterface', { + initialValue: verify.proInterface || '', + })( + <TextArea rows={2}/> + )} + </Form.Item> + </Col> : null} + </Row> + </Form> + ) + } +} + +export default Form.create()(BaseForm) \ No newline at end of file diff --git a/src/menu/components/module/invoice/verifycard/baseform/index.scss b/src/menu/components/module/invoice/verifycard/baseform/index.scss new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/menu/components/module/invoice/verifycard/baseform/index.scss diff --git a/src/menu/components/module/invoice/verifycard/callbackcustomscript/index.jsx b/src/menu/components/module/invoice/verifycard/callbackcustomscript/index.jsx new file mode 100644 index 0000000..dbe1850 --- /dev/null +++ b/src/menu/components/module/invoice/verifycard/callbackcustomscript/index.jsx @@ -0,0 +1,294 @@ +import React, {Component} from 'react' +import PropTypes from 'prop-types' +import { Form, Row, Col, Button, Modal, Tooltip, Radio, Select, Switch, notification } from 'antd' +import { QuestionCircleOutlined } from '@ant-design/icons' + +import Api from '@/api' +import { checkSQL } from '@/utils/utils-custom.js' +import CodeMirror from '@/templates/zshare/codemirror' +// import './index.scss' + +class CustomForm extends Component { + static propTpyes = { + systemScripts: PropTypes.array, + customScripts: PropTypes.array, + scriptsChange: PropTypes.func + } + + state = { + editItem: null, + loading: false, + skip: false + } + + edit = (record) => { + this.setState({ + editItem: record + }) + + if (this.props.type) { + this.props.form.setFieldsValue({ + sql: record.sql + }) + } else { + this.props.form.setFieldsValue({ + sql: record.sql, + position: record.position || 'back' + }) + } + } + + handleConfirm = () => { + const { type } = this.props + const { editItem, skip } = this.state + // 琛ㄥ崟鎻愪氦鏃舵鏌ヨ緭鍏ュ�兼槸鍚︽纭� + this.props.form.validateFieldsAndScroll((err, values) => { + if (type === 'fullscreen' && err) { + notification.warning({ + top: 92, + message: '璇疯緭鍏ql!', + duration: 5 + }) + return + } + + if (!err) { + if (/^[\s\n]+$/.test(values.sql)) { + notification.warning({ + top: 92, + message: '璇疯緭鍏ql!', + duration: 5 + }) + return + } + + values.uuid = editItem ? editItem.uuid : '' + values.position = values.position || (editItem ? editItem.position : 'front') + + if (type === 'fullscreen' && editItem) { + values.status = editItem.status || 'true' + } + + let pass = checkSQL(values.sql, 'customscript') + + if (!pass) return + + let sql = ` + /* 绯荤粺瀛楁 */ + + Declare @UserName nvarchar(50), @FullName nvarchar(50), @RoleID nvarchar(512), @mk_departmentcode nvarchar(512), @mk_organization nvarchar(512), @mk_user_type nvarchar(20), @mk_nation nvarchar(50), @mk_province nvarchar(50), @mk_city nvarchar(50), @mk_district nvarchar(50), @mk_address nvarchar(100), @ErrorCode nvarchar(50), @retmsg nvarchar(4000), @account_id nvarchar(50), @account_year_id nvarchar(50), @account_code nvarchar(50), @account_year_code nvarchar(50), @bid nvarchar(50), @tbid nvarchar(50) + + Select @UserName='', @FullName='', @RoleID='', @mk_departmentcode='', @mk_organization='', @mk_user_type='', @mk_nation='', @mk_province='', @mk_city='', @mk_district='', @mk_address='', @ErrorCode='', @retmsg='', @account_id='', @account_year_id='', @account_code='', @account_year_code='', @bid='' + + ` + + let _prevCustomScript = '' // 榛樿sql鍓嶆墽琛岃剼鏈� + let _backCustomScript = '' // 榛樿sql鍚庢墽琛岃剼鏈� + + this.props.customScripts.forEach(item => { + if (item.status === 'false') return + + if (item.position === 'front') { + _prevCustomScript += ` + /* 榛樿sql鍓嶈剼鏈� */ + ${values.uuid === item.uuid ? values.sql : item.sql} + ` + } else { + _backCustomScript += ` + /* 榛樿sql鍚庤剼鏈� */ + ${values.uuid === item.uuid ? values.sql : item.sql} + ` + } + }) + + if (!values.uuid) { + if (values.position === 'front') { + _prevCustomScript += ` + /* 榛樿sql鍓嶈剼鏈� */ + ${values.sql} + ` + } else { + _backCustomScript += ` + /* 榛樿sql鍚庤剼鏈� */ + ${values.sql} + ` + } + } + + sql += _prevCustomScript + _backCustomScript + sql += ` + aaa: select @ErrorCode as ErrorCode,@retmsg as retmsg + ` + + // 鏁版嵁鏉冮檺 + sql = sql.replace(/@\$|\$@/ig, '') + sql = sql.replace(/@datam@/ig, `''`) + sql = sql.replace(/@typename@/ig, `'debug'`) + + if (skip) { + this.setState({ + skip: false, + editItem: null + }, () => { + this.props.scriptsChange(values) + }) + this.props.form.setFieldsValue({ + sql: ' ' + }) + } else { + this.setState({loading: true}) + Api.sDebug(sql).then(res => { + if (res.status || res.ErrCode === '-2') { + this.setState({ + loading: false, + editItem: null + }, () => { + this.props.scriptsChange(values) + }) + this.props.form.setFieldsValue({ + sql: ' ' + }) + } else { + this.setState({loading: false}) + + Modal.error({ + title: res.message + }) + } + }) + } + } + }) + } + + handleCancel = () => { + this.setState({ + editItem: null + }) + + this.props.form.setFieldsValue({ + sql: ' ' + }) + } + + selectScript = (value, option) => { + if (!value || !option) return + let _sql = this.props.form.getFieldValue('sql') + if (/^\s+$/.test(_sql)) { + _sql = '' + } + if (_sql) { + _sql = _sql + ` + + ` + } + + _sql = _sql.replace(/\s{6}$/, '') + _sql = _sql + `/*${option.props.children}*/ + ` + _sql = _sql.replace(/\s{4}$/, '') + _sql = _sql + value + + this.props.form.setFieldsValue({ + sql: _sql + }) + } + + render() { + const { systemScripts, type } = this.props + const { getFieldDecorator } = this.props.form + const { editItem, skip } = this.state + const formItemLayout = { + labelCol: { + xs: { span: 24 }, + sm: { span: 8 } + }, + wrapperCol: { + xs: { span: 24 }, + sm: { span: 16 } + } + } + + return ( + <Form {...formItemLayout} className="verify-form"> + <Row gutter={24}> + {!type ? <Col span={8}> + <Form.Item label="鎶ラ敊瀛楁" style={{margin: 0, whiteSpace: 'nowrap'}}> + ErrorCode锛堝鍔犲悗缂�NT琛ㄧず鏁版嵁涓嶅洖婊氾紝濡侲NT銆丯NT銆丗NT銆丯MNT銆丆NT銆�-2NT锛�, retmsg + </Form.Item> + </Col> : null} + {!type ? <Col span={24} className="sqlfield"> + <Form.Item label="鍙敤瀛楁"> + <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'鍏叡鍊硷紝璇锋寜鐓xxx@鏍煎紡浣跨敤銆�'}><span style={{color: '#1890ff'}}>BID, ID, LoginUID, SessionUid, UserID, Appkey, time_id, typename, datam</span></Tooltip>, + <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title={'绯荤粺鍙橀噺锛岀郴缁熶細瀹氫箟鍙橀噺骞惰祴鍊笺��'}><span style={{color: '#fa8c16'}}>UserName, FullName, RoleID, mk_departmentcode, mk_organization, mk_user_type, mk_nation, mk_province, mk_city, mk_district, mk_address</span></Tooltip>, + </Form.Item> + </Col> : null} + {!type ? <Col span={8} style={{whiteSpace: 'nowrap'}}> + <Form.Item style={{marginBottom: 0}} label={ + <Tooltip placement="bottomLeft" title={'鑷畾涔夎剼鏈笌榛樿sql浣嶇疆鍏崇郴銆�'}> + <QuestionCircleOutlined className="mk-form-tip" /> + 鎵ц浣嶇疆 + </Tooltip> + }> + {getFieldDecorator('position', { + initialValue: 'front' + })( + <Radio.Group> + <Radio value="front">sql鍓�</Radio> + <Radio value="back">sql鍚�</Radio> + </Radio.Group> + )} + </Form.Item> + </Col> : null} + {!type ? <Col span={8}> + <Form.Item label="蹇嵎娣诲姞" style={{marginBottom: 0}}> + <Select + showSearch + dropdownMatchSelectWidth={false} + filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0} + onChange={this.selectScript} + > + <Select.Option key="default" value="defaultSql">榛樿sql</Select.Option> + {systemScripts.map((option, i) => + <Select.Option key={i} value={option.value}>{option.name}</Select.Option> + )} + </Select> + </Form.Item> + </Col> : null} + <Col span={5} className="add" style={{whiteSpace: 'nowrap'}}> + <Button onClick={this.handleConfirm} loading={this.state.loading} className="mk-green" style={{marginBottom: 15, marginLeft: 40}}> + {type === 'fullscreen' && !editItem ? '娣诲姞' : '淇濆瓨'} + </Button> + <Button onClick={this.handleCancel} style={{marginBottom: 15, marginLeft: 10}}> + 鍙栨秷 + </Button> + </Col> + <Col span={3} className="forced" style={{paddingTop: '12px', fontSize: '12px', whiteSpace: 'nowrap'}}> + 寮哄埗淇濆瓨锛� + <Switch checked={skip} size="small" onChange={() => this.setState({skip: !skip})}/> + </Col> + <Col span={24} className="sql"> + <Form.Item label={ + <Tooltip placement="bottomLeft" title="鏁版嵁鏉冮檺鏇挎崲绗� $@ -> /* 鎴� \'\'銆� @$ -> */ 鎴� \'\'"> + <QuestionCircleOutlined className="mk-form-tip" /> + sql + </Tooltip> + }> + {getFieldDecorator('sql', { + initialValue: '', + rules: [ + { + required: true, + message: '璇疯緭鍏ql!' + } + ] + })(<CodeMirror />)} + </Form.Item> + </Col> + </Row> + </Form> + ) + } +} + +export default Form.create()(CustomForm) \ No newline at end of file diff --git a/src/menu/components/module/invoice/verifycard/callbackcustomscript/index.scss b/src/menu/components/module/invoice/verifycard/callbackcustomscript/index.scss new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/menu/components/module/invoice/verifycard/callbackcustomscript/index.scss diff --git a/src/menu/components/module/invoice/verifycard/customscript/index.jsx b/src/menu/components/module/invoice/verifycard/customscript/index.jsx new file mode 100644 index 0000000..d7b10ff --- /dev/null +++ b/src/menu/components/module/invoice/verifycard/customscript/index.jsx @@ -0,0 +1,284 @@ +import React, {Component} from 'react' +import PropTypes from 'prop-types' +import { Form, Row, Col, Button, notification, Modal, Tooltip, Select, Switch } from 'antd' +import { QuestionCircleOutlined } from '@ant-design/icons' + +import Api from '@/api' +import { checkSQL } from '@/utils/utils-custom.js' +import CodeMirror from '@/templates/zshare/codemirror' +// import './index.scss' + +class CustomForm extends Component { + static propTpyes = { + type: PropTypes.any, + systemScripts: PropTypes.array, + customScripts: PropTypes.array, + scriptsChange: PropTypes.func + } + + state = { + editItem: null, + loading: false, + skip: false + } + + edit = (record) => { + this.setState({ + editItem: record + }) + + this.props.form.setFieldsValue({ + sql: record.sql + }) + } + + handleConfirm = () => { + const { type } = this.props + const { editItem, skip } = this.state + // 琛ㄥ崟鎻愪氦鏃舵鏌ヨ緭鍏ュ�兼槸鍚︽纭� + this.props.form.validateFieldsAndScroll((err, values) => { + if (type === 'fullscreen' && err) { + notification.warning({ + top: 92, + message: '璇疯緭鍏ql!', + duration: 5 + }) + return + } + if (!err) { + if (/^[\s\n]+$/.test(values.sql)) { + notification.warning({ + top: 92, + message: '璇疯緭鍏ql!', + duration: 5 + }) + return + } + values.uuid = editItem ? editItem.uuid : '' + + if (type === 'fullscreen' && editItem) { + values.status = editItem.status || 'true' + } + + let pass = checkSQL(values.sql, 'customscript') + + if (!pass) return + + let sql = ` + /* 绯荤粺瀛楁 */ + + Declare @UserName nvarchar(50), @FullName nvarchar(50), @RoleID nvarchar(512), @mk_departmentcode nvarchar(512), @mk_organization nvarchar(512), @mk_user_type nvarchar(20), @mk_nation nvarchar(50), @mk_province nvarchar(50), @mk_city nvarchar(50), @mk_district nvarchar(50), @mk_address nvarchar(100), @ErrorCode nvarchar(50), @retmsg nvarchar(4000), @account_id nvarchar(50), @account_year_id nvarchar(50), @account_code nvarchar(50), @account_year_code nvarchar(50), @bid nvarchar(50), @tbid nvarchar(50) + + Select @UserName='', @FullName='', @RoleID='', @mk_departmentcode='', @mk_organization='', @mk_user_type='', @mk_nation='', @mk_province='', @mk_city='', @mk_district='', @mk_address='', @ErrorCode='', @retmsg='', @account_id='', @account_year_id='', @account_code='', @account_year_code='', @bid='' + + /* 鍙戠エ涓昏〃瀛楁 */ + + Declare @invoice_type Nvarchar(50), @from_to_name Nvarchar(50), @from_to_tax_no Nvarchar(50), @from_to_addr Nvarchar(100), @from_to_tel Nvarchar(50), @from_to_bank_name Nvarchar(50), @from_to_account_no Nvarchar(50), @from_to_mob Nvarchar(50), @from_to_email Nvarchar(50), @from_to_code Nvarchar(50), @orgname Nvarchar(50), @tax_no Nvarchar(50), @addr Nvarchar(100), @tel Nvarchar(50), @bank_name Nvarchar(50), @account_no Nvarchar(50), @remark Nvarchar(512), @payee Nvarchar(50), @reviewer Nvarchar(50), @drawer Nvarchar(50) + + Select @invoice_type='', @from_to_name='', @from_to_tax_no='', @from_to_addr='', @from_to_tel='', @from_to_bank_name='', @from_to_account_no='', @from_to_mob='', @from_to_email='', @from_to_code='', @orgname='', @tax_no='', @addr='', @tel='', @bank_name='', @account_no='', @remark='', @payee='', @reviewer='', @drawer='' + + /* 鍙戠エ鏄庣粏涓存椂琛� */ + Declare @details_list table (productcode Nvarchar(50), productname Nvarchar(50), spec Nvarchar(50), unit Nvarchar(50), bill_count Decimal(18,10), unitprice Decimal(18,10), amount_line Decimal(18,2), tax_classify_code Nvarchar(50), tax_classify_name Nvarchar(50), tax_rate Decimal(18,2), tax_amount Decimal(18,2)) + + Insert into @details_list (productcode, productname, spec, unit, bill_count, unitprice, amount_line, tax_classify_code, tax_classify_name, tax_rate, tax_amount) + + Select '', '', '', '', 0, 0, 0, '', '', 0, 0 + + ` + + this.props.customScripts.forEach(item => { + let _item = values.uuid === item.uuid ? values : item + + if (_item.status === 'false') return + + sql += ` + ${_item.sql} + ` + }) + + if (!values.uuid) { + sql += ` + ${values.sql} + ` + } + + sql += ` + aaa: select @ErrorCode as ErrorCode,@retmsg as retmsg + ` + + // 鏁版嵁鏉冮檺 + sql = sql.replace(/@\$|\$@/ig, '') + sql = sql.replace(/@datam@/ig, `''`) + sql = sql.replace(/@typename@/ig, `'debug'`) + + if (skip) { + this.setState({ + skip: false, + editItem: null + }, () => { + this.props.scriptsChange(values) + }) + this.props.form.setFieldsValue({ + sql: ' ' + }) + } else { + this.setState({loading: true}) + Api.sDebug(sql).then(res => { + if (res.status || res.ErrCode === '-2') { + this.setState({ + loading: false, + editItem: null + }, () => { + this.props.scriptsChange(values) + }) + this.props.form.setFieldsValue({ + sql: ' ' + }) + } else { + this.setState({loading: false}) + + Modal.error({ + title: res.message + }) + } + }) + } + } + }) + } + + handleCancel = () => { + this.setState({ + editItem: null + }) + + this.props.form.setFieldsValue({ + sql: ' ' + }) + } + + selectScript = (value, option) => { + if (!value || !option) return + + let _sql = this.props.form.getFieldValue('sql') + if (/^\s+$/.test(_sql)) { + _sql = '' + } + if (_sql) { + _sql = _sql + ` + + ` + } + + _sql = _sql.replace(/\s{6}$/, '') + _sql = _sql + `/*${option.props.children}*/ + ` + _sql = _sql.replace(/\s{4}$/, '') + _sql = _sql + value + + this.props.form.setFieldsValue({ + sql: _sql + }) + } + + render() { + const { systemScripts, type } = this.props + const { getFieldDecorator } = this.props.form + const { editItem, skip } = this.state + const formItemLayout = { + labelCol: { + xs: { span: 24 }, + sm: { span: 8 } + }, + wrapperCol: { + xs: { span: 24 }, + sm: { span: 16 } + } + } + + return ( + <Form {...formItemLayout} className="verify-form"> + <Row gutter={24}> + {!type ? <Col span={8}> + <Form.Item label={'鎶ラ敊瀛楁'} style={{margin: 0, whiteSpace: 'nowrap'}}> + ErrorCode锛堝鍔犲悗缂�NT琛ㄧず鏁版嵁涓嶅洖婊氾紝濡侲NT銆丯NT銆丗NT銆丯MNT銆丆NT銆�-2NT锛�, retmsg + </Form.Item> + </Col> : null} + {!type ? <Col span={24} className="sqlfield"> + <Form.Item label={'鍙敤瀛楁'}> + <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title="鍏叡鍊硷紝璇锋寜鐓xxx@鏍煎紡浣跨敤銆�"><span style={{color: '#1890ff'}}>BID, ID, LoginUID, SessionUid, UserID, Appkey, time_id, typename, datam</span></Tooltip>, + <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title="绯荤粺鍙橀噺锛岀郴缁熶細瀹氫箟鍙橀噺骞惰祴鍊笺��"><span style={{color: '#fa8c16'}}>UserName, FullName, RoleID, mk_departmentcode, mk_organization, mk_user_type, mk_nation, mk_province, mk_city, mk_district, mk_address</span></Tooltip>, + <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title="璐﹀瀛楁锛岀郴缁熶細瀹氫箟鍙橀噺骞惰祴鍊笺��"><span style={{color: '#13c2c2'}}>account_id, account_year_id, account_code, account_year_code </span></Tooltip>, + <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title="涓昏〃瀛楁锛岀郴缁熶細瀹氫箟鍙橀噺骞惰祴鍊笺��"><span style={{color: '#8E44AD'}}>invoice_type, from_to_name, from_to_tax_no, from_to_addr, from_to_tel, from_to_bank_name, from_to_account_no, from_to_mob, from_to_email, from_to_code, orgname, tax_no, addr, tel, bank_name, account_no, remark, payee, reviewer, drawer</span></Tooltip>, + <Tooltip mouseLeaveDelay={0.3} mouseEnterDelay={0.3} placement="top" title="瀛愯〃瀛楁锛堝晢鍝佹槑缁嗭級锛岀郴缁熶細瀹氫箟鍙橀噺骞惰祴鍊笺��">productcode, productname, spec, unit, bill_count, unitprice, amount_line, tax_classify_code, tax_classify_name, tax_rate, tax_amount</Tooltip> + </Form.Item> + </Col> : null} + {/* {!_type ? <Col span={8} style={{whiteSpace: 'nowrap'}}> + <Form.Item style={{marginBottom: 0}} label={ + <Tooltip placement="bottomLeft" title="鑷畾涔夎剼鏈笌榛樿sql浣嶇疆鍏崇郴銆�"> + <QuestionCircleOutlined className="mk-form-tip" /> + 鎵ц浣嶇疆 + </Tooltip> + }> + {getFieldDecorator('position', { + initialValue: 'front' + })( + <Radio.Group> + <Radio value="init">鍒濆鍖�</Radio> + <Radio value="front">sql鍓�</Radio> + <Radio value="back">sql鍚�</Radio> + </Radio.Group> + )} + </Form.Item> + </Col> : null} */} + {!type ? <Col span={8}> + <Form.Item label={'蹇嵎娣诲姞'} style={{marginBottom: 0}}> + <Select + showSearch + dropdownMatchSelectWidth={false} + filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0} + onSelect={this.selectScript} + > + {systemScripts.map((option, i) => + <Select.Option key={i} value={option.value}>{option.name}</Select.Option> + )} + </Select> + </Form.Item> + </Col> : null} + <Col span={5} className="add" style={{whiteSpace: 'nowrap'}}> + <Button onClick={this.handleConfirm} loading={this.state.loading} className="mk-green" style={{marginBottom: 15, marginLeft: 30}}> + {type === 'fullscreen' && !editItem ? '娣诲姞' : '淇濆瓨'} + </Button> + <Button onClick={this.handleCancel} style={{marginBottom: 15, marginLeft: 10}}> + 鍙栨秷 + </Button> + </Col> + <Col span={3} className="forced" style={{paddingTop: '12px', fontSize: '12px', whiteSpace: 'nowrap'}}> + 寮哄埗淇濆瓨锛� + <Switch checked={skip} size="small" onChange={() => this.setState({skip: !skip})}/> + </Col> + <Col span={24} className="sql"> + <Form.Item label={ + <Tooltip placement="bottomLeft" title="鏁版嵁鏉冮檺鏇挎崲绗� $@ -> /* 鎴� \'\'銆� @$ -> */ 鎴� \'\'"> + <QuestionCircleOutlined className="mk-form-tip" /> + sql + </Tooltip> + }> + {getFieldDecorator('sql', { + initialValue: '', + rules: [ + { + required: true, + message: '璇疯緭鍏ql!' + } + ] + })(<CodeMirror />)} + </Form.Item> + </Col> + </Row> + </Form> + ) + } +} + +export default Form.create()(CustomForm) \ No newline at end of file diff --git a/src/menu/components/module/invoice/verifycard/customscript/index.scss b/src/menu/components/module/invoice/verifycard/customscript/index.scss new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/menu/components/module/invoice/verifycard/customscript/index.scss diff --git a/src/menu/components/module/invoice/verifycard/index.jsx b/src/menu/components/module/invoice/verifycard/index.jsx new file mode 100644 index 0000000..b61b9ec --- /dev/null +++ b/src/menu/components/module/invoice/verifycard/index.jsx @@ -0,0 +1,690 @@ +import React, {Component} from 'react' +import PropTypes from 'prop-types' +import { is, fromJS } from 'immutable' +import { Form, Tabs, Row, Col, Button, Popconfirm, notification, Modal, message, Typography, InputNumber } from 'antd' +import { CheckCircleOutlined, StopOutlined, EditOutlined, SwapOutlined, DeleteOutlined } from '@ant-design/icons' +import moment from 'moment' + +import Api from '@/api' +import Utils from '@/utils/utils.js' +import BaseForm from './baseform' +import CustomScript from './customscript' +import CallBackCustomScript from './callbackcustomscript' +import asyncComponent from '@/utils/asyncComponent' +import MKEmitter from '@/utils/events.js' +import './index.scss' + +const { TabPane } = Tabs +const { confirm } = Modal +const { Paragraph } = Typography +const EditTable = asyncComponent(() => import('@/templates/zshare/editTable')) +const FullScripts = asyncComponent(() => import('@/templates/zshare/verifycard/fullScripts')) + +class VerifyCard extends Component { + static propTpyes = { + config: PropTypes.any, + card: PropTypes.object, + columns: PropTypes.array + } + + state = { + activeKey: 'base', + verify: {}, + systemScripts: [], + scriptsColumns: [ + { + title: 'SQL', + dataIndex: 'sql', + width: '70%', + render: (text) => { + let title = text.match(/^\s*\/\*.+\*\//) + title = title && title[0] ? title[0] : '' + let _text = title ? text.replace(title, '') : text + + return ( + <div> + {title ? <span style={{color: '#a50'}}>{title}<span style={{fontSize: '12px', marginLeft: '5px'}}>{_text.length}</span></span> : null} + <Paragraph copyable={{ text: text }} ellipsis={{ rows: 4, expandable: true }}>{_text}</Paragraph> + </div> + ) + } + }, + // { + // title: '鎵ц浣嶇疆', + // dataIndex: 'position', + // width: '10%', + // render: (text, record) => { + // if (record.position === 'init') { + // return <span style={{color: 'orange'}}>鍒濆鍖�</span> + // } else if (record.position === 'front') { + // return <span style={{color: '#26C281'}}>sql鍓�</span> + // } else { + // return <span style={{color: '#1890ff'}}>sql鍚�</span> + // } + // } + // }, + { + title: '鐘舵��', + dataIndex: 'status', + width: '10%', + render: (text, record) => record.status === 'false' ? + ( + <div style={{color: '#ff4d4f'}}> + 绂佺敤 + <StopOutlined style={{marginLeft: '5px'}} /> + </div> + ) : + ( + <div style={{color: '#26C281'}}> + 鍚敤 + <CheckCircleOutlined style={{marginLeft: '5px'}}/> + </div> + ) + }, + { + title: '鎿嶄綔', + align: 'center', + width: '140px', + dataIndex: 'operation', + render: (_, record) => + (<div style={{textAlign: 'center'}}> + <span className="operation-btn" title="缂栬緫" onClick={() => this.handleEdit(record, 'scripts')} style={{color: '#1890ff'}}><EditOutlined /></span> + <span className="operation-btn" title="鐘舵�佸垏鎹�" onClick={() => this.handleStatus(record, 'scripts')} style={{color: '#8E44AD'}}><SwapOutlined /></span> + <Popconfirm + overlayClassName="popover-confirm" + title="纭畾鍒犻櫎鍚�?" + onConfirm={() => this.handleDelete(record, 'scripts') + }> + <span className="operation-btn" style={{color: '#ff4d4f'}}><DeleteOutlined /></span> + </Popconfirm> + </div>) + } + ], + cbScriptsColumns: [ + { + title: 'SQL', + dataIndex: 'sql', + width: '60%', + render: (text) => { + let title = text.match(/^\s*\/\*.+\*\//) + title = title && title[0] ? title[0] : '' + let _text = title ? text.replace(title, '') : text + + return ( + <div> + {title ? <span style={{color: '#a50'}}>{title}<span style={{fontSize: '12px', marginLeft: '5px'}}>{_text.length}</span></span> : null} + <Paragraph copyable={{ text: text }} ellipsis={{ rows: 4, expandable: true }}>{_text}</Paragraph> + </div> + ) + } + }, + { + title: '鎵ц浣嶇疆', + dataIndex: 'position', + width: '10%', + render: (_, record) => { + if (record.position === 'front') { + return <span style={{color: '#26C281'}}>sql鍓�</span> + } else { + return <span style={{color: '#1890ff'}}>sql鍚�</span> + } + } + }, + { + title: '鐘舵��', + dataIndex: 'status', + width: '10%', + render: (_, record) => record.status === 'false' ? + ( + <div style={{color: '#ff4d4f'}}> + 绂佺敤 + <StopOutlined style={{marginLeft: '5px'}} /> + </div> + ) : + ( + <div style={{color: '#26C281'}}> + 鍚敤 + <CheckCircleOutlined style={{marginLeft: '5px'}}/> + </div> + ) + }, + { + title: '鎿嶄綔', + align: 'center', + width: '20%', + dataIndex: 'operation', + render: (text, record) => + (<div style={{textAlign: 'center'}}> + <span className="operation-btn" title="缂栬緫" onClick={() => this.handleEdit(record, 'cbscripts')} style={{color: '#1890ff'}}><EditOutlined /></span> + <span className="operation-btn" title="鐘舵�佸垏鎹�" onClick={() => this.handleStatus(record, 'cbscripts')} style={{color: '#8E44AD'}}><SwapOutlined /></span> + <Popconfirm + overlayClassName="popover-confirm" + title="纭畾鍒犻櫎鍚�?" + onConfirm={() => this.handleDelete(record, 'cbscripts') + }> + <span className="operation-btn" style={{color: '#ff4d4f'}}><DeleteOutlined /></span> + </Popconfirm> + </div>) + } + ] + } + + UNSAFE_componentWillMount() { + const { card } = this.props + let _verify = fromJS(card).toJS() + + // _verify.intertype = _verify.intertype || 'system' + _verify.scripts = _verify.scripts || [] + _verify.cbScripts = _verify.cbScripts || [] + + _verify.scripts.forEach((item, i) => { + item.$index = i + 1 + }) + _verify.cbScripts.forEach((item, i) => { + item.$index = i + 1 + }) + + this.setState({ + activeKey: 'base', + verify: _verify, + oriVerify: fromJS(_verify).toJS() + }) + } + + componentDidMount() { + let mutilForms = [ + { + obj_name: 'scripts', + arr_field: 'funcname,longparam', + LText: window.btoa(window.encodeURIComponent(`Select distinct func+Remark as funcname,longparam, s.Sort from s_custom_script s inner join (select OpenID from sapp where ID=@Appkey@) p on s.openid = case when s.appkey='' then s.openid else p.OpenID end order by s.Sort`)) + } + ] + + mutilForms = mutilForms.map(item => `select '${item.obj_name}' as obj_name,'${item.arr_field}' as arr_field,'${item.LText}' as LText`) + + let mutilparam = { + func: 'sPC_Get_SelectedList', + LText: mutilForms.join(' union all '), + obj_name: '', + arr_field: '', + table_type: 'Y', + exec_type: 'x' + } + + mutilparam.LText = Utils.formatOptions(mutilparam.LText, 'x') + mutilparam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') + mutilparam.secretkey = Utils.encrypt('', mutilparam.timestamp) + mutilparam.open_key = Utils.encryptOpenKey(mutilparam.secretkey, mutilparam.timestamp) + + if (window.GLOB.cloudServiceApi) { // 浜戠璇锋眰 + mutilparam.rduri = window.GLOB.cloudServiceApi + mutilparam.userid = sessionStorage.getItem('CloudUserID') || '' + mutilparam.LoginUID = sessionStorage.getItem('CloudLoginUID') || '' + } + + Api.getSystemCacheConfig(mutilparam).then(res => { + if (res.status) { + this.setState({ + systemScripts: res.scripts.map(item => { + return { + name: item.funcname, + value: window.decodeURIComponent(window.atob(item.longparam)) + } + }) + }) + } else { + notification.warning({ + top: 92, + message: res.message, + duration: 5 + }) + } + }) + } + + scriptsChange = (values) => { + let verify = fromJS(this.state.verify).toJS() + + if (values.uuid) { + verify.scripts = verify.scripts.map(item => { + if (item.uuid === values.uuid) { + return values + } else { + return item + } + }) + } else { + values.uuid = Utils.getuuid() + verify.scripts.push(values) + } + + MKEmitter.emit('editLineId', values.uuid) + + this.setState({ verify }) + } + + cbScriptsChange = (values) => { + let verify = fromJS(this.state.verify).toJS() + + if (values.uuid) { + verify.cbScripts = verify.cbScripts.map(item => { + if (item.uuid === values.uuid) { + return values + } else { + return item + } + }) + } else { + values.uuid = Utils.getuuid() + verify.cbScripts.push(values) + } + + MKEmitter.emit('editLineId', values.uuid) + + this.setState({ verify }) + } + + handleDelete = (record, type) => { + const { verify } = this.state + + if (type === 'scripts') { + verify.scripts = verify.scripts.filter(item => item.uuid !== record.uuid) + } else if (type === 'cbscripts') { + verify.cbScripts = verify.cbScripts.filter(item => item.uuid !== record.uuid) + } + + this.setState({ verify }) + } + + handleEdit = (record, type) => { + let node = null + + if (type === 'scripts') { + this.scriptsForm.edit(record) + node = document.getElementById('mk-normal-script') + } else if (type === 'cbscripts') { + this.cbscriptsForm.edit(record) + node = document.getElementById('mk-callback-script') + } + + if (node && node.scrollTop) { + let inter = Math.ceil(node.scrollTop / 10) + + let timer = setInterval(() => { + if (node.scrollTop - inter > 0) { + node.scrollTop = node.scrollTop - inter + } else { + node.scrollTop = 0 + clearInterval(timer) + } + }, 10) + } + } + + handleStatus = (record, type) => { + let verify = fromJS(this.state.verify).toJS() + record.status = record.status === 'false' ? 'true' : 'false' + + if (type === 'scripts') { + verify.scripts = verify.scripts.map(item => { + if (item.uuid === record.uuid) { + return record + } else { + return item + } + }) + } else if (type === 'cbscripts') { + verify.cbScripts = verify.cbScripts.map(item => { + if (item.uuid === record.uuid) { + return record + } else { + return item + } + }) + } + + this.setState({ verify }) + } + + showError = (errorType) => { + const { verify } = this.state + + if (errorType === 'S') { + let time = verify.stime || 2 + notification.success({ + top: 92, + message: '鎵ц鎴愬姛锛�', + duration: time + }) + } else if (errorType === 'Y') { + Modal.success({ + title: '鎵ц鎴愬姛锛�' + }) + } else if (errorType === 'F') { + notification.error({ + className: 'notification-custom-error', + top: 92, + message: '鎵ц澶辫触锛�', + duration: verify.ftime || 10 + }) + } else if (errorType === 'N') { + notification.error({ + top: 92, + message: '鎵ц澶辫触锛�', + duration: verify.ntime || 10 + }) + } else if (errorType === 'E') { + Modal.error({ + title: '鎵ц澶辫触锛�' + }) + } else if (errorType === 'NM') { + message.error('鎵ц澶辫触锛�') + } + } + + timeChange = (val, type) => { + const { verify } = this.state + + this.setState({ + verify: {...verify, [type]: val} + }) + } + + handleConfirm = () => { + const { activeKey } = this.state + let verify = fromJS(this.state.verify).toJS() + + let msg = '' + if (this.scriptsForm && this.scriptsForm.state.editItem) { + msg = '鍓嶇疆鑴氭湰' + } else if (this.scriptsForm && this.scriptsForm.props.form.getFieldValue('sql') && !/^\s+$/.test(this.scriptsForm.props.form.getFieldValue('sql'))) { + msg = '鍓嶇疆鑴氭湰' + } else if (this.cbscriptsForm && this.cbscriptsForm.state.editItem) { + msg = '鍥炶皟鑴氭湰' + } else if (this.cbscriptsForm && this.cbscriptsForm.props.form.getFieldValue('sql') && !/^\s+$/.test(this.cbscriptsForm.props.form.getFieldValue('sql'))) { + msg = '鍥炶皟鑴氭湰' + } + + return new Promise((resolve, reject) => { + if (activeKey === 'base' && verify.type === 'billout') { + this.baseForm.handleConfirm().then(res => { + let _verify = {...verify, ...res} + + if (msg) { + confirm({ + content: msg + '鏈繚瀛橈紝纭畾鎻愪氦鍚楋紵', + onOk() { + resolve(_verify) + }, + onCancel() {} + }) + } else { + resolve(_verify) + } + }) + } else { + if (msg) { + confirm({ + content: msg + '鏈繚瀛橈紝纭畾鎻愪氦鍚楋紵', + onOk() { + resolve(verify) + }, + onCancel() {} + }) + } else { + resolve(verify) + } + } + }) + } + + handleCancel = () => { + const { verify, oriVerify } = this.state + // 琛ㄥ崟鎻愪氦鏃舵鏌ヨ緭鍏ュ�兼槸鍚︽纭� + return new Promise((resolve, reject) => { + if (!is(fromJS(verify), fromJS(oriVerify))) { + confirm({ + content: '鎸夐挳淇℃伅宸蹭慨鏀癸紝纭畾鍙栨秷鍚楋紵', + onOk() { + resolve() + }, + onCancel() {} + }) + } else { + resolve() + } + }) + } + + changeTab = (val) => { + const { activeKey, verify } = this.state + + if (activeKey === 'base') { + this.baseForm.handleConfirm().then(res => { + this.setState({ + verify: {...verify, ...res}, + activeKey: val + }) + }) + } else { + this.setState({ + activeKey: val + }) + } + } + + /** + * @description 缁勪欢閿�姣侊紝娓呴櫎state鏇存柊 + */ + componentWillUnmount () { + this.setState = () => { + return + } + } + + render() { + const { card, columns } = this.props + const { activeKey, verify, scriptsColumns, cbScriptsColumns } = this.state + + return ( + <div> + <div className="mk-com-name">{card.label}</div> + <Tabs activeKey={activeKey} className="mk-invoice-tabs" onChange={this.changeTab}> + <TabPane tab="鍩虹璁剧疆" key="base"> + <BaseForm columns={columns} verify={verify} onChange={(verify) => this.setState({verify})} wrappedComponentRef={(inst) => this.baseForm = inst}/> + </TabPane> + <TabPane tab={ + <span> + 鍓嶇疆鑴氭湰 + {verify.scripts.length ? <span className="count-tip">{verify.scripts.length}</span> : null} + </span> + } key="scripts" id="mk-normal-script"> + <FullScripts + scripts={verify.scripts} + getScriptsFullForm={() => this.scriptsFullForm} + getScriptsForm={() => this.scriptsForm} + handleStatus={this.handleStatus} + handleDelete={this.handleDelete} + > + <CustomScript + type="fullscreen" + customScripts={verify.scripts} + systemScripts={this.state.systemScripts} + scriptsChange={this.scriptsChange} + wrappedComponentRef={(inst) => this.scriptsFullForm = inst} + /> + </FullScripts> + <CustomScript + customScripts={verify.scripts} + systemScripts={this.state.systemScripts} + scriptsChange={this.scriptsChange} + wrappedComponentRef={(inst) => this.scriptsForm = inst} + /> + <EditTable actions={['move']} data={verify.scripts} columns={scriptsColumns} onChange={(scripts) => {this.setState({verify: {...verify, scripts}})}}/> + </TabPane> + {card.type === 'billout' ? <TabPane tab={ + <span> + 鍥炶皟鑴氭湰 + {verify.cbScripts.length ? <span className="count-tip">{verify.cbScripts.length}</span> : null} + </span> + } key="cbScripts" id="mk-callback-script"> + <FullScripts + scripts={verify.cbScripts} + getScriptsFullForm={() => this.cbscriptsFullForm} + getScriptsForm={() => this.cbscriptsForm} + handleStatus={(item) => this.handleStatus(item, 'cbscripts')} + handleDelete={(item) => this.handleDelete(item, 'cbscripts')} + > + <CallBackCustomScript + type="fullscreen" + customScripts={verify.cbScripts} + systemScripts={this.state.systemScripts} + scriptsChange={this.cbScriptsChange} + wrappedComponentRef={(inst) => this.cbscriptsFullForm = inst} + /> + </FullScripts> + <CallBackCustomScript + customScripts={verify.cbScripts} + systemScripts={this.state.systemScripts} + scriptsChange={this.cbScriptsChange} + wrappedComponentRef={(inst) => this.cbscriptsForm = inst} + /> + <EditTable actions={['move']} data={verify.cbScripts} columns={cbScriptsColumns} onChange={(cbScripts) => {this.setState({verify: {...verify, cbScripts}})}}/> + </TabPane> : null} + <TabPane tab="sql绀轰緥" key="sql"> + <div className="mk-sql-wrap"> + <p className="note">{`/* 绯荤粺瀛楁 */`}</p> + <p> + Declare @UserName nvarchar(50), @FullName nvarchar(50), @RoleID nvarchar(512), @mk_departmentcode nvarchar(512), @mk_organization nvarchar(512), @mk_user_type nvarchar(20), @mk_nation nvarchar(50), @mk_province nvarchar(50), @mk_city nvarchar(50), @mk_district nvarchar(50), @mk_address nvarchar(100), @ErrorCode nvarchar(50), @retmsg nvarchar(4000), @account_id nvarchar(50), @account_year_id nvarchar(50), @account_code nvarchar(50), @account_year_code nvarchar(50), @bid nvarchar(50), @tbid nvarchar(50) + </p> + <p> + Select @UserName='', @FullName='', @RoleID='', @mk_departmentcode='', @mk_organization='', @mk_user_type='', @mk_nation='', @mk_province='', @mk_city='', @mk_district='', @mk_address='', @ErrorCode='', @retmsg='', @account_id='', @account_year_id='', @account_code='', @account_year_code='', @bid='' + </p> + <p className="note">{`/* 鍙戠エ涓昏〃瀛楁 */`}</p> + <p> + Declare @invoice_type Nvarchar(50), @from_to_name Nvarchar(50), @from_to_tax_no Nvarchar(50), @from_to_addr Nvarchar(100), @from_to_tel Nvarchar(50), @from_to_bank_name Nvarchar(50), @from_to_account_no Nvarchar(50), @from_to_mob Nvarchar(50), @from_to_email Nvarchar(50), @from_to_code Nvarchar(50), @orgname Nvarchar(50), @tax_no Nvarchar(50), @addr Nvarchar(100), @tel Nvarchar(50), @bank_name Nvarchar(50), @account_no Nvarchar(50), @remark Nvarchar(512), @payee Nvarchar(50), @reviewer Nvarchar(50), @drawer Nvarchar(50) + </p> + <p> + Select @invoice_type='', @from_to_name='', @from_to_tax_no='', @from_to_addr='', @from_to_tel='', @from_to_bank_name='', @from_to_account_no='', @from_to_mob='', @from_to_email='', @from_to_code='', @orgname='', @tax_no='', @addr='', @tel='', @bank_name='', @account_no='', @remark='', @payee='', @reviewer='', @drawer='' + </p> + <p className="note">{`/* 鍙戠エ鏄庣粏涓存椂琛� */`}</p> + <p> + Declare @details_list table (productcode Nvarchar(50), productname Nvarchar(50), spec Nvarchar(50), unit Nvarchar(50), bill_count Decimal(18,10), unitprice Decimal(18,10), amount_line Decimal(18,2), tax_classify_code Nvarchar(50), tax_classify_name Nvarchar(50), tax_rate Decimal(18,2), tax_amount Decimal(18,2)) + </p> + <p> + Insert into @details_list (productcode, productname, spec, unit, bill_count, unitprice, amount_line, tax_classify_code, tax_classify_name, tax_rate, tax_amount) + </p> + <p> + Select '', '', '', '', 0, 0, 0, '', '', 0, 0 + </p> + <p className="note">{`/* 鍓嶇疆鑴氭湰 */`}</p> + <p> + ...... + </p> + <p> + aaa: select @ErrorCode as ErrorCode,@retmsg as retmsg + </p> + </div> + </TabPane> + <TabPane tab="淇℃伅鎻愮ず" key="tip"> + <Form className="tip-form"> + <Row gutter={24}> + <Col offset={6} span={6}> + <Form.Item label="鎻愮ず缂栫爜"> + <span className="errorval"> S </span> + <Button onClick={() => {this.showError('S')}} type="primary" size="small"> + 鏌ョ湅 + </Button> + </Form.Item> + </Col> + <Col span={8}> + <Form.Item label="鍋滅暀鏃堕棿"> + <InputNumber defaultValue={verify.stime || 2} min={1} max={10000} precision={0} onChange={(val) => {this.timeChange(val, 'stime')}} /> + </Form.Item> + </Col> + </Row> + <Row gutter={24}> + <Col offset={6} span={6}> + <Form.Item label="鎻愮ず缂栫爜"> + <span className="errorval"> Y </span> + <Button onClick={() => {this.showError('Y')}} type="primary" size="small"> + 鏌ョ湅 + </Button> + </Form.Item> + </Col> + </Row> + <Row gutter={24}> + <Col offset={6} span={6}> + <Form.Item label="鎻愮ず缂栫爜"> + <span className="errorval"> -1 </span> + 鎵ц鎴愬姛鏃犳彁绀恒�� + </Form.Item> + </Col> + </Row> + <Row gutter={24}> + <Col offset={6} span={6}> + <Form.Item label="鎻愮ず缂栫爜"> + <span className="errorval"> N </span> + <Button onClick={() => {this.showError('N')}} type="primary" size="small"> + 鏌ョ湅 + </Button> + </Form.Item> + </Col> + <Col span={8}> + <Form.Item label="鍋滅暀鏃堕棿"> + <InputNumber defaultValue={verify.ntime || 10} min={1} max={10000} precision={0} onChange={(val) => {this.timeChange(val, 'ntime')}} /> + </Form.Item> + </Col> + </Row> + <Row gutter={24}> + <Col offset={6} span={6}> + <Form.Item label="鎻愮ず缂栫爜"> + <span className="errorval"> F </span> + <Button onClick={() => {this.showError('F')}} type="primary" size="small"> + 鏌ョ湅 + </Button> + </Form.Item> + </Col> + <Col span={8}> + <Form.Item label="鍋滅暀鏃堕棿"> + <InputNumber defaultValue={verify.ftime || 10} min={1} max={10000} precision={0} onChange={(val) => {this.timeChange(val, 'ftime')}} /> + </Form.Item> + </Col> + </Row> + <Row gutter={24}> + <Col offset={6} span={6}> + <Form.Item label="鎻愮ず缂栫爜"> + <span className="errorval"> E </span> + <Button onClick={() => {this.showError('E')}} type="primary" size="small"> + 鏌ョ湅 + </Button> + </Form.Item> + </Col> + </Row> + <Row gutter={24}> + <Col offset={6} span={6}> + <Form.Item label="鎻愮ず缂栫爜"> + <span className="errorval"> NM </span> + <Button onClick={() => {this.showError('NM')}} type="primary" size="small"> + 鏌ョ湅 + </Button> + </Form.Item> + </Col> + </Row> + <Row gutter={24}> + <Col offset={6} span={6}> + <Form.Item label="鎻愮ず缂栫爜"> + <span className="errorval"> -2 </span> + 鎵ц澶辫触鏃犳彁绀� + </Form.Item> + </Col> + </Row> + </Form> + </TabPane> + </Tabs> + </div> + ) + } +} + +export default Form.create()(VerifyCard) \ No newline at end of file diff --git a/src/menu/components/module/invoice/verifycard/index.scss b/src/menu/components/module/invoice/verifycard/index.scss new file mode 100644 index 0000000..c05f0e1 --- /dev/null +++ b/src/menu/components/module/invoice/verifycard/index.scss @@ -0,0 +1,124 @@ +.mk-invoice-tabs { + .ant-tabs-nav .ant-tabs-tab { + margin-right: 25px; + } + .ant-tabs-nav-scroll { + text-align: center; + } + .ant-tabs-content { + min-height: 40vh; + } + table tr td { + word-wrap: break-word; + word-break: break-word; + } + .count-tip { + position: absolute; + top: 0px; + color: #1890ff; + font-size: 12px; + } + .ant-input-disabled { + color: rgba(0, 0, 0, 0.85); + background-color: #ffffff; + cursor: text; + } + .ant-radio-disabled + span { + color: rgba(0, 0, 0, 0.85); + } + .base-form { + padding-right: 50px; + .ant-form-item { + display: flex; + .ant-form-item-control-wrapper { + flex: 1; + } + } + .ant-col-8 { + .ant-form-item-label { + width: 33.33%; + } + } + .ant-col-24 { + .ant-form-item-label { + width: 10.8%; + } + } + } + .tip-form { + .ant-form-item { + display: flex; + } + } + .mk-sql-wrap { + color: rgba(0, 0, 0, 0.85); + .note { + margin-bottom: 0px; + } + } + .verify-form { + .sql { + .ant-col-sm-8 { + width: 10.5%; + } + .ant-col-sm-16 { + width: 89.5%; + padding-top: 4px; + } + .CodeMirror { + height: 350px; + } + } + .sqlfield { + .ant-form-item { + margin-bottom: 5px; + } + .ant-form-item-control { + line-height: 24px; + } + .ant-form-item-label { + line-height: 25px; + } + .ant-form-item-children { + line-height: 22px; + } + .ant-col-sm-8 { + width: 10.5%; + } + .ant-col-sm-16 { + width: 89.5%; + } + } + .add { + padding-top: 4px; + + .mk-green { + margin-bottom: 15px; + } + } + } + .custom-table .ant-empty { + margin: 20px 8px!important; + } + .errorval { + display: inline-block; + width: 30px; + } + .operation-btn { + display: inline-block; + font-size: 16px; + padding: 0 5px; + cursor: pointer; + } + .operation-btn:not(:first-child) { + margin-left: 5px; + } + .full-scripts { + position: absolute; + right: 24px; + top: 0px; + font-size: 16px; + color: #1890ff; + z-index: 1; + } +} \ No newline at end of file diff --git a/src/menu/components/share/actioncomponent/actionform/index.jsx b/src/menu/components/share/actioncomponent/actionform/index.jsx index a8028cf..7c83d79 100644 --- a/src/menu/components/share/actioncomponent/actionform/index.jsx +++ b/src/menu/components/share/actioncomponent/actionform/index.jsx @@ -602,6 +602,7 @@ * 3銆佸垏鎹㈡爣绛剧被鍨嬶紝閲嶇疆鍙�夋爣绛� */ optionChange = (key, value) => { + const { type } = this.props const { hasclass, appType, requireOptions } = this.state this.record[key] = value @@ -636,9 +637,16 @@ _fieldval.label = '瀵煎嚭Excel' _fieldval.class = 'dgreen' _fieldval.execSuccess = 'never' - _fieldval.Ot = 'requiredOnce' _fieldval.control = '' - this.record.Ot = 'requiredOnce' + + if (type !== 'card') { + _fieldval.Ot = 'requiredOnce' + this.record.Ot = 'requiredOnce' + } else { + _fieldval.Ot = 'notRequired' + this.record.Ot = 'notRequired' + } + this.record.label = '瀵煎嚭Excel' this.record.class = 'dgreen' this.record.execSuccess = 'never' diff --git a/src/menu/components/share/actioncomponent/index.jsx b/src/menu/components/share/actioncomponent/index.jsx index 4029b06..a70ce71 100644 --- a/src/menu/components/share/actioncomponent/index.jsx +++ b/src/menu/components/share/actioncomponent/index.jsx @@ -718,6 +718,7 @@ destroyOnClose > <ActionForm + type={config.type === 'tree' ? 'card' : ''} card={card} formlist={this.state.formlist} inputSubmit={this.handleSubmit} diff --git a/src/menu/components/tree/antd-tree/index.jsx b/src/menu/components/tree/antd-tree/index.jsx index b093ad7..6ae5917 100644 --- a/src/menu/components/tree/antd-tree/index.jsx +++ b/src/menu/components/tree/antd-tree/index.jsx @@ -88,6 +88,7 @@ card.name = card.wrap.name card.$c_ds = true + card.$c_ac = true card.errors = checkComponent(card) diff --git a/src/tabviews/custom/components/module/invoice/index.jsx b/src/tabviews/custom/components/module/invoice/index.jsx index 7be4d48..17eda8d 100644 --- a/src/tabviews/custom/components/module/invoice/index.jsx +++ b/src/tabviews/custom/components/module/invoice/index.jsx @@ -1,13 +1,13 @@ import React, {Component} from 'react' import PropTypes from 'prop-types' import { is, fromJS } from 'immutable' -import { Select, Form, Input, Button, Modal, Spin } from 'antd' +import { Select, Form, Input, Button, Modal, Spin, notification } from 'antd' import { EllipsisOutlined } from '@ant-design/icons' import moment from 'moment' import Api from '@/api' import UtilsDM from '@/utils/utils-datamanage.js' -// import Utils from '@/utils/utils.js' +import Utils from '@/utils/utils.js' import MKEmitter from '@/utils/events.js' import InvoiceTable from './invoiceTable' import SubTable from './subTable' @@ -52,7 +52,10 @@ details: [], book: null, loading: false, - tax_type: '' + saveType: '', + tax_type: '', + reqfields: [], + requireds: [] } UNSAFE_componentWillMount () { @@ -242,8 +245,17 @@ } resetParam = (book) => { + let invTypes = book.invoice_type || [] + let invoice_type = sessionStorage.getItem('pre_invoice_type') || '' + if (invoice_type && invTypes.findIndex(item => item.value === invoice_type) === -1) { + invoice_type = '' + } + + this.getRequired(invoice_type) + return { - invTypes: book.invoice_type || [], + invoice_type, + invTypes: invTypes, orgname: book.orgname || '', tax_no: book.tax_no || '', addr: book.addr || '', @@ -295,7 +307,267 @@ } changeType = (val) => { + sessionStorage.setItem('pre_invoice_type', val) this.setState({invoice_type: val}) + this.getRequired(val) + } + + getRequired = (invoice_type) => { + if (!invoice_type) return + + let reqfields = [] + let requireds = [] + let rds = [ + {value: 'from_to_name', label: '璐拱鏂瑰悕绉�'}, + {value: 'from_to_tax_no', label: '璐拱鏂圭撼绋庝汉璇嗗埆鍙�'}, + {value: 'from_to_addr', label: '璐拱鏂瑰湴鍧�'}, + {value: 'from_to_tel', label: '璐拱鏂圭數璇�'}, + {value: 'from_to_bank_name', label: '璐拱鏂瑰紑鎴疯'}, + {value: 'from_to_account_no', label: '璐拱鏂硅处鍙�'}, + {value: 'from_to_mob', label: '璐拱鏂规墜鏈哄彿'}, + {value: 'from_to_email', label: '璐拱鏂归偖绠�'}, + + {value: 'orgname', label: '閿�鍞柟鍚嶇О'}, + {value: 'tax_no', label: '閿�鍞柟绾崇◣浜鸿瘑鍒彿'}, + {value: 'addr', label: '閿�鍞柟鍦板潃'}, + {value: 'tel', label: '閿�鍞柟鐢佃瘽'}, + {value: 'bank_name', label: '閿�鍞柟寮�鎴疯'}, + {value: 'account_no', label: '閿�鍞柟璐﹀彿'}, + ] + if (invoice_type === 'e_general') { + reqfields = ['from_to_name', 'from_to_tax_no', 'orgname', 'tax_no'] + rds.forEach(item => { + if (reqfields.includes(item.value)) { + requireds.push(item) + } + }) + } else if (invoice_type === 'e_special') { + reqfields = ['from_to_name', 'from_to_tax_no', 'from_to_addr', 'from_to_tel', 'from_to_bank_name', 'from_to_account_no', 'orgname', 'tax_no', 'addr', 'tel', 'bank_name', 'account_no'] + rds.forEach(item => { + if (reqfields.includes(item.value)) { + requireds.push(item) + } + }) + } + + this.setState({ + reqfields, + requireds + }) + } + + saveBill = () => { + const { config, saveType } = this.state + + if (saveType) return + + setTimeout(() => { + this.getBillMsg().then(() => { + let sql = this.getPreSql(config.billSaveBtn) + + let param = { + func: 'sPC_TableData_InUpDe', + LText: sql, + exec_type: window.GLOB.execType || 'y', + timestamp: moment().format('YYYY-MM-DD HH:mm:ss'), + } + + param.secretkey = Utils.encrypt('', param.timestamp) + param.LText = Utils.formatOptions(param.LText, param.exec_type) + + this.setState({ + saveType: 'bill' + }) + + Api.genericInterface(param).then(res => { + if (res.status) { + notification.success({ + top: 92, + message: '淇濆瓨鎴愬姛銆�', + duration: 5 + }) + } else { + notification.warning({ + top: 92, + message: res.message, + duration: 5 + }) + } + this.setState({ + saveType: '' + }) + }) + }, (error) => { + notification.warning({ + top: 92, + message: error, + duration: 5 + }) + return + }) + }, 20) + } + + outBill = () => { + const { config, saveType } = this.state + + if (saveType) return + + setTimeout(() => { + this.getBillMsg().then(() => { + let sql = this.getPreSql(config.billOutBtn) + + let param = { + func: 'sPC_TableData_InUpDe', + // BID: BID || '', + LText: sql, + key_back_type: 'Y', + exec_type: window.GLOB.execType || 'y', + timestamp: moment().format('YYYY-MM-DD HH:mm:ss'), + } + + param.secretkey = Utils.encrypt('', param.timestamp) + param.LText = Utils.formatOptions(param.LText, param.exec_type) + + console.info(sql) + }, (error) => { + notification.warning({ + top: 92, + message: error, + duration: 5 + }) + return + }) + }) + } + + getPreSql = (btn) => { + const { book, details, invoice_type, from_to_name, from_to_tax_no, from_to_addr, from_to_tel, from_to_bank_name, from_to_account_no, from_to_mob, from_to_email, from_to_code, orgname, tax_no, addr, tel, bank_name, account_no, remark, reviewer, drawer, payee } = this.state + + let userName = sessionStorage.getItem('User_Name') || '' + let fullName = sessionStorage.getItem('Full_Name') || '' + let RoleID = sessionStorage.getItem('role_id') || '' + let departmentcode = sessionStorage.getItem('departmentcode') || '' + let organization = sessionStorage.getItem('organization') || '' + let mk_user_type = sessionStorage.getItem('mk_user_type') || '' + let nation = sessionStorage.getItem('nation') || '' + let province = sessionStorage.getItem('province') || '' + let city = sessionStorage.getItem('city') || '' + let district = sessionStorage.getItem('district') || '' + let address = sessionStorage.getItem('address') || '' + + let lines = details.map(line => `Select '${line.productcode}', '${line.productname}', '${line.spec}', '${line.unit}', ${line.bill_count}, ${line.unitprice}, ${line.amount_line}, '${line.tax_classify_code}', '${line.tax_classify_name}', ${line.tax_rate}, ${line.tax_amount}`) + lines = lines.join(' union all ') + + let _script = '' + btn.scripts.forEach(item => { + if (item.status === 'false') return + _script += ` + ${item.sql} + ` + }) + + let sql = `/* 绯荤粺瀛楁 */ + Declare @UserName nvarchar(50), @FullName nvarchar(50), @RoleID nvarchar(512), @mk_departmentcode nvarchar(512), @mk_organization nvarchar(512), @mk_user_type nvarchar(20), @mk_nation nvarchar(50), @mk_province nvarchar(50), @mk_city nvarchar(50), @mk_district nvarchar(50), @mk_address nvarchar(100), @ErrorCode nvarchar(50), @retmsg nvarchar(4000), @account_id nvarchar(50), @account_year_id nvarchar(50), @account_code nvarchar(50), @account_year_code nvarchar(50), @bid nvarchar(50), @tbid nvarchar(50) + + Select @UserName='${userName}', @FullName='${fullName}', @RoleID='${RoleID}', @mk_departmentcode='${departmentcode}', @mk_organization='${organization}', @mk_user_type='${mk_user_type}', @mk_nation='${nation}', @mk_province='${province}', @mk_city='${city}', @mk_district='${district}', @mk_address='${address}', @ErrorCode='', @retmsg='', @account_id='${book.account_id || ''}', @account_year_id='${book.account_year_id || ''}', @account_code='${book.account_code || ''}', @account_year_code='${book.account_year_code || ''}', @bid='' + + /* 鍙戠エ涓昏〃瀛楁 */ + Declare @invoice_type Nvarchar(50), @from_to_name Nvarchar(50), @from_to_tax_no Nvarchar(50), @from_to_addr Nvarchar(100), @from_to_tel Nvarchar(50), @from_to_bank_name Nvarchar(50), @from_to_account_no Nvarchar(50), @from_to_mob Nvarchar(50), @from_to_email Nvarchar(50), @from_to_code Nvarchar(50), @orgname Nvarchar(50), @tax_no Nvarchar(50), @addr Nvarchar(100), @tel Nvarchar(50), @bank_name Nvarchar(50), @account_no Nvarchar(50), @remark Nvarchar(512), @payee Nvarchar(50), @reviewer Nvarchar(50), @drawer Nvarchar(50) + + Select @invoice_type='${invoice_type}', @from_to_name='${from_to_name}', @from_to_tax_no='${from_to_tax_no}', @from_to_addr='${from_to_addr}', @from_to_tel='${from_to_tel}', @from_to_bank_name='${from_to_bank_name}', @from_to_account_no='${from_to_account_no}', @from_to_mob='${from_to_mob}', @from_to_email='${from_to_email}', @from_to_code='${from_to_code}', @orgname='${orgname}', @tax_no='${tax_no}', @addr='${addr}', @tel='${tel}', @bank_name='${bank_name}', @account_no='${account_no}', @remark='${remark}', @payee='${payee}', @reviewer='${reviewer}', @drawer='${drawer}' + + /* 鍙戠エ鏄庣粏涓存椂琛� */ + + Declare @details_list table (productcode Nvarchar(50), productname Nvarchar(50), spec Nvarchar(50), unit Nvarchar(50), bill_count Decimal(18,10), unitprice Decimal(18,10), amount_line Decimal(18,2), tax_classify_code Nvarchar(50), tax_classify_name Nvarchar(50), tax_rate Decimal(18,2), tax_amount Decimal(18,2)) + + Insert into @details_list (productcode, productname, spec, unit, bill_count, unitprice, amount_line, tax_classify_code, tax_classify_name, tax_rate, tax_amount) + + ${lines} + + /* 鑷畾涔夎剼鏈� */ + ${_script} + + aaa: select @ErrorCode as ErrorCode,@retmsg as retmsg` + + sql = sql.replace(/@ID@/ig, `''`) + sql = sql.replace(/@BID@/ig, `''`) + sql = sql.replace(/@LoginUID@/ig, `'${sessionStorage.getItem('LoginUID') || ''}'`) + sql = sql.replace(/@SessionUid@/ig, `'${localStorage.getItem('SessionUid') || ''}'`) + sql = sql.replace(/@UserID@/ig, `'${sessionStorage.getItem('UserID') || ''}'`) + sql = sql.replace(/@Appkey@/ig, `'${window.GLOB.appkey || ''}'`) + sql = sql.replace(/@typename@/ig, `'admin'`) + + if (window.GLOB.externalDatabase !== null) { + sql = sql.replace(/@db@/ig, window.GLOB.externalDatabase) + } + + if (sessionStorage.getItem('dataM') === 'true') { // 鏁版嵁鏉冮檺 + sql = sql.replace(/\$@/ig, '/*').replace(/@\$/ig, '*/').replace(/@datam@/ig, `'Y'`) + } else { + sql = sql.replace(/@\$|\$@/ig, '').replace(/@datam@/ig, `''`) + } + + if (window.GLOB.debugger === true) { + console.info(sql.replace(/\n\s{6}/ig, '\n')) + } + + return sql + } + + getBillMsg = () => { + const { requireds, invoice_type, details, remark, from_to_addr, addr } = this.state + + return new Promise((resolve, reject) => { + let error = '' + + if (!invoice_type) { + error = '璇烽�夋嫨鍙戠エ绫诲瀷锛�' + } + + if (!error) { + requireds.forEach(item => { + if (!this.state[item.value] && !error) { + error = '璇疯緭鍏�' + item.label + '锛�' + } + }) + } + + if (!error && remark.length > 512) { + error = '澶囨敞涓嶅彲瓒呰繃512涓瓧绗︼紒' + } + if (!error && from_to_addr.length > 100) { + error = '璐拱鏂瑰湴鍧�涓嶅彲瓒呰繃100涓瓧绗︼紒' + } + if (!error && addr.length > 100) { + error = '閿�鍞柟鍦板潃涓嶅彲瓒呰繃100涓瓧绗︼紒' + } + + if (!error) { + if (details.length === 0) { + error = '璇锋坊鍔犳槑缁嗭紒' + } else { + details.forEach((line, index) => { + if (error) return + if (line.productcode) { + if (!line.bill_count) { + error = '鏄庣粏绗�' + (index + 1) + '琛岋紝璇疯緭鍏ユ暟閲忥紒' + } else if (!line.unitprice) { + error = '鏄庣粏绗�' + (index + 1) + '琛岋紝璇疯緭鍏ュ崟浠凤紒' + } + } else { + error = '鏄庣粏绗�' + (index + 1) + '琛岋紝璇烽�夋嫨璐х墿鎴栧簲绋庡姵鍔°�佹湇鍔″悕绉帮紒' + } + }) + } + } + + if (error) { + reject(error) + } else { + resolve() + } + }) } changeBuyer = (item) => { @@ -314,7 +586,7 @@ } render() { - const { config, book, loading, invTypes, date, from_to_name, from_to_tax_no, from_to_addr, from_to_tel, from_to_bank_name, from_to_account_no, from_to_mob, from_to_email, orgname, tax_no, addr, tel, bank_name, account_no, remark, reviewer, drawer, payee, details, visible, tax_type } = this.state + const { config, book, loading, invTypes, reqfields, saveType, date, invoice_type, from_to_name, from_to_tax_no, from_to_addr, from_to_tel, from_to_bank_name, from_to_account_no, from_to_mob, from_to_email, orgname, tax_no, addr, tel, bank_name, account_no, remark, reviewer, drawer, payee, details, visible, tax_type } = this.state if (!book || (config.wrap.datatype === 'dynamic' && !tax_no)) { return <div className="menu-invoice-wrap" style={config.style}> @@ -334,15 +606,19 @@ </div> : null } <div className="inv-action"> - <Button className="mk-bill">淇濆瓨鍗曟嵁</Button> - <Button className="mk-submit">鎻愪氦寮�绁�</Button> + <Button className="mk-bill" loading={saveType === 'bill'} onClick={this.saveBill}>淇濆瓨鍗曟嵁</Button> + <Button className="mk-submit" loading={saveType === 'out'} onClick={this.outBill}>鎻愪氦寮�绁�</Button> </div> <div className="inv-header"> - <Select placeholder="璇烽�夋嫨鍙戠エ绉嶇被" onChange={this.changeType} dropdownClassName="inv-type-select"> + {invoice_type ? <Select defaultValue={invoice_type} onChange={this.changeType} dropdownClassName="inv-type-select"> {invTypes.map(item => ( <Select.Option key={item.value} value={item.value}>{item.label}</Select.Option> ))} - </Select> + </Select> : <Select placeholder="璇烽�夋嫨鍙戠エ绉嶇被" onChange={this.changeType} dropdownClassName="inv-type-select"> + {invTypes.map(item => ( + <Select.Option key={item.value} value={item.value}>{item.label}</Select.Option> + ))} + </Select>} <div className="date">寮�绁ㄦ棩鏈燂細{date}</div> </div> <div className="inv-body"> @@ -350,17 +626,17 @@ <div className="inv-buyer"> <div className="inv-label">璐拱鏂�</div> <div className="inv-content"> - <Form.Item label={<>鍚�<span></span>绉�</>} extra={<EllipsisOutlined onClick={() => this.setState({visible: true})}/>}> + <Form.Item required={reqfields.includes('from_to_name')} label={<>鍚�<span></span>绉�</>} extra={<EllipsisOutlined onClick={() => this.setState({visible: true})}/>}> <Input placeholder="璇疯緭鍏ヨ喘涔版柟鍚嶇О" allowClear value={from_to_name} autoComplete="off" onChange={(e) => this.setState({from_to_name: e.target.value})}/> </Form.Item> - <Form.Item label="绾崇◣浜鸿瘑鍒彿"> + <Form.Item required={reqfields.includes('from_to_tax_no')} label="绾崇◣浜鸿瘑鍒彿"> <Input placeholder="璇疯緭鍏ヨ喘涔版柟绾崇◣浜鸿瘑鍒彿" allowClear value={from_to_tax_no} autoComplete="off" onChange={(e) => this.setState({from_to_tax_no: e.target.value})}/> </Form.Item> - <Form.Item className="mutil-input" label={<>鍦�<span></span>鍧�<span></span>銆�<span></span>鐢�<span></span>璇�</>}> + <Form.Item required={reqfields.includes('from_to_addr')} className="mutil-input" label={<>鍦�<span></span>鍧�<span></span>銆�<span></span>鐢�<span></span>璇�</>}> <Input placeholder="璇疯緭鍏ヨ喘涔版柟鍦板潃" allowClear value={from_to_addr} autoComplete="off" onChange={(e) => this.setState({from_to_addr: e.target.value})}/> <Input placeholder="璇疯緭鍏ヨ喘涔版柟鐢佃瘽" allowClear value={from_to_tel} autoComplete="off" onChange={(e) => this.setState({from_to_tel: e.target.value})}/> </Form.Item> - <Form.Item className="mutil-input" label="寮�鎴疯鍙婅处鍙�"> + <Form.Item required={reqfields.includes('from_to_bank_name')} className="mutil-input" label="寮�鎴疯鍙婅处鍙�"> <Input placeholder="璇疯緭鍏ヨ喘涔版柟寮�鎴疯" allowClear value={from_to_bank_name} autoComplete="off" onChange={(e) => this.setState({from_to_bank_name: e.target.value})}/> <Input placeholder="璇疯緭鍏ヨ喘涔版柟璐﹀彿" allowClear value={from_to_account_no} autoComplete="off" onChange={(e) => this.setState({from_to_account_no: e.target.value})}/> </Form.Item> @@ -369,10 +645,10 @@ <div className="inv-notice"> <div className="inv-label">閫氱煡鍒�</div> <div className="inv-content"> - <Form.Item label={<>鎵�<span></span>鏈�<span></span>鍙�</>}> + <Form.Item required={reqfields.includes('from_to_mob')} label={<>鎵�<span></span>鏈�<span></span>鍙�</>}> <Input placeholder="璇疯緭鍏ヨ喘涔版柟鎵嬫満鍙�" allowClear value={from_to_mob} autoComplete="off" onChange={(e) => this.setState({from_to_mob: e.target.value})}/> </Form.Item> - <Form.Item label={<>閭�<span></span>绠�</>}> + <Form.Item required={reqfields.includes('from_to_email')} label={<>閭�<span></span>绠�</>}> <Input placeholder="璇疯緭鍏ヨ喘涔版柟閭" allowClear value={from_to_email} autoComplete="off" onChange={(e) => this.setState({from_to_email: e.target.value})}/> </Form.Item> </div> @@ -385,17 +661,17 @@ <div className="inv-buyer"> <div className="inv-label">閿�鍞柟</div> <div className="inv-content"> - <Form.Item label={<>鍚�<span></span>绉�</>}> + <Form.Item required={reqfields.includes('orgname')} label={<>鍚�<span></span>绉�</>}> <Input placeholder="璇疯緭鍏ラ攢鍞柟鍚嶇О" value={orgname} autoComplete="off" onChange={(e) => this.setState({orgname: e.target.value})}/> </Form.Item> - <Form.Item label="绾崇◣浜鸿瘑鍒彿"> + <Form.Item required={reqfields.includes('tax_no')} label="绾崇◣浜鸿瘑鍒彿"> <Input placeholder="璇疯緭鍏ラ攢鍞柟绾崇◣浜鸿瘑鍒彿" disabled value={tax_no} autoComplete="off"/> </Form.Item> - <Form.Item className="mutil-input" label={<>鍦�<span></span>鍧�<span></span>銆�<span></span>鐢�<span></span>璇�</>}> + <Form.Item required={reqfields.includes('addr')} className="mutil-input" label={<>鍦�<span></span>鍧�<span></span>銆�<span></span>鐢�<span></span>璇�</>}> <Input placeholder="璇疯緭鍏ラ攢鍞柟鍦板潃" value={addr} autoComplete="off" onChange={(e) => this.setState({addr: e.target.value})}/> <Input placeholder="璇疯緭鍏ラ攢鍞柟鐢佃瘽" value={tel} autoComplete="off" onChange={(e) => this.setState({tel: e.target.value})}/> </Form.Item> - <Form.Item className="mutil-input" label="寮�鎴疯鍙婅处鍙�"> + <Form.Item required={reqfields.includes('bank_name')} className="mutil-input" label="寮�鎴疯鍙婅处鍙�"> <Input placeholder="璇疯緭鍏ラ攢鍞柟寮�鎴疯" value={bank_name} autoComplete="off" onChange={(e) => this.setState({bank_name: e.target.value})}/> <Input placeholder="璇疯緭鍏ラ攢鍞柟璐﹀彿" value={account_no} autoComplete="off" onChange={(e) => this.setState({account_no: e.target.value})}/> </Form.Item> diff --git a/src/tabviews/custom/components/module/invoice/index.scss b/src/tabviews/custom/components/module/invoice/index.scss index 3774eff..2d09086 100644 --- a/src/tabviews/custom/components/module/invoice/index.scss +++ b/src/tabviews/custom/components/module/invoice/index.scss @@ -191,8 +191,14 @@ .inv-buyer { border-right: var(--inv-color, #13509c) 1px solid; .ant-form-item-label { - width: 95px; - min-width: 95px; + width: 103px; + min-width: 103px; + label:not(.ant-form-item-required) { + padding-left: 11px; + } + .ant-form-item-required::before { + line-height: 30px; + } } } .inv-notice { diff --git a/src/tabviews/custom/components/tree/antd-tree/index.jsx b/src/tabviews/custom/components/tree/antd-tree/index.jsx index 1009ba9..361b59a 100644 --- a/src/tabviews/custom/components/tree/antd-tree/index.jsx +++ b/src/tabviews/custom/components/tree/antd-tree/index.jsx @@ -254,7 +254,7 @@ * @param {*} position // 鍒锋柊浣嶇疆 * @param {*} btn // 鎵ц鐨勬寜閽� */ - refreshByButtonResult = (menuId, position, btn) => { + refreshByButtonResult = (menuId, position) => { const { config, BID } = this.state if (config.uuid !== menuId) return @@ -591,7 +591,7 @@ } render() { - const { config, loading, treeNodes, expandedKeys, selectedKeys } = this.state + const { BID, BData, config, loading, treeNodes, expandedKeys, selectedKeys } = this.state let extra = config.action && config.action.length > 0 @@ -607,6 +607,14 @@ <span className={'title ' + (config.wrap.searchable !== 'true' ? 'search-unable' : '')}>{config.wrap.title}</span> {config.wrap.searchable === 'true' ? <Search allowClear onSearch={this.treeFilter} /> : null} </div> : null} + {extra ? <MainAction + BID={BID} + setting={config.setting} + actions={config.action} + BData={BData} + columns={config.columns} + selectedData={[]} + /> : null} {treeNodes && treeNodes.length > 0 ? <div className="tree-box" style={{height: config.wrap.contentHeight}}> <Tree blockNode -- Gitblit v1.8.0