mirror of
https://github.com/getrebuild/rebuild.git
synced 2025-02-25 23:05:06 +08:00
config pages
This commit is contained in:
parent
0bc2138427
commit
bf8ff7835d
16 changed files with 421 additions and 105 deletions
|
@ -18,9 +18,6 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|||
|
||||
package com.rebuild.server.business.trigger;
|
||||
|
||||
import com.rebuild.server.business.trigger.impl.FieldAggregation;
|
||||
import com.rebuild.server.business.trigger.impl.SendNotification;
|
||||
|
||||
/**
|
||||
* @author devezhao zhaofang123@gmail.com
|
||||
* @since 2019/05/24
|
||||
|
@ -31,7 +28,7 @@ public class ActionFactory {
|
|||
* @return
|
||||
*/
|
||||
public static ActionType[] getAvailableActions() {
|
||||
return new ActionType[] { ActionType.FIELDAGGREGATION, ActionType.SENDNOTIFICATION };
|
||||
return ActionType.values();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -57,11 +54,10 @@ public class ActionFactory {
|
|||
* @return
|
||||
*/
|
||||
public static TriggerAction createAction(ActionType type, ActionContext context) {
|
||||
if (type == ActionType.FIELDAGGREGATION) {
|
||||
return new FieldAggregation(context);
|
||||
} else if (type == ActionType.SENDNOTIFICATION) {
|
||||
return new SendNotification(context);
|
||||
try {
|
||||
return type.newInstance(context);
|
||||
} catch (NoSuchMethodException ex) {
|
||||
throw new TriggerException("无效操作类型: " + type, ex);
|
||||
}
|
||||
throw new TriggerException("未知操作类型: " + type);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,14 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|||
|
||||
package com.rebuild.server.business.trigger;
|
||||
|
||||
import com.rebuild.server.business.trigger.impl.AutoAssign;
|
||||
import com.rebuild.server.business.trigger.impl.AutoShare;
|
||||
import com.rebuild.server.business.trigger.impl.FieldAggregation;
|
||||
import com.rebuild.server.business.trigger.impl.SendNotification;
|
||||
import org.springframework.cglib.core.ReflectUtils;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
/**
|
||||
* 支持的操作类型
|
||||
*
|
||||
|
@ -26,18 +34,43 @@ package com.rebuild.server.business.trigger;
|
|||
*/
|
||||
public enum ActionType {
|
||||
|
||||
FIELDAGGREGATION("数据聚合"),
|
||||
|
||||
SENDNOTIFICATION("发送通知 (内部消息)"),
|
||||
|
||||
FIELDAGGREGATION("数据聚合", FieldAggregation.class),
|
||||
SENDNOTIFICATION("发送通知 (内部消息)", SendNotification.class),
|
||||
|
||||
AUTOSHARE("自动共享", AutoShare.class),
|
||||
AUTOASSIGN("自动分派", AutoAssign.class),
|
||||
|
||||
;
|
||||
|
||||
private String displayName;
|
||||
private ActionType(String displayName) {
|
||||
private Class<? extends TriggerAction> actionClazz;
|
||||
|
||||
ActionType(String displayName, Class<? extends TriggerAction> actionClazz) {
|
||||
this.displayName = displayName;
|
||||
this.actionClazz = actionClazz;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public Class<? extends TriggerAction> getActionClazz() {
|
||||
return actionClazz;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param context
|
||||
* @return
|
||||
* @throws NoSuchMethodException
|
||||
*/
|
||||
public TriggerAction newInstance(ActionContext context) throws NoSuchMethodException {
|
||||
Constructor c = getActionClazz().getConstructor(ActionContext.class);
|
||||
return (TriggerAction) ReflectUtils.newInstance(c, new Object[] { context });
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
rebuild - Building your business-systems freely.
|
||||
Copyright (C) 2019 devezhao <zhaofang123@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.rebuild.server.business.trigger.impl;
|
||||
|
||||
import cn.devezhao.persist4j.Entity;
|
||||
import com.rebuild.server.business.trigger.ActionContext;
|
||||
import com.rebuild.server.business.trigger.ActionType;
|
||||
import com.rebuild.server.business.trigger.TriggerAction;
|
||||
import com.rebuild.server.business.trigger.TriggerException;
|
||||
import com.rebuild.server.metadata.MetadataHelper;
|
||||
import com.rebuild.server.service.OperatingContext;
|
||||
|
||||
/**
|
||||
* @author devezhao
|
||||
* @since 2019/8/23
|
||||
*/
|
||||
public class AutoAssign implements TriggerAction {
|
||||
|
||||
final protected ActionContext context;
|
||||
|
||||
public AutoAssign(ActionContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionType getType() {
|
||||
return ActionType.AUTOASSIGN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUsableSourceEntity(int entityCode) {
|
||||
Entity entity = MetadataHelper.getEntity(entityCode);
|
||||
// 明细不可用
|
||||
return entity.getMasterEntity() == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(OperatingContext operatingContext) throws TriggerException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepare(OperatingContext operatingContext) throws TriggerException {
|
||||
// Nothings
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
rebuild - Building your business-systems freely.
|
||||
Copyright (C) 2019 devezhao <zhaofang123@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.rebuild.server.business.trigger.impl;
|
||||
|
||||
import com.rebuild.server.business.trigger.ActionContext;
|
||||
import com.rebuild.server.business.trigger.ActionType;
|
||||
import com.rebuild.server.business.trigger.TriggerException;
|
||||
import com.rebuild.server.service.OperatingContext;
|
||||
|
||||
/**
|
||||
* @author devezhao
|
||||
* @since 2019/8/23
|
||||
*/
|
||||
public class AutoShare extends AutoAssign {
|
||||
|
||||
public AutoShare(ActionContext context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionType getType() {
|
||||
return ActionType.AUTOSHARE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(OperatingContext operatingContext) throws TriggerException {
|
||||
}
|
||||
}
|
|
@ -67,7 +67,7 @@ public class FieldAggregation implements TriggerAction {
|
|||
|
||||
private String followSourceField;
|
||||
private ID targetRecordId;
|
||||
|
||||
|
||||
public FieldAggregation(ActionContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ import java.util.Set;
|
|||
public class SendNotification implements TriggerAction {
|
||||
|
||||
final private ActionContext context;
|
||||
|
||||
|
||||
public SendNotification(ActionContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
|
|
@ -18,25 +18,22 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|||
|
||||
package com.rebuild.web;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import cn.devezhao.commons.CodecUtils;
|
||||
import cn.devezhao.commons.ThrowableUtils;
|
||||
import cn.devezhao.commons.web.ServletUtils;
|
||||
import cn.devezhao.persist4j.engine.ID;
|
||||
import com.rebuild.server.Application;
|
||||
import com.rebuild.server.ServerListener;
|
||||
import com.rebuild.utils.AppUtils;
|
||||
import com.rebuild.web.admin.AdminEntryControll;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
|
||||
|
||||
import com.rebuild.server.Application;
|
||||
import com.rebuild.server.ServerListener;
|
||||
import com.rebuild.utils.AppUtils;
|
||||
import com.rebuild.web.admin.AdminEntryControll;
|
||||
|
||||
import cn.devezhao.commons.CodecUtils;
|
||||
import cn.devezhao.commons.ThrowableUtils;
|
||||
import cn.devezhao.commons.web.ServletUtils;
|
||||
import cn.devezhao.persist4j.engine.ID;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Controll 请求拦截
|
||||
|
@ -89,14 +86,17 @@ public class RequestWatchHandler extends HandlerInterceptorAdapter {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see RebuildExceptionResolver
|
||||
*/
|
||||
@Override
|
||||
public void afterCompletion(HttpServletRequest request,
|
||||
HttpServletResponse response, Object handler, Exception exception)
|
||||
throws Exception {
|
||||
super.afterCompletion(request, response, handler, exception);
|
||||
|
||||
ID caller = Application.getSessionStore().get(true);
|
||||
final ID caller = Application.getSessionStore().get(true);
|
||||
if (caller != null) {
|
||||
Application.getSessionStore().clean();
|
||||
}
|
||||
|
@ -108,7 +108,7 @@ public class RequestWatchHandler extends HandlerInterceptorAdapter {
|
|||
StringBuffer sb = new StringBuffer()
|
||||
.append("\n++ EXECUTE REQUEST ERROR(s) TRACE +++++++++++++++++++++++++++++++++++++++++++++")
|
||||
.append("\nUser : ").append(caller == null ? "-" : caller)
|
||||
.append("\nHandler : ").append(request.getRequestURI() + " [ " + handler + " ]")
|
||||
.append("\nHandler : ").append(request.getRequestURI()).append(" [ ").append(handler).append(" ]")
|
||||
.append("\nIP : ").append(ServletUtils.getRemoteAddr(request))
|
||||
.append("\nReferer : ").append(StringUtils.defaultIfEmpty(ServletUtils.getReferer(request), "-"))
|
||||
.append("\nUserAgent : ").append(StringUtils.defaultIfEmpty(request.getHeader("user-agent"), "-"))
|
||||
|
@ -119,7 +119,7 @@ public class RequestWatchHandler extends HandlerInterceptorAdapter {
|
|||
}
|
||||
|
||||
/**
|
||||
* 处理时间 LOG
|
||||
* 打印处理时间
|
||||
*
|
||||
* @param request
|
||||
*/
|
||||
|
@ -139,6 +139,8 @@ public class RequestWatchHandler extends HandlerInterceptorAdapter {
|
|||
private static final String TIMEOUT_KEY = "ErrorHandler_TIMEOUT";
|
||||
|
||||
/**
|
||||
* 用户验证
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
* @return
|
||||
|
@ -182,7 +184,7 @@ public class RequestWatchHandler extends HandlerInterceptorAdapter {
|
|||
}
|
||||
|
||||
/**
|
||||
* 忽略权限验证
|
||||
* 是否忽略用户验证
|
||||
*
|
||||
* @param requestUrl
|
||||
* @return
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
|
||||
<%@ page import="com.rebuild.web.admin.AdminEntryControll"%>
|
||||
<%@ page import="com.rebuild.utils.AppUtils"%>
|
||||
<%@ page import="com.rebuild.server.Application"%>
|
||||
<%@ page import="com.rebuild.server.service.bizz.privileges.User"%>
|
||||
<%@ page import="com.rebuild.server.service.bizz.UserHelper"%>
|
||||
<%@ page import="org.apache.commons.lang.StringUtils"%>
|
||||
<%
|
||||
final User currentUser = Application.getUserStore().getUser(AppUtils.getRequestUser(request));
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
|
@ -125,7 +126,9 @@ window.__PageConfig = {
|
|||
</script>
|
||||
<script src="${baseUrl}/assets/js/rb-advfilter.jsx" type="text/babel"></script>
|
||||
<script src="${baseUrl}/assets/js/triggers/trigger-design.jsx" type="text/babel"></script>
|
||||
<script src="${baseUrl}/assets/js/triggers/trigger.field-aggregation.jsx" type="text/babel"></script>
|
||||
<script src="${baseUrl}/assets/js/triggers/trigger.send-notification.jsx" type="text/babel"></script>
|
||||
<c:if test="${actionType == 'FIELDAGGREGATION'}"><script src="${baseUrl}/assets/js/triggers/trigger.field-aggregation.jsx" type="text/babel"></script></c:if>
|
||||
<c:if test="${actionType == 'SENDNOTIFICATION'}"><script src="${baseUrl}/assets/js/triggers/trigger.send-notification.jsx" type="text/babel"></script></c:if>
|
||||
<c:if test="${actionType == 'AUTOASSIGN'}"><script src="${baseUrl}/assets/js/triggers/trigger.auto-assign.jsx" type="text/babel"></script></c:if>
|
||||
<c:if test="${actionType == 'AUTOSHARE'}"><script src="${baseUrl}/assets/js/triggers/trigger.auto-share.jsx" type="text/babel"></script></c:if>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
}
|
||||
|
||||
.timeline.spare form.simple .col-form-label {
|
||||
max-width: 160px
|
||||
max-width: 180px
|
||||
}
|
||||
|
||||
.timeline.spare .timeline-content {
|
||||
|
@ -44,8 +44,8 @@
|
|||
padding: 20px;
|
||||
}
|
||||
|
||||
.send-notification {
|
||||
max-width: 800px;
|
||||
#react-content>div {
|
||||
max-width: 881px;
|
||||
}
|
||||
|
||||
.field-aggregation p {
|
||||
|
@ -106,4 +106,9 @@
|
|||
|
||||
.field-aggregation .items>div .col-5>a.del:hover {
|
||||
color: #222;
|
||||
}
|
||||
|
||||
.auto-assign ol,
|
||||
.auto-assign ul {
|
||||
line-height: auto;
|
||||
}
|
|
@ -116,8 +116,8 @@ class DlgShare extends DlgAssign {
|
|||
*/
|
||||
static create(props) {
|
||||
let that = this
|
||||
if (that.__HOLDER) that.__HOLDER.show(props)
|
||||
else renderRbcomp(<DlgShare {...props} />, null, function () { that.__HOLDER = this })
|
||||
if (that.__HOLDER2) that.__HOLDER2.show(props)
|
||||
else renderRbcomp(<DlgShare {...props} />, null, function () { that.__HOLDER2 = this })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
const wpc = window.__PageConfig
|
||||
var contentComp = null
|
||||
$(document).ready(() => {
|
||||
$.fn.select2.defaults.set('allowClear', false)
|
||||
|
||||
|
@ -17,21 +18,11 @@ $(document).ready(() => {
|
|||
})
|
||||
saveFilter(wpc.whenFilter)
|
||||
|
||||
let contentComp
|
||||
const compProps = { sourceEntity: wpc.sourceEntity, content: wpc.actionContent }
|
||||
if (wpc.actionType === 'FIELDAGGREGATION') {
|
||||
// eslint-disable-next-line react/jsx-no-undef
|
||||
renderRbcomp(<ContentFieldAggregation {...compProps} />, 'react-content', function () { contentComp = this })
|
||||
} else if (wpc.actionType === 'SENDNOTIFICATION') {
|
||||
// eslint-disable-next-line react/jsx-no-undef
|
||||
renderRbcomp(<ContentSendNotification {...compProps} />, 'react-content', function () { contentComp = this })
|
||||
} else {
|
||||
renderRbcomp(<div className="text-danger">未实现的操作类型: {wpc.actionType}</div>, 'react-content')
|
||||
$('.J_save').attr('disabled', true)
|
||||
return
|
||||
}
|
||||
renderContentComp({ sourceEntity: wpc.sourceEntity, content: wpc.actionContent })
|
||||
|
||||
let _btn = $('.J_save').click(() => {
|
||||
if (!contentComp) return
|
||||
|
||||
let when = 0
|
||||
$('.J_when input:checked').each(function () {
|
||||
when += ~~$(this).val()
|
||||
|
@ -60,6 +51,56 @@ const saveFilter = function (res) {
|
|||
else $('.J_whenFilter a').text('点击设置')
|
||||
}
|
||||
|
||||
// 组件复写
|
||||
var renderContentComp = function (props) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(props)
|
||||
}
|
||||
|
||||
// 用户选择器
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
class UserSelectorExt extends UserSelector {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.tabTypes.push(['FIELDS', '使用字段'])
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
super.componentDidMount()
|
||||
this.__fields = []
|
||||
$.get(`${rb.baseUrl}/commons/metadata/fields?deep=2&entity=${this.props.entity || wpc.sourceEntity}`, (res) => {
|
||||
$(res.data).each((idx, item) => {
|
||||
if (item.type === 'REFERENCE' && item.ref && (item.ref[0] === 'User' || item.ref[0] === 'Department' || item.ref[0] === 'Role')) {
|
||||
this.__fields.push({ id: item.name, text: item.label })
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
switchTab(type) {
|
||||
type = type || this.state.tabType
|
||||
if (type === 'FIELDS') {
|
||||
const q = this.state.query
|
||||
const cacheKey = type + '-' + q
|
||||
this.setState({ tabType: type, items: this.cached[cacheKey] }, () => {
|
||||
if (!this.cached[cacheKey]) {
|
||||
if (!q) this.cached[cacheKey] = this.__fields
|
||||
else {
|
||||
let fs = []
|
||||
$(this.__fields).each(function () {
|
||||
if (this.text.contains(q)) fs.push(this)
|
||||
})
|
||||
this.cached[cacheKey] = fs
|
||||
}
|
||||
this.switchTab(type)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
super.switchTab(type)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 动作类定义
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
class ActionContentSpec extends React.Component {
|
||||
|
|
92
src/main/webapp/assets/js/triggers/trigger.auto-assign.jsx
Normal file
92
src/main/webapp/assets/js/triggers/trigger.auto-assign.jsx
Normal file
|
@ -0,0 +1,92 @@
|
|||
/* eslint-disable eqeqeq */
|
||||
/* eslint-disable react/jsx-no-undef */
|
||||
// ~~ 自动分派
|
||||
// eslint-disable-next-line
|
||||
class ContentAutoAssign extends ActionContentSpec {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state.assignRule = 1
|
||||
}
|
||||
|
||||
render() {
|
||||
return <div className="auto-assign">
|
||||
<form className="simple">
|
||||
<div className="form-group row pt-1">
|
||||
<label className="col-12 col-lg-3 col-form-label text-lg-right">分派给谁</label>
|
||||
<div className="col-12 col-lg-8">
|
||||
<UserSelectorExt ref={(c) => this._assignTo = c} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="form-group row pb-1">
|
||||
<label className="col-12 col-lg-3 col-form-label text-lg-right">(多人) 分派规则</label>
|
||||
<div className="col-12 col-lg-8 pt-1">
|
||||
<label className="custom-control custom-control-sm custom-radio custom-control-inline">
|
||||
<input className="custom-control-input" name="assignRule" type="radio" checked={this.state.assignRule == 1} value="1" onChange={this.changeValue} />
|
||||
<span className="custom-control-label">依次平均分派</span>
|
||||
</label>
|
||||
<label className="custom-control custom-control-sm custom-radio custom-control-inline">
|
||||
<input className="custom-control-input" name="assignRule" type="radio" checked={this.state.assignRule == 2} value="2" onChange={this.changeValue} />
|
||||
<span className="custom-control-label">随机分派</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div className="form-group row pb-1">
|
||||
<label className="col-12 col-lg-3 col-form-label text-lg-right">同时分派关联记录</label>
|
||||
<div className="col-12 col-lg-8 pt-1">
|
||||
<div className="entity-select">
|
||||
<select className="form-control form-control-sm" ref={(c) => this._cascades = c}>
|
||||
{(this.state.cascadesEntity || []).map((item) => {
|
||||
return <option key={'option-' + item[0]} value={item[0]}>{item[1]}</option>
|
||||
})}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
$('.J_when').find('.custom-control-input').each(function () {
|
||||
let v = ~~$(this).val()
|
||||
if (!(v == 1 || v == 4)) $(this).attr('disabled', true)
|
||||
// if (!(v == 1 || v == 4)) $(this).parent().remove()
|
||||
})
|
||||
|
||||
if (this.props.content && this.props.content.assignTo) {
|
||||
$.post(`${rb.baseUrl}/commons/search/user-selector?entity=${this.props.sourceEntity}`, JSON.stringify(this.props.content.assignTo), (res) => {
|
||||
if (res.error_code === 0 && res.data.length > 0) this._assignTo.setState({ selected: res.data })
|
||||
})
|
||||
}
|
||||
|
||||
if (this.props.content && this.props.content.assignRule == 2) this.setState({ assignRule: 2 })
|
||||
|
||||
let cascades = this.props.content && this.props.content.cascades ? this.props.content.cascades.split(',') : []
|
||||
$.get(rb.baseUrl + '/commons/metadata/references?entity=' + this.props.sourceEntity, (res) => {
|
||||
this.setState({ cascadesEntity: res.data }, () => {
|
||||
this.__select2 = $(this._cascades).select2({
|
||||
multiple: true,
|
||||
placeholder: '选择关联实体 (可选)'
|
||||
}).val(cascades.length === 0 ? null : cascades).trigger('change')
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
changeValue = (e) => {
|
||||
let s = {}
|
||||
s[e.target.name] = e.target.value
|
||||
this.setState(s)
|
||||
}
|
||||
|
||||
buildContent() {
|
||||
let _data = { assignTo: this._assignTo.getSelected(), assignRule: ~~this.state.assignRule, cascades: this.__select2.val().join(',') }
|
||||
if (!_data.assignTo || _data.assignTo.length === 0) { RbHighbar.create('请选择分派给谁'); return false }
|
||||
return _data
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-undef
|
||||
renderContentComp = function (props) {
|
||||
// eslint-disable-next-line no-undef
|
||||
renderRbcomp(<ContentAutoAssign {...props} />, 'react-content', function () { contentComp = this })
|
||||
}
|
70
src/main/webapp/assets/js/triggers/trigger.auto-share.jsx
Normal file
70
src/main/webapp/assets/js/triggers/trigger.auto-share.jsx
Normal file
|
@ -0,0 +1,70 @@
|
|||
/* eslint-disable eqeqeq */
|
||||
/* eslint-disable react/jsx-no-undef */
|
||||
// ~~ 自动共享
|
||||
// eslint-disable-next-line
|
||||
class ContentAutoShare extends ActionContentSpec {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
}
|
||||
|
||||
render() {
|
||||
return <div className="auto-share">
|
||||
<form className="simple">
|
||||
<div className="form-group row pt-1">
|
||||
<label className="col-12 col-lg-3 col-form-label text-lg-right">共享给谁</label>
|
||||
<div className="col-12 col-lg-8">
|
||||
<UserSelectorExt ref={(c) => this._shareTo = c} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="form-group row pb-1">
|
||||
<label className="col-12 col-lg-3 col-form-label text-lg-right">同时共享关联记录</label>
|
||||
<div className="col-12 col-lg-8 pt-1">
|
||||
<div>
|
||||
<select className="form-control form-control-sm" ref={(c) => this._cascades = c}>
|
||||
{(this.state.cascadesEntity || []).map((item) => {
|
||||
return <option key={'option-' + item[0]} value={item[0]}>{item[1]}</option>
|
||||
})}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
$('.J_when').find('.custom-control-input').each(function () {
|
||||
let v = ~~$(this).val()
|
||||
if (!(v == 1 || v == 4)) $(this).attr('disabled', true)
|
||||
// if (!(v == 1 || v == 4)) $(this).parent().remove()
|
||||
})
|
||||
|
||||
if (this.props.content && this.props.content.shareTo) {
|
||||
$.post(`${rb.baseUrl}/commons/search/user-selector?entity=${this.props.sourceEntity}`, JSON.stringify(this.props.content.shareTo), (res) => {
|
||||
if (res.error_code === 0 && res.data.length > 0) this._shareTo.setState({ selected: res.data })
|
||||
})
|
||||
}
|
||||
|
||||
let cascades = this.props.content && this.props.content.cascades ? this.props.content.cascades.split(',') : []
|
||||
$.get(rb.baseUrl + '/commons/metadata/references?entity=' + this.props.sourceEntity, (res) => {
|
||||
this.setState({ cascadesEntity: res.data }, () => {
|
||||
this.__select2 = $(this._cascades).select2({
|
||||
multiple: true,
|
||||
placeholder: '选择关联实体 (可选)'
|
||||
}).val(cascades.length === 0 ? null : cascades).trigger('change')
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
buildContent() {
|
||||
let _data = { shareTo: this._shareTo.getSelected(), cascades: this.__select2.val().join(',') }
|
||||
if (!_data.shareTo || _data.shareTo.length === 0) { RbHighbar.create('请选择共享给谁'); return false }
|
||||
return _data
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-undef
|
||||
renderContentComp = function (props) {
|
||||
// eslint-disable-next-line no-undef
|
||||
renderRbcomp(<ContentAutoShare {...props} />, 'react-content', function () { contentComp = this })
|
||||
}
|
|
@ -1,9 +1,7 @@
|
|||
|
||||
const CALC_MODES = { 'SUM': '求和', 'COuNT': '计数', 'AVG': '平均值', 'MAX': '最大', 'MIN': '最小' }
|
||||
|
||||
// ~~ 数据聚合
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
// eslint-disable-next-line
|
||||
// eslint-disable-next-line no-undef
|
||||
class ContentFieldAggregation extends ActionContentSpec {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
@ -169,3 +167,9 @@ class ContentFieldAggregation extends ActionContentSpec {
|
|||
return _data
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-undef
|
||||
renderContentComp = function (props) {
|
||||
// eslint-disable-next-line no-undef
|
||||
renderRbcomp(<ContentFieldAggregation {...props} />, 'react-content', function () { contentComp = this })
|
||||
}
|
|
@ -1,22 +1,22 @@
|
|||
|
||||
/* eslint-disable react/jsx-no-undef */
|
||||
// ~~ 发送通知
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
// eslint-disable-next-line
|
||||
// eslint-disable-next-line no-undef
|
||||
class ContentSendNotification extends ActionContentSpec {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
}
|
||||
|
||||
render() {
|
||||
return <div className="send-notification">
|
||||
<form className="simple">
|
||||
<div className="form-group row pt-1">
|
||||
<label className="col-12 col-lg-2 col-form-label text-lg-right">发送给谁</label>
|
||||
<label className="col-12 col-lg-3 col-form-label text-lg-right">发送给谁</label>
|
||||
<div className="col-12 col-lg-8">
|
||||
<UserSelectorExt ref={(c) => this._sendTo = c} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="form-group row pb-1">
|
||||
<label className="col-12 col-lg-2 col-form-label text-lg-right">发送内容</label>
|
||||
<label className="col-12 col-lg-3 col-form-label text-lg-right">发送内容</label>
|
||||
<div className="col-12 col-lg-8">
|
||||
<textarea className="form-control form-control-sm row3x" ref={(c) => this._content = c} maxLength="600"></textarea>
|
||||
</div>
|
||||
|
@ -24,6 +24,7 @@ class ContentSendNotification extends ActionContentSpec {
|
|||
</form>
|
||||
</div>
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
if (this.props.content && this.props.content.sendTo) {
|
||||
$.post(`${rb.baseUrl}/commons/search/user-selector?entity=${this.props.sourceEntity}`, JSON.stringify(this.props.content.sendTo), (res) => {
|
||||
|
@ -32,6 +33,7 @@ class ContentSendNotification extends ActionContentSpec {
|
|||
}
|
||||
$(this._content).val(this.props.content.content || '')
|
||||
}
|
||||
|
||||
buildContent() {
|
||||
let _data = { sendTo: this._sendTo.getSelected(), content: $(this._content).val() }
|
||||
if (!_data.sendTo || _data.sendTo.length === 0) { RbHighbar.create('请选择发送给谁'); return false }
|
||||
|
@ -39,43 +41,9 @@ class ContentSendNotification extends ActionContentSpec {
|
|||
return _data
|
||||
}
|
||||
}
|
||||
class UserSelectorExt extends UserSelector {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.tabTypes.push(['FIELDS', '使用字段'])
|
||||
}
|
||||
componentDidMount() {
|
||||
super.componentDidMount()
|
||||
|
||||
this.__fields = []
|
||||
$.get(`${rb.baseUrl}/commons/metadata/fields?deep=2&entity=${wpc.sourceEntity}`, (res) => {
|
||||
$(res.data).each((idx, item) => {
|
||||
if (item.type === 'REFERENCE' && item.ref && (item.ref[0] === 'User' || item.ref[0] === 'Department' || item.ref[0] === 'Role')) {
|
||||
this.__fields.push({ id: item.name, text: item.label })
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
switchTab(type) {
|
||||
type = type || this.state.tabType
|
||||
if (type === 'FIELDS') {
|
||||
const q = this.state.query
|
||||
const cacheKey = type + '-' + q
|
||||
this.setState({ tabType: type, items: this.cached[cacheKey] }, () => {
|
||||
if (!this.cached[cacheKey]) {
|
||||
if (!q) this.cached[cacheKey] = this.__fields
|
||||
else {
|
||||
let fs = []
|
||||
$(this.__fields).each(function () {
|
||||
if (this.text.contains(q)) fs.push(this)
|
||||
})
|
||||
this.cached[cacheKey] = fs
|
||||
}
|
||||
this.switchTab(type)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
super.switchTab(type)
|
||||
}
|
||||
}
|
||||
// eslint-disable-next-line no-undef
|
||||
renderContentComp = function (props) {
|
||||
// eslint-disable-next-line no-undef
|
||||
renderRbcomp(<ContentSendNotification {...props} />, 'react-content', function () { contentComp = this })
|
||||
}
|
Loading…
Reference in a new issue