Commit 8fc7c7915a883bd2d7b5251e621aa2d5803fbb2b
1 parent
81ca23ff
测试完成房屋装修模块
Showing
16 changed files
with
1036 additions
and
105 deletions
src/api/community/listRoomDecorationRecordApi.js
0 → 100644
| 1 | +import request from '@/utils/request' | |
| 2 | + | |
| 3 | +// 查询装修跟踪记录列表 | |
| 4 | +export function queryRoomRenovationRecord(params) { | |
| 5 | + return new Promise((resolve, reject) => { | |
| 6 | + request({ | |
| 7 | + url: '/roomRenovation/queryRoomRenovationRecord', | |
| 8 | + method: 'get', | |
| 9 | + params | |
| 10 | + }).then(response => { | |
| 11 | + const res = response.data | |
| 12 | + resolve(res) | |
| 13 | + }).catch(error => { | |
| 14 | + reject(error) | |
| 15 | + }) | |
| 16 | + }) | |
| 17 | +} | |
| 18 | + | |
| 19 | +// 更新装修跟踪记录 | |
| 20 | +export function updateRoomDecorationRecord(data) { | |
| 21 | + return new Promise((resolve, reject) => { | |
| 22 | + request({ | |
| 23 | + url: '/roomRenovation/updateRoomDecorationRecord', | |
| 24 | + method: 'post', | |
| 25 | + data | |
| 26 | + }).then(response => { | |
| 27 | + const res = response.data | |
| 28 | + resolve(res) | |
| 29 | + }).catch(error => { | |
| 30 | + reject(error) | |
| 31 | + }) | |
| 32 | + }) | |
| 33 | +} | |
| 34 | + | |
| 35 | +// 删除装修跟踪记录 | |
| 36 | +export function deleteRoomRenovationRecord(data) { | |
| 37 | + return new Promise((resolve, reject) => { | |
| 38 | + request({ | |
| 39 | + url: '/roomRenovation/deleteRoomRenovationRecord', | |
| 40 | + method: 'post', | |
| 41 | + data | |
| 42 | + }).then(response => { | |
| 43 | + const res = response.data | |
| 44 | + resolve(res) | |
| 45 | + }).catch(error => { | |
| 46 | + reject(error) | |
| 47 | + }) | |
| 48 | + }) | |
| 49 | +} | |
| 50 | + | |
| 51 | +// 上传图片 | |
| 52 | +export function uploadImage(data) { | |
| 53 | + return new Promise((resolve, reject) => { | |
| 54 | + request({ | |
| 55 | + url: '/uploadImage', | |
| 56 | + method: 'post', | |
| 57 | + data, | |
| 58 | + headers: { | |
| 59 | + 'Content-Type': 'multipart/form-data' | |
| 60 | + } | |
| 61 | + }).then(response => { | |
| 62 | + const res = response.data | |
| 63 | + resolve(res) | |
| 64 | + }).catch(error => { | |
| 65 | + reject(error) | |
| 66 | + }) | |
| 67 | + }) | |
| 68 | +} | |
| 69 | + | |
| 70 | +// 上传视频 | |
| 71 | +export function uploadVedio(data, config) { | |
| 72 | + return new Promise((resolve, reject) => { | |
| 73 | + request({ | |
| 74 | + url: '/uploadVedio', | |
| 75 | + method: 'post', | |
| 76 | + data, | |
| 77 | + headers: { | |
| 78 | + 'Content-Type': 'multipart/form-data' | |
| 79 | + }, | |
| 80 | + ...config | |
| 81 | + }).then(response => { | |
| 82 | + const res = response.data | |
| 83 | + resolve(res) | |
| 84 | + }).catch(error => { | |
| 85 | + reject(error) | |
| 86 | + }) | |
| 87 | + }) | |
| 88 | +} | |
| 0 | 89 | \ No newline at end of file | ... | ... |
src/api/community/listRoomRenovationRecordDetailsApi.js
0 → 100644
| 1 | +import request from '@/utils/request' | |
| 2 | +import { getCommunityId } from '@/api/community/communityApi' | |
| 3 | + | |
| 4 | +/** | |
| 5 | + * 查询房屋装修记录详情 | |
| 6 | + * @param {Object} params 查询参数 | |
| 7 | + * @param {string} params.recordId 记录ID | |
| 8 | + * @param {string} params.roomName 房间名称 | |
| 9 | + * @param {string} params.state 状态 | |
| 10 | + * @param {string} params.roomId 房间ID | |
| 11 | + * @param {number} params.page 页码 | |
| 12 | + * @param {number} params.row 每页条数 | |
| 13 | + * @returns {Promise} 返回Promise对象 | |
| 14 | + */ | |
| 15 | +export function queryRoomRenovationRecordDetail(params) { | |
| 16 | + return new Promise((resolve, reject) => { | |
| 17 | + // 确保有communityId | |
| 18 | + const queryParams = { | |
| 19 | + ...params, | |
| 20 | + communityId: params.communityId || getCommunityId() | |
| 21 | + } | |
| 22 | + | |
| 23 | + request({ | |
| 24 | + url: '/roomRenovation/queryRoomRenovationRecordDetail', | |
| 25 | + method: 'get', | |
| 26 | + params: queryParams | |
| 27 | + }).then(response => { | |
| 28 | + const res = response.data | |
| 29 | + resolve({ | |
| 30 | + data: res.data, | |
| 31 | + total: res.total, | |
| 32 | + records: res.records | |
| 33 | + }) | |
| 34 | + }).catch(error => { | |
| 35 | + reject(error) | |
| 36 | + }) | |
| 37 | + }) | |
| 38 | +} | |
| 0 | 39 | \ No newline at end of file | ... | ... |
src/components/community/DeleteRoomDecorationRecord.vue
0 → 100644
| 1 | +<template> | |
| 2 | + <el-dialog | |
| 3 | + :title="$t('deleteRoomDecorationRecord.title')" | |
| 4 | + :visible.sync="visible" | |
| 5 | + width="30%" | |
| 6 | + @close="handleClose" | |
| 7 | + > | |
| 8 | + <div class="confirm-message"> | |
| 9 | + {{ $t('deleteRoomDecorationRecord.confirm') }} | |
| 10 | + </div> | |
| 11 | + <div slot="footer" class="dialog-footer"> | |
| 12 | + <el-button @click="visible = false"> | |
| 13 | + {{ $t('deleteRoomDecorationRecord.cancel') }} | |
| 14 | + </el-button> | |
| 15 | + <el-button type="primary" @click="confirmDelete"> | |
| 16 | + {{ $t('deleteRoomDecorationRecord.confirmDelete') }} | |
| 17 | + </el-button> | |
| 18 | + </div> | |
| 19 | + </el-dialog> | |
| 20 | +</template> | |
| 21 | + | |
| 22 | +<script> | |
| 23 | +import { deleteRoomRenovationRecord } from '@/api/community/listRoomDecorationRecordApi' | |
| 24 | +import { getCommunityId } from '@/api/community/communityApi' | |
| 25 | + | |
| 26 | +export default { | |
| 27 | + name: 'DeleteRoomDecorationRecord', | |
| 28 | + data() { | |
| 29 | + return { | |
| 30 | + visible: false, | |
| 31 | + record: {} | |
| 32 | + } | |
| 33 | + }, | |
| 34 | + methods: { | |
| 35 | + open(record) { | |
| 36 | + this.record = { ...record } | |
| 37 | + this.visible = true | |
| 38 | + }, | |
| 39 | + handleClose() { | |
| 40 | + this.record = {} | |
| 41 | + }, | |
| 42 | + async confirmDelete() { | |
| 43 | + try { | |
| 44 | + this.record.communityId = getCommunityId() | |
| 45 | + await deleteRoomRenovationRecord(this.record) | |
| 46 | + this.$message.success(this.$t('deleteRoomDecorationRecord.success')) | |
| 47 | + this.$emit('success') | |
| 48 | + this.visible = false | |
| 49 | + } catch (error) { | |
| 50 | + this.$message.error(this.$t('deleteRoomDecorationRecord.failed')) | |
| 51 | + } | |
| 52 | + } | |
| 53 | + } | |
| 54 | +} | |
| 55 | +</script> | |
| 56 | + | |
| 57 | +<style lang="scss" scoped> | |
| 58 | +.confirm-message { | |
| 59 | + text-align: center; | |
| 60 | + font-size: 16px; | |
| 61 | + margin-bottom: 20px; | |
| 62 | +} | |
| 63 | +</style> | |
| 0 | 64 | \ No newline at end of file | ... | ... |
src/components/community/RoomDecorationRecord.vue
0 → 100644
| 1 | +<template> | |
| 2 | + <el-dialog :title="$t('roomDecorationRecord.title')" :visible.sync="visible" width="40%" @close="handleClose"> | |
| 3 | + <el-form ref="form" :model="roomDecorationRecordInfo" label-width="120px" class="text-left" label-position="left"> | |
| 4 | + <el-form-item :label="$t('roomDecorationRecord.room')"> | |
| 5 | + <el-input v-model="roomDecorationRecordInfo.roomName" disabled | |
| 6 | + :placeholder="$t('roomDecorationRecord.roomPlaceholder')" /> | |
| 7 | + </el-form-item> | |
| 8 | + <el-form-item :label="$t('roomDecorationRecord.status')"> | |
| 9 | + <el-input v-model="roomDecorationRecordInfo.stateName" disabled /> | |
| 10 | + </el-form-item> | |
| 11 | + <el-form-item :label="$t('roomDecorationRecord.isViolation')" required> | |
| 12 | + <el-select v-model="roomDecorationRecordInfo.isTrue" style="width: 100%" | |
| 13 | + :placeholder="$t('roomDecorationRecord.isViolationPlaceholder')"> | |
| 14 | + <el-option value="" disabled :label="$t('roomDecorationRecord.isViolationPlaceholder')" /> | |
| 15 | + <el-option value="true" :label="$t('roomDecorationRecord.yes')" /> | |
| 16 | + <el-option value="false" :label="$t('roomDecorationRecord.no')" /> | |
| 17 | + </el-select> | |
| 18 | + </el-form-item> | |
| 19 | + <el-form-item :label="$t('roomDecorationRecord.remark')" required> | |
| 20 | + <el-input v-model="roomDecorationRecordInfo.remark" type="textarea" | |
| 21 | + :placeholder="$t('roomDecorationRecord.remarkPlaceholder')" :rows="3" /> | |
| 22 | + </el-form-item> | |
| 23 | + <el-form-item :label="$t('roomDecorationRecord.uploadImage')"> | |
| 24 | + <upload-image-url ref="uploadImageUrl" :image-count="99" @notifyUploadCoverImage="handleImageChange" /> | |
| 25 | + </el-form-item> | |
| 26 | + <el-form-item :label="$t('roomDecorationRecord.uploadVideo')"> | |
| 27 | + <upload-vedio ref="uploadVedio" @change="handleVideoChange" /> | |
| 28 | + </el-form-item> | |
| 29 | + </el-form> | |
| 30 | + <div slot="footer" class="dialog-footer"> | |
| 31 | + <el-button @click="visible = false"> | |
| 32 | + {{ $t('common.cancel') }} | |
| 33 | + </el-button> | |
| 34 | + <el-button type="primary" @click="saveRoomDecorationRecordInfo"> | |
| 35 | + {{ $t('common.save') }} | |
| 36 | + </el-button> | |
| 37 | + </div> | |
| 38 | + </el-dialog> | |
| 39 | +</template> | |
| 40 | + | |
| 41 | +<script> | |
| 42 | +import { updateRoomDecorationRecord } from '@/api/community/listRoomDecorationRecordApi' | |
| 43 | +import { getCommunityId } from '@/api/community/communityApi' | |
| 44 | +import UploadImageUrl from '@/components/upload/UploadImageUrl' | |
| 45 | +import UploadVedio from './UploadVedio' | |
| 46 | + | |
| 47 | +export default { | |
| 48 | + name: 'RoomDecorationRecord', | |
| 49 | + components: { | |
| 50 | + UploadImageUrl, | |
| 51 | + UploadVedio | |
| 52 | + }, | |
| 53 | + props: { | |
| 54 | + callBackListener: { | |
| 55 | + type: String, | |
| 56 | + default: '' | |
| 57 | + }, | |
| 58 | + callBackFunction: { | |
| 59 | + type: String, | |
| 60 | + default: '' | |
| 61 | + } | |
| 62 | + }, | |
| 63 | + data() { | |
| 64 | + return { | |
| 65 | + visible: false, | |
| 66 | + roomDecorationRecordInfo: { | |
| 67 | + rId: '', | |
| 68 | + roomName: '', | |
| 69 | + state: '', | |
| 70 | + stateName: '', | |
| 71 | + remark: '', | |
| 72 | + examineRemark: '', | |
| 73 | + roomId: '', | |
| 74 | + photos: [], | |
| 75 | + videoName: '', | |
| 76 | + url: '', | |
| 77 | + detailType: '1001', | |
| 78 | + isTrue: '', | |
| 79 | + isTrues: [] | |
| 80 | + } | |
| 81 | + } | |
| 82 | + }, | |
| 83 | + methods: { | |
| 84 | + open(params) { | |
| 85 | + this.clearRoomDecorationRecordInfo() | |
| 86 | + this.roomDecorationRecordInfo.rId = params[0] | |
| 87 | + this.roomDecorationRecordInfo.roomId = params[1] | |
| 88 | + this.roomDecorationRecordInfo.roomName = params[2] | |
| 89 | + this.roomDecorationRecordInfo.state = params[3] | |
| 90 | + this.roomDecorationRecordInfo.stateName = params[4] | |
| 91 | + this.visible = true | |
| 92 | + }, | |
| 93 | + handleClose() { | |
| 94 | + this.clearRoomDecorationRecordInfo() | |
| 95 | + }, | |
| 96 | + handleImageChange(photosUrl) { | |
| 97 | + this.roomDecorationRecordInfo.photos = photosUrl.map(item => item.fileId) | |
| 98 | + }, | |
| 99 | + handleVideoChange(videoInfo) { | |
| 100 | + this.roomDecorationRecordInfo.videoName = videoInfo.realFileName | |
| 101 | + }, | |
| 102 | + validateForm() { | |
| 103 | + if (!this.roomDecorationRecordInfo.isTrue) { | |
| 104 | + this.$message.error(this.$t('roomDecorationRecord.isViolationRequired')) | |
| 105 | + return false | |
| 106 | + } | |
| 107 | + if (!this.roomDecorationRecordInfo.remark) { | |
| 108 | + this.$message.error(this.$t('roomDecorationRecord.remarkRequired')) | |
| 109 | + return false | |
| 110 | + } | |
| 111 | + return true | |
| 112 | + }, | |
| 113 | + async saveRoomDecorationRecordInfo() { | |
| 114 | + if (!this.validateForm()) return | |
| 115 | + | |
| 116 | + try { | |
| 117 | + this.roomDecorationRecordInfo.communityId = getCommunityId() | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + await updateRoomDecorationRecord(this.roomDecorationRecordInfo) | |
| 122 | + this.$message.success(this.$t('common.saveSuccess')) | |
| 123 | + this.$emit('success') | |
| 124 | + this.visible = false | |
| 125 | + } catch (error) { | |
| 126 | + this.$message.error(this.$t('common.saveFailed')) | |
| 127 | + } | |
| 128 | + }, | |
| 129 | + clearRoomDecorationRecordInfo() { | |
| 130 | + setTimeout(() => { | |
| 131 | + this.$refs.uploadImageUrl.clearImages() | |
| 132 | + this.$refs.uploadVedio.clear() | |
| 133 | + },100) | |
| 134 | + this.roomDecorationRecordInfo = { | |
| 135 | + rId: '', | |
| 136 | + state: '', | |
| 137 | + remark: '', | |
| 138 | + examineRemark: '', | |
| 139 | + roomId: '', | |
| 140 | + photos: [], | |
| 141 | + videoName: '', | |
| 142 | + detailType: '1001', | |
| 143 | + isTrue: '', | |
| 144 | + isTrues: [] | |
| 145 | + } | |
| 146 | + } | |
| 147 | + } | |
| 148 | +} | |
| 149 | +</script> | |
| 0 | 150 | \ No newline at end of file | ... | ... |
src/components/community/RoomToExamine.vue
| 1 | 1 | <template> |
| 2 | - <el-dialog | |
| 3 | - :title="$t('roomRenovationManage.review')" | |
| 4 | - :visible.sync="visible" | |
| 5 | - width="40%" | |
| 6 | - @close="resetForm" | |
| 7 | - > | |
| 2 | + <el-dialog :title="$t('roomRenovationManage.review')" :visible.sync="visible" width="40%" @close="resetForm"> | |
| 8 | 3 | <el-form :model="form" ref="form" label-width="120px"> |
| 9 | 4 | <el-form-item :label="$t('roomRenovationManage.room')" prop="roomName"> |
| 10 | - <el-input | |
| 11 | - v-model.trim="form.roomName" | |
| 12 | - disabled | |
| 13 | - /> | |
| 5 | + <el-input v-model.trim="form.roomName" disabled /> | |
| 14 | 6 | </el-form-item> |
| 15 | - | |
| 7 | + | |
| 16 | 8 | <el-form-item :label="$t('roomRenovationManage.status')" prop="state" required> |
| 17 | 9 | <el-select v-model="form.state"> |
| 18 | - <el-option | |
| 19 | - :label="$t('roomRenovationManage.reviewPass')" | |
| 20 | - value="3000" | |
| 21 | - /> | |
| 22 | - <el-option | |
| 23 | - :label="$t('roomRenovationManage.reviewReject')" | |
| 24 | - value="2000" | |
| 25 | - /> | |
| 10 | + <el-option :label="$t('roomRenovationManage.reviewPass')" value="3000" /> | |
| 11 | + <el-option :label="$t('roomRenovationManage.reviewReject')" value="2000" /> | |
| 26 | 12 | </el-select> |
| 27 | 13 | </el-form-item> |
| 28 | - | |
| 14 | + | |
| 29 | 15 | <el-form-item :label="$t('roomRenovationManage.reviewOpinion')" prop="examineRemark" required> |
| 30 | - <el-input | |
| 31 | - v-model.trim="form.examineRemark" | |
| 32 | - type="textarea" | |
| 33 | - /> | |
| 16 | + <el-input v-model.trim="form.examineRemark" type="textarea" /> | |
| 34 | 17 | </el-form-item> |
| 35 | 18 | </el-form> |
| 36 | - | |
| 19 | + | |
| 37 | 20 | <div slot="footer" class="dialog-footer"> |
| 38 | 21 | <el-button @click="visible = false"> |
| 39 | 22 | {{ $t('roomRenovationManage.cancel') }} |
| ... | ... | @@ -73,7 +56,7 @@ export default { |
| 73 | 56 | } |
| 74 | 57 | this.visible = true |
| 75 | 58 | }, |
| 76 | - | |
| 59 | + | |
| 77 | 60 | resetForm() { |
| 78 | 61 | this.form = { |
| 79 | 62 | rId: '', |
| ... | ... | @@ -83,7 +66,7 @@ export default { |
| 83 | 66 | communityId: '' |
| 84 | 67 | } |
| 85 | 68 | }, |
| 86 | - | |
| 69 | + | |
| 87 | 70 | async saveRoomToExamine() { |
| 88 | 71 | try { |
| 89 | 72 | await updateRoomToExamine(this.form) | ... | ... |
src/components/community/UploadVedio.vue
0 → 100644
| 1 | +<template> | |
| 2 | + <div class="upload-vedio-container"> | |
| 3 | + <div v-if="progress > 0" class="progress-container"> | |
| 4 | + <el-progress :percentage="progress" :stroke-width="2" /> | |
| 5 | + <div class="file-name">{{ fileName }}</div> | |
| 6 | + </div> | |
| 7 | + <el-button type="primary" @click="triggerUpload"> | |
| 8 | + {{ $t('common.upload') }} | |
| 9 | + </el-button> | |
| 10 | + <input | |
| 11 | + ref="fileInput" | |
| 12 | + type="file" | |
| 13 | + accept="video/*" | |
| 14 | + hidden | |
| 15 | + @change="handleFileChange" | |
| 16 | + /> | |
| 17 | + </div> | |
| 18 | +</template> | |
| 19 | + | |
| 20 | +<script> | |
| 21 | +import { uploadVedio } from '@/api/community/listRoomDecorationRecordApi' | |
| 22 | +import { getCommunityId } from '@/api/community/communityApi' | |
| 23 | + | |
| 24 | +export default { | |
| 25 | + name: 'UploadVedio', | |
| 26 | + props: { | |
| 27 | + callBackListener: { | |
| 28 | + type: String, | |
| 29 | + default: '' | |
| 30 | + }, | |
| 31 | + callBackFunction: { | |
| 32 | + type: String, | |
| 33 | + default: '' | |
| 34 | + } | |
| 35 | + }, | |
| 36 | + data() { | |
| 37 | + return { | |
| 38 | + vedio: {}, | |
| 39 | + fileName: '', | |
| 40 | + realFileName: '', | |
| 41 | + progress: 0 | |
| 42 | + } | |
| 43 | + }, | |
| 44 | + watch: { | |
| 45 | + vedio: { | |
| 46 | + handler(newVal) { | |
| 47 | + this.$emit('change', newVal) | |
| 48 | + }, | |
| 49 | + deep: true | |
| 50 | + } | |
| 51 | + }, | |
| 52 | + methods: { | |
| 53 | + triggerUpload() { | |
| 54 | + this.$refs.fileInput.click() | |
| 55 | + }, | |
| 56 | + async handleFileChange(event) { | |
| 57 | + const file = event.target.files[0] | |
| 58 | + if (!file) return | |
| 59 | + | |
| 60 | + if (file.size > 500 * 1024 * 1024) { | |
| 61 | + this.$message.error(this.$t('uploadVedio.sizeLimit')) | |
| 62 | + return | |
| 63 | + } | |
| 64 | + | |
| 65 | + this.fileName = file.name | |
| 66 | + await this.uploadFile(file) | |
| 67 | + event.target.value = null | |
| 68 | + }, | |
| 69 | + async uploadFile(file) { | |
| 70 | + const formData = new FormData() | |
| 71 | + formData.append('uploadFile', file) | |
| 72 | + formData.append('communityId', getCommunityId()) | |
| 73 | + | |
| 74 | + try { | |
| 75 | + const response = await uploadVedio(formData, { | |
| 76 | + onUploadProgress: (progressEvent) => { | |
| 77 | + const percentCompleted = Math.round( | |
| 78 | + (progressEvent.loaded * 90) / progressEvent.total | |
| 79 | + ) | |
| 80 | + this.progress = percentCompleted | |
| 81 | + } | |
| 82 | + }) | |
| 83 | + | |
| 84 | + this.progress = 100 | |
| 85 | + this.realFileName = response.realFileName | |
| 86 | + this.vedio = response | |
| 87 | + this.$message.success(this.$t('uploadVedio.success')) | |
| 88 | + } catch (error) { | |
| 89 | + this.$message.error(this.$t('uploadVedio.failed')) | |
| 90 | + this.progress = 0 | |
| 91 | + } | |
| 92 | + }, | |
| 93 | + clear() { | |
| 94 | + this.vedio = {} | |
| 95 | + this.fileName = '' | |
| 96 | + this.realFileName = '' | |
| 97 | + this.progress = 0 | |
| 98 | + }, | |
| 99 | + notifyVedio(fileName) { | |
| 100 | + this.fileName = fileName | |
| 101 | + this.realFileName = fileName | |
| 102 | + this.progress = 100 | |
| 103 | + } | |
| 104 | + } | |
| 105 | +} | |
| 106 | +</script> | |
| 107 | + | |
| 108 | +<style lang="scss" scoped> | |
| 109 | +.upload-vedio-container { | |
| 110 | + .progress-container { | |
| 111 | + margin-bottom: 15px; | |
| 112 | + | |
| 113 | + .file-name { | |
| 114 | + margin-top: 5px; | |
| 115 | + font-size: 12px; | |
| 116 | + color: #606266; | |
| 117 | + } | |
| 118 | + } | |
| 119 | +} | |
| 120 | +</style> | |
| 0 | 121 | \ No newline at end of file | ... | ... |
src/components/community/uploadImageUrl.vue
| ... | ... | @@ -2,30 +2,23 @@ |
| 2 | 2 | <div class="upload-image-container"> |
| 3 | 3 | <div v-for="(image, index) in photos" :key="index" class="image-item"> |
| 4 | 4 | <el-image |
| 5 | - :src="image.url || image" | |
| 5 | + :src="getImageUrl(image)" | |
| 6 | 6 | fit="cover" |
| 7 | 7 | style="width: 100px; height: 100px" |
| 8 | - :preview-src-list="[image.url || image]" | |
| 9 | - > | |
| 10 | - <div slot="error" class="image-slot"> | |
| 11 | - <i class="el-icon-picture-outline"></i> | |
| 12 | - </div> | |
| 13 | - </el-image> | |
| 14 | - <i | |
| 15 | - class="el-icon-delete remove-icon" | |
| 16 | - @click="removeImage(index)" | |
| 17 | - ></i> | |
| 8 | + :preview-src-list="[getImageUrl(image)]" | |
| 9 | + /> | |
| 10 | + <i class="el-icon-delete delete-icon" @click="removeImage(index)" /> | |
| 18 | 11 | </div> |
| 19 | 12 | <div |
| 20 | 13 | v-if="photos.length < imageCount" |
| 21 | 14 | class="upload-button" |
| 22 | 15 | @click="triggerUpload" |
| 23 | 16 | > |
| 24 | - <i class="el-icon-plus"></i> | |
| 17 | + <i class="el-icon-plus" /> | |
| 25 | 18 | </div> |
| 26 | 19 | <input |
| 27 | - type="file" | |
| 28 | 20 | ref="fileInput" |
| 21 | + type="file" | |
| 29 | 22 | accept="image/*" |
| 30 | 23 | hidden |
| 31 | 24 | @change="handleFileChange" |
| ... | ... | @@ -34,7 +27,8 @@ |
| 34 | 27 | </template> |
| 35 | 28 | |
| 36 | 29 | <script> |
| 37 | -import { uploadImage } from '@/api/community/addCommunityPublicityApi' | |
| 30 | +import { uploadImage } from '@/api/community/listRoomDecorationRecordApi' | |
| 31 | +import { getCommunityId } from '@/api/community/communityApi' | |
| 38 | 32 | |
| 39 | 33 | export default { |
| 40 | 34 | name: 'UploadImageUrl', |
| ... | ... | @@ -45,11 +39,11 @@ export default { |
| 45 | 39 | }, |
| 46 | 40 | callBackListener: { |
| 47 | 41 | type: String, |
| 48 | - required: true | |
| 42 | + default: '' | |
| 49 | 43 | }, |
| 50 | 44 | callBackFunction: { |
| 51 | 45 | type: String, |
| 52 | - required: true | |
| 46 | + default: '' | |
| 53 | 47 | } |
| 54 | 48 | }, |
| 55 | 49 | data() { |
| ... | ... | @@ -60,64 +54,81 @@ export default { |
| 60 | 54 | }, |
| 61 | 55 | watch: { |
| 62 | 56 | photosUrl: { |
| 63 | - deep: true, | |
| 64 | 57 | handler(newVal) { |
| 65 | - this.$emit(this.callBackFunction, newVal) | |
| 66 | - } | |
| 58 | + this.$emit('change', newVal) | |
| 59 | + }, | |
| 60 | + deep: true | |
| 67 | 61 | } |
| 68 | 62 | }, |
| 69 | 63 | methods: { |
| 64 | + getImageUrl(image) { | |
| 65 | + if (image.indexOf('base64,') > -1) return image | |
| 66 | + if (image.indexOf('http') > -1 || image.indexOf('https') > -1) return image | |
| 67 | + return `/callComponent/download/getFile/file?fileId=${image}&communityId=${getCommunityId()}` | |
| 68 | + }, | |
| 70 | 69 | triggerUpload() { |
| 71 | 70 | this.$refs.fileInput.click() |
| 72 | 71 | }, |
| 73 | 72 | async handleFileChange(event) { |
| 74 | - const files = event.target.files | |
| 75 | - if (!files || files.length === 0) return | |
| 73 | + const file = event.target.files[0] | |
| 74 | + if (!file) return | |
| 76 | 75 | |
| 77 | - const file = files[0] | |
| 78 | 76 | if (file.size > 2 * 1024 * 1024) { |
| 79 | - this.$message.error(this.$t('uploadImage.fileSizeError')) | |
| 77 | + this.$message.error(this.$t('uploadImage.imageSizeLimit')) | |
| 80 | 78 | return |
| 81 | 79 | } |
| 82 | 80 | |
| 83 | - try { | |
| 84 | - // Preview image | |
| 85 | - const reader = new FileReader() | |
| 86 | - reader.onload = (e) => { | |
| 87 | - this.photos.push(e.target.result) | |
| 88 | - } | |
| 89 | - reader.readAsDataURL(file) | |
| 81 | + // Preview image | |
| 82 | + const reader = new FileReader() | |
| 83 | + reader.onload = (e) => { | |
| 84 | + this.photos.push(e.target.result) | |
| 85 | + } | |
| 86 | + reader.readAsDataURL(file) | |
| 90 | 87 | |
| 91 | - // Upload image | |
| 88 | + // Upload image | |
| 89 | + try { | |
| 92 | 90 | const formData = new FormData() |
| 93 | 91 | formData.append('uploadFile', file) |
| 92 | + formData.append('communityId', getCommunityId()) | |
| 93 | + | |
| 94 | 94 | const response = await uploadImage(formData) |
| 95 | - this.photosUrl.push(response.data) | |
| 95 | + this.photosUrl.push(response) | |
| 96 | 96 | } catch (error) { |
| 97 | - this.$message.error(this.$t('uploadImage.uploadError')) | |
| 98 | - } finally { | |
| 99 | - event.target.value = '' | |
| 97 | + this.$message.error(this.$t('uploadImage.uploadFailed')) | |
| 100 | 98 | } |
| 99 | + | |
| 100 | + event.target.value = null | |
| 101 | 101 | }, |
| 102 | 102 | removeImage(index) { |
| 103 | 103 | this.photos.splice(index, 1) |
| 104 | 104 | this.photosUrl.splice(index, 1) |
| 105 | 105 | }, |
| 106 | - clearImages() { | |
| 106 | + clear() { | |
| 107 | 107 | this.photos = [] |
| 108 | 108 | this.photosUrl = [] |
| 109 | 109 | }, |
| 110 | - setImages(images) { | |
| 111 | - this.clearImages() | |
| 112 | - images.forEach(image => { | |
| 113 | - if (typeof image === 'string') { | |
| 114 | - this.photos.push(image) | |
| 115 | - this.photosUrl.push({ fileId: image, url: image }) | |
| 116 | - } else { | |
| 117 | - this.photos.push(image.url) | |
| 118 | - this.photosUrl.push(image) | |
| 110 | + notifyPhotos(photos) { | |
| 111 | + this.clear() | |
| 112 | + photos.forEach(photo => { | |
| 113 | + if (photo.indexOf('base64,') > -1) { | |
| 114 | + this.photos.push(photo) | |
| 115 | + return | |
| 116 | + } | |
| 117 | + if (photo.indexOf('http') > -1 || photo.indexOf('https') > -1) { | |
| 118 | + this.photos.push(photo) | |
| 119 | + const fileId = this.getFileIdFromUrl(photo) | |
| 120 | + if (fileId) { | |
| 121 | + this.photosUrl.push({ fileId, url: photo }) | |
| 122 | + } | |
| 123 | + return | |
| 119 | 124 | } |
| 125 | + this.photos.push(this.getImageUrl(photo)) | |
| 126 | + this.photosUrl.push({ fileId: photo, url: this.getImageUrl(photo) }) | |
| 120 | 127 | }) |
| 128 | + }, | |
| 129 | + getFileIdFromUrl(url) { | |
| 130 | + const match = url.match(/fileId=([^&]+)/) | |
| 131 | + return match ? match[1] : null | |
| 121 | 132 | } |
| 122 | 133 | } |
| 123 | 134 | } |
| ... | ... | @@ -131,23 +142,19 @@ export default { |
| 131 | 142 | |
| 132 | 143 | .image-item { |
| 133 | 144 | position: relative; |
| 134 | - margin-right: 10px; | |
| 135 | - margin-bottom: 10px; | |
| 145 | + width: 100px; | |
| 146 | + height: 100px; | |
| 136 | 147 | |
| 137 | - .remove-icon { | |
| 148 | + .delete-icon { | |
| 138 | 149 | position: absolute; |
| 139 | 150 | top: -10px; |
| 140 | 151 | right: -10px; |
| 141 | 152 | color: #f56c6c; |
| 142 | - background: #fff; | |
| 143 | - border-radius: 50%; | |
| 144 | 153 | cursor: pointer; |
| 145 | 154 | font-size: 16px; |
| 146 | - z-index: 1; | |
| 147 | - | |
| 148 | - &:hover { | |
| 149 | - color: #f78989; | |
| 150 | - } | |
| 155 | + background: white; | |
| 156 | + border-radius: 50%; | |
| 157 | + padding: 2px; | |
| 151 | 158 | } |
| 152 | 159 | } |
| 153 | 160 | |
| ... | ... | @@ -155,7 +162,6 @@ export default { |
| 155 | 162 | width: 100px; |
| 156 | 163 | height: 100px; |
| 157 | 164 | border: 1px dashed #dcdfe6; |
| 158 | - border-radius: 4px; | |
| 159 | 165 | display: flex; |
| 160 | 166 | align-items: center; |
| 161 | 167 | justify-content: center; |
| ... | ... | @@ -168,16 +174,5 @@ export default { |
| 168 | 174 | color: #409eff; |
| 169 | 175 | } |
| 170 | 176 | } |
| 171 | - | |
| 172 | - .image-slot { | |
| 173 | - display: flex; | |
| 174 | - justify-content: center; | |
| 175 | - align-items: center; | |
| 176 | - width: 100%; | |
| 177 | - height: 100%; | |
| 178 | - background: #f5f7fa; | |
| 179 | - color: #909399; | |
| 180 | - font-size: 30px; | |
| 181 | - } | |
| 182 | 177 | } |
| 183 | 178 | </style> |
| 184 | 179 | \ No newline at end of file | ... | ... |
src/components/community/viewImage.vue
src/i18n/communityI18n.js
| ... | ... | @@ -11,6 +11,8 @@ import { messages as adminRoomDetailMessages } from '../views/aCommunity/adminRo |
| 11 | 11 | import { messages as adminOwnerDetailMessages } from '../views/aCommunity/adminOwnerDetailLang.js' |
| 12 | 12 | import { messages as adminCarDetailMessages } from '../views/aCommunity/adminCarDetailLang.js' |
| 13 | 13 | import { messages as adminFeeDetailMessages } from '../views/aCommunity/adminFeeDetailLang.js' |
| 14 | +import { messages as listRoomDecorationRecordMessages } from '../views/community/listRoomDecorationRecordLang' | |
| 15 | +import { messages as listRoomRenovationRecordDetailsMessages } from '../views/community/listRoomRenovationRecordDetailsLang' | |
| 14 | 16 | export const messages = { |
| 15 | 17 | en: { |
| 16 | 18 | ...roomStructureMessages.en, |
| ... | ... | @@ -26,6 +28,8 @@ export const messages = { |
| 26 | 28 | ...adminOwnerDetailMessages.en, |
| 27 | 29 | ...adminCarDetailMessages.en, |
| 28 | 30 | ...adminFeeDetailMessages.en, |
| 31 | + ...listRoomDecorationRecordMessages.en, | |
| 32 | + ...listRoomRenovationRecordDetailsMessages.en, | |
| 29 | 33 | }, |
| 30 | 34 | zh: { |
| 31 | 35 | ...roomStructureMessages.zh, |
| ... | ... | @@ -41,5 +45,7 @@ export const messages = { |
| 41 | 45 | ...adminOwnerDetailMessages.zh, |
| 42 | 46 | ...adminCarDetailMessages.zh, |
| 43 | 47 | ...adminFeeDetailMessages.zh, |
| 48 | + ...listRoomDecorationRecordMessages.zh, | |
| 49 | + ...listRoomRenovationRecordDetailsMessages.zh, | |
| 44 | 50 | } |
| 45 | 51 | } |
| 46 | 52 | \ No newline at end of file | ... | ... |
src/router/communityRouter.js
| ... | ... | @@ -60,8 +60,18 @@ export default [ |
| 60 | 60 | component: () => import('@/views/aCommunity/adminCarDetailList.vue') |
| 61 | 61 | }, |
| 62 | 62 | { |
| 63 | - path:'/pages/fee/adminFeeDetail', | |
| 64 | - name:'/pages/fee/adminFeeDetail', | |
| 63 | + path: '/pages/fee/adminFeeDetail', | |
| 64 | + name: '/pages/fee/adminFeeDetail', | |
| 65 | 65 | component: () => import('@/views/aCommunity/adminFeeDetailList.vue') |
| 66 | - }, | |
| 66 | + }, | |
| 67 | + { | |
| 68 | + path: '/views/community/listRoomDecorationRecord', | |
| 69 | + name: '/views/community/listRoomDecorationRecord', | |
| 70 | + component: () => import('@/views/community/listRoomDecorationRecordList.vue') | |
| 71 | + }, | |
| 72 | + { | |
| 73 | + path: '/views/community/listRoomRenovationRecordDetails', | |
| 74 | + name: '/views/community/listRoomRenovationRecordDetails', | |
| 75 | + component: () => import('@/views/community/listRoomRenovationRecordDetailsList.vue') | |
| 76 | + }, | |
| 67 | 77 | ] |
| 68 | 78 | \ No newline at end of file | ... | ... |
src/views/community/listRoomDecorationRecordLang.js
0 → 100644
| 1 | +export const messages = { | |
| 2 | + en: { | |
| 3 | + listRoomDecorationRecord: { | |
| 4 | + title: 'Decoration Tracking Record', | |
| 5 | + add: 'Add', | |
| 6 | + back: 'Back', | |
| 7 | + recordId: 'Record ID', | |
| 8 | + room: 'Room', | |
| 9 | + operator: 'Operator', | |
| 10 | + createTime: 'Create Time', | |
| 11 | + status: 'Status', | |
| 12 | + originalImage: 'Original Image', | |
| 13 | + isViolation: 'Is Violation', | |
| 14 | + remark: 'Remark', | |
| 15 | + operation: 'Operation', | |
| 16 | + viewDetails: 'View Details', | |
| 17 | + delete: 'Delete', | |
| 18 | + fetchError: 'Failed to fetch decoration records' | |
| 19 | + }, | |
| 20 | + roomDecorationRecord: { | |
| 21 | + title: 'Decoration Tracking', | |
| 22 | + room: 'Room', | |
| 23 | + roomPlaceholder: 'Required, please fill in the room', | |
| 24 | + status: 'Status', | |
| 25 | + isViolation: 'Is Violation', | |
| 26 | + isViolationPlaceholder: 'Please select whether it is a violation', | |
| 27 | + yes: 'Yes', | |
| 28 | + no: 'No', | |
| 29 | + remark: 'Remark', | |
| 30 | + remarkPlaceholder: 'Please fill in the remark', | |
| 31 | + uploadImage: 'Upload Image', | |
| 32 | + uploadVideo: 'Upload Video', | |
| 33 | + isViolationRequired: 'Is violation is required', | |
| 34 | + remarkRequired: 'Remark is required' | |
| 35 | + }, | |
| 36 | + uploadImage: { | |
| 37 | + imageSizeLimit: 'Image size cannot exceed 2MB', | |
| 38 | + uploadFailed: 'Failed to upload image' | |
| 39 | + }, | |
| 40 | + uploadVedio: { | |
| 41 | + upload: 'Upload Video', | |
| 42 | + sizeLimit: 'Video size cannot exceed 500MB', | |
| 43 | + success: 'Video uploaded successfully', | |
| 44 | + failed: 'Failed to upload video' | |
| 45 | + }, | |
| 46 | + deleteRoomDecorationRecord: { | |
| 47 | + title: 'Confirm Your Operation', | |
| 48 | + confirm: 'Are you sure to delete the room decoration record?', | |
| 49 | + cancel: 'Cancel', | |
| 50 | + confirmDelete: 'Confirm Delete', | |
| 51 | + success: 'Deleted successfully', | |
| 52 | + failed: 'Failed to delete' | |
| 53 | + } | |
| 54 | + }, | |
| 55 | + zh: { | |
| 56 | + listRoomDecorationRecord: { | |
| 57 | + title: '装修跟踪记录', | |
| 58 | + add: '添加', | |
| 59 | + back: '返回', | |
| 60 | + recordId: '记录ID', | |
| 61 | + room: '房屋', | |
| 62 | + operator: '操作人员', | |
| 63 | + createTime: '创建时间', | |
| 64 | + status: '状态', | |
| 65 | + originalImage: '原始图片', | |
| 66 | + isViolation: '是否违规', | |
| 67 | + remark: '备注', | |
| 68 | + operation: '操作', | |
| 69 | + viewDetails: '查看详情', | |
| 70 | + delete: '删除', | |
| 71 | + fetchError: '获取装修记录失败' | |
| 72 | + }, | |
| 73 | + roomDecorationRecord: { | |
| 74 | + title: '装修跟踪', | |
| 75 | + room: '房屋', | |
| 76 | + roomPlaceholder: '必填,请填写房屋', | |
| 77 | + status: '状态', | |
| 78 | + isViolation: '是否违规', | |
| 79 | + isViolationPlaceholder: '请选择是否违规', | |
| 80 | + yes: '是', | |
| 81 | + no: '否', | |
| 82 | + remark: '备注', | |
| 83 | + remarkPlaceholder: '请填写备注', | |
| 84 | + uploadImage: '上传图片', | |
| 85 | + uploadVideo: '上传视频', | |
| 86 | + isViolationRequired: '是否违规不能为空', | |
| 87 | + remarkRequired: '备注不能为空' | |
| 88 | + }, | |
| 89 | + uploadImage: { | |
| 90 | + imageSizeLimit: '图片大小不能超过2MB', | |
| 91 | + uploadFailed: '图片上传失败' | |
| 92 | + }, | |
| 93 | + uploadVedio: { | |
| 94 | + upload: '上传视频', | |
| 95 | + sizeLimit: '视频大小不能超过500MB', | |
| 96 | + success: '视频上传成功', | |
| 97 | + failed: '视频上传失败' | |
| 98 | + }, | |
| 99 | + deleteRoomDecorationRecord: { | |
| 100 | + title: '请确认您的操作', | |
| 101 | + confirm: '确定删除房屋装修记录?', | |
| 102 | + cancel: '点错了', | |
| 103 | + confirmDelete: '确认删除', | |
| 104 | + success: '删除成功', | |
| 105 | + failed: '删除失败' | |
| 106 | + } | |
| 107 | + } | |
| 108 | +} | |
| 0 | 109 | \ No newline at end of file | ... | ... |
src/views/community/listRoomDecorationRecordList.vue
0 → 100644
| 1 | +<template> | |
| 2 | + <div class="list-room-decoration-record-container"> | |
| 3 | + <el-card class="box-card"> | |
| 4 | + <div slot="header" class="flex justify-between"> | |
| 5 | + <div> | |
| 6 | + <span>{{ roomDecorationRecordsInfo.conditions.roomName }}</span> | |
| 7 | + <span>{{ $t('listRoomDecorationRecord.title') }}</span> | |
| 8 | + </div> | |
| 9 | + <div > | |
| 10 | + <el-button type="primary" size="small" @click="_openAddModal(roomDecorationRecordsInfo.roomRenovation)"> | |
| 11 | + <i class="el-icon-plus"></i> | |
| 12 | + {{ $t('listRoomDecorationRecord.add') }} | |
| 13 | + </el-button> | |
| 14 | + <el-button type="primary" size="small" style="margin-left: 10px" @click="_goBack()"> | |
| 15 | + <i class="el-icon-close"></i> | |
| 16 | + {{ $t('listRoomDecorationRecord.back') }} | |
| 17 | + </el-button> | |
| 18 | + </div> | |
| 19 | + | |
| 20 | + </div> | |
| 21 | + | |
| 22 | + <el-table :data="roomDecorationRecordsInfo.roomRenovationRecords" border style="width: 100%"> | |
| 23 | + <el-table-column prop="recordId" :label="$t('listRoomDecorationRecord.recordId')" align="center" /> | |
| 24 | + <el-table-column prop="roomName" :label="$t('listRoomDecorationRecord.room')" align="center" /> | |
| 25 | + <el-table-column prop="staffName" :label="$t('listRoomDecorationRecord.operator')" align="center" /> | |
| 26 | + <el-table-column prop="createTime" :label="$t('listRoomDecorationRecord.createTime')" align="center" /> | |
| 27 | + <el-table-column prop="stateName" :label="$t('listRoomDecorationRecord.status')" align="center"> | |
| 28 | + <template slot-scope="scope"> | |
| 29 | + <span v-if="scope.row.state === '1000'"> | |
| 30 | + {{ scope.row.stateName }}({{ $t('listRoomDecorationRecord.originalImage') }}) | |
| 31 | + </span> | |
| 32 | + <span v-else>{{ scope.row.stateName }}</span> | |
| 33 | + </template> | |
| 34 | + </el-table-column> | |
| 35 | + <el-table-column prop="isTrueName" :label="$t('listRoomDecorationRecord.isViolation')" align="center" /> | |
| 36 | + <el-table-column prop="remark" :label="$t('listRoomDecorationRecord.remark')" align="center" /> | |
| 37 | + <el-table-column :label="$t('listRoomDecorationRecord.operation')" align="center" width="200"> | |
| 38 | + <template slot-scope="scope"> | |
| 39 | + <el-button size="mini" @click="_openRoomRenovationRecordDetailsModel(scope.row)"> | |
| 40 | + {{ $t('listRoomDecorationRecord.viewDetails') }} | |
| 41 | + </el-button> | |
| 42 | + <el-button size="mini" type="danger" @click="_openDeleteRoomRenovationRecordModel(scope.row)"> | |
| 43 | + {{ $t('listRoomDecorationRecord.delete') }} | |
| 44 | + </el-button> | |
| 45 | + </template> | |
| 46 | + </el-table-column> | |
| 47 | + </el-table> | |
| 48 | + | |
| 49 | + <el-pagination :current-page.sync="page.current" :page-sizes="[10, 20, 30, 50]" :page-size="page.size" | |
| 50 | + :total="page.total" layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange" | |
| 51 | + @current-change="handleCurrentChange" /> | |
| 52 | + </el-card> | |
| 53 | + | |
| 54 | + <room-decoration-record ref="roomDecorationRecord" @success="handleSuccess" /> | |
| 55 | + <delete-room-decoration-record ref="deleteRoomDecorationRecord" @success="handleSuccess" /> | |
| 56 | + </div> | |
| 57 | +</template> | |
| 58 | + | |
| 59 | +<script> | |
| 60 | +import { queryRoomRenovationRecord } from '@/api/community/listRoomDecorationRecordApi' | |
| 61 | +import { getCommunityId } from '@/api/community/communityApi' | |
| 62 | +import RoomDecorationRecord from '@/components/community/RoomDecorationRecord' | |
| 63 | +import DeleteRoomDecorationRecord from '@/components/community/DeleteRoomDecorationRecord' | |
| 64 | + | |
| 65 | +export default { | |
| 66 | + name: 'ListRoomDecorationRecord', | |
| 67 | + components: { | |
| 68 | + RoomDecorationRecord, | |
| 69 | + DeleteRoomDecorationRecord | |
| 70 | + }, | |
| 71 | + data() { | |
| 72 | + return { | |
| 73 | + roomDecorationRecordsInfo: { | |
| 74 | + roomRenovationRecords: [], | |
| 75 | + roomRenovation: [], | |
| 76 | + conditions: { | |
| 77 | + rId: '', | |
| 78 | + roomName: '', | |
| 79 | + roomId: '', | |
| 80 | + stateName: '', | |
| 81 | + state: '', | |
| 82 | + communityId: '' | |
| 83 | + } | |
| 84 | + }, | |
| 85 | + page: { | |
| 86 | + current: 1, | |
| 87 | + size: 10, | |
| 88 | + total: 0 | |
| 89 | + } | |
| 90 | + } | |
| 91 | + }, | |
| 92 | + created() { | |
| 93 | + this.communityId = getCommunityId() | |
| 94 | + this.roomDecorationRecordsInfo.conditions.communityId = this.communityId | |
| 95 | + this.roomDecorationRecordsInfo.conditions.rId = this.$route.query.rId | |
| 96 | + this.roomDecorationRecordsInfo.conditions.roomId = this.$route.query.roomId | |
| 97 | + this.roomDecorationRecordsInfo.conditions.roomName = this.$route.query.roomName | |
| 98 | + this.roomDecorationRecordsInfo.conditions.state = this.$route.query.state | |
| 99 | + this.roomDecorationRecordsInfo.conditions.stateName = this.$route.query.stateName | |
| 100 | + this._listRoomRenovationRecords(this.page.current, this.page.size) | |
| 101 | + }, | |
| 102 | + methods: { | |
| 103 | + async _listRoomRenovationRecords(page, size) { | |
| 104 | + try { | |
| 105 | + const params = { | |
| 106 | + page, | |
| 107 | + row: size, | |
| 108 | + ...this.roomDecorationRecordsInfo.conditions | |
| 109 | + } | |
| 110 | + const { data, total } = await queryRoomRenovationRecord(params) | |
| 111 | + this.roomDecorationRecordsInfo.roomRenovationRecords = data | |
| 112 | + this.page.total = total | |
| 113 | + } catch (error) { | |
| 114 | + this.$message.error(this.$t('listRoomDecorationRecord.fetchError')) | |
| 115 | + } | |
| 116 | + }, | |
| 117 | + _openAddModal(roomRenovation) { | |
| 118 | + roomRenovation.push(this.roomDecorationRecordsInfo.conditions.rId) | |
| 119 | + roomRenovation.push(this.roomDecorationRecordsInfo.conditions.roomId) | |
| 120 | + roomRenovation.push(this.roomDecorationRecordsInfo.conditions.roomName) | |
| 121 | + roomRenovation.push(this.roomDecorationRecordsInfo.conditions.state) | |
| 122 | + roomRenovation.push(this.roomDecorationRecordsInfo.conditions.stateName) | |
| 123 | + this.$refs.roomDecorationRecord.open(roomRenovation) | |
| 124 | + }, | |
| 125 | + _openDeleteRoomRenovationRecordModel(record) { | |
| 126 | + this.$refs.deleteRoomDecorationRecord.open(record) | |
| 127 | + }, | |
| 128 | + _openRoomRenovationRecordDetailsModel(record) { | |
| 129 | + this.$router.push({ | |
| 130 | + path: '/views/community/listRoomRenovationRecordDetails', | |
| 131 | + query: { | |
| 132 | + recordId: record.recordId, | |
| 133 | + roomName: record.roomName, | |
| 134 | + state: record.state | |
| 135 | + } | |
| 136 | + }) | |
| 137 | + }, | |
| 138 | + handleSuccess() { | |
| 139 | + this._listRoomRenovationRecords(this.page.current, this.page.size) | |
| 140 | + }, | |
| 141 | + handleSizeChange(val) { | |
| 142 | + this.page.size = val | |
| 143 | + this._listRoomRenovationRecords(this.page.current, val) | |
| 144 | + }, | |
| 145 | + handleCurrentChange(val) { | |
| 146 | + this.page.current = val | |
| 147 | + this._listRoomRenovationRecords(val, this.page.size) | |
| 148 | + }, | |
| 149 | + _goBack() { | |
| 150 | + this.$router.go(-1) | |
| 151 | + } | |
| 152 | + } | |
| 153 | +} | |
| 154 | +</script> | |
| 155 | + | |
| 156 | +<style lang="scss" scoped> | |
| 157 | +.list-room-decoration-record-container { | |
| 158 | + padding: 20px; | |
| 159 | + | |
| 160 | + .box-card { | |
| 161 | + margin-bottom: 20px; | |
| 162 | + | |
| 163 | + .card-header { | |
| 164 | + display: flex; | |
| 165 | + align-items: center; | |
| 166 | + justify-content: space-between; | |
| 167 | + | |
| 168 | + span { | |
| 169 | + font-size: 16px; | |
| 170 | + font-weight: bold; | |
| 171 | + } | |
| 172 | + } | |
| 173 | + | |
| 174 | + .el-pagination { | |
| 175 | + margin-top: 20px; | |
| 176 | + text-align: right; | |
| 177 | + } | |
| 178 | + } | |
| 179 | +} | |
| 180 | +</style> | |
| 0 | 181 | \ No newline at end of file | ... | ... |
src/views/community/listRoomRenovationRecordDetailsLang.js
0 → 100644
| 1 | +export const messages = { | |
| 2 | + en: { | |
| 3 | + listRoomRenovationRecordDetails: { | |
| 4 | + title: 'Renovation Record', | |
| 5 | + back: 'Back', | |
| 6 | + room: 'Room', | |
| 7 | + media: 'Media', | |
| 8 | + originalMedia: 'Original Media', | |
| 9 | + createTime: 'Create Time', | |
| 10 | + fetchError: 'Failed to fetch renovation record details' | |
| 11 | + } | |
| 12 | + }, | |
| 13 | + zh: { | |
| 14 | + listRoomRenovationRecordDetails: { | |
| 15 | + title: '装修记录', | |
| 16 | + back: '返回', | |
| 17 | + room: '房屋', | |
| 18 | + media: '图片/视频', | |
| 19 | + originalMedia: '原始图片/视频', | |
| 20 | + createTime: '创建时间', | |
| 21 | + fetchError: '获取装修记录详情失败' | |
| 22 | + } | |
| 23 | + } | |
| 24 | +} | |
| 0 | 25 | \ No newline at end of file | ... | ... |
src/views/community/listRoomRenovationRecordDetailsList.vue
0 → 100644
| 1 | +<template> | |
| 2 | + <div class="list-room-renovation-record-details-container"> | |
| 3 | + <el-row :gutter="20" style="width:100%"> | |
| 4 | + <el-col :span="24" style="width:100%"> | |
| 5 | + <el-card> | |
| 6 | + <div slot="header" class="flex justify-between"> | |
| 7 | + <div> | |
| 8 | + <span>{{ roomRenovationRecordDetailsInfo.conditions.roomName }}</span> | |
| 9 | + <span>{{ $t('listRoomRenovationRecordDetails.title') }}</span> | |
| 10 | + </div> | |
| 11 | + <div class="header-tools"> | |
| 12 | + | |
| 13 | + <el-button type="primary" size="small" @click="_goBack" icon="el-icon-close"> | |
| 14 | + {{ $t('listRoomRenovationRecordDetails.back') }} | |
| 15 | + </el-button> | |
| 16 | + </div> | |
| 17 | + </div> | |
| 18 | + | |
| 19 | + <el-table :data="roomRenovationRecordDetailsInfo.roomRenovationRecordDetails" border style="width: 100%"> | |
| 20 | + <el-table-column prop="roomName" :label="$t('listRoomRenovationRecordDetails.room')" align="center" /> | |
| 21 | + <el-table-column :label="$t('listRoomRenovationRecordDetails.media')" align="center"> | |
| 22 | + <template slot-scope="scope"> | |
| 23 | + <div v-if="scope.row.relTypeCd === '19000'" class="image-container" @click="showImg(scope.row.url)"> | |
| 24 | + <el-image :src="scope.row.url" :preview-src-list="[scope.row.url]" fit="cover" | |
| 25 | + style="width:50px;height:50px"> | |
| 26 | + <div slot="error" class="image-slot"> | |
| 27 | + <img src="/img/noPhoto.jpg" style="width:50px;height:50px"> | |
| 28 | + </div> | |
| 29 | + </el-image> | |
| 30 | + <img src="/img/icon-bigimg.png" class="preview-icon"> | |
| 31 | + </div> | |
| 32 | + <video v-else-if="scope.row.relTypeCd === '21000'" width="200" height="200" controls autoplay> | |
| 33 | + <source :src="scope.row.url" type="video/mp4"> | |
| 34 | + </video> | |
| 35 | + </template> | |
| 36 | + </el-table-column> | |
| 37 | + <el-table-column prop="createTime" :label="$t('listRoomRenovationRecordDetails.createTime')" | |
| 38 | + align="center" /> | |
| 39 | + </el-table> | |
| 40 | + | |
| 41 | + <el-pagination :current-page.sync="pagination.current" :page-sizes="[10, 20, 30, 50]" | |
| 42 | + :page-size="pagination.size" :total="pagination.total" layout="total, sizes, prev, pager, next, jumper" | |
| 43 | + @size-change="handleSizeChange" @current-change="handleCurrentChange" /> | |
| 44 | + </el-card> | |
| 45 | + </el-col> | |
| 46 | + </el-row> | |
| 47 | + | |
| 48 | + <view-image ref="viewImage" /> | |
| 49 | + </div> | |
| 50 | +</template> | |
| 51 | + | |
| 52 | +<script> | |
| 53 | +import { queryRoomRenovationRecordDetail } from '@/api/community/listRoomRenovationRecordDetailsApi' | |
| 54 | +import ViewImage from '@/components/community/viewImage' | |
| 55 | +import { getCommunityId } from '@/api/community/communityApi' | |
| 56 | + | |
| 57 | +export default { | |
| 58 | + name: 'ListRoomRenovationRecordDetails', | |
| 59 | + components: { | |
| 60 | + ViewImage | |
| 61 | + }, | |
| 62 | + data() { | |
| 63 | + return { | |
| 64 | + roomRenovationRecordDetailsInfo: { | |
| 65 | + roomRenovationRecordDetails: [], | |
| 66 | + conditions: { | |
| 67 | + recordId: '', | |
| 68 | + roomName: '', | |
| 69 | + state: '', | |
| 70 | + roomId: '', | |
| 71 | + communityId: '', | |
| 72 | + page: 1, | |
| 73 | + row: 10 | |
| 74 | + } | |
| 75 | + }, | |
| 76 | + pagination: { | |
| 77 | + current: 1, | |
| 78 | + size: 10, | |
| 79 | + total: 0 | |
| 80 | + }, | |
| 81 | + loading: false | |
| 82 | + } | |
| 83 | + }, | |
| 84 | + created() { | |
| 85 | + this.roomRenovationRecordDetailsInfo.conditions.communityId = getCommunityId() | |
| 86 | + this.roomRenovationRecordDetailsInfo.conditions.recordId = this.$route.query.recordId | |
| 87 | + this.roomRenovationRecordDetailsInfo.conditions.roomName = this.$route.query.roomName | |
| 88 | + this.roomRenovationRecordDetailsInfo.conditions.state = this.$route.query.state | |
| 89 | + this._listRoomRenovationRecordDetails() | |
| 90 | + }, | |
| 91 | + methods: { | |
| 92 | + async _listRoomRenovationRecordDetails() { | |
| 93 | + try { | |
| 94 | + this.loading = true | |
| 95 | + const params = { | |
| 96 | + ...this.roomRenovationRecordDetailsInfo.conditions, | |
| 97 | + page: this.pagination.current, | |
| 98 | + row: this.pagination.size | |
| 99 | + } | |
| 100 | + const { data, total } = await queryRoomRenovationRecordDetail(params) | |
| 101 | + this.roomRenovationRecordDetailsInfo.roomRenovationRecordDetails = data | |
| 102 | + this.pagination.total = total | |
| 103 | + } catch (error) { | |
| 104 | + this.$message.error(this.$t('listRoomRenovationRecordDetails.fetchError')) | |
| 105 | + } finally { | |
| 106 | + this.loading = false | |
| 107 | + } | |
| 108 | + }, | |
| 109 | + handleSizeChange(val) { | |
| 110 | + this.pagination.size = val | |
| 111 | + this._listRoomRenovationRecordDetails() | |
| 112 | + }, | |
| 113 | + handleCurrentChange(val) { | |
| 114 | + this.pagination.current = val | |
| 115 | + this._listRoomRenovationRecordDetails() | |
| 116 | + }, | |
| 117 | + _goBack() { | |
| 118 | + this.$router.go(-1) | |
| 119 | + }, | |
| 120 | + showImg(url) { | |
| 121 | + this.$refs.viewImage.open(url) | |
| 122 | + } | |
| 123 | + } | |
| 124 | +} | |
| 125 | +</script> | |
| 126 | + | |
| 127 | +<style lang="scss" scoped> | |
| 128 | +.list-room-renovation-record-details-container { | |
| 129 | + padding: 20px; | |
| 130 | + | |
| 131 | + .clearfix { | |
| 132 | + display: flex; | |
| 133 | + align-items: center; | |
| 134 | + justify-content: space-between; | |
| 135 | + } | |
| 136 | + | |
| 137 | + .header-tools { | |
| 138 | + display: flex; | |
| 139 | + align-items: center; | |
| 140 | + } | |
| 141 | + | |
| 142 | + .image-container { | |
| 143 | + position: relative; | |
| 144 | + display: inline-block; | |
| 145 | + cursor: pointer; | |
| 146 | + | |
| 147 | + .preview-icon { | |
| 148 | + position: absolute; | |
| 149 | + right: 0; | |
| 150 | + bottom: 0; | |
| 151 | + width: 20px; | |
| 152 | + height: 20px; | |
| 153 | + } | |
| 154 | + } | |
| 155 | +} | |
| 156 | +</style> | |
| 0 | 157 | \ No newline at end of file | ... | ... |
src/views/community/roomRenovationManageLang.js
| ... | ... | @@ -58,7 +58,11 @@ export const messages = { |
| 58 | 58 | acceptanceOpinion: "Acceptance Opinion", |
| 59 | 59 | reviewOpinion: "Review Opinion", |
| 60 | 60 | violationPlaceholder: "Please select if violation", |
| 61 | - violationDescPlaceholder: "Please enter violation description" | |
| 61 | + violationDescPlaceholder: "Please enter violation description", | |
| 62 | + reviewPass: "Review Pass", | |
| 63 | + reviewReject: "Review Reject", | |
| 64 | + acceptanceSuccess: "Acceptance Success", | |
| 65 | + acceptanceFailed: "Acceptance Failure" | |
| 62 | 66 | } |
| 63 | 67 | }, |
| 64 | 68 | zh: { |
| ... | ... | @@ -120,7 +124,11 @@ export const messages = { |
| 120 | 124 | acceptanceOpinion: "验收意见", |
| 121 | 125 | reviewOpinion: "审核意见", |
| 122 | 126 | violationPlaceholder: "请选择是否违规", |
| 123 | - violationDescPlaceholder: "请输入违规说明" | |
| 127 | + violationDescPlaceholder: "请输入违规说明", | |
| 128 | + reviewPass: "审核通过", | |
| 129 | + reviewReject: "审核不通过", | |
| 130 | + acceptanceSuccess: "验收成功", | |
| 131 | + acceptanceFailed: "验收失败" | |
| 124 | 132 | } |
| 125 | 133 | } |
| 126 | 134 | } |
| 127 | 135 | \ No newline at end of file | ... | ... |
src/views/community/roomRenovationManageList.vue
| ... | ... | @@ -112,10 +112,10 @@ |
| 112 | 112 | <el-table-column prop="remark" :label="$t('roomRenovationManage.remark')" align="center" /> |
| 113 | 113 | <el-table-column :label="$t('roomRenovationManage.operation')" align="center" width="150"> |
| 114 | 114 | <template slot-scope="scope"> |
| 115 | - <el-button v-if="scope.row.state === '1000'" size="mini" type="text" | |
| 115 | + <!-- <el-button v-if="scope.row.state === '1000'" size="mini" type="text" | |
| 116 | 116 | @click="openRoomRenovationFee(scope.row)"> |
| 117 | 117 | {{ $t('roomRenovationManage.fee') }} |
| 118 | - </el-button> | |
| 118 | + </el-button> --> | |
| 119 | 119 | <el-button size="mini" v-if="scope.row.state === '1000' && scope.row.isViolation === 'N'" type="text" |
| 120 | 120 | @click="openToExamine(scope.row)"> |
| 121 | 121 | {{ $t('roomRenovationManage.review') }} |
| ... | ... | @@ -326,10 +326,13 @@ export default { |
| 326 | 326 | // 打开跟踪记录 |
| 327 | 327 | openRoomDecorationRecord(row) { |
| 328 | 328 | this.$router.push({ |
| 329 | - path: '/property/room-decoration-record', | |
| 329 | + path: '/views/community/listRoomDecorationRecord', | |
| 330 | 330 | query: { |
| 331 | 331 | roomId: row.roomId, |
| 332 | - rId: row.rId | |
| 332 | + rId: row.rId, | |
| 333 | + roomName: row.roomName, | |
| 334 | + state: row.state, | |
| 335 | + stateName: row.stateName | |
| 333 | 336 | } |
| 334 | 337 | }) |
| 335 | 338 | }, |
| ... | ... | @@ -337,7 +340,7 @@ export default { |
| 337 | 340 | // 打开验收明细 |
| 338 | 341 | openRoomRenovationDetail(row) { |
| 339 | 342 | this.$router.push({ |
| 340 | - path: '/property/room-renovation-detail', | |
| 343 | + path: '/views/community/listRoomDecorationRecord', | |
| 341 | 344 | query: { |
| 342 | 345 | rId: row.rId, |
| 343 | 346 | roomName: row.roomName | ... | ... |