Răsfoiți Sursa

新版应用市场接口及数据同步

o2sword 5 ani în urmă
părinte
comite
a66aa44e0d
19 a modificat fișierele cu 1044 adăugiri și 20 ștergeri
  1. 1 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/config/Collect.java
  2. 1 0
      o2server/x_base_core_project/src/main/java/com/x/base/core/project/x_program_center.java
  3. 53 0
      o2server/x_program_center/src/main/java/com/x/program/center/Business.java
  4. 2 17
      o2server/x_program_center/src/main/java/com/x/program/center/ThisApplication.java
  5. 2 0
      o2server/x_program_center/src/main/java/com/x/program/center/jaxrs/ActionApplication.java
  6. 10 0
      o2server/x_program_center/src/main/java/com/x/program/center/jaxrs/MarketJaxrsFilter.java
  7. 3 1
      o2server/x_program_center/src/main/java/com/x/program/center/jaxrs/collect/ActionRegist.java
  8. 3 1
      o2server/x_program_center/src/main/java/com/x/program/center/jaxrs/collect/ActionValidate.java
  9. 3 1
      o2server/x_program_center/src/main/java/com/x/program/center/jaxrs/collect/ActionValidateDirect.java
  10. 53 0
      o2server/x_program_center/src/main/java/com/x/program/center/jaxrs/market/ActionGet.java
  11. 40 0
      o2server/x_program_center/src/main/java/com/x/program/center/jaxrs/market/ActionGetCoverPic.java
  12. 173 0
      o2server/x_program_center/src/main/java/com/x/program/center/jaxrs/market/ActionListPaging.java
  13. 23 0
      o2server/x_program_center/src/main/java/com/x/program/center/jaxrs/market/ActionSync.java
  14. 13 0
      o2server/x_program_center/src/main/java/com/x/program/center/jaxrs/market/BaseAction.java
  15. 100 0
      o2server/x_program_center/src/main/java/com/x/program/center/jaxrs/market/MarketAction.java
  16. 146 0
      o2server/x_program_center/src/main/java/com/x/program/center/schedule/CollectMarket.java
  17. 263 0
      o2server/x_program_center_core_entity/src/main/java/com/x/program/center/core/entity/Application.java
  18. 147 0
      o2server/x_program_center_core_entity/src/main/java/com/x/program/center/core/entity/Attachment.java
  19. 8 0
      o2server/x_program_center_core_entity/src/main/java/com/x/program/center/core/entity/PersistenceProperties.java

+ 1 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/config/Collect.java

