Commit c85e0853e2d6489182db9ad106b58a3eb964ea7d

Authored by wuxw
1 parent 2f9e3ba9

业主详情开发完成

Showing 66 changed files with 5111 additions and 284 deletions
src/api/owner/addOwnerMemberApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +export function saveOwnerMember(data) {
  4 + return new Promise((resolve, reject) => {
  5 + request({
  6 + url: '/owner.saveOwnerMember',
  7 + method: 'post',
  8 + data
  9 + }).then(response => {
  10 + const res = response.data
  11 + if (res.code === 0) {
  12 + resolve(res)
  13 + } else {
  14 + reject(new Error(res.msg || 'Failed to save owner member'))
  15 + }
  16 + }).catch(error => {
  17 + reject(error)
  18 + })
  19 + })
  20 +}
0 21 \ No newline at end of file
... ...
src/api/owner/ownerDetailAccessControlApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +export function listMachineTranslates(params) {
  4 + return new Promise((resolve, reject) => {
  5 + request({
  6 + url: '/machineTranslate.listMachineTranslates',
  7 + method: 'get',
  8 + params
  9 + }).then(response => {
  10 + const res = response.data
  11 + if (res.code === 0) {
  12 + resolve(res)
  13 + } else {
  14 + reject(new Error(res.msg || '获取门禁同步记录失败'))
  15 + }
  16 + }).catch(error => {
  17 + reject(error)
  18 + })
  19 + })
  20 +}
0 21 \ No newline at end of file
... ...
src/api/owner/ownerDetailAccessControlRecordApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +export function getOpenApi(params) {
  4 + return new Promise((resolve, reject) => {
  5 + request({
  6 + url: '/iot.getOpenApi',
  7 + method: 'get',
  8 + params
  9 + }).then(response => {
  10 + const res = response.data
  11 + if (res.code === 0) {
  12 + resolve(res)
  13 + } else {
  14 + reject(new Error(res.msg || '获取门禁记录失败'))
  15 + }
  16 + }).catch(error => {
  17 + reject(error)
  18 + })
  19 + })
  20 +}
0 21 \ No newline at end of file
... ...
src/api/owner/ownerDetailAccountApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +export function queryCommunityOwnerAccount(params) {
  4 + return new Promise((resolve, reject) => {
  5 + request({
  6 + url: '/account.queryCommunityOwnerAccount',
  7 + method: 'get',
  8 + params
  9 + }).then(response => {
  10 + const res = response.data
  11 + if (res.code == 0) {
  12 + resolve(res)
  13 + } else {
  14 + reject(new Error(res.msg || '获取业主账户列表失败'))
  15 + }
  16 + }).catch(error => {
  17 + reject(error)
  18 + })
  19 + })
  20 +}
0 21 \ No newline at end of file
... ...
src/api/owner/ownerDetailAccountReceiptApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +export function listAccountReceipt(params) {
  4 + return new Promise((resolve, reject) => {
  5 + request({
  6 + url: '/receipt.listAccountReceipt',
  7 + method: 'get',
  8 + params
  9 + }).then(response => {
  10 + const res = response.data
  11 + if (res.code === 0) {
  12 + resolve(res)
  13 + } else {
  14 + reject(new Error(res.msg || '获取账户收据列表失败'))
  15 + }
  16 + }).catch(error => {
  17 + reject(error)
  18 + })
  19 + })
  20 +}
0 21 \ No newline at end of file
... ...
src/api/owner/ownerDetailApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +// Query owner information
  4 +export function queryOwners(params) {
  5 + return new Promise((resolve, reject) => {
  6 + request({
  7 + url: '/owner.queryOwners',
  8 + method: 'get',
  9 + params
  10 + }).then(response => {
  11 + const res = response.data
  12 + if (res.code === 0) {
  13 + resolve(res)
  14 + } else {
  15 + reject(new Error(res.msg || 'Failed to query owners'))
  16 + }
  17 + }).catch(error => {
  18 + reject(error)
  19 + })
  20 + })
  21 +}
0 22 \ No newline at end of file
... ...
src/api/owner/ownerDetailAppUserApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +export function listAuditAppUserBindingOwners(params) {
  4 + return new Promise((resolve, reject) => {
  5 + request({
  6 + url: '/owner.listAuditAppUserBindingOwners',
  7 + method: 'get',
  8 + params
  9 + }).then(response => {
  10 + const res = response.data
  11 + if (res.code == 0) {
  12 + resolve(res)
  13 + } else {
  14 + reject(new Error(res.msg || '获取业主APP用户列表失败'))
  15 + }
  16 + }).catch(error => {
  17 + reject(error)
  18 + })
  19 + })
  20 +}
  21 +
  22 +export function updateAppUserBindingOwner(data) {
  23 + return new Promise((resolve, reject) => {
  24 + request({
  25 + url: '/owner.updateAppUserBindingOwner',
  26 + method: 'post',
  27 + data
  28 + }).then(response => {
  29 + const res = response.data
  30 + if (res.code == 0) {
  31 + resolve(res)
  32 + } else {
  33 + reject(new Error(res.msg || '审核业主APP用户失败'))
  34 + }
  35 + }).catch(error => {
  36 + reject(error)
  37 + })
  38 + })
  39 +}
0 40 \ No newline at end of file
... ...
src/api/owner/ownerDetailCarApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +export function queryOwnerCars(params) {
  4 + return new Promise((resolve, reject) => {
  5 + request({
  6 + url: '/owner.queryOwnerCars',
  7 + method: 'get',
  8 + params
  9 + }).then(response => {
  10 + const res = response.data
  11 + if (res.code === 0) {
  12 + resolve(res)
  13 + } else {
  14 + reject(new Error(res.msg || 'Failed to query owner cars'))
  15 + }
  16 + }).catch(error => {
  17 + reject(error)
  18 + })
  19 + })
  20 +}
0 21 \ No newline at end of file
... ...
src/api/owner/ownerDetailChargeMachineOrderApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +export function getOpenApi(params) {
  4 + return new Promise((resolve, reject) => {
  5 + request({
  6 + url: '/iot.getOpenApi',
  7 + method: 'get',
  8 + params
  9 + }).then(response => {
  10 + const res = response.data
  11 + if (res.code === 0) {
  12 + resolve(res)
  13 + } else {
  14 + reject(new Error(res.msg || '获取充电订单失败'))
  15 + }
  16 + }).catch(error => {
  17 + reject(error)
  18 + })
  19 + })
  20 +}
0 21 \ No newline at end of file
... ...
src/api/owner/ownerDetailComplaintApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +export function listComplaints(params) {
  4 + return request({
  5 + url: '/complaint.listComplaints',
  6 + method: 'get',
  7 + params
  8 + })
  9 +}
  10 +
  11 +export function listRunWorkflowImage(params) {
  12 + return request({
  13 + url: '/complaint/listRunWorkflowImage',
  14 + method: 'get',
  15 + params
  16 + })
  17 +}
0 18 \ No newline at end of file
... ...
src/api/owner/ownerDetailContractApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +export function queryContract(params) {
  4 + return new Promise((resolve, reject) => {
  5 + request({
  6 + url: '/contract/queryContract',
  7 + method: 'get',
  8 + params
  9 + }).then(response => {
  10 + const res = response.data
  11 + if (res.code == 0) {
  12 + resolve(res)
  13 + } else {
  14 + reject(new Error(res.msg || '获取业主合同列表失败'))
  15 + }
  16 + }).catch(error => {
  17 + reject(error)
  18 + })
  19 + })
  20 +}
0 21 \ No newline at end of file
... ...
src/api/owner/ownerDetailCouponApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +export function listComplaints(params) {
  4 + return request({
  5 + url: '/complaint/listComplaints',
  6 + method: 'get',
  7 + params
  8 + })
  9 + }
0 10 \ No newline at end of file
... ...
src/api/owner/ownerDetailHisApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +export function queryHisOwner(params) {
  4 + return new Promise((resolve, reject) => {
  5 + request({
  6 + url: '/owner.queryHisOwner',
  7 + method: 'get',
  8 + params
  9 + })
  10 + .then(response => {
  11 + const res = response.data
  12 + if (res.code === 0) {
  13 + resolve(res)
  14 + } else {
  15 + reject(new Error(res.msg || '查询业主历史记录失败'))
  16 + }
  17 + })
  18 + .catch(error => {
  19 + reject(error)
  20 + })
  21 + })
  22 +}
0 23 \ No newline at end of file
... ...
src/api/owner/ownerDetailHisFeeApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +export function queryFeeDetail(params) {
  4 + return new Promise((resolve, reject) => {
  5 + request({
  6 + url: '/fee.queryFeeDetail',
  7 + method: 'get',
  8 + params
  9 + }).then(response => {
  10 + const res = response.data
  11 + if (res.code === 0) {
  12 + resolve(res)
  13 + } else {
  14 + reject(new Error(res.msg || '获取费用明细失败'))
  15 + }
  16 + }).catch(error => {
  17 + reject(error)
  18 + })
  19 + })
  20 +}
0 21 \ No newline at end of file
... ...
src/api/owner/ownerDetailMemberApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +export function queryOwnerMembers(params) {
  4 + return new Promise((resolve, reject) => {
  5 + request({
  6 + url: '/owner.queryOwnerMembers',
  7 + method: 'get',
  8 + params
  9 + }).then(response => {
  10 + const res = response.data
  11 + if (res.code == 0) {
  12 + resolve(res)
  13 + } else {
  14 + reject(new Error(res.msg || '获取业主成员列表失败'))
  15 + }
  16 + }).catch(error => {
  17 + reject(error)
  18 + })
  19 + })
  20 +}
0 21 \ No newline at end of file
... ...
src/api/owner/ownerDetailReceiptApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +export function queryFeeReceipt(params) {
  4 + return new Promise((resolve, reject) => {
  5 + request({
  6 + url: '/feeReceipt/queryFeeReceipt',
  7 + method: 'get',
  8 + params
  9 + }).then(response => {
  10 + const res = response.data
  11 + if (res.code === 0) {
  12 + resolve(res)
  13 + } else {
  14 + reject(new Error(res.msg || '获取收据列表失败'))
  15 + }
  16 + }).catch(error => {
  17 + reject(error)
  18 + })
  19 + })
  20 +}
  21 +
  22 +export function listFeePrintPage(params) {
  23 + return new Promise((resolve, reject) => {
  24 + request({
  25 + url: '/feePrintPage.listFeePrintPage',
  26 + method: 'get',
  27 + params
  28 + }).then(response => {
  29 + const res = response.data
  30 + if (res.code === 0) {
  31 + resolve(res)
  32 + } else {
  33 + reject(new Error(res.msg || '获取打印页面配置失败'))
  34 + }
  35 + }).catch(error => {
  36 + reject(error)
  37 + })
  38 + })
  39 +}
0 40 \ No newline at end of file
... ...
src/api/owner/ownerDetailRepairApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +export function listOwnerRepairs(params) {
  4 + return new Promise((resolve, reject) => {
  5 + request({
  6 + url: '/ownerRepair.listOwnerRepairs',
  7 + method: 'get',
  8 + params
  9 + }).then(response => {
  10 + const res = response.data
  11 + if (res.code == 0) {
  12 + resolve(res)
  13 + } else {
  14 + reject(new Error(res.msg || '获取业主报修列表失败'))
  15 + }
  16 + }).catch(error => {
  17 + reject(error)
  18 + })
  19 + })
  20 +}
0 21 \ No newline at end of file
... ...
src/api/owner/ownerDetailRoomApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +export function queryRoomsByOwner(params) {
  4 + return new Promise((resolve, reject) => {
  5 + request({
  6 + url: '/room.queryRoomsByOwner',
  7 + method: 'get',
  8 + params
  9 + }).then(response => {
  10 + const res = response.data
  11 + if (res.code === 0) {
  12 + resolve(res)
  13 + } else {
  14 + reject(new Error(res.msg || 'Failed to query rooms by owner'))
  15 + }
  16 + }).catch(error => {
  17 + reject(error)
  18 + })
  19 + })
  20 +}
0 21 \ No newline at end of file
... ...
src/api/owner/ownerDetailRoomFeeApi.js 0 → 100644
src/api/owner/ownerDetailVisitApi.js 0 → 100644
src/components/owner/addOwnerMember.vue 0 → 100644
  1 +<template>
  2 + <el-dialog
  3 + :title="$t('addOwnerMember.title')"
  4 + :visible.sync="dialogVisible"
  5 + width="80%"
  6 + @close="_closeSaveOwnerModal"
  7 + >
  8 + <el-form :model="addOwnerMemberInfo" :rules="rules" ref="form" label-width="120px">
  9 + <el-row :gutter="20">
  10 + <el-col :span="12">
  11 + <el-form-item :label="$t('addOwnerMember.personRole')" prop="personRole">
  12 + <el-select
  13 + v-model="addOwnerMemberInfo.personRole"
  14 + :placeholder="$t('addOwnerMember.placeholder.personRole')"
  15 + class="w100"
  16 + >
  17 + <el-option
  18 + v-for="item in roleOptions"
  19 + :key="item.value"
  20 + :label="item.label"
  21 + :value="item.value"
  22 + />
  23 + </el-select>
  24 + </el-form-item>
  25 +
  26 + <el-form-item :label="$t('addOwnerMember.name')" prop="name">
  27 + <el-input
  28 + v-model.trim="addOwnerMemberInfo.name"
  29 + :placeholder="$t('addOwnerMember.placeholder.name')"
  30 + clearable
  31 + />
  32 + </el-form-item>
  33 +
  34 + <el-form-item :label="$t('addOwnerMember.link')" prop="link">
  35 + <el-input
  36 + v-model.trim="addOwnerMemberInfo.link"
  37 + :placeholder="$t('addOwnerMember.placeholder.link')"
  38 + clearable
  39 + />
  40 + </el-form-item>
  41 +
  42 + <el-form-item :label="$t('addOwnerMember.sex')" prop="sex">
  43 + <el-select
  44 + v-model="addOwnerMemberInfo.sex"
  45 + :placeholder="$t('addOwnerMember.placeholder.sex')"
  46 + class="w100"
  47 + >
  48 + <el-option
  49 + v-for="item in sexOptions"
  50 + :key="item.value"
  51 + :label="item.label"
  52 + :value="item.value"
  53 + />
  54 + </el-select>
  55 + </el-form-item>
  56 + </el-col>
  57 +
  58 + <el-col :span="12" class="text-center">
  59 + <div class="avatar-uploader">
  60 + <img
  61 + v-if="addOwnerMemberInfo.ownerPhotoUrl"
  62 + :src="addOwnerMemberInfo.ownerPhotoUrl"
  63 + class="avatar"
  64 + :alt="$t('addOwnerMember.photo')"
  65 + >
  66 + <img
  67 + v-else
  68 + src="/img/noPhoto.jpg"
  69 + class="avatar"
  70 + :alt="$t('addOwnerMember.photo')"
  71 + >
  72 + </div>
  73 + <el-button
  74 + type="primary"
  75 + class="mt10"
  76 + @click="_uploadPhoto"
  77 + >
  78 + {{ $t('addOwnerMember.uploadPhoto') }}
  79 + </el-button>
  80 + <input
  81 + type="file"
  82 + ref="fileInput"
  83 + accept=".jpg,.jpeg,.png"
  84 + @change="_choosePhoto"
  85 + style="display: none"
  86 + >
  87 + </el-col>
  88 + </el-row>
  89 +
  90 + <el-row :gutter="20">
  91 + <el-col :span="12">
  92 + <el-form-item :label="$t('addOwnerMember.concactLink')">
  93 + <el-input
  94 + v-model.trim="addOwnerMemberInfo.concactLink"
  95 + :placeholder="$t('addOwnerMember.placeholder.concactLink')"
  96 + clearable
  97 + />
  98 + </el-form-item>
  99 +
  100 + <el-form-item :label="$t('addOwnerMember.address')">
  101 + <el-input
  102 + v-model.trim="addOwnerMemberInfo.address"
  103 + :placeholder="$t('addOwnerMember.placeholder.address')"
  104 + clearable
  105 + />
  106 + </el-form-item>
  107 + </el-col>
  108 +
  109 + <el-col :span="12">
  110 + <el-form-item :label="$t('addOwnerMember.idCard')">
  111 + <el-input
  112 + v-model.trim="addOwnerMemberInfo.idCard"
  113 + :placeholder="$t('addOwnerMember.placeholder.idCard')"
  114 + clearable
  115 + />
  116 + </el-form-item>
  117 +
  118 + <el-form-item :label="$t('addOwnerMember.remark')">
  119 + <el-input
  120 + v-model.trim="addOwnerMemberInfo.remark"
  121 + :placeholder="$t('addOwnerMember.placeholder.remark')"
  122 + clearable
  123 + />
  124 + </el-form-item>
  125 + </el-col>
  126 + </el-row>
  127 +
  128 + <template v-for="(item,index) in addOwnerMemberInfo.attrs">
  129 + <el-row :gutter="20" v-if="index % 2 === 0" :key="index">
  130 + <el-col :span="12">
  131 + <el-form-item :label="item.specName" v-if="item.specType === '2233'">
  132 + <el-input
  133 + v-model="item.value"
  134 + :placeholder="item.specHoldplace"
  135 + clearable
  136 + />
  137 + </el-form-item>
  138 +
  139 + <el-form-item :label="item.specName" v-if="item.specType === '3344'">
  140 + <el-select
  141 + v-model="item.value"
  142 + :placeholder="item.specHoldplace"
  143 + class="w100"
  144 + >
  145 + <el-option
  146 + v-for="value in item.values"
  147 + :key="value.value"
  148 + :label="value.valueName"
  149 + :value="value.value"
  150 + />
  151 + </el-select>
  152 + </el-form-item>
  153 + </el-col>
  154 +
  155 + <el-col :span="12" v-if="index < addOwnerMemberInfo.attrs.length-1">
  156 + <el-form-item
  157 + :label="addOwnerMemberInfo.attrs[index+1].specName"
  158 + v-if="addOwnerMemberInfo.attrs[index+1].specType === '2233'"
  159 + >
  160 + <el-input
  161 + v-model="addOwnerMemberInfo.attrs[index+1].value"
  162 + :placeholder="addOwnerMemberInfo.attrs[index+1].specHoldplace"
  163 + clearable
  164 + />
  165 + </el-form-item>
  166 +
  167 + <el-form-item
  168 + :label="addOwnerMemberInfo.attrs[index+1].specName"
  169 + v-if="addOwnerMemberInfo.attrs[index+1].specType === '3344'"
  170 + >
  171 + <el-select
  172 + v-model="addOwnerMemberInfo.attrs[index+1].value"
  173 + :placeholder="addOwnerMemberInfo.attrs[index+1].specHoldplace"
  174 + class="w100"
  175 + >
  176 + <el-option
  177 + v-for="value in addOwnerMemberInfo.attrs[index+1].values"
  178 + :key="value.value"
  179 + :label="value.valueName"
  180 + :value="value.value"
  181 + />
  182 + </el-select>
  183 + </el-form-item>
  184 + </el-col>
  185 + </el-row>
  186 + </template>
  187 + </el-form>
  188 +
  189 + <div slot="footer" class="dialog-footer">
  190 + <el-button @click="_closeSaveOwnerModal">{{ $t('common.cancel') }}</el-button>
  191 + <el-button type="primary" @click="saveOwnerMemberInfo">{{ $t('common.save') }}</el-button>
  192 + </div>
  193 + </el-dialog>
  194 +</template>
  195 +
  196 +<script>
  197 +import { getCommunityId } from '@/api/community/communityApi'
  198 +import { getAttrSpec, getAttrValue } from '@/api/community/communityApi'
  199 +import { uploadFile } from '@/api/staff/addStaffApi'
  200 +
  201 +export default {
  202 + name: 'AddOwnerMember',
  203 + data() {
  204 + return {
  205 + dialogVisible: false,
  206 + addOwnerMemberInfo: {
  207 + name: '',
  208 + link: '',
  209 + address: '',
  210 + sex: '',
  211 + remark: '',
  212 + ownerId: '',
  213 + ownerPhoto: '',
  214 + ownerPhotoUrl: '',
  215 + idCard: '',
  216 + personType: 'P',
  217 + personRole: '3',
  218 + concactLink: '',
  219 + attrs: []
  220 + },
  221 + roleOptions: [
  222 + { value: '2', label: this.$t('addOwnerMember.role.tenant') },
  223 + { value: '3', label: this.$t('addOwnerMember.role.family') },
  224 + { value: '4', label: this.$t('addOwnerMember.role.staff') },
  225 + { value: '99', label: this.$t('addOwnerMember.role.other') }
  226 + ],
  227 + sexOptions: [
  228 + { value: '0', label: this.$t('common.male') },
  229 + { value: '1', label: this.$t('common.female') }
  230 + ],
  231 + rules: {
  232 + personRole: [
  233 + { required: true, message: this.$t('addOwnerMember.placeholder.personRole'), trigger: 'change' }
  234 + ],
  235 + name: [
  236 + { required: true, message: this.$t('addOwnerMember.placeholder.name'), trigger: 'blur' },
  237 + { min: 2, max: 64, message: this.$t('addOwnerMember.validate.nameLength'), trigger: 'blur' }
  238 + ],
  239 + link: [
  240 + { required: true, message: this.$t('addOwnerMember.placeholder.link'), trigger: 'blur' },
  241 + { pattern: /^1[3-9]\d{9}$/, message: this.$t('addOwnerMember.validate.phoneFormat'), trigger: 'blur' }
  242 + ],
  243 + sex: [
  244 + { required: true, message: this.$t('addOwnerMember.placeholder.sex'), trigger: 'change' }
  245 + ],
  246 + idCard: [
  247 + { pattern: /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/, message: this.$t('addOwnerMember.validate.idCardFormat'), trigger: 'blur' }
  248 + ],
  249 + remark: [
  250 + { max: 200, message: this.$t('addOwnerMember.validate.remarkLength'), trigger: 'blur' }
  251 + ]
  252 + }
  253 + }
  254 + },
  255 + methods: {
  256 + open(ownerId) {
  257 + this.addOwnerMemberInfo.ownerId = ownerId
  258 + this._loadOwnerAttrSpec()
  259 + this.dialogVisible = true
  260 + this.$nextTick(() => {
  261 + this.$refs.form.clearValidate()
  262 + })
  263 + },
  264 +
  265 + saveOwnerMemberInfo() {
  266 + this.$refs.form.validate(valid => {
  267 + if (valid) {
  268 + const params = {
  269 + ...this.addOwnerMemberInfo,
  270 + communityId: getCommunityId()
  271 + }
  272 +
  273 + this.$http.post('/owner.saveOwnerMember', params)
  274 + .then(res => {
  275 + if (res.data.code === 0) {
  276 + this.$message.success(this.$t('common.saveSuccess'))
  277 + this.dialogVisible = false
  278 + this.$emit('save-success')
  279 + } else {
  280 + this.$message.error(res.data.msg || this.$t('common.saveFailed'))
  281 + }
  282 + })
  283 + .catch(err => {
  284 + console.error('请求失败:', err)
  285 + this.$message.error(this.$t('common.saveFailed'))
  286 + })
  287 + }
  288 + })
  289 + },
  290 +
  291 + _loadOwnerAttrSpec() {
  292 + this.addOwnerMemberInfo.attrs = []
  293 + getAttrSpec('building_owner_attr').then(data => {
  294 + data.forEach(item => {
  295 + if (item.specShow === 'Y') {
  296 + item.value = ''
  297 + item.values = []
  298 + this._loadAttrValue(item.specCd, item.values)
  299 + this.addOwnerMemberInfo.attrs.push(item)
  300 + }
  301 + })
  302 + })
  303 + },
  304 +
  305 + _loadAttrValue(specCd, values) {
  306 + getAttrValue(specCd).then(data => {
  307 + data.forEach(item => {
  308 + if (item.valueShow === 'Y') {
  309 + values.push(item)
  310 + }
  311 + })
  312 + })
  313 + },
  314 +
  315 + _uploadPhoto() {
  316 + this.$refs.fileInput.click()
  317 + },
  318 +
  319 + _choosePhoto(event) {
  320 + const files = event.target.files
  321 + if (files && files.length > 0) {
  322 + const file = files[0]
  323 + if (file.size > 1024 * 1024 * 2) {
  324 + this.$message.error(this.$t('addOwnerMember.validate.photoSize'))
  325 + return
  326 + }
  327 +
  328 + this._doUploadImage(file)
  329 + }
  330 + },
  331 +
  332 + _doUploadImage(file) {
  333 + const formData = new FormData()
  334 + formData.append('uploadFile', file)
  335 + formData.append('communityId', getCommunityId())
  336 +
  337 + uploadFile(formData).then(res => {
  338 + this.addOwnerMemberInfo.ownerPhoto = res.fileId
  339 + this.addOwnerMemberInfo.ownerPhotoUrl = res.url
  340 + }).catch(err => {
  341 + console.error('上传失败:', err)
  342 + this.$message.error(this.$t('addOwnerMember.uploadFailed'))
  343 + })
  344 + },
  345 +
  346 + _closeSaveOwnerModal() {
  347 + this.dialogVisible = false
  348 + this.$refs.form.resetFields()
  349 + this.addOwnerMemberInfo = {
  350 + name: '',
  351 + link: '',
  352 + address: '',
  353 + sex: '',
  354 + remark: '',
  355 + ownerId: '',
  356 + ownerPhoto: '',
  357 + ownerPhotoUrl: '',
  358 + idCard: '',
  359 + personType: 'P',
  360 + personRole: '3',
  361 + concactLink: '',
  362 + attrs: []
  363 + }
  364 + }
  365 + }
  366 +}
  367 +</script>
  368 +
  369 +<style scoped>
  370 +.w100 {
  371 + width: 100%;
  372 +}
  373 +.mt10 {
  374 + margin-top: 10px;
  375 +}
  376 +.text-center {
  377 + text-align: center;
  378 +}
  379 +.avatar-uploader {
  380 + width: 100%;
  381 + display: flex;
  382 + justify-content: center;
  383 + margin-bottom: 10px;
  384 +}
  385 +.avatar {
  386 + width: 150px;
  387 + height: 150px;
  388 + object-fit: cover;
  389 +}
  390 +</style>
0 391 \ No newline at end of file
... ...
src/components/owner/addOwnerMemberLang.js 0 → 100644
  1 +export default {
  2 + en: {
  3 + addOwnerMember: {
  4 + title: 'Add Member',
  5 + personRole: 'Person Role',
  6 + name: 'Name',
  7 + link: 'Phone',
  8 + sex: 'Gender',
  9 + concactLink: 'Alternate Phone',
  10 + address: 'Address',
  11 + idCard: 'ID Card',
  12 + remark: 'Remark',
  13 + photo: 'Photo',
  14 + uploadPhoto: 'Upload Photo',
  15 + placeholder: {
  16 + personRole: 'Required, please select person role',
  17 + name: 'Required, please enter name',
  18 + link: 'Required, please enter phone number',
  19 + sex: 'Required, please select gender',
  20 + concactLink: 'Optional, please enter alternate phone',
  21 + address: 'Optional, please enter address',
  22 + idCard: 'Optional, please enter ID card',
  23 + remark: 'Optional, please enter remark'
  24 + },
  25 + role: {
  26 + tenant: 'Tenant',
  27 + family: 'Family Member',
  28 + staff: 'Company Staff',
  29 + other: 'Other'
  30 + },
  31 + validate: {
  32 + nameLength: 'Name length must be between 2 and 64 characters',
  33 + phoneFormat: 'Invalid phone number format',
  34 + idCardFormat: 'Invalid ID card format',
  35 + remarkLength: 'Remark length cannot exceed 200 characters',
  36 + photoSize: 'Photo size cannot exceed 2MB'
  37 + },
  38 + uploadFailed: 'Photo upload failed'
  39 + }
  40 + },
  41 + zh: {
  42 + addOwnerMember: {
  43 + title: '添加成员',
  44 + personRole: '人员角色',
  45 + name: '客户名称',
  46 + link: '联系手机',
  47 + sex: '性别',
  48 + concactLink: '备用手机',
  49 + address: '地址',
  50 + idCard: '身份证',
  51 + remark: '备注',
  52 + photo: '照片',
  53 + uploadPhoto: '上传照片',
  54 + placeholder: {
  55 + personRole: '必填,请选择人员角色',
  56 + name: '必填,请填写客户名称',
  57 + link: '必填,请填写联系方式',
  58 + sex: '必填,请选择性别',
  59 + concactLink: '可选,请填写备用手机',
  60 + address: '可填,请填写地址',
  61 + idCard: '可选,请填写身份证',
  62 + remark: '可填,请填写备注'
  63 + },
  64 + role: {
  65 + tenant: '租客',
  66 + family: '家庭成员',
  67 + staff: '公司员工',
  68 + other: '其他'
  69 + },
  70 + validate: {
  71 + nameLength: '姓名长度必须在2位至64位',
  72 + phoneFormat: '手机号格式错误',
  73 + idCardFormat: '身份证格式不对',
  74 + remarkLength: '备注长度不能超过200位',
  75 + photoSize: '图片大小不能超过2MB'
  76 + },
  77 + uploadFailed: '照片上传失败'
  78 + }
  79 + }
  80 +}
