add PERM_VIEW_AGENT_DAILY_IDLE_DETAIL_LIST
This commit is contained in:
parent
c5c74ec86a
commit
1e102b6bad
@ -1,19 +1,57 @@
|
||||
package com.pudonghot.yo.cms.controller;
|
||||
|
||||
import com.wacai.tigon.form.FormList;
|
||||
import lombok.val;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import com.wacai.tigon.web.annotation.ListApi;
|
||||
import com.wacai.tigon.web.annotation.OrderCol;
|
||||
import com.wacai.tigon.web.controller.ArgQuery;
|
||||
import com.wacai.tigon.web.annotation.FilterCol;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.apache.commons.lang3.time.DateFormatUtils;
|
||||
import com.pudonghot.yo.cms.annotation.TenantResource;
|
||||
import com.pudonghot.yo.model.domain.AgentDailyIdleDetail;
|
||||
import com.wacai.tigon.web.controller.BaseQueryController;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import com.pudonghot.yo.cms.form.AgentDailyIdleDetailListCtrlrReq;
|
||||
|
||||
/**
|
||||
* @author Donghuang
|
||||
* @date Sep 01, 2021 17:39:45
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/agent-daily-idle-detail")
|
||||
@TenantResource
|
||||
@ListApi(searchCols = {
|
||||
AgentDailyIdleDetail.ACCOUNT
|
||||
},
|
||||
filterCols = {
|
||||
@FilterCol(param = AgentDailyIdleDetail.ACCOUNT, type = String.class),
|
||||
},
|
||||
orderCols = {
|
||||
@OrderCol(AgentDailyIdleDetail.IDLE_START_TIME),
|
||||
@OrderCol(AgentDailyIdleDetail.DURATION)
|
||||
})
|
||||
@RequestMapping("/cms/api/agent-daily-idle-detail")
|
||||
public class AgentDailyIdleDetailController
|
||||
extends BaseQueryController<Integer,
|
||||
AgentDailyIdleDetail,
|
||||
FormList> {
|
||||
AgentDailyIdleDetailListCtrlrReq> {
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void before(final ArgQuery<?> arg) {
|
||||
if (arg.getType() == ArgQuery.Type.LIST) {
|
||||
val req = (AgentDailyIdleDetailListCtrlrReq) arg.getArg();
|
||||
val search = arg.getSearch()
|
||||
.eq(AgentDailyIdleDetail.DATE,
|
||||
DateFormatUtils.format(req.getDate(), "yyyy-MM-dd"));
|
||||
|
||||
// connId only
|
||||
val account = req.getAccount();
|
||||
if (StringUtils.isNotBlank(account)) {
|
||||
search.eq(AgentDailyIdleDetail.ACCOUNT, account);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package com.pudonghot.yo.cms.form;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import java.util.Date;
|
||||
import com.wacai.tigon.form.FormList;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import com.wacai.tigon.format.annotation.Trim;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.wacai.tigon.format.annotation.EmptyToNull;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
/**
|
||||
* @author Donghuang
|
||||
* @date Sep 05, 2021 23:03:01
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class AgentDailyIdleDetailListCtrlrReq extends FormList {
|
||||
@NotNull
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING,
|
||||
pattern = "yyyy-MM-dd",
|
||||
timezone = "Asia/Shanghai")
|
||||
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
|
||||
private Date date;
|
||||
@Trim
|
||||
@EmptyToNull
|
||||
private String account;
|
||||
}
|
@ -1,8 +1,10 @@
|
||||
package com.wacai.tigon.web.converter;
|
||||
|
||||
import java.util.Date;
|
||||
import java.text.ParseException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.time.DateUtils;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
|
||||
/**
|
||||
@ -20,13 +22,28 @@ public class StringToDateTypeConverter
|
||||
@Override
|
||||
public Date convert(final String text) {
|
||||
log.debug("Convert [{}] to date.", text);
|
||||
try {
|
||||
return StringUtils.isNotBlank(text) ?
|
||||
new Date(Long.parseLong(text.trim())) : null;
|
||||
|
||||
if (StringUtils.isBlank(text)) {
|
||||
return null;
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
|
||||
if (StringUtils.isNumeric(text)) {
|
||||
try {
|
||||
return StringUtils.isNotBlank(text) ?
|
||||
new Date(Long.parseLong(text.trim())) : null;
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid date [" + text + "]", e);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
return DateUtils.parseDate(text, "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd");
|
||||
}
|
||||
catch (ParseException e) {
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid date [" + text + "]", e);
|
||||
"Invalid date [" + text + "]", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -80,6 +80,12 @@ export default (function() {
|
||||
route: 'agent-status.list',
|
||||
icon: 'fa-comments',
|
||||
text: '坐席状态管理'
|
||||
},
|
||||
{
|
||||
perm: 'PERM_VIEW_AGENT_DAILY_IDLE_DETAIL_LIST',
|
||||
route: 'agent-daily-idle-detail.list',
|
||||
icon: 'fa-ship',
|
||||
text: '坐席日空闲管理'
|
||||
}
|
||||
]
|
||||
}, {
|
||||
|
@ -158,6 +158,10 @@ Router.map(function() {
|
||||
this.route('call-satisfaction', function() {
|
||||
this.route('list');
|
||||
});
|
||||
|
||||
this.route('agent-daily-idle-detail', function() {
|
||||
this.route('list');
|
||||
});
|
||||
});
|
||||
|
||||
export default Router;
|
||||
|
52
web/cms/app/routes/agent-daily-idle-detail/list.js
Normal file
52
web/cms/app/routes/agent-daily-idle-detail/list.js
Normal file
@ -0,0 +1,52 @@
|
||||
import BaseListRoute from '../base-list';
|
||||
|
||||
export default BaseListRoute.extend({
|
||||
perm: 'PERM_VIEW_AGENT_DAILY_IDLE_DETAIL_LIST',
|
||||
breadcrumbs: [{text: '坐席日空闲列表'}],
|
||||
queryParams: {
|
||||
page: {
|
||||
refreshModel: true
|
||||
},
|
||||
date: {
|
||||
refreshModel: false
|
||||
},
|
||||
account: {
|
||||
refreshModel: false
|
||||
}
|
||||
},
|
||||
model(params) {
|
||||
const me = this;
|
||||
let page = params.page;
|
||||
if (!Number.isInteger(page)) {
|
||||
page = parseInt(page);
|
||||
}
|
||||
if (page < 1) {
|
||||
page = 1;
|
||||
}
|
||||
|
||||
if (!params.date) {
|
||||
params.date = moment(new Date()).format('YYYY-MM-DD');
|
||||
}
|
||||
|
||||
return me.get('service').listPage(page, params);
|
||||
},
|
||||
setupController(controller) {
|
||||
const me = this;
|
||||
me._super(...arguments);
|
||||
|
||||
if (!controller.get('date')) {
|
||||
controller.set('date', moment(new Date()).format('YYYY-MM-DD'));
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
search() {
|
||||
let me = this;
|
||||
if (me.get('controller.page') == 1) {
|
||||
me.refresh();
|
||||
}
|
||||
else {
|
||||
me.set('controller.page', 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
5
web/cms/app/services/agent-daily-idle-detail/service.js
Normal file
5
web/cms/app/services/agent-daily-idle-detail/service.js
Normal file
@ -0,0 +1,5 @@
|
||||
import Service from '../service';
|
||||
|
||||
export default Service.extend({
|
||||
modelName: 'AgentDailyIdleDetail'
|
||||
});
|
81
web/cms/app/templates/agent-daily-idle-detail/list.hbs
Normal file
81
web/cms/app/templates/agent-daily-idle-detail/list.hbs
Normal file
@ -0,0 +1,81 @@
|
||||
<div class="widget-box transparent" style="padding-top: 2px; border: 1px solid #ddd;">
|
||||
<div class="space"></div>
|
||||
<form class="form-horizontal" role="form">
|
||||
<div class="row">
|
||||
{{form-input-datepicker
|
||||
class='col-sm-5 col-md-5'
|
||||
label-class='col-sm-3 col-md-3'
|
||||
input-class='col-sm-9 col-md-9'
|
||||
error-msg=false
|
||||
model=this
|
||||
name='date'
|
||||
label='日期'}}
|
||||
|
||||
{{form-input
|
||||
class='col-sm-5 col-md-5'
|
||||
label-class='col-sm-3 col-md-3'
|
||||
input-class='col-sm-9 col-md-9'
|
||||
error-msg=false
|
||||
model=this
|
||||
name='account'
|
||||
label='坐席账户'}}
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-5 col-md-5">
|
||||
<div class="col-sm-3 col-md-3">
|
||||
</div>
|
||||
<button type="button" class="btn btn-info btn-sm col-sm-4 col-md-4"
|
||||
{{action (route-action 'search')}}>
|
||||
<i class="ace-icon fa fa-search bigger-110"></i>查询
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="space-18"></div>
|
||||
|
||||
<div class="widget-body">
|
||||
<!-- #section:custom/scrollbar -->
|
||||
<div class="widget-main no-padding">
|
||||
<table class="table table-striped table-bordered table-hover dataTable" style="border-top-width: 1px;">
|
||||
<thead class="thin-border-bottom">
|
||||
<tr>
|
||||
<th>
|
||||
日期
|
||||
</th>
|
||||
<th>
|
||||
坐席
|
||||
</th>
|
||||
{{#sortable-th name='idleStartTime'}}
|
||||
开始时间
|
||||
{{/sortable-th}}
|
||||
{{#sortable-th name='duration'}}
|
||||
空闲时长
|
||||
{{/sortable-th}}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{#each model.data as |it|}}
|
||||
<tr>
|
||||
<td>
|
||||
{{date-cell value=it.date format='YYYY-MM-DD'}}
|
||||
</td>
|
||||
<td>
|
||||
{{it.account}}
|
||||
</td>
|
||||
<td>
|
||||
{{date-cell value=it.idleStartTime}}
|
||||
</td>
|
||||
<td>
|
||||
{{readable-duration it.duration}}
|
||||
</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{pagination-bar}}
|
||||
</div>
|
||||
</div>
|
||||
{{outlet}}
|
@ -0,0 +1,11 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
module('Unit | Route | agent-daily-idle-detail/list', function(hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
test('it exists', function(assert) {
|
||||
let route = this.owner.lookup('route:agent-daily-idle-detail/list');
|
||||
assert.ok(route);
|
||||
});
|
||||
});
|
@ -0,0 +1,12 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
module('Unit | Service | agent-daily-idle-detail/service', function(hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
// Replace this with your real tests.
|
||||
test('it exists', function(assert) {
|
||||
let service = this.owner.lookup('service:agent-daily-idle-detail/service');
|
||||
assert.ok(service);
|
||||
});
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user