mirror of
				https://github.com/nsnail/NetAdmin.git
				synced 2025-11-01 03:35:28 +08:00 
			
		
		
		
	feat: ✨ 版本更新日志组件 (#96)
This commit is contained in:
		| @@ -1,35 +1,83 @@ | |||||||
| <wpf:ResourceDictionary xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xml:space="preserve"> | <wpf:ResourceDictionary xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xml:space="preserve"> | ||||||
|     <s:String x:Key="/Default/CodeEditing/GenerateMemberBody/DocumentationGenerationKind/@EntryValue">Inherit</s:String> |  | ||||||
|     <s:Boolean x:Key="/Default/CodeEditing/TypingAssist/SkipClosingBracesOnTabInStringLiterals/@EntryValue">True</s:Boolean> |     <s:Boolean x:Key="/Default/CodeEditing/TypingAssist/SkipClosingBracesOnTabInStringLiterals/@EntryValue">True</s:Boolean> | ||||||
|     <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=AssignmentInConditionalExpression/@EntryIndexedValue">DO_NOT_SHOW</s:String> |     <s:Boolean x:Key="/Default/CodeInspection/ExcludedFiles/FileMasksToSkip/=_002A_002Ett/@EntryIndexedValue">True</s:Boolean> | ||||||
|     <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UnusedAutoPropertyAccessor_002EGlobal/@EntryIndexedValue">DO_NOT_SHOW</s:String> |  | ||||||
|     <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UnusedAutoPropertyAccessor_002ELocal/@EntryIndexedValue">DO_NOT_SHOW</s:String> |  | ||||||
|     <s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_ACCESSOR_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String> |  | ||||||
|     <s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_ACCESSORHOLDER_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String> |  | ||||||
|     <s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_FIELD_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String> |  | ||||||
|     <s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_RECORD_FIELD_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String> |  | ||||||
|     <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=ID/@EntryIndexedValue">ID</s:String> |  | ||||||
|     <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=IOS/@EntryIndexedValue">IOS</s:String> |  | ||||||
|     <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=IP/@EntryIndexedValue">IP</s:String> |  | ||||||
|     <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=TypesAndNamespaces/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb_AaBb" /></s:String> |  | ||||||
|     <s:String x:Key="/Default/CustomTools/CustomToolsData/@EntryValue"></s:String> |  | ||||||
|     <s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue">True</s:Boolean> |     <s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue">True</s:Boolean> | ||||||
|     <s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean> |     <s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean> | ||||||
|     <s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpUseContinuousIndentInsideBracesMigration/@EntryIndexedValue">True</s:Boolean> |     <s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpUseContinuousIndentInsideBracesMigration/@EntryIndexedValue">True</s:Boolean> | ||||||
|     <s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean> |     <s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean> | ||||||
|     <s:Boolean x:Key="/Default/ReSpeller/ReSpellerEnabled/@EntryValue">True</s:Boolean> |     <s:Boolean x:Key="/Default/ReSpeller/ReSpellerEnabled/@EntryValue">True</s:Boolean> | ||||||
|  |     <s:Boolean x:Key="/Default/UserDictionary/Words/=Aigc/@EntryIndexedValue">True</s:Boolean> | ||||||
|  |     <s:Boolean x:Key="/Default/UserDictionary/Words/=Biji/@EntryIndexedValue">True</s:Boolean> | ||||||
|  |     <s:Boolean x:Key="/Default/UserDictionary/Words/=Callbacked/@EntryIndexedValue">True</s:Boolean> | ||||||
|  |     <s:Boolean x:Key="/Default/UserDictionary/Words/=Callbacking/@EntryIndexedValue">True</s:Boolean> | ||||||
|  |     <s:Boolean x:Key="/Default/UserDictionary/Words/=Childs/@EntryIndexedValue">True</s:Boolean> | ||||||
|  |     <s:Boolean x:Key="/Default/UserDictionary/Words/=Cmds/@EntryIndexedValue">True</s:Boolean> | ||||||
|  |     <s:Boolean x:Key="/Default/UserDictionary/Words/=Consum/@EntryIndexedValue">True</s:Boolean> | ||||||
|  |     <s:Boolean x:Key="/Default/UserDictionary/Words/=DATEADD/@EntryIndexedValue">True</s:Boolean> | ||||||
|  |     <s:Boolean x:Key="/Default/UserDictionary/Words/=Davinci/@EntryIndexedValue">True</s:Boolean> | ||||||
|  |     <s:Boolean x:Key="/Default/UserDictionary/Words/=Deblocking/@EntryIndexedValue">True</s:Boolean> | ||||||
|  |     <s:Boolean x:Key="/Default/UserDictionary/Words/=Decaptcha/@EntryIndexedValue">True</s:Boolean> | ||||||
|  |     <s:Boolean x:Key="/Default/UserDictionary/Words/=Depts/@EntryIndexedValue">True</s:Boolean> | ||||||
|  |     <s:Boolean x:Key="/Default/UserDictionary/Words/=FFFFFF/@EntryIndexedValue">True</s:Boolean> | ||||||
|  |     <s:Boolean x:Key="/Default/UserDictionary/Words/=Furion/@EntryIndexedValue">True</s:Boolean> | ||||||
|  |     <s:Boolean x:Key="/Default/UserDictionary/Words/=GETDATE/@EntryIndexedValue">True</s:Boolean> | ||||||
|  |     <s:Boolean x:Key="/Default/UserDictionary/Words/=Haojia/@EntryIndexedValue">True</s:Boolean> | ||||||
|  |     <s:Boolean x:Key="/Default/UserDictionary/Words/=Meituan/@EntryIndexedValue">True</s:Boolean> | ||||||
|  |     <s:Boolean x:Key="/Default/UserDictionary/Words/=Responsing/@EntryIndexedValue">True</s:Boolean> | ||||||
|  |     <s:Boolean x:Key="/Default/UserDictionary/Words/=Smzdm/@EntryIndexedValue">True</s:Boolean> | ||||||
|  |     <s:Boolean x:Key="/Default/UserDictionary/Words/=Tabao/@EntryIndexedValue">True</s:Boolean> | ||||||
|  |     <s:Boolean x:Key="/Default/UserDictionary/Words/=Taobao/@EntryIndexedValue">True</s:Boolean> | ||||||
|  |     <s:Boolean x:Key="/Default/UserDictionary/Words/=Taoke/@EntryIndexedValue">True</s:Boolean> | ||||||
|  |     <s:Boolean x:Key="/Default/UserDictionary/Words/=Tese/@EntryIndexedValue">True</s:Boolean> | ||||||
|  |     <s:Boolean x:Key="/Default/UserDictionary/Words/=XBOXONE/@EntryIndexedValue">True</s:Boolean> | ||||||
|  |     <s:Boolean x:Key="/Default/UserDictionary/Words/=YYYYMMDD/@EntryIndexedValue">True</s:Boolean> | ||||||
|  |     <s:Boolean x:Key="/Default/UserDictionary/Words/=YYYYMMDDHHMMSSFFFZZZZ/@EntryIndexedValue">True</s:Boolean> | ||||||
|  |     <s:Boolean x:Key="/Default/UserDictionary/Words/=alienware/@EntryIndexedValue">True</s:Boolean> | ||||||
|  |     <s:Boolean x:Key="/Default/UserDictionary/Words/=fenlei/@EntryIndexedValue">True</s:Boolean> | ||||||
|  |     <s:Boolean x:Key="/Default/UserDictionary/Words/=hongbao/@EntryIndexedValue">True</s:Boolean> | ||||||
|  |     <s:Boolean x:Key="/Default/UserDictionary/Words/=inte/@EntryIndexedValue">True</s:Boolean> | ||||||
|  |     <s:Boolean x:Key="/Default/UserDictionary/Words/=iqoo/@EntryIndexedValue">True</s:Boolean> | ||||||
|  |     <s:Boolean x:Key="/Default/UserDictionary/Words/=logourl/@EntryIndexedValue">True</s:Boolean> | ||||||
|  |     <s:Boolean x:Key="/Default/UserDictionary/Words/=miaosha/@EntryIndexedValue">True</s:Boolean> | ||||||
|  |     <s:Boolean x:Key="/Default/UserDictionary/Words/=nicktitle/@EntryIndexedValue">True</s:Boolean> | ||||||
|  |     <s:Boolean x:Key="/Default/UserDictionary/Words/=qudao/@EntryIndexedValue">True</s:Boolean> | ||||||
|  |     <s:Boolean x:Key="/Default/UserDictionary/Words/=redbook/@EntryIndexedValue">True</s:Boolean> | ||||||
|  |     <s:Boolean x:Key="/Default/UserDictionary/Words/=tablename/@EntryIndexedValue">True</s:Boolean> | ||||||
|  |     <s:Boolean x:Key="/Default/UserDictionary/Words/=thinkpad/@EntryIndexedValue">True</s:Boolean> | ||||||
|  |     <s:Boolean x:Key="/Default/UserDictionary/Words/=timesort/@EntryIndexedValue">True</s:Boolean> | ||||||
|  |     <s:Boolean x:Key="/Default/UserDictionary/Words/=vivo/@EntryIndexedValue">True</s:Boolean> | ||||||
|  |     <s:Boolean x:Key="/Default/UserDictionary/Words/=weixin/@EntryIndexedValue">True</s:Boolean> | ||||||
|  |     <s:Boolean x:Key="/Default/UserDictionary/Words/=youhui/@EntryIndexedValue">True</s:Boolean> | ||||||
|  |     <s:Boolean x:Key="/Default/UserDictionary/Words/=yugao/@EntryIndexedValue">True</s:Boolean> | ||||||
|  |     <s:Boolean x:Key="/Default/UserDictionary/Words/=zhiyou/@EntryIndexedValue">True</s:Boolean> | ||||||
|  |     <s:Boolean x:Key="/Default/UserDictionary/Words/=zhuanlan/@EntryIndexedValue">True</s:Boolean> | ||||||
|  |  | ||||||
|     <s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_BLANK_LINES_IN_CODE/@EntryValue">1</s:Int64> |     <s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_BLANK_LINES_IN_CODE/@EntryValue">1</s:Int64> | ||||||
|     <s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_BLANK_LINES_IN_DECLARATIONS/@EntryValue">1</s:Int64> |     <s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_BLANK_LINES_IN_DECLARATIONS/@EntryValue">1</s:Int64> | ||||||
|  |  | ||||||
|  |     <s:String x:Key="/Default/CodeEditing/GenerateMemberBody/DocumentationGenerationKind/@EntryValue">Inherit</s:String> | ||||||
|     <s:String x:Key="/Default/CodeInspection/Highlighting/AnalysisEnabled/@EntryValue">OFF</s:String> |     <s:String x:Key="/Default/CodeInspection/Highlighting/AnalysisEnabled/@EntryValue">OFF</s:String> | ||||||
|  |     <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=AssignmentInConditionalExpression/@EntryIndexedValue">DO_NOT_SHOW</s:String> | ||||||
|  |     <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ClassNeverInstantiated_002EGlobal/@EntryIndexedValue">DO_NOT_SHOW</s:String> | ||||||
|  |     <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=DuplicateResource/@EntryIndexedValue">DO_NOT_SHOW</s:String> | ||||||
|  |     <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantPatternParentheses/@EntryIndexedValue">DO_NOT_SHOW</s:String> | ||||||
|  |     <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SuggestBaseTypeForParameter/@EntryIndexedValue">DO_NOT_SHOW</s:String> | ||||||
|  |     <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SuggestBaseTypeForParameterInConstructor/@EntryIndexedValue">DO_NOT_SHOW</s:String> | ||||||
|     <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=TooWideLocalVariableScope/@EntryIndexedValue">HINT</s:String> |     <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=TooWideLocalVariableScope/@EntryIndexedValue">HINT</s:String> | ||||||
|  |     <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UnusedAutoPropertyAccessor_002EGlobal/@EntryIndexedValue">DO_NOT_SHOW</s:String> | ||||||
|  |     <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UnusedAutoPropertyAccessor_002ELocal/@EntryIndexedValue">DO_NOT_SHOW</s:String> | ||||||
|     <s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_FOR/@EntryValue">Required</s:String> |     <s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_FOR/@EntryValue">Required</s:String> | ||||||
|     <s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_FOREACH/@EntryValue">Required</s:String> |     <s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_FOREACH/@EntryValue">Required</s:String> | ||||||
|     <s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_IFELSE/@EntryValue">Required</s:String> |     <s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_IFELSE/@EntryValue">Required</s:String> | ||||||
|     <s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_WHILE/@EntryValue">Required</s:String> |     <s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_WHILE/@EntryValue">Required</s:String> | ||||||
|  |     <s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_ACCESSORHOLDER_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String> | ||||||
|     <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=Constants/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AA_BB" /></s:String> |     <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=Constants/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AA_BB" /></s:String> | ||||||
|     <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateConstants/@EntryIndexedValue"><Policy Inspect="True" Prefix="_" Suffix="" Style="AA_BB" /></s:String> |     <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateConstants/@EntryIndexedValue"><Policy Inspect="True" Prefix="_" Suffix="" Style="AA_BB" /></s:String> | ||||||
|     <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticReadonly/@EntryIndexedValue"><Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /></s:String> |     <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticReadonly/@EntryIndexedValue"><Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /></s:String> | ||||||
|     <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=StaticReadonly/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String> |     <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=StaticReadonly/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String> | ||||||
|  |     <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=TypesAndNamespaces/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb_AaBb" /></s:String> | ||||||
|  |  | ||||||
|  |  | ||||||
|     <s:String x:Key="/Default/CodeStyle/CSharpFileLayoutPatterns/Pattern/@EntryValue"><?xml version="1.0" encoding="utf-16"?> |     <s:String x:Key="/Default/CodeStyle/CSharpFileLayoutPatterns/Pattern/@EntryValue"><?xml version="1.0" encoding="utf-16"?> | ||||||
| <Patterns xmlns="urn:schemas-jetbrains-com:member-reordering-patterns"> | <Patterns xmlns="urn:schemas-jetbrains-com:member-reordering-patterns"> | ||||||
|     <TypePattern> |     <TypePattern> | ||||||
| @@ -70,36 +118,4 @@ | |||||||
|         </Entry> |         </Entry> | ||||||
|     </TypePattern> |     </TypePattern> | ||||||
| </Patterns></s:String> | </Patterns></s:String> | ||||||
|     <s:Boolean x:Key="/Default/UserDictionary/Words/=Aigc/@EntryIndexedValue">True</s:Boolean> |  | ||||||
|     <s:Boolean x:Key="/Default/UserDictionary/Words/=Biji/@EntryIndexedValue">True</s:Boolean> |  | ||||||
|     <s:Boolean x:Key="/Default/UserDictionary/Words/=Childs/@EntryIndexedValue">True</s:Boolean> |  | ||||||
|     <s:Boolean x:Key="/Default/UserDictionary/Words/=Depts/@EntryIndexedValue">True</s:Boolean> |  | ||||||
|     <s:Boolean x:Key="/Default/UserDictionary/Words/=fenlei/@EntryIndexedValue">True</s:Boolean> |  | ||||||
|     <s:Boolean x:Key="/Default/UserDictionary/Words/=FFFFFF/@EntryIndexedValue">True</s:Boolean> |  | ||||||
|     <s:Boolean x:Key="/Default/UserDictionary/Words/=Furion/@EntryIndexedValue">True</s:Boolean> |  | ||||||
|     <s:Boolean x:Key="/Default/UserDictionary/Words/=Haojia/@EntryIndexedValue">True</s:Boolean> |  | ||||||
|     <s:Boolean x:Key="/Default/UserDictionary/Words/=hongbao/@EntryIndexedValue">True</s:Boolean> |  | ||||||
|     <s:Boolean x:Key="/Default/UserDictionary/Words/=inte/@EntryIndexedValue">True</s:Boolean> |  | ||||||
|     <s:Boolean x:Key="/Default/UserDictionary/Words/=logourl/@EntryIndexedValue">True</s:Boolean> |  | ||||||
|     <s:Boolean x:Key="/Default/UserDictionary/Words/=Meituan/@EntryIndexedValue">True</s:Boolean> |  | ||||||
|     <s:Boolean x:Key="/Default/UserDictionary/Words/=miaosha/@EntryIndexedValue">True</s:Boolean> |  | ||||||
|     <s:Boolean x:Key="/Default/UserDictionary/Words/=nicktitle/@EntryIndexedValue">True</s:Boolean> |  | ||||||
|     <s:Boolean x:Key="/Default/UserDictionary/Words/=qudao/@EntryIndexedValue">True</s:Boolean> |  | ||||||
|     <s:Boolean x:Key="/Default/UserDictionary/Words/=Responsing/@EntryIndexedValue">True</s:Boolean> |  | ||||||
|     <s:Boolean x:Key="/Default/UserDictionary/Words/=Smzdm/@EntryIndexedValue">True</s:Boolean> |  | ||||||
|     <s:Boolean x:Key="/Default/UserDictionary/Words/=Tabao/@EntryIndexedValue">True</s:Boolean> |  | ||||||
|     <s:Boolean x:Key="/Default/UserDictionary/Words/=tablename/@EntryIndexedValue">True</s:Boolean> |  | ||||||
|     <s:Boolean x:Key="/Default/UserDictionary/Words/=Taobao/@EntryIndexedValue">True</s:Boolean> |  | ||||||
|     <s:Boolean x:Key="/Default/UserDictionary/Words/=Taoke/@EntryIndexedValue">True</s:Boolean> |  | ||||||
|     <s:Boolean x:Key="/Default/UserDictionary/Words/=Tese/@EntryIndexedValue">True</s:Boolean> |  | ||||||
|     <s:Boolean x:Key="/Default/UserDictionary/Words/=timesort/@EntryIndexedValue">True</s:Boolean> |  | ||||||
|     <s:Boolean x:Key="/Default/UserDictionary/Words/=weixin/@EntryIndexedValue">True</s:Boolean> |  | ||||||
|     <s:Boolean x:Key="/Default/UserDictionary/Words/=XBOXONE/@EntryIndexedValue">True</s:Boolean> |  | ||||||
|     <s:Boolean x:Key="/Default/UserDictionary/Words/=youhui/@EntryIndexedValue">True</s:Boolean> |  | ||||||
|     <s:Boolean x:Key="/Default/UserDictionary/Words/=yugao/@EntryIndexedValue">True</s:Boolean> |  | ||||||
|     <s:Boolean x:Key="/Default/UserDictionary/Words/=YYYYMMDD/@EntryIndexedValue">True</s:Boolean> |  | ||||||
|     <s:Boolean x:Key="/Default/UserDictionary/Words/=YYYYMMDDHHMMSSFFFZZZZ/@EntryIndexedValue">True</s:Boolean> |  | ||||||
|     <s:Boolean x:Key="/Default/UserDictionary/Words/=zhiyou/@EntryIndexedValue">True</s:Boolean> |  | ||||||
|     <s:Boolean x:Key="/Default/UserDictionary/Words/=zhuanlan/@EntryIndexedValue">True</s:Boolean> |  | ||||||
|  |  | ||||||
| </wpf:ResourceDictionary> | </wpf:ResourceDictionary> | ||||||
| @@ -140,17 +140,6 @@ | |||||||
|     "Title": "缓存管理", |     "Title": "缓存管理", | ||||||
|     "Type": 1 |     "Type": 1 | ||||||
|   }, |   }, | ||||||
|   { |  | ||||||
|     "Component": "home/widgets/components/ver", |  | ||||||
|     "Icon": "el-icon-pointer", |  | ||||||
|     "Id": 480998862188554, |  | ||||||
|     "Name": "sys-about", |  | ||||||
|     "ParentId": 485278637670422, |  | ||||||
|     "Path": "/sys/about", |  | ||||||
|     "Sort": 94, |  | ||||||
|     "Title": "版本信息", |  | ||||||
|     "Type": 1, |  | ||||||
|   }, |  | ||||||
|   // ------------------------------  日志管理 ------------------------------ |   // ------------------------------  日志管理 ------------------------------ | ||||||
|   { |   { | ||||||
|     "Icon": "el-icon-tickets", |     "Icon": "el-icon-tickets", | ||||||
|   | |||||||
| @@ -13,10 +13,8 @@ git checkout main | |||||||
| git branch -D release | git branch -D release | ||||||
| git checkout -b release | git checkout -b release | ||||||
| ./node_modules/.bin/standard-version -r $types[$prefix][0] | ./node_modules/.bin/standard-version -r $types[$prefix][0] | ||||||
| cd ./scripts |  | ||||||
| ./code.clean.ps1 |  | ||||||
| git commit --amend --no-edit -a | git commit --amend --no-edit -a | ||||||
| $tag = $(git describe --tags $(git rev-list --tags --max-count=1)) | $tag = $( git describe --tags $( git rev-list --tags --max-count = 1 ) ) | ||||||
| git tag -d $tag | git tag -d $tag | ||||||
| git tag $tag | git tag $tag | ||||||
| git push --tags origin release | git push --tags origin release | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| npm --prefix ../src/frontend/admin run prettier | npm --prefix ../src/frontend/admin run prettier | ||||||
| dotnet jb cleanupcode --no-build --include=$($(git status --porcelain | Where-Object { $_ -match "^\s*[MA]" } | ForEach-Object { $_.TrimStart(" M").TrimStart(" A") }) -join ";") ../NetAdmin.sln | jb cleanupcode --no-build --include=$($(git status --porcelain | Where-Object { $_ -match "^\s*[MA]" } | ForEach-Object { $_.TrimStart(" M").TrimStart(" A") }) -join ";") ../NetAdmin.sln | ||||||
| dot rbom -w -e refs -e .git -e node_modules ../ | dot rbom -w -e refs -e .git -e node_modules ../ | ||||||
| dot trim -w -e refs -e .git -e node_modules ../ | dot trim -w -e refs -e .git -e node_modules ../ | ||||||
| dot tolf -w -e refs -e .git -e node_modules ../ | dot tolf -w -e refs -e .git -e node_modules ../ | ||||||
| @@ -1,4 +1,4 @@ | |||||||
| #r "nuget: NSExt, 1.1.0" | #r "nuget: NSExt, 2.1.0" | ||||||
| using NSExt.Extensions; | using NSExt.Extensions; | ||||||
|  |  | ||||||
| Console.WriteLine("请输入原始名称(NetAdmin):"); | Console.WriteLine("请输入原始名称(NetAdmin):"); | ||||||
|   | |||||||
| @@ -1 +1 @@ | |||||||
| dotnet jb cleanupcode --no-build ../NetAdmin.sln | jb cleanupcode --no-build ../NetAdmin.sln | ||||||
| @@ -9,7 +9,7 @@ | |||||||
|       "packages": [ |       "packages": [ | ||||||
|         { |         { | ||||||
|           "packageName": "NSExt", |           "packageName": "NSExt", | ||||||
|           "version": "1.1.0" |           "version": "2.1.0" | ||||||
|         } |         } | ||||||
|       ] |       ] | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -23,5 +23,5 @@ while ($null -eq $files[[int]$file - 1]) | |||||||
| } | } | ||||||
| $file = [int]$file - 1 | $file = [int]$file - 1 | ||||||
| Copy-Item $files[$file] 'switcher.json' -Force | Copy-Item $files[$file] 'switcher.json' -Force | ||||||
| dotnet dnt $targets[$key] ../NetAdmin.sln | dnt $targets[$key] ../NetAdmin.sln | ||||||
| Remove-Item switcher.json | Remove-Item switcher.json | ||||||
| @@ -2,6 +2,7 @@ | |||||||
|     <Import Project="$(SolutionDir)/build/code.quality.props"/> |     <Import Project="$(SolutionDir)/build/code.quality.props"/> | ||||||
|     <ItemGroup> |     <ItemGroup> | ||||||
|         <EmbeddedResource Include="$(SolutionDir)/assets/captcha/**" LinkBase="Assets/Captcha"/> |         <EmbeddedResource Include="$(SolutionDir)/assets/captcha/**" LinkBase="Assets/Captcha"/> | ||||||
|  |         <EmbeddedResource Include="$(SolutionDir)/CHANGELOG.md" LogicalName="CHANGELOG.md"/> | ||||||
|     </ItemGroup> |     </ItemGroup> | ||||||
|     <ItemGroup> |     <ItemGroup> | ||||||
|         <ProjectReference Include="../NetAdmin.SysComponent.Host/NetAdmin.SysComponent.Host.csproj"/> |         <ProjectReference Include="../NetAdmin.SysComponent.Host/NetAdmin.SysComponent.Host.csproj"/> | ||||||
|   | |||||||
| @@ -19,8 +19,8 @@ namespace NetAdmin.BizServer.Tests; | |||||||
| ///     所有测试 | ///     所有测试 | ||||||
| /// </summary> | /// </summary> | ||||||
| [SuppressMessage("Usage", "xUnit1028:Test method must have valid return type")] | [SuppressMessage("Usage", "xUnit1028:Test method must have valid return type")] | ||||||
| public class AllTests(WebApplicationFactory<Startup> factory, ITestOutputHelper testOutputHelper) | public class AllTests(WebApplicationFactory<Startup> factory, ITestOutputHelper testOutputHelper) : | ||||||
|     : WebApiTestBase<Startup>(factory, testOutputHelper), IToolsModule, ICacheModule, IApiModule, IConfigModule |     WebApiTestBase<Startup>(factory, testOutputHelper), IToolsModule, ICacheModule, IApiModule, IConfigModule | ||||||
|  |  | ||||||
| { | { | ||||||
|     /// <inheritdoc cref="ICrudModule{TCreateReq,TCreateRsp,TQueryReq,TQueryRsp,TUpdateReq,TUpdateRsp,TDelReq}.BulkDeleteAsync" /> |     /// <inheritdoc cref="ICrudModule{TCreateReq,TCreateRsp,TQueryReq,TQueryRsp,TUpdateReq,TUpdateRsp,TDelReq}.BulkDeleteAsync" /> | ||||||
| @@ -92,6 +92,12 @@ public class AllTests(WebApplicationFactory<Startup> factory, ITestOutputHelper | |||||||
|         throw new NotImplementedException(); |         throw new NotImplementedException(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// <inheritdoc /> | ||||||
|  |     public Task<string> GetChangeLogAsync() | ||||||
|  |     { | ||||||
|  |         throw new NotImplementedException(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /// <inheritdoc /> |     /// <inheritdoc /> | ||||||
|     public Task<QueryConfigRsp> GetLatestConfigAsync() |     public Task<QueryConfigRsp> GetLatestConfigAsync() | ||||||
|     { |     { | ||||||
|   | |||||||
| @@ -18,7 +18,7 @@ public sealed class UserIdAttribute : ValidationAttribute | |||||||
|         var req = new QueryReq<QueryUserReq> { Filter = new QueryUserReq { Id = (long)value! } }; |         var req = new QueryReq<QueryUserReq> { Filter = new QueryUserReq { Id = (long)value! } }; | ||||||
|  |  | ||||||
|         var method = service.GetType().GetMethod("ExistAsync"); |         var method = service.GetType().GetMethod("ExistAsync"); | ||||||
|         var exist  = ((Task<bool>)method!.Invoke(service, [req]))!.ConfigureAwait(false).GetAwaiter().GetResult(); |         var exist  = (Task<bool>)method!.Invoke(service, [req])!.ConfigureAwait(false).GetAwaiter().GetResult(); | ||||||
|         return !exist ? new ValidationResult(Ln.用户编号不存在) : ValidationResult.Success; |         return !exist ? new ValidationResult(Ln.用户编号不存在) : ValidationResult.Success; | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -18,7 +18,8 @@ public sealed record SqlCommandAfterEvent : SqlCommandBeforeEvent | |||||||
|     /// <summary> |     /// <summary> | ||||||
|     ///     耗时(单位:微秒) |     ///     耗时(单位:微秒) | ||||||
|     /// </summary> |     /// </summary> | ||||||
|     public long ElapsedMicroseconds { get; init; } |     /// de | ||||||
|  |     private long ElapsedMicroseconds { get; } | ||||||
|  |  | ||||||
|     /// <inheritdoc /> |     /// <inheritdoc /> | ||||||
|     public override string ToString() |     public override string ToString() | ||||||
|   | |||||||
| @@ -3,12 +3,15 @@ namespace NetAdmin.Domain.Events; | |||||||
| /// <summary> | /// <summary> | ||||||
| ///     Sql命令事件 | ///     Sql命令事件 | ||||||
| /// </summary> | /// </summary> | ||||||
| public record SqlCommandEvent : DataAbstraction, IEventSource | public abstract record SqlCommandEvent : DataAbstraction, IEventSource | ||||||
| { | { | ||||||
|     /// <summary> |     /// <summary> | ||||||
|     ///     标识符缩写 |     ///     Initializes a new instance of the <see cref="SqlCommandEvent" /> class. | ||||||
|     /// </summary> |     /// </summary> | ||||||
|     public string Id => Identifier.ToString()[..8].ToUpperInvariant(); |     protected SqlCommandEvent(bool isConsumOnce = false) | ||||||
|  |     { | ||||||
|  |         IsConsumOnce = isConsumOnce; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /// <inheritdoc /> |     /// <inheritdoc /> | ||||||
|     public bool IsConsumOnce { get; } |     public bool IsConsumOnce { get; } | ||||||
| @@ -22,16 +25,21 @@ public record SqlCommandEvent : DataAbstraction, IEventSource | |||||||
|     /// <inheritdoc /> |     /// <inheritdoc /> | ||||||
|     public string EventId { get; protected init; } |     public string EventId { get; protected init; } | ||||||
|  |  | ||||||
|     /// <summary> |  | ||||||
|     ///     标识符,可将 CommandBefore 与 CommandAfter 进行匹配 |  | ||||||
|     /// </summary> |  | ||||||
|     public Guid Identifier { get; protected init; } |  | ||||||
|  |  | ||||||
|     /// <inheritdoc /> |     /// <inheritdoc /> | ||||||
|     public object Payload { get; init; } |     public object Payload { get; init; } | ||||||
|  |  | ||||||
|  |     /// <summary> | ||||||
|  |     ///     标识符缩写 | ||||||
|  |     /// </summary> | ||||||
|  |     protected string Id => Identifier.ToString()[..8].ToUpperInvariant(); | ||||||
|  |  | ||||||
|  |     /// <summary> | ||||||
|  |     ///     标识符,可将 CommandBefore 与 CommandAfter 进行匹配 | ||||||
|  |     /// </summary> | ||||||
|  |     protected Guid Identifier { get; init; } | ||||||
|  |  | ||||||
|     /// <summary> |     /// <summary> | ||||||
|     ///     关联的Sql语句 |     ///     关联的Sql语句 | ||||||
|     /// </summary> |     /// </summary> | ||||||
|     public string Sql { get; protected init; } |     protected string Sql { get; init; } | ||||||
| } | } | ||||||
| @@ -19,7 +19,7 @@ public record SyncStructureBeforeEvent : SqlCommandEvent | |||||||
|     /// <summary> |     /// <summary> | ||||||
|     ///     实体类型 |     ///     实体类型 | ||||||
|     /// </summary> |     /// </summary> | ||||||
|     public Type[] EntityTypes { get; } |     protected Type[] EntityTypes { get; } | ||||||
|  |  | ||||||
|     /// <inheritdoc /> |     /// <inheritdoc /> | ||||||
|     public override string ToString() |     public override string ToString() | ||||||
|   | |||||||
| @@ -10,9 +10,14 @@ public sealed record RequestLogEvent : DataAbstraction, IEventSourceGeneric<Crea | |||||||
|     /// <summary> |     /// <summary> | ||||||
|     ///     Initializes a new instance of the <see cref="RequestLogEvent" /> class. |     ///     Initializes a new instance of the <see cref="RequestLogEvent" /> class. | ||||||
|     /// </summary> |     /// </summary> | ||||||
|     public RequestLogEvent(CreateRequestLogReq data) |     public RequestLogEvent(CreateRequestLogReq data, bool isConsumOnce = false, object payload = default | ||||||
|  |                          , DateTime            createdTime = default, CancellationToken cancellationToken = default) | ||||||
|     { |     { | ||||||
|         Data = data; |         Data              = data; | ||||||
|  |         IsConsumOnce      = isConsumOnce; | ||||||
|  |         Payload           = payload; | ||||||
|  |         CreatedTime       = createdTime; | ||||||
|  |         CancellationToken = cancellationToken; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// <inheritdoc /> |     /// <inheritdoc /> | ||||||
|   | |||||||
| @@ -10,9 +10,14 @@ public sealed record UserUpdatedEvent : DataAbstraction, IEventSourceGeneric<Use | |||||||
|     /// <summary> |     /// <summary> | ||||||
|     ///     Initializes a new instance of the <see cref="UserUpdatedEvent" /> class. |     ///     Initializes a new instance of the <see cref="UserUpdatedEvent" /> class. | ||||||
|     /// </summary> |     /// </summary> | ||||||
|     public UserUpdatedEvent(UserInfoRsp data) |     public UserUpdatedEvent(UserInfoRsp data,              DateTime createdTime = default, bool isConsumOnce = false | ||||||
|  |                           , object      payload = default, CancellationToken cancellationToken = default) | ||||||
|     { |     { | ||||||
|         Data = data; |         Data              = data; | ||||||
|  |         CancellationToken = cancellationToken; | ||||||
|  |         CreatedTime       = createdTime; | ||||||
|  |         IsConsumOnce      = isConsumOnce; | ||||||
|  |         Payload           = payload; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// <inheritdoc /> |     /// <inheritdoc /> | ||||||
|   | |||||||
| @@ -10,9 +10,14 @@ public sealed record VerifyCodeCreatedEvent : DataAbstraction, IEventSourceGener | |||||||
|     /// <summary> |     /// <summary> | ||||||
|     ///     Initializes a new instance of the <see cref="VerifyCodeCreatedEvent" /> class. |     ///     Initializes a new instance of the <see cref="VerifyCodeCreatedEvent" /> class. | ||||||
|     /// </summary> |     /// </summary> | ||||||
|     public VerifyCodeCreatedEvent(QueryVerifyCodeRsp data) |     public VerifyCodeCreatedEvent(QueryVerifyCodeRsp data, DateTime createdTime = default, bool isConsumOnce = false | ||||||
|  |                                 , object             payload = default, CancellationToken cancellationToken = default) | ||||||
|     { |     { | ||||||
|         Data = data; |         Data              = data; | ||||||
|  |         CancellationToken = cancellationToken; | ||||||
|  |         CreatedTime       = createdTime; | ||||||
|  |         IsConsumOnce      = isConsumOnce; | ||||||
|  |         Payload           = payload; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// <inheritdoc /> |     /// <inheritdoc /> | ||||||
|   | |||||||
| @@ -54,7 +54,7 @@ public abstract class WorkBase<TLogger> | |||||||
|     ///     通用工作流 |     ///     通用工作流 | ||||||
|     /// </summary> |     /// </summary> | ||||||
|     /// <exception cref="NetAdminGetLockerException">加锁失败异常</exception> |     /// <exception cref="NetAdminGetLockerException">加锁失败异常</exception> | ||||||
|     protected virtual async ValueTask WorkflowAsync(bool singleInstance, CancellationToken cancelToken) |     protected async ValueTask WorkflowAsync(bool singleInstance, CancellationToken cancelToken) | ||||||
|     { |     { | ||||||
|         if (singleInstance) { |         if (singleInstance) { | ||||||
|             // 加锁 |             // 加锁 | ||||||
|   | |||||||
| @@ -108,7 +108,7 @@ public static class IMvcBuilderExtensions | |||||||
|         options.JsonSerializerOptions.TypeInfoResolver = new CollectionJsonTypeInfoResolver(); |         options.JsonSerializerOptions.TypeInfoResolver = new CollectionJsonTypeInfoResolver(); | ||||||
|  |  | ||||||
|         // 日期格式 2023-01-18 20:02:12 |         // 日期格式 2023-01-18 20:02:12 | ||||||
|         _ = options.JsonSerializerOptions.Converters.AddDateTimeTypeConverters(Chars.TPL_DATE_YYYY_MM_DD_HH_MM_SS); |         _ = options.JsonSerializerOptions.Converters.AddDateTimeTypeConverters(); | ||||||
|  |  | ||||||
|         // object->json 枚举显名 而非数字 ,json->object 可以枚举名 也可以数值 |         // object->json 枚举显名 而非数字 ,json->object 可以枚举名 也可以数值 | ||||||
|         if (enumToString) { |         if (enumToString) { | ||||||
|   | |||||||
| @@ -159,9 +159,7 @@ public static class ServiceCollectionExtensions | |||||||
|         var freeSql = new FreeSqlBuilder(App.GetOptions<DatabaseOptions>()).Build(initMethods); |         var freeSql = new FreeSqlBuilder(App.GetOptions<DatabaseOptions>()).Build(initMethods); | ||||||
|         _ = me.AddSingleton(freeSql); |         _ = me.AddSingleton(freeSql); | ||||||
|  |  | ||||||
|         var sqlAuditor = App.GetService<SqlAuditor>(); |         freeSql.Aop.AuditValue += SqlAuditor.DataAuditHandler; // Insert/Update自动值处理 | ||||||
|  |  | ||||||
|         freeSql.Aop.AuditValue += sqlAuditor.DataAuditHandler; // Insert/Update自动值处理 |  | ||||||
|         var eventPublisher = App.GetService<IEventPublisher>(); |         var eventPublisher = App.GetService<IEventPublisher>(); | ||||||
|  |  | ||||||
|         #pragma warning disable VSTHRD110 |         #pragma warning disable VSTHRD110 | ||||||
|   | |||||||
| @@ -34,7 +34,7 @@ public sealed class SqlAuditor : ISingleton | |||||||
|     ///     对Insert/Update的数据加工 |     ///     对Insert/Update的数据加工 | ||||||
|     /// </summary> |     /// </summary> | ||||||
|     /// <exception cref="ArgumentOutOfRangeException">e</exception> |     /// <exception cref="ArgumentOutOfRangeException">e</exception> | ||||||
|     public void DataAuditHandler(object sender, AuditValueEventArgs e) |     public static void DataAuditHandler(object sender, AuditValueEventArgs e) | ||||||
|     { |     { | ||||||
|         // SetServerTime(e); |         // SetServerTime(e); | ||||||
|         SetSnowflake(e); |         SetSnowflake(e); | ||||||
| @@ -56,6 +56,48 @@ public sealed class SqlAuditor : ISingleton | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     private static void SetCreatedClientIp(AuditValueEventArgs e) | ||||||
|  |     { | ||||||
|  |         if (e.Value is null or 0) { | ||||||
|  |             e.Value = App.HttpContext?.GetRemoteIpAddressToIPv4().IpV4ToInt32(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private static void SetCreatedReferer(AuditValueEventArgs e) | ||||||
|  |     { | ||||||
|  |         if (e.Value is null or "") { | ||||||
|  |             e.Value = App.HttpContext?.Request.GetRefererUrlAddress(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private static void SetCreatedTime(AuditValueEventArgs e) | ||||||
|  |     { | ||||||
|  |         if (e.Value == null || (e.Value is DateTime val && val == default)) { | ||||||
|  |             e.Value = DateTime.Now; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private static void SetCreatedUserAgent(AuditValueEventArgs e) | ||||||
|  |     { | ||||||
|  |         if (e.Value is null or "") { | ||||||
|  |             e.Value = App.HttpContext?.Request.Headers[Chars.FLG_HTTP_HEADER_USER_AGENT].ToString(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private static void SetCreatedUserId(AuditValueEventArgs e, ContextUserInfo userInfo) | ||||||
|  |     { | ||||||
|  |         if (userInfo != null && e.Value is null or (long and 0)) { | ||||||
|  |             e.Value = userInfo.Id; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private static void SetCreatedUserName(AuditValueEventArgs e, ContextUserInfo userInfo) | ||||||
|  |     { | ||||||
|  |         if (userInfo != null && e.Value is null or "") { | ||||||
|  |             e.Value = userInfo.UserName; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /// <summary> |     /// <summary> | ||||||
|     ///     设置创建者 |     ///     设置创建者 | ||||||
|     /// </summary> |     /// </summary> | ||||||
| @@ -63,41 +105,22 @@ public sealed class SqlAuditor : ISingleton | |||||||
|     { |     { | ||||||
|         switch (e.Property.Name) { |         switch (e.Property.Name) { | ||||||
|             case nameof(IFieldCreatedTime.CreatedTime): |             case nameof(IFieldCreatedTime.CreatedTime): | ||||||
|                 if (e.Value == null || (e.Value is DateTime val && val == default)) { |                 SetCreatedTime(e); | ||||||
|                     e.Value = DateTime.Now; |  | ||||||
|                 } |  | ||||||
|  |  | ||||||
|                 break; |                 break; | ||||||
|             case nameof(IFieldCreatedUser.CreatedUserId): |             case nameof(IFieldCreatedUser.CreatedUserId): | ||||||
|                 if (userInfo != null && e.Value is null or (long and 0)) { |                 SetCreatedUserId(e, userInfo); | ||||||
|                     e.Value = userInfo.Id; |  | ||||||
|                 } |  | ||||||
|  |  | ||||||
|                 break; |                 break; | ||||||
|  |  | ||||||
|             case nameof(IFieldCreatedUser.CreatedUserName): |             case nameof(IFieldCreatedUser.CreatedUserName): | ||||||
|                 if (userInfo != null && e.Value is null or "") { |                 SetCreatedUserName(e, userInfo); | ||||||
|                     e.Value = userInfo.UserName; |  | ||||||
|                 } |  | ||||||
|  |  | ||||||
|                 break; |                 break; | ||||||
|             case nameof(IFieldCreatedClient.CreatedClientIp): |             case nameof(IFieldCreatedClient.CreatedClientIp): | ||||||
|                 if (e.Value is null or 0) { |                 SetCreatedClientIp(e); | ||||||
|                     e.Value = App.HttpContext?.GetRemoteIpAddressToIPv4().IpV4ToInt32(); |  | ||||||
|                 } |  | ||||||
|  |  | ||||||
|                 break; |                 break; | ||||||
|             case nameof(IFieldCreatedClient.CreatedUserAgent): |             case nameof(IFieldCreatedClient.CreatedUserAgent): | ||||||
|                 if (e.Value is null or "") { |                 SetCreatedUserAgent(e); | ||||||
|                     e.Value = App.HttpContext?.Request.Headers[Chars.FLG_HTTP_HEADER_USER_AGENT].ToString(); |  | ||||||
|                 } |  | ||||||
|  |  | ||||||
|                 break; |                 break; | ||||||
|             case nameof(IFieldCreatedClient.CreatedReferer): |             case nameof(IFieldCreatedClient.CreatedReferer): | ||||||
|                 if (e.Value is null or "") { |                 SetCreatedReferer(e); | ||||||
|                     e.Value = App.HttpContext?.Request.GetRefererUrlAddress(); |  | ||||||
|                 } |  | ||||||
|  |  | ||||||
|                 break; |                 break; | ||||||
|             default: |             default: | ||||||
|                 return; |                 return; | ||||||
|   | |||||||
| @@ -13,10 +13,7 @@ public static class HttpRequestPartExtensions | |||||||
|     public static HttpRequestPart SetLog<T>(this HttpRequestPart me, ILogger<T> logger |     public static HttpRequestPart SetLog<T>(this HttpRequestPart me, ILogger<T> logger | ||||||
|                                           , Func<string, string> bodyHandle = null) |                                           , Func<string, string> bodyHandle = null) | ||||||
|     { |     { | ||||||
|         Task RequestHandleAsync(HttpClient _, HttpRequestMessage req) |         return me.OnRequesting(RequestHandleAsync).OnResponsing(ResponseHandleAsync).OnException(ExceptionHandleAsync); | ||||||
|         { |  | ||||||
|             return req.LogAsync(logger); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         Task ExceptionHandleAsync(HttpClient _, HttpResponseMessage rsp, string errors) |         Task ExceptionHandleAsync(HttpClient _, HttpResponseMessage rsp, string errors) | ||||||
|         { |         { | ||||||
| @@ -28,6 +25,9 @@ public static class HttpRequestPartExtensions | |||||||
|             return rsp.LogAsync(logger, bodyHandle); |             return rsp.LogAsync(logger, bodyHandle); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         return me.OnRequesting(RequestHandleAsync).OnResponsing(ResponseHandleAsync).OnException(ExceptionHandleAsync); |         Task RequestHandleAsync(HttpClient _, HttpRequestMessage req) | ||||||
|  |         { | ||||||
|  |             return req.LogAsync(logger); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -6,7 +6,7 @@ | |||||||
|     <Import Project="$(SolutionDir)/build/copy.pkg.xml.comment.files.targets"/> |     <Import Project="$(SolutionDir)/build/copy.pkg.xml.comment.files.targets"/> | ||||||
|     <Import Project="$(SolutionDir)/build/prebuild.targets"/> |     <Import Project="$(SolutionDir)/build/prebuild.targets"/> | ||||||
|     <ItemGroup> |     <ItemGroup> | ||||||
|         <PackageReference Include="Cronos" Version="0.8.3"/> |         <PackageReference Include="Cronos" Version="0.8.4"/> | ||||||
|         <PackageReference Include="FreeSql.DbContext.NS" Version="3.2.813-preview20240208-ns1"/> |         <PackageReference Include="FreeSql.DbContext.NS" Version="3.2.813-preview20240208-ns1"/> | ||||||
|         <PackageReference Include="FreeSql.Provider.Sqlite.NS" Version="3.2.813-preview20240208-ns1"/> |         <PackageReference Include="FreeSql.Provider.Sqlite.NS" Version="3.2.813-preview20240208-ns1"/> | ||||||
|         <PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="4.9.1.31"/> |         <PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="4.9.1.31"/> | ||||||
| @@ -14,7 +14,7 @@ | |||||||
|         <PackageReference Include="Furion.Pure.NS" Version="4.9.1.31-ns2"/> |         <PackageReference Include="Furion.Pure.NS" Version="4.9.1.31-ns2"/> | ||||||
|         <PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="9.0.0-preview.1.24081.5"/> |         <PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="9.0.0-preview.1.24081.5"/> | ||||||
|         <PackageReference Include="Minio" Version="6.0.2"/> |         <PackageReference Include="Minio" Version="6.0.2"/> | ||||||
|         <PackageReference Include="NSExt" Version="2.0.11"/> |         <PackageReference Include="NSExt" Version="2.1.0"/> | ||||||
|         <PackageReference Include="RedLock.net" Version="2.3.2"/> |         <PackageReference Include="RedLock.net" Version="2.3.2"/> | ||||||
|         <PackageReference Include="SixLabors.ImageSharp.Drawing" Version="1.0.0"/> |         <PackageReference Include="SixLabors.ImageSharp.Drawing" Version="1.0.0"/> | ||||||
|         <PackageReference Include="Yitter.IdGenerator" Version="1.0.14"/> |         <PackageReference Include="Yitter.IdGenerator" Version="1.0.14"/> | ||||||
|   | |||||||
| @@ -12,7 +12,7 @@ namespace NetAdmin.Infrastructure.Utils; | |||||||
| /// </summary> | /// </summary> | ||||||
| public static class CaptchaImageHelper | public static class CaptchaImageHelper | ||||||
| { | { | ||||||
|     private static readonly int[] _randRange = [70, 100]; |     private static readonly int[] _randRange =  | ||||||
|  |  | ||||||
|     /// <summary> |     /// <summary> | ||||||
|     ///     创建一个缺口滑块验证码图片 |     ///     创建一个缺口滑块验证码图片 | ||||||
| @@ -96,6 +96,26 @@ public static class CaptchaImageHelper | |||||||
|               , offsetRand); |               , offsetRand); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     private static int BuildPathList(Span<Rgba32> rowSpan, int temp, List<IPath> pathList, int y) | ||||||
|  |     { | ||||||
|  |         for (var x = 0; x < rowSpan.Length; x++) { | ||||||
|  |             ref var pixel = ref rowSpan[x]; | ||||||
|  |             if (pixel.A != 0) { | ||||||
|  |                 temp = temp switch { 0 => x, _ => temp }; | ||||||
|  |             } | ||||||
|  |             else { | ||||||
|  |                 if (temp == 0) { | ||||||
|  |                     continue; | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 pathList.Add(new RectangularPolygon(temp, y, x - temp, 1)); | ||||||
|  |                 temp = 0; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         return temp; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     private static ComplexPolygon CalcBlockShape(Image<Rgba32> templateDarkImage) |     private static ComplexPolygon CalcBlockShape(Image<Rgba32> templateDarkImage) | ||||||
|     { |     { | ||||||
|         var temp     = 0; |         var temp     = 0; | ||||||
| @@ -103,20 +123,7 @@ public static class CaptchaImageHelper | |||||||
|         templateDarkImage.ProcessPixelRows(accessor => { |         templateDarkImage.ProcessPixelRows(accessor => { | ||||||
|             for (var y = 0; y < templateDarkImage.Height; y++) { |             for (var y = 0; y < templateDarkImage.Height; y++) { | ||||||
|                 var rowSpan = accessor.GetRowSpan(y); |                 var rowSpan = accessor.GetRowSpan(y); | ||||||
|                 for (var x = 0; x < rowSpan.Length; x++) { |                 temp = BuildPathList(rowSpan, temp, pathList, y); | ||||||
|                     ref var pixel = ref rowSpan[x]; |  | ||||||
|                     if (pixel.A != 0) { |  | ||||||
|                         temp = temp switch { 0 => x, _ => temp }; |  | ||||||
|                     } |  | ||||||
|                     else { |  | ||||||
|                         if (temp == 0) { |  | ||||||
|                             continue; |  | ||||||
|                         } |  | ||||||
|  |  | ||||||
|                         pathList.Add(new RectangularPolygon(temp, y, x - temp, 1)); |  | ||||||
|                         temp = 0; |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } |             } | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
| @@ -175,4 +182,6 @@ public static class CaptchaImageHelper | |||||||
|     { |     { | ||||||
|         return (endNum > startNum ? new[] { 0, endNum - startNum }.Rand() : 0) + startNum; |         return (endNum > startNum ? new[] { 0, endNum - startNum }.Rand() : 0) + startNum; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     [70, 100]; | ||||||
| } | } | ||||||
| @@ -266,7 +266,7 @@ public sealed class UserAgentParser | |||||||
|     /// <summary> |     /// <summary> | ||||||
|     ///     平台 |     ///     平台 | ||||||
|     /// </summary> |     /// </summary> | ||||||
|     public string Platform { get; set; } = string.Empty; |     public string Platform { get; private set; } = string.Empty; | ||||||
|  |  | ||||||
|     /// <summary> |     /// <summary> | ||||||
|     ///     机器人 |     ///     机器人 | ||||||
| @@ -301,49 +301,43 @@ public sealed class UserAgentParser | |||||||
|  |  | ||||||
|     private bool SetMobile() |     private bool SetMobile() | ||||||
|     { |     { | ||||||
|         #pragma warning disable S3267 |         var kv = _mobiles.FirstOrDefault(x => // | ||||||
|         foreach (var item in _mobiles) { |                                              _agent.Contains(x.Key, StringComparison.OrdinalIgnoreCase)); | ||||||
|             #pragma warning restore S3267 |  | ||||||
|             if (_agent.Contains(item.Key, StringComparison.OrdinalIgnoreCase)) { |         if (kv.Key == null) { | ||||||
|                 IsMobile = true; |             return false; | ||||||
|                 Mobile   = item.Value; |  | ||||||
|                 return true; |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         IsMobile = true; | ||||||
|  |         Mobile   = kv.Value; | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private bool SetPlatform() |     private bool SetPlatform() | ||||||
|     { |     { | ||||||
|         #pragma warning disable S3267 |         var kv = _platforms.First(x => // | ||||||
|         foreach (var item in _platforms) { |                                       Regex.IsMatch(_agent, $"{Regex.Escape(x.Key)}", RegexOptions.IgnoreCase)); | ||||||
|             #pragma warning restore S3267 |  | ||||||
|             if (!Regex.IsMatch(_agent, $"{Regex.Escape(item.Key)}", RegexOptions.IgnoreCase)) { |  | ||||||
|                 continue; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             Platform = item.Value; |         if (kv.Key == null) { | ||||||
|             return true; |             Platform = "Unknown Platform"; | ||||||
|  |             return false; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         Platform = "Unknown Platform"; |         Platform = kv.Value; | ||||||
|         return false; |         return true; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private bool SetRobot() |     private bool SetRobot() | ||||||
|     { |     { | ||||||
|         #pragma warning disable S3267 |         var kv = _robots.FirstOrDefault(x => // | ||||||
|         foreach (var item in _robots) { |                                             Regex.IsMatch(_agent, $"{Regex.Escape(x.Key)}", RegexOptions.IgnoreCase)); | ||||||
|             #pragma warning restore S3267 |         if (kv.Key == null) { | ||||||
|             if (Regex.IsMatch(_agent, $"{Regex.Escape(item.Key)}", RegexOptions.IgnoreCase)) { |             return false; | ||||||
|                 IsRobot = true; |  | ||||||
|                 Robot   = item.Value; |  | ||||||
|                 _       = SetMobile(); |  | ||||||
|                 return true; |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         return false; |         IsRobot = true; | ||||||
|  |         Robot   = kv.Value; | ||||||
|  |         _       = SetMobile(); | ||||||
|  |         return true; | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -7,6 +7,11 @@ namespace NetAdmin.SysComponent.Application.Modules.Sys; | |||||||
| /// </summary> | /// </summary> | ||||||
| public interface IToolsModule | public interface IToolsModule | ||||||
| { | { | ||||||
|  |     /// <summary> | ||||||
|  |     ///     获取更新日志 | ||||||
|  |     /// </summary> | ||||||
|  |     Task<string> GetChangeLogAsync(); | ||||||
|  |  | ||||||
|     /// <summary> |     /// <summary> | ||||||
|     ///     获取模块信息 |     ///     获取模块信息 | ||||||
|     /// </summary> |     /// </summary> | ||||||
|   | |||||||
| @@ -16,12 +16,14 @@ public sealed class ConfigService(DefaultRepository<Sys_Config> rpo) // | |||||||
|     public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req) |     public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req) | ||||||
|     { |     { | ||||||
|         req.ThrowIfInvalid(); |         req.ThrowIfInvalid(); | ||||||
|         var sum = 0; |         var ret = 0; | ||||||
|  |  | ||||||
|  |         // ReSharper disable once LoopCanBeConvertedToQuery | ||||||
|         foreach (var item in req.Items) { |         foreach (var item in req.Items) { | ||||||
|             sum += await DeleteAsync(item).ConfigureAwait(false); |             ret += await DeleteAsync(item).ConfigureAwait(false); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         return sum; |         return ret; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// <inheritdoc /> |     /// <inheritdoc /> | ||||||
|   | |||||||
| @@ -15,12 +15,14 @@ public sealed class DeptService(DefaultRepository<Sys_Dept> rpo) // | |||||||
|     public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req) |     public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req) | ||||||
|     { |     { | ||||||
|         req.ThrowIfInvalid(); |         req.ThrowIfInvalid(); | ||||||
|         var sum = 0; |         var ret = 0; | ||||||
|  |  | ||||||
|  |         // ReSharper disable once LoopCanBeConvertedToQuery | ||||||
|         foreach (var item in req.Items) { |         foreach (var item in req.Items) { | ||||||
|             sum += await DeleteAsync(item).ConfigureAwait(false); |             ret += await DeleteAsync(item).ConfigureAwait(false); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         return sum; |         return ret; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// <inheritdoc /> |     /// <inheritdoc /> | ||||||
|   | |||||||
| @@ -15,12 +15,14 @@ public sealed class DicCatalogService(DefaultRepository<Sys_DicCatalog> rpo) // | |||||||
|     public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req) |     public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req) | ||||||
|     { |     { | ||||||
|         req.ThrowIfInvalid(); |         req.ThrowIfInvalid(); | ||||||
|         var sum = 0; |         var ret = 0; | ||||||
|  |  | ||||||
|  |         // ReSharper disable once LoopCanBeConvertedToQuery | ||||||
|         foreach (var item in req.Items) { |         foreach (var item in req.Items) { | ||||||
|             sum += await DeleteAsync(item).ConfigureAwait(false); |             ret += await DeleteAsync(item).ConfigureAwait(false); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         return sum; |         return ret; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// <inheritdoc /> |     /// <inheritdoc /> | ||||||
|   | |||||||
| @@ -15,12 +15,14 @@ public sealed class DicContentService(DefaultRepository<Sys_DicContent> rpo) // | |||||||
|     public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req) |     public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req) | ||||||
|     { |     { | ||||||
|         req.ThrowIfInvalid(); |         req.ThrowIfInvalid(); | ||||||
|         var sum = 0; |         var ret = 0; | ||||||
|  |  | ||||||
|  |         // ReSharper disable once LoopCanBeConvertedToQuery | ||||||
|         foreach (var item in req.Items) { |         foreach (var item in req.Items) { | ||||||
|             sum += await DeleteAsync(item).ConfigureAwait(false); |             ret += await DeleteAsync(item).ConfigureAwait(false); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         return sum; |         return ret; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// <inheritdoc /> |     /// <inheritdoc /> | ||||||
|   | |||||||
| @@ -16,12 +16,14 @@ public sealed class JobRecordService(DefaultRepository<Sys_JobRecord> rpo) // | |||||||
|     public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req) |     public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req) | ||||||
|     { |     { | ||||||
|         req.ThrowIfInvalid(); |         req.ThrowIfInvalid(); | ||||||
|         var sum = 0; |         var ret = 0; | ||||||
|  |  | ||||||
|  |         // ReSharper disable once LoopCanBeConvertedToQuery | ||||||
|         foreach (var item in req.Items) { |         foreach (var item in req.Items) { | ||||||
|             sum += await DeleteAsync(item).ConfigureAwait(false); |             ret += await DeleteAsync(item).ConfigureAwait(false); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         return sum; |         return ret; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// <inheritdoc /> |     /// <inheritdoc /> | ||||||
|   | |||||||
| @@ -19,12 +19,14 @@ public sealed class JobService(DefaultRepository<Sys_Job> rpo, IJobRecordService | |||||||
|     public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req) |     public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req) | ||||||
|     { |     { | ||||||
|         req.ThrowIfInvalid(); |         req.ThrowIfInvalid(); | ||||||
|         var sum = 0; |         var ret = 0; | ||||||
|  |  | ||||||
|  |         // ReSharper disable once LoopCanBeConvertedToQuery | ||||||
|         foreach (var item in req.Items) { |         foreach (var item in req.Items) { | ||||||
|             sum += await DeleteAsync(item).ConfigureAwait(false); |             ret += await DeleteAsync(item).ConfigureAwait(false); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         return sum; |         return ret; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// <inheritdoc /> |     /// <inheritdoc /> | ||||||
| @@ -56,11 +58,12 @@ public sealed class JobService(DefaultRepository<Sys_Job> rpo, IJobRecordService | |||||||
|         var ret = await Rpo.UpdateDiy.Set(a => a.ExecutionCron == req.ExecutionCron) |         var ret = await Rpo.UpdateDiy.Set(a => a.ExecutionCron == req.ExecutionCron) | ||||||
|                            .Set(a => a.HttpMethod              == req.HttpMethod) |                            .Set(a => a.HttpMethod              == req.HttpMethod) | ||||||
|                            .Set(a => a.JobName                 == req.JobName) |                            .Set(a => a.JobName                 == req.JobName) | ||||||
|                            .Set(a => a.RequestHeader           == req.RequestHeader) |                            .SetIf(req.RequestHeaders == null, a => a.RequestHeader, null) | ||||||
|                            .Set(a => a.RequestBody             == req.RequestBody) |                            .SetIf(req.RequestHeaders != null, a => a.RequestHeader, req.RequestHeaders.Json()) | ||||||
|                            .Set(a => a.RequestUrl              == req.RequestUrl) |                            .Set(a => a.RequestBody == req.RequestBody) | ||||||
|                            .Set(a => a.UserId                  == req.UserId) |                            .Set(a => a.RequestUrl  == req.RequestUrl) | ||||||
|                            .Where(a => a.Id                    == req.Id) |                            .Set(a => a.UserId      == req.UserId) | ||||||
|  |                            .Where(a => a.Id        == req.Id) | ||||||
|                            .ExecuteUpdatedAsync() |                            .ExecuteUpdatedAsync() | ||||||
|                            .ConfigureAwait(false); |                            .ConfigureAwait(false); | ||||||
|         return ret[0].Adapt<QueryJobRsp>(); |         return ret[0].Adapt<QueryJobRsp>(); | ||||||
| @@ -97,24 +100,22 @@ public sealed class JobService(DefaultRepository<Sys_Job> rpo, IJobRecordService | |||||||
|     public async Task<QueryJobRsp> GetNextJobAsync() |     public async Task<QueryJobRsp> GetNextJobAsync() | ||||||
|     { |     { | ||||||
|         var df = new DynamicFilterInfo { |         var df = new DynamicFilterInfo { | ||||||
|                                            Filters = [ |                                            Filters =  [ new DynamicFilterInfo { Field = nameof(QueryJobReq.NextExecTime) | ||||||
|                                                new DynamicFilterInfo { |                                          , Value = DateTime.UtcNow | ||||||
|                                                                          Field    = nameof(QueryJobReq.NextExecTime) |                                          , Operator = DynamicFilterOperators.LessThan | ||||||
|                                                                        , Value    = DateTime.UtcNow |                                        } | ||||||
|                                                                        , Operator = DynamicFilterOperators.LessThan |           ,  new DynamicFilterInfo { | ||||||
|                                                                      } |                                        Field    = nameof(QueryJobReq.Status) | ||||||
|                                              , new DynamicFilterInfo { |                                      , Value    = JobStatues.Idle | ||||||
|                                                                          Field    = nameof(QueryJobReq.Status) |                                      , Operator = DynamicFilterOperators.Eq | ||||||
|                                                                        , Value    = JobStatues.Idle |                                    } | ||||||
|                                                                        , Operator = DynamicFilterOperators.Eq |           , new DynamicFilterInfo { | ||||||
|                                                                      } |                                       Field    = nameof(QueryJobReq.Enabled) | ||||||
|                                              , new DynamicFilterInfo { |                                     , Value    = true | ||||||
|                                                                          Field    = nameof(QueryJobReq.Enabled) |                                     , Operator = DynamicFilterOperators.Eq | ||||||
|                                                                        , Value    = true |                                   } | ||||||
|                                                                        , Operator = DynamicFilterOperators.Eq |             ] | ||||||
|                                                                      } |         }; | ||||||
|                                            ] |  | ||||||
|                                        }; |  | ||||||
|         var job = await QueryInternal(new QueryReq<QueryJobReq> { DynamicFilter = df, Count = 1 }, true) |         var job = await QueryInternal(new QueryReq<QueryJobReq> { DynamicFilter = df, Count = 1 }, true) | ||||||
|                         .Where(a => !Rpo.Orm.Select<Sys_JobRecord>() |                         .Where(a => !Rpo.Orm.Select<Sys_JobRecord>() | ||||||
|                                         .As("b") |                                         .As("b") | ||||||
|   | |||||||
| @@ -15,12 +15,14 @@ public sealed class MenuService(DefaultRepository<Sys_Menu> rpo, IUserService us | |||||||
|     public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req) |     public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req) | ||||||
|     { |     { | ||||||
|         req.ThrowIfInvalid(); |         req.ThrowIfInvalid(); | ||||||
|         var sum = 0; |         var ret = 0; | ||||||
|  |  | ||||||
|  |         // ReSharper disable once LoopCanBeConvertedToQuery | ||||||
|         foreach (var item in req.Items) { |         foreach (var item in req.Items) { | ||||||
|             sum += await DeleteAsync(item).ConfigureAwait(false); |             ret += await DeleteAsync(item).ConfigureAwait(false); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         return sum; |         return ret; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// <inheritdoc /> |     /// <inheritdoc /> | ||||||
| @@ -32,10 +34,15 @@ public sealed class MenuService(DefaultRepository<Sys_Menu> rpo, IUserService us | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// <inheritdoc /> |     /// <inheritdoc /> | ||||||
|     public Task<int> DeleteAsync(DelReq req) |     public async Task<int> DeleteAsync(DelReq req) | ||||||
|     { |     { | ||||||
|         req.ThrowIfInvalid(); |         req.ThrowIfInvalid(); | ||||||
|         return Rpo.DeleteAsync(a => a.Id == req.Id); |         var effect = await Rpo.DeleteAsync(a => a.Id == req.Id).ConfigureAwait(false); | ||||||
|  |         effect += await Rpo.Orm.Delete<Sys_RoleMenu>() | ||||||
|  |                            .Where(a => a.MenuId == req.Id) | ||||||
|  |                            .ExecuteAffrowsAsync() | ||||||
|  |                            .ConfigureAwait(false); | ||||||
|  |         return effect; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// <inheritdoc /> |     /// <inheritdoc /> | ||||||
|   | |||||||
| @@ -15,12 +15,14 @@ public sealed class RequestLogService(DefaultRepository<Sys_RequestLog> rpo) // | |||||||
|     public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req) |     public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req) | ||||||
|     { |     { | ||||||
|         req.ThrowIfInvalid(); |         req.ThrowIfInvalid(); | ||||||
|         var sum = 0; |         var ret = 0; | ||||||
|  |  | ||||||
|  |         // ReSharper disable once LoopCanBeConvertedToQuery | ||||||
|         foreach (var item in req.Items) { |         foreach (var item in req.Items) { | ||||||
|             sum += await DeleteAsync(item).ConfigureAwait(false); |             ret += await DeleteAsync(item).ConfigureAwait(false); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         return sum; |         return ret; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// <inheritdoc /> |     /// <inheritdoc /> | ||||||
|   | |||||||
| @@ -15,12 +15,14 @@ public sealed class RoleService(DefaultRepository<Sys_Role> rpo) // | |||||||
|     public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req) |     public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req) | ||||||
|     { |     { | ||||||
|         req.ThrowIfInvalid(); |         req.ThrowIfInvalid(); | ||||||
|         var sum = 0; |         var ret = 0; | ||||||
|  |  | ||||||
|  |         // ReSharper disable once LoopCanBeConvertedToQuery | ||||||
|         foreach (var item in req.Items) { |         foreach (var item in req.Items) { | ||||||
|             sum += await DeleteAsync(item).ConfigureAwait(false); |             ret += await DeleteAsync(item).ConfigureAwait(false); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         return sum; |         return ret; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// <inheritdoc /> |     /// <inheritdoc /> | ||||||
|   | |||||||
| @@ -16,12 +16,14 @@ public sealed class SiteMsgDeptService(DefaultRepository<Sys_SiteMsgDept> rpo) / | |||||||
|     public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req) |     public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req) | ||||||
|     { |     { | ||||||
|         req.ThrowIfInvalid(); |         req.ThrowIfInvalid(); | ||||||
|         var sum = 0; |         var ret = 0; | ||||||
|  |  | ||||||
|  |         // ReSharper disable once LoopCanBeConvertedToQuery | ||||||
|         foreach (var item in req.Items) { |         foreach (var item in req.Items) { | ||||||
|             sum += await DeleteAsync(item).ConfigureAwait(false); |             ret += await DeleteAsync(item).ConfigureAwait(false); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         return sum; |         return ret; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// <inheritdoc /> |     /// <inheritdoc /> | ||||||
|   | |||||||
| @@ -16,12 +16,14 @@ public sealed class SiteMsgFlagService(DefaultRepository<Sys_SiteMsgFlag> rpo) / | |||||||
|     public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req) |     public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req) | ||||||
|     { |     { | ||||||
|         req.ThrowIfInvalid(); |         req.ThrowIfInvalid(); | ||||||
|         var sum = 0; |         var ret = 0; | ||||||
|  |  | ||||||
|  |         // ReSharper disable once LoopCanBeConvertedToQuery | ||||||
|         foreach (var item in req.Items) { |         foreach (var item in req.Items) { | ||||||
|             sum += await DeleteAsync(item).ConfigureAwait(false); |             ret += await DeleteAsync(item).ConfigureAwait(false); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         return sum; |         return ret; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// <inheritdoc /> |     /// <inheritdoc /> | ||||||
|   | |||||||
| @@ -16,12 +16,14 @@ public sealed class SiteMsgRoleService(DefaultRepository<Sys_SiteMsgRole> rpo) / | |||||||
|     public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req) |     public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req) | ||||||
|     { |     { | ||||||
|         req.ThrowIfInvalid(); |         req.ThrowIfInvalid(); | ||||||
|         var sum = 0; |         var ret = 0; | ||||||
|  |  | ||||||
|  |         // ReSharper disable once LoopCanBeConvertedToQuery | ||||||
|         foreach (var item in req.Items) { |         foreach (var item in req.Items) { | ||||||
|             sum += await DeleteAsync(item).ConfigureAwait(false); |             ret += await DeleteAsync(item).ConfigureAwait(false); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         return sum; |         return ret; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// <inheritdoc /> |     /// <inheritdoc /> | ||||||
|   | |||||||
| @@ -12,22 +12,22 @@ using NetAdmin.SysComponent.Application.Services.Sys.Dependency; | |||||||
| namespace NetAdmin.SysComponent.Application.Services.Sys; | namespace NetAdmin.SysComponent.Application.Services.Sys; | ||||||
|  |  | ||||||
| /// <inheritdoc cref="ISiteMsgService" /> | /// <inheritdoc cref="ISiteMsgService" /> | ||||||
| public sealed class SiteMsgService( | public sealed class SiteMsgService(DefaultRepository<Sys_SiteMsg> rpo, ContextUserInfo contextUserInfo | ||||||
|     DefaultRepository<Sys_SiteMsg> rpo |                                  , ISiteMsgFlagService            siteMsgFlagService) // | ||||||
|   , ContextUserInfo                contextUserInfo |  | ||||||
|   , ISiteMsgFlagService            siteMsgFlagService) // |  | ||||||
|     : RepositoryService<Sys_SiteMsg, ISiteMsgService>(rpo), ISiteMsgService |     : RepositoryService<Sys_SiteMsg, ISiteMsgService>(rpo), ISiteMsgService | ||||||
| { | { | ||||||
|     /// <inheritdoc /> |     /// <inheritdoc /> | ||||||
|     public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req) |     public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req) | ||||||
|     { |     { | ||||||
|         req.ThrowIfInvalid(); |         req.ThrowIfInvalid(); | ||||||
|         var sum = 0; |         var ret = 0; | ||||||
|  |  | ||||||
|  |         // ReSharper disable once LoopCanBeConvertedToQuery | ||||||
|         foreach (var item in req.Items) { |         foreach (var item in req.Items) { | ||||||
|             sum += await DeleteAsync(item).ConfigureAwait(false); |             ret += await DeleteAsync(item).ConfigureAwait(false); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         return sum; |         return ret; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// <inheritdoc /> |     /// <inheritdoc /> | ||||||
| @@ -300,9 +300,9 @@ public sealed class SiteMsgService( | |||||||
|                   .WhereDynamicFilter(req.DynamicFilter) |                   .WhereDynamicFilter(req.DynamicFilter) | ||||||
|                   .Where((a, _, c, d, e, f) => |                   .Where((a, _, c, d, e, f) => | ||||||
|                              (SqlExt.EqualIsNull(f.UserSiteMsgStatus) || |                              (SqlExt.EqualIsNull(f.UserSiteMsgStatus) || | ||||||
|                               f.UserSiteMsgStatus != UserSiteMsgStatues.Deleted) && |                               f.UserSiteMsgStatus != UserSiteMsgStatues.Deleted) && (a.MsgType == SiteMsgTypes.Public || | ||||||
|                              (a.MsgType == SiteMsgTypes.Public || c.DeptId == contextUserInfo.DeptId || |                                  c.DeptId == contextUserInfo.DeptId || roleIds.Contains(d.RoleId) || | ||||||
|                               roleIds.Contains(d.RoleId)       || e.UserId == contextUserInfo.Id)) |                                  e.UserId == contextUserInfo.Id)) | ||||||
|                   .GroupBy((a, _, _, _, _, _) => a.Id); |                   .GroupBy((a, _, _, _, _, _) => a.Id); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -16,12 +16,14 @@ public sealed class SiteMsgUserService(DefaultRepository<Sys_SiteMsgUser> rpo) / | |||||||
|     public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req) |     public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req) | ||||||
|     { |     { | ||||||
|         req.ThrowIfInvalid(); |         req.ThrowIfInvalid(); | ||||||
|         var sum = 0; |         var ret = 0; | ||||||
|  |  | ||||||
|  |         // ReSharper disable once LoopCanBeConvertedToQuery | ||||||
|         foreach (var item in req.Items) { |         foreach (var item in req.Items) { | ||||||
|             sum += await DeleteAsync(item).ConfigureAwait(false); |             ret += await DeleteAsync(item).ConfigureAwait(false); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         return sum; |         return ret; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// <inheritdoc /> |     /// <inheritdoc /> | ||||||
|   | |||||||
| @@ -7,6 +7,14 @@ namespace NetAdmin.SysComponent.Application.Services.Sys; | |||||||
| /// <inheritdoc cref="IToolsService" /> | /// <inheritdoc cref="IToolsService" /> | ||||||
| public sealed class ToolsService : ServiceBase<IToolsService>, IToolsService | public sealed class ToolsService : ServiceBase<IToolsService>, IToolsService | ||||||
| { | { | ||||||
|  |     /// <inheritdoc /> | ||||||
|  |     public async Task<string> GetChangeLogAsync() | ||||||
|  |     { | ||||||
|  |         await using var stream       = Assembly.GetEntryAssembly()!.GetManifestResourceStream("CHANGELOG.md"); | ||||||
|  |         using var       streamReader = new StreamReader(stream!); | ||||||
|  |         return await streamReader.ReadToEndAsync().ConfigureAwait(false); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /// <inheritdoc /> |     /// <inheritdoc /> | ||||||
|     public Task<IEnumerable<GetModulesRsp>> GetModulesAsync() |     public Task<IEnumerable<GetModulesRsp>> GetModulesAsync() | ||||||
|     { |     { | ||||||
|   | |||||||
| @@ -17,12 +17,14 @@ public sealed class UserProfileService(DefaultRepository<Sys_UserProfile> rpo) / | |||||||
|     public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req) |     public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req) | ||||||
|     { |     { | ||||||
|         req.ThrowIfInvalid(); |         req.ThrowIfInvalid(); | ||||||
|         var sum = 0; |         var ret = 0; | ||||||
|  |  | ||||||
|  |         // ReSharper disable once LoopCanBeConvertedToQuery | ||||||
|         foreach (var item in req.Items) { |         foreach (var item in req.Items) { | ||||||
|             sum += await DeleteAsync(item).ConfigureAwait(false); |             ret += await DeleteAsync(item).ConfigureAwait(false); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         return sum; |         return ret; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// <inheritdoc /> |     /// <inheritdoc /> | ||||||
|   | |||||||
| @@ -13,11 +13,10 @@ using NetAdmin.SysComponent.Application.Services.Sys.Dependency; | |||||||
| namespace NetAdmin.SysComponent.Application.Services.Sys; | namespace NetAdmin.SysComponent.Application.Services.Sys; | ||||||
|  |  | ||||||
| /// <inheritdoc cref="IUserService" /> | /// <inheritdoc cref="IUserService" /> | ||||||
| public sealed class UserService( | public sealed class UserService(DefaultRepository<Sys_User> rpo                // | ||||||
|     DefaultRepository<Sys_User> rpo                // |                               , IUserProfileService         userProfileService // | ||||||
|   , IUserProfileService         userProfileService // |                               , IVerifyCodeService          verifyCodeService  // | ||||||
|   , IVerifyCodeService          verifyCodeService  // |                               , IEventPublisher             eventPublisher)    // | ||||||
|   , IEventPublisher             eventPublisher)    // |  | ||||||
|     : RepositoryService<Sys_User, IUserService>(rpo), IUserService |     : RepositoryService<Sys_User, IUserService>(rpo), IUserService | ||||||
| { | { | ||||||
|     private readonly Expression<Func<Sys_User, Sys_User>> _selectUserFields = a => new Sys_User { |     private readonly Expression<Func<Sys_User, Sys_User>> _selectUserFields = a => new Sys_User { | ||||||
| @@ -38,12 +37,14 @@ public sealed class UserService( | |||||||
|     public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req) |     public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req) | ||||||
|     { |     { | ||||||
|         req.ThrowIfInvalid(); |         req.ThrowIfInvalid(); | ||||||
|         var sum = 0; |         var ret = 0; | ||||||
|  |  | ||||||
|  |         // ReSharper disable once LoopCanBeConvertedToQuery | ||||||
|         foreach (var item in req.Items) { |         foreach (var item in req.Items) { | ||||||
|             sum += await DeleteAsync(item).ConfigureAwait(false); |             ret += await DeleteAsync(item).ConfigureAwait(false); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         return sum; |         return ret; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// <inheritdoc /> |     /// <inheritdoc /> | ||||||
| @@ -358,21 +359,18 @@ public sealed class UserService( | |||||||
|         req.ThrowIfInvalid(); |         req.ThrowIfInvalid(); | ||||||
|         var version = await Rpo.Where(a => a.Id == UserToken.Id && a.Password == req.OldPassword.Pwd().Guid()) |         var version = await Rpo.Where(a => a.Id == UserToken.Id && a.Password == req.OldPassword.Pwd().Guid()) | ||||||
|                                .ToOneAsync(a => new long?(a.Version)) |                                .ToOneAsync(a => new long?(a.Version)) | ||||||
|                                .ConfigureAwait(false); |                                .ConfigureAwait(false) ?? throw new NetAdminInvalidOperationException($"{Ln.旧密码不正确}"); | ||||||
|         if (version != null) { |  | ||||||
|             var ret = await Rpo.UpdateDiy |  | ||||||
|                                .SetSource(new Sys_User { |  | ||||||
|                                                            Id       = UserToken.Id |  | ||||||
|                                                          , Password = req.NewPassword.Pwd().Guid() |  | ||||||
|                                                          , Version  = version.Value |  | ||||||
|                                                        }) |  | ||||||
|                                .UpdateColumns(a => a.Password) |  | ||||||
|                                .ExecuteAffrowsAsync() |  | ||||||
|                                .ConfigureAwait(false); |  | ||||||
|             return ret <= 0 ? throw new NetAdminUnexpectedException() : (uint)ret; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         throw new NetAdminInvalidOperationException($"{Ln.旧密码不正确}"); |         var ret = await Rpo.UpdateDiy | ||||||
|  |                            .SetSource(new Sys_User { | ||||||
|  |                                                        Id       = UserToken.Id | ||||||
|  |                                                      , Password = req.NewPassword.Pwd().Guid() | ||||||
|  |                                                      , Version  = version | ||||||
|  |                                                    }) | ||||||
|  |                            .UpdateColumns(a => a.Password) | ||||||
|  |                            .ExecuteAffrowsAsync() | ||||||
|  |                            .ConfigureAwait(false); | ||||||
|  |         return ret <= 0 ? throw new NetAdminUnexpectedException() : (uint)ret; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// <inheritdoc /> |     /// <inheritdoc /> | ||||||
|   | |||||||
| @@ -14,18 +14,20 @@ namespace NetAdmin.SysComponent.Application.Services.Sys; | |||||||
| public sealed class VerifyCodeService(DefaultRepository<Sys_VerifyCode> rpo, IEventPublisher eventPublisher) // | public sealed class VerifyCodeService(DefaultRepository<Sys_VerifyCode> rpo, IEventPublisher eventPublisher) // | ||||||
|     : RepositoryService<Sys_VerifyCode, IVerifyCodeService>(rpo), IVerifyCodeService |     : RepositoryService<Sys_VerifyCode, IVerifyCodeService>(rpo), IVerifyCodeService | ||||||
| { | { | ||||||
|     private static readonly int[] _randRange = [0, 10000]; |     private static readonly int[] _randRange =  | ||||||
|  |  | ||||||
|     /// <inheritdoc /> |     /// <inheritdoc /> | ||||||
|     public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req) |     public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req) | ||||||
|     { |     { | ||||||
|         req.ThrowIfInvalid(); |         req.ThrowIfInvalid(); | ||||||
|         var sum = 0; |         var ret = 0; | ||||||
|  |  | ||||||
|  |         // ReSharper disable once LoopCanBeConvertedToQuery | ||||||
|         foreach (var item in req.Items) { |         foreach (var item in req.Items) { | ||||||
|             sum += await DeleteAsync(item).ConfigureAwait(false); |             ret += await DeleteAsync(item).ConfigureAwait(false); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         return sum; |         return ret; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// <inheritdoc /> |     /// <inheritdoc /> | ||||||
| @@ -161,6 +163,8 @@ public sealed class VerifyCodeService(DefaultRepository<Sys_VerifyCode> rpo, IEv | |||||||
|             : await GetAsync(new QueryVerifyCodeReq { Id = req.Id }).ConfigureAwait(false); |             : await GetAsync(new QueryVerifyCodeReq { Id = req.Id }).ConfigureAwait(false); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     [0, 10000]; | ||||||
|  |  | ||||||
|     private Task<Sys_VerifyCode> GetLastSentAsync(string destDevice) |     private Task<Sys_VerifyCode> GetLastSentAsync(string destDevice) | ||||||
|     { |     { | ||||||
|         return QueryInternal(new QueryReq<QueryVerifyCodeReq> { |         return QueryInternal(new QueryReq<QueryVerifyCodeReq> { | ||||||
|   | |||||||
| @@ -16,12 +16,14 @@ public sealed class ExampleService(DefaultRepository<Tpl_Example> rpo) // | |||||||
|     public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req) |     public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req) | ||||||
|     { |     { | ||||||
|         req.ThrowIfInvalid(); |         req.ThrowIfInvalid(); | ||||||
|         var sum = 0; |         var ret = 0; | ||||||
|  |  | ||||||
|  |         // ReSharper disable once LoopCanBeConvertedToQuery | ||||||
|         foreach (var item in req.Items) { |         foreach (var item in req.Items) { | ||||||
|             sum += await DeleteAsync(item).ConfigureAwait(false); |             ret += await DeleteAsync(item).ConfigureAwait(false); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         return sum; |         return ret; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// <inheritdoc /> |     /// <inheritdoc /> | ||||||
|   | |||||||
| @@ -9,6 +9,12 @@ namespace NetAdmin.SysComponent.Cache.Sys; | |||||||
| public sealed class ToolsCache(IDistributedCache cache, IToolsService service) // | public sealed class ToolsCache(IDistributedCache cache, IToolsService service) // | ||||||
|     : DistributedCache<IToolsService>(cache, service), IScoped, IToolsCache |     : DistributedCache<IToolsService>(cache, service), IScoped, IToolsCache | ||||||
| { | { | ||||||
|  |     /// <inheritdoc /> | ||||||
|  |     public Task<string> GetChangeLogAsync() | ||||||
|  |     { | ||||||
|  |         return Service.GetChangeLogAsync(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /// <inheritdoc /> |     /// <inheritdoc /> | ||||||
|     public Task<IEnumerable<GetModulesRsp>> GetModulesAsync() |     public Task<IEnumerable<GetModulesRsp>> GetModulesAsync() | ||||||
|     { |     { | ||||||
|   | |||||||
| @@ -12,6 +12,15 @@ namespace NetAdmin.SysComponent.Host.Controllers.Sys; | |||||||
| [ApiDescriptionSettings(nameof(Sys), Module = nameof(Sys))] | [ApiDescriptionSettings(nameof(Sys), Module = nameof(Sys))] | ||||||
| public sealed class ToolsController(IToolsCache cache) : ControllerBase<IToolsCache, IToolsService>(cache), IToolsModule | public sealed class ToolsController(IToolsCache cache) : ControllerBase<IToolsCache, IToolsService>(cache), IToolsModule | ||||||
| { | { | ||||||
|  |     /// <summary> | ||||||
|  |     ///     获取更新日志 | ||||||
|  |     /// </summary> | ||||||
|  |     [AllowAnonymous] | ||||||
|  |     public Task<string> GetChangeLogAsync() | ||||||
|  |     { | ||||||
|  |         return Cache.GetChangeLogAsync(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /// <summary> |     /// <summary> | ||||||
|     ///     获取模块信息 |     ///     获取模块信息 | ||||||
|     /// </summary> |     /// </summary> | ||||||
|   | |||||||
| @@ -68,6 +68,7 @@ | |||||||
|             } |             } | ||||||
|  |  | ||||||
|             .app-loading__title { |             .app-loading__title { | ||||||
|  |                 font-family: 'Lucida Console', 'Microsoft YaHei', 'monospace'; | ||||||
|                 font-size: 24px; |                 font-size: 24px; | ||||||
|                 color: #333; |                 color: #333; | ||||||
|                 margin-top: 30px; |                 margin-top: 30px; | ||||||
|   | |||||||
| @@ -20,6 +20,8 @@ | |||||||
|         "element-plus": "^2.5.6", |         "element-plus": "^2.5.6", | ||||||
|         "json-bigint": "^1.0.0", |         "json-bigint": "^1.0.0", | ||||||
|         "json5-to-table": "^0.1.8", |         "json5-to-table": "^0.1.8", | ||||||
|  |         "markdown-it": "^14.0.0", | ||||||
|  |         "markdown-it-emoji": "^3.0.0", | ||||||
|         "nprogress": "^0.2.0", |         "nprogress": "^0.2.0", | ||||||
|         "pinyin-match": "^1.2.5", |         "pinyin-match": "^1.2.5", | ||||||
|         "qrcodejs2": "^0.0.2", |         "qrcodejs2": "^0.0.2", | ||||||
|   | |||||||
| @@ -5,6 +5,17 @@ | |||||||
| import config from '@/config' | import config from '@/config' | ||||||
| import http from '@/utils/request' | import http from '@/utils/request' | ||||||
| export default { | export default { | ||||||
|  |     /** | ||||||
|  |      * 获取更新日志 | ||||||
|  |      */ | ||||||
|  |     getChangeLog: { | ||||||
|  |         url: `${config.API_URL}/api/sys/tools/get.change.log`, | ||||||
|  |         name: `获取更新日志`, | ||||||
|  |         post: async function (data = {}, config = {}) { | ||||||
|  |             return await http.post(this.url, data, config) | ||||||
|  |         }, | ||||||
|  |     }, | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * 获取模块信息 |      * 获取模块信息 | ||||||
|      */ |      */ | ||||||
|   | |||||||
| @@ -4,7 +4,7 @@ | |||||||
|         :apiObj="$API.sys_dic.pagedQueryContent" |         :apiObj="$API.sys_dic.pagedQueryContent" | ||||||
|         :params="form" |         :params="form" | ||||||
|         :props="{ label: 'key', value: 'value' }" |         :props="{ label: 'key', value: 'value' }" | ||||||
|         :table-width="600" |         :table-width="60" | ||||||
|         clearable |         clearable | ||||||
|         ref="area"> |         ref="area"> | ||||||
|         <template #header> |         <template #header> | ||||||
|   | |||||||
| @@ -2,7 +2,7 @@ | |||||||
|     <el-table-column v-bind="$attrs"> |     <el-table-column v-bind="$attrs"> | ||||||
|         <template #default="scope"> |         <template #default="scope"> | ||||||
|             <div @click="click(tool.getNestedProperty(scope.row, $attrs.prop))" class="avatar" style="cursor: pointer"> |             <div @click="click(tool.getNestedProperty(scope.row, $attrs.prop))" class="avatar" style="cursor: pointer"> | ||||||
|                 <el-avatar :src="getAvatar(scope)" size="small"></el-avatar> |                 <el-avatar v-if="tool.getNestedProperty(scope.row, $attrs.nestProp)" :src="getAvatar(scope)" size="small"></el-avatar> | ||||||
|                 <el-text tag="ins">{{ tool.getNestedProperty(scope.row, $attrs.nestProp) }}</el-text> |                 <el-text tag="ins">{{ tool.getNestedProperty(scope.row, $attrs.nestProp) }}</el-text> | ||||||
|             </div> |             </div> | ||||||
|             <save-dialog v-if="dialog.save" @closed="dialog.save = false" ref="saveDialog"></save-dialog> |             <save-dialog v-if="dialog.save" @closed="dialog.save = false" ref="saveDialog"></save-dialog> | ||||||
|   | |||||||
| @@ -79,6 +79,7 @@ | |||||||
|             <el-input |             <el-input | ||||||
|                 v-if="item.type === 'input' && (!item.condition || item.condition())" |                 v-if="item.type === 'input' && (!item.condition || item.condition())" | ||||||
|                 v-model="form[item.field[0]][item.field[1]]" |                 v-model="form[item.field[0]][item.field[1]]" | ||||||
|  |                 v-role="item.role || '*/*/*'" | ||||||
|                 :class="item.class" |                 :class="item.class" | ||||||
|                 :placeholder="item.placeholder" |                 :placeholder="item.placeholder" | ||||||
|                 :style="item.style" |                 :style="item.style" | ||||||
| @@ -86,6 +87,7 @@ | |||||||
|             <sc-select |             <sc-select | ||||||
|                 v-else-if="item.type === 'remote-select' && (!item.condition || item.condition())" |                 v-else-if="item.type === 'remote-select' && (!item.condition || item.condition())" | ||||||
|                 v-model="form[item.field[0]][item.field[1]]" |                 v-model="form[item.field[0]][item.field[1]]" | ||||||
|  |                 v-role="item.role || '*/*/*'" | ||||||
|                 :apiObj="item.api" |                 :apiObj="item.api" | ||||||
|                 :class="item.class" |                 :class="item.class" | ||||||
|                 :config="item.config" |                 :config="item.config" | ||||||
| @@ -96,6 +98,7 @@ | |||||||
|             <el-select |             <el-select | ||||||
|                 v-else-if="item.type === 'select' && (!item.condition || item.condition())" |                 v-else-if="item.type === 'select' && (!item.condition || item.condition())" | ||||||
|                 v-model="form[item.field[0]][item.field[1]]" |                 v-model="form[item.field[0]][item.field[1]]" | ||||||
|  |                 v-role="item.role || '*/*/*'" | ||||||
|                 :class="item.class" |                 :class="item.class" | ||||||
|                 :multiple="item.multiple === true" |                 :multiple="item.multiple === true" | ||||||
|                 :placeholder="item.placeholder" |                 :placeholder="item.placeholder" | ||||||
| @@ -108,6 +111,7 @@ | |||||||
|             <el-cascader |             <el-cascader | ||||||
|                 v-else-if="casLoaded && item.type === 'cascader' && (!item.condition || item.condition())" |                 v-else-if="casLoaded && item.type === 'cascader' && (!item.condition || item.condition())" | ||||||
|                 v-model="form[item.field[0]][item.field[1]]" |                 v-model="form[item.field[0]][item.field[1]]" | ||||||
|  |                 v-role="item.role || '*/*/*'" | ||||||
|                 :class="item.class" |                 :class="item.class" | ||||||
|                 :options="item.options" |                 :options="item.options" | ||||||
|                 :placeholder="item.placeholder" |                 :placeholder="item.placeholder" | ||||||
| @@ -116,7 +120,6 @@ | |||||||
|                 clearable |                 clearable | ||||||
|                 filterable /> |                 filterable /> | ||||||
|         </template> |         </template> | ||||||
|  |  | ||||||
|         <el-button-group> |         <el-button-group> | ||||||
|             <el-button @click="search" icon="el-icon-search" type="primary">查询</el-button> |             <el-button @click="search" icon="el-icon-search" type="primary">查询</el-button> | ||||||
|             <el-button @click="reset" icon="el-icon-refresh-left">重置</el-button> |             <el-button @click="reset" icon="el-icon-refresh-left">重置</el-button> | ||||||
|   | |||||||
| @@ -4,7 +4,7 @@ | |||||||
|         :apiObj="$API.sys_user.pagedQuery" |         :apiObj="$API.sys_user.pagedQuery" | ||||||
|         :params="form" |         :params="form" | ||||||
|         :props="{ label: 'userName', value: 'id' }" |         :props="{ label: 'userName', value: 'id' }" | ||||||
|         :table-width="600" |         :table-width="60" | ||||||
|         clearable |         clearable | ||||||
|         ref="user"> |         ref="user"> | ||||||
|         <template #header> |         <template #header> | ||||||
|   | |||||||
| @@ -161,7 +161,7 @@ export default { | |||||||
|     height: 50px; |     height: 50px; | ||||||
|     line-height: 50px; |     line-height: 50px; | ||||||
|     text-align: left; |     text-align: left; | ||||||
|     font-size: 16px; |     font-size: 1.2rem; | ||||||
|     color: #45494c; |     color: #45494c; | ||||||
|     border-bottom: 1px solid #e4e7eb; |     border-bottom: 1px solid #e4e7eb; | ||||||
|     box-sizing: border-box; |     box-sizing: border-box; | ||||||
| @@ -228,10 +228,10 @@ export default { | |||||||
| /* ---------------------------- */ | /* ---------------------------- */ | ||||||
| /*常规验证码*/ | /*常规验证码*/ | ||||||
| .verify-code { | .verify-code { | ||||||
|     font-size: 20px; |     font-size: 1.5rem; | ||||||
|     text-align: center; |     text-align: center; | ||||||
|     cursor: pointer; |     cursor: pointer; | ||||||
|     margin-bottom: 5px; |     margin-bottom: 0.4rem; | ||||||
|     border: 1px solid #ddd; |     border: 1px solid #ddd; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -332,7 +332,7 @@ export default { | |||||||
|     width: 25px; |     width: 25px; | ||||||
|     height: 25px; |     height: 25px; | ||||||
|     text-align: center; |     text-align: center; | ||||||
|     padding: 5px; |     padding: 0.4rem; | ||||||
|     cursor: pointer; |     cursor: pointer; | ||||||
|     position: absolute; |     position: absolute; | ||||||
|     top: 0; |     top: 0; | ||||||
| @@ -341,7 +341,7 @@ export default { | |||||||
| } | } | ||||||
|  |  | ||||||
| .verify-img-panel .icon-refresh { | .verify-img-panel .icon-refresh { | ||||||
|     font-size: 20px; |     font-size: 1.5rem; | ||||||
|     color: #fff; |     color: #fff; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -360,7 +360,7 @@ export default { | |||||||
| } | } | ||||||
|  |  | ||||||
| .verify-bar-area .verify-move-block .verify-icon { | .verify-bar-area .verify-move-block .verify-icon { | ||||||
|     font-size: 18px; |     font-size: 1.4rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .verify-bar-area .verify-msg { | .verify-bar-area .verify-msg { | ||||||
| @@ -378,7 +378,7 @@ export default { | |||||||
|  |  | ||||||
| .iconfont { | .iconfont { | ||||||
|     font-family: 'iconfont', serif !important; |     font-family: 'iconfont', serif !important; | ||||||
|     font-size: 16px; |     font-size: 1.2rem; | ||||||
|     font-style: normal; |     font-style: normal; | ||||||
|     -webkit-font-smoothing: antialiased; |     -webkit-font-smoothing: antialiased; | ||||||
|     -moz-osx-font-smoothing: grayscale; |     -moz-osx-font-smoothing: grayscale; | ||||||
|   | |||||||
| @@ -89,34 +89,34 @@ export default { | |||||||
| .sc-contextmenu { | .sc-contextmenu { | ||||||
|     position: fixed; |     position: fixed; | ||||||
|     z-index: 3000; |     z-index: 3000; | ||||||
|     font-size: 12px; |     font-size: 0.9rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .sc-contextmenu__menu { | .sc-contextmenu__menu { | ||||||
|     display: inline-block; |     display: inline-block; | ||||||
|     min-width: 120px; |     min-width: 10rem; | ||||||
|     border: 1px solid #e4e7ed; |     border: 1px solid var(--el-border-color-light); | ||||||
|     background: #fff; |     background: var(--el-bg-color-overlay); | ||||||
|     box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); |     box-shadow: 0 0.2rem 1rem 0 rgba(0, 0, 0, 0.1); | ||||||
|     z-index: 3000; |     z-index: 3000; | ||||||
|     list-style-type: none; |     list-style-type: none; | ||||||
|     padding: 10px 0; |     padding: 0 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| .sc-contextmenu__menu > hr { | .sc-contextmenu__menu > hr { | ||||||
|     margin: 5px 0; |     margin: 0.4rem 0; | ||||||
|     border: none; |     border: none; | ||||||
|     height: 1px; |     height: 1px; | ||||||
|     font-size: 0; |     font-size: 0; | ||||||
|     background-color: #ebeef5; |     background-color: var(--el-border-color-light); | ||||||
| } | } | ||||||
|  |  | ||||||
| .sc-contextmenu__menu > li { | .sc-contextmenu__menu > li { | ||||||
|     margin: 0; |     margin: 0; | ||||||
|     cursor: pointer; |     cursor: pointer; | ||||||
|     line-height: 30px; |     line-height: 2.5rem; | ||||||
|     padding: 0 17px 0 10px; |     padding: 0 1.3rem 0 0.8rem; | ||||||
|     color: #606266; |     color: var(--el-text-color-primary); | ||||||
|     display: flex; |     display: flex; | ||||||
|     justify-content: space-between; |     justify-content: space-between; | ||||||
|     white-space: nowrap; |     white-space: nowrap; | ||||||
| @@ -125,8 +125,8 @@ export default { | |||||||
| } | } | ||||||
|  |  | ||||||
| .sc-contextmenu__menu > li:hover { | .sc-contextmenu__menu > li:hover { | ||||||
|     background-color: #ecf5ff; |     background-color: var(--el-color-primary-light-9); | ||||||
|     color: #66b1ff; |     color: var(--el-color-primary-light-2); | ||||||
| } | } | ||||||
|  |  | ||||||
| .sc-contextmenu__menu > li.disabled { | .sc-contextmenu__menu > li.disabled { | ||||||
| @@ -137,13 +137,13 @@ export default { | |||||||
|  |  | ||||||
| .sc-contextmenu__icon { | .sc-contextmenu__icon { | ||||||
|     display: inline-block; |     display: inline-block; | ||||||
|     width: 14px; |     width: 1rem; | ||||||
|     font-size: 14px; |     font-size: 1.1rem; | ||||||
|     margin-right: 10px; |     margin-right: 0.8rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .sc-contextmenu__suffix { | .sc-contextmenu__suffix { | ||||||
|     margin-left: 40px; |     margin-left: 3rem; | ||||||
|     color: #999; |     color: #999; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -152,6 +152,6 @@ export default { | |||||||
|     top: 0; |     top: 0; | ||||||
|     left: 100%; |     left: 100%; | ||||||
|     display: none; |     display: none; | ||||||
|     margin: -11px 0; |     margin: -0.8rem 0; | ||||||
| } | } | ||||||
| </style> | </style> | ||||||
| @@ -801,7 +801,7 @@ export default { | |||||||
| .sc-cron:deep(.el-tabs__item) { | .sc-cron:deep(.el-tabs__item) { | ||||||
|     height: auto; |     height: auto; | ||||||
|     line-height: 1; |     line-height: 1; | ||||||
|     padding: 0 7px; |     padding: 1rem; | ||||||
|     vertical-align: bottom; |     vertical-align: bottom; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -812,20 +812,20 @@ export default { | |||||||
| } | } | ||||||
|  |  | ||||||
| .sc-cron-num h2 { | .sc-cron-num h2 { | ||||||
|     font-size: 12px; |     font-size: 0.9rem; | ||||||
|     margin-bottom: 1rem; |     margin-bottom: 1rem; | ||||||
|     font-weight: normal; |     font-weight: normal; | ||||||
| } | } | ||||||
|  |  | ||||||
| .sc-cron-num h4 { | .sc-cron-num h4 { | ||||||
|     display: block; |     display: block; | ||||||
|     height: 32px; |     height: 2.5rem; | ||||||
|     line-height: 30px; |     line-height: 2.5rem; | ||||||
|     width: 100%; |     width: 100%; | ||||||
|     font-size: 12px; |     font-size: 0.9rem; | ||||||
|     padding: 0 1rem; |     padding: 0 1rem; | ||||||
|     background: var(--el-color-primary-light-9); |     background: var(--el-color-primary-light-9); | ||||||
|     border-radius: 4px; |     border-radius: 0.3rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .sc-cron:deep(.el-tabs__item.is-active) .sc-cron-num h4 { | .sc-cron:deep(.el-tabs__item.is-active) .sc-cron-num h4 { | ||||||
|   | |||||||
| @@ -106,7 +106,7 @@ export default { | |||||||
|  |  | ||||||
| .sc-cropper__preview h4 { | .sc-cropper__preview h4 { | ||||||
|     font-weight: normal; |     font-weight: normal; | ||||||
|     font-size: 12px; |     font-size: 0.9rem; | ||||||
|     color: #999; |     color: #999; | ||||||
|     margin-bottom: 20px; |     margin-bottom: 20px; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -90,7 +90,7 @@ export default { | |||||||
|     border: none; |     border: none; | ||||||
|     outline: none; |     outline: none; | ||||||
|     cursor: pointer; |     cursor: pointer; | ||||||
|     font-size: var(--el-message-close-size, 16px); |     font-size: var(--el-message-close-size, 1.2rem); | ||||||
|     margin-left: 1rem; |     margin-left: 1rem; | ||||||
|     color: var(--el-color-info); |     color: var(--el-color-info); | ||||||
| } | } | ||||||
| @@ -107,7 +107,7 @@ export default { | |||||||
| } | } | ||||||
|  |  | ||||||
| .sc-dialog:deep(.el-dialog) .el-dialog__body { | .sc-dialog:deep(.el-dialog) .el-dialog__body { | ||||||
|     padding-top: 10px; |     padding-top: 1rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .sc-dialog:deep(.el-dialog).is-fullscreen .el-dialog__body { | .sc-dialog:deep(.el-dialog).is-fullscreen .el-dialog__body { | ||||||
| @@ -116,7 +116,7 @@ export default { | |||||||
| } | } | ||||||
|  |  | ||||||
| .sc-dialog:deep(.el-dialog).is-fullscreen .el-dialog__footer { | .sc-dialog:deep(.el-dialog).is-fullscreen .el-dialog__footer { | ||||||
|     padding-bottom: 10px; |     padding-bottom: 1rem; | ||||||
|     border-top: 1px solid var(--el-border-color-base); |     border-top: 1px solid var(--el-border-color-base); | ||||||
| } | } | ||||||
| </style> | </style> | ||||||
| @@ -69,7 +69,7 @@ export default { | |||||||
|     data() { |     data() { | ||||||
|         return { |         return { | ||||||
|             init: { |             init: { | ||||||
|                 language_url: '/public/tinymce/langs/zh_CN.js', |                 language_url: '/tinymce/langs/zh_CN.js', | ||||||
|                 language: 'zh_CN', |                 language: 'zh_CN', | ||||||
|                 skin_url: '', |                 skin_url: '', | ||||||
|                 content_css: '', |                 content_css: '', | ||||||
| @@ -138,8 +138,8 @@ export default { | |||||||
|     }, |     }, | ||||||
|     created() { |     created() { | ||||||
|         const darkMode = this.$TOOL.data.get('APP_DARK') ?? false |         const darkMode = this.$TOOL.data.get('APP_DARK') ?? false | ||||||
|         this.init.skin_url = `/public/tinymce/skins/ui/tinymce-5${darkMode ? '-dark' : ''}` |         this.init.skin_url = `/tinymce/skins/ui/tinymce-5${darkMode ? '-dark' : ''}` | ||||||
|         this.init.content_css = `/public/tinymce/skins/content/tinymce-5${darkMode ? '-dark' : ''}/content.css` |         this.init.content_css = `/tinymce/skins/content/tinymce-5${darkMode ? '-dark' : ''}/content.css` | ||||||
|     }, |     }, | ||||||
|     mounted() { |     mounted() { | ||||||
|         tinymce.init({}) |         tinymce.init({}) | ||||||
|   | |||||||
| @@ -43,7 +43,7 @@ | |||||||
|                     </div> |                     </div> | ||||||
|                 </template> |                 </template> | ||||||
|             </el-upload> |             </el-upload> | ||||||
|             <el-form v-if="$slots.form" inline label-position="left" label-width="100px" style="margin-top: 18px"> |             <el-form v-if="$slots.form" inline label-position="left" label-width="10rem" style="margin-top: 18px"> | ||||||
|                 <slot :formData="formData" name="form"></slot> |                 <slot :formData="formData" name="form"></slot> | ||||||
|             </el-form> |             </el-form> | ||||||
|         </div> |         </div> | ||||||
|   | |||||||
| @@ -388,7 +388,7 @@ export default { | |||||||
| } | } | ||||||
|  |  | ||||||
| .sc-file-select__item__checkbox i { | .sc-file-select__item__checkbox i { | ||||||
|     font-size: 14px; |     font-size: 1.1rem; | ||||||
|     color: #fff; |     color: #fff; | ||||||
|     font-weight: bold; |     font-weight: bold; | ||||||
|     display: none; |     display: none; | ||||||
| @@ -409,7 +409,7 @@ export default { | |||||||
| } | } | ||||||
|  |  | ||||||
| .sc-file-select__item__select i { | .sc-file-select__item__select i { | ||||||
|     font-size: 14px; |     font-size: 1.1rem; | ||||||
|     color: #fff; |     color: #fff; | ||||||
|     font-weight: bold; |     font-weight: bold; | ||||||
| } | } | ||||||
| @@ -436,7 +436,7 @@ export default { | |||||||
| } | } | ||||||
|  |  | ||||||
| .sc-file-select__item__file .item-file i { | .sc-file-select__item__file .item-file i { | ||||||
|     font-size: 40px; |     font-size: 3rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .sc-file-select__item__file .item-file.item-file-doc { | .sc-file-select__item__file .item-file.item-file-doc { | ||||||
| @@ -485,14 +485,14 @@ export default { | |||||||
| } | } | ||||||
|  |  | ||||||
| .sc-file-select__top .tips { | .sc-file-select__top .tips { | ||||||
|     font-size: 12px; |     font-size: 0.9rem; | ||||||
|     margin-left: 10px; |     margin-left: 10px; | ||||||
|     color: #999; |     color: #999; | ||||||
| } | } | ||||||
|  |  | ||||||
| .sc-file-select__top .tips i { | .sc-file-select__top .tips i { | ||||||
|     font-size: 14px; |     font-size: 1.1rem; | ||||||
|     margin-right: 5px; |     margin-right: 0.4rem; | ||||||
|     position: relative; |     position: relative; | ||||||
|     bottom: -0.125em; |     bottom: -0.125em; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -394,7 +394,7 @@ export default { | |||||||
| } | } | ||||||
|  |  | ||||||
| .sc-filter-main h2 { | .sc-filter-main h2 { | ||||||
|     font-size: 12px; |     font-size: 0.9rem; | ||||||
|     color: #999; |     color: #999; | ||||||
|     font-weight: normal; |     font-weight: normal; | ||||||
| } | } | ||||||
| @@ -405,7 +405,7 @@ export default { | |||||||
| } | } | ||||||
|  |  | ||||||
| .sc-filter-main table td { | .sc-filter-main table td { | ||||||
|     padding: 5px 10px 5px 0; |     padding: 0.4rem 10px 5px 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| .sc-filter-main table td:deep(.el-input .el-input__inner) { | .sc-filter-main table td:deep(.el-input .el-input__inner) { | ||||||
| @@ -429,7 +429,7 @@ export default { | |||||||
|     line-height: 32px; |     line-height: 32px; | ||||||
|     text-align: center; |     text-align: center; | ||||||
|     border-radius: 50%; |     border-radius: 50%; | ||||||
|     font-size: 12px; |     font-size: 0.9rem; | ||||||
|     cursor: pointer; |     cursor: pointer; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -110,7 +110,7 @@ export default { | |||||||
| } | } | ||||||
|  |  | ||||||
| .sc-filter-my-list h2 { | .sc-filter-my-list h2 { | ||||||
|     font-size: 12px; |     font-size: 0.9rem; | ||||||
|     color: #999; |     color: #999; | ||||||
|     font-weight: normal; |     font-weight: normal; | ||||||
|     padding: 20px; |     padding: 20px; | ||||||
| @@ -130,7 +130,7 @@ export default { | |||||||
|  |  | ||||||
| .sc-filter-my-list li label { | .sc-filter-my-list li label { | ||||||
|     cursor: pointer; |     cursor: pointer; | ||||||
|     font-size: 14px; |     font-size: 1.1rem; | ||||||
|     line-height: 1.8; |     line-height: 1.8; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -123,7 +123,7 @@ | |||||||
|                         </template> |                         </template> | ||||||
|                         <!-- rate --> |                         <!-- rate --> | ||||||
|                         <template v-else-if="item.component === 'rate'"> |                         <template v-else-if="item.component === 'rate'"> | ||||||
|                             <el-rate v-model="form[item.name]" style="margin-top: 6px"></el-rate> |                             <el-rate v-model="form[item.name]" style="margin-top: 0.5rem"></el-rate> | ||||||
|                         </template> |                         </template> | ||||||
|                         <!-- slider --> |                         <!-- slider --> | ||||||
|                         <template v-else-if="item.component === 'slider'"> |                         <template v-else-if="item.component === 'slider'"> | ||||||
|   | |||||||
| @@ -4,7 +4,7 @@ | |||||||
|         :apiObj="apiObj" |         :apiObj="apiObj" | ||||||
|         :multiple="item.options.multiple" |         :multiple="item.options.multiple" | ||||||
|         :props="item.options.props" |         :props="item.options.props" | ||||||
|         :table-width="600" |         :table-width="60" | ||||||
|         style="width: 100%"> |         style="width: 100%"> | ||||||
|         <el-table-column |         <el-table-column | ||||||
|             v-for="(_item, _index) in item.options.column" |             v-for="(_item, _index) in item.options.column" | ||||||
|   | |||||||
| @@ -150,7 +150,7 @@ export default { | |||||||
|  |  | ||||||
| .sc-form-table .move { | .sc-form-table .move { | ||||||
|     text-align: center; |     text-align: center; | ||||||
|     font-size: 14px; |     font-size: 1.1rem; | ||||||
|     margin-top: 3px; |     margin-top: 0.2rem; | ||||||
| } | } | ||||||
| </style> | </style> | ||||||
| @@ -13,7 +13,7 @@ | |||||||
|             <el-input v-model="value" :disabled="disabled" :prefix-icon="value || 'el-icon-plus'" readonly></el-input> |             <el-input v-model="value" :disabled="disabled" :prefix-icon="value || 'el-icon-plus'" readonly></el-input> | ||||||
|         </div> |         </div> | ||||||
|         <el-dialog v-model="dialogVisible" :title="$t('图标选择器')" :width="760" append-to-body destroy-on-close> |         <el-dialog v-model="dialogVisible" :title="$t('图标选择器')" :width="760" append-to-body destroy-on-close> | ||||||
|             <div class="sc-icon-select__dialog" style="margin: -20px 0 -10px 0"> |             <div class="sc-icon-select__dialog"> | ||||||
|                 <el-form :rules="{}"> |                 <el-form :rules="{}"> | ||||||
|                     <el-form-item prop="searchText"> |                     <el-form-item prop="searchText"> | ||||||
|                         <el-input |                         <el-input | ||||||
| @@ -29,7 +29,7 @@ | |||||||
|                     <el-tab-pane v-for="item in data" :key="item.name" lazy> |                     <el-tab-pane v-for="item in data" :key="item.name" lazy> | ||||||
|                         <template #label> |                         <template #label> | ||||||
|                             {{ item.name }} |                             {{ item.name }} | ||||||
|                             <el-tag size="small" type="info">{{ item.icons.length }}</el-tag> |                             <el-tag size="small" style="margin-left: 0.5rem" type="info">{{ item.icons.length }}</el-tag> | ||||||
|                         </template> |                         </template> | ||||||
|                         <div class="sc-icon-select__list"> |                         <div class="sc-icon-select__list"> | ||||||
|                             <el-scrollbar> |                             <el-scrollbar> | ||||||
| @@ -140,7 +140,7 @@ export default { | |||||||
|  |  | ||||||
| .sc-icon-select__wrapper:deep(.el-input__icon) { | .sc-icon-select__wrapper:deep(.el-input__icon) { | ||||||
|     margin: 0; |     margin: 0; | ||||||
|     font-size: 16px; |     font-size: 1.2rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .sc-icon-select__wrapper.hasValue:deep(.el-input__icon) { | .sc-icon-select__wrapper.hasValue:deep(.el-input__icon) { | ||||||
| @@ -148,18 +148,18 @@ export default { | |||||||
| } | } | ||||||
|  |  | ||||||
| .sc-icon-select__list { | .sc-icon-select__list { | ||||||
|     height: 270px; |     height: 30rem; | ||||||
|     overflow: auto; |     overflow: auto; | ||||||
| } | } | ||||||
|  |  | ||||||
| .sc-icon-select__list li { | .sc-icon-select__list li { | ||||||
|     display: inline-block; |     display: inline-block; | ||||||
|     width: 80px; |     width: 6rem; | ||||||
|     height: 80px; |     height: 6rem; | ||||||
|     margin: 5px; |     margin: 0.4rem; | ||||||
|     vertical-align: top; |     vertical-align: top; | ||||||
|     transition: all 0.1s; |     transition: all 0.1s; | ||||||
|     border-radius: 4px; |     border-radius: 0.3rem; | ||||||
|     position: relative; |     position: relative; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -176,16 +176,16 @@ export default { | |||||||
| .sc-icon-select__list li i { | .sc-icon-select__list li i { | ||||||
|     width: 100%; |     width: 100%; | ||||||
|     height: 100%; |     height: 100%; | ||||||
|     font-size: 26px; |     font-size: 2rem; | ||||||
|     color: #6d7882; |     color: #6d7882; | ||||||
|     display: flex; |     display: flex; | ||||||
|     justify-content: center; |     justify-content: center; | ||||||
|     align-items: center; |     align-items: center; | ||||||
|     border-radius: 4px; |     border-radius: 0.3rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .sc-icon-select__list li:hover { | .sc-icon-select__list li:hover { | ||||||
|     box-shadow: 0 0 1px 4px var(--el-color-primary); |     box-shadow: 0 0 1px 0.3rem var(--el-color-primary); | ||||||
|     background: var(--el-color-primary-light-9); |     background: var(--el-color-primary-light-9); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -24,8 +24,8 @@ export default { | |||||||
| .sc-state { | .sc-state { | ||||||
|     display: inline-block; |     display: inline-block; | ||||||
|     background: #000; |     background: #000; | ||||||
|     width: 8px; |     width: 0.6rem; | ||||||
|     height: 8px; |     height: 0.6rem; | ||||||
|     border-radius: 50%; |     border-radius: 50%; | ||||||
|     vertical-align: middle; |     vertical-align: middle; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -61,7 +61,7 @@ export default { | |||||||
| } | } | ||||||
|  |  | ||||||
| .sc-trend-icon { | .sc-trend-icon { | ||||||
|     margin-right: 2px; |     margin-right: 0.2rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .sc-trend em { | .sc-trend em { | ||||||
| @@ -69,11 +69,11 @@ export default { | |||||||
| } | } | ||||||
|  |  | ||||||
| .sc-trend-prefix { | .sc-trend-prefix { | ||||||
|     margin-right: 2px; |     margin-right: 0.2rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .sc-trend-suffix { | .sc-trend-suffix { | ||||||
|     margin-left: 2px; |     margin-left: 0.2rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .sc-trend--P { | .sc-trend--P { | ||||||
|   | |||||||
| @@ -42,17 +42,17 @@ export default { | |||||||
| .sc-page-header { | .sc-page-header { | ||||||
|     background: #fff; |     background: #fff; | ||||||
|     border-bottom: 1px solid #e6e6e6; |     border-bottom: 1px solid #e6e6e6; | ||||||
|     padding: 20px 25px; |     padding: 1.5rem 2rem; | ||||||
|     display: flex; |     display: flex; | ||||||
| } | } | ||||||
|  |  | ||||||
| .sc-page-header__icon { | .sc-page-header__icon { | ||||||
|     width: 50px; |     width: 4rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .sc-page-header__icon span { | .sc-page-header__icon span { | ||||||
|     width: 30px; |     width: 2.5rem; | ||||||
|     height: 30px; |     height: 2.5rem; | ||||||
|     background: #409eff; |     background: #409eff; | ||||||
|     border-radius: 40%; |     border-radius: 40%; | ||||||
|     display: flex; |     display: flex; | ||||||
| @@ -62,7 +62,7 @@ export default { | |||||||
|  |  | ||||||
| .sc-page-header__icon span i { | .sc-page-header__icon span i { | ||||||
|     color: #fff; |     color: #fff; | ||||||
|     font-size: 14px; |     font-size: 1.1rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .sc-page-header__title { | .sc-page-header__title { | ||||||
| @@ -70,14 +70,14 @@ export default { | |||||||
| } | } | ||||||
|  |  | ||||||
| .sc-page-header__title h2 { | .sc-page-header__title h2 { | ||||||
|     font-size: 17px; |     font-size: 1.3rem; | ||||||
|     color: #3c4a54; |     color: #3c4a54; | ||||||
|     font-weight: bold; |     font-weight: bold; | ||||||
|     margin-top: 3px; |     margin-top: 0.3rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .sc-page-header__title p { | .sc-page-header__title p { | ||||||
|     font-size: 13px; |     font-size: 1rem; | ||||||
|     color: #999; |     color: #999; | ||||||
|     margin-top: 1rem; |     margin-top: 1rem; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -103,7 +103,7 @@ export default { | |||||||
|     display: block; |     display: block; | ||||||
|     width: 20%; |     width: 20%; | ||||||
|     height: inherit; |     height: inherit; | ||||||
|     border: 5px solid var(--el-bg-color-overlay); |     border: 0.4rem solid var(--el-bg-color-overlay); | ||||||
|     border-top: 0; |     border-top: 0; | ||||||
|     border-bottom: 0; |     border-bottom: 0; | ||||||
|     z-index: 1; |     z-index: 1; | ||||||
|   | |||||||
| @@ -98,15 +98,15 @@ export default { | |||||||
|     bottom: 0; |     bottom: 0; | ||||||
|     background: #fff; |     background: #fff; | ||||||
|     z-index: 100; |     z-index: 100; | ||||||
|     border-radius: 5px; |     border-radius: 0.4rem; | ||||||
|     border: 1px solid #ebeef5; |     border: 1px solid #ebeef5; | ||||||
|     display: flex; |     display: flex; | ||||||
|     align-items: center; |     align-items: center; | ||||||
|     padding-left: 10px; |     padding-left: 1rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .sc-select-loading i { | .sc-select-loading i { | ||||||
|     font-size: 14px; |     font-size: 1.1rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .dark .sc-select-loading { | .dark .sc-select-loading { | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ | |||||||
|     <div class="sc-select-filter"> |     <div class="sc-select-filter"> | ||||||
|         <div v-if="data.length <= 0" class="sc-select-filter__no-data">暂无数据</div> |         <div v-if="data.length <= 0" class="sc-select-filter__no-data">暂无数据</div> | ||||||
|         <div v-for="item in data" :key="item.key" class="sc-select-filter__item"> |         <div v-for="item in data" :key="item.key" class="sc-select-filter__item"> | ||||||
|             <div :style="{ width: labelWidth + 'px' }" class="sc-select-filter__item-title"> |             <div :style="{ width: labelWidth + 'rem' }" class="sc-select-filter__item-title"> | ||||||
|                 <label>{{ item.title }}:</label> |                 <label>{{ item.title }}:</label> | ||||||
|             </div> |             </div> | ||||||
|             <div class="sc-select-filter__item-options"> |             <div class="sc-select-filter__item-options"> | ||||||
| @@ -42,7 +42,7 @@ export default { | |||||||
|                 return {} |                 return {} | ||||||
|             }, |             }, | ||||||
|         }, |         }, | ||||||
|         labelWidth: { type: Number, default: 80 }, |         labelWidth: { type: Number, default: 6 }, | ||||||
|         outputValueTypeToArray: { type: Boolean, default: false }, |         outputValueTypeToArray: { type: Boolean, default: false }, | ||||||
|     }, |     }, | ||||||
|     data() { |     data() { | ||||||
| @@ -137,12 +137,12 @@ export default { | |||||||
| } | } | ||||||
|  |  | ||||||
| .sc-select-filter__item-title { | .sc-select-filter__item-title { | ||||||
|     width: 80px; |     width: 6rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .sc-select-filter__item-title label { | .sc-select-filter__item-title label { | ||||||
|     font-size: 14px; |     font-size: 1.1rem; | ||||||
|     padding-top: 13px; |     padding-top: 1rem; | ||||||
|     display: inline-block; |     display: inline-block; | ||||||
|     color: #999; |     color: #999; | ||||||
| } | } | ||||||
| @@ -155,24 +155,24 @@ export default { | |||||||
| .sc-select-filter__item-options ul { | .sc-select-filter__item-options ul { | ||||||
|     display: flex; |     display: flex; | ||||||
|     flex-wrap: wrap; |     flex-wrap: wrap; | ||||||
|     padding-top: 10px; |     padding-top: 1rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .sc-select-filter__item-options li { | .sc-select-filter__item-options li { | ||||||
|     list-style: none; |     list-style: none; | ||||||
|     cursor: pointer; |     cursor: pointer; | ||||||
|     height: 28px; |     height: 2rem; | ||||||
|     padding: 0 1rem; |     padding: 0 1rem; | ||||||
|     border-radius: 32px; |     border-radius: 2.5rem; | ||||||
|     margin: 0 10px 10px 0; |     margin: 0 1rem 1rem 0; | ||||||
|     display: flex; |     display: flex; | ||||||
|     align-items: center; |     align-items: center; | ||||||
|     background: var(--el-color-primary-light-9); |     background: var(--el-color-primary-light-9); | ||||||
| } | } | ||||||
|  |  | ||||||
| .sc-select-filter__item-options li .el-icon { | .sc-select-filter__item-options li .el-icon { | ||||||
|     margin-right: 3px; |     margin-right: 0.2rem; | ||||||
|     font-size: 16px; |     font-size: 1.2rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .sc-select-filter__item-options li:hover { | .sc-select-filter__item-options li:hover { | ||||||
|   | |||||||
| @@ -13,7 +13,7 @@ | |||||||
|             {{ title }} |             {{ title }} | ||||||
|             <el-tooltip v-if="tips" effect="light"> |             <el-tooltip v-if="tips" effect="light"> | ||||||
|                 <template #content> |                 <template #content> | ||||||
|                     <div style="width: 200px; line-height: 2"> |                     <div style="width: 15rem; line-height: 2"> | ||||||
|                         {{ tips }} |                         {{ tips }} | ||||||
|                     </div> |                     </div> | ||||||
|                 </template> |                 </template> | ||||||
| @@ -59,19 +59,19 @@ export default { | |||||||
|  |  | ||||||
| <style scoped> | <style scoped> | ||||||
| .sc-statistic-title { | .sc-statistic-title { | ||||||
|     font-size: 12px; |     font-size: 0.9rem; | ||||||
|     color: #999; |     color: #999; | ||||||
|     margin-bottom: 10px; |     margin-bottom: 1rem; | ||||||
|     display: flex; |     display: flex; | ||||||
|     align-items: center; |     align-items: center; | ||||||
| } | } | ||||||
|  |  | ||||||
| .sc-statistic-tips { | .sc-statistic-tips { | ||||||
|     margin-left: 5px; |     margin-left: 0.4rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .sc-statistic-content { | .sc-statistic-content { | ||||||
|     font-size: 20px; |     font-size: 1.5rem; | ||||||
|     color: #333; |     color: #333; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -80,16 +80,16 @@ export default { | |||||||
| } | } | ||||||
|  |  | ||||||
| .sc-statistic-content-prefix { | .sc-statistic-content-prefix { | ||||||
|     margin-right: 5px; |     margin-right: 0.4rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .sc-statistic-content-suffix { | .sc-statistic-content-suffix { | ||||||
|     margin-left: 5px; |     margin-left: 0.4rem; | ||||||
|     font-size: 12px; |     font-size: 0.9rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .sc-statistic-description { | .sc-statistic-description { | ||||||
|     margin-top: 10px; |     margin-top: 1rem; | ||||||
|     color: #999; |     color: #999; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -103,63 +103,63 @@ export default { | |||||||
|     display: inline-block; |     display: inline-block; | ||||||
|     font-weight: bold; |     font-weight: bold; | ||||||
|     color: #909399; |     color: #909399; | ||||||
|     font-size: 12px; |     font-size: 0.9rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .setting-column__title span.move_b { | .setting-column__title span.move_b { | ||||||
|     width: 30px; |     width: 2.5rem; | ||||||
|     margin-right: 1rem; |     margin-right: 1rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .setting-column__title span.show_b { | .setting-column__title span.show_b { | ||||||
|     width: 60px; |     width: 5rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .setting-column__title span.name_b { | .setting-column__title span.name_b { | ||||||
|     width: 140px; |     width: 10rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .setting-column__title span.width_b { | .setting-column__title span.width_b { | ||||||
|     width: 60px; |     width: 5rem; | ||||||
|     margin-right: 1rem; |     margin-right: 1rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .setting-column__title span.sortable_b { | .setting-column__title span.sortable_b { | ||||||
|     width: 60px; |     width: 5rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .setting-column__title span.fixed_b { | .setting-column__title span.fixed_b { | ||||||
|     width: 60px; |     width: 5rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .setting-column__list { | .setting-column__list { | ||||||
|     max-height: 314px; |     max-height: 25rem; | ||||||
|     overflow: auto; |     overflow: auto; | ||||||
| } | } | ||||||
|  |  | ||||||
| .setting-column__list li { | .setting-column__list li { | ||||||
|     list-style: none; |     list-style: none; | ||||||
|     margin: 10px 0; |     margin: 1rem 0; | ||||||
|     display: flex; |     display: flex; | ||||||
|     align-items: center; |     align-items: center; | ||||||
| } | } | ||||||
|  |  | ||||||
| .setting-column__list li > span { | .setting-column__list li > span { | ||||||
|     display: inline-block; |     display: inline-block; | ||||||
|     font-size: 12px; |     font-size: 0.9rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .setting-column__list li span.move_b { | .setting-column__list li span.move_b { | ||||||
|     width: 30px; |     width: 2.5rem; | ||||||
|     margin-right: 1rem; |     margin-right: 1rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .setting-column__list li span.show_b { | .setting-column__list li span.show_b { | ||||||
|     width: 60px; |     width: 5rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .setting-column__list li span.name_b { | .setting-column__list li span.name_b { | ||||||
|     width: 140px; |     width: 10rem; | ||||||
|     white-space: nowrap; |     white-space: nowrap; | ||||||
|     text-overflow: ellipsis; |     text-overflow: ellipsis; | ||||||
|     overflow: hidden; |     overflow: hidden; | ||||||
| @@ -167,16 +167,16 @@ export default { | |||||||
| } | } | ||||||
|  |  | ||||||
| .setting-column__list li span.width_b { | .setting-column__list li span.width_b { | ||||||
|     width: 60px; |     width: 5rem; | ||||||
|     margin-right: 1rem; |     margin-right: 1rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .setting-column__list li span.sortable_b { | .setting-column__list li span.sortable_b { | ||||||
|     width: 60px; |     width: 5rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .setting-column__list li span.fixed_b { | .setting-column__list li span.fixed_b { | ||||||
|     width: 60px; |     width: 5rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .setting-column__list li.ghost { | .setting-column__list li.ghost { | ||||||
|   | |||||||
| @@ -91,7 +91,7 @@ | |||||||
|                     <template #reference> |                     <template #reference> | ||||||
|                         <el-button circle icon="el-icon-setting" style="margin-left: 1rem"></el-button> |                         <el-button circle icon="el-icon-setting" style="margin-left: 1rem"></el-button> | ||||||
|                     </template> |                     </template> | ||||||
|                     <el-form label-position="left" label-width="80px"> |                     <el-form label-position="left" label-width="10rem"> | ||||||
|                         <el-form-item :label="$t('表格尺寸')"> |                         <el-form-item :label="$t('表格尺寸')"> | ||||||
|                             <el-radio-group v-model="config.size" @change="configSizeChange" size="small"> |                             <el-radio-group v-model="config.size" @change="configSizeChange" size="small"> | ||||||
|                                 <el-radio-button label="large">大</el-radio-button> |                                 <el-radio-button label="large">大</el-radio-button> | ||||||
| @@ -179,7 +179,7 @@ export default { | |||||||
|             return Number(this.height) ? Number(this.height) + 'px' : this.height |             return Number(this.height) ? Number(this.height) + 'px' : this.height | ||||||
|         }, |         }, | ||||||
|         _table_height() { |         _table_height() { | ||||||
|             return this.hidePagination && this.hideDo ? '100%' : 'calc(100% - 50px)' |             return this.hidePagination && this.hideDo ? '100%' : 'calc(100% - 4rem)' | ||||||
|         }, |         }, | ||||||
|     }, |     }, | ||||||
|     data() { |     data() { | ||||||
| @@ -483,11 +483,11 @@ export default { | |||||||
| } | } | ||||||
|  |  | ||||||
| .scTable-table { | .scTable-table { | ||||||
|     height: calc(100% - 50px); |     height: calc(100% - 4rem); | ||||||
| } | } | ||||||
|  |  | ||||||
| .scTable-page { | .scTable-page { | ||||||
|     height: 50px; |     height: 4rem; | ||||||
|     display: flex; |     display: flex; | ||||||
|     align-items: center; |     align-items: center; | ||||||
|     justify-content: space-between; |     justify-content: space-between; | ||||||
| @@ -503,12 +503,12 @@ export default { | |||||||
| } | } | ||||||
|  |  | ||||||
| .scTable:deep(.el-table__body-wrapper) .el-scrollbar__bar.is-horizontal { | .scTable:deep(.el-table__body-wrapper) .el-scrollbar__bar.is-horizontal { | ||||||
|     height: 12px; |     height: 0.9rem; | ||||||
|     border-radius: 12px; |     border-radius: 0.9rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .scTable:deep(.el-table__body-wrapper) .el-scrollbar__bar.is-vertical { | .scTable:deep(.el-table__body-wrapper) .el-scrollbar__bar.is-vertical { | ||||||
|     width: 12px; |     width: 0.9rem; | ||||||
|     border-radius: 12px; |     border-radius: 0.9rem; | ||||||
| } | } | ||||||
| </style> | </style> | ||||||
| @@ -1,28 +0,0 @@ | |||||||
| <template> |  | ||||||
|     <div class="sc-title"> |  | ||||||
|         {{ title }} |  | ||||||
|     </div> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
| export default { |  | ||||||
|     props: { |  | ||||||
|         title: { type: String, required: true, default: '' }, |  | ||||||
|     }, |  | ||||||
|     data() { |  | ||||||
|         return {} |  | ||||||
|     }, |  | ||||||
|     computed: {}, |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style scoped> |  | ||||||
| .sc-title { |  | ||||||
|     border-bottom: 1px solid #eee; |  | ||||||
|     margin-bottom: 20px; |  | ||||||
|     font-size: 17px; |  | ||||||
|     padding-bottom: 1rem; |  | ||||||
|     color: #3c4a54; |  | ||||||
|     font-weight: bold; |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
| @@ -68,8 +68,8 @@ const scCropper = defineAsyncComponent(() => import('@/components/scCropper')) | |||||||
| export default { | export default { | ||||||
|     props: { |     props: { | ||||||
|         modelValue: { type: String, default: '' }, |         modelValue: { type: String, default: '' }, | ||||||
|         height: { type: Number, default: 148 }, |         height: { type: Number, default: 10 }, | ||||||
|         width: { type: Number, default: 148 }, |         width: { type: Number, default: 10 }, | ||||||
|         title: { type: String, default: '' }, |         title: { type: String, default: '' }, | ||||||
|         icon: { type: String, default: 'el-icon-plus' }, |         icon: { type: String, default: 'el-icon-plus' }, | ||||||
|         action: { type: String, default: '' }, |         action: { type: String, default: '' }, | ||||||
| @@ -108,8 +108,8 @@ export default { | |||||||
|             value: '', |             value: '', | ||||||
|             file: null, |             file: null, | ||||||
|             style: { |             style: { | ||||||
|                 width: this.width + 'px', |                 width: this.width + 'rem', | ||||||
|                 height: this.height + 'px', |                 height: this.height + 'rem', | ||||||
|             }, |             }, | ||||||
|             cropperDialogVisible: false, |             cropperDialogVisible: false, | ||||||
|             cropperFile: null, |             cropperFile: null, | ||||||
| @@ -309,14 +309,14 @@ export default { | |||||||
|     display: flex; |     display: flex; | ||||||
|     justify-content: center; |     justify-content: center; | ||||||
|     align-items: center; |     align-items: center; | ||||||
|     width: 25px; |     width: 1.9rem; | ||||||
|     height: 25px; |     height: 1.9rem; | ||||||
|     cursor: pointer; |     cursor: pointer; | ||||||
|     color: #fff; |     color: #fff; | ||||||
| } | } | ||||||
|  |  | ||||||
| .sc-upload__img-actions span i { | .sc-upload__img-actions span i { | ||||||
|     font-size: 12px; |     font-size: 0.9rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .sc-upload__img-actions .del { | .sc-upload__img-actions .del { | ||||||
| @@ -333,7 +333,7 @@ export default { | |||||||
|     align-items: center; |     align-items: center; | ||||||
|     width: 100%; |     width: 100%; | ||||||
|     height: 100%; |     height: 100%; | ||||||
|     font-size: 12px; |     font-size: 0.9rem; | ||||||
|     background-color: var(--el-fill-color-lighter); |     background-color: var(--el-fill-color-lighter); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -352,7 +352,7 @@ export default { | |||||||
|     align-items: center; |     align-items: center; | ||||||
|     background-color: var(--el-overlay-color-lighter); |     background-color: var(--el-overlay-color-lighter); | ||||||
|     z-index: 1; |     z-index: 1; | ||||||
|     padding: 10px; |     padding: 1rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .sc-upload__progress .el-progress { | .sc-upload__progress .el-progress { | ||||||
| @@ -374,14 +374,14 @@ export default { | |||||||
| } | } | ||||||
|  |  | ||||||
| .sc-upload .file-empty i { | .sc-upload .file-empty i { | ||||||
|     font-size: 28px; |     font-size: 2rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .sc-upload .file-empty h4 { | .sc-upload .file-empty h4 { | ||||||
|     font-size: 12px; |     font-size: 0.9rem; | ||||||
|     font-weight: normal; |     font-weight: normal; | ||||||
|     color: #8c939d; |     color: #8c939d; | ||||||
|     margin-top: 8px; |     margin-top: 1rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .sc-upload.sc-upload-round { | .sc-upload.sc-upload-round { | ||||||
|   | |||||||
| @@ -297,7 +297,7 @@ export default { | |||||||
|     align-items: center; |     align-items: center; | ||||||
|     width: 100%; |     width: 100%; | ||||||
|     height: 100%; |     height: 100%; | ||||||
|     font-size: 12px; |     font-size: 0.9rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .sc-upload-multiple .el-upload-list__item:hover .sc-upload__item-actions { | .sc-upload-multiple .el-upload-list__item:hover .sc-upload__item-actions { | ||||||
| @@ -322,7 +322,7 @@ export default { | |||||||
| } | } | ||||||
|  |  | ||||||
| .sc-upload__item-actions span i { | .sc-upload__item-actions span i { | ||||||
|     font-size: 12px; |     font-size: 0.9rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .sc-upload__item-actions .del { | .sc-upload__item-actions .del { | ||||||
|   | |||||||
| @@ -1,111 +0,0 @@ | |||||||
| <!-- |  | ||||||
|  * @Descripttion: xgplayer二次封装 |  | ||||||
|  * @version: 1.1 |  | ||||||
|  * @Author: sakuya |  | ||||||
|  * @Date: 2021年11月29日12:10:06 |  | ||||||
|  * @LastEditors: Xujianchen |  | ||||||
|  * @LastEditTime: 2023-03-18 13:14:13 |  | ||||||
| --> |  | ||||||
|  |  | ||||||
| <template> |  | ||||||
|     <div class="sc-video" ref="scVideo"></div> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
| import Player from 'xgplayer' |  | ||||||
| import HlsPlayer from 'xgplayer-hls' |  | ||||||
|  |  | ||||||
| export default { |  | ||||||
|     props: { |  | ||||||
|         src: { type: String, required: true, default: '' }, |  | ||||||
|         autoplay: { type: Boolean, default: false }, |  | ||||||
|         controls: { type: Boolean, default: true }, |  | ||||||
|         loop: { type: Boolean, default: false }, |  | ||||||
|         isLive: { type: Boolean, default: false }, |  | ||||||
|         options: { |  | ||||||
|             type: Object, |  | ||||||
|             default: () => {}, |  | ||||||
|         }, |  | ||||||
|     }, |  | ||||||
|     data() { |  | ||||||
|         return { |  | ||||||
|             player: null, |  | ||||||
|         } |  | ||||||
|     }, |  | ||||||
|     watch: { |  | ||||||
|         src(val) { |  | ||||||
|             if (this.player.hasStart) { |  | ||||||
|                 this.player.src = val |  | ||||||
|             } else { |  | ||||||
|                 this.player.start(val) |  | ||||||
|             } |  | ||||||
|         }, |  | ||||||
|     }, |  | ||||||
|     mounted() { |  | ||||||
|         if (this.isLive) { |  | ||||||
|             this.initHls() |  | ||||||
|         } else { |  | ||||||
|             this.init() |  | ||||||
|         } |  | ||||||
|     }, |  | ||||||
|     methods: { |  | ||||||
|         init() { |  | ||||||
|             this.player = new Player({ |  | ||||||
|                 el: this.$refs.scVideo, |  | ||||||
|                 url: this.src, |  | ||||||
|                 autoplay: this.autoplay, |  | ||||||
|                 loop: this.loop, |  | ||||||
|                 controls: this.controls, |  | ||||||
|                 fluid: true, |  | ||||||
|                 lang: 'zh-cn', |  | ||||||
|                 ...this.options, |  | ||||||
|             }) |  | ||||||
|         }, |  | ||||||
|         initHls() { |  | ||||||
|             this.player = new HlsPlayer({ |  | ||||||
|                 el: this.$refs.scVideo, |  | ||||||
|                 url: this.src, |  | ||||||
|                 autoplay: this.autoplay, |  | ||||||
|                 loop: this.loop, |  | ||||||
|                 controls: this.controls, |  | ||||||
|                 fluid: true, |  | ||||||
|                 isLive: true, |  | ||||||
|                 ignores: ['time', 'progress'], |  | ||||||
|                 lang: 'zh-cn', |  | ||||||
|                 ...this.options, |  | ||||||
|             }) |  | ||||||
|         }, |  | ||||||
|     }, |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style scoped> |  | ||||||
| .sc-video:deep(.danmu) > * { |  | ||||||
|     color: #fff; |  | ||||||
|     font-size: 20px; |  | ||||||
|     font-weight: bold; |  | ||||||
|     text-shadow: |  | ||||||
|         1px 1px 0 #000, |  | ||||||
|         -1px -1px 0 #000, |  | ||||||
|         -1px 1px 0 #000, |  | ||||||
|         1px -1px 0 #000; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .sc-video:deep(.xgplayer-controls) { |  | ||||||
|     background-image: linear-gradient(180deg, transparent, rgba(0, 0, 0, 0.3)); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .sc-video:deep(.xgplayer-progress-tip) { |  | ||||||
|     border: 0; |  | ||||||
|     color: #fff; |  | ||||||
|     background: rgba(0, 0, 0, 0.5); |  | ||||||
|     line-height: 25px; |  | ||||||
|     padding: 0 10px; |  | ||||||
|     border-radius: 25px; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .sc-video:deep(.xgplayer-enter-spinner) { |  | ||||||
|     width: 50px; |  | ||||||
|     height: 50px; |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
| @@ -1,572 +0,0 @@ | |||||||
| <!-- |  | ||||||
|  * @Descripttion: 仿钉钉流程设计器 |  | ||||||
|  * @version: 1.3 |  | ||||||
|  * @Author: sakuya |  | ||||||
|  * @Date: 2021年9月14日08:38:35 |  | ||||||
|  * @LastEditors: Xujianchen |  | ||||||
|  * @LastEditTime: 2023-03-18 13:16:31 |  | ||||||
| --> |  | ||||||
|  |  | ||||||
| <template> |  | ||||||
|     <div class="sc-workflow-design"> |  | ||||||
|         <div class="box-scale"> |  | ||||||
|             <node-wrap v-if="nodeConfig" v-model="nodeConfig"></node-wrap> |  | ||||||
|             <div class="end-node"> |  | ||||||
|                 <div class="end-node-circle"></div> |  | ||||||
|                 <div class="end-node-text">流程结束</div> |  | ||||||
|             </div> |  | ||||||
|         </div> |  | ||||||
|         <use-select v-if="selectVisible" @closed="selectVisible = false" ref="useselect"></use-select> |  | ||||||
|     </div> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
| import nodeWrap from './nodeWrap' |  | ||||||
| import useSelect from './select' |  | ||||||
|  |  | ||||||
| export default { |  | ||||||
|     provide() { |  | ||||||
|         return { |  | ||||||
|             select: this.selectHandle, |  | ||||||
|         } |  | ||||||
|     }, |  | ||||||
|     props: { |  | ||||||
|         modelValue: { |  | ||||||
|             type: Object, |  | ||||||
|             default: () => {}, |  | ||||||
|         }, |  | ||||||
|     }, |  | ||||||
|     components: { |  | ||||||
|         nodeWrap, |  | ||||||
|         useSelect, |  | ||||||
|     }, |  | ||||||
|     data() { |  | ||||||
|         return { |  | ||||||
|             nodeConfig: this.modelValue, |  | ||||||
|             selectVisible: false, |  | ||||||
|         } |  | ||||||
|     }, |  | ||||||
|     watch: { |  | ||||||
|         modelValue(val) { |  | ||||||
|             this.nodeConfig = val |  | ||||||
|         }, |  | ||||||
|         nodeConfig(val) { |  | ||||||
|             this.$emit('update:modelValue', val) |  | ||||||
|         }, |  | ||||||
|     }, |  | ||||||
|     mounted() {}, |  | ||||||
|     methods: { |  | ||||||
|         selectHandle(type, data) { |  | ||||||
|             this.selectVisible = true |  | ||||||
|             this.$nextTick(() => { |  | ||||||
|                 this.$refs.useselect.open(type, data) |  | ||||||
|             }) |  | ||||||
|         }, |  | ||||||
|     }, |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style lang="scss"> |  | ||||||
| .sc-workflow-design { |  | ||||||
|     width: 100%; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .sc-workflow-design .box-scale { |  | ||||||
|     display: inline-block; |  | ||||||
|     position: relative; |  | ||||||
|     width: 100%; |  | ||||||
|     padding: 54.5px 0; |  | ||||||
|     align-items: flex-start; |  | ||||||
|     justify-content: center; |  | ||||||
|     flex-wrap: wrap; |  | ||||||
|     min-width: min-content; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .sc-workflow-design { |  | ||||||
|     .node-wrap { |  | ||||||
|         display: inline-flex; |  | ||||||
|         width: 100%; |  | ||||||
|         flex-flow: column wrap; |  | ||||||
|         justify-content: flex-start; |  | ||||||
|         align-items: center; |  | ||||||
|         padding: 0 50px; |  | ||||||
|         position: relative; |  | ||||||
|         z-index: 1; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .node-wrap-box { |  | ||||||
|         display: inline-flex; |  | ||||||
|         flex-direction: column; |  | ||||||
|         position: relative; |  | ||||||
|         width: 220px; |  | ||||||
|         min-height: 72px; |  | ||||||
|         flex-shrink: 0; |  | ||||||
|         background: rgb(255, 255, 255); |  | ||||||
|         border-radius: 4px; |  | ||||||
|         cursor: pointer; |  | ||||||
|         box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.1); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .node-wrap-box::before { |  | ||||||
|         content: ''; |  | ||||||
|         position: absolute; |  | ||||||
|         top: -12px; |  | ||||||
|         left: 50%; |  | ||||||
|         transform: translateX(-50%); |  | ||||||
|         width: 0; |  | ||||||
|         border-style: solid; |  | ||||||
|         border-width: 8px 6px 4px; |  | ||||||
|         border-color: rgb(202, 202, 202) transparent transparent; |  | ||||||
|         background: #f6f8f9; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .node-wrap-box.start-node:before { |  | ||||||
|         content: none; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .node-wrap-box .title { |  | ||||||
|         height: 24px; |  | ||||||
|         line-height: 24px; |  | ||||||
|         color: #fff; |  | ||||||
|         padding-left: 16px; |  | ||||||
|         padding-right: 30px; |  | ||||||
|         border-radius: 4px 4px 0 0; |  | ||||||
|         position: relative; |  | ||||||
|         display: flex; |  | ||||||
|         align-items: center; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .node-wrap-box .title .icon { |  | ||||||
|         margin-right: 5px; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .node-wrap-box .title .close { |  | ||||||
|         font-size: 1rem; |  | ||||||
|         position: absolute; |  | ||||||
|         top: 50%; |  | ||||||
|         transform: translateY(-50%); |  | ||||||
|         right: 10px; |  | ||||||
|         display: none; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .node-wrap-box .content { |  | ||||||
|         position: relative; |  | ||||||
|         padding: 1rem; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .node-wrap-box .content .placeholder { |  | ||||||
|         color: #999; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .node-wrap-box:hover .close { |  | ||||||
|         display: block; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .add-node-btn-box { |  | ||||||
|         width: 240px; |  | ||||||
|         display: inline-flex; |  | ||||||
|         flex-shrink: 0; |  | ||||||
|         position: relative; |  | ||||||
|         z-index: 1; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .add-node-btn-box:before { |  | ||||||
|         content: ''; |  | ||||||
|         position: absolute; |  | ||||||
|         top: 0; |  | ||||||
|         left: 0; |  | ||||||
|         right: 0; |  | ||||||
|         bottom: 0; |  | ||||||
|         z-index: -1; |  | ||||||
|         margin: auto; |  | ||||||
|         width: 2px; |  | ||||||
|         height: 100%; |  | ||||||
|         background-color: rgb(202, 202, 202); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .add-node-btn { |  | ||||||
|         user-select: none; |  | ||||||
|         width: 240px; |  | ||||||
|         padding: 20px 0 32px; |  | ||||||
|         display: flex; |  | ||||||
|         justify-content: center; |  | ||||||
|         flex-shrink: 0; |  | ||||||
|         flex-grow: 1; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .add-branch { |  | ||||||
|         justify-content: center; |  | ||||||
|         padding: 0 10px; |  | ||||||
|         position: absolute; |  | ||||||
|         top: -16px; |  | ||||||
|         left: 50%; |  | ||||||
|         transform: translateX(-50%); |  | ||||||
|         transform-origin: center center; |  | ||||||
|         z-index: 1; |  | ||||||
|         display: inline-flex; |  | ||||||
|         align-items: center; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .branch-wrap { |  | ||||||
|         display: inline-flex; |  | ||||||
|         width: 100%; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .branch-box-wrap { |  | ||||||
|         display: flex; |  | ||||||
|         flex-flow: column wrap; |  | ||||||
|         align-items: center; |  | ||||||
|         min-height: 270px; |  | ||||||
|         width: 100%; |  | ||||||
|         flex-shrink: 0; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .col-box { |  | ||||||
|         display: inline-flex; |  | ||||||
|         flex-direction: column; |  | ||||||
|         align-items: center; |  | ||||||
|         position: relative; |  | ||||||
|         background: #f6f8f9; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .branch-box { |  | ||||||
|         display: flex; |  | ||||||
|         overflow: visible; |  | ||||||
|         min-height: 180px; |  | ||||||
|         height: auto; |  | ||||||
|         border-bottom: 2px solid #ccc; |  | ||||||
|         border-top: 2px solid #ccc; |  | ||||||
|         position: relative; |  | ||||||
|         margin-top: 1rem; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .branch-box .col-box::before { |  | ||||||
|         content: ''; |  | ||||||
|         position: absolute; |  | ||||||
|         top: 0; |  | ||||||
|         left: 0; |  | ||||||
|         right: 0; |  | ||||||
|         bottom: 0; |  | ||||||
|         z-index: 0; |  | ||||||
|         margin: auto; |  | ||||||
|         width: 2px; |  | ||||||
|         height: 100%; |  | ||||||
|         background-color: rgb(202, 202, 202); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .condition-node { |  | ||||||
|         display: inline-flex; |  | ||||||
|         flex-direction: column; |  | ||||||
|         min-height: 220px; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .condition-node-box { |  | ||||||
|         padding-top: 30px; |  | ||||||
|         padding-right: 50px; |  | ||||||
|         padding-left: 50px; |  | ||||||
|         justify-content: center; |  | ||||||
|         align-items: center; |  | ||||||
|         flex-grow: 1; |  | ||||||
|         position: relative; |  | ||||||
|         display: inline-flex; |  | ||||||
|         flex-direction: column; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .condition-node-box::before { |  | ||||||
|         content: ''; |  | ||||||
|         position: absolute; |  | ||||||
|         top: 0; |  | ||||||
|         left: 0; |  | ||||||
|         right: 0; |  | ||||||
|         bottom: 0; |  | ||||||
|         margin: auto; |  | ||||||
|         width: 2px; |  | ||||||
|         height: 100%; |  | ||||||
|         background-color: rgb(202, 202, 202); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .auto-judge { |  | ||||||
|         position: relative; |  | ||||||
|         width: 220px; |  | ||||||
|         min-height: 72px; |  | ||||||
|         background: rgb(255, 255, 255); |  | ||||||
|         border-radius: 4px; |  | ||||||
|         padding: 1rem 1rem; |  | ||||||
|         cursor: pointer; |  | ||||||
|         box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.1); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .auto-judge::before { |  | ||||||
|         content: ''; |  | ||||||
|         position: absolute; |  | ||||||
|         top: -12px; |  | ||||||
|         left: 50%; |  | ||||||
|         transform: translateX(-50%); |  | ||||||
|         width: 0; |  | ||||||
|         border-style: solid; |  | ||||||
|         border-width: 8px 6px 4px; |  | ||||||
|         border-color: rgb(202, 202, 202) transparent transparent; |  | ||||||
|         background: rgb(245, 245, 247); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .auto-judge .title { |  | ||||||
|         line-height: 16px; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .auto-judge .title .node-title { |  | ||||||
|         color: #15bc83; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .auto-judge .title .close { |  | ||||||
|         font-size: 1rem; |  | ||||||
|         position: absolute; |  | ||||||
|         top: 1rem; |  | ||||||
|         right: 1rem; |  | ||||||
|         color: #999; |  | ||||||
|         display: none; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .auto-judge .title .priority-title { |  | ||||||
|         position: absolute; |  | ||||||
|         top: 1rem; |  | ||||||
|         right: 1rem; |  | ||||||
|         color: #999; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .auto-judge .content { |  | ||||||
|         position: relative; |  | ||||||
|         padding-top: 1rem; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .auto-judge .content .placeholder { |  | ||||||
|         color: #999; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .auto-judge:hover { |  | ||||||
|         .close { |  | ||||||
|             display: block; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         .priority-title { |  | ||||||
|             display: none; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .top-left-cover-line, |  | ||||||
|     .top-right-cover-line { |  | ||||||
|         position: absolute; |  | ||||||
|         height: 3px; |  | ||||||
|         width: 50%; |  | ||||||
|         background-color: #f6f8f9; |  | ||||||
|         top: -2px; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .bottom-left-cover-line, |  | ||||||
|     .bottom-right-cover-line { |  | ||||||
|         position: absolute; |  | ||||||
|         height: 3px; |  | ||||||
|         width: 50%; |  | ||||||
|         background-color: #f6f8f9; |  | ||||||
|         bottom: -2px; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .top-left-cover-line { |  | ||||||
|         left: -1px; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .top-right-cover-line { |  | ||||||
|         right: -1px; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .bottom-left-cover-line { |  | ||||||
|         left: -1px; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .bottom-right-cover-line { |  | ||||||
|         right: -1px; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .end-node { |  | ||||||
|         border-radius: 50%; |  | ||||||
|         font-size: 14px; |  | ||||||
|         color: rgba(25, 31, 37, 0.4); |  | ||||||
|         text-align: left; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .end-node-circle { |  | ||||||
|         width: 10px; |  | ||||||
|         height: 10px; |  | ||||||
|         margin: auto; |  | ||||||
|         border-radius: 50%; |  | ||||||
|         background: #dbdcdc; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .end-node-text { |  | ||||||
|         margin-top: 5px; |  | ||||||
|         text-align: center; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .auto-judge:hover { |  | ||||||
|         .sort-left { |  | ||||||
|             display: flex; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         .sort-right { |  | ||||||
|             display: flex; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .auto-judge .sort-left { |  | ||||||
|         position: absolute; |  | ||||||
|         top: 0; |  | ||||||
|         bottom: 0; |  | ||||||
|         z-index: 1; |  | ||||||
|         left: 0; |  | ||||||
|         display: none; |  | ||||||
|         justify-content: center; |  | ||||||
|         align-items: center; |  | ||||||
|         flex-direction: column; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .auto-judge .sort-right { |  | ||||||
|         position: absolute; |  | ||||||
|         top: 0; |  | ||||||
|         bottom: 0; |  | ||||||
|         z-index: 1; |  | ||||||
|         right: 0; |  | ||||||
|         display: none; |  | ||||||
|         justify-content: center; |  | ||||||
|         align-items: center; |  | ||||||
|         flex-direction: column; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .auto-judge .sort-left:hover, |  | ||||||
|     .auto-judge .sort-right:hover { |  | ||||||
|         background: #eee; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .auto-judge:after { |  | ||||||
|         pointer-events: none; |  | ||||||
|         content: ''; |  | ||||||
|         position: absolute; |  | ||||||
|         top: 0; |  | ||||||
|         bottom: 0; |  | ||||||
|         left: 0; |  | ||||||
|         right: 0; |  | ||||||
|         z-index: 2; |  | ||||||
|         border-radius: 4px; |  | ||||||
|         transition: all 0.1s; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .auto-judge:hover:after { |  | ||||||
|         border: 1px solid #3296fa; |  | ||||||
|         box-shadow: 0 0 6px 0 rgba(50, 150, 250, 0.3); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .node-wrap-box:after { |  | ||||||
|         pointer-events: none; |  | ||||||
|         content: ''; |  | ||||||
|         position: absolute; |  | ||||||
|         top: 0; |  | ||||||
|         bottom: 0; |  | ||||||
|         left: 0; |  | ||||||
|         right: 0; |  | ||||||
|         z-index: 2; |  | ||||||
|         border-radius: 4px; |  | ||||||
|         transition: all 0.1s; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .node-wrap-box:hover:after { |  | ||||||
|         border: 1px solid #3296fa; |  | ||||||
|         box-shadow: 0 0 6px 0 rgba(50, 150, 250, 0.3); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .tags-list { |  | ||||||
|     margin-top: 1rem; |  | ||||||
|     width: 100%; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .add-node-popover-body li { |  | ||||||
|     display: inline-block; |  | ||||||
|     width: 80px; |  | ||||||
|     text-align: center; |  | ||||||
|     padding: 10px 0; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .add-node-popover-body li i { |  | ||||||
|     border: 1px solid var(--el-border-color-light); |  | ||||||
|     width: 40px; |  | ||||||
|     height: 40px; |  | ||||||
|     border-radius: 50%; |  | ||||||
|     text-align: center; |  | ||||||
|     line-height: 38px; |  | ||||||
|     font-size: 18px; |  | ||||||
|     cursor: pointer; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .add-node-popover-body li i:hover { |  | ||||||
|     border: 1px solid #3296fa; |  | ||||||
|     background: #3296fa; |  | ||||||
|     color: #fff !important; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .add-node-popover-body li p { |  | ||||||
|     font-size: 12px; |  | ||||||
|     margin-top: 5px; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .node-wrap-drawer__title { |  | ||||||
|     padding-right: 40px; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .node-wrap-drawer__title label { |  | ||||||
|     cursor: pointer; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .node-wrap-drawer__title label:hover { |  | ||||||
|     border-bottom: 1px dashed #409eff; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .node-wrap-drawer__title .node-wrap-drawer__title-edit { |  | ||||||
|     color: #409eff; |  | ||||||
|     margin-left: 10px; |  | ||||||
|     vertical-align: middle; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .dark .sc-workflow-design { |  | ||||||
|     .node-wrap-box, |  | ||||||
|     .auto-judge { |  | ||||||
|         background: #2b2b2b; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .col-box { |  | ||||||
|         background: var(--el-bg-color); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .top-left-cover-line, |  | ||||||
|     .top-right-cover-line, |  | ||||||
|     .bottom-left-cover-line, |  | ||||||
|     .bottom-right-cover-line { |  | ||||||
|         background-color: var(--el-bg-color); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .node-wrap-box::before, |  | ||||||
|     .auto-judge::before { |  | ||||||
|         background-color: var(--el-bg-color); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .branch-box .add-branch { |  | ||||||
|         background: var(--el-bg-color); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .end-node .end-node-text { |  | ||||||
|         color: #d0d0d0; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     .auto-judge .sort-left:hover, |  | ||||||
|     .auto-judge .sort-right:hover { |  | ||||||
|         background: var(--el-bg-color); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
| @@ -1,56 +0,0 @@ | |||||||
| <template> |  | ||||||
|     <promoter v-if="nodeConfig.type === 0" v-model="nodeConfig"></promoter> |  | ||||||
|  |  | ||||||
|     <approver v-if="nodeConfig.type === 1" v-model="nodeConfig"></approver> |  | ||||||
|  |  | ||||||
|     <send v-if="nodeConfig.type === 2" v-model="nodeConfig"></send> |  | ||||||
|  |  | ||||||
|     <branch v-if="nodeConfig.type === 4" v-model="nodeConfig"> |  | ||||||
|         <template v-slot="slot"> |  | ||||||
|             <node-wrap v-if="slot.node" v-model="slot.node.childNode"></node-wrap> |  | ||||||
|         </template> |  | ||||||
|     </branch> |  | ||||||
|  |  | ||||||
|     <node-wrap v-if="nodeConfig.childNode" v-model="nodeConfig.childNode"></node-wrap> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
| import approver from './nodes/approver' |  | ||||||
| import promoter from './nodes/promoter' |  | ||||||
| import branch from './nodes/branch' |  | ||||||
| import send from './nodes/send' |  | ||||||
|  |  | ||||||
| export default { |  | ||||||
|     props: { |  | ||||||
|         modelValue: { |  | ||||||
|             type: Object, |  | ||||||
|             default: () => {}, |  | ||||||
|         }, |  | ||||||
|     }, |  | ||||||
|     components: { |  | ||||||
|         approver, |  | ||||||
|         promoter, |  | ||||||
|         branch, |  | ||||||
|         send, |  | ||||||
|     }, |  | ||||||
|     data() { |  | ||||||
|         return { |  | ||||||
|             nodeConfig: {}, |  | ||||||
|         } |  | ||||||
|     }, |  | ||||||
|     watch: { |  | ||||||
|         modelValue(val) { |  | ||||||
|             this.nodeConfig = val |  | ||||||
|         }, |  | ||||||
|         nodeConfig(val) { |  | ||||||
|             this.$emit('update:modelValue', val) |  | ||||||
|         }, |  | ||||||
|     }, |  | ||||||
|     mounted() { |  | ||||||
|         this.nodeConfig = this.modelValue |  | ||||||
|     }, |  | ||||||
|     methods: {}, |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style></style> |  | ||||||
| @@ -1,104 +0,0 @@ | |||||||
| <template> |  | ||||||
|     <div class="add-node-btn-box"> |  | ||||||
|         <div class="add-node-btn"> |  | ||||||
|             <el-popover :hide-after="0" :show-after="0" :width="270" placement="right-start" trigger="click"> |  | ||||||
|                 <template #reference> |  | ||||||
|                     <el-button circle icon="el-icon-plus" type="primary"></el-button> |  | ||||||
|                 </template> |  | ||||||
|                 <div class="add-node-popover-body"> |  | ||||||
|                     <ul> |  | ||||||
|                         <li> |  | ||||||
|                             <el-icon @click="addType(1)" style="color: #ff943e"> |  | ||||||
|                                 <el-icon-user-filled /> |  | ||||||
|                             </el-icon> |  | ||||||
|                             <p>审批节点</p> |  | ||||||
|                         </li> |  | ||||||
|                         <li> |  | ||||||
|                             <el-icon @click="addType(2)" style="color: #3296fa"> |  | ||||||
|                                 <el-icon-promotion /> |  | ||||||
|                             </el-icon> |  | ||||||
|                             <p>抄送节点</p> |  | ||||||
|                         </li> |  | ||||||
|                         <li> |  | ||||||
|                             <el-icon @click="addType(4)" style="color: #15bc83"> |  | ||||||
|                                 <el-icon-share /> |  | ||||||
|                             </el-icon> |  | ||||||
|                             <p>条件分支</p> |  | ||||||
|                         </li> |  | ||||||
|                     </ul> |  | ||||||
|                 </div> |  | ||||||
|             </el-popover> |  | ||||||
|         </div> |  | ||||||
|     </div> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
| export default { |  | ||||||
|     props: { |  | ||||||
|         modelValue: { |  | ||||||
|             type: Object, |  | ||||||
|             default: () => {}, |  | ||||||
|         }, |  | ||||||
|     }, |  | ||||||
|     data() { |  | ||||||
|         return {} |  | ||||||
|     }, |  | ||||||
|     mounted() {}, |  | ||||||
|     methods: { |  | ||||||
|         addType(type) { |  | ||||||
|             let node = {} |  | ||||||
|             if (type === 1) { |  | ||||||
|                 node = { |  | ||||||
|                     nodeName: '审核人', |  | ||||||
|                     type: 1, //节点类型 |  | ||||||
|                     setType: 1, //审核人类型 |  | ||||||
|                     nodeUserList: [], //审核人成员 |  | ||||||
|                     nodeRoleList: [], //审核角色 |  | ||||||
|                     examineLevel: 1, //指定主管层级 |  | ||||||
|                     directorLevel: 1, //自定义连续主管审批层级 |  | ||||||
|                     selectMode: 1, //发起人自选类型 |  | ||||||
|                     termAuto: false, //审批期限超时自动审批 |  | ||||||
|                     term: 0, //审批期限 |  | ||||||
|                     termMode: 1, //审批期限超时后执行类型 |  | ||||||
|                     examineMode: 1, //多人审批时审批方式 |  | ||||||
|                     directorMode: 0, //连续主管审批方式 |  | ||||||
|                     childNode: this.modelValue, |  | ||||||
|                 } |  | ||||||
|             } else if (type === 2) { |  | ||||||
|                 node = { |  | ||||||
|                     nodeName: '抄送人', |  | ||||||
|                     type: 2, |  | ||||||
|                     userSelectFlag: true, |  | ||||||
|                     nodeUserList: [], |  | ||||||
|                     childNode: this.modelValue, |  | ||||||
|                 } |  | ||||||
|             } else if (type === 4) { |  | ||||||
|                 node = { |  | ||||||
|                     nodeName: '条件路由', |  | ||||||
|                     type: 4, |  | ||||||
|                     conditionNodes: [ |  | ||||||
|                         { |  | ||||||
|                             nodeName: '条件1', |  | ||||||
|                             type: 3, |  | ||||||
|                             priorityLevel: 1, |  | ||||||
|                             conditionMode: 1, |  | ||||||
|                             conditionList: [], |  | ||||||
|                         }, |  | ||||||
|                         { |  | ||||||
|                             nodeName: '条件2', |  | ||||||
|                             type: 3, |  | ||||||
|                             priorityLevel: 2, |  | ||||||
|                             conditionMode: 1, |  | ||||||
|                             conditionList: [], |  | ||||||
|                         }, |  | ||||||
|                     ], |  | ||||||
|                     childNode: this.modelValue, |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|             this.$emit('update:modelValue', node) |  | ||||||
|         }, |  | ||||||
|     }, |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style></style> |  | ||||||
| @@ -1,224 +0,0 @@ | |||||||
| <template> |  | ||||||
|     <div class="node-wrap"> |  | ||||||
|         <div @click="show" class="node-wrap-box"> |  | ||||||
|             <div class="title" style="background: #ff943e"> |  | ||||||
|                 <el-icon class="icon"> |  | ||||||
|                     <el-icon-user-filled /> |  | ||||||
|                 </el-icon> |  | ||||||
|                 <span>{{ nodeConfig.nodeName }}</span> |  | ||||||
|                 <el-icon @click.stop="delNode()" class="close"> |  | ||||||
|                     <el-icon-close /> |  | ||||||
|                 </el-icon> |  | ||||||
|             </div> |  | ||||||
|             <div class="content"> |  | ||||||
|                 <span v-if="toText(nodeConfig)">{{ toText(nodeConfig) }}</span> |  | ||||||
|                 <span v-else class="placeholder">请选择</span> |  | ||||||
|             </div> |  | ||||||
|         </div> |  | ||||||
|         <add-node v-model="nodeConfig.childNode"></add-node> |  | ||||||
|         <el-drawer v-model="drawer" :size="500" :title="$t('审批人设置')" append-to-body destroy-on-close> |  | ||||||
|             <template #header> |  | ||||||
|                 <div class="node-wrap-drawer__title"> |  | ||||||
|                     <label v-if="!isEditTitle" @click="editTitle" |  | ||||||
|                         >{{ form.nodeName }} |  | ||||||
|                         <el-icon class="node-wrap-drawer__title-edit"> |  | ||||||
|                             <el-icon-edit /> |  | ||||||
|                         </el-icon> |  | ||||||
|                     </label> |  | ||||||
|                     <el-input |  | ||||||
|                         v-if="isEditTitle" |  | ||||||
|                         v-model="form.nodeName" |  | ||||||
|                         @blur="saveTitle" |  | ||||||
|                         @keyup.enter="saveTitle" |  | ||||||
|                         clearable |  | ||||||
|                         ref="nodeTitle"></el-input> |  | ||||||
|                 </div> |  | ||||||
|             </template> |  | ||||||
|             <el-container> |  | ||||||
|                 <el-main style="padding: 0 20px 20px 20px"> |  | ||||||
|                     <el-form label-position="top"> |  | ||||||
|                         <el-form-item :label="$t('审批人员类型')"> |  | ||||||
|                             <el-select v-model="form.setType"> |  | ||||||
|                                 <el-option :label="$t('指定成员')" :value="1"></el-option> |  | ||||||
|                                 <el-option :label="$t('主管')" :value="2"></el-option> |  | ||||||
|                                 <el-option :label="$t('角色')" :value="3"></el-option> |  | ||||||
|                                 <el-option :label="$t('发起人自选')" :value="4"></el-option> |  | ||||||
|                                 <el-option :label="$t('发起人自己')" :value="5"></el-option> |  | ||||||
|                                 <el-option :label="$t('连续多级主管')" :value="7"></el-option> |  | ||||||
|                             </el-select> |  | ||||||
|                         </el-form-item> |  | ||||||
|  |  | ||||||
|                         <el-form-item v-if="form.setType === 1" :label="$t('选择成员')"> |  | ||||||
|                             <el-button @click="selectHandle(1, form.nodeUserList)" icon="el-icon-plus" round type="primary">选择人员</el-button> |  | ||||||
|                             <div class="tags-list"> |  | ||||||
|                                 <el-tag v-for="(user, index) in form.nodeUserList" :key="user.id" @close="delUser(index)" closable |  | ||||||
|                                     >{{ user.name }} |  | ||||||
|                                 </el-tag> |  | ||||||
|                             </div> |  | ||||||
|                         </el-form-item> |  | ||||||
|  |  | ||||||
|                         <el-form-item v-if="form.setType === 2" :label="$t('指定主管')"> |  | ||||||
|                             发起人的第 |  | ||||||
|                             <el-input-number v-model="form.examineLevel" :min="1" /> |  | ||||||
|                             级主管 |  | ||||||
|                         </el-form-item> |  | ||||||
|  |  | ||||||
|                         <el-form-item v-if="form.setType === 3" :label="$t('选择角色')"> |  | ||||||
|                             <el-button @click="selectHandle(2, form.nodeRoleList)" icon="el-icon-plus" round type="primary">选择角色</el-button> |  | ||||||
|                             <div class="tags-list"> |  | ||||||
|                                 <el-tag v-for="(role, index) in form.nodeRoleList" :key="role.id" @close="delRole(index)" closable type="info" |  | ||||||
|                                     >{{ role.name }} |  | ||||||
|                                 </el-tag> |  | ||||||
|                             </div> |  | ||||||
|                         </el-form-item> |  | ||||||
|  |  | ||||||
|                         <el-form-item v-if="form.setType === 4" :label="$t('发起人自选')"> |  | ||||||
|                             <el-radio-group v-model="form.selectMode"> |  | ||||||
|                                 <el-radio :label="1">自选一个人</el-radio> |  | ||||||
|                                 <el-radio :label="2">自选多个人</el-radio> |  | ||||||
|                             </el-radio-group> |  | ||||||
|                         </el-form-item> |  | ||||||
|  |  | ||||||
|                         <el-form-item v-if="form.setType === 7" :label="$t('连续主管审批终点')"> |  | ||||||
|                             <el-radio-group v-model="form.directorMode"> |  | ||||||
|                                 <el-radio :label="0">直到最上层主管</el-radio> |  | ||||||
|                                 <el-radio :label="1">自定义审批终点</el-radio> |  | ||||||
|                             </el-radio-group> |  | ||||||
|                             <p v-if="form.directorMode === 1"> |  | ||||||
|                                 直到发起人的第 |  | ||||||
|                                 <el-input-number v-model="form.directorLevel" :min="1" /> |  | ||||||
|                                 级主管 |  | ||||||
|                             </p> |  | ||||||
|                         </el-form-item> |  | ||||||
|  |  | ||||||
|                         <el-divider></el-divider> |  | ||||||
|                         <el-form-item label=""> |  | ||||||
|                             <el-checkbox v-model="form.termAuto" :label="$t('超时自动审批')"></el-checkbox> |  | ||||||
|                         </el-form-item> |  | ||||||
|                         <template v-if="form.termAuto"> |  | ||||||
|                             <el-form-item :label="$t('审批期限(为 0 则不生效)')"> |  | ||||||
|                                 <el-input-number v-model="form.term" :min="0" /> |  | ||||||
|                                 小时 |  | ||||||
|                             </el-form-item> |  | ||||||
|                             <el-form-item :label="$t('审批期限超时后执行')"> |  | ||||||
|                                 <el-radio-group v-model="form.termMode"> |  | ||||||
|                                     <el-radio :label="0">自动通过</el-radio> |  | ||||||
|                                     <el-radio :label="1">自动拒绝</el-radio> |  | ||||||
|                                 </el-radio-group> |  | ||||||
|                             </el-form-item> |  | ||||||
|                         </template> |  | ||||||
|                         <el-divider></el-divider> |  | ||||||
|                         <el-form-item :label="$t('多人审批时审批方式')"> |  | ||||||
|                             <el-radio-group v-model="form.examineMode"> |  | ||||||
|                                 <p style="width: 100%"> |  | ||||||
|                                     <el-radio :label="1">按顺序依次审批</el-radio> |  | ||||||
|                                 </p> |  | ||||||
|                                 <p style="width: 100%"> |  | ||||||
|                                     <el-radio :label="2">会签 (可同时审批,每个人必须审批通过)</el-radio> |  | ||||||
|                                 </p> |  | ||||||
|                                 <p style="width: 100%"> |  | ||||||
|                                     <el-radio :label="3">或签 (有一人审批通过即可)</el-radio> |  | ||||||
|                                 </p> |  | ||||||
|                             </el-radio-group> |  | ||||||
|                         </el-form-item> |  | ||||||
|                     </el-form> |  | ||||||
|                 </el-main> |  | ||||||
|                 <el-footer> |  | ||||||
|                     <el-button @click="save" type="primary">保存</el-button> |  | ||||||
|                     <el-button @click="drawer = false">取消</el-button> |  | ||||||
|                 </el-footer> |  | ||||||
|             </el-container> |  | ||||||
|         </el-drawer> |  | ||||||
|     </div> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
| import addNode from './addNode' |  | ||||||
|  |  | ||||||
| export default { |  | ||||||
|     inject: ['select'], |  | ||||||
|     props: { |  | ||||||
|         modelValue: { |  | ||||||
|             type: Object, |  | ||||||
|             default: () => {}, |  | ||||||
|         }, |  | ||||||
|     }, |  | ||||||
|     components: { |  | ||||||
|         addNode, |  | ||||||
|     }, |  | ||||||
|     data() { |  | ||||||
|         return { |  | ||||||
|             nodeConfig: {}, |  | ||||||
|             drawer: false, |  | ||||||
|             isEditTitle: false, |  | ||||||
|             form: {}, |  | ||||||
|         } |  | ||||||
|     }, |  | ||||||
|     watch: { |  | ||||||
|         modelValue() { |  | ||||||
|             this.nodeConfig = this.modelValue |  | ||||||
|         }, |  | ||||||
|     }, |  | ||||||
|     mounted() { |  | ||||||
|         this.nodeConfig = this.modelValue |  | ||||||
|     }, |  | ||||||
|     methods: { |  | ||||||
|         show() { |  | ||||||
|             this.form = {} |  | ||||||
|             this.form = JSON.parse(JSON.stringify(this.nodeConfig)) |  | ||||||
|             this.drawer = true |  | ||||||
|         }, |  | ||||||
|         editTitle() { |  | ||||||
|             this.isEditTitle = true |  | ||||||
|             this.$nextTick(() => { |  | ||||||
|                 this.$refs.nodeTitle.focus() |  | ||||||
|             }) |  | ||||||
|         }, |  | ||||||
|         saveTitle() { |  | ||||||
|             this.isEditTitle = false |  | ||||||
|         }, |  | ||||||
|         save() { |  | ||||||
|             this.$emit('update:modelValue', this.form) |  | ||||||
|             this.drawer = false |  | ||||||
|         }, |  | ||||||
|         delNode() { |  | ||||||
|             this.$emit('update:modelValue', this.nodeConfig.childNode) |  | ||||||
|         }, |  | ||||||
|         delUser(index) { |  | ||||||
|             this.form.nodeUserList.splice(index, 1) |  | ||||||
|         }, |  | ||||||
|         delRole(index) { |  | ||||||
|             this.form.nodeRoleList.splice(index, 1) |  | ||||||
|         }, |  | ||||||
|         selectHandle(type, data) { |  | ||||||
|             this.select(type, data) |  | ||||||
|         }, |  | ||||||
|         toText(nodeConfig) { |  | ||||||
|             if (nodeConfig.setType === 1) { |  | ||||||
|                 if (nodeConfig.nodeUserList && nodeConfig.nodeUserList.length > 0) { |  | ||||||
|                     return nodeConfig.nodeUserList.map((item) => item.name).join('、') |  | ||||||
|                 } else { |  | ||||||
|                     return false |  | ||||||
|                 } |  | ||||||
|             } else if (nodeConfig.setType === 2) { |  | ||||||
|                 return nodeConfig.examineLevel === 1 ? '直接主管' : `发起人的第${nodeConfig.examineLevel}级主管` |  | ||||||
|             } else if (nodeConfig.setType === 3) { |  | ||||||
|                 if (nodeConfig.nodeRoleList && nodeConfig.nodeRoleList.length > 0) { |  | ||||||
|                     const roles = nodeConfig.nodeRoleList.map((item) => item.name).join('、') |  | ||||||
|                     return '角色-' + roles |  | ||||||
|                 } else { |  | ||||||
|                     return false |  | ||||||
|                 } |  | ||||||
|             } else if (nodeConfig.setType === 4) { |  | ||||||
|                 return '发起人自选' |  | ||||||
|             } else if (nodeConfig.setType === 5) { |  | ||||||
|                 return '发起人自己' |  | ||||||
|             } else if (nodeConfig.setType === 7) { |  | ||||||
|                 return '连续多级主管' |  | ||||||
|             } |  | ||||||
|         }, |  | ||||||
|     }, |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style></style> |  | ||||||
| @@ -1,242 +0,0 @@ | |||||||
| <template> |  | ||||||
|     <div class="branch-wrap"> |  | ||||||
|         <div class="branch-box-wrap"> |  | ||||||
|             <div class="branch-box"> |  | ||||||
|                 <el-button @click="addTerm" class="add-branch" plain round type="success">添加条件</el-button> |  | ||||||
|                 <div v-for="(item, index) in nodeConfig.conditionNodes" :key="index" class="col-box"> |  | ||||||
|                     <div class="condition-node"> |  | ||||||
|                         <div class="condition-node-box"> |  | ||||||
|                             <div @click="show(index)" class="auto-judge"> |  | ||||||
|                                 <div v-if="index !== 0" @click.stop="arrTransfer(index, -1)" class="sort-left"> |  | ||||||
|                                     <el-icon> |  | ||||||
|                                         <el-icon-arrow-left /> |  | ||||||
|                                     </el-icon> |  | ||||||
|                                 </div> |  | ||||||
|                                 <div class="title"> |  | ||||||
|                                     <span class="node-title">{{ item.nodeName }}</span> |  | ||||||
|                                     <span class="priority-title">优先级{{ item.priorityLevel }}</span> |  | ||||||
|                                     <el-icon @click.stop="delTerm(index)" class="close"> |  | ||||||
|                                         <el-icon-close /> |  | ||||||
|                                     </el-icon> |  | ||||||
|                                 </div> |  | ||||||
|                                 <div class="content"> |  | ||||||
|                                     <span v-if="toText(nodeConfig, index)">{{ toText(nodeConfig, index) }}</span> |  | ||||||
|                                     <span v-else class="placeholder">请设置条件</span> |  | ||||||
|                                 </div> |  | ||||||
|                                 <div v-if="index !== nodeConfig.conditionNodes.length - 1" @click.stop="arrTransfer(index)" class="sort-right"> |  | ||||||
|                                     <el-icon> |  | ||||||
|                                         <el-icon-arrow-right /> |  | ||||||
|                                     </el-icon> |  | ||||||
|                                 </div> |  | ||||||
|                             </div> |  | ||||||
|                             <add-node v-model="item.childNode"></add-node> |  | ||||||
|                         </div> |  | ||||||
|                     </div> |  | ||||||
|                     <slot v-if="item.childNode" :node="item"></slot> |  | ||||||
|                     <div v-if="index === 0" class="top-left-cover-line"></div> |  | ||||||
|                     <div v-if="index === 0" class="bottom-left-cover-line"></div> |  | ||||||
|                     <div v-if="index === nodeConfig.conditionNodes.length - 1" class="top-right-cover-line"></div> |  | ||||||
|                     <div v-if="index === nodeConfig.conditionNodes.length - 1" class="bottom-right-cover-line"></div> |  | ||||||
|                 </div> |  | ||||||
|             </div> |  | ||||||
|             <add-node v-model="nodeConfig.childNode"></add-node> |  | ||||||
|         </div> |  | ||||||
|         <el-drawer v-model="drawer" :size="600" :title="$t('条件设置')" append-to-body destroy-on-close> |  | ||||||
|             <template #header> |  | ||||||
|                 <div class="node-wrap-drawer__title"> |  | ||||||
|                     <label v-if="!isEditTitle" @click="editTitle" |  | ||||||
|                         >{{ form.nodeName }} |  | ||||||
|                         <el-icon class="node-wrap-drawer__title-edit"> |  | ||||||
|                             <el-icon-edit /> |  | ||||||
|                         </el-icon> |  | ||||||
|                     </label> |  | ||||||
|                     <el-input |  | ||||||
|                         v-if="isEditTitle" |  | ||||||
|                         v-model="form.nodeName" |  | ||||||
|                         @blur="saveTitle" |  | ||||||
|                         @keyup.enter="saveTitle" |  | ||||||
|                         clearable |  | ||||||
|                         ref="nodeTitle"></el-input> |  | ||||||
|                 </div> |  | ||||||
|             </template> |  | ||||||
|             <el-container> |  | ||||||
|                 <el-main style="padding: 0 20px 20px 20px"> |  | ||||||
|                     <el-form label-position="top"> |  | ||||||
|                         <el-form-item :label="$t('条件关系')"> |  | ||||||
|                             <el-radio-group v-model="form.conditionMode"> |  | ||||||
|                                 <el-radio :label="1">且</el-radio> |  | ||||||
|                                 <el-radio :label="2">或</el-radio> |  | ||||||
|                             </el-radio-group> |  | ||||||
|                         </el-form-item> |  | ||||||
|                         <el-divider></el-divider> |  | ||||||
|                         <el-form-item> |  | ||||||
|                             <el-table :data="form.conditionList"> |  | ||||||
|                                 <el-table-column :label="$t('描述')" prop="label"> |  | ||||||
|                                     <template #default="scope"> |  | ||||||
|                                         <el-input v-model="scope.row.label" :placeholder="$t('描述')"></el-input> |  | ||||||
|                                     </template> |  | ||||||
|                                 </el-table-column> |  | ||||||
|                                 <el-table-column :label="$t('条件字段')" prop="field" width="130"> |  | ||||||
|                                     <template #default="scope"> |  | ||||||
|                                         <el-input v-model="scope.row.field" :placeholder="$t('条件字段')"></el-input> |  | ||||||
|                                     </template> |  | ||||||
|                                 </el-table-column> |  | ||||||
|                                 <el-table-column :label="$t('运算符')" prop="operator" width="130"> |  | ||||||
|                                     <template #default="scope"> |  | ||||||
|                                         <el-select v-model="scope.row.operator" placeholder="Select"> |  | ||||||
|                                             <el-option :label="$t('等于')" value="="></el-option> |  | ||||||
|                                             <el-option :label="$t('不等于')" value="!="></el-option> |  | ||||||
|                                             <el-option :label="$t('大于')" value=">"></el-option> |  | ||||||
|                                             <el-option :label="$t('大于等于')" value=">="></el-option> |  | ||||||
|                                             <el-option :label="$t('小于')" value="<"></el-option> |  | ||||||
|                                             <el-option :label="$t('小于等于')" value="<="></el-option> |  | ||||||
|                                             <el-option :label="$t('包含')" value="include"></el-option> |  | ||||||
|                                             <el-option :label="$t('不包含')" value="notinclude"></el-option> |  | ||||||
|                                         </el-select> |  | ||||||
|                                     </template> |  | ||||||
|                                 </el-table-column> |  | ||||||
|                                 <el-table-column :label="$t('值')" prop="value" width="100"> |  | ||||||
|                                     <template #default="scope"> |  | ||||||
|                                         <el-input v-model="scope.row.value" :placeholder="$t('值')"></el-input> |  | ||||||
|                                     </template> |  | ||||||
|                                 </el-table-column> |  | ||||||
|                                 <el-table-column :label="$t('移除')" prop="value" width="55"> |  | ||||||
|                                     <template #default="scope"> |  | ||||||
|                                         <el-link :underline="false" @click="deleteConditionList(scope.$index)" type="danger">移除</el-link> |  | ||||||
|                                     </template> |  | ||||||
|                                 </el-table-column> |  | ||||||
|                             </el-table> |  | ||||||
|                         </el-form-item> |  | ||||||
|                         <p> |  | ||||||
|                             <el-button @click="addConditionList" icon="el-icon-plus" round type="primary">增加条件</el-button> |  | ||||||
|                         </p> |  | ||||||
|                     </el-form> |  | ||||||
|                 </el-main> |  | ||||||
|                 <el-footer> |  | ||||||
|                     <el-button @click="save" type="primary">保存</el-button> |  | ||||||
|                     <el-button @click="drawer = false">取消</el-button> |  | ||||||
|                 </el-footer> |  | ||||||
|             </el-container> |  | ||||||
|         </el-drawer> |  | ||||||
|     </div> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
| import addNode from './addNode' |  | ||||||
|  |  | ||||||
| export default { |  | ||||||
|     props: { |  | ||||||
|         modelValue: { |  | ||||||
|             type: Object, |  | ||||||
|             default: () => {}, |  | ||||||
|         }, |  | ||||||
|     }, |  | ||||||
|     components: { |  | ||||||
|         addNode, |  | ||||||
|     }, |  | ||||||
|     data() { |  | ||||||
|         return { |  | ||||||
|             nodeConfig: {}, |  | ||||||
|             drawer: false, |  | ||||||
|             isEditTitle: false, |  | ||||||
|             index: 0, |  | ||||||
|             form: {}, |  | ||||||
|         } |  | ||||||
|     }, |  | ||||||
|     watch: { |  | ||||||
|         modelValue() { |  | ||||||
|             this.nodeConfig = this.modelValue |  | ||||||
|         }, |  | ||||||
|     }, |  | ||||||
|     mounted() { |  | ||||||
|         this.nodeConfig = this.modelValue |  | ||||||
|     }, |  | ||||||
|     methods: { |  | ||||||
|         show(index) { |  | ||||||
|             this.index = index |  | ||||||
|             this.form = {} |  | ||||||
|             this.form = JSON.parse(JSON.stringify(this.nodeConfig.conditionNodes[index])) |  | ||||||
|             this.drawer = true |  | ||||||
|         }, |  | ||||||
|         editTitle() { |  | ||||||
|             this.isEditTitle = true |  | ||||||
|             this.$nextTick(() => { |  | ||||||
|                 this.$refs.nodeTitle.focus() |  | ||||||
|             }) |  | ||||||
|         }, |  | ||||||
|         saveTitle() { |  | ||||||
|             this.isEditTitle = false |  | ||||||
|         }, |  | ||||||
|         save() { |  | ||||||
|             this.nodeConfig.conditionNodes[this.index] = this.form |  | ||||||
|             this.$emit('update:modelValue', this.nodeConfig) |  | ||||||
|             this.drawer = false |  | ||||||
|         }, |  | ||||||
|         addTerm() { |  | ||||||
|             let len = this.nodeConfig.conditionNodes.length + 1 |  | ||||||
|             this.nodeConfig.conditionNodes.push({ |  | ||||||
|                 nodeName: '条件' + len, |  | ||||||
|                 type: 3, |  | ||||||
|                 priorityLevel: len, |  | ||||||
|                 conditionMode: 1, |  | ||||||
|                 conditionList: [], |  | ||||||
|             }) |  | ||||||
|         }, |  | ||||||
|         delTerm(index) { |  | ||||||
|             this.nodeConfig.conditionNodes.splice(index, 1) |  | ||||||
|             if (this.nodeConfig.conditionNodes.length === 1) { |  | ||||||
|                 if (this.nodeConfig.childNode) { |  | ||||||
|                     if (this.nodeConfig.conditionNodes[0].childNode) { |  | ||||||
|                         this.reData(this.nodeConfig.conditionNodes[0].childNode, this.nodeConfig.childNode) |  | ||||||
|                     } else { |  | ||||||
|                         this.nodeConfig.conditionNodes[0].childNode = this.nodeConfig.childNode |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|                 this.$emit('update:modelValue', this.nodeConfig.conditionNodes[0].childNode) |  | ||||||
|             } |  | ||||||
|         }, |  | ||||||
|         reData(data, addData) { |  | ||||||
|             if (!data.childNode) { |  | ||||||
|                 data.childNode = addData |  | ||||||
|             } else { |  | ||||||
|                 this.reData(data.childNode, addData) |  | ||||||
|             } |  | ||||||
|         }, |  | ||||||
|         arrTransfer(index, type = 1) { |  | ||||||
|             this.nodeConfig.conditionNodes[index] = this.nodeConfig.conditionNodes.splice(index + type, 1, this.nodeConfig.conditionNodes[index])[0] |  | ||||||
|             this.nodeConfig.conditionNodes.map((item, index) => { |  | ||||||
|                 item.priorityLevel = index + 1 |  | ||||||
|             }) |  | ||||||
|             this.$emit('update:modelValue', this.nodeConfig) |  | ||||||
|         }, |  | ||||||
|         addConditionList() { |  | ||||||
|             this.form.conditionList.push({ |  | ||||||
|                 label: '', |  | ||||||
|                 field: '', |  | ||||||
|                 operator: '=', |  | ||||||
|                 value: '', |  | ||||||
|             }) |  | ||||||
|         }, |  | ||||||
|         deleteConditionList(index) { |  | ||||||
|             this.form.conditionList.splice(index, 1) |  | ||||||
|         }, |  | ||||||
|         toText(nodeConfig, index) { |  | ||||||
|             const { conditionList } = nodeConfig.conditionNodes[index] |  | ||||||
|             if (conditionList && conditionList.length === 1) { |  | ||||||
|                 return conditionList.map((item) => `${item.label}${item.operator}${item.value}`).join(' 和 ') |  | ||||||
|             } else if (conditionList && conditionList.length > 1) { |  | ||||||
|                 const conditionModeText = nodeConfig.conditionNodes[index].conditionMode === 1 ? '且行' : '或行' |  | ||||||
|                 return conditionList.length + '个条件,' + conditionModeText |  | ||||||
|             } else { |  | ||||||
|                 if (index === nodeConfig.conditionNodes.length - 1) { |  | ||||||
|                     return '其他条件进入此流程' |  | ||||||
|                 } else { |  | ||||||
|                     return false |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         }, |  | ||||||
|     }, |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style></style> |  | ||||||
| @@ -1,127 +0,0 @@ | |||||||
| <template> |  | ||||||
|     <div class="node-wrap"> |  | ||||||
|         <div @click="show" class="node-wrap-box start-node"> |  | ||||||
|             <div class="title" style="background: #576a95"> |  | ||||||
|                 <el-icon class="icon"> |  | ||||||
|                     <el-icon-user-filled /> |  | ||||||
|                 </el-icon> |  | ||||||
|                 <span>{{ nodeConfig.nodeName }}</span> |  | ||||||
|             </div> |  | ||||||
|             <div class="content"> |  | ||||||
|                 <span>{{ toText(nodeConfig) }}</span> |  | ||||||
|             </div> |  | ||||||
|         </div> |  | ||||||
|         <add-node v-model="nodeConfig.childNode"></add-node> |  | ||||||
|         <el-drawer v-model="drawer" :size="500" :title="$t('发起人')" append-to-body destroy-on-close> |  | ||||||
|             <template #header> |  | ||||||
|                 <div class="node-wrap-drawer__title"> |  | ||||||
|                     <label v-if="!isEditTitle" @click="editTitle" |  | ||||||
|                         >{{ form.nodeName }} |  | ||||||
|                         <el-icon class="node-wrap-drawer__title-edit"> |  | ||||||
|                             <el-icon-edit /> |  | ||||||
|                         </el-icon> |  | ||||||
|                     </label> |  | ||||||
|                     <el-input |  | ||||||
|                         v-if="isEditTitle" |  | ||||||
|                         v-model="form.nodeName" |  | ||||||
|                         @blur="saveTitle" |  | ||||||
|                         @keyup.enter="saveTitle" |  | ||||||
|                         clearable |  | ||||||
|                         ref="nodeTitle"></el-input> |  | ||||||
|                 </div> |  | ||||||
|             </template> |  | ||||||
|             <el-container> |  | ||||||
|                 <el-main style="padding: 0 20px 20px 20px"> |  | ||||||
|                     <el-form label-position="top"> |  | ||||||
|                         <el-form-item :label="$t('谁可以发起此审批')"> |  | ||||||
|                             <el-button @click="selectHandle(2, form.nodeRoleList)" icon="el-icon-plus" round type="primary">选择角色</el-button> |  | ||||||
|                             <div class="tags-list"> |  | ||||||
|                                 <el-tag v-for="(role, index) in form.nodeRoleList" :key="role.id" @close="delRole(index)" closable type="info" |  | ||||||
|                                     >{{ role.name }} |  | ||||||
|                                 </el-tag> |  | ||||||
|                             </div> |  | ||||||
|                         </el-form-item> |  | ||||||
|                         <el-alert |  | ||||||
|                             v-if="form.nodeRoleList.length === 0" |  | ||||||
|                             :closable="false" |  | ||||||
|                             :title="$t('不指定则默认所有人都可发起此审批')" |  | ||||||
|                             type="info" /> |  | ||||||
|                     </el-form> |  | ||||||
|                 </el-main> |  | ||||||
|                 <el-footer> |  | ||||||
|                     <el-button @click="save" type="primary">保存</el-button> |  | ||||||
|                     <el-button @click="drawer = false">取消</el-button> |  | ||||||
|                 </el-footer> |  | ||||||
|             </el-container> |  | ||||||
|         </el-drawer> |  | ||||||
|     </div> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
| import addNode from './addNode' |  | ||||||
|  |  | ||||||
| export default { |  | ||||||
|     inject: ['select'], |  | ||||||
|     props: { |  | ||||||
|         modelValue: { |  | ||||||
|             type: Object, |  | ||||||
|             default: () => {}, |  | ||||||
|         }, |  | ||||||
|     }, |  | ||||||
|     components: { |  | ||||||
|         addNode, |  | ||||||
|     }, |  | ||||||
|     data() { |  | ||||||
|         return { |  | ||||||
|             nodeConfig: {}, |  | ||||||
|             drawer: false, |  | ||||||
|             isEditTitle: false, |  | ||||||
|             form: {}, |  | ||||||
|         } |  | ||||||
|     }, |  | ||||||
|     watch: { |  | ||||||
|         modelValue() { |  | ||||||
|             this.nodeConfig = this.modelValue |  | ||||||
|         }, |  | ||||||
|     }, |  | ||||||
|     mounted() { |  | ||||||
|         this.nodeConfig = this.modelValue |  | ||||||
|     }, |  | ||||||
|     methods: { |  | ||||||
|         show() { |  | ||||||
|             this.form = {} |  | ||||||
|             this.form = JSON.parse(JSON.stringify(this.nodeConfig)) |  | ||||||
|             this.isEditTitle = false |  | ||||||
|             this.drawer = true |  | ||||||
|         }, |  | ||||||
|         editTitle() { |  | ||||||
|             this.isEditTitle = true |  | ||||||
|             this.$nextTick(() => { |  | ||||||
|                 this.$refs.nodeTitle.focus() |  | ||||||
|             }) |  | ||||||
|         }, |  | ||||||
|         saveTitle() { |  | ||||||
|             this.isEditTitle = false |  | ||||||
|         }, |  | ||||||
|         selectHandle(type, data) { |  | ||||||
|             this.select(type, data) |  | ||||||
|         }, |  | ||||||
|         delRole(index) { |  | ||||||
|             this.form.nodeRoleList.splice(index, 1) |  | ||||||
|         }, |  | ||||||
|         save() { |  | ||||||
|             this.$emit('update:modelValue', this.form) |  | ||||||
|             this.drawer = false |  | ||||||
|         }, |  | ||||||
|         toText(nodeConfig) { |  | ||||||
|             if (nodeConfig.nodeRoleList && nodeConfig.nodeRoleList.length > 0) { |  | ||||||
|                 return nodeConfig.nodeRoleList.map((item) => item.name).join('、') |  | ||||||
|             } else { |  | ||||||
|                 return '所有人' |  | ||||||
|             } |  | ||||||
|         }, |  | ||||||
|     }, |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style></style> |  | ||||||
| @@ -1,135 +0,0 @@ | |||||||
| <template> |  | ||||||
|     <div class="node-wrap"> |  | ||||||
|         <div @click="show" class="node-wrap-box"> |  | ||||||
|             <div class="title" style="background: #3296fa"> |  | ||||||
|                 <el-icon class="icon"> |  | ||||||
|                     <el-icon-promotion /> |  | ||||||
|                 </el-icon> |  | ||||||
|                 <span>{{ nodeConfig.nodeName }}</span> |  | ||||||
|                 <el-icon @click.stop="delNode()" class="close"> |  | ||||||
|                     <el-icon-close /> |  | ||||||
|                 </el-icon> |  | ||||||
|             </div> |  | ||||||
|             <div class="content"> |  | ||||||
|                 <span v-if="toText(nodeConfig)">{{ toText(nodeConfig) }}</span> |  | ||||||
|                 <span v-else class="placeholder">请选择人员</span> |  | ||||||
|             </div> |  | ||||||
|         </div> |  | ||||||
|         <add-node v-model="nodeConfig.childNode"></add-node> |  | ||||||
|         <el-drawer v-model="drawer" :size="500" :title="$t('抄送人设置')" append-to-body destroy-on-close> |  | ||||||
|             <template #header> |  | ||||||
|                 <div class="node-wrap-drawer__title"> |  | ||||||
|                     <label v-if="!isEditTitle" @click="editTitle" |  | ||||||
|                         >{{ form.nodeName }} |  | ||||||
|                         <el-icon class="node-wrap-drawer__title-edit"> |  | ||||||
|                             <el-icon-edit /> |  | ||||||
|                         </el-icon> |  | ||||||
|                     </label> |  | ||||||
|                     <el-input |  | ||||||
|                         v-if="isEditTitle" |  | ||||||
|                         v-model="form.nodeName" |  | ||||||
|                         @blur="saveTitle" |  | ||||||
|                         @keyup.enter="saveTitle" |  | ||||||
|                         clearable |  | ||||||
|                         ref="nodeTitle"></el-input> |  | ||||||
|                 </div> |  | ||||||
|             </template> |  | ||||||
|             <el-container> |  | ||||||
|                 <el-main style="padding: 0 20px 20px 20px"> |  | ||||||
|                     <el-form label-position="top"> |  | ||||||
|                         <el-form-item :label="$t('选择要抄送的人员')"> |  | ||||||
|                             <el-button @click="selectHandle(1, form.nodeUserList)" icon="el-icon-plus" round type="primary">选择人员</el-button> |  | ||||||
|                             <div class="tags-list"> |  | ||||||
|                                 <el-tag v-for="(user, index) in form.nodeUserList" :key="user.id" @close="delUser(index)" closable |  | ||||||
|                                     >{{ user.name }} |  | ||||||
|                                 </el-tag> |  | ||||||
|                             </div> |  | ||||||
|                         </el-form-item> |  | ||||||
|                         <el-form-item label=""> |  | ||||||
|                             <el-checkbox v-model="form.userSelectFlag" :label="$t('允许发起人自选抄送人')"></el-checkbox> |  | ||||||
|                         </el-form-item> |  | ||||||
|                     </el-form> |  | ||||||
|                 </el-main> |  | ||||||
|                 <el-footer> |  | ||||||
|                     <el-button @click="save" type="primary">保存</el-button> |  | ||||||
|                     <el-button @click="drawer = false">取消</el-button> |  | ||||||
|                 </el-footer> |  | ||||||
|             </el-container> |  | ||||||
|         </el-drawer> |  | ||||||
|     </div> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
| import addNode from './addNode' |  | ||||||
|  |  | ||||||
| export default { |  | ||||||
|     inject: ['select'], |  | ||||||
|     props: { |  | ||||||
|         modelValue: { |  | ||||||
|             type: Object, |  | ||||||
|             default: () => {}, |  | ||||||
|         }, |  | ||||||
|     }, |  | ||||||
|     components: { |  | ||||||
|         addNode, |  | ||||||
|     }, |  | ||||||
|     data() { |  | ||||||
|         return { |  | ||||||
|             nodeConfig: {}, |  | ||||||
|             drawer: false, |  | ||||||
|             isEditTitle: false, |  | ||||||
|             form: {}, |  | ||||||
|         } |  | ||||||
|     }, |  | ||||||
|     watch: { |  | ||||||
|         modelValue() { |  | ||||||
|             this.nodeConfig = this.modelValue |  | ||||||
|         }, |  | ||||||
|     }, |  | ||||||
|     mounted() { |  | ||||||
|         this.nodeConfig = this.modelValue |  | ||||||
|     }, |  | ||||||
|     methods: { |  | ||||||
|         show() { |  | ||||||
|             this.form = {} |  | ||||||
|             this.form = JSON.parse(JSON.stringify(this.nodeConfig)) |  | ||||||
|             this.drawer = true |  | ||||||
|         }, |  | ||||||
|         editTitle() { |  | ||||||
|             this.isEditTitle = true |  | ||||||
|             this.$nextTick(() => { |  | ||||||
|                 this.$refs.nodeTitle.focus() |  | ||||||
|             }) |  | ||||||
|         }, |  | ||||||
|         saveTitle() { |  | ||||||
|             this.isEditTitle = false |  | ||||||
|         }, |  | ||||||
|         save() { |  | ||||||
|             this.$emit('update:modelValue', this.form) |  | ||||||
|             this.drawer = false |  | ||||||
|         }, |  | ||||||
|         delNode() { |  | ||||||
|             this.$emit('update:modelValue', this.nodeConfig.childNode) |  | ||||||
|         }, |  | ||||||
|         delUser(index) { |  | ||||||
|             this.form.nodeUserList.splice(index, 1) |  | ||||||
|         }, |  | ||||||
|         selectHandle(type, data) { |  | ||||||
|             this.select(type, data) |  | ||||||
|         }, |  | ||||||
|         toText(nodeConfig) { |  | ||||||
|             if (nodeConfig.nodeUserList && nodeConfig.nodeUserList.length > 0) { |  | ||||||
|                 return nodeConfig.nodeUserList.map((item) => item.name).join('、') |  | ||||||
|             } else { |  | ||||||
|                 if (nodeConfig.userSelectFlag) { |  | ||||||
|                     return '发起人自选' |  | ||||||
|                 } else { |  | ||||||
|                     return false |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         }, |  | ||||||
|     }, |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style></style> |  | ||||||
| @@ -1,414 +0,0 @@ | |||||||
| <template> |  | ||||||
|     <el-dialog |  | ||||||
|         v-model="dialogVisible" |  | ||||||
|         :title="titleMap[type - 1]" |  | ||||||
|         :width="type === 1 ? 680 : 460" |  | ||||||
|         @closed="$emit('closed')" |  | ||||||
|         append-to-body |  | ||||||
|         destroy-on-close> |  | ||||||
|         <template v-if="type === 1"> |  | ||||||
|             <div class="sc-user-select"> |  | ||||||
|                 <div class="sc-user-select__left"> |  | ||||||
|                     <div class="sc-user-select__search"> |  | ||||||
|                         <el-input v-model="keyword" :placeholder="$t('搜索成员')" prefix-icon="el-icon-search"> |  | ||||||
|                             <template #append> |  | ||||||
|                                 <el-button @click="search" icon="el-icon-search"></el-button> |  | ||||||
|                             </template> |  | ||||||
|                         </el-input> |  | ||||||
|                     </div> |  | ||||||
|                     <div class="sc-user-select__select"> |  | ||||||
|                         <div v-loading="showGrouploading" class="sc-user-select__tree"> |  | ||||||
|                             <el-scrollbar> |  | ||||||
|                                 <el-tree |  | ||||||
|                                     :current-node-key="groupId" |  | ||||||
|                                     :data="group" |  | ||||||
|                                     :expand-on-click-node="false" |  | ||||||
|                                     :node-key="groupProps.key" |  | ||||||
|                                     :props="groupProps" |  | ||||||
|                                     @node-click="groupClick" |  | ||||||
|                                     class="menu" |  | ||||||
|                                     highlight-current |  | ||||||
|                                     ref="groupTree" /> |  | ||||||
|                             </el-scrollbar> |  | ||||||
|                         </div> |  | ||||||
|                         <div v-loading="showUserloading" class="sc-user-select__user"> |  | ||||||
|                             <div class="sc-user-select__user__list"> |  | ||||||
|                                 <el-scrollbar ref="userScrollbar"> |  | ||||||
|                                     <el-tree |  | ||||||
|                                         :data="user" |  | ||||||
|                                         :default-checked-keys="selectedIds" |  | ||||||
|                                         :node-key="userProps.key" |  | ||||||
|                                         :props="userProps" |  | ||||||
|                                         @check-change="userClick" |  | ||||||
|                                         check-on-click-node |  | ||||||
|                                         class="menu" |  | ||||||
|                                         ref="userTree" |  | ||||||
|                                         show-checkbox></el-tree> |  | ||||||
|                                 </el-scrollbar> |  | ||||||
|                             </div> |  | ||||||
|                             <footer> |  | ||||||
|                                 <el-pagination |  | ||||||
|                                     v-model:currentPage="currentPage" |  | ||||||
|                                     :page-size="pageSize" |  | ||||||
|                                     :total="total" |  | ||||||
|                                     @current-change="paginationChange" |  | ||||||
|                                     background |  | ||||||
|                                     layout="prev,next" |  | ||||||
|                                     small></el-pagination> |  | ||||||
|                             </footer> |  | ||||||
|                         </div> |  | ||||||
|                     </div> |  | ||||||
|                 </div> |  | ||||||
|                 <div class="sc-user-select__toicon"> |  | ||||||
|                     <el-icon> |  | ||||||
|                         <el-icon-arrow-right /> |  | ||||||
|                     </el-icon> |  | ||||||
|                 </div> |  | ||||||
|                 <div class="sc-user-select__selected"> |  | ||||||
|                     <header>已选 ({{ selected.length }})</header> |  | ||||||
|                     <ul> |  | ||||||
|                         <el-scrollbar> |  | ||||||
|                             <li v-for="(item, index) in selected" :key="item.id"> |  | ||||||
|                                 <span class="name"> |  | ||||||
|                                     <el-avatar size="small">{{ item.name.substring(0, 1) }}</el-avatar> |  | ||||||
|                                     <label>{{ item.name }}</label> |  | ||||||
|                                 </span> |  | ||||||
|                                 <span class="delete"> |  | ||||||
|                                     <el-button @click="deleteSelected(index)" circle icon="el-icon-delete" size="small" type="danger"></el-button> |  | ||||||
|                                 </span> |  | ||||||
|                             </li> |  | ||||||
|                         </el-scrollbar> |  | ||||||
|                     </ul> |  | ||||||
|                 </div> |  | ||||||
|             </div> |  | ||||||
|         </template> |  | ||||||
|  |  | ||||||
|         <template v-if="type === 2"> |  | ||||||
|             <div class="sc-user-select sc-user-select-role"> |  | ||||||
|                 <div class="sc-user-select__left"> |  | ||||||
|                     <div class="sc-user-select__select"> |  | ||||||
|                         <div v-loading="showGrouploading" class="sc-user-select__tree"> |  | ||||||
|                             <el-scrollbar> |  | ||||||
|                                 <el-tree |  | ||||||
|                                     :data="role" |  | ||||||
|                                     :default-checked-keys="selectedIds" |  | ||||||
|                                     :expand-on-click-node="false" |  | ||||||
|                                     :node-key="roleProps.key" |  | ||||||
|                                     :props="roleProps" |  | ||||||
|                                     @check-change="roleClick" |  | ||||||
|                                     check-on-click-node |  | ||||||
|                                     check-strictly |  | ||||||
|                                     class="menu" |  | ||||||
|                                     ref="groupTree" |  | ||||||
|                                     show-checkbox /> |  | ||||||
|                             </el-scrollbar> |  | ||||||
|                         </div> |  | ||||||
|                     </div> |  | ||||||
|                 </div> |  | ||||||
|                 <div class="sc-user-select__toicon"> |  | ||||||
|                     <el-icon> |  | ||||||
|                         <el-icon-arrow-right /> |  | ||||||
|                     </el-icon> |  | ||||||
|                 </div> |  | ||||||
|                 <div class="sc-user-select__selected"> |  | ||||||
|                     <header>已选 ({{ selected.length }})</header> |  | ||||||
|                     <ul> |  | ||||||
|                         <el-scrollbar> |  | ||||||
|                             <li v-for="(item, index) in selected" :key="item.id"> |  | ||||||
|                                 <span class="name"> |  | ||||||
|                                     <label>{{ item.name }}</label> |  | ||||||
|                                 </span> |  | ||||||
|                                 <span class="delete"> |  | ||||||
|                                     <el-button @click="deleteSelected(index)" circle icon="el-icon-delete" size="small" type="danger"></el-button> |  | ||||||
|                                 </span> |  | ||||||
|                             </li> |  | ||||||
|                         </el-scrollbar> |  | ||||||
|                     </ul> |  | ||||||
|                 </div> |  | ||||||
|             </div> |  | ||||||
|         </template> |  | ||||||
|  |  | ||||||
|         <template #footer> |  | ||||||
|             <el-button @click="dialogVisible = false">取 消</el-button> |  | ||||||
|             <el-button @click="save" type="primary">确 认</el-button> |  | ||||||
|         </template> |  | ||||||
|     </el-dialog> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
| import config from '@/config/workflow' |  | ||||||
|  |  | ||||||
| export default { |  | ||||||
|     props: { |  | ||||||
|         modelValue: { type: Boolean, default: false }, |  | ||||||
|     }, |  | ||||||
|     data() { |  | ||||||
|         return { |  | ||||||
|             groupProps: config.group.props, |  | ||||||
|             userProps: config.user.props, |  | ||||||
|             roleProps: config.role.props, |  | ||||||
|  |  | ||||||
|             titleMap: ['人员选择', '角色选择'], |  | ||||||
|             dialogVisible: false, |  | ||||||
|             showGrouploading: false, |  | ||||||
|             showUserloading: false, |  | ||||||
|             keyword: '', |  | ||||||
|             groupId: '', |  | ||||||
|             pageSize: config.user.pageSize, |  | ||||||
|             total: 0, |  | ||||||
|             currentPage: 1, |  | ||||||
|             group: [], |  | ||||||
|             user: [], |  | ||||||
|             role: [], |  | ||||||
|             type: 1, |  | ||||||
|             selected: [], |  | ||||||
|             value: [], |  | ||||||
|         } |  | ||||||
|     }, |  | ||||||
|     computed: { |  | ||||||
|         selectedIds() { |  | ||||||
|             return this.selected.map((t) => t.id) |  | ||||||
|         }, |  | ||||||
|     }, |  | ||||||
|     mounted() {}, |  | ||||||
|     methods: { |  | ||||||
|         //打开赋值 |  | ||||||
|         open(type, data) { |  | ||||||
|             this.type = type |  | ||||||
|             this.value = data || [] |  | ||||||
|             this.selected = JSON.parse(JSON.stringify(data || [])) |  | ||||||
|             this.dialogVisible = true |  | ||||||
|  |  | ||||||
|             if (this.type === 1) { |  | ||||||
|                 this.getGroup() |  | ||||||
|                 this.getUser() |  | ||||||
|             } else if (this.type === 2) { |  | ||||||
|                 this.getRole() |  | ||||||
|             } |  | ||||||
|         }, |  | ||||||
|         //获取组织 |  | ||||||
|         async getGroup() { |  | ||||||
|             this.showGrouploading = true |  | ||||||
|             const res = await config.group.apiObj.get() |  | ||||||
|             this.showGrouploading = false |  | ||||||
|             const allNode = { [config.group.props.key]: '', [config.group.props.label]: '所有' } |  | ||||||
|             res.data.unshift(allNode) |  | ||||||
|             this.group = config.group.parseData(res).rows |  | ||||||
|         }, |  | ||||||
|         //获取用户 |  | ||||||
|         async getUser() { |  | ||||||
|             this.showUserloading = true |  | ||||||
|             const params = { |  | ||||||
|                 [config.user.request.keyword]: this.keyword || null, |  | ||||||
|                 [config.user.request.groupId]: this.groupId || null, |  | ||||||
|                 [config.user.request.page]: this.currentPage, |  | ||||||
|                 [config.user.request.pageSize]: this.pageSize, |  | ||||||
|             } |  | ||||||
|             const res = await config.user.apiObj.get(params) |  | ||||||
|             this.showUserloading = false |  | ||||||
|             this.user = config.user.parseData(res).rows |  | ||||||
|             this.total = config.user.parseData(res).total || 0 |  | ||||||
|             this.$refs.userScrollbar.setScrollTop(0) |  | ||||||
|         }, |  | ||||||
|         //获取角色 |  | ||||||
|         async getRole() { |  | ||||||
|             this.showGrouploading = true |  | ||||||
|             const res = await config.role.apiObj.get() |  | ||||||
|             this.showGrouploading = false |  | ||||||
|             this.role = config.role.parseData(res).rows |  | ||||||
|         }, |  | ||||||
|         //组织点击 |  | ||||||
|         groupClick(data) { |  | ||||||
|             this.keyword = '' |  | ||||||
|             this.currentPage = 1 |  | ||||||
|             this.groupId = data[config.group.props.key] |  | ||||||
|             this.getUser() |  | ||||||
|         }, |  | ||||||
|         //用户点击 |  | ||||||
|         userClick(data, checked) { |  | ||||||
|             if (checked) { |  | ||||||
|                 this.selected.push({ |  | ||||||
|                     id: data[config.user.props.key], |  | ||||||
|                     name: data[config.user.props.label], |  | ||||||
|                 }) |  | ||||||
|             } else { |  | ||||||
|                 this.selected = this.selected.filter((item) => item.id !== data[config.user.props.key]) |  | ||||||
|             } |  | ||||||
|         }, |  | ||||||
|         //用户分页点击 |  | ||||||
|         paginationChange() { |  | ||||||
|             this.getUser() |  | ||||||
|         }, |  | ||||||
|         //用户搜索 |  | ||||||
|         search() { |  | ||||||
|             this.groupId = '' |  | ||||||
|             this.$refs.groupTree.setCurrentKey(this.groupId) |  | ||||||
|             this.currentPage = 1 |  | ||||||
|             this.getUser() |  | ||||||
|         }, |  | ||||||
|         //删除已选 |  | ||||||
|         deleteSelected(index) { |  | ||||||
|             this.selected.splice(index, 1) |  | ||||||
|             if (this.type === 1) { |  | ||||||
|                 this.$refs.userTree.setCheckedKeys(this.selectedIds) |  | ||||||
|             } else if (this.type === 2) { |  | ||||||
|                 this.$refs.groupTree.setCheckedKeys(this.selectedIds) |  | ||||||
|             } |  | ||||||
|         }, |  | ||||||
|         //角色点击 |  | ||||||
|         roleClick(data, checked) { |  | ||||||
|             if (checked) { |  | ||||||
|                 this.selected.push({ |  | ||||||
|                     id: data[config.role.props.key], |  | ||||||
|                     name: data[config.role.props.label], |  | ||||||
|                 }) |  | ||||||
|             } else { |  | ||||||
|                 this.selected = this.selected.filter((item) => item.id !== data[config.role.props.key]) |  | ||||||
|             } |  | ||||||
|         }, |  | ||||||
|         //提交保存 |  | ||||||
|         save() { |  | ||||||
|             this.value.splice(0, this.value.length) |  | ||||||
|             this.selected.map((item) => { |  | ||||||
|                 this.value.push(item) |  | ||||||
|             }) |  | ||||||
|             this.dialogVisible = false |  | ||||||
|         }, |  | ||||||
|     }, |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style scoped> |  | ||||||
| .sc-user-select { |  | ||||||
|     display: flex; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .sc-user-select__left { |  | ||||||
|     width: 400px; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .sc-user-select__right { |  | ||||||
|     flex: 1; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .sc-user-select__search { |  | ||||||
|     padding-bottom: 10px; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .sc-user-select__select { |  | ||||||
|     display: flex; |  | ||||||
|     border: 1px solid var(--el-border-color-light); |  | ||||||
|     background: var(--el-color-white); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .sc-user-select__tree { |  | ||||||
|     width: 200px; |  | ||||||
|     height: 300px; |  | ||||||
|     border-right: 1px solid var(--el-border-color-light); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .sc-user-select__user { |  | ||||||
|     width: 200px; |  | ||||||
|     height: 300px; |  | ||||||
|     display: flex; |  | ||||||
|     flex-direction: column; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .sc-user-select__user__list { |  | ||||||
|     flex: 1; |  | ||||||
|     overflow: auto; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .sc-user-select__user footer { |  | ||||||
|     height: 36px; |  | ||||||
|     padding-top: 5px; |  | ||||||
|     border-top: 1px solid var(--el-border-color-light); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .sc-user-select__toicon { |  | ||||||
|     display: flex; |  | ||||||
|     justify-content: center; |  | ||||||
|     align-items: center; |  | ||||||
|     margin: 0 10px; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .sc-user-select__toicon i { |  | ||||||
|     display: flex; |  | ||||||
|     justify-content: center; |  | ||||||
|     align-items: center; |  | ||||||
|     background: #ccc; |  | ||||||
|     width: 20px; |  | ||||||
|     height: 20px; |  | ||||||
|     text-align: center; |  | ||||||
|     line-height: 20px; |  | ||||||
|     border-radius: 50%; |  | ||||||
|     color: #fff; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .sc-user-select__selected { |  | ||||||
|     height: 345px; |  | ||||||
|     width: 200px; |  | ||||||
|     border: 1px solid var(--el-border-color-light); |  | ||||||
|     background: var(--el-color-white); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .sc-user-select__selected header { |  | ||||||
|     height: 43px; |  | ||||||
|     line-height: 43px; |  | ||||||
|     border-bottom: 1px solid var(--el-border-color-light); |  | ||||||
|     padding: 0 1rem; |  | ||||||
|     font-size: 12px; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .sc-user-select__selected ul { |  | ||||||
|     height: 300px; |  | ||||||
|     overflow: auto; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .sc-user-select__selected li { |  | ||||||
|     display: flex; |  | ||||||
|     align-items: center; |  | ||||||
|     justify-content: space-between; |  | ||||||
|     padding: 5px 5px 5px 1rem; |  | ||||||
|     height: 38px; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .sc-user-select__selected li .name { |  | ||||||
|     display: flex; |  | ||||||
|     align-items: center; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .sc-user-select__selected li .name .el-avatar { |  | ||||||
|     background: #409eff; |  | ||||||
|     margin-right: 10px; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .sc-user-select__selected li .delete { |  | ||||||
|     display: none; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .sc-user-select__selected li:hover { |  | ||||||
|     background: var(--el-color-primary-light-9); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .sc-user-select__selected li:hover .delete { |  | ||||||
|     display: inline-block; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .sc-user-select-role .sc-user-select__left { |  | ||||||
|     width: 200px; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .sc-user-select-role .sc-user-select__tree { |  | ||||||
|     border: none; |  | ||||||
|     height: 343px; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| [data-theme='dark'] .sc-user-select__selected li:hover { |  | ||||||
|     background: rgba(0, 0, 0, 0.2); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| [data-theme='dark'] .sc-user-select__toicon i { |  | ||||||
|     background: #383838; |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
| @@ -60,9 +60,9 @@ const DEFAULT_CONFIG = { | |||||||
|     //控制台首页默认布局 |     //控制台首页默认布局 | ||||||
|     DEFAULT_GRID: { |     DEFAULT_GRID: { | ||||||
|         //默认分栏数量和宽度 例如 [24] [18,6] [8,8,8] [6,12,6] |         //默认分栏数量和宽度 例如 [24] [18,6] [8,8,8] [6,12,6] | ||||||
|         layout: [24], |         layout: [24, 12, 12], | ||||||
|         //小组件分布,com取值:views/home/components 文件名 |         //小组件分布,com取值:views/home/components 文件名 | ||||||
|         compsList: [['ver']], |         compsList: [['ver'], ['modules'], ['change-log']], | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     //默认头像 |     //默认头像 | ||||||
|   | |||||||
| @@ -6,5 +6,5 @@ | |||||||
|  |  | ||||||
| export default { | export default { | ||||||
|     //是否显示第三方授权登录 |     //是否显示第三方授权登录 | ||||||
|     MY_SHOW_LOGIN_OAUTH: true, |     MY_SHOW_LOGIN_OAUTH: false, | ||||||
| } | } | ||||||
| @@ -28,7 +28,6 @@ import scStatusIndicator from '@/components/scMini/scStatusIndicator' | |||||||
| import scTable from '@/components/scTable' | import scTable from '@/components/scTable' | ||||||
| import scTableColumn from '@/components/scTable/column.js' | import scTableColumn from '@/components/scTable/column.js' | ||||||
| import scTableSelect from '@/components/scTableSelect' | import scTableSelect from '@/components/scTableSelect' | ||||||
| import scTitle from '@/components/scTitle' |  | ||||||
| import scTrend from '@/components/scMini/scTrend' | import scTrend from '@/components/scMini/scTrend' | ||||||
| import scUpload from '@/components/scUpload' | import scUpload from '@/components/scUpload' | ||||||
| import scUploadFile from '@/components/scUpload/file' | import scUploadFile from '@/components/scUpload/file' | ||||||
| @@ -98,7 +97,6 @@ export default { | |||||||
|         app.component('scTable', scTable) |         app.component('scTable', scTable) | ||||||
|         app.component('scTableColumn', scTableColumn) |         app.component('scTableColumn', scTableColumn) | ||||||
|         app.component('scTableSelect', scTableSelect) |         app.component('scTableSelect', scTableSelect) | ||||||
|         app.component('scTitle', scTitle) |  | ||||||
|         app.component('scTrend', scTrend) |         app.component('scTrend', scTrend) | ||||||
|         app.component('scUpload', scUpload) |         app.component('scUpload', scUpload) | ||||||
|         app.component('scUploadFile', scUploadFile) |         app.component('scUploadFile', scUploadFile) | ||||||
|   | |||||||
| @@ -24,7 +24,7 @@ | |||||||
|         <div class="sc-search-result"> |         <div class="sc-search-result"> | ||||||
|             <div v-if="result.length <= 0" class="sc-search-no-result">暂无搜索结果</div> |             <div v-if="result.length <= 0" class="sc-search-no-result">暂无搜索结果</div> | ||||||
|             <ul v-else> |             <ul v-else> | ||||||
|                 <el-scrollbar max-height="366px"> |                 <el-scrollbar max-height="30rem"> | ||||||
|                     <li v-for="item in result" :key="item.path" @click="to(item)"> |                     <li v-for="item in result" :key="item.path" @click="to(item)"> | ||||||
|                         <el-icon> |                         <el-icon> | ||||||
|                             <component :is="item.icon || 'el-icon-menu'" /> |                             <component :is="item.icon || 'el-icon-menu'" /> | ||||||
| @@ -147,12 +147,12 @@ export default { | |||||||
| <style scoped> | <style scoped> | ||||||
| .sc-search-no-result { | .sc-search-no-result { | ||||||
|     text-align: center; |     text-align: center; | ||||||
|     margin: 40px 0; |     margin: 3rem 0; | ||||||
|     color: #999; |     color: #999; | ||||||
| } | } | ||||||
|  |  | ||||||
| .sc-search-history { | .sc-search-history { | ||||||
|     margin-top: 10px; |     margin-top: 1rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .sc-search-history .el-tag { | .sc-search-history .el-tag { | ||||||
| @@ -164,21 +164,21 @@ export default { | |||||||
| } | } | ||||||
|  |  | ||||||
| .sc-search-result li { | .sc-search-result li { | ||||||
|     height: 56px; |     height: 4rem; | ||||||
|     padding: 0 1rem; |     padding: 0 1rem; | ||||||
|     background: var(--el-bg-color-overlay); |     background: var(--el-bg-color-overlay); | ||||||
|     border: 1px solid var(--el-border-color-light); |     border: 1px solid var(--el-border-color-light); | ||||||
|     list-style: none; |     list-style: none; | ||||||
|     border-radius: 4px; |     border-radius: 0.4rem; | ||||||
|     margin-bottom: 5px; |     margin-bottom: 0.4rem; | ||||||
|     font-size: 14px; |     font-size: 1.1rem; | ||||||
|     display: flex; |     display: flex; | ||||||
|     align-items: center; |     align-items: center; | ||||||
|     cursor: pointer; |     cursor: pointer; | ||||||
| } | } | ||||||
|  |  | ||||||
| .sc-search-result li i { | .sc-search-result li i { | ||||||
|     font-size: 20px; |     font-size: 1.5rem; | ||||||
|     margin-right: 1rem; |     margin-right: 1rem; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -18,7 +18,7 @@ | |||||||
|                         :default-active="$route.meta.active || $route.fullPath" |                         :default-active="$route.meta.active || $route.fullPath" | ||||||
|                         @select="select" |                         @select="select" | ||||||
|                         active-text-color="#409EFF" |                         active-text-color="#409EFF" | ||||||
|                         background-color="#212d3d" |                         background-color="#424c50" | ||||||
|                         router |                         router | ||||||
|                         text-color="#fff"> |                         text-color="#fff"> | ||||||
|                         <NavMenu :navMenus="menu"></NavMenu> |                         <NavMenu :navMenus="menu"></NavMenu> | ||||||
| @@ -132,13 +132,13 @@ export default { | |||||||
| <style scoped> | <style scoped> | ||||||
| .mobile-nav-button { | .mobile-nav-button { | ||||||
|     position: fixed; |     position: fixed; | ||||||
|     bottom: 10px; |     bottom: 1rem; | ||||||
|     left: 10px; |     left: 1rem; | ||||||
|     z-index: 10; |     z-index: 10; | ||||||
|     width: 50px; |     width: 4rem; | ||||||
|     height: 50px; |     height: 4rem; | ||||||
|     background: #409eff; |     background: #409eff; | ||||||
|     box-shadow: 0 2px 12px 0 rgba(64, 158, 255, 1); |     box-shadow: 0 0.2rem 1rem 0 rgba(64, 158, 255, 1); | ||||||
|     border-radius: 50%; |     border-radius: 50%; | ||||||
|     display: flex; |     display: flex; | ||||||
|     align-items: center; |     align-items: center; | ||||||
| @@ -147,11 +147,11 @@ export default { | |||||||
|  |  | ||||||
| .mobile-nav-button i { | .mobile-nav-button i { | ||||||
|     color: #fff; |     color: #fff; | ||||||
|     font-size: 20px; |     font-size: 1.5rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .mobile-nav { | .mobile-nav { | ||||||
|     background: #212d3d; |     background: #424c50; | ||||||
| } | } | ||||||
|  |  | ||||||
| .mobile-nav .el-header { | .mobile-nav .el-header { | ||||||
| @@ -167,16 +167,12 @@ export default { | |||||||
|     display: flex; |     display: flex; | ||||||
|     align-items: center; |     align-items: center; | ||||||
|     font-weight: bold; |     font-weight: bold; | ||||||
|     font-size: 20px; |     font-size: 1.5rem; | ||||||
|     color: #fff; |     color: #fff; | ||||||
| } | } | ||||||
|  |  | ||||||
| .mobile-nav .logo-bar img { | .mobile-nav .logo-bar img { | ||||||
|     width: 30px; |     width: 2.5rem; | ||||||
|     margin-right: 10px; |     margin-right: 1rem; | ||||||
| } |  | ||||||
|  |  | ||||||
| .mobile-nav .el-submenu__title:hover { |  | ||||||
|     background: #fff !important; |  | ||||||
| } | } | ||||||
| </style> | </style> | ||||||
| @@ -287,19 +287,19 @@ export default { | |||||||
| <style> | <style> | ||||||
| .contextmenu { | .contextmenu { | ||||||
|     position: fixed; |     position: fixed; | ||||||
|     width: 200px; |     width: 15rem; | ||||||
|     margin: 0; |     margin: 0; | ||||||
|     border-radius: 0; |     border-radius: 0; | ||||||
|     background: var(--el-bg-color-overlay); |     background: var(--el-bg-color-overlay); | ||||||
|     border: 1px solid var(--el-border-color-light); |     border: 1px solid var(--el-border-color-light); | ||||||
|     box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); |     box-shadow: 0 0.2rem 1rem 0 rgba(0, 0, 0, 0.1); | ||||||
|     z-index: 3000; |     z-index: 3000; | ||||||
|     list-style-type: none; |     list-style-type: none; | ||||||
|     padding: 10px 0; |     padding: 1rem 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| .contextmenu hr { | .contextmenu hr { | ||||||
|     margin: 5px 0; |     margin: 0.4rem 0; | ||||||
|     border: none; |     border: none; | ||||||
|     height: 1px; |     height: 1px; | ||||||
|     font-size: 0; |     font-size: 0; | ||||||
| @@ -311,14 +311,14 @@ export default { | |||||||
|     align-items: center; |     align-items: center; | ||||||
|     margin: 0; |     margin: 0; | ||||||
|     cursor: pointer; |     cursor: pointer; | ||||||
|     line-height: 30px; |     line-height: 2.5rem; | ||||||
|     padding: 0 17px; |     padding: 0 1.3rem; | ||||||
|     color: #606266; |     color: #606266; | ||||||
| } | } | ||||||
|  |  | ||||||
| .contextmenu li i { | .contextmenu li i { | ||||||
|     font-size: 14px; |     font-size: 1.1rem; | ||||||
|     margin-right: 10px; |     margin-right: 1rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .contextmenu li:hover { | .contextmenu li:hover { | ||||||
| @@ -332,14 +332,6 @@ export default { | |||||||
|     background: transparent; |     background: transparent; | ||||||
| } | } | ||||||
|  |  | ||||||
| .tags-tip { |  | ||||||
|     padding: 5px; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .tags-tip p { |  | ||||||
|     margin-bottom: 10px; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .dark .contextmenu li { | .dark .contextmenu li { | ||||||
|     color: var(--el-text-color-primary); |     color: var(--el-text-color-primary); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -50,8 +50,8 @@ export default { | |||||||
| } | } | ||||||
|  |  | ||||||
| .el-breadcrumb .el-breadcrumb__inner .icon { | .el-breadcrumb .el-breadcrumb__inner .icon { | ||||||
|     font-size: 14px; |     font-size: 1.1rem; | ||||||
|     margin-right: 5px; |     margin-right: 0.4rem; | ||||||
|     float: left; |     float: left; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -63,7 +63,7 @@ export default { | |||||||
| .breadcrumb-enter-from, | .breadcrumb-enter-from, | ||||||
| .breadcrumb-leave-active { | .breadcrumb-leave-active { | ||||||
|     opacity: 0; |     opacity: 0; | ||||||
|     transform: translateX(20px); |     transform: translateX(1.5rem); | ||||||
| } | } | ||||||
|  |  | ||||||
| .breadcrumb-leave-active { | .breadcrumb-leave-active { | ||||||
|   | |||||||
| @@ -181,7 +181,7 @@ export default { | |||||||
| } | } | ||||||
|  |  | ||||||
| .user-bar .panel-item { | .user-bar .panel-item { | ||||||
|     padding: 0 10px; |     padding: 0 0.5rem; | ||||||
|     cursor: pointer; |     cursor: pointer; | ||||||
|     height: 100%; |     height: 100%; | ||||||
|     display: flex; |     display: flex; | ||||||
| @@ -189,7 +189,7 @@ export default { | |||||||
| } | } | ||||||
|  |  | ||||||
| .user-bar .panel-item i { | .user-bar .panel-item i { | ||||||
|     font-size: 16px; |     font-size: 1.2rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .user-bar .panel-item:hover { | .user-bar .panel-item:hover { | ||||||
| @@ -197,15 +197,15 @@ export default { | |||||||
| } | } | ||||||
|  |  | ||||||
| .user-bar .user-avatar { | .user-bar .user-avatar { | ||||||
|     height: 49px; |     height: 4rem; | ||||||
|     display: flex; |     display: flex; | ||||||
|     align-items: center; |     align-items: center; | ||||||
| } | } | ||||||
|  |  | ||||||
| .user-bar .user-avatar label { | .user-bar .user-avatar label { | ||||||
|     display: inline-block; |     display: inline-block; | ||||||
|     margin-left: 5px; |     margin-left: 0.4rem; | ||||||
|     font-size: 12px; |     font-size: 0.9rem; | ||||||
|     cursor: pointer; |     cursor: pointer; | ||||||
| } | } | ||||||
| </style> | </style> | ||||||
| @@ -6,9 +6,9 @@ | |||||||
|         <div class="router-err__content"> |         <div class="router-err__content"> | ||||||
|             <h2>无权限或找不到页面</h2> |             <h2>无权限或找不到页面</h2> | ||||||
|             <p>当前页面无权限访问或者打开了一个不存在的链接,请检查当前账户权限和链接的可访问性。</p> |             <p>当前页面无权限访问或者打开了一个不存在的链接,请检查当前账户权限和链接的可访问性。</p> | ||||||
|             <el-button @click="gohome" plain round type="primary">返回首页</el-button> |             <el-button @click="goHome" plain round type="primary">返回首页</el-button> | ||||||
|             <el-button @click="gologin" plain round type="primary">重新登录</el-button> |             <el-button @click="goLogin" plain round type="primary">重新登录</el-button> | ||||||
|             <el-button @click="goback" round type="primary">返回上一页</el-button> |             <el-button @click="goBack" round type="primary">返回上一页</el-button> | ||||||
|         </div> |         </div> | ||||||
|     </div> |     </div> | ||||||
| </template> | </template> | ||||||
| @@ -16,13 +16,13 @@ | |||||||
| <script> | <script> | ||||||
| export default { | export default { | ||||||
|     methods: { |     methods: { | ||||||
|         gohome() { |         goHome() { | ||||||
|             location.href = '/' |             location.href = '/' | ||||||
|         }, |         }, | ||||||
|         goback() { |         goBack() { | ||||||
|             this.$router.go(-1) |             this.$router.go(-1) | ||||||
|         }, |         }, | ||||||
|         gologin() { |         goLogin() { | ||||||
|             this.$router.push('/guest/login') |             this.$router.push('/guest/login') | ||||||
|         }, |         }, | ||||||
|     }, |     }, | ||||||
| @@ -32,13 +32,13 @@ export default { | |||||||
| <style scoped> | <style scoped> | ||||||
| .router-err { | .router-err { | ||||||
|     display: flex; |     display: flex; | ||||||
|     width: 900px; |     width: 70rem; | ||||||
|     margin: 50px auto; |     margin: 4rem auto; | ||||||
|     align-items: center; |     align-items: center; | ||||||
| } | } | ||||||
|  |  | ||||||
| .router-err__icon { | .router-err__icon { | ||||||
|     width: 400px; |     width: 30rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .router-err__icon img { | .router-err__icon img { | ||||||
| @@ -47,30 +47,30 @@ export default { | |||||||
|  |  | ||||||
| .router-err__content { | .router-err__content { | ||||||
|     flex: 1; |     flex: 1; | ||||||
|     padding: 40px; |     padding: 3rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .router-err__content h2 { | .router-err__content h2 { | ||||||
|     font-size: 26px; |     font-size: 2rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .router-err__content p { | .router-err__content p { | ||||||
|     font-size: 14px; |     font-size: 1.1rem; | ||||||
|     color: #999; |     color: #999; | ||||||
|     margin: 1rem 0 30px 0; |     margin: 1rem 0 2.5rem 0; | ||||||
|     line-height: 1.5; |     line-height: 1.5; | ||||||
| } | } | ||||||
|  |  | ||||||
| @media (max-width: 992px) { | @media (max-width: 77rem) { | ||||||
|     .router-err { |     .router-err { | ||||||
|         display: block; |         display: block; | ||||||
|         width: 100%; |         width: 100%; | ||||||
|         margin-top: 10px; |         margin-top: 1rem; | ||||||
|         text-align: center; |         text-align: center; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     .router-err__icon { |     .router-err__icon { | ||||||
|         width: 280px; |         width: 22rem; | ||||||
|         margin: 0 auto; |         margin: 0 auto; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -5,8 +5,8 @@ html { | |||||||
|     width: 100%; |     width: 100%; | ||||||
|     height: 100%; |     height: 100%; | ||||||
|     background-color: #f6f8f9; |     background-color: #f6f8f9; | ||||||
|     font-size: 13px; |     font-size: var(--el-font-size-base); | ||||||
|     font-family: monospace; |     font-family: 'Lucida Console', 'Microsoft YaHei', 'monospace'; | ||||||
| } | } | ||||||
|  |  | ||||||
| a { | a { | ||||||
| @@ -63,8 +63,8 @@ textarea { | |||||||
| } | } | ||||||
|  |  | ||||||
| ::-webkit-scrollbar { | ::-webkit-scrollbar { | ||||||
|     width: 5px; |     width: 0.4rem; | ||||||
|     height: 5px; |     height: 0.4rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| ::-webkit-scrollbar-thumb { | ::-webkit-scrollbar-thumb { | ||||||
| @@ -86,10 +86,10 @@ textarea { | |||||||
| /*布局设置*/ | /*布局设置*/ | ||||||
| .layout-setting { | .layout-setting { | ||||||
|     position: fixed; |     position: fixed; | ||||||
|     width: 40px; |     width: 3rem; | ||||||
|     height: 40px; |     height: 3rem; | ||||||
|     border-radius: 3px 0 0 3px; |     border-radius: 0.3rem 0 0 0.3rem; | ||||||
|     bottom: 100px; |     bottom: 10rem; | ||||||
|     right: 0; |     right: 0; | ||||||
|     z-index: 100; |     z-index: 100; | ||||||
|     background: #409eff; |     background: #409eff; | ||||||
| @@ -101,13 +101,13 @@ textarea { | |||||||
| } | } | ||||||
|  |  | ||||||
| .layout-setting i { | .layout-setting i { | ||||||
|     font-size: 18px; |     font-size: 1.3rem; | ||||||
|     color: #fff; |     color: #fff; | ||||||
| } | } | ||||||
|  |  | ||||||
| /* 头部 */ | /* 头部 */ | ||||||
| .adminui-header { | .adminui-header { | ||||||
|     height: 58px; |     height: 4rem; | ||||||
|     background: #424c50; |     background: #424c50; | ||||||
|     color: #fff; |     color: #fff; | ||||||
|     display: flex; |     display: flex; | ||||||
| @@ -117,7 +117,7 @@ textarea { | |||||||
| .adminui-header-left { | .adminui-header-left { | ||||||
|     display: flex; |     display: flex; | ||||||
|     align-items: center; |     align-items: center; | ||||||
|     padding-left: 20px; |     padding-left: 1rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .adminui-header-right { | .adminui-header-right { | ||||||
| @@ -126,28 +126,28 @@ textarea { | |||||||
| } | } | ||||||
|  |  | ||||||
| .adminui-header .logo-bar { | .adminui-header .logo-bar { | ||||||
|     font-size: 20px; |     font-size: 1.5rem; | ||||||
|     font-weight: bold; |     font-weight: bold; | ||||||
|     display: flex; |     display: flex; | ||||||
|     align-items: center; |     align-items: center; | ||||||
| } | } | ||||||
|  |  | ||||||
| .adminui-header .logo-bar .logo { | .adminui-header .logo-bar .logo { | ||||||
|     margin-right: 10px; |     margin-right: 1rem; | ||||||
|     width: 35px; |     width: 3rem; | ||||||
|     height: 35px; |     height: 3rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .adminui-header .nav { | .adminui-header .nav { | ||||||
|     display: flex; |     display: flex; | ||||||
|     height: 100%; |     height: 100%; | ||||||
|     margin-left: 40px; |     margin-left: 3rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .adminui-header .nav li { | .adminui-header .nav li { | ||||||
|     padding: 0 10px; |     padding: 0 1rem; | ||||||
|     margin: 0 10px 0 0; |     margin: 0 1rem 0 0; | ||||||
|     font-size: 14px; |     font-size: 1.1rem; | ||||||
|     color: rgba(255, 255, 255, 0.6); |     color: rgba(255, 255, 255, 0.6); | ||||||
|     list-style: none; |     list-style: none; | ||||||
|     height: 100%; |     height: 100%; | ||||||
| @@ -157,7 +157,7 @@ textarea { | |||||||
| } | } | ||||||
|  |  | ||||||
| .adminui-header .nav li i { | .adminui-header .nav li i { | ||||||
|     margin-right: 5px; |     margin-right: 0.3rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .adminui-header .nav li:hover { | .adminui-header .nav li:hover { | ||||||
| @@ -179,7 +179,7 @@ textarea { | |||||||
|  |  | ||||||
| /* 左侧菜单 */ | /* 左侧菜单 */ | ||||||
| .aminui-side-split { | .aminui-side-split { | ||||||
|     width: 65px; |     width: 5rem; | ||||||
|     flex-shrink: 0; |     flex-shrink: 0; | ||||||
|     background: #424c50; |     background: #424c50; | ||||||
|     display: flex; |     display: flex; | ||||||
| @@ -187,7 +187,7 @@ textarea { | |||||||
| } | } | ||||||
|  |  | ||||||
| .aminui-side-split-top { | .aminui-side-split-top { | ||||||
|     height: 49px; |     height: 4rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .aminui-side-split-top a { | .aminui-side-split-top a { | ||||||
| @@ -199,7 +199,7 @@ textarea { | |||||||
| } | } | ||||||
|  |  | ||||||
| .aminui-side-split-top .logo { | .aminui-side-split-top .logo { | ||||||
|     height: 30px; |     height: 3rem; | ||||||
|     vertical-align: bottom; |     vertical-align: bottom; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -212,8 +212,8 @@ textarea { | |||||||
|  |  | ||||||
| .aminui-side-split li { | .aminui-side-split li { | ||||||
|     cursor: pointer; |     cursor: pointer; | ||||||
|     width: 65px; |     width: 5rem; | ||||||
|     height: 65px; |     height: 5rem; | ||||||
|     color: #fff; |     color: #fff; | ||||||
|     text-align: center; |     text-align: center; | ||||||
|     display: flex; |     display: flex; | ||||||
| @@ -223,11 +223,11 @@ textarea { | |||||||
| } | } | ||||||
|  |  | ||||||
| .aminui-side-split li i { | .aminui-side-split li i { | ||||||
|     font-size: 18px; |     font-size: 1.5rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .aminui-side-split li p { | .aminui-side-split li p { | ||||||
|     margin-top: 5px; |     margin-top: 0.5rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .aminui-side-split li:hover { | .aminui-side-split li:hover { | ||||||
| @@ -240,7 +240,7 @@ textarea { | |||||||
|  |  | ||||||
| .adminui-side-split-scroll::-webkit-scrollbar-thumb { | .adminui-side-split-scroll::-webkit-scrollbar-thumb { | ||||||
|     background-color: rgba(255, 255, 255, 0.4); |     background-color: rgba(255, 255, 255, 0.4); | ||||||
|     border-radius: 5px; |     border-radius: 0.4rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .adminui-side-split-scroll::-webkit-scrollbar-thumb:hover { | .adminui-side-split-scroll::-webkit-scrollbar-thumb:hover { | ||||||
| @@ -259,22 +259,21 @@ textarea { | |||||||
|     display: flex; |     display: flex; | ||||||
|     flex-flow: column; |     flex-flow: column; | ||||||
|     flex-shrink: 0; |     flex-shrink: 0; | ||||||
|     width: 210px; |     width: 15rem; | ||||||
|     background: #fff; |     background: #fff; | ||||||
|     box-shadow: 2px 0 8px 0 rgba(29, 35, 41, 0.05); |  | ||||||
|     border-right: 1px solid #e6e6e6; |     border-right: 1px solid #e6e6e6; | ||||||
|     transition: width 0.3s; |     transition: width 0.3s; | ||||||
| } | } | ||||||
|  |  | ||||||
| .adminui-side-top { | .adminui-side-top { | ||||||
|     border-bottom: 1px solid #ebeef5; |     border-bottom: 1px solid #ebeef5; | ||||||
|     height: 50px; |     height: 4rem; | ||||||
|     line-height: 50px; |     line-height: 4rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .adminui-side-top h2 { | .adminui-side-top h2 { | ||||||
|     padding: 0 20px; |     padding: 0 var(--el-menu-base-level-padding); | ||||||
|     font-size: 17px; |     font-size: 1.3rem; | ||||||
|     color: #3c4a54; |     color: #3c4a54; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -286,7 +285,7 @@ textarea { | |||||||
|  |  | ||||||
| .adminui-side-bottom { | .adminui-side-bottom { | ||||||
|     border-top: 1px solid #ebeef5; |     border-top: 1px solid #ebeef5; | ||||||
|     height: 51px; |     height: 4rem; | ||||||
|     cursor: pointer; |     cursor: pointer; | ||||||
|     display: flex; |     display: flex; | ||||||
|     align-items: center; |     align-items: center; | ||||||
| @@ -294,7 +293,7 @@ textarea { | |||||||
| } | } | ||||||
|  |  | ||||||
| .adminui-side-bottom i { | .adminui-side-bottom i { | ||||||
|     font-size: 16px; |     font-size: 1.3rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .adminui-side-bottom:hover { | .adminui-side-bottom:hover { | ||||||
| @@ -302,23 +301,19 @@ textarea { | |||||||
| } | } | ||||||
|  |  | ||||||
| .aminui-side.isCollapse { | .aminui-side.isCollapse { | ||||||
|     width: 65px; |     width: 5rem; | ||||||
| } | } | ||||||
|  |  | ||||||
| .el-menu .menu-tag { | .el-menu .menu-tag { | ||||||
|     position: absolute; |     position: absolute; | ||||||
|     height: 18px; |     height: 1.4rem; | ||||||
|     line-height: 18px; |     line-height: 1.4rem; | ||||||
|     background: var(--el-color-danger); |     background: var(--el-color-danger); | ||||||
|     font-size: 12px; |     font-size: 0.9rem; | ||||||
|     color: #fff; |     color: #fff; | ||||||
|     right: 20px; |     right: 1rem; | ||||||
|     border-radius: 18px; |     border-radius: 1.5rem; | ||||||
|     padding: 0 6px; |     padding: 0 0.5rem; | ||||||
| } |  | ||||||
|  |  | ||||||
| .el-menu .el-sub-menu__title .menu-tag { |  | ||||||
|     right: 40px; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| .el-menu--horizontal > li .menu-tag { | .el-menu--horizontal > li .menu-tag { | ||||||
| @@ -333,10 +328,9 @@ textarea { | |||||||
| } | } | ||||||
|  |  | ||||||
| .adminui-topbar { | .adminui-topbar { | ||||||
|     height: 50px; |     height: 3rem; | ||||||
|     border-bottom: 1px solid #ebeef5; |     border-bottom: 1px solid #ebeef5; | ||||||
|     background: #fff; |     background: #fff; | ||||||
|     box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08); |  | ||||||
|     display: flex; |     display: flex; | ||||||
|     justify-content: space-between; |     justify-content: space-between; | ||||||
| } | } | ||||||
| @@ -358,7 +352,7 @@ textarea { | |||||||
| } | } | ||||||
|  |  | ||||||
| .adminui-tags { | .adminui-tags { | ||||||
|     height: 35px; |     height: 3rem; | ||||||
|     background: #fff; |     background: #fff; | ||||||
|     border-bottom: 1px solid #e6e6e6; |     border-bottom: 1px solid #e6e6e6; | ||||||
| } | } | ||||||
| @@ -371,8 +365,8 @@ textarea { | |||||||
| .adminui-tags li { | .adminui-tags li { | ||||||
|     cursor: pointer; |     cursor: pointer; | ||||||
|     display: inline-block; |     display: inline-block; | ||||||
|     height: 34px; |     height: calc(3rem - 1px); | ||||||
|     line-height: 34px; |     line-height: calc(3rem - 1px); | ||||||
|     position: relative; |     position: relative; | ||||||
|     flex-shrink: 0; |     flex-shrink: 0; | ||||||
| } | } | ||||||
| @@ -387,7 +381,7 @@ textarea { | |||||||
| } | } | ||||||
|  |  | ||||||
| .adminui-tags li a { | .adminui-tags li a { | ||||||
|     padding: 0 10px; |     padding: 0 1rem; | ||||||
|     width: 100%; |     width: 100%; | ||||||
|     height: 100%; |     height: 100%; | ||||||
|     color: #999; |     color: #999; | ||||||
| @@ -397,10 +391,10 @@ textarea { | |||||||
| } | } | ||||||
|  |  | ||||||
| .adminui-tags li i { | .adminui-tags li i { | ||||||
|     margin-left: 10px; |     margin-left: 1rem; | ||||||
|     border-radius: 3px; |     border-radius: 0.3rem; | ||||||
|     width: 18px; |     width: 1.3rem; | ||||||
|     height: 18px; |     height: 1.3rem; | ||||||
|     display: flex; |     display: flex; | ||||||
|     align-items: center; |     align-items: center; | ||||||
|     justify-content: center; |     justify-content: center; | ||||||
| @@ -452,20 +446,20 @@ textarea { | |||||||
|     display: none; |     display: none; | ||||||
|     position: fixed; |     position: fixed; | ||||||
|     z-index: 3000; |     z-index: 3000; | ||||||
|     top: -20px; |     top: -1.5rem; | ||||||
|     left: 50%; |     left: 50%; | ||||||
|     margin-left: -20px; |     margin-left: -1.5rem; | ||||||
|     border-radius: 50%; |     border-radius: 50%; | ||||||
|     width: 40px; |     width: 3rem; | ||||||
|     height: 40px; |     height: 3rem; | ||||||
|     cursor: pointer; |     cursor: pointer; | ||||||
|     background: rgba(0, 0, 0, 0.2); |     background: rgba(0, 0, 0, 0.2); | ||||||
|     text-align: center; |     text-align: center; | ||||||
| } | } | ||||||
|  |  | ||||||
| .main-maximize-exit i { | .main-maximize-exit i { | ||||||
|     font-size: 14px; |     font-size: 1rem; | ||||||
|     margin-top: 22px; |     margin-top: 1.5rem; | ||||||
|     color: #fff; |     color: #fff; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -475,7 +469,7 @@ textarea { | |||||||
|  |  | ||||||
| /*定宽页面*/ | /*定宽页面*/ | ||||||
| .sc-page { | .sc-page { | ||||||
|     width: 1230px; |     width: 100rem; | ||||||
|     margin: 0 auto; |     margin: 0 auto; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -24,7 +24,7 @@ html.dark { | |||||||
|     .adminui-header { |     .adminui-header { | ||||||
|         background: var(--el-bg-color-overlay); |         background: var(--el-bg-color-overlay); | ||||||
|         border-bottom: 1px solid var(--el-border-color-light); |         border-bottom: 1px solid var(--el-border-color-light); | ||||||
|         height: 59px; |         height: 4rem; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     .aminui-side-split { |     .aminui-side-split { | ||||||
|   | |||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user
	 GitHub
						GitHub