diff --git a/Doc/客户提出的EXCEL要求/133个县区数据表.xls b/Doc/客户提出的EXCEL要求/133个县区数据表.xls new file mode 100644 index 00000000..39ef2bdb Binary files /dev/null and b/Doc/客户提出的EXCEL要求/133个县区数据表.xls differ diff --git a/Doc/客户提出的EXCEL要求/16个州市数据表.xls b/Doc/客户提出的EXCEL要求/16个州市数据表.xls new file mode 100644 index 00000000..d7847af6 Binary files /dev/null and b/Doc/客户提出的EXCEL要求/16个州市数据表.xls differ diff --git a/Doc/长春云校大数据部署情况.txt b/Doc/长春云校大数据部署情况.txt new file mode 100644 index 00000000..18ee562f --- /dev/null +++ b/Doc/长春云校大数据部署情况.txt @@ -0,0 +1,88 @@ +#RockyLinux 9.5 +IP:10.10.200.31 +root +DsideaL4r5t6y7u +端口:22 + +#Windows操作机 +IP:10.10.200.33 +Administrator +dsideal + +ToDesk +755 640 600 +密码: +DsideaL4r5t6y7u@123 + + +#公网IP: +222.161.203.183 +对外映射的三个端口: +8100 --> DataEase + +原始密码:admin DataEase@123456 +黄海修改过的密码:admin Dsideal4r5t6y7u!@# + +8200 -->MaxKB +admin Dsideal4r5t6y7u!@# + +9000 -->QingLong + +利用OpenResty反代两个项目 +8080:MaxKB ---> OpenResty ---> http://222.161.203.183:8200 +9100:YunNanDsBase--->OpenResty--->http://222.161.203:8200/dsBase/html/login.html + +利用端口映射直通两个项目 +8100:DataEase --->8100 ---> http://222.161.203.183:8100/dataease +9000:QingLong ---->9000 ---> http://222.161.203.183:9000/QingLong/login.html + + +http://222.161.203.183:9000/QingLong/yx/LessonConstructionInfoByXzqhSchool?type_id=1 + +### 错误: +(1)java.lang.RuntimeException: java.lang.UnsatisfiedLinkError: /usr/local/jdk21/lib/libfontmanager.so: libfreetype.so.6: cannot open shared object file: No such file or directory + +yum install freetype -y + +(2)java.lang.RuntimeException: Fontconfig head is null, check your fonts or fonts configuration + +yum install fontconfig dejavu-sans-fonts -y + +(3) java+pdf导出后,中文显示方框 +yum install -y fontconfig mkfontscale + +I 将C:\Windows\Fonts 下所有文件的打成一个压缩包:Fonts.zip +II 将Fonts.zip上传到 /usr/share/fonts/ + +cd /usr/share/fonts/ +unzip Fonts.zip +rm -rf Fonts.zip +rm -rf ./*.fon #这种字体是安装不上的 +mkfontscale +mkfontdir +fc-cache + + +# 部署的程序 +1、YunNanDsBase +目的:配合DataEase进行工作,起到路由或者修改数据的目的。使用了Mysql数据库ds_db,部署到DataEase的mysql实例中 +用户名:root +密码:Password123@mysql +端口:3306 +数据库名称:ds_db + +2、QingLong +目的:配合MaxKB进行工作,起到下载EXCEL,按个人创建知识库等功能(暂未上线) +用户名:root +密码:Password123@postgres +端口:5432 +数据库名称:szjz_db + +注意:由于我们开发环境10.10.14.71使用的是PG16,而MaxKB使用的是PG15.8,直接用Navicat进行PSC备份还原会失改,黄海的办法是导出SQL文件,然后再到目标机导入,成功创建表。 + + +# 更新的SQL语句 +update paragraph set content=replace(content,'10.10.21.20:9000','222.161.203.183:9000') + +# 演示的地址 +http://222.161.203.183:8200/ui/chat/a21c842f2eeffaa2 \ No newline at end of file diff --git a/Excel/幼儿入园.xlsx b/Excel/幼儿入园.xlsx new file mode 100644 index 00000000..8ed27ec9 Binary files /dev/null and b/Excel/幼儿入园.xlsx differ diff --git a/src/main/java/com/dsideal/base/BaseApplication.java b/src/main/java/com/dsideal/base/BaseApplication.java index 9a6ce8fe..546c688d 100644 --- a/src/main/java/com/dsideal/base/BaseApplication.java +++ b/src/main/java/com/dsideal/base/BaseApplication.java @@ -19,6 +19,7 @@ import com.dsideal.base.StudentYd.Controller.StudentYdController; import com.dsideal.base.Teacher.Controller.TeacherController; import com.dsideal.base.TeacherYd.Controller.TeacherYdController; import com.dsideal.base.Tools.Controller.excelConvertController; +import com.dsideal.base.YunXiao.Controller.YunXiaoController; import com.dsideal.base.Util.FileUtil; import com.dsideal.base.Util.LogBackLogFactory; import com.dsideal.base.Util.PkUtil; @@ -97,6 +98,8 @@ public class BaseApplication extends JFinalConfig { me.add("/dataease", DataEaseController.class); //资源管理 me.add("/res", ResourceController.class); + //云校 + me.add("/yx",YunXiaoController.class); } @Override diff --git a/src/main/java/com/dsideal/base/DataEase/Controller/DataEaseController.java b/src/main/java/com/dsideal/base/DataEase/Controller/DataEaseController.java index ed2e2e5a..262d22a4 100644 --- a/src/main/java/com/dsideal/base/DataEase/Controller/DataEaseController.java +++ b/src/main/java/com/dsideal/base/DataEase/Controller/DataEaseController.java @@ -44,6 +44,55 @@ public class DataEaseController extends Controller { !!!必须发布后访问才能做到进入此接口,否则浏览器就走缓存,不进来这个接口了!!! */ + //http://10.10.14.203/#/de-link/mOFfS3Ot?area_id=[区域] + //http://10.10.21.20:9000/dsBase/dataease/YxRoute?area_name=南关区 + //http://10.10.14.14:9000/dsBase/dataease/YxRoute?area_name=南关区 + + /** + * 长春云校的路由 + * + * @param area_name 区域名称 + */ + @Before({GET.class}) + @EmptyInterface({"area_name"}) + public void YxRoute(String area_name) { + //发布的地址 + String publish_url = BaseApplication.PropKit.get("YunXiao.publish_url"); + //拼接一下URL的最终地址 + JSONObject jo = new JSONObject(); + jo.put("area_name", area_name); + String base64Str = Base64.encode(jo.toString()); + //记录最后一次操作的是哪个县区 + dm.writeYxLastArea(area_name); + //跳转 + redirect(publish_url + "?attachParams=" + base64Str); + } + + /** + * 云校仪表盘路由 + * @param type_id 类型id + */ + //http://10.10.14.14:9000/dsBase/dataease/routeYxPage?type_id=1 + @Before({GET.class}) + public void routeYxPage(int type_id) { + //最后一次操作的区域名称 + String area_name = dm.getLastYxArea(); + //发布的地址 + String publish_url = BaseApplication.PropKit.get("dataEase.publish_url"); + //拼接一下URL的最终地址 + JSONObject jo = new JSONObject(); + jo.put("area_name", area_name); + String base64Str = Base64.encode(jo.toString()); + if(type_id == 1){ + publish_url = publish_url + BaseApplication.PropKit.get("dataEase.YxAreaClassStudentTeacher"); + }else if(type_id == 2){ + publish_url = publish_url + BaseApplication.PropKit.get("dataEase.YxKeCheng"); + } + //跳转 + redirect(publish_url + "?attachParams=" + base64Str); + } + + /** * 省级路由 * diff --git a/src/main/java/com/dsideal/base/DataEase/Model/DataEaseModel.java b/src/main/java/com/dsideal/base/DataEase/Model/DataEaseModel.java index 5a0822db..d778c569 100644 --- a/src/main/java/com/dsideal/base/DataEase/Model/DataEaseModel.java +++ b/src/main/java/com/dsideal/base/DataEase/Model/DataEaseModel.java @@ -518,6 +518,16 @@ public class DataEaseModel { Db.update(sql, area_name); } + /** + * 记录云校最后一次操作的是哪个县区 + * + * @param area_name + */ + public void writeYxLastArea(String area_name) { + String sql = "update t_dataease_yx_last_area set area_name=? where id=1"; + Db.update(sql, area_name); + } + /** * 获取最后一次操作的是哪个区域 @@ -529,6 +539,15 @@ public class DataEaseModel { return Db.findFirst(sql).getStr("area_name"); } + /** + * 云校最后一次操作的是哪个县区 + * @return + */ + public String getLastYxArea() { + String sql = "select area_name from t_dataease_yx_last_area where id=1"; + return Db.findFirst(sql).getStr("area_name"); + } + /** * 获取云南教科院项目的根节点 * diff --git a/src/main/java/com/dsideal/base/Tools/ExportExcel.java b/src/main/java/com/dsideal/base/Tools/ExportExcel.java new file mode 100644 index 00000000..ffdcf64e --- /dev/null +++ b/src/main/java/com/dsideal/base/Tools/ExportExcel.java @@ -0,0 +1,177 @@ +package com.dsideal.base.Tools; + +import com.dsideal.base.Tools.Util.LocalMysqlConnectUtil; +import com.jfinal.plugin.activerecord.Db; +import com.jfinal.plugin.activerecord.Record; +import com.jfinal.plugin.activerecord.SqlPara; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; + +import java.io.FileOutputStream; +import java.util.List; + +import static com.dsideal.base.DataEase.Model.DataEaseModel.DB_NAME; + +public class ExportExcel { + static String excelFileName = "D:\\dsWork\\YunNanDsBase\\Excel\\幼儿入园.xlsx"; + + public static void exportToExcel(List records, String filePath) { + try (Workbook workbook = new XSSFWorkbook()) { + Sheet sheet = workbook.createSheet("数据统计"); + + // 创建标题行样式 + CellStyle headerStyle = workbook.createCellStyle(); + // 设置边框 + headerStyle.setBorderTop(BorderStyle.THIN); + headerStyle.setBorderBottom(BorderStyle.THIN); + headerStyle.setBorderLeft(BorderStyle.THIN); + headerStyle.setBorderRight(BorderStyle.THIN); + // 设置背景色 + headerStyle.setFillForegroundColor(IndexedColors.LIGHT_BLUE.getIndex()); + headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); + // 设置对齐方式 + headerStyle.setAlignment(HorizontalAlignment.CENTER); + headerStyle.setVerticalAlignment(VerticalAlignment.CENTER); + // 设置字体 + Font headerFont = workbook.createFont(); + headerFont.setBold(true); + headerFont.setFontName("黑体"); + headerFont.setFontHeightInPoints((short) 12); + headerStyle.setFont(headerFont); + headerStyle.setFillForegroundColor(IndexedColors.LIME.getIndex()); + + // 创建数据行样式 + CellStyle dataStyle = workbook.createCellStyle(); + // 设置边框 + dataStyle.setBorderTop(BorderStyle.THIN); + dataStyle.setBorderBottom(BorderStyle.THIN); + dataStyle.setBorderLeft(BorderStyle.THIN); + dataStyle.setBorderRight(BorderStyle.THIN); + // 设置背景色 + dataStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex()); + dataStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); + // 设置对齐方式 + dataStyle.setAlignment(HorizontalAlignment.CENTER); + dataStyle.setVerticalAlignment(VerticalAlignment.CENTER); + + // 创建表头 + Row headerRow = sheet.createRow(0); + // 设置行高 + headerRow.setHeight((short) (28 * 20)); // 28像素 ≈ 28 * 20 缇 + String[] headers = {"行政区划", "年份", "年份", "2023", "2024", "2025", "2026", + "2027", "2028", "2029", "2030", "2031", "2032", "2033", "2034"}; + for (int i = 0; i < headers.length; i++) { + Cell cell = headerRow.createCell(i); + cell.setCellValue(headers[i]); + cell.setCellStyle(headerStyle); + sheet.setColumnWidth(i, 3500); // 设置列宽 + } + // 写入数据并处理合并单元格 + int rowNum = 1; + String lastDistrict = ""; + String lastType = ""; + int districtMergeStartRow = 1; // 行政区划合并起始行 + int typeMergeStartRow = 1; // 类型合并起始行 + + for (Record record : records) { + Row row = sheet.createRow(rowNum); + // 设置行高 + row.setHeight((short) (28 * 20)); + + String currentDistrict = record.getStr("行政区划"); + String currentType = record.getStr("类型"); + + // 填充数据 + for (int i = 0; i < headers.length; i++) { + Cell cell = row.createCell(i); + cell.setCellStyle(dataStyle); + + if (i == 0) { + cell.setCellValue(currentDistrict); + } + else if (i == 1) { + cell.setCellValue(currentType); + } + else if (i == 2) { + cell.setCellValue(record.getStr("分类")); + } + else { + Double value = record.getDouble(headers[i]); + if (value != null) { + cell.setCellValue(value); + } + } + } + + // 处理行政区划和类型的合并 + if (!currentDistrict.equals(lastDistrict)) { + // 处理上一个行政区划的最后一组类型合并 + if (rowNum > typeMergeStartRow) { + sheet.addMergedRegion(new CellRangeAddress( + typeMergeStartRow, rowNum - 1, 1, 1)); + } + + // 处理行政区划合并 + if (rowNum > districtMergeStartRow) { + sheet.addMergedRegion(new CellRangeAddress( + districtMergeStartRow, rowNum - 1, 0, 0)); + } + districtMergeStartRow = rowNum; + typeMergeStartRow = rowNum; + } + // 在同一个行政区划内,处理类型的合并 + else if (!currentType.equals(lastType)) { + if (rowNum > typeMergeStartRow) { + sheet.addMergedRegion(new CellRangeAddress( + typeMergeStartRow, rowNum - 1, 1, 1)); + } + typeMergeStartRow = rowNum; + } + + lastDistrict = currentDistrict; + lastType = currentType; + rowNum++; + } + + // 处理最后一组合并 + // 先处理最后一组类型合并 + if (rowNum > typeMergeStartRow) { + sheet.addMergedRegion(new CellRangeAddress( + typeMergeStartRow, rowNum - 1, 1, 1)); + } + // 再处理最后一组行政区划合并 + if (rowNum > districtMergeStartRow) { + sheet.addMergedRegion(new CellRangeAddress( + districtMergeStartRow, rowNum - 1, 0, 0)); + } + + // 合并表头中的"年份"列 + sheet.addMergedRegion(new CellRangeAddress(0, 0, 1, 2)); + + // 为合并后的单元格重新设置样式(避免合并后样式丢失) + Cell mergedCell = headerRow.getCell(1); + if (mergedCell != null) { + mergedCell.setCellValue("年份"); + mergedCell.setCellStyle(headerStyle); + } + + // 保存文件 + try (FileOutputStream fileOut = new FileOutputStream(filePath)) { + workbook.write(fileOut); + } + + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static void main(String[] args) { + LocalMysqlConnectUtil.Init(); + + SqlPara sqlPara = Db.getSqlPara("exportExcel.Xqry"); + List list = Db.use(DB_NAME).find(sqlPara); + + exportToExcel(list, excelFileName); + } +} diff --git a/src/main/java/com/dsideal/base/Tools/YunXiao/YunXiao_DataSetInit.java b/src/main/java/com/dsideal/base/Tools/YunXiao/YunXiao_DataSetInit.java new file mode 100644 index 00000000..025e3838 --- /dev/null +++ b/src/main/java/com/dsideal/base/Tools/YunXiao/YunXiao_DataSetInit.java @@ -0,0 +1,20 @@ +package com.dsideal.base.Tools.YunXiao; + +import com.dsideal.base.Tools.Util.LocalMysqlConnectUtil; +import com.dsideal.base.YunXiao.Model.YunXiaoModel; + +import java.io.IOException; + +public class YunXiao_DataSetInit { + public static YunXiaoModel ym = new YunXiaoModel(); + + public static void main(String[] args) throws IOException { + LocalMysqlConnectUtil.Init(); + //1、添加到数据集表中 + ym.collectDataSet(false); + //2、加上主键 + ym.addPrimaryKey(); + //3、将所有非空列去掉不允许为空的限制 + ym.updateNotNullColumns(); + } +} diff --git a/src/main/java/com/dsideal/base/YunXiao/Controller/YunXiaoController.java b/src/main/java/com/dsideal/base/YunXiao/Controller/YunXiaoController.java new file mode 100644 index 00000000..521e9958 --- /dev/null +++ b/src/main/java/com/dsideal/base/YunXiao/Controller/YunXiaoController.java @@ -0,0 +1,74 @@ +package com.dsideal.base.YunXiao.Controller; + +import com.dsideal.base.Interceptor.IsLoginInterface; +import com.dsideal.base.Interceptor.IsNumericInterface; +import com.dsideal.base.Util.CommonUtil; +import com.dsideal.base.Util.SqlInjectionUtils; +import com.dsideal.base.YunXiao.Model.YunXiaoModel; +import com.jfinal.aop.Before; +import com.jfinal.core.Controller; +import com.jfinal.ext.interceptor.GET; +import com.jfinal.ext.interceptor.POST; +import com.jfinal.kit.StrKit; +import com.jfinal.plugin.activerecord.Page; +import com.jfinal.plugin.activerecord.Record; +import io.github.yedaxia.apidocs.ApiDoc; + +import java.util.List; + +@ApiDoc +public class YunXiaoController extends Controller { + + YunXiaoModel ym = new YunXiaoModel(); + + /** + * 可以维护的数据集名称 + */ + // http://10.10.21.20:9000/dsBase/yx/getDataSet + @Before({GET.class}) + @IsLoginInterface({}) + public void getDataSet() { + List list = ym.getDataSet(); + renderJson(CommonUtil.renderJsonForLayUI(list)); + } + + /** + * 获取数据集下的数据表 + * + * @param id 数据集id + * @param pageNumber 第几页 + * @param keyword 关键字 + * @param pageSize 每页多少条数据 + */ + @Before(GET.class) + @IsLoginInterface({}) + @IsNumericInterface({"id"}) + public void getDataSetContent(int id, String keyword, int pageNumber, int pageSize) { + if (StrKit.isBlank(keyword)) keyword = ""; + if (pageNumber == 0) pageNumber = 1; + if (pageSize == 0) pageSize = 20; + if (SqlInjectionUtils.hasSqlInjectionRisk(keyword)) { + renderJson("输入的查询关键字存在SQL注入攻击,无法执行!"); + return; + } + + Page pageList = ym.getDataSetContent(id, keyword, pageNumber, pageSize); + renderJson(CommonUtil.renderJsonForLayUI(pageList)); + } + + /** + * 保存数据集下的数据表 + * + * @param dataset_id 数据集id + * @param id 数据集下的数据表的id + * @param field 字段名 + * @param value 值 + */ + @Before(POST.class) + @IsLoginInterface({}) + public void saveDataSet(int dataset_id, int id, String field, String value) { + ym.saveDataSet(dataset_id, id, field, value); + renderJson(CommonUtil.returnMessageJson(true, "保存成功")); + } + +} diff --git a/src/main/java/com/dsideal/base/YunXiao/Model/YunXiaoModel.java b/src/main/java/com/dsideal/base/YunXiao/Model/YunXiaoModel.java new file mode 100644 index 00000000..30fadf5d --- /dev/null +++ b/src/main/java/com/dsideal/base/YunXiao/Model/YunXiaoModel.java @@ -0,0 +1,259 @@ +package com.dsideal.base.YunXiao.Model; + +import com.jfinal.kit.Kv; +import com.jfinal.kit.StrKit; +import com.jfinal.plugin.activerecord.Db; +import com.jfinal.plugin.activerecord.Page; +import com.jfinal.plugin.activerecord.Record; +import com.jfinal.plugin.activerecord.SqlPara; + +import java.util.*; + + +public class YunXiaoModel { + //DataEase数据库名称 + public static String DB_NAME = "dataease"; + + /** + * 获取当前人员可以看到哪些数据集 + * + * @return 数据集列表 + */ + public List getDataSet() { + String sql = "select t1.* from t_dp_yx_dataset as t1 where t1.b_use=1 order by t1.dataset_group_id"; + List list = Db.find(sql); + for (Record record : list) { + String table_name = record.getStr("table_name"); + sql = "select count(1) as c from `" + table_name + "`"; + int cnt = Db.use(DB_NAME).queryInt(sql); + record.set("fill_count", cnt); + } + return list; + } + + /** + * 获取数据集的表名 + * + * @param dataset_group_id 数据集的id + * @return 表名 + */ + public String getTableName(String dataset_group_id) { + Kv kv = Kv.by("dataset_group_id", dataset_group_id); + SqlPara sqlPara = Db.getSqlPara("DataEase.getTableName", kv); + Record record = Db.findFirst(sqlPara); + if (record == null) { + System.out.println("数据集不存在" + dataset_group_id); + return null; + } + return Db.findFirst(sqlPara).getStr("table_name"); + } + + + /** + * 将数据集填充到数据库表中,用于配置此数据集让谁来维护 + * + * @param parent_name 数据集的父名称 + * @param table_name 表名 + * @param dataset_name 数据集名 + */ + public void collectDataSet(String parent_name, String table_name, String dataset_name, long dataset_group_id) { + String sql = "select count(1) from t_dp_yx_dataset where dataset_group_id=?"; + if (Db.queryInt(sql, dataset_group_id) > 0) { + System.out.println("数据集已经存在,无需再次添加"); + return; + } + Record record = new Record(); + record.set("parent_name", parent_name.replace("-", "")); + record.set("table_name", table_name); + record.set("dataset_name", dataset_name); + if (parent_name.contains("省")) { + record.set("owner_id", 1); + } else if (parent_name.contains("市") || parent_name.contains("州")) { + record.set("owner_id", 2); + } else if (parent_name.contains("县")) { + record.set("owner_id", 3); + } + record.set("dataset_group_id", dataset_group_id); + Db.save("t_dp_yx_dataset", "id", record); + //System.out.println("添加数据集成功,parent_name=" + parent_name + ",table_name=" + table_name + ",dataset_name=" + dataset_name); + } + + /** + * 获取表中不允许为空的列名 + * + * @param tableName 表名 + * @return 列名列表 + */ + public List getNotNullColumns(String tableName) { + List columns = new ArrayList<>(); + String sql = "SELECT COLUMN_NAME FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ? AND IS_NULLABLE = 'NO'"; + List results = Db.find(sql, YunXiaoModel.DB_NAME, tableName); + for (Record result : results) { + columns.add(result.get("COLUMN_NAME").toString()); + } + return columns; + } + + // 检查表是否存在主键 + public boolean hasPrimaryKey(String tableName) { + String sql = "SELECT COUNT(*) as c FROM information_schema.TABLE_CONSTRAINTS WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ? AND CONSTRAINT_TYPE = 'PRIMARY KEY'"; + return Db.use("dataease").queryInt(sql, YunXiaoModel.DB_NAME, tableName) > 0; + } + + // 添加主键列,并设置为主键 + public void addPrimaryKey(String tableName) { + // 添加 id 列 + String sql = "ALTER TABLE `" + tableName + "` ADD COLUMN `id` int(11) primary key auto_increment first"; + Db.use(YunXiaoModel.DB_NAME).update(sql); + } + + /** + * 获取所有以 excel_ 开头的表 + * + * @return + */ + public List getExcelTable() { + // 查询所有以 excel_ 开头的表 + String sql = "SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'dataease' AND TABLE_NAME LIKE 'excel\\_%'"; + return Db.use(YunXiaoModel.DB_NAME).find(sql); + } + + /** + * 添加主键 + */ + public void addPrimaryKey() { + // 查询所有以 excel_ 开头的表 + List tables = getExcelTable(); + for (Record table : tables) { + String tableName = table.getStr("TABLE_NAME"); + //没有主键的表,添加上主键 + if (!hasPrimaryKey(tableName)) { + System.out.println("表" + tableName + "没有主键,正在添加主键..."); + addPrimaryKey(tableName); + System.out.println("添加主键成功"); + } + } + } + + /** + * 将Excel表中不允许为空的列改为允许为空 + */ + public void updateNotNullColumns() { + // 查询所有以 excel_ 开头的表 + List tables = getExcelTable(); + for (Record table : tables) { + String tableName = table.getStr("TABLE_NAME"); + //获取非空列 + List cols = getNotNullColumns(tableName); + + for (String col : cols) { + if (!col.equals("id")) { + System.out.println("列" + col + "非空,正在去掉不允许为空的限制..."); + //去掉不允许为空的限制 + String sql = "ALTER TABLE `" + tableName + "` MODIFY `" + col + "` VARCHAR(255) NULL"; + Db.use(YunXiaoModel.DB_NAME).update(sql); + System.out.println("去掉不允许为空的限制成功"); + } + } + } + } + + /** + * 将数据集添加到数据库中 + */ + public void collectDataSet(boolean clear) { + //1、获取树根 + String sql = "select * from dataease.core_dataset_group where name='长春云校'"; + Record rRoot = Db.findFirst(sql); + long rootId = rRoot.getLong("id"); + + if (clear) { + //清空数据集表 + sql = "truncate table t_dp_yx_dataset"; + Db.update(sql); + } + + //2、查询有哪些数据集 + Kv kv = Kv.by("id", rootId); + kv.set("dataset", true); + SqlPara sqlPara = Db.getSqlPara("DataEase.getAllDataSet", kv); + List list = Db.find(sqlPara); + + for (Record record : list) { + long dataset_group_id = record.getLong("id"); + //数据集父名称 + String parent_name = record.getStr("parent_name"); + //数据集名称 + String dataset_name = record.getStr("name"); + //对应的表名 + String table_name = getTableName(String.valueOf(dataset_group_id)); + if (!StrKit.isBlank(table_name)) { + //将这些数据集扫描到表中,然后标识这个数据集由谁来维护 + collectDataSet(parent_name, table_name, dataset_name, dataset_group_id); + } + } + } + + /** + * 获取指定id的行政区划 + * + * @param id + * @return + */ + public Record getAreaById(String id) { + String sql = "select * from t_dm_area where id=?"; + return Db.findFirst(sql, id); + } + + + /** + * 递归获取所有子节点 + * + * @param id 节点id + * @return + */ + public List getChildren(long id) { + List list = new ArrayList<>(); + list.add(id); + String sql = "select * from data_visualization_info where pid=?"; + List children = Db.use(DB_NAME).find(sql, id); + for (Record r : children) { + list.addAll(getChildren(r.getLong("id"))); + } + return list; + } + + /** + * 获取数据集对应的表 + * + * @param id 数据集id + * @return + */ + public Page getDataSetContent(int id, String keyword, int pageNumber, int pageSize) { + Record record = Db.findById("t_dp_yx_dataset", "id", id); + String tableName = record.getStr("table_name"); + Page p = Db.paginate(pageNumber, pageSize, + "SELECT *", "from " + DB_NAME + ".`" + tableName + "` where `行政区划` like '%" + keyword + "%'"); + return p; + } + + + /** + * 保存数据集对应的表 + */ + public void saveDataSet(int dataset_id, int id, String field, String value) { + Record record = Db.findById("t_dp_yx_dataset", "id", dataset_id); + String tableName = record.getStr("table_name"); + String sql = "update `" + tableName + "` set `" + field + "`=? where id=?"; + Db.use(DB_NAME).update(sql, value, id); + } + + public String getCityNameByAreaName(String areaName) { + String sql = "select id,parent_id from t_dm_area where area_name=?"; + Record record = Db.findFirst(sql, areaName); + if (record == null) return null; + String parent_id = record.getStr("parent_id"); + if (parent_id == null) return null; + return getAreaById(parent_id).getStr("area_name"); + } +} diff --git a/src/main/resources/Sql/ExportExcel.sql b/src/main/resources/Sql/ExportExcel.sql new file mode 100644 index 00000000..93afa2d8 --- /dev/null +++ b/src/main/resources/Sql/ExportExcel.sql @@ -0,0 +1,192 @@ +#namespace("exportExcel") + -- 学前入园幼儿入园总量 + #sql("Xqry") + -- 入园总量数据查询 +(SELECT + 行政区划, + '入园数' as 类型, + '城区' as 分类, + MAX(IF(年份 = 2023, 区域数值, NULL)) as '2023', + MAX(IF(年份 = 2024, 区域数值, NULL)) as '2024', + MAX(IF(年份 = 2025, 区域数值, NULL)) as '2025', + MAX(IF(年份 = 2026, 区域数值, NULL)) as '2026', + MAX(IF(年份 = 2027, 区域数值, NULL)) as '2027', + MAX(IF(年份 = 2028, 区域数值, NULL)) as '2028', + MAX(IF(年份 = 2029, 区域数值, NULL)) as '2029', + MAX(IF(年份 = 2030, 区域数值, NULL)) as '2030', + MAX(IF(年份 = 2031, 区域数值, NULL)) as '2031', + MAX(IF(年份 = 2032, 区域数值, NULL)) as '2032', + MAX(IF(年份 = 2033, 区域数值, NULL)) as '2033', + MAX(IF(年份 = 2034, 区域数值, NULL)) as '2034' +FROM excel_学前幼儿入园总量_b25b1b09b0 +WHERE 区域分类 = '城区' +GROUP BY 行政区划) + +UNION ALL + +(SELECT + 行政区划, + '入园数' as 类型, + '镇区' as 分类, + MAX(IF(年份 = 2023, 区域数值, NULL)) as '2023', + MAX(IF(年份 = 2024, 区域数值, NULL)) as '2024', + MAX(IF(年份 = 2025, 区域数值, NULL)) as '2025', + MAX(IF(年份 = 2026, 区域数值, NULL)) as '2026', + MAX(IF(年份 = 2027, 区域数值, NULL)) as '2027', + MAX(IF(年份 = 2028, 区域数值, NULL)) as '2028', + MAX(IF(年份 = 2029, 区域数值, NULL)) as '2029', + MAX(IF(年份 = 2030, 区域数值, NULL)) as '2030', + MAX(IF(年份 = 2031, 区域数值, NULL)) as '2031', + MAX(IF(年份 = 2032, 区域数值, NULL)) as '2032', + MAX(IF(年份 = 2033, 区域数值, NULL)) as '2033', + MAX(IF(年份 = 2034, 区域数值, NULL)) as '2034' +FROM excel_学前幼儿入园总量_b25b1b09b0 +WHERE 区域分类 = '镇区' +GROUP BY 行政区划) + +UNION ALL + +(SELECT + 行政区划, + '入园数' as 类型, + '乡村' as 分类, + MAX(IF(年份 = 2023, 区域数值, NULL)) as '2023', + MAX(IF(年份 = 2024, 区域数值, NULL)) as '2024', + MAX(IF(年份 = 2025, 区域数值, NULL)) as '2025', + MAX(IF(年份 = 2026, 区域数值, NULL)) as '2026', + MAX(IF(年份 = 2027, 区域数值, NULL)) as '2027', + MAX(IF(年份 = 2028, 区域数值, NULL)) as '2028', + MAX(IF(年份 = 2029, 区域数值, NULL)) as '2029', + MAX(IF(年份 = 2030, 区域数值, NULL)) as '2030', + MAX(IF(年份 = 2031, 区域数值, NULL)) as '2031', + MAX(IF(年份 = 2032, 区域数值, NULL)) as '2032', + MAX(IF(年份 = 2033, 区域数值, NULL)) as '2033', + MAX(IF(年份 = 2034, 区域数值, NULL)) as '2034' +FROM excel_学前幼儿入园总量_b25b1b09b0 +WHERE 区域分类 = '乡村' +GROUP BY 行政区划) + +UNION ALL + +(SELECT + 行政区划, + '入园数' as 类型, + '总数' as 分类, + MAX(IF(年份 = 2023, 总量数值, NULL)) as '2023', + MAX(IF(年份 = 2024, 总量数值, NULL)) as '2024', + MAX(IF(年份 = 2025, 总量数值, NULL)) as '2025', + MAX(IF(年份 = 2026, 总量数值, NULL)) as '2026', + MAX(IF(年份 = 2027, 总量数值, NULL)) as '2027', + MAX(IF(年份 = 2028, 总量数值, NULL)) as '2028', + MAX(IF(年份 = 2029, 总量数值, NULL)) as '2029', + MAX(IF(年份 = 2030, 总量数值, NULL)) as '2030', + MAX(IF(年份 = 2031, 总量数值, NULL)) as '2031', + MAX(IF(年份 = 2032, 总量数值, NULL)) as '2032', + MAX(IF(年份 = 2033, 总量数值, NULL)) as '2033', + MAX(IF(年份 = 2034, 总量数值, NULL)) as '2034' +FROM excel_学前幼儿入园总量_b25b1b09b0 +WHERE 总量分类 = '总入园数' +GROUP BY 行政区划) + +UNION ALL +-- 在园总量数据查询 + +(SELECT + 行政区划, + '在园幼儿数' as 类型, + '城区' as 分类, + MAX(IF(年份 = 2023, 区域数值, NULL)) as '2023', + MAX(IF(年份 = 2024, 区域数值, NULL)) as '2024', + MAX(IF(年份 = 2025, 区域数值, NULL)) as '2025', + MAX(IF(年份 = 2026, 区域数值, NULL)) as '2026', + MAX(IF(年份 = 2027, 区域数值, NULL)) as '2027', + MAX(IF(年份 = 2028, 区域数值, NULL)) as '2028', + MAX(IF(年份 = 2029, 区域数值, NULL)) as '2029', + MAX(IF(年份 = 2030, 区域数值, NULL)) as '2030', + MAX(IF(年份 = 2031, 区域数值, NULL)) as '2031', + MAX(IF(年份 = 2032, 区域数值, NULL)) as '2032', + MAX(IF(年份 = 2033, 区域数值, NULL)) as '2033', + MAX(IF(年份 = 2034, 区域数值, NULL)) as '2034' +FROM excel_学前幼儿在园总量_c04222fd74 +WHERE 区域分类 = '城区' +GROUP BY 行政区划) + +UNION ALL + +(SELECT + 行政区划, + '在园幼儿数' as 类型, + '镇区' as 分类, + MAX(IF(年份 = 2023, 区域数值, NULL)) as '2023', + MAX(IF(年份 = 2024, 区域数值, NULL)) as '2024', + MAX(IF(年份 = 2025, 区域数值, NULL)) as '2025', + MAX(IF(年份 = 2026, 区域数值, NULL)) as '2026', + MAX(IF(年份 = 2027, 区域数值, NULL)) as '2027', + MAX(IF(年份 = 2028, 区域数值, NULL)) as '2028', + MAX(IF(年份 = 2029, 区域数值, NULL)) as '2029', + MAX(IF(年份 = 2030, 区域数值, NULL)) as '2030', + MAX(IF(年份 = 2031, 区域数值, NULL)) as '2031', + MAX(IF(年份 = 2032, 区域数值, NULL)) as '2032', + MAX(IF(年份 = 2033, 区域数值, NULL)) as '2033', + MAX(IF(年份 = 2034, 区域数值, NULL)) as '2034' +FROM excel_学前幼儿在园总量_c04222fd74 +WHERE 区域分类 = '镇区' +GROUP BY 行政区划) + +UNION ALL + +(SELECT + 行政区划, + '在园幼儿数' as 类型, + '乡村' as 分类, + MAX(IF(年份 = 2023, 区域数值, NULL)) as '2023', + MAX(IF(年份 = 2024, 区域数值, NULL)) as '2024', + MAX(IF(年份 = 2025, 区域数值, NULL)) as '2025', + MAX(IF(年份 = 2026, 区域数值, NULL)) as '2026', + MAX(IF(年份 = 2027, 区域数值, NULL)) as '2027', + MAX(IF(年份 = 2028, 区域数值, NULL)) as '2028', + MAX(IF(年份 = 2029, 区域数值, NULL)) as '2029', + MAX(IF(年份 = 2030, 区域数值, NULL)) as '2030', + MAX(IF(年份 = 2031, 区域数值, NULL)) as '2031', + MAX(IF(年份 = 2032, 区域数值, NULL)) as '2032', + MAX(IF(年份 = 2033, 区域数值, NULL)) as '2033', + MAX(IF(年份 = 2034, 区域数值, NULL)) as '2034' +FROM excel_学前幼儿在园总量_c04222fd74 +WHERE 区域分类 = '乡村' +GROUP BY 行政区划) + +UNION ALL + +(SELECT + 行政区划, + '在园幼儿数' as 类型, + '总数' as 分类, + MAX(IF(年份 = 2023, 总量数值, NULL)) as '2023', + MAX(IF(年份 = 2024, 总量数值, NULL)) as '2024', + MAX(IF(年份 = 2025, 总量数值, NULL)) as '2025', + MAX(IF(年份 = 2026, 总量数值, NULL)) as '2026', + MAX(IF(年份 = 2027, 总量数值, NULL)) as '2027', + MAX(IF(年份 = 2028, 总量数值, NULL)) as '2028', + MAX(IF(年份 = 2029, 总量数值, NULL)) as '2029', + MAX(IF(年份 = 2030, 总量数值, NULL)) as '2030', + MAX(IF(年份 = 2031, 总量数值, NULL)) as '2031', + MAX(IF(年份 = 2032, 总量数值, NULL)) as '2032', + MAX(IF(年份 = 2033, 总量数值, NULL)) as '2033', + MAX(IF(年份 = 2034, 总量数值, NULL)) as '2034' +FROM excel_学前幼儿在园总量_c04222fd74 +WHERE 总量分类 = '总在园数' +GROUP BY 行政区划) + +ORDER BY 行政区划, +CASE 类型 + WHEN '入园数' THEN 1 + WHEN '在园幼儿数' THEN 2 +END, +CASE 分类 + WHEN '城区' THEN 1 + WHEN '镇区' THEN 2 + WHEN '乡村' THEN 3 + WHEN '总数' THEN 4 +END; + #end +#end \ No newline at end of file diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index 7eb6f695..b11cdacd 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -41,7 +41,17 @@ dataEase: AreaLeft_url: /#/de-link/WTtaPIn6 AreaBottom_url: /#/de-link/j3vwbtKm AreaRight_url: /#/de-link/ufRSlWmB + + # 云校 + # 区县-班级学生教师应用统计 + YxAreaClassStudentTeacher: /#/de-link/h15XBsLH + # 区县-课程应用统计 + YxKeCheng: /#/de-link/vO7gtJmw # ============================================================== +# 长春云校配置 +YunXiao: + publish_url: http://10.10.14.203:8100/#/de-link/mOFfS3Ot + excel: # 导出excel 的模板配置路径