|
|
@@ -17,11 +17,19 @@ import { useRouter } from 'vue-router'
|
|
|
|
|
|
const MINIO_BASE_URL = import.meta.env.VITE_MINIO_BASE_URL
|
|
|
|
|
|
+// 户型类型映射
|
|
|
+const ROOM_TYPE_MAP = {
|
|
|
+ 1: { label: '公租房', color: '#67C23A' },
|
|
|
+ 2: { label: '厂房', color: '#E6A23C' },
|
|
|
+ 3: { label: '创新创业基地', color: '#409EFF' },
|
|
|
+}
|
|
|
+
|
|
|
interface HouseType {
|
|
|
id: string
|
|
|
accountNumber?: string
|
|
|
address?: string
|
|
|
area?: string
|
|
|
+ roomType?: number // 户型类型:1-公租房,2-厂房,3-创新创业基地
|
|
|
accountUrl?: string
|
|
|
createTime?: Date
|
|
|
createBy?: string
|
|
|
@@ -48,15 +56,15 @@ interface HouseTypeResponse extends BaseResponse {
|
|
|
}
|
|
|
|
|
|
interface Room {
|
|
|
- id?: string // 主键
|
|
|
- houseTypeId: string // 户型主键
|
|
|
- roomNumber: string // 房间
|
|
|
- roomPictureUrl?: string // 房间图片url
|
|
|
- attribute?: string // 按钮属性
|
|
|
- createTime?: Date // 创建时间
|
|
|
- createBy?: string // 创建人
|
|
|
- updateTime?: Date // 修改时间
|
|
|
- updateBy?: string // 修改人
|
|
|
+ id?: string
|
|
|
+ houseTypeId: string
|
|
|
+ roomNumber: string
|
|
|
+ roomPictureUrl?: string
|
|
|
+ attribute?: string
|
|
|
+ createTime?: Date
|
|
|
+ createBy?: string
|
|
|
+ updateTime?: Date
|
|
|
+ updateBy?: string
|
|
|
}
|
|
|
|
|
|
interface RoomListResponse extends BaseResponse {
|
|
|
@@ -70,13 +78,14 @@ interface HouseTypeOneResponse extends BaseResponse {
|
|
|
interface HouseTypeRequest {
|
|
|
pageNum: number
|
|
|
pageSize: number
|
|
|
- accountNumber?: string // 添加可选的搜索字段
|
|
|
+ accountNumber?: string
|
|
|
}
|
|
|
|
|
|
interface AddAndUpdateHouseType {
|
|
|
area: string
|
|
|
address: string
|
|
|
accountNumber: string
|
|
|
+ roomType: number
|
|
|
multipartFile: File
|
|
|
}
|
|
|
|
|
|
@@ -94,8 +103,8 @@ const searchKeyword = ref('')
|
|
|
const selectedIds = ref<string[]>([])
|
|
|
const previewVisible = ref(false)
|
|
|
const previewImageUrl = ref('')
|
|
|
-const localPreviewUrl = ref('') // 本地预览URL
|
|
|
-const currentHouseType = ref<HouseType | null>(null) // 当前编辑的户型数据
|
|
|
+const localPreviewUrl = ref('')
|
|
|
+const currentHouseType = ref<HouseType | null>(null)
|
|
|
const router = useRouter()
|
|
|
|
|
|
// 分页数据
|
|
|
@@ -110,23 +119,31 @@ const formData = reactive<AddAndUpdateHouseType>({
|
|
|
area: '',
|
|
|
address: '',
|
|
|
accountNumber: '',
|
|
|
+ roomType: 1,
|
|
|
multipartFile: null as any,
|
|
|
})
|
|
|
|
|
|
-// 动态表单规则 - 编辑时为选填,新增时为必填
|
|
|
+// 动态表单规则
|
|
|
const formRules = computed(() => {
|
|
|
const isEdit = !!currentEditId.value
|
|
|
-
|
|
|
return {
|
|
|
accountNumber: isEdit ? [] : [{ required: true, message: '请输入户号', trigger: 'blur' }],
|
|
|
address: isEdit ? [] : [{ required: true, message: '请输入位置', trigger: 'blur' }],
|
|
|
area: isEdit ? [] : [{ required: true, message: '请输入面积', trigger: 'blur' }],
|
|
|
+ roomType: [{ required: true, message: '请选择户型类型', trigger: 'change' }],
|
|
|
}
|
|
|
})
|
|
|
|
|
|
const formRef = ref()
|
|
|
const uploadRef = ref()
|
|
|
|
|
|
+// 获取户型类型标签
|
|
|
+const getRoomTypeInfo = (roomType?: number) => {
|
|
|
+ return (
|
|
|
+ ROOM_TYPE_MAP[roomType as keyof typeof ROOM_TYPE_MAP] || { label: '未知', color: '#909399' }
|
|
|
+ )
|
|
|
+}
|
|
|
+
|
|
|
// 分页获取数据
|
|
|
const getList = async () => {
|
|
|
loading.value = true
|
|
|
@@ -136,7 +153,6 @@ const getList = async () => {
|
|
|
pageSize: pagination.pageSize,
|
|
|
}
|
|
|
|
|
|
- // 如果有搜索关键词,添加到请求参数中
|
|
|
if (searchKeyword.value.trim()) {
|
|
|
params.accountNumber = searchKeyword.value.trim()
|
|
|
}
|
|
|
@@ -150,7 +166,6 @@ const getList = async () => {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
- // 修改数据获取方式
|
|
|
houseTypeList.value = res.data.records || []
|
|
|
pagination.total = res.data.total || 0
|
|
|
} catch (error) {
|
|
|
@@ -193,9 +208,11 @@ const add = async (houseType: AddAndUpdateHouseType) => {
|
|
|
houseTypeFormData.append('area', houseType.area)
|
|
|
houseTypeFormData.append('address', houseType.address)
|
|
|
houseTypeFormData.append('accountNumber', houseType.accountNumber)
|
|
|
+ houseTypeFormData.append('roomType', houseType.roomType.toString())
|
|
|
houseTypeFormData.append('multipartFile', houseType.multipartFile)
|
|
|
|
|
|
const res = await clientPostFormData<FormData, BaseResponse>('/houseType/save', houseTypeFormData)
|
|
|
+
|
|
|
if (res.code !== 200) {
|
|
|
ElMessage.error(res.msg)
|
|
|
return
|
|
|
@@ -208,7 +225,6 @@ const add = async (houseType: AddAndUpdateHouseType) => {
|
|
|
// 根据id查单个
|
|
|
const findById = async (id: string) => {
|
|
|
const res = await clientGet<string, HouseTypeOneResponse>('/houseType/getById/' + id)
|
|
|
-
|
|
|
if (res.code !== 200) {
|
|
|
ElMessage.error(res.msg)
|
|
|
return null
|
|
|
@@ -223,12 +239,14 @@ const update = async (id: string, houseType: AddAndUpdateHouseType) => {
|
|
|
houseTypeFormData.append('area', houseType.area)
|
|
|
houseTypeFormData.append('address', houseType.address)
|
|
|
houseTypeFormData.append('accountNumber', houseType.accountNumber)
|
|
|
+ houseTypeFormData.append('roomType', houseType.roomType.toString())
|
|
|
houseTypeFormData.append('multipartFile', houseType.multipartFile)
|
|
|
|
|
|
const res = await clientPostFormData<FormData, BaseResponse>(
|
|
|
'/houseType/update',
|
|
|
houseTypeFormData,
|
|
|
)
|
|
|
+
|
|
|
if (res.code !== 200) {
|
|
|
ElMessage.error(res.msg)
|
|
|
return
|
|
|
@@ -258,6 +276,7 @@ const openEditDialog = async (item: HouseType) => {
|
|
|
formData.area = data.area || ''
|
|
|
formData.address = data.address || ''
|
|
|
formData.accountNumber = data.accountNumber || ''
|
|
|
+ formData.roomType = data.roomType || 1
|
|
|
}
|
|
|
|
|
|
dialogVisible.value = true
|
|
|
@@ -268,6 +287,7 @@ const resetForm = () => {
|
|
|
formData.area = ''
|
|
|
formData.address = ''
|
|
|
formData.accountNumber = ''
|
|
|
+ formData.roomType = 1
|
|
|
formData.multipartFile = null as any
|
|
|
localPreviewUrl.value = ''
|
|
|
formRef.value?.clearValidate()
|
|
|
@@ -279,7 +299,6 @@ const submitForm = async () => {
|
|
|
try {
|
|
|
await formRef.value.validate()
|
|
|
|
|
|
- // 新增时必须上传图片,编辑时可选
|
|
|
if (!currentEditId.value && !formData.multipartFile) {
|
|
|
ElMessage.warning('请上传全景图')
|
|
|
return
|
|
|
@@ -300,7 +319,6 @@ const submitForm = async () => {
|
|
|
|
|
|
// 文件上传处理
|
|
|
const handleFileChange = (file: any) => {
|
|
|
- // 检查文件大小(10MB = 10 * 1024 * 1024 bytes)
|
|
|
const maxSize = 10 * 1024 * 1024
|
|
|
if (file.raw && file.raw.size > maxSize) {
|
|
|
ElMessage.error('上传文件大小不能超过 10MB!')
|
|
|
@@ -309,16 +327,14 @@ const handleFileChange = (file: any) => {
|
|
|
|
|
|
formData.multipartFile = file.raw
|
|
|
|
|
|
- // 创建本地预览URL
|
|
|
if (file.raw) {
|
|
|
- // 清理之前的URL
|
|
|
if (localPreviewUrl.value) {
|
|
|
URL.revokeObjectURL(localPreviewUrl.value)
|
|
|
}
|
|
|
localPreviewUrl.value = URL.createObjectURL(file.raw)
|
|
|
}
|
|
|
|
|
|
- return false // 阻止自动上传
|
|
|
+ return false
|
|
|
}
|
|
|
|
|
|
// 删除单个项目
|
|
|
@@ -369,7 +385,7 @@ const handleSizeChange = (size: number) => {
|
|
|
|
|
|
// 搜索功能
|
|
|
const handleSearch = () => {
|
|
|
- pagination.pageNum = 1 // 搜索时重置到第一页
|
|
|
+ pagination.pageNum = 1
|
|
|
getList()
|
|
|
}
|
|
|
|
|
|
@@ -388,9 +404,8 @@ const enterEditRoom = (item: HouseType) => {
|
|
|
router.push({ path: '/ar/room', query: { houseTypeId: item.id } })
|
|
|
}
|
|
|
|
|
|
-//进入AR看房
|
|
|
+// 进入AR看房
|
|
|
const previewRoom = async (item: HouseType) => {
|
|
|
- //判断内部是否有房间
|
|
|
const res = await clientGet<string, RoomListResponse>('/aroom/getById/' + item.id)
|
|
|
if (res.data.length === 0) {
|
|
|
ElMessage.warning('该户型暂无房间,请添加房间后再进行查看')
|
|
|
@@ -413,12 +428,8 @@ const handleDialogClose = () => {
|
|
|
resetForm()
|
|
|
}
|
|
|
|
|
|
-const init = () => {
|
|
|
- getList()
|
|
|
-}
|
|
|
-
|
|
|
onMounted(() => {
|
|
|
- init()
|
|
|
+ getList()
|
|
|
})
|
|
|
</script>
|
|
|
|
|
|
@@ -481,32 +492,39 @@ onMounted(() => {
|
|
|
<div
|
|
|
v-for="item in houseTypeList"
|
|
|
:key="item.id"
|
|
|
- class="bg-white m-5px rounded-lg shadow-md hover:shadow-lg transition-all duration-300 overflow-hidden cursor-pointer group relative"
|
|
|
+ class="bg-white rounded-lg shadow-md hover:shadow-lg transition-all duration-300 overflow-hidden group relative"
|
|
|
:class="{ 'ring-2 ring-blue-500': selectedIds.includes(item.id) }"
|
|
|
>
|
|
|
<!-- 全景图图片 -->
|
|
|
<div class="relative h-48 bg-gray-200 overflow-hidden">
|
|
|
+ <!-- 户型类型标签 -->
|
|
|
+ <div class="absolute top-2 left-2 z-10">
|
|
|
+ <el-tag :color="getRoomTypeInfo(item.roomType).color" effect="dark" size="small">
|
|
|
+ {{ getRoomTypeInfo(item.roomType).label }}
|
|
|
+ </el-tag>
|
|
|
+ </div>
|
|
|
+
|
|
|
<!-- 图片区域的遮罩和操作按钮 -->
|
|
|
<div
|
|
|
class="absolute inset-0 bg-black bg-opacity-50 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-300 z-20"
|
|
|
>
|
|
|
- <ElRow :gutter="24" class="w-full max-w-md px-4">
|
|
|
- <ElCol :span="12" class="text-center mb-2">
|
|
|
- <el-button type="primary" round :icon="View" @click.stop="viewHouseType(item)">
|
|
|
- 查看封面
|
|
|
- </el-button>
|
|
|
- </ElCol>
|
|
|
- <ElCol :span="12" class="text-center mb-2">
|
|
|
- <el-button type="success" round :icon="Setting" @click.stop="enterEditRoom(item)">
|
|
|
- 编辑房间
|
|
|
- </el-button>
|
|
|
- </ElCol>
|
|
|
- <ElCol :span="24" class="text-center">
|
|
|
- <el-button color="#626aef" round :icon="Platform" @click.stop="previewRoom(item)">
|
|
|
- AR看房
|
|
|
- </el-button>
|
|
|
- </ElCol>
|
|
|
- </ElRow>
|
|
|
+ <div class="grid grid-cols-2 gap-4 w-full max-w-md px-4">
|
|
|
+ <el-button type="primary" round :icon="View" @click.stop="viewHouseType(item)">
|
|
|
+ 查看封面
|
|
|
+ </el-button>
|
|
|
+ <el-button type="success" round :icon="Setting" @click.stop="enterEditRoom(item)">
|
|
|
+ 编辑房间
|
|
|
+ </el-button>
|
|
|
+ <el-button
|
|
|
+ color="#626aef"
|
|
|
+ round
|
|
|
+ :icon="Platform"
|
|
|
+ @click.stop="previewRoom(item)"
|
|
|
+ class="col-span-2"
|
|
|
+ >
|
|
|
+ AR看房
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
|
|
|
<img
|
|
|
@@ -522,7 +540,7 @@ onMounted(() => {
|
|
|
|
|
|
<!-- 户型信息 -->
|
|
|
<div class="p-4">
|
|
|
- <!-- 选择框移到这里 -->
|
|
|
+ <!-- 选择框 -->
|
|
|
<div class="flex items-center justify-between mb-3">
|
|
|
<el-checkbox
|
|
|
:model-value="selectedIds.includes(item.id)"
|
|
|
@@ -554,7 +572,7 @@ onMounted(() => {
|
|
|
}}</span>
|
|
|
</div>
|
|
|
|
|
|
- <!-- 内容框内的操作按钮 -->
|
|
|
+ <!-- 操作按钮 -->
|
|
|
<div class="flex justify-end gap-2">
|
|
|
<el-button
|
|
|
type="primary"
|
|
|
@@ -612,7 +630,7 @@ onMounted(() => {
|
|
|
ref="formRef"
|
|
|
:model="formData"
|
|
|
:rules="formRules"
|
|
|
- label-width="80px"
|
|
|
+ label-width="100px"
|
|
|
label-position="left"
|
|
|
>
|
|
|
<el-form-item label="户号" prop="accountNumber">
|
|
|
@@ -629,6 +647,17 @@ onMounted(() => {
|
|
|
</el-input>
|
|
|
</el-form-item>
|
|
|
|
|
|
+ <el-form-item label="户型类型" prop="roomType">
|
|
|
+ <el-select v-model="formData.roomType" placeholder="请选择户型类型" class="w-full">
|
|
|
+ <el-option
|
|
|
+ v-for="(info, key) in ROOM_TYPE_MAP"
|
|
|
+ :key="key"
|
|
|
+ :label="info.label"
|
|
|
+ :value="Number(key)"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
<el-form-item :label="currentEditId ? '全景图' : '全景图'" :required="!currentEditId">
|
|
|
<div class="w-full">
|
|
|
<!-- 当前图片预览(编辑模式下显示原图) -->
|
|
|
@@ -710,12 +739,4 @@ onMounted(() => {
|
|
|
'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', '微软雅黑',
|
|
|
Arial, sans-serif;
|
|
|
}
|
|
|
-
|
|
|
-.el-card {
|
|
|
- transition: all 0.3s ease;
|
|
|
-}
|
|
|
-
|
|
|
-.el-card:hover {
|
|
|
- transform: translateY(-2px);
|
|
|
-}
|
|
|
</style>
|