@@ -36,6 +36,7 @@ public class Collect extends ConfigObject {
 	public static String ADDRESS_COLLECT_VALIDATE = "/o2_collect_assemble/jaxrs/unit/validate";
 	public static String ADDRESS_COLLECT_VALIDATE = "/o2_collect_assemble/jaxrs/unit/validate";
 	public static String ADDRESS_COLLECT_VALIDATE_CODE = "/o2_collect_assemble/jaxrs/unit/validate/codeanswer";
 	public static String ADDRESS_COLLECT_VALIDATE_CODE = "/o2_collect_assemble/jaxrs/unit/validate/codeanswer";
 	public static String ADDRESS_COLLECT_APPLICATION_LIST = "/o2_collect_assemble/jaxrs/application/list";
 	public static String ADDRESS_COLLECT_APPLICATION_LIST = "/o2_collect_assemble/jaxrs/application/list";
+	public static String COLLECT_TOKEN = "c-token";
 
 
 	public static Collect defaultInstance() {
 	public static Collect defaultInstance() {
 		return new Collect();
 		return new Collect();

+ 1 - 0
o2server/x_base_core_project/src/main/java/com/x/base/core/project/x_program_center.java

@@ -11,6 +11,7 @@ import com.x.base.core.project.annotation.ModuleType;
 		"com.x.program.center.core.entity.PromptErrorLog", "com.x.program.center.core.entity.UnexpectedErrorLog",
 		"com.x.program.center.core.entity.PromptErrorLog", "com.x.program.center.core.entity.UnexpectedErrorLog",
 		"com.x.program.center.core.entity.Structure", "com.x.program.center.core.entity.WarnLog",
 		"com.x.program.center.core.entity.Structure", "com.x.program.center.core.entity.WarnLog",
 		"com.x.program.center.core.entity.validation.Meta", "com.x.portal.core.entity.Page",
 		"com.x.program.center.core.entity.validation.Meta", "com.x.portal.core.entity.Page",
+		"com.x.program.center.core.entity.Application", "com.x.program.center.core.entity.Attachment",
 		"com.x.portal.core.entity.Portal", "com.x.organization.core.entity.Group",
 		"com.x.portal.core.entity.Portal", "com.x.organization.core.entity.Group",
 		"com.x.organization.core.entity.Custom", "com.x.organization.core.entity.Role",
 		"com.x.organization.core.entity.Custom", "com.x.organization.core.entity.Role",
 		"com.x.organization.core.entity.Person", "com.x.organization.core.entity.Identity",
 		"com.x.organization.core.entity.Person", "com.x.organization.core.entity.Identity",

+ 53 - 0
o2server/x_program_center/src/main/java/com/x/program/center/Business.java

@@ -1,5 +1,7 @@
 package com.x.program.center;
 package com.x.program.center;
 
 
+import com.x.base.core.project.config.Collect;
+import com.x.base.core.project.http.TokenType;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.StringUtils;
 
 
 import com.x.base.core.container.EntityManagerContainer;
 import com.x.base.core.container.EntityManagerContainer;
@@ -11,6 +13,9 @@ import com.x.base.core.project.jaxrs.WrapBoolean;
 import com.x.program.center.factory.PersonFactory;
 import com.x.program.center.factory.PersonFactory;
 import com.x.program.center.factory.UnitFactory;
 import com.x.program.center.factory.UnitFactory;
 
 
+import java.util.HashMap;
+import java.util.Map;
+
 public class Business {
 public class Business {
 
 
 	private EntityManagerContainer emc;
 	private EntityManagerContainer emc;
@@ -49,6 +54,20 @@ public class Business {
 		return resp.getData(WoValidateCollect.class).getValue();
 		return resp.getData(WoValidateCollect.class).getValue();
 	}
 	}
 
 
+	public String loginCollect() throws Exception {
+		String url = Config.collect().url(Collect.ADDRESS_COLLECT_LOGIN);
+		Map<String, String> map = new HashMap<>();
+		map.put("credential", Config.collect().getName());
+		map.put("password", Config.collect().getPassword());
+		ActionResponse resp = ConnectionAction.post(url, null, map);
+		LoginWo loginWo = resp.getData(LoginWo.class);
+		if(loginWo!=null) {
+			return loginWo.getToken();
+		}else{
+			return null;
+		}
+	}
+
 	public static class ValidateReq extends GsonPropertyObject {
 	public static class ValidateReq extends GsonPropertyObject {
 
 
 		private String name;
 		private String name;
@@ -92,4 +111,38 @@ public class Business {
 	public static class WoValidateCollect extends WrapBoolean {
 	public static class WoValidateCollect extends WrapBoolean {
 	}
 	}
 
 
+	public static class LoginWo extends GsonPropertyObject {
+
+		private String token;
+
+		private String name;
+
+		private TokenType tokenType;
+
+		public String getToken() {
+			return token;
+		}
+
+		public void setToken(String token) {
+			this.token = token;
+		}
+
+		public String getName() {
+			return name;
+		}
+
+		public void setName(String name) {
+			this.name = name;
+		}
+
+		public TokenType getTokenType() {
+			return tokenType;
+		}
+
+		public void setTokenType(TokenType tokenType) {
+			this.tokenType = tokenType;
+		}
+
+	}
+
 }
 }

+ 2 - 17
o2server/x_program_center/src/main/java/com/x/program/center/ThisApplication.java

@@ -8,23 +8,7 @@ import java.util.concurrent.ConcurrentHashMap;
 import com.google.gson.internal.LinkedTreeMap;
 import com.google.gson.internal.LinkedTreeMap;
 import com.x.base.core.project.config.Config;
 import com.x.base.core.project.config.Config;
 import com.x.base.core.project.logger.LoggerFactory;
 import com.x.base.core.project.logger.LoggerFactory;
-import com.x.program.center.schedule.Area;
-import com.x.program.center.schedule.CleanupCode;
-import com.x.program.center.schedule.CleanupPromptErrorLog;
-import com.x.program.center.schedule.CleanupScheduleLog;
-import com.x.program.center.schedule.CleanupUnexpectedErrorLog;
-import com.x.program.center.schedule.CleanupWarnLog;
-import com.x.program.center.schedule.CollectLog;
-import com.x.program.center.schedule.CollectPerson;
-import com.x.program.center.schedule.DingdingSyncOrganization;
-import com.x.program.center.schedule.DingdingSyncOrganizationTrigger;
-import com.x.program.center.schedule.FireSchedule;
-import com.x.program.center.schedule.QiyeweixinSyncOrganization;
-import com.x.program.center.schedule.QiyeweixinSyncOrganizationTrigger;
-import com.x.program.center.schedule.RefreshApplications;
-import com.x.program.center.schedule.TriggerAgent;
-import com.x.program.center.schedule.ZhengwuDingdingSyncOrganization;
-import com.x.program.center.schedule.ZhengwuDingdingSyncOrganizationTrigger;
+import com.x.program.center.schedule.*;
 
 
 public class ThisApplication {
 public class ThisApplication {
 
 
@@ -87,6 +71,7 @@ public class ThisApplication {
 			context().scheduleLocal(CleanupUnexpectedErrorLog.class, 10, 60 * 30);
 			context().scheduleLocal(CleanupUnexpectedErrorLog.class, 10, 60 * 30);
 			context().scheduleLocal(CleanupWarnLog.class, 10, 60 * 30);
 			context().scheduleLocal(CleanupWarnLog.class, 10, 60 * 30);
 			context().scheduleLocal(CollectPerson.class, 10, 60 * 30);
 			context().scheduleLocal(CollectPerson.class, 10, 60 * 30);
+			context().scheduleLocal(CollectMarket.class, 10, 60 * 60 * 6);
 			context().scheduleLocal(CollectLog.class, 10, 60 * 30);
 			context().scheduleLocal(CollectLog.class, 10, 60 * 30);
 			// 运行间隔由60秒缩减到30秒
 			// 运行间隔由60秒缩减到30秒
 			context().scheduleLocal(TriggerAgent.class, 150, 30);
 			context().scheduleLocal(TriggerAgent.class, 150, 30);

+ 2 - 0
o2server/x_program_center/src/main/java/com/x/program/center/jaxrs/ActionApplication.java

@@ -23,6 +23,7 @@ import com.x.program.center.jaxrs.distribute.DistributeAction;
 import com.x.program.center.jaxrs.input.InputAction;
 import com.x.program.center.jaxrs.input.InputAction;
 import com.x.program.center.jaxrs.invoke.InvokeAction;
 import com.x.program.center.jaxrs.invoke.InvokeAction;
 import com.x.program.center.jaxrs.jest.JestAction;
 import com.x.program.center.jaxrs.jest.JestAction;
+import com.x.program.center.jaxrs.market.MarketAction;
 import com.x.program.center.jaxrs.module.ModuleAction;
 import com.x.program.center.jaxrs.module.ModuleAction;
 import com.x.program.center.jaxrs.output.OutputAction;
 import com.x.program.center.jaxrs.output.OutputAction;
 import com.x.program.center.jaxrs.pms.PmsAction;
 import com.x.program.center.jaxrs.pms.PmsAction;
@@ -68,6 +69,7 @@ public class ActionApplication extends AbstractActionApplication {
 		classes.add(TestAction.class);
 		classes.add(TestAction.class);
 		classes.add(OutputAction.class);
 		classes.add(OutputAction.class);
 		classes.add(InputAction.class);
 		classes.add(InputAction.class);
+		classes.add(MarketAction.class);
 		return classes;
 		return classes;
 	}
 	}
 }
 }

+ 10 - 0
o2server/x_program_center/src/main/java/com/x/program/center/jaxrs/MarketJaxrsFilter.java

@@ -0,0 +1,10 @@
+package com.x.program.center.jaxrs;
+
+import com.x.base.core.project.jaxrs.CipherManagerJaxrsFilter;
+
+import javax.servlet.annotation.WebFilter;
+
+@WebFilter(urlPatterns = "/jaxrs/market/*", asyncSupported = true)
+public class MarketJaxrsFilter extends CipherManagerJaxrsFilter {
+
+}

+ 3 - 1
o2server/x_program_center/src/main/java/com/x/program/center/jaxrs/collect/ActionRegist.java

@@ -1,5 +1,6 @@
 package com.x.program.center.jaxrs.collect;
 package com.x.program.center.jaxrs.collect;
 
 
+import com.x.program.center.schedule.CollectMarket;
 import org.apache.commons.lang3.BooleanUtils;
 import org.apache.commons.lang3.BooleanUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.StringUtils;
 
 
@@ -47,8 +48,9 @@ class ActionRegist extends BaseAction {
 			Config.collect().setPassword(password);
 			Config.collect().setPassword(password);
 			Config.collect().save();
 			Config.collect().save();
 			Config.flush();
 			Config.flush();
-			/* 直接提交人员 */
+			/* 人员和应用市场同步 */
 			ThisApplication.context().scheduleLocal(CollectPerson.class);
 			ThisApplication.context().scheduleLocal(CollectPerson.class);
+			ThisApplication.context().scheduleLocal(CollectMarket.class);
 		}
 		}
 		result.setData(wo);
 		result.setData(wo);
 		return result;
 		return result;

+ 3 - 1
o2server/x_program_center/src/main/java/com/x/program/center/jaxrs/collect/ActionValidate.java

@@ -4,6 +4,7 @@ import com.x.base.core.project.config.Config;
 import com.x.base.core.project.http.ActionResult;
 import com.x.base.core.project.http.ActionResult;
 import com.x.base.core.project.jaxrs.WrapBoolean;
 import com.x.base.core.project.jaxrs.WrapBoolean;
 import com.x.program.center.ThisApplication;
 import com.x.program.center.ThisApplication;
+import com.x.program.center.schedule.CollectMarket;
 import com.x.program.center.schedule.CollectPerson;
 import com.x.program.center.schedule.CollectPerson;
 import org.apache.commons.lang3.BooleanUtils;
 import org.apache.commons.lang3.BooleanUtils;
 
 
@@ -23,8 +24,9 @@ class ActionValidate extends BaseAction {
 			wo.setValue(false);
 			wo.setValue(false);
 		}
 		}
 		if (BooleanUtils.isTrue(wo.getValue())) {
 		if (BooleanUtils.isTrue(wo.getValue())) {
-			/* 提交人员同步 */
+			/* 人员和应用市场同步 */
 			ThisApplication.context().scheduleLocal(CollectPerson.class);
 			ThisApplication.context().scheduleLocal(CollectPerson.class);
+			ThisApplication.context().scheduleLocal(CollectMarket.class);
 		}
 		}
 		result.setData(wo);
 		result.setData(wo);
 		return result;
 		return result;

+ 3 - 1
o2server/x_program_center/src/main/java/com/x/program/center/jaxrs/collect/ActionValidateDirect.java

@@ -2,6 +2,7 @@ package com.x.program.center.jaxrs.collect;
 
 
 import com.x.base.core.project.config.Config;
 import com.x.base.core.project.config.Config;
 import com.x.program.center.ThisApplication;
 import com.x.program.center.ThisApplication;
+import com.x.program.center.schedule.CollectMarket;
 import com.x.program.center.schedule.CollectPerson;
 import com.x.program.center.schedule.CollectPerson;
 import org.apache.commons.lang3.BooleanUtils;
 import org.apache.commons.lang3.BooleanUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.StringUtils;
@@ -38,8 +39,9 @@ class ActionValidateDirect extends BaseAction {
 			Config.collect().setPassword(password);
 			Config.collect().setPassword(password);
 			Config.collect().save();
 			Config.collect().save();
 			Config.flush();
 			Config.flush();
-			/* 提交人员人员同步 */
+			/* 人员和应用市场同步 */
 			ThisApplication.context().scheduleLocal(CollectPerson.class);
 			ThisApplication.context().scheduleLocal(CollectPerson.class);
+			ThisApplication.context().scheduleLocal(CollectMarket.class);
 		}
 		}
 		result.setData(wo);
 		result.setData(wo);
 		return result;
 		return result;

+ 53 - 0
o2server/x_program_center/src/main/java/com/x/program/center/jaxrs/market/ActionGet.java

@@ -0,0 +1,53 @@
+package com.x.program.center.jaxrs.market;
+
+import com.x.base.core.container.EntityManagerContainer;
+import com.x.base.core.container.factory.EntityManagerContainerFactory;
+import com.x.base.core.project.annotation.FieldDescribe;
+import com.x.base.core.project.bean.WrapCopier;
+import com.x.base.core.project.bean.WrapCopierFactory;
+import com.x.base.core.project.exception.ExceptionAccessDenied;
+import com.x.base.core.project.exception.ExceptionEntityNotExist;
+import com.x.base.core.project.http.ActionResult;
+import com.x.base.core.project.http.EffectivePerson;
+import com.x.program.center.core.entity.Application;
+import com.x.program.center.core.entity.Attachment;
+
+import java.util.ArrayList;
+import java.util.List;
+
+class ActionGet extends BaseAction {
+
+	ActionResult<Wo> execute(EffectivePerson effectivePerson, String id) throws Exception {
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			if (effectivePerson.isAnonymous()) {
+				throw new ExceptionAccessDenied(effectivePerson);
+			}
+			ActionResult<Wo> result = new ActionResult<>();
+			Application app = emc.find(id, Application.class);
+			if (null == app) {
+				throw new ExceptionEntityNotExist(id, Application.class);
+			}
+			Wo wo = Wo.copier.copy(app);
+			wo.setAttList(emc.listEqual(Attachment.class, Attachment.application_FIELDNAME, wo.getId()));
+			result.setData(wo);
+			return result;
+		}
+	}
+
+	public static class Wo extends Application {
+
+		private static final long serialVersionUID = -4000191514240350631L;
+		static WrapCopier<Application, Wo> copier = WrapCopierFactory.wo(Application.class, Wo.class, null, Wo.FieldsInvisible);
+
+		@FieldDescribe("图片列表")
+		private List<Attachment> attList = new ArrayList<>();
+
+		public List<Attachment> getAttList() {
+			return attList;
+		}
+
+		public void setAttList(List<Attachment> attList) {
+			this.attList = attList;
+		}
+	}
+}

+ 40 - 0
o2server/x_program_center/src/main/java/com/x/program/center/jaxrs/market/ActionGetCoverPic.java

@@ -0,0 +1,40 @@
+package com.x.program.center.jaxrs.market;
+
+import com.x.base.core.container.EntityManagerContainer;
+import com.x.base.core.container.factory.EntityManagerContainerFactory;
+import com.x.base.core.project.exception.ExceptionAccessDenied;
+import com.x.base.core.project.exception.ExceptionEntityNotExist;
+import com.x.base.core.project.http.ActionResult;
+import com.x.base.core.project.http.EffectivePerson;
+import com.x.base.core.project.jaxrs.WrapString;
+import com.x.program.center.core.entity.Application;
+import com.x.program.center.core.entity.Attachment;
+
+import java.util.List;
+
+class ActionGetCoverPic extends BaseAction {
+
+	ActionResult<Wo> execute(EffectivePerson effectivePerson, String id) throws Exception {
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			if (effectivePerson.isAnonymous()) {
+				throw new ExceptionAccessDenied(effectivePerson);
+			}
+			ActionResult<Wo> result = new ActionResult<>();
+			Application app = emc.find(id, Application.class);
+			if (null == app) {
+				throw new ExceptionEntityNotExist(id, Application.class);
+			}
+			Wo wo = new Wo();
+			List<Attachment> attList = emc.listEqualAndEqual(Attachment.class, Attachment.application_FIELDNAME, id, Attachment.type_FIELDNAME, "coverPic");
+			if(attList!=null && !attList.isEmpty()){
+				wo.setValue(attList.get(0).getIcon());
+			}
+			result.setData(wo);
+			return result;
+		}
+	}
+
+	public static class Wo extends WrapString {
+
+	}
+}

