add batch op

This commit is contained in:
Shaun Chyxion 2021-11-16 01:17:02 +08:00
parent 8a270e4a9d
commit 8533faf904
8 changed files with 272 additions and 20 deletions

View File

@ -1,12 +1,15 @@
package com.pudonghot.yo.cms.controller;
import lombok.val;
import javax.validation.Valid;
import com.wacai.tigon.form.FormList;
import me.chyxion.tigon.mybatis.Search;
import com.pudonghot.yo.model.domain.Queue;
import com.pudonghot.yo.model.domain.Agent;
import com.wacai.tigon.web.controller.ArgQuery;
import com.pudonghot.yo.cms.form.BatchForm;
import com.wacai.tigon.web.annotation.ListApi;
import com.wacai.tigon.web.controller.ArgQuery;
import com.pudonghot.yo.cms.service.AgentService;
import org.springframework.stereotype.Controller;
import com.pudonghot.yo.model.domain.AgentGroup;
import com.wacai.tigon.web.annotation.FilterCol;
@ -18,6 +21,8 @@ import com.pudonghot.yo.cms.annotation.TenantResource;
import com.pudonghot.yo.cms.form.create.CreateFormAgent;
import com.pudonghot.yo.cms.form.update.UpdateFormAgent;
import com.wacai.tigon.web.controller.BaseCrudController;
import org.springframework.web.bind.annotation.PostMapping;
import com.pudonghot.yo.cms.form.create.CreateBatchFormAgent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
@ -72,10 +77,30 @@ public class AgentController
protected void after(final ArgQuery<?> arg) {
super.after(arg);
val model = arg.getResult();
final Integer tenantId = getTenantId();
val tenantId = getTenantId();
model.setAttr("groupsList", agentGroupService.list(
new Search(AgentGroup.TENANT_ID, tenantId)));
model.setAttr("queuesList", queueService.list(
new Search(Queue.TENANT_ID, tenantId)));
}
@PostMapping("/create-batch")
public void createBatch(@Valid CreateBatchFormAgent form) {
((AgentService) queryService).createBatch(form);
}
@PostMapping("/enable-batch")
public void enableBatch(@Valid BatchForm form) {
((AgentService) queryService).enableBatch(form);
}
@PostMapping("/disable-batch")
public void disableBatch(@Valid BatchForm form) {
((AgentService) queryService).disableBatch(form);
}
@PostMapping("/remove-batch")
public void removeBatch(@Valid BatchForm form) {
((AgentService) queryService).removeBatch(form);
}
}

View File

