增加白名单,黑名单,灰名单

This commit is contained in:
东煌 2020-09-25 00:38:38 +08:00
parent 76ced33bc9
commit 59e7901a0c
68 changed files with 934 additions and 41 deletions

View File

@ -0,0 +1,101 @@
package com.pudonghot.yo.cms.controller;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wacai.tigon.web.JSONView;
import com.wacai.tigon.web.JSONViewConfig;
import com.wacai.tigon.web.JSONViewDataModel;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Controller;
import org.springframework.util.ClassUtils;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.sql.SQLIntegrityConstraintViolationException;
/**
* @author Donghuang
*/
@Slf4j
@Order
@RequiredArgsConstructor(onConstructor_ = {@Autowired})
@org.springframework.web.bind.annotation.ControllerAdvice(annotations = {Controller.class, RestController.class})
public class ControllerAdvice {
private final Environment env;
private final JSONViewConfig jsonViewConfig;
private final ObjectMapper objectMapper;
@ExceptionHandler(SQLIntegrityConstraintViolationException.class)
public ModelAndView handleSQLIntegrityConstraintViolationException(
final SQLIntegrityConstraintViolationException ex) {
log.warn("Exception caused.", ex);
return modelAndView(new JSONViewDataModel(ex)
.setMessage("记录已经存在: " + ex.getMessage())
.setSuccess(false)
.setCode(getCode(ex, 500)));
}
ModelAndView modelAndView(final JSONViewDataModel model) {
return new ModelAndView(new JSONView(objectMapper, model, jsonViewConfig));
}
Object getCode(final Throwable throwable, final Object defaultCode) {
final Object code = getCode(throwable);
return code != null ? code : defaultCode;
}
Object getCode(final Throwable throwable) {
final String exName = throwable.getClass().getName();
// get code from env
final String strCode = env.getProperty(exName + ".code");
if (StringUtils.isNotBlank(strCode)) {
log.debug("Exception [{}] code [{}] got.", exName, strCode);
if ("int".equals(jsonViewConfig.getCodeType())) {
return Long.parseLong(strCode);
}
return strCode;
}
// get code from exception method
return getCode(throwable, new String[] {
"getCode",
"getErrCode",
"getErrorCode",
"getErrcode",
"getErrorcode",
});
}
private Object getCode(final Throwable throwable, final String[] methods) {
final Class<? extends Throwable> exClass = throwable.getClass();
for (final String methodName : methods) {
final Method method =
ClassUtils.getMethodIfAvailable(
exClass, methodName);
if (method != null && Modifier.isPublic(method.getModifiers())) {
log.debug("Exception [{}] method [{}] found.", exClass, methodName);
try {
final Object code = method.invoke(throwable);
log.info("Exception [{}] code [{}] got from method [{}].", exClass, code, methodName);
return code;
}
catch (final IllegalAccessException |
InvocationTargetException e) {
log.error("Invoke exception [{}] method [{}] error caused.",
exClass, methodName, e);
}
}
}
return null;
}
}

View File

@ -0,0 +1,54 @@
package com.pudonghot.yo.cms.controller;
import javax.servlet.RequestDispatcher;
import org.springframework.http.HttpStatus;
import com.wacai.tigon.web.JSONViewDataModel;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @author Donghuang
* @date Aug 20, 2020 14:58:47
*/
@Controller
public class ErrorController implements org.springframework.boot.web.servlet.error.ErrorController {
private final static String ERROR_PATH = "/error";
/**
* error mapping
*
* @param request request
* @return error model
*/
@RequestMapping(ERROR_PATH)
public JSONViewDataModel error(final HttpServletRequest request) {
final Object status = request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);
if (status != null) {
final Integer code = Integer.valueOf(status.toString());
final HttpStatus httpStatus = HttpStatus.valueOf(code);
return new JSONViewDataModel(null)
.setMessage(httpStatus.getReasonPhrase())
.setSuccess(false)
.setCode(code);
}
return new JSONViewDataModel(null)
.setMessage(HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase())
.setSuccess(false)
.setCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
}
/**
* {@inheritDoc}
*/
@Override
public String getErrorPath() {
return ERROR_PATH;
}
}

View File

