Commit 737b703ce52c9c1e5e3e47a8c47177f7176424f3

Authored by wuxw
1 parent 81955f61

添加房屋页面开发完成

src/api/room/addRoomViewApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +import { getCommunityId } from '@/api/community/communityApi'
  3 +
  4 +// 保存房屋信息
  5 +export function saveRoom(data) {
  6 + return new Promise((resolve, reject) => {
  7 + data.communityId = getCommunityId()
  8 + request({
  9 + url: '/room.saveRoom',
  10 + method: 'post',
  11 + data
  12 + }).then(response => {
  13 + const res = response.data
  14 + resolve(res)
  15 + }).catch(error => {
  16 + reject(error)
  17 + })
  18 + })
  19 +}
  20 +
  21 +// 查询楼栋信息
  22 +export function queryFloors(params) {
  23 + return new Promise((resolve, reject) => {
  24 + params.communityId = params.communityId || getCommunityId()
  25 + request({
  26 + url: '/floor.queryFloors',
  27 + method: 'get',
  28 + params
  29 + }).then(response => {
  30 + const res = response.data
  31 + resolve(res)
  32 + }).catch(error => {
  33 + reject(error)
  34 + })
  35 + })
  36 +}
  37 +
  38 +// 查询单元信息
  39 +export function queryUnits(params) {
  40 + return new Promise((resolve, reject) => {
  41 + params.communityId = params.communityId || getCommunityId()
  42 + request({
  43 + url: '/unit.queryUnits',
  44 + method: 'get',
  45 + params
  46 + }).then(response => {
  47 + const res = response.data
  48 + resolve(res)
  49 + }).catch(error => {
  50 + reject(error)
  51 + })
  52 + })
  53 +}
  54 +
  55 +// 查询业主信息
  56 +export function queryOwners(params) {
  57 + return new Promise((resolve, reject) => {
  58 + params.communityId = params.communityId || getCommunityId()
  59 + request({
  60 + url: '/owner.queryOwners',
  61 + method: 'get',
  62 + params
  63 + }).then(response => {
  64 + const res = response.data
  65 + resolve(res)
  66 + }).catch(error => {
  67 + reject(error)
  68 + })
  69 + })
  70 +}
