mirror of
https://github.com/getrebuild/rebuild.git
synced 2024-09-20 15:35:55 +08:00
parent
7ba44f5a28
commit
18680ce4a9
2
pom.xml
2
pom.xml
|
@ -10,7 +10,7 @@
|
|||
</parent>
|
||||
<groupId>com.rebuild</groupId>
|
||||
<artifactId>rebuild</artifactId>
|
||||
<version>2.9.0-beta2</version>
|
||||
<version>2.10.0-dev</version>
|
||||
<name>rebuild</name>
|
||||
<description>Building your business-systems freely!</description>
|
||||
<!-- UNCOMMENT USE TOMCAT -->
|
||||
|
|
|
@ -65,11 +65,11 @@ public class Application implements ApplicationListener<ApplicationStartedEvent>
|
|||
/**
|
||||
* Rebuild Version
|
||||
*/
|
||||
public static final String VER = "2.9.0-beta2";
|
||||
public static final String VER = "2.10.0-dev";
|
||||
/**
|
||||
* Rebuild Build [MAJOR]{1}[MINOR]{2}[PATCH]{2}[BUILD]{2}
|
||||
*/
|
||||
public static final int BUILD = 2090002;
|
||||
public static final int BUILD = 210000;
|
||||
|
||||
static {
|
||||
// Driver for DB
|
||||
|
|
|
@ -24,10 +24,7 @@ import com.rebuild.core.support.i18n.Language;
|
|||
import com.rebuild.utils.JSONUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 视图-相关项/新建相关
|
||||
|
@ -72,6 +69,42 @@ public class ViewAddonsManager extends BaseLayoutManager {
|
|||
return vtabs;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取显示项过滤条件
|
||||
*
|
||||
* @param entity
|
||||
* @param user
|
||||
* @return
|
||||
*/
|
||||
public Map<String, JSONObject> getViewTabFilters(String entity, ID user) {
|
||||
final ConfigBean config = getLayout(user, entity, TYPE_TAB);
|
||||
if (config == null) return Collections.emptyMap();
|
||||
|
||||
// compatible: v2.2
|
||||
JSON configJson = config.getJSON("config");
|
||||
if (configJson instanceof JSONArray) {
|
||||
configJson = JSONUtils.toJSONObject("items", configJson);
|
||||
}
|
||||
|
||||
JSONArray items = ((JSONObject) configJson).getJSONArray("items");
|
||||
if (items == null || items.isEmpty()) return Collections.emptyMap();
|
||||
|
||||
Map<String, JSONObject> filters = new HashMap<>();
|
||||
for (Object o : items) {
|
||||
// compatible: v2.8
|
||||
if (!(o instanceof JSONArray)) continue;
|
||||
|
||||
JSONArray item = (JSONArray) o;
|
||||
if (item.size() < 3) continue;
|
||||
|
||||
String entityKey = item.getString(0);
|
||||
JSONObject filter = item.getJSONObject(2);
|
||||
if (filter != null) filters.put(entityKey, filter);
|
||||
}
|
||||
|
||||
return filters;
|
||||
}
|
||||
|
||||
/**
|
||||
* 新建项
|
||||
*
|
||||
|
|
|
@ -14,11 +14,14 @@ import cn.devezhao.persist4j.Field;
|
|||
import cn.devezhao.persist4j.dialect.FieldType;
|
||||
import cn.devezhao.persist4j.engine.ID;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.rebuild.core.Application;
|
||||
import com.rebuild.core.configuration.general.ViewAddonsManager;
|
||||
import com.rebuild.core.metadata.EntityHelper;
|
||||
import com.rebuild.core.metadata.MetadataHelper;
|
||||
import com.rebuild.core.service.approval.ApprovalState;
|
||||
import com.rebuild.core.service.feeds.FeedsType;
|
||||
import com.rebuild.core.service.query.AdvFilterParser;
|
||||
import com.rebuild.core.service.query.ParseHelper;
|
||||
import com.rebuild.core.service.query.QueryHelper;
|
||||
import com.rebuild.core.support.general.FieldValueHelper;
|
||||
|
@ -54,16 +57,20 @@ public class RelatedListController extends BaseController {
|
|||
|
||||
String related = getParameterNotNull(request, "related");
|
||||
String q = getParameter(request, "q");
|
||||
String sort = getParameter(request, "sort", "modifiedOn:desc");
|
||||
String sql = buildBaseSql(mainid, related, q, false, user, null);
|
||||
|
||||
String sql = buildMainSql(mainid, related, q, false, user);
|
||||
Entity relatedEntity = MetadataHelper.getEntity(related.split("\\.")[0]);
|
||||
|
||||
String sort = getParameter(request, "sort", "modifiedOn:desc");
|
||||
// 名称字段排序
|
||||
if ("NAME".equalsIgnoreCase(sort)) {
|
||||
sort = relatedEntity.getNameField().getName() + ":asc";
|
||||
}
|
||||
sql += " order by " + sort.replace(":", " ");
|
||||
|
||||
int pn = NumberUtils.toInt(getParameter(request, "pageNo"), 1);
|
||||
int ps = NumberUtils.toInt(getParameter(request, "pageSize"), 200);
|
||||
|
||||
Entity relatedEntity = MetadataHelper.getEntity(related.split("\\.")[0]);
|
||||
|
||||
Object[][] array = QueryHelper.createQuery(sql, relatedEntity).setLimit(ps, pn * ps - ps).array();
|
||||
|
||||
List<Object> res = new ArrayList<>();
|
||||
|
@ -91,12 +98,16 @@ public class RelatedListController extends BaseController {
|
|||
|
||||
@GetMapping("related-counts")
|
||||
public Map<String, Integer> relatedCounts(@IdParam(name = "mainid") ID mainid, HttpServletRequest request) {
|
||||
final ID user = getRequestUser(request);
|
||||
String[] relateds = getParameterNotNull(request, "relateds").split(",");
|
||||
|
||||
final ID user = getRequestUser(request);
|
||||
// 附件过滤条件
|
||||
Map<String, JSONObject> vtabFilters = ViewAddonsManager.instance.getViewTabFilters(
|
||||
MetadataHelper.getEntity(mainid.getEntityCode()).getName(), user);
|
||||
|
||||
Map<String, Integer> countMap = new HashMap<>();
|
||||
for (String related : relateds) {
|
||||
String sql = buildMainSql(mainid, related, null, true, user);
|
||||
String sql = buildBaseSql(mainid, related, null, true, user, vtabFilters);
|
||||
if (sql != null) {
|
||||
// 任务是获取了全部的相关记录,因此总数可能与实际显示的条目数量不一致
|
||||
|
||||
|
@ -108,8 +119,9 @@ public class RelatedListController extends BaseController {
|
|||
return countMap;
|
||||
}
|
||||
|
||||
private String buildMainSql(ID recordOfMain, String relatedExpr, String q, boolean count, ID user) {
|
||||
// Entity.Field
|
||||
private String buildBaseSql(ID mainid, String relatedExpr, String q, boolean count, ID user,
|
||||
Map<String, JSONObject> vtabFilters) {
|
||||
// formatted: Entity.Field
|
||||
String[] ef = relatedExpr.split("\\.");
|
||||
Entity relatedEntity = MetadataHelper.getEntity(ef[0]);
|
||||
|
||||
|
@ -119,7 +131,7 @@ public class RelatedListController extends BaseController {
|
|||
relatedFields.add(ef[1]);
|
||||
} else {
|
||||
// v1.9 之前会把所有相关的查出来
|
||||
Entity mainEntity = MetadataHelper.getEntity(recordOfMain.getEntityCode());
|
||||
Entity mainEntity = MetadataHelper.getEntity(mainid.getEntityCode());
|
||||
for (Field field : relatedEntity.getFields()) {
|
||||
if ((field.getType() == FieldType.REFERENCE || field.getType() == FieldType.ANY_REFERENCE)
|
||||
&& ArrayUtils.contains(field.getReferenceEntities(), mainEntity)) {
|
||||
|
@ -130,12 +142,26 @@ public class RelatedListController extends BaseController {
|
|||
|
||||
if (relatedFields.isEmpty()) return null;
|
||||
|
||||
String mainWhere = "(" + StringUtils.join(relatedFields, " = ''{0}'' or ") + " = ''{0}'')";
|
||||
mainWhere = MessageFormat.format(mainWhere, recordOfMain);
|
||||
String where = MessageFormat.format(
|
||||
"(" + StringUtils.join(relatedFields, " = ''{0}'' or ") + " = ''{0}'')", mainid);
|
||||
|
||||
if (vtabFilters == null) {
|
||||
vtabFilters = ViewAddonsManager.instance.getViewTabFilters(
|
||||
MetadataHelper.getEntity(mainid.getEntityCode()).getName(), user);
|
||||
}
|
||||
|
||||
// 附件过滤条件
|
||||
JSONObject hasFilter = vtabFilters.get(relatedExpr);
|
||||
if (ParseHelper.validAdvFilter(hasFilter)) {
|
||||
String filterSql = new AdvFilterParser(hasFilter).toSqlWhere();
|
||||
if (filterSql != null) {
|
||||
where += " and " + filterSql;
|
||||
}
|
||||
}
|
||||
|
||||
// @see FeedsListController#fetchFeeds
|
||||
if (relatedEntity.getEntityCode() == EntityHelper.Feeds) {
|
||||
mainWhere += String.format(" and (type = %d or type = %d)",
|
||||
where += String.format(" and (type = %d or type = %d)",
|
||||
FeedsType.FOLLOWUP.getMask(),
|
||||
FeedsType.SCHEDULE.getMask());
|
||||
|
||||
|
@ -144,7 +170,7 @@ public class RelatedListController extends BaseController {
|
|||
for (Team t : Application.getUserStore().getUser(user).getOwningTeams()) {
|
||||
in.add(String.format("scope = '%s'", t.getIdentity()));
|
||||
}
|
||||
mainWhere += " and ( " + StringUtils.join(in, " or ") + " )";
|
||||
where += " and ( " + StringUtils.join(in, " or ") + " )";
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(q)) {
|
||||
|
@ -153,7 +179,7 @@ public class RelatedListController extends BaseController {
|
|||
if (!searchFields.isEmpty()) {
|
||||
String like = " like '%" + StringEscapeUtils.escapeSql(q) + "%'";
|
||||
String searchWhere = " and ( " + StringUtils.join(searchFields.iterator(), like + " or ") + like + " )";
|
||||
mainWhere += searchWhere;
|
||||
where += searchWhere;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -173,7 +199,7 @@ public class RelatedListController extends BaseController {
|
|||
}
|
||||
}
|
||||
|
||||
sql.append(" from ").append(relatedEntity.getName()).append(" where ").append(mainWhere);
|
||||
sql.append(" from ").append(relatedEntity.getName()).append(" where ").append(where);
|
||||
return sql.toString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
<option value="SERIES">[[${bundle.L('自动编号')}]]</option>
|
||||
<option value="DATE">[[${bundle.L('日期')}]]</option>
|
||||
<option value="DATETIME">[[${bundle.L('日期时间')}]]</option>
|
||||
<option value="TIME">[[${bundle.L('时间')}]]</option>
|
||||
<option value="PICKLIST">[[${bundle.L('下拉列表')}]]</option>
|
||||
<option value="CLASSIFICATION">[[${bundle.L('分类')}]]</option>
|
||||
<option value="MULTISELECT">[[${bundle.L('多选')}]]</option>
|
||||
|
@ -40,7 +41,6 @@
|
|||
<option value="SIGN">[[${bundle.L('签名')}]]</option>
|
||||
<option value="BOOL">[[${bundle.L('布尔')}]]</option>
|
||||
<optgroup th:label="${bundle.L('保留类型')}" class="bosskey-show">
|
||||
<option value="TIME">[[${bundle.L('时间')}]]</option>
|
||||
<option value="STATE">[[${bundle.L('状态')}]]</option>
|
||||
</optgroup>
|
||||
</select>
|
||||
|
|
|
@ -25,6 +25,11 @@
|
|||
.set-items .item > span {
|
||||
margin: 0 4px;
|
||||
}
|
||||
.set-items .item.star > span::after {
|
||||
content: '*';
|
||||
margin-left: 4px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.axis-target .ui-sortable-placeholder.ui-state-highlight {
|
||||
width: 7px;
|
||||
height: 0;
|
||||
|
|
|
@ -3,6 +3,13 @@
|
|||
<head>
|
||||
<th:block th:replace="~{/_include/header}" />
|
||||
<title>[[${bundle.L('视图配置')}]]</title>
|
||||
<style>
|
||||
.dd-item.star .dd3-content::after {
|
||||
content: '*';
|
||||
margin-left: 4px;
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="dialog">
|
||||
<div class="main-content">
|
||||
|
@ -10,7 +17,7 @@
|
|||
<div class="col-6 sortable-swap">
|
||||
<h5 class="sortable-box-title">[[${bundle.L('已显示')}]]</h5>
|
||||
<div class="sortable-box rb-scroller">
|
||||
<ol class="dd-list J_config"></ol>
|
||||
<ol class="dd-list J_config" th:_title="${bundle.L('无')}"></ol>
|
||||
</div>
|
||||
<i class="zmdi zmdi-swap"></i>
|
||||
</div>
|
||||
|
|
|
@ -1794,6 +1794,14 @@ th.column-fixed {
|
|||
height: 300px;
|
||||
}
|
||||
|
||||
.sortable-box .dd-list:empty::before {
|
||||
content: attr(_title);
|
||||
color: #777;
|
||||
font-style: italic;
|
||||
padding: 7px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.sortable-box.h380 {
|
||||
height: 388px;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ See LICENSE and COMMERCIAL in the project root for license information.
|
|||
$(document).ready(function () {
|
||||
const entity = $urlp('entity')
|
||||
|
||||
const $btn = $('.btn-primary').click(function () {
|
||||
const $btn = $('.btn-primary').on('click', function () {
|
||||
const fieldLabel = $val('#fieldLabel'),
|
||||
type = $val('#type'),
|
||||
comments = $val('#comments'),
|
||||
|
@ -62,7 +62,7 @@ $(document).ready(function () {
|
|||
|
||||
let referenceLoaded = false
|
||||
let classificationLoaded = false
|
||||
$('#type').change(function () {
|
||||
$('#type').on('change', function () {
|
||||
parent.RbModal.resize()
|
||||
|
||||
$('.J_dt-REFERENCE, .J_dt-N2NREFERENCE, .J_dt-CLASSIFICATION, .J_dt-STATE').addClass('hide')
|
||||
|
|
|
@ -83,7 +83,7 @@ $(document).ready(function () {
|
|||
'SERIES': $L('自动编号'),
|
||||
'DATE': $L('日期'),
|
||||
'DATETIME': $L('日期时间'),
|
||||
// 'TIME': $L('时间'),
|
||||
'TIME': $L('时间'),
|
||||
'PICKLIST': $L('下拉列表'),
|
||||
'CLASSIFICATION': $L('分类'),
|
||||
'MULTISELECT': $L('多选'),
|
||||
|
|
|
@ -28,6 +28,8 @@ $(document).ready(function () {
|
|||
const field = fields.find((x) => x.name === item.field)
|
||||
render_set({ ...item, name: item.field, specLabel: item.label, label: field ? field.label : `[${item.field.toUpperCase()}]` })
|
||||
})
|
||||
|
||||
refreshConfigStar()
|
||||
}
|
||||
|
||||
parent.RbModal.resize()
|
||||
|
@ -66,6 +68,8 @@ $(document).ready(function () {
|
|||
else RbHighbar.error(res.error_msg)
|
||||
})
|
||||
})
|
||||
|
||||
$('.J_tips').on('closed.bs.alert', () => parent.RbModal.resize())
|
||||
})
|
||||
|
||||
// 支持的计算类型
|
||||
|
@ -121,6 +125,7 @@ const render_set = function (item) {
|
|||
$item.attr({
|
||||
'data-label': s.label || '',
|
||||
})
|
||||
refreshConfigStar()
|
||||
}}
|
||||
/>,
|
||||
null,
|
||||
|
@ -134,3 +139,11 @@ const render_set = function (item) {
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
const refreshConfigStar = function () {
|
||||
$('.set-items > span').each(function () {
|
||||
const $this = $(this)
|
||||
if ($this.attr('data-label')) $this.find('.item').addClass('star')
|
||||
else $this.find('.item').removeClass('star')
|
||||
})
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ See LICENSE and COMMERCIAL in the project root for license information.
|
|||
*/
|
||||
|
||||
const _configLabels = {}
|
||||
const _configFilters = {}
|
||||
|
||||
$(document).ready(function () {
|
||||
const entity = $urlp('entity'),
|
||||
|
@ -24,10 +25,14 @@ $(document).ready(function () {
|
|||
// compatible: v2.8
|
||||
if (typeof this !== 'string') {
|
||||
key = this[0]
|
||||
_configLabels[key] = this[1]
|
||||
_configLabels[key] = this[1] // label
|
||||
_configFilters[key] = this[2] // filter
|
||||
}
|
||||
$(`.unset-list li[data-key="${key}"]`).trigger('click')
|
||||
})
|
||||
|
||||
refreshConfigStar()
|
||||
|
||||
$('#relatedAutoExpand').attr('checked', res.data.config.autoExpand === true)
|
||||
$('#relatedAutoHide').attr('checked', res.data.config.autoHide === true)
|
||||
}
|
||||
|
@ -37,12 +42,13 @@ $(document).ready(function () {
|
|||
}
|
||||
})
|
||||
|
||||
const $btn = $('.J_save').click(function () {
|
||||
const $btn = $('.J_save').on('click', () => {
|
||||
let config = []
|
||||
$('.J_config>li').each(function () {
|
||||
const $this = $(this)
|
||||
config.push([$this.data('key'), $this.attr('data-label') || ''])
|
||||
const key = $(this).data('key')
|
||||
config.push([key, _configLabels[key] || null, _configFilters[key] || null])
|
||||
})
|
||||
|
||||
config = {
|
||||
items: config,
|
||||
autoExpand: $val('#relatedAutoExpand'),
|
||||
|
@ -50,7 +56,7 @@ $(document).ready(function () {
|
|||
}
|
||||
|
||||
$btn.button('loading')
|
||||
$.post(url, JSON.stringify(config), function (res) {
|
||||
$.post(url, JSON.stringify(config), (res) => {
|
||||
$btn.button('reset')
|
||||
if (res.error_code === 0) parent.location.reload()
|
||||
else RbHighbar.error(res.error_msg)
|
||||
|
@ -58,26 +64,47 @@ $(document).ready(function () {
|
|||
})
|
||||
})
|
||||
|
||||
const refreshConfigStar = function () {
|
||||
$('.dd-list.J_config .dd-item').each(function () {
|
||||
const key = $(this).data('key')
|
||||
if (_configLabels[key] || _configFilters[key]) {
|
||||
$(this).addClass('star')
|
||||
} else {
|
||||
$(this).removeClass('star')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const ShowStyles_Comps = {}
|
||||
|
||||
// 不支持条件
|
||||
const _NO_FILTERS = ['ProjectTask', '', 'Feeds', 'Attachment']
|
||||
|
||||
// eslint-disable-next-line no-undef
|
||||
render_item_after = function ($item) {
|
||||
const key = $item.data('key')
|
||||
const $a = $(`<a class="mr-1" title="${$L('显示样式')}"><i class="zmdi zmdi-edit"></i></a>`)
|
||||
$item.find('.dd3-action>a').before($a)
|
||||
|
||||
$a.on('click', function () {
|
||||
$a.on('click', () => {
|
||||
if (ShowStyles_Comps[key]) {
|
||||
ShowStyles_Comps[key].show()
|
||||
} else {
|
||||
const entity = key.split('.')[0]
|
||||
|
||||
renderRbcomp(
|
||||
// eslint-disable-next-line react/jsx-no-undef
|
||||
<ShowStyles
|
||||
<ShowStyles2
|
||||
label={_configLabels[key]}
|
||||
onConfirm={(s) => {
|
||||
$item.attr({
|
||||
'data-label': s.label || '',
|
||||
})
|
||||
_configLabels[key] = s.label
|
||||
refreshConfigStar()
|
||||
}}
|
||||
filter={_configFilters[key]}
|
||||
filterShow={$urlp('type') === 'TAB' && !_NO_FILTERS.includes(entity)}
|
||||
filterEntity={entity}
|
||||
filterConfirm={(s) => {
|
||||
_configFilters[key] = s
|
||||
refreshConfigStar()
|
||||
}}
|
||||
/>,
|
||||
null,
|
||||
|
@ -88,3 +115,41 @@ render_item_after = function ($item) {
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-undef
|
||||
class ShowStyles2 extends ShowStyles {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = { filter: props.filter }
|
||||
}
|
||||
|
||||
renderExtras() {
|
||||
const fsl = this.state.filter && this.state.filter.items ? this.state.filter.items.length : 0
|
||||
return (
|
||||
this.props.filterShow && (
|
||||
<div className="form-group row">
|
||||
<label className="col-sm-3 col-form-label text-sm-right">{$L('附加过滤条件')}</label>
|
||||
<div className="col-sm-7">
|
||||
<a className="btn btn-sm btn-link pl-0 text-left down-2" onClick={() => this.showFilter()}>
|
||||
{fsl > 0 ? `${$L('已设置条件')} (${fsl})` : $L('点击设置')}
|
||||
</a>
|
||||
<p className="form-text mb-0 mt-0">{$L('符合过滤条件的数据才会在相关项列表中显示')}</p>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
showFilter() {
|
||||
parent._showFilterForAddons &&
|
||||
parent._showFilterForAddons({
|
||||
entity: this.props.filterEntity,
|
||||
filter: this.state.filter,
|
||||
onConfirm: (s) => {
|
||||
if (s.items.length === 0) s = null // No items
|
||||
this.props.filterConfirm(s)
|
||||
this.setState({ filter: s })
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -431,3 +431,9 @@ class LightAttachmentList extends RelatedList {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
// for view-addons.js
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
var _showFilterForAddons = function (opt) {
|
||||
renderRbcomp(<AdvFilter entity={opt.entity} filter={opt.filter} confirm={opt.onConfirm} title={$L('附加过滤条件')} inModal canNoFilters />)
|
||||
}
|
||||
|
|
|
@ -26,6 +26,8 @@ class ShowStyles extends React.Component {
|
|||
<input className="form-control form-control-sm" placeholder={$L('默认')} defaultValue={this.props.label || ''} maxLength="50" ref={(c) => (this._$label = c)} />
|
||||
</div>
|
||||
</div>
|
||||
{this.renderExtras()}
|
||||
|
||||
<div className="form-group row footer">
|
||||
<div className="col-sm-7 offset-sm-3">
|
||||
<button className="btn btn-primary btn-space" type="button" onClick={() => this.saveProps()}>
|
||||
|
@ -44,6 +46,10 @@ class ShowStyles extends React.Component {
|
|||
)
|
||||
}
|
||||
|
||||
renderExtras() {
|
||||
return null
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
$(this._$dlg).modal({ show: true, keyboard: true })
|
||||
}
|
||||
|
|
|
@ -129,5 +129,6 @@
|
|||
<script th:src="@{/assets/js/rb-view.append.js}" type="text/babel"></script>
|
||||
<script th:src="@{/assets/js/rb-assignshare.js}" type="text/babel"></script>
|
||||
<script th:src="@{/assets/js/rb-approval.js}" type="text/babel"></script>
|
||||
<script th:src="@{/assets/js/rb-advfilter.js}" type="text/babel"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<head>
|
||||
<th:block th:replace="~{/_include/header}" />
|
||||
<title>[[${bundle.L('导航菜单')}]]</title>
|
||||
<style type="text/css">
|
||||
<style>
|
||||
.dd3-content > .zmdi {
|
||||
position: absolute;
|
||||
width: 28px;
|
||||
|
@ -43,7 +43,7 @@
|
|||
<div class="row m-0">
|
||||
<div class="col-5 mt-2 pr-0">
|
||||
<div class="sortable-box h380 rb-scroller">
|
||||
<ol class="dd-list J_config"></ol>
|
||||
<ol class="dd-list J_config" th:_title="${bundle.L('无')}"></ol>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<button type="button" class="btn btn-secondary btn-sm J_add-menu">+ [[${bundle.L('添加菜单项')}]]</button>
|
||||
|
|
Loading…
Reference in a new issue