diff --git a/src/main/java/com/supwisdom/dlpay/framework/util/XmlUtils.java b/src/main/java/com/supwisdom/dlpay/framework/util/XmlUtils.java
index 38695bc..66deb65 100644
--- a/src/main/java/com/supwisdom/dlpay/framework/util/XmlUtils.java
+++ b/src/main/java/com/supwisdom/dlpay/framework/util/XmlUtils.java
@@ -7,91 +7,95 @@
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.JAXBException;
 import javax.xml.bind.Marshaller;
-import javax.xml.bind.Unmarshaller;
-import java.io.*;
-import java.util.*;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 public class XmlUtils {
-	public static <T> String getObjectToXml(T object) throws IOException {
-		ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
-		
-		try {
-			JAXBContext context = JAXBContext.newInstance(object.getClass());
-			// 将对象转变为xml Object------XML
-			// 指定对应的xml文件
-			Marshaller marshaller = context.createMarshaller();
-			marshaller.setProperty(Marshaller.JAXB_ENCODING,"gbk");//编码格式 
-			marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, false);// 是否格式化生成的xml串
-			marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);// 是否省略xml头信息
+  public static <T> String getObjectToXml(T object) throws IOException {
+    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
 
-			// 将对象转换为对应的XML文件
-			marshaller.marshal(object, byteArrayOutputStream);
-		} catch (JAXBException e) {
+    try {
+      JAXBContext context = JAXBContext.newInstance(object.getClass());
+      // 将对象转变为xml Object------XML
+      // 指定对应的xml文件
+      Marshaller marshaller = context.createMarshaller();
+      marshaller.setProperty(Marshaller.JAXB_ENCODING, "gbk");//编码格式 
+      marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, false);// 是否格式化生成的xml串
+      marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);// 是否省略xml头信息
 
-			e.printStackTrace();
-		}
-		// 转化为字符串返回
-		String xmlContent = new String(byteArrayOutputStream.toByteArray(),
-				"gbk");
-		return xmlContent;
-	}
+      // 将对象转换为对应的XML文件
+      marshaller.marshal(object, byteArrayOutputStream);
+    } catch (JAXBException e) {
 
-	public static <T> T getXmlToObject(String xmlContent, Class clazz) {
-		try {
-			JAXBContext context = JAXBContext.newInstance(clazz);
-			// xml转换为对象 XML------Object
-			InputStream inputStream;
-			try {
-				inputStream = new ByteArrayInputStream(
-						xmlContent.getBytes("GBK"));
-				Unmarshaller um = context.createUnmarshaller();
+      e.printStackTrace();
+    }
+    // 转化为字符串返回
+    String xmlContent = new String(byteArrayOutputStream.toByteArray(),
+        "gbk");
+    return xmlContent;
+  }
 
-				return (T) um.unmarshal(inputStream);
-			} catch (UnsupportedEncodingException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			}catch (Exception e) {
-				e.printStackTrace();
-			}
-		} catch (JAXBException e) {
+  /*
+    public static <T> T getXmlToObject(String xmlContent, Class clazz) {
+      try {
+        JAXBContext context = JAXBContext.newInstance(clazz);
+        // xml转换为对象 XML------Object
+        InputStream inputStream;
+        try {
+          inputStream = new ByteArrayInputStream(
+              xmlContent.getBytes("GBK"));
+          Unmarshaller um = context.createUnmarshaller();
 
-			e.printStackTrace();
-		}
-		return null;
-	}
-	
-	public static <T> T getXmlToObject(String xmlContent,String charset, Class clazz) {
-		try {
-			JAXBContext context = JAXBContext.newInstance(clazz);
-			// xml转换为对象 XML------Object
-			InputStream inputStream;
-			try {
-				inputStream = new ByteArrayInputStream(
-						xmlContent.getBytes(charset));
-				Unmarshaller um = context.createUnmarshaller();
+          @Suppress("UNCHECKED_CAST")
+          return (T) um.unmarshal(inputStream);
+        } catch (UnsupportedEncodingException e) {
+          // TODO Auto-generated catch block
+          e.printStackTrace();
+        }catch (Exception e) {
+          e.printStackTrace();
+        }
+      } catch (JAXBException e) {
 
-				return (T) um.unmarshal(inputStream);
-			} catch (UnsupportedEncodingException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			}catch (Exception e) {
-				e.printStackTrace();
-			}
-		} catch (JAXBException e) {
+        e.printStackTrace();
+      }
+      return null;
+    }
 
-			e.printStackTrace();
-		}
-		return null;
-	}
+    public static <T> T getXmlToObject(String xmlContent,String charset, Class clazz) {
+      try {
+        JAXBContext context = JAXBContext.newInstance(clazz);
+        // xml转换为对象 XML------Object
+        InputStream inputStream;
+        try {
+          inputStream = new ByteArrayInputStream(
+              xmlContent.getBytes(charset));
+          Unmarshaller um = context.createUnmarshaller();
 
-	public static Map<String, String> parseXml(String xml) throws Exception {
-		Map<String, String> map = new HashMap<String, String>();
-		Document document = DocumentHelper.parseText(xml);
-		Element root = document.getRootElement();
-		List<Element> elementList = root.elements();
-		for (Element e : elementList)
-			map.put(e.getName(), e.getText());
-		return map;
-	}
+          return (T) um.unmarshal(inputStream);
+        } catch (UnsupportedEncodingException e) {
+          // TODO Auto-generated catch block
+          e.printStackTrace();
+        }catch (Exception e) {
+          e.printStackTrace();
+        }
+      } catch (JAXBException e) {
+
+        e.printStackTrace();
+      }
+      return null;
+    }
+  */
+  public static Map<String, String> parseXml(String xml) throws Exception {
+    Map<String, String> map = new HashMap<String, String>();
+    Document document = DocumentHelper.parseText(xml);
+    Element root = document.getRootElement();
+    List<Element> elementList = root.elements();
+    for (Element e : elementList)
+      map.put(e.getName(), e.getText());
+    return map;
+  }
 
 }
