AddonsSmartFormTemplateUserForm.php 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572
  1. <?php
  2. namespace addons\SmartForm\common\models;
  3. use addons\SmartForm\common\enums\SmartFormEnum;
  4. use common\enums\StatusEnum;
  5. use common\models\mall\MallAddons;
  6. use common\models\user\User;
  7. use Yii;
  8. use common\components\export\CsvTool;
  9. use yii\db\Exception;
  10. use common\enums\DownloadEnum;
  11. use common\models\common\Download;
  12. use addons\SmartForm\common\models\AddonsSmartFormTemplateColumn; #模板字段
  13. use addons\SmartForm\common\models\AddonsSmartFormTemplate; #模板
  14. use addons\SmartForm\common\models\AddonsSmartFormTemplateUserFormInfo; # 用户明细字段
  15. use common\helpers\ArrayHelper;
  16. use common\models\common\Region;
  17. use yii\helpers\Json;
  18. /**
  19. * This is the model class for table "{{%addons_smart_form_template_user_form}}".
  20. *
  21. * @property int $id
  22. * @property int $mall_id 商城ID
  23. * @property int|null $status 状态[-1:删除;0:禁用;1启用]
  24. * @property int $created_at 创建时间
  25. * @property int $updated_at 修改时间
  26. * @property int $is_ignore 修改时间
  27. */
  28. class AddonsSmartFormTemplateUserForm extends \common\models\base\BaseActiveRecord
  29. {
  30. const ADDONS_NAME = 'SmartForm';
  31. /**
  32. * {@inheritdoc}
  33. */
  34. public static function tableName()
  35. {
  36. return '{{%addons_smart_form_template_user_form}}';
  37. }
  38. /**
  39. * {@inheritdoc}
  40. */
  41. public function rules()
  42. {
  43. return [
  44. [['smart_form_template_id','user_id','mall_id','source'], 'required'],
  45. [['smart_form_template_id','user_id','mall_id','source','updated_at','created_at','status','diy_page_id', 'is_ignore'], 'integer'],
  46. [['col_value','smart_form_template_column_id'], 'string'],
  47. ];
  48. }
  49. /**
  50. * {@inheritdoc}
  51. */
  52. public function attributeLabels()
  53. {
  54. return [
  55. 'id' => '主键' ,
  56. 'mall_id' => '商城id',
  57. 'smart_form_template_id' => '智能装修表单管理id',
  58. 'user_id' => '用户id',
  59. 'diy_page_id' => '使用页面id',
  60. 'smart_form_template_column_id' => '使用字段',
  61. 'col_value' => '字段值',
  62. 'source' => '来源[0:小程序]',
  63. 'status' => '状态[-1:删除;0:禁用;1:启用,2:已过期]',
  64. 'created_at' => '创建时间',
  65. 'updated_at' => '修改时间',
  66. ];
  67. }
  68. public function getUser()
  69. {
  70. return $this->hasOne(User::class, ['id' => 'user_id'])->select('id,mobile,nickname,avatar_url,parent_id,username');
  71. }
  72. public function getFormInfo(){
  73. return $this->hasMany(AddonsSmartFormTemplateUserFormInfo::class, ['smart_form_template_user_form_id' => 'id']);
  74. }
  75. public function getForm()
  76. {
  77. return $this->hasOne(AddonsSmartFormTemplate::class, ['id' => 'smart_form_template_id']);
  78. }
  79. /**
  80. * @method saveUserForm
  81. * 保存用户表单
  82. * @author zqh
  83. * @datetime 2022-05-07T10:33:40+0800
  84. * @param [type] $params [description]
  85. * @return [type] [description]
  86. */
  87. public static function saveUserForm($params)
  88. {
  89. # 模板参数
  90. $form = $params['form'];
  91. if(!isset($form['id']) || !$form['id']){
  92. self::$static_error = "模板不存在";
  93. return false;
  94. }
  95. # 获取模板信息
  96. $info = AddonsSmartFormTemplate::getOne([['id' => $form['id']]], true, [
  97. 'columnsInfo'=> function ($query) {
  98. }
  99. ]);
  100. if(!$info){
  101. self::$static_error = "模板不存在";
  102. return false;
  103. }
  104. # 获取模板字段信息
  105. $columnInfo = $params['column'];
  106. # 对比提交的模板字段是否一致
  107. $req_column_id = array_column($columnInfo,'key');
  108. $req_column_value = array_column($columnInfo,'value');
  109. $tpl_column_id = array_column($info['columnsInfo'],'id');
  110. # 获取两个字段的差集
  111. $diff_column_id = array_diff($tpl_column_id,$req_column_id);
  112. # 存在差集则非法提交
  113. if(!empty($diff_column_id)){
  114. self::$static_error = "非法提交!";
  115. return false;
  116. }
  117. # 判断提交文字是否合法
  118. $sms_notice_data = [];
  119. foreach ($columnInfo as $k => $v) {
  120. if($info['columnsInfo'][$v['key']]['required'] && !$v['value']){
  121. self::$static_error = $info['columnsInfo'][$v['key']]['title'] . '为必填';
  122. return false;
  123. }
  124. $info_extra_data = !empty($info['columnsInfo'][$v['key']]['extra_data']) ? Json::decode($info['columnsInfo'][$v['key']]['extra_data']) : [];
  125. // 这个需要发送短信
  126. if (!empty($params['user_id']) && !empty($info_extra_data) &&
  127. !empty($info_extra_data['is_enable_sms_notice']) &&
  128. !empty($info_extra_data['sms_template_id']) &&
  129. !empty($info_extra_data['sms_template_content']) &&
  130. !empty($v['value'])) {
  131. // 发送短信
  132. $goods = SmartFormTemplateGoods::getOne([
  133. ['goods_id' => $form['goods_id'] ?? 0],
  134. ['template_id' => $form['id']],
  135. ['status' => StatusEnum::ENABLED],
  136. ]);
  137. if (!empty($goods)) {
  138. $sms_notice_data[] = self::packSendSmsData($info_extra_data, $params['user_id'],
  139. $v['value'], $info['columnsInfo'][$v['key']], $params['mall_id'], $form['goods_id'] ?? 0);
  140. }
  141. }
  142. # 存在选项值
  143. if($info['columnsInfo'][$v['key']]['option']){
  144. $option = [];
  145. $option_value = [];
  146. $option = explode(SmartFormEnum::FIRST_CUTTER,$info['columnsInfo'][$v['key']]['option']);
  147. $option_value = array_keys($option);
  148. if(in_array($v['value'],$option_value,true)){
  149. self::$static_error = $info['columnsInfo'][$v['key']]['title'] . '参数不合法';
  150. return false;
  151. }
  152. }
  153. switch ($info['columnsInfo'][$v['key']]['smart_form_components_code']) {
  154. case 'city-chose':
  155. # 省市区
  156. // $regin = Region::getOne([['id' => $v['value']]], true);
  157. $regin = Region::find()->select('name')->where(['id' => $v['value']])->asArray()->all();
  158. if(!$regin && $info['columnsInfo'][$v['key']]['required']){
  159. self::$static_error = '选择的城市不存在';
  160. return false;
  161. }
  162. break;
  163. case 'upload-photo':
  164. # 上传
  165. $leng = 1;
  166. if(is_array($v['value'])){
  167. $leng = count($v['value']);
  168. }
  169. if($info['columnsInfo'][$v['key']]['limit'] && $leng > $info['columnsInfo'][$v['key']]['limit']){
  170. self::$static_error = $info['columnsInfo'][$v['key']]['title'] . '超出限制长度';
  171. return false;
  172. }
  173. break;
  174. default:
  175. if(is_array($v['value'])){
  176. $leng = count($v['value']);
  177. }else{
  178. $leng = mb_strlen($v['value']);
  179. }
  180. if($info['columnsInfo'][$v['key']]['limit'] && $leng > $info['columnsInfo'][$v['key']]['limit']){
  181. self::$static_error = $info['columnsInfo'][$v['key']]['title'] . '超出限制长度';
  182. return false;
  183. }
  184. break;
  185. }
  186. $arr = [];
  187. $arr['smart_form_template_id'] = $form['id'];
  188. $arr['smart_form_template_user_form_id'] = 0;
  189. $arr['user_id'] = $params['user_id'];
  190. $arr['smart_form_components_id'] = $v['key'];
  191. $arr['smart_form_components_code'] = $info['columnsInfo'][$v['key']]['smart_form_components_code'];
  192. $arr['smart_form_components_title'] = $info['columnsInfo'][$v['key']]['title'];
  193. $arr['col_value'] = $v['value'];
  194. $arr['created_at'] = time();
  195. $arr['updated_at'] = time();
  196. $insert[] = $arr;
  197. }
  198. foreach ($tpl_column_id as $k1 => $v1) {
  199. if(is_array($tpl_column_id[$k1])){
  200. $tpl_column_id[$k1] = json_encode($tpl_column_id[$k1],JSON_UNESCAPED_UNICODE);
  201. }
  202. }
  203. foreach ($req_column_value as $k2 => $v2) {
  204. if(is_array($req_column_value[$k2])){
  205. $req_column_value[$k2] = json_encode($req_column_value[$k2],JSON_UNESCAPED_UNICODE);
  206. }
  207. }
  208. # 写入主表
  209. $formModel = new self();
  210. $formModel->loadDefaultValues();
  211. $formModel->mall_id = $params['mall_id'];
  212. $formModel->diy_page_id = $form['diy_page_id'];
  213. $formModel->smart_form_template_id = $form['id'];
  214. $formModel->user_id = $params['user_id'];
  215. $formModel->smart_form_template_column_id = implode(',',$tpl_column_id);
  216. $formModel->col_value = implode(',',$req_column_value);
  217. $formModel->source = $form['source'];
  218. $formModel->created_at = time();
  219. $formModel->updated_at = time();
  220. if(!$formModel->save()){
  221. self::$static_error = $formModel->getErrorMessage();
  222. return false;
  223. }
  224. foreach ($insert as $k => $v) {
  225. $insert[$k]['smart_form_template_user_form_id'] = $formModel->id;
  226. if(is_array($insert[$k]['col_value'])){
  227. $insert[$k]['col_value'] = implode(',',$insert[$k]['col_value']);
  228. }
  229. }
  230. # 写入明细
  231. $field = ['smart_form_template_id','smart_form_template_user_form_id','user_id','smart_form_components_id','smart_form_components_code','smart_form_components_title','col_value','created_at','updated_at'];
  232. $res = Yii::$app->db->createCommand()->batchInsert(AddonsSmartFormTemplateUserFormInfo::tableName(), $field, $insert)->execute();
  233. if ($res == false) {
  234. self::$static_error = '写入模板字段失败';
  235. return false;
  236. }
  237. if (!empty($sms_notice_data)) { // 短信发送
  238. foreach ($sms_notice_data as &$datum) {
  239. $datum['user_form_id'] = $formModel->id;
  240. }
  241. $res = Yii::$app->db->createCommand()->batchInsert(AddonsStartFormSmsNotice::tableName(),
  242. array_keys($sms_notice_data[0]), $sms_notice_data)->execute();
  243. if (!$res) {
  244. self::$static_error = '写入短信失败';
  245. return false;
  246. }
  247. }
  248. return $formModel;
  249. }
  250. /**
  251. * 拼凑发送短信数据
  252. * @param array $config
  253. * @param $user_id
  254. * @param $send_at
  255. * @param $column
  256. * @param $mall_id
  257. * @param $goods_id
  258. * @return array
  259. */
  260. public static function packSendSmsData(array $config, $user_id, $send_at, $column, $mall_id, $goods_id)
  261. {
  262. // 创建需要发送的记录
  263. // 定时去发送
  264. $send_at = strtotime("$send_at {$config['send_at']}");
  265. $send_at += intval($config['send_day']) * 86400;
  266. return [
  267. 'content' => $config['sms_template_content'],
  268. 'user_id' => $user_id,
  269. 'send_at' => $send_at,
  270. 'send_var' => Json::encode(!empty($config['vars']) ? $config['vars'] : []), // 怎么找出变量
  271. 'template_id' => $config['sms_template_id'],
  272. 'column_id' => $column['id'],
  273. 'created_at'=> time(),
  274. 'updated_at'=> time(),
  275. 'mall_id' => $mall_id,
  276. 'goods_id' => $goods_id,
  277. 'send_status' => !empty($goods_id) ? StatusEnum::DISABLED : StatusEnum::ENABLED,
  278. // 'status' => StatusEnum::DISABLED, // 默认是0,如果下单后那么将其修改为1,如果超过时间还是0则将其设置为2
  279. ];
  280. }
  281. public static function fieldsList($template_id,$field=null)
  282. {
  283. # 获取模板字段
  284. $select = " id,smart_form_components_code type,smart_form_components_code,title label";
  285. $header = AddonsSmartFormTemplateColumn::find()->select($select)
  286. ->orderBy('sort asc')
  287. ->where(['smart_form_template_id'=>$template_id])->asArray()->all();
  288. $fields['nickname'] = '填写人';
  289. foreach ($header as $k => $v) {
  290. $fields[$v['id']] = $v['label'];
  291. }
  292. if ($field === null) return $fields;
  293. $temp = [];
  294. foreach ($field as $val) {
  295. if (isset($fields[$val])) $temp[$val] = $fields[$val];
  296. }
  297. return $temp;
  298. }
  299. /**
  300. * 导出字段
  301. */
  302. public static function exportFieldsList($template_id,$field=null)
  303. {
  304. # 获取模板字段
  305. $select = 'id,smart_form_components_code type,smart_form_components_code,title';
  306. $header = AddonsSmartFormTemplateColumn::find()->select($select)
  307. ->orderBy('sort asc')
  308. ->where(['smart_form_template_id'=>$template_id])->asArray()->all();
  309. $fields['nickname'] = '填写人';
  310. $fields['created_at'] = '填表日期';
  311. foreach ($header as $k => $v) {
  312. $fields[$v['id']] = $v['title'];
  313. }
  314. if ($field === null) return $fields;
  315. $temp = [];
  316. foreach ($field as $val) {
  317. if (isset($fields[$val])) $temp[$val] = $fields[$val];
  318. }
  319. return $temp;
  320. }
  321. /**
  322. * @name:
  323. * @msg: 处理导出数据,这个方法是异步队列处理时使用的,请别修改
  324. * @param {array} $data
  325. * @return bool
  326. */
  327. public static function exportHandle(array $data)
  328. {
  329. $download_id = $data['download_id'] ?? 0;
  330. $download = Download::findOne(['id' => $download_id]);
  331. if ($download) {
  332. try {
  333. $params = json_decode($download->params, true);
  334. $filename = $download->name;
  335. $type = $download->type;
  336. $fields = $params['fields'];
  337. $have_select_field_arr = [];
  338. foreach ($fields as $value) {
  339. $have_select_field_arr[] = $value;
  340. }
  341. $csv = new CsvTool();
  342. $csv->filename = $filename;
  343. $csv->file_dirname = DownloadEnum::getTypeStorageDirMap($type);
  344. $csv->export_mode = CsvTool::EXPORT_MODE_ASYNC;
  345. $csv->header = $have_select_field_arr;
  346. $where = [];
  347. $where[] = ['=', 'a.smart_form_template_id', $params['template_id']];
  348. if(isset($params['date_start'])) $where[] = ['>=','a.created_at',strtotime($params['date_start'])];
  349. if(isset($params['date_end'])) $where[] = ['<=','a.created_at',strtotime($params['date_end'])];
  350. if(isset($params['keyword'])){
  351. $user_ids = User::find()
  352. ->where(['and',['like', 'nickname', $params['keyword']]])
  353. ->select('id')
  354. ->asArray()
  355. ->all();
  356. $user_id_arr = array_column($user_ids, 'id');
  357. $where[] = ['in', 'a.user_id', $user_id_arr];
  358. }
  359. $where[] = ['>=', 'a.status', StatusEnum::DISABLED];
  360. # 排序
  361. $order = 'a.created_at desc';
  362. # 显示字段
  363. $select = 'a.id,a.user_id,a.smart_form_template_column_id,a.col_value,a.source,a.created_at,a.updated_at';
  364. $filter = array('where' => $where, 'order' => $order, 'select' => $select, 'alias' => 'a');
  365. $query = self::find()->select($select);
  366. self::paramPack($filter, $query);
  367. # 结果集
  368. $columnInfo = $query->asArray(true)->all();
  369. $new_col = [];
  370. $new_col = [];
  371. foreach ($columnInfo as $k => $v) {
  372. $users = User::findOne($v["user_id"]);
  373. $nickname = "普通用户";
  374. if(!empty($users)){
  375. $nickname = $users->nickname;
  376. }
  377. $new_col[$k]['nickname'] = $nickname;
  378. $new_col[$k]['created_at'] = date('Y-m-d H:i:s',$v['created_at']);
  379. // 用户填写表单的具体信息
  380. $v['formInfo'] = AddonsSmartFormTemplateUserFormInfo::find()
  381. ->where(['smart_form_template_user_form_id' => $v['id']])
  382. ->asArray()
  383. ->all();
  384. if(empty($v['formInfo'])){
  385. continue;
  386. // $v['formInfo'] = [];
  387. }
  388. // 表单label信息
  389. $template_columns = AddonsSmartFormTemplateColumn::find()
  390. ->where(['and',['in', 'id', array_column($v['formInfo'], 'smart_form_components_id')]])
  391. ->select('id, option')
  392. ->asArray()
  393. ->all();
  394. $template_columns = array_column($template_columns, 'option', 'id');
  395. foreach ($v['formInfo'] as $k1 => $v2) {
  396. $v2['option'] = isset($template_columns[$v2['smart_form_components_id']]) ? $template_columns[$v2['smart_form_components_id']] : [];
  397. switch ($v2['smart_form_components_code']) {
  398. case 'city-chose':
  399. $regin = Region::find()->select('name')->where(['id' => explode(',', $v2['col_value'])])->asArray()->all();
  400. $regin = implode(" ", array_column($regin, 'name'));
  401. $v2['col_value'] = $regin;
  402. break;
  403. case 'upload-photo':
  404. // $col_value = json_decode($v2['col_value'],true);
  405. // $v2['col_value'] = explode(',',$col_value);
  406. break;
  407. case 'checked-tool':
  408. # 多选
  409. // $col_value = json_decode($v2['col_value'], true);
  410. $col_value = explode(',', $v2['col_value']);
  411. if (strpos($v2['option'], SmartFormEnum::FIRST_CUTTER) !== false) {
  412. $col_option = explode(SmartFormEnum::FIRST_CUTTER, $v2['option']);
  413. } else {
  414. $col_option = (array)$v2['option'];
  415. }
  416. $new_col_option = [];
  417. if (is_array($col_value)) {
  418. foreach ($col_value as $ok => $ov) {
  419. if ($col_option[$ov]) {
  420. $new_col_option[] = $col_option[$ov];
  421. }
  422. }
  423. } else {
  424. $new_col_option[0] = $col_option[0];
  425. }
  426. $v2['col_value'] = implode(',', $new_col_option);
  427. break;
  428. case 'radio-tool':
  429. # 单选
  430. $col_value = json_decode($v2['col_value'], true);
  431. $col_value = explode(',', $col_value);
  432. if (strpos($v2['option'], SmartFormEnum::FIRST_CUTTER) !== false) {
  433. $col_option = explode(SmartFormEnum::FIRST_CUTTER, $v2['option']);
  434. } else {
  435. $col_option = (array)$v2['option'];
  436. }
  437. $new_col_option = [];
  438. if (is_array($col_value)) {
  439. foreach ($col_value as $ok => $ov) {
  440. if ($col_option[$ov]) {
  441. $new_col_option[] = $col_option[$ov];
  442. }
  443. }
  444. } else {
  445. $new_col_option[0] = $col_option[0];
  446. }
  447. $v2['col_value'] = implode(',', $new_col_option);
  448. break;
  449. case 'drow-box':
  450. # 下拉
  451. $col_value = json_decode($v2['col_value'], true);
  452. $col_value = explode(',', $col_value);
  453. if (strpos($v2['option'], SmartFormEnum::FIRST_CUTTER) !== false) {
  454. $col_option = explode(SmartFormEnum::FIRST_CUTTER, $v2['option']);
  455. } else {
  456. $col_option = (array)$v2['option'];
  457. }
  458. $new_col_option = [];
  459. if (is_array($col_value)) {
  460. foreach ($col_value as $ok => $ov) {
  461. if ($col_option[$ov]) {
  462. $new_col_option[] = $col_option[$ov];
  463. }
  464. }
  465. } else {
  466. $new_col_option[0] = $col_option[0];
  467. }
  468. $v2['col_value'] = implode(',', $new_col_option);
  469. break;
  470. case 'id-card':
  471. $v2['col_value'] = "'".$v2['col_value'];
  472. break;
  473. default:
  474. // $new_col[$k][$k1] = $v2['col_value'];
  475. break;
  476. }
  477. // $new_col[$k][$k1] = $v2['col_value'];
  478. $new_col[$k][$v2['smart_form_components_id']] = $v2['col_value'];
  479. }
  480. }
  481. $s = array_map(function ($vv) use ($fields) {
  482. $row = [];
  483. foreach ($fields as $k3 => $v3) {
  484. if (isset($vv[$k3])) {
  485. $row[] = $vv[$k3];
  486. }
  487. }
  488. return $row;
  489. }, $new_col);
  490. $csv->data = $s;
  491. $csv->export();
  492. $csv->updateDown($download, $params['mall_id']);
  493. return true;
  494. } catch (Exception $e) {
  495. $download->status = 3;
  496. $res = $download->save();
  497. var_dump($e->getMessage());
  498. self::setStaticError($e->getMessage());
  499. return false;
  500. }
  501. }
  502. }
  503. }