+ 173 - 0
o2server/x_program_center/src/main/java/com/x/program/center/jaxrs/market/ActionListPaging.java

@@ -0,0 +1,173 @@
+package com.x.program.center.jaxrs.market;
+
+import com.google.gson.JsonElement;
+import com.x.base.core.container.EntityManagerContainer;
+import com.x.base.core.container.factory.EntityManagerContainerFactory;
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.project.annotation.FieldDescribe;
+import com.x.base.core.project.bean.WrapCopier;
+import com.x.base.core.project.bean.WrapCopierFactory;
+import com.x.base.core.project.gson.GsonPropertyObject;
+import com.x.base.core.project.http.ActionResult;
+import com.x.base.core.project.http.EffectivePerson;
+import com.x.base.core.project.tools.DateTools;
+import com.x.base.core.project.tools.StringTools;
+import com.x.program.center.Business;
+import com.x.program.center.core.entity.Application;
+import com.x.program.center.core.entity.Application_;
+import org.apache.commons.lang3.BooleanUtils;
+import org.apache.commons.lang3.StringUtils;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Tuple;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+class ActionListPaging extends BaseAction {
+
+	ActionResult<List<Wo>> execute(EffectivePerson effectivePerson, Integer page, Integer size, JsonElement jsonElement)
+			throws Exception {
+		try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+			Business business = new Business(emc);
+			ActionResult<List<Wo>> result = new ActionResult<>();
+			Wi wi = this.convertToWrapIn(jsonElement, Wi.class);
+			Predicate p = this.toFilterPredicate(effectivePerson, business, wi);
+			String orderBy = Application.createTime_FIELDNAME;
+			if(StringUtils.isNotEmpty(wi.getOrderBy())){
+				orderBy = wi.getOrderBy();
+			}
+			List<Wo> wos = new ArrayList<>();
+			if(BooleanUtils.isTrue(wi.getAsc())){
+				emc.fetchAscPaging(Application.class, Wo.copier, p, page, size, orderBy);
+			}else {
+				wos = emc.fetchDescPaging(Application.class, Wo.copier, p, page, size, orderBy);
+			}
+			result.setData(wos);
+			result.setCount(emc.count(Application.class, p));
+			return result;
+		}
+	}
+
+	private Predicate toFilterPredicate(EffectivePerson effectivePerson, Business business, Wi wi) throws Exception {
+		EntityManager em = business.entityManagerContainer().get(Application.class);
+		CriteriaBuilder cb = em.getCriteriaBuilder();
+		CriteriaQuery<Tuple> cq = cb.createQuery(Tuple.class);
+		Root<Application> root = cq.from(Application.class);
+		Predicate p = cb.conjunction();
+
+		if(StringUtils.isNotEmpty(wi.getName())){
+			String key = StringTools.escapeSqlLikeKey(wi.getName());
+			if (StringUtils.isNotEmpty(key)) {
+				p = cb.and(p,cb.like(root.get(Application_.name), "%" + key + "%", StringTools.SQL_ESCAPE_CHAR));
+			}
+		}
+
+		if(StringUtils.isNotEmpty(wi.getCategory())){
+			p = cb.and(p, cb.equal(root.get(Application_.category), wi.getCategory()));
+		}
+
+		if (DateTools.isDateTimeOrDate(wi.getStartTime())) {
+			p = cb.and(p, cb.greaterThan(root.get(Application_.createTime), DateTools.parse(wi.getStartTime())));
+		}
+		if (DateTools.isDateTimeOrDate(wi.getEndTime())) {
+			p = cb.and(p, cb.lessThan(root.get(Application_.createTime), DateTools.parse(wi.getEndTime())));
+		}
+		return p;
+	}
+
+	public class Wi extends GsonPropertyObject {
+
+		@FieldDescribe("名称")
+		private String name;
+
+		@FieldDescribe("分类")
+		private String category;
+
+		@FieldDescribe("状态:draft|audit|publish")
+		private String status;
+
+		@FieldDescribe("排序字段:createTime(创建时间,默认)|orderNumber(排序)|recommend(推荐指数)")
+		private String orderBy;
+
+		@FieldDescribe("是否是升序排序:true|false")
+		private Boolean isAsc;
+
+		@FieldDescribe("开始时间yyyy-MM-dd HH:mm:ss")
+		private String startTime;
+
+		@FieldDescribe("结束时间yyyy-MM-dd HH:mm:ss")
+		private String endTime;
+
+		public String getName() {
+			return name;
+		}
+
+		public void setName(String name) {
+			this.name = name;
+		}
+
+		public String getCategory() {
+			return category;
+		}
+
+		public void setCategory(String category) {
+			this.category = category;
+		}
+
+		public String getStatus() {
+			return status;
+		}
+
+		public void setStatus(String status) {
+			this.status = status;
+		}
+
+		public String getOrderBy() {
+			return orderBy;
+		}
+
+		public void setOrderBy(String orderBy) {
+			this.orderBy = orderBy;
+		}
+
+		public Boolean getAsc() {
+			return isAsc;
+		}
+
+		public void setAsc(Boolean asc) {
+			isAsc = asc;
+		}
+
+		public String getStartTime() {
+			return startTime;
+		}
+
+		public void setStartTime(String startTime) {
+			this.startTime = startTime;
+		}
+
+		public String getEndTime() {
+			return endTime;
+		}
+
+		public void setEndTime(String endTime) {
+			this.endTime = endTime;
+		}
+	}
+
+	public static class Wo extends Application {
+
+		private static final long serialVersionUID = 9206739553467260926L;
+
+		static WrapCopier<Application, Wo> copier = WrapCopierFactory.wo(Application.class, Wo.class,
+				JpaObject.singularAttributeField(Application.class, true, false), Arrays.asList("abort", "installSteps"));
+
+
+	}
+
+}

