SaveController.class.php
19.5 KB
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
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
<?php
/**
* Created by PhpStorm.
* User: liyifei2012it
* Date: 17/4/11
* Time: 18:33
*/
namespace Apicp\Controller\News;
use Common\Common\ArticleHelper;
use Common\Common\Attach;
use Com\PackageValidate;
use Common\Common\Constant;
use Common\Common\NewsHelper;
use Common\Service\AttachService;
use Common\Service\ClassService;
use Common\Service\ReadService;
use Common\Service\RightService;
use Common\Service\ArticleService;
use Common\Service\TaskService;
use phpDocumentor\Reflection\Types\String_;
use VcySDK\Cron;
use VcySDK\Service;
class SaveController extends \Apicp\Controller\AbstractController
{
/**
* Save
* @author liyifei
* @desc 新闻保存(创建、修改)
* @param Int article_id 新闻ID
* @param String title:true 标题
* @param Int class_id:true 分类ID
* @param String author:true 作者
* @param String content 内容
* @param String cover_id:true 封面图片ID
* @param String is_show_cover:true:2 是否正文显示封面图片(1=不显示,2=显示)
* @param array file_at_ids 文件附件ID数组
* @param array audio_at_ids 音频附件ID数组
* @param array video_at_info 视频附件详情
* @param String video_at_info[].at_id:true 视频附件ID
* @param String video_at_info[].at_name:true 视频名称
* @param String video_at_info[].at_size:true 视频大小(单位:字节)
* @param String video_at_info[].at_time:true 视频时长
* @param array is_download:true:1 附件是否支持下载(1=不支持,2=支持)
* @param String summary:true 摘要(最多输入150字符)
* @param array right:true 阅读范围
* @param Int right.is_all 是否全公司(1=否;2=是)
* @param array right.uids 人员ID
* @param array right.dp_ids 部门ID
* @param array right.tag_ids 标签ID
* @param array right.job_ids 职位ID
* @param array right.role_ids 角色ID
* @param String link 外部链接
* @param Int is_jump 是否直接跳转外链(1=不直接跳转,2=直接跳转)
* @param Int is_secret:true:1 是否保密(1=不保密,2=保密)
* @param Int is_share:true:1 允许分享(1=不允许,2=允许)
* @param Int is_notice:true:2 消息通知(1=不开启,2=开启)
* @param Int is_comment:true:2 评论功能(1=不开启,2=开启)
* @param Int is_like:true:2 点赞功能(1=不开启,2=开启)
* @param Int is_recommend:true:2 首页推荐(1=不开启,2=开启)
* @param Int news_status:true:1 新闻状态(1=草稿与保存并预览,2=已发布)
* @param Int strategy_setting:true:2 积分策略设置(1=启用默认策略;2=不启用策略;3=自定义策略)
* @param array strategys 自定义策略数据
* @param String strategys[].action_key 触发行为key
* @param String strategys[].strategy_id 策略ID
* @param Int credit_strategy_setting:true:2 学分策略设置(1=启用默认策略;2=不启用策略;3=自定义策略)
* @param array credit_strategys 自定义策略数据
* @param String credit_strategys[].action_key 触发行为key
* @param String credit_strategys[].strategy_id 策略ID
* @return array 二维码链接
* array(
* 'qr_code' => 'asdadsdasdad.asdsadasdsa?asdasdds=adasdadad',
* )
*/
public function Index_post()
{
// 验证规则
$rules = [
// 非必填
'article_id' => 'integer',
'summary' => 'max:120',
'audio_at_ids' => 'array',
'file_at_ids' => 'array',
'video_at_info' => 'array',
'link' => 'max:500',
'is_jump' => 'integer|in:1,2',
'strategys' => 'array',
'credit_strategys' => 'array',
'cron_time' => 'max:20',
// 必填
'title' => 'require|max:64',
'class_id' => 'require|integer',
'author' => 'require|max:20',
'cover_id' => 'require',
'right' => 'require|array',
'is_show_cover' => 'require|integer|in:1,2',
'is_download' => 'require|integer|in:1,2',
'is_secret' => 'require|integer|in:1,2',
'is_share' => 'require|integer|in:1,2',
'is_notice' => 'require|integer|in:1,2',
'is_comment' => 'require|integer|in:1,2',
'comment_anonymous' => 'require|integer|in:1,2',
'is_like' => 'require|integer|in:1,2',
'is_recommend' => 'require|integer|in:1,2',
'news_status' => 'require|integer|in:1,2,4',
'strategy_setting' => 'require|integer|in:1,2,3',
'credit_strategy_setting' => 'require|integer|in:1,2,3',
];
// 验证请求数据
$validate = new PackageValidate($rules, [], array_keys($rules));
$postData = $validate->postData;
// 完整请求参数
$postData['content'] = I('post.content', '', 'trim');
$fixData = $this->_fixData($postData);
// 格式化权限数据
$rightServ = new RightService();
$formatRights = $rightServ->formatPostData($postData['right']);
if (empty($formatRights)) {
E('_ERR_ARTICLE_RIGHT_PARAM');
}
// 校验传参(验证器无法验证的部分)
$this->_checkData($fixData);
// 组合写入article表的数据
$sqlData = $this->_fixSqlData($fixData);
// 保存新闻
$articleServ = new ArticleService();
if ($fixData['article_id'] == 0) {
// 创建新闻
$articleId = $articleServ->insert($sqlData);
if (!$articleId) {
E('_ERR_ARTICLE_SAVE_FAILED');
}
// 二维码的链接
$qr_code = oaUrl('Frontend/Index/NewsQrcode/index', ['article_id' => $articleId]);
// RPC推送到运营中心
if ($sqlData['is_recommend'] == Constant::NEWS_IS_RECOMMEND_TRUE) {
$articleServ->addNewsRpc($articleId, $postData['right']);
}
} else {
// 修改前的新闻数据
$articleOld = $articleServ->get($fixData['article_id']);
$articleId = $articleOld['article_id'];
// 如果存在定时发布,删除定时发布
if ($articleOld['news_status'] == Constant::NEWS_STATUS_TIMING_RELEASE) {
// 实例化定时任务类
$cron_serv = new Cron(Service::instance());
$cron_serv->delete($articleOld['release_crid']);
}
// 二维码的链接
$qr_code = oaUrl('Frontend/Index/NewsQrcode/index', ['article_id' => $articleId]);
if (!in_array($fixData['news_status'], [Constant::NEWS_STATUS_DRAFT, Constant::NEWS_STATUS_READY_SEND, Constant::NEWS_STATUS_TIMING_RELEASE])) {
$this->_operationRpc($fixData['article_id'], $sqlData, $postData['right']);
}
// RPC推送到运营中心
// 修改新闻
$articleServ->update_by_conds(['article_id' => $fixData['article_id']], $sqlData);
}
// 定时发布, 增加定时任务
if ($sqlData['news_status'] == Constant::NEWS_STATUS_TIMING_RELEASE) {
$articleServ->cronAdd($articleId, $sqlData['cron_time']);
}
// 推送未读消息(草稿、预发布除外;新建已发布新闻、草稿新闻修改为已发布新闻时,也推送消息;)
$newsHelper = &NewsHelper::instance();
if (!in_array($sqlData['news_status'], [
Constant::NEWS_STATUS_DRAFT,
Constant::NEWS_STATUS_READY_SEND,
Constant::NEWS_STATUS_TIMING_RELEASE
]) && $sqlData['is_notice'] == Constant::NEWS_IS_NOTICE_TRUE) {
// 发布过就不推消息了
if ($fixData['article_id'] == 0 || (isset($articleOld) && $articleOld['news_status'] == Constant::NEWS_STATUS_DRAFT && $sqlData['news_status'] == Constant::NEWS_STATUS_SEND)) {
// 新闻所在顶级分类信息
$classServ = new ClassService();
$class = $classServ->getTopClass($sqlData['class_id']);
$sqlData['class_name'] = $class['class_name'];
$sqlData['article_id'] = $articleId;
$newsHelper->sendNotice($sqlData, $formatRights);
}
}
// 创建计划任务(预发布新闻:视频、文件附件) 添加定时任务
if ($sqlData['news_status'] == Constant::NEWS_STATUS_READY_SEND || $sqlData['news_status'] == Constant::NEWS_STATUS_TIMING_RELEASE) {
$taskServ = new TaskService();
$taskServ->createCheckAttachTask($articleId);
}
// 保存阅读范围
$rightServ->saveData(['article_id' => $articleId], $postData['right']);
// 修改新闻未读人数
list($uids_all, ,) = $newsHelper->getReadData($articleId);
sort($uids_all);
// 兼容多次编辑文章未读人数变化问题
$readServ = new ReadService();
$read_list = $readServ->list_by_conds([
'article_id' => $articleId,
'uid' => $uids_all,
]);
// 如果存在已读取过的人员
if (!empty($read_list)) {
// 获取已读取人员的uids
$read_uids = array_column($read_list, 'uid');
$uids_all = array_diff($uids_all, $read_uids);
}
$articleServ->update($articleId, ['unread_total' => count($uids_all)]);
// 保存附件(已发布、预发布的新闻,不可修改附件)
if ($fixData['article_id'] == 0 || (isset($articleOld) && $articleOld['news_status'] == Constant::NEWS_STATUS_DRAFT)) {
$attachServ = new AttachService();
$attachServ->saveData($articleId, $fixData);
}
$this->_result = ['qr_code' => $qr_code];
}
/**
* 补全请求数据
* @param array $postData 请求数据
* @return array
*/
private function _fixData($postData)
{
// 非必填参数,补全默认值
$postData['article_id'] = isset($postData['article_id']) ? $postData['article_id'] : 0;
$postData['summary'] = isset($postData['summary']) ? $postData['summary'] : '';
$postData['audio_at_ids'] = isset($postData['audio_at_ids']) ? $postData['audio_at_ids'] : '';
$postData['file_at_ids'] = isset($postData['file_at_ids']) ? $postData['file_at_ids'] : [];
$postData['video_at_info'] = isset($postData['video_at_info']) ? $postData['video_at_info'] : [];
$postData['link'] = isset($postData['link']) ? $postData['link'] : '';
$postData['is_jump'] = isset($postData['is_jump']) ? $postData['is_jump'] : Constant::NEWS_IS_JUMP_FALSE;
return $postData;
}
/**
* 校验传参
* @author liyifei
* @param array $fixData 补全后的请求参数
* @return mixed
*/
private function _checkData($fixData)
{
// 为定时发布时,定时发布时间不能为空且大于当前时间
if ($fixData['news_status'] == Constant::NEWS_STATUS_TIMING_RELEASE) {
if (!$fixData['cron_time'] || $fixData['cron_time'] <= MILLI_TIME) {
E('_ERR_CREDIT_CRON_TIME_ERR');
}
}
// 文件最多上传5个
if (isset($fixData['file_at_ids']) && count($fixData['file_at_ids']) > Constant::UPLOAD_FILE_ATTACH_LIMIT) {
E(L('_ERR_ARTICLE_FILE_ATTACH_MORE', ['at_type' => '文件']));
}
// 音频最多上传5个
if (isset($fixData['audio_at_ids']) && count($fixData['audio_at_ids']) > Constant::UPLOAD_FILE_ATTACH_LIMIT) {
E(L('_ERR_ARTICLE_FILE_ATTACH_MORE', ['at_type' => '音频']));
}
// 视频最多上传5个
if (isset($fixData['video_at_info']) && count($fixData['video_at_info']) > Constant::UPLOAD_FILE_ATTACH_LIMIT) {
E(L('_ERR_ARTICLE_FILE_ATTACH_MORE', ['at_type' => '视频']));
}
// 视频附件参数不正确
if (!empty($fixData['video_at_info'])) {
foreach ($fixData['video_at_info'] as $video) {
if (!isset($video['at_id'], $video['at_name'], $video['at_size'], $video['at_time'])) {
E('_ERR_ARTICLE_ATTACH_PARAM');
}
}
}
// 保存自定义积分策略时,策略数据必传
$allow_key = [
'action_key',
'strategy_id',
];
if ($fixData['strategy_setting'] == Constant::NEWS_STRATEGY_CUSTOM) {
if (!isset($fixData['strategys']) || empty($fixData['strategys'])) {
E('_ERR_ARTICLE_STRATEGY_ID_EMPTY');
}
foreach ($fixData['strategys'] as $strategys) {
if (!is_array($strategys) || empty($strategys)) {
E('_ERR_ARTICLE_STRATEGY_PARAM_FORMAT');
}
$strategy_key = array_keys($strategys);
if (array_diff($allow_key, $strategy_key)) {
E('_ERR_ARTICLE_STRATEGY_PARAM_LOSE');
}
}
}
// 保存自定义学分策略时,策略数据必传
if ($fixData['credit_strategy_setting'] == Constant::NEWS_STRATEGY_CUSTOM) {
if (!isset($fixData['credit_strategys']) || empty($fixData['credit_strategys'])) {
E('_ERR_CREDIT_STRATEGY_ID_EMPTY');
}
foreach ($fixData['credit_strategys'] as $credit_strategys) {
if (!is_array($credit_strategys) || empty($credit_strategys)) {
E('_ERR_CREDIT_STRATEGY_PARAM_FORMAT');
}
$strategy_key = array_keys($credit_strategys);
if (array_diff($allow_key, $strategy_key)) {
E('_ERR_CREDIT_STRATEGY_PARAM_LOSE');
}
}
}
return true;
}
/**
* 补全写入article表的数据
* @author liyifei
* @param array $fixData 补全后的请求参数
* @return array
*/
private function _fixSqlData($fixData)
{
// 补全data_id
$articleServ = new ArticleService();
if ($fixData['article_id'] == 0) {
$fixData['data_id'] = $articleServ->buildDataID();
}
// 补全管理员信息
$fixData['ea_id'] = $this->_login->user['eaId'];
$fixData['ea_name'] = $this->_login->user['eaRealname'];
// 补全class_name
$classServ = new ClassService();
$class = $classServ->get($fixData['class_id']);
if (empty($class)) {
E('_ERR_CLASS_DATA_NOT_FOUND');
}
$fixData['class_name'] = $class['class_name'];
// 补全summary
if (empty($fixData['summary']) && !empty($fixData['content'])) {
// 去除html格式,自动从内容中抓取54个字符
$content = htmlspecialchars(strip_tags($fixData['content']));
$fixData['summary'] = mb_substr($content, 0, Constant::AUTO_SUMMARY_LENGTH, 'UTF-8');
}
// 补全cover_url
$attachServ = &Attach::instance();
$fixData['cover_url'] = $attachServ->getAttachUrl($fixData['cover_id']);
// 补全send_time
$fixData['send_time'] = MILLI_TIME;
// 补全news_status、convert_status
$fixData['convert_status'] = Constant::FILE_STATUS_NORMAL;
if ($fixData['news_status'] == Constant::NEWS_STATUS_SEND) {
if ($fixData['article_id'] == 0) {
// 新建新闻,有附件(预发布、转码中)(视频现在必须转码完成后才能提交,因此不会在保存后进行转码)
if (!empty($fixData['file_at_ids'])) {
$fixData['news_status'] = Constant::NEWS_STATUS_READY_SEND;
$fixData['convert_status'] = Constant::FILE_STATUS_CONVERT;
}
} else {
$article = $articleServ->get($fixData['article_id']);
if (empty($article)) {
E('_ERR_ARTICLE_NOT_FOUND');
}
// 原草稿->现已发布,有附件(预发布、转码中)(视频现在必须转码完成后才能提交,因此不会在保存后进行转码)
if ($article['news_status'] == Constant::NEWS_STATUS_DRAFT && (!empty($fixData['file_at_ids']))) {
$fixData['news_status'] = Constant::NEWS_STATUS_READY_SEND;
$fixData['convert_status'] = Constant::FILE_STATUS_CONVERT;
}
// 原已发布->现已发布(不修改附件)
if ($article['news_status'] == Constant::NEWS_STATUS_SEND) {
$fixData['news_status'] = Constant::NEWS_STATUS_SEND;
$fixData['convert_status'] = Constant::FILE_STATUS_NORMAL;
}
}
}
// 序列化存储积分策略数据
if ($fixData['strategy_setting'] == Constant::NEWS_STRATEGY_CUSTOM && !empty($fixData['strategys'])) {
$strategys = [];
foreach ($fixData['strategys'] as $v) {
$action_key = $v['action_key'];
$strategys[$action_key] = $v['strategy_id'];
}
$fixData['strategys'] = serialize($strategys);
} else {
$fixData['strategys'] = '';
}
// 序列化存储学分策略数据
if ($fixData['credit_strategy_setting'] == Constant::NEWS_STRATEGY_CUSTOM && !empty($fixData['credit_strategys'])) {
$strategys = [];
foreach ($fixData['credit_strategys'] as $v) {
$action_key = $v['action_key'];
$strategys[$action_key] = $v['strategy_id'];
}
$fixData['credit_strategys'] = serialize($strategys);
} else {
$fixData['credit_strategys'] = '';
}
// 去掉postData请求参数中,不在article主表中的字段
$removeKeys = [
'article_id',
'audio_at_ids',
'file_at_ids',
'video_at_info',
'right',
];
foreach ($fixData as $k => $v) {
if (in_array($k, $removeKeys)) {
unset($fixData[$k]);
}
}
return $fixData;
}
/**
* @desc 更新数据时,数据库与提交数据对比,判断推送接口
* @author tangxingguo
* @param int $article_id 新闻ID
* @param array $newInfo 更新的新闻数据
* @param array $postRight 用户提交的权限数据
*/
private function _operationRpc($article_id, $newInfo, $postRight)
{
$articleServ = new ArticleService();
$articleDBInfo = $articleServ->get($article_id);
if (($articleDBInfo['is_recommend'] == Constant::NEWS_IS_RECOMMEND_TRUE && $newInfo['is_recommend'] == Constant::NEWS_IS_RECOMMEND_FALSE) || ($articleDBInfo['is_recommend'] == Constant::NEWS_IS_RECOMMEND_TRUE && $newInfo['news_status'] == Constant::NEWS_STATUS_READY_SEND)) {
// 有推送过取消推送 或 计划任务,删除接口
$articleServ->delNewsRpc($article_id);
} elseif ($articleDBInfo['is_recommend'] == Constant::NEWS_IS_RECOMMEND_FALSE && $newInfo['is_recommend'] == Constant::NEWS_IS_RECOMMEND_TRUE) {
// 第一次推送,添加接口
$articleServ->addNewsRpc($article_id, $postRight);
} elseif ($articleDBInfo['is_recommend'] == Constant::NEWS_IS_RECOMMEND_TRUE && $newInfo['is_recommend'] == Constant::NEWS_IS_RECOMMEND_TRUE) {
// 有推送过,更新接口
$articleServ->updateNewsRpc($article_id, $newInfo, $postRight);
}
}
}