😎1、优化条件必填参数验证特性 2、优化字典和下拉框组件 3、优化远程日志页面
This commit is contained in:
parent
83ca39fd9f
commit
801a31dfba
@ -64,11 +64,13 @@ public sealed class RequiredIFAttribute(
|
|||||||
|
|
||||||
var instance = validationContext.ObjectInstance;
|
var instance = validationContext.ObjectInstance;
|
||||||
var targetProperty = instance.GetType().GetProperty(PropertyName);
|
var targetProperty = instance.GetType().GetProperty(PropertyName);
|
||||||
|
// 判断校验字段内容是否为字典
|
||||||
|
var dictAttr = targetProperty?.GetCustomAttribute<DictAttribute>();
|
||||||
|
|
||||||
if (targetProperty == null) return new ValidationResult($"找不到属性: {PropertyName}");
|
if (targetProperty == null) return new ValidationResult($"找不到属性: {PropertyName}");
|
||||||
var targetValue = targetProperty.GetValue(instance);
|
var targetValue = targetProperty.GetValue(instance);
|
||||||
|
|
||||||
if (!ShouldValidate(targetValue)) return ValidationResult.Success;
|
if (!ShouldValidate(targetValue, dictAttr)) return ValidationResult.Success;
|
||||||
|
|
||||||
return IsEmpty(value) ? new ValidationResult(ErrorMessage ?? $"{validationContext.MemberName}不能为空") : ValidationResult.Success;
|
return IsEmpty(value) ? new ValidationResult(ErrorMessage ?? $"{validationContext.MemberName}不能为空") : ValidationResult.Success;
|
||||||
}
|
}
|
||||||
@ -78,7 +80,7 @@ public sealed class RequiredIFAttribute(
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="targetValue">依赖属性的值</param>
|
/// <param name="targetValue">依赖属性的值</param>
|
||||||
/// <returns>是否需要验证</returns>
|
/// <returns>是否需要验证</returns>
|
||||||
private bool ShouldValidate(object targetValue)
|
private bool ShouldValidate(object targetValue, DictAttribute dictAttr)
|
||||||
{
|
{
|
||||||
switch (Comparison)
|
switch (Comparison)
|
||||||
{
|
{
|
||||||
@ -94,8 +96,26 @@ public sealed class RequiredIFAttribute(
|
|||||||
case Operator.LessThanOrEqual:
|
case Operator.LessThanOrEqual:
|
||||||
case Operator.Contains:
|
case Operator.Contains:
|
||||||
case Operator.NotContains:
|
case Operator.NotContains:
|
||||||
if (targetValue is IEnumerable enumerable) return enumerable.Cast<object>().Any(item => CompareValues(item, TargetValue, Comparison));
|
// 多选字典
|
||||||
return TargetValue == null ? !IsEmpty(targetValue) : CompareValues(targetValue, TargetValue, Comparison);
|
if (dictAttr != null && targetValue is string targetString && targetString.Contains(','))
|
||||||
|
{
|
||||||
|
var values = targetString.Split(',')
|
||||||
|
.Select(v => v.Trim())
|
||||||
|
.Where(v => !string.IsNullOrEmpty(v))
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
return values.Any(value => CompareValues(value, TargetValue, Comparison));
|
||||||
|
}
|
||||||
|
// 处理其他集合情况
|
||||||
|
else if (targetValue is IEnumerable enumerable && !(targetValue is string))
|
||||||
|
{
|
||||||
|
return enumerable.Cast<object>().Any(item => CompareValues(item, TargetValue, Comparison));
|
||||||
|
}
|
||||||
|
// 单选字典
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return TargetValue == null ? !IsEmpty(targetValue) : CompareValues(targetValue, TargetValue, Comparison);
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
@ -137,9 +157,28 @@ public sealed class RequiredIFAttribute(
|
|||||||
|
|
||||||
case Operator.Contains:
|
case Operator.Contains:
|
||||||
case Operator.NotContains:
|
case Operator.NotContains:
|
||||||
if (targetValue is not IEnumerable enumerable) return false;
|
if (targetValue == null) return false;
|
||||||
bool contains = enumerable.Cast<object>().Any(item => item != null && item.Equals(sourceValue));
|
if (sourceValue == null) return comparison == Operator.NotContains;
|
||||||
return comparison == Operator.Contains ? contains : !contains;
|
|
||||||
|
// 多选字典
|
||||||
|
if (targetValue is string targetString)
|
||||||
|
{
|
||||||
|
string sourceString = sourceValue.ToString();
|
||||||
|
bool stringContains = targetString.Equals(sourceString);
|
||||||
|
return comparison == Operator.Contains ? stringContains : !stringContains;
|
||||||
|
}
|
||||||
|
// 其他集合类型处理
|
||||||
|
else if (targetValue is IEnumerable enumerable && !(targetValue is string))
|
||||||
|
{
|
||||||
|
bool contains = enumerable.OfType<object>().Any(item =>
|
||||||
|
item != null && item.Equals(sourceValue));
|
||||||
|
return comparison == Operator.Contains ? contains : !contains;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bool valuesEqual = targetValue.Equals(sourceValue);
|
||||||
|
return comparison == Operator.Contains ? valuesEqual : !valuesEqual;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio Version 18
|
# Visual Studio Version 17
|
||||||
VisualStudioVersion = 18.0.11012.119 d18.0
|
VisualStudioVersion = 17.14.36511.14 d17.14
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Admin.NET.Application", "Admin.NET.Application\Admin.NET.Application.csproj", "{C3F5AEC5-ACEE-4109-94E3-3F981DC18268}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Admin.NET.Application", "Admin.NET.Application\Admin.NET.Application.csproj", "{C3F5AEC5-ACEE-4109-94E3-3F981DC18268}"
|
||||||
EndProject
|
EndProject
|
||||||
|
|||||||
@ -26,7 +26,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="DocumentFormat.OpenXml" Version="3.3.0" />
|
<PackageReference Include="DocumentFormat.OpenXml" Version="3.3.0" />
|
||||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="4.14.0" />
|
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="4.14.0" />
|
||||||
<PackageReference Include="Rezero.Api" Version="1.8.26" />
|
<PackageReference Include="Rezero.Api" Version="1.8.27" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
"name": "admin.net.pro",
|
"name": "admin.net.pro",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "2.4.33",
|
"version": "2.4.33",
|
||||||
"lastBuildTime": "2025.09.22",
|
"lastBuildTime": "2025.09.23",
|
||||||
"description": "Admin.NET 站在巨人肩膀上的 .NET 通用权限开发框架",
|
"description": "Admin.NET 站在巨人肩膀上的 .NET 通用权限开发框架",
|
||||||
"author": "zuohuaijun",
|
"author": "zuohuaijun",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@ -93,8 +93,8 @@
|
|||||||
"@types/node": "^22.18.6",
|
"@types/node": "^22.18.6",
|
||||||
"@types/nprogress": "^0.2.3",
|
"@types/nprogress": "^0.2.3",
|
||||||
"@types/sortablejs": "^1.15.8",
|
"@types/sortablejs": "^1.15.8",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.44.0",
|
"@typescript-eslint/eslint-plugin": "^8.44.1",
|
||||||
"@typescript-eslint/parser": "^8.44.0",
|
"@typescript-eslint/parser": "^8.44.1",
|
||||||
"@vitejs/plugin-vue": "^6.0.1",
|
"@vitejs/plugin-vue": "^6.0.1",
|
||||||
"@vitejs/plugin-vue-jsx": "^5.1.1",
|
"@vitejs/plugin-vue-jsx": "^5.1.1",
|
||||||
"@vue/compiler-sfc": "^3.5.21",
|
"@vue/compiler-sfc": "^3.5.21",
|
||||||
@ -103,15 +103,15 @@
|
|||||||
"colors": "^1.4.0",
|
"colors": "^1.4.0",
|
||||||
"dotenv": "^17.2.1",
|
"dotenv": "^17.2.1",
|
||||||
"eslint": "^9.36.0",
|
"eslint": "^9.36.0",
|
||||||
"eslint-plugin-vue": "^10.4.0",
|
"eslint-plugin-vue": "^10.5.0",
|
||||||
"globals": "^16.4.0",
|
"globals": "^16.4.0",
|
||||||
"less": "^4.4.1",
|
"less": "^4.4.1",
|
||||||
"prettier": "^3.6.2",
|
"prettier": "^3.6.2",
|
||||||
"rollup-plugin-visualizer": "^6.0.3",
|
"rollup-plugin-visualizer": "^6.0.3",
|
||||||
"sass": "^1.93.0",
|
"sass": "^1.93.1",
|
||||||
"terser": "^5.44.0",
|
"terser": "^5.44.0",
|
||||||
"typescript": "^5.9.2",
|
"typescript": "^5.9.2",
|
||||||
"vite": "^7.1.6",
|
"vite": "^7.1.7",
|
||||||
"vite-auto-i18n-plugin": "^1.1.9",
|
"vite-auto-i18n-plugin": "^1.1.9",
|
||||||
"vite-plugin-cdn-import": "^1.0.1",
|
"vite-plugin-cdn-import": "^1.0.1",
|
||||||
"vite-plugin-compression2": "^2.2.1",
|
"vite-plugin-compression2": "^2.2.1",
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<!-- 下拉选择组件,支持远程搜索、分页、自定义查询表单等功能 -->
|
<!-- 下拉选择组件,支持远程搜索、分页、自定义查询表单等功能 -->
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onMounted, onUnmounted, reactive, ref, watch } from 'vue';
|
import { inject, onMounted, onUnmounted, reactive, ref, watch } from 'vue';
|
||||||
import { debounce } from 'xe-utils';
|
import { debounce } from 'xe-utils';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@ -258,7 +258,7 @@ const remoteMethod = debounce((query: any) => {
|
|||||||
state.tableData.items = [];
|
state.tableData.items = [];
|
||||||
state.tableData.total = 0;
|
state.tableData.total = 0;
|
||||||
}
|
}
|
||||||
}, 300);
|
}, 800);
|
||||||
|
|
||||||
const handleQuery = () => {
|
const handleQuery = () => {
|
||||||
remoteMethod(state.tableQuery);
|
remoteMethod(state.tableQuery);
|
||||||
@ -278,12 +278,15 @@ const handleChange = (row: any) => {
|
|||||||
// 去重
|
// 去重
|
||||||
state.selectedValues = props.multiple ? Array.from(new Set([...state.selectedValues, row[props.valueProp]])) : row[props.valueProp];
|
state.selectedValues = props.multiple ? Array.from(new Set([...state.selectedValues, row[props.valueProp]])) : row[props.valueProp];
|
||||||
|
|
||||||
// 设置表格选中效果,折叠选择器
|
// 通知父组件更新值
|
||||||
if (!props.multiple || state.selectedValues) selectRef.value?.blur();
|
|
||||||
tableRef.value?.setCurrentRow(row);
|
|
||||||
|
|
||||||
emit('update:modelValue', state.selectedValues);
|
emit('update:modelValue', state.selectedValues);
|
||||||
emit('change', state.selectedValues, row);
|
emit('change', state.selectedValues, row);
|
||||||
|
|
||||||
|
// 主动失焦,触发表单校验
|
||||||
|
selectRef.value?.blur();
|
||||||
|
|
||||||
|
// 设置表格选中效果,折叠选择器
|
||||||
|
tableRef.value?.setCurrentRow(row);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 选择器下拉框显示隐藏事件
|
// 选择器下拉框显示隐藏事件
|
||||||
@ -388,7 +391,7 @@ defineExpose({
|
|||||||
ref="tableRef"
|
ref="tableRef"
|
||||||
@row-click="handleChange"
|
@row-click="handleChange"
|
||||||
:data="state.tableData?.items ?? []"
|
:data="state.tableData?.items ?? []"
|
||||||
:height="`calc(${dropdownHeight} - 175px${$slots.queryForm ? ` - ${queryHeightOffset}px` : ''}${state.tableQuery[keywordProp] && allowCreate ? ` - ${queryHeightOffset}px` : ''})`"
|
:height="`calc(${dropdownHeight} - 175px${$slots.queryForm ? ` - ${queryHeightOffset}px` : ''}${state.tableQuery[keywordProp]})`"
|
||||||
highlight-current-row
|
highlight-current-row
|
||||||
>
|
>
|
||||||
<template #empty><el-empty :image-size="25" /></template>
|
<template #empty><el-empty :image-size="25" /></template>
|
||||||
@ -412,8 +415,7 @@ defineExpose({
|
|||||||
</div>
|
</div>
|
||||||
</el-select>
|
</el-select>
|
||||||
</template>
|
</template>
|
||||||
|
<style scoped>
|
||||||
<style scoped lang="scss">
|
|
||||||
.query-form {
|
.query-form {
|
||||||
z-index: 9999;
|
z-index: 9999;
|
||||||
}
|
}
|
||||||
@ -430,7 +432,8 @@ defineExpose({
|
|||||||
:deep(.popper-class) :deep(.el-select-dropdown__wrap) {
|
:deep(.popper-class) :deep(.el-select-dropdown__wrap) {
|
||||||
max-height: 600px !important;
|
max-height: 600px !important;
|
||||||
}
|
}
|
||||||
|
</style>
|
||||||
|
<style>
|
||||||
.popper-class .el-select-dropdown__wrap {
|
.popper-class .el-select-dropdown__wrap {
|
||||||
max-height: 450px !important;
|
max-height: 450px !important;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -589,11 +589,13 @@ watch(() => [userStore.dictList, userStore.constList, props.data, state], initDa
|
|||||||
<!-- 渲染选择器 -->
|
<!-- 渲染选择器 -->
|
||||||
<el-select v-else-if="props.renderAs === 'select'" v-model="state.value" v-bind="$attrs" :multiple="props.multiple" @change="updateValue" filterable allow-create default-first-option clearable>
|
<el-select v-else-if="props.renderAs === 'select'" v-model="state.value" v-bind="$attrs" :multiple="props.multiple" @change="updateValue" filterable allow-create default-first-option clearable>
|
||||||
<el-option v-for="(item, index) in formattedDictData" :key="index" :label="getDisplayText(item)" :value="item.value" :disabled="item.disabled" />
|
<el-option v-for="(item, index) in formattedDictData" :key="index" :label="getDisplayText(item)" :value="item.value" :disabled="item.disabled" />
|
||||||
|
<slot />
|
||||||
</el-select>
|
</el-select>
|
||||||
|
|
||||||
<!-- 多选框(多选) -->
|
<!-- 多选框(多选) -->
|
||||||
<el-checkbox-group v-else-if="props.renderAs === 'checkbox'" v-model="state.value" v-bind="$attrs" @change="updateValue">
|
<el-checkbox-group v-else-if="props.renderAs === 'checkbox'" v-model="state.value" v-bind="$attrs" @change="updateValue">
|
||||||
<el-checkbox v-for="(item, index) in formattedDictData" :key="index" :value="item.value" :label="getDisplayText(item)" :disabled="item.disabled" />
|
<el-checkbox v-for="(item, index) in formattedDictData" :key="index" :value="item.value" :label="getDisplayText(item)" :disabled="item.disabled" />
|
||||||
|
<slot />
|
||||||
</el-checkbox-group>
|
</el-checkbox-group>
|
||||||
|
|
||||||
<!-- 多选框-按钮(多选) -->
|
<!-- 多选框-按钮(多选) -->
|
||||||
@ -601,6 +603,7 @@ watch(() => [userStore.dictList, userStore.constList, props.data, state], initDa
|
|||||||
<el-checkbox-button v-for="(item, index) in formattedDictData" :key="index" :value="item.value" :disabled="item.disabled">
|
<el-checkbox-button v-for="(item, index) in formattedDictData" :key="index" :value="item.value" :disabled="item.disabled">
|
||||||
{{ getDisplayText(item) }}
|
{{ getDisplayText(item) }}
|
||||||
</el-checkbox-button>
|
</el-checkbox-button>
|
||||||
|
<slot />
|
||||||
</el-checkbox-group>
|
</el-checkbox-group>
|
||||||
|
|
||||||
<!-- 渲染单选框 -->
|
<!-- 渲染单选框 -->
|
||||||
@ -608,6 +611,7 @@ watch(() => [userStore.dictList, userStore.constList, props.data, state], initDa
|
|||||||
<el-radio v-for="(item, index) in formattedDictData" :key="index" :value="item.value">
|
<el-radio v-for="(item, index) in formattedDictData" :key="index" :value="item.value">
|
||||||
{{ getDisplayText(item) }}
|
{{ getDisplayText(item) }}
|
||||||
</el-radio>
|
</el-radio>
|
||||||
|
<slot />
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
|
|
||||||
<!-- 渲染单选框按钮 -->
|
<!-- 渲染单选框按钮 -->
|
||||||
@ -615,6 +619,7 @@ watch(() => [userStore.dictList, userStore.constList, props.data, state], initDa
|
|||||||
<el-radio-button v-for="(item, index) in formattedDictData" :key="index" :value="item.value">
|
<el-radio-button v-for="(item, index) in formattedDictData" :key="index" :value="item.value">
|
||||||
{{ getDisplayText(item) }}
|
{{ getDisplayText(item) }}
|
||||||
</el-radio-button>
|
</el-radio-button>
|
||||||
|
<slot />
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</template>
|
</template>
|
||||||
<style scoped lang="scss"></style>
|
<style scoped lang="scss"></style>
|
||||||
|
|||||||
@ -36,6 +36,7 @@
|
|||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item :span="3" label="请求头" class-name="row-line">
|
<el-descriptions-item :span="3" label="请求头" class-name="row-line">
|
||||||
<vue-json-pretty :data="data.requestHeaders" showLength showIcon showLineNumber showSelectController />
|
<vue-json-pretty :data="data.requestHeaders" showLength showIcon showLineNumber showSelectController />
|
||||||
|
<el-button @click="comFunc.copyText(JSON.stringify(data.requestHeaders))" v-if="data.requestHeaders" style="float: right" icon="ele-CopyDocument" />
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item :span="3" label="请求参数" class-name="row-line" v-if="data.requestUrl?.indexOf('?') != -1">
|
<el-descriptions-item :span="3" label="请求参数" class-name="row-line" v-if="data.requestUrl?.indexOf('?') != -1">
|
||||||
<el-row v-for="(value, key, index) in queryObject">
|
<el-row v-for="(value, key, index) in queryObject">
|
||||||
@ -44,22 +45,28 @@
|
|||||||
</el-row>
|
</el-row>
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item :span="3" label="请求体" class-name="row-line">
|
<el-descriptions-item :span="3" label="请求体" class-name="row-line">
|
||||||
<vue-json-pretty :data="data.requestBody" showLength showIcon showLineNumber showSelectController />
|
<c :data="data.requestBody" showLength showIcon showLineNumber showSelectController />
|
||||||
|
<el-button @click="comFunc.copyText(JSON.stringify(data.requestBody))" v-if="data.requestBody" style="float: right" icon="ele-CopyDocument" />
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item :span="3" label="请求明文" class-name="row-line" v-if="data.requestBodyPlaintext">
|
<el-descriptions-item :span="3" label="请求明文" class-name="row-line" v-if="data.requestBodyPlaintext">
|
||||||
<vue-json-pretty :data="data.requestBodyPlaintext" showLength showIcon showLineNumber showSelectController />
|
<vue-json-pretty :data="data.requestBodyPlaintext" showLength showIcon showLineNumber showSelectController />
|
||||||
|
<el-button @click="comFunc.copyText(JSON.stringify(data.requestBodyPlaintext))" v-if="data.requestBodyPlaintext" style="float: right" icon="ele-CopyDocument" />
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item :span="3" label="响应头" class-name="row-line">
|
<el-descriptions-item :span="3" label="响应头" class-name="row-line">
|
||||||
<vue-json-pretty :data="data.responseHeaders" showLength showIcon showLineNumber showSelectController />
|
<vue-json-pretty :data="data.responseHeaders" showLength showIcon showLineNumber showSelectController />
|
||||||
|
<el-button @click="comFunc.copyText(JSON.stringify(data.responseHeaders))" v-if="data.responseHeaders" style="float: right" icon="ele-CopyDocument" />
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item :span="3" label="响应体" class-name="row-line">
|
<el-descriptions-item :span="3" label="响应体" class-name="row-line">
|
||||||
<vue-json-pretty :data="data.responseBody" showLength showIcon showLineNumber showSelectController />
|
<vue-json-pretty :data="data.responseBody" showLength showIcon showLineNumber showSelectController />
|
||||||
|
<el-button @click="comFunc.copyText(JSON.stringify(data.responseBody))" v-if="data.responseBody" style="float: right" icon="ele-CopyDocument" />
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item :span="3" label="响应明文" class-name="row-line" v-if="data.responseBodyPlaintext">
|
<el-descriptions-item :span="3" label="响应明文" class-name="row-line" v-if="data.responseBodyPlaintext">
|
||||||
<vue-json-pretty :data="data.responseBodyPlaintext" showLength showIcon showLineNumber showSelectController />
|
<vue-json-pretty :data="data.responseBodyPlaintext" showLength showIcon showLineNumber showSelectController />
|
||||||
|
<el-button @click="comFunc.copyText(JSON.stringify(data.responseBodyPlaintext))" v-if="data.responseBodyPlaintext" style="float: right" icon="ele-CopyDocument" />
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item :span="3" label="异常信息" class-name="row-line" v-if="data.exception">
|
<el-descriptions-item :span="3" label="异常信息" class-name="row-line" v-if="data.exception">
|
||||||
<vue-json-pretty :data="data.exception" showLength showIcon showLineNumber showSelectController />
|
<vue-json-pretty :data="data.exception" showLength showIcon showLineNumber showSelectController />
|
||||||
|
<el-button @click="comFunc.copyText(JSON.stringify(data.exception))" v-if="data.exception" style="float: right" icon="ele-CopyDocument" />
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
</el-form>
|
</el-form>
|
||||||
@ -76,7 +83,9 @@ import { ref, reactive, computed } from 'vue';
|
|||||||
import { StringToObj } from '/@/utils/json-utils';
|
import { StringToObj } from '/@/utils/json-utils';
|
||||||
import { SysLogHttp } from '/@/api-services/system/models';
|
import { SysLogHttp } from '/@/api-services/system/models';
|
||||||
import VueJsonPretty from 'vue-json-pretty';
|
import VueJsonPretty from 'vue-json-pretty';
|
||||||
|
import commonFunction from '/@/utils/commonFunction';
|
||||||
|
|
||||||
|
const comFunc = commonFunction();
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
visible: false,
|
visible: false,
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user