mirror of
https://github.com/getrebuild/rebuild.git
synced 2025-09-06 14:46:44 +08:00
Merge b33e2d1236
into 4b32e2662f
This commit is contained in:
commit
d36e803da4
44 changed files with 316 additions and 156 deletions
2
@rbv
2
@rbv
|
@ -1 +1 @@
|
|||
Subproject commit 653879f9b8c8cc59876618091fa14265edf7ece8
|
||||
Subproject commit 64bee3bc986073e62a4d3ee6c94bd3d3d4231e1c
|
|
@ -17,6 +17,7 @@ import org.apache.commons.lang.StringUtils;
|
|||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -99,12 +100,36 @@ public class TableChart extends ChartData {
|
|||
sumsRow[i] = dataRaw.length;
|
||||
}
|
||||
}
|
||||
for (int i = numericalIndexStart; i < colLength; i++) {
|
||||
BigDecimal sum = new BigDecimal(0);
|
||||
for (Object[] row : dataRaw) {
|
||||
sum = sum.add(BigDecimal.valueOf(ObjectUtils.toDouble(row[i])));
|
||||
|
||||
for (int i = numericalIndexStart, j = 0; i < colLength; i++, j++) {
|
||||
final Numerical N = getNumericals()[j];
|
||||
final FormatCalc FC = N.getFormatCalc();
|
||||
|
||||
BigDecimal sums = null;
|
||||
if (FC == FormatCalc.MAX) {
|
||||
// 最大
|
||||
for (Object[] row : dataRaw) {
|
||||
BigDecimal b = BigDecimal.valueOf(ObjectUtils.toDouble(row[i]));
|
||||
if (sums == null || sums.compareTo(b) < 0) sums = b;
|
||||
}
|
||||
} else if (FC == FormatCalc.MIN) {
|
||||
// 最小
|
||||
for (Object[] row : dataRaw) {
|
||||
BigDecimal b = BigDecimal.valueOf(ObjectUtils.toDouble(row[i]));
|
||||
if (sums == null || sums.compareTo(b) > 0) sums = b;
|
||||
}
|
||||
} else {
|
||||
sums = new BigDecimal(0);
|
||||
// 求和
|
||||
for (Object[] row : dataRaw) {
|
||||
sums = sums.add(BigDecimal.valueOf(ObjectUtils.toDouble(row[i])));
|
||||
}
|
||||
// 均值
|
||||
if (FC == FormatCalc.AVG) {
|
||||
sums = sums.divide(new BigDecimal(dataRaw.length), N.getScale(), RoundingMode.HALF_UP);
|
||||
}
|
||||
}
|
||||
sumsRow[i] = sum.doubleValue();
|
||||
sumsRow[i] = sums.doubleValue();
|
||||
}
|
||||
|
||||
dataRawNew[dataRaw.length] = sumsRow;
|
||||
|
|
|
@ -120,7 +120,7 @@ public class FilesHelper {
|
|||
o[3] = user.equals(o[3]) || UserHelper.isAdmin(user); // v3.5.1 管理员可删除
|
||||
o[5] = scopeSpecUsers;
|
||||
JSONObject folder = JSONUtils.toJSONObject(
|
||||
new String[] { "id", "text", "private", "self", "parent", "specUsers" }, o);
|
||||
new String[]{"id", "text", "private", "self", "parent", "specUsers"}, o);
|
||||
|
||||
JSONArray children = getAccessableFolders(user, (ID) o[0]);
|
||||
if (!children.isEmpty()) {
|
||||
|
@ -176,14 +176,15 @@ public class FilesHelper {
|
|||
}
|
||||
|
||||
/**
|
||||
* 是否允许操作文件(管理员与创建人允许)
|
||||
* 是否允许操作文件(管理员与创建人允许)。
|
||||
* v4.2 可访问就可修改
|
||||
*
|
||||
* @param user
|
||||
* @param fileId
|
||||
* @return
|
||||
*/
|
||||
public static boolean isFileManageable(ID user, ID fileId) {
|
||||
return UserHelper.isAdmin(user) || UserHelper.isSelf(user, fileId);
|
||||
return isFileAccessable(user, fileId);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -263,7 +263,7 @@ public class AdvFilterParser extends SetUser {
|
|||
String field = item.getString("field");
|
||||
if (field.startsWith("&")) field = field.replace("&", NAME_FIELD_PREFIX); // fix: _$unthy
|
||||
|
||||
final boolean hasNameFlag = field.startsWith(NAME_FIELD_PREFIX);
|
||||
boolean hasNameFlag = field.startsWith(NAME_FIELD_PREFIX);
|
||||
if (hasNameFlag) field = field.substring(1);
|
||||
|
||||
Field lastFieldMeta = VF_ACU.equals(field)
|
||||
|
@ -274,6 +274,12 @@ public class AdvFilterParser extends SetUser {
|
|||
return null;
|
||||
}
|
||||
|
||||
String op = item.getString("op");
|
||||
// 引用字段`重复`特殊处理
|
||||
if (hasNameFlag && ParseHelper.REP.equalsIgnoreCase(op)) {
|
||||
hasNameFlag = false;
|
||||
}
|
||||
|
||||
DisplayType dt = EasyMetaFactory.getDisplayType(lastFieldMeta);
|
||||
if (dt == DisplayType.CLASSIFICATION || (dt == DisplayType.PICKLIST && hasNameFlag) /* 快速查询 */) {
|
||||
field = NAME_FIELD_PREFIX + field;
|
||||
|
@ -295,7 +301,7 @@ public class AdvFilterParser extends SetUser {
|
|||
final boolean isN2NUsers = dt == DisplayType.N2NREFERENCE
|
||||
&& lastFieldMeta.getReferenceEntity().getEntityCode() == EntityHelper.User;
|
||||
|
||||
String op = item.getString("op");
|
||||
|
||||
// v3.9 区间兼容
|
||||
if (ParseHelper.BW.equals(op)) {
|
||||
String valueBegin = item.getString("value");
|
||||
|
@ -645,9 +651,10 @@ public class AdvFilterParser extends SetUser {
|
|||
StringUtils.join(value.split("\\|"), "', '"));
|
||||
} else if (ParseHelper.REP.equalsIgnoreCase(op)) {
|
||||
// `in`
|
||||
int count = NumberUtils.toInt(value, 1);
|
||||
value = MessageFormat.format(
|
||||
"( select {0} from {1} group by {0} having (count({0}) > {2}) )",
|
||||
field, rootEntity.getName(), String.valueOf(NumberUtils.toInt(value, 1)));
|
||||
"( select {0} from {1} group by {0} having (count({0}) {2} {3}) )",
|
||||
field, rootEntity.getName(), count < 1 ? "=" : ">", Math.max(count, 1));
|
||||
}
|
||||
|
||||
if (StringUtils.isBlank(value)) {
|
||||
|
|
|
@ -185,63 +185,48 @@ public class QueryParser {
|
|||
|
||||
// 过滤器
|
||||
|
||||
List<String> wheres = new ArrayList<>();
|
||||
List<String> whereAnds = new ArrayList<>();
|
||||
|
||||
// Default
|
||||
String defaultFilter = dataListBuilder == null ? null : dataListBuilder.getDefaultFilter();
|
||||
if (StringUtils.isNotBlank(defaultFilter)) {
|
||||
wheres.add(defaultFilter);
|
||||
whereAnds.add(defaultFilter);
|
||||
}
|
||||
|
||||
// append: ProtocolFilter
|
||||
String protocolFilter = queryExpr.getString("protocolFilter");
|
||||
if (StringUtils.isNotBlank(protocolFilter)) {
|
||||
ProtocolFilterParser fp = new ProtocolFilterParser(protocolFilter);
|
||||
if (queryExpr.containsKey("protocolFilter__varRecord")) {
|
||||
fp.setVarRecord(queryExpr.getJSONObject("protocolFilter__varRecord"));
|
||||
}
|
||||
String where = fp.toSqlWhere();
|
||||
|
||||
// d 强制过滤明细切换支持
|
||||
if (StringUtils.isNotBlank(where) && protocolFilter.startsWith("via:014-") && entity.getMainEntity() != null) {
|
||||
ConfigBean filter = AdvFilterManager.instance.getAdvFilter(ID.valueOf(protocolFilter.split(":")[1]));
|
||||
String filterEntity = ((JSONObject) filter.getJSON("filter")).getString("entity");
|
||||
Entity filterEntityMeta = MetadataHelper.getEntity(filterEntity);
|
||||
// 明细使用主实体的
|
||||
Entity me = entity.getMainEntity();
|
||||
if (filterEntityMeta.equals(me)) {
|
||||
Field dtmField = MetadataHelper.getDetailToMainField(entity);
|
||||
where = String.format("%s in (select %sId from %s where %s)", dtmField.getName(), me.getName(), me.getName(), where);
|
||||
}
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(where)) {
|
||||
if (CommonsUtils.DEVLOG) System.out.println("[dev] Parse protocolFilter : " + protocolFilter + " >> " + where);
|
||||
wheres.add(where);
|
||||
}
|
||||
String w = parseProtocolFilter(protocolFilter);
|
||||
if (w != null) whereAnds.add(w);
|
||||
}
|
||||
// append: protocolFilterAnd
|
||||
String protocolFilterAnd = queryExpr.getString("protocolFilterAnd");
|
||||
if (StringUtils.isNotBlank(protocolFilterAnd)) {
|
||||
String w = parseProtocolFilter(protocolFilterAnd);
|
||||
if (w != null) whereAnds.add(w);
|
||||
}
|
||||
|
||||
// append: AdvFilter
|
||||
String advFilter = queryExpr.getString("advFilter");
|
||||
if (ID.isId(advFilter)) {
|
||||
String where = parseAdvFilter(ID.valueOf(advFilter));
|
||||
if (StringUtils.isNotBlank(where)) wheres.add(where);
|
||||
if (StringUtils.isNotBlank(where)) whereAnds.add(where);
|
||||
}
|
||||
|
||||
// append: QuickQuery
|
||||
JSONObject quickFilter = queryExpr.getJSONObject("filter");
|
||||
if (quickFilter != null) {
|
||||
String where = new AdvFilterParser(quickFilter, entity).toSqlWhere();
|
||||
if (StringUtils.isNotBlank(where)) wheres.add(where);
|
||||
if (StringUtils.isNotBlank(where)) whereAnds.add(where);
|
||||
}
|
||||
// v3.3
|
||||
JSONObject quickFilterAnd = queryExpr.getJSONObject("filterAnd");
|
||||
if (quickFilterAnd != null) {
|
||||
String where = new AdvFilterParser(quickFilterAnd, entity).toSqlWhere();
|
||||
if (StringUtils.isNotBlank(where)) wheres.add(where);
|
||||
if (StringUtils.isNotBlank(where)) whereAnds.add(where);
|
||||
}
|
||||
|
||||
final String whereClause = wheres.isEmpty() ? "1=1" : StringUtils.join(wheres.iterator(), " and ");
|
||||
final String whereClause = whereAnds.isEmpty() ? "1=1" : StringUtils.join(whereAnds.iterator(), " and ");
|
||||
fullSql.append(" where ").append(whereClause);
|
||||
|
||||
// v4.0-b3 分组
|
||||
|
@ -369,4 +354,32 @@ public class QueryParser {
|
|||
return String.format("select %s from %s where ",
|
||||
StringUtils.join(counts, ","), entity.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param protocolFilter
|
||||
* @return
|
||||
*/
|
||||
private String parseProtocolFilter(String protocolFilter) {
|
||||
ProtocolFilterParser fp = new ProtocolFilterParser(protocolFilter);
|
||||
if (queryExpr.containsKey("protocolFilter__varRecord")) {
|
||||
fp.setVarRecord(queryExpr.getJSONObject("protocolFilter__varRecord"));
|
||||
}
|
||||
String where = fp.toSqlWhere();
|
||||
|
||||
// d 强制过滤明细切换支持
|
||||
if (StringUtils.isNotBlank(where) && protocolFilter.startsWith("via:014-") && entity.getMainEntity() != null) {
|
||||
ConfigBean filter = AdvFilterManager.instance.getAdvFilter(ID.valueOf(protocolFilter.split(":")[1]));
|
||||
String filterEntity = ((JSONObject) filter.getJSON("filter")).getString("entity");
|
||||
Entity filterEntityMeta = MetadataHelper.getEntity(filterEntity);
|
||||
// 明细使用主实体的
|
||||
Entity me = entity.getMainEntity();
|
||||
if (filterEntityMeta.equals(me)) {
|
||||
Field dtmField = MetadataHelper.getDetailToMainField(entity);
|
||||
where = String.format("%s in (select %sId from %s where %s)", dtmField.getName(), me.getName(), me.getName(), where);
|
||||
}
|
||||
}
|
||||
|
||||
if (CommonsUtils.DEVLOG) System.out.println("[dev] Parse protocolFilter : " + protocolFilter + " >> " + where);
|
||||
return where;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -129,7 +129,7 @@ public class AdminVerfiyController extends BaseController {
|
|||
// 日志
|
||||
if ("log".equalsIgnoreCase(type)) {
|
||||
File logFile = SysbaseHeartbeat.getLastLogbackFile();
|
||||
FileDownloader.setDownloadHeaders(response, logFile.getName(), false);
|
||||
FileDownloader.setDownloadHeaders(response, logFile.getName(), true);
|
||||
FileDownloader.writeLocalFile(logFile, response);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -67,7 +67,7 @@ public class FilePreviewer extends BaseController {
|
|||
|
||||
@GetMapping("/commons/file-editor")
|
||||
public ModelAndView ooEditor(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
||||
getRequestUser(request);
|
||||
getRequestUser(request); // check
|
||||
return ooPreviewOrEditor(request, response, true);
|
||||
}
|
||||
|
||||
|
@ -141,15 +141,17 @@ public class FilePreviewer extends BaseController {
|
|||
ModelAndView mv = createModelAndView("/common/oo-preview");
|
||||
mv.getModel().put(OnlyofficeServer.name(), OnlyOffice.getOoServer());
|
||||
|
||||
String fileName = ((JSONObject) ps[0]).getString("title");
|
||||
|
||||
// 编辑模式
|
||||
if (editor) {
|
||||
ooConfig.put("type", "desktop");
|
||||
mv.getModel().put("title", Language.L("文档编辑"));
|
||||
mv.getModel().put("title", fileName + " - " + Language.L("文档编辑"));
|
||||
} else {
|
||||
// https://api.onlyoffice.com/docs/docs-api/usage-api/config/#type
|
||||
String view = StringUtils.defaultIfBlank(getParameter(request, "view"), "embedded");
|
||||
ooConfig.put("type", view);
|
||||
mv.getModel().put("title", Language.L("文档预览"));
|
||||
mv.getModel().put("title", fileName + " - " + Language.L("文档预览"));
|
||||
}
|
||||
if (Application.devMode()) System.out.println("[dev] " + JSONUtils.prettyPrint(ooConfig));
|
||||
mv.getModel().put("_DocEditorConfig", ooConfig);
|
||||
|
|
|
@ -24,6 +24,7 @@ import com.rebuild.core.metadata.easymeta.DisplayType;
|
|||
import com.rebuild.core.metadata.easymeta.EasyField;
|
||||
import com.rebuild.core.metadata.easymeta.EasyMetaFactory;
|
||||
import com.rebuild.core.privileges.PrivilegesManager;
|
||||
import com.rebuild.core.service.general.QuickCodeReindexTask;
|
||||
import com.rebuild.core.service.trigger.TriggerAction;
|
||||
import com.rebuild.web.BaseController;
|
||||
import com.rebuild.web.EntityParam;
|
||||
|
@ -61,24 +62,27 @@ public class MetadataGetting extends BaseController {
|
|||
for (Entity e : MetadataSorter.sortEntities(usesNopriv ? null : user, usesBizz, usesDetail)) {
|
||||
JSONObject item = (JSONObject) EasyMetaFactory.valueOf(e).toJSON();
|
||||
item.put("name", item.getString("entity"));
|
||||
item.put("label", item.getString("entityLabel"));
|
||||
String L42 = item.getString("entityLabel");
|
||||
item.put("label", L42);
|
||||
item.put("quickCode", QuickCodeReindexTask.generateQuickCode(L42));
|
||||
res.add(item);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
@GetMapping("fields")
|
||||
public JSON fields(HttpServletRequest request) {
|
||||
Entity entity = MetadataHelper.getEntity(getParameterNotNull(request, "entity"));
|
||||
public JSON fields(@EntityParam Entity entity, HttpServletRequest request) {
|
||||
// 返回引用实体的字段层级
|
||||
int appendRefFields = getIntParameter(request, "deep");
|
||||
// 丰富字段信息
|
||||
boolean riching = getBoolParameter(request, "riching", true);
|
||||
|
||||
// 根据不同的 referer 返回不同的字段列表
|
||||
// 返回 ID 主键字段
|
||||
String referer = getParameter(request, "referer");
|
||||
int forceWith = "withid".equals(referer) ? 1 : 0;
|
||||
|
||||
return MetaFormatter.buildFieldsWithRefs(entity, appendRefFields, true, forceWith, field -> {
|
||||
return MetaFormatter.buildFieldsWithRefs(entity, appendRefFields, riching, forceWith, field -> {
|
||||
if (!field.isQueryable()) return true;
|
||||
|
||||
if (field instanceof Field) {
|
||||
|
|
|
@ -27,6 +27,7 @@ import com.rebuild.core.metadata.easymeta.EasyMetaFactory;
|
|||
import com.rebuild.core.privileges.RoleService;
|
||||
import com.rebuild.core.privileges.UserHelper;
|
||||
import com.rebuild.core.privileges.bizz.ZeroEntry;
|
||||
import com.rebuild.core.service.general.QuickCodeReindexTask;
|
||||
import com.rebuild.core.support.i18n.Language;
|
||||
import com.rebuild.utils.JSONUtils;
|
||||
import com.rebuild.utils.RbAssert;
|
||||
|
@ -99,7 +100,9 @@ public class ListFieldsController extends BaseController implements ShareTo {
|
|||
List<Map<String, Object>> fieldList = new ArrayList<>();
|
||||
for (Field field : MetadataSorter.sortFields(entityMeta)) {
|
||||
if (canListField(field)) {
|
||||
fieldList.add(DataListManager.instance.formatField(field));
|
||||
Map<String, Object> m = DataListManager.instance.formatField(field);
|
||||
m.put("quickCode", QuickCodeReindexTask.generateQuickCode((String) m.get("label")));
|
||||
fieldList.add(m);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -121,7 +124,9 @@ public class ListFieldsController extends BaseController implements ShareTo {
|
|||
|
||||
for (Field field2 : MetadataSorter.sortFields(refEntity)) {
|
||||
if (canListField(field2)) {
|
||||
fieldList.add(DataListManager.instance.formatField(field2, field));
|
||||
Map<String, Object> m = DataListManager.instance.formatField(field2, field);
|
||||
m.put("quickCode", QuickCodeReindexTask.generateQuickCode((String) m.get("label")));
|
||||
fieldList.add(m);
|
||||
|
||||
if (deep3 && EasyMetaFactory.getDisplayType(field2) == DisplayType.REFERENCE) {
|
||||
refFieldsOf2.add(new Field[]{field, field2});
|
||||
|
@ -145,7 +150,9 @@ public class ListFieldsController extends BaseController implements ShareTo {
|
|||
|
||||
for (Field field3 : MetadataSorter.sortFields(refEntity2)) {
|
||||
if (canListField(field3)) {
|
||||
fieldList.add(DataListManager.instance.formatField(field3, parentField));
|
||||
Map<String, Object> m = DataListManager.instance.formatField(field3, parentField);
|
||||
m.put("quickCode", QuickCodeReindexTask.generateQuickCode((String) m.get("label")));
|
||||
fieldList.add(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import com.rebuild.core.metadata.easymeta.DisplayType;
|
|||
import com.rebuild.core.metadata.easymeta.EasyField;
|
||||
import com.rebuild.core.metadata.easymeta.EasyMetaFactory;
|
||||
import com.rebuild.core.metadata.impl.EasyFieldConfigProps;
|
||||
import com.rebuild.core.service.general.QuickCodeReindexTask;
|
||||
import com.rebuild.core.support.i18n.Language;
|
||||
import com.rebuild.core.support.state.StateManager;
|
||||
import com.rebuild.utils.JSONUtils;
|
||||
|
@ -71,6 +72,9 @@ public class MetaFormatter {
|
|||
field.getExtraAttr(EasyFieldConfigProps.DECIMAL_FORMAT));
|
||||
}
|
||||
|
||||
String L42 = res.getString("label");
|
||||
res.put("quickCode", QuickCodeReindexTask.generateQuickCode(L42));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -101,10 +105,10 @@ public class MetaFormatter {
|
|||
* 获取字段列表
|
||||
*
|
||||
* @param entity
|
||||
* @param deep 几级
|
||||
* @param deep
|
||||
* @param riching
|
||||
* @param forceWith 1=ID, 2=approvalStepNode
|
||||
* @param filter
|
||||
* @param filter 过滤
|
||||
* @return
|
||||
*/
|
||||
public static JSONArray buildFieldsWithRefs(Entity entity, int deep, boolean riching, int forceWith, Predicate<BaseMeta> filter) {
|
||||
|
@ -203,11 +207,13 @@ public class MetaFormatter {
|
|||
return res;
|
||||
}
|
||||
|
||||
private static JSONObject buildField(EasyField field, String[] parentsField, boolean rich) {
|
||||
private static JSONObject buildField(EasyField field, String[] parentField, boolean rich) {
|
||||
JSONObject item = rich ? buildRichField(field) : (JSONObject) field.toJSON();
|
||||
if (parentsField != null) {
|
||||
item.put("name", parentsField[0] + "." + item.get("name"));
|
||||
item.put("label", parentsField[1] + "." + item.get("label"));
|
||||
if (parentField != null) {
|
||||
item.put("name", parentField[0] + "." + item.get("name"));
|
||||
String L42 = parentField[1] + "." + item.get("label");
|
||||
item.put("label", L42);
|
||||
item.put("quickCode", QuickCodeReindexTask.generateQuickCode(L42));
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
<th:block th:replace="~{/_include/nav-left-admin(active='login-logs')}" />
|
||||
<div class="rb-content">
|
||||
<div class="main-content container-fluid">
|
||||
<div class="card card-table">
|
||||
<div class="card card-table card-topcolor">
|
||||
<div class="card-body">
|
||||
<div class="dataTables_wrapper container-fluid">
|
||||
<div class="row rb-datatable-header">
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<th:block th:replace="~{/_include/nav-left-admin(active='recycle-bin')}" />
|
||||
<div class="rb-content">
|
||||
<div class="main-content container-fluid">
|
||||
<div class="card card-table">
|
||||
<div class="card card-table card-topcolor">
|
||||
<div class="card-body">
|
||||
<div class="dataTables_wrapper container-fluid">
|
||||
<div class="row rb-datatable-header">
|
||||
|
@ -52,8 +52,6 @@
|
|||
<script th:src="@{/assets/js/general/rb-datalist.common.js}" type="text/babel"></script>
|
||||
<script th:src="@{/assets/js/general/rb-datalist.js}" type="text/babel"></script>
|
||||
<script th:src="@{/assets/js/admin/recycle-bin.js}" type="text/babel"></script>
|
||||
<script th:src="@{/assets/lib/prettier/standalone.js}"></script>
|
||||
<script th:src="@{/assets/lib/prettier/parser-babel.js}"></script>
|
||||
<script th:src="@{/assets/lib/clipboard.min.js}"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
<th:block th:replace="~{/_include/nav-left-admin(active='revision-history')}" />
|
||||
<div class="rb-content">
|
||||
<div class="main-content container-fluid">
|
||||
<div class="card card-table">
|
||||
<div class="card card-table card-topcolor">
|
||||
<div class="card-body">
|
||||
<div class="dataTables_wrapper container-fluid">
|
||||
<div class="row rb-datatable-header">
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
<a href="departments" class="nav-link active"><span class="icon mdi mdi-account-multiple"></span> [[${bundle.L('部门')}]]</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="card card-table">
|
||||
<div class="card card-table card-topcolor">
|
||||
<div class="card-body">
|
||||
<div class="dataTables_wrapper container-fluid">
|
||||
<div class="row rb-datatable-header">
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<th:block th:replace="~{/_include/nav-left-admin(active='teams')}" />
|
||||
<div class="rb-content">
|
||||
<div class="main-content container-fluid">
|
||||
<div class="card card-table">
|
||||
<div class="card card-table card-topcolor">
|
||||
<div class="card-body">
|
||||
<div class="dataTables_wrapper container-fluid">
|
||||
<div class="row rb-datatable-header">
|
||||
|
|
|
@ -58,7 +58,7 @@
|
|||
<a href="departments" class="nav-link"><span class="icon mdi mdi-account-multiple"></span> [[${bundle.L('部门')}]]</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="card card-table">
|
||||
<div class="card card-table card-topcolor">
|
||||
<div class="card-body">
|
||||
<div class="dataTables_wrapper container-fluid">
|
||||
<div class="row rb-datatable-header">
|
||||
|
|
|
@ -114,8 +114,6 @@
|
|||
<th:block th:replace="~{/_include/footer}" />
|
||||
<script th:src="@{/assets/js/admin/config-comps.js}" type="text/babel"></script>
|
||||
<script th:src="@{/assets/js/admin/apis-manager.js}" type="text/babel"></script>
|
||||
<script th:src="@{/assets/lib/prettier/standalone.js}"></script>
|
||||
<script th:src="@{/assets/lib/prettier/parser-babel.js}"></script>
|
||||
<script th:src="@{/assets/lib/clipboard.min.js}"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -671,10 +671,8 @@ See LICENSE and COMMERCIAL in the project root for license information.
|
|||
}
|
||||
|
||||
.tcs td.tcs-selected:not(.sel-from) {
|
||||
/*border: 1px double #4887c7;*/
|
||||
/*background-color: rgba(51, 122, 183, 0.2) !important;*/
|
||||
border: 1px double #4285f4;
|
||||
background-color: #f5f8fd;
|
||||
background-color: #f5f8fd !important;
|
||||
}
|
||||
|
||||
.chart-box.CNMAP .chart-body {
|
||||
|
@ -779,6 +777,15 @@ See LICENSE and COMMERCIAL in the project root for license information.
|
|||
|
||||
/* gradient-backgrounds.css */
|
||||
|
||||
.gradient-bg .tcs td.tcs-selected:not(.sel-from) {
|
||||
background-color: rgba(255, 255, 255, 0.5) !important;
|
||||
}
|
||||
|
||||
.gradient-bg .table-bordered th,
|
||||
.gradient-bg .table-bordered td {
|
||||
border-color: rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.gradient-bg-1 {
|
||||
background: linear-gradient(126deg, #c471f5, #fa71cd);
|
||||
}
|
||||
|
|
|
@ -348,6 +348,7 @@ See LICENSE and COMMERCIAL in the project root for license information.
|
|||
width: 100%;
|
||||
height: 240px;
|
||||
background-color: #fff;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
#asideCharts .chart-box .chart-body {
|
||||
|
@ -367,7 +368,6 @@ See LICENSE and COMMERCIAL in the project root for license information.
|
|||
}
|
||||
|
||||
#asideCharts .chart-box:hover .chart-oper a.J_source,
|
||||
#asideCharts .chart-box:hover .chart-oper a.J_fullscreen,
|
||||
#asideCharts .chart-box:hover .chart-oper a.J_chart-edit,
|
||||
#asideCharts .chart-box:hover .chart-oper a.J_export {
|
||||
display: none !important;
|
||||
|
@ -381,11 +381,28 @@ See LICENSE and COMMERCIAL in the project root for license information.
|
|||
position: fixed;
|
||||
top: 60px !important;
|
||||
left: 230px !important;
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
right: 0 !important;
|
||||
bottom: 0 !important;
|
||||
z-index: 9999;
|
||||
background-color: #fff;
|
||||
padding: 20px;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
#asideCharts .charts-wrap > div.fullscreen .chart-box {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) and (max-width: 1464px) {
|
||||
#asideCharts .charts-wrap > div.fullscreen {
|
||||
left: 200px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.rb-collapsible-sidebar-collapsed #asideCharts .charts-wrap > div.fullscreen {
|
||||
left: 60px !important;
|
||||
}
|
||||
|
||||
#asideCharts .charts-wrap .ui-sortable-helper {
|
||||
|
@ -444,3 +461,21 @@ See LICENSE and COMMERCIAL in the project root for license information.
|
|||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.dataTables_wrapper .rb-datatable-header.v42 {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.dataTables_wrapper .rb-datatable-header.v42 > div {
|
||||
flex: none;
|
||||
white-space: nowrap;
|
||||
width: unset;
|
||||
max-width: unset;
|
||||
}
|
||||
|
||||
.dataTables_wrapper .rb-datatable-header.v42 > div.right {
|
||||
text-align: right;
|
||||
}
|
||||
|
|
|
@ -3840,10 +3840,14 @@ a.user-show:not([href]) {
|
|||
}
|
||||
|
||||
.page-aside.widgets {
|
||||
z-index: 2;
|
||||
z-index: 3;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.page-aside.widgets + .main-content {
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.page-aside.widgets .tab-container {
|
||||
min-width: 279px;
|
||||
overflow: hidden;
|
||||
|
|
|
@ -264,9 +264,9 @@ class AppLogsViewer extends RbModal {
|
|||
<dt className="col-sm-3">{$L('请求地址')}</dt>
|
||||
<dd className="col-sm-9 text-break">{dataShow[3]}</dd>
|
||||
<dt className="col-sm-12">{$L('请求数据')}</dt>
|
||||
<dd className="col-sm-12">{dataShow[4] && <CodeViewport code={dataShow[4]} />}</dd>
|
||||
<dd className="col-sm-12">{dataShow[4] && <CodeViewport code={dataShow[4]} type="json" />}</dd>
|
||||
<dt className="col-sm-12">{$L('响应数据')}</dt>
|
||||
<dd className="col-sm-12 mb-0">{dataShow[5] && <CodeViewport code={dataShow[5]} />}</dd>
|
||||
<dd className="col-sm-12 mb-0">{dataShow[5] && <CodeViewport code={dataShow[5]} type="json" />}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
) : (
|
||||
|
|
|
@ -545,10 +545,12 @@ class StartNodeConfig extends RbFormHandler {
|
|||
<p className="form-text m-0">{$L('符合条件的记录才可以使用/选择此流程')}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="form-group mt-5 bosskey-show">
|
||||
|
||||
<div className="form-group mt-5 mb-0">
|
||||
<label className="text-bold">{$L('禁止撤回')}</label>
|
||||
<label className="custom-control custom-control-sm custom-checkbox">
|
||||
<input className="custom-control-input" type="checkbox" name="unallowCancel" checked={this.state.unallowCancel === true} onChange={this.handleChange} />
|
||||
<span className="custom-control-label">{$L('审批后禁止提交人撤回')} (LAB)</span>
|
||||
<span className="custom-control-label">{$L('审批后禁止提交人撤回')}</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -169,7 +169,7 @@ CellRenders.renderSimple = function (v, s, k) {
|
|||
// ~~ 数据详情
|
||||
class DlgDetails extends RbAlert {
|
||||
renderContent() {
|
||||
return this.state.code && <CodeViewport code={this.state.code} />
|
||||
return this.state.code && <CodeViewport code={this.state.code} type="json" />
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
|
|
|
@ -35,7 +35,9 @@ class ReportList extends ConfigList {
|
|||
{taggedTitle(item[3])}
|
||||
</a>
|
||||
) : (
|
||||
taggedTitle(item[3])
|
||||
<a title={$L('模版在线编辑')} href={`${rb.baseUrl}/commons/file-editor?src=${item[0]}`}>
|
||||
{taggedTitle(item[3])}
|
||||
</a>
|
||||
)}
|
||||
{item[6] === 1 && <span className="badge badge-info badge-arrow3 badge-pill ml-1 excel">EXCEL</span>}
|
||||
{item[6] === 2 && <span className="badge badge-info badge-arrow3 badge-pill ml-1 excel">{$L('EXCEL 列表')}</span>}
|
||||
|
|
|
@ -191,7 +191,7 @@ $(document).ready(() => {
|
|||
// 背景色
|
||||
function _removeClass($el) {
|
||||
$el.removeClass(function (index, className) {
|
||||
return (className.match(/\bgradient-bg-\S+/g) || []).join(' ')
|
||||
return (className.match(/gradient-bg(?:-\d+)?/g) || []).join(' ')
|
||||
})
|
||||
return $el
|
||||
}
|
||||
|
@ -207,7 +207,7 @@ $(document).ready(() => {
|
|||
renderRbcomp(
|
||||
<DlgBgcolor
|
||||
onConfirm={(colorIndex) => {
|
||||
_removeClass($('#chart-preview >.chart-box')).addClass(`gradient-bg-${colorIndex}`)
|
||||
_removeClass($('#chart-preview >.chart-box')).addClass(`gradient-bg gradient-bg-${colorIndex}`)
|
||||
_removeClass($bs.find('>a:eq(1)')).addClass(`gradient-bg-${colorIndex}`)
|
||||
$bs.find('>a:eq(0)').attr('data-bgcolor', colorIndex)
|
||||
// check
|
||||
|
|
|
@ -109,12 +109,13 @@ class BaseChart extends React.Component {
|
|||
const $stack = $('.chart-grid>.grid-stack')
|
||||
if (!$stack[0]) {
|
||||
// in DataList
|
||||
// $(this._$box).parent().toggleClass('fullscreen')
|
||||
const $wrap = $(this._$box).parent()
|
||||
$wrap.toggleClass('fullscreen')
|
||||
this.resize()
|
||||
return
|
||||
}
|
||||
|
||||
const $boxParent = $(this._$box).parents('.grid-stack-item')
|
||||
|
||||
if (this.state.fullscreen) {
|
||||
BaseChart.currentFullscreen = this
|
||||
if (!this.__chartStackHeight) this.__chartStackHeight = $stack.height()
|
||||
|
@ -527,9 +528,14 @@ const reOptionMutliYAxis = function (option) {
|
|||
}
|
||||
|
||||
const renderEChart = function (option, $target) {
|
||||
const c = echarts.init(document.getElementById($target), 'light', {
|
||||
$target = document.getElementById($target)
|
||||
const c = echarts.init($target, 'light', {
|
||||
renderer: navigator.userAgent.match(/(iPhone|iPod|Android|ios|SymbianOS)/i) ? 'svg' : 'canvas',
|
||||
})
|
||||
// v4.2 禁用右键
|
||||
$target.addEventListener('contextmenu', function (e) {
|
||||
e.preventDefault()
|
||||
})
|
||||
if (rb.env === 'dev') console.log(option)
|
||||
c.setOption(option)
|
||||
return c
|
||||
|
|
|
@ -355,7 +355,17 @@ class DlgAddChart extends RbFormHandler {
|
|||
<div className="form-group row">
|
||||
<label className="col-sm-3 col-form-label text-sm-right">{$L('图表数据来源')}</label>
|
||||
<div className="col-sm-7">
|
||||
<select className="form-control form-control-sm" ref={(c) => (this._$entity = c)} />
|
||||
<select className="form-control form-control-sm" ref={(c) => (this._$entity = c)}>
|
||||
{this.state._entities &&
|
||||
this.state._entities.map((item) => {
|
||||
if ($isSysMask(item.label)) return null
|
||||
return (
|
||||
<option key={item.name} value={item.name} data-pinyin={item.quickCode}>
|
||||
{item.label}
|
||||
</option>
|
||||
)
|
||||
})}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div className="form-group row footer">
|
||||
|
@ -375,16 +385,11 @@ class DlgAddChart extends RbFormHandler {
|
|||
|
||||
componentDidMount() {
|
||||
$.get('/commons/metadata/entities?detail=true', (res) => {
|
||||
const _data = res.data || []
|
||||
_data.forEach((item) => {
|
||||
if (!$isSysMask(item.label)) {
|
||||
$(`<option value="${item.name}">${item.label}</option>`).appendTo(this._$entity)
|
||||
}
|
||||
})
|
||||
|
||||
this.__select2 = $(this._$entity).select2({
|
||||
allowClear: false,
|
||||
placeholder: $L('选择数据来源'),
|
||||
this.setState({ _entities: res.data || [] }, () => {
|
||||
this.__select2 = $(this._$entity).select2({
|
||||
allowClear: false,
|
||||
placeholder: $L('选择数据来源'),
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ See LICENSE and COMMERCIAL in the project root for license information.
|
|||
// ~~ 图片/文档预览
|
||||
|
||||
const TYPE_TEXTS = ['.txt', '.xml', '.json', '.md', '.yml', '.css', '.js', '.htm', '.html', '.log', '.sql', '.conf', '.sh', '.bat', '.java', '.ini']
|
||||
const TYPE_DOCS = ['.doc', '.docx', '.rtf', '.xls', '.xlsx', '.ppt', '.pptx', '.pdf']
|
||||
const TYPE_DOCS = ['.doc', '.docx', '.xls', '.xlsx', '.ppt', '.pptx', '.pdf'] // .rtf, .csv
|
||||
const TYPE_IMGS = ['.jpg', '.jpeg', '.gif', '.png', '.bmp', '.jfif', '.webp']
|
||||
const TYPE_AUDIOS = ['.mp3', '.wma', '.m4a', '.flac', '.ogg', '.acc']
|
||||
const TYPE_VIDEOS = ['.mp4', '.wmv', '.mov', '.avi', '.mkv', '.webm', '.m4v', '.mpg', '.mpge']
|
||||
|
@ -57,6 +57,11 @@ class RbPreview extends React.Component {
|
|||
<h5 className="text-bold">{fileName}</h5>
|
||||
</div>
|
||||
<div className="float-right">
|
||||
{this.props.id && this._isDoc(fileName) && (
|
||||
<a href={`${rb.baseUrl}/commons/file-editor?src=${this.props.id}`} target="_blank" title={$L('在线编辑')}>
|
||||
<i className="mdi mdi-microsoft-office fs-17" />
|
||||
</a>
|
||||
)}
|
||||
{rb.fileSharable && (
|
||||
<a onClick={this.share} title={$L('分享')}>
|
||||
<i className="zmdi zmdi-share fs-17" />
|
||||
|
@ -388,11 +393,12 @@ class RbPreview extends React.Component {
|
|||
/**
|
||||
* @param {*} urls string or array of URL
|
||||
* @param {*} index
|
||||
* @param {*} id
|
||||
*/
|
||||
static create(urls, index) {
|
||||
static create(urls, index, id) {
|
||||
if (!urls) return
|
||||
if (typeof urls === 'string') urls = [urls]
|
||||
renderRbcomp(<RbPreview urls={urls} currentIndex={index || 0} />)
|
||||
renderRbcomp(<RbPreview urls={urls} currentIndex={index || 0} id={id} />)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -423,20 +423,30 @@ class FileEditDlg extends RbFormHandler {
|
|||
|
||||
render() {
|
||||
const file = this.props.file
|
||||
const isOffice = ['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx'].includes($fileExtName(file.fileName))
|
||||
return (
|
||||
<RbModal title={$L('修改文件')} ref={(c) => (this._dlg = c)} disposeOnHide>
|
||||
<div className="form">
|
||||
<div className="form-group row">
|
||||
<label className="col-sm-3 col-form-label text-sm-right">{$L('文件名称')}</label>
|
||||
<label className="col-sm-3 col-form-label text-sm-right">{$L('重命名')}</label>
|
||||
<div className="col-sm-7">
|
||||
<input className="form-control form-control-sm" defaultValue={file.fileName} ref={(c) => (this._$fileName = c)} />
|
||||
<p className="form-text bosskey-show">
|
||||
<a href={`${rb.baseUrl}/commons/file-editor?src=${file.id}`} target="_blank">
|
||||
{$L('在线编辑')} (LAB)
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{isOffice && (
|
||||
<div className="form-group row p-0">
|
||||
<label className="col-sm-3 col-form-label text-sm-right" />
|
||||
<div className="col-sm-7">
|
||||
<div className="form-control-plaintext">
|
||||
<a href={`${rb.baseUrl}/commons/file-editor?src=${file.id}`} target="_blank">
|
||||
<i className="mdi mdi-microsoft-office icon" />
|
||||
|
||||
{$L('在线编辑')}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className="form-group row footer">
|
||||
<div className="col-sm-7 offset-sm-3" ref={(c) => (this._btns = c)}>
|
||||
<button className="btn btn-primary" type="button" onClick={this._post}>
|
||||
|
@ -481,7 +491,7 @@ class FilesList4Docs extends FilesList {
|
|||
<div className="info position-relative">
|
||||
<span className="fop-action">
|
||||
<a title={$L('修改')} onClick={(e) => this._handleEdit(item, e)}>
|
||||
<i className="icon zmdi zmdi-edit up-1" />
|
||||
<i className="icon mdi mdi-square-edit-outline fs-17" />
|
||||
</a>
|
||||
<a title={$L('下载')} onClick={(e) => $stopEvent(e)} href={`${rb.baseUrl}/files/download?id=${item.id}`} target="_blank">
|
||||
<i className="icon zmdi zmdi-download fs-17" />
|
||||
|
|
|
@ -83,7 +83,7 @@ class FilesList extends React.Component {
|
|||
{this._pageNo === 1 && this.state.files && this.state.files.length === 0 && (
|
||||
<div className="list-nodata">
|
||||
<i className="zmdi zmdi-folder-outline" />
|
||||
<p>{$L('暂无数据')}</p>
|
||||
<p>{$L('暂无文件')}</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
@ -32,7 +32,7 @@ $(document).ready(() => {
|
|||
|
||||
$(_data.fieldList).each(function () {
|
||||
// eslint-disable-next-line no-undef
|
||||
if (!$isSysMask(this.label)) render_unset([this.field, this.label])
|
||||
if (!$isSysMask(this.label)) render_unset([this.field, this.label, this.quickCode])
|
||||
})
|
||||
$(_data.configList).each(function () {
|
||||
const fkey = this.field
|
||||
|
@ -119,7 +119,8 @@ $(document).ready(() => {
|
|||
const q = $trim(e.target.value).toLowerCase()
|
||||
$('.unset-list .dd-item').each(function () {
|
||||
const $item = $(this)
|
||||
if (!q || $item.text().toLowerCase().includes(q) || $item.data('key').toLowerCase().includes(q)) {
|
||||
const pinyin = $item.data('pinyin')
|
||||
if (!q || $item.text().toLowerCase().includes(q) || $item.data('key').toLowerCase().includes(q) || (pinyin && pinyin.toLowerCase().includes(q))) {
|
||||
$item.removeClass('hide')
|
||||
} else {
|
||||
$item.addClass('hide')
|
||||
|
|
|
@ -381,7 +381,7 @@ class FilterItem extends React.Component {
|
|||
<select className="form-control form-control-sm" ref={(c) => (this._filterField = c)}>
|
||||
{this.state.fields.map((item) => {
|
||||
return (
|
||||
<option value={item.name + NT_SPLIT + item.type} key={`field-${item.name}`} title={item.label}>
|
||||
<option value={item.name + NT_SPLIT + item.type} key={item.name} title={item.label} data-pinyin={item.quickCode}>
|
||||
{item.label}
|
||||
</option>
|
||||
)
|
||||
|
@ -392,7 +392,7 @@ class FilterItem extends React.Component {
|
|||
<select className="form-control form-control-sm" ref={(c) => (this._filterOp = c)}>
|
||||
{this.selectOp().map((item) => {
|
||||
return (
|
||||
<option value={item} key={`op-${item}`} title={OP_TYPE[item]}>
|
||||
<option value={item} key={item} title={OP_TYPE[item]}>
|
||||
{OP_TYPE[item]}
|
||||
</option>
|
||||
)
|
||||
|
@ -442,8 +442,8 @@ class FilterItem extends React.Component {
|
|||
op = ['IN', 'NIN']
|
||||
}
|
||||
|
||||
// v3.6-b4,v3.7
|
||||
if (['TEXT', 'PHONE', 'EMAIL', 'URL', 'DATE', 'DATETIME', 'TIME'].includes(fieldType)) op.push('REP')
|
||||
// v3.6-b4, v3.7, v4.2
|
||||
if (['TEXT', 'PHONE', 'EMAIL', 'URL', 'DATE', 'DATETIME', 'TIME', 'REFERENCE', 'ANYREFERENCE'].includes(fieldType)) op.push('REP')
|
||||
|
||||
if (this.isApprovalState()) op = ['IN', 'NIN']
|
||||
else if (this.state.field === VF_ACU) op = ['IN', 'SFU', 'SFB', 'SFT'] // v3.7 准备废弃
|
||||
|
|
|
@ -876,11 +876,11 @@ const RbListCommon = {
|
|||
|
||||
def40 = def40.split(':') // FILTER:LAYOUT
|
||||
if (def40[0]) {
|
||||
if (def40[0].startsWith('014-')) wpc.protocolFilter = `via:${def40[0]}`
|
||||
if (def40[0].startsWith('014-')) wpc.protocolFilterAnd = `via:${def40[0]}`
|
||||
else console.log('Use listConfig :', def40[0])
|
||||
}
|
||||
if (def40[1]) {
|
||||
if (def40[1].startsWith('014-')) wpc.protocolFilter = `via:${def40[1]}`
|
||||
if (def40[1].startsWith('014-')) wpc.protocolFilterAnd = `via:${def40[1]}`
|
||||
else console.log('Use listConfig :', def40[1])
|
||||
}
|
||||
}
|
||||
|
@ -1211,6 +1211,7 @@ class RbList extends React.Component {
|
|||
filter: this.lastFilter,
|
||||
advFilter: this.advFilterId,
|
||||
protocolFilter: this.props.protocolFilter || wpc.protocolFilter,
|
||||
protocolFilterAnd: this.props.protocolFilterAnd || wpc.protocolFilterAnd,
|
||||
sort: sort,
|
||||
reload: reload,
|
||||
statsField: wpc.statsField === true && rb.commercial > 0,
|
||||
|
@ -2347,6 +2348,7 @@ const CategoryWidget = {
|
|||
onItemClick={(query) => {
|
||||
if (!query || query[0] === CategoryWidget.__ALL) wpc.protocolFilter = null
|
||||
else wpc.protocolFilter = `category:${wpc.entity[0]}:${query.join('$$$$')}`
|
||||
_RbList().pageNo = 1
|
||||
RbListPage.reload()
|
||||
}}
|
||||
/>,
|
||||
|
|
|
@ -312,6 +312,7 @@ $(document).ready(() => {
|
|||
// v4.1 AI
|
||||
window.attachAibotPageData = function (cb) {
|
||||
renderRbcomp(
|
||||
// eslint-disable-next-line react/jsx-no-undef
|
||||
<DlgAttachRecordList
|
||||
onConfirm={(s) => {
|
||||
const qe = RbListPage._RbList.getLastQueryEntry()
|
||||
|
|
|
@ -810,7 +810,7 @@ class CompCategoryItem extends React.Component {
|
|||
<select className="form-control form-control-sm" ref={(c) => (this._$field = c)}>
|
||||
{this.props.fields.map((item) => {
|
||||
return (
|
||||
<option key={item.name} value={item.name}>
|
||||
<option key={item.name} value={item.name} data-pinyin={item.quickCode}>
|
||||
{item.label}
|
||||
</option>
|
||||
)
|
||||
|
|
|
@ -23,7 +23,7 @@ $(document).ready(() => {
|
|||
$.get('/commons/metadata/entities?detail=true', (res) => {
|
||||
$(res.data).each(function () {
|
||||
if (!$isSysMask(this.label)) {
|
||||
$(`<option value="${this.name}">${this.label}</option>`).appendTo('.J_menuEntity optgroup:eq(0)')
|
||||
$(`<option value="${this.name}" data-pinyin="${this.quickCode}">${this.label}</option>`).appendTo('.J_menuEntity optgroup:eq(0)')
|
||||
}
|
||||
_entities[this.name] = this
|
||||
})
|
||||
|
@ -33,7 +33,9 @@ $(document).ready(() => {
|
|||
placeholder: $L('选择关联项'),
|
||||
allowClear: false,
|
||||
templateResult: function (res) {
|
||||
const $span = $('<span class="icon-append"></span>').attr('title', res.text).text(res.text)
|
||||
console.log(res)
|
||||
const $span = $('<span></span>').attr('title', res.text).text(res.text)
|
||||
if (!res.children) $span.addClass('icon-append') // optgroup
|
||||
const found = _entities[res.id]
|
||||
if (found) $(`<i class="icon zmdi zmdi-${found.icon}"></i>`).appendTo($span)
|
||||
return $span
|
||||
|
|
|
@ -1173,7 +1173,7 @@ class Md2Html extends React.Component {
|
|||
}
|
||||
|
||||
// 替换换行并保持表格换行
|
||||
let cHtml = marked.parse(md.replace(/(?<!\|)\n(?!\|)/g, '\n\n'))
|
||||
let cHtml = marked.parse(md.replace(/(?<!\|)\n(?!\|)/g, '\n'))
|
||||
cHtml = cHtml.replace(/<img src="([^"]+)"/g, function (s, src) {
|
||||
let srcNew = src + (src.includes('?') ? '&' : '?') + 'imageView2/2/w/1000/interlace/1/q/100'
|
||||
return s.replace(src, srcNew)
|
||||
|
@ -1199,13 +1199,17 @@ class Md2Html extends React.Component {
|
|||
.each(function () {
|
||||
const $img = $(this)
|
||||
let isrc = $img.attr('src')
|
||||
isrc = isrc.split('/filex/img/')[1].split(/[?&]imageView2/)[0]
|
||||
imgs.push(isrc)
|
||||
$img.on('click', (e) => {
|
||||
$stopEvent(e, true)
|
||||
const p = parent || window
|
||||
p.RbPreview.create(imgs, imgs.indexOf(isrc) || 0)
|
||||
})
|
||||
if (isrc) {
|
||||
if (isrc.includes('/filex/img/')) {
|
||||
isrc = isrc.split('/filex/img/')[1].split(/[?&]imageView2/)[0]
|
||||
}
|
||||
imgs.push(isrc)
|
||||
$img.on('click', (e) => {
|
||||
$stopEvent(e, true)
|
||||
const p = parent || window
|
||||
p.RbPreview.create(imgs, imgs.indexOf(isrc) || 0)
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
@ -1318,7 +1322,7 @@ class CodeViewport extends React.Component {
|
|||
}
|
||||
|
||||
componentDidMount() {
|
||||
this._$code.innerHTML = $formattedCode(this.props.code || '')
|
||||
this._$code.innerHTML = $formattedCode(this.props.code || '', this.props.type)
|
||||
|
||||
if (this._$copy) {
|
||||
const that = this
|
||||
|
@ -1333,7 +1337,10 @@ class CodeViewport extends React.Component {
|
|||
}
|
||||
|
||||
UNSAFE_componentWillReceiveProps(newProps) {
|
||||
if (newProps.code) this._$code.innerHTML = $formattedCode(newProps.code)
|
||||
// eslint-disable-next-line eqeqeq
|
||||
if (newProps.code && newProps.code != this.props.code) {
|
||||
this._$code.innerHTML = $formattedCode(newProps.code, this.props.type)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -472,7 +472,7 @@ var _showNotification = function (state) {
|
|||
var _Notification = window.Notification || window.mozNotification || window.webkitNotification
|
||||
if (_Notification) {
|
||||
if (_Notification.permission === 'granted') {
|
||||
var n = new _Notification($L('你有 %d 条未读消息', state), {
|
||||
var n = new _Notification($L('你有 %d 条未读通知', state), {
|
||||
body: window.rb.appName,
|
||||
icon: rb.baseUrl + '/assets/img/icon-192x192.png',
|
||||
tag: 'rbNotification',
|
||||
|
@ -1239,14 +1239,18 @@ var $select2MatcherAll = function (params, data) {
|
|||
return null
|
||||
}
|
||||
|
||||
function _matcher(item, s) {
|
||||
// 匹配
|
||||
function _FN(item, s) {
|
||||
s = s.toLowerCase()
|
||||
return (item.text || '').toLowerCase().indexOf(s) > -1 || (item.id || '').toLowerCase().indexOf(s) > -1
|
||||
if ((item.text || '').toLowerCase().indexOf(s) > -1 || (item.id || '').toLowerCase().indexOf(s) > -1) return true
|
||||
// v4.2
|
||||
var pinyin = $(item.element).data('pinyin')
|
||||
return pinyin && pinyin.toLowerCase().indexOf(s) > -1
|
||||
}
|
||||
|
||||
if (data.children) {
|
||||
var ch = data.children.filter(function (item) {
|
||||
return _matcher(item, params.term)
|
||||
return _FN(item, params.term)
|
||||
})
|
||||
if (ch.length === 0) return null
|
||||
|
||||
|
@ -1254,7 +1258,7 @@ var $select2MatcherAll = function (params, data) {
|
|||
data2.children = ch
|
||||
return data2
|
||||
} else {
|
||||
if (_matcher(data, params.term)) {
|
||||
if (_FN(data, params.term, data.element)) {
|
||||
return data
|
||||
}
|
||||
}
|
||||
|
@ -1307,21 +1311,25 @@ var $pages = function (tp, cp) {
|
|||
|
||||
// 格式化代码
|
||||
var $formattedCode = function (c, type) {
|
||||
if (typeof c === 'object') c = JSON.stringify(c)
|
||||
if (!window.prettier) return c
|
||||
|
||||
try {
|
||||
// eslint-disable-next-line no-undef
|
||||
return prettier.format(c, {
|
||||
parser: type || 'json',
|
||||
// eslint-disable-next-line no-undef
|
||||
plugins: prettierPlugins,
|
||||
printWidth: 10,
|
||||
})
|
||||
} catch (err) {
|
||||
console.log('Cannot format code :', err)
|
||||
return c
|
||||
// v4.2
|
||||
if (type === 'json') {
|
||||
return JSON.stringify(typeof c === 'object' ? c : JSON.parse(c), null, 2)
|
||||
}
|
||||
|
||||
if (typeof c === 'object') c = JSON.stringify(c)
|
||||
if (window.prettier) {
|
||||
try {
|
||||
return window.prettier.format(c, {
|
||||
parser: type || 'json',
|
||||
plugins: window.prettierPlugins,
|
||||
printWidth: 10,
|
||||
})
|
||||
} catch (err) {
|
||||
console.log('Cannot format code :', err)
|
||||
return c
|
||||
}
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
// 复制
|
||||
|
|
|
@ -18,6 +18,7 @@ $(document).ready(function () {
|
|||
|
||||
const render_unset = function (data, target) {
|
||||
const $item = $(`<li class="dd-item" data-key="${data[0]}"><div class="dd-handle"><span>${data[1]}</span></div></li>`).appendTo(target || '.unset-list')
|
||||
if (data[2]) $item.attr('data-pinyin', data[2])
|
||||
$item.on('click', function () {
|
||||
render_item(data)
|
||||
$item.remove()
|
||||
|
|
|
@ -61,7 +61,7 @@
|
|||
<div class="card card-table card-topcolor">
|
||||
<div class="card-body">
|
||||
<div class="dataTables_wrapper container-fluid">
|
||||
<div class="row rb-datatable-header">
|
||||
<div class="row rb-datatable-header v42">
|
||||
<div class="col-12 col-md-6 pr-0">
|
||||
<div class="dataTables_filter">
|
||||
<div class="adv-search float-left">
|
||||
|
@ -87,7 +87,7 @@
|
|||
<span id="dropdown-menu-advfilter"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-md-6 pl-0">
|
||||
<div class="col-12 col-md-6 pl-2 right">
|
||||
<div class="dataTables_oper invisible2">
|
||||
<button class="btn btn-space btn-secondary J_view" type="button" disabled="disabled"><i class="icon mdi mdi-folder-open"></i> [[${bundle.L('打开')}]]</button>
|
||||
<button class="btn btn-space btn-secondary J_edit" type="button" disabled="disabled"><i class="icon zmdi zmdi-edit"></i> [[${bundle.L('编辑')}]]</button>
|
||||
|
@ -133,6 +133,7 @@
|
|||
}
|
||||
</script>
|
||||
<script th:src="@{/assets/lib/charts/echarts.min.js?v=5.5.0}"></script>
|
||||
<script th:src="@{/assets/lib/charts/tablecellsselection.js}"></script>
|
||||
<script th:src="@{/assets/js/charts/charts.js}" type="text/babel"></script>
|
||||
<script th:src="@{/assets/js/metadata/field-compatible.js}" type="text/babel"></script>
|
||||
<script th:src="@{/assets/js/metadata/field-valueset.js}" type="text/babel"></script>
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
position: relative;
|
||||
display: block;
|
||||
z-index: 1;
|
||||
border-radius: 4px;
|
||||
margin-top: 44px;
|
||||
border-top: 2px solid var(--rb-theme-color);
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
.iframe-wrap {
|
||||
margin-top: 44px;
|
||||
overflow: hidden;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.iframe-wrap iframe {
|
||||
position: relative;
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
.sortable-box-title a.search-btn {
|
||||
position: absolute;
|
||||
font-size: 1.231rem;
|
||||
margin-top: -2px;
|
||||
margin-top: -1px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
.sortable-box-title a.search-btn:hover {
|
||||
|
|
|
@ -61,7 +61,7 @@
|
|||
<div class="card card-table card-topcolor">
|
||||
<div class="card-body">
|
||||
<div class="dataTables_wrapper container-fluid">
|
||||
<div class="row rb-datatable-header">
|
||||
<div class="row rb-datatable-header v42">
|
||||
<div class="col-12 col-md-6 pr-0">
|
||||
<div class="dataTables_filter">
|
||||
<div class="adv-search float-left">
|
||||
|
@ -87,7 +87,7 @@
|
|||
<span id="dropdown-menu-advfilter"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-md-6 pl-0">
|
||||
<div class="col-12 col-md-6 pl-2 right">
|
||||
<div class="dataTables_oper invisible2">
|
||||
<button class="btn btn-space btn-secondary J_view" type="button" disabled="disabled"><i class="icon mdi mdi-folder-open"></i> [[${bundle.L('打开')}]]</button>
|
||||
<button class="btn btn-space btn-secondary J_edit" type="button" disabled="disabled"><i class="icon zmdi zmdi-edit"></i> [[${bundle.L('编辑')}]]</button>
|
||||
|
@ -144,6 +144,7 @@
|
|||
}
|
||||
</script>
|
||||
<script th:src="@{/assets/lib/charts/echarts.min.js?v=5.5.0}"></script>
|
||||
<script th:src="@{/assets/lib/charts/tablecellsselection.js}"></script>
|
||||
<script th:src="@{/assets/js/charts/charts.js}" type="text/babel"></script>
|
||||
<script th:src="@{/assets/js/metadata/field-compatible.js}" type="text/babel"></script>
|
||||
<script th:src="@{/assets/js/metadata/field-valueset.js}" type="text/babel"></script>
|
||||
|
|
Loading…
Add table
Reference in a new issue