0 \ No newline at end of file 71 \ No newline at end of file
src/components/owner/SearchOwner.vue 0 → 100644
  1 +<template>
  2 + <el-dialog
  3 + :title="$t('searchOwner.title')"
  4 + :visible.sync="visible"
  5 + width="80%"
  6 + >
  7 + <el-card class="box-card">
  8 + <el-row :gutter="20">
  9 + <el-col :span="8">
  10 + <el-input
  11 + v-model="searchOwnerInfo.roomName"
  12 + :placeholder="$t('searchOwner.roomPlaceholder')"
  13 + clearable
  14 + ></el-input>
  15 + </el-col>
  16 + <el-col :span="8">
  17 + <el-input
  18 + v-model="searchOwnerInfo._currentOwnerName"
  19 + :placeholder="$t('searchOwner.ownerPlaceholder')"
  20 + clearable
  21 + ></el-input>
  22 + </el-col>
  23 + <el-col :span="8">
  24 + <el-button type="primary" @click="searchOwners">
  25 + <i class="el-icon-search"></i>{{ $t('common.search') }}
  26 + </el-button>
  27 + <el-button type="primary" @click="resetOwners">
  28 + {{ $t('common.reset') }}
  29 + </el-button>
  30 + </el-col>
  31 + </el-row>
  32 +
  33 + <div class="table-responsive" style="margin-top:15px">
  34 + <el-table :data="searchOwnerInfo.owners" border>
  35 + <el-table-column prop="memberId" :label="$t('searchOwner.ownerId')" align="center"></el-table-column>
  36 + <el-table-column prop="name" :label="$t('searchOwner.name')" align="center"></el-table-column>
  37 + <el-table-column prop="personTypeName" :label="$t('searchOwner.personType')" align="center"></el-table-column>
  38 + <el-table-column prop="personRoleName" :label="$t('searchOwner.personRole')" align="center"></el-table-column>
  39 + <el-table-column prop="idCard" :label="$t('searchOwner.idCard')" align="center"></el-table-column>
  40 + <el-table-column prop="link" :label="$t('searchOwner.contact')" align="center"></el-table-column>
  41 + <el-table-column :label="$t('common.operation')" align="center" width="100">
  42 + <template slot-scope="scope">
  43 + <el-button
  44 + type="primary"
  45 + size="mini"
  46 + @click="chooseOwner(scope.row)"
  47 + >{{ $t('common.select') }}</el-button>
  48 + </template>
  49 + </el-table-column>
  50 + </el-table>
  51 + </div>
  52 +
  53 + <el-pagination
  54 + @size-change="handleSizeChange"
  55 + @current-change="handleCurrentChange"
  56 + :current-page="page.current"
  57 + :page-sizes="[10, 20, 30]"
  58 + :page-size="page.size"
  59 + layout="total, sizes, prev, pager, next, jumper"
  60 + :total="page.total"
  61 + style="margin-top: 20px;"
  62 + ></el-pagination>
  63 + </el-card>
  64 + </el-dialog>
  65 +</template>
  66 +
  67 +<script>
  68 +import { queryOwners } from '@/api/room/addRoomViewApi'
  69 +import { getCommunityId } from '@/api/community/communityApi'
  70 +
  71 +export default {
  72 + name: 'SearchOwner',
  73 + data() {
  74 + return {
  75 + visible: false,
  76 + searchOwnerInfo: {
  77 + owners: [],
  78 + _currentOwnerName: '',
  79 + roomName: '',
  80 + ownerTypeCd: '1001'
  81 + },
  82 + page: {
  83 + current: 1,
  84 + size: 10,
  85 + total: 0
  86 + }
  87 + }
  88 + },
  89 + methods: {
  90 + open() {
  91 + this.visible = true
  92 + this._refreshSearchOwnerData()
  93 + this._loadAllOwnerInfo(1, 10)
  94 + },
  95 + async _loadAllOwnerInfo(page, size) {
  96 + try {
  97 + const params = {
  98 + page: page,
  99 + row: size,
  100 + communityId: getCommunityId(),
  101 + name: this.searchOwnerInfo._currentOwnerName.trim(),
  102 + roomName: this.searchOwnerInfo.roomName.trim(),
  103 + ownerTypeCd: this.searchOwnerInfo.ownerTypeCd
  104 + }
  105 +
  106 + const res = await queryOwners(params)
  107 + this.searchOwnerInfo.owners = res.data
  108 + this.page.total = res.records
  109 + this.page.current = page
  110 + this.page.size = size
  111 + } catch (error) {
  112 + console.error('获取业主信息失败:', error)
  113 + }
  114 + },
  115 + chooseOwner(owner) {
  116 + this.$emit('chooseOwner', owner)
  117 + this.visible = false
  118 + },
  119 + searchOwners() {
  120 + this._loadAllOwnerInfo(1, this.page.size)
  121 + },
  122 + resetOwners() {
  123 + this.searchOwnerInfo.roomName = ""
  124 + this.searchOwnerInfo._currentOwnerName = ""
  125 + this._loadAllOwnerInfo(1, this.page.size)
  126 + },
  127 + handleSizeChange(val) {
  128 + this.page.size = val
  129 + this._loadAllOwnerInfo(1, val)
  130 + },
  131 + handleCurrentChange(val) {
  132 + this._loadAllOwnerInfo(val, this.page.size)
  133 + },
  134 + _refreshSearchOwnerData() {
  135 + this.searchOwnerInfo = {
  136 + owners: [],
  137 + _currentOwnerName: '',
  138 + roomName: '',
  139 + ownerTypeCd: '1001'
  140 + }
  141 + this.page = {
  142 + current: 1,
  143 + size: 10,
  144 + total: 0
  145 + }
  146 + }
  147 + }
  148 +}
  149 +</script>
  150 +
  151 +<style scoped>
  152 +.table-responsive {
  153 + overflow-x: auto;
  154 +}
  155 +</style>