@ -1,20 +1,28 @@
package com.pudonghot.yo.cms.controller;
import com.pudonghot.yo.model.domain.PhoneBlacklist;
import com.pudonghot.yo.cms.annotation.TenantResource;
import com.pudonghot.yo.model.domain.IvrMenu;
import com.wacai.tigon.form.FormList;
import com.wacai.tigon.web.annotation.FilterCol;
import com.wacai.tigon.web.annotation.ListApi;
import org.springframework.stereotype.Controller;
import com.pudonghot.yo.model.domain.PhoneBlacklist;
import com.wacai.tigon.web.controller.BaseCrudController;
import org.springframework.web.bind.annotation.RequestMapping;
import com.pudonghot.yo.cms.form.create.FormCreatePhoneBlacklist;
import com.pudonghot.yo.cms.form.update.FormUpdatePhoneBlacklist;
import com.wacai.tigon.web.controller.BaseCrudController;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @author Donghuang
* @date Sep 22, 2020 20:06:35
*/
@Controller
@RequestMapping("/phone_blacklist")
@ListApi(searchCols = {
PhoneBlacklist.PHONE,
PhoneBlacklist.NOTE
})
@TenantResource
@RequestMapping("/phone-blacklist")
public class PhoneBlacklistController
extends BaseCrudController<Integer,
PhoneBlacklist,

View File

@ -0,0 +1,31 @@
package com.pudonghot.yo.cms.controller;
import com.wacai.tigon.form.FormList;
import com.wacai.tigon.web.annotation.ListApi;
import org.springframework.stereotype.Controller;
import com.pudonghot.yo.model.domain.PhoneGreylist;
import com.pudonghot.yo.cms.annotation.TenantResource;
import com.wacai.tigon.web.controller.BaseCrudController;
import org.springframework.web.bind.annotation.RequestMapping;
import com.pudonghot.yo.cms.form.create.FormCreatePhoneGreylist;
import com.pudonghot.yo.cms.form.update.FormUpdatePhoneGreylist;
/**
* @author Donghuang
* @date Sep 23, 2020 22:17:01
*/
@Controller
@ListApi(searchCols = {
PhoneGreylist.PHONE,
PhoneGreylist.NOTE
})
@TenantResource
@RequestMapping("/phone-greylist")
public class PhoneGreylistController
extends BaseCrudController<Integer,
PhoneGreylist,
FormList,
FormCreatePhoneGreylist,
FormUpdatePhoneGreylist> {
}

View File

@ -1,20 +1,26 @@
package com.pudonghot.yo.cms.controller;
import com.pudonghot.yo.model.domain.PhoneWhitelist;
import com.wacai.tigon.form.FormList;
import com.wacai.tigon.web.annotation.ListApi;
import org.springframework.stereotype.Controller;
import com.pudonghot.yo.model.domain.PhoneWhitelist;
import com.pudonghot.yo.cms.annotation.TenantResource;
import com.wacai.tigon.web.controller.BaseCrudController;
import org.springframework.web.bind.annotation.RequestMapping;
import com.pudonghot.yo.cms.form.create.FormCreatePhoneWhitelist;
import com.pudonghot.yo.cms.form.update.FormUpdatePhoneWhitelist;
import com.wacai.tigon.web.controller.BaseCrudController;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @author Donghuang
* @date Sep 22, 2020 20:06:30
*/
@Controller
@RequestMapping("/phone_whitelist")
@ListApi(searchCols = {
PhoneWhitelist.PHONE,
PhoneWhitelist.NOTE
})
@TenantResource
@RequestMapping("/phone-whitelist")
public class PhoneWhitelistController
extends BaseCrudController<Integer,
PhoneWhitelist,

View File

@ -0,0 +1,29 @@
package com.pudonghot.yo.cms.form.create;
import lombok.Getter;
import lombok.Setter;
import com.pudonghot.yo.cms.form.BaseCreateForm;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.Date;
/**
* @author Donghuang
* @date Sep 23, 2020 22:17:01
*/
@Getter
@Setter
public class FormCreatePhoneGreylist extends BaseCreateForm {
private static final long serialVersionUID = 1L;
@NotBlank
private String phone;
@NotNull
private Date fromTime;
@NotNull
private Date toTime;
@NotNull
private Integer credit;
}

View File

@ -0,0 +1,23 @@
package com.pudonghot.yo.cms.form.update;
import lombok.Getter;
import lombok.Setter;
import java.util.Date;
import javax.validation.constraints.NotNull;
import com.pudonghot.yo.cms.form.BaseUpdateForm;
/**
* @author Donghuang
* @date Sep 23, 2020 22:17:01
*/
@Getter
@Setter
public class FormUpdatePhoneGreylist extends BaseUpdateForm {
private static final long serialVersionUID = 1L;
@NotNull
private Date fromTime;
@NotNull
private Date toTime;
@NotNull
private Integer credit;
}

View File

