liu
3 天以前 fe2d6627b8f1002af7a31b08f6f43bec034d04ee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
import type { PageParam, PageResult } from '@vben/request';
 
import { requestClient } from '#/api/request';
 
/** 活动模板类型 */
export const ACTIVITY_TYPE = {
  /** 纯通知:只推一条文本,无表单 */
  TEXT: 1,
  /** 单条消息:推一张可点击卡片 */
  MESSAGE: 2,
  /** 图片通知:上传图片后推送图片消息 */
  IMAGE: 3,
  /** 附件通知:上传文件后推送文件消息 */
  FILE: 4,
  /** 数据采集/评价:报名页 + 自定义字段 + 评价 */
  FORM: 5,
} as const;
 
export namespace WxCpActivityApi {
  /** 活动状态:0草稿 1已发布 2已结束 3已取消 */
  export const ACTIVITY_STATUS = {
    DRAFT: 0,
    PUBLISHED: 1,
    FINISHED: 2,
    CANCELED: 3,
  } as const;
 
  /** 推送范围:0全员 1指定部门 2指定成员 */
  export const PUSH_SCOPE = {
    ALL: 0,
    PARTY: 1,
    USER: 2,
  } as const;
 
  /** 采集字段 */
  export interface Field {
    id?: number;
    fieldLabel?: string;
    /** text / textarea / number / date / select / radio / checkbox / rating */
    fieldType?: string;
    /** 多个选项用英文逗号分隔 */
    fieldOptions?: string;
    required?: boolean;
    placeholder?: string;
    sortNo?: number;
  }
 
  /** 活动 */
  export interface Activity {
    id?: number;
    title?: string;
    /** 模板类型,见 ACTIVITY_TYPE */
    activityType?: number;
    activityTypeName?: string;
    content?: string;
    /** 卡片按钮文案 */
    buttonText?: string;
    /** 是否开启评价(数据采集模板) */
    ratingEnabled?: boolean;
    ratingTitle?: string;
    ratingMax?: number;
    /** 图片通知的图片 blobId */
    imageBlobIds?: number[];
    imageAttachmentList?: SignupAttachment[];
    /** 附件通知的附件 blobId */
    fileBlobIds?: number[];
    fileAttachmentList?: SignupAttachment[];
    /** 数据采集模板的自定义字段 */
    fieldList?: Field[];
    /**
     * 封面图文件编号(最多 1 张)
     *
     * 封面不落业务表字段,统一走 system_storage_attachment 中间表,
     * 保存时提交 blobIds,回显时读 attachmentList。
     */
    blobIds?: number[];
    /** 封面图附件列表(后端返回,最多 1 张) */
    attachmentList?: SignupAttachment[];
    /**
     * 详情图片文件编号(最多 5 张)
     *
     * 与封面同样走附件中间表,但 recordType 是 wxcp_activity_detail。
     * 报名页在「活动详情」文字下方按原图比例完整展示(不裁剪),
     * 二维码/海报这类被裁就失效的图要放这里,不要放封面。
     */
    detailBlobIds?: number[];
    /** 详情图片附件列表(后端返回,最多 5 张) */
    detailAttachmentList?: SignupAttachment[];
    location?: string;
    startTime?: string;
    endTime?: string;
    signupStartTime?: string;
    signupEndTime?: string;
    /** 报名上限,0 表示不限 */
    signupLimit?: number;
    signupCount?: number;
    status?: number;
    statusName?: string;
    pushScope?: number;
    pushScopeName?: string;
    pushTarget?: string;
    pushStatus?: number;
    pushTime?: string;
    remark?: string;
    createTime?: string;
  }
 
  /** 活动分页查询参数 */
  export interface ActivityPageParams extends PageParam {
    title?: string;
    status?: number;
    pushStatus?: number;
    startTime?: [string, string];
  }
 
  /** 报名记录 */
  export interface Signup {
    id?: number;
    activityId?: number;
    activityTitle?: string;
    wxUserId?: string;
    name?: string;
    mobile?: string;
    deptName?: string;
    content?: string;
    /** 评价星级 */
    ratingScore?: number;
    /** 自定义采集字段值 */
    fieldValues?: { fieldId?: number; fieldLabel?: string; fieldType?: string; fieldValue?: string }[];
    /** 状态:0已报名 1已取消 2已签到 */
    status?: number;
    statusName?: string;
    signupTime?: string;
    checkInTime?: string;
    remark?: string;
    createTime?: string;
  }
 
  /** 报名记录分页查询参数 */
  export interface SignupPageParams extends PageParam {
    activityId?: number;
    name?: string;
    mobile?: string;
    status?: number;
  }
 
