Commit 2803cb180b9dd5d51aa564cdf6b55d5c83caacbd

Authored by wuxw
1 parent 31330681

开发完成营销记录

src/api/market/marketBlacklistManageApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +// 获取营销黑白单列表
  4 +export function listMarketBlacklist(params) {
  5 + return new Promise((resolve, reject) => {
  6 + request({
  7 + url: '/marketBlacklist.listMarketBlacklist',
  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 saveMarketBlacklist(data) {
  25 + return new Promise((resolve, reject) => {
  26 + request({
  27 + url: '/marketBlacklist.saveMarketBlacklist',
  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 updateMarketBlacklist(data) {
  45 + return new Promise((resolve, reject) => {
  46 + request({
  47 + url: '/marketBlacklist.updateMarketBlacklist',
  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 deleteMarketBlacklist(data) {
  65 + return new Promise((resolve, reject) => {
  66 + request({
  67 + url: '/marketBlacklist.deleteMarketBlacklist',
  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/market/marketLogApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +// List market logs
  4 +export function listMarketLog(params) {
  5 + return new Promise((resolve, reject) => {
  6 + request({
  7 + url: '/marketRule.listMarketLog',
  8 + method: 'get',
  9 + params
  10 + }).then(response => {
  11 + const res = response.data
  12 + if (res.code === 0) {
  13 + resolve({
  14 + data: res.data,
  15 + total: res.total
  16 + })
  17 + } else {
  18 + reject(new Error(res.msg || 'Failed to get market logs'))
  19 + }
  20 + }).catch(error => {
  21 + reject(error)
  22 + })
  23 + })
  24 +}
0 \ No newline at end of file 25 \ No newline at end of file
src/components/market/AddMarketBlacklist.vue 0 → 100644
  1 +<template>
  2 + <el-dialog
  3 + :title="$t('marketBlacklist.add.title')"
  4 + :visible.sync="visible"
  5 + width="50%"
  6 + @close="handleClose"
  7 + >
  8 + <el-form ref="form" :model="formData" :rules="rules" label-width="120px">
  9 + <el-form-item :label="$t('marketBlacklist.form.personName')" prop="personName">
  10 + <el-input v-model="formData.personName" />
  11 + </el-form-item>
  12 + <el-form-item :label="$t('marketBlacklist.form.filter')" prop="filter">
  13 + <el-input v-model="formData.filter" />
  14 + </el-form-item>
  15 + <el-form-item :label="$t('marketBlacklist.form.remark')" prop="remark">
  16 + <el-input v-model="formData.remark" type="textarea" />
  17 + </el-form-item>
  18 + </el-form>
  19 +
  20 + <div slot="footer" class="dialog-footer">
  21 + <el-button @click="visible = false">{{ $t('common.cancel') }}</el-button>
  22 + <el-button type="primary" @click="handleSubmit">{{ $t('common.confirm') }}</el-button>
  23 + </div>
  24 + </el-dialog>
  25 +</template>
  26 +
  27 +<script>
  28 +import { saveMarketBlacklist } from '@/api/market/marketBlacklistManageApi'
  29 +
  30 +export default {
  31 + name: 'AddMarketBlacklist',
  32 + data() {
  33 + return {
  34 + visible: false,
  35 + formData: {
  36 + personName: '',
  37 + filter: '',
  38 + remark: ''
  39 + },
  40 + rules: {
  41 + personName: [
  42 + { required: true, message: this.$t('marketBlacklist.validate.personName'), trigger: 'blur' },
  43 + { max: 64, message: this.$t('marketBlacklist.validate.personNameMax'), trigger: 'blur' }
  44 + ],
  45 + filter: [
  46 + { required: true, message: this.$t('marketBlacklist.validate.filter'), trigger: 'blur' },
  47 + { max: 64, message: this.$t('marketBlacklist.validate.filterMax'), trigger: 'blur' }
  48 + ],
  49 + remark: [
  50 + { required: true, message: this.$t('marketBlacklist.validate.remark'), trigger: 'blur' },
  51 + { max: 512, message: this.$t('marketBlacklist.validate.remarkMax'), trigger: 'blur' }
  52 + ]
  53 + }
  54 + }
  55 + },
  56 + methods: {
  57 + open() {
  58 + this.visible = true
  59 + },
  60 + handleClose() {
  61 + this.$refs.form.resetFields()
  62 + },
  63 + handleSubmit() {
  64 + this.$refs.form.validate(async valid => {
  65 + if (valid) {
  66 + try {
  67 + await saveMarketBlacklist(this.formData)
  68 + this.$message.success(this.$t('marketBlacklist.add.success'))
  69 + this.visible = false
  70 + this.$emit('success')
  71 + } catch (error) {
  72 + this.$message.error(error.message)
  73 + }
  74 + }
  75 + })
  76 + }
  77 + }
  78 +}
  79 +</script>
0 \ No newline at end of file 80 \ No newline at end of file
src/components/market/DeleteMarketBlacklist.vue 0 → 100644
  1 +<template>
  2 + <el-dialog
  3 + :title="$t('marketBlacklist.delete.title')"
  4 + :visible.sync="visible"
  5 + width="30%"
  6 + >
  7 + <p>{{ $t('marketBlacklist.delete.confirm') }}</p>
  8 + <div slot="footer" class="dialog-footer">
  9 + <el-button @click="visible = false">{{ $t('common.cancel') }}</el-button>
  10 + <el-button type="primary" @click="handleConfirm">{{ $t('common.confirm') }}</el-button>
  11 + </div>
  12 + </el-dialog>
  13 +</template>
  14 +
  15 +<script>
  16 +import { deleteMarketBlacklist } from '@/api/market/marketBlacklistManageApi'
  17 +
  18 +export default {
  19 + name: 'DeleteMarketBlacklist',
  20 + data() {
  21 + return {
  22 + visible: false,
  23 + formData: {}
  24 + }
  25 + },
  26 + methods: {
  27 + open(data) {
  28 + this.formData = { ...data }
  29 + this.visible = true
  30 + },
  31 + async handleConfirm() {
  32 + try {
  33 + await deleteMarketBlacklist(this.formData)
  34 + this.$message.success(this.$t('marketBlacklist.delete.success'))
  35 + this.visible = false
  36 + this.$emit('success')
  37 + } catch (error) {
  38 + this.$message.error(error.message)
  39 + }
  40 + }
  41 + }
  42 +}
  43 +</script>
0 \ No newline at end of file 44 \ No newline at end of file
src/components/market/EditMarketBlacklist.vue 0 → 100644
  1 +<template>
  2 + <el-dialog
  3 + :title="$t('marketBlacklist.edit.title')"
  4 + :visible.sync="visible"
  5 + width="50%"
  6 + @close="handleClose"
  7 + >
  8 + <el-form ref="form" :model="formData" :rules="rules" label-width="120px">
  9 + <el-form-item :label="$t('marketBlacklist.form.personName')" prop="personName">
  10 + <el-input v-model="formData.personName" />
  11 + </el-form-item>
  12 + <el-form-item :label="$t('marketBlacklist.form.filter')" prop="filter">
  13 + <el-input v-model="formData.filter" />
  14 + </el-form-item>
  15 + <el-form-item :label="$t('marketBlacklist.form.remark')" prop="remark">
  16 + <el-input v-model="formData.remark" type="textarea" />
  17 + </el-form-item>
  18 + </el-form>
  19 +
  20 + <div slot="footer" class="dialog-footer">
  21 + <el-button @click="visible = false">{{ $t('common.cancel') }}</el-button>
  22 + <el-button type="primary" @click="handleSubmit">{{ $t('common.confirm') }}</el-button>
  23 + </div>
  24 + </el-dialog>
  25 +</template>
  26 +
  27 +<script>
  28 +import { updateMarketBlacklist } from '@/api/market/marketBlacklistManageApi'
  29 +
  30 +export default {
  31 + name: 'EditMarketBlacklist',
  32 + data() {
  33 + return {
  34 + visible: false,
  35 + formData: {
  36 + blId: '',
  37 + personName: '',
  38 + filter: '',
  39 + remark: ''
  40 + },
  41 + rules: {
  42 + personName: [
  43 + { required: true, message: this.$t('marketBlacklist.validate.personName'), trigger: 'blur' },
  44 + { max: 64, message: this.$t('marketBlacklist.validate.personNameMax'), trigger: 'blur' }
  45 + ],
  46 + filter: [
  47 + { required: true, message: this.$t('marketBlacklist.validate.filter'), trigger: 'blur' },
  48 + { max: 64, message: this.$t('marketBlacklist.validate.filterMax'), trigger: 'blur' }
  49 + ],
  50 + remark: [
  51 + { required: true, message: this.$t('marketBlacklist.validate.remark'), trigger: 'blur' },
  52 + { max: 512, message: this.$t('marketBlacklist.validate.remarkMax'), trigger: 'blur' }
  53 + ],
  54 + blId: [
  55 + { required: true, message: this.$t('marketBlacklist.validate.blId'), trigger: 'blur' }
  56 + ]
  57 + }
  58 + }
  59 + },
  60 + methods: {
  61 + open(data) {
  62 + this.formData = { ...data }
  63 + this.visible = true
  64 + },
  65 + handleClose() {
  66 + this.$refs.form.resetFields()
  67 + },
  68 + handleSubmit() {
  69 + this.$refs.form.validate(async valid => {
  70 + if (valid) {
  71 + try {
  72 + await updateMarketBlacklist(this.formData)
  73 + this.$message.success(this.$t('marketBlacklist.edit.success'))
  74 + this.visible = false
  75 + this.$emit('success')
  76 + } catch (error) {
  77 + this.$message.error(error.message)
  78 + }
  79 + }
  80 + })
  81 + }
  82 + }
  83 +}
  84 +</script>
0 \ No newline at end of file 85 \ No newline at end of file
src/components/market/ViewMarketSendContent.vue 0 → 100644
  1 +<template>
  2 + <el-dialog
  3 + :title="$t('marketLog.viewContent.title')"
  4 + :visible.sync="visible"
  5 + width="70%"
  6 + >
  7 + <el-form label-width="120px">
  8 + <el-form-item :label="$t('marketLog.viewContent.sendContent')">
  9 + <el-input
  10 + v-model="form.sendContent"
  11 + type="textarea"
  12 + :rows="8"
  13 + readonly
  14 + />
  15 + </el-form-item>
  16 + </el-form>
  17 + <span slot="footer" class="dialog-footer">
  18 + <el-button @click="visible = false">
  19 + {{ $t('common.close') }}
  20 + </el-button>
  21 + </span>
  22 + </el-dialog>
  23 +</template>
  24 +
  25 +<script>
  26 +export default {
  27 + name: 'ViewMarketSendContent',
  28 + data() {
  29 + return {
  30 + visible: false,
  31 + form: {
  32 + sendContent: ''
  33 + }
  34 + }
  35 + },
  36 + methods: {
  37 + open(data) {
  38 + this.form.sendContent = data.sendContent || ''
  39 + this.visible = true
  40 + }
  41 + }
  42 +}
  43 +</script>
0 \ No newline at end of file 44 \ No newline at end of file
src/i18n/index.js
@@ -100,6 +100,8 @@ import { messages as marketSmsManageMessages } from &#39;../views/market/marketSmsMa @@ -100,6 +100,8 @@ import { messages as marketSmsManageMessages } from &#39;../views/market/marketSmsMa
100 import { messages as marketWayMessages } from '../views/market/marketWayLang' 100 import { messages as marketWayMessages } from '../views/market/marketWayLang'
101 import { messages as marketGoodsItemManageMessages } from '../views/market/marketGoodsItemManageLang' 101 import { messages as marketGoodsItemManageMessages } from '../views/market/marketGoodsItemManageLang'
102 import { messages as marketRuleMessages } from '../views/market/marketRuleLang' 102 import { messages as marketRuleMessages } from '../views/market/marketRuleLang'
  103 +import { messages as marketBlacklistManageMessages } from '../views/market/marketBlacklistManageLang'
  104 +import { messages as marketLogMessages } from '../views/market/marketLogLang'
103 105
104 Vue.use(VueI18n) 106 Vue.use(VueI18n)
105 107
@@ -204,6 +206,8 @@ const messages = { @@ -204,6 +206,8 @@ const messages = {
204 ...marketWayMessages.en, 206 ...marketWayMessages.en,
205 ...marketGoodsItemManageMessages.en, 207 ...marketGoodsItemManageMessages.en,
206 ...marketRuleMessages.en, 208 ...marketRuleMessages.en,
  209 + ...marketBlacklistManageMessages.en,
  210 + ...marketLogMessages.en,
207 }, 211 },
208 zh: { 212 zh: {
209 ...loginMessages.zh, 213 ...loginMessages.zh,
@@ -304,6 +308,8 @@ const messages = { @@ -304,6 +308,8 @@ const messages = {
304 ...marketWayMessages.zh, 308 ...marketWayMessages.zh,
305 ...marketGoodsItemManageMessages.zh, 309 ...marketGoodsItemManageMessages.zh,
306 ...marketRuleMessages.zh, 310 ...marketRuleMessages.zh,
  311 + ...marketBlacklistManageMessages.zh,
  312 + ...marketLogMessages.zh,
307 } 313 }
308 } 314 }
309 315
src/router/index.js
@@ -486,6 +486,16 @@ const routes = [ @@ -486,6 +486,16 @@ const routes = [
486 name: '/pages/admin/marketRule', 486 name: '/pages/admin/marketRule',
487 component: () => import('@/views/market/marketRuleList.vue') 487 component: () => import('@/views/market/marketRuleList.vue')
488 }, 488 },
  489 + {
  490 + path:'/pages/admin/marketBlacklistManage',
  491 + name:'/pages/admin/marketBlacklistManage',
  492 + component: () => import('@/views/market/marketBlacklistManageList.vue')
  493 + },
  494 + {
  495 + path:'/pages/admin/marketLog',
  496 + name:'/pages/admin/marketLog',
  497 + component: () => import('@/views/market/marketLogList.vue')
  498 + },
489 // 其他子路由可以在这里添加 499 // 其他子路由可以在这里添加
490 ] 500 ]
491 }, 501 },
src/views/market/marketBlacklistManageLang.js 0 → 100644
  1 +export const messages = {
  2 + en: {
  3 + marketBlacklist: {
  4 + search: {
  5 + title: 'Search Conditions',
  6 + personName: 'Please enter person name',
  7 + filter: 'Please enter filter'
  8 + },
  9 + list: {
  10 + title: 'Marketing Blacklist'
  11 + },
  12 + table: {
  13 + personName: 'Person Name',
  14 + filter: 'Filter',
  15 + createTime: 'Create Time',
  16 + remark: 'Remark'
  17 + },
  18 + form: {
  19 + personName: 'Person Name',
  20 + filter: 'Filter',
  21 + remark: 'Remark'
  22 + },
  23 + validate: {
  24 + personName: 'Person name is required',
  25 + personNameMax: 'Person name cannot exceed 64 characters',
  26 + filter: 'Filter is required',
  27 + filterMax: 'Filter cannot exceed 64 characters',
  28 + remark: 'Remark is required',
  29 + remarkMax: 'Remark cannot exceed 512 characters',
  30 + blId: 'ID is required'
  31 + },
  32 + add: {
  33 + title: 'Add Marketing Blacklist',
  34 + success: 'Add successfully'
  35 + },
  36 + edit: {
  37 + title: 'Edit Marketing Blacklist',
  38 + success: 'Edit successfully'
  39 + },
  40 + delete: {
  41 + title: 'Delete Confirmation',
  42 + confirm: 'Are you sure to delete this marketing blacklist?',
  43 + success: 'Delete successfully'
  44 + },
  45 + fetchError: 'Failed to fetch marketing blacklist data'
  46 + }
  47 + },
  48 + zh: {
  49 + marketBlacklist: {
  50 + search: {
  51 + title: '查询条件',
  52 + personName: '请输入用户名称',
  53 + filter: '请输入过滤条件'
  54 + },
  55 + list: {
  56 + title: '营销黑白单'
  57 + },
  58 + table: {
  59 + personName: '用户名称',
  60 + filter: '过滤条件',
  61 + createTime: '创建时间',
  62 + remark: '备注'
  63 + },
  64 + form: {
  65 + personName: '用户名称',
  66 + filter: '过滤条件',
  67 + remark: '备注'
  68 + },
  69 + validate: {
  70 + personName: '用户名称不能为空',
  71 + personNameMax: '用户名称不能超过64个字符',
  72 + filter: '过滤条件不能为空',
  73 + filterMax: '过滤条件不能超过64个字符',
  74 + remark: '备注不能为空',
  75 + remarkMax: '备注不能超过512个字符',
  76 + blId: '编号不能为空'
  77 + },
  78 + add: {
  79 + title: '添加营销黑白单',
  80 + success: '添加成功'
  81 + },
  82 + edit: {
  83 + title: '修改营销黑白单',
  84 + success: '修改成功'
  85 + },
  86 + delete: {
  87 + title: '删除确认',
  88 + confirm: '确定删除该营销黑白单吗?',
  89 + success: '删除成功'
  90 + },
  91 + fetchError: '获取营销黑白单数据失败'
  92 + }
  93 + }
  94 +}
0 \ No newline at end of file 95 \ No newline at end of file
src/views/market/marketBlacklistManageList.vue 0 → 100644
  1 +<template>
  2 + <div class="market-blacklist-container">
  3 + <!-- 查询条件 -->
  4 + <el-card class="search-wrapper">
  5 + <div slot="header" class="clearfix text-left">
  6 + <span>{{ $t('marketBlacklist.search.title') }}</span>
  7 + </div>
  8 + <el-row :gutter="20">
  9 + <el-col :span="6">
  10 + <el-input v-model="searchForm.personName" :placeholder="$t('marketBlacklist.search.personName')" clearable />
  11 + </el-col>
  12 + <el-col :span="6">
  13 + <el-input v-model="searchForm.filter" :placeholder="$t('marketBlacklist.search.filter')" clearable />
  14 + </el-col>
  15 + <el-col :span="2">
  16 + <el-button type="primary" @click="handleSearch">{{ $t('common.search') }}</el-button>
  17 + </el-col>
  18 + </el-row>
  19 + </el-card>
  20 +
  21 + <!-- 列表 -->
  22 + <el-card class="list-wrapper">
  23 + <div slot="header" class="clearfix flex justify-between">
  24 + <span>{{ $t('marketBlacklist.list.title') }}</span>
  25 + <el-button type="primary" style="float: right" @click="handleAdd">{{ $t('common.add') }}</el-button>
  26 + </div>
  27 +
  28 + <el-table :data="tableData" border style="width: 100%">
  29 + <el-table-column prop="personName" :label="$t('marketBlacklist.table.personName')" align="center" />
  30 + <el-table-column prop="filter" :label="$t('marketBlacklist.table.filter')" align="center" />
  31 + <el-table-column prop="createTime" :label="$t('marketBlacklist.table.createTime')" align="center" />
  32 + <el-table-column prop="remark" :label="$t('marketBlacklist.table.remark')" align="center" />
  33 + <el-table-column :label="$t('common.operation')" align="center" width="200">
  34 + <template slot-scope="scope">
  35 + <el-button size="mini" type="primary" @click="handleEdit(scope.row)">{{ $t('common.edit') }}</el-button>
  36 + <el-button size="mini" type="danger" @click="handleDelete(scope.row)">{{ $t('common.delete') }}</el-button>
  37 + </template>
  38 + </el-table-column>
  39 + </el-table>
  40 +
  41 + <el-pagination :current-page.sync="page.current" :page-sizes="[10, 20, 30, 50]" :page-size="page.size"
  42 + :total="page.total" layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange"
  43 + @current-change="handleCurrentChange" />
  44 + </el-card>
  45 +
  46 + <!-- 组件 -->
  47 + <add-market-blacklist ref="addDialog" @success="handleSuccess" />
  48 + <edit-market-blacklist ref="editDialog" @success="handleSuccess" />
  49 + <delete-market-blacklist ref="deleteDialog" @success="handleSuccess" />
  50 + </div>
  51 +</template>
  52 +
  53 +<script>
  54 +import { listMarketBlacklist } from '@/api/market/marketBlacklistManageApi'
  55 +import AddMarketBlacklist from '@/components/market/AddMarketBlacklist'
  56 +import EditMarketBlacklist from '@/components/market/EditMarketBlacklist'
  57 +import DeleteMarketBlacklist from '@/components/market/DeleteMarketBlacklist'
  58 +
  59 +export default {
  60 + name: 'MarketBlacklistManageList',
  61 + components: {
  62 + AddMarketBlacklist,
  63 + EditMarketBlacklist,
  64 + DeleteMarketBlacklist
  65 + },
  66 + data() {
  67 + return {
  68 + loading: false,
  69 + searchForm: {
  70 + personName: '',
  71 + filter: ''
  72 + },
  73 + tableData: [],
  74 + page: {
  75 + current: 1,
  76 + size: 10,
  77 + total: 0
  78 + }
  79 + }
  80 + },
  81 + created() {
  82 + this.getList()
  83 + },
  84 + methods: {
  85 + async getList() {
  86 + try {
  87 + this.loading = true
  88 + const params = {
  89 + page: this.page.current,
  90 + row: this.page.size,
  91 + ...this.searchForm
  92 + }
  93 + const { data, records } = await listMarketBlacklist(params)
  94 + this.tableData = data
  95 + this.page.total = records
  96 + } catch (error) {
  97 + this.$message.error(this.$t('marketBlacklist.fetchError'))
  98 + } finally {
  99 + this.loading = false
  100 + }
  101 + },
  102 + handleSearch() {
  103 + this.page.current = 1
  104 + this.getList()
  105 + },
  106 + handleAdd() {
  107 + this.$refs.addDialog.open()
  108 + },
  109 + handleEdit(row) {
  110 + this.$refs.editDialog.open(row)
  111 + },
  112 + handleDelete(row) {
  113 + this.$refs.deleteDialog.open(row)
  114 + },
  115 + handleSuccess() {
  116 + this.getList()
  117 + },
  118 + handleSizeChange(val) {
  119 + this.page.size = val
  120 + this.getList()
  121 + },
  122 + handleCurrentChange(val) {
  123 + this.page.current = val
  124 + this.getList()
  125 + }
  126 + }
  127 +}
  128 +</script>
  129 +
  130 +<style lang="scss" scoped>
  131 +.market-blacklist-container {
  132 + padding: 20px;
  133 +
  134 + .search-wrapper {
  135 + margin-bottom: 20px;
  136 + }
  137 +
  138 + .el-pagination {
  139 + margin-top: 20px;
  140 + text-align: right;
  141 + }
  142 +}
  143 +</style>
0 \ No newline at end of file 144 \ No newline at end of file
src/views/market/marketLogLang.js 0 → 100644
  1 +export const messages = {
  2 + en: {
  3 + marketLog: {
  4 + search: {
  5 + title: 'Search Conditions',
  6 + communityName: 'Community Name',
  7 + sendWay: 'Marketing Method',
  8 + businessType: 'Business Type',
  9 + personNameLike: 'Marketer Name',
  10 + startTime: 'Start Time',
  11 + endTime: 'End Time'
  12 + },
  13 + list: {
  14 + title: 'Marketing Records'
  15 + },
  16 + table: {
  17 + logId: 'ID',
  18 + ruleName: 'Marketing Rule',
  19 + communityName: 'Community Name',
  20 + personName: 'Marketer',
  21 + personTel: 'Phone',
  22 + openId: 'OpenId',
  23 + sendWayName: 'Marketing Method',
  24 + businessTypeName: 'Business Type',
  25 + createTime: 'Send Time',
  26 + remark: 'Remark',
  27 + viewContent: 'View Content'
  28 + },
  29 + sendWay: {
  30 + sms: 'SMS',
  31 + wechat: 'WeChat Template Message',
  32 + other: 'Other'
  33 + },
  34 + businessType: {
  35 + accessControl: 'Access Control',
  36 + vehicleGate: 'Vehicle Gate',
  37 + mobilePayment: 'Mobile Payment',
  38 + repairOrder: 'Repair Order'
  39 + },
  40 + viewContent: {
  41 + title: 'Send Content',
  42 + sendContent: 'Send Content'
  43 + },
  44 + fetchError: 'Failed to fetch marketing logs'
  45 + }
  46 + },
  47 + zh: {
  48 + marketLog: {
  49 + search: {
  50 + title: '查询条件',
  51 + communityName: '小区名称',
  52 + sendWay: '营销方式',
  53 + businessType: '业务类型',
  54 + personNameLike: '营销人',
  55 + startTime: '开始时间',
  56 + endTime: '结束时间'
  57 + },
  58 + list: {
  59 + title: '营销记录'
  60 + },
  61 + table: {
  62 + logId: '编号',
  63 + ruleName: '营销规则',
  64 + communityName: '小区名称',
  65 + personName: '营销人',
  66 + personTel: '手机号',
  67 + openId: 'OpenId',
  68 + sendWayName: '营销方式',
  69 + businessTypeName: '业务类型',
  70 + createTime: '发送时间',
  71 + remark: '说明',
  72 + viewContent: '发送内容'
  73 + },
  74 + sendWay: {
  75 + sms: '短信',
  76 + wechat: '微信模板消息',
  77 + other: '其他'
  78 + },
  79 + businessType: {
  80 + accessControl: '门禁',
  81 + vehicleGate: '车辆道闸',
  82 + mobilePayment: '手机支付完成',
  83 + repairOrder: '报修单提交'
  84 + },
  85 + viewContent: {
  86 + title: '发送内容',
  87 + sendContent: '发送内容'
  88 + },
  89 + fetchError: '获取营销记录失败'
  90 + }
  91 + }
  92 +}
0 \ No newline at end of file 93 \ No newline at end of file
src/views/market/marketLogList.vue 0 → 100644
  1 +<template>
  2 + <div class="market-log-container">
  3 + <!-- Search Conditions -->
  4 + <el-card class="search-wrapper">
  5 + <div slot="header" class="clearfix text-left">
  6 + <span>{{ $t('marketLog.search.title') }}</span>
  7 + </div>
  8 + <el-row :gutter="20">
  9 + <el-col :span="4">
  10 + <el-input v-model="searchForm.communityName" :placeholder="$t('marketLog.search.communityName')" clearable />
  11 + </el-col>
  12 + <el-col :span="4">
  13 + <el-select v-model="searchForm.sendWay" :placeholder="$t('marketLog.search.sendWay')" clearable>
  14 + <el-option v-for="item in sendWayOptions" :key="item.value" :label="item.label" :value="item.value" />
  15 + </el-select>
  16 + </el-col>
  17 + <el-col :span="4">
  18 + <el-select v-model="searchForm.businessType" :placeholder="$t('marketLog.search.businessType')" clearable>
  19 + <el-option v-for="item in businessTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
  20 + </el-select>
  21 + </el-col>
  22 + <el-col :span="4">
  23 + <el-input v-model="searchForm.personNameLike" :placeholder="$t('marketLog.search.personNameLike')" clearable />
  24 + </el-col>
  25 +
  26 + <el-col :span="4">
  27 + <el-button type="primary" @click="handleSearch">
  28 + {{ $t('common.search') }}
  29 + </el-button>
  30 + </el-col>
  31 + </el-row>
  32 + <el-row :gutter="20" style="margin-top: 20px">
  33 + <el-col :span="4">
  34 + <el-date-picker v-model="searchForm.startTime" type="datetime" :placeholder="$t('marketLog.search.startTime')"
  35 + value-format="yyyy-MM-dd HH:mm:ss" />
  36 + </el-col>
  37 + <el-col :span="4">
  38 + <el-date-picker v-model="searchForm.endTime" type="datetime" :placeholder="$t('marketLog.search.endTime')"
  39 + value-format="yyyy-MM-dd HH:mm:ss" />
  40 + </el-col>
  41 + </el-row>
  42 + </el-card>
  43 +
  44 + <!-- Market Log List -->
  45 + <el-card class="list-wrapper">
  46 + <div slot="header" class="clearfix text-left">
  47 + <span>{{ $t('marketLog.list.title') }}</span>
  48 + </div>
  49 + <el-table v-loading="loading" :data="tableData" border style="width: 100%">
  50 + <el-table-column prop="logId" :label="$t('marketLog.table.logId')" align="center" />
  51 + <el-table-column prop="ruleName" :label="$t('marketLog.table.ruleName')" align="center" />
  52 + <el-table-column prop="communityName" :label="$t('marketLog.table.communityName')" align="center" />
  53 + <el-table-column prop="personName" :label="$t('marketLog.table.personName')" align="center" />
  54 + <el-table-column prop="personTel" :label="$t('marketLog.table.personTel')" align="center" />
  55 + <el-table-column prop="openId" :label="$t('marketLog.table.openId')" align="center" />
  56 + <el-table-column prop="sendWayName" :label="$t('marketLog.table.sendWayName')" align="center" />
  57 + <el-table-column prop="businessTypeName" :label="$t('marketLog.table.businessTypeName')" align="center" />
  58 + <el-table-column prop="createTime" :label="$t('marketLog.table.createTime')" align="center" />
  59 + <el-table-column prop="remark" :label="$t('marketLog.table.remark')" align="center" />
  60 + <el-table-column :label="$t('common.operation')" align="center" width="150">
  61 + <template slot-scope="scope">
  62 + <el-button size="mini" type="primary" @click="handleViewContent(scope.row)">
  63 + {{ $t('marketLog.table.viewContent') }}
  64 + </el-button>
  65 + </template>
  66 + </el-table-column>
  67 + </el-table>
  68 +
  69 + <el-pagination :current-page.sync="page.current" :page-sizes="[10, 20, 30, 50]" :page-size="page.size"
  70 + :total="page.total" layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange"
  71 + @current-change="handleCurrentChange" />
  72 + </el-card>
  73 +
  74 + <ViewMarketSendContent ref="viewContentDialog" />
  75 + </div>
  76 +</template>
  77 +
  78 +<script>
  79 +import { listMarketLog } from '@/api/market/marketLogApi'
  80 +import ViewMarketSendContent from '@/components/market/ViewMarketSendContent'
  81 +
  82 +export default {
  83 + name: 'MarketLogList',
  84 + components: {
  85 + ViewMarketSendContent
  86 + },
  87 + data() {
  88 + return {
  89 + loading: false,
  90 + searchForm: {
  91 + communityName: '',
  92 + sendWay: '',
  93 + businessType: '',
  94 + personNameLike: '',
  95 + startTime: '',
  96 + endTime: ''
  97 + },
  98 + sendWayOptions: [
  99 + { value: '1001', label: this.$t('marketLog.sendWay.sms') },
  100 + { value: '2002', label: this.$t('marketLog.sendWay.wechat') },
  101 + { value: '3003', label: this.$t('marketLog.sendWay.other') }
  102 + ],
  103 + businessTypeOptions: [
  104 + { value: '1001', label: this.$t('marketLog.businessType.accessControl') },
  105 + { value: '2002', label: this.$t('marketLog.businessType.vehicleGate') },
  106 + { value: '3003', label: this.$t('marketLog.businessType.mobilePayment') },
  107 + { value: '4004', label: this.$t('marketLog.businessType.repairOrder') }
  108 + ],
  109 + tableData: [],
  110 + page: {
  111 + current: 1,
  112 + size: 10,
  113 + total: 0
  114 + }
  115 + }
  116 + },
  117 + created() {
  118 + this.getList()
  119 + },
  120 + methods: {
  121 + async getList() {
  122 + try {
  123 + this.loading = true
  124 + const params = {
  125 + ...this.searchForm,
  126 + page: this.page.current,
  127 + row: this.page.size
  128 + }
  129 + const { data, total } = await listMarketLog(params)
  130 + this.tableData = data
  131 + this.page.total = total
  132 + } catch (error) {
  133 + this.$message.error(this.$t('marketLog.fetchError'))
  134 + } finally {
  135 + this.loading = false
  136 + }
  137 + },
  138 + handleSearch() {
  139 + this.page.current = 1
  140 + this.getList()
  141 + },
  142 + handleSizeChange(val) {
  143 + this.page.size = val
  144 + this.getList()
  145 + },
  146 + handleCurrentChange(val) {
  147 + this.page.current = val
  148 + this.getList()
  149 + },
  150 + handleViewContent(row) {
  151 + this.$refs.viewContentDialog.open(row)
  152 + }
  153 + }
  154 +}
  155 +</script>
  156 +
  157 +<style lang="scss" scoped>
  158 +.market-log-container {
  159 + padding: 20px;
  160 +
  161 + .search-wrapper {
  162 + margin-bottom: 20px;
  163 + }
  164 +
  165 + .list-wrapper {
  166 + margin-bottom: 20px;
  167 + }
  168 +
  169 + .el-pagination {
  170 + margin-top: 20px;
  171 + text-align: right;
  172 + }
  173 +}
  174 +</style>
0 \ No newline at end of file 175 \ No newline at end of file