0 81 \ No newline at end of file
... ...
src/components/owner/editOwnerMember.vue 0 → 100644
  1 +<template>
  2 + <el-dialog
  3 + :title="$t('editOwnerMember.title')"
  4 + :visible.sync="dialogVisible"
  5 + width="80%"
  6 + @close="_closeEditOwnerMemberModal"
  7 + >
  8 + <el-form :model="editOwnerMemberInfo" :rules="rules" ref="form" label-width="120px">
  9 + <el-row :gutter="20">
  10 + <el-col :span="12">
  11 + <el-form-item :label="$t('editOwnerMember.personRole')" prop="personRole">
  12 + <el-select
  13 + v-model="editOwnerMemberInfo.personRole"
  14 + :placeholder="$t('editOwnerMember.placeholder.personRole')"
  15 + class="w100"
  16 + >
  17 + <el-option
  18 + v-for="item in roleOptions"
  19 + :key="item.value"
  20 + :label="item.label"
  21 + :value="item.value"
  22 + />
  23 + </el-select>
  24 + </el-form-item>
  25 +
  26 + <el-form-item :label="$t('editOwnerMember.name')" prop="name">
  27 + <el-input
  28 + v-model.trim="editOwnerMemberInfo.name"
  29 + :placeholder="$t('editOwnerMember.placeholder.name')"
  30 + clearable
  31 + />
  32 + </el-form-item>
  33 +
  34 + <el-form-item :label="$t('editOwnerMember.link')" prop="link">
  35 + <el-input
  36 + v-model.trim="editOwnerMemberInfo.link"
  37 + :placeholder="$t('editOwnerMember.placeholder.link')"
  38 + clearable
  39 + maxlength="11"
  40 + />
  41 + </el-form-item>
  42 +
  43 + <el-form-item
  44 + :label="$t('editOwnerMember.sex')"
  45 + prop="sex"
  46 + v-if="editOwnerMemberInfo.personType === 'P'"
  47 + >
  48 + <el-select
  49 + v-model="editOwnerMemberInfo.sex"
  50 + :placeholder="$t('editOwnerMember.placeholder.sex')"
  51 + class="w100"
  52 + >
  53 + <el-option
  54 + v-for="item in sexOptions"
  55 + :key="item.value"
  56 + :label="item.label"
  57 + :value="item.value"
  58 + />
  59 + </el-select>
  60 + </el-form-item>
  61 +
  62 + <el-form-item :label="$t('editOwnerMember.address')">
  63 + <el-input
  64 + v-model.trim="editOwnerMemberInfo.address"
  65 + :placeholder="$t('editOwnerMember.placeholder.address')"
  66 + clearable
  67 + />
  68 + </el-form-item>
  69 + </el-col>
  70 +
  71 + <el-col :span="12" class="text-center">
  72 + <div class="avatar-uploader">
  73 + <img
  74 + v-if="editOwnerMemberInfo.ownerPhotoUrl"
  75 + :src="editOwnerMemberInfo.ownerPhotoUrl"
  76 + class="avatar"
  77 + :alt="$t('editOwnerMember.photo')"
  78 + @error="handleImageError"
  79 + >
  80 + <img
  81 + v-else
  82 + src="/img/noPhoto.jpg"
  83 + class="avatar"
  84 + :alt="$t('editOwnerMember.photo')"
  85 + >
  86 + </div>
  87 + <el-button
  88 + type="primary"
  89 + class="mt10"
  90 + @click="_uploadEditMemberPhoto"
  91 + >
  92 + {{ $t('editOwnerMember.uploadPhoto') }}
  93 + </el-button>
  94 + <input
  95 + type="file"
  96 + ref="fileInput"
  97 + accept=".jpg,.jpeg,.png"
  98 + @change="_chooseEditMemberPhoto"
  99 + style="display: none"
  100 + >
  101 + </el-col>
  102 + </el-row>
  103 +
  104 + <el-row :gutter="20">
  105 + <el-col :span="12">
  106 + <el-form-item :label="$t('editOwnerMember.concactLink')">
  107 + <el-input
  108 + v-model.trim="editOwnerMemberInfo.concactLink"
  109 + :placeholder="$t('editOwnerMember.placeholder.concactLink')"
  110 + clearable
  111 + />
  112 + </el-form-item>
  113 + </el-col>
  114 +
  115 + <el-col :span="12">
  116 + <el-form-item :label="$t('editOwnerMember.idCard')">
  117 + <el-input
  118 + v-model.trim="editOwnerMemberInfo.idCard"
  119 + :placeholder="$t('editOwnerMember.placeholder.idCard')"
  120 + clearable
  121 + />
  122 + </el-form-item>
  123 +
  124 + <el-form-item :label="$t('editOwnerMember.remark')">
  125 + <el-input
  126 + v-model.trim="editOwnerMemberInfo.remark"
  127 + :placeholder="$t('editOwnerMember.placeholder.remark')"
  128 + clearable
  129 + />
  130 + </el-form-item>
  131 + </el-col>
  132 + </el-row>
  133 +
  134 + <template v-for="(item,index) in editOwnerMemberInfo.attrs">
  135 + <el-row :gutter="20" v-if="index % 2 === 0" :key="index">
  136 + <el-col :span="12">
  137 + <el-form-item :label="item.specName" v-if="item.specType === '2233'">
  138 + <el-input
  139 + v-model="item.value"
  140 + :placeholder="item.specHoldplace"
  141 + clearable
  142 + />
  143 + </el-form-item>
  144 +
  145 + <el-form-item :label="item.specName" v-if="item.specType === '3344'">
  146 + <el-select
  147 + v-model="item.value"
  148 + :placeholder="item.specHoldplace"
  149 + class="w100"
  150 + >
  151 + <el-option
  152 + v-for="value in item.values"
  153 + :key="value.value"
  154 + :label="value.valueName"
  155 + :value="value.value"
  156 + />
  157 + </el-select>
  158 + </el-form-item>
  159 + </el-col>
  160 +
  161 + <el-col :span="12" v-if="index < editOwnerMemberInfo.attrs.length-1">
  162 + <el-form-item
  163 + :label="editOwnerMemberInfo.attrs[index+1].specName"
  164 + v-if="editOwnerMemberInfo.attrs[index+1].specType === '2233'"
  165 + >
  166 + <el-input
  167 + v-model="editOwnerMemberInfo.attrs[index+1].value"
  168 + :placeholder="editOwnerMemberInfo.attrs[index+1].specHoldplace"
  169 + clearable
  170 + />
  171 + </el-form-item>
  172 +
  173 + <el-form-item
  174 + :label="editOwnerMemberInfo.attrs[index+1].specName"
  175 + v-if="editOwnerMemberInfo.attrs[index+1].specType === '3344'"
  176 + >
  177 + <el-select
  178 + v-model="editOwnerMemberInfo.attrs[index+1].value"
  179 + :placeholder="editOwnerMemberInfo.attrs[index+1].specHoldplace"
  180 + class="w100"
  181 + >
  182 + <el-option
  183 + v-for="value in editOwnerMemberInfo.attrs[index+1].values"
  184 + :key="value.value"
  185 + :label="value.valueName"
  186 + :value="value.value"
  187 + />
  188 + </el-select>
  189 + </el-form-item>
  190 + </el-col>
  191 + </el-row>
  192 + </template>
  193 + </el-form>
  194 +
  195 + <div slot="footer" class="dialog-footer">
  196 + <el-button @click="_closeEditOwnerMemberModal">{{ $t('common.cancel') }}</el-button>
  197 + <el-button type="primary" @click="editOwnerMemberMethod">{{ $t('common.save') }}</el-button>
  198 + </div>
  199 + </el-dialog>
  200 +</template>
  201 +
  202 +<script>
  203 +import { getCommunityId } from '@/api/community/communityApi'
  204 +import { getAttrSpec, getAttrValue } from '@/api/community/communityApi'
  205 +import { uploadFile } from '@/api/staff/addStaffApi'
  206 +
  207 +export default {
  208 + name: 'EditOwnerMember',
  209 + data() {
  210 + return {
  211 + dialogVisible: false,
  212 + editOwnerMemberInfo: {
  213 + ownerId: '',
  214 + memberId: '',
  215 + ownerTypeCd: '',
  216 + name: '',
  217 + link: '',
  218 + address: '',
  219 + sex: '',
  220 + remark: '',
  221 + ownerPhoto: '',
  222 + ownerPhotoUrl: '',
  223 + idCard: '',
  224 + personType: 'P',
  225 + personRole: '1',
  226 + concactLink: '',
  227 + attrs: []
  228 + },
  229 + roleOptions: [
  230 + { value: '2', label: this.$t('editOwnerMember.role.tenant') },
  231 + { value: '3', label: this.$t('editOwnerMember.role.family') },
  232 + { value: '4', label: this.$t('editOwnerMember.role.staff') },
  233 + { value: '99', label: this.$t('editOwnerMember.role.other') }
  234 + ],
  235 + sexOptions: [
  236 + { value: '0', label: this.$t('common.male') },
  237 + { value: '1', label: this.$t('common.female') }
  238 + ],
  239 + rules: {
  240 + personRole: [
  241 + { required: true, message: this.$t('editOwnerMember.placeholder.personRole'), trigger: 'change' }
  242 + ],
  243 + name: [
  244 + { required: true, message: this.$t('editOwnerMember.placeholder.name'), trigger: 'blur' }
  245 + ],
  246 + link: [
  247 + { required: true, message: this.$t('editOwnerMember.placeholder.link'), trigger: 'blur' },
  248 + { pattern: /^1[3-9]\d{9}$/, message: this.$t('editOwnerMember.validate.phoneFormat'), trigger: 'blur' }
  249 + ],
  250 + sex: [
  251 + { required: true, message: this.$t('editOwnerMember.placeholder.sex'), trigger: 'change' }
  252 + ],
  253 + idCard: [
  254 + { pattern: /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/, message: this.$t('editOwnerMember.validate.idCardFormat'), trigger: 'blur' }
  255 + ],
  256 + remark: [
  257 + { max: 200, message: this.$t('editOwnerMember.validate.remarkLength'), trigger: 'blur' }
  258 + ]
  259 + }
  260 + }
  261 + },
  262 + methods: {
  263 + open(member) {
  264 + this.editOwnerMemberInfo = {
  265 + ...member,
  266 + ownerPhoto: member.faceUrl,
  267 + ownerPhotoUrl: member.faceUrl,
  268 + attrs: []
  269 + }
  270 +
  271 + this._loadEditOwnerMemberAttrSpec().then(() => {
  272 + if (Object.prototype.hasOwnProperty.call(member,'ownerAttrDtos')) {
  273 + const ownerAttrDtos = member.ownerAttrDtos
  274 + this.editOwnerMemberInfo.attrs.forEach(attrItem => {
  275 + ownerAttrDtos.forEach(item => {
  276 + if (item.specCd === attrItem.specCd) {
  277 + attrItem.attrId = item.attrId
  278 + attrItem.value = item.value
  279 + }
  280 + })
  281 + })
  282 + }
  283 +
  284 + this.dialogVisible = true
  285 + this.$nextTick(() => {
  286 + this.$refs.form.clearValidate()
  287 + })
  288 + })
  289 + },
  290 +
  291 + editOwnerMemberMethod() {
  292 + this.$refs.form.validate(valid => {
  293 + if (valid) {
  294 + const params = {
  295 + ...this.editOwnerMemberInfo,
  296 + communityId: getCommunityId()
  297 + }
  298 +
  299 + this.$http.post('/owner.editOwnerMember', params)
  300 + .then(res => {
  301 + if (res.data.code === 0) {
  302 + this.$message.success(this.$t('common.saveSuccess'))
  303 + this.dialogVisible = false
  304 + this.$emit('save-success')
  305 + } else {
  306 + this.$message.error(res.data.msg || this.$t('common.saveFailed'))
  307 + }
  308 + })
  309 + .catch(err => {
  310 + console.error('请求失败:', err)
  311 + this.$message.error(this.$t('common.saveFailed'))
  312 + })
  313 + }
  314 + })
  315 + },
  316 +
  317 + _loadEditOwnerMemberAttrSpec() {
  318 + return new Promise(resolve => {
  319 + this.editOwnerMemberInfo.attrs = []
  320 + getAttrSpec('building_owner_attr').then(data => {
  321 + data.forEach(item => {
  322 + if (item.specShow === 'Y') {
  323 + item.value = ''
  324 + item.values = []
  325 + this._loadEditMemberAttrValue(item.specCd, item.values)
  326 + this.editOwnerMemberInfo.attrs.push(item)
  327 + }
  328 + })
  329 + resolve()
  330 + })
  331 + })
  332 + },
  333 +
  334 + _loadEditMemberAttrValue(specCd, values) {
  335 + getAttrValue(specCd).then(data => {
  336 + data.forEach(item => {
  337 + if (item.valueShow === 'Y') {
  338 + values.push(item)
  339 + }
  340 + })
  341 + })
  342 + },
  343 +
  344 + _uploadEditMemberPhoto() {
  345 + this.$refs.fileInput.click()
  346 + },
  347 +
  348 + _chooseEditMemberPhoto(event) {
  349 + const files = event.target.files
  350 + if (files && files.length > 0) {
  351 + const file = files[0]
  352 + if (file.size > 1024 * 1024 * 2) {
  353 + this.$message.error(this.$t('editOwnerMember.validate.photoSize'))
  354 + return
  355 + }
  356 +
  357 + this._doUploadImageEditOwnerMember(file)
  358 + }
  359 + },
  360 +
  361 + _doUploadImageEditOwnerMember(file) {
  362 + const formData = new FormData()
  363 + formData.append('uploadFile', file)
  364 + formData.append('communityId', getCommunityId())
  365 +
  366 + uploadFile(formData).then(res => {
  367 + this.editOwnerMemberInfo.ownerPhoto = res.fileId
  368 + this.editOwnerMemberInfo.ownerPhotoUrl = res.url
  369 + }).catch(err => {
  370 + console.error('上传失败:', err)
  371 + this.$message.error(this.$t('editOwnerMember.uploadFailed'))
  372 + })
  373 + },
  374 +
  375 + _closeEditOwnerMemberModal() {
  376 + this.dialogVisible = false
  377 + this.$refs.form.resetFields()
  378 + },
  379 +
  380 + handleImageError(e) {
  381 + e.target.src = '/img/noPhoto.jpg'
  382 + }
  383 + }
  384 +}
  385 +</script>
  386 +
  387 +<style scoped>
  388 +.w100 {
  389 + width: 100%;
  390 +}
  391 +.mt10 {
  392 + margin-top: 10px;
  393 +}
  394 +.text-center {
  395 + text-align: center;
  396 +}
  397 +.avatar-uploader {
  398 + width: 100%;
  399 + display: flex;
  400 + justify-content: center;
  401 + margin-bottom: 10px;
  402 +}
  403 +.avatar {
  404 + width: 150px;
  405 + height: 150px;
  406 + object-fit: cover;
  407 +}
  408 +</style>
0 409 \ No newline at end of file
... ...
src/components/owner/ownerDetailAccessControl.vue 0 → 100644
  1 +<template>
  2 + <div class="margin-top">
  3 + <el-table
  4 + :data="ownerDetailAccessControlInfo.machineTranslates"
  5 + style="width: 100%"
  6 + border
  7 + stripe
  8 + >
  9 + <el-table-column prop="typeCdName" :label="$t('ownerDetailAccessControl.objectType')" align="center"></el-table-column>
  10 + <el-table-column prop="objName" :label="$t('ownerDetailAccessControl.objectName')" align="center"></el-table-column>
  11 + <el-table-column prop="machineCmdName" :label="$t('ownerDetailAccessControl.command')" align="center"></el-table-column>
  12 + <el-table-column prop="stateName" :label="$t('ownerDetailAccessControl.status')" align="center"></el-table-column>
  13 + <el-table-column :label="$t('ownerDetailAccessControl.description')" align="center">
  14 + <template slot-scope="scope">
  15 + <div class="hc-td">{{scope.row.remark}}</div>
  16 + </template>
  17 + </el-table-column>
  18 + <el-table-column prop="updateTime" :label="$t('ownerDetailAccessControl.syncTime')" align="center"></el-table-column>
  19 + <el-table-column :label="$t('ownerDetailAccessControl.operation')" align="center">
  20 + <template slot-scope="scope">
  21 + <el-button
  22 + v-if="scope.row.state != '20000'"
  23 + type="text"
  24 + size="small"
  25 + @click="_openEditMachineTranslateModel(scope.row)"
  26 + >
  27 + {{$t('ownerDetailAccessControl.resync')}}
  28 + </el-button>
  29 + </template>
  30 + </el-table-column>
  31 + </el-table>
  32 + <el-row>
  33 + <el-col :span="4"></el-col>
  34 + <el-col :span="20">
  35 + <el-pagination
  36 + @current-change="handleCurrentChange"
  37 + :current-page="currentPage"
  38 + :page-size="pageSize"
  39 + layout="total, prev, pager, next, jumper"
  40 + :total="total">
  41 + </el-pagination>
  42 + </el-col>
  43 + </el-row>
  44 + <edit-machine-translate ref="editMachineTranslate"></edit-machine-translate>
  45 + </div>
  46 +</template>
  47 +
  48 +<script>
  49 +import { listMachineTranslates } from '@/api/owner/ownerDetailAccessControlApi'
  50 +import { getCommunityId } from '@/api/community/communityApi'
  51 +import EditMachineTranslate from '@/components/machine/editMachineTranslate'
  52 +
  53 +export default {
  54 + name: 'OwnerDetailAccessControl',
  55 + components: {
  56 + EditMachineTranslate
  57 + },
  58 + data() {
  59 + return {
  60 + ownerDetailAccessControlInfo: {
  61 + machineTranslates: [],
  62 + ownerId: ''
  63 + },
  64 + currentPage: 1,
  65 + pageSize: 10,
  66 + total: 0,
  67 + communityId: ''
  68 + }
  69 + },
  70 + created() {
  71 + this.communityId = getCommunityId()
  72 + },
  73 + methods: {
  74 + open(ownerId) {
  75 + this.ownerDetailAccessControlInfo.ownerId = ownerId
  76 + this._loadOwnerDetailAccessControlData(this.currentPage, this.pageSize)
  77 + },
  78 + _loadOwnerDetailAccessControlData(page, row) {
  79 + const param = {
  80 + page: page,
  81 + row: row,
  82 + communityId: this.communityId,
  83 + objId: this.ownerDetailAccessControlInfo.ownerId,
  84 + typeCd: '8899'
  85 + }
  86 +
  87 + listMachineTranslates(param).then(response => {
  88 + this.ownerDetailAccessControlInfo.machineTranslates = response.data.machineTranslates
  89 + this.total = response.data.total
  90 + }).catch(error => {
  91 + console.error('请求失败:', error)
  92 + })
  93 + },
  94 + _openEditMachineTranslateModel(machineTranslate) {
  95 + this.$refs.editMachineTranslate.open(machineTranslate)
  96 + },
  97 + handleCurrentChange(val) {
  98 + this.currentPage = val
  99 + this._loadOwnerDetailAccessControlData(val, this.pageSize)
  100 + }
  101 + }
  102 +}
  103 +</script>
0 104 \ No newline at end of file
... ...
src/components/owner/ownerDetailAccessControlDemo.vue 0 → 100644
  1 +<template>
  2 + <owner-detail-access-control ref="ownerDetailAccessControl" />
  3 +</template>
  4 +
  5 +<script>
  6 +import OwnerDetailAccessControl from '@/components/owner/ownerDetailAccessControl'
  7 +
  8 +export default {
  9 + components: {
  10 + OwnerDetailAccessControl
  11 + },
  12 + methods: {
  13 + open(ownerId) {
  14 + this.$refs.ownerDetailAccessControl.open(ownerId)
  15 + }
  16 + }
  17 +}
  18 +</script>
0 19 \ No newline at end of file
... ...
src/components/owner/ownerDetailAccessControlRecord.vue 0 → 100644
  1 +<template>
  2 + <div class="margin-top">
  3 + <el-table
  4 + :data="ownerDetailAccessControlRecordInfo.inouts"
  5 + style="width: 100%"
  6 + border
  7 + stripe
  8 + >
  9 + <el-table-column :label="$t('ownerDetailAccessControlRecord.face')" align="center" width="120">
  10 + <template slot-scope="scope">
  11 + <img
  12 + style="width: 60px; height: 60px;"
  13 + class="border-radius"
  14 + :src="scope.row.facePath || '/img/noPhoto.jpg'"
  15 + @click="_viewOwnerFace(scope.row.facePath)"
  16 + />
  17 + </template>
  18 + </el-table-column>
  19 + <el-table-column prop="inoutId" :label="$t('ownerDetailAccessControlRecord.id')" align="center"></el-table-column>
  20 + <el-table-column prop="machineName" :label="$t('ownerDetailAccessControlRecord.deviceName')" align="center"></el-table-column>
  21 + <el-table-column prop="machineCode" :label="$t('ownerDetailAccessControlRecord.deviceCode')" align="center"></el-table-column>
  22 + <el-table-column prop="name" :label="$t('ownerDetailAccessControlRecord.userName')" align="center"></el-table-column>
  23 + <el-table-column :label="$t('ownerDetailAccessControlRecord.openType')" align="center">
  24 + <template slot-scope="scope">
  25 + {{scope.row.openTypeCd === '1000' ? $t('ownerDetailAccessControlRecord.face') : $t('ownerDetailAccessControlRecord.other')}}
  26 + </template>
  27 + </el-table-column>
  28 + <el-table-column prop="tel" :label="$t('ownerDetailAccessControlRecord.phone')" align="center">
  29 + <template slot-scope="scope">
  30 + {{scope.row.tel || '-'}}
  31 + </template>
  32 + </el-table-column>
  33 + <el-table-column prop="idCard" :label="$t('ownerDetailAccessControlRecord.idCard')" align="center">
  34 + <template slot-scope="scope">
  35 + {{scope.row.idCard || '-'}}
  36 + </template>
  37 + </el-table-column>
  38 + <el-table-column prop="similar" :label="$t('ownerDetailAccessControlRecord.similarity')" align="center"></el-table-column>
  39 + <el-table-column :label="$t('ownerDetailAccessControlRecord.openStatus')" align="center">
  40 + <template slot-scope="scope">
  41 + {{scope.row.state === 'C' ? $t('ownerDetailAccessControlRecord.success') : $t('ownerDetailAccessControlRecord.failed')}}
  42 + </template>
  43 + </el-table-column>
  44 + <el-table-column prop="createTime" :label="$t('ownerDetailAccessControlRecord.openTime')" align="center"></el-table-column>
  45 + </el-table>
  46 + <el-row>
  47 + <el-col :span="4"></el-col>
  48 + <el-col :span="20">
  49 + <el-pagination
  50 + @current-change="handleCurrentChange"
  51 + :current-page="currentPage"
  52 + :page-size="pageSize"
  53 + layout="total, prev, pager, next, jumper"
  54 + :total="total">
  55 + </el-pagination>
  56 + </el-col>
  57 + </el-row>
  58 + <view-image ref="viewImage"></view-image>
  59 + </div>
  60 +</template>
  61 +
  62 +<script>
  63 +import { getOpenApi } from '@/api/owner/ownerDetailAccessControlRecordApi'
  64 +import { getCommunityId } from '@/api/community/communityApi'
  65 +import ViewImage from '@/components/system/viewImage'
  66 +
  67 +export default {
  68 + name: 'OwnerDetailAccessControlRecord',
  69 + components: {
  70 + ViewImage
  71 + },
  72 + data() {
  73 + return {
  74 + ownerDetailAccessControlRecordInfo: {
  75 + inouts: [],
  76 + ownerId: '',
  77 + link: ''
  78 + },
  79 + currentPage: 1,
  80 + pageSize: 10,
  81 + total: 0,
  82 + communityId: ''
  83 + }
  84 + },
  85 + created() {
  86 + this.communityId = getCommunityId()
  87 + },
  88 + methods: {
  89 + open(ownerId, link) {
  90 + this.ownerDetailAccessControlRecordInfo.ownerId = ownerId
  91 + this.ownerDetailAccessControlRecordInfo.link = link
  92 + this._loadOwnerDetailAccessControlRecordData(this.currentPage, this.pageSize)
  93 + },
  94 + _loadOwnerDetailAccessControlRecordData(page, row) {
  95 + const param = {
  96 + page: page,
  97 + row: row,
  98 + communityId: this.communityId,
  99 + tel: this.ownerDetailAccessControlRecordInfo.link,
  100 + iotApiCode: 'listAccessControlInoutBmoImpl'
  101 + }
  102 +
  103 + getOpenApi(param).then(response => {
  104 + this.ownerDetailAccessControlRecordInfo.inouts = response.data.data
  105 + this.total = response.data.total
  106 + }).catch(error => {
  107 + console.error('请求失败:', error)
  108 + })
  109 + },
  110 + _viewOwnerFace(url) {
  111 + if (url) {
  112 + this.$refs.viewImage.show(url)
  113 + }
  114 + },
  115 + handleCurrentChange(val) {
  116 + this.currentPage = val
  117 + this._loadOwnerDetailAccessControlRecordData(val, this.pageSize)
  118 + }
  119 + }
  120 +}
  121 +</script>
0 122 \ No newline at end of file
... ...
src/components/owner/ownerDetailAccessControlRecordDemo.vue 0 → 100644
  1 +<template>
  2 + <owner-detail-access-control-record ref="ownerDetailAccessControlRecord" />
  3 +</template>
  4 +
  5 +<script>
  6 +import OwnerDetailAccessControlRecord from '@/components/owner/ownerDetailAccessControlRecord'
  7 +
  8 +export default {
  9 + components: {
  10 + OwnerDetailAccessControlRecord
  11 + },
  12 + methods: {
  13 + open(ownerId, link) {
  14 + this.$refs.ownerDetailAccessControlRecord.open(ownerId, link)
  15 + }
  16 + }
  17 +}
  18 +</script>
0 19 \ No newline at end of file
... ...
src/components/owner/ownerDetailAccount.vue 0 → 100644
  1 +<template>
  2 + <div class="margin-top">
  3 + <el-row>
  4 + <el-col :span="24" class="text-right">
  5 + <el-button type="primary" size="small" style="margin-left:10px"
  6 + v-if="ownerDetailAccountInfo.accounts.length <1 && hasPrivilege('502023032809461736')"
  7 + @click="_prestoreAccount1()">
  8 + {{ $t('ownerDetailAccount.prestore') }}
  9 + </el-button>
  10 + </el-col>
  11 + </el-row>
  12 + <div class="margin-top">
  13 + <el-table :data="ownerDetailAccountInfo.accounts" style="width: 100%">
  14 + <el-table-column prop="acctId" :label="$t('ownerDetailAccount.acctId')" align="center"></el-table-column>
  15 + <el-table-column prop="acctName" :label="$t('ownerDetailAccount.acctName')" align="center"></el-table-column>
  16 + <el-table-column prop="link" :label="$t('ownerDetailAccount.phone')" align="center"></el-table-column>
  17 + <el-table-column prop="acctTypeName" :label="$t('ownerDetailAccount.acctType')" align="center"></el-table-column>
  18 + <el-table-column prop="amount" :label="$t('ownerDetailAccount.amount')" align="center"></el-table-column>
  19 + <el-table-column prop="createTime" :label="$t('ownerDetailAccount.createTime')" align="center"></el-table-column>
  20 + <el-table-column :label="$t('common.operation')" align="center" width="200">
  21 + <template slot-scope="scope">
  22 + <el-button-group>
  23 + <el-button size="mini" @click="_prestoreAccount(scope.row)"
  24 + v-if="hasPrivilege('502023032809461736')">
  25 + {{ $t('ownerDetailAccount.prestore') }}
  26 + </el-button>
  27 + <el-button size="mini" @click="_accountDetail(scope.row)">
  28 + {{ $t('ownerDetailAccount.detail') }}
  29 + </el-button>
  30 + </el-button-group>
  31 + </template>
  32 + </el-table-column>
  33 + </el-table>
  34 + <el-pagination
  35 + @current-change="handleCurrentChange"
  36 + :current-page="pagination.currentPage"
  37 + :page-size="pagination.pageSize"
  38 + :total="pagination.total"
  39 + layout="total, prev, pager, next, jumper">
  40 + </el-pagination>
  41 + </div>
  42 +
  43 + <prestore-account ref="prestoreAccount" @refresh="_loadOwnerDetailAccountData"></prestore-account>
  44 + </div>
  45 +</template>
  46 +
  47 +<script>
  48 +import PrestoreAccount from '@/components/account/prestoreAccount'
  49 +import { queryCommunityOwnerAccount } from '@/api/owner/ownerDetailAccountApi'
  50 +import { getCommunityId } from '@/api/community/communityApi'
  51 +
  52 +export default {
  53 + name: 'OwnerDetailAccount',
  54 + components: {
  55 + PrestoreAccount
  56 + },
  57 + data() {
  58 + return {
  59 + ownerDetailAccountInfo: {
  60 + accounts: [],
  61 + ownerId: '',
  62 + name: '',
  63 + },
  64 + pagination: {
  65 + currentPage: 1,
  66 + pageSize: 10,
  67 + total: 0
  68 + }
  69 + }
  70 + },
  71 + methods: {
  72 + open(ownerId, ownerName, link) {
  73 + this.ownerDetailAccountInfo.ownerId = ownerId
  74 + this.ownerDetailAccountInfo.ownerName = ownerName
  75 + this.ownerDetailAccountInfo.link = link
  76 + this._loadOwnerDetailAccountData(1, this.pagination.pageSize)
  77 + },
  78 + _loadOwnerDetailAccountData(page, row) {
  79 + const params = {
  80 + communityId: getCommunityId(),
  81 + ownerId: this.ownerDetailAccountInfo.ownerId,
  82 + page: page,
  83 + row: row
  84 + }
  85 +
  86 + queryCommunityOwnerAccount(params).then(response => {
  87 + this.ownerDetailAccountInfo.accounts = response.data
  88 + this.pagination.total = response.records
  89 + }).catch(error => {
  90 + console.error('请求失败处理', error)
  91 + })
  92 + },
  93 + _accountDetail(account) {
  94 + this.$router.push(`/property/accountDetailManage?acctId=${account.acctId}`)
  95 + },
  96 + _prestoreAccount(account) {
  97 + this.$refs.prestoreAccount.open({
  98 + ownerId: this.ownerDetailAccountInfo.ownerId,
  99 + acctType: account.acctType,
  100 + tel: account.link,
  101 + roomId: account.roomId
  102 + })
  103 + },
  104 + _prestoreAccount1() {
  105 + this.$refs.prestoreAccount.open({})
  106 + },
  107 + handleCurrentChange(val) {
  108 + this._loadOwnerDetailAccountData(val, this.pagination.pageSize)
  109 + },
  110 + },
  111 + created() {
  112 + this.$on('switch', (data) => {
  113 + this.ownerDetailAccountInfo.ownerId = data.ownerId
  114 + this._loadOwnerDetailAccountData(1, this.pagination.pageSize)
  115 + })
  116 + }
  117 +}
  118 +</script>
  119 +
  120 +<style scoped>
  121 +/* 样式同上一个组件 */
  122 +</style>
0 123 \ No newline at end of file
... ...
src/components/owner/ownerDetailAccountDemo.vue 0 → 100644
  1 +<template>
  2 + <owner-detail-account ref="ownerDetailAccount" />
  3 +</template>
  4 +
  5 +<script>
  6 +import OwnerDetailAccount from './ownerDetailAccount'
  7 +
  8 +export default {
  9 + components: {
  10 + OwnerDetailAccount
  11 + },
  12 + methods: {
  13 + open(ownerId) {
  14 + this.$refs.ownerDetailAccount.ownerDetailAccountInfo.ownerId = ownerId
  15 + this.$refs.ownerDetailAccount._loadOwnerDetailAccountData(1, 10)
  16 + }
  17 + }
  18 +}
  19 +</script>
0 20 \ No newline at end of file
... ...
src/components/owner/ownerDetailAccountReceipt.vue 0 → 100644
  1 +<template>
  2 + <div>
  3 + <el-row class="margin-top-lg">
  4 + <el-col :span="12"></el-col>
  5 + <el-col :span="12" class="text-right">
  6 + <el-button type="primary" size="small" @click="_printFeeAccountReceipt" style="margin-left:10px">
  7 + {{$t('ownerDetailAccountReceipt.print')}}
  8 + </el-button>
  9 + <el-button type="primary" size="small" @click="_printFeeSmallAccountReceipt" style="margin-left:10px">
  10 + {{$t('ownerDetailAccountReceipt.printSmall')}}
  11 + </el-button>
  12 + </el-col>
  13 + </el-row>
  14 + <div class="margin-top">
  15 + <el-table
  16 + :data="ownerDetailAccountReceiptInfo.feeReceipts"
  17 + style="width: 100%; margin-top: 10px"
  18 + border
  19 + stripe
  20 + >
  21 + <el-table-column width="50" align="center">
  22 + <template slot-scope="scope">
  23 + <el-checkbox
  24 + v-model="scope.row.checked"
  25 + @change="handleCheckChange(scope.row)"
  26 + ></el-checkbox>
  27 + </template>
  28 + </el-table-column>
  29 + <el-table-column prop="acctName" :label="$t('ownerDetailAccountReceipt.accountName')" align="center"></el-table-column>
  30 + <el-table-column prop="acctTypeName" :label="$t('ownerDetailAccountReceipt.accountType')" align="center"></el-table-column>
  31 + <el-table-column prop="ownerName" :label="$t('ownerDetailAccountReceipt.owner')" align="center"></el-table-column>
  32 + <el-table-column prop="receivedAmount" :label="$t('ownerDetailAccountReceipt.prestoreAmount')" align="center"></el-table-column>
  33 + <el-table-column prop="primeRateName" :label="$t('ownerDetailAccountReceipt.prestoreMethod')" align="center"></el-table-column>
  34 + <el-table-column prop="amount" :label="$t('ownerDetailAccountReceipt.totalAmount')" align="center"></el-table-column>
  35 + <el-table-column prop="createTime" :label="$t('ownerDetailAccountReceipt.prestoreTime')" align="center"></el-table-column>
  36 + <el-table-column prop="arId" :label="$t('ownerDetailAccountReceipt.receiptId')" align="center"></el-table-column>
  37 + </el-table>
  38 + <el-pagination
  39 + @current-change="handleCurrentChange"
  40 + :current-page="currentPage"
  41 + :page-size="pageSize"
  42 + layout="total, prev, pager, next, jumper"
  43 + :total="total">
  44 + </el-pagination>
  45 + </div>
  46 + </div>
  47 +</template>
  48 +
  49 +<script>
  50 +import { listAccountReceipt } from '@/api/owner/ownerDetailAccountReceiptApi'
  51 +import { getCommunityId } from '@/api/community/communityApi'
  52 +
  53 +export default {
  54 + name: 'OwnerDetailAccountReceipt',
  55 + data() {
  56 + return {
  57 + ownerDetailAccountReceiptInfo: {
  58 + feeReceipts: [],
  59 + ownerId: '',
  60 + total: 0,
  61 + records: 0,
  62 + selectReceipts: []
  63 + },
  64 + currentPage: 1,
  65 + pageSize: 10,
  66 + total: 0,
  67 + communityId: ''
  68 + }
  69 + },
  70 + created() {
  71 + this.communityId = getCommunityId()
  72 + },
  73 + methods: {
  74 + open(ownerId) {
  75 + this.ownerDetailAccountReceiptInfo.ownerId = ownerId
  76 + this._listOwnerDetailAccountReceipt(this.currentPage, this.pageSize)
  77 + },
  78 + _listOwnerDetailAccountReceipt(page, rows) {
  79 + this.ownerDetailAccountReceiptInfo.selectReceipts = []
  80 + const param = {
  81 + page: page,
  82 + row: rows,
  83 + ownerId: this.ownerDetailAccountReceiptInfo.ownerId,
  84 + communityId: this.communityId
  85 + }
  86 +
  87 + listAccountReceipt(param).then(response => {
  88 + this.ownerDetailAccountReceiptInfo.feeReceipts = response.data.data.map(item => {
  89 + return { ...item, checked: false }
  90 + })
  91 + this.total = response.data.total
  92 + }).catch(error => {
  93 + console.error('请求失败:', error)
  94 + })
  95 + },
  96 + _printFeeAccountReceipt() {
  97 + const selected = this.ownerDetailAccountReceiptInfo.feeReceipts.filter(item => item.checked)
  98 + if (selected.length < 1) {
  99 + this.$message.warning(this.$t('ownerDetailAccountReceipt.selectPrint'))
  100 + return
  101 + }
  102 + const arIds = selected.map(item => item.arId).join(',')
  103 + window.open(`/print.html#/pages/property/printAccountReceipt?arIds=${arIds}&apply=N`)
  104 + },
  105 + _printFeeSmallAccountReceipt() {
  106 + const selected = this.ownerDetailAccountReceiptInfo.feeReceipts.filter(item => item.checked)
  107 + if (selected.length < 1) {
  108 + this.$message.warning(this.$t('ownerDetailAccountReceipt.selectPrint'))
  109 + return
  110 + }
  111 + const arIds = selected.map(item => item.arId).join(',')
  112 + window.open(`/smallPrint.html#/pages/property/printSmallAccountReceipt?arIds=${arIds}`)
  113 + },
  114 + handleCheckChange(row) {
  115 + if (row.checked) {
  116 + this.ownerDetailAccountReceiptInfo.selectReceipts.push(row.arId)
  117 + } else {
  118 + const index = this.ownerDetailAccountReceiptInfo.selectReceipts.indexOf(row.arId)
  119 + if (index > -1) {
  120 + this.ownerDetailAccountReceiptInfo.selectReceipts.splice(index, 1)
  121 + }
  122 + }
  123 + },
  124 + handleCurrentChange(val) {
  125 + this.currentPage = val
  126 + this._listOwnerDetailAccountReceipt(val, this.pageSize)
  127 + }
  128 + }
  129 +}
  130 +</script>
0 131 \ No newline at end of file
... ...
src/components/owner/ownerDetailAccountReceiptDemo.vue 0 → 100644
  1 +<template>
  2 + <owner-detail-account-receipt ref="ownerDetailAccountReceipt" />
  3 +</template>
  4 +
  5 +<script>
  6 +import OwnerDetailAccountReceipt from '@/components/owner/ownerDetailAccountReceipt'
  7 +
  8 +export default {
  9 + components: {
  10 + OwnerDetailAccountReceipt
  11 + },
  12 + methods: {
  13 + open(ownerId) {
  14 + this.$refs.ownerDetailAccountReceipt.open(ownerId)
  15 + }
  16 + }
  17 +}
  18 +</script>
0 19 \ No newline at end of file
... ...
src/components/owner/ownerDetailAppUser.vue 0 → 100644
  1 +<template>
  2 + <div class="margin-top">
  3 + <el-table :data="ownerDetailAppUserInfo.appUsers" style="width: 100%">
  4 + <el-table-column prop="communityName" :label="$t('ownerDetailAppUser.communityName')" align="center"></el-table-column>
  5 + <el-table-column prop="appUserName" :label="$t('ownerDetailAppUser.relatedOwner')" align="center"></el-table-column>
  6 + <el-table-column prop="idCard" :label="$t('ownerDetailAppUser.idCard')" align="center"></el-table-column>
  7 + <el-table-column prop="link" :label="$t('ownerDetailAppUser.phone')" align="center"></el-table-column>
  8 + <el-table-column prop="stateName" :label="$t('ownerDetailAppUser.status')" align="center"></el-table-column>
  9 + <el-table-column prop="createTime" :label="$t('ownerDetailAppUser.applyTime')" align="center"></el-table-column>
  10 + <el-table-column prop="appTypeName" :label="$t('ownerDetailAppUser.appType')" align="center"></el-table-column>
  11 + <el-table-column :label="$t('common.operation')" align="center" width="300">
  12 + <template slot-scope="scope">
  13 + <el-button-group>
  14 + <el-button size="mini" v-if="scope.row.state == '10000'"
  15 + @click="_openAuditAppUserBindingOwnerModel(scope.row)">
  16 + {{ $t('common.audit') }}
  17 + </el-button>
  18 + <el-button size="mini" @click="_deleteAppUserBindingOwnerModel(scope.row)">
  19 + {{ $t('ownerDetailAppUser.unbind') }}
  20 + </el-button>
  21 + <el-button size="mini" @click="_resetUserPwdModel(scope.row)">
  22 + {{ $t('ownerDetailAppUser.resetPwd') }}
  23 + </el-button>
  24 + </el-button-group>
  25 + </template>
  26 + </el-table-column>
  27 + </el-table>
  28 + <el-pagination
  29 + @current-change="handleCurrentChange"
  30 + :current-page="pagination.currentPage"
  31 + :page-size="pagination.pageSize"
  32 + :total="pagination.total"
  33 + layout="total, prev, pager, next, jumper">
  34 + </el-pagination>
  35 +
  36 + <audit ref="audit" @auditMessage="auditMessage"></audit>
  37 + <delete-app-user-binding-owner ref="deleteAppUserBindingOwner" @refresh="_loadOwnerDetailAppUserData"></delete-app-user-binding-owner>
  38 + <reset-staff-pwd ref="resetStaffPwd"></reset-staff-pwd>
  39 + </div>
  40 +</template>
  41 +
  42 +<script>
  43 +import Audit from '@/components/staff/Audit'
  44 +import DeleteAppUserBindingOwner from './DeleteAppUserBindingOwner'
  45 +import ResetStaffPwd from '@/components/staff/resetStaffPwd'
  46 +import { listAuditAppUserBindingOwners, updateAppUserBindingOwner } from '@/api/owner/ownerDetailAppUserApi'
  47 +import { getCommunityId } from '@/api/community/communityApi'
  48 +
  49 +export default {
  50 + name: 'OwnerDetailAppUser',
  51 + components: {
  52 + Audit,
  53 + DeleteAppUserBindingOwner,
  54 + ResetStaffPwd
  55 + },
  56 + data() {
  57 + return {
  58 + ownerDetailAppUserInfo: {
  59 + appUsers: [],
  60 + ownerId: '',
  61 + name: '',
  62 + currentAppUserId: ''
  63 + },
  64 + pagination: {
  65 + currentPage: 1,
  66 + pageSize: 10,
  67 + total: 0
  68 + }
  69 + }
  70 + },
  71 + methods: {
  72 + open(ownerId, ownerName, link) {
  73 + this.ownerDetailAppUserInfo.ownerId = ownerId
  74 + this.ownerDetailAppUserInfo.ownerName = ownerName
  75 + this.ownerDetailAppUserInfo.link = link
  76 + this._loadOwnerDetailAppUserData(1, this.pagination.pageSize)
  77 + },
  78 + _loadOwnerDetailAppUserData(page, row) {
  79 + const params = {
  80 + communityId: getCommunityId(),
  81 + memberId: this.ownerDetailAppUserInfo.ownerId,
  82 + name: this.ownerDetailAppUserInfo.name,
  83 + page: page,
  84 + row: row
  85 + }
  86 +
  87 + listAuditAppUserBindingOwners(params).then(response => {
  88 + this.ownerDetailAppUserInfo.appUsers = response.data
  89 + this.pagination.total = response.records
  90 + }).catch(error => {
  91 + console.error('请求失败处理', error)
  92 + })
  93 + },
  94 + _openAuditAppUserBindingOwnerModel(auditAppUserBindingOwner) {
  95 + this.ownerDetailAppUserInfo.currentAppUserId = auditAppUserBindingOwner.appUserId
  96 + this.$refs.audit.open({})
  97 + },
  98 + _auditAppUserBindingOwner(auditInfo) {
  99 + auditInfo.communityId = getCommunityId()
  100 + auditInfo.appUserId = this.ownerDetailAppUserInfo.currentAppUserId
  101 +
  102 + updateAppUserBindingOwner(auditInfo).then(() => {
  103 + this.$message.success(this.$t('common.processSuccess'))
  104 + this._loadOwnerDetailAppUserData(1, this.pagination.pageSize)
  105 + }).catch(error => {
  106 + this.$message.error(this.$t('common.processFailed') + error)
  107 + })
  108 + },
  109 + _deleteAppUserBindingOwnerModel(auditAppUserBindingOwner) {
  110 + this.$refs.deleteAppUserBindingOwner.open(auditAppUserBindingOwner)
  111 + },
  112 + _resetUserPwdModel(staff) {
  113 + this.$refs.resetStaffPwd.open(staff)
  114 + },
  115 + handleCurrentChange(val) {
  116 + this._loadOwnerDetailAppUserData(val, this.pagination.pageSize)
  117 + },
  118 + },
  119 + created() {
  120 + this.$on('switch', (data) => {
  121 + this.ownerDetailAppUserInfo.ownerId = data.ownerId
  122 + this._loadOwnerDetailAppUserData(1, this.pagination.pageSize)
  123 + })
  124 + }
  125 +}
  126 +</script>
0 127 \ No newline at end of file
... ...
src/components/owner/ownerDetailAppUserDemo.vue 0 → 100644
  1 +<template>
  2 + <owner-detail-app-user ref="ownerDetailAppUser" />
  3 +</template>
  4 +
  5 +<script>
  6 +import OwnerDetailAppUser from './ownerDetailAppUser'
  7 +
  8 +export default {
  9 + components: {
  10 + OwnerDetailAppUser
  11 + },
  12 + methods: {
  13 + open(ownerId) {
  14 + this.$refs.ownerDetailAppUser.ownerDetailAppUserInfo.ownerId = ownerId
  15 + this.$refs.ownerDetailAppUser._loadOwnerDetailAppUserData(1, 10)
  16 + }
  17 + }
  18 +}
  19 +</script>
0 20 \ No newline at end of file
... ...
src/components/owner/ownerDetailCar.vue 0 → 100644
  1 +<template>
  2 + <div class="margin-top">
  3 + <el-row class="margin-top-lg">
  4 + <el-col :span="4" class="padding-right-xs padding-left-xl">
  5 + <el-input
  6 + v-model="ownerDetailCarInfo.carNum"
  7 + :placeholder="$t('ownerDetailCar.pleaseEnterCarNumber')"
  8 + />
  9 + </el-col>
  10 + <el-col :span="4" class="padding-right-xs padding-right-xl">
  11 + <el-button
  12 + type="primary"
  13 + size="small"
  14 + style="margin-left:10px"
  15 + @click="_qureyOwnerDetailCar"
  16 + >
  17 + <i class="el-icon-search"></i>{{ $t('common.query') }}
  18 + </el-button>
  19 + </el-col>
  20 + <el-col :span="16" class="text-right">
  21 + <el-button
  22 + type="primary"
  23 + size="small"
  24 + style="margin-left:10px"
  25 + v-if="hasPrivilege('502023032813991677')"
  26 + @click="_addOwnerCar"
  27 + >
  28 + {{ $t('ownerDetailCar.addCar') }}
  29 + </el-button>
  30 + </el-col>
  31 + </el-row>
  32 + <div class="margin-top">
  33 + <el-table
  34 + :data="ownerDetailCarInfo.cars"
  35 + style="width: 100%"
  36 + border
  37 + stripe
  38 + >
  39 + <el-table-column
  40 + prop="carNum"
  41 + :label="$t('ownerDetailCar.carNumber')"
  42 + align="center"
  43 + />
  44 + <el-table-column
  45 + :label="$t('ownerDetailCar.licenseType')"
  46 + align="center"
  47 + >
  48 + <template slot-scope="scope">
  49 + {{ scope.row.leaseType === 'T' ? $t('ownerDetailCar.temporaryCar') : scope.row.leaseTypeName }}
  50 + </template>
  51 + </el-table-column>
  52 + <el-table-column
  53 + prop="carTypeName"
  54 + :label="$t('ownerDetailCar.carType')"
  55 + align="center"
  56 + />
  57 + <el-table-column
  58 + prop="carColor"
  59 + :label="$t('ownerDetailCar.color')"
  60 + align="center"
  61 + />
  62 + <el-table-column
  63 + :label="$t('ownerDetailCar.owner')"
  64 + align="center"
  65 + >
  66 + <template slot-scope="scope">
  67 + {{ scope.row.ownerName }}({{ scope.row.link }})
  68 + </template>
  69 + </el-table-column>
  70 + <el-table-column
  71 + :label="$t('ownerDetailCar.parkingSpace')"
  72 + align="center"
  73 + >
  74 + <template slot-scope="scope">
  75 + <span v-if="scope.row.areaNum && scope.row.state === '1001'">
  76 + {{ scope.row.areaNum }}-{{ scope.row.num }}
  77 + </span>
  78 + <span v-else>
  79 + {{ $t('ownerDetailCar.parkingSpaceReleased') }}
  80 + </span>
  81 + </template>
  82 + </el-table-column>
  83 + <el-table-column
  84 + :label="$t('ownerDetailCar.validityPeriod')"
  85 + align="center"
  86 + >
  87 + <template slot-scope="scope">
  88 + <div v-if="scope.row.leaseType === 'H'">
  89 + {{ scope.row.startTime }}<br>~{{ scope.row.endTime }}
  90 + </div>
  91 + <div v-else>-</div>
  92 + </template>
  93 + </el-table-column>
  94 + </el-table>
  95 + <el-row>
  96 + <el-col :span="12" :offset="12">
  97 + <el-pagination
  98 + @current-change="handlePageChange"
  99 + :current-page="pagination.currentPage"
  100 + :page-size="pagination.pageSize"
  101 + :total="pagination.total"
  102 + layout="total, prev, pager, next, jumper"
  103 + class="text-right"
  104 + />
  105 + </el-col>
  106 + </el-row>
  107 + </div>
  108 + </div>
  109 +</template>
  110 +
  111 +<script>
  112 +import { queryOwnerCars } from '@/api/owner/ownerDetailCarApi'
  113 +import { getCommunityId } from '@/api/community/communityApi'
  114 +
  115 +export default {
  116 + name: 'OwnerDetailCar',
  117 + data() {
  118 + return {
  119 + ownerDetailCarInfo: {
  120 + cars: [],
  121 + ownerId: '',
  122 + ownerName: '',
  123 + carNum: ''
  124 + },
  125 + pagination: {
  126 + currentPage: 1,
  127 + pageSize: 10,
  128 + total: 0
  129 + }
  130 + }
  131 + },
  132 + methods: {
  133 + open(ownerId, ownerName) {
  134 + this.ownerDetailCarInfo.ownerId = ownerId
  135 + this.ownerDetailCarInfo.ownerName = ownerName
  136 + this._loadOwnerDetailCarData(1, 10)
  137 + },
  138 + _loadOwnerDetailCarData(page, row) {
  139 + const params = {
  140 + communityId: getCommunityId(),
  141 + ownerId: this.ownerDetailCarInfo.ownerId,
  142 + carNum: this.ownerDetailCarInfo.carNum,
  143 + page,
  144 + row
  145 + }
  146 +
  147 + queryOwnerCars(params).then(res => {
  148 + this.ownerDetailCarInfo.cars = res.data
  149 + this.pagination = {
  150 + currentPage: page,
  151 + pageSize: row,
  152 + total: res.records
  153 + }
  154 + }).catch(error => {
  155 + console.error('请求失败:', error)
  156 + })
  157 + },
  158 + _qureyOwnerDetailCar() {
  159 + this._loadOwnerDetailCarData(1, 10)
  160 + },
  161 + _addOwnerCar() {
  162 + this.$router.push({
  163 + path: '/pages/property/hireParkingSpace',
  164 + query: {
  165 + ownerId: this.ownerDetailCarInfo.ownerId,
  166 + ownerName: this.ownerDetailCarInfo.ownerName
  167 + }
  168 + })
  169 + },
  170 + handlePageChange(currentPage) {
  171 + this._loadOwnerDetailCarData(currentPage, this.pagination.pageSize)
  172 + },
  173 + }
  174 +}
  175 +</script>
  176 +
  177 +<style scoped>
  178 +.margin-top {
  179 + margin-top: 20px;
  180 +}
  181 +.margin-top-lg {
  182 + margin-top: 30px;
  183 +}
  184 +.padding-right-xs {
  185 + padding-right: 5px;
  186 +}
  187 +.padding-left-xl {
  188 + padding-left: 20px;
  189 +}
  190 +.padding-right-xl {
  191 + padding-right: 20px;
  192 +}
  193 +.text-right {
  194 + text-align: right;
  195 +}
  196 +</style>
0 197 \ No newline at end of file
... ...
src/components/owner/ownerDetailCarDemo.vue 0 → 100644
  1 +<template>
  2 + <owner-detail-car ref="ownerDetailCar" />
  3 +</template>
  4 +
  5 +<script>
  6 +import OwnerDetailCar from '@/components/owner/ownerDetailCar'
  7 +
  8 +export default {
  9 + components: {
  10 + OwnerDetailCar
  11 + },
  12 + methods: {
  13 + open(ownerId, ownerName) {
  14 + this.$refs.ownerDetailCar.ownerDetailCarInfo.ownerId = ownerId
  15 + this.$refs.ownerDetailCar.ownerDetailCarInfo.ownerName = ownerName
  16 + this.$refs.ownerDetailCar._loadOwnerDetailCarData(1, 10)
  17 + }
  18 + }
  19 +}
  20 +</script>
0 21 \ No newline at end of file
... ...
src/components/owner/ownerDetailCarLang.js 0 → 100644
  1 +export default {
  2 + en: {
  3 + ownerDetailCar: {
  4 + placeholder: {
  5 + carNum: 'Please enter license plate number'
  6 + },
  7 + table: {
  8 + carNum: 'License Plate',
  9 + licenseType: 'License Type',
  10 + tempCar: 'Temporary Car',
  11 + carType: 'Car Type',
  12 + color: 'Color',
  13 + owner: 'Owner',
  14 + parkingSpace: 'Parking Space',
  15 + spaceReleased: 'Space released',
  16 + validity: 'Validity'
  17 + },
  18 + addCar: 'Add Vehicle'
  19 + }
  20 + },
  21 + zh: {
  22 + ownerDetailCar: {
  23 + placeholder: {
  24 + carNum: '请填写车牌号'
  25 + },
  26 + table: {
  27 + carNum: '车牌号',
  28 + licenseType: '车牌类型',
  29 + tempCar: '临时车',
  30 + carType: '车辆类型',
  31 + color: '颜色',
  32 + owner: '业主',
  33 + parkingSpace: '车位',
  34 + spaceReleased: '车位已释放',
  35 + validity: '有效期'
  36 + },
  37 + addCar: '添加车辆'
  38 + }
  39 + }
  40 +}