+ 23 - 0
o2server/x_program_center/src/main/java/com/x/program/center/jaxrs/market/ActionSync.java

@@ -0,0 +1,23 @@
+package com.x.program.center.jaxrs.market;
+
+import com.x.base.core.project.http.ActionResult;
+import com.x.base.core.project.http.EffectivePerson;
+import com.x.base.core.project.jaxrs.WrapBoolean;
+import com.x.program.center.ThisApplication;
+import com.x.program.center.schedule.CollectMarket;
+
+class ActionSync extends BaseAction {
+
+	ActionResult<Wo> execute(EffectivePerson effectivePerson) throws Exception {
+		ActionResult<Wo> result = new ActionResult<>();
+		Wo wo = new Wo();
+		wo.setValue(true);
+		result.setData(wo);
+		ThisApplication.context().scheduleLocal(CollectMarket.class);
+		return result;
+	}
+
+	public static class Wo extends WrapBoolean {
+	}
+
+}

+ 13 - 0
o2server/x_program_center/src/main/java/com/x/program/center/jaxrs/market/BaseAction.java

@@ -0,0 +1,13 @@
+package com.x.program.center.jaxrs.market;
+
+import com.x.base.core.project.cache.ApplicationCache;
+import com.x.base.core.project.jaxrs.StandardJaxrsAction;
+import com.x.program.center.WrapModule;
+import com.x.program.center.core.entity.Application;
+import net.sf.ehcache.Ehcache;
+
+abstract class BaseAction extends StandardJaxrsAction {
+
+	protected Ehcache cache = ApplicationCache.instance().getCache(Application.class);
+
+}

