11<?php
2+
23namespace plugin \admin \app \common ;
34
45use support \exception \BusinessException ;
@@ -45,19 +46,19 @@ public function js($indent = 0): string
4546 */
4647 protected function options ($ options ): array
4748 {
48- array_walk_recursive ($ options , function (&$ item , $ key ){
49+ array_walk_recursive ($ options , function (&$ item , $ key ) {
4950 if (is_string ($ item )) {
5051 $ item = htmlspecialchars ($ item );
5152 if ($ key === 'url ' ) {
5253 $ item = str_replace ('& ' , '& ' , $ item );
5354 }
5455 }
5556 });
56- $ field = $ options ['field ' ]?? '' ;
57+ $ field = $ options ['field ' ] ?? '' ;
5758 $ props = !empty ($ options ['props ' ]) ? $ options ['props ' ] : [];
58- $ verify_string = !empty ($ props ['lay-verify ' ]) ? ' lay-verify=" ' . $ props ['lay-verify ' ]. '" ' : '' ;
59+ $ verify_string = !empty ($ props ['lay-verify ' ]) ? ' lay-verify=" ' . $ props ['lay-verify ' ] . '" ' : '' ;
5960 $ required_string = strpos ($ verify_string , 'required ' ) ? ' required ' : '' ;
60- $ label = !empty ($ options ['label ' ]) ? '<label class="layui-form-label ' . $ required_string. '"> ' . $ options ['label ' ]. '</label> ' : '' ;
61+ $ label = !empty ($ options ['label ' ]) ? '<label class="layui-form-label ' . $ required_string . '"> ' . $ options ['label ' ] . '</label> ' : '' ;
6162 $ value = $ props ['value ' ] ?? '' ;
6263 $ class = $ props ['class ' ] ?? 'layui-input-block ' ;
6364
@@ -73,8 +74,8 @@ public function input($options)
7374 {
7475 [$ label , $ field , $ value , $ props , $ verify_string , $ required_string , $ class ] = $ this ->options ($ options );
7576
76- $ placeholder_string = !empty ($ props ['placeholder ' ]) ? ' placeholder=" ' . $ props ['placeholder ' ]. '" ' : '' ;
77- $ autocomplete_string = !empty ($ props ['autocomplete ' ]) ? ' autocomplete=" ' . $ props ['autocomplete ' ]. '" ' : '' ;
77+ $ placeholder_string = !empty ($ props ['placeholder ' ]) ? ' placeholder=" ' . $ props ['placeholder ' ] . '" ' : '' ;
78+ $ autocomplete_string = !empty ($ props ['autocomplete ' ]) ? ' autocomplete=" ' . $ props ['autocomplete ' ] . '" ' : '' ;
7879 $ disabled_string = !empty ($ props ['disabled ' ]) ? ' disabled ' : '' ;
7980 $ type = $ props ['type ' ] ?? 'text ' ;
8081
@@ -194,7 +195,7 @@ public function textArea($options)
194195 {
195196 [$ label , $ field , $ value , $ props , $ verify_string , $ required_string , $ class ] = $ this ->options ($ options );
196197
197- $ placeholder_string = !empty ($ props ['placeholder ' ]) ? ' placeholder=" ' . $ props ['placeholder ' ]. '" ' : '' ;
198+ $ placeholder_string = !empty ($ props ['placeholder ' ]) ? ' placeholder=" ' . $ props ['placeholder ' ] . '" ' : '' ;
198199 $ disabled_string = !empty ($ props ['disabled ' ]) ? ' disabled ' : '' ;
199200
200201 $ this ->htmlContent .= <<<EOF
@@ -218,7 +219,7 @@ public function richText($options)
218219 {
219220 [$ label , $ field , $ value , $ props , $ verify_string , $ required_string , $ class ] = $ this ->options ($ options );
220221
221- $ placeholder_string = !empty ($ props ['placeholder ' ]) ? ' placeholder=" ' . $ props ['placeholder ' ]. '" ' : '' ;
222+ $ placeholder_string = !empty ($ props ['placeholder ' ]) ? ' placeholder=" ' . $ props ['placeholder ' ] . '" ' : '' ;
222223 $ disabled_string = !empty ($ props ['disabled ' ]) ? ' disabled ' : '' ;
223224 $ id = $ field ;
224225
@@ -264,12 +265,12 @@ public function jsonEditor($options)
264265 {
265266 [$ label , $ field , $ value , $ props , $ verify_string , $ required_string , $ class ] = $ this ->options ($ options );
266267
267- $ placeholder_string = !empty ($ props ['placeholder ' ]) ? ' placeholder=" ' . $ props ['placeholder ' ]. '" ' : '' ;
268- $ autocomplete_string = !empty ($ props ['autocomplete ' ]) ? ' autocomplete=" ' . $ props ['autocomplete ' ]. '" ' : '' ;
268+ $ placeholder_string = !empty ($ props ['placeholder ' ]) ? ' placeholder=" ' . $ props ['placeholder ' ] . '" ' : '' ;
269+ $ autocomplete_string = !empty ($ props ['autocomplete ' ]) ? ' autocomplete=" ' . $ props ['autocomplete ' ] . '" ' : '' ;
269270 $ disabled_string = !empty ($ props ['disabled ' ]) ? ' disabled ' : '' ;
270271 $ type = $ props ['type ' ] ?? 'text ' ;
271- if (empty ($ value )){
272- $ value= '{} ' ;
272+ if (empty ($ value )) {
273+ $ value = '{} ' ;
273274 }
274275 $ this ->htmlContent .= <<<EOF
275276
@@ -368,6 +369,8 @@ public function uploadImage($options)
368369 [$ label , $ field , $ value , $ props , $ verify_string , $ required_string , $ class ] = $ this ->options ($ options );
369370 $ props ['acceptMime ' ] = $ props ['acceptMime ' ] ?? 'image/gif,image/jpeg,image/jpg,image/png ' ;
370371 $ props ['url ' ] = $ props ['url ' ] ?? '/app/admin/upload/image ' ;
372+ $ props ['multiple ' ] = $ props ['multiple ' ] ? 1 : 0 ;
373+
371374 $ id = $ this ->createId ($ field );
372375
373376 unset($ props ['lay-verify ' ]);
@@ -376,7 +379,8 @@ public function uploadImage($options)
376379 $ props = $ this ->prepareProps ($ props );
377380 $ options_string .= "\n" . $ this ->preparePropsToJsObject ($ props , 1 , true );
378381
379- $ this ->htmlContent .= <<<EOF
382+ if ($ props ['multiple ' ] == 0 ) {
383+ $ this ->htmlContent .= <<<EOF
380384
381385<div class="layui-form-item">
382386 $ label
@@ -393,7 +397,7 @@ public function uploadImage($options)
393397</div>
394398
395399EOF ;
396- $ this ->jsContent .= <<<EOF
400+ $ this ->jsContent .= <<<EOF
397401
398402// 字段 {$ options ['label ' ]} $ field
399403layui.use(["upload", "layer"], function() {
@@ -422,6 +426,123 @@ public function uploadImage($options)
422426});
423427
424428EOF ;
429+ } else {
430+ $ this ->htmlContent .= <<<EOF
431+
432+ <div class="layui-form-item">
433+ $ label
434+ <div class=" $ class">
435+
436+ <div class="layui-upload">
437+ <input type="text" class="uploader-list" style="display:none" name=" $ field" value=" $ value" id=" $ id"/>
438+ <blockquote class="layui-elem-quote layui-quote-nm" style="margin-top: 10px;">
439+ 预览图:
440+ <div class="layui-upload-list uploader-list" style="overflow: auto;" id="uploader-list- $ id">
441+ </div>
442+ </blockquote>
443+
444+ <button type="button" class="pear-btn pear-btn-primary pear-btn-sm" id="multi-upload- $ id" permission="app.admin.upload.image">
445+ <i class="layui-icon layui-icon-upload"></i>多图上传
446+ </button>
447+
448+ <button type="button" class="pear-btn pear-btn-primary pear-btn-sm" id="attachment-choose- $ id" permission="app.admin.upload.attachment">
449+ <i class="layui-icon layui-icon-align-left"></i>选择图片
450+ </button>
451+ </div>
452+ </div>
453+ </div>
454+
455+ EOF ;
456+ $ this ->jsContent .= <<<EOF
457+
458+ // 字段 {$ options ['label ' ]} $ field
459+ layui.use(["upload", "layer"], function() {
460+ var upload = layui.upload;
461+ var $ = layui.$;
462+ let multiple_images = layui.$("# $ id").attr("value").split(",");
463+
464+
465+ $("#attachment-choose- $ id").on("click", function() {
466+ parent.layer.open({
467+ type: 2,
468+ title: "选择附件",
469+ content: "/app/admin/upload/attachment?ext=jpg,jpeg,png,gif,bmp",
470+ area: ["95%", "90%"],
471+ success: function (layero, index) {
472+ parent.layui.$("#layui-layer" + index).data("callback", function (data) {
473+ //上传完毕
474+ $('#uploader-list- $ id').append(
475+ '<div class="file-iteme">' +
476+ '<div class="handle"><i class="layui-icon layui-icon-delete"></i></div>' +
477+ '<img src='+ data.url +' alt="'+ data.name +'" >' +
478+ '</div>'
479+ );
480+
481+ //追加图片成功追加文件名至图片容器
482+ multiple_images.push(data.url);
483+ $('# $ id').val(multiple_images);
484+ });
485+ }
486+ });
487+ });
488+
489+ upload.render({
490+ elem: '#multi-upload- $ id', $ options_string
491+ before: function(obj){
492+ layer.msg('图片上传中...', {
493+ icon: 16,
494+ shade: 0.01,
495+ time: 0
496+ })
497+ },
498+ done: function(res){
499+ layer.close(layer.msg());//关闭上传提示窗口
500+ //上传完毕
501+ $('#uploader-list- $ id').append(
502+ '<div class="file-iteme">' +
503+ '<div class="handle"><i class="layui-icon layui-icon-delete"></i></div>' +
504+ '<img src='+ res.data.url +' alt="'+ res.data.name +'" >' +
505+ '</div>'
506+ );
507+
508+ //追加图片成功追加文件名至图片容器
509+ multiple_images.push(res.data.url);
510+ $('# $ id').val(multiple_images);
511+ }
512+ });
513+
514+ //鼠标悬浮事件
515+ $(document).on("mouseenter mouseleave", ".file-iteme", function(event){
516+ if(event.type === "mouseenter"){
517+ //鼠标悬浮
518+ $(this).children(".info").fadeIn("fast");
519+ $(this).children(".handle").fadeIn("fast");
520+ }else if(event.type === "mouseleave") {
521+ //鼠标离开
522+ $(this).children(".info").hide();
523+ $(this).children(".handle").hide();
524+ }
525+ });
526+
527+ // 删除图片
528+ $(document).on("click", ".file-iteme .handle", function(event){
529+ var delImg = $(this).parent().children("img").attr("src")
530+ var index = multiple_images.indexOf(delImg);
531+ if (index !== -1) {
532+ multiple_images.splice(index, 1);
533+ }
534+ //重新赋值
535+ $('# $ id').val(multiple_images);
536+ //删除标签
537+ $(this).parent().remove();
538+ });
539+ //多图上传 end
540+
541+ });
542+
543+ EOF ;
544+ }
545+
425546
426547 }
427548
@@ -444,7 +565,7 @@ public function dateTimePicker($options)
444565 public function datePicker ($ options )
445566 {
446567 [$ label , $ field , $ value , $ props , $ verify_string , $ required_string , $ class ] = $ this ->options ($ options );
447- $ value_string = $ value ? ' value=" ' . $ value. '" ' : '' ;
568+ $ value_string = $ value ? ' value=" ' . $ value . '" ' : '' ;
448569 $ options_string = '' ;
449570 unset($ props ['required ' ], $ props ['lay-verify ' ], $ props ['value ' ]);
450571 $ props = $ this ->prepareProps ($ props );
@@ -463,7 +584,7 @@ public function datePicker($options)
463584EOF ;
464585 $ this ->jsContent .= <<<EOF
465586
466- // 字段 {$ options [" label " ]} $ field
587+ // 字段 {$ options [' label ' ]} $ field
467588layui.use(["laydate"], function() {
468589 layui.laydate.render({
469590 elem: "# $ id", $ options_string
@@ -548,7 +669,7 @@ public function iconPicker($options)
548669 {
549670 [$ label , $ field , $ value , $ props , $ verify_string , $ required_string , $ class ] = $ this ->options ($ options );
550671
551- $ value_string = $ value ? ' value=" ' . $ value. '" ' : '' ;
672+ $ value_string = $ value ? ' value=" ' . $ value . '" ' : '' ;
552673 $ id = $ this ->createId ($ field );
553674 $ options_string = '' ;
554675 $ props = $ this ->prepareProps ($ props );
@@ -647,7 +768,7 @@ public function selectMulti($options)
647768 {
648769 $ options ['props ' ]['toolbar ' ] = array_merge_recursive ([
649770 'show ' => true ,
650- 'list ' => [ 'ALL ' , 'CLEAR ' , 'REVERSE ' ]
771+ 'list ' => ['ALL ' , 'CLEAR ' , 'REVERSE ' ]
651772 ], $ options ['props ' ]['toolbar ' ] ?? []);
652773 $ this ->apiSelect ($ options );
653774 }
@@ -686,7 +807,7 @@ public function treeSelectMulti($options)
686807 '$expandedKeys ' => '$initValue ' ], $ options ['props ' ]['tree ' ] ?? []);
687808 $ options ['props ' ]['toolbar ' ] = array_merge_recursive ([
688809 '$show ' => true ,
689- '$list ' => [ 'ALL ' , 'CLEAR ' , 'REVERSE ' ]
810+ '$list ' => ['ALL ' , 'CLEAR ' , 'REVERSE ' ]
690811 ], $ options ['props ' ]['toolbar ' ] ?? []);
691812 $ this ->apiSelect ($ options );
692813 }
@@ -712,11 +833,11 @@ public function apiSelect($options)
712833 if (is_array ($ item )) {
713834 $ item = json_encode ($ item , JSON_UNESCAPED_UNICODE );
714835 $ item = preg_replace ('/"\$([^"]+)"/ ' , '$1 ' , $ item );
715- $ options_string .= "\n" . ($ url? ' ' : ' ' ). "$ key: $ item, " ;
836+ $ options_string .= "\n" . ($ url ? ' ' : ' ' ) . "$ key: $ item, " ;
716837 } else if (is_string ($ item )) {
717- $ options_string .= "\n" . ($ url? ' ' : ' ' ). "$ key: \"$ item \", " ;
838+ $ options_string .= "\n" . ($ url ? ' ' : ' ' ) . "$ key: \"$ item \", " ;
718839 } else {
719- $ options_string .= "\n" . ($ url? ' ' : ' ' ). "$ key: " . var_export ($ item , true ). " , " ;
840+ $ options_string .= "\n" . ($ url ? ' ' : ' ' ) . "$ key: " . var_export ($ item , true ) . ' , ' ;
720841 }
721842 }
722843
@@ -824,7 +945,7 @@ public static function buildForm($table, string $type = 'insert'): Layui
824945 if ($ filter == 'form_show ' && !$ columns [$ key ]['nullable ' ] && $ default === null && ($ field !== 'password ' || $ type === 'insert ' )) {
825946 if (!isset ($ props ['lay-verify ' ])) {
826947 $ props ['lay-verify ' ] = 'required ' ;
827- // 非类似字符串类型不允许传空
948+ // 非类似字符串类型不允许传空
828949 } elseif (!in_array ($ columns [$ key ]['type ' ], ['string ' , 'text ' , 'mediumText ' , 'longText ' , 'char ' , 'binary ' , 'json ' ])
829950 && strpos ($ props ['lay-verify ' ], 'required ' ) === false ) {
830951 $ props ['lay-verify ' ] = 'required| ' . $ props ['lay-verify ' ];
@@ -938,12 +1059,27 @@ public static function buildTable($table, int $indent = 0)
9381059EOF ;
9391060 break ;
9401061 case 'uploadimage ' :
941- $ templet = <<<EOF
1062+ $ props = Util::getControlProps ($ info ['control ' ], $ info ['control_args ' ]);
1063+ $ multiple = $ props ['multiple ' ] ?? 0 ;
1064+ if ($ multiple == 0 ) {
1065+ $ templet = <<<EOF
9421066
9431067 templet: function (d) {
9441068 return '<img src="'+encodeURI(d[' $ field'])+'" style="max-width:32px;max-height:32px;" alt="" />'
9451069 }
9461070EOF ;
1071+ } else {
1072+ $ templet = <<<EOF
1073+ templet: function (d) {
1074+ const images = d[' $ field'].split(',');
1075+ let html = '';
1076+ for (let img of images) {
1077+ html += '<img src="' + encodeURI(img.trim()) + '" style="max-width:32px;max-height:32px;" alt="" />';
1078+ }
1079+ return html;
1080+ }
1081+ EOF ;
1082+ }
9471083 break ;
9481084
9491085 }
@@ -961,7 +1097,7 @@ public static function buildTable($table, int $indent = 0)
9611097 $ options [$ option ['value ' ]] = $ option ['name ' ];
9621098 }
9631099 }
964- $ api_result .= "\napiResults[ \"$ field \"] = " . json_encode ($ options , JSON_UNESCAPED_UNICODE ) . " ; " ;
1100+ $ api_result .= "\napiResults[ \"$ field \"] = " . json_encode ($ options , JSON_UNESCAPED_UNICODE ) . ' ; ' ;
9651101 } else {
9661102 $ api_result .= "\napiResults[ \"$ field \"] = []; " ;
9671103 }
@@ -1122,12 +1258,12 @@ function travel(items) {
11221258 */
11231259 private function prepareProps ($ props )
11241260 {
1125- $ raw_list = ['true ' ,'false ' ,'null ' ,'undefined ' ];
1261+ $ raw_list = ['true ' , 'false ' , 'null ' , 'undefined ' ];
11261262 foreach ($ props as $ k => $ v ) {
11271263 if (is_array ($ v )) {
11281264 $ props [$ k ] = $ this ->prepareProps ($ v );
11291265 } elseif (!in_array ($ v , $ raw_list ) && !is_numeric ($ v )) {
1130- if (strpos ($ v , " # " ) === 0 ){
1266+ if (strpos ($ v , ' # ' ) === 0 ) {
11311267 $ props [$ k ] = substr ($ v , 1 );
11321268 } else {
11331269 $ props [$ k ] = "\"$ v \"" ;
@@ -1145,7 +1281,7 @@ private function preparePropsToJsObject($props, $indent = 0, $sub = false)
11451281 $ string .= "$ indent_string{ \n" ;
11461282 }
11471283 foreach ($ props as $ k => $ v ) {
1148- if (!preg_match (" #^[a-zA-Z0-9_]+$# " , $ k )) {
1284+ if (!preg_match (' #^[a-zA-Z0-9_]+$# ' , $ k )) {
11491285 $ k = "' $ k' " ;
11501286 }
11511287 if (is_array ($ v )) {
@@ -1157,7 +1293,7 @@ private function preparePropsToJsObject($props, $indent = 0, $sub = false)
11571293 if (!$ sub ) {
11581294 $ string .= "$ indent_string} \n" ;
11591295 }
1160- return trim ($ string ,"\n" );
1296+ return trim ($ string , "\n" );
11611297 }
11621298
11631299
0 commit comments