package com.fourdage.dingding.util;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.math.BigDecimal;
import java.nio.charset.Charset;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.joda.time.DateTime;
import org.joda.time.LocalDateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Repository;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fourdage.base.common.HttpHelper;
import com.fourdage.dingding.entity.PdfVO;
import com.fourdage.system.entity.DataDictionary;
import com.fourdage.system.entity.User;
import com.fourdage.system.service.IDataDictionaryService;
import com.itextpdf.text.Document;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.tool.xml.XMLWorkerFontProvider;
import com.itextpdf.tool.xml.XMLWorkerHelper;

import freemarker.template.Configuration;
import freemarker.template.Template;


@Repository
public class HtmlPdfUtil {


	
	@Autowired
	private IDataDictionaryService dataDictionaryService;
	
	@Autowired
	private DingDingUtil dingdingUtil;
	
	@Value("${web.pdf.file.path}")
    private String path;
	
	private Logger logger = LoggerFactory.getLogger(HtmlPdfUtil.class);
	
	private String blankCode = "            &nbsp;&nbsp;";
	
	public void generateHTMLFile_1(String accessToken, String processInstanceId, String fileName) {
		logger.info("run generateHTMLFile");
//		FileWriter out = null;
		OutputStreamWriter out = null;
		try {
			String title = "";
			String businessId = "";
			logger.info("请求参数，processInstanceId：{}， accessToken：{}", processInstanceId, accessToken);
//			dingdingUtil.getWorkflowInfo(accessToken, processInstanceId);

//				String body = HttpUtil.
//					createGet(StrUtil.format("http://127.0.0.1:8001//api/dingTalk/getWorkflowInfo/{}", processInstanceId))
//					.execute().body();
//				logger.info("服务返回值：{}", body);
//
//			JSONObject parseJson = JSONObject.parseObject(body);
//
//			Integer code = parseJson.getInteger("code");
//			if (code != 0){
//				logger.error("服务返回异常");
//				return;
//			}
//
//			JSONObject jsonResult = parseJson.getJSONObject("data");


			JSONObject jsonResult = dingdingUtil.getDingDingJSONResult(processInstanceId, accessToken);
			logger.info("钉钉返回数据： {}", jsonResult);
			if (jsonResult.getBoolean("success")){
//				DataDictionary corp = dataDictionaryService.findByCodeAndDataKey("corp_code", dingdingUtil.getRegion());

				JSONObject result = jsonResult.getJSONObject("process_instance");
				logger.info("result:{}", result);
				//企业名称
//				String corpName = corp.getDataValue();
				String corpName = "四维时代 & 中德人工智能研究院";
				//申请日期
				String applyDate = result.getString("create_time");
				//审批编码
				businessId = result.getString("business_id");
				String[] titlesArr = null;
				if(result.getString("title").contains("的")){
					titlesArr = result.getString("title").split("的");
				}
				if(result.getString("title").contains("'s")){
					titlesArr = result.getString("title").split("'s");
				}
				String applyUserName = titlesArr[0];
				//申请人
				//模板名称
				title = titlesArr[1];
				//申请人部门
				String org = result.getString("originator_dept_name");

				PdfVO vo = new PdfVO();
				vo.setCorpName(corpName);
				vo.setApplyDate(applyDate);
				vo.setBusinessId(businessId);
				vo.setApplyUserName(applyUserName);
				vo.setTitle(title);
				vo.setOrg(org);
				vo.setStatus(dingdingUtil.getStatus(result.getString("status")));
				// 内容 html
				vo.setForm(generateForm_1(result).toString());
				vo.setOperations(generateOperators_1(accessToken, result).toString());
				vo.setPrintDate(new DateTime().toString("yyyy-MM-dd HH:mm"));

				Subject subject = SecurityUtils.getSubject();
	            Object principal = subject.getPrincipal();
	            String userName = "";
	            if (principal != null) {
	            	userName = ((User) principal).getNickName();
	            }
	            vo.setPrinter(userName);

				Configuration configuration = new Configuration();
				configuration.setDirectoryForTemplateLoading(new File(path));
				configuration.setDefaultEncoding("UTF-8");
				// 获取或创建一个模版。
				Template template = configuration.getTemplate("pdf.ftl");
				//设置输出流
				File file = new File(path + fileName + ".html");
//				out = new FileWriter(file);
				//设置文件输入流编码，不然生成的html文件会中文乱码
				out = new OutputStreamWriter(new FileOutputStream(file),"UTF-8");
				//模板输出静态文件
				template.process(vo, out);
			}
		}catch (Exception e) {
    		logger.error("系统异常：", e);
    	} finally {
    		if(null != out) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
    	}
	}