+ 100 - 0
o2server/x_program_center/src/main/java/com/x/program/center/jaxrs/market/MarketAction.java

@@ -0,0 +1,100 @@
+package com.x.program.center.jaxrs.market;
+
+import com.google.gson.JsonElement;
+import com.x.base.core.project.annotation.JaxrsDescribe;
+import com.x.base.core.project.annotation.JaxrsMethodDescribe;
+import com.x.base.core.project.annotation.JaxrsParameterDescribe;
+import com.x.base.core.project.http.ActionResult;
+import com.x.base.core.project.http.EffectivePerson;
+import com.x.base.core.project.http.HttpMediaType;
+import com.x.base.core.project.jaxrs.ResponseFactory;
+import com.x.base.core.project.jaxrs.StandardJaxrsAction;
+import com.x.base.core.project.logger.Logger;
+import com.x.base.core.project.logger.LoggerFactory;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.*;
+import javax.ws.rs.container.AsyncResponse;
+import javax.ws.rs.container.Suspended;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import java.util.List;
+
+@Path("market")
+@JaxrsDescribe("应用市场")
+public class MarketAction extends StandardJaxrsAction {
+
+	private static Logger logger = LoggerFactory.getLogger(MarketAction.class);
+
+	@JaxrsMethodDescribe(value = "分页查询.", action = ActionListPaging.class)
+	@POST
+	@Path("list/paging/{page}/size/{size}")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public void listPaging(@Suspended final AsyncResponse asyncResponse, @Context HttpServletRequest request,
+						   @JaxrsParameterDescribe("分页") @PathParam("page") Integer page,
+						   @JaxrsParameterDescribe("每页数量") @PathParam("size") Integer size, JsonElement jsonElement) {
+		ActionResult<List<ActionListPaging.Wo>> result = new ActionResult<>();
+		EffectivePerson effectivePerson = this.effectivePerson(request);
+		try {
+			result = new ActionListPaging().execute(effectivePerson, page, size, jsonElement);
+		} catch (Exception e) {
+			logger.error(e, effectivePerson, request, jsonElement);
+			result.error(e);
+		}
+		asyncResponse.resume(ResponseFactory.getDefaultActionResultResponse(result));
+	}
+
+	@JaxrsMethodDescribe(value = "获取对象.", action = ActionGet.class)
+	@GET
+	@Path("{flag}")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public void get(@Suspended final AsyncResponse asyncResponse, @Context HttpServletRequest request,
+					@JaxrsParameterDescribe("标识") @PathParam("flag") String flag) {
+		ActionResult<ActionGet.Wo> result = new ActionResult<>();
+		EffectivePerson effectivePerson = this.effectivePerson(request);
+		try {
+			result = new ActionGet().execute(effectivePerson, flag);
+		} catch (Exception e) {
+			logger.error(e, effectivePerson, request, null);
+			result.error(e);
+		}
+		asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result));
+	}
+
+	@JaxrsMethodDescribe(value = "获取封面图片.", action = ActionGetCoverPic.class)
+	@GET
+	@Path("{flag}/cover/pic")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public void getCoverPic(@Suspended final AsyncResponse asyncResponse, @Context HttpServletRequest request,
+					@JaxrsParameterDescribe("标识") @PathParam("flag") String flag) {
+		ActionResult<ActionGetCoverPic.Wo> result = new ActionResult<>();
+		EffectivePerson effectivePerson = this.effectivePerson(request);
+		try {
+			result = new ActionGetCoverPic().execute(effectivePerson, flag);
+		} catch (Exception e) {
+			logger.error(e, effectivePerson, request, null);
+			result.error(e);
+		}
+		asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result));
+	}
+
+	@JaxrsMethodDescribe(value = "同步数据.", action = ActionSync.class)
+	@GET
+	@Path("sync")
+	@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
+	@Consumes(MediaType.APPLICATION_JSON)
+	public void sync(@Suspended final AsyncResponse asyncResponse, @Context HttpServletRequest request) {
+		ActionResult<ActionSync.Wo> result = new ActionResult<>();
+		EffectivePerson effectivePerson = this.effectivePerson(request);
+		try {
+			result = new ActionSync().execute(effectivePerson);
+		} catch (Exception e) {
+			logger.error(e, effectivePerson, request, null);
+			result.error(e);
+		}
+		asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result));
+	}
+
+}

+ 146 - 0
o2server/x_program_center/src/main/java/com/x/program/center/schedule/CollectMarket.java

