diff --git a/cms/src/main/java/com/pudonghot/yo/cms/controller/CampaignQuotaController.java b/cms/src/main/java/com/pudonghot/yo/cms/controller/CampaignQuotaController.java index 431f17ac..fd138ede 100644 --- a/cms/src/main/java/com/pudonghot/yo/cms/controller/CampaignQuotaController.java +++ b/cms/src/main/java/com/pudonghot/yo/cms/controller/CampaignQuotaController.java @@ -1,9 +1,14 @@ package com.pudonghot.yo.cms.controller; -import com.wacai.tigon.form.FormList; +import lombok.val; +import com.wacai.tigon.model.ViewModel; +import com.wacai.tigon.web.controller.ArgQuery; import org.springframework.stereotype.Controller; import com.pudonghot.yo.model.domain.CampaignQuota; +import com.pudonghot.yo.cms.service.CampaignService; +import com.pudonghot.yo.cms.form.FormListCampaignQuota; import com.wacai.tigon.web.controller.BaseCrudController; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import com.pudonghot.yo.cms.form.create.FormCreateCampaignQuota; import com.pudonghot.yo.cms.form.update.FormUpdateCampaignQuota; @@ -13,11 +18,48 @@ import com.pudonghot.yo.cms.form.update.FormUpdateCampaignQuota; * @date Oct 14, 2021 14:24:45 */ @Controller -@RequestMapping("/campaign-quota") +@RequestMapping("/cms/api/campaign-quota") public class CampaignQuotaController extends BaseCrudController { + + @Autowired + private CampaignService campaignService; + + /** + * {@inheritDoc} + */ + @Override + protected void before(final ArgQuery arg) { + super.before(arg); + + if (arg.getType() == ArgQuery.Type.LIST) { + val form = (FormListCampaignQuota) arg.getArg(); + arg.getSearch() + .eq(CampaignQuota.CAMPAIGN_ID, + form.getCampaignId()); + } + } + + /** + * {@inheritDoc} + */ + @Override + protected void after(final ArgQuery arg) { + super.after(arg); + + val vm = (ViewModel) arg.getResult(); + final Integer campaignId; + if (arg.getType() == ArgQuery.Type.LIST) { + val form = (FormListCampaignQuota) arg.getArg(); + campaignId = form.getCampaignId(); + } + else { + campaignId = ((CampaignQuota) vm.getData()).getCampaignId(); + } + vm.attr("campaign", campaignService.find(campaignId)); + } } \ No newline at end of file diff --git a/cms/src/main/java/com/pudonghot/yo/cms/form/FormListCampaignQuota.java b/cms/src/main/java/com/pudonghot/yo/cms/form/FormListCampaignQuota.java new file mode 100644 index 00000000..8d194f3e --- /dev/null +++ b/cms/src/main/java/com/pudonghot/yo/cms/form/FormListCampaignQuota.java @@ -0,0 +1,15 @@ +package com.pudonghot.yo.cms.form; + +import lombok.Getter; +import lombok.Setter; +import com.wacai.tigon.form.FormList; + +/** + * @author Donghuang + * @date Oct 18, 2021 23:52:22 + */ +@Getter +@Setter +public class FormListCampaignQuota extends FormList { + private Integer campaignId; +} diff --git a/web/cms/app/router.js b/web/cms/app/router.js index 0a14d792..dce120d6 100644 --- a/web/cms/app/router.js +++ b/web/cms/app/router.js @@ -162,6 +162,12 @@ Router.map(function() { this.route('agent-daily-idle-detail', function() { this.route('list'); }); + + this.route('campaign-quota', function() { + this.route('list'); + this.route('create'); + this.route('edit', {path: '/:id/edit'}); + }); }); export default Router; diff --git a/web/cms/app/routes/campaign-quota/create.js b/web/cms/app/routes/campaign-quota/create.js new file mode 100644 index 00000000..20370339 --- /dev/null +++ b/web/cms/app/routes/campaign-quota/create.js @@ -0,0 +1,33 @@ +import BaseRoute from '../base'; +import RSVP from 'rsvp'; + +export default BaseRoute.extend({ + perm: 'PERM_VIEW_CAMPAIGN_QUOTA_CREATE', + queryParams: { + campaignId: { + refreshModel: true + } + }, + model(params) { + const me = this; + return RSVP.hash({ + campaignId: params.campaignId, + campaign: me.get('store').ajaxGet('campaign/find', {id: params.campaignId}), + active: true + }); + }, + afterModel(model) { + const me = this; + me._super(...arguments); + + me.set('breadcrumbs', [{ + route: 'campaign.list', text: '呼叫活动列表' + }, { + route: 'campaign-quota.list', + text: '呼叫活动[' + model.campaign.name + ']配额列表', + queryParams: {campaignId: model.campaign.id} + }, { + text: '创建呼叫活动配额' + }]); + } +}); diff --git a/web/cms/app/routes/campaign-quota/edit.js b/web/cms/app/routes/campaign-quota/edit.js new file mode 100644 index 00000000..d448852c --- /dev/null +++ b/web/cms/app/routes/campaign-quota/edit.js @@ -0,0 +1,12 @@ +import BaseEditRoute from '../base-edit'; + +export default BaseEditRoute.extend({ + perm: 'PERM_VIEW_CAMPAIGN_QUOTA_EDIT', + afterModel(model) { + this.set('breadcrumbs', + [{route: 'campaign-quota.list', + text: '呼叫活动[' + model.campaign.name + ']配额列表', + queryParams: {campaignId: model.campaign.id}}, + {text: '编辑呼叫活动配额'}]); + } +}); diff --git a/web/cms/app/routes/campaign-quota/list.js b/web/cms/app/routes/campaign-quota/list.js new file mode 100644 index 00000000..4ff54bd5 --- /dev/null +++ b/web/cms/app/routes/campaign-quota/list.js @@ -0,0 +1,20 @@ +import BaseListRoute from '../base-list'; + +export default BaseListRoute.extend({ + perm: 'PERM_VIEW_CAMPAIGN_QUOTA_LIST', + queryParams: { + campaignId: { + refreshModel: true + } + }, + afterModel(model) { + const me = this; + me._super(...arguments); + + me.set('breadcrumbs', [{ + route: 'campaign.list', text: '呼叫活动列表' + }, { + text: '呼叫活动[' + model.campaign.name + ']配额列表' + }]); + } +}); diff --git a/web/cms/app/services/campaign-quota/service.js b/web/cms/app/services/campaign-quota/service.js new file mode 100644 index 00000000..7331e6a5 --- /dev/null +++ b/web/cms/app/services/campaign-quota/service.js @@ -0,0 +1,26 @@ +import Service from '../service'; + +export default Service.extend({ + modelName: 'CampaignQuota', + constraints: { + dailyFrom: { + presence: true, + format: { + pattern: '^([01]?[0-9]|2[0-3]):([0-5]?[0-9])(:[0-5]?[0-9])?$' + } + }, + dailyTo: { + presence: true, + format: { + pattern: '^([01]?[0-9]|2[0-3]):([0-5]?[0-9])(:[0-5]?[0-9])?$' + } + }, + quota: { + presence: true, + numericality: { + onlyInteger: true, + greaterThan: 0 + } + }, + } +}); diff --git a/web/cms/app/templates/campaign-quota/create.hbs b/web/cms/app/templates/campaign-quota/create.hbs new file mode 100644 index 00000000..fe4aacd7 --- /dev/null +++ b/web/cms/app/templates/campaign-quota/create.hbs @@ -0,0 +1,18 @@ +{{#form-content}} +
+ {{form-input type='hidden' name='campaignId'}} + + {{form-input name='dailyFrom' label='开始时间'}} + {{form-input name='dailyTo' label='结束时间'}} + {{form-input name='quota' label='配额'}} + + {{form-input-enabled}} + {{form-input name='note' label='备注'}} + +
+ {{form-footer-buttons type='create' + back-route='campaign-quota.list' + back-route-query-params=(hash campaignId=campaignId) + }} +{{/form-content}} +{{outlet}} diff --git a/web/cms/app/templates/campaign-quota/edit.hbs b/web/cms/app/templates/campaign-quota/edit.hbs new file mode 100644 index 00000000..5c7a1a66 --- /dev/null +++ b/web/cms/app/templates/campaign-quota/edit.hbs @@ -0,0 +1,17 @@ +{{#form-content}} + {{form-input type='hidden' name='id'}} + + {{form-input name='dailyFrom' label='开始时间'}} + {{form-input name='dailyTo' label='结束时间'}} + {{form-input name='quota' label='配额'}} + + {{form-input-enabled}} + {{form-input name='note' label='备注'}} + +
+ {{form-footer-buttons type='update' + back-route='campaign-quota.list' + back-route-query-params=(hash campaignId=model.campaignId) + }} +{{/form-content}} +{{outlet}} diff --git a/web/cms/app/templates/campaign-quota/list.hbs b/web/cms/app/templates/campaign-quota/list.hbs new file mode 100644 index 00000000..1ee64bca --- /dev/null +++ b/web/cms/app/templates/campaign-quota/list.hbs @@ -0,0 +1,86 @@ +
+ {{#grid-header}} + {{#has-perm 'PERM_VIEW_CAMPAIGN_QUOTA_CREATE'}} +
  • + {{#link-to 'campaign-quota.create' (query-params campaignId=campaignId)}} + + 新建呼叫活动配额 + {{/link-to}} +
  • + {{/has-perm}} + {{/grid-header}} + +
    + +
    + + + + + + + + + + + + + {{#each model.data as |it|}} + + + + + + + + + {{/each}} + +
    + 开始时间 + + 结束时间 + + 限额 + + + 备注 + + + {{th-filter name='active' + text='状态' + dialog-title='状态' + options=(array (hash value=true text='启用') + (hash value=false text='禁用')) + }} + + + 管理 +
    + {{it.dailyFrom}} + + {{it.dailyTo}} + + {{it.quota}} + + {{editable-cell model=it field='note'}} + + {{status-cell model=it}} + +
    + {{#has-perm 'PERM_VIEW_CAMPAIGN_QUOTA_EDIT'}} + {{status-toggle-button model=it}} + {{edit-btn route-name='campaign-quota.edit' model-id=it.id perm='PERM_VIEW_CAMPAIGN_QUOTA_EDIT'}} + {{/has-perm}} + {{#has-perm 'PERM_VIEW_CAMPAIGN_QUOTA_DELETE'}} + {{#unless it.active}} + {{delete-button model=it}} + {{/unless}} + {{/has-perm}} +
    +
    +
    + {{pagination-bar}} +
    +
    +{{outlet}} diff --git a/web/cms/app/templates/campaign/list.hbs b/web/cms/app/templates/campaign/list.hbs index e5f82474..0f71e619 100644 --- a/web/cms/app/templates/campaign/list.hbs +++ b/web/cms/app/templates/campaign/list.hbs @@ -22,6 +22,7 @@ Key + {{!-- {{th-filter name='type' text='类型' @@ -34,6 +35,7 @@ options=model.targetTypesList }} + --}} 转接目标 @@ -99,12 +101,14 @@ {{it.campaignKey}} + {{!-- {{it.type}} {{it.targetType}} + --}} {{option-text model.queuesList it.targetId 'id' 'name'}} @@ -152,6 +156,15 @@ {{/link-to}} {{/has-perm}} + {{#has-perm 'PERM_VIEW_CAMPAIGN_QUOTA_LIST'}} + {{#link-to 'campaign-quota.list' + (query-params campaignId=it.id) + class='btn btn-xs btn-info2' + data-rel='tooltip' + title='呼叫活动配额管理'}} + + {{/link-to}} + {{/has-perm}} {{#has-perm 'PERM_VIEW_CAMPAIGN_EDIT'}} {{status-toggle-button model=it}} {{edit-btn route-name='campaign.edit' model-id=it.id perm='PERM_VIEW_CAMPAIGN_EDIT'}} diff --git a/web/cms/tests/unit/routes/campaign-quota/create-test.js b/web/cms/tests/unit/routes/campaign-quota/create-test.js new file mode 100644 index 00000000..53c1f55e --- /dev/null +++ b/web/cms/tests/unit/routes/campaign-quota/create-test.js @@ -0,0 +1,11 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | Route | campaign-quota/create', function(hooks) { + setupTest(hooks); + + test('it exists', function(assert) { + let route = this.owner.lookup('route:campaign-quota/create'); + assert.ok(route); + }); +}); diff --git a/web/cms/tests/unit/routes/campaign-quota/edit-test.js b/web/cms/tests/unit/routes/campaign-quota/edit-test.js new file mode 100644 index 00000000..afb60a93 --- /dev/null +++ b/web/cms/tests/unit/routes/campaign-quota/edit-test.js @@ -0,0 +1,11 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | Route | campaign-quota/edit', function(hooks) { + setupTest(hooks); + + test('it exists', function(assert) { + let route = this.owner.lookup('route:campaign-quota/edit'); + assert.ok(route); + }); +}); diff --git a/web/cms/tests/unit/routes/campaign-quota/list-test.js b/web/cms/tests/unit/routes/campaign-quota/list-test.js new file mode 100644 index 00000000..ecd9b951 --- /dev/null +++ b/web/cms/tests/unit/routes/campaign-quota/list-test.js @@ -0,0 +1,11 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | Route | campaign-quota/list', function(hooks) { + setupTest(hooks); + + test('it exists', function(assert) { + let route = this.owner.lookup('route:campaign-quota/list'); + assert.ok(route); + }); +}); diff --git a/web/cms/tests/unit/services/campaign-quota/service-test.js b/web/cms/tests/unit/services/campaign-quota/service-test.js new file mode 100644 index 00000000..0a1f771c --- /dev/null +++ b/web/cms/tests/unit/services/campaign-quota/service-test.js @@ -0,0 +1,12 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | Service | campaign-quota/service', function(hooks) { + setupTest(hooks); + + // Replace this with your real tests. + test('it exists', function(assert) { + let service = this.owner.lookup('service:campaign-quota/service'); + assert.ok(service); + }); +});