You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

471 lines
14 KiB

<template>
<ContentWrap
>{{ formData.id ? '修改企业信息' : '发布企业信息' }}
<section class="taskForm">
<el-form
ref="formRef"
:model="formData"
:rules="formRules"
label-width="auto"
v-loading="loading"
>
<el-form-item label="企业名称" prop="enterprisesName">
<el-input v-model="formData.enterprisesName" placeholder="请输入企业名称" />
</el-form-item>
<el-form-item label="企业类型" prop="type">
<el-select v-model="formData.type" placeholder="请选择企业类型">
<el-option
v-for="dict in getStrDictOptions(DICT_TYPE.ENTERPRISES_TYPE)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="企业所属区域" prop="region">
<el-select v-model="formData.region" placeholder="请选择企业所属区域">
<el-option
v-for="dict in getStrDictOptions(DICT_TYPE.ENTERPRISES_AREA)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="专管员" prop="startUserSelectAssignees">
<section class="selec-wrapper">
<!-- 动态显示选中的专管员 -->
<section class="select" @click="handlerClickSelect">
{{ selectedUser ? selectedUser : '请选择专管员' }}
</section>
</section>
</el-form-item>
<el-form-item label="企业地址" prop="address">
<el-input v-model="formData.address" type="textarea" placeholder="请输入企业地址" />
</el-form-item>
<el-form-item label="企业环保负责人姓名" prop="contactName">
<el-input v-model="formData.contactName" placeholder="请输入环保负责人姓名" />
</el-form-item>
<el-form-item label="企业环保负责人联系电话" prop="environmentalContactPhone">
<el-input
v-model="formData.environmentalContactPhone"
placeholder="请输入企业环保负责人联系电话"
/>
</el-form-item>
<el-form-item label="企业注册号" prop="registrationNumber">
<el-input v-model="formData.registrationNumber" placeholder="请输入企业注册号" />
</el-form-item>
<el-form-item label="企业介绍" prop="introduction">
<el-input v-model="formData.introduction" type="textarea" placeholder="请输入企业介绍" />
</el-form-item>
<el-form-item label="企业照片" prop="size">
<InnerUploadImg
:uploadList="uploadList"
@handler-success="uploadSuccess"
ref="uploadRef"
@handler-remove="uploadRemove"
/>
</el-form-item>
<el-form-item label="企业资质照片" prop="size">
<InnerUploadImg
:uploadList="uploadList"
@handler-success="uploadSuccess"
ref="uploadRef"
@handler-remove="uploadRemove"
/>
</el-form-item>
<el-form-item label="企业成立时间" prop="establishmentDate">
<el-date-picker
v-model="formData.establishmentDate"
type="date"
value-format="x"
placeholder="选择企业成立时间"
/>
</el-form-item>
<el-form-item label="企业经纬度" prop="gpsLocation">
<el-input
v-model="formData.gpsLocation"
placeholder="点击按钮选择坐标"
readonly
style="width: 500px"
>
<template #append>
<!-- 选择坐标按钮 -->
<el-button @click="showMap = true">选择坐标</el-button>
</template>
</el-input>
</el-form-item>
<!-- 地图弹窗 -->
<el-dialog v-model="showMap" title="选择坐标" width="80%" :before-el-close="handleClose">
<div>
<el-input
type="text"
v-model="formData.searchQuery"
placeholder="可通过名称联想搜索"
style="width: 20%"
/>
<el-button @click="handleSearch">搜索</el-button>
</div>
<div ref="mapContainerRef" style="width: 100%; height: 600px"></div>
<template #footer>
<el-button @click="showMap = false">关闭</el-button>
<el-button type="primary" @click="showMap = false">确定</el-button>
</template>
</el-dialog>
<el-form-item label="签到半径" prop="gpsLocation">
<el-input
v-model="formData.signRadius"
placeholder="请输入签到半径"
style="width: 280px"
/><span style="margin-left: 10px"></span>
</el-form-item>
<el-form-item style="align-items: center">
<el-button type="success" @click="submitForm">确认</el-button>
</el-form-item>
</el-form>
</section>
<SelectUser ref="selectUserRef" @select-user="echoUser" />
</ContentWrap>
</template>
<script setup lang="ts">
import { getStrDictOptions, DICT_TYPE } from '@/utils/dict'
import { EnterprisesApi, EnterprisesVO } from '@/api/enterprises'
import { FileInfoApi } from '@/api/enterprises/fileinfo'
import { ElMessage } from 'element-plus'
import SelectUser from './components/SelectUser.vue'
import * as UserApi from '@/api/system/user'
/** 企业 表单 */
defineOptions({ name: 'UpdateEnterprises' })
const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗
const dialogVisible = ref(false) // 弹窗的是否展示
const dialogTitle = ref('') // 弹窗的标题
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
const formType = ref('') // 表单的类型:create - 新增;update - 修改
const selectUserRef = ref()
const loading = ref(false)
const selectedUser = ref()
const formData = ref({
id: undefined,
departmentId: undefined,
userId: undefined,
type: undefined,
region: undefined,
enterprisesName: undefined,
address: undefined,
contactName: undefined,
enterprisesStatus:undefined,
environmentalContactPhone: undefined,
registrationNumber: undefined,
introduction: undefined,
establishmentDate: undefined,
gpsLocation: undefined,
searchQuery: undefined,
managerDeptId: undefined,
ides: undefined,
startUserSelectAssignees:undefined
})
const formRules = reactive({
type: [{ required: true, message: '企业类型不能为空', trigger: 'change' }],
enterprisesName: [{ required: true, message: '企业名称不能为空', trigger: 'blur' }],
contactName: [{ required: true, message: '负责人不能为空', trigger: 'blur' }],
environmentalContactPhone: [{ required: true, message: '企业环保负责人联系电话不能为空', trigger: 'blur' }]
})
const formRef = ref() // 表单 Ref
const { query } = useRoute()
function init() {
if (query.id) {
// 修改:如果有 id 则设置为 'update'
formType.value = 'update'
EnterprisesApi.getEnterprises(query.id).then((res) => {
selectedUser.value=res.inviterName;
// formData.value.startUserSelectAssignees=res.userId;
formData.value = res
})
}else{ formType.value = 'create'}
}
// 控制地图弹窗显示隐藏
const showMap = ref(false)
// 地图实例
let map
// 标记实例
let marker
let searchService=null
// const searchService = ref()
const mapContainerRef = ref<HTMLDivElement | null>(null)
// 初始化地图
const initMap = () => {
if (!window.qq || !window.qq.maps) {
ElMessage.error('腾讯地图 API 未加载完成')
return
}
if (!mapContainerRef.value) {
ElMessage.error('地图容器元素未找到')
return
}
map = new window.qq.maps.Map(mapContainerRef.value, {
center: new window.qq.maps.LatLng(41.520282, 121.265721), // 初始中心点
zoom: 14
})
// 添加地图点击事件监听器
window.qq.maps.event.addListener(map, 'click', (event: any) => {
const latLng = event.latLng
const lat = latLng.getLat()
const lng = latLng.getLng()
// 更新表单中的经纬度信息
formData.value.gpsLocation = `${lat},${lng}`
// 在地图上显示标记
if (marker) {
marker.setMap(null) // 清除之前的标记
}
marker = new window.qq.maps.Marker({
position: latLng,
map: map
})
})
// 确保 searchService 已经正确初始化
searchService = new window.qq.maps.SearchService({
complete: (results) => {
// console.log('搜索结果:', results) // 打印 results 对象
if (results.detail && results.detail.pois.length > 0) {
const firstResult = results.detail.pois[0]
const position = firstResult.latLng
// 设置地图中心点为搜索结果的位置
map.setCenter(position)
// 创建标记
if (marker) {
marker.setMap(null)
}
marker = new window.qq.maps.Marker({
position: position,
map: map
})
// 更新表单中的经纬度信息
formData.value.gpsLocation = `${position.getLat()},${position.getLng()}`
}
},
error: (e) => {
console.error('搜索出错:', e)
ElMessage.error('搜索出错,请重试')
}
})
}
// 搜索按钮点击事件处理函数
const handleSearch = () => {
if (searchService && formData.value.searchQuery) {
searchService.search(formData.value.searchQuery)
} else {
ElMessage.error('请输入搜索关键词')
}
}
onMounted(() => {
init()
const openMapAndInit = async () => {
if (showMap.value) {
await nextTick() // 等待 DOM 更新
if (qq && qq.maps) {
initMap() // 初始化地图
} else {
console.error('腾讯地图 API 未加载完成')
}
}
}
// 监听 showMap 的变化
watch(
showMap,
() => {
openMapAndInit()
},
{ immediate: true }
)
})
function handlerClickSelect() {
// 调用 SelectUser 组件的 open 方法
unref(selectUserRef)?.open()
}
function handlerSelectUser(row) {
if (formData.value.startUserSelectAssignees.findIndex((i) => i.id == row.id) > -1) return
formData.value.startUserSelectAssignees.push(row)
}
/** 提交表单 */
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
const submitForm = async () => {
// 校验表单
await formRef.value.validate()
formData.value.enterprisesStatus=1;
// 提交请求
loading.value = true
try {
const data = formData.value as unknown as EnterprisesVO
if (formType.value === 'create') {
await EnterprisesApi.pccreateEnterprises(data)
message.success(t('common.createSuccess'))
} else {
await EnterprisesApi.updateEnterprises(data)
message.success(t('common.updateSuccess'))
}
dialogVisible.value = false
// 发送操作成功的事件
emit('success')
} finally {
loading.value = false
}
}
const echoUser = async (v) => {
// console.log('当前选择',v)
const users = await UserApi.getUser(v)
selectedUser.value = users.username
formData.value.userId=users.id
}
/** 重置表单 */
const resetForm = () => {
formData.value = {
id: undefined,
departmentId: undefined,
userId: undefined,
type: undefined,
region: undefined,
enterprisesName: undefined,
address: undefined,
contactName: undefined,
environmentalContactPhone: undefined,
registrationNumber: undefined,
introduction: undefined,
establishmentDate: undefined,
gpsLocation: undefined,
searchadd: undefined,
managerDeptId: undefined,
startUserSelectAssignees: undefined
}
formRef.value?.resetFields()
}
const uploadList: any = ref([])
async function uploadSuccess(res) {
if (res) {
await FileInfoApi.createFileInfo({
unitId: formData.value.id || id.value,
attachmentPath: res.data,
attachmentName: res.filename,
attachmentSuffix: res.type
//type: 4
}).then(() => {
loading.value.close()
dialogVisible.value = false
emit('success')
})
} else {
loading.value.close()
dialogVisible.value = false
emit('success')
}
}
function getCarImg() {
loading.value = true
FileInfoApi.getFileInfoPage({ unitId: formData.value.id, type: 4 }).then((res) => {
uploadList.value = res.list.map((item) => {
return {
...item,
url: item.attachmentPath,
name: item.attachmentName
}
})
loading.value = false
})
}
function uploadRemove(file) {
FileInfoApi.deleteFileInfo(file.id).then(() => {
ElMessage.success('删除成功')
})
}
</script>
<style lang="scss" scoped>
.selec-wrapper {
max-width: 400px;
display: flex;
flex-flow: row nowrap;
gap: 5px;
.users {
flex: 1;
display: flex;
flex-flow: row wrap;
gap: 5px;
}
.select {
cursor: pointer;
background-color: #f1faff;
border: 1px dashed #00a3ff;
padding: 1px 40px;
color: #00a3ff;
// color: #00a3ff;
// text-decoration: underline;
border-radius: 6px;
height: fit-content;
&:hover {
opacity: 0.8;
}
}
}
.modal-enter-from {
opacity: 0;
transition: 0.2s all;
}
.modal-leave-to {
opacity: 0;
}
.modal-enter-from .modal-container,
.modal-leave-to .modal-container {
-webkit-transform: scale(1.1);
transform: scale(1.1);
}
#map-container {
width: 100%;
height: 400px;
margin-top: 20px;
}
</style>