@@ -0,0 +1,146 @@
+package com.x.program.center.schedule;
+
+import com.x.base.core.container.EntityManagerContainer;
+import com.x.base.core.container.factory.EntityManagerContainerFactory;
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.entity.annotation.CheckPersistType;
+import com.x.base.core.project.annotation.FieldDescribe;
+import com.x.base.core.project.bean.NameValuePair;
+import com.x.base.core.project.bean.WrapCopier;
+import com.x.base.core.project.bean.WrapCopierFactory;
+import com.x.base.core.project.config.CenterServer;
+import com.x.base.core.project.config.Collect;
+import com.x.base.core.project.config.Config;
+import com.x.base.core.project.connection.ActionResponse;
+import com.x.base.core.project.connection.ConnectionAction;
+import com.x.base.core.project.gson.GsonPropertyObject;
+import com.x.base.core.project.http.HttpToken;
+import com.x.base.core.project.http.WrapOutBoolean;
+import com.x.base.core.project.jaxrs.WrapString;
+import com.x.base.core.project.logger.Logger;
+import com.x.base.core.project.logger.LoggerFactory;
+import com.x.base.core.project.tools.Host;
+import com.x.base.core.project.tools.ListTools;
+import com.x.organization.core.entity.Person;
+import com.x.program.center.Business;
+import com.x.program.center.core.entity.Application;
+import com.x.program.center.core.entity.Attachment;
+import org.apache.commons.lang3.BooleanUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.eclipse.jetty.deploy.App;
+import org.quartz.JobExecutionContext;
+import org.quartz.JobExecutionException;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class CollectMarket extends BaseAction {
+
+	private static Logger logger = LoggerFactory.getLogger(CollectMarket.class);
+
+	@Override
+	public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
+
+		try {
+			if (pirmaryCenter() && BooleanUtils.isTrue(Config.collect().getEnable())) {
+				try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
+					Business business = new Business(emc);
+					String token = business.loginCollect();
+					if (StringUtils.isNotEmpty(token)) {
+						logger.info("开始同步应用市场数据=====");
+						List<Wi> wiList = null;
+						try {
+							ActionResponse response = ConnectionAction
+									.get(Config.collect().url(Collect.ADDRESS_COLLECT_APPLICATION_LIST),
+											ListTools.toList(new NameValuePair(Collect.COLLECT_TOKEN, token)));
+							wiList = response.getDataAsList(Wi.class);
+						} catch (Exception e) {
+							logger.warn("与云服务器连接错误:{}." + e.getMessage());
+						}
+						if(wiList!=null && !wiList.isEmpty()){
+							logger.info("将要同步应用数:{}",wiList.size());
+							emc.beginTransaction(Application.class);
+							emc.beginTransaction(Attachment.class);
+							List<Application> appList = emc.listAll(Application.class);
+							Map<String, Application> appMap = new HashMap<>();
+							List<String> appIds = ListTools.extractField(wiList, JpaObject.id_FIELDNAME, String.class, true, true);
+							for (Application app : appList){
+								if(appIds.contains(app.getId())){
+									appMap.put(app.getId(), app);
+								}else{
+									List<Attachment> attachments = emc.listEqual(Attachment.class, Attachment.application_FIELDNAME, app.getId());
+									for(Attachment att : attachments){
+										emc.remove(att);
+									}
+									emc.remove(app);
+								}
+							}
+							for(Wi wi : wiList){
+								Application app = appMap.get(wi.getId());
+								if(app != null){
+									if(wi.getLastUpdateTime().compareTo(app.getLastUpdateTime()) == 1){
+										Wi.copier.copy(wi, app);
+										emc.persist(app, CheckPersistType.all);
+										List<Attachment> attachments = emc.listEqual(Attachment.class, Attachment.application_FIELDNAME, app.getId());
+										List<String> attIds = ListTools.extractField(wi.getAttList(), JpaObject.id_FIELDNAME, String.class, true, true);
+										List<String> attIds2 = new ArrayList<>();
+										for(Attachment att : attachments){
+											if(attIds.contains(att.getId())){
+												attIds2.add(att.getId());
+											}else{
+												emc.remove(att);
+											}
+										}
+										if(wi.getAttList() != null){
+											for (Attachment att : wi.getAttList()){
+												if(!attIds2.contains(att.getId())){
+													emc.persist(att, CheckPersistType.all);
+												}
+											}
+										}
+									}
+								}else{
+									app = Wi.copier.copy(wi);
+									emc.persist(app, CheckPersistType.all);
+									if(wi.attList!=null){
+										for(Attachment att: wi.attList){
+											emc.persist(att, CheckPersistType.all);
+										}
+									}
+								}
+							}
+							emc.commit();
+						}
+						logger.info("完成同步应用市场数据=====");
+					} else {
+						logger.debug("无法登录到云服务器.");
+					}
+				}
+			} else {
+				logger.debug("系统没有启用O2云服务器连接.");
+			}
+		} catch (Exception e) {
+			logger.error(e);
+			throw new JobExecutionException(e);
+		}
+	}
+
+	public static class Wi extends Application {
+
+		static WrapCopier<Wi, Application> copier = WrapCopierFactory.wo(Wi.class, Application.class, null, ListTools.toList("attList"));
+
+		private List<Attachment> attList = new ArrayList<>();
+
+		public List<Attachment> getAttList() {
+			return attList;
+		}
+
+		public void setAttList(List<Attachment> attList) {
+			this.attList = attList;
+		}
+	}
+
+
+}

+ 263 - 0
o2server/x_program_center_core_entity/src/main/java/com/x/program/center/core/entity/Application.java

@@ -0,0 +1,263 @@
+package com.x.program.center.core.entity;
+
+import com.x.base.core.entity.JpaObject;
+import com.x.base.core.entity.SliceJpaObject;
+import com.x.base.core.entity.annotation.CheckPersist;
+import com.x.base.core.entity.annotation.ContainerEntity;
+import com.x.base.core.project.annotation.FieldDescribe;
+import org.apache.openjpa.persistence.jdbc.Index;
+
+import javax.persistence.*;
+import java.util.Date;
+
+@ContainerEntity
+@Entity
+@Table(name = PersistenceProperties.Application.table, uniqueConstraints = {
+		@UniqueConstraint(name = PersistenceProperties.Application.table + JpaObject.IndexNameMiddle
+				+ JpaObject.DefaultUniqueConstraintSuffix, columnNames = { JpaObject.IDCOLUMN,
+						JpaObject.CREATETIMECOLUMN, JpaObject.UPDATETIMECOLUMN, JpaObject.SEQUENCECOLUMN }) })
+@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
+public class Application extends SliceJpaObject {
+
+	private static final long serialVersionUID = 874852784032487858L;
+
+	private static final String TABLE = PersistenceProperties.Application.table;
+
+	public String getId() {
+		return id;
+	}
+
+	public void setId(String id) {
+		this.id = id;
+	}
+
+	@FieldDescribe("数据库主键,自动生成.")
+	@Id
+	@Column(length = length_id, name = ColumnNamePrefix + id_FIELDNAME)
+	private String id = createId();
+
+	/* 以上为 JpaObject 默认字段 */
+
+	public void onPersist() throws Exception {
+	}
+
+	public static final String name_FIELDNAME = "name";
+
+	@FieldDescribe("名称")
+	@Column(length = JpaObject.length_255B, name = ColumnNamePrefix + name_FIELDNAME)
+	@Index(name = TABLE + IndexNameMiddle + name_FIELDNAME)
+	@CheckPersist(allowEmpty = false)
+	private String name;
+
+	public static final String category_FIELDNAME = "category";
+	@FieldDescribe("分类")
+	@Column(length = JpaObject.length_255B, name = ColumnNamePrefix + category_FIELDNAME)
+	@Index(name = TABLE + IndexNameMiddle + category_FIELDNAME)
+	@CheckPersist(allowEmpty = true)
+	private String category;
+
+	public static final String subCategory_FIELDNAME = "subCategory";
+	@FieldDescribe("子分类.")
+	@Column(length = JpaObject.length_255B, name = ColumnNamePrefix + subCategory_FIELDNAME)
+	@CheckPersist(allowEmpty = true)
+	private String subCategory;
+
+	public static final String version_FIELDNAME = "version";
+	@FieldDescribe("版本")
+	@Column(length = JpaObject.length_255B, name = ColumnNamePrefix + version_FIELDNAME)
+	@CheckPersist(allowEmpty = true)
+	private String version;
+
+	public static final String price_FIELDNAME = "price";
+	@FieldDescribe("价格.")
+	@Column(name = ColumnNamePrefix + price_FIELDNAME)
+	@CheckPersist(allowEmpty = true)
+	private Double price;
+
+	public static final String abort_FIELDNAME = "abort";
+	@FieldDescribe("应用简介")
+	@Lob
+	@Basic(fetch = FetchType.EAGER)
+	@Column(length = JpaObject.length_4K, name = ColumnNamePrefix + abort_FIELDNAME)
+	@CheckPersist(allowEmpty = true)
+	private String abort;
+
+	public static final String installSteps_FIELDNAME = "installSteps";
+	@FieldDescribe("应用安装步骤")
+	@Lob
+	@Basic(fetch = FetchType.EAGER)
+	@Column(length = JpaObject.length_1M, name = ColumnNamePrefix + installSteps_FIELDNAME)
+	@CheckPersist(allowEmpty = true)
+	private String installSteps;
+
+	public static final String icon_FIELDNAME = "icon";
+	@FieldDescribe("首页图片 Base64编码后的文本.")
+	@Lob
+	@Basic(fetch = FetchType.EAGER)
+	@Column(length = JpaObject.length_1M, name = ColumnNamePrefix + icon_FIELDNAME)
+	private String icon;
+
+	public static final String publisher_FIELDNAME = "publisher";
+	@FieldDescribe("发布者.")
+	@Column(length = JpaObject.length_255B, name = ColumnNamePrefix + publisher_FIELDNAME)
+	@Index(name = TABLE + IndexNameMiddle + publisher_FIELDNAME)
+	@CheckPersist(allowEmpty = false)
+	private String publisher;
+
+	public static final String publishTime_FIELDNAME = "publishTime";
+	@FieldDescribe("发布时间")
+	@Column(name = ColumnNamePrefix + publishTime_FIELDNAME)
+	@Index(name = TABLE + IndexNameMiddle + publishTime_FIELDNAME)
+	@CheckPersist(allowEmpty = true)
+	private Date publishTime;
+
+	public static final String grade_FIELDNAME = "grade";
+	@FieldDescribe("评分.")
+	@Column(name = ColumnNamePrefix + grade_FIELDNAME)
+	@Index(name = TABLE + IndexNameMiddle + grade_FIELDNAME)
+	private Double grade;
+
+	public static final String orderNumber_FIELDNAME = "orderNumber";
+	@FieldDescribe("排序号,升序排列,为空在最后")
+	@Column(name = ColumnNamePrefix + orderNumber_FIELDNAME)
+	@Index(name = TABLE + IndexNameMiddle + orderNumber_FIELDNAME)
+	private Integer orderNumber;
+
+	public static final String recommend_FIELDNAME = "recommend";
+	@FieldDescribe("推荐指数")
+	@Column(name = ColumnNamePrefix + recommend_FIELDNAME)
+	@Index(name = TABLE + IndexNameMiddle + recommend_FIELDNAME)
+	private Integer recommend;
+
+	public static final String downloadCount_FIELDNAME = "downloadCount";
+	@FieldDescribe("下载次数")
+	@Column(name = ColumnNamePrefix + downloadCount_FIELDNAME)
+	private Integer downloadCount;
+
+	public static final String lastUpdateTime_FIELDNAME = "lastUpdateTime";
+	@FieldDescribe("最后更新时间")
+	@Column(name = ColumnNamePrefix + lastUpdateTime_FIELDNAME)
+	@Index(name = TABLE + IndexNameMiddle + lastUpdateTime_FIELDNAME)
+	@CheckPersist(allowEmpty = false)
+	private Date lastUpdateTime;
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public String getCategory() {
+		return category;
+	}
+
+	public void setCategory(String category) {
+		this.category = category;
+	}
+
+	public String getIcon() {
+		return icon;
+	}
+
+	public void setIcon(String icon) {
+		this.icon = icon;
+	}
+
+	public Integer getDownloadCount() {
+		return downloadCount;
+	}
+
+	public void setDownloadCount(Integer downloadCount) {
+		this.downloadCount = downloadCount;
+	}
+
+	public String getSubCategory() {
+		return subCategory;
+	}
+
+	public void setSubCategory(String subCategory) {
+		this.subCategory = subCategory;
+	}
+
+	public String getVersion() {
+		return version;
+	}
+
+	public void setVersion(String version) {
+		this.version = version;
+	}
+
+	public Double getPrice() {
+		return price;
+	}
+
+	public void setPrice(Double price) {
+		this.price = price;
+	}
+
+	public String getAbort() {
+		return abort;
+	}
+
+	public void setAbort(String abort) {
+		this.abort = abort;
+	}
+
+	public String getInstallSteps() {
+		return installSteps;
+	}
+
+	public void setInstallSteps(String installSteps) {
+		this.installSteps = installSteps;
+	}
+
+	public String getPublisher() {
+		return publisher;
+	}
+
+	public void setPublisher(String publisher) {
+		this.publisher = publisher;
+	}
+
+	public Date getPublishTime() {
+		return publishTime;
+	}
+
+	public void setPublishTime(Date publishTime) {
+		this.publishTime = publishTime;
+	}
+
+	public Integer getOrderNumber() {
+		return orderNumber;
+	}
+
+	public void setOrderNumber(Integer orderNumber) {
+		this.orderNumber = orderNumber;
+	}
+
+	public Integer getRecommend() {
+		return recommend;
+	}
+
+	public void setRecommend(Integer recommend) {
+		this.recommend = recommend;
+	}
+
+	public Date getLastUpdateTime() {
+		return lastUpdateTime;
+	}
+
+	public void setLastUpdateTime(Date lastUpdateTime) {
+		this.lastUpdateTime = lastUpdateTime;
+	}
+
+	public Double getGrade() {
+		return grade;
+	}
+
+	public void setGrade(Double grade) {
+		this.grade = grade;
+	}
+}

