Merge remote-tracking branch 'origin/master'

master
guoxin 1 year ago
commit a3637f44b8
  1. 47
      dbsql/update/update202308.sql
  2. 2
      shandan-basedata/src/main/java/com/keyware/shandan/dynacmicform/controller/DynamicFormController.java
  3. 20
      shandan-basedata/src/main/java/com/keyware/shandan/dynacmicform/core/basic/services/DynamicDataService.java
  4. 40
      shandan-basedata/src/main/java/com/keyware/shandan/dynacmicform/core/basic/services/DynamicFormService.java
  5. 8
      shandan-basedata/src/main/java/com/keyware/shandan/dynacmicform/core/basic/services/impl/FormInfoServiceImpl.java
  6. 15
      shandan-basedata/src/main/java/com/keyware/shandan/dynacmicform/core/db/SqlHelper.java
  7. 56
      shandan-basedata/src/main/java/com/keyware/shandan/dynacmicform/core/db/executor/SqlExecutor.java
  8. 2
      shandan-basedata/src/main/resources/view/dynamicForm/designForm.html
  9. 31
      shandan-basedata/src/main/resources/view/dynamicForm/formList.html
  10. 7
      shandan-bianmu/src/main/java/com/keyware/shandan/bianmu/controller/MetadataController.java
  11. 3
      shandan-bianmu/src/main/resources/application-dev.yml
  12. 2
      shandan-bianmu/src/main/resources/static/js/business/directory/directory.js
  13. 3
      shandan-bianmu/src/main/resources/static/js/business/metadata/edit.js
  14. 14
      shandan-bianmu/src/main/resources/static/js/business/metadata/metadata.js
  15. 66
      shandan-bianmu/src/main/resources/view/business/metadata/metadataEdit.html
  16. 14
      shandan-browser/src/main/java/com/keyware/shandan/browser/controller/BrowserIndexController.java
  17. 5
      shandan-browser/src/main/java/com/keyware/shandan/browser/controller/SearchController.java
  18. 34
      shandan-browser/src/main/java/com/keyware/shandan/browser/entity/SearchConditionVo.java
  19. 34
      shandan-browser/src/main/java/com/keyware/shandan/browser/entity/SearchResultSort.java
  20. 17
      shandan-browser/src/main/java/com/keyware/shandan/browser/service/ExportComponent.java
  21. 41
      shandan-browser/src/main/java/com/keyware/shandan/browser/service/FileSearchService.java
  22. 38
      shandan-browser/src/main/java/com/keyware/shandan/browser/service/MetadataSearchService.java
  23. 3
      shandan-browser/src/main/resources/application-dev.yml
  24. 247
      shandan-browser/src/main/resources/static/js/browser.js
  25. 3
      shandan-browser/src/main/resources/static/js/meta_search.js
  26. 15
      shandan-browser/src/main/resources/static/js/report.js
  27. 58
      shandan-browser/src/main/resources/view/browser.html
  28. 4
      shandan-common/src/main/java/com/keyware/shandan/common/entity/TreeVo.java
  29. 2
      shandan-common/src/main/java/com/keyware/shandan/common/util/TreeUtil.java
  30. 18
      shandan-common/src/main/resources/static/css/common/common.css
  31. 68
      shandan-common/src/main/resources/static/js/common/layui/extend/datalabel.js
  32. 9
      shandan-common/src/main/resources/static/js/common/layui/extend/dict.js
  33. 4
      shandan-common/src/main/resources/view/common/head.html
  34. 5
      shandan-control/src/main/java/com/keyware/shandan/control/config/DynamicFormListener.java
  35. 6
      shandan-control/src/main/resources/application-dev.yml
  36. 3
      shandan-desktop/src/main/resources/application-dev.yml
  37. 9
      shandan-system/src/main/java/com/keyware/shandan/bianmu/controller/MetadataCommonController.java
  38. 10
      shandan-system/src/main/java/com/keyware/shandan/bianmu/entity/DataLabelsVo.java
  39. 18
      shandan-system/src/main/java/com/keyware/shandan/bianmu/entity/DirectoryVo.java
  40. 4
      shandan-system/src/main/java/com/keyware/shandan/bianmu/entity/LabelEntity.java
  41. 19
      shandan-system/src/main/java/com/keyware/shandan/bianmu/mapper/LabelEntityMapper.java
  42. 36
      shandan-system/src/main/java/com/keyware/shandan/bianmu/service/DirectoryTreeService.java
  43. 7
      shandan-system/src/main/java/com/keyware/shandan/bianmu/utils/DirectoryUtil.java
  44. 17
      shandan-system/src/main/java/com/keyware/shandan/frame/aspect/SafetyAspect.java
  45. 2
      shandan-system/src/main/java/com/keyware/shandan/mark/controller/MarkViewController.java
  46. 2
      shandan-system/src/main/java/com/keyware/shandan/mark/services/MarkService.java
  47. 12
      shandan-system/src/main/java/com/keyware/shandan/system/constants/FormTypeEnum.java
  48. 6
      shandan-system/src/main/java/com/keyware/shandan/system/controller/SysFileController.java
  49. 57
      shandan-system/src/main/java/com/keyware/shandan/system/controller/SysFormConfigController.java
  50. 42
      shandan-system/src/main/java/com/keyware/shandan/system/controller/SysTheadConfigController.java
  51. 66
      shandan-system/src/main/java/com/keyware/shandan/system/entity/SysFormConfig.java
  52. 65
      shandan-system/src/main/java/com/keyware/shandan/system/entity/SysTheadConfig.java
  53. 15
      shandan-system/src/main/java/com/keyware/shandan/system/mapper/SysFormConfigMapper.java
  54. 15
      shandan-system/src/main/java/com/keyware/shandan/system/mapper/SysTheadConfigMapper.java
  55. 18
      shandan-system/src/main/java/com/keyware/shandan/system/service/SysFormConfigService.java
  56. 16
      shandan-system/src/main/java/com/keyware/shandan/system/service/SysTheadConfigService.java
  57. 2
      shandan-system/src/main/java/com/keyware/shandan/system/service/impl/SysDictServiceImpl.java
  58. 27
      shandan-system/src/main/java/com/keyware/shandan/system/service/impl/SysFormConfigServiceImpl.java
  59. 78
      shandan-system/src/main/java/com/keyware/shandan/system/service/impl/SysTheadConfigServiceImpl.java
  60. 1
      shandan-system/src/main/resources/mybatis/mapper/bianmu/DirectoryMapper.xml
  61. 2
      shandan-system/src/main/resources/static/css/sys/file/fileView.css
  62. 6
      shandan-system/src/main/resources/static/js/business/datalabels/managerIndex.js
  63. 24
      shandan-system/src/main/resources/static/js/business/directory/dirCommon.js
  64. 2
      shandan-system/src/main/resources/static/js/sys/file/dirUpload.js
  65. 8
      shandan-system/src/main/resources/static/js/sys/file/view.js
  66. 88
      shandan-system/src/main/resources/static/js/sys/form/formConfig.js
  67. 72
      shandan-system/src/main/resources/view/business/metadata/details.html
  68. 8
      shandan-system/src/main/resources/view/sys/dict/dictEdit.html
  69. 197
      shandan-system/src/main/resources/view/sys/file/dirUploadLayer.html
  70. 159
      shandan-system/src/main/resources/view/sys/file/fileEditLayer.html
  71. 53
      shandan-system/src/main/resources/view/sys/file/fileView.html
  72. 57
      shandan-system/src/main/resources/view/sys/form/formConfig.html

@ -0,0 +1,47 @@
-- 目录表增加加载顺序字段
alter table BIANMU.B_DIRECTORY add SORT integer;
comment on column BIANMU.B_DIRECTORY.SORT is '加载顺序';
-- 置标标签表增加加载顺序字段
alter table BIANMU.B_DATA_LABELS add SORT integer;
comment on column BIANMU.B_DATA_LABELS.SORT is '加载顺序';
-- 更新菜单数据
UPDATE BIANMU.SYS_MENU t
SET t.IS_DELETE = '0',
t.MENU_NAME = '表单配置',
t.MENU_PATH = '/sys/form/config/page/index'
WHERE t.MENU_ID = '1525058137475338242';
CREATE TABLE "BIANMU"."SYS_FORM_CONFIG"
(
"ID" INTEGER IDENTITY(1000, 1) NOT NULL,
"FORM_TYPE" INTEGER,
"FIELD_TITLE" VARCHAR2(50),
"SHOW_TITLE" VARCHAR2(50),
"FIELD_TYPE" VARCHAR2(50),
"DEFAULT_VALUE" VARCHAR2(50) DEFAULT '',
"IS_REQUIRED" BIT DEFAULT 0,
"IS_DISABLED" BIT DEFAULT 0,
"IS_SHOW" BIT DEFAULT 1,
"SORT" INTEGER,
"CREATE_USER" VARCHAR2(50),
"CREATE_TIME" TIMESTAMP(6),
"MODIFY_USER" VARCHAR2(50),
"MODIFY_TIME" TIMESTAMP(6),
CLUSTER PRIMARY KEY("ID")
) STORAGE(ON "MAIN", CLUSTERBTR);
COMMENT ON TABLE "BIANMU"."SYS_FORM_CONFIG" IS '系统表单配置表';
COMMENT ON COLUMN "BIANMU"."SYS_FORM_CONFIG"."CREATE_TIME" IS '创建时间';
COMMENT ON COLUMN "BIANMU"."SYS_FORM_CONFIG"."CREATE_USER" IS '创建人';
COMMENT ON COLUMN "BIANMU"."SYS_FORM_CONFIG"."DEFAULT_VALUE" IS '默认值';
COMMENT ON COLUMN "BIANMU"."SYS_FORM_CONFIG"."FIELD_TITLE" IS '字段标题';
COMMENT ON COLUMN "BIANMU"."SYS_FORM_CONFIG"."FIELD_TYPE" IS '字段类型';
COMMENT ON COLUMN "BIANMU"."SYS_FORM_CONFIG"."FORM_TYPE" IS '表单类型:1-资源注册表单,2-文件上传表单';
COMMENT ON COLUMN "BIANMU"."SYS_FORM_CONFIG"."ID" IS '主键';
COMMENT ON COLUMN "BIANMU"."SYS_FORM_CONFIG"."IS_DISABLED" IS '是否必填:0-非必填,1-必填';
COMMENT ON COLUMN "BIANMU"."SYS_FORM_CONFIG"."IS_REQUIRED" IS '是否禁用:0-不禁用,1-禁用';
COMMENT ON COLUMN "BIANMU"."SYS_FORM_CONFIG"."IS_SHOW" IS '是否显示';
COMMENT ON COLUMN "BIANMU"."SYS_FORM_CONFIG"."MODIFY_TIME" IS '修改时间';
COMMENT ON COLUMN "BIANMU"."SYS_FORM_CONFIG"."MODIFY_USER" IS '修改人';
COMMENT ON COLUMN "BIANMU"."SYS_FORM_CONFIG"."SHOW_TITLE" IS '显示标题';
COMMENT ON COLUMN "BIANMU"."SYS_FORM_CONFIG"."SORT" IS '显示顺序';

@ -157,7 +157,7 @@ public class DynamicFormController {
* @return 结果 * @return 结果
*/ */
@PostMapping("/api/form/delete") @PostMapping("/api/form/delete")
public Result<Object> deleteFormInfo(int id) { public Result<Object> deleteFormInfo(int id) throws Exception {
return Result.of(dynamicFormService.delete(id)); return Result.of(dynamicFormService.delete(id));
} }
} }

