import React, {Component} from 'react'
|
import PropTypes from 'prop-types'
|
import { is, fromJS } from 'immutable'
|
import { Button, Modal, notification, message } from 'antd'
|
import JSZip from 'jszip'
|
import { saveAs } from 'file-saver'
|
|
import Utils from '@/utils/utils.js'
|
import Api from '@/api'
|
import MKEmitter from '@/utils/events.js'
|
import MkIcon from '@/components/mk-icon'
|
|
// import './index.scss'
|
|
class FuncZip extends Component {
|
static propTpyes = {
|
btn: PropTypes.object, // 按钮
|
disabled: PropTypes.any, // 行按钮禁用
|
}
|
|
state = {
|
loading: false,
|
disabled: false,
|
hidden: false,
|
dict: window.GLOB.dict
|
}
|
|
UNSAFE_componentWillMount () {
|
const { btn, selectedData, BData, disabled } = this.props
|
|
if (btn.controlField) {
|
this.setStatus(btn, selectedData || [], BData, disabled)
|
} else if (disabled) {
|
this.setState({disabled: true})
|
}
|
}
|
|
componentDidMount () {
|
MKEmitter.addListener('triggerBtnId', this.actionTrigger)
|
}
|
|
UNSAFE_componentWillReceiveProps (nextProps) {
|
const { btn } = this.props
|
|
if (btn.controlField) {
|
this.setStatus(btn, nextProps.selectedData || [], nextProps.BData, nextProps.disabled)
|
} else {
|
this.setState({disabled: nextProps.disabled === true})
|
}
|
}
|
|
shouldComponentUpdate (nextProps, nextState) {
|
return !is(fromJS(this.state), fromJS(nextState))
|
}
|
|
componentWillUnmount () {
|
this.setState = () => {
|
return
|
}
|
MKEmitter.removeListener('triggerBtnId', this.actionTrigger)
|
}
|
|
setStatus = (btn, data, BData, disprop) => {
|
let disabled = false
|
let hidden = false
|
|
if (btn.control !== 'parent') {
|
if (data.length > 0) {
|
data.forEach(item => {
|
let s = item[btn.controlField] !== undefined ? item[btn.controlField] + '' : ''
|
if (btn.controlVals.includes(s)) {
|
disabled = true
|
}
|
})
|
} else if (btn.controlVals.includes('')) {
|
disabled = true
|
}
|
} else {
|
if (!BData || !BData.hasOwnProperty(btn.controlField)) {
|
hidden = true
|
} else {
|
let s = BData[btn.controlField] + ''
|
if (btn.controlVals.includes(s)) {
|
hidden = true
|
}
|
}
|
}
|
|
if (disabled && btn.control === 'hidden') {
|
hidden = true
|
}
|
|
if (disprop) {
|
disabled = true
|
}
|
|
this.setState({hidden, disabled})
|
}
|
|
/**
|
* @description 触发按钮操作
|
*/
|
actionTrigger = (triggerId, record, type, lid) => {
|
const { BID, btn, selectedData, setting, LID } = this.props
|
const { loading, disabled, dict } = this.state
|
|
if (loading || disabled) return
|
if (triggerId && btn.uuid !== triggerId) return
|
if (type === 'linkbtn' && !btn.$toolbtn && LID !== lid) return
|
|
let data = record || selectedData || []
|
|
if (setting.supModule && !BID) {
|
notification.warning({
|
top: 92,
|
message: setting.supModTip || dict['sup_key_req'] || '需要上级主键值!',
|
duration: 5
|
})
|
return
|
} else if (btn.Ot !== 'notRequired' && data.length === 0) {
|
notification.warning({
|
top: 92,
|
message: dict['select_row'] || '请选择行!',
|
duration: 5
|
})
|
return
|
} else if (btn.Ot === 'requiredSgl' && data.length !== 1) {
|
notification.warning({
|
top: 92,
|
message: dict['select_single_row'] || '请选择单行数据!',
|
duration: 5
|
})
|
return
|
}
|
|
this.setState({
|
loading: true
|
})
|
|
if (btn.innerFunc) {
|
let params = []
|
let param = {
|
func: btn.innerFunc,
|
BID: BID || ''
|
}
|
|
if (btn.Ot === 'notRequired') {
|
params.push(param)
|
} else if (btn.Ot === 'requiredSgl') {
|
param.ID = data[0].$$uuid || ''
|
params.push(param)
|
} else if (btn.Ot === 'required') {
|
params = data.map(item => {
|
return {
|
...param,
|
ID: item.$$uuid || ''
|
}
|
})
|
} else if (btn.Ot === 'requiredOnce') {
|
param.ID = data.map(item => item.$$uuid || '').filter(Boolean).join(',')
|
params.push(param)
|
}
|
|
this.getInnerData(params)
|
} else {
|
this.downloadZipImage(data, btn.urlkey).then((res) => {
|
if (res) {
|
this.execError({ErrCode: res})
|
} else {
|
this.execSuccess()
|
}
|
}, (err) => {
|
this.execError({ErrCode: err})
|
})
|
}
|
}
|
|
getInnerData = (params) => {
|
let param = params.shift()
|
|
Api.genericInterface(param).then(res => {
|
if (res.status) {
|
this.downloadZipImage(res.data, this.props.btn.urlkey).then((res) => {
|
if (params.length === 0) {
|
if (res) {
|
this.execError({ErrCode: res})
|
} else {
|
this.execSuccess()
|
}
|
} else {
|
this.getInnerData(params)
|
}
|
}, (err) => {
|
if (params.length === 0) {
|
this.execError({ErrCode: err})
|
} else {
|
this.getInnerData(params)
|
}
|
})
|
} else {
|
this.execError(res)
|
}
|
})
|
}
|
|
downloadZipImage = (imgArr, imgKey = '') => {
|
let images = []
|
if (imgArr && imgArr.length > 0) {
|
let names = []
|
let imgs = []
|
imgArr.forEach(item => {
|
let itemImg = imgKey ? item[imgKey] : item
|
|
if (!itemImg || !/^data:image|jpg$|jpeg$|png$|gif$/.test(itemImg)) return
|
if (imgs.includes(itemImg)) return
|
|
let name = Utils.getguid() + '.png'
|
|
if (/.(jpg|jpeg|png|gif)$/.test(itemImg)) {
|
let _name = itemImg.replace(/.*\//ig, '')
|
if (!names.includes(_name)) {
|
name = _name
|
}
|
}
|
|
imgs.push(itemImg)
|
names.push(name)
|
|
images.push({url: itemImg, name: name})
|
})
|
}
|
|
if (images.length === 0) {
|
return Promise.reject('01')
|
}
|
|
const zip = new JSZip()
|
const imgFolder = zip.folder('images') // 创建images文件夹
|
|
return new Promise((resolve, reject) => {
|
let deffers = images.map((img) => {
|
return new Promise(resolve => {
|
this.getBase64(img.url).then((base64) => {
|
if (base64) {
|
base64 = base64.split('base64,')[1]
|
imgFolder.file(img.name, base64, {
|
base64: true
|
})
|
resolve(true)
|
} else {
|
resolve(false)
|
}
|
})
|
})
|
})
|
|
Promise.all(deffers).then((res) => {
|
let hasSuccess = res.filter((m) => m).length > 0
|
let hasError = res.filter((m) => !m).length > 0
|
|
if (hasSuccess) {
|
zip.generateAsync({
|
type: 'blob'
|
}).then((blob) => {
|
saveAs(blob, Utils.getguid() + '.zip')
|
if (hasError) {
|
resolve('02')
|
} else {
|
resolve('')
|
}
|
})
|
} else {
|
reject('03')
|
}
|
})
|
})
|
}
|
|
/**
|
* 将图片转换成base64 并返回路径
|
* @param img
|
* @param {number} width 调用时传入具体像素值,控制大小 ,不传则默认图像大小
|
* @param {number} height
|
* @returns {string}
|
*/
|
getBase64Image = (img, width = 0, height = 0) => {
|
const canvas = document.createElement('canvas')
|
canvas.width = width ? width : img.width
|
canvas.height = height ? height : img.height
|
|
const ctx = canvas.getContext('2d')
|
ctx.drawImage(img, 0, 0, canvas.width, canvas.height)
|
const dataURL = canvas.toDataURL()
|
return dataURL
|
}
|
|
/**
|
* 加载图片 加载成功后经图片返回
|
* @param img
|
* @returns {Promise<any>}
|
*/
|
getBase64 = (img) => {
|
if (/^data:image/.test(img)) {
|
return Promise.resolve(img)
|
} else {
|
const image = new Image()
|
image.crossOrigin = '*'
|
image.src = img
|
return new Promise((resolve, reject) => {
|
image.onload = () => {
|
let base64 = ''
|
try {
|
base64 = this.getBase64Image(image)
|
} catch (e) {
|
base64 = ''
|
}
|
resolve(base64)
|
}
|
image.onerror = () => {
|
resolve('')
|
}
|
})
|
}
|
}
|
|
/**
|
* @description 操作成功后处理
|
* 1、excel导出,成功后取消导出按钮加载中状态
|
* 2、状态码为 S 时,显示成功信息后系统默认信息
|
* 3、状态码为 -1 时,不显示任何信息
|
* 4、模态框执行成功后是否关闭
|
* 5、通知主列表刷新
|
*/
|
execSuccess = () => {
|
const { btn } = this.props
|
|
this.setState({
|
loading: false
|
})
|
|
if (btn.execSuccess !== 'never') {
|
MKEmitter.emit('refreshByButtonResult', btn.$menuId, btn.execSuccess, btn)
|
}
|
|
if (btn.execSuccess === 'popclose' && btn.$tabId) { // 标签关闭刷新
|
MKEmitter.emit('refreshPopButton', btn.$tabId)
|
}
|
}
|
|
/**
|
* @description 操作失败后处理
|
*/
|
execError = (res) => {
|
const { btn } = this.props
|
const { dict } = this.state
|
|
this.setState({
|
loading: false
|
})
|
|
if (res.ErrCode === '01') {
|
message.error(dict['exc_fail'] || '未获取到下载文件。')
|
return
|
} else if (res.ErrCode === '02') {
|
Modal.error({
|
title: dict['exc_fail'] || '部分文件下载失败:1、请检查文件路径是否正确,2、请检查文件是否跨域。',
|
okText: dict['got_it'] || '知道了'
|
})
|
return
|
} else if (res.ErrCode === '03') {
|
Modal.error({
|
title: dict['exc_fail'] || '文件下载失败:1、请检查文件路径是否正确,2、请检查文件是否跨域。',
|
okText: dict['got_it'] || '知道了'
|
})
|
return
|
} else if (res.ErrCode === 'E') {
|
Modal.error({
|
title: res.message || dict['exc_fail'] || '执行失败!',
|
okText: dict['got_it'] || '知道了'
|
})
|
} else if (res.ErrCode === 'N') {
|
notification.error({
|
top: 92,
|
message: res.message || dict['exc_fail'] || '执行失败!',
|
duration: 10
|
})
|
} else if (res.ErrCode === 'F') {
|
notification.error({
|
className: 'notification-custom-error',
|
top: 92,
|
message: res.message || dict['exc_fail'] || '执行失败!',
|
duration: 10
|
})
|
} else if (res.ErrCode === 'NM') {
|
message.error(res.message || dict['exc_fail'] || '执行失败!')
|
}
|
|
if (btn.execError !== 'never') {
|
MKEmitter.emit('refreshByButtonResult', btn.$menuId, btn.execError, btn)
|
}
|
|
if (btn.execError === 'popclose' && btn.$tabId) { // 标签关闭刷新
|
MKEmitter.emit('refreshPopButton', btn.$tabId)
|
}
|
}
|
|
render() {
|
const { btn } = this.props
|
const { loading, disabled, hidden } = this.state
|
|
if (hidden) return null
|
|
let label = ''
|
|
if (btn.show === 'link') {
|
label = <span>{btn.label}{btn.icon ? <MkIcon style={{marginLeft: '8px'}} type={btn.icon} /> : ''}</span>
|
} else if (btn.show === 'icon') {
|
label = !loading ? <MkIcon type={btn.icon} /> : null
|
} else {
|
label = <span>{!loading && btn.icon ? <MkIcon style={{marginRight: '8px'}} type={btn.icon} /> : ''}{btn.label}</span>
|
}
|
|
return (
|
<Button
|
type="link"
|
title={disabled ? (btn.reason || '') : (btn.show === 'icon' ? btn.label : '')}
|
loading={loading}
|
disabled={disabled}
|
style={btn.style}
|
className={btn.hover || ''}
|
onClick={(e) => {e.stopPropagation(); this.actionTrigger()}}
|
>{label}</Button>
|
)
|
}
|
}
|
|
export default FuncZip
|