mirror of
https://github.com/getrebuild/rebuild.git
synced 2024-09-20 07:25:54 +08:00
Fix v3.5 beta4 (#691)
* bumplib * be: styles * be: op after reload * Batch updates countdown * delete item.referenceQuickNew // v35 * 1.取消禁用设置; 2.已禁用显示; 3.be:TextFunction * be: user's dept * be: qr width * fix: bizz delete check * lang --------- Co-authored-by: devezhao <zhaofang123@gmail.com>
This commit is contained in:
parent
f94926ae24
commit
9e9ceb063d
10
.vscode/settings.json
vendored
10
.vscode/settings.json
vendored
|
@ -2,7 +2,7 @@
|
|||
"editor.fontSize": 12,
|
||||
"editor.tabSize": 2,
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": true
|
||||
"source.fixAll.eslint": "explicit"
|
||||
},
|
||||
"eslint.codeAction.showDocumentation": {
|
||||
"enable": true
|
||||
|
@ -15,12 +15,6 @@
|
|||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
|
||||
"LineCount.excludes": [
|
||||
"**/.vscode/**",
|
||||
"**/.idea/**",
|
||||
"**/node_modules/**",
|
||||
"**/target/**",
|
||||
"**/assets/lib/**"
|
||||
],
|
||||
"LineCount.excludes": ["**/.vscode/**", "**/.idea/**", "**/node_modules/**", "**/target/**", "**/assets/lib/**"],
|
||||
"editor.formatOnSave": true
|
||||
}
|
||||
|
|
2
@rbv
2
@rbv
|
@ -1 +1 @@
|
|||
Subproject commit 2ab2c88a6c5750feb36c13d3d35358a85fc78501
|
||||
Subproject commit a4de177b845e1ae7d47881be646aff468d9e09fc
|
5
pom.xml
5
pom.xml
|
@ -10,9 +10,10 @@
|
|||
</parent>
|
||||
<groupId>com.rebuild</groupId>
|
||||
<artifactId>rebuild</artifactId>
|
||||
<version>3.5.0-beta3</version>
|
||||
<version>3.5.0-beta4</version>
|
||||
<name>rebuild</name>
|
||||
<description>Building your business-systems freely!</description>
|
||||
<url>https://getrebuild.com/</url>
|
||||
<!-- UNCOMMENT USE TOMCAT -->
|
||||
<!-- <packaging>war</packaging> -->
|
||||
|
||||
|
@ -290,7 +291,7 @@
|
|||
<dependency>
|
||||
<groupId>com.github.devezhao</groupId>
|
||||
<artifactId>persist4j</artifactId>
|
||||
<version>1.7.5</version>
|
||||
<version>1.7.6</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.alibaba</groupId>
|
||||
|
|
|
@ -74,11 +74,11 @@ public class Application implements ApplicationListener<ApplicationStartedEvent>
|
|||
/**
|
||||
* Rebuild Version
|
||||
*/
|
||||
public static final String VER = "3.5.0-beta3";
|
||||
public static final String VER = "3.5.0-beta4";
|
||||
/**
|
||||
* Rebuild Build [MAJOR]{1}[MINOR]{2}[PATCH]{2}[BUILD]{2}
|
||||
*/
|
||||
public static final int BUILD = 3050003;
|
||||
public static final int BUILD = 3050004;
|
||||
|
||||
static {
|
||||
// Driver for DB
|
||||
|
|
|
@ -7,6 +7,7 @@ See LICENSE and COMMERCIAL in the project root for license information.
|
|||
|
||||
package com.rebuild.core.metadata;
|
||||
|
||||
import cn.devezhao.bizz.privileges.PrivilegesException;
|
||||
import cn.devezhao.commons.CalendarUtils;
|
||||
import cn.devezhao.persist4j.Entity;
|
||||
import cn.devezhao.persist4j.Record;
|
||||
|
@ -219,7 +220,11 @@ public class EntityHelper {
|
|||
r.setID(EntityHelper.OwningUser, r.getEditor());
|
||||
}
|
||||
if (entity.containsField(EntityHelper.OwningDept)) {
|
||||
com.rebuild.core.privileges.bizz.User user = Application.getUserStore().getUser(r.getEditor());
|
||||
com.rebuild.core.privileges.bizz.User user = r.getEditor() == null
|
||||
? null : Application.getUserStore().getUser(r.getEditor());
|
||||
if (user == null || user.getOwningDept() == null) {
|
||||
throw new PrivilegesException("Bad member! No dept found in user : " + r.getEditor());
|
||||
}
|
||||
r.setID(EntityHelper.OwningDept, (ID) user.getOwningDept().getIdentity());
|
||||
}
|
||||
}
|
||||
|
@ -243,7 +248,9 @@ public class EntityHelper {
|
|||
* @see #newUnsavedId(int)
|
||||
*/
|
||||
public static boolean isUnsavedId(Object id) {
|
||||
return ID.isId(id) && (UNSAVED_ID.equals(id) || id.toString().endsWith(UNSAVED_ID_SUFFIX));
|
||||
boolean s = ID.isId(id) && (UNSAVED_ID.equals(id) || id.toString().endsWith(UNSAVED_ID_SUFFIX));
|
||||
if (!s) return false;
|
||||
return !UserService.SYSTEM_USER.equals(id);
|
||||
}
|
||||
|
||||
// 公共字段/保留字段
|
||||
|
|
|
@ -91,6 +91,10 @@ public class DepartmentService extends BaseService {
|
|||
* @param transferTo
|
||||
*/
|
||||
public void deleteAndTransfer(ID deptId, ID transferTo) {
|
||||
if (ROOT_DEPT.equals(deptId)) {
|
||||
throw new OperationDeniedException(Language.L("内置部门禁止删除"));
|
||||
}
|
||||
|
||||
checkAdminGuard(BizzPermission.DELETE, null);
|
||||
|
||||
Department dept = Application.getUserStore().getDepartment(deptId);
|
||||
|
|
|
@ -118,12 +118,12 @@ public class UserService extends BaseService {
|
|||
|
||||
@Override
|
||||
public int delete(ID recordId) {
|
||||
checkAdminGuard(BizzPermission.DELETE, null);
|
||||
|
||||
if (ADMIN_USER.equals(recordId) || SYSTEM_USER.equals(recordId)) {
|
||||
throw new OperationDeniedException(Language.L("内置用户禁止删除"));
|
||||
}
|
||||
|
||||
checkAdminGuard(BizzPermission.DELETE, null);
|
||||
|
||||
if (checkHasUsed(recordId)) {
|
||||
throw new OperationDeniedException(Language.L("已使用过的用户禁止删除"));
|
||||
}
|
||||
|
|
|
@ -18,8 +18,6 @@ import com.googlecode.aviator.runtime.type.AviatorString;
|
|||
import com.rebuild.core.Application;
|
||||
import com.rebuild.core.metadata.MetadataHelper;
|
||||
import com.rebuild.core.support.general.FieldValueHelper;
|
||||
import com.rebuild.utils.CommonsUtils;
|
||||
import com.rebuild.web.commons.MetadataGetting;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
@ -65,6 +63,9 @@ public class TextFunction extends AbstractFunction {
|
|||
final String sep = ObjectUtils.defaultIfNull(arg3.getValue(env), ", ").toString();
|
||||
final String fieldName = arg4.getValue(env) == null ? null : arg4.getValue(env).toString();
|
||||
|
||||
// No value
|
||||
if ($id == null) return arg2;
|
||||
|
||||
// 引用 ID
|
||||
if (ID.isId($id)) {
|
||||
ID anyid = $id instanceof ID ? (ID) $id : ID.valueOf($id.toString());
|
||||
|
|
|
@ -146,13 +146,13 @@ public class BarCodeSupport {
|
|||
protected static BitMatrix createBarCodeImage(String content, BarcodeFormat format, int width, int height) {
|
||||
Map<EncodeHintType, Object> hints = new HashMap<>();
|
||||
hints.put(EncodeHintType.CHARACTER_SET, AppUtils.UTF8);
|
||||
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L); // 高级别导致空白边框???
|
||||
hints.put(EncodeHintType.MARGIN, 0);
|
||||
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
|
||||
hints.put(EncodeHintType.MARGIN, 1);
|
||||
|
||||
try {
|
||||
if (format == BarcodeFormat.QR_CODE) {
|
||||
width = height = Math.max(width, height);
|
||||
if (width <= 0) width = height = 80;
|
||||
if (width <= 0) width = height = 120;
|
||||
|
||||
} else {
|
||||
final int base = 64;
|
||||
|
|
|
@ -62,16 +62,14 @@ public class UserController extends EntityController {
|
|||
}
|
||||
|
||||
@RequestMapping("check-user-status")
|
||||
public RespBody checkUserStatus(@IdParam ID userId) {
|
||||
if (!Application.getUserStore().existsUser(userId)) {
|
||||
return RespBody.error();
|
||||
}
|
||||
public RespBody checkUserStatus(@IdParam ID uid) {
|
||||
if (!Application.getUserStore().existsUser(uid)) return RespBody.error();
|
||||
|
||||
User checkedUser = Application.getUserStore().getUser(userId);
|
||||
final User checkedUser = Application.getUserStore().getUser(uid);
|
||||
|
||||
Map<String, Object> ret = new HashMap<>();
|
||||
ret.put("active", checkedUser.isActive());
|
||||
ret.put("system", "system".equals(checkedUser.getName()) || "admin".equals(checkedUser.getName()));
|
||||
ret.put("system", uid.equals(UserService.ADMIN_USER) || uid.equals(UserService.SYSTEM_USER));
|
||||
ret.put("disabled", checkedUser.isDisabled());
|
||||
|
||||
if (checkedUser.getOwningRole() != null) {
|
||||
|
@ -79,7 +77,7 @@ public class UserController extends EntityController {
|
|||
ret.put("roleDisabled", checkedUser.getOwningRole().isDisabled());
|
||||
|
||||
// 附加角色
|
||||
ret.put("roleAppends", UserHelper.getRoleAppends(userId));
|
||||
ret.put("roleAppends", UserHelper.getRoleAppends(uid));
|
||||
}
|
||||
|
||||
if (checkedUser.getOwningDept() != null) {
|
||||
|
@ -89,7 +87,7 @@ public class UserController extends EntityController {
|
|||
|
||||
Object[] lastLogin = Application.createQueryNoFilter(
|
||||
"select loginTime,ipAddr from LoginLog where user = ? order by loginTime desc")
|
||||
.setParameter(1, userId)
|
||||
.setParameter(1, uid)
|
||||
.unique();
|
||||
if (lastLogin != null) {
|
||||
ret.put("lastLogin",
|
||||
|
|
|
@ -56,7 +56,7 @@ public class ApprovalAdminController extends BaseController {
|
|||
public ModelAndView page(@PathVariable String id, HttpServletResponse response) throws IOException {
|
||||
ID configId = ID.valueOf(id);
|
||||
Object[] config = Application.createQuery(
|
||||
"select belongEntity,name,flowDefinition from RobotApprovalConfig where configId = ?")
|
||||
"select belongEntity,name,flowDefinition,isDisabled from RobotApprovalConfig where configId = ?")
|
||||
.setParameter(1, configId)
|
||||
.unique();
|
||||
if (config == null) {
|
||||
|
@ -71,6 +71,7 @@ public class ApprovalAdminController extends BaseController {
|
|||
mv.getModel().put("name", config[1]);
|
||||
mv.getModel().put("applyEntity", applyEntity.getName());
|
||||
mv.getModel().put("flowDefinition", config[2]);
|
||||
mv.getModel().put("isDisabled", config[3]);
|
||||
return mv;
|
||||
}
|
||||
|
||||
|
|
|
@ -92,6 +92,7 @@ public class TransformConfigController extends BaseController {
|
|||
}
|
||||
|
||||
mv.getModelMap().put("name", config.getString("name"));
|
||||
mv.getModelMap().put("isDisabled", config.getBoolean("disabled"));
|
||||
|
||||
// v3.1 明细导入
|
||||
if (targetEntity.getMainEntity() != null) {
|
||||
|
|
|
@ -2670,7 +2670,7 @@
|
|||
"复制分享链接":"复制分享链接",
|
||||
"下月":"下月",
|
||||
"明细所属主记录已经不存在,无法恢复":"明细所属主记录已经不存在,无法恢复",
|
||||
"已发送给":"已发送给",
|
||||
"已发送至":"已发送至",
|
||||
"请输入有效的群 Webhook 地址":"请输入有效的群 Webhook 地址",
|
||||
"请分别上传深色与白色 LOGO,透明背景,建议尺寸 300 × 60":"请分别上传深色与白色 LOGO,透明背景,建议尺寸 300 × 60",
|
||||
"群号":"群号",
|
||||
|
@ -2841,5 +2841,7 @@
|
|||
"无效模板文件 (无法读取文件内容)":"无效模板文件 (无法读取文件内容)",
|
||||
"请正确填写目标实体/记录匹配规则":"请正确填写目标实体/记录匹配规则",
|
||||
"上传 WORD 文件请选择 WORD 模板类型":"上传 WORD 文件请选择 WORD 模板类型",
|
||||
"APP 安装包":"APP 安装包"
|
||||
"APP 安装包":"APP 安装包",
|
||||
"内置部门禁止删除":"内置部门禁止删除",
|
||||
"系统内置超级管理员。此用户拥有最高级系统权限,请谨慎使用":"系统内置超级管理员。此用户拥有最高级系统权限,请谨慎使用"
|
||||
}
|
|
@ -4,6 +4,11 @@
|
|||
<th:block th:replace="~{/_include/header}" />
|
||||
<meta name="page-help" content="https://getrebuild.com/docs/admin/entity/field-classification#%E5%88%86%E7%B1%BB%E6%95%B0%E6%8D%AE" />
|
||||
<title>[[${bundle.L('分类数据')}]]</title>
|
||||
<style>
|
||||
.modal.rbmodal .modal-dialog .modal-body {
|
||||
min-height: auto;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="rb-wrapper rb-fixed-sidebar rb-collapsible-sidebar rb-collapsible-sidebar-hide-logo rb-color-header" th:classappend="${sideCollapsedClazz}">
|
||||
|
|
|
@ -149,10 +149,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-md-12 col-xl-3 col-lg-4 col-form-label text-lg-right pt-1">
|
||||
<i class="support-plat2 mdi mdi-monitor"></i>
|
||||
[[${bundle.L('启用快速新建')}]]
|
||||
</label>
|
||||
<label class="col-md-12 col-xl-3 col-lg-4 col-form-label text-lg-right pt-1">[[${bundle.L('启用快速新建')}]]</label>
|
||||
<div class="col-md-12 col-xl-6 col-lg-8">
|
||||
<label class="custom-control custom-control-sm custom-checkbox custom-control-inline mb-0">
|
||||
<input class="custom-control-input" type="checkbox" id="referenceQuickNew" />
|
||||
|
|
|
@ -18,7 +18,11 @@
|
|||
<div class="rb-content">
|
||||
<div class="page-head">
|
||||
<div class="float-left">
|
||||
<div class="page-head-title">[[${bundle.L('审批流程')}]]<span class="sub-title">[[${name}]]</span></div>
|
||||
<div class="page-head-title">
|
||||
[[${bundle.L('审批流程')}]]
|
||||
<span class="sub-title">[[${name}]]</span>
|
||||
<span th:if="${isDisabled}" class="badge badge-grey badge-pill up-1 ml-1">[[${bundle.L('未启用')}]]</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="float-right pt-1">
|
||||
<div class="btn-group">
|
||||
|
|
|
@ -84,7 +84,11 @@
|
|||
<th:block th:replace="~{/_include/nav-left-admin(active='robot-transforms')}" />
|
||||
<div class="rb-content">
|
||||
<div class="page-head">
|
||||
<div class="page-head-title">[[${bundle.L('记录转换')}]]<span class="sub-title">[[${name ?: bundle.L('未命名')}]]</span></div>
|
||||
<div class="page-head-title">
|
||||
[[${bundle.L('记录转换')}]]
|
||||
<span class="sub-title">[[${name ?: bundle.L('未命名')}]]</span>
|
||||
<span th:if="${isDisabled}" class="badge badge-grey badge-pill up-1 ml-1">[[${bundle.L('未启用')}]]</span>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div class="main-content container-fluid pt-0">
|
||||
|
|
|
@ -89,7 +89,7 @@ code {
|
|||
}
|
||||
|
||||
.dropdown-menu.auto-scroller {
|
||||
max-height: 487px;
|
||||
max-height: 488px;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
|
@ -181,7 +181,6 @@ code {
|
|||
|
||||
.text-disabled {
|
||||
color: #aaa !important;
|
||||
font-style: italic;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
|
@ -2266,11 +2265,6 @@ th.column-fixed {
|
|||
color: #444;
|
||||
}
|
||||
|
||||
.aside-tree li > a.text-disabled {
|
||||
color: #aaa;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.aside-tree > ul > li > a {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
@ -3342,6 +3336,21 @@ form {
|
|||
padding-bottom: 7px;
|
||||
}
|
||||
|
||||
@media (max-width: 575.98px) {
|
||||
.rb-icons-nav > li.dropdown.global-create2 .dropdown-menu {
|
||||
position: fixed;
|
||||
top: 60px;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
margin: 0;
|
||||
border-radius: 0;
|
||||
border-bottom: 1px solid #ebebeb;
|
||||
}
|
||||
.rb-icons-nav > li.dropdown.global-create2 > a:after {
|
||||
bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.rb-icons-nav > li.dropdown.global-create2 > a .icon {
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
|
|
@ -91,8 +91,16 @@ $(document).ready(function () {
|
|||
}
|
||||
|
||||
if (res.data.system === true) {
|
||||
$('.view-action').remove()
|
||||
$('.J_tips').removeClass('hide').find('.message p').text($L('系统内置超级管理员,不允许修改。此用户拥有最高级系统权限,请谨慎使用'))
|
||||
// v35
|
||||
if (userId === '001-0000000000000000') {
|
||||
$('.view-action').remove()
|
||||
} else {
|
||||
$('.J_mores .dropdown-menu>*').each(function () {
|
||||
if (!$(this).hasClass('J_resetpwd')) $(this).remove()
|
||||
})
|
||||
}
|
||||
|
||||
$('.J_tips').removeClass('hide').find('.message p').text($L('系统内置超级管理员。此用户拥有最高级系统权限,请谨慎使用'))
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ $(document).ready(() => {
|
|||
}, 200)
|
||||
}
|
||||
|
||||
$('.h5-mobile img').attr('src', `${rb.baseUrl}/commons/barcode/render-qr?w=150&t=${$encode($('.h5-mobile a').attr('href'))}`)
|
||||
$('.h5-mobile img').attr('src', `${rb.baseUrl}/commons/barcode/render-qr?w=296&t=${$encode($('.h5-mobile a').attr('href'))}`)
|
||||
|
||||
$.get('/user/live-wallpaper', (res) => {
|
||||
if (res.error_code !== 0 || !res.data) return
|
||||
|
|
|
@ -85,6 +85,7 @@ class DlgEdit extends RbFormHandler {
|
|||
}
|
||||
|
||||
render() {
|
||||
// v35 取消禁用设置
|
||||
return (
|
||||
<RbModal title={this.props.id ? $L('修改分类数据') : $L('添加分类数据')} ref={(c) => (this._dlg = c)} disposeOnHide={true}>
|
||||
<div className="form">
|
||||
|
@ -94,7 +95,7 @@ class DlgEdit extends RbFormHandler {
|
|||
<input className="form-control form-control-sm" value={this.state.name || ''} data-id="name" onChange={this.handleChange} maxLength="40" />
|
||||
</div>
|
||||
</div>
|
||||
{this.props.id && (
|
||||
{this.props.id && this.state.isDisabled === true && (
|
||||
<div className="form-group row">
|
||||
<div className="col-sm-7 offset-sm-3">
|
||||
<label className="custom-control custom-control-sm custom-checkbox custom-control-inline mb-0">
|
||||
|
|
|
@ -517,6 +517,7 @@ class ApprovalApproveForm extends ApprovalUsersForm {
|
|||
<LiteForm entity={this.props.entity} id={this.props.id} rawModel={{}} $$$parent={fake} ref={(c) => (this._LiteForm = c)}>
|
||||
{this.state.aform.map((item) => {
|
||||
item.isFull = true
|
||||
delete item.referenceQuickNew // v35
|
||||
// eslint-disable-next-line no-undef
|
||||
return detectElement(item)
|
||||
})}
|
||||
|
@ -627,6 +628,7 @@ class ApprovalApproveForm extends ApprovalUsersForm {
|
|||
if (res.error_code === 0) {
|
||||
_alert.hide()
|
||||
_reload(this, $L('已转审'))
|
||||
typeof this.props.call === 'function' && this.props.call()
|
||||
} else {
|
||||
RbHighbar.error(res.error_msg)
|
||||
}
|
||||
|
@ -650,6 +652,7 @@ class ApprovalApproveForm extends ApprovalUsersForm {
|
|||
if (res.error_code === 0) {
|
||||
_alert.hide()
|
||||
_reload(this, $L('已加签'))
|
||||
typeof this.props.call === 'function' && this.props.call()
|
||||
} else {
|
||||
RbHighbar.error(res.error_msg)
|
||||
}
|
||||
|
|
|
@ -457,9 +457,9 @@ class BatchUpdate extends BatchOperator {
|
|||
}
|
||||
})
|
||||
},
|
||||
onRendered: function () {
|
||||
$countdownButton($(this._dlg).find('.btn-primary'))
|
||||
},
|
||||
// onRendered: function () {
|
||||
// $countdownButton($(this._dlg).find('.btn-primary'))
|
||||
// },
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -2389,7 +2389,7 @@ class RbFormBarcode extends RbFormElement {
|
|||
onClick={() => {
|
||||
RbAlert.create(
|
||||
<div className="mb-4">
|
||||
<img src={`${codeUrl}&w=${isbar ? 64 * 2 : 80 * 2.5}`} alt={this.state.value} />
|
||||
<img src={`${codeUrl}&w=${isbar ? 64 * 2 : 80 * 3}`} alt={this.state.value} style={{ maxWidth: '100%' }} />
|
||||
{!isbar && <div className="text-muted mt-3 mb-1 text-break">{this.state.value}</div>}
|
||||
</div>,
|
||||
{
|
||||
|
|
|
@ -278,7 +278,7 @@ class AccountSelectorWithField extends UserSelector {
|
|||
LastLogsViewer.renderLog = function (log) {
|
||||
return log.level === 1 && log.message ? (
|
||||
<dl className="m-0">
|
||||
<dt>{$L('已发送给')}</dt>
|
||||
<dt>{$L('已发送至')}</dt>
|
||||
<dd className="mb-0">
|
||||
{log.message.split(',').map((a, idx) => {
|
||||
return $regex.isId(a) ? (
|
||||
|
@ -286,7 +286,7 @@ LastLogsViewer.renderLog = function (log) {
|
|||
{a}
|
||||
</a>
|
||||
) : (
|
||||
<span key={idx} className="badge text-id">
|
||||
<span key={idx} className="badge text-id text-break">
|
||||
{a}
|
||||
</span>
|
||||
)
|
||||
|
|
|
@ -166,7 +166,7 @@
|
|||
<span class="up-1">[[${bundle.L('手机版')}]]</span>
|
||||
</a>
|
||||
<div class="dropdown-menu shadow-lg">
|
||||
<div class="p-1">
|
||||
<div>
|
||||
<img class="w-100" alt="Mobile QR" />
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Reference in a new issue