Commit 1f3f7892ac15b1ab7ae9270eae4217417c8c6c32
1 parent
dedd9ade
开发完成admin 系统小区公众号
Showing
11 changed files
with
1140 additions
and
7 deletions
src/api/community/communityMiniApi.js
0 → 100644
| 1 | +import request from '@/utils/request' | ||
| 2 | + | ||
| 3 | +// 查询管理员小区列表 | ||
| 4 | +export function listAdminCommunitys(params) { | ||
| 5 | + return new Promise((resolve, reject) => { | ||
| 6 | + request({ | ||
| 7 | + url: '/community.listAdminCommunitys', | ||
| 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 || '获取小区列表失败')) | ||
| 16 | + } | ||
| 17 | + }).catch(error => { | ||
| 18 | + reject(error) | ||
| 19 | + }) | ||
| 20 | + }) | ||
| 21 | +} | ||
| 22 | + | ||
| 23 | +// 查询小程序列表 | ||
| 24 | +export function listAdminSmallWeChats(params) { | ||
| 25 | + return new Promise((resolve, reject) => { | ||
| 26 | + request({ | ||
| 27 | + url: '/smallWeChat.listAdminSmallWeChats', | ||
| 28 | + method: 'get', | ||
| 29 | + params | ||
| 30 | + }).then(response => { | ||
| 31 | + const res = response.data | ||
| 32 | + if (res.code === 0) { | ||
| 33 | + resolve(res) | ||
| 34 | + } else { | ||
| 35 | + reject(new Error(res.msg || '获取小程序列表失败')) | ||
| 36 | + } | ||
| 37 | + }).catch(error => { | ||
| 38 | + reject(error) | ||
| 39 | + }) | ||
| 40 | + }) | ||
| 41 | +} | ||
| 42 | + | ||
| 43 | +// 添加小程序 | ||
| 44 | +export function saveAdminSmallWeChat(data) { | ||
| 45 | + return new Promise((resolve, reject) => { | ||
| 46 | + request({ | ||
| 47 | + url: '/smallWeChat.saveAdminSmallWeChat', | ||
| 48 | + method: 'post', | ||
| 49 | + data | ||
| 50 | + }).then(response => { | ||
| 51 | + const res = response.data | ||
| 52 | + if (res.code === 0) { | ||
| 53 | + resolve(res) | ||
| 54 | + } else { | ||
| 55 | + reject(new Error(res.msg || '添加小程序失败')) | ||
| 56 | + } | ||
| 57 | + }).catch(error => { | ||
| 58 | + reject(error) | ||
| 59 | + }) | ||
| 60 | + }) | ||
| 61 | +} | ||
| 62 | + | ||
| 63 | +// 更新小程序 | ||
| 64 | +export function updateAdminSmallWeChat(data) { | ||
| 65 | + return new Promise((resolve, reject) => { | ||
| 66 | + request({ | ||
| 67 | + url: '/smallWeChat.updateAdminSmallWeChat', | ||
| 68 | + method: 'post', | ||
| 69 | + data | ||
| 70 | + }).then(response => { | ||
| 71 | + const res = response.data | ||
| 72 | + if (res.code === 0) { | ||
| 73 | + resolve(res) | ||
| 74 | + } else { | ||
| 75 | + reject(new Error(res.msg || '更新小程序失败')) | ||
| 76 | + } | ||
| 77 | + }).catch(error => { | ||
| 78 | + reject(error) | ||
| 79 | + }) | ||
| 80 | + }) | ||
| 81 | +} | ||
| 0 | \ No newline at end of file | 82 | \ No newline at end of file |
src/api/fee/communityPaymentApi.js
0 → 100644
| 1 | +import request from '@/utils/request' | ||
| 2 | + | ||
| 3 | +// 获取小区支付列表 | ||
| 4 | +export function listAdminPayment(params) { | ||
| 5 | + return new Promise((resolve, reject) => { | ||
| 6 | + request({ | ||
| 7 | + url: '/payment.listAdminPayment', | ||
| 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 || '获取小区支付列表失败')) | ||
| 16 | + } | ||
| 17 | + }).catch(error => { | ||
| 18 | + reject(error) | ||
| 19 | + }) | ||
| 20 | + }) | ||
| 21 | +} | ||
| 22 | + | ||
| 23 | +// 保存支付配置 | ||
| 24 | +export function saveAdminPaymentPool(data) { | ||
| 25 | + return new Promise((resolve, reject) => { | ||
| 26 | + request({ | ||
| 27 | + url: '/payment.saveAdminPaymentPool', | ||
| 28 | + method: 'post', | ||
| 29 | + data | ||
| 30 | + }).then(response => { | ||
| 31 | + const res = response.data | ||
| 32 | + if (res.code == 0) { | ||
| 33 | + resolve(res) | ||
| 34 | + } else { | ||
| 35 | + reject(new Error(res.msg || '保存支付配置失败')) | ||
| 36 | + } | ||
| 37 | + }).catch(error => { | ||
| 38 | + reject(error) | ||
| 39 | + }) | ||
| 40 | + }) | ||
| 41 | +} | ||
| 42 | + | ||
| 43 | +// 更新支付配置 | ||
| 44 | +export function updateAdminPaymentPool(data) { | ||
| 45 | + return new Promise((resolve, reject) => { | ||
| 46 | + request({ | ||
| 47 | + url: '/payment.updateAdminPaymentPool', | ||
| 48 | + method: 'post', | ||
| 49 | + data | ||
| 50 | + }).then(response => { | ||
| 51 | + const res = response.data | ||
| 52 | + if (res.code == 0) { | ||
| 53 | + resolve(res) | ||
| 54 | + } else { | ||
| 55 | + reject(new Error(res.msg || '更新支付配置失败')) | ||
| 56 | + } | ||
| 57 | + }).catch(error => { | ||
| 58 | + reject(error) | ||
| 59 | + }) | ||
| 60 | + }) | ||
| 61 | +} | ||
| 62 | + | ||
| 63 | +// 删除支付配置 | ||
| 64 | +export function deleteAdminPaymentPool(data) { | ||
| 65 | + return new Promise((resolve, reject) => { | ||
| 66 | + request({ | ||
| 67 | + url: '/payment.deleteAdminPaymentPool', | ||
| 68 | + method: 'post', | ||
| 69 | + data | ||
| 70 | + }).then(response => { | ||
| 71 | + const res = response.data | ||
| 72 | + if (res.code == 0) { | ||
| 73 | + resolve(res) | ||
| 74 | + } else { | ||
| 75 | + reject(new Error(res.msg || '删除支付配置失败')) | ||
| 76 | + } | ||
| 77 | + }).catch(error => { | ||
| 78 | + reject(error) | ||
| 79 | + }) | ||
| 80 | + }) | ||
| 81 | +} | ||
| 82 | + | ||
| 83 | +// 获取支付厂商列表 | ||
| 84 | +export function listPaymentAdapt(params) { | ||
| 85 | + return new Promise((resolve, reject) => { | ||
| 86 | + request({ | ||
| 87 | + url: '/payment.listPaymentAdapt', | ||
| 88 | + method: 'get', | ||
| 89 | + params | ||
| 90 | + }).then(response => { | ||
| 91 | + const res = response.data | ||
| 92 | + if (res.code == 0) { | ||
| 93 | + resolve(res) | ||
| 94 | + } else { | ||
| 95 | + reject(new Error(res.msg || '获取支付厂商列表失败')) | ||
| 96 | + } | ||
| 97 | + }).catch(error => { | ||
| 98 | + reject(error) | ||
| 99 | + }) | ||
| 100 | + }) | ||
| 101 | +} | ||
| 102 | + | ||
| 103 | +// 获取支付密钥列表 | ||
| 104 | +export function listPaymentKey(params) { | ||
| 105 | + return new Promise((resolve, reject) => { | ||
| 106 | + request({ | ||
| 107 | + url: '/payment.listPaymentKey', | ||
| 108 | + method: 'get', | ||
| 109 | + params | ||
| 110 | + }).then(response => { | ||
| 111 | + const res = response.data | ||
| 112 | + if (res.code == 0) { | ||
| 113 | + resolve(res) | ||
| 114 | + } else { | ||
| 115 | + reject(new Error(res.msg || '获取支付密钥列表失败')) | ||
| 116 | + } | ||
| 117 | + }).catch(error => { | ||
| 118 | + reject(error) | ||
| 119 | + }) | ||
| 120 | + }) | ||
| 121 | +} | ||
| 122 | + | ||
| 123 | +// 获取费用项列表 | ||
| 124 | +export function queryAdminFeeConfigs(params) { | ||
| 125 | + return new Promise((resolve, reject) => { | ||
| 126 | + request({ | ||
| 127 | + url: '/feeConfig.queryAdminFeeConfigs', | ||
| 128 | + method: 'get', | ||
| 129 | + params | ||
| 130 | + }).then(response => { | ||
| 131 | + const res = response.data | ||
| 132 | + if (res.code == 0) { | ||
| 133 | + resolve(res) | ||
| 134 | + } else { | ||
| 135 | + reject(new Error(res.msg || '获取费用项列表失败')) | ||
| 136 | + } | ||
| 137 | + }).catch(error => { | ||
| 138 | + reject(error) | ||
| 139 | + }) | ||
| 140 | + }) | ||
| 141 | +} | ||
| 0 | \ No newline at end of file | 142 | \ No newline at end of file |
src/components/fee/AddCommunityPayment.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <el-dialog :title="$t('addCommunityPayment.title')" :visible.sync="visible" width="800px" @closed="resetForm"> | ||
| 3 | + <el-form ref="form" :model="form" label-width="120px" :rules="rules"> | ||
| 4 | + <el-form-item :label="$t('communityPayment.paymentName')" prop="paymentName"> | ||
| 5 | + <el-input v-model="form.paymentName" :placeholder="$t('addCommunityPayment.namePlaceholder')" /> | ||
| 6 | + </el-form-item> | ||
| 7 | + | ||
| 8 | + <el-form-item :label="$t('communityPayment.paymentVendor')" prop="paymentType"> | ||
| 9 | + <el-select v-model="form.paymentType" :placeholder="$t('addCommunityPayment.vendorPlaceholder')" | ||
| 10 | + style="width: 100%" @change="handleVendorChange"> | ||
| 11 | + <el-option v-for="item in paymentTypes" :key="item.paymentType" :label="item.name" :value="item.paymentType" /> | ||
| 12 | + </el-select> | ||
| 13 | + </el-form-item> | ||
| 14 | + | ||
| 15 | + <el-form-item v-for="(key, index) in paymentKeys" :key="index" :label="key.name"> | ||
| 16 | + <el-input v-model="key.columnValue" type="textarea" :rows="2" :placeholder="key.remark" /> | ||
| 17 | + </el-form-item> | ||
| 18 | + | ||
| 19 | + <el-form-item v-if="form.paymentType === 'WECHAT'" :label="$t('communityPayment.merchantCert')"> | ||
| 20 | + <file-upload ref="uploader" namespace="addCommunityPayment" @upload-success="handleUploadSuccess" /> | ||
| 21 | + </el-form-item> | ||
| 22 | + | ||
| 23 | + <el-form-item :label="$t('communityPayment.paymentScope')" prop="payType"> | ||
| 24 | + <el-select v-model="form.payType" :placeholder="$t('addCommunityPayment.scopePlaceholder')" style="width: 100%" | ||
| 25 | + @change="handleScopeChange"> | ||
| 26 | + <el-option :label="$t('communityPayment.communityFee')" value="1001" /> | ||
| 27 | + <el-option :label="$t('communityPayment.tempParkingFee')" value="2002" /> | ||
| 28 | + <el-option :label="$t('communityPayment.specificFee')" value="3003" /> | ||
| 29 | + </el-select> | ||
| 30 | + </el-form-item> | ||
| 31 | + | ||
| 32 | + <el-form-item v-if="form.payType === '3003'" :label="$t('communityPayment.selectFeeItem')"> | ||
| 33 | + <el-checkbox-group v-model="form.configIds"> | ||
| 34 | + <el-checkbox v-for="fee in feeConfigs" :key="fee.configId" :label="fee.configId"> | ||
| 35 | + {{ fee.feeName }} | ||
| 36 | + </el-checkbox> | ||
| 37 | + </el-checkbox-group> | ||
| 38 | + </el-form-item> | ||
| 39 | + | ||
| 40 | + <el-form-item :label="$t('communityPayment.instruction')"> | ||
| 41 | + <el-input v-model="form.remark" type="textarea" :rows="3" | ||
| 42 | + :placeholder="$t('addCommunityPayment.remarkPlaceholder')" /> | ||
| 43 | + </el-form-item> | ||
| 44 | + </el-form> | ||
| 45 | + | ||
| 46 | + <div slot="footer"> | ||
| 47 | + <el-button @click="visible = false">{{ $t('communityPayment.cancel') }}</el-button> | ||
| 48 | + <el-button type="primary" @click="submitForm">{{ $t('communityPayment.save') }}</el-button> | ||
| 49 | + </div> | ||
| 50 | + </el-dialog> | ||
| 51 | +</template> | ||
| 52 | + | ||
| 53 | +<script> | ||
| 54 | +import { saveAdminPaymentPool, listPaymentKey, listPaymentAdapt, queryAdminFeeConfigs } from '@/api/fee/communityPaymentApi' | ||
| 55 | +import FileUpload from '@/components/upload/FileUpload' | ||
| 56 | + | ||
| 57 | +export default { | ||
| 58 | + name: 'AddCommunityPayment', | ||
| 59 | + components: { FileUpload }, | ||
| 60 | + data() { | ||
| 61 | + return { | ||
| 62 | + visible: false, | ||
| 63 | + form: { | ||
| 64 | + communityId: '', | ||
| 65 | + paymentName: '', | ||
| 66 | + paymentType: '', | ||
| 67 | + certPath: '', | ||
| 68 | + state: 'Y', | ||
| 69 | + remark: '', | ||
| 70 | + payType: '1001', | ||
| 71 | + configIds: [] | ||
| 72 | + }, | ||
| 73 | + paymentTypes: [], | ||
| 74 | + paymentKeys: [], | ||
| 75 | + feeConfigs: [], | ||
| 76 | + rules: { | ||
| 77 | + paymentName: [ | ||
| 78 | + { required: true, message: this.$t('communityPayment.requiredField'), trigger: 'blur' }, | ||
| 79 | + { max: 64, message: this.$t('communityPayment.maxLength64'), trigger: 'blur' } | ||
| 80 | + ], | ||
| 81 | + paymentType: [ | ||
| 82 | + { required: true, message: this.$t('communityPayment.requiredField'), trigger: 'change' } | ||
| 83 | + ], | ||
| 84 | + payType: [ | ||
| 85 | + { required: true, message: this.$t('communityPayment.requiredField'), trigger: 'change' } | ||
| 86 | + ] | ||
| 87 | + } | ||
| 88 | + } | ||
| 89 | + }, | ||
| 90 | + created() { | ||
| 91 | + this.loadPaymentTypes() | ||
| 92 | + }, | ||
| 93 | + methods: { | ||
| 94 | + open(params) { | ||
| 95 | + this.form.communityId = params.communityId | ||
| 96 | + this.visible = true | ||
| 97 | + this.$nextTick(() => { | ||
| 98 | + this.$refs.form && this.$refs.form.clearValidate() | ||
| 99 | + this.loadFeeConfigs() | ||
| 100 | + }) | ||
| 101 | + }, | ||
| 102 | + resetForm() { | ||
| 103 | + this.form = { | ||
| 104 | + communityId: this.form.communityId, | ||
| 105 | + paymentName: '', | ||
| 106 | + paymentType: '', | ||
| 107 | + certPath: '', | ||
| 108 | + state: 'Y', | ||
| 109 | + remark: '', | ||
| 110 | + payType: '1001', | ||
| 111 | + configIds: [] | ||
| 112 | + } | ||
| 113 | + this.paymentKeys = [] | ||
| 114 | + if (this.$refs.uploader) { | ||
| 115 | + this.$refs.uploader.clearFile() | ||
| 116 | + } | ||
| 117 | + }, | ||
| 118 | + async loadPaymentTypes() { | ||
| 119 | + try { | ||
| 120 | + const res = await listPaymentAdapt({ page: 1, row: 100 }) | ||
| 121 | + this.paymentTypes = res.data || [] | ||
| 122 | + } catch (error) { | ||
| 123 | + console.error('Failed to load payment types:', error) | ||
| 124 | + } | ||
| 125 | + }, | ||
| 126 | + async handleVendorChange() { | ||
| 127 | + try { | ||
| 128 | + const res = await listPaymentKey({ | ||
| 129 | + paymentType: this.form.paymentType, | ||
| 130 | + page: 1, | ||
| 131 | + row: 100 | ||
| 132 | + }) | ||
| 133 | + this.paymentKeys = (res.data || []).map(item => ({ | ||
| 134 | + ...item, | ||
| 135 | + columnValue: '' | ||
| 136 | + })) | ||
| 137 | + } catch (error) { | ||
| 138 | + console.error('Failed to load payment keys:', error) | ||
| 139 | + this.paymentKeys = [] | ||
| 140 | + } | ||
| 141 | + }, | ||
| 142 | + async loadFeeConfigs() { | ||
| 143 | + if (!this.form.communityId) return | ||
| 144 | + | ||
| 145 | + try { | ||
| 146 | + const res = await queryAdminFeeConfigs({ | ||
| 147 | + communityId: this.form.communityId, | ||
| 148 | + isDefault: 'F', | ||
| 149 | + page: 1, | ||
| 150 | + row: 100 | ||
| 151 | + }) | ||
| 152 | + this.feeConfigs = res.feeConfigs || [] | ||
| 153 | + } catch (error) { | ||
| 154 | + console.error('Failed to load fee configs:', error) | ||
| 155 | + this.feeConfigs = [] | ||
| 156 | + } | ||
| 157 | + }, | ||
| 158 | + handleScopeChange() { | ||
| 159 | + this.form.configIds = [] | ||
| 160 | + }, | ||
| 161 | + handleUploadSuccess(file) { | ||
| 162 | + this.form.certPath = file.realFileName | ||
| 163 | + }, | ||
| 164 | + submitForm() { | ||
| 165 | + this.$refs.form.validate(async valid => { | ||
| 166 | + if (!valid) return | ||
| 167 | + | ||
| 168 | + try { | ||
| 169 | + const payload = { | ||
| 170 | + ...this.form, | ||
| 171 | + paymentKeys: this.paymentKeys | ||
| 172 | + } | ||
| 173 | + await saveAdminPaymentPool(payload) | ||
| 174 | + this.$message.success(this.$t('common.saveSuccess')) | ||
| 175 | + this.visible = false | ||
| 176 | + this.$emit('success') | ||
| 177 | + } catch (error) { | ||
| 178 | + this.$message.error(error.message || this.$t('common.saveFailed')) | ||
| 179 | + } | ||
| 180 | + }) | ||
| 181 | + } | ||
| 182 | + } | ||
| 183 | +} | ||
| 184 | +</script> | ||
| 0 | \ No newline at end of file | 185 | \ No newline at end of file |
src/components/fee/DeleteCommunityPayment.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <el-dialog | ||
| 3 | + :title="$t('deleteCommunityPayment.title')" | ||
| 4 | + :visible.sync="visible" | ||
| 5 | + width="500px" | ||
| 6 | + :close-on-click-modal="false" | ||
| 7 | + > | ||
| 8 | + <div class="delete-content"> | ||
| 9 | + <i class="el-icon-warning" style="color: #e6a23c; font-size: 24px; margin-right: 10px"></i> | ||
| 10 | + <span>{{ $t('deleteCommunityPayment.message') }}</span> | ||
| 11 | + </div> | ||
| 12 | + | ||
| 13 | + <div slot="footer"> | ||
| 14 | + <el-button @click="visible = false">{{ $t('communityPayment.cancel') }}</el-button> | ||
| 15 | + <el-button type="primary" @click="confirmDelete">{{ $t('communityPayment.confirmDelete') }}</el-button> | ||
| 16 | + </div> | ||
| 17 | + </el-dialog> | ||
| 18 | +</template> | ||
| 19 | + | ||
| 20 | +<script> | ||
| 21 | +import { deleteAdminPaymentPool } from '@/api/fee/communityPaymentApi' | ||
| 22 | + | ||
| 23 | +export default { | ||
| 24 | + name: 'DeleteCommunityPayment', | ||
| 25 | + data() { | ||
| 26 | + return { | ||
| 27 | + visible: false, | ||
| 28 | + paymentId: '' | ||
| 29 | + } | ||
| 30 | + }, | ||
| 31 | + methods: { | ||
| 32 | + open(row) { | ||
| 33 | + this.paymentId = row.ppId | ||
| 34 | + this.visible = true | ||
| 35 | + }, | ||
| 36 | + async confirmDelete() { | ||
| 37 | + try { | ||
| 38 | + await deleteAdminPaymentPool({ ppId: this.paymentId }) | ||
| 39 | + this.$message.success(this.$t('common.deleteSuccess')) | ||
| 40 | + this.visible = false | ||
| 41 | + this.$emit('success') | ||
| 42 | + } catch (error) { | ||
| 43 | + this.$message.error(error.message || this.$t('common.deleteFailed')) | ||
| 44 | + } | ||
| 45 | + } | ||
| 46 | + } | ||
| 47 | +} | ||
| 48 | +</script> | ||
| 49 | + | ||
| 50 | +<style lang="scss" scoped> | ||
| 51 | +.delete-content { | ||
| 52 | + display: flex; | ||
| 53 | + align-items: center; | ||
| 54 | + justify-content: center; | ||
| 55 | + padding: 20px; | ||
| 56 | + font-size: 16px; | ||
| 57 | +} | ||
| 58 | +</style> | ||
| 0 | \ No newline at end of file | 59 | \ No newline at end of file |
src/components/fee/EditCommunityPayment.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <el-dialog :title="$t('editCommunityPayment.title')" :visible.sync="visible" width="800px" @closed="resetForm"> | ||
| 3 | + <el-form ref="form" :model="form" label-width="120px" :rules="rules"> | ||
| 4 | + <el-form-item :label="$t('communityPayment.paymentName')" prop="paymentName"> | ||
| 5 | + <el-input v-model="form.paymentName" :placeholder="$t('addCommunityPayment.namePlaceholder')" /> | ||
| 6 | + </el-form-item> | ||
| 7 | + | ||
| 8 | + <el-form-item :label="$t('communityPayment.paymentVendor')"> | ||
| 9 | + <el-select v-model="form.paymentType" disabled style="width: 100%"> | ||
| 10 | + <el-option v-for="item in paymentTypes" :key="item.paymentType" :label="item.name" :value="item.paymentType" /> | ||
| 11 | + </el-select> | ||
| 12 | + </el-form-item> | ||
| 13 | + | ||
| 14 | + <el-form-item v-for="(key, index) in paymentKeys" :key="index" :label="key.name"> | ||
| 15 | + <el-input v-model="key.columnValue" type="textarea" :rows="2" :placeholder="key.remark" /> | ||
| 16 | + </el-form-item> | ||
| 17 | + | ||
| 18 | + <el-form-item v-if="form.paymentType === 'WECHAT'" :label="$t('communityPayment.merchantCert')"> | ||
| 19 | + <file-upload ref="uploader" namespace="editCommunityPayment" @upload-success="handleUploadSuccess" /> | ||
| 20 | + </el-form-item> | ||
| 21 | + | ||
| 22 | + <el-form-item :label="$t('communityPayment.paymentScope')"> | ||
| 23 | + <el-select v-model="form.payType" disabled style="width: 100%"> | ||
| 24 | + <el-option :label="$t('communityPayment.communityFee')" value="1001" /> | ||
| 25 | + <el-option :label="$t('communityPayment.tempParkingFee')" value="2002" /> | ||
| 26 | + <el-option :label="$t('communityPayment.specificFee')" value="3003" /> | ||
| 27 | + </el-select> | ||
| 28 | + </el-form-item> | ||
| 29 | + | ||
| 30 | + <el-form-item v-if="form.payType === '3003'" :label="$t('communityPayment.selectFeeItem')"> | ||
| 31 | + <el-checkbox-group v-model="form.configIds"> | ||
| 32 | + <el-checkbox v-for="fee in feeConfigs" :key="fee.configId" :label="fee.configId"> | ||
| 33 | + {{ fee.feeName }} | ||
| 34 | + </el-checkbox> | ||
| 35 | + </el-checkbox-group> | ||
| 36 | + </el-form-item> | ||
| 37 | + | ||
| 38 | + <el-form-item :label="$t('communityPayment.status')" prop="state"> | ||
| 39 | + <el-select v-model="form.state" :placeholder="$t('editCommunityPayment.statusPlaceholder')" style="width: 100%"> | ||
| 40 | + <el-option :label="$t('communityPayment.enabled')" value="Y" /> | ||
| 41 | + <el-option :label="$t('communityPayment.disabled')" value="N" /> | ||
| 42 | + </el-select> | ||
| 43 | + </el-form-item> | ||
| 44 | + | ||
| 45 | + <el-form-item :label="$t('communityPayment.instruction')"> | ||
| 46 | + <el-input v-model="form.remark" type="textarea" :rows="3" | ||
| 47 | + :placeholder="$t('addCommunityPayment.remarkPlaceholder')" /> | ||
| 48 | + </el-form-item> | ||
| 49 | + </el-form> | ||
| 50 | + | ||
| 51 | + <div slot="footer"> | ||
| 52 | + <el-button @click="visible = false">{{ $t('communityPayment.cancel') }}</el-button> | ||
| 53 | + <el-button type="primary" @click="submitForm">{{ $t('communityPayment.save') }}</el-button> | ||
| 54 | + </div> | ||
| 55 | + </el-dialog> | ||
| 56 | +</template> | ||
| 57 | + | ||
| 58 | +<script> | ||
| 59 | +import { updateAdminPaymentPool, listPaymentKey, listPaymentAdapt, queryAdminFeeConfigs } from '@/api/fee/communityPaymentApi' | ||
| 60 | +import FileUpload from '@/components/upload/FileUpload' | ||
| 61 | + | ||
| 62 | +export default { | ||
| 63 | + name: 'EditCommunityPayment', | ||
| 64 | + components: { FileUpload }, | ||
| 65 | + data() { | ||
| 66 | + return { | ||
| 67 | + visible: false, | ||
| 68 | + form: { | ||
| 69 | + ppId: '', | ||
| 70 | + communityId: '', | ||
| 71 | + paymentName: '', | ||
| 72 | + paymentType: '', | ||
| 73 | + certPath: '', | ||
| 74 | + state: '', | ||
| 75 | + remark: '', | ||
| 76 | + payType: '', | ||
| 77 | + configIds: [] | ||
| 78 | + }, | ||
| 79 | + paymentTypes: [], | ||
| 80 | + paymentKeys: [], | ||
| 81 | + feeConfigs: [], | ||
| 82 | + rules: { | ||
| 83 | + paymentName: [ | ||
| 84 | + { required: true, message: this.$t('communityPayment.requiredField'), trigger: 'blur' }, | ||
| 85 | + { max: 64, message: this.$t('communityPayment.maxLength64'), trigger: 'blur' } | ||
| 86 | + ], | ||
| 87 | + state: [ | ||
| 88 | + { required: true, message: this.$t('communityPayment.requiredField'), trigger: 'change' } | ||
| 89 | + ] | ||
| 90 | + } | ||
| 91 | + } | ||
| 92 | + }, | ||
| 93 | + created() { | ||
| 94 | + this.loadPaymentTypes() | ||
| 95 | + }, | ||
| 96 | + methods: { | ||
| 97 | + open(row) { | ||
| 98 | + this.form = { ...row } | ||
| 99 | + this.visible = true | ||
| 100 | + this.$nextTick(() => { | ||
| 101 | + this.$refs.form && this.$refs.form.clearValidate() | ||
| 102 | + this.loadPaymentKeys() | ||
| 103 | + this.loadFeeConfigs() | ||
| 104 | + if (row.certPath && this.$refs.uploader) { | ||
| 105 | + this.$refs.uploader.setFileName(row.certPath) | ||
| 106 | + } | ||
| 107 | + }) | ||
| 108 | + }, | ||
| 109 | + resetForm() { | ||
| 110 | + this.form = { | ||
| 111 | + ppId: '', | ||
| 112 | + communityId: '', | ||
| 113 | + paymentName: '', | ||
| 114 | + paymentType: '', | ||
| 115 | + certPath: '', | ||
| 116 | + state: '', | ||
| 117 | + remark: '', | ||
| 118 | + payType: '', | ||
| 119 | + configIds: [] | ||
| 120 | + } | ||
| 121 | + this.paymentKeys = [] | ||
| 122 | + if (this.$refs.uploader) { | ||
| 123 | + this.$refs.uploader.clearFile() | ||
| 124 | + } | ||
| 125 | + }, | ||
| 126 | + async loadPaymentTypes() { | ||
| 127 | + try { | ||
| 128 | + const res = await listPaymentAdapt({ page: 1, row: 100 }) | ||
| 129 | + this.paymentTypes = res.data || [] | ||
| 130 | + } catch (error) { | ||
| 131 | + console.error('Failed to load payment types:', error) | ||
| 132 | + } | ||
| 133 | + }, | ||
| 134 | + async loadPaymentKeys() { | ||
| 135 | + if (!this.form.paymentType) return | ||
| 136 | + | ||
| 137 | + try { | ||
| 138 | + const res = await listPaymentKey({ | ||
| 139 | + paymentType: this.form.paymentType, | ||
| 140 | + page: 1, | ||
| 141 | + row: 100 | ||
| 142 | + }) | ||
| 143 | + this.paymentKeys = res.data || [] | ||
| 144 | + | ||
| 145 | + // Load existing values | ||
| 146 | + if (this.form.values) { | ||
| 147 | + this.paymentKeys.forEach(key => { | ||
| 148 | + const value = this.form.values.find(v => v.columnKey === key.columnKey) | ||
| 149 | + if (value) { | ||
| 150 | + key.columnValue = value.columnValue | ||
| 151 | + } | ||
| 152 | + }) | ||
| 153 | + } | ||
| 154 | + } catch (error) { | ||
| 155 | + console.error('Failed to load payment keys:', error) | ||
| 156 | + this.paymentKeys = [] | ||
| 157 | + } | ||
| 158 | + }, | ||
| 159 | + async loadFeeConfigs() { | ||
| 160 | + if (!this.form.communityId) return | ||
| 161 | + | ||
| 162 | + try { | ||
| 163 | + const res = await queryAdminFeeConfigs({ | ||
| 164 | + communityId: this.form.communityId, | ||
| 165 | + isDefault: 'F', | ||
| 166 | + page: 1, | ||
| 167 | + row: 100 | ||
| 168 | + }) | ||
| 169 | + this.feeConfigs = res.feeConfigs || [] | ||
| 170 | + } catch (error) { | ||
| 171 | + console.error('Failed to load fee configs:', error) | ||
| 172 | + this.feeConfigs = [] | ||
| 173 | + } | ||
| 174 | + }, | ||
| 175 | + handleUploadSuccess(file) { | ||
| 176 | + this.form.certPath = file.realFileName | ||
| 177 | + }, | ||
| 178 | + submitForm() { | ||
| 179 | + this.$refs.form.validate(async valid => { | ||
| 180 | + if (!valid) return | ||
| 181 | + | ||
| 182 | + try { | ||
| 183 | + const payload = { | ||
| 184 | + ...this.form, | ||
| 185 | + paymentKeys: this.paymentKeys | ||
| 186 | + } | ||
| 187 | + await updateAdminPaymentPool(payload) | ||
| 188 | + this.$message.success(this.$t('common.updateSuccess')) | ||
| 189 | + this.visible = false | ||
| 190 | + this.$emit('success') | ||
| 191 | + } catch (error) { | ||
| 192 | + this.$message.error(error.message || this.$t('common.updateFailed')) | ||
| 193 | + } | ||
| 194 | + }) | ||
| 195 | + } | ||
| 196 | + } | ||
| 197 | +} | ||
| 198 | +</script> | ||
| 0 | \ No newline at end of file | 199 | \ No newline at end of file |
src/i18n/index.js
| @@ -116,6 +116,8 @@ import { messages as aStaffMessages } from '../views/staff/aStaffLang' | @@ -116,6 +116,8 @@ import { messages as aStaffMessages } from '../views/staff/aStaffLang' | ||
| 116 | import { messages as aStaffDetailMessages } from '../views/staff/aStaffDetailLang' | 116 | import { messages as aStaffDetailMessages } from '../views/staff/aStaffDetailLang' |
| 117 | import { messages as aStaffCommunityMessages } from '../views/staff/aStaffCommunityLang' | 117 | import { messages as aStaffCommunityMessages } from '../views/staff/aStaffCommunityLang' |
| 118 | import { messages as communityWechatMessages } from '../views/community/communityWechatLang' | 118 | import { messages as communityWechatMessages } from '../views/community/communityWechatLang' |
| 119 | +import { messages as communityMiniMessages } from '../views/community/communityMiniLang' | ||
| 120 | +import { messages as communityPaymentMessages } from '../views/fee/communityPaymentLang' | ||
| 119 | 121 | ||
| 120 | Vue.use(VueI18n) | 122 | Vue.use(VueI18n) |
| 121 | 123 | ||
| @@ -236,6 +238,8 @@ const messages = { | @@ -236,6 +238,8 @@ const messages = { | ||
| 236 | ...aStaffDetailMessages.en, | 238 | ...aStaffDetailMessages.en, |
| 237 | ...aStaffCommunityMessages.en, | 239 | ...aStaffCommunityMessages.en, |
| 238 | ...communityWechatMessages.en, | 240 | ...communityWechatMessages.en, |
| 241 | + ...communityMiniMessages.en, | ||
| 242 | + ...communityPaymentMessages.en, | ||
| 239 | }, | 243 | }, |
| 240 | zh: { | 244 | zh: { |
| 241 | ...loginMessages.zh, | 245 | ...loginMessages.zh, |
| @@ -352,6 +356,8 @@ const messages = { | @@ -352,6 +356,8 @@ const messages = { | ||
| 352 | ...aStaffDetailMessages.zh, | 356 | ...aStaffDetailMessages.zh, |
| 353 | ...aStaffCommunityMessages.zh, | 357 | ...aStaffCommunityMessages.zh, |
| 354 | ...communityWechatMessages.zh, | 358 | ...communityWechatMessages.zh, |
| 359 | + ...communityMiniMessages.zh, | ||
| 360 | + ...communityPaymentMessages.zh, | ||
| 355 | } | 361 | } |
| 356 | } | 362 | } |
| 357 | 363 |
src/router/index.js
| @@ -557,15 +557,25 @@ const routes = [ | @@ -557,15 +557,25 @@ const routes = [ | ||
| 557 | component: () => import('@/views/staff/aStaffDetailList.vue') | 557 | component: () => import('@/views/staff/aStaffDetailList.vue') |
| 558 | }, | 558 | }, |
| 559 | { | 559 | { |
| 560 | - path:'/pages/staff/aStaffCommunity', | ||
| 561 | - name:'/pages/staff/aStaffCommunity', | 560 | + path: '/pages/staff/aStaffCommunity', |
| 561 | + name: '/pages/staff/aStaffCommunity', | ||
| 562 | component: () => import('@/views/staff/aStaffCommunityList.vue') | 562 | component: () => import('@/views/staff/aStaffCommunityList.vue') |
| 563 | + }, | ||
| 564 | + { | ||
| 565 | + path: '/pages/community/communityWechat', | ||
| 566 | + name: '/pages/community/communityWechat', | ||
| 567 | + component: () => import('@/views/community/communityWechatList.vue') | ||
| 568 | + }, | ||
| 569 | + { | ||
| 570 | + path: '/pages/community/communityMini', | ||
| 571 | + name: '/pages/community/communityMini', | ||
| 572 | + component: () => import('@/views/community/communityMiniList.vue') | ||
| 573 | + }, | ||
| 574 | + { | ||
| 575 | + path:'/pages/fee/communityPayment', | ||
| 576 | + name:'/pages/fee/communityPayment', | ||
| 577 | + component: () => import('@/views/fee/communityPaymentList.vue') | ||
| 563 | }, | 578 | }, |
| 564 | - { | ||
| 565 | - path:'/pages/community/communityWechat', | ||
| 566 | - name:'/pages/community/communityWechat', | ||
| 567 | - component: () => import('@/views/community/communityWechatList.vue') | ||
| 568 | - }, | ||
| 569 | // 其他子路由可以在这里添加 | 579 | // 其他子路由可以在这里添加 |
| 570 | ] | 580 | ] |
| 571 | }, | 581 | }, |
src/views/community/communityMiniLang.js
0 → 100644
| 1 | +export const messages = { | ||
| 2 | + en: { | ||
| 3 | + communityMini: { | ||
| 4 | + title: 'Community Mini Program', | ||
| 5 | + name: 'Name', | ||
| 6 | + communityName: 'Community Name', | ||
| 7 | + appSecret: 'App Secret', | ||
| 8 | + description: 'Description', | ||
| 9 | + operation: 'Operation', | ||
| 10 | + add: 'Add', | ||
| 11 | + edit: 'Edit', | ||
| 12 | + cancel: 'Cancel', | ||
| 13 | + save: 'Save', | ||
| 14 | + requiredName: 'Required, please fill in the name', | ||
| 15 | + requiredAppId: 'Required, please fill in APPID', | ||
| 16 | + requiredSecret: 'Required, please fill in App Secret', | ||
| 17 | + optionalDescription: 'Optional, please fill in description' | ||
| 18 | + } | ||
| 19 | + }, | ||
| 20 | + zh: { | ||
| 21 | + communityMini: { | ||
| 22 | + title: '小区小程序', | ||
| 23 | + name: '名称', | ||
| 24 | + communityName: '小区名称', | ||
| 25 | + appSecret: '应用密钥', | ||
| 26 | + description: '描述', | ||
| 27 | + operation: '操作', | ||
| 28 | + add: '添加', | ||
| 29 | + edit: '修改', | ||
| 30 | + cancel: '取消', | ||
| 31 | + save: '保存', | ||
| 32 | + requiredName: '必填,请填写名称', | ||
| 33 | + requiredAppId: '必填,请填写APPID', | ||
| 34 | + requiredSecret: '必填,请填写应用密钥', | ||
| 35 | + optionalDescription: '选填,请填写描述信息' | ||
| 36 | + } | ||
| 37 | + } | ||
| 38 | +} | ||
| 0 | \ No newline at end of file | 39 | \ No newline at end of file |
src/views/community/communityMiniList.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="community-mini-container"> | ||
| 3 | + <el-row :gutter="20"> | ||
| 4 | + <el-col :span="4"> | ||
| 5 | + <select-admin-community :community-id="communityId" @changeCommunity="handleCommunityChange" /> | ||
| 6 | + </el-col> | ||
| 7 | + | ||
| 8 | + <el-col :span="20"> | ||
| 9 | + <el-card> | ||
| 10 | + <div slot="header" class="clearfix flex justify-between"> | ||
| 11 | + <span>{{ $t('communityMini.title') }}</span> | ||
| 12 | + <div class="header-tools"> | ||
| 13 | + <el-button v-if="smallWeChats.length === 0 && conditions.communityId" type="primary" size="small" | ||
| 14 | + icon="el-icon-plus" @click="openAddModal"> | ||
| 15 | + {{ $t('communityMini.add') }} | ||
| 16 | + </el-button> | ||
| 17 | + </div> | ||
| 18 | + </div> | ||
| 19 | + | ||
| 20 | + <el-table :data="smallWeChats" border style="width: 100%"> | ||
| 21 | + <el-table-column prop="name" :label="$t('communityMini.name')" align="center" /> | ||
| 22 | + <el-table-column prop="communityName" :label="$t('communityMini.communityName')" align="center" /> | ||
| 23 | + <el-table-column prop="appId" label="APPID" align="center" /> | ||
| 24 | + <el-table-column :label="$t('communityMini.appSecret')" align="center"> | ||
| 25 | + <template > | ||
| 26 | + ******** | ||
| 27 | + </template> | ||
| 28 | + </el-table-column> | ||
| 29 | + <el-table-column prop="remarks" :label="$t('communityMini.description')" align="center" /> | ||
| 30 | + <el-table-column :label="$t('communityMini.operation')" align="center" width="120"> | ||
| 31 | + <template slot-scope="scope"> | ||
| 32 | + <el-button type="text" size="small" @click="openEditModal(scope.row)"> | ||
| 33 | + {{ $t('communityMini.edit') }} | ||
| 34 | + </el-button> | ||
| 35 | + </template> | ||
| 36 | + </el-table-column> | ||
| 37 | + </el-table> | ||
| 38 | + </el-card> | ||
| 39 | + </el-col> | ||
| 40 | + </el-row> | ||
| 41 | + | ||
| 42 | + <add-community-wechat ref="addModal" @success="loadSmallWeChats" /> | ||
| 43 | + <edit-community-wechat ref="editModal" @success="loadSmallWeChats" /> | ||
| 44 | + </div> | ||
| 45 | +</template> | ||
| 46 | + | ||
| 47 | +<script> | ||
| 48 | +import { listAdminSmallWeChats } from '@/api/community/communityMiniApi' | ||
| 49 | +import SelectAdminCommunity from '@/components/community/selectAdminCommunity' | ||
| 50 | +import AddCommunityWechat from '@/components/community/addCommunityWechat' | ||
| 51 | +import EditCommunityWechat from '@/components/community/editCommunityWechat' | ||
| 52 | + | ||
| 53 | +export default { | ||
| 54 | + name: 'CommunityMiniList', | ||
| 55 | + components: { | ||
| 56 | + SelectAdminCommunity, | ||
| 57 | + AddCommunityWechat, | ||
| 58 | + EditCommunityWechat | ||
| 59 | + }, | ||
| 60 | + data() { | ||
| 61 | + return { | ||
| 62 | + conditions: { | ||
| 63 | + communityId: '', | ||
| 64 | + weChatType: '1000', | ||
| 65 | + page: 1, | ||
| 66 | + row: 100 | ||
| 67 | + }, | ||
| 68 | + smallWeChats: [], | ||
| 69 | + loading: false | ||
| 70 | + } | ||
| 71 | + }, | ||
| 72 | + mounted() { | ||
| 73 | + this.loadSmallWeChats() | ||
| 74 | + }, | ||
| 75 | + methods: { | ||
| 76 | + async loadSmallWeChats() { | ||
| 77 | + this.loading = true | ||
| 78 | + try { | ||
| 79 | + const res = await listAdminSmallWeChats(this.conditions) | ||
| 80 | + if (res.code === 0) { | ||
| 81 | + this.smallWeChats = res.data || [] | ||
| 82 | + } else { | ||
| 83 | + this.$message.error(res.msg || '加载小程序列表失败') | ||
| 84 | + } | ||
| 85 | + } catch (error) { | ||
| 86 | + console.error('加载小程序列表失败:', error) | ||
| 87 | + } finally { | ||
| 88 | + this.loading = false | ||
| 89 | + } | ||
| 90 | + }, | ||
| 91 | + handleCommunityChange(community) { | ||
| 92 | + this.conditions.communityId = community.communityId | ||
| 93 | + this.loadSmallWeChats() | ||
| 94 | + }, | ||
| 95 | + openAddModal() { | ||
| 96 | + const params = { | ||
| 97 | + objId: this.conditions.communityId, | ||
| 98 | + communityId: this.conditions.communityId, | ||
| 99 | + weChatType: '1000' | ||
| 100 | + } | ||
| 101 | + this.$refs.addModal.open(params) | ||
| 102 | + }, | ||
| 103 | + openEditModal(row) { | ||
| 104 | + this.$refs.editModal.open(row) | ||
| 105 | + } | ||
| 106 | + } | ||
| 107 | +} | ||
| 108 | +</script> | ||
| 109 | + | ||
| 110 | +<style scoped> | ||
| 111 | +.community-mini-container { | ||
| 112 | + padding: 20px; | ||
| 113 | +} | ||
| 114 | + | ||
| 115 | +.header-tools { | ||
| 116 | + float: right; | ||
| 117 | +} | ||
| 118 | + | ||
| 119 | +.clearfix:after { | ||
| 120 | + content: ""; | ||
| 121 | + display: table; | ||
| 122 | + clear: both; | ||
| 123 | +} | ||
| 124 | +</style> | ||
| 0 | \ No newline at end of file | 125 | \ No newline at end of file |
src/views/fee/communityPaymentLang.js
0 → 100644
| 1 | +export const messages = { | ||
| 2 | + en: { | ||
| 3 | + communityPayment: { | ||
| 4 | + title: 'Community Payment', | ||
| 5 | + search: 'Search', | ||
| 6 | + add: 'Add', | ||
| 7 | + edit: 'Edit', | ||
| 8 | + delete: 'Delete', | ||
| 9 | + confirmDelete: 'Confirm Delete', | ||
| 10 | + paymentName: 'Name', | ||
| 11 | + communityName: 'Community', | ||
| 12 | + paymentVendor: 'Payment Vendor', | ||
| 13 | + paymentScope: 'Payment Scope', | ||
| 14 | + status: 'Status', | ||
| 15 | + createTime: 'Create Time', | ||
| 16 | + instruction: 'Instruction', | ||
| 17 | + operation: 'Operation', | ||
| 18 | + communityFee: 'Community Fee', | ||
| 19 | + tempParkingFee: 'Temporary Parking Fee', | ||
| 20 | + specificFee: 'Specific Fee Item', | ||
| 21 | + enabled: 'Enabled', | ||
| 22 | + disabled: 'Disabled', | ||
| 23 | + selectCommunity: 'Select Community', | ||
| 24 | + selectStatus: 'Select Status', | ||
| 25 | + selectVendor: 'Select Vendor', | ||
| 26 | + selectScope: 'Select Scope', | ||
| 27 | + selectFeeItem: 'Select Fee Item', | ||
| 28 | + merchantCert: 'Merchant Certificate (.p12)', | ||
| 29 | + uploadFile: 'Upload Attachment', | ||
| 30 | + cancel: 'Cancel', | ||
| 31 | + save: 'Save', | ||
| 32 | + requiredField: 'Required field' | ||
| 33 | + }, | ||
| 34 | + addCommunityPayment: { | ||
| 35 | + title: 'Add Payment', | ||
| 36 | + namePlaceholder: 'Please enter name', | ||
| 37 | + vendorPlaceholder: 'Please select vendor', | ||
| 38 | + scopePlaceholder: 'Please select scope', | ||
| 39 | + remarkPlaceholder: 'Optional, usage instructions' | ||
| 40 | + }, | ||
| 41 | + editCommunityPayment: { | ||
| 42 | + title: 'Edit Payment', | ||
| 43 | + statusPlaceholder: 'Please select status' | ||
| 44 | + }, | ||
| 45 | + deleteCommunityPayment: { | ||
| 46 | + title: 'Delete Confirmation', | ||
| 47 | + message: 'Are you sure to delete this payment configuration?' | ||
| 48 | + } | ||
| 49 | + }, | ||
| 50 | + zh: { | ||
| 51 | + communityPayment: { | ||
| 52 | + title: '小区支付', | ||
| 53 | + search: '查询', | ||
| 54 | + add: '添加', | ||
| 55 | + edit: '修改', | ||
| 56 | + delete: '删除', | ||
| 57 | + confirmDelete: '确认删除', | ||
| 58 | + paymentName: '名称', | ||
| 59 | + communityName: '小区名称', | ||
| 60 | + paymentVendor: '支付厂家', | ||
| 61 | + paymentScope: '支付范围', | ||
| 62 | + status: '状态', | ||
| 63 | + createTime: '创建时间', | ||
| 64 | + instruction: '使用说明', | ||
| 65 | + operation: '操作', | ||
| 66 | + communityFee: '小区费用', | ||
| 67 | + tempParkingFee: '临时停车费', | ||
| 68 | + specificFee: '指定费用项', | ||
| 69 | + enabled: '启用', | ||
| 70 | + disabled: '停用', | ||
| 71 | + selectCommunity: '请选择小区', | ||
| 72 | + selectStatus: '请选择状态', | ||
| 73 | + selectVendor: '请选择厂家', | ||
| 74 | + selectScope: '请选择范围', | ||
| 75 | + selectFeeItem: '请选择费用项', | ||
| 76 | + merchantCert: '商户证书(.p12)', | ||
| 77 | + uploadFile: '上传附件', | ||
| 78 | + cancel: '取消', | ||
| 79 | + save: '保存', | ||
| 80 | + requiredField: '必填项' | ||
| 81 | + }, | ||
| 82 | + addCommunityPayment: { | ||
| 83 | + title: '添加支付', | ||
| 84 | + namePlaceholder: '必填,请填写名称', | ||
| 85 | + vendorPlaceholder: '必填,请选择支付厂家', | ||
| 86 | + scopePlaceholder: '必填,请选择支付范围', | ||
| 87 | + remarkPlaceholder: '选填,请填写使用说明' | ||
| 88 | + }, | ||
| 89 | + editCommunityPayment: { | ||
| 90 | + title: '修改支付', | ||
| 91 | + statusPlaceholder: '必填,请选择状态' | ||
| 92 | + }, | ||
| 93 | + deleteCommunityPayment: { | ||
| 94 | + title: '删除确认', | ||
| 95 | + message: '确定删除支付配置' | ||
| 96 | + } | ||
| 97 | + } | ||
| 98 | +} | ||
| 0 | \ No newline at end of file | 99 | \ No newline at end of file |
src/views/fee/communityPaymentList.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="community-payment-container"> | ||
| 3 | + <el-row :gutter="20"> | ||
| 4 | + <el-col :span="4" class="tree-container"> | ||
| 5 | + <select-admin-community @change-community="handleCommunityChange" /> | ||
| 6 | + </el-col> | ||
| 7 | + <el-col :span="20"> | ||
| 8 | + <el-card class="search-card"> | ||
| 9 | + <div slot="header"> | ||
| 10 | + <span>{{ $t('communityPayment.search') }}</span> | ||
| 11 | + </div> | ||
| 12 | + <el-form :inline="true" :model="searchForm"> | ||
| 13 | + <el-form-item> | ||
| 14 | + <el-input | ||
| 15 | + v-model="searchForm.paymentName" | ||
| 16 | + :placeholder="$t('communityPayment.paymentName')" | ||
| 17 | + clearable | ||
| 18 | + /> | ||
| 19 | + </el-form-item> | ||
| 20 | + <el-form-item> | ||
| 21 | + <el-select | ||
| 22 | + v-model="searchForm.state" | ||
| 23 | + :placeholder="$t('communityPayment.selectStatus')" | ||
| 24 | + clearable | ||
| 25 | + > | ||
| 26 | + <el-option value="" :label="$t('communityPayment.selectStatus')" /> | ||
| 27 | + <el-option value="Y" :label="$t('communityPayment.enabled')" /> | ||
| 28 | + <el-option value="N" :label="$t('communityPayment.disabled')" /> | ||
| 29 | + </el-select> | ||
| 30 | + </el-form-item> | ||
| 31 | + <el-form-item> | ||
| 32 | + <el-button type="primary" @click="handleSearch"> | ||
| 33 | + {{ $t('communityPayment.search') }} | ||
| 34 | + </el-button> | ||
| 35 | + </el-form-item> | ||
| 36 | + </el-form> | ||
| 37 | + </el-card> | ||
| 38 | + | ||
| 39 | + <el-card class="list-card"> | ||
| 40 | + <div slot="header"> | ||
| 41 | + <span>{{ $t('communityPayment.title') }}</span> | ||
| 42 | + <el-button | ||
| 43 | + v-if="searchForm.communityId" | ||
| 44 | + type="primary" | ||
| 45 | + size="mini" | ||
| 46 | + style="float: right" | ||
| 47 | + @click="openAddDialog" | ||
| 48 | + > | ||
| 49 | + {{ $t('communityPayment.add') }} | ||
| 50 | + </el-button> | ||
| 51 | + </div> | ||
| 52 | + <el-table :data="payments" border stripe> | ||
| 53 | + <el-table-column prop="paymentName" :label="$t('communityPayment.paymentName')" align="center" /> | ||
| 54 | + <el-table-column prop="communityName" :label="$t('communityPayment.communityName')" align="center" /> | ||
| 55 | + <el-table-column prop="paymentTypeName" :label="$t('communityPayment.paymentVendor')" align="center" /> | ||
| 56 | + <el-table-column :label="$t('communityPayment.paymentScope')" align="center"> | ||
| 57 | + <template slot-scope="{ row }"> | ||
| 58 | + <span v-if="row.payType === '1001'">{{ $t('communityPayment.communityFee') }}</span> | ||
| 59 | + <span v-else-if="row.payType === '2002'">{{ $t('communityPayment.tempParkingFee') }}</span> | ||
| 60 | + <span v-else>{{ $t('communityPayment.specificFee') }}</span> | ||
| 61 | + </template> | ||
| 62 | + </el-table-column> | ||
| 63 | + <el-table-column :label="$t('communityPayment.status')" align="center"> | ||
| 64 | + <template slot-scope="{ row }"> | ||
| 65 | + {{ row.state === 'Y' ? $t('communityPayment.enabled') : $t('communityPayment.disabled') }} | ||
| 66 | + </template> | ||
| 67 | + </el-table-column> | ||
| 68 | + <el-table-column prop="createTime" :label="$t('communityPayment.createTime')" align="center" /> | ||
| 69 | + <el-table-column prop="remark" :label="$t('communityPayment.instruction')" align="center" /> | ||
| 70 | + <el-table-column :label="$t('communityPayment.operation')" align="center" width="180"> | ||
| 71 | + <template slot-scope="{ row }"> | ||
| 72 | + <el-button size="mini" @click="openEditDialog(row)">{{ $t('communityPayment.edit') }}</el-button> | ||
| 73 | + <el-button size="mini" type="danger" @click="openDeleteDialog(row)"> | ||
| 74 | + {{ $t('communityPayment.delete') }} | ||
| 75 | + </el-button> | ||
| 76 | + </template> | ||
| 77 | + </el-table-column> | ||
| 78 | + </el-table> | ||
| 79 | + | ||
| 80 | + <el-pagination | ||
| 81 | + :current-page="pagination.current" | ||
| 82 | + :page-sizes="[10, 20, 30, 50]" | ||
| 83 | + :page-size="pagination.size" | ||
| 84 | + layout="total, sizes, prev, pager, next, jumper" | ||
| 85 | + :total="pagination.total" | ||
| 86 | + @size-change="handleSizeChange" | ||
| 87 | + @current-change="handlePageChange" | ||
| 88 | + /> | ||
| 89 | + </el-card> | ||
| 90 | + </el-col> | ||
| 91 | + </el-row> | ||
| 92 | + | ||
| 93 | + <add-community-payment ref="addDialog" @success="handleSuccess" /> | ||
| 94 | + <edit-community-payment ref="editDialog" @success="handleSuccess" /> | ||
| 95 | + <delete-community-payment ref="deleteDialog" @success="handleSuccess" /> | ||
| 96 | + </div> | ||
| 97 | +</template> | ||
| 98 | + | ||
| 99 | +<script> | ||
| 100 | +import SelectAdminCommunity from '@/components/fee/SelectAdminCommunity' | ||
| 101 | +import AddCommunityPayment from '@/components/fee/AddCommunityPayment' | ||
| 102 | +import EditCommunityPayment from '@/components/fee/EditCommunityPayment' | ||
| 103 | +import DeleteCommunityPayment from '@/components/fee/DeleteCommunityPayment' | ||
| 104 | +import { listAdminPayment } from '@/api/fee/communityPaymentApi' | ||
| 105 | + | ||
| 106 | +export default { | ||
| 107 | + name: 'CommunityPaymentList', | ||
| 108 | + components: { | ||
| 109 | + SelectAdminCommunity, | ||
| 110 | + AddCommunityPayment, | ||
| 111 | + EditCommunityPayment, | ||
| 112 | + DeleteCommunityPayment | ||
| 113 | + }, | ||
| 114 | + data() { | ||
| 115 | + return { | ||
| 116 | + searchForm: { | ||
| 117 | + paymentName: '', | ||
| 118 | + state: '', | ||
| 119 | + communityId: '' | ||
| 120 | + }, | ||
| 121 | + payments: [], | ||
| 122 | + pagination: { | ||
| 123 | + current: 1, | ||
| 124 | + size: 10, | ||
| 125 | + total: 0 | ||
| 126 | + } | ||
| 127 | + } | ||
| 128 | + }, | ||
| 129 | + created() { | ||
| 130 | + this.fetchPayments() | ||
| 131 | + }, | ||
| 132 | + methods: { | ||
| 133 | + async fetchPayments() { | ||
| 134 | + try { | ||
| 135 | + const params = { | ||
| 136 | + ...this.searchForm, | ||
| 137 | + page: this.pagination.current, | ||
| 138 | + row: this.pagination.size | ||
| 139 | + } | ||
| 140 | + const res = await listAdminPayment(params) | ||
| 141 | + this.payments = res.data || [] | ||
| 142 | + this.pagination.total = res.total || 0 | ||
| 143 | + } catch (error) { | ||
| 144 | + console.error('Failed to fetch payments:', error) | ||
| 145 | + this.$message.error(this.$t('communityPayment.fetchError')) | ||
| 146 | + } | ||
| 147 | + }, | ||
| 148 | + handleCommunityChange(community) { | ||
| 149 | + this.searchForm.communityId = community.communityId | ||
| 150 | + this.fetchPayments() | ||
| 151 | + }, | ||
| 152 | + handleSearch() { | ||
| 153 | + this.pagination.current = 1 | ||
| 154 | + this.fetchPayments() | ||
| 155 | + }, | ||
| 156 | + handleSizeChange(size) { | ||
| 157 | + this.pagination.size = size | ||
| 158 | + this.fetchPayments() | ||
| 159 | + }, | ||
| 160 | + handlePageChange(page) { | ||
| 161 | + this.pagination.current = page | ||
| 162 | + this.fetchPayments() | ||
| 163 | + }, | ||
| 164 | + openAddDialog() { | ||
| 165 | + this.$refs.addDialog.open({ | ||
| 166 | + communityId: this.searchForm.communityId | ||
| 167 | + }) | ||
| 168 | + }, | ||
| 169 | + openEditDialog(row) { | ||
| 170 | + this.$refs.editDialog.open(row) | ||
| 171 | + }, | ||
| 172 | + openDeleteDialog(row) { | ||
| 173 | + this.$refs.deleteDialog.open(row) | ||
| 174 | + }, | ||
| 175 | + handleSuccess() { | ||
| 176 | + this.fetchPayments() | ||
| 177 | + } | ||
| 178 | + } | ||
| 179 | +} | ||
| 180 | +</script> | ||
| 181 | + | ||
| 182 | +<style lang="scss" scoped> | ||
| 183 | +.community-payment-container { | ||
| 184 | + height: calc(100vh - 84px); | ||
| 185 | + | ||
| 186 | + .tree-container { | ||
| 187 | + height: calc(100vh - 140px); | ||
| 188 | + overflow-y: auto; | ||
| 189 | + } | ||
| 190 | + | ||
| 191 | + .search-card, .list-card { | ||
| 192 | + margin-bottom: 20px; | ||
| 193 | + } | ||
| 194 | +} | ||
| 195 | +</style> | ||
| 0 | \ No newline at end of file | 196 | \ No newline at end of file |