mirror of
https://github.com/getrebuild/rebuild.git
synced 2024-09-20 23:45:55 +08:00
commit
d2014a03af
2
pom.xml
2
pom.xml
|
@ -10,7 +10,7 @@
|
|||
</parent>
|
||||
<groupId>com.rebuild</groupId>
|
||||
<artifactId>rebuild</artifactId>
|
||||
<version>2.0.0</version>
|
||||
<version>2.0.1</version>
|
||||
<name>rebuild</name>
|
||||
<description>RB V2 use SpringBoot</description>
|
||||
<!-- UNCOMMENT USE TOMCAT -->
|
||||
|
|
|
@ -14,7 +14,9 @@ import cn.devezhao.persist4j.Query;
|
|||
import cn.devezhao.persist4j.engine.ID;
|
||||
import cn.devezhao.persist4j.engine.StandardRecord;
|
||||
import cn.devezhao.persist4j.query.QueryedRecord;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.serializer.SerializeConfig;
|
||||
import com.alibaba.fastjson.serializer.SerializerFeature;
|
||||
import com.alibaba.fastjson.serializer.ToStringSerializer;
|
||||
import com.rebuild.core.cache.CommonsCache;
|
||||
import com.rebuild.core.metadata.impl.DynamicMetadataFactory;
|
||||
|
@ -65,11 +67,11 @@ public class Application implements ApplicationListener<ApplicationStartedEvent>
|
|||
/**
|
||||
* Rebuild Version
|
||||
*/
|
||||
public static final String VER = "2.0.0";
|
||||
public static final String VER = "2.0.1";
|
||||
/**
|
||||
* Rebuild Build
|
||||
*/
|
||||
public static final int BUILD = 20000;
|
||||
public static final int BUILD = 20001;
|
||||
|
||||
static {
|
||||
// Driver for DB
|
||||
|
@ -87,6 +89,9 @@ public class Application implements ApplicationListener<ApplicationStartedEvent>
|
|||
SerializeConfig.getGlobalInstance().put(Date.class, RbDateCodec.instance);
|
||||
SerializeConfig.getGlobalInstance().put(StandardRecord.class, RbRecordCodec.instance);
|
||||
SerializeConfig.getGlobalInstance().put(QueryedRecord.class, RbRecordCodec.instance);
|
||||
|
||||
JSON.DEFAULT_GENERATE_FEATURE |= SerializerFeature.DisableCircularReferenceDetect.getMask();
|
||||
JSON.DEFAULT_GENERATE_FEATURE |= SerializerFeature.WriteMapNullValue.getMask();
|
||||
}
|
||||
|
||||
// 服务启动状态
|
||||
|
@ -175,7 +180,7 @@ public class Application implements ApplicationListener<ApplicationStartedEvent>
|
|||
// 版本升级会清除缓存
|
||||
int lastBuild = ObjectUtils.toInt(RebuildConfiguration.get(ConfigurationItem.AppBuild, true), 0);
|
||||
if (lastBuild < BUILD) {
|
||||
LOG.warn("Clear all cache after the first upgrade : " + BUILD);
|
||||
LOG.warn("CLEAR ALL CACHE AFTER THE FIRST UPGRADE : " + BUILD);
|
||||
Installer.clearAllCache();
|
||||
RebuildConfiguration.set(ConfigurationItem.AppBuild, BUILD);
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ See LICENSE and COMMERCIAL in the project root for license information.
|
|||
package com.rebuild.core.service.trigger.impl;
|
||||
|
||||
import cn.devezhao.commons.CalendarUtils;
|
||||
import cn.devezhao.commons.ObjectUtils;
|
||||
import cn.devezhao.persist4j.Field;
|
||||
import cn.devezhao.persist4j.engine.ID;
|
||||
import cn.devezhao.persist4j.engine.NullValue;
|
||||
|
@ -19,6 +20,7 @@ import com.rebuild.core.support.general.FieldValueWrapper;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
|
@ -130,8 +132,14 @@ public class CompatibleValueConversion {
|
|||
}
|
||||
} else if (is2Text) {
|
||||
compatibleValue = FieldValueWrapper.instance.wrapFieldValue(sourceValue, sourceField);
|
||||
|
||||
} else if (sourceType == DisplayType.NUMBER && targetType == DisplayType.DECIMAL) {
|
||||
compatibleValue = BigDecimal.valueOf((Long) sourceValue);
|
||||
|
||||
} else if (sourceType == DisplayType.DECIMAL && targetType == DisplayType.NUMBER) {
|
||||
compatibleValue = ObjectUtils.toLong(sourceValue);
|
||||
|
||||
}
|
||||
// 整数/浮点数无需转换,因为持久层框架已有兼容处理
|
||||
|
||||
return compatibleValue;
|
||||
}
|
||||
|
|
|
@ -187,8 +187,7 @@ public class RebuildConfiguration extends KVStorage {
|
|||
* @return
|
||||
*/
|
||||
public static String get(ConfigurationItem name, boolean noCache) {
|
||||
if (name == ConfigurationItem.AppName && !License.isCommercial()) return "REBUILD";
|
||||
else return getValue(name.name(), noCache, name.getDefaultValue());
|
||||
return getValue(name.name(), noCache, name.getDefaultValue());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -67,7 +67,7 @@ public class AppUtils {
|
|||
* @see #getRequestUserViaRbMobile(HttpServletRequest, boolean)
|
||||
*/
|
||||
public static ID getRequestUser(HttpServletRequest request) {
|
||||
Object user = request.getSession(true).getAttribute(WebUtils.CURRENT_USER);
|
||||
Object user = request.getSession().getAttribute(WebUtils.CURRENT_USER);
|
||||
return user == null ? null : (ID) user;
|
||||
}
|
||||
|
||||
|
|
|
@ -77,6 +77,7 @@ public class HeavyTaskController extends BaseController {
|
|||
*/
|
||||
private JSON formatTaskState(HeavyTask<?> task) {
|
||||
JSONObject state = new JSONObject();
|
||||
state.put("total", task.getTotal());
|
||||
state.put("progress", task.getCompletedPercent());
|
||||
state.put("completed", task.getCompleted());
|
||||
state.put("succeeded", task.getSucceeded());
|
||||
|
|
|
@ -1195,7 +1195,7 @@
|
|||
"s.ApprovalState.REVOKED": "撤销",
|
||||
"s.HowtoState.DRAFT": "草稿",
|
||||
"s.HowtoState.PENDING": "处理中",
|
||||
"s.HowtoState.SOLVED": "已驳回",
|
||||
"s.HowtoState.SOLVED": "已解决",
|
||||
"s.HowtoState.REJECTED": "已驳回",
|
||||
"t.__": "字段类型",
|
||||
"t.NUMBER": "数字",
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
}
|
||||
|
||||
$btn.button('loading')
|
||||
$.post('admin-verify?passwd=' + passwd, function (res) {
|
||||
$.post('admin-verify?passwd=' + $encode(passwd), function (res) {
|
||||
if (res.error_code == 0) location.replace(nexturl)
|
||||
else {
|
||||
RbHighbar.create(res.error_msg)
|
||||
|
|
|
@ -75,16 +75,13 @@
|
|||
<div class="form-group row">
|
||||
<label class="col-md-12 col-xl-3 col-lg-4 col-form-label text-lg-right">[[${bundle.L('UploadSome,DataFile')}]]</label>
|
||||
<div class="col-md-12 col-xl-6 col-lg-8">
|
||||
<div class="float-left">
|
||||
<div class="file-select">
|
||||
<input type="file" class="inputfile" id="upload-input" accept=".xlsx,.xls,.csv" data-maxsize="52428800" />
|
||||
<label for="upload-input" class="btn-secondary"><i class="zmdi zmdi-upload"></i><span>[[${bundle.L('UploadFile')}]]</span></label>
|
||||
</div>
|
||||
<div class="file-select">
|
||||
<input type="file" class="inputfile" id="upload-input" accept=".xlsx,.xls,.csv" data-temp="true" data-maxsize="52428800" />
|
||||
<label for="upload-input" class="btn-secondary"><i class="zmdi zmdi-upload"></i><span>[[${bundle.L('UploadFile')}]]</span></label>
|
||||
</div>
|
||||
<div class="float-left ml-2 pt-1">
|
||||
<div>
|
||||
<u class="text-bold J_upload-input"></u>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
<div class="form-text mb-0">
|
||||
<ul class="mb-0 pl-4">
|
||||
<li>[[${bundle.L('ImportDataTips1')}]]</li>
|
||||
|
@ -123,7 +120,7 @@
|
|||
<div class="form-group row">
|
||||
<label class="col-md-12 col-xl-3 col-lg-4 col-form-label text-lg-right">[[${bundle.L('RecordOwningUser')}]]</label>
|
||||
<div class="col-md-12 col-xl-6 col-lg-8">
|
||||
<select class="form-control form-control-sm" id="toUser"></select>
|
||||
<div id="toUser"></div>
|
||||
<div class="form-text mb-0">[[${bundle.L('RecordOwningUserTips')}]]</div>
|
||||
<div id="user-warn"></div>
|
||||
</div>
|
||||
|
@ -166,7 +163,9 @@
|
|||
<div class="col-6"><h5 class="text-bold m-0 p-0 J_import_state">[[${bundle.L('DataReading')}]]</h5></div>
|
||||
<div class="col-6 text-right text-muted">[[${bundle.L('TimeConsuming')}]] <span class="J_import_time">00:00:00</span></div>
|
||||
</div>
|
||||
<div class="progress"></div>
|
||||
<div class="progress">
|
||||
<div class="progress-bar J_import-bar"></div>
|
||||
</div>
|
||||
<div class="mt-3">
|
||||
<button class="btn btn-danger btn-space J_step3-cancel" type="button">[[${bundle.L('InterruptImport')}]]</button>
|
||||
<a class="btn btn-link btn-space J_step3-logs hide" href="data-imports">[[${bundle.L('ContinueImport')}]]</a>
|
||||
|
|
|
@ -5,7 +5,8 @@ rebuild is dual-licensed under commercial and open source licenses (GPLv3).
|
|||
See LICENSE and COMMERCIAL in the project root for license information.
|
||||
*/
|
||||
|
||||
const ientry = {
|
||||
// 导入规则
|
||||
const _Config = {
|
||||
file: null,
|
||||
entity: null,
|
||||
repeat_opt: 1,
|
||||
|
@ -19,31 +20,6 @@ let import_inprogress = false
|
|||
let import_taskid
|
||||
|
||||
$(document).ready(() => {
|
||||
init_upload()
|
||||
|
||||
const fileds_render = (entity) => {
|
||||
if (!entity) return
|
||||
const $el = $('#repeatFields').empty()
|
||||
$.get(`/admin/data/data-imports/import-fields?entity=${entity}`, (res) => {
|
||||
$(res.data).each(function () {
|
||||
if (this.name === 'createdBy' || this.name === 'createdOn' || this.name === 'modifiedOn' || this.name === 'modifiedBy') return
|
||||
$('<option value="' + this.name + '">' + this.label + '</option>').appendTo($el)
|
||||
})
|
||||
|
||||
$el
|
||||
.select2({
|
||||
maximumSelectionLength: 3,
|
||||
placeholder: $L('SelectSome,Field'),
|
||||
})
|
||||
.on('change', function () {
|
||||
ientry.repeat_fields = $(this).val()
|
||||
})
|
||||
|
||||
fields_cached = res.data
|
||||
ientry.entity = entity
|
||||
})
|
||||
}
|
||||
|
||||
$.get('/commons/metadata/entities?detail=true', (res) => {
|
||||
$(res.data).each(function () {
|
||||
$('<option value="' + this.name + '">' + this.label + '</option>').appendTo('#toEntity')
|
||||
|
@ -54,122 +30,73 @@ $(document).ready(() => {
|
|||
allowClear: false,
|
||||
})
|
||||
.on('change', function () {
|
||||
fileds_render($(this).val())
|
||||
check_user()
|
||||
_renderRepeatFields($(this).val())
|
||||
_checkUserPrivileges()
|
||||
})
|
||||
if ($urlp('entity')) $toe.val($urlp('entity'))
|
||||
$toe.trigger('change')
|
||||
})
|
||||
|
||||
$createUploader('#upload-input', null, (res) => {
|
||||
_Config.file = res.key
|
||||
$('.J_upload-input').text($fileCutName(_Config.file))
|
||||
})
|
||||
|
||||
$('input[name=repeatOpt]').click(function () {
|
||||
ientry.repeat_opt = ~~$(this).val()
|
||||
if (ientry.repeat_opt === 3) $('.J_repeatFields').hide()
|
||||
_Config.repeat_opt = ~~$(this).val()
|
||||
if (_Config.repeat_opt === 3) $('.J_repeatFields').hide()
|
||||
else $('.J_repeatFields').show()
|
||||
})
|
||||
|
||||
$('#toUser')
|
||||
.select2({
|
||||
placeholder: $L('Default'),
|
||||
minimumInputLength: 1,
|
||||
ajax: {
|
||||
url: '/commons/search/search',
|
||||
delay: 300,
|
||||
data: function (params) {
|
||||
const query = {
|
||||
entity: 'User',
|
||||
quickFields: 'loginName,fullName,email,quickCode',
|
||||
q: params.term,
|
||||
}
|
||||
return query
|
||||
},
|
||||
processResults: function (data) {
|
||||
const rs = data.data.map((item) => {
|
||||
return item
|
||||
})
|
||||
return { results: rs }
|
||||
},
|
||||
},
|
||||
})
|
||||
.on('change', function () {
|
||||
ientry.owning_user = $(this).val() || null
|
||||
check_user()
|
||||
})
|
||||
const _onSelectUser = function (s, isRemove) {
|
||||
if (isRemove || !s) _Config.owning_user = null
|
||||
else _Config.owning_user = s.id
|
||||
}
|
||||
renderRbcomp(
|
||||
<UserSelector hideDepartment={true} hideRole={true} hideTeam={true} multiple={false} onSelectItem={(s, isRemove) => _onSelectUser(s, isRemove)} onClearSelection={() => _onSelectUser()} />,
|
||||
'toUser'
|
||||
)
|
||||
|
||||
$('.J_step1-btn').click(step_mapping)
|
||||
$('.J_step2-btn').click(step_import)
|
||||
$('.J_step2-return').click(step_upload)
|
||||
$('.J_step3-cancel').click(import_cancel)
|
||||
|
||||
window.onbeforeunload = function () {
|
||||
if (import_inprogress === true) return false
|
||||
}
|
||||
import_taskid = $urlp('task', location.hash)
|
||||
if (import_taskid) {
|
||||
step_import_show()
|
||||
import_inprogress = true
|
||||
import_state(import_taskid, true)
|
||||
}
|
||||
|
||||
window.onbeforeunload = function () {
|
||||
if (import_inprogress === true) return false
|
||||
}
|
||||
})
|
||||
|
||||
const init_upload = () => {
|
||||
$('#upload-input').html5Uploader({
|
||||
postUrl: rb.baseUrl + '/filex/upload?temp=yes',
|
||||
onSelectError: function (field, error) {
|
||||
if (error === 'ErrorType') RbHighbar.create($L('PlsUploadSomeFile').replace('%s', 'EXCEL/CSV '))
|
||||
else if (error === 'ErrorMaxSize') RbHighbar.create($L('ExceedMaxLimit') + ' (50MB)')
|
||||
},
|
||||
onClientLoad: function () {
|
||||
$mp.start()
|
||||
},
|
||||
onSuccess: function (d) {
|
||||
$mp.end()
|
||||
d = JSON.parse(d.currentTarget.response)
|
||||
if (d.error_code === 0) {
|
||||
ientry.file = d.data
|
||||
$('.J_upload-input').text($fileCutName(ientry.file))
|
||||
} else {
|
||||
RbHighbar.error($L('ErrorUpload'))
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// 检查所属用户权限
|
||||
const check_user = () => $setTimeout(check_user0, 200, 'check_user')
|
||||
const check_user0 = () => {
|
||||
if (!ientry.entity || !ientry.owning_user) return
|
||||
$.get(`/admin/data/data-imports/check-user?user=${ientry.owning_user}&entity=${ientry.entity}`, (res) => {
|
||||
let hasError = []
|
||||
if (res.data.canCreate !== true) hasError.push($L('Create'))
|
||||
if (res.data.canUpdate !== true) hasError.push($L('Update'))
|
||||
if (hasError.length > 0) {
|
||||
renderRbcomp(<RbAlertBox message={$L('SelectUserNoPermissionConfirm').replace('%s', hasError.join('/'))} />, 'user-warn')
|
||||
} else {
|
||||
$('#user-warn').empty()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 1. 初始导入
|
||||
const step_upload = () => {
|
||||
$('.steps li, .step-content .step-pane').removeClass('active complete')
|
||||
$('.steps li[data-step=1], .step-content .step-pane[data-step=1]').addClass('active')
|
||||
}
|
||||
|
||||
// 2. 字段映射
|
||||
const step_mapping = () => {
|
||||
if (!ientry.entity) {
|
||||
if (!_Config.entity) {
|
||||
RbHighbar.create($L('PlsSelectSome,ImportEntity'))
|
||||
return
|
||||
}
|
||||
if (!ientry.file) {
|
||||
if (!_Config.file) {
|
||||
RbHighbar.create($L('PlsUploadSome,DataFile'))
|
||||
return
|
||||
}
|
||||
if (ientry.repeat_opt !== 3 && (!ientry.repeat_fields || ientry.repeat_fields.length === 0)) {
|
||||
if (_Config.repeat_opt !== 3 && (!_Config.repeat_fields || _Config.repeat_fields.length === 0)) {
|
||||
RbHighbar.create($L('PlsSelectSome,DuplicateFields'))
|
||||
return
|
||||
}
|
||||
|
||||
const $btn = $('.J_step1-btn').button('loading')
|
||||
$.get(`/admin/data/data-imports/check-file?file=${$encode(ientry.file)}`, (res) => {
|
||||
$.get(`/admin/data/data-imports/check-file?file=${$encode(_Config.file)}`, (res) => {
|
||||
$btn.button('reset')
|
||||
if (res.error_code > 0) {
|
||||
RbHighbar.create(res.error_msg)
|
||||
|
@ -188,6 +115,8 @@ const step_mapping = () => {
|
|||
$('.steps li[data-step=2], .step-content .step-pane[data-step=2]').addClass('active')
|
||||
})
|
||||
}
|
||||
|
||||
// 3. 开始导入
|
||||
const step_import = () => {
|
||||
let fm = {}
|
||||
$('#fieldsMapping tbody>tr').each(function () {
|
||||
|
@ -206,12 +135,12 @@ const step_import = () => {
|
|||
}
|
||||
})
|
||||
if (!fm) return
|
||||
ientry.fields_mapping = fm
|
||||
_Config.fields_mapping = fm
|
||||
|
||||
RbAlert.create($L('DataImportConfirm'), {
|
||||
confirm: function () {
|
||||
this.disabled(true)
|
||||
$.post('/admin/data/data-imports/import-submit', JSON.stringify(ientry), (res) => {
|
||||
$.post('/admin/data/data-imports/import-submit', JSON.stringify(_Config), (res) => {
|
||||
if (res.error_code === 0) {
|
||||
this.hide()
|
||||
step_import_show()
|
||||
|
@ -224,11 +153,15 @@ const step_import = () => {
|
|||
},
|
||||
})
|
||||
}
|
||||
|
||||
// 3.1. 开始导入
|
||||
const step_import_show = () => {
|
||||
$('.steps li, .step-content .step-pane').removeClass('active complete')
|
||||
$('.steps li[data-step=1], .steps li[data-step=2]').addClass('complete')
|
||||
$('.steps li[data-step=3], .step-content .step-pane[data-step=3]').addClass('active')
|
||||
}
|
||||
|
||||
// 3.2. 导入状态
|
||||
const import_state = (taskid, inLoad) => {
|
||||
$.get(`/commons/task/state?taskid=${taskid}`, (res) => {
|
||||
if (res.error_code !== 0) {
|
||||
|
@ -243,7 +176,7 @@ const import_state = (taskid, inLoad) => {
|
|||
}
|
||||
|
||||
const _data = res.data
|
||||
$('.J_import_time').text(sec_to_time(~~_data.elapsedTime / 1000))
|
||||
$('.J_import_time').text(_secToTime(~~_data.elapsedTime / 1000))
|
||||
|
||||
if (_data.isCompleted === true) {
|
||||
$('.J_import-bar').css('width', '100%')
|
||||
|
@ -251,6 +184,7 @@ const import_state = (taskid, inLoad) => {
|
|||
} else if (_data.isInterrupted === true) {
|
||||
$('.J_import_state').text($L('ImportInterrupttedTips').replace('%d', _data.succeeded))
|
||||
}
|
||||
|
||||
if (_data.isCompleted === true || _data.isInterrupted === true) {
|
||||
$('.J_step3-cancel').attr('disabled', true).text($L('ImportFinshed'))
|
||||
$('.J_step3-logs').removeClass('hide')
|
||||
|
@ -258,15 +192,18 @@ const import_state = (taskid, inLoad) => {
|
|||
return
|
||||
}
|
||||
|
||||
if (_data.total > -1) {
|
||||
if (_data.progress > 0) {
|
||||
$('.J_import_state').text($L('DataImporting') + ' ' + _data.completed + '/' + _data.total)
|
||||
$('.J_import-bar').css('width', _data.progress * 100 + '%')
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
import_state(taskid)
|
||||
}, 500)
|
||||
})
|
||||
}
|
||||
|
||||
// 3.3. 中断导入
|
||||
const import_cancel = () => {
|
||||
RbAlert.create($L('ImportInterrupttedConfirm'), {
|
||||
type: 'danger',
|
||||
|
@ -319,7 +256,8 @@ const render_fieldsMapping = (columns, fields) => {
|
|||
})
|
||||
}
|
||||
|
||||
const sec_to_time = function (s) {
|
||||
// 格式化秒显示
|
||||
function _secToTime(s) {
|
||||
if (!s || s <= 0) return '00:00:00'
|
||||
let hh = Math.floor(s / 3600)
|
||||
let mm = Math.floor(s / 60) % 60
|
||||
|
@ -329,3 +267,42 @@ const sec_to_time = function (s) {
|
|||
if (ss < 10) ss = '0' + ss
|
||||
return hh + ':' + mm + ':' + ss
|
||||
}
|
||||
|
||||
// 检查所属用户权限
|
||||
function _checkUserPrivileges() {
|
||||
if (!_Config.entity || !_Config.owning_user) return
|
||||
$.get(`/admin/data/data-imports/check-user?user=${_Config.owning_user}&entity=${_Config.entity}`, (res) => {
|
||||
let hasError = []
|
||||
if (res.data.canCreate !== true) hasError.push($L('Create'))
|
||||
if (res.data.canUpdate !== true) hasError.push($L('Update'))
|
||||
if (hasError.length > 0) {
|
||||
renderRbcomp(<RbAlertBox message={$L('SelectUserNoPermissionConfirm').replace('%s', hasError.join('/'))} />, 'user-warn')
|
||||
} else {
|
||||
$('#user-warn').empty()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 渲染重复判断字段
|
||||
function _renderRepeatFields(entity) {
|
||||
if (!entity) return
|
||||
const $el = $('#repeatFields').empty()
|
||||
$.get(`/admin/data/data-imports/import-fields?entity=${entity}`, (res) => {
|
||||
$(res.data).each(function () {
|
||||
if (this.name === 'createdBy' || this.name === 'createdOn' || this.name === 'modifiedOn' || this.name === 'modifiedBy') return
|
||||
$('<option value="' + this.name + '">' + this.label + '</option>').appendTo($el)
|
||||
})
|
||||
|
||||
$el
|
||||
.select2({
|
||||
maximumSelectionLength: 3,
|
||||
placeholder: $L('SelectSome,Field'),
|
||||
})
|
||||
.on('change', function () {
|
||||
_Config.repeat_fields = $(this).val()
|
||||
})
|
||||
|
||||
fields_cached = res.data
|
||||
_Config.entity = entity
|
||||
})
|
||||
}
|
||||
|
|
|
@ -205,7 +205,7 @@ class DlgEnableUser extends RbModalHandler {
|
|||
}
|
||||
if (this._roleAppends) {
|
||||
data.roleAppends = this._roleAppends.val().join(',')
|
||||
if (data.roleAppends && rb.commercial > 0) {
|
||||
if (data.roleAppends && rb.commercial < 1) {
|
||||
return RbHighbar.error($L('FreeVerNotSupportted,AppendRoles'))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -557,7 +557,9 @@ class UserSelector extends React.Component {
|
|||
}
|
||||
|
||||
clearSelection() {
|
||||
this.setState({ selected: [] })
|
||||
this.setState({ selected: [] }, () => {
|
||||
typeof this.props.onClearSelection === 'function' && this.props.onClearSelection()
|
||||
})
|
||||
}
|
||||
|
||||
switchTab(type) {
|
||||
|
@ -587,7 +589,7 @@ class UserSelector extends React.Component {
|
|||
const st = $(this._scroller).scrollTop()
|
||||
const et = $el.position().top
|
||||
if (et >= 0) {
|
||||
const top = et + st - (222 - 36) // maxHeight - elementHeight
|
||||
const top = et + st - (222 - 36) // maxHeight - elementHeight
|
||||
if (top > 0) $(this._scroller).scrollTop(top)
|
||||
} else {
|
||||
const top = st + et
|
||||
|
@ -620,14 +622,14 @@ class UserSelector extends React.Component {
|
|||
})
|
||||
}
|
||||
|
||||
clickItem(e) {
|
||||
clickItem(e, isRemove) {
|
||||
const $target = $(e.currentTarget)
|
||||
const id = $target.data('id') || $target.parents('.select2-results__option').data('id')
|
||||
|
||||
let exists = false
|
||||
let ns = []
|
||||
// 单选
|
||||
if (this.props.multiple !== false) {
|
||||
if (this.props.multiple !== false || isRemove) {
|
||||
ns = this.state.selected.filter((x) => {
|
||||
if (x.id === id) {
|
||||
exists = true
|
||||
|
@ -646,7 +648,7 @@ class UserSelector extends React.Component {
|
|||
}
|
||||
|
||||
this.setState({ selected: ns }, () => {
|
||||
typeof this.props.onSelectItem === 'function' && this.props.onSelectItem(selected)
|
||||
typeof this.props.onSelectItem === 'function' && this.props.onSelectItem(selected, isRemove)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue