!3 merge 0.0.3 to master

Merge pull request !3 from Shaun Chyxion/feature/v0.0.3
This commit is contained in:
Shaun Chyxion 2022-05-22 08:13:26 +00:00 committed by Gitee
commit e85857702c
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
139 changed files with 2290 additions and 13679 deletions

1
.gitignore vendored
View File

@ -17,6 +17,7 @@
/web/libpeerconnection.log
/web/npm-debug.log
/web/testem.log
/web/package-lock.json
.*
!.editorconfig

View File

@ -17,7 +17,7 @@
<properties>
<project.build.finalName>ambition-crm</project.build.finalName>
<start-class>com.pudonghot.ambition.crm.AmbitionCRM</start-class>
<spring-boot.run.main-class>com.pudonghot.ambition.crm.AmbitionCRM</spring-boot.run.main-class>
</properties>
<dependencies>
@ -99,6 +99,10 @@
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<skip>false</skip>
<fork>true</fork>
</configuration>
</plugin>
</plugins>
</build>

View File

@ -1,8 +1,8 @@
package com.pudonghot.ambition.crm.auth;
import lombok.val;
import lombok.extern.slf4j.Slf4j;
import me.chyxion.tigon.model.ViewModel;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import me.chyxion.tigon.shiro.AuthCallback;
import me.chyxion.tigon.shiro.model.AuthUser;
@ -43,23 +43,23 @@ public class AuthCallbackSupport implements AuthCallback {
public void onSuccessfulLogin(AuthenticationToken token,
AuthenticationInfo info, Subject subject) {
WebSubject ws = (WebSubject) subject;
Session session = ws.getSession(false);
HttpServletRequest request = (HttpServletRequest) ws.getServletRequest();
val ws = (WebSubject) subject;
val session = ws.getSession(false);
val request = (HttpServletRequest) ws.getServletRequest();
AuthUser<ViewModel<User>> authUser = new AuthUser<ViewModel<User>>();
String ip = HttpServletRequestUtils.getClientIP(request);
val authUser = new AuthUser<ViewModel<User>>();
val ip = HttpServletRequestUtils.getClientIP(request);
authUser.setAttr("ip", ip);
String userAgent = request.getHeader("User-Agent");
val userAgent = request.getHeader("User-Agent");
authUser.setAttr("userAgent", userAgent);
ViewModel<User> user = (ViewModel<User>) ((AuthInfo) info).getExtra();
final String userId = user.getData().getId();
val user = (ViewModel<User>) ((AuthInfo) info).getExtra();
val userId = user.getData().getId();
authUser.setUserId(userId);
authUser.setUser(user);
log.info("Save Auth User [{}] To Session [{}].", user, session.getId());
authUser.save(session);
AuthLogFormForCreate alForm = new AuthLogFormForCreate();
val alForm = new AuthLogFormForCreate();
alForm.setUserId(userId);
alForm.setIp(ip);
alForm.setUserAgent(userAgent);
@ -68,7 +68,6 @@ public class AuthCallbackSupport implements AuthCallback {
authLogService.create(alForm);
// HttpServletResponse response = (HttpServletResponse) ws.getServletResponse();
log.info("User [{}] Logined.", userId);
}
/**
@ -76,14 +75,16 @@ public class AuthCallbackSupport implements AuthCallback {
*/
@Override
public void onFailedLogin(AuthenticationToken token,
AuthenticationException ae, Subject subject) {
String loginId = (String) token.getPrincipal();
String password = new String((char[]) token.getCredentials());
AuthenticationException ae,
Subject subject) {
val loginId = (String) token.getPrincipal();
val password = new String((char[]) token.getCredentials());
log.info("Login Id [{}] Password [{}] Login Failed.", loginId, password);
WebSubject ws = (WebSubject) subject;
HttpServletRequest request = (HttpServletRequest) ws.getServletRequest();
AuthFailedLogFormForCreate form = new AuthFailedLogFormForCreate();
val ws = (WebSubject) subject;
val request = (HttpServletRequest) ws.getServletRequest();
val form = new AuthFailedLogFormForCreate();
form.setLoginId(loginId);
form.setPassword(password);
form.setIp(HttpServletRequestUtils.getClientIP(request));
@ -95,9 +96,9 @@ public class AuthCallbackSupport implements AuthCallback {
* {@inheritDoc}
*/
@Override
public void beforeLogout(Subject subject) {
final WebSubject ws = (WebSubject) subject;
final Session session = ws.getSession(false);
public void beforeLogout(final Subject subject) {
val ws = (WebSubject) subject;
val session = ws.getSession(false);
if (session != null) {
log.warn("Session [{}] Logout.", session);
}

View File

@ -1,11 +1,11 @@
package com.pudonghot.ambition.crm.auth;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.*;
import lombok.val;
import me.chyxion.tigon.mybatis.Search;
import me.chyxion.tigon.model.ViewModel;
import me.chyxion.tigon.shiro.AuthRealm;
import org.apache.commons.lang3.ArrayUtils;
import com.pudonghot.ambition.crm.model.User;
import org.springframework.stereotype.Service;
import me.chyxion.tigon.shiro.model.Credential;
@ -32,7 +32,7 @@ public class AuthRealmSupport extends AuthRealm {
@Override
public Credential credential(Object principal) {
Credential credential = null;
final ViewModel<User> userViewModel =
val userViewModel =
userService.findViewModel(new Search(User.EMPLOYEE_ID, principal));
if (userViewModel != null) {
User admin = userViewModel.getData();
@ -56,8 +56,20 @@ public class AuthRealmSupport extends AuthRealm {
new String((char[])password));
}
/**
* {@inheritDoc}
*/
@Override
public Collection<String> roles(Object principal) {
final User user = userService.find(new Search(User.EMPLOYEE_ID, principal));
return user.isAdmin() ? Arrays.asList(User.ROLE_ADMIN) : Collections.emptyList();
val user = userService.find(new Search(User.EMPLOYEE_ID, principal));
val roles = new ArrayList<String>(4);
if (user.isAdmin()) {
roles.add(User.ROLE_ADMIN);
}
val account = user.getAccount();
if (ArrayUtils.contains(new String[] {User.ROLE_LELI, User.ROLE_CHYXION}, account)) {
roles.add(account);
}
return roles;
}
}

View File

@ -1,5 +1,6 @@
package com.pudonghot.ambition.crm.controller;
import lombok.val;
import java.util.*;
import java.net.URLDecoder;
import java.io.IOException;
@ -87,7 +88,7 @@ public abstract class AbstractBaseController {
}
catch (IOException e) {
throw new IllegalStateException(
"Read Stream Bytes Error Caused", e);
"Read stream bytes error caused", e);
}
}
@ -176,7 +177,7 @@ public abstract class AbstractBaseController {
search.limit(limit);
}
if (StringUtils.isNotBlank(strSearch)) {
final Search orSearch = new Search();
val orSearch = new Search();
for (final String col : searchCols()) {
orSearch.or(new Search().like(col, decodeLike(strSearch)));
}
@ -203,15 +204,16 @@ public abstract class AbstractBaseController {
"Invalid criteria [" + strCriteria + "]", e);
}
for (final Object[] criterion : criteria) {
for (val criterion : criteria) {
if (criterion.length == 3) {
final String field = (String) criterion[0];
if (StringUtils.isNotBlank(field)) {
final Pair<String, Class<?>> colProp = criterionCol(field);
final String col = colProp.getKey();
val colProp = criterionCol(field);
val col = colProp.getKey();
if (StringUtils.isNotBlank(col)) {
final String op = (String) criterion[1];
final Object val = TypeUtils.castToJavaBean(criterion[2], colProp.getValue());
val op = (String) criterion[1];
val val = TypeUtils.castToJavaBean(criterion[2], colProp.getValue());
if (StringUtils.isNotBlank(op) &&
val != null && val instanceof String ?
StringUtils.isNotBlank((String) val) : true) {
@ -274,12 +276,12 @@ public abstract class AbstractBaseController {
}
final JSONObject joFilters = filters(strFilters);
for (Map.Entry<String, Object> filter : joFilters.entrySet()) {
final String field = filter.getKey();
final Pair<String, Class<?>> colProp = filterCol(filter.getKey());
for (val filter : joFilters.entrySet()) {
val field = filter.getKey();
val colProp = filterCol(filter.getKey());
if (colProp != null) {
final String col = colProp.getKey();
final Object filterVal = filter.getValue();
val col = colProp.getKey();
val filterVal = filter.getValue();
if (filterVal != null) {
if (onSearch(search, col, filterVal)) {
continue;
@ -308,12 +310,12 @@ public abstract class AbstractBaseController {
throw new IllegalStateException(
"Invalid orders params [" + strOrders + "]", e);
}
for (final Object objOrder : jaOrders) {
final JSONObject joSorter = (JSONObject) objOrder;
for (val objOrder : jaOrders) {
val joSorter = (JSONObject) objOrder;
if (!joSorter.isEmpty()) {
final Map.Entry<String, Object> sortEntry =
val sortEntry =
joSorter.entrySet().iterator().next();
final String col = orderCol(sortEntry.getKey());
val col = orderCol(sortEntry.getKey());
if (StringUtils.isNotBlank(col)) {
final String dir = (String) sortEntry.getValue();
if ("asc".equalsIgnoreCase(dir)) {

View File

@ -11,9 +11,9 @@ import me.chyxion.tigon.model.ViewModel;
import me.chyxion.tigon.model.ListResult;
import com.pudonghot.ambition.crm.model.*;
import org.apache.commons.lang3.tuple.Pair;
import javax.validation.constraints.NotBlank;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Controller;
import org.hibernate.validator.constraints.NotBlank;
import com.pudonghot.ambition.crm.service.UserService;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.web.bind.annotation.RequestParam;
@ -25,8 +25,8 @@ import com.pudonghot.ambition.crm.form.create.ApplicationFormForCreate;
import com.pudonghot.ambition.crm.form.update.ApplicationFormForUpdate;
import com.pudonghot.ambition.crm.form.create.ApplicationImageFormForCreate;
import com.pudonghot.ambition.crm.form.update.ApplicationImageFormForUpdate;
import com.pudonghot.ambition.crm.form.create.ApplicationAttachmentFormForCreate;
import com.pudonghot.ambition.crm.form.update.ApplicationAttachmentFormForUpdate;
import com.pudonghot.ambition.crm.form.create.ApplicationAttachedFileFormForCreate;
import com.pudonghot.ambition.crm.form.update.ApplicationAttachedFileFormForUpdate;
/**
* @author Shaun Chyxion <br>
@ -41,8 +41,8 @@ public class ApplicationController
@Autowired
private UserService userService;
private final List<String> SEARCH_COLS =
Arrays.asList(CustomerProperty.NAME,
CustomerProperty.NOTE);
Arrays.asList(Application.NAME,
Application.NOTE);
@RequestMapping("/list")
public ListResult<ViewModel<Application>> list(
@ -63,6 +63,8 @@ public class ApplicationController
start, limit, strSearch, null, filters, null);
result.setAttr("users", userService.listViewModels(
new Search().asc(User.EMPLOYEE_ID)));
result.setAttr("namePrefixes",
((ApplicationService) queryService).listNamePrefixes());
return result;
}
@ -109,7 +111,7 @@ public class ApplicationController
}
@RequestMapping(value = "/add-image", method = RequestMethod.POST)
public ViewModel<ApplicationImage> addImage(
public ViewModel<AttachedImage> addImage(
@Valid ApplicationImageFormForCreate form) {
Assert.state(!form.getImage().isEmpty(), "Image content is empty");
form.setAdmin(getAuthUser().getUser().getData().isAdmin());
@ -129,8 +131,8 @@ public class ApplicationController
}
@RequestMapping(value = "/add-attachment", method = RequestMethod.POST)
public ViewModel<ApplicationAttachment> addAttachment(
@Valid ApplicationAttachmentFormForCreate form) {
public ViewModel<AttachedFile> addAttachment(
@Valid ApplicationAttachedFileFormForCreate form) {
Assert.state(!form.getAttachment().isEmpty(), "Image content is empty");
form.setAdmin(getAuthUser().getUser().getData().isAdmin());
return new ViewModel<>(((ApplicationService) queryService).addAttachment(form));
@ -143,7 +145,7 @@ public class ApplicationController
}
@RequestMapping(value = "/update-attachment", method = RequestMethod.POST)
public void updateImage(@Valid ApplicationAttachmentFormForUpdate form) {
public void updateImage(@Valid ApplicationAttachedFileFormForUpdate form) {
form.setAdmin(getAuthUser().getUser().getData().isAdmin());
((ApplicationService) queryService).updateAttachment(form);
}
@ -167,6 +169,12 @@ public class ApplicationController
*/
@Override
protected Pair<String, Class<?>> filterCol(final String field) {
return Application.OWNER.equals(field) ? Pair.of(field, String.class) : null;
if (Application.OWNER.equals(field)) {
return Pair.of(field, String.class);
}
if (Application.NAME_PREFIX.equals(field)) {
return Pair.of(field, String.class);
}
return null;
}
}

View File

@ -6,7 +6,7 @@ import me.chyxion.tigon.model.ViewModel;
import com.pudonghot.ambition.crm.model.User;
import org.springframework.stereotype.Controller;
import me.chyxion.tigon.shiro.service.AuthService;
import org.hibernate.validator.constraints.NotBlank;
import javax.validation.constraints.NotBlank;
import com.pudonghot.ambition.crm.service.UserService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestParam;

View File

@ -6,7 +6,7 @@ import me.chyxion.tigon.model.BaseModel;
import me.chyxion.tigon.model.ViewModel;
import me.chyxion.tigon.model.ListResult;
import me.chyxion.tigon.service.BaseQueryService;
import org.hibernate.validator.constraints.NotBlank;
import javax.validation.constraints.NotBlank;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;

View File

@ -1,5 +1,6 @@
package com.pudonghot.ambition.crm.controller;
import lombok.val;
import java.util.*;
import javax.validation.Valid;
import lombok.extern.slf4j.Slf4j;
@ -11,6 +12,7 @@ import javax.validation.constraints.Min;
import me.chyxion.tigon.model.ListResult;
import org.apache.commons.lang3.tuple.Pair;
import me.chyxion.tigon.webmvc.ResourceModel;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import org.apache.commons.lang3.StringUtils;
import com.pudonghot.ambition.crm.model.User;
@ -20,6 +22,7 @@ import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.web.multipart.MultipartFile;
import com.pudonghot.ambition.crm.model.CustomerProperty;
import com.pudonghot.ambition.crm.service.CustomerService;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestMapping;
@ -39,7 +42,7 @@ public class CustomerController
extends BaseQueryController<Customer> {
private static final List<String> SEARCH_COLS = Arrays.asList(
"customer.id",
"customer.id2",
"customer.name",
"customer.city",
"customer.country_code",
@ -122,8 +125,8 @@ public class CustomerController
@RequestParam(value = "orders", required = false)
final String orders) {
final Search search = new Search();
User user = getUser().getData();
val search = new Search();
val user = getUser().getData();
search.setAttr(User.ACCOUNT, user.getAccount());
// search year
@ -163,6 +166,12 @@ public class CustomerController
"text/csv; charset=gbk", null);
}
@RequiresRoles(User.ROLE_ADMIN)
@PostMapping("/delete")
public void delete(@NotBlank @RequestParam("id") String id) {
((CustomerService) queryService).delete(id);
}
/**
* {@inheritDoc}
*/

View File

@ -10,7 +10,7 @@ import org.apache.ibatis.annotations.Param;
import com.pudonghot.ambition.crm.model.User;
import com.pudonghot.ambition.crm.model.HomePage;
import org.springframework.stereotype.Controller;
import org.hibernate.validator.constraints.NotBlank;
import javax.validation.constraints.NotBlank;
import org.apache.shiro.authz.annotation.RequiresRoles;
import com.pudonghot.ambition.crm.service.HomePageService;
import org.springframework.web.bind.annotation.RequestParam;

View File

@ -0,0 +1,177 @@
package com.pudonghot.ambition.crm.controller;
import java.util.List;
import java.util.Arrays;
import javax.validation.Valid;
import org.springframework.util.Assert;
import me.chyxion.tigon.mybatis.Search;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import me.chyxion.tigon.model.ViewModel;
import me.chyxion.tigon.model.ListResult;
import com.pudonghot.ambition.crm.model.*;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.commons.lang3.StringUtils;
import javax.validation.constraints.NotBlank;
import org.springframework.stereotype.Controller;
import org.apache.shiro.authz.annotation.Logical;
import com.pudonghot.ambition.crm.service.UserService;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestMethod;
import com.pudonghot.ambition.crm.service.LocalProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import com.pudonghot.ambition.crm.form.create.LocalProductFormForCreate;
import com.pudonghot.ambition.crm.form.update.LocalProductFormForUpdate;
import com.pudonghot.ambition.crm.form.create.LocalProductImageFormForCreate;
import com.pudonghot.ambition.crm.form.update.LocalProductImageFormForUpdate;
import com.pudonghot.ambition.crm.form.create.LocalProductAttachedFileFormForCreate;
import com.pudonghot.ambition.crm.form.update.LocalProductAttachedFileFormForUpdate;
/**
* @author Shaun Chyxion <br>
* chyxion@163.com <br>
* Jun 23, 2017 21:39:49
*/
@Controller
@RequestMapping("/local-product")
public class LocalProductController
extends BaseQueryController<LocalProduct> {
@Autowired
private UserService userService;
private final List<String> SEARCH_COLS =
Arrays.asList(CustomerProperty.NAME,
CustomerProperty.NOTE);
@RequestMapping("/list")
public ListResult<ViewModel<LocalProduct>> list(
@Min(0)
@RequestParam(value = "start", defaultValue = "0")
final int start,
@Min(1)
@Max(2048)
@RequestParam(value = "limit", defaultValue = "16")
final int limit,
@RequestParam(value = "filters", required = false)
final String filters,
@RequestParam(value = "orders", required = false)
final String orders,
@RequestParam(value = "search", required = false)
final String strSearch) {
final ListResult<ViewModel<LocalProduct>> result =
listViewModels(start, limit, strSearch, null, filters, orders);
result.setAttr("namePrefixes",
((LocalProductService) queryService).listNamePrefixes());
return result;
}
@RequiresRoles(value = {User.ROLE_LELI, User.ROLE_CHYXION, User.ROLE_ADMIN}, logical = Logical.OR)
@RequestMapping(value = "/create", method = RequestMethod.POST)
public void create(
@Valid LocalProductFormForCreate form) {
((LocalProductService) queryService).create(form);
}
@RequiresRoles(value = {User.ROLE_LELI, User.ROLE_CHYXION, User.ROLE_ADMIN}, logical = Logical.OR)
@RequestMapping(value = "/update", method = RequestMethod.POST)
public void update(
@Valid LocalProductFormForUpdate form) {
((LocalProductService) queryService).update(form);
}
/**
* {@inheritDoc}
*/
@Override
public ViewModel<LocalProduct> find(final String id) {
final ViewModel<LocalProduct> viewModel = queryService.findViewModel(id);
if (getAuthUser().getUser().getData().isAdmin()) {
viewModel.setAttr("users", userService.listViewModels(
new Search().asc(User.EMPLOYEE_ID)));
}
return viewModel;
}
@RequiresRoles(value = {User.ROLE_LELI, User.ROLE_CHYXION, User.ROLE_ADMIN}, logical = Logical.OR)
@RequestMapping(value = "/add-image", method = RequestMethod.POST)
public ViewModel<AttachedImage> addImage(
@Valid LocalProductImageFormForCreate form) {
Assert.state(!form.getImage().isEmpty(), "Image content is empty");
return new ViewModel<>(((LocalProductService) queryService).addImage(form));
}
@RequiresRoles(value = {User.ROLE_LELI, User.ROLE_CHYXION, User.ROLE_ADMIN}, logical = Logical.OR)
@RequestMapping(value = "/remove-image", method = RequestMethod.POST)
public void removeImage(@NotBlank @RequestParam("id") String id) {
((LocalProductService) queryService).removeImage(id);
}
@RequiresRoles(value = {User.ROLE_LELI, User.ROLE_CHYXION, User.ROLE_ADMIN}, logical = Logical.OR)
@RequestMapping(value = "/update-image", method = RequestMethod.POST)
public void updateImage(@Valid LocalProductImageFormForUpdate form) {
((LocalProductService) queryService).updateImage(form);
}
@RequiresRoles(value = {User.ROLE_LELI, User.ROLE_CHYXION, User.ROLE_ADMIN}, logical = Logical.OR)
@RequestMapping(value = "/add-attachment", method = RequestMethod.POST)
public ViewModel<AttachedFile> addAttachment(
@Valid LocalProductAttachedFileFormForCreate form) {
Assert.state(!form.getAttachment().isEmpty(), "Image content is empty");
return new ViewModel<>(((LocalProductService) queryService).addAttachment(form));
}
@RequestMapping(value = "/remove-attachment", method = RequestMethod.POST)
public void removeAttachment(@NotBlank @RequestParam("id") String id) {
((LocalProductService) queryService).removeAttachment(id);
}
@RequiresRoles(value = {User.ROLE_LELI, User.ROLE_CHYXION, User.ROLE_ADMIN}, logical = Logical.OR)
@RequestMapping(value = "/update-attachment", method = RequestMethod.POST)
public void updateImage(@Valid LocalProductAttachedFileFormForUpdate form) {
((LocalProductService) queryService).updateAttachment(form);
}
@RequiresRoles(value = {User.ROLE_LELI, User.ROLE_CHYXION, User.ROLE_ADMIN}, logical = Logical.OR)
@RequestMapping(value = "/delete", method = RequestMethod.POST)
public void delete(@NotBlank @RequestParam("id") String id) {
((LocalProductService) queryService).delete(id);
}
/**
* {@inheritDoc}
*/
@Override
protected List<String> searchCols() {
return SEARCH_COLS;
}
/**
* {@inheritDoc}
*/
@Override
protected String orderCol(final String field) {
return StringUtils.isNotBlank(field) &&
ArrayUtils.contains(new String[] {
LocalProduct.NAME,
LocalProduct.CATEGORY
}, field) ? field : null;
}
/**
* {@inheritDoc}
*/
@Override
protected Pair<String, Class<?>> filterCol(final String field) {
if (LocalProduct.OWNER.equals(field)) {
return Pair.of(field, String.class);
}
if (LocalProduct.NAME_PREFIX.equals(field)) {
return Pair.of(field, String.class);
}
return null;
}
}

View File

@ -14,7 +14,7 @@ import org.apache.ibatis.annotations.Param;
import javax.validation.constraints.NotNull;
import com.pudonghot.ambition.crm.model.User;
import org.springframework.stereotype.Controller;
import org.hibernate.validator.constraints.NotBlank;
import javax.validation.constraints.NotBlank;
import com.pudonghot.ambition.crm.service.UserService;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.web.bind.annotation.RequestParam;

View File

@ -1,17 +1,19 @@
package com.pudonghot.ambition.crm.service;
import java.util.Map;
import java.util.List;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import com.pudonghot.ambition.crm.model.Application;
import org.hibernate.validator.constraints.NotBlank;
import com.pudonghot.ambition.crm.model.AttachedImage;
import me.chyxion.tigon.service.BaseCrudByFormService;
import com.pudonghot.ambition.crm.model.ApplicationImage;
import com.pudonghot.ambition.crm.model.ApplicationAttachment;
import com.pudonghot.ambition.crm.model.AttachedFile;
import com.pudonghot.ambition.crm.form.update.ApplicationFormForUpdate;
import com.pudonghot.ambition.crm.form.create.ApplicationFormForCreate;
import com.pudonghot.ambition.crm.form.create.ApplicationImageFormForCreate;
import com.pudonghot.ambition.crm.form.update.ApplicationImageFormForUpdate;
import com.pudonghot.ambition.crm.form.create.ApplicationAttachmentFormForCreate;
import com.pudonghot.ambition.crm.form.update.ApplicationAttachmentFormForUpdate;
import com.pudonghot.ambition.crm.form.create.ApplicationAttachedFileFormForCreate;
import com.pudonghot.ambition.crm.form.update.ApplicationAttachedFileFormForUpdate;
/**
* @author Shaun Chyxion <br>
@ -25,7 +27,7 @@ public interface ApplicationService
* add image
* @param form form
*/
ApplicationImage addImage(@Valid ApplicationImageFormForCreate form);
AttachedImage addImage(@Valid ApplicationImageFormForCreate form);
/**
* remove image
@ -41,12 +43,11 @@ public interface ApplicationService
*/
void updateImage(@Valid ApplicationImageFormForUpdate form);
/**
* add attachment
* @param form form
*/
ApplicationAttachment addAttachment(@Valid ApplicationAttachmentFormForCreate form);
AttachedFile addAttachment(@Valid ApplicationAttachedFileFormForCreate form);
/**
* remove attachment
@ -60,6 +61,12 @@ public interface ApplicationService
* update attachment
* @param form form
*/
void updateAttachment(@Valid ApplicationAttachmentFormForUpdate form);
void updateAttachment(@Valid ApplicationAttachedFileFormForUpdate form);
/**
* list name prefixes
* @return name prefixes
*/
List<Map<String, String>> listNamePrefixes();
}

View File

@ -0,0 +1,47 @@
package com.pudonghot.ambition.crm.service;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
import com.pudonghot.ambition.crm.model.Attachment;
import me.chyxion.tigon.model.M2;
import me.chyxion.tigon.mybatis.BaseMapper;
import org.springframework.web.multipart.MultipartFile;
import com.pudonghot.ambition.crm.form.update.AttachmentFormForUpdate;
/**
* @author Shaun Chyxion <br>
* chyxion@163.com <br>
* Jun 23, 2017 21:35:24
*/
public interface AttachmentService {
<T extends Attachment> List<T> upload(
String ownerId,
int sort,
MultipartFile[] files,
String[] titles,
String createdBy,
Supplier<T> constructor,
Consumer<T> insert);
<T extends Attachment> void update(
AttachmentFormForUpdate form,
Function<String, T> finder,
Function<String, List<T>> listSort,
Consumer<T> updater);
<T extends Attachment> void remove(
String id,
Function<String, T> finder,
Function<String, Integer> deleter,
Function<String, Integer> sortUpdater,
Consumer<T> validator);
<Key, M extends M2<Key>> M deleteOwner(
Key id,
BaseMapper<Key, M> mapper,
Consumer<M> validator);
}

View File

@ -3,7 +3,7 @@ package com.pudonghot.ambition.crm.service;
import java.util.List;
import me.chyxion.tigon.model.ViewModel;
import javax.validation.constraints.Min;
import org.hibernate.validator.constraints.NotBlank;
import javax.validation.constraints.NotBlank;
import com.pudonghot.ambition.crm.model.CustomerIssue;
import me.chyxion.tigon.service.BaseCrudByFormService;
import com.pudonghot.ambition.crm.form.create.CustomerIssueFormForCreate;

View File

@ -1,7 +1,7 @@
package com.pudonghot.ambition.crm.service;
import com.alibaba.fastjson.JSONArray;
import org.hibernate.validator.constraints.NotBlank;
import javax.validation.constraints.NotBlank;
import org.hibernate.validator.constraints.NotEmpty;
import me.chyxion.tigon.service.BaseCrudByFormService;
import com.pudonghot.ambition.crm.model.CustomerProperty;

View File

@ -4,7 +4,7 @@ import java.io.File;
import java.io.InputStream;
import javax.validation.constraints.NotNull;
import com.pudonghot.ambition.crm.model.Customer;
import org.hibernate.validator.constraints.NotBlank;
import javax.validation.constraints.NotBlank;
import me.chyxion.tigon.service.BaseCrudByFormService;
import com.pudonghot.ambition.crm.form.create.CustomerFormForCreate;
import com.pudonghot.ambition.crm.form.update.CustomerFormForUpdate;

View File

@ -2,7 +2,7 @@ package com.pudonghot.ambition.crm.service;
import java.io.InputStream;
import javax.validation.constraints.NotNull;
import org.hibernate.validator.constraints.NotBlank;
import javax.validation.constraints.NotBlank;
import me.chyxion.tigon.service.BaseCrudByFormService;
import com.pudonghot.ambition.crm.model.CustomerYearToDateSale;
import com.pudonghot.ambition.crm.form.create.CustomerYearToDateSaleFormForCreate;

View File

@ -2,7 +2,7 @@ package com.pudonghot.ambition.crm.service;
import me.chyxion.tigon.model.ViewModel;
import com.pudonghot.ambition.crm.model.HomePage;
import org.hibernate.validator.constraints.NotBlank;
import javax.validation.constraints.NotBlank;
import me.chyxion.tigon.service.BaseCrudByFormService;
import com.pudonghot.ambition.crm.form.create.HomePageFormForCreate;
import com.pudonghot.ambition.crm.form.update.HomePageFormForUpdate;

View File

@ -0,0 +1,68 @@
package com.pudonghot.ambition.crm.service;
import java.util.Map;
import java.util.List;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import com.pudonghot.ambition.crm.model.LocalProduct;
import com.pudonghot.ambition.crm.model.AttachedFile;
import com.pudonghot.ambition.crm.model.AttachedImage;
import me.chyxion.tigon.service.BaseCrudByFormService;
import com.pudonghot.ambition.crm.form.create.LocalProductFormForCreate;
import com.pudonghot.ambition.crm.form.update.LocalProductFormForUpdate;
import com.pudonghot.ambition.crm.form.create.LocalProductImageFormForCreate;
import com.pudonghot.ambition.crm.form.update.LocalProductImageFormForUpdate;
import com.pudonghot.ambition.crm.form.create.LocalProductAttachedFileFormForCreate;
import com.pudonghot.ambition.crm.form.update.LocalProductAttachedFileFormForUpdate;
/**
* @author Shaun Chyxion <br>
* chyxion@163.com <br>
* Jun 23, 2017 21:35:24
*/
public interface LocalProductService
extends BaseCrudByFormService<String, LocalProduct, LocalProductFormForCreate, LocalProductFormForUpdate> {
/**
* add image
* @param form form
*/
AttachedImage addImage(@Valid LocalProductImageFormForCreate form);
/**
* remove image
* @param id image id
*/
void removeImage(@NotBlank String id);
/**
* update image
* @param form form
*/
void updateImage(@Valid LocalProductImageFormForUpdate form);
/**
* add attachment
* @param form form
*/
AttachedFile addAttachment(@Valid LocalProductAttachedFileFormForCreate form);
/**
* remove attachment
* @param id attachment id
*/
void removeAttachment(@NotBlank String id);
/**
* update attachment
* @param form form
*/
void updateAttachment(@Valid LocalProductAttachedFileFormForUpdate form);
/**
* list name prefixes
* @return name prefixes
*/
List<Map<String, String>> listNamePrefixes();
}

View File

@ -5,7 +5,7 @@ import javax.validation.Valid;
import me.chyxion.tigon.model.ViewModel;
import javax.validation.constraints.NotNull;
import com.pudonghot.ambition.crm.model.User;
import org.hibernate.validator.constraints.NotBlank;
import javax.validation.constraints.NotBlank;
import me.chyxion.tigon.service.BaseCrudByFormService;
import com.pudonghot.ambition.crm.form.create.UserFormForCreate;
import com.pudonghot.ambition.crm.form.update.UserFormForUpdate;

View File

@ -11,7 +11,7 @@ import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import me.chyxion.tigon.service.BaseCrudService;
import com.pudonghot.ambition.crm.model.WeekGoal;
import org.hibernate.validator.constraints.NotBlank;
import javax.validation.constraints.NotBlank;
import com.pudonghot.ambition.crm.form.update.WeekGoalFormForUpdate;
/**

View File

@ -2,24 +2,20 @@ package com.pudonghot.ambition.crm.service.support;
import java.util.Date;
import java.util.List;
import java.util.ArrayList;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
import me.chyxion.tigon.mybatis.Search;
import org.springframework.util.Assert;
import me.chyxion.tigon.model.ViewModel;
import com.pudonghot.ambition.crm.model.*;
import org.apache.commons.io.FilenameUtils;
import com.pudonghot.ambition.crm.mapper.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import com.pudonghot.ambition.file.DiskFileApi;
import com.pudonghot.ambition.crm.service.UserService;
import org.springframework.web.multipart.MultipartFile;
import com.pudonghot.ambition.crm.service.AttachmentService;
import com.pudonghot.ambition.crm.service.ApplicationService;
import org.springframework.beans.factory.annotation.Autowired;
import me.chyxion.tigon.service.support.BaseCrudServiceSupport;
@ -27,11 +23,10 @@ import org.springframework.transaction.annotation.Transactional;
import com.pudonghot.ambition.crm.service.CustomerPermissionService;
import com.pudonghot.ambition.crm.form.update.ApplicationFormForUpdate;
import com.pudonghot.ambition.crm.form.create.ApplicationFormForCreate;
import com.pudonghot.ambition.crm.form.update.ApplicationFileFormForUpdate;
import com.pudonghot.ambition.crm.form.create.ApplicationImageFormForCreate;
import com.pudonghot.ambition.crm.form.update.ApplicationImageFormForUpdate;
import com.pudonghot.ambition.crm.form.create.ApplicationAttachmentFormForCreate;
import com.pudonghot.ambition.crm.form.update.ApplicationAttachmentFormForUpdate;
import com.pudonghot.ambition.crm.form.create.ApplicationAttachedFileFormForCreate;
import com.pudonghot.ambition.crm.form.update.ApplicationAttachedFileFormForUpdate;
/**
* @author Shaun Chyxion <br>
@ -45,9 +40,9 @@ public class ApplicationServiceSupport
implements ApplicationService {
@Autowired
private ApplicationImageMapper imageMapper;
private AttachedImageMapper imageMapper;
@Autowired
private ApplicationAttachmentMapper attachmentMapper;
private AttachedFileMapper attachmentMapper;
@Autowired
private DiskFileApi fileApi;
@Autowired
@ -58,6 +53,8 @@ public class ApplicationServiceSupport
private UserService userService;
@Autowired
private CustomerPermissionService customerPermissionService;
@Autowired
private AttachmentService attachmentService;
/**
* {@inheritDoc}
@ -67,11 +64,12 @@ public class ApplicationServiceSupport
final String id = idSeq.get();
final Application application = form.copy(new Application());
application.setId(id);
application.setNamePrefix(namePrefix(application.getName()));
final Date now = new Date();
application.setDateUpdated(now);
uploadFiles(id, 1, form.getImages(), form.getImageTitles(), form.getCreatedBy(), ApplicationImage::new, imageMapper::insert);
uploadFiles(id, 1, form.getAttachments(), form.getAttachmentTitles(), form.getCreatedBy(), ApplicationAttachment::new, attachmentMapper::insert);
attachmentService.upload(id, 1, form.getImages(), form.getImageTitles(), form.getCreatedBy(), AttachedImage::new, imageMapper::insert);
attachmentService.upload(id, 1, form.getAttachments(), form.getAttachmentTitles(), form.getCreatedBy(), AttachedFile::new, attachmentMapper::insert);
mapper.insert(application);
return toViewModel(application);
}
@ -118,6 +116,7 @@ public class ApplicationServiceSupport
else {
application.setOwner(updatedBy);
}
application.setNamePrefix(namePrefix(application.getName()));
return update(application);
}
@ -127,8 +126,8 @@ public class ApplicationServiceSupport
@Override
public ViewModel<Application> findViewModel(final String id) {
final Search search =
new Search(ApplicationImage.APPLICATION_ID, id)
.asc(ApplicationImage.SORT);
new Search(AttachedImage.OWNER_ID, id)
.asc(AttachedImage.SORT);
return super.findViewModel(id)
.setAttr("images", imageMapper.list(search))
@ -139,16 +138,16 @@ public class ApplicationServiceSupport
* {@inheritDoc}
*/
@Override
public ApplicationImage addImage(final ApplicationImageFormForCreate form) {
public AttachedImage addImage(final ApplicationImageFormForCreate form) {
final String applicationId = form.getApplicationId();
final String createdBy = form.getCreatedBy();
validatePerm(applicationId, createdBy, form.isAdmin());
return uploadFiles(applicationId,
return attachmentService.upload(applicationId,
imageMapper.nextSort(applicationId),
new MultipartFile[] {form.getImage()},
new String[] {form.getNote()},
createdBy,
ApplicationImage::new,
AttachedImage::new,
imageMapper::insert).iterator().next();
}
@ -157,7 +156,7 @@ public class ApplicationServiceSupport
*/
@Override
public void updateImage(final ApplicationImageFormForUpdate form) {
updateFile(form, imageMapper::find, imageMapper::listSort, imageMapper::update);
attachmentService.update(form, imageMapper::find, imageMapper::listSort, imageMapper::update);
}
/**
@ -166,23 +165,27 @@ public class ApplicationServiceSupport
@Override
@Transactional(rollbackFor = Throwable.class)
public void removeImage(final String id, final String userId, final boolean admin) {
removeFile(id, userId, admin, imageMapper::find, imageMapper::delete, imageMapper::updateSort);
attachmentService.remove(id,
imageMapper::find,
imageMapper::delete,
imageMapper::updateSort,
attachment -> validatePerm(attachment.getOwnerId(), userId, admin));
}
/**
* {@inheritDoc}
*/
@Override
public ApplicationAttachment addAttachment(final ApplicationAttachmentFormForCreate form) {
public AttachedFile addAttachment(final ApplicationAttachedFileFormForCreate form) {
final String applicationId = form.getApplicationId();
final String createdBy = form.getCreatedBy();
validatePerm(applicationId, createdBy, form.isAdmin());
return uploadFiles(applicationId,
return attachmentService.upload(applicationId,
attachmentMapper.nextSort(applicationId),
new MultipartFile[] {form.getAttachment()},
new String[] {form.getNote()},
createdBy,
ApplicationAttachment::new,
AttachedFile::new,
attachmentMapper::insert).iterator().next();
}
@ -190,8 +193,16 @@ public class ApplicationServiceSupport
* {@inheritDoc}
*/
@Override
public void updateAttachment(final ApplicationAttachmentFormForUpdate form) {
updateFile(form, attachmentMapper::find, attachmentMapper::listSort, attachmentMapper::update);
public void updateAttachment(final ApplicationAttachedFileFormForUpdate form) {
attachmentService.update(form, attachmentMapper::find, attachmentMapper::listSort, attachmentMapper::update);
}
/**
* {@inheritDoc}
*/
@Override
public List<Map<String, String>> listNamePrefixes() {
return mapper.listNamePrefixes();
}
/**
@ -200,7 +211,11 @@ public class ApplicationServiceSupport
@Override
@Transactional(rollbackFor = Throwable.class)
public void removeAttachment(final String id, final String userId, final boolean admin) {
removeFile(id, userId, admin, attachmentMapper::find, attachmentMapper::delete, attachmentMapper::updateSort);
attachmentService.remove(id,
attachmentMapper::find,
attachmentMapper::delete,
attachmentMapper::updateSort,
attachment -> validatePerm(attachment.getOwnerId(), userId, admin));
}
/**
@ -209,130 +224,11 @@ public class ApplicationServiceSupport
@Override
@Transactional(rollbackFor = Throwable.class)
public Application delete(final String id) {
log.info("Delete application [{}].", id);
final Application app = find(id);
Assert.state(app != null, "No application [" + id + "] found");
Assert.state(!app.isEnabled(), "Application [" + id + "] is enabled");
Assert.state(customerApplicationMapper.count(
new Search(CustomerApplication.APPLICATION_ID, id)) == 0,
"Application [" + id + "] is in using");
final Search appFileSearch = new Search(ApplicationImage.APPLICATION_ID, id);
imageMapper.list(appFileSearch).forEach(
image -> fileApi.deleteById(image.getFileId()));
imageMapper.delete(appFileSearch);
attachmentMapper.list(appFileSearch).forEach(
attachment -> fileApi.deleteById(attachment.getFileId()));
attachmentMapper.delete(appFileSearch);
mapper.delete(id);
return app;
}
private <T extends ApplicationFile> List<T> uploadFiles(
final String applicationId,
int sort,
final MultipartFile[] files,
final String[] titles,
final String createdBy,
Supplier<T> constructor,
Consumer<T> insert) {
final List<T> appFiles = new ArrayList<>();
final Date now = new Date();
final String fileFolder = fileFolder(applicationId);
int i = 0;
for (final MultipartFile file : files) {
if (!file.isEmpty()) {
final String originalFilename = file.getOriginalFilename();
try (final InputStream ins = file.getInputStream()) {
final String fileId = idSeq.get();
final T appFile = constructor.get();
final FileInfo fileInfo = fileApi.upload(ins,
file.getSize(),
fileFolder,
fileId,
file.getContentType(),
FilenameUtils.getExtension(originalFilename),
originalFilename);
appFile.setId(fileId);
appFile.setApplicationId(applicationId);
appFile.setFileId(fileInfo.getId());
appFile.setUrl(fileInfo.getUrl());
appFile.setSort(sort++);
appFile.setEnabled(true);
appFile.setNote(StringUtils.defaultIfBlank(titles[i], originalFilename));
appFile.setCreatedBy(createdBy);
appFile.setDateCreated(now);
// insert
insert.accept(appFile);
appFiles.add(appFile);
}
catch (final IOException e) {
throw new IllegalStateException(
"Read upload file [" + originalFilename + "] error cased", e);
}
}
else {
log.info("Application file [{}] is empty, ignore.", file);
}
++i;
}
return appFiles;
}
private <T extends ApplicationFile> void updateFile(
final ApplicationFileFormForUpdate form,
final Function<String, T> finder,
final Function<String, List<T>> listSort,
final Consumer<T> updater) {
final String id = form.getId();
final T appImage = finder.apply(id);
Assert.state(appImage != null, "No application file [" + id + "] found");
final String applicationId = appImage.getApplicationId();
final String updatedBy = form.getUpdatedBy();
validatePerm(applicationId, updatedBy, form.isAdmin());
boolean sortUpdated = false;
final float sort = form.getSort();
final float sortOld = appImage.getSort();
if (sort < sortOld) {
sortUpdated = true;
appImage.setSort(sortOld - 1.5f);
}
else if (sort > sortOld) {
sortUpdated = true;
appImage.setSort(sortOld + 1.5f);
}
appImage.setNote(form.getNote());
appImage.setDateUpdated(new Date());
appImage.setUpdatedBy(updatedBy);
updater.accept(appImage);
if (sortUpdated) {
listSort.apply(applicationId).forEach(updater);
}
}
private <T extends ApplicationFile> void removeFile(
final String id,
final String userId,
final boolean admin,
final Function<String, T> finder,
final Function<String, Integer> deleter,
final Function<String, Integer> sortUpdater) {
final T appFile = finder.apply(id);
Assert.state(appFile != null, "No application file [" + id + "] found");
final String applicationId = appFile.getApplicationId();
validatePerm(applicationId, userId, admin);
fileApi.delete(fileFolder(applicationId) + "/" + id);
deleter.apply(id);
sortUpdater.apply(applicationId);
}
private String fileFolder(final String appId) {
return "app/" + appId;
return attachmentService.deleteOwner(id,
mapper, application ->
Assert.state(customerApplicationMapper.count(
new Search(CustomerApplication.APPLICATION_ID, id)) == 0,
"Application [" + id + "] is in using"));
}
private Application validatePerm(final String appId, final String userId, final boolean admin) {
@ -359,4 +255,12 @@ public class ApplicationServiceSupport
return false;
});
}
private String namePrefix(final String name) {
int i = name.indexOf("-");
if (i > 0) {
return name.substring(0, i);
}
return null;
}
}

View File

@ -0,0 +1,196 @@
package com.pudonghot.ambition.crm.service.support;
import java.util.Date;
import java.util.List;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import lombok.extern.slf4j.Slf4j;
import me.chyxion.tigon.model.M2;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
import me.chyxion.tigon.mybatis.Search;
import me.chyxion.tigon.sequence.IdSequence;
import org.springframework.util.Assert;
import me.chyxion.tigon.mybatis.BaseMapper;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import com.pudonghot.ambition.file.DiskFileApi;
import com.pudonghot.ambition.crm.model.FileInfo;
import com.pudonghot.ambition.crm.model.Attachment;
import com.pudonghot.ambition.crm.model.AttachedImage;
import org.springframework.web.multipart.MultipartFile;
import com.pudonghot.ambition.crm.service.AttachmentService;
import com.pudonghot.ambition.crm.mapper.AttachedFileMapper;
import com.pudonghot.ambition.crm.mapper.AttachedImageMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import com.pudonghot.ambition.crm.form.update.AttachmentFormForUpdate;
/**
* @author Shaun Chyxion <br>
* chyxion@163.com <br>
* Jun 23, 2017 21:36:31
*/
@Slf4j
@Service
public class AttachmentServiceSupport
implements AttachmentService {
@Autowired
private IdSequence idSeq;
@Autowired
private AttachedImageMapper imageMapper;
@Autowired
private AttachedFileMapper attachmentMapper;
@Autowired
private DiskFileApi fileApi;
/**
* {@inheritDoc}
*/
public <T extends Attachment> List<T> upload(
final String ownerId,
int sort,
final MultipartFile[] files,
final String[] titles,
final String createdBy,
final Supplier<T> constructor,
final Consumer<T> insert) {
final List<T> appFiles = new ArrayList<>();
final Date now = new Date();
final String fileFolder = fileFolder(ownerId);
int i = 0;
for (final MultipartFile file : files) {
if (!file.isEmpty()) {
final String originalFilename = file.getOriginalFilename();
try (final InputStream ins = file.getInputStream()) {
final String fileId = idSeq.get();
final T appFile = constructor.get();
final FileInfo fileInfo = fileApi.upload(ins,
file.getSize(),
fileFolder,
fileId,
file.getContentType(),
FilenameUtils.getExtension(originalFilename),
originalFilename);
appFile.setId(fileId);
appFile.setOwnerId(ownerId);
appFile.setFileId(fileInfo.getId());
appFile.setUrl(fileInfo.getUrl());
appFile.setSort(sort++);
appFile.setEnabled(true);
appFile.setNote(StringUtils.defaultIfBlank(titles[i], originalFilename));
appFile.setCreatedBy(createdBy);
appFile.setDateCreated(now);
// insert
insert.accept(appFile);
appFiles.add(appFile);
}
catch (final IOException e) {
throw new IllegalStateException(
"Read upload file [" + originalFilename + "] error cased", e);
}
}
else {
log.info("LocalProduct file [{}] is empty, ignore.", file);
}
++i;
}
return appFiles;
}
/**
* {@inheritDoc}
*/
public <T extends Attachment> void update(
final AttachmentFormForUpdate form,
final Function<String, T> finder,
final Function<String, List<T>> listSort,
final Consumer<T> updater) {
final String id = form.getId();
final T appImage = finder.apply(id);
Assert.state(appImage != null, "No local product file [" + id + "] found");
final String ownerId = appImage.getOwnerId();
final String updatedBy = form.getUpdatedBy();
boolean sortUpdated = false;
final float sort = form.getSort();
final float sortOld = appImage.getSort();
if (sort < sortOld) {
sortUpdated = true;
appImage.setSort(sortOld - 1.5f);
}
else if (sort > sortOld) {
sortUpdated = true;
appImage.setSort(sortOld + 1.5f);
}
appImage.setNote(form.getNote());
appImage.setDateUpdated(new Date());
appImage.setUpdatedBy(updatedBy);
updater.accept(appImage);
if (sortUpdated) {
listSort.apply(ownerId).forEach(updater);
}
}
/**
* {@inheritDoc}
*/
@Transactional(rollbackFor = Throwable.class)
public <T extends Attachment> void remove(
final String id,
final Function<String, T> finder,
final Function<String, Integer> deleter,
final Function<String, Integer> sortUpdater,
final Consumer<T> validator) {
final T attachment = finder.apply(id);
Assert.state(attachment != null, "No file [" + id + "] found");
if (validator != null) {
validator.accept(attachment);
}
final String ownerId = attachment.getOwnerId();
fileApi.delete(fileFolder(ownerId) + "/" + id);
deleter.apply(id);
sortUpdater.apply(ownerId);
}
/**
* {@inheritDoc}
*/
@Transactional(rollbackFor = Throwable.class)
public <Key, M extends M2<Key>> M deleteOwner(final Key ownerId,
final BaseMapper<Key, M> mapper,
final Consumer<M> validator) {
log.info("Delete attachment owner [{}].", ownerId);
final M owner = mapper.find(ownerId);
Assert.state(owner != null, "No attachment owner [" + ownerId + "] found");
Assert.state(!owner.isEnabled(), "Attachment owner [" + ownerId + "] is enabled");
if (validator != null) {
validator.accept(owner);
}
final Search search = new Search(AttachedImage.OWNER_ID, ownerId);
imageMapper.list(search).forEach(
image -> fileApi.deleteById(image.getFileId()));
imageMapper.delete(search);
attachmentMapper.list(search).forEach(
attachment -> fileApi.deleteById(attachment.getFileId()));
attachmentMapper.delete(search);
mapper.delete(ownerId);
return owner;
}
private String fileFolder(final String appId) {
return "app/" + appId;
}
}

View File

@ -7,7 +7,7 @@ import javax.validation.constraints.Min;
import me.chyxion.tigon.model.ViewModel;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.hibernate.validator.constraints.NotBlank;
import javax.validation.constraints.NotBlank;
import com.pudonghot.ambition.crm.model.CustomerIssue;
import com.pudonghot.ambition.crm.service.UserService;
import com.pudonghot.ambition.crm.mapper.CustomerIssueMapper;

View File

@ -2,6 +2,7 @@ package com.pudonghot.ambition.crm.service.support;
import java.io.*;
import java.util.*;
import lombok.val;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.springframework.util.Assert;
@ -9,13 +10,13 @@ import me.chyxion.tigon.mybatis.Search;
import me.chyxion.tigon.model.ViewModel;
import org.apache.commons.csv.CSVRecord;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVPrinter;
import com.pudonghot.ambition.crm.model.*;
import me.chyxion.tigon.model.ListResult;
import com.pudonghot.ambition.crm.mapper.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import com.pudonghot.ambition.crm.util.CSVUtils;
import org.apache.commons.lang3.RandomStringUtils;
import com.pudonghot.ambition.crm.common.Constants;
import org.apache.commons.lang3.time.DateFormatUtils;
import com.pudonghot.ambition.crm.service.UserService;
@ -82,20 +83,21 @@ public class CustomerServiceSupport
/**
* override find by id with find by search
*
* {@inheritDoc}
*/
@Override
public ViewModel<Customer> findViewModel(final String id) {
final Customer customer = mapper.findForShow(id);
val customer = mapper.findForShow(id);
ViewModel<Customer> viewModel = null;
if (customer != null) {
viewModel = toViewModel(customer);
// accounts
final List<CustomerPermission> permissions = customerPermissionMapper.list(
val permissions = customerPermissionMapper.list(
new Search(CustomerPermission.CUSTOMER_ID, id)
.eq(CustomerPermission.ENABLED, true));
final List<String> accounts = new ArrayList<>(permissions.size());
val accounts = new ArrayList<>(permissions.size());
for (CustomerPermission permission : permissions) {
accounts.add(permission.getUserAccount());
}
@ -113,6 +115,7 @@ public class CustomerServiceSupport
applicationMapper.list(new Search().asc(Application.NAME)));
}
return viewModel;
}
@ -122,7 +125,7 @@ public class CustomerServiceSupport
@Override
public ListResult<ViewModel<Customer>> listViewModelsPage(Search search) {
final String account = search.getAttr(User.ACCOUNT);
final ListResult<ViewModel<Customer>> result =
val result =
new ListResult<>(toViewModel(
mapper.listForShow(search, account)),
mapper.countForShow(search, account));
@ -136,12 +139,12 @@ public class CustomerServiceSupport
result.setAttr("cityList", mapper.listCity());
result.setAttr("salespersonList", mapper.listSalesperson());
final List<CustomerProperty> statusList =
val statusList =
customerPropertyMapper.list(
new Search(CustomerProperty.TYPE,
CustomerProperty.Type.STATUS)
.asc(CustomerProperty.SORT));
final CustomerProperty noneStatus = new CustomerProperty();
val noneStatus = new CustomerProperty();
noneStatus.setId("null");
noneStatus.setName("None");
noneStatus.setEnabled(true);
@ -161,26 +164,25 @@ public class CustomerServiceSupport
*/
@Override
public ViewModel<Customer> update(final CustomerFormForUpdate form) {
final String customerId = form.getId();
val customerId = form.getId();
customerApplicationMapper.delete(
new Search(CustomerApplication.CUSTOMER_ID, customerId));
customerPermissionMapper.delete(
new Search(CustomerPermission.CUSTOMER_ID, customerId)
.eq(CustomerPermission.TYPE, CustomerPermission.Type.APPLICATION));
final String[] applications = form.getApplications();
val applications = form.getApplications();
if (applications != null && applications.length > 0) {
final String operator = form.getUpdatedBy();
final Date now = new Date();
for (final String applicationId : applications) {
final Application application =
applicationMapper.find(applicationId);
val operator = form.getUpdatedBy();
val now = new Date();
for (val applicationId : applications) {
val application = applicationMapper.find(applicationId);
Assert.state(application != null,
"No application [" + applicationId + "] found");
Assert.state(application.isEnabled(),
"Application [" + application.getName() + "] is disabled");
final CustomerApplication customerApplication = new CustomerApplication();
val customerApplication = new CustomerApplication();
customerApplication.setId(idSeq.get());
customerApplication.setEnabled(true);
customerApplication.setCustomerId(customerId);
@ -189,7 +191,7 @@ public class CustomerServiceSupport
customerApplication.setDateCreated(now);
customerApplicationMapper.insert(customerApplication);
final String applicationOwner = application.getOwner();
val applicationOwner = application.getOwner();
if (StringUtils.isNotBlank(applicationOwner)) {
log.info("Add application owner [{}] customer [{}] permission.",
applicationOwner, customerId);
@ -210,15 +212,15 @@ public class CustomerServiceSupport
List<Map<String, Object>> ytdSales = null;
final String strYears = model.getYears();
final String strYtdSales = model.getYtdSales();
val strYears = model.getYears();
val strYtdSales = model.getYtdSales();
String[] years = null;
if (StringUtils.isNotBlank(strYears) &&
StringUtils.isNotBlank(strYtdSales)) {
years = strYears.split(SPLITTER);
final String[] sales = strYtdSales.split(SPLITTER);
val sales = strYtdSales.split(SPLITTER);
ytdSales = new ArrayList<>(years.length);
int i = 0;
for (final String year : years) {
@ -233,26 +235,15 @@ public class CustomerServiceSupport
viewModel.setAttr("ytdSales", ytdSales != null ?
ytdSales : Collections.emptyList());
// recent 3 issues
// final List<ViewModel<CustomerIssue>> recentIssues =
// customerIssueService.listRecent(model.getId(), 3);
final String lastIssue = model.getLastIssue();
val lastIssue = model.getLastIssue();
if (StringUtils.isNotBlank(lastIssue)) {
final String[] issueParts = lastIssue.split(SPLITTER);
CustomerIssue issue = new CustomerIssue();
val issueParts = lastIssue.split(SPLITTER);
val issue = new CustomerIssue();
issue.setId(issueParts[0]);
issue.setIssue(issueParts[1]);
issue.setDateCreated(new Date(Long.parseLong(issueParts[2])));
viewModel.setAttr("issue1", issue);
}
// if (!recentIssues.isEmpty()) {
// int i = 0;
// final Iterator<ViewModel<CustomerIssue>> it = recentIssues.iterator();
// while (it.hasNext()) {
// viewModel.setAttr("issue" + (++i), it.next());
// }
// }
}
/**
@ -262,9 +253,8 @@ public class CustomerServiceSupport
@Override
public void importCSV(final String operator, final InputStream csvIn) {
final Date now = new Date();
final ImportRecord importRecord = new ImportRecord();
val now = new Date();
val importRecord = new ImportRecord();
importRecord.setId(idSeq.get());
importRecord.setType(ImportRecord.TYPE_CUSTOMER);
importRecord.setCompleted(false);
@ -279,6 +269,35 @@ public class CustomerServiceSupport
private final User user = new User();
private final CustomerPermission permission = new CustomerPermission();
/**
* {@inheritDoc}
*/
@Override
public void read(final CSVRecord record) {
val customerId = record.get(0).trim();
if (StringUtils.isBlank(customerId)) {
log.info("Blank customer id found, ignore.");
return;
}
customer.setId2(customerId);
customer.setName(record.get(1).trim());
customer.setCountryCode(record.get(2).trim());
customer.setState(record.get(3).trim());
customer.setCity(record.get(4).trim());
customer.setMs(record.get(5).trim());
customer.setRegion(record.get(6).trim());
val employeeId = StringUtils.defaultIfBlank(
record.get(7).trim(), null);
customer.setSalesperson(employeeId);
log.info("Customer [{}] read.", customer);
createUserIfNotExist(operator, employeeId, now);
createOrUpdateCustomer(operator, customer, now);
createOrUpdateCustomerPermissions(operator, customer, record.get(8), now);
}
/**
* {@inheritDoc}
*/
@ -298,32 +317,6 @@ public class CustomerServiceSupport
*/
}
/**
* {@inheritDoc}
*/
@Override
public void read(final CSVRecord record) {
final String customerId = record.get(0).trim();
if (StringUtils.isBlank(customerId)) {
log.info("Blank customer id found, ignore.");
return;
}
customer.setId(customerId);
customer.setName(record.get(1).trim());
customer.setCountryCode(record.get(2).trim());
customer.setState(record.get(3).trim());
customer.setCity(record.get(4).trim());
customer.setMs(record.get(5).trim());
customer.setRegion(record.get(6).trim());
final String employeeId = StringUtils.defaultIfBlank(record.get(7).trim(), null);
customer.setSalesperson(employeeId);
log.info("Customer [{}] read.", customer);
createUserIfNotExist(operator, employeeId, now);
createOrUpdateCustomer(operator, customer, now);
createOrUpdateCustomerPermissions(operator, customerId, record.get(8), now);
}
// --
// private methods
@ -336,7 +329,7 @@ public class CustomerServiceSupport
user.setAccount(employeeId);
user.setEmployeeId(employeeId);
final String password = idSeq.get();
val password = RandomStringUtils.randomAlphanumeric(8);
user.setPassword(password);
user.setGender(Constants.GENDER_MALE);
user.setEnabled(true);
@ -351,14 +344,17 @@ public class CustomerServiceSupport
private void createOrUpdateCustomer(final String operator, final Customer customer, final Date date) {
log.info("User [{}] create or update customer [{}].", operator, customer);
final String customerId = customer.getId();
final String ms = customer.getMs();
val ms = customer.getMs();
val customerExisted = mapper.find(
new Search(Customer.ID2, customer.getId2())
.eq(Customer.COUNTRY_CODE, customer.getCountryCode()));
final Customer customerExisted = mapper.find(customerId);
if (customerExisted != null) {
log.info("Customer existed [{}] found, update.", customerExisted);
customer.setId(customerExisted.getId());
// basic props
customerExisted.setName(customer.getName());
// customerExisted.setName(customer.getName());
customerExisted.setCountryCode(customer.getCountryCode());
customerExisted.setState(customer.getState());
customerExisted.setCity(customer.getCity());
@ -375,6 +371,7 @@ public class CustomerServiceSupport
mapper.update(customerExisted);
}
else {
customer.setId(idSeq.get());
customer.setEnabled(true);
customer.setCreatedBy(operator);
customer.setDateCreated(date);
@ -382,11 +379,12 @@ public class CustomerServiceSupport
mapper.insert(customer);
}
val customerId = customer.getId();
// no issues
if (customerIssueMapper.count(
new Search(CustomerIssue.CUSTOMER_ID, customerId)
.eq(CustomerIssue.ENABLED, true)) < 1) {
final CustomerIssue ci = new CustomerIssue();
val ci = new CustomerIssue();
ci.setId(idSeq.get());
ci.setArtificial(false);
ci.setCustomerId(customerId);
@ -400,15 +398,16 @@ public class CustomerServiceSupport
}
}
private void createOrUpdateCustomerPermissions(final String operator, final String customerId, final String strAccounts, Date date) {
private void createOrUpdateCustomerPermissions(final String operator, final Customer customer, final String strAccounts, Date date) {
val customerId = customer.getId();
log.info("User [{}] create or update customer [{}] permissions [{}].", operator, customerId, strAccounts);
if (StringUtils.isNotBlank(strAccounts)) {
for (final String account : new HashSet<>(
for (val account : new HashSet<>(
Arrays.asList(strAccounts.trim().split("\\s*,\\s*")))) {
if (StringUtils.isNotBlank(account)) {
final CustomerPermission permOld = customerPermissionMapper.find(
val permOld = customerPermissionMapper.find(
new Search(CustomerPermission.CUSTOMER_ID, customerId)
.eq(CustomerPermission.USER_ACCOUNT, account));
if (permOld != null) {
@ -458,12 +457,12 @@ public class CustomerServiceSupport
*/
@Override
public File exportCSV(final String operator) {
final File file = new File(FileUtils.getTempDirectory(),
val file = new File(FileUtils.getTempDirectory(),
"Customers_" + DateFormatUtils.format(System.currentTimeMillis(),
"yyyy-MM-dd_HHmmss") + ".csv");
try (final OutputStreamWriter fileWriter =
try (val fileWriter =
new OutputStreamWriter(new FileOutputStream(file), CSVUtils.GBK);
final CSVPrinter printer = EXPORT_FORMAT.print(fileWriter)) {
val printer = EXPORT_FORMAT.print(fileWriter)) {
scan(512, new Search()
// .setAttr("APPLICATION_NOT_NULL", true)
@ -489,7 +488,7 @@ public class CustomerServiceSupport
try {
log.info("Export Customer [{}].", c);
printer.printRecord(c.getId(),
printer.printRecord(c.getId2(),
c.getName(),
c.getSumYtdSales(),
joinYtdSales(c.getYears(), c.getYtdSales()),
@ -545,12 +544,12 @@ public class CustomerServiceSupport
private String joinYtdSales(final String strYears, final String strYtdSales) {
if (StringUtils.isNotBlank(strYears) &&
StringUtils.isNotBlank(strYtdSales)) {
final String[] years = strYears.split(SPLITTER);
final String[] sales = strYtdSales.split(SPLITTER);
final List<String> ytdSales = new ArrayList<>(years.length);
val years = strYears.split(SPLITTER);
val sales = strYtdSales.split(SPLITTER);
val ytdSales = new ArrayList<>(years.length);
int i = 0;
for (final String year : years) {
for (val year : years) {
ytdSales.add(year + ": " + sales[i++]);
}
return StringUtils.join(ytdSales, "\n");
@ -561,4 +560,24 @@ public class CustomerServiceSupport
private String dateFormat(Date date, String pattern) {
return date != null ? DateFormatUtils.format(date, pattern) : "";
}
/**
* {@inheritDoc}
*/
@Override
public Customer delete(final String id) {
val customer = super.delete(id);
Assert.state(customer != null,
"No customer [" + id + "] found");
customerPermissionMapper.delete(
new Search(CustomerPermission.CUSTOMER_ID, id));
customerIssueMapper.delete(
new Search(CustomerIssue.CUSTOMER_ID, id));
customerYearToDateSaleMapper.delete(
new Search(CustomerYearToDateSale.CUSTOMER_ID, id));
customerApplicationMapper.delete(
new Search(CustomerApplication.CUSTOMER_ID, id));
return customer;
}
}

View File

@ -1,5 +1,6 @@
package com.pudonghot.ambition.crm.service.support;
import lombok.val;
import java.util.Date;
import java.io.InputStream;
import java.text.ParseException;
@ -51,10 +52,9 @@ public class CustomerYearToDateSaleServiceSupport
*/
@Override
public void importCSV(final String operator, final InputStream csvIn) {
val now = new Date();
final Date now = new Date();
final ImportRecord importRecord = new ImportRecord();
val importRecord = new ImportRecord();
importRecord.setId(idSeq.get());
importRecord.setType(ImportRecord.TYPE_YTD_SALES);
importRecord.setCompleted(false);
@ -62,6 +62,7 @@ public class CustomerYearToDateSaleServiceSupport
importRecord.setEnabled(true);
importRecord.setCreatedBy(operator);
importRecord.setDateCreated(now);
try {
CSVUtils.eachRecord(csvIn, CSVUtils.GBK, new CSVUtils.RecordReader() {
private final CustomerYearToDateSale customerYtdSale =
@ -89,17 +90,34 @@ public class CustomerYearToDateSaleServiceSupport
*/
@Override
public void read(final CSVRecord record) {
final String customerId = StringUtils.trim(record.get(0));
if (StringUtils.isBlank(customerId)) {
val customerId2 = StringUtils.trim(record.get(0));
if (StringUtils.isBlank(customerId2)) {
log.info("Blank customer id found, ignore.");
return;
}
val customerName = StringUtils.trim(record.get(1));
if (StringUtils.isBlank(customerName)) {
log.warn("Record [{}] blank customer name found, ignore.", record);
return;
}
val customer = customerMapper.find(
new Search(Customer.ID2, customerId2)
.eq(Customer.NAME, customerName));
if (customer == null) {
log.warn("No customer [{}] found, ignore.", customerName);
return;
}
val customerId = customer.getId();
customerYtdSale.setCustomerId(customerId);
customerYtdSale.setYear(StringUtils.trim(record.get(3)));
customerYtdSale.setYtdSale(Long.parseLong(StringUtils.trim(record.get(6)).replace(",", "")));
// update date added
final String strDateAdded = StringUtils.trim(record.get(5));
val strDateAdded = StringUtils.trim(record.get(5));
if (StringUtils.isNotBlank(strDateAdded)) {
log.info("Update customer [{}] date added [{}].", customerId, strDateAdded);
Date dateAdded = null;
@ -112,8 +130,8 @@ public class CustomerYearToDateSaleServiceSupport
catch (ParseException e) {
log.warn("Parse date [{}] error caused, ignore.", strDateAdded, e);
}
if (dateAdded != null) {
final Customer customer = customerMapper.find(customerId);
customer.setDateAdded(dateAdded);
customer.setUpdatedBy(operator);
customer.setDateUpdated(now);
@ -126,6 +144,7 @@ public class CustomerYearToDateSaleServiceSupport
createOrUpdateCustomerYTDSale(operator, customerYtdSale, now);
}
}, true);
// update customer's status
customerPropertyService.initSystemStatus(operator);
customerMapper.listStatusSleeping().forEach(customer -> {
@ -162,10 +181,14 @@ public class CustomerYearToDateSaleServiceSupport
}
}
private void createOrUpdateCustomerYTDSale(final String operator, final CustomerYearToDateSale customerYtdSale, final Date date) {
private void createOrUpdateCustomerYTDSale(
final String operator,
final CustomerYearToDateSale customerYtdSale,
final Date date) {
log.info("User [{}] create or update customer YTD sale [{}].", operator, customerYtdSale);
final CustomerYearToDateSale customerYtdSaleExisted =
val customerYtdSaleExisted =
mapper.find(new Search(CustomerYearToDateSale.CUSTOMER_ID,
customerYtdSale.getCustomerId())
.eq(CustomerYearToDateSale.YEAR,

View File

@ -0,0 +1,180 @@
package com.pudonghot.ambition.crm.service.support;
import java.util.Map;
import java.util.Date;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import me.chyxion.tigon.mybatis.Search;
import org.springframework.util.Assert;
import me.chyxion.tigon.model.ViewModel;
import com.pudonghot.ambition.crm.model.*;
import com.pudonghot.ambition.crm.mapper.*;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import com.pudonghot.ambition.crm.service.AttachmentService;
import org.springframework.beans.factory.annotation.Autowired;
import com.pudonghot.ambition.crm.service.LocalProductService;
import me.chyxion.tigon.service.support.BaseCrudServiceSupport;
import org.springframework.transaction.annotation.Transactional;
import com.pudonghot.ambition.crm.form.create.LocalProductFormForCreate;
import com.pudonghot.ambition.crm.form.update.LocalProductFormForUpdate;
import com.pudonghot.ambition.crm.form.create.LocalProductImageFormForCreate;
import com.pudonghot.ambition.crm.form.update.LocalProductImageFormForUpdate;
import com.pudonghot.ambition.crm.form.update.LocalProductAttachedFileFormForUpdate;
import com.pudonghot.ambition.crm.form.create.LocalProductAttachedFileFormForCreate;
/**
* @author Shaun Chyxion <br>
* chyxion@163.com <br>
* Jun 23, 2017 21:36:31
*/
@Slf4j
@Service
public class LocalProductServiceSupport
extends BaseCrudServiceSupport<String, LocalProduct, LocalProductMapper>
implements LocalProductService {
@Autowired
private AttachedImageMapper imageMapper;
@Autowired
private AttachedFileMapper attachmentMapper;
@Autowired
private AttachmentService attachmentService;
/**
* {@inheritDoc}
*/
@Override
public ViewModel<LocalProduct> create(final LocalProductFormForCreate form) {
final String id = idSeq.get();
final LocalProduct product = form.copy(new LocalProduct());
product.setId(id);
product.setNamePrefix(namePrefix(product.getName()));
final Date now = new Date();
product.setDateUpdated(now);
attachmentService.upload(id, 1, form.getImages(), form.getImageTitles(), form.getCreatedBy(), AttachedImage::new, imageMapper::insert);
attachmentService.upload(id, 1, form.getAttachments(), form.getAttachmentTitles(), form.getCreatedBy(), AttachedFile::new, attachmentMapper::insert);
mapper.insert(product);
return toViewModel(product);
}
/**
* {@inheritDoc}
*/
@Override
public ViewModel<LocalProduct> update(final LocalProductFormForUpdate form) {
final LocalProduct product = find(form.getId());
Assert.state(product != null, "No local product found");
form.copy(product);
product.setNamePrefix(namePrefix(product.getName()));
return update(product);
}
/**
* {@inheritDoc}
*/
@Override
public ViewModel<LocalProduct> findViewModel(final String id) {
final Search search =
new Search(AttachedImage.OWNER_ID, id)
.asc(AttachedImage.SORT);
return super.findViewModel(id)
.setAttr("images", imageMapper.list(search))
.setAttr("attachments", attachmentMapper.list(search));
}
/**
* {@inheritDoc}
*/
@Override
public AttachedImage addImage(final LocalProductImageFormForCreate form) {
final String productId = form.getProductId();
final String createdBy = form.getCreatedBy();
return attachmentService.upload(productId,
imageMapper.nextSort(productId),
new MultipartFile[] {form.getImage()},
new String[] {form.getNote()},
createdBy,
AttachedImage::new,
imageMapper::insert).iterator().next();
}
/**
* {@inheritDoc}
*/
@Override
public void updateImage(final LocalProductImageFormForUpdate form) {
attachmentService.update(form, imageMapper::find, imageMapper::listSort, imageMapper::update);
}
/**
* {@inheritDoc}
*/
@Override
@Transactional(rollbackFor = Throwable.class)
public void removeImage(final String id) {
attachmentService.remove(id, imageMapper::find, imageMapper::delete, imageMapper::updateSort, null);
}
/**
* {@inheritDoc}
*/
@Override
public AttachedFile addAttachment(final LocalProductAttachedFileFormForCreate form) {
final String productId = form.getProductId();
final String createdBy = form.getCreatedBy();
return attachmentService.upload(productId,
attachmentMapper.nextSort(productId),
new MultipartFile[] {form.getAttachment()},
new String[] {form.getNote()},
createdBy,
AttachedFile::new,
attachmentMapper::insert).iterator().next();
}
/**
* {@inheritDoc}
*/
@Override
public void updateAttachment(final LocalProductAttachedFileFormForUpdate form) {
attachmentService.update(form, attachmentMapper::find, attachmentMapper::listSort, attachmentMapper::update);
}
/**
* {@inheritDoc}
*/
@Override
public List<Map<String, String>> listNamePrefixes() {
return mapper.listNamePrefixes();
}
/**
* {@inheritDoc}
*/
@Override
public void removeAttachment(final String id) {
attachmentService.remove(id,
attachmentMapper::find,
attachmentMapper::delete,
attachmentMapper::updateSort, null);
}
/**
* {@inheritDoc}
*/
@Override
@Transactional(rollbackFor = Throwable.class)
public LocalProduct delete(final String id) {
return attachmentService.deleteOwner(id, mapper, null);
}
private String namePrefix(final String name) {
int i = name.indexOf("-");
if (i > 0) {
return name.substring(0, i);
}
return null;
}
}

View File

@ -8,7 +8,7 @@ import org.apache.commons.lang3.StringUtils;
import com.pudonghot.ambition.crm.model.User;
import org.springframework.stereotype.Service;
import com.pudonghot.ambition.crm.util.Sha512Utils;
import org.hibernate.validator.constraints.NotBlank;
import javax.validation.constraints.NotBlank;
import com.pudonghot.ambition.crm.mapper.UserMapper;
import com.pudonghot.ambition.crm.service.UserService;
import com.pudonghot.ambition.crm.form.create.UserFormForCreate;

View File

@ -14,8 +14,8 @@ database.restore-shell=/data/program/mysql-backup/bin/mysql_restore.sh
# Shiro
shiro.session.validation.scheduler.enabled=true
spring.http.multipart.max-file-size=1024MB
spring.http.multipart.max-request-size=1024MB
spring.servlet.multipart.max-file-size=512MB
spring.servlet.multipart.max-request-size=512MB
# File
file.base-path=http://127.0.0.1:1217/lm-f/

View File

@ -1,17 +1,16 @@
package com.pudonghot.ambition.crm;
import com.pudonghot.ambition.crm.model.ApplicationImage;
import com.pudonghot.ambition.crm.util.AmDateUtil;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;
import com.pudonghot.ambition.crm.model.AttachedImage;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.joda.time.DateTimeConstants;
import org.joda.time.Interval;
import org.joda.time.Period;
import org.junit.Test;
import java.text.ParseException;
import java.util.Date;
import java.text.ParseException;
import org.joda.time.DateTimeConstants;
import org.apache.commons.lang3.time.DateUtils;
import com.pudonghot.ambition.crm.util.AmDateUtil;
/**
* @version 0.0.1
@ -20,6 +19,7 @@ import java.util.Date;
* chyxion@163.com <br />
* Sep 1, 2015 2:34:08 PM
*/
@Slf4j
public class TestDriver {
@Test
@ -96,10 +96,18 @@ public class TestDriver {
@Test
public void testFloat() {
ApplicationImage image = new ApplicationImage();
AttachedImage image = new AttachedImage();
image.setUrl("http://www.image.com");
int sortOld = 2;
image.setSort(sortOld - 1.5f);
System.err.println(image);
}
@Test
public void testNamePrefix() {
String name = "AT-Foo";
int i = name.indexOf('-');
log.info("index [{}].", i);
log.info("prefix [{}].", name.substring(0, i));
}
}

View File

@ -12,10 +12,17 @@ get_real_path() {
f=`dirname "$f"`/"$link"
fi
done
eval "$2"="'$f'"
echo "$f"
}
get_real_path "$0" prg_path
if [ "$1" = "prod" ]; then
SERVER=lemo@116.62.189.211
else
echo "Profile required."
exit 1
fi
prg_path=$(get_real_path "$0")
echo "Script Path [$prg_path]"
PROJECT_HOME=$(dirname $prg_path)
echo "Project Home [$PROJECT_HOME]"
@ -23,18 +30,7 @@ cd "$PROJECT_HOME"
mvn clean package -o -pl crm -am -DskipTests -Ptest
SERVICE_HOME=/data/program/lemo-crm
echo "Service Home [$SERVICE_HOME]"
# SERVER=ambition@101.236.35.13
# SERVER=root@116.62.189.211
if [ "$1" = "prod" ]; then
SERVER=lemo@116.62.189.211
else
SERVER=ambition@101.236.35.13
fi
echo "$SERVER $SERVICE_HOME/bin/stop.sh"
ssh "$SERVER" "$SERVICE_HOME/bin/stop.sh"
echo "Service Home [$SERVICE_HOME], Server [$SERVER]"
echo "$SERVER [ -f $SERVICE_HOME/lib/main.jar ] && mv $SERVICE_HOME/lib/main.jar $SERVICE_HOME/main_prev.jar"
ssh "$SERVER" "[ -f $SERVICE_HOME/lib/main.jar ] && mv $SERVICE_HOME/lib/main.jar $SERVICE_HOME/main_prev.jar"
@ -42,6 +38,9 @@ ssh "$SERVER" "[ -f $SERVICE_HOME/lib/main.jar ] && mv $SERVICE_HOME/lib/main.ja
echo "$PROJECT_HOME/crm/target/ambition-crm.jar $SERVER:$SERVICE_HOME/lib/main.jar"
scp "$PROJECT_HOME/crm/target/ambition-crm.jar" "$SERVER:$SERVICE_HOME/lib/main.jar"
echo "$SERVER $SERVICE_HOME/bin/stop.sh"
ssh "$SERVER" "$SERVICE_HOME/bin/stop.sh"
echo "$SERVER $SERVICE_HOME/bin/start.sh"
ssh "$SERVER" "$SERVICE_HOME/bin/start.sh"

View File

@ -5,7 +5,7 @@ import java.util.List;
import java.io.InputStream;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import org.hibernate.validator.constraints.NotBlank;
import javax.validation.constraints.NotBlank;
import org.springframework.validation.annotation.Validated;
/**

View File

@ -6,7 +6,7 @@ import java.io.InputStream;
import java.util.Collection;
import java.awt.image.BufferedImage;
import javax.validation.constraints.NotNull;
import org.hibernate.validator.constraints.NotBlank;
import javax.validation.constraints.NotBlank;
import org.springframework.validation.annotation.Validated;
/**

View File

@ -1,7 +1,7 @@
package com.pudonghot.ambition.file;
import com.pudonghot.ambition.crm.model.FileInfo;
import org.hibernate.validator.constraints.NotBlank;
import javax.validation.constraints.NotBlank;
import java.io.File;

28
server/launch.sh Executable file
View File

@ -0,0 +1,28 @@
#!/bin/bash
# get real path of softlink
get_real_path() {
local f="$1"
while [ -h "$f" ]; do
ls=`ls -ld "$f"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
f="$link"
else
f=`dirname "$f"`/"$link"
fi
done
echo "$f"
}
prg_path=$(get_real_path "$0")
echo "Script path [$prg_path]"
# Service Home
pushd $(dirname "$prg_path")
WORK_DIR=$(pwd)
echo "Work dir [$WORK_DIR]"
mvn -T 4C clean -pl crm -am -DskipTests \
spring-boot:run

@ -1 +1 @@
Subproject commit 7a0c14ba3f821049872595609dbf278cf410cbd5
Subproject commit 40acef80b8af560cbf19a0a841748c0d63406dde

View File

@ -6,11 +6,7 @@
<modelVersion>4.0.0</modelVersion>
<artifactId>crm-mapper</artifactId>
<name>Ambition Mapper</name>
<packaging>${packaging}</packaging>
<properties>
<packaging>jar</packaging>
</properties>
<packaging>jar</packaging>
<parent>
<groupId>com.pudonghot.ambition</groupId>
@ -20,11 +16,6 @@
</parent>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.pudonghot.ambition</groupId>
<artifactId>crm-model</artifactId>
@ -54,11 +45,6 @@
</dependency>
<!-- Test And Optional Dependencies -->
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
@ -69,35 +55,19 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.0</version>
<optional>true</optional>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
@ -123,49 +93,6 @@
<value>true</value>
</property>
</activation>
<properties>
<packaging>war</packaging>
<maven.tomcat.port>8088</maven.tomcat.port>
<log.dir>${project.basedir}/.log</log.dir>
<log.level>DEBUG</log.level>
<log.appender>
<![CDATA[
<AppenderRef ref="File" level="${log.level}" />
<AppenderRef ref="Console" level="${log.level}" />
]]>
</log.appender>
</properties>
<dependencies>
<dependency>
<groupId>me.chyxion.tigon</groupId>
<artifactId>tigon-codegen</artifactId>
</dependency>
<dependency>
<groupId>me.chyxion.tigon</groupId>
<artifactId>tigon-props-config</artifactId>
</dependency>
<dependency>
<groupId>me.chyxion.tigon</groupId>
<artifactId>tigon-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>dep</id>

View File

@ -1,14 +0,0 @@
package com.pudonghot.ambition.crm.mapper;
import me.chyxion.tigon.mybatis.BaseMapper;
import com.pudonghot.ambition.crm.model.ApplicationAttachment;
/**
* @author Shaun Chyxion <br>
* chyxion@163.com <br>
* Mar 11, 2018 11:39:49
*/
public interface ApplicationAttachmentMapper
extends ApplicationFileMapper<ApplicationAttachment>,
BaseMapper<String, ApplicationAttachment> {
}

View File

@ -1,38 +0,0 @@
package com.pudonghot.ambition.crm.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.hibernate.validator.constraints.NotBlank;
import com.pudonghot.ambition.crm.model.ApplicationFile;
/**
* @author Shaun Chyxion <br>
* chyxion@163.com <br>
* Mar 11, 2018 11:39:49
*/
interface ApplicationFileMapper<T extends ApplicationFile> {
/**
* find next sort
* @param applicationId application id
* @return next sort
*/
int nextSort(@NotBlank @Param("applicationId") String applicationId);
/**
* update sort
* @param applicationId application id
* @return effected rows
*/
int updateSort(@NotBlank @Param("applicationId") String applicationId);
/**
* list application files
* @param applicationId
* @return images
*/
List<T> listSort(
@NotBlank
@Param("applicationId")
String applicationId);
}

View File

@ -1,44 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
* @author Shaun Chyxion <br>
* chyxion@163.com <br>
* May 17, 2018 17:29:10
*/
-->
<!DOCTYPE mapper PUBLIC
"-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pudonghot.ambition.crm.mapper.ApplicationFileMapper">
<sql id="nextSort">
select if (application_id, max(sort) + 1, 1)
from <include refid="table" />
where application_id = #{applicationId}
</sql>
<sql id="updateSort">
update <include refid="table" /> a
join (
select id, @cur_row := @cur_row + 1 sort
from <include refid="table" />
join (select @cur_row := 0) r
where application_id = #{applicationId}
order by <include refid="table" />.sort) s
on a.id = s.id
set a.sort = s.sort
</sql>
<sql id="listSort">
select id, file_id,
url, application_id,
created_by, date_created,
updated_by, date_updated,
enabled, note,
@cur_row := @cur_row + 1 sort
from <include refid="table" />
join (select @cur_row := 0) r
where application_id = #{applicationId}
order by <include refid="table" />.sort
</sql>
</mapper>

View File

@ -1,14 +0,0 @@
package com.pudonghot.ambition.crm.mapper;
import me.chyxion.tigon.mybatis.BaseMapper;
import com.pudonghot.ambition.crm.model.ApplicationImage;
/**
* @author Shaun Chyxion <br>
* chyxion@163.com <br>
* Mar 11, 2018 11:39:49
*/
public interface ApplicationImageMapper
extends ApplicationFileMapper<ApplicationImage>,
BaseMapper<String, ApplicationImage> {
}

View File

@ -1,5 +1,7 @@
package com.pudonghot.ambition.crm.mapper;
import java.util.List;
import java.util.Map;
import me.chyxion.tigon.mybatis.BaseMapper;
import com.pudonghot.ambition.crm.model.Application;
@ -10,4 +12,9 @@ import com.pudonghot.ambition.crm.model.Application;
*/
public interface ApplicationMapper extends BaseMapper<String, Application> {
/**
* list name prefixes
* @return name prefixes
*/
List<Map<String, String>> listNamePrefixes();
}

View File

@ -12,31 +12,14 @@
<mapper namespace="com.pudonghot.ambition.crm.mapper.ApplicationMapper">
<select id="list" resultType="com.pudonghot.ambition.crm.model.Application">
select
<include refid="cols" />,
(select group_concat(url order by sort separator 0x1d) from
crm_application_image
where application_id = a.id
group by application_id) images,
(select group_concat(note order by sort separator 0x1d) from
crm_application_image
where application_id = a.id
group by application_id) image_titles,
(select group_concat(url order by sort separator 0x1d) from
crm_application_attachment
where application_id = a.id
group by application_id) attachments,
(select group_concat(note order by sort separator 0x1d) from
crm_application_attachment
where application_id = a.id
group by application_id) attachment_titles
from
<include refid="table" /> a
<include refid="Tigon.search" />
<include refid="com.pudonghot.ambition.crm.mapper.AttachmentMapper.listForOwner" />
</select>
<select id="listNamePrefixes" resultType="map">
select
distinct name_prefix text, name_prefix value
from <include refid="table" />
where name_prefix is not null
order by name_prefix
</select>
</mapper>

View File

@ -0,0 +1,14 @@
package com.pudonghot.ambition.crm.mapper;
import me.chyxion.tigon.mybatis.BaseMapper;
import com.pudonghot.ambition.crm.model.AttachedFile;
/**
* @author Shaun Chyxion <br>
* chyxion@163.com <br>
* Mar 11, 2018 11:39:49
*/
public interface AttachedFileMapper
extends AttachmentMapper<AttachedFile>,
BaseMapper<String, AttachedFile> {
}

View File

@ -9,17 +9,18 @@
<!DOCTYPE mapper PUBLIC
"-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pudonghot.ambition.crm.mapper.ApplicationAttachmentMapper">
<mapper namespace="com.pudonghot.ambition.crm.mapper.AttachedFileMapper">
<select id="nextSort" resultType="int">
<include refid="com.pudonghot.ambition.crm.mapper.ApplicationFileMapper.nextSort" />
<include refid="com.pudonghot.ambition.crm.mapper.AttachmentMapper.nextSort" />
</select>
<update id="updateSort">
<include refid="com.pudonghot.ambition.crm.mapper.ApplicationFileMapper.updateSort" />
<include refid="com.pudonghot.ambition.crm.mapper.AttachmentMapper.updateSort" />
</update>
<select id="listSort" resultType="com.pudonghot.ambition.crm.model.ApplicationAttachment">
<include refid="com.pudonghot.ambition.crm.mapper.ApplicationFileMapper.listSort" />
<select id="listSort" resultType="com.pudonghot.ambition.crm.model.AttachedImage">
<include refid="com.pudonghot.ambition.crm.mapper.AttachmentMapper.listSort" />
</select>
</mapper>

View File

@ -0,0 +1,14 @@
package com.pudonghot.ambition.crm.mapper;
import me.chyxion.tigon.mybatis.BaseMapper;
import com.pudonghot.ambition.crm.model.AttachedImage;
/**
* @author Shaun Chyxion <br>
* chyxion@163.com <br>
* Mar 11, 2018 11:39:49
*/
public interface AttachedImageMapper
extends AttachmentMapper<AttachedImage>,
BaseMapper<String, AttachedImage> {
}

View File

@ -9,17 +9,18 @@
<!DOCTYPE mapper PUBLIC
"-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pudonghot.ambition.crm.mapper.ApplicationImageMapper">
<mapper namespace="com.pudonghot.ambition.crm.mapper.AttachedImageMapper">
<select id="nextSort" resultType="int">
<include refid="com.pudonghot.ambition.crm.mapper.ApplicationFileMapper.nextSort" />
<include refid="com.pudonghot.ambition.crm.mapper.AttachmentMapper.nextSort" />
</select>
<update id="updateSort">
<include refid="com.pudonghot.ambition.crm.mapper.ApplicationFileMapper.updateSort" />
<include refid="com.pudonghot.ambition.crm.mapper.AttachmentMapper.updateSort" />
</update>
<select id="listSort" resultType="com.pudonghot.ambition.crm.model.ApplicationImage">
<include refid="com.pudonghot.ambition.crm.mapper.ApplicationFileMapper.listSort" />
<select id="listSort" resultType="com.pudonghot.ambition.crm.model.AttachedImage">
<include refid="com.pudonghot.ambition.crm.mapper.AttachmentMapper.listSort" />
</select>
</mapper>

View File

@ -0,0 +1,38 @@
package com.pudonghot.ambition.crm.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import javax.validation.constraints.NotBlank;
import com.pudonghot.ambition.crm.model.Attachment;
/**
* @author Shaun Chyxion <br>
* chyxion@163.com <br>
* Mar 11, 2018 11:39:49
*/
interface AttachmentMapper<T extends Attachment> {
/**
* find next sort
* @param ownerId owner id
* @return next sort
*/
int nextSort(@NotBlank @Param("ownerId") String ownerId);
/**
* update sort
* @param ownerId owner id
* @return effected rows
*/
int updateSort(@NotBlank @Param("ownerId") String ownerId);
/**
* list owner attachments
* @param ownerId owner id
* @return attachments
*/
List<T> listSort(
@NotBlank
@Param("ownerId")
String ownerId);
}

View File

@ -0,0 +1,72 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
* @author Shaun Chyxion <br>
* chyxion@163.com <br>
* May 17, 2018 17:29:10
*/
-->
<!DOCTYPE mapper PUBLIC
"-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pudonghot.ambition.crm.mapper.AttachmentMapper">
<sql id="listForOwner">
select
<include refid="cols" />,
(select group_concat(url order by sort separator 0x1d) from
crm_attached_image
where owner_id = a.id
group by owner_id) images,
(select group_concat(note order by sort separator 0x1d) from
crm_attached_image
where owner_id = a.id
group by owner_id) image_titles,
(select group_concat(url order by sort separator 0x1d) from
crm_attached_file
where owner_id = a.id
group by owner_id) attachments,
(select group_concat(note order by sort separator 0x1d) from
crm_attached_file
where owner_id = a.id
group by owner_id) attachment_titles
from
<include refid="table" /> a
<include refid="Tigon.search" />
</sql>
<sql id="nextSort">
select if (owner_id, max(sort) + 1, 1)
from <include refid="table" />
where owner_id = #{ownerId}
</sql>
<sql id="updateSort">
update <include refid="table" /> a
join (
select id, @cur_row := @cur_row + 1 sort
from <include refid="table" />
join (select @cur_row := 0) r
where owner_id = #{ownerId}
order by <include refid="table" />.sort) s
on a.id = s.id
set a.sort = s.sort
</sql>
<sql id="listSort">
select id, file_id,
url, owner_id,
created_by, date_created,
updated_by, date_updated,
enabled, note,
@cur_row := @cur_row + 1 sort
from <include refid="table" />
join (select @cur_row := 0) r
where owner_id = #{ownerId}
order by <include refid="table" />.sort
</sql>
</mapper>

View File

@ -4,7 +4,7 @@ import java.util.List;
import javax.validation.constraints.Min;
import me.chyxion.tigon.mybatis.BaseMapper;
import org.apache.ibatis.annotations.Param;
import org.hibernate.validator.constraints.NotBlank;
import javax.validation.constraints.NotBlank;
import com.pudonghot.ambition.crm.model.CustomerIssue;
/**

View File

@ -9,7 +9,7 @@ import org.apache.ibatis.annotations.Param;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import com.pudonghot.ambition.crm.model.Customer;
import org.hibernate.validator.constraints.NotBlank;
import javax.validation.constraints.NotBlank;
/**
* @version 0.0.1

View File

@ -0,0 +1,20 @@
package com.pudonghot.ambition.crm.mapper;
import java.util.List;
import java.util.Map;
import me.chyxion.tigon.mybatis.BaseMapper;
import com.pudonghot.ambition.crm.model.LocalProduct;
/**
* @author Shaun Chyxion <br>
* chyxion@163.com <br>
* Mar 11, 2018 11:39:28
*/
public interface LocalProductMapper extends BaseMapper<String, LocalProduct> {
/**
* list name prefixes
* @return name prefixes
*/
List<Map<String, String>> listNamePrefixes();
}

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
* @author Shaun Chyxion <br>
* chyxion@163.com <br>
* Mar 06, 2018 22:49:18
*/
-->
<!DOCTYPE mapper PUBLIC
"-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pudonghot.ambition.crm.mapper.LocalProductMapper">
<select id="list" resultType="com.pudonghot.ambition.crm.model.LocalProduct">
<include refid="com.pudonghot.ambition.crm.mapper.AttachmentMapper.listForOwner" />
</select>
<select id="listNamePrefixes" resultType="map">
select
distinct name_prefix text, name_prefix value
from <include refid="table" />
where name_prefix is not null
order by name_prefix
</select>
</mapper>

View File

@ -4,7 +4,7 @@ import java.util.List;
import me.chyxion.tigon.mybatis.BaseMapper;
import org.apache.ibatis.annotations.Param;
import com.pudonghot.ambition.crm.model.User;
import org.hibernate.validator.constraints.NotBlank;
import javax.validation.constraints.NotBlank;
/**
* @version 0.0.1

View File

@ -1,6 +0,0 @@
# CodeGen Config
base.cols=enabled,note,date_created,date_updated,created_by,updated_by
base.package=com.pudonghot.ambition.crm
super.base.model.name=M3<String, String>
super.base.model.full.name=me.chyxion.tigon.model.M3
table.prefix=crm

View File

@ -1,8 +0,0 @@
# Config Dev
# Database
datasource.host=127.0.0.1
datasource.port=63306
datasource.database-name=ambition_crm_test
datasource.username=root
datasource.password=696@2^~)oZ@^#*Q

View File

@ -4,7 +4,7 @@ import org.junit.Test;
import java.util.List;
import org.junit.runner.RunWith;
import lombok.extern.slf4j.Slf4j;
import com.pudonghot.ambition.crm.model.ApplicationImage;
import com.pudonghot.ambition.crm.model.AttachedImage;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@ -19,14 +19,18 @@ import org.springframework.test.context.junit4.AbstractTransactionalJUnit4Spring
@Slf4j
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath*:spring/spring-*.xml")
public class ApplicationImageMapperTest extends AbstractTransactionalJUnit4SpringContextTests {
public class AttachedImageMapperTest extends AbstractTransactionalJUnit4SpringContextTests {
@Autowired
private ApplicationImageMapper mapper;
private AttachedImageMapper mapper;
@Autowired
private AttachedFileMapper fileMapper;
@Test
public void testListSort() {
final List<ApplicationImage> images =
final List<AttachedImage> images =
mapper.listSort("5aadc3be13987ee957e00caf");
log.info("Images: [{}].", images);
log.info("Next attached file sort: [{}].", fileMapper.nextSort("5aadc3be13987ee957e00caf"));
log.info("Next attached image sort: [{}].", mapper.nextSort("5aadc3be13987ee957e00caf"));
}
}

View File

@ -0,0 +1,18 @@
package com.pudonghot.ambition.crm.mapper;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
/**
* @author Shaun Chyxion <br>
* chyxion@163.com <br>
* Nov 24, 2018 12:44:25
*/
@Slf4j
public class TestDriver {
@Test
public void run() {
log.info("Run.");
}
}

View File

@ -1,5 +1,6 @@
package com.pudonghot.ambition.crm.mapper;
import lombok.extern.slf4j.Slf4j;
import org.junit.Assert;
import org.junit.Test;
import java.util.Date;
@ -17,64 +18,22 @@ import com.pudonghot.ambition.crm.model.User;
* Tech Support <a href="mailto:chyxion@163.com">Shaun Chyxion</a><br>
* Jun 7, 2017 8:55:14 PM
*/
@Slf4j
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath*:spring/spring-*.xml")
public class UserMapperTest extends AbstractTransactionalJUnit4SpringContextTests {
@Autowired
private UserMapper mapper;
@Autowired
private LocalProductMapper localProductMapper;
@Test
public void mapperTest() {
// String id = String.valueOf(new Date().getTime());
// init model
User m = new User();
String id = "id";
m.setId(id);
m.setDateCreated(new Date());
m.setAccount("s");
m.setPassword("s");
m.setMobile("s");
m.setEmail("s");
m.setName("s");
m.setGender("s");
mapper.insert(m);
Assert.assertTrue(mapper.list(null).size() > 0);
/*
// Your Test Logics
User m1 = mapper.find(id);
// asserts
Assert.assertEquals(id, m1.getId());
Assert.assertEquals("s", m.getLoginId());
Assert.assertEquals("s", m.getPassword());
Assert.assertEquals("s", m.getMobile());
Assert.assertEquals("s", m.getEmail());
Assert.assertEquals("s", m.getName());
Assert.assertEquals("s", m.getGender());
// update
m.setDateUpdated(new Date());
m.setLoginId("S");
m.setPassword("S");
m.setMobile("S");
m.setEmail("S");
m.setName("S");
m.setGender("S");
mapper.update(m);
m1 = mapper.find(id);
// asserts
Assert.assertEquals(id, m1.getId());
Assert.assertNotNull(m1.getDateUpdated());
Assert.assertEquals("S", m.getLoginId());
Assert.assertEquals("S", m.getPassword());
Assert.assertEquals("S", m.getMobile());
Assert.assertEquals("S", m.getEmail());
Assert.assertEquals("S", m.getName());
Assert.assertEquals("S", m.getGender());
// list
Assert.assertTrue(mapper.list(null).size() > 0);
// delete
mapper.delete(id);
m1 = mapper.find(id);
Assert.assertNull(m1);
*/
}
@Test
public void testListProducts() {
log.info("local products [{}].", localProductMapper.list(null));
}
}

View File

@ -10,7 +10,7 @@
<properties>
<packaging>jar</packaging>
<tigon.webmvc.scrope>provided</tigon.webmvc.scrope>
<tigon.webmvc.scope>provided</tigon.webmvc.scope>
</properties>
<parent>
@ -36,7 +36,7 @@
<dependency>
<groupId>me.chyxion.tigon</groupId>
<artifactId>tigon-web</artifactId>
<scope>${tigon.webmvc.scrope}</scope>
<scope>${tigon.webmvc.scope}</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
@ -67,7 +67,7 @@
</activation>
<properties>
<packaging>war</packaging>
<tigon.webmvc.scrope>compile</tigon.webmvc.scrope>
<tigon.webmvc.scope>compile</tigon.webmvc.scope>
<maven.tomcat.port>8088</maven.tomcat.port>
<log.level>DEBUG</log.level>
<log.dir>${project.basedir}/.logs</log.dir>

View File

@ -4,7 +4,7 @@ import lombok.Getter;
import lombok.Setter;
import me.chyxion.tigon.form.FC2;
import javax.validation.constraints.NotNull;
import org.hibernate.validator.constraints.NotBlank;
import javax.validation.constraints.NotBlank;
import org.springframework.web.multipart.MultipartFile;
/**
@ -14,7 +14,7 @@ import org.springframework.web.multipart.MultipartFile;
*/
@Getter
@Setter
public class ApplicationAttachmentFormForCreate extends FC2<String> {
public class ApplicationAttachedFileFormForCreate extends FC2<String> {
private static final long serialVersionUID = 1L;
// Properties

View File

@ -4,7 +4,7 @@ import lombok.Getter;
import lombok.Setter;
import me.chyxion.tigon.form.FC2;
import me.chyxion.tigon.format.annotation.Trim;
import org.hibernate.validator.constraints.NotBlank;
import javax.validation.constraints.NotBlank;
import me.chyxion.tigon.format.annotation.EmptyToNull;
import org.springframework.web.multipart.MultipartFile;

View File

@ -4,7 +4,7 @@ import lombok.Getter;
import lombok.Setter;
import me.chyxion.tigon.form.FC2;
import javax.validation.constraints.NotNull;
import org.hibernate.validator.constraints.NotBlank;
import javax.validation.constraints.NotBlank;
import org.springframework.web.multipart.MultipartFile;
/**

View File

@ -3,7 +3,7 @@ package com.pudonghot.ambition.crm.form.create;
import lombok.Getter;
import lombok.Setter;
import me.chyxion.tigon.form.BaseForm;
import org.hibernate.validator.constraints.NotBlank;
import javax.validation.constraints.NotBlank;
/**
* @version 0.0.1

View File

@ -3,7 +3,7 @@ package com.pudonghot.ambition.crm.form.create;
import lombok.Getter;
import lombok.Setter;
import me.chyxion.tigon.form.FC2;
import org.hibernate.validator.constraints.NotBlank;
import javax.validation.constraints.NotBlank;
/**
* @version 0.0.1

View File

@ -4,7 +4,7 @@ import lombok.Getter;
import lombok.Setter;
import me.chyxion.tigon.form.FC2;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotBlank;
import javax.validation.constraints.NotBlank;
import me.chyxion.tigon.format.annotation.EmptyToNull;
/**

View File

@ -4,7 +4,7 @@ import lombok.Getter;
import lombok.Setter;
import me.chyxion.tigon.form.FC2;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotBlank;
import javax.validation.constraints.NotBlank;
/**
* @version 0.0.1

View File

@ -4,7 +4,7 @@ import lombok.Getter;
import lombok.Setter;
import me.chyxion.tigon.form.FC2;
import javax.validation.constraints.NotNull;
import org.hibernate.validator.constraints.NotBlank;
import javax.validation.constraints.NotBlank;
import com.pudonghot.ambition.crm.model.CustomerProperty;
/**

View File

@ -5,7 +5,7 @@ import lombok.Setter;
import me.chyxion.tigon.form.FC2;
import javax.validation.constraints.NotNull;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotBlank;
import javax.validation.constraints.NotBlank;
/**
* @version 0.0.1

View File

@ -4,7 +4,7 @@ import lombok.Getter;
import lombok.Setter;
import me.chyxion.tigon.form.FC2;
import me.chyxion.tigon.format.annotation.Trim;
import org.hibernate.validator.constraints.NotBlank;
import javax.validation.constraints.NotBlank;
/**
* @version 0.0.1

View File

@ -0,0 +1,26 @@
package com.pudonghot.ambition.crm.form.create;
import lombok.Getter;
import lombok.Setter;
import me.chyxion.tigon.form.FC2;
import org.springframework.web.multipart.MultipartFile;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
* @author Donghuang <br>
* donghuang@wacai.com <br>
* May 17, 2018 17:12:56
*/
@Getter
@Setter
public class LocalProductAttachedFileFormForCreate extends FC2<String> {
private static final long serialVersionUID = 1L;
// Properties
@NotBlank
private String productId;
@NotNull
private MultipartFile attachment;
}

View File

@ -0,0 +1,35 @@
package com.pudonghot.ambition.crm.form.create;
import lombok.Getter;
import lombok.Setter;
import me.chyxion.tigon.form.FC2;
import javax.validation.constraints.NotBlank;
import me.chyxion.tigon.format.annotation.Trim;
import me.chyxion.tigon.format.annotation.EmptyToNull;
import org.springframework.web.multipart.MultipartFile;
/**
* @author Shaun Chyxion <br>
* chyxion@163.com <br>
* Mar 11, 2018 11:14:07
*/
@Getter
@Setter
public class LocalProductFormForCreate extends FC2<String> {
private static final long serialVersionUID = 1L;
// Properties
@Trim
@NotBlank
private String category;
@Trim
@NotBlank
private String name;
@Trim
@EmptyToNull
private String content;
private String[] imageTitles;
private MultipartFile[] images;
private String[] attachmentTitles;
private MultipartFile[] attachments;
}

View File

@ -0,0 +1,25 @@
package com.pudonghot.ambition.crm.form.create;
import lombok.Getter;
import lombok.Setter;
import me.chyxion.tigon.form.FC2;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.NotBlank;
import org.springframework.web.multipart.MultipartFile;
/**
* @author Shaun Chyxion <br>
* chyxion@163.com <br>
* Mar 11, 2018 11:14:07
*/
@Getter
@Setter
public class LocalProductImageFormForCreate extends FC2<String> {
private static final long serialVersionUID = 1L;
// Properties
@NotBlank
private String productId;
@NotNull
private MultipartFile image;
}

View File

@ -7,7 +7,7 @@ import javax.validation.constraints.Pattern;
import me.chyxion.tigon.format.annotation.Trim;
import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotBlank;
import javax.validation.constraints.NotBlank;
import static com.pudonghot.ambition.crm.common.Constants.GENDER_REGEXP;
/**

View File

@ -0,0 +1,15 @@
package com.pudonghot.ambition.crm.form.update;
import lombok.Getter;
import lombok.Setter;
/**
* @author Donghuang <br>
* donghuang@wacai.com <br>
* May 17, 2018 17:12:46
*/
@Getter
@Setter
public class ApplicationAttachedFileFormForUpdate extends ApplicationAttachmentFormForUpdate {
private static final long serialVersionUID = 1L;
}

View File

@ -2,14 +2,18 @@ package com.pudonghot.ambition.crm.form.update;
import lombok.Getter;
import lombok.Setter;
import com.pudonghot.ambition.crm.model.Attachment;
/**
* @author Donghuang <br>
* donghuang@wacai.com <br>
* May 17, 2018 17:12:46
* @author Shaun Chyxion <br>
* chyxion@163.com <br>
* May 17, 2018 17:50:22
*/
@Getter
@Setter
public class ApplicationAttachmentFormForUpdate extends ApplicationFileFormForUpdate {
public class ApplicationAttachmentFormForUpdate extends AttachmentFormForUpdate {
private static final long serialVersionUID = 1L;
// current user is admin
private boolean admin;
}

View File

@ -3,9 +3,9 @@ package com.pudonghot.ambition.crm.form.update;
import lombok.Getter;
import lombok.Setter;
import me.chyxion.tigon.form.FU2;
import javax.validation.constraints.NotBlank;
import me.chyxion.tigon.format.annotation.Trim;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotBlank;
import me.chyxion.tigon.format.annotation.EmptyToNull;
/**

View File

@ -12,6 +12,6 @@ import lombok.Setter;
*/
@Getter
@Setter
public class ApplicationImageFormForUpdate extends ApplicationFileFormForUpdate {
public class ApplicationImageFormForUpdate extends ApplicationAttachmentFormForUpdate {
private static final long serialVersionUID = 1L;
}

View File

@ -11,10 +11,8 @@ import me.chyxion.tigon.form.FU2;
*/
@Getter
@Setter
public class ApplicationFileFormForUpdate extends FU2<String, String> {
public class AttachmentFormForUpdate extends FU2<String, String> {
private static final long serialVersionUID = 1L;
// current user is admin
private boolean admin;
private float sort;
}

View File

@ -4,7 +4,7 @@ import lombok.Getter;
import lombok.Setter;
import me.chyxion.tigon.form.FU2;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotBlank;
import javax.validation.constraints.NotBlank;
/**
* @version 0.0.1

View File

@ -4,7 +4,7 @@ import lombok.Getter;
import lombok.Setter;
import me.chyxion.tigon.form.FU2;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotBlank;
import javax.validation.constraints.NotBlank;
/**
* @version 0.0.1

View File

@ -5,7 +5,7 @@ import lombok.Setter;
import me.chyxion.tigon.form.FU2;
import javax.validation.constraints.NotNull;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotBlank;
import javax.validation.constraints.NotBlank;
/**
* @version 0.0.1

View File

@ -3,7 +3,7 @@ package com.pudonghot.ambition.crm.form.update;
import lombok.Getter;
import lombok.Setter;
import me.chyxion.tigon.form.FU2;
import org.hibernate.validator.constraints.NotBlank;
import javax.validation.constraints.NotBlank;
/**
* @version 0.0.1

View File

@ -0,0 +1,15 @@
package com.pudonghot.ambition.crm.form.update;
import lombok.Getter;
import lombok.Setter;
/**
* @author Donghuang <br>
* donghuang@wacai.com <br>
* May 17, 2018 17:12:46
*/
@Getter
@Setter
public class LocalProductAttachedFileFormForUpdate extends LocalProductAttachmentFormForUpdate {
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,15 @@
package com.pudonghot.ambition.crm.form.update;
import lombok.Getter;
import lombok.Setter;
/**
* @author Shaun Chyxion <br>
* chyxion@163.com <br>
* May 17, 2018 17:50:22
*/
@Getter
@Setter
public class LocalProductAttachmentFormForUpdate extends AttachmentFormForUpdate {
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,32 @@
package com.pudonghot.ambition.crm.form.update;
import lombok.Getter;
import lombok.Setter;
import me.chyxion.tigon.form.FU2;
import javax.validation.constraints.NotBlank;
import me.chyxion.tigon.format.annotation.Trim;
import org.hibernate.validator.constraints.Length;
import me.chyxion.tigon.format.annotation.EmptyToNull;
/**
* @version 0.0.1
* @since 0.0.1
* @author Shaun Chyxion <br>
* chyxion@163.com <br>
* May 10, 2016 1:42:01 PM
*/
@Getter
@Setter
public class LocalProductFormForUpdate extends FU2<String, String> {
private static final long serialVersionUID = 1L;
@Trim
@NotBlank
private String category;
@NotBlank
@Length(max = 64)
private String name;
@Trim
@EmptyToNull
private String content;
}

View File

@ -0,0 +1,18 @@
package com.pudonghot.ambition.crm.form.update;
import com.pudonghot.ambition.crm.model.LocalProduct;
import lombok.Getter;
import lombok.Setter;
/**
* @version 0.0.1
* @since 0.0.1
* @author Shaun Chyxion <br>
* chyxion@163.com <br>
* May 10, 2016 1:42:01 PM
*/
@Getter
@Setter
public class LocalProductImageFormForUpdate extends LocalProductAttachmentFormForUpdate {
private static final long serialVersionUID = 1L;
}

View File

@ -8,7 +8,7 @@ import javax.validation.constraints.Pattern;
import me.chyxion.tigon.format.annotation.Trim;
import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotBlank;
import javax.validation.constraints.NotBlank;
import me.chyxion.tigon.format.annotation.EmptyToNull;
import static com.pudonghot.ambition.crm.common.Constants.GENDER_REGEXP;

View File

@ -3,7 +3,7 @@ package com.pudonghot.ambition.crm.form.update;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotBlank;
import javax.validation.constraints.NotBlank;
/**
* @version 0.0.1

View File

@ -5,6 +5,7 @@ import lombok.Setter;
import me.chyxion.tigon.model.M3;
import me.chyxion.tigon.mybatis.Table;
import me.chyxion.tigon.mybatis.Transient;
import lombok.experimental.FieldNameConstants;
/**
* @author Donghuang <br>
@ -14,15 +15,10 @@ import me.chyxion.tigon.mybatis.Transient;
@Getter
@Setter
@Table("crm_application")
@FieldNameConstants(prefix = "")
public class Application extends M3<String, String> {
private static final long serialVersionUID = 1L;
// Column Names
public static final String NAME = "name";
public static final String NAME_PREFIX = "name_prefix";
public static final String CONTENT = "content";
public static final String OWNER = "owner";
// Properties
private String name;
private String namePrefix;

View File

@ -11,7 +11,7 @@ import me.chyxion.tigon.mybatis.Table;
*/
@Getter
@Setter
@Table("crm_application_attachment")
public class ApplicationAttachment extends ApplicationFile {
@Table("crm_attached_file")
public class AttachedFile extends Attachment {
private static final long serialVersionUID = 1L;
}

View File

@ -11,7 +11,7 @@ import me.chyxion.tigon.mybatis.Table;
*/
@Getter
@Setter
@Table("crm_application_image")
public class ApplicationImage extends ApplicationFile {
@Table("crm_attached_image")
public class AttachedImage extends Attachment {
private static final long serialVersionUID = 1L;
}

View File

@ -3,6 +3,7 @@ package com.pudonghot.ambition.crm.model;
import lombok.Getter;
import lombok.Setter;
import me.chyxion.tigon.model.M3;
import lombok.experimental.FieldNameConstants;
/**
* @author Donghuang <br>
@ -11,18 +12,13 @@ import me.chyxion.tigon.model.M3;
*/
@Getter
@Setter
public class ApplicationFile extends M3<String, String> {
@FieldNameConstants(prefix = "")
public class Attachment extends M3<String, String> {
private static final long serialVersionUID = 1L;
// Column Names
public static final String FILE_ID = "file_id";
public static final String URL = "url";
public static final String APPLICATION_ID = "application_id";
public static final String SORT = "sort";
// Properties
private String ownerId;
private String fileId;
private String url;
private String applicationId;
private float sort;
}

View File

@ -4,6 +4,7 @@ import lombok.Getter;
import lombok.Setter;
import me.chyxion.tigon.model.M3;
import me.chyxion.tigon.mybatis.Table;
import lombok.experimental.FieldNameConstants;
import me.chyxion.tigon.mybatis.UseGeneratedKeys;
/**
@ -15,17 +16,11 @@ import me.chyxion.tigon.mybatis.UseGeneratedKeys;
@Getter
@Setter
@UseGeneratedKeys
@FieldNameConstants(prefix = "")
@Table("crm_auth_failed_log")
public class AuthFailedLog extends M3<String, Long> {
private static final long serialVersionUID = 1L;
// Column Names
public static final String LOGIN_ID = "login_id";
public static final String PASSWORD = "password";
public static final String IP = "ip";
public static final String USER_AGENT = "user_agent";
public static final String EXT = "ext";
// Properties
private String loginId;
private String password;

View File

@ -4,6 +4,7 @@ import lombok.Getter;
import lombok.Setter;
import me.chyxion.tigon.model.M3;
import me.chyxion.tigon.mybatis.Table;
import lombok.experimental.FieldNameConstants;
import me.chyxion.tigon.mybatis.UseGeneratedKeys;
/**
@ -16,19 +17,13 @@ import me.chyxion.tigon.mybatis.UseGeneratedKeys;
@Setter
@UseGeneratedKeys
@Table("crm_auth_log")
@FieldNameConstants(prefix = "")
public class AuthLog extends M3<String, Long> {
private static final long serialVersionUID = 1L;
// Column Names
public static final String USER_ID = "user_id";
public static final String USER_AGENT = "user_agent";
public static final String IP = "ip";
public static final String EXT = "ext";
// Properties
private String userId;
private String userAgent;
private String ip;
private String ext;
}

View File

@ -6,6 +6,7 @@ import java.util.Date;
import me.chyxion.tigon.model.M3;
import me.chyxion.tigon.mybatis.Table;
import me.chyxion.tigon.mybatis.Transient;
import lombok.experimental.FieldNameConstants;
/**
* @version 0.0.1
@ -16,25 +17,14 @@ import me.chyxion.tigon.mybatis.Transient;
@Getter
@Setter
@Table("crm_customer")
@FieldNameConstants(prefix = "")
public class Customer extends M3<String, String> {
private static final long serialVersionUID = 1L;
// Column Names
public static final String SALESPERSON = "salesperson";
public static final String DATE_ADDED = "date_added";
public static final String NAME = "name";
public static final String COUNTRY_CODE = "country_code";
public static final String STATE = "state";
public static final String CITY = "city";
public static final String MS = "ms";
public static final String REGION = "region";
public static final String STATUS = "status";
public static final String SUM_YTD_SALES = "sum_ytd_sales";
public static final String COUNT_YTD_SALES = "count_ytd_sales";
// Properties
private String salesperson;
private Date dateAdded;
private String id2;
private String name;
private String countryCode;
private String state;

View File

@ -2,8 +2,9 @@ package com.pudonghot.ambition.crm.model;
import lombok.Getter;
import lombok.Setter;
import me.chyxion.tigon.mybatis.Table;
import me.chyxion.tigon.model.M3;
import me.chyxion.tigon.mybatis.Table;
import lombok.experimental.FieldNameConstants;
/**
* @version 0.0.1
@ -13,14 +14,11 @@ import me.chyxion.tigon.model.M3;
*/
@Getter
@Setter
@FieldNameConstants(prefix = "")
@Table("crm_customer_application")
public class CustomerApplication extends M3<String, String> {
private static final long serialVersionUID = 1L;
// Column Names
public static final String CUSTOMER_ID = "customer_id";
public static final String APPLICATION_ID = "application_id";
// Properties
private String customerId;
private String applicationId;

View File

@ -4,6 +4,7 @@ import lombok.Getter;
import lombok.Setter;
import me.chyxion.tigon.model.M3;
import me.chyxion.tigon.mybatis.Table;
import lombok.experimental.FieldNameConstants;
/**
* @version 0.0.1
@ -13,15 +14,11 @@ import me.chyxion.tigon.mybatis.Table;
*/
@Getter
@Setter
@FieldNameConstants(prefix = "")
@Table("crm_customer_issue")
public class CustomerIssue extends M3<String, String> {
private static final long serialVersionUID = 1L;
// Column Names
public static final String CUSTOMER_ID = "customer_id";
public static final String ISSUE = "issue";
public static final String ARTIFICIAL = "artificial";
// Properties
private String customerId;
private String issue;

View File

@ -4,6 +4,7 @@ import lombok.Getter;
import lombok.Setter;
import me.chyxion.tigon.model.M3;
import me.chyxion.tigon.mybatis.Table;
import lombok.experimental.FieldNameConstants;
/**
* @version 0.0.1
@ -13,15 +14,11 @@ import me.chyxion.tigon.mybatis.Table;
*/
@Getter
@Setter
@FieldNameConstants(prefix = "")
@Table("crm_customer_permission")
public class CustomerPermission extends M3<String, String> {
private static final long serialVersionUID = 1L;
// Column Names
public static final String USER_ACCOUNT = "user_account";
public static final String CUSTOMER_ID = "customer_id";
public static final String TYPE = "type";
public enum Type {
SYSTEM,
APPLICATION

Some files were not shown because too many files have changed in this diff Show More