add PERM_VIEW_AGENT_DAILY_IDLE_DETAIL_LIST

This commit is contained in:
Shaun Chyxion 2021-09-06 00:36:08 +08:00
parent c5c74ec86a
commit 1e102b6bad
10 changed files with 263 additions and 8 deletions

View File

@ -1,19 +1,57 @@
package com.pudonghot.yo.cms.controller; 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.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.pudonghot.yo.model.domain.AgentDailyIdleDetail;
import com.wacai.tigon.web.controller.BaseQueryController; import com.wacai.tigon.web.controller.BaseQueryController;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import com.pudonghot.yo.cms.form.AgentDailyIdleDetailListCtrlrReq;
/** /**
* @author Donghuang * @author Donghuang
* @date Sep 01, 2021 17:39:45 * @date Sep 01, 2021 17:39:45
*/ */
@Controller @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 public class AgentDailyIdleDetailController
extends BaseQueryController<Integer, extends BaseQueryController<Integer,
AgentDailyIdleDetail, 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);
}
}
}
} }

View File

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

View File

@ -1,8 +1,10 @@
package com.wacai.tigon.web.converter; package com.wacai.tigon.web.converter;
import java.util.Date; import java.util.Date;
import java.text.ParseException;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.converter.Converter;
/** /**
@ -20,6 +22,12 @@ public class StringToDateTypeConverter
@Override @Override
public Date convert(final String text) { public Date convert(final String text) {
log.debug("Convert [{}] to date.", text); log.debug("Convert [{}] to date.", text);
if (StringUtils.isBlank(text)) {
return null;
}
if (StringUtils.isNumeric(text)) {
try { try {
return StringUtils.isNotBlank(text) ? return StringUtils.isNotBlank(text) ?
new Date(Long.parseLong(text.trim())) : null; new Date(Long.parseLong(text.trim())) : null;
@ -29,4 +37,13 @@ public class StringToDateTypeConverter
"Invalid date [" + text + "]", e); "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);
}
}
} }

View File

@ -80,6 +80,12 @@ export default (function() {
route: 'agent-status.list', route: 'agent-status.list',
icon: 'fa-comments', icon: 'fa-comments',
text: '坐席状态管理' text: '坐席状态管理'
},
{
perm: 'PERM_VIEW_AGENT_DAILY_IDLE_DETAIL_LIST',
route: 'agent-daily-idle-detail.list',
icon: 'fa-ship',
text: '坐席日空闲管理'
} }
] ]
}, { }, {

View File

@ -158,6 +158,10 @@ Router.map(function() {
this.route('call-satisfaction', function() { this.route('call-satisfaction', function() {
this.route('list'); this.route('list');
}); });
this.route('agent-daily-idle-detail', function() {
this.route('list');
});
}); });
export default Router; export default Router;

View 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);
}
}
}
});

View File

@ -0,0 +1,5 @@
import Service from '../service';
export default Service.extend({
modelName: 'AgentDailyIdleDetail'
});

View 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}}

View File

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

View File

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