<template>
|
<div class="main-box">
|
<TreeFilter label="name" :title="t('User.companyList')" :request-api="getUserDepartment" @change="changeTreeFilter" />
|
<div class="table-box">
|
<ProTable
|
ref="proTable"
|
:columns="columns"
|
:request-api="getComapnyList"
|
:init-param="initParam"
|
:search-col="{ xs: 1, sm: 1, md: 2, lg: 3, xl: 3 }"
|
>
|
<!-- 表格 header 按钮 -->
|
<template #tableHeader>
|
<el-button type="primary" v-if="BUTTONS.add" :icon="CirclePlus" @click="openDrawer(t('Config.add'))">
|
{{ t("company.addCompany") }}
|
</el-button>
|
</template>
|
<!-- 表格操作 -->
|
<template #operation="scope">
|
<el-button type="primary" link :icon="View" @click="openDrawer(t('Config.view'), scope.row)">
|
{{ t("Config.view") }}
|
</el-button>
|
<el-button type="primary" v-if="BUTTONS.edit" link :icon="EditPen" @click="openDrawer(t('Config.update'), scope.row)">
|
{{ t("Config.update") }}
|
</el-button>
|
<el-button type="primary" v-if="BUTTONS.delete" link :icon="Delete" @click="deleteAccount(scope.row)">
|
{{ t("Config.delete") }}
|
</el-button>
|
</template>
|
</ProTable>
|
<CompanyDrawer ref="drawerRef" />
|
<ImportExcel ref="dialogRef" />
|
<div v-if="showBindingDialog" class="binding-dialog-overlay">
|
<div class="binding-dialog-container">
|
<div class="binding-dialog">
|
<div class="dialog-header">
|
<el-icon class="warning-icon"><Warning /></el-icon>
|
<span class="dialog-title">{{ t("company.cannotDelete") }}</span>
|
</div>
|
|
<div class="dialog-content">
|
<p class="company-name">
|
{{ t("company.companyName") }}:<strong>{{ bindingCompanyName }}</strong>
|
</p>
|
<p class="reason-text">{{ t("company.deleteReason") }}</p>
|
|
<div class="binding-data-list">
|
<div v-for="item in bindingDataList" :key="item.name" class="data-item">
|
<el-icon class="data-icon"><Document /></el-icon>
|
<span class="data-name">{{ item.name }}</span>
|
<el-tag type="danger" size="small" class="data-count">{{ item.count }} {{ t("company.records") }}</el-tag>
|
</div>
|
</div>
|
|
<div class="action-tips">
|
<el-icon class="info-icon"><InfoFilled /></el-icon>
|
<span class="tip-text">{{ t("company.cleanDataTip") }}</span>
|
</div>
|
</div>
|
|
<div class="dialog-footer">
|
<el-button type="primary" @click="closeBindingDialog">{{ t("company.iUnderstand") }}</el-button>
|
<el-button @click="closeBindingDialog">{{ t("Config.cancel") }}</el-button>
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
</template>
|
<script setup lang="tsx" name="useTreeFilter">
|
import { ref, reactive } from "vue";
|
import { useI18n } from "vue-i18n";
|
import { User } from "@/api/interface";
|
import { useHandleData } from "@/hooks/useHandleData";
|
import ProTable from "@/components/ProTable/index.vue";
|
import TreeFilter from "@/components/TreeFilter/index.vue";
|
import ImportExcel from "@/components/ImportExcel/index.vue";
|
import CompanyDrawer from "@/views/proTable/components/hxzk/user/CompanyDrawer.vue";
|
import { ProTableInstance, ColumnProps } from "@/components/ProTable/interface";
|
import { CirclePlus, Delete, EditPen, View, Warning, Document, InfoFilled } from "@element-plus/icons-vue";
|
import { getUserDepartment } from "@/api/modules/hxzk/user/user";
|
import { getComapnyList, addCompany, editCompany, deleteCompany, checkCompanyDelete } from "@/api/modules/hxzk/user/company";
|
import localImage from "../../../assets/images/notData.png";
|
import { useAuthButtons } from "@/hooks/useAuthButtons";
|
|
const { t } = useI18n();
|
const { BUTTONS } = useAuthButtons();
|
|
// ProTable 实例
|
const proTable = ref<ProTableInstance>();
|
|
// 如果表格需要初始化请求参数,直接定义传给 ProTable(之后每次请求都会自动带上该参数,此参数更改之后也会一直带上,改变此参数会自动刷新表格数据)
|
const initParam = reactive({ departmentId: "" });
|
|
// 树形筛选切换
|
const changeTreeFilter = (val: string) => {
|
proTable.value!.pageable.pageNum = 1;
|
initParam.departmentId = val;
|
};
|
|
// 表格配置项
|
const columns = reactive<ColumnProps<User.ResUserList>[]>([
|
{ type: "index", label: "", width: 80 },
|
{ prop: "companyname", label: t("User.companyName"), width: 120, search: { el: "input", span: 3 } },
|
{ prop: "systemname", label: t("company.systemName") },
|
{
|
prop: "logo",
|
label: "LOGO",
|
render: scope => {
|
// 默认的本地图片路径,确保这个路径是正确的
|
const defaultImage = localImage; // 替换为您的默认图片路径
|
// 拼接完整的图片 URL,或者为null的情况提供默认图片
|
const imageUrl = scope.row.logo || defaultImage;
|
return (
|
<img
|
src={imageUrl}
|
width="30"
|
height="30"
|
alt="图片"
|
style={{ cursor: "pointer" }} // 添加这一行设置鼠标指针样式
|
onError={e => {
|
// 当图片加载失败时,也替换为默认图片
|
e.target.src = defaultImage;
|
}}
|
/>
|
);
|
}
|
},
|
{ prop: "addusername", label: t("role.creator") },
|
{ prop: "addtime", label: t("role.updateTime") },
|
{ prop: "operation", label: t("Config.operation"), width: 260 }
|
]);
|
|
// 删除公司信息
|
const deleteAccount = async (params: any) => {
|
try {
|
// 先检查公司是否可以删除
|
const checkResult = await checkCompanyDelete({ id: params.id });
|
|
if (checkResult.msg.includes("CompanyHasBindingData:")) {
|
// 检查失败,显示详细的绑定数据信息
|
let bindingDataList: Array<{ name: string; count: number }> = [];
|
|
if (checkResult.msg && checkResult.msg.includes("CompanyHasBindingData:")) {
|
// 解析后端返回的详细绑定数据
|
const bindingDataStr = checkResult.msg.split("CompanyHasBindingData:")[1];
|
if (bindingDataStr) {
|
// 解析格式:部门(5),人员(10),用户(3),角色(2),图标(1),车辆(0),物资(0),地图(0),警告(0)
|
const dataItems = bindingDataStr.split(",");
|
|
dataItems.forEach(item => {
|
const match = item.match(/(.+?)\((\d+)\)/);
|
if (match) {
|
const name = match[1];
|
const count = parseInt(match[2]);
|
if (count > 0) {
|
bindingDataList.push({ name, count });
|
}
|
}
|
});
|
}
|
}
|
|
// 显示美化的绑定数据对话框
|
showBindingDataDialog(bindingDataList, params.companyname);
|
return;
|
}
|
|
// 用户确认删除
|
await useHandleData(deleteCompany, { id: params.id }, t("company.deleteConfirm", { name: params.companyname }), t);
|
proTable.value?.getTableList();
|
} catch {}
|
};
|
|
// 绑定数据对话框相关状态
|
const showBindingDialog = ref(false);
|
const bindingCompanyName = ref("");
|
const bindingDataList = ref<Array<{ name: string; count: number }>>([]);
|
|
// 显示绑定数据对话框
|
const showBindingDataDialog = (list: Array<{ name: string; count: number }>, companyName: string) => {
|
bindingDataList.value = list;
|
bindingCompanyName.value = companyName;
|
showBindingDialog.value = true;
|
};
|
|
// 关闭对话框
|
const closeBindingDialog = () => {
|
showBindingDialog.value = false;
|
};
|
// 批量添加用户
|
const dialogRef = ref<InstanceType<typeof ImportExcel> | null>(null);
|
|
// 打开 drawer(新增、查看、编辑)
|
const drawerRef = ref<InstanceType<typeof CompanyDrawer> | null>(null);
|
const openDrawer = (title: string, row: any = {}) => {
|
const params = {
|
title,
|
initParam: initParam,
|
isView: title === t("Config.view"),
|
row: { ...row },
|
api: title === t("Config.add") ? addCompany : title === t("Config.update") ? editCompany : undefined,
|
getTableList: proTable.value?.getTableList
|
};
|
drawerRef.value?.acceptParams(params);
|
};
|
</script>
|
<style scoped>
|
/* 绑定数据对话框样式 */
|
.binding-dialog-overlay {
|
position: fixed;
|
inset: 0;
|
z-index: 2000;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
background-color: rgb(0 0 0 / 50%);
|
}
|
.binding-dialog-container {
|
width: 90%;
|
max-width: 600px;
|
animation: dialog-fade-in 0.3s;
|
}
|
.binding-dialog {
|
overflow: hidden;
|
background-color: #ffffff;
|
border-radius: 8px;
|
box-shadow: 0 4px 12px rgb(0 0 0 / 15%);
|
}
|
.dialog-header {
|
display: flex;
|
align-items: center;
|
padding: 16px 20px;
|
background-color: #fff4e6;
|
border-bottom: 1px solid #ffe8cc;
|
}
|
.warning-icon {
|
margin-right: 10px;
|
font-size: 20px;
|
color: #fa8c16;
|
}
|
.dialog-title {
|
font-size: 16px;
|
font-weight: 600;
|
color: #fa8c16;
|
}
|
.dialog-content {
|
padding: 20px;
|
}
|
.company-name {
|
margin: 0 0 12px;
|
font-size: 14px;
|
color: #606266;
|
}
|
.reason-text {
|
margin: 0 0 16px;
|
font-size: 14px;
|
color: #606266;
|
}
|
.binding-data-list {
|
margin: 16px 0;
|
overflow: hidden;
|
border: 1px solid #f0f0f0;
|
border-radius: 4px;
|
}
|
.data-item {
|
display: flex;
|
align-items: center;
|
padding: 10px 16px;
|
border-bottom: 1px solid #f5f5f5;
|
transition: background-color 0.3s;
|
}
|
.data-item:last-child {
|
border-bottom: none;
|
}
|
.data-item:hover {
|
background-color: #fafafa;
|
}
|
.data-icon {
|
margin-right: 12px;
|
font-size: 16px;
|
color: #8c8c8c;
|
}
|
.data-name {
|
flex: 1;
|
font-size: 14px;
|
color: #595959;
|
}
|
.data-count {
|
min-width: 60px;
|
text-align: center;
|
}
|
.action-tips {
|
display: flex;
|
align-items: center;
|
padding: 12px;
|
margin-top: 20px;
|
background-color: #f6f6f6;
|
border-radius: 4px;
|
}
|
.info-icon {
|
margin-right: 8px;
|
font-size: 16px;
|
color: #1890ff;
|
}
|
.tip-text {
|
font-size: 14px;
|
color: #595959;
|
}
|
.dialog-footer {
|
padding: 16px 20px;
|
text-align: right;
|
border-top: 1px solid #f0f0f0;
|
}
|
|
@keyframes dialog-fade-in {
|
from {
|
opacity: 0;
|
transform: translateY(-20px);
|
}
|
to {
|
opacity: 1;
|
transform: translateY(0);
|
}
|
}
|
</style>
|