Be template5 (#793)

* fix: CVE

* $tagStyle2

* Update rb-forms.append.js
This commit is contained in:
REBUILD 企业管理系统 2024-07-31 13:43:53 +08:00 committed by GitHub
parent aea4dfde4e
commit becc14196f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 36 additions and 21 deletions

View file

@ -145,5 +145,6 @@ module.exports = {
$hex2rgb: true,
$isImage: true,
$dropUpload: true,
$tagStyle2: true,
},
}

2
@rbv

@ -1 +1 @@
Subproject commit 39b2d87b878552ce784b31ce1bb54d7e9a9f060b
Subproject commit 99657adb1967c170bb028340ad3f63f3cc29c48e

View file

@ -106,6 +106,7 @@ public class DataReportManager implements ConfigManager {
int type = ObjectUtils.toInt(o[4], TYPE_RECORD);
if (type == TYPE_WORD && outputType.contains("excel")) outputType += ",word";
else if (type == TYPE_HTML5) outputType = "html5";
ConfigBean cb = new ConfigBean()
.set("id", o[0])

View file

@ -253,9 +253,8 @@ public class RebuildWebInterceptor implements AsyncHandlerInterceptor, InstallSt
}
private boolean isIgnoreAuth(String requestUri) {
if (requestUri.contains("/user/") && !requestUri.contains("/user/admin")) {
return true;
}
if (requestUri.contains("..")) return false;
if (requestUri.contains("/user/") && !requestUri.contains("/user/admin")) return true;
requestUri = requestUri.replaceFirst(AppUtils.getContextPath(), "");

View file

@ -7,6 +7,7 @@ See LICENSE and COMMERCIAL in the project root for license information.
package com.rebuild.web.admin.data;
import cn.devezhao.commons.web.ServletUtils;
import cn.devezhao.persist4j.Entity;
import cn.devezhao.persist4j.engine.ID;
import cn.hutool.core.io.file.FileNameUtil;
@ -95,11 +96,12 @@ public class ReportTemplateController extends BaseController {
boolean isDocx = file.toLowerCase().endsWith(".docx");
if (type == DataReportManager.TYPE_WORD) {
if (!isDocx) return RespBody.errorl("上传 WORD 文件请选择 WORD 模板类型");
} else {
} else if (type != DataReportManager.TYPE_HTML5) {
if (isDocx) return RespBody.errorl("上传 EXCEL 文件请选择 EXCEL 模板类型");
}
File template = RebuildConfiguration.getFileOfData(file);
File template = type == DataReportManager.TYPE_HTML5
? null : RebuildConfiguration.getFileOfData(file);
Map<String, String> vars = null;
try {
if (type == DataReportManager.TYPE_RECORD) {
@ -110,6 +112,11 @@ public class ReportTemplateController extends BaseController {
//noinspection unchecked
vars = (Map<String, String>) CommonsUtils.invokeMethod(
"com.rebuild.rbv.data.WordTemplateExtractor#transformVars", template, entity.getName());
} else if (type == DataReportManager.TYPE_HTML5) {
String templateContent = ServletUtils.getRequestString(request);
//noinspection unchecked
vars = (Map<String, String>) CommonsUtils.invokeMethod(
"com.rebuild.rbv.data.Html5TemplateExtractor#transformVars", templateContent, entity.getName());
}
} catch (Exception ex) {
@ -233,6 +240,9 @@ public class ReportTemplateController extends BaseController {
FileDownloader.writeLocalFile(template, response);
}
// --
private static String HTML5_INLINE_STYLE;
/**
* @param html5
* @param title
@ -244,6 +254,10 @@ public class ReportTemplateController extends BaseController {
ModelAndView mv = new ModelAndView("/admin/data/template5-view");
mv.getModelMap().put("reportName", title);
mv.getModelMap().put("reportContent", content);
if (HTML5_INLINE_STYLE == null) {
HTML5_INLINE_STYLE = CommonsUtils.getStringOfRes("/web/assets/css/template5-design-content.css");
}
mv.getModelMap().put("inlineStyle", HTML5_INLINE_STYLE);
return mv;
}
}

View file

@ -95,7 +95,7 @@ public class ReportsController extends BaseController {
File output = null;
try {
EasyExcelGenerator reportGenerator = null;
EasyExcelGenerator reportGenerator;
if (tt.type == DataReportManager.TYPE_WORD) {
reportGenerator = (EasyExcelGenerator33) CommonsUtils.invokeMethod(
"com.rebuild.rbv.data.WordReportGenerator#create", reportId, recordId);

View file

@ -1771,9 +1771,8 @@ CellRenders.addRender('MULTISELECT', (v, s, k) => {
<div className="column-multi" style={s}>
{(v.text || []).map((item) => {
if (typeof item === 'object') {
const style2 = item.color ? { borderColor: item.color, backgroundColor: item.color, color: $isLight(item.color) ? '#444' : '#fff' } : null
return (
<span key={item.text} className="badge" title={item.text} style={style2}>
<span key={item.text} className="badge" title={item.text} style={$tagStyle2(item.color)}>
{item.text}
</span>
)
@ -1823,11 +1822,10 @@ CellRenders.addRender('SIGN', (v, s, k) => {
const _renderOptionField = (v, s, k) => {
// Use badge
if (typeof v === 'object') {
const style2 = v.color ? { borderColor: v.color, backgroundColor: v.color, color: $isLight(v.color) ? '#444' : '#fff' } : null
return (
<td key={k} className="td-sm column-state">
<div style={s} title={v.text}>
<span className="badge" style={style2}>
<span className="badge" style={$tagStyle2(v.color)}>
{v.text}
</span>
</div>
@ -1845,9 +1843,8 @@ CellRenders.addRender('TAG', (v, s, k) => {
<td key={k} className="td-sm" title={$L(' %d ', vLen)}>
<div className="column-multi" style={s}>
{(v || []).map((item) => {
const style2 = item.color ? { color: item.color, borderColor: item.color } : null
return (
<span key={item.name} className="badge" title={item.name} style={style2}>
<span key={item.name} className="badge" title={item.name} style={$tagStyle2(item.color)}>
{item.name}
</span>
)

View file

@ -250,7 +250,7 @@ class DeleteConfirm extends RbAlert {
this.setState({ cascadesEntity: res.data }, () => {
this.__select2 = $(this._cascades)
.select2({
placeholder: $L('选择相关实体 (可选)'),
placeholder: $L('选择要同时删除的相关记录'),
width: '88%',
})
.val(null)

View file

@ -2339,9 +2339,8 @@ class RbFormClassification extends RbFormElement {
renderViewElement() {
let text = this.state.value
if (text && text.color) {
const style2 = { borderColor: text.color, backgroundColor: text.color, color: $isLight(text.color) ? '#444' : '#fff' }
text = (
<span className="badge" style={style2}>
<span className="badge" style={$tagStyle2(text.color)}>
{text.text}
</span>
)
@ -3104,9 +3103,8 @@ const __findOptionText = function (options, value, useColor) {
let text = (o || {}).text || `[${value.toUpperCase()}]`
if (useColor) {
if (o && o.color) {
const style2 = { borderColor: o.color, backgroundColor: o.color, color: $isLight(o.color) ? '#444' : '#fff' }
text = (
<span className="badge" style={style2}>
<span className="badge" style={$tagStyle2(o.color)}>
{text}
</span>
)
@ -3143,9 +3141,8 @@ const __findTagTexts = function (options, value) {
let item = options.find((x) => x.name === name)
if (!item) item = { name: name }
const style2 = item.color ? { borderColor: item.color, color: item.color } : null
const text = (
<span key={`tag-${item.name}`} style={style2}>
<span key={`tag-${item.name}`} style={$tagStyle2(item.color)}>
{item.name}
</span>
)

View file

@ -477,7 +477,7 @@ class SelectReport extends React.Component {
rb._officePreviewUrl = 111
const reportUrl = `${rb.baseUrl}/app/${this.props.entity}/report/export?report=${item.id}&record=${this.props.id}`
const showPdf = (item.outputType || '').includes('pdf')
const showHtml = (item.outputType || '').includes('html')
const showHtml = item.outputType !== 'html5' && (item.outputType || '').includes('html')
return (
<li key={item.id} className={`${rb._officePreviewUrl && 'has-preview'} ${showPdf && 'has-pdf'} ${showHtml && 'has-html'}`}>
<a target="_blank" href={reportUrl} className="text-truncate" title={$L('下载')}>

View file

@ -1284,3 +1284,9 @@ function $openWindow(url) {
// 不支持排序的字段联系
var UNSORT_FIELDTYPES = ['N2NREFERENCE', 'ANYREFERENCE', 'MULTISELECT', 'TAG', 'FILE', 'IMAGE', 'AVATAR', 'SIGN']
// 字段颜色
function $tagStyle2(color) {
if (!color) return null
return { backgroundColor: color, borderColor: color, color: $isLight(color) ? '#444' : '#fff' }
}