package com.product.data.sync.service;
import com.google.common.base.Joiner;
import com.product.admin.service.OrganizationCacheService;
import com.product.core.cache.DataPoolCacheImpl;
import com.product.core.dao.BaseDao;
import com.product.core.entity.DataTableEntity;
import com.product.core.entity.FieldSetEntity;
import com.product.core.exception.BaseException;
import com.product.core.spring.context.SpringMVCContextHolder;
import com.product.core.transfer.Transactional;
import com.product.data.sync.config.CmnConst;
import com.product.data.sync.service.ide.IViewDataProcessService;
import com.product.data.sync.util.BatchData;
import com.product.util.SystemParamReplace;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/**
* 鎶婅鍥句腑鐨勬暟鎹悓姝ュ埌瀹炰綋琛ㄤ腑
* 澶栭儴鏁版嵁鍚屾瀹氭椂浠诲姟鎵ц瀹屾垚鍚庤皟鐢ㄦ绫荤殑鏂规硶锛屽弬瑙�
*
* @author Administrator
*/
@Service
public class ViewDataProcessService implements IViewDataProcessService {
@Autowired
public BaseDao baseDao;
/**
* 1銆佷粠杩滅▼鏁版嵁鍚屾鍒版湰鍦板簱
* 2銆佹煡鎵炬暟鎹鐞嗚〃product_sys_database_sync_processing_config涓叧鑱旇〃瀛楁鍚湁鍚屾琛ㄧ殑涓旂埗uuid瀛楁绛夌┖鐨勫鐞嗛厤缃俊鎭�
* 锛屾姝ヤ负鎶婄浉鍏宠〃杩涜鍏宠仈鏌ヨ锛屽鐞嗛儴闂ㄣ€佸叕鍙搞€佷汉鍛樹俊鎭紝姝ゆ涓哄閲忓鐞�
* 3銆佸啀鐢ㄧ埗uuid瀛楁绛夌┖杩欐潯璁板綍鍘绘壘涓嬩竴姝ュ鐞嗚锛屼緷娆℃槸鐢熸垚浜哄憳淇℃伅銆侀儴闂ㄤ俊鎭€佸叕鍙镐俊鎭€傛姝ヤ负鍏ㄩ噺澶勭悊
* product_sys_database_sync_processing_config涓殑鎵€鏈夐厤缃鐞嗘柟寮忛兘鏄粠view sql涓煡璇㈠嚭鏉ユ彃鍏ュ埌瀹炰綋琛ㄤ腑
* 瑙嗗浘sql鏌ヨ鍑烘潵鐨勫瓧娈典笌瀹炰綋琛ㄤ腑鐨勫瓧娈靛悕蹇呴』涓€鑷�
*
* @param aimTable
*/
@Override
@Transactional
public void copyViewDataToTable(String aimTable) {
OrgDataMap orgDataMap = null;
if (StringUtils.isEmpty(aimTable.trim())) {
return;
}
ExecutorService executorService = null;
DataTableEntity dt = baseDao.listTable("product_sys_database_sync_processing_config", "concat(',',relevance_table,',') like concat('%,',?,',%') and (parent_uuid is null or parent_uuid ='')", new Object[]{aimTable});
if (!dt.isEmpty()) {
for (int i = 0; i < dt.getRows(); i++) {
FieldSetEntity fs = dt.getFieldSetEntity(i);
String basic_table = fs.getString("relevance_table");
if (!StringUtils.isEmpty(basic_table.trim())) {
String bts[] = basic_table.split(",");
//瀵瑰簲鍒悕
Map<String, String> aliash = new HashMap<String, String>();
if (!StringUtils.isEmpty(fs.getString("table_alias"))) {
String alias[] = fs.getString("table_alias").split(",");
for (int k = 0; k < bts.length; k++) {
if (alias.length > k) {
if (alias[k] == null) {
continue;
}
aliash.put(bts[k], alias[k]);
}
}
}
Integer num = fs.getInteger("execute_count");
if (bts.length == num.intValue() && !StringUtils.isEmpty(fs.getString("template_sql"))) {//鐩哥瓑璇存槑涓変釜琛ㄩ兘鏇存柊瀹�
DataTableEntity sdt = baseDao.listTable("product_sys_database_sync_processing_config_sub", "main_uuid =? ", new String[]{fs.getUUID()});
FieldSetEntity table_filter = new FieldSetEntity();
table_filter.setTableName("temp");
StringBuilder b = new StringBuilder();
for (int j = 0; j < sdt.getRows(); j++) {
FieldSetEntity fss = sdt.getFieldSetEntity(j);
String pkf = baseDao.getPKField(fss.getString("table_name"));//鑾峰彇琛ㄧ殑pk瀛楁
if (pkf != null) {
if (!StringUtils.isEmpty(aliash.get(fss.getString("table_name")))) {
pkf = aliash.get(fss.getString("table_name")) + "." + pkf;
}
if (!StringUtils.isEmpty(fss.getString("update_ids"))) {//鏈変慨鏀逛簡鏁版嵁
if (b.length() > 0) {
b.append(" or ");
}
b.append(pkf).append(" in (").append(fss.getString("update_ids")).append(")");
}
if (!StringUtils.isEmpty(fss.getString("add_scope_id"))) {//鏈夋柊澧炴暟鎹�
if (b.length() > 0) {
b.append(" or ");
}
String scope[] = fss.getString("add_scope_id").split("~");
b.append(pkf).append(" between ").append(scope[0]).append(" and ").append(scope[1]);
}
} else {
//娌℃湁涓婚敭瀛楁锛屾槸鍚︽姏閿�
SpringMVCContextHolder.getSystemLogger().error("銆�" + fss.getString("table_name") + "銆戣〃娌℃湁閰嶇疆PK瀛楁銆�");
}
}
//鐢熸垚涓€涓€荤殑鏉′欢琛ㄨ揪寮忥紝濡傛灉娌℃湁锛屽垯continue;
if (b.length() > 0) {
table_filter.setValue("sync_data_process_data_filter", b.toString());
} else {
// continue;
table_filter.setValue("sync_data_process_data_filter", "1=1");
}
//寮€濮嬫浛鎹iew璇彞涓殑鏉′欢琛ㄨ揪寮�
String sql = SystemParamReplace.formParamsReplace(fs.getString("template_sql"), table_filter);
if (executorService == null) {
executorService = Executors.newFixedThreadPool(2);
}
if (orgDataMap == null) {
orgDataMap = new OrgDataMap();
}
OrgDataMap finalOrgDataMap = orgDataMap;
executorService.execute(() -> {
BatchData batchData = new BatchData(sql, fs.getString("basic_table"), 50000, 2000);
batchData.getDefaultValueMap().put("organization_type", 4);
batchData.getDefaultValueMap().put("dept_code", null);
fs.setValue("execute_count", 0);
baseDao.update(fs);
//寮€濮嬪鐞嗘暟鎹敓鎴愪汉鍛�,浠庡悓姝ヨ〃鍒版姤琛ㄥ熀纭€琛�
batchData.batchImprovedCoverage(fs.getBoolean("delete_data"), (obj) -> {
Map<String, Object> map = (Map<String, Object>) obj[0];
String user_id = null;
if (map.get("user_id") != null) {
user_id = String.valueOf(map.get("user_id"));
}
if (map.get(CmnConst.ORG_LEVEL_CODE) != null && map.containsKey(CmnConst.USER_ID) && map.containsKey("dept_code")) {
String code = (String) map.get(CmnConst.ORG_LEVEL_CODE);
if (finalOrgDataMap.isCompany(code)) {
if (user_id != null) {
String deptCode = finalOrgDataMap.getDeptCodeByUser(user_id);
if (!StringUtils.isEmpty(deptCode)) {
map.put("dept_code", deptCode);
}
}
} else if (finalOrgDataMap.isDept(code)) {
String companyCode = finalOrgDataMap.getCompanyCode(code);
if (StringUtils.isEmpty(companyCode)) {
companyCode = finalOrgDataMap.getCompanyCodeByUser(user_id);
}
if (!StringUtils.isEmpty(companyCode)) {
map.put(CmnConst.ORG_LEVEL_CODE, companyCode);
map.put("dept_code", code);
}
}
}
});
batchData.closeConnection();
//澶勭悊鏁版嵁鐢熸垚浜哄憳鏁版嵁锛屼粠鍚屾琛ㄥ埌鎶ヨ〃鍩虹琛紝鍐嶇敓鎴愰儴闂ㄣ€佸叕鍙告暟鎹紝鎶ヨ〃鍩虹琛ㄥ唴瀹瑰鐞�
lastProcessData(fs.getUUID());
baseDao.delete("product_sys_database_sync_processing_config_sub", "main_uuid=?", new Object[]{fs.getUUID()});
});
}
}
}
if (executorService != null) {
executorService.shutdown();
try {
executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
} catch (Exception e) {
e.printStackTrace();
SpringMVCContextHolder.getSystemLogger().error(e);
}
}
SpringMVCContextHolder.getSystemLogger().error("鍚屾澶勭悊鏁版嵁瀹屾垚锛侊紒锛�");
}
}
public class OrgDataMap {
private Map<String, FieldSetEntity> companyMap = new HashMap<>();
private Map<String, FieldSetEntity> deptMap = new HashMap<>();
private Map<String, String> staffDeptMap = new HashMap<>();
private Map<String, String> staffCompanyMap = new HashMap<>();
public OrgDataMap() {
//鍒濆鍖栫粍缁囨満鏋勮〃鏁版嵁
DataPoolCacheImpl dataPoolCache = DataPoolCacheImpl.getInstance();
// DataTableEntity companyDt = dataPoolCache.getCacheData("鎵€鏈夊叕鍙镐俊鎭�");
DataTableEntity companyDt = OrganizationCacheService.getOrgDataStatic("1");
readRecord(companyDt, this.companyMap);
// DataTableEntity deptDt = dataPoolCache.getCacheData("鍏徃-閮ㄩ棬");
DataTableEntity deptDt = OrganizationCacheService.getOrgDataStatic("2");
readRecord(deptDt, this.deptMap);
DataTableEntity dt = baseDao.listTable("SELECT user_id,l.org_level_code dept_code,l1.org_level_code company_code FROM `product_sys_staffs` s join product_sys_org_levels l on s.dept_uuid=l.uuid \n" +
"join product_sys_org_levels l1 on s.org_level_uuid=l1.uuid ", new Object[]{});
if (!DataTableEntity.isEmpty(dt)) {
DataTableEntity clones = dt.clones();
for (int i = 0; i < clones.getRows(); i++) {
this.staffDeptMap.put(clones.getString(i, "user_id"), clones.getString(i, "dept_code"));
this.staffCompanyMap.put(clones.getString(i, "user_id"), clones.getString(i, "company_code"));
}
}
}
/**
* 鏍规嵁userid鎵鹃儴闂╟ode
*
* @param userId
* @return
*/
public String getDeptCodeByUser(String userId) {
return this.staffDeptMap.get(userId);
}
/**
* 鏍规嵁userid鎵鹃儴闂╟ode
*
* @param userId
* @return
*/
public String getCompanyCodeByUser(String userId) {
return this.staffCompanyMap.get(userId);
}
/**
* 鑾峰彇鍏徃缂栫爜鏍规嵁閮ㄩ棬缂栫爜
*
* @param deptCode
* @return
*/
public String getCompanyCode(String deptCode) {
if (isExist(deptCode, this.deptMap)) {
FieldSetEntity fs = this.deptMap.get(deptCode);
String parentCode = fs.getString("org_level_code_parent");
String[] code = parentCode.split("-");
for (int i = 0; i < code.length; i++) {
parentCode = "";
for (int j = 0; j < code.length - i; j++) {
parentCode = (j > 0 ? parentCode + "-" : parentCode) + code[j];
}
if (isExist(parentCode, this.companyMap)) {
return this.companyMap.get(parentCode).getString(CmnConst.ORG_LEVEL_CODE);
}
}
}
return null;
}
/**
* 鍒ゆ柇鏄惁涓洪儴闂�
*
* @param code
* @return
*/
public boolean isDept(String code) {
return isExist(code, this.deptMap);
}
/**
* 鍒ゆ柇鏄惁涓哄叕鍙�
*
* @param code
* @return
*/
public boolean isCompany(String code) {
return isExist(code, this.companyMap);
}
/**
* 鏄惁瀛樺湪
*
* @param code 閿�
* @param map 鏄惁瀛樺湪姝ap
* @return
*/
private boolean isExist(String code, Map<String, FieldSetEntity> map) {
return code != null ? map.get(code) != null : false;
}
}
private void readRecord(DataTableEntity dt, Map<String, FieldSetEntity> map) {
if (DataTableEntity.isEmpty(dt) || map == null) return;
for (int i = 0; i < dt.getRows(); i++) {
FieldSetEntity fs = dt.getFieldSetEntity(i);
String code = fs.getString(CmnConst.ORG_LEVEL_CODE);
map.put(code, fs.clones());
}
}
/**
* 浜屾澶勭悊鏁版嵁鏍规嵁宸插鐞嗙殑鍩虹琛�
*/
public void firstProcessData() {
DataTableEntity dt = baseDao.listTable("product_sys_database_sync_processing_config", " (parent_uuid is null or parent_uuid ='')", new Object[]{});
OrgDataMap orgDataMap = new OrgDataMap();
FieldSetEntity table_filter = new FieldSetEntity();
table_filter.setTableName("temp");
table_filter.setValue("sync_data_process_data_filter", "1=1");
ExecutorService executorService = Executors.newFixedThreadPool(10);
for (int i = 0; i < dt.getRows(); i++) {
int finalI = i;
executorService.execute(() -> {
FieldSetEntity fs = dt.getFieldSetEntity(finalI);
String sql = SystemParamReplace.formParamsReplace(fs.getString("template_sql"), table_filter);
BatchData batchData = new BatchData(sql, fs.getString("basic_table"), 100000, 2000);
batchData.getDefaultValueMap().put("organization_type", 4);
batchData.getDefaultValueMap().put("dept_code", null);
OrgDataMap finalOrgDataMap = orgDataMap;
//寮€濮嬪鐞嗘暟鎹敓鎴愪汉鍛�,浠庡悓姝ヨ〃鍒版姤琛ㄥ熀纭€琛�
batchData.batchImprovedCoverage(fs.getBoolean("delete_data"), (obj) -> {
Map<String, Object> map = (Map<String, Object>) obj[0];
String user_id = null;
if (map.get("user_id") != null) {
user_id = String.valueOf(map.get("user_id"));
}
if (map.get(CmnConst.ORG_LEVEL_CODE) != null && map.containsKey(CmnConst.USER_ID) && map.containsKey("dept_code")) {
String code = (String) map.get(CmnConst.ORG_LEVEL_CODE);
if (finalOrgDataMap.isCompany(code)) {
if (user_id != null) {
String deptCode = finalOrgDataMap.getDeptCodeByUser(user_id);
if (StringUtils.isEmpty(deptCode)) {
map.put("dept_code", deptCode);
}
}
} else if (finalOrgDataMap.isDept(code)) {
String companyCode = finalOrgDataMap.getCompanyCode(code);
if (StringUtils.isEmpty(companyCode)) {
companyCode = finalOrgDataMap.getCompanyCodeByUser(user_id);
}
if (!StringUtils.isEmpty(companyCode)) {
map.put(CmnConst.ORG_LEVEL_CODE, companyCode);
map.put("dept_code", code);
}
}
}
});
batchData.closeConnection();
//澶勭悊鏁版嵁鐢熸垚浜哄憳鏁版嵁锛屼粠鍚屾琛ㄥ埌鎶ヨ〃鍩虹琛紝鍐嶇敓鎴愰儴闂ㄣ€佸叕鍙告暟鎹紝鎶ヨ〃鍩虹琛ㄥ唴瀹瑰鐞�
lastProcessData(fs.getUUID());
});
}
executorService.shutdown();
while (!executorService.isTerminated()) {
}
SpringMVCContextHolder.getSystemLogger().info("缁撴潫浠诲姟firstProcessData锛侊紒锛侊紒锛侊紒锛侊紒锛侊紒锛侊紒");
}
/**
* 鏍规嵁 product_sys_database_sync_processing_config.uuid 鎵ц鏁版嵁澶勭悊
*/
public void firstProcessData(String parent_uuid) {
FieldSetEntity fs = baseDao.getFieldSetByFilter("product_sys_database_sync_processing_config", "parent_uuid=?", new Object[]{parent_uuid}, false);
if (fs != null) {
firstProcessData(fs);
}
}
/**
* 鏍规嵁 product_sys_database_sync_processing_config琛ㄤ俊鎭� 鎵ц鏁版嵁澶勭悊
*/
public void firstProcessData(FieldSetEntity fs) {
if (fs == null) {
return;
}
OrgDataMap orgDataMap = new OrgDataMap();
BatchData batchData = new BatchData(fs.getString("template_sql"), fs.getString("basic_table"), 100000, 2000);
batchData.getDefaultValueMap().put("organization_type", 4);
if (orgDataMap == null) {
orgDataMap = new OrgDataMap();
}
OrgDataMap finalOrgDataMap = orgDataMap;
batchData.getDefaultValueMap().put("dept_code", null);
batchData.batchImprovedCoverage(true, (obj) -> {
Map<String, Object> map = (Map<String, Object>) obj[0];
String user_id = null;
if (map.get("user_id") != null) {
user_id = String.valueOf(map.get("user_id"));
}
if (map.get(CmnConst.ORG_LEVEL_CODE) != null && map.containsKey(CmnConst.USER_ID) && map.containsKey("dept_code")) {
String code = (String) map.get(CmnConst.ORG_LEVEL_CODE);
if (finalOrgDataMap.isCompany(code)) {
if (user_id != null) {
String deptCode = finalOrgDataMap.getDeptCodeByUser(user_id);
if (StringUtils.isEmpty(deptCode)) {
map.put("dept_code", deptCode);
}
}
} else if (finalOrgDataMap.isDept(code)) {
String companyCode = finalOrgDataMap.getCompanyCode(code);
if (StringUtils.isEmpty(companyCode)) {
companyCode = finalOrgDataMap.getCompanyCodeByUser(user_id);
}
if (!StringUtils.isEmpty(companyCode)) {
map.put(CmnConst.ORG_LEVEL_CODE, companyCode);
map.put("dept_code", code);
}
}
}
});
batchData.closeConnection();
lastProcessData(fs.getUUID());
baseDao.update(fs);
baseDao.delete("product_sys_database_sync_processing_config_sub", "main_uuid=?", new Object[]{fs.getUUID()});
}
public void lastProcessData(String parentUuid) {
DataTableEntity dt = baseDao.listTable("product_sys_database_sync_processing_config", "parent_uuid=?", new Object[]{parentUuid});
for (int i = 0; i < dt.getRows(); i++) {
FieldSetEntity ff = dt.getFieldSetEntity(i);
if (ff != null && ff.getUUID() != null) {
this.executeDataProcess(ff.getString("template_sql"), ff.getString("basic_table"), ff.getBoolean("delete_data"));
this.lastProcessData(ff.getUUID());
}
}
}
private void executeDataProcess(String sql, String basic_table, boolean deleteData) {
BatchData batchData = new BatchData(sql, basic_table, 50000, 2000);
batchData.batchImprovedCoverage(deleteData, null);
batchData.closeConnection();
}
/**
* 鏇存柊鍚屾璁板綍
*
* @param tableName 鍚屾鐩爣琛�
* @param add_ids 鍚屾淇敼鎴栨柊澧炵殑鏁版嵁ids
* @param updateIds 鏇存柊鏁版嵁鐨刬ds 閫楀彿鍒嗛殧
*/
@Override
@Transactional
public void updateSyncRecord(String tableName, Integer[] add_ids, String updateIds) throws BaseException {
DataTableEntity dt = baseDao.listTable("product_sys_database_sync_processing_config", "concat(',',relevance_table,',') like concat('%,',?,',%') and (parent_uuid is null or parent_uuid ='')", new Object[]{tableName});
if (!DataTableEntity.isEmpty(dt)) {
for (int i = 0; i < dt.getRows(); i++) {
if (!StringUtils.isEmpty(updateIds) || (add_ids != null && add_ids.length > 0)) {
FieldSetEntity fs = new FieldSetEntity();
fs.setTableName("product_sys_database_sync_processing_config_sub");
fs.setValue(CmnConst.TABLE_NAME, tableName);
if (add_ids != null && add_ids.length > 0) {
List<String> idScope = summaryRanges(add_ids);
fs.setValue("add_scope_id", Joiner.on(",").join(idScope.toArray()));
}
fs.setValue("update_ids", updateIds);
DataTableEntity dataTableEntity = new DataTableEntity();
dataTableEntity.addFieldSetEntity(fs);
dt.getFieldSetEntity(i).addSubDataTable(dataTableEntity);
}
//鎵ц娆℃暟+1
Integer execute_count = dt.getInt(i, "execute_count");
if (execute_count == null) {
execute_count = 1;
} else {
execute_count++;
}
dt.setFieldValue(i, "execute_count", execute_count);
baseDao.update(dt.getFieldSetEntity(i));
}
}
this.copyViewDataToTable(tableName);
}
/**
* 鑾峰彇鏁扮粍涓暟瀛楃殑鑼冨洿
*
* @param nums 鏁扮粍
* @return
*/
public static List<String> summaryRanges(Integer[] nums) {
Arrays.sort(nums);
List<String> list = new ArrayList<>();
if (nums.length == 0) {
return list;
}
int begin = Integer.MIN_VALUE;
int end = Integer.MIN_VALUE;
for (int i = 0; i < nums.length; i++) {
if (i == 0) {
begin = nums[i];
} else if (nums[i - 1] < nums[i] - 1) {
list.add(begin + "~" + end);
begin = nums[i];
}
end = nums[i];
if (i == nums.length - 1) {
list.add(begin + "~" + end);
}
}
return list;
}
}