rebuild/src/main/resources/web/assets/js/admin/system-cfg.js
REBUILD 企业管理系统 0a9fbcdde1
Fix 3.9.1 (#855)
* fix: 表单回填ID无效

* feat: check-state st

* fix: tel/mailto pdf for dd/wx

* fix: 刷新导致标题变化

* 3.9.1

* be:变量匹配 {}

* fix: AnyRecordSelector

* style:_backup

* enh: filter date EQ

* OSC

* Update rb-forms.js
2025-01-09 13:22:12 +08:00

401 lines
14 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*!
Copyright (c) REBUILD <https://getrebuild.com/> and/or its owners. All rights reserved.
rebuild is dual-licensed under commercial and open source licenses (GPLv3).
See LICENSE and COMMERCIAL in the project root for license information.
*/
/* eslint-disable no-undef, react/display-name */
const wpc = window.__PageConfig
$(document).ready(() => {
const $dl = $('#_DefaultLanguage')
$dl.text(wpc._LANGS[$dl.text()] || '中文')
const $ns = $('#_MobileNavStyle')
// eslint-disable-next-line eqeqeq
$ns.text($ns.text() == '35' ? $L('卡片式') : $L('默认'))
// 禁用
;['PasswordExpiredDays', 'DBBackupsKeepingDays', 'RevisionHistoryKeepingDays', 'RecycleBinKeepingDays'].forEach((item) => {
const $d = $(`td[data-id=${item}]`)
if (~~$d.attr('data-value') <= 0) $d.text($L('不启用'))
})
// UC
UCenter.query((res) => {
const bindAccount = res.bindAccount
if (bindAccount) {
$('.J_cloudAccount').removeClass('hide')
$('.J_has-bind').removeClass('hide')
$('.J_has-bind a').text(bindAccount)
} else if (rb.commercial === 10 || rb.commercial === 20) {
$('.J_cloudAccount').removeClass('hide')
$('.J_not-bind').removeClass('hide')
$('.J_not-bind .btn').on('click', () => {
if (res.canBind) UCenter.bind()
else RbHighbar.create($L('仅超级管理员可操作'))
})
}
})
// v34
const $mm = $('.J_maintenanceMode')
$.get('/admin/systems/maintenance-mode', (res) => {
const _data = res.data
if (_data) {
$mm
.find('.btn')
.text($L('取消维护计划'))
.on('click', () => {
RbAlert.create($L('确认取消维护计划'), {
onConfirm: function () {
const that = this
$.post('/admin/systems/maintenance-mode?cancel=yes', () => {
that.hide()
setTimeout(() => location.reload(), 200)
})
},
})
})
$mm.find('.note dd:eq(0)').text(_data.startTime.substr(0, 16) + ` ${$L('至')} ` + _data.endTime.substr(0, 16))
$mm.find('.note dd:eq(1)').text(_data.note || $L('无'))
$mm.find('.note').show()
} else {
$mm.find('.btn').on('click', () => {
if (rb.commercial < 1) return RbHighbar.error(WrapHtml($L('免费版不支持开启维护计划功能 [(查看详情)](https://getrebuild.com/docs/rbv-features)')))
renderRbcomp(<DlgMM />)
})
}
})
$('.J_backDb').on('click', () => renderRbcomp(<DlgBackup />))
})
useEditComp = function (name) {
if (['OpenSignUp', 'LiveWallpaper', 'FileSharable', 'MarkWatermark', 'DBBackupsEnable', 'MultipleSessions', 'ShowViewHistory', 'PageMourningMode'].includes(name)) {
return (
<select className="form-control form-control-sm">
<option value="true">{$L('是')}</option>
<option value="false">{$L('否')}</option>
</select>
)
} else if ('PasswordPolicy' === name) {
// 借用贵宝地
_toggleImage('.applogo', true)
_toggleImage('.bgimg')
return (
<select className="form-control form-control-sm">
<option value="1">{$L(' (最低6位无字符类型限制)')}</option>
<option value="2">{$L(' (最低6位必须同时包含数字字母)')}</option>
<option value="3">{$L(' (最低10位必须同时包含数字字母特殊字符)')}</option>
</select>
)
} else if ('DefaultLanguage' === name) {
const options = []
for (let k in wpc._LANGS) {
options.push(
<option value={k} key={k}>
{wpc._LANGS[k]}
</option>
)
}
return <select className="form-control form-control-sm">{options}</select>
} else if ('LoginCaptchaPolicy' === name) {
return (
<select className="form-control form-control-sm">
<option value="1">{$L('自动')}</option>
<option value="2">{$L('总是显示')}</option>
</select>
)
} else if ('PageFooter' === name || 'AllowUsesTime' === name || 'AllowUsesIp' === name) {
return <textarea name={name} className="form-control form-control-sm row3x" maxLength="600" />
} else if ('Login2FAMode' === name) {
return (
<select className="form-control form-control-sm">
<option value="0">{$L('不启用')}</option>
<option value="1">{$L('手机或邮箱')}</option>
<option value="2">{$L('仅手机')}</option>
<option value="3">{$L('仅邮箱')}</option>
</select>
)
} else if ('MobileNavStyle' === name) {
return (
<select className="form-control form-control-sm">
<option value="34">{$L('默认')}</option>
<option value="35">{$L('卡片式')}</option>
</select>
)
}
}
let _$imgCurrent
const _toggleImage = function (el, init) {
const $file = $('.file_4image')
if (init) {
$initUploader($file, null, (res) => {
_$imgCurrent.find('>i').css('background-image', `url(${rb.baseUrl}/filex/img/${res.key}?local=true)`)
changeValue({ target: { name: _$imgCurrent.data('id'), value: res.key } })
})
}
const $img = $(el).addClass('edit')
$img.find('p').removeClass('hide')
$img
.find('a')
.attr('title', $L('点击上传'))
.on('click', function () {
_$imgCurrent = $(this)
$file[0].click()
})
$img.find('a>b').on('click', function (e) {
$stopEvent(e, true)
_$imgCurrent = $(this).parent()
_$imgCurrent.find('>i').css('background-image', `url(${rb.baseUrl}/assets/img/s.gif)`)
changeValue({ target: { name: _$imgCurrent.data('id'), value: '' } })
})
$img
.find('.J_logo-gen')
.removeAttr('title')
.off('click')
.on('click', () => {})
}
class DlgMM extends RbAlert {
renderContent() {
return (
<form className="rbalert-form-sm">
<div className="form-group">
<label>{$L('计划维护时间')}</label>
<div className="input-group">
<input type="text" className="form-control form-control-sm bg-white J_start" ref={(c) => (this._$startTime = c)} placeholder={$L('开始时间')} readOnly />
<div className="input-group-prepend input-group-append">
<span className="input-group-text pt-0 pb-0">{$L('至')}</span>
</div>
<input type="text" className="form-control form-control-sm bg-white" ref={(c) => (this._$endTime = c)} placeholder={$L('结束时间')} readOnly />
</div>
{this.state.takeTime1 ? <div className="form-text text-warning">{$L('将在 %s 分钟后开始维护时间 %s 分钟', this.state.takeTime1, this.state.takeTime2)}</div> : null}
</div>
<div className="form-group">
<label>{$L('弹窗附加内容')}</label>
<textarea className="form-control form-control-sm row2x" ref={(c) => (this._$note = c)} placeholder={$L('维护期间系统将无法使用请及时保存数据')} />
</div>
<div className="form-group mb-2">
<button type="button" className="btn btn-danger" onClick={this._onConfirm}>
{$L('开启')}
</button>
<div className="mt-3">
<RbAlertBox message={$L('开启后系统将以弹窗形式通知所有登录用户')} />
</div>
</div>
</form>
)
}
componentDidMount() {
super.componentDidMount()
const that = this
function calcTakeTime() {
const post = that._buildPost()
if (post.startTime && post.endTime) {
that.setState({
takeTime1: moment(post.startTime).diff(moment(), 'minutes'),
takeTime2: Math.max(moment(post.endTime).diff(moment(post.startTime), 'minutes'), 0),
})
} else {
that.setState({ takeTime: null })
}
}
// $([this._$startTime, this._$endTime])
// .datetimepicker({
// startDate: new Date(),
// })
// .on('changeDate', (e) => {
// if ($(e.target).hasClass('J_start')) {
// if ($val(this._$startTime) && !$val(this._$endTime)) {
// const autoEnd = moment($val(this._$startTime)).add('minute', 10).format('YYYY-MM-DD HH:mm')
// $(this._$endTime).val(autoEnd)
// }
// }
// calcTakeTime()
// })
// https://flatpickr.js.org/options/
$([this._$startTime, this._$endTime]).flatpickr({
enableTime: true,
enableSeconds: false,
time_24hr: true,
minuteIncrement: 1,
// defaultDate: new Date(),
minDate: new Date(),
dateFormat: 'Y-m-d H:i', // :S
prevArrow: '<i class="mdi mdi-chevron-left"></i>',
nextArrow: '<i class="mdi mdi-chevron-right"></i>',
locale: rb.locale.split('_')[0], // zh, en
onClose: function (s, d, inst) {
const st = $val(that._$startTime)
if ($(inst.element).hasClass('J_start') && st && !$val(that._$endTime)) {
const endd = moment(st).add('minute', 10).format('YYYY-MM-DD HH:mm')
$(that._$endTime).val(endd)
}
calcTakeTime()
},
plugins: [
new ShortcutButtonsPlugin({
button: [{ label: $L('今天') }],
onClick(index, fp) {
fp.setDate(new Date())
fp.close()
},
}),
],
})
}
_buildPost() {
return {
startTime: $val(this._$startTime),
endTime: $val(this._$endTime),
note: $val(this._$note),
}
}
_onConfirm = () => {
const post = this._buildPost()
if (!post.startTime || !post.endTime) return RbHighbar.create($L('请选择计划维护时间'))
post.startTime += ':00'
post.endTime += ':00'
$.post('/admin/systems/maintenance-mode', JSON.stringify(post), (res) => {
if (res.error_code === 0) {
this.hide()
setTimeout(() => location.reload(), 200)
} else {
RbHighbar.error(res.error_msg)
}
})
}
}
// ~~ App
$(document).ready(() => {
if (rb.commercial < 1) {
$('.td-MobileAppPath button').remove()
return
}
const renderMobileAppPath = function (key) {
$('.td-MobileAppPath>a').text($fileCutName(key)).attr({
href: '../h5app-download',
target: '_blank',
})
$('button.J_MobileAppPath-del').removeClass('hide')
}
const $input = $('input.J_MobileAppPath')
$initUploader(
$input,
(res) => {
$('button.J_MobileAppPath span').text(` (${res.percent.toFixed(1)}%)`)
},
(res) => {
const fileKey = res.key
$.post(location.href, JSON.stringify({ MobileAppPath: fileKey }), (res) => {
if (res.error_code === 0) {
renderMobileAppPath(fileKey)
RbHighbar.success($L('上传成功'))
} else {
RbHighbar.error(res.error_msg)
}
$('button.J_MobileAppPath span').text('')
})
}
)
$('button.J_MobileAppPath').on('click', () => $input[0].click())
$('button.J_MobileAppPath-del').on('click', () => {
RbAlert.create($L('确认删除 APP 安装包?'), {
onConfirm: function () {
this.hide()
$.post(location.href, JSON.stringify({ MobileAppPath: '' }), () => {
location.reload()
})
},
})
})
const apk = $('.td-MobileAppPath>a').text()
if (apk && apk.length > 20) renderMobileAppPath(apk)
})
class DlgBackup extends RbAlert {
state = { ...this.props }
renderContent() {
const _backup = this.state.db || this.state.file
return (
<form className="rbalert-form-sm">
<div className="form-group mb-0">
<label className="text-bold">{$L('选择要备份哪些数据')}</label>
<div ref={(c) => (this._$bkType = c)}>
<label className="custom-control custom-control-sm custom-checkbox custom-control-inline">
<input className="custom-control-input" type="checkbox" defaultChecked />
<span className="custom-control-label">{$L('数据库')}</span>
</label>
<label className="custom-control custom-control-sm custom-checkbox custom-control-inline">
<input className="custom-control-input" type="checkbox" defaultChecked />
<span className="custom-control-label">{$L('数据目录文件')}</span>
</label>
</div>
</div>
<div className="form-group mb-1">
{_backup ? (
<div className="backup-box">
<table>
<tbody>
<tr>
<td className="text-ellipsis pr-1">{$L('数据库')}</td>
<td>{this.state.db ? <code>{this.state.db}</code> : <span className="text-muted">{$L('未备份')}</span>}</td>
</tr>
<tr>
<td className="text-ellipsis pr-1">{$L('数据目录文件')}</td>
<td>{this.state.file ? <code>{this.state.file}</code> : <span className="text-muted">{$L('未备份')}</span>}</td>
</tr>
</tbody>
</table>
</div>
) : (
<div className="text-warning mb-1" ref={(c) => (this._$tips = c)}>
<i className="mdi-alert-outline mdi" /> {$L('请勿在业务高峰时段执行备份')}
</div>
)}
<button type="button" className="btn btn-space btn-primary" onClick={this.confirm} ref={(c) => (this._$btn = c)} data-spinner>
{$L('开始备份')}
</button>
</div>
</form>
)
}
confirm = () => {
const type = ($(this._$bkType).find('input:eq(0)').prop('checked') ? 1 : 0) + ($(this._$bkType).find('input:eq(1)').prop('checked') ? 2 : 0)
if (type === 0) return
this.disabled(true, true)
const $btn = $(this._$btn).button('loading')
$.post(`systems/backup?type=${type}`, (res) => {
if (res.error_code === 0) this.setState({ ...res.data })
else RbHighbar.error(res.error_msg)
this.disabled(false, false)
$btn.button('reset')
})
}
}