Commit 1f3f7892ac15b1ab7ae9270eae4217417c8c6c32

Authored by wuxw
1 parent dedd9ade

开发完成admin 系统小区公众号

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 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 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 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 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 199 \ No newline at end of file
... ...
src/i18n/index.js
... ... @@ -116,6 +116,8 @@ import { messages as aStaffMessages } from &#39;../views/staff/aStaffLang&#39;
116 116 import { messages as aStaffDetailMessages } from '../views/staff/aStaffDetailLang'
117 117 import { messages as aStaffCommunityMessages } from '../views/staff/aStaffCommunityLang'
118 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 122 Vue.use(VueI18n)
121 123  
... ... @@ -236,6 +238,8 @@ const messages = {
236 238 ...aStaffDetailMessages.en,
237 239 ...aStaffCommunityMessages.en,
238 240 ...communityWechatMessages.en,
  241 + ...communityMiniMessages.en,
  242 + ...communityPaymentMessages.en,
239 243 },
240 244 zh: {
241 245 ...loginMessages.zh,
... ... @@ -352,6 +356,8 @@ const messages = {
352 356 ...aStaffDetailMessages.zh,
353 357 ...aStaffCommunityMessages.zh,
354 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 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 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 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 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 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 196 \ No newline at end of file
... ...