diff --git a/server/crm/src/main/java/com/pudonghot/ambition/crm/controller/ApplicationController.java b/server/crm/src/main/java/com/pudonghot/ambition/crm/controller/ApplicationController.java index dd4357c..5c9ff9e 100644 --- a/server/crm/src/main/java/com/pudonghot/ambition/crm/controller/ApplicationController.java +++ b/server/crm/src/main/java/com/pudonghot/ambition/crm/controller/ApplicationController.java @@ -3,6 +3,9 @@ package com.pudonghot.ambition.crm.controller; import java.util.List; import java.util.Arrays; import javax.validation.Valid; + +import com.pudonghot.ambition.crm.form.create.ApplicationImageFormForCreate; +import com.pudonghot.ambition.crm.form.update.ApplicationImageFormForUpdate; import me.chyxion.tigon.mybatis.Search; import javax.validation.constraints.Max; import javax.validation.constraints.Min; @@ -11,6 +14,7 @@ import me.chyxion.tigon.model.ListResult; import org.apache.commons.lang3.StringUtils; import com.pudonghot.ambition.crm.model.User; import org.apache.commons.lang3.tuple.Pair; +import org.hibernate.validator.constraints.NotBlank; import org.springframework.stereotype.Controller; import com.pudonghot.ambition.crm.model.Application; import com.pudonghot.ambition.crm.service.UserService; @@ -93,7 +97,6 @@ public class ApplicationController ((ApplicationService) queryService).create(form); } - @RequiresRoles(User.ROLE_ADMIN) @RequestMapping(value = "/update", method = RequestMethod.POST) public void update( @Valid ApplicationFormForUpdate form) { @@ -101,6 +104,25 @@ public class ApplicationController ((ApplicationService) queryService).update(form); } + @RequestMapping(value = "/add-image", method = RequestMethod.POST) + public void addImage( + @Valid ApplicationImageFormForCreate form) { + form.setAdmin(getAuthUser().getUser().getData().isAdmin()); + ((ApplicationService) queryService).addImage(form); + } + + @RequestMapping(value = "/remove-image", method = RequestMethod.POST) + public void removeImage(@NotBlank @RequestParam("id") String id) { + final User user = getAuthUser().getUser().getData(); + ((ApplicationService) queryService).removeImage(id, user.getId(), user.isAdmin()); + } + + @RequestMapping(value = "/update-image", method = RequestMethod.POST) + public void updateImage(@Valid ApplicationImageFormForUpdate form) { + form.setAdmin(getAuthUser().getUser().getData().isAdmin()); + ((ApplicationService) queryService).updateImage(form); + } + /** * {@inheritDoc} */ diff --git a/server/crm/src/main/java/com/pudonghot/ambition/crm/service/ApplicationService.java b/server/crm/src/main/java/com/pudonghot/ambition/crm/service/ApplicationService.java index 135fc3e..9396a22 100644 --- a/server/crm/src/main/java/com/pudonghot/ambition/crm/service/ApplicationService.java +++ b/server/crm/src/main/java/com/pudonghot/ambition/crm/service/ApplicationService.java @@ -1,9 +1,13 @@ package com.pudonghot.ambition.crm.service; +import javax.validation.Valid; import com.pudonghot.ambition.crm.model.Application; +import org.hibernate.validator.constraints.NotBlank; import me.chyxion.tigon.service.BaseCrudByFormService; 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; /** * @author Shaun Chyxion
@@ -12,5 +16,25 @@ import com.pudonghot.ambition.crm.form.create.ApplicationFormForCreate; */ public interface ApplicationService extends BaseCrudByFormService { + + /** + * add image + * @param form form + */ + void addImage(@Valid ApplicationImageFormForCreate form); + + /** + * remove image + * @param id image id + * @param userId user id + * @param admin admin + */ + void removeImage(@NotBlank String id, String userId, boolean admin); + + /** + * update image + * @param form form + */ + void updateImage(@Valid ApplicationImageFormForUpdate form); } diff --git a/server/crm/src/main/java/com/pudonghot/ambition/crm/service/support/ApplicationServiceSupport.java b/server/crm/src/main/java/com/pudonghot/ambition/crm/service/support/ApplicationServiceSupport.java index b7870f7..b4ba2ad 100644 --- a/server/crm/src/main/java/com/pudonghot/ambition/crm/service/support/ApplicationServiceSupport.java +++ b/server/crm/src/main/java/com/pudonghot/ambition/crm/service/support/ApplicationServiceSupport.java @@ -1,9 +1,15 @@ package com.pudonghot.ambition.crm.service.support; +import java.util.Arrays; import java.util.Date; import java.io.IOException; import java.io.InputStream; + +import com.pudonghot.ambition.crm.form.create.ApplicationImageFormForCreate; +import com.pudonghot.ambition.crm.form.update.ApplicationImageFormForUpdate; import lombok.extern.slf4j.Slf4j; +import me.chyxion.tigon.mybatis.Search; +import org.springframework.transaction.annotation.Transactional; import org.springframework.util.Assert; import me.chyxion.tigon.model.ViewModel; import org.springframework.stereotype.Service; @@ -56,21 +62,62 @@ public class ApplicationServiceSupport */ @Override public ViewModel update(final ApplicationFormForUpdate form) { - final String id = form.getId(); - final Application application = find(id); - Assert.state(application != null, "No application [" + id + "] found"); - final String updatedBy = form.getUpdatedBy(); - Assert.state(form.isAdmin() || application.getOwner().equals(updatedBy), - "No permission to update application"); - - uploadImages(id, imageMapper.nextSort(id), form.getImages(), form.getImageTitles(), updatedBy); - return update(form.copy(application)); + return update(form.copy(validatePerm(form.getId(), form.getUpdatedBy(), form.isAdmin()))); } - private void uploadImages(final String id, int sort, final MultipartFile[] images, final String[] titles, final String createdBy) { + /** + * {@inheritDoc} + */ + @Override + public ViewModel findViewModel(final String id) { + return super.findViewModel(id) + .setAttr("images", imageMapper.list( + new Search(ApplicationImage.APPLICATION_ID, id) + .asc(ApplicationImage.SORT))); + } + + /** + * {@inheritDoc} + */ + @Override + public void addImage(final ApplicationImageFormForCreate form) { + final String applicationId = form.getApplicationId(); + final String createdBy = form.getCreatedBy(); + validatePerm(applicationId, createdBy, form.isAdmin()); + uploadImages(applicationId, + imageMapper.nextSort(applicationId), + new MultipartFile[] {form.getImage()}, + new String[] {form.getNote()}, + createdBy); + } + + /** + * {@inheritDoc} + */ + @Override + @Transactional + public void removeImage(final String id, final String userId, final boolean admin) { + final ApplicationImage appImage = imageMapper.find(id); + Assert.state(appImage != null, "No application image [" + id + "] found"); + final String applicationId = appImage.getApplicationId(); + validatePerm(applicationId, userId, admin); + fileApi.delete(imageFolder(applicationId) + "/" + id); + imageMapper.delete(id); + imageMapper.updateSort(applicationId); + } + + /** + * {@inheritDoc} + */ + @Override + public void updateImage(final ApplicationImageFormForUpdate form) { + + } + + private void uploadImages(final String applicationId, int sort, final MultipartFile[] images, final String[] titles, final String createdBy) { if (images != null) { final Date now = new Date(); - final String imageFolder = imageFolder(id); + final String imageFolder = imageFolder(applicationId); int i = 0; for (final MultipartFile image : images) { if (!image.isEmpty()) { @@ -79,7 +126,7 @@ public class ApplicationServiceSupport fileApi.uploadImage(ins, imageFolder, imageId); final ApplicationImage appImage = new ApplicationImage(); appImage.setId(imageId); - appImage.setApplicationId(id); + appImage.setApplicationId(applicationId); appImage.setSort(sort++); appImage.setEnabled(true); appImage.setNote(titles[i]); @@ -92,6 +139,9 @@ public class ApplicationServiceSupport "Read upload image [" + image.getOriginalFilename() + "] error cased", e); } } + else { + log.info("Application image [{}] is empty, ignore.", image); + } ++i; } } @@ -100,4 +150,12 @@ public class ApplicationServiceSupport private String imageFolder(final String appId) { return "app/" + appId; } + + private Application validatePerm(final String appId, final String userId, final boolean admin) { + final Application application = find(appId); + Assert.state(application != null, "No application [" + appId + "] found"); + Assert.state(admin || application.getOwner().equals(userId), + "No permission to update application"); + return application; + } } diff --git a/server/file-disk/src/main/java/com/pudonghot/ambition/file/disk/DiskFileSupport.java b/server/file-disk/src/main/java/com/pudonghot/ambition/file/disk/DiskFileSupport.java index 4945fb0..2f426a1 100644 --- a/server/file-disk/src/main/java/com/pudonghot/ambition/file/disk/DiskFileSupport.java +++ b/server/file-disk/src/main/java/com/pudonghot/ambition/file/disk/DiskFileSupport.java @@ -65,9 +65,9 @@ public class DiskFileSupport */ @Override @Transactional - public void delete(String name) { - fileInfoMapper.delete(nameSearch(name)); + public void delete(final String name) { FileUtils.deleteQuietly(getFile(name)); + fileInfoMapper.delete(nameSearch(name)); } /** diff --git a/server/mapper/src/main/java/com/pudonghot/ambition/crm/mapper/ApplicationImageMapper.java b/server/mapper/src/main/java/com/pudonghot/ambition/crm/mapper/ApplicationImageMapper.java index db8a6d5..1bd937d 100644 --- a/server/mapper/src/main/java/com/pudonghot/ambition/crm/mapper/ApplicationImageMapper.java +++ b/server/mapper/src/main/java/com/pudonghot/ambition/crm/mapper/ApplicationImageMapper.java @@ -18,4 +18,11 @@ public interface ApplicationImageMapper extends BaseMapper + + update crm_application_image a + join ( + select id, @cur_row := @cur_row + 1 sort + from crm_application_image + join (select @cur_row := 0) r + where application_id = #{applicationId}) s + on a.id = s.id + set a.sort = s.sort + diff --git a/server/model/src/main/java/com/pudonghot/ambition/crm/form/create/ApplicationImageFormForCreate.java b/server/model/src/main/java/com/pudonghot/ambition/crm/form/create/ApplicationImageFormForCreate.java new file mode 100644 index 0000000..368bae5 --- /dev/null +++ b/server/model/src/main/java/com/pudonghot/ambition/crm/form/create/ApplicationImageFormForCreate.java @@ -0,0 +1,27 @@ +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 org.hibernate.validator.constraints.NotBlank; +import org.springframework.web.multipart.MultipartFile; + +/** + * @author Shaun Chyxion
+ * chyxion@163.com
+ * Mar 11, 2018 11:14:07 + */ +@Getter +@Setter +public class ApplicationImageFormForCreate extends FC2 { + private static final long serialVersionUID = 1L; + + // Properties + // current user is admin + private boolean admin; + @NotBlank + private String applicationId; + @NotNull + private MultipartFile image; +} diff --git a/server/model/src/main/java/com/pudonghot/ambition/crm/form/update/ApplicationFormForUpdate.java b/server/model/src/main/java/com/pudonghot/ambition/crm/form/update/ApplicationFormForUpdate.java index 934f55b..efd1cfd 100644 --- a/server/model/src/main/java/com/pudonghot/ambition/crm/form/update/ApplicationFormForUpdate.java +++ b/server/model/src/main/java/com/pudonghot/ambition/crm/form/update/ApplicationFormForUpdate.java @@ -7,7 +7,6 @@ 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; -import org.springframework.web.multipart.MultipartFile; /** * @version 0.0.1 @@ -32,6 +31,4 @@ public class ApplicationFormForUpdate extends FU2 { @Trim @EmptyToNull private String owner; - private String[] imageTitles; - private MultipartFile[] images; } diff --git a/server/model/src/main/java/com/pudonghot/ambition/crm/form/update/ApplicationImageFormForUpdate.java b/server/model/src/main/java/com/pudonghot/ambition/crm/form/update/ApplicationImageFormForUpdate.java new file mode 100644 index 0000000..3f5d839 --- /dev/null +++ b/server/model/src/main/java/com/pudonghot/ambition/crm/form/update/ApplicationImageFormForUpdate.java @@ -0,0 +1,22 @@ +package com.pudonghot.ambition.crm.form.update; + +import lombok.Getter; +import lombok.Setter; +import me.chyxion.tigon.form.FU2; + +/** + * @version 0.0.1 + * @since 0.0.1 + * @author Shaun Chyxion
+ * chyxion@163.com
+ * May 10, 2016 1:42:01 PM + */ +@Getter +@Setter +public class ApplicationImageFormForUpdate extends FU2 { + private static final long serialVersionUID = 1L; + + // current user is admin + private boolean admin; + private int sort; +} diff --git a/web/app/components/editable-cell.js b/web/app/components/editable-cell.js index 0a7adb2..a591b50 100644 --- a/web/app/components/editable-cell.js +++ b/web/app/components/editable-cell.js @@ -33,25 +33,9 @@ export default BaseComponent.extend({ me.set('isUpdating', false); } else { - let service = me.get('service'); - let model = me.get('model'); - let vr = service.updateValidate(model); - if (vr) { - Ember.Logger.info('Validate Result: ', vr); - me.get('message').warn(Object.keys(vr).map((e)=> { - return vr[e]; - }).reduce((msg, e)=> { - return (msg ? msg + '
' : '') + e.join('
'); - }, '')); - // reset field value - me.resetValue(); - me.set('isUpdating', false); - } - else if (me.get('confirm-update')) { + if (me.get('confirm-update')) { me.get('dialog').confirm('Are you sure to update?', () => { - let onUpdated = me.get('on-updated'); - onUpdated ? service.update(model).then(r => onUpdated(r)) : service.update(model, true); - me.set('isUpdating', false); + me.execUpdate(); }, () => { // reset field value @@ -60,14 +44,12 @@ export default BaseComponent.extend({ }); } else { - let onUpdated = me.get('on-updated'); - onUpdated ? service.update(model).then(r => onUpdated(r)) : service.update(model, true); - me.set('isUpdating', false); + me.execUpdate(); } } } else { - Ember.Logger.info('Field Value Not Changed.') + Ember.Logger.info('Editable cell field value not changed.') me.set('isUpdating', false); } me.set('isEditing', false); @@ -79,5 +61,20 @@ export default BaseComponent.extend({ resetValue() { let me = this; me.set('model.' + me.get('field'), me.get('oldValue')); + }, + execUpdate() { + const me = this; + const model = me.get('model'); + let onUpdated = me.get('on-updated'); + let postUrl = me.get('post-url'); + if (postUrl) { + let p = me.get('store').ajaxPost(postUrl, model); + onUpdated && p.then(onUpdated); + } + else { + let service = me.get('service'); + onUpdated ? service.update(model).then(onUpdated) : service.update(model, true); + } + me.set('isUpdating', false); } }); diff --git a/web/app/routes/customer-application/edit.js b/web/app/routes/customer-application/edit.js index 4b5f5f0..b5af587 100644 --- a/web/app/routes/customer-application/edit.js +++ b/web/app/routes/customer-application/edit.js @@ -5,7 +5,7 @@ export default BaseEditRoute.extend({ afterModel(model) { const me = this; me._super(...arguments); - model.images = [{}]; + // model.images = [{}]; this.set('breadcrumbs', [{route: 'customer-application.list', params: 1, text: 'Customer Application'}, {text: 'Edit Customer Application[' + model.name + ']'}]); diff --git a/web/app/templates/customer-application/edit.hbs b/web/app/templates/customer-application/edit.hbs index 2f06e43..ab5bac3 100644 --- a/web/app/templates/customer-application/edit.hbs +++ b/web/app/templates/customer-application/edit.hbs @@ -5,6 +5,62 @@ {{wysiwyg-editor model=model name='content'}} {{/form-input}} + {{#form-input label='Images' name='images'}} +
+ +
+ {{!--
+ + Users +
--}} +
+ + + +
+
+ + +
+
+ + + + + + + + + + + {{#each model.images as |image|}} + + + + + + {{/each}} + +
+ + Image + + Description + + + Settings +
+ {{image.id}} + + {{image.note}} + + {{u.note}} +
+
+
+
+ {{/form-input}} + {{#form-input name='image' label='Images'}}
@@ -33,7 +89,6 @@
{{/form-input}} - {{form-input-enabled label='Enabled' enabledText='TRUE' disabledText='FALSE'}} {{form-input name='note' label='Remark'}}