image created

This commit is contained in:
Shaun Chyxion 2018-03-21 08:58:00 +08:00
parent 2bf6f74181
commit bc711855ac
12 changed files with 261 additions and 42 deletions

View File

@ -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}
*/

View File

@ -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 <br>
@ -12,5 +16,25 @@ import com.pudonghot.ambition.crm.form.create.ApplicationFormForCreate;
*/
public interface ApplicationService
extends BaseCrudByFormService<String, Application, ApplicationFormForCreate, ApplicationFormForUpdate> {
/**
* 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);
}

View File

@ -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<Application> 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<Application> 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;
}
}

View File

@ -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));
}
/**

View File

@ -18,4 +18,11 @@ public interface ApplicationImageMapper extends BaseMapper<String, ApplicationIm
* @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);
}

View File

@ -17,4 +17,14 @@
where application_id = #{applicationId}
</select>
<update id="updateSort">
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
</update>
</mapper>

View File

@ -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 <br>
* chyxion@163.com <br>
* Mar 11, 2018 11:14:07
*/
@Getter
@Setter
public class ApplicationImageFormForCreate extends FC2<String> {
private static final long serialVersionUID = 1L;
// Properties
// current user is admin
private boolean admin;
@NotBlank
private String applicationId;
@NotNull
private MultipartFile image;
}

View File

@ -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<String, String> {
@Trim
@EmptyToNull
private String owner;
private String[] imageTitles;
private MultipartFile[] images;
}

View File

@ -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 <br>
* chyxion@163.com <br>
* May 10, 2016 1:42:01 PM
*/
@Getter
@Setter
public class ApplicationImageFormForUpdate extends FU2<String, String> {
private static final long serialVersionUID = 1L;
// current user is admin
private boolean admin;
private int sort;
}

View File

@ -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 + '<br />' : '') + e.join('<br />');
}, ''));
// 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);
}
});

View File

@ -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 + ']'}]);

View File

@ -5,6 +5,62 @@
{{wysiwyg-editor model=model name='content'}}
{{/form-input}}
{{#form-input label='Images' name='images'}}
<div class="widget-box transparent" style="opacity: 1;">
<!-- #section:custom/widget-box.options -->
<div class="widget-header">
{{!-- <h5 class="widget-title bigger lighter">
<i class="ace-icon fa fa-table"></i>
Users
</h5> --}}
<div class="widget-toolbar action-buttons">
<a href="#" data-rel="tooltip" title="Add Image" {{action (route-action 'addImage')}}>
<i class="ace-icon fa fa-plus-circle green"></i>
</a>
</div>
</div>
<!-- /section:custom/widget-box.options -->
<div class="widget-body">
<div class="widget-main no-padding">
<table class="table table-striped table-bordered table-hover">
<thead class="thin-border-bottom">
<tr>
<th>
<i class="ace-icon fa fa-user"></i>
Image
</th>
<th>
Description
</th>
<th>
<i class="ace-icon fa fa-cogs bigger-110 hidden-480"></i>
Settings
</th>
</tr>
</thead>
<tbody>
{{#each model.images as |image|}}
<tr>
<td>
{{image.id}}
</td>
<td>
{{image.note}}
</td>
<td>
{{u.note}}
</td>
</tr>
{{/each}}
</tbody>
</table>
</div>
</div>
</div>
{{/form-input}}
{{#form-input name='image' label='Images'}}
<div class="widget-box transparent">
<div class="widget-header widget-header-small">
@ -33,7 +89,6 @@
</div>
{{/form-input}}
{{form-input-enabled label='Enabled' enabledText='TRUE' disabledText='FALSE'}}
{{form-input name='note' label='Remark'}}
<hr />