@ -0,0 +1,18 @@
package com.pudonghot.yo.cms.service;
import com.pudonghot.yo.model.domain.PhoneGreylist;
import com.pudonghot.yo.cms.form.create.FormCreatePhoneGreylist;
import com.pudonghot.yo.cms.form.update.FormUpdatePhoneGreylist;
import com.wacai.tigon.service.BaseCrudByFormService;
/**
* @author Donghuang
* @date Sep 23, 2020 22:17:01
*/
public interface PhoneGreylistService
extends BaseCrudByFormService<Integer,
PhoneGreylist,
FormCreatePhoneGreylist,
FormUpdatePhoneGreylist> {
}

View File

@ -0,0 +1,24 @@
package com.pudonghot.yo.cms.service.impl;
import org.springframework.stereotype.Service;
import com.pudonghot.yo.model.domain.PhoneGreylist;
import com.pudonghot.yo.mapper.PhoneGreylistMapper;
import com.pudonghot.yo.cms.service.PhoneGreylistService;
import com.pudonghot.yo.cms.form.create.FormCreatePhoneGreylist;
import com.pudonghot.yo.cms.form.update.FormUpdatePhoneGreylist;
import com.wacai.tigon.service.support.BaseCrudByFormServiceSupport;
/**
* @author Donghuang
* @date Sep 23, 2020 22:17:01
*/
@Service
public class PhoneGreylistServiceImpl
extends BaseCrudByFormServiceSupport<Integer,
PhoneGreylist,
FormCreatePhoneGreylist,
FormUpdatePhoneGreylist,
PhoneGreylistMapper>
implements PhoneGreylistService {
}

View File

@ -56,6 +56,10 @@ tigon.codegen.service-impl.base-package=com.pudonghot.yo.cms.service.impl
tigon.codegen.controller.project-dir=cms
tigon.codegen.controller.base-package=com.pudonghot.yo.cms.controller
# Controller
tigon.codegen.view.project-dir=web/cms
# tigon.codegen.view.base-package=com.pudonghot.yo.cms.controller
# File Doc
tigon.codegen.file-doc.gen=true
tigon.codegen.file-doc.author=Donghuang

View File

@ -0,0 +1,12 @@
package com.pudonghot.yo.mapper;
import com.wacai.tigon.mybatis.BaseMapper;
import com.pudonghot.yo.model.domain.PhoneGreylist;
/**
* @author Donghuang
* @date Sep 23, 2020 22:17:01
*/
public interface PhoneGreylistMapper extends BaseMapper<Integer, PhoneGreylist> {
}

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
* @author Donghuang
* @date Sep 23, 2020 22:17:01
*/
-->
<!DOCTYPE mapper PUBLIC
"-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pudonghot.yo.mapper.PhoneGreylistMapper">
</mapper>

View File

@ -1,5 +1,8 @@
package com.pudonghot.yo.mapper;
import com.pudonghot.yo.model.domain.AgentStatus;
import com.wacai.tigon.mybatis.Search;
import lombok.val;
import org.junit.Test;
import org.junit.runner.RunWith;
import lombok.extern.slf4j.Slf4j;
@ -7,6 +10,8 @@ import org.springframework.test.context.ContextConfiguration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.List;
/**
* @author Donghuang <br>
* Oct 26, 2019 15:31:51
@ -18,6 +23,12 @@ public class AgentStatusMapperTest {
@Autowired
private AgentStatusMapper mapper;
@Test
public void testList() {
val list = mapper.list(new Search().limit(1));
log.info("List {}", list);
}
@Test
public void testLockCleanup() {
final String lockKey = "TEST_LOCK";

View File

@ -0,0 +1,25 @@
package com.pudonghot.yo.mapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import com.wacai.tigon.mybatis.Search;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests;
/**
* @author Donghuang
* @date Sep 23, 2020 22:17:01
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath*:spring/spring-*.xml")
public class PhoneGreylistMapperTest extends AbstractTransactionalJUnit4SpringContextTests {
@Autowired
private PhoneGreylistMapper mapper;
@Test
public void mapperTest() {
mapper.list(new Search().limit(8));
}
}

View File

@ -3,6 +3,7 @@ package com.pudonghot.yo.model.domain;
import lombok.Getter;
import lombok.Setter;
import com.wacai.tigon.mybatis.Table;
import com.wacai.tigon.mybatis.NotUpdate;
import lombok.experimental.FieldNameConstants;
/**
@ -16,5 +17,6 @@ import lombok.experimental.FieldNameConstants;
public class PhoneBlacklist extends TenantDomain {
private static final long serialVersionUID = 1L;
@NotUpdate
private String phone;
}

View File

@ -0,0 +1,26 @@
package com.pudonghot.yo.model.domain;
import lombok.Getter;
import lombok.Setter;
import java.util.Date;
import com.wacai.tigon.mybatis.Table;
import com.wacai.tigon.mybatis.NotUpdate;
import lombok.experimental.FieldNameConstants;
/**
* @author Donghuang
* @date Sep 23, 2020 22:17:01
*/
@Getter
@Setter
@Table("br_phone_greylist")
@FieldNameConstants(prefix = "")
public class PhoneGreylist extends TenantDomain {
private static final long serialVersionUID = 1L;
@NotUpdate
private String phone;
private Date fromTime;
private Date toTime;
private Integer credit;
}

