Files
Web_IoTBase_Vue3_Prod/src/pages/commanage/index.vue
2025-12-11 14:24:29 +08:00

564 lines
16 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="company-management">
<!-- 操作栏 -->
<div class="header">
<el-button type="primary" @click="handleAdd" :icon="Plus">添加企业</el-button>
</div>
<!-- 企业表格 -->
<el-table :data="companies" border style="width: 100%" v-loading="loading" empty-text="暂无数据">
<el-table-column label="操作" width="102">
<template #default="{ row }">
<el-button type="info" :icon="Edit" circle plain @click="handleEdit(row)" />
<el-button type="danger" :icon="Delete" circle plain @click="handleDelete(row)" />
</template>
</el-table-column>
<el-table-column prop="code" label="公司代码" width="100" />
<el-table-column prop="nameCn" label="中文名称" width="180" />
<el-table-column prop="nameEn" label="英文名称" width="180" />
<el-table-column prop="industry" label="所属行业" width="120" />
<el-table-column prop="identity" label="身份" width="120" />
<el-table-column prop="region" label="地区" width="120" />
<!--<el-table-column prop="licenseCode" label="营业执照" width="220" />-->
</el-table>
<!-- 添加/编辑对话框 -->
<el-dialog v-model="dialogVisible"
:title="isEdit ? '编辑企业' : '添加企业'"
destroy-on-close
:close-on-click-modal="false"
width="800px">
<el-form :model="form"
:rules="rules"
ref="formRef"
label-width="120px"
label-position="right">
<el-form-item label="中文名称" prop="nameCn">
<el-input v-model="form.nameCn" placeholder="请输入中文名称" />
</el-form-item>
<el-form-item label="英文名称" prop="nameEn">
<el-input v-model="form.nameEn" placeholder="请输入英文名称" />
</el-form-item>
<el-form-item label="所属行业" prop="industry">
<el-select v-model="form.industry" placeholder="请选择行业">
<el-option v-for="item in industryOptions"
:key="item"
:label="item"
:value="item" />
</el-select>
</el-form-item>
<el-form-item label="公司身份" prop="identity">
<el-select v-model="form.identity" placeholder="请选择身份">
<el-option v-for="item in identityOptions"
:key="item"
:label="item"
:value="item" />
</el-select>
</el-form-item>
<el-form-item label="所属地区" prop="region">
<el-select v-model="form.region" placeholder="请选择地区">
<el-option v-for="(key,item) in regionOptions"
:key="item"
:label="item"
:value="item" />
</el-select>
</el-form-item>
<!--
<el-form-item label="营业执照代码" prop="licenseCode">
<el-input v-model="form.licenseCode" placeholder="请输入营业执照代码" />
</el-form-item>-->
<!--<el-form-item label="营业执照" prop="licenseImage">
<el-upload class="license-uploader"
drag
action="/api/upload"
:show-file-list="false"
:on-change="handleLicenseChange"
:auto-upload="false">-->
<!-- 预览区域 -->
<!--<div v-if="form.licenseImage || form.licensePreview" class="image-preview">
<img v-if="isImageFile(form.licenseImageFile)"
:src="form.licensePreview || getFullUrl(form.licenseImage)"
class="preview-image" />
<div v-else class="file-preview">
<el-icon size="33"><DocumentChecked /></el-icon>
<div>营业执照文件 <span style="color: #409EFF">已上传</span></div>
<div class="file-name">{{ getFileName(form.licenseImage) }}</div>
</div>
<div class="preview-mask">
<el-icon><UploadFilled /></el-icon>
<div>点击更换文件</div>
</div>
</div>-->
<!-- 未上传状态 -->
<!--<template v-else>
<el-icon class="el-icon--upload"><UploadFilled /></el-icon>
<div class="el-upload__text">
拖拽文件到此 <em>点击上传</em>
</div>
<div class="el-upload__tip">
支持JPG/PNG/PDF格式大小不超过5MB
</div>
</template>
</el-upload>
</el-form-item>-->
<el-form-item label="公司Logo" prop="logo">
<el-upload class="logo-uploader"
drag
action="/api/upload"
:show-file-list="false"
:on-change="handleLogoChange"
:auto-upload="false">
<!-- 预览区域 -->
<div v-if="form.logoaddress || form.logoPreview" class="image-preview">
<img :src="form.logoPreview || getFullUrl(form.logoaddress)"
class="preview-image" />
<div class="preview-mask">
<el-icon><UploadFilled /></el-icon>
<div>点击更换Logo</div>
</div>
</div>
<!-- 未上传状态 -->
<template v-else>
<el-icon class="el-icon--upload"><UploadFilled /></el-icon>
<div class="el-upload__text">
拖拽图片到此 <em>点击上传</em>
</div>
<div class="el-upload__tip">
支持JPG/PNG格式大小不超过5MB
</div>
</template>
</el-upload>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="submitForm">确定</el-button>
</template>
</el-dialog>
</div>
</template>
<script setup>
import { ref, reactive, onMounted, inject, onUnmounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Plus, Delete, Edit, UploadFilled, DocumentChecked } from '@element-plus/icons-vue'
const $http = inject('$http')
const ajaxfile = inject('ajaxfile');
const config = inject('config');
// 数据列表
const companies = ref([])
const loading = ref(false)
// 对话框相关
const dialogVisible = ref(false)
const isEdit = ref(false)
const currentCompanyId = ref(null)
const formRef = ref(null)
// 表单初始数据
const defaultForm = {
code: '',
nameCn: '',
nameEn: '',
industry: '',
identity: '',
region: '',
licenseCode: '',
logoaddress: '',
licenseImage: ''
}
const form = reactive({ ...defaultForm })
// 选项数据
const industryOptions = ref([]);
const getIndustry = () => {
try {
const rs = $http.post('ConfigPY/GetSingleValue', {
VarName: "行业分类",
}).then(rs => {
//console.log(JSON.parse(rs.data.response));
industryOptions.value = JSON.parse(rs.data.response)
})
} catch (error) {
console.log(error);
}
};
const identityOptions = ref([]);
const getIdentity = () => {
try {
const rs = $http.post('ConfigPY/GetSingleValue', {
VarName: "公司身份",
}).then(rs => {
//console.log(JSON.parse(rs.data.response));
identityOptions.value = JSON.parse(rs.data.response)
})
} catch (error) {
console.log(error);
}
};
const regionOptions = ref([]);
const getRegion = () => {
try {
const rs = $http.post('ConfigPY/GetSingleValue', {
VarName: "区域",
}).then(rs => {
//console.log(JSON.parse(rs.data.response));
regionOptions.value = JSON.parse(rs.data.response)
})
} catch (error) {
console.log(error);
}
};
// 验证规则
const rules = reactive({
nameCn: [
{ required: true, message: '请输入中文名称', trigger: 'blur' }
],
industry: [
{ required: true, message: '请选择所属行业', trigger: 'change' }
],
identity: [
{ required: true, message: '请选择所属身份', trigger: 'change' }
],
region: [
{ required: true, message: '请选择所属地区', trigger: 'change' }
]/*,
licenseCode: [
{ required: true, message: '请输入营业执照代码', trigger: 'blur' }
]*/
})
// 获取企业列表
const getCompanies = async () => {
try {
loading.value = true
const rs = await $http.post('Company/GetComInfo', {
IsAll: true,
ID: 0,
})
if (rs.data.isok) {
companies.value = rs.data.response
//console.log(companies.value);
} else {
ElMessage.error(rs.data.message)
}
} catch (error) {
ElMessage.error('获取企业列表失败')
console.error(error)
} finally {
loading.value = false
}
}
// 获取完整图片URL
const getFullUrl = (filename) => {
//console.log(config.httpAds + `${filename}`);
if (!filename) return '';
// 如果已经是完整URL直接返回
if (filename.startsWith('http')) return filename;
// 根据实际存储路径拼接
return config.Ads + `${filename}`;
}
const beforeImageUpload = (file) => {
const isImage = file.type.startsWith('image/')
const isLt5M = file.size / 1024 / 1024 < 5
if (!isImage) {
ElMessage.error('只能上传图片文件!')
return false
}
if (!isLt5M) {
ElMessage.error('文件大小不能超过5MB!')
return false
}
return true
}
const beforeImageUploadPDF = (file) => {
const isImageOrPDF = file.type.startsWith('image/') || file.type === 'application/pdf';
const isLt5M = file.size / 1024 / 1024 < 5;
if (!isImageOrPDF) {
ElMessage.error('只能上传图片文件或PDF文件!');
return false;
}
if (!isLt5M) {
ElMessage.error('文件大小不能超过5MB!');
return false;
}
return true;
}
// 添加公司
const handleAdd = () => {
Object.assign(form, defaultForm);
isEdit.value = false;
dialogVisible.value = true;
};
// 编辑公司
const handleEdit = (row) => {
Object.assign(form, row);
isEdit.value = true;
currentCompanyId.value = row.id;
dialogVisible.value = true;
};
// 删除公司
const handleDelete = (row) => {
ElMessageBox.confirm('确定删除该公司吗?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(async () => {
try {
//console.log(row.id);
const rs = await $http.post('Company/DelCom', { Id: row.id });
if (rs.data.isok) {
ElMessage.success('删除成功');
await getCompanies();
} else {
ElMessage.error(rs.data.message);
}
} catch (error) {
ElMessage.error('删除失败');
console.error(error);
}
}).catch(() => { });
};
const handleLogoChange = (file) => {
form.logoFile = file.raw;
// 生成本地预览图URL
form.logoPreview = URL.createObjectURL(file.raw); // 新增预览字段
};
const handleLicenseChange = (file) => {
form.licenseImageFile = file.raw;
// 生成本地预览图URL
form.licensePreview = URL.createObjectURL(file.raw); // 新增预览字段
};
const submitForm = async () => {
await formRef.value.validate();
try {
// 上传Logo
if (form.logoFile) {
const logoFileData = {
File: form.logoFile,
Folder: "companylogo" // 根据实际存储目录调整
};
const logoUploadRes = await ajaxfile(logoFileData);
if (logoUploadRes?.fileName) {
form.logoaddress = "Uploads/companylogo/" + logoUploadRes.fileName;
} else {
ElMessage.error('上传Logo失败: ' + logoUploadRes);
return;
}
} else if (form.logoaddress) { // 保留已有Logo逻辑
form.logoaddress = form.logoaddress.substring(form.logoaddress.lastIndexOf('/') + 1);
}
/* // 上传营业执照
if (form.licenseImageFile) {
const licenseFileData = {
File: form.licenseImageFile,
Folder: "businesslic" // 根据实际存储目录调整
};
const licenseUploadRes = await ajaxfile(licenseFileData);
if (licenseUploadRes?.fileName) {
form.licenseImage = licenseUploadRes.fileName;
} else {
ElMessage.error('上传营业执照失败: ' + licenseUploadRes);
return;
}
} else if (form.licenseImage) { // 保留已有营业执照逻辑
form.licenseImage = form.licenseImage.substring(form.licenseImage.lastIndexOf('/') + 1);
}*/
// 提交表单数据
const api = isEdit.value ? 'Company/EditCom' : 'Company/AddCom';
const data = isEdit.value ? { ...form, id: currentCompanyId.value } : form;
const rs = await $http.post(api, data);
if (rs.data.isok) {
ElMessage.success(isEdit.value ? '修改成功' : '添加成功');
dialogVisible.value = false;
await getCompanies();
} else {
ElMessage.error(rs.data.message);
}
} catch (error) {
ElMessage.error('操作失败');
console.error(error);
}
};
const isImageFile = (url) => {
return /\.(jpe?g|png|gif|webp)$/i.test(url)
}
const getFileName = (url) => {
return url.split('/').pop()
}
// 其他操作函数handleAdd/handleEdit/handleDelete与公司管理页面逻辑类似
// 此处省略,保持与公司管理页面相同逻辑即可
onMounted(() => {
getCompanies()
getIndustry()
getIdentity()
getRegion()
})
// 在组件卸载时释放对象URL
onUnmounted(() => {
if (form.logoPreview) URL.revokeObjectURL(form.logoPreview);
if (form.licensePreview) URL.revokeObjectURL(form.licensePreview);
})
</script>
<style scoped>
.company-management {
padding: 12px;
}
.header {
margin-bottom: 10px;
}
.logo-uploader,
.license-uploader {
border: 1px dashed var(--el-border-color);
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
transition: border-color 0.3s;
}
.logo-uploader {
width: 300px;
height: 180px;
}
.license-uploader {
width: 300px;
height: 180px;
}
.logo-uploader:hover,
.license-uploader:hover {
border-color: var(--el-color-primary);
}
.uploader-icon {
font-size: 28px;
color: #8c939d;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.logo-image {
width: 100%;
height: 100%;
object-fit: contain;
}
.license-image {
width: 100%;
height: 100%;
object-fit: cover;
}
.upload-tip {
font-size: 12px;
color: #606266;
margin-top: 8px;
}
/* 通用上传样式 */
.logo-uploader :deep(.el-upload-dragger),
.license-uploader :deep(.el-upload-dragger) {
width: 100%;
min-height: 180px;
padding: 20px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
/* 预览区域公共样式 */
.image-preview {
position: relative;
width: 100%;
height: 100%;
}
.preview-image {
max-width: 100%;
max-height: 200px;
object-fit: contain;
}
/* 遮罩层样式 */
.preview-mask {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
color: white;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
opacity: 0;
transition: opacity 0.3s;
}
.image-preview:hover .preview-mask {
opacity: 1;
}
.el-icon--upload {
font-size: 36px;
color: var(--el-text-color-secondary);
margin-bottom: 12px;
}
.el-upload__text {
font-size: 14px;
color: var(--el-text-color-regular);
text-align: center;
}
.el-upload__tip {
font-size: 12px;
color: var(--el-text-color-secondary);
margin-top: 8px;
}
</style>