diff --git a/src/main/java/com/supwisdom/dlpay/system/service/impl/FunctionServiceImpl.java b/src/main/java/com/supwisdom/dlpay/system/service/impl/FunctionServiceImpl.java
index cab0d50..5a764a5 100644
--- a/src/main/java/com/supwisdom/dlpay/system/service/impl/FunctionServiceImpl.java
+++ b/src/main/java/com/supwisdom/dlpay/system/service/impl/FunctionServiceImpl.java
@@ -23,119 +23,119 @@
 
 @Service
 public class FunctionServiceImpl implements FunctionService {
-    @Autowired
-    private FunctionDao functionDao;
-    @Autowired
-    private ResourceDao resourceDao;
-    @Autowired
-    private RoleFunctionDao roleFunctionDao;
+  @Autowired
+  private FunctionDao functionDao;
+  @Autowired
+  private ResourceDao resourceDao;
+  @Autowired
+  private RoleFunctionDao roleFunctionDao;
 
-    @Override
-    public List<TFunction> getFunctionsByOperid(String operid) {
-        List<TFunction> list = functionDao.getTFunctionsByOperid(StringUtil.isEmpty(operid) ? "" : operid.trim());
-        if (!StringUtil.isEmpty(list)) return list;
-        return new ArrayList(0);
-    }
+  @Override
+  public List<TFunction> getFunctionsByOperid(String operid) {
+    List<TFunction> list = functionDao.getTFunctionsByOperid(StringUtil.isEmpty(operid) ? "" : operid.trim());
+    if (!StringUtil.isEmpty(list)) return list;
+    return new ArrayList<>(0);
+  }
 
-    @Override
-    public List<Map<String, Object>> getMenuTree(List<TFunction> funcList, Integer parentId) {
-        List<Map<String, Object>> list = new ArrayList<>(0);
-        for (TFunction func : funcList) {
-            if (parentId.equals(func.getParentId())) {
-                Map<String, Object> map = new HashMap<>(0);
-                map.put("menuName", func.getName());
-                map.put("menuIcon", func.getMenuIcon());
-                if ("#".equals(func.getMenuUrl())) {
-                    map.put("menuUrl", "javascript:;");
-                } else {
-                    map.put("menuUrl", func.getMenuUrl());
-                }
-                map.put("subMenus", getMenuTree(funcList, func.getId()));
-                list.add(map);
-            }
-        }
-        return list;
-    }
-
-    @Override
-    public PageResult<TFunction> getFunctionsByKey(FunctionSearchBean param) {
-        Pageable pageable = PageRequest.of(param.getPageNo() - 1, param.getPageSize()
-                , Sort.by("id"));
-        if (!StringUtil.isEmpty(param.getFunctioname())) {
-            return new PageResult<>(functionDao.findAllByNameContaining(param.getFunctioname(), pageable));
-        }
-        return new PageResult<>(functionDao.findAll(pageable));
-    }
-
-    @Override
-    public TFunction getFunctionByNameAndId(String name, Integer id) {
-        if (id != null && id != 0) {
-            return functionDao.findByNameAndIdNot(name, id);
-        }
-        return functionDao.findByName(name);
-    }
-
-    @Override
-    public JsonResult saveFunction(TFunction function) {
-        TFunction temp = getFunctionByNameAndId(function.getName(), function.getId());
-        if (temp != null) {
-            return JsonResult.error("功能名称重复");
-        }
-        if (function.getParentId() == null) {
-            function.setParentId(-1);
-        }
-        functionDao.save(function);
-        return JsonResult.ok("成功");
-    }
-
-    @Override
-    public TFunction getFunctionById(Integer id) {
-        return functionDao.getOne(id);
-    }
-
-    @Override
-    public List<TFunction> getParentFunction() {
-        return functionDao.findByIsLeaf(0);
-    }
-
-    @Override
-    public List<TResource> getResources(Integer function) {
-        return resourceDao.findByFunctionId(function);
-    }
-
-    @Override
-    public List<TFunction> getLeafFunction() {
-        return functionDao.findByIsLeaf(1);
-    }
-
-    @Override
-    public JsonResult saveRes(TResource resource) {
-        if (resource.getId() != null && resource.getId() != 0) {
-            TResource temp = resourceDao.findByUriAndIdNot(resource.getUri(), resource.getId());
-            if (temp != null) {
-                return JsonResult.error("资源路径已存在");
-            }
+  @Override
+  public List<Map<String, Object>> getMenuTree(List<TFunction> funcList, Integer parentId) {
+    List<Map<String, Object>> list = new ArrayList<>(0);
+    for (TFunction func : funcList) {
+      if (parentId.equals(func.getParentId())) {
+        Map<String, Object> map = new HashMap<>(0);
+        map.put("menuName", func.getName());
+        map.put("menuIcon", func.getMenuIcon());
+        if ("#".equals(func.getMenuUrl())) {
+          map.put("menuUrl", "javascript:;");
         } else {
-            TResource temp = resourceDao.findByUri(resource.getUri());
-            if (temp != null) {
-                return JsonResult.error("资源路径已存在");
-            }
+          map.put("menuUrl", func.getMenuUrl());
         }
-        resourceDao.save(resource);
-        return JsonResult.ok("成功");
+        map.put("subMenus", getMenuTree(funcList, func.getId()));
+        list.add(map);
+      }
     }
+    return list;
+  }
 
-    @Override
-    public JsonResult deleteResource(Integer resid) {
-        resourceDao.deleteById(resid);
-        return JsonResult.ok("成功");
+  @Override
+  public PageResult<TFunction> getFunctionsByKey(FunctionSearchBean param) {
+    Pageable pageable = PageRequest.of(param.getPageNo() - 1, param.getPageSize()
+        , Sort.by("id"));
+    if (!StringUtil.isEmpty(param.getFunctioname())) {
+      return new PageResult<>(functionDao.findAllByNameContaining(param.getFunctioname(), pageable));
     }
+    return new PageResult<>(functionDao.findAll(pageable));
+  }
 
-    @Override
-    public JsonResult deleteFunction(Integer funcid) {
-        resourceDao.deleteByFunctionId(funcid);
-        roleFunctionDao.deleteByFunctionId(funcid);
-        functionDao.deleteById(funcid);
-        return JsonResult.ok("成功");
+  @Override
+  public TFunction getFunctionByNameAndId(String name, Integer id) {
+    if (id != null && id != 0) {
+      return functionDao.findByNameAndIdNot(name, id);
     }
+    return functionDao.findByName(name);
+  }
+
+  @Override
+  public JsonResult saveFunction(TFunction function) {
+    TFunction temp = getFunctionByNameAndId(function.getName(), function.getId());
+    if (temp != null) {
+      return JsonResult.error("功能名称重复");
+    }
+    if (function.getParentId() == null) {
+      function.setParentId(-1);
+    }
+    functionDao.save(function);
+    return JsonResult.ok("成功");
+  }
+
+  @Override
+  public TFunction getFunctionById(Integer id) {
+    return functionDao.getOne(id);
+  }
+
+  @Override
+  public List<TFunction> getParentFunction() {
+    return functionDao.findByIsLeaf(0);
+  }
+
+  @Override
+  public List<TResource> getResources(Integer function) {
+    return resourceDao.findByFunctionId(function);
+  }
+
+  @Override
+  public List<TFunction> getLeafFunction() {
+    return functionDao.findByIsLeaf(1);
+  }
+
+  @Override
+  public JsonResult saveRes(TResource resource) {
+    if (resource.getId() != null && resource.getId() != 0) {
+      TResource temp = resourceDao.findByUriAndIdNot(resource.getUri(), resource.getId());
+      if (temp != null) {
+        return JsonResult.error("资源路径已存在");
+      }
+    } else {
+      TResource temp = resourceDao.findByUri(resource.getUri());
+      if (temp != null) {
+        return JsonResult.error("资源路径已存在");
+      }
+    }
+    resourceDao.save(resource);
+    return JsonResult.ok("成功");
+  }
+
+  @Override
+  public JsonResult deleteResource(Integer resid) {
+    resourceDao.deleteById(resid);
+    return JsonResult.ok("成功");
+  }
+
+  @Override
+  public JsonResult deleteFunction(Integer funcid) {
+    resourceDao.deleteByFunctionId(funcid);
+    roleFunctionDao.deleteByFunctionId(funcid);
+    functionDao.deleteById(funcid);
+    return JsonResult.ok("成功");
+  }
 }
