u
This commit is contained in:
1 parent
401a6719f6
commit
b7f50f3ccb
22 files changed
+1595
-343
No files matched your search
@@ -0,0 +1,508 @@
|
||||
<script lang="js" setup>
|
||||
import {
|
||||
deleteFileApi,
|
||||
loadDataApi,
|
||||
loadPageDataApi,
|
||||
loadViewColumnsApi,
|
||||
saveObjectApi,
|
||||
} from "@/request/api";
|
||||
import { getAlignByFormat, formatValueByFormat } from "@/utils/columns";
|
||||
import { updateViewTableColumns } from "@/utils/columns";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
const tableRef = ref();
|
||||
|
||||
const columns = ref([]);
|
||||
const tableData = ref([]);
|
||||
|
||||
const showSearch = ref(true);
|
||||
const loading = reactive({
|
||||
table: true,
|
||||
});
|
||||
|
||||
const searchForm = ref({
|
||||
startTime: "",
|
||||
endTime: "",
|
||||
containerNo: "",
|
||||
username: "",
|
||||
});
|
||||
|
||||
const pagination = reactive({
|
||||
page: 1,
|
||||
size: 20,
|
||||
total: 0,
|
||||
});
|
||||
|
||||
const fileCategories = [
|
||||
{
|
||||
label: "集装箱号",
|
||||
cateId: "0",
|
||||
},
|
||||
{
|
||||
label: "其它照片",
|
||||
cateId: "1",
|
||||
},
|
||||
];
|
||||
|
||||
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);
|
||||
});
|
||||
|
||||
const currentRow = ref({});
|
||||
const showFile = ref(false);
|
||||
|
||||
onMounted(async () => {
|
||||
loading.table = true;
|
||||
|
||||
await loadTableColumns();
|
||||
await loadTableDatas();
|
||||
|
||||
loading.table = false;
|
||||
});
|
||||
|
||||
const handleSizeChange = (val) => {
|
||||
pagination.size = val;
|
||||
|
||||
loadTableDatas();
|
||||
};
|
||||
const handleCurrentChange = (val) => {
|
||||
pagination.page = val;
|
||||
|
||||
loadTableDatas();
|
||||
};
|
||||
|
||||
async function loadTableColumns() {
|
||||
const columnRes = await loadViewColumnsApi(viewName);
|
||||
|
||||
if (columnRes.success) {
|
||||
columns.value = columnRes.data;
|
||||
}
|
||||
}
|
||||
|
||||
async function loadTableDatas() {
|
||||
loading.table = true;
|
||||
|
||||
let searchCondition = "";
|
||||
|
||||
if (searchForm.value.startTime) {
|
||||
searchCondition += `b_inputdatetime >= '${searchForm.value.startTime}' AND `;
|
||||
}
|
||||
|
||||
if (searchForm.value.endTime) {
|
||||
searchCondition += `b_inputdatetime <= '${searchForm.value.endTime}' AND `;
|
||||
}
|
||||
|
||||
if (searchForm.value.containerNo) {
|
||||
searchCondition += `b_container_no LIKE '%${searchForm.value.containerNo}%' AND `;
|
||||
}
|
||||
|
||||
if (searchForm.value.username) {
|
||||
searchCondition += `v_username LIKE '%${searchForm.value.username}%' AND `;
|
||||
}
|
||||
|
||||
if (searchCondition.endsWith(" AND ")) {
|
||||
searchCondition = searchCondition.slice(0, -4);
|
||||
}
|
||||
|
||||
await loadPageDataApi({
|
||||
viewName,
|
||||
page: pagination.page,
|
||||
size: pagination.size,
|
||||
searchCondition,
|
||||
orderField: "b_inputdatetime DESC",
|
||||
}).then((res) => {
|
||||
if (res.success) {
|
||||
tableData.value = res.data.rows;
|
||||
pagination.total = res.data.total;
|
||||
|
||||
loading.table = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 删除单行
|
||||
async function handleDeleteRow(row) {
|
||||
if (!row) return;
|
||||
const $table = tableRef.value;
|
||||
|
||||
if ($table) {
|
||||
deleteRows([row]);
|
||||
}
|
||||
}
|
||||
|
||||
// 删除多选行
|
||||
async function handleDeleteRows() {
|
||||
const $table = tableRef.value;
|
||||
if ($table) {
|
||||
deleteRows($table.getCheckboxRecords());
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteRows(rows = []) {
|
||||
const $table = tableRef.value;
|
||||
|
||||
if (!$table) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!rows.length) {
|
||||
ElMessage.warning("请先选择要删除的行");
|
||||
return;
|
||||
}
|
||||
|
||||
const containerNos = rows.map((row) => row.b_container_no);
|
||||
const deleteIds = rows.map((row) => row.b_id);
|
||||
|
||||
const tipMessage = `确定要删除以下箱号记录吗?<br/><strong>${containerNos.join(", ")}</strong>`;
|
||||
|
||||
await ElMessageBox.confirm(tipMessage, "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
dangerouslyUseHTMLString: true,
|
||||
});
|
||||
|
||||
if (deleteIds.length === 0) {
|
||||
ElMessage.success("删除成功");
|
||||
loadTableDatas();
|
||||
return;
|
||||
}
|
||||
|
||||
// 确保 deleteIds 数组中的值是数字,防止 SQL 注入
|
||||
const safeDeleteIds = deleteIds.map((id) => Number(id));
|
||||
|
||||
// 使用安全的 SQL 查询
|
||||
const fileRes = await loadDataApi("bf_file", `father IN (${safeDeleteIds.join(",")})`, "", [
|
||||
"subid",
|
||||
]);
|
||||
|
||||
if (!fileRes.success) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const file of fileRes.data) {
|
||||
await deleteFileApi(file.subid);
|
||||
}
|
||||
|
||||
const requestData = [
|
||||
{
|
||||
tableName: "b_container",
|
||||
keyField: "b_id",
|
||||
inserts: [],
|
||||
updates: [],
|
||||
deletes: deleteIds.map((id) => ({ b_id: id })),
|
||||
},
|
||||
];
|
||||
|
||||
await saveObjectApi(requestData).then((res) => {
|
||||
if (res.success) {
|
||||
ElMessage.success("删除成功");
|
||||
loadTableDatas();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function handleSearch() {
|
||||
pagination.page = 1;
|
||||
|
||||
loadTableDatas();
|
||||
}
|
||||
|
||||
function handleSearchReset() {
|
||||
searchForm.value.startTime = "";
|
||||
searchForm.value.endTime = "";
|
||||
searchForm.value.containerNo = "";
|
||||
searchForm.value.username = "";
|
||||
}
|
||||
|
||||
function handlePreviewShow(imgUrl) {
|
||||
const index = previewImageList.value.indexOf(imgUrl);
|
||||
|
||||
if (index !== -1) {
|
||||
previewIndex.value = index;
|
||||
showPreview.value = true;
|
||||
} else {
|
||||
showPreview.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function handlePreviewClose() {
|
||||
showPreview.value = false;
|
||||
previewIndex.value = -1;
|
||||
}
|
||||
|
||||
function handleFileShow(data) {
|
||||
currentRow.value = data;
|
||||
|
||||
showFile.value = true;
|
||||
}
|
||||
|
||||
function handleDownloadOne(data) {
|
||||
console.log(data);
|
||||
// 获取
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="g3-container">
|
||||
<div v-if="showSearch" class="g3-search">
|
||||
<G3Grid class="grid">
|
||||
<G3GridGroup :label-width="80" :column="2">
|
||||
<G3GridItem label="上传日期" :span="2">
|
||||
<el-date-picker
|
||||
type="datetime"
|
||||
placeholder="开始日期"
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
v-model="searchForm.startTime"
|
||||
/>
|
||||
<el-divider direction="vertical" />
|
||||
<el-date-picker
|
||||
type="datetime"
|
||||
placeholder="结束日期"
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
v-model="searchForm.endTime"
|
||||
/>
|
||||
</G3GridItem>
|
||||
<G3GridItem label="箱号">
|
||||
<el-input v-model="searchForm.containerNo" />
|
||||
</G3GridItem>
|
||||
|
||||
<G3GridItem label="操作员">
|
||||
<el-input v-model="searchForm.username" />
|
||||
</G3GridItem>
|
||||
</G3GridGroup>
|
||||
</G3Grid>
|
||||
|
||||
<div class="search-extra">
|
||||
<el-button type="primary" @click="handleSearch">
|
||||
<el-icon class="el-icon--left">
|
||||
<G3Icon icon="lucide:search" />
|
||||
</el-icon>
|
||||
搜索
|
||||
</el-button>
|
||||
|
||||
<el-button @click="handleSearchReset">
|
||||
<el-icon class="el-icon--left">
|
||||
<G3Icon icon="lucide:refresh-ccw" />
|
||||
</el-icon>
|
||||
重置
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="g3-content">
|
||||
<div class="content-top">
|
||||
<div>
|
||||
<el-button type="primary">
|
||||
<el-icon class="el-icon--left">
|
||||
<G3Icon icon="lucide:cloud-download" />
|
||||
</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>
|
||||
<el-tooltip content="显示/关闭 搜索">
|
||||
<el-button circle @click="showSearch = !showSearch">
|
||||
<el-icon>
|
||||
<G3Icon icon="lucide:search" />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="刷新">
|
||||
<el-button circle>
|
||||
<el-icon>
|
||||
<G3Icon icon="lucide:refresh-ccw" />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
<el-dropdown>
|
||||
<el-button circle style="margin-left: 12px">
|
||||
<el-icon>
|
||||
<G3Icon icon="lucide:ellipsis" />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item @click="updateViewTableColumns(tableRef)">
|
||||
栏位保存
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item>导出Execl</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</div>
|
||||
<div class="g3-table">
|
||||
<vxe-table
|
||||
ref="tableRef"
|
||||
:loading="loading.table"
|
||||
:data="tableData"
|
||||
:cell-config="{ height: 100 }"
|
||||
:column-config="{
|
||||
resizable: true,
|
||||
drag: true,
|
||||
}"
|
||||
:row-config="{
|
||||
useKey: true,
|
||||
isCurrent: true,
|
||||
isHover: true,
|
||||
}"
|
||||
:filter-config="{
|
||||
showIcon: false,
|
||||
}"
|
||||
:column-drag-config="{
|
||||
showIcon: false,
|
||||
trigger: 'cell',
|
||||
}"
|
||||
height="100%"
|
||||
>
|
||||
<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"
|
||||
:key="column.col_FieldName"
|
||||
:field="column.col_FieldName"
|
||||
:title="column.col_Caption"
|
||||
:width="column.col_Width"
|
||||
align="center"
|
||||
:params="column"
|
||||
:sortable="column.col_FieldName !== 'b_container_img'"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<template v-if="column.col_FieldName === 'b_container_img'">
|
||||
<el-image
|
||||
style="width: 100px; height: 100px; cursor: pointer"
|
||||
:src="row.b_container_img"
|
||||
@click="handlePreviewShow(row.b_container_img)"
|
||||
/>
|
||||
</template>
|
||||
<template v-else>
|
||||
{{ formatValueByFormat(row[column.col_FieldName], column.col_DisplayFormat) }}
|
||||
</template>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column width="220" align="center" fixed="right" title="操作">
|
||||
<template #default="{ row }">
|
||||
<el-button link type="primary" @click="handleDownloadOne(row)">
|
||||
<el-icon class="el-icon--left">
|
||||
<G3Icon icon="lucide:cloud-download" />
|
||||
</el-icon>
|
||||
下载
|
||||
</el-button>
|
||||
<el-button link type="primary" @click="handleFileShow(row)">
|
||||
<el-icon class="el-icon--left">
|
||||
<G3Icon icon="lucide:file-image" />
|
||||
</el-icon>
|
||||
图片
|
||||
</el-button>
|
||||
<el-button link type="danger" @click="handleDeleteRow(row)">
|
||||
<el-icon class="el-icon--left">
|
||||
<G3Icon icon="lucide:trash-2" />
|
||||
</el-icon>
|
||||
删除
|
||||
</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-image-viewer
|
||||
v-if="showPreview"
|
||||
:url-list="previewImageList"
|
||||
show-progress
|
||||
:initial-index="previewIndex"
|
||||
@close="handlePreviewClose"
|
||||
/>
|
||||
|
||||
<G3File
|
||||
v-model="showFile"
|
||||
:father="currentRow.b_id"
|
||||
module-id="b_container"
|
||||
:categories="fileCategories"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.g3-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.g3-search {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 10px;
|
||||
background-color: #fff;
|
||||
margin-bottom: 12px;
|
||||
|
||||
.grid {
|
||||
width: 500px;
|
||||
}
|
||||
|
||||
.search-extra {
|
||||
display: flex;
|
||||
margin-left: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
.g3-content {
|
||||
flex-grow: 1;
|
||||
background-color: #fff;
|
||||
padding: 10px;
|
||||
min-height: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.content-top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 8px;
|
||||
::v-deep(.el-button) {
|
||||
height: 32px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.g3-table {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.g3-pagination {
|
||||
margin-top: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
flex-shrink: 0;
|
||||
min-height: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in new issue
Block a user