Commit e5d4300992114f97527a90f8aab29f38e5edecbf
1 parent
caba9d96
测试投诉待办
Showing
14 changed files
with
1163 additions
and
1 deletions
src/api/oa/complaintDetailApi.js
0 → 100644
| 1 | +import request from '@/utils/request' | ||
| 2 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 3 | + | ||
| 4 | +// 获取投诉详情 | ||
| 5 | +export function getComplaintDetail(params) { | ||
| 6 | + return new Promise((resolve, reject) => { | ||
| 7 | + request({ | ||
| 8 | + url: '/complaint.listComplaints', | ||
| 9 | + method: 'get', | ||
| 10 | + params: { | ||
| 11 | + ...params, | ||
| 12 | + communityId: getCommunityId() | ||
| 13 | + } | ||
| 14 | + }).then(response => { | ||
| 15 | + const res = response.data | ||
| 16 | + resolve(res) | ||
| 17 | + }).catch(error => { | ||
| 18 | + reject(error) | ||
| 19 | + }) | ||
| 20 | + }) | ||
| 21 | +} | ||
| 22 | + | ||
| 23 | +// 获取工单流转记录 | ||
| 24 | +export function listComplaintEvent(params) { | ||
| 25 | + return new Promise((resolve, reject) => { | ||
| 26 | + request({ | ||
| 27 | + url: '/complaint.listComplaintEvent', | ||
| 28 | + method: 'get', | ||
| 29 | + params: { | ||
| 30 | + ...params, | ||
| 31 | + communityId: getCommunityId() | ||
| 32 | + } | ||
| 33 | + }).then(response => { | ||
| 34 | + const res = response.data | ||
| 35 | + resolve(res) | ||
| 36 | + }).catch(error => { | ||
| 37 | + reject(error) | ||
| 38 | + }) | ||
| 39 | + }) | ||
| 40 | +} | ||
| 41 | + | ||
| 42 | +// 获取工单评价列表 | ||
| 43 | +export function listComplaintAppraise(params) { | ||
| 44 | + return new Promise((resolve, reject) => { | ||
| 45 | + request({ | ||
| 46 | + url: '/complaintAppraise.listComplaintAppraise', | ||
| 47 | + method: 'get', | ||
| 48 | + params: { | ||
| 49 | + ...params, | ||
| 50 | + communityId: getCommunityId() | ||
| 51 | + } | ||
| 52 | + }).then(response => { | ||
| 53 | + const res = response.data | ||
| 54 | + resolve(res) | ||
| 55 | + }).catch(error => { | ||
| 56 | + reject(error) | ||
| 57 | + }) | ||
| 58 | + }) | ||
| 59 | +} | ||
| 60 | + | ||
| 61 | +// 回复工单评价 | ||
| 62 | +export function replyComplaintAppraise(data) { | ||
| 63 | + return new Promise((resolve, reject) => { | ||
| 64 | + request({ | ||
| 65 | + url: '/complaintAppraise.replyComplaintAppraise', | ||
| 66 | + method: 'post', | ||
| 67 | + data: { | ||
| 68 | + ...data, | ||
| 69 | + communityId: getCommunityId() | ||
| 70 | + } | ||
| 71 | + }).then(response => { | ||
| 72 | + const res = response.data | ||
| 73 | + resolve(res) | ||
| 74 | + }).catch(error => { | ||
| 75 | + reject(error) | ||
| 76 | + }) | ||
| 77 | + }) | ||
| 78 | +} | ||
| 79 | + | ||
| 80 | +// 获取工单类型列表 | ||
| 81 | +export function listComplaintType(params) { | ||
| 82 | + return new Promise((resolve, reject) => { | ||
| 83 | + request({ | ||
| 84 | + url: '/complaintType.listComplaintType', | ||
| 85 | + method: 'get', | ||
| 86 | + params: { | ||
| 87 | + ...params, | ||
| 88 | + communityId: getCommunityId() | ||
| 89 | + } | ||
| 90 | + }).then(response => { | ||
| 91 | + const res = response.data | ||
| 92 | + resolve(res) | ||
| 93 | + }).catch(error => { | ||
| 94 | + reject(error) | ||
| 95 | + }) | ||
| 96 | + }) | ||
| 97 | +} | ||
| 0 | \ No newline at end of file | 98 | \ No newline at end of file |
src/api/oa/uodoComplaintsApi.js
0 → 100644
| 1 | +import request from '@/utils/request' | ||
| 2 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 3 | + | ||
| 4 | +// 获取待办投诉单列表 | ||
| 5 | +export function listAuditComplaints(params) { | ||
| 6 | + return new Promise((resolve, reject) => { | ||
| 7 | + request({ | ||
| 8 | + url: '/auditUser.listAuditComplaints', | ||
| 9 | + method: 'get', | ||
| 10 | + params: { | ||
| 11 | + ...params, | ||
| 12 | + communityId: getCommunityId() | ||
| 13 | + } | ||
| 14 | + }).then(response => { | ||
| 15 | + const res = response.data | ||
| 16 | + resolve(res) | ||
| 17 | + }).catch(error => { | ||
| 18 | + reject(error) | ||
| 19 | + }) | ||
| 20 | + }) | ||
| 21 | +} | ||
| 22 | + | ||
| 23 | +// 办理投诉单 | ||
| 24 | +export function auditComplaint(data) { | ||
| 25 | + return new Promise((resolve, reject) => { | ||
| 26 | + request({ | ||
| 27 | + url: '/complaint.auditComplaint', | ||
| 28 | + method: 'post', | ||
| 29 | + data: { | ||
| 30 | + ...data, | ||
| 31 | + communityId: getCommunityId() | ||
| 32 | + } | ||
| 33 | + }).then(response => { | ||
| 34 | + const res = response.data | ||
| 35 | + resolve(res) | ||
| 36 | + }).catch(error => { | ||
| 37 | + reject(error) | ||
| 38 | + }) | ||
| 39 | + }) | ||
| 40 | +} | ||
| 41 | + | ||
| 42 | +// 获取投诉单详情 | ||
| 43 | +export function getComplaintDetail(params) { | ||
| 44 | + return new Promise((resolve, reject) => { | ||
| 45 | + request({ | ||
| 46 | + url: '/complaint.getComplaint', | ||
| 47 | + method: 'get', | ||
| 48 | + params | ||
| 49 | + }).then(response => { | ||
| 50 | + const res = response.data | ||
| 51 | + resolve(res) | ||
| 52 | + }).catch(error => { | ||
| 53 | + reject(error) | ||
| 54 | + }) | ||
| 55 | + }) | ||
| 56 | +} | ||
| 0 | \ No newline at end of file | 57 | \ No newline at end of file |
src/components/oa/ComplaintDetailAppraise.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="complaint-detail-appraise"> | ||
| 3 | + <el-table | ||
| 4 | + :data="appraises" | ||
| 5 | + border | ||
| 6 | + style="width: 100%" | ||
| 7 | + v-loading="loading" | ||
| 8 | + > | ||
| 9 | + <el-table-column | ||
| 10 | + prop="createUserName" | ||
| 11 | + :label="$t('complaintDetailAppraise.userName')" | ||
| 12 | + align="center" | ||
| 13 | + /> | ||
| 14 | + <el-table-column | ||
| 15 | + prop="context" | ||
| 16 | + :label="$t('complaintDetailAppraise.content')" | ||
| 17 | + align="center" | ||
| 18 | + /> | ||
| 19 | + <el-table-column | ||
| 20 | + prop="score" | ||
| 21 | + :label="$t('complaintDetailAppraise.score')" | ||
| 22 | + align="center" | ||
| 23 | + /> | ||
| 24 | + <el-table-column | ||
| 25 | + prop="state" | ||
| 26 | + :label="$t('complaintDetailAppraise.status')" | ||
| 27 | + align="center" | ||
| 28 | + > | ||
| 29 | + <template slot-scope="scope"> | ||
| 30 | + <span>{{ scope.row.state === 'W' ? $t('complaintDetailAppraise.waitReply') : $t('complaintDetailAppraise.replied') }}</span> | ||
| 31 | + </template> | ||
| 32 | + </el-table-column> | ||
| 33 | + <el-table-column | ||
| 34 | + prop="createTime" | ||
| 35 | + :label="$t('complaintDetailAppraise.time')" | ||
| 36 | + align="center" | ||
| 37 | + /> | ||
| 38 | + <el-table-column | ||
| 39 | + prop="replyUserName" | ||
| 40 | + :label="$t('complaintDetailAppraise.replyUser')" | ||
| 41 | + align="center" | ||
| 42 | + /> | ||
| 43 | + <el-table-column | ||
| 44 | + prop="replyContext" | ||
| 45 | + :label="$t('complaintDetailAppraise.replyContent')" | ||
| 46 | + align="center" | ||
| 47 | + /> | ||
| 48 | + <el-table-column | ||
| 49 | + :label="$t('common.operation')" | ||
| 50 | + align="center" | ||
| 51 | + > | ||
| 52 | + <template slot-scope="scope"> | ||
| 53 | + <el-button | ||
| 54 | + v-if="scope.row.state === 'W'" | ||
| 55 | + type="text" | ||
| 56 | + size="small" | ||
| 57 | + @click="openReplyModal(scope.row)" | ||
| 58 | + > | ||
| 59 | + {{ $t('complaintDetailAppraise.reply') }} | ||
| 60 | + </el-button> | ||
| 61 | + </template> | ||
| 62 | + </el-table-column> | ||
| 63 | + </el-table> | ||
| 64 | + | ||
| 65 | + <reply-complaint-appraise | ||
| 66 | + ref="replyComplaintAppraise" | ||
| 67 | + @success="handleSuccess" | ||
| 68 | + /> | ||
| 69 | + </div> | ||
| 70 | +</template> | ||
| 71 | + | ||
| 72 | +<script> | ||
| 73 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 74 | +import { listComplaintAppraise } from '@/api/oa/complaintDetailApi' | ||
| 75 | +import ReplyComplaintAppraise from './ReplyComplaintAppraise' | ||
| 76 | + | ||
| 77 | +export default { | ||
| 78 | + name: 'ComplaintDetailAppraise', | ||
| 79 | + components: { | ||
| 80 | + ReplyComplaintAppraise | ||
| 81 | + }, | ||
| 82 | + data() { | ||
| 83 | + return { | ||
| 84 | + appraises: [], | ||
| 85 | + loading: false, | ||
| 86 | + complaintId: '', | ||
| 87 | + communityId: '' | ||
| 88 | + } | ||
| 89 | + }, | ||
| 90 | + methods: { | ||
| 91 | + async initData(params) { | ||
| 92 | + this.communityId = getCommunityId() | ||
| 93 | + this.complaintId = params.complaintId | ||
| 94 | + await this.loadData() | ||
| 95 | + }, | ||
| 96 | + async loadData() { | ||
| 97 | + try { | ||
| 98 | + this.loading = true | ||
| 99 | + const params = { | ||
| 100 | + communityId: this.communityId, | ||
| 101 | + complaintId: this.complaintId, | ||
| 102 | + page: 1, | ||
| 103 | + row: 100 | ||
| 104 | + } | ||
| 105 | + const { data } = await listComplaintAppraise(params) | ||
| 106 | + this.appraises = data || [] | ||
| 107 | + } catch (error) { | ||
| 108 | + console.error('获取工单评价数据失败:', error) | ||
| 109 | + } finally { | ||
| 110 | + this.loading = false | ||
| 111 | + } | ||
| 112 | + }, | ||
| 113 | + openReplyModal(row) { | ||
| 114 | + this.$refs.replyComplaintAppraise.open(row) | ||
| 115 | + }, | ||
| 116 | + handleSuccess() { | ||
| 117 | + this.loadData() | ||
| 118 | + } | ||
| 119 | + } | ||
| 120 | +} | ||
| 121 | +</script> | ||
| 122 | + | ||
| 123 | +<style lang="scss" scoped> | ||
| 124 | +.complaint-detail-appraise { | ||
| 125 | + margin-top: 20px; | ||
| 126 | +} | ||
| 127 | +</style> | ||
| 0 | \ No newline at end of file | 128 | \ No newline at end of file |
src/components/oa/ComplaintDetailEvent.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="complaint-detail-event"> | ||
| 3 | + <el-table :data="events" border style="width: 100%" v-loading="loading"> | ||
| 4 | + <el-table-column prop="eventType" :label="$t('complaintDetailEvent.type')" align="center"> | ||
| 5 | + <template slot-scope="scope"> | ||
| 6 | + <span v-if="scope.row.eventType === '1000'">{{ $t('complaintDetailEvent.submit') }}</span> | ||
| 7 | + <span v-else-if="scope.row.eventType === '1001'">{{ $t('complaintDetailEvent.process') }}</span> | ||
| 8 | + <span v-else-if="scope.row.eventType === '2002'">{{ $t('complaintDetailEvent.evaluate') }}</span> | ||
| 9 | + <span v-else>{{ $t('complaintDetailEvent.reply') }}</span> | ||
| 10 | + </template> | ||
| 11 | + </el-table-column> | ||
| 12 | + <el-table-column prop="createUserName" :label="$t('complaintDetailEvent.operator')" align="center" /> | ||
| 13 | + <el-table-column prop="remark" :label="$t('complaintDetailEvent.remark')" align="center" /> | ||
| 14 | + <el-table-column prop="createTime" :label="$t('complaintDetailEvent.time')" align="center" /> | ||
| 15 | + </el-table> | ||
| 16 | + </div> | ||
| 17 | +</template> | ||
| 18 | + | ||
| 19 | +<script> | ||
| 20 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 21 | +import { listComplaintEvent } from '@/api/oa/complaintDetailApi' | ||
| 22 | + | ||
| 23 | +export default { | ||
| 24 | + name: 'ComplaintDetailEvent', | ||
| 25 | + data() { | ||
| 26 | + return { | ||
| 27 | + events: [], | ||
| 28 | + loading: false, | ||
| 29 | + complaintId: '', | ||
| 30 | + communityId: '' | ||
| 31 | + } | ||
| 32 | + }, | ||
| 33 | + methods: { | ||
| 34 | + async initData(params) { | ||
| 35 | + this.communityId = getCommunityId() | ||
| 36 | + this.complaintId = params.complaintId | ||
| 37 | + await this.loadData() | ||
| 38 | + }, | ||
| 39 | + async loadData() { | ||
| 40 | + try { | ||
| 41 | + this.loading = true | ||
| 42 | + const params = { | ||
| 43 | + communityId: this.communityId, | ||
| 44 | + complaintId: this.complaintId, | ||
| 45 | + page: 1, | ||
| 46 | + row: 100 | ||
| 47 | + } | ||
| 48 | + const { data } = await listComplaintEvent(params) | ||
| 49 | + this.events = data || [] | ||
| 50 | + } catch (error) { | ||
| 51 | + console.error('获取工单流转数据失败:', error) | ||
| 52 | + } finally { | ||
| 53 | + this.loading = false | ||
| 54 | + } | ||
| 55 | + } | ||
| 56 | + } | ||
| 57 | +} | ||
| 58 | +</script> | ||
| 59 | + | ||
| 60 | +<style lang="scss" scoped> | ||
| 61 | +.complaint-detail-event { | ||
| 62 | + margin-top: 20px; | ||
| 63 | +} | ||
| 64 | +</style> | ||
| 0 | \ No newline at end of file | 65 | \ No newline at end of file |
src/components/oa/ComplaintDetailType.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="complaint-detail-type"> | ||
| 3 | + <el-table | ||
| 4 | + :data="complaintTypes" | ||
| 5 | + border | ||
| 6 | + style="width: 100%" | ||
| 7 | + v-loading="loading" | ||
| 8 | + > | ||
| 9 | + <el-table-column | ||
| 10 | + prop="typeName" | ||
| 11 | + :label="$t('complaintDetailType.typeName')" | ||
| 12 | + align="center" | ||
| 13 | + /> | ||
| 14 | + <el-table-column | ||
| 15 | + prop="notifyWay" | ||
| 16 | + :label="$t('complaintDetailType.notifyWay')" | ||
| 17 | + align="center" | ||
| 18 | + > | ||
| 19 | + <template slot-scope="scope"> | ||
| 20 | + <span>{{ scope.row.notifyWay === 'SMS' ? $t('complaintDetailType.sms') : $t('complaintDetailType.wechat') }}</span> | ||
| 21 | + </template> | ||
| 22 | + </el-table-column> | ||
| 23 | + <el-table-column | ||
| 24 | + prop="appraiseReply" | ||
| 25 | + :label="$t('complaintDetailType.appraiseReply')" | ||
| 26 | + align="center" | ||
| 27 | + > | ||
| 28 | + <template slot-scope="scope"> | ||
| 29 | + <span>{{ scope.row.appraiseReply === 'Y' ? $t('complaintDetailType.autoReply') : $t('complaintDetailType.manualReply') }}</span> | ||
| 30 | + </template> | ||
| 31 | + </el-table-column> | ||
| 32 | + <el-table-column | ||
| 33 | + :label="$t('complaintDetailType.handler')" | ||
| 34 | + align="center" | ||
| 35 | + > | ||
| 36 | + <template slot-scope="scope"> | ||
| 37 | + <div v-for="(item, index) in scope.row.staffs" :key="index"> | ||
| 38 | + {{ item.staffName }} | ||
| 39 | + </div> | ||
| 40 | + </template> | ||
| 41 | + </el-table-column> | ||
| 42 | + <el-table-column | ||
| 43 | + prop="createTime" | ||
| 44 | + :label="$t('complaintDetailType.createTime')" | ||
| 45 | + align="center" | ||
| 46 | + /> | ||
| 47 | + </el-table> | ||
| 48 | + </div> | ||
| 49 | +</template> | ||
| 50 | + | ||
| 51 | +<script> | ||
| 52 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 53 | +import { listComplaintType } from '@/api/oa/complaintDetailApi' | ||
| 54 | + | ||
| 55 | +export default { | ||
| 56 | + name: 'ComplaintDetailType', | ||
| 57 | + data() { | ||
| 58 | + return { | ||
| 59 | + complaintTypes: [], | ||
| 60 | + loading: false, | ||
| 61 | + typeCd: '', | ||
| 62 | + communityId: '' | ||
| 63 | + } | ||
| 64 | + }, | ||
| 65 | + methods: { | ||
| 66 | + async initData(params) { | ||
| 67 | + this.communityId = getCommunityId() | ||
| 68 | + this.typeCd = params.typeCd | ||
| 69 | + await this.loadData() | ||
| 70 | + }, | ||
| 71 | + async loadData() { | ||
| 72 | + try { | ||
| 73 | + this.loading = true | ||
| 74 | + const params = { | ||
| 75 | + communityId: this.communityId, | ||
| 76 | + typeCd: this.typeCd, | ||
| 77 | + page: 1, | ||
| 78 | + row: 100 | ||
| 79 | + } | ||
| 80 | + const { data } = await listComplaintType(params) | ||
| 81 | + this.complaintTypes = data || [] | ||
| 82 | + } catch (error) { | ||
| 83 | + console.error('获取工单类型数据失败:', error) | ||
| 84 | + } finally { | ||
| 85 | + this.loading = false | ||
| 86 | + } | ||
| 87 | + } | ||
| 88 | + } | ||
| 89 | +} | ||
| 90 | +</script> | ||
| 91 | + | ||
| 92 | +<style lang="scss" scoped> | ||
| 93 | +.complaint-detail-type { | ||
| 94 | + margin-top: 20px; | ||
| 95 | +} | ||
| 96 | +</style> | ||
| 0 | \ No newline at end of file | 97 | \ No newline at end of file |
src/components/oa/ReplyComplaintAppraise.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <el-dialog | ||
| 3 | + :title="$t('replyComplaintAppraise.title')" | ||
| 4 | + :visible.sync="visible" | ||
| 5 | + width="50%" | ||
| 6 | + @close="resetForm" | ||
| 7 | + > | ||
| 8 | + <el-form ref="form" :model="form" :rules="rules" label-width="120px"> | ||
| 9 | + <el-form-item :label="$t('replyComplaintAppraise.content')" prop="replyContext"> | ||
| 10 | + <el-input | ||
| 11 | + type="textarea" | ||
| 12 | + :rows="5" | ||
| 13 | + v-model="form.replyContext" | ||
| 14 | + :placeholder="$t('replyComplaintAppraise.placeholder')" | ||
| 15 | + /> | ||
| 16 | + </el-form-item> | ||
| 17 | + </el-form> | ||
| 18 | + | ||
| 19 | + <span slot="footer" class="dialog-footer"> | ||
| 20 | + <el-button @click="visible = false">{{ $t('common.cancel') }}</el-button> | ||
| 21 | + <el-button type="primary" @click="submitForm" :loading="submitting"> | ||
| 22 | + {{ $t('common.submit') }} | ||
| 23 | + </el-button> | ||
| 24 | + </span> | ||
| 25 | + </el-dialog> | ||
| 26 | +</template> | ||
| 27 | + | ||
| 28 | +<script> | ||
| 29 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 30 | +import { replyComplaintAppraise } from '@/api/oa/complaintDetailApi' | ||
| 31 | + | ||
| 32 | +export default { | ||
| 33 | + name: 'ReplyComplaintAppraise', | ||
| 34 | + data() { | ||
| 35 | + return { | ||
| 36 | + visible: false, | ||
| 37 | + submitting: false, | ||
| 38 | + form: { | ||
| 39 | + appraiseId: '', | ||
| 40 | + replyContext: '', | ||
| 41 | + communityId: '' | ||
| 42 | + }, | ||
| 43 | + rules: { | ||
| 44 | + replyContext: [ | ||
| 45 | + { required: true, message: this.$t('replyComplaintAppraise.required'), trigger: 'blur' }, | ||
| 46 | + { max: 512, message: this.$t('replyComplaintAppraise.maxLength'), trigger: 'blur' } | ||
| 47 | + ] | ||
| 48 | + } | ||
| 49 | + } | ||
| 50 | + }, | ||
| 51 | + methods: { | ||
| 52 | + open(row) { | ||
| 53 | + this.form.appraiseId = row.appraiseId | ||
| 54 | + this.form.communityId = getCommunityId() | ||
| 55 | + this.visible = true | ||
| 56 | + this.$nextTick(() => { | ||
| 57 | + this.$refs.form && this.$refs.form.clearValidate() | ||
| 58 | + }) | ||
| 59 | + }, | ||
| 60 | + async submitForm() { | ||
| 61 | + try { | ||
| 62 | + const valid = await this.$refs.form.validate() | ||
| 63 | + if (!valid) return | ||
| 64 | + | ||
| 65 | + this.submitting = true | ||
| 66 | + await replyComplaintAppraise(this.form) | ||
| 67 | + this.$message.success(this.$t('replyComplaintAppraise.success')) | ||
| 68 | + this.visible = false | ||
| 69 | + this.$emit('success') | ||
| 70 | + } catch (error) { | ||
| 71 | + console.error('回复评价失败:', error) | ||
| 72 | + } finally { | ||
| 73 | + this.submitting = false | ||
| 74 | + } | ||
| 75 | + }, | ||
| 76 | + resetForm() { | ||
| 77 | + this.form.replyContext = '' | ||
| 78 | + this.$refs.form && this.$refs.form.clearValidate() | ||
| 79 | + } | ||
| 80 | + } | ||
| 81 | +} | ||
| 82 | +</script> | ||
| 0 | \ No newline at end of file | 83 | \ No newline at end of file |
src/components/oa/doingComplaint.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <el-dialog | ||
| 3 | + :title="$t('doingComplaint.title')" | ||
| 4 | + :visible.sync="visible" | ||
| 5 | + width="60%" | ||
| 6 | + @close="handleClose" | ||
| 7 | + > | ||
| 8 | + <el-form ref="form" :model="formData" label-width="120px"> | ||
| 9 | + <el-form-item | ||
| 10 | + :label="$t('doingComplaint.description')" | ||
| 11 | + prop="context" | ||
| 12 | + :rules="[ | ||
| 13 | + { required: true, message: $t('doingComplaint.required'), trigger: 'blur' }, | ||
| 14 | + { max: 512, message: $t('doingComplaint.maxLength'), trigger: 'blur' } | ||
| 15 | + ]" | ||
| 16 | + > | ||
| 17 | + <el-input | ||
| 18 | + v-model="formData.context" | ||
| 19 | + type="textarea" | ||
| 20 | + :rows="4" | ||
| 21 | + :placeholder="$t('doingComplaint.placeholder')" | ||
| 22 | + /> | ||
| 23 | + </el-form-item> | ||
| 24 | + </el-form> | ||
| 25 | + | ||
| 26 | + <span slot="footer" class="dialog-footer"> | ||
| 27 | + <el-button @click="visible = false">{{ $t('doingComplaint.cancel') }}</el-button> | ||
| 28 | + <el-button type="primary" @click="handleSubmit">{{ $t('doingComplaint.submit') }}</el-button> | ||
| 29 | + </span> | ||
| 30 | + </el-dialog> | ||
| 31 | +</template> | ||
| 32 | + | ||
| 33 | +<script> | ||
| 34 | +import { auditComplaint } from '@/api/oa/uodoComplaintsApi' | ||
| 35 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 36 | + | ||
| 37 | +export default { | ||
| 38 | + name: 'DoingComplaint', | ||
| 39 | + data() { | ||
| 40 | + return { | ||
| 41 | + visible: false, | ||
| 42 | + formData: { | ||
| 43 | + complaintId: '', | ||
| 44 | + context: '', | ||
| 45 | + communityId: '' | ||
| 46 | + } | ||
| 47 | + } | ||
| 48 | + }, | ||
| 49 | + methods: { | ||
| 50 | + open(data) { | ||
| 51 | + this.formData.complaintId = data.complaintId | ||
| 52 | + this.formData.communityId = getCommunityId() | ||
| 53 | + this.visible = true | ||
| 54 | + this.$nextTick(() => { | ||
| 55 | + this.$refs.form && this.$refs.form.resetFields() | ||
| 56 | + }) | ||
| 57 | + }, | ||
| 58 | + handleClose() { | ||
| 59 | + this.$refs.form.resetFields() | ||
| 60 | + }, | ||
| 61 | + async handleSubmit() { | ||
| 62 | + try { | ||
| 63 | + const valid = await this.$refs.form.validate() | ||
| 64 | + if (!valid) return | ||
| 65 | + | ||
| 66 | + await auditComplaint(this.formData) | ||
| 67 | + this.$emit('success') | ||
| 68 | + this.visible = false | ||
| 69 | + this.$message.success(this.$t('doingComplaint.success')) | ||
| 70 | + } catch (error) { | ||
| 71 | + console.error(error) | ||
| 72 | + this.$message.error(this.$t('doingComplaint.error')) | ||
| 73 | + } | ||
| 74 | + } | ||
| 75 | + } | ||
| 76 | +} | ||
| 77 | +</script> | ||
| 78 | + | ||
| 79 | +<style scoped> | ||
| 80 | +.el-textarea { | ||
| 81 | + width: 100%; | ||
| 82 | +} | ||
| 83 | +</style> | ||
| 0 | \ No newline at end of file | 84 | \ No newline at end of file |
src/i18n/oaI18n.js
| @@ -50,6 +50,8 @@ import { messages as newOaWorkflowMessages } from '../views/oa/newOaWorkflowLang | @@ -50,6 +50,8 @@ import { messages as newOaWorkflowMessages } from '../views/oa/newOaWorkflowLang | ||
| 50 | import { messages as newOaWorkflowDetailMessages } from '../views/oa/newOaWorkflowDetailLang' | 50 | import { messages as newOaWorkflowDetailMessages } from '../views/oa/newOaWorkflowDetailLang' |
| 51 | import { messages as newOaWorkflowFormEditMessages } from '../views/oa/newOaWorkflowFormEditLang' | 51 | import { messages as newOaWorkflowFormEditMessages } from '../views/oa/newOaWorkflowFormEditLang' |
| 52 | import { messages as simplifyNotepadManageMessages } from '../views/oa/simplifyNotepadManageLang' | 52 | import { messages as simplifyNotepadManageMessages } from '../views/oa/simplifyNotepadManageLang' |
| 53 | +import { messages as uodoComplaintsMessages } from '../views/oa/uodoComplaintsLang' | ||
| 54 | +import { messages as complaintDetailMessages } from '../views/oa/complaintDetailLang' | ||
| 53 | 55 | ||
| 54 | 56 | ||
| 55 | export const messages ={ | 57 | export const messages ={ |
| @@ -105,6 +107,8 @@ export const messages ={ | @@ -105,6 +107,8 @@ export const messages ={ | ||
| 105 | ...newOaWorkflowDetailMessages.en, | 107 | ...newOaWorkflowDetailMessages.en, |
| 106 | ...newOaWorkflowFormEditMessages.en, | 108 | ...newOaWorkflowFormEditMessages.en, |
| 107 | ...simplifyNotepadManageMessages.en, | 109 | ...simplifyNotepadManageMessages.en, |
| 110 | + ...uodoComplaintsMessages.en, | ||
| 111 | + ...complaintDetailMessages.en, | ||
| 108 | }, | 112 | }, |
| 109 | zh:{ | 113 | zh:{ |
| 110 | ...activitiesTypeManageMessages.zh, | 114 | ...activitiesTypeManageMessages.zh, |
| @@ -158,5 +162,7 @@ export const messages ={ | @@ -158,5 +162,7 @@ export const messages ={ | ||
| 158 | ...newOaWorkflowDetailMessages.zh, | 162 | ...newOaWorkflowDetailMessages.zh, |
| 159 | ...newOaWorkflowFormEditMessages.zh, | 163 | ...newOaWorkflowFormEditMessages.zh, |
| 160 | ...simplifyNotepadManageMessages.zh, | 164 | ...simplifyNotepadManageMessages.zh, |
| 165 | + ...uodoComplaintsMessages.zh, | ||
| 166 | + ...complaintDetailMessages.zh, | ||
| 161 | } | 167 | } |
| 162 | } | 168 | } |
| 163 | \ No newline at end of file | 169 | \ No newline at end of file |
src/router/oaRouter.js
| @@ -239,4 +239,14 @@ export default [ | @@ -239,4 +239,14 @@ export default [ | ||
| 239 | name: '/pages/property/simplifyNotepadManage', | 239 | name: '/pages/property/simplifyNotepadManage', |
| 240 | component: () => import('@/views/oa/simplifyNotepadManageList.vue') | 240 | component: () => import('@/views/oa/simplifyNotepadManageList.vue') |
| 241 | }, | 241 | }, |
| 242 | + { | ||
| 243 | + path: '/pages/complaint/uodoComplaints', | ||
| 244 | + name: '/pages/complaint/uodoComplaints', | ||
| 245 | + component: () => import('@/views/oa/uodoComplaintsList.vue') | ||
| 246 | + }, | ||
| 247 | + { | ||
| 248 | + path: '/pages/complaint/complaintDetail', | ||
| 249 | + name: '/pages/complaint/complaintDetail', | ||
| 250 | + component: () => import('@/views/oa/complaintDetailList.vue') | ||
| 251 | + }, | ||
| 242 | ] | 252 | ] |
| 243 | \ No newline at end of file | 253 | \ No newline at end of file |
src/views/oa/complaintDetailLang.js
0 → 100644
| 1 | +export const messages = { | ||
| 2 | + en: { | ||
| 3 | + complaintDetail: { | ||
| 4 | + title: 'Complaint Details', | ||
| 5 | + workflow: 'Workflow', | ||
| 6 | + evaluation: 'Evaluation', | ||
| 7 | + type: 'Type' | ||
| 8 | + }, | ||
| 9 | + complaintDetailInfo: { | ||
| 10 | + orderNo: 'Order No:', | ||
| 11 | + type: 'Type:', | ||
| 12 | + house: 'House:', | ||
| 13 | + contact: 'Contact:', | ||
| 14 | + phone: 'Phone:', | ||
| 15 | + status: 'Status:', | ||
| 16 | + createTime: 'Create Time:', | ||
| 17 | + content: 'Content:' | ||
| 18 | + }, | ||
| 19 | + complaintDetailEvent: { | ||
| 20 | + type: 'Type', | ||
| 21 | + operator: 'Operator', | ||
| 22 | + remark: 'Remark', | ||
| 23 | + time: 'Time', | ||
| 24 | + submit: 'Submit', | ||
| 25 | + process: 'Process', | ||
| 26 | + evaluate: 'Evaluate', | ||
| 27 | + reply: 'Reply' | ||
| 28 | + }, | ||
| 29 | + complaintDetailAppraise: { | ||
| 30 | + userName: 'User Name', | ||
| 31 | + content: 'Content', | ||
| 32 | + score: 'Score', | ||
| 33 | + status: 'Status', | ||
| 34 | + time: 'Time', | ||
| 35 | + replyUser: 'Reply User', | ||
| 36 | + replyContent: 'Reply Content', | ||
| 37 | + operation: 'Operation', | ||
| 38 | + reply: 'Reply', | ||
| 39 | + waitReply: 'Wait Reply', | ||
| 40 | + replied: 'Replied' | ||
| 41 | + }, | ||
| 42 | + replyComplaintAppraise: { | ||
| 43 | + title: 'Reply Evaluation', | ||
| 44 | + content: 'Content', | ||
| 45 | + placeholder: 'Required, please enter reply content', | ||
| 46 | + required: 'Reply content is required', | ||
| 47 | + maxLength: 'Reply content exceeds 500 characters', | ||
| 48 | + success: 'Reply successfully' | ||
| 49 | + }, | ||
| 50 | + complaintDetailType: { | ||
| 51 | + typeName: 'Type Name', | ||
| 52 | + notifyWay: 'Notify Way', | ||
| 53 | + appraiseReply: 'Appraise Reply', | ||
| 54 | + handler: 'Handler', | ||
| 55 | + createTime: 'Create Time', | ||
| 56 | + sms: 'SMS', | ||
| 57 | + wechat: 'WeChat', | ||
| 58 | + autoReply: 'Auto Reply', | ||
| 59 | + manualReply: 'Manual Reply' | ||
| 60 | + } | ||
| 61 | + }, | ||
| 62 | + zh: { | ||
| 63 | + complaintDetail: { | ||
| 64 | + title: '投诉详情', | ||
| 65 | + workflow: '工单流转', | ||
| 66 | + evaluation: '工单评价', | ||
| 67 | + type: '工单类型' | ||
| 68 | + }, | ||
| 69 | + complaintDetailInfo: { | ||
| 70 | + orderNo: '订单编号:', | ||
| 71 | + type: '类型:', | ||
| 72 | + house: '房屋:', | ||
| 73 | + contact: '联系人:', | ||
| 74 | + phone: '联系电话:', | ||
| 75 | + status: '状态:', | ||
| 76 | + createTime: '创建时间:', | ||
| 77 | + content: '投诉内容:' | ||
| 78 | + }, | ||
| 79 | + complaintDetailEvent: { | ||
| 80 | + type: '类型', | ||
| 81 | + operator: '操作人', | ||
| 82 | + remark: '说明', | ||
| 83 | + time: '时间', | ||
| 84 | + submit: '提交', | ||
| 85 | + process: '投诉处理', | ||
| 86 | + evaluate: '评价', | ||
| 87 | + reply: '评价回复' | ||
| 88 | + }, | ||
| 89 | + complaintDetailAppraise: { | ||
| 90 | + userName: '用户名称', | ||
| 91 | + content: '评价内容', | ||
| 92 | + score: '评价得分', | ||
| 93 | + status: '评价状态', | ||
| 94 | + time: '评价时间', | ||
| 95 | + replyUser: '回复人', | ||
| 96 | + replyContent: '回复内容', | ||
| 97 | + operation: '操作', | ||
| 98 | + reply: '回复', | ||
| 99 | + waitReply: '待回复', | ||
| 100 | + replied: '已回复' | ||
| 101 | + }, | ||
| 102 | + replyComplaintAppraise: { | ||
| 103 | + title: '回复评价', | ||
| 104 | + content: '内容', | ||
| 105 | + placeholder: '必填,请填写回复内容', | ||
| 106 | + required: '回复内容不能为空', | ||
| 107 | + maxLength: '回复内容超过500个字', | ||
| 108 | + success: '回复成功' | ||
| 109 | + }, | ||
| 110 | + complaintDetailType: { | ||
| 111 | + typeName: '类型名称', | ||
| 112 | + notifyWay: '通知方式', | ||
| 113 | + appraiseReply: '评价回复', | ||
| 114 | + handler: '处理人', | ||
| 115 | + createTime: '创建时间', | ||
| 116 | + sms: '短信', | ||
| 117 | + wechat: '微信', | ||
| 118 | + autoReply: '自动回复', | ||
| 119 | + manualReply: '人工回复' | ||
| 120 | + } | ||
| 121 | + } | ||
| 122 | +} | ||
| 0 | \ No newline at end of file | 123 | \ No newline at end of file |
src/views/oa/complaintDetailList.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="complaint-detail-container"> | ||
| 3 | + <el-card class="box-card"> | ||
| 4 | + <div class="flex justify-between"> | ||
| 5 | + <div class="text-title">{{ $t('complaintDetail.title') }}</div> | ||
| 6 | + <div> | ||
| 7 | + <el-button type="primary" size="small" style="margin-left:10px" @click="goBack"> | ||
| 8 | + {{ $t('common.back') }} | ||
| 9 | + </el-button> | ||
| 10 | + </div> | ||
| 11 | + </div> | ||
| 12 | + | ||
| 13 | + <!-- 业主信息 --> | ||
| 14 | + <div class="margin-top"> | ||
| 15 | + <el-row :gutter="20" class="text-left"> | ||
| 16 | + <el-col :span="24"> | ||
| 17 | + <el-row :gutter="20"> | ||
| 18 | + <el-col :span="6"> | ||
| 19 | + <div class="form-group"> | ||
| 20 | + <label class="col-form-label"> | ||
| 21 | + {{ $t('complaintDetailInfo.orderNo') }} | ||
| 22 | + </label> | ||
| 23 | + <label class="">{{complaintDetailInfo.complaintId}}</label> | ||
| 24 | + </div> | ||
| 25 | + </el-col> | ||
| 26 | + <el-col :span="6"> | ||
| 27 | + <div class="form-group"> | ||
| 28 | + <label class="col-form-label"> | ||
| 29 | + {{ $t('complaintDetailInfo.type') }} | ||
| 30 | + </label> | ||
| 31 | + <label class="">{{complaintDetailInfo.typeName}}</label> | ||
| 32 | + </div> | ||
| 33 | + </el-col> | ||
| 34 | + <el-col :span="6"> | ||
| 35 | + <div class="form-group"> | ||
| 36 | + <label class="col-form-label"> | ||
| 37 | + {{ $t('complaintDetailInfo.house') }} | ||
| 38 | + </label> | ||
| 39 | + <label class=""> | ||
| 40 | + {{complaintDetailInfo.roomName}} | ||
| 41 | + </label> | ||
| 42 | + </div> | ||
| 43 | + </el-col> | ||
| 44 | + <el-col :span="6"> | ||
| 45 | + <div class="form-group"> | ||
| 46 | + <label class="col-form-label"> | ||
| 47 | + {{ $t('complaintDetailInfo.contact') }} | ||
| 48 | + </label> | ||
| 49 | + <label class="">{{complaintDetailInfo.complaintName}}</label> | ||
| 50 | + </div> | ||
| 51 | + </el-col> | ||
| 52 | + </el-row> | ||
| 53 | + <el-row :gutter="20"> | ||
| 54 | + <el-col :span="6"> | ||
| 55 | + <div class="form-group"> | ||
| 56 | + <label class="col-form-label"> | ||
| 57 | + {{ $t('complaintDetailInfo.phone') }} | ||
| 58 | + </label> | ||
| 59 | + <label class="">{{complaintDetailInfo.tel}}</label> | ||
| 60 | + </div> | ||
| 61 | + </el-col> | ||
| 62 | + <el-col :span="6"> | ||
| 63 | + <div class="form-group"> | ||
| 64 | + <label class="col-form-label"> | ||
| 65 | + {{ $t('complaintDetailInfo.status') }} | ||
| 66 | + </label> | ||
| 67 | + <label class="">{{complaintDetailInfo.stateName}}</label> | ||
| 68 | + </div> | ||
| 69 | + </el-col> | ||
| 70 | + <el-col :span="12"> | ||
| 71 | + <div class="form-group"> | ||
| 72 | + <label class="col-form-label"> | ||
| 73 | + {{ $t('complaintDetailInfo.createTime') }} | ||
| 74 | + </label> | ||
| 75 | + <label class="">{{complaintDetailInfo.createTime}}</label> | ||
| 76 | + </div> | ||
| 77 | + </el-col> | ||
| 78 | + <el-col :span="24"> | ||
| 79 | + <div class="form-group"> | ||
| 80 | + <label class="col-form-label"> | ||
| 81 | + {{ $t('complaintDetailInfo.content') }} | ||
| 82 | + </label> | ||
| 83 | + <label class="">{{complaintDetailInfo.context}}</label> | ||
| 84 | + </div> | ||
| 85 | + </el-col> | ||
| 86 | + </el-row> | ||
| 87 | + </el-col> | ||
| 88 | + </el-row> | ||
| 89 | + </div> | ||
| 90 | + | ||
| 91 | + <divider></divider> | ||
| 92 | + | ||
| 93 | + <div class="margin-top-sm"> | ||
| 94 | + <el-tabs v-model="complaintDetailInfo._currentTab" @tab-click="changeTab(complaintDetailInfo._currentTab)"> | ||
| 95 | + <el-tab-pane :label="$t('complaintDetail.workflow')" name="complaintDetailEvent"> | ||
| 96 | + <complaint-detail-event v-if="complaintDetailInfo._currentTab === 'complaintDetailEvent'" | ||
| 97 | + ref="complaintDetailEvent" /> | ||
| 98 | + </el-tab-pane> | ||
| 99 | + <el-tab-pane :label="$t('complaintDetail.evaluation')" name="complaintDetailAppraise"> | ||
| 100 | + <complaint-detail-appraise v-if="complaintDetailInfo._currentTab === 'complaintDetailAppraise'" | ||
| 101 | + ref="complaintDetailAppraise" /> | ||
| 102 | + </el-tab-pane> | ||
| 103 | + <el-tab-pane :label="$t('complaintDetail.type')" name="complaintDetailType"> | ||
| 104 | + <complaint-detail-type v-if="complaintDetailInfo._currentTab === 'complaintDetailType'" | ||
| 105 | + ref="complaintDetailType" /> | ||
| 106 | + </el-tab-pane> | ||
| 107 | + </el-tabs> | ||
| 108 | + </div> | ||
| 109 | + </el-card> | ||
| 110 | + </div> | ||
| 111 | +</template> | ||
| 112 | + | ||
| 113 | +<script> | ||
| 114 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 115 | +import ComplaintDetailEvent from '@/components/oa/ComplaintDetailEvent' | ||
| 116 | +import ComplaintDetailAppraise from '@/components/oa/ComplaintDetailAppraise' | ||
| 117 | +import ComplaintDetailType from '@/components/oa/ComplaintDetailType' | ||
| 118 | +import { getComplaintDetail } from '@/api/oa/complaintDetailApi' | ||
| 119 | +import divider from '@/components/system/divider' | ||
| 120 | + | ||
| 121 | +export default { | ||
| 122 | + name: 'ComplaintDetailList', | ||
| 123 | + components: { | ||
| 124 | + ComplaintDetailEvent, | ||
| 125 | + ComplaintDetailAppraise, | ||
| 126 | + ComplaintDetailType, | ||
| 127 | + divider | ||
| 128 | + }, | ||
| 129 | + data() { | ||
| 130 | + return { | ||
| 131 | + complaintDetailInfo: { | ||
| 132 | + viewComplaintFlag: '', | ||
| 133 | + complaintId: "", | ||
| 134 | + typeName: '', | ||
| 135 | + typeCd: '', | ||
| 136 | + roomName: "", | ||
| 137 | + complaintName: "", | ||
| 138 | + tel: "", | ||
| 139 | + stateName: "", | ||
| 140 | + createTime: "", | ||
| 141 | + context: '', | ||
| 142 | + _currentTab: 'complaintDetailEvent', | ||
| 143 | + }, | ||
| 144 | + communityId: '' | ||
| 145 | + } | ||
| 146 | + }, | ||
| 147 | + created() { | ||
| 148 | + this.communityId = getCommunityId() | ||
| 149 | + this.complaintDetailInfo.complaintId = this.$route.query.complaintId | ||
| 150 | + if (!this.complaintDetailInfo.complaintId) { | ||
| 151 | + return | ||
| 152 | + } | ||
| 153 | + const currentTab = this.$route.query.currentTab | ||
| 154 | + if (currentTab) { | ||
| 155 | + this.complaintDetailInfo._currentTab = currentTab | ||
| 156 | + } | ||
| 157 | + this.loadComplaintInfo() | ||
| 158 | + }, | ||
| 159 | + methods: { | ||
| 160 | + async loadComplaintInfo() { | ||
| 161 | + try { | ||
| 162 | + const params = { | ||
| 163 | + complaintId: this.complaintDetailInfo.complaintId, | ||
| 164 | + page: 1, | ||
| 165 | + row: 1, | ||
| 166 | + communityId: this.communityId, | ||
| 167 | + ownerTypeCd: '1001' | ||
| 168 | + } | ||
| 169 | + const { data } = await getComplaintDetail(params) | ||
| 170 | + if (data && data.length > 0) { | ||
| 171 | + Object.assign(this.complaintDetailInfo, data[0]) | ||
| 172 | + } | ||
| 173 | + } catch (error) { | ||
| 174 | + console.error('获取投诉详情失败:', error) | ||
| 175 | + } | ||
| 176 | + }, | ||
| 177 | + changeTab(tab) { | ||
| 178 | + this.complaintDetailInfo._currentTab = tab | ||
| 179 | + setTimeout(() => { | ||
| 180 | + if (this.$refs[tab]) { | ||
| 181 | + this.$refs[tab].initData({ | ||
| 182 | + complaintId: this.complaintDetailInfo.complaintId, | ||
| 183 | + typeCd: this.complaintDetailInfo.typeCd | ||
| 184 | + }) | ||
| 185 | + } | ||
| 186 | + }, 500) | ||
| 187 | + }, | ||
| 188 | + goBack() { | ||
| 189 | + this.$router.go(-1) | ||
| 190 | + } | ||
| 191 | + } | ||
| 192 | +} | ||
| 193 | +</script> | ||
| 194 | + | ||
| 195 | +<style lang="scss" scoped> | ||
| 196 | +.complaint-detail-container { | ||
| 197 | + padding: 20px; | ||
| 198 | + | ||
| 199 | + .box-card { | ||
| 200 | + padding: 20px; | ||
| 201 | + } | ||
| 202 | + | ||
| 203 | + .text-title { | ||
| 204 | + font-size: 18px; | ||
| 205 | + font-weight: bold; | ||
| 206 | + color: #333; | ||
| 207 | + } | ||
| 208 | + | ||
| 209 | + .margin-top { | ||
| 210 | + margin-top: 20px; | ||
| 211 | + } | ||
| 212 | + | ||
| 213 | + .margin-top-sm { | ||
| 214 | + margin-top: 10px; | ||
| 215 | + } | ||
| 216 | + | ||
| 217 | + .form-group { | ||
| 218 | + margin-bottom: 15px; | ||
| 219 | + | ||
| 220 | + .col-form-label { | ||
| 221 | + margin-bottom: 5px; | ||
| 222 | + color: #606266; | ||
| 223 | + } | ||
| 224 | + } | ||
| 225 | +} | ||
| 226 | +</style> | ||
| 0 | \ No newline at end of file | 227 | \ No newline at end of file |
src/views/oa/complaintList.vue
| @@ -204,7 +204,7 @@ export default { | @@ -204,7 +204,7 @@ export default { | ||
| 204 | this.$refs.deleteComplaint.open(row) | 204 | this.$refs.deleteComplaint.open(row) |
| 205 | }, | 205 | }, |
| 206 | _openComplaintDetailModel(row) { | 206 | _openComplaintDetailModel(row) { |
| 207 | - this.$refs.complaintDetail.open(row) | 207 | + this.$router.push(`/pages/complaint/complaintDetail?complaintId=${row.complaintId}`) |
| 208 | }, | 208 | }, |
| 209 | _queryComplaintMethod() { | 209 | _queryComplaintMethod() { |
| 210 | this.page.current = 1 | 210 | this.page.current = 1 |
src/views/oa/uodoComplaintsLang.js
0 → 100644
| 1 | +export const messages = { | ||
| 2 | + en: { | ||
| 3 | + uodoComplaints: { | ||
| 4 | + title: 'Pending Complaints', | ||
| 5 | + back: 'Back', | ||
| 6 | + refresh: 'Refresh', | ||
| 7 | + orderNumber: 'Order Number', | ||
| 8 | + complaintType: 'Complaint Type', | ||
| 9 | + house: 'House', | ||
| 10 | + complainant: 'Complainant', | ||
| 11 | + complaintPhone: 'Complaint Phone', | ||
| 12 | + complaintStatus: 'Complaint Status', | ||
| 13 | + createTime: 'Create Time', | ||
| 14 | + operation: 'Operation', | ||
| 15 | + process: 'Process', | ||
| 16 | + detail: 'Detail', | ||
| 17 | + fetchError: 'Failed to fetch complaints data' | ||
| 18 | + }, | ||
| 19 | + doingComplaint: { | ||
| 20 | + title: 'Process Complaint', | ||
| 21 | + description: 'Description', | ||
| 22 | + required: 'Required, please fill in the reply content', | ||
| 23 | + maxLength: 'Reply content exceeds 500 characters', | ||
| 24 | + placeholder: 'Required, please fill in the reply content', | ||
| 25 | + cancel: 'Cancel', | ||
| 26 | + submit: 'Submit', | ||
| 27 | + success: 'Processed successfully', | ||
| 28 | + error: 'Failed to process complaint' | ||
| 29 | + } | ||
| 30 | + }, | ||
| 31 | + zh: { | ||
| 32 | + uodoComplaints: { | ||
| 33 | + title: '待办投诉单', | ||
| 34 | + back: '返回', | ||
| 35 | + refresh: '刷新', | ||
| 36 | + orderNumber: '订单编号', | ||
| 37 | + complaintType: '投诉类型', | ||
| 38 | + house: '房屋', | ||
| 39 | + complainant: '投诉人', | ||
| 40 | + complaintPhone: '投诉电话', | ||
| 41 | + complaintStatus: '投诉状态', | ||
| 42 | + createTime: '创建时间', | ||
| 43 | + operation: '操作', | ||
| 44 | + process: '办理', | ||
| 45 | + detail: '详情', | ||
| 46 | + fetchError: '获取投诉数据失败' | ||
| 47 | + }, | ||
| 48 | + doingComplaint: { | ||
| 49 | + title: '办理投诉', | ||
| 50 | + description: '说明', | ||
| 51 | + required: '必填,请填写回复内容', | ||
| 52 | + maxLength: '回复内容超过500个字', | ||
| 53 | + placeholder: '必填,请填写回复内容', | ||
| 54 | + cancel: '取消', | ||
| 55 | + submit: '提交', | ||
| 56 | + success: '办理成功', | ||
| 57 | + error: '办理投诉失败' | ||
| 58 | + } | ||
| 59 | + } | ||
| 60 | +} | ||
| 0 | \ No newline at end of file | 61 | \ No newline at end of file |
src/views/oa/uodoComplaintsList.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="uodo-complaints-container animated fadeInRight"> | ||
| 3 | + <el-card class="box-card"> | ||
| 4 | + <div slot="header" class="flex justify-between "> | ||
| 5 | + <span>{{ $t('uodoComplaints.title') }}</span> | ||
| 6 | + <div class="card-header-actions"> | ||
| 7 | + <el-button size="small" @click="handleGoBack">{{ $t('uodoComplaints.back') }}</el-button> | ||
| 8 | + <el-button type="primary" size="small" @click="handleRefresh">{{ $t('uodoComplaints.refresh') }}</el-button> | ||
| 9 | + </div> | ||
| 10 | + </div> | ||
| 11 | + | ||
| 12 | + <el-table v-loading="loading" :data="tableData" border style="width: 100%"> | ||
| 13 | + <el-table-column prop="complaintId" :label="$t('uodoComplaints.orderNumber')" align="center" /> | ||
| 14 | + <el-table-column prop="typeName" :label="$t('uodoComplaints.complaintType')" align="center" /> | ||
| 15 | + <el-table-column prop="roomName" :label="$t('uodoComplaints.house')" align="center" /> | ||
| 16 | + <el-table-column prop="complaintName" :label="$t('uodoComplaints.complainant')" align="center" /> | ||
| 17 | + <el-table-column prop="tel" :label="$t('uodoComplaints.complaintPhone')" align="center" /> | ||
| 18 | + <el-table-column prop="stateName" :label="$t('uodoComplaints.complaintStatus')" align="center" /> | ||
| 19 | + <el-table-column prop="createTime" :label="$t('uodoComplaints.createTime')" align="center" /> | ||
| 20 | + <el-table-column :label="$t('uodoComplaints.operation')" align="center" width="180"> | ||
| 21 | + <template slot-scope="scope"> | ||
| 22 | + <el-button-group> | ||
| 23 | + <el-button size="mini" @click="handleProcess(scope.row)">{{ $t('uodoComplaints.process') }}</el-button> | ||
| 24 | + <el-button size="mini" @click="handleDetail(scope.row)">{{ $t('uodoComplaints.detail') }}</el-button> | ||
| 25 | + </el-button-group> | ||
| 26 | + </template> | ||
| 27 | + </el-table-column> | ||
| 28 | + </el-table> | ||
| 29 | + | ||
| 30 | + <el-pagination :current-page="pagination.currentPage" :page-sizes="[10, 20, 30, 50]" | ||
| 31 | + :page-size="pagination.pageSize" :total="pagination.total" layout="total, sizes, prev, pager, next, jumper" | ||
| 32 | + @size-change="handleSizeChange" @current-change="handleCurrentChange" /> | ||
| 33 | + </el-card> | ||
| 34 | + | ||
| 35 | + <doing-complaint ref="doingComplaint" @success="handleSuccess" /> | ||
| 36 | + </div> | ||
| 37 | +</template> | ||
| 38 | + | ||
| 39 | +<script> | ||
| 40 | +import { listAuditComplaints } from '@/api/oa/uodoComplaintsApi' | ||
| 41 | +import DoingComplaint from '@/components/oa/doingComplaint' | ||
| 42 | +import { getCommunityId } from '@/api/community/communityApi' | ||
| 43 | + | ||
| 44 | +export default { | ||
| 45 | + name: 'UodoComplaintsList', | ||
| 46 | + components: { | ||
| 47 | + DoingComplaint | ||
| 48 | + }, | ||
| 49 | + data() { | ||
| 50 | + return { | ||
| 51 | + loading: false, | ||
| 52 | + tableData: [], | ||
| 53 | + pagination: { | ||
| 54 | + currentPage: 1, | ||
| 55 | + pageSize: 10, | ||
| 56 | + total: 0 | ||
| 57 | + }, | ||
| 58 | + conditions: { | ||
| 59 | + communityId: '', | ||
| 60 | + userName: '', | ||
| 61 | + auditLink: '' | ||
| 62 | + } | ||
| 63 | + } | ||
| 64 | + }, | ||
| 65 | + created() { | ||
| 66 | + this.communityId = getCommunityId() | ||
| 67 | + this.getList() | ||
| 68 | + }, | ||
| 69 | + methods: { | ||
| 70 | + async getList() { | ||
| 71 | + try { | ||
| 72 | + this.loading = true | ||
| 73 | + const params = { | ||
| 74 | + page: this.pagination.currentPage, | ||
| 75 | + row: this.pagination.pageSize, | ||
| 76 | + communityId: this.communityId, | ||
| 77 | + ...this.conditions | ||
| 78 | + } | ||
| 79 | + const { data, total } = await listAuditComplaints(params) | ||
| 80 | + this.tableData = data | ||
| 81 | + this.pagination.total = total | ||
| 82 | + } catch (error) { | ||
| 83 | + this.$message.error(this.$t('uodoComplaints.fetchError')) | ||
| 84 | + } finally { | ||
| 85 | + this.loading = false | ||
| 86 | + } | ||
| 87 | + }, | ||
| 88 | + handleGoBack() { | ||
| 89 | + this.$router.go(-1) | ||
| 90 | + }, | ||
| 91 | + handleRefresh() { | ||
| 92 | + this.pagination.currentPage = 1 | ||
| 93 | + this.getList() | ||
| 94 | + }, | ||
| 95 | + handleProcess(row) { | ||
| 96 | + this.$refs.doingComplaint.open(row) | ||
| 97 | + }, | ||
| 98 | + handleDetail(row) { | ||
| 99 | + this.$router.push(`/pages/complaint/complaintDetail?complaintId=${row.complaintId}`) | ||
| 100 | + }, | ||
| 101 | + handleSuccess() { | ||
| 102 | + this.getList() | ||
| 103 | + }, | ||
| 104 | + handleSizeChange(val) { | ||
| 105 | + this.pagination.pageSize = val | ||
| 106 | + this.getList() | ||
| 107 | + }, | ||
| 108 | + handleCurrentChange(val) { | ||
| 109 | + this.pagination.currentPage = val | ||
| 110 | + this.getList() | ||
| 111 | + } | ||
| 112 | + } | ||
| 113 | +} | ||
| 114 | +</script> | ||
| 115 | + | ||
| 116 | +<style lang="scss" scoped> | ||
| 117 | +.uodo-complaints-container { | ||
| 118 | + padding: 20px; | ||
| 119 | + | ||
| 120 | + .box-card { | ||
| 121 | + margin-bottom: 20px; | ||
| 122 | + } | ||
| 123 | + | ||
| 124 | + .card-header-actions { | ||
| 125 | + float: right; | ||
| 126 | + } | ||
| 127 | + | ||
| 128 | + .el-pagination { | ||
| 129 | + margin-top: 20px; | ||
| 130 | + text-align: right; | ||
| 131 | + } | ||
| 132 | +} | ||
| 133 | +</style> | ||
| 0 | \ No newline at end of file | 134 | \ No newline at end of file |