+ 147 - 0
o2server/x_program_center_core_entity/src/main/java/com/x/program/center/core/entity/Attachment.java

@@ -0,0 +1,147 @@
+package com.x.program.center.core.entity;
+
+import com.x.base.core.entity.*;
+import com.x.base.core.entity.annotation.CheckPersist;
+import com.x.base.core.entity.annotation.CitationNotExist;
+import com.x.base.core.entity.annotation.ContainerEntity;
+import com.x.base.core.entity.annotation.Equal;
+import com.x.base.core.project.annotation.FieldDescribe;
+import com.x.base.core.project.tools.DateTools;
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.lang3.BooleanUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.openjpa.persistence.jdbc.Index;
+
+import javax.persistence.*;
+import java.util.Date;
+
+@ContainerEntity
+@Entity
+@Table(name = PersistenceProperties.Attachment.table, uniqueConstraints = {
+		@UniqueConstraint(name = PersistenceProperties.Attachment.table + JpaObject.IndexNameMiddle
+				+ JpaObject.DefaultUniqueConstraintSuffix, columnNames = { JpaObject.IDCOLUMN,
+						JpaObject.CREATETIMECOLUMN, JpaObject.UPDATETIMECOLUMN, JpaObject.SEQUENCECOLUMN }) })
+@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
+public class Attachment extends SliceJpaObject {
+
+	private static final long serialVersionUID = 7706126788445253456L;
+
+	private static final String TABLE = PersistenceProperties.Attachment.table;
+
+	public String getId() {
+		return id;
+	}
+
+	public void setId(String id) {
+		this.id = id;
+	}
+
+	@FieldDescribe("数据库主键,自动生成.")
+	@Id
+	@Column(length = length_id, name = ColumnNamePrefix + id_FIELDNAME)
+	private String id = createId();
+
+	/* 以上为 JpaObject 默认字段 */
+
+	public void onPersist() throws Exception {
+	}
+
+	/* 更新运行方法 */
+
+	public Attachment() {
+
+	}
+
+	public static final String person_FIELDNAME = "person";
+	@FieldDescribe("所属用户.")
+	@Column(length = length_255B, name = ColumnNamePrefix + person_FIELDNAME)
+	@Index(name = TABLE + IndexNameMiddle + person_FIELDNAME)
+	@CheckPersist(allowEmpty = false)
+	private String person;
+
+	public static final String name_FIELDNAME = "name";
+	@FieldDescribe("文件名称.")
+	@Column(length = length_255B, name = ColumnNamePrefix + name_FIELDNAME)
+	@Index(name = TABLE + IndexNameMiddle + name_FIELDNAME)
+	@CheckPersist(allowEmpty = false, fileNameString = true, citationNotExists =
+	/* 同一应用下不能有重名 */
+	@CitationNotExist(fields = { "name", "id" }, type = Attachment.class, equals = {
+			@Equal(property = "application", field = "application") }))
+	private String name;
+
+	public static final String application_FIELDNAME = "application";
+	@FieldDescribe("归属应用ID.")
+	@Column(length = JpaObject.length_id, name = ColumnNamePrefix + application_FIELDNAME)
+	@Index(name = TABLE + IndexNameMiddle + application_FIELDNAME)
+	@CheckPersist(allowEmpty = false)
+	private String application;
+
+	public static final String type_FIELDNAME = "type";
+	@FieldDescribe("类型:首页图片|图片|视频|安装包|静态资源包.")
+	@Column(length = JpaObject.length_255B, name = ColumnNamePrefix + type_FIELDNAME)
+	@Index(name = TABLE + IndexNameMiddle + type_FIELDNAME)
+	@CheckPersist(allowEmpty = false)
+	private String type;
+
+	public static final String icon_FIELDNAME = "icon";
+	@FieldDescribe("icon Base64编码后的文本.")
+	@Lob
+	@Basic(fetch = FetchType.EAGER)
+	@Column(length = JpaObject.length_1M, name = ColumnNamePrefix + icon_FIELDNAME)
+	private String icon;
+
+	public static final String lastUpdateTime_FIELDNAME = "lastUpdateTime";
+	@FieldDescribe("最后更新时间")
+	@Column(name = ColumnNamePrefix + lastUpdateTime_FIELDNAME)
+	@Index(name = TABLE + IndexNameMiddle + lastUpdateTime_FIELDNAME)
+	@CheckPersist(allowEmpty = false)
+	private Date lastUpdateTime;
+
+	public String getPerson() {
+		return person;
+	}
+
+	public void setPerson(String person) {
+		this.person = person;
+	}
+
+	public String getApplication() {
+		return application;
+	}
+
+	public void setApplication(String application) {
+		this.application = application;
+	}
+
+	public String getType() {
+		return type;
+	}
+
+	public void setType(String type) {
+		this.type = type;
+	}
+
+	public String getIcon() {
+		return icon;
+	}
+
+	public void setIcon(String icon) {
+		this.icon = icon;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public Date getLastUpdateTime() {
+		return lastUpdateTime;
+	}
+
+	public void setLastUpdateTime(Date lastUpdateTime) {
+		this.lastUpdateTime = lastUpdateTime;
+	}
+}

+ 8 - 0
o2server/x_program_center_core_entity/src/main/java/com/x/program/center/core/entity/PersistenceProperties.java

@@ -64,6 +64,14 @@ public final class PersistenceProperties extends AbstractPersistenceProperties {
 		public static final String table = "CTE_INVOKE";
 		public static final String table = "CTE_INVOKE";
 	}
 	}
 
 
+	public static class Application {
+		public static final String table = "CTE_APPLICATION";
+	}
+
+	public static class Attachment {
+		public static final String table = "CTE_ATTACHMENT";
+	}
+
 	public static class Validation {
 	public static class Validation {
 		public static class Meta {
 		public static class Meta {
 			public static final String table = "VAL_META";
 			public static final String table = "VAL_META";