diff --git a/com.actionsoft.apps.coe.pal/lib/com.actionsoft.apps.coe.pal.jar b/com.actionsoft.apps.coe.pal/lib/com.actionsoft.apps.coe.pal.jar index cbdd4568..de6a27fa 100644 Binary files a/com.actionsoft.apps.coe.pal/lib/com.actionsoft.apps.coe.pal.jar and b/com.actionsoft.apps.coe.pal/lib/com.actionsoft.apps.coe.pal.jar differ diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/CoEPALController.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/CoEPALController.java index 5cdaaefc..f9dcf315 100755 --- a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/CoEPALController.java +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/CoEPALController.java @@ -3,6 +3,7 @@ package com.actionsoft.apps.coe.pal; import com.actionsoft.apps.AppsConst; import com.actionsoft.apps.coe.pal.constant.CoEConstant; import com.actionsoft.apps.coe.pal.pal.repository.cache.PALRepositoryCache; +import com.actionsoft.apps.coe.pal.pal.repository.designer.no.epc.web.EpcGraphWeb; import com.actionsoft.bpms.bpmn.modeler.ProcessBPMNDesignerController; import com.actionsoft.bpms.commons.htmlframework.AlertWindow; import com.actionsoft.bpms.commons.htmlframework.HtmlPageTemplate; @@ -3431,4 +3432,16 @@ public class CoEPALController { return web.queryConditionData(wsId,teamId); } + /** + * 编号刷 + * @param uc + * @param uuid + * @return + */ + @Mapping("com.actionsoft.apps.coe.pal_repository_designer_no_refresh") + public String refreshDesignerNo(UserContext uc, String uuid) { + EpcGraphWeb web = new EpcGraphWeb(uc); + return web.refreshDesignerNo(uuid); + } + } diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/no/epc/model/EpcGraphModel.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/no/epc/model/EpcGraphModel.java new file mode 100644 index 00000000..4ea67b34 --- /dev/null +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/no/epc/model/EpcGraphModel.java @@ -0,0 +1,81 @@ +package com.actionsoft.apps.coe.pal.pal.repository.designer.no.epc.model; + +import java.util.List; + +/** + * 图结构Model + */ +public class EpcGraphModel { + private String id; + private String name; + private String shapeName; + private boolean hasNum; + private int visitPrevCount;// 访问的入线数量 + private int no;// 编号 + private List prevShapes;// 入线 + private List nextShapes;// 出线 + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getVisitPrevCount() { + return visitPrevCount; + } + + public void setVisitPrevCount(int visitPrevCount) { + this.visitPrevCount = visitPrevCount; + } + + public List getPrevShapes() { + return prevShapes; + } + + public void setPrevShapes(List prevShapes) { + this.prevShapes = prevShapes; + } + + public List getNextShapes() { + return nextShapes; + } + + public void setNextShapes(List nextShapes) { + this.nextShapes = nextShapes; + } + + public int getNo() { + return no; + } + + public void setNo(int no) { + this.no = no; + } + + public String getShapeName() { + return shapeName; + } + + public void setShapeName(String shapeName) { + this.shapeName = shapeName; + } + + public boolean isHasNum() { + return hasNum; + } + + public void setHasNum(boolean hasNum) { + this.hasNum = hasNum; + } +} diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/no/epc/tree/EpcGraphTree.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/no/epc/tree/EpcGraphTree.java new file mode 100644 index 00000000..d424703c --- /dev/null +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/no/epc/tree/EpcGraphTree.java @@ -0,0 +1,344 @@ +package com.actionsoft.apps.coe.pal.pal.repository.designer.no.epc.tree; + +import com.actionsoft.apps.coe.pal.pal.repository.designer.CoeDesignerShapeAPIManager; +import com.actionsoft.apps.coe.pal.pal.repository.designer.no.epc.model.EpcGraphModel; +import com.actionsoft.apps.coe.pal.pal.repository.model.PALRepositoryAttributeModel; +import com.actionsoft.apps.coe.pal.pal.repository.model.PALRepositoryModel; +import com.actionsoft.bpms.util.UUIDGener; +import com.actionsoft.bpms.util.UtilString; +import com.alibaba.fastjson.JSONObject; + +import java.util.*; + +public class EpcGraphTree { + + public List headerShapes = new ArrayList<>(); + + public Map graphShapeMap = new HashMap<>(); + + public Map shapeObjMap = new HashMap<>(); + + /** + * 初始化数据 + * @param elements + */ + public void initData(Set hasNumShapeNames, JSONObject elements) { + + // 构造数据 + Set ids = elements.keySet(); + for (String shapeId : ids) { + JSONObject shape = elements.getJSONObject(shapeId); + String shapeName = shape.getString("name"); + if(!"linker".equals(shapeName)) { + EpcGraphModel model = new EpcGraphModel(); + model.setId(shapeId); + model.setName(UtilString.isEmpty(shape.getString("text")) ? shape.getString("title") : shape.getString("text")); + model.setShapeName(shapeName); + model.setHasNum(hasNumShapeNames.contains(shapeName)); + model.setNextShapes(getNextShapes(shapeId, ids, elements)); + model.setPrevShapes(getPrevShapes(shapeId, ids, elements)); + graphShapeMap.put(shapeId, model); + shapeObjMap.put(shapeId, shape); + } + } + // 找开始节点(有出线无入线) + initHeaderData(); + // 去除环结构(有向图不能有环结构,否则无法进行拓扑排序) + removeHoopRelation(headerShapes); + // test(); + // testNo(); + } + + public void test() { + for (Map.Entry entry : graphShapeMap.entrySet()) { + String shape = entry.getKey(); + EpcGraphModel model = entry.getValue(); + // 查找前置 + List prevList = model.getPrevShapes(); + for (String id : prevList) { + System.out.println("【" + model.getName() + "】的上一个形状是【" + graphShapeMap.get(id).getName() + "】"); + } + // 查找后置 + List nextList = model.getNextShapes(); + for (String id : nextList) { + System.out.println("【" + model.getName() + "】的下一个形状是【" + graphShapeMap.get(id).getName() + "】"); + } + } + } + public void testNo() { + for (Map.Entry entry : graphShapeMap.entrySet()) { + String shape = entry.getKey(); + EpcGraphModel model = entry.getValue(); + System.out.println("【" + model.getName() + "】的编号是【" + model.getNo() + "】"); + } + } + + /** + * 初始化开始节点 + */ + private void initHeaderData() { + for (Map.Entry entry : graphShapeMap.entrySet()) { + if (entry.getValue().getNextShapes().size() > 0 && entry.getValue().getPrevShapes().size() == 0) { + headerShapes.add(entry.getKey()); + } + } + headerShapes.sort((s1, s2)->{return shapeObjMap.get(s1).getJSONObject("props").getInteger("x") - shapeObjMap.get(s2).getJSONObject("props").getInteger("x");}); + } + + /** + * 遍历所有节点,寻找从该节点出发又回到该节点的环,对环线进行删除 + * 一级一级往下寻找,currShape遇到有循环的环结构,则删除环的最后一个闭环线 + */ + public void removeHoopRelation(List shapeList) { + for (String currShape : shapeList) { + List currPrevShapes = graphShapeMap.get(currShape).getPrevShapes(); + + Set ids = new HashSet<>(); + List nextList = graphShapeMap.get(currShape).getNextShapes();// 出线节点s + while (nextList.size() > 0) { + Set ttt = new HashSet<>(); + for (String next : nextList) { + if (ids.contains(next)) { + continue; + } + ids.add(next); + List nextNextList = graphShapeMap.get(next).getNextShapes(); + boolean remove = false; + for (String nextNext : nextNextList) { + if (nextNext.equals(currShape)) { + remove = true; + currPrevShapes.remove(next); + } + } + if (remove) { + nextNextList.remove(currShape); + } + ttt.addAll(graphShapeMap.get(next).getNextShapes()); + } + nextList = new ArrayList<>(ttt); + } + } + Set ids2 = new HashSet<>(); + for (String curr : shapeList) { + ids2.addAll(graphShapeMap.get(curr).getNextShapes()); + } + if (ids2.size() > 0) { + removeHoopRelation(new ArrayList<>(ids2)); + } + + } + + /** + * 获取形状的上一个(多个)形状 + * @param shapeId + * @param ids + * @param elements + * @return + */ + public List getPrevShapes(String shapeId, Set ids, JSONObject elements) { + List result = new ArrayList<>(); + for (String id : ids) { + JSONObject shape = elements.getJSONObject(id); + String shapeName = shape.getString("name"); + if ("linker".equals(shapeName)) { + JSONObject to = shape.getJSONObject("to"); + String toId = to.getString("id"); + if (shapeId.equals(toId)) { + JSONObject from = shape.getJSONObject("from"); + String fromId = from.getString("id"); + if (elements.containsKey(fromId)) { + if (!shapeId.equals(fromId)) { + result.add(fromId); + } + } + } + } + } + // 按照x坐标进行排序 + result.sort((i1, i2)-> { + return elements.getJSONObject(i1).getJSONObject("props").getInteger("x") - elements.getJSONObject(i2).getJSONObject("props").getInteger("x"); + }); + return result; + } + + /** + * 获取形状的下一个(多个)形状 + * @param shapeId + * @param ids + * @param elements + * @return + */ + public List getNextShapes(String shapeId, Set ids, JSONObject elements) { + List result = new ArrayList<>(); + for (String id : ids) { + JSONObject shape = elements.getJSONObject(id); + String shapeName = shape.getString("name"); + if ("linker".equals(shapeName)) { + JSONObject from = shape.getJSONObject("from"); + String fromId = from.getString("id"); + if (shapeId.equals(fromId)) { + JSONObject to = shape.getJSONObject("to"); + String toId = to.getString("id"); + if (elements.containsKey(toId)) { + if (!shapeId.equals(toId)) { + result.add(toId); + } + } + } + } + } + // 按照x坐标进行排序 + result.sort((i1, i2)-> { + return elements.getJSONObject(i1).getJSONObject("props").getInteger("x") - elements.getJSONObject(i2).getJSONObject("props").getInteger("x"); + }); + return result; + } + + /** + * 形状排序 + * @return + */ + public JSONObject sort() { + int index = handleShapesNo(headerShapes, 1); + List list = new ArrayList<>(); + for (Map.Entry entry : graphShapeMap.entrySet()) { + EpcGraphModel model = entry.getValue(); + if (model.getNo() == 0) { + model.setNo(index++); + } + if (model.isHasNum()) { + list.add(model); + } + } + list.sort((e1, e2)-> {return e1.getNo() - e2.getNo();}); + JSONObject result = new JSONObject(); + int no = 1; + for (EpcGraphModel model : list) { + result.put(model.getId(), getNoStr(no)); + System.out.println("【" + model.getName() + "】的编号是【" + getNoStr(no) + "】"); + no++; + } + return result; + } + + private String getNoStr(int no) { + return no <= 0 ? (no + "") : no < 10 ? ("0" + no) : (no + ""); + } + + private void newSort() { + String id = UUIDGener.getUUID(); + EpcGraphModel newHeader = new EpcGraphModel(); + newHeader.setId(id); + newHeader.setShapeName("起点归并"); + newHeader.setPrevShapes(new ArrayList<>()); + newHeader.setName("起点归并"); + newHeader.setNextShapes(headerShapes); + graphShapeMap.put(id, newHeader); + // sort + newSort2(newHeader, 1); + } + + private void newSort2(EpcGraphModel parent, int index) { + List nextList = graphShapeMap.get(parent).getNextShapes(); + + + + + } + + + + /** + * 编号 + * 1.标记路径访问次数 + * 2.赋值序号 + * @param startShapes + * @param index + */ + private int handleShapesNo(List startShapes, int index) { + for (String start : startShapes) { + EpcGraphModel curr = graphShapeMap.get(start); + List prevList = curr.getPrevShapes(); + List nextList = curr.getNextShapes(); + // 通过当前节点的出入线数量执行不同的策略 + + // 单进单出 + if (prevList.size() == 1 && nextList.size() == 1) { + curr.setNo(index++); + curr.setVisitPrevCount(curr.getPrevShapes().size()); + // 下一个编号判断 + index = handleShapesNo(nextList, index); + } + // 单进多出 + if (prevList.size() == 1 && nextList.size() > 1) { + curr.setNo(index++); + curr.setVisitPrevCount(curr.getPrevShapes().size()); + // 下多个编号判断 + index = handleShapesNo(nextList, index); + } + // 单进不出 + if (prevList.size() == 1 && nextList.size() ==0) { + curr.setNo(index++); + curr.setVisitPrevCount(curr.getPrevShapes().size()); + // 没有下一个编号 + } + // 多进单出 + if (prevList.size() > 1 && nextList.size() == 1) { + if (curr.getVisitPrevCount() == curr.getPrevShapes().size() - 1) {// 其他路径已走完,执行编号累加 + curr.setNo(index++); + curr.setVisitPrevCount(curr.getPrevShapes().size()); + // 下一个编号判断 + index = handleShapesNo(nextList, index); + } else {// 访问过,进行访问次数累加 + curr.setVisitPrevCount(curr.getVisitPrevCount() + 1); + } + } + // 多进多出 + if (prevList.size() > 1 && nextList.size() > 1) { + if (curr.getVisitPrevCount() == curr.getPrevShapes().size() - 1) {// 其他路径已走完,执行编号累加 + curr.setNo(index++); + curr.setVisitPrevCount(curr.getPrevShapes().size()); + // 下多个编号判断 + index = handleShapesNo(nextList, index); + } else {// 访问过,进行访问次数累加 + curr.setVisitPrevCount(curr.getVisitPrevCount() + 1); + } + } + // 多进不出 + if (prevList.size() > 1 && nextList.size() == 0) { + if (curr.getVisitPrevCount() == curr.getPrevShapes().size() - 1) {// 其他路径已走完,执行编号累加 + curr.setNo(index++); + curr.setVisitPrevCount(curr.getPrevShapes().size()); + // 没有下一个编号 + + } else {// 访问过,进行访问次数累加 + curr.setVisitPrevCount(curr.getVisitPrevCount() + 1); + } + } + // 以下为起点 + // 零入单出 + if (prevList.size() == 0 && nextList.size() == 1) { + curr.setNo(index++); + // 下一个编号判断 + index = handleShapesNo(nextList, index); + } + // 零入多出 + if (prevList.size() == 0 && nextList.size() > 1) { + curr.setNo(index++); + // 下多个编号判断 + index = handleShapesNo(nextList, index); + } + // 零入零出 暂不处理,其他方法执行放入最后 + } + return index; + } + + public void handleSerializeShape(String next, List nextList, int index) { + EpcGraphModel model = graphShapeMap.get(next); + if (model.getPrevShapes().size() == 1 && model.getNextShapes().size() == 1) { + model.setNo(index++); + model.setVisitPrevCount(1); + handleSerializeShape(model.getNextShapes().get(0), null, index); + } + } +} diff --git a/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/no/epc/web/EpcGraphWeb.java b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/no/epc/web/EpcGraphWeb.java new file mode 100644 index 00000000..f1e2a9ad --- /dev/null +++ b/com.actionsoft.apps.coe.pal/src/com/actionsoft/apps/coe/pal/pal/repository/designer/no/epc/web/EpcGraphWeb.java @@ -0,0 +1,70 @@ +package com.actionsoft.apps.coe.pal.pal.repository.designer.no.epc.web; + +import com.actionsoft.apps.coe.pal.pal.method.model.PALMethodAttributeModel; +import com.actionsoft.apps.coe.pal.pal.repository.PALRepositoryQueryAPIManager; +import com.actionsoft.apps.coe.pal.pal.repository.cache.PALRepositoryCache; +import com.actionsoft.apps.coe.pal.pal.repository.designer.CoeDesignerShapeAPIManager; +import com.actionsoft.apps.coe.pal.pal.repository.designer.no.epc.tree.EpcGraphTree; +import com.actionsoft.apps.coe.pal.pal.repository.designer.relation.model.DesignerShapeRelationModel; +import com.actionsoft.apps.coe.pal.pal.repository.model.PALRepositoryAttributeModel; +import com.actionsoft.apps.coe.pal.pal.repository.model.PALRepositoryModel; +import com.actionsoft.bpms.commons.mvc.view.ActionWeb; +import com.actionsoft.bpms.commons.mvc.view.ResponseObject; +import com.actionsoft.bpms.server.UserContext; +import com.alibaba.fastjson.JSONObject; + +import java.util.*; + + +public class EpcGraphWeb extends ActionWeb { + + private UserContext uc; + + public EpcGraphWeb(UserContext uc) { + super(); + this.uc = uc; + } + + /** + * 刷新编号 + * @param uuid + * @return + */ + public String refreshDesignerNo(String uuid) { + PALRepositoryModel model = PALRepositoryCache.getCache().get(uuid); + if (model == null) { + return ResponseObject.newErrResponse("模型不存在,uuid:" + uuid).toString(); + } + EpcGraphTree tree = new EpcGraphTree(); + + String define = PALRepositoryQueryAPIManager.getInstance().getProcessDefinition(uc, uuid); + JSONObject definition = JSONObject.parseObject(define); + JSONObject elements = definition.getJSONObject("elements"); + // 记录有序号属性的节点 + Set hasNumShapeNames = new HashSet<>(); + Iterator it = elements.keySet().iterator(); + while (it.hasNext()) { + String key = it.next(); + JSONObject shape = elements.getJSONObject(key); + String shapeName = shape.getString("name"); + if(!"linker".equals(shapeName)) { + if (!hasNumShapeNames.contains(shapeName)) { + List useAttrList = CoeDesignerShapeAPIManager.getInstance().getValidAndUseAttributeModels(model.getWsId(), shape.getString("category").replace("_", "."), shapeName, model.getMethodId()); + for (PALMethodAttributeModel attr : useAttrList) { + if ("activity_number".equals(attr.getKey())) { + hasNumShapeNames.add(shapeName); + break; + } + } + } + } + } + tree.initData(hasNumShapeNames, elements); + JSONObject result = new JSONObject(); + result.put("attrId", "activity_number"); + result.put("data", tree.sort()); + ResponseObject ro = ResponseObject.newOkResponse(); + ro.setData(result); + return ro.toString(); + } +} diff --git a/com.actionsoft.apps.coe.pal/web/com.actionsoft.apps.coe.pal/action.xml b/com.actionsoft.apps.coe.pal/web/com.actionsoft.apps.coe.pal/action.xml index d91b9fbf..7da0ec55 100755 --- a/com.actionsoft.apps.coe.pal/web/com.actionsoft.apps.coe.pal/action.xml +++ b/com.actionsoft.apps.coe.pal/web/com.actionsoft.apps.coe.pal/action.xml @@ -1750,4 +1750,7 @@ + + + \ No newline at end of file diff --git a/com.actionsoft.apps.coe.pal/web/com.actionsoft.apps.coe.pal/js/coe.team.pal.designer.js b/com.actionsoft.apps.coe.pal/web/com.actionsoft.apps.coe.pal/js/coe.team.pal.designer.js index de47aa6d..519a1233 100644 --- a/com.actionsoft.apps.coe.pal/web/com.actionsoft.apps.coe.pal/js/coe.team.pal.designer.js +++ b/com.actionsoft.apps.coe.pal/web/com.actionsoft.apps.coe.pal/js/coe.team.pal.designer.js @@ -250,71 +250,55 @@ $(function() { // 编号刷点击事件 $('#bar_sort').off("click").on("click",function (){ - if ($("#saving_tip").text() != "已保存成功" && $("#saving_tip").text() != "保存成功" && $("#saving_tip").text() != "您的文件已经成功保存") { + if ($("#saving_tip").text() != "已保存成功" && $("#saving_tip").text() != "保存成功" && $("#saving_tip").text() != "您的文件已经成功保存" && $("#saving_tip").text() != "") { $.simpleAlert('页面未保存,请先保存', 'error', 1500); } else { - // $.simpleAlert("正在编号", "loading"); - // $.ajax({ - // type: "POST", - // url: "./jd", - // data: { - // sid: CLB.sid, - // cmd: "com.actionsoft.apps.coe.pal_repository_process_define_save", - // uuid: ruuid, - // }, - // success: function (msg, textStatus, jqXHR) { - // $.simpleAlert("close"); - // console.log(msg) - // }, - // error: function (jqXHR, textStatus, errorThrown) { - // $.simpleAlert("close"); - // $.simpleAlert('编号失败', 'error', 1500); - // } - // }) - let numObj = { - brushId: 'number_brush', - orderList: [ - { shapeId: 'obj_c9e1cda208700001132717c019b9a350',order: 1}, - { shapeId: 'obj_c9e1cda2b8a000013b42e5f045db1f01',order: 2}, - { shapeId: 'obj_c9e1cda4ac10000164dd6bb015406b40',order: 3}, - { shapeId: 'obj_c9e1cda3109000015741104116a918a8',order: 4}, - { shapeId: 'obj_c9e1cdab200000014a2eade016e8170d',order: 5}, - { shapeId: 'obj_c9e1cdb266f0000159a7c8afa7701a68',order: 6}, - ] - }; - let obj = Model.define; - console.log(obj); - let elements = obj.elements; - let orderList = numObj.orderList; - for (let j = 0; j < orderList.length; j++) { - for(let i in elements) { - if (orderList[j].shapeId == i) { - for(let a = 0; a < elements[i].dataAttributes.length; a ++ ) { - if(elements[i].dataAttributes[a].attributesJsonArray !== undefined) { - for(let b = 0; b < elements[i].dataAttributes[a].attributesJsonArray.length; b ++) { - if(elements[i].dataAttributes[a].attributesJsonArray[b].id == numObj.brushId) { - elements[i].dataAttributes[a].attributesJsonArray[b].value = orderList[j].order + $.simpleAlert("正在编号", "loading"); + $.ajax({ + type: "POST", + url: "./jd", + data: { + sid: CLB.sid, + cmd: "com.actionsoft.apps.coe.pal_repository_designer_no_refresh", + uuid: ruuid, + }, + success: function (r, textStatus, jqXHR) { + $.simpleAlert("close"); + var data = r.data; + var elements = Model.define.elements; + var attrId = data.attrId; + var shapeNo = data.data; + var updateShape = []; + for (var i in elements) { + if (shapeNo[i] != undefined) { + var flag = false; + for(var a = 0; a < elements[i].dataAttributes.length; a ++ ) { + if(elements[i].dataAttributes[a].attributesJsonArray !== undefined) { + for(var b = 0; b < elements[i].dataAttributes[a].attributesJsonArray.length; b ++) { + if(elements[i].dataAttributes[a].attributesJsonArray[b].id == attrId) { + elements[i].dataAttributes[a].attributesJsonArray[b].value = shapeNo[i]; + flag = true; + break; + } } } } + if (flag) { + updateShape.push(elements[i]); + Designer.painter.renderShape(elements[i]); + } } } + if (updateShape.length > 0) { + Model.updateMulti(updateShape); + } + }, + error: function (jqXHR, textStatus, errorThrown) { + $.simpleAlert("close"); + $.simpleAlert('编号失败', 'error', 1500); } - } - // for(let i in elements) { - // for(let a = 0; a < elements[i].dataAttributes.length; a ++ ) { - // if(elements[i].dataAttributes[a].attributesJsonArray !== undefined) { - // for(let b = 0; b < elements[i].dataAttributes[a].attributesJsonArray.length; b ++) { - // if(elements[i].dataAttributes[a].attributesJsonArray[b].id == 'number_brush') { - // elements[i].dataAttributes[a].attributesJsonArray[b].value = 24 - // } - // } - // } - // } - // } - $("#saving_tip").css("color", "rgb(255, 0, 0)"); - $("#saving_tip").text("文件已修改,未保存"); + }) } })