564 lines
16 KiB
Vue
564 lines
16 KiB
Vue
<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>
|