T insert(T obj);
+
+ /**
+ * 将一个对象按FieldFilter过滤后,插入到一个数据源。
+ *
+ * dao.insert(pet, FieldFilter.create(Pet.class, FieldMatcher.create(false)));
+ *
+ * @param obj 要被插入的对象
+ * @param filter 字段过滤器, 其中FieldMatcher.isIgnoreId生效
+ * @return 插入后的对象
+ * @see Dao#insert(Object)
+ */
+ T insert(T obj, FieldFilter filter);
+
+ /**
+ * 根据对象的主键(@Id/@Name/@Pk)先查询, 如果存在就更新, 不存在就插入
+ *
+ * @param obj 对象
+ * @return 原对象
+ */
+ T insertOrUpdate(T obj);
+
+ /**
+ * 根据对象的主键(@Id/@Name/@Pk)先查询, 如果存在就更新, 不存在就插入
+ *
+ * @param obj 对象
+ * @param insertFieldFilter 插入时的字段过滤, 可以是null
+ * @param updateFieldFilter 更新时的字段过滤,可以是null
+ * @return 原对象
+ */
+ T insertOrUpdate(T obj, FieldFilter insertFieldFilter, FieldFilter updateFieldFilter);
+
+ /**
+ * 自由的向一个数据表插入一条数据
+ *
+ * @param tableName 表名
+ * @param chain 数据名值链
+ */
+ void insert(String tableName, Chain chain);
+
+ /**
+ * 快速插入一个对象,对象的 '@Prev' 以及 '@Next' 在这个函数里不起作用
+ *
+ * @param obj
+ * @return
+ */
+ T fastInsert(T obj);
+
+ /**
+ * 将对象插入数据库同时,也将符合一个正则表达式的所有关联字段关联的对象统统插入相应的数据库
+ *
+ * 关于关联字段更多信息,请参看 '@One' | '@Many' | '@ManyMany' 更多的描述
+ *
+ * @param obj 数据对象
+ * @param regex 正则表达式,描述了什么样的关联字段将被关注。如果为 null,则表示全部的关联字段都会被插入
+ * @return 数据对象本身
+ * @see org.nutz.dao.entity.annotation.One
+ * @see org.nutz.dao.entity.annotation.Many
+ * @see org.nutz.dao.entity.annotation.ManyMany
+ */
+ T insertWith(T obj, String regex);
+
+ /**
+ * 根据一个正则表达式,仅将对象所有的关联字段插入到数据库中,并不包括对象本身
+ *
+ * @param obj 数据对象
+ * @param regex 正则表达式,描述了什么样的关联字段将被关注。如果为 null,则表示全部的关联字段都会被插入
+ * @return 数据对象本身
+ * @see org.nutz.dao.entity.annotation.One
+ * @see org.nutz.dao.entity.annotation.Many
+ * @see org.nutz.dao.entity.annotation.ManyMany
+ */
+ T insertLinks(T obj, String regex);
+
+ /**
+ * 将对象的一个或者多个,多对多的关联信息,插入数据表
+ *
+ * @param obj 对象
+ * @param regex 正则表达式,描述了那种多对多关联字段将被执行该操作
+ * @return 对象自身
+ * @see org.nutz.dao.entity.annotation.ManyMany
+ */
+ T insertRelation(T obj, String regex);
+
+ /**
+ * 更新数据
+ *
+ * @param obj
+ * @return
+ */
+ int update(Object obj);
+
+ /**
+ * 更新数据忽略值为null的字段
+ *
+ * @param obj
+ * @return
+ */
+ int updateIgnoreNull(Object obj);
+
+ /**
+ * 部分更新实体表
+ *
+ * @param chain
+ * @param cnd
+ * @return
+ */
+ int update(Chain chain, Condition cnd);
+
+ /**
+ * 部分更新表
+ *
+ * @param tableName
+ * @param chain
+ * @param cnd
+ * @return
+ */
+ int update(String tableName, Chain chain, Condition cnd);
+
+ /**
+ * 将对象更新的同时,也将符合一个正则表达式的所有关联字段关联的对象统统更新
+ *
+ * 关于关联字段更多信息,请参看 '@One' | '@Many' | '@ManyMany' 更多的描述
+ *
+ * @param obj 数据对象
+ * @param regex 正则表达式,描述了什么样的关联字段将被关注。如果为 null,则表示全部的关联字段都会被更新
+ * @return 数据对象本身
+ * @see org.nutz.dao.entity.annotation.One
+ * @see org.nutz.dao.entity.annotation.Many
+ * @see org.nutz.dao.entity.annotation.ManyMany
+ */
+ T updateWith(T obj, String regex);
+
+ /**
+ * 根据一个正则表达式,仅更新对象所有的关联字段,并不包括对象本身
+ *
+ * @param obj 数据对象
+ * @param regex 正则表达式,描述了什么样的关联字段将被关注。如果为 null,则表示全部的关联字段都会被更新
+ * @return 数据对象本身
+ * @see org.nutz.dao.entity.annotation.One
+ * @see org.nutz.dao.entity.annotation.Many
+ * @see org.nutz.dao.entity.annotation.ManyMany
+ */
+ T updateLinks(T obj, String regex);
+
+ /**
+ * 多对多关联是通过一个中间表将两条数据表记录关联起来。
+ *
+ * 而这个中间表可能还有其他的字段,比如描述关联的权重等
+ *
+ * 这个操作可以让你一次更新某一个对象中多个多对多关联的数据
+ *
+ * @param classOfT 对象类型
+ * @param regex 正则表达式,描述了那种多对多关联字段将被执行该操作
+ * @param chain 针对中间关联表的名值链。
+ * @param cnd 针对中间关联表的 WHERE 条件
+ * @return 共有多少条数据被更新
+ * @see org.nutz.dao.entity.annotation.ManyMany
+ */
+ int updateRelation(Class> classOfT, String regex, Chain chain, Condition cnd);
+
+ /**
+ * 基于版本的更新,版本不一样无法更新到数据
+ *
+ * @param obj 需要更新的对象, 必须有version属性
+ * @return 若更新成功, 大于0, 否则小于0
+ */
+ int updateWithVersion(Object obj);
+
+ /**
+ * 基于版本的更新,版本不一样无法更新到数据
+ *
+ * @param obj 需要更新的对象, 必须有version属性
+ * @param filter 需要过滤的字段设置
+ * @return 若更新成功, 大于0, 否则小于0
+ */
+ int updateWithVersion(Object obj, FieldFilter filter);
+
+ /**
+ * 乐观锁, 以特定字段的值作为限制条件,更新对象,并自增该字段.
+ *
+ * 执行的sql如下:
+ *
+ * update t_user set age=30, city="广州", version=version+1 where name="wendal" and version=124;
+ *
+ * @param obj 需要更新的对象, 必须带@Id/@Name/@Pk中的其中一种.
+ * @param fieldFilter 需要过滤的属性. 若设置了哪些字段不更新,那务必确保过滤掉fieldName的字段
+ * @param fieldName 参考字段的Java属性名.默认是"version",可以是任意数值字段
+ * @return 若更新成功, 返回值大于0, 否则小于等于0
+ */
+ int updateAndIncrIfMatch(Object obj, FieldFilter fieldFilter, String fieldName);
+
+ /**
+ * 获取某个对象,最大的 ID 值,这个对象必须声明了 '@Id'
+ *
+ * @return
+ */
+ int getMaxId();
+
+ /**
+ * 通过long主键删除数据
+ *
+ * @param id
+ * @return
+ */
+ int delete(long id);
+
+ /**
+ * 通过int主键删除数据
+ *
+ * @param id
+ * @return
+ */
+ int delete(int id);
+
+ /**
+ * 通过string主键删除数据
+ *
+ * @param id
+ * @return
+ */
+ int delete(String id);
+
+ /**
+ * 批量删除
+ *
+ * @param ids
+ */
+ void delete(Integer[] ids);
+
+ /**
+ * 批量删除
+ *
+ * @param ids
+ */
+ void delete(Long[] ids);
+
+ /**
+ * 批量删除
+ *
+ * @param ids
+ */
+ void delete(String[] ids);
+
+ /**
+ * 批量删除
+ *
+ * @param ids
+ */
+ void delete(List ids);
+
+ /**
+ * 清空表
+ *
+ * @return
+ */
+ int clear();
+
+ /**
+ * 清空表
+ *
+ * @return
+ */
+ int clear(String tableName);
+
+ /**
+ * 按条件清除一组数据
+ *
+ * @return
+ */
+ int clear(Condition cnd);
+
+ /**
+ * 按条件清除一组数据
+ *
+ * @return
+ */
+ int clear(String tableName, Condition cnd);
+
+ /**
+ * 伪删除
+ *
+ * @param id
+ * @return
+ */
+ int vDelete(String id);
+
+ /**
+ * 批量伪删除
+ *
+ * @param ids
+ * @return
+ */
+ int vDelete(String[] ids);
+
+ /**
+ * 批量伪删除
+ *
+ * @param ids
+ * @return
+ */
+ int vDelete(List ids);
+
+ /**
+ * 根据条件进行伪删除
+ *
+ * @param cnd
+ * @return
+ */
+ int vDelete(Condition cnd);
+
+ /**
+ * 根据条件进行伪删除
+ *
+ * @param cnd
+ * @return
+ */
+ int vDelete(String tableName, Condition cnd);
+
+ /**
+ * 通过LONG主键获取部分字段值
+ *
+ * @param fieldName
+ * @param id
+ * @return
+ */
+ T getField(String fieldName, long id);
+
+ /**
+ * 通过INT主键获取部分字段值
+ *
+ * @param fieldName
+ * @param id
+ * @return
+ */
+ T getField(String fieldName, int id);
+
+ /**
+ * 通过NAME主键获取部分字段值
+ *
+ * @param fieldName 支持通配符 ^(a|b)$
+ * @param name
+ * @return
+ */
+ T getField(String fieldName, String name);
+
+ /**
+ * 通过条件获取部分字段值
+ *
+ * @param fieldName 支持通配符 ^(a|b)$
+ * @param cnd
+ * @return
+ */
+ T getField(String fieldName, Condition cnd);
+
+ /**
+ * 查询获取部分字段
+ *
+ * @param fieldName 支持通配符 ^(a|b)$
+ * @param cnd
+ * @return
+ */
+ List query(String fieldName, Condition cnd);
+
+ /**
+ * 查询一组对象。你可以为这次查询设定条件
+ *
+ * @param cnd WHERE 条件。如果为 null,将获取全部数据,顺序为数据库原生顺序
+ * 只有在调用这个函数的时候, cnd.limit 才会生效
+ * @return 对象列表
+ */
+ List query(Condition cnd);
+
+ /**
+ * 获取全部数据
+ *
+ * @return
+ */
+ List query();
+
+ /**
+ * @param cnd 查询条件
+ * @param linkName 关联字段,支持正则 ^(a|b)$
+ * @return
+ */
+ List query(Condition cnd, String linkName);
+
+ /**
+ * 获取表及关联表全部数据(支持子查询)
+ *
+ * @param cnd 查询条件
+ * @param linkName 关联字段,支持正则 ^(a|b)$
+ * @param linkCnd 关联条件
+ * @return
+ */
+ List query(Condition cnd, String linkName, Condition linkCnd);
+
+ /**
+ * 获取表及关联表全部数据
+ *
+ * @param linkName 关联字段,支持正则 ^(a|b)$
+ * @return
+ */
+ List query(String linkName);
+
+ /**
+ * 分页关联字段查询
+ *
+ * @param cnd 查询条件
+ * @param linkName 关联字段,支持正则 ^(a|b)$
+ * @param pager 分页对象
+ * @return
+ */
+ List query(Condition cnd, String linkName, Pager pager);
+
+ /**
+ * 分页关联字段查询(支持关联条件)
+ *
+ * @param cnd 查询条件
+ * @param linkName 关联字段,支持正则 ^(a|b)$
+ * @param linkCnd 关联条件
+ * @param pager 分页对象
+ * @return
+ */
+ List query(Condition cnd, String linkName, Condition linkCnd, Pager pager);
+
+ /**
+ * 分页查询
+ *
+ * @param cnd 查询条件
+ * @param pager 分页对象
+ * @return
+ */
+ List query(Condition cnd, Pager pager);
+
+ /**
+ * 查询获取NutMap对象
+ *
+ * @param keyColumnName 作为key的字段名
+ * @param valueColumnName 作为value的字段名
+ * @param cnd 查询条件
+ * @return
+ */
+ NutMap query(String keyColumnName, String valueColumnName, Condition cnd);
+
+ /**
+ * 查询获取NutMap对象
+ *
+ * @param tableName 表名
+ * @param keyColumnName 作为key的字段名
+ * @param valueColumnName 作为value的字段名
+ * @param cnd 查询条件
+ * @return
+ */
+ NutMap query(String tableName, String keyColumnName, String valueColumnName, Condition cnd);
+
+ /**
+ * 计算子节点TREEID
+ *
+ * @param tableName
+ * @param colName
+ * @param value
+ * @return
+ */
+ String getSubPath(String tableName, String colName, String value);
+
+ /**
+ * 获取TREEID父级
+ *
+ * @param path
+ * @return
+ */
+ String getParentPath(String path);
+
+
+ /**
+ * 执行一条自定义SQL
+ *
+ * @param sql
+ * @return
+ */
+ Sql execute(Sql sql);
+
+ /**
+ * 自定义SQL返回Record记录集,Record是个MAP但不区分大小写
+ * 别返回Map对象,因为MySql和Oracle中字段名有大小写之分
+ *
+ * @param sql
+ * @return
+ */
+ List list(Sql sql);
+
+ /**
+ * 自定义SQL返回NutMap记录集,区分大小写
+ *
+ * @param sql
+ * @return
+ */
+ List listMap(Sql sql);
+
+ /**
+ * 自定义查询,并返回当前实体类对象
+ *
+ * @param sql
+ * @return
+ */
+ List listEntity(Sql sql);
+
+ /**
+ * 自定义sql获取map key-value
+ *
+ * @param sql
+ * @return
+ */
+ Map getMap(Sql sql);
+
+ /**
+ * 自定义sql获取NutMap key-value
+ *
+ * @param sql
+ * @return
+ */
+ NutMap getNutMap(Sql sql);
+
+ /**
+ * 分页查询
+ *
+ * @param pageNumber
+ * @param cnd
+ * @return
+ */
+ Pagination listPage(Integer pageNumber, Condition cnd);
+
+ /**
+ * 分页查询
+ *
+ * @param pageNumber
+ * @param sql
+ * @return
+ */
+ Pagination listPage(Integer pageNumber, Sql sql);
+
+
+ /**
+ * 分页查询(sql)
+ *
+ * @param pageNumber
+ * @param pageSize
+ * @param sql
+ * @return
+ */
+ Pagination listPage(Integer pageNumber, int pageSize, Sql sql);
+
+ /**
+ * 分页查询
+ *
+ * @param pageNumber
+ * @param sql 查询语句
+ * @param countSql 统计语句
+ * @return
+ */
+ Pagination listPage(Integer pageNumber, Sql sql, Sql countSql);
+
+ /**
+ * 分页查询
+ *
+ * @param pageNumber
+ * @param pageSize
+ * @param sql 查询语句
+ * @param countSql 统计语句
+ * @return
+ */
+ Pagination listPage(Integer pageNumber, int pageSize, Sql sql, Sql countSql);
+
+ /**
+ * 分页查询
+ *
+ * @param pageNumber
+ * @param sql
+ * @return
+ */
+ Pagination listPageMap(Integer pageNumber, Sql sql);
+
+
+ /**
+ * 分页查询(sql)
+ *
+ * @param pageNumber
+ * @param pageSize
+ * @param sql
+ * @return
+ */
+ Pagination listPageMap(Integer pageNumber, int pageSize, Sql sql);
+
+ /**
+ * 分页查询
+ *
+ * @param pageNumber
+ * @param sql 查询语句
+ * @param countSql 统计语句
+ * @return
+ */
+ Pagination listPageMap(Integer pageNumber, Sql sql, Sql countSql);
+
+ /**
+ * 分页查询
+ *
+ * @param pageNumber
+ * @param pageSize
+ * @param sql 查询语句
+ * @param countSql 统计语句
+ * @return
+ */
+ Pagination listPageMap(Integer pageNumber, int pageSize, Sql sql, Sql countSql);
+
+ /**
+ * 分页查询
+ *
+ * @param pageNumber
+ * @param tableName
+ * @param cnd
+ * @return
+ */
+ Pagination listPage(Integer pageNumber, String tableName, Condition cnd);
+
+ /**
+ * 分页查询(cnd)
+ *
+ * @param pageNumber
+ * @param pageSize
+ * @param cnd
+ * @return
+ */
+ Pagination listPage(Integer pageNumber, int pageSize, Condition cnd);
+
+ /**
+ * 分页查询,获取部分字段(cnd)
+ *
+ * @param pageNumber
+ * @param pageSize
+ * @param cnd
+ * @param fieldName 支持通配符 ^(a|b)$
+ * @return
+ */
+ Pagination listPage(Integer pageNumber, int pageSize, Condition cnd, String fieldName);
+
+ /**
+ * 关联查询
+ *
+ * @param pageNumber
+ * @param pageSize
+ * @param cnd
+ * @param linkName 支持通配符 ^(a|b)$
+ * @return
+ */
+ Pagination listPageLinks(Integer pageNumber, int pageSize, Condition cnd, String linkName);
+
+ /**
+ * 关联查询,带子查询条件
+ *
+ * @param pageNumber
+ * @param pageSize
+ * @param cnd
+ * @param linkName 支持通配符 ^(a|b)$
+ * @param subCnd 子查询条件
+ * @return
+ */
+ Pagination listPageLinks(Integer pageNumber, int pageSize, Condition cnd, String linkName, Condition subCnd);
+
+ /**
+ * 分页查询(tabelName)
+ *
+ * @param pageNumber
+ * @param pageSize
+ * @param tableName
+ * @param cnd
+ * @return
+ */
+ Pagination listPage(Integer pageNumber, int pageSize, String tableName, Condition cnd);
+
+ /**
+ * 分页查询并返回包含实体类内容的NutMap对象
+ *
+ * @param pageNumber
+ * @param cnd
+ * @return
+ */
+ Pagination listPageMap(Integer pageNumber, Condition cnd);
+
+ /**
+ * 分页查询并返回包含实体类内容的NutMap对象
+ *
+ * @param pageNumber
+ * @param pageSize
+ * @param cnd
+ * @return
+ */
+ Pagination listPageMap(Integer pageNumber, int pageSize, Condition cnd);
+
+
+ /**
+ * DataTable Page
+ *
+ * @param length 页大小
+ * @param start start
+ * @param draw draw
+ * @param orders 排序
+ * @param columns 字段
+ * @param cnd 查询条件
+ * @param linkName 关联查询 支持通配符 ^(a|b)$
+ * @return
+ */
+ NutMap data(int length, int start, int draw, List orders, List columns, Cnd cnd, String linkName);
+
+ /**
+ * DataTable Page
+ *
+ * @param length 页大小
+ * @param start start
+ * @param draw draw
+ * @param orders 排序
+ * @param columns 字段
+ * @param cnd 查询条件
+ * @param linkName 关联查询 支持通配符 ^(a|b)$
+ * @param subCnd 关联查询条件
+ * @return
+ */
+ NutMap data(int length, int start, int draw, List orders, List columns, Cnd cnd, String linkName, Cnd subCnd);
+
+ /**
+ * DataTable Page 自定义SQL
+ *
+ * @param length 页大小
+ * @param start start
+ * @param draw draw
+ * @param countSql 统计查询语句
+ * @param orderSql 结果查询语句
+ * @return
+ */
+ NutMap data(int length, int start, int draw, Sql countSql, Sql orderSql);
+
+ /**
+ * DataTable Page 自定义SQL
+ *
+ * @param length 页大小
+ * @param start start
+ * @param draw draw
+ * @param countSql 统计查询语句
+ * @param orderSql 结果查询语句
+ * @param countOnly 统计查询语句是否只有count()
+ * @return
+ */
+ NutMap data(int length, int start, int draw, Sql countSql, Sql orderSql, boolean countOnly);
+
+ /**
+ * DataTable Page
+ *
+ * @param length 页大小
+ * @param start start
+ * @param draw draw
+ * @param cnd 查询条件
+ * @param linkName 关联查询 支持通配符 ^(a|b)$
+ * @return
+ */
+ NutMap data(int length, int start, int draw, Cnd cnd, String linkName);
+}
diff --git a/backend/src/main/java/com/budwk/app/base/service/impl/BaseServiceImpl.java b/backend/src/main/java/com/budwk/app/base/service/impl/BaseServiceImpl.java
new file mode 100644
index 0000000..9db462d
--- /dev/null
+++ b/backend/src/main/java/com/budwk/app/base/service/impl/BaseServiceImpl.java
@@ -0,0 +1,1373 @@
+package com.budwk.app.base.service.impl;
+
+import com.budwk.app.base.page.OffsetPager;
+import com.budwk.app.base.page.Pagination;
+import com.budwk.app.base.page.datatable.DataTableColumn;
+import com.budwk.app.base.page.datatable.DataTableOrder;
+import com.budwk.app.base.service.BaseService;
+import org.nutz.dao.*;
+import org.nutz.dao.entity.Entity;
+import org.nutz.dao.entity.Record;
+import org.nutz.dao.pager.Pager;
+import org.nutz.dao.sql.Sql;
+import org.nutz.dao.sql.SqlCallback;
+import org.nutz.dao.util.Daos;
+import org.nutz.lang.Lang;
+import org.nutz.lang.Strings;
+import org.nutz.lang.util.NutMap;
+import org.nutz.service.EntityService;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Created by wizzer on 2016/12/22.
+ */
+public class BaseServiceImpl extends EntityService implements BaseService {
+ private static int DEFAULT_PAGE_NUMBER = 10;
+
+ public BaseServiceImpl(Dao dao) {
+ super(dao);
+ }
+
+ /**
+ * 获取实体的Entity
+ *
+ * @return 实体的Entity
+ */
+ public Entity getEntity() {
+ return super.getEntity();
+ }
+
+ /**
+ * 获取实体类型
+ *
+ * @return 实体类型
+ */
+ public Class getEntityClass() {
+ return super.getEntityClass();
+ }
+
+ /**
+ * 统计符合条件的对象表条数
+ *
+ * @param cnd
+ * @return
+ */
+ public int count(Condition cnd) {
+ return this.dao().count(this.getEntityClass(), cnd);
+ }
+
+ /**
+ * 统计对象表条数
+ *
+ * @return
+ */
+ public int count() {
+ return this.dao().count(this.getEntityClass());
+ }
+
+ /**
+ * 统计符合条件的记录条数
+ *
+ * @param tableName
+ * @param cnd
+ * @return
+ */
+ public int count(String tableName, Condition cnd) {
+ return this.dao().count(tableName, cnd);
+ }
+
+ /**
+ * 统计表记录条数
+ *
+ * @param tableName
+ * @return
+ */
+ public int count(String tableName) {
+ return this.dao().count(tableName);
+ }
+
+ /**
+ * 自定义SQL统计
+ *
+ * @param sql
+ * @return
+ */
+ public int count(Sql sql) {
+ sql.setCallback(new SqlCallback() {
+ public Object invoke(Connection conn, ResultSet rs, Sql sql)
+ throws SQLException {
+ int rsvalue = 0;
+ if (rs != null && rs.next()) {
+ rsvalue = rs.getInt(1);
+ }
+ return rsvalue;
+ }
+ });
+ this.dao().execute(sql);
+ return sql.getInt();
+ }
+
+ /**
+ * 通过数字型主键查询对象
+ *
+ * @param id
+ * @return
+ */
+ public T fetch(long id) {
+ return this.dao().fetch(this.getEntityClass(), id);
+ }
+
+ /**
+ * 通过字符型主键查询对象
+ *
+ * @param id
+ * @return
+ */
+ public T fetch(String id) {
+ return this.dao().fetch(this.getEntityClass(), id);
+ }
+
+ /**
+ * 查询关联表
+ *
+ * @param obj 数据对象,可以是普通对象或集合,但不是类
+ * @param regex 为null查询全部,支持通配符 ^(a|b)$
+ * @return
+ */
+ public T fetchLinks(T obj, String regex) {
+ return this.dao().fetchLinks(obj, regex);
+ }
+
+ /**
+ * 查询关联表
+ *
+ * @param obj 数据对象,可以是普通对象或集合,但不是类
+ * @param regex 为null查询全部,支持通配符 ^(a|b)$
+ * @param cnd 关联字段的过滤(排序,条件语句,分页等)
+ * @return
+ */
+ public T fetchLinks(T obj, String regex, Condition cnd) {
+ return this.dao().fetchLinks(obj, regex, cnd);
+ }
+
+ /**
+ * 查出符合条件的第一条记录
+ *
+ * @param cnd 查询条件
+ * @return 实体, 如不存在则为null
+ */
+ public T fetch(Condition cnd) {
+ return dao().fetch(getEntityClass(), cnd);
+ }
+
+ /**
+ * 复合主键专用
+ *
+ * @param pks 键值
+ * @return 对象 T
+ */
+ public T fetchx(Object... pks) {
+ return dao().fetchx(getEntityClass(), pks);
+ }
+
+ /**
+ * 复合主键专用
+ *
+ * @param pks 键值
+ * @return 对象 T
+ */
+ public boolean exists(Object... pks) {
+ return null != fetchx(pks);
+ }
+
+ /**
+ * 将一个对象插入到一个数据库
+ *
+ * @param obj 要被插入的对象
+ * 它可以是:
+ * 普通 POJO
+ * 集合
+ * 数组
+ * Map
+ * 注意:如果是集合,数组或者 Map,所有的对象必须类型相同,否则可能会出错
+ * @return 插入后的对象
+ */
+ public T insert(T obj) {
+ return this.dao().insert(obj);
+ }
+
+ /**
+ * 将一个对象按FieldFilter过滤后,插入到一个数据源。
+ *
+ * dao.insert(pet, FieldFilter.create(Pet.class, FieldMatcher.create(false)));
+ *
+ * @param obj 要被插入的对象
+ * @param filter 字段过滤器, 其中FieldMatcher.isIgnoreId生效
+ * @return 插入后的对象
+ * @see Dao#insert(Object)
+ */
+ public T insert(T obj, FieldFilter filter) {
+ return this.dao().insert(obj, filter);
+ }
+
+ /**
+ * 根据对象的主键(@Id/@Name/@Pk)先查询, 如果存在就更新, 不存在就插入
+ *
+ * @param obj 对象
+ * @return 原对象
+ */
+ public T insertOrUpdate(T obj) {
+ return this.dao().insertOrUpdate(obj);
+ }
+
+ /**
+ * 根据对象的主键(@Id/@Name/@Pk)先查询, 如果存在就更新, 不存在就插入
+ *
+ * @param obj 对象
+ * @param insertFieldFilter 插入时的字段过滤, 可以是null
+ * @param updateFieldFilter 更新时的字段过滤,可以是null
+ * @return 原对象
+ */
+ public T insertOrUpdate(T obj, FieldFilter insertFieldFilter, FieldFilter updateFieldFilter) {
+ return this.dao().insertOrUpdate(obj, insertFieldFilter, updateFieldFilter);
+ }
+
+ /**
+ * 自由的向一个数据表插入一条数据
+ *
+ * @param tableName 表名
+ * @param chain 数据名值链
+ */
+ public void insert(String tableName, Chain chain) {
+ this.dao().insert(tableName, chain);
+ }
+
+ /**
+ * 快速插入一个对象,对象的 '@Prev' 以及 '@Next' 在这个函数里不起作用
+ *
+ * @param obj
+ * @return
+ */
+ public T fastInsert(T obj) {
+ return this.dao().fastInsert(obj);
+ }
+
+ /**
+ * 将对象插入数据库同时,也将符合一个正则表达式的所有关联字段关联的对象统统插入相应的数据库
+ *
+ * 关于关联字段更多信息,请参看 '@One' | '@Many' | '@ManyMany' 更多的描述
+ *
+ * @param obj 数据对象
+ * @param regex 正则表达式,描述了什么样的关联字段将被关注。如果为 null,则表示全部的关联字段都会被插入
+ * @return 数据对象本身
+ * @see org.nutz.dao.entity.annotation.One
+ * @see org.nutz.dao.entity.annotation.Many
+ * @see org.nutz.dao.entity.annotation.ManyMany
+ */
+ public T insertWith(T obj, String regex) {
+ return this.dao().insertWith(obj, regex);
+ }
+
+ /**
+ * 根据一个正则表达式,仅将对象所有的关联字段插入到数据库中,并不包括对象本身
+ *
+ * @param obj 数据对象
+ * @param regex 正则表达式,描述了什么样的关联字段将被关注。如果为 null,则表示全部的关联字段都会被插入
+ * @return 数据对象本身
+ * @see org.nutz.dao.entity.annotation.One
+ * @see org.nutz.dao.entity.annotation.Many
+ * @see org.nutz.dao.entity.annotation.ManyMany
+ */
+ public T insertLinks(T obj, String regex) {
+ return this.dao().insertLinks(obj, regex);
+ }
+
+ /**
+ * 将对象的一个或者多个,多对多的关联信息,插入数据表
+ *
+ * @param obj 对象
+ * @param regex 正则表达式,描述了那种多对多关联字段将被执行该操作
+ * @return 对象自身
+ * @see org.nutz.dao.entity.annotation.ManyMany
+ */
+ public T insertRelation(T obj, String regex) {
+ return this.dao().insertRelation(obj, regex);
+ }
+
+ /**
+ * 更新数据
+ *
+ * @param obj
+ * @return
+ */
+ public int update(Object obj) {
+ return this.dao().update(obj);
+ }
+
+ /**
+ * 更新数据忽略值为null的字段
+ *
+ * @param obj
+ * @return
+ */
+ public int updateIgnoreNull(Object obj) {
+ return this.dao().updateIgnoreNull(obj);
+ }
+
+ /**
+ * 部分更新实体表
+ *
+ * @param chain
+ * @param cnd
+ * @return
+ */
+ public int update(Chain chain, Condition cnd) {
+ return this.dao().update(this.getEntityClass(), chain, cnd);
+ }
+
+ /**
+ * 部分更新表
+ *
+ * @param tableName
+ * @param chain
+ * @param cnd
+ * @return
+ */
+ public int update(String tableName, Chain chain, Condition cnd) {
+ return this.dao().update(tableName, chain, cnd);
+ }
+
+ /**
+ * 将对象更新的同时,也将符合一个正则表达式的所有关联字段关联的对象统统更新
+ *
+ * 关于关联字段更多信息,请参看 '@One' | '@Many' | '@ManyMany' 更多的描述
+ *
+ * @param obj 数据对象
+ * @param regex 正则表达式,描述了什么样的关联字段将被关注。如果为 null,则表示全部的关联字段都会被更新
+ * @return 数据对象本身
+ * @see org.nutz.dao.entity.annotation.One
+ * @see org.nutz.dao.entity.annotation.Many
+ * @see org.nutz.dao.entity.annotation.ManyMany
+ */
+ public T updateWith(T obj, String regex) {
+ return this.dao().updateWith(obj, regex);
+ }
+
+ /**
+ * 根据一个正则表达式,仅更新对象所有的关联字段,并不包括对象本身
+ *
+ * @param obj 数据对象
+ * @param regex 正则表达式,描述了什么样的关联字段将被关注。如果为 null,则表示全部的关联字段都会被更新
+ * @return 数据对象本身
+ * @see org.nutz.dao.entity.annotation.One
+ * @see org.nutz.dao.entity.annotation.Many
+ * @see org.nutz.dao.entity.annotation.ManyMany
+ */
+ public T updateLinks(T obj, String regex) {
+ return this.dao().updateLinks(obj, regex);
+ }
+
+ /**
+ * 多对多关联是通过一个中间表将两条数据表记录关联起来。
+ *
+ * 而这个中间表可能还有其他的字段,比如描述关联的权重等
+ *
+ * 这个操作可以让你一次更新某一个对象中多个多对多关联的数据
+ *
+ * @param classOfT 对象类型
+ * @param regex 正则表达式,描述了那种多对多关联字段将被执行该操作
+ * @param chain 针对中间关联表的名值链。
+ * @param cnd 针对中间关联表的 WHERE 条件
+ * @return 共有多少条数据被更新
+ * @see org.nutz.dao.entity.annotation.ManyMany
+ */
+ public int updateRelation(Class> classOfT, String regex, Chain chain, Condition cnd) {
+ return this.dao().updateRelation(classOfT, regex, chain, cnd);
+ }
+
+ /**
+ * 基于版本的更新,版本不一样无法更新到数据
+ *
+ * @param obj 需要更新的对象, 必须有version属性
+ * @return 若更新成功, 大于0, 否则小于0
+ */
+ public int updateWithVersion(Object obj) {
+ return this.dao().updateWithVersion(obj);
+ }
+
+ /**
+ * 基于版本的更新,版本不一样无法更新到数据
+ *
+ * @param obj 需要更新的对象, 必须有version属性
+ * @param fieldFilter 需要过滤的字段设置
+ * @return 若更新成功, 大于0, 否则小于0
+ */
+ public int updateWithVersion(Object obj, FieldFilter fieldFilter) {
+ return this.dao().updateWithVersion(obj, fieldFilter);
+ }
+
+ /**
+ * 乐观锁, 以特定字段的值作为限制条件,更新对象,并自增该字段.
+ *
+ * 执行的sql如下:
+ *
+ * update t_user set age=30, city="广州", version=version+1 where name="wendal" and version=124;
+ *
+ * @param obj 需要更新的对象, 必须带@Id/@Name/@Pk中的其中一种.
+ * @param fieldFilter 需要过滤的属性. 若设置了哪些字段不更新,那务必确保过滤掉fieldName的字段
+ * @param fieldName 参考字段的Java属性名.默认是"version",可以是任意数值字段
+ * @return 若更新成功, 返回值大于0, 否则小于等于0
+ */
+ public int updateAndIncrIfMatch(Object obj, FieldFilter fieldFilter, String fieldName) {
+ return this.dao().updateAndIncrIfMatch(obj, fieldFilter, fieldName);
+ }
+
+ /**
+ * 获取某个对象,最大的 ID 值,这个对象必须声明了 '@Id'
+ *
+ * @return
+ */
+ public int getMaxId() {
+ return this.dao().getMaxId(this.getEntityClass());
+ }
+
+ /**
+ * 通过long主键删除数据
+ *
+ * @param id
+ * @return
+ */
+ public int delete(long id) {
+ return this.dao().delete(this.getEntityClass(), id);
+ }
+
+ /**
+ * 通过int主键删除数据
+ *
+ * @param id
+ * @return
+ */
+ public int delete(int id) {
+ return this.dao().delete(this.getEntityClass(), id);
+ }
+
+ /**
+ * 通过string主键删除数据
+ *
+ * @param id
+ * @return
+ */
+ public int delete(String id) {
+ return this.dao().delete(this.getEntityClass(), id);
+ }
+
+ /**
+ * 批量删除
+ *
+ * @param ids
+ */
+ public void delete(Integer[] ids) {
+ this.dao().clear(this.getEntityClass(), Cnd.where("id", "in", ids));
+ }
+
+ /**
+ * 批量删除
+ *
+ * @param ids
+ */
+ public void delete(Long[] ids) {
+ this.dao().clear(this.getEntityClass(), Cnd.where("id", "in", ids));
+ }
+
+ /**
+ * 批量删除
+ *
+ * @param ids
+ */
+ public void delete(String[] ids) {
+ this.dao().clear(this.getEntityClass(), Cnd.where("id", "in", ids));
+ }
+
+ /**
+ * 批量删除
+ *
+ * @param ids
+ */
+ public void delete(List ids) {
+ this.dao().clear(this.getEntityClass(), Cnd.where("id", "in", ids));
+ }
+
+ /**
+ * 清空表
+ *
+ * @return
+ */
+ public int clear() {
+ return this.dao().clear(this.getEntityClass());
+ }
+
+ /**
+ * 清空表
+ *
+ * @return
+ */
+ public int clear(String tableName) {
+ return this.dao().clear(tableName);
+ }
+
+ /**
+ * 按条件清除一组数据
+ *
+ * @return
+ */
+ public int clear(Condition cnd) {
+ return this.dao().clear(this.getEntityClass(), cnd);
+ }
+
+ /**
+ * 按条件清除一组数据
+ *
+ * @return
+ */
+ public int clear(String tableName, Condition cnd) {
+ return this.dao().clear(tableName, cnd);
+ }
+
+ /**
+ * 伪删除
+ *
+ * @param id
+ * @return
+ */
+ public int vDelete(String id) {
+ return this.dao().update(this.getEntityClass(), Chain.make("delFlag", true), Cnd.where("id", "=", id));
+ }
+
+ /**
+ * 批量伪删除
+ *
+ * @param ids
+ * @return
+ */
+ public int vDelete(String[] ids) {
+ return this.dao().update(this.getEntityClass(), Chain.make("delFlag", true), Cnd.where("id", "in", ids));
+ }
+
+ /**
+ * 批量伪删除
+ *
+ * @param ids
+ * @return
+ */
+ public int vDelete(List ids) {
+ return this.dao().update(this.getEntityClass(), Chain.make("delFlag", true), Cnd.where("id", "in", ids));
+ }
+
+ /**
+ * 根据条件进行伪删除
+ *
+ * @param cnd
+ * @return
+ */
+ public int vDelete(Condition cnd) {
+ return this.dao().update(this.getEntityClass(), Chain.make("delFlag", true), cnd);
+ }
+
+ /**
+ * 根据条件进行伪删除
+ *
+ * @param cnd
+ * @return
+ */
+ public int vDelete(String tableName, Condition cnd) {
+ return this.dao().update(tableName, Chain.make("delFlag", true), cnd);
+ }
+
+ /**
+ * 通过LONG主键获取部分字段值
+ *
+ * @param fieldName
+ * @param id
+ * @return
+ */
+ public T getField(String fieldName, long id) {
+ return Daos.ext(this.dao(), FieldFilter.create(this.getEntityClass(), fieldName))
+ .fetch(this.getEntityClass(), id);
+ }
+
+ /**
+ * 通过INT主键获取部分字段值
+ *
+ * @param fieldName
+ * @param id
+ * @return
+ */
+ public T getField(String fieldName, int id) {
+ return Daos.ext(this.dao(), FieldFilter.create(this.getEntityClass(), fieldName))
+ .fetch(this.getEntityClass(), id);
+ }
+
+
+ /**
+ * 通过NAME主键获取部分字段值
+ *
+ * @param fieldName 支持通配符 ^(a|b)$
+ * @param name
+ * @return
+ */
+ public T getField(String fieldName, String name) {
+ return Daos.ext(this.dao(), FieldFilter.create(this.getEntityClass(), fieldName))
+ .fetch(this.getEntityClass(), name);
+ }
+
+ /**
+ * 通过条件获取部分字段值
+ *
+ * @param fieldName 支持通配符 ^(a|b)$
+ * @param cnd
+ * @return
+ */
+ public T getField(String fieldName, Condition cnd) {
+ return Daos.ext(this.dao(), FieldFilter.create(this.getEntityClass(), fieldName))
+ .fetch(this.getEntityClass(), cnd);
+ }
+
+ /**
+ * 查询获取部分字段
+ *
+ * @param fieldName 支持通配符 ^(a|b)$
+ * @param cnd
+ * @return
+ */
+ public List query(String fieldName, Condition cnd) {
+ return Daos.ext(this.dao(), FieldFilter.create(this.getEntityClass(), fieldName))
+ .query(this.getEntityClass(), cnd);
+ }
+
+ /**
+ * 查询一组对象。你可以为这次查询设定条件
+ *
+ * @param cnd WHERE 条件。如果为 null,将获取全部数据,顺序为数据库原生顺序
+ * 只有在调用这个函数的时候, cnd.limit 才会生效
+ * @return 对象列表
+ */
+ public List query(Condition cnd) {
+ return dao().query(getEntityClass(), cnd);
+ }
+
+
+ /**
+ * 获取全部数据
+ *
+ * @return
+ */
+ public List query() {
+ return dao().query(getEntityClass(), null);
+ }
+
+
+ /**
+ * 获取表及关联表全部数据
+ *
+ * @param cnd 查询条件
+ * @param linkName 关联字段,支持正则 ^(a|b)$
+ * @return
+ */
+ public List query(Condition cnd, String linkName) {
+ List list = this.dao().query(this.getEntityClass(), cnd);
+ if (!Strings.isBlank(linkName)) {
+ this.dao().fetchLinks(list, linkName);
+ }
+ return list;
+ }
+
+ /**
+ * 获取表及关联表全部数据(支持子查询)
+ *
+ * @param cnd 查询条件
+ * @param linkName 关联字段,支持正则 ^(a|b)$
+ * @param linkCnd 关联条件
+ * @return
+ */
+ public List query(Condition cnd, String linkName, Condition linkCnd) {
+ List list = this.dao().query(this.getEntityClass(), cnd);
+ if (!Strings.isBlank(linkName)) {
+ this.dao().fetchLinks(list, linkName, linkCnd);
+ }
+ return list;
+ }
+
+ /**
+ * 获取表及关联表全部数据
+ *
+ * @param linkName 关联字段,支持正则 ^(a|b)$
+ * @return
+ */
+ public List query(String linkName) {
+ return this.query(null, linkName);
+ }
+
+
+ /**
+ * 分页关联字段查询
+ *
+ * @param cnd 查询条件
+ * @param linkName 关联字段,支持正则 ^(a|b)$
+ * @param pager 分页对象
+ * @return
+ */
+ public List query(Condition cnd, String linkName, Pager pager) {
+ List list = this.dao().query(this.getEntityClass(), cnd, pager);
+ if (!Strings.isBlank(linkName)) {
+ this.dao().fetchLinks(list, linkName);
+ }
+ return list;
+ }
+
+ /**
+ * 分页关联字段查询(支持关联条件)
+ *
+ * @param cnd 查询条件
+ * @param linkName 关联字段,支持正则 ^(a|b)$
+ * @param linkCnd 关联条件
+ * @param pager 分页对象
+ * @return
+ */
+ public List query(Condition cnd, String linkName, Condition linkCnd, Pager pager) {
+ List list = this.dao().query(this.getEntityClass(), cnd, pager);
+ if (!Strings.isBlank(linkName)) {
+ this.dao().fetchLinks(list, linkName, linkCnd);
+ }
+ return list;
+ }
+
+ /**
+ * 分页查询
+ *
+ * @param cnd 查询条件
+ * @param pager 分页对象
+ * @return
+ */
+ public List query(Condition cnd, Pager pager) {
+ return dao().query(getEntityClass(), cnd, pager);
+ }
+
+ /**
+ * 查询获取NutMap对象
+ *
+ * @param keyColumnName 作为key的字段名
+ * @param valueColumnName 作为value的字段名
+ * @param cnd 查询条件
+ * @return
+ */
+ public NutMap query(String keyColumnName, String valueColumnName, Condition cnd) {
+ NutMap nutMap = NutMap.NEW();
+ List list = this.dao().query(this.getEntity().getTableName(), cnd);
+ for (Record record : list) {
+ nutMap.addv(Strings.sNull(record.get(keyColumnName)), record.get(valueColumnName));
+ }
+ return nutMap;
+ }
+
+ /**
+ * 查询获取NutMap对象
+ *
+ * @param tableName 表名
+ * @param keyColumnName 作为key的字段名
+ * @param valueColumnName 作为value的字段名
+ * @param cnd 查询条件
+ * @return
+ */
+ public NutMap query(String tableName, String keyColumnName, String valueColumnName, Condition cnd) {
+ NutMap nutMap = NutMap.NEW();
+ List list = this.dao().query(tableName, cnd);
+ for (Record record : list) {
+ nutMap.addv(Strings.sNull(record.get(keyColumnName)), record.get(valueColumnName));
+ }
+ return nutMap;
+ }
+
+ /**
+ * 计算子节点TREEID
+ *
+ * @param tableName
+ * @param colName
+ * @param value
+ * @return
+ */
+ public String getSubPath(String tableName, String colName, String value) {
+ final String val = Strings.sNull(value);
+ Sql sql = Sqls.create("select " + colName + " from " + tableName
+ + " where " + colName + " like '" + val + "____' order by "
+ + colName + " desc");
+ sql.setCallback(new SqlCallback() {
+ public Object invoke(Connection conn, ResultSet rs, Sql sql)
+ throws SQLException {
+ String rsvalue = val + "0001";
+ if (rs != null && rs.next()) {
+ rsvalue = rs.getString(1);
+ int newvalue = Integer.valueOf(rsvalue
+ .substring(rsvalue.length() - 4)) + 1;
+ rsvalue = rsvalue.substring(0, rsvalue.length() - 4)
+ + new java.text.DecimalFormat("0000")
+ .format(newvalue);
+ }
+ return rsvalue;
+ }
+ });
+ this.dao().execute(sql);
+ return sql.getString();
+
+ }
+
+ /**
+ * 获取TREEID父级
+ *
+ * @param path
+ * @return
+ */
+ public String getParentPath(String path) {
+ return !Strings.isEmpty(path) && path.length() > 4 ? path.substring(0, path.length() - 4) : "";
+ }
+
+ /**
+ * 执行自定义SQL
+ *
+ * @param sql
+ * @return
+ */
+ public Sql execute(Sql sql) {
+ return this.dao().execute(sql);
+ }
+
+ /**
+ * 自定义SQL返回Record记录集,Record是个MAP但不区分大小写
+ * 别返回Map对象,因为MySql和Oracle中字段名有大小写之分
+ *
+ * @param sql
+ * @return
+ */
+ public List list(Sql sql) {
+ sql.setCallback(Sqls.callback.records());
+ this.dao().execute(sql);
+ return sql.getList(Record.class);
+
+ }
+
+ /**
+ * 自定义SQL返回NutMap记录集,区分大小写
+ *
+ * @param sql
+ * @return
+ */
+ @Override
+ public List listMap(Sql sql) {
+ sql.setCallback(Sqls.callback.maps());
+ this.dao().execute(sql);
+ return sql.getList(NutMap.class);
+ }
+
+ /**
+ * 自定义查询,并返回当前实体类对象
+ *
+ * @param sql
+ * @return
+ */
+ public List listEntity(Sql sql) {
+ sql.setEntity(getEntity());
+ sql.setCallback(Sqls.callback.entities());
+ this.dao().execute(sql);
+ return sql.getList(getEntityClass());
+ }
+
+ /**
+ * 自定义sql获取map key-value
+ *
+ * @param sql
+ * @return
+ */
+ public Map getMap(Sql sql) {
+ sql.setCallback(new SqlCallback() {
+ @Override
+ public Object invoke(Connection conn, ResultSet rs, Sql sql)
+ throws SQLException {
+ Map map = new HashMap<>();
+ while (rs.next()) {
+ map.put(Strings.sNull(rs.getString(1)), Strings.sNull(rs.getString(2)));
+ }
+ return map;
+ }
+ });
+ this.dao().execute(sql);
+ return sql.getObject(Map.class);
+ }
+
+ /**
+ * 自定义sql获取NutMap key-value
+ *
+ * @param sql
+ * @return
+ */
+ public NutMap getNutMap(Sql sql) {
+ sql.setCallback(new SqlCallback() {
+ @Override
+ public Object invoke(Connection conn, ResultSet rs, Sql sql)
+ throws SQLException {
+ NutMap map = NutMap.NEW();
+ while (rs.next()) {
+ map.put(Strings.sNull(rs.getString(1)), Strings.sNull(rs.getString(2)));
+ }
+ return map;
+ }
+ });
+ this.dao().execute(sql);
+ return sql.getObject(NutMap.class);
+ }
+
+ /**
+ * 分页查询
+ *
+ * @param pageNumber
+ * @param cnd
+ * @return
+ */
+ public Pagination listPage(Integer pageNumber, Condition cnd) {
+ return listPage(pageNumber, DEFAULT_PAGE_NUMBER, cnd);
+ }
+
+ /**
+ * 分页查询
+ *
+ * @param pageNumber
+ * @param sql
+ * @return
+ */
+ public Pagination listPage(Integer pageNumber, Sql sql) {
+ return listPage(pageNumber, DEFAULT_PAGE_NUMBER, sql);
+ }
+
+ /**
+ * 分页查询(sql)
+ *
+ * @param pageNumber
+ * @param pageSize
+ * @param sql
+ * @return
+ */
+ public Pagination listPage(Integer pageNumber, int pageSize, Sql sql) {
+ pageNumber = getPageNumber(pageNumber);
+ pageSize = getPageSize(pageSize);
+ Pager pager = this.dao().createPager(pageNumber, pageSize);
+ pager.setRecordCount((int) Daos.queryCount(this.dao(), sql));// 记录数需手动设置
+ sql.setPager(pager);
+ sql.setCallback(Sqls.callback.records());
+ this.dao().execute(sql);
+ return new Pagination(pageNumber, pageSize, pager.getRecordCount(), sql.getList(Record.class));
+ }
+
+ /**
+ * @param pageNumber
+ * @param sql 查询语句
+ * @param countSql 统计语句
+ * @return
+ */
+ public Pagination listPage(Integer pageNumber, Sql sql, Sql countSql) {
+ return listPage(pageNumber, DEFAULT_PAGE_NUMBER, sql, countSql);
+ }
+
+ /**
+ * @param pageNumber
+ * @param pageSize
+ * @param sql 查询语句
+ * @param countSql 统计语句
+ * @return
+ */
+ public Pagination listPage(Integer pageNumber, int pageSize, Sql sql, Sql countSql) {
+ pageNumber = getPageNumber(pageNumber);
+ pageSize = getPageSize(pageSize);
+ Pager pager = this.dao().createPager(pageNumber, pageSize);
+ countSql.setCallback(Sqls.callback.integer());
+ this.dao().execute(countSql);
+ pager.setRecordCount(countSql.getInt());// 记录数需手动设置
+ sql.setPager(pager);
+ sql.setCallback(Sqls.callback.records());
+ this.dao().execute(sql);
+ return new Pagination(pageNumber, pageSize, pager.getRecordCount(), sql.getList(Record.class));
+ }
+
+ /**
+ * 分页查询
+ *
+ * @param pageNumber
+ * @param sql
+ * @return
+ */
+ public Pagination listPageMap(Integer pageNumber, Sql sql) {
+ return listPageMap(pageNumber, DEFAULT_PAGE_NUMBER, sql);
+ }
+
+ /**
+ * 分页查询(sql)
+ *
+ * @param pageNumber
+ * @param pageSize
+ * @param sql
+ * @return
+ */
+ public Pagination listPageMap(Integer pageNumber, int pageSize, Sql sql) {
+ pageNumber = getPageNumber(pageNumber);
+ pageSize = getPageSize(pageSize);
+ Pager pager = this.dao().createPager(pageNumber, pageSize);
+ pager.setRecordCount((int) Daos.queryCount(this.dao(), sql));// 记录数需手动设置
+ sql.setPager(pager);
+ sql.setCallback(Sqls.callback.maps());
+ this.dao().execute(sql);
+ return new Pagination(pageNumber, pageSize, pager.getRecordCount(), sql.getList(Map.class));
+ }
+
+ /**
+ * @param pageNumber
+ * @param sql 查询语句
+ * @param countSql 统计语句
+ * @return
+ */
+ public Pagination listPageMap(Integer pageNumber, Sql sql, Sql countSql) {
+ return listPageMap(pageNumber, DEFAULT_PAGE_NUMBER, sql, countSql);
+ }
+
+ /**
+ * @param pageNumber
+ * @param pageSize
+ * @param sql 查询语句
+ * @param countSql 统计语句
+ * @return
+ */
+ public Pagination listPageMap(Integer pageNumber, int pageSize, Sql sql, Sql countSql) {
+ pageNumber = getPageNumber(pageNumber);
+ pageSize = getPageSize(pageSize);
+ Pager pager = this.dao().createPager(pageNumber, pageSize);
+ countSql.setCallback(Sqls.callback.integer());
+ this.dao().execute(countSql);
+ pager.setRecordCount(countSql.getInt());// 记录数需手动设置
+ sql.setPager(pager);
+ sql.setCallback(Sqls.callback.maps());
+ this.dao().execute(sql);
+ return new Pagination(pageNumber, pageSize, pager.getRecordCount(), sql.getList(Map.class));
+ }
+
+ /**
+ * 分页查询
+ *
+ * @param pageNumber
+ * @param tableName
+ * @param cnd
+ * @return
+ */
+ public Pagination listPage(Integer pageNumber, String tableName, Condition cnd) {
+ return listPage(pageNumber, DEFAULT_PAGE_NUMBER, tableName, cnd);
+ }
+
+ /**
+ * 分页查询(cnd)
+ *
+ * @param pageNumber
+ * @param pageSize
+ * @param cnd
+ * @return
+ */
+ public Pagination listPage(Integer pageNumber, int pageSize, Condition cnd) {
+ pageNumber = getPageNumber(pageNumber);
+ pageSize = getPageSize(pageSize);
+ Pager pager = this.dao().createPager(pageNumber, pageSize);
+ List list = this.dao().query(this.getEntityClass(), cnd, pager);
+ pager.setRecordCount(this.dao().count(this.getEntityClass(), cnd));
+ return new Pagination(pageNumber, pageSize, pager.getRecordCount(), list);
+ }
+
+ /**
+ * 分页查询,获取部分字段(cnd)
+ *
+ * @param pageNumber
+ * @param pageSize
+ * @param cnd
+ * @param fieldName 支持通配符 ^(a|b)$
+ * @return
+ */
+ public Pagination listPage(Integer pageNumber, int pageSize, Condition cnd, String fieldName) {
+ pageNumber = getPageNumber(pageNumber);
+ pageSize = getPageSize(pageSize);
+ Pager pager = this.dao().createPager(pageNumber, pageSize);
+ List list = Daos.ext(this.dao(), FieldFilter.create(this.getEntityClass(), fieldName)).query(this.getEntityClass(), cnd, pager);
+ pager.setRecordCount(this.dao().count(this.getEntityClass(), cnd));
+ return new Pagination(pageNumber, pageSize, pager.getRecordCount(), list);
+ }
+
+ /**
+ * 关联查询
+ *
+ * @param pageNumber
+ * @param pageSize
+ * @param cnd
+ * @param linkName 支持通配符 ^(a|b)$
+ * @return
+ */
+ public Pagination listPageLinks(Integer pageNumber, int pageSize, Condition cnd, String linkName) {
+ pageNumber = getPageNumber(pageNumber);
+ pageSize = getPageSize(pageSize);
+ Pager pager = this.dao().createPager(pageNumber, pageSize);
+ List list = this.dao().query(this.getEntityClass(), cnd, pager);
+ pager.setRecordCount(this.dao().count(this.getEntityClass(), cnd));
+ if (!Strings.isBlank(linkName)) {
+ this.dao().fetchLinks(list, linkName);
+ }
+ return new Pagination(pageNumber, pageSize, pager.getRecordCount(), list);
+ }
+
+ /**
+ * @param pageNumber
+ * @param pageSize
+ * @param cnd
+ * @param linkName 支持通配符 ^(a|b)$
+ * @param subCnd 子查询条件
+ * @return
+ */
+ public Pagination listPageLinks(Integer pageNumber, int pageSize, Condition cnd, String linkName, Condition subCnd) {
+ pageNumber = getPageNumber(pageNumber);
+ pageSize = getPageSize(pageSize);
+ Pager pager = this.dao().createPager(pageNumber, pageSize);
+ List list = this.dao().query(this.getEntityClass(), cnd, pager);
+ pager.setRecordCount(this.dao().count(this.getEntityClass(), cnd));
+ if (!Strings.isBlank(linkName)) {
+ if (subCnd != null)
+ this.dao().fetchLinks(list, linkName, subCnd);
+ else
+ this.dao().fetchLinks(list, linkName);
+ }
+ return new Pagination(pageNumber, pageSize, pager.getRecordCount(), list);
+ }
+
+ /**
+ * 分页查询(tabelName)
+ *
+ * @param pageNumber
+ * @param pageSize
+ * @param tableName
+ * @param cnd
+ * @return
+ */
+ public Pagination listPage(Integer pageNumber, int pageSize, String tableName, Condition cnd) {
+ pageNumber = getPageNumber(pageNumber);
+ pageSize = getPageSize(pageSize);
+ Pager pager = this.dao().createPager(pageNumber, pageSize);
+ List list = this.dao().query(tableName, cnd, pager);
+ pager.setRecordCount(this.dao().count(tableName, cnd));
+ return new Pagination(pageNumber, pageSize, pager.getRecordCount(), list);
+ }
+
+ /**
+ * 分页查询并返回包含实体类内容的NutMap对象
+ *
+ * @param pageNumber
+ * @param cnd
+ * @return
+ */
+ @Override
+ public Pagination listPageMap(Integer pageNumber, Condition cnd) {
+ return listPageMap(pageNumber, DEFAULT_PAGE_NUMBER, cnd);
+ }
+
+ /**
+ * 分页查询并返回包含实体类内容的NutMap对象
+ *
+ * @param pageNumber
+ * @param pageSize
+ * @param cnd
+ * @return
+ */
+ @Override
+ public Pagination listPageMap(Integer pageNumber, int pageSize, Condition cnd) {
+ pageNumber = getPageNumber(pageNumber);
+ pageSize = getPageSize(pageSize);
+ Pager pager = this.dao().createPager(pageNumber, pageSize);
+ List list = this.dao().query(this.getEntityClass(), cnd, pager);
+ pager.setRecordCount(this.dao().count(this.getEntityClass(), cnd));
+ List mapList = new ArrayList<>();
+ for (Object obj : list) {
+ mapList.add(Lang.obj2nutmap(obj));
+ }
+ return new Pagination(pageNumber, pageSize, pager.getRecordCount(), mapList);
+ }
+
+ /**
+ * 默认页码
+ *
+ * @param pageNumber
+ * @return
+ */
+ protected int getPageNumber(Integer pageNumber) {
+ return Lang.isEmpty(pageNumber) ? 1 : pageNumber;
+ }
+
+ /**
+ * 默认页大小
+ *
+ * @param pageSize
+ * @return
+ */
+ protected int getPageSize(int pageSize) {
+ return pageSize == 0 ? DEFAULT_PAGE_NUMBER : pageSize;
+ }
+
+ /**
+ * DataTable Page
+ *
+ * @param length 页大小
+ * @param start start
+ * @param draw draw
+ * @param orders 排序
+ * @param columns 字段
+ * @param cnd 查询条件
+ * @param linkName 关联查询 支持通配符 ^(a|b)$
+ * @return
+ */
+ public NutMap data(int length, int start, int draw, List orders, List columns, Cnd cnd, String linkName) {
+ NutMap re = new NutMap();
+ if (orders != null && orders.size() > 0) {
+ for (DataTableOrder order : orders) {
+ DataTableColumn col = columns.get(order.getColumn());
+ cnd.orderBy(Sqls.escapeSqlFieldValue(col.getData()).toString(), order.getDir());
+ }
+ }
+ Pager pager = new OffsetPager(start, length);
+ re.put("recordsFiltered", this.dao().count(this.getEntityClass(), cnd));
+ List> list = this.dao().query(this.getEntityClass(), cnd, pager);
+ if (!Strings.isBlank(linkName)) {
+ this.dao().fetchLinks(list, linkName);
+ }
+ re.put("data", list);
+ re.put("draw", draw);
+ re.put("recordsTotal", length);
+ return re;
+ }
+
+ /**
+ * DataTable Page
+ *
+ * @param length 页大小
+ * @param start start
+ * @param draw draw
+ * @param orders 排序
+ * @param columns 字段
+ * @param cnd 查询条件
+ * @param linkName 关联查询 支持通配符 ^(a|b)$
+ * @param subCnd 关联查询条件
+ * @return
+ */
+ public NutMap data(int length, int start, int draw, List orders, List columns, Cnd cnd, String linkName, Cnd subCnd) {
+ NutMap re = new NutMap();
+ if (orders != null && orders.size() > 0) {
+ for (DataTableOrder order : orders) {
+ DataTableColumn col = columns.get(order.getColumn());
+ cnd.orderBy(Sqls.escapeSqlFieldValue(col.getData()).toString(), order.getDir());
+ }
+ }
+ Pager pager = new OffsetPager(start, length);
+ re.put("recordsFiltered", this.dao().count(this.getEntityClass(), cnd));
+ List> list = this.dao().query(this.getEntityClass(), cnd, pager);
+ if (!Strings.isBlank(linkName)) {
+ if (subCnd != null)
+ this.dao().fetchLinks(list, linkName, subCnd);
+ else
+ this.dao().fetchLinks(list, linkName);
+ }
+ re.put("data", list);
+ re.put("draw", draw);
+ re.put("recordsTotal", length);
+ return re;
+ }
+
+ /**
+ * DataTable Page 自定义SQL
+ *
+ * @param length 页大小
+ * @param start start
+ * @param draw draw
+ * @param countSql 统计查询语句
+ * @param orderSql 结果查询语句
+ * @return
+ */
+ public NutMap data(int length, int start, int draw, Sql countSql, Sql orderSql) {
+ NutMap re = new NutMap();
+ Pager pager = new OffsetPager(start, length);
+ pager.setRecordCount((int) Daos.queryCount(this.dao(), countSql));// 记录数需手动设置
+ orderSql.setPager(pager);
+ orderSql.setCallback(Sqls.callback.records());
+ this.dao().execute(orderSql);
+ re.put("recordsFiltered", pager.getRecordCount());
+ re.put("data", orderSql.getList(Record.class));
+ re.put("draw", draw);
+ re.put("recordsTotal", length);
+ return re;
+ }
+
+ /**
+ * DataTable Page 自定义SQL
+ *
+ * @param length 页大小
+ * @param start start
+ * @param draw draw
+ * @param countSql 统计查询语句
+ * @param orderSql 结果查询语句
+ * @param countOnly 统计查询语句是否只有count()
+ * @return
+ */
+ public NutMap data(int length, int start, int draw, Sql countSql, Sql orderSql, boolean countOnly) {
+ if (!countOnly) {
+ return this.data(length, start, draw, countSql, orderSql);
+ }
+ NutMap re = new NutMap();
+ Pager pager = new OffsetPager(start, length);
+ countSql.setCallback(Sqls.callback.integer());
+ this.dao().execute(countSql);
+ pager.setRecordCount(countSql.getInt());// 记录数需手动设置
+ orderSql.setPager(pager);
+ orderSql.setCallback(Sqls.callback.records());
+ this.dao().execute(orderSql);
+ re.put("recordsFiltered", pager.getRecordCount());
+ re.put("data", orderSql.getList(Record.class));
+ re.put("draw", draw);
+ re.put("recordsTotal", length);
+ return re;
+ }
+
+ /**
+ * DataTable Page
+ *
+ * @param length 页大小
+ * @param start start
+ * @param draw draw
+ * @param cnd 查询条件
+ * @param linkName 关联查询 支持通配符 ^(a|b)$
+ * @return
+ */
+ public NutMap data(int length, int start, int draw, Cnd cnd, String linkName) {
+ NutMap re = new NutMap();
+ Pager pager = new OffsetPager(start, length);
+ re.put("recordsFiltered", this.dao().count(this.getEntityClass(), cnd));
+ List> list = this.dao().query(this.getEntityClass(), cnd, pager);
+ if (!Strings.isBlank(linkName)) {
+ this.dao().fetchLinks(list, linkName);
+ }
+ re.put("data", list);
+ re.put("draw", draw);
+ re.put("recordsTotal", length);
+ return re;
+ }
+}
diff --git a/backend/src/main/java/com/budwk/app/base/utils/DateUtil.java b/backend/src/main/java/com/budwk/app/base/utils/DateUtil.java
new file mode 100644
index 0000000..13f1487
--- /dev/null
+++ b/backend/src/main/java/com/budwk/app/base/utils/DateUtil.java
@@ -0,0 +1,116 @@
+package com.budwk.app.base.utils;
+
+import org.apache.commons.lang3.time.DateFormatUtils;
+import org.nutz.lang.Times;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+
+/**
+ * Created by wizzer on 2016/6/24.
+ */
+public class DateUtil {
+ private static final Locale DEFAULT_LOCALE = Locale.CHINA;
+ private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+ /**
+ * 获取当前时间(HH:mm:ss)
+ *
+ * @return
+ */
+ public static String getDate() {
+ return DateFormatUtils.format(new Date(), "yyyy-MM-dd", DEFAULT_LOCALE);
+ }
+
+ /**
+ * 获取当前时间(HH:mm:ss)
+ *
+ * @return
+ */
+ public static String getTime() {
+ return DateFormatUtils.format(new Date(), "HH:mm:ss", DEFAULT_LOCALE);
+ }
+
+ /**
+ * 获取当前时间(yyyy-MM-dd HH:mm:ss)
+ *
+ * @return
+ */
+ public static String getDateTime() {
+ return DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss", DEFAULT_LOCALE);
+ }
+
+ /**
+ * 转换日期格式(yyyy-MM-dd HH:mm:ss)
+ *
+ * @param date
+ * @return
+ */
+ public static String formatDateTime(Date date) {
+ if (date == null) return "";
+ return DateFormatUtils.format(date, "yyyy-MM-dd HH:mm:ss", DEFAULT_LOCALE);
+ }
+
+ /**
+ * 转换日期格式(yyyy-MM-dd HH:mm:ss)
+ *
+ * @param date
+ * @param f
+ * @return
+ */
+ public static String format(Date date, String f) {
+ if (date == null) return "";
+ return DateFormatUtils.format(date, f, DEFAULT_LOCALE);
+ }
+
+ /**
+ * 时间戳日期
+ *
+ * @param time
+ * @return
+ */
+ public static String getDate(long time) {
+ return DateFormatUtils.format(new Date(time * 1000), "yyyy-MM-dd HH:mm:ss", DEFAULT_LOCALE);
+ }
+
+ /**
+ * 时间戳日期
+ *
+ * @param time
+ * @param f
+ * @return
+ */
+ public static String getDate(long time, String f) {
+ return DateFormatUtils.format(new Date(time * 1000), f, DEFAULT_LOCALE);
+ }
+
+ /**
+ * 通过字符串时间获取时间戳 nutzwk5.0改为long
+ *
+ * @param date
+ * @return
+ */
+ public static long getTime(String date) {
+ try {
+ return Times.parse(sdf, date).getTime() / 1000;
+ } catch (ParseException e) {
+ return 0;
+ }
+ }
+
+ /**
+ * 通过字符串时间获取时间戳 nutzwk5.0改为long
+ *
+ * @param date
+ * @return
+ */
+ public static long getTime(SimpleDateFormat sdf, String date) {
+ try {
+ return Times.parse(sdf, date).getTime() / 1000;
+ } catch (ParseException e) {
+ return 0;
+ }
+ }
+}
diff --git a/backend/src/main/java/com/budwk/app/base/utils/FileUtil.java b/backend/src/main/java/com/budwk/app/base/utils/FileUtil.java
new file mode 100644
index 0000000..dd2a50a
--- /dev/null
+++ b/backend/src/main/java/com/budwk/app/base/utils/FileUtil.java
@@ -0,0 +1,61 @@
+package com.budwk.app.base.utils;
+
+import org.nutz.lang.util.NutMap;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import java.util.stream.Stream;
+
+/**
+ * @author wizzer@qq.com
+ */
+public class FileUtil {
+
+ /**
+ * 分页获取文件列表
+ *
+ * @param basePath 目录
+ * @param pageNumber 页码
+ * @param pageSize 页大小
+ * @param sort 按文件名排序
+ * @return 列表
+ * @throws Exception
+ */
+ public static NutMap readListPage(String basePath, Integer pageNumber, Integer pageSize, String sort)
+ throws Exception {
+ int offset = (pageNumber - 1) * pageSize;
+ int limit = pageNumber * pageSize;
+ long total = 0;
+ List list = new ArrayList<>();
+ Comparator comparator = Comparator.naturalOrder();
+ if ("desc".equals(sort)) {
+ comparator = Comparator.reverseOrder();
+ }
+ try (Stream fileList = Files.list(Paths.get(basePath))) {
+ total = fileList.count();
+ }
+ try (Stream fileList = Files.list(Paths.get(basePath)).sorted(comparator).skip(offset)
+ .limit(limit)) {
+ fileList.forEach(file -> {
+ NutMap nutMap = NutMap.NEW();
+ String fileName = file.getFileName().toString();
+ nutMap.addv("fileName", fileName);
+ if (Files.isDirectory(file.toAbsolutePath())) {
+ nutMap.addv("folder", true);
+ nutMap.addv("suffix", "folder");
+ } else {
+ String suffix = fileName.substring(fileName.indexOf(".") + 1).toLowerCase();
+ nutMap.addv("folder", false);
+ nutMap.addv("suffix", suffix);
+ }
+ list.add(nutMap);
+ });
+ return NutMap.NEW().addv("total", total).addv("list", list);
+ }
+ }
+
+}
diff --git a/backend/src/main/java/com/budwk/app/base/utils/MapUtil.java b/backend/src/main/java/com/budwk/app/base/utils/MapUtil.java
new file mode 100644
index 0000000..db91966
--- /dev/null
+++ b/backend/src/main/java/com/budwk/app/base/utils/MapUtil.java
@@ -0,0 +1,33 @@
+package com.budwk.app.base.utils;
+
+import java.util.Comparator;
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * Created by wizzer on 2017/7/21.
+ */
+public class MapUtil {
+ /**
+ * 使用 Map按key进行排序
+ *
+ * @param map
+ * @return
+ */
+ public static Map sortMapByKey(Map map) {
+ if (map == null || map.isEmpty()) {
+ return null;
+ }
+ Map sortMap = new TreeMap<>(
+ new MapKeyComparator());
+ sortMap.putAll(map);
+ return sortMap;
+ }
+}
+
+class MapKeyComparator implements Comparator {
+ @Override
+ public int compare(String str1, String str2) {
+ return str1.compareTo(str2);
+ }
+}
\ No newline at end of file
diff --git a/backend/src/main/java/com/budwk/app/base/utils/MsgApi.java b/backend/src/main/java/com/budwk/app/base/utils/MsgApi.java
new file mode 100644
index 0000000..f0ca389
--- /dev/null
+++ b/backend/src/main/java/com/budwk/app/base/utils/MsgApi.java
@@ -0,0 +1,173 @@
+//package com.budwk.app.base.utils;
+//
+//import com.fasterxml.jackson.databind.ObjectMapper;
+//import lombok.extern.slf4j.Slf4j;
+//import org.apache.commons.net.util.Base64;
+//import org.nutz.aop.interceptor.async.Async;
+//import org.nutz.ioc.loader.annotation.IocBean;
+//import org.nutz.lang.Strings;
+//import java.security.MessageDigest;
+//import java.security.NoSuchAlgorithmException;
+//import java.text.SimpleDateFormat;
+//import java.util.*;
+//import java.util.concurrent.ExecutorService;
+//import java.util.stream.Collectors;
+//
+//@IocBean
+//@Slf4j
+//public class MsgApi {
+//
+//
+// /**
+// * token -redis - name
+// */
+// private static final String msgTokenName = "msg_token";
+// /**
+// * 发送消息接口
+// */
+// private static final String smsSendMsgApi = "http://txgl.cug.edu.cn/tp_mp/service/SmsService?wsdl";
+//
+// private static final String weChatSendMsgApi = "http://txgl.cug.edu.cn/tp_mp/service/WechatService?wsdl";
+// /**
+// * 密钥
+// */
+// private static final String PASSWORD = "kzOm2sr9ki0ZREJX6GbrpQJyM5E=";
+//
+// /**
+// * 通用模板id
+// */
+// private static final String COMMON_TEMPLATE_ID = "7218401631600640";
+//
+// private static ExecutorService pool;
+//
+// /**
+// * 发送短信信息
+// */
+// @Async
+// public void sendSmsMsg(String person_info, String sms_info) {
+//
+//
+// ObjectMapper mapper = new ObjectMapper();
+// Map map = new HashMap<>();
+// try {
+//// ApplicationContext appContext = new ClassPathXmlApplicationContext(new String[]{});
+//// Resource resource = appContext.getResource("url:" + smsSendMsgApi);
+// Date date = new Date();
+// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+// //秘钥,必须
+// map.put("secret_key", getSHA(PASSWORD));
+//
+// //对应的第三方系统名称(协议值),必须
+// map.put("tp_name", "zhihuigonghui");
+//
+// //对应的模块名称(协议值),必须
+// map.put("module_id", "sms");
+//
+// //对应的平台系统名称(协议值),必须
+// map.put("sys_id", "mp");
+//
+// //对应的接口方法名称(协议值),必须
+// map.put("interface_method", "saveSmsInfo");
+//
+// //接收人信息,每个人员信息格式为: 名字|学工号|部门ID|部门名称|电话号码|邮箱,人与人之间用“^@^”隔开(如果数据无法提供,可以写空,但是“|”不可省略),必须
+// map.put("person_info", person_info);
+//
+// //邮件内容,必须
+// map.put("sms_info", sms_info);
+//
+// //发送优先级(1:紧急通知;2:验证码;3:立即发送;4:发送),必须
+// map.put("send_priority", "3");
+//
+// //发送时间,String型,可为空,参数不可省略
+// map.put("send_time", sdf.format(date));
+//
+// //发送人UID,发送模板的时候不可为空,参数不可省略;发送人一般为部门信息管理员(在职教职工6位工号)。
+// map.put("operator_id", "");
+//
+// //发送人ID_NUMBER,需要发送回执的时候不可为空,其他可为空,参数不可省略;发送人一般为部门信息管理员(在职教职工6位工号)。
+// map.put("operator_id_number", "");
+//
+// //发送人姓名,需和发送人工号匹配,可为空,参数不可省略。
+// map.put("operator_name", "");
+//
+// //发送人部门ID,不可为空,参数不可省略,有关于短信的配额问题;必须填写实际的发送部门编号,可咨询网信中心。
+// map.put("operator_unit_id", "421");
+//
+// //发送人部门名称,可为空,参数不可省略。使用短信配额的机构名称,和部门编号匹配。
+// map.put("operator_unit_name", "工会");
+//
+// //发送模板选择,不发送模板值为”0”,参数不可省略。这里使用网信中心提供的通用模板ID:7218401631600640。模板内容:【智慧地大】${ person_info}您好!${ person_send }通知信息:${ sms_info }。
+// map.put("templet_id", COMMON_TEMPLATE_ID);
+//
+// //发送回执选择,不发送模板值为”0”,参数不可省略
+// map.put("receipt_id", "0");
+//
+// //发送人签名,参数不可省略。通用模板中有“发送人签名”标签,必须填写准确的系统名称。
+// map.put("person_send", "智慧工会");
+//
+// //发送平台码,必须
+// map.put("send_sys_id", "1");
+//
+// //发送平台名称,必须
+// map.put("send_sys_name", "智慧工会");
+//
+// //发送使用的浏览器,可为空,参数不可省略
+// map.put("user_browser", "");
+// //转化
+// String json = mapper.writeValueAsString(map);
+// System.out.println("json:" + json);
+// //调用
+//
+// try {
+// /* Client client = null;
+// client = new Client(resource.getInputStream(), null);
+// //输出结果 boolean型,true代表推送成功,false为失败
+// Object[] result = client.invoke("saveSmsInfo", new Object[]{json});
+// System.out.println(result[0]);
+// System.out.println(person_info);
+// log.info("短信发送成功!{}", result[0]);
+// client.close();*/
+// } catch (Exception e) {
+// e.printStackTrace();
+// }
+//
+//
+// } catch (Exception e) {
+// e.printStackTrace();
+// }
+// return;
+// }
+//
+// /**
+// * 获取token
+// *
+// * @return
+// */
+// private String getSHA(String password) {
+// try {
+// MessageDigest sha = MessageDigest.getInstance("SHA");
+// sha.update(password.getBytes());
+// byte[] hash = sha.digest();
+// return new String(Base64.encodeBase64(hash));
+// } catch (NoSuchAlgorithmException e1) {
+// e1.printStackTrace();
+// }
+// return "";
+//
+// }
+//
+// public String userData(String mobile) {
+// List list = new ArrayList<>();
+// list.add("");
+// list.add("");
+// list.add("");
+// list.add("");
+// list.add(Strings.isNotBlank(mobile) ? mobile : "");
+// list.add("");
+// list.add("");
+// String collect = list.stream().collect(Collectors.joining("|"));
+// return collect;
+// }
+//
+//
+//}
diff --git a/backend/src/main/java/com/budwk/app/base/utils/PageUtil.java b/backend/src/main/java/com/budwk/app/base/utils/PageUtil.java
new file mode 100644
index 0000000..818e2ea
--- /dev/null
+++ b/backend/src/main/java/com/budwk/app/base/utils/PageUtil.java
@@ -0,0 +1,13 @@
+package com.budwk.app.base.utils;
+
+import org.nutz.lang.util.NutMap;
+
+/**
+ * Created by wizzer on 2018.09
+ */
+public class PageUtil {
+ public static String getOrder(String key) {
+ NutMap map = NutMap.NEW().addv("ascending", "asc").addv("descending", "desc");
+ return map.getString(key);
+ }
+}
diff --git a/backend/src/main/java/com/budwk/app/base/utils/PinyinUtil.java b/backend/src/main/java/com/budwk/app/base/utils/PinyinUtil.java
new file mode 100644
index 0000000..ad115dd
--- /dev/null
+++ b/backend/src/main/java/com/budwk/app/base/utils/PinyinUtil.java
@@ -0,0 +1,68 @@
+package com.budwk.app.base.utils;
+
+import net.sourceforge.pinyin4j.PinyinHelper;
+import org.nutz.ioc.loader.annotation.IocBean;
+
+/**
+ * Created by wizzer on 2017/5/24.
+ */
+@IocBean
+public class PinyinUtil {
+ /**
+ * 将汉字转换为全拼
+ */
+ public static String getPingYin(String name) {
+ char[] charArray = name.toCharArray();
+ StringBuilder pinyin = new StringBuilder();
+ for (int i = 0; i < charArray.length; i++) {
+ if (Character.toString(charArray[i]).matches("[\\u4E00-\\u9FA5]+")) {
+ pinyin.append(PinyinHelper.toHanyuPinyinStringArray(charArray[i])[0]);
+ } else {
+ pinyin.append(charArray[i]);
+ }
+ }
+ return pinyin.toString();
+ }
+
+ /**
+ * 返回中文的首字母
+ *
+ * @param str
+ * @return
+ */
+ public static String getPinYinHeadChar(String str) {
+
+ String convert = "";
+ for (int j = 0; j < str.length(); j++) {
+ char word = str.charAt(j);
+ String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(word);
+ if (pinyinArray != null) {
+ convert += pinyinArray[0].charAt(0);
+ } else {
+ convert += word;
+ }
+ }
+ return convert;
+ }
+
+ /**
+ * 将字符串转移为ASCII码
+ *
+ * @param cnStr
+ * @return
+ */
+ public static String getCnASCII(String cnStr) {
+ StringBuffer strBuf = new StringBuffer();
+ byte[] bGBK = cnStr.getBytes();
+ for (int i = 0; i < bGBK.length; i++) {
+ strBuf.append(Integer.toHexString(bGBK[i] & 0xff));
+ }
+ return strBuf.toString();
+ }
+
+// public static void main(String[] args) {
+// System.out.println(getPingYin("綦江qq县"));
+// System.out.println(getPinYinHeadChar("綦江县"));
+// System.out.println(getCnASCII("綦江县"));
+// }
+}
diff --git a/backend/src/main/java/com/budwk/app/base/utils/PwdUtil.java b/backend/src/main/java/com/budwk/app/base/utils/PwdUtil.java
new file mode 100644
index 0000000..ccf58c9
--- /dev/null
+++ b/backend/src/main/java/com/budwk/app/base/utils/PwdUtil.java
@@ -0,0 +1,43 @@
+package com.budwk.app.base.utils;
+
+import org.nutz.lang.Lang;
+
+import java.security.MessageDigest;
+
+/**
+ * 为老兼容老的密码加密方式
+ *
+ * @author wizzer@qq.com
+ */
+public class PwdUtil {
+
+ public static String getPassword(String passowrd, String salt) {
+ byte[] bytes = hash(passowrd.getBytes(), salt.getBytes(), 1024);
+ if (bytes != null) {
+ return Lang.fixedHexString(bytes);
+ }
+ return "";
+ }
+
+ public static byte[] hash(byte[] bytes, byte[] salt, int hashIterations) {
+ try {
+ MessageDigest digest = MessageDigest.getInstance("SHA-256");
+ if (salt != null) {
+ digest.reset();
+ digest.update(salt);
+ }
+
+ byte[] hashed = digest.digest(bytes);
+ int iterations = hashIterations - 1;
+
+ for (int i = 0; i < iterations; ++i) {
+ digest.reset();
+ hashed = digest.digest(hashed);
+ }
+ return hashed;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+}
diff --git a/backend/src/main/java/com/budwk/app/base/utils/SignUtil.java b/backend/src/main/java/com/budwk/app/base/utils/SignUtil.java
new file mode 100644
index 0000000..f90ec23
--- /dev/null
+++ b/backend/src/main/java/com/budwk/app/base/utils/SignUtil.java
@@ -0,0 +1,32 @@
+package com.budwk.app.base.utils;
+
+import org.nutz.lang.Lang;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Created by wizzer on 2018/6/28.
+ */
+public class SignUtil {
+
+ public static String createSign(String appkey, Map params) {
+ Map map = MapUtil.sortMapByKey(params);
+ StringBuffer sb = new StringBuffer();
+ Set keySet = map.keySet();
+ Iterator it = keySet.iterator();
+ while (it.hasNext()) {
+ String k = it.next();
+ String v = (String) map.get(k);
+ if (null != v && !"".equals(v)
+ && !"sign".equals(k)) {
+ sb.append(k + "=" + v + "&");
+ }
+ }
+ sb.append("appkey=" + appkey);
+ String sign = Lang.md5(sb.toString());
+ return sign;
+ }
+
+}
diff --git a/backend/src/main/java/com/budwk/app/base/utils/StringUtil.java b/backend/src/main/java/com/budwk/app/base/utils/StringUtil.java
new file mode 100644
index 0000000..2915ede
--- /dev/null
+++ b/backend/src/main/java/com/budwk/app/base/utils/StringUtil.java
@@ -0,0 +1,86 @@
+package com.budwk.app.base.utils;
+
+import org.nutz.ioc.loader.annotation.IocBean;
+import org.nutz.json.Json;
+import org.nutz.json.JsonFormat;
+import org.nutz.lang.Strings;
+
+import java.util.Random;
+
+/**
+ * Created by wizzer on 2018/3/17.
+ */
+public class StringUtil {
+ /**
+ * 去掉URL中?后的路径
+ *
+ * @param p
+ * @return
+ */
+ public static String getPath(String p) {
+ if (Strings.sNull(p).contains("?")) {
+ return p.substring(0, p.indexOf("?"));
+ }
+ return Strings.sNull(p);
+ }
+
+ /**
+ * 获得父节点ID
+ *
+ * @param s
+ * @return
+ */
+ public static String getParentId(String s) {
+ if (!Strings.isEmpty(s) && s.length() > 4) {
+ return s.substring(0, s.length() - 4);
+ }
+ return "";
+ }
+
+ /**
+ * 得到n位随机数
+ *
+ * @param s
+ * @return
+ */
+ public static String getRndNumber(int s) {
+ Random ra = new Random();
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < s; i++) {
+ sb.append(String.valueOf(ra.nextInt(8)));
+ }
+ return sb.toString();
+ }
+
+ /**
+ * 判断是否以字符串开头
+ *
+ * @param str
+ * @param s
+ * @return
+ */
+ public boolean startWith(String str, String s) {
+ return Strings.sNull(str).startsWith(Strings.sNull(s));
+ }
+
+ /**
+ * 判断是否包含字符串
+ *
+ * @param str
+ * @param s
+ * @return
+ */
+ public boolean contains(String str, String s) {
+ return Strings.sNull(str).contains(Strings.sNull(s));
+ }
+
+ /**
+ * 将对象转为JSON字符串(页面上使用)
+ *
+ * @param obj
+ * @return
+ */
+ public String toJson(Object obj) {
+ return Json.toJson(obj, JsonFormat.compact());
+ }
+}
diff --git a/backend/src/main/java/com/budwk/app/base/utils/WebUtil.java b/backend/src/main/java/com/budwk/app/base/utils/WebUtil.java
new file mode 100644
index 0000000..75cdc5e
--- /dev/null
+++ b/backend/src/main/java/com/budwk/app/base/utils/WebUtil.java
@@ -0,0 +1,38 @@
+package com.budwk.app.base.utils;
+
+import org.nutz.json.JsonFormat;
+import org.nutz.lang.Encoding;
+import org.nutz.mvc.view.UTF8JsonView;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * @author wizzer@qq.com
+ */
+public class WebUtil {
+
+ public static String AjaxEncode = Encoding.UTF8;
+
+ public static boolean isAjax(HttpServletRequest req) {
+ String value = req.getHeader("X-Requested-With");
+ return value != null && "XMLHttpRequest".equalsIgnoreCase(value.trim());
+ }
+
+ public static void rendAjaxResp(HttpServletRequest req, HttpServletResponse resp, Object re) {
+ try {
+ if (AjaxEncode != null) {
+ resp.setCharacterEncoding(AjaxEncode);
+ }
+ (new UTF8JsonView(JsonFormat.compact())).render(req, resp, re);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ public static boolean isMiniApp(HttpServletRequest request) {
+ return request.getHeader("X-WK-MiniApp") != null;
+ }
+}
diff --git a/backend/src/main/java/com/budwk/app/client/auth/controller/ClientAuthController.java b/backend/src/main/java/com/budwk/app/client/auth/controller/ClientAuthController.java
new file mode 100644
index 0000000..4e26cf3
--- /dev/null
+++ b/backend/src/main/java/com/budwk/app/client/auth/controller/ClientAuthController.java
@@ -0,0 +1,84 @@
+package com.budwk.app.client.auth.controller;
+
+import cn.dev33.satoken.stp.StpUtil;
+import com.budwk.app.base.exception.BaseException;
+import com.budwk.app.base.result.Result;
+import com.budwk.app.sys.models.Client_user;
+import com.budwk.app.sys.models.Sys_log;
+import com.budwk.app.sys.models.Sys_user;
+import com.budwk.app.sys.services.SysMsgService;
+import com.budwk.app.sys.services.SysUserService;
+import com.budwk.app.web.commons.auth.satoken.StpClientUtil;
+import com.budwk.app.web.commons.auth.service.ValidateService;
+import com.budwk.app.web.commons.slog.SLogService;
+import lombok.extern.slf4j.Slf4j;
+import org.nutz.dao.Cnd;
+import org.nutz.dao.Dao;
+import org.nutz.integration.jedis.RedisService;
+import org.nutz.ioc.loader.annotation.Inject;
+import org.nutz.ioc.loader.annotation.IocBean;
+import org.nutz.mvc.annotation.At;
+import org.nutz.mvc.annotation.Filters;
+import org.nutz.mvc.annotation.Ok;
+import org.nutz.mvc.annotation.Param;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+
+/**
+ * 客户端登录认证
+ */
+@IocBean
+@At("/client/auth")
+@Slf4j
+public class ClientAuthController {
+
+ @Inject
+ private Dao dao;
+ @Inject
+ private SysUserService sysUserService;
+ @Inject
+ private SLogService sLogService;
+ @Inject
+ private RedisService redisService;
+ @Inject
+ private SysMsgService sysMsgService;
+ @Inject
+ private ValidateService validateService;
+
+ @At("")
+ @Ok("beetl:/platform/sys/login.html")
+ @Filters
+ public void login(HttpServletRequest req, HttpSession session) {
+ }
+
+ /**
+ * 短信登录
+ * @param mobile 手机号
+ * @param code 验证码
+ * @param req 请求
+ */
+ @At("/doSmsLogin")
+ @Ok("json")
+ public Object doSmsLogin(@Param("mobile") String mobile, @Param("code") String code, HttpServletRequest req) {
+ try {
+ int count = dao.count(Client_user.class, Cnd.where(Client_user::getMobile, "=", mobile));
+ if (count == 0) {
+ return Result.error("手机号不存在");
+ }
+ Client_user user = null;
+ validateService.checkSMSCode(mobile, code);
+ user = dao.fetch(Client_user.class, Cnd.where(Client_user::getMobile, "=", mobile));
+ if (user == null) {
+ return Result.error("用户登录失败");
+ }
+ StpClientUtil.STP.login(user.getId());
+ StpClientUtil.STP.checkLogin();
+ return Result.success("login.success");
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ return Result.error(e.getMessage());
+ }
+ }
+
+}
diff --git a/backend/src/main/java/com/budwk/app/client/module/activity/controller/ClientActivityController.java b/backend/src/main/java/com/budwk/app/client/module/activity/controller/ClientActivityController.java
new file mode 100644
index 0000000..39fdbae
--- /dev/null
+++ b/backend/src/main/java/com/budwk/app/client/module/activity/controller/ClientActivityController.java
@@ -0,0 +1,47 @@
+package com.budwk.app.client.module.activity.controller;
+
+import com.budwk.app.base.page.PageForm;
+import com.budwk.app.base.page.Pagination;
+import com.budwk.app.base.result.Result;
+import com.budwk.app.client.module.activity.service.ClientActivityService;
+import org.nutz.dao.Cnd;
+import org.nutz.dao.Sqls;
+import org.nutz.dao.sql.Sql;
+import org.nutz.ioc.loader.annotation.Inject;
+import org.nutz.ioc.loader.annotation.IocBean;
+import org.nutz.mvc.adaptor.JsonAdaptor;
+import org.nutz.mvc.annotation.AdaptBy;
+import org.nutz.mvc.annotation.At;
+import org.nutz.mvc.annotation.Ok;
+
+@IocBean
+@At("/client/activity")
+@Ok("json:full")
+public class ClientActivityController {
+
+ @Inject
+ private ClientActivityService clientActivityService;
+
+ @At
+ @AdaptBy(type = JsonAdaptor.class)
+ public Result pageData(PageForm pageForm) {
+ Sql sql = Sqls.create("""
+ SELECT
+ t1.id,
+ t1.title,
+ t1.address,
+ t1.startTime,
+ t1.endTime,
+ t1.signStartTime,
+ t1.signEndTime
+ FROM
+ activity t1
+ $condition
+ """);
+ Cnd cnd = Cnd.NEW();
+ sql.setCondition(cnd);
+ Pagination pagination = clientActivityService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
+ return Result.success(pagination);
+ }
+
+}
diff --git a/backend/src/main/java/com/budwk/app/client/module/activity/controller/ClientHomeController.java b/backend/src/main/java/com/budwk/app/client/module/activity/controller/ClientHomeController.java
new file mode 100644
index 0000000..2c2a0a2
--- /dev/null
+++ b/backend/src/main/java/com/budwk/app/client/module/activity/controller/ClientHomeController.java
@@ -0,0 +1,18 @@
+package com.budwk.app.client.module.activity.controller;
+
+import org.nutz.ioc.loader.annotation.IocBean;
+import org.nutz.mvc.annotation.At;
+import org.nutz.mvc.annotation.Ok;
+
+@IocBean
+@At("/client/home")
+@Ok("json:full")
+public class ClientHomeController {
+
+ @At("")
+ @Ok("re")
+ public String index(){
+ return "beetl:/client/home/index.html";
+ }
+
+}
diff --git a/backend/src/main/java/com/budwk/app/client/module/activity/service/ClientActivityService.java b/backend/src/main/java/com/budwk/app/client/module/activity/service/ClientActivityService.java
new file mode 100644
index 0000000..cd851a1
--- /dev/null
+++ b/backend/src/main/java/com/budwk/app/client/module/activity/service/ClientActivityService.java
@@ -0,0 +1,7 @@
+package com.budwk.app.client.module.activity.service;
+
+import com.budwk.app.base.service.BaseService;
+import com.budwk.app.module.activity.models.Activity;
+
+public interface ClientActivityService extends BaseService {
+}
diff --git a/backend/src/main/java/com/budwk/app/client/module/activity/service/impl/ClientActivityServiceImpl.java b/backend/src/main/java/com/budwk/app/client/module/activity/service/impl/ClientActivityServiceImpl.java
new file mode 100644
index 0000000..42df4b2
--- /dev/null
+++ b/backend/src/main/java/com/budwk/app/client/module/activity/service/impl/ClientActivityServiceImpl.java
@@ -0,0 +1,14 @@
+package com.budwk.app.client.module.activity.service.impl;
+
+import com.budwk.app.base.service.impl.BaseServiceImpl;
+import com.budwk.app.client.module.activity.service.ClientActivityService;
+import com.budwk.app.module.activity.models.Activity;
+import org.nutz.dao.Dao;
+import org.nutz.ioc.loader.annotation.IocBean;
+
+@IocBean(args = {"refer:dao"})
+public class ClientActivityServiceImpl extends BaseServiceImpl implements ClientActivityService {
+ public ClientActivityServiceImpl(Dao dao) {
+ super(dao);
+ }
+}
diff --git a/backend/src/main/java/com/budwk/app/module/activity/controller/ActivityManageController.java b/backend/src/main/java/com/budwk/app/module/activity/controller/ActivityManageController.java
new file mode 100644
index 0000000..ff0ce72
--- /dev/null
+++ b/backend/src/main/java/com/budwk/app/module/activity/controller/ActivityManageController.java
@@ -0,0 +1,156 @@
+package com.budwk.app.module.activity.controller;
+
+import cn.hutool.core.collection.CollUtil;
+import com.budwk.app.base.page.PageForm;
+import com.budwk.app.base.page.Pagination;
+import com.budwk.app.base.result.Result;
+import com.budwk.app.module.activity.models.Activity;
+import com.budwk.app.module.activity.models.ActivityItem;
+import com.budwk.app.module.activity.service.ActivityManageService;
+import lombok.extern.slf4j.Slf4j;
+import org.nutz.aop.interceptor.ioc.TransAop;
+import org.nutz.dao.Cnd;
+import org.nutz.dao.Dao;
+import org.nutz.ioc.aop.Aop;
+import org.nutz.ioc.loader.annotation.Inject;
+import org.nutz.ioc.loader.annotation.IocBean;
+import org.nutz.mvc.annotation.At;
+import org.nutz.mvc.annotation.Ok;
+import org.nutz.mvc.annotation.Param;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+@IocBean
+@At("/platform/activity/manage")
+@Slf4j
+@Ok("json:full")
+public class ActivityManageController {
+
+ @Inject
+ private Dao dao;
+ @Inject
+ private ActivityManageService activityService;
+
+ @At("")
+ @Ok("beetl:/platform/activity/manage/index.html")
+ public void index() {
+ }
+
+ @At
+ public Result pageData(@Param("pageForm") PageForm pageForm) {
+ Cnd cnd = Cnd.NEW();
+ Pagination pagination = activityService.listPage(pageForm.getPageNumber(), pageForm.getPageSize(), cnd);
+ return Result.success(pagination);
+ }
+
+ /**
+ * 保存活动
+ */
+ @At
+ @Aop(TransAop.READ_COMMITTED)
+ public Result save(Activity activity) {
+// activityService.insertWith(activity, "items");
+ activityService.insert(activity);
+ return Result.success();
+ }
+
+ /**
+ * 更新活动
+ */
+ @At
+ @Aop(TransAop.READ_COMMITTED)
+ public Result update(Activity activity) {
+ activityService.updateIgnoreNull(activity);
+
+
+// // 查询出旧的活动信息
+// Activity oldActivity = activityService.fetch(activity.getId());
+// activityService.fetchLinks(oldActivity, "items");
+//
+// // 更新活动基础信息
+// activityService.updateIgnoreNull(activity);
+//
+// // 更新项目信息 找出需要新增的 找出需要删除的
+// List oldItemIdList = oldActivity.getItems().stream().map(ActivityItem::getId).toList();
+// dao.insertOrUpdate(activity.getItems());
+// List newItemIdList = activity.getItems().stream().map(ActivityItem::getId).toList();
+//
+// // 删除旧的项目信息
+// Collection deleteItemIdList = CollUtil.subtract(oldItemIdList, newItemIdList);
+// dao.clear(ActivityItem.class, Cnd.where("id", "in", deleteItemIdList));
+
+ return Result.success();
+ }
+
+ /**
+ * 删除活动
+ */
+ @At
+ @Aop(TransAop.READ_COMMITTED)
+ public Result delete(@Param("id") Long id) {
+ // 删除活动信息
+ activityService.delete(id);
+ // 删除项目信息
+ dao.clear(ActivityItem.class, Cnd.where("activityId", "=", id));
+ // 删除报名信息等等。。。。。
+ return Result.success();
+ }
+
+ /**
+ * 获取活动信息
+ */
+ @At
+ @Aop(TransAop.READ_COMMITTED)
+ public Result get(@Param("id") Long id) {
+ Activity activity = activityService.fetch(id);
+ return Result.success(activity);
+ }
+
+ /**
+ * 获取活动信息及项目信息
+ */
+ @At
+ @Aop(TransAop.READ_COMMITTED)
+ public Result getFull(@Param("id") Long id) {
+ Activity activity = activityService.fetch(id);
+ activityService.fetchLinks(activity, "items");
+ return Result.success(activity);
+ }
+
+ /**
+ * 获取项目信息
+ */
+ @At
+ @Aop(TransAop.READ_COMMITTED)
+ public Result getItems(@Param("id") Long id) {
+ List items = dao.query(ActivityItem.class, Cnd.where(ActivityItem::getActivityId, "=", id));
+ return Result.success(items);
+ }
+
+
+ /**
+ * 更新活动项目信息
+ */
+ @At
+ @Aop(TransAop.READ_COMMITTED)
+ public Result updateItem(Long id, @Param("items") ActivityItem[] items) {
+ // 查询出旧的活动信息
+ List oldItems = dao.query(ActivityItem.class, Cnd.where(ActivityItem::getActivityId, "=", id));
+ // 更新项目信息
+ List oldItemIdList = oldItems.stream().map(ActivityItem::getId).toList();
+ // 更新项目信息
+ for (ActivityItem item : items) {
+ item.setActivityId(id);
+ }
+ dao.insertOrUpdate(items);
+ // 找出需要新增的 找出需要删除的
+ List newItemIdList = Arrays.stream(items).map(ActivityItem::getId).toList();
+ // 删除旧的项目信息
+ Collection deleteItemIdList = CollUtil.subtract(oldItemIdList, newItemIdList);
+ dao.clear(ActivityItem.class, Cnd.where("id", "in", deleteItemIdList));
+ return Result.success();
+ }
+
+}
diff --git a/backend/src/main/java/com/budwk/app/module/activity/models/Activity.java b/backend/src/main/java/com/budwk/app/module/activity/models/Activity.java
new file mode 100644
index 0000000..c66cbd8
--- /dev/null
+++ b/backend/src/main/java/com/budwk/app/module/activity/models/Activity.java
@@ -0,0 +1,83 @@
+package com.budwk.app.module.activity.models;
+
+import com.budwk.app.base.model.BaseModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.nutz.dao.entity.annotation.*;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+@EqualsAndHashCode(callSuper = true)
+@Table("activity")
+@TableMeta("{'mysql-charset':'utf8mb4'}")
+@Comment("活动")
+@Data
+public class Activity extends BaseModel {
+
+ @Id
+ @Comment("ID")
+ private Long id;
+
+ @Comment("标题")
+ @Column
+ @ColDefine(type = ColType.VARCHAR, width = 255)
+ private String title;
+
+ @Comment("地点")
+ @Column
+ @ColDefine(type = ColType.VARCHAR, width = 255)
+ private String address;
+
+ @Comment("活动开始时间")
+ @Column
+ @ColDefine(type = ColType.DATETIME)
+ private LocalDateTime startTime;
+
+ @Comment("活动结束时间")
+ @Column
+ @ColDefine(type = ColType.DATETIME)
+ private LocalDateTime endTime;
+
+ @Comment("报名开始时间")
+ @Column
+ @ColDefine(type = ColType.DATETIME)
+ private LocalDateTime signStartTime;
+
+ @Comment("报名结束时间")
+ @Column
+ @ColDefine(type = ColType.DATETIME)
+ private LocalDateTime signEndTime;
+
+ @Comment("主办单位")
+ @Column
+ @ColDefine(type = ColType.VARCHAR, width = 255)
+ private String hostUnit;
+
+ @Comment("承办单位")
+ @Column
+ @ColDefine(type = ColType.VARCHAR, width = 255)
+ private String coHostUnit;
+
+ @Comment("联系人")
+ @Column
+ @ColDefine(type = ColType.VARCHAR, width = 50)
+ private String contact;
+
+ @Comment("活动内容")
+ @Column
+ @ColDefine(type = ColType.TEXT)
+ private String content;
+
+ @Comment("封面")
+ @Column
+ @ColDefine(type = ColType.VARCHAR, width = 500)
+ private String cover;
+
+ /**
+ * 项目列表
+ */
+ @Many(field = "activityId")
+ private List items;
+
+}
diff --git a/backend/src/main/java/com/budwk/app/module/activity/models/ActivityItem.java b/backend/src/main/java/com/budwk/app/module/activity/models/ActivityItem.java
new file mode 100644
index 0000000..23cb25a
--- /dev/null
+++ b/backend/src/main/java/com/budwk/app/module/activity/models/ActivityItem.java
@@ -0,0 +1,43 @@
+package com.budwk.app.module.activity.models;
+
+import com.budwk.app.base.model.BaseModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.nutz.dao.entity.annotation.*;
+
+@EqualsAndHashCode(callSuper = true)
+@Table("activity_item")
+@TableMeta("{'mysql-charset':'utf8mb4'}")
+@Comment("活动项目")
+@Data
+public class ActivityItem extends BaseModel {
+
+ @Id
+ @Comment("ID")
+ private Long id;
+
+ @Column
+ @Comment("活动ID")
+ @ColDefine(type = ColType.INT)
+ private Long activityId;
+
+ @Comment("项目名称")
+ @Column
+ @ColDefine(type = ColType.VARCHAR, width = 30)
+ private String name;
+
+ @Comment("活动形式")
+ @Column
+ @ColDefine(type = ColType.VARCHAR, width = 300)
+ private String form;
+
+ @Comment("评分规则")
+ @Column
+ @ColDefine(type = ColType.VARCHAR, width = 300)
+ private String rule;
+
+ @Comment("排序")
+ @Column
+ @ColDefine(type = ColType.INT)
+ private Integer sort;
+}
diff --git a/backend/src/main/java/com/budwk/app/module/activity/service/ActivityManageService.java b/backend/src/main/java/com/budwk/app/module/activity/service/ActivityManageService.java
new file mode 100644
index 0000000..a1e30d3
--- /dev/null
+++ b/backend/src/main/java/com/budwk/app/module/activity/service/ActivityManageService.java
@@ -0,0 +1,7 @@
+package com.budwk.app.module.activity.service;
+
+import com.budwk.app.base.service.BaseService;
+import com.budwk.app.module.activity.models.Activity;
+
+public interface ActivityManageService extends BaseService {
+}
diff --git a/backend/src/main/java/com/budwk/app/module/activity/service/impl/ActivityManageServiceImpl.java b/backend/src/main/java/com/budwk/app/module/activity/service/impl/ActivityManageServiceImpl.java
new file mode 100644
index 0000000..c033bc2
--- /dev/null
+++ b/backend/src/main/java/com/budwk/app/module/activity/service/impl/ActivityManageServiceImpl.java
@@ -0,0 +1,14 @@
+package com.budwk.app.module.activity.service.impl;
+
+import com.budwk.app.base.service.impl.BaseServiceImpl;
+import com.budwk.app.module.activity.models.Activity;
+import com.budwk.app.module.activity.service.ActivityManageService;
+import org.nutz.dao.Dao;
+import org.nutz.ioc.loader.annotation.IocBean;
+
+@IocBean(args = {"refer:dao"})
+public class ActivityManageServiceImpl extends BaseServiceImpl implements ActivityManageService {
+ public ActivityManageServiceImpl(Dao dao) {
+ super(dao);
+ }
+}
diff --git a/backend/src/main/java/com/budwk/app/sys/controller/SysApiController.java b/backend/src/main/java/com/budwk/app/sys/controller/SysApiController.java
new file mode 100644
index 0000000..dfe2172
--- /dev/null
+++ b/backend/src/main/java/com/budwk/app/sys/controller/SysApiController.java
@@ -0,0 +1,105 @@
+package com.budwk.app.sys.controller;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import com.budwk.app.base.result.Result;
+import com.budwk.app.base.utils.PageUtil;
+import com.budwk.app.sys.services.SysApiService;
+import com.budwk.app.web.commons.auth.utils.SecurityUtil;
+import com.budwk.app.web.commons.slog.annotation.SLog;
+import org.nutz.dao.Cnd;
+import org.nutz.ioc.loader.annotation.Inject;
+import org.nutz.ioc.loader.annotation.IocBean;
+import org.nutz.lang.Strings;
+import org.nutz.log.Log;
+import org.nutz.log.Logs;
+import org.nutz.mvc.annotation.At;
+import org.nutz.mvc.annotation.Ok;
+import org.nutz.mvc.annotation.Param;
+
+import javax.servlet.http.HttpServletRequest;
+
+;
+
+/**
+ * Created by wizzer on 2016/6/24.
+ */
+@IocBean
+@At("/platform/sys/api")
+public class SysApiController {
+ private static final Log log = Logs.get();
+ @Inject
+ private SysApiService sysApiService;
+
+ @At("")
+ @Ok("beetl:/platform/sys/api/index.html")
+ @SaCheckPermission("sys.manager.api")
+ public void index() {
+ }
+
+ @At
+ @Ok("json")
+ @SaCheckPermission("sys.manager.api.add")
+ @SLog(tag = "新建密钥", msg = "应用名称:${name}")
+ public Object addDo(@Param("name") String name, HttpServletRequest req) {
+ try {
+ sysApiService.createAppkey(name, SecurityUtil.getUserId());
+ return Result.success();
+ } catch (Exception e) {
+ return Result.error();
+ }
+ }
+
+ @At("/delete/?")
+ @Ok("json")
+ @SaCheckPermission("sys.manager.api.delete")
+ @SLog(tag = "删除密钥", msg = "Appid:${appid}")
+ public Object delete(String appid, HttpServletRequest req) {
+ try {
+ sysApiService.deleteAppkey(appid);
+ return Result.success();
+ } catch (Exception e) {
+ return Result.error();
+ }
+ }
+
+ @At("/enable/?")
+ @Ok("json")
+ @SaCheckPermission("sys.manager.api.edit")
+ @SLog(tag = "启用密钥", msg = "Appid:${appid}")
+ public Object enable(String appid, HttpServletRequest req) {
+ try {
+ sysApiService.updateAppkey(appid, false);
+ return Result.success();
+ } catch (Exception e) {
+ return Result.error();
+ }
+ }
+
+ @At("/disable/?")
+ @Ok("json")
+ @SaCheckPermission("sys.manager.api.edit")
+ @SLog(tag = "禁用密钥", msg = "Appid:${appid}")
+ public Object disable(String appid, HttpServletRequest req) {
+ try {
+ sysApiService.updateAppkey(appid, true);
+ return Result.success();
+ } catch (Exception e) {
+ return Result.error();
+ }
+ }
+
+ @At
+ @Ok("json:full")
+ @SaCheckPermission("sys.manager.api")
+ public Object data(@Param("pageNumber") int pageNumber, @Param("pageSize") int pageSize, @Param("pageOrderName") String pageOrderName, @Param("pageOrderBy") String pageOrderBy) {
+ try {
+ Cnd cnd = Cnd.NEW();
+ if (Strings.isNotBlank(pageOrderName) && Strings.isNotBlank(pageOrderBy)) {
+ cnd.orderBy(pageOrderName, PageUtil.getOrder(pageOrderBy));
+ }
+ return Result.success().addData(sysApiService.listPage(pageNumber, pageSize, cnd));
+ } catch (Exception e) {
+ return Result.error();
+ }
+ }
+}
diff --git a/backend/src/main/java/com/budwk/app/sys/controller/SysConfController.java b/backend/src/main/java/com/budwk/app/sys/controller/SysConfController.java
new file mode 100644
index 0000000..e3df6ab
--- /dev/null
+++ b/backend/src/main/java/com/budwk/app/sys/controller/SysConfController.java
@@ -0,0 +1,118 @@
+package com.budwk.app.sys.controller;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import com.budwk.app.base.constant.RedisConstant;
+import com.budwk.app.base.result.Result;
+import com.budwk.app.base.utils.PageUtil;
+import com.budwk.app.sys.models.Sys_config;
+import com.budwk.app.sys.services.SysConfigService;
+import com.budwk.app.web.commons.auth.utils.SecurityUtil;
+import com.budwk.app.web.commons.slog.annotation.SLog;
+import org.nutz.dao.Cnd;
+import org.nutz.integration.jedis.pubsub.PubSubService;
+import org.nutz.ioc.loader.annotation.Inject;
+import org.nutz.ioc.loader.annotation.IocBean;
+import org.nutz.lang.Strings;
+import org.nutz.log.Log;
+import org.nutz.log.Logs;
+import org.nutz.mvc.annotation.At;
+import org.nutz.mvc.annotation.Ok;
+import org.nutz.mvc.annotation.Param;
+
+;
+
+/**
+ * Created by wizzer on 2016/6/28.
+ */
+@IocBean
+@At("/platform/sys/conf")
+public class SysConfController {
+ private static final Log log = Logs.get();
+ @Inject
+ private SysConfigService sysConfigService;
+ @Inject
+ private PubSubService pubSubService;
+
+ @At("")
+ @Ok("beetl:/platform/sys/conf/index.html")
+ @SaCheckPermission("sys.manager.conf")
+ public void index() {
+
+ }
+
+ @At
+ @Ok("json")
+ @SaCheckPermission("sys.manager.conf.add")
+ @SLog(tag = "添加参数", msg = "${conf.configKey}:${conf.configValue}")
+ public Object addDo(@Param("..") Sys_config conf) {
+ try {
+ conf.setCreatedBy(SecurityUtil.getUserId());
+ if (sysConfigService.insert(conf) != null) {
+ pubSubService.fire(RedisConstant.PLATFORM_REDIS_PREFIX + "web:platform", "sys_config");
+ }
+ return Result.success();
+ } catch (Exception e) {
+ return Result.error();
+ }
+ }
+
+ @At("/edit/?")
+ @Ok("json")
+ @SaCheckPermission("sys.manager.conf")
+ public Object edit(String id) {
+ try {
+ return Result.success().addData(sysConfigService.fetch(id));
+ } catch (Exception e) {
+ return Result.error();
+ }
+ }
+
+ @At
+ @Ok("json")
+ @SaCheckPermission("sys.manager.conf.edit")
+ @SLog(tag = "修改参数", msg = "${conf.configKey}:${conf.configValue}")
+ public Object editDo(@Param("..") Sys_config conf) {
+ try {
+ conf.setUpdatedBy(SecurityUtil.getUserId());
+ if (sysConfigService.updateIgnoreNull(conf) > 0) {
+ pubSubService.fire(RedisConstant.PLATFORM_REDIS_PREFIX + "web:platform", "sys_config");
+ }
+ return Result.success();
+ } catch (Exception e) {
+ return Result.error();
+ }
+ }
+
+ @At("/delete/?")
+ @Ok("json")
+ @SaCheckPermission("sys.manager.conf.delete")
+ @SLog(tag = "删除参数", msg = "参数:${configKey}")
+ public Object delete(String configKey) {
+ try {
+ if (Strings.sBlank(configKey).startsWith("App")) {
+ return Result.error("系统参数不可删除");
+ }
+ if (sysConfigService.delete(configKey) > 0) {
+ pubSubService.fire(RedisConstant.PLATFORM_REDIS_PREFIX + "web:platform", "sys_config");
+ }
+ return Result.success();
+ } catch (Exception e) {
+ return Result.error();
+ }
+ }
+
+ @At
+ @Ok("json:full")
+ @SaCheckPermission("sys.manager.conf")
+ public Object data(@Param("pageNumber") int pageNumber, @Param("pageSize") int pageSize, @Param("pageOrderName") String pageOrderName, @Param("pageOrderBy") String pageOrderBy) {
+ try {
+ Cnd cnd = Cnd.NEW();
+ if (Strings.isNotBlank(pageOrderName) && Strings.isNotBlank(pageOrderBy)) {
+ cnd.orderBy(pageOrderName, PageUtil.getOrder(pageOrderBy));
+ }
+ return Result.success().addData(sysConfigService.listPage(pageNumber, pageSize, cnd));
+ } catch (Exception e) {
+ return Result.error();
+ }
+ }
+}
diff --git a/backend/src/main/java/com/budwk/app/sys/controller/SysDictController.java b/backend/src/main/java/com/budwk/app/sys/controller/SysDictController.java
new file mode 100644
index 0000000..85b555f
--- /dev/null
+++ b/backend/src/main/java/com/budwk/app/sys/controller/SysDictController.java
@@ -0,0 +1,261 @@
+package com.budwk.app.sys.controller;
+
+import cn.dev33.satoken.annotation.SaCheckLogin;
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import com.budwk.app.base.result.Result;
+import com.budwk.app.sys.models.Sys_dict;
+import com.budwk.app.sys.services.SysDictService;
+import com.budwk.app.web.commons.auth.utils.SecurityUtil;
+import com.budwk.app.web.commons.slog.annotation.SLog;
+import org.apache.commons.lang3.StringUtils;
+import org.nutz.dao.Cnd;
+import org.nutz.dao.Sqls;
+import org.nutz.ioc.loader.annotation.Inject;
+import org.nutz.ioc.loader.annotation.IocBean;
+import org.nutz.lang.Lang;
+import org.nutz.lang.Strings;
+import org.nutz.lang.util.NutMap;
+import org.nutz.log.Log;
+import org.nutz.log.Logs;
+import org.nutz.mvc.annotation.At;
+import org.nutz.mvc.annotation.Ok;
+import org.nutz.mvc.annotation.Param;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
+import java.util.List;
+
+;
+
+/**
+ * Created by wizzer on 2016/6/24.
+ */
+@IocBean
+@At("/platform/sys/dict")
+public class SysDictController {
+ private static final Log log = Logs.get();
+ @Inject
+ private SysDictService sysDictService;
+
+ @At("")
+ @Ok("beetl:/platform/sys/dict/index.html")
+ @SaCheckPermission("sys.manager.dict")
+ public Object index() {
+ return sysDictService.query(Cnd.where("parentId", "=", "").or("parentId", "is", null).asc("location").asc("path"));
+ }
+
+
+ @At("/child")
+ @Ok("json")
+ @SaCheckLogin
+ public Object child(@Param("pid") String pid, HttpServletRequest req) {
+ List list = new ArrayList<>();
+ List treeList = new ArrayList<>();
+ Cnd cnd = Cnd.NEW();
+ if (Strings.isBlank(pid)) {
+ cnd.and("parentId", "=", "").or("parentId", "is", null);
+ } else {
+ cnd.and("parentId", "=", pid);
+ }
+ cnd.asc("location").asc("path");
+ list = sysDictService.query(cnd);
+ for (Sys_dict sysDict : list) {
+ if (sysDictService.count(Cnd.where("parentId", "=", sysDict.getId())) > 0) {
+ sysDict.setHasChildren(true);
+ }
+ NutMap map = Lang.obj2nutmap(sysDict);
+ map.addv("expanded", false);
+ map.addv("children", new ArrayList<>());
+ treeList.add(map);
+ }
+ return Result.success().addData(treeList);
+ }
+
+ @At("/tree")
+ @Ok("json")
+ @SaCheckLogin
+ public Object tree(@Param("pid") String pid, HttpServletRequest req) {
+ try {
+ List treeList = new ArrayList<>();
+ if (Strings.isBlank(pid)) {
+ NutMap root = NutMap.NEW().addv("value", "root").addv("label", "不选择菜单").addv("leaf", true);
+ treeList.add(root);
+ }
+ Cnd cnd = Cnd.NEW();
+ if (Strings.isBlank(pid)) {
+ cnd.and("parentId", "=", "").or("parentId", "is", null);
+ } else {
+ cnd.and("parentId", "=", pid);
+ }
+ cnd.asc("location").asc("path");
+ List list = sysDictService.query(cnd);
+ for (Sys_dict sysDict : list) {
+ NutMap map = NutMap.NEW().addv("value", sysDict.getId()).addv("label", sysDict.getName());
+ if (sysDict.isHasChildren()) {
+ map.addv("children", new ArrayList<>());
+ map.addv("leaf", false);
+ } else {
+ map.addv("leaf", true);
+ }
+ treeList.add(map);
+ }
+ return Result.success().addData(treeList);
+ } catch (Exception e) {
+ return Result.error();
+ }
+ }
+
+ @At
+ @Ok("json")
+ @SaCheckPermission("sys.manager.dict.add")
+ @SLog(tag = "新建字典", msg = "字典名称:${args[0].name}")
+ public Object addDo(@Param("..") Sys_dict dict, @Param(value = "parentId", df = "") String parentId, HttpServletRequest req) {
+ try {
+ if ("root".equals(parentId)) {
+ parentId = "";
+ }
+ dict.setHasChildren(false);
+ dict.setCreatedBy(SecurityUtil.getUserId());
+ sysDictService.save(dict, parentId);
+ sysDictService.clearCache();
+ return Result.success("system.success");
+ } catch (Exception e) {
+ return Result.error("system.error");
+ }
+ }
+
+ @At("/edit/?")
+ @Ok("json")
+ @SaCheckPermission("sys.manager.dict")
+ public Object edit(String id, HttpServletRequest req) {
+ try {
+ return Result.success().addData(sysDictService.fetch(id));
+ } catch (Exception e) {
+ return Result.error();
+ }
+ }
+
+ @At
+ @Ok("json")
+ @SaCheckPermission("sys.manager.dict.edit")
+ @SLog(tag = "编辑字典", msg = "字典名称:${args[0].name}")
+ public Object editDo(@Param("..") Sys_dict dict, @Param("parentId") String parentId, HttpServletRequest req) {
+ try {
+ dict.setUpdatedBy(SecurityUtil.getUserId());
+ sysDictService.updateIgnoreNull(dict);
+ sysDictService.clearCache();
+ return Result.success();
+ } catch (Exception e) {
+ return Result.error();
+ }
+ }
+
+ @At("/delete/?")
+ @Ok("json")
+ @SaCheckPermission("sys.manager.dict.delete")
+ @SLog(tag = "删除字典", msg = "字典名称:${args[1].getAttribute('name')}")
+ public Object delete(String id, HttpServletRequest req) {
+ try {
+ Sys_dict dict = sysDictService.fetch(id);
+ req.setAttribute("name", dict.getName());
+ sysDictService.deleteAndChild(dict);
+ sysDictService.clearCache();
+ return Result.success();
+ } catch (Exception e) {
+ return Result.error();
+ }
+ }
+
+ @At("/enable/?")
+ @Ok("json")
+ @SaCheckPermission("sys.manager.dict.edit")
+ @SLog(tag = "启用菜单", msg = "菜单名称:${args[1].getAttribute('name')}")
+ public Object enable(String menuId, HttpServletRequest req) {
+ try {
+ req.setAttribute("name", sysDictService.fetch(menuId).getName());
+ sysDictService.update(org.nutz.dao.Chain.make("disabled", false), Cnd.where("id", "=", menuId));
+ sysDictService.clearCache();
+ return Result.success();
+ } catch (Exception e) {
+ return Result.error();
+ }
+ }
+
+ @At("/disable/?")
+ @Ok("json")
+ @SaCheckPermission("sys.manager.dict.edit")
+ @SLog(tag = "禁用菜单", msg = "菜单名称:${args[1].getAttribute('name')}")
+ public Object disable(String menuId, HttpServletRequest req) {
+ try {
+ req.setAttribute("name", sysDictService.fetch(menuId).getName());
+ sysDictService.update(org.nutz.dao.Chain.make("disabled", true), Cnd.where("id", "=", menuId));
+ sysDictService.clearCache();
+ return Result.success();
+ } catch (Exception e) {
+ return Result.error();
+ }
+ }
+
+ @At("/menuAll")
+ @Ok("json")
+ @SaCheckPermission("sys.manager.dict")
+ public Object menuAll(HttpServletRequest req) {
+ try {
+ List list = sysDictService.query(Cnd.NEW().asc("location").asc("path"));
+ NutMap menuMap = NutMap.NEW();
+ for (Sys_dict unit : list) {
+ List list1 = menuMap.getList(unit.getParentId(), Sys_dict.class);
+ if (list1 == null) {
+ list1 = new ArrayList<>();
+ }
+ list1.add(unit);
+ menuMap.put(unit.getParentId(), list1);
+ }
+ return Result.success().addData(getTree(menuMap, ""));
+ } catch (Exception e) {
+ return Result.error();
+ }
+ }
+
+ private List getTree(NutMap menuMap, String pid) {
+ List treeList = new ArrayList<>();
+ List subList = menuMap.getList(pid, Sys_dict.class);
+ for (Sys_dict menu : subList) {
+ NutMap map = Lang.obj2nutmap(menu);
+ map.put("label", menu.getName());
+ if (menu.isHasChildren() || (menuMap.get(menu.getId()) != null)) {
+ map.put("children", getTree(menuMap, menu.getId()));
+ }
+ treeList.add(map);
+ }
+ return treeList;
+ }
+
+ @At
+ @Ok("json")
+ @SaCheckPermission("sys.manager.dict.edit")
+ public Object sortDo(@Param("ids") String ids, HttpServletRequest req) {
+ try {
+ String[] menuIds = StringUtils.split(ids, ",");
+ int i = 0;
+ sysDictService.execute(Sqls.create("update sys_dict set location=0"));
+ for (String s : menuIds) {
+ if (!Strings.isBlank(s)) {
+ sysDictService.update(org.nutz.dao.Chain.make("location", i), Cnd.where("id", "=", s));
+ i++;
+ }
+ }
+ sysDictService.clearCache();
+ return Result.success();
+ } catch (Exception e) {
+ return Result.error();
+ }
+ }
+
+ @At
+ @Ok("json")
+ @SaCheckLogin
+ public Result dictOptions(String code) {
+ return Result.success(sysDictService.getSubListByCode(code));
+ }
+}
diff --git a/backend/src/main/java/com/budwk/app/sys/controller/SysHomeController.java b/backend/src/main/java/com/budwk/app/sys/controller/SysHomeController.java
new file mode 100644
index 0000000..0d5a3ae
--- /dev/null
+++ b/backend/src/main/java/com/budwk/app/sys/controller/SysHomeController.java
@@ -0,0 +1,81 @@
+package com.budwk.app.sys.controller;
+
+import cn.dev33.satoken.annotation.SaCheckLogin;
+import cn.dev33.satoken.stp.StpUtil;
+import com.budwk.app.sys.services.SysMenuService;
+import com.budwk.app.sys.services.SysUserService;
+import org.nutz.dao.Dao;
+import org.nutz.ioc.loader.annotation.Inject;
+import org.nutz.ioc.loader.annotation.IocBean;
+import org.nutz.lang.Strings;
+import org.nutz.log.Log;
+import org.nutz.log.Logs;
+import org.nutz.mvc.annotation.At;
+import org.nutz.mvc.annotation.Ok;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+
+/**
+ * Created by wizzer on 2016/6/23.
+ */
+@IocBean
+@At("/platform/home")
+public class SysHomeController {
+ private static final Log log = Logs.get();
+ @Inject
+ private Dao dao;
+ @Inject
+ private SysMenuService sysMenuService;
+ @Inject
+ private SysUserService sysUserService;
+
+ @At("")
+ @Ok("re")
+ @SaCheckLogin
+ public String home(HttpSession session, HttpServletRequest req) {
+// if (StpUtil.hasRole("sysadmin")) {
+// return "beetl:/platform/sys/dashboard.html";
+// }
+ return "beetl:/platform/sys/home.html";
+ }
+
+ @At("/403")
+ @Ok("re")
+ public Object error403(HttpServletRequest req) {
+ StpUtil.checkLogin();
+ if (Strings.sNull(req.getAttribute("original_request_uri")).startsWith("/platform")) {
+ return "beetl:/platform/sys/403.html";
+ } else {
+ return ">>:/error/404.html";
+ }
+ }
+
+ @At("/404")
+ @Ok("re")
+ public Object error404(HttpServletRequest req) {
+ StpUtil.checkLogin();
+ if (Strings.sNull(req.getAttribute("original_request_uri")).startsWith("/platform")) {
+ return "beetl:/platform/sys/404.html";
+ } else {
+ return ">>:/error/404.html";
+ }
+ }
+
+ @At("/500")
+ @Ok("re")
+ public Object error500(HttpServletRequest req) {
+ StpUtil.checkLogin();
+ if (Strings.sNull(req.getAttribute("original_request_uri")).startsWith("/platform")) {
+ return "beetl:/platform/sys/500.html";
+ } else {
+ return ">>:/error/500.html";
+ }
+ }
+
+ @At(value = {"/", "/index"}, top = true)
+ @Ok(">>:/sysadmin")
+ public void index() {
+ }
+
+}
diff --git a/backend/src/main/java/com/budwk/app/sys/controller/SysLogController.java b/backend/src/main/java/com/budwk/app/sys/controller/SysLogController.java
new file mode 100644
index 0000000..a45f6dc
--- /dev/null
+++ b/backend/src/main/java/com/budwk/app/sys/controller/SysLogController.java
@@ -0,0 +1,49 @@
+package com.budwk.app.sys.controller;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import com.budwk.app.base.result.Result;
+import com.budwk.app.base.utils.DateUtil;
+import com.budwk.app.base.utils.PageUtil;
+import com.budwk.app.sys.services.SysLogService;
+import org.apache.commons.lang3.StringUtils;
+import org.nutz.ioc.loader.annotation.Inject;
+import org.nutz.ioc.loader.annotation.IocBean;
+import org.nutz.log.Log;
+import org.nutz.log.Logs;
+import org.nutz.mvc.annotation.At;
+import org.nutz.mvc.annotation.Ok;
+import org.nutz.mvc.annotation.Param;
+
+import javax.servlet.http.HttpServletRequest;
+
+;
+
+/**
+ * Created by wizzer on 2016/6/29.
+ */
+@IocBean
+@At("/platform/sys/log")
+public class SysLogController {
+ private static final Log log = Logs.get();
+ @Inject
+ private SysLogService sysLogService;
+
+ @At("")
+ @Ok("beetl:/platform/sys/log/index.html")
+ @SaCheckPermission("sys.manager.log")
+ public void index(HttpServletRequest req) {
+ req.setAttribute("today", DateUtil.getDate());
+ }
+
+ @At
+ @Ok("json:full")
+ @SaCheckPermission("sys.manager.log")
+ public Object data(@Param("searchDate") String searchDate, @Param("searchType") String searchType, @Param("pageNumber") int pageNumber, @Param("pageSize") int pageSize, @Param("pageOrderName") String pageOrderName, @Param("pageOrderBy") String pageOrderBy) {
+ try {
+ String[] date = StringUtils.split(searchDate, ",");
+ return Result.success().addData(sysLogService.data(date, searchType, pageOrderName, PageUtil.getOrder(pageOrderBy), pageNumber, pageSize));
+ } catch (Exception e) {
+ return Result.error();
+ }
+ }
+}
diff --git a/backend/src/main/java/com/budwk/app/sys/controller/SysLoginController.java b/backend/src/main/java/com/budwk/app/sys/controller/SysLoginController.java
new file mode 100644
index 0000000..78a8ed6
--- /dev/null
+++ b/backend/src/main/java/com/budwk/app/sys/controller/SysLoginController.java
@@ -0,0 +1,234 @@
+package com.budwk.app.sys.controller;
+
+import cn.dev33.satoken.annotation.SaCheckLogin;
+import cn.dev33.satoken.stp.StpUtil;
+import com.budwk.app.base.constant.RedisConstant;
+import com.budwk.app.base.exception.BaseException;
+import com.budwk.app.base.result.Result;
+import com.budwk.app.base.utils.PwdUtil;
+import com.budwk.app.sys.models.Sys_log;
+import com.budwk.app.sys.models.Sys_role;
+import com.budwk.app.sys.models.Sys_unit;
+import com.budwk.app.sys.models.Sys_user;
+import com.budwk.app.sys.services.SysMsgService;
+import com.budwk.app.sys.services.SysRoleService;
+import com.budwk.app.sys.services.SysUnitService;
+import com.budwk.app.sys.services.SysUserService;
+import com.budwk.app.web.commons.auth.service.ValidateService;
+import com.budwk.app.web.commons.auth.utils.SecurityUtil;
+import com.budwk.app.web.commons.base.Globals;
+import com.budwk.app.web.commons.slog.SLogService;
+import org.nutz.dao.Chain;
+import org.nutz.dao.Cnd;
+import org.nutz.integration.jedis.RedisService;
+import org.nutz.ioc.loader.annotation.Inject;
+import org.nutz.ioc.loader.annotation.IocBean;
+import org.nutz.lang.Lang;
+import org.nutz.lang.Strings;
+import org.nutz.lang.random.R;
+import org.nutz.lang.util.NutMap;
+import org.nutz.log.Log;
+import org.nutz.log.Logs;
+import org.nutz.mvc.annotation.At;
+import org.nutz.mvc.annotation.Filters;
+import org.nutz.mvc.annotation.Ok;
+import org.nutz.mvc.annotation.Param;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+
+/**
+ * Created by wizzer on 2016/6/22.
+ */
+@IocBean // 声明为Ioc容器中的一个Bean
+@At("/platform/login") // 整个模块的路径前缀
+@Ok("json:{locked:'password|createAt',ignoreNull:true}") // 忽略password和createAt属性,忽略空属性的json输出
+public class SysLoginController {
+ private static final Log log = Logs.get();
+ @Inject
+ private SysUserService sysUserService;
+ @Inject
+ private SysRoleService sysRoleService;
+ @Inject
+ private SysUnitService sysUnitService;
+ @Inject
+ private SLogService sLogService;
+ @Inject
+ private RedisService redisService;
+ @Inject
+ private SysMsgService sysMsgService;
+ @Inject
+ private ValidateService validateService;
+
+ @At("")
+ @Ok("beetl:/platform/sys/login.html")
+ @Filters
+ public void login(HttpServletRequest req, HttpSession session) {
+
+ }
+
+ @At("/noPermission")
+ @Ok("beetl:/platform/sys/noPermission.html")
+ @Filters
+ public void noPermission() {
+
+ }
+
+ /**
+ * 用户登录
+ *
+ * @return
+ */
+ @At("/doLogin")
+ @Ok("json")
+ public Object doLogin(@Param("username") String username,
+ @Param("password") String password,
+ @Param("platformKey") String captchaKey,
+ @Param("platformCaptcha") String captchaCode,
+ HttpServletRequest req, HttpSession session) {
+ try {
+ Sys_user user = null;
+ sysUserService.checkLoginname(username);
+ validateService.checkCode(captchaKey, captchaCode);
+ user = sysUserService.loginByPassword(username, password);
+ if (user == null) {
+ throw new BaseException("用户登录失败");
+ }
+ StpUtil.login(user.getId());
+ StpUtil.checkLogin();
+ StpUtil.getSession(true).set("loginname", Strings.sNull(user.getLoginname()))
+ .set("username", Strings.sNull(user.getUsername()))
+ .set("unitId", Strings.sNull(user.getUnitId()))
+ .set("unitPath", Strings.sNull(user.getUnitPath()));
+ sysUserService.setLoginInfo(user.getId(), Lang.getIP(req));
+ Sys_log sysLog = new Sys_log();
+ sysLog.setType("info");
+ sysLog.setTag("用户登陆");
+ sysLog.setSrc(this.getClass().getName() + "#doLogin");
+ sysLog.setMsg("成功登录系统!");
+ sysLog.setIp(Lang.getIP(req));
+ sysLog.setCreatedBy(user.getId());
+ sysLog.setUsername(user.getUsername());
+ sysLog.setLoginname(user.getLoginname());
+ sLogService.async(sysLog);
+ return Result.success("login.success");
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ return Result.error(e.getMessage());
+ }
+ }
+
+ @At("/doSmsLogin")
+ @Ok("json")
+ public Object doSmsLogin(@Param("mobile") String mobile, @Param("code") String code, HttpServletRequest req) {
+ try {
+ Sys_user user = null;
+ sysUserService.checkMobile(mobile);
+ validateService.checkSMSCode(mobile, code);
+ user = sysUserService.loginByMobile(mobile);
+ if (user == null) {
+ throw new BaseException("用户登录失败");
+ }
+ StpUtil.login(user.getId());
+ StpUtil.checkLogin();
+ StpUtil.getSession(true).set("loginname", Strings.sNull(user.getLoginname()))
+ .set("username", Strings.sNull(user.getUsername()))
+ .set("unitId", Strings.sNull(user.getUnitId()))
+ .set("unitPath", Strings.sNull(user.getUnitPath()));
+ sysUserService.setLoginInfo(user.getId(), Lang.getIP(req));
+ Sys_log sysLog = new Sys_log();
+ sysLog.setType("info");
+ sysLog.setTag("用户登陆");
+ sysLog.setSrc(this.getClass().getName() + "#doLogin");
+ sysLog.setMsg("成功登录系统!");
+ sysLog.setIp(Lang.getIP(req));
+ sysLog.setCreatedBy(user.getId());
+ sysLog.setUsername(user.getUsername());
+ sysLog.setLoginname(user.getLoginname());
+ sLogService.async(sysLog);
+ return Result.success("login.success");
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ return Result.error(e.getMessage());
+ }
+ }
+
+
+ /**
+ * 退出系统
+ */
+ @At
+ @Ok(">>:/platform/login")
+ public void logout(HttpSession session, HttpServletRequest req) {
+ try {
+ Sys_user user = sysUserService.getUserById(SecurityUtil.getUserId());
+ StpUtil.logout();
+ if (user != null) {
+ Sys_log sysLog = new Sys_log();
+ sysLog.setType("info");
+ sysLog.setTag("用户登出");
+ sysLog.setSrc(this.getClass().getName() + "#logout");
+ sysLog.setMsg("成功退出系统!");
+ sysLog.setIp(Lang.getIP(req));
+ sysLog.setCreatedBy(user.getId());
+ sysLog.setUsername(user.getUsername());
+ sysLog.setLoginname(user.getLoginname());
+ sLogService.async(sysLog);
+ }
+ } catch (Exception e) {
+ log.debug("Logout error", e);
+ }
+ }
+
+ @At("/captcha")
+ @Ok("json")
+ public Object next() {
+ return Result.success(validateService.getCaptcha());
+ }
+
+ @At("/sendSmsCode")
+ @Ok("json")
+ public Object sendSmsCode(@Param("mobile") String mobile) {
+ try {
+ validateService.getSmsCode(mobile);
+ return Result.success(NutMap.NEW().addv("key", RedisConstant.UCENTER_SMSCODE + mobile)).addMsg("发送成功");
+ } catch (BaseException e) {
+ return Result.error(e.getMessage());
+ }
+ }
+
+ @At("/doReg")
+ @Ok("json")
+ public Object doReg(@Param("mobile") String mobile, @Param("password") String password, @Param("code") String code, HttpServletRequest req) {
+ try {
+ int count = sysUserService.count(Cnd.where("loginname", "=", Strings.trim(mobile)));
+ if (count > 0) {
+ return Result.error("手机号已存在");
+ }
+ validateService.checkSMSCode(mobile, code);
+ Sys_user user = new Sys_user();
+ user.setLoginname(mobile);
+ user.setUsername(mobile);
+ user.setMobile(mobile);
+ String salt = R.UU32();
+ user.setSalt(salt);
+ user.setPassword(PwdUtil.getPassword(password, salt));
+ user.setLoginCount(0);
+ user.setCreatedBy(SecurityUtil.getUserId());
+ Sys_unit unit = sysUnitService.fetch(Cnd.where("unitcode", "=", Globals.MyConfig.getString("AppDefaultUserUnit")));
+ if (unit != null) {
+ user.setUnitId(unit.getId());
+ user.setUnitPath(unit.getPath());
+ }
+ Sys_role role = sysRoleService.fetch(Cnd.where("code", "=", Globals.MyConfig.getString("AppDefaultUserRole")));
+ sysUserService.insert(user);
+ if (role != null)
+ sysRoleService.insert("sys_user_role", Chain.make("roleId", role.getId()).add("userId", user.getId()));
+ sysUserService.clearCache();
+ return Result.success();
+ } catch (BaseException e) {
+ return Result.error(e.getMessage());
+ }
+ }
+
+}
diff --git a/backend/src/main/java/com/budwk/app/sys/controller/SysMenuController.java b/backend/src/main/java/com/budwk/app/sys/controller/SysMenuController.java
new file mode 100644
index 0000000..9fb97e7
--- /dev/null
+++ b/backend/src/main/java/com/budwk/app/sys/controller/SysMenuController.java
@@ -0,0 +1,354 @@
+package com.budwk.app.sys.controller;
+
+import cn.dev33.satoken.annotation.SaCheckLogin;
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import com.budwk.app.base.result.Result;
+import com.budwk.app.sys.models.Sys_menu;
+import com.budwk.app.sys.services.SysMenuService;
+import com.budwk.app.sys.services.SysRoleService;
+import com.budwk.app.sys.services.SysUserService;
+import com.budwk.app.web.commons.auth.utils.SecurityUtil;
+import com.budwk.app.web.commons.slog.annotation.SLog;
+import org.apache.commons.lang3.StringUtils;
+import org.nutz.dao.Cnd;
+import org.nutz.dao.Sqls;
+import org.nutz.ioc.loader.annotation.Inject;
+import org.nutz.ioc.loader.annotation.IocBean;
+import org.nutz.json.Json;
+import org.nutz.lang.Lang;
+import org.nutz.lang.Strings;
+import org.nutz.lang.util.NutMap;
+import org.nutz.log.Log;
+import org.nutz.log.Logs;
+import org.nutz.mvc.annotation.At;
+import org.nutz.mvc.annotation.Ok;
+import org.nutz.mvc.annotation.Param;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
+import java.util.List;
+
+;
+
+/**
+ * Created by wizzer on 2016/6/28.
+ */
+@IocBean
+@At("/platform/sys/menu")
+public class SysMenuController {
+ private static final Log log = Logs.get();
+ @Inject
+ private SysMenuService sysMenuService;
+ @Inject
+ private SysUserService sysUserService;
+ @Inject
+ private SysRoleService sysRoleService;
+
+ @At("")
+ @Ok("beetl:/platform/sys/menu/index.html")
+ @SaCheckPermission("sys.manager.menu")
+ public void index(HttpServletRequest req) {
+ }
+
+ @At("/child")
+ @Ok("json")
+ @SaCheckLogin
+ public Object child(@Param("pid") String pid, HttpServletRequest req) {
+ List list = new ArrayList<>();
+ List treeList = new ArrayList<>();
+ Cnd cnd = Cnd.NEW();
+ if (Strings.isBlank(pid)) {
+ cnd.and(Cnd.exps("parentId", "=", "").or("parentId", "is", null));
+ } else {
+ cnd.and("parentId", "=", pid);
+ }
+ cnd.asc("location").asc("path");
+ list = sysMenuService.query(cnd);
+ for (Sys_menu menu : list) {
+ if (sysMenuService.count(Cnd.where("parentId", "=", menu.getId())) > 0) {
+ menu.setHasChildren(true);
+ }
+ NutMap map = Lang.obj2nutmap(menu);
+ map.addv("expanded", false);
+ map.addv("children", new ArrayList<>());
+ treeList.add(map);
+ }
+ return Result.success().addData(treeList);
+ }
+
+ @At("/tree")
+ @Ok("json")
+ @SaCheckLogin
+ public Object tree(@Param("pid") String pid, HttpServletRequest req) {
+ try {
+ List treeList = new ArrayList<>();
+ if (Strings.isBlank(pid)) {
+ NutMap root = NutMap.NEW().addv("value", "root").addv("label", "不选择菜单").addv("leaf", true);
+ treeList.add(root);
+ }
+ Cnd cnd = Cnd.NEW();
+ if (Strings.isBlank(pid)) {
+ cnd.and(Cnd.exps("parentId", "=", "").or("parentId", "is", null));
+ } else {
+ cnd.and("parentId", "=", pid);
+ }
+ cnd.and("type", "=", "menu");
+ cnd.asc("location").asc("path");
+ List list = sysMenuService.query(cnd);
+ for (Sys_menu menu : list) {
+ NutMap map = NutMap.NEW().addv("value", menu.getId()).addv("label", menu.getName());
+ if (menu.isHasChildren()) {
+ map.addv("children", new ArrayList<>());
+ map.addv("leaf", false);
+ } else {
+ map.addv("leaf", true);
+ }
+ treeList.add(map);
+ }
+ return Result.success().addData(treeList);
+ } catch (Exception e) {
+ return Result.error();
+ }
+ }
+
+ @At
+ @Ok("json")
+ @SaCheckPermission("sys.manager.menu.add")
+ @SLog(tag = "新建菜单", msg = "菜单名称:${args[1].getAttribute('name')}")
+ public Object addDo(@Param("..") NutMap nutMap, HttpServletRequest req) {
+ try {
+ Sys_menu sysMenu = nutMap.getAs("menu", Sys_menu.class);
+ List buttons = Json.fromJsonAsList(NutMap.class, nutMap.getString("buttons"));
+ int num = sysMenuService.count(Cnd.where("permission", "=", sysMenu.getPermission().trim()));
+ if (num > 0) {
+ return Result.error("sys.role.code");
+ }
+ for (NutMap map : buttons) {
+ num = sysMenuService.count(Cnd.where("permission", "=", map.getString("permission", "").trim()));
+ if (num > 0) {
+ return Result.error("sys.role.code");
+ }
+ }
+ String parentId = sysMenu.getParentId();
+ if ("root".equals(sysMenu.getParentId())) {
+ parentId = "";
+ }
+ sysMenu.setHasChildren(false);
+ sysMenu.setShowit(true);
+ sysMenu.setCreatedBy(SecurityUtil.getUserId());
+ sysMenuService.save(sysMenu, Strings.sNull(parentId), buttons);
+ req.setAttribute("name", sysMenu.getName());
+ sysMenuService.clearCache();
+ sysUserService.clearCache();
+ sysRoleService.clearCache();
+ return Result.success();
+ } catch (Exception e) {
+ return Result.error();
+ }
+ }
+
+ //编辑菜单,组装一下js表单数据
+ @At("/editMenu/?")
+ @Ok("json")
+ @SaCheckPermission("sys.manager.menu")
+ public Object editMenu(String id, HttpServletRequest req) {
+ try {
+ Sys_menu menu = sysMenuService.fetch(id);
+ NutMap map = Lang.obj2nutmap(menu);
+ map.put("parentName", "无");
+ map.put("children", "false");
+ if (Strings.isNotBlank(menu.getParentId())) {
+ map.put("parentName", sysMenuService.fetch(menu.getParentId()).getName());
+ }
+ List list = sysMenuService.query(Cnd.where("parentId", "=", id).and("type", "=", "data").asc("location").asc("path"));
+ List buttons = new ArrayList<>();
+ if (list != null && list.size() > 0) {
+ map.put("children", "true");
+ for (Sys_menu m : list) {
+ buttons.add(NutMap.NEW().addv("key", m.getId()).addv("name", m.getName()).addv("permission", m.getPermission()));
+ }
+ }
+ map.put("buttons", buttons);
+ return Result.success().addData(map);
+ } catch (Exception e) {
+ return Result.error();
+ }
+ }
+
+ @At
+ @Ok("json")
+ @SaCheckPermission("sys.manager.menu.edit")
+ @SLog(tag = "修改菜单", msg = "菜单名称:${args[1].getAttribute('name')}")
+ public Object editMenuDo(@Param("..") NutMap nutMap, HttpServletRequest req) {
+ try {
+ Sys_menu sysMenu = nutMap.getAs("menu", Sys_menu.class);
+ List buttons = Json.fromJsonAsList(NutMap.class, nutMap.getString("buttons"));
+ //如果权限标识不是自己的,并且被其他记录占用
+ int num = sysMenuService.count(Cnd.where("permission", "=", sysMenu.getPermission().trim()).and("id", "<>", sysMenu.getId()));
+ if (num > 0) {
+ return Result.error("sys.role.code");
+ }
+ for (NutMap map : buttons) {
+ num = sysMenuService.count(Cnd.where("permission", "=", map.getString("permission", "").trim()).and("id", "<>", map.getString("key", "")));
+ if (num > 0) {
+ return Result.error("sys.role.code");
+ }
+ }
+ sysMenu.setHasChildren(false);
+ sysMenu.setShowit(true);
+ sysMenu.setUpdatedBy(SecurityUtil.getUserId());
+ sysMenuService.edit(sysMenu, sysMenu.getParentId(), buttons);
+ req.setAttribute("name", sysMenu.getName());
+ sysMenuService.clearCache();
+ sysUserService.clearCache();
+ sysRoleService.clearCache();
+ return Result.success();
+ } catch (Exception e) {
+ return Result.error();
+ }
+ }
+
+ @At("/editData/?")
+ @Ok("json")
+ @SaCheckPermission("sys.manager.menu")
+ public Object editData(String id, HttpServletRequest req) {
+ try {
+ return Result.success().addData(sysMenuService.fetch(id));
+ } catch (Exception e) {
+ return Result.error();
+ }
+ }
+
+ @At
+ @Ok("json")
+ @SaCheckPermission("sys.manager.menu.edit")
+ @SLog(tag = "修改权限", msg = "权限名称:${args[0].name}")
+ public Object editDataDo(@Param("..") Sys_menu menu, HttpServletRequest req) {
+ try {
+ int num = sysMenuService.count(Cnd.where("permission", "=", menu.getPermission().trim()).and("id", "<>", menu.getId()));
+ if (num > 0) {
+ return Result.error("sys.role.code");
+ }
+ sysMenuService.updateIgnoreNull(menu);
+ sysMenuService.clearCache();
+ sysUserService.clearCache();
+ sysRoleService.clearCache();
+ return Result.success();
+ } catch (Exception e) {
+ return Result.error();
+ }
+ }
+
+ @At("/delete/?")
+ @Ok("json")
+ @SaCheckPermission("sys.manager.menu.delete")
+ @SLog(tag = "删除菜单", msg = "菜单名称:${args[1].getAttribute('name')}")
+ public Object delete(String id, HttpServletRequest req) {
+ try {
+ Sys_menu menu = sysMenuService.fetch(id);
+ req.setAttribute("name", menu.getName());
+ if (menu.getPath().startsWith("0001")) {
+ return Result.error("system.not.allow");
+ }
+ sysMenuService.deleteAndChild(menu);
+ sysMenuService.clearCache();
+ sysUserService.clearCache();
+ sysRoleService.clearCache();
+ return Result.success();
+ } catch (Exception e) {
+ return Result.error();
+ }
+ }
+
+ @At("/enable/?")
+ @Ok("json")
+ @SaCheckPermission("sys.manager.menu.edit")
+ @SLog(tag = "启用菜单", msg = "菜单名称:${args[1].getAttribute('name')}")
+ public Object enable(String menuId, HttpServletRequest req) {
+ try {
+ req.setAttribute("name", sysMenuService.fetch(menuId).getName());
+ sysMenuService.update(org.nutz.dao.Chain.make("disabled", false), Cnd.where("id", "=", menuId));
+ sysMenuService.clearCache();
+ sysUserService.clearCache();
+ sysRoleService.clearCache();
+ return Result.success();
+ } catch (Exception e) {
+ return Result.error();
+ }
+ }
+
+ @At("/disable/?")
+ @Ok("json")
+ @SaCheckPermission("sys.manager.menu.edit")
+ @SLog(tag = "禁用菜单", msg = "菜单名称:${args[1].getAttribute('name')}")
+ public Object disable(String menuId, HttpServletRequest req) {
+ try {
+ req.setAttribute("name", sysMenuService.fetch(menuId).getName());
+ sysMenuService.update(org.nutz.dao.Chain.make("disabled", true), Cnd.where("id", "=", menuId));
+ sysMenuService.clearCache();
+ sysUserService.clearCache();
+ sysRoleService.clearCache();
+ return Result.success();
+ } catch (Exception e) {
+ return Result.error();
+ }
+ }
+
+ @At("/menuAll")
+ @Ok("json")
+ @SaCheckPermission("sys.manager.menu")
+ public Object menuAll(HttpServletRequest req) {
+ try {
+ List list = sysMenuService.query(Cnd.where("type", "=", "menu").asc("location").asc("path"));
+ NutMap menuMap = NutMap.NEW();
+ for (Sys_menu unit : list) {
+ List list1 = menuMap.getList(unit.getParentId(), Sys_menu.class);
+ if (list1 == null) {
+ list1 = new ArrayList<>();
+ }
+ list1.add(unit);
+ menuMap.put(unit.getParentId(), list1);
+ }
+ return Result.success().addData(getTree(menuMap, ""));
+ } catch (Exception e) {
+ return Result.error();
+ }
+ }
+
+ private List getTree(NutMap menuMap, String pid) {
+ List treeList = new ArrayList<>();
+ List subList = menuMap.getList(pid, Sys_menu.class);
+ for (Sys_menu menu : subList) {
+ NutMap map = Lang.obj2nutmap(menu);
+ map.put("label", menu.getName());
+ if (menu.isHasChildren() || (menuMap.get(menu.getId()) != null)) {
+ map.put("children", getTree(menuMap, menu.getId()));
+ }
+ treeList.add(map);
+ }
+ return treeList;
+ }
+
+ @At
+ @Ok("json")
+ @SaCheckPermission("sys.manager.menu.edit")
+ public Object sortDo(@Param("ids") String ids, HttpServletRequest req) {
+ try {
+ String[] menuIds = StringUtils.split(ids, ",");
+ int i = 0;
+ sysMenuService.execute(Sqls.create("update sys_menu set location=0"));
+ for (String s : menuIds) {
+ if (!Strings.isBlank(s)) {
+ sysMenuService.update(org.nutz.dao.Chain.make("location", i), Cnd.where("id", "=", s));
+ i++;
+ }
+ }
+ sysMenuService.clearCache();
+ sysUserService.clearCache();
+ sysRoleService.clearCache();
+ return Result.success();
+ } catch (Exception e) {
+ return Result.error();
+ }
+ }
+}
diff --git a/backend/src/main/java/com/budwk/app/sys/controller/SysMsgController.java b/backend/src/main/java/com/budwk/app/sys/controller/SysMsgController.java
new file mode 100644
index 0000000..50e2640
--- /dev/null
+++ b/backend/src/main/java/com/budwk/app/sys/controller/SysMsgController.java
@@ -0,0 +1,152 @@
+package com.budwk.app.sys.controller;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import com.budwk.app.base.page.Pagination;
+import com.budwk.app.base.result.Result;
+import com.budwk.app.base.utils.PageUtil;
+import com.budwk.app.sys.models.Sys_msg;
+import com.budwk.app.sys.services.SysMsgService;
+import com.budwk.app.sys.services.SysMsgUserService;
+import com.budwk.app.sys.services.SysUserService;
+import com.budwk.app.web.commons.auth.utils.SecurityUtil;
+import com.budwk.app.web.commons.slog.annotation.SLog;
+import org.apache.commons.lang3.StringUtils;
+import org.nutz.dao.Cnd;
+import org.nutz.dao.Sqls;
+import org.nutz.ioc.loader.annotation.Inject;
+import org.nutz.ioc.loader.annotation.IocBean;
+import org.nutz.lang.Lang;
+import org.nutz.lang.Strings;
+import org.nutz.lang.Times;
+import org.nutz.lang.util.NutMap;
+import org.nutz.log.Log;
+import org.nutz.log.Logs;
+import org.nutz.mvc.annotation.At;
+import org.nutz.mvc.annotation.Ok;
+import org.nutz.mvc.annotation.Param;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+;
+
+@IocBean
+@At("/platform/sys/msg")
+public class SysMsgController {
+ private static final Log log = Logs.get();
+ @Inject
+ private SysMsgService sysMsgService;
+ @Inject
+ private SysMsgUserService sysMsgUserService;
+ @Inject
+ private SysUserService sysUserService;
+
+ @At({"/", "/list/?"})
+ @Ok("beetl:/platform/sys/msg/index.html")
+ @SaCheckPermission("sys.manager.msg")
+ public void index(String type, HttpServletRequest req) {
+ req.setAttribute("type", Strings.isBlank(type) ? "all" : type);
+ }
+
+ @At
+ @Ok("json:full")
+ @SaCheckPermission("sys.manager.msg")
+ public Object data(@Param("searchType") String searchType, @Param("pageNumber") int pageNumber, @Param("pageSize") int pageSize, @Param("pageOrderName") String pageOrderName, @Param("pageOrderBy") String pageOrderBy) {
+ try {
+ Cnd cnd = Cnd.NEW();
+ if (Strings.isNotBlank(searchType) && !"all".equals(searchType)) {
+ cnd.and("type", "=", searchType);
+ }
+ if (Strings.isNotBlank(pageOrderName) && Strings.isNotBlank(pageOrderBy)) {
+ cnd.orderBy(pageOrderName, PageUtil.getOrder(pageOrderBy));
+ }
+ List