提交 a4537f07 authored 作者: 钟是志's avatar 钟是志

中医大评奖评优 奖状打印第一个版本

上级 5124493b
import React, { Fragment, Component } from 'react';
import PrintSetting from '@/webPublic/zyd_private/DragAndPrint';
import styles from './index.less';
export default class Index extends Component {
constructor(props) {
......@@ -7,9 +7,83 @@ export default class Index extends Component {
this.state = {};
}
render(){
dragEventList = () => {
const { updateConfig } = this.props;
let draggedRef = null;
document.addEventListener('dragstart', function(event) {
// 保存拖动元素的引用(ref.)
draggedRef = event.target;
// 使其半透明
event.target.style.opacity = 0.5;
}, false);
document.addEventListener('dragend', function(event) {
// 重置透明度
event.target.style.opacity = '';
}, false);
/* 放下目标节点时触发事件 */
document.addEventListener('dragover', function(event) {
// 阻止默认动作
event.preventDefault();
}, false);
document.addEventListener('drop', function(event) {
// 阻止默认动作(如打开一些元素的链接)
event.preventDefault();
// 将拖动的元素到所选择的放置目标节点中
if (event.target.id === 'dropZone') {
const left = event.offsetX;
if (left > (event.target.width - draggedRef.offsetWidth - 10)) {
console.error('拖拽到了图片区域外部,不能进行拖拽');
return false;
}
const top = event.offsetY;
updateConfig({
id: draggedRef.id.replace('dragKey-', ''),
x: left,
y: top,
});
draggedRef.style.left = left; // `${left}px`;
draggedRef.style.top = top; // `${top}px`;
}
}, false);
};
componentDidMount() {
this.dragEventList();
}
render() {
const { backgroundUrl, configAll: { config } } = this.props;
return (
<PrintSetting code={'award'}/>
<div className={styles.outSideDiv}>
<div style={{
padding: '12px',
}}>
<img src={backgroundUrl}
id={'dropZone'}
draggable={false}
className={styles.bgimage}
alt={'背景图'}
/>
{config.map((item, index) => {
return (
<div draggable={true}
className={styles.inSideItem}
key={item.id}
id={`dragKey-${item.id}`}
style={{
top: `${item.y || 20 + index * 40}px`,
left: `${item.x || 20}px`,
}}
>
{item.title}
</div>
);
})}
</div>
</div>
);
}
......
import React from 'react';
import JsBarcode from 'jsbarcode';
import styles from '../index.less';
/**
* -2 条形码
* -1 常量
* 0 文字
* 1 时间
* 2 照片
* */
const normalTextRender = (text, config) => {
if (!text) {
return null;
}
const style = {
fontSize: `${config.fieldFontSize || 16}px`, // 默认 16px
fontFamily: `${config.fieldFont || '黑体'}`, // 默认黑体
};
return <span style={style}>
{text}
</span>;
};
class BarCode extends React.Component {
componentDidMount() {
this.toJsBarcode();
}
toJsBarcode() {
// 调用 JsBarcode方法生成条形码
JsBarcode(this.barcode, this.props.value || '1234567890', {
text: '',
format: 'CODE39',
displayValue: false,
width: 1.0,
height: 30,
margin: 0,
});
}
render() {
return (
<div className="barcode-box">
<svg
ref={(ref) => {
this.barcode = ref;
}}
/>
</div>
);
}
}
export default function DetailDom({ config, data }) {
const { x, y, fieldCode } = config;
const outSideDom = (children) => {
return (
<div
className={styles.inSideItemPrint}
key={fieldCode}
style={{
left: x + 'px',
top: y + 'px',
}}>
{children}
</div>
);
};
let children = null;
switch (config.fieldType) {
case '-2': // 条形码
children = <BarCode value={data}/>;
break;
case '-1': // 常量
children = normalTextRender(config.content, config);
break;
case '0': // 文字
children = normalTextRender(data, config);
break;
case '1': // 时间
children = normalTextRender(config.content, config);
break;
case '2': // 照片
children = normalTextRender(config.content, config);
break;
default:
children = normalTextRender(config.content, config);
break;
}
return outSideDom(children);
}
import React, { Component, Fragment } from 'react';
import { queryConfig } from '../services';
import { getInfo } from '@/highOrderComponent/Service';
import { message, Button } from 'antd';
import Shell from '@/baseComponent/Shell';
import ReactToPrint from 'react-to-print';
import ButtonDiy from '@/baseComponent/ButtonDiy';
import router from 'umi/router';
import styles from '../index.less';
import DetailDom from './DetailDom';
export default class ViewPrint extends Component {
constructor(props) {
super(props);
this.state = {
configAll: null,
viewData: null,
loading: false,
minHeight: 700,
showWindowPrint: false,
};
this.getConfigInfo = queryConfig.bind(this);
}
countImageHeight = () => {
const {
configAll: { backgroundUrl },
} = this.state;
const img = new Image();
img.src = backgroundUrl;
img.onload = () => {
this.setState({
minHeight: img.height,
});
};
};
getViewData = () => {
const { selectedRows } = this.props;
const ids = selectedRows.map((x) => x.id);
this.getConfigInfo().then((x) => {
this.countImageHeight();
if (x && x.queryUrl) {
getInfo(
{
ids: ids.join(','),
},
x.queryUrl,
).then((viewData) => {
if (!viewData || !viewData.length) {
message.warning('未查询到可打印的奖状数据');
console.error(`${x.queryUrl}接口报错或者没有返回数据`);
}
this.setState({
viewData,
});
});
}
});
};
componentDidMount() {
this.getViewData();
}
detailDom = (data) => {
const {
configAll: { config },
} = this.state;
const res = [];
for (let item of config) {
if (item.fieldCode && data[item.fieldCode]) {
res.push(
DetailDom({
config: item,
data: data[item.fieldCode],
}),
);
}
}
return res;
};
onBeforeGetContent = () => {
this.setState({
loading: true,
});
return new Promise((resolve, reject) => {
const { selectedRows } = this.props;
const { configAll } = this.state;
const ids = selectedRows.map((x) => {
return x.id;
});
if (configAll.callUrl && false) { // 暂时关闭调用这个接口 不通知后台是否打印了
getInfo({ ids: ids.join(',') }, configAll.callUrl).then((x) => {
if (x) {
this.setState({ showWindowPrint: true }, () => {
resolve(true);
});
} else {
resolve(true);
}
});
} else {
this.setState({ showWindowPrint: true }, () => {
resolve(true);
});
}
});
};
render() {
const {
loading,
configAll,
viewData,
showWindowPrint,
minHeight,
} = this.state;
if (!configAll) {
return null;
}
const { hasPrintBackground, backgroundUrl } = configAll;
return (
<Fragment>
<Shell styleShell={{ marginTop: '0', marginBottom: '20px' }}>
<div style={{ height: '54px', padding: '12px 0 12px 12px' }}>
<ReactToPrint
trigger={() => (
<Button
shape="round"
type="primary"
loading={loading}
style={{ marginRight: '20px' }}>
打印
</Button>
)}
content={() => this.content}
onBeforeGetContent={this.onBeforeGetContent}
onAfterPrint={() => {
this.setState({
showWindowPrint: false,
loading: false,
});
}}
/>
<ButtonDiy
name={'返回'}
handleClick={() => {
router.goBack();
}}
/>
</div>
</Shell>
{/** 预览的dom **/}
{viewData && viewData.length ? (
<div>
{viewData.map((info, index) => {
return (
<div className={styles.outSideDivPrint} key={index + 'divKey'}>
<img
src={backgroundUrl}
draggable={false}
className={styles.bgimagePrint}
alt={'背景图'}
/>
{this.detailDom(info)}
</div>
);
})}
</div>
) : null}
{/** 打印的dom */}
{viewData && viewData.length ? (
<div
ref={(node) => (this.content = node)}
style={{
display: showWindowPrint ? 'block' : 'none',
}}>
{!showWindowPrint
? null
: viewData.map((info, index) => {
return (
<div
className={styles.outSideDivPrint}
key={`${index}divKey`}
style={{
minHeight,
}}>
{hasPrintBackground ? (
<img
src={backgroundUrl}
draggable={false}
className={styles.bgimagePrint}
alt={'背景图'}
/>
) : null}
{this.detailDom(info)}
</div>
);
})}
</div>
) : null}
</Fragment>
);
}
}
/**
* 钟是志
* 2020年5月25日 18:03:24
* 一站式请勿使用此组件
* 拖拽配置 打印数据页面
* 用于中医大评奖评优 奖状打印
* 后续可以会应用于其他学校的其他 打印.
* */
import React, { Component } from 'react';
import { getInfo } from '@/highOrderComponent/Service';
import PropTypes from 'prop-types';
import DragSetting from './DragSetting';
import Shell from '@/baseComponent/Shell';
import ButtonDiy from '@/baseComponent/ButtonDiy';
import router from 'umi/router';
import { message } from 'antd';
import { saveConfig, queryConfig } from './services';
export default class Index extends Component {
constructor(props) {
super(props);
this.state = {
configAll: null,
};
this.getConfigInfo = queryConfig.bind(this);
}
updateConfig = ({ id, x, y }) => {
const { configAll } = this.state;
for (const item of configAll.config) {
if (item.id + '' === id) {
item.x = x;
item.y = y;
}
}
this.setState({
configAll,
});
};
saveConfig = () => {
const {
configAll: { config },
} = this.state;
saveConfig({
contentStr: JSON.stringify(config),
}).then((x) => {
if (x) {
message.success('保存成功');
}
});
};
componentDidMount() {
this.getConfigInfo();
}
render() {
const { configAll } = this.state;
if (!configAll || !configAll.backgroundUrl) {
return null;
}
return (
<Shell styleShell={{ marginTop: '0', marginBottom: '20px' }}>
<div style={{ height: '54px', padding: '12px 0 24px 12px' }}>
<ButtonDiy
name="保存"
className="primary"
handleClick={this.saveConfig}
/>
</div>
<DragSetting
backgroundUrl={configAll.backgroundUrl}
updateConfig={this.updateConfig}
configAll={configAll}
/>
</Shell>
);
}
}
Index.propTypes = {
code: PropTypes.string.isRequired, // 后端配置的表里面的code 用于获取所有的配置项
};
Index.defaultProps = {
code: 'award',
};
.outSideDiv{
position: relative;
text-align: left;
width: 100%;
.bgimage{
height: auto;
overflow: auto;
z-index: 1;
}
.inSideItem{
position: absolute;
cursor: move;
z-index: 10;
color: #000;
padding-left: 10px;
padding-right: 10px;
font-size: 14px;
line-height: 28px;
border: 1px solid gray;
background-color: #CCC;
}
}
.outSideDivPrint{
position: relative;
width: 100%;
margin-bottom: 10px;
page-break-after: always;
.bgimagePrint{
height: auto;
overflow: auto;
z-index: 1;
}
.inSideItemPrint{
position: absolute;
z-index: 10;
padding-left: 10px;
padding-right: 10px;
font-weight: bold;
}
}
import { getInfo } from '@/highOrderComponent/Service';
export function getConfigApi(code) {
return getInfo(
{ code },
'/PublicPrintApi/query',
);
}
export const queryConfig = function() {
const { code } = this.props;
return getConfigApi(code).then((x) => {
if (!x) {
console.error('配置接口报错');
return false;
}
if (x) {
if (!x.backgroundUrl) {
console.error('未配置打印背景图 无法进行操作');
return false;
}
x.config = x.config.filter((y) => { // 过滤不显示的字段.
return y.hasHidden === false;
});
this.setState({
configAll: x,
});
return x;
}
});
};
export function saveConfig(parmas = {}) {
return getInfo(parmas, '/PublicPrintApi/update');
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论