application image layout update
This commit is contained in:
parent
eec7f13410
commit
35ca35f583
@ -9,6 +9,7 @@ import me.chyxion.tigon.model.ViewModel;
|
||||
import javax.validation.constraints.Max;
|
||||
import javax.validation.constraints.Min;
|
||||
import me.chyxion.tigon.model.ListResult;
|
||||
import me.chyxion.tigon.webmvc.ResourceModel;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@ -101,21 +102,6 @@ public class CustomerController
|
||||
Pair.of(CRITERION_COLS.get("application"), String.class));
|
||||
FILTER_COLS.put("issue",
|
||||
Pair.of(CRITERION_COLS.get("issue"), Boolean.class));
|
||||
|
||||
// filter(search, joFilters, "dateAdded", Integer[].class);
|
||||
// filter(search, joFilters, "year");
|
||||
//
|
||||
// filter(search, joFilters, "ms");
|
||||
// filter(search, joFilters, "region");
|
||||
// filter(search, joFilters, "countryCode");
|
||||
// filter(search, joFilters, "state");
|
||||
// filter(search, joFilters, "city");
|
||||
// filter(search, joFilters, "salesperson");
|
||||
// filter(search, joFilters, "status");
|
||||
// filter(search, joFilters, "application");
|
||||
//
|
||||
// filter(search, joFilters, "issue", Boolean[].class);
|
||||
|
||||
}
|
||||
|
||||
@RequestMapping("/list")
|
||||
@ -169,6 +155,12 @@ public class CustomerController
|
||||
((CustomerService) queryService).importCSV(getUserId(), getInputStream(csv));
|
||||
}
|
||||
|
||||
@RequiresRoles(User.ROLE_ADMIN)
|
||||
@RequestMapping(value = "/export", method = RequestMethod.POST)
|
||||
public ResourceModel exportCSV() {
|
||||
return new ResourceModel(((CustomerService) queryService).exportCSV(getUserId()), null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.pudonghot.ambition.crm.service;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import com.pudonghot.ambition.crm.model.Customer;
|
||||
@ -25,5 +26,11 @@ public interface CustomerService
|
||||
* @param csvIn csv input stream
|
||||
*/
|
||||
void importCSV(@NotBlank String operator, @NotNull InputStream csvIn);
|
||||
|
||||
/**
|
||||
* export csv
|
||||
* @param operator
|
||||
*/
|
||||
File exportCSV(@NotBlank String operator);
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,14 @@
|
||||
package com.pudonghot.ambition.crm.service.support;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.csv.CSVFormat;
|
||||
import org.apache.commons.csv.CSVPrinter;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.springframework.util.Assert;
|
||||
import me.chyxion.tigon.mybatis.Search;
|
||||
import me.chyxion.tigon.model.ViewModel;
|
||||
@ -14,6 +20,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.pudonghot.ambition.crm.util.CSVUtils;
|
||||
import com.pudonghot.ambition.crm.common.Constants;
|
||||
import org.apache.commons.lang3.time.DateFormatUtils;
|
||||
import com.pudonghot.ambition.crm.service.UserService;
|
||||
import com.pudonghot.ambition.crm.service.CustomerService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -54,6 +61,24 @@ public class CustomerServiceSupport
|
||||
@Autowired
|
||||
private ApplicationMapper applicationMapper;
|
||||
|
||||
private static final String SPLITTER = new String(new int[]{0x1d}, 0, 1);
|
||||
private static final CSVFormat EXPORT_FORMAT =
|
||||
CSVFormat.DEFAULT.withHeader(
|
||||
"ID",
|
||||
"Name",
|
||||
"Sales(3 Years)",
|
||||
"Comment",
|
||||
"Application",
|
||||
"Status",
|
||||
"Year Added",
|
||||
"Year",
|
||||
"Country",
|
||||
"State",
|
||||
"City",
|
||||
"MS",
|
||||
"Region",
|
||||
"Sales Person");
|
||||
|
||||
/**
|
||||
* override find by id with find by search
|
||||
* {@inheritDoc}
|
||||
@ -176,9 +201,9 @@ public class CustomerServiceSupport
|
||||
String[] years = null;
|
||||
if (StringUtils.isNotBlank(strYears) &&
|
||||
StringUtils.isNotBlank(strYtdSales)) {
|
||||
years = strYears.split("\\s*,\\s*");
|
||||
years = strYears.split(SPLITTER);
|
||||
|
||||
final String[] sales = strYtdSales.split("\\s*,\\s*");
|
||||
final String[] sales = strYtdSales.split(SPLITTER);
|
||||
ytdSales = new ArrayList<>(years.length);
|
||||
int i = 0;
|
||||
for (final String year : years) {
|
||||
@ -194,16 +219,25 @@ public class CustomerServiceSupport
|
||||
ytdSales : Collections.emptyList());
|
||||
|
||||
// recent 3 issues
|
||||
final List<ViewModel<CustomerIssue>> recentIssues =
|
||||
customerIssueService.listRecent(model.getId(), 3);
|
||||
// final List<ViewModel<CustomerIssue>> recentIssues =
|
||||
// customerIssueService.listRecent(model.getId(), 3);
|
||||
|
||||
if (!recentIssues.isEmpty()) {
|
||||
int i = 0;
|
||||
final Iterator<ViewModel<CustomerIssue>> it = recentIssues.iterator();
|
||||
while (it.hasNext()) {
|
||||
viewModel.setAttr("issue" + (++i), it.next());
|
||||
}
|
||||
final String lastIssue = model.getLastIssue();
|
||||
if (StringUtils.isNotBlank(lastIssue)) {
|
||||
final String[] issueParts = lastIssue.split(SPLITTER);
|
||||
CustomerIssue 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());
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
@ -401,4 +435,88 @@ public class CustomerServiceSupport
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public File exportCSV(final String operator) {
|
||||
// final File file = new File(FileUtils.getTempDirectory(),
|
||||
final File file = new File(FileUtils.getUserDirectory(),
|
||||
DateFormatUtils.format(System.currentTimeMillis(),
|
||||
"yyyy-MM-dd_HHmmss") + ".csv");
|
||||
try (final FileWriter fileWriter = new FileWriter(file);
|
||||
final CSVPrinter printer = EXPORT_FORMAT.print(fileWriter)) {
|
||||
scan(512, new Search(), this::exportList, this::exportCount, c -> {
|
||||
// "ID",
|
||||
// "Name",
|
||||
// "Sales(3 Years)",
|
||||
// "Comment",
|
||||
// "Application",
|
||||
// "Status",
|
||||
// "Year Added",
|
||||
// "Year",
|
||||
// "Country",
|
||||
// "State",
|
||||
// "City",
|
||||
// "MS",
|
||||
// "Region",
|
||||
// "Sales Person");
|
||||
|
||||
try {
|
||||
log.info("Customer [{}].", c);
|
||||
printer.printRecord(c.getId(),
|
||||
c.getName(),
|
||||
c.getYtdSales(),
|
||||
extractIssue(c.getLastIssue()),
|
||||
joinApplicationNames(c.getApplicationNames()),
|
||||
c.getStatusText(),
|
||||
dateFormat(c.getDateAdded(), "yyyy"),
|
||||
c.getYear(),
|
||||
c.getCountryCode(),
|
||||
c.getState(),
|
||||
c.getCity(),
|
||||
c.getMs(),
|
||||
c.getRegion(),
|
||||
c.getSalesperson());
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new IllegalStateException(
|
||||
"Export customer csv data IO exception caused", e);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new IllegalStateException(
|
||||
"Export customer csv data IO exception caused", e);
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
|
||||
List<Customer> exportList(final Search search) {
|
||||
return mapper.listForShow(search, null);
|
||||
}
|
||||
|
||||
int exportCount(final Search search) {
|
||||
return mapper.countForShow(search, null);
|
||||
}
|
||||
private String extractIssue(final String issue) {
|
||||
if (StringUtils.isNotBlank(issue)) {
|
||||
return issue.split(SPLITTER)[1];
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private String joinApplicationNames(final String applicationNames) {
|
||||
if (StringUtils.isNotBlank(applicationNames)) {
|
||||
return StringUtils.join(applicationNames.split(SPLITTER), ", ");
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private String dateFormat(Date date, String pattern) {
|
||||
return date != null ? DateFormatUtils.format(date, pattern) : "";
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.pudonghot.ambition.crm.service;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -14,6 +15,7 @@ import com.pudonghot.ambition.crm.AmbitionCRM;
|
||||
* donghuang@wacai.com <br>
|
||||
* Apr 24, 2017 11:33 PM
|
||||
*/
|
||||
@Slf4j
|
||||
@SpringBootTest
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = AmbitionCRM.class)
|
||||
@ -26,4 +28,9 @@ public class CustomerServiceTest {
|
||||
customerService.importCSV("58c8106bec4970f89059edb3",
|
||||
CustomerServiceTest.class.getResourceAsStream("/data/customers.csv"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExportCSV() {
|
||||
log.info("Result [{}].", customerService.exportCSV("donghuang"));
|
||||
}
|
||||
}
|
||||
|
@ -153,14 +153,14 @@
|
||||
and enabled = 1) year,
|
||||
|
||||
<!-- all years list -->
|
||||
(select group_concat(year order by year asc separator ',')
|
||||
(select group_concat(year order by year asc separator 0x1d)
|
||||
from crm_customer_year_to_date_sale
|
||||
where customer_id = customer.id
|
||||
and enabled = 1
|
||||
group by customer_id) years,
|
||||
|
||||
<!-- all sales list -->
|
||||
(select group_concat(ytd_sale order by year asc separator ',')
|
||||
(select group_concat(ytd_sale order by year asc separator 0x1d)
|
||||
from crm_customer_year_to_date_sale
|
||||
where customer_id = customer.id
|
||||
and enabled = 1
|
||||
@ -180,7 +180,7 @@
|
||||
and enabled = 1) count_ytd_sales,
|
||||
|
||||
<!-- application ids -->
|
||||
(select group_concat(p.id order by p.name separator ',')
|
||||
(select group_concat(p.id order by p.name separator 0x1d)
|
||||
from crm_customer_application a
|
||||
join crm_application p
|
||||
on a.application_id = p.id
|
||||
@ -188,12 +188,27 @@
|
||||
group by a.customer_id) applications,
|
||||
|
||||
<!-- applications names -->
|
||||
(select group_concat(p.name order by p.name separator ',')
|
||||
(select group_concat(p.name order by p.name separator 0x1d)
|
||||
from crm_customer_application a
|
||||
join crm_application p
|
||||
on a.application_id = p.id
|
||||
where a.customer_id = customer.id
|
||||
group by a.customer_id) application_names
|
||||
group by a.customer_id) application_names,
|
||||
|
||||
<!-- last issue -->
|
||||
(select concat(a.id, 0x1d,
|
||||
a.issue, 0x1d,
|
||||
unix_timestamp(ifnull(a.date_updated, a.date_created)) * 1000)
|
||||
from crm_customer_issue a
|
||||
left join crm_customer_issue b
|
||||
on a.customer_id = b.customer_id
|
||||
and ifnull(a.date_updated, a.date_created)
|
||||
<![CDATA[<]]>
|
||||
ifnull(b.date_updated, b.date_created)
|
||||
where a.customer_id = customer.id
|
||||
and a.enabled = 1
|
||||
and b.id is null
|
||||
) last_issue
|
||||
|
||||
from <include refid="table" /> customer
|
||||
</sql>
|
||||
|
@ -58,5 +58,9 @@ public class Customer extends M3<String, String> {
|
||||
@Transient
|
||||
private String applications;
|
||||
@Transient
|
||||
private String applicationNames;
|
||||
@Transient
|
||||
private boolean artificialIssue;
|
||||
@Transient
|
||||
private String lastIssue;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { helper } from '@ember/component/helper';
|
||||
|
||||
export function strSplit([str, sep]) {
|
||||
return str ? str.split(sep || ',') : [];
|
||||
return str ? str.split(sep || String.fromCharCode(0x1d)) : [];
|
||||
}
|
||||
|
||||
export default helper(strSplit);
|
||||
|
@ -18,7 +18,15 @@
|
||||
<hr />
|
||||
{{#with (customer-application-images model.images model.imageTitles) as |images|}}
|
||||
{{#each images as |image index|}}
|
||||
{{image-previews cover-title=true image-height=192 image-style='border-radius: 2%; border: 1px solid #DCDCDC; max-width: 480px;' previews=images index=index}}
|
||||
<div class="row">
|
||||
<div class="col-xs-12 center">
|
||||
{{#if image.title}}
|
||||
<h5 class="grey">{{image.title}}</h5>
|
||||
{{/if}}
|
||||
{{image-previews image-height=192 image-style='border-radius: 2%; border: 1px solid #DCDCDC; max-width: 480px;' previews=images index=index}}
|
||||
<div class="space-6"></div>
|
||||
</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
{{/with}}
|
||||
</div>
|
||||
|
Loading…
x
Reference in New Issue
Block a user