View File

@ -2,8 +2,9 @@ package com.pudonghot.yo.model.domain;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.FieldNameConstants;
import com.wacai.tigon.mybatis.Table;
import com.wacai.tigon.mybatis.NotUpdate;
import lombok.experimental.FieldNameConstants;
/**
* @author Donghuang
@ -16,6 +17,6 @@ import com.wacai.tigon.mybatis.Table;
public class PhoneWhitelist extends TenantDomain {
private static final long serialVersionUID = 1L;
@NotUpdate
private String phone;
}

View File

@ -16,6 +16,8 @@ public enum ErrorCode {
DN_NOT_REGISTERED("001-001", "分机未注册"),
DN_OFFLINE("001-002", "分机已掉线"),
DN_IS_BUSY("001-003", "话机正忙"),
// 客户号码
EXCEED_DIAL("001-004", "拨打超限"),
// 内部咨询
INNER_HELP_OTHER_AGENT_NOT_FOUND("002-001", "求助坐席不存在"),

View File

@ -8,7 +8,6 @@ import ${baseControllerFullName};
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
<#if objDoc?has_content>
${objDoc}
</#if>

View File

@ -2,5 +2,10 @@ import BaseRoute from '../base';
export default BaseRoute.extend({
perm: 'PERM_VIEW_${permName}_CREATE',
breadcrumbs: [{route: '${minusJoinedModelName}.list', text: '${nameCn}列表'}, {text: '创建${nameCn}'}]
breadcrumbs: [{route: '${minusJoinedModelName}.list', text: '${nameCn}列表'}, {text: '创建${nameCn}'}],
model(params) {
return {
active: true
};
}
});

View File

@ -19,7 +19,6 @@
<th>
名称
</th>
<th>
<i class="ace-icon fa fa-sticky-note-o bigger-110"></i>
备注
@ -45,7 +44,6 @@
<td>
{{it.name}}
</td>
<td>
{{editable-cell model=it field='note'}}
</td>

View File

@ -84,6 +84,17 @@ public class CallController implements SessionAbility {
val calledNumber =
PhoneNumberUtils.cleanupMobile(
args.getCalled());
// 黑名单
// 白名单
// 拨打次数
// 灰名单
// 过去21天累计拨打不超过7次
// 当日不超过2次
// 当日未接通为4小时前
val reqAgentDial = new ReqAgentDial();
reqAgentDial.setTenantId(getTenantId());

View File

@ -3,5 +3,5 @@ import Ember from 'ember';
export default Ember.Component.extend({
tagName: 'span',
value: Ember.computed.alias('model'),
format: 'YYYY-MM-DD H:mm:ss'
format: 'YYYY-MM-DD HH:mm:ss'
});

View File

@ -103,6 +103,24 @@ export default (function() {
route: 'call-detail-record.quality-inspection',
icon: 'fa fa-calendar-check-o',
text: '话务质检'
},
{
perm: 'PERM_VIEW_PHONE_WHITELIST_LIST',
route: 'phone-whitelist.list',
icon: 'fa fa-list-ul',
text: '电话呼叫白名单'
},
{
perm: 'PERM_VIEW_PHONE_BLACKLIST_LIST',
route: 'phone-blacklist.list',
icon: 'fa fa-th-list',
text: '电话呼叫黑名单'
},
{
perm: 'PERM_VIEW_PHONE_GREYLIST_LIST',
route: 'phone-greylist.list',
icon: 'fa fa-list-alt',
text: '电话呼叫灰名单'
}
]
}, {

View File

@ -133,6 +133,22 @@ Router.map(function() {
this.route('calling-list', function() {
this.route('summary');
});
this.route('phone-blacklist', function() {
this.route('list');
this.route('create');
this.route('edit', {path: '/:id/edit'});
});
this.route('phone-whitelist', function() {
this.route('list');
this.route('create');
this.route('edit', {path: '/:id/edit'});
});
this.route('phone-greylist', function() {
this.route('list');
this.route('create');
this.route('edit', {path: '/:id/edit'});
});
});
export default Router;

View File

@ -1,4 +1,4 @@
import BaseListRoute from './../base-list';
import BaseListRoute from '../base-list';
export default BaseListRoute.extend({
perm: 'PERM_VIEW_AGENT_GROUP_LIST',

View File

@ -1,4 +1,4 @@
import BaseListRoute from './../base-list';
import BaseListRoute from '../base-list';
export default BaseListRoute.extend({
perm: 'PERM_VIEW_AGENT_STATUS_LIST',

View File

@ -1,4 +1,4 @@
import BaseListRoute from './../base-list';
import BaseListRoute from '../base-list';
export default BaseListRoute.extend({
perm: 'PERM_VIEW_AGENT_LIST',

View File

@ -1,4 +1,4 @@
import BaseListRoute from './../base-list';
import BaseListRoute from '../base-list';
export default BaseListRoute.extend({
perm: 'PERM_VIEW_AREA_CODE_LIST',

View File

@ -1,4 +1,4 @@
import BaseListRoute from './../base-list';
import BaseListRoute from '../base-list';
export default BaseListRoute.extend({
perm: 'PERM_VIEW_AUTH_PERMISSION_LIST',

View File

@ -1,4 +1,4 @@
import BaseListRoute from './../base-list';
import BaseListRoute from '../base-list';
export default BaseListRoute.extend({
perm: 'PERM_VIEW_AUTH_ROLE_LIST',

View File

@ -1,4 +1,4 @@
import BaseListRoute from './../base-list';
import BaseListRoute from '../base-list';
export default BaseListRoute.extend({
perm: 'PERM_VIEW_AUTH_USER_LIST',

View File

@ -1,4 +1,4 @@
import BaseListRoute from './../base-list';
import BaseListRoute from '../base-list';
export default BaseListRoute.extend({
perm: 'PERM_VIEW_CALL_DETAIL_RECORD_LIST',

View File

@ -1,4 +1,4 @@
import BaseListRoute from './../base-list';
import BaseListRoute from '../base-list';
export default BaseListRoute.extend({
perm: 'PERM_VIEW_CALL_DETAIL_RECORD_QUALITY_INSPECTION',

View File

@ -1,4 +1,4 @@
import BaseListRoute from './../base-list';
import BaseListRoute from '../base-list';
import { set } from '@ember/object';
export default BaseListRoute.extend({

View File

@ -1,4 +1,4 @@
import BaseListRoute from './../base-list';
import BaseListRoute from '../base-list';
export default BaseListRoute.extend({
perm: 'PERM_VIEW_GATEWAY_LIST',

View File

@ -1,4 +1,4 @@
import BaseListRoute from './../base-list';
import BaseListRoute from '../base-list';
export default BaseListRoute.extend({
perm: 'PERM_VIEW_IVR_ENTRY_LIST',

View File

@ -1,4 +1,4 @@
import BaseListRoute from './../base-list';
import BaseListRoute from '../base-list';
export default BaseListRoute.extend({
perm: 'PERM_VIEW_IVR_MENU_LIST',

View File

@ -0,0 +1,11 @@
import BaseRoute from '../base';
export default BaseRoute.extend({
perm: 'PERM_VIEW_PHONE_BLACKLIST_CREATE',
breadcrumbs: [{route: 'phone-blacklist.list', text: '黑名单列表'}, {text: '创建黑名单'}],
model(params) {
return {
active: true
};
}
});

View File

@ -0,0 +1,10 @@
import BaseEditRoute from '../base-edit';
export default BaseEditRoute.extend({
perm: 'PERM_VIEW_PHONE_BLACKLIST_EDIT',
afterModel(model) {
this.set('breadcrumbs',
[{route: 'phone-blacklist.list', text: '黑名单列表'},
{text: '编辑黑名单[' + model.phone + ']'}]);
}
});

View File

@ -0,0 +1,6 @@
import BaseListRoute from '../base-list';
export default BaseListRoute.extend({
perm: 'PERM_VIEW_PHONE_BLACKLIST_LIST',
breadcrumbs: [{text: '黑名单列表'}]
});

View File

@ -0,0 +1,17 @@
import BaseRoute from '../base';
export default BaseRoute.extend({
perm: 'PERM_VIEW_PHONE_GREYLIST_CREATE',
breadcrumbs: [{route: 'phone-greylist.list', text: '灰名单列表'}, {text: '创建灰名单'}],
model(params) {
const tomorrow = new Date();
tomorrow.setDate(new Date().getDate() + 1);
return {
active: true,
fromTime: new Date(new Date().toDateString()).getTime(),
toTime: new Date(tomorrow.toDateString()).getTime(),
credit: 3
};
}
});

View File

@ -0,0 +1,10 @@
import BaseEditRoute from '../base-edit';
export default BaseEditRoute.extend({
perm: 'PERM_VIEW_PHONE_GREYLIST_EDIT',
afterModel(model) {
this.set('breadcrumbs',
[{route: 'phone-greylist.list', text: '灰名单列表'},
{text: '编辑灰名单[' + model.phone + ']'}]);
}
});

View File

@ -0,0 +1,6 @@
import BaseListRoute from '../base-list';
export default BaseListRoute.extend({
perm: 'PERM_VIEW_PHONE_GREYLIST_LIST',
breadcrumbs: [{text: '灰名单列表'}]
});

View File

@ -0,0 +1,11 @@
import BaseRoute from '../base';
export default BaseRoute.extend({
perm: 'PERM_VIEW_PHONE_WHITELIST_CREATE',
breadcrumbs: [{route: 'phone-whitelist.list', text: '白名单列表'}, {text: '创建白名单'}],
model(params) {
return {
active: true
};
}
});

View File

@ -0,0 +1,10 @@
import BaseEditRoute from '../base-edit';
export default BaseEditRoute.extend({
perm: 'PERM_VIEW_PHONE_WHITELIST_EDIT',
afterModel(model) {
this.set('breadcrumbs',
[{route: 'phone-whitelist.list', text: '白名单列表'},
{text: '编辑白名单[' + model.phone + ']'}]);
}
});

View File

@ -0,0 +1,6 @@
import BaseListRoute from '../base-list';
export default BaseListRoute.extend({
perm: 'PERM_VIEW_PHONE_WHITELIST_LIST',
breadcrumbs: [{text: '白名单列表'}]
});

View File

@ -1,4 +1,4 @@
import BaseListRoute from './../base-list';
import BaseListRoute from '../base-list';
export default BaseListRoute.extend({
perm: 'PERM_VIEW_QUEUE_LIST',

View File

@ -1,4 +1,4 @@
import BaseListRoute from './../base-list';
import BaseListRoute from '../base-list';
export default BaseListRoute.extend({
perm: 'PERM_VIEW_SEQUENCE_LIST',

View File

@ -1,4 +1,4 @@
import BaseListRoute from './../base-list';
import BaseListRoute from '../base-list';
export default BaseListRoute.extend({
perm: 'PERM_VIEW_SOUND_LIST',

View File

@ -1,4 +1,4 @@
import BaseListRoute from './../base-list';
import BaseListRoute from '../base-list';
export default BaseListRoute.extend({
perm: 'PERM_VIEW_TAG_LIST',

View File

@ -1,4 +1,4 @@
import BaseListRoute from './../base-list';
import BaseListRoute from '../base-list';
export default BaseListRoute.extend({
perm: 'PERM_VIEW_TELECOM_VENDOR_LIST',

View File

@ -1,4 +1,4 @@
import BaseListRoute from './../base-list';
import BaseListRoute from '../base-list';
import { set, get } from '@ember/object';
export default BaseListRoute.extend({

View File

@ -1,4 +1,4 @@
import BaseListRoute from './../base-list';
import BaseListRoute from '../base-list';
export default BaseListRoute.extend({
perm: 'PERM_VIEW_TRUNK_ATTR_LIST',

View File

@ -1,4 +1,4 @@
import BaseListRoute from './../base-list';
import BaseListRoute from '../base-list';
export default BaseListRoute.extend({
perm: 'PERM_VIEW_TRUNK_STRATEGY_LIST',

View File

@ -1,4 +1,4 @@
import BaseListRoute from './../base-list';
import BaseListRoute from '../base-list';
export default BaseListRoute.extend({
perm: 'PERM_VIEW_TRUNK_LIST',

View File

@ -0,0 +1,14 @@
import Service from '../service';
export default Service.extend({
modelName: 'PhoneBlacklist',
constraints: {
phone: {
presence: true,
length: {
minimum: 4,
maximum: 36
}
}
}
});

View File

@ -0,0 +1,23 @@
import Service from '../service';
export default Service.extend({
modelName: 'PhoneGreylist',
constraints: {
phone: {
presence: true,
length: {
minimum: 4,
maximum: 36
}
},
fromTime: {
presence: true
},
toTime: {
presence: true
},
credit: {
presence: true
},
}
});

View File

@ -0,0 +1,14 @@
import Service from '../service';
export default Service.extend({
modelName: 'PhoneWhitelist',
constraints: {
phone: {
presence: true,
length: {
minimum: 4,
maximum: 36
}
}
}
});

View File

@ -0,0 +1,9 @@
{{#form-content}}
<hr />
{{form-input name='phone' label='号码'}}
{{form-input name='note' label='备注'}}
<hr />
{{form-footer-buttons type='create'}}
{{/form-content}}
{{outlet}}

View File

@ -0,0 +1,12 @@
{{#form-content}}
{{form-input type='hidden' name='id'}}
{{form-input name='phone' label='号码' readonly=true}}
{{form-input-enabled}}
{{form-input name='note' label='备注'}}
<hr />
{{form-footer-buttons type='update'}}
{{/form-content}}
{{outlet}}

View File

@ -0,0 +1,74 @@
<div class="widget-box transparent" style="padding-top: 2px; border: 1px solid #ddd;">
{{#grid-header}}
{{#has-perm 'PERM_VIEW_PHONE_BLACKLIST_CREATE'}}
<li>
{{#link-to 'phone-blacklist.create'}}
<i class="ace-icon fa fa-plus-circle bigger-110 green"></i>
新建黑名单
{{/link-to}}
</li>
{{/has-perm}}
{{/grid-header}}
<div class="widget-body">
<!-- #section:custom/scrollbar -->
<div class="widget-main no-padding">
<table class="table table-striped table-bordered table-hover dataTable">
<thead class="thin-border-bottom">
<tr>
<th>
号码
</th>
<th>
<i class="ace-icon fa fa-sticky-note-o bigger-110"></i>
备注
</th>
<th>
<i class="ace-icon fa fa-exchange bigger-110 hidden-480"></i>
{{th-filter name='active'
text='状态'
dialog-title='状态'
options=(array (hash value=true text='启用')
(hash value=false text='禁用'))
}}
</th>
<th>
<i class="ace-icon fa fa-cogs bigger-110 hidden-480"></i>
管理
</th>
</tr>
</thead>
<tbody>
{{#each model.data as |it|}}
<tr>
<td>
{{it.phone}}
</td>
<td>
{{editable-cell model=it field='note'}}
</td>
<td>
{{status-cell model=it}}
</td>
<td>
<div class="btn-group">
{{#has-perm 'PERM_VIEW_PHONE_BLACKLIST_EDIT'}}
{{status-toggle-button model=it}}
{{edit-btn route-name='phone-blacklist.edit' model-id=it.id perm='PERM_VIEW_PHONE_BLACKLIST_EDIT'}}
{{/has-perm}}
{{#has-perm 'PERM_VIEW_PHONE_BLACKLIST_DELETE'}}
{{#unless it.active}}
{{delete-button model=it}}
{{/unless}}
{{/has-perm}}
</div>
</td>
</tr>
{{/each}}
</tbody>
</table>
</div>
{{pagination-bar}}
</div>
</div>
{{outlet}}

View File

@ -0,0 +1,16 @@
{{#form-content}}
<hr />
{{form-input name='phone' label='号码'}}
{{form-input-datetimepicker
name='fromTime'
label='开始时间'}}
{{form-input-datetimepicker
name='toTime'
label='截止时间'}}
{{form-input type='number' min=1 max=8 step=1 name='credit' label='额度'}}
{{form-input name='note' label='备注'}}
<hr />
{{form-footer-buttons type='create'}}
{{/form-content}}
{{outlet}}

View File

@ -0,0 +1,20 @@
{{#form-content}}
{{form-input type='hidden' name='id'}}
{{form-input name='phone' label='号码' readonly=true}}
{{form-input-datetimepicker
name='fromTime'
label='开始时间'}}
{{form-input-datetimepicker
name='toTime'
label='截止时间'}}
{{form-input type='number' min=1 max=8 step=1 name='credit' label='额度'}}
{{form-input-enabled}}
{{form-input name='note' label='备注'}}
<hr />
{{form-footer-buttons type='update'}}
{{/form-content}}
{{outlet}}

View File

@ -0,0 +1,92 @@
<div class="widget-box transparent" style="padding-top: 2px; border: 1px solid #ddd;">
{{#grid-header}}
{{#has-perm 'PERM_VIEW_PHONE_GREYLIST_CREATE'}}
<li>
{{#link-to 'phone-greylist.create'}}
<i class="ace-icon fa fa-plus-circle bigger-110 green"></i>
新建灰名单
{{/link-to}}
</li>
{{/has-perm}}
{{/grid-header}}
<div class="widget-body">
<!-- #section:custom/scrollbar -->
<div class="widget-main no-padding">
<table class="table table-striped table-bordered table-hover dataTable">
<thead class="thin-border-bottom">
<tr>
<th>
号码
</th>
<th>
开始时间
</th>
<th>
结束时间
</th>
<th>
额度
</th>
<th>
<i class="ace-icon fa fa-sticky-note-o bigger-110"></i>
备注
</th>
<th>
<i class="ace-icon fa fa-exchange bigger-110 hidden-480"></i>
{{th-filter name='active'
text='状态'
dialog-title='状态'
options=(array (hash value=true text='启用')
(hash value=false text='禁用'))
}}
</th>
<th>
<i class="ace-icon fa fa-cogs bigger-110 hidden-480"></i>
管理
</th>
</tr>
</thead>
<tbody>
{{#each model.data as |it|}}
<tr>
<td>
{{it.phone}}
</td>
<td>
{{date-cell value=it.fromTime}}
</td>
<td>
{{date-cell value=it.toTime}}
</td>
<td>
{{it.credit}}
</td>
<td>
{{editable-cell model=it field='note'}}
</td>
<td>
{{status-cell model=it}}
</td>
<td>
<div class="btn-group">
{{#has-perm 'PERM_VIEW_PHONE_GREYLIST_EDIT'}}
{{status-toggle-button model=it}}
{{edit-btn route-name='phone-greylist.edit' model-id=it.id perm='PERM_VIEW_PHONE_GREYLIST_EDIT'}}
{{/has-perm}}
{{#has-perm 'PERM_VIEW_PHONE_GREYLIST_DELETE'}}
{{#unless it.active}}
{{delete-button model=it}}
{{/unless}}
{{/has-perm}}
</div>
</td>
</tr>
{{/each}}
</tbody>
</table>
</div>
{{pagination-bar}}
</div>
</div>
{{outlet}}

View File

@ -0,0 +1,9 @@
{{#form-content}}
<hr />
{{form-input name='phone' label='号码'}}
{{form-input name='note' label='备注'}}
<hr />
{{form-footer-buttons type='create'}}
{{/form-content}}
{{outlet}}

View File

@ -0,0 +1,12 @@
{{#form-content}}
{{form-input type='hidden' name='id'}}
{{form-input name='phone' label='号码' readonly=true}}
{{form-input-enabled}}
{{form-input name='note' label='备注'}}
<hr />
{{form-footer-buttons type='update'}}
{{/form-content}}
{{outlet}}

View File

@ -0,0 +1,75 @@
<div class="widget-box transparent" style="padding-top: 2px; border: 1px solid #ddd;">
{{#grid-header}}
{{#has-perm 'PERM_VIEW_PHONE_WHITELIST_CREATE'}}
<li>
{{#link-to 'phone-whitelist.create'}}
<i class="ace-icon fa fa-plus-circle bigger-110 green"></i>
新建白名单
{{/link-to}}
</li>
{{/has-perm}}
{{/grid-header}}
<div class="widget-body">
<!-- #section:custom/scrollbar -->
<div class="widget-main no-padding">
<table class="table table-striped table-bordered table-hover dataTable">
<thead class="thin-border-bottom">
<tr>
<th>
号码
</th>
<th>
<i class="ace-icon fa fa-sticky-note-o bigger-110"></i>
备注
</th>
<th>
<i class="ace-icon fa fa-exchange bigger-110 hidden-480"></i>
{{th-filter name='active'
text='状态'
dialog-title='状态'
options=(array (hash value=true text='启用')
(hash value=false text='禁用'))
}}
</th>
<th>
<i class="ace-icon fa fa-cogs bigger-110 hidden-480"></i>
管理
</th>
</tr>
</thead>
<tbody>
{{#each model.data as |it|}}
<tr>
<td>
{{it.phone}}
</td>
<td>
{{editable-cell model=it field='note'}}
</td>
<td>
{{status-cell model=it}}
</td>
<td>
<div class="btn-group">
{{#has-perm 'PERM_VIEW_PHONE_WHITELIST_EDIT'}}
{{status-toggle-button model=it}}
{{edit-btn route-name='phone-whitelist.edit' model-id=it.id perm='PERM_VIEW_PHONE_WHITELIST_EDIT'}}
{{/has-perm}}
{{#has-perm 'PERM_VIEW_PHONE_WHITELIST_DELETE'}}
{{#unless it.active}}
{{delete-button model=it}}
{{/unless}}
{{/has-perm}}
</div>
</td>
</tr>
{{/each}}
</tbody>
</table>
</div>
{{pagination-bar}}
</div>
</div>
{{outlet}}