This commit is contained in:
devezhao-corp 2018-10-10 22:32:25 +08:00
parent ebad4335cf
commit dae6ff0a03
14 changed files with 19953 additions and 163 deletions

View file

@ -137,7 +137,12 @@ public class AccessibleMeta implements BaseMeta {
return dt;
}
Type ft = ((Field) baseMeta).getType();
Field field = (Field) baseMeta;
if (field.getOwnEntity().getEntityCode() == EntityHelper.User && "email".equals(field.getName())) {
return DisplayType.EMAIL;
}
Type ft = field.getType();
if (ft == FieldType.PRIMARY) {
return DisplayType.ID;
} else if (ft == FieldType.REFERENCE) {

View file

@ -77,8 +77,8 @@ public class FormManager extends LayoutManager {
* @param entity
* @return
*/
public static JSON getFormModal(String entity, ID user) {
return getFormModal(entity, user, null);
public static JSON getFormModel(String entity, ID user) {
return getFormModel(entity, user, null);
}
/**
@ -89,7 +89,7 @@ public class FormManager extends LayoutManager {
* @param recordId
* @return
*/
public static JSON getFormModal(String entity, ID user, ID recordId) {
public static JSON getFormModel(String entity, ID user, ID recordId) {
Assert.notNull(entity, "[entity] not be null");
Assert.notNull(user, "[user] not be null");
@ -102,7 +102,7 @@ public class FormManager extends LayoutManager {
Record record = null;
if (!elements.isEmpty() && recordId != null) {
record = record(recordId, elements);
record = queryRecord(recordId, elements);
}
for (Object element : elements) {
@ -178,9 +178,9 @@ public class FormManager extends LayoutManager {
* @param recordId
* @return
*/
public static JSON getViewModal(String entity, ID user, ID recordId) {
public static JSON getViewModel(String entity, ID user, ID recordId) {
Assert.notNull(recordId, "[recordId] not be null");
return getFormModal(entity, user, recordId);
return getFormModel(entity, user, recordId);
}
/**
@ -188,7 +188,7 @@ public class FormManager extends LayoutManager {
* @param elements
* @return
*/
protected static Record record(ID id, JSONArray elements) {
protected static Record queryRecord(ID id, JSONArray elements) {
if (elements.isEmpty()) {
return null;
}

View file

@ -24,6 +24,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@ -44,10 +45,9 @@ import cn.devezhao.persist4j.engine.ID;
* @since 10/08/2018
*/
@Controller
@RequestMapping("/admin/bizuser/")
public class UserControll extends BaseControll {
@RequestMapping("users")
@RequestMapping("/admin/bizuser/users")
public ModelAndView pageList(HttpServletRequest request) throws IOException {
ModelAndView mv = createModelAndView("/admin/bizuser/user-list.jsp", "User");
JSON cfg = DataListManager.getColumnLayout("User");
@ -55,7 +55,15 @@ public class UserControll extends BaseControll {
return mv;
}
@RequestMapping("dept-tree")
@RequestMapping("/app/User/view/{id}")
public ModelAndView pageView(@PathVariable String id, HttpServletRequest request) throws IOException {
ID recordId = ID.valueOf(id);
ModelAndView mv = createModelAndView("/admin/bizuser/user-view.jsp", "User");
mv.getModel().put("id", recordId);
return mv;
}
@RequestMapping("/admin/bizuser/dept-tree")
public void deptTreeGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
Object[][] firstDepts = Application.createQuery(
"select deptId from Department where parentDept is null")

View file

@ -52,21 +52,21 @@ public class GeneralEntityControll extends BaseControll {
return mv;
}
@RequestMapping("{entity}/form-modal")
@RequestMapping("{entity}/form-model")
public void entityForm(@PathVariable String entity,
HttpServletRequest request, HttpServletResponse response) throws IOException {
ID recordId = getIdParameter(request, "id");
JSON fc = FormManager.getFormModal(entity, getRequestUser(request), recordId);
JSON fc = FormManager.getFormModel(entity, getRequestUser(request), recordId);
writeSuccess(response, fc);
}
@RequestMapping("{entity}/view-modal")
@RequestMapping("{entity}/view-model")
public void entityView(@PathVariable String entity,
HttpServletRequest request, HttpServletResponse response) throws IOException {
ID user = getRequestUser(request);
ID recordId = getIdParameterNotNull(request, "id");
JSON modal = FormManager.getViewModal(entity, user, recordId);
JSON modal = FormManager.getViewModel(entity, user, recordId);
writeSuccess(response, modal);
}
}

View file

@ -11,6 +11,6 @@
<script src="${baseUrl}/assets/js/rb-base.js"></script>
<script src="${baseUrl}/assets/js/rb-page.js"></script>
<script src="${baseUrl}/assets/lib/react/babel.min.js"></script>
<script src="${baseUrl}/assets/lib/react/react.production.min.js"></script>
<script src="${baseUrl}/assets/lib/react/react-dom.production.min.js"></script>
<script src="${baseUrl}/assets/lib/react/react.development.js"></script>
<script src="${baseUrl}/assets/lib/react/react-dom.development.js"></script>
<script src="${baseUrl}/assets/js/rb-components.jsx" type="text/babel"></script>

View file

@ -0,0 +1,57 @@
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<%@ include file="/_include/Head.jsp"%>
<title>${entityLabel}视图</title>
<style type="text/css">
html,body{overflow:auto;height:100%;}
.main-content{margin-top:62px;}
.tab-container{margin-top:-8px}
.tab-content{padding:0;margin:0;padding-top:13px}
.view-header{padding:15px 20px;height:62px;border-bottom:1px solid #e3e3e3;position:absolute;top:0;left:0;width:100%;z-index:101;background-color:#fff}
.view-header .header-icon{float:left;}
.view-header .title{line-height:1.428571;display:inline-block;margin:0;font-weight:300;font-size:1.538rem}
.view-oper{}
.view-oper .btns{padding-bottom:15px;}
.view-oper .btns .btn{width:100%;}
.view-oper .btns .btn+.btn{margin-top:6px}
</style>
</head>
<body class="dialog">
<div class="view-header">
<span class="header-icon zmdi zmdi-${entityIcon}"></span>
<h3 class="title">${entityLabel}视图</h3>
</div>
<div class="main-content container-fluid invisible">
<div class="row">
<div class="col-sm-10">
<div id="tab-rbview"></div>
</div>
<div class="col-sm-2">
<div class="view-oper">
<div class="btns">
<button class="btn btn-secondary J_edit" type="button">编辑</button>
</div>
</div>
</div>
</div>
</div>
<%@ include file="/_include/Foot.jsp"%>
<script src="${baseUrl}/assets/js/rb-forms.jsx" type="text/babel"></script>
<script src="${baseUrl}/assets/js/rb-forms-ext.jsx" type="text/babel"></script>
<script src="${baseUrl}/assets/js/rb-view.jsx" type="text/babel"></script>
<script type="text/babel">
var rbFromView
$(document).ready(function(){
const recordId = '${id}'
rbFromView = renderRbcomp(<RbViewForm entity="${entityName}" id={recordId} />, 'tab-rbview')
$('.J_edit').click(function(){
renderRbFormModal(recordId, '编辑记录', '${entityName}', '${entityIcon}')
});
});
</script>
</body>
</html>

View file

@ -277,10 +277,11 @@ a {
width: 100%;
height: 100%;
}
.img-field.avatar label.img-upload {
.img-field.avatar .img-upload {
border-radius: 50%;
overflow: hidden;
padding: 0;
border: 0 none;
}
.img-field.avatar label.img-upload:hover{
border: 0 none;

View file

@ -14,7 +14,7 @@ class RbModal extends React.Component {
<button className="close" type="button" onClick={()=>this.hide()}><span className="zmdi zmdi-close"></span></button>
</div>
<div className={'modal-body rb-loading ' + (this.state.inLoad == true && ' rb-loading-active') + ' ' + (this.state.url && ' iframe')}>
{this.props.children || <iframe src={this.state.url || 'about:blank'} frameborder="0" scrolling="no" onLoad={()=>this.resize()} onResize={()=>this.resize()}></iframe>}
{this.props.children || <iframe src={this.state.url || 'about:blank'} frameBorder="0" scrolling="no" onLoad={()=>this.resize()} onResize={()=>this.resize()}></iframe>}
<RbSpinner />
</div>
</div>
@ -77,7 +77,7 @@ class RbAlter extends React.Component {
<h4>{this.props.title || '提示'}</h4>
{content}
<div className="mt-6 mb-4">
<button class="btn btn-space btn-secondary" type="button" onClick={()=>this.hide()}>取消</button>
<button className="btn btn-space btn-secondary" type="button" onClick={()=>this.hide()}>取消</button>
<button className={'btn btn-space btn-' + type} type="button" onClick={confirm}>确定</button>
</div>
</div>
@ -136,7 +136,7 @@ class RbNotice extends React.Component {
function RbSpinner(props) {
return <div className="rb-spinner">
<svg width="40px" height="40px" viewBox="0 0 66 66" xmlns="http://-www.w3.org/2000/svg">
<circle fill="none" stroke-width="4" stroke-linecap="round" cx="33" cy="33" r="30" class="circle"></circle>
<circle fill="none" strokeWidth="4" strokeLinecap="round" cx="33" cy="33" r="30" className="circle"></circle>
</svg>
</div>
}

View file

@ -13,11 +13,13 @@ class RbFormBool extends RbFormElement {
renderElement() {
return (
<div>
<label className="custom-control custom-radio custom-control-inline" onClick={this.changeValue.bind(this, 'T')}>
<input className="custom-control-input" name="radio-inline" type="radio" value="F" checked={this.state.value == 'T'}/><span className="custom-control-label"></span>
<label className="custom-control custom-radio custom-control-inline">
<input className="custom-control-input" name={'radio-' + this.props.field} type="radio" checked={this.state.value == 'T'} onChange={this.changeValue.bind(this, 'T')} />
<span className="custom-control-label"></span>
</label>
<label className="custom-control custom-radio custom-control-inline" onClick={this.changeValue.bind(this, 'F')}>
<input className="custom-control-input" name="radio-inline" type="radio" value="T" checked={this.state.value == 'F'}/><span className="custom-control-label"></span>
<label className="custom-control custom-radio custom-control-inline">
<input className="custom-control-input" name={'radio-' + this.props.field} type="radio" checked={this.state.value == 'F'} onChange={this.changeValue.bind(this, 'F')} />
<span className="custom-control-label"></span>
</label>
</div>
)
@ -33,14 +35,26 @@ class RbFormAvatar extends RbFormElement {
super(props)
}
renderElement() {
let avatarUrl = rb.storageUrl + (this.state.value || 'rebuild/20181010/041046550__avatar.png') + '?imageView2/2/w/100/interlace/1/q/100'
return (
<div className="img-field avatar">
<span title="选择头像图片">
<input type="file" className="inputfile" ref="upload-input" id={this.props.field + '-input'} accept="image/*" />
<label for={this.props.field + '-input'} class="img-thumbnail img-upload"><img src={avatarUrl}/></label>
<label htmlFor={this.props.field + '-input'} className="img-thumbnail img-upload">
<img src={rb.storageUrl + (this.state.value || 'rebuild/20181010/041046550__avatar.png') + '?imageView2/2/w/100/interlace/1/q/100'}/>
</label>
</span>
</div>)
</div>
)
}
renderViewElement() {
let avatarUrl = rb.storageUrl + (this.props.value || 'rebuild/20181010/041046550__avatar.png') + '?imageView2/2/w/100/interlace/1/q/100'
return (
<div className="img-field avatar">
<a className="img-thumbnail img-upload">
<img src={rb.storageUrl + (this.state.value || 'rebuild/20181010/041046550__avatar.png') + '?imageView2/2/w/100/interlace/1/q/100'}/>
</a>
</div>
)
}
componentDidMount() {
super.componentDidMount()
@ -50,15 +64,15 @@ class RbFormAvatar extends RbFormElement {
postUrl: rb.baseUrl + '/filex/upload?cloud=auto&type=image',
onClientLoad: function(e, file){
if (file.type.substr(0, 5) != 'image'){
that.props.$$$parent.showNotice('请上传图片')
rb.notice('请上传图片')
return false
}
},
onSuccess:function(d){
d = JSON.parse(d.currentTarget.response)
if (d.error_code == 0){
that.handleChange({ target:{ value: d.data } }, false)
} else that.showNotice(d.error_msg || '上传失败,请稍后重试')
that.handleChange({ target:{ value: d.data } }, true)
} else rb.notice(d.error_msg || '上传失败,请稍后重试', 'danger')
}
})
}

View file

@ -28,14 +28,15 @@ class RbFormModal extends React.Component {
}
componentDidMount() {
this.show()
if (!!!this.state.id) this.__getFormModal()
if (!!!this.state.id) this.getFormModel()
}
//
__getFormModal() {
getFormModel() {
let that = this
const entity = this.state.entity
const id = this.state.id || ''
$.get(rb.baseUrl + '/app/' + entity + '/form-modal?entity=' + entity + '&id=' + id, function(res){
$.get(rb.baseUrl + '/app/' + entity + '/form-model?entity=' + entity + '&id=' + id, function(res){
let elements = res.data.elements
const FORM = <RbForm entity={entity} id={id} $$$parent={that}>
{elements.map((item) => {
@ -47,36 +48,35 @@ class RbFormModal extends React.Component {
})
})
}
show(state) {
state = state || {}
let that = this
if (state.id != this.state.id || state.entity != this.state.entity) {
state = { ...state, isDestroy: true, formComponent: null, inLoad: true }
this.setState(state, function(){
that.__show({ ...state, isDestroy: false }, true)
that.showAfter({ ...state, isDestroy: false }, true)
})
} else {
this.__show({ ...state, isDestroy: false })
this.showAfter({ ...state, isDestroy: false })
}
}
__show(state, idChanged) {
showAfter(state, modelChanged) {
let that = this
this.setState(state, function(){
$(that.refs['rbmodal']).modal({ show: true, backdrop: 'static' })
if (idChanged == true) {
that.__getFormModal()
if (modelChanged == true) {
that.getFormModel()
}
})
}
hide(destroy) {
$(this.refs['rbmodal']).modal('hide')
let state = { noticeMessage: null, isDestroy: false }
if (destroy == true) state = { ...state, isDestroy: true, id: null }
let state = { isDestroy: false }
if (destroy === true) state = { ...state, isDestroy: true, id: null }
this.setState(state)
}
showNotice(message, type) {
rb.notice(message, type, { html: true })
}
}
// ~~
@ -87,7 +87,6 @@ class RbForm extends React.Component {
this.__FormData = {}
this.setFieldValue = this.setFieldValue.bind(this)
this.showNotice = this.showNotice.bind(this)
}
render() {
let that = this
@ -95,68 +94,73 @@ class RbForm extends React.Component {
<div className="rbform">
<form>
{this.props.children.map((child) => {
child.props.$$$parent = that
return child
return React.cloneElement(child, { $$$parent: that })
// strict mode have error
// child.$$$parent = that
// return child
})}
{this.props.children.length == 0 ? this.__renderFormError() :
(<div className="form-group row footer">
<div className="col-12 col-sm-8 offset-sm-3" ref="rbform-action">
<button className="btn btn-primary btn-space" type="button" onClick={()=>this.post()}>保存</button>
&nbsp;
<button className="btn btn-secondary btn-space" type="button" onClick={()=>this.props.$$$parent.hide()}>取消</button>
</div>
</div>)
}
{this.props.children.length == 0 ? this.renderFormError() : this.renderFormAction()}
</form>
</div>
)
}
__renderFormError(message) {
let fdUrl = rb.baseUrl + '/admin/entity/' + this.props.entity + '/form-design'
message = message || `布局尚未配置,请 <a href="${fdUrl}">配置</a> 后使用`
renderFormAction() {
return (
<div className="form-group row footer">
<div className="col-12 col-sm-8 offset-sm-3" ref="rbform-action">
<button className="btn btn-primary btn-space" type="button" onClick={()=>this.post()}>保存</button>
&nbsp;
<button className="btn btn-secondary btn-space" type="button" onClick={()=>this.props.$$$parent.hide()}>取消</button>
</div>
</div>
)
}
renderFormError(message) {
let adminUrl = rb.baseUrl + '/admin/entity/' + this.props.entity + '/form-design'
message = message || `布局尚未配置,请 <a href="${adminUrl}">配置</a> 后使用`
message = { __html: '<strong>错误! </strong> ' + message }
return <div class="alert alert-contrast alert-warning">
<div class="icon"><span class="zmdi zmdi-alert-triangle"></span></div>
<div class="message" dangerouslySetInnerHTML={message}></div>
return <div className="alert alert-contrast alert-warning">
<div className="icon"><span className="zmdi zmdi-alert-triangle"></span></div>
<div className="message" dangerouslySetInnerHTML={message}></div>
</div>
}
componentDidMount() {
}
setFieldValue(field, value, error) {
this.__FormData[field] = { value:value, error:error }
console.log('Set data ... ' + JSON.stringify(this.__FormData))
this.__FormData[field] = { value: value, error: error }
console.log('Sets field-value ... ' + JSON.stringify(this.__FormData))
}
showNotice(message, type) {
this.props.$$$parent.showNotice(message, type)
setFieldUnchanged(field) {
delete this.__FormData[field]
console.log('Unchanged field-value ... ' + JSON.stringify(this.__FormData))
}
post() {
console.log('Post data ... ' + JSON.stringify(this.__FormData))
// Check Error
let _data = {}
for (let k in this.__FormData) {
let err = this.__FormData[k].error
if (err){ this.showNotice(err); return }
if (err){ rb.notice(err); return }
else _data[k] = this.__FormData[k].value
}
_data.metadata = { entity: this.state.entity, id: this.state.id }
let actions = $(this.refs['rbform-action']).find('.btn').button('loading')
let btns = $(this.refs['rbform-action']).find('.btn').button('loading')
let that = this
$.post(rb.baseUrl + '/app/entity/record-save', JSON.stringify(_data), function(res){
actions.button('reset')
btns.button('reset')
if (res.error_code == 0){
that.showNotice('保存成功', 'success')
rb.notice('保存成功', 'success')
that.props.$$$parent.hide(true)
if (window.formPostAfterCall) window.formPostAfterCall()
}else{
that.showNotice(res.error_msg || '保存失败,请稍后重试', 'danger')
rb.notice(res.error_msg || '保存失败,请稍后重试', 'danger')
}
})
}
}
//
//
class RbFormElement extends React.Component {
constructor(props) {
super(props)
@ -165,46 +169,62 @@ class RbFormElement extends React.Component {
this.handleChange = this.handleChange.bind(this)
this.checkError = this.checkError.bind(this)
}
render() {
let colWidths = [3, 8]
if (this.props.onView) {
colWidths[0] = 4
if (this.props.isFull) colWidths = [2, 10]
if (this.props.isFull == true) colWidths = [2, 10]
}
return (
<div className={'form-group row type-' + this.props.type}>
<label className={'col-12 col-form-label text-sm-right col-sm-' + colWidths[0]} title={this.props.nullable ? '' : '必填项'}>{this.props.label}{!this.props.nullable && <em/>}</label>
<div className={'col-12 col-sm-' + colWidths[1]}>
{this.state.editMode === false ? this.renderViewElement() : this.renderElement()}
{this.state.viewMode === true ? this.renderViewElement() : this.renderElement()}
</div>
</div>
)
}
componentDidMount(e) {
let props = this.props
if (props.nullable == false && props.readonly == false) {
if (props.onView === true) {
} else {
this.props.$$$parent.setFieldValue(this.props.field, null, this.props.label + '不能为空')
}
}
}
renderViewElement() {
return <div className="form-control-plaintext">{this.state.value || (<span className="text-muted"></span>)}</div>
}
renderElement() {
return '子类复写此方法'
}
handleChange(event, fireCheckError) {
componentDidMount(e) {
let props = this.props
//
if (props.nullable == false && props.readonly == false && props.onView != true) {
if (!props.value) {
props.$$$parent.setFieldValue(props.field, null, props.label + '不能为空')
}
}
}
//
handleChange(event, checkError) {
let val = event.target.value
let that = this
this.setState({ value: val }, fireCheckError && function(){ that.checkError() })
this.setState({ value: val }, function(){ checkError == true && that.checkError() } )
}
checkError() {
// Unchanged Uncheck
if (this.state.value && this.props.value == this.state.value) {
if (this.__lastValue != this.props.value) {
this.props.$$$parent.setFieldUnchanged(this.props.field)
this.__lastValue = this.props.value
}
return
}
if (this.__lastValue && this.__lastValue == this.state.value) {
return
}
this.__lastValue = this.state.value
let err = this.checkHasError()
this.setState({ hasError: err })
let errTips = !!err ? (this.props.label + err) : null
this.props.$$$parent.setFieldValue(this.props.field, this.state.value, errTips)
let errMsg = !!err ? (this.props.label + err) : null
this.props.$$$parent.setFieldValue(this.props.field, this.state.value, errMsg)
}
checkHasError(){
if (this.props.nullable == false) {
@ -233,7 +253,7 @@ class RbFormText extends RbFormElement {
}
renderElement() {
return (
<input ref="field-value" className={'form-control form-control-sm ' + (this.state.hasError ? 'is-invalid' : '')} title={this.state.hasError} type="text" value={this.state.value} data-nullable={this.props.nullable} onChange={this.handleChange} onBlur={this.checkError} />
<input ref="field-value" className={'form-control form-control-sm ' + (this.state.hasError ? 'is-invalid' : '')} title={this.state.hasError} type="text" value={this.state.value} onChange={this.handleChange} onBlur={this.checkError} />
)
}
}
@ -245,14 +265,13 @@ class RbFormUrl extends RbFormText {
}
renderViewElement() {
if (!!!this.state.value) return super.renderViewElement()
let link = rb.baseUrl + '/commons/url-safe?url=' + encodeURIComponent(this.state.value)
return (<div className="form-control-plaintext"><a href={link} className="link" target="_blank">{this.state.value}</a></div>)
let clickUrl = rb.baseUrl + '/commons/url-safe?url=' + encodeURIComponent(this.state.value)
return (<div className="form-control-plaintext"><a href={clickUrl} className="link" target="_blank">{this.state.value}</a></div>)
}
checkHasError() {
let err = super.checkHasError()
if (err) return err
let val = this.state.value
return (!!val && $regex.isUrl(val) == false) ? '链接格式不正确' : null
return (!!this.state.value && $regex.isUrl(this.state.value) == false) ? '链接格式不正确' : null
}
}
@ -268,8 +287,7 @@ class RbFormEMail extends RbFormText {
checkHasError() {
let err = super.checkHasError()
if (err) return err
let val = this.state.value
return (!!val && $regex.isMail(val) == false) ? '邮箱格式不正确' : null
return (!!this.state.value && $regex.isMail(this.state.value) == false) ? '邮箱格式不正确' : null
}
}
@ -281,8 +299,7 @@ class RbFormPhone extends RbFormText {
checkHasError() {
let err = super.checkHasError()
if (err) return err
let val = this.state.value
return (!!val && $regex.isTel(val) == false) ? '电话/手机格式不正确' : null
return (!!this.state.value && $regex.isTel(this.state.value) == false) ? '电话/手机格式不正确' : null
}
}
@ -294,8 +311,7 @@ class RbFormNumber extends RbFormText {
checkHasError() {
let err = super.checkHasError()
if (err) return err
let val = this.state.value
return (!!val && $regex.isNumber(val) == false) ? '整数格式不正确' : null
return (!!this.state.value && $regex.isNumber(this.state.value) == false) ? '整数格式不正确' : null
}
}
@ -307,8 +323,7 @@ class RbFormDecimal extends RbFormText {
checkHasError() {
let err = super.checkHasError()
if (err) return err
let val = this.state.value
return (!!val && $regex.isDecimal(val) == false) ? '货币格式不正确' : null
return (!!this.state.value && $regex.isDecimal(this.state.value) == false) ? '货币格式不正确' : null
}
}
@ -319,7 +334,7 @@ class RbFormTextarea extends RbFormElement {
}
renderElement() {
return (
<textarea ref="field-value" className={'form-control form-control-sm row3x ' + (this.state.hasError ? 'is-invalid' : '')} title={this.state.hasError} value={this.state.value} data-nullable={this.props.nullable} onChange={this.handleChange} onBlur={this.checkError} />
<textarea ref="field-value" className={'form-control form-control-sm row3x ' + (this.state.hasError ? 'is-invalid' : '')} title={this.state.hasError} value={this.state.value} onChange={this.handleChange} onBlur={this.checkError} />
)
}
}
@ -333,7 +348,7 @@ class RbFormDateTime extends RbFormElement {
renderElement() {
return (
<div className="input-group datetime-field">
<input ref="field-value" className={'form-control form-control-sm ' + (this.state.hasError ? 'is-invalid' : '')} title={this.state.hasError} type="text" value={this.state.value} data-nullable={this.props.nullable} />
<input ref="field-value" className={'form-control form-control-sm ' + (this.state.hasError ? 'is-invalid' : '')} title={this.state.hasError} type="text" value={this.state.value}/>
<span className={'zmdi zmdi-close clean ' + (this.state.value ? '' : 'hide')} onClick={this.cleanValue}></span>
<div className="input-group-append">
<button className="btn btn-primary" type="button" ref="field-value-icon"><i className="icon zmdi zmdi-calendar"></i></button>
@ -371,14 +386,14 @@ class RbFormDateTime extends RbFormElement {
keyboardNavigation: false,
}).on('changeDate', function(event){
let val = $(this).val()
that.handleChange({ target: { value:val } }, true)
that.handleChange({ target: { value: val } }, true)
})
$(this.refs['field-value-icon']).click(()=>{
dtp.datetimepicker('show')
})
}
cleanValue() {
this.handleChange({ target: { value:'' } }, true)
this.handleChange({ target: { value: '' } }, true)
}
}
@ -392,11 +407,11 @@ class RbFormImage extends RbFormElement {
return (
<div className="img-field">
{this.state.value.map((item) => {
return (<span><a class="img-thumbnail img-upload"><img src={rb.storageUrl + item}/><b title="移除" onClick={()=>this.removeItem(item)}><span className="zmdi zmdi-delete"></span></b></a></span>)
return (<span><a className="img-thumbnail img-upload"><img src={rb.storageUrl + item + '?imageView2/2/w/100/interlace/1/q/100'}/><b title="移除" onClick={()=>this.removeItem(item)}><span className="zmdi zmdi-delete"></span></b></a></span>)
})}
<span title="选择图片">
<input type="file" className="inputfile" ref="upload-input" id={this.props.field + '-input'} accept="image/*" />
<label for={this.props.field + '-input'} className="img-thumbnail img-upload"><span className="zmdi zmdi-image-alt"></span></label>
<label htmlFor={this.props.field + '-input'} className="img-thumbnail img-upload"><span className="zmdi zmdi-image-alt"></span></label>
</span>
<input ref="field-value" type="hidden" value={this.state.value} />
</div>
@ -418,7 +433,7 @@ class RbFormImage extends RbFormElement {
postUrl: rb.baseUrl + '/filex/upload?cloud=auto&type=image',
onClientLoad: function(e, file){
if (file.type.substr(0, 5) != 'image'){
that.props.$$$parent.showNotice('请上传图片')
rb.notice('请上传图片')
return false
}
mprogress = new Mprogress({ template:3 })
@ -429,17 +444,17 @@ class RbFormImage extends RbFormElement {
mprogress.end()
d = JSON.parse(d.currentTarget.response)
if (d.error_code == 0){
let path = that.state.value
path.push(d.data)
that.handleChange({ target:{ value:path } }, true)
} else that.showNotice(d.error_msg || '上传失败,请稍后重试')
let paths = that.state.value
paths.push(d.data)
that.handleChange({ target:{ value: paths } }, true)
} else rb.notice(d.error_msg || '上传失败,请稍后重试', 'danger')
}
})
}
removeItem(item) {
let path = this.state.value
path.remove(item)
this.handleChange({ target:{ value:path } }, true)
let paths = this.state.value
paths.remove(item)
this.handleChange({ target:{ value: paths } }, true)
}
clickPreview() {
}
@ -460,7 +475,7 @@ class RbFormFile extends RbFormElement {
})}
<div className="file-select">
<input type="file" className="inputfile" ref="upload-input" id={this.props.field + '-input'} />
<label for={this.props.field + '-input'} className="btn-secondary"><i className="zmdi zmdi-upload"></i><span>选择文件</span></label>
<label htmlFor={this.props.field + '-input'} className="btn-secondary"><i className="zmdi zmdi-upload"></i><span>选择文件</span></label>
</div>
<input ref="field-value" type="hidden" value={this.state.value} />
</div>
@ -489,17 +504,17 @@ class RbFormFile extends RbFormElement {
mprogress.end()
d = JSON.parse(d.currentTarget.response)
if (d.error_code == 0){
let path = that.state.value
path.push(d.data)
that.handleChange({ target:{ value:path } }, true)
} else that.showNotice(d.error_msg || '上传失败,请稍后重试')
let paths = that.state.value
paths.push(d.data)
that.handleChange({ target:{ value: paths } }, true)
} else rb.notice(d.error_msg || '上传失败,请稍后重试', 'danger')
}
})
}
removeItem(item) {
let path = this.state.value
path.remove(item)
this.handleChange({ target:{ value:path } }, true)
let paths = this.state.value
paths.remove(item)
this.handleChange({ target:{ value: paths } }, true)
}
clickPreview() {
}
@ -510,7 +525,7 @@ class RbFormPickList extends RbFormElement {
constructor(props) {
super(props)
let options = this.props.options
let options = props.options
for (let i = 0; i < options.length; i++){
if (options[i]['default'] === true) {
this.state.value = options[i]['id']
@ -538,9 +553,7 @@ class RbFormPickList extends RbFormElement {
let value = e.target.value
that.handleChange({ target:{ value:value } }, true)
})
$setTimeout(function() {
select2.trigger("change")
}, 100)
$setTimeout(function() { select2.trigger("change") }, 100)
}
componentWillUnmount() {
$(this.refs['field-value']).select2('destroy')
@ -554,22 +567,21 @@ class RbFormReference extends RbFormElement {
}
renderElement() {
return (
<select ref="field-value" className="form-control form-control-sm" value={this.state.value} onChange={this.handleChange} multiple="multiple" style={{width:'100%'}} />
<select ref="field-value" className="form-control form-control-sm" onChange={this.handleChange} multiple="multiple" style={{width:'100%'}} />
)
}
renderViewElement() {
if (!!!this.state.value) return super.renderViewElement()
return (<div className="form-control-plaintext"><a href="javascript:;" onClick={()=>this.clickView()}>{this.state.value[1]}</a></div>)
return <div className="form-control-plaintext"><a href="javascript:;" onClick={()=>this.clickView()}>{this.state.value[1]}</a></div>
}
componentDidMount() {
console.log('fire componentDidMount ... ')
super.componentDidMount()
let that = this
let select2 = $(this.refs['field-value']).select2({
language: 'zh-CN',
placeholder: '选择' + that.props.label,
allowClear: true,
minimumInputLength: 1,
minimumInputLength: 2,
ajax: {
url: rb.baseUrl + '/app/commons/search',
delay: 300,
@ -585,17 +597,22 @@ class RbFormReference extends RbFormElement {
let rs = data.data.map((item) => {
return item
})
return {
results: rs
}
return { results: rs }
}
}
}).on('change.select2', function(e){
let value = e.target.value
that.handleChange({ target:{ value:value } }, true)
})
let val = this.state.value
$setTimeout(function() {
select2.trigger("change")
if (val) {
let option = new Option(val[1], val[0], true, true)
select2.append(option)
}
select2.trigger('change')
select2.on('change.select2', function(e){
that.handleChange({ target:{ value: e.target.value } }, true)
})
}, 100)
}
componentWillUnmount() {
@ -696,7 +713,7 @@ class RbViewModal extends React.Component {
<button className="close" type="button" onClick={()=>this.hide()}><span className="zmdi zmdi-close"></span></button>
</div>
<div className={'modal-body iframe rb-loading ' + (this.state.inLoad == true && 'rb-loading-active')}>
<iframe src={this.state.showAfterUrl || 'about:blank'} frameborder="0" scrolling="no"></iframe>
<iframe src={this.state.showAfterUrl || 'about:blank'} frameBorder="0" scrolling="no"></iframe>
<RbSpinner />
</div>
</div>

View file

@ -29,22 +29,22 @@ class RbList extends React.Component {
</th>
{this.state.fields.map((item, index) =>{
let columnWidth = (item.width || that.__defaultColumnWidth) + 'px'
let styles = { width:columnWidth }
let haveSort = item.sort || ''
return (<th data-field={item.field} style={styles} className="sortable unselect" onClick={this.fieldSort.bind(this,item.field)}><div style={styles}>{item.label}<i className={'zmdi ' + haveSort}></i><i className="split"></i></div></th>)
let styles = { width: columnWidth }
let sortClazz = item.sort || ''
return (<th key={'field-' + item.field} style={styles} className="sortable unselect" onClick={this.fieldSort.bind(this, item.field)}><div style={styles}>{item.label}<i className={'zmdi ' + sortClazz}></i><i className="split"></i></div></th>)
})}
<th className="column-empty"></th>
</tr>
</thead>
<tbody>
{this.state.rowData.map((item, index) => {
let lastGhost = item[lastIndex];
return (<tr className={lastGhost[3] && 'table-active'} data-id={lastGhost[0]} onClick={this.clickRow.bind(this, index, false)}>
let lastGhost = item[lastIndex]
return (<tr key={'row-' + lastGhost[0]} className={lastGhost[3] ? 'table-active' : ''} onClick={this.clickRow.bind(this, index, false)}>
<td className="column-checkbox">
<div><label className="custom-control custom-control-sm custom-checkbox"><input className="custom-control-input" type="checkbox" checked={lastGhost[3]} onClick={this.clickRow.bind(this, index, true)} /><span className="custom-control-label"></span></label></div>
</td>
{item.map((cell, index) => {
return that.__renderCell(cell, index, lastGhost)
return that.renderCell(cell, index, lastGhost)
})}
<td className="column-empty"></td>
</tr>)
@ -60,6 +60,7 @@ class RbList extends React.Component {
componentDidMount() {
const scroller = $(this.refs['rblist-scroller'])
scroller.perfectScrollbar()
let that = this
scroller.find('th .split').draggable({ containment: '.rb-datatable-body', axis: 'x', helper: 'clone', stop: function(event, ui){
let field = $(event.target).parent().parent().data('field')
@ -73,7 +74,6 @@ class RbList extends React.Component {
}
}
that.setState({ fields: fields }, function(){
// scroller.perfectScrollbar('update')
})
}})
this.fetchList()
@ -87,9 +87,9 @@ class RbList extends React.Component {
})
$('.J_delete, .J_view, .J_edit').attr('disabled', true)
let sLen = this.__selectedRows.length
if (sLen > 0) $('.J_delete').attr('disabled', false)
if (sLen == 1) $('.J_view, .J_edit').attr('disabled', false)
let len = this.__selectedRows.length
if (len > 0) $('.J_delete').attr('disabled', false)
if (len == 1) $('.J_view, .J_edit').attr('disabled', false)
}
fetchList(filter) {
@ -132,7 +132,7 @@ class RbList extends React.Component {
//
__renderCell(cellVal, index, lastGhost) {
renderCell(cellVal, index, lastGhost) {
if (this.state.fields.length == index) return null
if (!!!cellVal) return <td><div></div></td>
@ -162,6 +162,7 @@ class RbList extends React.Component {
return <td><div style={styles}>{cellVal}</div></td>
}
}
toggleAllRow(e) {
let checked = this.state.checkedAll == false
let _rowData = this.state.rowData
@ -192,6 +193,7 @@ class RbList extends React.Component {
this.setState({ rowData: _rowData })
return false
}
clickView(cellVal) {
renderRbViewModal(cellVal[0], cellVal[2][0])
return false;

View file

@ -5,17 +5,18 @@ class RbViewForm extends React.Component {
this.state = { ...props }
}
render() {
let that = this
return (<div className="rbview-form" ref="reviewForm">
{this.state.formComponent}
</div>)
return (
<div className="rbview-form" ref="reviewForm">
{this.state.formComponent}
</div>
)
}
componentDidMount() {
let that = this
$.get(rb.baseUrl + '/app/' + this.props.entity + '/view-modal?id=' + this.props.id, function(res){
$.get(rb.baseUrl + '/app/' + this.props.entity + '/view-model?id=' + this.props.id, function(res){
let elements = res.data.elements
const FORM = <div class="row">{elements.map((item) => {
return __detectViewElement(item)
const FORM = <div className="row">{elements.map((item) => {
return detectViewElement(item)
})}</div>
that.setState({ formComponent: FORM }, function(){
$('.invisible').removeClass('invisible')
@ -29,8 +30,8 @@ class RbViewForm extends React.Component {
}
}
const __detectViewElement = function(item){
const detectViewElement = function(item){
item.onView = true
item.editMode = false // viewMode and editMode
return (<div className={'col-12 col-sm-' + (item.isFull ? 12 : 6)}>{__detectElement(item)}</div>)
item.viewMode = true
return (<div className={'col-12 col-sm-' + (item.isFull ? 12 : 6)}>{detectElement(item)}</div>)
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff