| | |
| | | "randomfill": "^1.0.3" |
| | | } |
| | | }, |
| | | "crypto-js": { |
| | | "version": "4.1.1", |
| | | "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz", |
| | | "integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==" |
| | | }, |
| | | "css": { |
| | | "version": "2.2.4", |
| | | "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", |
| | |
| | | "camelcase": "^5.2.0", |
| | | "case-sensitive-paths-webpack-plugin": "2.2.0", |
| | | "codemirror": "^5.52.2", |
| | | "crypto-js": "^4.1.1", |
| | | "css-loader": "2.1.1", |
| | | "dotenv": "6.2.0", |
| | | "dotenv-expand": "4.2.0", |
| | |
| | | { |
| | | "appId": "201912040924165801464FF1788654BC5AC73", |
| | | "appkey": "20191106103859640976D6E924E464D029CF0", |
| | | "appId": "202108312122504607B107A83F55B40C98CCF", |
| | | "appkey": "20210831212235413F287EC3BF489424496C8", |
| | | "mainSystemApi": "http://sso.mk9h.cn/cloud/webapi/dostars", |
| | | "systemType": "", |
| | | "externalDatabase": "false", |
| | | "lineColor": "", |
| | | "filter": "false", |
| | | "defaultApp": "mk", |
| | | "defaultApp": "mkindustry", |
| | | "defaultLang": "zh-CN", |
| | | "WXAppID": "", |
| | | "debugger": false, |
| | | "licenseKey": "", |
| | | "probation": "", |
| | | "licenseKey": "7EFE13KIKLILIJB64C12", |
| | | "probation": "2021-12-31", |
| | | "keepPassword": "true", |
| | | "host": "http://qingqiumarket.cn", |
| | | "service": "MKWMS/" |
| | | "host": "http://demo.mk9h.cn", |
| | | "service": "erp_new/" |
| | | } |
| | |
| | | return Promise.resolve(response.data) |
| | | } |
| | | }, (error) => { |
| | | if (error && error.response) { |
| | | notification.error({ |
| | | className: 'notification-custom-error', |
| | | bottom: 0, |
| | | message: '状态码-' + error.response.status + ',请联系管理员', |
| | | placement: 'bottomRight', |
| | | duration: 15 |
| | | }) |
| | | let response = error.response |
| | | |
| | | if (response) { |
| | | if (!response.data || !response.data.errors) { // 过滤旷视报错信息 |
| | | notification.error({ |
| | | className: 'notification-custom-error', |
| | | bottom: 0, |
| | | message: '状态码-' + response.status + ',请联系管理员', |
| | | placement: 'bottomRight', |
| | | duration: 15 |
| | | }) |
| | | } |
| | | return Promise.reject(response) |
| | | } else { |
| | | return Promise.reject() |
| | | } |
| | | return Promise.reject(error.response) |
| | | }) |
| | | |
| | | class Api { |
New file |
| | |
| | | import axios from 'axios' |
| | | import jsSHA from 'jssha' |
| | | |
| | | class W4kApi { |
| | | /** |
| | | * @description 鉴权挑战 |
| | | * @param {Object} param 查询及提交参数 |
| | | */ |
| | | login (ip, username = 'admin', password) { |
| | | return new Promise((resolve, reject) => { |
| | | let challurl = ip + '/api/auth/login/challenge?username=' + username |
| | | challurl = '/trans/redirect?rd=' + challurl + '&method=get' |
| | | |
| | | let loginurl = ip + '/api/auth/login' |
| | | loginurl = '/trans/redirect?rd=' + loginurl + '&method=post' |
| | | |
| | | axios({ |
| | | url: challurl, |
| | | method: 'post' // get |
| | | }).then(res => { |
| | | if (res.errors) { |
| | | reject(res) |
| | | } else { |
| | | const shaObj = new jsSHA('SHA-256', 'TEXT', { encoding: 'UTF8' }) |
| | | shaObj.update(password + res.salt + res.challenge) |
| | | const hash = shaObj.getHash('HEX') |
| | | |
| | | axios({ |
| | | url: loginurl, |
| | | method: 'post', |
| | | data: { |
| | | session_id: res.session_id, |
| | | username: username, |
| | | password: hash |
| | | } |
| | | }).then(result => { |
| | | resolve(result) |
| | | }, (err) => { |
| | | reject(err) |
| | | }) |
| | | } |
| | | }, (err) => { |
| | | reject(err) |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | queryUsers (ip) { |
| | | let url = ip + '/api/persons/query' |
| | | url = '/trans/redirect?rd=' + url + '&method=post' |
| | | |
| | | return axios({ |
| | | url: url, |
| | | method: 'POST', |
| | | withCredentials: true, |
| | | headers: { 'Content-Type': 'application/json' }, |
| | | data: { |
| | | limit: 100, |
| | | offset: 0, |
| | | sort: 'desc', |
| | | query_id: '', |
| | | query_string: '' |
| | | } |
| | | }) |
| | | } |
| | | |
| | | addUsers (ip, data) { |
| | | return new Promise((resolve, reject) => { |
| | | let delurl = ip + '/api/persons/item/' + data.id |
| | | delurl = '/trans/redirect?rd=' + delurl + '&method=DELETE' |
| | | |
| | | let addurl = ip + '/api/persons/item' |
| | | addurl = '/trans/redirect?rd=' + addurl + '&method=post' |
| | | |
| | | if (data.deleted) { |
| | | delete data.deleted |
| | | axios({ |
| | | url: delurl, |
| | | method: 'post' // DELETE |
| | | }).then(res => { |
| | | if (res.errors) { |
| | | reject(res) |
| | | } else { |
| | | axios({ |
| | | url: addurl, |
| | | method: 'post', |
| | | data: data |
| | | }).then(result => { |
| | | resolve(result) |
| | | }, (err) => { |
| | | reject(err) |
| | | }) |
| | | } |
| | | }, (err) => { |
| | | reject(err) |
| | | }) |
| | | } else { |
| | | delete data.deleted |
| | | axios({ |
| | | url: addurl, |
| | | method: 'post', |
| | | data: data |
| | | }).then(result => { |
| | | resolve(result) |
| | | }, (err) => { |
| | | reject(err) |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | | } |
| | | |
| | | export default new W4kApi() |
| | |
| | | reTooltip.linkmenu = '使用扫码登录功能或菜单跳转功能时,需选择跳转的菜单。' |
| | | } else if (_funcType === 'goBack') { |
| | | shows.push('reload') |
| | | // } else if (_funcType === 'megvii') { |
| | | // shows.push('subFunc') |
| | | } else if (_funcType === 'megvii') { |
| | | shows.push('subFunc') |
| | | } |
| | | } |
| | | |
| | |
| | | hasProfile = true |
| | | } else if (card.funcType === 'print') { |
| | | hasProfile = true |
| | | } else if (card.funcType === 'megvii') { |
| | | hasProfile = true |
| | | } |
| | | |
| | | let btnElement = null |
| | |
| | | { value: 'changeuser', text: '切换用户' }, |
| | | { value: 'print', text: '标签打印' }, |
| | | { value: 'closetab', text: '标签关闭' }, |
| | | { value: 'megvii', text: '旷视面板机' }, |
| | | ] |
| | | |
| | | if (isApp) { |
| | |
| | | { value: 'mkUnsubscribe', text: '注销账户' }, |
| | | { value: 'reAuth', text: '切换系统(清空缓存-小程序)' }, |
| | | { value: 'goBack', text: '返回' }, |
| | | // { value: 'megvii', text: '旷视面板机' }, |
| | | ] |
| | | pageTemps = [ |
| | | { value: 'linkpage', text: '关联菜单' }, |
| | |
| | | required: true, |
| | | options: funTypes |
| | | }, |
| | | // { |
| | | // type: 'select', |
| | | // key: 'subFunc', |
| | | // label: '接口名称', |
| | | // initVal: card.subFunc || '', |
| | | // required: true, |
| | | // options: [ |
| | | // { value: 'login', text: '登录' } |
| | | // ] |
| | | // }, |
| | | { |
| | | type: 'radio', |
| | | key: 'subFunc', |
| | | label: '接口名称', |
| | | initVal: card.subFunc || 'addUser', |
| | | required: true, |
| | | options: [ |
| | | { value: 'addUser', text: '添加用户' }, |
| | | ] |
| | | }, |
| | | { |
| | | type: 'radio', |
| | | key: 'formType', |
| | |
| | | const VerifyPrint = asyncSpinComponent(() => import('@/templates/sharecomponent/actioncomponent/verifyprint')) |
| | | const VerifyExcelIn = asyncSpinComponent(() => import('@/templates/sharecomponent/actioncomponent/verifyexcelin')) |
| | | const VerifyExcelOut = asyncSpinComponent(() => import('@/templates/sharecomponent/actioncomponent/verifyexcelout')) |
| | | const VerifyMegvii = asyncSpinComponent(() => import('@/templates/sharecomponent/actioncomponent/verifymegvii')) |
| | | |
| | | class ActionComponent extends Component { |
| | | static propTpyes = { |
| | |
| | | }) |
| | | } |
| | | |
| | | getVerify = (card) => { |
| | | const { config } = this.props |
| | | const { dict } = this.state |
| | | |
| | | if (!card) return null |
| | | |
| | | if (['pop', 'prompt', 'exec'].includes(card.OpenType)) { |
| | | return <VerifyCard |
| | | card={card} |
| | | dict={dict} |
| | | config={config} |
| | | columns={config.columns} |
| | | wrappedComponentRef={(inst) => this.verifyRef = inst} |
| | | /> |
| | | } else if (card.OpenType === 'excelIn') { |
| | | return <VerifyExcelIn |
| | | card={card} |
| | | dict={dict} |
| | | columns={config.columns} |
| | | wrappedComponentRef={(inst) => this.verifyRef = inst} |
| | | /> |
| | | } else if (card.OpenType === 'excelOut') { |
| | | return <VerifyExcelOut |
| | | card={card} |
| | | dict={dict} |
| | | config={config} |
| | | wrappedComponentRef={(inst) => this.verifyRef = inst} |
| | | /> |
| | | } else if (card.OpenType === 'funcbutton' && card.funcType === 'print') { |
| | | return <VerifyPrint |
| | | card={card} |
| | | dict={dict} |
| | | columns={config.columns} |
| | | wrappedComponentRef={(inst) => this.verifyRef = inst} |
| | | /> |
| | | } else if (card.OpenType === 'funcbutton' && card.funcType === 'megvii') { |
| | | return <VerifyMegvii |
| | | card={card} |
| | | dict={dict} |
| | | columns={config.columns} |
| | | wrappedComponentRef={(inst) => this.verifyRef = inst} |
| | | /> |
| | | } |
| | | } |
| | | |
| | | render() { |
| | | const { config, type } = this.props |
| | | const { actionlist, visible, appType, card, dict, profVisible } = this.state |
| | |
| | | }} |
| | | destroyOnClose |
| | | > |
| | | {card && !card.execMode && card.OpenType !== 'excelIn' && card.OpenType !== 'excelOut' ? |
| | | <VerifyCard |
| | | card={card} |
| | | dict={dict} |
| | | config={config} |
| | | columns={config.columns} |
| | | wrappedComponentRef={(inst) => this.verifyRef = inst} |
| | | /> : null |
| | | } |
| | | {card && card.execMode ? |
| | | <VerifyPrint |
| | | card={card} |
| | | dict={dict} |
| | | columns={config.columns} |
| | | wrappedComponentRef={(inst) => this.verifyRef = inst} |
| | | /> : null |
| | | } |
| | | {card && card.OpenType === 'excelIn' ? |
| | | <VerifyExcelIn |
| | | card={card} |
| | | dict={dict} |
| | | columns={config.columns} |
| | | wrappedComponentRef={(inst) => this.verifyRef = inst} |
| | | /> : null |
| | | } |
| | | {card && card.OpenType === 'excelOut' ? |
| | | <VerifyExcelOut |
| | | card={card} |
| | | dict={dict} |
| | | config={config} |
| | | wrappedComponentRef={(inst) => this.verifyRef = inst} |
| | | /> : null |
| | | } |
| | | {this.getVerify(card)} |
| | | </Modal> |
| | | </div> |
| | | ) |
| | |
| | | // const proxy = require('http-proxy-middleware') |
| | | // const host = 'http://qingqiumarket.cn' |
| | | // const service = 'mkwms/' |
| | | const proxy = require('http-proxy-middleware') |
| | | const host = 'http://qingqiumarket.cn' |
| | | const service = 'mkwms/' |
| | | |
| | | module.exports = function() {} |
| | | // module.exports = function(app) { |
| | | // app.use(proxy('/webapi', { |
| | | // target: `${host}/${service}webapi`, |
| | | // secure: false, |
| | | // changeOrigin: true, |
| | | // pathRewrite: { |
| | | // '^/webapi': '/' |
| | | // } |
| | | // // cookieDomainRewrite: "http://localhost:3000" |
| | | // })) |
| | | // module.exports = function(app) {} |
| | | module.exports = function(app) { |
| | | // app.use(proxy('/webapi', { |
| | | // target: `${host}/${service}webapi`, |
| | | // secure: false, |
| | | // changeOrigin: true, |
| | | // pathRewrite: { |
| | | // '^/webapi': '/' |
| | | // } |
| | | // // cookieDomainRewrite: "http://localhost:3000" |
| | | // })) |
| | | |
| | | // app.use(proxy('/zh-CN', { // 登录接口 |
| | | // target: `${host}/${service}zh-CN`, |
| | | // secure: false, |
| | | // changeOrigin: true, |
| | | // pathRewrite: { |
| | | // '^/zh-CN': '/' |
| | | // } |
| | | // })) |
| | | // app.use(proxy('/zh-CN', { // 登录接口 |
| | | // target: `${host}/${service}zh-CN`, |
| | | // secure: false, |
| | | // changeOrigin: true, |
| | | // pathRewrite: { |
| | | // '^/zh-CN': '/' |
| | | // } |
| | | // })) |
| | | |
| | | // app.use(proxy('/Upload', { |
| | | // target: `${host}/${service}zh-CN/Home/Upload`, |
| | | // secure: false, |
| | | // changeOrigin: true, |
| | | // pathRewrite: { |
| | | // '^/Upload': '/' |
| | | // } |
| | | // })) |
| | | // app.use(proxy('/Upload', { |
| | | // target: `${host}/${service}zh-CN/Home/Upload`, |
| | | // secure: false, |
| | | // changeOrigin: true, |
| | | // pathRewrite: { |
| | | // '^/Upload': '/' |
| | | // } |
| | | // })) |
| | | |
| | | // app.use(proxy('/wxpay', { |
| | | // target: `${host}/${service}wxpay`, |
| | | // secure: false, |
| | | // changeOrigin: true, |
| | | // pathRewrite: { |
| | | // '^/wxpay': '/' |
| | | // } |
| | | // })) |
| | | // app.use(proxy('/wxpay', { |
| | | // target: `${host}/${service}wxpay`, |
| | | // secure: false, |
| | | // changeOrigin: true, |
| | | // pathRewrite: { |
| | | // '^/wxpay': '/' |
| | | // } |
| | | // })) |
| | | |
| | | // app.use(proxy('/trans', { |
| | | // target: `${host}/${service}trans`, |
| | | // secure: false, |
| | | // changeOrigin: true, |
| | | // pathRewrite: { |
| | | // '^/trans': '/' |
| | | // } |
| | | // })) |
| | | // } |
| | | app.use(proxy('/trans', { |
| | | target: `${host}/${service}`, |
| | | secure: false, |
| | | changeOrigin: true |
| | | })) |
| | | |
| | | app.use(proxy('/api', { // 旷视面板机接口测试 |
| | | target: `http://192.168.1.66:80`, |
| | | secure: false, |
| | | changeOrigin: true |
| | | })) |
| | | } |
| | |
| | | const NewPageButton = asyncComponent(() => import('@/tabviews/zshare/actionList/newpagebutton')) |
| | | const ChangeUserButton = asyncComponent(() => import('@/tabviews/zshare/actionList/changeuserbutton')) |
| | | const PrintButton = asyncComponent(() => import('@/tabviews/zshare/actionList/printbutton')) |
| | | const FuncMegvii = asyncComponent(() => import('@/tabviews/zshare/actionList/funcMegvii')) |
| | | const BarCode = asyncElementComponent(() => import('@/components/barcode')) |
| | | const QrCode = asyncElementComponent(() => import('@/components/qrcode')) |
| | | const MkProgress = asyncElementComponent(() => import('@/components/mkProgress')) |
| | |
| | | /> |
| | | </Col> |
| | | ) |
| | | } else if (card.funcType === 'megvii') { |
| | | return ( |
| | | <Col key={card.uuid} className="mk-cell-btn" style={card.wrapStyle} span={card.width}> |
| | | <FuncMegvii |
| | | BID={data.$$BID} |
| | | disabled={_disabled} |
| | | lineId={data.$$key || ''} |
| | | btn={card} |
| | | show={card.show} |
| | | style={card.style} |
| | | setting={cards.setting} |
| | | selectedData={_data} |
| | | /> |
| | | </Col> |
| | | ) |
| | | } |
| | | } |
| | | } |
| | |
| | | let photos = '' |
| | | if (record[col.field]) { |
| | | photos = `${record[col.field]}` |
| | | photos = photos.split(',') |
| | | } |
| | | |
| | | if (/^data:image/.test(photos)) { |
| | | photos = [photos] |
| | | } else { |
| | | photos = photos.split(',').filter(Boolean) |
| | | } |
| | | |
| | | let cols = 24 / (col.picSort || 1) |
| | |
| | | btn.verify.columns.forEach(op => { |
| | | let _name = typeof(header[op.Column]) === 'string' ? header[op.Column].replace(/(^\s*|\s*$)/g, '') : header[op.Column] |
| | | let _text = op.Text ? op.Text.replace(/(^\s*|\s*$)/g, '') : op.Text |
| | | |
| | | if (_name !== _text && !iserror) { |
| | | |
| | | if (!_name && !iserror) { |
| | | iserror = true |
| | | errors = 'headerError' |
| | | errDetail = `Excel中不存在(${_text})列!` |
| | | } else if (_name !== _text && !iserror) { |
| | | iserror = true |
| | | errors = 'headerError' |
| | | errDetail = `Excel中(${_name})与按钮列信息(${_text})不一致!` |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { withRouter } from 'react-router' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Button, Modal, notification, message } from 'antd' |
| | | import CryptoJS from 'crypto-js' |
| | | import moment from 'moment' |
| | | |
| | | import NApi from '@/api' |
| | | import Utils from '@/utils/utils.js' |
| | | import Api from '@/api/w4k.js' |
| | | import MKEmitter from '@/utils/events.js' |
| | | import MkIcon from '@/components/mk-icon' |
| | | |
| | | // import { mockdata } from './mock' |
| | | |
| | | import './index.scss' |
| | | |
| | | class FuncButton extends Component { |
| | | static propTpyes = { |
| | | btn: PropTypes.object, // 按钮 |
| | | disabled: PropTypes.any, // 行按钮禁用 |
| | | } |
| | | |
| | | state = { |
| | | loading: false, |
| | | disabled: false, |
| | | loadingNumber: '', |
| | | hidden: false, |
| | | IpList: [], |
| | | lines: [], |
| | | selectIp: {}, |
| | | visible: false |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | const { btn, selectedData } = this.props |
| | | let disabled = false |
| | | |
| | | if (btn.controlField && selectedData && selectedData.length > 0) { // 表格中按钮隐藏控制 |
| | | selectedData.forEach(item => { |
| | | let s = item[btn.controlField] !== undefined ? item[btn.controlField] + '' : '' |
| | | if (btn.controlVals.includes(s)) { |
| | | disabled = true |
| | | } |
| | | }) |
| | | this.setState({hidden: disabled && btn.control === 'hidden'}) |
| | | } |
| | | |
| | | if (this.props.disabled || disabled) { |
| | | this.setState({disabled: true}) |
| | | } |
| | | } |
| | | |
| | | componentDidMount () { |
| | | MKEmitter.addListener('triggerBtnId', this.actionTrigger) |
| | | } |
| | | |
| | | UNSAFE_componentWillReceiveProps (nextProps) { |
| | | const { btn, selectedData } = this.props |
| | | |
| | | let disabled = false |
| | | if (btn.controlField && !is(fromJS(nextProps.selectedData || []), fromJS(selectedData || []))) { |
| | | if (nextProps.selectedData && nextProps.selectedData.length > 0) { // 表格中按钮隐藏控制 |
| | | nextProps.selectedData.forEach(item => { |
| | | let s = item[btn.controlField] !== undefined ? item[btn.controlField] + '' : '' |
| | | if (btn.controlVals.includes(s)) { |
| | | disabled = true |
| | | } |
| | | }) |
| | | } |
| | | this.setState({hidden: disabled && btn.control === 'hidden'}) |
| | | } |
| | | |
| | | if (nextProps.disabled || disabled) { |
| | | this.setState({disabled: true}) |
| | | } else { |
| | | this.setState({disabled: false}) |
| | | } |
| | | } |
| | | |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | | return !is(fromJS(this.state), fromJS(nextState)) |
| | | } |
| | | |
| | | componentWillUnmount () { |
| | | this.setState = () => { |
| | | return |
| | | } |
| | | MKEmitter.removeListener('triggerBtnId', this.actionTrigger) |
| | | } |
| | | |
| | | /** |
| | | * @description 触发按钮操作 |
| | | */ |
| | | actionTrigger = (triggerId, record, type) => { |
| | | const { Tab, BID, btn, selectedData, setting } = this.props |
| | | const { loading, disabled } = this.state |
| | | |
| | | if (loading || disabled) return |
| | | if (triggerId) { |
| | | if (btn.uuid !== triggerId) return |
| | | if (this.props.lineId && record && record[0] && this.props.lineId !== record[0].$$key) { |
| | | return |
| | | } |
| | | } |
| | | |
| | | if (((Tab && Tab.supMenu) || setting.supModule) && !BID) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '需要上级主键值!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } else if (type === 'linkbtn' && selectedData && selectedData.length === 1) { |
| | | if (record[0].$Index !== selectedData[0].$Index) { |
| | | return |
| | | } |
| | | } |
| | | |
| | | let data = record || selectedData || [] |
| | | // let data = fromJS(mockdata.data).toJS() |
| | | |
| | | if (data.length === 0) { |
| | | // 需要选择行时,校验数据 |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '请选择行!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | this.setState({ |
| | | loading: true, |
| | | lines: data |
| | | }) |
| | | |
| | | this.getIpList() |
| | | } |
| | | |
| | | getIpList = () => { |
| | | let _scriptSql = `select ID,data_code,data_name,Remark,face_ip,face_uname,face_pwd from bd_data where typecharone='face_device' and deleted=0` |
| | | |
| | | _scriptSql = Utils.formatOptions(_scriptSql) |
| | | |
| | | let _sParam = { |
| | | func: 'sPC_Get_SelectedList', |
| | | LText: _scriptSql, |
| | | obj_name: 'data', |
| | | arr_field: 'ID,data_code,data_name,Remark,face_ip,face_uname,face_pwd' |
| | | } |
| | | |
| | | _sParam.timestamp = moment().format('YYYY-MM-DD HH:mm:ss') |
| | | _sParam.secretkey = Utils.encrypt(_sParam.LText, _sParam.timestamp) |
| | | |
| | | NApi.getSystemCacheConfig(_sParam).then(res => { |
| | | if (res.status) { |
| | | let IpList = res.data || [] |
| | | |
| | | if (IpList.length === 0) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '未获取到设备信息!', |
| | | duration: 5 |
| | | }) |
| | | this.setState({ |
| | | loading: false |
| | | }) |
| | | } else { |
| | | this.setState({ |
| | | IpList: IpList.map(item => { |
| | | if (item.face_ip) { |
| | | if (!/^http:/.test(item.face_ip)) { |
| | | item.face_ip = 'http://' + item.face_ip |
| | | } |
| | | if (!/:\d{2,4}$/.test(item.face_ip)) { |
| | | item.face_ip = item.face_ip + ':80' |
| | | } |
| | | } |
| | | return item |
| | | }), |
| | | selectIp: {}, |
| | | visible: true |
| | | }) |
| | | } |
| | | } else { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: res.message, |
| | | duration: 5 |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | loginDevice = () => { |
| | | const { lines, selectIp } = this.state |
| | | |
| | | // let ip = 'http://localhost:3001' |
| | | let ip = selectIp.face_ip |
| | | |
| | | Api.login(ip, selectIp.face_uname, selectIp.face_pwd).then(result => { |
| | | if (result.errors) { |
| | | this.execPreError(result) |
| | | return |
| | | } |
| | | |
| | | document.cookie = 'sessionID=' + result.session_id |
| | | |
| | | Api.queryUsers(ip).then(res => { |
| | | if (res.errors) { |
| | | this.execPreError(res) |
| | | return |
| | | } |
| | | |
| | | let persons = {} |
| | | res.data.forEach(item => { |
| | | persons[item.id] = true |
| | | }) |
| | | |
| | | let data = lines.map(cell => { |
| | | let item = {} |
| | | Object.keys(cell).forEach(key => { |
| | | item[key.toLowerCase()] = cell[key] |
| | | }) |
| | | |
| | | return { |
| | | deleted: persons[item.id] || false, |
| | | recognition_type: item.recognition_type || 'staff', |
| | | is_admin: item.is_admin === 'true', |
| | | person_name: item.person_name || '', |
| | | id: item.id || '', |
| | | card_number: item.card_number || '', |
| | | person_code: item.person_code || '', |
| | | group_list: item.group_list ? item.group_list.split(',') : [], |
| | | password: item.password || '', |
| | | id_number: item.id_number || '', |
| | | face_list: [{ |
| | | idx: item.face_idx || 0, |
| | | data: item.face_data ? item.face_data.replace(/^data:image\/(jpeg|png|jpg|gif);base64,/, '') : '', |
| | | }] |
| | | } |
| | | }) |
| | | |
| | | this.addUser(ip, data, result.session_id) |
| | | }) |
| | | }, err => { |
| | | this.execPreError(err) |
| | | }) |
| | | } |
| | | |
| | | addUser = (ip, datas, sessionId) => { |
| | | let data = datas.shift() |
| | | |
| | | this.setState({ |
| | | loadingNumber: datas.length || '' |
| | | }) |
| | | |
| | | let error = '' |
| | | if (!data.person_name) { |
| | | error = '人员名称不可为空' |
| | | } else if (!data.id) { |
| | | error = '人员id不可为空' |
| | | } else if (data.group_list.length === 0) { |
| | | error = '人员分组不可为空' |
| | | } else if (!data.face_list[0].data) { |
| | | error = '人员图片不可为空' |
| | | } else if (data.password) { |
| | | if (/^\d{6}$/.test(data.password)) { |
| | | let key = CryptoJS.enc.Utf8.parse(sessionId) |
| | | let srcs = CryptoJS.enc.Utf8.parse(data.password) |
| | | let encrypted = CryptoJS.AES.encrypt(srcs, key, {mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7}) |
| | | |
| | | data.password = CryptoJS.enc.Base64.stringify(encrypted.ciphertext) |
| | | } else { |
| | | error = '密码使用6位数字' |
| | | } |
| | | } |
| | | |
| | | if (error) { |
| | | this.execError({ErrCode: 'E', ErrMesg: error}) |
| | | return |
| | | } |
| | | |
| | | if (data.id_number) { |
| | | let key = CryptoJS.enc.Utf8.parse(sessionId) |
| | | let srcs = CryptoJS.enc.Utf8.parse(data.id_number) |
| | | let encrypted = CryptoJS.AES.encrypt(srcs, key, {mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7}) |
| | | |
| | | data.id_number = CryptoJS.enc.Base64.stringify(encrypted.ciphertext) |
| | | } |
| | | |
| | | Api.addUsers(ip, data).then(res => { |
| | | if (res.errors) { |
| | | this.execPreError(res, data) |
| | | return |
| | | } |
| | | if (datas.length > 0) { |
| | | this.addUser(ip, datas, sessionId) |
| | | } else { |
| | | this.execSuccess({ErrCode: 'S', ErrMesg: '执行成功。'}) |
| | | } |
| | | }, (err) => { |
| | | this.execPreError(err, data) |
| | | }) |
| | | } |
| | | |
| | | /** |
| | | * @description 操作成功后处理 |
| | | * 1、excel导出,成功后取消导出按钮加载中状态 |
| | | * 2、状态码为 S 时,显示成功信息后系统默认信息 |
| | | * 3、状态码为 -1 时,不显示任何信息 |
| | | * 4、模态框执行成功后是否关闭 |
| | | * 5、通知主列表刷新 |
| | | */ |
| | | execSuccess = (res) => { |
| | | const { btn } = this.props |
| | | |
| | | if (res && (res.ErrCode === 'S' || !res.ErrCode)) { // 执行成功 |
| | | notification.success({ |
| | | top: 92, |
| | | message: res.ErrMesg || '执行成功', |
| | | duration: btn.verify && btn.verify.stime ? btn.verify.stime : 2 |
| | | }) |
| | | } else if (res && res.ErrCode === 'Y') { // 执行成功 |
| | | Modal.success({ |
| | | title: res.ErrMesg || '执行成功' |
| | | }) |
| | | } else if (res && res.ErrCode === '-1') { // 完成后不提示 |
| | | |
| | | } |
| | | |
| | | this.setState({ |
| | | loading: false, |
| | | loadingNumber: '' |
| | | }) |
| | | |
| | | if (btn.execSuccess !== 'never') { |
| | | MKEmitter.emit('refreshByButtonResult', btn.$menuId, btn.execSuccess, btn) |
| | | } |
| | | } |
| | | |
| | | execPreError = (err, data) => { |
| | | if (err.data && err.data.errors && err.data.errors[0]) { |
| | | let error = err.data.errors[0] |
| | | let message = error.detail |
| | | if (error.source.pointer === '/api/persons/item' && error.error_code) { |
| | | let list = [ |
| | | {val: 1, msg: '图片格式错误'}, |
| | | {val: 2, msg: '图片大小超出限制'}, |
| | | {val: 3, msg: '图片分辨率超出限制'}, |
| | | {val: 16, msg: '人脸无特征值'}, |
| | | {val: 17, msg: '入库无图片'}, |
| | | {val: 18, msg: '未检测到人脸'}, |
| | | {val: 19, msg: '检测到多个人脸'}, |
| | | {val: 20, msg: '人脸太小'}, |
| | | {val: 21, msg: '图片太亮'}, |
| | | {val: 22, msg: '图片太暗'}, |
| | | {val: 23, msg: '人脸太模糊'}, |
| | | {val: 24, msg: '人脸方向错误'}, |
| | | {val: 32, msg: '数据库满'}, |
| | | {val: 33, msg: '人脸图片重复'}, |
| | | {val: 34, msg: '人员编号重复'}, |
| | | {val: 35, msg: '卡号重复'}, |
| | | {val: 48, msg: '人员名称重复'}, |
| | | {val: -1, msg: '未知错误'}, |
| | | {val: -2141716476, msg: '系统参数错误,有可能是人员组不存在。'}, |
| | | ] |
| | | |
| | | list.forEach(item => { |
| | | if (item.val === error.error_code) { |
| | | message = (data ? data.person_name + ' - ' : '') + item.msg |
| | | } |
| | | }) |
| | | } |
| | | |
| | | this.execError({ |
| | | ErrCode: 'E', |
| | | message: message |
| | | }) |
| | | } else { |
| | | this.execError({ |
| | | ErrCode: 'E', |
| | | message: '请检查设备状态!' |
| | | }) |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @description 操作失败后处理 |
| | | */ |
| | | execError = (res) => { |
| | | const { btn } = this.props |
| | | |
| | | if (res.ErrCode === 'E') { |
| | | Modal.error({ |
| | | title: res.message || res.ErrMesg, |
| | | }) |
| | | } else if (res.ErrCode === 'N') { |
| | | notification.error({ |
| | | top: 92, |
| | | message: res.message || res.ErrMesg, |
| | | duration: btn.verify && btn.verify.ntime ? btn.verify.ntime : 10 |
| | | }) |
| | | } else if (res.ErrCode === 'F') { |
| | | notification.error({ |
| | | className: 'notification-custom-error', |
| | | top: 92, |
| | | message: res.message || res.ErrMesg, |
| | | duration: btn.verify && btn.verify.ftime ? btn.verify.ftime : 10 |
| | | }) |
| | | } else if (res.ErrCode === 'NM') { |
| | | message.error(res.message || res.ErrMesg) |
| | | } |
| | | |
| | | this.setState({ |
| | | loading: false, |
| | | loadingNumber: '' |
| | | }) |
| | | |
| | | if (btn.execError !== 'never') { |
| | | MKEmitter.emit('refreshByButtonResult', btn.$menuId, btn.execError, btn) |
| | | } |
| | | } |
| | | |
| | | handleOk = () => { |
| | | const { selectIp } = this.state |
| | | |
| | | if (!selectIp.ID) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '请选择面板机!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } else if (!selectIp.face_ip) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '面板机IP缺失!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } else if (!selectIp.face_uname) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '面板机用户名缺失!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } else if (!selectIp.face_pwd) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '面板机密码缺失!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | this.setState({ |
| | | visible: false |
| | | }) |
| | | |
| | | this.loginDevice() |
| | | } |
| | | |
| | | getModels = () => { |
| | | const { IpList, visible, selectIp } = this.state |
| | | |
| | | return ( |
| | | <Modal |
| | | title="请选择面板机" |
| | | maskClosable={false} |
| | | getContainer={document.body} |
| | | wrapClassName='ip-list-modal' |
| | | visible={visible} |
| | | width={700} |
| | | onOk={this.handleOk} |
| | | onCancel={() => this.setState({visible: false, loading: false})} |
| | | destroyOnClose |
| | | > |
| | | {IpList.map(item => { |
| | | return <div className={'ip-item' + (selectIp.ID === item.ID ? ' active' : '')} key={item.ID} onClick={() => {this.setState({selectIp: item})}}> |
| | | <div className="ip">IP:{item.face_ip}</div> |
| | | <div className="user">用户:{item.face_uname}</div> |
| | | <div className="remark">备注:{item.Remark}</div> |
| | | </div> |
| | | })} |
| | | </Modal> |
| | | ) |
| | | } |
| | | |
| | | render() { |
| | | const { btn, show } = this.props |
| | | const { loading, disabled, hidden, loadingNumber } = this.state |
| | | |
| | | if (hidden) return null |
| | | |
| | | if (show === 'actionList') { |
| | | return ( |
| | | <> |
| | | <Button |
| | | icon={btn.icon} |
| | | loading={loading} |
| | | disabled={disabled} |
| | | title={disabled ? (btn.reason || '') : ''} |
| | | className={'mk-btn mk-' + btn.class} |
| | | onClick={(e) => {e.stopPropagation(); this.actionTrigger()}} |
| | | >{(loadingNumber ? `(${loadingNumber})` : '') + btn.label}</Button> |
| | | {this.getModels()} |
| | | </> |
| | | ) |
| | | } else { // icon、text、 all 卡片 |
| | | let label = '' |
| | | let icon = '' |
| | | |
| | | if (show === 'button') { |
| | | label = btn.label |
| | | icon = btn.icon || '' |
| | | } else if (show === 'link') { |
| | | label = <span>{btn.label}{btn.icon ? <MkIcon style={{marginLeft: '8px'}} type={btn.icon}/> : ''}</span> |
| | | icon = '' |
| | | } else if (show === 'icon') { |
| | | icon = btn.icon || '' |
| | | } else { |
| | | label = btn.label |
| | | } |
| | | |
| | | return ( |
| | | <> |
| | | <Button |
| | | type="link" |
| | | title={disabled ? (btn.reason || '') : (show === 'icon' ? btn.label : '')} |
| | | loading={loading} |
| | | disabled={disabled} |
| | | style={btn.style} |
| | | icon={icon} |
| | | onClick={(e) => {e.stopPropagation(); this.actionTrigger()}} |
| | | >{label}</Button> |
| | | {this.getModels()} |
| | | </> |
| | | ) |
| | | } |
| | | } |
| | | } |
| | | |
| | | export default withRouter(FuncButton) |
New file |
| | |
| | | .ip-list-modal { |
| | | .ip-item { |
| | | display: inline-block; |
| | | border: 1px solid #d9d9d9; |
| | | padding: 10px; |
| | | height: 100px; |
| | | width: calc(33% - 20px); |
| | | margin: 10px; |
| | | cursor: pointer; |
| | | .ip { |
| | | color: #000000; |
| | | } |
| | | .remark { |
| | | word-break: break-all; |
| | | text-overflow: ellipsis; |
| | | display: -webkit-box; |
| | | -webkit-box-orient: vertical; |
| | | -webkit-line-clamp: 2; |
| | | overflow: hidden; |
| | | } |
| | | } |
| | | .ip-item.active { |
| | | border-color: var(--antd-wave-shadow-color); |
| | | box-shadow: 0 0 2px var(--antd-wave-shadow-color); |
| | | } |
| | | } |
New file |
| | |
| | | export const mockdata = { |
| | | data: [ |
| | | { |
| | | "recognition_type": "staff", |
| | | "id": "2226169", |
| | | "type": "persons", |
| | | "is_admin": "true", |
| | | "person_name": "king", |
| | | "card_number": "mk001", |
| | | "person_code": "2018", |
| | | "id_number": "130982193002054729", |
| | | "group_list": "1", |
| | | "face_data":"" |
| | | }, |
| | | { |
| | | "recognition_type": "staff", |
| | | "id": "3272487", |
| | | "is_admin": 'false', |
| | | "person_name": "jinfei", |
| | | "card_number": "mk002", |
| | | "person_code": "02", |
| | | "id_number": "", |
| | | "group_list": "1", |
| | | "face_data": "" |
| | | } |
| | | ] |
| | | } |
| | |
| | | const NewPageButton = asyncComponent(() => import('./newpagebutton')) |
| | | const ChangeUserButton = asyncComponent(() => import('./changeuserbutton')) |
| | | const PrintButton = asyncComponent(() => import('./printbutton')) |
| | | const FuncMegvii = asyncComponent(() => import('./funcMegvii')) |
| | | |
| | | class ActionList extends Component { |
| | | static propTpyes = { |
| | |
| | | |
| | | getButtonList = (actions) => { |
| | | const { BID, BData, MenuID, Tab, columns, setting, ContainerId, selectedData, lock } = this.props |
| | | |
| | | return actions.map(item => { |
| | | if (['exec', 'prompt', 'pop'].includes(item.OpenType)) { |
| | | return ( |
| | |
| | | return ( |
| | | <NewPageButton |
| | | key={item.uuid} |
| | | show="actionList" |
| | | show={item.show || 'actionList'} |
| | | disabled={lock || false} |
| | | btn={item} |
| | | BData={BData} |
| | |
| | | selectedData={selectedData} |
| | | /> |
| | | ) |
| | | } else if (item.funcType === 'megvii') { |
| | | return ( |
| | | <FuncMegvii |
| | | key={item.uuid} |
| | | show={item.show || 'actionList'} |
| | | disabled={lock || false} |
| | | BID={BID} |
| | | Tab={Tab} |
| | | btn={item} |
| | | setting={setting} |
| | | selectedData={selectedData} |
| | | /> |
| | | ) |
| | | } |
| | | } |
| | | return null |
| | |
| | | |
| | | let filelist = [] |
| | | if (config.initval) { |
| | | try { |
| | | filelist = config.initval.split(',').map((url, index) => { |
| | | return { |
| | | uid: `${index}`, |
| | | name: url.slice(url.lastIndexOf('/') + 1), |
| | | status: 'done', |
| | | url: url, |
| | | origin: true |
| | | } |
| | | }) |
| | | } catch (e) { |
| | | filelist = [] |
| | | if (/^data:image/.test(config.initval)) { |
| | | filelist = [{ |
| | | uid: '0', |
| | | name: 'data:image/jpeg;base64', |
| | | status: 'done', |
| | | url: config.initval, |
| | | origin: true |
| | | }] |
| | | } else { |
| | | try { |
| | | filelist = config.initval.split(',').map((url, index) => { |
| | | return { |
| | | uid: `${index}`, |
| | | name: url.slice(url.lastIndexOf('/') + 1), |
| | | status: 'done', |
| | | url: url, |
| | | origin: true |
| | | } |
| | | }) |
| | | } catch (e) { |
| | | filelist = [] |
| | | } |
| | | } |
| | | } |
| | | |
| | | let accept = '' |
| | | let accepts = null |
| | | let compress = false |
| | | if (config.compress === 'true') { |
| | | let maxFile = config.maxfile && config.maxfile > 0 ? config.maxfile : null |
| | | if (config.compress === 'true' || config.compress === 'base64') { |
| | | compress = true |
| | | accepts = ['.jpg', '.png', '.gif', '.jpeg'] |
| | | accept = accepts.join(',') |
| | | if (config.compress === 'base64') { |
| | | maxFile = 1 |
| | | } |
| | | } else if (config.suffix) { |
| | | accepts = config.suffix.split(',').map(item => { |
| | | if (!/^\./ig.test(item)) { |
| | |
| | | filelist, |
| | | compress, |
| | | limit: config.limit || 2, |
| | | maxFile: config.maxfile && config.maxfile > 0 ? config.maxfile : null, |
| | | maxFile: maxFile, |
| | | fileType: config.fileType || 'text' |
| | | }) |
| | | } |
| | |
| | | |
| | | let param = {Base64Img: cvs.toDataURL('image/jpeg', compressRate)} |
| | | |
| | | if (rduri) { |
| | | param.rduri = rduri |
| | | } |
| | | |
| | | Api.fileuploadbase64(param).then(result => { |
| | | if (result.status && result.Images) { |
| | | let url = service + result.Images |
| | | |
| | | if (rduri) { |
| | | url = rduri.replace(/webapi(.*)$/, '') + result.Images |
| | | } |
| | | |
| | | this.onUpdate(url) |
| | | |
| | | this.setState({ |
| | | percent: 100 |
| | | }, () => { |
| | | setTimeout(() => { |
| | | this.setState({ |
| | | showprogress: false, |
| | | percent: 0 |
| | | }) |
| | | }, 200) |
| | | }) |
| | | } else { |
| | | this.onFail(result.message) |
| | | if (this.props.config.compress === 'base64') { |
| | | this.onUpdate(param.Base64Img) |
| | | |
| | | this.setState({ |
| | | percent: 100 |
| | | }, () => { |
| | | setTimeout(() => { |
| | | this.setState({ |
| | | showprogress: false, |
| | | percent: 0 |
| | | }) |
| | | }, 200) |
| | | }) |
| | | } else { |
| | | if (rduri) { |
| | | param.rduri = rduri |
| | | } |
| | | }) |
| | | |
| | | Api.fileuploadbase64(param).then(result => { |
| | | if (result.status && result.Images) { |
| | | let url = service + result.Images |
| | | |
| | | if (rduri) { |
| | | url = rduri.replace(/webapi(.*)$/, '') + result.Images |
| | | } |
| | | |
| | | this.onUpdate(url) |
| | | |
| | | this.setState({ |
| | | percent: 100 |
| | | }, () => { |
| | | setTimeout(() => { |
| | | this.setState({ |
| | | showprogress: false, |
| | | percent: 0 |
| | | }) |
| | | }, 200) |
| | | }) |
| | | } else { |
| | | this.onFail(result.message) |
| | | } |
| | | }) |
| | | } |
| | | } |
| | | |
| | | img.onerror = () => { |
| | |
| | | let photos = '' |
| | | if (item.field && record.hasOwnProperty(item.field)) { |
| | | photos = record[item.field] + '' |
| | | photos = photos.split(',').filter(Boolean) |
| | | } |
| | | if (/^data:image/.test(photos)) { |
| | | photos = [photos] |
| | | } else { |
| | | photos = '' |
| | | photos = photos.split(',').filter(Boolean) |
| | | } |
| | | |
| | | let maxHeight = item.maxHeight || 128 |
| | |
| | | let photos = [] |
| | | try { |
| | | photos = record[col.field] + '' |
| | | photos = photos.split(',').filter(Boolean) |
| | | |
| | | if (/^data:image/.test(photos)) { |
| | | photos = [photos] |
| | | } else { |
| | | photos = photos.split(',').filter(Boolean) |
| | | } |
| | | } catch (e) { |
| | | photos = [] |
| | | } |
| | |
| | | } |
| | | } else if (_funcType === 'closetab') { |
| | | shows.push('refreshTab') |
| | | } else if (_funcType === 'megvii') { |
| | | shows.push('subFunc') |
| | | } |
| | | } |
| | | |
| | |
| | | } |
| | | } else if (card.funcType === 'print') { |
| | | hasProfile = true |
| | | } else if (card.funcType === 'megvii') { |
| | | hasProfile = true |
| | | } |
| | | |
| | | return ( |
| | |
| | | const VerifyCard = asyncSpinComponent(() => import('@/templates/zshare/verifycard')) |
| | | const VerifyPrint = asyncSpinComponent(() => import('@/templates/sharecomponent/actioncomponent/verifyprint')) |
| | | const VerifyExcelIn = asyncSpinComponent(() => import('@/templates/sharecomponent/actioncomponent/verifyexcelin')) |
| | | const VerifyMegvii = asyncSpinComponent(() => import('@/templates/sharecomponent/actioncomponent/verifymegvii')) |
| | | const VerifyExcelOut = asyncSpinComponent(() => import('@/templates/sharecomponent/actioncomponent/verifyexcelout')) |
| | | |
| | | class ActionComponent extends Component { |
| | |
| | | MKEmitter.removeListener('pasteButton', this.pasteButton) |
| | | } |
| | | |
| | | getVerify = (card) => { |
| | | const { config } = this.props |
| | | const { dict } = this.state |
| | | |
| | | if (!card) return null |
| | | |
| | | if (['pop', 'prompt', 'exec'].includes(card.OpenType)) { |
| | | return <VerifyCard |
| | | card={card} |
| | | dict={dict} |
| | | config={config} |
| | | columns={config.columns} |
| | | wrappedComponentRef={(inst) => this.verifyRef = inst} |
| | | /> |
| | | } else if (card.OpenType === 'excelIn') { |
| | | return <VerifyExcelIn |
| | | card={card} |
| | | dict={dict} |
| | | columns={config.columns} |
| | | wrappedComponentRef={(inst) => this.verifyRef = inst} |
| | | /> |
| | | } else if (card.OpenType === 'excelOut') { |
| | | return <VerifyExcelOut |
| | | card={card} |
| | | dict={dict} |
| | | config={config} |
| | | wrappedComponentRef={(inst) => this.verifyRef = inst} |
| | | /> |
| | | } else if (card.OpenType === 'funcbutton' && card.funcType === 'print') { |
| | | return <VerifyPrint |
| | | card={card} |
| | | dict={dict} |
| | | columns={config.columns} |
| | | wrappedComponentRef={(inst) => this.verifyRef = inst} |
| | | /> |
| | | } else if (card.OpenType === 'funcbutton' && card.funcType === 'megvii') { |
| | | return <VerifyMegvii |
| | | card={card} |
| | | dict={dict} |
| | | columns={config.columns} |
| | | wrappedComponentRef={(inst) => this.verifyRef = inst} |
| | | /> |
| | | } |
| | | } |
| | | |
| | | render() { |
| | | const { config } = this.props |
| | | const { actionlist, visible, card, dict, copying, profVisible } = this.state |
| | |
| | | }} |
| | | destroyOnClose |
| | | > |
| | | {card && !card.execMode && card.OpenType !== 'excelIn' && card.OpenType !== 'excelOut' ? |
| | | <VerifyCard |
| | | card={card} |
| | | dict={dict} |
| | | config={config} |
| | | columns={config.columns} |
| | | wrappedComponentRef={(inst) => this.verifyRef = inst} |
| | | /> : null |
| | | } |
| | | {card && card.execMode ? |
| | | <VerifyPrint |
| | | card={card} |
| | | dict={dict} |
| | | columns={config.columns} |
| | | wrappedComponentRef={(inst) => this.verifyRef = inst} |
| | | /> : null |
| | | } |
| | | {card && card.OpenType === 'excelIn' ? |
| | | <VerifyExcelIn |
| | | card={card} |
| | | dict={dict} |
| | | columns={config.columns} |
| | | wrappedComponentRef={(inst) => this.verifyRef = inst} |
| | | /> : null |
| | | } |
| | | {card && card.OpenType === 'excelOut' ? |
| | | <VerifyExcelOut |
| | | card={card} |
| | | dict={dict} |
| | | config={config} |
| | | wrappedComponentRef={(inst) => this.verifyRef = inst} |
| | | /> : null |
| | | } |
| | | {this.getVerify(card)} |
| | | </Modal> |
| | | </div> |
| | | ) |
New file |
| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { fromJS } from 'immutable' |
| | | import { Form, Tabs, Table, Row, Col, Button, notification, Modal, message, InputNumber } from 'antd' |
| | | |
| | | import './index.scss' |
| | | |
| | | const { TabPane } = Tabs |
| | | |
| | | class MegviiCard extends Component { |
| | | static propTpyes = { |
| | | columns: PropTypes.array, // 显示列 |
| | | dict: PropTypes.object, // 字典项 |
| | | card: PropTypes.object, |
| | | } |
| | | |
| | | state = { |
| | | verify: {}, |
| | | activeKey: 'excelcolumn', |
| | | excelColumns: [ |
| | | { |
| | | title: '名称', |
| | | dataIndex: 'field', |
| | | width: '20%' |
| | | }, |
| | | { |
| | | title: '数据类型', |
| | | dataIndex: 'datatype', |
| | | width: '20%' |
| | | }, |
| | | { |
| | | title: '变量类型', |
| | | dataIndex: 'type', |
| | | width: '20%' |
| | | }, |
| | | { |
| | | title: '是否必须', |
| | | dataIndex: 'required', |
| | | width: '15%' |
| | | }, |
| | | { |
| | | title: '备注', |
| | | dataIndex: 'remark', |
| | | width: '25%', |
| | | } |
| | | ], |
| | | excelData: [ |
| | | {field: 'id', datatype: 'string', type: 'nvarchar(50)', required: '必须', remark: '人员id'}, |
| | | {field: 'person_name', datatype: 'string', type: 'nvarchar(50)', required: '必须', remark: '人员名称'}, |
| | | {field: 'group_list', datatype: 'string', type: 'nvarchar(50)', required: '必须', remark: '绑定人员组的列表,多个使用逗号分隔,示例:\'1,2\''}, |
| | | {field: 'face_data', datatype: 'string', type: 'text', required: '必须', remark: 'Base64编码的照片数据(人脸信息)'}, |
| | | {field: 'face_idx', datatype: 'integer', type: 'int', required: '非必须', remark: '照片索引,默认为0'}, |
| | | {field: 'is_admin', datatype: 'string', type: 'nvarchar(50)', required: '非必须', remark: '是否启用管理员权限,默认为\'false\''}, |
| | | {field: 'recognition_type', datatype: 'string', type: 'nvarchar(50)', required: '非必须', remark: '人员类型,staff – 普通人员(默认),visitor – 访客,blacklist – 黑名单'}, |
| | | {field: 'password', datatype: 'string', type: 'nvarchar(50)', required: '非必须', remark: '密码使用6位数字(AES加密)'}, |
| | | {field: 'id_number', datatype: 'string', type: 'nvarchar(50)', required: '非必须', remark: '身份证号码(AES加密)'}, |
| | | {field: 'person_code', datatype: 'string', type: 'nvarchar(50)', required: '非必须', remark: '人员编号'}, |
| | | {field: 'card_number', datatype: 'string', type: 'nvarchar(50)', required: '非必须', remark: '卡号,最大20位数字'}, |
| | | ] |
| | | } |
| | | |
| | | UNSAFE_componentWillMount() { |
| | | const { card } = this.props |
| | | let _verify = fromJS(card.verify || {}).toJS() |
| | | |
| | | this.setState({ |
| | | verify: _verify |
| | | }) |
| | | } |
| | | |
| | | componentDidMount () { |
| | | |
| | | } |
| | | |
| | | handleConfirm = () => { |
| | | const { verify } = this.state |
| | | |
| | | return Promise.resolve(verify) |
| | | } |
| | | |
| | | showError = (errorType) => { |
| | | if (errorType === 'S') { |
| | | notification.success({ |
| | | top: 92, |
| | | message: '执行成功!', |
| | | duration: 2 |
| | | }) |
| | | } else if (errorType === 'Y') { |
| | | Modal.success({ |
| | | title: '执行成功!' |
| | | }) |
| | | } else if (errorType === 'F') { |
| | | notification.error({ |
| | | className: 'notification-custom-error', |
| | | top: 92, |
| | | message: '执行失败!', |
| | | duration: 10 |
| | | }) |
| | | } else if (errorType === 'N') { |
| | | notification.error({ |
| | | top: 92, |
| | | message: '执行失败!', |
| | | duration: 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} |
| | | }) |
| | | } |
| | | |
| | | tabchange = (val) => { |
| | | this.setState({activeKey: val}) |
| | | } |
| | | |
| | | render() { |
| | | const { verify, excelColumns, excelData, activeKey } = this.state |
| | | const formItemLayout = { |
| | | labelCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 8 } |
| | | }, |
| | | wrapperCol: { |
| | | xs: { span: 24 }, |
| | | sm: { span: 16 } |
| | | } |
| | | } |
| | | |
| | | return ( |
| | | <div> |
| | | <Tabs activeKey={activeKey} className="megvii-verify-card-box" onChange={this.tabchange}> |
| | | <TabPane tab={ |
| | | <span> |
| | | 列设置 |
| | | </span> |
| | | } key="excelcolumn"> |
| | | <Table |
| | | bordered |
| | | rowKey="field" |
| | | className="custom-table" |
| | | dataSource={excelData} |
| | | columns={excelColumns} |
| | | pagination={false} |
| | | /> |
| | | </TabPane> |
| | | <TabPane tab="信息提示" key="tip"> |
| | | <Form {...formItemLayout}> |
| | | <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"> 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"> -1 </span> |
| | | 不提示 |
| | | </Form.Item> |
| | | </Col> |
| | | </Row> |
| | | </Form> |
| | | </TabPane> |
| | | </Tabs> |
| | | </div> |
| | | ) |
| | | } |
| | | } |
| | | |
| | | export default Form.create()(MegviiCard) |
New file |
| | |
| | | .megvii-verify-card-box { |
| | | .ant-tabs-nav-scroll { |
| | | text-align: center; |
| | | } |
| | | .ant-tabs-content { |
| | | min-height: 40vh; |
| | | } |
| | | table tr td { |
| | | word-wrap: break-word; |
| | | word-break: break-word; |
| | | } |
| | | |
| | | .excel-custom-table { |
| | | position: relative; |
| | | top: -25px; |
| | | } |
| | | .errorval { |
| | | display: inline-block; |
| | | width: 30px; |
| | | } |
| | | .operation-btn { |
| | | display: inline-block; |
| | | font-size: 16px; |
| | | padding: 0 5px; |
| | | cursor: pointer; |
| | | } |
| | | .ant-tabs-tabpane { |
| | | position: relative; |
| | | .excel-col-add { |
| | | position: relative; |
| | | float: right; |
| | | right: -9px; |
| | | margin-right: 10px; |
| | | top: 10px; |
| | | z-index: 1; |
| | | } |
| | | } |
| | | } |
| | |
| | | }, { |
| | | value: 'closetab', |
| | | text: '标签关闭' |
| | | }, { |
| | | value: 'megvii', |
| | | text: '旷视面板机' |
| | | }] |
| | | }, |
| | | { // 旷视面板机接口 待扩展 |
| | | type: 'radio', |
| | | key: 'subFunc', |
| | | label: '接口名称', |
| | | initVal: card.subFunc || 'addUser', |
| | | required: true, |
| | | options: [ |
| | | { value: 'addUser', text: '添加用户' }, |
| | | ] |
| | | }, |
| | | { |
| | | type: 'select', |
| | |
| | | { |
| | | type: 'radio', |
| | | key: 'compress', |
| | | label: '压缩', |
| | | label: '文件处理', |
| | | initVal: card.compress || 'false', |
| | | tooltip: '文件压缩必须为图片,图片格式为jpg、png、gif 或 jpeg', |
| | | tooltip: '文件压缩或base64必须为图片,图片格式为jpg、png、gif 或 jpeg。注:base64只可上传一张图片。', |
| | | options: [{ |
| | | value: 'true', |
| | | text: Formdict['model.true'] |
| | | }, { |
| | | value: 'false', |
| | | text: Formdict['model.false'] |
| | | text: '无' |
| | | }, { |
| | | value: 'true', |
| | | text: '压缩' |
| | | }, { |
| | | value: 'base64', |
| | | text: 'base64' |
| | | }] |
| | | }, |
| | | { |
| | |
| | | } |
| | | |
| | | saveTree = () => { |
| | | const { trees } = this.state |
| | | // const { trees } = this.state |
| | | const _this = this |
| | | |
| | | if (!trees || trees.length === 0) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '未获取到权限信息!', |
| | | duration: 5 |
| | | }) |
| | | return |
| | | } |
| | | // if (!trees || trees.length === 0) { |
| | | // notification.warning({ |
| | | // top: 92, |
| | | // message: '未获取到权限信息!', |
| | | // duration: 5 |
| | | // }) |
| | | // return |
| | | // } |
| | | |
| | | confirm({ |
| | | content: '确定执行吗?', |