diff --git a/src/main/java/com/rebuild/core/configuration/general/FormsBuilder.java b/src/main/java/com/rebuild/core/configuration/general/FormsBuilder.java
index 10d5ad189..851595f95 100644
--- a/src/main/java/com/rebuild/core/configuration/general/FormsBuilder.java
+++ b/src/main/java/com/rebuild/core/configuration/general/FormsBuilder.java
@@ -347,11 +347,13 @@ public class FormsBuilder extends FormsManager {
// v2.2 高级控制
if (viewModel) useAdvControl = false;
if (useAdvControl) {
- Object displayOnCreate = el.remove("displayOnCreate");
- Object displayOnUpdate = el.remove("displayOnUpdate");
- Object requiredOnCreate = el.remove("requiredOnCreate");
- Object requiredOnUpdate = el.remove("requiredOnUpdate");
-
+ final Object displayOnCreate = el.remove("displayOnCreate");
+ final Object displayOnUpdate = el.remove("displayOnUpdate");
+ final Object requiredOnCreate = el.remove("requiredOnCreate");
+ final Object requiredOnUpdate = el.remove("requiredOnUpdate");
+ final Object readonlyOnCreate = el.remove("readonlyOnCreate");
+ final Object readonlyOnUpdate = el.remove("readonlyOnUpdate");
+
// fix v3.3.4 跟随主记录新建/更新
boolean isNew2 = isNew;
if (entity.getMainEntity() != null) {
@@ -376,6 +378,14 @@ public class FormsBuilder extends FormsManager {
if (requiredOnUpdate != null && (Boolean) requiredOnUpdate && !isNew2) {
el.put("nullable", false);
}
+
+ // 只读 v3.6
+ if (readonlyOnCreate != null && (Boolean) readonlyOnCreate && isNew2) {
+ el.put("readonly", true);
+ }
+ if (readonlyOnUpdate != null && (Boolean) readonlyOnUpdate && !isNew2) {
+ el.put("readonly", true);
+ }
}
// 自动只读的
diff --git a/src/main/java/com/rebuild/core/support/CommonsLog.java b/src/main/java/com/rebuild/core/support/CommonsLog.java
index c007e9859..a7ce8be7c 100644
--- a/src/main/java/com/rebuild/core/support/CommonsLog.java
+++ b/src/main/java/com/rebuild/core/support/CommonsLog.java
@@ -13,6 +13,7 @@ import cn.devezhao.persist4j.engine.ID;
import com.rebuild.core.Application;
import com.rebuild.core.metadata.EntityHelper;
import com.rebuild.core.support.task.TaskExecutors;
+import com.rebuild.utils.CommonsUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
@@ -65,7 +66,7 @@ public class CommonsLog {
clog.setID("source", ObjectUtils.defaultIfNull(source, user));
clog.setInt("status", status);
clog.setDate("logTime", CalendarUtils.now());
- if (content != null) clog.setString("logContent", content);
+ if (content != null) clog.setString("logContent", CommonsUtils.maxstr(content, 32767));
TaskExecutors.queue(() -> Application.getCommonsService().create(clog, false));
}
diff --git a/src/main/java/com/rebuild/web/admin/metadata/MetaFieldController.java b/src/main/java/com/rebuild/web/admin/metadata/MetaFieldController.java
index 284dc17e0..0c5b553bb 100644
--- a/src/main/java/com/rebuild/web/admin/metadata/MetaFieldController.java
+++ b/src/main/java/com/rebuild/web/admin/metadata/MetaFieldController.java
@@ -80,6 +80,7 @@ public class MetaFieldController extends BaseController {
map.put("nullable", field.isNullable());
map.put("builtin", easyMeta.isBuiltin());
map.put("creatable", field.isCreatable());
+ map.put("updatable", field.isUpdatable());
DisplayType dt = easyMeta.getDisplayType();
map.put("displayType", Language.L(dt));
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index c782ed3a1..282911f58 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -14,7 +14,7 @@ server:
cookie:
same-site: lax
name: RBSESSION
- timeout: 14400
+ timeout: 7200
error:
whitelabel.enabled: false
tomcat:
diff --git a/src/main/resources/web/admin/metadata/entities.html b/src/main/resources/web/admin/metadata/entities.html
index 48782afdf..3450a1942 100644
--- a/src/main/resources/web/admin/metadata/entities.html
+++ b/src/main/resources/web/admin/metadata/entities.html
@@ -81,21 +81,13 @@
}
.table.table-excel th,
.table.table-excel td {
- padding: 3px;
- border-width: 1px;
- color: #222;
- max-width: 200px;
+ vertical-align: text-top;
}
- .table.table-excel th {
- text-align: center;
- background-color: #dee2e6;
- color: #444;
+ .table.table-excel thead th {
+ border: 0 none;
}
- .table.table-excel .form-control {
- width: 100%;
- min-width: 140px;
- /* padding: 4px; */
- /* height: auto !important; */
+ .table.table-excel {
+ border-bottom: 1px solid #dee2e6;
}
diff --git a/src/main/resources/web/admin/metadata/form-design.html b/src/main/resources/web/admin/metadata/form-design.html
index 7c38a9ecb..ba56ba83e 100644
--- a/src/main/resources/web/admin/metadata/form-design.html
+++ b/src/main/resources/web/admin/metadata/form-design.html
@@ -93,6 +93,9 @@
@@ -329,16 +329,23 @@ class DlgAddChart extends RbFormHandler {
}
componentDidMount() {
- const $entity = $(this.refs['entity'])
$.get('/commons/metadata/entities?detail=true', (res) => {
- $(res.data).each(function () {
- if (!$isSysMask(this.label)) {
- $(`
`).appendTo($entity)
+ const _data = res.data || []
+ _data.forEach((item) => {
+ if (!$isSysMask(item.label)) {
+ $(`
`).appendTo(this._$entity)
}
})
- this.__select2 = $entity.select2({
+
+ this.__select2 = $(this._$entity).select2({
allowClear: false,
placeholder: $L('选择数据来源'),
+ // templateResult: function (res) {
+ // const $span = $('
').attr('title', res.text).text(res.text)
+ // const found = _data.find((x) => x.entity === res.id)
+ // if (found) $(`
`).appendTo($span)
+ // return $span
+ // },
})
})
}
diff --git a/src/main/resources/web/assets/js/metadata/entity-new2.js b/src/main/resources/web/assets/js/metadata/entity-new2.js
index 558328a56..0e1117207 100644
--- a/src/main/resources/web/assets/js/metadata/entity-new2.js
+++ b/src/main/resources/web/assets/js/metadata/entity-new2.js
@@ -17,6 +17,7 @@ class EntityNew2 extends RbModalHandler {
constructor(props) {
super(props)
this.state = { ...props }
+ // this.state.excelfile = '134807507__副本IUI000008390352CNY23100100N-111.xls'
}
render() {
@@ -305,7 +306,9 @@ class EntityNew2 extends RbModalHandler {
const excelfile = this.state.excelfile
if (!excelfile) return RbHighbar.create($L('请上传数据文件'))
+ const $btn = $(this._$container).find('.btn').button('loading')
$.get(`/app/entity/data-imports/check-file?file=${$encode(excelfile)}`, (res) => {
+ $btn.button('reset')
if (res.error_code > 0) {
this.setState({ excelfile: null })
RbHighbar.create(res.error_msg)
@@ -318,7 +321,7 @@ class EntityNew2 extends RbModalHandler {
const entityLabel = $val(this._$excelEntityLabel)
if (!entityLabel) return RbHighbar.create($L('请输入实体名称'))
- renderRbcomp(
)
+ renderRbcomp(
)
})
}
@@ -343,126 +346,88 @@ class EntityNew2 extends RbModalHandler {
}
const _LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('')
-class ExcelPreview extends RbModal {
+class ExcelFieldsPreview extends RbModal {
renderContent() {
- let colMax = 0
- this.props.datas.forEach((d) => {
- colMax = Math.max(colMax, d.length)
- })
-
+ const ftKeys = Object.keys(FIELD_TYPES)
+ const fieldsHead = this.props.datas[0]
const colNames = []
- for (let i = 0; i < colMax; i++) {
+ for (let i = 0; i < fieldsHead.length; i++) {
let L = _LETTERS[i]
if (i > 25) L = `A${_LETTERS[i - 26] || 'X'}` // AA
if (i > 51) L = `B${_LETTERS[i - 52] || 'X'}` // BA
colNames.push(L)
}
- const ftKeys = Object.keys(FIELD_TYPES)
- const dataHead = this.props.datas[0]
-
- this.__colNames = colNames
- this.__colDatas = {}
-
return (
-
-
-
-
- |
- {colNames.map((item) => {
- return {item} |
- })}
-
-
-
- (this._$datahead = c)}>
- 1 |
- {colNames.map((item, idx) => {
- return (
-
-
-
-
-
-
-
- |
- )
- })}
-
-
-
-
-
{$L('最多显示前 %d 行数据', 20)}
-
-
(this._$btns = c)}>
-
-
)
@@ -471,38 +436,24 @@ class ExcelPreview extends RbModal {
componentDidMount() {
super.componentDidMount()
- // 评估字段类型
- function _evalFieldType(cols) {
- let isNumber = undefined
- let isDecimal = undefined
- cols.forEach((item) => {
- if ($empty(item)) return
-
- if (isNumber || isNumber === undefined) isNumber = !isNaN(item)
- if (isDecimal || isDecimal === undefined) {
- isDecimal = isNumber && /\./g.test(item)
- }
- })
- if (isDecimal) return 'DECIMAL'
- if (isNumber) return 'NUMBER'
- return null
- }
-
$.get('/admin/entity/entity-list?detail=true', (res) => {
this.setState({ refEntities: res.data || [] })
$.get('/admin/metadata/classification/list', (res2) => {
this.setState({ refClasses: res2.data || [] }, () => {
// init
- this.__colNames.forEach((item, idx) => {
- const type = _evalFieldType(this.__colDatas[idx] || [])
- type && $(this._$datahead).find('td').eq(idx).find('.J_type select').val(type)
- })
-
- $(this._$datahead)
- .find('.J_type select')
+ $(this._$tbody)
+ .find('.J_type')
+ .select2({
+ allowClear: false,
+ templateResult: function (res) {
+ const $span = $('
').attr('title', res.text).text(res.text)
+ $(`
`).appendTo($span)
+ return $span
+ },
+ })
.on('change', function () {
- const $td = $(this).parents('td')
+ const $td = $(this).parent()
$td.find('.J_refEntity, .J_refClass').addClass('hide')
const t = $(this).val()
@@ -513,20 +464,39 @@ class ExcelPreview extends RbModal {
}
})
- $(this._$datahead).find('select').select2({ allowClear: false })
+ $(this._$tbody).find('.J_refEntity select, .J_refClass select').select2({ allowClear: false })
})
})
})
}
+ _evalFieldType(name, colidx) {
+ if ($empty(name)) return null
+
+ let isNumber = undefined
+ let isDecimal = undefined
+ this.props.datas.forEach((row, idx) => {
+ if (idx < 1) return
+ const v = row[colidx]
+ if (isNumber || isNumber === undefined) isNumber = !isNaN(v)
+ if (isDecimal || isDecimal === undefined) {
+ isDecimal = isNumber && /\./g.test(v)
+ }
+ })
+
+ if (isDecimal) return 'DECIMAL'
+ if (isNumber) return 'NUMBER'
+ return null
+ }
+
post2() {
const fieldsNew = []
- $(this._$datahead)
- .find('td')
+ $(this._$tbody)
+ .find('tr')
.each(function () {
const name = $(this).find('input').val()
- const type = $(this).find('.J_type select').val()
- if (name && type && type !== '-') {
+ const type = $(this).find('.J_type').val()
+ if (name) {
let ref2 = null
if (type === 'REFERENCE' || type === 'N2NREFERENCE') {
ref2 = $(this).find('.J_refEntity select').val()
@@ -539,7 +509,7 @@ class ExcelPreview extends RbModal {
fieldsNew.push([name, type, ref2])
}
})
- if (fieldsNew.length === 0) return RbHighbar.create($L('没有配置任何导入字段'))
+ if (fieldsNew.length === 0) return RbHighbar.create($L('没有任何导入字段'))
const that = this
const post = {
@@ -547,21 +517,24 @@ class ExcelPreview extends RbModal {
fields: fieldsNew,
}
- RbAlert.create($L('请确认导入字段配置。开始导入吗?'), {
+ RbAlert.create($L('请再次确认导入字段。开始导入吗?'), {
onConfirm: function () {
this.disabled(true, true)
$.post('/admin/entity/entity-excel', JSON.stringify(post), (res) => {
this.hide(true)
if (res.error_code === 0) {
- RbAlert.create($L('实体导入成功。是否需要进行数据导入?'), {
- onConfirm: function () {
- location.href = `${rb.baseUrl}/admin/data/data-imports?entity=${res.data}&file=${$encode(that.props.excelfile)}`
- },
- onCancel: function () {
- location.href = `${rb.baseUrl}/admin/entity/${res.data}/fields`
- },
- })
+ setTimeout(() => {
+ RbAlert.create($L('实体导入成功。是否需要进行数据导入?'), {
+ onConfirm: function () {
+ location.href = `${rb.baseUrl}/admin/data/data-imports?entity=${res.data}&file=${$encode(that.props.excelfile)}`
+ },
+ onCancel: function () {
+ location.href = `${rb.baseUrl}/admin/entity/${res.data}/fields`
+ },
+ cancelText: $L('不需要'),
+ })
+ }, 200)
} else {
RbHighbar.error(res.error_msg)
}
diff --git a/src/main/resources/web/assets/js/metadata/form-design.js b/src/main/resources/web/assets/js/metadata/form-design.js
index 24f39109f..c42b8b610 100644
--- a/src/main/resources/web/assets/js/metadata/form-design.js
+++ b/src/main/resources/web/assets/js/metadata/form-design.js
@@ -563,9 +563,20 @@ const AdvControl = {
set: function (field) {
const $c = $(`
${this._template}
`).appendTo(this.$tbody)
$c.find('td:eq(0)').text(field.fieldLabel)
+
+ // 必填
const $req = $c.find('td:eq(2)')
if (field.builtin) $req.empty()
- else if (!field.nullable) $req.find('input').attr({ disabled: true, checked: true })
+ else if (!field.nullable) {
+ $req.find('input').attr({ disabled: true, checked: true })
+ }
+ // 只读
+ const $ro = $c.find('td:eq(3)')
+ if (field.builtin) $ro.empty()
+ else {
+ if (!field.creatable) $ro.find('input:eq(0)').attr({ disabled: true, checked: true })
+ if (!field.updatable) $ro.find('input:eq(1)').attr({ disabled: true, checked: true })
+ }
this.$tbody.find(`tr[data-field="${field.fieldName}"] input`).each(function () {
const $this = $(this)