| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269 |
- import { Component, EventEmitter, Input, Output } from '@angular/core';
- import { CommonModule, DatePipe } from '@angular/common';
- // NG-ZORRO 组件
- import { NzModalModule } from 'ng-zorro-antd/modal';
- import { NzDescriptionsModule } from 'ng-zorro-antd/descriptions';
- import { NzCardModule } from 'ng-zorro-antd/card';
- import { NzTagModule } from 'ng-zorro-antd/tag';
- import { NzSwitchModule } from 'ng-zorro-antd/switch';
- import { NzCollapseModule } from 'ng-zorro-antd/collapse';
- // 类型
- import { IMessageActivity, FilterCondition } from '../services/message.service';
- import { FormsModule } from '@angular/forms';
- @Component({
- selector: 'app-activity-detail',
- standalone: true,
- imports: [
- CommonModule,
- NzModalModule,
- FormsModule,
- NzDescriptionsModule,
- NzCardModule,
- NzTagModule,
- NzSwitchModule,
- NzCollapseModule,
- DatePipe,
- ],
- template: `
- <nz-modal
- [(nzVisible)]="isVisible"
- [nzTitle]="'活动详情 - ' + (activity?.name || '')"
- [nzFooter]="null"
- (nzOnCancel)="onCancel.emit()"
- [nzWidth]="800"
- >
- <ng-container *nzModalContent>
- <nz-descriptions nzBordered [nzColumn]="1">
- <nz-descriptions-item nzTitle="活动名称">{{
- activity?.name
- }}</nz-descriptions-item>
- <nz-descriptions-item nzTitle="关联模板">{{
- getTemplateName(activity?.templateId)
- }}</nz-descriptions-item>
- <nz-descriptions-item nzTitle="推送策略">
- <nz-tag [nzColor]="getStrategyColor(activity?.strategy || 0)">
- {{ getStrategyName(activity?.strategy || 0) }}
- </nz-tag>
- </nz-descriptions-item>
- <nz-descriptions-item nzTitle="计划时间">{{
- activity?.scheduleAt | date : 'yyyy-MM-dd HH:mm:ss'
- }}</nz-descriptions-item>
- <nz-descriptions-item nzTitle="每日推送">
- <nz-switch
- [ngModel]="activity?.everyday"
- [nzDisabled]="true"
- ></nz-switch>
- </nz-descriptions-item>
- <nz-descriptions-item nzTitle="状态">
- <nz-tag [nzColor]="getStatusColor(activity?.status || 0)">
- {{ getStatusName(activity?.status || 0) }}
- </nz-tag>
- </nz-descriptions-item>
- <nz-descriptions-item nzTitle="创建时间">{{
- activity?.createdAt | date : 'yyyy-MM-dd HH:mm:ss'
- }}</nz-descriptions-item>
- <nz-descriptions-item nzTitle="更新时间">{{
- activity?.updatedAt | date : 'yyyy-MM-dd HH:mm:ss'
- }}</nz-descriptions-item>
- </nz-descriptions>
- <nz-card nzTitle="其他信息" style="margin-top: 16px;">
- <nz-descriptions nzBordered [nzColumn]="2">
- <nz-descriptions-item nzTitle="通知图片">
- <img
- [src]="activity?.image"
- style="max-width: 100px; max-height: 100px"
- onerror="this.style.display='none'"
- />
- </nz-descriptions-item>
- <nz-descriptions-item nzTitle="允许展开">
- <nz-switch
- [ngModel]="activity?.bigger"
- [nzDisabled]="true"
- ></nz-switch>
- </nz-descriptions-item>
- <nz-descriptions-item nzTitle="客户端行为">{{
- activity?.action || '无'
- }}</nz-descriptions-item>
- <nz-descriptions-item nzTitle="参数">{{
- activity?.param || '无'
- }}</nz-descriptions-item>
- <nz-descriptions-item nzTitle="扩展参数">{{
- activity?.extend || '无'
- }}</nz-descriptions-item>
- </nz-descriptions>
- <!-- 目标用户筛选条件展示 -->
- <nz-collapse style="margin-top: 16px;">
- <nz-collapse-panel nzHeader="目标用户筛选条件">
- @if (activity && activity.filter && activity.filter.length > 0) {
- <div class="filter-conditions">
- @for (condition of activity.filter; track $index) {
- <div class="filter-condition">
- <div class="condition-field">
- {{ getFieldLabel(condition.field) }}
- </div>
- <div class="condition-operator">
- {{ getOperatorLabel(condition.operator) }}
- </div>
- <div class="condition-value">
- {{ formatConditionValue(condition) }}
- </div>
- </div>
- }
- </div>
- } @else {
- <div>无筛选条件</div>
- }
- </nz-collapse-panel>
- </nz-collapse>
- <nz-descriptions nzBordered [nzColumn]="1">
- <nz-descriptions-item nzTitle="活动描述">{{
- activity?.description
- }}</nz-descriptions-item>
- </nz-descriptions>
- </nz-card>
- </ng-container>
- </nz-modal>
- `,
- styles: [
- `
- nz-card {
- margin-bottom: 16px;
- }
- .filter-conditions {
- display: flex;
- flex-direction: column;
- gap: 8px;
- }
- .filter-condition {
- display: flex;
- align-items: center;
- gap: 8px;
- padding: 8px;
- background: #f5f5f5;
- border-radius: 4px;
- }
- .condition-field {
- font-weight: 500;
- min-width: 100px;
- }
- .condition-operator {
- color: #666;
- min-width: 80px;
- }
- .condition-value {
- flex: 1;
- }
- `,
- ],
- })
- export class ActivityDetailComponent {
- @Input() activity: IMessageActivity | null = null;
- @Input() isVisible = false;
- @Input() templates: { _id: string; templateName: string }[] = [];
- @Output() onCancel = new EventEmitter<void>();
- getTemplateName(templateId: string | undefined): string {
- if (!templateId) return '-';
- const template = this.templates.find((t) => t._id === templateId);
- return template ? template.templateName : '-';
- }
- getStrategyName(strategy: number): string {
- const strategies = {
- 0: '自定义策略',
- 1: '活跃用户推送',
- 2: '新用户推送',
- 3: '沉默用户唤醒',
- };
- return strategies[strategy as keyof typeof strategies] || '未知策略';
- }
- getStrategyColor(strategy: number): string {
- const colors = {
- 0: 'blue',
- 1: 'green',
- 2: 'orange',
- 3: 'purple',
- };
- return colors[strategy as keyof typeof colors] || 'default';
- }
- getStatusName(status: number): string {
- const statuses = {
- 0: '未发布',
- 1: '已发布',
- 2: '已完成',
- };
- return statuses[status as keyof typeof statuses] || '未知状态';
- }
- getStatusColor(status: number): string {
- const colors = {
- 0: 'default',
- 1: 'processing',
- 2: 'success',
- };
- return colors[status as keyof typeof colors] || 'default';
- }
- /**
- * 获取字段的显示标签
- */
- getFieldLabel(field: string): string {
- const fieldLabels: { [key: string]: string } = {
- cc: '国家',
- firstLoginAt: '首次登录时间',
- lastActiveAt: '最后活跃时间',
- // 可以添加更多字段映射
- };
- return fieldLabels[field] || field;
- }
- /**
- * 获取运算符的显示标签
- */
- getOperatorLabel(operator: string): string {
- const operatorLabels: { [key: string]: string } = {
- $in: '包含',
- $nin: '不包含',
- $gt: '大于',
- $lt: '小于',
- $gte: '大于等于',
- $lte: '小于等于',
- };
- return operatorLabels[operator] || operator;
- }
- /**
- * 格式化条件值的显示
- */
- formatConditionValue(condition: FilterCondition): string {
- if (condition.field === 'cc' && Array.isArray(condition.value)) {
- return condition.value.join(', ');
- }
- if (
- condition.field === 'firstLoginAt' ||
- condition.field === 'lastActiveAt'
- ) {
- if (condition.operator === '$in' && Array.isArray(condition.value)) {
- return `${condition.value[0]} 至 ${condition.value[1]} 天前`;
- } else if (typeof condition.value === 'number') {
- return `${condition.value} 天前`;
- }
- }
- return JSON.stringify(condition.value);
- }
- }
|