common.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. <?php
  2. use app\common\model\Category;
  3. use fast\Form;
  4. use fast\Tree;
  5. use think\Db;
  6. if (!function_exists('build_select')) {
  7. /**
  8. * 生成下拉列表
  9. * @param string $name
  10. * @param mixed $options
  11. * @param mixed $selected
  12. * @param mixed $attr
  13. * @return string
  14. */
  15. function build_select($name, $options, $selected = [], $attr = [])
  16. {
  17. $options = is_array($options) ? $options : explode(',', $options);
  18. $selected = is_array($selected) ? $selected : explode(',', $selected);
  19. return Form::select($name, $options, $selected, $attr);
  20. }
  21. }
  22. if (!function_exists('build_radios')) {
  23. /**
  24. * 生成单选按钮组
  25. * @param string $name
  26. * @param array $list
  27. * @param mixed $selected
  28. * @return string
  29. */
  30. function build_radios($name, $list = [], $selected = null)
  31. {
  32. $html = [];
  33. $selected = is_null($selected) ? key($list) : $selected;
  34. $selected = is_array($selected) ? $selected : explode(',', $selected);
  35. foreach ($list as $k => $v) {
  36. $html[] = sprintf(Form::label("{$name}-{$k}", "%s {$v}"), Form::radio($name, $k, in_array($k, $selected), ['id' => "{$name}-{$k}"]));
  37. }
  38. return '<div class="radio">' . implode(' ', $html) . '</div>';
  39. }
  40. }
  41. if (!function_exists('build_checkboxs')) {
  42. /**
  43. * 生成复选按钮组
  44. * @param string $name
  45. * @param array $list
  46. * @param mixed $selected
  47. * @return string
  48. */
  49. function build_checkboxs($name, $list = [], $selected = null)
  50. {
  51. $html = [];
  52. $selected = is_null($selected) ? [] : $selected;
  53. $selected = is_array($selected) ? $selected : explode(',', $selected);
  54. foreach ($list as $k => $v) {
  55. $html[] = sprintf(Form::label("{$name}-{$k}", "%s {$v}"), Form::checkbox($name, $k, in_array($k, $selected), ['id' => "{$name}-{$k}"]));
  56. }
  57. return '<div class="checkbox">' . implode(' ', $html) . '</div>';
  58. }
  59. }
  60. if (!function_exists('build_category_select')) {
  61. /**
  62. * 生成分类下拉列表框
  63. * @param string $name
  64. * @param string $type
  65. * @param mixed $selected
  66. * @param array $attr
  67. * @param array $header
  68. * @return string
  69. */
  70. function build_category_select($name, $type, $selected = null, $attr = [], $header = [])
  71. {
  72. $tree = Tree::instance();
  73. $tree->init(Category::getCategoryArray($type), 'pid');
  74. $categorylist = $tree->getTreeList($tree->getTreeArray(0), 'name');
  75. $categorydata = $header ? $header : [];
  76. foreach ($categorylist as $k => $v) {
  77. $categorydata[$v['id']] = $v['name'];
  78. }
  79. $attr = array_merge(['id' => "c-{$name}", 'class' => 'form-control selectpicker'], $attr);
  80. return build_select($name, $categorydata, $selected, $attr);
  81. }
  82. }
  83. if (!function_exists('build_toolbar')) {
  84. /**
  85. * 生成表格操作按钮栏
  86. * @param array $btns 按钮组
  87. * @param array $attr 按钮属性值
  88. * @return string
  89. */
  90. function build_toolbar($btns = null, $attr = [])
  91. {
  92. $auth = \app\admin\library\Auth::instance();
  93. $controller = str_replace('.', '/', strtolower(think\Request::instance()->controller()));
  94. $btns = $btns ? $btns : ['refresh', 'add', 'edit', 'del', 'import'];
  95. $btns = is_array($btns) ? $btns : explode(',', $btns);
  96. $index = array_search('delete', $btns);
  97. if ($index !== false) {
  98. $btns[$index] = 'del';
  99. }
  100. $btnAttr = [
  101. 'refresh' => ['javascript:;', 'btn btn-primary btn-refresh', 'fa fa-refresh', '', __('Refresh')],
  102. 'add' => ['javascript:;', 'btn btn-success btn-add', 'fa fa-plus', __('Add'), __('Add')],
  103. 'edit' => ['javascript:;', 'btn btn-success btn-edit btn-disabled disabled', 'fa fa-pencil', __('Edit'), __('Edit')],
  104. 'del' => ['javascript:;', 'btn btn-danger btn-del btn-disabled disabled', 'fa fa-trash', __('Delete'), __('Delete')],
  105. 'import' => ['javascript:;', 'btn btn-info btn-import', 'fa fa-upload', __('Import'), __('Import')],
  106. ];
  107. $btnAttr = array_merge($btnAttr, $attr);
  108. $html = [];
  109. foreach ($btns as $k => $v) {
  110. //如果未定义或没有权限
  111. if (!isset($btnAttr[$v]) || ($v !== 'refresh' && !$auth->check("{$controller}/{$v}"))) {
  112. continue;
  113. }
  114. list($href, $class, $icon, $text, $title) = $btnAttr[$v];
  115. //$extend = $v == 'import' ? 'id="btn-import-file" data-url="ajax/upload" data-mimetype="csv,xls,xlsx" data-multiple="false"' : '';
  116. //$html[] = '<a href="' . $href . '" class="' . $class . '" title="' . $title . '" ' . $extend . '><i class="' . $icon . '"></i> ' . $text . '</a>';
  117. if ($v == 'import') {
  118. $template = str_replace('/', '_', $controller);
  119. $download = '';
  120. if (file_exists("./template/{$template}.xlsx")) {
  121. $download .= "<li><a href=\"/template/{$template}.xlsx\" target=\"_blank\">XLSX模版</a></li>";
  122. }
  123. if (file_exists("./template/{$template}.xls")) {
  124. $download .= "<li><a href=\"/template/{$template}.xls\" target=\"_blank\">XLS模版</a></li>";
  125. }
  126. if (file_exists("./template/{$template}.csv")) {
  127. $download .= empty($download) ? '' : "<li class=\"divider\"></li>";
  128. $download .= "<li><a href=\"/template/{$template}.csv\" target=\"_blank\">CSV模版</a></li>";
  129. }
  130. $download .= empty($download) ? '' : "\n ";
  131. if (!empty($download)) {
  132. $html[] = <<<EOT
  133. <div class="btn-group">
  134. <button type="button" href="{$href}" class="btn btn-info btn-import" title="{$title}" id="btn-import-file" data-url="ajax/upload" data-mimetype="csv,xls,xlsx" data-multiple="false"><i class="{$icon}"></i> {$text}</button>
  135. <button type="button" class="btn btn-info dropdown-toggle" data-toggle="dropdown" title="下载批量导入模版">
  136. <span class="caret"></span>
  137. <span class="sr-only">Toggle Dropdown</span>
  138. </button>
  139. <ul class="dropdown-menu" role="menu">{$download}</ul>
  140. </div>
  141. EOT;
  142. } else {
  143. $html[] = '<a href="' . $href . '" class="' . $class . '" title="' . $title . '" id="btn-import-file" data-url="ajax/upload" data-mimetype="csv,xls,xlsx" data-multiple="false"><i class="' . $icon . '"></i> ' . $text . '</a>';
  144. }
  145. } else {
  146. $html[] = '<a href="' . $href . '" class="' . $class . '" title="' . $title . '"><i class="' . $icon . '"></i> ' . $text . '</a>';
  147. }
  148. }
  149. return implode(' ', $html);
  150. }
  151. }
  152. if (!function_exists('build_heading')) {
  153. /**
  154. * 生成页面Heading
  155. *
  156. * @param string $path 指定的path
  157. * @return string
  158. */
  159. function build_heading($path = null, $container = true)
  160. {
  161. $title = $content = '';
  162. if (is_null($path)) {
  163. $action = request()->action();
  164. $controller = str_replace('.', '/', request()->controller());
  165. $path = strtolower($controller . ($action && $action != 'index' ? '/' . $action : ''));
  166. }
  167. // 根据当前的URI自动匹配父节点的标题和备注
  168. $data = Db::name('auth_rule')->where('name', $path)->field('title,remark')->find();
  169. if ($data) {
  170. $title = __($data['title']);
  171. $content = __($data['remark']);
  172. }
  173. if (!$content) {
  174. return '';
  175. }
  176. $result = '<div class="panel-lead"><em>' . $title . '</em>' . $content . '</div>';
  177. if ($container) {
  178. $result = '<div class="panel-heading">' . $result . '</div>';
  179. }
  180. return $result;
  181. }
  182. }
  183. if (!function_exists('dd')) {
  184. function dd($data)
  185. {
  186. echo '<pre>';
  187. var_dump($data);
  188. die;
  189. }
  190. }
  191. if (!function_exists('getNewRand'))
  192. {
  193. /**
  194. * 获取字母数字随机数
  195. * @param int $len
  196. * @return string
  197. * @author matielong
  198. */
  199. function getNewRand($len = 4)
  200. {
  201. $chars_array = array(
  202. "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
  203. "A", "B", "C", "D", "E", "F", "G",
  204. "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R",
  205. "S", "T", "U", "V", "W", "X", "Y", "Z",
  206. );
  207. $charsLen = count($chars_array) - 1;
  208. $outputstr = "";
  209. for ($i=0; $i<$len; $i++)
  210. {
  211. $outputstr .= $chars_array[mt_rand(0, $charsLen)];
  212. }
  213. return $outputstr;
  214. }
  215. }
  216. if (!function_exists('ch2arr'))
  217. {
  218. /**
  219. * 字符串转换数组
  220. * @param $str
  221. * @return array
  222. */
  223. function ch2arr($str)
  224. {
  225. $length = mb_strlen($str, 'utf-8');
  226. $array = [];
  227. for ($i=0; $i<$length; $i++)
  228. $array[] = mb_substr($str, $i, 1, 'utf-8');
  229. return $array;
  230. }
  231. }
  232. if (!function_exists('exportOrderExcel')) {
  233. /**
  234. * execl数据导出
  235. * 应用场景:订单导出
  236. * @param string $title 模型名(如Member),用于导出生成文件名的前缀
  237. * @param array $cellName 表头及字段名
  238. * @param array $data 导出的表数据
  239. * 特殊处理:合并单元格需要先对数据进行处理
  240. * @throws PHPExcel_Exception
  241. * @throws PHPExcel_Reader_Exception
  242. * @throws PHPExcel_Writer_Exception
  243. */
  244. function exportOrderExcel($title,$cellName,$data)
  245. {
  246. //引入核心文件
  247. include EXTEND_PATH.'PHPExcel/PHPExcel.php';
  248. $objPHPExcel = new \PHPExcel();
  249. //定义配置
  250. $topNumber = 1;//表头有几行占用
  251. $xlsTitle = iconv('utf-8', 'gb2312', $title);//文件名称
  252. // $fileName = $title.date('_YmdHis');//文件名称
  253. $fileName = $title;//文件名称
  254. $cellKey = array(
  255. 'A','B','C','D','E','F','G','H','I','J','K','L','M',
  256. 'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
  257. 'AA','AB','AC','AD','AE','AF','AG','AH','AI','AJ','AK','AL','AM',
  258. 'AN','AO','AP','AQ','AR','AS','AT','AU','AV','AW','AX','AY','AZ'
  259. );
  260. //写在处理的前面(了解表格基本知识,已测试)
  261. // $objPHPExcel->getActiveSheet()->getDefaultRowDimension()->setRowHeight(20);//所有单元格(行)默认高度
  262. // $objPHPExcel->getActiveSheet()->getDefaultColumnDimension()->setWidth(20);//所有单元格(列)默认宽度
  263. // $objPHPExcel->getActiveSheet()->getRowDimension('1')->setRowHeight(30);//设置行高度
  264. // $objPHPExcel->getActiveSheet()->getColumnDimension('C')->setWidth(30);//设置列宽度
  265. // $objPHPExcel->getActiveSheet()->getStyle('A1')->getFont()->setSize(18);//设置文字大小
  266. // $objPHPExcel->getActiveSheet()->getStyle('A1')->getFont()->setBold(true);//设置是否加粗
  267. // $objPHPExcel->getActiveSheet()->getStyle('A1')->getFont()->getColor()->setARGB(PHPExcel_Style_Color::COLOR_WHITE);// 设置文字颜色
  268. // $objPHPExcel->getActiveSheet()->getStyle('A1')->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_CENTER);//设置文字居左(HORIZONTAL_LEFT,默认值)中(HORIZONTAL_CENTER)右(HORIZONTAL_RIGHT)
  269. // $objPHPExcel->getActiveSheet()->getStyle('A1')->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_CENTER);//垂直居中
  270. // $objPHPExcel->getActiveSheet()->getStyle('A1')->getFill()->setFillType(PHPExcel_Style_Fill::FILL_SOLID);//设置填充颜色
  271. // $objPHPExcel->getActiveSheet()->getStyle('A1')->getFill()->getStartColor()->setARGB('FF7F24');//设置填充颜色
  272. // $objPHPExcel->getActiveSheet()->getStyle('A1')->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_TEXT);
  273. //处理表头标题
  274. // $objPHPExcel->getActiveSheet()->mergeCells('A1:'.$cellKey[count($cellName)-1].'1');//合并单元格(如果要拆分单元格是需要先合并再拆分的,否则程序会报错)
  275. // $objPHPExcel->setActiveSheetIndex(0)->setCellValue('A1','订单信息');
  276. // $objPHPExcel->getActiveSheet()->getStyle('A1')->getFont()->setBold(true);
  277. // $objPHPExcel->getActiveSheet()->getStyle('A1')->getFont()->setSize(18);
  278. // $objPHPExcel->getActiveSheet()->getStyle('A1')->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_CENTER);
  279. // $objPHPExcel->getActiveSheet()->getStyle('A1')->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_CENTER);
  280. //处理表头
  281. foreach ($cellName as $k=>$v)
  282. {
  283. $objPHPExcel->setActiveSheetIndex(0)->setCellValue($cellKey[$k].$topNumber, $v[1]);//设置表头数据
  284. // $objPHPExcel->getActiveSheet()->freezePane($cellKey[$k].($topNumber+1));//冻结窗口
  285. $objPHPExcel->getActiveSheet()->getStyle($cellKey[$k].$topNumber)->getFont()->setBold(true);//设置是否加粗
  286. $objPHPExcel->getActiveSheet()->getStyle($cellKey[$k].$topNumber)->getFont()->getColor()->setARGB(PHPExcel_Style_Color::COLOR_RED);// 设置文字颜色
  287. $objPHPExcel->getActiveSheet()->getStyle($cellKey[$k].$topNumber)->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_CENTER);//垂直居中
  288. if($v[3] > 0)//大于0表示需要设置宽度
  289. {
  290. $objPHPExcel->getActiveSheet()->getColumnDimension($cellKey[$k])->setWidth($v[3]);//设置列宽度
  291. }
  292. }
  293. //处理数据
  294. foreach ($data as $k=>$v)
  295. {
  296. foreach ($cellName as $k1=>$v1)
  297. {
  298. $objPHPExcel->getActiveSheet()->setCellValue($cellKey[$k1].($k+1+$topNumber), $v[$v1[0]]);
  299. if(isset($v['end']) && $v['end'] > 0)
  300. {
  301. if($v1[2] == 1)//这里表示合并单元格
  302. {
  303. $objPHPExcel->getActiveSheet()->mergeCells($cellKey[$k1].$v['start'].':'.$cellKey[$k1].$v['end']);
  304. $objPHPExcel->getActiveSheet()->getStyle($cellKey[$k1].$v['start'])->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_CENTER);
  305. }
  306. }
  307. if($v1[4] != "" && in_array($v1[4], array("LEFT","CENTER","RIGHT")))
  308. {
  309. $v1[4] = eval('return PHPExcel_Style_Alignment::HORIZONTAL_'.$v1[4].';');
  310. //这里也可以直接传常量定义的值,即left,center,right;小写的strtolower
  311. $objPHPExcel->getActiveSheet()->getStyle($cellKey[$k1].($k+1+$topNumber))->getAlignment()->setHorizontal($v1[4]);
  312. }
  313. }
  314. }
  315. ob_end_clean();//解决乱码核心 就在此处添加此函数
  316. //导出execl
  317. header('pragma:public');
  318. header('Content-type:application/vnd.ms-excel;charset=utf-8;name="'.$xlsTitle.'.xlsx"');
  319. header("Content-Disposition:attachment;filename=$fileName.xlsx");//attachment新窗口打印inline本窗口打印
  320. $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
  321. $objWriter->save('php://output');
  322. exit;
  323. }
  324. }