PlanService.class.php
20.7 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
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
<?php
/**
* 培训计划表Service
* Created by PhpStorm.
*/
namespace Common\Service;
use Common\Common\Constant;
use Common\Common\Teacher;
use Common\Common\AttachOperation;
use Common\Model\PlanModel;
class PlanService extends AbstractService
{
// 计划名称最大长度
const PLAN_NAME_MAX_LENGTH = 62;
// 培训计划启用状态:失效
const PLAN_STATUS_CLOSE = 0;
// 培训计划启用状态:启用
const PLAN_STATUS_OPEN = 1;
// 培训计划操作状态:锁定
const PLAN_OPERATE_LOCK = 0;
// 培训计划操作状态:开启
const PLAN_OPERATE_OPEN = 1;
// 培训计划操作状态:已完成(已签到,素材、照片墙已查看,完成考试,完成问卷)
const PLAN_OPERATE_DONE = 2;
// 培训计划类型:签到
const PLAN_TYPE_SIGN = 1;
// 培训计划类型:素材
const PLAN_TYPE_SOURCE = 2;
// 培训计划类型:问卷
const PLAN_TYPE_QUESTION = 3;
// 培训计划类型:考试
const PLAN_TYPE_EXAM = 4;
// 培训计划类型:照片墙
const PLAN_TYPE_PHOTO = 5;
// 培训计划类型:线下课程
const PLAN_TYPE_UNDER_LINE_COURSE = 6;
// 允许员工上传照片
const ALLOW_UPLOAD = 1;
// 不允许员工上传照片
const NOT_ALLOW_UPLOAD = 0;
// 每个类型计划个数最大值
const PLAN_MAX_COUNT = 10;
/** @var PlanModel */
protected $_d;
/** @var PlanPicService */
protected $plan_pic_service;
/** @var CourseArticleService */
protected $course_article_service;
// 计划类型对应的类型名称
protected $plan_type_names = [
self::PLAN_TYPE_SIGN => '签到',
self::PLAN_TYPE_SOURCE => '素材',
self::PLAN_TYPE_QUESTION => '问卷',
self::PLAN_TYPE_EXAM => '考试',
self::PLAN_TYPE_PHOTO => '照片墙',
self::PLAN_TYPE_UNDER_LINE_COURSE => '线下课程',
];
public function __construct()
{
parent::__construct();
// 实例化培训计划model
$this->_d = new PlanModel();
$this->plan_pic_service = new PlanPicService();
$this->course_article_service = new CourseArticleService();
}
/**
* 验证培训计划列表数据
*
* @author houyingcai
* @param array $list 培训计划列表
* @int int $ed_status 培训状态(1=草稿;2=发布;3=已终止)
* @int int $old_ed_status 原培训状态(1=草稿;2=已发布;3=已终止)
*
* @return bool
*/
public function validate_plan_data($list = [], $ed_status = Constant::EDUCATION_PUBLISH_STATUS_PUBLISHED, $old_ed_status = Constant::EDUCATION_PUBLISH_STATUS_PUBLISHED)
{
$plan_max_error = [];
foreach ($list as $key => $val) {
if (isset($plan_max_error[$val['plan_type']])) {
// 如果没有定义 默认值已
$plan_max_error[$val['plan_type']] = 1;
} else {
// 如果存在定义 加一下
$plan_max_error[$val['plan_type']] = $plan_max_error[$val['plan_type']] + 1;
}
// 判断每个计划不能超过10个
foreach ($plan_max_error as $k => $value) {
if ($value > self::PLAN_MAX_COUNT) {
E('【' . $this->plan_type_names[$k] . '不能超过10个');
}
}
// 计划名称不能有空
if (empty($val['plan_name'])) {
E('_EMPTY_PLAN_NAME');
}
// 计划对应ID不能为空(除签到、线下课程之外)
if ($val['plan_type'] != self::PLAN_TYPE_SIGN && $val['plan_type'] != self::PLAN_TYPE_UNDER_LINE_COURSE && !intval($val['plan_obj_id'])) {
E('【' . $this->plan_type_names[$val['plan_type']] . '】:' . $val['plan_name'] . ':计划对应ID不能为空', 2169100);
}
// 计划类型参数无效(类型必须在 1-6 之间)
if (intval($val['plan_type']) < self::PLAN_TYPE_SIGN || intval($val['plan_type']) > self::PLAN_TYPE_UNDER_LINE_COURSE) {
E('【' . $this->plan_type_names[$val['plan_type']] . '】:' . $val['plan_name'] . ':类型参数无效', 2169101);
}
// 计划启用状态参数无效
if ($val['plan_use_status'] != self::PLAN_OPERATE_LOCK && $val['plan_use_status'] != self::PLAN_OPERATE_OPEN) {
E('【' . $this->plan_type_names[$val['plan_type']] . '】:' . $val['plan_name'] . ':启用状态参数无效', 2169103);
}
// 计划启用状态时启用时间大于0
if ($val['plan_use_status'] == self::PLAN_STATUS_OPEN && !$val['plan_use_time']) {
E('【' . $this->plan_type_names[$val['plan_type']] . '】:' . $val['plan_name'] . ':启用时间不能为空', 2169104);
}
// 培训计划类型为:签到类型
if (self::PLAN_TYPE_SIGN == $val['plan_type']) {
// 组装签到时间段数组,用于验证时间段是否有重叠
$sign_list[$key]['plan_sign_begin'] = $val['plan_sign_begin'];
$sign_list[$key]['plan_sign_end'] = $val['plan_sign_end'];
// 签到是否是新增
if (!$val['plan_id']) {
// 签到开始时间不能为空
if (empty($val['plan_sign_begin'])) {
E('【' . $this->plan_type_names[$val['plan_type']] . '】:' . $val['plan_name'] . ':签到开始时间不能为空', 2169105);
}
// 签到结束时间不能为空
if (empty($val['plan_sign_end'])) {
E('【' . $this->plan_type_names[$val['plan_type']] . '】:' . $val['plan_name'] . ':签到结束时间不能为空', 2169106);
}
// 签到结束时间不能小于开始时间
if ($val['plan_sign_end'] < $val['plan_sign_begin']) {
E('【' . $this->plan_type_names[$val['plan_type']] . '】:' . $val['plan_name'] . ':签到结束时间不能小于当前时间', 2169108);
}
}
// 验证签到时间段是否有重叠
if (!empty($sign_list) && count($sign_list) > 1) {
foreach ($sign_list as $k => $v) {
// 签到时间段有重叠
if (!empty($val['plan_sign_begin']) && (($val['plan_sign_begin'] >= $v['plan_sign_begin'] && $val['plan_sign_begin'] <= $v['plan_sign_end']) || ($val['plan_sign_end'] >= $v['plan_sign_begin'] && $val['plan_sign_end'] <= $v['plan_sign_end'])) && $k != $key
) {
E('_ERR_PLAN_SIGN_TIME_REPEAT');
}
}
}
}
// 培训计划类型为:照片墙类型
if (self::PLAN_TYPE_PHOTO == $val['plan_type'] && !in_array(intval($val['plan_allow_upload']), [self::NOT_ALLOW_UPLOAD, self::ALLOW_UPLOAD], true)) {
E('【' . $this->plan_type_names[$val['plan_type']] . '】:' . $val['plan_name'] . ':是否允许员工上传参数无效', 2169111);
}
// 培训计划类型为:线下课程
if (self::PLAN_TYPE_UNDER_LINE_COURSE == $val['plan_type']) {
$this->course_article_service->check_data($val['course'], $ed_status, $old_ed_status);
}
}
return true;
}
/**
* 批量删除培训安排
* @author liyifei
* @param array $plan_ids 待删除的培训安排id
* @int int $ed_status 培训状态(1=草稿;2=发布;3=已终止)
* @return bool
*/
public function delete_plan($plan_ids, $ed_status = Constant::EDUCATION_PUBLISH_STATUS_PUBLISHED)
{
// 删除线下课程类型的培训计划时,需通知讲师中心、删除课程的计划任务
$conds = [
'plan_id' => $plan_ids,
'plan_type' => Constant::PLAN_TYPE_UNDER_LINE_COURSE,
];
$article_plan_list = $this->list_by_conds($conds, [], [], 'plan_obj_id');
if (!empty($article_plan_list)) {
$articleServ = new CourseArticleService();
$signServ = new SignService();
$cronServ = new CronService();
$teacherServ = &Teacher::instance();
$article_ids = array_column($article_plan_list, 'plan_obj_id');
$article_list = $articleServ->list_by_pks($article_ids);
// 删除线下课程数据
$articleServ->delete($article_ids);
// 删除线下课程签到数据
$signServ->delete_by_conds(['article_id' => $article_ids]);
foreach ($article_list as $article) {
if ($ed_status == Constant::EDUCATION_PUBLISH_STATUS_PUBLISHED) {
// 将讲师ID设置为0
$article['teacher_id'] = 0;
$teacherServ->saveOfflineCourse($article);
// 删除课程的计划任务
$cronServ->delCron('', $article['article_id']);
}
}
}
// 删除照片墙类型的培训计划时,需删除UC附件服务器文件
$conds['plan_type'] = Constant::PLAN_TYPE_PHOTO;
$del_photos = $this->list_by_conds($conds, [], [], 'plan_id');
if (!empty($del_photos)) {
$attachServ = new AttachOperation();
$del_photo_plan_ids = array_column($del_photos, 'plan_id');
$attachServ->delete_attach(APP_DIR, 'plan', $del_photo_plan_ids);
}
$this->delete($plan_ids);
}
/**
* 保存培训安排
*
* @author houyingcai
* @param int $ed_id 培训ID
* @param int $stage_id 培训阶段ID
* @param array $data 培训安排数据
* @int int $ed_status 培训状态(1=草稿;2=发布;3=已终止)
*
* @return bool
*/
public function save_plan($ed_id = 0, $stage_id = 0, $data = [], $ed_status = Constant::EDUCATION_PUBLISH_STATUS_PUBLISHED)
{
$courseServ = new CourseArticleService();
// 组装数据
$insert_data = [];
foreach ($data as $k => &$v) {
unset($v['plan_id']);
$v['ed_id'] = $ed_id;
$v['stage_id'] = $stage_id;
$v['plan_obj_id'] = $v['plan_obj_id'] ? (int)$v['plan_obj_id'] : 0;
$v['plan_order'] = $k + 1;
$v['plan_name'] = raddslashes($v['plan_name']);
$v['plan_sign_begin'] = !empty($v['plan_sign_begin']) ? $v['plan_sign_begin'] : '';
$v['plan_sign_end'] = !empty($v['plan_sign_end']) ? $v['plan_sign_end'] : '';
$v['plan_sign_comments'] = !empty($v['plan_sign_comments']) ? raddslashes($v['plan_sign_comments']) : '';
// 对数组进行排序,防止insert_all时出错
ksort($v);
switch ($v['plan_type']) {
// 照片墙(数据已提前写入plan表,此处仅需修改即可)
case self::PLAN_TYPE_PHOTO:
$plan_id = $v['plan_obj_id'];
$v['plan_obj_id'] = 0;
$row = $this->update($plan_id, $v);
if (!$row) {
E('【照片墙】:' . $v['plan_name'] . ' 添加失败', '2169112');
}
// 更新照片表的培训ID
$this->plan_pic_service->update_by_conds(['plan_id' => $plan_id], ['ed_id' => $ed_id]);
break;
// 线下课程
case self::PLAN_TYPE_UNDER_LINE_COURSE:
// 保存线下课程
$v['plan_obj_id'] = $courseServ->save_course($v['course'], $ed_status, $v['plan_use_status']);
// 保存培训安排
unset($v['course']);
$insert_data[] = $v;
break;
default:
$insert_data[] = $v;
break;
}
}
// 批量插入新增数据
if (!empty($insert_data)) {
$row_plans = $this->insert_all($insert_data);
if (!$row_plans) {
E('培训计划添加失败', '2169114');
}
}
// 为所有线下课程绑定ed_id和plan_id
$plan_list = $this->list_by_conds(['ed_id' => $ed_id, 'plan_type' => Constant::PLAN_TYPE_UNDER_LINE_COURSE]);
if (!empty($plan_list)) {
foreach ($plan_list as $plan) {
$update_data = [
'ed_id' => $plan['ed_id'],
'plan_id' => $plan['plan_id'],
];
$this->course_article_service->update($plan['plan_obj_id'], $update_data);
}
}
return true;
}
/**
* 编辑计划数据
*
* @author houyingcai
* @param int $ed_id 培训ID
* @param int $stage_id 培训阶段ID
* @param array $plans 计划数据数组
* @param array $plan_del_ids 需删除的培训安排id
* @int int $ed_status 培训状态(1=草稿;2=发布;3=已终止)
*
* @return bool
*/
public function edit_plan($ed_id = 0, $stage_id = 0, $plans = [], $plan_del_ids = [], $ed_status = Constant::EDUCATION_PUBLISH_STATUS_PUBLISHED)
{
$courseServ = new CourseArticleService();
$insert_data = [];
$plan_order = 0;
foreach ($plans as &$v) {
// 要删除的培训安排,不再更新
if (in_array($v['plan_id'], $plan_del_ids)) {
continue;
}
$plan_order++;
// 更新需要更新的数据
if (isset($v['plan_id']) && $v['plan_id'] > 0) {
$update['ed_id'] = $ed_id;
$update['stage_id'] = $stage_id;
$update['plan_order'] = $plan_order;
$update['plan_name'] = raddslashes($v['plan_name']);
$update['plan_use_status'] = intval($v['plan_use_status']);
$update['plan_use_time'] = $v['plan_use_time'];
switch ($v['plan_type']) {
// 签到
case self::PLAN_TYPE_SIGN:
$update['plan_sign_begin'] = $v['plan_sign_begin'];
$update['plan_sign_end'] = $v['plan_sign_end'];
$update['plan_sign_comments'] = $v['plan_sign_comments'];
break;
// 照片墙
case self::PLAN_TYPE_PHOTO:
$update['plan_allow_upload'] = intval($v['plan_allow_upload']);
// 更新照片表的培训ID
$this->plan_pic_service->update_by_conds(['plan_id' => $v['plan_id']], ['ed_id' => $ed_id]);
break;
// 线下课程
case self::PLAN_TYPE_UNDER_LINE_COURSE:
if (isset($v['course']) && !empty($v['course'])) {
// 修改线下课程详情
$courseServ->save_course($v['course'], $ed_status, $v['plan_use_status']);
}
break;
}
$row = $this->_d->update($v['plan_id'], $update);
if (!$row) {
E($v['plan_name'] . ' 更新失败', '2169112');
}
} else {
$v['ed_id'] = $ed_id;
$v['stage_id'] = $stage_id;
$v['plan_order'] = $plan_order;
$v['plan_name'] = raddslashes($v['plan_name']);
$v['plan_obj_id'] = $v['plan_obj_id'] ? intval($v['plan_obj_id']) : 0;
$v['plan_sign_begin'] = !empty($v['plan_sign_begin']) ? $v['plan_sign_begin'] : '';
$v['plan_sign_end'] = !empty($v['plan_sign_end']) ? $v['plan_sign_end'] : '';
$v['plan_sign_comments'] = !empty($v['plan_sign_comments']) ? raddslashes($v['plan_sign_comments']) : '';
// 新增线下课程类型
if ($v['plan_type'] == Constant::PLAN_TYPE_UNDER_LINE_COURSE) {
// 保存线下课程
$v['plan_obj_id'] = $courseServ->save_course($v['course'], $ed_status, $v['plan_use_status']);
unset($v['course']);
}
// 保存培训安排
ksort($v);
$insert_data[] = $v;
}
}
// 批量插入新增数据
if (!empty($insert_data)) {
$row_plans = $this->insert_all($insert_data);
if (!$row_plans) {
E('培训计划添加失败', '2169114');
}
}
// 为所有线下课程绑定ed_id和plan_id
$plan_list = $this->list_by_conds(['ed_id' => $ed_id, 'plan_type' => Constant::PLAN_TYPE_UNDER_LINE_COURSE]);
if (!empty($plan_list)) {
foreach ($plan_list as $plan) {
$update_data = [
'ed_id' => $plan['ed_id'],
'plan_id' => $plan['plan_id'],
];
$this->course_article_service->update($plan['plan_obj_id'], $update_data);
}
}
return true;
}
/**
* 添加照片墙
*
* @author 蔡建华
* @param $params array 表单数据
*
* @return mixed
*/
public function add_pic_plan($params = [])
{
if (empty($params['plan_name'])) {
// 照片墙名称不能把为空
E('_EMPTY_PLAN_PIC_NAME');
}
if (strlen($params['plan_name']) > self::PLAN_NAME_MAX_LENGTH) {
// 照片墙名称长度超过最大值
E('_EMPTY_PLAN_PIC_NAME_MORE');
}
try {
// 开始事务
$this->start_trans();
$data = [
'plan_name' => $params['plan_name'],
'plan_type' => self::PLAN_TYPE_PHOTO,
'plan_allow_upload' => intval($params['plan_allow_upload']),
'plan_use_status' => self::PLAN_STATUS_OPEN
];
// 添加照片墙数据
$plan_id = $this->_d->insert($data);
$pics = [];
if ($plan_id) {
// 照片墙添加成功 后台添加照片
$upload = $params['upload'];
foreach ($upload as $val) {
if (!empty($val['pic_at_id'])) {
$value = $val;
$value['plan_id'] = $plan_id;
$value['pic_uid'] = '';
$value['pic_type'] = PlanPicService::PIC_UPLOAD_TYPE_ADMIN;
$pics[] = $value;
}
}
}
if (!empty($pics)) {
// 照片数据入库
$this->plan_pic_service->insert_all($pics);
}
// 提交事务
$this->commit();
} catch (\Exception $e) {
\Think\Log::record($e);
$this->_set_error($e->getMessage(), $e->getCode());
// 事务回滚
$this->rollback();
return false;
}
// 附件操作
if (!empty($upload)) {
$attach_serv = new AttachOperation();
$attach_ids = array_column($upload, 'pic_at_id');
$attach_serv->insert_attach(
APP_DIR,
'plan',
$plan_id,
['attach_ids' => $attach_ids]
);
}
return $plan_id;
}
/**
* 编辑照片墙
*
* @author 蔡建华
* @param $params array 表单数据
*
* @return bool
*/
public function edit_pic_plan($params = [])
{
if (empty($params['plan_id'])) {
E('_EMPTY_PLAN_PIC_ID');
}
if (empty($params['plan_name'])) {
E('_EMPTY_PLAN_PIC_NAME');
}
if (strlen($params['plan_name']) > self::PLAN_NAME_MAX_LENGTH) {
// 照片墙名称长度超过最大值
E('_EMPTY_PLAN_PIC_NAME_MORE');
}
$data = [
'plan_name' => $params['plan_name'],
'plan_allow_upload' => intval($params['plan_allow_upload']),
'plan_use_status' => self::PLAN_STATUS_OPEN
];
$conds = [
'plan_id' => $params['plan_id'],
'plan_type' => self::PLAN_TYPE_PHOTO
];
$this->_d->update_by_conds($conds, $data);
return true;
}
/**
* 获取被使用的应用id集合
*
* @param int $plan_type 应用类型
*
* @return array 被使用的id集合
*/
public function get_obj_ids($plan_type = 0)
{
return $this->_d->get_obj_ids($plan_type);
}
}