commit
05bc5e4a94
1460 changed files with 252185 additions and 0 deletions
@ -0,0 +1,870 @@ |
|||
[*] |
|||
charset = utf-8 |
|||
end_of_line = crlf |
|||
indent_size = 4 |
|||
indent_style = space |
|||
insert_final_newline = false |
|||
max_line_length = 120 |
|||
tab_width = 4 |
|||
ij_continuation_indent_size = 8 |
|||
ij_formatter_off_tag = @formatter:off |
|||
ij_formatter_on_tag = @formatter:on |
|||
ij_formatter_tags_enabled = false |
|||
ij_smart_tabs = false |
|||
ij_visual_guides = none |
|||
ij_wrap_on_typing = false |
|||
|
|||
[*.blade.php] |
|||
ij_blade_keep_indents_on_empty_lines = false |
|||
|
|||
[*.css] |
|||
ij_css_align_closing_brace_with_properties = false |
|||
ij_css_blank_lines_around_nested_selector = 1 |
|||
ij_css_blank_lines_between_blocks = 1 |
|||
ij_css_brace_placement = end_of_line |
|||
ij_css_enforce_quotes_on_format = false |
|||
ij_css_hex_color_long_format = false |
|||
ij_css_hex_color_lower_case = false |
|||
ij_css_hex_color_short_format = false |
|||
ij_css_hex_color_upper_case = false |
|||
ij_css_keep_blank_lines_in_code = 2 |
|||
ij_css_keep_indents_on_empty_lines = false |
|||
ij_css_keep_single_line_blocks = false |
|||
ij_css_properties_order = font,font-family,font-size,font-weight,font-style,font-variant,font-size-adjust,font-stretch,line-height,position,z-index,top,right,bottom,left,display,visibility,float,clear,overflow,overflow-x,overflow-y,clip,zoom,align-content,align-items,align-self,flex,flex-flow,flex-basis,flex-direction,flex-grow,flex-shrink,flex-wrap,justify-content,order,box-sizing,width,min-width,max-width,height,min-height,max-height,margin,margin-top,margin-right,margin-bottom,margin-left,padding,padding-top,padding-right,padding-bottom,padding-left,table-layout,empty-cells,caption-side,border-spacing,border-collapse,list-style,list-style-position,list-style-type,list-style-image,content,quotes,counter-reset,counter-increment,resize,cursor,user-select,nav-index,nav-up,nav-right,nav-down,nav-left,transition,transition-delay,transition-timing-function,transition-duration,transition-property,transform,transform-origin,animation,animation-name,animation-duration,animation-play-state,animation-timing-function,animation-delay,animation-iteration-count,animation-direction,text-align,text-align-last,vertical-align,white-space,text-decoration,text-emphasis,text-emphasis-color,text-emphasis-style,text-emphasis-position,text-indent,text-justify,letter-spacing,word-spacing,text-outline,text-transform,text-wrap,text-overflow,text-overflow-ellipsis,text-overflow-mode,word-wrap,word-break,tab-size,hyphens,pointer-events,opacity,color,border,border-width,border-style,border-color,border-top,border-top-width,border-top-style,border-top-color,border-right,border-right-width,border-right-style,border-right-color,border-bottom,border-bottom-width,border-bottom-style,border-bottom-color,border-left,border-left-width,border-left-style,border-left-color,border-radius,border-top-left-radius,border-top-right-radius,border-bottom-right-radius,border-bottom-left-radius,border-image,border-image-source,border-image-slice,border-image-width,border-image-outset,border-image-repeat,outline,outline-width,outline-style,outline-color,outline-offset,background,background-color,background-image,background-repeat,background-attachment,background-position,background-position-x,background-position-y,background-clip,background-origin,background-size,box-decoration-break,box-shadow,text-shadow |
|||
ij_css_space_after_colon = true |
|||
ij_css_space_before_opening_brace = true |
|||
ij_css_use_double_quotes = true |
|||
ij_css_value_alignment = do_not_align |
|||
|
|||
[*.feature] |
|||
indent_size = 2 |
|||
ij_gherkin_keep_indents_on_empty_lines = false |
|||
|
|||
[*.haml] |
|||
indent_size = 2 |
|||
ij_haml_keep_indents_on_empty_lines = false |
|||
|
|||
[*.less] |
|||
indent_size = 2 |
|||
ij_less_align_closing_brace_with_properties = false |
|||
ij_less_blank_lines_around_nested_selector = 1 |
|||
ij_less_blank_lines_between_blocks = 1 |
|||
ij_less_brace_placement = 0 |
|||
ij_less_enforce_quotes_on_format = false |
|||
ij_less_hex_color_long_format = false |
|||
ij_less_hex_color_lower_case = false |
|||
ij_less_hex_color_short_format = false |
|||
ij_less_hex_color_upper_case = false |
|||
ij_less_keep_blank_lines_in_code = 2 |
|||
ij_less_keep_indents_on_empty_lines = false |
|||
ij_less_keep_single_line_blocks = false |
|||
ij_less_properties_order = font,font-family,font-size,font-weight,font-style,font-variant,font-size-adjust,font-stretch,line-height,position,z-index,top,right,bottom,left,display,visibility,float,clear,overflow,overflow-x,overflow-y,clip,zoom,align-content,align-items,align-self,flex,flex-flow,flex-basis,flex-direction,flex-grow,flex-shrink,flex-wrap,justify-content,order,box-sizing,width,min-width,max-width,height,min-height,max-height,margin,margin-top,margin-right,margin-bottom,margin-left,padding,padding-top,padding-right,padding-bottom,padding-left,table-layout,empty-cells,caption-side,border-spacing,border-collapse,list-style,list-style-position,list-style-type,list-style-image,content,quotes,counter-reset,counter-increment,resize,cursor,user-select,nav-index,nav-up,nav-right,nav-down,nav-left,transition,transition-delay,transition-timing-function,transition-duration,transition-property,transform,transform-origin,animation,animation-name,animation-duration,animation-play-state,animation-timing-function,animation-delay,animation-iteration-count,animation-direction,text-align,text-align-last,vertical-align,white-space,text-decoration,text-emphasis,text-emphasis-color,text-emphasis-style,text-emphasis-position,text-indent,text-justify,letter-spacing,word-spacing,text-outline,text-transform,text-wrap,text-overflow,text-overflow-ellipsis,text-overflow-mode,word-wrap,word-break,tab-size,hyphens,pointer-events,opacity,color,border,border-width,border-style,border-color,border-top,border-top-width,border-top-style,border-top-color,border-right,border-right-width,border-right-style,border-right-color,border-bottom,border-bottom-width,border-bottom-style,border-bottom-color,border-left,border-left-width,border-left-style,border-left-color,border-radius,border-top-left-radius,border-top-right-radius,border-bottom-right-radius,border-bottom-left-radius,border-image,border-image-source,border-image-slice,border-image-width,border-image-outset,border-image-repeat,outline,outline-width,outline-style,outline-color,outline-offset,background,background-color,background-image,background-repeat,background-attachment,background-position,background-position-x,background-position-y,background-clip,background-origin,background-size,box-decoration-break,box-shadow,text-shadow |
|||
ij_less_space_after_colon = true |
|||
ij_less_space_before_opening_brace = true |
|||
ij_less_use_double_quotes = true |
|||
ij_less_value_alignment = 0 |
|||
|
|||
[*.sass] |
|||
indent_size = 2 |
|||
ij_sass_align_closing_brace_with_properties = false |
|||
ij_sass_blank_lines_around_nested_selector = 1 |
|||
ij_sass_blank_lines_between_blocks = 1 |
|||
ij_sass_brace_placement = 0 |
|||
ij_sass_enforce_quotes_on_format = false |
|||
ij_sass_hex_color_long_format = false |
|||
ij_sass_hex_color_lower_case = false |
|||
ij_sass_hex_color_short_format = false |
|||
ij_sass_hex_color_upper_case = false |
|||
ij_sass_keep_blank_lines_in_code = 2 |
|||
ij_sass_keep_indents_on_empty_lines = false |
|||
ij_sass_keep_single_line_blocks = false |
|||
ij_sass_properties_order = font,font-family,font-size,font-weight,font-style,font-variant,font-size-adjust,font-stretch,line-height,position,z-index,top,right,bottom,left,display,visibility,float,clear,overflow,overflow-x,overflow-y,clip,zoom,align-content,align-items,align-self,flex,flex-flow,flex-basis,flex-direction,flex-grow,flex-shrink,flex-wrap,justify-content,order,box-sizing,width,min-width,max-width,height,min-height,max-height,margin,margin-top,margin-right,margin-bottom,margin-left,padding,padding-top,padding-right,padding-bottom,padding-left,table-layout,empty-cells,caption-side,border-spacing,border-collapse,list-style,list-style-position,list-style-type,list-style-image,content,quotes,counter-reset,counter-increment,resize,cursor,user-select,nav-index,nav-up,nav-right,nav-down,nav-left,transition,transition-delay,transition-timing-function,transition-duration,transition-property,transform,transform-origin,animation,animation-name,animation-duration,animation-play-state,animation-timing-function,animation-delay,animation-iteration-count,animation-direction,text-align,text-align-last,vertical-align,white-space,text-decoration,text-emphasis,text-emphasis-color,text-emphasis-style,text-emphasis-position,text-indent,text-justify,letter-spacing,word-spacing,text-outline,text-transform,text-wrap,text-overflow,text-overflow-ellipsis,text-overflow-mode,word-wrap,word-break,tab-size,hyphens,pointer-events,opacity,color,border,border-width,border-style,border-color,border-top,border-top-width,border-top-style,border-top-color,border-right,border-right-width,border-right-style,border-right-color,border-bottom,border-bottom-width,border-bottom-style,border-bottom-color,border-left,border-left-width,border-left-style,border-left-color,border-radius,border-top-left-radius,border-top-right-radius,border-bottom-right-radius,border-bottom-left-radius,border-image,border-image-source,border-image-slice,border-image-width,border-image-outset,border-image-repeat,outline,outline-width,outline-style,outline-color,outline-offset,background,background-color,background-image,background-repeat,background-attachment,background-position,background-position-x,background-position-y,background-clip,background-origin,background-size,box-decoration-break,box-shadow,text-shadow |
|||
ij_sass_space_after_colon = true |
|||
ij_sass_space_before_opening_brace = true |
|||
ij_sass_use_double_quotes = true |
|||
ij_sass_value_alignment = 0 |
|||
|
|||
[*.scss] |
|||
indent_size = 2 |
|||
ij_scss_align_closing_brace_with_properties = false |
|||
ij_scss_blank_lines_around_nested_selector = 1 |
|||
ij_scss_blank_lines_between_blocks = 1 |
|||
ij_scss_brace_placement = 0 |
|||
ij_scss_enforce_quotes_on_format = false |
|||
ij_scss_hex_color_long_format = false |
|||
ij_scss_hex_color_lower_case = false |
|||
ij_scss_hex_color_short_format = false |
|||
ij_scss_hex_color_upper_case = false |
|||
ij_scss_keep_blank_lines_in_code = 2 |
|||
ij_scss_keep_indents_on_empty_lines = false |
|||
ij_scss_keep_single_line_blocks = false |
|||
ij_scss_properties_order = font,font-family,font-size,font-weight,font-style,font-variant,font-size-adjust,font-stretch,line-height,position,z-index,top,right,bottom,left,display,visibility,float,clear,overflow,overflow-x,overflow-y,clip,zoom,align-content,align-items,align-self,flex,flex-flow,flex-basis,flex-direction,flex-grow,flex-shrink,flex-wrap,justify-content,order,box-sizing,width,min-width,max-width,height,min-height,max-height,margin,margin-top,margin-right,margin-bottom,margin-left,padding,padding-top,padding-right,padding-bottom,padding-left,table-layout,empty-cells,caption-side,border-spacing,border-collapse,list-style,list-style-position,list-style-type,list-style-image,content,quotes,counter-reset,counter-increment,resize,cursor,user-select,nav-index,nav-up,nav-right,nav-down,nav-left,transition,transition-delay,transition-timing-function,transition-duration,transition-property,transform,transform-origin,animation,animation-name,animation-duration,animation-play-state,animation-timing-function,animation-delay,animation-iteration-count,animation-direction,text-align,text-align-last,vertical-align,white-space,text-decoration,text-emphasis,text-emphasis-color,text-emphasis-style,text-emphasis-position,text-indent,text-justify,letter-spacing,word-spacing,text-outline,text-transform,text-wrap,text-overflow,text-overflow-ellipsis,text-overflow-mode,word-wrap,word-break,tab-size,hyphens,pointer-events,opacity,color,border,border-width,border-style,border-color,border-top,border-top-width,border-top-style,border-top-color,border-right,border-right-width,border-right-style,border-right-color,border-bottom,border-bottom-width,border-bottom-style,border-bottom-color,border-left,border-left-width,border-left-style,border-left-color,border-radius,border-top-left-radius,border-top-right-radius,border-bottom-right-radius,border-bottom-left-radius,border-image,border-image-source,border-image-slice,border-image-width,border-image-outset,border-image-repeat,outline,outline-width,outline-style,outline-color,outline-offset,background,background-color,background-image,background-repeat,background-attachment,background-position,background-position-x,background-position-y,background-clip,background-origin,background-size,box-decoration-break,box-shadow,text-shadow |
|||
ij_scss_space_after_colon = true |
|||
ij_scss_space_before_opening_brace = true |
|||
ij_scss_use_double_quotes = true |
|||
ij_scss_value_alignment = 0 |
|||
|
|||
[*.twig] |
|||
ij_twig_keep_indents_on_empty_lines = false |
|||
ij_twig_spaces_inside_comments_delimiters = true |
|||
ij_twig_spaces_inside_delimiters = true |
|||
ij_twig_spaces_inside_variable_delimiters = true |
|||
|
|||
[*.vue] |
|||
indent_size = 2 |
|||
tab_width = 2 |
|||
ij_continuation_indent_size = 4 |
|||
ij_vue_indent_children_of_top_level = template |
|||
ij_vue_interpolation_new_line_after_start_delimiter = true |
|||
ij_vue_interpolation_new_line_before_end_delimiter = true |
|||
ij_vue_interpolation_wrap = off |
|||
ij_vue_keep_indents_on_empty_lines = false |
|||
ij_vue_spaces_within_interpolation_expressions = true |
|||
ij_vue_uniform_indent = true |
|||
|
|||
[.editorconfig] |
|||
ij_editorconfig_align_group_field_declarations = false |
|||
ij_editorconfig_space_after_colon = false |
|||
ij_editorconfig_space_after_comma = true |
|||
ij_editorconfig_space_before_colon = false |
|||
ij_editorconfig_space_before_comma = false |
|||
ij_editorconfig_spaces_around_assignment_operators = true |
|||
|
|||
[{*.ant,*.fxml,*.jhm,*.jnlp,*.jrxml,*.rng,*.tld,*.wsdl,*.xml,*.xsd,*.xsl,*.xslt,*.xul,phpunit.xml.dist}] |
|||
ij_xml_align_attributes = true |
|||
ij_xml_align_text = false |
|||
ij_xml_attribute_wrap = normal |
|||
ij_xml_block_comment_at_first_column = true |
|||
ij_xml_keep_blank_lines = 2 |
|||
ij_xml_keep_indents_on_empty_lines = false |
|||
ij_xml_keep_line_breaks = true |
|||
ij_xml_keep_line_breaks_in_text = true |
|||
ij_xml_keep_whitespaces = false |
|||
ij_xml_keep_whitespaces_around_cdata = preserve |
|||
ij_xml_keep_whitespaces_inside_cdata = false |
|||
ij_xml_line_comment_at_first_column = true |
|||
ij_xml_space_after_tag_name = false |
|||
ij_xml_space_around_equals_in_attribute = false |
|||
ij_xml_space_inside_empty_tag = false |
|||
ij_xml_text_wrap = normal |
|||
|
|||
[{*.ats,*.ts}] |
|||
ij_continuation_indent_size = 4 |
|||
ij_typescript_align_imports = false |
|||
ij_typescript_align_multiline_array_initializer_expression = false |
|||
ij_typescript_align_multiline_binary_operation = false |
|||
ij_typescript_align_multiline_chained_methods = false |
|||
ij_typescript_align_multiline_extends_list = false |
|||
ij_typescript_align_multiline_for = true |
|||
ij_typescript_align_multiline_parameters = true |
|||
ij_typescript_align_multiline_parameters_in_calls = false |
|||
ij_typescript_align_multiline_ternary_operation = false |
|||
ij_typescript_align_object_properties = 0 |
|||
ij_typescript_align_union_types = false |
|||
ij_typescript_align_var_statements = 0 |
|||
ij_typescript_array_initializer_new_line_after_left_brace = false |
|||
ij_typescript_array_initializer_right_brace_on_new_line = false |
|||
ij_typescript_array_initializer_wrap = off |
|||
ij_typescript_assignment_wrap = off |
|||
ij_typescript_binary_operation_sign_on_next_line = false |
|||
ij_typescript_binary_operation_wrap = off |
|||
ij_typescript_blacklist_imports = rxjs/Rx,node_modules/**,**/node_modules/**,@angular/material,@angular/material/typings/** |
|||
ij_typescript_blank_lines_after_imports = 1 |
|||
ij_typescript_blank_lines_around_class = 1 |
|||
ij_typescript_blank_lines_around_field = 0 |
|||
ij_typescript_blank_lines_around_field_in_interface = 0 |
|||
ij_typescript_blank_lines_around_function = 1 |
|||
ij_typescript_blank_lines_around_method = 1 |
|||
ij_typescript_blank_lines_around_method_in_interface = 1 |
|||
ij_typescript_block_brace_style = end_of_line |
|||
ij_typescript_call_parameters_new_line_after_left_paren = false |
|||
ij_typescript_call_parameters_right_paren_on_new_line = false |
|||
ij_typescript_call_parameters_wrap = off |
|||
ij_typescript_catch_on_new_line = false |
|||
ij_typescript_chained_call_dot_on_new_line = true |
|||
ij_typescript_class_brace_style = end_of_line |
|||
ij_typescript_comma_on_new_line = false |
|||
ij_typescript_do_while_brace_force = never |
|||
ij_typescript_else_on_new_line = false |
|||
ij_typescript_enforce_trailing_comma = keep |
|||
ij_typescript_extends_keyword_wrap = off |
|||
ij_typescript_extends_list_wrap = off |
|||
ij_typescript_field_prefix = _ |
|||
ij_typescript_file_name_style = relaxed |
|||
ij_typescript_finally_on_new_line = false |
|||
ij_typescript_for_brace_force = never |
|||
ij_typescript_for_statement_new_line_after_left_paren = false |
|||
ij_typescript_for_statement_right_paren_on_new_line = false |
|||
ij_typescript_for_statement_wrap = off |
|||
ij_typescript_force_quote_style = false |
|||
ij_typescript_force_semicolon_style = false |
|||
ij_typescript_function_expression_brace_style = end_of_line |
|||
ij_typescript_if_brace_force = never |
|||
ij_typescript_import_merge_members = global |
|||
ij_typescript_import_prefer_absolute_path = global |
|||
ij_typescript_import_sort_members = true |
|||
ij_typescript_import_sort_module_name = false |
|||
ij_typescript_import_use_node_resolution = true |
|||
ij_typescript_imports_wrap = on_every_item |
|||
ij_typescript_indent_case_from_switch = true |
|||
ij_typescript_indent_chained_calls = true |
|||
ij_typescript_indent_package_children = 0 |
|||
ij_typescript_jsdoc_include_types = false |
|||
ij_typescript_jsx_attribute_value = braces |
|||
ij_typescript_keep_blank_lines_in_code = 2 |
|||
ij_typescript_keep_first_column_comment = true |
|||
ij_typescript_keep_indents_on_empty_lines = false |
|||
ij_typescript_keep_line_breaks = true |
|||
ij_typescript_keep_simple_blocks_in_one_line = false |
|||
ij_typescript_keep_simple_methods_in_one_line = false |
|||
ij_typescript_line_comment_add_space = true |
|||
ij_typescript_line_comment_at_first_column = false |
|||
ij_typescript_method_brace_style = end_of_line |
|||
ij_typescript_method_call_chain_wrap = off |
|||
ij_typescript_method_parameters_new_line_after_left_paren = false |
|||
ij_typescript_method_parameters_right_paren_on_new_line = false |
|||
ij_typescript_method_parameters_wrap = off |
|||
ij_typescript_object_literal_wrap = on_every_item |
|||
ij_typescript_parentheses_expression_new_line_after_left_paren = false |
|||
ij_typescript_parentheses_expression_right_paren_on_new_line = false |
|||
ij_typescript_place_assignment_sign_on_next_line = false |
|||
ij_typescript_prefer_as_type_cast = false |
|||
ij_typescript_prefer_explicit_types_function_expression_returns = false |
|||
ij_typescript_prefer_explicit_types_function_returns = false |
|||
ij_typescript_prefer_explicit_types_vars_fields = false |
|||
ij_typescript_prefer_parameters_wrap = false |
|||
ij_typescript_reformat_c_style_comments = false |
|||
ij_typescript_space_after_colon = true |
|||
ij_typescript_space_after_comma = true |
|||
ij_typescript_space_after_dots_in_rest_parameter = false |
|||
ij_typescript_space_after_generator_mult = true |
|||
ij_typescript_space_after_property_colon = true |
|||
ij_typescript_space_after_quest = true |
|||
ij_typescript_space_after_type_colon = true |
|||
ij_typescript_space_after_unary_not = false |
|||
ij_typescript_space_before_async_arrow_lparen = true |
|||
ij_typescript_space_before_catch_keyword = true |
|||
ij_typescript_space_before_catch_left_brace = true |
|||
ij_typescript_space_before_catch_parentheses = true |
|||
ij_typescript_space_before_class_lbrace = true |
|||
ij_typescript_space_before_class_left_brace = true |
|||
ij_typescript_space_before_colon = true |
|||
ij_typescript_space_before_comma = false |
|||
ij_typescript_space_before_do_left_brace = true |
|||
ij_typescript_space_before_else_keyword = true |
|||
ij_typescript_space_before_else_left_brace = true |
|||
ij_typescript_space_before_finally_keyword = true |
|||
ij_typescript_space_before_finally_left_brace = true |
|||
ij_typescript_space_before_for_left_brace = true |
|||
ij_typescript_space_before_for_parentheses = true |
|||
ij_typescript_space_before_for_semicolon = false |
|||
ij_typescript_space_before_function_left_parenth = true |
|||
ij_typescript_space_before_generator_mult = false |
|||
ij_typescript_space_before_if_left_brace = true |
|||
ij_typescript_space_before_if_parentheses = true |
|||
ij_typescript_space_before_method_call_parentheses = false |
|||
ij_typescript_space_before_method_left_brace = true |
|||
ij_typescript_space_before_method_parentheses = false |
|||
ij_typescript_space_before_property_colon = false |
|||
ij_typescript_space_before_quest = true |
|||
ij_typescript_space_before_switch_left_brace = true |
|||
ij_typescript_space_before_switch_parentheses = true |
|||
ij_typescript_space_before_try_left_brace = true |
|||
ij_typescript_space_before_type_colon = false |
|||
ij_typescript_space_before_unary_not = false |
|||
ij_typescript_space_before_while_keyword = true |
|||
ij_typescript_space_before_while_left_brace = true |
|||
ij_typescript_space_before_while_parentheses = true |
|||
ij_typescript_spaces_around_additive_operators = true |
|||
ij_typescript_spaces_around_arrow_function_operator = true |
|||
ij_typescript_spaces_around_assignment_operators = true |
|||
ij_typescript_spaces_around_bitwise_operators = true |
|||
ij_typescript_spaces_around_equality_operators = true |
|||
ij_typescript_spaces_around_logical_operators = true |
|||
ij_typescript_spaces_around_multiplicative_operators = true |
|||
ij_typescript_spaces_around_relational_operators = true |
|||
ij_typescript_spaces_around_shift_operators = true |
|||
ij_typescript_spaces_around_unary_operator = false |
|||
ij_typescript_spaces_within_array_initializer_brackets = false |
|||
ij_typescript_spaces_within_brackets = false |
|||
ij_typescript_spaces_within_catch_parentheses = false |
|||
ij_typescript_spaces_within_for_parentheses = false |
|||
ij_typescript_spaces_within_if_parentheses = false |
|||
ij_typescript_spaces_within_imports = false |
|||
ij_typescript_spaces_within_interpolation_expressions = false |
|||
ij_typescript_spaces_within_method_call_parentheses = false |
|||
ij_typescript_spaces_within_method_parentheses = false |
|||
ij_typescript_spaces_within_object_literal_braces = false |
|||
ij_typescript_spaces_within_object_type_braces = true |
|||
ij_typescript_spaces_within_parentheses = false |
|||
ij_typescript_spaces_within_switch_parentheses = false |
|||
ij_typescript_spaces_within_type_assertion = false |
|||
ij_typescript_spaces_within_union_types = true |
|||
ij_typescript_spaces_within_while_parentheses = false |
|||
ij_typescript_special_else_if_treatment = true |
|||
ij_typescript_ternary_operation_signs_on_next_line = false |
|||
ij_typescript_ternary_operation_wrap = off |
|||
ij_typescript_union_types_wrap = on_every_item |
|||
ij_typescript_use_chained_calls_group_indents = false |
|||
ij_typescript_use_double_quotes = true |
|||
ij_typescript_use_explicit_js_extension = global |
|||
ij_typescript_use_path_mapping = always |
|||
ij_typescript_use_public_modifier = false |
|||
ij_typescript_use_semicolon_after_statement = true |
|||
ij_typescript_var_declaration_wrap = normal |
|||
ij_typescript_while_brace_force = never |
|||
ij_typescript_while_on_new_line = false |
|||
ij_typescript_wrap_comments = false |
|||
|
|||
[{*.bash,*.sh,*.zsh}] |
|||
indent_size = 2 |
|||
tab_width = 2 |
|||
ij_shell_binary_ops_start_line = false |
|||
ij_shell_keep_column_alignment_padding = false |
|||
ij_shell_minify_program = false |
|||
ij_shell_redirect_followed_by_space = false |
|||
ij_shell_switch_cases_indented = false |
|||
ij_shell_use_unix_line_separator = true |
|||
|
|||
[{*.cjs,*.js}] |
|||
ij_continuation_indent_size = 4 |
|||
ij_javascript_align_imports = false |
|||
ij_javascript_align_multiline_array_initializer_expression = false |
|||
ij_javascript_align_multiline_binary_operation = false |
|||
ij_javascript_align_multiline_chained_methods = false |
|||
ij_javascript_align_multiline_extends_list = false |
|||
ij_javascript_align_multiline_for = true |
|||
ij_javascript_align_multiline_parameters = true |
|||
ij_javascript_align_multiline_parameters_in_calls = false |
|||
ij_javascript_align_multiline_ternary_operation = false |
|||
ij_javascript_align_object_properties = 0 |
|||
ij_javascript_align_union_types = false |
|||
ij_javascript_align_var_statements = 0 |
|||
ij_javascript_array_initializer_new_line_after_left_brace = false |
|||
ij_javascript_array_initializer_right_brace_on_new_line = false |
|||
ij_javascript_array_initializer_wrap = off |
|||
ij_javascript_assignment_wrap = off |
|||
ij_javascript_binary_operation_sign_on_next_line = false |
|||
ij_javascript_binary_operation_wrap = off |
|||
ij_javascript_blacklist_imports = rxjs/Rx,node_modules/**,**/node_modules/**,@angular/material,@angular/material/typings/** |
|||
ij_javascript_blank_lines_after_imports = 1 |
|||
ij_javascript_blank_lines_around_class = 1 |
|||
ij_javascript_blank_lines_around_field = 0 |
|||
ij_javascript_blank_lines_around_function = 1 |
|||
ij_javascript_blank_lines_around_method = 1 |
|||
ij_javascript_block_brace_style = end_of_line |
|||
ij_javascript_call_parameters_new_line_after_left_paren = false |
|||
ij_javascript_call_parameters_right_paren_on_new_line = false |
|||
ij_javascript_call_parameters_wrap = off |
|||
ij_javascript_catch_on_new_line = false |
|||
ij_javascript_chained_call_dot_on_new_line = true |
|||
ij_javascript_class_brace_style = end_of_line |
|||
ij_javascript_comma_on_new_line = false |
|||
ij_javascript_do_while_brace_force = never |
|||
ij_javascript_else_on_new_line = false |
|||
ij_javascript_enforce_trailing_comma = keep |
|||
ij_javascript_extends_keyword_wrap = off |
|||
ij_javascript_extends_list_wrap = off |
|||
ij_javascript_field_prefix = _ |
|||
ij_javascript_file_name_style = relaxed |
|||
ij_javascript_finally_on_new_line = false |
|||
ij_javascript_for_brace_force = never |
|||
ij_javascript_for_statement_new_line_after_left_paren = false |
|||
ij_javascript_for_statement_right_paren_on_new_line = false |
|||
ij_javascript_for_statement_wrap = off |
|||
ij_javascript_force_quote_style = false |
|||
ij_javascript_force_semicolon_style = false |
|||
ij_javascript_function_expression_brace_style = end_of_line |
|||
ij_javascript_if_brace_force = never |
|||
ij_javascript_import_merge_members = global |
|||
ij_javascript_import_prefer_absolute_path = global |
|||
ij_javascript_import_sort_members = true |
|||
ij_javascript_import_sort_module_name = false |
|||
ij_javascript_import_use_node_resolution = true |
|||
ij_javascript_imports_wrap = on_every_item |
|||
ij_javascript_indent_case_from_switch = true |
|||
ij_javascript_indent_chained_calls = true |
|||
ij_javascript_indent_package_children = 0 |
|||
ij_javascript_jsx_attribute_value = braces |
|||
ij_javascript_keep_blank_lines_in_code = 2 |
|||
ij_javascript_keep_first_column_comment = true |
|||
ij_javascript_keep_indents_on_empty_lines = false |
|||
ij_javascript_keep_line_breaks = true |
|||
ij_javascript_keep_simple_blocks_in_one_line = false |
|||
ij_javascript_keep_simple_methods_in_one_line = false |
|||
ij_javascript_line_comment_add_space = true |
|||
ij_javascript_line_comment_at_first_column = false |
|||
ij_javascript_method_brace_style = end_of_line |
|||
ij_javascript_method_call_chain_wrap = off |
|||
ij_javascript_method_parameters_new_line_after_left_paren = false |
|||
ij_javascript_method_parameters_right_paren_on_new_line = false |
|||
ij_javascript_method_parameters_wrap = off |
|||
ij_javascript_object_literal_wrap = on_every_item |
|||
ij_javascript_parentheses_expression_new_line_after_left_paren = false |
|||
ij_javascript_parentheses_expression_right_paren_on_new_line = false |
|||
ij_javascript_place_assignment_sign_on_next_line = false |
|||
ij_javascript_prefer_as_type_cast = false |
|||
ij_javascript_prefer_explicit_types_function_expression_returns = false |
|||
ij_javascript_prefer_explicit_types_function_returns = false |
|||
ij_javascript_prefer_explicit_types_vars_fields = false |
|||
ij_javascript_prefer_parameters_wrap = false |
|||
ij_javascript_reformat_c_style_comments = false |
|||
ij_javascript_space_after_colon = true |
|||
ij_javascript_space_after_comma = true |
|||
ij_javascript_space_after_dots_in_rest_parameter = false |
|||
ij_javascript_space_after_generator_mult = true |
|||
ij_javascript_space_after_property_colon = true |
|||
ij_javascript_space_after_quest = true |
|||
ij_javascript_space_after_type_colon = true |
|||
ij_javascript_space_after_unary_not = false |
|||
ij_javascript_space_before_async_arrow_lparen = true |
|||
ij_javascript_space_before_catch_keyword = true |
|||
ij_javascript_space_before_catch_left_brace = true |
|||
ij_javascript_space_before_catch_parentheses = true |
|||
ij_javascript_space_before_class_lbrace = true |
|||
ij_javascript_space_before_class_left_brace = true |
|||
ij_javascript_space_before_colon = true |
|||
ij_javascript_space_before_comma = false |
|||
ij_javascript_space_before_do_left_brace = true |
|||
ij_javascript_space_before_else_keyword = true |
|||
ij_javascript_space_before_else_left_brace = true |
|||
ij_javascript_space_before_finally_keyword = true |
|||
ij_javascript_space_before_finally_left_brace = true |
|||
ij_javascript_space_before_for_left_brace = true |
|||
ij_javascript_space_before_for_parentheses = true |
|||
ij_javascript_space_before_for_semicolon = false |
|||
ij_javascript_space_before_function_left_parenth = true |
|||
ij_javascript_space_before_generator_mult = false |
|||
ij_javascript_space_before_if_left_brace = true |
|||
ij_javascript_space_before_if_parentheses = true |
|||
ij_javascript_space_before_method_call_parentheses = false |
|||
ij_javascript_space_before_method_left_brace = true |
|||
ij_javascript_space_before_method_parentheses = false |
|||
ij_javascript_space_before_property_colon = false |
|||
ij_javascript_space_before_quest = true |
|||
ij_javascript_space_before_switch_left_brace = true |
|||
ij_javascript_space_before_switch_parentheses = true |
|||
ij_javascript_space_before_try_left_brace = true |
|||
ij_javascript_space_before_type_colon = false |
|||
ij_javascript_space_before_unary_not = false |
|||
ij_javascript_space_before_while_keyword = true |
|||
ij_javascript_space_before_while_left_brace = true |
|||
ij_javascript_space_before_while_parentheses = true |
|||
ij_javascript_spaces_around_additive_operators = true |
|||
ij_javascript_spaces_around_arrow_function_operator = true |
|||
ij_javascript_spaces_around_assignment_operators = true |
|||
ij_javascript_spaces_around_bitwise_operators = true |
|||
ij_javascript_spaces_around_equality_operators = true |
|||
ij_javascript_spaces_around_logical_operators = true |
|||
ij_javascript_spaces_around_multiplicative_operators = true |
|||
ij_javascript_spaces_around_relational_operators = true |
|||
ij_javascript_spaces_around_shift_operators = true |
|||
ij_javascript_spaces_around_unary_operator = false |
|||
ij_javascript_spaces_within_array_initializer_brackets = false |
|||
ij_javascript_spaces_within_brackets = false |
|||
ij_javascript_spaces_within_catch_parentheses = false |
|||
ij_javascript_spaces_within_for_parentheses = false |
|||
ij_javascript_spaces_within_if_parentheses = false |
|||
ij_javascript_spaces_within_imports = false |
|||
ij_javascript_spaces_within_interpolation_expressions = false |
|||
ij_javascript_spaces_within_method_call_parentheses = false |
|||
ij_javascript_spaces_within_method_parentheses = false |
|||
ij_javascript_spaces_within_object_literal_braces = false |
|||
ij_javascript_spaces_within_object_type_braces = true |
|||
ij_javascript_spaces_within_parentheses = false |
|||
ij_javascript_spaces_within_switch_parentheses = false |
|||
ij_javascript_spaces_within_type_assertion = false |
|||
ij_javascript_spaces_within_union_types = true |
|||
ij_javascript_spaces_within_while_parentheses = false |
|||
ij_javascript_special_else_if_treatment = true |
|||
ij_javascript_ternary_operation_signs_on_next_line = false |
|||
ij_javascript_ternary_operation_wrap = off |
|||
ij_javascript_union_types_wrap = on_every_item |
|||
ij_javascript_use_chained_calls_group_indents = false |
|||
ij_javascript_use_double_quotes = true |
|||
ij_javascript_use_explicit_js_extension = global |
|||
ij_javascript_use_path_mapping = always |
|||
ij_javascript_use_public_modifier = false |
|||
ij_javascript_use_semicolon_after_statement = true |
|||
ij_javascript_var_declaration_wrap = normal |
|||
ij_javascript_while_brace_force = never |
|||
ij_javascript_while_on_new_line = false |
|||
ij_javascript_wrap_comments = false |
|||
|
|||
[{*.cjsx,*.coffee}] |
|||
indent_size = 2 |
|||
tab_width = 2 |
|||
ij_continuation_indent_size = 2 |
|||
ij_coffeescript_align_function_body = false |
|||
ij_coffeescript_align_imports = false |
|||
ij_coffeescript_align_multiline_array_initializer_expression = true |
|||
ij_coffeescript_align_multiline_parameters = true |
|||
ij_coffeescript_align_multiline_parameters_in_calls = false |
|||
ij_coffeescript_align_object_properties = 0 |
|||
ij_coffeescript_align_union_types = false |
|||
ij_coffeescript_align_var_statements = 0 |
|||
ij_coffeescript_array_initializer_new_line_after_left_brace = false |
|||
ij_coffeescript_array_initializer_right_brace_on_new_line = false |
|||
ij_coffeescript_array_initializer_wrap = normal |
|||
ij_coffeescript_blacklist_imports = rxjs/Rx,node_modules/**,**/node_modules/**,@angular/material,@angular/material/typings/** |
|||
ij_coffeescript_blank_lines_around_function = 1 |
|||
ij_coffeescript_call_parameters_new_line_after_left_paren = false |
|||
ij_coffeescript_call_parameters_right_paren_on_new_line = false |
|||
ij_coffeescript_call_parameters_wrap = normal |
|||
ij_coffeescript_chained_call_dot_on_new_line = true |
|||
ij_coffeescript_comma_on_new_line = false |
|||
ij_coffeescript_enforce_trailing_comma = keep |
|||
ij_coffeescript_field_prefix = _ |
|||
ij_coffeescript_file_name_style = relaxed |
|||
ij_coffeescript_force_quote_style = false |
|||
ij_coffeescript_force_semicolon_style = false |
|||
ij_coffeescript_function_expression_brace_style = end_of_line |
|||
ij_coffeescript_import_merge_members = global |
|||
ij_coffeescript_import_prefer_absolute_path = global |
|||
ij_coffeescript_import_sort_members = true |
|||
ij_coffeescript_import_sort_module_name = false |
|||
ij_coffeescript_import_use_node_resolution = true |
|||
ij_coffeescript_imports_wrap = on_every_item |
|||
ij_coffeescript_indent_chained_calls = true |
|||
ij_coffeescript_indent_package_children = 0 |
|||
ij_coffeescript_jsx_attribute_value = braces |
|||
ij_coffeescript_keep_blank_lines_in_code = 2 |
|||
ij_coffeescript_keep_first_column_comment = true |
|||
ij_coffeescript_keep_indents_on_empty_lines = false |
|||
ij_coffeescript_keep_line_breaks = true |
|||
ij_coffeescript_keep_simple_methods_in_one_line = false |
|||
ij_coffeescript_method_parameters_new_line_after_left_paren = false |
|||
ij_coffeescript_method_parameters_right_paren_on_new_line = false |
|||
ij_coffeescript_method_parameters_wrap = off |
|||
ij_coffeescript_object_literal_wrap = on_every_item |
|||
ij_coffeescript_prefer_as_type_cast = false |
|||
ij_coffeescript_prefer_explicit_types_function_expression_returns = false |
|||
ij_coffeescript_prefer_explicit_types_function_returns = false |
|||
ij_coffeescript_prefer_explicit_types_vars_fields = false |
|||
ij_coffeescript_reformat_c_style_comments = false |
|||
ij_coffeescript_space_after_comma = true |
|||
ij_coffeescript_space_after_dots_in_rest_parameter = false |
|||
ij_coffeescript_space_after_generator_mult = true |
|||
ij_coffeescript_space_after_property_colon = true |
|||
ij_coffeescript_space_after_type_colon = true |
|||
ij_coffeescript_space_after_unary_not = false |
|||
ij_coffeescript_space_before_async_arrow_lparen = true |
|||
ij_coffeescript_space_before_class_lbrace = true |
|||
ij_coffeescript_space_before_comma = false |
|||
ij_coffeescript_space_before_function_left_parenth = true |
|||
ij_coffeescript_space_before_generator_mult = false |
|||
ij_coffeescript_space_before_property_colon = false |
|||
ij_coffeescript_space_before_type_colon = false |
|||
ij_coffeescript_space_before_unary_not = false |
|||
ij_coffeescript_spaces_around_additive_operators = true |
|||
ij_coffeescript_spaces_around_arrow_function_operator = true |
|||
ij_coffeescript_spaces_around_assignment_operators = true |
|||
ij_coffeescript_spaces_around_bitwise_operators = true |
|||
ij_coffeescript_spaces_around_equality_operators = true |
|||
ij_coffeescript_spaces_around_logical_operators = true |
|||
ij_coffeescript_spaces_around_multiplicative_operators = true |
|||
ij_coffeescript_spaces_around_relational_operators = true |
|||
ij_coffeescript_spaces_around_shift_operators = true |
|||
ij_coffeescript_spaces_around_unary_operator = false |
|||
ij_coffeescript_spaces_within_array_initializer_braces = false |
|||
ij_coffeescript_spaces_within_array_initializer_brackets = false |
|||
ij_coffeescript_spaces_within_imports = false |
|||
ij_coffeescript_spaces_within_index_brackets = false |
|||
ij_coffeescript_spaces_within_interpolation_expressions = false |
|||
ij_coffeescript_spaces_within_method_call_parentheses = false |
|||
ij_coffeescript_spaces_within_method_parentheses = false |
|||
ij_coffeescript_spaces_within_object_braces = false |
|||
ij_coffeescript_spaces_within_object_literal_braces = false |
|||
ij_coffeescript_spaces_within_object_type_braces = true |
|||
ij_coffeescript_spaces_within_range_brackets = false |
|||
ij_coffeescript_spaces_within_type_assertion = false |
|||
ij_coffeescript_spaces_within_union_types = true |
|||
ij_coffeescript_union_types_wrap = on_every_item |
|||
ij_coffeescript_use_chained_calls_group_indents = false |
|||
ij_coffeescript_use_double_quotes = true |
|||
ij_coffeescript_use_explicit_js_extension = global |
|||
ij_coffeescript_use_path_mapping = always |
|||
ij_coffeescript_use_public_modifier = false |
|||
ij_coffeescript_use_semicolon_after_statement = false |
|||
ij_coffeescript_var_declaration_wrap = normal |
|||
|
|||
[{*.ctp,*.hphp,*.inc,*.module,*.php,*.php4,*.php5,*.phtml}] |
|||
ij_continuation_indent_size = 4 |
|||
ij_php_align_assignments = true |
|||
ij_php_align_class_constants = true |
|||
ij_php_align_group_field_declarations = true |
|||
ij_php_align_inline_comments = true |
|||
ij_php_align_key_value_pairs = true |
|||
ij_php_align_multiline_array_initializer_expression = false |
|||
ij_php_align_multiline_binary_operation = false |
|||
ij_php_align_multiline_chained_methods = false |
|||
ij_php_align_multiline_extends_list = false |
|||
ij_php_align_multiline_for = true |
|||
ij_php_align_multiline_parameters = true |
|||
ij_php_align_multiline_parameters_in_calls = false |
|||
ij_php_align_multiline_ternary_operation = false |
|||
ij_php_align_phpdoc_comments = true |
|||
ij_php_align_phpdoc_param_names = true |
|||
ij_php_anonymous_brace_style = end_of_line |
|||
ij_php_api_weight = 28 |
|||
ij_php_array_initializer_new_line_after_left_brace = false |
|||
ij_php_array_initializer_right_brace_on_new_line = false |
|||
ij_php_array_initializer_wrap = off |
|||
ij_php_assignment_wrap = off |
|||
ij_php_attributes_wrap = off |
|||
ij_php_author_weight = 28 |
|||
ij_php_binary_operation_sign_on_next_line = false |
|||
ij_php_binary_operation_wrap = off |
|||
ij_php_blank_lines_after_class_header = 0 |
|||
ij_php_blank_lines_after_function = 1 |
|||
ij_php_blank_lines_after_imports = 1 |
|||
ij_php_blank_lines_after_opening_tag = 0 |
|||
ij_php_blank_lines_after_package = 0 |
|||
ij_php_blank_lines_around_class = 1 |
|||
ij_php_blank_lines_around_constants = 0 |
|||
ij_php_blank_lines_around_field = 0 |
|||
ij_php_blank_lines_around_method = 1 |
|||
ij_php_blank_lines_before_class_end = 0 |
|||
ij_php_blank_lines_before_imports = 1 |
|||
ij_php_blank_lines_before_method_body = 0 |
|||
ij_php_blank_lines_before_package = 1 |
|||
ij_php_blank_lines_before_return_statement = 0 |
|||
ij_php_blank_lines_between_imports = 0 |
|||
ij_php_block_brace_style = end_of_line |
|||
ij_php_call_parameters_new_line_after_left_paren = false |
|||
ij_php_call_parameters_right_paren_on_new_line = false |
|||
ij_php_call_parameters_wrap = off |
|||
ij_php_catch_on_new_line = false |
|||
ij_php_category_weight = 28 |
|||
ij_php_class_brace_style = next_line |
|||
ij_php_comma_after_last_array_element = false |
|||
ij_php_concat_spaces = true |
|||
ij_php_copyright_weight = 28 |
|||
ij_php_deprecated_weight = 28 |
|||
ij_php_do_while_brace_force = never |
|||
ij_php_else_if_style = as_is |
|||
ij_php_else_on_new_line = false |
|||
ij_php_example_weight = 28 |
|||
ij_php_extends_keyword_wrap = off |
|||
ij_php_extends_list_wrap = off |
|||
ij_php_fields_default_visibility = private |
|||
ij_php_filesource_weight = 28 |
|||
ij_php_finally_on_new_line = false |
|||
ij_php_for_brace_force = never |
|||
ij_php_for_statement_new_line_after_left_paren = false |
|||
ij_php_for_statement_right_paren_on_new_line = false |
|||
ij_php_for_statement_wrap = off |
|||
ij_php_force_short_declaration_array_style = false |
|||
ij_php_getters_setters_naming_style = camel_case |
|||
ij_php_getters_setters_order_style = getters_first |
|||
ij_php_global_weight = 28 |
|||
ij_php_group_use_wrap = on_every_item |
|||
ij_php_if_brace_force = never |
|||
ij_php_if_lparen_on_next_line = false |
|||
ij_php_if_rparen_on_next_line = false |
|||
ij_php_ignore_weight = 28 |
|||
ij_php_import_sorting = alphabetic |
|||
ij_php_indent_break_from_case = true |
|||
ij_php_indent_case_from_switch = true |
|||
ij_php_indent_code_in_php_tags = false |
|||
ij_php_internal_weight = 28 |
|||
ij_php_keep_blank_lines_after_lbrace = 2 |
|||
ij_php_keep_blank_lines_before_right_brace = 2 |
|||
ij_php_keep_blank_lines_in_code = 2 |
|||
ij_php_keep_blank_lines_in_declarations = 2 |
|||
ij_php_keep_control_statement_in_one_line = true |
|||
ij_php_keep_first_column_comment = true |
|||
ij_php_keep_indents_on_empty_lines = false |
|||
ij_php_keep_line_breaks = true |
|||
ij_php_keep_rparen_and_lbrace_on_one_line = false |
|||
ij_php_keep_simple_classes_in_one_line = false |
|||
ij_php_keep_simple_methods_in_one_line = false |
|||
ij_php_lambda_brace_style = end_of_line |
|||
ij_php_license_weight = 28 |
|||
ij_php_line_comment_add_space = false |
|||
ij_php_line_comment_at_first_column = true |
|||
ij_php_link_weight = 28 |
|||
ij_php_lower_case_boolean_const = false |
|||
ij_php_lower_case_keywords = true |
|||
ij_php_lower_case_null_const = false |
|||
ij_php_method_brace_style = next_line |
|||
ij_php_method_call_chain_wrap = off |
|||
ij_php_method_parameters_new_line_after_left_paren = false |
|||
ij_php_method_parameters_right_paren_on_new_line = false |
|||
ij_php_method_parameters_wrap = off |
|||
ij_php_method_weight = 28 |
|||
ij_php_modifier_list_wrap = false |
|||
ij_php_multiline_chained_calls_semicolon_on_new_line = false |
|||
ij_php_namespace_brace_style = 1 |
|||
ij_php_new_line_after_php_opening_tag = false |
|||
ij_php_null_type_position = in_the_end |
|||
ij_php_package_weight = 28 |
|||
ij_php_param_weight = 0 |
|||
ij_php_parameters_attributes_wrap = off |
|||
ij_php_parentheses_expression_new_line_after_left_paren = false |
|||
ij_php_parentheses_expression_right_paren_on_new_line = false |
|||
ij_php_phpdoc_blank_line_before_tags = false |
|||
ij_php_phpdoc_blank_lines_around_parameters = false |
|||
ij_php_phpdoc_keep_blank_lines = true |
|||
ij_php_phpdoc_param_spaces_between_name_and_description = 1 |
|||
ij_php_phpdoc_param_spaces_between_tag_and_type = 1 |
|||
ij_php_phpdoc_param_spaces_between_type_and_name = 1 |
|||
ij_php_phpdoc_use_fqcn = false |
|||
ij_php_phpdoc_wrap_long_lines = false |
|||
ij_php_place_assignment_sign_on_next_line = false |
|||
ij_php_place_parens_for_constructor = 0 |
|||
ij_php_property_read_weight = 28 |
|||
ij_php_property_weight = 28 |
|||
ij_php_property_write_weight = 28 |
|||
ij_php_return_type_on_new_line = false |
|||
ij_php_return_weight = 1 |
|||
ij_php_see_weight = 28 |
|||
ij_php_since_weight = 28 |
|||
ij_php_sort_phpdoc_elements = true |
|||
ij_php_space_after_colon = true |
|||
ij_php_space_after_colon_in_named_argument = true |
|||
ij_php_space_after_colon_in_return_type = true |
|||
ij_php_space_after_comma = true |
|||
ij_php_space_after_for_semicolon = true |
|||
ij_php_space_after_quest = true |
|||
ij_php_space_after_type_cast = false |
|||
ij_php_space_after_unary_not = false |
|||
ij_php_space_before_array_initializer_left_brace = false |
|||
ij_php_space_before_catch_keyword = true |
|||
ij_php_space_before_catch_left_brace = true |
|||
ij_php_space_before_catch_parentheses = true |
|||
ij_php_space_before_class_left_brace = true |
|||
ij_php_space_before_closure_left_parenthesis = true |
|||
ij_php_space_before_colon = true |
|||
ij_php_space_before_colon_in_named_argument = false |
|||
ij_php_space_before_colon_in_return_type = false |
|||
ij_php_space_before_comma = false |
|||
ij_php_space_before_do_left_brace = true |
|||
ij_php_space_before_else_keyword = true |
|||
ij_php_space_before_else_left_brace = true |
|||
ij_php_space_before_finally_keyword = true |
|||
ij_php_space_before_finally_left_brace = true |
|||
ij_php_space_before_for_left_brace = true |
|||
ij_php_space_before_for_parentheses = true |
|||
ij_php_space_before_for_semicolon = false |
|||
ij_php_space_before_if_left_brace = true |
|||
ij_php_space_before_if_parentheses = true |
|||
ij_php_space_before_method_call_parentheses = false |
|||
ij_php_space_before_method_left_brace = true |
|||
ij_php_space_before_method_parentheses = false |
|||
ij_php_space_before_quest = true |
|||
ij_php_space_before_short_closure_left_parenthesis = false |
|||
ij_php_space_before_switch_left_brace = true |
|||
ij_php_space_before_switch_parentheses = true |
|||
ij_php_space_before_try_left_brace = true |
|||
ij_php_space_before_unary_not = false |
|||
ij_php_space_before_while_keyword = true |
|||
ij_php_space_before_while_left_brace = true |
|||
ij_php_space_before_while_parentheses = true |
|||
ij_php_space_between_ternary_quest_and_colon = false |
|||
ij_php_spaces_around_additive_operators = true |
|||
ij_php_spaces_around_arrow = false |
|||
ij_php_spaces_around_assignment_in_declare = false |
|||
ij_php_spaces_around_assignment_operators = true |
|||
ij_php_spaces_around_bitwise_operators = true |
|||
ij_php_spaces_around_equality_operators = true |
|||
ij_php_spaces_around_logical_operators = true |
|||
ij_php_spaces_around_multiplicative_operators = true |
|||
ij_php_spaces_around_null_coalesce_operator = true |
|||
ij_php_spaces_around_relational_operators = true |
|||
ij_php_spaces_around_shift_operators = true |
|||
ij_php_spaces_around_unary_operator = false |
|||
ij_php_spaces_around_var_within_brackets = false |
|||
ij_php_spaces_within_array_initializer_braces = false |
|||
ij_php_spaces_within_brackets = false |
|||
ij_php_spaces_within_catch_parentheses = false |
|||
ij_php_spaces_within_for_parentheses = false |
|||
ij_php_spaces_within_if_parentheses = false |
|||
ij_php_spaces_within_method_call_parentheses = false |
|||
ij_php_spaces_within_method_parentheses = false |
|||
ij_php_spaces_within_parentheses = false |
|||
ij_php_spaces_within_short_echo_tags = true |
|||
ij_php_spaces_within_switch_parentheses = false |
|||
ij_php_spaces_within_while_parentheses = false |
|||
ij_php_special_else_if_treatment = false |
|||
ij_php_subpackage_weight = 28 |
|||
ij_php_ternary_operation_signs_on_next_line = false |
|||
ij_php_ternary_operation_wrap = off |
|||
ij_php_throws_weight = 2 |
|||
ij_php_todo_weight = 28 |
|||
ij_php_unknown_tag_weight = 28 |
|||
ij_php_upper_case_boolean_const = false |
|||
ij_php_upper_case_null_const = false |
|||
ij_php_uses_weight = 28 |
|||
ij_php_var_weight = 28 |
|||
ij_php_variable_naming_style = mixed |
|||
ij_php_version_weight = 28 |
|||
ij_php_while_brace_force = never |
|||
ij_php_while_on_new_line = false |
|||
|
|||
[{*.har,*.jsb2,*.jsb3,*.json,.babelrc,.eslintrc,.stylelintrc,bowerrc,composer.lock,jest.config}] |
|||
indent_size = 2 |
|||
ij_json_keep_blank_lines_in_code = 0 |
|||
ij_json_keep_indents_on_empty_lines = false |
|||
ij_json_keep_line_breaks = true |
|||
ij_json_space_after_colon = true |
|||
ij_json_space_after_comma = true |
|||
ij_json_space_before_colon = true |
|||
ij_json_space_before_comma = false |
|||
ij_json_spaces_within_braces = false |
|||
ij_json_spaces_within_brackets = false |
|||
ij_json_wrap_long_lines = false |
|||
|
|||
[{*.htm,*.html,*.ng,*.sht,*.shtm,*.shtml}] |
|||
ij_html_add_new_line_before_tags = body,div,p,form,h1,h2,h3 |
|||
ij_html_align_attributes = true |
|||
ij_html_align_text = false |
|||
ij_html_attribute_wrap = normal |
|||
ij_html_block_comment_at_first_column = true |
|||
ij_html_do_not_align_children_of_min_lines = 0 |
|||
ij_html_do_not_break_if_inline_tags = title,h1,h2,h3,h4,h5,h6,p |
|||
ij_html_do_not_indent_children_of_tags = html,body,thead,tbody,tfoot |
|||
ij_html_enforce_quotes = false |
|||
ij_html_inline_tags = a,abbr,acronym,b,basefont,bdo,big,br,cite,cite,code,dfn,em,font,i,img,input,kbd,label,q,s,samp,select,small,span,strike,strong,sub,sup,textarea,tt,u,var |
|||
ij_html_keep_blank_lines = 2 |
|||
ij_html_keep_indents_on_empty_lines = false |
|||
ij_html_keep_line_breaks = true |
|||
ij_html_keep_line_breaks_in_text = true |
|||
ij_html_keep_whitespaces = false |
|||
ij_html_keep_whitespaces_inside = span,pre,textarea |
|||
ij_html_line_comment_at_first_column = true |
|||
ij_html_new_line_after_last_attribute = never |
|||
ij_html_new_line_before_first_attribute = never |
|||
ij_html_quote_style = double |
|||
ij_html_remove_new_line_before_tags = br |
|||
ij_html_space_after_tag_name = false |
|||
ij_html_space_around_equality_in_attribute = false |
|||
ij_html_space_inside_empty_tag = false |
|||
ij_html_text_wrap = normal |
|||
ij_html_uniform_ident = false |
|||
|
|||
[{*.markdown,*.md}] |
|||
ij_markdown_force_one_space_after_blockquote_symbol = true |
|||
ij_markdown_force_one_space_after_header_symbol = true |
|||
ij_markdown_force_one_space_after_list_bullet = true |
|||
ij_markdown_force_one_space_between_words = true |
|||
ij_markdown_keep_indents_on_empty_lines = false |
|||
ij_markdown_max_lines_around_block_elements = 1 |
|||
ij_markdown_max_lines_around_header = 1 |
|||
ij_markdown_max_lines_between_paragraphs = 1 |
|||
ij_markdown_min_lines_around_block_elements = 1 |
|||
ij_markdown_min_lines_around_header = 1 |
|||
ij_markdown_min_lines_between_paragraphs = 1 |
|||
|
|||
[{*.yaml,*.yml}] |
|||
indent_size = 2 |
|||
ij_yaml_align_values_properties = do_not_align |
|||
ij_yaml_autoinsert_sequence_marker = true |
|||
ij_yaml_block_mapping_on_new_line = false |
|||
ij_yaml_indent_sequence_value = true |
|||
ij_yaml_keep_indents_on_empty_lines = false |
|||
ij_yaml_keep_line_breaks = true |
|||
ij_yaml_sequence_on_new_line = false |
|||
ij_yaml_space_before_colon = false |
|||
ij_yaml_spaces_within_braces = true |
|||
ij_yaml_spaces_within_brackets = true |
|||
@ -0,0 +1,30 @@ |
|||
# 应用调试模式(true=开启;false=关闭) |
|||
APP_DEBUG = true |
|||
|
|||
[APP] |
|||
DEFAULT_TIMEZONE = Asia/Shanghai |
|||
|
|||
[DATABASE] |
|||
TYPE = mysql |
|||
HOSTNAME = 127.0.0.1 |
|||
DATABASE = api_junfei_iiixo |
|||
USERNAME = root |
|||
PASSWORD = root |
|||
HOSTPORT = 3306 |
|||
CHARSET = utf8mb4 |
|||
DEBUG = true |
|||
PREFIX = tp_ |
|||
|
|||
[LANG] |
|||
# 默认语言 |
|||
default_lang = zh-cn |
|||
|
|||
[BUILDER] |
|||
# 后台添加/编辑等页启用layer弹层加载(true=启用;false=不启用) |
|||
LAYER_OPEN = true |
|||
|
|||
[ROUTE] |
|||
# 开启请求缓存(true=自动缓存;false=关闭缓存) |
|||
REQUEST_CACHE_KEY = false |
|||
# 请求缓存有效期(秒) |
|||
REQUEST_CACHE_EXPIRE = 3600 |
|||
@ -0,0 +1,5 @@ |
|||
/.idea |
|||
/.vscode |
|||
*.log |
|||
/runtime |
|||
/vendor |
|||
@ -0,0 +1,42 @@ |
|||
sudo: false |
|||
|
|||
language: php |
|||
|
|||
branches: |
|||
only: |
|||
- stable |
|||
|
|||
cache: |
|||
directories: |
|||
- $HOME/.composer/cache |
|||
|
|||
before_install: |
|||
- composer self-update |
|||
|
|||
install: |
|||
- composer install --no-dev --no-interaction --ignore-platform-reqs |
|||
- zip -r --exclude='*.git*' --exclude='*.zip' --exclude='*.travis.yml' ThinkPHP_Core.zip . |
|||
- composer require --update-no-dev --no-interaction "topthink/think-image:^1.0" |
|||
- composer require --update-no-dev --no-interaction "topthink/think-migration:^1.0" |
|||
- composer require --update-no-dev --no-interaction "topthink/think-captcha:^1.0" |
|||
- composer require --update-no-dev --no-interaction "topthink/think-mongo:^1.0" |
|||
- composer require --update-no-dev --no-interaction "topthink/think-worker:^1.0" |
|||
- composer require --update-no-dev --no-interaction "topthink/think-helper:^1.0" |
|||
- composer require --update-no-dev --no-interaction "topthink/think-queue:^1.0" |
|||
- composer require --update-no-dev --no-interaction "topthink/think-angular:^1.0" |
|||
- composer require --dev --update-no-dev --no-interaction "topthink/think-testing:^1.0" |
|||
- zip -r --exclude='*.git*' --exclude='*.zip' --exclude='*.travis.yml' ThinkPHP_Full.zip . |
|||
|
|||
script: |
|||
- php think unit |
|||
|
|||
deploy: |
|||
provider: releases |
|||
api_key: |
|||
secure: TSF6bnl2JYN72UQOORAJYL+CqIryP2gHVKt6grfveQ7d9rleAEoxlq6PWxbvTI4jZ5nrPpUcBUpWIJHNgVcs+bzLFtyh5THaLqm39uCgBbrW7M8rI26L8sBh/6nsdtGgdeQrO/cLu31QoTzbwuz1WfAVoCdCkOSZeXyT/CclH99qV6RYyQYqaD2wpRjrhA5O4fSsEkiPVuk0GaOogFlrQHx+C+lHnf6pa1KxEoN1A0UxxVfGX6K4y5g4WQDO5zT4bLeubkWOXK0G51XSvACDOZVIyLdjApaOFTwamPcD3S1tfvuxRWWvsCD5ljFvb2kSmx5BIBNwN80MzuBmrGIC27XLGOxyMerwKxB6DskNUO9PflKHDPI61DRq0FTy1fv70SFMSiAtUv9aJRT41NQh9iJJ0vC8dl+xcxrWIjU1GG6+l/ZcRqVx9V1VuGQsLKndGhja7SQ+X1slHl76fRq223sMOql7MFCd0vvvxVQ2V39CcFKao/LB1aPH3VhODDEyxwx6aXoTznvC/QPepgWsHOWQzKj9ftsgDbsNiyFlXL4cu8DWUty6rQy8zT2b4O8b1xjcwSUCsy+auEjBamzQkMJFNlZAIUrukL/NbUhQU37TAbwsFyz7X0E/u/VMle/nBCNAzgkMwAUjiHM6FqrKKBRWFbPrSIixjfjkCnrMEPw= |
|||
file: |
|||
- ThinkPHP_Core.zip |
|||
- ThinkPHP_Full.zip |
|||
skip_cleanup: true |
|||
on: |
|||
tags: true |
|||
@ -0,0 +1,21 @@ |
|||
MIT License |
|||
|
|||
Copyright (c) 2020 若水印象 |
|||
|
|||
Permission is hereby granted, free of charge, to any person obtaining a copy |
|||
of this software and associated documentation files (the "Software"), to deal |
|||
in the Software without restriction, including without limitation the rights |
|||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|||
copies of the Software, and to permit persons to whom the Software is |
|||
furnished to do so, subject to the following conditions: |
|||
|
|||
The above copyright notice and this permission notice shall be included in all |
|||
copies or substantial portions of the Software. |
|||
|
|||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
|||
SOFTWARE. |
|||
@ -0,0 +1,80 @@ |
|||
## SIYUCMS V6.1 快速开发内容管理系统 |
|||
|
|||
[](https://gitee.com/ruoshuiyx/tp6/stargazers) |
|||
[](https://gitee.com/ruoshuiyx/tp6/members) |
|||
 |
|||
[](https://gitee.com/ruoshuiyx/tp6/blob/master/LICENSE) |
|||
|
|||
SIYUCMS 基于 ThinkPHP6.0 + AdminLTE 开发,简单 / 易用 / 响应式 / 低门槛。 |
|||
|
|||
系统内置了表单构建器和表格构建器,配合后台模块管理和字段管理能快速方便的构建Web应用程序。 |
|||
|
|||
|
|||
## 安装使用 |
|||
|
|||
> 下载SIYUCMS完整包解压到你本地(建议采用git方式拉取,或宝塔一键部署) |
|||
|
|||
> 将你的站点绑定到public目录(强烈建议绑定到public目录) |
|||
|
|||
> 将文件夹中siyucms.sql还原到你自己项目的数据库中(需自行创建数据库) |
|||
|
|||
> 修改.env 中数据库配置信息(调试模式也是在这个文件中进行打开和关闭) |
|||
|
|||
> 访问后台并登录查看是否正常,后台目录为http://www.yourwebsite.com/admin (如无法访问请尝试隐藏index.php https://www.kancloud.cn/ruoshuiyx/siyucms/1032705) |
|||
|
|||
> 默认后台用户名:admin 密码:admin |
|||
|
|||
## 在线体验 |
|||
- 用户名:test 密码:123456 |
|||
- 陆续收到一些捐赠、授权和打赏,谢谢各位小伙伴的支持。 |
|||
|
|||
演示地址: |
|||
[https://v6.siyucms.com/admin](https://v6.siyucms.com/admin) |
|||
|
|||
文档地址:[https://www.kancloud.cn/ruoshuiyx/siyucms/](https://www.kancloud.cn/ruoshuiyx/siyucms/) |
|||
|
|||
## 演示图 |
|||
|
|||
<table> |
|||
<tr> |
|||
<td><img src="https://oscimg.oschina.net/oscnet/up-b4b04b9033593ade89b42a20c7dbc4cdbd1.JPEG"/></td> |
|||
<td><img src="https://oscimg.oschina.net/oscnet/up-f3d19bd061ed7046fb1d648ee4daaba3ab9.JPEG"/></td> |
|||
</tr> |
|||
<tr> |
|||
<td><img src="https://oscimg.oschina.net/oscnet/up-1145a21c76fdc552d80010e299431c0a857.JPEG"/></td> |
|||
<td><img src="https://oscimg.oschina.net/oscnet/up-96e50291450aed07bcd37362cc9d84e80a9.JPEG"/></td> |
|||
</tr> |
|||
<tr> |
|||
<td><img src="https://oscimg.oschina.net/oscnet/up-cc975637268ec7c56f8f53d47ba4c8f53ca.JPEG"/></td> |
|||
<td><img src="https://oscimg.oschina.net/oscnet/up-0fae3534357c5f4fe38c38520b38ec28e7a.JPEG"/></td> |
|||
</tr> |
|||
<tr> |
|||
<td><img src="https://oscimg.oschina.net/oscnet/up-37dfb84b8a047cb5dd8b3153e7bfc688f4e.JPEG"/></td> |
|||
<td><img src="https://oscimg.oschina.net/oscnet/up-b4b0d3c405f86527555b86c2f7a94bd2bbf.JPEG"/></td> |
|||
</tr> |
|||
<tr> |
|||
<td><img src="https://oscimg.oschina.net/oscnet/up-7f917fb75032f0eedd7ab4b8944cdf55b6c.JPEG"/></td> |
|||
<td><img src="https://oscimg.oschina.net/oscnet/up-afe8a9ec02ecb9299c30be835fea4fbee42.JPEG"/></td> |
|||
</tr> |
|||
<tr> |
|||
<td><img src="https://oscimg.oschina.net/oscnet/up-b28d0574a8984e016ecab0d54d8c5ae43d5.JPEG"/></td> |
|||
<td><img src="https://oscimg.oschina.net/oscnet/up-1fb975c7931d5f946054b6ab5ffe1ff190f.JPEG"/></td> |
|||
</tr> |
|||
<tr> |
|||
<td><img src="https://oscimg.oschina.net/oscnet/up-b6a8f7507b23b414b61bef796ab213f2b78.JPEG"/></td> |
|||
<td><img src="https://oscimg.oschina.net/oscnet/up-7f9fb85d0727aa87b717d95ef0e6f7e30d1.JPEG"/></td> |
|||
</tr> |
|||
<tr> |
|||
<td><img src="https://oscimg.oschina.net/oscnet/up-bc84053e8b6250e57d42f3c0b03980a799d.JPEG"/></td> |
|||
<td><img src="https://oscimg.oschina.net/oscnet/up-85a769ccbb17fb074053296094e3e3e4ac9.JPEG"/></td> |
|||
</tr> |
|||
</table> |
|||
|
|||
## 交流群 |
|||
|
|||
QQ群: |
|||
[883855822](https://qm.qq.com/cgi-bin/qm/qr?k=yPFJoUxXBYhHoGxh5lLSp3mpAdgw1v8x&jump_from=webapi) |
|||
|
|||
## 版权信息 |
|||
|
|||
请尊重SIYUCMS开发者的劳动成果,SIYUCMS提供免费使用,但未授权前请保留前台 Powered by SIYUCMS ,并不得修改后台版权信息。 |
|||
@ -0,0 +1,66 @@ |
|||
<?php |
|||
// 注意命名空间规范 |
|||
namespace addons\test; |
|||
|
|||
use think\Addons; |
|||
|
|||
/** |
|||
* 插件测试 |
|||
* 注意名字不可以修改,只能为Plugin |
|||
*/ |
|||
class Plugin extends Addons |
|||
{ |
|||
// 该插件的基础信息,系统优先获取info.ini中的配置信息 |
|||
public $info = [ |
|||
'name' => 'test', // 插件标识 |
|||
'title' => '插件测试', // 插件名称 |
|||
'description' => 'thinkph6插件测试', // 插件简介 |
|||
'status' => 0, // 状态[1 启用,0 禁用] |
|||
'install' => 0, // 是否已安装[1 已安装,0 未安装] |
|||
'author' => 'SIYUCMS', // 作者 |
|||
'version' => '1.0', // 版本 |
|||
]; |
|||
|
|||
// 插件的安装 [添加文件、执行sql等] |
|||
public function install() |
|||
{ |
|||
return true; |
|||
} |
|||
|
|||
// 插件的卸载 [移除文件、执行sql等] |
|||
public function uninstall() |
|||
{ |
|||
return true; |
|||
} |
|||
|
|||
/** |
|||
* 实现的testhook钩子方法 |
|||
* @param $param 调用钩子时候的参数信息 |
|||
* @return false|mixed|string |
|||
* |
|||
* 用法: |
|||
* 模版中调用:<div>{:hook('testhook', ['id'=>1])}</div> |
|||
* PHP中调用:hook('testhook', ['id'=>1]); |
|||
*/ |
|||
public function testhook($param) |
|||
{ |
|||
// 当前插件的基础信息,系统优先获取info.ini中的配置信息 |
|||
$info = $this->getInfo(); |
|||
|
|||
// 插件禁用后不再进行任何输出 |
|||
if($info['status'] == 0){ |
|||
return false; |
|||
} |
|||
|
|||
// 当前插件的配置信息,配置信息存在当前目录的config.php文件中 |
|||
$config = $this->getConfig(); |
|||
|
|||
|
|||
// 打印调用钩子时候的参数信息和当前参加的配置信息 |
|||
dump($param, $info, $config); |
|||
|
|||
// 可以返回模板,模板文件默认读取的为插件目录中的文件。模板名不能为空! |
|||
return $this->fetch('info'); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,57 @@ |
|||
<?php |
|||
|
|||
return array ( |
|||
'field_1' => |
|||
array ( |
|||
'title' => '文本框:', |
|||
'type' => 'text', |
|||
'options' => |
|||
array ( |
|||
), |
|||
'value' => '文本框的值', |
|||
), |
|||
'field_2' => |
|||
array ( |
|||
'title' => '文本域:', |
|||
'type' => 'textarea', |
|||
'options' => |
|||
array ( |
|||
), |
|||
'value' => '文本域的值', |
|||
), |
|||
'field_3' => |
|||
array ( |
|||
'title' => '单选:', |
|||
'type' => 'radio', |
|||
'options' => |
|||
array ( |
|||
1 => '是', |
|||
0 => '否', |
|||
), |
|||
'value' => '0', |
|||
), |
|||
'field_4' => |
|||
array ( |
|||
'title' => '多选:', |
|||
'type' => 'checkbox', |
|||
'options' => |
|||
array ( |
|||
1 => '选项1', |
|||
2 => '选项2', |
|||
3 => '选项3', |
|||
), |
|||
'value' => '1,2', |
|||
), |
|||
'field_5' => |
|||
array ( |
|||
'title' => '下拉:', |
|||
'type' => 'select', |
|||
'options' => |
|||
array ( |
|||
1 => '选项1', |
|||
2 => '选项2', |
|||
3 => '选项3', |
|||
), |
|||
'value' => '1', |
|||
), |
|||
); |
|||
@ -0,0 +1,15 @@ |
|||
<?php |
|||
namespace addons\test\controller; |
|||
|
|||
class Index |
|||
{ |
|||
public function link() |
|||
{ |
|||
echo 'hello link'; |
|||
} |
|||
|
|||
public function test() |
|||
{ |
|||
echo 'hello test'; |
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
<h1>hello tpl</h1> |
|||
|
|||
如果插件中需要有链接或提交数据的业务,可以在插件中创建controller业务文件, |
|||
要访问插件中的controller时使用addons_url生成url链接。<br> |
|||
<hr> |
|||
如: |
|||
<a href="{:addons_url('Index/test')}">Index test</a><br> |
|||
格式为: |
|||
test为插件名,Index为controller中的类名[多级控制器可以用.分割],test同时也为controller中的方法命<br> |
|||
|
|||
或 |
|||
<a href="{:addons_url('test://Index/link')}">Index link</a><br> |
|||
格式为: |
|||
test为插件名,Index为controller中的类名[多级控制器可以用.分割],link为controller中的方法 |
|||
@ -0,0 +1 @@ |
|||
deny from all |
|||
@ -0,0 +1,22 @@ |
|||
<?php |
|||
declare (strict_types = 1); |
|||
|
|||
namespace app; |
|||
|
|||
use think\Service; |
|||
|
|||
/** |
|||
* 应用服务类 |
|||
*/ |
|||
class AppService extends Service |
|||
{ |
|||
public function register() |
|||
{ |
|||
// 服务注册 |
|||
} |
|||
|
|||
public function boot() |
|||
{ |
|||
// 服务启动 |
|||
} |
|||
} |
|||
@ -0,0 +1,58 @@ |
|||
<?php |
|||
namespace app; |
|||
|
|||
use think\db\exception\DataNotFoundException; |
|||
use think\db\exception\ModelNotFoundException; |
|||
use think\exception\Handle; |
|||
use think\exception\HttpException; |
|||
use think\exception\HttpResponseException; |
|||
use think\exception\ValidateException; |
|||
use think\Response; |
|||
use Throwable; |
|||
|
|||
/** |
|||
* 应用异常处理类 |
|||
*/ |
|||
class ExceptionHandle extends Handle |
|||
{ |
|||
/** |
|||
* 不需要记录信息(日志)的异常类列表 |
|||
* @var array |
|||
*/ |
|||
protected $ignoreReport = [ |
|||
HttpException::class, |
|||
HttpResponseException::class, |
|||
ModelNotFoundException::class, |
|||
DataNotFoundException::class, |
|||
ValidateException::class, |
|||
]; |
|||
|
|||
/** |
|||
* 记录异常信息(包括日志或者其它方式记录) |
|||
* |
|||
* @access public |
|||
* @param Throwable $exception |
|||
* @return void |
|||
*/ |
|||
public function report(Throwable $exception): void |
|||
{ |
|||
// 使用内置的方式记录异常日志 |
|||
parent::report($exception); |
|||
} |
|||
|
|||
/** |
|||
* Render an exception into an HTTP response. |
|||
* |
|||
* @access public |
|||
* @param \think\Request $request |
|||
* @param Throwable $e |
|||
* @return Response |
|||
*/ |
|||
public function render($request, Throwable $e): Response |
|||
{ |
|||
// 添加自定义异常处理机制 |
|||
|
|||
// 其他错误交给系统处理 |
|||
return parent::render($request, $e); |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
<?php |
|||
namespace app; |
|||
|
|||
// 应用请求对象类 |
|||
class Request extends \think\Request |
|||
{ |
|||
|
|||
} |
|||
@ -0,0 +1,272 @@ |
|||
<?php |
|||
|
|||
/** |
|||
* 生成页码跳转 |
|||
* @param int $page_size 每页显示的数量 |
|||
* @return string |
|||
*/ |
|||
function page_size($page_size = 0, $total = 0) |
|||
{ |
|||
$str = '<select class="form-control page_size">'; |
|||
for ($i = 10; $i <= 100; $i += 10) { |
|||
$selected = $page_size == $i ? 'selected' : ''; |
|||
$str .= '<option value="' . $i . '" ' . $selected . ' >' . $i . ' 条/页</option>'; |
|||
} |
|||
$str .= '</select>'; |
|||
if ($total > 0) { |
|||
$str .= '<span class="form-control page_total">总共 ' . $total . ' 条记录</span>'; |
|||
} |
|||
return $str; |
|||
} |
|||
|
|||
/** |
|||
* 空数据提示 |
|||
* @param int $num |
|||
* @return string |
|||
*/ |
|||
function empty_list($num = 10) |
|||
{ |
|||
$empty = "<tr><td colspan='" . $num . "' align='center'>暂无数据</td></tr>"; |
|||
return $empty; |
|||
} |
|||
|
|||
/** |
|||
* 权限设置选中状态 |
|||
* @param $cate 栏目 |
|||
* @param int $pid 父ID |
|||
* @param $rules 规则 |
|||
* @return array |
|||
*/ |
|||
function auth($cate, $pid, $rules) |
|||
{ |
|||
$arr = array(); |
|||
$rulesArr = explode(',', $rules); |
|||
foreach ($cate as $v) { |
|||
if ($v['pid'] == $pid) { |
|||
if (in_array($v['id'], $rulesArr)) { |
|||
$v['checked'] = true; |
|||
} |
|||
$v['open'] = true; |
|||
$arr[] = $v; |
|||
$arr = array_merge($arr, auth($cate, $v['id'], $rules)); |
|||
} |
|||
} |
|||
return $arr; |
|||
} |
|||
|
|||
/** |
|||
* PHP格式化字节大小 |
|||
* @param number $size 字节数 |
|||
* @param string $delimiter 数字和单位分隔符 |
|||
* @return string 格式化后的带单位的大小 |
|||
*/ |
|||
function format_bytes($size, $delimiter = '') |
|||
{ |
|||
$units = array('B', 'KB', 'MB', 'GB', 'TB', 'PB'); |
|||
for ($i = 0; $size >= 1024 && $i < 5; $i++) $size /= 1024; |
|||
return round($size, 2) . $delimiter . $units[$i]; |
|||
} |
|||
|
|||
/** |
|||
* 获取目录里的文件,不包括下级文件夹 |
|||
* @param string $dir 路径 |
|||
* @return array |
|||
*/ |
|||
function get_dir($dir) |
|||
{ |
|||
$file = @ scandir($dir); |
|||
foreach ($file as $key) { |
|||
if ($key != ".." && $key != ".") { |
|||
$files[] = $key; |
|||
} |
|||
} |
|||
return $files; |
|||
} |
|||
|
|||
/** |
|||
* 获取文件夹中的文件,含目录 |
|||
* @param $path |
|||
* @param string $exts |
|||
* @param array $list |
|||
* @return array |
|||
*/ |
|||
function dir_list($path, $exts = '', $list = array()) |
|||
{ |
|||
$path = dir_path($path); |
|||
$files = glob($path . '*'); |
|||
foreach ($files as $v) { |
|||
$fileext = fileext($v); |
|||
if (!$exts || preg_match("/\.($exts)/i", $v)) { |
|||
$list[] = $v; |
|||
if (is_dir($v)) { |
|||
$list = dir_list($v, $exts, $list); |
|||
} |
|||
} |
|||
} |
|||
return $list; |
|||
} |
|||
|
|||
/** |
|||
* 补齐目录后的/ |
|||
* @param $path 目录 |
|||
* @return string |
|||
*/ |
|||
function dir_path($path) |
|||
{ |
|||
$path = str_replace('\\', '/', $path); |
|||
if (substr($path, -1) != '/') $path = $path . '/'; |
|||
return $path; |
|||
} |
|||
|
|||
/** |
|||
* 查找文件后缀 |
|||
* @param $filename 文件名称 |
|||
* @return string 后缀名称(如:html) |
|||
*/ |
|||
function fileext($filename) |
|||
{ |
|||
return strtolower(trim(substr(strrchr($filename, '.'), 1, 10))); |
|||
} |
|||
|
|||
/** |
|||
* 删除目录及文件 |
|||
* @param $dir |
|||
* @return bool |
|||
*/ |
|||
function dir_delete($dir) |
|||
{ |
|||
$dir = dir_path($dir); |
|||
if (!is_dir($dir)) return FALSE; |
|||
$list = glob($dir . '*'); |
|||
foreach ($list as $v) { |
|||
is_dir($v) ? dir_delete($v) : @unlink($v); |
|||
} |
|||
return @rmdir($dir); |
|||
} |
|||
|
|||
/** |
|||
* 生成不同的编辑器(目前只支持ckeditor) |
|||
* @param string $name 字段名称 |
|||
* @param string $conetnt 内容 |
|||
* @param string $editor 编辑器 |
|||
* @param string $height 高度 |
|||
* @param string $width 宽度 |
|||
* @return string |
|||
*/ |
|||
function make_editor($name, $conetnt = '', $editor = '', $height = '400px', $width = '') |
|||
{ |
|||
$result = '<textarea name="' . $name . '" id="' . $name . '">' . $conetnt . '</textarea><script>CKEDITOR.replace(\'' . $name . '\', { height: \'' . $height . '\', width: \'' . $width . '\' });</script>'; |
|||
return $result; |
|||
} |
|||
|
|||
/*** |
|||
* 日期筛选格式化 |
|||
* @param $dateran |
|||
* @return array |
|||
*/ |
|||
function get_dateran($dateran) |
|||
{ |
|||
if ($dateran) { |
|||
$dateran = explode(" 至 ", $dateran); |
|||
} |
|||
if (is_array($dateran) && count($dateran) == 2) { |
|||
$dateran[0] = strtotime($dateran[0]); |
|||
$dateran[1] = strtotime($dateran[1]) + 24 * 60 * 60 - 1; |
|||
} |
|||
return $dateran; |
|||
} |
|||
|
|||
/** |
|||
* 根据数组中某个字段重新分组 |
|||
* @param {dataArr:需要分组的数据;keyStr:分组依据} |
|||
* @return: array |
|||
*/ |
|||
function array_group(array $dataArr, string $keyStr): array |
|||
{ |
|||
$newArr = []; |
|||
foreach ($dataArr as $k => $val) { |
|||
$newArr[$val[$keyStr]][] = $val; |
|||
} |
|||
return $newArr; |
|||
} |
|||
|
|||
/*** |
|||
* 格式化面包导航(用户后台面包导航) |
|||
* @param $data |
|||
* @return array |
|||
*/ |
|||
function format_bread_crumb($data) |
|||
{ |
|||
$result = array(); |
|||
if (!empty($data)) { |
|||
$data = array_reverse($data); |
|||
if (count($data) == 4) { |
|||
//非常规 添加或修改 |
|||
$result['right'] = $data[1]; |
|||
$result['left'][0] = $data[1]['title']; |
|||
//查看是添加还是修改 |
|||
$result['left'][1] = $data[2]['title'] . '-' . str_replace('操作-', '', $data[3]['title']); |
|||
} else if (count($data) == 3) { |
|||
//常规 添加或修改 |
|||
$result['right'] = $data[1]; |
|||
$result['left'][0] = $data[1]['title']; |
|||
//查看是添加还是修改 |
|||
$result['left'][1] = str_replace('操作-', '', $data[2]['title']); |
|||
} else if (count($data) == 2) { |
|||
//常规 列表 |
|||
$result['right'] = $data[1]; |
|||
$result['left'][0] = $data[1]['title']; |
|||
$result['left'][1] = '列表'; |
|||
} else { |
|||
//单独定义 |
|||
$result['right'] = $data[0]; |
|||
$result['left'][0] = $data[0]['title']; |
|||
$result['left'][1] = ''; |
|||
} |
|||
} |
|||
|
|||
// 内容管理重构数组 |
|||
$controller = \think\facade\Request::controller(); |
|||
$module = \app\common\model\Module::where('model_name', $controller)->find(); |
|||
|
|||
if ($module && $module->table_type == 1) { |
|||
// 判断当前方法是添加、修改、列表 |
|||
$action = \think\facade\Request::action(); |
|||
if ($action == 'add') { |
|||
$action = '添加'; |
|||
} else if ($action == 'edit') { |
|||
$action = '修改'; |
|||
} else { |
|||
$action = '列表'; |
|||
} |
|||
|
|||
// 内容管理 |
|||
$cateId = \think\facade\Request::param('cate_id'); |
|||
if (empty($cateId)) { |
|||
$model = '\app\common\model\\' . $module->model_name; |
|||
if ($module['pk'] && \think\facade\Request::param('id')) { |
|||
$cateId = $model::where($module['pk'], \think\facade\Request::param('id'))->value('cate_id'); |
|||
} |
|||
} |
|||
|
|||
// 调用当前栏目名称 |
|||
if ($cateId) { |
|||
$cateName = \app\common\model\Cate::where('id', $cateId)->value('cate_name'); |
|||
if ($module->is_single) { |
|||
$url = 'edit?id=' . \think\facade\Request::param('id'); |
|||
} else { |
|||
$url = 'index?cate_id=' . $cateId; |
|||
} |
|||
$result['right'] = [ |
|||
'url' => $url, |
|||
'title' => $cateName, |
|||
'icon' => '', |
|||
]; |
|||
$result['left'][0] = $cateName; |
|||
$result['left'][1] = $action; |
|||
} |
|||
|
|||
} |
|||
|
|||
return $result; |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
<?php |
|||
// +---------------------------------------------------------------------- |
|||
// | 应用设置 |
|||
// +---------------------------------------------------------------------- |
|||
|
|||
return [ |
|||
// 默认分页显示数量 |
|||
'page_size' => 10, |
|||
// 版本信息 |
|||
'siyu_version' => '6.1.7', |
|||
// 默认跳转页面对应的模板文件 |
|||
'dispatch_success_tmpl' => app()->getBasePath() . 'common' . DIRECTORY_SEPARATOR . 'view' . DIRECTORY_SEPARATOR . 'dispatch_jump.tpl', |
|||
'dispatch_error_tmpl' => app()->getBasePath() . 'common' . DIRECTORY_SEPARATOR . 'view' . DIRECTORY_SEPARATOR . 'dispatch_jump.tpl', |
|||
]; |
|||
@ -0,0 +1,23 @@ |
|||
<?php |
|||
// +---------------------------------------------------------------------- |
|||
// | 构建器设置 |
|||
// +---------------------------------------------------------------------- |
|||
|
|||
return [ |
|||
// CMS模块添加字段时是否需要自动增加栏目ID等字段 |
|||
'add_cate_id' => true, |
|||
// select2 插件是否启用ajax分页 |
|||
'select2_ajax' => true, |
|||
// 添加/编辑等页启用layer弹层加载 |
|||
'layer_open' => env('builder.layer_open', true), |
|||
// 不可生成的模块[内置模块][模型名称] |
|||
'un_make_module' => [ |
|||
'Field', // 字段 |
|||
'Module', // 模型 |
|||
'AuthGroup', // 角色组 |
|||
'Admin', // 管理员 |
|||
'AuthRule', // 菜单规则 |
|||
'AdminLog', // 管理员日志 |
|||
'Cate', // 栏目管理 |
|||
], |
|||
]; |
|||
@ -0,0 +1,20 @@ |
|||
<?php |
|||
|
|||
use think\facade\Env; |
|||
|
|||
return [ |
|||
'default' => Env::get('filesystem.driver', 'local'), |
|||
'disks' => [ |
|||
'local' => [ |
|||
'type' => 'local', |
|||
'root' => app()->getRuntimePath() . 'storage', |
|||
], |
|||
'public' => [ |
|||
'type' => 'local', |
|||
'root' => app()->getRootPath() . 'public', |
|||
'url' => '', |
|||
'visibility' => 'public', |
|||
], |
|||
// 更多的磁盘配置信息 |
|||
], |
|||
]; |
|||
@ -0,0 +1,9 @@ |
|||
<?php |
|||
// +---------------------------------------------------------------------- |
|||
// | 模板设置 |
|||
// +---------------------------------------------------------------------- |
|||
|
|||
return [ |
|||
// 开启模板布局 |
|||
'layout_on' => true, |
|||
]; |
|||
@ -0,0 +1,47 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 广告管理控制器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2021/06/23 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\controller; |
|||
|
|||
// 引入框架内置类 |
|||
use think\facade\Request; |
|||
|
|||
// 引入表格和表单构建器 |
|||
use app\common\facade\MakeBuilder; |
|||
use app\common\builder\FormBuilder; |
|||
use app\common\builder\TableBuilder; |
|||
|
|||
class Ad extends Base |
|||
{ |
|||
// 验证器 |
|||
protected $validate = 'Ad'; |
|||
|
|||
// 当前主表 |
|||
protected $tableName = 'ad'; |
|||
|
|||
// 当前主模型 |
|||
protected $modelName = 'Ad'; |
|||
|
|||
} |
|||
@ -0,0 +1,47 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 广告分组控制器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2021/06/23 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\controller; |
|||
|
|||
// 引入框架内置类 |
|||
use think\facade\Request; |
|||
|
|||
// 引入表格和表单构建器 |
|||
use app\common\facade\MakeBuilder; |
|||
use app\common\builder\FormBuilder; |
|||
use app\common\builder\TableBuilder; |
|||
|
|||
class AdType extends Base |
|||
{ |
|||
// 验证器 |
|||
protected $validate = 'AdType'; |
|||
|
|||
// 当前主表 |
|||
protected $tableName = 'ad_type'; |
|||
|
|||
// 当前主模型 |
|||
protected $modelName = 'AdType'; |
|||
|
|||
} |
|||
@ -0,0 +1,230 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 管理员列表控制器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2020/02/03 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\controller; |
|||
|
|||
// 引入框架内置类 |
|||
use think\facade\Request; |
|||
|
|||
// 引入表格和表单构建器 |
|||
use app\common\facade\MakeBuilder; |
|||
use app\common\builder\FormBuilder; |
|||
use app\common\builder\TableBuilder; |
|||
use think\facade\Session; |
|||
|
|||
class Admin extends Base |
|||
{ |
|||
// 验证器 |
|||
protected $validate = 'Admin'; |
|||
|
|||
// 当前主表 |
|||
protected $tableName = 'admin'; |
|||
|
|||
// 当前主模型 |
|||
protected $modelName = 'Admin'; |
|||
|
|||
// 列表 |
|||
public function index(){ |
|||
// 获取主键 |
|||
$pk = MakeBuilder::getPrimarykey($this->tableName); |
|||
// 获取列表数据 |
|||
$columns = MakeBuilder::getListColumns($this->tableName); |
|||
// 插入`角色组`字段到第1个元素 |
|||
array_splice($columns, 1, 0, [['group_name','角色组','text','',[],'','false']]); |
|||
// 获取搜索数据 |
|||
$search = MakeBuilder::getListSearch($this->tableName); |
|||
// 获取当前模块信息 |
|||
$model = '\app\common\model\\' . $this->modelName; |
|||
$module = \app\common\model\Module::where('table_name', $this->tableName)->find(); |
|||
// 搜索 |
|||
if (Request::param('getList') == 1) { |
|||
$where = MakeBuilder::getListWhere($this->tableName); |
|||
$orderByColumn = Request::param('orderByColumn') ?? $pk; |
|||
$isAsc = Request::param('isAsc') ?? 'desc'; |
|||
return $model::getList($where, $this->pageSize, [$orderByColumn => $isAsc]); |
|||
} |
|||
// 构建页面 |
|||
return TableBuilder::getInstance() |
|||
->setUniqueId($pk) // 设置主键 |
|||
->addColumns($columns) // 添加列表字段数据 |
|||
->setSearch($search) // 添加头部搜索 |
|||
->addColumn('right_button', '操作', 'btn') // 启用右侧操作列 |
|||
->addRightButtons($module->right_button) // 设置右侧操作列 |
|||
->addTopButtons($module->top_button) // 设置顶部按钮组 |
|||
->fetch(); |
|||
} |
|||
|
|||
// 添加 |
|||
public function add() |
|||
{ |
|||
// 获取字段信息 |
|||
$columns = MakeBuilder::getAddColumns($this->tableName); |
|||
// 获取分组后的字段信息 |
|||
$groups = MakeBuilder::getAddGroups($this->modelName, $this->tableName, $columns); |
|||
|
|||
// 构建页面 |
|||
$builder = FormBuilder::getInstance(); |
|||
$builder->addSelect('group_id', '角色组', '', $this->getAuthGroupOptions(), '', '', '', '', true); |
|||
$groups ? $builder->addGroup($groups) : $builder->addFormItems($columns); |
|||
return $builder->fetch(); |
|||
} |
|||
|
|||
// 添加保存 |
|||
public function addPost() |
|||
{ |
|||
if (Request::isPost()) { |
|||
$data = MakeBuilder::changeFormData(Request::except(['file'], 'post'), $this->tableName); |
|||
$data['group_id'] = Request::param('group_id'); |
|||
// 单独校验并去除角色组 |
|||
if (empty($data['group_id'])) { |
|||
$this->error('请选择角色组'); |
|||
} else { |
|||
$groupId = $data['group_id']; |
|||
unset($data['group_id']); |
|||
} |
|||
//单独验证密码 |
|||
if (empty($data['password'])) { |
|||
$this->error('密码不能为空'); |
|||
} |
|||
$result = $this->validate($data, $this->validate); |
|||
$data['login_time'] = time(); |
|||
$data['login_ip'] = Request::ip(); |
|||
if (true !== $result) { |
|||
// 验证失败 输出错误信息 |
|||
$this->error($result); |
|||
} else { |
|||
$model = '\app\common\model\\' . $this->modelName; |
|||
$result = $model::create($data); |
|||
\app\common\model\AuthGroupAccess::create([ |
|||
'uid' => $result->id, |
|||
'group_id' => $groupId |
|||
]); |
|||
$this->success('添加成功', 'index'); |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 修改 |
|||
public function edit(string $id) |
|||
{ |
|||
$model = '\app\common\model\\' . $this->modelName; |
|||
$info = $model::edit($id)->toArray(); |
|||
// 获取字段信息 |
|||
$columns = MakeBuilder::getAddColumns($this->tableName, $info); |
|||
// 获取分组后的字段信息 |
|||
$groups = MakeBuilder::getAddGroups($this->modelName, $this->tableName, $columns); |
|||
// 获取当前管理员的分组 |
|||
$groupId = \app\common\model\AuthGroupAccess::where('uid', $info['id']) |
|||
->value('group_id'); |
|||
|
|||
// 构建页面 |
|||
$builder = FormBuilder::getInstance(); |
|||
$builder->addSelect('group_id', '角色组', '', $this->getAuthGroupOptions(), $groupId, '', '', '', true); |
|||
$groups ? $builder->addGroup($groups) : $builder->addFormItems($columns); |
|||
return $builder->fetch(); |
|||
} |
|||
|
|||
// 修改保存 |
|||
public function editPost() |
|||
{ |
|||
if (Request::isPost()) { |
|||
$data = MakeBuilder::changeFormData(Request::except(['file'], 'post'), $this->tableName); |
|||
$data['group_id'] = Request::param('group_id'); |
|||
if (!$data['group_id']) { |
|||
$this->error('请选择角色组!'); |
|||
} |
|||
|
|||
if (Session::get('admin.group_id') != 1) { |
|||
// 非管理员组不可修改他人信息 |
|||
if (Session::get('admin.id') != $data['id']) { |
|||
$this->error('非管理员组人员不可修改他人信息!', 'index'); |
|||
} |
|||
// 非管理员组不可修改角色组 |
|||
if (Session::get('admin.group_id') != $data['group_id']) { |
|||
$this->error('非管理员组人员不可修改所属角色组!', 'index'); |
|||
} |
|||
} |
|||
|
|||
$where['id'] = $data['id']; |
|||
|
|||
$group_id = $data['group_id']; |
|||
unset($data['group_id']); |
|||
|
|||
$result = $this->validate($data,'Admin'); |
|||
if (true !== $result) { |
|||
$this->error($result); |
|||
} |
|||
\app\common\model\Admin::update($data, $where); |
|||
\app\common\model\AuthGroupAccess::update([ |
|||
'group_id' => $group_id |
|||
], ['uid'=>$data['id']]); |
|||
$this->success('修改成功!', 'index'); |
|||
} |
|||
} |
|||
|
|||
// 删除 |
|||
public function del(string $id) |
|||
{ |
|||
if (Request::isPost()) { |
|||
if ($id == 1) { |
|||
return json(['error' => 1, 'msg' => '超级管理员不可删除!']); |
|||
} |
|||
if (strpos($id, ',') !== false) { |
|||
return $this->selectDel($id); |
|||
} |
|||
$model = '\app\common\model\\' . $this->modelName; |
|||
return $model::del($id); |
|||
} |
|||
} |
|||
|
|||
// 批量删除 |
|||
public function selectDel(string $id){ |
|||
if (Request::isPost()) { |
|||
$ids = explode(',',$id); |
|||
if (in_array(1, $ids)) { |
|||
return json(['error' => 1, 'msg' => '超级管理员不可删除!']); |
|||
} |
|||
$model = '\app\common\model\\' . $this->modelName; |
|||
return $model::selectDel($id); |
|||
} |
|||
} |
|||
|
|||
//=========================== |
|||
|
|||
// 获取角色分组信息 |
|||
private function getAuthGroupOptions() |
|||
{ |
|||
// 获取角色组 |
|||
$authGroup = \app\common\model\AuthGroup::where('status', '=', 1) |
|||
->select() |
|||
->toArray(); |
|||
$groupOptions = []; |
|||
foreach ($authGroup as $k => $v) { |
|||
$groupOptions[$v['id']] = $v['title']; |
|||
} |
|||
return $groupOptions; |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,69 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 管理员日志控制器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2020/02/03 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\controller; |
|||
|
|||
// 引入框架内置类 |
|||
use think\facade\Request; |
|||
|
|||
// 引入表格和表单构建器 |
|||
use app\common\facade\MakeBuilder; |
|||
use app\common\builder\FormBuilder; |
|||
use app\common\builder\TableBuilder; |
|||
|
|||
class AdminLog extends Base |
|||
{ |
|||
// 验证器 |
|||
protected $validate = 'AdminLog'; |
|||
|
|||
// 当前主表 |
|||
protected $tableName = 'admin_log'; |
|||
|
|||
// 当前主模型 |
|||
protected $modelName = 'AdminLog'; |
|||
|
|||
// 修改 |
|||
public function edit(string $id) |
|||
{ |
|||
$model = '\app\common\model\\' . $this->modelName; |
|||
$info = $model::edit($id)->toArray(); |
|||
// 获取字段信息 |
|||
$columns = MakeBuilder::getAddColumns($this->tableName, $info); |
|||
// 获取分组后的字段信息 |
|||
$groups = MakeBuilder::getAddGroups($this->modelName, $this->tableName, $columns); |
|||
// 隐藏<显示全部>按钮 |
|||
$hideShowAll = MakeBuilder::getHideShowAll($this->tableName); |
|||
|
|||
// 构建页面 |
|||
$builder = FormBuilder::getInstance(); |
|||
if ($hideShowAll) { |
|||
$builder->hideShowAll(); |
|||
} |
|||
$builder->hideBtn(['submit','back']); |
|||
$groups ? $builder->addGroup($groups) : $builder->addFormItems($columns); |
|||
return $builder->fetch(); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,47 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 文章模块控制器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2021/06/23 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\controller; |
|||
|
|||
// 引入框架内置类 |
|||
use think\facade\Request; |
|||
|
|||
// 引入表格和表单构建器 |
|||
use app\common\facade\MakeBuilder; |
|||
use app\common\builder\FormBuilder; |
|||
use app\common\builder\TableBuilder; |
|||
|
|||
class Article extends Base |
|||
{ |
|||
// 验证器 |
|||
protected $validate = 'Article'; |
|||
|
|||
// 当前主表 |
|||
protected $tableName = 'article'; |
|||
|
|||
// 当前主模型 |
|||
protected $modelName = 'Article'; |
|||
|
|||
} |
|||
@ -0,0 +1,134 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 角色组管理控制器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2020/02/02 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
|
|||
namespace app\admin\controller; |
|||
|
|||
// 引入框架内置类 |
|||
use think\facade\Request; |
|||
|
|||
// 引入表格和表单构建器 |
|||
use app\common\facade\MakeBuilder; |
|||
use app\common\builder\FormBuilder; |
|||
use app\common\builder\TableBuilder; |
|||
use think\facade\View; |
|||
|
|||
class AuthGroup extends Base |
|||
{ |
|||
// 验证器 |
|||
protected $validate = 'AuthGroup'; |
|||
|
|||
// 当前主表 |
|||
protected $tableName = 'auth_group'; |
|||
|
|||
// 当前主模型 |
|||
protected $modelName = 'AuthGroup'; |
|||
|
|||
// 列表 |
|||
public function index() |
|||
{ |
|||
// 获取主键 |
|||
$pk = MakeBuilder::getPrimarykey($this->tableName); |
|||
// 获取列表数据 |
|||
$columns = MakeBuilder::getListColumns($this->tableName); |
|||
// 获取搜索数据 |
|||
$search = MakeBuilder::getListSearch($this->tableName); |
|||
// 获取当前模块信息 |
|||
$model = '\app\common\model\\' . $this->modelName; |
|||
$module = \app\common\model\Module::where('table_name', $this->tableName)->find(); |
|||
// 搜索 |
|||
if (Request::param('getList') == 1) { |
|||
$where = MakeBuilder::getListWhere($this->tableName); |
|||
$orderByColumn = Request::param('orderByColumn') ?? $pk; |
|||
$isAsc = Request::param('isAsc') ?? 'desc'; |
|||
return $model::getList($where, $this->pageSize, [$orderByColumn => $isAsc]); |
|||
} |
|||
// 检测单页模式 |
|||
$isSingle = MakeBuilder::checkSingle($this->modelName); |
|||
if ($isSingle) { |
|||
return $this->jump($isSingle); |
|||
} |
|||
// 获取新增地址 |
|||
$addUlr = MakeBuilder::getAddUrl($this->tableName); |
|||
// 构建页面 |
|||
return TableBuilder::getInstance() |
|||
->setUniqueId($pk) // 设置主键 |
|||
->addColumns($columns) // 添加列表字段数据 |
|||
->setSearch($search) // 添加头部搜索 |
|||
->addColumn('right_button', '操作', 'btn') // 启用右侧操作列 |
|||
->addRightButton('info', [ |
|||
'title' => '权限', |
|||
'icon' => 'far fa-check-square', |
|||
'class' => 'btn btn-warning btn-xs confirm', |
|||
'href' => url('access', ['id' => '__id__']) |
|||
]) // 添加额外按钮 |
|||
->addRightButtons($module->right_button) // 设置右侧操作列 |
|||
->addTopButtons($module->top_button) // 设置顶部按钮组 |
|||
->setAddUrl($addUlr) // 设置新增地址 |
|||
->fetch(); |
|||
} |
|||
|
|||
//=================================== |
|||
|
|||
// 权限 |
|||
public function access(string $id) |
|||
{ |
|||
// 获取菜单规则 |
|||
$authRule = \app\common\model\AuthRule::field('id, pid, title') |
|||
->order('sort asc') |
|||
->select() |
|||
->toArray(); |
|||
// 获取当前组权限并格式化 |
|||
$rules = \app\common\model\AuthGroup::where('id', $id)->value('rules'); |
|||
$list = auth($authRule, 0, $rules); |
|||
$list[] = array( |
|||
"id" => 0, |
|||
"pid" => 0, |
|||
"title" => "全部", |
|||
"open" => true |
|||
); |
|||
$view = [ |
|||
'list' => $list |
|||
]; |
|||
View::assign($view); |
|||
return View::fetch('auth/group_access'); |
|||
} |
|||
|
|||
// 权限保存 |
|||
public function accessPost() |
|||
{ |
|||
$rules = Request::post('rules'); |
|||
if (empty($rules)) { |
|||
return json(['msg' => '请选择权限!', 'error' => 1]); |
|||
} |
|||
$data = Request::post(); |
|||
$where['id'] = $data['id']; |
|||
if (\app\common\model\AuthGroup::update($data, $where)) { |
|||
return json(['msg' => '修改成功!', 'url' => url('index')->__toString(), 'error' => 0]); |
|||
} else { |
|||
return json(['msg' => '修改失败', 'error' => 1]); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,165 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 菜单规则控制器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2020/02/03 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
|
|||
namespace app\admin\controller; |
|||
|
|||
// 引入框架内置类 |
|||
use think\facade\Request; |
|||
|
|||
// 引入表格和表单构建器 |
|||
use app\common\facade\MakeBuilder; |
|||
use app\common\builder\FormBuilder; |
|||
use app\common\builder\TableBuilder; |
|||
|
|||
class AuthRule extends Base |
|||
{ |
|||
// 验证器 |
|||
protected $validate = 'AuthRule'; |
|||
|
|||
// 当前主表 |
|||
protected $tableName = 'auth_rule'; |
|||
|
|||
// 当前主模型 |
|||
protected $modelName = 'AuthRule'; |
|||
|
|||
// 列表 |
|||
public function index() |
|||
{ |
|||
// 获取主键 |
|||
$pk = MakeBuilder::getPrimarykey($this->tableName); |
|||
// 获取列表数据 |
|||
$columns = MakeBuilder::getListColumns($this->tableName); |
|||
// 获取搜索数据 |
|||
$search = MakeBuilder::getListSearch($this->tableName); |
|||
// 获取当前模块信息 |
|||
$model = '\app\common\model\\' . $this->modelName; |
|||
$module = \app\common\model\Module::where('table_name', $this->tableName)->find(); |
|||
// 搜索 |
|||
if (Request::param('getList') == 1) { |
|||
$where = MakeBuilder::getListWhere($this->tableName); |
|||
$orderByColumn = Request::param('orderByColumn') ?? $pk; |
|||
$isAsc = Request::param('isAsc') ?? 'desc'; |
|||
return $model::getList($where, $this->pageSize, [$orderByColumn => $isAsc]); |
|||
} |
|||
// 检测单页模式 |
|||
$isSingle = MakeBuilder::checkSingle($this->modelName); |
|||
if ($isSingle) { |
|||
return $this->jump($isSingle); |
|||
} |
|||
// 获取新增地址 |
|||
$addUlr = MakeBuilder::getAddUrl($this->tableName); |
|||
// 构建页面 |
|||
return TableBuilder::getInstance() |
|||
->setUniqueId($pk) // 设置主键 |
|||
->addColumns($columns) // 添加列表字段数据 |
|||
->setSearch($search) // 添加头部搜索 |
|||
->addColumn('right_button', '操作', 'btn') // 启用右侧操作列 |
|||
->addRightButton('info', [ // 添加额外按钮 |
|||
'title' => '添加', |
|||
'icon' => 'fa fa-plus', |
|||
'class' => 'btn btn-success btn-xs', |
|||
'href' => url('add', ['pid' => '__id__']) |
|||
]) |
|||
->addRightButtons($module->right_button) // 设置右侧操作列 |
|||
->addTopButtons($module->top_button) // 设置顶部按钮组 |
|||
->setAddUrl($addUlr) // 设置新增地址 |
|||
->addTopButton('default', [ |
|||
'title' => '展开/折叠', |
|||
'icon' => 'fas fa-exchange-alt', |
|||
'class' => 'btn btn-info treeStatus', |
|||
'href' => '', |
|||
'onclick' => '$.operate.treeStatus()' |
|||
]) // 自定义按钮 |
|||
->setPagination('false') // 关闭分页显示 |
|||
->setParentIdField('pid') // 设置列表树父id |
|||
->fetch(); |
|||
} |
|||
|
|||
// 添加 |
|||
public function add(string $pid = '') |
|||
{ |
|||
// 获取字段信息 |
|||
$columns = MakeBuilder::getAddColumns($this->tableName); |
|||
|
|||
// 获取父ID数据 |
|||
foreach ($columns as $k => $v) { |
|||
if ($v[1] == 'pid') { |
|||
$model = '\app\common\model\\' . $this->modelName; |
|||
$pidOptions = $model::getPidOptions(); |
|||
// 设置父ID选项 |
|||
$columns[$k][4] = $pidOptions; |
|||
// 设置父ID默认值 |
|||
if ($pid) { |
|||
$columns[$k][5] = $pid; |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 获取分组后的字段信息 |
|||
$groups = MakeBuilder::getAddGroups($this->modelName, $this->tableName, $columns); |
|||
// 隐藏<显示全部>按钮 |
|||
$hideShowAll = MakeBuilder::getHideShowAll($this->tableName); |
|||
|
|||
// 构建页面 |
|||
$builder = FormBuilder::getInstance(); |
|||
if ($hideShowAll) { |
|||
$builder->hideShowAll(); |
|||
} |
|||
$groups ? $builder->addGroup($groups) : $builder->addFormItems($columns); |
|||
return $builder->fetch(); |
|||
} |
|||
|
|||
// 修改 |
|||
public function edit(string $id) |
|||
{ |
|||
$model = '\app\common\model\\' . $this->modelName; |
|||
$info = $model::edit($id)->toArray(); |
|||
// 获取字段信息 |
|||
$columns = MakeBuilder::getAddColumns($this->tableName, $info); |
|||
|
|||
// 获取父ID数据 |
|||
foreach ($columns as $k => $v) { |
|||
if ($v[1] == 'pid') { |
|||
$model = '\app\common\model\\' . $this->modelName; |
|||
$pidOptions = $model::getPidOptions(); |
|||
$columns[$k][4] = $pidOptions; |
|||
} |
|||
} |
|||
|
|||
// 获取分组后的字段信息 |
|||
$groups = MakeBuilder::getAddGroups($this->modelName, $this->tableName, $columns); |
|||
// 隐藏<显示全部>按钮 |
|||
$hideShowAll = MakeBuilder::getHideShowAll($this->tableName); |
|||
|
|||
// 构建页面 |
|||
$builder = FormBuilder::getInstance(); |
|||
if ($hideShowAll) { |
|||
$builder->hideShowAll(); |
|||
} |
|||
$groups ? $builder->addGroup($groups) : $builder->addFormItems($columns); |
|||
return $builder->fetch(); |
|||
} |
|||
} |
|||
@ -0,0 +1,476 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 基础控制器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2020/03/08 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
declare (strict_types=1); |
|||
|
|||
namespace app\admin\controller; |
|||
|
|||
// 引入框架内置类 |
|||
use think\App; |
|||
use think\exception\HttpResponseException; |
|||
use think\exception\ValidateException; |
|||
use think\facade\Config; |
|||
use think\facade\Request; |
|||
use think\facade\View; |
|||
use think\Response; |
|||
use think\Validate; |
|||
|
|||
// 引入表格和表单构建器 |
|||
use app\common\builder\FormBuilder; |
|||
use app\common\builder\TableBuilder; |
|||
use app\common\facade\MakeBuilder; |
|||
|
|||
/** |
|||
* 控制器基础类 |
|||
*/ |
|||
abstract class Base |
|||
{ |
|||
/** |
|||
* Request实例 |
|||
* @var \think\Request |
|||
*/ |
|||
protected $request; |
|||
|
|||
/** |
|||
* 应用实例 |
|||
* @var \think\App |
|||
*/ |
|||
protected $app; |
|||
|
|||
/** |
|||
* 是否批量验证 |
|||
* @var bool |
|||
*/ |
|||
protected $batchValidate = false; |
|||
|
|||
/** |
|||
* 控制器中间件 |
|||
* @var array |
|||
*/ |
|||
protected $middleware = ['app\admin\middleware\Admin']; |
|||
|
|||
/** |
|||
* 分页数量 |
|||
* @var string |
|||
*/ |
|||
protected $pageSize = ''; |
|||
|
|||
/** |
|||
* 系统设置 |
|||
* @var array |
|||
*/ |
|||
protected $system = []; |
|||
|
|||
/** |
|||
* 构造方法 |
|||
* @access public |
|||
* @param App $app 应用对象 |
|||
*/ |
|||
public function __construct(App $app) |
|||
{ |
|||
$this->app = $app; |
|||
$this->request = $this->app->request; |
|||
|
|||
// 控制器初始化 |
|||
$this->initialize(); |
|||
} |
|||
|
|||
// 初始化 |
|||
protected function initialize() |
|||
{ |
|||
// 每页显示数据量 |
|||
$this->pageSize = (int)Request::param('pageSize', Config::get('app.page_size')); |
|||
|
|||
// 左侧菜单 |
|||
$menus = \app\admin\model\Base::getMenus(); |
|||
View::assign(['menus' => $menus]); |
|||
|
|||
// 面包导航 |
|||
$auth = new \Auth(); |
|||
$breadCrumb = $auth->getBreadCrumb(); |
|||
$breadCrumb = format_bread_crumb($breadCrumb); |
|||
View::assign(['breadCrumb' => $breadCrumb]); |
|||
|
|||
// 内容管理,获取栏目列表 |
|||
if (class_exists('\app\common\model\Cate')) { |
|||
$cates = \app\common\model\Cate::getList(); |
|||
} |
|||
View::assign(['cates' => unlimitedForLayer($cates['data'] ?? [])]); |
|||
|
|||
// index应用地址 |
|||
$domainBind = Config::get('app.domain_bind'); |
|||
if ($domainBind) { |
|||
$domainBindKey = array_search('index', $domainBind); |
|||
$domainBindKey = $domainBindKey == '*' ? 'www.' : ($domainBindKey ? $domainBindKey . '.' : ''); |
|||
$indexUrl = Request::scheme() . '://' . $domainBindKey . Request::rootDomain() . '/'; |
|||
} |
|||
View::assign(['indexUrl' => $indexUrl ?? '/']); |
|||
|
|||
// 查询系统设置 |
|||
$system = \app\common\model\System::find(1); |
|||
$this->system = $system; |
|||
View::assign(['system' => $system]); |
|||
|
|||
// pjax单页面模式 |
|||
if (Request::has('_pjax')) { |
|||
View::assign(['pjax' => true]); |
|||
} else { |
|||
View::assign(['pjax' => false]); |
|||
} |
|||
|
|||
// iframe多标签模式 |
|||
if ($system['display_mode'] == 1) { |
|||
if ($this->request->controller() == 'Index' && $this->request->action() == 'index') { |
|||
View::assign(['iframe' => false]); |
|||
} else { |
|||
View::assign(['iframe' => true]); |
|||
} |
|||
} else { |
|||
View::assign(['iframe' => false]); |
|||
} |
|||
|
|||
// layer open |
|||
if (Request::has('_layer')) { |
|||
View::assign(['layer' => true]); |
|||
} else { |
|||
View::assign(['layer' => false]); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 验证数据 |
|||
* @access protected |
|||
* @param array $data 数据 |
|||
* @param string|array $validate 验证器名或者验证规则数组 |
|||
* @param array $message 提示信息 |
|||
* @param bool $batch 是否批量验证 |
|||
* @return array|string|true |
|||
* @throws ValidateException |
|||
*/ |
|||
protected function validate(array $data, $validate, array $message = [], bool $batch = false) |
|||
{ |
|||
if (is_array($validate)) { |
|||
$v = new Validate(); |
|||
$v->rule($validate); |
|||
} else { |
|||
if (strpos($validate, '.')) { |
|||
// 支持场景 |
|||
list($validate, $scene) = explode('.', $validate); |
|||
} |
|||
$class = false !== strpos($validate, '\\') ? $validate : $this->app->parseClass('validate', $validate); |
|||
$v = new $class(); |
|||
if (!empty($scene)) { |
|||
$v->scene($scene); |
|||
} |
|||
} |
|||
|
|||
$v->message($message); |
|||
|
|||
//是否批量验证 |
|||
if ($batch || $this->batchValidate) { |
|||
$v->batch(true); |
|||
} |
|||
|
|||
$result = $v->failException(false)->check($data); |
|||
if (true !== $result) { |
|||
return $v->getError(); |
|||
} else { |
|||
return $result; |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 操作错误跳转 |
|||
* @param mixed $msg 提示信息 |
|||
* @param string $url 跳转的URL地址 |
|||
* @param mixed $data 返回的数据 |
|||
* @param integer $wait 跳转等待时间 |
|||
* @param array $header 发送的Header信息 |
|||
* @return void |
|||
*/ |
|||
protected function error($msg = '', string $url = null, $data = '', int $wait = 3, array $header = []): Response |
|||
{ |
|||
if (is_null($url)) { |
|||
$url = request()->isAjax() ? '' : 'javascript:history.back(-1);'; |
|||
} elseif ($url) { |
|||
$url = (strpos($url, '://') || 0 === strpos($url, '/')) ? $url : app('route')->buildUrl($url)->__toString(); |
|||
} |
|||
|
|||
$result = [ |
|||
'code' => 0, |
|||
'msg' => $msg, |
|||
'data' => $data, |
|||
'url' => $url, |
|||
'wait' => $wait, |
|||
]; |
|||
|
|||
$type = (request()->isJson() || request()->isAjax()) ? 'json' : 'html'; |
|||
if ($type == 'html') { |
|||
$response = view(app('config')->get('app.dispatch_error_tmpl'), $result); |
|||
} else if ($type == 'json') { |
|||
$response = json($result); |
|||
} |
|||
throw new HttpResponseException($response); |
|||
} |
|||
|
|||
/** |
|||
* 返回封装后的API数据到客户端 |
|||
* @param mixed $data 要返回的数据 |
|||
* @param integer $code 返回的code |
|||
* @param mixed $msg 提示信息 |
|||
* @param string $type 返回数据格式 |
|||
* @param array $header 发送的Header信息 |
|||
* @return Response |
|||
*/ |
|||
protected function result($data, int $code = 0, $msg = '', string $type = '', array $header = []): Response |
|||
{ |
|||
$result = [ |
|||
'code' => $code, |
|||
'msg' => $msg, |
|||
'time' => time(), |
|||
'data' => $data, |
|||
]; |
|||
|
|||
$type = $type ?: 'json'; |
|||
$response = Response::create($result, $type)->header($header); |
|||
|
|||
throw new HttpResponseException($response); |
|||
} |
|||
|
|||
/** |
|||
* 操作成功跳转 |
|||
* @param mixed $msg 提示信息 |
|||
* @param string $url 跳转的URL地址 |
|||
* @param mixed $data 返回的数据 |
|||
* @param integer $wait 跳转等待时间 |
|||
* @param array $header 发送的Header信息 |
|||
* @return void |
|||
*/ |
|||
protected function success($msg = '', string $url = null, $data = '', int $wait = 3, array $header = []): Response |
|||
{ |
|||
if (is_null($url) && isset($_SERVER["HTTP_REFERER"])) { |
|||
$url = $_SERVER["HTTP_REFERER"]; |
|||
} elseif ($url) { |
|||
$url = (strpos($url, '://') || 0 === strpos($url, '/')) ? $url : app('route')->buildUrl($url, get_back_url())->__toString(); |
|||
} |
|||
|
|||
$result = [ |
|||
'code' => 1, |
|||
'msg' => $msg, |
|||
'data' => $data, |
|||
'url' => $url, |
|||
'wait' => $wait, |
|||
]; |
|||
|
|||
$type = (request()->isJson() || request()->isAjax()) ? 'json' : 'html'; |
|||
if ($type == 'html') { |
|||
$response = view(app('config')->get('app.dispatch_success_tmpl'), $result); |
|||
} else if ($type == 'json') { |
|||
$response = json($result); |
|||
} |
|||
throw new HttpResponseException($response); |
|||
} |
|||
|
|||
/** |
|||
* 跳转页 |
|||
* @param string $url |
|||
* @return Response |
|||
*/ |
|||
protected function jump(string $url = '') |
|||
{ |
|||
if ($this->request->isPjax()) { |
|||
return response('<span style="display: none">loading...</span>', 200, ['X-PJAX-URL' => $url]); |
|||
} else { |
|||
return redirect($url); |
|||
} |
|||
} |
|||
|
|||
|
|||
// 列表 |
|||
public function index() |
|||
{ |
|||
// 获取主键 |
|||
$pk = MakeBuilder::getPrimarykey($this->tableName); |
|||
// 获取列表数据 |
|||
$columns = MakeBuilder::getListColumns($this->tableName); |
|||
// 获取搜索数据 |
|||
$search = MakeBuilder::getListSearch($this->tableName); |
|||
// 获取当前模块信息 |
|||
$model = '\app\common\model\\' . $this->modelName; |
|||
$module = \app\common\model\Module::where('table_name', $this->tableName)->find(); |
|||
// 搜索 |
|||
if (Request::param('getList') == 1) { |
|||
$where = MakeBuilder::getListWhere($this->tableName); |
|||
$orderByColumn = Request::param('orderByColumn') ?? $pk; |
|||
$isAsc = Request::param('isAsc') ?? 'desc'; |
|||
return $model::getList($where, $this->pageSize, [$orderByColumn => $isAsc]); |
|||
} |
|||
// 检测单页模式 |
|||
$isSingle = MakeBuilder::checkSingle($this->modelName); |
|||
if ($isSingle) { |
|||
return $this->jump($isSingle); |
|||
} |
|||
// 获取新增地址 |
|||
$addUlr = MakeBuilder::getAddUrl($this->tableName); |
|||
// 构建页面 |
|||
return TableBuilder::getInstance() |
|||
->setUniqueId($pk) // 设置主键 |
|||
->addColumns($columns) // 添加列表字段数据 |
|||
->setSearch($search) // 添加头部搜索 |
|||
->addColumn('right_button', '操作', 'btn') // 启用右侧操作列 |
|||
->addRightButtons($module->right_button) // 设置右侧操作列 |
|||
->addTopButtons($module->top_button) // 设置顶部按钮组 |
|||
->setAddUrl($addUlr) // 设置新增地址 |
|||
->fetch(); |
|||
} |
|||
|
|||
// 添加 |
|||
public function add() |
|||
{ |
|||
// 获取字段信息 |
|||
$columns = MakeBuilder::getAddColumns($this->tableName); |
|||
// 获取分组后的字段信息 |
|||
$groups = MakeBuilder::getAddGroups($this->modelName, $this->tableName, $columns); |
|||
// 隐藏<显示全部>按钮 |
|||
$hideShowAll = MakeBuilder::getHideShowAll($this->tableName); |
|||
|
|||
// 构建页面 |
|||
$builder = FormBuilder::getInstance(); |
|||
if ($hideShowAll) { |
|||
$builder->hideShowAll(); |
|||
} |
|||
$groups ? $builder->addGroup($groups) : $builder->addFormItems($columns); |
|||
return $builder->fetch(); |
|||
} |
|||
|
|||
// 添加保存 |
|||
public function addPost() |
|||
{ |
|||
if (Request::isPost()) { |
|||
$data = MakeBuilder::changeFormData(Request::except(['file'], 'post'), $this->tableName); |
|||
$result = $this->validate($data, $this->validate); |
|||
if (true !== $result) { |
|||
// 验证失败 输出错误信息 |
|||
$this->error($result); |
|||
} else { |
|||
$model = '\app\common\model\\' . $this->modelName; |
|||
$result = $model::addPost($data); |
|||
if ($result['error']) { |
|||
$this->error($result['msg']); |
|||
} else { |
|||
$this->success($result['msg'], 'index'); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 修改 |
|||
public function edit(string $id) |
|||
{ |
|||
$model = '\app\common\model\\' . $this->modelName; |
|||
$info = $model::edit($id)->toArray(); |
|||
// 获取字段信息 |
|||
$columns = MakeBuilder::getAddColumns($this->tableName, $info); |
|||
// 获取分组后的字段信息 |
|||
$groups = MakeBuilder::getAddGroups($this->modelName, $this->tableName, $columns); |
|||
// 隐藏<显示全部>按钮 |
|||
$hideShowAll = MakeBuilder::getHideShowAll($this->tableName); |
|||
|
|||
// 构建页面 |
|||
$builder = FormBuilder::getInstance(); |
|||
if ($hideShowAll) { |
|||
$builder->hideShowAll(); |
|||
} |
|||
$groups ? $builder->addGroup($groups) : $builder->addFormItems($columns); |
|||
return $builder->fetch(); |
|||
} |
|||
|
|||
// 修改保存 |
|||
public function editPost() |
|||
{ |
|||
if (Request::isPost()) { |
|||
$data = MakeBuilder::changeFormData(Request::except(['file'], 'post'), $this->tableName); |
|||
$result = $this->validate($data, $this->validate); |
|||
if (true !== $result) { |
|||
// 验证失败 输出错误信息 |
|||
$this->error($result); |
|||
} else { |
|||
$model = '\app\common\model\\' . $this->modelName; |
|||
$result = $model::editPost($data); |
|||
if ($result['error']) { |
|||
$this->error($result['msg']); |
|||
} else { |
|||
$this->success($result['msg'], 'index'); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 删除 |
|||
public function del(string $id) |
|||
{ |
|||
if (Request::isPost()) { |
|||
if (strpos($id, ',') !== false) { |
|||
return $this->selectDel($id); |
|||
} |
|||
$model = '\app\common\model\\' . $this->modelName; |
|||
return $model::del($id); |
|||
} |
|||
} |
|||
|
|||
// 批量删除 |
|||
public function selectDel(string $id) |
|||
{ |
|||
if (Request::isPost()) { |
|||
$model = '\app\common\model\\' . $this->modelName; |
|||
return $model::selectDel($id); |
|||
} |
|||
} |
|||
|
|||
// 排序 |
|||
public function sort() |
|||
{ |
|||
if (Request::isPost()) { |
|||
$data = Request::post(); |
|||
$model = '\app\common\model\\' . $this->modelName; |
|||
return $model::sort($data); |
|||
} |
|||
} |
|||
|
|||
// 状态变更 |
|||
public function state(string $id) |
|||
{ |
|||
if (Request::isPost()) { |
|||
$model = '\app\common\model\\' . $this->modelName; |
|||
return $model::state($id); |
|||
} |
|||
} |
|||
|
|||
// 导出 |
|||
public function export() |
|||
{ |
|||
\app\common\model\Base::export($this->tableName, $this->modelName); |
|||
} |
|||
} |
|||
@ -0,0 +1,457 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 栏目管理控制器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2020/02/05 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\controller; |
|||
|
|||
// 引入框架内置类 |
|||
use think\facade\Request; |
|||
|
|||
// 引入表格和表单构建器 |
|||
use app\common\facade\MakeBuilder; |
|||
use app\common\builder\FormBuilder; |
|||
use app\common\builder\TableBuilder; |
|||
|
|||
class Cate extends Base |
|||
{ |
|||
// 验证器 |
|||
protected $validate = 'Cate'; |
|||
|
|||
// 当前主表 |
|||
protected $tableName = 'cate'; |
|||
|
|||
// 当前主模型 |
|||
protected $modelName = 'Cate'; |
|||
|
|||
// 列表 |
|||
public function index(){ |
|||
// 获取主键 |
|||
$pk = MakeBuilder::getPrimarykey($this->tableName); |
|||
// 获取列表数据 |
|||
$columns = MakeBuilder::getListColumns($this->tableName); |
|||
// 获取搜索数据 |
|||
$search = MakeBuilder::getListSearch($this->tableName); |
|||
// 获取当前模块信息 |
|||
$model = '\app\common\model\\' . $this->modelName; |
|||
$module = \app\common\model\Module::where('table_name', $this->tableName)->find(); |
|||
// 检测单页模式 |
|||
$isSingle = MakeBuilder::checkSingle($this->modelName); |
|||
if ($isSingle) { |
|||
return redirect($isSingle); |
|||
} |
|||
// 搜索 |
|||
if (Request::param('getList') == 1) { |
|||
return $model::getList(); |
|||
} |
|||
// 构建页面 |
|||
return TableBuilder::getInstance() |
|||
->setUniqueId($pk) // 设置主键 |
|||
->addColumns($columns) // 添加列表字段数据 |
|||
->setSearch($search) // 添加头部搜索 |
|||
->addColumn('right_button', '操作', 'btn') // 启用右侧操作列 |
|||
->addRightButton('info', [ // 添加额外按钮 |
|||
'title' => '添加', |
|||
'icon' => 'fa fa-plus', |
|||
'class' => 'btn btn-success btn-xs', |
|||
'href' => url('add', ['parentId' => '__id__']) |
|||
]) |
|||
->addRightButtons($module->right_button) // 设置右侧操作列 |
|||
->addTopButtons($module->top_button) // 设置顶部按钮组 |
|||
->addTopButton('default', [ |
|||
'title' => '展开/折叠', |
|||
'icon' => 'fas fa-exchange-alt', |
|||
'class' => 'btn btn-info treeStatus', |
|||
'href' => '', |
|||
'onclick' => '$.operate.treeStatus()' |
|||
]) // 自定义按钮 |
|||
->addTopButton('default', [ |
|||
'title' => '批量新增', |
|||
'icon' => 'fa fa-plus', |
|||
'class' => 'btn btn-success', |
|||
'href' => '', |
|||
'onclick' => '$.operate.batchAdd(\'' . url('batchAdd') . '\')' |
|||
]) // 自定义按钮 |
|||
->setPagination('false') // 关闭分页显示 |
|||
->setParentIdField('parent_id') // 设置列表树父id |
|||
->fetch(); |
|||
} |
|||
|
|||
// 添加 |
|||
public function add(string $parentId = '') |
|||
{ |
|||
// 获取字段信息 |
|||
$columns = MakeBuilder::getAddColumns($this->tableName); |
|||
// 重置`所属模块`和`上级栏目`的选项 |
|||
foreach ($columns as $k => $coloumn) { |
|||
if ($coloumn[1] == 'module_id') { |
|||
$columns[$k][4] = $this->getModuleIds(); |
|||
} |
|||
if ($coloumn[1] == 'parent_id') { |
|||
$model = '\app\common\model\\' . $this->modelName; |
|||
$pidOptions = $model::getPidOptions(); |
|||
$columns[$k][4] = $pidOptions; |
|||
// 设置父ID默认值 |
|||
if ($parentId) { |
|||
$columns[$k][5] = $parentId; |
|||
} |
|||
} |
|||
} |
|||
// 获取分组后的字段信息 |
|||
$groups = MakeBuilder::getAddGroups($this->modelName, $this->tableName, $columns); |
|||
// 构建页面 |
|||
$builder = FormBuilder::getInstance(); |
|||
|
|||
$groups ? $builder->addGroup($groups) : $builder->addFormItems($columns); |
|||
return $builder->fetch(); |
|||
} |
|||
|
|||
// 添加保存 |
|||
public function addPost() |
|||
{ |
|||
if (Request::isPost()) { |
|||
$data = MakeBuilder::changeFormData(Request::except(['file'], 'post'), $this->tableName); |
|||
$result = $this->validate($data, $this->validate); |
|||
if (true !== $result) { |
|||
// 验证失败 输出错误信息 |
|||
$this->error($result); |
|||
} else { |
|||
$model = '\app\common\model\\' . $this->modelName; |
|||
$result = $model::addPost($data); |
|||
if ($result['error']) { |
|||
$this->error($result['msg']); |
|||
} else { |
|||
$this->singleCateInit($data); |
|||
$this->success($result['msg'], 'index'); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 修改 |
|||
public function edit(string $id) |
|||
{ |
|||
$model = '\app\common\model\\' . $this->modelName; |
|||
$info = $model::edit($id)->toArray(); |
|||
// 获取字段信息 |
|||
$columns = MakeBuilder::getAddColumns($this->tableName, $info); |
|||
|
|||
// 重置`所属模块`和`上级栏目`的选项 |
|||
foreach ($columns as $k => $coloumn) { |
|||
if ($coloumn[1] == 'module_id') { |
|||
$columns[$k][4] = $this->getModuleIds(); |
|||
} |
|||
if ($coloumn[1] == 'parent_id') { |
|||
$model = '\app\common\model\\' . $this->modelName; |
|||
$pidOptions = $model::getPidOptions(); |
|||
$columns[$k][4] = $pidOptions; |
|||
// 设置父ID默认值 |
|||
if ($info['parent_id']) { |
|||
$columns[$k][5] = $info['parent_id']; |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 获取分组后的字段信息 |
|||
$groups = MakeBuilder::getAddGroups($this->modelName, $this->tableName, $columns); |
|||
|
|||
// 构建页面 |
|||
$builder = FormBuilder::getInstance(); |
|||
$groups ? $builder->addGroup($groups) : $builder->addFormItems($columns); |
|||
return $builder->fetch(); |
|||
} |
|||
|
|||
// 修改保存 |
|||
public function editPost() |
|||
{ |
|||
if (Request::isPost()) { |
|||
$data = MakeBuilder::changeFormData(Request::except(['file'], 'post'), $this->tableName); |
|||
if ($data['id'] == $data['parent_id']) { |
|||
$this->error('上级栏目不可以为当前栏目'); |
|||
} |
|||
$result = $this->validate($data, $this->validate); |
|||
if (true !== $result) { |
|||
// 验证失败 输出错误信息 |
|||
$this->error($result); |
|||
} else { |
|||
$model = '\app\common\model\\' . $this->modelName; |
|||
$result = $model::editPost($data); |
|||
if ($result['error']) { |
|||
$this->error($result['msg']); |
|||
} else { |
|||
$this->success($result['msg'], 'index'); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 删除 |
|||
public function del(string $id) |
|||
{ |
|||
if (Request::isPost()) { |
|||
// 删除子分类 |
|||
$this->delChildsCate($id); |
|||
if (strpos($id, ',') !== false) { |
|||
return $this->selectDel($id); |
|||
} |
|||
$model = '\app\common\model\\' . $this->modelName; |
|||
return $model::del($id); |
|||
} |
|||
} |
|||
|
|||
// 批量添加 |
|||
public function batchAdd() |
|||
{ |
|||
// 额外CSS |
|||
$css = '<style> |
|||
.form_builder .form-group{margin-bottom: 0} |
|||
.form_builder .col-form-label{padding-right: 5px;} |
|||
.form_builder .form-control{padding-left: 0.5rem; padding-right: 0.5rem} |
|||
.form_builder .js_cates_content .col-form-label{display: none} |
|||
.form_builder .js_cates button{display: none} |
|||
.form_builder .js_cates_content button{margin-top: 4px} |
|||
</style>'; |
|||
|
|||
// 额外js |
|||
$js = '<script type="text/javascript"> |
|||
// 增加一行 |
|||
$(document).on("click", \'.js_add_row\', function () { |
|||
var html = $(\'.js_cates\').html(); |
|||
$(\'.js_cates_content\').append(html); |
|||
}) |
|||
// 刪除一行 |
|||
$(document).on("click", \'.js_del_row\', function () { |
|||
$(this).parent().parent().remove(); |
|||
}) |
|||
|
|||
</script>'; |
|||
|
|||
// 添加按钮 |
|||
$html = '<div class="row dd_input_group"><button type="button" class="btn btn-success btn-sm js_add_row"><i class="fa fa-plus"></i> 增加一行</button></div>'; |
|||
|
|||
// 所属模块 |
|||
$modules = $this->getModuleIds(); |
|||
$modulesStr = ''; |
|||
foreach ($modules as $k => $v) { |
|||
$modulesStr .= '<option value="' . $k . '">' . $v . '</option>'; |
|||
} |
|||
$html .= '<div class="js_cates"> |
|||
<div class="row dd_input_group"> |
|||
<div class="col-2"> |
|||
<div class="form-group"> |
|||
<label class="col-form-label is-required">所属模块</label> |
|||
<select class="form-control" name="module_id[]"><option value="">请选择</option>' . $modulesStr . '</select> |
|||
</div> |
|||
</div>'; |
|||
// 上级栏目 |
|||
$model = '\app\common\model\\' . $this->modelName; |
|||
$pidOptions = $model::getPidOptions(); |
|||
$pidOptionsStr = ''; |
|||
foreach ($pidOptions as $k => $v) { |
|||
$pidOptionsStr .= '<option value="' . $k . '">' . $v . '</option>'; |
|||
} |
|||
$html .= '<div class="col-2"> |
|||
<div class="form-group"> |
|||
<label class="col-form-label">上级栏目</label> |
|||
<select class="form-control" name="parent_id[]"><option value="">请选择</option>' . $pidOptionsStr . '</select> |
|||
</div> |
|||
</div>'; |
|||
|
|||
// 栏目名称 |
|||
$html .= '<div class="col-2"> |
|||
<div class="form-group"> |
|||
<label class="col-form-label is-required">栏目名称</label> |
|||
<input class="form-control" type="text" name="cate_name[]" placeholder="请输入栏目名称"> |
|||
</div> |
|||
</div>'; |
|||
|
|||
// 英文名称 |
|||
$html .= '<div class="col-2"> |
|||
<div class="form-group"> |
|||
<label class="col-form-label">英文名称</label> |
|||
<input class="form-control" type="text" name="en_name[]" placeholder="请输入英文名称"> |
|||
</div> |
|||
</div>'; |
|||
|
|||
// 栏目目录 |
|||
$html .= '<div class="col-2"> |
|||
<div class="form-group"> |
|||
<label class="col-form-label">栏目目录</label> |
|||
<input class="form-control" type="text" name="cate_folder[]" placeholder="请输入栏目目录"> |
|||
</div> |
|||
</div>'; |
|||
|
|||
// 排序 |
|||
$html .= '<div class="col-1"> |
|||
<div class="form-group"> |
|||
<label class="col-form-label is-required">排序</label> |
|||
<input class="form-control" type="number" name="sort[]" value="50" step="1"> |
|||
</div> |
|||
</div>'; |
|||
|
|||
// 删除行 |
|||
$html .= '<div class="col-1"> |
|||
<button type="button" class="btn btn-success btn-sm js_del_row"><i class="fa fa-times"></i></button> |
|||
</div>'; |
|||
|
|||
$html .= '</div></div><div class="js_cates_content"></div>'; |
|||
|
|||
// 构建页面 |
|||
$builder = FormBuilder::getInstance(); |
|||
$builder->setExtraCss($css) |
|||
->setExtraJs($js) |
|||
->addHtml($html); |
|||
return $builder->fetch(); |
|||
} |
|||
|
|||
// 批量添加保存 |
|||
public function batchAddPost() |
|||
{ |
|||
if (Request::isPost()) { |
|||
$data = Request::except(['file'], 'post'); |
|||
if ($data) { |
|||
$dataNew = []; |
|||
for ($i = 0; $i < count($data['module_id']); $i++) { |
|||
if (empty($data['module_id'][$i]) || empty($data['cate_name'][$i]) || empty($data['sort'][$i])) { |
|||
$this->error('所属模块、栏目名称和排序不可为空'); |
|||
} |
|||
$dataNew[] = [ |
|||
'module_id' => $data['module_id'][$i], |
|||
'parent_id' => $data['parent_id'][$i], |
|||
'cate_name' => $data['cate_name'][$i], |
|||
'en_name' => $data['en_name'][$i], |
|||
'cate_folder' => $data['cate_folder'][$i], |
|||
'sort' => $data['sort'][$i], |
|||
'status' => 1, |
|||
'summary' => '', |
|||
]; |
|||
} |
|||
foreach ($dataNew as $k => $v) { |
|||
$result = $this->validate($v, $this->validate); |
|||
if (true !== $result) { |
|||
// 验证失败 输出错误信息 |
|||
$this->error($result); |
|||
} else { |
|||
$model = '\app\common\model\\' . $this->modelName; |
|||
$result = $model::addPost($v); |
|||
if ($result['error']) { |
|||
$this->error($result['msg']); |
|||
} else { |
|||
$this->singleCateInit($v); |
|||
} |
|||
} |
|||
} |
|||
$this->success($result['msg'], 'index'); |
|||
} |
|||
} |
|||
} |
|||
|
|||
// ===================== |
|||
|
|||
// 获取CMS模块 |
|||
private function getModuleIds() |
|||
{ |
|||
$modules = \app\common\model\Module::where('table_type', 1) |
|||
->field('id,module_name') |
|||
->select() |
|||
->toArray(); |
|||
$result = []; |
|||
foreach ($modules as &$module) { |
|||
$result[$module['id']] = $module['module_name']; |
|||
} |
|||
return $result; |
|||
} |
|||
|
|||
/** |
|||
* 删除分类时删除子分类和子分类的数据 |
|||
* @param string $id |
|||
* @throws \Exception |
|||
*/ |
|||
private function delChildsCate(string $id) |
|||
{ |
|||
// 多选时重新调用 |
|||
if (strpos($id, ',') !== false) { |
|||
$idArr = explode(',', $id); |
|||
foreach ($idArr as $k => $v) { |
|||
$this->delChildsCate($v); |
|||
} |
|||
} |
|||
// 查找当前分类的所有子分类 |
|||
$cate = \app\common\model\Cate::select()->toArray(); |
|||
$ids = getChildsId($cate, $id); |
|||
foreach ($ids as $k => $v) { |
|||
// 删除一个分类的内容 |
|||
$this->delCateContent($v['id'], $v['module_id']); |
|||
// 删除一个分类 |
|||
\app\common\model\Cate::where('id', '=', $v['id'])->delete(); |
|||
} |
|||
// 查找当前分类信息并尝试删除 |
|||
$cateOn = \app\common\model\Cate::find($id); |
|||
if ($cateOn) { |
|||
// 删除一个分类的内容 |
|||
$this->delCateContent($cateOn['id'], $cateOn['module_id']); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 删除某个分类的内容 |
|||
* @param string $cateId |
|||
* @param string $moduleId |
|||
* @return bool |
|||
*/ |
|||
private function delCateContent(string $cateId, string $moduleId) |
|||
{ |
|||
$module = \app\common\model\Module::find($moduleId); |
|||
if ($module) { |
|||
$model = '\app\common\model\\' . $module->model_name; |
|||
return $model::where('cate_id', $cateId)->delete(); |
|||
} else { |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 单页模块栏目新增时初始化操作 |
|||
* @param array $data |
|||
* @return bool |
|||
*/ |
|||
private function singleCateInit(array $data = []) |
|||
{ |
|||
if ($data['module_id'] == '18') { |
|||
$cate = \app\common\model\Cate::order('id', 'desc')->limit(1)->select()->toArray(); |
|||
if (count($cate) > 0) { |
|||
$data = [ |
|||
'sort' => 50, |
|||
'status' => 1, |
|||
'cate_id' => $cate[0]['id'], |
|||
'title' => $cate[0]['cate_name'], |
|||
'content' => '', |
|||
]; |
|||
\app\common\model\Page::create($data); |
|||
return true; |
|||
} |
|||
} |
|||
return false; |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,241 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 配置信息控制器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2020/01/21 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\controller; |
|||
|
|||
// 引入框架内置类 |
|||
use think\facade\Request; |
|||
// 引入表格和表单构建器 |
|||
use app\common\builder\FormBuilder; |
|||
// 引入阿里云SDK |
|||
use AlibabaCloud\Client\AlibabaCloud; |
|||
use AlibabaCloud\Client\Exception\ClientException; |
|||
use AlibabaCloud\Client\Exception\ServerException; |
|||
|
|||
class Config extends Base |
|||
{ |
|||
// 邮件配置 |
|||
public function email(){ |
|||
$smtp = \app\common\model\Config::where('inc_type','=','smtp') |
|||
->select(); |
|||
$info = convert_arr_kv($smtp,'name','value'); |
|||
|
|||
return FormBuilder::getInstance() |
|||
->addText('smtp_server', '服务器') |
|||
->addText('smtp_port', 'SMTP端口') |
|||
->addText('email_id', '发件人') |
|||
->addText('smtp_user', '发件邮箱') |
|||
->addPassword('smtp_pwd', '身份验证码') |
|||
->addText('regis_smtp_enable', '标题') |
|||
->addText('test_eamil', '测试邮箱') |
|||
->addEditor('test_eamil_info', '测试邮件内容', '', '', '100') |
|||
->setFormData($info) |
|||
->setFormUrl(url('emailPost')) |
|||
->hideBtn('back') |
|||
->addBtn('<button type="button" id="test_email" class="btn btn-flat btn-info ">测试发送</button>') |
|||
->setExtraHtml($this->getEmailExtraHtml(), 'content_bottom') |
|||
->setPageTips('<div style="line-height: 32px;float: left">系统采用SMTP方式发送邮件</div>', 'success', 'search') |
|||
->hideShowAll() |
|||
->fetch(); |
|||
} |
|||
|
|||
// 邮件配置保存 |
|||
public function emailPost() |
|||
{ |
|||
if (Request::isPost()) { |
|||
$data = Request::post(); |
|||
foreach ($data as $k => $v) { |
|||
$result = \app\common\model\Config::where([['name', '=', $k], ['inc_type', '=', 'smtp']])->find(); |
|||
if ($k == 'smtp_pwd') { |
|||
if (!empty($v)) { |
|||
$result->value = $v; |
|||
} |
|||
} else { |
|||
$result->value = $v; |
|||
} |
|||
$result->save(); |
|||
} |
|||
$this->success('修改成功', 'email'); |
|||
} |
|||
} |
|||
|
|||
// 测试邮件发送 |
|||
public function emailSend(){ |
|||
$sender = Request::param('email'); |
|||
//检查是否邮箱格式 |
|||
if (!is_email($sender)) { |
|||
return json(['error' => 1, 'msg' => '测试邮箱码格式有误']); |
|||
} |
|||
$data = \app\common\model\Config::where('inc_type','smtp') |
|||
->select(); |
|||
$config = convert_arr_kv($data,'name','value'); |
|||
$content = $config['test_eamil_info']; |
|||
//所有项目必须填写 |
|||
if (empty($config['smtp_server']) || empty($config['smtp_port']) || empty($config['smtp_user']) || empty($config['smtp_pwd'])) { |
|||
return json(['error' => 1, 'msg' => '请完善邮件配置信息!']); |
|||
} |
|||
|
|||
$send = send_email($sender, '测试邮件',$content); |
|||
if ($send) { |
|||
return ['error' => 0, 'msg' => '邮件发送成功!']; |
|||
} else { |
|||
return ['error' => 1, 'msg' => '邮件发送失败!']; |
|||
} |
|||
} |
|||
|
|||
// 获取邮件配置额外HTML |
|||
private function getEmailExtraHtml() |
|||
{ |
|||
$str = '<script type="text/javascript"> |
|||
$("#test_email").click(function () { |
|||
var url = "' . url('emailSend') . '"; |
|||
var email = $("input[name=\'test_eamil\']").val(); |
|||
$.modal.confirm(\'确定要发送吗?如有修改请先提交保存!\', function () { |
|||
$.post(url,{email:email},function(result){ |
|||
if(result.error == 0){ |
|||
$.modal.alertSuccess(result.msg); |
|||
}else{ |
|||
$.modal.alertError(result.msg); |
|||
} |
|||
},\'json\'); |
|||
}) |
|||
|
|||
}) |
|||
</script> |
|||
'; |
|||
return $str; |
|||
} |
|||
|
|||
// ========================================== |
|||
|
|||
// 短信配置 |
|||
public function sms(){ |
|||
$smtp = \app\common\model\Config::where('inc_type','=','sms') |
|||
->select(); |
|||
$info = convert_arr_kv($smtp,'name','value'); |
|||
|
|||
return FormBuilder::getInstance() |
|||
->addText('accessKeyId', 'AccessKey ID', ' |
|||
<a href="https://help.aliyun.com/document_detail/53045.html" target="_blank">【创建】</a> |
|||
<a href="https://usercenter.console.aliyun.com/#/manage/ak" target="_blank">【查看】</a>') |
|||
->addText('accessKeySecret', '密钥secret') |
|||
->addText('signName', '签名名称', ' |
|||
<a href="https://help.aliyun.com/document_detail/108072.html" target="_blank">【签名简介】</a> |
|||
<a href="https://dysms.console.aliyun.com/dysms.htm#/domestic/text/sign" target="_blank">【查看签名】</a>') |
|||
->addText('templateCode', '模版CODE', ' |
|||
<a href="https://dysms.console.aliyun.com/dysms.htm#/domestic/text/template" target="_blank">【查看模版】</a>') |
|||
->addText('test_mobile', '测试手机') |
|||
->setFormData($info) |
|||
->setFormUrl(url('smsPost')) |
|||
->hideBtn('back') |
|||
->addBtn('<button type="button" id="test_sms" class="btn btn-flat btn-info ">测试发送</button>') |
|||
->setExtraHtml($this->getSmsExtraHtml(), 'content_bottom') |
|||
->setPageTips('<div style="line-height: 32px;float: left">系统采用阿里云短信服务发送短信 <a class="btn btn-flat btn-primary m-r-10" href="https://help.aliyun.com/document_detail/101346.html" target="_blank">查看错误码</a><a class="btn btn-flat btn-primary" href="https://help.aliyun.com/document_detail/59210.html" target="_blank">使用指引</a></div>', 'success', 'search') |
|||
->hideShowAll() |
|||
->fetch(); |
|||
} |
|||
|
|||
// 短信配置保存 |
|||
public function smsPost() |
|||
{ |
|||
if (Request::isPost()) { |
|||
$data = Request::post(); |
|||
foreach ($data as $k => $v) { |
|||
\app\common\model\Config::where([ |
|||
['name', '=', $k], ['inc_type', '=', 'sms'] |
|||
]) |
|||
->update(['value' => $v]); |
|||
} |
|||
$this->success('保存成功', 'sms'); |
|||
} |
|||
} |
|||
|
|||
// 测试短信发送 |
|||
public function smsSend() |
|||
{ |
|||
$data = \app\common\model\Config::where('inc_type', 'sms')->select(); |
|||
$config = convert_arr_kv($data, 'name', 'value'); |
|||
|
|||
// 生成验证码 |
|||
$code = json_encode(['code' => rand(1000, 9999)]); |
|||
|
|||
// 新版发送 |
|||
AlibabaCloud::accessKeyClient($config['accessKeyId'], $config['accessKeySecret']) |
|||
->regionId('cn-hangzhou') |
|||
->asDefaultClient(); |
|||
|
|||
try { |
|||
$result = AlibabaCloud::rpc() |
|||
->product('Dysmsapi') |
|||
// ->scheme('https') // https | http |
|||
->version('2017-05-25') |
|||
->action('SendSms') |
|||
->method('POST') |
|||
->host('dysmsapi.aliyuncs.com') |
|||
->options([ |
|||
'query' => [ |
|||
'RegionId' => "cn-hangzhou", |
|||
'PhoneNumbers' => $config['test_mobile'], |
|||
'SignName' => $config['signName'], |
|||
'TemplateCode' => $config['templateCode'], |
|||
'TemplateParam' => $code, |
|||
], |
|||
]) |
|||
->request(); |
|||
$resultArr = $result->toArray(); |
|||
if ($resultArr['Code'] == 'OK') { |
|||
return json(['error' => 0, 'msg' => '发送成功']); |
|||
} else { |
|||
return json(['error' => 1, 'msg' => $resultArr['Message']]); |
|||
} |
|||
} catch (ClientException $e) { |
|||
return json(['error' => 1, 'msg' => $e->getErrorMessage()]); |
|||
} catch (ServerException $e) { |
|||
return json(['error' => 1, 'msg' => $e->getErrorMessage()]); |
|||
} |
|||
} |
|||
|
|||
// 获取短信配置额外HTML |
|||
private function getSmsExtraHtml(){ |
|||
$str = '<script type="text/javascript"> |
|||
$("#test_sms").click(function () { |
|||
var url = "' . url('smsSend') . '"; |
|||
var mobile = $("input[name=\'mobile\']").val(); |
|||
$.modal.confirm(\'确定要发送吗?如有修改请先提交保存!\', function () { |
|||
$.post(url,{mobile:mobile},function(result){ |
|||
if(result.error == 0){ |
|||
$.modal.alertSuccess(result.msg); |
|||
}else{ |
|||
$.modal.alertError(result.msg); |
|||
} |
|||
},\'json\'); |
|||
}) |
|||
}) |
|||
</script> |
|||
'; |
|||
return $str; |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,313 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 数据库备份控制器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2020/01/31 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\controller; |
|||
|
|||
use think\facade\Request; |
|||
use \tp5er\Backup; |
|||
|
|||
// 引入表格构建器 |
|||
use app\common\builder\TableBuilder; |
|||
|
|||
class Database extends Base |
|||
{ |
|||
protected $db = '', $datadir; |
|||
function initialize(){ |
|||
parent::initialize(); |
|||
$this->config=array( |
|||
'path' => './Data/', // 数据库备份路径 |
|||
'part' => 20971520, // 数据库备份卷大小 |
|||
'compress' => 0, // 数据库备份文件是否启用压缩 0不压缩 1 压缩 |
|||
'level' => 9 // 数据库备份文件压缩级别 1普通 4 一般 9最高 |
|||
); |
|||
$this->db = new Backup($this->config); |
|||
} |
|||
|
|||
// 数据列表 |
|||
public function database() |
|||
{ |
|||
// 设置主键 |
|||
$pk = 'name'; |
|||
// 字段信息 |
|||
$columns = [ |
|||
['name' , '数据表'], |
|||
['engine', '存储引擎'], |
|||
//['version', '版本'], |
|||
['row_format', '行格式'], |
|||
['rows', '行数', '', '', '', '', 'true'], |
|||
//['avg_row_length', '平均每行包括的字节数'], |
|||
['data_size', '字节数', '', '', '', '', 'true'], |
|||
['data_length', '数据量'], |
|||
//['max_data_length', '可容纳的最大数据量'], |
|||
//['index_length', '索引占用磁盘的空间大小'], |
|||
//['data_free', '已经分配,但目前没有使用的空间'], |
|||
//['auto_increment', 'auto_increment'], |
|||
['comment', '额外信息'], |
|||
['create_time', '创建时间'], |
|||
['update_time', '更新时间'], |
|||
//['check_time', '最后一次检查表的时间'], |
|||
//['collation', '表的默认字符集和字符排序规则'], |
|||
//['checksum', '整个表的实时校验和'], |
|||
//['create_options', '创建表时指定的其他选项'], |
|||
]; |
|||
// 数据信息 |
|||
$list = $this->db->dataList(); |
|||
// 计算总大小 |
|||
$total = 0; |
|||
foreach ($list as $k => $v) { |
|||
$total += $v['data_length']; |
|||
$list[$k]['data_size'] = $v['data_length']; |
|||
$list[$k]['data_length'] = format_bytes($v['data_length']); |
|||
} |
|||
// 提示信息 |
|||
$pageTips = '数据库中共有 ' . count($list) . ' 张表,共计 ' . format_bytes($total); |
|||
// 可搜索的字段 |
|||
$search = [ |
|||
['text', 'name', '数据表', 'LIKE'], |
|||
]; |
|||
// 搜索 |
|||
if (Request::param('getList') == 1) { |
|||
// 排序规则 |
|||
$orderByColumn = Request::param('orderByColumn') ?? $pk; |
|||
$isAsc = Request::param('isAsc') ?? 'desc'; |
|||
$isAsc = $isAsc == 'desc' ? SORT_DESC : SORT_ASC; |
|||
// 排序处理 |
|||
$date = array_column($list, $orderByColumn); |
|||
array_multisort($date, $isAsc, $list); |
|||
if (Request::param('name')) { |
|||
foreach ($list as $k => $v) { |
|||
if (strpos($v['name'], Request::param('name')) == false) { |
|||
unset($list[$k]); |
|||
} |
|||
} |
|||
} |
|||
// 渲染输出 |
|||
$result = [ |
|||
'total' => count($list), |
|||
'per_page' => 1000, |
|||
'current_page' => 1, |
|||
'last_page' => 1, |
|||
'data' => $list, |
|||
]; |
|||
return $result; |
|||
} |
|||
// 构建页面 |
|||
return TableBuilder::getInstance() |
|||
->setUniqueId($pk) // 设置主键 |
|||
->addColumns($columns) // 添加列表字段数据 |
|||
->setSearch($search) // 添加头部搜索 |
|||
->setPageTips($pageTips, 'warning') // 提示信息 |
|||
->setPagination('false') // 关闭分页显示 |
|||
->addTopButtons([ |
|||
'backup' => [ |
|||
'title' => '备份', |
|||
'icon' => 'fa fa-server', |
|||
'class' => 'btn btn-success multiple disabled', |
|||
'href' => '', |
|||
'target' => '', |
|||
'onclick' => '$.operate.database(\''.url('backup').'\' , \'备份\')', |
|||
], |
|||
'optimize' => [ |
|||
'title' => '优化', |
|||
'icon' => 'fa fa-medkit', |
|||
'class' => 'btn btn-primary multiple disabled', |
|||
'href' => '', |
|||
'target' => '', |
|||
'onclick' => '$.operate.database(\''.url('optimize').'\', \'优化\')', |
|||
], |
|||
'repair' => [ |
|||
'title' => '修复', |
|||
'icon' => 'fa fa-user-md', |
|||
'class' => 'btn btn-warning multiple disabled', |
|||
'href' => '', |
|||
'target' => '', |
|||
'onclick' => '$.operate.database(\''.url('repair').'\', \'修复\')', |
|||
], |
|||
]) |
|||
->fetch(); |
|||
} |
|||
|
|||
// 备份 |
|||
public function backup() |
|||
{ |
|||
$tables = Request::param('id'); |
|||
if (!empty($tables)) { |
|||
$tables = explode(',', $tables); |
|||
foreach ($tables as $table) { |
|||
$this->db->setFile()->backup($table, 0); |
|||
} |
|||
return json(['error' => 0, 'msg' => '备份成功!']); |
|||
} else { |
|||
return json(['error' => 1, 'msg' => '请选择要备份的表!']); |
|||
} |
|||
} |
|||
|
|||
// 优化 |
|||
public function optimize() { |
|||
$tables = Request::param('id'); |
|||
if (empty($tables)) { |
|||
return json(['error'=>1,'msg'=>'请选择要优化的表!']); |
|||
} |
|||
$tables = explode(',',$tables); |
|||
if ($this->db->optimize($tables)) { |
|||
return json(['error'=>0, 'msg'=>'数据表优化成功!']); |
|||
} else { |
|||
return json(['error'=>1, 'msg'=>'数据表优化出错请重试!']); |
|||
} |
|||
} |
|||
|
|||
// 修复 |
|||
public function repair() { |
|||
$tables = Request::param('id'); |
|||
if (empty($tables)) { |
|||
return json(['error'=>1,'msg'=>'请选择要修复的表!']); |
|||
} |
|||
$tables = explode(',',$tables); |
|||
if ($this->db->repair($tables)) { |
|||
return json(['error'=>0, 'msg'=>'数据表修复成功!']); |
|||
} else { |
|||
return json(['error'=>1, 'msg'=>'数据表修复出错请重试!']); |
|||
} |
|||
} |
|||
|
|||
// =========================== |
|||
|
|||
// 还原 |
|||
public function restore() |
|||
{ |
|||
$list = $this->db->fileList(); |
|||
$total = 0; |
|||
$listNew = []; |
|||
foreach ($list as $k => $v) { |
|||
$total += $v['size_num']; |
|||
$listNew[] = $list[$k]; |
|||
} |
|||
$list = $listNew; |
|||
array_multisort(array_column($list, 'time'), SORT_DESC, $list); |
|||
|
|||
// 设置主键 |
|||
$pk = 'time'; |
|||
// 字段信息 |
|||
$columns = [ |
|||
['time', '编号',], |
|||
['name', '文件名称'], |
|||
['part', '分卷'], |
|||
['size', '文件大小'], |
|||
['compress', '分隔符'], |
|||
['addtime', '创建时间', '', '', '', '', 'true'], |
|||
]; |
|||
// 可搜索的字段 |
|||
$search = [ |
|||
// ['text', 'name', '文件名称', 'LIKE'], |
|||
]; |
|||
// 提示信息 |
|||
$pageTips = '备份文件列表中共有 ' . count($list) . ' 个文件,共计 ' . format_bytes($total); |
|||
|
|||
// 搜索 |
|||
if (Request::param('getList') == 1) { |
|||
// 排序规则 |
|||
$orderByColumn = Request::param('orderByColumn') ?? $pk; |
|||
$isAsc = Request::param('isAsc') ?? 'desc'; |
|||
$isAsc = $isAsc == 'desc' ? SORT_DESC : SORT_ASC; |
|||
// 排序处理 |
|||
$date = array_column($list, $orderByColumn); |
|||
array_multisort($date, $isAsc, $list); |
|||
if (Request::param('name')) { |
|||
foreach ($list as $k => $v) { |
|||
if (strpos($v['name'], Request::param('name')) == false) { |
|||
unset($list[$k]); |
|||
} |
|||
} |
|||
} |
|||
// 渲染输出 |
|||
$result = [ |
|||
'total' => count($list), |
|||
'per_page' => 1000, |
|||
'current_page' => 1, |
|||
'last_page' => 1, |
|||
'data' => $list, |
|||
]; |
|||
return $result; |
|||
} |
|||
// 构建页面 |
|||
return TableBuilder::getInstance() |
|||
->setUniqueId($pk)// 设置主键 |
|||
->addColumns($columns)// 添加列表字段数据 |
|||
->setSearch($search)// 添加头部搜索 |
|||
->setPageTips($pageTips, 'warning')// 提示信息 |
|||
->setPagination('false')// 关闭分页显示 |
|||
->addColumn('right_button', '操作', 'btn') |
|||
->addTopButtons('del') |
|||
->addRightButton('info', [ |
|||
'title' => '恢复', |
|||
'icon' => 'fa fa-exclamation-triangle', |
|||
'class' => 'btn btn-flat btn-warning btn-xs confirm', |
|||
'href' => url('import', ['id' => '__time__']) |
|||
]) // 添加额外按钮 |
|||
->addRightButton('info', [ |
|||
'title' => '下载', |
|||
'icon' => 'fa fa-download', |
|||
'target'=> '_blank', |
|||
'class' => 'btn btn-flat btn-success btn-xs confirm', |
|||
'href' => url('downFile', ['id' => '__time__']) |
|||
]) // 添加额外按钮 |
|||
->addRightButton('delete') |
|||
->fetch(); |
|||
} |
|||
|
|||
// 执行还原数据库操作 |
|||
public function import(string $id) |
|||
{ |
|||
$list = $this->db->getFile('timeverif', $id); |
|||
$this->db->setFile($list)->import(1); |
|||
return json(['error' => 0, 'msg' => '还原成功!']); |
|||
} |
|||
|
|||
// 下载 |
|||
public function downFile(string $id) |
|||
{ |
|||
$this->db->downloadFile($id); |
|||
} |
|||
|
|||
// 删除sql文件 |
|||
public function del(string $id) |
|||
{ |
|||
if (Request::isPost()) { |
|||
if (strpos($id, ',') !== false) { |
|||
$idArr = explode(',', $id); |
|||
foreach ($idArr as $k => $v) { |
|||
$this->db->delFile($v); |
|||
} |
|||
return json(['error' => 0, 'msg' => "删除成功!"]); |
|||
} |
|||
if ($this->db->delFile($id)) { |
|||
return json(['error' => 0, 'msg' => "删除成功!"]); |
|||
} else { |
|||
return json(['error' => 1, 'msg' => "备份文件删除失败,请检查文件权限!"]); |
|||
} |
|||
} |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,47 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 碎片管理控制器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2021/06/23 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\controller; |
|||
|
|||
// 引入框架内置类 |
|||
use think\facade\Request; |
|||
|
|||
// 引入表格和表单构建器 |
|||
use app\common\facade\MakeBuilder; |
|||
use app\common\builder\FormBuilder; |
|||
use app\common\builder\TableBuilder; |
|||
|
|||
class Debris extends Base |
|||
{ |
|||
// 验证器 |
|||
protected $validate = 'Debris'; |
|||
|
|||
// 当前主表 |
|||
protected $tableName = 'debris'; |
|||
|
|||
// 当前主模型 |
|||
protected $modelName = 'Debris'; |
|||
|
|||
} |
|||
@ -0,0 +1,82 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 演示控制器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2020/02/09 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\controller; |
|||
|
|||
|
|||
use think\facade\Request; |
|||
use think\facade\View; |
|||
|
|||
class Demo extends Base |
|||
{ |
|||
// 按钮 |
|||
public function button() |
|||
{ |
|||
return View::fetch(); |
|||
} |
|||
|
|||
// 图标 |
|||
public function icons() |
|||
{ |
|||
return View::fetch(); |
|||
} |
|||
|
|||
// 常规 |
|||
public function general() |
|||
{ |
|||
return View::fetch(); |
|||
} |
|||
|
|||
// 模态框 |
|||
public function modals() |
|||
{ |
|||
return View::fetch(); |
|||
} |
|||
|
|||
// 时间轴 |
|||
public function timeline() |
|||
{ |
|||
return View::fetch(); |
|||
} |
|||
|
|||
// 弹层 |
|||
public function layer() |
|||
{ |
|||
return View::fetch(); |
|||
} |
|||
|
|||
// layer表单 |
|||
public function layerForm() |
|||
{ |
|||
return View::fetch(); |
|||
} |
|||
|
|||
// 模拟提交 |
|||
public function addPost() |
|||
{ |
|||
$this->success('提交成功', 'layer'); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,47 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 字典数据控制器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2021/06/23 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\controller; |
|||
|
|||
// 引入框架内置类 |
|||
use think\facade\Request; |
|||
|
|||
// 引入表格和表单构建器 |
|||
use app\common\facade\MakeBuilder; |
|||
use app\common\builder\FormBuilder; |
|||
use app\common\builder\TableBuilder; |
|||
|
|||
class Dictionary extends Base |
|||
{ |
|||
// 验证器 |
|||
protected $validate = 'Dictionary'; |
|||
|
|||
// 当前主表 |
|||
protected $tableName = 'dictionary'; |
|||
|
|||
// 当前主模型 |
|||
protected $modelName = 'Dictionary'; |
|||
|
|||
} |
|||
@ -0,0 +1,47 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 字典类型控制器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2021/06/23 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\controller; |
|||
|
|||
// 引入框架内置类 |
|||
use think\facade\Request; |
|||
|
|||
// 引入表格和表单构建器 |
|||
use app\common\facade\MakeBuilder; |
|||
use app\common\builder\FormBuilder; |
|||
use app\common\builder\TableBuilder; |
|||
|
|||
class DictionaryType extends Base |
|||
{ |
|||
// 验证器 |
|||
protected $validate = 'DictionaryType'; |
|||
|
|||
// 当前主表 |
|||
protected $tableName = 'dictionary_type'; |
|||
|
|||
// 当前主模型 |
|||
protected $modelName = 'DictionaryType'; |
|||
|
|||
} |
|||
@ -0,0 +1,47 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 下载模块控制器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2021/06/23 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\controller; |
|||
|
|||
// 引入框架内置类 |
|||
use think\facade\Request; |
|||
|
|||
// 引入表格和表单构建器 |
|||
use app\common\facade\MakeBuilder; |
|||
use app\common\builder\FormBuilder; |
|||
use app\common\builder\TableBuilder; |
|||
|
|||
class Download extends Base |
|||
{ |
|||
// 验证器 |
|||
protected $validate = 'Download'; |
|||
|
|||
// 当前主表 |
|||
protected $tableName = 'download'; |
|||
|
|||
// 当前主模型 |
|||
protected $modelName = 'Download'; |
|||
|
|||
} |
|||
@ -0,0 +1,799 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 字段控制器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2020/01/21 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
|
|||
namespace app\admin\controller; |
|||
|
|||
use think\facade\Config; |
|||
use think\facade\Db; |
|||
use think\facade\Request; |
|||
use think\facade\View; |
|||
|
|||
// 引入构建器 |
|||
use app\common\builder\TableBuilder; |
|||
use app\common\facade\MakeBuilder; |
|||
|
|||
class Field extends Base |
|||
{ |
|||
// 验证器 |
|||
protected $validate = 'field'; |
|||
|
|||
// 当前主表 |
|||
protected $tableName = 'field'; |
|||
|
|||
// 当前主模型 |
|||
protected $modelName = 'Field'; |
|||
|
|||
// 列表 |
|||
public function index() |
|||
{ |
|||
// 获取主键 |
|||
$pk = MakeBuilder::getPrimarykey($this->tableName); |
|||
// 获取列表数据 |
|||
$columns = MakeBuilder::getListColumns($this->tableName); |
|||
// 获取搜索数据 |
|||
$search = MakeBuilder::getListSearch($this->tableName); |
|||
// 搜索 |
|||
if (Request::param('getList') == 1) { |
|||
$where = MakeBuilder::getListWhere($this->tableName); |
|||
$orderByColumn = Request::param('orderByColumn') ?? $pk; |
|||
$isAsc = Request::param('isAsc') ?? 'desc'; |
|||
$model = '\app\common\model\\' . $this->modelName; |
|||
|
|||
return $model::getList($where, $this->pageSize, [$orderByColumn => $isAsc]); |
|||
} |
|||
|
|||
// 构建页面 |
|||
return TableBuilder::getInstance() |
|||
->setUniqueId($pk) // 设置主键 |
|||
->addColumns($columns) // 添加列表字段数据 |
|||
->setSearch($search) // 添加头部搜索 |
|||
->addColumn('right_button', '操作', 'btn') // 启用右侧操作列 |
|||
->addRightButtons(['edit', 'delete']) // 设置右侧操作列 |
|||
->addTopButtons(['add', 'edit', 'del']) // 设置顶部按钮组 |
|||
->setExtraJs($this->getIndexExtraJs()) // 设置额外JS |
|||
->fetch(); |
|||
} |
|||
|
|||
/** |
|||
* 添加 |
|||
* @param int $moduleId 模块(表)ID |
|||
* @return string |
|||
*/ |
|||
public function add(int $moduleId = 0) |
|||
{ |
|||
// 获取所有模块 |
|||
$modules = \app\common\model\Module::field('id,module_name,table_name,table_comment') |
|||
->select(); |
|||
// 获取所有字典类型 |
|||
$dictTypes = \app\common\model\DictionaryType::field('id,dict_name, remark') |
|||
->where('status', 1) |
|||
->order('sort asc, id desc') |
|||
->select(); |
|||
|
|||
$view = [ |
|||
'module_id' => $moduleId, |
|||
'info' => null, |
|||
'fieldInfo' => null, |
|||
'modules' => $modules, |
|||
'dictTypes' => $dictTypes, |
|||
'groups' => [], |
|||
]; |
|||
View::assign($view); |
|||
|
|||
return View::fetch(); |
|||
} |
|||
|
|||
/** |
|||
* 添加/修改时字段变更后重新加载配置信息 |
|||
* @param int $moduleId 模块(表)ID |
|||
* @param string $type 类型 |
|||
* @param string $field 字段(编辑字段时需传递该参数) |
|||
* @return string |
|||
*/ |
|||
public function changeType(int $moduleId, string $type, string $field = '') |
|||
{ |
|||
if (Request::isPost()) { |
|||
if (Request::param('isajax')) { |
|||
// 调用字段设置模版 |
|||
View::assign(Request::param()); |
|||
// 传递field说明是编辑字段,编辑字段需要调取当前字段的配置信息 |
|||
if (!empty($field)) { |
|||
$fieldInfo = \app\common\model\Field::where('module_id', $moduleId) |
|||
->where('field', '=', $field) |
|||
->find(); |
|||
$fieldInfo['setup'] = string2array($fieldInfo['setup']); |
|||
} else { |
|||
$fieldInfo = null; |
|||
} |
|||
$view = [ |
|||
'fieldInfo' => $fieldInfo, |
|||
]; |
|||
View::assign($view); |
|||
|
|||
return View::fetch('changeType'); |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 添加保存 |
|||
public function addPost() |
|||
{ |
|||
if (Request::isPost()) { |
|||
$data = MakeBuilder::changeFormData(Request::except(['file'], 'post'), $this->tableName); |
|||
// 验证数据 |
|||
$result = $this->validate($data, 'field'); |
|||
if (true !== $result) { |
|||
$this->error($result); |
|||
} |
|||
// 查询字段是否已录入 |
|||
$hasIn = \app\common\model\Field::where('field', $data['field']) |
|||
->where('module_id', $data['module_id']) |
|||
->count(); |
|||
if ($hasIn) { |
|||
$this->error('该模块中已存在字段' . $data['field']); |
|||
} |
|||
|
|||
// 查询字段是否已在表中存在 |
|||
$name = \app\common\model\Module::where('id', '=', $data['module_id'])->value('table_name'); |
|||
$tablename = Config::get('database.connections.mysql.prefix') . $name; |
|||
if ($this->_iset_field($tablename, $data['field'])) { |
|||
//$this->error($tablename . '表已存在[' . $data['field'] . ']字段'); |
|||
} else { |
|||
// 获取字段sql |
|||
$addfieldsql = $this->get_tablesql($data, 'add'); |
|||
} |
|||
if (isset($data['setup'])) { |
|||
$data['setup'] = array2string($data['setup']); |
|||
} |
|||
$model = Db::name('field'); |
|||
if ($model->insert($data) !== false) { |
|||
// 数据库已存在字段时不再执行字段操作 |
|||
if (isset($addfieldsql) && !empty($addfieldsql)) { |
|||
if (is_array($addfieldsql)) { |
|||
foreach ($addfieldsql as $sql) { |
|||
try { |
|||
Db::execute($sql); |
|||
} catch (\Exception $e) { |
|||
$this->error($e->getMessage() . '<br><br>[SQL]: ' . $sql); |
|||
} |
|||
} |
|||
} else { |
|||
try { |
|||
Db::execute($addfieldsql); |
|||
} catch (\Exception $e) { |
|||
$this->error($e->getMessage() . '<br><br>[SQL]: ' . $addfieldsql); |
|||
} |
|||
} |
|||
} |
|||
$this->success('添加成功!', url('index', array('module_id' => $data['module_id']))); |
|||
} else { |
|||
$this->error('添加失败!'); |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 修改 |
|||
public function edit(string $id) |
|||
{ |
|||
// 获取所有模块 |
|||
$modules = \app\common\model\Module::field('id,module_name,table_name,table_comment') |
|||
->select()->toArray(); |
|||
// 获取所有字典类型 |
|||
$dictTypes = \app\common\model\DictionaryType::field('id,dict_name, remark') |
|||
->order('sort asc, id desc') |
|||
->select(); |
|||
// 获取所有字段分组 |
|||
$groups = \app\common\model\FieldGroup::order('sort asc,id desc') |
|||
->select() |
|||
->toArray(); |
|||
// 格式化字段分组中的分组名称,避免重复展示 |
|||
foreach ($groups as $k => $v) { |
|||
foreach ($modules as $kk => $vv) { |
|||
if ($vv['id'] == $v['module_id']) { |
|||
$v['group_name'] = $vv['module_name'] . ' - ' . $v['group_name']; |
|||
break; |
|||
} |
|||
} |
|||
$groups[$k]['group_name'] = $v['group_name']; |
|||
} |
|||
|
|||
$fieldInfo = \app\common\model\Field::where('id', '=', $id)->find(); |
|||
if ($fieldInfo['setup']) { |
|||
$fieldInfo['setup'] = string2array($fieldInfo['setup']); |
|||
} |
|||
$view = [ |
|||
'module_id' => $fieldInfo['module_id'], |
|||
'info' => $fieldInfo, |
|||
'modules' => $modules, |
|||
'dictTypes' => $dictTypes, |
|||
'groups' => $groups, |
|||
]; |
|||
View::assign($view); |
|||
|
|||
return View::fetch('add'); |
|||
} |
|||
|
|||
// 修改保存 |
|||
public function editPost() |
|||
{ |
|||
if (Request::isPost()) { |
|||
$data = MakeBuilder::changeFormData(Request::except(['old_field']), $this->tableName); |
|||
$oldfield = Request::param('old_field'); |
|||
|
|||
// 验证数据 |
|||
$result = $this->validate($data, 'field'); |
|||
if (true !== $result) { |
|||
$this->error($result); |
|||
} |
|||
|
|||
$data['is_list'] = $data['is_list'] ?? 0; |
|||
$data['is_add'] = $data['is_add'] ?? 0; |
|||
$data['is_edit'] = $data['is_edit'] ?? 0; |
|||
$data['is_search'] = $data['is_search'] ?? 0; |
|||
$data['is_sort'] = $data['is_sort'] ?? 0; |
|||
|
|||
// 查询字段是否已在表中存在 |
|||
if (strpos($data['field'], '.') === false) { |
|||
$name = \app\common\model\Module::where('id', '=', $data['module_id'])->value('table_name'); |
|||
$tablename = Config::get('database.connections.mysql.prefix') . $name; |
|||
// 新的字段已被存在于表中 |
|||
if ($this->_iset_field($tablename, $data['field']) && $oldfield != $data['field']) { |
|||
$this->error($tablename . '表已存在[' . $data['field'] . ']字段'); |
|||
} |
|||
// 旧的字段不存在于表中 |
|||
if ($this->_iset_field($tablename, $oldfield) == false) { |
|||
$this->error($tablename . '表不存在[' . $oldfield . ']字段'); |
|||
} |
|||
} |
|||
|
|||
$editfieldsql = $this->get_tablesql(Request::post(), 'edit'); |
|||
|
|||
if (array_key_exists("setup", $data) && $data['setup']) { |
|||
$data['setup'] = array2string($data['setup']); |
|||
} |
|||
$model = Db::name('field'); |
|||
|
|||
if (false !== $model->update($data)) { |
|||
if (Request::param('execute_sql', 0) == 1 && !empty($editfieldsql)) { |
|||
if (is_array($editfieldsql)) { |
|||
foreach ($editfieldsql as $sql) { |
|||
try { |
|||
Db::execute($sql); |
|||
} catch (\Exception $e) { |
|||
$this->error($e->getMessage() . '<br><br>[SQL]: ' . $sql); |
|||
} |
|||
} |
|||
} else { |
|||
try { |
|||
Db::execute($editfieldsql); |
|||
} catch (\Exception $e) { |
|||
$this->error($e->getMessage() . '<br><br>[SQL]: ' . $editfieldsql); |
|||
} |
|||
} |
|||
} |
|||
|
|||
$this->success('修改成功!', 'index'); |
|||
} else { |
|||
$this->error('修改失败!'); |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 状态变更 |
|||
public function state(string $id, string $field = '') |
|||
{ |
|||
if (Request::isPost()) { |
|||
// 其他字段变更 |
|||
if ($field) { |
|||
$alowField = ['is_add', 'is_edit', 'is_list', 'is_search', 'is_sort', 'required']; |
|||
if (in_array($field, $alowField)) { |
|||
$model = '\app\common\model\\' . $this->modelName; |
|||
$info = $model::find($id); |
|||
$value = $info[$field] == 1 ? 0 : 1; |
|||
$info[$field] = $value; |
|||
$info->save(); |
|||
|
|||
return json(['error' => 0, 'msg' => '修改成功!']); |
|||
} |
|||
} |
|||
$model = '\app\common\model\\' . $this->modelName; |
|||
|
|||
return $model::state($id); |
|||
} |
|||
} |
|||
|
|||
// 删除 |
|||
public function del(string $id) |
|||
{ |
|||
if (Request::isPost()) { |
|||
if (strpos($id, ',') !== false) { |
|||
return $this->selectDel($id); |
|||
} |
|||
$r = Db::name('field')->find($id); |
|||
if ($r) { |
|||
//删除字段表中的记录 |
|||
Db::name('field')->delete($id); |
|||
} |
|||
|
|||
$moduleId = $r['module_id']; |
|||
$field = $r['field']; |
|||
|
|||
$prefix = Config::get('database.connections.mysql.prefix'); |
|||
$name = Db::name('module') |
|||
->where('id', '=', $moduleId) |
|||
->value('table_name'); |
|||
$tableName = $prefix . $name; |
|||
|
|||
//实际查询表中是否有该字段 |
|||
if ($this->_iset_field($tableName, $field)) { |
|||
Db::execute("ALTER TABLE `{$tableName}` DROP `$field`"); |
|||
} |
|||
|
|||
return json(['error' => 0, 'msg' => '删除成功!']); |
|||
} |
|||
} |
|||
|
|||
// 批量删除 |
|||
public function selectDel(string $id) |
|||
{ |
|||
$ids = explode(',', $id); |
|||
foreach ($ids as $k => $v) { |
|||
$r = Db::name('field')->find($v); |
|||
if ($r) { |
|||
// 删除字段表中的记录 |
|||
Db::name('field')->delete($r['id']); |
|||
} |
|||
|
|||
$moduleId = $r['module_id']; |
|||
$field = $r['field']; |
|||
|
|||
$prefix = Config::get('database.connections.mysql.prefix'); |
|||
$name = Db::name('module') |
|||
->where('id', '=', $moduleId) |
|||
->value('table_name'); |
|||
$tableName = $prefix . $name; |
|||
|
|||
// 实际查询表中是否有该字段 |
|||
if ($this->_iset_field($tableName, $field)) { |
|||
Db::execute("ALTER TABLE `{$tableName}` DROP `$field`"); |
|||
} |
|||
} |
|||
|
|||
return json(['error' => 0, 'msg' => '删除成功!']); |
|||
} |
|||
|
|||
//============================================ |
|||
|
|||
/** |
|||
* 获取要执行的sql |
|||
* @param array $info 字段信息 |
|||
* @param string $do 操作类型[add/edit] |
|||
* @return array|string |
|||
*/ |
|||
protected function get_tablesql(array $info, string $do = 'add') |
|||
{ |
|||
$comment = $info['name']; |
|||
$type = $info['type']; |
|||
|
|||
if (isset($info['setup']['fieldtype'])) { |
|||
$fieldtype = strtoupper($info['setup']['fieldtype']); |
|||
} |
|||
$moduleid = $info['module_id']; |
|||
$default = $info['setup']['default'] ?? ''; |
|||
$field = $info['field']; |
|||
// 字段包含.时不创建字段 |
|||
if (strpos($field, '.') !== false) { |
|||
return ''; |
|||
} |
|||
|
|||
$module = \app\common\model\Module::find($moduleid); |
|||
$name = $module->table_name; |
|||
$pk = $module->pk ?: 'id'; |
|||
|
|||
$tablename = Config::get('database.connections.mysql.prefix') . $name; |
|||
$maxlength = intval($info['maxlength']); |
|||
$minlength = intval($info['minlength']); |
|||
$numbertype = $info['setup']['numbertype'] ?? '1'; // 是否包含负数 |
|||
if ($do == 'add') { |
|||
$do = ' ADD '; |
|||
} else { |
|||
$oldfield = $info['old_field']; |
|||
$do = " CHANGE `" . $oldfield . "` "; |
|||
} |
|||
// text,textarea,radio,checkbox,date,time,datetime,daterange,tag,number,password,select,select2,image,images,file,files,editor,hidden,color |
|||
switch ($type) { |
|||
case 'text': |
|||
$fieldtype = $fieldtype ?? 'VARCHAR'; |
|||
if ($fieldtype == 'VARCHAR' || $fieldtype == 'CHAR') { |
|||
if (!$maxlength) { |
|||
$maxlength = 255; |
|||
} |
|||
$maxlength = min($maxlength, 255); |
|||
$sql = "ALTER TABLE `$tablename` $do `$field` $fieldtype( $maxlength ) NOT NULL DEFAULT '$default' COMMENT '$comment'"; |
|||
} else { |
|||
$sql = "ALTER TABLE `$tablename` $do `$field` TEXT NULL COMMENT '$comment'"; |
|||
} |
|||
break; |
|||
case 'textarea': |
|||
$fieldtype = $fieldtype ?? 'VARCHAR'; |
|||
if ($fieldtype == 'VARCHAR' || $fieldtype == 'CHAR') { |
|||
if (!$maxlength) { |
|||
$maxlength = 255; |
|||
} |
|||
$maxlength = min($maxlength, 255); |
|||
$sql = "ALTER TABLE `$tablename` $do `$field` $fieldtype( $maxlength ) NOT NULL DEFAULT '$default' COMMENT '$comment'"; |
|||
} else { |
|||
$sql = "ALTER TABLE `$tablename` $do `$field` TEXT NULL COMMENT '$comment'"; |
|||
} |
|||
break; |
|||
case 'radio': |
|||
$fieldtype = $fieldtype ?? 'VARCHAR'; |
|||
if ($fieldtype == 'VARCHAR' || $fieldtype == 'CHAR') { |
|||
if (!$maxlength) { |
|||
$maxlength = 255; |
|||
} |
|||
$maxlength = min($maxlength, 255); |
|||
$sql = "ALTER TABLE `$tablename` $do `$field` $fieldtype( $maxlength ) NOT NULL DEFAULT '$default' COMMENT '$comment'"; |
|||
} else { |
|||
$default = $default !== '' ? intval($default) : 0; |
|||
if (!$maxlength) { |
|||
$maxlength = 10; |
|||
} |
|||
$sql = "ALTER TABLE `$tablename` $do `$field` $fieldtype( $maxlength ) " . ($numbertype == 1 ? 'UNSIGNED' : '') . " NOT NULL DEFAULT '$default' COMMENT '$comment'"; |
|||
} |
|||
break; |
|||
case 'checkbox': |
|||
$fieldtype = $fieldtype ?? 'VARCHAR'; |
|||
if ($fieldtype == 'VARCHAR' || $fieldtype == 'CHAR') { |
|||
if (!$maxlength) { |
|||
$maxlength = 255; |
|||
} |
|||
$maxlength = min($maxlength, 255); |
|||
$sql = "ALTER TABLE `$tablename` $do `$field` $fieldtype( $maxlength ) NOT NULL DEFAULT '$default' COMMENT '$comment'"; |
|||
} else { |
|||
if (!$maxlength) { |
|||
$maxlength = 10; |
|||
} |
|||
$sql = "ALTER TABLE `$tablename` $do `$field` $fieldtype( $maxlength ) " . ($numbertype == 1 ? 'UNSIGNED' : '') . " NOT NULL DEFAULT '$default' COMMENT '$comment'"; |
|||
} |
|||
break; |
|||
case 'date': |
|||
$fieldtype = $fieldtype ?? 'INT'; |
|||
if ($fieldtype == 'VARCHAR' || $fieldtype == 'CHAR') { |
|||
if (!$maxlength) { |
|||
$maxlength = 255; |
|||
} |
|||
$maxlength = min($maxlength, 255); |
|||
$sql = "ALTER TABLE `$tablename` $do `$field` $fieldtype( $maxlength ) NOT NULL DEFAULT '$default' COMMENT '$comment'"; |
|||
} else { |
|||
if (!$maxlength) { |
|||
$maxlength = 10; |
|||
} |
|||
$sql = "ALTER TABLE `$tablename` $do `$field` $fieldtype( $maxlength ) " . ($numbertype == 1 ? 'UNSIGNED' : '') . " NOT NULL DEFAULT '$default' COMMENT '$comment'"; |
|||
} |
|||
break; |
|||
case 'time': |
|||
$fieldtype = $fieldtype ?? 'INT'; |
|||
if ($fieldtype == 'VARCHAR' || $fieldtype == 'CHAR') { |
|||
if (!$maxlength) { |
|||
$maxlength = 255; |
|||
} |
|||
$maxlength = min($maxlength, 255); |
|||
$sql = "ALTER TABLE `$tablename` $do `$field` $fieldtype( $maxlength ) NOT NULL DEFAULT '$default' COMMENT '$comment'"; |
|||
} else { |
|||
if (!$maxlength) { |
|||
$maxlength = 10; |
|||
} |
|||
$sql = "ALTER TABLE `$tablename` $do `$field` $fieldtype( $maxlength ) " . ($numbertype == 1 ? 'UNSIGNED' : '') . " NOT NULL DEFAULT '$default' COMMENT '$comment'"; |
|||
} |
|||
break; |
|||
case 'datetime': |
|||
$fieldtype = $fieldtype ?? 'INT'; |
|||
if ($fieldtype == 'VARCHAR' || $fieldtype == 'CHAR') { |
|||
if (!$maxlength) { |
|||
$maxlength = 255; |
|||
} |
|||
$maxlength = min($maxlength, 255); |
|||
$sql = "ALTER TABLE `$tablename` $do `$field` $fieldtype( $maxlength ) NOT NULL DEFAULT '$default' COMMENT '$comment'"; |
|||
} else { |
|||
if (!$maxlength) { |
|||
$maxlength = 10; |
|||
} |
|||
$sql = "ALTER TABLE `$tablename` $do `$field` $fieldtype( $maxlength ) " . ($numbertype == 1 ? 'UNSIGNED' : '') . " NOT NULL DEFAULT '$default' COMMENT '$comment'"; |
|||
} |
|||
break; |
|||
case 'daterange': |
|||
if (!$maxlength) { |
|||
$maxlength = 50; |
|||
} |
|||
$maxlength = min($maxlength, 255); |
|||
$fieldtype = $fieldtype ?? 'VARCHAR'; |
|||
$sql = "ALTER TABLE `$tablename` $do `$field` $fieldtype( $maxlength ) NOT NULL DEFAULT '$default' COMMENT '$comment'"; |
|||
break; |
|||
case 'tag': |
|||
$fieldtype = $fieldtype ?? 'VARCHAR'; |
|||
if ($fieldtype == 'VARCHAR' || $fieldtype == 'CHAR') { |
|||
if (!$maxlength) { |
|||
$maxlength = 255; |
|||
} |
|||
$maxlength = min($maxlength, 255); |
|||
$sql = "ALTER TABLE `$tablename` $do `$field` $fieldtype( $maxlength ) NOT NULL DEFAULT '$default' COMMENT '$comment'"; |
|||
} else { |
|||
$sql = "ALTER TABLE `$tablename` $do `$field` TEXT NULL COMMENT '$comment'"; |
|||
} |
|||
break; |
|||
case 'number': |
|||
$fieldtype = $fieldtype ?? 'INT'; |
|||
if ($fieldtype == 'VARCHAR' || $fieldtype == 'CHAR') { |
|||
if (!$maxlength) { |
|||
$maxlength = 255; |
|||
} |
|||
$maxlength = min($maxlength, 255); |
|||
$sql = "ALTER TABLE `$tablename` $do `$field` $fieldtype( $maxlength ) NOT NULL DEFAULT '$default' COMMENT '$comment'"; |
|||
} else { |
|||
$default = $default !== '' ? intval($default) : 0; |
|||
if (!$maxlength) { |
|||
$maxlength = 10; |
|||
} |
|||
if ($fieldtype == 'FLOAT' || $fieldtype == 'DECIMAL' || $fieldtype == 'DOUBLE') { |
|||
$point = isset($info['setup']['point']) && $info['setup']['point'] !== '' ? $info['setup']['point'] : '0'; |
|||
$maxlength = $maxlength . ',' . $point; |
|||
} |
|||
$sql = "ALTER TABLE `$tablename` $do `$field` $fieldtype( $maxlength ) " . ($numbertype == 1 ? 'UNSIGNED' : '') . " NOT NULL DEFAULT {$default} COMMENT '$comment'"; |
|||
} |
|||
break; |
|||
case 'password': |
|||
$fieldtype = $fieldtype ?? 'VARCHAR'; |
|||
if ($fieldtype == 'VARCHAR' || $fieldtype == 'CHAR') { |
|||
if (!$maxlength) { |
|||
$maxlength = 255; |
|||
} |
|||
$maxlength = min($maxlength, 255); |
|||
$sql = "ALTER TABLE `$tablename` $do `$field` $fieldtype( $maxlength ) NOT NULL DEFAULT '$default' COMMENT '$comment'"; |
|||
} else { |
|||
$sql = "ALTER TABLE `$tablename` $do `$field` TEXT NULL COMMENT '$comment'"; |
|||
} |
|||
break; |
|||
case 'select': |
|||
$fieldtype = $fieldtype ?? 'VARCHAR'; |
|||
if ($fieldtype == 'VARCHAR' || $fieldtype == 'CHAR') { |
|||
if (!$maxlength) { |
|||
$maxlength = 255; |
|||
} |
|||
$maxlength = min($maxlength, 255); |
|||
$sql = "ALTER TABLE `$tablename` $do `$field` $fieldtype( $maxlength ) NOT NULL DEFAULT '$default' COMMENT '$comment'"; |
|||
} elseif ($fieldtype == 'INT' || $fieldtype == 'TINYINT') { |
|||
$default = $default !== '' ? intval($default) : 0; |
|||
if (!$maxlength) { |
|||
$maxlength = $fieldtype == 'INT' ? 10 : 4; |
|||
} |
|||
$sql = "ALTER TABLE `$tablename` $do `$field` $fieldtype( $maxlength ) " . ($numbertype == 1 ? 'UNSIGNED' : '') . " NOT NULL DEFAULT {$default} COMMENT '$comment'"; |
|||
} else { |
|||
$sql = "ALTER TABLE `$tablename` $do `$field` TEXT NULL COMMENT '$comment'"; |
|||
} |
|||
break; |
|||
case 'select2': |
|||
$fieldtype = $fieldtype ?? 'VARCHAR'; |
|||
if ($fieldtype == 'VARCHAR' || $fieldtype == 'CHAR') { |
|||
if (!$maxlength) { |
|||
$maxlength = 255; |
|||
} |
|||
$maxlength = min($maxlength, 255); |
|||
$sql = "ALTER TABLE `$tablename` $do `$field` $fieldtype( $maxlength ) NOT NULL DEFAULT '$default' COMMENT '$comment'"; |
|||
} elseif ($fieldtype == 'INT' || $fieldtype == 'TINYINT') { |
|||
$default = $default !== '' ? intval($default) : 0; |
|||
if (!$maxlength) { |
|||
$maxlength = $fieldtype == 'INT' ? 10 : 4; |
|||
} |
|||
$sql = "ALTER TABLE `$tablename` $do `$field` $fieldtype( $maxlength ) " . ($numbertype == 1 ? 'UNSIGNED' : '') . " NOT NULL DEFAULT {$default} COMMENT '$comment'"; |
|||
} else { |
|||
$sql = "ALTER TABLE `$tablename` $do `$field` TEXT NULL COMMENT '$comment'"; |
|||
} |
|||
break; |
|||
case 'linkage': |
|||
$fieldtype = $fieldtype ?? 'VARCHAR'; |
|||
if ($fieldtype == 'VARCHAR' || $fieldtype == 'CHAR') { |
|||
if (!$maxlength) { |
|||
$maxlength = 255; |
|||
} |
|||
$maxlength = min($maxlength, 255); |
|||
$sql = "ALTER TABLE `$tablename` $do `$field` $fieldtype( $maxlength ) NOT NULL DEFAULT '$default' COMMENT '$comment'"; |
|||
} elseif ($fieldtype == 'INT' || $fieldtype == 'TINYINT') { |
|||
$default = $default !== '' ? intval($default) : 0; |
|||
if (!$maxlength) { |
|||
$maxlength = $fieldtype == 'INT' ? 10 : 4; |
|||
} |
|||
$sql = "ALTER TABLE `$tablename` $do `$field` $fieldtype( $maxlength ) " . ($numbertype == 1 ? 'UNSIGNED' : '') . " NOT NULL DEFAULT {$default} COMMENT '$comment'"; |
|||
} else { |
|||
$sql = "ALTER TABLE `$tablename` $do `$field` TEXT NULL COMMENT '$comment'"; |
|||
} |
|||
break; |
|||
case 'image': |
|||
$fieldtype = $fieldtype ?? 'VARCHAR'; |
|||
if ($fieldtype == 'VARCHAR' || $fieldtype == 'CHAR') { |
|||
if (!$maxlength) { |
|||
$maxlength = 80; |
|||
} |
|||
$maxlength = min($maxlength, 255); |
|||
$sql = "ALTER TABLE `$tablename` $do `$field` $fieldtype( $maxlength ) NOT NULL DEFAULT '$default' COMMENT '$comment'"; |
|||
} else { |
|||
$sql = "ALTER TABLE `$tablename` $do `$field` TEXT NULL COMMENT '$comment'"; |
|||
} |
|||
break; |
|||
case 'images': |
|||
$fieldtype = $fieldtype ?? 'VARCHAR'; |
|||
if ($fieldtype == 'VARCHAR' || $fieldtype == 'CHAR') { |
|||
if (!$maxlength) { |
|||
$maxlength = 255; |
|||
} |
|||
$maxlength = min($maxlength, 255); |
|||
$sql = "ALTER TABLE `$tablename` $do `$field` $fieldtype( $maxlength ) NOT NULL DEFAULT '$default' COMMENT '$comment'"; |
|||
} else { |
|||
$sql = "ALTER TABLE `$tablename` $do `$field` TEXT NULL COMMENT '$comment'"; |
|||
} |
|||
break; |
|||
case 'file': |
|||
$fieldtype = $fieldtype ?? 'VARCHAR'; |
|||
if ($fieldtype == 'VARCHAR' || $fieldtype == 'CHAR') { |
|||
if (!$maxlength) { |
|||
$maxlength = 80; |
|||
} |
|||
$maxlength = min($maxlength, 255); |
|||
$sql = "ALTER TABLE `$tablename` $do `$field` $fieldtype( $maxlength ) NOT NULL DEFAULT '$default' COMMENT '$comment'"; |
|||
} else { |
|||
$sql = "ALTER TABLE `$tablename` $do `$field` TEXT NULL COMMENT '$comment'"; |
|||
} |
|||
break; |
|||
case 'files': |
|||
$fieldtype = $fieldtype ?? 'VARCHAR'; |
|||
if ($fieldtype == 'VARCHAR' || $fieldtype == 'CHAR') { |
|||
if (!$maxlength) { |
|||
$maxlength = 255; |
|||
} |
|||
$maxlength = min($maxlength, 255); |
|||
$sql = "ALTER TABLE `$tablename` $do `$field` $fieldtype( $maxlength ) NOT NULL DEFAULT '$default' COMMENT '$comment'"; |
|||
} else { |
|||
$sql = "ALTER TABLE `$tablename` $do `$field` TEXT NULL COMMENT '$comment'"; |
|||
} |
|||
break; |
|||
case 'editor': |
|||
$fieldtype = $fieldtype ?? 'VARCHAR'; |
|||
if ($fieldtype == 'VARCHAR' || $fieldtype == 'CHAR') { |
|||
if (!$maxlength) { |
|||
$maxlength = 255; |
|||
} |
|||
$maxlength = min($maxlength, 255); |
|||
$sql = "ALTER TABLE `$tablename` $do `$field` $fieldtype( $maxlength ) NOT NULL DEFAULT '$default' COMMENT '$comment'"; |
|||
} else { |
|||
$sql = "ALTER TABLE `$tablename` $do `$field` TEXT NULL COMMENT '$comment'"; |
|||
} |
|||
break; |
|||
case 'hidden': |
|||
$fieldtype = $fieldtype ?? 'VARCHAR'; |
|||
if ($fieldtype == 'VARCHAR' || $fieldtype == 'CHAR') { |
|||
if (!$maxlength) { |
|||
$maxlength = 255; |
|||
} |
|||
$maxlength = min($maxlength, 255); |
|||
$sql = "ALTER TABLE `$tablename` $do `$field` $fieldtype( $maxlength ) NOT NULL DEFAULT '$default' COMMENT '$comment'"; |
|||
} else { |
|||
if (!$maxlength) { |
|||
$maxlength = 10; |
|||
} |
|||
// 主键字段自增 |
|||
if ($pk == $field) { |
|||
$sql = "ALTER TABLE `$tablename` $do `$field` $fieldtype( $maxlength ) " . ($numbertype == 1 ? 'UNSIGNED' : '') . " NOT NULL AUTO_INCREMENT COMMENT '$comment'"; |
|||
} else { |
|||
$sql = "ALTER TABLE `$tablename` $do `$field` $fieldtype( $maxlength ) " . ($numbertype == 1 ? 'UNSIGNED' : '') . " NOT NULL DEFAULT '$default' COMMENT '$comment'"; |
|||
} |
|||
} |
|||
break; |
|||
case 'color': |
|||
$fieldtype = $fieldtype ?? 'VARCHAR'; |
|||
if ($fieldtype == 'VARCHAR' || $fieldtype == 'CHAR') { |
|||
if (!$maxlength) { |
|||
$maxlength = 10; |
|||
} |
|||
$maxlength = min($maxlength, 255); |
|||
$sql = "ALTER TABLE `$tablename` $do `$field` $fieldtype( $maxlength ) NOT NULL DEFAULT '$default' COMMENT '$comment'"; |
|||
} else { |
|||
$sql = "ALTER TABLE `$tablename` $do `$field` TEXT NULL COMMENT '$comment'"; |
|||
} |
|||
break; |
|||
} |
|||
|
|||
return $sql; |
|||
} |
|||
|
|||
/** |
|||
* 判断表中是否存在所选字段 |
|||
* @param $table 表全称 |
|||
* @param $field 字段名称 |
|||
* @return mixed |
|||
*/ |
|||
protected function _iset_field($table, $field) |
|||
{ |
|||
$fields = Db::getTableFields($table); |
|||
if (array_search($field, $fields) === false) { |
|||
return false; |
|||
} else { |
|||
return true; |
|||
} |
|||
} |
|||
|
|||
// 列表页额外JS |
|||
private function getIndexExtraJs() |
|||
{ |
|||
$url = url('state'); |
|||
$js = '<script type="text/javascript"> |
|||
$(document).ready(function() { |
|||
//避免pjax重复加载js导致事件重复绑定 |
|||
if (typeof (fieldIndexExtraJs) != "undefined") { |
|||
return; |
|||
} |
|||
$(document).on("click", \'.js_is_add\', function () { |
|||
var id = $(this).parent(\'tr\').data(\'uniqueid\'); |
|||
if(id){ |
|||
$.operate.submit(\'' . $url . '\', "post", "json", {"id": id,"field": \'is_add\'}); |
|||
} |
|||
}) |
|||
$(document).on("click", \'.js_is_edit\', function () { |
|||
var id = $(this).parent(\'tr\').data(\'uniqueid\'); |
|||
if(id){ |
|||
$.operate.submit(\'' . $url . '\', "post", "json", {"id": id,"field": \'is_edit\'}); |
|||
} |
|||
}) |
|||
$(document).on("click", \'.js_is_list\', function () { |
|||
var id = $(this).parent(\'tr\').data(\'uniqueid\'); |
|||
if(id){ |
|||
$.operate.submit(\'' . $url . '\', "post", "json", {"id": id,"field": \'is_list\'}); |
|||
} |
|||
}) |
|||
$(document).on("click", \'.js_is_search\', function () { |
|||
var id = $(this).parent(\'tr\').data(\'uniqueid\'); |
|||
if(id){ |
|||
$.operate.submit(\'' . $url . '\', "post", "json", {"id": id,"field": \'is_search\'}); |
|||
} |
|||
}) |
|||
$(document).on("click", \'.js_is_sort\', function () { |
|||
var id = $(this).parent(\'tr\').data(\'uniqueid\'); |
|||
if(id){ |
|||
$.operate.submit(\'' . $url . '\', "post", "json", {"id": id,"field": \'is_sort\'}); |
|||
} |
|||
}) |
|||
$(document).on("click", \'.js_required\', function () { |
|||
var id = $(this).parent(\'tr\').data(\'uniqueid\'); |
|||
if(id){ |
|||
$.operate.submit(\'' . $url . '\', "post", "json", {"id": id,"field": \'required\'}); |
|||
} |
|||
}) |
|||
fieldIndexExtraJs = true; |
|||
}) |
|||
</script>'; |
|||
|
|||
return $js; |
|||
} |
|||
} |
|||
@ -0,0 +1,47 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 字段分组控制器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2021/06/23 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\controller; |
|||
|
|||
// 引入框架内置类 |
|||
use think\facade\Request; |
|||
|
|||
// 引入表格和表单构建器 |
|||
use app\common\facade\MakeBuilder; |
|||
use app\common\builder\FormBuilder; |
|||
use app\common\builder\TableBuilder; |
|||
|
|||
class FieldGroup extends Base |
|||
{ |
|||
// 验证器 |
|||
protected $validate = 'FieldGroup'; |
|||
|
|||
// 当前主表 |
|||
protected $tableName = 'field_group'; |
|||
|
|||
// 当前主模型 |
|||
protected $modelName = 'FieldGroup'; |
|||
|
|||
} |
|||
@ -0,0 +1,251 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 首页控制器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | QQ: 407593529 |
|||
* '::::::::::::' | DATETIME: 2019/04/03 |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
|
|||
namespace app\admin\controller; |
|||
|
|||
use think\facade\App; |
|||
use think\facade\Cache; |
|||
use think\facade\Config; |
|||
use think\facade\Db; |
|||
use think\facade\Request; |
|||
use think\facade\View; |
|||
|
|||
class Index extends Base |
|||
{ |
|||
// 首页 |
|||
public function index() |
|||
{ |
|||
// 系统信息 |
|||
$mysqlVersion = Db::query('SELECT VERSION() AS ver'); |
|||
$config = [ |
|||
'url' => $_SERVER['HTTP_HOST'], |
|||
'document_root' => $_SERVER['DOCUMENT_ROOT'], |
|||
'server_os' => PHP_OS, |
|||
'server_port' => $_SERVER['SERVER_PORT'], |
|||
'server_ip' => isset($_SERVER['SERVER_ADDR']) ? $_SERVER['SERVER_ADDR'] : '', |
|||
'server_soft' => $_SERVER['SERVER_SOFTWARE'], |
|||
'php_version' => PHP_VERSION, |
|||
'mysql_version' => $mysqlVersion[0]['ver'], |
|||
'max_upload_size' => ini_get('upload_max_filesize'), |
|||
'version' => App::version(), |
|||
'siyu_version' => Config::get('app.siyu_version'), |
|||
]; |
|||
|
|||
// 查找一周内注册用户信息 |
|||
$user = \app\common\model\Users::where('create_time', '>', time() - 60 * 60 * 24 * 7)->count(); |
|||
|
|||
// 查找待处理留言信息 |
|||
if (class_exists('\app\common\model\Message')) { |
|||
$message = \app\common\model\Message::where('status', '0')->count(); |
|||
} |
|||
|
|||
// 查找是否有在线留言的模型id |
|||
$messageModuleId = \app\common\model\Module::where('table_name', 'message')->value('id'); |
|||
$messageCatUrl = url('Message/index'); |
|||
if ($messageModuleId) { |
|||
// 查询留言模块第一个栏目ID |
|||
$messageCatId = \app\common\model\Cate::where('module_id', $messageModuleId)->value('id'); |
|||
if (!is_null($messageCatId)) { |
|||
// 生成URL |
|||
$messageCatUrl = url('Message/index', ['cate_id' => $messageCatId]); |
|||
} |
|||
} |
|||
|
|||
$view = [ |
|||
'config' => $config, |
|||
'user' => $user, |
|||
'message' => $message ?? 0, |
|||
'messageCatUrl' => $messageCatUrl, |
|||
'indexTips' => $this->getIndexTips(), |
|||
]; |
|||
View::assign($view); |
|||
return View::fetch(); |
|||
} |
|||
|
|||
// 清除缓存 |
|||
public function clear() |
|||
{ |
|||
$path = App::getRootPath() . 'runtime'; |
|||
if ($this->_deleteDir($path)) { |
|||
$result['msg'] = '清除缓存成功!'; |
|||
$result['error'] = 0; |
|||
} else { |
|||
$result['msg'] = '清除缓存失败!'; |
|||
$result['error'] = 1; |
|||
} |
|||
$result['url'] = (string)url('login/index'); |
|||
return json($result); |
|||
} |
|||
|
|||
/** |
|||
* 预览 |
|||
* @param string $module 模型名称 |
|||
* @param string $id 文章id |
|||
* @return \think\response\Redirect |
|||
*/ |
|||
public function preview(string $module, string $id) |
|||
{ |
|||
// 查询当前模块信息 |
|||
$model = '\app\common\model\\' . $module; |
|||
$info = $model::find($id); |
|||
if ($info) { |
|||
// 查询所在栏目信息 |
|||
$cate = \app\common\model\Cate::find($info['cate_id']); |
|||
if ($cate->module->getData('model_name') == 'Page') { |
|||
if ($cate['cate_folder']) { |
|||
$url = $cate['cate_folder'] . '.' . Config::get('route.url_html_suffix'); |
|||
} else { |
|||
$url = $module . Config::get('route.pathinfo_depr') . 'index.' . Config::get('route.url_html_suffix') . '?cate=' . $cate['id']; |
|||
} |
|||
} else { |
|||
if ($cate['cate_folder']) { |
|||
$url = $cate['cate_folder'] . Config::get('route.pathinfo_depr') . $id . '.' . Config::get('route.url_html_suffix'); |
|||
} else { |
|||
$url = $module . Config::get('route.pathinfo_depr') . 'info.' . Config::get('route.url_html_suffix') . '?cate=' . $cate['id'] . '&id=' . $id; |
|||
} |
|||
} |
|||
if (isset($url) && !empty($url)) { |
|||
// 检测是否开启了域名绑定 |
|||
$domainBind = Config::get('app.domain_bind'); |
|||
if ($domainBind) { |
|||
$domainBindKey = array_search('index', $domainBind); |
|||
$domainBindKey = $domainBindKey == '*' ? 'www.' : ($domainBindKey ? $domainBindKey . '.' : ''); |
|||
$url = Request::scheme() . '://' . $domainBindKey . Request::rootDomain() . '/' . $url; |
|||
} else { |
|||
$url = '/index/' . $url; |
|||
} |
|||
} |
|||
} |
|||
return redirect($url); |
|||
} |
|||
|
|||
/** |
|||
* select 2 ajax分页获取数据 |
|||
* @param int $id 字段id |
|||
* @param string $keyWord 搜索词 |
|||
* @param string $rows 显示数量 |
|||
* @param string $value 默认值 |
|||
* @return array |
|||
*/ |
|||
public function select2(int $id, string $keyWord = '', string $rows = '10', string $value = '') |
|||
{ |
|||
// 字段信息 |
|||
$field = \app\common\model\Field::find($id); |
|||
if (is_null($field) || empty($field['relation_model']) || empty($field['relation_field'])) { |
|||
return []; |
|||
} |
|||
$model = '\app\common\model\\' . $field['relation_model']; |
|||
// 获取主键 |
|||
$pk = \app\common\model\Module::where('model_name', $field['relation_model'])->value('pk') ?? 'id'; |
|||
// 默认值 |
|||
if ($value) { |
|||
$valueText = $model::where($pk, $value)->value($field['relation_field']); |
|||
if ($valueText) { |
|||
return [ |
|||
'key' => $value, |
|||
'value' => $valueText |
|||
]; |
|||
} |
|||
} |
|||
|
|||
// 搜索条件 |
|||
$where = []; |
|||
if ($keyWord) { |
|||
$where[] = [$field['relation_field'], 'LIKE', '%' . $keyWord . '%']; |
|||
} |
|||
|
|||
$list = $model::field($pk . ',' . $field['relation_field']) |
|||
->where($where) |
|||
->order($pk . ' desc') |
|||
->paginate([ |
|||
'query' => Request::get(), |
|||
'list_rows' => $rows, |
|||
]); |
|||
foreach ($list as $k => $v) { |
|||
$v['text'] = $v[$field['relation_field']]; |
|||
} |
|||
return $list; |
|||
} |
|||
|
|||
/** |
|||
* ajax获取多级联动数据 |
|||
* @param string $model 模型名称 |
|||
* @param string $key 关联模型的主键 |
|||
* @param string $keyValue 要展示的字段 |
|||
* @param int $pid 父ID |
|||
* @param string $pidFieldName 关联模型的父级id字段名 |
|||
* @return array |
|||
*/ |
|||
public function linkage(string $model, string $key, string $keyValue, int $pid = 0, string $pidFieldName = 'pid') |
|||
{ |
|||
$list = getLinkageData($model, $pid, $pidFieldName); |
|||
$result = []; |
|||
foreach ($list as $v) { |
|||
$result[] = [ |
|||
'key' => $v[$key], |
|||
'value' => $v[$keyValue], |
|||
]; |
|||
} |
|||
return [ |
|||
'code' => 1, |
|||
'list' => $result |
|||
]; |
|||
} |
|||
|
|||
// 执行删除 |
|||
private function _deleteDir($R) |
|||
{ |
|||
Cache::clear(); |
|||
$handle = opendir($R); |
|||
while (($item = readdir($handle)) !== false) { |
|||
// log目录不可以删除 |
|||
if ($item != '.' && $item != '..' && $item != 'log') { |
|||
if (is_dir($R . DIRECTORY_SEPARATOR . $item)) { |
|||
$this->_deleteDir($R . DIRECTORY_SEPARATOR . $item); |
|||
} else { |
|||
if ($item != '.gitignore') { |
|||
if (!unlink($R . DIRECTORY_SEPARATOR . $item)) { |
|||
return false; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
closedir($handle); |
|||
return true; |
|||
//return rmdir($R); // 删除空的目录 |
|||
} |
|||
|
|||
// 检查提示信息 |
|||
private function getIndexTips() |
|||
{ |
|||
$password = \app\common\model\Admin::where('id', session('admin.id'))->value('password'); |
|||
if ($password == md5('admin')) { |
|||
return '<h6 class="mb-0"><i class="icon fas fa-fw fa-exclamation-triangle"></i> 请尽快修改后台初始密码!</h6>'; |
|||
} |
|||
return ''; |
|||
} |
|||
} |
|||
@ -0,0 +1,47 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 友情链接控制器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2021/06/23 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\controller; |
|||
|
|||
// 引入框架内置类 |
|||
use think\facade\Request; |
|||
|
|||
// 引入表格和表单构建器 |
|||
use app\common\facade\MakeBuilder; |
|||
use app\common\builder\FormBuilder; |
|||
use app\common\builder\TableBuilder; |
|||
|
|||
class Link extends Base |
|||
{ |
|||
// 验证器 |
|||
protected $validate = 'Link'; |
|||
|
|||
// 当前主表 |
|||
protected $tableName = 'link'; |
|||
|
|||
// 当前主模型 |
|||
protected $modelName = 'Link'; |
|||
|
|||
} |
|||
@ -0,0 +1,66 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 后台登录控制制器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | QQ: 407593529 |
|||
* '::::::::::::' | DATETIME: 2019/04/03 |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\controller; |
|||
|
|||
use think\captcha\facade\Captcha; |
|||
use think\facade\Request; |
|||
use think\facade\Session; |
|||
use think\facade\View; |
|||
|
|||
class Login |
|||
{ |
|||
// 登录页面 |
|||
public function index() |
|||
{ |
|||
// 已登录自动跳转 |
|||
if (Session::has('admin')) { |
|||
return redirect((string)url('Index/index')); |
|||
} |
|||
// 查找系统设置 |
|||
$system = \app\common\model\System::find(1); |
|||
|
|||
$view['mobile'] = Request::isMobile(); |
|||
$view['system'] = $system; |
|||
View::assign($view); |
|||
return View::fetch(); |
|||
} |
|||
|
|||
// 校验登录 |
|||
public function checkLogin(){ |
|||
return \app\common\model\Admin::checkLogin(); |
|||
} |
|||
|
|||
// 验证码 |
|||
public function captcha(){ |
|||
return Captcha::create(); |
|||
} |
|||
|
|||
// 退出登录 |
|||
public function logout(){ |
|||
Session::delete('admin'); |
|||
return redirect('index'); |
|||
} |
|||
} |
|||
@ -0,0 +1,47 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 留言模块控制器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2021/06/23 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\controller; |
|||
|
|||
// 引入框架内置类 |
|||
use think\facade\Request; |
|||
|
|||
// 引入表格和表单构建器 |
|||
use app\common\facade\MakeBuilder; |
|||
use app\common\builder\FormBuilder; |
|||
use app\common\builder\TableBuilder; |
|||
|
|||
class Message extends Base |
|||
{ |
|||
// 验证器 |
|||
protected $validate = 'Message'; |
|||
|
|||
// 当前主表 |
|||
protected $tableName = 'message'; |
|||
|
|||
// 当前主模型 |
|||
protected $modelName = 'Message'; |
|||
|
|||
} |
|||
@ -0,0 +1,419 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 模块管理控制器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2021/04/16 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
|
|||
namespace app\admin\controller; |
|||
|
|||
// 引入框架内置类 |
|||
use think\facade\Db; |
|||
use think\facade\Request; |
|||
|
|||
// 引入表格和表单构建器 |
|||
use app\common\facade\MakeBuilder; |
|||
use app\common\builder\FormBuilder; |
|||
use app\common\builder\TableBuilder; |
|||
|
|||
class Module extends Base |
|||
{ |
|||
// 验证器 |
|||
protected $validate = 'Module'; |
|||
|
|||
// 当前主表 |
|||
protected $tableName = 'module'; |
|||
|
|||
// 当前主模型 |
|||
protected $modelName = 'Module'; |
|||
|
|||
// 列表 |
|||
public function index() |
|||
{ |
|||
// 获取主键 |
|||
$pk = MakeBuilder::getPrimarykey($this->tableName); |
|||
// 获取列表数据 |
|||
$columns = MakeBuilder::getListColumns($this->tableName); |
|||
// 获取搜索数据 |
|||
$search = MakeBuilder::getListSearch($this->tableName); |
|||
// 搜索 |
|||
if (Request::param('getList') == 1) { |
|||
$where = MakeBuilder::getListWhere($this->tableName); |
|||
$orderByColumn = Request::param('orderByColumn') ?? $pk; |
|||
$isAsc = Request::param('isAsc') ?? 'desc'; |
|||
$model = '\app\common\model\\' . $this->modelName; |
|||
return $model::getList($where, $this->pageSize, [$orderByColumn => $isAsc]); |
|||
} |
|||
// 构建页面 |
|||
return TableBuilder::getInstance() |
|||
->setUniqueId($pk) // 设置主键 |
|||
->addColumns($columns) // 添加列表字段数据 |
|||
->setSearch($search) // 添加头部搜索 |
|||
->addColumn('right_button', '操作', 'btn') // 启用右侧操作列 |
|||
->addRightButtons(['edit', 'delete']) // 设置右侧操作列 |
|||
->addTopButtons(['add', 'edit', 'del', 'export', 'build']) // 设置顶部按钮组 |
|||
->addTopButton( |
|||
'default', [ |
|||
'title' => '生成菜单规则', |
|||
'icon' => 'fa fa-bars', |
|||
'class' => 'btn btn-danger single disabled', |
|||
'href' => '', |
|||
'onclick' => '$.operate.makeRule(\'' . url('makeRule') . '\')' |
|||
] |
|||
) // 自定义按钮 |
|||
->fetch(); |
|||
} |
|||
|
|||
// 添加 |
|||
public function add() |
|||
{ |
|||
// 获取字段信息 |
|||
$columns = MakeBuilder::getAddColumns($this->tableName); |
|||
// 提示信息 |
|||
$pageTips = '1、没有表时会创建表和字段并插入至字段管理中;<br>2、已有表时会检测必要字段后插入至字段管理中;<br>3、已有表需包含的字段:主键、create_time、update_time、[sort 勾选排序字段时]、[status 勾选状态字段时]、[cate_id, hits, keywords, description, template, url 表类型为CMS时];'; |
|||
// 构建页面 |
|||
return FormBuilder::getInstance() |
|||
->addFormItems($columns) |
|||
->setPageTips($pageTips, 'warning') // 提示信息 |
|||
->setExtraJs($this->getAddExtraJs()) // 设置额外JS |
|||
->fetch(); |
|||
} |
|||
|
|||
// 添加保存 |
|||
public function addPost() |
|||
{ |
|||
if (Request::isPost()) { |
|||
$data = MakeBuilder::changeFormData(Request::except(['file'], 'post'), $this->tableName); |
|||
$result = $this->validate($data, $this->validate); |
|||
if (true !== $result) { |
|||
// 验证失败 输出错误信息 |
|||
$this->error($result); |
|||
} else { |
|||
$model = '\app\common\model\\' . $this->modelName; |
|||
// 唯一判断 |
|||
$count = $model::where('table_name', $data['table_name'])->count(); |
|||
if ($count) { |
|||
$this->error('表名称 [' . $data['table_name'] . '] 已存在'); |
|||
} |
|||
$result = $model::addPost($data); |
|||
if ($result['error']) { |
|||
$this->error($result['msg']); |
|||
} else { |
|||
$makeTable = \app\common\model\Module::makeTable($data['table_name']); |
|||
if ($makeTable === true) { |
|||
$this->success($result['msg'], 'index'); |
|||
} else { |
|||
// 删除刚插入的数据 |
|||
$model::where('table_name', $data['table_name'])->delete(); |
|||
$this->error($makeTable); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 修改 |
|||
public function edit(string $id) |
|||
{ |
|||
$model = '\app\common\model\\' . $this->modelName; |
|||
$info = $model::edit($id)->toArray(); |
|||
// 获取字段信息 |
|||
$columns = MakeBuilder::getAddColumns($this->tableName, $info); |
|||
// 提示信息 |
|||
$pageTips = '1、主键发生变动时会更改数据库中的表结构,字段管理中的主键字段也会相应改变;<br>2、表名称发生变动时会更改数据库中的表名称,需要重新进行代码生成和菜单生成;'; |
|||
// 构建页面 |
|||
return FormBuilder::getInstance() |
|||
->addFormItems($columns) |
|||
->setPageTips($pageTips, 'warning') // 提示信息 |
|||
->setExtraJs($this->getEditExtraJs()) // 设置额外JS |
|||
->fetch(); |
|||
} |
|||
|
|||
// 修改保存 |
|||
public function editPost() |
|||
{ |
|||
if (Request::isPost()) { |
|||
$data = MakeBuilder::changeFormData(Request::except(['file'], 'post'), $this->tableName); |
|||
$result = $this->validate($data, $this->validate); |
|||
if (true !== $result) { |
|||
// 验证失败 输出错误信息 |
|||
$this->error($result); |
|||
} else { |
|||
// 尝试修改表名称和主键 |
|||
$result = \app\common\model\Module::changeTable($data); |
|||
if ($result !== true) { |
|||
$this->error($result); |
|||
} |
|||
// 修改表记录信息 |
|||
$model = '\app\common\model\\' . $this->modelName; |
|||
$result = $model::editPost($data); |
|||
if ($result['error']) { |
|||
$this->error($result['msg']); |
|||
} else { |
|||
$this->success($result['msg'], 'index'); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 删除 |
|||
public function del(string $id) |
|||
{ |
|||
if (Request::isPost()) { |
|||
// 当有栏目使用该模块时不可删除 |
|||
if ($this->checkCate($id) == false) { |
|||
return ['error' => 1, 'msg' => '删除失败,请先删除已使用该模块的栏目']; |
|||
} |
|||
// 模块删除的同时删除字段管理中对应的数据 |
|||
$this->delModuleField($id); |
|||
// 是否清空表[不删除] |
|||
// 是否删除模型、控制器、验证器文件[不删除] |
|||
|
|||
if (strpos($id, ',') !== false) { |
|||
return $this->selectDel($id); |
|||
} |
|||
$model = '\app\common\model\\' . $this->modelName; |
|||
return $model::del($id); |
|||
} |
|||
} |
|||
|
|||
// 批量删除 |
|||
public function selectDel(string $id) |
|||
{ |
|||
if (Request::isPost()) { |
|||
$model = '\app\common\model\\' . $this->modelName; |
|||
return $model::selectDel($id); |
|||
} |
|||
} |
|||
|
|||
// ========================== |
|||
|
|||
// 检查表信息 |
|||
public function checkTale(string $table_name = '') |
|||
{ |
|||
if ($table_name) { |
|||
try { |
|||
// 获取模型名称 |
|||
$modelName = ''; |
|||
$tableNameArr = explode('_', $table_name); |
|||
foreach ($tableNameArr as $v) { |
|||
$modelName .= ucfirst($v); |
|||
} |
|||
// 获取完整表名称 |
|||
$tableName = \think\facade\Config::get('database.connections.mysql.prefix') . $table_name; |
|||
// 获取表全部字段 |
|||
$fields = Db::getTableFields($tableName); |
|||
// 从数据库中获取表字段信息 |
|||
$sql = "SELECT * FROM `information_schema`.`columns` WHERE TABLE_SCHEMA = :table_schema AND table_name = :table_name " |
|||
. "ORDER BY ORDINAL_POSITION"; |
|||
$columnList = Db::query($sql, ['table_schema' => \think\facade\Config::get('database.connections.mysql.database'), 'table_name' => $tableName]); |
|||
$priKey = ''; |
|||
foreach ($columnList as $v) { |
|||
if ($v['COLUMN_KEY'] == 'PRI') { |
|||
$priKey = $v['COLUMN_NAME']; |
|||
break; |
|||
} |
|||
} |
|||
if (!$priKey) { |
|||
return json(['error' => 1, 'msg' => '请设置 [' . $tableName . '] 表的主键']); |
|||
} |
|||
// 获取表基础信息 |
|||
$tableInfo = Db::query("SHOW TABLE STATUS LIKE '{$tableName}'"); |
|||
$tableInfo = $tableInfo[0]; |
|||
// 获取表类型 |
|||
$tableType = '2'; |
|||
if (in_array('cate_id', $fields) && in_array('hits', $fields) && in_array('keywords', $fields) && in_array('description', $fields) && in_array('template', $fields) && in_array('url', $fields)) { |
|||
$tableType = '1'; |
|||
} |
|||
// 自动时间戳 |
|||
if (in_array('create_time', $fields) && in_array('update_time', $fields)) { |
|||
$autoTimestamp = '1'; |
|||
} |
|||
|
|||
// 返回信息 |
|||
$data = [ |
|||
'module_name' => $tableInfo['Comment'] ?: $table_name, // 模块名称 |
|||
'model_name' => $modelName, // 模型名称 |
|||
'table_comment' => $tableInfo['Comment'], // 表注释 |
|||
'pk' => $priKey, // 主键 |
|||
'table_type' => $tableType, // 表类型 |
|||
'is_sort' => in_array('sort', $fields) ? '1' : '0', // 排序字段 |
|||
'is_status' => in_array('status', $fields) ? '1' : '0', // 状态字段 |
|||
'remark' => $tableInfo['Comment'], // 备注 |
|||
'auto_timestamp' => $autoTimestamp ?? '0', // 自动写入时间戳 |
|||
'add_param' => $addParam ?? '', // 添加参数 |
|||
]; |
|||
return json(['error' => 0, 'msg' => '数据表已存在,系统已自动补全其他字段', 'data' => $data]); |
|||
} catch (\Exception $e) { |
|||
return json(['error' => 2, 'msg' => $e->getMessage()]); |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 生成代码 |
|||
public function build(string $id, string $file = '') |
|||
{ |
|||
return MakeBuilder::makeModule($id, $file); |
|||
} |
|||
|
|||
// 生成菜单 |
|||
public function makeRule(string $id) |
|||
{ |
|||
return MakeBuilder::makeRule($id); |
|||
} |
|||
|
|||
/** |
|||
* 删除模块时判断是否已有栏目在应用[兼容多选和单选] |
|||
* @param $id 模块id |
|||
* @return bool false 不可删除,true 可删除 |
|||
*/ |
|||
private function checkCate(string $id) |
|||
{ |
|||
strpos($id, ',') !== false ? $op = 'in' : $op = '='; |
|||
$count = \app\common\model\Cate::where('module_id', $op, $id)->count(); |
|||
if ($count) { |
|||
return false; |
|||
} |
|||
return true; |
|||
} |
|||
|
|||
/** |
|||
* 删除模型时删除当前模型的所有字段数据[兼容多选和单选] |
|||
* @param string $id |
|||
* @return bool |
|||
* @throws \Exception |
|||
*/ |
|||
private function delModuleField(string $id) |
|||
{ |
|||
strpos($id, ',') !== false ? $op = 'in' : $op = '='; |
|||
return \app\common\model\Field::where('module_id', $op, $id)->delete(); |
|||
} |
|||
|
|||
// 添加页额外JS |
|||
private function getAddExtraJs() |
|||
{ |
|||
$js = '<script type="text/javascript"> |
|||
$(function () { |
|||
// 添加默认隐藏预览按钮 |
|||
$("input[name=\'right_button[]\']").each(function(){ |
|||
var value = $(this).val(); |
|||
if(value == \'preview\'){ |
|||
$(this).parent(\'.dd_radio_lable\').hide(); |
|||
} |
|||
}); |
|||
// 切换表类型时显示/隐藏预览按钮,设置添加参数 |
|||
$("select[name=\'table_type\']").change(function(){ |
|||
var value = $(this).val(); |
|||
if(value == \'1\'){ |
|||
$("input[name=\'right_button[]\']").each(function(){ |
|||
if($(this).val() == \'preview\'){ |
|||
$(this).attr("checked",true); |
|||
$(this).parent(\'.dd_radio_lable\').show(); |
|||
} |
|||
}); |
|||
$("input[name=\'add_param\']").val(\'cate_id\'); |
|||
} else { |
|||
$("input[name=\'right_button[]\']").each(function(){ |
|||
if($(this).val() == \'preview\'){ |
|||
$(this).attr("checked",false); |
|||
$(this).parent(\'.dd_radio_lable\').hide(); |
|||
} |
|||
}); |
|||
$("input[name=\'add_param\']").val(\'\'); |
|||
} |
|||
}) |
|||
// 表名称添加完时尝试补充其他信息 |
|||
$("input[name=\'table_name\']").change(function(){ |
|||
var config = { |
|||
url: \'checkTale\', |
|||
dataType: \'json\', |
|||
data: {table_name:$("input[name=\'table_name\']").val()}, |
|||
success: function(result) { |
|||
if(result.error == 1){ |
|||
toastr.success(result.msg); |
|||
} else if(result.error == 0) { |
|||
$("input[name=\'module_name\']").val(result.data.module_name); |
|||
$("input[name=\'model_name\']").val(result.data.model_name); |
|||
$("input[name=\'table_comment\']").val(result.data.table_comment); |
|||
$("input[name=\'pk\']").val(result.data.pk); |
|||
$("select[name=\'table_type\']").val(result.data.table_type); |
|||
if(result.data.is_sort == \'1\'){ |
|||
$("#is_sort1").attr(\'checked\', \'checked\'); |
|||
} else { |
|||
$("#is_sort2").attr(\'checked\', \'checked\'); |
|||
} |
|||
if(result.data.is_status == \'1\'){ |
|||
$("#is_status1").attr(\'checked\', \'checked\'); |
|||
} else { |
|||
$("#is_status2").attr(\'checked\', \'checked\'); |
|||
} |
|||
$("textarea[name=\'remark\']").text(result.data.remark); |
|||
toastr.success(result.msg); |
|||
} |
|||
} |
|||
}; |
|||
$.ajax(config) |
|||
}) |
|||
}) |
|||
</script>'; |
|||
return $js; |
|||
} |
|||
|
|||
// 编辑页额外JS |
|||
private function getEditExtraJs() |
|||
{ |
|||
$js = '<script type="text/javascript"> |
|||
$(function () { |
|||
// 添加默认隐藏预览按钮 |
|||
if($("select[name=\'table_type\']").val() != "1"){ |
|||
$("input[name=\'right_button[]\']").each(function(){ |
|||
var value = $(this).val(); |
|||
if(value == \'preview\'){ |
|||
$(this).parent(\'.dd_radio_lable\').hide(); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
// 切换表类型为CMS时显示预览按钮 |
|||
$("select[name=\'table_type\']").change(function(){ |
|||
var value = $(this).val(); |
|||
if(value == \'1\'){ |
|||
$("input[name=\'right_button[]\']").each(function(){ |
|||
if($(this).val() == \'preview\'){ |
|||
//$(this).attr("checked",true); |
|||
$(this).parent(\'.dd_radio_lable\').show(); |
|||
} |
|||
}); |
|||
} else { |
|||
$("input[name=\'right_button[]\']").each(function(){ |
|||
if($(this).val() == \'preview\'){ |
|||
$(this).attr("checked",false); |
|||
$(this).parent(\'.dd_radio_lable\').hide(); |
|||
} |
|||
}); |
|||
} |
|||
}) |
|||
}) |
|||
</script>'; |
|||
return $js; |
|||
} |
|||
} |
|||
@ -0,0 +1,47 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 单页模块控制器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2021/06/23 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\controller; |
|||
|
|||
// 引入框架内置类 |
|||
use think\facade\Request; |
|||
|
|||
// 引入表格和表单构建器 |
|||
use app\common\facade\MakeBuilder; |
|||
use app\common\builder\FormBuilder; |
|||
use app\common\builder\TableBuilder; |
|||
|
|||
class Page extends Base |
|||
{ |
|||
// 验证器 |
|||
protected $validate = 'Page'; |
|||
|
|||
// 当前主表 |
|||
protected $tableName = 'page'; |
|||
|
|||
// 当前主模型 |
|||
protected $modelName = 'Page'; |
|||
|
|||
} |
|||
@ -0,0 +1,47 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 图片模块控制器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2021/06/23 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\controller; |
|||
|
|||
// 引入框架内置类 |
|||
use think\facade\Request; |
|||
|
|||
// 引入表格和表单构建器 |
|||
use app\common\facade\MakeBuilder; |
|||
use app\common\builder\FormBuilder; |
|||
use app\common\builder\TableBuilder; |
|||
|
|||
class Picture extends Base |
|||
{ |
|||
// 验证器 |
|||
protected $validate = 'Picture'; |
|||
|
|||
// 当前主表 |
|||
protected $tableName = 'picture'; |
|||
|
|||
// 当前主模型 |
|||
protected $modelName = 'Picture'; |
|||
|
|||
} |
|||
@ -0,0 +1,374 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 插件管理控制器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | QQ: 407593529 |
|||
* '::::::::::::' | DATETIME: 2020/03/11 |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\controller; |
|||
|
|||
use think\facade\Request; |
|||
use think\facade\View; |
|||
|
|||
// 表单和表格构建器 |
|||
use app\common\builder\FormBuilder; |
|||
use app\common\builder\TableBuilder; |
|||
// 插件服务 |
|||
use app\admin\facade\ThinkAddons; |
|||
|
|||
class Plugin extends Base |
|||
{ |
|||
// 列表 |
|||
public function index() |
|||
{ |
|||
// 搜索 |
|||
if (Request::param('getList') == 1) { |
|||
// 获取插件列表 |
|||
$list = ThinkAddons::localAddons(); |
|||
// 渲染输出 |
|||
$result = [ |
|||
'total' => count($list), |
|||
'per_page' => 1000, |
|||
'current_page' => 1, |
|||
'last_page' => 1, |
|||
'data' => $list, |
|||
]; |
|||
return $result; |
|||
} |
|||
|
|||
return TableBuilder::getInstance() |
|||
->addColumns([ // 批量添加列 |
|||
['name', '编号'], |
|||
['title', '插件名称'], |
|||
['description', '插件介绍'], |
|||
['status', '状态(启用/禁用)', 'status', '0',[ |
|||
['0' => '禁用'], |
|||
['1' => '启用'] |
|||
]], |
|||
['author', '作者'], |
|||
['version', '版本'], |
|||
['button', '操作', 'text'] |
|||
]) |
|||
->setUniqueId('name') |
|||
//->addRightButton('edit', ['title' => '配置']) |
|||
->setEditUrl(url('config', ['name' => '__id__'])) |
|||
->setExtraJs($this->makeExtraJs()) |
|||
->fetch(); |
|||
} |
|||
|
|||
// 插件配置信息预览 |
|||
public function config(string $name) |
|||
{ |
|||
$config = ThinkAddons::config($name); |
|||
// 如果插件自带配置模版的话加载插件自带的,否则调用表单构建器 |
|||
$file = app()->getRootPath() . 'addons' . DIRECTORY_SEPARATOR . $name . DIRECTORY_SEPARATOR . 'config.html'; |
|||
if (file_exists($file)) { |
|||
View::assign([ |
|||
'config' => $config |
|||
]); |
|||
return View::fetch($file); |
|||
} else { |
|||
// 获取字段数据 |
|||
$columns = $this->makeAddColumns($config); |
|||
// 判断是否分组 |
|||
$group = ThinkAddons::checkConfigGroup($config); |
|||
// 构建页面 |
|||
$builder = FormBuilder::getInstance(); |
|||
$builder->setFormUrl(url('configSave')) |
|||
->addHidden('id', $name); |
|||
$group ? $builder->addGroup($columns) : $builder->addFormItems($columns); |
|||
return $builder->fetch(); |
|||
} |
|||
} |
|||
|
|||
// 插件配置信息保存 |
|||
public function configSave() |
|||
{ |
|||
if (Request::isPost()) { |
|||
$result = ThinkAddons::configPost(Request::except(['file'], 'post')); |
|||
if ($result['code'] == 1) { |
|||
$this->success($result['msg'], 'index'); |
|||
} else { |
|||
$this->error($result['msg']); |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 更改插件状态 [启用/禁用] |
|||
public function state(string $id) |
|||
{ |
|||
return ThinkAddons::state($id); |
|||
} |
|||
|
|||
// 安装插件 |
|||
public function install(string $id) |
|||
{ |
|||
return ThinkAddons::install($id); |
|||
} |
|||
|
|||
// 卸载插件 |
|||
public function uninstall(string $id) |
|||
{ |
|||
return ThinkAddons::uninstall($id); |
|||
} |
|||
|
|||
// ========================================= |
|||
|
|||
// 生成表单信息 |
|||
private function makeAddColumns(array $config) |
|||
{ |
|||
// 判断是否开启了分组 |
|||
if (ThinkAddons::checkConfigGroup($config) === false) { |
|||
// 未开启分组 |
|||
return $this->makeAddColumnsArr($config); |
|||
} else { |
|||
$columns = []; |
|||
// 开启分组 |
|||
foreach ($config as $k => $v) { |
|||
$columns[$k] = $this->makeAddColumnsArr($v); |
|||
} |
|||
return $columns; |
|||
} |
|||
} |
|||
|
|||
// 生成表单返回数组 |
|||
private function makeAddColumnsArr(array $config) |
|||
{ |
|||
$columns = []; |
|||
foreach ($config as $k => $field) { |
|||
// 初始化 |
|||
$field['name'] = $field['name'] ?? $field['title']; |
|||
$field['field'] = $k; |
|||
$field['tips'] = $field['tips'] ?? ''; |
|||
$field['required'] = $field['required'] ?? 0; |
|||
$field['group'] = $field['group'] ?? ''; |
|||
if (!isset($field['setup'])) { |
|||
$field['setup'] = [ |
|||
'default' => $field['value'] ?? '', |
|||
'extra_attr' => $field['extra_attr'] ?? '', |
|||
'extra_attr' => $field['extra_attr'] ?? '', |
|||
'extra_class' => $field['extra_class'] ?? '', |
|||
'placeholder' => $field['placeholder'] ?? '', |
|||
]; |
|||
} |
|||
|
|||
if ($field['type'] == 'text') { |
|||
$columns[] = [ |
|||
$field['type'], // 类型 |
|||
$field['field'], // 字段名称 |
|||
$field['name'], // 字段别名 |
|||
$field['tips'], // 提示信息 |
|||
$field['setup']['default'], // 默认值 |
|||
$field['group'], // 标签组,可以在文本框前后添加按钮或者文字 |
|||
$field['setup']['extra_attr'], // 额外属性 |
|||
$field['setup']['extra_class'],// 额外CSS |
|||
$field['setup']['placeholder'],// 占位符 |
|||
$field['required'], // 是否必填 |
|||
]; |
|||
} |
|||
elseif ($field['type'] == 'textarea' || $field['type'] == 'password') { |
|||
$columns[] = [ |
|||
$field['type'], // 类型 |
|||
$field['field'], // 字段名称 |
|||
$field['name'], // 字段别名 |
|||
$field['tips'], // 提示信息 |
|||
$field['setup']['default'], // 默认值 |
|||
$field['setup']['extra_attr'], // 额外属性 |
|||
$field['setup']['extra_class'] ?? '', // 额外CSS |
|||
$field['setup']['placeholder'] ?? '', // 占位符 |
|||
$field['required'], // 是否必填 |
|||
]; |
|||
} |
|||
elseif ($field['type'] == 'radio' || $field['type'] == 'checkbox') { |
|||
$columns[] = [ |
|||
$field['type'], // 类型 |
|||
$field['field'], // 字段名称 |
|||
$field['name'], // 字段别名 |
|||
$field['tips'], // 提示信息 |
|||
$field['options'], // 选项(数组) |
|||
$field['setup']['default'], // 默认值 |
|||
$field['setup']['extra_attr'], // 额外属性 extra_attr |
|||
'', // 额外CSS extra_class |
|||
$field['required'], // 是否必填 |
|||
]; |
|||
} |
|||
elseif ($field['type'] == 'select' || $field['type'] == 'select2' ) { |
|||
$columns[] = [ |
|||
$field['type'], // 类型 |
|||
$field['field'], // 字段名称 |
|||
$field['name'], // 字段别名 |
|||
$field['tips'], // 提示信息 |
|||
$field['options'], // 选项(数组) |
|||
$field['setup']['default'], // 默认值 |
|||
$field['setup']['extra_attr'], // 额外属性 |
|||
$field['setup']['extra_class'] ?? '', // 额外CSS |
|||
$field['setup']['placeholder'] ?? '', // 占位符 |
|||
$field['required'], // 是否必填 |
|||
]; |
|||
} |
|||
elseif ($field['type'] == 'number') { |
|||
$columns[] = [ |
|||
$field['type'], // 类型 |
|||
$field['field'], // 字段名称 |
|||
$field['name'], // 字段别名 |
|||
$field['tips'], // 提示信息 |
|||
$field['setup']['default'], // 默认值 |
|||
'', // 最小值 |
|||
'', // 最大值 |
|||
$field['setup']['step'], // 步进值 |
|||
$field['setup']['extra_attr'], // 额外属性 |
|||
$field['setup']['extra_class'], // 额外CSS |
|||
$field['setup']['placeholder'] ?? '', // 占位符 |
|||
$field['required'], // 是否必填 |
|||
]; |
|||
} |
|||
elseif ($field['type'] == 'hidden') { |
|||
$columns[] = [ |
|||
$field['type'], // 类型 |
|||
$field['field'], // 字段名称 |
|||
$field['setup']['default'] ?? '', // 默认值 |
|||
$field['setup']['extra_attr'] ?? '', // 额外属性 extra_attr |
|||
]; |
|||
} |
|||
elseif ($field['type'] == 'date' || $field['type'] == 'time' || $field['type'] == 'datetime') { |
|||
// 使用每个字段设定的格式 |
|||
if ($field['type'] == 'time') { |
|||
$field['setup']['format'] = str_replace("HH", "h", $field['setup']['format']); |
|||
$field['setup']['format'] = str_replace("mm", "i", $field['setup']['format']); |
|||
$field['setup']['format'] = str_replace("ss", "s", $field['setup']['format']); |
|||
$format = $field['setup']['format'] ?? 'H:i:s'; |
|||
} else { |
|||
$field['setup']['format'] = str_replace("yyyy", "Y", $field['setup']['format']); |
|||
$field['setup']['format'] = str_replace("mm", "m", $field['setup']['format']); |
|||
$field['setup']['format'] = str_replace("dd", "d", $field['setup']['format']); |
|||
$field['setup']['format'] = str_replace("hh", "h", $field['setup']['format']); |
|||
$field['setup']['format'] = str_replace("ii", "i", $field['setup']['format']); |
|||
$field['setup']['format'] = str_replace("ss", "s", $field['setup']['format']); |
|||
$format = $field['setup']['format'] ?? 'Y-m-d H:i:s'; |
|||
} |
|||
$field['setup']['default'] = $field['setup']['default'] > 0 ? date($format, $field['setup']['default']) : ''; |
|||
$columns[] = [ |
|||
$field['type'], // 类型 |
|||
$field['field'], // 字段名称 |
|||
$field['name'], // 字段别名 |
|||
$field['tips'], // 提示信息 |
|||
$field['setup']['default'], // 默认值 |
|||
$field['setup']['format'], // 日期格式 |
|||
$field['setup']['extra_attr'], // 额外属性 extra_attr |
|||
'', // 额外CSS extra_class |
|||
$field['setup']['placeholder'],// 占位符 |
|||
$field['required'], // 是否必填 |
|||
]; |
|||
} |
|||
elseif ($field['type'] == 'daterange') { |
|||
$columns[] = [ |
|||
$field['type'], // 类型 |
|||
$field['field'], // 字段名称 |
|||
$field['name'], // 字段别名 |
|||
$field['tips'], // 提示信息 |
|||
$field['setup']['default'], // 默认值 |
|||
$field['setup']['format'], // 日期格式 |
|||
$field['setup']['extra_attr'] ?? '', // 额外属性 |
|||
$field['setup']['extra_class'] ?? '', // 额外CSS |
|||
$field['required'], // 是否必填 |
|||
]; |
|||
} |
|||
elseif ($field['type'] == 'tag') { |
|||
$columns[] = [ |
|||
$field['type'], // 类型 |
|||
$field['field'], // 字段名称 |
|||
$field['name'], // 字段别名 |
|||
$field['tips'], // 提示信息 |
|||
$field['setup']['default'], // 默认值 |
|||
$field['setup']['extra_attr'] ?? '', // 额外属性 |
|||
$field['setup']['extra_class'] ?? '', // 额外CSS |
|||
$field['required'], // 是否必填 |
|||
]; |
|||
} |
|||
elseif ($field['type'] == 'image' || $field['type'] == 'images' || $field['type'] == 'file' || $field['type'] == 'files') { |
|||
$columns[] = [ |
|||
$field['type'], // 类型 |
|||
$field['field'], // 字段名称 |
|||
$field['name'], // 字段别名 |
|||
$field['tips'], // 提示信息 |
|||
$field['setup']['default'], // 默认值 |
|||
$field['setup']['size'], // 限制大小(单位kb) |
|||
$field['setup']['ext'], // 文件后缀 |
|||
$field['setup']['extra_attr'] ?? '', // 额外属性 |
|||
$field['setup']['extra_class'] ?? '', // 额外CSS |
|||
$field['setup']['placeholder'] ?? '', // 占位符 |
|||
$field['required'], // 是否必填 |
|||
]; |
|||
} |
|||
elseif ($field['type'] == 'editor') { |
|||
$columns[] = [ |
|||
$field['type'], // 类型 |
|||
$field['field'], // 字段名称 |
|||
$field['name'], // 字段别名 |
|||
$field['tips'], // 提示信息 |
|||
$field['setup']['default'], // 默认值 |
|||
$field['setup']['heidht'] ?? 0, // 高度 |
|||
$field['setup']['extra_attr'] ?? '', // 额外属性 |
|||
$field['setup']['extra_class'] ?? '', // 额外CSS |
|||
$field['required'], // 是否必填 |
|||
]; |
|||
} |
|||
elseif ($field['type'] == 'color') { |
|||
$columns[] = [ |
|||
$field['type'], // 类型 |
|||
$field['field'], // 字段名称 |
|||
$field['name'], // 字段别名 |
|||
$field['tips'], // 提示信息 |
|||
$field['setup']['default'], // 默认值 |
|||
$field['setup']['extra_attr'] ?? '', // 额外属性 |
|||
$field['setup']['extra_class'] ?? '', // 额外CSS |
|||
$field['setup']['placeholder'] ?? '', // 占位符 |
|||
$field['required'], // 是否必填 |
|||
]; |
|||
} |
|||
} |
|||
return $columns; |
|||
} |
|||
|
|||
// 生成列表页额外JS |
|||
private function makeExtraJs() |
|||
{ |
|||
$js = '<script type="text/javascript"> |
|||
// 安装 |
|||
$.operate.pluginInstall = function(id) { |
|||
var url = \''.url('install').'\'; |
|||
$.modal.confirm("确认要安装?", function () { |
|||
var data = {"id": id}; |
|||
$.operate.submit(url, "post", "json", data); |
|||
}); |
|||
} |
|||
// 卸载 |
|||
$.operate.pluginUninstall = function(id) { |
|||
var url = \''.url('uninstall').'\'; |
|||
$.modal.confirm("确认要卸载?", function () { |
|||
var data = {"id": id}; |
|||
$.operate.submit(url, "post", "json", data); |
|||
}); |
|||
} |
|||
</script>'; |
|||
return $js; |
|||
} |
|||
} |
|||
@ -0,0 +1,47 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 产品模块控制器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2021/06/23 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\controller; |
|||
|
|||
// 引入框架内置类 |
|||
use think\facade\Request; |
|||
|
|||
// 引入表格和表单构建器 |
|||
use app\common\facade\MakeBuilder; |
|||
use app\common\builder\FormBuilder; |
|||
use app\common\builder\TableBuilder; |
|||
|
|||
class Product extends Base |
|||
{ |
|||
// 验证器 |
|||
protected $validate = 'Product'; |
|||
|
|||
// 当前主表 |
|||
protected $tableName = 'product'; |
|||
|
|||
// 当前主模型 |
|||
protected $modelName = 'Product'; |
|||
|
|||
} |
|||
@ -0,0 +1,47 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 系统设置控制器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2021/06/23 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\controller; |
|||
|
|||
// 引入框架内置类 |
|||
use think\facade\Request; |
|||
|
|||
// 引入表格和表单构建器 |
|||
use app\common\facade\MakeBuilder; |
|||
use app\common\builder\FormBuilder; |
|||
use app\common\builder\TableBuilder; |
|||
|
|||
class System extends Base |
|||
{ |
|||
// 验证器 |
|||
protected $validate = 'System'; |
|||
|
|||
// 当前主表 |
|||
protected $tableName = 'system'; |
|||
|
|||
// 当前主模型 |
|||
protected $modelName = 'System'; |
|||
|
|||
} |
|||
@ -0,0 +1,47 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 团队模块控制器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2021/06/23 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\controller; |
|||
|
|||
// 引入框架内置类 |
|||
use think\facade\Request; |
|||
|
|||
// 引入表格和表单构建器 |
|||
use app\common\facade\MakeBuilder; |
|||
use app\common\builder\FormBuilder; |
|||
use app\common\builder\TableBuilder; |
|||
|
|||
class Team extends Base |
|||
{ |
|||
// 验证器 |
|||
protected $validate = 'Team'; |
|||
|
|||
// 当前主表 |
|||
protected $tableName = 'team'; |
|||
|
|||
// 当前主模型 |
|||
protected $modelName = 'Team'; |
|||
|
|||
} |
|||
@ -0,0 +1,417 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 模板控制器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | QQ: 407593529 |
|||
* '::::::::::::' | DATETIME: 2019/03/06 |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
|
|||
namespace app\admin\controller; |
|||
|
|||
use think\facade\Request; |
|||
use think\facade\View; |
|||
|
|||
// 引入表格和表单构建器 |
|||
use app\common\builder\TableBuilder; |
|||
use app\common\builder\FormBuilder; |
|||
|
|||
class Template extends Base |
|||
{ |
|||
protected $public, $template_path, $template_html, $template_css, $template_js, $template_img, $upload_path; |
|||
|
|||
// 默认开启备份功能 |
|||
protected $templateOpening = true; |
|||
|
|||
function initialize() |
|||
{ |
|||
parent::initialize(); |
|||
// 查找所有系统设置表数据 |
|||
$system = \app\common\model\System::find(1); |
|||
$this->public = '/template/' . |
|||
$system['template'] . |
|||
'/' . |
|||
'index' . |
|||
'/'; |
|||
$this->template_path = |
|||
'.' . $this->public; |
|||
$this->template_html = $system['html']; |
|||
$this->template_css = 'css'; |
|||
$this->template_js = 'js'; |
|||
$this->template_img = 'img'; |
|||
|
|||
$initialize = [ |
|||
'html' => $this->template_html, // 自定义html目录 |
|||
'css' => $this->template_css, // 自定义css目录 |
|||
'js' => $this->template_js, // 自定义js目录 |
|||
'img' => $this->template_img, // 自定义媒体文件目录 |
|||
]; |
|||
View::assign($initialize); |
|||
|
|||
// 查找是否开启了模板修改备份功能 |
|||
$this->templateOpening = $system['template_opening']; |
|||
} |
|||
|
|||
// 列表 |
|||
public function index(string $type = 'html') |
|||
{ |
|||
if ($type == 'html') { |
|||
$path = $this->template_path . $this->template_html . DIRECTORY_SEPARATOR; |
|||
} else { |
|||
$path = $this->template_path . $type . DIRECTORY_SEPARATOR; |
|||
} |
|||
|
|||
// 设置主键 |
|||
$pk = 'id'; |
|||
// 字段信息 |
|||
$columns = [ |
|||
['id', '文件名称'], |
|||
['filepath', '目录'], |
|||
['filesize', '文件大小'], |
|||
['filemtime', '更新时间', '', '', '', '', 'true'], |
|||
['ext', '后缀'], |
|||
]; |
|||
$files = dir_list($path, $type); |
|||
$list = []; |
|||
foreach ($files as $key => $file) { |
|||
$filename = basename($file); |
|||
//$list[$key]['value'] = substr($filename, 0, strrpos($filename, '.')); |
|||
$list[$key]['id'] = $filename; |
|||
$list[$key]['filepath'] = $file; |
|||
$list[$key]['filesize'] = format_bytes(filesize($file)); |
|||
$list[$key]['filemtime'] = date('Y-m-d H:i:s', filemtime($file)); |
|||
$list[$key]['ext'] = strtolower(substr($filename, strrpos($filename, '.') - strlen($filename))); |
|||
} |
|||
// 搜索 |
|||
if (Request::param('getList') == 1) { |
|||
// 排序规则 |
|||
$orderByColumn = Request::param('orderByColumn') ?? $pk; |
|||
$isAsc = Request::param('isAsc') ?? 'desc'; |
|||
$isAsc = $isAsc == 'desc' ? SORT_DESC : SORT_ASC; |
|||
// 排序处理 |
|||
$date = array_column($list, $orderByColumn); |
|||
array_multisort($date, $isAsc, $list); |
|||
// 渲染输出 |
|||
$result = [ |
|||
'total' => count($list), |
|||
'per_page' => 1000, |
|||
'current_page' => 1, |
|||
'last_page' => 1, |
|||
'data' => $list, |
|||
]; |
|||
return $result; |
|||
} |
|||
|
|||
// 获取头部切换按钮 |
|||
$pageTips = $this->getPageTips($type); |
|||
|
|||
// 构建页面 |
|||
return TableBuilder::getInstance() |
|||
->setUniqueId($pk) // 设置主键 |
|||
->addColumns($columns) // 添加列表字段数据 |
|||
->setPageTips($pageTips, 'success', 'search') // 提示信息 |
|||
->setPagination('false') // 关闭分页显示 |
|||
->addColumn('right_button', '操作', 'btn') |
|||
->addRightButton('edit', ['href' => (string)url('edit', ['id' => '__id__', 'type' => $type])]) |
|||
->addRightButton('delete') |
|||
->addTopButtons(['add', 'edit', 'del']) // 设置顶部按钮组 |
|||
->setEditUrl((string)url('edit', ['id' => '__id__', 'type' => $type])) |
|||
->setDelUrl((string)url('del', ['id' => '__id__', 'type' => $type])) |
|||
->setDataUrl(url('index', ['getList' => '1', 'type' => $type])) |
|||
->fetch(); |
|||
} |
|||
|
|||
// 添加 |
|||
public function add() |
|||
{ |
|||
// 默认文件类型 |
|||
$type = Request::param('type', 'html'); |
|||
// 文件类型数组 |
|||
$fileType = ['html' => 'HTML', 'css' => 'CSS', 'js' => 'JS']; |
|||
// 构建页面 |
|||
return FormBuilder::getInstance() |
|||
->addFormItems([ |
|||
['text', 'filename', '文件名称', '不需要输入文件后缀,如 style.css 请填写style', '', [], '', '', '', true], |
|||
['radio', 'type', '文件类型', '', $fileType, $type, '', '', true], |
|||
['code', 'content', '内容', '', '', '', '', '', false, $type], |
|||
]) |
|||
->fetch(); |
|||
} |
|||
|
|||
// 添加保存 |
|||
public function addPost() |
|||
{ |
|||
if (Request::isPost()) { |
|||
$filename = $this->checkFilename(Request::post('filename')); |
|||
$type = $this->checkFiletype(Request::param('type', 'html')); |
|||
if (empty($filename)) { |
|||
$this->error('文件名称不可以为空'); |
|||
} |
|||
if ($type == 'html') { |
|||
$path = $this->template_path . $this->template_html . '/'; |
|||
} else { |
|||
$path = $this->template_path . $type . '/'; |
|||
} |
|||
$file = $path . $filename . '.' . $type; |
|||
if (file_exists($file)) { |
|||
$this->error('文件已经存在!'); |
|||
} else { |
|||
try { |
|||
file_put_contents($file, stripslashes(input('post.content'))); |
|||
} catch (\Exception $e) { |
|||
$this->error($e->getMessage()); |
|||
} |
|||
$this->success('添加成功!', url('index', ['type' => $type])); |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 修改 |
|||
public function edit(string $id) |
|||
{ |
|||
$id = $this->checkFilename($id); |
|||
// 默认文件类型 |
|||
$type = $this->checkFiletype(Request::param('type', 'html')); |
|||
// 文件类型数组 |
|||
$fileType = ['html' => 'HTML', 'css' => 'CSS', 'js' => 'JS']; |
|||
if ($type == 'html') { |
|||
$path = $this->template_path . $this->template_html . '/'; |
|||
} else { |
|||
$path = $this->template_path . $type . '/'; |
|||
} |
|||
$file = $path . $id; |
|||
if (file_exists($file)) { |
|||
$file = iconv('gb2312', 'utf-8', $file); |
|||
$content = file_get_contents($file); |
|||
$info = [ |
|||
'filename' => $id, |
|||
'file' => $file, |
|||
'content' => $content, |
|||
'type' => $type |
|||
]; |
|||
} else { |
|||
$this->error('文件不存在!'); |
|||
} |
|||
|
|||
// 构建页面 |
|||
return FormBuilder::getInstance() |
|||
->addFormItems([ |
|||
['text', 'filename', '文件名称', '不需要输入文件后缀,如 style.css 请填写style', $info['filename'], [], 'readonly', '', '', true], |
|||
['radio', 'type', '文件类型', '', $fileType, $info['type'], '', '', true], |
|||
['code', 'content', '内容', '', $info['content'], '', '', '', false, $type], |
|||
['hidden', 'file', $info['file']] |
|||
]) |
|||
->fetch(); |
|||
} |
|||
|
|||
// 修改保存 |
|||
public function editPost() |
|||
{ |
|||
if (Request::isPost()) { |
|||
$filename = $this->checkFilename(Request::post('filename')); |
|||
$type = $this->checkFiletype(Request::param('type', 'html')); |
|||
if (empty($filename)) { |
|||
$this->error('文件名称不可以为空'); |
|||
} |
|||
if ($type == 'html') { |
|||
$path = $this->template_path . $this->template_html . '/'; |
|||
} else { |
|||
$path = $this->template_path . $type . '/'; |
|||
} |
|||
$file = $path . $filename; |
|||
if (file_exists($file)) { |
|||
// 判断是否有写入权限 |
|||
if (!is_writable($file)) { |
|||
$this->error('无写入权限!'); |
|||
} |
|||
|
|||
// 备份文件(防止出错) |
|||
if ($this->templateOpening) { |
|||
// 设置备份文件名 |
|||
$newFile = $path . str_replace('.', '_back-' . date("Y-m-d_H-i-s") . '.', $filename); |
|||
// 执行复制操作 |
|||
copy($file, $newFile); |
|||
} |
|||
|
|||
if (false !== file_put_contents($file, stripslashes(input('content')))) { |
|||
$this->success('修改成功!', url('index', ['type' => $type])); |
|||
} else { |
|||
$this->error('修改失败!'); |
|||
} |
|||
} else { |
|||
$this->error('文件不存在!'); |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 删除 |
|||
public function del(string $id, string $type = 'html') |
|||
{ |
|||
$id = $this->checkFilename($id); |
|||
$type = $this->checkFiletype($type); |
|||
if (strpos($id, ',') !== false) { |
|||
return $this->selectDel($id, $type); |
|||
} |
|||
//删除文件 |
|||
if ($type == 'html') { |
|||
$path = $this->template_path . $this->template_html . '/'; |
|||
} else { |
|||
$path = $this->template_path . $type . '/'; |
|||
} |
|||
$file = $path . $id; |
|||
if (file_exists($file)) { |
|||
unlink($file); |
|||
return ['error' => 0, 'msg' => '删除成功!']; |
|||
} else { |
|||
return ['error' => 1, 'msg' => '删除失败!']; |
|||
} |
|||
} |
|||
|
|||
// 批量删除 |
|||
public function selectDel(string $id, string $type = 'html') |
|||
{ |
|||
$type = $this->checkFiletype($type); |
|||
if (Request::isPost()) { |
|||
$ids = explode(',', $id); |
|||
if ($type == 'html') { |
|||
$path = $this->template_path . $this->template_html . '/'; |
|||
} else { |
|||
$path = $this->template_path . $type . '/'; |
|||
} |
|||
foreach ($ids as $k => $v) { |
|||
$v = $this->checkFilename($v); |
|||
//删除文件 |
|||
$file = $path . $v; |
|||
if (file_exists($file)) { |
|||
unlink($file); |
|||
} |
|||
} |
|||
return ['error' => 0, 'msg' => '删除成功!']; |
|||
} |
|||
} |
|||
|
|||
// 媒体文件 |
|||
public function img() |
|||
{ |
|||
$path = $this->template_path . $this->template_img . '/' . Request::param('folder'); |
|||
$folder = Request::param('folder', ''); |
|||
$uppath = explode('/', Request::param('folder')); |
|||
$leve = count($uppath) - 1; |
|||
unset($uppath[$leve]); |
|||
if ($leve > 1) { |
|||
unset($uppath[$leve - 1]); |
|||
$uppath = implode('/', $uppath) . '/'; |
|||
} else { |
|||
$uppath = ''; |
|||
} |
|||
|
|||
$files = glob($path . '*'); |
|||
$folders = $templates = array(); |
|||
foreach ($files as $key => $file) { |
|||
$filename = basename($file); |
|||
if (is_dir($file)) { |
|||
$folders[$key]['filename'] = $filename; |
|||
$folders[$key]['filepath'] = $file; |
|||
$folders[$key]['ext'] = 'folder'; |
|||
} else { |
|||
$templates[$key]['filename'] = $filename; |
|||
$templates[$key]['filepath'] = ltrim($file, '.'); |
|||
$templates[$key]['ext'] = strtolower(substr($filename, strrpos($filename, '.') - strlen($filename) + 1)); |
|||
if (!in_array($templates[$key]['ext'], array('gif', 'jpg', 'png', 'bmp'))) { |
|||
$templates[$key]['ico'] = 1; |
|||
} |
|||
} |
|||
} |
|||
$view = [ |
|||
'folder' => $folder, |
|||
'leve' => $leve, |
|||
'uppath' => $uppath, |
|||
'path' => $path, //路径 |
|||
'folders' => $folders, //文件夹 |
|||
'files' => $templates, //文件 |
|||
'type' => $this->template_img, //当前显示的类型 |
|||
]; |
|||
View::assign($view); |
|||
return View::fetch(); |
|||
} |
|||
|
|||
// 媒体文件删除 |
|||
public function imgDel() |
|||
{ |
|||
$folder = str_replace("..", "", Request::param('folder')); |
|||
$path = $this->template_path . $this->template_img . '/' . $folder; |
|||
$file = $path . $this->checkFilename(Request::post('filename')); |
|||
|
|||
if (file_exists($file)) { |
|||
is_dir($file) ? dir_delete($file) : unlink($file); |
|||
return json(['error' => 0, 'msg' => '删除成功!']); |
|||
} else { |
|||
return json(['error' => 1, 'msg' => '文件不存在!']); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 获取头部切换按钮 |
|||
* @param string $type |
|||
* @return string |
|||
*/ |
|||
private function getPageTips(string $type) |
|||
{ |
|||
$html = $type == 'html' ? 'btn-info' : 'btn-primary'; |
|||
$css = $type == 'css' ? 'btn-info' : 'btn-primary'; |
|||
$js = $type == 'js' ? 'btn-info' : 'btn-primary'; |
|||
$img = $type == 'img' ? 'btn-info' : 'btn-primary'; |
|||
|
|||
$link = [ |
|||
'html' => url('index', ['type' => 'html']), |
|||
'css' => url('index', ['type' => 'css']), |
|||
'js' => url('index', ['type' => 'js']), |
|||
'img' => url('img', ['type' => 'img']), |
|||
]; |
|||
$pageTips = ' |
|||
<a class="btn btn-flat m-r-5 ' . $html . '" href="' . $link['html'] . '">html</a> |
|||
<a class="btn btn-flat m-r-5 ' . $css . '" href="' . $link['css'] . '">css</a> |
|||
<a class="btn btn-flat m-r-5 ' . $js . '" href="' . $link['js'] . '">js</a> |
|||
<a class="btn btn-flat m-r-5 ' . $img . '" href="' . $link['img'] . '">媒体文件</a> |
|||
'; |
|||
return $pageTips; |
|||
} |
|||
|
|||
// 过滤文件名 |
|||
private function checkFilename(string $fileName) |
|||
{ |
|||
$fileName = str_replace("/", "", $fileName); |
|||
$fileName = str_replace("..", "", $fileName); |
|||
$fileName = str_ireplace(".php", ".html", $fileName); |
|||
$fileName = str_ireplace(".asp", ".html", $fileName); |
|||
return $fileName; |
|||
} |
|||
|
|||
// 过滤文件类型 |
|||
private function checkFiletype(string $fileType) |
|||
{ |
|||
$arr = ['html', 'css', 'js']; |
|||
if (!in_array(strtolower($fileType), $arr)) { |
|||
return 'html'; |
|||
} else { |
|||
return $fileType; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,815 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 上传控制器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | QQ: 407593529 |
|||
* '::::::::::::' | DATETIME: 2019/04/03 |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\controller; |
|||
|
|||
use think\App; |
|||
use think\facade\Request; |
|||
|
|||
class Upload extends Base |
|||
{ |
|||
|
|||
// 上传方式 [chunk 大文件分片上传, tp 沿用TP上传] |
|||
private $uploadType = ""; |
|||
|
|||
// 上传验证规则 |
|||
protected $uploadValidate = []; |
|||
|
|||
// 构造方法 |
|||
public function __construct(App $app) |
|||
{ |
|||
parent::__construct($app); |
|||
// 默认上传方式 |
|||
$this->uploadType = "chunk"; |
|||
|
|||
// 验证规则 |
|||
$this->uploadValidate = [ |
|||
'file' => $this->uploadVal() |
|||
]; |
|||
} |
|||
|
|||
// 上传文件 |
|||
public function index() |
|||
{ |
|||
if (Request::param('from') == 'ckeditor') { |
|||
// 获取上传文件表单字段名 |
|||
$fileKey = array_keys(request()->file()); |
|||
$path = []; |
|||
for ($i = 0; $i < count($fileKey); $i++) { |
|||
// 获取表单上传文件并执行上传操作 |
|||
$uploadFile = $this->uploadFile($fileKey[$i]); |
|||
if ($uploadFile['code'] == 1) { |
|||
$path[] = $uploadFile['url']; |
|||
} else { |
|||
$path = []; |
|||
$error = $uploadFile['msg']; |
|||
} |
|||
} |
|||
|
|||
if ($path) { |
|||
$result['uploaded'] = true; |
|||
// 分辨是否截图上传,截图上传只能上传一个,非截图上传可以上传多个 |
|||
if (Request::param('responseType') == 'json') { |
|||
$result["url"] = $path[0]; |
|||
} else { |
|||
$result["url"] = $path; |
|||
} |
|||
return json($result); |
|||
} else { |
|||
// 上传失败 |
|||
$result['uploaded'] = false; |
|||
$result['url'] = ''; |
|||
$result['message'] = $error; |
|||
return json($result); |
|||
} |
|||
} else if ((Request::param('from') == 'ueditor')) { |
|||
return $this->ueIndex(); |
|||
} else { |
|||
if ($this->uploadType == 'tp') { |
|||
// webupload [file是webloader固定写入的隐藏文本名称] |
|||
return json($this->uploadFile('file')); |
|||
} else { |
|||
return json($this->bigUpload()); |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 上传验证规则 |
|||
private function uploadVal() |
|||
{ |
|||
$file = []; |
|||
if (Request::param('upload_type') == 'file' || Request::param('action') == 'upload_video' | Request::param('action') == 'upload_file') { |
|||
// 文件限制 |
|||
if ($this->system['upload_file_ext']) { |
|||
$file['fileExt'] = $this->removeExt($this->system['upload_file_ext']); |
|||
} else { |
|||
$file['fileExt'] = 'rar,zip,avi,rmvb,3gp,flv,mp3,mp4,txt,doc,xls,ppt,pdf,xls,docx,xlsx,doc'; |
|||
} |
|||
// 限制文件大小(单位b) |
|||
if ($this->system['upload_file_size']) { |
|||
$file['fileSize'] = $this->system['upload_file_size'] * 1024; |
|||
} |
|||
} else { |
|||
// 图片限制 |
|||
if ($this->system['upload_image_ext']) { |
|||
$file['fileExt'] = $this->removeExt($this->system['upload_image_ext']); |
|||
} else { |
|||
$file['fileExt'] = 'jpg,png,gif,jpeg'; |
|||
} |
|||
// 限制图片大小(单位b) |
|||
if ($this->system['upload_image_size']) { |
|||
$file['fileSize'] = $this->system['upload_image_size'] * 1024; |
|||
} |
|||
} |
|||
return $file; |
|||
} |
|||
|
|||
// tp上传文件 |
|||
private function uploadFile(string $fileName) |
|||
{ |
|||
$file = request()->file($fileName); |
|||
try { |
|||
validate($this->uploadValidate) |
|||
->check(['file' => $file]); |
|||
$savename = \think\facade\Filesystem::disk('public')->putFile('uploads', $file); |
|||
// windows系统中路径反斜杠处理 |
|||
$savename = '/' . str_replace('\\', '/', $savename); |
|||
// 上传驱动 |
|||
$savename = $this->uploadDriver($savename); |
|||
if (is_array($savename)) { |
|||
return [ |
|||
'code' => 0, |
|||
'msg' => $savename['msg'], |
|||
'url' => '', |
|||
]; |
|||
} |
|||
return [ |
|||
'code' => 1, |
|||
'msg' => '上传成功', |
|||
'url' => $savename |
|||
]; |
|||
} catch (\Exception $e) { // think\exception\ValidateException 取消验证异常捕获 |
|||
return [ |
|||
'code' => 0, |
|||
'msg' => 'ERROR:' . $e->getMessage(), |
|||
'url' => '' |
|||
]; |
|||
} |
|||
} |
|||
|
|||
// 大文件切片上传 |
|||
private function bigUpload() |
|||
{ |
|||
// 验证 |
|||
$file = request()->file('file'); |
|||
try { |
|||
validate($this->uploadValidate) |
|||
->check(['file' => $file]); |
|||
} catch (\Exception $e) { // think\exception\ValidateException 取消验证异常捕获 |
|||
return [ |
|||
'code' => 0, |
|||
'msg' => 'ERROR:' . $e->getMessage(), |
|||
'url' => '' |
|||
]; |
|||
} |
|||
|
|||
// Make sure file is not cached (as it happens for example on iOS devices) |
|||
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); |
|||
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); |
|||
header("Cache-Control: no-store, no-cache, must-revalidate"); |
|||
header("Cache-Control: post-check=0, pre-check=0", false); |
|||
header("Pragma: no-cache"); |
|||
|
|||
// 跨域支持 |
|||
// header("Access-Control-Allow-Origin: *"); |
|||
// other CORS headers if any... |
|||
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') { |
|||
exit; // finish preflight CORS requests here |
|||
} |
|||
|
|||
if (!empty($_REQUEST['debug'])) { |
|||
$random = rand(0, intval($_REQUEST['debug'])); |
|||
if ($random === 0) { |
|||
header("HTTP/1.0 500 Internal Server Error"); |
|||
exit; |
|||
} |
|||
} |
|||
|
|||
// 页面执行时间不限制 |
|||
@set_time_limit(5 * 60); |
|||
|
|||
// Uncomment this one to fake upload time |
|||
// usleep(5000); |
|||
|
|||
// Settings |
|||
// $targetDir = ini_get("upload_tmp_dir") . DIRECTORY_SEPARATOR . "plupload"; |
|||
// 设置临时上传目录 |
|||
$targetDir = public_path() . DIRECTORY_SEPARATOR . 'uploads' . DIRECTORY_SEPARATOR . 'temp'; |
|||
// 设置上传目录 |
|||
$uploadDir = public_path() . DIRECTORY_SEPARATOR . 'uploads' . DIRECTORY_SEPARATOR . date('Ymd'); |
|||
// 上传完后清空临时目录 |
|||
$cleanupTargetDir = true; |
|||
// 临时文件期限 |
|||
$maxFileAge = 5 * 3600; |
|||
|
|||
// 创建临时目录 |
|||
if (!file_exists($targetDir)) { |
|||
@mkdir($targetDir); |
|||
} |
|||
|
|||
// 创建上传目录 |
|||
if (!file_exists($uploadDir)) { |
|||
@mkdir($uploadDir); |
|||
} |
|||
|
|||
// 获取上传文件名称 |
|||
$fileName = $file->getOriginalName(); |
|||
$oldName = $fileName; |
|||
$fileName = iconv('UTF-8', 'gb2312', $fileName); |
|||
|
|||
// 临时上传完整目录信息 |
|||
$filePath = $targetDir . DIRECTORY_SEPARATOR . $fileName; |
|||
|
|||
// 定义命名规则 |
|||
$pathInfo = pathinfo($fileName); |
|||
// md5 |
|||
$fileName = md5(time() . $pathInfo['basename']) . '.' . $pathInfo['extension']; |
|||
|
|||
// 正式上传完整目录信息 |
|||
$uploadPath = $uploadDir . DIRECTORY_SEPARATOR . $fileName; |
|||
|
|||
// Chunking might be enabled |
|||
$chunk = isset($_REQUEST["chunk"]) ? intval($_REQUEST["chunk"]) : 0; |
|||
$chunks = isset($_REQUEST["chunks"]) ? intval($_REQUEST["chunks"]) : 1; |
|||
|
|||
// 清空临时目录 |
|||
if ($cleanupTargetDir) { |
|||
if (!is_dir($targetDir) || !$dir = opendir($targetDir)) { |
|||
return [ |
|||
'code' => 0, |
|||
'msg' => 'Failed to open temp directory.', |
|||
'url' => '' |
|||
]; |
|||
} |
|||
|
|||
while (($file = readdir($dir)) !== false) { |
|||
$tmpfilePath = $targetDir . DIRECTORY_SEPARATOR . $file; |
|||
|
|||
// 如果临时文件是当前文件,则转到下一个 |
|||
if ($tmpfilePath == "{$filePath}_{$chunk}.part" || $tmpfilePath == "{$filePath}_{$chunk}.parttmp") { |
|||
continue; |
|||
} |
|||
|
|||
// 如果临时文件早于最大使用期限并且不是当前文件,则将其删除 |
|||
if (preg_match('/\.(part|parttmp)$/', $file) && (@filemtime($tmpfilePath) < time() - $maxFileAge)) { |
|||
@unlink($tmpfilePath); |
|||
} |
|||
} |
|||
closedir($dir); |
|||
} |
|||
|
|||
// 打开临时文件 |
|||
if (!$out = @fopen("{$filePath}_{$chunk}.parttmp", "wb")) { |
|||
return [ |
|||
'code' => 0, |
|||
'msg' => 'Failed to open output stream.', |
|||
'url' => '' |
|||
]; |
|||
} |
|||
|
|||
if (!empty($_FILES)) { |
|||
if ($_FILES["file"]["error"] || !is_uploaded_file($_FILES["file"]["tmp_name"])) { |
|||
return [ |
|||
'code' => 0, |
|||
'msg' => 'Failed to move uploaded file.', |
|||
'url' => '' |
|||
]; |
|||
} |
|||
|
|||
// 读取二进制输入流并将其附加到临时文件 |
|||
if (!$in = @fopen($_FILES["file"]["tmp_name"], "rb")) { |
|||
return [ |
|||
'code' => 0, |
|||
'msg' => 'Failed to open input stream.', |
|||
'url' => '' |
|||
]; |
|||
} |
|||
} else { |
|||
if (!$in = @fopen("php://input", "rb")) { |
|||
return [ |
|||
'code' => 0, |
|||
'msg' => 'Failed to open input stream.', |
|||
'url' => '' |
|||
]; |
|||
} |
|||
} |
|||
|
|||
while ($buff = fread($in, 4096)) { |
|||
fwrite($out, $buff); |
|||
} |
|||
|
|||
@fclose($out); |
|||
@fclose($in); |
|||
|
|||
rename("{$filePath}_{$chunk}.parttmp", "{$filePath}_{$chunk}.part"); |
|||
|
|||
$index = 0; |
|||
$done = true; |
|||
for ($index = 0; $index < $chunks; $index++) { |
|||
if (!file_exists("{$filePath}_{$index}.part")) { |
|||
$done = false; |
|||
break; |
|||
} |
|||
} |
|||
if ($done) { |
|||
if (!$out = @fopen($uploadPath, "wb")) { |
|||
return [ |
|||
'code' => 0, |
|||
'msg' => 'Failed to open output stream.', |
|||
'url' => '' |
|||
]; |
|||
} |
|||
|
|||
if (flock($out, LOCK_EX)) { |
|||
for ($index = 0; $index < $chunks; $index++) { |
|||
if (!$in = @fopen("{$filePath}_{$index}.part", "rb")) { |
|||
break; |
|||
} |
|||
|
|||
while ($buff = fread($in, 4096)) { |
|||
fwrite($out, $buff); |
|||
} |
|||
|
|||
@fclose($in); |
|||
@unlink("{$filePath}_{$index}.part"); |
|||
} |
|||
|
|||
flock($out, LOCK_UN); |
|||
} |
|||
@fclose($out); |
|||
|
|||
// 输出 |
|||
// 移除public目录 |
|||
$uploadPath = str_replace(public_path() . DIRECTORY_SEPARATOR, '', $uploadPath); |
|||
// windows系统中路径反斜杠处理 |
|||
$uploadPath = '/' . str_replace('\\', '/', $uploadPath); |
|||
// 上传驱动 |
|||
$uploadPath = $this->uploadDriver($uploadPath); |
|||
if (is_array($uploadPath)) { |
|||
return [ |
|||
'code' => 0, |
|||
'msg' => $uploadPath['msg'], |
|||
'url' => '', |
|||
]; |
|||
} |
|||
return [ |
|||
'code' => 1, |
|||
'msg' => '上传完毕', |
|||
'url' => $uploadPath, |
|||
'title' => $_FILES["file"]['name'], |
|||
'original' => $_FILES["file"]['name'], |
|||
'state' => 'SUCCESS', |
|||
]; |
|||
|
|||
/*$response = [ |
|||
'success'=>true, |
|||
'oldName'=>$oldName, |
|||
'filePaht'=>$uploadPath, |
|||
'fileSize'=>$data['size'], |
|||
'fileSuffixes'=>$pathInfo['extension'], |
|||
'file_id'=>$data['id'], |
|||
]; |
|||
|
|||
die(json_encode($response));*/ |
|||
} |
|||
|
|||
// Return Success JSON-RPC response |
|||
die('{"jsonrpc" : "2.0", "result" : null, "id" : "id"}'); |
|||
} |
|||
|
|||
// 移除上传危险后缀 |
|||
private function removeExt(string $ext = '') |
|||
{ |
|||
$ext = strtolower($ext); |
|||
if (strpos($ext, 'php') !== false) { |
|||
$ext = str_ireplace("php", "", $ext); |
|||
return $this->removeExt($ext); |
|||
} |
|||
if (strpos($ext, 'asp') !== false) { |
|||
$ext = str_ireplace("asp", "", $ext); |
|||
return $this->removeExt($ext); |
|||
} |
|||
return $ext; |
|||
} |
|||
|
|||
// 上传驱动 |
|||
private function uploadDriver(string $fineName = '') |
|||
{ |
|||
if ($fineName) { |
|||
$uploadDriver = \app\common\model\System::where('id', 1)->value('upload_driver'); |
|||
if ($uploadDriver == '1') { |
|||
return $fineName; |
|||
} else if ($uploadDriver == '2') { |
|||
// 阿里云 |
|||
$urlArr = hook('aliyunOssHook', ['url' => $fineName]); |
|||
$urlArr = json_decode($urlArr, true); |
|||
if (isset($urlArr['error']) && $urlArr['error'] == 0) { |
|||
return $urlArr['data']; |
|||
} else { |
|||
return $urlArr; |
|||
} |
|||
} else if ($uploadDriver == '3') { |
|||
// 七牛云 |
|||
$urlArr = hook('qiniuOssHook', ['url' => $fineName]); |
|||
$urlArr = json_decode($urlArr, true); |
|||
if (isset($urlArr['error']) && $urlArr['error'] == 0) { |
|||
return $urlArr['data']; |
|||
} else { |
|||
return $urlArr; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
// ===================================Ueditor=================================== |
|||
|
|||
// 配置信息,部分信息会重新赋值,仅做参考 |
|||
private $ueConfig = [ |
|||
/* 上传图片配置项 */ |
|||
"imageActionName" => "upload_image", /* 执行上传图片的action名称 */ |
|||
"imageFieldName" => "file", /* 提交的图片表单名称 */ |
|||
"imageMaxSize" => 10485760, /* 上传大小限制,单位B 102400=100KB, 512000=500KB,1048576=1M */ |
|||
"imageAllowFiles" => [".png", ".jpg", ".jpeg", ".gif", ".bmp", ".webp"], /* 上传图片格式显示 */ |
|||
"imageCompressEnable" => true, /* 是否压缩图片,默认是true */ |
|||
"imageCompressBorder" => 1600, /* 图片压缩最长边限制 */ |
|||
"imageInsertAlign" => "none", /* 插入的图片浮动方式 */ |
|||
"imageUrlPrefix" => "", /* 图片访问路径前缀 */ |
|||
"imagePathFormat" => "", |
|||
|
|||
/* 截图工具上传 */ |
|||
"snapscreenActionName" => "upload_image", /* 执行上传截图的action名称 */ |
|||
"snapscreenPathFormat" => "", /* 上传保存路径,可以自定义保存路径和文件名格式 */ |
|||
"snapscreenUrlPrefix" => "", /* 图片访问路径前缀 */ |
|||
"snapscreenInsertAlign" => "none", /* 插入的图片浮动方式 */ |
|||
|
|||
/* 抓取远程图片配置 */ |
|||
"catcherLocalDomain" => ["127.0.0.1", "localhost", "img.baidu.com"], |
|||
"catcherActionName" => "catch_image", /* 执行抓取远程图片的action名称 */ |
|||
"catcherFieldName" => "file", /* 提交的图片列表表单名称 */ |
|||
"catcherPathFormat" => "", /* 上传保存路径,可以自定义保存路径和文件名格式 */ |
|||
"catcherUrlPrefix" => "", /* 图片访问路径前缀 */ |
|||
"catcherMaxSize" => 10485760, /* 上传大小限制,单位B 102400=100KB, 512000=500KB,1048576=1M */ |
|||
"catcherAllowFiles" => [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 抓取图片格式显示 */ |
|||
|
|||
/* 上传视频配置 */ |
|||
"videoActionName" => "upload_video", /* 执行上传视频的action名称 */ |
|||
"videoFieldName" => "file", /* 提交的视频表单名称 */ |
|||
"videoPathFormat" => "./upload/ueditor/video/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */ |
|||
"videoUrlPrefix" => "", /* 视频访问路径前缀 */ |
|||
"videoMaxSize" => 104857600, /* 上传大小限制,单位B,默认100MB */ |
|||
"videoAllowFiles" => [ |
|||
".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg", |
|||
".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid" |
|||
], /* 上传视频格式显示 */ |
|||
|
|||
/* 上传文件配置 */ |
|||
"fileActionName" => "upload_file", /* controller里,执行上传视频的action名称 */ |
|||
"fileFieldName" => "file", /* 提交的文件表单名称 */ |
|||
"filePathFormat" => "", /* 上传保存路径,可以自定义保存路径和文件名格式 */ |
|||
"fileUrlPrefix" => "", /* 文件访问路径前缀 */ |
|||
"fileMaxSize" => 51200000, /* 上传大小限制,单位B,默认50MB */ |
|||
"fileAllowFiles" => [ |
|||
".png", ".jpg", ".jpeg", ".gif", ".bmp", |
|||
".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg", |
|||
".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid", |
|||
".rar", ".zip", ".tar", ".gz", ".7z", ".bz2", ".cab", ".iso", |
|||
".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml", |
|||
], /* 上传文件格式显示 */ |
|||
|
|||
/* 列出指定目录下的图片 */ |
|||
"imageManagerActionName" => "list_image", /* 执行图片管理的action名称 */ |
|||
"imageManagerListPath" => "", /* 指定要列出图片的目录 */ |
|||
"imageManagerListSize" => 20, /* 每次列出文件数量 */ |
|||
"imageManagerUrlPrefix" => "", /* 图片访问路径前缀 */ |
|||
"imageManagerInsertAlign" => "none", /* 插入的图片浮动方式 */ |
|||
"imageManagerAllowFiles" => [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 列出的文件类型 */ |
|||
|
|||
/* 列出指定目录下的文件 */ |
|||
"fileManagerActionName" => "list_file", /* 执行文件管理的action名称 */ |
|||
"fileManagerListPath" => "", /* 指定要列出文件的目录 */ |
|||
"fileManagerUrlPrefix" => "", /* 文件访问路径前缀 */ |
|||
"fileManagerListSize" => 20, /* 每次列出文件数量 */ |
|||
"fileManagerAllowFiles" => [ |
|||
".png", ".jpg", ".jpeg", ".gif", ".bmp", |
|||
".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg", |
|||
".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid", |
|||
".rar", ".zip", ".tar", ".gz", ".7z", ".bz2", ".cab", ".iso", |
|||
".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml", |
|||
], /* 列出的文件类型 */ |
|||
]; |
|||
|
|||
// 针对ueditor的请求链接进行分发 |
|||
private function ueIndex() |
|||
{ |
|||
$action = Request::param('action', ''); |
|||
switch ($action) { |
|||
case 'config': |
|||
return json($this->ueConfig); |
|||
break; |
|||
|
|||
/* 上传图片 */ |
|||
case 'upload_image': |
|||
return json($this->bigUpload()); |
|||
break; |
|||
|
|||
/* 上传视频 */ |
|||
case 'upload_video': |
|||
return json($this->bigUpload()); |
|||
break; |
|||
|
|||
/* 上传文件 */ |
|||
case 'upload_file': |
|||
return json($this->bigUpload()); |
|||
break; |
|||
|
|||
/* 列出图片 */ |
|||
case 'list_image': |
|||
$allowFiles = $this->system['upload_image_ext']; |
|||
$listSize = $this->ueConfig['imageManagerListSize']; |
|||
$path = public_path() . 'uploads'; |
|||
$get = Request::param(); |
|||
$result = $this->fileList($allowFiles, $listSize, $path, $get); |
|||
break; |
|||
|
|||
/* 列出文件 */ |
|||
case 'list_file': |
|||
$allowFiles = $this->system['upload_file_ext']; |
|||
$listSize = $this->ueConfig['imageManagerListSize']; |
|||
$path = public_path() . 'uploads'; |
|||
$get = Request::param(); |
|||
$result = $this->fileList($allowFiles, $listSize, $path, $get); |
|||
break; |
|||
|
|||
/* 抓取远程文件 */ |
|||
case 'catch_image': |
|||
$config = [ |
|||
"maxSize" => $this->system['upload_image_size'], |
|||
"allowFiles" => $this->system['upload_image_ext'] ? explode(',', $this->system['upload_image_ext']) : [], |
|||
"oriName" => "remote.png", |
|||
]; |
|||
|
|||
/* 抓取远程图片 */ |
|||
$list = []; |
|||
$failList = []; //错误的列表 |
|||
$source = Request::param('file'); |
|||
if (empty($source)) { |
|||
return $this->error('参数错误'); |
|||
} |
|||
|
|||
foreach ($source as $imgUrl) { |
|||
$remoteResult = $this->saveRemote($config, $imgUrl); |
|||
if (is_array($remoteResult) && $remoteResult['code'] == 1) { |
|||
array_push($list, [ |
|||
"state" => $remoteResult["state"], |
|||
"url" => $remoteResult["url"], |
|||
"size" => $remoteResult["size"], |
|||
"title" => htmlspecialchars($remoteResult["title"]), |
|||
"original" => htmlspecialchars($remoteResult["original"]), |
|||
"source" => htmlspecialchars($imgUrl), |
|||
]); |
|||
} else { |
|||
array_push($failList, [ |
|||
"state" => 'ERROR', |
|||
"source" => htmlspecialchars($imgUrl), |
|||
]); |
|||
} |
|||
} |
|||
|
|||
$result = [ |
|||
'state' => count($list) ? 'SUCCESS' : 'ERROR', |
|||
'list' => $list, |
|||
'fail_list' => $failList, |
|||
]; |
|||
break; |
|||
|
|||
default: |
|||
return $this->error('请求地址出错'); |
|||
break; |
|||
} |
|||
|
|||
return json($result); |
|||
} |
|||
|
|||
/** |
|||
* 文件列表 |
|||
* @param string $allowFiles 指定的文件后缀 |
|||
* @param int $listSize 列表分页数量 |
|||
* @param string $path 文件目录 |
|||
* @param array $get ['size'=>xxx,'start'=>xxx] |
|||
* @return array |
|||
*/ |
|||
private function fileList($allowFiles, $listSize, $path, $get) |
|||
{ |
|||
$dirname = $path; |
|||
$allowFiles = substr(str_replace(",", "|", $allowFiles), 0); |
|||
|
|||
/* 获取参数 */ |
|||
$size = isset($get['size']) ? htmlspecialchars($get['size']) : $listSize; |
|||
$start = isset($get['start']) ? htmlspecialchars($get['start']) : 0; |
|||
$end = $start + $size; |
|||
|
|||
/* 获取文件列表 */ |
|||
$files = $this->getFiles($dirname, $allowFiles); |
|||
if (!count($files)) { |
|||
return [ |
|||
"code" => 0, |
|||
"state" => "no match file", |
|||
"list" => [], |
|||
"start" => $start, |
|||
"total" => count($files), |
|||
]; |
|||
} |
|||
|
|||
/* 获取指定范围的列表 */ |
|||
$len = count($files); |
|||
for ($i = min($end, $len) - 1, $list = array(); $i < $len && $i >= 0 && $i >= $start; $i--) { |
|||
$list[] = $files[$i]; |
|||
} |
|||
|
|||
/* 返回数据 */ |
|||
$result = [ |
|||
"code" => 1, |
|||
"state" => "SUCCESS", |
|||
"list" => $list, |
|||
"start" => $start, |
|||
"total" => count($files), |
|||
]; |
|||
|
|||
return $result; |
|||
} |
|||
|
|||
/** |
|||
* 遍历获取目录下的指定类型的文件 |
|||
* @param string $path 文件路径 |
|||
* @param string $allowFiles 指定的文件后缀,以|分隔的文本 |
|||
* @param array $files 文件数组 |
|||
* @return array |
|||
*/ |
|||
private function getFiles($path, $allowFiles, &$files = array()) |
|||
{ |
|||
if (!is_dir($path)) { |
|||
return []; |
|||
} |
|||
if (substr($path, strlen($path) - 1) != '/') { |
|||
$path .= '/'; |
|||
} |
|||
|
|||
$handle = opendir($path); |
|||
while (false !== ($file = readdir($handle))) { |
|||
if ($file != '.' && $file != '..') { |
|||
$path2 = $path . $file; |
|||
if (is_dir($path2)) { |
|||
$this->getFiles($path2, $allowFiles, $files); |
|||
} else { |
|||
if (preg_match("/\.(" . $allowFiles . ")$/i", $file)) { |
|||
$files[] = array( |
|||
'url' => preg_replace('/(.*)upload/i', '/upload', $path2), |
|||
'mtime' => filemtime($path2), |
|||
); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
return $files; |
|||
} |
|||
|
|||
/** |
|||
* 拉取远程图片 |
|||
* @return mixed |
|||
*/ |
|||
private function saveRemote($config, $fieldName) |
|||
{ |
|||
$imgUrl = htmlspecialchars($fieldName); |
|||
$imgUrl = str_replace("&", "&", $imgUrl); |
|||
|
|||
// http开头验证 |
|||
if (strpos($imgUrl, "http") !== 0) { |
|||
return [ |
|||
'code' => 0, |
|||
'msg' => '链接不是http|https链接', |
|||
'url' => '', |
|||
]; |
|||
} |
|||
// 获取请求头并检测死链 |
|||
$heads = get_headers($imgUrl, true); |
|||
if (!(stristr($heads[0], "200") && stristr($heads[0], "OK"))) { |
|||
return [ |
|||
'code' => 0, |
|||
'msg' => '链接不可用', |
|||
'url' => '', |
|||
]; |
|||
} |
|||
// 格式验证(扩展名验证和Content-Type验证) |
|||
$fileType = strtolower(strrchr(strrchr($imgUrl, '/'), '.')); |
|||
$fileType = ltrim($fileType, '.'); |
|||
// img链接后缀可能为空,Content-Type须为image |
|||
if ((!empty($fileType) && !in_array($fileType, $config['allowFiles'])) || stristr($heads['Content-Type'], "image") === -1) { |
|||
return [ |
|||
'code' => 0, |
|||
'msg' => '链接contentType不正确', |
|||
'url' => '', |
|||
]; |
|||
} |
|||
|
|||
// 解析出域名作为http_referer |
|||
$urlArr = explode('/', $imgUrl); |
|||
$protocol = str_replace(':', '', $urlArr[0]); |
|||
$httpReferer = $protocol . ':' . '//' . $urlArr[2]; |
|||
|
|||
// 打开输出缓冲区并获取远程图片 |
|||
ob_start(); |
|||
$context = stream_context_create([ |
|||
'http' => array( |
|||
//'header' => "Referer:$httpReferer", //突破防盗链,不可用 |
|||
'user_agent' => 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36', //突破防盗链 |
|||
'follow_location' => false, // don't follow redirects |
|||
), |
|||
]); |
|||
$res = false; |
|||
$message = ''; |
|||
try { |
|||
$res = readfile($imgUrl, false, $context); |
|||
} catch (\Exception $e) { |
|||
$message = $e->getMessage(); |
|||
} |
|||
|
|||
$img = ob_get_contents(); |
|||
ob_end_clean(); |
|||
|
|||
if ($res === false) { |
|||
return [ |
|||
'code' => 0, |
|||
'msg' => $message, |
|||
'url' => '', |
|||
]; |
|||
} |
|||
|
|||
preg_match("/[\/]([^\/]*)[\.]?[^\.\/]*$/", $imgUrl, $fileName); |
|||
|
|||
$dirname = public_path() . DIRECTORY_SEPARATOR . 'uploads' . DIRECTORY_SEPARATOR . date('Ymd') . DIRECTORY_SEPARATOR; |
|||
$file['oriName'] = $fileName ? $fileName[1] : ""; |
|||
$file['filesize'] = strlen($img); |
|||
$file['ext'] = strtolower(strrchr($config['oriName'], '.')); |
|||
$file['name'] = uniqid() . $file['ext']; |
|||
$file['fullName'] = $dirname . $file['name']; |
|||
$fullName = $file['fullName']; |
|||
|
|||
// 检查文件大小是否超出限制 |
|||
if ($config["maxSize"] > 0 && $file['filesize'] >= $config["maxSize"] * 1024) { |
|||
return [ |
|||
'code' => 0, |
|||
'msg' => '文件大小超出网站限制', |
|||
'url' => '', |
|||
]; |
|||
} |
|||
|
|||
// 创建目录失败 |
|||
if (!file_exists($dirname) && !mkdir($dirname, 0777, true)) { |
|||
return [ |
|||
'code' => 0, |
|||
'msg' => '目录创建失败', |
|||
'url' => '', |
|||
]; |
|||
} else if (!is_writeable($dirname)) { |
|||
return [ |
|||
'code' => 0, |
|||
'msg' => '目录没有写权限', |
|||
'url' => '', |
|||
]; |
|||
} |
|||
|
|||
// 移动文件 |
|||
if (!(file_put_contents($fullName, $img) && file_exists($fullName))) { |
|||
return [ |
|||
'code' => 0, |
|||
'msg' => '写入文件内容错误', |
|||
'url' => '', |
|||
]; |
|||
} |
|||
// 移动成功 |
|||
$data = array( |
|||
'code' => 1, |
|||
'state' => 'SUCCESS', |
|||
'url' => '/uploads/' . date('Ymd') . '/' . $file['name'], |
|||
'title' => $file['name'], |
|||
'original' => $file['oriName'], |
|||
'type' => $file['ext'], |
|||
'size' => $file['filesize'], |
|||
); |
|||
return $data; |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,47 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 会员管理控制器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2021/06/23 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\controller; |
|||
|
|||
// 引入框架内置类 |
|||
use think\facade\Request; |
|||
|
|||
// 引入表格和表单构建器 |
|||
use app\common\facade\MakeBuilder; |
|||
use app\common\builder\FormBuilder; |
|||
use app\common\builder\TableBuilder; |
|||
|
|||
class Users extends Base |
|||
{ |
|||
// 验证器 |
|||
protected $validate = 'Users'; |
|||
|
|||
// 当前主表 |
|||
protected $tableName = 'users'; |
|||
|
|||
// 当前主模型 |
|||
protected $modelName = 'Users'; |
|||
|
|||
} |
|||
@ -0,0 +1,47 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 会员分组控制器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2021/06/23 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\controller; |
|||
|
|||
// 引入框架内置类 |
|||
use think\facade\Request; |
|||
|
|||
// 引入表格和表单构建器 |
|||
use app\common\facade\MakeBuilder; |
|||
use app\common\builder\FormBuilder; |
|||
use app\common\builder\TableBuilder; |
|||
|
|||
class UsersType extends Base |
|||
{ |
|||
// 验证器 |
|||
protected $validate = 'UsersType'; |
|||
|
|||
// 当前主表 |
|||
protected $tableName = 'users_type'; |
|||
|
|||
// 当前主模型 |
|||
protected $modelName = 'UsersType'; |
|||
|
|||
} |
|||
@ -0,0 +1,21 @@ |
|||
<?php |
|||
// +---------------------------------------------------------------------- |
|||
// | ThinkPHP [ WE CAN DO IT JUST THINK ] |
|||
// +---------------------------------------------------------------------- |
|||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. |
|||
// +---------------------------------------------------------------------- |
|||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) |
|||
// +---------------------------------------------------------------------- |
|||
// | Author: liu21st <liu21st@gmail.com> |
|||
// +---------------------------------------------------------------------- |
|||
|
|||
// 事件定义文件 |
|||
return [ |
|||
'bind' => [ |
|||
// 更多事件绑定 |
|||
], |
|||
'listen' => [ |
|||
'AdminLogin' => ['app\admin\listener\AdminLogin'], |
|||
// 更多事件监听 |
|||
], |
|||
]; |
|||
@ -0,0 +1,12 @@ |
|||
<?php |
|||
namespace app\admin\facade; |
|||
|
|||
use think\Facade; |
|||
|
|||
class ThinkAddons extends Facade |
|||
{ |
|||
protected static function getFacadeClass() |
|||
{ |
|||
return 'app\admin\service\ThinkAddons'; |
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
<?php |
|||
|
|||
namespace app\admin\listener; |
|||
|
|||
use app\common\model\AdminLog; |
|||
|
|||
class AdminLogin |
|||
{ |
|||
public function handle($admin) |
|||
{ |
|||
// 事件监听处理 |
|||
AdminLog::record(); |
|||
} |
|||
} |
|||
@ -0,0 +1,157 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 后台中间件 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2020/03/08 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\middleware; |
|||
|
|||
use think\facade\Session; |
|||
use think\facade\Request; |
|||
use think\Response; |
|||
use think\exception\HttpResponseException; |
|||
|
|||
class Admin |
|||
{ |
|||
public function handle($request, \Closure $next) |
|||
{ |
|||
// 获取当前用户 |
|||
$admin_id = Session::get('admin.id'); |
|||
if (empty($admin_id)) { |
|||
return redirect((string)url('Login/index')); |
|||
} |
|||
|
|||
// 定义方法白名单 |
|||
$allow = [ |
|||
'Index/index', // 首页 |
|||
'Index/clear', // 清除缓存 |
|||
'Index/preview', // 预览 |
|||
'Index/select2', // ajax select2 |
|||
'Upload/index', // 上传文件 |
|||
'Login/index', // 登录页面 |
|||
'Login/checkLogin', // 校验登录 |
|||
'Login/captcha', // 登录验证码 |
|||
'Login/logout', // 退出登录 |
|||
]; |
|||
|
|||
// 查询所有不验证的方法并放入白名单 |
|||
$authOpen = \app\common\model\AuthRule::where('auth_open', '=', '0') |
|||
->select(); |
|||
$authRole = \app\common\model\AuthRule::select(); |
|||
$authOpens = []; |
|||
foreach ($authOpen as $k => $v) { |
|||
// 转换方法名为小写 |
|||
$ruleName = explode('/', $v['name']); |
|||
if ($ruleName[1]) { |
|||
$ruleName[1] = strtolower($ruleName[1]); |
|||
} |
|||
// 转换控制器首字母大写 |
|||
$ruleName = trim(implode('/', $ruleName)); |
|||
$authOpens[] = ucfirst($ruleName); |
|||
// 查询所有下级权限 |
|||
$ids = getChildsRule($authRole, $v['id']); |
|||
foreach ($ids as $kk => $vv) { |
|||
// 转换方法名为小写 |
|||
$ruleName = explode('/', $vv['name']); |
|||
if ($ruleName[1]) { |
|||
$ruleName[1] = strtolower($ruleName[1]); |
|||
} |
|||
// 转换控制器首字母大写 |
|||
$ruleName = trim(implode('/', $ruleName)); |
|||
$authOpens[] = ucfirst($ruleName); |
|||
} |
|||
} |
|||
$allow = array_merge($allow, $authOpens); |
|||
|
|||
// 查找当前控制器和方法,控制器首字母大写,方法名首字母小写 如:Index/index |
|||
$route = Request::controller() . '/' . lcfirst(Request::action()); |
|||
|
|||
// 权限认证 |
|||
if (!in_array($route, $allow)) { |
|||
if ($admin_id != 1) { |
|||
//开始认证 |
|||
$auth = new \Auth(); |
|||
|
|||
$result = $auth->check($route, $admin_id); |
|||
if (!$result) { |
|||
$this->error('您无此操作权限!'); |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 进行操作日志的记录 |
|||
\app\common\model\AdminLog::record(); |
|||
|
|||
// 当url中有ref=tab时表示刷新当前页(用于后台tab模式刷新) |
|||
if (Request::get("ref") == 'tab') { |
|||
|
|||
// 去除url中ref参数 |
|||
$url = preg_replace_callback("/([\?|&]+)ref=tab(&?)/i", function ($matches) { |
|||
return $matches[2] == '&' ? $matches[1] : ''; |
|||
}, Request::url()); |
|||
|
|||
// 重定向隐式传值使用的是Session闪存数据隐式传值,并且仅在下一次请求有效,再次访问重定向地址的时候无效 |
|||
return redirect('Index/index')->with('referer', $url); |
|||
} |
|||
|
|||
// 中间件handle方法的返回值必须是一个Response对象。 |
|||
return $next($request); |
|||
} |
|||
|
|||
/** |
|||
* 操作错误跳转 |
|||
* @param mixed $msg 提示信息 |
|||
* @param string $url 跳转的URL地址 |
|||
* @param mixed $data 返回的数据 |
|||
* @param integer $wait 跳转等待时间 |
|||
* @param array $header 发送的Header信息 |
|||
* @return void |
|||
*/ |
|||
protected function error($msg = '', string $url = null, $data = '', int $wait = 3, array $header = []): Response |
|||
{ |
|||
if (is_null($url)) { |
|||
$url = request()->isAjax() ? '' : 'javascript:history.back(-1);'; |
|||
} elseif ($url) { |
|||
$url = (strpos($url, '://') || 0 === strpos($url, '/')) ? $url : app('route')->buildUrl($url); |
|||
} |
|||
|
|||
$result = [ |
|||
'code' => 0, |
|||
'msg' => $msg, |
|||
'data' => $data, |
|||
'url' => $url, |
|||
'wait' => $wait, |
|||
]; |
|||
|
|||
$type = (request()->isJson() || request()->isAjax()) ? 'json' : 'html'; |
|||
|
|||
// 所有form返回的都必须是json,所有A链接返回的都必须是Html |
|||
$type = request()->isGet() ? 'html' : $type; |
|||
|
|||
if ($type == 'html') { |
|||
$response = view(app('config')->get('app.dispatch_error_tmpl'), $result); |
|||
} else if ($type == 'json') { |
|||
$response = json($result); |
|||
} |
|||
throw new HttpResponseException($response); |
|||
} |
|||
} |
|||
@ -0,0 +1,68 @@ |
|||
<?php |
|||
namespace app\admin\model; |
|||
|
|||
use think\facade\Session; |
|||
use think\Model; |
|||
|
|||
class Base extends Model |
|||
{ |
|||
// 获取左侧主菜单 |
|||
public static function getMenus() |
|||
{ |
|||
$authRule = \app\common\model\AuthRule::where('status', 1) |
|||
->order('sort asc') |
|||
->select() |
|||
->toArray(); |
|||
|
|||
$menus = []; |
|||
// 查找一级 |
|||
foreach ($authRule as $key => $val) { |
|||
$authRule[$key]['href'] = (string)url($val['name']); |
|||
if ($val['pid'] == 0) { |
|||
if (Session::get('admin.id') != 1) { |
|||
if (in_array($val['id'], Session::get('admin.rules', []))) { |
|||
$menus[] = $val; |
|||
} |
|||
} else { |
|||
$menus[] = $val; |
|||
} |
|||
} |
|||
} |
|||
// 查找二级 |
|||
foreach ($menus as $k => $v) { |
|||
$menus[$k]['children'] = []; |
|||
foreach ($authRule as $kk => $vv) { |
|||
if ($v['id'] == $vv['pid']) { |
|||
if (Session::get('admin.id') != 1) { |
|||
if (in_array($vv['id'], Session::get('admin.rules'))) { |
|||
$menus[$k]['children'][] = $vv; |
|||
} |
|||
} else { |
|||
$menus[$k]['children'][] = $vv; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
// 查找三级 |
|||
foreach ($menus as $k => $v) { |
|||
if ($v['children']) { |
|||
// 循环二级 |
|||
foreach ($v['children'] as $kk => $vv) { |
|||
$menus[$k]['children'][$kk]['children'] = []; |
|||
foreach ($authRule as $kkk => $vvv) { |
|||
if ($vv['id'] == $vvv['pid']) { |
|||
if (Session::get('admin.id') != 1) { |
|||
if (in_array($vvv['id'], Session::get('admin.rules'))) { |
|||
$menus[$k]['children'][$kk]['children'][] = $vvv; |
|||
} |
|||
} else { |
|||
$menus[$k]['children'][$kk]['children'][] = $vvv; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
return $menus; |
|||
} |
|||
} |
|||
@ -0,0 +1,502 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 插件服务类 |
|||
* +---------------------------------------------------------------------- |
|||
* test // 插件名称 |
|||
* ├── app // 此文件夹中所有文件会覆盖到根目录的/app文件夹 |
|||
* ├── public // 此文件夹中所有文件会覆盖到根目录的/public文件夹 |
|||
* ├── controller // 此文件夹为插件控制器目录 |
|||
* ├── model // 此文件夹为插件模型目录 |
|||
* ├── view // 此文件夹为插件视图目录 |
|||
* ├── Plugin.php // 此文件为插件核心安装卸载控制器,必需存在,且名称不可以变动 |
|||
* ├── config.php // 插件配置文件,后台插件管理中配置中读取和保存的就是这个文件,必须存在,且名称不可以变动 |
|||
* ├── config.html // 插件配置模板文件,优先获取此文件,不存在则调用表单构建器[可选] |
|||
* ├── LICENSE // 版权文件 |
|||
* ├── info.ini // 插件信息文件,用于保存插件基本信息,不存在则读取Plugin中的配置 |
|||
* └── install.sql // 插件数据库安装文件,此文件仅在插件安装时会进行导入,如重复安装可能会导致报错 |
|||
*/ |
|||
namespace app\admin\service; |
|||
|
|||
use think\Facade; |
|||
use think\facade\Config; |
|||
use think\facade\Db; |
|||
use RecursiveDirectoryIterator; |
|||
use RecursiveIteratorIterator; |
|||
|
|||
class ThinkAddons |
|||
{ |
|||
// 插件目录 |
|||
protected $addonsPath = ''; |
|||
|
|||
// 插件安装需要复制的文件夹 |
|||
protected $copyDirs = []; |
|||
|
|||
// 构造方法 |
|||
public function __construct() |
|||
{ |
|||
$this->addonsPath = app()->getRootPath() . 'addons'; |
|||
$this->copyDirs = [ |
|||
'app', // 此文件夹中所有文件会覆盖到根目录的/app文件夹 |
|||
'public', // 此文件夹中所有文件会覆盖到根目录的/public文件夹 |
|||
]; |
|||
} |
|||
|
|||
// 获得本地插件列表 [目前只获取本地插件,后期会扩展为获取线上插件] |
|||
public function localAddons() |
|||
{ |
|||
$plugins = scandir($this->addonsPath); |
|||
$list = []; |
|||
foreach ($plugins as $name) { |
|||
if ($name === '.' or $name === '..') |
|||
continue; |
|||
if (is_file($this->addonsPath . DIRECTORY_SEPARATOR . $name)) |
|||
continue; |
|||
$addonDir = $this->addonsPath . DIRECTORY_SEPARATOR . $name . DIRECTORY_SEPARATOR; |
|||
if (!is_dir($addonDir)) |
|||
continue; |
|||
|
|||
$object = $this->getInstance($name); |
|||
if ($object) { |
|||
// 获取插件基础信息 |
|||
$info = $object->getInfo(); |
|||
|
|||
// 增加右侧按钮组 |
|||
$str = ''; |
|||
if ($info['install'] == 1) { |
|||
// 已安装,增加配置按钮 |
|||
$str .= '<a class="btn btn-primary btn-xs" href="javascript:void(0)" onclick="$.operate.edit(\''.$name.'\')"><i class="fa fa-edit"></i> 配置</a> '; |
|||
$str .= '<a class="btn btn-danger btn-xs confirm" href="javascript:void(0)" onclick="$.operate.pluginUninstall(\'' . $name . '\')"><i class="fa fa-edit"></i> 卸载</a> '; |
|||
} else { |
|||
// 未安装,增加安装按钮 |
|||
$str = '<a class="btn btn-primary btn-xs" href="javascript:void(0)" onclick="$.operate.pluginInstall(\'' . $name . '\')"><i class="fa fa-edit"></i> 安装</a>'; |
|||
} |
|||
|
|||
$info['button'] = $str; |
|||
|
|||
$list[] = $info; |
|||
} |
|||
} |
|||
return $list; |
|||
} |
|||
|
|||
// 获取插件信息 |
|||
public function config(string $name) |
|||
{ |
|||
$check = $this->check($name); |
|||
if ($check !== true) { |
|||
return [ |
|||
'code' => 0, |
|||
'msg' => $check |
|||
]; |
|||
} |
|||
return $this->getConfig($name); |
|||
} |
|||
|
|||
// 保存插件信息 |
|||
public function configPost(array $data = []) |
|||
{ |
|||
$check = $this->check($data['id']); |
|||
if ($check !== true) { |
|||
return [ |
|||
'code' => 0, |
|||
'msg' => $check |
|||
]; |
|||
} |
|||
// 实例化插件 |
|||
$object = $this->getInstance($data['id']); |
|||
if ($object) { |
|||
|
|||
// 获取插件配置信息 |
|||
$config = $this->getConfig($data['id']); |
|||
// 判断是否分组 |
|||
$group = $this->checkConfigGroup($config); |
|||
if ($data) { |
|||
if ($group) { |
|||
// 开启分组 |
|||
foreach ($config as $k => $v) { |
|||
foreach ($v as $kk => $vv) { |
|||
if (isset($data[$kk])) { |
|||
$value = is_array($data[$kk]) ? implode(',', $data[$kk]) : ($data[$kk] ?? $vv['value']); |
|||
$config[$k][$kk]['value'] = $value; |
|||
} |
|||
} |
|||
} |
|||
} else { |
|||
// 未开启分组 |
|||
foreach ($config as $k => $v) { |
|||
if (isset($data[$k])) { |
|||
$value = is_array($data[$k]) ? implode(',', $data[$k]) : ($data[$k] ?? $v['value']); |
|||
$config[$k]['value'] = $value; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
// 更新配置文件 |
|||
$result = $this->setPluginConfig($data['id'], $config); |
|||
if ($result['code'] == 1) { |
|||
return [ |
|||
'code' => 1, |
|||
'msg' => '保存成功!' |
|||
]; |
|||
} else { |
|||
return [ |
|||
'code' => 0, |
|||
'msg' => $result['msg'] |
|||
]; |
|||
} |
|||
} else { |
|||
return [ |
|||
'code' => 0, |
|||
'msg' => '插件实例化失败' |
|||
]; |
|||
} |
|||
} |
|||
|
|||
// 启用插件或禁用插件 |
|||
public function state(string $name) |
|||
{ |
|||
$check = $this->check($name); |
|||
if ($check !== true) { |
|||
return [ |
|||
'code' => 0, |
|||
'msg' => $check |
|||
]; |
|||
} |
|||
// 实例化插件 |
|||
$object = $this->getInstance($name); |
|||
// 获取插件基础信息 |
|||
$info = $object->getInfo(); |
|||
if (!$info) { |
|||
return [ |
|||
'code' => 0, |
|||
'msg' => '未找到该插件的信息' |
|||
]; |
|||
} else { |
|||
// 请先安装 |
|||
if ($info['install'] != 1) { |
|||
return [ |
|||
'code' => 0, |
|||
'msg' => '请先安装该插件', |
|||
]; |
|||
} else { |
|||
return $this->changeStatus($name); |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 安装插件 |
|||
public function install(string $name) |
|||
{ |
|||
// 实例化插件 |
|||
$object = $this->getInstance($name); |
|||
// 获取插件基础信息 |
|||
$info = $object->getInfo(); |
|||
|
|||
if (false !== $object->install()) { |
|||
$info['status'] = 1; |
|||
$info['install'] = 1; |
|||
try { |
|||
// 更新或创建插件的ini文件 |
|||
$result = $this->setPluginIni($name, $info); |
|||
if ($result['code'] == 0) { |
|||
return [ |
|||
'code' => 1, |
|||
'msg' => $result['msg'], |
|||
]; |
|||
} |
|||
// 复制文件 |
|||
$this->copyDir($name); |
|||
// 导入SQL |
|||
$this->importsql($name); |
|||
} catch (\Exception $e) { |
|||
return [ |
|||
'code' => 0, |
|||
'msg' => '安装失败:' . $e->getMessage(), |
|||
]; |
|||
} |
|||
} else { |
|||
return [ |
|||
'code' => 0, |
|||
'msg' => '插件实例化失败', |
|||
]; |
|||
} |
|||
return [ |
|||
'code' => 1, |
|||
'msg' => '插件安装成功', |
|||
]; |
|||
} |
|||
|
|||
// 卸载插件 |
|||
public function uninstall(string $name) |
|||
{ |
|||
// 实例化插件 |
|||
$object = $this->getInstance($name); |
|||
// 获取插件基础信息 |
|||
$info = $object->getInfo(); |
|||
|
|||
if (false !== $object->uninstall()) { |
|||
$info['status'] = 0; |
|||
$info['install'] = 0; |
|||
// 更新或创建插件的ini文件 |
|||
$result = $this->setPluginIni($name, $info); |
|||
if ($result['code'] == 0) { |
|||
return [ |
|||
'code' => 0, |
|||
'msg' => $result['msg'], |
|||
]; |
|||
} else { |
|||
return [ |
|||
'code' => 1, |
|||
'msg' => '插件卸载成功', |
|||
]; |
|||
} |
|||
} else { |
|||
return [ |
|||
'code' => 0, |
|||
'msg' => '插件实例化失败', |
|||
]; |
|||
} |
|||
} |
|||
|
|||
// 启用/禁用插件 |
|||
public function changeStatus(string $name) |
|||
{ |
|||
// 实例化插件 |
|||
$object = $this->getInstance($name); |
|||
// 获取插件基础信息 |
|||
$info = $object->getInfo(); |
|||
|
|||
if (false !== $object->install()) { |
|||
$info['status'] = $info['status'] == 1 ? 0 : 1; |
|||
try { |
|||
// 更新或创建插件的ini文件 |
|||
$result = $this->setPluginIni($name, $info); |
|||
if ($result['code'] == 0) { |
|||
return [ |
|||
'code' => 1, |
|||
'msg' => $result['msg'], |
|||
]; |
|||
} |
|||
} catch (\Exception $e) { |
|||
return [ |
|||
'code' => 0, |
|||
'msg' => '状态变动失败:' . $e->getMessage(), |
|||
]; |
|||
} |
|||
} else { |
|||
return [ |
|||
'code' => 0, |
|||
'msg' => '插件实例化失败', |
|||
]; |
|||
} |
|||
return [ |
|||
'code' => 1, |
|||
'msg' => '状态变动成功', |
|||
]; |
|||
} |
|||
|
|||
// 判断插件配置文件是否进行了分组 |
|||
public function checkConfigGroup(array $config) |
|||
{ |
|||
// 空配置信息 |
|||
if (!$config) { |
|||
return false; |
|||
} |
|||
// 获取第一个元素 |
|||
$arrayShift = array_shift($config); |
|||
if (array_key_exists('title', $arrayShift) && array_key_exists('type', $arrayShift)) { |
|||
// 未开启分组 |
|||
return false; |
|||
} else { |
|||
// 开启分组 |
|||
return true; |
|||
} |
|||
} |
|||
// =========================================== |
|||
|
|||
// 验证插件是否完整 |
|||
private function check(string $name) |
|||
{ |
|||
if (!is_dir($this->addonsPath . DIRECTORY_SEPARATOR . $name)) { |
|||
return '未发现该插件,请先下载并放入到addons目录中'; |
|||
} |
|||
return true; |
|||
} |
|||
|
|||
// 获取插件实例 |
|||
private function getInstance(string $file) |
|||
{ |
|||
$class = "\\addons\\{$file}\\Plugin"; |
|||
if (class_exists($class)) { |
|||
// 容器类的工作由think\Container类完成,但大多数情况我们只需要通过app助手函数或者think\App类即可容器操作 |
|||
return app($class); |
|||
} |
|||
return false; |
|||
} |
|||
|
|||
// 获取完整配置列表[config.php] |
|||
private function getConfig(string $name) |
|||
{ |
|||
$file = app()->getRootPath() . 'addons' . DIRECTORY_SEPARATOR . $name . DIRECTORY_SEPARATOR . 'config.php'; |
|||
if (file_exists($file)) { |
|||
return include $file; |
|||
} else { |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 更新插件的配置文件 |
|||
* @param string $name 插件名 |
|||
* @param array $array |
|||
* @return boolean |
|||
* @throws Exception |
|||
*/ |
|||
private function setPluginConfig(string $name, array $array = []) |
|||
{ |
|||
$file = $this->addonsPath . DIRECTORY_SEPARATOR . $name . DIRECTORY_SEPARATOR . 'config.php'; |
|||
if (!$this->checkFileWritable($file)) { |
|||
return [ |
|||
'code' => 0, |
|||
'msg' => '文件没有写入权限', |
|||
]; |
|||
} |
|||
if ($handle = fopen($file, 'w')) { |
|||
fwrite($handle, "<?php\n\n" . "return " . var_export($array, TRUE) . ";\n");
|
|||
fclose($handle); |
|||
} else { |
|||
return [ |
|||
'code' => 0, |
|||
'msg' => '文件没有写入权限', |
|||
]; |
|||
} |
|||
return [ |
|||
'code' => 1, |
|||
'msg' => '文件写入完毕', |
|||
]; |
|||
} |
|||
|
|||
/** |
|||
* 更新插件的ini文件 |
|||
* @param string $name 插件名 |
|||
* @param array $array |
|||
* @return boolean |
|||
* @throws Exception |
|||
*/ |
|||
private function setPluginIni(string $name, array $array = []) |
|||
{ |
|||
$file = $this->addonsPath . DIRECTORY_SEPARATOR . $name . DIRECTORY_SEPARATOR . 'info.ini'; |
|||
if (!$this->checkFileWritable($file)) { |
|||
return [ |
|||
'code' => 0, |
|||
'msg' => '文件没有写入权限', |
|||
]; |
|||
} |
|||
// 拼接要写入的数据 |
|||
$str = ''; |
|||
foreach ($array as $k => $v) { |
|||
$str .= $k . " = " . $v . "\n"; |
|||
} |
|||
if ($handle = fopen($file, 'w')) { |
|||
fwrite($handle, $str); |
|||
fclose($handle); |
|||
} else { |
|||
return [ |
|||
'code' => 0, |
|||
'msg' => '文件没有写入权限', |
|||
]; |
|||
} |
|||
return [ |
|||
'code' => 1, |
|||
'msg' => '文件写入完毕', |
|||
]; |
|||
} |
|||
|
|||
/** |
|||
* 判断文件或目录是否可写 |
|||
* @param string $file 文件或目录 |
|||
* @return bool |
|||
*/ |
|||
private function checkFileWritable(string $file) |
|||
{ |
|||
if (is_dir($file)) { |
|||
// 判断目录是否可写 |
|||
return is_writable($file); |
|||
} elseif (file_exists($file)) { |
|||
// 文件存在则判断文件是否可写 |
|||
return is_writable($file); |
|||
} else { |
|||
// 文件不存在则判断当前目录是否可写 |
|||
$file = pathinfo($file, PATHINFO_DIRNAME); |
|||
return is_writable($file); |
|||
} |
|||
} |
|||
|
|||
// 导入SQL |
|||
private function importsql(string $name) |
|||
{ |
|||
$sqlFile = $this->addonsPath . DIRECTORY_SEPARATOR . $name . DIRECTORY_SEPARATOR . 'install.sql'; |
|||
if (is_file($sqlFile)) { |
|||
$lines = file($sqlFile); |
|||
$templine = ''; |
|||
foreach ($lines as $line) { |
|||
if (substr($line, 0, 2) == '--' || $line == '' || substr($line, 0, 2) == '/*') |
|||
continue; |
|||
|
|||
$templine .= $line; |
|||
if (substr(trim($line), -1, 1) == ';') { |
|||
// 不区分大小写替换前缀 |
|||
$templine = str_ireplace('__PREFIX__', Config::get('database.connections.mysql.prefix'), $templine); |
|||
// 忽略数据库中已经存在的数据 |
|||
$templine = str_ireplace('INSERT INTO ', 'INSERT IGNORE INTO ', $templine); |
|||
try { |
|||
Db::execute($templine); |
|||
} catch (\PDOException $e) { |
|||
//$e->getMessage(); |
|||
} |
|||
$templine = ''; |
|||
} |
|||
} |
|||
} |
|||
return true; |
|||
} |
|||
|
|||
// 安装时复制文件 |
|||
private function copyDir(string $name) |
|||
{ |
|||
$addonDir = $this->addonsPath . DIRECTORY_SEPARATOR . $name . DIRECTORY_SEPARATOR; |
|||
foreach ($this->copyDirs as $k => $dir) { |
|||
if (is_dir($addonDir . $dir)) { |
|||
$this->copydirs($addonDir . $dir, app()->getRootPath() . $dir); |
|||
} |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 复制文件夹到另一个文件夹 |
|||
* @param string $source 源文件夹 |
|||
* @param string $dest 目标文件夹 |
|||
*/ |
|||
private function copydirs($source, $dest) |
|||
{ |
|||
if (!is_dir($dest)) { |
|||
mkdir($dest, 0755, true); |
|||
} |
|||
foreach ( |
|||
$iterator = new RecursiveIteratorIterator( |
|||
new RecursiveDirectoryIterator($source, RecursiveDirectoryIterator::SKIP_DOTS), |
|||
RecursiveIteratorIterator::SELF_FIRST |
|||
) as $item |
|||
) { |
|||
if ($item->isDir()) { |
|||
$sontDir = $dest . DIRECTORY_SEPARATOR . $iterator->getSubPathName(); |
|||
if (!is_dir($sontDir)) { |
|||
mkdir($sontDir, 0755, true); |
|||
} |
|||
} else { |
|||
copy($item, $dest . DIRECTORY_SEPARATOR . $iterator->getSubPathName()); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,52 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 广告管理验证器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2021/06/23 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\validate; |
|||
|
|||
use think\Validate; |
|||
|
|||
class Ad extends Validate |
|||
{ |
|||
protected $rule = [ |
|||
'sort|排序' => [ |
|||
'require' => 'require', |
|||
'max' => '8', |
|||
'number' => 'number', |
|||
], |
|||
'status|状态' => [ |
|||
'require' => 'require', |
|||
'max' => '1', |
|||
], |
|||
'type_id|广告位' => [ |
|||
'require' => 'require', |
|||
], |
|||
'name|广告名称' => [ |
|||
'require' => 'require', |
|||
], |
|||
'description|备注' => [ |
|||
'max' => '250', |
|||
] |
|||
]; |
|||
} |
|||
@ -0,0 +1,44 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 广告分组验证器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2021/06/23 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\validate; |
|||
|
|||
use think\Validate; |
|||
|
|||
class AdType extends Validate |
|||
{ |
|||
protected $rule = [ |
|||
'name|分组名称' => [ |
|||
'require' => 'require', |
|||
], |
|||
'sort|排序' => [ |
|||
'require' => 'require', |
|||
'number' => 'number', |
|||
], |
|||
'status|状态' => [ |
|||
'require' => 'require', |
|||
] |
|||
]; |
|||
} |
|||
@ -0,0 +1,55 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 管理员列表验证器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2020/02/03 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\validate; |
|||
|
|||
use think\Validate; |
|||
|
|||
class Admin extends Validate |
|||
{ |
|||
protected $rule = [ |
|||
'status|状态' => [ |
|||
'require' => 'require', |
|||
'max' => '1', |
|||
], |
|||
'username|用户名' => [ |
|||
'require' => 'require', |
|||
'max' => '25', |
|||
'min' => '4', |
|||
], |
|||
'password|密码' => [ |
|||
'max' => '50', |
|||
'min' => '5', |
|||
], |
|||
'nickname|昵称' => [ |
|||
'require' => 'require', |
|||
'max' => '25', |
|||
'min' => '4', |
|||
], |
|||
'image|头像' => [ |
|||
'require' => 'require', |
|||
] |
|||
]; |
|||
} |
|||
@ -0,0 +1,43 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 管理员日志验证器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2020/02/03 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\validate; |
|||
|
|||
use think\Validate; |
|||
|
|||
class AdminLog extends Validate |
|||
{ |
|||
protected $rule = [ |
|||
'admin_id|管理员' => [ |
|||
'max' => '8', |
|||
], |
|||
'title|日志标题' => [ |
|||
'max' => '100', |
|||
], |
|||
'ip|操作IP' => [ |
|||
'max' => '20', |
|||
] |
|||
]; |
|||
} |
|||
@ -0,0 +1,55 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 文章模块验证器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2021/06/23 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\validate; |
|||
|
|||
use think\Validate; |
|||
|
|||
class Article extends Validate |
|||
{ |
|||
protected $rule = [ |
|||
'sort|排序' => [ |
|||
'require' => 'require', |
|||
'max' => '8', |
|||
'number' => 'number', |
|||
], |
|||
'status|状态' => [ |
|||
'require' => 'require', |
|||
'max' => '1', |
|||
], |
|||
'cate_id|栏目' => [ |
|||
'require' => 'require', |
|||
], |
|||
'title|标题' => [ |
|||
'require' => 'require', |
|||
], |
|||
'hits|点击次数' => [ |
|||
'number' => 'number', |
|||
], |
|||
'template|模板' => [ |
|||
'max' => '30', |
|||
] |
|||
]; |
|||
} |
|||
@ -0,0 +1,41 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 角色组管理验证器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2020/02/02 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\validate; |
|||
|
|||
use think\Validate; |
|||
|
|||
class AuthGroup extends Validate |
|||
{ |
|||
protected $rule = [ |
|||
'status|状态' => [ |
|||
'require' => 'require', |
|||
'max' => '1', |
|||
], |
|||
'title|角色组' => [ |
|||
'require' => 'require', |
|||
] |
|||
]; |
|||
} |
|||
@ -0,0 +1,45 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 菜单规则验证器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2020/02/03 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\validate; |
|||
|
|||
use think\Validate; |
|||
|
|||
class AuthRule extends Validate |
|||
{ |
|||
protected $rule = [ |
|||
'status|菜单状态' => [ |
|||
'require' => 'require', |
|||
'max' => '1', |
|||
], |
|||
'name|控制器/方法' => [ |
|||
'require' => 'require', |
|||
'unique' => 'auth_rule', // 唯一 |
|||
], |
|||
'title|权限名称' => [ |
|||
'require' => 'require', |
|||
] |
|||
]; |
|||
} |
|||
@ -0,0 +1,85 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 栏目管理验证器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2020/02/05 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\validate; |
|||
|
|||
use think\Validate; |
|||
|
|||
class Cate extends Validate |
|||
{ |
|||
protected $rule = [ |
|||
'sort|排序' => [ |
|||
'require' => 'require', |
|||
'max' => '8', |
|||
'number' => 'number', |
|||
], |
|||
'status|状态' => [ |
|||
'require' => 'require', |
|||
'max' => '1', |
|||
], |
|||
'cate_name|栏目名称' => [ |
|||
'require' => 'require', |
|||
'max' => '255', |
|||
], |
|||
'en_name|英文名称' => [ |
|||
'max' => '255', |
|||
], |
|||
'cate_folder|栏目目录' => [ |
|||
'max' => '255', |
|||
'unique' => 'cate' |
|||
], |
|||
'module_id|所属模块' => [ |
|||
'require' => 'require', |
|||
], |
|||
'url|外部链接' => [ |
|||
'max' => '255', |
|||
], |
|||
'image|栏目图片' => [ |
|||
'max' => '255', |
|||
], |
|||
'ico_image|ICO图片' => [ |
|||
'max' => '255', |
|||
], |
|||
'title|SEO标题' => [ |
|||
'max' => '255', |
|||
], |
|||
'keywords|SEO关键字' => [ |
|||
'max' => '255', |
|||
], |
|||
'description|SEO描述' => [ |
|||
'max' => '255', |
|||
], |
|||
'template_list|列表模板' => [ |
|||
'max' => '255', |
|||
], |
|||
'template_show|详情模版' => [ |
|||
'max' => '255', |
|||
], |
|||
'page_size|分页条数' => [ |
|||
'max' => '5', |
|||
'number' => 'number', |
|||
] |
|||
]; |
|||
} |
|||
@ -0,0 +1,57 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 碎片管理验证器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2021/06/23 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\validate; |
|||
|
|||
use think\Validate; |
|||
|
|||
class Debris extends Validate |
|||
{ |
|||
protected $rule = [ |
|||
'sort|排序' => [ |
|||
'require' => 'require', |
|||
'max' => '8', |
|||
'number' => 'number', |
|||
], |
|||
'status|状态' => [ |
|||
'require' => 'require', |
|||
'max' => '1', |
|||
], |
|||
'title|碎片标题' => [ |
|||
'require' => 'require', |
|||
'max' => '255', |
|||
], |
|||
'name|调用名称' => [ |
|||
'require' => 'require', |
|||
'max' => '255', |
|||
], |
|||
'url|链接地址' => [ |
|||
'max' => '255', |
|||
], |
|||
'description|描述' => [ |
|||
'max' => '255', |
|||
] |
|||
]; |
|||
} |
|||
@ -0,0 +1,56 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 字典数据验证器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2021/06/23 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\validate; |
|||
|
|||
use think\Validate; |
|||
|
|||
class Dictionary extends Validate |
|||
{ |
|||
protected $rule = [ |
|||
'dict_label|字典标签' => [ |
|||
'require' => 'require', |
|||
'max' => '100', |
|||
], |
|||
'dict_value|字典键值' => [ |
|||
'require' => 'require', |
|||
], |
|||
'dict_type|字典类型' => [ |
|||
'require' => 'require', |
|||
'max' => '5', |
|||
], |
|||
'remark|备注' => [ |
|||
'max' => '200', |
|||
], |
|||
'sort|排序' => [ |
|||
'require' => 'require', |
|||
'max' => '5', |
|||
'number' => 'number', |
|||
], |
|||
'status|状态' => [ |
|||
'require' => 'require', |
|||
] |
|||
]; |
|||
} |
|||
@ -0,0 +1,49 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 字典类型验证器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2021/06/23 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\validate; |
|||
|
|||
use think\Validate; |
|||
|
|||
class DictionaryType extends Validate |
|||
{ |
|||
protected $rule = [ |
|||
'dict_name|字典名称' => [ |
|||
'require' => 'require', |
|||
'max' => '100', |
|||
], |
|||
'status|状态' => [ |
|||
'require' => 'require', |
|||
], |
|||
'remark|备注' => [ |
|||
'max' => '200', |
|||
], |
|||
'sort|排序' => [ |
|||
'require' => 'require', |
|||
'max' => '5', |
|||
'number' => 'number', |
|||
] |
|||
]; |
|||
} |
|||
@ -0,0 +1,55 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 下载模块验证器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2021/06/23 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\validate; |
|||
|
|||
use think\Validate; |
|||
|
|||
class Download extends Validate |
|||
{ |
|||
protected $rule = [ |
|||
'sort|排序' => [ |
|||
'require' => 'require', |
|||
'max' => '8', |
|||
'number' => 'number', |
|||
], |
|||
'status|状态' => [ |
|||
'require' => 'require', |
|||
'max' => '1', |
|||
], |
|||
'cate_id|栏目' => [ |
|||
'require' => 'require', |
|||
], |
|||
'title|标题' => [ |
|||
'require' => 'require', |
|||
], |
|||
'hits|点击次数' => [ |
|||
'number' => 'number', |
|||
], |
|||
'template|模板' => [ |
|||
'max' => '30', |
|||
] |
|||
]; |
|||
} |
|||
@ -0,0 +1,61 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 字段管理验证器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2019/05/25 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\validate; |
|||
|
|||
use think\Validate; |
|||
|
|||
class Field extends Validate |
|||
{ |
|||
protected $rule = [ |
|||
'module_id|所属模块' => [ |
|||
'require' => 'require', |
|||
'max' => '3', |
|||
], |
|||
'type|字段类型' => [ |
|||
'require' => 'require', |
|||
'max' => '40', |
|||
], |
|||
'field|字段名' => [ |
|||
'require' => 'require', |
|||
'max' => '40', |
|||
], |
|||
'name|别名' => [ |
|||
'require' => 'require', |
|||
'max' => '30', |
|||
], |
|||
'minlength|字符长度' => [ |
|||
'max' => '10', |
|||
], |
|||
'maxlength|字符长度' => [ |
|||
'max' => '10', |
|||
], |
|||
'sort|排序' => [ |
|||
'require' => 'require', |
|||
'number' => 'number', |
|||
'max' => '10', |
|||
] |
|||
]; |
|||
} |
|||
@ -0,0 +1,49 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 字段分组验证器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2021/06/23 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\validate; |
|||
|
|||
use think\Validate; |
|||
|
|||
class FieldGroup extends Validate |
|||
{ |
|||
protected $rule = [ |
|||
'module_id|所属模块' => [ |
|||
'require' => 'require', |
|||
'max' => '5', |
|||
], |
|||
'group_name|分组名称' => [ |
|||
'require' => 'require', |
|||
], |
|||
'status|状态' => [ |
|||
'require' => 'require', |
|||
], |
|||
'sort|排序' => [ |
|||
'require' => 'require', |
|||
'max' => '5', |
|||
'number' => 'number', |
|||
] |
|||
]; |
|||
} |
|||
@ -0,0 +1,47 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 友情链接验证器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2021/06/23 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\validate; |
|||
|
|||
use think\Validate; |
|||
|
|||
class Link extends Validate |
|||
{ |
|||
protected $rule = [ |
|||
'name|网站名称' => [ |
|||
'require' => 'require', |
|||
], |
|||
'url|网站地址' => [ |
|||
'require' => 'require', |
|||
], |
|||
'sort|排序' => [ |
|||
'require' => 'require', |
|||
'number' => 'number', |
|||
], |
|||
'status|状态' => [ |
|||
'require' => 'require', |
|||
] |
|||
]; |
|||
} |
|||
@ -0,0 +1,50 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 留言模块验证器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2021/06/23 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\validate; |
|||
|
|||
use think\Validate; |
|||
|
|||
class Message extends Validate |
|||
{ |
|||
protected $rule = [ |
|||
'title|标题' => [ |
|||
'require' => 'require', |
|||
], |
|||
'cate_id|栏目' => [ |
|||
'require' => 'require', |
|||
], |
|||
'status|状态' => [ |
|||
'require' => 'require', |
|||
'max' => '1', |
|||
], |
|||
'name|姓名' => [ |
|||
'max' => '255', |
|||
], |
|||
'phone|电话' => [ |
|||
'max' => '255', |
|||
] |
|||
]; |
|||
} |
|||
@ -0,0 +1,63 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 模块管理验证器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2019/05/25 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\validate; |
|||
|
|||
use think\Validate; |
|||
|
|||
class Module extends Validate |
|||
{ |
|||
protected $rule = [ |
|||
'module_name|模块名称' => [ |
|||
'require' => 'require', |
|||
'max' => '100', |
|||
], |
|||
'table_name|表名称' => [ |
|||
'require' => 'require', |
|||
'max' => '50', |
|||
], |
|||
'model_name|模型名称' => [ |
|||
'require' => 'require', |
|||
'max' => '50', |
|||
], |
|||
'table_comment|表注释' => [ |
|||
'max' => '200', |
|||
], |
|||
'table_type|表类型' => [ |
|||
'require' => 'require', |
|||
'max' => '10', |
|||
], |
|||
'pk|主键' => [ |
|||
'require' => 'require', |
|||
'max' => '50', |
|||
], |
|||
'sort|排序' => [ |
|||
'require' => 'require', |
|||
'number' => 'number', |
|||
'max' => '3', |
|||
] |
|||
]; |
|||
|
|||
} |
|||
@ -0,0 +1,49 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 单页模块验证器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2021/06/23 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\validate; |
|||
|
|||
use think\Validate; |
|||
|
|||
class Page extends Validate |
|||
{ |
|||
protected $rule = [ |
|||
'status|状态' => [ |
|||
'require' => 'require', |
|||
'max' => '1', |
|||
], |
|||
'sort|排序' => [ |
|||
'require' => 'require', |
|||
'max' => '8', |
|||
'number' => 'number', |
|||
], |
|||
'cate_id|栏目' => [ |
|||
'require' => 'require', |
|||
], |
|||
'title|标题' => [ |
|||
'max' => '255', |
|||
] |
|||
]; |
|||
} |
|||
@ -0,0 +1,55 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 图片模块验证器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2021/06/23 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\validate; |
|||
|
|||
use think\Validate; |
|||
|
|||
class Picture extends Validate |
|||
{ |
|||
protected $rule = [ |
|||
'sort|排序' => [ |
|||
'require' => 'require', |
|||
'max' => '8', |
|||
'number' => 'number', |
|||
], |
|||
'status|状态' => [ |
|||
'require' => 'require', |
|||
'max' => '1', |
|||
], |
|||
'cate_id|栏目' => [ |
|||
'require' => 'require', |
|||
], |
|||
'title|标题' => [ |
|||
'require' => 'require', |
|||
], |
|||
'hits|点击次数' => [ |
|||
'number' => 'number', |
|||
], |
|||
'template|模板' => [ |
|||
'max' => '30', |
|||
] |
|||
]; |
|||
} |
|||
@ -0,0 +1,55 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 产品模块验证器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2021/06/23 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\validate; |
|||
|
|||
use think\Validate; |
|||
|
|||
class Product extends Validate |
|||
{ |
|||
protected $rule = [ |
|||
'sort|排序' => [ |
|||
'require' => 'require', |
|||
'max' => '8', |
|||
'number' => 'number', |
|||
], |
|||
'status|状态' => [ |
|||
'require' => 'require', |
|||
'max' => '1', |
|||
], |
|||
'cate_id|栏目' => [ |
|||
'require' => 'require', |
|||
], |
|||
'title|标题' => [ |
|||
'require' => 'require', |
|||
], |
|||
'hits|点击次数' => [ |
|||
'number' => 'number', |
|||
], |
|||
'template|模板' => [ |
|||
'max' => '30', |
|||
] |
|||
]; |
|||
} |
|||
@ -0,0 +1,46 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 系统设置验证器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2021/06/23 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\validate; |
|||
|
|||
use think\Validate; |
|||
|
|||
class System extends Validate |
|||
{ |
|||
protected $rule = [ |
|||
'copyright|版权信息' => [ |
|||
'max' => '255', |
|||
], |
|||
'upload_driver|上传驱动' => [ |
|||
'require' => 'require', |
|||
], |
|||
'upload_file_size|文件限制' => [ |
|||
'max' => '50', |
|||
], |
|||
'upload_image_size|图片限制' => [ |
|||
'max' => '50', |
|||
] |
|||
]; |
|||
} |
|||
@ -0,0 +1,61 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 团队模块验证器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2021/06/23 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\validate; |
|||
|
|||
use think\Validate; |
|||
|
|||
class Team extends Validate |
|||
{ |
|||
protected $rule = [ |
|||
'sort|排序' => [ |
|||
'require' => 'require', |
|||
'max' => '8', |
|||
'number' => 'number', |
|||
], |
|||
'status|状态' => [ |
|||
'require' => 'require', |
|||
'max' => '1', |
|||
], |
|||
'cate_id|栏目' => [ |
|||
'require' => 'require', |
|||
], |
|||
'title|标题' => [ |
|||
'require' => 'require', |
|||
], |
|||
'hits|点击次数' => [ |
|||
'number' => 'number', |
|||
], |
|||
'template|模板' => [ |
|||
'max' => '30', |
|||
], |
|||
'area|区域' => [ |
|||
'max' => '4', |
|||
], |
|||
'sex|性别' => [ |
|||
'max' => '4', |
|||
] |
|||
]; |
|||
} |
|||
@ -0,0 +1,75 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 会员管理验证器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2021/06/23 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\validate; |
|||
|
|||
use think\Validate; |
|||
|
|||
class Users extends Validate |
|||
{ |
|||
protected $rule = [ |
|||
'email|邮箱' => [ |
|||
'require' => 'require', |
|||
'max' => '100', |
|||
], |
|||
'password|密码' => [ |
|||
'max' => '100', |
|||
], |
|||
'sex|性别' => [ |
|||
'require' => 'require', |
|||
'max' => '1', |
|||
], |
|||
'last_login_time|最后登录时间' => [ |
|||
'max' => '10', |
|||
], |
|||
'last_login_ip|最后登录IP' => [ |
|||
'max' => '15', |
|||
], |
|||
'qq|QQ' => [ |
|||
'max' => '20', |
|||
], |
|||
'mobile|手机' => [ |
|||
'max' => '20', |
|||
], |
|||
'mobile_validated|手机验证' => [ |
|||
'require' => 'require', |
|||
'max' => '3', |
|||
], |
|||
'email_validated|邮箱验证' => [ |
|||
'require' => 'require', |
|||
'max' => '3', |
|||
], |
|||
'type_id|所属分组' => [ |
|||
'require' => 'require', |
|||
'max' => '3', |
|||
], |
|||
'status|状态' => [ |
|||
'require' => 'require', |
|||
], |
|||
'create_ip|注册IP' => [ |
|||
'max' => '15', |
|||
] |
|||
]; |
|||
} |
|||
@ -0,0 +1,46 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 会员分组验证器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | DATETIME: 2021/06/23 |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\validate; |
|||
|
|||
use think\Validate; |
|||
|
|||
class UsersType extends Validate |
|||
{ |
|||
protected $rule = [ |
|||
'name|分组名称' => [ |
|||
'require' => 'require', |
|||
'max' => '100', |
|||
], |
|||
'sort|排序' => [ |
|||
'require' => 'require', |
|||
'max' => '5', |
|||
'number' => 'number', |
|||
], |
|||
'status|状态' => [ |
|||
'require' => 'require', |
|||
] |
|||
]; |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
{ |
|||
"name": "SIYUCMS", |
|||
"version": "6.0.0", |
|||
"description": "api接口", |
|||
"title": "SIYUCMS V6 API接口", |
|||
"url": "http://api.junfei.iiixo.com/api", |
|||
"header": { |
|||
"title": "SIYUCMS", |
|||
"filename": "" |
|||
}, |
|||
"template": { |
|||
"withCompare": true, |
|||
"withGenerator": false |
|||
} |
|||
} |
|||
@ -0,0 +1,19 @@ |
|||
<?php |
|||
// +---------------------------------------------------------------------- |
|||
// | ThinkPHP [ WE CAN DO IT JUST THINK ] |
|||
// +---------------------------------------------------------------------- |
|||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. |
|||
// +---------------------------------------------------------------------- |
|||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) |
|||
// +---------------------------------------------------------------------- |
|||
// | Author: liu21st <liu21st@gmail.com> |
|||
// +---------------------------------------------------------------------- |
|||
|
|||
// +---------------------------------------------------------------------- |
|||
// | 应用设置 |
|||
// +---------------------------------------------------------------------- |
|||
|
|||
return [ |
|||
// 默认分页显示数量 |
|||
'page_size' => 10, |
|||
]; |
|||
@ -0,0 +1,117 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | api基础控制器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | QQ: 407593529 |
|||
* '::::::::::::' | DATETIME: 2019/07/18 |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
declare (strict_types = 1); |
|||
|
|||
namespace app\api\controller; |
|||
|
|||
use think\App; |
|||
use think\facade\Config; |
|||
use think\facade\Request; |
|||
use think\Response; |
|||
use think\Validate; |
|||
use think\exception\HttpResponseException; |
|||
|
|||
/** |
|||
* 控制器基础类 |
|||
*/ |
|||
abstract class Base |
|||
{ |
|||
/** |
|||
* Request实例 |
|||
* @var \think\Request |
|||
*/ |
|||
protected $request; |
|||
|
|||
/** |
|||
* 应用实例 |
|||
* @var \think\App |
|||
*/ |
|||
protected $app; |
|||
|
|||
/** |
|||
* 是否批量验证 |
|||
* @var bool |
|||
*/ |
|||
protected $batchValidate = false; |
|||
|
|||
/** |
|||
* 控制器中间件 |
|||
* @var array |
|||
*/ |
|||
protected $middleware = []; |
|||
|
|||
/** |
|||
* 分页数量 |
|||
* @var string |
|||
*/ |
|||
protected $pageSize = ''; |
|||
|
|||
/** |
|||
* 构造方法 |
|||
* @access public |
|||
* @param App $app 应用对象 |
|||
*/ |
|||
public function __construct(App $app) |
|||
{ |
|||
$this->app = $app; |
|||
$this->request = $this->app->request; |
|||
|
|||
// 控制器初始化 |
|||
$this->initialize(); |
|||
} |
|||
|
|||
// 初始化 |
|||
protected function initialize() |
|||
{ |
|||
//每页显示数据量 |
|||
$this->pageSize = Request::param('page_size', Config::get('app.page_size')); |
|||
} |
|||
|
|||
/** |
|||
* 返回封装后的API数据到客户端 |
|||
* @param mixed $data 要返回的数据 |
|||
* @param integer $code 返回的code |
|||
* @param mixed $msg 提示信息 |
|||
* @param string $type 返回数据格式 |
|||
* @param array $header 发送的Header信息 |
|||
* @return Response |
|||
*/ |
|||
protected function result($data, int $code = 0, $msg = '', string $type = '', array $header = []): Response |
|||
{ |
|||
$result = [ |
|||
'code' => $code, |
|||
'msg' => $msg, |
|||
'time' => time(), |
|||
'data' => $data, |
|||
]; |
|||
|
|||
$type = $type ?: 'json'; |
|||
$response = Response::create($result, $type)->header($header); |
|||
|
|||
throw new HttpResponseException($response); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,155 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 用户中心控制器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | QQ: 407593529 |
|||
* '::::::::::::' | DATETIME: 2019/07/19 |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
|
|||
namespace app\api\controller; |
|||
|
|||
|
|||
use app\api\service\JwtAuth; |
|||
use app\common\model\Product; |
|||
use app\common\model\Users; |
|||
use think\facade\Db; |
|||
use think\facade\Request; |
|||
|
|||
class Content extends Base |
|||
{ |
|||
/** |
|||
* 控制器中间件 [登录、注册 不需要鉴权] |
|||
* @var array |
|||
*/ |
|||
protected $middleware = [ |
|||
'app\api\middleware\Api' => ['except' => ['login', 'index', 'about', 'cate', 'product', 'detail_product', 'register']], |
|||
]; |
|||
|
|||
/** |
|||
* @api {post} /Content/index 01 首页api |
|||
* @apiGroup Content |
|||
* @apiVersion 1.0.0 |
|||
* @apiDescription 首页接口,返回 广告列表(最新6条),产品数据(最大4条) |
|||
* @apiSuccessExample {json} 成功示例 |
|||
* {"code":1,"msg":"","time":1660034733,"data":{"ad":[{"id":1,"create_time":1580378718,"update_time":1580378718,"sort":1,"status":1,"type_id":1,"name":"banner_1 ","image":"\/uploads\/20181225\/b671c6f234a72c2e6560c63ddd9dc0ff.jpg","thumb":"\/uploads\/20181225\/b671c6f234a72c2e6560c63ddd9dc0ff.jpg","url":"","description":"banner_1"},{"id":2,"create_time":1580378773,"update_time":1583585682,"sort":2,"status":1,"type_id":1,"name":"banner_2","image":"\/uploads\/20181225\/25670f5712b4acfb61c5d2a1bce79225.jpg","thumb":"\/uploads\/20181225\/25670f5712b4acfb61c5d2a1bce79225.jpg","url":"","description":"banner_2"}],"yinshidapeng":[{"id":1,"create_time":1581076523,"update_time":1581076523,"sort":50,"status":1,"cate_id":9,"title":"一本书","author":"管理员","source":"本站","content":"","summary":"","image":"\/uploads\/20181224\/065928f94ebe13ab1fbdc09cdd28a18b.jpg","images":"","download":"","tags":"书本","hits":0,"keywords":"","description":"","template":"","url":"","view_auth":0},{"id":2,"create_time":1581076563,"update_time":1581076563,"sort":50,"status":1,"cate_id":9,"title":"一支笔","author":"管理员","source":"本站","content":"","summary":"","image":"\/uploads\/20181224\/f05f564a79e650d566251152fa4fa75e.jpg","images":"","download":"","tags":"笔","hits":0,"keywords":"","description":"","template":"","url":"","view_auth":0},{"id":5,"create_time":1581076652,"update_time":1581076652,"sort":50,"status":1,"cate_id":9,"title":"笔记本","author":"管理员","source":"本站","content":"","summary":"","image":"\/uploads\/20181224\/d42552c77b14805f6d48e00b7a38f2e8.jpg","images":"","download":"","tags":"","hits":0,"keywords":"","description":"","template":"","url":"","view_auth":0},{"id":7,"create_time":1581076718,"update_time":1581076718,"sort":50,"status":1,"cate_id":9,"title":"铅笔盒","author":"管理员","source":"本站","content":"","summary":"","image":"\/uploads\/20181224\/c89c7634f5bcd3b60884da427bc0b384.jpg","images":"","download":"","tags":"","hits":0,"keywords":"","description":"","template":"","url":"","view_auth":0}],"shijingpianchang":[{"id":4,"create_time":1581076620,"update_time":1660025639,"sort":50,"status":1,"cate_id":10,"title":"背包","author":"管理员","source":"本站","content":"","summary":"","image":"\/uploads\/20181224\/8852280b4dc3365af4855c779e4239c6.jpg","images":"[]","download":"","tags":"","hits":0,"keywords":"","description":"","template":"","url":"","view_auth":0},{"id":6,"create_time":1581076690,"update_time":1660025634,"sort":50,"status":1,"cate_id":10,"title":"一支笔","author":"管理员","source":"本站","content":"","summary":"","image":"\/uploads\/20181224\/d42552c77b14805f6d48e00b7a38f2e8.jpg","images":"[]","download":"","tags":"笔","hits":0,"keywords":"","description":"","template":"","url":"","view_auth":0}],"peitaosheshi":[{"id":3,"create_time":1581076594,"update_time":1660025645,"sort":50,"status":1,"cate_id":14,"title":"一支铅笔","author":"管理员","source":"本站","content":"","summary":"","image":"\/uploads\/20181224\/d5e07bd3fdd9f3cbb0bdc798ccdba178.jpg","images":"[]","download":"","tags":"笔","hits":2,"keywords":"","description":"","template":"","url":"","view_auth":0}]}} |
|||
* @apiErrorExample {json} 失败示例 |
|||
* {"code":0,"msg":"数据异常,请稍后操作","time":1563525638,"data":[]} |
|||
*/ |
|||
public function index() |
|||
{ |
|||
//广告 |
|||
$_data['ad'] = Db::name('ad')->where('status', 1)->order('sort DESC,create_time DESC')->limit(6)->select(); |
|||
//三个产品分类 |
|||
$_data['yinshidapeng'] = Db::name('product')->where('cate_id', 9) |
|||
->order('sort DESC,create_time DESC')->limit(4)->select(); |
|||
$_data['shijingpianchang'] = Db::name('product')->where('cate_id', 10) |
|||
->order('sort DESC,create_time DESC')->limit(4)->select(); |
|||
$_data['peitaosheshi'] = Db::name('product')->where('cate_id', 14) |
|||
->order('sort DESC,create_time DESC')->limit(4)->select(); |
|||
return $this->result($_data, 1, ''); |
|||
|
|||
} |
|||
|
|||
/** |
|||
* @api {get} /Content/about 02 关于我们 |
|||
* @apiGroup Content |
|||
* @apiVersion 1.0.0 |
|||
* @apiDescription 关于我们内容详情接口,返回实体内容 |
|||
* @apiSuccessExample {json} 成功示例 |
|||
* {"code":1,"msg":"","time":1660034052,"data":{"content":"<p>ThinkPHP是一个免费开源的,快速、简单的面向对象的轻量级PHP开发框架,是为了敏捷WEB应用开发和简化企业应用开发而诞生的。ThinkPHP从诞生以来一直秉承简洁实用的设计原则,在保持出色的性能和至简代码的同时,更注重易用性。遵循<code>Apache2<\/code>开源许可协议发布,意味着你可以免费使用ThinkPHP,甚至允许把你基于ThinkPHP开发的应用开源或商业产品发布\/销售。<\/p>\n\n<p>ThinkPHP<code>6.0<\/code>基于精简核心和统一用法两大原则在<code>5.1<\/code>的基础上对底层架构做了进一步的优化改进,并更加规范化。由于引入了一些新特性,ThinkPHP<code>6.0<\/code>运行环境要求<code>PHP7.1+<\/code>,不支持<code>5.1<\/code>的无缝升级(官方给出了升级指导用于项目的升级参考)。<\/p>\n"}} |
|||
* @apiErrorExample {json} 失败示例 |
|||
* {"code":0,"msg":"数据异常,请稍后操作","time":1563525638,"data":[]} |
|||
*/ |
|||
public function about() |
|||
{ |
|||
//联系我们 |
|||
$_data = Db::name('page')->where('id', 1)->field('content')->find(); |
|||
$_data['map'] = Db::name('page')->where('id', 1)->field('content')->find(); |
|||
return $this->result($_data, 1, ''); |
|||
} |
|||
|
|||
/** |
|||
* @api {get} /Content/cate 03 获取产品栏目 |
|||
* @apiGroup Content |
|||
* @apiVersion 1.0.0 |
|||
* @apiDescription 产品栏目列表接口 |
|||
* @apiSuccessExample {json} 成功示例 |
|||
* {"code":1,"msg":"","time":1660034279,"data":[{"id":9,"sort":41,"status":1,"cate_name":"影视大棚","en_name":"","parent_id":8},{"id":10,"sort":42,"status":1,"cate_name":"实景片场","en_name":"","parent_id":8},{"id":14,"sort":50,"status":1,"cate_name":"配套设施","en_name":"","parent_id":8}]} |
|||
* @apiErrorExample {json} 失败示例 |
|||
* {"code":0,"msg":"数据异常,请稍后操作","time":1563525638,"data":[]} |
|||
*/ |
|||
public function cate() |
|||
{ |
|||
//获取产品栏目 |
|||
$_data = Db::name('cate')->where('parent_id', 8) |
|||
->where('status',1) |
|||
->field('id,sort,status,cate_name,en_name,parent_id') |
|||
->select(); |
|||
return $this->result($_data, 1, ''); |
|||
} |
|||
|
|||
/** |
|||
* @api {get} /Content/product/cate_id/{cate_id}/page/{page}/limit/{limit} 04 产品列表 |
|||
* @apiGroup Content |
|||
* @apiVersion 1.0.0 |
|||
* @apiDescription 产品列表接口,返回某个栏目下所有的产品列表,可分页 |
|||
* @apiParam (请求参数:) {int} cate_id 栏目id 必填 |
|||
* @apiParam (请求参数:) {int} page 当前页数 |
|||
* @apiParam (请求参数:) {int} limit 每页数量 默认10 |
|||
* @apiSuccessExample {json} 成功示例 |
|||
* {"code":1,"msg":"","time":1660034442,"data":[{"id":1,"image":"\/uploads\/20181224\/065928f94ebe13ab1fbdc09cdd28a18b.jpg","cate_id":9,"title":"一本书"},{"id":2,"image":"\/uploads\/20181224\/f05f564a79e650d566251152fa4fa75e.jpg","cate_id":9,"title":"一支笔"}]} |
|||
* @apiErrorExample {json} 失败示例 |
|||
* {"code":0,"msg":"数据异常,请稍后操作","time":1563525638,"data":[]} |
|||
*/ |
|||
public function product(int $cate_id, int $page = 1, int $limit = 2) |
|||
{ |
|||
|
|||
//获取所有产品栏目内容 |
|||
$_db = Db::name('product'); |
|||
$_data = $_db->where('cate_id', $cate_id)->field('id,image,cate_id,title') |
|||
->where('status',1) |
|||
->page($page, $limit)->select(); |
|||
return $this->result($_data, 1, ''); |
|||
} |
|||
|
|||
/** |
|||
* @api {get} /Content/product/id/{id} 05 产品详情 |
|||
* @apiGroup Content |
|||
* @apiVersion 1.0.0 |
|||
* @apiDescription 产品详情以及相关推荐接口,返回产品详情以及相关推荐数据 |
|||
* @apiParam (请求参数:) {int} id 产品id 必填 |
|||
* @apiSuccessExample {json} 成功示例 |
|||
* {"code":1,"msg":"","time":1660034541,"data":{"detail":{"id":8,"title":"钢笔","create_time":1581076758,"source":"本站","cate_id":9,"content":"","summary":""},"postion":[{"id":8,"title":"钢笔","image":"\/uploads\/20181224\/f05f564a79e650d566251152fa4fa75e.jpg"},{"id":7,"title":"铅笔盒","image":"\/uploads\/20181224\/c89c7634f5bcd3b60884da427bc0b384.jpg"},{"id":6,"title":"一支笔","image":"\/uploads\/20181224\/d42552c77b14805f6d48e00b7a38f2e8.jpg"},{"id":5,"title":"笔记本","image":"\/uploads\/20181224\/d42552c77b14805f6d48e00b7a38f2e8.jpg"}]}} |
|||
* @apiErrorExample {json} 失败示例 |
|||
* {"code":0,"msg":"数据异常,请稍后操作","time":1563525638,"data":[]} |
|||
*/ |
|||
public function detail_product(int $id) |
|||
{ |
|||
$_db = Db::name('product'); |
|||
$_data['detail'] = $_db->field('id,title,create_time,source,cate_id,content,summary') |
|||
->where('status',1) |
|||
->find($id); |
|||
$_data['postion'] = Db::name('product')->field('id,title,image')->limit(4) |
|||
->order('sort DESC,create_time DESC')->select(); |
|||
return $this->result($_data, 1, ''); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,233 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 用户中心控制器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | QQ: 407593529 |
|||
* '::::::::::::' | DATETIME: 2019/07/19 |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\api\controller; |
|||
|
|||
|
|||
use app\api\service\JwtAuth; |
|||
use app\common\model\Users; |
|||
use think\facade\Db; |
|||
use think\facade\Request; |
|||
|
|||
class User extends Base |
|||
{ |
|||
/** |
|||
* 控制器中间件 [登录、注册 不需要鉴权] |
|||
* @var array |
|||
*/ |
|||
protected $middleware = [ |
|||
'app\api\middleware\Api' => ['except' => ['login', 'register']], |
|||
]; |
|||
|
|||
/** |
|||
* @api {post} /User/login 01、会员登录 |
|||
* @apiGroup User |
|||
* @apiVersion 6.0.0 |
|||
* @apiDescription 系统登录接口,返回 token 用于操作需验证身份的接口 |
|||
|
|||
* @apiParam (请求参数:) {string} username 登录用户名 |
|||
* @apiParam (请求参数:) {string} password 登录密码 |
|||
|
|||
* @apiParam (响应字段:) {string} token Token |
|||
|
|||
* @apiSuccessExample {json} 成功示例 |
|||
* {"code":1,"msg":"登录成功","time":1563525780,"data":{"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJhcGkuc2l5dWNtcy5jb20iLCJhdWQiOiJzaXl1Y21zX2FwcCIsImlhdCI6MTU2MzUyNTc4MCwiZXhwIjoxNTYzNTI5MzgwLCJ1aWQiOjEzfQ.prQbqT00DEUbvsA5M14HpNoUqm31aj2JEaWD7ilqXjw"}} |
|||
* @apiErrorExample {json} 失败示例 |
|||
* {"code":0,"msg":"帐号或密码错误","time":1563525638,"data":[]} |
|||
*/ |
|||
public function login(string $username, string $password) |
|||
{ |
|||
// 校验用户名密码 |
|||
$user = Users::where('email|mobile', $username) |
|||
->where('password', md5($password)) |
|||
->find(); |
|||
if (empty($user)) { |
|||
$this->result([], 0, '帐号或密码错误'); |
|||
} else { |
|||
if ($user['status'] == 1) { |
|||
//获取jwt的句柄 |
|||
$jwtAuth = JwtAuth::getInstance(); |
|||
$token = $jwtAuth->setUid($user['id'])->encode()->getToken(); |
|||
//更新信息 |
|||
Users::where('id', $user['id']) |
|||
->update(['last_login_time' => time(), 'last_login_ip' => Request::ip()]); |
|||
$this->result(['token' => $token], 1, '登录成功'); |
|||
} else { |
|||
$this->result([], 0, '用户已被禁用'); |
|||
} |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* @api {post} /User/register 02、会员注册 |
|||
* @apiGroup User |
|||
* @apiVersion 6.0.0 |
|||
* @apiDescription 系统注册接口,返回是否成功的提示,需再次登录 |
|||
|
|||
* @apiParam (请求参数:) {string} email 邮箱 |
|||
* @apiParam (请求参数:) {string} password 密码 |
|||
|
|||
* @apiSuccessExample {json} 成功示例 |
|||
* {"code":1,"msg":"注册成功","time":1563526721,"data":[]} |
|||
* @apiErrorExample {json} 失败示例 |
|||
* {"code":0,"msg":"邮箱已被注册","time":1563526693,"data":[]} |
|||
*/ |
|||
public function register(string $email, string $password){ |
|||
// 密码长度不能低于6位 |
|||
if (strlen($password) < 6) { |
|||
$this->result([], 0, '密码长度不能低于6位'); |
|||
} |
|||
|
|||
// 邮箱合法性判断 |
|||
if (!is_email($email)) { |
|||
$this->result([], 0, '邮箱格式错误'); |
|||
} |
|||
|
|||
// 防止重复 |
|||
$id = Db::name('users')->where('email|mobile', '=', $email)->find(); |
|||
if ($id) { |
|||
$this->result([], 0, '邮箱已被注册'); |
|||
} |
|||
|
|||
// 注册入库 |
|||
$data = []; |
|||
$data['email'] = $email; |
|||
$data['password'] = md5($password); |
|||
$data['last_login_time'] = $data['create_time'] = time(); |
|||
$data['create_ip'] = $data['last_login_ip'] = Request::ip(); |
|||
$data['status'] = 1; |
|||
$data['type_id'] = 1; |
|||
$data['sex'] = Request::post('sex') ? Request::post('sex') : 0; |
|||
$id = Db::name('users')->insertGetId($data); |
|||
if ($id) { |
|||
$this->result([], 1, '注册成功'); |
|||
} else { |
|||
$this->result([], 0, '注册失败'); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* @api {post} /User/index 03、会员中心首页 |
|||
* @apiGroup User |
|||
* @apiVersion 6.0.0 |
|||
* @apiDescription 会员中心首页,返回用户个人信息 |
|||
|
|||
* @apiParam (请求参数:) {string} token Token |
|||
|
|||
* @apiSuccessExample {json} 响应数据样例 |
|||
* {"code":1,"msg":"","time":1563517637,"data":{"id":13,"email":"test110@qq.com","password":"e10adc3949ba59abbe56e057f20f883e","sex":1,"last_login_time":1563517503,"last_login_ip":"127.0.0.1","qq":"123455","mobile":"","mobile_validated":0,"email_validated":0,"type_id":1,"status":1,"create_ip":"127.0.0.1","update_time":1563507130,"create_time":1563503991,"type_name":"注册会员"}} |
|||
*/ |
|||
public function index() |
|||
{ |
|||
$user = Db::name('users') |
|||
->alias('u') |
|||
->leftJoin('users_type ut', 'u.type_id = ut.id') |
|||
->field('u.*,ut.name as type_name') |
|||
->where('u.id', $this->getUid()) |
|||
->find(); |
|||
return $this->result($user, 1, ''); |
|||
} |
|||
|
|||
/** |
|||
* @api {post} /User/editPwd 04、修改密码 |
|||
* @apiGroup User |
|||
* @apiVersion 6.0.0 |
|||
* @apiDescription 修改会员密码,返回成功或失败提示 |
|||
|
|||
* @apiParam (请求参数:) {string} token Token |
|||
* @apiParam (请求参数:) {string} oldPassword 原密码 |
|||
* @apiParam (请求参数:) {string} newPassword 新密码 |
|||
|
|||
* @apiSuccessExample {json} 成功示例 |
|||
* {"code":1,"msg":"密码修改成功","time":1563527107,"data":[]} |
|||
* @apiErrorExample {json} 失败示例 |
|||
* {"code":0,"msg":"token已过期","time":1563527082,"data":[]} |
|||
*/ |
|||
public function editPwd(string $oldPassword, string $newPassword){ |
|||
// 密码长度不能低于6位 |
|||
if (strlen($newPassword) < 6) { |
|||
$this->result([], 0, '密码长度不能低于6位'); |
|||
} |
|||
|
|||
// 查看原密码是否正确 |
|||
$user = Users::where('id', $this->getUid()) |
|||
->where('password', md5($oldPassword)) |
|||
->find(); |
|||
if (!$user) { |
|||
$this->result([], 0, '原密码输入有误'); |
|||
} |
|||
|
|||
//更新信息 |
|||
$user = Users::find($this->getUid()); |
|||
$user->password = md5($newPassword); |
|||
$user->save(); |
|||
$this->result([], 1, '密码修改成功'); |
|||
} |
|||
|
|||
/** |
|||
* @api {post} /User/editInfo 05、修改信息 |
|||
* @apiGroup User |
|||
* @apiVersion 6.0.0 |
|||
* @apiDescription 修改用户信息,返回成功或失败提示 |
|||
|
|||
* @apiParam (请求参数:) {string} token Token |
|||
* @apiParam (请求参数:) {string} sex 性别 [1男/0女] |
|||
* @apiParam (请求参数:) {string} qq qq |
|||
* @apiParam (请求参数:) {string} mobile 手机号 |
|||
|
|||
* @apiSuccessExample {json} 成功示例 |
|||
* {"code":0,"msg":"修改成功","time":1563507660,"data":[]} |
|||
* @apiErrorExample {json} 失败示例 |
|||
* {"code":0,"msg":"token已过期","time":1563527082,"data":[]} |
|||
*/ |
|||
public function editInfo(){ |
|||
$data['sex'] = trim(Request::param("sex")); |
|||
$data['qq'] = trim(Request::param("qq")); |
|||
$data['mobile'] = trim(Request::param("mobile")); |
|||
if ($data['mobile']) { |
|||
// 不可和其他用户的一致 |
|||
$id = Users:: |
|||
where('mobile', $data['mobile']) |
|||
->where('id', '<>', $this->getUid()) |
|||
->find(); |
|||
if ($id) { |
|||
$this->result([], 0, '手机号已存在'); |
|||
} |
|||
} |
|||
// 更新信息 |
|||
Users::where('id', $this->getUid()) |
|||
->update($data); |
|||
$this->result([], 0, '修改成功'); |
|||
} |
|||
|
|||
/** |
|||
* 获取用户id |
|||
* @return mixed |
|||
*/ |
|||
protected function getUid(){ |
|||
$jwtAuth = JwtAuth::getInstance(); |
|||
return $jwtAuth->getUid(); |
|||
} |
|||
} |
|||
@ -0,0 +1,81 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | Api中间件 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | QQ: 407593529 |
|||
* '::::::::::::' | DATETIME: 2019/07/18 |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\api\middleware; |
|||
|
|||
use app\api\service\JwtAuth; |
|||
|
|||
use think\facade\Request; |
|||
use think\Response; |
|||
use think\exception\HttpResponseException; |
|||
|
|||
class Api |
|||
{ |
|||
public function handle($request, \Closure $next) |
|||
{ |
|||
$token = Request::header('token'); |
|||
if ($token) { |
|||
if (count(explode('.', $token)) <> 3) { |
|||
$this->result([], 0, 'token格式错误'); |
|||
} |
|||
$jwtAuth = JwtAuth::getInstance(); |
|||
$jwtAuth->setToken($token); |
|||
if ($jwtAuth->validate() && $jwtAuth->verify()) { |
|||
return $next($request); |
|||
} else { |
|||
$this->result([], 0, 'token已过期'); |
|||
} |
|||
} else { |
|||
$this->result([], 0, 'token不能为空'); |
|||
} |
|||
|
|||
return $next($request); |
|||
} |
|||
|
|||
/** |
|||
* 返回封装后的API数据到客户端 |
|||
* @param mixed $data 要返回的数据 |
|||
* @param integer $code 返回的code |
|||
* @param mixed $msg 提示信息 |
|||
* @param string $type 返回数据格式 |
|||
* @param array $header 发送的Header信息 |
|||
* @return Response |
|||
*/ |
|||
protected function result($data, int $code = 0, $msg = '', string $type = '', array $header = []): Response |
|||
{ |
|||
$result = [ |
|||
'code' => $code, |
|||
'msg' => $msg, |
|||
'time' => time(), |
|||
'data' => $data, |
|||
]; |
|||
|
|||
$type = $type ?: 'json'; |
|||
$response = Response::create($result, $type)->header($header); |
|||
|
|||
throw new HttpResponseException($response); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,130 @@ |
|||
<?php |
|||
namespace app\api\service; |
|||
|
|||
use Lcobucci\JWT\Builder; |
|||
use Lcobucci\JWT\Parser; |
|||
use Lcobucci\JWT\Signer\Hmac\Sha256; |
|||
use Lcobucci\JWT\ValidationData; |
|||
|
|||
/** |
|||
* 单例 一次请求中所有出现jwt的地方都是一个用户 |
|||
* Class JwtAuth |
|||
* @package app\api\service |
|||
*/ |
|||
class JwtAuth |
|||
{ |
|||
// jwt token |
|||
private $token; |
|||
|
|||
// jwt 过期时间 |
|||
private $expTime = 3600; |
|||
|
|||
// claim iss |
|||
private $iss = 'api.siyucms.com'; |
|||
|
|||
// claim aud |
|||
private $aud = 'siyucms_app'; |
|||
|
|||
// claim uid |
|||
private $uid; |
|||
|
|||
// secrect |
|||
private $secrect = '1faASDF3'; |
|||
|
|||
// decode token |
|||
private $decodeToken; |
|||
|
|||
// 单例模式JwtAuth句柄 |
|||
private static $instance; |
|||
|
|||
// 获取JwtAuth的句柄 |
|||
public static function getInstance() |
|||
{ |
|||
if (is_null(self::$instance)) { |
|||
self::$instance = new self(); |
|||
} |
|||
return self::$instance; |
|||
} |
|||
|
|||
// 私有化构造函数 |
|||
private function __construct() |
|||
{ |
|||
|
|||
} |
|||
|
|||
// 私有化clone函数 |
|||
private function __clone() |
|||
{ |
|||
// TODO: Implement __clone() method. |
|||
} |
|||
|
|||
// 获取token |
|||
public function getToken() |
|||
{ |
|||
return (string)$this->token; |
|||
} |
|||
|
|||
// 设置token |
|||
public function setToken($token) |
|||
{ |
|||
$this->token = $token; |
|||
return $this; |
|||
} |
|||
|
|||
// 设置uid |
|||
public function setUid($uid) |
|||
{ |
|||
$this->uid = $uid; |
|||
return $this; |
|||
} |
|||
|
|||
// 获取uid |
|||
public function getUid() |
|||
{ |
|||
return $this->uid; |
|||
} |
|||
|
|||
// 编码jwt token |
|||
public function encode() |
|||
{ |
|||
$time = time(); |
|||
$this->token = (new Builder())->setHeader('alg', 'HS256') |
|||
->setIssuer($this->iss) |
|||
->setAudience($this->aud) |
|||
->setIssuedAt($time) |
|||
->setExpiration($time + $this->expTime) |
|||
->set('uid', $this->uid) |
|||
->sign(new Sha256(), $this->secrect) |
|||
->getToken(); |
|||
|
|||
return $this; |
|||
} |
|||
|
|||
public function decode() |
|||
{ |
|||
if (!$this->decodeToken) { |
|||
$this->decodeToken = (new Parser())->parse((string)$this->token); // Parses from a string |
|||
$this->uid = $this->decodeToken->getClaim('uid'); |
|||
} |
|||
return $this->decodeToken; |
|||
} |
|||
|
|||
// validate |
|||
public function validate() |
|||
{ |
|||
$data = new ValidationData(); // It will use the current time to validate (iat, nbf and exp) |
|||
$data->setIssuer($this->iss); |
|||
$data->setAudience($this->aud); |
|||
$data->setId($this->uid); |
|||
|
|||
return $this->decode()->validate($data); |
|||
} |
|||
|
|||
// verify token |
|||
public function verify() |
|||
{ |
|||
$signer = new Sha256(); |
|||
return $this->decode()->verify($signer, $this->secrect); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,108 @@ |
|||
<?php |
|||
declare (strict_types=1); |
|||
|
|||
namespace app\command; |
|||
|
|||
use think\console\Command; |
|||
use think\console\Input; |
|||
use think\console\input\Argument; |
|||
use think\console\input\Option; |
|||
use think\console\Output; |
|||
|
|||
class Admin extends Command |
|||
{ |
|||
/** |
|||
* 精简列表 |
|||
* ====文件和目录==== |
|||
* public/template/ 前台模板目录 |
|||
* public/uploads/ 前台上传文件目录 |
|||
* app/api 前台api应用文件 |
|||
* app/index 前台index应用文件 |
|||
* app/mobile 前台mobile应用文件 |
|||
* ====删除的模块==== |
|||
* link,ad_type,ad,debris,page,article,cate,picture,product,download,team,message |
|||
* 1、删除字段管理中的数据[field表,根据 module_id删除] |
|||
* 2、删除菜单规则表中的数据[auth_rule表,根据 model_name 删除] |
|||
* 3、删除模块表中的数据 |
|||
* 4、删除模块的控制器、模型、验证器[根据 model_name 删除] |
|||
* 5、删除模块对应的表 |
|||
*/ |
|||
protected function configure() |
|||
{ |
|||
// 指令配置 |
|||
$this->setName('admin') |
|||
->setDescription('精简文件和数据库'); |
|||
} |
|||
|
|||
protected function execute(Input $input, Output $output) |
|||
{ |
|||
try { |
|||
$rootPath = app()->getRootPath(); |
|||
|
|||
$this->dirDelete($rootPath . 'public' . DIRECTORY_SEPARATOR . 'template' . DIRECTORY_SEPARATOR); |
|||
$this->dirDelete($rootPath . 'public' . DIRECTORY_SEPARATOR . 'uploads' . DIRECTORY_SEPARATOR, false); |
|||
$this->dirDelete($rootPath . 'app' . DIRECTORY_SEPARATOR . 'api' . DIRECTORY_SEPARATOR); |
|||
$this->dirDelete($rootPath . 'app' . DIRECTORY_SEPARATOR . 'index' . DIRECTORY_SEPARATOR); |
|||
$this->dirDelete($rootPath . 'app' . DIRECTORY_SEPARATOR . 'mobile' . DIRECTORY_SEPARATOR); |
|||
|
|||
$tableName = ['link', 'ad_type', 'ad', 'debris', 'page', 'article', 'cate', 'picture', 'product', 'download', 'team', 'message']; |
|||
$module = \app\common\model\Module::where('table_name', 'in', $tableName)->select(); |
|||
if ($module) { |
|||
$module = $module->toArray(); |
|||
$prefix = \think\facade\Config::get('database.connections.mysql.prefix'); |
|||
foreach ($module as $k => $v) { |
|||
\app\common\model\Field::where('module_id', $v['id'])->delete(); |
|||
\app\common\model\AuthRule::where('name', $v['model_name'])->whereOr('name', 'like', $v['model_name'] . '/%')->delete(); |
|||
\app\common\model\Module::where('table_name', 'in', $tableName)->delete(); |
|||
$this->dirDelete($rootPath . 'app' . DIRECTORY_SEPARATOR . 'admin' . DIRECTORY_SEPARATOR . 'controller' . DIRECTORY_SEPARATOR . $v['model_name'] . '.php'); |
|||
$this->dirDelete($rootPath . 'app' . DIRECTORY_SEPARATOR . 'common' . DIRECTORY_SEPARATOR . 'model' . DIRECTORY_SEPARATOR . $v['model_name'] . '.php'); |
|||
$this->dirDelete($rootPath . 'app' . DIRECTORY_SEPARATOR . 'admin' . DIRECTORY_SEPARATOR . 'validate' . DIRECTORY_SEPARATOR . $v['model_name'] . '.php'); |
|||
$sql = 'DROP TABLE IF EXISTS `' . $prefix . $v['table_name'] . '`'; |
|||
\think\facade\Db::query($sql); |
|||
} |
|||
} |
|||
// 指令输出 |
|||
$output->writeln('END'); |
|||
} catch (\Exception $e) { |
|||
// 指令输出 |
|||
$output->writeln('ERROR:' . $e->getMessage()); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 删除目录及文件 |
|||
* @param string $path 要删除的目录 |
|||
* @param bool $delSelf 是否删除当前目录 |
|||
* @return bool |
|||
*/ |
|||
private function dirDelete(string $path, bool $delSelf = true) |
|||
{ |
|||
// 如果是目录则继续 |
|||
if (is_dir($path)) { |
|||
// 扫描一个文件夹内的所有文件夹和文件并返回数组 |
|||
$p = scandir($path); |
|||
foreach ($p as $val) { |
|||
// 排除目录中的.和.. |
|||
if ($val != "." && $val != "..") { |
|||
// 如果是目录则递归子目录,继续操作 |
|||
if (is_dir($path . $val)) { |
|||
// 子目录中操作删除文件夹和文件 |
|||
$this->dirDelete($path . $val . DIRECTORY_SEPARATOR); |
|||
// 目录清空后删除空文件夹 |
|||
@rmdir($path . $val . DIRECTORY_SEPARATOR); |
|||
} else { |
|||
// 如果是文件直接删除 |
|||
unlink($path . $val); |
|||
} |
|||
} |
|||
} |
|||
if ($delSelf) { |
|||
// 刪除空文件夾 |
|||
@rmdir($path); |
|||
} |
|||
} else if (is_file($path)) { |
|||
// 如果是文件直接删除 |
|||
unlink($path); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,953 @@ |
|||
<?php |
|||
// 应用公共文件 |
|||
|
|||
// 获取列表链接地址 |
|||
function getUrl($v) |
|||
{ |
|||
// 判断是否外部链接 |
|||
if (trim($v['url']) == '') { |
|||
// 判断是否跳转到下级栏目 |
|||
if ($v['is_next'] == 1) { |
|||
$is_next = \app\common\model\Cate::with(['module']) |
|||
->where('parent_id', $v['id']) |
|||
->order('sort asc,id desc') |
|||
->find(); |
|||
if ($is_next) { |
|||
$v['url'] = getUrl($is_next); |
|||
} |
|||
} else { |
|||
if ($v['cate_folder']) { |
|||
$v['url'] = (string)\think\facade\Route::buildUrl($v['cate_folder'] . '/index')->domain(''); |
|||
} else { |
|||
if (isset($v['module']['model_name']) && !empty($v['module']['model_name'])) { |
|||
$moduleName = $v['module']['model_name']; |
|||
} else { |
|||
$moduleId = $v['module']['id'] ?? $v['module_id']; |
|||
$moduleName = \app\common\model\Module::where('id', $moduleId) |
|||
->value('model_name'); |
|||
} |
|||
$v['url'] = (string)\think\facade\Route::buildUrl($moduleName . '/index', ['cate' => $v['id']])->domain(''); |
|||
} |
|||
} |
|||
} |
|||
return $v['url']; |
|||
} |
|||
|
|||
// 获取详情URL |
|||
function getShowUrl($v) |
|||
{ |
|||
if ($v) { |
|||
if (isset($v['url']) && !empty($v['url'])) { |
|||
return $v['url']; |
|||
} |
|||
if (isset($v['cate_id']) && !empty($v['cate_id'])) { |
|||
if (isset($v['cate'])) { |
|||
$cate = $v['cate']; |
|||
} else { |
|||
$cate = \app\common\model\Cate::field('id,cate_folder,module_id') |
|||
->where('id', $v['cate_id']) |
|||
->find(); |
|||
} |
|||
if ($cate['cate_folder']) { |
|||
$url = (string)\think\facade\Route::buildUrl($cate['cate_folder'] . '/info', ['id' => $v['id']])->domain(''); |
|||
} else { |
|||
if (isset($v['cate']['module'])) { |
|||
$modelName = $v['cate']['module']['model_name']; |
|||
} else { |
|||
$modelName = \app\common\model\Module::where('id', $cate['module_id']) |
|||
->value('model_name'); |
|||
} |
|||
$url = (string)\think\facade\Route::buildUrl($modelName . '/info', ['cate' => $cate['id'], 'id' => $v['id']])->domain(''); |
|||
} |
|||
} |
|||
} |
|||
return $url ?? ''; |
|||
} |
|||
|
|||
/*** |
|||
* 处理数据(把列表中需要处理的字段转换成数组和对应的值,用于自定义标签文件中) |
|||
* @param $list 列表 |
|||
* @param $moduleId 模型ID |
|||
* @return array |
|||
*/ |
|||
function changeFields($list, $moduleId) |
|||
{ |
|||
// 根据模型ID查询字段信息 |
|||
$fields = \app\common\model\Field::with(['module', 'dictionaryType'])->where('module_id', '=', $moduleId) |
|||
->select() |
|||
->toArray(); |
|||
$optionsArr = []; |
|||
foreach ($fields as $k => $v) { |
|||
$options = \app\common\facade\MakeBuilder::getFieldOptions($v); |
|||
$optionsArr[$v['field']] = $options; |
|||
} |
|||
|
|||
foreach ($list as $k => $v) { |
|||
$url = getShowUrl($v); |
|||
$list[$k] = changeField($v, $moduleId, $optionsArr); |
|||
$info[$k] = $list[$k]; // 定义中间变量防止报错 |
|||
$info[$k]['url'] = $url; |
|||
} |
|||
return $info ?? []; |
|||
} |
|||
|
|||
/*** |
|||
* 处理数据(用于详情页中数据转换) |
|||
* @param $info 内容详情 |
|||
* @param $moduleid 模型ID |
|||
* @param $optionsArr 选项信息 |
|||
* @return array |
|||
*/ |
|||
function changeField($info, $moduleId, $optionsArr) |
|||
{ |
|||
$fields = \app\common\model\Field::with(['module', 'dictionaryType'])->where('module_id', '=', $moduleId) |
|||
->select() |
|||
->toArray(); |
|||
foreach ($fields as $k => $v) { |
|||
// select等需要获取数据的字段 |
|||
if ($optionsArr) { |
|||
$options = $optionsArr[$v['field']]; |
|||
} else { |
|||
$options = \app\common\facade\MakeBuilder::getFieldOptions($v); |
|||
} |
|||
if (isset($info[$v['field']])) { |
|||
if ($v['type'] == 'text') { |
|||
// 忽略 |
|||
} elseif ($v['type'] == 'textarea' || $v['type'] == 'password') { |
|||
// 忽略 |
|||
} elseif ($v['type'] == 'radio' || $v['type'] == 'checkbox') { |
|||
|
|||
$info[$v['field'] . '_array'] = \app\common\facade\Cms::changeOptionsValue($options, $info[$v['field']], true); |
|||
$info[$v['field']] = \app\common\facade\Cms::changeOptionsValue($options, $info[$v['field']], false); |
|||
} elseif ($v['type'] == 'select' || $v['type'] == 'select2') { |
|||
if ($v['field'] !== 'cate_id') { |
|||
$info[$v['field'] . '_array'] = \app\common\facade\Cms::changeOptionsValue($options, $info[$v['field']], true); |
|||
$info[$v['field']] = \app\common\facade\Cms::changeOptionsValue($options, $info[$v['field']], false); |
|||
} |
|||
} elseif ($v['type'] == 'number') { |
|||
} elseif ($v['type'] == 'hidden') { |
|||
} elseif ($v['type'] == 'date' || $v['type'] == 'time' || $v['type'] == 'datetime') { |
|||
|
|||
} elseif ($v['type'] == 'daterange') { |
|||
} elseif ($v['type'] == 'tag') { |
|||
if (!empty($info[$v['field']])) { |
|||
$tags = explode(',', $info[$v['field']]); |
|||
foreach ($tags as $k => $tag) { |
|||
$tags[$k] = [ |
|||
'name' => $tag, |
|||
'url' => \think\facade\Route::buildUrl('index/tag', ['module' => $moduleId, 't' => $tag])->__toString(), |
|||
]; |
|||
} |
|||
$info[$v['field']] = $tags; |
|||
} |
|||
} elseif ($v['type'] == 'images' || $v['type'] == 'files') { |
|||
$info[$v['field']] = json_decode($info[$v['field']], true); |
|||
} elseif ($v['type'] == 'editor') { |
|||
|
|||
} elseif ($v['type'] == 'color') { |
|||
|
|||
} |
|||
} |
|||
} |
|||
return $info; |
|||
} |
|||
|
|||
/** |
|||
* 邮件发送 |
|||
* @param $to 接收人 |
|||
* @param string $subject 邮件标题 |
|||
* @param string $content 邮件内容(html模板渲染后的内容) |
|||
* @throws Exception |
|||
* @throws phpmailerException |
|||
*/ |
|||
function send_email($to, $subject = '', $content = '') |
|||
{ |
|||
$mail = new PHPMailer\PHPMailer\PHPMailer(); |
|||
$arr = \think\facade\Db::name('config') |
|||
->where('inc_type', 'smtp') |
|||
->select(); |
|||
$config = convert_arr_kv($arr, 'name', 'value'); |
|||
|
|||
$mail->CharSet = 'UTF-8'; //设定邮件编码,默认ISO-8859-1,如果发中文此项必须设置,否则乱码 |
|||
$mail->isSMTP(); |
|||
$mail->SMTPDebug = 0; |
|||
//调试输出格式 |
|||
//$mail->Debugoutput = 'html'; |
|||
//smtp服务器 |
|||
$mail->Host = $config['smtp_server']; |
|||
//端口 - likely to be 25, 465 or 587 |
|||
$mail->Port = $config['smtp_port']; |
|||
|
|||
if ($mail->Port == '465') { |
|||
$mail->SMTPSecure = 'ssl'; |
|||
}// 使用安全协议 |
|||
//Whether to use SMTP authentication |
|||
$mail->SMTPAuth = true; |
|||
//发送邮箱 |
|||
$mail->Username = $config['smtp_user']; |
|||
//密码 |
|||
$mail->Password = $config['smtp_pwd']; |
|||
//Set who the message is to be sent from |
|||
$mail->setFrom($config['smtp_user'], $config['email_id']); |
|||
//回复地址 |
|||
//$mail->addReplyTo('replyto@example.com', 'First Last'); |
|||
//接收邮件方 |
|||
if (is_array($to)) { |
|||
foreach ($to as $v) { |
|||
$mail->addAddress($v); |
|||
} |
|||
} else { |
|||
$mail->addAddress($to); |
|||
} |
|||
|
|||
$mail->isHTML(true);// send as HTML |
|||
//标题 |
|||
$mail->Subject = $subject; |
|||
//HTML内容转换 |
|||
$mail->msgHTML($content); |
|||
return $mail->send(); |
|||
} |
|||
|
|||
/** |
|||
* 验证输入的邮件地址是否合法 |
|||
* @param $user_email 邮箱 |
|||
* @return bool |
|||
*/ |
|||
function is_email($user_email) |
|||
{ |
|||
$chars = "/^([a-z0-9+_]|\\-|\\.)+@(([a-z0-9_]|\\-)+\\.)+[a-z]{2,6}\$/i"; |
|||
if (strpos($user_email, '@') !== false && strpos($user_email, '.') !== false) { |
|||
if (preg_match($chars, $user_email)) { |
|||
return true; |
|||
} else { |
|||
return false; |
|||
} |
|||
} else { |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 验证输入的手机号码是否合法 |
|||
* @param $mobile_phone 手机号 |
|||
* @return bool |
|||
*/ |
|||
function is_mobile_phone($mobile_phone) |
|||
{ |
|||
$chars = "/^13[0-9]{1}[0-9]{8}$|15[0-9]{1}[0-9]{8}$|18[0-9]{1}[0-9]{8}$|17[0-9]{1}[0-9]{8}$/"; |
|||
if (preg_match($chars, $mobile_phone)) { |
|||
return true; |
|||
} |
|||
return false; |
|||
} |
|||
|
|||
/** |
|||
* 过滤数组元素前后空格 (支持多维数组) |
|||
* @param $array 要过滤的数组 |
|||
* @return array|string |
|||
*/ |
|||
function trim_array_element($array) |
|||
{ |
|||
if (!is_array($array)) |
|||
return trim($array); |
|||
return array_map('trim_array_element', $array); |
|||
} |
|||
|
|||
/** |
|||
* 将数据库中查出的列表以指定的 值作为数组的键名,并以另一个值作为键值 |
|||
* @param $arr |
|||
* @param $key_name |
|||
* @return array |
|||
*/ |
|||
function convert_arr_kv($arr, $key_name, $value) |
|||
{ |
|||
$arr2 = array(); |
|||
foreach ($arr as $key => $val) { |
|||
$arr2[$val[$key_name]] = $val[$value]; |
|||
} |
|||
return $arr2; |
|||
} |
|||
|
|||
function string2array($info) |
|||
{ |
|||
if ($info == '') return array(); |
|||
eval("\$r = $info;"); |
|||
return $r; |
|||
} |
|||
|
|||
function array2string($info) |
|||
{ |
|||
//删除空格,某些情况下字段的设置会出现换行和空格的情况 |
|||
if (is_array($info)) { |
|||
if (array_key_exists('options', $info)) { |
|||
$info['options'] = trim($info['options']); |
|||
} |
|||
} |
|||
if ($info == '') return ''; |
|||
if (!is_array($info)) { |
|||
//删除反斜杠 |
|||
$string = stripslashes($info); |
|||
} |
|||
foreach ($info as $key => $val) { |
|||
$string[$key] = stripslashes($val); |
|||
} |
|||
$setup = var_export($string, TRUE); |
|||
return $setup; |
|||
} |
|||
|
|||
/** |
|||
* 文本域中换行标签输出 |
|||
* @param $info 内容 |
|||
* @return mixed |
|||
*/ |
|||
function textareaBr($info) |
|||
{ |
|||
$info = str_replace("\r\n", "<br />", $info); |
|||
$info = str_replace("\n", "<br />", $info); |
|||
$info = str_replace("\r", "<br />", $info); |
|||
return $info; |
|||
} |
|||
|
|||
/** |
|||
* 无限分类-栏目 |
|||
* @param $cate |
|||
* @param string $lefthtml |
|||
* @param int $pid |
|||
* @param int $lvl |
|||
* @return array |
|||
*/ |
|||
function tree_cate($cate, $leftHtml = '|— ', $pid = 0, $lvl = 0) |
|||
{ |
|||
$arr = array(); |
|||
foreach ($cate as $v) { |
|||
if ($v['parent_id'] == $pid) { |
|||
$v['lvl'] = $lvl + 1; |
|||
$v['left_html'] = str_repeat($leftHtml, $lvl); |
|||
$v['l_cate_name'] = $v['left_html'] . $v['cate_name']; |
|||
$arr[] = $v; |
|||
$arr = array_merge($arr, tree_cate($cate, $leftHtml, $v['id'], $lvl + 1)); |
|||
} |
|||
} |
|||
return $arr; |
|||
} |
|||
|
|||
/** |
|||
* 组合多维数组 |
|||
* @param $cate |
|||
* @param string $name |
|||
* @param int $pid |
|||
* @return array |
|||
*/ |
|||
function unlimitedForLayer($cate, $name = 'sub', $pid = 0) |
|||
{ |
|||
$arr = array(); |
|||
foreach ($cate as $v) { |
|||
if ($v['parent_id'] == $pid) { |
|||
$v[$name] = unlimitedForLayer($cate, $name, $v['id']); |
|||
$v['url'] = getUrl($v); |
|||
$arr[] = $v; |
|||
} |
|||
} |
|||
return $arr; |
|||
} |
|||
|
|||
/** |
|||
* 传递一个父级分类ID返回当前子分类 |
|||
* @param $cate |
|||
* @param $pid |
|||
* @return array |
|||
*/ |
|||
function getChildsOn($cate, $pid) |
|||
{ |
|||
$arr = array(); |
|||
foreach ($cate as $v) { |
|||
if ($v['parent_id'] == $pid) { |
|||
$v['sub'] = getChilds($cate, $v['id']); |
|||
$v['url'] = getUrl($v); |
|||
$arr[] = $v; |
|||
} |
|||
} |
|||
return $arr; |
|||
} |
|||
|
|||
/** |
|||
* 传递一个父级分类ID返回所有子分类 |
|||
* @param $cate |
|||
* @param $pid |
|||
* @return array |
|||
*/ |
|||
function getChilds($cate, $pid) |
|||
{ |
|||
$arr = array(); |
|||
foreach ($cate as $v) { |
|||
if ($v['parent_id'] == $pid) { |
|||
$v['url'] = getUrl($v); |
|||
$arr[] = $v; |
|||
$arr = array_merge($arr, getChilds($cate, $v['id'])); |
|||
} |
|||
} |
|||
return $arr; |
|||
} |
|||
|
|||
/** |
|||
* 传递一个父级分类ID返回所有子分类ID |
|||
* @param $cate |
|||
* @param $pid |
|||
* @return array |
|||
*/ |
|||
function getChildsId($cate, $pid) |
|||
{ |
|||
$arr = []; |
|||
foreach ($cate as $v) { |
|||
if ($v['parent_id'] == $pid) { |
|||
$arr[] = $v; |
|||
$arr = array_merge($arr, getChildsId($cate, $v['id'])); |
|||
} |
|||
} |
|||
return $arr; |
|||
} |
|||
|
|||
/** |
|||
* 格式化分类数组为字符串 |
|||
* @param $ids |
|||
* @param string $pid |
|||
* @return string |
|||
*/ |
|||
function getChildsIdStr($ids, $pid = '') |
|||
{ |
|||
$result = ''; |
|||
foreach ($ids as $k => $v) { |
|||
$result .= $v['id'] . ','; |
|||
} |
|||
if ($pid) { |
|||
$result = $pid . ',' . $result; |
|||
} |
|||
$result = rtrim($result, ','); |
|||
return $result; |
|||
} |
|||
|
|||
/** |
|||
* 传递一个子分类ID返回所有的父级分类[前台栏目] |
|||
* @param $cate |
|||
* @param $id |
|||
* @return array |
|||
*/ |
|||
function getParents($cate, $id) |
|||
{ |
|||
$arr = array(); |
|||
foreach ($cate as $v) { |
|||
if ($v['id'] == $id) { |
|||
$arr[] = $v; |
|||
$arr = array_merge(getParents($cate, $v['parent_id']), $arr); |
|||
} |
|||
} |
|||
return $arr; |
|||
} |
|||
|
|||
/** |
|||
* 查找一个分类id的顶级分类id |
|||
* @param $id |
|||
* @return string |
|||
*/ |
|||
function getTopId($id) |
|||
{ |
|||
$cate = \app\common\model\Cate::field('id,parent_id')->select()->toArray(); |
|||
$cateArr = []; |
|||
if ($cate) { |
|||
foreach ($cate as $k => $v) { |
|||
$cateArr[$v['id']] = $v['parent_id'] ?: "0"; |
|||
} |
|||
} |
|||
while ($cateArr[$id]) { |
|||
$id = $cateArr[$id]; |
|||
} |
|||
return $id; |
|||
} |
|||
|
|||
/** |
|||
* 获取文件目录列表 |
|||
* @param string $pathname 路径 |
|||
* @param integer $fileFlag 文件列表 0所有文件列表,1只读文件夹,2是只读文件(不包含文件夹) |
|||
* @param string $pathname 路径 |
|||
* @return array |
|||
*/ |
|||
function get_file_folder_List($pathname, $fileFlag = 0, $pattern = '*') |
|||
{ |
|||
$fileArray = array(); |
|||
$pathname = rtrim($pathname, '/') . '/'; |
|||
$list = glob($pathname . $pattern); |
|||
foreach ($list as $i => $file) { |
|||
switch ($fileFlag) { |
|||
case 0: |
|||
$fileArray[] = basename($file); |
|||
break; |
|||
case 1: |
|||
if (is_dir($file)) { |
|||
$fileArray[] = basename($file); |
|||
} |
|||
break; |
|||
|
|||
case 2: |
|||
if (is_file($file)) { |
|||
$fileArray[] = basename($file); |
|||
} |
|||
break; |
|||
|
|||
default: |
|||
break; |
|||
} |
|||
} |
|||
|
|||
if (empty($fileArray)) $fileArray = NULL; |
|||
return $fileArray; |
|||
} |
|||
|
|||
/** |
|||
* 获取所有模版 |
|||
* @return mixed |
|||
*/ |
|||
function getTemplate() |
|||
{ |
|||
// 查找所有系统设置表数据 |
|||
$system = \app\common\model\System::find(1); |
|||
|
|||
$path = './template/' . $system['template'] . '/index/' . $system['html'] . '/'; |
|||
$tpl['list'] = get_file_folder_List($path, 2, '*_list*'); |
|||
$tpl['show'] = get_file_folder_List($path, 2, '*_show*'); |
|||
return $tpl; |
|||
} |
|||
|
|||
/** |
|||
* 传递一个父级分类ID返回所有子分类 |
|||
* @param $cate |
|||
* @param $pid |
|||
* @return array |
|||
*/ |
|||
function getChildsRule($rules, $pid) |
|||
{ |
|||
$arr = []; |
|||
foreach ($rules as $v) { |
|||
if ($v['pid'] == $pid) { |
|||
$arr[] = $v; |
|||
$arr = array_merge($arr, getChildsRule($rules, $v['id'])); |
|||
} |
|||
} |
|||
return $arr; |
|||
} |
|||
|
|||
/*** |
|||
* 对象转数组 |
|||
* @param $object |
|||
* @return array |
|||
*/ |
|||
function object2array($object) |
|||
{ |
|||
$array = array(); |
|||
if (is_object($object)) { |
|||
foreach ($object as $key => $value) { |
|||
$array[$key] = $value; |
|||
} |
|||
} else { |
|||
$array = $object; |
|||
} |
|||
return $array; |
|||
} |
|||
|
|||
/*** |
|||
* 获取当前栏目ID |
|||
* @return mixed |
|||
*/ |
|||
function getCateId() |
|||
{ |
|||
if (\think\facade\Request::has('cate')) { |
|||
$result = (int)\think\facade\Request::param('cate'); |
|||
} else { |
|||
$cateFolder = get_cate_folder(); |
|||
if ($cateFolder) { |
|||
$result = \app\common\model\Cate::where('cate_folder', '=', $cateFolder)->value('id'); |
|||
} |
|||
} |
|||
return $result ?? ''; |
|||
} |
|||
|
|||
/** |
|||
* 改变前台字典数据标签取得的数据 |
|||
* @param array $list |
|||
* @return array |
|||
*/ |
|||
function changeDict(array $list, string $field, string $all = "全部") |
|||
{ |
|||
$get = \think\facade\Request::except(['page'], 'get'); |
|||
foreach ($list as $k => $v) { |
|||
$url = $get; |
|||
$url[$field] = $v['dict_value']; |
|||
$list[$k]['url'] = (string)url(get_cate_folder() . '/' . \think\facade\Request::action(), $url); |
|||
$param = \think\facade\Request::param('', '', 'htmlspecialchars'); |
|||
// 高亮显示 |
|||
$list[$k]['current'] = 0; |
|||
if (!empty($param)) { |
|||
foreach ($param as $kk => $vv) { |
|||
if ($kk == $field) { |
|||
if (strpos($vv, '|') !== false) { |
|||
// 多选 |
|||
$paramArr = explode("|", $vv); |
|||
foreach ($paramArr as $kkk => $vvv) { |
|||
if ($vvv == $v['dict_value']) { |
|||
$list[$k]['current'] = 1; |
|||
break; |
|||
} |
|||
} |
|||
} else { |
|||
// 单选 |
|||
if ($vv == $v['dict_value']) { |
|||
$list[$k]['current'] = 1; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
$list[$k]['param'] = $param; |
|||
} |
|||
|
|||
// 添加[全部]字段在第一位 |
|||
if (isset($get[$field])) { |
|||
unset($get[$field]); |
|||
} else { |
|||
$hover = 1; |
|||
} |
|||
$url = (string)url(get_cate_folder() . '/' . \think\facade\Request::action(), $get); |
|||
|
|||
$all = [ |
|||
'dict_label' => $all, |
|||
'dict_value' => 0, |
|||
'url' => $url, |
|||
'current' => $hover ?? 0, |
|||
]; |
|||
array_unshift($list, $all); |
|||
|
|||
return $list; |
|||
} |
|||
|
|||
/** |
|||
* 改变模版标签中分类字段传递 |
|||
* @param string $field 需要分类查询的字段,通过,分割或|分割 |
|||
* @return string |
|||
*/ |
|||
function getSearchField(string $field) |
|||
{ |
|||
$sql = ''; |
|||
if ($field) { |
|||
$field = str_replace('|', ',', $field); |
|||
$fieldArr = explode(',', $field); |
|||
foreach ($fieldArr as $k => $v) { |
|||
if (!empty($v)) { |
|||
// 查询浏览器参数是否包含此参数 |
|||
if (\think\facade\Request::has($v, 'get')) { |
|||
$str = \think\facade\Request::get($v, '', ['strip_tags', 'htmlspecialchars']); |
|||
if (strpos($str, '|') !== false) { |
|||
$sql = ' AND ('; |
|||
$strArr = explode("|", $str); |
|||
foreach ($strArr as &$strAr) { |
|||
// 检测是否存在 |
|||
$dictCount = \app\common\model\Dictionary::where('dict_value', $strAr)->count(); |
|||
if ($dictCount) { |
|||
$sql .= ' FIND_IN_SET(\'' . $strAr . '\', ' . $v . ') OR'; |
|||
} |
|||
} |
|||
// 去除最后一个or |
|||
$sql = substr($sql, 0, strlen($sql) - 2); |
|||
$sql .= ') '; |
|||
} else { |
|||
// 检测是否存在 |
|||
$dictCount = \app\common\model\Dictionary::where('dict_value', $str)->count(); |
|||
if ($dictCount) { |
|||
$sql .= ' AND FIND_IN_SET(\'' . $str . '\', ' . $v . ') '; |
|||
} else { |
|||
// 常规搜索 |
|||
$sql .= ' AND ' . $v . ' LIKE "%' . $str . '%" '; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
return $sql; |
|||
} |
|||
|
|||
/** |
|||
* 无限分类-权限 |
|||
* @param $cate 栏目 |
|||
* @param string $lefthtml 分隔符 |
|||
* @param int $pid 父ID |
|||
* @param int $lvl 层级 |
|||
* @return array |
|||
*/ |
|||
function tree($cate, $lefthtml = '|— ', $pid = 0, $lvl = 0) |
|||
{ |
|||
$arr = array(); |
|||
foreach ($cate as $v) { |
|||
if ($v['pid'] == $pid) { |
|||
$v['lvl'] = $lvl + 1; |
|||
$v['lefthtml'] = str_repeat($lefthtml, $lvl); |
|||
$v['ltitle'] = $v['lefthtml'] . $v['title']; |
|||
$arr[] = $v; |
|||
$arr = array_merge($arr, tree($cate, $lefthtml, $v['id'], $lvl + 1)); |
|||
} |
|||
} |
|||
return $arr; |
|||
} |
|||
|
|||
/** |
|||
* 无限分类-权限 |
|||
* @param $cate 栏目 |
|||
* @param string $lefthtml 分隔符 |
|||
* @param int $pid 父ID |
|||
* @param int $lvl 层级 |
|||
* @return array |
|||
*/ |
|||
function tree_three($cate, $lefthtml = '|— ', $pid = 0, $lvl = 0) |
|||
{ |
|||
$arr = array(); |
|||
foreach ($cate as $v) { |
|||
$keys = array_keys($v); |
|||
if (end($v) == $pid) { |
|||
$v['lvl'] = $lvl + 1; |
|||
$v['lefthtml'] = str_repeat($lefthtml, $lvl); |
|||
$v[$keys[1]] = $v['lefthtml'] . $v[$keys[1]]; |
|||
$arr[] = $v; |
|||
$arr = array_merge($arr, tree_three($cate, $lefthtml, $v[$keys[0]], $lvl + 1)); |
|||
} |
|||
} |
|||
return $arr; |
|||
} |
|||
|
|||
/** |
|||
* 标签云数据处理 |
|||
* @param $list |
|||
* @return array |
|||
*/ |
|||
function get_tagcloud($list, $moduleId, $limit = 10) |
|||
{ |
|||
$result = []; |
|||
if ($list) { |
|||
foreach ($list as $k => $v) { |
|||
if ($v['tags']) { |
|||
$arr = explode(',', $v['tags']); |
|||
foreach ($arr as $ar) { |
|||
if (!empty($ar)) { |
|||
$result[] = $ar; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
if ($result) { |
|||
$arr = array_count_values($result); // 统计数组中所有的值出现的次数 |
|||
// 降序排序 |
|||
arsort($arr); |
|||
$arr = array_slice($arr, 0, $limit);// 截取前N条数据 |
|||
$result = []; |
|||
foreach ($arr as $k => $v) { |
|||
$result[] = [ |
|||
'name' => $k, |
|||
'count' => $v, |
|||
'url' => \think\facade\Route::buildUrl('index/tag', ['module' => $moduleId, 't' => $k])->__toString(), |
|||
]; |
|||
} |
|||
} |
|||
return $result; |
|||
} |
|||
|
|||
/** |
|||
* 获取前一页地址中设置的返回url |
|||
* @return array |
|||
*/ |
|||
function get_back_url() |
|||
{ |
|||
if (isset($_SERVER["HTTP_REFERER"]) && !empty($_SERVER["HTTP_REFERER"])) { |
|||
$queryStr = explode('?', $_SERVER["HTTP_REFERER"]); |
|||
if (count($queryStr) == 2) { |
|||
parse_str($queryStr[1], $queryArr); |
|||
if (isset($queryArr['back_url']) && !empty($queryArr['back_url'])) { |
|||
$backUrl = explode("&", urldecode($queryArr['back_url'])); |
|||
foreach ($backUrl as $k => $v) { |
|||
$v = explode("=", $v); |
|||
if (isset($v[1]) && !empty($v[1])) { |
|||
$backArr[$v[0]] = $v[1]; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
return $backArr ?? []; |
|||
} |
|||
|
|||
/** |
|||
* 转换moment格式为php可用格式[废弃] |
|||
* @param $format |
|||
* @return string |
|||
*/ |
|||
function convert_moment_format_to_php(string $format = '') |
|||
{ |
|||
$replacements = [ |
|||
'DD' => 'd', |
|||
'ddd' => 'D', |
|||
'D' => 'j', |
|||
'dddd' => 'l', |
|||
'E' => 'N', |
|||
'o' => 'S', |
|||
'e' => 'w', |
|||
'DDD' => 'z', |
|||
'W' => 'W', |
|||
'MMMM' => 'F', |
|||
'MM' => 'm', |
|||
'MMM' => 'M', |
|||
'M' => 'n', |
|||
'YYYY' => 'Y', |
|||
'YY' => 'y', |
|||
'a' => 'a', |
|||
'A' => 'A', |
|||
'h' => 'g', |
|||
'H' => 'G', |
|||
'hh' => 'h', |
|||
'HH' => 'H', |
|||
'mm' => 'i', |
|||
'ss' => 's', |
|||
'SSS' => 'u', |
|||
'zz' => 'e', |
|||
'X' => 'U', |
|||
]; |
|||
$phpFormat = strtr($format, $replacements); |
|||
return $phpFormat; |
|||
} |
|||
|
|||
/** |
|||
* 转换php格式为moment可用格式 |
|||
* @param $format |
|||
* @return string |
|||
*/ |
|||
function convert_php_to_moment_format(string $format = '') |
|||
{ |
|||
$replacements = [ |
|||
'd' => 'DD', |
|||
'D' => 'ddd', |
|||
'j' => 'D', |
|||
'l' => 'dddd', |
|||
'N' => 'E', |
|||
'S' => 'o', |
|||
'w' => 'e', |
|||
'z' => 'DDD', |
|||
'W' => 'W', |
|||
'F' => 'MMMM', |
|||
'm' => 'MM', |
|||
'M' => 'MMM', |
|||
'n' => 'M', |
|||
't' => '', // no equivalent |
|||
'L' => '', // no equivalent |
|||
'o' => 'YYYY', |
|||
'Y' => 'YYYY', |
|||
'y' => 'YY', |
|||
'a' => 'a', |
|||
'A' => 'A', |
|||
'B' => '', // no equivalent |
|||
'g' => 'h', |
|||
'G' => 'H', |
|||
'h' => 'hh', |
|||
'H' => 'HH', |
|||
'i' => 'mm', |
|||
's' => 'ss', |
|||
'u' => 'SSS', |
|||
'e' => 'zz', // deprecated since version 1.6.0 of moment.js |
|||
'I' => '', // no equivalent |
|||
'O' => '', // no equivalent |
|||
'P' => '', // no equivalent |
|||
'T' => '', // no equivalent |
|||
'Z' => '', // no equivalent |
|||
'c' => '', // no equivalent |
|||
'r' => '', // no equivalent |
|||
'U' => 'X', |
|||
]; |
|||
$momentFormat = strtr($format, $replacements); |
|||
return $momentFormat; |
|||
} |
|||
|
|||
/** |
|||
* 根据url获取栏目目录 |
|||
*/ |
|||
function get_cate_folder() |
|||
{ |
|||
//return \think\facade\Request::controller(); // 控制器的方式无法使用'-','_','/'连接符 |
|||
$careFolder = \think\facade\Request::rule()->getRule(); // 获取当前路由规则 |
|||
$careFolder = str_replace('<id>', '', $careFolder); // 移除路由规则多余的字符 |
|||
$careFolder = trim($careFolder, '/'); // 移除两侧的/ |
|||
return $careFolder; |
|||
} |
|||
|
|||
/** |
|||
* 根据父ID获取下级联动数据 |
|||
* @param string $modelName 模型名称 |
|||
* @param int $pid 父ID |
|||
* @param string $pidFieldName 父ID字段名 |
|||
* @return array |
|||
*/ |
|||
function getLinkageData(string $modelName, int $pid = 0, string $pidFieldName = 'pid') |
|||
{ |
|||
$model = '\app\common\model\\' . $modelName; |
|||
if (class_exists($model)) { |
|||
return $model:: where($pidFieldName, $pid)->select()->toArray(); |
|||
} |
|||
return []; |
|||
} |
|||
|
|||
/** |
|||
* 根据末级ID获取父级联动数据 |
|||
* @param string $modelName 模型名称 |
|||
* @param string $id 主键值 |
|||
* @param string $idFieldName 主键字段名 |
|||
* @param string $nameFieldName name字段名 |
|||
* @param string $pidFieldName pid字段名 |
|||
* @param int $level 级别 |
|||
*/ |
|||
function getLinkageAllData(string $modelName, $id = '', $idFieldName = 'id', $nameFieldName = 'name', $pidFieldName = 'pid', $level = 1) |
|||
{ |
|||
$model = '\app\common\model\\' . $modelName; |
|||
// 获取当前数据的父ID |
|||
$pidFielValue = $model:: where($idFieldName, $id)->value($pidFieldName); |
|||
|
|||
// 当前级别的数据 |
|||
$resultKey[$level] = $pidFielValue; |
|||
$resultData[$level] = getLinkageData($modelName, (int)$pidFielValue, $pidFieldName); |
|||
|
|||
if ($pidFielValue != 0) { |
|||
$data = getLinkageAllData($modelName, $pidFielValue, $idFieldName, $nameFieldName, $pidFieldName, $level + 1); |
|||
$resultKey = $resultKey + $data['key']; // 后面一个数组,加入到前面一个数组中,键名相同时,不会被覆盖 |
|||
$resultData = $resultData + $data['data']; |
|||
} |
|||
|
|||
$result['key'] = $resultKey; |
|||
$result['data'] = $resultData; |
|||
return $result; |
|||
} |
|||
|
|||
/** |
|||
* 根据末级ID获取每级的联动数据 |
|||
* @param string $modelName 模型名称 |
|||
* @param string $id 主键值 |
|||
* @param string $idFieldName 主键字段名 |
|||
* @param string $nameFieldName name字段名 |
|||
* @param string $pidFieldName pid字段名 |
|||
* @param array $result 数据 |
|||
*/ |
|||
function getLinkageListData(string $modelName, $id = '', $idFieldName = 'id', $nameFieldName = 'name', $pidFieldName = 'pid', $result = []) |
|||
{ |
|||
$model = '\app\common\model\\' . $modelName; |
|||
// 查找当前层的数据 |
|||
$data = $model:: where($idFieldName, $id)->field([$idFieldName, $nameFieldName, $pidFieldName])->find(); |
|||
if ($data) { |
|||
$result[] = $data->toArray(); |
|||
if ($data->{$pidFieldName}) { |
|||
return getLinkageListData($modelName, $data->{$pidFieldName}, $idFieldName, $nameFieldName, $pidFieldName, $result); |
|||
} |
|||
} |
|||
return $result; |
|||
} |
|||
File diff suppressed because it is too large
File diff suppressed because it is too large
@ -0,0 +1,715 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | 表格快速构造器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: siyu |
|||
* ::::::::::: | EMAIL: 407593529@qq.com |
|||
* ..:::::::::::' | QQ: 407593529 |
|||
* '::::::::::::' | DATETIME: 2019/08/05 |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
|
|||
namespace app\common\builder; |
|||
|
|||
use think\facade\Request; |
|||
use think\facade\View; |
|||
|
|||
class TableBuilder |
|||
{ |
|||
/** |
|||
* @var array 列名 |
|||
*/ |
|||
private $_field_name = []; |
|||
|
|||
/** |
|||
* @var string 模板路径(默认使用系统内置路径,无需设置) |
|||
*/ |
|||
private $_template = ''; |
|||
|
|||
/** |
|||
* @var array 模板变量 |
|||
*/ |
|||
private $_vars = [ |
|||
'page_title' => '', // 页面标题 |
|||
'page_tips' => '', // 页面提示 |
|||
'page_tips_top' => '', // 页面提示[top] |
|||
'page_tips_search' => '', // 页面提示[search] |
|||
'page_tips_bottom' => '', // 页面提示[bottom] |
|||
'page_size' => '', // 每页显示的行数 |
|||
'tips_type' => '', // 页面提示类型 |
|||
'extra_js' => '', // 额外JS代码 |
|||
'extra_css' => '', // 额外CSS代码 |
|||
'extra_html' => '', // 额外HTML代码 |
|||
'columns' => [], // 表格列集合 |
|||
'right_buttons' => [], // 表格右侧按钮 |
|||
'top_buttons' => [], // 顶部栏按钮组[toolbar] |
|||
'unique_id' => 'id', // 表格主键名称(默认为id,如表主键不为id必须设置主键) |
|||
'data_url' => '', // 表格数据源 |
|||
'add_url' => '', // 默认的新增地址 |
|||
'edit_url' => '', // 默认的修改地址 |
|||
'del_url' => '', // 默认的删除地址 |
|||
'export_url' => '', // 默认的导出地址 |
|||
'sort_url' => '', // 默认的排序地址 |
|||
'search' => [], // 搜索参数 |
|||
'pagination' => 'true', // 是否进行分页 |
|||
'parent_id_field' => '', // 列表树模式需传递父id |
|||
'empty_tips' => '没有找到匹配的记录', // 空数据提示信息 |
|||
'hide_checkbox' => false, // 是否隐藏第一列多选[待完善] |
|||
'layer_open' => true, // 添加/编辑等页启用layer弹层加载 |
|||
'fixed_left' => 0, // 左侧固定列数 |
|||
'fixed_right' => 1, // 右侧固定列数 |
|||
]; |
|||
|
|||
/** |
|||
* @var 单例模式句柄 |
|||
*/ |
|||
private static $instance; |
|||
|
|||
/** |
|||
* 获取句柄 |
|||
* @return FormBuilder |
|||
*/ |
|||
public static function getInstance() |
|||
{ |
|||
if (is_null(self::$instance)) { |
|||
self::$instance = new self(); |
|||
} |
|||
return self::$instance; |
|||
} |
|||
|
|||
/** |
|||
* 私有化构造函数 |
|||
*/ |
|||
private function __construct() |
|||
{ |
|||
// 初始化 |
|||
$this->initialize(); |
|||
} |
|||
|
|||
/** |
|||
* 初始化 |
|||
*/ |
|||
protected function initialize() |
|||
{ |
|||
// 每页显示的行数 |
|||
$this->_vars['page_size'] = \think\facade\Config::get('app.page_size', '10'); |
|||
// layer弹层 |
|||
$this->_vars['layer_open'] = \think\facade\Config::get('builder.layer_open', false); |
|||
|
|||
// 设置默认模版 |
|||
$this->_template = 'table_builder/layout'; |
|||
|
|||
// 设置默认URL |
|||
$this->_vars['data_url'] = Request::baseUrl() . '?getList=1'; |
|||
$this->_vars['add_url'] = url('add'); |
|||
$this->_vars['edit_url'] = url('edit', ['id' => '__id__']); |
|||
$this->_vars['del_url'] = url('del'); |
|||
$this->_vars['export_url'] = url('export'); |
|||
$this->_vars['sort_url'] = url('sort'); |
|||
} |
|||
|
|||
/** |
|||
* 私有化clone函数 |
|||
*/ |
|||
private function __clone() |
|||
{ |
|||
// TODO: Implement __clone() method. |
|||
} |
|||
|
|||
/** |
|||
* 渲染模版 |
|||
* @param string $template 模板文件名 |
|||
* @return string |
|||
* @throws \Exception |
|||
*/ |
|||
public function fetch(string $template = '') |
|||
{ |
|||
// 单独设置模板 |
|||
if ($template != '') { |
|||
$this->_template = $template; |
|||
} |
|||
View::assign($this->_vars); |
|||
return View::fetch($this->_template); |
|||
} |
|||
|
|||
/** |
|||
* 设置表格主键 |
|||
* @param string $key 主键名称 |
|||
* @return $this |
|||
*/ |
|||
public function setUniqueId($key = '') |
|||
{ |
|||
if ($key != '') { |
|||
$this->_vars['unique_id'] = $key; |
|||
} |
|||
return $this; |
|||
} |
|||
|
|||
/** |
|||
* 设置页面标题 |
|||
* @param string $title 页面标题 |
|||
* @return $this |
|||
*/ |
|||
public function setPageTitle($title = '') |
|||
{ |
|||
if ($title != '') { |
|||
$this->_vars['page_title'] = trim($title); |
|||
} |
|||
return $this; |
|||
} |
|||
|
|||
/** |
|||
* 设置表单页提示信息 |
|||
* @param string $tips 提示信息 |
|||
* @param string $type 提示类型:danger,info,warning,success |
|||
* @param string $pos 提示位置:top,search,bottom |
|||
* @return $this |
|||
*/ |
|||
public function setPageTips($tips = '', $type = 'info', $pos = 'top') |
|||
{ |
|||
if ($tips != '') { |
|||
$this->_vars['page_tips_' . $pos] = $tips; |
|||
$this->_vars['tips_type'] = trim($type); |
|||
} |
|||
return $this; |
|||
} |
|||
|
|||
/** |
|||
* 设置额外JS代码 |
|||
* @param string $extra_js 额外JS代码 |
|||
* @return $this |
|||
*/ |
|||
public function setExtraJs($extra_js = '') |
|||
{ |
|||
if ($extra_js != '') { |
|||
$this->_vars['extra_js'] = $extra_js; |
|||
} |
|||
return $this; |
|||
} |
|||
|
|||
/** |
|||
* 设置额外CSS代码 |
|||
* @param string $extra_css 额外CSS代码 |
|||
* @return $this |
|||
*/ |
|||
public function setExtraCss($extra_css = '') |
|||
{ |
|||
if ($extra_css != '') { |
|||
$this->_vars['extra_css'] = $extra_css; |
|||
} |
|||
return $this; |
|||
} |
|||
|
|||
/** |
|||
* 设置额外HTML代码 |
|||
* @param string $extra_html 额外HTML代码 |
|||
* @param string $pos 位置 [top和bottom] |
|||
* @return $this |
|||
*/ |
|||
public function setExtraHtml($extra_html = '', $pos = '') |
|||
{ |
|||
if ($extra_html != '') { |
|||
$pos != '' && $pos = '_' . $pos; |
|||
$this->_vars['extra_html' . $pos] = $extra_html; |
|||
} |
|||
return $this; |
|||
} |
|||
|
|||
/** |
|||
* 添加一列 |
|||
* @param string $name 字段名称 |
|||
* @param string $title 字段别名 |
|||
* @param string $type 单元格类型 |
|||
* @param string $default 默认值 |
|||
* @param string $param 额外参数 |
|||
* @param string $class css类名 |
|||
* @param string $sortable 是否排序 |
|||
* @param int $with 列宽 |
|||
* @return $this |
|||
*/ |
|||
public function addColumn($name = '', $title = '', $type = '', $default = '', $param = '', $class = '', $sortable = 'false', $width = 0) |
|||
{ |
|||
$column = [ |
|||
'name' => $name, // 字段名称 |
|||
'title' => $title, // 字段别名 |
|||
'type' => $type, // 单元格类型 |
|||
'default' => $default, // 默认值 |
|||
'param' => $param, // 额外参数 |
|||
'class' => $class, // css类名 |
|||
'sortable' => $sortable, // 是否排序 |
|||
'width' => $width, // 列宽 |
|||
]; |
|||
|
|||
$this->_vars['columns'][] = $column; |
|||
$this->_field_name[$name] = $title; |
|||
return $this; |
|||
} |
|||
|
|||
/** |
|||
* 一次性添加多列 |
|||
* @param array $columns 数据列 |
|||
* @return $this |
|||
*/ |
|||
public function addColumns($columns = []) |
|||
{ |
|||
if (!empty($columns)) { |
|||
foreach ($columns as $column) { |
|||
call_user_func_array([$this, 'addColumn'], $column); |
|||
} |
|||
} |
|||
return $this; |
|||
} |
|||
|
|||
/** |
|||
* 设置是否显示分页 |
|||
* @param string $value 是否显示分页 true|false |
|||
* @return $this |
|||
*/ |
|||
public function setPagination($value = '') |
|||
{ |
|||
if ($value != '') { |
|||
$this->_vars['pagination'] = $value; |
|||
} |
|||
return $this; |
|||
} |
|||
|
|||
/** |
|||
* 设置列表树父ID |
|||
* @param string $value 字段 |
|||
* @return $this |
|||
*/ |
|||
public function setParentIdField($value = '') |
|||
{ |
|||
if ($value != '') { |
|||
$this->_vars['parent_id_field'] = $value; |
|||
} |
|||
return $this; |
|||
} |
|||
|
|||
/** |
|||
* 设置空数据提示信息 |
|||
* @param string $value 字段 |
|||
* @return $this |
|||
*/ |
|||
public function setEmptyTips($value = '') |
|||
{ |
|||
if ($value != '') { |
|||
$this->_vars['empty_tips'] = $value; |
|||
} |
|||
return $this; |
|||
} |
|||
|
|||
/** |
|||
* 设置每页显示的行数 |
|||
* @param string $value 数量 |
|||
* @return $this |
|||
*/ |
|||
public function setPageSize($value = '') |
|||
{ |
|||
if ($value != '') { |
|||
$this->_vars['page_size'] = $value; |
|||
} |
|||
return $this; |
|||
} |
|||
|
|||
/** |
|||
* 隐藏第一列多选框(默认显示,多选列多用于批量删除等操作) |
|||
* @return $this |
|||
*/ |
|||
public function hideCheckbox() |
|||
{ |
|||
$this->_vars['hide_checkbox'] = true; |
|||
return $this; |
|||
} |
|||
|
|||
/** |
|||
* 添加一个右侧按钮 |
|||
* @param string $type 按钮类型:edit/delete/default |
|||
* @param array $attribute 按钮属性 |
|||
* @param array $extra 扩展参数(待用) |
|||
* @return $this |
|||
*/ |
|||
public function addRightButton($type = '', $attribute = []) |
|||
{ |
|||
switch ($type) { |
|||
// 预览按钮 |
|||
case 'preview': |
|||
// 默认属性 |
|||
$btn_attribute = [ |
|||
'type' => 'preview', |
|||
'title' => '预览', |
|||
'icon' => 'fa fa-eye', |
|||
'class' => 'btn btn-success btn-xs', |
|||
'href' => url('index/preview', ['module' => Request::controller(), 'id' => '__id__']), |
|||
'target' => '_blank' |
|||
]; |
|||
break; |
|||
|
|||
// 编辑按钮 |
|||
case 'edit': |
|||
// 默认属性 |
|||
$btn_attribute = [ |
|||
'type' => 'edit', |
|||
'title' => '编辑', |
|||
'icon' => 'fa fa-edit', |
|||
'class' => 'btn btn-primary btn-xs', |
|||
]; |
|||
break; |
|||
|
|||
// 删除按钮(不可恢复) |
|||
case 'delete': |
|||
// 默认属性 |
|||
$btn_attribute = [ |
|||
'type' => 'delete', |
|||
'title' => '删除', |
|||
'icon' => 'far fa-trash-alt', |
|||
'class' => 'btn btn-danger btn-xs confirm', |
|||
]; |
|||
break; |
|||
|
|||
// 自定义按钮 |
|||
default: |
|||
// 默认属性 |
|||
$btn_attribute = [ |
|||
'title' => '自定义按钮', |
|||
'icon' => 'fa fa-smile-o', |
|||
'class' => 'btn btn-flat btn-default btn-xs', |
|||
'href' => 'javascript:void(0);' |
|||
]; |
|||
break; |
|||
} |
|||
// 合并自定义属性 |
|||
if ($attribute && is_array($attribute)) { |
|||
$btn_attribute = array_merge($btn_attribute, $attribute); |
|||
} |
|||
|
|||
$this->_vars['right_buttons'][] = $btn_attribute; |
|||
return $this; |
|||
} |
|||
|
|||
/** |
|||
* 添加多个右侧按钮 |
|||
* @param array|string $buttons 按钮类型 |
|||
* 例如: |
|||
* $builder->addRightButtons('edit'); |
|||
* $builder->addRightButtons('edit,delete'); |
|||
* $builder->addRightButtons(['edit', 'delete']); |
|||
* $builder->addRightButtons(['edit' => ['title' => '查看'], 'delete']); |
|||
* @return $this |
|||
*/ |
|||
public function addRightButtons($buttons = []) |
|||
{ |
|||
if (!empty($buttons)) { |
|||
$buttons = is_array($buttons) ? $buttons : explode(',', $buttons); |
|||
foreach ($buttons as $key => $value) { |
|||
if (is_numeric($key)) { |
|||
$this->addRightButton($value); |
|||
} else { |
|||
$this->addRightButton(trim($key), $value); |
|||
} |
|||
} |
|||
} |
|||
return $this; |
|||
} |
|||
|
|||
/** |
|||
* 设置表格URL |
|||
* @param string $url url地址 |
|||
* @return $this |
|||
*/ |
|||
public function setDataUrl($url = '') |
|||
{ |
|||
if ($url != '') { |
|||
$this->_vars['data_url'] = $url; |
|||
} |
|||
return $this; |
|||
} |
|||
|
|||
/** |
|||
* 设置表格默认的新增地址 |
|||
* @param string $url url地址 |
|||
* @return $this |
|||
*/ |
|||
public function setAddUrl($url = '') |
|||
{ |
|||
if ($url != '') { |
|||
$this->_vars['add_url'] = $url; |
|||
} |
|||
return $this; |
|||
} |
|||
|
|||
/** |
|||
* 设置表格默认的修改地址 |
|||
* @param string $url url地址 |
|||
* @return $this |
|||
*/ |
|||
public function setEditUrl($url = '') |
|||
{ |
|||
if ($url != '') { |
|||
$this->_vars['edit_url'] = $url; |
|||
} |
|||
return $this; |
|||
} |
|||
|
|||
/** |
|||
* 设置表格默认的删除地址 |
|||
* @param string $url url地址 |
|||
* @return $this |
|||
*/ |
|||
public function setDelUrl($url = '') |
|||
{ |
|||
if ($url != '') { |
|||
$this->_vars['del_url'] = $url; |
|||
} |
|||
return $this; |
|||
} |
|||
|
|||
/** |
|||
* 设置表格默认的导出地址 |
|||
* @param string $url url地址 |
|||
* @return $this |
|||
*/ |
|||
public function setExportUrl($url = '') |
|||
{ |
|||
if ($url != '') { |
|||
$this->_vars['export_url'] = $url; |
|||
} |
|||
return $this; |
|||
} |
|||
|
|||
/** |
|||
* 设置表格默认的更改排序地址 |
|||
* @param string $url url地址 |
|||
* @return $this |
|||
*/ |
|||
public function setSortUrl($url = '') |
|||
{ |
|||
if ($url != '') { |
|||
$this->_vars['sort_url'] = $url; |
|||
} |
|||
return $this; |
|||
} |
|||
|
|||
/** |
|||
* 设置搜索参数 |
|||
* @param array $items |
|||
* @return $this |
|||
* 第一个参数:类型 |
|||
* 第二个参数:字段名称 |
|||
* 第三个参数:字段别名 |
|||
* 第四个参数:匹配方式(默认为'=',也可以是'<>,>,>=,<,<=,LIKE'等等) |
|||
* 第五个参数:默认值 |
|||
* 第六个参数:额外参数(不同类型,用途不同) |
|||
*/ |
|||
public function setSearch($items = []) |
|||
{ |
|||
if (!empty($items)) { |
|||
foreach ($items as &$item) { |
|||
$item['type'] = $item[0] ?? ''; // 字段类型 |
|||
$item['name'] = $item[1] ?? ''; // 字段名称 |
|||
$item['title'] = $item[2] ?? ''; // 字段别名 |
|||
$item['option'] = $item[3] ?? '='; // 匹配方式 |
|||
$item['default'] = $item[4] ?? ''; // 默认值 |
|||
$item['param'] = $item[5] ?? []; // 额外参数 |
|||
$item['data_source'] = $item[6] ?? 0; // 数据源 [0 字段本身, 1 系统字典, 2 模型数据] |
|||
$item['relation_model'] = $item[7] ?? ''; // 模型关联 |
|||
$item['relation_field'] = $item[8] ?? ''; // 关联字段 |
|||
$item['field_id'] = $item[9] ?? 0; // 字段编号 |
|||
} |
|||
$this->_vars['search'] = $items; |
|||
} |
|||
return $this; |
|||
} |
|||
|
|||
/** |
|||
* 添加一个顶部按钮 |
|||
* @param string $type 按钮类型:add/edit/del/export/build/default |
|||
* @param array $attribute 按钮属性 |
|||
* @return $this |
|||
*/ |
|||
public function addTopButton($type = '', $attribute = []) |
|||
{ |
|||
switch ($type) { |
|||
|
|||
// 新增按钮 |
|||
case 'add': |
|||
// 默认属性 |
|||
$btn_attribute = [ |
|||
'title' => '新增', |
|||
'icon' => 'fa fa-plus', |
|||
'class' => 'btn btn-success', |
|||
'href' => '', |
|||
'onclick' => '$.operate.add()', |
|||
]; |
|||
break; |
|||
|
|||
// 修改按钮 |
|||
case 'edit': |
|||
// 默认属性 |
|||
$btn_attribute = [ |
|||
'title' => '修改', |
|||
'icon' => 'fa fa-edit', |
|||
'class' => 'btn btn-primary single disabled', |
|||
'href' => '', |
|||
'onclick' => '$.operate.edit()', |
|||
]; |
|||
break; |
|||
|
|||
// 删除按钮 |
|||
case 'del': |
|||
// 默认属性 |
|||
$btn_attribute = [ |
|||
'title' => '删除', |
|||
'icon' => 'fa fa-times', |
|||
'class' => 'btn btn-danger multiple disabled', |
|||
'href' => '', |
|||
'onclick' => '$.operate.removeAll()' |
|||
]; |
|||
break; |
|||
|
|||
// 导出按钮 |
|||
case 'export': |
|||
// 默认属性 |
|||
$btn_attribute = [ |
|||
'title' => '导出', |
|||
'icon' => 'fa fa-download', |
|||
'class' => 'btn btn-warning', |
|||
'href' => '', |
|||
'onclick' => '$.table.export()' |
|||
]; |
|||
break; |
|||
|
|||
// 生成按钮 |
|||
case 'build': |
|||
// 默认属性 |
|||
$btn_attribute = [ |
|||
'title' => '代码生成', |
|||
'icon' => 'fa fa-code', |
|||
'class' => 'btn btn-info single disabled', |
|||
'href' => '', |
|||
'onclick' => '$.operate.build(\'\', \'' . url('module/build') . '\')', |
|||
'group' => [ |
|||
'class' => 'btn-info single disabled', // 下拉分组组样式 |
|||
'menus' => [ // 下拉分组数据(内容同按钮一样) |
|||
[ |
|||
'title' => '生成验证器', |
|||
'icon' => '', |
|||
'class' => 'btn btn-info', |
|||
'href' => '', |
|||
'onclick' => '$.operate.build(\'\', \'' . url('module/build', ['file' => 'validate']) . '\')', |
|||
], |
|||
[ |
|||
'title' => '生成模型', |
|||
'icon' => '', |
|||
'class' => 'btn btn-info', |
|||
'href' => '', |
|||
'onclick' => '$.operate.build(\'\', \'' . url('module/build', ['file' => 'model']) . '\')', |
|||
], |
|||
[ |
|||
'title' => '生成控制器', |
|||
'icon' => '', |
|||
'class' => 'btn btn-info', |
|||
'href' => '', |
|||
'onclick' => '$.operate.build(\'\', \'' . url('module/build', ['file' => 'controller']) . '\')', |
|||
], |
|||
], |
|||
] |
|||
]; |
|||
break; |
|||
|
|||
// 自定义按钮 |
|||
default: |
|||
// 默认属性 |
|||
$btn_attribute = [ |
|||
'title' => '自定义', |
|||
'icon' => 'fa fa-lightbulb', |
|||
'class' => 'btn btn-default', |
|||
'href' => '', |
|||
'onclick' => '' |
|||
]; |
|||
break; |
|||
} |
|||
|
|||
// 合并自定义属性 |
|||
if ($attribute && is_array($attribute)) { |
|||
$btn_attribute = array_merge($btn_attribute, $attribute); |
|||
} |
|||
$this->_vars['top_buttons'][] = $btn_attribute; |
|||
return $this; |
|||
} |
|||
|
|||
/** |
|||
* 一次性添加多个顶部按钮 |
|||
* @param array|string $buttons 按钮组 |
|||
* 例如: |
|||
* addTopButtons('add') |
|||
* addTopButtons('add, edit, del') |
|||
* addTopButtons(['add', 'del']) |
|||
* addTopButtons(['add' => ['title' => '增加'], 'del']) |
|||
* @return $this |
|||
*/ |
|||
public function addTopButtons($buttons = []) |
|||
{ |
|||
if (!empty($buttons)) { |
|||
$buttons = is_array($buttons) ? $buttons : explode(',', $buttons); |
|||
foreach ($buttons as $key => $value) { |
|||
if (is_numeric($key)) { |
|||
// key为数字则直接添加一个按钮 |
|||
$this->addTopButton($value); |
|||
} else { |
|||
// key不为数字则需设置属性,去除前后空格 |
|||
$this->addTopButton(trim($key), $value); |
|||
} |
|||
} |
|||
} |
|||
return $this; |
|||
} |
|||
|
|||
/** |
|||
* 设置是否在添加/编辑等页启用layer弹层加载 |
|||
* @param string $value 是否启用layer true|false |
|||
* @return $this |
|||
*/ |
|||
public function setLayerOpen($value = true) |
|||
{ |
|||
$this->_vars['layer_open'] = $value; |
|||
return $this; |
|||
} |
|||
|
|||
/** |
|||
* 设置左侧固定列数 |
|||
* @param string $value 列数 |
|||
* @return $this |
|||
*/ |
|||
public function setFixedLeft($value = 1) |
|||
{ |
|||
$this->_vars['fixed_left'] = $value; |
|||
return $this; |
|||
} |
|||
|
|||
/** |
|||
* 设置右侧固定列数 |
|||
* @param string $value 列数 |
|||
* @return $this |
|||
*/ |
|||
public function setFixedRight($value = 1) |
|||
{ |
|||
$this->_vars['fixed_right'] = $value; |
|||
return $this; |
|||
} |
|||
} |
|||
@ -0,0 +1,47 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | {$comment}控制器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: {$author} |
|||
* ::::::::::: | EMAIL: {$email} |
|||
* ..:::::::::::' | DATETIME: {$dateTime} |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\controller; |
|||
|
|||
// 引入框架内置类 |
|||
use think\facade\Request; |
|||
|
|||
// 引入表格和表单构建器 |
|||
use app\common\facade\MakeBuilder; |
|||
use app\common\builder\FormBuilder; |
|||
use app\common\builder\TableBuilder; |
|||
|
|||
class {$modelName} extends Base |
|||
{ |
|||
// 验证器 |
|||
protected $validate = '{$validate}'; |
|||
|
|||
// 当前主表 |
|||
protected $tableName = '{$tableName}'; |
|||
|
|||
// 当前主模型 |
|||
protected $modelName = '{$modelName}'; |
|||
|
|||
} |
|||
@ -0,0 +1,38 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | {$comment}模型 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: {$author} |
|||
* ::::::::::: | EMAIL: {$email} |
|||
* ..:::::::::::' | DATETIME: {$dateTime} |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\common\model; |
|||
|
|||
class {$modelName} extends Base |
|||
{ |
|||
// 定义时间戳字段名 |
|||
protected $createTime = 'create_time'; |
|||
protected $updateTime = 'update_time'; |
|||
|
|||
{$modulePk} |
|||
{$moduleTable} |
|||
{$relations} |
|||
|
|||
} |
|||
@ -0,0 +1,33 @@ |
|||
<?php |
|||
/** |
|||
* +---------------------------------------------------------------------- |
|||
* | {$comment}验证器 |
|||
* +---------------------------------------------------------------------- |
|||
* .::::. |
|||
* .::::::::. | AUTHOR: {$author} |
|||
* ::::::::::: | EMAIL: {$email} |
|||
* ..:::::::::::' | DATETIME: {$dateTime} |
|||
* '::::::::::::' |
|||
* .:::::::::: |
|||
* '::::::::::::::.. |
|||
* ..::::::::::::. |
|||
* ``:::::::::::::::: |
|||
* ::::``:::::::::' .:::. |
|||
* ::::' ':::::' .::::::::. |
|||
* .::::' :::: .:::::::'::::. |
|||
* .:::' ::::: .:::::::::' ':::::. |
|||
* .::' :::::.:::::::::' ':::::. |
|||
* .::' ::::::::::::::' ``::::. |
|||
* ...::: ::::::::::::' ``::. |
|||
* ```` ':. ':::::::::' ::::.. |
|||
* '.:::::' ':'````.. |
|||
* +---------------------------------------------------------------------- |
|||
*/ |
|||
namespace app\admin\validate; |
|||
|
|||
use think\Validate; |
|||
|
|||
class {$modelName} extends Validate |
|||
{ |
|||
{$rules} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
<?php |
|||
namespace app\common\facade; |
|||
|
|||
use think\Facade; |
|||
|
|||
class Cms extends Facade |
|||
{ |
|||
protected static function getFacadeClass() |
|||
{ |
|||
return 'app\common\service\Cms'; |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
<?php |
|||
namespace app\common\facade; |
|||
|
|||
use think\Facade; |
|||
|
|||
class MakeBuilder extends Facade |
|||
{ |
|||
protected static function getFacadeClass() |
|||
{ |
|||
return 'app\common\builder\MakeBuilder'; |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
<?php |
|||
namespace app\common\facade; |
|||
|
|||
use think\Facade; |
|||
|
|||
class User extends Facade |
|||
{ |
|||
protected static function getFacadeClass() |
|||
{ |
|||
return 'app\common\service\User'; |
|||
} |
|||
} |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue