Commit 1db0a60cb54020679a8f4507dc6425d48aea40f4
1 parent
d720526e
优化常用菜单 和搜索功能
Showing
14 changed files
with
1281 additions
and
6 deletions
src/api/system/menuUserManageApi.js
0 → 100644
| 1 | +import request from '@/utils/request' | ||
| 2 | + | ||
| 3 | +/** | ||
| 4 | + * 获取用户菜单列表 | ||
| 5 | + * @param {Object} params 查询参数 | ||
| 6 | + * @returns {Promise} | ||
| 7 | + */ | ||
| 8 | +export function listMenuUser(params) { | ||
| 9 | + return new Promise((resolve, reject) => { | ||
| 10 | + request({ | ||
| 11 | + url: '/menuUser.listMenuUser', | ||
| 12 | + method: 'get', | ||
| 13 | + params | ||
| 14 | + }).then(response => { | ||
| 15 | + const res = response.data | ||
| 16 | + resolve(res) | ||
| 17 | + }).catch(error => { | ||
| 18 | + reject(error) | ||
| 19 | + }) | ||
| 20 | + }) | ||
| 21 | +} | ||
| 22 | + | ||
| 23 | +/** | ||
| 24 | + * 添加用户菜单 | ||
| 25 | + * @param {Object} data 菜单数据 | ||
| 26 | + * @returns {Promise} | ||
| 27 | + */ | ||
| 28 | +export function saveMenuUser(data) { | ||
| 29 | + return new Promise((resolve, reject) => { | ||
| 30 | + request({ | ||
| 31 | + url: '/menuUser.saveMenuUser', | ||
| 32 | + method: 'post', | ||
| 33 | + data | ||
| 34 | + }).then(response => { | ||
| 35 | + const res = response.data | ||
| 36 | + resolve(res) | ||
| 37 | + }).catch(error => { | ||
| 38 | + reject(error) | ||
| 39 | + }) | ||
| 40 | + }) | ||
| 41 | +} | ||
| 42 | + | ||
| 43 | +/** | ||
| 44 | + * 删除用户菜单 | ||
| 45 | + * @param {Object} data 删除参数 | ||
| 46 | + * @returns {Promise} | ||
| 47 | + */ | ||
| 48 | +export function deleteMenuUser(data) { | ||
| 49 | + return new Promise((resolve, reject) => { | ||
| 50 | + request({ | ||
| 51 | + url: '/menuUser.deleteMenuUser', | ||
| 52 | + method: 'post', | ||
| 53 | + data | ||
| 54 | + }).then(response => { | ||
| 55 | + const res = response.data | ||
| 56 | + resolve(res) | ||
| 57 | + }).catch(error => { | ||
| 58 | + reject(error) | ||
| 59 | + }) | ||
| 60 | + }) | ||
| 61 | +} | ||
| 62 | + | ||
| 63 | +/** | ||
| 64 | + * 获取目录菜单列表 | ||
| 65 | + * @returns {Promise} | ||
| 66 | + */ | ||
| 67 | +export function listCatalogMenus() { | ||
| 68 | + return new Promise((resolve, reject) => { | ||
| 69 | + request({ | ||
| 70 | + url: '/menu.listCatalogMenus', | ||
| 71 | + method: 'get' | ||
| 72 | + }).then(response => { | ||
| 73 | + const res = response.data | ||
| 74 | + resolve(res) | ||
| 75 | + }).catch(error => { | ||
| 76 | + reject(error) | ||
| 77 | + }) | ||
| 78 | + }) | ||
| 79 | +} | ||
| 0 | \ No newline at end of file | 80 | \ No newline at end of file |
src/api/system/searchCommunityDataApi.js
0 → 100644
| 1 | +import request from '@/utils/request' | ||
| 2 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 3 | + | ||
| 4 | +// 搜索社区数据 | ||
| 5 | +export function searchCommunityData(params) { | ||
| 6 | + return new Promise((resolve, reject) => { | ||
| 7 | + const communityId = getCommunityId() | ||
| 8 | + request({ | ||
| 9 | + url: '/search.searchCommunityData', | ||
| 10 | + method: 'get', | ||
| 11 | + params: { | ||
| 12 | + ...params, | ||
| 13 | + communityId | ||
| 14 | + } | ||
| 15 | + }).then(response => { | ||
| 16 | + const res = response.data | ||
| 17 | + resolve(res) | ||
| 18 | + }).catch(error => { | ||
| 19 | + reject(error) | ||
| 20 | + }) | ||
| 21 | + }) | ||
| 22 | +} | ||
| 23 | + | ||
| 24 | +// 获取电话机信息 | ||
| 25 | +export function getTelMachineInfo() { | ||
| 26 | + return new Promise((resolve, reject) => { | ||
| 27 | + const communityId = getCommunityId() | ||
| 28 | + request({ | ||
| 29 | + url: '/iot.getOpenApi', | ||
| 30 | + method: 'get', | ||
| 31 | + params: { | ||
| 32 | + page: 1, | ||
| 33 | + row: 1, | ||
| 34 | + communityId, | ||
| 35 | + iotApiCode: 'queryTelMachineBmoImpl' | ||
| 36 | + } | ||
| 37 | + }).then(response => { | ||
| 38 | + const res = response.data | ||
| 39 | + resolve(res) | ||
| 40 | + }).catch(error => { | ||
| 41 | + reject(error) | ||
| 42 | + }) | ||
| 43 | + }) | ||
| 44 | +} | ||
| 45 | + | ||
| 46 | +// 保存电话机消息 | ||
| 47 | +export function saveTelMachineMsg(data) { | ||
| 48 | + return new Promise((resolve, reject) => { | ||
| 49 | + const communityId = getCommunityId() | ||
| 50 | + request({ | ||
| 51 | + url: '/iot.postOpenApi', | ||
| 52 | + method: 'post', | ||
| 53 | + data: { | ||
| 54 | + ...data, | ||
| 55 | + communityId, | ||
| 56 | + iotApiCode: 'telMachineMsgBmoImpl' | ||
| 57 | + } | ||
| 58 | + }).then(response => { | ||
| 59 | + const res = response.data | ||
| 60 | + resolve(res) | ||
| 61 | + }).catch(error => { | ||
| 62 | + reject(error) | ||
| 63 | + }) | ||
| 64 | + }) | ||
| 65 | +} | ||
| 0 | \ No newline at end of file | 66 | \ No newline at end of file |
src/api/system/viewMenuUserApi.js
0 → 100644
| 1 | +import request from '@/utils/request' | ||
| 2 | + | ||
| 3 | +/** | ||
| 4 | + * 获取用户菜单列表 | ||
| 5 | + * @param {Object} params 查询参数 | ||
| 6 | + * @returns {Promise} Promise对象 | ||
| 7 | + */ | ||
| 8 | +export function listMenuUser(params) { | ||
| 9 | + return new Promise((resolve, reject) => { | ||
| 10 | + request({ | ||
| 11 | + url: '/menuUser.listMenuUser', | ||
| 12 | + method: 'get', | ||
| 13 | + params | ||
| 14 | + }).then(response => { | ||
| 15 | + const res = response.data | ||
| 16 | + resolve(res) | ||
| 17 | + }).catch(error => { | ||
| 18 | + reject(error) | ||
| 19 | + }) | ||
| 20 | + }) | ||
| 21 | +} | ||
| 0 | \ No newline at end of file | 22 | \ No newline at end of file |
src/components/system/addMenuUser.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <el-dialog :title="$t('menuUserManage.add.title')" :visible.sync="visible" width="50%" @close="handleClose"> | ||
| 3 | + <el-form ref="form" :model="form" :rules="rules" label-width="120px"> | ||
| 4 | + <el-form-item :label="$t('menuUserManage.add.menu')" prop="mId"> | ||
| 5 | + <el-select v-model="form.mId" :placeholder="$t('menuUserManage.add.menuPlaceholder')" style="width:100%"> | ||
| 6 | + <el-option v-for="item in menus" :key="item.mId" :label="`${item.menuGroupName}-${item.name}`" | ||
| 7 | + :value="item.mId" :disabled="item.isShow !== 'Y'" /> | ||
| 8 | + </el-select> | ||
| 9 | + </el-form-item> | ||
| 10 | + | ||
| 11 | + <el-form-item :label="$t('menuUserManage.add.icon')" prop="icon"> | ||
| 12 | + <el-radio-group v-model="form.icon"> | ||
| 13 | + <el-radio label="fa fa-adjust"> | ||
| 14 | + <i class="fa fa-adjust"></i> | ||
| 15 | + </el-radio> | ||
| 16 | + <el-radio label="fa fa-bar-chart"> | ||
| 17 | + <i class="fa fa-bar-chart"></i> | ||
| 18 | + </el-radio> | ||
| 19 | + <el-radio label="fa fa-comment-o"> | ||
| 20 | + <i class="fa fa-comment-o"></i> | ||
| 21 | + </el-radio> | ||
| 22 | + <el-radio label="fa fa-folder-o"> | ||
| 23 | + <i class="fa fa-folder-o"></i> | ||
| 24 | + </el-radio> | ||
| 25 | + <el-radio label="fa fa-futbol-o"> | ||
| 26 | + <i class="fa fa-futbol-o"></i> | ||
| 27 | + </el-radio> | ||
| 28 | + <el-radio label="fa fa-globe"> | ||
| 29 | + <i class="fa fa-globe"></i> | ||
| 30 | + </el-radio> | ||
| 31 | + <el-radio label="fa fa-female"> | ||
| 32 | + <i class="fa fa-female"></i> | ||
| 33 | + </el-radio> | ||
| 34 | + </el-radio-group> | ||
| 35 | + </el-form-item> | ||
| 36 | + | ||
| 37 | + <el-form-item :label="$t('menuUserManage.add.seq')" prop="seq"> | ||
| 38 | + <el-input-number v-model="form.seq" :placeholder="$t('menuUserManage.add.seqPlaceholder')" :min="1" | ||
| 39 | + style="width:100%" /> | ||
| 40 | + </el-form-item> | ||
| 41 | + </el-form> | ||
| 42 | + | ||
| 43 | + <div slot="footer" class="dialog-footer"> | ||
| 44 | + <el-button @click="visible = false">{{ $t('common.cancel') }}</el-button> | ||
| 45 | + <el-button type="primary" @click="handleSubmit">{{ $t('common.confirm') }}</el-button> | ||
| 46 | + </div> | ||
| 47 | + </el-dialog> | ||
| 48 | +</template> | ||
| 49 | + | ||
| 50 | +<script> | ||
| 51 | +import { saveMenuUser,listCatalogMenus } from '@/api/system/menuUserManageApi' | ||
| 52 | + | ||
| 53 | +export default { | ||
| 54 | + name: 'AddMenuUser', | ||
| 55 | + data() { | ||
| 56 | + return { | ||
| 57 | + visible: false, | ||
| 58 | + form: { | ||
| 59 | + mId: '', | ||
| 60 | + icon: 'fa fa-adjust', | ||
| 61 | + seq: 1 | ||
| 62 | + }, | ||
| 63 | + menus: [], | ||
| 64 | + rules: { | ||
| 65 | + mId: [ | ||
| 66 | + { required: true, message: this.$t('menuUserManage.validate.menuRequired'), trigger: 'blur' } | ||
| 67 | + ], | ||
| 68 | + icon: [ | ||
| 69 | + { required: true, message: this.$t('menuUserManage.validate.iconRequired'), trigger: 'blur' } | ||
| 70 | + ], | ||
| 71 | + seq: [ | ||
| 72 | + { required: true, message: this.$t('menuUserManage.validate.seqRequired'), trigger: 'blur' } | ||
| 73 | + ] | ||
| 74 | + } | ||
| 75 | + } | ||
| 76 | + }, | ||
| 77 | + methods: { | ||
| 78 | + open() { | ||
| 79 | + this.visible = true | ||
| 80 | + this.loadMenus() | ||
| 81 | + }, | ||
| 82 | + async loadMenus() { | ||
| 83 | + try { | ||
| 84 | + const { data } = await listCatalogMenus() | ||
| 85 | + const newMenus = [] | ||
| 86 | + data.forEach(item => { | ||
| 87 | + item.childs.forEach(child => { | ||
| 88 | + child.menuGroupName = item.name | ||
| 89 | + newMenus.push(child) | ||
| 90 | + }) | ||
| 91 | + }) | ||
| 92 | + this.menus = newMenus | ||
| 93 | + } catch (error) { | ||
| 94 | + console.error('Failed to load menus:', error) | ||
| 95 | + } | ||
| 96 | + }, | ||
| 97 | + handleSubmit() { | ||
| 98 | + this.$refs.form.validate(async valid => { | ||
| 99 | + if (valid) { | ||
| 100 | + try { | ||
| 101 | + await saveMenuUser(this.form) | ||
| 102 | + this.$message.success(this.$t('menuUserManage.add.success')) | ||
| 103 | + this.$emit('success') | ||
| 104 | + this.visible = false | ||
| 105 | + } catch (error) { | ||
| 106 | + this.$message.error(error.message || this.$t('menuUserManage.add.error')) | ||
| 107 | + } | ||
| 108 | + } | ||
| 109 | + }) | ||
| 110 | + }, | ||
| 111 | + handleClose() { | ||
| 112 | + this.$refs.form.resetFields() | ||
| 113 | + this.form.icon = 'fa fa-adjust' | ||
| 114 | + this.form.seq = 1 | ||
| 115 | + } | ||
| 116 | + } | ||
| 117 | +} | ||
| 118 | +</script> | ||
| 119 | + | ||
| 120 | +<style scoped> | ||
| 121 | +.el-radio-group { | ||
| 122 | + display: flex; | ||
| 123 | + flex-wrap: wrap; | ||
| 124 | +} | ||
| 125 | + | ||
| 126 | +.el-radio { | ||
| 127 | + margin-right: 15px; | ||
| 128 | + margin-bottom: 10px; | ||
| 129 | +} | ||
| 130 | +</style> | ||
| 0 | \ No newline at end of file | 131 | \ No newline at end of file |
src/components/system/deleteMenuUser.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <el-dialog | ||
| 3 | + :title="$t('menuUserManage.delete.title')" | ||
| 4 | + :visible.sync="visible" | ||
| 5 | + width="30%" | ||
| 6 | + @close="handleClose" | ||
| 7 | + > | ||
| 8 | + <div class="delete-content"> | ||
| 9 | + <i class="el-icon-warning" style="color:#E6A23C;font-size:24px;margin-right:10px;"></i> | ||
| 10 | + <span>{{ $t('menuUserManage.delete.confirm') }}</span> | ||
| 11 | + </div> | ||
| 12 | + <div slot="footer" class="dialog-footer"> | ||
| 13 | + <el-button @click="visible = false">{{ $t('common.cancel') }}</el-button> | ||
| 14 | + <el-button type="primary" @click="handleConfirm">{{ $t('common.confirm') }}</el-button> | ||
| 15 | + </div> | ||
| 16 | + </el-dialog> | ||
| 17 | +</template> | ||
| 18 | + | ||
| 19 | +<script> | ||
| 20 | +import { deleteMenuUser } from '@/api/system/menuUserManageApi' | ||
| 21 | + | ||
| 22 | +export default { | ||
| 23 | + name: 'DeleteMenuUser', | ||
| 24 | + data() { | ||
| 25 | + return { | ||
| 26 | + visible: false, | ||
| 27 | + currentData: null | ||
| 28 | + } | ||
| 29 | + }, | ||
| 30 | + methods: { | ||
| 31 | + open(data) { | ||
| 32 | + this.currentData = data | ||
| 33 | + this.visible = true | ||
| 34 | + }, | ||
| 35 | + async handleConfirm() { | ||
| 36 | + try { | ||
| 37 | + await deleteMenuUser(this.currentData) | ||
| 38 | + this.$message.success(this.$t('menuUserManage.delete.success')) | ||
| 39 | + this.$emit('success') | ||
| 40 | + this.visible = false | ||
| 41 | + } catch (error) { | ||
| 42 | + this.$message.error(error.message || this.$t('menuUserManage.delete.error')) | ||
| 43 | + } | ||
| 44 | + }, | ||
| 45 | + handleClose() { | ||
| 46 | + this.currentData = null | ||
| 47 | + } | ||
| 48 | + } | ||
| 49 | +} | ||
| 50 | +</script> | ||
| 51 | + | ||
| 52 | +<style scoped> | ||
| 53 | +.delete-content { | ||
| 54 | + display: flex; | ||
| 55 | + align-items: center; | ||
| 56 | + justify-content: center; | ||
| 57 | + font-size: 16px; | ||
| 58 | + padding: 20px 0; | ||
| 59 | +} | ||
| 60 | +</style> | ||
| 0 | \ No newline at end of file | 61 | \ No newline at end of file |
src/components/system/searchCommunityDataList.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <el-dialog | ||
| 3 | + :visible.sync="visible" | ||
| 4 | + :title="$t('searchCommunityData.title')" | ||
| 5 | + width="80%" | ||
| 6 | + @close="handleClose" | ||
| 7 | + > | ||
| 8 | + <el-row class="margin-bottom"> | ||
| 9 | + <el-col :span="14" :offset="2"> | ||
| 10 | + <el-input | ||
| 11 | + v-model="searchValue" | ||
| 12 | + :placeholder="$t('searchCommunityData.placeholder')" | ||
| 13 | + @keyup.enter.native="doSearch" | ||
| 14 | + /> | ||
| 15 | + </el-col> | ||
| 16 | + <el-col :span="3" :offset="1"> | ||
| 17 | + <el-button type="primary" @click="doSearch"> | ||
| 18 | + {{ $t('common.search') }} | ||
| 19 | + </el-button> | ||
| 20 | + </el-col> | ||
| 21 | + <el-col :span="3"> | ||
| 22 | + <el-button @click="queryCallInTel"> | ||
| 23 | + {{ $t('searchCommunityData.callInNumber') }} | ||
| 24 | + </el-button> | ||
| 25 | + </el-col> | ||
| 26 | + </el-row> | ||
| 27 | + <el-divider /> | ||
| 28 | + <div class="margin-top margin-bottom" style="min-height: 200px;"> | ||
| 29 | + <template v-if="!noData"> | ||
| 30 | + <div class="vc-search-community-item" v-if="rooms.length > 0"> | ||
| 31 | + <div class="item-title">{{ $t('searchCommunityData.roomInfo') }}</div> | ||
| 32 | + <div class="item-content"> | ||
| 33 | + <el-link | ||
| 34 | + v-for="(item, index) in rooms" | ||
| 35 | + :key="'room'+index" | ||
| 36 | + @click="toSimplifyAcceptance(item)" | ||
| 37 | + > | ||
| 38 | + {{ item.roomName }} | ||
| 39 | + </el-link> | ||
| 40 | + </div> | ||
| 41 | + </div> | ||
| 42 | + <div class="vc-search-community-item" v-if="owners.length > 0"> | ||
| 43 | + <div class="item-title">{{ $t('searchCommunityData.ownerInfo') }}</div> | ||
| 44 | + <div class="item-content"> | ||
| 45 | + <el-link | ||
| 46 | + v-for="(item, index) in owners" | ||
| 47 | + :key="'owner'+index" | ||
| 48 | + :href="'/#/views/owner/ownerDetail?ownerId='+item.ownerId" | ||
| 49 | + target="_blank" | ||
| 50 | + > | ||
| 51 | + {{ item.name }} | ||
| 52 | + </el-link> | ||
| 53 | + </div> | ||
| 54 | + </div> | ||
| 55 | + <div class="vc-search-community-item" v-if="ownerMembers.length > 0"> | ||
| 56 | + <div class="item-title">{{ $t('searchCommunityData.ownerMember') }}</div> | ||
| 57 | + <div class="item-content"> | ||
| 58 | + <el-link | ||
| 59 | + v-for="(item, index) in ownerMembers" | ||
| 60 | + :key="'ownerMember'+index" | ||
| 61 | + :href="'/#/views/owner/ownerDetail?ownerId='+item.ownerId" | ||
| 62 | + target="_blank" | ||
| 63 | + > | ||
| 64 | + {{ item.name }} | ||
| 65 | + </el-link> | ||
| 66 | + </div> | ||
| 67 | + </div> | ||
| 68 | + <div class="vc-search-community-item" v-if="cars.length > 0"> | ||
| 69 | + <div class="item-title">{{ $t('searchCommunityData.communityCar') }}</div> | ||
| 70 | + <div class="item-content"> | ||
| 71 | + <el-link | ||
| 72 | + v-for="(item, index) in cars" | ||
| 73 | + :key="'car'+index" | ||
| 74 | + :href="'/#/views/car/carDetail?memberId='+item.carId" | ||
| 75 | + target="_blank" | ||
| 76 | + > | ||
| 77 | + {{ item.carNum }} | ||
| 78 | + </el-link> | ||
| 79 | + </div> | ||
| 80 | + </div> | ||
| 81 | + <div class="vc-search-community-item" v-if="carMembers.length > 0"> | ||
| 82 | + <div class="item-title">{{ $t('searchCommunityData.memberCar') }}</div> | ||
| 83 | + <div class="item-content"> | ||
| 84 | + <el-link | ||
| 85 | + v-for="(item, index) in carMembers" | ||
| 86 | + :key="'carMember'+index" | ||
| 87 | + :href="'/#/views/car/carDetail?memberId='+item.carId" | ||
| 88 | + target="_blank" | ||
| 89 | + > | ||
| 90 | + {{ item.carNum }} | ||
| 91 | + </el-link> | ||
| 92 | + </div> | ||
| 93 | + </div> | ||
| 94 | + <div class="vc-search-community-item" v-if="contracts.length > 0"> | ||
| 95 | + <div class="item-title">{{ $t('searchCommunityData.contract') }}</div> | ||
| 96 | + <div class="item-content"> | ||
| 97 | + <el-link | ||
| 98 | + v-for="(item, index) in contracts" | ||
| 99 | + :key="'contract'+index" | ||
| 100 | + :href="'/#/views/contract/contractDetail?contractId='+item.contractId" | ||
| 101 | + target="_blank" | ||
| 102 | + > | ||
| 103 | + {{ item.contractName }} | ||
| 104 | + </el-link> | ||
| 105 | + </div> | ||
| 106 | + </div> | ||
| 107 | + <div class="vc-search-community-item" v-if="repairs.length > 0"> | ||
| 108 | + <div class="item-title">{{ $t('searchCommunityData.repairOrder') }}</div> | ||
| 109 | + <div class="item-content"> | ||
| 110 | + <el-link | ||
| 111 | + v-for="(item, index) in repairs" | ||
| 112 | + :key="'repair'+index" | ||
| 113 | + :href="'/#/pages/property/ownerRepairDetail?repairId='+item.repairId" | ||
| 114 | + target="_blank" | ||
| 115 | + > | ||
| 116 | + {{ item.repairName }} | ||
| 117 | + </el-link> | ||
| 118 | + </div> | ||
| 119 | + </div> | ||
| 120 | + <div class="vc-search-community-item" v-if="visits.length > 0"> | ||
| 121 | + <div class="item-title">{{ $t('searchCommunityData.visitor') }}</div> | ||
| 122 | + <div class="item-content"> | ||
| 123 | + <el-link | ||
| 124 | + v-for="(item, index) in visits" | ||
| 125 | + :key="'visit'+index" | ||
| 126 | + :href="'/#/pages/property/visitDetail?vId='+item.vId+'&flowId='+item.flowId" | ||
| 127 | + target="_blank" | ||
| 128 | + > | ||
| 129 | + {{ item.vName }} | ||
| 130 | + </el-link> | ||
| 131 | + </div> | ||
| 132 | + </div> | ||
| 133 | + <div class="vc-search-community-item" v-if="staffs.length > 0"> | ||
| 134 | + <div class="item-title">{{ $t('searchCommunityData.staff') }}</div> | ||
| 135 | + <div class="item-content"> | ||
| 136 | + <el-link | ||
| 137 | + v-for="(item, index) in staffs" | ||
| 138 | + :key="'staff'+index" | ||
| 139 | + :href="'/#/views/staff/staffDetail?staffId='+item.userId" | ||
| 140 | + target="_blank" | ||
| 141 | + > | ||
| 142 | + {{ item.name }} | ||
| 143 | + </el-link> | ||
| 144 | + </div> | ||
| 145 | + </div> | ||
| 146 | + </template> | ||
| 147 | + <div v-else class="text-center" style="font-size: 38px;color: #aaa;margin-top: 100px;"> | ||
| 148 | + {{ $t('searchCommunityData.noData') }} | ||
| 149 | + </div> | ||
| 150 | + </div> | ||
| 151 | + <div slot="footer" class="dialog-footer"> | ||
| 152 | + <el-button @click="visible = false">{{ $t('common.close') }}</el-button> | ||
| 153 | + </div> | ||
| 154 | + </el-dialog> | ||
| 155 | +</template> | ||
| 156 | + | ||
| 157 | +<script> | ||
| 158 | +import { searchCommunityData, getTelMachine, postTelMachineMsg } from '@/api/system/searchCommunityDataApi' | ||
| 159 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 160 | + | ||
| 161 | +export default { | ||
| 162 | + name: 'SearchCommunityData', | ||
| 163 | + data() { | ||
| 164 | + return { | ||
| 165 | + visible: false, | ||
| 166 | + searchValue: '', | ||
| 167 | + rooms: [], | ||
| 168 | + owners: [], | ||
| 169 | + ownerMembers: [], | ||
| 170 | + cars: [], | ||
| 171 | + carMembers: [], | ||
| 172 | + contracts: [], | ||
| 173 | + repairs: [], | ||
| 174 | + visits: [], | ||
| 175 | + staffs: [], | ||
| 176 | + noData: true, | ||
| 177 | + machine: {}, | ||
| 178 | + ws: null, | ||
| 179 | + componentName: '', | ||
| 180 | + communityId: '' | ||
| 181 | + } | ||
| 182 | + }, | ||
| 183 | + created() { | ||
| 184 | + this.communityId = getCommunityId() | ||
| 185 | + this.initTelMachine() | ||
| 186 | + }, | ||
| 187 | + methods: { | ||
| 188 | + open() { | ||
| 189 | + this.visible = true | ||
| 190 | + this.clearSearchData() | ||
| 191 | + }, | ||
| 192 | + handleClose() { | ||
| 193 | + this.clearSearchData() | ||
| 194 | + }, | ||
| 195 | + initTelMachine() { | ||
| 196 | + if (!this.communityId || this.communityId === '-1') { | ||
| 197 | + return | ||
| 198 | + } | ||
| 199 | + getTelMachine({ | ||
| 200 | + page: 1, | ||
| 201 | + row: 1, | ||
| 202 | + communityId: this.communityId | ||
| 203 | + }).then(res => { | ||
| 204 | + if (res.code !== 0 || res.data.length < 1) { | ||
| 205 | + return | ||
| 206 | + } | ||
| 207 | + this.machine = res.data[0] | ||
| 208 | + this.connectTelMachine(this.machine) | ||
| 209 | + }).catch(error => { | ||
| 210 | + console.error('Failed to get tel machine:', error) | ||
| 211 | + }) | ||
| 212 | + }, | ||
| 213 | + doSearch() { | ||
| 214 | + if (!this.searchValue) { | ||
| 215 | + this.$message.warning(this.$t('searchCommunityData.inputTip')) | ||
| 216 | + return | ||
| 217 | + } | ||
| 218 | + | ||
| 219 | + searchCommunityData({ | ||
| 220 | + searchValue: this.searchValue, | ||
| 221 | + communityId: this.communityId | ||
| 222 | + }).then(res => { | ||
| 223 | + if (res.code !== 0) { | ||
| 224 | + this.$message.error(res.msg) | ||
| 225 | + return | ||
| 226 | + } | ||
| 227 | + | ||
| 228 | + this.noData = false | ||
| 229 | + const data = res.data | ||
| 230 | + this.rooms = data.rooms || [] | ||
| 231 | + this.owners = data.owners || [] | ||
| 232 | + this.ownerMembers = data.ownerMembers || [] | ||
| 233 | + this.cars = data.cars || [] | ||
| 234 | + this.carMembers = data.carMembers || [] | ||
| 235 | + this.contracts = data.contracts || [] | ||
| 236 | + this.repairs = data.repairs || [] | ||
| 237 | + this.visits = data.visitDtos || [] | ||
| 238 | + this.staffs = data.staffs || [] | ||
| 239 | + | ||
| 240 | + this.noData = !(this.rooms.length > 0 || this.owners.length > 0 || | ||
| 241 | + this.ownerMembers.length > 0 || this.cars.length > 0 || | ||
| 242 | + this.carMembers.length > 0 || this.contracts.length > 0 || | ||
| 243 | + this.repairs.length > 0 || this.visits.length > 0 || | ||
| 244 | + this.staffs.length > 0) | ||
| 245 | + }).catch(error => { | ||
| 246 | + console.error('Search failed:', error) | ||
| 247 | + }) | ||
| 248 | + }, | ||
| 249 | + toSimplifyAcceptance(room) { | ||
| 250 | + const date = new Date() | ||
| 251 | + localStorage.setItem("JAVA110_IS_BACK", date.getTime()) | ||
| 252 | + localStorage.setItem('simplifyAcceptanceSearch', JSON.stringify({ | ||
| 253 | + searchType: '1', | ||
| 254 | + searchValue: `${room.floorNum}-${room.unitNum}-${room.roomNum}`, | ||
| 255 | + searchPlaceholder: this.$t('searchCommunityData.roomPlaceholder') | ||
| 256 | + })) | ||
| 257 | + window.open('/#/pages/property/simplifyAcceptance?tab=businessAcceptance') | ||
| 258 | + }, | ||
| 259 | + clearSearchData() { | ||
| 260 | + const ws = this.ws | ||
| 261 | + const machine = this.machine | ||
| 262 | + | ||
| 263 | + this.searchValue = '' | ||
| 264 | + this.noData = true | ||
| 265 | + this.rooms = [] | ||
| 266 | + this.owners = [] | ||
| 267 | + this.ownerMembers = [] | ||
| 268 | + this.cars = [] | ||
| 269 | + this.carMembers = [] | ||
| 270 | + this.contracts = [] | ||
| 271 | + this.repairs = [] | ||
| 272 | + this.visits = [] | ||
| 273 | + this.staffs = [] | ||
| 274 | + this.machine = machine | ||
| 275 | + this.ws = ws | ||
| 276 | + }, | ||
| 277 | + queryCallInTel() { | ||
| 278 | + if (!this.ws) { | ||
| 279 | + this.$message.warning(this.$t('searchCommunityData.telNotConnected')) | ||
| 280 | + return | ||
| 281 | + } | ||
| 282 | + this.ws.send(JSON.stringify({ | ||
| 283 | + action: 'Query', | ||
| 284 | + type: 'Device', | ||
| 285 | + cb: 'cb_data' | ||
| 286 | + })) | ||
| 287 | + }, | ||
| 288 | + connectTelMachine(machine) { | ||
| 289 | + const protocol = window.location.protocol | ||
| 290 | + let url = "ws://" | ||
| 291 | + if (protocol.startsWith('https')) { | ||
| 292 | + url = "wss://" | ||
| 293 | + } | ||
| 294 | + url = `${url}${machine.machineIp}:${machine.machinePort}/APP_2AD85C71-BEF8-463C-9B4B-B672F603542A_fast` | ||
| 295 | + | ||
| 296 | + const ws = new WebSocket(url) | ||
| 297 | + | ||
| 298 | + ws.onerror = (event) => { | ||
| 299 | + console.log('WebSocket error:', event) | ||
| 300 | + setTimeout(() => { | ||
| 301 | + this.connectTelMachine(machine) | ||
| 302 | + }, 2000) | ||
| 303 | + } | ||
| 304 | + | ||
| 305 | + ws.onclose = () => { | ||
| 306 | + console.log('WebSocket closed') | ||
| 307 | + } | ||
| 308 | + | ||
| 309 | + ws.onopen = () => { | ||
| 310 | + console.log('WebSocket connected') | ||
| 311 | + } | ||
| 312 | + | ||
| 313 | + ws.onmessage = (event) => { | ||
| 314 | + try { | ||
| 315 | + const data = JSON.parse(event.data) | ||
| 316 | + console.log('WebSocket message:', data) | ||
| 317 | + | ||
| 318 | + if (data.message === 'query') { | ||
| 319 | + if (data.name === 'Device' && data.param.CallerId) { | ||
| 320 | + this.clearSearchData() | ||
| 321 | + this.searchValue = data.param.CallerId | ||
| 322 | + this.doSearch() | ||
| 323 | + return | ||
| 324 | + } | ||
| 325 | + if (data.name === 'Device' && Object.prototype.hasOwnProperty.call(data.param, 'CallerId')) { | ||
| 326 | + this.$message.warning(this.$t('searchCommunityData.noCallInNumber')) | ||
| 327 | + return | ||
| 328 | + } | ||
| 329 | + return | ||
| 330 | + } | ||
| 331 | + | ||
| 332 | + const param = data.param | ||
| 333 | + | ||
| 334 | + if (param && param.status === 'CallIn') { | ||
| 335 | + this.clearSearchData() | ||
| 336 | + this.searchValue = param.number | ||
| 337 | + this.visible = true | ||
| 338 | + this.doSearch() | ||
| 339 | + return | ||
| 340 | + } | ||
| 341 | + | ||
| 342 | + if (param && param.status === 'TalkingStart') { | ||
| 343 | + this.$emit('TalkingStart', param) | ||
| 344 | + return | ||
| 345 | + } | ||
| 346 | + | ||
| 347 | + if (param && param.status === 'TalkingEnd') { | ||
| 348 | + this.$emit('TalkingEnd', param) | ||
| 349 | + return | ||
| 350 | + } | ||
| 351 | + | ||
| 352 | + this.saveTelMachineMsg(data) | ||
| 353 | + } catch (error) { | ||
| 354 | + console.error('Error parsing WebSocket message:', error) | ||
| 355 | + } | ||
| 356 | + } | ||
| 357 | + | ||
| 358 | + this.ws = ws | ||
| 359 | + }, | ||
| 360 | + saveTelMachineMsg(data) { | ||
| 361 | + data.communityId = this.communityId | ||
| 362 | + data.machineId = this.machine.machineId | ||
| 363 | + | ||
| 364 | + postTelMachineMsg(data).then(res => { | ||
| 365 | + if (res.code !== 0) { | ||
| 366 | + console.error('Failed to save tel machine message:', res.msg) | ||
| 367 | + return | ||
| 368 | + } | ||
| 369 | + | ||
| 370 | + const param = res.data || {} | ||
| 371 | + if (param.action === 'sms') { | ||
| 372 | + this.$emit('sendTelMsg', { | ||
| 373 | + tel: param.tel, | ||
| 374 | + msgText: param.msgText | ||
| 375 | + }) | ||
| 376 | + } | ||
| 377 | + }).catch(error => { | ||
| 378 | + console.error('Failed to post tel machine message:', error) | ||
| 379 | + }) | ||
| 380 | + }, | ||
| 381 | + playTts(data) { | ||
| 382 | + if (this.ws) { | ||
| 383 | + this.ws.send(JSON.stringify({ | ||
| 384 | + action: 'PlayMusic', | ||
| 385 | + url: data.url, | ||
| 386 | + file_name: this.uuid() + '.wav', | ||
| 387 | + volume: 100, | ||
| 388 | + loop: true | ||
| 389 | + })) | ||
| 390 | + } | ||
| 391 | + }, | ||
| 392 | + hangup() { | ||
| 393 | + if (this.ws) { | ||
| 394 | + this.ws.send(JSON.stringify({ | ||
| 395 | + action: 'Hangup' | ||
| 396 | + })) | ||
| 397 | + } | ||
| 398 | + }, | ||
| 399 | + callTel(data) { | ||
| 400 | + if (this.ws) { | ||
| 401 | + this.ws.send(JSON.stringify({ | ||
| 402 | + action: 'CallOut', | ||
| 403 | + number: data.tel, | ||
| 404 | + cb: 'callout_cb' | ||
| 405 | + })) | ||
| 406 | + this.componentName = data.componentName | ||
| 407 | + } | ||
| 408 | + }, | ||
| 409 | + sendTelMsg(data) { | ||
| 410 | + if (this.ws) { | ||
| 411 | + this.ws.send(JSON.stringify({ | ||
| 412 | + action: 'SmsSend', | ||
| 413 | + number: data.tel, | ||
| 414 | + content: data.msgText | ||
| 415 | + })) | ||
| 416 | + } | ||
| 417 | + }, | ||
| 418 | + uuid() { | ||
| 419 | + return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { | ||
| 420 | + const r = Math.random() * 16 | 0 | ||
| 421 | + const v = c === 'x' ? r : (r & 0x3 | 0x8) | ||
| 422 | + return v.toString(16) | ||
| 423 | + }) | ||
| 424 | + } | ||
| 425 | + } | ||
| 426 | +} | ||
| 427 | +</script> | ||
| 428 | + | ||
| 429 | +<style scoped> | ||
| 430 | +.vc-search-community-item { | ||
| 431 | + margin-bottom: 20px; | ||
| 432 | +} | ||
| 433 | + | ||
| 434 | +.item-title { | ||
| 435 | + font-weight: bold; | ||
| 436 | + margin-bottom: 10px; | ||
| 437 | +} | ||
| 438 | + | ||
| 439 | +.item-content { | ||
| 440 | + display: flex; | ||
| 441 | + flex-wrap: wrap; | ||
| 442 | + gap: 10px; | ||
| 443 | +} | ||
| 444 | + | ||
| 445 | +.margin-top { | ||
| 446 | + margin-top: 20px; | ||
| 447 | +} | ||
| 448 | + | ||
| 449 | +.margin-bottom { | ||
| 450 | + margin-bottom: 20px; | ||
| 451 | +} | ||
| 452 | + | ||
| 453 | +.text-center { | ||
| 454 | + text-align: center; | ||
| 455 | +} | ||
| 456 | +</style> | ||
| 0 | \ No newline at end of file | 457 | \ No newline at end of file |
src/components/system/viewMenuUserList.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="view-menu-user-container"> | ||
| 3 | + <el-dialog :visible.sync="dialogVisible" width="80%" :before-close="handleClose" | ||
| 4 | + custom-class="view-menu-user-dialog"> | ||
| 5 | + <el-row> | ||
| 6 | + <el-col :span="22"></el-col> | ||
| 7 | + <el-col :span="2" class="text-right"> | ||
| 8 | + <i class="el-icon-close close-icon" @click="handleClose"></i> | ||
| 9 | + </el-col> | ||
| 10 | + </el-row> | ||
| 11 | + | ||
| 12 | + <el-row class="menu-items" :gutter="20"> | ||
| 13 | + <el-col v-for="(item, index) in viewMenuUserInfo.menus" :key="index" :span="4" | ||
| 14 | + class="text-center menu-item" @click.native="jumpToUserPage(item)"> | ||
| 15 | + <div> | ||
| 16 | + <i :class="item.icon" class="menu-icon"></i> | ||
| 17 | + </div> | ||
| 18 | + <div class="menu-name"> | ||
| 19 | + {{ item.name }} | ||
| 20 | + </div> | ||
| 21 | + </el-col> | ||
| 22 | + </el-row> | ||
| 23 | + | ||
| 24 | + <el-row class="menu-items" :gutter="20"> | ||
| 25 | + <el-col :span="4" class="text-center menu-item" @click.native="toUserMenu"> | ||
| 26 | + <div> | ||
| 27 | + <i class="el-icon-plus menu-icon"></i> | ||
| 28 | + </div> | ||
| 29 | + <div class="menu-name"> | ||
| 30 | + {{ $t('viewMenuUser.custom') }} | ||
| 31 | + </div> | ||
| 32 | + </el-col> | ||
| 33 | + </el-row> | ||
| 34 | + </el-dialog> | ||
| 35 | + </div> | ||
| 36 | +</template> | ||
| 37 | + | ||
| 38 | +<script> | ||
| 39 | +import { listMenuUser } from '@/api/system/viewMenuUserApi' | ||
| 40 | + | ||
| 41 | +export default { | ||
| 42 | + name: 'ViewMenuUserList', | ||
| 43 | + data() { | ||
| 44 | + return { | ||
| 45 | + dialogVisible: false, | ||
| 46 | + viewMenuUserInfo: { | ||
| 47 | + menus: [] | ||
| 48 | + } | ||
| 49 | + } | ||
| 50 | + }, | ||
| 51 | + methods: { | ||
| 52 | + open() { | ||
| 53 | + this.dialogVisible = true | ||
| 54 | + this.listViewMenuUsers() | ||
| 55 | + }, | ||
| 56 | + handleClose() { | ||
| 57 | + this.dialogVisible = false | ||
| 58 | + }, | ||
| 59 | + async listViewMenuUsers() { | ||
| 60 | + try { | ||
| 61 | + const params = { | ||
| 62 | + page: 1, | ||
| 63 | + row: 100 | ||
| 64 | + } | ||
| 65 | + const { data } = await listMenuUser(params) | ||
| 66 | + this.viewMenuUserInfo.menus = data | ||
| 67 | + } catch (error) { | ||
| 68 | + console.error('Failed to fetch menu data:', error) | ||
| 69 | + } | ||
| 70 | + }, | ||
| 71 | + toUserMenu() { | ||
| 72 | + this.handleClose() | ||
| 73 | + this.$router.push('/views/system/menuUserManage?tab=commonMenu') | ||
| 74 | + }, | ||
| 75 | + jumpToUserPage(item) { | ||
| 76 | + this.handleClose() | ||
| 77 | + let href = item.url | ||
| 78 | + if (href.indexOf('/#/') > -1) { | ||
| 79 | + href = href.replace('/#/', '/') | ||
| 80 | + } | ||
| 81 | + if (href.indexOf('?') > -1) { | ||
| 82 | + href += `&tab=${item.name}` | ||
| 83 | + } else { | ||
| 84 | + href += `?tab=${item.name}` | ||
| 85 | + } | ||
| 86 | + this.$router.push(href) | ||
| 87 | + } | ||
| 88 | + } | ||
| 89 | +} | ||
| 90 | +</script> | ||
| 91 | + | ||
| 92 | +<style lang="scss" scoped> | ||
| 93 | +.view-menu-user-container { | ||
| 94 | + ::v-deep .view-menu-user-dialog { | ||
| 95 | + background: rgba(66, 66, 66, 0.9); | ||
| 96 | + color: #fff; | ||
| 97 | + box-shadow: 0 0px 0px rgba(0, 0, 0, 0.3); | ||
| 98 | + | ||
| 99 | + .el-dialog__header { | ||
| 100 | + display: none; | ||
| 101 | + } | ||
| 102 | + | ||
| 103 | + .el-dialog__body { | ||
| 104 | + color: #fff; | ||
| 105 | + padding: 20px; | ||
| 106 | + } | ||
| 107 | + } | ||
| 108 | + | ||
| 109 | + .close-icon { | ||
| 110 | + font-size: 18px; | ||
| 111 | + cursor: pointer; | ||
| 112 | + | ||
| 113 | + &:hover { | ||
| 114 | + color: #409EFF; | ||
| 115 | + } | ||
| 116 | + } | ||
| 117 | + | ||
| 118 | + .menu-items { | ||
| 119 | + margin-top: 40px; | ||
| 120 | + cursor: pointer; | ||
| 121 | + } | ||
| 122 | + | ||
| 123 | + .menu-item { | ||
| 124 | + margin-bottom: 20px; | ||
| 125 | + | ||
| 126 | + &:hover { | ||
| 127 | + | ||
| 128 | + .menu-icon, | ||
| 129 | + .menu-name { | ||
| 130 | + color: #409EFF; | ||
| 131 | + } | ||
| 132 | + } | ||
| 133 | + } | ||
| 134 | + | ||
| 135 | + .menu-icon { | ||
| 136 | + font-size: 48px; | ||
| 137 | + margin-bottom: 10px; | ||
| 138 | + } | ||
| 139 | + | ||
| 140 | + .menu-name { | ||
| 141 | + font-size: 14px; | ||
| 142 | + } | ||
| 143 | +} | ||
| 144 | +</style> | ||
| 0 | \ No newline at end of file | 145 | \ No newline at end of file |
src/i18n/systemI18n.js
| @@ -11,6 +11,7 @@ import { messages as downloadTempFileMessages } from '../views/system/downloadTe | @@ -11,6 +11,7 @@ import { messages as downloadTempFileMessages } from '../views/system/downloadTe | ||
| 11 | import { messages as assetImportLogMessages } from '../views/system/assetImportLogLang' | 11 | import { messages as assetImportLogMessages } from '../views/system/assetImportLogLang' |
| 12 | import { messages as assetImportLogDetailMessages } from '../views/system/assetImportLogDetailLang' | 12 | import { messages as assetImportLogDetailMessages } from '../views/system/assetImportLogDetailLang' |
| 13 | import { messages as payFeeQrcodeMessages } from '../views/fee/payFeeQrcodeLang' | 13 | import { messages as payFeeQrcodeMessages } from '../views/fee/payFeeQrcodeLang' |
| 14 | +import { messages as menuUserManageMessages } from '../views/system/menuUserManageLang' | ||
| 14 | 15 | ||
| 15 | export const messages = { | 16 | export const messages = { |
| 16 | en: { | 17 | en: { |
| @@ -27,6 +28,7 @@ export const messages = { | @@ -27,6 +28,7 @@ export const messages = { | ||
| 27 | ...assetImportLogMessages.en, | 28 | ...assetImportLogMessages.en, |
| 28 | ...assetImportLogDetailMessages.en, | 29 | ...assetImportLogDetailMessages.en, |
| 29 | ...payFeeQrcodeMessages.en, | 30 | ...payFeeQrcodeMessages.en, |
| 31 | + ...menuUserManageMessages.en, | ||
| 30 | }, | 32 | }, |
| 31 | zh: { | 33 | zh: { |
| 32 | ...communitySettingManageMessages.zh, | 34 | ...communitySettingManageMessages.zh, |
| @@ -42,5 +44,6 @@ export const messages = { | @@ -42,5 +44,6 @@ export const messages = { | ||
| 42 | ...assetImportLogMessages.zh, | 44 | ...assetImportLogMessages.zh, |
| 43 | ...assetImportLogDetailMessages.zh, | 45 | ...assetImportLogDetailMessages.zh, |
| 44 | ...payFeeQrcodeMessages.zh, | 46 | ...payFeeQrcodeMessages.zh, |
| 47 | + ...menuUserManageMessages.zh, | ||
| 45 | } | 48 | } |
| 46 | } | 49 | } |
| 47 | \ No newline at end of file | 50 | \ No newline at end of file |
src/router/systemRouter.js
| @@ -74,4 +74,9 @@ export default [ | @@ -74,4 +74,9 @@ export default [ | ||
| 74 | name: '/pages/fee/payFeeQrcode', | 74 | name: '/pages/fee/payFeeQrcode', |
| 75 | component: () => import('@/views/fee/payFeeQrcodeList.vue') | 75 | component: () => import('@/views/fee/payFeeQrcodeList.vue') |
| 76 | }, | 76 | }, |
| 77 | + { | ||
| 78 | + path: '/views/system/menuUserManage', | ||
| 79 | + name: '/views/system/menuUserManage', | ||
| 80 | + component: () => import('@/views/system/menuUserManageList.vue') | ||
| 81 | + }, | ||
| 77 | ] | 82 | ] |
| 78 | \ No newline at end of file | 83 | \ No newline at end of file |
src/views/layout/layout.vue
| @@ -71,6 +71,8 @@ | @@ -71,6 +71,8 @@ | ||
| 71 | </el-main> | 71 | </el-main> |
| 72 | </el-container> | 72 | </el-container> |
| 73 | <more-community ref="moreCommunity" /> | 73 | <more-community ref="moreCommunity" /> |
| 74 | + <view-menu-user-list ref="viewMenuUserModel" /> | ||
| 75 | + <search-community-data-list ref="searchCommunityDataModel" /> | ||
| 74 | </el-container> | 76 | </el-container> |
| 75 | </template> | 77 | </template> |
| 76 | 78 | ||
| @@ -80,6 +82,8 @@ import { getStoreInfo } from "@/api/user/indexApi" | @@ -80,6 +82,8 @@ import { getStoreInfo } from "@/api/user/indexApi" | ||
| 80 | import { deepCopy, setCurrentCommunity } from "@/utils/vc" | 82 | import { deepCopy, setCurrentCommunity } from "@/utils/vc" |
| 81 | import { getCommunityName, _loadCommunityInfo } from '@/api/community/communityApi' | 83 | import { getCommunityName, _loadCommunityInfo } from '@/api/community/communityApi' |
| 82 | import moreCommunity from '@/components/community/moreCommunity.vue' | 84 | import moreCommunity from '@/components/community/moreCommunity.vue' |
| 85 | +import viewMenuUserList from '@/components/system/viewMenuUserList.vue' | ||
| 86 | +import searchCommunityDataList from '@/components/system/searchCommunityDataList.vue' | ||
| 83 | 87 | ||
| 84 | export default { | 88 | export default { |
| 85 | name: 'Layout', | 89 | name: 'Layout', |
| @@ -113,7 +117,9 @@ export default { | @@ -113,7 +117,9 @@ export default { | ||
| 113 | this.loadCommunity() | 117 | this.loadCommunity() |
| 114 | }, | 118 | }, |
| 115 | components: { | 119 | components: { |
| 116 | - moreCommunity | 120 | + moreCommunity, |
| 121 | + viewMenuUserList, | ||
| 122 | + searchCommunityDataList | ||
| 117 | }, | 123 | }, |
| 118 | methods: { | 124 | methods: { |
| 119 | async loadCommunity() { | 125 | async loadCommunity() { |
| @@ -152,7 +158,9 @@ export default { | @@ -152,7 +158,9 @@ export default { | ||
| 152 | }, | 158 | }, |
| 153 | _changeMenuCatalog(_catalog, _isJump) { | 159 | _changeMenuCatalog(_catalog, _isJump) { |
| 154 | this.activeMenu = _catalog.caId; | 160 | this.activeMenu = _catalog.caId; |
| 155 | - | 161 | + if (this._showModelDiv(_catalog)) { |
| 162 | + return; | ||
| 163 | + } | ||
| 156 | if (_catalog.caId === '1') { | 164 | if (_catalog.caId === '1') { |
| 157 | this.$router.push('/#/pages/mall/product'); | 165 | this.$router.push('/#/pages/mall/product'); |
| 158 | } | 166 | } |
| @@ -172,7 +180,7 @@ export default { | @@ -172,7 +180,7 @@ export default { | ||
| 172 | } | 180 | } |
| 173 | this.loadMenuTree(_catalog) | 181 | this.loadMenuTree(_catalog) |
| 174 | }, | 182 | }, |
| 175 | - | 183 | + |
| 176 | handleCommand(command) { | 184 | handleCommand(command) { |
| 177 | if (command === 'logout') { | 185 | if (command === 'logout') { |
| 178 | // 处理退出登录 | 186 | // 处理退出登录 |
| @@ -260,7 +268,7 @@ export default { | @@ -260,7 +268,7 @@ export default { | ||
| 260 | console.log(_href, _tabName) | 268 | console.log(_href, _tabName) |
| 261 | // 子菜单默认选中 | 269 | // 子菜单默认选中 |
| 262 | this._setSelectedMenusChild(_href); | 270 | this._setSelectedMenusChild(_href); |
| 263 | - if(_href.indexOf('.html') > -1){ | 271 | + if (_href.indexOf('.html') > -1) { |
| 264 | window.open(_href, '_blank') | 272 | window.open(_href, '_blank') |
| 265 | return | 273 | return |
| 266 | } | 274 | } |
| @@ -275,7 +283,16 @@ export default { | @@ -275,7 +283,16 @@ export default { | ||
| 275 | } | 283 | } |
| 276 | }) | 284 | }) |
| 277 | }, | 285 | }, |
| 278 | - | 286 | + _showModelDiv: function (_catalog) { |
| 287 | + console.log(_catalog) | ||
| 288 | + if (_catalog.url.startsWith('?')) { | ||
| 289 | + let _modelName = _catalog.url.substring(1, _catalog.url.length); | ||
| 290 | + this.$refs[_modelName].open() | ||
| 291 | + return true; | ||
| 292 | + } | ||
| 293 | + return false; | ||
| 294 | + } | ||
| 295 | + | ||
| 279 | } | 296 | } |
| 280 | } | 297 | } |
| 281 | </script> | 298 | </script> |
src/views/oa/attendanceClassesStaffManageList.vue
| @@ -185,7 +185,7 @@ export default { | @@ -185,7 +185,7 @@ export default { | ||
| 185 | this.$refs.viewImage.open(url) | 185 | this.$refs.viewImage.open(url) |
| 186 | }, | 186 | }, |
| 187 | openStaffDetail(staff) { | 187 | openStaffDetail(staff) { |
| 188 | - this.$router.push(`/staff/staffDetail?staffId=${staff.staffId}`) | 188 | + this.$router.push(`/views/staff/staffDetail?staffId=${staff.staffId}`) |
| 189 | }, | 189 | }, |
| 190 | handleSizeChange(val) { | 190 | handleSizeChange(val) { |
| 191 | this.page.size = val | 191 | this.page.size = val |
src/views/system/menuUserManageLang.js
0 → 100644
| 1 | +export const messages = { | ||
| 2 | + en: { | ||
| 3 | + menuUserManage: { | ||
| 4 | + search: { | ||
| 5 | + title: 'Search Conditions', | ||
| 6 | + muId: 'Please enter ID', | ||
| 7 | + name: 'Please enter menu name', | ||
| 8 | + seq: 'Please enter sequence' | ||
| 9 | + }, | ||
| 10 | + list: { | ||
| 11 | + title: 'Common Menu' | ||
| 12 | + }, | ||
| 13 | + table: { | ||
| 14 | + muId: 'ID', | ||
| 15 | + name: 'Menu', | ||
| 16 | + icon: 'Icon', | ||
| 17 | + seq: 'Sequence' | ||
| 18 | + }, | ||
| 19 | + add: { | ||
| 20 | + title: 'Add Menu', | ||
| 21 | + menu: 'Menu', | ||
| 22 | + menuPlaceholder: 'Required, please select menu', | ||
| 23 | + icon: 'Icon', | ||
| 24 | + seq: 'Sequence', | ||
| 25 | + seqPlaceholder: 'Required, please enter sequence', | ||
| 26 | + success: 'Add success', | ||
| 27 | + error: 'Add failed' | ||
| 28 | + }, | ||
| 29 | + delete: { | ||
| 30 | + title: 'Confirm Operation', | ||
| 31 | + confirm: 'Are you sure to delete this menu?', | ||
| 32 | + success: 'Delete success', | ||
| 33 | + error: 'Delete failed' | ||
| 34 | + }, | ||
| 35 | + validate: { | ||
| 36 | + menuRequired: 'Menu is required', | ||
| 37 | + iconRequired: 'Icon is required', | ||
| 38 | + seqRequired: 'Sequence is required' | ||
| 39 | + }, | ||
| 40 | + fetchError: 'Failed to fetch menu data' | ||
| 41 | + } | ||
| 42 | + }, | ||
| 43 | + zh: { | ||
| 44 | + menuUserManage: { | ||
| 45 | + search: { | ||
| 46 | + title: '查询条件', | ||
| 47 | + muId: '请输入编号', | ||
| 48 | + name: '请输入菜单', | ||
| 49 | + seq: '请输入列顺序' | ||
| 50 | + }, | ||
| 51 | + list: { | ||
| 52 | + title: '常用菜单' | ||
| 53 | + }, | ||
| 54 | + table: { | ||
| 55 | + muId: '编号', | ||
| 56 | + name: '菜单', | ||
| 57 | + icon: '图标', | ||
| 58 | + seq: '顺序' | ||
| 59 | + }, | ||
| 60 | + add: { | ||
| 61 | + title: '添加菜单', | ||
| 62 | + menu: '菜单', | ||
| 63 | + menuPlaceholder: '必填,请选择菜单', | ||
| 64 | + icon: '图标', | ||
| 65 | + seq: '列顺序', | ||
| 66 | + seqPlaceholder: '必填,请填写列顺序', | ||
| 67 | + success: '添加成功', | ||
| 68 | + error: '添加失败' | ||
| 69 | + }, | ||
| 70 | + delete: { | ||
| 71 | + title: '请确认您的操作', | ||
| 72 | + confirm: '确定删除常用菜单?', | ||
| 73 | + success: '删除成功', | ||
| 74 | + error: '删除失败' | ||
| 75 | + }, | ||
| 76 | + validate: { | ||
| 77 | + menuRequired: '菜单不能为空', | ||
| 78 | + iconRequired: '图标不能为空', | ||
| 79 | + seqRequired: '列顺序不能为空' | ||
| 80 | + }, | ||
| 81 | + fetchError: '获取菜单数据失败' | ||
| 82 | + } | ||
| 83 | + } | ||
| 84 | +} | ||
| 0 | \ No newline at end of file | 85 | \ No newline at end of file |
src/views/system/menuUserManageList.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="menu-user-manage-container"> | ||
| 3 | + <!-- 查询条件 --> | ||
| 4 | + <el-card class="search-wrapper"> | ||
| 5 | + <div slot="header" class="flex justify-between"> | ||
| 6 | + <span>{{ $t('menuUserManage.search.title') }}</span> | ||
| 7 | + </div> | ||
| 8 | + <el-row :gutter="20"> | ||
| 9 | + <el-col :span="6"> | ||
| 10 | + <el-input v-model="searchForm.muId" :placeholder="$t('menuUserManage.search.muId')" clearable | ||
| 11 | + @keyup.enter.native="handleSearch" /> | ||
| 12 | + </el-col> | ||
| 13 | + <el-col :span="6"> | ||
| 14 | + <el-input v-model="searchForm.name" :placeholder="$t('menuUserManage.search.name')" clearable | ||
| 15 | + @keyup.enter.native="handleSearch" /> | ||
| 16 | + </el-col> | ||
| 17 | + <el-col :span="6"> | ||
| 18 | + <el-input v-model="searchForm.seq" :placeholder="$t('menuUserManage.search.seq')" clearable | ||
| 19 | + @keyup.enter.native="handleSearch" /> | ||
| 20 | + </el-col> | ||
| 21 | + <el-col :span="6"> | ||
| 22 | + <el-button type="primary" @click="handleSearch">{{ $t('common.search') }}</el-button> | ||
| 23 | + <el-button @click="handleReset">{{ $t('common.reset') }}</el-button> | ||
| 24 | + </el-col> | ||
| 25 | + </el-row> | ||
| 26 | + </el-card> | ||
| 27 | + | ||
| 28 | + <!-- 常用菜单列表 --> | ||
| 29 | + <el-card class="list-wrapper"> | ||
| 30 | + <div slot="header" class="flex justify-between"> | ||
| 31 | + <span>{{ $t('menuUserManage.list.title') }}</span> | ||
| 32 | + <el-button type="primary" size="small" class="float-right" @click="handleAdd"> | ||
| 33 | + <i class="el-icon-plus"></i> {{ $t('common.add') }} | ||
| 34 | + </el-button> | ||
| 35 | + </div> | ||
| 36 | + | ||
| 37 | + <el-table v-loading="loading" :data="tableData" border style="width: 100%"> | ||
| 38 | + <el-table-column prop="muId" :label="$t('menuUserManage.table.muId')" align="center" /> | ||
| 39 | + <el-table-column prop="name" :label="$t('menuUserManage.table.name')" align="center" /> | ||
| 40 | + <el-table-column :label="$t('menuUserManage.table.icon')" align="center"> | ||
| 41 | + <template slot-scope="scope"> | ||
| 42 | + <i :class="scope.row.icon"></i> | ||
| 43 | + </template> | ||
| 44 | + </el-table-column> | ||
| 45 | + <el-table-column prop="seq" :label="$t('menuUserManage.table.seq')" align="center" /> | ||
| 46 | + <el-table-column :label="$t('common.operation')" align="center" width="150"> | ||
| 47 | + <template slot-scope="scope"> | ||
| 48 | + <el-button size="mini" type="danger" @click="handleDelete(scope.row)"> | ||
| 49 | + {{ $t('common.delete') }} | ||
| 50 | + </el-button> | ||
| 51 | + </template> | ||
| 52 | + </el-table-column> | ||
| 53 | + </el-table> | ||
| 54 | + | ||
| 55 | + <el-pagination :current-page.sync="page.current" :page-sizes="[10, 20, 30, 50]" :page-size="page.size" | ||
| 56 | + :total="page.total" layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange" | ||
| 57 | + @current-change="handleCurrentChange" /> | ||
| 58 | + </el-card> | ||
| 59 | + | ||
| 60 | + <!-- 添加菜单弹窗 --> | ||
| 61 | + <add-menu-user ref="addMenuUser" @success="handleSuccess" /> | ||
| 62 | + | ||
| 63 | + <!-- 删除菜单确认弹窗 --> | ||
| 64 | + <delete-menu-user ref="deleteMenuUser" @success="handleSuccess" /> | ||
| 65 | + </div> | ||
| 66 | +</template> | ||
| 67 | + | ||
| 68 | +<script> | ||
| 69 | +import { listMenuUser } from '@/api/system/menuUserManageApi' | ||
| 70 | +import AddMenuUser from '@/components/system/addMenuUser' | ||
| 71 | +import DeleteMenuUser from '@/components/system/deleteMenuUser' | ||
| 72 | + | ||
| 73 | +export default { | ||
| 74 | + name: 'MenuUserManageList', | ||
| 75 | + components: { | ||
| 76 | + AddMenuUser, | ||
| 77 | + DeleteMenuUser | ||
| 78 | + }, | ||
| 79 | + data() { | ||
| 80 | + return { | ||
| 81 | + loading: false, | ||
| 82 | + searchForm: { | ||
| 83 | + muId: '', | ||
| 84 | + name: '', | ||
| 85 | + seq: '' | ||
| 86 | + }, | ||
| 87 | + tableData: [], | ||
| 88 | + page: { | ||
| 89 | + current: 1, | ||
| 90 | + size: 10, | ||
| 91 | + total: 0 | ||
| 92 | + } | ||
| 93 | + } | ||
| 94 | + }, | ||
| 95 | + created() { | ||
| 96 | + this.getList() | ||
| 97 | + }, | ||
| 98 | + methods: { | ||
| 99 | + async getList() { | ||
| 100 | + try { | ||
| 101 | + this.loading = true | ||
| 102 | + const params = { | ||
| 103 | + page: this.page.current, | ||
| 104 | + row: this.page.size, | ||
| 105 | + ...this.searchForm | ||
| 106 | + } | ||
| 107 | + const { data, total } = await listMenuUser(params) | ||
| 108 | + this.tableData = data | ||
| 109 | + this.page.total = total | ||
| 110 | + } catch (error) { | ||
| 111 | + this.$message.error(this.$t('menuUserManage.fetchError')) | ||
| 112 | + } finally { | ||
| 113 | + this.loading = false | ||
| 114 | + } | ||
| 115 | + }, | ||
| 116 | + handleSearch() { | ||
| 117 | + this.page.current = 1 | ||
| 118 | + this.getList() | ||
| 119 | + }, | ||
| 120 | + handleReset() { | ||
| 121 | + this.searchForm = { | ||
| 122 | + muId: '', | ||
| 123 | + name: '', | ||
| 124 | + seq: '' | ||
| 125 | + } | ||
| 126 | + this.handleSearch() | ||
| 127 | + }, | ||
| 128 | + handleAdd() { | ||
| 129 | + this.$refs.addMenuUser.open() | ||
| 130 | + }, | ||
| 131 | + handleDelete(row) { | ||
| 132 | + this.$refs.deleteMenuUser.open(row) | ||
| 133 | + }, | ||
| 134 | + handleSuccess() { | ||
| 135 | + this.getList() | ||
| 136 | + }, | ||
| 137 | + handleSizeChange(val) { | ||
| 138 | + this.page.size = val | ||
| 139 | + this.getList() | ||
| 140 | + }, | ||
| 141 | + handleCurrentChange(val) { | ||
| 142 | + this.page.current = val | ||
| 143 | + this.getList() | ||
| 144 | + } | ||
| 145 | + } | ||
| 146 | +} | ||
| 147 | +</script> | ||
| 148 | + | ||
| 149 | +<style lang="scss" scoped> | ||
| 150 | +.menu-user-manage-container { | ||
| 151 | + padding: 20px; | ||
| 152 | + | ||
| 153 | + .search-wrapper { | ||
| 154 | + margin-bottom: 20px; | ||
| 155 | + | ||
| 156 | + .el-row { | ||
| 157 | + margin-bottom: -20px; | ||
| 158 | + } | ||
| 159 | + | ||
| 160 | + .el-col { | ||
| 161 | + margin-bottom: 20px; | ||
| 162 | + } | ||
| 163 | + } | ||
| 164 | + | ||
| 165 | + .list-wrapper { | ||
| 166 | + .el-pagination { | ||
| 167 | + margin-top: 20px; | ||
| 168 | + text-align: right; | ||
| 169 | + } | ||
| 170 | + } | ||
| 171 | +} | ||
| 172 | +</style> | ||
| 0 | \ No newline at end of file | 173 | \ No newline at end of file |
src/views/system/systemInfoManageLang.js
| @@ -17,7 +17,27 @@ export const messages = { | @@ -17,7 +17,27 @@ export const messages = { | ||
| 17 | required: '{field} is required', | 17 | required: '{field} is required', |
| 18 | maxLength: '{field} cannot exceed {length} characters', | 18 | maxLength: '{field} cannot exceed {length} characters', |
| 19 | fetchError: 'Failed to fetch system information' | 19 | fetchError: 'Failed to fetch system information' |
| 20 | + }, | ||
| 21 | + searchCommunityData: { | ||
| 22 | + title: 'Search', | ||
| 23 | + placeholder: 'Please enter house number, owner name, car number or family member name, etc.', | ||
| 24 | + callInNumber: 'Calling number', | ||
| 25 | + noData: 'Sorry, no data available', | ||
| 26 | + inputTip: 'Please enter search criteria', | ||
| 27 | + telNotConnected: 'Fixed telephone not connected', | ||
| 28 | + noCallInNumber: 'No calling number returned from the telephone', | ||
| 29 | + roomInfo: 'Room Information', | ||
| 30 | + ownerInfo: 'Owner Information', | ||
| 31 | + ownerMember: 'Owner Member', | ||
| 32 | + communityCar: 'Community Vehicle', | ||
| 33 | + memberCar: 'Member Vehicle', | ||
| 34 | + contract: 'Contract', | ||
| 35 | + repairOrder: 'Repair Order', | ||
| 36 | + visitor: 'Visitor', | ||
| 37 | + staff: 'Staff', | ||
| 38 | + roomPlaceholder: 'Please enter room number like building-unit-room, e.g. 1-1-1' | ||
| 20 | } | 39 | } |
| 40 | + | ||
| 21 | }, | 41 | }, |
| 22 | zh: { | 42 | zh: { |
| 23 | systemInfo: { | 43 | systemInfo: { |
| @@ -37,6 +57,25 @@ export const messages = { | @@ -37,6 +57,25 @@ export const messages = { | ||
| 37 | required: '{field}不能为空', | 57 | required: '{field}不能为空', |
| 38 | maxLength: '{field}不能超过{length}个字符', | 58 | maxLength: '{field}不能超过{length}个字符', |
| 39 | fetchError: '获取系统信息失败' | 59 | fetchError: '获取系统信息失败' |
| 60 | + }, | ||
| 61 | + searchCommunityData: { | ||
| 62 | + title: '搜索', | ||
| 63 | + placeholder: '请输入房屋编号,业主名称,车辆编号或者家庭成员名称等', | ||
| 64 | + callInNumber: '通话中号码', | ||
| 65 | + noData: '抱歉,没有数据', | ||
| 66 | + inputTip: '请输入查询条件', | ||
| 67 | + telNotConnected: '未连接固定电话', | ||
| 68 | + noCallInNumber: '座机未返回通话中号码', | ||
| 69 | + roomInfo: '房屋信息', | ||
| 70 | + ownerInfo: '业主信息', | ||
| 71 | + ownerMember: '业主成员', | ||
| 72 | + communityCar: '小区车辆', | ||
| 73 | + memberCar: '成员车辆', | ||
| 74 | + contract: '合同', | ||
| 75 | + repairOrder: '报修工单', | ||
| 76 | + visitor: '访客', | ||
| 77 | + staff: '员工', | ||
| 78 | + roomPlaceholder: '请输入房屋编号 楼栋-单元-房屋 如1-1-1' | ||
| 40 | } | 79 | } |
| 41 | } | 80 | } |
| 42 | } | 81 | } |
| 43 | \ No newline at end of file | 82 | \ No newline at end of file |