  /** 名称-数量统计项 */
  export interface NameCount {
    name: string;
    count: number;
  }
 
  /** 报名统计 */
  export interface ActivityStats {
    activityId: number;
    activityTitle?: string;
    signupLimit?: number;
    totalSignup: number;
    signedUpCount: number;
    checkedInCount: number;
    canceledCount: number;
    /** 不限名额时为 null */
    remaining?: null | number;
    signupPercent?: null | number;
    checkInPercent: number;
    deptStats: NameCount[];
    dateStats: NameCount[];
    sourceStats: NameCount[];
  }
 
  /** 推送请求 */
  export interface PushParams {
    id: number;
    pushScope?: number;
    pushTarget?: string;
  }
 
  /** 推送结果 */
  export interface PushResult {
    success: boolean;
    errCode?: null | number;
    message?: string;
    toUser?: string;
    toParty?: string;
  }
 
  /** 报名附件 */
  export interface SignupAttachment {
    id: number;
    name?: string;
    originalFilename?: string;
    contentType?: string;
    byteSize?: number;
    url?: string;
    previewURL?: string;
    downloadURL?: string;
  }
}
 
/** 获得活动分页 */
export function getActivityPage(params: WxCpActivityApi.ActivityPageParams) {
  return requestClient.get<PageResult<WxCpActivityApi.Activity>>(
    '/wxcp/activity/page',
    { params },
  );
}
 
/** 获得活动详情 */
export function getActivity(id: number) {
  return requestClient.get<WxCpActivityApi.Activity>(
    '/wxcp/activity/get',
    { params: { id } },
  );
}
 
/** 创建活动(存为草稿) */
export function createActivity(data: WxCpActivityApi.Activity) {
  return requestClient.post<number>('/wxcp/activity/create', data);
}
 
/** 修改活动 */
export function updateActivity(data: WxCpActivityApi.Activity) {
  return requestClient.put<boolean>('/wxcp/activity/update', data);
}
 
/** 删除活动 */
export function deleteActivity(id: number) {
  return requestClient.delete<boolean>('/wxcp/activity/delete', {
    params: { id },
  });
}
 
/** 发布活动 */
export function publishActivity(id: number) {
  return requestClient.put<boolean>('/wxcp/activity/publish', null, {
    params: { id },
  });
}
 
/** 结束活动 */
export function finishActivity(id: number) {
  return requestClient.put<boolean>('/wxcp/activity/finish', null, {
    params: { id },
  });
}
 
/** 取消活动 */
export function cancelActivity(id: number) {
  return requestClient.put<boolean>('/wxcp/activity/cancel', null, {
    params: { id },
  });
}
 
/** 推送活动给企业微信成员 */
export function pushActivity(data: WxCpActivityApi.PushParams) {
  return requestClient.post<WxCpActivityApi.PushResult>(
    '/wxcp/activity/push',
    data,
  );
}
 
/** 获得活动报名页地址 */
export function getActivitySignupUrl(id: number) {
  return requestClient.get<string>('/wxcp/activity/signup-url', {
    params: { id },
  });
}
 
/**
 * 获得活动报名二维码(PNG Blob)
 *
 * 该接口返回图片二进制,而 <img src> 无法携带请求头,
 * 所以这里用 raw 模式取回 Blob,再由调用方转成 objectURL 显示/下载。
 */
export function getActivityQrCodeBlob(id: number, size?: number) {
  return requestClient.request('/wxcp/activity/qrcode', {
    method: 'GET',
    params: { id, size },
    responseType: 'blob',
    responseReturn: 'raw',
  });
}
 
/** 获得活动报名统计 */
export function getActivityStats(id: number) {
  return requestClient.get<WxCpActivityApi.ActivityStats>(
    '/wxcp/activity/stats',
    { params: { id } },
  );
}
 
/** 获得报名记录分页 */
export function getSignupPage(params: WxCpActivityApi.SignupPageParams) {
  return requestClient.get<PageResult<WxCpActivityApi.Signup>>(
    '/wxcp/activity/signup/page',
    { params },
  );
}
 
/** 取消报名 */
export function cancelSignup(id: number) {
  return requestClient.put<boolean>('/wxcp/activity/signup/cancel', null, {
    params: { id },
  });
}
 
/** 报名签到 */
export function checkInSignup(id: number) {
  return requestClient.put<boolean>('/wxcp/activity/signup/check-in', null, {
    params: { id },
  });
}
 
/** 获得某条报名记录上传的图片/附件 */
export function getSignupAttachments(signupId: number) {
  return requestClient.get<WxCpActivityApi.SignupAttachment[]>(
    '/wxcp/activity/signup/attachments',
    { params: { signupId } },
  );
}