@ -11,7 +11,7 @@ import javax.validation.constraints.NotEmpty;
*/
@Setter
@Getter
public class BatchForm<T> extends BasicForm {
public class BatchForm extends BasicForm {
@NotEmpty
private List<T> ids;
private Integer[] ids;
}

View File

@ -0,0 +1,42 @@
package com.pudonghot.yo.cms.form.create;
import lombok.Getter;
import lombok.Setter;
import com.pudonghot.yo.model.domain.Agent;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.NotBlank;
import com.pudonghot.yo.cms.form.TaggableForm;
import com.wacai.tigon.format.annotation.Trim;
import com.pudonghot.yo.cms.form.BaseCreateForm;
import org.hibernate.validator.constraints.Range;
import com.wacai.tigon.format.annotation.EmptyToNull;
/**
* @author Donghuang <br>
* Nov 02, 2019 12:51:22
*/
@Getter
@Setter
public class CreateBatchFormAgent extends BaseCreateForm implements TaggableForm {
@NotNull
private Integer groupId;
@NotNull
private Agent.Type type;
private Boolean webrtc;
@Trim
@NotBlank
private String accounts;
@Trim
@EmptyToNull
private String password;
@Range(min = 0, max = 240000)
private Integer wrapUpTime;
@NotNull
private Boolean updateExisted;
@NotNull
private Boolean trunkDialAllowed;
@NotNull
private Boolean internalDialAllowed;
private Integer[] queues;
private Integer[] tags;
}

View File

@ -1,5 +1,7 @@
package com.pudonghot.yo.cms.service;
import com.pudonghot.yo.cms.form.BatchForm;
import com.pudonghot.yo.cms.form.create.CreateBatchFormAgent;
import com.pudonghot.yo.cms.form.create.CreateFormAgent;
import com.pudonghot.yo.cms.form.update.UpdateFormAgent;
import com.pudonghot.yo.model.domain.Agent;
@ -13,6 +15,14 @@ public interface AgentService
CreateFormAgent,
UpdateFormAgent> {
void createBatch(CreateBatchFormAgent form);
void enableBatch(BatchForm form);
void disableBatch(BatchForm form);
void removeBatch(BatchForm form);
/**
* find agent of domain
* @param domain domain

View File

@ -1,21 +1,22 @@
package com.pudonghot.yo.cms.service.impl;
import lombok.val;
import java.util.Set;
import java.util.*;
import lombok.extern.slf4j.Slf4j;
import java.util.stream.Collectors;
import me.chyxion.tigon.mybatis.Search;
import com.wacai.tigon.model.ViewModel;
import org.springframework.util.Assert;
import com.wacai.tigon.json.JsonService;
import org.apache.commons.lang3.tuple.Pair;
import com.pudonghot.yo.model.domain.Agent;
import com.pudonghot.yo.mapper.AgentMapper;
import com.pudonghot.yo.cms.form.BatchForm;
import org.apache.commons.lang3.StringUtils;
import com.pudonghot.yo.cms.form.SessionForm;
import org.springframework.stereotype.Service;
import com.pudonghot.yo.mapper.AgentGroupMapper;
import com.pudonghot.yo.mapper.QueueAgentMapper;
import com.pudonghot.yo.model.domain.AgentGroup;
import com.pudonghot.yo.model.domain.QueueAgent;
import com.pudonghot.yo.cms.service.AgentService;
import org.apache.commons.lang3.RandomStringUtils;
@ -23,6 +24,7 @@ import com.pudonghot.yo.cms.service.SequenceService;
import com.pudonghot.yo.cms.form.create.CreateFormAgent;
import com.pudonghot.yo.cms.form.update.UpdateFormAgent;
import org.springframework.beans.factory.annotation.Value;
import com.pudonghot.yo.cms.form.create.CreateBatchFormAgent;
import org.springframework.beans.factory.annotation.Autowired;
/**
@ -48,17 +50,126 @@ public class AgentServiceImpl
private AgentGroupMapper agentGroupMapper;
@Autowired
private QueueAgentMapper queueAgentMapper;
@Autowired
private JsonService jsonService;
/**
* {@inheritDoc}
*/
@Override
public void createBatch(final CreateBatchFormAgent form) {
log.info("Batch create agents [{}].", form);
val groupId = form.getGroupId();
val agentGroup = agentGroupMapper.find(groupId);
Assert.state(agentGroup != null,
() -> "No agent group [" + groupId + "] found");
Assert.state(agentGroup != null,
() -> "Agent group [" + agentGroup.getName() + "] is not active");
val validateResult = batchCreateValidate(form);
// create agents
for (val createAgent : validateResult.getLeft()) {
create(createAgent);
}
// update agents
for (val updateAgent : validateResult.getRight()) {
update(updateAgent);
}
}
/**
* {@inheritDoc}
*/
@Override
public void enableBatch(final BatchForm form) {
log.info("Batch enable agents [{}].", form);
for (val id : form.getIds()) {
val agent = find(id);
Assert.state(agent != null, "No agent [" + id + "] found");
agent.setActive(true);
update(agent);
}
}
/**
* {@inheritDoc}
*/
@Override
public void disableBatch(final BatchForm form) {
log.info("Batch disable agents [{}].", form);
for (val id : form.getIds()) {
val agent = find(id);
Assert.state(agent != null, "No agent [" + id + "] found");
agent.setActive(false);
update(agent);
}
}
/**
* {@inheritDoc}
*/
@Override
public void removeBatch(final BatchForm form) {
log.info("Batch remove agents [{}].", form);
delete(new Search(form.getIds()));
}
private Pair<List<CreateFormAgent>, List<UpdateFormAgent>> batchCreateValidate(
final CreateBatchFormAgent form) {
val accounts = form.getAccounts().split("\n");
val agentsCreate = new ArrayList<CreateFormAgent>(accounts.length);
val agentsUpdate = new ArrayList<UpdateFormAgent>(accounts.length);
for (val line : accounts) {
if (StringUtils.isNotBlank(line)) {
log.info("Create agent [{}].", line);
val agentData = line.split("\\s\\+");
Assert.state(agentData.length < 3, () -> "Agent info [" + agentData + "] is not valid");
val name = agentData[0];
val account = agentData.length == 2 ? agentData[1] : agentData[0];
Assert.state(account.matches("^[_a-zA-Z]+[_a-zA-z0-9]+$"),
"Agent [" + line + "] account [" + account + "] is not valid");
val agentExisted = mapper.find(new Search(Agent.ACCOUNT, account));
if (agentExisted != null) {
Assert.state(form.getUpdateExisted(),
() -> "Agent [" + account + "] existed");
val formUpdate = jsonService.convert(form, UpdateFormAgent.class);
formUpdate.setId(agentExisted.getId());
formUpdate.setName(name);
agentsUpdate.add(formUpdate);
continue;
}
val formCreate = jsonService.convert(form, CreateFormAgent.class);
formCreate.setName(name);
formCreate.setAccount(account);
agentsCreate.add(formCreate);
}
}
return Pair.of(agentsCreate, agentsUpdate);
}
/**
* {@inheritDoc}
*/
@Override
public ViewModel<Agent> create(final CreateFormAgent form) {
final ViewModel<Agent> vm = super.create(form);
final Agent agent = vm.getData();
final Integer[] queues = form.getQueues();
val vm = super.create(form);
val agent = vm.getData();
val queues = form.getQueues();
if (queues != null) {
for (final Integer queue : queues) {
for (val queue : queues) {
insertQueueAgent(agent, queue, form);
}
}
@ -70,20 +181,19 @@ public class AgentServiceImpl
*/
@Override
public ViewModel<Agent> update(final UpdateFormAgent form) {
final ViewModel<Agent> vm = super.update(form);
final Agent agent = vm.getData();
val vm = super.update(form);
val agent = vm.getData();
final Integer agentId = agent.getId();
val agentId = agent.getId();
final Set<Integer> queuesExisted = queueAgentMapper.list(
val queuesExisted = queueAgentMapper.list(
new Search(QueueAgent.AGENT_ID, agentId)).stream()
.map(QueueAgent::getQueueId)
.collect(Collectors.toSet());
final Pair<Set<Integer>, Set<Integer>> queuesDiff =
diff(queuesExisted, form.getQueues());
val queuesDiff = diff(queuesExisted, form.getQueues());
for (final Integer queueId : queuesDiff.getLeft()) {
for (val queueId : queuesDiff.getLeft()) {
insertQueueAgent(agent, queueId, form);
}
@ -102,8 +212,8 @@ public class AgentServiceImpl
@Override
protected void validate(final CreateFormAgent form) {
super.validate(form);
final Integer groupId = form.getGroupId();
final AgentGroup agentGroup = agentGroupMapper.find(groupId);
val groupId = form.getGroupId();
val agentGroup = agentGroupMapper.find(groupId);
Assert.state(agentGroup != null, () -> "No agent group [" + groupId + "] found");
Assert.state(agentGroup.getActive(), () -> "Agent group [" + groupId + "] is inactive");
Assert.state(!mapper.exists(

View File

@ -1,6 +1,8 @@
import BaseListRoute from '../base-list';
import batchActions from '../batch-actions';
export default BaseListRoute.extend({
perm: 'PERM_VIEW_AGENT_LIST',
breadcrumbs: [{text: '坐席列表'}],
actions: batchActions
});

View File

@ -0,0 +1,38 @@
export default {
enableBatch() {
const me = this;
const ids = me.get('controller.model.data').filter(i => i.checked).map(i => i.id);
ids.length && me.get('dialog').confirm('确认启用选中项吗?', () => {
me.get('service').ajaxPost('enable-batch', {
ids: ids.join(',')
}).then(() => {
me.refresh();
me.get('message').alert('启用成功');
});
});
},
disableBatch() {
const me = this;
const ids = me.get('controller.model.data').filter(i => i.checked).map(i => i.id);
ids.length && me.get('dialog').confirm('确认禁用选中项吗?', () => {
me.get('service').ajaxPost('disable-batch', {
ids: ids.join(',')
}).then(() => {
me.refresh();
me.get('message').alert('禁用成功');
});
});
},
removeBatch() {
const me = this;
const ids = me.get('controller.model.data').filter(i => i.checked).map(i => i.id);
ids.length && me.get('dialog').confirm('确认删除选中项吗?', () => {
me.get('service').ajaxPost('remove-batch', {
ids: ids.join(',')
}).then(() => {
me.refresh();
me.get('message').alert('删除成功');
});
});
}
}

View File

@ -1,5 +1,18 @@
<div class="widget-box transparent" style="padding-top: 2px; border: 1px solid #ddd;">
{{#grid-header}}
{{#grid-header button=true as |sec|}}
{{#if (and sec.button model.checked)}}
{{#a-btn click=(route-action 'enableBatch') title='启用'}}
<i class="ace-icon fa fa-check bigger-120 green"></i>
{{/a-btn}}
{{#a-btn click=(route-action 'disableBatch') title='禁用'}}
<i class="ace-icon fa fa-ban bigger-120 orange2"></i>
{{/a-btn}}
{{#a-btn click=(route-action 'removeBatch') title='删除'}}
<i class="ace-icon fa fa-trash-o bigger-120 red"></i>
{{/a-btn}}
{{/if}}
{{#if sec.dropdown}}
{{#has-perm 'PERM_VIEW_AGENT_CREATE'}}
<li>
{{#link-to 'agent.create'}}
@ -8,6 +21,7 @@
{{/link-to}}
</li>
{{/has-perm}}
{{/if}}
{{/grid-header}}
<div class="widget-body">
@ -16,6 +30,12 @@
<table class="table table-striped table-bordered table-hover dataTable">
<thead class="thin-border-bottom">
<tr>
{{!#if agentGroupFiltered}}
<th style="width: 32px;">
{{grid-all-checkbox list=model.data
any-checked=(mut model.checked)}}
</th>
{{!/if}}
<th>
名称
</th>
@ -111,6 +131,11 @@
<tbody>
{{#each model.data as |it|}}
<tr>
{{!#if agentGroupFiltered}}
<td>
{{grid-row-checkbox checked=(mut it.checked)}}
</td>
{{!/if}}
<td>
{{it.name}}
</td>