u
This commit is contained in:
1 parent
a4e59dd5d1
commit
c7240ea7c9
16 files changed
+598
-476
No files matched your search
+2
-4
@@ -15,7 +15,6 @@ declare module 'vue' {
|
||||
ElButton: typeof import('element-plus/es')['ElButton']
|
||||
ElCard: typeof import('element-plus/es')['ElCard']
|
||||
ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
|
||||
ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider']
|
||||
ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
|
||||
ElDialog: typeof import('element-plus/es')['ElDialog']
|
||||
ElDivider: typeof import('element-plus/es')['ElDivider']
|
||||
@@ -34,8 +33,8 @@ declare module 'vue' {
|
||||
ElPopover: typeof import('element-plus/es')['ElPopover']
|
||||
ElRadio: typeof import('element-plus/es')['ElRadio']
|
||||
ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
|
||||
ElResult: typeof import('element-plus/es')['ElResult']
|
||||
ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
|
||||
ElSegmented: typeof import('element-plus/es')['ElSegmented']
|
||||
ElSelect: typeof import('element-plus/es')['ElSelect']
|
||||
ElSplitter: typeof import('element-plus/es')['ElSplitter']
|
||||
ElSplitterPanel: typeof import('element-plus/es')['ElSplitterPanel']
|
||||
@@ -43,13 +42,12 @@ declare module 'vue' {
|
||||
ElSwitch: typeof import('element-plus/es')['ElSwitch']
|
||||
ElTable: typeof import('element-plus/es')['ElTable']
|
||||
ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
|
||||
ElTabPane: typeof import('element-plus/es')['ElTabPane']
|
||||
ElTabs: typeof import('element-plus/es')['ElTabs']
|
||||
ElText: typeof import('element-plus/es')['ElText']
|
||||
ElTooltip: typeof import('element-plus/es')['ElTooltip']
|
||||
ElTree: typeof import('element-plus/es')['ElTree']
|
||||
G3Column: typeof import('./src/components/g3-table/g3-column.vue')['default']
|
||||
G3Detail: typeof import('./src/components/g3-detail/index.vue')['default']
|
||||
G3Error: typeof import('./src/components/g3-error/index.vue')['default']
|
||||
G3File: typeof import('./src/components/g3-file/index.vue')['default']
|
||||
G3Grid: typeof import('./src/components/g3-grid/g3-grid.vue')['default']
|
||||
G3GridGroup: typeof import('./src/components/g3-grid/g3-grid-group.vue')['default']
|
||||
|
||||
@@ -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(() => {
|
||||
|
||||
@@ -48,9 +48,9 @@ function onFullScreenChange(val) {
|
||||
<el-splitter-panel>
|
||||
<div class="g3-layout-right">
|
||||
<Topbar
|
||||
v-if="!fullScreen"
|
||||
:collapse="isCollapse"
|
||||
@collapse="handleCollapse"
|
||||
:style="fullScreen ? { height: '0', border: 'none' } : {}"
|
||||
/>
|
||||
<Tab @full-screen-change="onFullScreenChange" />
|
||||
<Content />
|
||||
|
||||
@@ -30,3 +30,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.el-message {
|
||||
z-index: 99999 !important;
|
||||
}
|
||||
@@ -56,7 +56,9 @@ const viewName = "v_container";
|
||||
const showPreview = ref(false);
|
||||
const previewIndex = ref(-1);
|
||||
const previewImageList = computed(() => {
|
||||
return tableData.value.map((item) => item.b_container_img).filter((img) => img);
|
||||
return tableData.value
|
||||
.map((item) => item.b_container_img)
|
||||
.filter((img) => img);
|
||||
});
|
||||
|
||||
const currentRow = ref({});
|
||||
@@ -189,9 +191,12 @@ async function deleteRows(rows = []) {
|
||||
const safeDeleteIds = deleteIds.map((id) => Number(id));
|
||||
|
||||
// 使用安全的 SQL 查询
|
||||
const fileRes = await loadDataApi("bf_file", `father IN (${safeDeleteIds.join(",")})`, "", [
|
||||
"subid",
|
||||
]);
|
||||
const fileRes = await loadDataApi(
|
||||
"bf_file",
|
||||
`father IN (${safeDeleteIds.join(",")})`,
|
||||
"",
|
||||
["subid"],
|
||||
);
|
||||
|
||||
if (!fileRes.success) {
|
||||
return;
|
||||
@@ -267,7 +272,11 @@ async function handleDownloadOne(data) {
|
||||
});
|
||||
|
||||
try {
|
||||
const fileRes = await loadDataApi("bf_file", `father = ${data.b_id}`, "mx_xh asc");
|
||||
const fileRes = await loadDataApi(
|
||||
"bf_file",
|
||||
`father = ${data.b_id}`,
|
||||
"mx_xh asc",
|
||||
);
|
||||
|
||||
if (!fileRes.success) {
|
||||
ElMessage.error("获取附件失败");
|
||||
@@ -275,7 +284,11 @@ async function handleDownloadOne(data) {
|
||||
}
|
||||
|
||||
const downloadFiles = fileRes.data.map((item, index) => ({
|
||||
mx_filename: buildFileName(data.b_container_no, index + 1, item.mx_filename),
|
||||
mx_filename: buildFileName(
|
||||
data.b_container_no,
|
||||
index + 1,
|
||||
item.mx_filename,
|
||||
),
|
||||
mx_mapfilename: item.mx_mapfilename,
|
||||
}));
|
||||
|
||||
@@ -338,7 +351,11 @@ async function handleDownloadBatch() {
|
||||
|
||||
// 👉 先统计总文件数(用于进度)
|
||||
for (const item of records) {
|
||||
const fileRes = await loadDataApi("bf_file", `father = '${item.b_id}'`, "");
|
||||
const fileRes = await loadDataApi(
|
||||
"bf_file",
|
||||
`father = '${item.b_id}'`,
|
||||
"",
|
||||
);
|
||||
if (fileRes.success) {
|
||||
total += (fileRes.data || []).length;
|
||||
}
|
||||
@@ -350,7 +367,11 @@ async function handleDownloadBatch() {
|
||||
|
||||
const folder = zip.folder(folderName);
|
||||
|
||||
const fileRes = await loadDataApi("bf_file", `father = '${item.b_id}'`, "mx_xh asc");
|
||||
const fileRes = await loadDataApi(
|
||||
"bf_file",
|
||||
`father = '${item.b_id}'`,
|
||||
"mx_xh asc",
|
||||
);
|
||||
|
||||
if (!fileRes.success) {
|
||||
ElMessage.error("获取附件失败");
|
||||
@@ -367,7 +388,8 @@ async function handleDownloadBatch() {
|
||||
const blob = await res.blob();
|
||||
|
||||
const fileName =
|
||||
buildFileName(item.b_container_no, index + 1, file.mx_filename) || "未命名文件";
|
||||
buildFileName(item.b_container_no, index + 1, file.mx_filename) ||
|
||||
"未命名文件";
|
||||
|
||||
folder.file(fileName, blob);
|
||||
} catch (e) {
|
||||
@@ -432,7 +454,15 @@ function buildFileName(containerNo, index, fileName) {
|
||||
</G3GridItem>
|
||||
|
||||
<G3GridItem label="操作员">
|
||||
<el-input v-model="searchForm.username" />
|
||||
<G3Select
|
||||
v-model="searchForm.username"
|
||||
v-model:label="searchForm.username"
|
||||
search-condition="b_id <> 'g3soft'"
|
||||
view-name="b_user"
|
||||
value-key="b_name"
|
||||
label-key="b_name"
|
||||
keep-input
|
||||
/>
|
||||
</G3GridItem>
|
||||
</G3GridGroup>
|
||||
</G3Grid>
|
||||
@@ -470,7 +500,7 @@ function buildFileName(containerNo, index, fileName) {
|
||||
<el-button
|
||||
type="danger"
|
||||
@click="handleDeleteRows"
|
||||
:disabled="!permissionStore.hasActionPermission(2)"
|
||||
:disabled="!permissionStore.hasActionPermission(2)"
|
||||
>
|
||||
<el-icon class="el-icon--left">
|
||||
<G3Icon icon="lucide:trash-2" />
|
||||
@@ -534,7 +564,14 @@ function buildFileName(containerNo, index, fileName) {
|
||||
}"
|
||||
height="100%"
|
||||
>
|
||||
<vxe-column field="seq" type="seq" width="50" align="center" title=" " fixed="left" />
|
||||
<vxe-column
|
||||
field="seq"
|
||||
type="seq"
|
||||
width="50"
|
||||
align="center"
|
||||
title=" "
|
||||
fixed="left"
|
||||
/>
|
||||
<vxe-column type="checkbox" width="50" align="center" fixed="left" />
|
||||
<vxe-column
|
||||
v-for="column in columns"
|
||||
@@ -555,7 +592,12 @@ function buildFileName(containerNo, index, fileName) {
|
||||
/>
|
||||
</template>
|
||||
<template v-else>
|
||||
{{ formatValueByFormat(row[column.col_FieldName], column.col_DisplayFormat) }}
|
||||
{{
|
||||
formatValueByFormat(
|
||||
row[column.col_FieldName],
|
||||
column.col_DisplayFormat,
|
||||
)
|
||||
}}
|
||||
</template>
|
||||
</template>
|
||||
</vxe-column>
|
||||
|
||||
@@ -9,7 +9,11 @@ const dialogData = ref({});
|
||||
const showFile = ref(false);
|
||||
|
||||
onMounted(async () => {
|
||||
const loadRes = await loadDataApi("oa_notices", ` b_visible='1'`, "b_inputdate desc");
|
||||
const loadRes = await loadDataApi(
|
||||
"v_oa_notices",
|
||||
` b_visible='1'`,
|
||||
"b_inputdatetime desc",
|
||||
);
|
||||
|
||||
if (loadRes.success) {
|
||||
dataList.value = loadRes.data;
|
||||
@@ -31,10 +35,18 @@ function handleShowDialog(data) {
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<div v-for="item in dataList" class="notice-item" @click="handleShowDialog(item)">
|
||||
<div
|
||||
v-if="dataList.length > 0"
|
||||
v-for="item in dataList"
|
||||
class="notice-item"
|
||||
@click="handleShowDialog(item)"
|
||||
>
|
||||
{{ item.b_subject }}
|
||||
</div>
|
||||
|
||||
<el-result v-else icon="primary" title="空空如也" sub-title="快去发布公告吧">
|
||||
</el-result>
|
||||
|
||||
<el-dialog v-model="showDialog" :title="dialogData.b_subject" :width="800">
|
||||
<div class="section">
|
||||
<div class="section-title">发布人</div>
|
||||
@@ -45,7 +57,11 @@ function handleShowDialog(data) {
|
||||
<div class="section">
|
||||
<div class="section-title">发布时间</div>
|
||||
<div class="section-value">
|
||||
{{ formatToDateTime(dialogData.b_updatedatetime || dialogData.b_inputdatetime) }}
|
||||
{{
|
||||
formatToDateTime(
|
||||
dialogData.b_updatedatetime || dialogData.b_inputdatetime,
|
||||
)
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
@@ -69,7 +85,12 @@ function handleShowDialog(data) {
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<G3File v-model="showFile" :father="dialogData.b_id" module-id="oa_notices" readonly />
|
||||
<G3File
|
||||
v-model="showFile"
|
||||
:father="dialogData.b_id"
|
||||
module-id="oa_notices"
|
||||
readonly
|
||||
/>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
<script setup lang="js">
|
||||
import { saveAs } from "file-saver";
|
||||
import JSZip from "jszip";
|
||||
|
||||
// 假设这些是文件数据和它们的路径
|
||||
const files = [
|
||||
{ name: "file1.txt", folder: "folder1", content: "This is file 1 content" },
|
||||
{ name: "file2.txt", folder: "folder2", content: "This is file 2 content" },
|
||||
{ name: "file3.txt", folder: "folder1", content: "This is file 3 content" },
|
||||
{ name: "file4.txt", folder: "folder3", content: "This is file 4 content" },
|
||||
];
|
||||
|
||||
async function createZip() {
|
||||
const zip = new JSZip();
|
||||
|
||||
// 遍历文件列表,将文件按文件夹添加到 ZIP 文件中
|
||||
files.forEach((file) => {
|
||||
// 创建文件夹并将文件添加到对应的文件夹下
|
||||
zip.folder(file.folder).file(file.name, file.content);
|
||||
});
|
||||
|
||||
// 生成并下载 ZIP 文件
|
||||
const content = await zip.generateAsync({ type: "blob" });
|
||||
saveAs(content, "files.zip");
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-button @click="createZip">测试</el-button>
|
||||
</template>
|
||||
@@ -2,7 +2,12 @@
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import EditDrawer from "./edit-drawer.vue";
|
||||
import CategoryDialog from "./category-dialog.vue";
|
||||
import { loadDataBySqlApi, saveObjectApi } from "@/request/api";
|
||||
import {
|
||||
loadDataApi,
|
||||
loadDataBySqlApi,
|
||||
loadPageDataApi,
|
||||
saveObjectApi,
|
||||
} from "@/request/api";
|
||||
|
||||
const tableRef = ref(null);
|
||||
|
||||
@@ -15,7 +20,7 @@ const columnData = ref([
|
||||
{ prop: "v_inputuser_name", label: "发布人", width: 120 },
|
||||
{ prop: "b_inputdate", label: "发布日期", width: 140 },
|
||||
]);
|
||||
const treeId = ref("");
|
||||
const treeId = ref(-1);
|
||||
const tableData = ref([]);
|
||||
const loading = reactive({
|
||||
table: false,
|
||||
@@ -24,12 +29,27 @@ const loading = reactive({
|
||||
error: "",
|
||||
});
|
||||
|
||||
const searchForm = ref({
|
||||
username: "",
|
||||
subject: "",
|
||||
});
|
||||
|
||||
const pagination = reactive({
|
||||
page: 0,
|
||||
size: 20,
|
||||
total: 0,
|
||||
});
|
||||
|
||||
const defaultProps = {
|
||||
children: "children",
|
||||
label: "label",
|
||||
isLeaf: "leaf",
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
loadTableDatas();
|
||||
});
|
||||
|
||||
async function handleNodeClick(node) {
|
||||
if (!node.id) {
|
||||
return;
|
||||
@@ -122,7 +142,8 @@ async function handleEditRow(row) {
|
||||
|
||||
function handleEditChange() {
|
||||
drawerVisible.value = false;
|
||||
loadNodeData(treeId.value, "10");
|
||||
// loadNodeData(treeId.value, "10");
|
||||
loadTableDatas();
|
||||
}
|
||||
|
||||
function handleEditClosed() {
|
||||
@@ -130,6 +151,58 @@ function handleEditClosed() {
|
||||
}
|
||||
// -----------------------------------
|
||||
|
||||
function loadTableDatas() {
|
||||
loading.table = true;
|
||||
|
||||
let searchCondition = "";
|
||||
|
||||
if (searchForm.value.subject) {
|
||||
searchCondition += `b_subject LIKE '%${searchForm.value.subject}%' AND `;
|
||||
}
|
||||
|
||||
if (searchForm.value.username) {
|
||||
searchCondition += `v_inputuser_name LIKE '%${searchForm.value.username}%' AND `;
|
||||
}
|
||||
|
||||
if (searchCondition.endsWith(" AND ")) {
|
||||
searchCondition = searchCondition.slice(0, -4);
|
||||
}
|
||||
|
||||
loadPageDataApi({
|
||||
viewName: "v_oa_notices",
|
||||
page: pagination.page,
|
||||
size: pagination.size,
|
||||
orderField: "b_updatedatetime desc",
|
||||
searchCondition,
|
||||
})
|
||||
.then((res) => {
|
||||
if (res.success) {
|
||||
tableData.value = res.data.rows;
|
||||
pagination.total = res.data.total;
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
loading.table = false;
|
||||
});
|
||||
}
|
||||
|
||||
const handleSizeChange = (val) => {
|
||||
pagination.size = val;
|
||||
|
||||
loadTableDatas();
|
||||
};
|
||||
const handleCurrentChange = (val) => {
|
||||
pagination.page = val;
|
||||
|
||||
loadTableDatas();
|
||||
};
|
||||
|
||||
function handleSearch() {
|
||||
pagination.page = 1;
|
||||
|
||||
loadTableDatas();
|
||||
}
|
||||
|
||||
// 删除单行
|
||||
async function handleDeleteRow(row) {
|
||||
if (!row) return;
|
||||
@@ -182,7 +255,8 @@ async function deleteRows(rows = []) {
|
||||
if (res.success) {
|
||||
ElMessage.success("删除成功");
|
||||
|
||||
loadNodeData(treeId.value, "10");
|
||||
// loadNodeData(treeId.value, "10");
|
||||
loadTableDatas()
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -190,16 +264,16 @@ async function deleteRows(rows = []) {
|
||||
|
||||
<template>
|
||||
<div class="g3-flex-container">
|
||||
<div class="g3-header">
|
||||
<!-- <div class="g3-header">
|
||||
<el-button type="primary" @click="showCategory = true">
|
||||
<el-icon class="el-icon--left">
|
||||
<G3Icon icon="lucide:settings" />
|
||||
</el-icon>
|
||||
分类设置
|
||||
</el-button>
|
||||
</div>
|
||||
</div> -->
|
||||
<div class="g3-container">
|
||||
<el-splitter>
|
||||
<!-- <el-splitter>
|
||||
<el-splitter-panel size="220">
|
||||
<div class="g3-container-left">
|
||||
<div class="g3-title">
|
||||
@@ -217,104 +291,150 @@ async function deleteRows(rows = []) {
|
||||
@node-click="handleNodeClick"
|
||||
/>
|
||||
</div>
|
||||
</el-splitter-panel>
|
||||
</el-splitter-panel> -->
|
||||
|
||||
<el-splitter-panel>
|
||||
<div class="g3-container-right">
|
||||
<div style="width: 100%">
|
||||
<div style="display: flex; height: 32px; margin-bottom: 8px">
|
||||
<el-button type="primary" @click="handleAdd">
|
||||
<el-icon class="el-icon--left">
|
||||
<G3Icon icon="lucide:plus" />
|
||||
</el-icon>
|
||||
新增
|
||||
</el-button>
|
||||
<el-button type="danger" @click="handleDeleteRows">
|
||||
<el-icon class="el-icon--left">
|
||||
<G3Icon icon="lucide:trash-2" />
|
||||
</el-icon>
|
||||
批量删除
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="g3-table">
|
||||
<vxe-table
|
||||
ref="tableRef"
|
||||
border
|
||||
stripe
|
||||
header-align="center"
|
||||
:data="tableData"
|
||||
:sort-config="{
|
||||
// showIcon: false,
|
||||
trigger: 'cell',
|
||||
}"
|
||||
:filter-config="{
|
||||
showIcon: false,
|
||||
}"
|
||||
:column-drag-config="{
|
||||
showIcon: false,
|
||||
trigger: 'cell',
|
||||
}"
|
||||
:row-config="{
|
||||
useKey: true,
|
||||
keyField: 'b_id',
|
||||
isCurrent: true,
|
||||
isHover: true,
|
||||
}"
|
||||
:column-config="{
|
||||
resizable: true,
|
||||
drag: true,
|
||||
}"
|
||||
show-overflow
|
||||
show-header-overflow
|
||||
height="100%"
|
||||
>
|
||||
<vxe-column type="checkbox" width="50" align="center" />
|
||||
<vxe-column
|
||||
v-for="column in columnData"
|
||||
:key="column.prop"
|
||||
:field="column.prop"
|
||||
:title="column.label"
|
||||
:width="column.width"
|
||||
sortable
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<template v-if="['b_visible'].includes(column.prop)">
|
||||
<el-checkbox
|
||||
v-model="row[column.prop]"
|
||||
disabled
|
||||
true-value="1"
|
||||
false-value="0"
|
||||
@change="handleCheckChange(row, column.prop)"
|
||||
/>
|
||||
</template>
|
||||
<template v-else>
|
||||
{{ row[column.prop] }}
|
||||
</template>
|
||||
</template>
|
||||
</vxe-column>
|
||||
|
||||
<vxe-column
|
||||
width="200"
|
||||
align="center"
|
||||
fixed="right"
|
||||
title="操作"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<el-button type="primary" link @click="handleEditRow(row)">
|
||||
编辑
|
||||
</el-button>
|
||||
|
||||
<el-button type="danger" link @click="handleDeleteRow(row)">
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</vxe-column>
|
||||
</vxe-table>
|
||||
</div>
|
||||
<!-- <el-splitter-panel> -->
|
||||
<div class="g3-container-right">
|
||||
<div
|
||||
style="
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 8px;
|
||||
"
|
||||
>
|
||||
<div style="display: flex">
|
||||
<el-button type="primary" @click="handleAdd">
|
||||
<el-icon class="el-icon--left">
|
||||
<G3Icon icon="lucide:plus" />
|
||||
</el-icon>
|
||||
新增
|
||||
</el-button>
|
||||
<el-button type="danger" @click="handleDeleteRows">
|
||||
<el-icon class="el-icon--left">
|
||||
<G3Icon icon="lucide:trash-2" />
|
||||
</el-icon>
|
||||
批量删除
|
||||
</el-button>
|
||||
</div>
|
||||
</el-splitter-panel>
|
||||
</el-splitter>
|
||||
|
||||
<div style="display: flex; align-items: center">
|
||||
<G3Grid style="width: 400px">
|
||||
<G3GridGroup :label-width="60" :column="2">
|
||||
<G3GridItem label="主题">
|
||||
<el-input v-model="searchForm.subject" />
|
||||
</G3GridItem>
|
||||
<G3GridItem label="发布人">
|
||||
<G3Select
|
||||
v-model="searchForm.username"
|
||||
v-model:label="searchForm.username"
|
||||
search-condition="b_id <> 'g3soft'"
|
||||
view-name="b_user"
|
||||
value-key="b_name"
|
||||
label-key="b_name"
|
||||
keep-input
|
||||
/>
|
||||
</G3GridItem>
|
||||
</G3GridGroup>
|
||||
</G3Grid>
|
||||
<el-button
|
||||
type="primary"
|
||||
style="margin-left: 8px"
|
||||
@click="handleSearch"
|
||||
>
|
||||
<el-icon class="el-icon--left">
|
||||
<G3Icon icon="lucide:search" />
|
||||
</el-icon>
|
||||
搜索
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="g3-table">
|
||||
<vxe-table
|
||||
ref="tableRef"
|
||||
border
|
||||
stripe
|
||||
header-align="center"
|
||||
:data="tableData"
|
||||
:sort-config="{
|
||||
// showIcon: false,
|
||||
trigger: 'cell',
|
||||
}"
|
||||
:filter-config="{
|
||||
showIcon: false,
|
||||
}"
|
||||
:column-drag-config="{
|
||||
showIcon: false,
|
||||
trigger: 'cell',
|
||||
}"
|
||||
:row-config="{
|
||||
useKey: true,
|
||||
keyField: 'b_id',
|
||||
isCurrent: true,
|
||||
isHover: true,
|
||||
}"
|
||||
:column-config="{
|
||||
resizable: true,
|
||||
drag: true,
|
||||
}"
|
||||
show-overflow
|
||||
show-header-overflow
|
||||
height="100%"
|
||||
>
|
||||
<vxe-column type="checkbox" width="50" align="center" />
|
||||
<vxe-column
|
||||
v-for="column in columnData"
|
||||
:key="column.prop"
|
||||
:field="column.prop"
|
||||
:title="column.label"
|
||||
:width="column.width"
|
||||
sortable
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<template v-if="['b_visible'].includes(column.prop)">
|
||||
<el-checkbox
|
||||
v-model="row[column.prop]"
|
||||
disabled
|
||||
true-value="1"
|
||||
false-value="0"
|
||||
@change="handleCheckChange(row, column.prop)"
|
||||
/>
|
||||
</template>
|
||||
<template v-else>
|
||||
{{ row[column.prop] }}
|
||||
</template>
|
||||
</template>
|
||||
</vxe-column>
|
||||
|
||||
<vxe-column width="200" align="center" fixed="right" title="操作">
|
||||
<template #default="{ row }">
|
||||
<el-button type="primary" link @click="handleEditRow(row)">
|
||||
编辑
|
||||
</el-button>
|
||||
|
||||
<el-button type="danger" link @click="handleDeleteRow(row)">
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</vxe-column>
|
||||
</vxe-table>
|
||||
</div>
|
||||
|
||||
<div class="g3-pagination">
|
||||
<el-pagination
|
||||
v-model:current-page="pagination.page"
|
||||
v-model:page-size="pagination.size"
|
||||
:page-sizes="[20, 50, 100, 200]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="pagination.total"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- </el-splitter-panel> -->
|
||||
<!-- </el-splitter> -->
|
||||
</div>
|
||||
|
||||
<EditDrawer
|
||||
@@ -390,6 +510,15 @@ async function deleteRows(rows = []) {
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.g3-pagination {
|
||||
margin-top: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
flex-shrink: 0;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.g3-footer {
|
||||
padding-top: 8px;
|
||||
display: flex;
|
||||
|
||||
Reference in new issue
Block a user