@ -14,6 +14,12 @@ import java.util.*;
@Service @Service
public class DynamicDataService { public class DynamicDataService {
private final SqlExecutor sqlExecutor;
public DynamicDataService(SqlExecutor sqlExecutor) {
this.sqlExecutor = sqlExecutor;
}
/** /**
* 根据ID删除数据 * 根据ID删除数据
@ -25,7 +31,7 @@ public class DynamicDataService {
*/ */
public boolean deleteById(FormInfoPo form, Integer id) throws Exception { public boolean deleteById(FormInfoPo form, Integer id) throws Exception {
QueryParam param = QueryParam.builder().column("ID").eq(id).build(); QueryParam param = QueryParam.builder().column("ID").eq(id).build();
return SqlExecutor.executeUpdate(SqlHelper.deleteSql(form, param), id); return sqlExecutor.executeUpdate(SqlHelper.deleteSql(form, param), id);
} }
@ -58,7 +64,7 @@ public class DynamicDataService {
// 插入Sql,去除主键列 // 插入Sql,去除主键列
params.remove("ID"); params.remove("ID");
LinkedHashMap<String, Object> data = new LinkedHashMap<>(params); LinkedHashMap<String, Object> data = new LinkedHashMap<>(params);
return SqlExecutor.executeUpdate(SqlHelper.insertSql(form, data), data.values().toArray()); return sqlExecutor.executeUpdate(SqlHelper.insertSql(form, data), data.values().toArray());
} }
/** /**
@ -75,7 +81,7 @@ public class DynamicDataService {
QueryParam queryParam = QueryParam.builder().column("ID").eq(id).build(); QueryParam queryParam = QueryParam.builder().column("ID").eq(id).build();
List<Object> paramValues = new ArrayList<>(dataMap.values()); List<Object> paramValues = new ArrayList<>(dataMap.values());
paramValues.addAll(queryParam.getParamValues()); paramValues.addAll(queryParam.getParamValues());
return SqlExecutor.executeUpdate(SqlHelper.updateSql(form, dataMap, queryParam), paramValues.toArray()); return sqlExecutor.executeUpdate(SqlHelper.updateSql(form, dataMap, queryParam), paramValues.toArray());
} }
/** /**
@ -88,7 +94,7 @@ public class DynamicDataService {
*/ */
public Map<String, Object> getById(FormInfoPo form, @NotNull Integer id) throws Exception { public Map<String, Object> getById(FormInfoPo form, @NotNull Integer id) throws Exception {
QueryParam param = QueryParam.builder().column("ID").eq(id).build(); QueryParam param = QueryParam.builder().column("ID").eq(id).build();
List<Map<String, Object>> list = SqlExecutor.executeQuery(SqlHelper.selectSql(form, param), id); List<Map<String, Object>> list = sqlExecutor.executeQuery(SqlHelper.selectSql(form, param), id);
if (list == null) { if (list == null) {
return null; return null;
} }
@ -105,12 +111,12 @@ public class DynamicDataService {
* @throws Exception - * @throws Exception -
*/ */
public Page<Map<String, Object>> pageList(FormInfoPo form, QueryParam params) throws Exception { public Page<Map<String, Object>> pageList(FormInfoPo form, QueryParam params) throws Exception {
List<Map<String, Object>> countList = SqlExecutor.executeQuery(SqlHelper.countSql(form, params), params.getParamValues().toArray()); List<Map<String, Object>> countList = sqlExecutor.executeQuery(SqlHelper.countSql(form, params), params.getParamValues().toArray());
long count = 0; long count = 0;
if (countList != null && countList.size() > 0) { if (countList != null && countList.size() > 0) {
count = (long) countList.get(0).get("COUNT"); count = (long) countList.get(0).get("COUNT");
} }
List<Map<String, Object>> dataList = SqlExecutor.executeQuery(SqlHelper.pageSelectSql(form, params), params.getParamValues().toArray()); List<Map<String, Object>> dataList = sqlExecutor.executeQuery(SqlHelper.pageSelectSql(form, params), params.getParamValues().toArray());
Page<Map<String, Object>> page = new Page<>(params.getPage(), params.getPageSize(), count); Page<Map<String, Object>> page = new Page<>(params.getPage(), params.getPageSize(), count);
page.setRecords(dataList); page.setRecords(dataList);
return page; return page;
@ -124,6 +130,6 @@ public class DynamicDataService {
* @throws Exception * @throws Exception
*/ */
public List<Map<String, Object>> list(FormInfoPo form) throws Exception { public List<Map<String, Object>> list(FormInfoPo form) throws Exception {
return SqlExecutor.executeQuery(SqlHelper.selectSql(form, null)); return sqlExecutor.executeQuery(SqlHelper.selectSql(form, null));
} }
} }

@ -3,6 +3,7 @@ package com.keyware.shandan.dynacmicform.core.basic.services;
import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.keyware.shandan.common.util.DateUtil;
import com.keyware.shandan.common.util.StringUtils; import com.keyware.shandan.common.util.StringUtils;
import com.keyware.shandan.dynacmicform.core.DynamicFormEventListener; import com.keyware.shandan.dynacmicform.core.DynamicFormEventListener;
import com.keyware.shandan.dynacmicform.core.basic.entity.FormInfoPo; import com.keyware.shandan.dynacmicform.core.basic.entity.FormInfoPo;
@ -12,6 +13,7 @@ import com.keyware.shandan.dynacmicform.core.db.parser.TableInfoParser;
import com.keyware.shandan.dynacmicform.core.db.pojo.Table; import com.keyware.shandan.dynacmicform.core.db.pojo.Table;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List; import java.util.List;
@ -21,11 +23,14 @@ import java.util.List;
@Slf4j @Slf4j
@Service @Service
public class DynamicFormService { public class DynamicFormService {
private final SqlExecutor sqlExecutor;
private final FormInfoService formInfoService; private final FormInfoService formInfoService;
private final DynamicFormEventListener dynamicFormEventListener; private final DynamicFormEventListener dynamicFormEventListener;
public DynamicFormService(FormInfoService formInfoService, DynamicFormEventListener dynamicFormEventListener) { public DynamicFormService(SqlExecutor sqlExecutor,
FormInfoService formInfoService,
DynamicFormEventListener dynamicFormEventListener) {
this.sqlExecutor = sqlExecutor;
this.formInfoService = formInfoService; this.formInfoService = formInfoService;
this.dynamicFormEventListener = dynamicFormEventListener; this.dynamicFormEventListener = dynamicFormEventListener;
} }
@ -37,12 +42,13 @@ public class DynamicFormService {
* @return boolean * @return boolean
* @throws Exception 异常 * @throws Exception 异常
*/ */
@Transactional(rollbackFor = Exception.class)
public boolean saveForm(FormInfoPo form) throws Exception { public boolean saveForm(FormInfoPo form) throws Exception {
FormInfoPo oldForm = formInfoService.getById(form.getId()); FormInfoPo oldForm = formInfoService.getById(form.getId());
Table table = TableInfoParser.parseTable(form); Table table = TableInfoParser.parseTable(form);
if (oldForm == null) { if (oldForm == null) {
String sql = SqlHelper.createSql(table); String sql = SqlHelper.tableCreateSql(table);
SqlExecutor.execute(sql); sqlExecutor.execute(sql);
} else { } else {
Table oldTable = TableInfoParser.parseTable(oldForm); Table oldTable = TableInfoParser.parseTable(oldForm);
List<String> alterSqlList = SqlHelper.alterTableDropColumnSql(oldTable, table); List<String> alterSqlList = SqlHelper.alterTableDropColumnSql(oldTable, table);
@ -51,7 +57,7 @@ public class DynamicFormService {
alterSqlList.addAll(SqlHelper.alterTableAddColumnSql(oldTable, table)); alterSqlList.addAll(SqlHelper.alterTableAddColumnSql(oldTable, table));
alterSqlList.addAll(SqlHelper.commentTableSql(oldTable, table)); alterSqlList.addAll(SqlHelper.commentTableSql(oldTable, table));
alterSqlList.addAll(SqlHelper.commentColumnSql(oldTable, table)); alterSqlList.addAll(SqlHelper.commentColumnSql(oldTable, table));
SqlExecutor.executeBatch(alterSqlList); sqlExecutor.executeBatch(alterSqlList);
} }
if (StringUtils.isBlank(form.getQueryConfig())) { if (StringUtils.isBlank(form.getQueryConfig())) {
generateQueryConfig(form); generateQueryConfig(form);
@ -65,18 +71,30 @@ public class DynamicFormService {
} }
/** /**
* 删除表单信息 * 删除表单信息逻辑删除并对实际数据表进行重命名备份
* *
* @param id * @param id
* @return * @return
*/ */
public boolean delete(Integer id) { @Transactional(rollbackFor = Exception.class)
public boolean delete(Integer id) throws Exception {
FormInfoPo form = formInfoService.getById(id); FormInfoPo form = formInfoService.getById(id);
boolean ok = formInfoService.removeById(id); if (form != null) {
if (ok) { // 对原始表结构进行重命名备份
dynamicFormEventListener.onDrop(form); Table table = TableInfoParser.parseTable(form);
String newName = table.getName() + "_BACKUP_" + DateUtil.getFormatNowDate("yyyyMMddHHmmss");
String sql = SqlHelper.tableRenameSql(table.getName(), newName);
sqlExecutor.execute(sql);
// 更新表名后进行逻辑删除
form.setFormId(newName);
formInfoService.updateById(form);
boolean ok = formInfoService.removeById(id);
if (!ok) {
throw new RuntimeException("表单信息删除异常");
}
} }
return ok; dynamicFormEventListener.onDrop(form);
return true;
} }
/** /**

@ -5,6 +5,8 @@ import com.keyware.shandan.dynacmicform.core.basic.entity.FormInfoPo;
import com.keyware.shandan.dynacmicform.core.basic.mapper.FormInfoMapper; import com.keyware.shandan.dynacmicform.core.basic.mapper.FormInfoMapper;
import com.keyware.shandan.dynacmicform.core.basic.services.FormInfoService; import com.keyware.shandan.dynacmicform.core.basic.services.FormInfoService;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.io.Serializable; import java.io.Serializable;
@ -15,4 +17,10 @@ public class FormInfoServiceImpl extends ServiceImpl<FormInfoMapper, FormInfoPo>
public boolean removeById(Serializable id) { public boolean removeById(Serializable id) {
return super.removeById(id); return super.removeById(id);
} }
/*@Override
@Transactional(rollbackFor = Exception.class, propagation = Propagation.SUPPORTS)
public boolean saveOrUpdate(FormInfoPo entity) {
return super.saveOrUpdate(entity);
}*/
} }

@ -1,6 +1,7 @@
package com.keyware.shandan.dynacmicform.core.db; package com.keyware.shandan.dynacmicform.core.db;
import cn.hutool.core.lang.Assert; import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.keyware.shandan.common.util.StreamUtil; import com.keyware.shandan.common.util.StreamUtil;
import com.keyware.shandan.common.util.StringUtils; import com.keyware.shandan.common.util.StringUtils;
import com.keyware.shandan.dynacmicform.core.basic.entity.FormInfoPo; import com.keyware.shandan.dynacmicform.core.basic.entity.FormInfoPo;
@ -23,7 +24,7 @@ public class SqlHelper {
* @param table * @param table
* @return * @return
*/ */
public static String createSql(Table table) { public static String tableCreateSql(Table table) {
StringBuilder sqlBuilder = new StringBuilder("CREATE TABLE "); StringBuilder sqlBuilder = new StringBuilder("CREATE TABLE ");
sqlBuilder.append("\"").append(table.getName()).append("\" ("); sqlBuilder.append("\"").append(table.getName()).append("\" (");
@ -46,13 +47,17 @@ public class SqlHelper {
return sqlBuilder.toString(); return sqlBuilder.toString();
} }
public static String tableRenameSql(String oldTableName, String newTableName) {
return StrUtil.format("alter table \"{}\" rename to \"{}\"", oldTableName, newTableName);
}
/** /**
* 修改表的sql * 修改表的sql
* *
* @param columns 修改的列集合 * @param columns 修改的列集合
* @return * @return
*/ */
public static List<String> alterSql(Map<String, List<Column>> columns) { public static List<String> tableAlterSql(Map<String, List<Column>> columns) {
List<String> alterSqlList = new ArrayList<>(); List<String> alterSqlList = new ArrayList<>();
return alterSqlList; return alterSqlList;
@ -64,10 +69,8 @@ public class SqlHelper {
* @param table * @param table
* @return * @return
*/ */
public static String dropSql(Table table) { public static String tableDropSql(Table table) {
StringBuilder sqlBuilder = new StringBuilder(); return "DROP TABLE \"" + table.getName() + "\"";
return sqlBuilder.toString();
} }
/** /**

@ -6,8 +6,10 @@ import com.keyware.shandan.common.util.StringUtils;
import com.keyware.shandan.dynacmicform.config.spring.ContextHelper; import com.keyware.shandan.dynacmicform.config.spring.ContextHelper;
import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.io.IOException; import java.io.IOException;
import java.io.Reader; import java.io.Reader;
@ -15,19 +17,24 @@ import java.sql.Date;
import java.sql.*; import java.sql.*;
import java.util.*; import java.util.*;
@Component
public class SqlExecutor { public class SqlExecutor {
private static final Logger log = LoggerFactory.getLogger(SqlExecutor.class); private static final Logger log = LoggerFactory.getLogger(SqlExecutor.class);
private final SqlSession sqlSession;
public SqlExecutor(SqlSession sqlSession) {
this.sqlSession = sqlSession;
}
/** /**
* 检查SQL是否可以正常执行 * 检查SQL是否可以正常执行
* *
* @param sql sql * @param sql sql
* @return boolean * @return boolean
*/ */
public static boolean validateQuery(String sql) { public boolean validateQuery(String sql) {
// 获取SqlSessionFactory实例 try (Connection conn = getConnection(); PreparedStatement stmt = conn.prepareStatement(sql)) {
SqlSessionFactory sqlSessionFactory = getSessionFactory();
try (SqlSession session = sqlSessionFactory.openSession(); Connection conn = session.getConnection(); PreparedStatement stmt = conn.prepareStatement(sql)) {
ResultSet rs = stmt.executeQuery(); ResultSet rs = stmt.executeQuery();
rs.close(); rs.close();
log.debug("==> {}", sql); log.debug("==> {}", sql);
@ -38,15 +45,15 @@ public class SqlExecutor {
} }
} }
public static boolean execute(String sql) throws Exception { public boolean execute(String sql) throws Exception {
if (StringUtils.isEmpty(sql)) { if (StringUtils.isEmpty(sql)) {
return false; return false;
} }
// 获取SqlSessionFactory实例
SqlSessionFactory sqlSessionFactory = getSessionFactory();
log.debug("==> SQL: " + sql); log.debug("==> SQL: " + sql);
try (SqlSession session = sqlSessionFactory.openSession(); Connection conn = session.getConnection(); PreparedStatement stmt = conn.prepareStatement(sql)) { try {
Connection conn = sqlSession.getConnection();
PreparedStatement stmt = conn.prepareStatement(sql);
return stmt.execute(); return stmt.execute();
} catch (Exception e) { } catch (Exception e) {
log.error("执行sql查询异常: " + sql, e); log.error("执行sql查询异常: " + sql, e);
@ -61,15 +68,15 @@ public class SqlExecutor {
* @return * @return
* @throws SQLException * @throws SQLException
*/ */
public static int[] executeBatch(Collection<String> sqlList) throws SQLException { public int[] executeBatch(Collection<String> sqlList) throws SQLException {
int[] count = new int[sqlList.size()]; int[] count = new int[sqlList.size()];
if (sqlList.isEmpty()) { if (sqlList.isEmpty()) {
return count; return count;
} }
SqlSessionFactory sqlSessionFactory = getSessionFactory();
PreparedStatement stmt = null; PreparedStatement stmt = null;
try (SqlSession session = sqlSessionFactory.openSession(); Connection conn = session.getConnection()) { try {
Connection conn = getConnection();
conn.setAutoCommit(false); conn.setAutoCommit(false);
for (String sql : sqlList) { for (String sql : sqlList) {
if (StringUtils.hasText(sql)) { if (StringUtils.hasText(sql)) {
@ -102,12 +109,11 @@ public class SqlExecutor {
* @return boolean * @return boolean
* @throws Exception - * @throws Exception -
*/ */
public static boolean executeUpdate(String sql, Object... params) throws Exception { public boolean executeUpdate(String sql, Object... params) throws Exception {
if (StringUtils.isEmpty(sql)) { if (StringUtils.isEmpty(sql)) {
return false; return false;
} }
// 获取SqlSessionFactory实例
SqlSessionFactory sqlSessionFactory = getSessionFactory();
log.debug("==> SQL: " + sql); log.debug("==> SQL: " + sql);
// 替换单个?参数为多个,用于拼接IN参数 // 替换单个?参数为多个,用于拼接IN参数
if (params != null && params.length > 0) { if (params != null && params.length > 0) {
@ -116,7 +122,9 @@ public class SqlExecutor {
log.warn("更新参数集合数量过多, size={},请检查调用是否合理!", params.length); log.warn("更新参数集合数量过多, size={},请检查调用是否合理!", params.length);
} }
} }
try (SqlSession session = sqlSessionFactory.openSession(); Connection conn = session.getConnection(); PreparedStatement stmt = conn.prepareStatement(sql)) { try {
Connection conn = getConnection();
PreparedStatement stmt = conn.prepareStatement(sql);
if (params != null && params.length > 0) { if (params != null && params.length > 0) {
for (int i = 0; i < params.length; i++) { for (int i = 0; i < params.length; i++) {
stmt.setObject(i + 1, params[i]); stmt.setObject(i + 1, params[i]);
@ -137,12 +145,11 @@ public class SqlExecutor {
* @param sql * @param sql
* @return * @return
*/ */
public static List<Map<String, Object>> executeQuery(String sql, Object... params) throws Exception { public List<Map<String, Object>> executeQuery(String sql, Object... params) throws Exception {
if (StringUtils.isBlank(sql)) { if (StringUtils.isBlank(sql)) {
return null; return null;
} }
// 获取SqlSessionFactory实例
SqlSessionFactory sqlSessionFactory = getSessionFactory();
log.debug("==> SQL: " + sql); log.debug("==> SQL: " + sql);
// 替换单个?参数为多个,用于拼接IN参数 // 替换单个?参数为多个,用于拼接IN参数
if (params != null && params.length > 0) { if (params != null && params.length > 0) {
@ -151,7 +158,9 @@ public class SqlExecutor {
log.warn("查询参数集合数量过多, size={},请检查调用是否合理!", params.length); log.warn("查询参数集合数量过多, size={},请检查调用是否合理!", params.length);
} }
} }
try (SqlSession session = sqlSessionFactory.openSession(); Connection conn = session.getConnection(); PreparedStatement stmt = conn.prepareStatement(sql)) { try {
Connection conn = getConnection();
PreparedStatement stmt = conn.prepareStatement(sql);
if (params != null && params.length > 0) { if (params != null && params.length > 0) {
for (int i = 0; i < params.length; i++) { for (int i = 0; i < params.length; i++) {
stmt.setObject(i + 1, params[i]); stmt.setObject(i + 1, params[i]);
@ -186,13 +195,8 @@ public class SqlExecutor {
} }
} }
private static SqlSessionFactory getSessionFactory() { private Connection getConnection() throws SQLException {
SqlSessionFactory sqlSessionFactory = ContextHelper.getBean(SqlSessionFactory.class); return sqlSession.getConfiguration().getEnvironment().getDataSource().getConnection();
if (sqlSessionFactory == null) {
log.warn("无法获取SqlSessionFactory实例,SQL将不被执行。");
throw new RuntimeException("获取SqlSessionFactory实例异常");
}
return sqlSessionFactory;
} }
private static String clobRsConvert(Clob clob) { private static String clobRsConvert(Clob clob) {

@ -62,7 +62,7 @@
postRequest(`${ctx}/dynamic-form/api/form/save`, params).then(res => { postRequest(`${ctx}/dynamic-form/api/form/save`, params).then(res => {
if (res.flag) { if (res.flag) {
temp_data = params; temp_data = params;
showOkMsg('保存成功'); saveCallback && saveCallback();
} else { } else {
showErrorMsg(res.msg) showErrorMsg(res.msg)
} }

@ -14,10 +14,12 @@
<div id="form-list-table" lay-filter="form-list-table"></div> <div id="form-list-table" lay-filter="form-list-table"></div>
<script type="text/html" id="table-head-toolbar"> <script type="text/html" id="table-head-toolbar">
<div class="btn-comp"> <div class="btn-comp">
<button type="button" class="layui-btn layui-btn-sm layui-btn-warm" lay-event="newDesign">设计表单</button> <button type="button" class="layui-btn layui-btn-sm layui-btn-warm" lay-event="newDesign">设计表单
</button>
</div> </div>
<div class="search-comp"> <div class="search-comp">
<input class="layui-input" type="text" id="searchText" name="searchText" placeholder="请输入表单名称进行查询"/> <input class="layui-input" type="text" id="searchText" name="searchText"
placeholder="请输入表单名称进行查询"/>
<button type="button" class="layui-btn layui-btn-sm" lay-event="query">查 询</button> <button type="button" class="layui-btn layui-btn-sm" lay-event="query">查 询</button>
</div> </div>
</script> </script>
@ -79,7 +81,7 @@
openFormConfigLayer(id); openFormConfigLayer(id);
break; break;
case 'delete': case 'delete':
formDelete(id) formDelete(data)
break; break;
} }
} }
@ -97,10 +99,21 @@
*/ */
function openFormDesignPage(id) { function openFormDesignPage(id) {
openMaxLayer(`${ctx}/dynamic-form/view/form/design?formId=${id}`, { openMaxLayer(`${ctx}/dynamic-form/view/form/design?formId=${id}`, {
success: function(layero, index){
let iframeWin = window[layero.find('iframe')[0]['name']];
iframeWin.saveCallback = function(){
formListTable.reload();
showOkMsg('保存成功');
layer.closeAll();
}
},
cancel: function (index, layerObj) { cancel: function (index, layerObj) {
let iframeWin = window[layerObj.find('iframe')[0]['name']]; let iframeWin = window[layerObj.find('iframe')[0]['name']];
if (iframeWin.isChange()) { if (iframeWin.isChange()) {
layer.confirm('关闭窗口将不会保存更改的内容,是否继续关闭?', {title: '关闭表单设计器', btn: ['关闭', '取消']}, function () { layer.confirm('关闭窗口将不会保存更改的内容,是否继续关闭?', {
title: '关闭表单设计器',
btn: ['关闭', '取消']
}, function () {
layer.closeAll(); layer.closeAll();
}) })
} else { } else {
@ -132,10 +145,14 @@
/** /**
* 删除表单 * 删除表单
* @param id * @param data
*/ */
function formDelete(id) { function formDelete(data) {
layer.confirm('是否删除该表单?', {title: '删除确认', btn: ['删除', '取消']}, function (layIndex) { const {id, formId} = data;
layer.confirm(`将同时删除以下数据库表:<br/><label style="color: orange">${formId}</label><br/>是否继续删除?`, {
title: '删除确认',
btn: ['删除', '取消']
}, function (layIndex) {
postRequest(`${ctx}/dynamic-form/api/form/delete`, {id}).then(res => { postRequest(`${ctx}/dynamic-form/api/form/delete`, {id}).then(res => {
layer.close(layIndex); layer.close(layIndex);
res.flag ? showOkMsg('删除成功') : showErrorMsg(res.msg); res.flag ? showOkMsg('删除成功') : showErrorMsg(res.msg);

@ -13,8 +13,11 @@ import com.keyware.shandan.common.entity.Result;
import com.keyware.shandan.common.enums.SecretLevel; import com.keyware.shandan.common.enums.SecretLevel;
import com.keyware.shandan.common.util.StreamUtil; import com.keyware.shandan.common.util.StreamUtil;
import com.keyware.shandan.common.util.StringUtils; import com.keyware.shandan.common.util.StringUtils;
import com.keyware.shandan.system.constants.FormTypeEnum;
import com.keyware.shandan.system.entity.SysFile; import com.keyware.shandan.system.entity.SysFile;
import com.keyware.shandan.system.entity.SysFormConfig;
import com.keyware.shandan.system.service.SysFileService; import com.keyware.shandan.system.service.SysFileService;
import com.keyware.shandan.system.service.SysFormConfigService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.ModelAndView;
@ -46,6 +49,9 @@ public class MetadataController extends BaseController<MetadataService, Metadata
@Autowired @Autowired
private DataLabelsService labelsService; private DataLabelsService labelsService;
@Autowired
private SysFormConfigService formConfigService;
@GetMapping("/") @GetMapping("/")
public ModelAndView index(ModelAndView mov) { public ModelAndView index(ModelAndView mov) {
mov.setViewName("business/metadata/metadata"); mov.setViewName("business/metadata/metadata");
@ -93,6 +99,7 @@ public class MetadataController extends BaseController<MetadataService, Metadata
public ModelAndView edit(ModelAndView mav) { public ModelAndView edit(ModelAndView mav) {
mav.setViewName("business/metadata/metadataEdit"); mav.setViewName("business/metadata/metadataEdit");
mav.addObject("LabelConfigSet", labelsService.formConfigList()); mav.addObject("LabelConfigSet", labelsService.formConfigList());
mav.addObject("metadataFormConfig", formConfigService.listByFormType(FormTypeEnum.metadataEditForm));
return mav; return mav;
} }

@ -50,4 +50,5 @@ project:
# 日志级别 # 日志级别
logging: logging:
level: level:
root: debug com.keyware: debug

@ -297,6 +297,8 @@ function startRender() {
}, },
}); });
}else{
showErrorMsg('数据表不支持下载');
} }
}) })
} }

@ -276,9 +276,10 @@ layui.use(['form', 'layer', 'editPage', 'laytpl', 'laydate', 'element', 'table',
layui.dict.setData('dict-secret-level', data); layui.dict.setData('dict-secret-level', data);
} }
console.info(new Date().getTime())
//日期选择器 //日期选择器
laydate.render({ laydate.render({
elem: '#collectionTime', elem: 'input[name="collectionTime"]',
type: 'datetime', type: 'datetime',
value: new Date(), value: new Date(),
format: "yyyy-MM-dd HH:mm:ss" format: "yyyy-MM-dd HH:mm:ss"

@ -12,8 +12,11 @@ layui.use(['layer', 'listPage', 'form', 'dict'], function () {
let height = $(document).height(); let height = $(document).height();
height = height < 650 ? height : height * 0.8; height = height < 650 ? height : height * 0.8;
let where = {metadataName: '', reviewStatus: '', useStatus: ''}; let where = {metadataName: '', reviewStatus: '', useStatus: ''};
const fieldMap = new Map()
METADATA_FORM_CONFIG.forEach(conf=>fieldMap.set(conf.fieldName, conf));
console.info(fieldMap);
const listPage = layui.listPage.init({ const listPage = layui.listPage.init({
deleteUrl: `${ctx}/business/metadata/delete`, deleteUrl: `${ctx}/business/metadata/delete`,
table: { table: {
@ -27,23 +30,26 @@ layui.use(['layer', 'listPage', 'form', 'dict'], function () {
{ {
field: 'metadataName', field: 'metadataName',
title: '数据名称', title: '数据名称',
hide: !fieldMap.get('metadataName').isShow,
templet: data => `<lable style="font-weight: ${data.hasMark ? 'bold' : 'italic'};">${data.metadataName}</lable>` templet: data => `<lable style="font-weight: ${data.hasMark ? 'bold' : 'italic'};">${data.metadataName}</lable>`
}, },
{field: 'metadataComment', title: '中文注释'}, {field: 'metadataComment', title: '中文注释',hide: fieldMap.get('metadataName').isShow},
{ {
field: 'secretLevel', field: 'secretLevel',
title: '密级', title: '密级',
hide: !fieldMap.get('secretLevel').isShow,
templet: data => layui.dict.getDictDesc('secret_level', data.secretLevel) templet: data => layui.dict.getDictDesc('secret_level', data.secretLevel)
}, },
{field: 'themeTask', title: '主题任务'}, {field: 'themeTask', title: '主题任务', hide: !fieldMap.get('themeTask').isShow},
{ {
field: 'dataFrom', field: 'dataFrom',
title: '数据来源', title: '数据来源',
hide: !fieldMap.get('dataFrom').isShow,
width: 100, width: 100,
templet: data => layui.dict.getDictDesc('data_source', data.dataFrom) templet: data => layui.dict.getDictDesc('data_source', data.dataFrom)
}, },
{field: 'collectionTime', title: '任务时间', width: 180, align: 'center'}, {field: 'collectionTime', title: '任务时间', width: 180, align: 'center',hide: !fieldMap.get('collectionTime').isShow},
{ {
field: 'used', title: '关联状态', width: 120, align: 'center', templet: (data) => { field: 'used', title: '关联状态', width: 120, align: 'center', templet: (data) => {
if (data.used) { if (data.used) {

@ -34,47 +34,28 @@
<div class="layui-form-item"> <div class="layui-form-item">
<div id="metadataTablesTab"><label style="color: red">* 请先选择数据表</label></div> <div id="metadataTablesTab"><label style="color: red">* 请先选择数据表</label></div>
</div> </div>
<div class="layui-form-item"> <div class="layui-form-item" th:each="field,iterStat : ${metadataFormConfig}" th:if="${field.isShow}">
<label class="layui-form-label">数据名称</label> <label th:if="${field.isRequired}" class="layui-form-label">
<div class="layui-input-block"> <label style="color: red">*</label>
<input type="hidden" name="metadataComment"> <label th:text="${field.showTitle}">*</label>
<input type="text" name="metadataName" autocomplete="off" placeholder="数据名称" </label>
class="layui-input" lay-verify="required" readonly> <label th:if="${!field.isRequired}" class="layui-form-label" th:text="${field.showTitle}"></label>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">任务时间</label>
<div class="layui-input-block">
<input type="text" id="collectionTime" name="collectionTime" placeholder="任务时间"
class="layui-input" lay-verify="required">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">数据来源</label>
<div class="layui-input-block">
<div dict-component="select" dict-type="data_source" dict-name="dataFrom"
id="dict-data-form"></div>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">数据类型</label>
<div class="layui-input-block">
<div dict-component="select" dict-type="data_type" dict-name="dataType"
id="dict-data-type"></div>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">数据密级</label>
<div class="layui-input-block"> <div class="layui-input-block">
<div dict-component="radio" dict-type="secret_level" dict-name="secretLevel" <input type="hidden" name="metadataComment" th:if="${field.fieldName == 'metadataName'}">
id="dict-secret-level"></div> <!-- 文本框输入框类型 -->
</div> <input class="layui-input" type="text" autocomplete="off"
</div> th:if="${field.fieldType == 'input' || field.fieldType == 'date'}"
<div class="layui-form-item"> th:name="${field.fieldName}"
<label class="layui-form-label">主题任务</label> th:disabled="${field.isDisabled}"
<div class="layui-input-block"> th:placeholder="${field.showTitle}"
<input type="text" name="themeTask" autocomplete="off" placeholder="主题任务" th:lay-verify="${field.isRequired ? 'required' : ''}">
class="layui-input"> <!-- 数据字典类型 -->
<div dict-component="select"
th:if="${field.fieldType == 'dict'}"
th:disabled="${field.isDisabled}"
th:dict-type="${field.dictType}"
th:dict-name="${field.fieldName}"
th:id="${'dict-'+field.fieldName}"></div>
</div> </div>
</div> </div>
<div class="layui-form-item" th:each="labelSet, iterState:${LabelConfigSet}"> <div class="layui-form-item" th:each="labelSet, iterState:${LabelConfigSet}">
@ -89,7 +70,9 @@
</div> </div>
<div class="layui-form-item other-label-item"> <div class="layui-form-item other-label-item">
<label class="layui-form-label"><a class="label-type choose-data add-other" id="addOtherLabelBtn">添加</a>其他标签</label> <label class="layui-form-label"><a class="label-type choose-data add-other" id="addOtherLabelBtn">添加</a>其他标签</label>
<div class="layui-input-block label-set-component other-label" th:data-field-title="其他标签"></div> <div class="layui-input-block other-label-item">
<div class="label-set-component other-label" th:data-field-title="其他标签"></div>
</div>
</div> </div>
<!-- 隐藏域 --> <!-- 隐藏域 -->
<input type="text" name="id" hidden="hidden"/> <input type="text" name="id" hidden="hidden"/>
@ -147,6 +130,5 @@
{{# } }} {{# } }}
</script> </script>
<!-- js --> <!-- js -->
<script th:src="@{/js/business/mark/markTag.js}"></script>
<script th:src="@{/js/business/metadata/edit.js}"></script> <script th:src="@{/js/business/metadata/edit.js}"></script>
</html> </html>

@ -4,7 +4,6 @@ import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.keyware.shandan.bianmu.entity.MetadataBasicVo; import com.keyware.shandan.bianmu.entity.MetadataBasicVo;
import com.keyware.shandan.bianmu.service.DirPermissionService; import com.keyware.shandan.bianmu.service.DirPermissionService;
import com.keyware.shandan.bianmu.service.DirectoryService;
import com.keyware.shandan.bianmu.service.MetadataService; import com.keyware.shandan.bianmu.service.MetadataService;
import com.keyware.shandan.common.enums.SystemTypes; import com.keyware.shandan.common.enums.SystemTypes;
import com.keyware.shandan.common.util.RsaUtil; import com.keyware.shandan.common.util.RsaUtil;
@ -13,11 +12,12 @@ import com.keyware.shandan.datasource.entity.DBTableColumnVo;
import com.keyware.shandan.frame.config.security.SecurityUtil; import com.keyware.shandan.frame.config.security.SecurityUtil;
import com.keyware.shandan.system.entity.SysSetting; import com.keyware.shandan.system.entity.SysSetting;
import com.keyware.shandan.system.entity.SysUser; import com.keyware.shandan.system.entity.SysUser;
import com.keyware.shandan.system.service.SysFileService; import com.keyware.shandan.system.service.SysTheadConfigService;
import com.keyware.shandan.system.service.SysUserService; import com.keyware.shandan.system.service.SysUserService;
import com.keyware.shandan.system.utils.SysSettingUtil; import com.keyware.shandan.system.utils.SysSettingUtil;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
@ -39,9 +39,6 @@ import java.util.List;
@RequestMapping("/") @RequestMapping("/")
public class BrowserIndexController { public class BrowserIndexController {
@Autowired
private DirectoryService directoryService;
@Autowired @Autowired
private MetadataService metadataService; private MetadataService metadataService;
@ -49,10 +46,10 @@ public class BrowserIndexController {
private SysUserService sysUserService; private SysUserService sysUserService;
@Autowired @Autowired
private SysFileService sysFileService; private DirPermissionService permissionService;
@Autowired @Autowired
private DirPermissionService permissionService; private SysTheadConfigService theadConfigService;
@Value("${project.cors-lib-search:#}") @Value("${project.cors-lib-search:#}")
private String corsLibSearchUrl; private String corsLibSearchUrl;
@ -90,10 +87,11 @@ public class BrowserIndexController {
} }
@GetMapping("/browser") @GetMapping("/browser")
public ModelAndView browser(ModelAndView mov) { public ModelAndView browser(ModelAndView mov, Authentication auth) {
mov.setViewName("browser"); mov.setViewName("browser");
SysSetting bianmuSetting = SysSettingUtil.getSysSetting(SystemTypes.BIANMU.name()); SysSetting bianmuSetting = SysSettingUtil.getSysSetting(SystemTypes.BIANMU.name());
mov.addObject("bianmuServer", bianmuSetting.getSysAddress()); mov.addObject("bianmuServer", bianmuSetting.getSysAddress());
mov.addObject("theadConfig", theadConfigService.listByCreateUser(auth.getName()));
return mov; return mov;
} }

@ -10,6 +10,7 @@ import com.keyware.shandan.bianmu.entity.MetadataBasicVo;
import com.keyware.shandan.bianmu.service.MetadataService; import com.keyware.shandan.bianmu.service.MetadataService;
import com.keyware.shandan.browser.entity.PageVo; import com.keyware.shandan.browser.entity.PageVo;
import com.keyware.shandan.browser.entity.SearchConditionVo; import com.keyware.shandan.browser.entity.SearchConditionVo;
import com.keyware.shandan.browser.entity.SearchResultSort;
import com.keyware.shandan.browser.service.*; import com.keyware.shandan.browser.service.*;
import com.keyware.shandan.common.entity.Result; import com.keyware.shandan.common.entity.Result;
import com.keyware.shandan.common.util.FileDownload; import com.keyware.shandan.common.util.FileDownload;
@ -138,10 +139,10 @@ public class SearchController {
*/ */
@AppLog(operate = "文件全文检索查询") @AppLog(operate = "文件全文检索查询")
@GetMapping("/full/file") @GetMapping("/full/file")
public Result<Object> searchFile(PageVo page, String search, String metaId) { public Result<Object> searchFile(PageVo page, String search, String metaId, SearchResultSort sort) {
try { try {
return Result.of(fileSearchService.searchFile(page, search, metaId)); return Result.of(fileSearchService.searchFile(page, search, metaId, sort));
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
return Result.of(null, false, "Elasticsearch 请求异常"); return Result.of(null, false, "Elasticsearch 请求异常");

@ -10,7 +10,6 @@ import org.elasticsearch.search.sort.SortOrder;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -35,7 +34,7 @@ public class SearchConditionVo extends PageVo implements Serializable {
//搜索条件集合 //搜索条件集合
private List<Item> conditions = new ArrayList<>(); private List<Item> conditions = new ArrayList<>();
// 排序 // 排序
private Sort sort = new Sort(); private SearchResultSort sort = new SearchResultSort();
//排序字段 //排序字段
@Deprecated @Deprecated
private String sortFiled; private String sortFiled;
@ -113,35 +112,4 @@ public class SearchConditionVo extends PageVo implements Serializable {
return " " + logicJoin + " \"" + table + "\".\"" + fieldName + "\" " + logicJudgement + " " + fieldValue; return " " + logicJoin + " \"" + table + "\".\"" + fieldName + "\" " + logicJudgement + " " + fieldValue;
} }
} }
/**
* 排序
*/
@Getter
@Setter
public static class Sort {
//排序字段
private String field;
//排序方式
private String sort;
public String getField() {
return " " + field;
}
public String getSort() {
return " " + sort;
}
/**
* @return order by sql语句
*/
public String getOrderBy() {
return isEmpty() ? Strings.EMPTY : " order by" + getField() + " " + getSort();
}
public boolean isEmpty() {
return StringUtils.isBlankAny(this.field, this.sort);
}
}
} }

@ -0,0 +1,34 @@
package com.keyware.shandan.browser.entity;
import com.keyware.shandan.common.util.StringUtils;
import joptsimple.internal.Strings;
import lombok.Getter;
import lombok.Setter;
/**
* 排序
*
* @author GuoXin
* @date 2023/8/29
*/
@Getter
@Setter
public class SearchResultSort {
//排序字段
private String field;
//排序方式
private String sort;
/**
* @return order by sql语句
*/
public String getOrderBy() {
return isEmpty() ? Strings.EMPTY : " order by " + getField() + " " + getSort();
}
public boolean isEmpty() {
return StringUtils.isBlankAny(this.field, this.sort);
}
}

@ -21,14 +21,12 @@ import com.keyware.shandan.system.service.SysFileService;
import com.keyware.shandan.system.utils.SysSettingUtil; import com.keyware.shandan.system.utils.SysSettingUtil;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors;
public class ExportComponent { public class ExportComponent {
private final String exportId; private final String exportId;
@ -107,9 +105,8 @@ public class ExportComponent {
JSONObject col = (JSONObject) json; JSONObject col = (JSONObject) json;
String comment = col.getString("comment"); String comment = col.getString("comment");
String colName = col.getString("columnName"); String colName = col.getString("columnName");
String name = StringUtils.hasTextByDefault(comment, colName);
colNameList.add(colName); colNameList.add(colName);
return name; return colName + (StringUtils.hasText(comment) ? "[" + comment + "]" : "");
}).toList(); }).toList();
// 添加第一行 // 添加第一行
@ -118,7 +115,13 @@ public class ExportComponent {
// 遍历数据 // 遍历数据
datas.forEach(data -> { datas.forEach(data -> {
// 遍历字段列名,获取对应数据并拼接成列的集合 // 遍历字段列名,获取对应数据并拼接成列的集合
List<String> cells = StreamUtil.as(colNameList).map(col -> data.get(col).toString()).toList(); List<String> cells = colNameList.stream().map(col -> {
Object value = data.get(col);
if (value == null) {
return "";
}
return String.valueOf(value);
}).collect(Collectors.toList());
rowList.add(cells); rowList.add(cells);
}); });
@ -189,7 +192,7 @@ public class ExportComponent {
private void delete(String path) { private void delete(String path) {
File file = new File(path); File file = new File(path);
if(file.exists()){ if (file.exists()) {
file.delete(); file.delete();
} }
} }

@ -1,12 +1,16 @@
package com.keyware.shandan.browser.service; package com.keyware.shandan.browser.service;
import cn.hutool.core.util.ReflectUtil;
import com.keyware.shandan.bianmu.entity.DirectoryVo; import com.keyware.shandan.bianmu.entity.DirectoryVo;
import com.keyware.shandan.bianmu.enums.ReviewStatus; import com.keyware.shandan.bianmu.enums.ReviewStatus;
import com.keyware.shandan.bianmu.service.DirectoryService; import com.keyware.shandan.bianmu.service.DirectoryService;
import com.keyware.shandan.browser.entity.PageVo; import com.keyware.shandan.browser.entity.PageVo;
import com.keyware.shandan.browser.entity.SearchResultSort;
import com.keyware.shandan.common.constants.DirConstant; import com.keyware.shandan.common.constants.DirConstant;
import com.keyware.shandan.common.util.StreamUtil; import com.keyware.shandan.common.util.StreamUtil;
import com.keyware.shandan.common.util.StringUtils; import com.keyware.shandan.common.util.StringUtils;
import com.keyware.shandan.system.entity.SysFile;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RequestOptions;
@ -17,10 +21,15 @@ import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder; import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.annotations.FieldType;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.io.IOException; import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -30,6 +39,7 @@ import java.util.List;
* @author Administrator * @author Administrator
* @since 2021/12/21 * @since 2021/12/21
*/ */
@Slf4j
@Service @Service
public class FileSearchService { public class FileSearchService {
@ -38,13 +48,13 @@ public class FileSearchService {
@Autowired @Autowired
private DirectoryService directoryService; private DirectoryService directoryService;
public PageVo searchFile(PageVo page, String text, String metaId) throws IOException { public PageVo searchFile(PageVo page, String text, String metaId, SearchResultSort sort) throws IOException {
SearchRequest request = Requests.searchRequest("shandan"); SearchRequest request = Requests.searchRequest("shandan");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.from(page.getPage() * page.getSize() - page.getSize()).size(page.getSize()); searchSourceBuilder.from(page.getPage() * page.getSize() - page.getSize()).size(page.getSize());
BoolQueryBuilder builder = QueryBuilders.boolQuery(); BoolQueryBuilder builder = QueryBuilders.boolQuery();
if(!DirConstant.DIR_ROOT_ID.equals(metaId)){ if (!DirConstant.DIR_ROOT_ID.equals(metaId)) {
List<String> ids = new ArrayList<>(); List<String> ids = new ArrayList<>();
ids.add(metaId); ids.add(metaId);
ids.addAll(getChildrenByDirId(metaId)); ids.addAll(getChildrenByDirId(metaId));
@ -75,13 +85,38 @@ public class FileSearchService {
highlightBuilder.preTags("<label style=\"color:red\">").postTags("</label>").field("*"); highlightBuilder.preTags("<label style=\"color:red\">").postTags("</label>").field("*");
highlightBuilder.forceSource(true); highlightBuilder.forceSource(true);
searchSourceBuilder.query(builder).highlighter(highlightBuilder); searchSourceBuilder.query(builder).highlighter(highlightBuilder);
// 设置排序
if (!sort.isEmpty()) {
String sortField = sort.getField();
// 使用反射获取文件实体类中字段上的注解设置的字段类型
Field field = ReflectUtil.getField(SysFile.class, sortField);
if (field != null) {
org.springframework.data.elasticsearch.annotations.Field fieldAnno = field.getAnnotation(org.springframework.data.elasticsearch.annotations.Field.class);
if(fieldAnno.type() != FieldType.Text
&& fieldAnno.type() != FieldType.Object
&& fieldAnno.type() != FieldType.Auto
&& fieldAnno.type() != FieldType.Nested
&& fieldAnno.type() != FieldType.Ip
&& fieldAnno.type() != FieldType.Attachment){
if(fieldAnno.type() == FieldType.Keyword){
sortField = sortField.concat(".keyword");
}
searchSourceBuilder.sort(sortField, SortOrder.fromString(sort.getSort()));
}else {
log.error("不支持的排序类型:{}:{}", sortField, fieldAnno.type());
}
}
}
request.source(searchSourceBuilder); request.source(searchSourceBuilder);
// 设置排序
SearchResponse response = esClient.search(request, RequestOptions.DEFAULT); SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
return PageVo.ofSearchHits(response.getHits(), page); return PageVo.ofSearchHits(response.getHits(), page);
} }
private List<String> getChildrenByDirId(String dirId){ private List<String> getChildrenByDirId(String dirId) {
DirectoryVo dir = directoryService.getById(dirId); DirectoryVo dir = directoryService.getById(dirId);
return StreamUtil.as(directoryService.childrenLists(dir, ReviewStatus.SUBMITTED)).map(DirectoryVo::getId).toList(); return StreamUtil.as(directoryService.childrenLists(dir, ReviewStatus.SUBMITTED)).map(DirectoryVo::getId).toList();
} }

@ -1,5 +1,7 @@
package com.keyware.shandan.browser.service; package com.keyware.shandan.browser.service;
import cn.hutool.core.util.ReflectUtil;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.keyware.shandan.bianmu.entity.DirectoryResource; import com.keyware.shandan.bianmu.entity.DirectoryResource;
@ -10,14 +12,17 @@ import com.keyware.shandan.bianmu.mapper.DirectoryResourceMapper;
import com.keyware.shandan.bianmu.service.DirectoryService; import com.keyware.shandan.bianmu.service.DirectoryService;
import com.keyware.shandan.browser.entity.PageVo; import com.keyware.shandan.browser.entity.PageVo;
import com.keyware.shandan.browser.entity.SearchConditionVo; import com.keyware.shandan.browser.entity.SearchConditionVo;
import com.keyware.shandan.browser.entity.SearchResultSort;
import com.keyware.shandan.common.util.StreamUtil; import com.keyware.shandan.common.util.StreamUtil;
import com.keyware.shandan.common.util.StringUtils; import com.keyware.shandan.common.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import java.lang.reflect.Field;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
/** /**
* @author Administrator * @author Administrator
@ -81,22 +86,33 @@ public class MetadataSearchService {
} }
break; break;
case "markTag": case "markTag":
String tagText = item.getFieldValue(); String tagIds = item.getFieldValue();
List<String> tags = Arrays.asList(tagText.split(",")); List<String> ids = Arrays.asList(tagIds.split(","));
StringBuilder existsSql = new StringBuilder("select 1 from MARK_RECORD MR where MR.ENTITY_ID = V_DIRECTORY_RESOURCE.ID and ( 1 = 1 "); if (ids.size() > 0) {
tags.forEach(tagItem -> { StringBuilder existsSql = new StringBuilder("select 1 from (select ENTITY_ID, WM_CONCAT(LABEL_ID) LABEL_IDS from B_DATA_LABEL_ENTITY DLN where DLN.ENTITY_ID = V_DIRECTORY_RESOURCE.ID group by ENTITY_ID) tmp1");
if (StringUtils.hasText(tagItem)) { List<String> andSqlList = ids.stream().map(id -> "tmp1.LABEL_IDS like '%" + id + "%'").collect(Collectors.toList());
String[] arr = tagItem.split("-"); existsSql.append(" where ").append(String.join(" and ", andSqlList));
existsSql.append(" and MR.MARK_VALUE like '%").append(arr[1]).append("%' "); wrapper.exists(existsSql.toString());
} }
});
existsSql.append(")");
wrapper.exists(existsSql.toString());
break; break;
default: default:
} }
}); });
}); });
// 排序设置
SearchResultSort sort = condition.getSort();
if(sort != null && sort.getSort() != null ){
// 通过反射获取资源类字段注解中的数据库表相关的列名
Field field = ReflectUtil.getField(DirectoryResource.class, sort.getField().trim());
if(field != null){
TableField tableField = field.getAnnotation(TableField.class);
if(tableField != null && StringUtils.hasText(tableField.value())){
queryWrapper.orderBy(true, sort.getSort().equalsIgnoreCase("asc"), tableField.value());
}
}
}
return queryWrapper; return queryWrapper;
} }

@ -50,4 +50,5 @@ project:
logging: logging:
level: level:
root: debug com.keyware: debug

@ -8,15 +8,16 @@
*/ */
// 目录树数据缓存 // 目录树数据缓存
const dirCache = new Map(); const dirCache = new Map();
layui.use(['layer', 'listPage', 'globalTree', 'gtable', 'form', 'element', 'dropdown', 'laydate', 'dict'], function () { layui.use(['layer', 'listPage', 'globalTree', 'gtable', 'form', 'element', 'dropdown', 'laydate', 'dict', 'datalabel'], function () {
const listPage = layui.listPage, const listPage = layui.listPage,
form = layui.form, form = layui.form,
element = layui.element, element = layui.element,
laydate = layui.laydate, laydate = layui.laydate,
globalTree = layui.globalTree; globalTree = layui.globalTree,
DataLabel = layui.datalabel;
let metaListTable, dirFileTable, tagSelector, tags = [], unchecked_tags = [], conditions = [];
let metaListTable, dirFileTable, tagSelector, tags = [], conditions = [];
const unchecked_tags = new Set();
// 初始化 // 初始化
initDirectoryTree(); initDirectoryTree();
@ -105,7 +106,7 @@ layui.use(['layer', 'listPage', 'globalTree', 'gtable', 'form', 'element', 'drop
* @param basicData * @param basicData
*/ */
function setCurrentPosition(basicData) { function setCurrentPosition(basicData) {
let directoryPath = basicData.directoryPath.replaceAll('/', ' / '); let directoryPath = basicData.directoryPath.replaceAll('/', ' / ');
$('.current-position label').text(directoryPath); $('.current-position label').text(directoryPath);
} }
@ -133,26 +134,27 @@ layui.use(['layer', 'listPage', 'globalTree', 'gtable', 'form', 'element', 'drop
url: `${ctx}/search/metadata/all/page/${id}`, url: `${ctx}/search/metadata/all/page/${id}`,
height: 'full-110', height: 'full-110',
method: 'post', method: 'post',
defaultToolbar: [{ autoSort: false,
title: '导出' //标题 defaultToolbar: [
, layEvent: 'export' //事件名,用于 toolbar 事件中使用 {title: '导出', layEvent: 'export', icon: 'layui-icon-export'},
, icon: 'layui-icon-export' //图标类名 {title: '列表配置', layEvent: 'theadSet', icon: 'layui-icon-cols'}
}], ],
request: {pageName: 'page', limitName: 'size'}, request: {pageName: 'page', limitName: 'size'},
limit: 30, limit: 30,
cols: [[ cols: [[
{field: 'id', title: 'ID', hide: true}, {field: 'id', title: 'ID', hide: true},
{field: 'resourceName', title: '数据名称', width: 300}, {field: 'resourceName', title: '数据名称', width: 300, sort: true},
{field: 'resourceComment', title: '中文注释/描述'}, {field: 'resourceComment', title: '中文注释/描述', sort: true},
{field: 'directoryPath', title: '资源路径'}, {field: 'directoryPath', title: '资源路径', sort: true},
{field: 'themeTask', title: '主题任务', hide: true}, {field: 'themeTask', title: '主题任务', hide: true, sort: true},
{ {
field: 'dataSource', field: 'dataSource',
title: '数据来源', title: '数据来源',
width: 160, width: 160,
templet: (data) => DICT.getText("data_source", data.dataSource) || data.dataSource || '' templet: (data) => DICT.getText("data_source", data.dataSource) || data.dataSource || '',
sort: true
}, },
{field: 'taskTime', title: '任务时间', width: 180, align: 'center'}, {field: 'taskTime', title: '任务时间', width: 180, align: 'center', sort: true},
{field: 'modifyTime', title: '注册时间', width: 160, align: 'center', hide: true}, {field: 'modifyTime', title: '注册时间', width: 160, align: 'center', hide: true},
{fixed: 'right', title: '操作', toolbar: '#rowToolBar', width: 100, align: 'center'} {fixed: 'right', title: '操作', toolbar: '#rowToolBar', width: 100, align: 'center'}
]], ]],
@ -171,6 +173,15 @@ layui.use(['layer', 'listPage', 'globalTree', 'gtable', 'form', 'element', 'drop
} }
}, },
}); });
metaListTable.gtable.on('sort', function (data) {
const {field, type} = data;
let sort = type;
if (!sort || sort === 'null') {
sort = undefined;
}
metaListTable.where.sort = {field: field.trim(), sort: sort}
beginSearch();
})
metaListTable.addTableRowEvent('export', function (obj) { metaListTable.addTableRowEvent('export', function (obj) {
if (id === DIR_ROOT_ID) { if (id === DIR_ROOT_ID) {
showErrorMsg('不允许导出根目录数据'); showErrorMsg('不允许导出根目录数据');
@ -206,6 +217,8 @@ layui.use(['layer', 'listPage', 'globalTree', 'gtable', 'form', 'element', 'drop
openMaxLayerWithURL(`${ctx}/search/meta/${obj.id}`) openMaxLayerWithURL(`${ctx}/search/meta/${obj.id}`)
} }
}) })
new THeadSetLayer(metaListTable, layui);
} }
function initFileSearchTable(id) { function initFileSearchTable(id) {
@ -218,32 +231,42 @@ layui.use(['layer', 'listPage', 'globalTree', 'gtable', 'form', 'element', 'drop
url: `${ctx}/search/full/file?metaId=${id}`, url: `${ctx}/search/full/file?metaId=${id}`,
height: 'full-110', height: 'full-110',
request: {pageName: 'page', limitName: 'size'}, request: {pageName: 'page', limitName: 'size'},
defaultToolbar: [
{title: '列表配置', layEvent: 'theadSet', icon: 'layui-icon-cols'}
],
autoSort: false,
limit: 30, limit: 30,
method: 'get', method: 'get',
cols: [[ cols: [[
{field: 'id', title: 'ID', hide: true}, {field: 'id', title: 'ID', hide: true},
{field: 'fileName', title: '文件名称', minWidth: 300, fixed: 'left'}, {field: 'fileName', title: '文件名称', minWidth: 300, fixed: 'left'},
{ {
field: 'source',
title: '文件来源', title: '文件来源',
minWidth: 160, minWidth: 160,
sort: true,
templet: data => DICT.getText('data_source', data.source) || data.source || '' templet: data => DICT.getText('data_source', data.source) || data.source || ''
}, },
{field: 'taskCode', title: '任务代号', minWidth: 160}, {field: 'taskCode', title: '任务代号', sort: true, minWidth: 160},
{ {
field: 'taskNature',
title: '任务性质', title: '任务性质',
minWidth: 160, minWidth: 160,
sort: true,
templet: data => DICT.getText('task_nature', data.taskNature) || data.taskNature || '' templet: data => DICT.getText('task_nature', data.taskNature) || data.taskNature || ''
}, },
{field: 'troopCode', title: '部队代号', minWidth: 160}, {field: 'troopCode', title: '部队代号', sort: true, minWidth: 160},
{field: 'missileNumber', title: '导弹编号', minWidth: 160}, {field: 'missileNumber', title: '导弹编号', sort: true, minWidth: 160},
{field: 'equipmentModel', title: '装备型号', minWidth: 160}, {field: 'equipmentModel', title: '装备型号', sort: true, minWidth: 160},
{ {
field: 'targetNumber',
title: '目标/靶标类型', title: '目标/靶标类型',
minWidth: 160, minWidth: 160,
sort: true,
templet: data => DICT.getText('target_type', data.targetNumber) || data.targetNumber || '' templet: data => DICT.getText('target_type', data.targetNumber) || data.targetNumber || ''
}, },
{field: 'entryStaff', title: '录入人员', minWidth: 160}, {field: 'entryStaff', title: '录入人员', sort: true, minWidth: 160},
{field: 'inputDate', title: '收文时间', width: 160, align: 'center'}, {field: 'inputDate', title: '收文时间', sort: true, width: 160, align: 'center'},
{field: 'remark', title: '文件描述', width: 300}, {field: 'remark', title: '文件描述', width: 300},
{field: 'text', title: '文件内容', width: 300}, {field: 'text', title: '文件内容', width: 300},
{fixed: 'right', title: '操作', toolbar: '#fileRowToolBar', width: 100, align: 'center'} {fixed: 'right', title: '操作', toolbar: '#fileRowToolBar', width: 100, align: 'center'}
@ -251,10 +274,23 @@ layui.use(['layer', 'listPage', 'globalTree', 'gtable', 'form', 'element', 'drop
}, },
}); });
dirFileTable.gtable.on('sort', function (data) {
const {field, type} = data;
let sort = type;
if (!sort || sort === 'null') {
sort = undefined;
}
dirFileTable.table.where.field = field.trim();
dirFileTable.table.where.sort = sort;
dirFileTable.reloadTable({table: dirFileTable.table})
})
// 查看按钮监听 // 查看按钮监听
dirFileTable.addTableRowEvent('details-file', function (obj) { dirFileTable.addTableRowEvent('details-file', function (obj) {
openMaxLayerWithURL(`${ctx}/sys/file/view?fileId=${obj.id}`) openMaxLayerWithURL(`${ctx}/sys/file/view?fileId=${obj.id}`)
}) })
new THeadSetLayer(dirFileTable, layui);
} }
/** /**
@ -273,15 +309,13 @@ layui.use(['layer', 'listPage', 'globalTree', 'gtable', 'form', 'element', 'drop
$('#condition-div').slideToggle(100, 'linear', conditionSlideToggle) $('#condition-div').slideToggle(100, 'linear', conditionSlideToggle)
}); });
if (!tagSelector) {
tagSelector = new MarkerSelector('#mark-selector-input');
}
tagSelector.bindBtnEvent()
tagSelector.onOkBtn(data => {
tags = data
setMarkTagInputValue();
});
$('#mark-selector-input').on('click', function () {
DataLabel.openChooseDialog(null, null, null, true).then((labels) => {
tags = labels || [];
setMarkTagInputValue();
})
})
// 监听标签点击事件 // 监听标签点击事件
element.on('tab(condition-tab)', function (data) { element.on('tab(condition-tab)', function (data) {
// 点击后移除选中样式 // 点击后移除选中样式
@ -296,6 +330,9 @@ layui.use(['layer', 'listPage', 'globalTree', 'gtable', 'form', 'element', 'drop
// 监听条件标签删除事件 // 监听条件标签删除事件
element.on('tabDelete(condition-tab)', function (data) { element.on('tabDelete(condition-tab)', function (data) {
let key = $(this).parent().data('key'); let key = $(this).parent().data('key');
if (key === 'markTag') {
tags = [];
}
let formVal = form.val('search-form'); let formVal = form.val('search-form');
formVal[key] = ''; formVal[key] = '';
form.val('search-form', formVal); form.val('search-form', formVal);
@ -310,7 +347,7 @@ layui.use(['layer', 'listPage', 'globalTree', 'gtable', 'form', 'element', 'drop
$('#condition-clear-btn').on('click', function () { $('#condition-clear-btn').on('click', function () {
$('#searchKeyInput').val(''); $('#searchKeyInput').val('');
tags = []; tags = [];
unchecked_tags = []; unchecked_tags.clear();
conditions = []; conditions = [];
beginSearch(); beginSearch();
}); });
@ -342,9 +379,7 @@ layui.use(['layer', 'listPage', 'globalTree', 'gtable', 'form', 'element', 'drop
function setMarkTagInputValue() { function setMarkTagInputValue() {
let temp = []; let temp = [];
for (let tag of tags) { for (let tag of tags) {
let arr = tag.split('-'); temp.push(tag.title);
let text = tag.replace(arr[0] + '-' + arr[1] + '-', '');
temp.push(text);
} }
$('#mark-selector-input').val(temp.join(', ')); $('#mark-selector-input').val(temp.join(', '));
} }
@ -370,7 +405,7 @@ layui.use(['layer', 'listPage', 'globalTree', 'gtable', 'form', 'element', 'drop
let htm = ''; let htm = '';
conditions = []; conditions = [];
for (let key in formVal) { for (let key in formVal) {
if (key == 'searchKeyInput') continue; if (key === 'searchKeyInput') continue;
let fieldName = key, fieldValue = formVal[key], logicJudgement; let fieldName = key, fieldValue = formVal[key], logicJudgement;
// 如果fieldName是条件下拉框,则跳过 // 如果fieldName是条件下拉框,则跳过
if (fieldName.startsWith('logic-') || fieldName === 'directoryId' || fieldName === 'metadataId') continue; if (fieldName.startsWith('logic-') || fieldName === 'directoryId' || fieldName === 'metadataId') continue;
@ -397,11 +432,11 @@ layui.use(['layer', 'listPage', 'globalTree', 'gtable', 'form', 'element', 'drop
condition = '包含'; condition = '包含';
} }
if (fieldName == 'secretLevel') { if (fieldName === 'secretLevel') {
hasText = $(`select[name="secretLevel"] option[value="${fieldValue}"]`).text(); hasText = $(`select[name="secretLevel"] option[value="${fieldValue}"]`).text();
} else if (fieldName == 'dataFrom') { } else if (fieldName === 'dataFrom') {
hasText = $(`select[name="dataFrom"] option[value="${fieldValue}"]`).text(); hasText = $(`select[name="dataFrom"] option[value="${fieldValue}"]`).text();
} else if (fieldName == 'dataType') { } else if (fieldName === 'dataType') {
hasText = $(`select[name="dataType"] option[value="${fieldValue}"]`).text(); hasText = $(`select[name="dataType"] option[value="${fieldValue}"]`).text();
} }
conditions.push({fieldName, fieldValue, logicJudgement}) conditions.push({fieldName, fieldValue, logicJudgement})
@ -409,40 +444,29 @@ layui.use(['layer', 'listPage', 'globalTree', 'gtable', 'form', 'element', 'drop
} }
} }
let temp = []; let tag_htm = '';
for (let tag of tags) { for (let tag of tags) {
let tag_arr = tag.split('-'); let checked = 'checked';
let tag_type = tag_arr[1], tag_text = tag_arr[2], temp_tags = temp[tag_type]; if (unchecked_tags.has(tag.id + '')) {
if (!temp_tags) { checked = '';
temp_tags = []
} }
temp_tags.push({id: tag_arr[0], text: tag_text}); tag_htm += `<input type="checkbox" title="${tag.title}" value="${tag.id}" ${checked} lay-skin="primary">`;
temp[tag_type] = temp_tags;
} }
if (tag_htm) {
for (let type in temp) { htm += `<li data-key="markTag">置标标签:${tag_htm}</li>`;
let tag_type = type, tag_items = temp[type], tag_htm = '';
for (let item of tag_items) {
let val = item.id + '-' + item.text, checked = 'checked';
if (unchecked_tags.includes(val)) {
checked = '';
}
tag_htm += `<input type="checkbox" title="${item.text}" value="${val}" ${checked} lay-skin="primary">`;
}
htm += `<li data-key="markTag">${tag_type}${tag_htm}</li>`;
} }
$('#condition-tab ul').html(htm); $('#condition-tab ul').html(htm);
element.render('tab'); element.render('tab');
$('#condition-tab ul li[data-key="markTag"] i').remove(); $('#condition-tab ul li[data-key="markTag"] i').css({'margin-left': '-10px'});
form.render('checkbox'); form.render('checkbox');
$('li[data-key="markTag"] .layui-form-checkbox').on('click', function () { $('li[data-key="markTag"] .layui-form-checkbox').on('click', function () {
let val = $(this).prev().val(), index = unchecked_tags.indexOf(val); let val = $(this).prev().val();
if (!$(this).hasClass('layui-form-checked')) { if (unchecked_tags.has(val)) {
unchecked_tags.push(val); unchecked_tags.delete(val);
} else if (index > -1) { } else {
unchecked_tags.splice(index, 1) unchecked_tags.add(val);
} }
beginSearch(); beginSearch();
}) })
@ -453,7 +477,6 @@ layui.use(['layer', 'listPage', 'globalTree', 'gtable', 'form', 'element', 'drop
} }
} }
function beginSearch() { function beginSearch() {
setMarkTagsValue() setMarkTagsValue()
metaListTable.where.conditions = conditions; metaListTable.where.conditions = conditions;
@ -491,4 +514,98 @@ layui.use(['layer', 'listPage', 'globalTree', 'gtable', 'form', 'element', 'drop
closeBtn: 1 closeBtn: 1
}); });
} }
}) })
/**
* 表格表头配置组件
*/
class THeadSetLayer {
constructor(pageTable, lay) {
this.layer = lay.layer;
this.form = lay.form;
this.gtable = lay.gtable;
this.pageTable = pageTable;
this.id = pageTable.id + 'Set';
this.pageTable.addTableRowEvent('theadSet', () => this.show())
}
show() {
const {layer, pageTable, id} = this;
layer.open({
id: id + 'Layer',
title: '数据列表配置',
type: 1,
area: ['1000px', '700px'],
shadeClose: true,
maxmin: false,
anim: 0,
content: `<table id="${id}" lay-filter="${id}"></table>`,
btn: ['保存', '取消'],
success: () => {
this._renderInnerTable();
},
yes: (layerIndex) => {
this._saveTheadSet().then(() => {
pageTable.reloadTable();
layer.close(layerIndex);
})
}
});
}
_renderInnerTable() {
const {gtable, form, id} = this;
gtable.init({
id,
data: [...sourceTableConfigMap.values()],
method: 'get',
toolbar: false,
height: 'full-310',
page: false,
cols: [[
{field: 'id', hide: true},
{field: 'colName', title: '列名'},
{field: 'colTitle', title: '列标题', edit: 'text'},
{field: 'colSort', title: '列顺序', edit: 'text'},
{field: 'colWidth', title: '列宽度', edit: 'text'},
{
field: 'isSort',
title: '是否允许排序',
templet: (data) => renderSwitch('isSort', data)
},
{
field: 'isShow',
title: '是否显示',
templet: (data) => renderSwitch('isShow', data)
}
]],
});
gtable.on(`edit(${id})`, ({field, value, data}) => {
sourceTableConfigMap.get(data.id)[field] = value;
})
// 监听switch按钮
form.on(`switch(${id}-switch)`, ({elem}) => {
const id = $(elem).attr('id'), name = $(elem).attr('name');
const value = sourceTableConfigMap.get(id)[name];
sourceTableConfigMap.get(id)[name] = !value;
});
function renderSwitch(colName, data) {
const dataId = data.id, value = data[colName];
return `<input type="checkbox" id="${dataId}" name="${colName}" value="${value}" title="是|否" lay-skin="switch" lay-filter="${id}-switch" ${value ? 'checked' : ''} />`
}
}
_saveTheadSet() {
return new Promise(resolve => {
Util.post(`/sys/thead/config/api/save`, {params: JSON.stringify([...sourceTableConfigMap.values()])}).then(res=>{
if(res.flag){
showOkMsg('保存成功')
}else{
showErrorMsg2('保存失败:'+res.msg)
}
})
resolve();
})
}
}

@ -36,6 +36,7 @@ layui.use(['dropdown', 'gtable', 'laydate', 'form'], function () {
cols: [cols], cols: [cols],
limit: 20, limit: 20,
toolbar: '#table-title', toolbar: '#table-title',
request:{pageName: 'page', limitName: 'size'},
defaultToolbar: ['filter', 'print', 'exports', { defaultToolbar: ['filter', 'print', 'exports', {
title: '统计报表', title: '统计报表',
layEvent: 'tong-ji', layEvent: 'tong-ji',
@ -194,7 +195,7 @@ layui.use(['dropdown', 'gtable', 'laydate', 'form'], function () {
let id = $(this).data('id'); let id = $(this).data('id');
$condition_list.find(`li[id="li_${id}"]`).remove(); $condition_list.find(`li[id="li_${id}"]`).remove();
$condition_list.find(`li:first a[name="${LOGIC_JOIN}"]`).addClass("layui-hide").data('value', 'and'); $condition_list.find(`li:first a[name="${LOGIC_JOIN}"]`).addClass("layui-hide").data('value', 'and');
if ($condition_list.find('li').length == 0) { if ($condition_list.find('li').length === 0) {
$condition_list.find('p.condition-none').removeClass('layui-hide'); $condition_list.find('p.condition-none').removeClass('layui-hide');
} }
}); });

@ -63,7 +63,7 @@ ReportComponent.prototype.openEchartsConfigLayer = function () {
$('#echartsConfigForm').parent().css('overflow', 'visible') $('#echartsConfigForm').parent().css('overflow', 'visible')
}, },
yes: function (index) { yes: function (index) {
_this.requestData(()=> layer.close(index)); _this.requestData(() => layer.close(index));
} }
}); });
} }
@ -203,12 +203,15 @@ ReportComponent.prototype.validate = function (formVal) {
if (!formVal.aggregationType) { if (!formVal.aggregationType) {
showErrorMsg('请设置聚合方式'); showErrorMsg('请设置聚合方式');
return; return;
} else {
if ((formVal.aggregationType == 'sum' || formVal.aggregationType == 'avg') && !formVal.fieldY) {
showErrorMsg('请设置聚合字段');
return;
}
} }
if ((formVal.aggregationType == 'sum' || formVal.aggregationType == 'avg') && !formVal.fieldY) {
showErrorMsg('请设置聚合字段');
return;
}
if(formVal.aggregationType == 'count' && !formVal.fieldY){
formVal.fieldY = formVal.fieldX;
}
return true; return true;
} }

@ -11,6 +11,18 @@
<link rel="stylesheet" th:href="@{/css/browser.css}"/> <link rel="stylesheet" th:href="@{/css/browser.css}"/>
<script th:inline="javascript"> <script th:inline="javascript">
const bus_type = 0; const bus_type = 0;
const resourceTableId = 'browser_resource_table',
fileTableId = 'browser_file_table',
theadConfig = /*[[${theadConfig}]]*/ [];
const sourceTableConfigMap = new Map(), fileTableConfigMap = new Map();
theadConfig.forEach(item => {
if (item.tableId === resourceTableId) {
sourceTableConfigMap.set(item.id, item);
} else if (item.tableId === fileTableId) {
fileTableConfigMap.set(item.id, item);
}
});
</script> </script>
</head> </head>
<body onselectstart="return false"> <body onselectstart="return false">
@ -79,18 +91,23 @@
<div class="current-position">当前位置:<label></label></div> <div class="current-position">当前位置:<label></label></div>
<table class="layui-hide" id="dirMetadataTable" lay-filter="dirMetadataTable"></table> <table class="layui-hide" id="dirMetadataTable" lay-filter="dirMetadataTable"></table>
<script type="text/html" id="tableToolBar"> <script type="text/html" id="tableToolBar">
<div class="layui-form" lay-filter="search-form" style="display: flex;flex-direction: column;"> <div class="layui-form" lay-filter="search-form"
<div class="layui-btn-container" style="display: flex; justify-content: flex-start; margin-bottom: 0"> style="display: flex;flex-direction: column;">
<div class="layui-btn-container"
style="display: flex; justify-content: flex-start; margin-bottom: 0">
<div style="position: unset;"> <div style="position: unset;">
<input type="text" id="searchKeyInput" name="searchKeyInput" <input type="text" id="searchKeyInput" name="searchKeyInput"
autocomplete="off" autocomplete="off"
placeholder="请输入关键字查询" class="layui-input layui-btn-sm"> placeholder="请输入关键字查询" class="layui-input layui-btn-sm">
<button class="layui-btn layui-btn-sm" id="begin-search-btn" lay-event="query">查询</button> <button class="layui-btn layui-btn-sm" id="begin-search-btn"
lay-event="query">查询
</button>
</div> </div>
<div style="position: unset;"> <div style="position: unset;">
<button class="layui-btn layui-btn-primary layui-border-green" <button class="layui-btn layui-btn-primary layui-border-green"
style="border: 0" style="border: 0"
id="condition-btn">更多条件<i class="layui-icon layui-icon-down"></i> id="condition-btn">更多条件<i
class="layui-icon layui-icon-down"></i>
</button> </button>
<button class="layui-btn layui-btn-primary layui-border-green" <button class="layui-btn layui-btn-primary layui-border-green"
style="border: 0;padding:0;margin:0" style="border: 0;padding:0;margin:0"
@ -106,7 +123,8 @@
<div class="layui-input-inline"> <div class="layui-input-inline">
<input type="text" id="input-date-begin" name="inputDate" <input type="text" id="input-date-begin" name="inputDate"
autocomplete="off" autocomplete="off"
class="layui-input input-date c-input" placeholder="选择日期范围"/> class="layui-input input-date c-input"
placeholder="选择日期范围"/>
</div> </div>
</div> </div>
<div class="layui-inline"> <div class="layui-inline">
@ -117,7 +135,8 @@
<option value="nq">不等于</option> <option value="nq">不等于</option>
<!--<option value="like">包含</option>--> <!--<option value="like">包含</option>-->
</select> </select>
<div dict-component="select" dict-type="data_source" dict-name="dataFrom" id="dict-data-form"></div> <div dict-component="select" dict-type="data_source"
dict-name="dataFrom" id="dict-data-form"></div>
</div> </div>
</div> </div>
<div class="layui-inline"> <div class="layui-inline">
@ -128,11 +147,13 @@
<option value="nq">不等于</option> <option value="nq">不等于</option>
<!--<option value="like">包含</option>--> <!--<option value="like">包含</option>-->
</select> </select>
<div dict-component="select" dict-type="data_type" dict-name="dataType" id="dict-data-type"></div> <div dict-component="select" dict-type="data_type"
dict-name="dataType" id="dict-data-type"></div>
</div> </div>
</div> </div>
<div class="layui-inline"> <div class="layui-inline">
<label class="layui-form-label" label-name="secretLevel">数据密级</label> <label class="layui-form-label"
label-name="secretLevel">数据密级</label>
<div class="layui-input-inline" <div class="layui-input-inline"
style="width: 80px;height: 38px; margin-right: -1px;"> style="width: 80px;height: 38px; margin-right: -1px;">
<select name="logic-secretLevel" lay-verify="select-condition"> <select name="logic-secretLevel" lay-verify="select-condition">
@ -142,14 +163,16 @@
<option value="lt">小于</option> <option value="lt">小于</option>
</select> </select>
</div> </div>
<div dict-component="select" dict-type="secret_level" dict-name="secretLevel" id="dict-secret-level"></div> <div dict-component="select" dict-type="secret_level"
dict-name="secretLevel" id="dict-secret-level"></div>
</div> </div>
<div class="layui-inline"> <div class="layui-inline">
<label class="layui-form-label" label-name="mark">置标标签</label> <label class="layui-form-label" label-name="mark">置标标签</label>
<div class="layui-input-inline mark-selector" style="width: 340px;"> <div class="layui-input-inline mark-selector" style="width: 340px;">
<div class="layui-unselect layui-form-select"> <div class="layui-unselect layui-form-select">
<div class="layui-select-title"> <div class="layui-select-title">
<input placeholder="请选择" id="mark-selector-input" readonly <input placeholder="请选择" id="mark-selector-input"
readonly
type="text" class="layui-input layui-unselect"> type="text" class="layui-input layui-unselect">
<i class="layui-edge"></i> <i class="layui-edge"></i>
</div> </div>
@ -157,13 +180,15 @@
</div> </div>
</div> </div>
</div> </div>
<div class="layui-form-item" style="justify-content: center; align-items: center"> <div class="layui-form-item"
style="justify-content: center; align-items: center">
<button class="layui-btn layui-border-green" <button class="layui-btn layui-border-green"
style="height: 20px;line-height: 16px; color: #FFFFFF !important;margin-right: 10px; padding: 0 10px" style="height: 20px;line-height: 16px; color: #FFFFFF !important;margin-right: 10px; padding: 0 10px"
onclick="$(`#condition-btn`).click()">确定 onclick="$(`#condition-btn`).click()">确定
</button> </button>
<button class="layui-btn layui-btn-primary layui-border-green" <button class="layui-btn layui-btn-primary layui-border-green"
style="border: 0;padding:0;margin:0;height: 16px;line-height: 16px;" id="condition-cancel-btn">取消 style="border: 0;padding:0;margin:0;height: 16px;line-height: 16px;"
id="condition-cancel-btn">取消
</button> </button>
</div> </div>
</div> </div>
@ -180,7 +205,8 @@
</div>--> </div>-->
</div> </div>
</div> </div>
<div id="mengban" style="width: 100%; display: none; height: 100%; position: fixed; top:0px; left: 0px; background: #0C0C0C47; z-index: 1"></div> <div id="mengban"
style="width: 100%; display: none; height: 100%; position: fixed; top:0px; left: 0px; background: #0C0C0C47; z-index: 1"></div>
</script> </script>
<script type="text/html" id="rowToolBar"> <script type="text/html" id="rowToolBar">
<div class="layui-btn-container"> <div class="layui-btn-container">
@ -204,7 +230,8 @@
</script> </script>
<script type="text/html" id="fileRowToolBar"> <script type="text/html" id="fileRowToolBar">
<div class="layui-btn-container"> <div class="layui-btn-container">
<button class="layui-btn layui-btn-xs remove-link" lay-event="details-file">查看</button> <button class="layui-btn layui-btn-xs remove-link" lay-event="details-file">查看
</button>
</div> </div>
</script> </script>
</div> </div>
@ -219,7 +246,6 @@
<!-- js --> <!-- js -->
<script th:replace="common/head::static-foot"></script> <script th:replace="common/head::static-foot"></script>
<script th:src="@{/js/business/mark/markTag.js}"></script> <script th:src="@{/js/business/mark/markTag.js}"></script>
<script th:src="@{/js/marker_selector.js}"></script>
<script th:src="@{/js/browser.js}"></script> <script th:src="@{/js/browser.js}"></script>
<script th:src="@{/js/view.js}"></script> <script th:src="@{/js/view.js}"></script>
<script type="text/javascript"> <script type="text/javascript">

@ -57,6 +57,10 @@ public class TreeVo implements Serializable {
* 选中状态 * 选中状态
*/ */
private String checked = "0"; private String checked = "0";
/**
* 加载顺序
*/
private int sort;
/** /**
* 节点原始数据 * 节点原始数据
*/ */

@ -5,6 +5,7 @@ import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
import java.text.Collator; import java.text.Collator;
import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -29,6 +30,7 @@ public class TreeUtil {
.filter(node -> (node.getParentId().equals(parentId))) .filter(node -> (node.getParentId().equals(parentId)))
// 给子节点设置子节点 // 给子节点设置子节点
.peek(child -> child.setChildren(buildDirTree(nodes, child.getId()))) .peek(child -> child.setChildren(buildDirTree(nodes, child.getId())))
.sorted(Comparator.comparingInt(TreeVo::getSort))
.toList(); .toList();
} }

@ -290,4 +290,22 @@ fieldset a, fieldset a:hover{
position: absolute; position: absolute;
top: 0; top: 0;
font-size: 20px; font-size: 20px;
}
.dynamic-form{
display: flex;
max-width: 100%;
flex-flow: wrap;
}
.dynamic-form .layui-form-item{
display: flex;
justify-content: center;
width: calc(50% - 20px);
margin-left: 10px;
}
.dynamic-form .layui-form-label{
width: 100px;
}
.dynamic-form .layui-input-block{
margin-left: 0;
flex: 1;
} }

@ -14,7 +14,7 @@ layui.define(['globalTree'], function (exports) {
labelId = newLabel.id; labelId = newLabel.id;
label = newLabel.titlePathWithSelf; label = newLabel.titlePathWithSelf;
} }
if(label && label !== '/'){ if (label && label !== '/') {
label = label.endsWith("/") ? label.substring(0, label.length - 1) : label; label = label.endsWith("/") ? label.substring(0, label.length - 1) : label;
let temp = { let temp = {
entityId, entityId,
@ -59,9 +59,9 @@ layui.define(['globalTree'], function (exports) {
} }
setData(data) { setData(data) {
if(data){ if (data) {
let path = data.label.replace(this.fixedTitlePath, ''); let path = data.label.replace(this.fixedTitlePath, '');
if(path !== '/'){ if (path !== '/') {
this.newLabel = {id: data.labelId, titlePathWithSelf: path} this.newLabel = {id: data.labelId, titlePathWithSelf: path}
} }
this.render(); this.render();
@ -118,8 +118,7 @@ layui.define(['globalTree'], function (exports) {
function addEventListen() { function addEventListen() {
$elem.find('.choose-data').on('click', function () { $elem.find('.choose-data').on('click', function () {
let labelId = $(this).data('labelId') || 0; let labelId = $(this).data('labelId') || 0;
labelId = labelId === 'undefined' ? 0 : labelId; chooseLabelData(labelId, labelIdPath).then(data => {
chooseLabelData(labelId, fixedTitlePath, labelIdPath).then(data => {
component.newLabel = data; component.newLabel = data;
renderLabelElement(component); renderLabelElement(component);
}); });
@ -136,7 +135,18 @@ layui.define(['globalTree'], function (exports) {
} }
} }
function chooseLabelData(labelId, titlePath, idPath) { /**
* 显示置标标签选择窗口
* @param labelId {String} 上级置标标签ID为空则查询所有
* @param idPath {String} 上级标签的id路径用于默认勾选和设置为不可选
* @param chooseIds {String | String[]} 默认选中的ID集合逗号拼接的数组或者字符数组
* @param multiple {Boolean} 多选
* @returns {Promise<Object>}
*/
function chooseLabelData(labelId, idPath, chooseIds, multiple) {
if (!labelId || labelId === 'undefined') {
labelId = 0;
}
return new Promise(resolve => { return new Promise(resolve => {
layer.open({ layer.open({
type: 1, type: 1,
@ -160,17 +170,27 @@ layui.define(['globalTree'], function (exports) {
all: true, all: true,
cache: true, cache: true,
checkbar: true, checkbar: true,
checkbarType: 'only', checkbarType: multiple ? 'no-all' : 'only',
scroll: '#label-tree', scroll: '#label-tree',
done: function () { done: function () {
let _chooseIds = [];
if (disableIds.length > 0) { if (disableIds.length > 0) {
treeObj.chooseDataInit(disableIds.join(',')); _chooseIds.concat(disableIds);
treeObj.setDisabledNodes(disableIds.join(',')); treeObj.setDisabledNodes(disableIds.join(','));
} }
if (chooseIds) {
_chooseIds.concat(Array.isArray(chooseIds) ? chooseIds : chooseIds.split(','));
}
treeObj.chooseDataInit(disableIds.join(','));
$('#layerCancel').on('click', () => layer.close(index)); $('#layerCancel').on('click', () => layer.close(index));
$('#layerOk').on('click', () => { $('#layerOk').on('click', () => {
if (treeObj.chooseNodes && treeObj.chooseNodes.length > 0) { const nodes = treeObj.chooseNodes;
resolve && resolve(treeObj.chooseNodes[0].basicData); if (nodes && nodes.length > 0) {
let return_data = nodes.map(node => node.basicData);
if (!multiple) {
resolve(return_data[0]);
}
resolve(return_data);
layer.close(index); layer.close(index);
} else { } else {
showErrorMsg('请选择一条数据') showErrorMsg('请选择一条数据')
@ -182,7 +202,21 @@ layui.define(['globalTree'], function (exports) {
if (disableIds.length > 0) { if (disableIds.length > 0) {
treeObj.chooseDataInit(disableIds.join(',')); treeObj.chooseDataInit(disableIds.join(','));
} }
treeObj.chooseNodes = nodes; const chooseNodes = treeObj.chooseNodes;
if (!multiple) {
treeObj.chooseNodes = nodes;
} else {
const nodeMap = new Map();
const choosePids = nodes.map(n => n.id);
// 如果包含选中节点中包含上下级关系,则在选中节点中去掉上级节点
for(const node of nodes){
if(nodeMap.has(node.parentId)){
nodeMap.delete(node.parentId);
}
nodeMap.set(node.id, node)
}
treeObj.chooseNodes = [...nodeMap.values()];
}
} }
} }
}); });
@ -215,9 +249,9 @@ layui.define(['globalTree'], function (exports) {
}); });
} }
function addOtherLabel(value) { function addOtherLabel(value, readonly) {
let template = `<div class="layui-input-block label-set-component other-label" th:data-field-title="其他标签"></div>`; let template = `<div class="label-set-component other-label ${readonly?'read-only':''}" th:data-field-title="其他标签"></div>`;
$('.other-label-item').append(template); $('.other-label-item.layui-input-block').append(template);
let cid = _KEY + _CACHE.size, let cid = _KEY + _CACHE.size,
component = new Component(cid, $('.label-set-component.other-label:last')); component = new Component(cid, $('.label-set-component.other-label:last'));
@ -238,15 +272,16 @@ layui.define(['globalTree'], function (exports) {
function setData(dataArr = []) { function setData(dataArr = []) {
for (let data of dataArr) { for (let data of dataArr) {
let find = false; let find = false, readonly = false;
for (let component of _CACHE.values()) { for (let component of _CACHE.values()) {
readonly = component.isReadOnly();
if (data.fieldTitle !== '其他标签' && data.fieldTitle === component.fieldTitle) { if (data.fieldTitle !== '其他标签' && data.fieldTitle === component.fieldTitle) {
component.setData(data); component.setData(data);
find = true; find = true;
} }
} }
if (!find) { if (!find) {
addOtherLabel(data); addOtherLabel(data, readonly);
} }
} }
} }
@ -256,6 +291,7 @@ layui.define(['globalTree'], function (exports) {
const _exports = { const _exports = {
getData: (entityId, entityType) => _CACHE.getData(entityId, entityType), getData: (entityId, entityType) => _CACHE.getData(entityId, entityType),
setData, setData,
openChooseDialog: chooseLabelData
}; };
exports('datalabel', _exports) exports('datalabel', _exports)
}) })

@ -52,6 +52,7 @@ layui.define(['form'], function (exports) {
data = '';// 选中的数据 data = '';// 选中的数据
change;// 数据改变后的回调函数 change;// 数据改变后的回调函数
readonly;// 是否只读 readonly;// 是否只读
disabled; // 是否禁用
width;// 宽度 width;// 宽度
constructor(type, options) { constructor(type, options) {
@ -82,7 +83,8 @@ layui.define(['form'], function (exports) {
this.change = options.onchange || function () { this.change = options.onchange || function () {
}; };
this.readonly = options.readonly; this.readonly = options.readonly;
this.width = options.width || 'fit-content'; this.disabled = options.disabled;
this.width = options.width || '100%';
// 开始渲染 // 开始渲染
this.render(); this.render();
@ -249,7 +251,7 @@ layui.define(['form'], function (exports) {
} }
let nodes_html = nodes.join(''); let nodes_html = nodes.join('');
return `<select id="${_this.id}" name="${_this.name}" lay-filter="${_this.id}">${nodes_html}</select>`; return `<select id="${_this.id}" name="${_this.name}" lay-filter="${_this.id}" ${_this.readonly ? 'readonly="readonly"' : ''} ${_this.disabled ? 'disabled="disabled"' : ''}>${nodes_html}</select>`;
} }
/** /**
@ -304,11 +306,12 @@ layui.define(['form'], function (exports) {
type = _elem.attr('dict-type'), type = _elem.attr('dict-type'),
dictType = _elem.attr('dict-component'), dictType = _elem.attr('dict-component'),
readonly = _elem.attr('readonly'), readonly = _elem.attr('readonly'),
disabled = _elem.attr('disabled'),
data = _elem.attr('data'), data = _elem.attr('data'),
width = _elem.attr('dict-width'), width = _elem.attr('dict-width'),
formFilter = getFormElementFilter(_elem); formFilter = getFormElementFilter(_elem);
let option = {elem, id, name, type, formFilter, readonly, data, width}; let option = {elem, id, name, type, formFilter, readonly, disabled, data, width};
new DictComponent(dictType, option) new DictComponent(dictType, option)
}); });
} }

@ -34,6 +34,10 @@
USER_ROLES.push(role.roleName); USER_ROLES.push(role.roleName);
} }
} }
// 表单配置
const METADATA_FORM_CONFIG = /*[[${metadataFormConfig}]]*/ [];
const FILEUPLOAD_FORM_CONFIG = /*[[${uploadFormConfig}]]*/ [];
</script> </script>
<!-- 引入公用库 --> <!-- 引入公用库 -->

@ -7,8 +7,11 @@ import com.keyware.shandan.system.entity.SysMenu;
import com.keyware.shandan.system.service.SysMenuService; import com.keyware.shandan.system.service.SysMenuService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@Component @Component
@Transactional(rollbackFor = Exception.class, propagation = Propagation.SUPPORTS)
public class DynamicFormListener implements DynamicFormEventListener { public class DynamicFormListener implements DynamicFormEventListener {
@Autowired @Autowired
@ -21,7 +24,7 @@ public class DynamicFormListener implements DynamicFormEventListener {
menu.setMenuId(form.getId().toString()); menu.setMenuId(form.getId().toString());
menu.setParentMenu(parentMenu); menu.setParentMenu(parentMenu);
menu.setMenuParentId(parentMenu.getMenuId()); menu.setMenuParentId(parentMenu.getMenuId());
menu.setMenuName(form.getFormName() + "管理"); menu.setMenuName(form.getFormName());
menu.setMenuPath("/dynamic-data/view/data/list/" + form.getId()); menu.setMenuPath("/dynamic-data/view/data/list/" + form.getId());
menu.setSystem(parentMenu.getSystem()); menu.setSystem(parentMenu.getSystem());
menu.setMenuParentName(parentMenu.getMenuName()); menu.setMenuParentName(parentMenu.getMenuName());

@ -25,10 +25,6 @@ spring:
rest: rest:
uris: http://192.168.134.128:9200 uris: http://192.168.134.128:9200
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
security: security:
oauth2: oauth2:
client: client:
@ -51,4 +47,4 @@ project:
logging: logging:
level: level:
root: debug com.keyware: debug

@ -48,7 +48,6 @@ security:
user-authorization-uri: ${oauth.server.proxy}/oauth/authorize user-authorization-uri: ${oauth.server.proxy}/oauth/authorize
resource: resource:
user-info-uri: ${oauth.server.internal}/oauth/user/info user-info-uri: ${oauth.server.internal}/oauth/user/info
logging: logging:
level: level:
root: debug com.keyware: debug

@ -1,6 +1,7 @@
package com.keyware.shandan.bianmu.controller; package com.keyware.shandan.bianmu.controller;
import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.keyware.shandan.bianmu.entity.DirectoryResource; import com.keyware.shandan.bianmu.entity.DirectoryResource;
import com.keyware.shandan.bianmu.entity.DirectoryVo; import com.keyware.shandan.bianmu.entity.DirectoryVo;
@ -12,6 +13,9 @@ import com.keyware.shandan.common.util.StringUtils;
import com.keyware.shandan.datasource.entity.DBTableColumnVo; import com.keyware.shandan.datasource.entity.DBTableColumnVo;
import com.keyware.shandan.datasource.entity.DataSourceVo; import com.keyware.shandan.datasource.entity.DataSourceVo;
import com.keyware.shandan.datasource.service.DataSourceService; import com.keyware.shandan.datasource.service.DataSourceService;
import com.keyware.shandan.system.constants.FormTypeEnum;
import com.keyware.shandan.system.entity.SysFormConfig;
import com.keyware.shandan.system.service.SysFormConfigService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
@ -50,6 +54,9 @@ public class MetadataCommonController {
@Autowired @Autowired
private DataLabelsService labelsService; private DataLabelsService labelsService;
@Autowired
private SysFormConfigService formConfigService;
/** /**
* 数据资源详细信息页面 * 数据资源详细信息页面
* *
@ -74,6 +81,8 @@ public class MetadataCommonController {
mav.addObject("exampleList", exampleData.getRecords()); mav.addObject("exampleList", exampleData.getRecords());
mav.addObject("LabelConfigSet", labelsService.formConfigList()); mav.addObject("LabelConfigSet", labelsService.formConfigList());
mav.addObject("metadataFormConfig", formConfigService.listByFormType(FormTypeEnum.metadataEditForm));
return mav; return mav;
} }

@ -3,7 +3,6 @@ package com.keyware.shandan.bianmu.entity;
import com.baomidou.mybatisplus.annotation.*; import com.baomidou.mybatisplus.annotation.*;
import com.keyware.shandan.common.entity.BaseEntity; import com.keyware.shandan.common.entity.BaseEntity;
import com.keyware.shandan.common.util.StringUtils; import com.keyware.shandan.common.util.StringUtils;
import com.keyware.shandan.system.utils.StringUtil;
import lombok.*; import lombok.*;
import java.util.Date; import java.util.Date;
@ -74,6 +73,13 @@ public class DataLabelsVo extends BaseEntity {
@OrderBy(isDesc = false, sort = 1) @OrderBy(isDesc = false, sort = 1)
private Boolean isLabel; private Boolean isLabel;
/**
* 渲染顺序
*/
@TableField(value = "SORT")
@OrderBy(isDesc = false)
private Integer sort;
/** /**
* 创建时间 * 创建时间
*/ */
@ -91,7 +97,7 @@ public class DataLabelsVo extends BaseEntity {
return ""; return "";
} }
public String getTitlePathWithSelf(){ public String getTitlePathWithSelf() {
if (StringUtils.hasText(titlePath)) { if (StringUtils.hasText(titlePath)) {
return titlePath + title + "/"; return titlePath + title + "/";
} }

@ -130,21 +130,9 @@ public class DirectoryVo extends BaseEntity {
@OrderBy(isDesc = false) @OrderBy(isDesc = false)
private Date createTime; private Date createTime;
/**
* 所属部门对象
*/
/*@TableField(exist = false)
private SysOrg org;*/
@TableField(exist = false) @TableField(exist = false)
private String modifyUserName; private String modifyUserName;
/**
* 是否有子级
*/
/*@TableField(exist = false)
private Boolean hasChild;*/
/** /**
* 子级目录 * 子级目录
*/ */
@ -157,6 +145,12 @@ public class DirectoryVo extends BaseEntity {
@TableField(exist = false) @TableField(exist = false)
private boolean applyChild; private boolean applyChild;
/**
* 目录顺序
*/
@TableField(value = "SORT")
private Integer sort;
/** /**
* 创建人名称 * 创建人名称
*/ */

@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import com.keyware.shandan.common.util.MD5Util; import com.keyware.shandan.common.util.MD5Util;
import lombok.*; import lombok.*;
import org.apache.ibatis.annotations.One;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import java.io.Serializable; import java.io.Serializable;
@ -42,6 +43,9 @@ public class LabelEntity implements Serializable {
@TableField("LABEL") @TableField("LABEL")
private String label; private String label;
@TableField(exist = false)
private DataLabelsVo data;
public String getId() { public String getId() {
if (StringUtils.hasText(id)) { if (StringUtils.hasText(id)) {
return id; return id;

@ -2,9 +2,9 @@ package com.keyware.shandan.bianmu.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.keyware.shandan.bianmu.entity.LabelEntity; import com.keyware.shandan.bianmu.entity.LabelEntity;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.*;
import org.apache.ibatis.annotations.Select;
import java.io.Serializable;
import java.util.List; import java.util.List;
/** /**
@ -14,6 +14,21 @@ import java.util.List;
@Mapper @Mapper
public interface LabelEntityMapper extends BaseMapper<LabelEntity> { public interface LabelEntityMapper extends BaseMapper<LabelEntity> {
@Override
@Results(id="all_result_map", value = {
@Result(id = true, column = "ID", property = "id"),
@Result(column = "ENTITY_ID", property = "entityId"),
@Result(column = "ENTITY_TYPE", property = "entityType"),
@Result(column = "LABEL_ID", property = "labelId"),
@Result(column = "FIELD_TITLE", property = "fieldTitle"),
@Result(column = "LABEL", property = "label"),
@Result(column = "LABEL_ID", property = "data", one = @One(select = "com.keyware.shandan.bianmu.mapper.DataLabelsMapper.selectById"))
})
@Select("SELECT * FROM B_DATA_LABEL_ENTITY WHERE ID = #{id}")
LabelEntity selectById(Serializable id);
@ResultMap(value = {"all_result_map"})
@Select("SELECT * FROM B_DATA_LABEL_ENTITY WHERE ENTITY_ID = #{entityId}") @Select("SELECT * FROM B_DATA_LABEL_ENTITY WHERE ENTITY_ID = #{entityId}")
List<LabelEntity> selectByEntityId(String entityId); List<LabelEntity> selectByEntityId(String entityId);
} }

@ -53,15 +53,41 @@ public class DirectoryTreeService {
if (StringUtils.hasText(pid)) { if (StringUtils.hasText(pid)) {
parentDir = directoryService.getById(pid); parentDir = directoryService.getById(pid);
} }
// 获取子级节点
List<DirectoryVo> directoryList = getDirectoryList(parentDir, allChild, hasMetadata, busType); List<DirectoryVo> directoryList = getDirectoryList(parentDir, allChild, hasMetadata, busType);
// 审核状态
ReviewStatus status = StringUtils.hasText(reviewStatus) ? ReviewStatus.valueOf(reviewStatus) : null; ReviewStatus status = StringUtils.hasText(reviewStatus) ? ReviewStatus.valueOf(reviewStatus) : null;
// 当前用户
SysUser user = SecurityUtil.getLoginSysUser(); SysUser user = SecurityUtil.getLoginSysUser();
// 根据权限类型获取权限范围内的数据的ID集合
Set<String> permisDis = "write".equals(permis) ? dirPermissionService.getByWritePermis(user) : dirPermissionService.getByReadPermis(user); Set<String> permisDis = "write".equals(permis) ? dirPermissionService.getByWritePermis(user) : dirPermissionService.getByReadPermis(user);
// 判断权限范围
List<DirectoryVo> permisDirectoryList = StreamUtil.as(directoryList).filter(dir -> { List<DirectoryVo> permisDirectoryList = StreamUtil.as(directoryList).filter(dir -> {
if (status == null) { if (dir.getDirectoryType() == DirectoryType.FILE
return permisDis.contains(dir.getId()); || dir.getDirectoryType() == DirectoryType.LINK_FILE
|| dir.getDirectoryType() == DirectoryType.METADATA
|| dir.getDirectoryType() == DirectoryType.LINK_METADATA) {
return true;
} }
return dir.getReviewStatus() == status && permisDis.contains(dir.getId());
if (dir.getReviewStatus() == status || status == null) {
boolean permisAllow = permisDis.contains(dir.getId());
if (permisAllow) {
return true;
}
// 如果权限不允许,则需要判断当前节点的所有子级节点是否有允许的目录,如果有则需要返回到前端的树组件中
Set<String> childrenIds = getDirectoryList(dir, true, false, busType)
.stream()
.map(DirectoryVo::getId)
.collect(Collectors.toSet());
for (String id : childrenIds) {
if (permisDis.contains(id)) {
return true;
}
}
return false;
}
return false;
}).toList(); }).toList();
DirectoryParentBuilder dpb = new DirectoryParentBuilder(directoryList, permisDirectoryList); DirectoryParentBuilder dpb = new DirectoryParentBuilder(directoryList, permisDirectoryList);
@ -87,9 +113,9 @@ public class DirectoryTreeService {
*/ */
private List<DirectoryVo> getDirectoryList(DirectoryVo parentDir, boolean allChild, boolean hasResource, int busType) { private List<DirectoryVo> getDirectoryList(DirectoryVo parentDir, boolean allChild, boolean hasResource, int busType) {
QueryWrapper<DirectoryVo> wrapper = new QueryWrapper<>(); QueryWrapper<DirectoryVo> wrapper = new QueryWrapper<>();
if(parentDir == null){ if (parentDir == null) {
wrapper.eq("ID", "ROOT"); wrapper.eq("ID", "ROOT");
}else { } else {
wrapper.in(!hasResource, "DIRECTORY_TYPE", DirectoryType.DIRECTORY, DirectoryType.LINK_DIR).eq("IS_BASIC_DIR", busType); wrapper.in(!hasResource, "DIRECTORY_TYPE", DirectoryType.DIRECTORY, DirectoryType.LINK_DIR).eq("IS_BASIC_DIR", busType);
if (parentDir != null) { if (parentDir != null) {
if (allChild) { if (allChild) {

@ -29,13 +29,14 @@ public class DirectoryUtil {
tree.setType("DIRECTORY"); tree.setType("DIRECTORY");
tree.setPath(dir.getDirectoryPath()); tree.setPath(dir.getDirectoryPath());
tree.setBasicData(dir); tree.setBasicData(dir);
if(dir.getDirectoryType() == DirectoryType.FILE || dir.getDirectoryType() == DirectoryType.LINK_FILE){ tree.setSort(dir.getSort() == null ? Integer.MAX_VALUE : dir.getSort());
if (dir.getDirectoryType() == DirectoryType.FILE || dir.getDirectoryType() == DirectoryType.LINK_FILE) {
tree.setIconClass("dtree-icon-normal-file"); tree.setIconClass("dtree-icon-normal-file");
tree.setLast(true); tree.setLast(true);
}else if(dir.getDirectoryType() == DirectoryType.METADATA || dir.getDirectoryType() == DirectoryType.LINK_METADATA){ } else if (dir.getDirectoryType() == DirectoryType.METADATA || dir.getDirectoryType() == DirectoryType.LINK_METADATA) {
tree.setIconClass("dtree-icon-sort"); tree.setIconClass("dtree-icon-sort");
tree.setLast(true); tree.setLast(true);
}else{ } else {
tree.setLast(false); tree.setLast(false);
} }
} }

@ -6,8 +6,10 @@ import com.keyware.shandan.common.entity.Result;
import com.keyware.shandan.common.util.*; import com.keyware.shandan.common.util.*;
import com.keyware.shandan.frame.config.security.SecurityUtil; import com.keyware.shandan.frame.config.security.SecurityUtil;
import com.keyware.shandan.frame.properties.CustomProperties; import com.keyware.shandan.frame.properties.CustomProperties;
import com.keyware.shandan.system.entity.SysFormConfig;
import com.keyware.shandan.system.entity.SysRole; import com.keyware.shandan.system.entity.SysRole;
import com.keyware.shandan.system.entity.SysUser; import com.keyware.shandan.system.entity.SysUser;
import com.keyware.shandan.system.service.SysFormConfigService;
import com.keyware.shandan.system.service.SysRoleService; import com.keyware.shandan.system.service.SysRoleService;
import com.keyware.shandan.system.utils.SysSettingUtil; import com.keyware.shandan.system.utils.SysSettingUtil;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -25,7 +27,9 @@ import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.*; import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/** /**
* AES + RSA 加解密AOP处理 * AES + RSA 加解密AOP处理
@ -44,6 +48,9 @@ public class SafetyAspect {
@Autowired @Autowired
private SysRoleService sysRoleService; private SysRoleService sysRoleService;
@Autowired
private SysFormConfigService formConfigService;
/** /**
* Pointcut 切入点 * Pointcut 切入点
*/ */
@ -80,7 +87,7 @@ public class SafetyAspect {
Object result = joinPoint.proceed(AspectUtil.parseJoinPointArgs(joinPoint, request)); Object result = joinPoint.proceed(AspectUtil.parseJoinPointArgs(joinPoint, request));
//执行方法之前解密,且只拦截post请求 //执行方法之前解密,且只拦截post请求
if ("post".equalsIgnoreCase(request.getMethod()) && !ServletFileUpload.isMultipartContent(request)) { if ("post".equalsIgnoreCase(request.getMethod()) && !ServletFileUpload.isMultipartContent(request) && StringUtils.hasText(publicKey)) {
// 返回之前对结果进行加密 // 返回之前对结果进行加密
//每次响应之前随机获取AES的key,加密data数据 //每次响应之前随机获取AES的key,加密data数据
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
@ -98,7 +105,7 @@ public class SafetyAspect {
ModelAndView modelAndView = (ModelAndView) result; ModelAndView modelAndView = (ModelAndView) result;
modelAndView.addObject("publicKey", RsaUtil.getPublicKey()); modelAndView.addObject("publicKey", RsaUtil.getPublicKey());
modelAndView.addObject("sys", SysSettingUtil.getCurrentSysSetting()); modelAndView.addObject("sys", SysSettingUtil.getCurrentSysSetting());
SysUser loginUser = SecurityUtil.getLoginSysUser(); SysUser loginUser = SecurityUtil.getLoginSysUser();
loginUser.setPassword(null); loginUser.setPassword(null);
modelAndView.addObject("loginUser", loginUser); modelAndView.addObject("loginUser", loginUser);
//登录用户角色信息 //登录用户角色信息
@ -121,6 +128,10 @@ public class SafetyAspect {
} }
//展示用户角色 //展示用户角色
modelAndView.addObject("userRole", userRoles.get(index)); modelAndView.addObject("userRole", userRoles.get(index));
List<SysFormConfig> formConfigList = formConfigService.list();
modelAndView.addObject("metadataFormConfig", formConfigList.stream().filter(conf -> conf.getFormType() == 1).collect(Collectors.toList()));
modelAndView.addObject("uploadFormConfig", formConfigList.stream().filter(conf -> conf.getFormType() == 2).collect(Collectors.toList()));
setStaticResourceAddress(request, modelAndView); setStaticResourceAddress(request, modelAndView);
} }
return result; return result;

@ -1,6 +1,6 @@
package com.keyware.shandan.mark.controller; package com.keyware.shandan.mark.controller;
import com.keyware.shandan.mark.constant.FormTypeEnum; import com.keyware.shandan.system.constants.FormTypeEnum;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;

@ -1,7 +1,7 @@
package com.keyware.shandan.mark.services; package com.keyware.shandan.mark.services;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.keyware.shandan.mark.constant.FormTypeEnum; import com.keyware.shandan.system.constants.FormTypeEnum;
import com.keyware.shandan.mark.pojo.FormMark; import com.keyware.shandan.mark.pojo.FormMark;
import com.keyware.shandan.mark.pojo.MarkRecord; import com.keyware.shandan.mark.pojo.MarkRecord;
import com.keyware.shandan.mark.pojo.MarkType; import com.keyware.shandan.mark.pojo.MarkType;

@ -1,5 +1,6 @@
package com.keyware.shandan.mark.constant; package com.keyware.shandan.system.constants;
import com.baomidou.mybatisplus.annotation.EnumValue;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
@ -16,16 +17,19 @@ public enum FormTypeEnum {
/** /**
* 数据资源注册表单 * 数据资源注册表单
*/ */
metadataEditForm("数据资源注册表单"), metadataEditForm(1,"数据资源注册表单"),
/** /**
* 文件上传表单 * 文件上传表单
*/ */
fileUploadForm("文件上传表单"), fileUploadForm(2, "文件上传表单"),
/** /**
* 文件夹上传表单 * 文件夹上传表单
*/ */
@Deprecated @Deprecated
dirUploadForm("文件夹上传表单"); dirUploadForm(3, "文件夹上传表单");
@EnumValue
private final Integer value;
/** /**
* 描述 * 描述

@ -8,10 +8,12 @@ import com.keyware.shandan.common.controller.BaseController;
import com.keyware.shandan.common.entity.Result; import com.keyware.shandan.common.entity.Result;
import com.keyware.shandan.common.util.FileDownload; import com.keyware.shandan.common.util.FileDownload;
import com.keyware.shandan.frame.properties.CustomProperties; import com.keyware.shandan.frame.properties.CustomProperties;
import com.keyware.shandan.system.constants.FormTypeEnum;
import com.keyware.shandan.system.entity.SysFile; import com.keyware.shandan.system.entity.SysFile;
import com.keyware.shandan.system.entity.SysFileChunk; import com.keyware.shandan.system.entity.SysFileChunk;
import com.keyware.shandan.system.entity.SysSetting; import com.keyware.shandan.system.entity.SysSetting;
import com.keyware.shandan.system.service.SysFileService; import com.keyware.shandan.system.service.SysFileService;
import com.keyware.shandan.system.service.SysFormConfigService;
import com.keyware.shandan.system.service.SysSettingService; import com.keyware.shandan.system.service.SysSettingService;
import com.keyware.shandan.system.utils.FileChunkUploadUtil; import com.keyware.shandan.system.utils.FileChunkUploadUtil;
import org.apache.tomcat.util.http.ResponseUtil; import org.apache.tomcat.util.http.ResponseUtil;
@ -57,12 +59,16 @@ public class SysFileController extends BaseController<SysFileService, SysFile, S
@Autowired @Autowired
private DataLabelsService labelsService; private DataLabelsService labelsService;
@Autowired
private SysFormConfigService formConfigService;
@GetMapping("/layer") @GetMapping("/layer")
public ModelAndView fileUploadLayer(ModelAndView mav) { public ModelAndView fileUploadLayer(ModelAndView mav) {
mav.setViewName("sys/file/fileUploadLayer"); mav.setViewName("sys/file/fileUploadLayer");
mav.addObject("LabelConfigSet", labelsService.formConfigList()); mav.addObject("LabelConfigSet", labelsService.formConfigList());
mav.addObject("uploadFormConfig", formConfigService.listByFormType(FormTypeEnum.fileUploadForm));
return mav; return mav;
} }

@ -0,0 +1,57 @@
package com.keyware.shandan.system.controller;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.keyware.shandan.common.entity.Result;
import com.keyware.shandan.system.entity.SysFormConfig;
import com.keyware.shandan.system.service.SysFormConfigService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import java.util.List;
/**
* 系统表单配置模块前端控制类
*
* @author GuoXin
* @date 2023/8/23
*/
@Slf4j
@RestController
@RequestMapping("/sys/form/config")
public class SysFormConfigController {
private final SysFormConfigService formConfigService;
public SysFormConfigController(SysFormConfigService formConfigService) {
this.formConfigService = formConfigService;
}
@GetMapping("/page/index")
public ModelAndView indexPage(ModelAndView mav) {
mav.setViewName("sys/form/formConfig");
return mav;
}
@GetMapping("/api/get/{id}")
public Result<SysFormConfig> getById(@PathVariable String id) {
return Result.of(formConfigService.getById(id));
}
@GetMapping("/api/list/{formType}")
public Result<List<SysFormConfig>> list(@PathVariable String formType) {
QueryWrapper<SysFormConfig> query = new QueryWrapper<>();
query.eq("FORM_TYPE", formType);
return Result.of(formConfigService.list(query));
}
@PostMapping(value = "/api/save")
public Result<Object> save(String params) {
JSONArray jsonArray = JSONUtil.parseArray(params);
List<SysFormConfig> list = jsonArray.toList(SysFormConfig.class);
return Result.of(formConfigService.saveOrUpdateBatch(list));
}
}

@ -0,0 +1,42 @@
package com.keyware.shandan.system.controller;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.keyware.shandan.common.entity.Result;
import com.keyware.shandan.common.util.StringUtils;
import com.keyware.shandan.system.entity.SysTheadConfig;
import com.keyware.shandan.system.service.SysTheadConfigService;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* 前端数据表格表头配置前端控制器
*
* @author GuoXin
* @date 2023/8/30
*/
@RestController
@RequestMapping("/sys/thead/config")
public class SysTheadConfigController {
private final SysTheadConfigService theadConfigService;
public SysTheadConfigController(SysTheadConfigService theadConfigService) {
this.theadConfigService = theadConfigService;
}
@PostMapping(value = "/api/save")
public Result<Object> save(String params, Authentication auth) {
JSONArray jsonArray = JSONUtil.parseArray(params);
List<SysTheadConfig> list = jsonArray.toList(SysTheadConfig.class);
list.forEach(item->{
if(!StringUtils.hasText(item.getId())){
item.genId(auth.getName());
}
});
return Result.of(theadConfigService.saveOrUpdateBatch(list));
}
}

@ -0,0 +1,66 @@
package com.keyware.shandan.system.entity;
import com.baomidou.mybatisplus.annotation.OrderBy;
import com.keyware.shandan.common.entity.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 系统表单配置实体类
*
* @author GuoXin
* @date 2023/8/23
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class SysFormConfig extends BaseEntity {
private static final long serialVersionUID = 6628747783449277117L;
/**
* 主键
*/
private Integer id;
/**
* 表单类型1-资源注册表单2-文件上传表单
*/
private Integer formType;
/**
* 字段名
*/
private String fieldName;
/**
* 字段显示标题
*/
private String showTitle;
/**
* 字段类型
*/
private String fieldType;
/**
* 数据字典类型只有当fieldType为"dict"时才有效
*/
private String dictType;
/**
* 默认值
*/
private String defaultValue;
/**
* 是否必填0-非必填1-必填
*/
private Boolean isRequired;
/**
* 是否禁用0-不禁用1-禁用
*/
private Boolean isDisabled;
/**
* 是否禁用0-不禁用1-禁用
*/
private Boolean isShow;
/**
* 显示顺序
*/
@OrderBy(isDesc = false)
private Integer sort;
}

@ -0,0 +1,65 @@
package com.keyware.shandan.system.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.OrderBy;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.keyware.shandan.common.entity.BaseEntity;
import com.keyware.shandan.common.util.MD5Util;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 前端数据表格表头配置实体类
*
* @author GuoXin
* @date 2023/8/30
*/
@Data
@Builder
@EqualsAndHashCode(callSuper = true)
@TableName("SYS_THEAD_CONFIG")
public class SysTheadConfig extends BaseEntity {
private static final long serialVersionUID = 1480474706145625172L;
/**
* 主键
*/
@TableId(type = IdType.INPUT)
private String id;
/**
* 数据表ID对应前端页面上的layui中table组件的id
*/
private String tableId;
/**
* 列名
*/
private String colName;
/**
* 列标题
*/
private String colTitle;
/**
* 列顺序
*/
@OrderBy(isDesc = false, sort = 2)
private Integer colSort;
/**
* 列宽度
*/
private String colWidth;
/**
* 是否显示
*/
@OrderBy(sort = 1)
private Boolean isShow;
/**
* 是否允许排序
*/
private Boolean isSort;
public void genId(String userName) {
this.id = MD5Util.getMD5(tableId + colName + userName);
}
}

@ -0,0 +1,15 @@
package com.keyware.shandan.system.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.keyware.shandan.system.entity.SysFormConfig;
import org.apache.ibatis.annotations.Mapper;
/**
* 系统表单配置数据库操作映射
*
* @author GuoXin
* @date 2023/8/23
*/
@Mapper
public interface SysFormConfigMapper extends BaseMapper<SysFormConfig> {
}

@ -0,0 +1,15 @@
package com.keyware.shandan.system.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.keyware.shandan.system.entity.SysTheadConfig;
import org.apache.ibatis.annotations.Mapper;
/**
* 前端数据表格表头配置数据库操作映射接口
*
* @author GuoXin
* @date 2023/8/30
*/
@Mapper
public interface SysTheadConfigMapper extends BaseMapper<SysTheadConfig> {
}

@ -0,0 +1,18 @@
package com.keyware.shandan.system.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.keyware.shandan.system.constants.FormTypeEnum;
import com.keyware.shandan.system.entity.SysFormConfig;
import java.util.List;
/**
* 系统表单配置服务接口类
*
* @author GuoXin
* @date 2023/8/23
*/
public interface SysFormConfigService extends IService<SysFormConfig> {
List<SysFormConfig> listByFormType(FormTypeEnum formTypeEnum);
}

@ -0,0 +1,16 @@
package com.keyware.shandan.system.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.keyware.shandan.system.entity.SysTheadConfig;
import java.util.List;
/**
* 前端数据表格表头配置数据库操作接口
*
* @author GuoXin
* @date 2023/8/30
*/
public interface SysTheadConfigService extends IService<SysTheadConfig> {
List<SysTheadConfig> listByCreateUser(String userId);
}

@ -33,7 +33,7 @@ public class SysDictServiceImpl extends BaseServiceImpl<SysDictMapper, SysDict,
return Result.of(null, false, "字典名称已存在"); return Result.of(null, false, "字典名称已存在");
} }
} }
entity.setDictCode(entity.getDictName()); entity.setDictCode(entity.getDictValue());
// entity.setDictValue(entity.getDictName()); // entity.setDictValue(entity.getDictName());
boolean ok = super.saveOrUpdate(entity); boolean ok = super.saveOrUpdate(entity);
if(ok){ if(ok){

@ -0,0 +1,27 @@
package com.keyware.shandan.system.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.keyware.shandan.system.constants.FormTypeEnum;
import com.keyware.shandan.system.entity.SysFormConfig;
import com.keyware.shandan.system.mapper.SysFormConfigMapper;
import com.keyware.shandan.system.service.SysFormConfigService;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 系统表单配置服务实现类
*
* @author GuoXin
* @date 2023/8/23
*/
@Service
public class SysFormConfigServiceImpl extends ServiceImpl<SysFormConfigMapper, SysFormConfig> implements SysFormConfigService {
@Override
public List<SysFormConfig> listByFormType(FormTypeEnum formTypeEnum) {
QueryWrapper<SysFormConfig> query = new QueryWrapper<>();
query.eq("FORM_TYPE", formTypeEnum.getValue());
return list(query);
}
}

@ -0,0 +1,78 @@
package com.keyware.shandan.system.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.keyware.shandan.common.util.StringUtils;
import com.keyware.shandan.system.entity.SysTheadConfig;
import com.keyware.shandan.system.mapper.SysTheadConfigMapper;
import com.keyware.shandan.system.service.SysTheadConfigService;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
/**
* 前端数据表格表头配置数据库操作接口实现类
*
* @author GuoXin
* @date 2023/8/30
*/
@Service
public class SysTheadConfigServiceImpl extends ServiceImpl<SysTheadConfigMapper, SysTheadConfig> implements SysTheadConfigService {
static final String resourceTableId = "browser_resource_table", fileTableId = "browser_file_table";
static List<SysTheadConfig> defaultConfig = new ArrayList<>();
static {
SysTheadConfig.SysTheadConfigBuilder builder = SysTheadConfig.builder();
// 初始化综合浏览系统资源查询数据表表头默认配置
defaultConfig.add(builder.tableId(resourceTableId).colName("resourceName").colTitle("资源名称").colSort(1).colWidth("100").isShow(true).isSort(false).build());
defaultConfig.add(builder.tableId(resourceTableId).colName("resourceComment").colTitle("资源注释").colSort(2).colWidth("100").isShow(true).isSort(false).build());
defaultConfig.add(builder.tableId(resourceTableId).colName("directoryPath").colTitle("目录路径").colSort(3).colWidth("100").isShow(true).isSort(false).build());
defaultConfig.add(builder.tableId(resourceTableId).colName("themeTask").colTitle("主题任务").colSort(4).colWidth("100").isShow(true).isSort(false).build());
defaultConfig.add(builder.tableId(resourceTableId).colName("dataSource").colTitle("数据来源").colSort(5).colWidth("100").isShow(true).isSort(false).build());
defaultConfig.add(builder.tableId(resourceTableId).colName("taskTime").colTitle("任务时间").colSort(6).colWidth("100").isShow(true).isSort(false).build());
defaultConfig.add(builder.tableId(resourceTableId).colName("dataType").colTitle("数据类型").colSort(7).colWidth("100").isShow(true).isSort(false).build());
defaultConfig.add(builder.tableId(resourceTableId).colName("secretLevel").colTitle("数据密级").colSort(8).colWidth("100").isShow(true).isSort(false).build());
defaultConfig.add(builder.tableId(resourceTableId).colName("resourceType").colTitle("资源类型").colSort(9).colWidth("100").isShow(true).isSort(false).build());
// 初始化综合浏览系统文件全文检索数据表表头默认配置
defaultConfig.add(builder.tableId(fileTableId).colName("fileName").colTitle("文件名称").colSort(9).colWidth("100").isShow(true).isSort(false).build());
defaultConfig.add(builder.tableId(fileTableId).colName("fileType").colTitle("文件类型").colSort(9).colWidth("100").isShow(true).isSort(false).build());
defaultConfig.add(builder.tableId(fileTableId).colName("fileSize").colTitle("文件大小").colSort(9).colWidth("100").isShow(true).isSort(false).build());
defaultConfig.add(builder.tableId(fileTableId).colName("remark").colTitle("文件描述").colSort(9).colWidth("100").isShow(true).isSort(false).build());
defaultConfig.add(builder.tableId(fileTableId).colName("exerciseData").colTitle("是否演训数据").colSort(9).colWidth("100").isShow(true).isSort(false).build());
defaultConfig.add(builder.tableId(fileTableId).colName("entryStaff").colTitle("录入人员").colSort(9).colWidth("100").isShow(true).isSort(false).build());
defaultConfig.add(builder.tableId(fileTableId).colName("equipmentModel").colTitle("装备型号").colSort(9).colWidth("100").isShow(true).isSort(false).build());
defaultConfig.add(builder.tableId(fileTableId).colName("inputDate").colTitle("任务时间").colSort(9).colWidth("100").isShow(true).isSort(false).build());
defaultConfig.add(builder.tableId(fileTableId).colName("source").colTitle("文件来源").colSort(9).colWidth("100").isShow(true).isSort(false).build());
defaultConfig.add(builder.tableId(fileTableId).colName("taskCode").colTitle("任务代号").colSort(9).colWidth("100").isShow(true).isSort(false).build());
defaultConfig.add(builder.tableId(fileTableId).colName("taskNature").colTitle("任务性质").colSort(9).colWidth("100").isShow(true).isSort(false).build());
defaultConfig.add(builder.tableId(fileTableId).colName("troopCode").colTitle("部队代号").colSort(9).colWidth("100").isShow(true).isSort(false).build());
defaultConfig.add(builder.tableId(fileTableId).colName("targetNumber").colTitle("目标/靶标类型").colSort(9).colWidth("100").isShow(true).isSort(false).build());
defaultConfig.add(builder.tableId(fileTableId).colName("missileNumber").colTitle("导弹编号").colSort(9).colWidth("100").isShow(true).isSort(false).build());
defaultConfig.add(builder.tableId(fileTableId).colName("themeTask").colTitle("主题任务").colSort(9).colWidth("100").isShow(true).isSort(false).build());
defaultConfig.add(builder.tableId(fileTableId).colName("secretLevel").colTitle("文件密级").colSort(9).colWidth("100").isShow(true).isSort(false).build());
}
@Override
public List<SysTheadConfig> listByCreateUser(String userId) {
if (StringUtils.hasText(userId)) {
LambdaQueryWrapper<SysTheadConfig> query = new LambdaQueryWrapper<>();
query.eq(SysTheadConfig::getCreateUser, userId);
List<SysTheadConfig> list = list(query);
if (list.size() == 0) {
// 为默认数据生成包含用户主键的ID
defaultConfig.forEach(conf -> conf.genId(userId));
return defaultConfig;
}
return list;
}
return Collections.emptyList();
}
@Override
public boolean saveOrUpdateBatch(Collection<SysTheadConfig> entityList, int batchSize) {
return super.saveOrUpdateBatch(entityList, batchSize);
}
}

@ -14,6 +14,7 @@
<result column="OWNER" property="owner"/> <result column="OWNER" property="owner"/>
<result column="OWNER_ID" property="ownerId"/> <result column="OWNER_ID" property="ownerId"/>
<result column="OWNER_TYPE" property="ownerType"/> <result column="OWNER_TYPE" property="ownerType"/>
<result column="SORT" property="sort"/>
<result column="CREATE_USER" property="createUser"/> <result column="CREATE_USER" property="createUser"/>
<result column="CREATE_TIME" property="createTime"/> <result column="CREATE_TIME" property="createTime"/>
<result column="MODIFY_USER" property="modifyUser"/> <result column="MODIFY_USER" property="modifyUser"/>

@ -51,6 +51,8 @@ ul.file-viewer-tab li:hover {
} }
.file-property .field-name{ .file-property .field-name{
width: 70px; width: 70px;
text-align: right;
padding-right: 10px;
} }
.file-property .field-value{ .file-property .field-value{
flex: 1; flex: 1;

@ -289,6 +289,12 @@ layui.use(['layer', 'form', 'gtable', 'globalTree'], function () {
<input class="layui-input" type="text" name="title" value="${data.title || ''}" maxlength="50" placeholder="请输入${titleName}名称" lay-verify="required"> <input class="layui-input" type="text" name="title" value="${data.title || ''}" maxlength="50" placeholder="请输入${titleName}名称" lay-verify="required">
</div> </div>
</div> </div>
<div class="layui-form-item">
<div class="layui-inline" style="width: calc(100% - 30px); margin:15px 15px 0 15px">
<label style="color: #555;">顺序</label>
<input class="layui-input" name="sort" value="${data.sort || '0'}" lay-verify="number" autocomplete="false" maxlength="230" placeholder="请输入加载顺序" />
</div>
</div>
<div class="layui-form-item"> <div class="layui-form-item">
<div class="layui-inline" style="width: calc(100% - 30px); margin:15px 15px 0 15px"> <div class="layui-inline" style="width: calc(100% - 30px); margin:15px 15px 0 15px">
<label style="color: #555;">备注</label> <label style="color: #555;">备注</label>

@ -117,11 +117,15 @@ function openDirectoryEditLayer(data, callback, view) {
</div> </div>
<a lay-submit lay-filter="directoryEditForm" id="directoryEditFormSubmit" style=""></a> <a lay-submit lay-filter="directoryEditForm" id="directoryEditFormSubmit" style=""></a>
</div> </div>
<div class="layui-inline" style="width: calc(100% - 30px); margin:15px 15px 0 15px"> <div class="layui-inline" style="width: calc(63% - 30px); margin:15px 15px 0 15px">
<label style="color: #555">目录创建人</label><span style="color: #000" >${data.createUserName || user.userName}</span> <label style="color: #555">目录创建人</label><span style="color: #000" >${data.createUserName || user.userName}</span>
<input type="hidden" name="createUserName" value="${data.createUserName || user.userName}" /> <input type="hidden" name="createUserName" value="${data.createUserName || user.userName}" />
<input type="hidden" name="createUser" value="${data.createUser || user.userId}" /> <input type="hidden" name="createUser" value="${data.createUser || user.userId}" />
</div> </div>
<div class="layui-inline" style="width: calc(37% - 40px); margin:15px 15px 0 15px">
<label style="color: #555">目录顺序</label>
<input class="layui-input" type="text" name="sort" value="${data.sort}" style="width: 60px"/>
</div>
</div> </div>
</div>`, </div>`,
success: function () { success: function () {
@ -137,12 +141,12 @@ function openDirectoryEditLayer(data, callback, view) {
click: dirOwnerChangeCallback click: dirOwnerChangeCallback
}); });
layui.dict.render(); layui.dict.render();
if(!data || !data.secretLevel){ if (!data || !data.secretLevel) {
data['secretLevel'] = 0; data['secretLevel'] = 0;
} }
layui.dict.setData('dict-secret-level', data) layui.dict.setData('dict-secret-level', data)
$('div.dict-component').css({'margin-top': '5px', 'width': '380px', 'margin-left': '4px'}) $('div.dict-component').css({'margin-top': '5px', 'width': '380px', 'margin-left': '4px'})
if(view){ if (view) {
layui.dict.setReadonly(); layui.dict.setReadonly();
} }
// 目录成员管理事件 // 目录成员管理事件
@ -166,7 +170,9 @@ function openDirectoryEditLayer(data, callback, view) {
applyChildCheckbox(isEdit); applyChildCheckbox(isEdit);
}, },
yes: function (index) { yes: function (index) {
if(view){return;} if (view) {
return;
}
saveDirectory(index, callback); saveDirectory(index, callback);
} }
}) })
@ -174,10 +180,16 @@ function openDirectoryEditLayer(data, callback, view) {
function saveDirectory(index, callback) { function saveDirectory(index, callback) {
form.on('submit(directoryEditForm)', function ({elem, field}) { form.on('submit(directoryEditForm)', function ({elem, field}) {
if(field.secretLevel > user.secretLevel){ if (field.secretLevel > user.secretLevel) {
layer.alert('禁止上传超过自身涉密等级的文件,您的涉密等级为【'+ DICT.getText('secret_level', user.secretLevel) +'】', {icon:2}) layer.alert('禁止上传超过自身涉密等级的文件,您的涉密等级为【' + DICT.getText('secret_level', user.secretLevel) + '】', {icon: 2})
return; return;
} }
if (isNaN(parseInt(field.sort))) {
layer.alert('目录顺序只能为数字');
return;
}
// 转换数据类型 // 转换数据类型
field.basicDir = field.basicDir === '1'; field.basicDir = field.basicDir === '1';
// 如果是基础数据目录,则自动为提交状态 // 如果是基础数据目录,则自动为提交状态

@ -131,7 +131,7 @@ layui.use(['layer', 'uploader', 'element', 'form', 'laydate', 'dict', 'datalabel
function bindDatetimePlugins() { function bindDatetimePlugins() {
//日期选择器 //日期选择器
laydate.render({ laydate.render({
elem: '#input-data', elem: 'input[name="inputDate"]',
format: "yyyy-MM-dd HH:mm:ss", format: "yyyy-MM-dd HH:mm:ss",
type: 'datetime', type: 'datetime',
value: new Date(), value: new Date(),

@ -9,6 +9,9 @@
layui.use(['layer', 'laytpl', 'dropdown', 'carousel', 'form', 'datalabel'], function () { layui.use(['layer', 'laytpl', 'dropdown', 'carousel', 'form', 'datalabel'], function () {
for (let col in file) { for (let col in file) {
switch (col) { switch (col) {
case 'secretLevel':
$(`label[name="${col}"]`).text(DICT.getText('secret_level', file[col]));
break;
case 'taskNature': case 'taskNature':
$(`label[name="${col}"]`).text(DICT.getText('task_nature', file[col])); $(`label[name="${col}"]`).text(DICT.getText('task_nature', file[col]));
break; break;
@ -26,7 +29,10 @@ layui.use(['layer', 'laytpl', 'dropdown', 'carousel', 'form', 'datalabel'], func
} }
} }
break; break;
case 'secretLevel': case 'exerciseData':
$(`label[name="${col}"]`).text(file[col] == 0 ? '否' : '是');
break;
case '':
$(`label[name="${col}"]`).text(DICT.getText('secret_level', file[col])); $(`label[name="${col}"]`).text(DICT.getText('secret_level', file[col]));
break; break;
default: default:

@ -0,0 +1,88 @@
class FormConfigComponent {
constructor(formType, elemId, lay) {
this.formType = formType;
this.elemId = elemId;
this.lay = lay;
this.dataMap = new Map();
this.renderTable();
}
renderTable() {
const {lay, formType, elemId} = this, {form, gtable} = lay;
gtable.init({
id: elemId,
url: `${ctx}/sys/form/config/api/list/${formType}`,
method: 'get',
toolbar: '#tableTool',
height: 'full-125',
page: false,
cols: [[
{field: 'id', hide: true},
{field: 'fieldName', title: '字段名'},
{field: 'showTitle', title: '显示的标题', edit: 'text'},
{field: 'fieldType', title: '字段类型', hide: true},
{field: 'dictType', title: '数据字典', hide: true},
{field: 'defaultValue', title: '默认值', edit: 'text', hide: true},
{
field: 'isRequired',
title: '是否必填',
templet: (data) => renderSwitch('isRequired', data)
},
{
field: 'isDisabled',
title: '是否禁用',
templet: (data) => renderSwitch('isDisabled', data)
},
{
field: 'isShow',
title: '是否显示',
templet: (data) => renderSwitch('isShow', data)
},
{field: 'sort', title: '显示顺序', edit: 'text'}
]],
done: (res) => this.tableLoadDoneListen(res),
onToolBarTable: ({event, config})=> {
if(event === 'save'){
const datas = [...this.dataMap.values()];
Util.post(`/sys/form/config/api/save`, {params: JSON.stringify(datas)}).then(res=>{
if(res.flag){
showOkMsg('保存成功')
}else{
showErrorMsg2('保存失败:'+res.msg)
}
})
}
}
});
gtable.on(`edit(${elemId})`, ({field, value, data}) => {
this.dataMap.get(data.id)[field] = value;
})
// 监听switch按钮
form.on(`switch(${elemId}-switch)`, (data) => this.switchChangeListen(data));
function renderSwitch(fieldName, data) {
const id = data.id, value = data[fieldName];
return `<input type="checkbox" id="${id}" name="${fieldName}" value="${value}" title="是|否" lay-skin="switch" lay-filter="${elemId}-switch" ${value ? 'checked' : ''} />`
}
}
tableLoadDoneListen(res) {
if (res.flag) {
res.records.map(record => this.dataMap.set(record.id + '', record));
}
}
switchChangeListen({elem}) {
const id = $(elem).attr('id'), name = $(elem).attr('name');
const value = this.dataMap.get(id)[name];
this.dataMap.get(id)[name] = !value;
}
}
layui.use(['form', 'gtable', 'dropdown', 'element'], function () {
const metadataForm = new FormConfigComponent(1, 'metadataFormTable', layui);
const fileUploadForm = new FormConfigComponent(2, 'fileUploadFormTable', layui);
});

@ -47,56 +47,40 @@
<div class="layui-tab-item layui-show"> <div class="layui-tab-item layui-show">
<div class="layui-form" lay-filter="details-form"> <div class="layui-form" lay-filter="details-form">
<div class="layui-form-item"> <div class="layui-form-item">
<label class="layui-form-label">数据名称</label> <label class="layui-form-label">数据表注释</label>
<div class="layui-input-block"> <div class="layui-input-block">
<input type="text" readonly class="layui-input" name="metadataName" <input class="layui-input" type="text" readonly th:value="${detailsData.metadataComment}">
th:value="${detailsData.metadataName}">
</div> </div>
</div> </div>
<div class="layui-form-item"> <div class="layui-form-item" th:each="field,iterStat : ${metadataFormConfig}" th:if="${field.isShow}">
<label class="layui-form-label">中文注释</label> <label class="layui-form-label" th:text="${field.showTitle}">字段名称</label>
<div class="layui-input-block">
<input type="text" readonly class="layui-input" name="metadataComment"
th:value="${detailsData.metadataComment}">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">数据密级</label>
<div class="layui-input-block">
<div dict-component="select" readonly dict-type="secret_level"
dict-name="secretLevel" th:data="${detailsData.secretLevel}"
id="dict-secret-level"></div>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">主题任务</label>
<div class="layui-input-block">
<input type="text" readonly class="layui-input" name="themeTask"
th:value="${detailsData.themeTask}">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">数据类型</label>
<div class="layui-input-block">
<div dict-component="select" readonly dict-type="data_type" dict-name="dataType"
th:data="${detailsData.dataType}" id="dict-data-type"></div>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">数据来源</label>
<div class="layui-input-block"> <div class="layui-input-block">
<div dict-component="select" readonly dict-type="data_source" <input type="hidden" name="metadataComment" th:if="${field.fieldName == 'metadataName'}">
dict-name="dataFrom" th:data="${detailsData.dataFrom}" <!-- 文本输入框-文本类型 -->
id="dict-data-form"></div> <input class="layui-input" type="text" readonly
</div> th:if="${field.fieldType == 'input'}"
</div> th:name="${field.fieldName}"
<div class="layui-form-item"> th:value="${detailsData[field.fieldName]}">
<label class="layui-form-label">任务时间</label> <!-- 文本输入框-日期类型 -->
<div class="layui-input-block"> <input class="layui-input" type="text" readonly
<input type="text" readonly class="layui-input" name="collectionTime" th:if="${field.fieldType == 'date'}"
th:value="${#dates.format(detailsData.collectionTime, 'yyyy-MM-dd HH:mm:ss')}"> th:name="${field.fieldName}"
th:value="${#dates.format(detailsData[field.fieldName], 'yyyy-MM-dd HH:mm:ss')}">
<!-- 文本输入框-文本域类型 -->
<textarea class="layui-textarea" readonly
th:if="${field.fieldType == 'textarea'}"
th:name="${field.fieldName}"
th:text="${detailsData[field.fieldName]}"></textarea>
<!-- 数据字典类型 -->
<div dict-component="select" readonly="readonly"
th:if="${field.fieldType == 'dict'}"
th:dict-type="${field.dictType}"
th:dict-name="${field.fieldName}"
th:data="${detailsData[field.fieldName]}"
th:id="${'dict-'+field.fieldName}"></div>
</div> </div>
</div> </div>
<div class="layui-form-item" th:each="labelSet, iterState:${LabelConfigSet}"> <div class="layui-form-item" th:each="labelSet, iterState:${LabelConfigSet}">
<label class="layui-form-label" th:text="${labelSet.fieldTitle}">标签类型</label> <label class="layui-form-label" th:text="${labelSet.fieldTitle}">标签类型</label>
<div class="layui-input-block label-set-component read-only" <div class="layui-input-block label-set-component read-only"

@ -29,6 +29,14 @@
class="layui-input" lay-verify="required"> class="layui-input" lay-verify="required">
</div> </div>
</div> </div>
<div class="layui-form-item">
<label class="layui-form-label">字典值</label>
<div class="layui-input-block">
<input type="text" name="dictValue" autocomplete="off" placeholder="字典值"
th:value="${dict.dictValue}"
class="layui-input" lay-verify="required">
</div>
</div>
<div class="layui-form-item"> <div class="layui-form-item">
<label class="layui-form-label">排序</label> <label class="layui-form-label">排序</label>
<div class="layui-input-block"> <div class="layui-input-block">

@ -8,32 +8,10 @@
<!-- 样式 --> <!-- 样式 -->
<link th:href="@{/css/common/contianer.css}" rel="stylesheet" type="text/css"/> <link th:href="@{/css/common/contianer.css}" rel="stylesheet" type="text/css"/>
<style> <style>
.layui-form-item {
display: flex;
justify-content: center;
}
.layui-form-label {
width: 90px;
}
.layui-inline {
width: 50%;
}
.layui-form-item .layui-input-inline {
width: calc(100% - 130px);
margin-right: 10px;
}
.webuploader-pick { .webuploader-pick {
width: auto !important; width: auto !important;
} }
.layui-card-body {
padding: 10px 10px;
line-height: 24px;
}
.layui-layer-loading .layui-layer-loading1 { .layui-layer-loading .layui-layer-loading1 {
height: 37px !important; height: 37px !important;
@ -49,7 +27,6 @@
background-color: #FFF; background-color: #FFF;
border-top: 1px solid #eee; border-top: 1px solid #eee;
} }
.star-mark{color: red; display: none}
</style> </style>
</head> </head>
@ -60,125 +37,73 @@
<div style="overflow: hidden; flex: 1"> <div style="overflow: hidden; flex: 1">
<div class="layui-upload" id="uploader-table"></div> <div class="layui-upload" id="uploader-table"></div>
</div> </div>
<div class="layui-form" lay-filter="file-form" <div class="layui-form dynamic-form" lay-filter="file-form"
style="border: 1px solid #eee; padding-top:15px; margin-bottom: 50px;"> style="border: 1px solid #eee; padding-top:15px; margin-bottom: 50px;"
<div class="layui-form-item"> th:object="${@securityUtil.getLoginSysUser()}">
<div class="layui-inline"> <div class="layui-form-item"
<label class="layui-form-label"><span style="color: red">*</span>文件密级</label> th:each="field,iterStat : ${uploadFormConfig}"
<div class="layui-input-inline"> th:if="${field.isShow}"
<div dict-component="select" dict-type="secret_level" dict-name="secretLevel" th:style="${field.fieldType == 'textarea' ? 'width: calc(100% - 30px);' : ''}"
dict-width="100%" id="dict-secret-level"></div> th:with="username=*{userName}">
</div> <label th:if="${field.isRequired}" class="layui-form-label">
</div> <label style="color: red">*</label>
<div class="layui-inline"> <label th:text="${field.showTitle}">*</label>
<label class="layui-form-label">是否演训数据</label> </label>
<div class="layui-input-inline"> <label th:if="${!field.isRequired}" class="layui-form-label" th:text="${field.showTitle}"></label>
<input class="layui-input" type="radio" name="exerciseData" value="0" title="否" checked lay-filter="exerciseData"/> <div class="layui-input-block">
<input class="layui-input" type="radio" name="exerciseData" value="1" title="是" lay-filter="exerciseData"/> <!-- 文本框类型 -->
</div> <input class="layui-input" type="text" autocomplete="off"
</div> th:if="${field.fieldType == 'input' || field.fieldType == 'date'}"
</div> th:name="${field.fieldName}"
<div class="layui-form-item"> th:value="${field.fieldName=='entryStaff'?username:''}"
<div class="layui-inline"> th:disabled="${field.isDisabled}"
<label class="layui-form-label"><span class="star-mark">*</span>任务时间</label> th:placeholder="${field.showTitle}"
<div class="layui-input-inline"> th:lay-verify="${field.isRequired ? 'required' : ''}">
<input class="layui-input" id="input-data" name="inputDate" type="text"> <!-- 文本域类型 -->
</div> <textarea class="layui-textarea" type="text" autocomplete="off"
</div> th:if="${field.fieldType == 'textarea'}"
<div class="layui-inline"> th:name="${field.fieldName}"
<label class="layui-form-label">录入人员</label> th:disabled="${field.isDisabled}"
<div class="layui-input-inline" th:object="${@securityUtil.getLoginSysUser()}"> th:placeholder="${field.showTitle}"
<input class="layui-input" name="entryStaff" type="text" readonly th:lay-verify="${field.isRequired ? 'required' : ''}"></textarea>
th:value="*{userName}"> <th:block th:if="${field.fieldType == 'radio' && field.isShow}">
</div> <input class="layui-inline" type="radio"
th:each="exp, stat : ${#strings.listSplit(field.dictType, ';')}"
th:with="tmp=${#strings.arraySplit(exp, '-')}, value=${tmp[0]}, title=${tmp[1]}, checked=${#arrays.length(tmp)==3?tmp[2]:false}"
th:name="${field.fieldName}"
th:value="${value}"
th:title="${title}"
th:checked="${checked}"
/>
</th:block>
<!-- 数据字典类型 -->
<div dict-component="select"
th:if="${field.fieldType == 'dict'}"
th:disabled="${field.isDisabled}"
th:dict-type="${field.dictType}"
th:dict-name="${field.fieldName}"
th:id="${'dict-'+field.fieldName}"></div>
</div> </div>
</div> </div>
<div class="layui-form-item"> <div class="layui-form-item" style="width: 100%" th:each="labelSet, iterState:${LabelConfigSet}">
<div class="layui-inline"> <label class="layui-form-label" th:text="${labelSet.fieldTitle}">标签类型</label>
<label class="layui-form-label"><span class="star-mark">*</span>文件来源</label> <div class="layui-input-block">
<div class="layui-input-inline"> <div class="label-set-component"
<div dict-component="select" dict-type="data_source" dict-name="source" th:data-id="${labelSet.id}"
dict-width="100%" id="dict-data-form"></div> th:data-field-title="${labelSet.fieldTitle}"
</div> th:data-label-id="${labelSet.labelId}"
</div> th:data-label-title="${labelSet.labelTitle}"
<div class="layui-inline"> th:data-label-id-path="${labelSet.labelIdPath}"
<label class="layui-form-label">目标/靶标类型</label> th:data-label-title-path="${labelSet.labelTitlePath}"
<div class="layui-input-inline"> style="width:calc(100% - 120px);margin-left: 0"></div>
<div dict-component="select" dict-type="target_type" dict-name="targetNumber"
dict-width="100%" id="dict-target-type"></div>
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label"><span class="star-mark">*</span>任务代号</label>
<div class="layui-input-inline">
<div dict-component="select" dict-type="task_code" dict-name="taskCode"
dict-width="100%" id="dict-task-code"></div>
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label"><span class="star-mark">*</span>任务性质</label>
<div class="layui-input-inline">
<div dict-component="select" dict-type="task_nature" dict-name="taskNature"
dict-width="100%" id="dict-task-nature"></div>
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label"><span class="star-mark">*</span>部队代号</label>
<div class="layui-input-inline">
<div dict-component="select" dict-type="troop_code" dict-name="troopCode"
dict-width="100%" id="dict-troop-code"></div>
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label"><span class="star-mark">*</span>装备型号</label>
<div class="layui-input-inline">
<div dict-component="select" dict-type="equipment_model" dict-name="equipmentModel"
dict-width="100%" id="dict-equipment-model"></div>
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">导弹编号</label>
<div class="layui-input-inline">
<div dict-component="select" dict-type="missile_number" dict-name="missileNumber"
dict-width="100%" id="dict-missile-number"></div>
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">主题任务</label>
<div class="layui-input-inline">
<input class="layui-input" name="themeTask" type="text">
</div>
</div> </div>
</div> </div>
<div class="layui-form-item layui-form-text"> <div class="layui-form-item other-label-item" style="width: 100%">
<label class="layui-form-label" style="margin-left: -10px;">文件描述</label> <label class="layui-form-label"><a class="label-type choose-data add-other" id="addOtherLabelBtn">添加</a>其他标签</label>
<div class="layui-input-block" style="width:calc(100% - 130px);margin-left: 0"> <div class="layui-input-block other-label-item">
<textarea class="layui-textarea" name="remark"></textarea> <div class="label-set-component other-label" th:data-field-title="其他标签"></div>
</div> </div>
</div> </div>
<div class="layui-form-item" th:each="labelSet, iterState:${LabelConfigSet}">
<label class="layui-form-label" th:text="${labelSet.fieldTitle}">标签类型</label>
<div class="layui-input-block label-set-component"
th:data-id="${labelSet.id}"
th:data-field-title="${labelSet.fieldTitle}"
th:data-label-id="${labelSet.labelId}"
th:data-label-title="${labelSet.labelTitle}"
th:data-label-id-path="${labelSet.labelIdPath}"
th:data-label-title-path="${labelSet.labelTitlePath}"
style="width:calc(100% - 120px);margin-left: 0"></div>
</div>
<div class="layui-form-item other-label-item">
<label class="layui-form-label"><a class="label-type choose-data add-other"
id="addOtherLabelBtn">添加</a>其他标签</label>
<div class="layui-input-block label-set-component other-label" th:data-field-title="其他标签"
style="width:calc(100% - 120px);margin-left: 0"></div>
</div>
</div> </div>
<div class="bottom-btns"> <div class="bottom-btns">
<button type="button" class="layui-btn layui-btn-sm layui-btn-normal btn-ok" id="fileUploadAction"> <button type="button" class="layui-btn layui-btn-sm layui-btn-normal btn-ok" id="fileUploadAction">

@ -15,10 +15,6 @@
.layui-form-item .layui-input-inline { .layui-form-item .layui-input-inline {
width: 260px; width: 260px;
} }
.label-set-component{
margin-left: 120px;
}
.star-mark{color: red; display: none}
</style> </style>
<script th:inline="javascript"> <script th:inline="javascript">
const file = /*[[${file}]]*/ {}; const file = /*[[${file}]]*/ {};
@ -34,7 +30,7 @@
<div class="layui-upload"> <div class="layui-upload">
<h2 th:text="${file.fileName}" style="margin-bottom: 10px;"></h2> <h2 th:text="${file.fileName}" style="margin-bottom: 10px;"></h2>
</div> </div>
<form class="layui-form" id="file-form" lay-filter="file-form" style="border: 1px solid #eee; padding-top:15px"> <form class="layui-form dynamic-form" id="file-form" lay-filter="file-form" style="border: 1px solid #eee; padding-top:15px">
<input type="hidden" name="id"> <input type="hidden" name="id">
<input type="hidden" name="fileName"> <input type="hidden" name="fileName">
<input type="hidden" name="entityId"> <input type="hidden" name="entityId">
@ -48,107 +44,72 @@
<input type="hidden" name="currentChunkIndex"> <input type="hidden" name="currentChunkIndex">
<input type="hidden" name="MD5"> <input type="hidden" name="MD5">
<input type="hidden" name="isFirst"> <input type="hidden" name="isFirst">
<div class="layui-form-item"> <div class="layui-form-item"
<div class="layui-inline"> th:each="field,iterStat : ${uploadFormConfig}"
<label class="layui-form-label"><span style="color: red">*</span>文件密级</label> th:if="${field.isShow}"
<div class="layui-input-inline"> th:style="${field.fieldType == 'textarea' ? 'width: calc(100% - 30px);' : ''}"
<div dict-component="select" dict-type="secret_level" dict-name="secretLevel" th:with="username=*{userName}">
dict-width="100%" id="dict-secret-level"></div> <label th:if="${field.isRequired}" class="layui-form-label">
</div> <label style="color: red">*</label>
</div> <label th:text="${field.showTitle}">*</label>
<div class="layui-inline"> </label>
<label class="layui-form-label">是否演训数据</label> <label th:if="${!field.isRequired}" class="layui-form-label" th:text="${field.showTitle}"></label>
<div class="layui-input-inline"> <div class="layui-input-block">
<input class="layui-input" type="radio" name="exerciseData" value="0" title="否" checked lay-filter="exerciseData"/> <!-- 文本框类型 -->
<input class="layui-input" type="radio" name="exerciseData" value="1" title="是" lay-filter="exerciseData"/> <input class="layui-input" type="text" autocomplete="off"
</div> th:if="${field.fieldType == 'input' || field.fieldType == 'date'}"
</div> th:name="${field.fieldName}"
</div> th:value="${field.fieldName}"
<div class="layui-form-item"> th:disabled="${field.isDisabled}"
<div class="layui-inline"> th:placeholder="${field.showTitle}"
<label class="layui-form-label">录入人员</label> th:readonly="${field.fieldName == 'inputDate' || field.fieldName == 'entryStaff'}"
<div class="layui-input-inline"> th:lay-verify="${field.isRequired ? 'required' : ''}">
<input class="layui-input" name="entryStaff" type="text" readonly> <!-- 文本域类型 -->
</div> <textarea class="layui-textarea" type="text" autocomplete="off"
<label class="layui-form-label"><span class="star-mark">*</span>任务时间</label> th:if="${field.fieldType == 'textarea'}"
<div class="layui-input-inline"> th:name="${field.fieldName}"
<input class="layui-input" id="input-data" name="inputDate" type="text"> th:disabled="${field.isDisabled}"
</div> th:placeholder="${field.showTitle}"
</div> th:lay-verify="${field.isRequired ? 'required' : ''}"></textarea>
</div> <th:block th:if="${field.fieldType == 'radio' && field.isShow}">
<div class="layui-form-item"> <input class="layui-inline" type="radio"
<div class="layui-inline"> th:each="exp, stat : ${#strings.listSplit(field.dictType, ';')}"
<label class="layui-form-label"><span class="star-mark">*</span>文件来源</label> th:with="tmp=${#strings.arraySplit(exp, '-')}, value=${tmp[0]}, title=${tmp[1]}, checked=${#arrays.length(tmp)==3?tmp[2]:false}"
<div class="layui-input-inline"> th:name="${field.fieldName}"
<div dict-component="select" dict-type="data_source" dict-name="source" th:value="${value}"
dict-width="100%" id="dict-data-form"></div> th:title="${title}"
</div> th:checked="${checked}"
<label class="layui-form-label">目标/靶标类型</label> />
<div class="layui-input-inline"> </th:block>
<div dict-component="select" dict-type="target_type" dict-name="targetNumber" <!-- 数据字典类型 -->
dict-width="100%" id="dict-target-type"></div> <div dict-component="select"
</div> th:if="${field.fieldType == 'dict'}"
</div> th:disabled="${field.isDisabled}"
</div> th:dict-type="${field.dictType}"
<div class="layui-form-item"> th:dict-name="${field.fieldName}"
<div class="layui-inline"> th:id="${'dict-'+field.fieldName}"></div>
<label class="layui-form-label"><span class="star-mark">*</span>任务代号</label>
<div class="layui-input-inline">
<div dict-component="select" dict-type="task_code" dict-name="taskCode"
dict-width="100%" id="dict-task-code"></div>
</div>
<label class="layui-form-label"><span class="star-mark">*</span>任务性质</label>
<div class="layui-input-inline">
<div dict-component="select" dict-type="task_nature" dict-name="taskNature"
dict-width="100%" id="dict-task-nature"></div>
</div>
</div> </div>
</div> </div>
<div class="layui-form-item"> <div class="layui-form-item" style="width: 100%" th:each="labelSet, iterState:${LabelConfigSet}">
<div class="layui-inline">
<label class="layui-form-label"><span class="star-mark">*</span>部队代号</label>
<div class="layui-input-inline">
<div dict-component="select" dict-type="troop_code" dict-name="troopCode"
dict-width="100%" id="dict-troop-code"></div>
</div>
<label class="layui-form-label"><span class="star-mark">*</span>装备型号</label>
<div class="layui-input-inline">
<div dict-component="select" dict-type="equipment_model" dict-name="equipmentModel"
dict-width="100%" id="dict-equipment-model"></div>
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">导弹编号</label>
<div class="layui-input-inline">
<div dict-component="select" dict-type="missile_number" dict-name="missileNumber"
dict-width="100%" id="dict-missile-number"></div>
</div>
</div>
</div>
<div class="layui-form-item layui-form-text">
<label class="layui-form-label">文件描述</label>
<div class="layui-input-block" style="margin-left: 120px; width:640px;">
<textarea class="layui-textarea" name="remark"></textarea>
</div>
</div>
<div class="layui-form-item" th:each="labelSet, iterState:${LabelConfigSet}">
<label class="layui-form-label" th:text="${labelSet.fieldTitle}">标签类型</label> <label class="layui-form-label" th:text="${labelSet.fieldTitle}">标签类型</label>
<div class="layui-input-block label-set-component" <div class="layui-input-block">
th:data-id="${labelSet.id}" <div class="label-set-component"
th:data-field-title="${labelSet.fieldTitle}" th:data-id="${labelSet.id}"
th:data-label-id="${labelSet.labelId}" th:data-field-title="${labelSet.fieldTitle}"
th:data-label-title="${labelSet.labelTitle}" th:data-label-id="${labelSet.labelId}"
th:data-label-id-path="${labelSet.labelIdPath}" th:data-label-title="${labelSet.labelTitle}"
th:data-label-title-path="${labelSet.labelTitlePath}"></div> th:data-label-id-path="${labelSet.labelIdPath}"
th:data-label-title-path="${labelSet.labelTitlePath}"></div>
</div>
</div> </div>
<div class="layui-form-item other-label-item"> <div class="layui-form-item" style="width: 100%">
<label class="layui-form-label"><a class="label-type choose-data add-other" id="addOtherLabelBtn">添加</a>其他标签</label> <label class="layui-form-label"><a class="label-type choose-data add-other" id="addOtherLabelBtn">添加</a>其他标签</label>
<div class="layui-input-block label-set-component other-label" th:data-field-title="其他标签"></div> <div class="layui-input-block other-label-item">
<div class="label-set-component other-label" th:data-field-title="其他标签"></div>
</div>
</div> </div>
<button class="layui-btn layui-btn-sm" id="btn_submit" <button class="layui-btn layui-btn-sm" id="btn_submit"
style="position: absolute; left: -50px; height: 0; border:0"> style="width: 100%;position: absolute; left: -50px; height: 0; border:0">
</button> </button>
</form> </form>
</div> </div>

@ -8,6 +8,11 @@
<!-- 样式 --> <!-- 样式 -->
<link th:href="@{/css/common/contianer.css}" rel="stylesheet" type="text/css"/> <link th:href="@{/css/common/contianer.css}" rel="stylesheet" type="text/css"/>
<link th:href="@{/css/sys/file/fileView.css}" rel="stylesheet" type="text/css"/> <link th:href="@{/css/sys/file/fileView.css}" rel="stylesheet" type="text/css"/>
<style>
.layui-input-block{
margin-left: 0;
}
</style>
<script th:inline="javascript"> <script th:inline="javascript">
const file = /*[[${fileData}]]*/ {}; const file = /*[[${fileData}]]*/ {};
const fileViewUrl = /*[[${fileViewUrl}]]*/ ''; const fileViewUrl = /*[[${fileViewUrl}]]*/ '';
@ -35,45 +40,13 @@
<label class="field-name">文件名称</label> <label class="field-name">文件名称</label>
<label class="field-value" name="fileName"></label> <label class="field-value" name="fileName"></label>
</div> </div>
<div class="file-property"> <div class="file-property"
<label class="field-name">文件密级</label> th:each="field,iterStat : ${uploadFormConfig}"
<label class="field-value" name="secretLevel"></label> th:if="${field.isShow}"
</div> th:style="${field.fieldType == 'textarea' ? 'width: calc(100% - 30px);' : ''}"
<div class="file-property"> th:with="username=*{userName}">
<label class="field-name">录入人员</label> <label class="field-name" th:text="${field.showTitle}">文件名称</label>
<label class="field-value" name="entryStaff"></label> <label class="field-value" th:name="${field.fieldName}" th:value="${field.fieldName}"></label>
</div>
<div class="file-property">
<label class="field-name">导弹编号</label>
<label class="field-value" name="missileNumber"></label>
</div>
<div class="file-property">
<label class="field-name">目标/靶标类型</label>
<label class="field-value" name="targetNumber"></label>
</div>
<div class="file-property">
<label class="field-name">文件来源</label>
<label class="field-value" name="source"></label>
</div>
<div class="file-property">
<label class="field-name">目标性质</label>
<label class="field-value" name="taskNature"></label>
</div>
<div class="file-property">
<label class="field-name">部队代号</label>
<label class="field-value" name="troopCode"></label>
</div>
<div class="file-property">
<label class="field-name">装备型号</label>
<label class="field-value" name="equipmentModel"></label>
</div>
<div class="file-property">
<label class="field-name">任务时间</label>
<label class="field-value" th:text="${file_inputDate}"></label>
</div>
<div class="file-property">
<label class="field-name">文件描述</label>
<label class="field-value" name="remark"></label>
</div> </div>
<div class="file-property" th:each="labelSet, iterState:${LabelConfigSet}"> <div class="file-property" th:each="labelSet, iterState:${LabelConfigSet}">
<label class="field-name" th:text="${labelSet.fieldTitle}">标签类型</label> <label class="field-name" th:text="${labelSet.fieldTitle}">标签类型</label>
@ -87,7 +60,7 @@
</div> </div>
<div class="file-property"> <div class="file-property">
<label class="field-name">其他标签</label> <label class="field-name">其他标签</label>
<div class=" other-label-item read-only"></div> <div class="other-label-item layui-input-block read-only"></div>
</div> </div>
<div class="layui-form-item" style="display: flex; flex-direction: column;"> <div class="layui-form-item" style="display: flex; flex-direction: column;">
<input type="hidden" name="id"> <input type="hidden" name="id">

@ -0,0 +1,57 @@
<!DOCTYPE html>
<!--解决idea thymeleaf 表达式模板报红波浪线-->
<!--suppress ALL -->
<html xmlns:th="http://www.thymeleaf.org">
<head>
<!-- 引入公用部分 -->
<script th:replace="common/head::static"></script>
<!-- 样式 -->
<link th:href="@{/css/common/contianer.css}" rel="stylesheet" type="text/css"/>
<script th:inline="javascript">
const FormTypeEnum = /*[[${FormTypeEnum}]]*/ {};
</script>
</head>
<body>
<div class="layui-row">
<!---->
<div class="layui-col-md12">
<div class="layui-card">
<div class="layui-card-header layui-hide"></div>
<div class="layui-card-body">
<div class="layui-tab layui-tab-brief" lay-filter="form-config-tab">
<ul class="layui-tab-title">
<li class="layui-this" data-form-type="1">数据资源注册表单</li>
<li data-form-type="2">文件上传表单</li>
</ul>
<div class="layui-tab-content" style="padding: 0">
<div class="layui-tab-item layui-show">
<table class="layui-hide" id="metadataFormTable"
lay-filter="metadataFormTable"></table>
</div>
<div class="layui-tab-item">
<table class="layui-hide" id="fileUploadFormTable"
lay-filter="fileUploadFormTable"></table>
</div>
<script type="text/html" id="tableTool">
<div class="layui-btn-container">
<button class="layui-btn layui-btn-sm" lay-event="save">保存修改</button>
</div>
</script>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
<!-- js -->
<script th:replace="common/head::static-foot"></script>
<script th:src="@{/js/sys/form/formConfig.js}"></script>
<script>
const sizeInit = () => {
$(".layui-card-body").height(window.innerHeight - 43 - 40 - 20);
}
window.onresize = sizeInit;
sizeInit();
</script>
</html>