0 41 \ No newline at end of file
... ...
src/components/owner/ownerDetailChargeMachineOrder.vue 0 → 100644
  1 +<template>
  2 + <div class="margin-top">
  3 + <el-table :data="ownerDetailChargeMachineOrderInfo.chargeMachineOrders" style="width: 100%" border stripe>
  4 + <el-table-column prop="orderId" :label="$t('ownerDetailChargeMachineOrder.id')" align="center"></el-table-column>
  5 + <el-table-column prop="personName" :label="$t('ownerDetailChargeMachineOrder.name')"
  6 + align="center"></el-table-column>
  7 + <el-table-column prop="personTel" :label="$t('ownerDetailChargeMachineOrder.phone')"
  8 + align="center"></el-table-column>
  9 + <el-table-column prop="machineName" :label="$t('ownerDetailChargeMachineOrder.charger')"
  10 + align="center"></el-table-column>
  11 + <el-table-column prop="portName" :label="$t('ownerDetailChargeMachineOrder.slot')"
  12 + align="center"></el-table-column>
  13 + <el-table-column :label="$t('ownerDetailChargeMachineOrder.chargeHours')" align="center">
  14 + <template slot-scope="scope">
  15 + <span v-if="scope.row.chargeHours === 999">{{ $t('ownerDetailChargeMachineOrder.byAmount') }}</span>
  16 + <span v-else>{{ scope.row.chargeHours }}{{ $t('ownerDetailChargeMachineOrder.hours') }}</span>
  17 + </template>
  18 + </el-table-column>
  19 + <el-table-column prop="energy" :label="$t('ownerDetailChargeMachineOrder.chargeAmount')"
  20 + align="center"></el-table-column>
  21 + <el-table-column prop="startTime" :label="$t('ownerDetailChargeMachineOrder.startTime')"
  22 + align="center"></el-table-column>
  23 + <el-table-column prop="endTime" :label="$t('ownerDetailChargeMachineOrder.endTime')"
  24 + align="center"></el-table-column>
  25 + <el-table-column prop="acctDetailId" :label="$t('ownerDetailChargeMachineOrder.deductionAccount')" align="center"
  26 + class-name="hand"></el-table-column>
  27 + <el-table-column prop="durationPrice" :label="$t('ownerDetailChargeMachineOrder.hourPrice')"
  28 + align="center"></el-table-column>
  29 + <el-table-column :label="$t('ownerDetailChargeMachineOrder.deductionAmount')" align="center">
  30 + <template slot-scope="scope">
  31 + {{ scope.row.amount }}(<a href="javascript:void(0)"
  32 + @click="_viewOrderAccts(scope.row)">{{ $t('ownerDetailChargeMachineOrder.detail') }}</a>)
  33 + </template>
  34 + </el-table-column>
  35 + <el-table-column :label="$t('ownerDetailChargeMachineOrder.socketStatus')" align="center">
  36 + <template slot-scope="scope">
  37 + {{ scope.row.stateName }}
  38 + <span v-if="scope.row.state === '1001'">
  39 + (<a href="javascript:void(0)"
  40 + @click="_showStopCharge(scope.row)">{{ $t('ownerDetailChargeMachineOrder.stopCharge') }}</a>)
  41 + </span>
  42 + </template>
  43 + </el-table-column>
  44 + <el-table-column prop="remark" :label="$t('ownerDetailChargeMachineOrder.description')" align="center">
  45 + <template slot-scope="scope">
  46 + {{ scope.row.remark || '-' }}
  47 + </template>
  48 + </el-table-column>
  49 + </el-table>
  50 + <el-row>
  51 + <el-col :span="4"></el-col>
  52 + <el-col :span="20">
  53 + <el-pagination @current-change="handleCurrentChange" :current-page="currentPage" :page-size="pageSize"
  54 + layout="total, prev, pager, next, jumper" :total="total">
  55 + </el-pagination>
  56 + </el-col>
  57 + </el-row>
  58 + <!-- <stop-charge-machine ref="stopChargeMachine"></stop-charge-machine> -->
  59 + </div>
  60 +</template>
  61 +
  62 +<script>
  63 +import { getOpenApi } from '@/api/owner/ownerDetailChargeMachineOrderApi'
  64 +import { getCommunityId } from '@/api/community/communityApi'
  65 +// import StopChargeMachine from '@/components/machine/stopChargeMachine'
  66 +
  67 +export default {
  68 + name: 'OwnerDetailChargeMachineOrder',
  69 + components: {
  70 + //StopChargeMachine
  71 + },
  72 + data() {
  73 + return {
  74 + ownerDetailChargeMachineOrderInfo: {
  75 + chargeMachineOrders: [],
  76 + ownerId: '',
  77 + link: ''
  78 + },
  79 + currentPage: 1,
  80 + pageSize: 10,
  81 + total: 0,
  82 + communityId: ''
  83 + }
  84 + },
  85 + created() {
  86 + this.communityId = getCommunityId()
  87 + },
  88 + methods: {
  89 + open(ownerId, link) {
  90 + this.ownerDetailChargeMachineOrderInfo.ownerId = ownerId
  91 + this.ownerDetailChargeMachineOrderInfo.link = link
  92 + this._loadOwnerDetailChargeMachineOrderData(this.currentPage, this.pageSize)
  93 + },
  94 + _loadOwnerDetailChargeMachineOrderData(page, row) {
  95 + const param = {
  96 + page: page,
  97 + row: row,
  98 + communityId: this.communityId,
  99 + personTel: this.ownerDetailChargeMachineOrderInfo.link,
  100 + iotApiCode: 'listChargeMachineOrderBmoImpl'
  101 + }
  102 +
  103 + getOpenApi(param).then(response => {
  104 + this.ownerDetailChargeMachineOrderInfo.chargeMachineOrders = response.data.data
  105 + this.total = response.data.total
  106 + }).catch(error => {
  107 + console.error('请求失败:', error)
  108 + })
  109 + },
  110 + _viewOrderAccts(order) {
  111 + this.$router.push(`/pages/machine/chargeMachineOrderAccts?orderId=${order.orderId}`)
  112 + },
  113 + _showStopCharge(order) {
  114 + this.$refs.stopChargeMachine.open(order)
  115 + },
  116 + handleCurrentChange(val) {
  117 + this.currentPage = val
  118 + this._loadOwnerDetailChargeMachineOrderData(val, this.pageSize)
  119 + }
  120 + }
  121 +}
  122 +</script>
  123 +
  124 +<style scoped>
  125 +.hand {
  126 + cursor: pointer;
  127 +}
  128 +</style>
0 129 \ No newline at end of file
... ...
src/components/owner/ownerDetailChargeMachineOrderDemo.vue 0 → 100644
  1 +<template>
  2 + <owner-detail-charge-machine-order ref="ownerDetailChargeMachineOrder" />
  3 +</template>
  4 +
  5 +<script>
  6 +import OwnerDetailChargeMachineOrder from '@/components/owner/ownerDetailChargeMachineOrder'
  7 +
  8 +export default {
  9 + components: {
  10 + OwnerDetailChargeMachineOrder
  11 + },
  12 + methods: {
  13 + open(ownerId, link) {
  14 + this.$refs.ownerDetailChargeMachineOrder.open(ownerId, link)
  15 + }
  16 + }
  17 +}
  18 +</script>
0 19 \ No newline at end of file
... ...
src/components/owner/ownerDetailComplaint.vue 0 → 100644
  1 +<template>
  2 + <div class="margin-top">
  3 + <el-table :data="ownerDetailComplaintInfo.complaints" style="width: 100%">
  4 + <el-table-column prop="typeCdName" :label="$t('complaint.table.type')" align="center"></el-table-column>
  5 + <el-table-column :label="$t('complaint.table.room')" align="center">
  6 + <template slot-scope="scope">
  7 + {{scope.row.floorNum}}-{{scope.row.unitNum}}-{{scope.row.roomNum}}
  8 + </template>
  9 + </el-table-column>
  10 + <el-table-column prop="complaintName" :label="$t('complaint.table.contact')" align="center"></el-table-column>
  11 + <el-table-column prop="tel" :label="$t('complaint.table.phone')" align="center"></el-table-column>
  12 + <el-table-column prop="stateName" :label="$t('complaint.table.status')" align="center"></el-table-column>
  13 + <el-table-column prop="currentUserName" :label="$t('complaint.table.handler')" align="center">
  14 + <template slot-scope="scope">
  15 + {{scope.row.currentUserName == '' ? $t('common.none'):scope.row.currentUserName}}
  16 + </template>
  17 + </el-table-column>
  18 + <el-table-column prop="currentUserTel" :label="$t('complaint.table.handlerPhone')" align="center">
  19 + <template slot-scope="scope">
  20 + {{scope.row.currentUserTel == '' ? $t('common.none'):scope.row.currentUserTel}}
  21 + </template>
  22 + </el-table-column>
  23 + <el-table-column prop="createTime" :label="$t('complaint.table.createTime')" align="center"></el-table-column>
  24 + <el-table-column :label="$t('common.operation')" align="center" width="200">
  25 + <template slot-scope="scope">
  26 + <el-button-group>
  27 + <el-button size="mini" @click="_openComplaintDetailModel(scope.row)">
  28 + {{ $t('common.detail') }}
  29 + </el-button>
  30 + <el-button size="mini" @click="_openRunWorkflowImage(scope.row)">
  31 + {{ $t('ownerDetailComplaint.flowChart') }}
  32 + </el-button>
  33 + </el-button-group>
  34 + </template>
  35 + </el-table-column>
  36 + </el-table>
  37 + <el-pagination
  38 + @current-change="handleCurrentChange"
  39 + :current-page="pagination.currentPage"
  40 + :page-size="pagination.pageSize"
  41 + :total="pagination.total"
  42 + layout="total, prev, pager, next, jumper">
  43 + </el-pagination>
  44 +
  45 + <complaint-detail ref="complaintDetail"></complaint-detail>
  46 + <view-image ref="viewImage"></view-image>
  47 + </div>
  48 +</template>
  49 +
  50 +<script>
  51 +import ComplaintDetail from '@/components/oa/complaintDetail'
  52 +import ViewImage from '@/components/system/viewImage'
  53 +import { listComplaints, listRunWorkflowImage } from '@/api/owner/ownerDetailComplaintApi'
  54 +import { getCommunityId } from '@/api/community/communityApi'
  55 +
  56 +export default {
  57 + name: 'OwnerDetailComplaint',
  58 + components: {
  59 + ComplaintDetail,
  60 + ViewImage
  61 + },
  62 + data() {
  63 + return {
  64 + ownerDetailComplaintInfo: {
  65 + complaints: [],
  66 + ownerId: '',
  67 + ownerName: '',
  68 + link: ''
  69 + },
  70 + pagination: {
  71 + currentPage: 1,
  72 + pageSize: 10,
  73 + total: 0
  74 + }
  75 + }
  76 + },
  77 + methods: {
  78 + open(ownerId, ownerName, link) {
  79 + this.ownerDetailComplaintInfo.ownerId = ownerId
  80 + this.ownerDetailComplaintInfo.ownerName = ownerName
  81 + this.ownerDetailComplaintInfo.link = link
  82 + this._loadOwnerDetailComplaintData(1, this.pagination.pageSize)
  83 + },
  84 + _loadOwnerDetailComplaintData(page, row) {
  85 + const params = {
  86 + communityId: getCommunityId(),
  87 + memberId: this.ownerDetailComplaintInfo.ownerId,
  88 + page: page,
  89 + row: row
  90 + }
  91 +
  92 + listComplaints(params).then(response => {
  93 + this.ownerDetailComplaintInfo.complaints = response.complaints
  94 + this.pagination.total = response.records
  95 + }).catch(error => {
  96 + console.error('请求失败处理', error)
  97 + })
  98 + },
  99 + _openComplaintDetailModel(complaint) {
  100 + this.$refs.complaintDetail.open(complaint)
  101 + },
  102 + _openRunWorkflowImage(complaint) {
  103 + const params = {
  104 + communityId: getCommunityId(),
  105 + businessKey: complaint.complaintId
  106 + }
  107 +
  108 + listRunWorkflowImage(params).then(response => {
  109 + if (response.code != '0') {
  110 + this.$message.error(response.msg)
  111 + return
  112 + }
  113 + this.$refs.viewImage.open('data:image/png;base64,' + response.data)
  114 + }).catch(error => {
  115 + console.error('请求失败处理', error)
  116 + })
  117 + },
  118 + handleCurrentChange(val) {
  119 + this._loadOwnerDetailComplaintData(val, this.pagination.pageSize)
  120 + }
  121 + },
  122 + created() {
  123 + this.$on('switch', (data) => {
  124 + this.ownerDetailComplaintInfo.ownerId = data.ownerId
  125 + this._loadOwnerDetailComplaintData(1, this.pagination.pageSize)
  126 + })
  127 + }
  128 +}
  129 +</script>
0 130 \ No newline at end of file
... ...
src/components/owner/ownerDetailContract.vue 0 → 100644
  1 +<template>
  2 + <div class="margin-top">
  3 + <el-table :data="ownerDetailContractInfo.contracts" style="width: 100%">
  4 + <el-table-column prop="contractName" :label="$t('ownerDetailContract.contractName')" align="center"></el-table-column>
  5 + <el-table-column prop="contractCode" :label="$t('ownerDetailContract.contractCode')" align="center"></el-table-column>
  6 + <el-table-column :label="$t('ownerDetailContract.parentContractCode')" align="center">
  7 + <template slot-scope="scope">
  8 + {{scope.row.parentContractCode?scope.row.parentContractCode:'-'}}
  9 + </template>
  10 + </el-table-column>
  11 + <el-table-column prop="contractTypeName" :label="$t('ownerDetailContract.contractType')" align="center"></el-table-column>
  12 + <el-table-column prop="operator" :label="$t('ownerDetailContract.operator')" align="center"></el-table-column>
  13 + <el-table-column prop="amount" :label="$t('ownerDetailContract.amount')" align="center"></el-table-column>
  14 + <el-table-column prop="startTime" :label="$t('ownerDetailContract.startTime')" align="center"></el-table-column>
  15 + <el-table-column prop="endTime" :label="$t('ownerDetailContract.endTime')" align="center"></el-table-column>
  16 + <el-table-column prop="createTime" :label="$t('ownerDetailContract.createTime')" align="center"></el-table-column>
  17 + <el-table-column prop="stateName" :label="$t('ownerDetailContract.status')" align="center"></el-table-column>
  18 + </el-table>
  19 + <el-pagination
  20 + @current-change="handleCurrentChange"
  21 + :current-page="pagination.currentPage"
  22 + :page-size="pagination.pageSize"
  23 + :total="pagination.total"
  24 + layout="total, prev, pager, next, jumper">
  25 + </el-pagination>
  26 + </div>
  27 +</template>
  28 +
  29 +<script>
  30 +import { queryContract } from '@/api/owner/ownerDetailContractApi'
  31 +import { getCommunityId } from '@/api/community/communityApi'
  32 +
  33 +export default {
  34 + name: 'OwnerDetailContract',
  35 + data() {
  36 + return {
  37 + ownerDetailContractInfo: {
  38 + contracts: [],
  39 + ownerId: '',
  40 + },
  41 + pagination: {
  42 + currentPage: 1,
  43 + pageSize: 10,
  44 + total: 0
  45 + }
  46 + }
  47 + },
  48 + methods: {
  49 + _loadOwnerDetailContractData(page, row) {
  50 + const params = {
  51 + communityId: getCommunityId(),
  52 + objId: this.ownerDetailContractInfo.ownerId,
  53 + page: page,
  54 + row: row
  55 + }
  56 +
  57 + queryContract(params).then(response => {
  58 + this.ownerDetailContractInfo.contracts = response.data
  59 + this.pagination.total = response.records
  60 + }).catch(error => {
  61 + console.error('请求失败处理', error)
  62 + })
  63 + },
  64 + handleCurrentChange(val) {
  65 + this._loadOwnerDetailContractData(val, this.pagination.pageSize)
  66 + }
  67 + },
  68 + created() {
  69 + this.$on('switch', (data) => {
  70 + this.ownerDetailContractInfo.ownerId = data.ownerId
  71 + this._loadOwnerDetailContractData(1, this.pagination.pageSize)
  72 + })
  73 + }
  74 +}
  75 +</script>
0 76 \ No newline at end of file
... ...
src/components/owner/ownerDetailContractDemo.vue 0 → 100644
  1 +<template>
  2 + <owner-detail-contract ref="ownerDetailContract" />
  3 +</template>
  4 +
  5 +<script>
  6 +import OwnerDetailContract from './ownerDetailContract'
  7 +
  8 +export default {
  9 + components: {
  10 + OwnerDetailContract
  11 + },
  12 + methods: {
  13 + open(ownerId) {
  14 + this.$refs.ownerDetailContract.ownerDetailContractInfo.ownerId = ownerId
  15 + this.$refs.ownerDetailContract._loadOwnerDetailContractData(1, 10)
  16 + }
  17 + }
  18 +}
  19 +</script>
0 20 \ No newline at end of file
... ...
src/components/owner/ownerDetailCoupon.vue 0 → 100644
  1 +<template>
  2 + <div class="margin-top">
  3 + <el-table :data="ownerDetailCouponInfo.coupons" style="width: 100%">
  4 + <el-table-column prop="couponId" :label="$t('ownerDetailCoupon.id')" align="center"></el-table-column>
  5 + <el-table-column prop="couponName" :label="$t('ownerDetailCoupon.couponName')" align="center"></el-table-column>
  6 + <el-table-column prop="value" :label="$t('ownerDetailCoupon.value')" align="center"></el-table-column>
  7 + <el-table-column prop="validityDay" :label="$t('ownerDetailCoupon.validity')" align="center"></el-table-column>
  8 + <el-table-column prop="userName" :label="$t('ownerDetailCoupon.userName')" align="center"></el-table-column>
  9 + <el-table-column prop="tel" :label="$t('ownerDetailCoupon.phone')" align="center"></el-table-column>
  10 + <el-table-column prop="toTypeName" :label="$t('ownerDetailCoupon.purpose')" align="center"></el-table-column>
  11 + <el-table-column prop="stock" :label="$t('ownerDetailCoupon.quantity')" align="center">
  12 + <template slot-scope="scope">{{scope.row.stock}}张</template>
  13 + </el-table-column>
  14 + <el-table-column prop="state" :label="$t('ownerDetailCoupon.status')" align="center">
  15 + <template slot-scope="scope">{{scope.row.state == '1001'?$t('ownerDetailCoupon.unused'):$t('ownerDetailCoupon.used')}}</template>
  16 + </el-table-column>
  17 + <el-table-column prop="startTime" :label="$t('ownerDetailCoupon.effectiveTime')" align="center"></el-table-column>
  18 + </el-table>
  19 + <el-pagination
  20 + @current-change="handleCurrentChange"
  21 + :current-page="pagination.currentPage"
  22 + :page-size="pagination.pageSize"
  23 + :total="pagination.total"
  24 + layout="total, prev, pager, next, jumper">
  25 + </el-pagination>
  26 + </div>
  27 +</template>
  28 +
  29 +<script>
  30 +import { listCouponPropertyUser } from '@/api/owner/ownerDetailCouponApi'
  31 +import { getCommunityId } from '@/api/community/communityApi'
  32 +
  33 +export default {
  34 + name: 'OwnerDetailCoupon',
  35 + data() {
  36 + return {
  37 + ownerDetailCouponInfo: {
  38 + coupons: [],
  39 + ownerId: '',
  40 + link: '',
  41 + },
  42 + pagination: {
  43 + currentPage: 1,
  44 + pageSize: 10,
  45 + total: 0
  46 + }
  47 + }
  48 + },
  49 + methods: {
  50 + open(ownerId, ownerName, link) {
  51 + this.ownerDetailCouponInfo.ownerId = ownerId
  52 + this.ownerDetailCouponInfo.ownerName = ownerName
  53 + this.ownerDetailCouponInfo.link = link
  54 + this._loadOwnerDetailCouponData(1, this.pagination.pageSize)
  55 + },
  56 + _loadOwnerDetailCouponData(page, row) {
  57 + const params = {
  58 + page: page,
  59 + row: row,
  60 + communityId: getCommunityId(),
  61 + tel: this.ownerDetailCouponInfo.link
  62 + }
  63 +
  64 + listCouponPropertyUser(params).then(response => {
  65 + this.ownerDetailCouponInfo.coupons = response.data
  66 + this.pagination.total = response.records
  67 + }).catch(error => {
  68 + console.error('请求失败处理', error)
  69 + })
  70 + },
  71 + handleCurrentChange(val) {
  72 + this._loadOwnerDetailCouponData(val, this.pagination.pageSize)
  73 + }
  74 + },
  75 + created() {
  76 + this.$on('switch', (data) => {
  77 + this.ownerDetailCouponInfo.ownerId = data.ownerId
  78 + this.ownerDetailCouponInfo.link = data.link
  79 + this._loadOwnerDetailCouponData(1, this.pagination.pageSize)
  80 + })
  81 + }
  82 +}
  83 +</script>
  84 +
  85 +<style scoped>
  86 +/* 样式同上一个组件 */
  87 +</style>
0 88 \ No newline at end of file
... ...
src/components/owner/ownerDetailHis.vue 0 → 100644
  1 +<template>
  2 + <div class="owner-detail-his">
  3 + <el-row class="margin-top">
  4 + <el-table :data="ownerDetailHisInfo.owners" border style="width: 100%" class="footable">
  5 + <el-table-column prop="operate" :label="$t('ownerDetailHis.action')" align="center" >
  6 + <template slot-scope="scope">
  7 + {{ _getHisOwnerOperate(scope.row) }}
  8 + </template>
  9 + </el-table-column>
  10 + <el-table-column prop="userName" :label="$t('ownerDetailHis.operator')" align="center" >
  11 + <template slot-scope="scope">
  12 + {{ scope.row.userName || '-' }}
  13 + </template>
  14 + </el-table-column>
  15 + <el-table-column prop="createTime" :label="$t('ownerDetailHis.operateTime')" align="center"
  16 + width="180"></el-table-column>
  17 + <el-table-column prop="name" :label="$t('ownerDetailHis.name')" align="center" >
  18 + <template slot-scope="scope">
  19 + {{ scope.row.name }}({{ scope.row.link }})
  20 + </template>
  21 + </el-table-column>
  22 + <el-table-column prop="sex" :label="$t('ownerDetailHis.gender')" align="center" >
  23 + <template slot-scope="scope">
  24 + {{ scope.row.sex == 0 ? $t('ownerDetailHis.male') : $t('ownerDetailHis.female') }}
  25 + </template>
  26 + </el-table-column>
  27 + <el-table-column prop="idCard" :label="$t('ownerDetailHis.idCard')" align="center" >
  28 + <template slot-scope="scope">
  29 + {{ scope.row.idCard || '-' }}
  30 + </template>
  31 + </el-table-column>
  32 + <el-table-column prop="address" :label="$t('ownerDetailHis.address')" align="center" >
  33 + <template slot-scope="scope">
  34 + {{ scope.row.address || '-' }}
  35 + </template>
  36 + </el-table-column>
  37 + <el-table-column v-for="(item, index) in ownerDetailHisInfo.listColumns" :key="index" :label="item"
  38 + align="center" width="150">
  39 + <template slot-scope="scope">
  40 + {{ scope.row.listValues[index] || '-' }}
  41 + </template>
  42 + </el-table-column>
  43 + </el-table>
  44 +
  45 + <el-row class="margin-top">
  46 + <el-col :span="24" class="text-right">
  47 + <el-pagination @current-change="handleCurrentChange" :current-page="pagination.currentPage"
  48 + :page-size="pagination.pageSize" layout="total, prev, pager, next, jumper"
  49 + :total="pagination.total"></el-pagination>
  50 + </el-col>
  51 + </el-row>
  52 + </el-row>
  53 + </div>
  54 +</template>
  55 +
  56 +<script>
  57 +import { queryHisOwner } from '@/api/owner/ownerDetailHisApi'
  58 +import { getCommunityId } from '@/api/community/communityApi'
  59 +import { getDict } from '@/api/community/communityApi'
  60 +
  61 +export default {
  62 + name: 'OwnerDetailHis',
  63 + data() {
  64 + return {
  65 + ownerDetailHisInfo: {
  66 + owners: [],
  67 + ownerId: '',
  68 + ownerName: '',
  69 + carNum: '',
  70 + listColumns: [],
  71 + logStartTime: '',
  72 + logEndTime: '',
  73 + ownerNameLike: '',
  74 + staffNameLike: ''
  75 + },
  76 + pagination: {
  77 + currentPage: 1,
  78 + pageSize: 10,
  79 + total: 0
  80 + }
  81 + }
  82 + },
  83 + methods: {
  84 + open(ownerId, ownerName, ownerNameLike, logStartTime, logEndTime, staffNameLike) {
  85 + this.ownerDetailHisInfo.ownerId = ownerId
  86 + this.ownerDetailHisInfo.ownerName = ownerName
  87 + this.ownerDetailHisInfo.ownerNameLike = ownerNameLike
  88 + this.ownerDetailHisInfo.logStartTime = logStartTime
  89 + this.ownerDetailHisInfo.logEndTime = logEndTime
  90 + this.ownerDetailHisInfo.staffNameLike = staffNameLike
  91 + this._getColumns(() => {
  92 + this._loadOwnerDetailHisData(1, this.pagination.pageSize)
  93 + })
  94 + },
  95 + _loadOwnerDetailHisData(page, row) {
  96 + const params = {
  97 + communityId: getCommunityId(),
  98 + memberId: this.ownerDetailHisInfo.ownerId,
  99 + ownerNameLike: this.ownerDetailHisInfo.ownerNameLike,
  100 + logStartTime: this.ownerDetailHisInfo.logStartTime,
  101 + logEndTime: this.ownerDetailHisInfo.logEndTime,
  102 + staffNameLike: this.ownerDetailHisInfo.staffNameLike,
  103 + page: page,
  104 + row: row
  105 + }
  106 +
  107 + queryHisOwner(params)
  108 + .then(response => {
  109 + const data = response.data
  110 + this.ownerDetailHisInfo.owners = data.data
  111 + this.dealOwnerAttr(data.data)
  112 + this.pagination.total = data.records
  113 + this.pagination.currentPage = page
  114 + })
  115 + .catch(error => {
  116 + console.error('请求失败:', error)
  117 + })
  118 + },
  119 + handleCurrentChange(currentPage) {
  120 + this._loadOwnerDetailHisData(currentPage, this.pagination.pageSize)
  121 + },
  122 + dealOwnerAttr(owners) {
  123 + if (!owners) {
  124 + return
  125 + }
  126 + owners.forEach(item => {
  127 + this._getColumnsValue(item)
  128 + })
  129 + },
  130 + _getColumnsValue(owner) {
  131 + owner.listValues = []
  132 + if (!Object.prototype.hasOwnProperty.call(owner, 'ownerAttrDtos') || owner.ownerAttrDtos.length < 1) {
  133 + this.ownerDetailHisInfo.listColumns.forEach(() => {
  134 + owner.listValues.push('')
  135 + })
  136 + return
  137 + }
  138 + const ownerAttrDtos = owner.ownerAttrDtos
  139 + this.ownerDetailHisInfo.listColumns.forEach(value => {
  140 + let tmpValue = ''
  141 + ownerAttrDtos.forEach(attrItem => {
  142 + if (value === attrItem.specName) {
  143 + tmpValue = attrItem.valueName
  144 + }
  145 + })
  146 + owner.listValues.push(tmpValue)
  147 + })
  148 + },
  149 + _getColumns(callback) {
  150 + this.ownerDetailHisInfo.listColumns = []
  151 + getDict('building_owner_attr').then(data => {
  152 + this.ownerDetailHisInfo.listColumns = []
  153 + data.forEach(item => {
  154 + if (item.listShow === 'Y') {
  155 + this.ownerDetailHisInfo.listColumns.push(item.specName)
  156 + }
  157 + })
  158 + callback()
  159 + })
  160 + },
  161 + _getHisOwnerOperate(owner) {
  162 + let ownerCount = 0
  163 + this.ownerDetailHisInfo.owners.forEach(item => {
  164 + if (owner.bId === item.bId) {
  165 + ownerCount += 1
  166 + }
  167 + })
  168 + if (ownerCount <= 1) {
  169 + if (owner.operate === 'ADD') {
  170 + return this.$t('ownerDetailHis.add')
  171 + }
  172 + if (owner.operate === 'DEL') {
  173 + return this.$t('ownerDetailHis.delete')
  174 + }
  175 + return '-'
  176 + }
  177 + if (owner.operate === 'ADD') {
  178 + return this.$t('ownerDetailHis.modifyNew')
  179 + }
  180 + if (owner.operate === 'DEL') {
  181 + return this.$t('ownerDetailHis.modifyOld')
  182 + }
  183 + return '-'
  184 + }
  185 + }
  186 +}
  187 +</script>
  188 +
  189 +<style scoped>
  190 +.margin-top {
  191 + margin-top: 20px;
  192 +}
  193 +
  194 +.text-right {
  195 + text-align: right;
  196 +}
  197 +</style>
0 198 \ No newline at end of file
... ...
src/components/owner/ownerDetailHisFee.vue 0 → 100644
  1 +<template>
  2 + <div>
  3 + <div class="margin-top">
  4 + <el-table
  5 + :data="ownerDetailHisFeeInfo.feeDetails"
  6 + style="width: 100%; margin-top: 10px"
  7 + border
  8 + stripe
  9 + >
  10 + <el-table-column prop="feeName" :label="$t('ownerDetailHisFee.feeItem')" align="center"></el-table-column>
  11 + <el-table-column prop="payerObjName" :label="$t('ownerDetailHisFee.chargeObject')" align="center"></el-table-column>
  12 + <el-table-column prop="cycles" :label="$t('ownerDetailHisFee.cycle')" align="center"></el-table-column>
  13 + <el-table-column :label="$t('ownerDetailHisFee.receivableAmount')" align="center">
  14 + <template slot-scope="scope">
  15 + {{scope.row.receivableAmount}}/{{scope.row.receivedAmount}}<br>
  16 + <div v-if="scope.row.acctAmount>0">
  17 + {{$t('ownerDetailHisFee.accountDeduction')}}: {{scope.row.acctAmount}}<br>
  18 + </div>
  19 + <div v-for="(item,index) in scope.row.payFeeDetailDiscountDtoList" :key="index">
  20 + {{item.discountName}}: {{Math.abs(item.discountPrice)}}<br>
  21 + </div>
  22 + </template>
  23 + </el-table-column>
  24 + <el-table-column prop="primeRateName" :label="$t('ownerDetailHisFee.paymentMethod')" align="center"></el-table-column>
  25 + <el-table-column :label="$t('ownerDetailHisFee.paymentPeriod')" align="center">
  26 + <template slot-scope="scope">
  27 + {{dateFormat(scope.row.startTime)}}~<br>
  28 + {{dateFormat(scope.row.endTime)}}
  29 + </template>
  30 + </el-table-column>
  31 + <el-table-column prop="createTime" :label="$t('ownerDetailHisFee.paymentTime')" align="center"></el-table-column>
  32 + <el-table-column prop="cashierName" :label="$t('ownerDetailHisFee.cashier')" align="center">
  33 + <template slot-scope="scope">
  34 + {{scope.row.cashierName || '-'}}
  35 + </template>
  36 + </el-table-column>
  37 + <el-table-column prop="stateName" :label="$t('ownerDetailHisFee.status')" align="center"></el-table-column>
  38 + <el-table-column prop="remark" :label="$t('ownerDetailHisFee.remark')" align="center"></el-table-column>
  39 + <el-table-column :label="$t('ownerDetailHisFee.operation')" align="center">
  40 + <template slot-scope="scope">
  41 + <el-button
  42 + v-if="scope.row.state=='1400' || scope.row.state== '1200' || scope.row.state== ''"
  43 + type="text"
  44 + size="small"
  45 + @click="_toRefundFee(scope.row)"
  46 + >
  47 + {{$t('ownerDetailHisFee.detail')}}
  48 + </el-button>
  49 + </template>
  50 + </el-table-column>
  51 + </el-table>
  52 + <el-pagination
  53 + @current-change="handleCurrentChange"
  54 + :current-page="currentPage"
  55 + :page-size="pageSize"
  56 + layout="total, prev, pager, next, jumper"
  57 + :total="total">
  58 + </el-pagination>
  59 + </div>
  60 + </div>
  61 +</template>
  62 +
  63 +<script>
  64 +import { queryFeeDetail } from '@/api/owner/ownerDetailHisFeeApi'
  65 +import { getCommunityId } from '@/api/community/communityApi'
  66 +
  67 +export default {
  68 + name: 'OwnerDetailHisFee',
  69 + data() {
  70 + return {
  71 + ownerDetailHisFeeInfo: {
  72 + feeDetails: [],
  73 + ownerId: ''
  74 + },
  75 + currentPage: 1,
  76 + pageSize: 10,
  77 + total: 0,
  78 + communityId: ''
  79 + }
  80 + },
  81 + created() {
  82 + this.communityId = getCommunityId()
  83 + },
  84 + methods: {
  85 + open(ownerId) {
  86 + this.clearOwnerDetailHisFeeInfo()
  87 + this.ownerDetailHisFeeInfo.ownerId = ownerId
  88 + this._listOwnerDetailFeeDetails(this.currentPage, this.pageSize)
  89 + },
  90 + _listOwnerDetailFeeDetails(page, row) {
  91 + const param = {
  92 + page: page,
  93 + row: row,
  94 + communityId: this.communityId,
  95 + ownerId: this.ownerDetailHisFeeInfo.ownerId
  96 + }
  97 +
  98 + queryFeeDetail(param).then(response => {
  99 + this.ownerDetailHisFeeInfo.feeDetails = response.data.feeDetails
  100 + this.total = response.data.total
  101 + }).catch(error => {
  102 + console.error('请求失败:', error)
  103 + })
  104 + },
  105 + clearOwnerDetailHisFeeInfo() {
  106 + this.ownerDetailHisFeeInfo = {
  107 + feeDetails: [],
  108 + ownerId: ''
  109 + }
  110 + },
  111 + _toRefundFee(detail) {
  112 + this.$router.push(`/pages/property/propertyFee?feeId=${detail.feeId}`)
  113 + },
  114 + handleCurrentChange(val) {
  115 + this.currentPage = val
  116 + this._listOwnerDetailFeeDetails(val, this.pageSize)
  117 + },
  118 + dateFormat(date) {
  119 + // Implement your date formatting logic here
  120 + return date
  121 + }
  122 + }
  123 +}
  124 +</script>
0 125 \ No newline at end of file
... ...
src/components/owner/ownerDetailHisFeeDemo.vue 0 → 100644
  1 +<template>
  2 + <owner-detail-his-fee ref="ownerDetailHisFee" />
  3 +</template>
  4 +
  5 +<script>
  6 +import OwnerDetailHisFee from '@/components/owner/ownerDetailHisFee'
  7 +
  8 +export default {
  9 + components: {
  10 + OwnerDetailHisFee
  11 + },
  12 + methods: {
  13 + open(ownerId) {
  14 + this.$refs.ownerDetailHisFee.open(ownerId)
  15 + }
  16 + }
  17 +}
  18 +</script>
0 19 \ No newline at end of file
... ...
src/components/owner/ownerDetailMember.vue 0 → 100644
  1 +<template>
  2 + <div class="margin-top">
  3 + <el-row class="margin-top-lg">
  4 + <el-col :span="4" class="padding-right-xs padding-left-xl">
  5 + <el-input v-model="ownerDetailMemberInfo.name" type="text"
  6 + :placeholder="$t('ownerDetailMember.placeholder.name')" class="form-control"></el-input>
  7 + </el-col>
  8 + <el-col :span="4" class="padding-right-xs padding-right-xl">
  9 + <el-button type="primary" size="small" style="margin-left:10px"
  10 + @click="_qureyOwnerDetailMember()">
  11 + <i class="el-icon-search"></i>{{ $t('common.query') }}
  12 + </el-button>
  13 + </el-col>
  14 + <el-col :span="16" class="text-right">
  15 + <el-button type="primary" size="small" style="margin-left:10px"
  16 + v-if="hasPrivilege('502023032885101706')" @click="openAddMemberModel()">
  17 + <i class="el-icon-plus"></i>{{ $t('common.add') }}
  18 + </el-button>
  19 + </el-col>
  20 + </el-row>
  21 + <div class="margin-top">
  22 + <el-table :data="ownerDetailMemberInfo.members" style="width: 100%">
  23 + <el-table-column prop="faceUrl" :label="$t('ownerDetailMember.face')" align="center">
  24 + <template slot-scope="scope">
  25 + <img style="width: 60px; height: 60px;" class="border-radius" v-if="scope.row.faceUrl"
  26 + :src="scope.row.faceUrl" @click="_viewOwnerFace(scope.row.faceUrl)" />
  27 + <img style="width: 60px; height: 60px;" class="border-radius" v-else
  28 + src="/img/noPhoto.jpg" />
  29 + </template>
  30 + </el-table-column>
  31 + <el-table-column prop="name" :label="$t('ownerDetailMember.name')" align="center"></el-table-column>
  32 + <el-table-column prop="sex" :label="$t('ownerDetailMember.gender')" align="center">
  33 + <template slot-scope="scope">
  34 + {{scope.row.sex == 0 ? $t('common.male') : $t('common.female')}}
  35 + </template>
  36 + </el-table-column>
  37 + <el-table-column prop="personRoleName" :label="$t('ownerDetailMember.role')" align="center"></el-table-column>
  38 + <el-table-column prop="idCard" :label="$t('ownerDetailMember.idCard')" align="center"></el-table-column>
  39 + <el-table-column prop="link" :label="$t('ownerDetailMember.contact')" align="center"></el-table-column>
  40 + <el-table-column prop="address" :label="$t('ownerDetailMember.address')" align="center"></el-table-column>
  41 + <el-table-column :label="$t('common.operation')" align="center" width="180">
  42 + <template slot-scope="scope">
  43 + <el-button-group>
  44 + <el-button size="mini" @click="_openEditOwnerModel(scope.row)"
  45 + v-if="hasPrivilege('502023032899781711')">
  46 + {{ $t('common.edit') }}
  47 + </el-button>
  48 + <el-button size="mini" @click="_openDeleteOwnerModel(scope.row)"
  49 + v-if="hasPrivilege('502023032818941714')">
  50 + {{ $t('common.delete') }}
  51 + </el-button>
  52 + </el-button-group>
  53 + </template>
  54 + </el-table-column>
  55 + </el-table>
  56 + <el-pagination
  57 + @current-change="handleCurrentChange"
  58 + :current-page="pagination.currentPage"
  59 + :page-size="pagination.pageSize"
  60 + :total="pagination.total"
  61 + layout="total, prev, pager, next, jumper">
  62 + </el-pagination>
  63 + </div>
  64 +
  65 + <add-owner-member ref="addOwnerMember" @refresh="_loadOwnerDetailMemberData"></add-owner-member>
  66 + <edit-owner-member ref="editOwnerMember" @refresh="_loadOwnerDetailMemberData"></edit-owner-member>
  67 + <delete-owner ref="deleteOwner" @refresh="_loadOwnerDetailMemberData"></delete-owner>
  68 + </div>
  69 +</template>
  70 +
  71 +<script>
  72 +import AddOwnerMember from './addOwnerMember'
  73 +import EditOwnerMember from './editOwnerMember'
  74 +import DeleteOwner from './deleteOwner'
  75 +import { queryOwnerMembers } from '@/api/owner/ownerDetailMemberApi'
  76 +import { getCommunityId } from '@/api/community/communityApi'
  77 +
  78 +export default {
  79 + name: 'OwnerDetailMember',
  80 + components: {
  81 + AddOwnerMember,
  82 + EditOwnerMember,
  83 + DeleteOwner
  84 + },
  85 + data() {
  86 + return {
  87 + ownerDetailMemberInfo: {
  88 + members: [],
  89 + ownerId: '',
  90 + name: '',
  91 + },
  92 + pagination: {
  93 + currentPage: 1,
  94 + pageSize: 10,
  95 + total: 0
  96 + }
  97 + }
  98 + },
  99 + methods: {
  100 + open(ownerId, ownerName, link) {
  101 + this.ownerDetailMemberInfo.ownerId = ownerId
  102 + this.ownerDetailMemberInfo.ownerName = ownerName
  103 + this.ownerDetailMemberInfo.link = link
  104 + this._loadOwnerDetailMemberData(1, this.pagination.pageSize)
  105 + },
  106 + _loadOwnerDetailMemberData(page, row) {
  107 + const params = {
  108 + communityId: getCommunityId(),
  109 + ownerId: this.ownerDetailMemberInfo.ownerId,
  110 + name: this.ownerDetailMemberInfo.name,
  111 + page: page,
  112 + row: row
  113 + }
  114 +
  115 + queryOwnerMembers(params).then(response => {
  116 + this.ownerDetailMemberInfo.members = response.data
  117 + this.pagination.total = response.records
  118 + }).catch(error => {
  119 + console.error('请求失败处理', error)
  120 + })
  121 + },
  122 + _qureyOwnerDetailMember() {
  123 + this._loadOwnerDetailMemberData(1, this.pagination.pageSize)
  124 + },
  125 + openAddMemberModel() {
  126 + this.$refs.addOwnerMember.open({ ownerId: this.ownerDetailMemberInfo.ownerId })
  127 + },
  128 + _openDeleteOwnerModel(member) {
  129 + member.ownerId = this.ownerDetailMemberInfo.ownerId
  130 + this.$refs.deleteOwner.open(member)
  131 + },
  132 + _openEditOwnerModel(member) {
  133 + member.ownerId = this.ownerDetailMemberInfo.ownerId
  134 + this.$refs.editOwnerMember.open(member)
  135 + },
  136 + _viewOwnerFace(url) {
  137 + this.$emit('viewImage', url)
  138 + },
  139 + handleCurrentChange(val) {
  140 + this._loadOwnerDetailMemberData(val, this.pagination.pageSize)
  141 + },
  142 + },
  143 + created() {
  144 + this.$on('switch', (data) => {
  145 + this.ownerDetailMemberInfo.ownerId = data.ownerId
  146 + this._loadOwnerDetailMemberData(1, this.pagination.pageSize)
  147 + })
  148 + }
  149 +}
  150 +</script>
  151 +
  152 +<style scoped>
  153 +.margin-top {
  154 + margin-top: 20px;
  155 +}
  156 +.margin-top-lg {
  157 + margin-top: 30px;
  158 +}
  159 +.padding-right-xs {
  160 + padding-right: 5px;
  161 +}
  162 +.padding-left-xl {
  163 + padding-left: 20px;
  164 +}
  165 +.border-radius {
  166 + border-radius: 4px;
  167 +}
  168 +.text-right {
  169 + text-align: right;
  170 +}
  171 +</style>
0 172 \ No newline at end of file
... ...
src/components/owner/ownerDetailMemberDemo.vue 0 → 100644
  1 +<template>
  2 + <owner-detail-member ref="ownerDetailMember" />
  3 +</template>
  4 +
  5 +<script>
  6 +import OwnerDetailMember from './ownerDetailMember'
  7 +
  8 +export default {
  9 + components: {
  10 + OwnerDetailMember
  11 + },
  12 + methods: {
  13 + open(ownerId) {
  14 + this.$refs.ownerDetailMember.ownerDetailMemberInfo.ownerId = ownerId
  15 + this.$refs.ownerDetailMember._loadOwnerDetailMemberData(1, 10)
  16 + }
  17 + }
  18 +}
  19 +</script>
0 20 \ No newline at end of file
... ...
src/components/owner/ownerDetailReceipt.vue 0 → 100644
  1 +<template>
  2 + <div>
  3 + <el-row class="margin-top-lg">
  4 + <el-col :span="12"></el-col>
  5 + <el-col :span="12" class="text-right">
  6 + <el-button type="primary" size="small" @click="_printFeeReceipt" style="margin-left:10px">
  7 + {{$t('ownerDetailReceipt.print')}}
  8 + </el-button>
  9 + <el-button type="primary" size="small" @click="_printFeeSmallReceipt" style="margin-left:10px">
  10 + {{$t('ownerDetailReceipt.printSmall')}}
  11 + </el-button>
  12 + <el-button type="primary" size="small" @click="_printApplyFeeReceipt" style="margin-left:10px">
  13 + {{$t('ownerDetailReceipt.printApply')}}
  14 + </el-button>
  15 + </el-col>
  16 + </el-row>
  17 + <div class="margin-top">
  18 + <el-table
  19 + :data="ownerDetailReceiptInfo.feeReceipts"
  20 + style="width: 100%; margin-top: 10px"
  21 + border
  22 + stripe
  23 + >
  24 + <el-table-column width="50" align="center">
  25 + <template slot-scope="scope">
  26 + <el-checkbox
  27 + v-model="scope.row.checked"
  28 + @change="handleCheckChange(scope.row)"
  29 + ></el-checkbox>
  30 + </template>
  31 + </el-table-column>
  32 + <el-table-column prop="objName" :label="$t('ownerDetailReceipt.feeType')" align="center"></el-table-column>
  33 + <el-table-column prop="payObjName" :label="$t('ownerDetailReceipt.owner')" align="center"></el-table-column>
  34 + <el-table-column prop="feeName" :label="$t('ownerDetailReceipt.feeItem')" align="center"></el-table-column>
  35 + <el-table-column :label="$t('ownerDetailReceipt.chargePeriod')" align="center">
  36 + <template slot-scope="scope">
  37 + {{dateFormat(scope.row.startTime)}}~<br>
  38 + {{dateFormat(scope.row.endTime)}}
  39 + </template>
  40 + </el-table-column>
  41 + <el-table-column prop="amount" :label="$t('ownerDetailReceipt.totalAmount')" align="center"></el-table-column>
  42 + <el-table-column prop="createTime" :label="$t('ownerDetailReceipt.paymentTime')" align="center"></el-table-column>
  43 + <el-table-column prop="receiptId" :label="$t('ownerDetailReceipt.receiptId')" align="center"></el-table-column>
  44 + </el-table>
  45 + <el-pagination
  46 + @current-change="handleCurrentChange"
  47 + :current-page="currentPage"
  48 + :page-size="pageSize"
  49 + layout="total, prev, pager, next, jumper"
  50 + :total="total">
  51 + </el-pagination>
  52 + </div>
  53 + </div>
  54 +</template>
  55 +
  56 +<script>
  57 +import { queryFeeReceipt, listFeePrintPage } from '@/api/owner/ownerDetailReceiptApi'
  58 +import { getCommunityId } from '@/api/community/communityApi'
  59 +
  60 +export default {
  61 + name: 'OwnerDetailReceipt',
  62 + data() {
  63 + return {
  64 + ownerDetailReceiptInfo: {
  65 + feeReceipts: [],
  66 + payObjId: '',
  67 + total: 0,
  68 + records: 0,
  69 + selectReceipts: [],
  70 + printUrl: '/print.html#/pages/property/printPayFee'
  71 + },
  72 + currentPage: 1,
  73 + pageSize: 10,
  74 + total: 0,
  75 + communityId: ''
  76 + }
  77 + },
  78 + created() {
  79 + this.communityId = getCommunityId()
  80 + },
  81 + methods: {
  82 + open(ownerId) {
  83 + this.ownerDetailReceiptInfo.payObjId = ownerId
  84 + this._listFeePrintPages()
  85 + this._listOwnerDetailReceipt(this.currentPage, this.pageSize)
  86 + },
  87 + _listOwnerDetailReceipt(page, rows) {
  88 + this.ownerDetailReceiptInfo.selectReceipts = []
  89 + const param = {
  90 + page: page,
  91 + row: rows,
  92 + payObjId: this.ownerDetailReceiptInfo.payObjId,
  93 + communityId: this.communityId
  94 + }
  95 +
  96 + queryFeeReceipt(param).then(response => {
  97 + this.ownerDetailReceiptInfo.feeReceipts = response.data.data.map(item => {
  98 + return { ...item, checked: false }
  99 + })
  100 + this.total = response.data.total
  101 + }).catch(error => {
  102 + console.error('请求失败:', error)
  103 + })
  104 + },
  105 + _listFeePrintPages() {
  106 + const param = {
  107 + page: 1,
  108 + row: 1,
  109 + state: 'T',
  110 + communityId: this.communityId
  111 + }
  112 +
  113 + listFeePrintPage(param).then(response => {
  114 + const feePrintPages = response.data.data
  115 + if (feePrintPages && feePrintPages.length > 0) {
  116 + this.ownerDetailReceiptInfo.printUrl = feePrintPages[0].url
  117 + }
  118 + }).catch(error => {
  119 + console.error('请求失败:', error)
  120 + })
  121 + },
  122 + _printFeeReceipt() {
  123 + const selected = this.ownerDetailReceiptInfo.feeReceipts.filter(item => item.checked)
  124 + if (selected.length < 1) {
  125 + this.$message.warning(this.$t('ownerDetailReceipt.selectPrint'))
  126 + return
  127 + }
  128 + const receiptIds = selected.map(item => item.receiptId).join(',')
  129 + window.open(`${this.ownerDetailReceiptInfo.printUrl}?receiptIds=${receiptIds}&apply=N`)
  130 + },
  131 + _printApplyFeeReceipt() {
  132 + const selected = this.ownerDetailReceiptInfo.feeReceipts.filter(item => item.checked)
  133 + if (selected.length < 1) {
  134 + this.$message.warning(this.$t('ownerDetailReceipt.selectPrint'))
  135 + return
  136 + }
  137 + const receiptIds = selected.map(item => item.receiptId).join(',')
  138 + window.open(`/print.html#/pages/property/printPayFee?receiptIds=${receiptIds}&apply=Y`)
  139 + },
  140 + _printFeeSmallReceipt() {
  141 + const selected = this.ownerDetailReceiptInfo.feeReceipts.filter(item => item.checked)
  142 + if (selected.length < 1) {
  143 + this.$message.warning(this.$t('ownerDetailReceipt.selectPrint'))
  144 + return
  145 + }
  146 + const receiptIds = selected.map(item => item.receiptId).join(',')
  147 + window.open(`/smallPrint.html#/pages/property/printSmallPayFee?receiptIds=${receiptIds}`)
  148 + },
  149 + handleCheckChange(row) {
  150 + if (row.checked) {
  151 + this.ownerDetailReceiptInfo.selectReceipts.push(row.receiptId)
  152 + } else {
  153 + const index = this.ownerDetailReceiptInfo.selectReceipts.indexOf(row.receiptId)
  154 + if (index > -1) {
  155 + this.ownerDetailReceiptInfo.selectReceipts.splice(index, 1)
  156 + }
  157 + }
  158 + },
  159 + handleCurrentChange(val) {
  160 + this.currentPage = val
  161 + this._listOwnerDetailReceipt(val, this.pageSize)
  162 + },
  163 + dateFormat(date) {
  164 + // Implement your date formatting logic here
  165 + return date
  166 + }
  167 + }
  168 +}
  169 +</script>
0 170 \ No newline at end of file
... ...
src/components/owner/ownerDetailReceiptDemo.vue 0 → 100644
  1 +<template>
  2 + <owner-detail-receipt ref="ownerDetailReceipt" />
  3 +</template>
  4 +
  5 +<script>
  6 +import OwnerDetailReceipt from '@/components/owner/ownerDetailReceipt'
  7 +
  8 +export default {
  9 + components: {
  10 + OwnerDetailReceipt
  11 + },
  12 + methods: {
  13 + open(ownerId) {
  14 + this.$refs.ownerDetailReceipt.open(ownerId)
  15 + }
  16 + }
  17 +}
  18 +</script>
0 19 \ No newline at end of file
... ...
src/components/owner/ownerDetailRepair.vue 0 → 100644
  1 +<template>
  2 + <div class="margin-top">
  3 + <el-table :data="ownerDetailRepairInfo.repairs" style="width: 100%">
  4 + <el-table-column prop="repairId" :label="$t('ownerDetailRepair.repairId')" align="center"></el-table-column>
  5 + <el-table-column prop="repairObjName" :label="$t('ownerDetailRepair.location')" align="center"></el-table-column>
  6 + <el-table-column prop="repairTypeName" :label="$t('ownerDetailRepair.repairType')" align="center"></el-table-column>
  7 + <el-table-column prop="repairName" :label="$t('ownerDetailRepair.reporter')" align="center"></el-table-column>
  8 + <el-table-column prop="tel" :label="$t('ownerDetailRepair.contact')" align="center"></el-table-column>
  9 + <el-table-column prop="appointmentTime" :label="$t('ownerDetailRepair.appointmentTime')" align="center"></el-table-column>
  10 + <el-table-column prop="stateName" :label="$t('ownerDetailRepair.status')" align="center">
  11 + <template slot-scope="scope">
  12 + <span v-if="scope.row.state == '1800' && (scope.row.returnVisitFlag == '001' || scope.row.returnVisitFlag == '002')">
  13 + {{scope.row.stateName}}({{$t('ownerDetailRepair.taskProcess')}})
  14 + </span>
  15 + <span v-else>
  16 + {{scope.row.stateName}}
  17 + </span>
  18 + </template>
  19 + </el-table-column>
  20 + <el-table-column :label="$t('common.operation')" align="center" width="120">
  21 + <template slot-scope="scope">
  22 + <el-button size="mini" @click="_openRepairDetail(scope.row)">
  23 + {{ $t('common.detail') }}
  24 + </el-button>
  25 + </template>
  26 + </el-table-column>
  27 + </el-table>
  28 + <el-pagination
  29 + @current-change="handleCurrentChange"
  30 + :current-page="pagination.currentPage"
  31 + :page-size="pagination.pageSize"
  32 + :total="pagination.total"
  33 + layout="total, prev, pager, next, jumper">
  34 + </el-pagination>
  35 + </div>
  36 +</template>
  37 +
  38 +<script>
  39 +import { listOwnerRepairs } from '@/api/owner/ownerDetailRepairApi'
  40 +import { getCommunityId } from '@/api/community/communityApi'
  41 +
  42 +export default {
  43 + name: 'OwnerDetailRepair',
  44 + data() {
  45 + return {
  46 + ownerDetailRepairInfo: {
  47 + repairs: [],
  48 + ownerId: '',
  49 + },
  50 + pagination: {
  51 + currentPage: 1,
  52 + pageSize: 10,
  53 + total: 0
  54 + }
  55 + }
  56 + },
  57 + methods: {
  58 + _loadOwnerDetailRepairData(page, row) {
  59 + const params = {
  60 + communityId: getCommunityId(),
  61 + ownerId: this.ownerDetailRepairInfo.ownerId,
  62 + page: page,
  63 + row: row
  64 + }
  65 +
  66 + listOwnerRepairs(params).then(response => {
  67 + this.ownerDetailRepairInfo.repairs = response.data
  68 + this.pagination.total = response.records
  69 + }).catch(error => {
  70 + console.error('请求失败处理', error)
  71 + })
  72 + },
  73 + _openRepairDetail(repairPool) {
  74 + this.$router.push(`/property/ownerRepairDetail?repairId=${repairPool.repairId}`)
  75 + },
  76 + handleCurrentChange(val) {
  77 + this._loadOwnerDetailRepairData(val, this.pagination.pageSize)
  78 + }
  79 + },
  80 + created() {
  81 + this.$on('switch', (data) => {
  82 + this.ownerDetailRepairInfo.ownerId = data.ownerId
  83 + this._loadOwnerDetailRepairData(1, this.pagination.pageSize)
  84 + })
  85 + }
  86 +}
  87 +</script>
0 88 \ No newline at end of file
... ...
src/components/owner/ownerDetailRepairDemo.vue 0 → 100644
  1 +<template>
  2 + <owner-detail-repair ref="ownerDetailRepair" />
  3 +</template>
  4 +
  5 +<script>
  6 +import OwnerDetailRepair from './ownerDetailRepair'
  7 +
  8 +export default {
  9 + components: {
  10 + OwnerDetailRepair
  11 + },
  12 + methods: {
  13 + open(ownerId) {
  14 + this.$refs.ownerDetailRepair.ownerDetailRepairInfo.ownerId = ownerId
  15 + this.$refs.ownerDetailRepair._loadOwnerDetailRepairData(1, 10)
  16 + }
  17 + }
  18 +}
  19 +</script>
