Browse Source

Merge branch 'wrdp' into 'release'

Wrdp

See merge request o2oa/o2oa!2299
胡起 5 years ago
parent
commit
3180056fe3

+ 200 - 196
o2server/x_organization_assemble_control/src/main/java/com/x/organization/assemble/control/jaxrs/personcard/CodeUtil.java

@@ -12,7 +12,8 @@ import java.util.Map;
 import java.util.Objects;
 
 import javax.imageio.ImageIO;
-import sun.misc.BASE64Decoder;
+
+import org.apache.commons.codec.binary.Base64;
 import org.apache.commons.lang3.StringUtils;
 
 import com.google.zxing.BarcodeFormat;
@@ -20,200 +21,203 @@ import com.google.zxing.EncodeHintType;
 import com.google.zxing.MultiFormatWriter;
 import com.google.zxing.common.BitMatrix;
 
-
 public class CodeUtil {
-	 private static final int QRCOLOR = 0xFF000000; // 默认是黑色
-	 private static final int BGWHITE = 0xFFFFFFFF; // 背景颜色	 
-	 private static final int WIDTH = 300; // 二维码宽
-	 private static final int HEIGHT = 300; // 二维码高
-	 
-	 /**
-	     *生成带logo的二维码图片
-	     * @param logoFile /logo图片文件
-	     * @param codeFile /二维码图片
-	     * @param qrUrl /二维码存储的信息:vcard格式
-	     * @param note /二维码描述信息
-	     */
-	    public static void drawLogoQRCode(File logoFile, File codeFile, String qrUrl, String note) {
-	        try {
-	            MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
-	            // 参数顺序分别为:编码内容,编码类型,生成图片宽度,生成图片高度,设置参数
-	            BitMatrix bm = multiFormatWriter.encode(qrUrl, BarcodeFormat.QR_CODE, WIDTH, HEIGHT, hints);
-	            BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
-
-	            // 开始利用二维码数据创建Bitmap图片,分别设为黑(0xFFFFFFFF)白(0xFF000000)两色
-	            for (int x = 0; x < WIDTH; x++) {
-	                for (int y = 0; y < HEIGHT; y++) {
-	                    image.setRGB(x, y, bm.get(x, y) ? QRCOLOR : BGWHITE);
-	                }
-	            }
-
-	            int width = image.getWidth();
-	            int height = image.getHeight();
-	            if (Objects.nonNull(logoFile) && logoFile.exists()) {
-	                // 构建绘图对象
-	                Graphics2D g = image.createGraphics();
-	                // 读取Logo图片
-	                BufferedImage logo = ImageIO.read(logoFile);
-	                // 开始绘制logo图片
-	                g.drawImage(logo, width * 2 / 5, height * 2 / 5, width * 2 / 10, height * 2 / 10, null);
-	                g.dispose();
-	                logo.flush();
-	            }
-
-	            // 自定义文本描述
-	            if (StringUtils.isNotEmpty(note)) {
-	                // 新的图片,把带logo的二维码下面加上文字
-	                BufferedImage outImage = new BufferedImage(400, 445, BufferedImage.TYPE_4BYTE_ABGR);
-	                Graphics2D outg = outImage.createGraphics();
-	                // 画二维码到新的面板
-	                outg.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), null);
-	                // 画文字到新的面板
-	                outg.setColor(Color.BLACK);
-	                outg.setFont(new Font("楷体", Font.BOLD, 30)); // 字体、字型、字号
-	                int strWidth = outg.getFontMetrics().stringWidth(note);
-	                if (strWidth > WIDTH) {
-	                    // //长度过长就截取前面部分
-	                    // 长度过长就换行
-	                    String note1 = note.substring(0, note.length() / 2);
-	                    String note2 = note.substring(note.length() / 2, note.length());
-	                    int strWidth1 = outg.getFontMetrics().stringWidth(note1);
-	                    int strWidth2 = outg.getFontMetrics().stringWidth(note2);
-	                    outg.drawString(note1, 200 - strWidth1 / 2, height + (outImage.getHeight() - height) / 2 + 12);
-	                    BufferedImage outImage2 = new BufferedImage(400, 485, BufferedImage.TYPE_4BYTE_ABGR);
-	                    Graphics2D outg2 = outImage2.createGraphics();
-	                    outg2.drawImage(outImage, 0, 0, outImage.getWidth(), outImage.getHeight(), null);
-	                    outg2.setColor(Color.BLACK);
-	                    outg2.setFont(new Font("宋体", Font.BOLD, 30)); // 字体、字型、字号
-	                    outg2.drawString(note2, 200 - strWidth2 / 2,outImage.getHeight() + (outImage2.getHeight() - outImage.getHeight()) / 2 + 5);
-	                    outg2.dispose();
-	                    outImage2.flush();
-	                    outImage = outImage2;
-	                } else {
-	                    outg.drawString(note, 200 - strWidth / 2, height + (outImage.getHeight() - height) / 2 + 12); // 画文字
-	                }
-	                outg.dispose();
-	                outImage.flush();
-	                image = outImage;
-	            }
-
-	            image.flush();
-
-	            ImageIO.write(image, "png", codeFile); // TODO
-	            if (Objects.nonNull(logoFile) && logoFile.exists()) {
-	            	logoFile.delete();
-	            }
-	        } catch (Exception e) {
-	            e.printStackTrace();
-	        }
-	    }
-	    
-	    /**
-	     *生成带logo的二维码图片
-	     * @param logoFile /logo图片文件
-	     * @param codeFile /二维码图片
-	     * @param qrUrl /二维码存储的信息:vcard格式
-	     * @param note /二维码描述信息
-	     */
-	    public static byte[] drawLogoQRCodeByte(BufferedImage logo, ByteArrayOutputStream codeFile, String qrUrl, String note) {
-	    	byte[] bs = null;
-	        try {
-	            MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
-	            // 参数顺序分别为:编码内容,编码类型,生成图片宽度,生成图片高度,设置参数
-	            BitMatrix bm = multiFormatWriter.encode(qrUrl, BarcodeFormat.QR_CODE, WIDTH, HEIGHT, hints);
-	            BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
-
-	            // 开始利用二维码数据创建Bitmap图片,分别设为黑(0xFFFFFFFF)白(0xFF000000)两色
-	            for (int x = 0; x < WIDTH; x++) {
-	                for (int y = 0; y < HEIGHT; y++) {
-	                    image.setRGB(x, y, bm.get(x, y) ? QRCOLOR : BGWHITE);
-	                }
-	            }
-
-	            int width = image.getWidth();
-	            int height = image.getHeight();
-	            if (Objects.nonNull(logo)) {
-	                // 构建绘图对象
-	                Graphics2D g = image.createGraphics();
-	                // 读取Logo图片
-	                //BufferedImage logo = ImageIO.read(logoFile);
-	                // 开始绘制logo图片
-	                g.drawImage(logo, width * 2 / 5, height * 2 / 5, width * 2 / 10, height * 2 / 10, null);
-	                g.dispose();
-	                logo.flush();
-	            }
-
-	            // 自定义文本描述
-	            if (StringUtils.isNotEmpty(note)) {
-	                // 新的图片,把带logo的二维码下面加上文字
-	                BufferedImage outImage = new BufferedImage(400, 445, BufferedImage.TYPE_4BYTE_ABGR);
-	                Graphics2D outg = outImage.createGraphics();
-	                // 画二维码到新的面板
-	                outg.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), null);
-	                // 画文字到新的面板
-	                outg.setColor(Color.BLACK);
-	                outg.setFont(new Font("楷体", Font.BOLD, 30)); // 字体、字型、字号
-	                int strWidth = outg.getFontMetrics().stringWidth(note);
-	                if (strWidth > WIDTH) {
-	                    // //长度过长就截取前面部分
-	                    // 长度过长就换行
-	                    String note1 = note.substring(0, note.length() / 2);
-	                    String note2 = note.substring(note.length() / 2, note.length());
-	                    int strWidth1 = outg.getFontMetrics().stringWidth(note1);
-	                    int strWidth2 = outg.getFontMetrics().stringWidth(note2);
-	                    outg.drawString(note1, 200 - strWidth1 / 2, height + (outImage.getHeight() - height) / 2 + 12);
-	                    BufferedImage outImage2 = new BufferedImage(400, 485, BufferedImage.TYPE_4BYTE_ABGR);
-	                    Graphics2D outg2 = outImage2.createGraphics();
-	                    outg2.drawImage(outImage, 0, 0, outImage.getWidth(), outImage.getHeight(), null);
-	                    outg2.setColor(Color.BLACK);
-	                    outg2.setFont(new Font("宋体", Font.BOLD, 30)); // 字体、字型、字号
-	                    outg2.drawString(note2, 200 - strWidth2 / 2,outImage.getHeight() + (outImage2.getHeight() - outImage.getHeight()) / 2 + 5);
-	                    outg2.dispose();
-	                    outImage2.flush();
-	                    outImage = outImage2;
-	                } else {
-	                    outg.drawString(note, 200 - strWidth / 2, height + (outImage.getHeight() - height) / 2 + 12); // 画文字
-	                }
-	                outg.dispose();
-	                outImage.flush();
-	                image = outImage;
-	            }
-
-	            image.flush();
-
-	            ImageIO.write(image, "png", codeFile); // TODO
-	            bs = codeFile.toByteArray();
-	        } catch (Exception e) {
-	            e.printStackTrace();
-	        }
-	        return bs;
-	    }
-	    
-	    // 用于设置QR二维码参数
-	    private static Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>() {
-	        private static final long serialVersionUID = 1L;
-	        {
-	            //put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);// 设置QR二维码的纠错级别(H为最高级别)具体级别信息
-	            put(EncodeHintType.CHARACTER_SET, "utf-8");// 设置编码方式
-	            put(EncodeHintType.MARGIN, 1);
-	        }
-	    };
-	    
-	    /**
-	     * 将base64字符解码保存文件
-	     *
-	     * @param base64Code
-	     * @param targetPath
-	     * @throws Exception
-	     */
-	    public static File decoderBase64File(String targetPath, String base64Code) throws Exception {
-	    	System.out.println("base64Code="+base64Code);
-	    	System.out.println("targetPath="+targetPath);
-		    byte[] buffer = new BASE64Decoder().decodeBuffer(base64Code);  
-		    FileOutputStream out = new FileOutputStream(targetPath);  
-		    out.write(buffer);  
-		    out.close();  
-		    File file = new File(targetPath);
-		    return file;
-	    }
+	private static final int QRCOLOR = 0xFF000000; // 默认是黑色
+	private static final int BGWHITE = 0xFFFFFFFF; // 背景颜色
+	private static final int WIDTH = 300; // 二维码宽
+	private static final int HEIGHT = 300; // 二维码高
+
+	/**
+	 * 生成带logo的二维码图片
+	 * 
+	 * @param logoFile /logo图片文件
+	 * @param codeFile /二维码图片
+	 * @param qrUrl    /二维码存储的信息:vcard格式
+	 * @param note     /二维码描述信息
+	 */
+	public static void drawLogoQRCode(File logoFile, File codeFile, String qrUrl, String note) {
+		try {
+			MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
+			// 参数顺序分别为:编码内容,编码类型,生成图片宽度,生成图片高度,设置参数
+			BitMatrix bm = multiFormatWriter.encode(qrUrl, BarcodeFormat.QR_CODE, WIDTH, HEIGHT, hints);
+			BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
+
+			// 开始利用二维码数据创建Bitmap图片,分别设为黑(0xFFFFFFFF)白(0xFF000000)两色
+			for (int x = 0; x < WIDTH; x++) {
+				for (int y = 0; y < HEIGHT; y++) {
+					image.setRGB(x, y, bm.get(x, y) ? QRCOLOR : BGWHITE);
+				}
+			}
+
+			int width = image.getWidth();
+			int height = image.getHeight();
+			if (Objects.nonNull(logoFile) && logoFile.exists()) {
+				// 构建绘图对象
+				Graphics2D g = image.createGraphics();
+				// 读取Logo图片
+				BufferedImage logo = ImageIO.read(logoFile);
+				// 开始绘制logo图片
+				g.drawImage(logo, width * 2 / 5, height * 2 / 5, width * 2 / 10, height * 2 / 10, null);
+				g.dispose();
+				logo.flush();
+			}
+
+			// 自定义文本描述
+			if (StringUtils.isNotEmpty(note)) {
+				// 新的图片,把带logo的二维码下面加上文字
+				BufferedImage outImage = new BufferedImage(400, 445, BufferedImage.TYPE_4BYTE_ABGR);
+				Graphics2D outg = outImage.createGraphics();
+				// 画二维码到新的面板
+				outg.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), null);
+				// 画文字到新的面板
+				outg.setColor(Color.BLACK);
+				outg.setFont(new Font("楷体", Font.BOLD, 30)); // 字体、字型、字号
+				int strWidth = outg.getFontMetrics().stringWidth(note);
+				if (strWidth > WIDTH) {
+					// //长度过长就截取前面部分
+					// 长度过长就换行
+					String note1 = note.substring(0, note.length() / 2);
+					String note2 = note.substring(note.length() / 2, note.length());
+					int strWidth1 = outg.getFontMetrics().stringWidth(note1);
+					int strWidth2 = outg.getFontMetrics().stringWidth(note2);
+					outg.drawString(note1, 200 - strWidth1 / 2, height + (outImage.getHeight() - height) / 2 + 12);
+					BufferedImage outImage2 = new BufferedImage(400, 485, BufferedImage.TYPE_4BYTE_ABGR);
+					Graphics2D outg2 = outImage2.createGraphics();
+					outg2.drawImage(outImage, 0, 0, outImage.getWidth(), outImage.getHeight(), null);
+					outg2.setColor(Color.BLACK);
+					outg2.setFont(new Font("宋体", Font.BOLD, 30)); // 字体、字型、字号
+					outg2.drawString(note2, 200 - strWidth2 / 2,
+							outImage.getHeight() + (outImage2.getHeight() - outImage.getHeight()) / 2 + 5);
+					outg2.dispose();
+					outImage2.flush();
+					outImage = outImage2;
+				} else {
+					outg.drawString(note, 200 - strWidth / 2, height + (outImage.getHeight() - height) / 2 + 12); // 画文字
+				}
+				outg.dispose();
+				outImage.flush();
+				image = outImage;
+			}
+
+			image.flush();
+
+			ImageIO.write(image, "png", codeFile); // TODO
+			if (Objects.nonNull(logoFile) && logoFile.exists()) {
+				logoFile.delete();
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+
+	/**
+	 * 生成带logo的二维码图片
+	 * 
+	 * @param logoFile /logo图片文件
+	 * @param codeFile /二维码图片
+	 * @param qrUrl    /二维码存储的信息:vcard格式
+	 * @param note     /二维码描述信息
+	 */
+	public static byte[] drawLogoQRCodeByte(BufferedImage logo, ByteArrayOutputStream codeFile, String qrUrl,
+			String note) {
+		byte[] bs = null;
+		try {
+			MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
+			// 参数顺序分别为:编码内容,编码类型,生成图片宽度,生成图片高度,设置参数
+			BitMatrix bm = multiFormatWriter.encode(qrUrl, BarcodeFormat.QR_CODE, WIDTH, HEIGHT, hints);
+			BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
+
+			// 开始利用二维码数据创建Bitmap图片,分别设为黑(0xFFFFFFFF)白(0xFF000000)两色
+			for (int x = 0; x < WIDTH; x++) {
+				for (int y = 0; y < HEIGHT; y++) {
+					image.setRGB(x, y, bm.get(x, y) ? QRCOLOR : BGWHITE);
+				}
+			}
+
+			int width = image.getWidth();
+			int height = image.getHeight();
+			if (Objects.nonNull(logo)) {
+				// 构建绘图对象
+				Graphics2D g = image.createGraphics();
+				// 读取Logo图片
+				// BufferedImage logo = ImageIO.read(logoFile);
+				// 开始绘制logo图片
+				g.drawImage(logo, width * 2 / 5, height * 2 / 5, width * 2 / 10, height * 2 / 10, null);
+				g.dispose();
+				logo.flush();
+			}
+
+			// 自定义文本描述
+			if (StringUtils.isNotEmpty(note)) {
+				// 新的图片,把带logo的二维码下面加上文字
+				BufferedImage outImage = new BufferedImage(400, 445, BufferedImage.TYPE_4BYTE_ABGR);
+				Graphics2D outg = outImage.createGraphics();
+				// 画二维码到新的面板
+				outg.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), null);
+				// 画文字到新的面板
+				outg.setColor(Color.BLACK);
+				outg.setFont(new Font("楷体", Font.BOLD, 30)); // 字体、字型、字号
+				int strWidth = outg.getFontMetrics().stringWidth(note);
+				if (strWidth > WIDTH) {
+					// //长度过长就截取前面部分
+					// 长度过长就换行
+					String note1 = note.substring(0, note.length() / 2);
+					String note2 = note.substring(note.length() / 2, note.length());
+					int strWidth1 = outg.getFontMetrics().stringWidth(note1);
+					int strWidth2 = outg.getFontMetrics().stringWidth(note2);
+					outg.drawString(note1, 200 - strWidth1 / 2, height + (outImage.getHeight() - height) / 2 + 12);
+					BufferedImage outImage2 = new BufferedImage(400, 485, BufferedImage.TYPE_4BYTE_ABGR);
+					Graphics2D outg2 = outImage2.createGraphics();
+					outg2.drawImage(outImage, 0, 0, outImage.getWidth(), outImage.getHeight(), null);
+					outg2.setColor(Color.BLACK);
+					outg2.setFont(new Font("宋体", Font.BOLD, 30)); // 字体、字型、字号
+					outg2.drawString(note2, 200 - strWidth2 / 2,
+							outImage.getHeight() + (outImage2.getHeight() - outImage.getHeight()) / 2 + 5);
+					outg2.dispose();
+					outImage2.flush();
+					outImage = outImage2;
+				} else {
+					outg.drawString(note, 200 - strWidth / 2, height + (outImage.getHeight() - height) / 2 + 12); // 画文字
+				}
+				outg.dispose();
+				outImage.flush();
+				image = outImage;
+			}
+
+			image.flush();
+
+			ImageIO.write(image, "png", codeFile); // TODO
+			bs = codeFile.toByteArray();
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		return bs;
+	}
+
+	// 用于设置QR二维码参数
+	private static Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>() {
+		private static final long serialVersionUID = 1L;
+		{
+			// put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);//
+			// 设置QR二维码的纠错级别(H为最高级别)具体级别信息
+			put(EncodeHintType.CHARACTER_SET, "utf-8");// 设置编码方式
+			put(EncodeHintType.MARGIN, 1);
+		}
+	};
+
+	/**
+	 * 将base64字符解码保存文件
+	 *
+	 * @param base64Code
+	 * @param targetPath
+	 * @throws Exception
+	 */
+	public static File decoderBase64File(String targetPath, String base64Code) throws Exception {
+		byte[] buffer = Base64.decodeBase64(base64Code);
+		try (FileOutputStream out = new FileOutputStream(targetPath)) {
+			out.write(buffer);
+		}
+		File file = new File(targetPath);
+		return file;
+	}
 }

