TableServiceCmdService.java 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  1. package com.boman.system.common;
  2. import com.alibaba.fastjson.JSON;
  3. import com.alibaba.fastjson.JSONArray;
  4. import com.alibaba.fastjson.JSONObject;
  5. import com.boman.common.core.utils.SecurityUtils;
  6. import com.boman.common.core.utils.collection.CollectionUtils;
  7. import com.boman.common.core.utils.obj.ObjectUtils;
  8. import com.boman.common.core.web.domain.AjaxResult;
  9. import com.boman.common.redis.RedisKey;
  10. import com.boman.common.redis.service.RedisService;
  11. import com.boman.gen.controller.MyController;
  12. import com.boman.gen.domain.GenTable;
  13. import com.boman.gen.domain.GenTableColumn;
  14. import com.boman.system.mapper.StandardlyMapper;
  15. import com.boman.system.service.*;
  16. import com.boman.system.utils.IdUtils;
  17. import com.google.common.collect.Lists;
  18. import org.slf4j.Logger;
  19. import org.slf4j.LoggerFactory;
  20. import org.springframework.stereotype.Component;
  21. import javax.annotation.Resource;
  22. import java.sql.Timestamp;
  23. import java.util.*;
  24. import java.util.stream.Collectors;
  25. import static com.boman.common.core.utils.obj.ObjectUtils.requireNonNull;
  26. import static com.boman.common.core.utils.obj.ObjectUtils.requiredNonNull;
  27. import static com.boman.system.common.FormDataConstant.CONDITION;
  28. import static com.boman.system.common.FormDataConstant.SHOW_DATA;
  29. /**
  30. * @author shiqian
  31. * @description
  32. * @date 2021年03月22日 09:51
  33. **/
  34. @Component
  35. public class TableServiceCmdService {
  36. @Resource
  37. private IBaseDeleteService deleteService;
  38. @Resource
  39. private IBaseSaveService saveService;
  40. @Resource
  41. private RedisService redisService;
  42. @Resource
  43. private IBaseSelectService selectService;
  44. @Resource
  45. private IBaseSubmitService submitService;
  46. private static final Logger LOGGER = LoggerFactory.getLogger(TableServiceCmdService.class);
  47. private BaseTableDTO packTableDTO(BaseTableSaveDTO baseTableSaveDTO) {
  48. BaseTableDTO baseTableDTO = new BaseTableDTO();
  49. baseTableDTO.setFixedData(baseTableSaveDTO.getFixedData());
  50. baseTableDTO.setObjId(baseTableSaveDTO.getObjId());
  51. baseTableDTO.setTable(baseTableSaveDTO.getTable());
  52. return baseTableDTO;
  53. }
  54. public final AjaxResult objectSave(BaseTableSaveDTO baseTableSaveDTO) {
  55. BaseTableDTO baseTableDTO = packTableDTO(baseTableSaveDTO);
  56. TableServiceContext context = TableServiceContext.createFrom(baseTableDTO);
  57. // 拿到pkName和maxId
  58. List<GenTableColumn> columns = context.getTable().getColumns();
  59. String pkName = IdUtils.getPkName(columns);
  60. requireNonNull(pkName, "主键名称为空");;
  61. //
  62. List<String> allColumnNameList = columns.stream()
  63. .map(GenTableColumn::getColumnName)
  64. .collect(Collectors.toList());
  65. Long maxId = IdUtils.getMaxId(baseTableDTO.getTable(), pkName);
  66. RowResult rowResult = saveService.insertRow(context.getRealTableName(), pkName, maxId, context.getRows().get(0), allColumnNameList);
  67. if (RowResult.checkSuccess(rowResult)) {
  68. LOGGER.info("保存成功,封装到数据库的数据为: {}", JSON.toJSONString(rowResult.getData()));
  69. } else {
  70. LOGGER.error("保存失败,保持的原始数据为: {}", JSON.toJSONString(baseTableSaveDTO));
  71. }
  72. return AjaxResult.success(rowResult);
  73. }
  74. /**
  75. * 功能描述: 通用删除接口 (真的删除)
  76. *
  77. * @param dto 前台传过来的dto
  78. * @return com.boman.common.core.web.domain.AjaxResult
  79. */
  80. public AjaxResult objectDelete(BaseTableSaveDTO dto) {
  81. requireNonNull(dto.getTable());
  82. Long[] idArr = CollectionUtils.listToArray(dto.getIdList());
  83. requiredNonNull(idArr);
  84. // 拿到pkName
  85. GenTable genTable = getTableFromRedisByTableName(RedisKey.TABLE_INFO, dto.getTable());
  86. String pkName = IdUtils.getPkName(genTable.getColumns());
  87. RowResult rowResult = deleteService.objectDelete(idArr, dto.getTable(), requireNonNull(pkName, "主键名称为空"));
  88. LOGGER.info(rowResult.getMessage() + ", id: {}", Arrays.toString(idArr));
  89. return AjaxResult.success(rowResult);
  90. }
  91. /**
  92. * 功能描述: 通用删除接口 (真的删除)
  93. *
  94. * @param dto 前台传过来的dto
  95. * @return com.boman.common.core.web.domain.AjaxResult
  96. */
  97. public AjaxResult objectLogicDelete(BaseTableSaveDTO dto) {
  98. requireNonNull(dto.getTable());
  99. Long[] idArr = CollectionUtils.listToArray(dto.getIdList());
  100. requiredNonNull(idArr);
  101. // 拿到pkName
  102. GenTable genTable = getTableFromRedisByTableName(RedisKey.TABLE_INFO, dto.getTable());
  103. String pkName = IdUtils.getPkName(genTable.getColumns());
  104. JSONObject jsonObject= new JSONObject();
  105. jsonObject.put(dto.getLogicDelName(), dto.getLogicDelValue());
  106. RowResult rowResult = deleteService.objectLogicDelete(idArr, dto.getTable(), requireNonNull(pkName, "主键名称为空"), jsonObject);
  107. LOGGER.info(rowResult.getMessage() + ", id: {}", Arrays.toString(idArr));
  108. return AjaxResult.success(rowResult);
  109. }
  110. /**
  111. * 功能描述: 获取单表单数据
  112. *
  113. * @param dto condition
  114. * @return com.boman.common.core.web.domain.AjaxResult
  115. */
  116. public AjaxResult queryList(BaseTableSaveDTO dto) {
  117. requireNonNull(dto.getTable());
  118. // 拿到每个字段对应的查询类型,=、 like、 >、 <
  119. GenTable genTable = getTableFromRedisByTableName(RedisKey.TABLE_INFO, dto.getTable());
  120. JSONObject fixedData = dto.getFixedData();
  121. fixedData = ObjectUtils.ifNullSetEmpty(fixedData);
  122. // 查询条件
  123. JSONObject condition = ObjectUtils.ifNullSetEmpty(fixedData.getJSONObject(CONDITION));
  124. List<GenTableColumn> columns = genTable.getColumns();
  125. // 封装好以后的查询条件
  126. JSONObject packCondition = ObjectUtils.ifNullSetEmpty(packColCondition(columns, condition));
  127. // 需要返回到前台的列
  128. JSONArray showData = ObjectUtils.ifNullSetEmpty(fixedData.getJSONArray(SHOW_DATA));
  129. JSONObject rows = new JSONObject();
  130. int total = selectService.countByCondition(genTable.getTableName(), condition, packCondition);
  131. rows.put(FormDataConstant.PAGE_TOTAL, total);
  132. if (total <= 0) {
  133. rows.put(FormDataConstant.PAGE_ROWS, null);
  134. return AjaxResult.success(rows);
  135. }
  136. List<JSONObject> result = selectService.selectByCondition(genTable.getTableName(), condition, packCondition
  137. , showData, dto.getOrderBy(), dto.getLimit(), dto.getOffset());
  138. rows.put(FormDataConstant.PAGE_ROWS, result);
  139. return AjaxResult.success(rows);
  140. }
  141. /**
  142. * 功能描述: 获取单表单数据
  143. *
  144. * @param dto condition
  145. * @return com.boman.common.core.web.domain.AjaxResult
  146. */
  147. public AjaxResult getObject(BaseTableSaveDTO dto) {
  148. requireNonNull(dto.getTable());
  149. // 拿到每个字段对应的查询类型,=、 like、 >、 <
  150. // 拿到pkName
  151. GenTable genTable = getTableFromRedisByTableName(RedisKey.TABLE_INFO, dto.getTable());
  152. String pkName = IdUtils.getPkName(genTable.getColumns());
  153. JSONObject fixedData = dto.getFixedData();
  154. fixedData = ObjectUtils.ifNullSetEmpty(fixedData);
  155. Long id = fixedData.getLong(FormDataConstant.ID);
  156. requireNonNull(id);
  157. // 默认查所有字段,不支持自定义
  158. JSONObject jsonObject = selectService.selectById(genTable.getTableName(), pkName, id);
  159. return AjaxResult.success(jsonObject);
  160. }
  161. /**
  162. * 功能描述: 封装成查询条件 key: 列名, value:查询条件_查询类别
  163. * eg: [{"config_name":"系统配置_like"}, {"config_name":"_like"}]
  164. *
  165. * @param columns columns
  166. * @return com.alibaba.fastjson.JSONObject
  167. */
  168. private JSONObject packColCondition(List<GenTableColumn> columns, JSONObject condition) {
  169. requireNonNull(columns);
  170. JSONObject result = new JSONObject(columns.size());
  171. for (Map.Entry<String, Object> entry : condition.entrySet()) {
  172. String key = entry.getKey();
  173. Object value = entry.getValue();
  174. for (GenTableColumn column : columns) {
  175. // long string collection 暂时只作此三种类型判断
  176. if (column.getColumnName().equalsIgnoreCase(key) && ObjectUtils.isNotEmpty(value)) {
  177. // columnType 作为判断需不需要转义的一个标准,防止索引失效
  178. result.put(key, packValue(String.valueOf(value), column.getQueryType(), column.getColumnType()));
  179. break;
  180. }
  181. }
  182. }
  183. return result;
  184. }
  185. /**
  186. * 功能描述: 获取表单查询字段、按钮、表头
  187. * 注意: 都是从redis中拿的,如果数据库和redis不一致,则需刷新一下redis
  188. * 刷新的入口为 {@link MyController#loadTable(com.boman.gen.domain.GenTable)}
  189. *
  190. * eg:{
  191. * "table": "sys_config",
  192. * }
  193. *
  194. * @param condition condition
  195. * @return com.boman.common.core.web.domain.AjaxResult
  196. */
  197. public AjaxResult getTableQuery(BaseTableSaveDTO condition) {
  198. GenTable genTable = getTableFromRedisByTableName(RedisKey.TABLE_INFO, condition.getTable());
  199. List<GenTableColumn> columns = genTable.getColumns();
  200. JSONObject jsonObject = new JSONObject();
  201. // 查询字段
  202. ArrayList<GenTableColumn> queryList = Lists.newArrayListWithCapacity(16);
  203. for (GenTableColumn column : columns) {
  204. if (GenTableColumn.IS_QUERY.equalsIgnoreCase(column.getIsQuery())) {
  205. queryList.add(column);
  206. }
  207. }
  208. jsonObject.put(FormDataConstant.QUERY_LIST, queryList);
  209. // genTable.getMenuRole() 暂时数据库没有数据,
  210. jsonObject.put(FormDataConstant.BUTTON_LIST, genTable.getMenuRole());
  211. // 表头
  212. List<GenTableColumn> tableHeadList = columns.stream()
  213. .filter(genTableColumn -> GenTableColumn.IS_LIST.equals(genTableColumn.getIsList()))
  214. .collect(Collectors.toList());
  215. jsonObject.put(FormDataConstant.TABLE_HEAD_LIST, tableHeadList);
  216. return AjaxResult.success(jsonObject);
  217. }
  218. /**
  219. * 功能描述: 封装查询条件,在拼sql的时候按照此规则去取值
  220. * {@link StandardlyMapper.SqlProvider#selectByCondition(java.util.Map)}
  221. *
  222. * @param value 查询的值
  223. * @param queryType queryType
  224. * @param columnType columnType
  225. * @return java.lang.String
  226. */
  227. public String packValue(String value, String queryType, String columnType) {
  228. requireNonNull(value);
  229. requireNonNull(queryType);
  230. return value + "_" + queryType + "_" + columnType;
  231. }
  232. /**
  233. * 功能描述: 获取表单子表
  234. *
  235. * @param condition condition
  236. * @return com.boman.common.core.web.domain.AjaxResult
  237. */
  238. public AjaxResult objectTab(BaseTableSaveDTO condition) {
  239. GenTable genTable = getTableFromRedisByTableName(RedisKey.RELATION, condition.getTable());
  240. List<GenTable> childTableList = genTable.getRelationList();
  241. // 此表没有关联子表,查啥查
  242. requireNonNull(childTableList);
  243. for (GenTable childTable : childTableList) {
  244. String childTableName = childTable.getTableName();
  245. }
  246. return AjaxResult.success();
  247. }
  248. /**
  249. * 功能描述: 表单提交接口
  250. *
  251. * @param condition condition
  252. * @param isSubmit 提交true, 反提交false
  253. * @return com.boman.common.core.web.domain.AjaxResult
  254. */
  255. public AjaxResult objectSubmit(BaseTableSaveDTO condition, boolean isSubmit) {
  256. GenTable genTable = getTableFromRedisByTableName(RedisKey.TABLE_INFO, condition.getTable());
  257. List<JSONObject> commitData = condition.getCommitData();
  258. requireNonNull(commitData, "啥都不提交, 调什么接口??");
  259. String tableName = requireNonNull(genTable.getTableName());
  260. String pkName = IdUtils.getPkName(genTable.getColumns());
  261. // 先去查出之前的状态
  262. List<Long> idList = commitData.stream().map(jsonObject -> jsonObject.getLong(FormDataConstant.ID))
  263. .collect(Collectors.toList());
  264. JSONArray showData = new JSONArray();
  265. showData.add(FormDataConstant.STATUS);
  266. showData.add(pkName);
  267. List<JSONObject> beforeList = selectService.selectByIdList(tableName, pkName, idList, showData);
  268. requireNonNull(beforeList);
  269. for (JSONObject commitDatum : commitData) {
  270. String dbStatus = getStatusFromFormData(commitDatum, beforeList);
  271. // 只能是未提交的状态下,才能调用提交
  272. if (isSubmit) {
  273. // 只能是未提交的状态下,才能调用提交, 下面是不允许
  274. if (!SubmitConstant.NOT_SUBMIT.equals(dbStatus)) {
  275. commitDatum.put(SubmitConstant.SUBMIT_RESULT, SubmitConstant.NOT_ALLOWED);
  276. } else {
  277. commitDatum.put(SubmitConstant.SUBMIT_USERID, 123);
  278. commitDatum.put(SubmitConstant.SUBMIT_TIME, new Timestamp(System.currentTimeMillis()));
  279. int effective = submitService.handlerSubmit(tableName, pkName, commitDatum, commitDatum.getLong(FormDataConstant.ID));
  280. if (effective > 0) {
  281. commitDatum.put(SubmitConstant.SUBMIT_RESULT, SubmitConstant.SUCCESS);
  282. } else {
  283. commitDatum.put(SubmitConstant.SUBMIT_RESULT, SubmitConstant.FAIL);
  284. }
  285. }
  286. } else {
  287. // 只有在已提交的情况下才能反提交, 下面是不允许
  288. if (!SubmitConstant.SUBMITTED.equals(dbStatus)) {
  289. commitDatum.put(SubmitConstant.SUBMIT_RESULT, SubmitConstant.NOT_ALLOWED);
  290. } else {
  291. commitDatum.put(SubmitConstant.SUBMIT_USERID, 123);
  292. commitDatum.put(SubmitConstant.SUBMIT_TIME, new Timestamp(System.currentTimeMillis()));
  293. int effective = submitService.handlerSubmit(tableName, pkName, commitDatum, commitDatum.getLong(FormDataConstant.ID));
  294. if (effective > 0) {
  295. commitDatum.put(SubmitConstant.SUBMIT_RESULT, SubmitConstant.SUCCESS);
  296. } else {
  297. commitDatum.put(SubmitConstant.SUBMIT_RESULT, SubmitConstant.FAIL);
  298. }
  299. }
  300. }
  301. }
  302. return AjaxResult.success(commitData);
  303. }
  304. private String getStatusFromFormData(JSONObject next, List<JSONObject> commitData) {
  305. for (JSONObject jsonObject : commitData) {
  306. if (jsonObject.getLong(FormDataConstant.ID).equals(next.getLong(FormDataConstant.ID))) {
  307. return jsonObject.getString(FormDataConstant.STATUS);
  308. }
  309. }
  310. throw new IllegalArgumentException("不可能没有一个合适的");
  311. }
  312. // todo redis中未找到,要去查数据库,然后再塞进去
  313. private GenTable getTableFromRedisByTableName(String redisKeyPrefix, String tableName){
  314. GenTable genTable = redisService.getCacheObject(redisKeyPrefix + requireNonNull(tableName));
  315. return requireNonNull(genTable);
  316. }
  317. }