0 20 \ No newline at end of file
... ...
src/components/owner/ownerDetailRoom.vue 0 → 100644
  1 +<template>
  2 + <div class="margin-top">
  3 + <el-row class="margin-top-lg">
  4 + <el-col :span="4" class="padding-right-xs padding-left-xl">
  5 + <el-input v-model="ownerDetailRoomInfo.roomNum" :placeholder="$t('ownerDetailRoom.pleaseEnterRoomNumber')" />
  6 + </el-col>
  7 + <el-col :span="4" class="padding-right-xs padding-right-xl">
  8 + <el-button type="primary" size="small" @click="_qureyOwnerDetailRoom">
  9 + <i class="el-icon-search"></i>{{ $t('common.query') }}
  10 + </el-button>
  11 + <el-button type="primary" size="small" @click="_resetOwnerDetailRoom">
  12 + <i class="el-icon-refresh"></i>{{ $t('common.reset') }}
  13 + </el-button>
  14 + </el-col>
  15 + <el-col :span="16" class="text-right">
  16 + <el-button v-if="hasPrivilege('502023021978930012')" type="primary" size="small" @click="_openAddOwnerRoom">
  17 + <i class="el-icon-plus"></i>
  18 + {{ $t('ownerDetailRoom.deliverRoom') }}
  19 + </el-button>
  20 + </el-col>
  21 + </el-row>
  22 +
  23 + <div class="margin-top">
  24 + <el-table :data="ownerDetailRoomInfo.rooms" border style="width: 100%">
  25 + <el-table-column prop="roomNum" :label="$t('ownerDetailRoom.roomNumber')" align="center">
  26 + <template slot-scope="scope">
  27 + {{ scope.row.floorNum }}-{{ scope.row.unitNum }}-{{ scope.row.roomNum }}
  28 + </template>
  29 + </el-table-column>
  30 + <el-table-column prop="layer" :label="$t('ownerDetailRoom.floor')" align="center" />
  31 + <el-table-column prop="roomSubTypeName" :label="$t('ownerDetailRoom.type')" align="center" />
  32 + <el-table-column :label="$t('ownerDetailRoom.area')" align="center">
  33 + <template slot-scope="scope">
  34 + {{ scope.row.builtUpArea }}/{{ scope.row.roomArea }}
  35 + </template>
  36 + </el-table-column>
  37 + <el-table-column prop="roomRent" :label="$t('ownerDetailRoom.rent')" align="center" />
  38 + <el-table-column :label="$t('ownerDetailRoom.validity')" align="center">
  39 + <template slot-scope="scope">
  40 + {{ scope.row.startTime }}<br />~{{ scope.row.endTime }}
  41 + </template>
  42 + </el-table-column>
  43 + <el-table-column prop="stateName" :label="$t('ownerDetailRoom.roomStatus')" align="center" />
  44 + <el-table-column :label="$t('ownerDetailRoom.roomArrears')" align="center">
  45 + <template slot-scope="scope">
  46 + {{ scope.row.roomOweFee || '0.00' }}({{ $t('ownerDetailRoom.updateDaily') }})
  47 + </template>
  48 + </el-table-column>
  49 + <el-table-column :label="$t('common.operation')" align="center" width="250">
  50 + <template slot-scope="scope">
  51 + <el-button v-if="hasPrivilege('502020082493857941')" size="mini" @click="_openEditRoomModel(scope.row)">
  52 + {{ $t('common.edit') }}
  53 + </el-button>
  54 + <el-button v-if="hasPrivilege('502023021973760015')" size="mini" @click="ownerExitRoomModel(scope.row)">
  55 + {{ $t('ownerDetailRoom.checkOut') }}
  56 + </el-button>
  57 + <el-button v-if="scope.row.state != '2002'" size="mini" @click="_toSimplifyAcceptance(scope.row)">
  58 + {{ $t('ownerDetailRoom.businessAcceptance') }}
  59 + </el-button>
  60 + </template>
  61 + </el-table-column>
  62 + </el-table>
  63 +
  64 + <el-row class="margin-top">
  65 + <el-col :span="8">
  66 + <span>
  67 + {{ $t('ownerDetailRoom.arrearsSubtotal') }}:
  68 + {{ ownerDetailRoomInfo.allOweFeeAmount }}
  69 + </span>
  70 + </el-col>
  71 + <el-col :span="16" class="text-right">
  72 + <el-pagination @current-change="handleCurrentChange" :current-page="pagination.currentPage"
  73 + :page-size="pagination.pageSize" :total="pagination.total" layout="total, prev, pager, next, jumper" />
  74 + </el-col>
  75 + </el-row>
  76 + </div>
  77 +
  78 + <edit-room ref="editRoom" @refresh="_loadOwnerDetailRoomData" />
  79 + <owner-exit-room ref="ownerExitRoom" @refresh="_loadOwnerDetailRoomData" />
  80 + </div>
  81 +</template>
  82 +
  83 +<script>
  84 +import EditRoom from '@/components/room/editRoom'
  85 +import { queryRoomsByOwner } from '@/api/owner/ownerDetailRoomApi'
  86 +
  87 +import OwnerExitRoom from '@/components/owner/ownerExitRoom'
  88 +import { getCommunityId } from '@/api/community/communityApi'
  89 +
  90 +
  91 +export default {
  92 + name: 'OwnerDetailRoom',
  93 + components: {
  94 + EditRoom,
  95 + OwnerExitRoom
  96 + },
  97 + data() {
  98 + return {
  99 + ownerDetailRoomInfo: {
  100 + rooms: [],
  101 + ownerId: '',
  102 + roomNum: '',
  103 + allOweFeeAmount: '0'
  104 + },
  105 + pagination: {
  106 + currentPage: 1,
  107 + pageSize: 10,
  108 + total: 0
  109 + }
  110 + }
  111 + },
  112 + methods: {
  113 + open(ownerId, ownerName, ownerLink) {
  114 + this.ownerDetailRoomInfo.ownerId = ownerId
  115 + this.ownerDetailRoomInfo.ownerName = ownerName
  116 + this.ownerDetailRoomInfo.ownerLink = ownerLink
  117 + this._loadOwnerDetailRoomData()
  118 + },
  119 + async _loadOwnerDetailRoomData() {
  120 + try {
  121 + const params = {
  122 + communityId: getCommunityId(),
  123 + ownerId: this.ownerDetailRoomInfo.ownerId,
  124 + roomNum: this.ownerDetailRoomInfo.roomNum,
  125 + page: this.pagination.currentPage,
  126 + row: this.pagination.pageSize
  127 + }
  128 +
  129 + const response = await queryRoomsByOwner(params)
  130 + this.ownerDetailRoomInfo.rooms = response.data.rooms
  131 + this.pagination.total = response.data.total
  132 + this._computeOwnerRoomOweFeeAmount()
  133 + } catch (error) {
  134 + console.error('Failed to load owner room data:', error)
  135 + }
  136 + },
  137 + _qureyOwnerDetailRoom() {
  138 + this.pagination.currentPage = 1
  139 + this._loadOwnerDetailRoomData()
  140 + },
  141 + _resetOwnerDetailRoom() {
  142 + this.ownerDetailRoomInfo.roomNum = ''
  143 + this._qureyOwnerDetailRoom()
  144 + },
  145 + _computeOwnerRoomOweFeeAmount() {
  146 + const rooms = this.ownerDetailRoomInfo.rooms
  147 + let totalOweFeeAmount = 0
  148 + this.ownerDetailRoomInfo.allOweFeeAmount = 0
  149 +
  150 + if (!rooms || rooms.length < 1) return
  151 +
  152 + rooms.forEach(room => {
  153 + if (room.roomOweFee) {
  154 + totalOweFeeAmount += parseFloat(room.roomOweFee)
  155 + }
  156 + })
  157 +
  158 + this.ownerDetailRoomInfo.allOweFeeAmount = totalOweFeeAmount.toFixed(2)
  159 + },
  160 + _openAddOwnerRoom() {
  161 + this.$router.push({
  162 + path: '/property/addOwnerRoomBinding',
  163 + query: { ownerId: this.ownerDetailRoomInfo.ownerId }
  164 + })
  165 + },
  166 + ownerExitRoomModel(room) {
  167 + this.$refs.ownerExitRoom.open({
  168 + ownerId: this.ownerDetailRoomInfo.ownerId,
  169 + roomId: room.roomId
  170 + })
  171 + },
  172 + _toSimplifyAcceptance(room) {
  173 + const date = new Date()
  174 + this.$store.dispatch('app/saveData', {
  175 + key: 'JAVA110_IS_BACK',
  176 + value: date.getTime()
  177 + })
  178 + this.$store.dispatch('app/saveData', {
  179 + key: 'simplifyAcceptanceSearch',
  180 + value: {
  181 + searchType: '1',
  182 + searchValue: `${room.floorNum}-${room.unitNum}-${room.roomNum}`,
  183 + searchPlaceholder: this.$t('ownerDetailRoom.roomNumberPlaceholder')
  184 + }
  185 + })
  186 + this.$router.push('/property/simplifyAcceptance?tab=businessAcceptance')
  187 + },
  188 + _openEditRoomModel(room) {
  189 + this.$refs.editRoom.open(room)
  190 + },
  191 + handleCurrentChange(currentPage) {
  192 + this.pagination.currentPage = currentPage
  193 + this._loadOwnerDetailRoomData()
  194 + },
  195 + }
  196 +}
  197 +</script>
  198 +
  199 +<style scoped>
  200 +.margin-top {
  201 + margin-top: 20px;
  202 +}
  203 +
  204 +.margin-top-lg {
  205 + margin-top: 30px;
  206 +}
  207 +
  208 +.padding-right-xs {
  209 + padding-right: 5px;
  210 +}
  211 +
  212 +.padding-left-xl {
  213 + padding-left: 20px;
  214 +}
  215 +
  216 +.text-right {
  217 + text-align: right;
  218 +}
  219 +</style>
0 220 \ No newline at end of file
... ...
src/components/owner/ownerDetailRoomDemo.vue 0 → 100644
  1 +<template>
  2 + <owner-detail-room ref="ownerDetailRoom" />
  3 +</template>
  4 +
  5 +<script>
  6 +import OwnerDetailRoom from '@/components/owner/ownerDetailRoom'
  7 +
  8 +export default {
  9 + components: {
  10 + OwnerDetailRoom
  11 + },
  12 + methods: {
  13 + open(ownerId) {
  14 + this.$refs.ownerDetailRoom.ownerDetailRoomInfo.ownerId = ownerId
  15 + this.$refs.ownerDetailRoom._loadOwnerDetailRoomData(1, 10)
  16 + }
  17 + }
  18 +}
  19 +</script>
0 20 \ No newline at end of file
... ...
src/components/owner/ownerDetailRoomFee.vue 0 → 100644
  1 +<template>
  2 + <div class="margin-top">
  3 + <el-row class="margin-top-lg">
  4 + <el-col :span="12" class="padding-right-xs padding-left-xl">
  5 + <span class="margin-right" v-for="(item, index) in ownerDetailRoomFeeInfo.payObjs" :key="index">
  6 + <el-checkbox class="checkRoomItem" v-model="ownerDetailRoomFeeInfo.payerObjIds" :label="item.roomId"
  7 + @change="_chanagePayerObjId()">
  8 + {{ item.floorNum }}-{{ item.unitNum }}-{{ item.roomNum }}
  9 + </el-checkbox>
  10 + </span>
  11 + </el-col>
  12 + <el-col :span="3" class="padding-lr-xs">
  13 + <el-select v-model="ownerDetailRoomFeeInfo.state" @change="_changeContractConfigId()" size="small"
  14 + :placeholder="$t('ownerDetailRoomFee.selectStatus')">
  15 + <el-option :label="$t('ownerDetailRoomFee.valid')" value="2008001"></el-option>
  16 + <el-option :label="$t('ownerDetailRoomFee.feeEnd')" value="2009001"></el-option>
  17 + </el-select>
  18 + </el-col>
  19 + <el-col :span="9" class="text-right">
  20 + <el-button type="primary" size="small" style="margin-left:10px" v-if="hasPrivilege('502020082314267912')"
  21 + @click="_openBatchPayRoomFeeModal()">
  22 + {{ $t('ownerDetailRoomFee.batchPay') }}
  23 + </el-button>
  24 + <el-button type="primary" size="small" style="margin-left:10px" v-if="hasPrivilege('502022073007100003')"
  25 + @click="_openTempImportRoomFeeModal()">
  26 + {{ $t('ownerDetailRoomFee.tempFee') }}
  27 + </el-button>
  28 + <el-button type="primary" size="small" style="margin-left:10px" v-if="hasPrivilege('502022073049300004')"
  29 + @click="_openProxyFeeModal()">
  30 + {{ $t('ownerDetailRoomFee.quantityPay') }}
  31 + </el-button>
  32 + <el-button type="primary" size="small" style="margin-left:10px" v-if="hasPrivilege('502022073096990007')"
  33 + @click="_openRoomsCreateFeeModal()">
  34 + {{ $t('ownerDetailRoomFee.createFee') }}
  35 + </el-button>
  36 + <el-button type="primary" size="small" style="margin-left:10px" v-if="hasPrivilege('502020080570210194')"
  37 + @click="_toRoomOwePayFee()">
  38 + {{ $t('ownerDetailRoomFee.owePay') }}
  39 + </el-button>
  40 + <el-button type="default" size="small" style="margin-left:10px" @click="_printOwnOrder()">
  41 + {{ $t('ownerDetailRoomFee.reminder') }}
  42 + </el-button>
  43 + </el-col>
  44 + </el-row>
  45 + <div class="margin-top">
  46 + <el-table :data="ownerDetailRoomFeeInfo.fees" style="width: 100%">
  47 + <el-table-column prop="payerObjName" :label="$t('ownerDetailRoomFee.room')" align="center"></el-table-column>
  48 + <el-table-column prop="feeName" :label="$t('ownerDetailRoomFee.feeItem')" align="center"></el-table-column>
  49 + <el-table-column prop="feeFlagName" :label="$t('ownerDetailRoomFee.feeFlag')" align="center"></el-table-column>
  50 + <el-table-column prop="feeTypeCdName" :label="$t('ownerDetailRoomFee.feeType')"
  51 + align="center"></el-table-column>
  52 + <el-table-column prop="amountOwed" :label="$t('ownerDetailRoomFee.amount')" align="center"></el-table-column>
  53 + <el-table-column prop="startTime" :label="$t('ownerDetailRoomFee.createTime')" align="center"></el-table-column>
  54 + <el-table-column :label="$t('ownerDetailRoomFee.timeRange')" align="center">
  55 + <template slot-scope="scope">
  56 + {{ _getRoomEndTime(scope.row) }}~<br>{{ _getRoomDeadlineTime(scope.row) }}
  57 + </template>
  58 + </el-table-column>
  59 + <el-table-column :label="$t('ownerDetailRoomFee.remark')" align="center" width="150">
  60 + <template slot-scope="scope">
  61 + <div v-if="scope.row.computingFormula == '5005' || scope.row.computingFormula == '9009'">
  62 + <div><span>{{ $t('ownerDetailRoomFee.lastDegree') }}</span>{{ scope.row.preDegrees }}</div>
  63 + <div><span>{{ $t('ownerDetailRoomFee.currentDegree') }}</span>{{ scope.row.curDegrees }}</div>
  64 + <div><span>{{ $t('ownerDetailRoomFee.unitPrice')
  65 + }}</span>{{ scope.row.mwPrice ? scope.row.mwPrice : scope.row.squarePrice }}</div>
  66 + <div><span>{{ $t('ownerDetailRoomFee.additionalFee') }}</span>{{ scope.row.additionalAmount }}</div>
  67 + </div>
  68 + <div v-else-if="scope.row.computingFormula == '6006'">
  69 + <div><span>{{ $t('ownerDetailRoomFee.usage') }}</span>{{ _getRoomAttrValue(scope.row.feeAttrs, '390006') }}
  70 + </div>
  71 + <div><span>{{ $t('ownerDetailRoomFee.unitPrice') }}</span>{{ scope.row.squarePrice }}</div>
  72 + <div><span>{{ $t('ownerDetailRoomFee.additionalFee') }}</span>{{ scope.row.additionalAmount }}</div>
  73 + </div>
  74 + <div v-else-if="scope.row.feeTypeCd == '888800010017'" width="150">
  75 + <div><span>{{ $t('ownerDetailRoomFee.algorithm')
  76 + }}</span>{{ _getRoomAttrValue(scope.row.feeAttrs, '390005') }}</div>
  77 + <div><span>{{ $t('ownerDetailRoomFee.usage') }}</span>{{ _getRoomAttrValue(scope.row.feeAttrs, '390003') }}
  78 + </div>
  79 + </div>
  80 + <div v-else-if="scope.row.computingFormula == '4004'">
  81 + <div>{{ $t('ownerDetailRoomFee.feeByActual') }}</div>
  82 + </div>
  83 + <div v-else>
  84 + <div><span>{{ $t('ownerDetailRoomFee.unitPrice') }}</span>{{ scope.row.squarePrice }}</div>
  85 + <div v-if="scope.row.feeFlag == '1003006'"><span>{{ $t('ownerDetailRoomFee.additionalFee')
  86 + }}</span>{{ scope.row.additionalAmount }}</div>
  87 + <div v-else><span>{{ $t('ownerDetailRoomFee.fixedFee') }}</span>{{ scope.row.additionalAmount }}</div>
  88 + </div>
  89 + </template>
  90 + </el-table-column>
  91 + <el-table-column prop="stateName" :label="$t('ownerDetailRoomFee.status')" align="center"></el-table-column>
  92 + <el-table-column :label="$t('common.operation')" align="center" width="300">
  93 + <template slot-scope="scope">
  94 + <el-button-group>
  95 + <el-button type="text" size="mini"
  96 + v-if="scope.row.state != '2009001' && hasPrivilege('502020082314267912')"
  97 + @click="_payRoomFee(scope.row)">
  98 + {{ $t('ownerDetailRoomFee.pay') }}
  99 + </el-button>
  100 + <el-button type="text" size="mini" @click="_payRoomFeeHis(scope.row)">
  101 + {{ $t('ownerDetailRoomFee.payHistory') }}
  102 + </el-button>
  103 + <el-button type="text" size="mini" v-if="hasPrivilege('502020090604200029')"
  104 + @click="_deleteRoomFee(scope.row)">
  105 + {{ $t('ownerDetailRoomFee.cancel') }}
  106 + </el-button>
  107 + <el-button type="text" size="mini"
  108 + v-if="scope.row.state != '2009001' && hasPrivilege('502021070488970005')"
  109 + @click="_finishRoomFee(scope.row)">
  110 + {{ $t('ownerDetailRoomFee.end') }}
  111 + </el-button>
  112 + <el-button type="text" size="mini"
  113 + v-if="scope.row.state != '2009001' && hasPrivilege('502020090427190001')"
  114 + @click="_editRoomFee(scope.row)">
  115 + {{ $t('ownerDetailRoomFee.change') }}
  116 + </el-button>
  117 + </el-button-group>
  118 + </template>
  119 + </el-table-column>
  120 + </el-table>
  121 + <el-row>
  122 + <el-col :span="12">
  123 + <div>{{ $t('ownerDetailRoomFee.note1') }}</div>
  124 + <div>{{ $t('ownerDetailRoomFee.note2') }}</div>
  125 + </el-col>
  126 + <el-col :span="4">
  127 + <span>{{ $t('ownerDetailRoomFee.oweSubtotal') }}</span>
  128 + {{ ownerDetailRoomFeeInfo.totalAmount }}
  129 + </el-col>
  130 + <el-col :span="8">
  131 + <el-pagination @current-change="handleCurrentChange" :current-page="pagination.currentPage"
  132 + :page-size="pagination.pageSize" :total="pagination.total" layout="total, prev, pager, next, jumper">
  133 + </el-pagination>
  134 + </el-col>
  135 + </el-row>
  136 + </div>
  137 +
  138 + <rooms-import-temp-fee ref="roomsImportTempFee"></rooms-import-temp-fee>
  139 + <rooms-create-fee ref="roomsCreateFee"></rooms-create-fee>
  140 + <rooms-proxy-fee ref="roomsProxyFee"></rooms-proxy-fee>
  141 + </div>
  142 +</template>
  143 +
  144 +<script>
  145 +import RoomsImportTempFee from '@/components/fee/roomsImportTempFee'
  146 +import RoomsCreateFee from '@/components/fee/roomsCreateFee'
  147 +import RoomsProxyFee from '@/components/fee/roomsProxyFee'
  148 +import { listFee, listRoomsByOwner } from '@/api/owner/ownerDetailRoomFeeApi'
  149 +import { getCommunityId } from '@/api/community/communityApi'
  150 +
  151 +export default {
  152 + name: 'OwnerDetailRoomFee',
  153 + components: {
  154 + RoomsImportTempFee,
  155 + RoomsCreateFee,
  156 + RoomsProxyFee
  157 + },
  158 + data() {
  159 + return {
  160 + ownerDetailRoomFeeInfo: {
  161 + fees: [],
  162 + payObjs: [],
  163 + payerObjIds: [],
  164 + ownerId: '',
  165 + state: '2008001',
  166 + totalAmount: 0,
  167 + },
  168 + pagination: {
  169 + currentPage: 1,
  170 + pageSize: 10,
  171 + total: 0
  172 + }
  173 + }
  174 + },
  175 + methods: {
  176 + _loadOwnerDetailRoomFeeData(page, row) {
  177 + const _payerObjIds = this.ownerDetailRoomFeeInfo.payerObjIds.join(',')
  178 + const params = {
  179 + page: page,
  180 + row: row,
  181 + communityId: getCommunityId(),
  182 + payerObjIds: _payerObjIds,
  183 + state: this.ownerDetailRoomFeeInfo.state
  184 + }
  185 +
  186 + listFee(params).then(response => {
  187 + this.ownerDetailRoomFeeInfo.fees = response.fees
  188 + this.pagination.total = response.records
  189 + let _totalAmount = 0.0
  190 + response.fees.forEach(item => {
  191 + _totalAmount += parseFloat(item.amountOwed)
  192 + })
  193 + this.ownerDetailRoomFeeInfo.totalAmount = _totalAmount.toFixed(2)
  194 + }).catch(error => {
  195 + console.error('请求失败处理', error)
  196 + })
  197 + },
  198 + _loadDetailRoomsData() {
  199 + const params = {
  200 + communityId: getCommunityId(),
  201 + ownerId: this.ownerDetailRoomFeeInfo.ownerId,
  202 + page: 1,
  203 + row: 100
  204 + }
  205 +
  206 + this.ownerDetailRoomFeeInfo.payerObjIds = []
  207 + listRoomsByOwner(params).then(response => {
  208 + this.ownerDetailRoomFeeInfo.payObjs = response.rooms
  209 + response.rooms.forEach(room => {
  210 + this.ownerDetailRoomFeeInfo.payerObjIds.push(room.roomId)
  211 + })
  212 + this._loadOwnerDetailRoomFeeData(1, this.pagination.pageSize)
  213 + }).catch(error => {
  214 + console.error('请求失败处理', error)
  215 + })
  216 + },
  217 + _openTempImportRoomFeeModal() {
  218 + this.$refs.roomsImportTempFee.open({
  219 + ownerId: this.ownerDetailRoomFeeInfo.ownerId,
  220 + ownerName: this.ownerDetailRoomFeeInfo.ownerName
  221 + })
  222 + },
  223 + _payRoomFee(fee) {
  224 + this.$router.push(`/property/payFeeOrder?feeId=${fee.feeId}`)
  225 + },
  226 + _editRoomFee(fee) {
  227 + this.$emit('editFee', fee)
  228 + },
  229 + _payRoomFeeHis(fee) {
  230 + this.$router.push(`/property/propertyFee?${this.objToGetParam(fee)}`)
  231 + },
  232 + _deleteRoomFee(fee) {
  233 + this.$emit('deleteFee', {
  234 + communityId: getCommunityId(),
  235 + feeId: fee.feeId
  236 + })
  237 + },
  238 + _finishRoomFee(fee) {
  239 + this.$emit('finishFee', {
  240 + communityId: getCommunityId(),
  241 + feeId: fee.feeId
  242 + })
  243 + },
  244 + _toRoomOwePayFee() {
  245 + const _ids = this.ownerDetailRoomFeeInfo.payerObjIds
  246 + if (!_ids || _ids.length < 1) {
  247 + this.$message.warning(this.$t('ownerDetailRoomFee.selectRoom'))
  248 + return
  249 + }
  250 + this.$router.push(`/property/owePayFeeOrder?payObjId=${_ids.join(',')}&payObjType=3333&roomName=`)
  251 + },
  252 + _printOwnOrder() {
  253 + const _ids = this.ownerDetailRoomFeeInfo.payerObjIds
  254 + if (!_ids || _ids.length < 1) {
  255 + this.$message.warning(this.$t('ownerDetailRoomFee.selectRoom'))
  256 + return
  257 + }
  258 + window.open(`/print.html#/pages/property/printOweFee?payObjId=${_ids.join(',')}&payObjType=3333&payObjName=`)
  259 + },
  260 + _openRoomsCreateFeeModal() {
  261 + this.$refs.roomsCreateFee.open({
  262 + ownerId: this.ownerDetailRoomFeeInfo.ownerId,
  263 + ownerName: this.ownerDetailRoomFeeInfo.ownerName
  264 + })
  265 + },
  266 + _getRoomAttrValue(attrs, specCd) {
  267 + let _value = ""
  268 + attrs.forEach(item => {
  269 + if (item.specCd == specCd) {
  270 + _value = item.value
  271 + return
  272 + }
  273 + })
  274 + return _value
  275 + },
  276 + _getRoomDeadlineTime(fee) {
  277 + if (fee.amountOwed == 0 && fee.endTime == fee.deadlineTime) {
  278 + return "-"
  279 + }
  280 + if (fee.state == '2009001') {
  281 + return "-"
  282 + }
  283 + return this.$options.filters.dateFormat(fee.deadlineTime)
  284 + },
  285 + _getRoomEndTime(fee) {
  286 + if (fee.state == '2009001') {
  287 + return "-"
  288 + }
  289 + return this.$options.filters.dateFormat(fee.endTime)
  290 + },
  291 + _chanagePayerObjId() {
  292 + this._loadOwnerDetailRoomFeeData(1, this.pagination.pageSize)
  293 + },
  294 + _changeContractConfigId() {
  295 + this._loadOwnerDetailRoomFeeData(1, this.pagination.pageSize)
  296 + },
  297 + _openBatchPayRoomFeeModal() {
  298 + this.$router.push(`/property/batchPayFeeOrder?ownerId=${this.ownerDetailRoomFeeInfo.ownerId}&payerObjType=3333`)
  299 + },
  300 + _openProxyFeeModal() {
  301 + this.$refs.roomsProxyFee.open({
  302 + ownerId: this.ownerDetailRoomFeeInfo.ownerId,
  303 + ownerName: this.ownerDetailRoomFeeInfo.ownerName
  304 + })
  305 + },
  306 + handleCurrentChange(val) {
  307 + this._loadOwnerDetailRoomFeeData(val, this.pagination.pageSize)
  308 + },
  309 +
  310 + objToGetParam(obj) {
  311 + return Object.keys(obj).map(key => `${key}=${obj[key]}`).join('&')
  312 + }
  313 + },
  314 + created() {
  315 + this.$on('switch', (data) => {
  316 + this.ownerDetailRoomFeeInfo.ownerId = data.ownerId
  317 + this._loadDetailRoomsData()
  318 + })
  319 + }
  320 +}
  321 +</script>
0 322 \ No newline at end of file
... ...
src/components/owner/ownerDetailRoomLang.js 0 → 100644
  1 +export default {
  2 + en: {
  3 + ownerDetailRoom: {
  4 + placeholder: {
  5 + roomNum: 'Please enter room number',
  6 + searchRoom: 'Please enter room number like 1-1-1'
  7 + },
  8 + table: {
  9 + roomNum: 'Room Number',
  10 + floor: 'Floor',
  11 + type: 'Type',
  12 + area: 'Built/Indoor Area',
  13 + rent: 'Rent',
  14 + validity: 'Validity',
  15 + state: 'Room Status',
  16 + oweFee: 'Room Arrears',
  17 + updateDaily: 'Update daily',
  18 + exitRoom: 'Check Out',
  19 + businessAcceptance: 'Business Acceptance',
  20 + oweSubtotal: 'Arrears Subtotal'
  21 + }
  22 + }
  23 + },
  24 + zh: {
  25 + ownerDetailRoom: {
  26 + placeholder: {
  27 + roomNum: '请填写房屋编号',
  28 + searchRoom: '请输入房屋编号 楼栋-单元-房屋 如1-1-1'
  29 + },
  30 + table: {
  31 + roomNum: '房屋编号',
  32 + floor: '楼层',
  33 + type: '类型',
  34 + area: '建筑/室内面积',
  35 + rent: '租金',
  36 + validity: '有效期',
  37 + state: '房屋状态',
  38 + oweFee: '房屋欠费',
  39 + updateDaily: '按天更新',
  40 + exitRoom: '退房',
  41 + businessAcceptance: '业务受理',
  42 + oweSubtotal: '欠费小计'
  43 + }
  44 + }
  45 + }
  46 +}
