u
This commit is contained in:
1 parent
a4e59dd5d1
commit
c7240ea7c9
16 files changed
+598
-476
No files matched your search
@@ -1,15 +1,33 @@
|
||||
import ErrorModal from "./index.vue";
|
||||
|
||||
let isShowingErrorModal = false;
|
||||
let currentApp = null;
|
||||
|
||||
export const ErrorModalService = {
|
||||
show(responseData) {
|
||||
if (isShowingErrorModal && currentApp) {
|
||||
currentApp._instance.props.responseData = responseData;
|
||||
return;
|
||||
}
|
||||
|
||||
isShowingErrorModal = true;
|
||||
|
||||
const container = document.createElement("div");
|
||||
document.body.appendChild(container);
|
||||
|
||||
const app = createApp({
|
||||
data() {
|
||||
return {
|
||||
data: responseData,
|
||||
};
|
||||
},
|
||||
render() {
|
||||
return h(ErrorModal, {
|
||||
responseData: responseData,
|
||||
responseData: this.data,
|
||||
onClose: () => {
|
||||
isShowingErrorModal = false;
|
||||
currentApp = null;
|
||||
|
||||
app.unmount();
|
||||
document.body.removeChild(container);
|
||||
},
|
||||
@@ -17,6 +35,7 @@ export const ErrorModalService = {
|
||||
},
|
||||
});
|
||||
|
||||
currentApp = app;
|
||||
app.mount(container);
|
||||
},
|
||||
};
|
||||
@@ -2,11 +2,13 @@
|
||||
<div class="error-modal-wrapper" @click.self="handleClose">
|
||||
<div v-if="visible" class="error-modal" @click.stop>
|
||||
<div class="error-modal-header">
|
||||
<span class="error-modal-title"
|
||||
>⚠️ 系统异常提示 - {{ props.responseData.message }} -
|
||||
{{ props.responseData.code || 500 }}</span
|
||||
<span class="error-modal-title">⚠️ 系统异常提示 </span>
|
||||
<div
|
||||
class="error-modal-close-btn"
|
||||
@click="handleClose"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<div class="error-modal-close-btn" @click="handleClose" role="button" tabindex="0">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
@@ -25,9 +27,12 @@
|
||||
<div class="log-item" v-for="item in logList" :key="item.label">
|
||||
<div class="log-label">{{ item.label }}</div>
|
||||
<div class="log-value">
|
||||
<pre v-if="item.label === '堆栈跟踪' || item.label === '请求参数'" class="code-block">{{
|
||||
item.value
|
||||
}}</pre>
|
||||
<pre
|
||||
v-if="item.label === '堆栈跟踪' || item.label === '请求参数'"
|
||||
class="code-block"
|
||||
>
|
||||
{{ item.value }}
|
||||
</pre>
|
||||
<div v-else>{{ item.value }}</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -48,10 +53,21 @@
|
||||
<line x1="12" y1="16" x2="12" y2="12" />
|
||||
<line x1="12" y1="8" x2="12.01" y2="8" />
|
||||
</svg>
|
||||
<span>请将错误信息 导出 或 复制 发送给管理员!</span>
|
||||
<span style="margin-left: 4px">
|
||||
请将错误信息
|
||||
<span class="highlight" @click="exportAsTxt">导出</span>
|
||||
或
|
||||
<span class="highlight" @click="copyInfo">复制</span>
|
||||
发送给管理员!
|
||||
</span>
|
||||
</div>
|
||||
<div class="error-modal-actions">
|
||||
<div class="btn txt-btn" role="button" tabindex="0" @click="exportAsTxt">
|
||||
<div
|
||||
class="btn txt-btn"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
@click="exportAsTxt"
|
||||
>
|
||||
<svg
|
||||
class="btn-icon"
|
||||
viewBox="0 0 24 24"
|
||||
@@ -61,14 +77,21 @@
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8l-6-6z" />
|
||||
<path
|
||||
d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8l-6-6z"
|
||||
/>
|
||||
<path d="M14 2v6h6m-9 4H9m3 3H9m6-9h-1" />
|
||||
<path d="M12 18v-6m2 3h-4" />
|
||||
</svg>
|
||||
<span>导出TXT</span>
|
||||
</div>
|
||||
|
||||
<div class="btn data-btn" role="button" tabindex="0" @click="copyInfo">
|
||||
<div
|
||||
class="btn data-btn"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
@click="copyInfo"
|
||||
>
|
||||
<svg
|
||||
class="btn-icon"
|
||||
viewBox="0 0 24 24"
|
||||
@@ -79,12 +102,19 @@
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<rect x="9" y="9" width="13" height="13" rx="2" />
|
||||
<path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" />
|
||||
<path
|
||||
d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"
|
||||
/>
|
||||
</svg>
|
||||
<span>复制信息</span>
|
||||
</div>
|
||||
|
||||
<div class="btn cancel-btn" role="button" tabindex="0" @click="handleClose">
|
||||
<div
|
||||
class="btn cancel-btn"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
@click="handleClose"
|
||||
>
|
||||
<svg
|
||||
class="btn-icon"
|
||||
viewBox="0 0 24 24"
|
||||
@@ -157,7 +187,9 @@ function handleClose() {
|
||||
}
|
||||
|
||||
function exportAsTxt() {
|
||||
const content = logList.value.map((item) => `${item.label}:\n${item.value}\n`).join("\n");
|
||||
const content = logList.value
|
||||
.map((item) => `${item.label}:\n${item.value}\n`)
|
||||
.join("\n");
|
||||
const blob = new Blob([content], { type: "text/plain;charset=utf-8" });
|
||||
const url = URL.createObjectURL(blob);
|
||||
|
||||
@@ -177,6 +209,8 @@ function copyInfo() {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@use "@/styles/mixins.scss" as *;
|
||||
|
||||
@keyframes modalFadeIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
@@ -263,7 +297,6 @@ function copyInfo() {
|
||||
.log-item {
|
||||
display: grid;
|
||||
grid-template-columns: 120px 1fr;
|
||||
gap: 16px;
|
||||
padding: 14px 0;
|
||||
border-bottom: 1px solid #d9d9d9;
|
||||
&:last-child {
|
||||
@@ -274,6 +307,7 @@ function copyInfo() {
|
||||
font-weight: 600;
|
||||
text-align: right;
|
||||
opacity: 0.9;
|
||||
margin-right: 16px;
|
||||
}
|
||||
.log-value {
|
||||
word-break: break-all;
|
||||
@@ -302,12 +336,23 @@ function copyInfo() {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: #ff7d00;
|
||||
gap: 8px;
|
||||
font-size: 16px;
|
||||
font-size: 14px;
|
||||
background: #fff7e6;
|
||||
padding: 8px 12px;
|
||||
border-radius: 6px;
|
||||
|
||||
.highlight {
|
||||
color: #fff;
|
||||
background: #ff7d00;
|
||||
padding: 2px 12px;
|
||||
border-radius: 4px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
.error-modal-actions {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
@include flexGapRow(12px);
|
||||
margin-left: auto;
|
||||
|
||||
.btn {
|
||||
|
||||
@@ -17,6 +17,10 @@ const props = defineProps({
|
||||
searchColumns: { type: Array, default: () => [] },
|
||||
orderField: { type: String, default: "" },
|
||||
sql: { type: String, default: "" },
|
||||
keepInput: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
|
||||
// ===============================
|
||||
@@ -42,12 +46,9 @@ const inputChange = ref(false); // 输入变化标记
|
||||
const pagination = reactive({ page: 1, size: 10, total: 0 }); // 分页
|
||||
|
||||
const popperPaneRef = computed(() => popoverRef.value?.popperRef?.contentRef); // Popover 内容 DOM
|
||||
const searchColumns = computed(() => [
|
||||
props.labelKey,
|
||||
props.valueKey,
|
||||
...props.searchColumns,
|
||||
]); // 搜索列
|
||||
|
||||
const searchColumns = computed(() => {
|
||||
return [...new Set([props.labelKey, props.valueKey, ...props.searchColumns])];
|
||||
});
|
||||
// ===============================
|
||||
// Watchers
|
||||
// ===============================
|
||||
@@ -76,14 +77,19 @@ function onPopoverAfterLeave() {
|
||||
|
||||
function onPopoverBeforeLeave() {
|
||||
// 弹窗关闭前恢复或清空状态
|
||||
if (props.label) {
|
||||
if (innerInput.value === "") {
|
||||
emits("update:label", "");
|
||||
emits("update:modelValue", "");
|
||||
emits("change", null);
|
||||
} else {
|
||||
innerInput.value = props.label;
|
||||
if (!props.keepInput) {
|
||||
if (props.label) {
|
||||
if (innerInput.value === "") {
|
||||
emits("update:label", "");
|
||||
emits("update:modelValue", "");
|
||||
emits("change", null);
|
||||
} else {
|
||||
innerInput.value = props.label;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
emits("update:label", innerInput.value);
|
||||
emits("update:modelValue", innerInput.value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,7 +205,7 @@ function _fetchOptions(searchTitle) {
|
||||
: [...options.value, ...res.data.rows];
|
||||
pagination.total = res.data.total;
|
||||
|
||||
popoverVisible.value = true
|
||||
popoverVisible.value = true;
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
|
||||
Reference in new issue
Block a user