説明なし
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

Form.php 58KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434
  1. <?php
  2. /**
  3. * 易优CMS
  4. * ============================================================================
  5. * 版权所有 2016-2028 海口快推科技有限公司,并保留所有权利。
  6. * 网站地址: http://www.eyoucms.com
  7. * ----------------------------------------------------------------------------
  8. * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
  9. * ============================================================================
  10. * Author: 小虎哥 <1105415366@qq.com>
  11. * Date: 2023-3-8
  12. */
  13. namespace app\admin\controller;
  14. use think\Page;
  15. use think\Db;
  16. use think\Cache;
  17. use app\admin\logic\FormLogic;
  18. class Form extends Base
  19. {
  20. // 表单类型
  21. public $attrInputTypeArr = array();
  22. public function _initialize()
  23. {
  24. parent::_initialize();
  25. $this->attrInputTypeArr = config('global.guestbook_attr_input_type');
  26. // 数据表
  27. $this->form_db = Db::name('form');
  28. // 业务层
  29. $this->formLogic = new FormLogic;
  30. // 模型层
  31. $this->form_model = model('Form');
  32. }
  33. /**
  34. * 留言列表 - 栏目关联、表单的留言
  35. */
  36. public function index()
  37. {
  38. $assign_data = array();
  39. $condition = array();
  40. // 获取到所有GET参数
  41. $param = input('param.');
  42. $typeid = $param['typeid'] = empty($param['typeid']) ? '' : intval($param['typeid']);
  43. $form_type = $param['form_type'] = empty($param['form_type']) ? '' : intval($param['form_type']);
  44. $source = $param['source'] = empty($param['source']) ? 1 : intval($param['source']);
  45. $count_type = empty($param['count_type']) ? 'all' : $param['count_type'];
  46. $begin = strtotime(input('param.add_time_begin/s'));
  47. $end = input('param.add_time_end/s');
  48. !empty($end) && $end .= ' 23:59:59';
  49. $end = strtotime($end);
  50. // 应用搜索条件
  51. foreach (['keywords', 'typeid', 'count_type','source'] as $key) {
  52. if (isset($param[$key]) && $param[$key] !== '') {
  53. if ($key == 'keywords') {
  54. $attr_row = Db::name('guestbook_attr')->field('aid')->where(array('attr_value' => array('LIKE', "%{$param[$key]}%")))->group('aid')->getAllWithIndex('aid');
  55. $aids = array_keys($attr_row);
  56. $condition['a.aid'] = array('IN', $aids);
  57. } else if ($key == 'count_type') {
  58. if ('unread' == $count_type) {
  59. $condition['a.is_read'] = 0;
  60. } else if ('read' == $count_type) {
  61. $condition['a.is_read'] = 1;
  62. } else if ('star' == $count_type) {
  63. $condition['a.is_star'] = 1;
  64. }
  65. } else {
  66. $condition['a.' . $key] = array('eq', $param[$key]);
  67. }
  68. }
  69. }
  70. // 时间检索
  71. if ($begin > 0 && $end > 0) {
  72. $condition['a.add_time'] = array('between',"$begin,$end");
  73. } else if ($begin > 0) {
  74. $condition['a.add_time'] = array('egt', $begin);
  75. } else if ($end > 0) {
  76. $condition['a.add_time'] = array('elt', $end);
  77. }
  78. if (empty($typeid)) {
  79. /*权限控制 by 小虎哥*/
  80. $admin_info = session('admin_info');
  81. if (0 < intval($admin_info['role_id'])) {
  82. $auth_role_info = $admin_info['auth_role_info'];
  83. if(! empty($auth_role_info)){
  84. $is_notaccess = false;
  85. $permission_arctype = !empty($auth_role_info['permission']['arctype']) ? $auth_role_info['permission']['arctype'] : [];
  86. if(!empty($permission_arctype)){
  87. $typeids_tmp = Db::name('arctype')->where(['current_channel'=>8,'lang'=>$this->admin_lang])->cache(true, EYOUCMS_CACHE_TIME, 'arctype')->column('id');
  88. $typeids_tmp = !empty($typeids_tmp) ? $typeids_tmp : [];
  89. $typeids_tmp1 = array_intersect($typeids_tmp, $auth_role_info['permission']['arctype']);
  90. if (!empty($typeids_tmp1)) {
  91. $is_notaccess = true;
  92. $typeids_tmp2 = implode(',', $typeids_tmp1);
  93. $rawstr = " (a.typeid IN ({$typeids_tmp2}) AND a.form_type = 0) ";
  94. $formids_tmp1 = Db::name('form')->where(['lang'=>$this->admin_lang])->cache(true, EYOUCMS_CACHE_TIME, 'form')->column('form_id');
  95. if (!empty($formids_tmp1)) {
  96. $formids_tmp2 = implode(',', $formids_tmp1);
  97. $rawstr .= " OR (a.typeid IN ({$formids_tmp2}) AND a.form_type = 1) ";
  98. }
  99. $condition[] = Db::raw("({$rawstr})");
  100. }
  101. }
  102. if (false === $is_notaccess) {
  103. $this->error('您没有操作权限,请联系超级管理员分配权限');
  104. }
  105. }
  106. }
  107. /*--end*/
  108. }
  109. // 多语言
  110. $condition['a.lang'] = array('eq', $this->admin_lang);
  111. /**
  112. * 数据查询,搜索出主键ID的值
  113. */
  114. $count = Db::name('guestbook')->alias('a')->where($condition)->count('aid');// 查询满足要求的总记录数
  115. $Page = new Page($count, config('paginate.list_rows'));// 实例化分页类 传入总记录数和每页显示的记录数
  116. $list = Db::name('guestbook')
  117. ->field("a.*")
  118. ->alias('a')
  119. ->where($condition)
  120. ->order('a.is_read asc, a.add_time desc')
  121. ->limit($Page->firstRow . ',' . $Page->listRows)
  122. ->getAllWithIndex('aid');
  123. /**
  124. * 完善数据集信息
  125. * 在数据量大的情况下,经过优化的搜索逻辑,先搜索出主键ID,再通过ID将其他信息补充完整;
  126. */
  127. $aids = $typeids = $formids = [];
  128. if ($list) {
  129. foreach ($list as $key => $val) {
  130. $aids[] = $val['aid'];
  131. if (1 == $val['form_type']) {
  132. $formids[] = $val['typeid'];
  133. } else {
  134. $typeids[] = $val['typeid'];
  135. }
  136. }
  137. $where = [
  138. 'b.aid' => ['IN', $aids],
  139. 'a.is_showlist' => 1,
  140. 'a.is_del' => 0,
  141. ];
  142. $row = Db::name('guestbook_attribute')
  143. ->field('a.attr_name, a.typeid, b.attr_value, b.aid, b.attr_id,a.attr_input_type')
  144. ->alias('a')
  145. ->join('__GUESTBOOK_ATTR__ b', 'b.attr_id = a.attr_id', 'LEFT')
  146. ->where($where)
  147. ->order('b.aid desc, a.sort_order asc, a.attr_id asc')
  148. ->getAllWithIndex();
  149. $attr_list = array();
  150. foreach ($row as $key => $val) {
  151. if (9 == $val['attr_input_type']){
  152. //如果是区域类型,转换名称
  153. $val['attr_value'] = Db::name('region')->where('id','in',$val['attr_value'])->column('name');
  154. $val['attr_value'] = implode('',$val['attr_value']);
  155. }else if(10 == $val['attr_input_type']){
  156. $val['attr_value'] = date('Y-m-d H:i:s',$val['attr_value']);
  157. }else if(in_array($val['attr_input_type'], [5,11])){
  158. $val['attr_value'] = str_replace(['|',PHP_EOL], ',', $val['attr_value']);
  159. $attr_values = explode(',', $val['attr_value']);
  160. foreach ($attr_values as $_k => $_v) {
  161. $_v = handle_subdir_pic($_v);
  162. $_v = "<i class='fa fa-picture-o color_z curpoin' onclick=\"Images('{$_v}', 900, 600);\"></i>";
  163. $attr_values[$_k] = $_v;
  164. }
  165. $val['attr_value'] = implode('&nbsp;', $attr_values);
  166. }else if(8 == $val['attr_input_type']){
  167. $val['attr_value'] = handle_subdir_pic($val['attr_value']);
  168. $val['attr_value'] = "<img src='{$this->root_dir}/public/static/admin/images/addon.gif' width='14' /><a href='{$val['attr_value']}' target='_blank'>下载附件</a>";
  169. }
  170. $attr_list[$val['aid']][] = $val;
  171. }
  172. $formList = Db::name('form')->field('form_id,form_name')->where(['form_id'=>['IN',$formids]])->getAllWithIndex('form_id');
  173. $arctypeList = Db::name('arctype')->field('id,typename')->where(['id'=>['IN',$typeids]])->getAllWithIndex('id');
  174. foreach ($list as $key => $val) {
  175. if (1 == $val['form_type']) {
  176. $val['form_name'] = empty($formList[$val['typeid']]) ? '' : $formList[$val['typeid']]['form_name'];
  177. } else {
  178. $val['form_name'] = empty($arctypeList[$val['typeid']]) ? '' : $arctypeList[$val['typeid']]['typename'];
  179. }
  180. $val['attr_list'] = isset($attr_list[$val['aid']]) ? $attr_list[$val['aid']] : array();
  181. $list[$key] = $val;
  182. }
  183. }
  184. $typeids_arr = array_merge($typeids, $formids);
  185. $tab_list = Db::name('guestbook_attribute')->where([
  186. 'typeid' => ['IN', $typeids_arr],
  187. 'is_showlist' => 1,
  188. 'is_del' => 0,
  189. ])->order('typeid asc, sort_order asc, attr_id asc')->select();
  190. $tab_list = group_same_key($tab_list, 'typeid');
  191. $assign_data['tab_list'] = $tab_list;
  192. $show = $Page->show(); // 分页显示输出
  193. $assign_data['page'] = $show; // 赋值分页输出
  194. $assign_data['list'] = $list; // 赋值数据集
  195. $assign_data['pager'] = $Page; // 赋值分页对象
  196. $assign_data['typeid'] = $typeid; // 栏目/表单的ID
  197. $assign_data['form_type'] = $form_type;
  198. $assign_data['count_type'] = $count_type;
  199. $assign_data['source'] = $source;
  200. $assign_data['iframe'] = input('param.iframe/d', 0);
  201. //计算留言数量
  202. $gbCountList = [
  203. 'all' => [
  204. 'type' => 'all',
  205. 'name' => '全部',
  206. 'count' => 0,
  207. ],
  208. ];
  209. if (isset($condition['a.is_read'])) {
  210. unset($condition['a.is_read']);
  211. }
  212. if (isset($condition['a.is_star'])) {
  213. unset($condition['a.is_star']);
  214. }
  215. $condition['lang'] = $this->admin_lang;
  216. $gbCountRow = Db::name('guestbook')->alias('a')->field('is_read,count(aid) as num')->where($condition)->group('is_read')->order('is_read asc')->select();
  217. if (empty($gbCountRow)) {
  218. $gbCountRow = [
  219. ['is_read'=>0,'num'=>0],
  220. ['is_read'=>1,'num'=>0],
  221. ];
  222. }
  223. foreach ($gbCountRow as $key => $val) {
  224. $type = 'unread';
  225. $name = '未读';
  226. if (!empty($val['is_read'])) {
  227. $type = 'read';
  228. $name = '已读';
  229. }
  230. $gbCountList[$type] = [
  231. 'type' => $type,
  232. 'name' => $name,
  233. 'count' => $val['num'],
  234. ];
  235. $gbCountList['all']['count'] += $val['num'];
  236. }
  237. if (isset($condition['a.is_read'])) {
  238. unset($condition['a.is_read']);
  239. }
  240. $condition['is_star'] = 1;
  241. $star_num = Db::name('guestbook')->alias('a')->where($condition)->count();
  242. $gbCountList['star'] = [
  243. 'type' => 'star',
  244. 'name' => '星标',
  245. 'count' => intval($star_num),
  246. ];
  247. $assign_data['gbCountList'] = $gbCountList;
  248. // 获取留言类型(系统留言、可视化百度小程序留言、可视化微信小程序留言)
  249. $gbTypeList = $this->getGbTypeList(1);
  250. $assign_data['gbTypeList'] = $gbTypeList;
  251. // 加载数据
  252. $this->assign($assign_data);
  253. // 手机端后台管理插件特定使用参数
  254. $isMobile = input('param.isMobile/d', 0);
  255. // 如果安装手机端后台管理插件并且在手机端访问时执行
  256. if (is_dir('./weapp/Mbackend/') && !empty($isMobile)) {
  257. $mbPage = input('param.p/d', 1);
  258. $nullShow = intval($Page->totalPages) === intval($mbPage) ? 1 : 0;
  259. $this->assign('nullShow', $nullShow);
  260. if ($mbPage >= 2) {
  261. return $this->display('form/form_list');
  262. } else {
  263. return $this->display('form/index');
  264. }
  265. } else {
  266. return $this->fetch();
  267. }
  268. }
  269. /*可视化百度小程序*/
  270. // 可视化百度小程序留言列表
  271. public function baidu_diyminipro_index()
  272. {
  273. // 查询当前小程序 mini_id
  274. $result = $this->getBaiduDiyminiproInfo();
  275. // 查询条件
  276. $where = [
  277. 'a.lang' => $result['lang'],
  278. 'a.mini_id' => $result['mini_id']
  279. ];
  280. // 全部、已读、未读查询条件
  281. $count_type = input('param.count_type/s', 'all');
  282. if ('unread' == $count_type) {
  283. $where['a.is_read'] = 0;
  284. } else if ('read' == $count_type) {
  285. $where['a.is_read'] = 1;
  286. }
  287. $assign_data['count_type'] = $count_type;
  288. // 模糊查询
  289. $keywords = input('param.keywords/s', 'all');
  290. if (!empty($keywords)) {
  291. $list_ids = Db::name('weapp_bd_diyminipro_form_value')->where(['field_value' => ['LIKE', "%{$keywords}%"]])->column('list_id');
  292. if (!empty($list_ids)) $where['a.list_id'] = ['IN', array_unique($list_ids)];
  293. }
  294. // 如果有表单ID则指定查询
  295. $form_id = input('param.form_id/d', 0);
  296. if (!empty($form_id)) $where['a.form_id'] = $form_id;
  297. // 分页查询
  298. $count = Db::name('weapp_bd_diyminipro_form_list')->alias('a')->where($where)->join('weapp_bd_diyminipro_form b', 'a.form_id = b.form_id', 'LEFT')->count();
  299. $Page = new Page($count, config('paginate.list_rows'));
  300. // 数据查询
  301. $list = Db::name('weapp_bd_diyminipro_form_list')
  302. ->field('a.*, b.form_name')
  303. ->alias('a')
  304. ->where($where)
  305. ->join('weapp_bd_diyminipro_form b', 'a.form_id = b.form_id', 'LEFT')
  306. ->order('a.update_time desc, a.list_id desc')
  307. ->limit($Page->firstRow.','.$Page->listRows)
  308. ->select();
  309. // 内容查询
  310. $result = Db::name('weapp_bd_diyminipro_form_field')
  311. ->field('b.*, a.field_name')
  312. ->alias('a')
  313. ->join('weapp_bd_diyminipro_form_value b', 'b.field_id = a.field_id', 'LEFT')
  314. ->where(['b.list_id' => ['IN', get_arr_column($list, 'list_id')]])
  315. ->order('b.value_id asc')
  316. ->select();
  317. $field_list = [];
  318. foreach ($result as $key => $value) {
  319. if ('checkbox' == $value['field_type'] && !empty($value['field_value'])) {
  320. $value['field_value'] = str_replace(',', '] [', '['.$value['field_value'].']');
  321. } else if ('datetime' == $value['field_type'] && !empty($value['field_value'])){
  322. $value['field_value'] = date('Y-m-d H:i:s', $value['field_value']);
  323. } else if ('location' == $value['field_type'] && !empty($value['field_value'])){
  324. $value['field_value'] = htmlspecialchars_decode($value['field_value']);
  325. $location_value = json_decode($value['field_value'], true);
  326. $value['field_value'] = $location_value['address']. $location_value['number'];
  327. }
  328. $field_list[$value['list_id']][] = $value;
  329. }
  330. // 数据处理
  331. foreach ($list as $key => $value) {
  332. $value['field_list'] = isset($field_list[$value['list_id']]) ? $field_list[$value['list_id']] : [];
  333. $list[$key] = $value;
  334. }
  335. $assign_data['list'] = $list;
  336. $assign_data['pager'] = $Page;
  337. $assign_data['page'] = $Page->show();
  338. // 查询所有留言
  339. unset($where['a.is_read']);
  340. $formCountRow = Db::name('weapp_bd_diyminipro_form_list')->alias('a')->where($where)->select();
  341. // 计算(全部、已读、未读)留言数量
  342. $all = $read = $unread = 0;
  343. foreach ($formCountRow as $value) {
  344. $all++;
  345. if (!empty($value['is_read'])) {
  346. $read++;
  347. } else {
  348. $unread++;
  349. }
  350. }
  351. $formCountList = [
  352. 'all' => [
  353. 'type' => 'all',
  354. 'name' => '全部',
  355. 'count' => intval($all),
  356. ],
  357. 'read' => [
  358. 'type' => 'read',
  359. 'name' => '已读',
  360. 'count' => intval($read),
  361. ],
  362. 'unread' => [
  363. 'type' => 'unread',
  364. 'name' => '未读',
  365. 'count' => intval($unread),
  366. ],
  367. ];
  368. $assign_data['formCountList'] = $formCountList;
  369. // 获取留言类型(系统留言、可视化百度小程序留言、可视化微信小程序留言)
  370. $gbTypeList = $this->getGbTypeList(2);
  371. $assign_data['gbTypeList'] = $gbTypeList;
  372. // 加载数据
  373. $this->assign($assign_data);
  374. return $this->fetch();
  375. }
  376. // 可视化百度小程序留言详情
  377. public function baidu_diyminipro_details()
  378. {
  379. $list_id = input('list_id/d', 0);
  380. $form_id = input('form_id/d', 0);
  381. if (empty($list_id) || empty($form_id)) $this->error('参数有误');
  382. // 查询当前小程序 mini_id
  383. $result = $this->getBaiduDiyminiproInfo();
  384. // 查询条件
  385. $where = [
  386. 'a.list_id' => $list_id,
  387. 'a.form_id' => $form_id,
  388. 'a.lang' => $result['lang'],
  389. 'a.mini_id' => $result['mini_id']
  390. ];
  391. // 更新为已读
  392. $update = [
  393. 'is_read' => 1,
  394. 'update_time' => getTime()
  395. ];
  396. Db::name('weapp_bd_diyminipro_form_list')->alias('a')->where($where)->update($update);
  397. // 执行查询
  398. $info = Db::name('weapp_bd_diyminipro_form_list')
  399. ->field('a.*, b.form_name')
  400. ->alias('a')
  401. ->where($where)
  402. ->join('weapp_bd_diyminipro_form b', 'a.form_id = b.form_id', 'LEFT')
  403. ->find();
  404. $assign_data['info'] = $info;
  405. // 执行查询
  406. $value_list = Db::name('weapp_bd_diyminipro_form_value')
  407. ->field('a.*, b.field_name')
  408. ->alias('a')
  409. ->where($where)
  410. ->join('weapp_bd_diyminipro_form_field b', 'a.field_id = b.field_id', 'LEFT')
  411. ->select();
  412. foreach ($value_list as $key => $value) {
  413. if ('checkbox' == $value['field_type'] && !empty($value['field_value'])) {
  414. $value_list[$key]['field_value'] = str_replace(',', '] [', '['.$value['field_value'].']');
  415. } else if ('datetime' == $value['field_type'] && !empty($value['field_value'])){
  416. $value_list[$key]['field_value'] = date('Y-m-d H:i:s', $value['field_value']);
  417. } else if ('location' == $value['field_type'] && !empty($value['field_value'])){
  418. $value['field_value'] = htmlspecialchars_decode($value['field_value']);
  419. $location_value = json_decode($value['field_value'], true);
  420. $value_list[$key]['field_value'] = $location_value['address']. $location_value['number'];
  421. }
  422. }
  423. $assign_data['value_list'] = $value_list;
  424. $this->assign($assign_data);
  425. return $this->fetch();
  426. }
  427. // 删除可视化百度小程序留言
  428. public function baidu_diyminipro_del()
  429. {
  430. if (IS_AJAX_POST) {
  431. $list_id = input('post.list_id/d', 0);
  432. if (empty($list_id)) $this->error('参数有误');
  433. // 查询当前小程序 mini_id
  434. $result = $this->getBaiduDiyminiproInfo();
  435. // 执行条件
  436. $where = [
  437. 'list_id' => $list_id,
  438. 'lang' => $result['lang'],
  439. 'mini_id' => $result['mini_id']
  440. ];
  441. // 删除表单列表数据
  442. $resultID = Db::name('weapp_bd_diyminipro_form_list')->where($where)->delete(true);
  443. if (!empty($resultID)) {
  444. // 同步删除表单下的字段
  445. Db::name('weapp_bd_diyminipro_form_value')->where($where)->delete(true);
  446. $this->success('删除成功');
  447. } else {
  448. $this->error('删除失败');
  449. }
  450. }
  451. }
  452. // 查询 查询可视化百度小程序 当前使用的 mini_id
  453. private function getBaiduDiyminiproInfo()
  454. {
  455. return Db::name('weapp_bd_diyminipro')->where(['is_del'=> 0])->order('mini_id desc')->find();
  456. }
  457. /*end*/
  458. /*可视化微信小程序*/
  459. // 可视化微信小程序留言列表
  460. public function wechat_diyminipro_index()
  461. {
  462. // 查询当前小程序 mini_id
  463. $result = $this->getWechatDiyminiproInfo();
  464. // 查询条件
  465. $where = [
  466. 'a.lang' => $result['lang'],
  467. 'a.mini_id' => $result['mini_id']
  468. ];
  469. // 全部、已读、未读查询条件
  470. $count_type = input('param.count_type/s', 'all');
  471. if ('unread' == $count_type) {
  472. $where['a.is_read'] = 0;
  473. } else if ('read' == $count_type) {
  474. $where['a.is_read'] = 1;
  475. }
  476. $assign_data['count_type'] = $count_type;
  477. // 模糊查询
  478. $keywords = input('param.keywords/s', 'all');
  479. if (!empty($keywords)) {
  480. $list_ids = Db::name('diyminipro_form_value')->where(['field_value' => ['LIKE', "%{$keywords}%"]])->column('list_id');
  481. if (!empty($list_ids)) $where['a.list_id'] = ['IN', array_unique($list_ids)];
  482. }
  483. // 如果有表单ID则指定查询
  484. $form_id = input('param.form_id/d', 0);
  485. if (!empty($form_id)) $where['a.form_id'] = $form_id;
  486. // 分页查询
  487. $count = Db::name('diyminipro_form_list')->alias('a')->where($where)->join('diyminipro_form b', 'a.form_id = b.form_id', 'LEFT')->count();
  488. $Page = new Page($count, config('paginate.list_rows'));
  489. // 数据查询
  490. $list = Db::name('diyminipro_form_list')
  491. ->field('a.*, b.form_name')
  492. ->alias('a')
  493. ->where($where)
  494. ->join('diyminipro_form b', 'a.form_id = b.form_id', 'LEFT')
  495. ->order('a.update_time desc, a.list_id desc')
  496. ->limit($Page->firstRow.','.$Page->listRows)
  497. ->select();
  498. // 内容查询
  499. $result = Db::name('weapp_bd_diyminipro_form_field')
  500. ->field('b.*, a.field_name')
  501. ->alias('a')
  502. ->join('diyminipro_form_value b', 'b.field_id = a.field_id', 'LEFT')
  503. ->where(['b.list_id' => ['IN', get_arr_column($list, 'list_id')]])
  504. ->order('b.value_id asc')
  505. ->select();
  506. $field_list = [];
  507. foreach ($result as $key => $value) {
  508. if ('checkbox' == $value['field_type'] && !empty($value['field_value'])) {
  509. $value['field_value'] = str_replace(',', '] [', '['.$value['field_value'].']');
  510. } else if ('datetime' == $value['field_type'] && !empty($value['field_value'])){
  511. $value['field_value'] = date('Y-m-d H:i:s', $value['field_value']);
  512. } else if ('location' == $value['field_type'] && !empty($value['field_value'])){
  513. $value['field_value'] = htmlspecialchars_decode($value['field_value']);
  514. $location_value = json_decode($value['field_value'], true);
  515. $value['field_value'] = $location_value['address']. $location_value['number'];
  516. }
  517. $field_list[$value['list_id']][] = $value;
  518. }
  519. // 数据处理
  520. foreach ($list as $key => $value) {
  521. $value['field_list'] = isset($field_list[$value['list_id']]) ? $field_list[$value['list_id']] : [];
  522. $list[$key] = $value;
  523. }
  524. $assign_data['list'] = $list;
  525. $assign_data['pager'] = $Page;
  526. $assign_data['page'] = $Page->show();
  527. // 查询所有留言
  528. unset($where['a.is_read']);
  529. $formCountRow = Db::name('diyminipro_form_list')->alias('a')->where($where)->select();
  530. // 计算(全部、已读、未读)留言数量
  531. $all = $read = $unread = 0;
  532. foreach ($formCountRow as $value) {
  533. $all++;
  534. if (!empty($value['is_read'])) {
  535. $read++;
  536. } else {
  537. $unread++;
  538. }
  539. }
  540. $formCountList = [
  541. 'all' => [
  542. 'type' => 'all',
  543. 'name' => '全部',
  544. 'count' => intval($all),
  545. ],
  546. 'read' => [
  547. 'type' => 'read',
  548. 'name' => '已读',
  549. 'count' => intval($read),
  550. ],
  551. 'unread' => [
  552. 'type' => 'unread',
  553. 'name' => '未读',
  554. 'count' => intval($unread),
  555. ],
  556. ];
  557. $assign_data['formCountList'] = $formCountList;
  558. // 获取留言类型(系统留言、可视化百度小程序留言、可视化微信小程序留言)
  559. $gbTypeList = $this->getGbTypeList(3);
  560. $assign_data['gbTypeList'] = $gbTypeList;
  561. // 加载数据
  562. $this->assign($assign_data);
  563. return $this->fetch();
  564. }
  565. // 可视化微信小程序留言详情
  566. public function wechat_diyminipro_details()
  567. {
  568. $list_id = input('list_id/d', 0);
  569. $form_id = input('form_id/d', 0);
  570. if (empty($list_id) || empty($form_id)) $this->error('参数有误');
  571. // 查询当前小程序 mini_id
  572. $result = $this->getWechatDiyminiproInfo();
  573. // 查询条件
  574. $where = [
  575. 'a.list_id' => $list_id,
  576. 'a.form_id' => $form_id,
  577. 'a.lang' => $result['lang'],
  578. 'a.mini_id' => $result['mini_id']
  579. ];
  580. // 更新为已读
  581. $update = [
  582. 'is_read' => 1,
  583. 'update_time' => getTime()
  584. ];
  585. Db::name('diyminipro_form_list')->alias('a')->where($where)->update($update);
  586. // 执行查询
  587. $info = Db::name('diyminipro_form_list')
  588. ->field('a.*, b.form_name')
  589. ->alias('a')
  590. ->where($where)
  591. ->join('diyminipro_form b', 'a.form_id = b.form_id', 'LEFT')
  592. ->find();
  593. $assign_data['info'] = $info;
  594. // 执行查询
  595. $value_list = Db::name('diyminipro_form_value')
  596. ->field('a.*, b.field_name')
  597. ->alias('a')
  598. ->where($where)
  599. ->join('diyminipro_form_field b', 'a.field_id = b.field_id', 'LEFT')
  600. ->select();
  601. foreach ($value_list as $key => $value) {
  602. if ('checkbox' == $value['field_type'] && !empty($value['field_value'])) {
  603. $value_list[$key]['field_value'] = str_replace(',', '] [', '['.$value['field_value'].']');
  604. } else if ('datetime' == $value['field_type'] && !empty($value['field_value'])){
  605. $value_list[$key]['field_value'] = date('Y-m-d H:i:s', $value['field_value']);
  606. } else if ('location' == $value['field_type'] && !empty($value['field_value'])){
  607. $value['field_value'] = htmlspecialchars_decode($value['field_value']);
  608. $location_value = json_decode($value['field_value'], true);
  609. $value_list[$key]['field_value'] = $location_value['address']. $location_value['number'];
  610. }
  611. }
  612. $assign_data['value_list'] = $value_list;
  613. $this->assign($assign_data);
  614. return $this->fetch();
  615. }
  616. // 删除可视化微信小程序留言
  617. public function wechat_diyminipro_del()
  618. {
  619. if (IS_AJAX_POST) {
  620. $list_id = input('post.list_id/d', 0);
  621. if (empty($list_id)) $this->error('参数有误');
  622. // 查询当前小程序 mini_id
  623. $result = $this->getWechatDiyminiproInfo();
  624. // 执行条件
  625. $where = [
  626. 'list_id' => $list_id,
  627. 'lang' => $result['lang'],
  628. 'mini_id' => $result['mini_id']
  629. ];
  630. // 删除表单列表数据
  631. $resultID = Db::name('diyminipro_form_list')->where($where)->delete(true);
  632. if (!empty($resultID)) {
  633. // 同步删除表单下的字段
  634. Db::name('diyminipro_form_value')->where($where)->delete(true);
  635. $this->success('删除成功');
  636. } else {
  637. $this->error('删除失败');
  638. }
  639. }
  640. }
  641. // 查询 可视化微信小程序 当前使用的 mini_id
  642. private function getWechatDiyminiproInfo()
  643. {
  644. return Db::name('diyminipro')->where(['is_del'=> 0])->order('mini_id desc')->find();
  645. }
  646. /*end*/
  647. // 获取留言类型(系统留言、可视化百度小程序留言、可视化微信小程序留言)
  648. private function getGbTypeList($type = 1)
  649. {
  650. $source = input('param.source/d', 1);
  651. // 系统留言
  652. $result['pc'] = [
  653. 'url' => url('Form/index', ['source'=>1]),
  654. 'name' => '电脑端',
  655. 'count' => Db::name('guestbook')->where(['source'=>1, 'lang'=>$this->admin_lang])->count(),
  656. 'class' => 1 === intval($type) && 1 === intval($source) ? 'cur' : '',
  657. ];
  658. $result['mobile'] = [
  659. 'url' => url('Form/index', ['source'=>2]),
  660. 'name' => '手机端',
  661. 'count' => Db::name('guestbook')->where(['source'=>2, 'lang'=>$this->admin_lang])->count(),
  662. 'class' => 1 === intval($type) && 2 === intval($source) ? 'cur' : '',
  663. ];
  664. // 如果安装了可视化百度小程序插件则执行
  665. if (is_dir('./weapp/BdDiyminipro/')) {
  666. // 开启可视化百度小程序插件则执行
  667. $data = model('Weapp')->getWeappList('BdDiyminipro');
  668. if (!empty($data['status']) && 1 == $data['status']) {
  669. $result['baidu'] = [
  670. 'url' => url('Form/baidu_diyminipro_index'),
  671. 'name' => '可视化百度小程序',
  672. 'count' => Db::name('weapp_bd_diyminipro_form_list')->count(),
  673. 'class' => 2 === intval($type) ? 'cur' : '',
  674. ];
  675. }
  676. }
  677. // 如果安装了可视化微信小程序插件则执行
  678. if (is_dir('./weapp/Diyminipro/')) {
  679. // 开启可视化微信小程序插件则执行
  680. $data = model('Weapp')->getWeappList('Diyminipro');
  681. if (!empty($data['status']) && 1 == $data['status']) {
  682. $result['wechat'] = [
  683. 'url' => url('Form/wechat_diyminipro_index'),
  684. 'name' => '可视化微信小程序',
  685. 'count' => Db::name('diyminipro_form_list')->count(),
  686. 'class' => 3 === intval($type) ? 'cur' : '',
  687. ];
  688. }
  689. }
  690. return $result;
  691. }
  692. public function field()
  693. {
  694. $assign_data = [];
  695. // 查询条件
  696. $condition = [
  697. 'lang' => $this->admin_lang,
  698. ];
  699. // 应用搜索条件
  700. $keywords = input('keywords/s');
  701. $keywords = trim($keywords);
  702. if (!empty($keywords)) $condition['form_name'] = array('LIKE', "%{$keywords}%");
  703. // 分页查询
  704. $count = $this->form_db->where($condition)->count();
  705. $Page = new Page($count, config('paginate.list_rows'));
  706. $show = $Page->show();
  707. $assign_data['page'] = $show;
  708. $assign_data['pager'] = $Page;
  709. // 数据查询
  710. $list = $this->form_db
  711. ->where($condition)
  712. ->order('form_id asc')
  713. ->limit($Page->firstRow.','.$Page->listRows)
  714. ->select();
  715. $assign_data['list'] = $list;
  716. $form_ids = get_arr_column($list, 'form_id');
  717. // 查询表单填写数量
  718. $assign_data['form_list_count'] = $this->form_model->GetFormListCount($form_ids);
  719. /*多语言模式下,表单ID显示主体语言的ID*/
  720. $main_form_list = [];
  721. if ($this->admin_lang != $this->main_lang && empty($this->globalConfig['language_split'])) {
  722. $attr_values = get_arr_column($list, 'form_id');
  723. $languageAttrRow = Db::name('language_attr')->field('attr_name,attr_value')->where([
  724. 'attr_value' => ['IN', $attr_values],
  725. 'attr_group' => 'form',
  726. 'lang' => $this->admin_lang,
  727. ])->getAllWithIndex('attr_value');
  728. $groupids = [];
  729. foreach ($languageAttrRow as $key => $val) {
  730. $gid_tmp = str_replace('form', '', $val['attr_name']);
  731. array_push($groupids, intval($gid_tmp));
  732. }
  733. $main_FormRow = Db::name('form')->field("form_id,CONCAT('form', form_id) AS attr_name")
  734. ->where([
  735. 'form_id' => ['IN', $groupids],
  736. 'lang' => $this->main_lang,
  737. ])->getAllWithIndex('attr_name');
  738. foreach ($list as $key => $val) {
  739. $key_tmp = !empty($languageAttrRow[$val['form_id']]['attr_name']) ? $languageAttrRow[$val['form_id']]['attr_name'] : '';
  740. $main_form_list[$val['form_id']] = [
  741. 'form_id' => !empty($main_FormRow[$key_tmp]['form_id']) ? $main_FormRow[$key_tmp]['form_id'] : 0,
  742. ];
  743. }
  744. }
  745. $this->assign('main_form_list', $main_form_list);
  746. /*end*/
  747. $this->assign($assign_data);
  748. return $this->fetch();
  749. }
  750. /**
  751. * 新增表单
  752. */
  753. public function field_add()
  754. {
  755. if (is_language() && empty($this->globalConfig['language_split'])) {
  756. $this->language_access(); // 多语言功能操作权限
  757. }
  758. if (IS_POST) {
  759. $post = input('post.');
  760. $post['form_name'] = trim($post['form_name']);
  761. if (empty($post['form_name'])) {
  762. $this->error('表单名称不能为空!');
  763. }
  764. $data = array(
  765. 'form_name' => $post['form_name'],
  766. 'intro' => '',
  767. 'status' => 1,
  768. 'attr_auto' => intval($post['attr_auto']),
  769. 'lang' => $this->admin_lang,
  770. 'add_time' => getTime(),
  771. 'update_time' => getTime(),
  772. );
  773. $insertID = Db::name('form')->insertGetId($data);
  774. if (!empty($insertID)) {
  775. // 同步表单ID到多语言的模板变量里,添加多语言表单
  776. $this->formLogic->syn_add_language_form($insertID);
  777. Cache::clear('form');
  778. adminLog('新增表单:'.$data['form_name']);
  779. $this->success("操作成功", url('Form/field'));
  780. }
  781. $this->error("操作失败", url('Form/field'));
  782. }
  783. return $this->fetch();
  784. }
  785. /**
  786. * 编辑表单
  787. */
  788. public function field_edit()
  789. {
  790. if (IS_POST) {
  791. $post = input('post.');
  792. $post['form_id'] = intval($post['form_id']);
  793. if (!empty($post['form_id'])) {
  794. $post['form_name'] = trim($post['form_name']);
  795. if (empty($post['form_name'])) {
  796. $this->error('表单名称不能为空!');
  797. }
  798. $data = array(
  799. 'form_name' => $post['form_name'],
  800. 'attr_auto' => intval($post['attr_auto']),
  801. 'update_time' => getTime(),
  802. );
  803. $resultID = Db::name('form')->where(['form_id'=>$post['form_id']])->cache(true,null,'form')->update($data);
  804. if ($resultID !== false) {
  805. adminLog('编辑表单:'.$data['form_name']);
  806. $this->success("操作成功", url('Form/field'));
  807. }
  808. }
  809. $this->error("操作失败", url('Form/field'));
  810. }
  811. $id = input('id/d');
  812. $info = Db::name('form')->where([
  813. 'form_id' => $id,
  814. ])->find();
  815. if (empty($info)) {
  816. $this->error('表单不存在,请联系管理员!');
  817. exit;
  818. }
  819. $assign_data = array();
  820. $assign_data['info'] = $info;
  821. $this->assign($assign_data);
  822. return $this->fetch();
  823. }
  824. /**
  825. * 删除表单
  826. */
  827. public function field_del()
  828. {
  829. $id_arr = input('del_id/a');
  830. $id_arr = eyIntval($id_arr);
  831. if (IS_POST && !empty($id_arr)) {
  832. /*多语言*/
  833. $attr_name_arr = [];
  834. foreach ($id_arr as $key => $val) {
  835. $attr_name_arr[] = 'form'.$val;
  836. }
  837. if (is_language() && empty($this->globalConfig['language_split'])) {
  838. $new_id_arr = Db::name('language_attr')->where([
  839. 'attr_name' => ['IN', $attr_name_arr],
  840. 'attr_group' => 'form',
  841. ])->column('attr_value');
  842. !empty($new_id_arr) && $id_arr = $new_id_arr;
  843. }
  844. /*--end*/
  845. $form_name_list = $this->form_db->where([
  846. 'form_id' => ['IN', $id_arr],
  847. ])->column('form_name');
  848. $r = $this->form_db->where([
  849. 'form_id' => ['IN', $id_arr],
  850. ])->delete();
  851. if($r !== false){
  852. $aid_arr = Db::name('guestbook')->where([
  853. 'typeid' => ['IN', $id_arr],
  854. 'form_type' => 1,
  855. ])->column('aid');
  856. if (!empty($aid_arr)) {
  857. Db::name('guestbook')->where([
  858. 'aid' => ['IN', $aid_arr],
  859. ])->delete();
  860. Db::name('guestbook_attr')->where([
  861. 'aid' => ['IN', $aid_arr],
  862. ])->delete();
  863. Db::name('guestbook_attribute')->where([
  864. 'typeid' => ['IN', $id_arr],
  865. 'form_type' => 1,
  866. ])->delete();
  867. }
  868. Cache::clear('form');
  869. Cache::clear('guestbook');
  870. adminLog('删除表单:'.implode(',', $form_name_list));
  871. $this->success('删除成功');
  872. }
  873. }
  874. $this->error('删除失败');
  875. }
  876. //留言表单列表
  877. public function attribute_index()
  878. {
  879. $assign_data = array();
  880. $condition = array();
  881. $get = input('get.');
  882. $typeid = input('typeid/d');
  883. foreach (['keywords','typeid'] as $key) {
  884. if (isset($get[$key]) && $get[$key] !== '') {
  885. if ($key == 'keywords') {
  886. $condition['a.attr_name'] = array('LIKE', "%{$get[$key]}%");
  887. } else {
  888. $condition['a.'.$key] = array('eq', $get[$key]);
  889. }
  890. }
  891. }
  892. $condition['a.form_type'] = 1;
  893. $condition['b.form_id'] = ['gt', 0];
  894. $condition['a.is_del'] = 0;
  895. $condition['a.lang'] = $this->admin_lang;
  896. $count = Db::name('guestbook_attribute')->alias('a')
  897. ->join('__FORM__ b', 'a.typeid = b.form_id', 'LEFT')
  898. ->where($condition)
  899. ->count();
  900. $Page = new Page($count, config('paginate.list_rows'));
  901. $list = Db::name('guestbook_attribute')
  902. ->field("a.attr_id")
  903. ->alias('a')
  904. ->join('__FORM__ b', 'a.typeid = b.form_id', 'LEFT')
  905. ->where($condition)
  906. ->order('a.typeid desc, a.sort_order asc, a.attr_id asc')
  907. ->limit($Page->firstRow.','.$Page->listRows)
  908. ->getAllWithIndex('attr_id');
  909. if ($list) {
  910. $attr_ida = array_keys($list);
  911. $fields = "b.*, a.*,a.attr_id as orgin_attr_id";
  912. $row = Db::name('guestbook_attribute')
  913. ->field($fields)
  914. ->alias('a')
  915. ->join('__FORM__ b', 'a.typeid = b.form_id', 'LEFT')
  916. ->where('a.attr_id', 'in', $attr_ida)
  917. ->getAllWithIndex('attr_id');
  918. $row = model('LanguageAttr')->getBindValue($row, 'form_attribute', $this->main_lang); // 获取多语言关联绑定的值
  919. foreach ($row as $key => $val) {
  920. $val['fieldname'] = 'attr_'.$val['attr_id'];
  921. $row[$key] = $val;
  922. }
  923. foreach ($list as $key => $val) {
  924. $list[$key] = $row[$val['attr_id']];
  925. }
  926. }
  927. $show = $Page->show();
  928. $assign_data['page'] = $show;
  929. $assign_data['list'] = $list;
  930. $assign_data['pager'] = $Page;
  931. $assign_data['typeid'] = $typeid;
  932. // 表单列表
  933. $assign_data['attrInputTypeArr'] = $this->attrInputTypeArr; // 表单类型
  934. $this->assign($assign_data);
  935. return $this->fetch();
  936. }
  937. /**
  938. * 新增表单属性
  939. */
  940. public function attribute_add()
  941. {
  942. //防止php超时
  943. function_exists('set_time_limit') && set_time_limit(0);
  944. if (is_language() && empty($this->globalConfig['language_split'])) {
  945. $this->language_access(); // 多语言功能操作权限
  946. }
  947. if(IS_AJAX && IS_POST)//ajax提交验证
  948. {
  949. $model = model('GuestbookAttribute');
  950. $attr_values = str_replace('_', '', input('attr_values')); // 替换特殊字符
  951. $attr_values = str_replace('@', '', $attr_values); // 替换特殊字符
  952. $attr_values = trim($attr_values);
  953. /*过滤重复值*/
  954. $attr_values_arr = explode(PHP_EOL, $attr_values);
  955. foreach ($attr_values_arr as $key => $val) {
  956. $tmp_val = trim($val);
  957. if (empty($tmp_val)) {
  958. unset($attr_values_arr[$key]);
  959. continue;
  960. }
  961. $attr_values_arr[$key] = $tmp_val;
  962. }
  963. $attr_values_arr = array_unique($attr_values_arr);
  964. $attr_values = implode(PHP_EOL, $attr_values_arr);
  965. /*end*/
  966. $post_data = input('post.');
  967. $post_data['attr_values'] = $attr_values;
  968. $attr_input_type = isset($post_data['attr_input_type']) ? $post_data['attr_input_type'] : 0;
  969. /*前台输入是否JS验证*/
  970. $validate_type = 0;
  971. $validate_type_list = config("global.validate_type_list"); // 前台输入验证类型
  972. if (!empty($validate_type_list[$attr_input_type])) {
  973. $validate_type = $attr_input_type;
  974. }
  975. /*end*/
  976. if (9 == $post_data['attr_input_type']) {
  977. if (!empty($post_data['region_data'])) {
  978. $post_data['attr_values'] = serialize($post_data['region_data']);
  979. } else {
  980. $this->error("请选择区域范围!");
  981. }
  982. }
  983. $savedata = array(
  984. 'attr_name' => $post_data['attr_name'],
  985. 'typeid' => $post_data['typeid'],
  986. 'form_type' => 1,
  987. 'attr_input_type' => $attr_input_type,
  988. 'attr_values' => isset($post_data['attr_values']) ? $post_data['attr_values'] : '',
  989. 'is_showlist' => $post_data['is_showlist'],
  990. 'required' => $post_data['required'],
  991. 'real_validate' => $post_data['real_validate'],
  992. 'validate_type' => $validate_type,
  993. 'sort_order' => 100,
  994. 'lang' => $this->admin_lang,
  995. 'add_time' => getTime(),
  996. 'update_time' => getTime(),
  997. );
  998. // 如果是添加手机号码类型则执行
  999. if (!empty($savedata['typeid']) && 6 === intval($savedata['attr_input_type']) && 1 === intval($savedata['real_validate'])) {
  1000. // 查询是否已添加需要真实验证的手机号码类型
  1001. $where = [
  1002. 'typeid' => $savedata['typeid'],
  1003. 'form_type' => 1,
  1004. 'real_validate' => $savedata['real_validate'],
  1005. 'attr_input_type' => $savedata['attr_input_type']
  1006. ];
  1007. $realValidate = $model->get($where);
  1008. if (!empty($realValidate)) $this->error('只能设置一个需要真实验证的手机号码类型');
  1009. }
  1010. // 数据验证
  1011. $validate = \think\Loader::validate('GuestbookAttribute');
  1012. if(!$validate->batch()->check($savedata))
  1013. {
  1014. $error = $validate->getError();
  1015. $error_msg = array_values($error);
  1016. $return_arr = array(
  1017. 'status' => -1,
  1018. 'msg' => $error_msg[0],
  1019. 'data' => $error,
  1020. );
  1021. respose($return_arr);
  1022. } else {
  1023. $model->data($savedata,true); // 收集数据
  1024. $model->save(); // 写入数据到数据库
  1025. $insertId = $model->getLastInsID();
  1026. // 同步表单ID到多语言的模板变量里,添加多语言表单
  1027. $this->formLogic->syn_add_language_attribute($insertId);
  1028. $return_arr = array(
  1029. 'status' => 1,
  1030. 'msg' => '操作成功',
  1031. 'data' => array('url'=>url('Form/attribute_index', array('typeid'=>$post_data['typeid']))),
  1032. );
  1033. adminLog('新增表单:'.$savedata['attr_name']);
  1034. respose($return_arr);
  1035. }
  1036. }
  1037. $typeid = input('param.typeid/d', 0);
  1038. if ($typeid > 0) {
  1039. $formdata = $this->form_db->where(['form_id'=>$typeid])->find();
  1040. } else {
  1041. $formdata = $this->form_db->where(['lang'=>$this->admin_lang,'status'=>1])->select();
  1042. }
  1043. $assign_data['formdata'] = $formdata; //
  1044. $assign_data['typeid'] = $typeid; // 表单ID
  1045. $assign_data['attrInputTypeArr'] = $this->attrInputTypeArr; // 表单类型
  1046. //区域
  1047. $China[] = [
  1048. 'id' => 0,
  1049. 'name' => '全国',
  1050. ];
  1051. $Province = get_province_list();
  1052. $assign_data['Province'] = array_merge($China, $Province);
  1053. $this->assign($assign_data);
  1054. return $this->fetch();
  1055. }
  1056. /**
  1057. * 编辑表单属性
  1058. */
  1059. public function attribute_edit()
  1060. {
  1061. if(IS_AJAX && IS_POST)//ajax提交验证
  1062. {
  1063. $model = model('GuestbookAttribute');
  1064. $attr_values = str_replace('_', '', input('attr_values')); // 替换特殊字符
  1065. $attr_values = str_replace('@', '', $attr_values); // 替换特殊字符
  1066. $attr_values = trim($attr_values);
  1067. /*过滤重复值*/
  1068. $attr_values_arr = explode(PHP_EOL, $attr_values);
  1069. foreach ($attr_values_arr as $key => $val) {
  1070. $tmp_val = trim($val);
  1071. if (empty($tmp_val)) {
  1072. unset($attr_values_arr[$key]);
  1073. continue;
  1074. }
  1075. $attr_values_arr[$key] = $tmp_val;
  1076. }
  1077. $attr_values_arr = array_unique($attr_values_arr);
  1078. $attr_values = implode(PHP_EOL, $attr_values_arr);
  1079. /*end*/
  1080. $post_data = input('post.');
  1081. $post_data['attr_id'] = intval($post_data['attr_id']);
  1082. $post_data['attr_values'] = $attr_values;
  1083. $attr_input_type = isset($post_data['attr_input_type']) ? $post_data['attr_input_type'] : 0;
  1084. /*前台输入是否JS验证*/
  1085. $validate_type = 0;
  1086. $validate_type_list = config("global.validate_type_list"); // 前台输入验证类型
  1087. if (!empty($validate_type_list[$attr_input_type])) {
  1088. $validate_type = $attr_input_type;
  1089. }
  1090. /*end*/
  1091. if (9 == $post_data['attr_input_type']) {
  1092. if (!empty($post_data['region_data'])) {
  1093. $post_data['attr_values'] = serialize($post_data['region_data']);
  1094. } else {
  1095. $this->error("请选择区域范围!");
  1096. }
  1097. }
  1098. $savedata = array(
  1099. 'attr_id' => $post_data['attr_id'],
  1100. 'attr_name' => $post_data['attr_name'],
  1101. 'typeid' => $post_data['typeid'],
  1102. 'form_type' => 1,
  1103. 'attr_input_type' => $attr_input_type,
  1104. 'attr_values' => isset($post_data['attr_values']) ? $post_data['attr_values'] : '',
  1105. 'is_showlist' => $post_data['is_showlist'],
  1106. 'required' => $post_data['required'],
  1107. 'real_validate' => $post_data['real_validate'],
  1108. 'validate_type' => $validate_type,
  1109. 'sort_order' => 100,
  1110. 'update_time' => getTime(),
  1111. );
  1112. // 如果是添加手机号码类型则执行
  1113. if (!empty($savedata['typeid']) && 6 === intval($savedata['attr_input_type']) && 1 === intval($savedata['real_validate'])) {
  1114. // 查询是否已添加需要真实验证的手机号码类型
  1115. $where = [
  1116. 'typeid' => $savedata['typeid'],
  1117. 'form_type' => 1,
  1118. 'attr_id' => ['NEQ', $savedata['attr_id']],
  1119. 'real_validate' => $savedata['real_validate'],
  1120. 'attr_input_type' => $savedata['attr_input_type']
  1121. ];
  1122. $realValidate = $model->get($where);
  1123. if (!empty($realValidate)) $this->error('只能设置一个需要真实验证的手机号码类型');
  1124. }
  1125. // 数据验证
  1126. $validate = \think\Loader::validate('GuestbookAttribute');
  1127. if(!$validate->batch()->check($savedata))
  1128. {
  1129. $error = $validate->getError();
  1130. $error_msg = array_values($error);
  1131. $return_arr = array(
  1132. 'status' => -1,
  1133. 'msg' => $error_msg[0],
  1134. 'data' => $error,
  1135. );
  1136. respose($return_arr);
  1137. } else {
  1138. $model->data($savedata, true); // 收集数据
  1139. $model->isUpdate(true, [
  1140. 'attr_id' => $post_data['attr_id'],
  1141. ])->save(); // 写入数据到数据库
  1142. $return_arr = array(
  1143. 'status' => 1,
  1144. 'msg' => '操作成功',
  1145. 'data' => array('url' => url('Form/attribute_index', array('typeid' => intval($post_data['typeid'])))),
  1146. );
  1147. adminLog('编辑表单:' . $savedata['attr_name']);
  1148. respose($return_arr);
  1149. }
  1150. }
  1151. $assign_data = array();
  1152. $id = input('id/d');
  1153. /*获取多语言关联绑定的值*/
  1154. $new_id = model('LanguageAttr')->getBindValue($id, 'form_attribute'); // 多语言
  1155. !empty($new_id) && $id = $new_id;
  1156. /*--end*/
  1157. $info = Db::name('GuestbookAttribute')->where([
  1158. 'attr_id' => $id,
  1159. 'form_type' => 1,
  1160. ])->find();
  1161. if (empty($info)) {
  1162. $this->error('数据不存在,请联系管理员!');
  1163. exit;
  1164. }
  1165. $assign_data['field'] = $info;
  1166. // 所在表单
  1167. $formdata = $this->form_db->where('form_id', $info['typeid'])->find();
  1168. $assign_data['formdata'] = $formdata;
  1169. $assign_data['attrInputTypeArr'] = $this->attrInputTypeArr; // 表单类型
  1170. /*区域字段处理*/
  1171. // 初始化参数
  1172. $assign_data['region'] = [
  1173. 'parent_id' => '-1',
  1174. 'region_id' => '-1',
  1175. 'region_names' => '',
  1176. 'region_ids' => '',
  1177. ];
  1178. // 定义全国参数
  1179. $China[] = [
  1180. 'id' => 0,
  1181. 'name' => '全国',
  1182. ];
  1183. // 查询省份信息并且拼装上$China数组
  1184. $Province = get_province_list();
  1185. $assign_data['Province'] = array_merge($China, $Province);
  1186. // 区域选择时,指定不出现下级地区列表
  1187. $assign_data['parent_array'] = "[]";
  1188. // 如果是区域类型则执行
  1189. if (9 == $info['attr_input_type']) {
  1190. // 反序列化默认值参数
  1191. $dfvalue = unserialize($info['attr_values']);
  1192. if (0 == $dfvalue['region_id']) {
  1193. $parent_id = $dfvalue['region_id'];
  1194. } else {
  1195. // 查询当前选中的区域父级ID
  1196. $parent_id = Db::name('region')->where("id", $dfvalue['region_id'])->getField('parent_id');
  1197. if (0 == $parent_id) {
  1198. $parent_id = $dfvalue['region_id'];
  1199. }
  1200. }
  1201. // 查询市\区\县信息
  1202. $assign_data['City'] = Db::name('region')->where("parent_id", $parent_id)->select();
  1203. // 加载数据到模板
  1204. $assign_data['region'] = [
  1205. 'parent_id' => $parent_id,
  1206. 'region_id' => $dfvalue['region_id'],
  1207. 'region_names' => $dfvalue['region_names'],
  1208. 'region_ids' => $dfvalue['region_ids'],
  1209. ];
  1210. // 删除默认值,防止切换其他类型时使用到
  1211. unset($info['attr_values']);
  1212. // 区域选择时,指定不出现下级地区列表
  1213. $assign_data['parent_array'] = convert_js_array(config('global.field_region_all_type'));
  1214. }
  1215. /*区域字段处理结束*/
  1216. $this->assign($assign_data);
  1217. return $this->fetch();
  1218. }
  1219. /**
  1220. * 删除表单属性
  1221. */
  1222. public function attribute_del()
  1223. {
  1224. if (is_language() && empty($this->globalConfig['language_split'])) {
  1225. $this->language_access(); // 多语言功能操作权限
  1226. }
  1227. $thorough = input('thorough/d');
  1228. $id_arr = input('del_id/a');
  1229. $id_arr = eyIntval($id_arr);
  1230. if (!empty($id_arr)) {
  1231. //多语言
  1232. $attr_name_arr = [];
  1233. foreach ($id_arr as $key => $val) {
  1234. $attr_name_arr[] = 'attr_' . $val;
  1235. }
  1236. if (is_language() && empty($this->globalConfig['language_split'])) {
  1237. $new_id_arr = Db::name('language_attr')->where([
  1238. 'attr_name' => ['IN', $attr_name_arr],
  1239. 'attr_group' => 'form_attribute',
  1240. ])->column('attr_value');
  1241. !empty($new_id_arr) && $id_arr = $new_id_arr;
  1242. }
  1243. if (1 == $thorough){//彻底删除
  1244. $r = Db::name('GuestbookAttribute')->where([
  1245. 'attr_id' => ['IN', $id_arr],
  1246. 'form_type' => 1,
  1247. ])->delete();
  1248. }else{
  1249. $r = Db::name('GuestbookAttribute')->where([
  1250. 'attr_id' => ['IN', $id_arr],
  1251. 'form_type' => 1,
  1252. ])->update([
  1253. 'is_del' => 1,
  1254. 'update_time' => getTime(),
  1255. ]);
  1256. }
  1257. if($r !== false){
  1258. // 删除多语言表单属性关联绑定
  1259. if (1 == $thorough){//彻底删除
  1260. if (!empty($attr_name_arr)) {
  1261. if (get_admin_lang() == get_main_lang()) {
  1262. Db::name('language_attribute')->where([
  1263. 'attr_name' => ['IN', $attr_name_arr],
  1264. 'attr_group' => 'form_attribute',
  1265. ])->delete();
  1266. }
  1267. if (empty($this->globalConfig['language_split'])) {
  1268. Db::name('language_attr')->where([
  1269. 'attr_name' => ['IN', $attr_name_arr],
  1270. 'attr_group' => 'form_attribute',
  1271. ])->delete();
  1272. } else {
  1273. Db::name('language_attr')->where([
  1274. 'attr_value' => ['IN', $id_arr],
  1275. 'attr_group' => 'form_attribute',
  1276. ])->delete();
  1277. }
  1278. }
  1279. }
  1280. /*--end*/
  1281. adminLog('删除表单属性-id:'.implode(',', $id_arr));
  1282. $this->success('删除成功');
  1283. }
  1284. }
  1285. $this->error('删除失败');
  1286. }
  1287. //标签调用
  1288. public function label_call(){
  1289. $form_id = input('form_id/d',0);
  1290. if (!empty($form_id)) {
  1291. $form = model('form')->where(['form_id'=>$form_id])->find();
  1292. $content =<<<EOF
  1293. {eyou:form type="auto" formid="{$form['form_id']}" id="field"}
  1294. <form method="POST" {\$field.formhidden} action="{\$field.action}" onsubmit="{\$field.submit}">
  1295. {eyou:volist name="\$field.attrlist" id="attr"}
  1296. {\$attr.attr_name}:{\$attr.attr_html}
  1297. {/eyou:volist}
  1298. <div class='eyou_form_attr'>
  1299. <input class="eyou_form_btn" type="submit" value="提交"/>
  1300. </div>
  1301. {\$field.hidden}
  1302. </form>
  1303. {/eyou:form}
  1304. EOF;
  1305. $assign_data = [
  1306. 'content' => htmlspecialchars($content)
  1307. ];
  1308. $this->assign($assign_data);
  1309. return $this->fetch();
  1310. }
  1311. $this->error('数据不存在!');
  1312. }
  1313. }