0 47 \ No newline at end of file
... ...
src/components/owner/ownerDetailVisit.vue 0 → 100644
  1 +<template>
  2 + <div class="margin-top">
  3 + <el-table :data="ownerDetailVisitInfo.visits" style="width: 100%">
  4 + <el-table-column prop="vId" :label="$t('visitManage.table.visitId')" align="center"></el-table-column>
  5 + <el-table-column :label="$t('visitManage.table.photo')" align="center">
  6 + <template slot-scope="scope">
  7 + <div style="position: relative; display: inline-block;"
  8 + @click="showVisitImg(scope.row.url?scope.row.url:'/img/noPhoto.jpg')">
  9 + <img width="50" height="50" :src="scope.row.url?scope.row.url:'/img/noPhoto.jpg'"
  10 + onerror="this.src='/img/noPhoto.jpg';">
  11 + <img src="/img/icon-bigimg.png" style="position: absolute;right: 0;bottom: 0;" width="50"
  12 + height="50" alt="">
  13 + </div>
  14 + </template>
  15 + </el-table-column>
  16 + <el-table-column :label="$t('visitManage.table.name')" align="center">
  17 + <template slot-scope="scope">
  18 + {{scope.row.vName}}({{scope.row.phoneNumber}})/{{scope.row.visitGender=='0'?$t('common.male'):$t('common.female')}}
  19 + </template>
  20 + </el-table-column>
  21 + <el-table-column prop="ownerName" :label="$t('visitManage.table.ownerName')" align="center"></el-table-column>
  22 + <el-table-column :label="$t('visitManage.table.visitCase')" align="center">
  23 + <template slot-scope="scope">
  24 + {{scope.row.visitCase}}({{scope.row.reasonTypeName}})
  25 + </template>
  26 + </el-table-column>
  27 + <el-table-column :label="$t('visitManage.table.carNum')" align="center">
  28 + <template slot-scope="scope">
  29 + <span v-if="scope.row.carState == '1' && scope.row.psId != null && scope.row.psId != '' && scope.row.psId != undefined">
  30 + {{scope.row.carNum}}<br />({{scope.row.parkAreaNum}}{{$t('visitManage.table.parkingLot')}}-{{scope.row.parkingSpaceNum}}{{$t('visitManage.table.parkingSpace')}})
  31 + </span>
  32 + <span v-else>{{scope.row.carNum}}</span>
  33 + </template>
  34 + </el-table-column>
  35 + <el-table-column prop="entourage" :label="$t('visitManage.table.entourage')" align="center"></el-table-column>
  36 + <el-table-column prop="createTime" :label="$t('visitManage.table.createTime')" align="center"></el-table-column>
  37 + <el-table-column :label="$t('visitManage.table.visitTime')" align="center">
  38 + <template slot-scope="scope">
  39 + {{scope.row.visitTime}}<br />{{scope.row.departureTime}}
  40 + </template>
  41 + </el-table-column>
  42 + <el-table-column prop="stateName" :label="$t('visitManage.table.state')" align="center"></el-table-column>
  43 + <el-table-column prop="carStateName" :label="$t('visitManage.table.carStatus')" align="center"></el-table-column>
  44 + <el-table-column :label="$t('common.operation')" align="center" width="300">
  45 + <template slot-scope="scope">
  46 + <el-button-group>
  47 + <el-button size="mini" @click="_openVisitDetail(scope.row)">
  48 + {{ $t('common.detail') }}
  49 + </el-button>
  50 + <el-button size="mini" v-if="scope.row.state != '1' && scope.row.state != '2'"
  51 + @click="_openEditVisitModel(scope.row)">
  52 + {{ $t('common.edit') }}
  53 + </el-button>
  54 + <el-button size="mini" v-if="scope.row.carNum != '' && scope.row.carState == '0'"
  55 + @click="_openExamineVisitCarModel(scope.row)">
  56 + {{ $t('common.audit') }}
  57 + </el-button>
  58 + <el-button size="mini" @click="_openDeleteVisitModel(scope.row)">
  59 + {{ $t('common.delete') }}
  60 + </el-button>
  61 + </el-button-group>
  62 + </template>
  63 + </el-table-column>
  64 + </el-table>
  65 + <el-pagination
  66 + @current-change="handleCurrentChange"
  67 + :current-page="pagination.currentPage"
  68 + :page-size="pagination.pageSize"
  69 + :total="pagination.total"
  70 + layout="total, prev, pager, next, jumper">
  71 + </el-pagination>
  72 +
  73 + <edit-visit ref="editVisit" @refresh="_loadOwnerDetailVisitData"></edit-visit>
  74 + <examine-visit-car ref="examineVisitCar" @refresh="_loadOwnerDetailVisitData"></examine-visit-car>
  75 + <delete-visit ref="deleteVisit" @refresh="_loadOwnerDetailVisitData"></delete-visit>
  76 + <view-image ref="viewImage"></view-image>
  77 + </div>
  78 +</template>
  79 +
  80 +<script>
  81 +//import EditVisit from '@/components/oa/editVisit'
  82 +//import ExamineVisitCar from '@/components/oa/examineVisitCar'
  83 +//import DeleteVisit from '@/components/oa/deleteVisit'
  84 +import ViewImage from '@/components/system/viewImage'
  85 +import { listVisits } from '@/api/owner/ownerDetailVisitApi'
  86 +import { getCommunityId } from '@/api/community/communityApi'
  87 +
  88 +export default {
  89 + name: 'OwnerDetailVisit',
  90 + components: {
  91 + //EditVisit,
  92 + //ExamineVisitCar,
  93 + //DeleteVisit,
  94 + ViewImage
  95 + },
  96 + data() {
  97 + return {
  98 + ownerDetailVisitInfo: {
  99 + visits: [],
  100 + ownerId: '',
  101 + link: '',
  102 + },
  103 + pagination: {
  104 + currentPage: 1,
  105 + pageSize: 10,
  106 + total: 0
  107 + }
  108 + }
  109 + },
  110 + methods: {
  111 + _loadOwnerDetailVisitData(page, row) {
  112 + const params = {
  113 + page: page,
  114 + row: row,
  115 + communityId: getCommunityId(),
  116 + ownerTel: this.ownerDetailVisitInfo.link,
  117 + channel: 'PC'
  118 + }
  119 +
  120 + listVisits(params).then(response => {
  121 + this.ownerDetailVisitInfo.visits = response.visits
  122 + this.pagination.total = response.records
  123 + }).catch(error => {
  124 + console.error('请求失败处理', error)
  125 + })
  126 + },
  127 + showVisitImg(url) {
  128 + this.$refs.viewImage.open(url || '/img/noPhoto.jpg')
  129 + },
  130 + _openVisitDetail(item) {
  131 + const flowId = item.flowId || ''
  132 + this.$router.push(`/property/visitDetail?vId=${item.vId}&flowId=${flowId}`)
  133 + },
  134 + _openEditVisitModel(visit) {
  135 + this.$refs.editVisit.open(visit)
  136 + },
  137 + _openExamineVisitCarModel(visit) {
  138 + this.$refs.examineVisitCar.open(visit)
  139 + },
  140 + _openDeleteVisitModel(visit) {
  141 + this.$refs.deleteVisit.open(visit)
  142 + },
  143 + handleCurrentChange(val) {
  144 + this._loadOwnerDetailVisitData(val, this.pagination.pageSize)
  145 + }
  146 + },
  147 + created() {
  148 + this.$on('switch', (data) => {
  149 + this.ownerDetailVisitInfo.ownerId = data.ownerId
  150 + this.ownerDetailVisitInfo.link = data.link
  151 + this._loadOwnerDetailVisitData(1, this.pagination.pageSize)
  152 + })
  153 + }
  154 +}
  155 +</script>
0 156 \ No newline at end of file
... ...
src/components/system/ownerDetailHis.vue deleted
1   -<template>
2   - <div class="owner-detail-his">
3   - <el-table
4   - :data="ownerDetailHisInfo.owners"
5   - border
6   - style="width: 100%"
7   - v-loading="loading">
8   - <el-table-column
9   - :label="$t('ownerDetailHis.operate')"
10   - align="center">
11   - <template slot-scope="scope">
12   - {{ _getHisOwnerOperate(scope.row) }}
13   - </template>
14   - </el-table-column>
15   - <el-table-column
16   - :label="$t('ownerDetailHis.userName')"
17   - align="center">
18   - <template slot-scope="scope">
19   - {{ scope.row.userName || '-' }}
20   - </template>
21   - </el-table-column>
22   - <el-table-column
23   - :label="$t('ownerDetailHis.createTime')"
24   - align="center">
25   - <template slot-scope="scope">
26   - {{ scope.row.createTime }}
27   - </template>
28   - </el-table-column>
29   - <el-table-column
30   - :label="$t('ownerDetailHis.name')"
31   - align="center">
32   - <template slot-scope="scope">
33   - {{ scope.row.name }}({{ scope.row.link }})
34   - </template>
35   - </el-table-column>
36   - <el-table-column
37   - :label="$t('ownerDetailHis.sex')"
38   - align="center">
39   - <template slot-scope="scope">
40   - {{ scope.row.sex === 0 ? $t('ownerDetailHis.male') : $t('ownerDetailHis.female') }}
41   - </template>
42   - </el-table-column>
43   - <el-table-column
44   - :label="$t('ownerDetailHis.idCard')"
45   - align="center">
46   - <template slot-scope="scope">
47   - {{ scope.row.idCard || '-' }}
48   - </template>
49   - </el-table-column>
50   - <el-table-column
51   - :label="$t('ownerDetailHis.address')"
52   - align="center">
53   - <template slot-scope="scope">
54   - {{ scope.row.address || '-' }}
55   - </template>
56   - </el-table-column>
57   - <el-table-column
58   - v-for="(item,index) in ownerDetailHisInfo.listColumns"
59   - :key="index"
60   - :label="item"
61   - align="center">
62   - <template slot-scope="scope">
63   - {{ scope.row.listValues[index] || '-' }}
64   - </template>
65   - </el-table-column>
66   - </el-table>
67   -
68   - <el-pagination
69   - @size-change="handleSizeChange"
70   - @current-change="handleCurrentChange"
71   - :current-page="page.current"
72   - :page-sizes="[10, 20, 30, 50]"
73   - :page-size="page.size"
74   - layout="total, sizes, prev, pager, next, jumper"
75   - :total="page.total">
76   - </el-pagination>
77   - </div>
78   -</template>
79   -
80   -<script>
81   -import { queryHisOwner, getAttrSpec } from '@/api/system/operateDataLogApi'
82   -
83   -export default {
84   - name: 'OwnerDetailHis',
85   - data() {
86   - return {
87   - loading: false,
88   - ownerDetailHisInfo: {
89   - owners: [],
90   - ownerId: '',
91   - ownerName: '',
92   - carNum: '',
93   - listColumns: [],
94   - logStartTime: '',
95   - logEndTime: '',
96   - ownerNameLike: '',
97   - staffNameLike: ''
98   - },
99   - page: {
100   - current: 1,
101   - size: 10,
102   - total: 0
103   - }
104   - }
105   - },
106   - methods: {
107   - async open(conditions) {
108   - this.ownerDetailHisInfo = {
109   - ...this.ownerDetailHisInfo,
110   - ...conditions
111   - }
112   - await this._getColumns()
113   - this._loadOwnerDetailHisData()
114   - },
115   - async _loadOwnerDetailHisData() {
116   - try {
117   - this.loading = true
118   - const params = {
119   - page: this.page.current,
120   - row: this.page.size,
121   - memberId: this.ownerDetailHisInfo.ownerId,
122   - ownerNameLike: this.ownerDetailHisInfo.ownerNameLike,
123   - logStartTime: this.ownerDetailHisInfo.logStartTime,
124   - logEndTime: this.ownerDetailHisInfo.logEndTime,
125   - staffNameLike: this.ownerDetailHisInfo.staffNameLike
126   - }
127   -
128   - const { data, total } = await queryHisOwner(params)
129   - this.ownerDetailHisInfo.owners = data
130   - this._dealOwnerAttr(data)
131   - this.page.total = total
132   - } catch (error) {
133   - console.error('Failed to load owner history:', error)
134   - } finally {
135   - this.loading = false
136   - }
137   - },
138   - _getHisOwnerOperate(owner) {
139   - const ownerCount = this.ownerDetailHisInfo.owners.filter(item => item.bId === owner.bId).length
140   -
141   - if (ownerCount <= 1) {
142   - if (owner.operate === 'ADD') return this.$t('ownerDetailHis.add')
143   - if (owner.operate === 'DEL') return this.$t('ownerDetailHis.delete')
144   - return '-'
145   - }
146   -
147   - if (owner.operate === 'ADD') return this.$t('ownerDetailHis.modifyNew')
148   - if (owner.operate === 'DEL') return this.$t('ownerDetailHis.modifyOld')
149   - return '-'
150   - },
151   - async _getColumns() {
152   - try {
153   - const data = await getAttrSpec('building_owner_attr')
154   - this.ownerDetailHisInfo.listColumns = data
155   - .filter(item => item.listShow === 'Y')
156   - .map(item => item.specName)
157   - } catch (error) {
158   - console.error('Failed to get columns:', error)
159   - }
160   - },
161   - _dealOwnerAttr(owners) {
162   - if (!owners) return
163   -
164   - owners.forEach(item => {
165   - this._getColumnsValue(item)
166   - })
167   - },
168   - _getColumnsValue(owner) {
169   - owner.listValues = []
170   - if (!owner['ownerAttrDtos'] || owner.ownerAttrDtos.length < 1) {
171   - this.ownerDetailHisInfo.listColumns.forEach(() => {
172   - owner.listValues.push('')
173   - })
174   - return
175   - }
176   -
177   - this.ownerDetailHisInfo.listColumns.forEach(value => {
178   - let tmpValue = ''
179   - owner.ownerAttrDtos.forEach(attrItem => {
180   - if (value === attrItem.specName) {
181   - tmpValue = attrItem.valueName
182   - }
183   - })
184   - owner.listValues.push(tmpValue)
185   - })
186   - },
187   - handleSizeChange(size) {
188   - this.page.size = size
189   - this._loadOwnerDetailHisData()
190   - },
191   - handleCurrentChange(current) {
192   - this.page.current = current
193   - this._loadOwnerDetailHisData()
194   - }
195   - }
196   -}
197   -</script>
198   -
199   -<style scoped>
200   -.owner-detail-his {
201   - padding: 20px;
202   -}
203   -
204   -.el-pagination {
205   - margin-top: 20px;
206   - text-align: right;
207   -}
208   -</style>
209 0 \ No newline at end of file
src/i18n/userI18n.js
... ... @@ -8,6 +8,7 @@ import { messages as editScheduleClassesMessages } from &#39;../views/org/editSchedu
8 8 import { messages as scheduleClassesPageMessages } from '../views/org/scheduleClassesPageLang'
9 9 import { messages as workflowManageMessages } from '../views/system/workflowManageLang'
10 10 import { messages as workflowSettingManageMessages } from '../views/system/workflowSettingManageLang'
  11 +import { messages as ownerDetailMessages } from '../views/owner/ownerDetailLang'