+ 3 - 1
o2server/x_organization_assemble_express/src/main/java/com/x/organization/assemble/express/jaxrs/unit/ActionListWithIdentityObject.java

@@ -79,7 +79,9 @@ class ActionListWithIdentityObject extends BaseAction {
 		List<String> unitIds = em.createQuery(cq.select(root.get(Identity_.unit)).where(p))
 				.getResultList().stream().distinct().collect(Collectors.toList());
 		unitIds = ListTools.trim(unitIds, true, true);
-		for (Unit o : business.unit().pick(unitIds)) {
+		List<Unit> units = business.unit().pick(unitIds);
+		units = business.unit().sort(units);
+		for (Unit o : units) {
 			wos.add(this.convert(business, o, Wo.class));
 		}
 		return wos;

+ 3 - 1
o2server/x_organization_assemble_express/src/main/java/com/x/organization/assemble/express/jaxrs/unit/ActionListWithIdentitySupNestedObject.java

@@ -83,7 +83,9 @@ class ActionListWithIdentitySupNestedObject extends BaseAction {
 			unitIds.addAll(business.unit().listSupNested(str));
 		}
 		unitIds = ListTools.trim(unitIds, true, true);
-		for (Unit o : business.unit().pick(unitIds)) {
+		List<Unit> units = business.unit().pick(unitIds);
+		units = business.unit().sort(units);
+		for (Unit o : units) {
 			wos.add(this.convert(business, o, Wo.class));
 		}
 		return wos;

+ 4 - 4
o2server/x_organization_assemble_express/src/main/java/com/x/organization/assemble/express/jaxrs/unit/ActionListWithLevelObject.java

@@ -72,10 +72,10 @@ class ActionListWithLevelObject extends BaseAction {
 		CriteriaQuery<String> cq = cb.createQuery(String.class);
 		Root<Unit> root = cq.from(Unit.class);
 		Predicate p = root.get(Unit_.level).in(wi.getLevelList());
-		List<String> unitIds = em.createQuery(cq.select(root.get(Unit_.id)).where(p))
-				.getResultList().stream().distinct().collect(Collectors.toList());
-		unitIds = ListTools.trim(unitIds, true, true);
-		for (Unit o : business.unit().pick(unitIds)) {
+		List<String> unitIds = em.createQuery(cq.select(root.get(Unit_.id)).where(p)).getResultList();
+		List<Unit> units = business.unit().pick(unitIds);
+		units = business.unit().sort(units);
+		for (Unit o : units) {
 			wos.add(this.convert(business, o, Wo.class));
 		}
 		return wos;

+ 3 - 2
o2server/x_organization_assemble_express/src/main/java/com/x/organization/assemble/express/jaxrs/unit/ActionListWithPersonObject.java

@@ -80,8 +80,9 @@ class ActionListWithPersonObject extends BaseAction {
 			Predicate p = root.get(Identity_.person).in(ids);
 			List<String> unitIds = em.createQuery(cq.select(root.get(Identity_.unit)).where(p))
 					.getResultList().stream().distinct().collect(Collectors.toList());
-			unitIds = ListTools.trim(unitIds, true, true);
-			for (Unit o : business.unit().pick(unitIds)) {
+			List<Unit> units = business.unit().pick(unitIds);
+			units = business.unit().sort(units);
+			for (Unit o : units) {
 				wos.add(this.convert(business, o, Wo.class));
 			}
 		}

+ 3 - 1
o2server/x_organization_assemble_express/src/main/java/com/x/organization/assemble/express/jaxrs/unit/ActionListWithPersonSupNestedObject.java

@@ -83,7 +83,9 @@ class ActionListWithPersonSupNestedObject extends BaseAction {
 			unitIds.addAll(business.unit().listSupNested(str));
 		}
 		unitIds = ListTools.trim(unitIds, true, true);
-		for (Unit o : business.unit().pick(unitIds)) {
+		List<Unit> units = business.unit().pick(unitIds);
+		units = business.unit().sort(units);
+		for (Unit o : units) {
 			wos.add(this.convert(business, o, Wo.class));
 		}
 		return wos;

+ 3 - 1
o2server/x_organization_assemble_express/src/main/java/com/x/organization/assemble/express/jaxrs/unit/ActionListWithUnitAttributeObject.java

@@ -88,7 +88,9 @@ class ActionListWithUnitAttributeObject extends BaseAction {
 		List<String> unitIds = em.createQuery(cq.select(root.get(UnitAttribute_.unit)).where(p))
 				.getResultList().stream().distinct().collect(Collectors.toList());
 		unitIds = ListTools.trim(unitIds, true, true);
-		for (Unit o : business.unit().pick(unitIds)) {
+		List<Unit> units = business.unit().pick(unitIds);
+		units = business.unit().sort(units);
+		for (Unit o : units) {
 			wos.add(this.convert(business, o, Wo.class));
 		}
 		return wos;

+ 3 - 1
o2server/x_organization_assemble_express/src/main/java/com/x/organization/assemble/express/jaxrs/unit/ActionListWithUnitDutyObject.java

@@ -91,7 +91,9 @@ class ActionListWithUnitDutyObject extends BaseAction {
 			List<String> unitIds = em.createQuery(cq.select(root.get(UnitDuty_.unit)).where(p))
 					.getResultList().stream().distinct().collect(Collectors.toList());
 			unitIds = ListTools.trim(unitIds, true, true);
-			for (Unit o : business.unit().pick(unitIds)) {
+			List<Unit> units = business.unit().pick(unitIds);
+			units = business.unit().sort(units);
+			for (Unit o : units) {
 				wos.add(this.convert(business, o, Wo.class));
 			}
 		}

+ 4 - 1
o2web/source/o2_core/o2/xDesktop/Actions/RestActions.js

@@ -592,15 +592,18 @@ MWF.xDesktop.Actions.RestActions.Callback = new Class({
 			   case "success":
 				   if (this.appendSuccess) this.appendSuccess(responseJSON);
 				   if (this.success) return this.success(responseJSON, responseText);
+				   return responseJSON;
 			       break;
 			   case "warn":
 				   MWF.xDesktop.notice("info", {x: "right", y:"top"}, responseJSON.errorMessage.join("\n"));
 				   
 				   if (this.appendSuccess) this.appendSuccess(responseJSON);
 				   if (this.success) return this.success(responseJSON);
-			       break;
+                   return responseJSON;
+				   break;
 			   case "error":
 				   return this.doError(null, responseText, responseJSON.message);
+                   return responseJSON;
 				   break;
 			}
 		}else{

+ 3 - 2
o2web/source/o2_core/o2/xScript/Environment.js

@@ -1502,8 +1502,8 @@ MWF.xScript.Environment = function(ev){
             }else{
                 optionsOrName.each(function(option){
                     _includeSingle.apply(this, [option]);
-                    if (callback) callback.apply(this);
                 }.bind(this));
+                if (callback) callback.apply(this);
             }
         }else{
             _includeSingle.apply(this, [optionsOrName , callback, async])
@@ -1523,7 +1523,8 @@ MWF.xScript.Environment = function(ev){
     //在异步调用结束后 执行 resolve.cb();
     //目前只有表单的queryload事件支持此方法。
     this.wait = function(){
-        resolve = {};
+        var _self = this;
+        resolve = {"cb":  _self.goon.bind(_self)};
         var setResolve = function(callback){
             resolve.cb = callback;
         }.bind(this);

+ 2 - 0
o2web/source/x_component_process_Xform/Form.js

@@ -1154,12 +1154,14 @@ MWF.xApplication.process.Xform.Form = MWF.APPForm = new Class({
 
         if (this.businessData.control["allowSave"]) {
             this.fireEvent("beforeSave");
+            this.fireEvent("beforeSaveWork");
 
             if (this.app && this.app.fireEvent) this.app.fireEvent("beforeSave");
             this.saveFormData(function (json) {
                 if (this.app && !silent) this.app.notice(MWF.xApplication.process.Xform.LP.dataSaved, "success");
                 if (callback && typeOf(callback) === "function") callback();
                 this.fireEvent("afterSave");
+                this.fireEvent("afterSaveWork");
                 if (this.app && this.app.fireEvent) this.app.fireEvent("afterSave");
             }.bind(this));