import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zyxx.common.annotation.Dict;
import com.zyxx.common.utils.LayTableResult;
import com.zyxx.common.utils.ObjConvertUtils;
import com.zyxx.sbm.entity.SysDictDetail;
import com.zyxx.sbm.service.SysDictService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* Data dictionary cutout
*
* @author Tellsea
* @date 2020/6/23
*/
@Aspect
@Component
@Slf4j
public class DictAspect {
/**
* Dictionary suffix
*/
private static String DICT_TEXT_SUFFIX = "Text";
@Autowired
private SysDictService sysDictService;
/**
* Cut point, cuts into all methods under the controller package.
*/
@Pointcut("execution( * .*.controller.*.*(..))")
public void dict() {
}
@Around("dict()")
public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
long time1 = System.currentTimeMillis();
Object result = pjp.proceed();
long time2 = System.currentTimeMillis();
log.debug("Getting JSON data Time consuming:" + (time2 - time1) + "ms");
long start = System.currentTimeMillis();
this.parseDictText(result);
long end = System.currentTimeMillis();
log.debug("Parsing injected JSON data Time consuming" + (end - start) + "ms");
return result;
}
private void parseDictText(Object result) {
if (result instanceof LayTableResult) {
List<JSONObject> items = new ArrayList<>();
LayTableResult rr = (LayTableResult) result;
if (rr.getCount() > 0) {
List<?> list = (List<?>) rr.getData();
for (Object record : list) {
ObjectMapper mapper = new ObjectMapper();
String json = "{}";
try {
// See @JsonFormat in the SysAnnouncement class for a solution to the problem of @JsonFormat annotations not being parsed.
json = mapper.writeValueAsString(record);
} catch (JsonProcessingException e) {
log.error("Json parsing failed:" + e);
}
JSONObject item = JSONObject.parseObject(json);
// Resolve untranslatable inherited entity fields
for (Field field : ObjConvertUtils.getAllFields(record)) {
//Resolve untranslatable fields of inherited entities
// Translate if there is a @Dict annotation above the property
if (field.getAnnotation(Dict.class) != null) {
// Get the value of the annotated dictDataSource property.
String dictType = field.getAnnotation(Dict.class).dictCode();
// Get the value of the annotation's dictText property.
String text = field.getAnnotation(Dict.class).dictText();
// Get the current value with translation
String key = String.valueOf(item.get(field.getName()));
//Translate the text value corresponding to the dictionary value.
String textValue = translateDictValue(dictType, key);
// The value of DICT_TEXT_SUFFIX is the default value:
// public static final String DICT_TEXT_SUFFIX = "_dictText";
log.debug("Dictionary Val:" + textValue);
log.debug("Translation of dictionary fields:" + field.getName() + DICT_TEXT_SUFFIX + ": " + textValue);
// If a text name is given
if (!StringUtils.isBlank(text)) {
item.put(text, textValue);
} else {
// Go to the default policy
item.put(field.getName() + DICT_TEXT_SUFFIX, textValue);
}
}
// The date type is converted to string formatting by default.
if ("".equals(field.getType().getName())
&& field.getAnnotation(JsonFormat.class) == null
&& item.get(field.getName()) != null) {
SimpleDateFormat aDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
item.put(field.getName(), aDate.format(new Date((Long) item.get(field.getName()))));
}
}
items.add(item);
}
rr.setData(items);
}
}
}
/**
* :: Translation of dictionary text
*
* @param dictType
* @param key
* @return
*/
private String translateDictValue(String dictType, String key) {
if (ObjConvertUtils.isEmpty(key)) {
return null;
}
StringBuffer textValue = new StringBuffer();
String[] keys = key.split(",");
for (String k : keys) {
if (k.trim().length() == 0) {
continue;
}
/**
* According to dictCode and code query dictionary value, for example: dictCode:sex,code:1, return:male
* Should be placed in redis to improve response time
*/
SysDictDetail dictData = sysDictService.getDictDataByTypeAndValue(dictType, key);
if (dictData.getName() != null) {
if (!"".equals(textValue.toString())) {
textValue.append(",");
}
textValue.append(dictData.getName());
}
log.info("Data dictionary translation: dictionary type: {}, current translation value: {}, translation result: {}", dictType, k.trim(), dictData.getName());
}
return textValue.toString();
}
}