0 \ No newline at end of file 156 \ No newline at end of file
src/components/room/deleteRoom.vue
@@ -22,10 +22,8 @@ export default { @@ -22,10 +22,8 @@ export default {
22 } 22 }
23 }, 23 },
24 created() { 24 created() {
25 - this.$eventBus.$on('deleteRoom', this.open)  
26 }, 25 },
27 beforeDestroy() { 26 beforeDestroy() {
28 - this.$eventBus.$off('deleteRoom', this.open)  
29 }, 27 },
30 methods: { 28 methods: {
31 open(roomInfo) { 29 open(roomInfo) {
src/i18n/index.js
@@ -123,6 +123,7 @@ import { messages as roomRenovationManageMessages } from &#39;../views/community/roo @@ -123,6 +123,7 @@ import { messages as roomRenovationManageMessages } from &#39;../views/community/roo
123 import { messages as feeConfigManageMessages } from '../views/fee/feeConfigManageLang' 123 import { messages as feeConfigManageMessages } from '../views/fee/feeConfigManageLang'
124 import { messages as payFeeConfigDiscountManageMessages } from '../views/fee/payFeeConfigDiscountManageLang' 124 import { messages as payFeeConfigDiscountManageMessages } from '../views/fee/payFeeConfigDiscountManageLang'
125 import { messages as roomMessages } from '../views/room/roomLang.js' 125 import { messages as roomMessages } from '../views/room/roomLang.js'
  126 +import { messages as addRoomViewMessages } from '../views/room/addRoomViewLang'
126 127
127 128
128 Vue.use(VueI18n) 129 Vue.use(VueI18n)
@@ -251,6 +252,7 @@ const messages = { @@ -251,6 +252,7 @@ const messages = {
251 ...feeConfigManageMessages.en, 252 ...feeConfigManageMessages.en,
252 ...payFeeConfigDiscountManageMessages.en, 253 ...payFeeConfigDiscountManageMessages.en,
253 ...roomMessages.en, 254 ...roomMessages.en,
  255 + ...addRoomViewMessages.en,
254 }, 256 },
255 zh: { 257 zh: {
256 ...loginMessages.zh, 258 ...loginMessages.zh,
@@ -374,6 +376,7 @@ const messages = { @@ -374,6 +376,7 @@ const messages = {
374 ...feeConfigManageMessages.zh, 376 ...feeConfigManageMessages.zh,
375 ...payFeeConfigDiscountManageMessages.zh, 377 ...payFeeConfigDiscountManageMessages.zh,
376 ...roomMessages.zh, 378 ...roomMessages.zh,
  379 + ...addRoomViewMessages.zh,
377 } 380 }
378 } 381 }
379 382
src/router/index.js
@@ -601,6 +601,11 @@ const routes = [ @@ -601,6 +601,11 @@ const routes = [
601 name: '/pages/property/room', 601 name: '/pages/property/room',
602 component: () => import('@/views/room/roomList.vue') 602 component: () => import('@/views/room/roomList.vue')
603 }, 603 },
  604 + {
  605 + path:'/views/room/addRoomView',
  606 + name:'/views/room/addRoomView',
  607 + component: () => import('@/views/room/addRoomViewList.vue')
  608 + },
604 // 其他子路由可以在这里添加 609 // 其他子路由可以在这里添加
605 ] 610 ]
606 }, 611 },
src/views/layout/layout.vue
@@ -334,7 +334,8 @@ export default { @@ -334,7 +334,8 @@ export default {
334 334
335 .app-main { 335 .app-main {
336 background-color: #f5f7fa; 336 background-color: #f5f7fa;
337 - padding: 10px; 337 + height: calc(100vh - 60px) ;
  338 + padding: 0px;
338 } 339 }
339 340
340 :deep(.el-menu--horizontal) { 341 :deep(.el-menu--horizontal) {
src/views/room/addRoomViewLang.js 0 → 100644
  1 +export const messages = {
  2 + en: {
  3 + addRoomView: {
  4 + title: 'Add Room',
  5 + building: 'Building',
  6 + unit: 'Unit',
  7 + roomNumber: 'Room Number',
  8 + roomFloor: 'Room Floor',
  9 + roomType: 'Room Type',
  10 + rent: 'Rent',
  11 + builtUpArea: 'Built-up Area (㎡)',
  12 + roomArea: 'Room Area (㎡)',
  13 + feeCoefficient: 'Fee Coefficient',
  14 + roomStatus: 'Room Status',
  15 + owner: 'Owner',
  16 + remark: 'Remark',
  17 + selectOwner: 'Select Owner',
  18 + requiredRoomNumber: 'Required, please enter room number',
  19 + requiredRoomFloor: 'Required, please enter room floor',
  20 + requiredRent: 'Required, please enter rent',
  21 + requiredBuiltUpArea: 'Required, please enter built-up area',
  22 + requiredRoomArea: 'Required, please enter room area',
  23 + requiredFeeCoefficient: 'Required, please enter fee coefficient',
  24 + requiredOwner: 'Required, please select owner',
  25 + optionalRemark: 'Optional, please enter remark',
  26 + notSold: 'Not Sold',
  27 + living: 'Living',
  28 + delivered: 'Delivered',
  29 + decorated: 'Decorated',
  30 + notLived: 'Not Lived',
  31 + decorating: 'Decorating',
  32 + saveSuccess: 'Room added successfully',
  33 + saveError: 'Failed to add room',
  34 + validate: {
  35 + roomNumRequired: 'Room number is required',
  36 + roomNumMaxLength: 'Room number cannot exceed 64 characters',
  37 + layerRequired: 'Room floor is required',
  38 + builtUpAreaRequired: 'Built-up area is required',
  39 + builtUpAreaFormat: 'Invalid built-up area format, e.g. 300.00',
  40 + roomAreaRequired: 'Room area is required',
  41 + roomAreaFormat: 'Invalid room area format, e.g. 300.00',
  42 + feeCoefficientRequired: 'Fee coefficient is required',
  43 + feeCoefficientFormat: 'Invalid fee coefficient format, e.g. 1.00',
  44 + stateRequired: 'Room status is required',
  45 + stateMaxLength: 'Room status cannot exceed 12 characters',
  46 + roomSubTypeRequired: 'Room type is required',
  47 + remarkMaxLength: 'Remark cannot exceed 200 characters'
  48 + }
  49 + },
  50 + searchOwner: {
  51 + title: 'Select Owner',
  52 + ownerId: 'Owner ID',
  53 + name: 'Name',
  54 + personType: 'Person Type',
  55 + personRole: 'Person Role',
  56 + idCard: 'ID Card',
  57 + contact: 'Contact',
  58 + operation: 'Operation',
  59 + roomPlaceholder: 'Enter room number (Building-Unit-Room)',
  60 + ownerPlaceholder: 'Enter owner name'
  61 + }
  62 + },
  63 + zh: {
  64 + addRoomView: {
  65 + title: '添加房屋',
  66 + building: '楼栋',
  67 + unit: '单元',
  68 + roomNumber: '房屋编号',
  69 + roomFloor: '房屋楼层',
  70 + roomType: '房屋类型',
  71 + rent: '租金',
  72 + builtUpArea: '建筑面积(平方)',
  73 + roomArea: '室内面积(平方)',
  74 + feeCoefficient: '算费系数',
  75 + roomStatus: '房屋状态',
  76 + owner: '业主',
  77 + remark: '备注',
  78 + selectOwner: '选择业主',
  79 + requiredRoomNumber: '必填,请填写房屋编号',
  80 + requiredRoomFloor: '必填,请填写房屋楼层',
  81 + requiredRent: '必填,请填写租金',
  82 + requiredBuiltUpArea: '必填,请填写建筑面积',
  83 + requiredRoomArea: '必填,请填写室内面积',
  84 + requiredFeeCoefficient: '必填,请填写算费系数',
  85 + requiredOwner: '必填,请选择业主',
  86 + optionalRemark: '选填,请填写备注',
  87 + notSold: '未销售',
  88 + living: '已入住',
  89 + delivered: '已交房',
  90 + decorated: '已装修',
  91 + notLived: '未入住',
  92 + decorating: '装修中',
  93 + saveSuccess: '房屋添加成功',
  94 + saveError: '房屋添加失败',
  95 + validate: {
  96 + roomNumRequired: '房屋编号不能为空',
  97 + roomNumMaxLength: '房屋编号长度不能超过64位',
  98 + layerRequired: '房屋楼层不能为空',
  99 + builtUpAreaRequired: '建筑面积不能为空',
  100 + builtUpAreaFormat: '建筑面积错误,如 300.00',
  101 + roomAreaRequired: '室内面积不能为空',
  102 + roomAreaFormat: '室内面积错误,如 300.00',
  103 + feeCoefficientRequired: '算费系数不能为空',
  104 + feeCoefficientFormat: '算费系数错误,如 1.00',
  105 + stateRequired: '房屋状态不能为空',
  106 + stateMaxLength: '房屋状态不能超过12位',
  107 + roomSubTypeRequired: '房屋类型不能为空',
  108 + remarkMaxLength: '备注内容不能超过200'
  109 + }
  110 + },
  111 + searchOwner: {
  112 + title: '选择业主',
  113 + ownerId: '业主编号',
  114 + name: '名称',
  115 + personType: '人员类型',
  116 + personRole: '人员角色',
  117 + idCard: '证件号',
  118 + contact: '联系方式',
  119 + operation: '操作',
  120 + roomPlaceholder: '输入房屋编号楼栋-单元-房屋',
  121 + ownerPlaceholder: '输入业主名称'
  122 + }
  123 + }
  124 +}
0 \ No newline at end of file 125 \ No newline at end of file
src/views/room/addRoomViewList.vue 0 → 100644
  1 +<template>
  2 + <div class="add-room-view-container">
  3 + <el-card class="box-card">
  4 + <div slot="header" class="clearfix">
  5 + <h5>{{ $t('addRoomView.title') }}</h5>
  6 + <div class="ibox-tools">
  7 + <el-button type="primary" size="small" @click="_goBack">
  8 + <i class="el-icon-close"></i>{{ $t('common.back') }}
  9 + </el-button>
  10 + </div>
  11 + </div>
  12 + <el-form :model="addRoomViewInfo" label-position="right" label-width="120px">
  13 + <el-row :gutter="20">
  14 + <el-col :span="12">
  15 + <el-form-item :label="$t('addRoomView.building')">
  16 + <el-select v-model="addRoomViewInfo.floorId" @change="_loadUnit" placeholder="必填,请选择楼栋" style="width:100%">
  17 + <el-option v-for="(floor, index) in addRoomViewInfo.floors" :key="index" :label="floor.floorName"
  18 + :value="floor.floorId"></el-option>
  19 + </el-select>
  20 + </el-form-item>
  21 + </el-col>
  22 + <el-col :span="12">
  23 + <el-form-item :label="$t('addRoomView.unit')">
  24 + <el-select v-model="addRoomViewInfo.unitId" placeholder="必填,请选择单元" style="width:100%">
  25 + <template v-for="(unit, index) in addRoomViewInfo.units">
  26 + <el-option v-if="unit.unitNum != '0'" :key="index" :label="unit.unitNum"
  27 + :value="unit.unitId"></el-option>
  28 + </template>
  29 + </el-select>
  30 +
  31 + </el-form-item>
  32 + </el-col>
  33 + </el-row>
  34 +
  35 + <el-row :gutter="20">
  36 + <el-col :span="12">
  37 + <el-form-item :label="$t('addRoomView.roomNumber')">
  38 + <el-input v-model="addRoomViewInfo.roomNum" :placeholder="$t('addRoomView.requiredRoomNumber')"></el-input>
  39 + </el-form-item>
  40 + </el-col>
  41 + <el-col :span="12">
  42 + <el-form-item :label="$t('addRoomView.roomFloor')">
  43 + <el-input v-model="addRoomViewInfo.layer" :placeholder="$t('addRoomView.requiredRoomFloor')"></el-input>
  44 + </el-form-item>
  45 + </el-col>
  46 + </el-row>
  47 +
  48 + <el-row :gutter="20">
  49 + <el-col :span="12">
  50 + <el-form-item :label="$t('addRoomView.roomType')">
  51 + <el-select v-model="addRoomViewInfo.roomSubType" placeholder="必填,请选择房屋类型" style="width:100%">
  52 + <el-option v-for="(item, index) in addRoomViewInfo.roomSubTypes" :key="index" :label="item.name"
  53 + :value="item.statusCd"></el-option>
  54 + </el-select>
  55 + </el-form-item>
  56 + </el-col>
  57 + <el-col :span="12" v-if="addRoomViewInfo.roomSubType != '110'">
  58 + <el-form-item :label="$t('addRoomView.rent')">
  59 + <el-input v-model="addRoomViewInfo.roomRent" :placeholder="$t('addRoomView.requiredRent')"></el-input>
  60 + </el-form-item>
  61 + </el-col>
  62 + </el-row>
  63 +
  64 + <el-row :gutter="20">
  65 + <el-col :span="12">
  66 + <el-form-item :label="$t('addRoomView.builtUpArea')">
  67 + <el-input v-model="addRoomViewInfo.builtUpArea"
  68 + :placeholder="$t('addRoomView.requiredBuiltUpArea')"></el-input>
  69 + </el-form-item>
  70 + </el-col>
  71 + <el-col :span="12">
  72 + <el-form-item :label="$t('addRoomView.roomArea')">
  73 + <el-input v-model="addRoomViewInfo.roomArea" :placeholder="$t('addRoomView.requiredRoomArea')"></el-input>
  74 + </el-form-item>
  75 + </el-col>
  76 + </el-row>
  77 +
  78 + <el-row :gutter="20">
  79 + <el-col :span="12">
  80 + <el-form-item :label="$t('addRoomView.feeCoefficient')">
  81 + <el-input v-model="addRoomViewInfo.feeCoefficient"
  82 + :placeholder="$t('addRoomView.requiredFeeCoefficient')"></el-input>
  83 + </el-form-item>
  84 + </el-col>
  85 + <el-col :span="12">
  86 + <el-form-item :label="$t('addRoomView.roomStatus')">
  87 + <el-select v-model="addRoomViewInfo.state" placeholder="必填,请选择房屋状态" style="width:100%">
  88 + <el-option value="2002" :label="$t('addRoomView.notSold')"></el-option>
  89 + <el-option value="2001" :label="$t('addRoomView.living')"></el-option>
  90 + <el-option value="2003" :label="$t('addRoomView.delivered')"></el-option>
  91 + <el-option value="2005" :label="$t('addRoomView.decorated')"></el-option>
  92 + <el-option value="2004" :label="$t('addRoomView.notLived')"></el-option>
  93 + <el-option value="2009" :label="$t('addRoomView.decorating')"></el-option>
  94 + </el-select>
  95 + </el-form-item>
  96 + </el-col>
  97 + </el-row>
  98 +
  99 + <el-row :gutter="20" v-if="addRoomViewInfo.state != '2002'">
  100 + <el-col :span="12">
  101 + <el-form-item :label="$t('addRoomView.owner')">
  102 + <el-input v-model="addRoomViewInfo.ownerName" disabled
  103 + :placeholder="$t('addRoomView.requiredOwner')"></el-input>
  104 + </el-form-item>
  105 + </el-col>
  106 + <el-col :span="4">
  107 + <el-button type="primary" size="small" @click="_openChooseOwner">{{ $t('addRoomView.selectOwner')
  108 + }}</el-button>
  109 + </el-col>
  110 + </el-row>
  111 +
  112 + <div v-for="(item, index) in addRoomViewInfo.attrs" :key="index">
  113 + <el-row :gutter="20" v-if="item.specType == '2233'">
  114 + <el-col :span="12">
  115 + <el-form-item :label="item.specName">
  116 + <el-input v-model="item.value" :placeholder="item.specHoldplace"></el-input>
  117 + </el-form-item>
  118 + </el-col>
  119 + </el-row>
  120 + <el-row :gutter="20" v-if="item.specType == '3344'">
  121 + <el-col :span="12">
  122 + <el-form-item :label="item.specName">
  123 + <el-select v-model="item.value" :placeholder="item.specHoldplace" style="width:100%">
  124 + <el-option v-for="value in item.values" :key="value.value" :label="value.valueName"
  125 + :value="value.value"></el-option>
  126 + </el-select>
  127 + </el-form-item>
  128 + </el-col>
  129 + </el-row>
  130 + </div>
  131 +
  132 + <el-row :gutter="20">
  133 + <el-col :span="12">
  134 + <el-form-item :label="$t('addRoomView.remark')">
  135 + <el-input type="textarea" :placeholder="$t('addRoomView.optionalRemark')"
  136 + v-model="addRoomViewInfo.remark"></el-input>
  137 + </el-form-item>
  138 + </el-col>
  139 + </el-row>
  140 + </el-form>
  141 + </el-card>
  142 +
  143 + <div class="text-right" style="margin-top:20px">
  144 + <el-button type="warning" style="margin-right:20px;" @click="_goBack">
  145 + {{ $t('common.back') }}
  146 + </el-button>
  147 + <el-button type="primary" @click="saveAddRoomInfo">
  148 + <i class="el-icon-check"></i>{{ $t('common.submit') }}
  149 + </el-button>
  150 + </div>
  151 +
  152 + <search-owner ref="searchOwner" @chooseOwner="chooseOwner"></search-owner>
  153 + </div>
  154 +</template>
  155 +
  156 +<script>
  157 +import { saveRoom, queryFloors, queryUnits } from '@/api/room/addRoomViewApi'
  158 +import { getDict } from '@/api/community/communityApi'
  159 +import { getCommunityId } from '@/api/community/communityApi'
  160 +import SearchOwner from '@/components/owner/SearchOwner'
  161 +
  162 +export default {
  163 + name: 'AddRoomViewList',
  164 + components: { SearchOwner },
  165 + data() {
  166 + return {
  167 + addRoomViewInfo: {
  168 + roomNum: '',
  169 + layer: '',
  170 + section: '0',
  171 + apartment: '10102',
  172 + builtUpArea: '',
  173 + feeCoefficient: '1.00',
  174 + state: '2002',
  175 + remark: '',
  176 + roomSubType: '110',
  177 + roomArea: '',
  178 + roomRent: '0',
  179 + unitPrice: '0',
  180 + floorId: '',
  181 + unitId: '',
  182 + ownerId: '',
  183 + ownerName: '',
  184 + communityId: '',
  185 + attrs: [],
  186 + roomSubTypes: [],
  187 + floors: [],
  188 + units: []
  189 + }
  190 + }
  191 + },
  192 + created() {
  193 + this.addRoomViewInfo.communityId = getCommunityId()
  194 + this._loadRoomAttrSpec()
  195 + this._loadDictData()
  196 + this._loadFloor()
  197 + },
  198 + methods: {
  199 + async _loadDictData() {
  200 + try {
  201 + const data = await getDict('building_room', 'room_sub_type')
  202 + this.addRoomViewInfo.roomSubTypes = data
  203 + } catch (error) {
  204 + console.error('获取字典数据失败:', error)
  205 + }
  206 + },
  207 + async _loadRoomAttrSpec() {
  208 + try {
  209 + this.addRoomViewInfo.attrs = []
  210 + const data = await getDict('building_room_attr', '')
  211 + data.forEach(item => {
  212 + item.value = ''
  213 + if (item.specShow == 'Y') {
  214 + item.values = []
  215 + this._loadAttrValue(item.specCd, item.values)
  216 + this.addRoomViewInfo.attrs.push(item)
  217 + }
  218 + })
  219 + } catch (error) {
  220 + console.error('获取属性规格失败:', error)
  221 + }
  222 + },
  223 + async _loadAttrValue(specCd, values) {
  224 + try {
  225 + const data = await getDict('attr_value', specCd)
  226 + data.forEach(item => {
  227 + if (item.valueShow == 'Y') {
  228 + values.push(item)
  229 + }
  230 + })
  231 + } catch (error) {
  232 + console.error('获取属性值失败:', error)
  233 + }
  234 + },
  235 + addRoomValidate() {
  236 + const rules = {
  237 + 'addRoomViewInfo.roomNum': [
  238 + { required: true, message: this.$t('addRoomView.validate.roomNumRequired') },
  239 + { max: 64, message: this.$t('addRoomView.validate.roomNumMaxLength') }
  240 + ],
  241 + 'addRoomViewInfo.layer': [
  242 + { required: true, message: this.$t('addRoomView.validate.layerRequired') }
  243 + ],
  244 + 'addRoomViewInfo.builtUpArea': [
  245 + { required: true, message: this.$t('addRoomView.validate.builtUpAreaRequired') },
  246 + { pattern: /^\d+(\.\d{1,2})?$/, message: this.$t('addRoomView.validate.builtUpAreaFormat') }
  247 + ],
  248 + 'addRoomViewInfo.roomArea': [
  249 + { required: true, message: this.$t('addRoomView.validate.roomAreaRequired') },
  250 + { pattern: /^\d+(\.\d{1,2})?$/, message: this.$t('addRoomView.validate.roomAreaFormat') }
  251 + ],
  252 + 'addRoomViewInfo.feeCoefficient': [
  253 + { required: true, message: this.$t('addRoomView.validate.feeCoefficientRequired') },
  254 + { pattern: /^\d+(\.\d{1,2})?$/, message: this.$t('addRoomView.validate.feeCoefficientFormat') }
  255 + ],
  256 + 'addRoomViewInfo.state': [
  257 + { required: true, message: this.$t('addRoomView.validate.stateRequired') },
  258 + { max: 12, message: this.$t('addRoomView.validate.stateMaxLength') }
  259 + ],
  260 + 'addRoomViewInfo.roomSubType': [
  261 + { required: true, message: this.$t('addRoomView.validate.roomSubTypeRequired') }
  262 + ],
  263 + 'addRoomViewInfo.remark': [
  264 + { max: 200, message: this.$t('addRoomView.validate.remarkMaxLength') }
  265 + ]
  266 + }
  267 +
  268 + for (const field in rules) {
  269 + const value = this._getNestedValue(field)
  270 + const fieldRules = rules[field]
  271 +
  272 + for (const rule of fieldRules) {
  273 + if (rule.required && (value === undefined || value === null || value === '')) {
  274 + this.$message.error(rule.message)
  275 + return false
  276 + }
  277 + if (rule.max && value && value.length > rule.max) {
  278 + this.$message.error(rule.message)
  279 + return false
  280 + }
  281 + if (rule.pattern && value && !rule.pattern.test(value)) {
  282 + this.$message.error(rule.message)
  283 + return false
  284 + }
  285 + }
  286 + }
  287 +
  288 + return true
  289 + },
  290 + _getNestedValue(path) {
  291 + return path.split('.').reduce((obj, key) => (obj ? obj[key] : undefined), this)
  292 + },
  293 + async saveAddRoomInfo() {
  294 + // 验证必填属性
  295 + let msg = ''
  296 + this.addRoomViewInfo.attrs.forEach((item) => {
  297 + if (item.required == 'Y' && !item.value) {
  298 + msg = item.specHoldplace
  299 + }
  300 + })
  301 + if (msg) {
  302 + this.$message.error(msg)
  303 + return
  304 + }
  305 +
  306 + // 表单验证
  307 + if (!this.addRoomValidate()) return
  308 +
  309 + try {
  310 + await saveRoom(this.addRoomViewInfo)
  311 + this.$message.success(this.$t('addRoomView.saveSuccess'))
  312 + this._goBack()
  313 + } catch (error) {
  314 + console.error('保存失败:', error)
  315 + this.$message.error(error.message || this.$t('addRoomView.saveError'))
  316 + }
  317 + },
  318 + _goBack() {
  319 + this.$router.go(-1)
  320 + },
  321 + _openChooseOwner() {
  322 + this.$refs.searchOwner.open()
  323 + },
  324 + chooseOwner(owner) {
  325 + this.addRoomViewInfo.ownerName = owner.name
  326 + this.addRoomViewInfo.ownerId = owner.ownerId
  327 + },
  328 + async _loadFloor() {
  329 + try {
  330 + const params = {
  331 + page: 1,
  332 + row: 300,
  333 + communityId: this.addRoomViewInfo.communityId
  334 + }
  335 + const data = await queryFloors(params)
  336 + this.addRoomViewInfo.floors = data.apiFloorDataVoList || []
  337 + } catch (error) {
  338 + console.error('获取楼栋信息失败:', error)
  339 + }
  340 + },
  341 + async _loadUnit() {
  342 + if (!this.addRoomViewInfo.floorId) return
  343 + this.addRoomViewInfo.unitId=''
  344 + try {
  345 + const params = {
  346 + page: 1,
  347 + row: 300,
  348 + communityId: this.addRoomViewInfo.communityId,
  349 + floorId: this.addRoomViewInfo.floorId
  350 + }
  351 + const data = await queryUnits(params)
  352 + this.addRoomViewInfo.units = data || []
  353 + } catch (error) {
  354 + console.error('获取单元信息失败:', error)
  355 + }
  356 + }
  357 + }
  358 +}
  359 +</script>
  360 +
  361 +<style scoped>
  362 +.add-room-view-container {
  363 + padding: 20px;
  364 +}
  365 +
  366 +.text-right {
  367 + text-align: right;
  368 + margin-top: 20px;
  369 +}
  370 +
  371 +.ibox-tools {
  372 + position: absolute;
  373 + right: 15px;
  374 + top: 10px;
  375 +}
  376 +</style>
0 \ No newline at end of file 377 \ No newline at end of file
src/views/room/roomList.vue
@@ -505,7 +505,7 @@ export default { @@ -505,7 +505,7 @@ export default {
505 }, 505 },
506 // 按钮操作相关方法 506 // 按钮操作相关方法
507 openAddRoom() { 507 openAddRoom() {
508 - this.$router.push('/pages/property/addRoomView') 508 + this.$router.push('/views/room/addRoomView')
509 }, 509 },
510 510
511 openEditRoomModel(room) { 511 openEditRoomModel(room) {