From a954a0e771ef26cc81e44ca9a2cc5b9ccca025b5 Mon Sep 17 00:00:00 2001 From: RuicyWu <1063154311@qq.com> Date: Thu, 25 Dec 2025 16:44:58 +0800 Subject: [PATCH] =?UTF-8?q?=E6=89=AB=E6=8F=8F=E4=BB=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apps/src_saomaoyi/SaoMiaoYiPluginApi.java | 43 ++ .../src_saomaoyi/btn/SaoMiaoYiImgBtn.java | 54 ++ .../src_saomaoyi/btn/SaoMiaoYiInitBtn.java | 54 ++ .../config/SaoMiaoYiPluginConfigProvider.java | 17 + .../constants/SaoMiaoYiConstants.java | 30 + .../invoice/InvoiceImgSaveService.java | 8 + .../invoice/InvoiceImgSaveServiceImpl.java | 143 ++++ .../apps/src_saomaoyi/utils/ClauseFactor.java | 19 + .../apps/src_saomaoyi/utils/EnumMapUtils.java | 86 +++ .../apps/src_saomaoyi/utils/FormColumn.java | 24 + .../src_saomaoyi/utils/FormDataOperator.java | 630 ++++++++++++++++++ .../src_saomaoyi/utils/FormExportUtil.java | 84 +++ .../apps/src_saomaoyi/utils/FormFieldVo.java | 22 + .../src_saomaoyi/utils/FormUpdateField.java | 57 ++ .../utils/FormWhereCondition.java | 121 ++++ .../apps/src_saomaoyi/utils/HttpClient.java | 417 ++++++++++++ .../resources/HandleSaoMiaoYiImgResource.java | 57 ++ v5/apps-customize/src/main/test/TestB.java | 8 + .../plugin/src_saomiaoyi/pluginCfg.xml | 6 + .../src_saomiaoyi/spring/spring-bean.xml | 12 + .../src_saomiaoyi/spring/spring-quartz.xml | 4 + .../plugin/src_saomiaoyi/spring/spring.xml | 6 + .../saomiaoyiBtnResources/css/img/icon16.png | Bin 0 -> 103273 bytes .../css/saomiaoyiBtn.css | 36 + .../saomiaoyiBtnResources/html/saomiaoyi.html | 16 + .../html/saomiaoyiImg.html | 16 + .../saomiaoyiBtnResources/js/img.js | 354 ++++++++++ .../saomiaoyiBtnResources/js/init.js | 291 ++++++++ .../src/test/SheBaoFenZhangTest.java | 7 + 29 files changed, 2622 insertions(+) create mode 100644 v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/SaoMiaoYiPluginApi.java create mode 100644 v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/btn/SaoMiaoYiImgBtn.java create mode 100644 v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/btn/SaoMiaoYiInitBtn.java create mode 100644 v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/config/SaoMiaoYiPluginConfigProvider.java create mode 100644 v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/constants/SaoMiaoYiConstants.java create mode 100644 v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/invoice/InvoiceImgSaveService.java create mode 100644 v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/invoice/InvoiceImgSaveServiceImpl.java create mode 100644 v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/utils/ClauseFactor.java create mode 100644 v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/utils/EnumMapUtils.java create mode 100644 v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/utils/FormColumn.java create mode 100644 v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/utils/FormDataOperator.java create mode 100644 v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/utils/FormExportUtil.java create mode 100644 v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/utils/FormFieldVo.java create mode 100644 v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/utils/FormUpdateField.java create mode 100644 v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/utils/FormWhereCondition.java create mode 100644 v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/utils/HttpClient.java create mode 100644 v5/apps-customize/src/main/java/com/seeyon/ctp/rest/resources/HandleSaoMiaoYiImgResource.java create mode 100644 v5/apps-customize/src/main/test/TestB.java create mode 100644 v5/apps-customize/src/main/webapp/WEB-INF/cfgHome/plugin/src_saomiaoyi/pluginCfg.xml create mode 100644 v5/apps-customize/src/main/webapp/WEB-INF/cfgHome/plugin/src_saomiaoyi/spring/spring-bean.xml create mode 100644 v5/apps-customize/src/main/webapp/WEB-INF/cfgHome/plugin/src_saomiaoyi/spring/spring-quartz.xml create mode 100644 v5/apps-customize/src/main/webapp/WEB-INF/cfgHome/plugin/src_saomiaoyi/spring/spring.xml create mode 100644 v5/apps-customize/src/main/webapp/apps_res/cap/customCtrlResources/saomiaoyiBtnResources/css/img/icon16.png create mode 100644 v5/apps-customize/src/main/webapp/apps_res/cap/customCtrlResources/saomiaoyiBtnResources/css/saomiaoyiBtn.css create mode 100644 v5/apps-customize/src/main/webapp/apps_res/cap/customCtrlResources/saomiaoyiBtnResources/html/saomiaoyi.html create mode 100644 v5/apps-customize/src/main/webapp/apps_res/cap/customCtrlResources/saomiaoyiBtnResources/html/saomiaoyiImg.html create mode 100644 v5/apps-customize/src/main/webapp/apps_res/cap/customCtrlResources/saomiaoyiBtnResources/js/img.js create mode 100644 v5/apps-customize/src/main/webapp/apps_res/cap/customCtrlResources/saomiaoyiBtnResources/js/init.js create mode 100644 v5/apps-customize/src/test/SheBaoFenZhangTest.java diff --git a/v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/SaoMiaoYiPluginApi.java b/v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/SaoMiaoYiPluginApi.java new file mode 100644 index 0000000..4f8e8df --- /dev/null +++ b/v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/SaoMiaoYiPluginApi.java @@ -0,0 +1,43 @@ +package com.seeyon.apps.src_saomaoyi; + +import com.seeyon.apps.common.plugin.api.APluginInfoApi; +import com.seeyon.apps.common.plugin.vo.ConfigVo; +import com.seeyon.apps.src_saomaoyi.constants.SaoMiaoYiConstants; +import org.springframework.stereotype.Component; + +@Component +public class SaoMiaoYiPluginApi extends APluginInfoApi { + + public SaoMiaoYiPluginApi() { + } + + public String getPluginId() { + System.out.println(SaoMiaoYiConstants.getPluginId()); + return SaoMiaoYiConstants.getPluginId(); + } + + public String getCreateUser() { + return "橙阳科技"; + } + + public String getDescription() { + return "三峡旅游水扫描仪控件"; + } + + public ConfigVo getDefaultConfig() { + ConfigVo configVo = new ConfigVo(); + SaoMiaoYiConstants[] var2 = SaoMiaoYiConstants.values(); + int var3 = var2.length; + + for(int var4 = 0; var4 < var3; ++var4) { + SaoMiaoYiConstants value = var2[var4]; + if (value != SaoMiaoYiConstants.plugin) { + configVo.getDevParams().put(value.name(), value.getDefaultValue()); + configVo.getProdParams().put(value.name(), value.getDefaultValue()); + configVo.getParamMap().put(value.name(), value.getDescription()); + } + } + + return configVo; + } +} diff --git a/v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/btn/SaoMiaoYiImgBtn.java b/v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/btn/SaoMiaoYiImgBtn.java new file mode 100644 index 0000000..afb96f1 --- /dev/null +++ b/v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/btn/SaoMiaoYiImgBtn.java @@ -0,0 +1,54 @@ +package com.seeyon.apps.src_saomaoyi.btn; + +import com.seeyon.cap4.form.bean.button.CommonBtn; +import com.seeyon.cap4.form.util.Enums; +import org.springframework.stereotype.Component; + +@Component +public class SaoMiaoYiImgBtn extends CommonBtn { + @Override + public String getPCInjectionInfo() { + return "{\"path\":\"apps_res/cap/customCtrlResources/saomiaoyiBtnResources/\",\"jsUri\":\"js/img.js\",\"initMethod\":\"init\",\"nameSpace\":\"" + + this.getNameSpace() + "\"}"; + } + + @Override + public String getMBInjectionInfo() { + return null; + } + + @Override + public String getKey() { + return "1992789877417263104"; + } + + @Override + public boolean canUse(Enums.FormType formType) { + return true; + } + + public String getNameSpace() { + return "customBtn_" + this.getKey(); + } + + public String getFieldLength() { + return "20"; + } + @Override + public String getText() { + return "获取扫描仪图片按钮"; + } + + /** + * 控件初始化接口,此接口在控件初始化的时候,会调用,主要用于定义控件所属插件id、在表单编辑器中的图标、表单编辑器中有哪些属性可以设置。 + * 使用举例:在接口中定义自定义控件在在表单编辑器中有哪些控件属性需要配置 + */ + @Override + public void init() { + //设置图标和插件ID + setPluginId("src_saomiaoyi"); + setIcon("cap-icon-custom-button"); + // 自定义参数 + } + +} diff --git a/v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/btn/SaoMiaoYiInitBtn.java b/v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/btn/SaoMiaoYiInitBtn.java new file mode 100644 index 0000000..d8acdee --- /dev/null +++ b/v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/btn/SaoMiaoYiInitBtn.java @@ -0,0 +1,54 @@ +package com.seeyon.apps.src_saomaoyi.btn; + +import com.seeyon.cap4.form.bean.button.CommonBtn; +import com.seeyon.cap4.form.util.Enums; +import org.springframework.stereotype.Component; + +@Component +public class SaoMiaoYiInitBtn extends CommonBtn { + @Override + public String getPCInjectionInfo() { + return "{\"path\":\"apps_res/cap/customCtrlResources/saomiaoyiBtnResources/\",\"jsUri\":\"js/init.js\",\"initMethod\":\"init\",\"nameSpace\":\"" + + this.getNameSpace() + "\"}"; + } + + @Override + public String getMBInjectionInfo() { + return null; + } + + @Override + public String getKey() { + return "1992789877417263105"; + } + + @Override + public boolean canUse(Enums.FormType formType) { + return true; + } + + public String getNameSpace() { + return "customBtn_" + this.getKey(); + } + + public String getFieldLength() { + return "20"; + } + @Override + public String getText() { + return "初始化扫描仪按钮"; + } + + /** + * 控件初始化接口,此接口在控件初始化的时候,会调用,主要用于定义控件所属插件id、在表单编辑器中的图标、表单编辑器中有哪些属性可以设置。 + * 使用举例:在接口中定义自定义控件在在表单编辑器中有哪些控件属性需要配置 + */ + @Override + public void init() { + //设置图标和插件ID + setPluginId("src_saomiaoyi"); + setIcon("cap-icon-custom-button"); + // 自定义参数 + } + +} diff --git a/v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/config/SaoMiaoYiPluginConfigProvider.java b/v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/config/SaoMiaoYiPluginConfigProvider.java new file mode 100644 index 0000000..ba40e1e --- /dev/null +++ b/v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/config/SaoMiaoYiPluginConfigProvider.java @@ -0,0 +1,17 @@ +package com.seeyon.apps.src_saomaoyi.config; + +import com.seeyon.apps.common.config.ICstConfigApi; +import com.seeyon.apps.common.plugin.vo.ConfigVo; +import com.seeyon.apps.src_saomaoyi.constants.SaoMiaoYiConstants; +import com.seeyon.ctp.common.AppContext; + +import static com.seeyon.apps.src_saomaoyi.constants.SaoMiaoYiConstants.getPluginId; + +public class SaoMiaoYiPluginConfigProvider { + protected ICstConfigApi cstConfigApi = (ICstConfigApi) AppContext.getBean("cstConfigApi"); + + public String getBizConfigByKey(SaoMiaoYiConstants key) { + ConfigVo config = cstConfigApi.getConfig(getPluginId()); + return config.getParamVal(key.name()); + } +} diff --git a/v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/constants/SaoMiaoYiConstants.java b/v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/constants/SaoMiaoYiConstants.java new file mode 100644 index 0000000..0d993e6 --- /dev/null +++ b/v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/constants/SaoMiaoYiConstants.java @@ -0,0 +1,30 @@ +package com.seeyon.apps.src_saomaoyi.constants; + +public enum SaoMiaoYiConstants { + + plugin("src_saomiaoyi","插件ID"), + formDataLoginName("wukangqiao","档案表创建人"), + updateAccountName("wukangqiao","更新账号"), + updateLoginName("wukangqiao","更新登录名"), + formCode("smy","表单编码"), + ; + + private String defaultValue; + private String description; + + SaoMiaoYiConstants(String defaultValue,String description) { + this.defaultValue = defaultValue; + this.description = description; + } + + public String getDescription() { + return description; + } + + public String getDefaultValue() { + return defaultValue; + } + public static String getPluginId() { + return plugin.defaultValue; + } +} diff --git a/v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/invoice/InvoiceImgSaveService.java b/v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/invoice/InvoiceImgSaveService.java new file mode 100644 index 0000000..8a38e5a --- /dev/null +++ b/v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/invoice/InvoiceImgSaveService.java @@ -0,0 +1,8 @@ +package com.seeyon.apps.src_saomaoyi.invoice; + +import java.io.InputStream; + +public interface InvoiceImgSaveService { + + void saveInvoiceImg(InputStream is) throws Exception; +} diff --git a/v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/invoice/InvoiceImgSaveServiceImpl.java b/v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/invoice/InvoiceImgSaveServiceImpl.java new file mode 100644 index 0000000..d51e727 --- /dev/null +++ b/v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/invoice/InvoiceImgSaveServiceImpl.java @@ -0,0 +1,143 @@ +package com.seeyon.apps.src_saomaoyi.invoice; + +import com.seeyon.apps.src_saomaoyi.config.SaoMiaoYiPluginConfigProvider; +import com.seeyon.apps.src_saomaoyi.constants.SaoMiaoYiConstants; +import com.seeyon.apps.src_saomaoyi.utils.*; +import com.seeyon.ctp.common.AppContext; +import com.seeyon.ctp.common.filemanager.manager.AttachmentManager; +import com.seeyon.ctp.common.po.filemanager.Attachment; +import com.seeyon.ctp.organization.bo.V3xOrgAccount; +import com.seeyon.ctp.organization.bo.V3xOrgMember; +import com.seeyon.ctp.organization.manager.OrgManager; +import com.seeyon.ctp.services.FileUploadExporter; +import com.seeyon.v3x.services.form.FormFactory; +import com.seeyon.v3x.services.form.bean.FormExport; +import com.seeyon.v3x.services.form.bean.ValueExport; + +import java.io.*; +import java.text.SimpleDateFormat; +import java.util.*; + +public class InvoiceImgSaveServiceImpl implements InvoiceImgSaveService { + + private FormFactory formFactory; + + private SaoMiaoYiPluginConfigProvider configProvider = (SaoMiaoYiPluginConfigProvider) AppContext.getBean("saoMiaoYiPluginConfigProvider"); + + public FormFactory getFormFactory() { + if (formFactory == null) { + formFactory = (FormFactory) AppContext.getBean("formFactory"); + } + return formFactory; + } + public void setFormFactory(FormFactory formFactory) { + this.formFactory = formFactory; + } + + @Override + public void saveInvoiceImg(InputStream is) throws Exception { + String code = insertRecord(); + String formCode = configProvider.getBizConfigByKey(SaoMiaoYiConstants.formCode); + FormDataOperator formDataOperator = new FormDataOperator(); + List condiitonVo = new ArrayList<>(); + List updateFields = new ArrayList<>(); + condiitonVo.add(FormWhereCondition.build().display("编号").value(code)); + + List formColumns = formDataOperator.queryFormDataCondition(formCode, null, condiitonVo); + if (formColumns == null || formColumns.size() == 0) { + throw new RuntimeException("查询错误"); + } + String formId = formColumns.get(0).getId(); + String refId = bindFileRef(formId,is); + updateFields.add(FormUpdateField.build().value(refId).display("文件")); + List whereClause = new ArrayList<>(); + whereClause.add(FormWhereCondition.build().display("ID").value(Long.parseLong(formId))); + formDataOperator.updateMasterForm(formCode, updateFields, whereClause); + } + + private String bindFileRef(String formId, InputStream is) throws Exception { + String refId = Math.abs(UUID.randomUUID().getLeastSignificantBits()) + ""; + String localFilePath = System.getProperty("java.io.tmpdir") + File.separator + "seeyontempfile"; + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + String tempFileName = UUID.randomUUID() + ".pdf"; + File tempFileParent = new File(localFilePath); + + if (!tempFileParent.exists()) { + tempFileParent.mkdirs(); + } + + File tempFile = new File(tempFileParent, tempFileName); + + // ----------- 关键修复:用字节流复制 InputStream 到 PDF ----------- + try (InputStream input = is; + OutputStream output = new FileOutputStream(tempFile)) { + + byte[] buffer = new byte[8192]; + int len; + while ((len = input.read(buffer)) != -1) { + output.write(buffer, 0, len); + } + } catch (Exception e) { + throw new RuntimeException("保存临时 PDF 文件失败", e); + } + + // 限制 100MB + if (tempFile.length() > 102400000) { + tempFile.delete(); + return null; + } + + // 调用 Seeyon 附件服务上传 + FileUploadExporter fileUpload = new FileUploadExporter(); + String uploadResult = fileUpload.processUpload(new String[]{tempFile.getAbsolutePath()}); + + Map map = new HashMap<>(); + map.put("type", "0"); + map.put("fileUrl", uploadResult); + map.put("mimeType", "application/pdf"); + map.put("size", String.valueOf(tempFile.length())); + map.put("subReference", refId); + map.put("category", "66"); + map.put("createdate", sdf.format(new Date())); + map.put("filename", tempFileName); + map.put("reference", formId); + + // 删除本地临时文件 + tempFile.delete(); + + Attachment attachment = new Attachment(map); + OrgManager orgManager = (OrgManager) AppContext.getBean("orgManager"); + AttachmentManager attachmentManager = (AttachmentManager) AppContext.getBean("attachmentManager"); + + String loginName = configProvider.getBizConfigByKey(SaoMiaoYiConstants.formDataLoginName); + String updateAccountName = configProvider.getBizConfigByKey(SaoMiaoYiConstants.updateAccountName); + + V3xOrgMember member = orgManager.getMemberByLoginName(loginName); + V3xOrgAccount account = orgManager.getAccountByName(updateAccountName); + + attachmentManager.create(Collections.singletonList(attachment), member.getId(), account.getId()); + + return refId; + } + + + public String insertRecord() throws Exception { + String code = UUID.randomUUID().toString().replace("-", ""); + String loginName = configProvider.getBizConfigByKey(SaoMiaoYiConstants.formDataLoginName); + String formCode = configProvider.getBizConfigByKey(SaoMiaoYiConstants.formCode); + Map map = new HashMap(); + Long currentUserId = AppContext.currentUserId(); + if(currentUserId != null) { + map.put("操作人",currentUserId); + } + map.put("编号", code); + FormExport formExport = new FormExport(); + FormExportUtil formExportUtil = new FormExportUtil(); + List valueExport = formExportUtil.setFormValue(map); + formExport.setValues(valueExport); + getFormFactory().importBusinessFormData(loginName, formCode, + formExport, new String[] {}); + return code; + } +} diff --git a/v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/utils/ClauseFactor.java b/v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/utils/ClauseFactor.java new file mode 100644 index 0000000..da43d90 --- /dev/null +++ b/v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/utils/ClauseFactor.java @@ -0,0 +1,19 @@ +package com.seeyon.apps.src_saomaoyi.utils; + +public enum ClauseFactor { + EQ, //相等 + GT, //大于 + GE, //大于等于 + LT, //小于 + LE, //小于等于 + NULL, //空 + NOT_NULL, //非空 + LIKE, //模糊 + AND, + OR + ; + + public boolean isNullType() { + return this == NULL || this == NOT_NULL; + } +} diff --git a/v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/utils/EnumMapUtils.java b/v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/utils/EnumMapUtils.java new file mode 100644 index 0000000..97a6c03 --- /dev/null +++ b/v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/utils/EnumMapUtils.java @@ -0,0 +1,86 @@ +package com.seeyon.apps.src_saomaoyi.utils; + +import com.seeyon.ctp.common.AppContext; +import com.seeyon.ctp.common.ctpenumnew.manager.EnumManager; +import com.seeyon.ctp.common.po.ctpenumnew.CtpEnumBean; +import com.seeyon.ctp.common.po.ctpenumnew.CtpEnumItem; +import com.seeyon.ctp.util.JDBCAgent; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +public class EnumMapUtils { + public static String getEnumItemValue(String rootPCode, String groupValue, String targetValue) { + if(targetValue == null || "null".equals(targetValue) || "".equals(targetValue)){ + return ""; + } + String queryIdSql = "SELECT ce.ID FROM ctp_enum ce inner join ctp_enum cei on ce.`PARENT_ID` = cei.ID where CEI.`PROGRAM_CODE` = ? and ce.`ENUMNAME` = ?"; + Long enumId = null; + JDBCAgent agent = new JDBCAgent(); + try { + agent.execute(queryIdSql, Arrays.asList(rootPCode,groupValue)); + List> list = (List>) agent.resultSetToList(); + if(list == null || list.size() == 0) { + return ""; + } + Map map = list.get(0); + enumId = (Long)map.get("ID"); + } catch (Exception e) { + return ""; + }finally { + agent.close(); + } + EnumManager enumManagerNew = (EnumManager) AppContext.getBean("enumManagerNew"); + CtpEnumBean ctpEnumBean = enumManagerNew.getEnum(enumId); + if(ctpEnumBean == null) { + return ""; + } + List ctpEnumItems = ctpEnumBean.getItems(); + if(ctpEnumBean.getItems() == null) { + return ""; + } + for (CtpEnumItem enumItem : ctpEnumItems) { + if(enumItem.getShowvalue().equals(targetValue)) { + return enumItem.getId() + ""; + } + } + return ""; + } + + public static String getEnumItemValueByEnumId(String showValue,long enumId) { + EnumManager enumManagerNew = (EnumManager) AppContext.getBean("enumManagerNew"); + CtpEnumBean ctpEnumBean = enumManagerNew.getEnum(enumId); + if(ctpEnumBean == null) { + return ""; + } + List ctpEnumItems = ctpEnumBean.getItems(); + if(ctpEnumBean.getItems() == null) { + return ""; + } + for (CtpEnumItem enumItem : ctpEnumItems) { + if(enumItem.getShowvalue().equals(showValue)) { + return enumItem.getId() + ""; + } + } + return ""; + } + + public static String getEnumItemValueByEnumIdAndEnumValue(String value,long enumId) { + EnumManager enumManagerNew = (EnumManager) AppContext.getBean("enumManagerNew"); + CtpEnumBean ctpEnumBean = enumManagerNew.getEnum(enumId); + if(ctpEnumBean == null) { + return ""; + } + List ctpEnumItems = ctpEnumBean.getItems(); + if(ctpEnumBean.getItems() == null) { + return ""; + } + for (CtpEnumItem enumItem : ctpEnumItems) { + if(enumItem.getValue().equals(value)) { + return enumItem.getId() + ""; + } + } + return ""; + } +} diff --git a/v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/utils/FormColumn.java b/v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/utils/FormColumn.java new file mode 100644 index 0000000..850967d --- /dev/null +++ b/v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/utils/FormColumn.java @@ -0,0 +1,24 @@ +package com.seeyon.apps.src_saomaoyi.utils; + +import java.util.List; + +public class FormColumn { + private String id; + private List vos; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public List getVos() { + return vos; + } + + public void setVos(List vos) { + this.vos = vos; + } +} diff --git a/v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/utils/FormDataOperator.java b/v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/utils/FormDataOperator.java new file mode 100644 index 0000000..309d9a4 --- /dev/null +++ b/v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/utils/FormDataOperator.java @@ -0,0 +1,630 @@ +package com.seeyon.apps.src_saomaoyi.utils; + +import com.alibaba.fastjson.JSONObject; +import com.seeyon.aicloud.common.JsonUtils; +import com.seeyon.apps.src_powerfeeinvoice.config.HttpFormRestApiConfig; +import com.seeyon.cap4.form.api.FormApi4Cap4; +import com.seeyon.cap4.form.bean.FormBean; +import com.seeyon.cap4.form.bean.FormFieldBean; +import com.seeyon.cap4.form.bean.FormTableBean; +import com.seeyon.ctp.common.AppContext; +import com.seeyon.ctp.common.exceptions.BusinessException; +import com.seeyon.ctp.util.JDBCAgent; +import org.apache.commons.httpclient.HttpStatus; +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.message.BasicHeader; +import org.apache.http.util.EntityUtils; +import www.seeyon.com.utils.StringUtil; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.*; +import java.util.stream.Collectors; + +public class FormDataOperator { + + public void updateMasterForm(String formNo, List updateFieldVos, List conditionVos) throws BusinessException { + FormApi4Cap4 formApi4Cap4 = (FormApi4Cap4) AppContext.getBean("formApi4Cap4"); + FormBean cap4FormBean = formApi4Cap4.getFormByFormCode(formNo); + FormTableBean masterTableBean = cap4FormBean.getMasterTableBean(); + if (updateFieldVos == null) { + throw new IllegalArgumentException("要修改的字段为空"); + } + for (FormUpdateField fieldVo : updateFieldVos) { + FormFieldBean bean = masterTableBean.getFieldBeanByDisplay(fieldVo.getDisplay()); + if (bean == null) { + continue; + } + if(bean.getInputType().equals("image") || bean.getInputType().equals("attachment")) { + + } + fieldVo.fieldName(bean.getColumnName()); + } + List updateFields = updateFieldVos.stream().filter(u -> u.getFieldName() != null).collect(Collectors.toList()); + for (FormWhereCondition conditionVo : conditionVos) { + FormFieldBean bean = masterTableBean.getFieldBeanByDisplay(conditionVo.getDisplay()); + if (bean == null) { + if (conditionVo.getDisplay().equals("ID") || conditionVo.getDisplay().equals("id")) { + conditionVo.setFieldName(conditionVo.getDisplay()); + } + continue; + } + conditionVo.setFieldName(bean.getColumnName()); + } + List conditions = conditionVos.stream().filter(c -> c.getFieldName() != null).collect(Collectors.toList()); + Map map = generateSql(updateFields, masterTableBean.getTableName(), conditions); + JDBCAgent agent = new JDBCAgent(); + try { + agent.execute((String) map.get("sql"), (List) map.get("params")); + return; + } catch (Exception e) { + e.printStackTrace(); + } finally { + agent.close(); + } + } + + public Long countCondition(String formNo,List conditionVos) throws BusinessException { + FormApi4Cap4 formApi4Cap4 = (FormApi4Cap4) AppContext.getBean("formApi4Cap4"); + FormBean cap4FormBean = formApi4Cap4.getFormByFormCode(formNo); + FormTableBean masterTableBean = cap4FormBean.getMasterTableBean(); + String tableName = masterTableBean.getTableName(); + for (FormWhereCondition conditionVo : conditionVos) { + FormFieldBean fieldBeanByDisplay = masterTableBean.getFieldBeanByDisplay(conditionVo.getDisplay()); + if (fieldBeanByDisplay == null) { + continue; + } + conditionVo.setFieldName(fieldBeanByDisplay.getColumnName()); + } + + Map generateSql = generateSql(conditionVos, tableName); + String sql = (String) generateSql.get("sql"); + List params = (List) generateSql.get("params"); + JDBCAgent jdbcAgent = new JDBCAgent(); + try { + jdbcAgent.execute(sql, params); + return (Long) jdbcAgent.resultSetToMap().get("countsize"); + } catch (Exception e) { + System.out.println(e.getMessage()); + } finally { + jdbcAgent.close(); + } + return null; + } + + public void refreshForm(String id, String formNo, String formLoginName, HttpFormRestApiConfig config) throws BusinessException, IOException { + FormApi4Cap4 formApi4Cap4 = (FormApi4Cap4) AppContext.getBean("formApi4Cap4"); + FormBean cap4FormBean = formApi4Cap4.getFormByFormCode(formNo); + FormTableBean masterTableBean = cap4FormBean.getMasterTableBean(); + List dataList = new ArrayList<>(); + Map temp1 = new HashMap<>(); + Map temp2 = new HashMap<>(); + temp1.put("masterTable",temp2); + temp2.put("name",masterTableBean.getTableName()); + Map recordMap = new HashMap<>(3); // 容量=3 (2/0.75≈2.67) + recordMap.put("id", id); + recordMap.put("fields", new ArrayList<>()); + temp2.put("record", recordMap); + temp2.put("changedFields",new ArrayList<>()); + dataList.add(temp1); + String token = getToken(config.getTokenUrl(),config.getRestUserName(),config.getRestPwd(),formLoginName); + Map beanMap = new HashMap(); + beanMap.put("formCode", formNo); + beanMap.put("loginName", formLoginName); + beanMap.put("doTrigger", "true"); + beanMap.put("rightId", config.getRightId()); + beanMap.put("dataList",dataList); + Map header = new HashMap<>(); + header.put("token", token); + String url = config.getBaseUrl() + "/seeyon/rest/cap4/form/soap/batch-update"; + String response = HttpClient.httpPostRaw(url, JsonUtils.toJSONString(beanMap), header, "UTF-8"); + System.out.println(response); + } + private String getToken(String oatokenurl,String restName,String restPassword,String loginName) throws FileNotFoundException, IOException { + String address = oatokenurl + restName + "/" + restPassword; + if(StringUtil.isNotEmpty(loginName)){ + address = address +"?loginName="+loginName; + } + DefaultHttpClient client = new DefaultHttpClient(); + String result = ""; + HttpGet get = new HttpGet(address); + // 添加 Headers 信息 + get.addHeader(new BasicHeader("Accept", "application/json")); + try { + HttpResponse res = client.execute(get); + if (res.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { + result = EntityUtils.toString(res.getEntity()); + } + } catch (Exception e) { + throw new RuntimeException(e); + } + String token = ""; + if(result.contains("{")) { + JSONObject jsObj = JSONObject.parseObject(result); + token = jsObj.get("id").toString(); + }else { + token = result; + } + return token; + } + + public List queryFormDataCondition(String formNo, List queryColumnVos, List conditionVos) throws BusinessException { + FormApi4Cap4 formApi4Cap4 = (FormApi4Cap4) AppContext.getBean("formApi4Cap4"); + FormBean cap4FormBean = formApi4Cap4.getFormByFormCode(formNo); + List queryColumns = new ArrayList<>(); + FormTableBean masterTableBean = cap4FormBean.getMasterTableBean(); + String tableName = masterTableBean.getTableName(); + Map fieldMap4Name = masterTableBean.getFieldMap4Name(); + if (queryColumnVos != null) { + for (String queryColumnVo : queryColumnVos) { + FormFieldBean fieldBeanByDisplay = masterTableBean.getFieldBeanByDisplay(queryColumnVo); + if (fieldBeanByDisplay == null) { + continue; + } + queryColumns.add(fieldBeanByDisplay.getColumnName()); + } + } + for (FormWhereCondition conditionVo : conditionVos) { + FormFieldBean fieldBeanByDisplay = masterTableBean.getFieldBeanByDisplay(conditionVo.getDisplay()); + if (fieldBeanByDisplay == null) { + if (conditionVo.getDisplay().equals("ID") || conditionVo.getDisplay().equals("id")) { + conditionVo.setFieldName(conditionVo.getDisplay()); + } + continue; + } + conditionVo.setFieldName(fieldBeanByDisplay.getColumnName()); + } + + Map generateSql = generateSql(queryColumns, conditionVos, tableName); + String sql = (String) generateSql.get("sql"); + List params = (List) generateSql.get("params"); + JDBCAgent jdbcAgent = new JDBCAgent(); + List columns = new ArrayList<>(); + try { + jdbcAgent.execute(sql, params); + List list = jdbcAgent.resultSetToList(); + for (Object o : list) { + FormColumn column = new FormColumn(); + Map columnMap = (Map) o; + List vos = new ArrayList<>(); + for (String key : columnMap.keySet()) { + FormFieldVo fieldVo = new FormFieldVo(); + if (fieldMap4Name.containsKey(key)) { + FormFieldBean fieldBean = fieldMap4Name.get(key); + fieldVo.setDisplayName(fieldBean.getDisplay()); + fieldVo.setValue(columnMap.get(key)); + vos.add(fieldVo); + } + } + column.setVos(vos); + if (columnMap.get("id") != null) { + column.setId(columnMap.get("id") + ""); + } + columns.add(column); + } + return columns; + } catch (Exception e) { + System.out.println(e.getMessage()); + } finally { + jdbcAgent.close(); + } + return null; + } + + private Map generateSql(List conditions, String tableName) { + if (tableName == null) { + throw new IllegalArgumentException("tableName cannot be null or empty"); + } + StringBuilder sqlBuilder = new StringBuilder("SELECT count(*) as countSize "); + sqlBuilder.append(" from " + tableName); + List params = new ArrayList<>(); + sqlBuilder.append(buildWhereClause(conditions,params)); + Map result = new HashMap<>(); + result.put("sql", sqlBuilder.toString()); + result.put("params", params); + return result; + } + + private Map generateSql(List queryColumn, List conditions, String tableName) { + if (tableName == null) { + throw new IllegalArgumentException("tableName cannot be null or empty"); + } + StringBuilder sqlBuilder = new StringBuilder("SELECT "); + if (queryColumn == null || queryColumn.isEmpty()) { + sqlBuilder.append("*"); + } + + for (int i = 0; i < queryColumn.size(); i++) { + sqlBuilder.append(queryColumn.get(i)); + if (queryColumn.size() > 1 && i >= 0 && i < queryColumn.size() - 1) { + sqlBuilder.append(","); + } + } + + if (queryColumn.size() > 0) { + sqlBuilder.append(",`ID`"); + } + + sqlBuilder.append(" from " + tableName); + List params = new ArrayList<>(); + sqlBuilder.append(buildWhereClause(conditions,params)); + Map result = new HashMap<>(); + result.put("sql", sqlBuilder.toString()); + result.put("params", params); + return result; + } + + private Map generateSql(List fieldValues, String tableName, List conditions) { + if (fieldValues == null || fieldValues.isEmpty()) { + throw new IllegalArgumentException("Field values cannot be null or empty"); + } + if (tableName == null || tableName.trim().isEmpty()) { + throw new IllegalArgumentException("Table name cannot be null or empty"); + } + StringBuilder sqlBuilder = new StringBuilder("UPDATE ").append(tableName).append(" SET "); + List params = new ArrayList<>(); + // Build the SET clause + int fieldCount = 0; + for (FormUpdateField updateField : fieldValues) { + if (updateField.getValue() == null || "".equals(updateField.getValue()) || "null".equals(updateField.getValue())) { + continue; + } + if (fieldCount > 0) { + sqlBuilder.append(", "); + } + if (updateField.getValue() instanceof String && ((String) updateField.getValue()).startsWith("DATE>")) { + String oldValue = (String) updateField.getValue(); + sqlBuilder.append(updateField.getFieldName()).append(" = TO_DATE( ?, 'YYYY-MM-DD')"); + updateField.setValue(oldValue.substring(oldValue.indexOf(">") + 1)); + } else { + sqlBuilder.append(updateField.getFieldName()).append(" = ?"); + } + params.add(updateField.getValue()); + fieldCount++; + } + String whereClauseStr = buildWhereClause(conditions,params); + // Append the WHERE clause + sqlBuilder.append(whereClauseStr); + // Create result map + Map result = new HashMap<>(); + result.put("sql", sqlBuilder.toString()); + result.put("params", params); + return result; + } + + public Map> getMainFormTableAttachments(String formNo,Map sourceMap) throws BusinessException { + FormApi4Cap4 formApi4Cap4 = (FormApi4Cap4) AppContext.getBean("formApi4Cap4"); + FormBean cap4FormBean = formApi4Cap4.getFormByFormCode(formNo); + FormTableBean masterTableBean = cap4FormBean.getMasterTableBean(); + Map> attachmentTempMap = new HashMap<>(); + Set removeKey = new HashSet<>(); + for (String key : sourceMap.keySet()) { + FormFieldBean fieldBeanByDisplay = masterTableBean.getFieldBeanByDisplay(key); + if(fieldBeanByDisplay == null ){ + continue; + } + if(fieldBeanByDisplay.getInputType().equals("image") || + fieldBeanByDisplay.getInputType().equals("attachment")) { + attachmentTempMap.put(fieldBeanByDisplay.getDisplay(),(List)sourceMap.get(key)); + removeKey.add(key); + } + } + for (String key : removeKey) { + sourceMap.remove(key); + } + return attachmentTempMap; + } + + public Map> getSubFormTableAttachments(String formNo,Map sourceMap) throws BusinessException { + FormApi4Cap4 formApi4Cap4 = (FormApi4Cap4) AppContext.getBean("formApi4Cap4"); + FormBean cap4FormBean = formApi4Cap4.getFormByFormCode(formNo); + List subTableBean = cap4FormBean.getSubTableBean(); + Map> attachmentTempMap = new HashMap<>(); + String tableName = null; + for (String key : sourceMap.keySet()) { + tableName = key; + } + String finalTableName = tableName; + FormTableBean tableBean = subTableBean.stream().filter(s->s.getTableName().equals(finalTableName)).collect(Collectors.toList()).get(0); + List> tableData = (List>)sourceMap.get(tableName); + Set removeKey = new HashSet<>(); + for (Map rowData : tableData) { + for (String key : rowData.keySet()) { + FormFieldBean fieldBeanByDisplay = tableBean.getFieldBeanByDisplay(key); + if(fieldBeanByDisplay == null ){ + continue; + } + if(fieldBeanByDisplay.getInputType().equals("image") || + fieldBeanByDisplay.getInputType().equals("attachment")) { + attachmentTempMap.put(fieldBeanByDisplay.getDisplay(),(List)sourceMap.get(key)); + removeKey.add(key); + } + } + for (String key : removeKey) { + rowData.remove(key); + } + removeKey.clear(); + } + return attachmentTempMap; + } + + public void addSubTableRecord(String subTableName,List data,String formNo,String formId) { + JDBCAgent agent = new JDBCAgent(); + try { + FormApi4Cap4 formApi4Cap4 = (FormApi4Cap4) AppContext.getBean("formApi4Cap4"); + FormBean cap4FormBean = formApi4Cap4.getFormByFormCode(formNo); + List tableBean = cap4FormBean.getSubTableBean(); + for (FormTableBean bean : tableBean) { + if(!bean.getTableName().equals(subTableName)) { + continue; + } + for (Object column : data) { + Map map = (Map) column; + Map tempMap = new HashMap<>(); + for (String key : map.keySet()) { + FormFieldBean fieldBeanByDisplay = bean.getFieldBeanByDisplay(key); + if(fieldBeanByDisplay == null) { + continue; + } + tempMap.put(fieldBeanByDisplay.getColumnName(),map.get(key)); + } + tempMap.put("formmain_id",formId); + tempMap.put("sort",1); + tempMap.put("ID",Math.abs(UUID.randomUUID().getLeastSignificantBits())); + Map insertSql = generateInsertSql(tempMap, subTableName); + agent.execute((String)insertSql.get("sql"),(List)insertSql.get("params")); + } + } + } catch (Exception e) { + + } finally { + agent.close(); + } + } + + public void rebuildSubTableRecord(String subTableName,List data,String formNo,String formId) { + String deleteSql = "delete from " + subTableName + " where formmain_id = ? "; + JDBCAgent agent = new JDBCAgent(); + try { + agent.execute(deleteSql, Arrays.asList(formId)); + FormApi4Cap4 formApi4Cap4 = (FormApi4Cap4) AppContext.getBean("formApi4Cap4"); + FormBean cap4FormBean = formApi4Cap4.getFormByFormCode(formNo); + List tableBean = cap4FormBean.getSubTableBean(); + for (FormTableBean bean : tableBean) { + if(!bean.getTableName().equals(subTableName)) { + continue; + } + for (Object column : data) { + Map map = (Map) column; + Map tempMap = new HashMap<>(); + for (String key : map.keySet()) { + FormFieldBean fieldBeanByDisplay = bean.getFieldBeanByDisplay(key); + if(fieldBeanByDisplay == null) { + continue; + } + tempMap.put(fieldBeanByDisplay.getColumnName(),map.get(key)); + } + tempMap.put("formmain_id",formId); + tempMap.put("sort",1); + tempMap.put("ID",Math.abs(UUID.randomUUID().getLeastSignificantBits())); + Map insertSql = generateInsertSql(tempMap, subTableName); + agent.execute((String)insertSql.get("sql"),(List)insertSql.get("params")); + } + } + } catch (Exception e) { + + } finally { + agent.close(); + } + } + + public void handleEnumDeptEtc(Map map,String formNo) throws BusinessException { + FormApi4Cap4 formApi4Cap4 = (FormApi4Cap4) AppContext.getBean("formApi4Cap4"); + FormBean cap4FormBean = formApi4Cap4.getFormByFormCode(formNo); + FormTableBean masterTableBean = cap4FormBean.getMasterTableBean(); + for (String key : map.keySet()) { + FormFieldBean fieldBean = masterTableBean.getFieldBeanByDisplay(key); + if(fieldBean == null) { + continue; + } + switch (fieldBean.getInputType()) { + case "select": if(fieldBean.getEnumId() != 0l) { + String enumItemId = EnumMapUtils.getEnumItemValueByEnumId((String)map.get(key),fieldBean.getEnumId()); + map.put(key,enumItemId); + } break; + case "image":break; + case "attachment": break; + case "account": break; + case "department": break; + case "radio": break; + case "member":break; + case "checkbox": + case "date": + case "text":break; + default: break; + + } + } + } + + public void handleSubTableEnumDeptEtc(Map map,String formNo) throws BusinessException { + FormApi4Cap4 formApi4Cap4 = (FormApi4Cap4) AppContext.getBean("formApi4Cap4"); + FormBean cap4FormBean = formApi4Cap4.getFormByFormCode(formNo); + List subTableBean = cap4FormBean.getSubTableBean(); + for (FormTableBean tableBean : subTableBean) { + String tableName = null; + for (String key : map.keySet()) { + tableName = key; + } + if(!tableBean.getTableName().equals(tableName)) { + continue; + } + List> subDatas = (List>) map.get(tableName); + for (Map subData : subDatas) { + for (String key : subData.keySet()) { + FormFieldBean fieldBean = tableBean.getFieldBeanByDisplay(key); + if(fieldBean == null) { + continue; + } + switch (fieldBean.getInputType()) { + case "select": if(fieldBean.getEnumId() != 0l) { + String enumItemId = EnumMapUtils.getEnumItemValueByEnumId((String)subData.get(key),fieldBean.getEnumId()); + subData.put(key,enumItemId); + } break; + case "image":break; + case "attachment": break; + case "account": break; + case "department": break; + case "radio": break; + case "member":break; + case "checkbox": + case "date": + case "text":break; + default: break; + + } + } + } + } + } + + public boolean isMasterTableFile(String displayName,String formNo) { + FormApi4Cap4 formApi4Cap4 = (FormApi4Cap4) AppContext.getBean("formApi4Cap4"); + try { + FormBean cap4FormBean = formApi4Cap4.getFormByFormCode(formNo); + FormTableBean masterTableBean = cap4FormBean.getMasterTableBean(); + FormFieldBean fieldBeanByDisplay = masterTableBean.getFieldBeanByDisplay(displayName); + return fieldBeanByDisplay.getInputType().equals("image") || fieldBeanByDisplay.getInputType().equals("attachment"); + } catch (BusinessException e) { + + } + return false; + } + + private Map generateInsertSql(Map data, String tableName) { + if (tableName == null || tableName.isEmpty()) { + throw new IllegalArgumentException("tableName cannot be null or empty"); + } + if (data == null || data.isEmpty()) { + throw new IllegalArgumentException("data cannot be null or empty"); + } + StringBuilder sqlBuilder = new StringBuilder("INSERT INTO " + tableName + " ("); + List params = new ArrayList<>(); + // 拼接字段名 + StringBuilder columns = new StringBuilder(); + // 拼接字段值 + StringBuilder values = new StringBuilder(); + for (Map.Entry entry : data.entrySet()) { + // 拼接字段名 + if (columns.length() > 0) { + columns.append(", "); + } + columns.append(entry.getKey()); + // 拼接值,使用占位符 ? + if (values.length() > 0) { + values.append(", "); + } + values.append("?"); + // 将值加入 params 列表 + params.add(entry.getValue()); + } + // 完善 SQL 语句 + sqlBuilder.append(columns).append(") VALUES (").append(values).append(");"); + Map result = new HashMap<>(); + result.put("sql", sqlBuilder.toString()); + result.put("params", params); + return result; + } + + /** + * 动态生成 WHERE 子句 + * @param conditions 条件集合 + * @param params 参数列表(引用传递) + * @return 拼接后的 WHERE 子句(包含 WHERE 关键字) + */ + private String buildWhereClause(List conditions, List params) { + if (conditions == null || conditions.isEmpty()) { + return ""; + } + + StringBuilder whereClause = new StringBuilder(" WHERE "); + int conditionIndex = 0; + + for (FormWhereCondition condition : conditions) { + // 处理括号起始 + if (condition.isStartWithBracket()) { + whereClause.append("("); + } + + // 字段名校验 + String fieldName = condition.getFieldName(); + ClauseFactor factor = condition.getClauseFactor(); + String operator = parseOperator(factor); + + // 构建条件表达式 + String conditionExpr; + if (factor != null && factor.isNullType()) { + // 处理 NULL/NOT NULL 条件(无需参数) + conditionExpr = String.format("%s %s", fieldName, operator); + } else { + // 处理普通条件(带占位符) + conditionExpr = String.format("%s %s ?", fieldName, operator); + // 处理函数模板(如 TO_DATE) + if (condition.getIndex() != null) { + conditionExpr = conditionExpr.replace("?", condition.getIndex()); + } + // 添加参数值 + params.add(condition.getValue()); + } + + whereClause.append(conditionExpr); + + // 处理括号闭合 + if (condition.isEndWithBracket()) { + whereClause.append(")"); + } + + // 添加连接符(AND/OR) + if (conditionIndex < conditions.size() - 1) { + whereClause.append(" ").append(condition.getConcatFactor()).append(" "); + } + conditionIndex++; + } + + return whereClause.toString(); + } + + /** + * 校验字段名合法性(防止 SQL 注入) + */ + private String validateFieldName(String fieldName) { + if (!fieldName.matches("^[a-zA-Z_][a-zA-Z0-9_]*$")) { + throw new IllegalArgumentException("非法字段名: " + fieldName); + } + return fieldName; + } + + /** + * 解析运算符映射(eq -> =, lt -> < 等) + */ + private String parseOperator(ClauseFactor factor) { + if(factor == null) { + return "="; + } + switch (factor) { + case EQ: return "="; + case GT: return ">"; + case GE: return ">="; + case LT: return "<"; + case LE: return "<="; + case LIKE: return "LIKE"; + case NULL: return "IS NULL"; // 空值判断 + case NOT_NULL: return "IS NOT NULL"; // 非空判断 + default: throw new UnsupportedOperationException("不支持的运算符: " + factor); + } + } + + +} \ No newline at end of file diff --git a/v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/utils/FormExportUtil.java b/v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/utils/FormExportUtil.java new file mode 100644 index 0000000..67e6d57 --- /dev/null +++ b/v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/utils/FormExportUtil.java @@ -0,0 +1,84 @@ +package com.seeyon.apps.src_saomaoyi.utils; + +import com.seeyon.v3x.services.form.bean.RecordExport; +import com.seeyon.v3x.services.form.bean.SubordinateFormExport; +import com.seeyon.v3x.services.form.bean.ValueExport; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +//创建无流程表单数据处理工具类 +public class FormExportUtil { + + /** + * 设置主表信息 + * @param map 设置主表字段。Map<主表显示名称,主表数据> + * @return + */ + public List setFormValue(Map map ){ +// 创建返回值对象 + List valueExports = new ArrayList(); + ValueExport valueExport ; +// 获取参数信息(显示名称) + Set keys = map.keySet(); + if(keys.size()>0) { +// 对控件赋值 + for (String key : keys) { + if(map.get(key) != null ){ + valueExport = new ValueExport(); + valueExport.setDisplayName(key); + valueExport.setValue(map.get(key).toString()); + valueExports.add(valueExport); + } + System.out.println(key+":"+map.get(key)); + } + } + return valueExports; + } + + /** + * 设置从表信息 + * @param lists 设置主表字段。List> + */ + public List setSubordinateFormValue(List> lists){ + List subordinateFormExports = new ArrayList(); + SubordinateFormExport subordinateFormExport = new SubordinateFormExport(); + List recordExports = new ArrayList(); + List valueExports; + RecordExport recordExport; + for(int i = 0 ; i < lists.size() ; i++) { + recordExport = new RecordExport(); + valueExports = setFormValue(lists.get(i)); + recordExport.setRecord(valueExports); + recordExports.add(recordExport); + } + subordinateFormExport.setValues(recordExports); + subordinateFormExports.add(subordinateFormExport); + + return subordinateFormExports; + } + + public List setAllSubordinateFormValue(List> lists){ + List subordinateFormExports = new ArrayList(); + for (Map list : lists) { + SubordinateFormExport subordinateFormExport = new SubordinateFormExport(); + List recordExports = new ArrayList(); + for (String key : list.keySet()) { + List> columns = (List>) list.get(key); + for(int i = 0 ; i < columns.size() ; i++) { + List valueExports = setFormValue(columns.get(i)); + RecordExport recordExport = new RecordExport(); + recordExport.setRecord(valueExports); + recordExports.add(recordExport); + } + } + subordinateFormExport.setValues(recordExports); + subordinateFormExports.add(subordinateFormExport); + } + return subordinateFormExports; + } + + +} diff --git a/v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/utils/FormFieldVo.java b/v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/utils/FormFieldVo.java new file mode 100644 index 0000000..16e3b51 --- /dev/null +++ b/v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/utils/FormFieldVo.java @@ -0,0 +1,22 @@ +package com.seeyon.apps.src_saomaoyi.utils; + +public class FormFieldVo { + private String displayName; + private Object value; + + public String getDisplayName() { + return displayName; + } + + public void setDisplayName(String displayName) { + this.displayName = displayName; + } + + public Object getValue() { + return value; + } + + public void setValue(Object value) { + this.value = value; + } +} diff --git a/v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/utils/FormUpdateField.java b/v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/utils/FormUpdateField.java new file mode 100644 index 0000000..af70603 --- /dev/null +++ b/v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/utils/FormUpdateField.java @@ -0,0 +1,57 @@ +package com.seeyon.apps.src_saomaoyi.utils; + +public class FormUpdateField { + private String display; + private String fieldName; + private Object value; + + public FormUpdateField(Object value) { + this.value = value; + } + + public FormUpdateField() { + } + + public static FormUpdateField build() { + return new FormUpdateField(); + } + + public FormUpdateField display(String display) { + this.display = display; + return this; + } + + public FormUpdateField value(String value) { + this.value = value; + return this; + } + + public FormUpdateField fieldName(String fieldName) { + this.fieldName = fieldName; + return this; + } + + public Object getValue() { + return value; + } + + public void setValue(Object value) { + this.value = value; + } + + public String getDisplay() { + return display; + } + + public void setDisplay(String display) { + this.display = display; + } + + public String getFieldName() { + return fieldName; + } + + public void setFieldName(String fieldName) { + this.fieldName = fieldName; + } +} diff --git a/v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/utils/FormWhereCondition.java b/v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/utils/FormWhereCondition.java new file mode 100644 index 0000000..0415821 --- /dev/null +++ b/v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/utils/FormWhereCondition.java @@ -0,0 +1,121 @@ +package com.seeyon.apps.src_saomaoyi.utils; + +public class FormWhereCondition { + private String display; + private String fieldName; //字段名 + private Object value; //值 + private ClauseFactor clauseFactor; //条件因子 eq lt gt not_null null + private ClauseFactor concatFactor = ClauseFactor.AND; //拼接因子 + private boolean startWithBracket = false; //是否以括号开头生成子条件 + private boolean endWithBracket = false; //是否以括号结尾结束子条件 + private String index; + + public FormWhereCondition() { + } + + public String getDisplay() { + return display; + } + + public void setDisplay(String display) { + this.display = display; + } + + public static FormWhereCondition build() { + return new FormWhereCondition(); + } + + public FormWhereCondition display(String display) { + this.display = display; + return this; + } + public FormWhereCondition value(Object value) { + this.value = value; + return this; + } + public FormWhereCondition clauseFactor(ClauseFactor clauseFactor) { + this.clauseFactor = clauseFactor; + return this; + } + public FormWhereCondition index(String index) { + this.index = index; + return this; + } + + public FormWhereCondition startWithBracket(boolean startWithBracket) { + this.startWithBracket = startWithBracket; + return this; + } + + public FormWhereCondition endWithBracket(boolean endWithBracket) { + this.endWithBracket = endWithBracket; + return this; + } + + public FormWhereCondition concatFactor(ClauseFactor concatFactor) { + this.concatFactor = concatFactor; + return this; + } + + + public FormWhereCondition(Object value, ClauseFactor clauseFactor) { + this.value = value; + this.clauseFactor = clauseFactor; + } + + public boolean isStartWithBracket() { + return startWithBracket; + } + + public void setStartWithBracket(boolean startWithBracket) { + this.startWithBracket = startWithBracket; + } + + public String getFieldName() { + return fieldName; + } + + public void setFieldName(String fieldName) { + this.fieldName = fieldName; + } + + public Object getValue() { + return value; + } + + public void setValue(Object value) { + this.value = value; + } + + public ClauseFactor getClauseFactor() { + return clauseFactor; + } + + public void setClauseFactor(ClauseFactor clauseFactor) { + this.clauseFactor = clauseFactor; + } + + public ClauseFactor getConcatFactor() { + return concatFactor; + } + + public void setConcatFactor(ClauseFactor concatFactor) { + this.concatFactor = concatFactor; + } + + public String getIndex() { + return index; + } + + public void setIndex(String index) { + this.index = index; + } + + public boolean isEndWithBracket() { + return endWithBracket; + } + + public void setEndWithBracket(boolean endWithBracket) { + this.endWithBracket = endWithBracket; + } +} diff --git a/v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/utils/HttpClient.java b/v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/utils/HttpClient.java new file mode 100644 index 0000000..fe865a2 --- /dev/null +++ b/v5/apps-customize/src/main/java/com/seeyon/apps/src_saomaoyi/utils/HttpClient.java @@ -0,0 +1,417 @@ +package com.seeyon.apps.src_saomaoyi.utils; + +import org.apache.http.HttpEntity; +import org.apache.http.NameValuePair; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.*; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.entity.mime.HttpMultipartMode; +import org.apache.http.entity.mime.MultipartEntityBuilder; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; + +import java.io.*; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * @ClassName: HttpClient + * @Description: HTTP请求工具类 + * @Author: GiikJc + * @Date: 2022/7/12 15:03 + */ + +/** + * 发送Get请求:HttpResponse httpGet(String url,Map headers,String encode) + *发送Post请求,同表单Post提交:HttpResponse httpPostForm(String url,Map params, Map headers,String encode) + *发送Post Raw请求:HttpResponse httpPostRaw(String url,String stringJson,Map headers, String encode) + *发送Put Raw请求:HttpResponse httpPutRaw(String url,String stringJson,Map headers, String encode) + *发送Delete请求:HttpResponse httpDelete(String url,Map headers,String encode) + */ +public class HttpClient { + + + /** + * 发送 HTTP GET 请求下载文件 + * @param url 下载文件的 URL + * @param headers 请求头 + * @param savePath 文件保存的路径 + * @param encode 文件内容的编码 + * @return 下载成功返回 true,失败返回 false + */ + public static boolean httpDownloadFile(String url, Map headers, String savePath, String encode) { + if (encode == null) { + encode = "utf-8"; // 默认字符编码 + } + + CloseableHttpClient httpClient = null; + CloseableHttpResponse httpResponse = null; + InputStream inputStream = null; + OutputStream outputStream = null; + + try { + // 创建 HttpClient 实例 + httpClient = HttpClients.createDefault(); + HttpGet httpGet = new HttpGet(url); + + // 设置请求头 + if (headers != null && headers.size() > 0) { + for (Map.Entry entry : headers.entrySet()) { + httpGet.setHeader(entry.getKey(), entry.getValue()); + } + } + + // 执行请求 + httpResponse = httpClient.execute(httpGet); + HttpEntity entity = httpResponse.getEntity(); + + // 检查响应状态码 + if (httpResponse.getStatusLine().getStatusCode() == 200) { + inputStream = entity.getContent(); + + // 创建输出流,将文件保存到本地 + outputStream = new FileOutputStream(savePath); + + // 设置缓冲区 + byte[] buffer = new byte[4096]; + int bytesRead; + while ((bytesRead = inputStream.read(buffer)) != -1) { + outputStream.write(buffer, 0, bytesRead); + } + + // 文件下载成功 + return true; + } else { + System.out.println("Download failed, HTTP error code: " + httpResponse.getStatusLine().getStatusCode()); + return false; + } + } catch (Exception e) { + e.printStackTrace(); + return false; + } finally { + try { + if (inputStream != null) { + inputStream.close(); + } + if (outputStream != null) { + outputStream.close(); + } + if (httpResponse != null) { + httpResponse.close(); + } + if (httpClient != null) { + httpClient.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + /** + * 发送http get请求 + */ + public static String httpGet(String url,Map headers,String encode){ + + if(encode == null){ + encode = "utf-8"; + } + CloseableHttpResponse httpResponse = null; + CloseableHttpClient closeableHttpClient = null; + String content = null; + //since 4.3 不再使用 DefaultHttpClient + try { + closeableHttpClient = HttpClientBuilder.create().build(); + HttpGet httpGet = new HttpGet(url); + //设置header + if (headers != null && headers.size() > 0) { + for (Map.Entry entry : headers.entrySet()) { + httpGet.setHeader(entry.getKey(),entry.getValue()); + } + } + + httpResponse = closeableHttpClient.execute(httpGet); + HttpEntity entity = httpResponse.getEntity(); + content = EntityUtils.toString(entity, encode); + } catch (Exception e) { + e.printStackTrace(); + }finally{ + try { + httpResponse.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + try { //关闭连接、释放资源 + closeableHttpClient.close(); + } catch (IOException e) { + e.printStackTrace(); + } + return content; + } + /** + * 发送 http post 请求,参数以form表单键值对的形式提交。 + */ + public static String httpPostForm(String url,Map params, Map headers,String encode){ + + if(encode == null){ + encode = "utf-8"; + } + + String content = null; + CloseableHttpResponse httpResponse = null; + CloseableHttpClient closeableHttpClient = null; + try { + + closeableHttpClient = HttpClients.createDefault(); + HttpPost httpost = new HttpPost(url); + + //设置header + if (headers != null && headers.size() > 0) { + for (Map.Entry entry : headers.entrySet()) { + httpost.setHeader(entry.getKey(),entry.getValue()); + } + } + //组织请求参数 + List paramList = new ArrayList (); + if(params != null && params.size() > 0){ + Set keySet = params.keySet(); + for(String key : keySet) { + paramList.add(new BasicNameValuePair(key, params.get(key))); + } + } + httpost.setEntity(new UrlEncodedFormEntity(paramList, encode)); + + + httpResponse = closeableHttpClient.execute(httpost); + HttpEntity entity = httpResponse.getEntity(); + content = EntityUtils.toString(entity, encode); + } catch (Exception e) { + e.printStackTrace(); + }finally{ + try { + httpResponse.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + try { //关闭连接、释放资源 + closeableHttpClient.close(); + } catch (IOException e) { + e.printStackTrace(); + } + return content; + } + + /** + * 发送 http post 请求,参数以原生字符串进行提交 + * @param url + * @param encode + * @return + */ + public static String httpPostRaw(String url,String stringJson,Map headers, String encode){ + if(encode == null){ + encode = "utf-8"; + } + String content = null; + CloseableHttpResponse httpResponse = null; + CloseableHttpClient closeableHttpClient = null; + try { + + //HttpClients.createDefault()等价于 HttpClientBuilder.create().build(); + closeableHttpClient = HttpClients.createDefault(); + HttpPost httpost = new HttpPost(url); + + //设置header + httpost.setHeader("Content-type", "application/json"); + if (headers != null && headers.size() > 0) { + for (Map.Entry entry : headers.entrySet()) { + httpost.setHeader(entry.getKey(),entry.getValue()); + } + } + //组织请求参数 + StringEntity stringEntity = new StringEntity(stringJson, encode); + httpost.setEntity(stringEntity); + + + //响应信息 + httpResponse = closeableHttpClient.execute(httpost); + HttpEntity entity = httpResponse.getEntity(); + content = EntityUtils.toString(entity, encode); + } catch (Exception e) { + e.printStackTrace(); + }finally{ + try { + httpResponse.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + try { //关闭连接、释放资源 + closeableHttpClient.close(); + } catch (IOException e) { + e.printStackTrace(); + } + return content; + } + + /** + * 发送 http put 请求,参数以原生字符串进行提交 + * @param url + * @param encode + * @return + */ + public static String httpPutRaw(String url,String stringJson,Map headers, String encode){ + if(encode == null){ + encode = "utf-8"; + } + CloseableHttpResponse httpResponse = null; + CloseableHttpClient closeableHttpClient = null; + String content = null; + //since 4.3 不再使用 DefaultHttpClient + try { + + //HttpClients.createDefault()等价于 HttpClientBuilder.create().build(); + closeableHttpClient = HttpClients.createDefault(); + HttpPut httpput = new HttpPut(url); + + //设置header + httpput.setHeader("Content-type", "application/json"); + if (headers != null && headers.size() > 0) { + for (Map.Entry entry : headers.entrySet()) { + httpput.setHeader(entry.getKey(),entry.getValue()); + } + } + //组织请求参数 + StringEntity stringEntity = new StringEntity(stringJson, encode); + httpput.setEntity(stringEntity); + //响应信息 + httpResponse = closeableHttpClient.execute(httpput); + HttpEntity entity = httpResponse.getEntity(); + content = EntityUtils.toString(entity, encode); + } catch (Exception e) { + e.printStackTrace(); + }finally{ + try { + httpResponse.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + try { + closeableHttpClient.close(); //关闭连接、释放资源 + } catch (IOException e) { + e.printStackTrace(); + } + return content; + } + /** + * 发送http delete请求 + */ + public static String httpDelete(String url,Map headers,String encode){ + if(encode == null){ + encode = "utf-8"; + } + String content = null; + CloseableHttpResponse httpResponse = null; + CloseableHttpClient closeableHttpClient = null; + try { + //since 4.3 不再使用 DefaultHttpClient + closeableHttpClient = HttpClientBuilder.create().build(); + HttpDelete httpdelete = new HttpDelete(url); + //设置header + if (headers != null && headers.size() > 0) { + for (Map.Entry entry : headers.entrySet()) { + httpdelete.setHeader(entry.getKey(),entry.getValue()); + } + } + + httpResponse = closeableHttpClient.execute(httpdelete); + HttpEntity entity = httpResponse.getEntity(); + content = EntityUtils.toString(entity, encode); + } catch (Exception e) { + e.printStackTrace(); + }finally{ + try { + httpResponse.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + try { //关闭连接、释放资源 + closeableHttpClient.close(); + } catch (IOException e) { + e.printStackTrace(); + } + return content; + } + + /** + * 发送 http post 请求,支持文件上传 + */ + public static String httpPostFormMultipart(String url,Map params, List files,Map headers,String encode){ + if(encode == null){ + encode = "utf-8"; + } + CloseableHttpResponse httpResponse = null; + CloseableHttpClient closeableHttpClient = null; + String content = null; + //since 4.3 不再使用 DefaultHttpClient + try { + + closeableHttpClient = HttpClients.createDefault(); + HttpPost httpost = new HttpPost(url); + + //设置header + if (headers != null && headers.size() > 0) { + for (Map.Entry entry : headers.entrySet()) { + httpost.setHeader(entry.getKey(),entry.getValue()); + } + } + MultipartEntityBuilder mEntityBuilder = MultipartEntityBuilder.create(); + mEntityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE); + mEntityBuilder.setCharset(Charset.forName(encode)); + + // 普通参数 + ContentType contentType = ContentType.create("text/plain",Charset.forName(encode));//解决中文乱码 + if (params != null && params.size() > 0) { + Set keySet = params.keySet(); + for (String key : keySet) { + mEntityBuilder.addTextBody(key, params.get(key),contentType); + } + } + //二进制参数 + if (files != null && files.size() > 0) { + for (File file : files) { + mEntityBuilder.addBinaryBody("file", file); + } + } + httpost.setEntity(mEntityBuilder.build()); + httpResponse = closeableHttpClient.execute(httpost); + HttpEntity entity = httpResponse.getEntity(); + content = EntityUtils.toString(entity, encode); + } catch (Exception e) { + e.printStackTrace(); + }finally{ + try { + httpResponse.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + try { //关闭连接、释放资源 + closeableHttpClient.close(); + } catch (IOException e) { + e.printStackTrace(); + } + return content; + } + +} diff --git a/v5/apps-customize/src/main/java/com/seeyon/ctp/rest/resources/HandleSaoMiaoYiImgResource.java b/v5/apps-customize/src/main/java/com/seeyon/ctp/rest/resources/HandleSaoMiaoYiImgResource.java new file mode 100644 index 0000000..4a8138b --- /dev/null +++ b/v5/apps-customize/src/main/java/com/seeyon/ctp/rest/resources/HandleSaoMiaoYiImgResource.java @@ -0,0 +1,57 @@ +package com.seeyon.ctp.rest.resources; + +import com.seeyon.apps.src_saomaoyi.invoice.InvoiceImgSaveService; +import com.seeyon.ctp.common.AppContext; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.MultipartHttpServletRequest; +import org.springframework.web.multipart.commons.CommonsMultipartResolver; + +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.Response; +import java.io.InputStream; +import java.util.Iterator; + +@Path("/saomiaoyi") +@Produces({"application/json", "application/xml"}) +public class HandleSaoMiaoYiImgResource extends BaseResource { + + private InvoiceImgSaveService invoiceImgSaveService = (InvoiceImgSaveService) AppContext.getBean("invoiceImgSaveServiceImpl"); + + @Context + HttpServletRequest req; + + @POST + @Path("/fileSave") + @Produces({"application/json"}) + @Consumes({"multipart/form-data"}) + public Response fileSave() { + try { + CommonsMultipartResolver resolver = new CommonsMultipartResolver(); + resolver.setDefaultEncoding("utf-8"); + if (resolver.isMultipart(req)) { + MultipartHttpServletRequest multipartRequest = resolver.resolveMultipart(req); + + // 获取所有文件名 + Iterator fileNames = multipartRequest.getFileNames(); + + while (fileNames.hasNext()) { + String name = fileNames.next(); + MultipartFile file = multipartRequest.getFile(name); + if (file != null && !file.isEmpty()) { + InputStream inputStream = file.getInputStream(); + invoiceImgSaveService.saveInvoiceImg(inputStream); + inputStream.close(); + } + } + } + return success(""); + }catch (Exception e) { + return fail(e.getMessage()); + } + } +} diff --git a/v5/apps-customize/src/main/test/TestB.java b/v5/apps-customize/src/main/test/TestB.java new file mode 100644 index 0000000..2199405 --- /dev/null +++ b/v5/apps-customize/src/main/test/TestB.java @@ -0,0 +1,8 @@ +import com.seeyon.apps.src_saomaoyi.invoice.InvoiceImgSaveServiceImpl; + +public class TestB { + + public static void main(String[] args) { + InvoiceImgSaveServiceImpl saveService = new InvoiceImgSaveServiceImpl(); + } +} diff --git a/v5/apps-customize/src/main/webapp/WEB-INF/cfgHome/plugin/src_saomiaoyi/pluginCfg.xml b/v5/apps-customize/src/main/webapp/WEB-INF/cfgHome/plugin/src_saomiaoyi/pluginCfg.xml new file mode 100644 index 0000000..5f6a29f --- /dev/null +++ b/v5/apps-customize/src/main/webapp/WEB-INF/cfgHome/plugin/src_saomiaoyi/pluginCfg.xml @@ -0,0 +1,6 @@ + + + src_saomiaoyi + 扫描仪 + 20251201 + \ No newline at end of file diff --git a/v5/apps-customize/src/main/webapp/WEB-INF/cfgHome/plugin/src_saomiaoyi/spring/spring-bean.xml b/v5/apps-customize/src/main/webapp/WEB-INF/cfgHome/plugin/src_saomiaoyi/spring/spring-bean.xml new file mode 100644 index 0000000..19d4cd3 --- /dev/null +++ b/v5/apps-customize/src/main/webapp/WEB-INF/cfgHome/plugin/src_saomiaoyi/spring/spring-bean.xml @@ -0,0 +1,12 @@ + + + + + \ No newline at end of file diff --git a/v5/apps-customize/src/main/webapp/WEB-INF/cfgHome/plugin/src_saomiaoyi/spring/spring-quartz.xml b/v5/apps-customize/src/main/webapp/WEB-INF/cfgHome/plugin/src_saomiaoyi/spring/spring-quartz.xml new file mode 100644 index 0000000..f701d88 --- /dev/null +++ b/v5/apps-customize/src/main/webapp/WEB-INF/cfgHome/plugin/src_saomiaoyi/spring/spring-quartz.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/v5/apps-customize/src/main/webapp/WEB-INF/cfgHome/plugin/src_saomiaoyi/spring/spring.xml b/v5/apps-customize/src/main/webapp/WEB-INF/cfgHome/plugin/src_saomiaoyi/spring/spring.xml new file mode 100644 index 0000000..fad8443 --- /dev/null +++ b/v5/apps-customize/src/main/webapp/WEB-INF/cfgHome/plugin/src_saomiaoyi/spring/spring.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/v5/apps-customize/src/main/webapp/apps_res/cap/customCtrlResources/saomiaoyiBtnResources/css/img/icon16.png b/v5/apps-customize/src/main/webapp/apps_res/cap/customCtrlResources/saomiaoyiBtnResources/css/img/icon16.png new file mode 100644 index 0000000000000000000000000000000000000000..e43def3b7a2d46b32ea439d5f5e133a03204e1f6 GIT binary patch literal 103273 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 z zX72LN*Y>(-sf`uxb$Cy&@}jV%{({3fhC*;^4zcYX2<iCqI=~=B9GG9<8N5TU4}5*y3ev8B3f?QF44_7Q zC9hLMT&}9>h*R`kO|K97JjPD)o!93h{=JhIV*XTPRf+-c=u>?)EolTjdtp8+-${P7 z@@ZabVvqx@pzcZ@#J|63VW28hG4}wLq@-SX(bBKyEa`OhRhRwQ=bFxc;hCEJsPY2M-f7hn$A*Qv6qdzY1Ku~{=DVw%vB8QC zk*YGYsc2jPr5n$*p}2~bpI1D}pZL$}5}5r5cmR?mPaQvlGo!2X| zg*fvReb=H~|0G)O^Zly-N;K`y<1bhjRCOM%o2T$BjQ3ANlVX&IawzEu302MM@q-8h zt%g5a@ZqK$^0ld5PJT6KY1wP9>T=?XIZMvR6DZfEc3J-A>?P%TWnXI=dBp* z!s;gblAJEG^U(?)mq6@4MF9k-+sZ`1z8TlQ#7$|q>2`&}_(I%;AnAkx8&^rIFkX46aa;y(PSo0Q&M$i_k4xTG0XWFr|TQ7y>P>2iN~c*RO0YE zvUM0q80YD_eg;}@vk|}hB6!o(LZ8}Lk|46!a`ssQm-e{w3_-u&4?aav{dhn;Zfl6g zwo~-F@x6ryKuRD3t^MRaS9QtcZDkPrGtbmUL{UBn?B9T%%-t!}NY}TJ6YQ!VkKo->SsJ_} z267#X@EoV~`fp7L=tTmk>8^=HRUh!hDak1W^fobzk#>j_QHIBml77za`dzzr%@P0> zLFnh{kgfboV^A585*&q!K}*ko>&dJbXpF#TxZM&w5!`=9&~M4cPjeHX{TBD1kH?9S z+#^gW$x%gdZY*>z3tZN$e&`;>8|uR)Q2B46fJ#Ij?Q52z*^M$1KPisAZxL=KqU%di z)a$zv9q4%iYY)v*hhUwpXv;PdOiX@MQKsL z6?GQ(!Sx?liP7j|>hqusu3tEv3&EZGuUa6`Q@U>v^l(!03gvd&4)ie50#?P8!-qP6 zKQNq@2DK5b+L$f*I7zvvnz1lc$&|cKI@b=|R*5|tpTVQZL&cz{l2DWt`FZ(!>OOx| z9zC=T7gii9KDR2Ou>g-%P?nb<&FPntY@j9b{~|OMV=aech|20$#B)$gd~K_p2>Jx9 z6ta0gTkr&^GzT+{U->YSTtIe$O2TY2DWV5WwmoE`Y-ptK*ZA{N_9W!zyoTu{vyR*Y zr~qmR9BKH{@tX2ZpI5nBRa9-bCwhkO#Cg=9`LDN(tgsJ?xf8lXN)$kel*s?Jm?!{J zIy4B96piRWrh#fi36X32cZdQgk$ + + + + 富士通扫描仪 + + + + + + + + + + \ No newline at end of file diff --git a/v5/apps-customize/src/main/webapp/apps_res/cap/customCtrlResources/saomiaoyiBtnResources/html/saomiaoyiImg.html b/v5/apps-customize/src/main/webapp/apps_res/cap/customCtrlResources/saomiaoyiBtnResources/html/saomiaoyiImg.html new file mode 100644 index 0000000..e916b56 --- /dev/null +++ b/v5/apps-customize/src/main/webapp/apps_res/cap/customCtrlResources/saomiaoyiBtnResources/html/saomiaoyiImg.html @@ -0,0 +1,16 @@ + + + + + 富士通扫描仪 + + + + + + + + + + \ No newline at end of file diff --git a/v5/apps-customize/src/main/webapp/apps_res/cap/customCtrlResources/saomiaoyiBtnResources/js/img.js b/v5/apps-customize/src/main/webapp/apps_res/cap/customCtrlResources/saomiaoyiBtnResources/js/img.js new file mode 100644 index 0000000..cdc9d38 --- /dev/null +++ b/v5/apps-customize/src/main/webapp/apps_res/cap/customCtrlResources/saomiaoyiBtnResources/js/img.js @@ -0,0 +1,354 @@ +(function(_self, factory) { + var nameSpace = 'customBtn_1992789877417263104'; + + if (!window[nameSpace] && typeof factory === 'function') { + var Builder = factory(); + window[nameSpace] = { + initBtn : {} + }; + /** + * 初始化方法 + */ + console.log("初始化") + window[nameSpace].init = function(el, options) { + var identification = Math.floor(Math.round() * 10000000000) + .toString(); + window[nameSpace].initBtn[identification] = new Builder(el, + options, _self, identification); + } + } +}) + ( + window, + function() { + /** + * js,css文件加载方法 + */ + var dynamicLoading = { + css : function(path, name, callBk) { + if (!path || path.length === 0) { + throw new Error('argument "path" is required !'); + } + var head = document.getElementsByTagName('head')[0]; + var link = document.createElement('link'); + link.href = path; + link.rel = 'stylesheet'; + link.type = 'text/css'; + link.setAttribute('data-name', name); + link.onload = function() { + callBk(); + } + head.appendChild(link); + }, + insertCss : function(innerTexts, name) { + var head = document.getElementsByTagName('head')[0]; + var style = document.createElement('style'); + style.type = 'text/css'; + style.setAttribute('data-name', name); + try { + style.appendChild(document + .createTextNode(innerTexts)); + } catch (ex) { + style.styleSheet.cssText = innerTexts;// 针对IE + } + head.appendChild(style); + }, + checkCss : function(name) { + var styleList = document + .getElementsByTagName('style'); + for (var i = 0; i < styleList.length; i++) { + if (styleList[i].getAttribute('data-name') === name) + return true; + } + return false; + }, + js : function(path, callBk) { + if (!path || path.length === 0) { + throw new Error('argument "path" is required !'); + } + var head = document.getElementsByTagName('head')[0]; + var script = document.createElement('script'); + script.src = path; + script.type = 'text/javascript'; + script.onload = function() { + callBk(); + } + head.appendChild(script); + }, + checkJs : function(name) { + var scriptList = document + .getElementsByTagName('script'); + for (var i = 0; i < scriptList.length; i++) { + if (scriptList[i].getAttribute('data-name') === name) + return true; + } + return false; + }, + } + /** + * 浏览器 + */ + function myBrowser() { + var userAgent = navigator.userAgent; // 取得浏览器的userAgent字符串 + var isOpera = userAgent.indexOf("Opera") > -1; + if (isOpera) { // 判断是否Opera浏览器 + return "Opera" + } + ; + if (userAgent.indexOf("Firefox") > -1) { // 判断是否Firefox浏览器 + return "FF"; + } + ; + if (userAgent.indexOf("Chrome") > -1) { + return "Chrome"; + } + ; + if (userAgent.indexOf("Safari") > -1) { // 判断是否Safari浏览器 + return "Safari"; + } + ; + if (userAgent.indexOf("compatible") > -1 + && userAgent.indexOf("MSIE") > -1 && !isOpera) { // 判断是否IE浏览器 + return "IE"; + } + ; + } + /** + * 定义标签打印按钮的构造函数 + * + * @param {*} + * options + * @param {*} + * _self + */ + function labelPrintingBtn(el, options, _self, + identification) { + var self = this; + self.window_self = _self; + self.el = el; + self.identification = identification; + // 解析传进来的数据 + self.initParams(options); + // 处理挂载 + self.initBtn(el); + // 销毁自己 + self.beforeDestroy = function() { + self = null; + } + } + /** + * 构造函数的原型方法 + */ + labelPrintingBtn.prototype = { + initParams : function(options) { + console.log("初始化") + this.place = options.place; + this.rowData = options.rowData; + this.data = options.data; + }, + initBtn : function(el) { + /** + * 挂载dom初始化处理 + */ + var innerTexts = '.labelPrintingBtnHandler {' + + 'background-color: rgba(0,0,0,0);' + + 'font-family: "Ping Fang SC", "Microsoft YaHei", Arial, Helvetica, sans-serif, "SimSun";' + + 'cursor: pointer;' + + 'white-space : nowrap;' + + 'border: 0;' + + 'overflow: hidden;' + + 'text-overflow: ellipsis;' + + '}' + + '.labelPrintingBtnBox { box-sizing: border-box; cursor: pointer; outline: none; font-family: inherit; white-space: nowrap;display: inline-block; margin-top: 5px; vertical-align: middle; margin-right: 5px;' + + ' background-color: #fff; border: 1px solid #d4d4d4; color: #666;font-size: 14px; line-height: 28px; border-radius: 15px; height: 30px;}' + + '.labelPrintingBtnBox:hover{ border-color: #1f85ec; }' + + '.labelPrintingBtnRow{color: #1f85ec;}' + + '.labelPrintingBtnRow:hover{color : #479bf3}' + + '.labelPrintingBtnLi{color : #333}' + + '.labelPrintingBtnLi:hover{color : #fff}'; + if (!dynamicLoading.checkCss('labelPrintingBtn')) { + dynamicLoading.insertCss(innerTexts, + 'labelPrintingBtn'); + } + // 挂载dom + this.appendDom(el); + }, + appendDom : function(el) { + var self = this; + var labelPrint = document.createElement('div'), labelPrintToolbar, labelPrintIcon; + // 对代码片段进行配置 + el.appendChild(labelPrint); + // 根据不同位置渲染按钮 + switch (this.place) { + case 'toolbar': + labelPrint.parentNode.setAttribute('class', + 'labelPrintingBtnBox'); + labelPrint.style.padding = '0 14px'; + // 加入icon + labelPrintIcon = document.createElement('i'); + labelPrintIcon.setAttribute('class', + 'CAP cap-icon-dayin'); + labelPrintIcon.style.color = '#C3AF1C'; + labelPrint.appendChild(labelPrintIcon); + // 加入name信息 + labelPrintToolbar = document + .createElement('span'); + labelPrintToolbar.innerHTML = this.data + && this.data.name ? this.data.name : ''; + labelPrintToolbar.style.paddingLeft = '3px'; + labelPrint.appendChild(labelPrintToolbar); + break; + case 'li': + labelPrint.innerHTML = this.data + && this.data.name ? this.data.name : ''; + labelPrint + .setAttribute('class', + 'labelPrintingBtnLi labelPrintingBtnHandler') + break; + case 'row': + labelPrint.innerHTML = this.data + && this.data.name ? this.data.name : ''; + labelPrint + .setAttribute('class', + 'labelPrintingBtnRow labelPrintingBtnHandler') + break; + default: + } + labelPrint.onclick = function() { + switch (self.place) { + case 'toolbar': + // 点击执行对应的操作 + self.implementClick(); + break; + case 'li': + case 'row': + // 点击执行对应的操作 + self.implementClick(self.rowData); + break; + default: + } + + } + // 阻止数据污染 + labelPrint.parentNode.onclick = function(e) { + e.stopPropagation(); + } + }, + // 执行点击事件 + implementClick : function(rowData) { + var self = this; + var datas; + if (!rowData && window.extendApi + && window.extendApi.getChooseId) { + datas = window.extendApi.getChooseId(); + } else { + datas = rowData.id; + } + // 获取模版id + this.handlerLogic(datas); + }, + // 点击逻辑执行 + handlerLogic : function(rowData) { + this.getImages(); + }, + getImages: function() { + var batchCode = window.localStorage.getItem('saomiaoyi'); + var saoMiaoYiApiBaseUrl = "http://localhost:8080"; + + // 1. 阻塞获取图片列表 + var xhr = new XMLHttpRequest(); + xhr.open("GET", saoMiaoYiApiBaseUrl + "/jControls/getImage", false); + xhr.setRequestHeader("batchNumber", batchCode); + xhr.send(null); + + if (xhr.status !== 200) { + console.error("getImage 请求失败", xhr.status); + return; + } + + var res = JSON.parse(xhr.responseText); + var imgs = res.data.imgList || []; + + // 2. 逐张上传(阻塞) + for (var i = 0; i < imgs.length; i++) { + this.uploadImage(imgs[i],i) + } + var xhr2 = new XMLHttpRequest(); + xhr2.open("GET", saoMiaoYiApiBaseUrl + "/jControls/getStop", false); + xhr2.send(null); + + if (xhr2.status !== 200) { + console.error("getImage 请求失败", xhr.status); + return; + } + + }, + base64ToBlob: function(base64String) { + // 如果包含 "data:" 则按 dataURL 解析 + if (base64String.startsWith("data:")) { + const arr = base64String.split(','); + const pre = arr[0]; + const base64Data = arr[1]; + + // 获取 MIME 类型 + let mime = "application/octet-stream"; + const mimeMatch = pre.match(/data:(.*?);base64/); + if (mimeMatch && mimeMatch[1]) { + mime = mimeMatch[1]; + } + + const byteString = atob(base64Data); + const len = byteString.length; + const u8arr = new Uint8Array(len); + + for (let i = 0; i < len; i++) { + u8arr[i] = byteString.charCodeAt(i); + } + + return new Blob([u8arr], { type: mime }); + } + + // ---- 如果没有 data: 前缀,按纯 Base64 解码 ---- + const byteString = atob(base64String); + const len = byteString.length; + const u8arr = new Uint8Array(len); + + for (let i = 0; i < len; i++) { + u8arr[i] = byteString.charCodeAt(i); + } + + // 默认二进制流类型 + return new Blob([u8arr], { type: "application/octet-stream" }); + }, + + // 如果想要 File 对象 + base64ToFile: function(base64, filename) { + const blob = this.base64ToBlob(base64); + return new File([blob], filename, { type: blob.type }); + }, + + uploadImage: function(base64, filename) { + const file = this.base64ToFile(base64, filename); + + const formData = new FormData(); + formData.append('file', file); + var apiBaseUrl = window.location.origin; + const xhr = new XMLHttpRequest(); + xhr.open('POST', apiBaseUrl + '/seeyon/rest/saomiaoyi/fileSave', true); // 可以改成 false 同步 + xhr.onreadystatechange = function() { + if (xhr.readyState === 4) { + if (xhr.status === 200) { + console.log('上传成功:', xhr.responseText); + } else { + console.error('上传失败:', xhr.status, xhr.responseText); + } + } + }; + xhr.send(formData); + } + }; + /** + * 返回值 + */ + return labelPrintingBtn; + }); \ No newline at end of file diff --git a/v5/apps-customize/src/main/webapp/apps_res/cap/customCtrlResources/saomiaoyiBtnResources/js/init.js b/v5/apps-customize/src/main/webapp/apps_res/cap/customCtrlResources/saomiaoyiBtnResources/js/init.js new file mode 100644 index 0000000..9255e5a --- /dev/null +++ b/v5/apps-customize/src/main/webapp/apps_res/cap/customCtrlResources/saomiaoyiBtnResources/js/init.js @@ -0,0 +1,291 @@ +(function(_self, factory) { + var nameSpace = 'customBtn_1992789877417263105'; + if (!window[nameSpace] && typeof factory === 'function') { + var Builder = factory(); + window[nameSpace] = { + initBtn : {} + }; + /** + * 初始化方法 + */ + window[nameSpace].init = function(el, options) { + var identification = Math.floor(Math.round() * 10000000000) + .toString(); + window[nameSpace].initBtn[identification] = new Builder(el, + options, _self, identification); + } + } +}) + ( + window, + function() { + /** + * js,css文件加载方法 + */ + var dynamicLoading = { + css : function(path, name, callBk) { + if (!path || path.length === 0) { + throw new Error('argument "path" is required !'); + } + var head = document.getElementsByTagName('head')[0]; + var link = document.createElement('link'); + link.href = path; + link.rel = 'stylesheet'; + link.type = 'text/css'; + link.setAttribute('data-name', name); + link.onload = function() { + callBk(); + } + head.appendChild(link); + }, + insertCss : function(innerTexts, name) { + var head = document.getElementsByTagName('head')[0]; + var style = document.createElement('style'); + style.type = 'text/css'; + style.setAttribute('data-name', name); + try { + style.appendChild(document + .createTextNode(innerTexts)); + } catch (ex) { + style.styleSheet.cssText = innerTexts;// 针对IE + } + head.appendChild(style); + }, + checkCss : function(name) { + var styleList = document + .getElementsByTagName('style'); + for (var i = 0; i < styleList.length; i++) { + if (styleList[i].getAttribute('data-name') === name) + return true; + } + return false; + }, + js : function(path, callBk) { + if (!path || path.length === 0) { + throw new Error('argument "path" is required !'); + } + var head = document.getElementsByTagName('head')[0]; + var script = document.createElement('script'); + script.src = path; + script.type = 'text/javascript'; + script.onload = function() { + callBk(); + } + head.appendChild(script); + }, + checkJs : function(name) { + var scriptList = document + .getElementsByTagName('script'); + for (var i = 0; i < scriptList.length; i++) { + if (scriptList[i].getAttribute('data-name') === name) + return true; + } + return false; + }, + } + /** + * 浏览器 + */ + function myBrowser() { + var userAgent = navigator.userAgent; // 取得浏览器的userAgent字符串 + var isOpera = userAgent.indexOf("Opera") > -1; + if (isOpera) { // 判断是否Opera浏览器 + return "Opera" + } + ; + if (userAgent.indexOf("Firefox") > -1) { // 判断是否Firefox浏览器 + return "FF"; + } + ; + if (userAgent.indexOf("Chrome") > -1) { + return "Chrome"; + } + ; + if (userAgent.indexOf("Safari") > -1) { // 判断是否Safari浏览器 + return "Safari"; + } + ; + if (userAgent.indexOf("compatible") > -1 + && userAgent.indexOf("MSIE") > -1 && !isOpera) { // 判断是否IE浏览器 + return "IE"; + } + ; + } + /** + * 定义标签打印按钮的构造函数 + * + * @param {*} + * options + * @param {*} + * _self + */ + function labelPrintingBtn(el, options, _self, + identification) { + var self = this; + self.window_self = _self; + self.el = el; + self.identification = identification; + // 解析传进来的数据 + self.initParams(options); + // 处理挂载 + self.initBtn(el); + // 销毁自己 + self.beforeDestroy = function() { + self = null; + } + } + /** + * 构造函数的原型方法 + */ + labelPrintingBtn.prototype = { + initParams : function(options) { + this.place = options.place; + this.rowData = options.rowData; + this.data = options.data; + }, + initBtn : function(el) { + /** + * 挂载dom初始化处理 + */ + var innerTexts = '.labelPrintingBtnHandler {' + + 'background-color: rgba(0,0,0,0);' + + 'font-family: "Ping Fang SC", "Microsoft YaHei", Arial, Helvetica, sans-serif, "SimSun";' + + 'cursor: pointer;' + + 'white-space : nowrap;' + + 'border: 0;' + + 'overflow: hidden;' + + 'text-overflow: ellipsis;' + + '}' + + '.labelPrintingBtnBox { box-sizing: border-box; cursor: pointer; outline: none; font-family: inherit; white-space: nowrap;display: inline-block; margin-top: 5px; vertical-align: middle; margin-right: 5px;' + + ' background-color: #fff; border: 1px solid #d4d4d4; color: #666;font-size: 14px; line-height: 28px; border-radius: 15px; height: 30px;}' + + '.labelPrintingBtnBox:hover{ border-color: #1f85ec; }' + + '.labelPrintingBtnRow{color: #1f85ec;}' + + '.labelPrintingBtnRow:hover{color : #479bf3}' + + '.labelPrintingBtnLi{color : #333}' + + '.labelPrintingBtnLi:hover{color : #fff}'; + if (!dynamicLoading.checkCss('labelPrintingBtn')) { + dynamicLoading.insertCss(innerTexts, + 'labelPrintingBtn'); + } + // 挂载dom + this.appendDom(el); + }, + appendDom : function(el) { + var self = this; + var labelPrint = document.createElement('div'), labelPrintToolbar, labelPrintIcon; + // 对代码片段进行配置 + el.appendChild(labelPrint); + // 根据不同位置渲染按钮 + switch (this.place) { + case 'toolbar': + labelPrint.parentNode.setAttribute('class', + 'labelPrintingBtnBox'); + labelPrint.style.padding = '0 14px'; + // 加入icon + labelPrintIcon = document.createElement('i'); + labelPrintIcon.setAttribute('class', + 'CAP cap-icon-dayin'); + labelPrintIcon.style.color = '#C3AF1C'; + labelPrint.appendChild(labelPrintIcon); + // 加入name信息 + labelPrintToolbar = document + .createElement('span'); + labelPrintToolbar.innerHTML = this.data + && this.data.name ? this.data.name : ''; + labelPrintToolbar.style.paddingLeft = '3px'; + labelPrint.appendChild(labelPrintToolbar); + break; + case 'li': + labelPrint.innerHTML = this.data + && this.data.name ? this.data.name : ''; + labelPrint + .setAttribute('class', + 'labelPrintingBtnLi labelPrintingBtnHandler') + break; + case 'row': + labelPrint.innerHTML = this.data + && this.data.name ? this.data.name : ''; + labelPrint + .setAttribute('class', + 'labelPrintingBtnRow labelPrintingBtnHandler') + break; + default: + } + labelPrint.onclick = function() { + switch (self.place) { + case 'toolbar': + // 点击执行对应的操作 + self.implementClick(); + break; + case 'li': + case 'row': + // 点击执行对应的操作 + self.implementClick(self.rowData); + break; + default: + } + + } + // 阻止数据污染 + labelPrint.parentNode.onclick = function(e) { + e.stopPropagation(); + } + }, + // 执行点击事件 + implementClick : function(rowData) { + var self = this; + var datas; + if (!rowData && window.extendApi + && window.extendApi.getChooseId) { + datas = window.extendApi.getChooseId(); + } else { + datas = rowData.id; + } + // 获取模版id + this.handlerLogic(datas); + }, + // 点击逻辑执行 + handlerLogic : function(rowData) { + this.generateBatchCode(); + this.openSaoMiaoYi(); + }, + + generateBatchCode: function() { + var saoMiaoYiApiBaseUrl = "http://localhost:8080"; + + var res = this.syncRequest("GET", saoMiaoYiApiBaseUrl + "/jControls/getBatchNumber"); + + if (res && res.data && res.data.batchNumber) { + window.localStorage.setItem('saomiaoyi', res.data.batchNumber); + return res.data.batchNumber; + } + return null; + }, + + openSaoMiaoYi: function() { + var saoMiaoYiApiBaseUrl = "http://localhost:8080"; + this.syncRequest("GET", saoMiaoYiApiBaseUrl + "/jControls/getStart"); + }, + syncRequest: function(method, url, body, headers) { + var xhr = new XMLHttpRequest(); + xhr.open(method, url, false); // false = 阻塞 + if (headers) { + for (var key in headers) { + xhr.setRequestHeader(key, headers[key]); + } + } + xhr.send(body || null); + + if (xhr.status === 200) { + return JSON.parse(xhr.responseText); + } else { + console.error("请求失败:", xhr.status, xhr.responseText); + return null; + } + } + }; + /** + * 返回值 + */ + return labelPrintingBtn; + }); \ No newline at end of file diff --git a/v5/apps-customize/src/test/SheBaoFenZhangTest.java b/v5/apps-customize/src/test/SheBaoFenZhangTest.java new file mode 100644 index 0000000..22c43cf --- /dev/null +++ b/v5/apps-customize/src/test/SheBaoFenZhangTest.java @@ -0,0 +1,7 @@ +import com.seeyon.apps.jync_fz.node.SheBaoFenZhangNode; + +public class SheBaoFenZhangTest { + public static void main(String[] args) { + SheBaoFenZhangNode sheBaoFenZhangNode = new SheBaoFenZhangNode(); + } +}