Compare commits

...

5 commits

Author SHA1 Message Date
RB
68ef1f42f8 style 2025-09-02 00:45:37 +08:00
RB
18e347f2bd Update charts.js 2025-09-01 23:58:52 +08:00
RB
7ec48fc54f Improve file management and code formatting features 2025-09-01 23:50:39 +08:00
RB
41dbda6cb4 Update rb-page.js 2025-09-01 21:19:37 +08:00
RB
ea320ccb01 Update rb-advfilter.js 2025-09-01 21:19:00 +08:00
24 changed files with 103 additions and 61 deletions

2
@rbv

@ -1 +1 @@
Subproject commit 3c40f82ef6eac7641a651907fefe6a51a14a9c52
Subproject commit 64bee3bc986073e62a4d3ee6c94bd3d3d4231e1c

View file

@ -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);
}
/**

View file

@ -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);

View file

@ -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">

View file

@ -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>

View file

@ -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">

View file

@ -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">

View file

@ -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">

View file

@ -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">

View file

@ -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>

View file

@ -461,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;
}

View file

@ -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>
) : (

View file

@ -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() {

View file

@ -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>}

View file

@ -528,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

View file

@ -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" />
&nbsp;
{$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" />

View file

@ -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>

View file

@ -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={item.name} title={item.label} data-pinyin={item.quickCode || null}>
<option value={item.name + NT_SPLIT + item.type} key={item.name} title={item.label} data-pinyin={item.quickCode}>
{item.label}
</option>
)

View file

@ -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)
}
}
}

View file

@ -1241,7 +1241,6 @@ var $select2MatcherAll = function (params, data) {
// 匹配
function _FN(item, s) {
console.log('_FN', item, s)
s = s.toLowerCase()
if ((item.text || '').toLowerCase().indexOf(s) > -1 || (item.id || '').toLowerCase().indexOf(s) > -1) return true
// v4.2
@ -1312,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
}
// 复制

View file

@ -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>

View file

@ -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);
}

View file

@ -8,7 +8,6 @@
.iframe-wrap {
margin-top: 44px;
overflow: hidden;
border-radius: 4px;
}
.iframe-wrap iframe {
position: relative;

View file

@ -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>