11 12  
12 13 export const messages = {
13 14 en: {
... ... @@ -21,6 +22,7 @@ export const messages = {
21 22 ...scheduleClassesPageMessages.en,
22 23 ...workflowManageMessages.en,
23 24 ...workflowSettingManageMessages.en,
  25 + ...ownerDetailMessages.en,
24 26 },
25 27 zh: {
26 28 ...staffCommunityMessages.zh,
... ... @@ -33,5 +35,6 @@ export const messages = {
33 35 ...scheduleClassesPageMessages.zh,
34 36 ...workflowManageMessages.zh,
35 37 ...workflowSettingManageMessages.zh,
  38 + ...ownerDetailMessages.zh,
36 39 }
37 40 }
38 41 \ No newline at end of file
... ...
src/router/userRouter.js
... ... @@ -35,8 +35,13 @@ export default [
35 35 component: () => import('@/views/org/editScheduleClassesList.vue')
36 36 },
37 37 {
38   - path:'/pages/property/scheduleClassesPage',
39   - name:'/pages/property/scheduleClassesPage',
  38 + path: '/pages/property/scheduleClassesPage',
  39 + name: '/pages/property/scheduleClassesPage',
40 40 component: () => import('@/views/org/scheduleClassesPageList.vue')
41   - },
  41 + },
  42 + {
  43 + path: '/views/owner/ownerDetail',
  44 + name: '/views/owner/ownerDetail',
  45 + component: () => import('@/views/owner/ownerDetail.vue')
  46 + },
42 47 ]
43 48 \ No newline at end of file
... ...
src/views/oa/complaintLang.js
... ... @@ -28,6 +28,7 @@ export const messages = {
28 28 phone: 'Phone',
29 29 status: 'Status',
30 30 handler: 'Handler',
  31 + handlerPhone: 'Handler Phone',
31 32 createTime: 'Create Time'
32 33 },
33 34 edit: {
... ... @@ -106,6 +107,7 @@ export const messages = {
106 107 phone: '联系电话',
107 108 status: '状态',
108 109 handler: '处理人',
  110 + handlerPhone: '处理人电话',
109 111 createTime: '创建时间'
110 112 },
111 113 edit: {
... ...
src/views/oa/visitManageLang.js
... ... @@ -18,6 +18,8 @@ export const messages = {
18 18 table: {
19 19 visitId: 'Visit ID',
20 20 name: 'Name',
  21 + photo: 'Photo',
  22 +
21 23 gender: 'Gender',
22 24 phoneNumber: 'Phone Number',
23 25 roomName: 'Visit Room',
... ... @@ -29,6 +31,9 @@ export const messages = {
29 31 departureTime: 'Departure Time',
30 32 state: 'Audit Status',
31 33 msg: 'Audit Remark',
  34 + entourage: 'Entourage',
  35 + carStatus: 'Car Status',
  36 +
32 37 createTime: 'Create Time'
33 38 },
34 39 gender: {
... ... @@ -58,6 +63,8 @@ export const messages = {
58 63 table: {
59 64 visitId: '拜访ID',
60 65 name: '姓名',
  66 + photo: '照片',
  67 +
61 68 gender: '性别',
62 69 phoneNumber: '电话号码',
63 70 roomName: '拜访房屋',
... ... @@ -65,9 +72,12 @@ export const messages = {
65 72 carNum: '访客车辆',
66 73 visitType: '访客类型',
67 74 visitCase: '拜访事由',
  75 + entourage: '随行人数',
68 76 visitTime: '拜访时间',
69 77 departureTime: '离开时间',
70 78 state: '审核状态',
  79 + carStatus: '车辆状态',
  80 +
71 81 msg: '审核备注',
72 82 createTime: '创建时间'
73 83 },
... ...
src/views/owner/listOwner.vue
... ... @@ -21,8 +21,10 @@
21 21 <el-row :gutter="20">
22 22 <el-col :span="4">
23 23 <el-form-item>
24   - <el-select v-model="conditions.personType" :placeholder="$t('listOwner.personTypeName')" style="width:100%">
25   - <el-option v-for="(type,index) in personTypes" :key="index" :label="type.label" :value="type.value" />
  24 + <el-select v-model="conditions.personType" :placeholder="$t('listOwner.personTypeName')"
  25 + style="width:100%">
  26 + <el-option v-for="(type, index) in personTypes" :key="index" :label="type.label"
  27 + :value="type.value" />
26 28 </el-select>
27 29 </el-form-item>
28 30 </el-col>
... ... @@ -275,7 +277,8 @@ export default {
275 277 const data = await getAttrSpecList({
276 278 page: 1,
277 279 row: 100,
278   - tableName:'building_owner_attr'})
  280 + tableName: 'building_owner_attr'
  281 + })
279 282 this.listColumns = data
280 283 .filter(item => item.specShow === 'Y')
281 284 .map(item => item.specName)
... ... @@ -409,11 +412,14 @@ export default {
409 412 openOwnerDetail(owner) {
410 413 console.log('Owner detail:', owner)
411 414 // 实际项目中跳转到详情页面
  415 + this.$router.push(`/views/owner/ownerDetail?ownerId=${owner.ownerId}`)
  416 +
412 417 },
413 418  
414 419 openOwnerDetailMember(owner) {
415 420 console.log('Owner detail member:', owner)
416 421 // 实际项目中跳转到成员详情页面
  422 + this.$router.push(`/views/owner/ownerDetail?ownerId=${owner.ownerId}`)
417 423  
418 424 }
419 425 }
... ...
src/views/owner/ownerDetail.vue 0 → 100644
  1 +<template>
  2 + <div class="white-bg padding-lg padding-top border-radius">
  3 + <el-row type="flex" justify="space-between">
  4 + <div class="text-title">{{ $t('ownerDetail.ownerInfo') }}</div>
  5 + <div>
  6 + <el-button v-if="ownerDetailInfo.needBack" type="primary" size="small" style="margin-left:10px"
  7 + @click="$router.go(-1)">
  8 + <i class="el-icon-close"></i>{{ $t('common.back') }}
  9 + </el-button>
  10 + <el-button type="primary" size="small" style="margin-left:10px" @click="_openEditOwnerDetailModel">
  11 + <i class="el-icon-edit"></i>{{ $t('common.edit') }}
  12 + </el-button>
  13 + </div>
  14 + </el-row>
  15 +
  16 + <!-- Owner Information -->
  17 + <div class="margin-top ">
  18 + <el-row style="min-height: 160px;">
  19 + <el-col :span="4">
  20 + <div class="text-center vc-float-left" style="width: 150px;" v-if="ownerDetailInfo.faceUrl">
  21 + <img width="120px" height="140px" class="border-radius" :src="ownerDetailInfo.faceUrl"
  22 + @error="errorLoadImg" />
  23 + </div>
  24 + <div class="text-center vc-float-left" style="width: 150px;" v-else>
  25 + <img width="120px" height="140px" class="border-radius" src="/img/noPhoto.jpg" />
  26 + </div>
  27 + </el-col>
  28 + <el-col :span="20" class="text-left">
  29 + <el-form>
  30 + <el-row>
  31 + <el-col :span="6">
  32 + <el-form-item :label="$t('ownerDetail.ownerId')">
  33 + <div>{{ ownerDetailInfo.ownerId }}</div>
  34 + </el-form-item>
  35 + </el-col>
  36 + <el-col :span="6">
  37 + <el-form-item :label="$t('ownerDetail.name')">
  38 + <div>{{ ownerDetailInfo.name }}</div>
  39 + </el-form-item>
  40 + </el-col>
  41 + <el-col :span="6" v-if="ownerDetailInfo.personType == 'P'">
  42 + <el-form-item :label="$t('ownerDetail.gender')">
  43 + <div>
  44 + {{ ownerDetailInfo.sex == '0' ? $t('common.male') : (ownerDetailInfo.sex == '1' ?
  45 + $t('common.female')
  46 + : '') }}
  47 + </div>
  48 + </el-form-item>
  49 + </el-col>
  50 + <el-col :span="6">
  51 + <el-form-item :label="$t('ownerDetail.personType')">
  52 + <div>{{ ownerDetailInfo.personTypeName }}</div>
  53 + </el-form-item>
  54 + </el-col>
  55 + <el-col :span="6">
  56 + <el-form-item :label="$t('ownerDetail.personRole')">
  57 + <div>{{ ownerDetailInfo.personRoleName }}</div>
  58 + </el-form-item>
  59 + </el-col>
  60 + <el-col :span="6">
  61 + <el-form-item :label="$t('ownerDetail.idCard')">
  62 + <div>{{ ownerDetailInfo.idCard }}</div>
  63 + </el-form-item>
  64 + </el-col>
  65 + <el-col :span="6">
  66 + <el-form-item :label="$t('ownerDetail.contact')">
  67 + <div>{{ ownerDetailInfo.link }}</div>
  68 + </el-form-item>
  69 + </el-col>
  70 + <el-col :span="6">
  71 + <el-form-item :label="$t('ownerDetail.backupPhone')">
  72 + <div>{{ ownerDetailInfo.concactLink }}</div>
  73 + </el-form-item>
  74 + </el-col>
  75 + <el-col :span="6" v-if="ownerDetailInfo.personType == 'C'">
  76 + <el-form-item :label="$t('ownerDetail.contactPerson')">
  77 + <div>{{ ownerDetailInfo.concactPerson }}</div>
  78 + </el-form-item>
  79 + </el-col>
  80 + <el-col :span="6">
  81 + <el-form-item :label="$t('ownerDetail.creator')">
  82 + <div>{{ ownerDetailInfo.userName }}</div>
  83 + </el-form-item>
  84 + </el-col>
  85 + <el-col :span="12">
  86 + <el-form-item :label="$t('ownerDetail.remark')">
  87 + <div>{{ ownerDetailInfo.remark }}</div>
  88 + </el-form-item>
  89 + </el-col>
  90 + </el-row>
  91 + <div v-for="(item, index) in ownerDetailInfo.ownerAttrDtos" :key="index">
  92 + <el-row v-if="index % 4 == 0">
  93 + <el-col :span="6">
  94 + <el-form-item :label="item.specName + ':'">
  95 + <div>{{ item.valueName }}</div>
  96 + </el-form-item>
  97 + </el-col>
  98 + <el-col :span="6" v-if="index < ownerDetailInfo.ownerAttrDtos.length - 1">
  99 + <el-form-item :label="ownerDetailInfo.ownerAttrDtos[index + 1].specName + ':'">
  100 + <div>{{ ownerDetailInfo.ownerAttrDtos[index + 1].valueName }}</div>
  101 + </el-form-item>
  102 + </el-col>
  103 + <el-col :span="6" v-if="index < ownerDetailInfo.ownerAttrDtos.length - 2">
  104 + <el-form-item :label="ownerDetailInfo.ownerAttrDtos[index + 2].specName + ':'">
  105 + <div>{{ ownerDetailInfo.ownerAttrDtos[index + 2].valueName }}</div>
  106 + </el-form-item>
  107 + </el-col>
  108 + <el-col :span="6" v-if="index < ownerDetailInfo.ownerAttrDtos.length - 3">
  109 + <el-form-item :label="ownerDetailInfo.ownerAttrDtos[index + 3].specName + ':'">
  110 + <div>{{ ownerDetailInfo.ownerAttrDtos[index + 3].valueName }}</div>
  111 + </el-form-item>
  112 + </el-col>
  113 + </el-row>
  114 + </div>
  115 + </el-form>
  116 + </el-col>
  117 + </el-row>
  118 + </div>
  119 +
  120 + <divider/>
  121 +
  122 + <div class="margin-top-sm">
  123 + <el-tabs v-model="ownerDetailInfo._currentTab" @tab-click="changeTab(ownerDetailInfo._currentTab)">
  124 + <el-tab-pane :label="$t('ownerDetail.room')" name="ownerDetailRoom"></el-tab-pane>
  125 + <el-tab-pane :label="$t('ownerDetail.car')" name="ownerDetailCar"></el-tab-pane>
  126 + <el-tab-pane :label="$t('ownerDetail.member')" name="ownerDetailMember"></el-tab-pane>
  127 + <el-tab-pane :label="$t('ownerDetail.history')" name="ownerDetailHis"></el-tab-pane>
  128 + <el-tab-pane :label="$t('ownerDetail.roomFee')" name="ownerDetailRoomFee"></el-tab-pane>
  129 + <el-tab-pane :label="$t('ownerDetail.paymentHistory')" name="ownerDetailHisFee"></el-tab-pane>
  130 + <el-tab-pane :label="$t('ownerDetail.account')" name="ownerDetailAccount"></el-tab-pane>
  131 + <el-tab-pane :label="$t('ownerDetail.coupon')" name="ownerDetailCoupon"></el-tab-pane>
  132 + <el-tab-pane :label="$t('ownerDetail.ownerBinding')" name="ownerDetailAppUser"></el-tab-pane>
  133 + <el-tab-pane :label="$t('ownerDetail.complaint')" name="ownerDetailComplaint"></el-tab-pane>
  134 + <el-tab-pane :label="$t('ownerDetail.repair')" name="ownerDetailRepair"></el-tab-pane>
  135 + <el-tab-pane :label="$t('ownerDetail.visitor')" name="ownerDetailVisit"></el-tab-pane>
  136 + <el-tab-pane :label="$t('ownerDetail.contract')" name="ownerDetailContract"></el-tab-pane>
  137 + <el-tab-pane :label="$t('ownerDetail.receipt')" name="ownerDetailReceipt"></el-tab-pane>
  138 + <el-tab-pane :label="$t('ownerDetail.depositReceipt')" name="ownerDetailAccountReceipt"></el-tab-pane>
  139 + <el-tab-pane :label="$t('ownerDetail.faceSync')" name="ownerDetailAccessControl"></el-tab-pane>
  140 + <el-tab-pane :label="$t('ownerDetail.accessRecord')" name="ownerDetailAccessControlRecord"></el-tab-pane>
  141 + <el-tab-pane :label="$t('ownerDetail.chargeOrder')" name="ownerDetailChargeMachineOrder"></el-tab-pane>
  142 + </el-tabs>
  143 + </div>
  144 +
  145 + <component :is="ownerDetailInfo._currentTab" ref="currentTabComponent"></component>
  146 +
  147 + <edit-owner ref="editOwner" @refresh="loadOwnerInfo"></edit-owner>
  148 + <delete-fee ref="deleteFee"></delete-fee>
  149 + <edit-fee ref="editFee"></edit-fee>
  150 + <finish-fee ref="finishFee"></finish-fee>
  151 + </div>
  152 +</template>
  153 +
  154 +<script>
  155 +import OwnerDetailRoom from '@/components/owner/ownerDetailRoom'
  156 +import OwnerDetailCar from '@/components/owner/ownerDetailCar'
  157 +import OwnerDetailMember from '@/components/owner/ownerDetailMember'
  158 +import OwnerDetailHis from '@/components/owner/ownerDetailHis'
  159 +import OwnerDetailAccount from '@/components/owner/ownerDetailAccount'
  160 +import OwnerDetailCoupon from '@/components/owner/ownerDetailCoupon'
  161 +import OwnerDetailAppUser from '@/components/owner/ownerDetailAppUser'
  162 +import OwnerDetailComplaint from '@/components/owner/ownerDetailComplaint'
  163 +import OwnerDetailRepair from '@/components/owner/ownerDetailRepair'
  164 +import OwnerDetailVisit from '@/components/owner/ownerDetailVisit'
  165 +import OwnerDetailContract from '@/components/owner/ownerDetailContract'
  166 +//import OwnerDetailRoomFee from '@/components/owner/ownerDetailRoomFee'
  167 +import OwnerDetailHisFee from '@/components/owner/ownerDetailHisFee'
  168 +import OwnerDetailReceipt from '@/components/owner/ownerDetailReceipt'
  169 +import OwnerDetailAccountReceipt from '@/components/owner/ownerDetailAccountReceipt'
  170 +import OwnerDetailAccessControl from '@/components/owner/ownerDetailAccessControl'
  171 +import OwnerDetailAccessControlRecord from '@/components/owner/ownerDetailAccessControlRecord'
  172 +import OwnerDetailChargeMachineOrder from '@/components/owner/ownerDetailChargeMachineOrder'
  173 +import EditOwner from '@/components/owner/editOwner'
  174 +import DeleteFee from '@/components/fee/deleteFee'
  175 +import EditFee from '@/components/fee/editFee'
  176 +//import FinishFee from '@/components/fee/finishFee'
  177 +import { getCommunityId } from '@/api/community/communityApi'
  178 +import { queryOwners } from '@/api/owner/ownerDetailApi'
  179 +import divider from '@/components/system/divider'
  180 +
  181 +export default {
  182 + name: 'OwnerDetail',
  183 + components: {
  184 + OwnerDetailRoom,
  185 + OwnerDetailCar,
  186 + OwnerDetailMember,
  187 + OwnerDetailHis,
  188 + OwnerDetailAccount,
  189 + OwnerDetailCoupon,
  190 + OwnerDetailAppUser,
  191 + OwnerDetailComplaint,
  192 + OwnerDetailRepair,
  193 + OwnerDetailVisit,
  194 + OwnerDetailContract,
  195 + //OwnerDetailRoomFee,
  196 + OwnerDetailHisFee,
  197 + OwnerDetailReceipt,
  198 + OwnerDetailAccountReceipt,
  199 + OwnerDetailAccessControl,
  200 + OwnerDetailAccessControlRecord,
  201 + OwnerDetailChargeMachineOrder,
  202 + EditOwner,
  203 + DeleteFee,
  204 + EditFee,
  205 + //FinishFee,
  206 + divider
  207 + },
  208 + data() {
  209 + return {
  210 + ownerDetailInfo: {
  211 + viewOwnerFlag: '',
  212 + ownerId: "",
  213 + memberId: '',
  214 + name: "",
  215 + age: "",
  216 + sex: "",
  217 + userName: "",
  218 + remark: "",
  219 + idCard: "",
  220 + link: "",
  221 + ownerPhoto: "/img/noPhoto.jpg",
  222 + ownerAttrDtos: [],
  223 + faceUrl: '',
  224 + _currentTab: 'ownerDetailRoom',
  225 + personType: '',
  226 + personTypeName: '',
  227 + personRole: '',
  228 + personRoleName: '',
  229 + concactLink: '',
  230 + concactPerson: '',
  231 + needBack: false
  232 + }
  233 + }
  234 + },
  235 + created() {
  236 + this.initData()
  237 + },
  238 + methods: {
  239 + initData() {
  240 + this.ownerDetailInfo.ownerId = this.$route.query.ownerId
  241 + this.ownerDetailInfo.needBack = this.$route.query.needBack
  242 + if (!this.ownerDetailInfo.ownerId) {
  243 + return
  244 + }
  245 + const currentTab = this.$route.query.currentTab
  246 + if (currentTab) {
  247 + this.ownerDetailInfo._currentTab = currentTab
  248 + }
  249 + this.loadOwnerInfo()
  250 + },
  251 + loadOwnerInfo() {
  252 + const params = {
  253 + ownerId: this.ownerDetailInfo.ownerId,
  254 + page: 1,
  255 + row: 1,
  256 + communityId: getCommunityId(),
  257 + ownerTypeCd: '1001'
  258 + }
  259 +
  260 + queryOwners(params).then(response => {
  261 + const data = response.data[0]
  262 + Object.assign(this.ownerDetailInfo, data)
  263 + this.ownerDetailInfo.ownerAttrDtos = response.owners[0].ownerAttrDtos
  264 + }).catch(error => {
  265 + console.error('Failed to load owner info:', error)
  266 + })
  267 + },
  268 + changeTab(tab) {
  269 + this.ownerDetailInfo._currentTab = tab || tab
  270 + setTimeout(() => {
  271 + if (this.$refs.currentTabComponent) {
  272 + this.$refs.currentTabComponent.open(
  273 + this.ownerDetailInfo.ownerId,
  274 + this.ownerDetailInfo.name,
  275 + this.ownerDetailInfo.link
  276 + )
  277 + }
  278 + }, 1000);
  279 +
  280 + },
  281 + errorLoadImg() {
  282 + this.ownerDetailInfo.ownerPhoto = "/img/noPhoto.jpg"
  283 + },
  284 + _openEditOwnerDetailModel() {
  285 + this.$refs.editOwner.open(this.ownerDetailInfo)
  286 + }
  287 + }
  288 +}
  289 +</script>
  290 +
  291 +<style scoped>
  292 +.white-bg {
  293 + background-color: #fff;
  294 +}
  295 +
  296 +.padding-lg {
  297 + padding: 20px;
  298 +}
  299 +
  300 +.padding-top {
  301 + padding-top: 15px;
  302 +}
  303 +
  304 +.border-radius {
  305 + border-radius: 4px;
  306 +}
  307 +
  308 +.margin-top {
  309 + margin-top: 15px;
  310 +}
  311 +
  312 +.margin-top-sm {
  313 + margin-top: 10px;
  314 +}
  315 +
  316 +.text-title {
  317 + font-size: 18px;
  318 + font-weight: bold;
  319 +}
  320 +
  321 +.vc-float-left {
  322 + float: left;
  323 +}
  324 +
  325 +.vc-line-primary {
  326 + border-top: 1px solid #409EFF;
  327 +}
  328 +</style>
0 329 \ No newline at end of file
... ...
src/views/owner/ownerDetailLang.js 0 → 100644
  1 +export const messages = {
  2 + en: {
  3 + ownerDetail: {
  4 + ownerInfo: 'Owner Information',
  5 + ownerId: 'Owner ID',
  6 + name: 'Name',
  7 + gender: 'Gender',
  8 + personType: 'Person Type',
  9 + personRole: 'Person Role',
  10 + idCard: 'ID Card',
  11 + contact: 'Contact',
  12 + backupPhone: 'Backup Phone',
  13 + contactPerson: 'Contact Person',
  14 + creator: 'Creator',
  15 + remark: 'Remark',
  16 + room: 'Room',
  17 + car: 'Car',
  18 + member: 'Member',
  19 + history: 'History',
  20 + roomFee: 'Room Fee',
  21 + paymentHistory: 'Payment History',
  22 + account: 'Account',
  23 + coupon: 'Coupon',
  24 + ownerBinding: 'Owner Binding',
  25 + complaint: 'Complaint',
  26 + repair: 'Repair',
  27 + visitor: 'Visitor',
  28 + contract: 'Contract',
  29 + receipt: 'Receipt',
  30 + depositReceipt: 'Deposit Receipt',
  31 + faceSync: 'Face Sync',
  32 + accessRecord: 'Access Record',
  33 + chargeOrder: 'Charge Order'
  34 + },
  35 + ownerDetailMember: {
  36 + placeholder: {
  37 + name: 'Please enter member name'
  38 + },
  39 + face: 'Face',
  40 + name: 'Name',
  41 + gender: 'Gender',
  42 + role: 'Role',
  43 + idCard: 'ID Card',
  44 + contact: 'Contact',
  45 + address: 'Address'
  46 + },
  47 + ownerDetailAccount: {
  48 + acctId: 'Account ID',
  49 + acctName: 'Account Name',
  50 + phone: 'Phone',
  51 + acctType: 'Account Type',
  52 + amount: 'Amount',
  53 + createTime: 'Create Time',
  54 + prestore: 'Prestore',
  55 + detail: 'Account Detail'
  56 + },
  57 + ownerDetailAppUser: {
  58 + communityName: 'Community Name',
  59 + relatedOwner: 'Related Owner',
  60 + idCard: 'ID Card',
  61 + phone: 'Phone',
  62 + status: 'Status',
  63 + applyTime: 'Apply Time',
  64 + appType: 'App Type',
  65 + unbind: 'Unbind',
  66 + resetPwd: 'Reset Password'
  67 + },
  68 + ownerDetailRepair: {
  69 + repairId: 'Work Order ID',
  70 + location: 'Location',
  71 + repairType: 'Repair Type',
  72 + reporter: 'Reporter',
  73 + contact: 'Contact',
  74 + appointmentTime: 'Appointment Time',
  75 + status: 'Status',
  76 + taskProcess: 'Task Process'
  77 + },
  78 + ownerDetailContract: {
  79 + contractName: 'Contract Name',
  80 + contractCode: 'Contract Code',
  81 + parentContractCode: 'Parent Contract Code',
  82 + contractType: 'Contract Type',
  83 + operator: 'Operator',
  84 + amount: 'Amount',
  85 + startTime: 'Start Time',
  86 + endTime: 'End Time',
  87 + createTime: 'Create Time',
  88 + status: 'Status'
  89 + },
  90 + ownerDetailHisFee: {
  91 + feeItem: 'Fee Item',
  92 + chargeObject: 'Charge Object',
  93 + cycle: 'Cycle (months)',
  94 + receivableAmount: 'Receivable/Received (yuan)',
  95 + paymentMethod: 'Payment Method',
  96 + paymentPeriod: 'Payment Period',
  97 + paymentTime: 'Payment Time',
  98 + cashier: 'Cashier',
  99 + status: 'Status',
  100 + remark: 'Remark',
  101 + operation: 'Operation',
  102 + detail: 'Detail',
  103 + accountDeduction: 'Account Deduction'
  104 + },
  105 + ownerDetailReceipt: {
  106 + print: 'Print',
  107 + printSmall: 'Print Small',
  108 + printApply: 'Print Application',
  109 + feeType: 'Fee Type',
  110 + owner: 'Owner',
  111 + feeItem: 'Fee Item',
  112 + chargePeriod: 'Charge Period',
  113 + totalAmount: 'Total Amount',
  114 + paymentTime: 'Payment Time',
  115 + receiptId: 'Receipt ID',
  116 + selectPrint: 'Please select receipts to print'
  117 + },
  118 + ownerDetailAccountReceipt: {
  119 + print: 'Print',
  120 + printSmall: 'Print Small',
  121 + accountName: 'Account Name',
  122 + accountType: 'Account Type',
  123 + owner: 'Owner',
  124 + prestoreAmount: 'Prestore Amount',
  125 + prestoreMethod: 'Prestore Method',
  126 + totalAmount: 'Total Amount',
  127 + prestoreTime: 'Prestore Time',
  128 + receiptId: 'Receipt ID',
  129 + selectPrint: 'Please select receipts to print'
  130 + },
  131 + ownerDetailAccessControl: {
  132 + objectType: 'Object Type',
  133 + objectName: 'Object Name',
  134 + command: 'Command',
  135 + status: 'Status',
  136 + description: 'Description',
  137 + syncTime: 'Sync Time',
  138 + operation: 'Operation',
  139 + resync: 'Resync'
  140 + },
  141 + ownerDetailAccessControlRecord: {
  142 + face: 'Face',
  143 + id: 'ID',
  144 + deviceName: 'Device Name',
  145 + deviceCode: 'Device Code',
  146 + userName: 'User Name',
  147 + openType: 'Open Type',
  148 + phone: 'Phone',
  149 + idCard: 'ID Card',
  150 + similarity: 'Similarity',
  151 + openStatus: 'Open Status',
  152 + openTime: 'Open Time',
  153 + other: 'Other',
  154 + success: 'Success',
  155 + failed: 'Failed'
  156 + },
  157 + ownerDetailChargeMachineOrder: {
  158 + id: 'ID',
  159 + name: 'Name',
  160 + phone: 'Phone',
  161 + charger: 'Charger',
  162 + slot: 'Slot',
  163 + chargeHours: 'Charge Hours',
  164 + byAmount: 'By Amount',
  165 + hours: 'hours',
  166 + chargeAmount: 'Charge Amount',
  167 + startTime: 'Start Time',
  168 + endTime: 'End Time',
  169 + deductionAccount: 'Deduction Account',
  170 + hourPrice: 'Hour Price',
  171 + deductionAmount: 'Deduction Amount',
  172 + detail: 'Detail',
  173 + socketStatus: 'Socket Status',
  174 + stopCharge: 'Stop Charge',
  175 + description: 'Description'
  176 + },
  177 + ownerDetailRoom: {
  178 + pleaseEnterRoomNumber: 'Please enter room number',
  179 + roomNumber: 'Room Number',
  180 + floor: 'Floor',
  181 + type: 'Type',
  182 + area: 'Area',
  183 + rent: 'Rent',
  184 + validity: 'Validity',
  185 + roomStatus: 'Room Status',
  186 + roomArrears: 'Room Arrears',
  187 + updateDaily: 'Update daily',
  188 + checkOut: 'Check Out',
  189 + businessAcceptance: 'Business Acceptance',
  190 + arrearsSubtotal: 'Arrears Subtotal',
  191 + roomNumberPlaceholder: 'Please enter room number like 1-1-1',
  192 + deliverRoom: 'Deliver Room'
  193 + },
  194 + ownerDetailCar: {
  195 + pleaseEnterCarNumber: 'Please enter license plate number',
  196 + addCar: 'Add Vehicle',
  197 + carNumber: 'License Plate',
  198 + licenseType: 'License Type',
  199 + temporaryCar: 'Temporary Vehicle',
  200 + carType: 'Vehicle Type',
  201 + color: 'Color',
  202 + owner: 'Owner',
  203 + parkingSpace: 'Parking Space',
  204 + parkingSpaceReleased: 'Parking Space Released',
  205 + validityPeriod: 'Validity Period'
  206 + },
  207 + ownerDetailHis: {
  208 + action: 'Action',
  209 + operator: 'Operator',
  210 + operateTime: 'Operate Time',
  211 + name: 'Name',
  212 + gender: 'Gender',
  213 + male: 'Male',
  214 + female: 'Female',
  215 + idCard: 'ID Card',
  216 + address: 'Address',
  217 + add: 'Add',
  218 + delete: 'Delete',
  219 + modifyNew: 'Modify(New)',
  220 + modifyOld: 'Modify(Old)'
  221 + },
  222 + ownerDetailCoupon: {
  223 + id: 'ID',
  224 + couponName: 'Coupon Name',
  225 + value: 'Value',
  226 + validity: 'Validity',
  227 + userName: 'User Name',
  228 + phone: 'Phone',
  229 + purpose: 'Purpose',
  230 + quantity: 'Quantity',
  231 + unit: 'pcs',
  232 + status: 'Status',
  233 + unused: 'Unused',
  234 + used: 'Used',
  235 + effectiveTime: 'Effective Time'
  236 + }
  237 + },
  238 + zh: {
  239 + ownerDetail: {
  240 + ownerInfo: '业主信息',
  241 + ownerId: '业主ID',
  242 + name: '名称',
  243 + gender: '性别',
  244 + personType: '人员类型',
  245 + personRole: '人员角色',
  246 + idCard: '证件号',
  247 + contact: '联系方式',
  248 + backupPhone: '备用手机',
  249 + contactPerson: '联系人',
  250 + creator: '创建员工',
  251 + remark: '备注',
  252 + room: '房屋',
  253 + car: '车辆',
  254 + member: '成员',
  255 + history: '修改记录',
  256 + roomFee: '房屋费用',
  257 + paymentHistory: '缴费历史',
  258 + account: '账户',
  259 + coupon: '优惠券',
  260 + ownerBinding: '业主绑定',
  261 + complaint: '投诉',
  262 + repair: '报修',
  263 + visitor: '访客',
  264 + contract: '合同',
  265 + receipt: '补打收据',
  266 + depositReceipt: '预存收据',
  267 + faceSync: '人脸同步',
  268 + accessRecord: '开门记录',
  269 + chargeOrder: '充电订单'
  270 + },
  271 + ownerDetailMember: {
  272 + placeholder: {
  273 + name: '请填写成员名称'
  274 + },
  275 + face: '人脸',
  276 + name: '名称',
  277 + gender: '性别',
  278 + role: '人员角色',
  279 + idCard: '身份证',
  280 + contact: '联系方式',
  281 + address: '地址'
  282 + },
  283 + ownerDetailAccount: {
  284 + acctId: '账户编号',
  285 + acctName: '账户名称',
  286 + phone: '手机号',
  287 + acctType: '账户类型',
  288 + amount: '账户金额',
  289 + createTime: '创建时间',
  290 + prestore: '预存',
  291 + detail: '账户明细'
  292 + },
  293 + ownerDetailAppUser: {
  294 + communityName: '小区名称',
  295 + relatedOwner: '关联业主',
  296 + idCard: '身份证',
  297 + phone: '手机号',
  298 + status: '状态',
  299 + applyTime: '申请时间',
  300 + appType: '手机端类型',
  301 + unbind: '解绑',
  302 + resetPwd: '重置密码'
  303 + },
  304 + ownerDetailRepair: {
  305 + repairId: '工单编码',
  306 + location: '位置',
  307 + repairType: '报修类型',
  308 + reporter: '报修人',
  309 + contact: '联系方式',
  310 + appointmentTime: '预约时间',
  311 + status: '状态',
  312 + taskProcess: '定时任务处理'
  313 + },
  314 + ownerDetailContract: {
  315 + contractName: '合同名称',
  316 + contractCode: '合同编号',
  317 + parentContractCode: '父合同编号',
  318 + contractType: '合同类型',
  319 + operator: '经办人',
  320 + amount: '合同金额',
  321 + startTime: '开始时间',
  322 + endTime: '结束时间',
  323 + createTime: '起草时间',
  324 + status: '状态'
  325 + },
  326 + ownerDetailHisFee: {
  327 + feeItem: '费用项',
  328 + chargeObject: '收费对象',
  329 + cycle: '周期(单位:月)',
  330 + receivableAmount: '应收/实收(单位:元)',
  331 + paymentMethod: '缴费方式',
  332 + paymentPeriod: '缴费起始段',
  333 + paymentTime: '缴费时间',
  334 + cashier: '收银员',
  335 + status: '状态',
  336 + remark: '备注',
  337 + operation: '操作',
  338 + detail: '详情',
  339 + accountDeduction: '账户扣款'
  340 + },
  341 + ownerDetailReceipt: {
  342 + print: '打印',
  343 + printSmall: '打印小票',
  344 + printApply: '申请单',
  345 + feeType: '费用类型',
  346 + owner: '业主',
  347 + feeItem: '费用项目',
  348 + chargePeriod: '收费时间段',
  349 + totalAmount: '总金额',
  350 + paymentTime: '缴费时间',
  351 + receiptId: '收据ID',
  352 + selectPrint: '请选择打印收据'
  353 + },
  354 + ownerDetailAccountReceipt: {
  355 + print: '打印',
  356 + printSmall: '打印小票',
  357 + accountName: '账户名称',
  358 + accountType: '账户类型',
  359 + owner: '业主',
  360 + prestoreAmount: '预存金额',
  361 + prestoreMethod: '预存方式',
  362 + totalAmount: '总金额',
  363 + prestoreTime: '预存时间',
  364 + receiptId: '收据ID',
  365 + selectPrint: '请选择打印收据'
  366 + },
  367 + ownerDetailAccessControl: {
  368 + objectType: '对象类型',
  369 + objectName: '对象名称',
  370 + command: '指令',
  371 + status: '状态',
  372 + description: '说明',
  373 + syncTime: '同步时间',
  374 + operation: '操作',
  375 + resync: '重新同步'
  376 + },
  377 + ownerDetailAccessControlRecord: {
  378 + face: '人脸',
  379 + id: '编号',
  380 + deviceName: '设备名称',
  381 + deviceCode: '设备编码',
  382 + userName: '用户名称',
  383 + openType: '开门方式',
  384 + phone: '手机号',
  385 + idCard: '用户身份证',
  386 + similarity: '相似度',
  387 + openStatus: '开门状态',
  388 + openTime: '开门时间',
  389 + other: '其他',
  390 + success: '开门成功',
  391 + failed: '开门失败'
  392 + },
  393 + ownerDetailChargeMachineOrder: {
  394 + id: '编号',
  395 + name: '名称',
  396 + phone: '手机号',
  397 + charger: '充电桩',
  398 + slot: '插槽',
  399 + chargeHours: '充电小时',
  400 + byAmount: '按量充电',
  401 + hours: '小时',
  402 + chargeAmount: '充电量',
  403 + startTime: '开始时间',
  404 + endTime: '结束时间',
  405 + deductionAccount: '扣款账户',
  406 + hourPrice: '小时电价',
  407 + deductionAmount: '扣款金额',
  408 + detail: '明细',
  409 + socketStatus: '插座状态',
  410 + stopCharge: '停止充电',
  411 + description: '说明'
  412 + },
  413 + ownerDetailRoom: {
  414 + pleaseEnterRoomNumber: '请填写房屋编号',
  415 + roomNumber: '房屋编号',
  416 + floor: '楼层',
  417 + type: '类型',
  418 + area: '建筑/室内面积',
  419 + rent: '租金',
  420 + validity: '有效期',
  421 + roomStatus: '房屋状态',
  422 + roomArrears: '房屋欠费',
  423 + updateDaily: '按天更新',
  424 + checkOut: '退房',
  425 + businessAcceptance: '业务受理',
  426 + arrearsSubtotal: '欠费小计',
  427 + roomNumberPlaceholder: '请输入房屋编号 楼栋-单元-房屋 如1-1-1',
  428 + deliverRoom: '交房'
  429 + },
  430 + ownerDetailCar: {
  431 + pleaseEnterCarNumber: '请填写车牌号',
  432 + addCar: '添加车辆',
  433 + carNumber: '车牌号',
  434 + licenseType: '车牌类型',
  435 + temporaryCar: '临时车',
  436 + carType: '车辆类型',
  437 + color: '颜色',
  438 + owner: '业主',
  439 + parkingSpace: '车位',
  440 + parkingSpaceReleased: '车位已释放',
  441 + validityPeriod: '有效期'
  442 + },
  443 + ownerDetailHis: {
  444 + action: '动作',
  445 + operator: '操作人',
  446 + operateTime: '操作时间',
  447 + name: '姓名',
  448 + gender: '性别',
  449 + male: '男',
  450 + female: '女',
  451 + idCard: '身份证',
  452 + address: '家庭住址',
  453 + add: '添加',
  454 + delete: '删除',
  455 + modifyNew: '修改(新)',
  456 + modifyOld: '修改(旧)'
  457 + },
  458 + ownerDetailCoupon: {
  459 + id: '编号',
  460 + couponName: '优惠券名称',
  461 + value: '面值',
  462 + validity: '有效期',
  463 + userName: '用户名称',
  464 + phone: '手机号',
  465 + purpose: '用途',
  466 + quantity: '数量',
  467 + unit: '张',
  468 + status: '状态',
  469 + unused: '未使用',
  470 + used: '已使用',
  471 + effectiveTime: '生效时间'
  472 + }
  473 + }
  474 +}
0 475 \ No newline at end of file
... ...
src/views/system/operateDataLogLang.js
... ... @@ -53,21 +53,6 @@ export const messages = {
53 53 modifyNew: 'modify(new)',
54 54 modifyOld: 'modify(old)'
55 55 },
56   - ownerDetailHis: {
57   - operate: 'action',
58   - userName: 'operator',
59   - createTime: 'create time',
60   - name: 'name',
61   - sex: 'sex',
62   - male: 'male',
63   - female: 'female',
64   - idCard: 'id card',
65   - address: 'address',
66   - add: 'add',
67   - delete: 'delete',
68   - modifyNew: 'modify(new)',
69   - modifyOld: 'modify(old)'
70   - },
71 56 roomDetailHis: {
72 57 operate: 'action',
73 58 userName: 'operator',
... ... @@ -170,21 +155,6 @@ export const messages = {
170 155 modifyNew: '修改(新)',
171 156 modifyOld: '修改(旧)'
172 157 },
173   - ownerDetailHis: {
174   - operate: '动作',
175   - userName: '操作人',
176   - createTime: '操作时间',
177   - name: '姓名',
178   - sex: '性别',
179   - male: '男',
180   - female: '女',
181   - idCard: '身份证',
182   - address: '家庭住址',
183   - add: '添加',
184   - delete: '删除',
185   - modifyNew: '修改(新)',
186   - modifyOld: '修改(旧)'
187   - },
188 158 roomDetailHis: {
189 159 operate: '动作',
190 160 userName: '操作人',
... ...
src/views/system/operateDataLogList.vue
... ... @@ -3,43 +3,32 @@
3 3 <el-card class="search-card">
4 4 <div slot="header" class="clearfix">
5 5 <span>{{ $t('operateDataLog.search.title') }}</span>
6   - <el-button
7   - type="text"
8   - style="float: right; padding: 3px 0"
9   - @click="_moreCondition">
  6 + <el-button type="text" style="float: right; padding: 3px 0" @click="_moreCondition">
10 7 {{ operateDataLogInfo.moreCondition ? $t('common.hide') : $t('common.more') }}
11 8 </el-button>
12 9 </div>
13   -
  10 +
14 11 <el-row :gutter="20">
15 12 <el-col :span="6">
16   - <el-date-picker
17   - v-model="operateDataLogInfo.conditions.logStartTime"
18   - type="datetime"
19   - :placeholder="$t('operateDataLog.search.logStartTime')"
20   - style="width: 100%"
  13 + <el-date-picker v-model="operateDataLogInfo.conditions.logStartTime" type="datetime"
  14 + :placeholder="$t('operateDataLog.search.logStartTime')" style="width: 100%"
21 15 value-format="yyyy-MM-dd HH:mm:ss">
22 16 </el-date-picker>
23 17 </el-col>
24   -
  18 +
25 19 <el-col :span="6">
26   - <el-date-picker
27   - v-model="operateDataLogInfo.conditions.logEndTime"
28   - type="datetime"
29   - :placeholder="$t('operateDataLog.search.logEndTime')"
30   - style="width: 100%"
31   - value-format="yyyy-MM-dd HH:mm:ss"
  20 + <el-date-picker v-model="operateDataLogInfo.conditions.logEndTime" type="datetime"
  21 + :placeholder="$t('operateDataLog.search.logEndTime')" style="width: 100%" value-format="yyyy-MM-dd HH:mm:ss"
32 22 :picker-options="endDateOptions">
33 23 </el-date-picker>
34 24 </el-col>
35   -
  25 +
36 26 <el-col :span="6">
37   - <el-input
38   - v-model="operateDataLogInfo.conditions.staffNameLike"
  27 + <el-input v-model="operateDataLogInfo.conditions.staffNameLike"
39 28 :placeholder="$t('operateDataLog.search.staffNameLike')">
40 29 </el-input>
41 30 </el-col>
42   -
  31 +
43 32 <el-col :span="6">
44 33 <el-button type="primary" @click="_queryDataMethod">
45 34 <i class="el-icon-search"></i>
... ... @@ -53,44 +42,39 @@
53 42 </el-row>
54 43  
55 44 <el-row :gutter="20" v-show="operateDataLogInfo.moreCondition">
56   - <el-col :span="6" v-if="operateDataLogInfo._currentTab === 'feeConfigDetailHis' || operateDataLogInfo._currentTab === 'feeDetailHis'">
57   - <el-input
58   - v-model="operateDataLogInfo.conditions.feeNameLike"
  45 + <el-col :span="6"
  46 + v-if="operateDataLogInfo._currentTab === 'feeConfigDetailHis' || operateDataLogInfo._currentTab === 'feeDetailHis'">
  47 + <el-input v-model="operateDataLogInfo.conditions.feeNameLike"
59 48 :placeholder="$t('operateDataLog.search.feeNameLike')">
60 49 </el-input>
61 50 </el-col>
62   -
  51 +
63 52 <el-col :span="6" v-if="operateDataLogInfo._currentTab === 'feeDetailHis'">
64   - <el-input
65   - v-model="operateDataLogInfo.conditions.payerObjName"
  53 + <el-input v-model="operateDataLogInfo.conditions.payerObjName"
66 54 :placeholder="$t('operateDataLog.search.payerObjName')">
67 55 </el-input>
68 56 </el-col>
69   -
  57 +
70 58 <el-col :span="6" v-if="operateDataLogInfo._currentTab === 'ownerDetailHis'">
71   - <el-input
72   - v-model="operateDataLogInfo.conditions.ownerNameLike"
  59 + <el-input v-model="operateDataLogInfo.conditions.ownerNameLike"
73 60 :placeholder="$t('operateDataLog.search.ownerNameLike')">
74 61 </el-input>
75 62 </el-col>
76   -
  63 +
77 64 <el-col :span="6" v-if="operateDataLogInfo._currentTab === 'roomDetailHis'">
78   - <el-input
79   - v-model="operateDataLogInfo.conditions.roomName"
  65 + <el-input v-model="operateDataLogInfo.conditions.roomName"
80 66 :placeholder="$t('operateDataLog.search.roomName')">
81 67 </el-input>
82 68 </el-col>
83   -
  69 +
84 70 <el-col :span="6" v-if="operateDataLogInfo._currentTab === 'carDetailHis'">
85   - <el-input
86   - v-model="operateDataLogInfo.conditions.carNumLike"
  71 + <el-input v-model="operateDataLogInfo.conditions.carNumLike"
87 72 :placeholder="$t('operateDataLog.search.carNumLike')">
88 73 </el-input>
89 74 </el-col>
90   -
  75 +
91 76 <el-col :span="6" v-if="operateDataLogInfo._currentTab === 'contractDetailChange'">
92   - <el-input
93   - v-model="operateDataLogInfo.conditions.contractCode"
  77 + <el-input v-model="operateDataLogInfo.conditions.contractCode"
94 78 :placeholder="$t('operateDataLog.search.contractCode')">
95 79 </el-input>
96 80 </el-col>
... ... @@ -116,7 +100,7 @@
116 100 import { getCommunityId } from '@/api/community/communityApi'
117 101 import FeeConfigDetailHis from '@/components/system/feeConfigDetailHis'
118 102 import FeeDetailHis from '@/components/system/feeDetailHis'
119   -import OwnerDetailHis from '@/components/system/ownerDetailHis'
  103 +import OwnerDetailHis from '@/components/owner/ownerDetailHis'
120 104 import RoomDetailHis from '@/components/system/roomDetailHis'
121 105 import CarDetailHis from '@/components/system/carDetailHis'
122 106 import ContractDetailChange from '@/components/system/contractDetailChange'
... ...