	/**
	 * 报销申请返回的数据结构变了， 使用新接口
	 * @param accessToken
	 * @param processInstanceId
	 * @param fileName
	 */
	public void generateHTMLFile_2(String accessToken, String processInstanceId, String fileName) {
		logger.info("run generateHTMLFile_2");
		OutputStreamWriter out = null;
		try {
			String title = "";
			String businessId = "";
			logger.info("请求参数，processInstanceId：{}， accessToken：{}, fileName:{}", processInstanceId, accessToken, fileName);

			// 2024-03-07 by owen, 旧接口的报销申请返回的数据结构变了,使用了钉钉工时提醒应用的appkey 对应的接口
			String body = HttpUtil.
					createGet(StrUtil.format("http://project.4dage.com:8003/api/dingTalk/getWorkflowInfo/{}", processInstanceId))
					.execute().body();
			logger.info("服务返回值：{}", body);

			JSONObject parseJson = JSONObject.parseObject(body);

			Integer code = parseJson.getInteger("code");
			if (code != 0){
				logger.error("服务返回异常");
				return;
			}

			JSONObject jsonResult = parseJson.getJSONObject("data");


			logger.info("钉钉返回数据： {}", jsonResult);
			if (jsonResult.getBoolean("success")){

				JSONObject result = jsonResult.getJSONObject("result");
				logger.info("result:{}", result);
				//企业名称
				String corpName = "四维时代 & 中德人工智能研究院";
				//申请日期
				String applyDate = result.getString("createTime");
				applyDate = convertTime(applyDate);

				//审批编码
				businessId = result.getString("businessId");
				String[] titlesArr = null;
				String titleStr = result.getString("title");
				if(titleStr.contains("的")){
					titlesArr = titleStr.split("的");
				}
				if(titleStr.contains("'s")){
					titlesArr = titleStr.split("'s");
				}
				String applyUserName = titlesArr[0];
				//申请人
				//模板名称
				title = titlesArr[1];
				//申请人部门
				String org = result.getString("originatorDeptName");

				PdfVO vo = new PdfVO();
				vo.setCorpName(corpName);
				vo.setApplyDate(applyDate);
				vo.setBusinessId(businessId);
				vo.setApplyUserName(applyUserName);
				vo.setTitle(title);
				vo.setOrg(org);
				vo.setStatus(dingdingUtil.getStatus(result.getString("status")));
				// 处理报销明细等
				vo.setForm(generateForm_2(result, title).toString());
				// 处理审批人详情
				vo.setOperations(generateOperators_2(accessToken, result).toString());
				vo.setPrintDate(new DateTime().toString("yyyy-MM-dd HH:mm"));

				Subject subject = SecurityUtils.getSubject();
				Object principal = subject.getPrincipal();
				String userName = "";
				if (principal != null) {
					userName = ((User) principal).getNickName();
				}
				vo.setPrinter(userName);

				Configuration configuration = new Configuration();
				configuration.setDirectoryForTemplateLoading(new File(path));
				configuration.setDefaultEncoding("UTF-8");
				// 获取或创建一个模版。
				Template template = configuration.getTemplate("pdf.ftl");
				//设置输出流
				File file = new File(path + fileName + ".html");
//				out = new FileWriter(file);
				//设置文件输入流编码，不然生成的html文件会中文乱码
				out = new OutputStreamWriter(new FileOutputStream(file),"UTF-8");
				//模板输出静态文件
				template.process(vo, out);
			}
		}catch (Exception e) {
			logger.error("系统异常：", e);
		} finally {
			if(null != out) {
				try {
					out.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	private String convertTime(String time){
		// 使用ISO_INSTANT日期时间格式化器解析ISO 8601格式的字符串
		OffsetDateTime offsetDateTime = OffsetDateTime.parse(time);

		// 创建自定义的日期时间格式化器，并指定时区为UTC
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneId.of("UTC"));

		// 使用格式化器格式化OffsetDateTime
		String formattedDateTime = offsetDateTime.format(formatter);

		return formattedDateTime;
	}

	public String generateHtmlAndPDF(String accessToken, String processInstanceId, String processCodeName) {
		logger.info("run generateHtmlAndPDF");
    	String fileName = "";	
    	try {
    		//从钉钉接口获取结果
//			logger.info("请求参数，processInstanceId：{}， accessToken：{}", processInstanceId, accessToken);
    		JSONObject jsonResult = dingdingUtil.getDingDingJSONResult(processInstanceId, accessToken);
			logger.info("钉钉返回数据2： {}", jsonResult);
    		if (!jsonResult.getBoolean("success")) {
    			return "";
    		}
    		//生成文件目录
    		File dirFile = new File(path + processCodeName);
    		if(!dirFile.exists()){
    			dirFile.mkdir();
    		}
    		JSONObject result = jsonResult.getJSONObject("process_instance");
    		fileName = result.getString("title") + result.getString("business_id");
    		String filePathName = path + processCodeName + "/" + fileName;
    		//生成HTML文件
    		generateHTMLFile_2(accessToken, processInstanceId, processCodeName + "/" + fileName);
    		//生成pdf文件
    		generatePdfFile(filePathName);
    		
    		FileUtil.deleteFile(filePathName + ".html");
    	} catch (Exception e) {
    		logger.error("系统异常：", e);
    	} finally {
    	}
    	return fileName;
    }
	
	public void generatePdfFile(String filePathName) {
		logger.info("run generatePdfFile 11111");
		Document document = null;
		FileInputStream fis = null;
		BufferedReader br = null;
		InputStreamReader reader  = null;
		try {
//			fis = new FileInputStream(filePathName + ".html"); 
//			byte[] buf = new byte[1024];  
//			int length = 0;
//			//循环读取文件内容，输入流中将最多buf.length个字节的数据读入一个buf数组中,返回类型是读取到的字节数。
//			//当文件读取到结尾时返回 -1,循环结束。
//			String content = null;
//			while((length = fis.read(buf)) != -1){
//				content = new String(buf,0,length);
//			    System.out.print(content);
//			}
			
			
            fis = new FileInputStream(filePathName + ".html");
            reader = new InputStreamReader(fis, "UTF-8"); 
            br = new BufferedReader(reader);
            String content;
            String ba = null;
            while ((content = br.readLine()) != null) {
                System.out.println(content);
                ba += content;
            }
			byte b[] = ba.getBytes("utf-8"); //这里是必须要设置编码的，不然导出中文就会乱码。 
			ByteArrayInputStream bais = new ByteArrayInputStream(b);//将字节数组包装到流中
			
			// step 1
			document = new Document(PageSize.A4);
			// step 2
			PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(filePathName + ".pdf"));
			// step 3
			document.open();
			// step 4
			XMLWorkerFontProvider fontImp = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS);
			fontImp.register("/font/simhei.ttf");
			XMLWorkerHelper.getInstance().parseXHtml(writer, document, bais, null, Charset.forName("UTF-8"), fontImp);
			document.close();
			br.close();
            reader.close();
			fis.close();
		} catch (Exception e) {
    		logger.error("系统异常：", e);
    	} finally {
    		if (document != null) {
    			document.close();
    		}
    		if (fis != null){
    			try {
					fis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
    		}
    		if (br != null){
    			try {
					br.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
    		}
    		if (reader != null){
    			try {
					reader.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
    		}
    	}
	}
	
	private StringBuffer generateOperators_1(String accessToken, JSONObject result) {
		JSONArray userArray = result.getJSONObject("operation_records").getJSONArray("operation_records_vo");
		StringBuffer userSB = null;
		if (userArray != null && userArray.size() > 0){
			userSB = new StringBuffer("<tr><td rowspan=\"").append(userArray.size()-1).append("\">审批人</td>");
			for (int i = 0; i < userArray.size(); i++){
				JSONObject ob = (JSONObject) userArray.get(i);
				if ("START_PROCESS_INSTANCE".equals(ob.getString("operation_type"))){
					continue;
				}
				if (i == 1){
					userSB.append("<td>");
				}else{
					userSB.append("<tr><td>");
				}
				
				//获取用户信息
		    	Map<String, Object> tokenMap = new HashMap<String, Object>();
		    	tokenMap.put("access_token", accessToken);
		    	tokenMap.put("userid", ob.getString("userid"));
		    	String userStr = HttpHelper.sendGetByHttpUrlConnection("https://oapi.dingtalk.com/user/get", tokenMap, "UTF-8");
		    	JSONObject userObject = JSON.parseObject(userStr);
				userSB.append(userObject.getString("name")).append(blankCode);
				//获取操作结果
				if ("EXECUTE_TASK_NORMAL".equals(ob.getString("operation_type"))){
					userSB.append(dingdingUtil.getTaskResult(ob.getString("operation_result")));
					if (StringUtils.isNotEmpty(ob.getString("remark"))){
						userSB.append("（").append(ob.getString("remark")).append("）").append(blankCode);
					}
					userSB.append(blankCode);
				}else if ("ADD_REMARK".equals(ob.getString("operation_type"))){
					userSB.append("添加评论（").append(ob.getString("remark")).append("）").append(blankCode);
				}else {
					userSB.append(dingdingUtil.getTaskResult(ob.getString("operation_result"))).append(blankCode);
				}
				userSB.append(ob.getString("date") == null ? "" : ob.getString("date")).append("</td></tr>");
			}
		}
		return userSB;
	}

	/**
	 * 2024-03-07 因钉钉返回数据结构变动，用此方法
	 * 处理审批人详情
	 * @param accessToken
	 * @param result
	 * @return
	 */
	private StringBuffer generateOperators_2(String accessToken, JSONObject result) {
		JSONArray userArray = result.getJSONArray("operationRecords");
		StringBuffer userSB = null;
		if (userArray != null && userArray.size() > 0){
			userSB = new StringBuffer("<tr><td rowspan=\"").append(userArray.size()-1).append("\">审批人</td>");
			for (int i = 0; i < userArray.size(); i++){
				JSONObject ob = (JSONObject) userArray.get(i);
				String type = ob.getString("type");
				if ("START_PROCESS_INSTANCE".equals(type)){
					continue;
				}
				if (i == 1){
					userSB.append("<td>");
				}else{
					userSB.append("<tr><td>");
				}

				//获取用户信息
				Map<String, Object> tokenMap = new HashMap<String, Object>();
				tokenMap.put("access_token", accessToken);
				tokenMap.put("userid", ob.getString("userId"));
				String userStr = HttpHelper.sendGetByHttpUrlConnection("https://oapi.dingtalk.com/user/get", tokenMap, "UTF-8");
//				logger.info("userStr:{}", userStr);
				JSONObject userObject = JSON.parseObject(userStr);
				userSB.append(userObject.getString("name")).append(blankCode);

				String remark = ob.getString("remark");
				String resultStr = ob.getString("result");
				//获取操作结果
				if ("EXECUTE_TASK_NORMAL".equals(type)){
					userSB.append(dingdingUtil.getTaskResult(resultStr));
					if (StringUtils.isNotEmpty(remark)){
						userSB.append("（").append(remark).append("）").append(blankCode);
					}
					userSB.append(blankCode);
				}else if ("ADD_REMARK".equals(type)){
					userSB.append("添加评论（").append(remark).append("）").append(blankCode);
				}else {
					userSB.append(dingdingUtil.getTaskResult(resultStr)).append(blankCode);
				}
				String date = ob.getString("date");
				date = convertTime(date);

				userSB.append(date == null ? "" : date).append("</td></tr>");
			}
		}
		return userSB;
	}
	
	private StringBuffer generateForm_1(JSONObject result) {
		logger.info("run generateForm_1");
		logger.info("输入参数：{}", result);

		JSONArray formArray = result.getJSONObject("form_component_values").getJSONArray("form_component_value_vo");
		logger.info("formArray：{}", formArray);


		// 2023-09-18 获取付款金额

		JSONObject hasPay = getHasPay(formArray);
		if (hasPay.getBooleanValue("hasAdd")){
			formArray.add(7, hasPay);
		}

		StringBuffer formSB = null;
		if (formArray != null && formArray.size() > 0){
			formSB = new StringBuffer();
			for (Object o : formArray){
				JSONObject ob = (JSONObject) o;
				// 图片、附件、说明的行不显示
				if ("图片".equals(ob.getString("name")) 
						|| "附件".equals(ob.getString("name")) 
						|| "说明".equals(ob.getString("name")) 
						|| "null".equals(ob.getString("name"))
						|| null == ob.getString("name")){
					continue;
				} 
				// 处理表单中表单名是否是json对象，如[开始时间、结束时间]
				if (dingdingUtil.isJSONValid(ob.getString("name"))){
					JSONArray array = JSON.parseArray(ob.getString("name"));
					if (array != null){
						formSB.append("<tr><td>");
						for (int i = 0; i < array.size(); i++){
							formSB.append(array.get(i)).append(i == array.size() - 1 ? "" : "/");
						}
						formSB.append("</td><td>");
					}
				}else{
					formSB.append("<tr><td>").append(ob.getString("name")).append("</td><td>");
				}
				//处理表单中表单名对应的表单值，空值不显示
				String value = ob.getString("value");
				if ("null".equals(value)){
					formSB.append("");
					//处理表单值是否是json对象
				}else if (dingdingUtil.isJSONValid(value)){
					JSONArray array = JSON.parseArray(ob.getString("value"));
					for (int i = 0; i < array.size(); i++){
						if (array.get(i) instanceof String || array.get(i) instanceof Integer || array.get(i) instanceof BigDecimal){
							formSB.append(array.get(i)).append(i == array.size() - 1 ? "" : blankCode);
						}
						else {
							JSONObject objecte = (JSONObject)array.get(i);
							JSONArray rowValue = objecte.getJSONArray("rowValue");
							if (rowValue != null){
								for (Object rowObj : rowValue){
									JSONObject row = (JSONObject)rowObj;
									formSB.append("<p>");
									if (dingdingUtil.isJSONValid(row.getString("label"))){
										JSONArray labelArray = JSON.parseArray(row.getString("label"));
										if (labelArray != null){
											for (int j = 0; j < labelArray.size(); j++){
												formSB.append(labelArray.get(j)).append(j == labelArray.size() - 1 ? "" : "/");
											}
										}
									}else if ("说明".equals(row.getString("label")) 
											|| "null".equals(row.getString("label"))
											|| null == row.getString("label")){
										formSB.append("</p>");
										continue;
									}else{
										formSB.append(row.getString("label"));
									}
									formSB.append("：");
									if (dingdingUtil.isJSONValid(row.getString("value"))){
										JSONArray valueArray = JSON.parseArray(row.getString("value"));
										if (valueArray != null){
											for (int j = 0; j < valueArray.size(); j++){
												formSB.append(valueArray.get(j)).append(j == valueArray.size() - 1 ? "" : "/");
											}
										}
									}else{
										formSB.append(row.getString("value")).append(blankCode);
									}
									formSB.append("</p>");
								}
							}else{
//								formSB.append("<td><tr>");
							}
						}
						if (i != array.size() - 1){
							formSB.append("<p>&nbsp;&nbsp;</p>");
						}
					}

					// 2022-2-23 by owen 钉钉返回的数据会导致解析异常
//					if (ob.getString("ext_value") != null){
//
//						JSONArray objArr = JSON.parseObject(ob.getString("ext_value")).getJSONArray("statValue");
//
//						if (objArr.size() > 0){
//							formSB.append("<p>&nbsp;&nbsp;</p>");
//							for (int i = 0; i < objArr.size(); i++){
//								JSONObject objecte = (JSONObject)objArr.get(i);
//								formSB.append(objecte.getString("label")).append("：").append(objecte.getString("num")).append("（").append(objecte.getString("upper")).append("）");
//								if (i != objArr.size() - 1){
//									formSB.append("<p>&nbsp;&nbsp;</p>");
//								}
//							}
//						}
//						}
					
				}else{
					formSB.append(value);
				}
				formSB.append("</td></tr>");
			}
		}
		return formSB;
	}


	/**
	 * 2024-03-07 因钉钉返回数据结构变动，用此方法
	 * 处理单位， 报销明细,原借款(元),合计报销金额(元)
	 * @param result
	 * @return
	 */
	private StringBuffer generateForm_2(JSONObject result, String title) {
		logger.info("run generateForm_2");
//		logger.info("输入参数：{}", result);

		// 报销详情
		JSONArray formArray = result.getJSONArray("formComponentValues");
		logger.info("formArray：{}", formArray);


		// 2023-09-18 获取付款金额
		JSONObject hasPay = getHasPay(formArray);
		if (hasPay.getBooleanValue("hasAdd")){
			formArray.add(7, hasPay);
		}

		StringBuffer formSB = null;

		List<String> constantType = Arrays.asList("单位", "报销明细","原借款(元)", "合计报销金额(元)");
		if (formArray != null && formArray.size() > 0){
			formSB = new StringBuffer();
			for (Object o : formArray){
				JSONObject ob = (JSONObject) o;

				// 图片、附件、说明的行不显示
				String name = ob.getString("name");

				// 过滤不显示类型
				if ("报销申请".equals(title)){
					if (!constantType.contains(name)){
						continue;
					}
				}

				if ("图片".equals(name)
						|| "附件".equals(name)
						|| "说明".equals(name)
						|| "预计付款日期".equals(name)
						|| "支出类别".equals(name)
						|| "归属人".equals(name)
						|| "发票".equals(name)
//						|| "备注".equals(name)
						|| "项目".equals(name)
						|| "客户".equals(name)
						|| "供应商".equals(name)
						|| "企业账户".equals(name)
						|| "null".equals(name)
						|| null == name){
					continue;
				}



				// 处理表单中表单名是否是json对象，如[开始时间、结束时间]
				if (dingdingUtil.isJSONValid(name)){
					JSONArray array = JSON.parseArray(name);
					if (array != null){
						formSB.append("<tr><td>");
						for (int i = 0; i < array.size(); i++){
							formSB.append(array.get(i)).append(i == array.size() - 1 ? "" : "/");
						}
						formSB.append("</td><td>");
					}
				}else{
					formSB.append("<tr><td>").append(name).append("</td><td>");
				}
				//处理表单中表单名对应的表单值，空值不显示
				String value = ob.getString("value");
				if ("null".equals(value) || StrUtil.isBlank(value)){
					formSB.append("");
					//处理表单值是否是json对象
				}else if (dingdingUtil.isJSONValid(value)){



					JSONArray array = JSON.parseArray(value);
					for (int i = 0; i < array.size(); i++){
						if (array.get(i) instanceof String || array.get(i) instanceof Integer || array.get(i) instanceof BigDecimal){
							formSB.append(array.get(i)).append(i == array.size() - 1 ? "" : blankCode);
						}
						else {
							JSONObject objecte = (JSONObject)array.get(i);
							JSONArray rowValue = objecte.getJSONArray("rowValue");
							if (rowValue != null){
								for (Object rowObj : rowValue){
									JSONObject row = (JSONObject)rowObj;
									formSB.append("<p>");
									if (dingdingUtil.isJSONValid(row.getString("label"))){
										JSONArray labelArray = JSON.parseArray(row.getString("label"));
										if (labelArray != null){
											for (int j = 0; j < labelArray.size(); j++){
												formSB.append(labelArray.get(j)).append(j == labelArray.size() - 1 ? "" : "/");
											}
										}
									}else if ("说明".equals(row.getString("label"))
											|| "null".equals(row.getString("label"))
											|| null == row.getString("label")){
										formSB.append("</p>");
										continue;
									}else{
										formSB.append(row.getString("label"));
									}
									formSB.append("：");
									if (dingdingUtil.isJSONValid(row.getString("value"))){
										JSONArray valueArray = JSON.parseArray(row.getString("value"));
										if (valueArray != null){
											for (int j = 0; j < valueArray.size(); j++){
												formSB.append(valueArray.get(j)).append(j == valueArray.size() - 1 ? "" : "/");
											}
										}
									}else{
										formSB.append(row.getString("value")).append(blankCode);
									}
									formSB.append("</p>");
								}
							}
						}
						if (i != array.size() - 1){
							formSB.append("<p>&nbsp;&nbsp;</p>");
						}
					}

				}else{
					formSB.append(value);
				}
				formSB.append("</td></tr>");
			}
		}
		return formSB;
	}


	// 获取报销明细
	private String formComponentValuesByTableField(JSONArray formArray){
		for (Object o : formArray) {
			JSONObject parseObject = JSONObject.parseObject(o.toString());
			if (!"TableField".equals(parseObject.getString("componentType"))){
				continue;
			}

			JSONArray value = parseObject.getJSONArray("value");

		}

		return null;
	}

	private JSONObject getHasPay(JSONArray formArray) {
		String subValue = "0";
		boolean hasAdd = false;

		for (Object o : formArray) {
			JSONObject parentJson = JSONObject.parseObject(o.toString());
			if ("DDBizSuite".equals(parentJson.getString("component_type"))){
				String valueStr = parentJson.getString("value");
				JSONArray subArray = JSONArray.parseArray(valueStr);
				for (Object sub : subArray) {
					JSONObject subJson = JSONObject.parseObject(sub.toString());
					if ("MoneyField".equals(subJson.getString("componentType"))){
						 subValue = subJson.getString("value");
						logger.info("付款金额：{}", subValue);
						hasAdd = true;
					}
				}

			}

		}

		JSONObject res = new JSONObject();
		res.put("component_type", "MoneyField");
		res.put("id", null);
		res.put("name", "付款金额");
		res.put("value", subValue);
		res.put("hasAdd", hasAdd);
		logger.info("返回结果：{}", res);

		return res;

	}

	private String getDetailHtml(String accessToken, JSONObject jsonResult, String type) {
		StringBuffer sb = new StringBuffer();
		JSONObject result = jsonResult.getJSONObject("process_instance");
		if (result != null){
			
			DataDictionary corp = dataDictionaryService.findByCodeAndDataKey("corp_code", dingdingUtil.getRegion());
			
			//企业名称
			String corpName = corp.getDataValue();
			//申请日期
			String applyDate = result.getString("create_time");
			//审批编码
			String businessId = result.getString("business_id");
			String[] titles = result.getString("title").split("的");
			//申请人
			String applyUserName = titles[0];
			//模板名称
			String title = titles[1];
			//申请人部门
			String org = result.getString("originator_dept_name");
			
			sb.append("<!DOCTYPE html> ")		
			.append("<html lang=\"en\">").append("<head>")
			.append("<meta charset=\"UTF-8\" />")
			.append("<style> ").append("body{font-family:SimHei;} .content{width: 100%; margin: 0 auto; margin-top: 30px;} h2{text-align:center;} .mgrl-10{margin-left:30px;} table tr{height: 30px;} table td {word-wrap:break-word;word-break:break-all;}").append("</style>")
			.append("</head>").append("<body>") 
			.append("<div class=\"content\">")
			.append("<h2>").append(title).append("</h2>")
			.append("<span>").append(corpName).append("</span>").append("            ").append("<span class=\"mgrl-10\">申请日期：").append(applyDate).append("</span>")
			.append("            ").append("<span class=\"mgrl-10\" style=\"color: red;\">审批状态：").append(dingdingUtil.getStatus(result.getString("status"))).append("</span>")
			.append("<table border=\"1\" cellspacing=\"0\" width=100% >")
			.append("<tr><td style=\"width:20%\">审批编码</td><td>").append(businessId).append("</td></tr>")
			.append("<tr><td>申请人</td><td>").append(applyUserName).append("</td></tr>")
			.append("<tr><td>申请人部门</td><td>").append(org).append("</td></tr>");
			
			//表单内容，循环生成表单内容
			StringBuffer formSB = generateForm_1(result);
			sb.append(formSB);
			
			//审批人
			StringBuffer userSB = generateOperators_1(accessToken, result);
			sb.append(userSB).append("</table>");
			
			if ("download".equals(type)){
				Subject subject = SecurityUtils.getSubject();
	            Object principal = subject.getPrincipal();
	            String userName = "";
	            if (principal != null) {
	            	userName = ((User) principal).getNickName();
	            }
				sb.append("<span>打印时间：").append(new DateTime().toString("yyyy-MM-dd HH:mm")).append("</span>            <span class=\"mgrl-10\">打印人：").append(userName).append("</span></div>");
			}
			sb.append("</body></html>");  
		}
		return sb.toString();
	}

}
