Commit 1705091dba112b3e79c4e11ab669fa9b8c76f42b
1 parent
10d3499d
开发完成 admin 台账功能
Showing
31 changed files
with
2718 additions
and
0 deletions
src/api/admin/orderManageApi.js
0 → 100644
| 1 | +import request from '@/utils/request' | ||
| 2 | + | ||
| 3 | +// 获取订单列表 | ||
| 4 | +export function listCorders(params) { | ||
| 5 | + return new Promise((resolve, reject) => { | ||
| 6 | + request({ | ||
| 7 | + url: '/corders.listCorders', | ||
| 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 listPublicApps(params) { | ||
| 25 | + return new Promise((resolve, reject) => { | ||
| 26 | + request({ | ||
| 27 | + url: '/app.listPublicApps', | ||
| 28 | + method: 'get', | ||
| 29 | + params | ||
| 30 | + }).then(response => { | ||
| 31 | + const res = response.data | ||
| 32 | + resolve(res) | ||
| 33 | + }).catch(error => { | ||
| 34 | + reject(error) | ||
| 35 | + }) | ||
| 36 | + }) | ||
| 37 | +} | ||
| 38 | + | ||
| 39 | +// 获取订单日志 | ||
| 40 | +export function listUnitemLog(params) { | ||
| 41 | + return new Promise((resolve, reject) => { | ||
| 42 | + request({ | ||
| 43 | + url: '/corders.listUnitemLog', | ||
| 44 | + method: 'get', | ||
| 45 | + params | ||
| 46 | + }).then(response => { | ||
| 47 | + const res = response.data | ||
| 48 | + if (res.code === 0) { | ||
| 49 | + resolve(res) | ||
| 50 | + } else { | ||
| 51 | + reject(new Error(res.msg || '获取订单日志失败')) | ||
| 52 | + } | ||
| 53 | + }).catch(error => { | ||
| 54 | + reject(error) | ||
| 55 | + }) | ||
| 56 | + }) | ||
| 57 | +} | ||
| 0 | \ No newline at end of file | 58 | \ No newline at end of file |
src/api/mall/housekeepingSjServApi.js
0 → 100644
| 1 | +import request from '@/utils/request' | ||
| 2 | + | ||
| 3 | +// 查询家政服务列表 | ||
| 4 | +export function queryHousekeepingServ(params) { | ||
| 5 | + return new Promise((resolve, reject) => { | ||
| 6 | + request({ | ||
| 7 | + url: '/mall.getAdminMallOpenApi', | ||
| 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 | + records: res.records | ||
| 17 | + }) | ||
| 18 | + } else { | ||
| 19 | + reject(new Error(res.msg || '查询家政服务列表失败')) | ||
| 20 | + } | ||
| 21 | + }).catch(error => { | ||
| 22 | + reject(error) | ||
| 23 | + }) | ||
| 24 | + }) | ||
| 25 | +} | ||
| 26 | + | ||
| 27 | +// 查询家政服务类型 | ||
| 28 | +export function queryHousekeepingType(params) { | ||
| 29 | + return new Promise((resolve, reject) => { | ||
| 30 | + request({ | ||
| 31 | + url: '/housekeepingType/queryHousekeepingType', | ||
| 32 | + method: 'get', | ||
| 33 | + params | ||
| 34 | + }).then(response => { | ||
| 35 | + const res = response.data | ||
| 36 | + if (res.code === 0) { | ||
| 37 | + resolve({ | ||
| 38 | + data: res.data | ||
| 39 | + }) | ||
| 40 | + } else { | ||
| 41 | + reject(new Error(res.msg || '查询家政服务类型失败')) | ||
| 42 | + } | ||
| 43 | + }).catch(error => { | ||
| 44 | + reject(error) | ||
| 45 | + }) | ||
| 46 | + }) | ||
| 47 | +} | ||
| 0 | \ No newline at end of file | 48 | \ No newline at end of file |
src/api/mall/integralDetailApi.js
0 → 100644
| 1 | +import request from '@/utils/request' | ||
| 2 | + | ||
| 3 | +// 获取积分交易明细列表 | ||
| 4 | +export function getIntegralDetailList(params) { | ||
| 5 | + return new Promise((resolve, reject) => { | ||
| 6 | + request({ | ||
| 7 | + url: '/mall.getAdminMallOpenApi', | ||
| 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 points transaction details')) | ||
| 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/api/mall/productSjApi.js
0 → 100644
| 1 | +import request from '@/utils/request' | ||
| 2 | + | ||
| 3 | +// 获取商品列表 | ||
| 4 | +export function getAdminProductList(params) { | ||
| 5 | + return new Promise((resolve, reject) => { | ||
| 6 | + request({ | ||
| 7 | + url: '/mall.getAdminMallOpenApi', | ||
| 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 product list')) | ||
| 19 | + } | ||
| 20 | + }).catch(error => { | ||
| 21 | + reject(error) | ||
| 22 | + }) | ||
| 23 | + }) | ||
| 24 | +} | ||
| 25 | + | ||
| 26 | +// 删除商品 | ||
| 27 | +export function deleteProduct(data) { | ||
| 28 | + return new Promise((resolve, reject) => { | ||
| 29 | + request({ | ||
| 30 | + url: '/product/deleteProduct', | ||
| 31 | + method: 'post', | ||
| 32 | + data | ||
| 33 | + }).then(response => { | ||
| 34 | + const res = response.data | ||
| 35 | + if (res.code === 0) { | ||
| 36 | + resolve(res) | ||
| 37 | + } else { | ||
| 38 | + reject(new Error(res.msg || 'Failed to delete product')) | ||
| 39 | + } | ||
| 40 | + }).catch(error => { | ||
| 41 | + reject(error) | ||
| 42 | + }) | ||
| 43 | + }) | ||
| 44 | +} | ||
| 0 | \ No newline at end of file | 45 | \ No newline at end of file |
src/api/mall/storeOrderCartManageApi.js
0 → 100644
| 1 | +import request from '@/utils/request' | ||
| 2 | + | ||
| 3 | +// 查询订单列表 | ||
| 4 | +export function queryAdminStoreOrderCart(params) { | ||
| 5 | + return new Promise((resolve, reject) => { | ||
| 6 | + request({ | ||
| 7 | + url: '/mall.getAdminMallOpenApi', | ||
| 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 query order list')) | ||
| 19 | + } | ||
| 20 | + }).catch(error => { | ||
| 21 | + reject(error) | ||
| 22 | + }) | ||
| 23 | + }) | ||
| 24 | +} | ||
| 25 | + | ||
| 26 | +// 查询商铺列表 | ||
| 27 | +export function queryShopsByAdmin(params) { | ||
| 28 | + return new Promise((resolve, reject) => { | ||
| 29 | + request({ | ||
| 30 | + url: '/mall.getAdminMallOpenApi', | ||
| 31 | + method: 'get', | ||
| 32 | + params | ||
| 33 | + }).then(response => { | ||
| 34 | + const res = response.data | ||
| 35 | + if (res.code === 0) { | ||
| 36 | + resolve({ | ||
| 37 | + data: res.data, | ||
| 38 | + total: res.total | ||
| 39 | + }) | ||
| 40 | + } else { | ||
| 41 | + reject(new Error(res.msg || 'Failed to query shops')) | ||
| 42 | + } | ||
| 43 | + }).catch(error => { | ||
| 44 | + reject(error) | ||
| 45 | + }) | ||
| 46 | + }) | ||
| 47 | +} | ||
| 0 | \ No newline at end of file | 48 | \ No newline at end of file |
src/api/mall/storeOrderCartReturnApi.js
0 → 100644
| 1 | +import request from '@/utils/request' | ||
| 2 | + | ||
| 3 | +// 获取退货订单列表 | ||
| 4 | +export function getStoreOrderCartReturnList(params) { | ||
| 5 | + return new Promise((resolve, reject) => { | ||
| 6 | + request({ | ||
| 7 | + url: '/mall.getAdminMallOpenApi', | ||
| 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 store order cart return list')) | ||
| 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/api/mall/userIntegralApi.js
0 → 100644
| 1 | +import request from '@/utils/request' | ||
| 2 | + | ||
| 3 | +// 查询积分列表 | ||
| 4 | +export function queryIntegralList(params) { | ||
| 5 | + return new Promise((resolve, reject) => { | ||
| 6 | + request({ | ||
| 7 | + url: '/mall.getAdminMallOpenApi', | ||
| 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 | +} | ||
| 0 | \ No newline at end of file | 22 | \ No newline at end of file |
src/api/user/userLoginApi.js
0 → 100644
| 1 | +import request from '@/utils/request' | ||
| 2 | + | ||
| 3 | +// 查询用户登录日志 | ||
| 4 | +export function queryUserLogin(params) { | ||
| 5 | + return new Promise((resolve, reject) => { | ||
| 6 | + request({ | ||
| 7 | + url: '/userLogin/queryUserLogin', | ||
| 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 | + records: res.records, | ||
| 16 | + total: res.total | ||
| 17 | + }) | ||
| 18 | + } else { | ||
| 19 | + reject(new Error(res.msg || 'Failed to query user login logs')) | ||
| 20 | + } | ||
| 21 | + }).catch(error => { | ||
| 22 | + reject(error) | ||
| 23 | + }) | ||
| 24 | + }) | ||
| 25 | +} | ||
| 26 | + | ||
| 27 | +// 获取门店列表 | ||
| 28 | +export function listStores(params) { | ||
| 29 | + return new Promise((resolve, reject) => { | ||
| 30 | + request({ | ||
| 31 | + url: '/store.listStores', | ||
| 32 | + method: 'get', | ||
| 33 | + params | ||
| 34 | + }).then(response => { | ||
| 35 | + const res = response.data | ||
| 36 | + if (res.code === 0) { | ||
| 37 | + resolve({ | ||
| 38 | + data: res.data | ||
| 39 | + }) | ||
| 40 | + } else { | ||
| 41 | + reject(new Error(res.msg || 'Failed to get store list')) | ||
| 42 | + } | ||
| 43 | + }).catch(error => { | ||
| 44 | + reject(error) | ||
| 45 | + }) | ||
| 46 | + }) | ||
| 47 | +} | ||
| 0 | \ No newline at end of file | 48 | \ No newline at end of file |
src/components/admin/viewUnItemLog.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <el-dialog | ||
| 3 | + :title="$t('viewUnItemLog.title')" | ||
| 4 | + :visible.sync="visible" | ||
| 5 | + width="70%" | ||
| 6 | + > | ||
| 7 | + <el-form label-width="120px"> | ||
| 8 | + <el-form-item :label="$t('viewUnItemLog.serviceName')"> | ||
| 9 | + <el-input v-model="viewUnItemLogInfo.serviceName" disabled /> | ||
| 10 | + </el-form-item> | ||
| 11 | + <el-row> | ||
| 12 | + <el-col :span="12"> | ||
| 13 | + <el-form-item :label="$t('viewUnItemLog.action')"> | ||
| 14 | + <el-input v-model="viewUnItemLogInfo.action" disabled /> | ||
| 15 | + </el-form-item> | ||
| 16 | + </el-col> | ||
| 17 | + <el-col :span="12"> | ||
| 18 | + <el-form-item :label="$t('viewUnItemLog.actionObj')"> | ||
| 19 | + <el-input v-model="viewUnItemLogInfo.actionObj" disabled /> | ||
| 20 | + </el-form-item> | ||
| 21 | + </el-col> | ||
| 22 | + </el-row> | ||
| 23 | + <el-form-item :label="$t('viewUnItemLog.preValue')"> | ||
| 24 | + <el-input | ||
| 25 | + v-model="viewUnItemLogInfo.preValue" | ||
| 26 | + type="textarea" | ||
| 27 | + :rows="5" | ||
| 28 | + disabled | ||
| 29 | + /> | ||
| 30 | + </el-form-item> | ||
| 31 | + <el-form-item :label="$t('viewUnItemLog.afterValue')"> | ||
| 32 | + <el-input | ||
| 33 | + v-model="viewUnItemLogInfo.afterValue" | ||
| 34 | + type="textarea" | ||
| 35 | + :rows="5" | ||
| 36 | + disabled | ||
| 37 | + /> | ||
| 38 | + </el-form-item> | ||
| 39 | + <el-form-item :label="$t('viewUnItemLog.logText')"> | ||
| 40 | + <el-input | ||
| 41 | + v-model="viewUnItemLogInfo.logText" | ||
| 42 | + type="textarea" | ||
| 43 | + :rows="5" | ||
| 44 | + disabled | ||
| 45 | + /> | ||
| 46 | + </el-form-item> | ||
| 47 | + </el-form> | ||
| 48 | + <div slot="footer" class="dialog-footer"> | ||
| 49 | + <el-button type="warning" @click="visible = false"> | ||
| 50 | + {{ $t('common.cancel') }} | ||
| 51 | + </el-button> | ||
| 52 | + </div> | ||
| 53 | + </el-dialog> | ||
| 54 | +</template> | ||
| 55 | + | ||
| 56 | +<script> | ||
| 57 | +import { listUnitemLog } from '@/api/admin/orderManageApi' | ||
| 58 | + | ||
| 59 | +export default { | ||
| 60 | + name: 'ViewUnItemLog', | ||
| 61 | + data() { | ||
| 62 | + return { | ||
| 63 | + visible: false, | ||
| 64 | + viewUnItemLogInfo: { | ||
| 65 | + bId: '', | ||
| 66 | + serviceName: '', | ||
| 67 | + logText: '', | ||
| 68 | + preValue: '', | ||
| 69 | + afterValue: '', | ||
| 70 | + action: '', | ||
| 71 | + actionObj: '' | ||
| 72 | + } | ||
| 73 | + } | ||
| 74 | + }, | ||
| 75 | + methods: { | ||
| 76 | + open(order) { | ||
| 77 | + this.clearLog() | ||
| 78 | + this.viewUnItemLogInfo.bId = order.bId | ||
| 79 | + | ||
| 80 | + if (order.action === 'ADD') { | ||
| 81 | + this.viewUnItemLogInfo.action = this.$t('viewUnItemLog.add') | ||
| 82 | + } else if (order.action === 'MOD') { | ||
| 83 | + this.viewUnItemLogInfo.action = this.$t('viewUnItemLog.modify') | ||
| 84 | + } else if (order.action === 'DEL') { | ||
| 85 | + this.viewUnItemLogInfo.action = this.$t('viewUnItemLog.delete') | ||
| 86 | + } else { | ||
| 87 | + this.viewUnItemLogInfo.action = '-' | ||
| 88 | + } | ||
| 89 | + | ||
| 90 | + this.viewUnItemLogInfo.actionObj = order.actionObj | ||
| 91 | + this.visible = true | ||
| 92 | + this._loadOrderUnitemLog() | ||
| 93 | + }, | ||
| 94 | + async _loadOrderUnitemLog() { | ||
| 95 | + try { | ||
| 96 | + const res = await listUnitemLog({ bId: this.viewUnItemLogInfo.bId }) | ||
| 97 | + Object.assign(this.viewUnItemLogInfo, res.data) | ||
| 98 | + | ||
| 99 | + const logText = JSON.parse(res.data.logText) | ||
| 100 | + this.viewUnItemLogInfo.preValue = JSON.stringify(logText.preValue, null, 2) | ||
| 101 | + this.viewUnItemLogInfo.afterValue = JSON.stringify(logText.afterValue, null, 2) | ||
| 102 | + } catch (error) { | ||
| 103 | + this.$message.error(this.$t('viewUnItemLog.fetchError')) | ||
| 104 | + } | ||
| 105 | + }, | ||
| 106 | + clearLog() { | ||
| 107 | + this.viewUnItemLogInfo = { | ||
| 108 | + bId: '', | ||
| 109 | + serviceName: '', | ||
| 110 | + logText: '', | ||
| 111 | + preValue: '', | ||
| 112 | + afterValue: '', | ||
| 113 | + action: '', | ||
| 114 | + actionObj: '' | ||
| 115 | + } | ||
| 116 | + } | ||
| 117 | + } | ||
| 118 | +} | ||
| 119 | +</script> | ||
| 0 | \ No newline at end of file | 120 | \ No newline at end of file |
src/components/mall/DeleteProduct.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <el-dialog | ||
| 3 | + :title="$t('deleteProduct.title')" | ||
| 4 | + :visible.sync="visible" | ||
| 5 | + width="30%" | ||
| 6 | + :before-close="handleClose" | ||
| 7 | + > | ||
| 8 | + <div style="text-align: center;"> | ||
| 9 | + <p>{{ $t('deleteProduct.confirm') }}</p> | ||
| 10 | + </div> | ||
| 11 | + <span slot="footer" class="dialog-footer"> | ||
| 12 | + <el-button @click="handleClose">{{ $t('deleteProduct.cancel') }}</el-button> | ||
| 13 | + <el-button type="primary" @click="confirmDelete">{{ $t('deleteProduct.confirmBtn') }}</el-button> | ||
| 14 | + </span> | ||
| 15 | + </el-dialog> | ||
| 16 | +</template> | ||
| 17 | + | ||
| 18 | +<script> | ||
| 19 | +import { deleteProduct } from '@/api/mall/productSjApi' | ||
| 20 | + | ||
| 21 | +export default { | ||
| 22 | + name: 'DeleteProduct', | ||
| 23 | + data() { | ||
| 24 | + return { | ||
| 25 | + visible: false, | ||
| 26 | + productId: '' | ||
| 27 | + } | ||
| 28 | + }, | ||
| 29 | + methods: { | ||
| 30 | + open(productId) { | ||
| 31 | + this.productId = productId | ||
| 32 | + this.visible = true | ||
| 33 | + }, | ||
| 34 | + handleClose() { | ||
| 35 | + this.visible = false | ||
| 36 | + }, | ||
| 37 | + async confirmDelete() { | ||
| 38 | + try { | ||
| 39 | + await deleteProduct({ productId: this.productId }) | ||
| 40 | + this.$message.success(this.$t('deleteProduct.success')) | ||
| 41 | + this.$emit('success') | ||
| 42 | + this.handleClose() | ||
| 43 | + } catch (error) { | ||
| 44 | + this.$message.error(this.$t('deleteProduct.error')) | ||
| 45 | + } | ||
| 46 | + } | ||
| 47 | + } | ||
| 48 | +} | ||
| 49 | +</script> | ||
| 0 | \ No newline at end of file | 50 | \ No newline at end of file |
src/components/mall/DeleteProductLang.js
0 → 100644
| 1 | +export const messages = { | ||
| 2 | + en: { | ||
| 3 | + deleteProduct: { | ||
| 4 | + title: 'Please confirm your operation', | ||
| 5 | + confirm: 'Are you sure to delete this product?', | ||
| 6 | + cancel: 'Cancel', | ||
| 7 | + confirmBtn: 'Confirm Delete', | ||
| 8 | + success: 'Product deleted successfully', | ||
| 9 | + error: 'Failed to delete product' | ||
| 10 | + } | ||
| 11 | + }, | ||
| 12 | + zh: { | ||
| 13 | + deleteProduct: { | ||
| 14 | + title: '请确认您的操作', | ||
| 15 | + confirm: '确定删除该商品吗?', | ||
| 16 | + cancel: '点错了', | ||
| 17 | + confirmBtn: '确认删除', | ||
| 18 | + success: '商品删除成功', | ||
| 19 | + error: '删除商品失败' | ||
| 20 | + } | ||
| 21 | + } | ||
| 22 | +} | ||
| 0 | \ No newline at end of file | 23 | \ No newline at end of file |
src/components/mall/Pagination.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <el-pagination | ||
| 3 | + :current-page.sync="currentPage" | ||
| 4 | + :page-sizes="[10, 20, 30, 50]" | ||
| 5 | + :page-size="pageSize" | ||
| 6 | + :total="total" | ||
| 7 | + layout="total, sizes, prev, pager, next, jumper" | ||
| 8 | + @size-change="handleSizeChange" | ||
| 9 | + @current-change="handleCurrentChange" | ||
| 10 | + /> | ||
| 11 | +</template> | ||
| 12 | + | ||
| 13 | +<script> | ||
| 14 | +export default { | ||
| 15 | + name: 'Pagination', | ||
| 16 | + props: { | ||
| 17 | + currentPage: { | ||
| 18 | + type: Number, | ||
| 19 | + default: 1 | ||
| 20 | + }, | ||
| 21 | + pageSize: { | ||
| 22 | + type: Number, | ||
| 23 | + default: 10 | ||
| 24 | + }, | ||
| 25 | + total: { | ||
| 26 | + type: Number, | ||
| 27 | + default: 0 | ||
| 28 | + } | ||
| 29 | + }, | ||
| 30 | + methods: { | ||
| 31 | + handleSizeChange(val) { | ||
| 32 | + this.$emit('size-change', val) | ||
| 33 | + }, | ||
| 34 | + handleCurrentChange(val) { | ||
| 35 | + this.$emit('current-change', val) | ||
| 36 | + } | ||
| 37 | + } | ||
| 38 | +} | ||
| 39 | +</script> | ||
| 0 | \ No newline at end of file | 40 | \ No newline at end of file |
src/components/user/Pagination.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <el-pagination | ||
| 3 | + @size-change="handleSizeChange" | ||
| 4 | + @current-change="handleCurrentChange" | ||
| 5 | + :current-page="currentPage" | ||
| 6 | + :page-sizes="[10, 20, 30, 50]" | ||
| 7 | + :page-size="pageSize" | ||
| 8 | + layout="total, sizes, prev, pager, next, jumper" | ||
| 9 | + :total="total"> | ||
| 10 | + </el-pagination> | ||
| 11 | +</template> | ||
| 12 | + | ||
| 13 | +<script> | ||
| 14 | +export default { | ||
| 15 | + name: 'Pagination', | ||
| 16 | + props: { | ||
| 17 | + currentPage: { | ||
| 18 | + type: Number, | ||
| 19 | + default: 1 | ||
| 20 | + }, | ||
| 21 | + pageSize: { | ||
| 22 | + type: Number, | ||
| 23 | + default: 10 | ||
| 24 | + }, | ||
| 25 | + total: { | ||
| 26 | + type: Number, | ||
| 27 | + default: 0 | ||
| 28 | + } | ||
| 29 | + }, | ||
| 30 | + methods: { | ||
| 31 | + handleSizeChange(val) { | ||
| 32 | + this.$emit('size-change', val) | ||
| 33 | + }, | ||
| 34 | + handleCurrentChange(val) { | ||
| 35 | + this.$emit('current-change', val) | ||
| 36 | + } | ||
| 37 | + } | ||
| 38 | +} | ||
| 39 | +</script> | ||
| 0 | \ No newline at end of file | 40 | \ No newline at end of file |
src/i18n/index.js
| @@ -88,6 +88,14 @@ import { messages as operationalAnalysisMessages } from '../views/report/operati | @@ -88,6 +88,14 @@ import { messages as operationalAnalysisMessages } from '../views/report/operati | ||
| 88 | import { messages as communityFeeSummaryMessages } from '../views/report/communityFeeSummaryLang' | 88 | import { messages as communityFeeSummaryMessages } from '../views/report/communityFeeSummaryLang' |
| 89 | import { messages as adminPayFeeDetailMessages } from '../views/fee/adminPayFeeDetailLang' | 89 | import { messages as adminPayFeeDetailMessages } from '../views/fee/adminPayFeeDetailLang' |
| 90 | import { messages as adminOweFeeDetailMessages } from '../views/fee/adminOweFeeDetailLang' | 90 | import { messages as adminOweFeeDetailMessages } from '../views/fee/adminOweFeeDetailLang' |
| 91 | +import { messages as orderManageMessages } from '../views/admin/orderManageLang' | ||
| 92 | +import { messages as userLoginMessages } from '../views/user/userLoginLang' | ||
| 93 | +import { messages as productSjMessages } from '../views/mall/productSjLang' | ||
| 94 | +import { messages as housekeepingSjServMessages } from '../views/mall/housekeepingSjServLang' | ||
| 95 | +import { messages as storeOrderCartManageMessages } from '../views/mall/storeOrderCartManageLang' | ||
| 96 | +import { messages as storeOrderCartReturnMessages } from '../views/mall/storeOrderCartReturnLang' | ||
| 97 | +import { messages as userIntegralMessages } from '../views/mall/userIntegralLang' | ||
| 98 | +import { messages as integralDetailMessages } from '../views/mall/integralDetailLang' | ||
| 91 | 99 | ||
| 92 | Vue.use(VueI18n) | 100 | Vue.use(VueI18n) |
| 93 | 101 | ||
| @@ -180,6 +188,14 @@ const messages = { | @@ -180,6 +188,14 @@ const messages = { | ||
| 180 | ...communityFeeSummaryMessages.en, | 188 | ...communityFeeSummaryMessages.en, |
| 181 | ...adminPayFeeDetailMessages.en, | 189 | ...adminPayFeeDetailMessages.en, |
| 182 | ...adminOweFeeDetailMessages.en, | 190 | ...adminOweFeeDetailMessages.en, |
| 191 | + ...orderManageMessages.en, | ||
| 192 | + ...userLoginMessages.en, | ||
| 193 | + ...productSjMessages.en, | ||
| 194 | + ...housekeepingSjServMessages.en, | ||
| 195 | + ...storeOrderCartManageMessages.en, | ||
| 196 | + ...storeOrderCartReturnMessages.en, | ||
| 197 | + ...userIntegralMessages.en, | ||
| 198 | + ...integralDetailMessages.en, | ||
| 183 | }, | 199 | }, |
| 184 | zh: { | 200 | zh: { |
| 185 | ...loginMessages.zh, | 201 | ...loginMessages.zh, |
| @@ -268,6 +284,14 @@ const messages = { | @@ -268,6 +284,14 @@ const messages = { | ||
| 268 | ...communityFeeSummaryMessages.zh, | 284 | ...communityFeeSummaryMessages.zh, |
| 269 | ...adminPayFeeDetailMessages.zh, | 285 | ...adminPayFeeDetailMessages.zh, |
| 270 | ...adminOweFeeDetailMessages.zh, | 286 | ...adminOweFeeDetailMessages.zh, |
| 287 | + ...orderManageMessages.zh, | ||
| 288 | + ...userLoginMessages.zh, | ||
| 289 | + ...productSjMessages.zh, | ||
| 290 | + ...housekeepingSjServMessages.zh, | ||
| 291 | + ...storeOrderCartManageMessages.zh, | ||
| 292 | + ...storeOrderCartReturnMessages.zh, | ||
| 293 | + ...userIntegralMessages.zh, | ||
| 294 | + ...integralDetailMessages.zh, | ||
| 271 | } | 295 | } |
| 272 | } | 296 | } |
| 273 | 297 |
src/router/index.js
| @@ -426,6 +426,46 @@ const routes = [ | @@ -426,6 +426,46 @@ const routes = [ | ||
| 426 | name: '/pages/fee/adminOweFeeDetail', | 426 | name: '/pages/fee/adminOweFeeDetail', |
| 427 | component: () => import('@/views/fee/adminOweFeeDetailList.vue') | 427 | component: () => import('@/views/fee/adminOweFeeDetailList.vue') |
| 428 | }, | 428 | }, |
| 429 | + { | ||
| 430 | + path: '/pages/admin/orderManage', | ||
| 431 | + name: '/pages/admin/orderManage', | ||
| 432 | + component: () => import('@/views/admin/orderManageList.vue') | ||
| 433 | + }, | ||
| 434 | + { | ||
| 435 | + path: '/pages/frame/userLogin', | ||
| 436 | + name: '/pages/frame/userLogin', | ||
| 437 | + component: () => import('@/views/user/userLoginList.vue') | ||
| 438 | + }, | ||
| 439 | + { | ||
| 440 | + path: '/pages/admin/productSj', | ||
| 441 | + name: '/pages/admin/productSj', | ||
| 442 | + component: () => import('@/views/mall/productSjList.vue') | ||
| 443 | + }, | ||
| 444 | + { | ||
| 445 | + path: '/pages/admin/housekeepingSjServ', | ||
| 446 | + name: '/pages/admin/housekeepingSjServ', | ||
| 447 | + component: () => import('@/views/mall/housekeepingSjServList.vue') | ||
| 448 | + }, | ||
| 449 | + { | ||
| 450 | + path: '/pages/admin/storeOrderCartManage', | ||
| 451 | + name: '/pages/admin/storeOrderCartManage', | ||
| 452 | + component: () => import('@/views/mall/storeOrderCartManageList.vue') | ||
| 453 | + }, | ||
| 454 | + { | ||
| 455 | + path: '/pages/admin/storeOrderCartReturn', | ||
| 456 | + name: '/pages/admin/storeOrderCartReturn', | ||
| 457 | + component: () => import('@/views/mall/storeOrderCartReturnList.vue') | ||
| 458 | + }, | ||
| 459 | + { | ||
| 460 | + path: '/pages/admin/userIntegral', | ||
| 461 | + name: '/pages/admin/userIntegral', | ||
| 462 | + component: () => import('@/views/mall/userIntegralList.vue') | ||
| 463 | + }, | ||
| 464 | + { | ||
| 465 | + path: '/pages/admin/integralDetail', | ||
| 466 | + name: '/pages/admin/integralDetail', | ||
| 467 | + component: () => import('@/views/mall/integralDetailList.vue') | ||
| 468 | + }, | ||
| 429 | // 其他子路由可以在这里添加 | 469 | // 其他子路由可以在这里添加 |
| 430 | ] | 470 | ] |
| 431 | }, | 471 | }, |
src/views/admin/orderManageLang.js
0 → 100644
| 1 | +export const messages = { | ||
| 2 | + en: { | ||
| 3 | + orderManage: { | ||
| 4 | + queryCondition: 'Query Condition', | ||
| 5 | + orderList: 'Order List', | ||
| 6 | + orderId: 'Order ID', | ||
| 7 | + externalId: 'External ID', | ||
| 8 | + businessId: 'Business ID', | ||
| 9 | + startTime: 'Start Time', | ||
| 10 | + endTime: 'End Time', | ||
| 11 | + operator: 'Operator', | ||
| 12 | + businessName: 'Business Name', | ||
| 13 | + appName: 'App Name', | ||
| 14 | + createTime: 'Create Time', | ||
| 15 | + action: 'Action', | ||
| 16 | + actionObj: 'Action Object', | ||
| 17 | + status: 'Status', | ||
| 18 | + operation: 'Operation', | ||
| 19 | + log: 'Log', | ||
| 20 | + noLog: 'No Log', | ||
| 21 | + add: 'Add', | ||
| 22 | + modify: 'Modify', | ||
| 23 | + delete: 'Delete', | ||
| 24 | + completed: 'Completed', | ||
| 25 | + failed: 'Failed', | ||
| 26 | + allApps: 'All Apps', | ||
| 27 | + fetchError: 'Failed to fetch orders', | ||
| 28 | + fetchAppsError: 'Failed to fetch apps' | ||
| 29 | + }, | ||
| 30 | + viewUnItemLog: { | ||
| 31 | + title: 'Order Log', | ||
| 32 | + serviceName: 'Service Name', | ||
| 33 | + action: 'Action', | ||
| 34 | + actionObj: 'Action Object', | ||
| 35 | + preValue: 'Before Value', | ||
| 36 | + afterValue: 'After Value', | ||
| 37 | + logText: 'Original Log', | ||
| 38 | + add: 'Add', | ||
| 39 | + modify: 'Modify', | ||
| 40 | + delete: 'Delete', | ||
| 41 | + fetchError: 'Failed to fetch log' | ||
| 42 | + } | ||
| 43 | + }, | ||
| 44 | + zh: { | ||
| 45 | + orderManage: { | ||
| 46 | + queryCondition: '查询条件', | ||
| 47 | + orderList: '受理单', | ||
| 48 | + orderId: '订单编号', | ||
| 49 | + externalId: '外部编号', | ||
| 50 | + businessId: '业务编号', | ||
| 51 | + startTime: '受理开始时间', | ||
| 52 | + endTime: '受理结束时间', | ||
| 53 | + operator: '操作人', | ||
| 54 | + businessName: '业务名称', | ||
| 55 | + appName: '应用名称', | ||
| 56 | + createTime: '受理时间', | ||
| 57 | + action: '受理动作', | ||
| 58 | + actionObj: '受理表', | ||
| 59 | + status: '状态', | ||
| 60 | + operation: '操作', | ||
| 61 | + log: '日志', | ||
| 62 | + noLog: '无日志', | ||
| 63 | + add: '添加', | ||
| 64 | + modify: '修改', | ||
| 65 | + delete: '删除', | ||
| 66 | + completed: '完成', | ||
| 67 | + failed: '失败', | ||
| 68 | + allApps: '全部应用', | ||
| 69 | + fetchError: '获取订单列表失败', | ||
| 70 | + fetchAppsError: '获取应用列表失败' | ||
| 71 | + }, | ||
| 72 | + viewUnItemLog: { | ||
| 73 | + title: '受理记录', | ||
| 74 | + serviceName: '受理服务', | ||
| 75 | + action: '受理动作', | ||
| 76 | + actionObj: '受理表', | ||
| 77 | + preValue: '受理前', | ||
| 78 | + afterValue: '受理后', | ||
| 79 | + logText: '原始记录', | ||
| 80 | + add: '添加', | ||
| 81 | + modify: '修改', | ||
| 82 | + delete: '删除', | ||
| 83 | + fetchError: '获取日志失败' | ||
| 84 | + } | ||
| 85 | + } | ||
| 86 | +} | ||
| 0 | \ No newline at end of file | 87 | \ No newline at end of file |
src/views/admin/orderManageList.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="order-manage-container animated fadeInRight"> | ||
| 3 | + <el-row :gutter="20"> | ||
| 4 | + <el-col :span="4"> | ||
| 5 | + <el-card class="border-radius"> | ||
| 6 | + <div class="treeview attendance-staff"> | ||
| 7 | + <ul class="list-group text-center border-radius"> | ||
| 8 | + <li v-for="(item, index) in orderManageInfo.apps" :key="index" class="list-group-item node-orgTree" | ||
| 9 | + :class="{ 'vc-node-selected': orderManageInfo.conditions.appId == item.appId }" @click="swatchApp(item)"> | ||
| 10 | + {{ item.name }} | ||
| 11 | + </li> | ||
| 12 | + </ul> | ||
| 13 | + </div> | ||
| 14 | + </el-card> | ||
| 15 | + </el-col> | ||
| 16 | + <el-col :span="20"> | ||
| 17 | + <el-card> | ||
| 18 | + <div slot="header" class="text-left"> | ||
| 19 | + <span>{{ $t('orderManage.queryCondition') }}</span> | ||
| 20 | + </div> | ||
| 21 | + <el-row :gutter="20"> | ||
| 22 | + <el-col :span="4"> | ||
| 23 | + <el-input v-model="orderManageInfo.conditions.oId" :placeholder="$t('orderManage.orderId')" clearable /> | ||
| 24 | + </el-col> | ||
| 25 | + <el-col :span="4"> | ||
| 26 | + <el-input v-model="orderManageInfo.conditions.extTransactionId" :placeholder="$t('orderManage.externalId')" | ||
| 27 | + clearable /> | ||
| 28 | + </el-col> | ||
| 29 | + <el-col :span="4"> | ||
| 30 | + <el-input v-model="orderManageInfo.conditions.bId" :placeholder="$t('orderManage.businessId')" clearable /> | ||
| 31 | + </el-col> | ||
| 32 | + <el-col :span="4"> | ||
| 33 | + <el-date-picker v-model="orderManageInfo.conditions.startTime" type="datetime" | ||
| 34 | + :placeholder="$t('orderManage.startTime')" class="w-100" /> | ||
| 35 | + </el-col> | ||
| 36 | + <el-col :span="4"> | ||
| 37 | + <el-date-picker v-model="orderManageInfo.conditions.endTime" type="datetime" | ||
| 38 | + :placeholder="$t('orderManage.endTime')" class="w-100" /> | ||
| 39 | + </el-col> | ||
| 40 | + <el-col :span="4"> | ||
| 41 | + <el-button type="primary" @click="_queryOrdersMethod"> | ||
| 42 | + <i class="el-icon-search"></i> | ||
| 43 | + {{ $t('common.search') }} | ||
| 44 | + </el-button> | ||
| 45 | + </el-col> | ||
| 46 | + </el-row> | ||
| 47 | + <el-row :gutter="20" class="mt-10"> | ||
| 48 | + <el-col :span="4"> | ||
| 49 | + <el-input v-model="orderManageInfo.conditions.staffNameLike" :placeholder="$t('orderManage.operator')" | ||
| 50 | + clearable /> | ||
| 51 | + </el-col> | ||
| 52 | + <el-col :span="4"> | ||
| 53 | + <el-input v-model="orderManageInfo.conditions.businessTypeNameLike" | ||
| 54 | + :placeholder="$t('orderManage.businessName')" clearable /> | ||
| 55 | + </el-col> | ||
| 56 | + </el-row> | ||
| 57 | + </el-card> | ||
| 58 | + | ||
| 59 | + <el-card class="mt-20"> | ||
| 60 | + <div slot="header" class="text-left"> | ||
| 61 | + <span>{{ $t('orderManage.orderList') }}</span> | ||
| 62 | + </div> | ||
| 63 | + <el-table :data="orderManageInfo.orderDataVos" border style="width: 100%"> | ||
| 64 | + <el-table-column prop="appName" :label="$t('orderManage.appName')" align="center" /> | ||
| 65 | + <el-table-column :label="$t('orderManage.orderId')" align="center"> | ||
| 66 | + <template slot-scope="scope"> | ||
| 67 | + <div>{{ scope.row.oId }}</div> | ||
| 68 | + <div>({{ scope.row.extTransactionId }})</div> | ||
| 69 | + </template> | ||
| 70 | + </el-table-column> | ||
| 71 | + <el-table-column :label="$t('orderManage.businessName')" align="center"> | ||
| 72 | + <template slot-scope="scope"> | ||
| 73 | + <div>{{ scope.row.name }}</div> | ||
| 74 | + <div>({{ scope.row.businessTypeCd }})</div> | ||
| 75 | + </template> | ||
| 76 | + </el-table-column> | ||
| 77 | + <el-table-column prop="bId" :label="$t('orderManage.businessId')" align="center" /> | ||
| 78 | + <el-table-column prop="createTime" :label="$t('orderManage.createTime')" align="center" /> | ||
| 79 | + <el-table-column :label="$t('orderManage.action')" align="center"> | ||
| 80 | + <template slot-scope="scope"> | ||
| 81 | + <span v-if="scope.row.action == 'ADD'">{{ $t('orderManage.add') }}</span> | ||
| 82 | + <span v-else-if="scope.row.action == 'MOD'">{{ $t('orderManage.modify') }}</span> | ||
| 83 | + <span v-else-if="scope.row.action == 'DEL'">{{ $t('orderManage.delete') }}</span> | ||
| 84 | + <span v-else>-</span> | ||
| 85 | + </template> | ||
| 86 | + </el-table-column> | ||
| 87 | + <el-table-column prop="actionObj" :label="$t('orderManage.actionObj')" align="center" /> | ||
| 88 | + <el-table-column prop="userName" :label="$t('orderManage.operator')" align="center" /> | ||
| 89 | + <el-table-column :label="$t('orderManage.status')" align="center"> | ||
| 90 | + <template slot-scope="scope"> | ||
| 91 | + {{ scope.row.statusCd == 'C' ? $t('orderManage.completed') : $t('orderManage.failed') }} | ||
| 92 | + </template> | ||
| 93 | + </el-table-column> | ||
| 94 | + <el-table-column :label="$t('common.operation')" align="center"> | ||
| 95 | + <template slot-scope="scope"> | ||
| 96 | + <el-button v-if="scope.row.bId" size="mini" @click="_showUnitemLog(scope.row)"> | ||
| 97 | + {{ $t('orderManage.log') }} | ||
| 98 | + </el-button> | ||
| 99 | + <span v-else>{{ $t('orderManage.noLog') }}</span> | ||
| 100 | + </template> | ||
| 101 | + </el-table-column> | ||
| 102 | + </el-table> | ||
| 103 | + <el-pagination :current-page="page.current" :page-sizes="[10, 20, 30, 50]" :page-size="page.size" | ||
| 104 | + :total="page.total" layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange" | ||
| 105 | + @current-change="handleCurrentChange" /> | ||
| 106 | + </el-card> | ||
| 107 | + </el-col> | ||
| 108 | + </el-row> | ||
| 109 | + | ||
| 110 | + <view-un-item-log ref="viewUnItemLog" /> | ||
| 111 | + </div> | ||
| 112 | +</template> | ||
| 113 | + | ||
| 114 | +<script> | ||
| 115 | +import { listCorders, listPublicApps } from '@/api/admin/orderManageApi' | ||
| 116 | +import ViewUnItemLog from '@/components/admin/viewUnItemLog' | ||
| 117 | + | ||
| 118 | +export default { | ||
| 119 | + name: 'OrderManageList', | ||
| 120 | + components: { | ||
| 121 | + ViewUnItemLog | ||
| 122 | + }, | ||
| 123 | + data() { | ||
| 124 | + return { | ||
| 125 | + orderManageInfo: { | ||
| 126 | + orderDataVos: [], | ||
| 127 | + apps: [], | ||
| 128 | + total: 0, | ||
| 129 | + records: 1, | ||
| 130 | + conditions: { | ||
| 131 | + oId: '', | ||
| 132 | + extTransactionId: '', | ||
| 133 | + orderTypeCd: '', | ||
| 134 | + appId: '', | ||
| 135 | + startTime: '', | ||
| 136 | + endTime: '', | ||
| 137 | + staffNameLike: '', | ||
| 138 | + bId: '', | ||
| 139 | + businessTypeNameLike: '', | ||
| 140 | + page: 1, | ||
| 141 | + row: 20 | ||
| 142 | + } | ||
| 143 | + }, | ||
| 144 | + page: { | ||
| 145 | + current: 1, | ||
| 146 | + size: 20, | ||
| 147 | + total: 0 | ||
| 148 | + } | ||
| 149 | + } | ||
| 150 | + }, | ||
| 151 | + created() { | ||
| 152 | + this._listOrders(this.page.current, this.page.size) | ||
| 153 | + this._loadApps() | ||
| 154 | + }, | ||
| 155 | + methods: { | ||
| 156 | + async _listOrders(page, rows) { | ||
| 157 | + try { | ||
| 158 | + this.orderManageInfo.conditions.page = page | ||
| 159 | + this.orderManageInfo.conditions.row = rows | ||
| 160 | + const params = { ...this.orderManageInfo.conditions } | ||
| 161 | + | ||
| 162 | + const res = await listCorders(params) | ||
| 163 | + this.orderManageInfo.total = res.total | ||
| 164 | + this.orderManageInfo.records = res.records | ||
| 165 | + this.orderManageInfo.orderDataVos = res.data | ||
| 166 | + this.page.total = res.records | ||
| 167 | + } catch (error) { | ||
| 168 | + this.$message.error(this.$t('orderManage.fetchError')) | ||
| 169 | + } | ||
| 170 | + }, | ||
| 171 | + async _loadApps() { | ||
| 172 | + try { | ||
| 173 | + this.orderManageInfo.apps = [{ | ||
| 174 | + appId: '', | ||
| 175 | + name: this.$t('orderManage.allApps') | ||
| 176 | + }] | ||
| 177 | + | ||
| 178 | + const res = await listPublicApps({ page: 1, row: 50 }) | ||
| 179 | + this.orderManageInfo.apps = [...this.orderManageInfo.apps, ...res.apps] | ||
| 180 | + } catch (error) { | ||
| 181 | + this.$message.error(this.$t('orderManage.fetchAppsError')) | ||
| 182 | + } | ||
| 183 | + }, | ||
| 184 | + _queryOrdersMethod() { | ||
| 185 | + this.page.current = 1 | ||
| 186 | + this._listOrders(this.page.current, this.page.size) | ||
| 187 | + }, | ||
| 188 | + swatchApp(app) { | ||
| 189 | + this.orderManageInfo.conditions.appId = app.appId | ||
| 190 | + this._listOrders(this.page.current, this.page.size) | ||
| 191 | + }, | ||
| 192 | + _showUnitemLog(order) { | ||
| 193 | + this.$refs.viewUnItemLog.open(order) | ||
| 194 | + }, | ||
| 195 | + handleSizeChange(val) { | ||
| 196 | + this.page.size = val | ||
| 197 | + this._listOrders(this.page.current, this.page.size) | ||
| 198 | + }, | ||
| 199 | + handleCurrentChange(val) { | ||
| 200 | + this.page.current = val | ||
| 201 | + this._listOrders(this.page.current, this.page.size) | ||
| 202 | + } | ||
| 203 | + } | ||
| 204 | +} | ||
| 205 | +</script> | ||
| 206 | + | ||
| 207 | +<style scoped> | ||
| 208 | +.order-manage-container { | ||
| 209 | + padding: 20px; | ||
| 210 | +} | ||
| 211 | + | ||
| 212 | +.border-radius { | ||
| 213 | + border-radius: 4px; | ||
| 214 | +} | ||
| 215 | + | ||
| 216 | +.list-group { | ||
| 217 | + list-style: none; | ||
| 218 | + padding: 0; | ||
| 219 | + margin: 0; | ||
| 220 | +} | ||
| 221 | + | ||
| 222 | +.list-group-item { | ||
| 223 | + padding: 10px; | ||
| 224 | + cursor: pointer; | ||
| 225 | +} | ||
| 226 | + | ||
| 227 | +.list-group-item:hover { | ||
| 228 | + background-color: #f5f7fa; | ||
| 229 | +} | ||
| 230 | + | ||
| 231 | +.vc-node-selected { | ||
| 232 | + background-color: #ecf5ff; | ||
| 233 | + color: #409eff; | ||
| 234 | +} | ||
| 235 | + | ||
| 236 | +.mt-10 { | ||
| 237 | + margin-top: 10px; | ||
| 238 | +} | ||
| 239 | + | ||
| 240 | +.mt-20 { | ||
| 241 | + margin-top: 20px; | ||
| 242 | +} | ||
| 243 | + | ||
| 244 | +.w-100 { | ||
| 245 | + width: 100%; | ||
| 246 | +} | ||
| 247 | +</style> | ||
| 0 | \ No newline at end of file | 248 | \ No newline at end of file |
src/views/mall/housekeepingSjServLang.js
0 → 100644
| 1 | +export const messages = { | ||
| 2 | + en: { | ||
| 3 | + housekeepingSjServ: { | ||
| 4 | + search: { | ||
| 5 | + title: 'Search Conditions', | ||
| 6 | + servName: 'Please enter service name', | ||
| 7 | + hktId: 'Please select service type' | ||
| 8 | + }, | ||
| 9 | + list: { | ||
| 10 | + title: 'On Shelf Services', | ||
| 11 | + today: 'Today On Shelf', | ||
| 12 | + all: 'All On Shelf' | ||
| 13 | + }, | ||
| 14 | + table: { | ||
| 15 | + servId: 'Service ID', | ||
| 16 | + servName: 'Service Name', | ||
| 17 | + servDesc: 'Service Description', | ||
| 18 | + hktName: 'Service Type', | ||
| 19 | + repairWay: 'Dispatch Method', | ||
| 20 | + returnVisitFlag: 'Return Visit Method', | ||
| 21 | + sales: 'Sales', | ||
| 22 | + defaultFee: 'Default Fee', | ||
| 23 | + sort: 'Sort', | ||
| 24 | + state: 'Shelf Status' | ||
| 25 | + }, | ||
| 26 | + repairWay: { | ||
| 27 | + grab: 'Grab Order', | ||
| 28 | + assign: 'Assign', | ||
| 29 | + roundRobin: 'Round Robin' | ||
| 30 | + }, | ||
| 31 | + returnVisit: { | ||
| 32 | + none: 'No Return Visit', | ||
| 33 | + ratedNoVisit: 'No Visit After Rated', | ||
| 34 | + allVisit: 'All Return Visit' | ||
| 35 | + }, | ||
| 36 | + state: { | ||
| 37 | + notOnShelf: 'Not On Shelf', | ||
| 38 | + onShelf: 'On Shelf' | ||
| 39 | + }, | ||
| 40 | + fetchError: 'Failed to fetch service list', | ||
| 41 | + fetchTypeError: 'Failed to fetch service types' | ||
| 42 | + } | ||
| 43 | + }, | ||
| 44 | + zh: { | ||
| 45 | + housekeepingSjServ: { | ||
| 46 | + search: { | ||
| 47 | + title: '查询条件', | ||
| 48 | + servName: '请输入服务名称', | ||
| 49 | + hktId: '请选择服务类型' | ||
| 50 | + }, | ||
| 51 | + list: { | ||
| 52 | + title: '上架服务', | ||
| 53 | + today: '今日上架', | ||
| 54 | + all: '所有上架' | ||
| 55 | + }, | ||
| 56 | + table: { | ||
| 57 | + servId: '服务编号', | ||
| 58 | + servName: '服务名称', | ||
| 59 | + servDesc: '服务描述', | ||
| 60 | + hktName: '服务类型', | ||
| 61 | + repairWay: '派单方式', | ||
| 62 | + returnVisitFlag: '回访方式', | ||
| 63 | + sales: '销量', | ||
| 64 | + defaultFee: '默认费用', | ||
| 65 | + sort: '排序', | ||
| 66 | + state: '上架状态' | ||
| 67 | + }, | ||
| 68 | + repairWay: { | ||
| 69 | + grab: '抢单', | ||
| 70 | + assign: '指派', | ||
| 71 | + roundRobin: '轮训' | ||
| 72 | + }, | ||
| 73 | + returnVisit: { | ||
| 74 | + none: '都不回访', | ||
| 75 | + ratedNoVisit: '已评价不回访', | ||
| 76 | + allVisit: '都回访' | ||
| 77 | + }, | ||
| 78 | + state: { | ||
| 79 | + notOnShelf: '未上架', | ||
| 80 | + onShelf: '上架' | ||
| 81 | + }, | ||
| 82 | + fetchError: '获取服务列表失败', | ||
| 83 | + fetchTypeError: '获取服务类型失败' | ||
| 84 | + } | ||
| 85 | + } | ||
| 86 | +} | ||
| 0 | \ No newline at end of file | 87 | \ No newline at end of file |
src/views/mall/housekeepingSjServList.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="housekeeping-sj-serv-container"> | ||
| 3 | + <!-- 查询条件 --> | ||
| 4 | + <el-card class="search-wrapper"> | ||
| 5 | + <div slot="header" class="clearfix text-left"> | ||
| 6 | + <span>{{ $t('housekeepingSjServ.search.title') }}</span> | ||
| 7 | + </div> | ||
| 8 | + <el-row :gutter="20"> | ||
| 9 | + <el-col :span="6"> | ||
| 10 | + <el-input v-model="searchForm.servName" :placeholder="$t('housekeepingSjServ.search.servName')" clearable | ||
| 11 | + @keyup.enter.native="handleSearch" /> | ||
| 12 | + </el-col> | ||
| 13 | + <el-col :span="6"> | ||
| 14 | + <el-select v-model="searchForm.hktId" :placeholder="$t('housekeepingSjServ.search.hktId')" clearable> | ||
| 15 | + <el-option v-for="item in housekeepingTypes" :key="item.hktId" :label="item.hktName" :value="item.hktId" /> | ||
| 16 | + </el-select> | ||
| 17 | + </el-col> | ||
| 18 | + <el-col :span="4"> | ||
| 19 | + <el-button type="primary" @click="handleSearch"> | ||
| 20 | + <i class="el-icon-search"></i> | ||
| 21 | + {{ $t('common.search') }} | ||
| 22 | + </el-button> | ||
| 23 | + </el-col> | ||
| 24 | + </el-row> | ||
| 25 | + </el-card> | ||
| 26 | + | ||
| 27 | + <!-- 上架服务列表 --> | ||
| 28 | + <el-card class="list-wrapper"> | ||
| 29 | + <div slot="header" class="clearfix text-left"> | ||
| 30 | + <span>{{ $t('housekeepingSjServ.list.title') }}</span> | ||
| 31 | + <div style="float: right;"> | ||
| 32 | + <el-button type="primary" size="small" @click="listHousekeepingServsToDay"> | ||
| 33 | + <i class="el-icon-plus"></i> | ||
| 34 | + {{ $t('housekeepingSjServ.list.today') }} | ||
| 35 | + </el-button> | ||
| 36 | + <el-button type="primary" size="small" style="margin-left: 10px" @click="listHousekeepingServsAll"> | ||
| 37 | + {{ $t('housekeepingSjServ.list.all') }} | ||
| 38 | + </el-button> | ||
| 39 | + </div> | ||
| 40 | + </div> | ||
| 41 | + | ||
| 42 | + <el-table v-loading="loading" :data="tableData" border style="width: 100%"> | ||
| 43 | + <el-table-column prop="servId" :label="$t('housekeepingSjServ.table.servId')" align="center" /> | ||
| 44 | + <el-table-column prop="servName" :label="$t('housekeepingSjServ.table.servName')" align="center" /> | ||
| 45 | + <el-table-column prop="servDesc" :label="$t('housekeepingSjServ.table.servDesc')" align="center" /> | ||
| 46 | + <el-table-column prop="hktName" :label="$t('housekeepingSjServ.table.hktName')" align="center" /> | ||
| 47 | + <el-table-column :label="$t('housekeepingSjServ.table.repairWay')" align="center"> | ||
| 48 | + <template slot-scope="scope"> | ||
| 49 | + <span v-if="scope.row.repairWay === '100'">{{ $t('housekeepingSjServ.repairWay.grab') }}</span> | ||
| 50 | + <span v-else-if="scope.row.repairWay === '200'">{{ $t('housekeepingSjServ.repairWay.assign') }}</span> | ||
| 51 | + <span v-else-if="scope.row.repairWay === '300'">{{ $t('housekeepingSjServ.repairWay.roundRobin') }}</span> | ||
| 52 | + </template> | ||
| 53 | + </el-table-column> | ||
| 54 | + <el-table-column :label="$t('housekeepingSjServ.table.returnVisitFlag')" align="center"> | ||
| 55 | + <template slot-scope="scope"> | ||
| 56 | + <span v-if="scope.row.returnVisitFlag === '001'">{{ $t('housekeepingSjServ.returnVisit.none') }}</span> | ||
| 57 | + <span v-else-if="scope.row.returnVisitFlag === '002'">{{ $t('housekeepingSjServ.returnVisit.ratedNoVisit') | ||
| 58 | + }}</span> | ||
| 59 | + <span v-else-if="scope.row.returnVisitFlag === '003'">{{ $t('housekeepingSjServ.returnVisit.allVisit') | ||
| 60 | + }}</span> | ||
| 61 | + </template> | ||
| 62 | + </el-table-column> | ||
| 63 | + <el-table-column prop="sales" :label="$t('housekeepingSjServ.table.sales')" align="center" /> | ||
| 64 | + <el-table-column prop="defaultFee" :label="$t('housekeepingSjServ.table.defaultFee')" align="center" /> | ||
| 65 | + <el-table-column prop="sort" :label="$t('housekeepingSjServ.table.sort')" align="center" /> | ||
| 66 | + <el-table-column :label="$t('housekeepingSjServ.table.state')" align="center"> | ||
| 67 | + <template slot-scope="scope"> | ||
| 68 | + {{ scope.row.state === '1001' ? $t('housekeepingSjServ.state.notOnShelf') : | ||
| 69 | + $t('housekeepingSjServ.state.onShelf') }} | ||
| 70 | + </template> | ||
| 71 | + </el-table-column> | ||
| 72 | + </el-table> | ||
| 73 | + | ||
| 74 | + <el-pagination :current-page.sync="page.current" :page-sizes="[10, 20, 30, 50]" :page-size="page.size" | ||
| 75 | + :total="page.total" layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange" | ||
| 76 | + @current-change="handleCurrentChange" /> | ||
| 77 | + </el-card> | ||
| 78 | + </div> | ||
| 79 | +</template> | ||
| 80 | + | ||
| 81 | +<script> | ||
| 82 | +import { queryHousekeepingServ, queryHousekeepingType } from '@/api/mall/housekeepingSjServApi' | ||
| 83 | + | ||
| 84 | +export default { | ||
| 85 | + name: 'HousekeepingSjServList', | ||
| 86 | + data() { | ||
| 87 | + return { | ||
| 88 | + loading: false, | ||
| 89 | + searchForm: { | ||
| 90 | + servName: '', | ||
| 91 | + hktId: '', | ||
| 92 | + state: '2002', | ||
| 93 | + createTime: '', | ||
| 94 | + mallApiCode: 'queryHousekeepingServBmoImpl' | ||
| 95 | + }, | ||
| 96 | + tableData: [], | ||
| 97 | + housekeepingTypes: [], | ||
| 98 | + page: { | ||
| 99 | + current: 1, | ||
| 100 | + size: 10, | ||
| 101 | + total: 0 | ||
| 102 | + } | ||
| 103 | + } | ||
| 104 | + }, | ||
| 105 | + created() { | ||
| 106 | + this.getList() | ||
| 107 | + this.getHousekeepingTypes() | ||
| 108 | + }, | ||
| 109 | + methods: { | ||
| 110 | + async getList() { | ||
| 111 | + try { | ||
| 112 | + this.loading = true | ||
| 113 | + const params = { | ||
| 114 | + page: this.page.current, | ||
| 115 | + row: this.page.size, | ||
| 116 | + ...this.searchForm | ||
| 117 | + } | ||
| 118 | + const { data, total } = await queryHousekeepingServ(params) | ||
| 119 | + this.tableData = data | ||
| 120 | + this.page.total = total | ||
| 121 | + } catch (error) { | ||
| 122 | + this.$message.error(this.$t('housekeepingSjServ.fetchError')) | ||
| 123 | + } finally { | ||
| 124 | + this.loading = false | ||
| 125 | + } | ||
| 126 | + }, | ||
| 127 | + async getHousekeepingTypes() { | ||
| 128 | + try { | ||
| 129 | + const params = { | ||
| 130 | + page: 1, | ||
| 131 | + row: 50, | ||
| 132 | + typeCd: 1001, | ||
| 133 | + shopId: '' | ||
| 134 | + } | ||
| 135 | + const { data } = await queryHousekeepingType(params) | ||
| 136 | + this.housekeepingTypes = data | ||
| 137 | + } catch (error) { | ||
| 138 | + this.$message.error(this.$t('housekeepingSjServ.fetchTypeError')) | ||
| 139 | + } | ||
| 140 | + }, | ||
| 141 | + handleSearch() { | ||
| 142 | + this.page.current = 1 | ||
| 143 | + this.getList() | ||
| 144 | + }, | ||
| 145 | + listHousekeepingServsToDay() { | ||
| 146 | + this.searchForm.createTime = this.$dayjs().format('YYYY-MM-DD HH:mm:ss') | ||
| 147 | + this.handleSearch() | ||
| 148 | + }, | ||
| 149 | + listHousekeepingServsAll() { | ||
| 150 | + this.searchForm.createTime = '' | ||
| 151 | + this.handleSearch() | ||
| 152 | + }, | ||
| 153 | + handleSizeChange(val) { | ||
| 154 | + this.page.size = val | ||
| 155 | + this.getList() | ||
| 156 | + }, | ||
| 157 | + handleCurrentChange(val) { | ||
| 158 | + this.page.current = val | ||
| 159 | + this.getList() | ||
| 160 | + } | ||
| 161 | + } | ||
| 162 | +} | ||
| 163 | +</script> | ||
| 164 | + | ||
| 165 | +<style lang="scss" scoped> | ||
| 166 | +.housekeeping-sj-serv-container { | ||
| 167 | + padding: 20px; | ||
| 168 | + | ||
| 169 | + .search-wrapper { | ||
| 170 | + margin-bottom: 20px; | ||
| 171 | + | ||
| 172 | + .el-select { | ||
| 173 | + width: 100%; | ||
| 174 | + } | ||
| 175 | + } | ||
| 176 | + | ||
| 177 | + .list-wrapper { | ||
| 178 | + .el-pagination { | ||
| 179 | + margin-top: 20px; | ||
| 180 | + text-align: right; | ||
| 181 | + } | ||
| 182 | + } | ||
| 183 | +} | ||
| 184 | +</style> | ||
| 0 | \ No newline at end of file | 185 | \ No newline at end of file |
src/views/mall/integralDetailLang.js
0 → 100644
| 1 | +export const messages = { | ||
| 2 | + en: { | ||
| 3 | + integralDetail: { | ||
| 4 | + all: 'All', | ||
| 5 | + personal: 'Personal', | ||
| 6 | + merchant: 'Merchant', | ||
| 7 | + searchTitle: 'Search Conditions', | ||
| 8 | + accountPlaceholder: 'Please enter account', | ||
| 9 | + typePlaceholder: 'Please select type', | ||
| 10 | + objectTypePlaceholder: 'Please select object type', | ||
| 11 | + orderIdPlaceholder: 'Please enter order ID', | ||
| 12 | + transferIn: 'Transfer In', | ||
| 13 | + transferOut: 'Transfer Out', | ||
| 14 | + user: 'User', | ||
| 15 | + tableTitle: 'Points Transaction', | ||
| 16 | + id: 'ID', | ||
| 17 | + accountName: 'Account Name', | ||
| 18 | + accountId: 'Account ID', | ||
| 19 | + type: 'Type', | ||
| 20 | + relatedAccount: 'Related Account', | ||
| 21 | + points: 'Points', | ||
| 22 | + objectType: 'Object Type', | ||
| 23 | + objectId: 'Object ID', | ||
| 24 | + phone: 'Phone', | ||
| 25 | + orderId: 'Order ID', | ||
| 26 | + transactionTime: 'Transaction Time', | ||
| 27 | + remark: 'Remark', | ||
| 28 | + fetchError: 'Failed to fetch points transaction data' | ||
| 29 | + } | ||
| 30 | + }, | ||
| 31 | + zh: { | ||
| 32 | + integralDetail: { | ||
| 33 | + all: '全部', | ||
| 34 | + personal: '个人', | ||
| 35 | + merchant: '商户', | ||
| 36 | + searchTitle: '查询条件', | ||
| 37 | + accountPlaceholder: '请填写账户', | ||
| 38 | + typePlaceholder: '请选择类型', | ||
| 39 | + objectTypePlaceholder: '请选择对象类型', | ||
| 40 | + orderIdPlaceholder: '请选择交易单号', | ||
| 41 | + transferIn: '转入', | ||
| 42 | + transferOut: '转出', | ||
| 43 | + user: '用户', | ||
| 44 | + tableTitle: '积分交易', | ||
| 45 | + id: '编号', | ||
| 46 | + accountName: '账户名称', | ||
| 47 | + accountId: '账户编号', | ||
| 48 | + type: '类型', | ||
| 49 | + relatedAccount: '关联账户', | ||
| 50 | + points: '积分数', | ||
| 51 | + objectType: '对象类型', | ||
| 52 | + objectId: '对象ID', | ||
| 53 | + phone: '手机号', | ||
| 54 | + orderId: '交易单号', | ||
| 55 | + transactionTime: '交易时间', | ||
| 56 | + remark: '备注', | ||
| 57 | + fetchError: '获取积分交易数据失败' | ||
| 58 | + } | ||
| 59 | + } | ||
| 60 | +} | ||
| 0 | \ No newline at end of file | 61 | \ No newline at end of file |
src/views/mall/integralDetailList.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="integral-detail-container"> | ||
| 3 | + <el-row :gutter="20"> | ||
| 4 | + <el-col :span="3"> | ||
| 5 | + <el-card class="tree-card"> | ||
| 6 | + <ul class="tree-list"> | ||
| 7 | + <li class="tree-item" @click="_switchIntegralObjType('')" | ||
| 8 | + :class="{ 'active': integralDetailInfo.conditions.objType === '' }"> | ||
| 9 | + {{ $t('integralDetail.all') }} | ||
| 10 | + </li> | ||
| 11 | + <li class="tree-item" @click="_switchIntegralObjType('6006')" | ||
| 12 | + :class="{ 'active': integralDetailInfo.conditions.objType === '6006' }"> | ||
| 13 | + {{ $t('integralDetail.personal') }} | ||
| 14 | + </li> | ||
| 15 | + <li class="tree-item" @click="_switchIntegralObjType('7007')" | ||
| 16 | + :class="{ 'active': integralDetailInfo.conditions.objType === '7007' }"> | ||
| 17 | + {{ $t('integralDetail.merchant') }} | ||
| 18 | + </li> | ||
| 19 | + </ul> | ||
| 20 | + </el-card> | ||
| 21 | + </el-col> | ||
| 22 | + <el-col :span="21"> | ||
| 23 | + <el-card class="search-card"> | ||
| 24 | + <div slot="header" class="clearfix text-left"> | ||
| 25 | + <span>{{ $t('integralDetail.searchTitle') }}</span> | ||
| 26 | + </div> | ||
| 27 | + <el-form :inline="true" :model="integralDetailInfo.conditions" class="search-form text-left"> | ||
| 28 | + <el-form-item> | ||
| 29 | + <el-input v-model="integralDetailInfo.conditions.integralNameLike" | ||
| 30 | + :placeholder="$t('integralDetail.accountPlaceholder')" clearable /> | ||
| 31 | + </el-form-item> | ||
| 32 | + <el-form-item> | ||
| 33 | + <el-select v-model="integralDetailInfo.conditions.detailType" | ||
| 34 | + :placeholder="$t('integralDetail.typePlaceholder')"> | ||
| 35 | + <el-option :label="$t('integralDetail.all')" value="" /> | ||
| 36 | + <el-option :label="$t('integralDetail.transferIn')" value="1001" /> | ||
| 37 | + <el-option :label="$t('integralDetail.transferOut')" value="2002" /> | ||
| 38 | + </el-select> | ||
| 39 | + </el-form-item> | ||
| 40 | + <el-form-item> | ||
| 41 | + <el-select v-model="integralDetailInfo.conditions.objType" | ||
| 42 | + :placeholder="$t('integralDetail.objectTypePlaceholder')"> | ||
| 43 | + <el-option :label="$t('integralDetail.all')" value="" /> | ||
| 44 | + <el-option :label="$t('integralDetail.user')" value="6006" /> | ||
| 45 | + <el-option :label="$t('integralDetail.merchant')" value="7007" /> | ||
| 46 | + </el-select> | ||
| 47 | + </el-form-item> | ||
| 48 | + <el-form-item> | ||
| 49 | + <el-input v-model="integralDetailInfo.conditions.orderId" | ||
| 50 | + :placeholder="$t('integralDetail.orderIdPlaceholder')" clearable /> | ||
| 51 | + </el-form-item> | ||
| 52 | + <el-form-item> | ||
| 53 | + <el-button type="primary" @click="_queryIntegralDetailMethod"> | ||
| 54 | + <i class="el-icon-search"></i> | ||
| 55 | + {{ $t('common.search') }} | ||
| 56 | + </el-button> | ||
| 57 | + </el-form-item> | ||
| 58 | + </el-form> | ||
| 59 | + </el-card> | ||
| 60 | + | ||
| 61 | + <el-card class="table-card"> | ||
| 62 | + <div slot="header" class="clearfix text-left"> | ||
| 63 | + <span>{{ $t('integralDetail.tableTitle') }}</span> | ||
| 64 | + </div> | ||
| 65 | + <el-table :data="integralDetailInfo.integralDetails" border style="width: 100%" v-loading="loading"> | ||
| 66 | + <el-table-column prop="detailId" :label="$t('integralDetail.id')" align="center" width="80" /> | ||
| 67 | + <el-table-column prop="integralName" :label="$t('integralDetail.accountName')" align="center" /> | ||
| 68 | + <el-table-column prop="integralId" :label="$t('integralDetail.accountId')" align="center" /> | ||
| 69 | + <el-table-column :label="$t('integralDetail.type')" align="center"> | ||
| 70 | + <template slot-scope="scope"> | ||
| 71 | + {{ scope.row.detailType === '2002' ? $t('integralDetail.transferOut') : $t('integralDetail.transferIn') }} | ||
| 72 | + </template> | ||
| 73 | + </el-table-column> | ||
| 74 | + <el-table-column prop="relIntegralId" :label="$t('integralDetail.relatedAccount')" align="center" /> | ||
| 75 | + <el-table-column prop="amount" :label="$t('integralDetail.points')" align="center" /> | ||
| 76 | + <el-table-column :label="$t('integralDetail.objectType')" align="center"> | ||
| 77 | + <template slot-scope="scope"> | ||
| 78 | + {{ scope.row.objType === '7007' ? $t('integralDetail.merchant') : $t('integralDetail.user') }} | ||
| 79 | + </template> | ||
| 80 | + </el-table-column> | ||
| 81 | + <el-table-column prop="objId" :label="$t('integralDetail.objectId')" align="center" /> | ||
| 82 | + <el-table-column prop="link" :label="$t('integralDetail.phone')" align="center" /> | ||
| 83 | + <el-table-column prop="orderId" :label="$t('integralDetail.orderId')" align="center" /> | ||
| 84 | + <el-table-column prop="createTime" :label="$t('integralDetail.transactionTime')" align="center" /> | ||
| 85 | + <el-table-column prop="remark" :label="$t('integralDetail.remark')" align="center" /> | ||
| 86 | + </el-table> | ||
| 87 | + <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" | ||
| 88 | + :current-page="page.current" :page-sizes="[10, 20, 30, 50]" :page-size="page.size" | ||
| 89 | + layout="total, sizes, prev, pager, next, jumper" :total="page.total" class="pagination"> | ||
| 90 | + </el-pagination> | ||
| 91 | + </el-card> | ||
| 92 | + </el-col> | ||
| 93 | + </el-row> | ||
| 94 | + </div> | ||
| 95 | +</template> | ||
| 96 | + | ||
| 97 | +<script> | ||
| 98 | +import { getIntegralDetailList } from '@/api/mall/integralDetailApi' | ||
| 99 | + | ||
| 100 | +export default { | ||
| 101 | + name: 'IntegralDetailList', | ||
| 102 | + data() { | ||
| 103 | + return { | ||
| 104 | + loading: false, | ||
| 105 | + integralDetailInfo: { | ||
| 106 | + integralDetails: [], | ||
| 107 | + conditions: { | ||
| 108 | + integralId: '', | ||
| 109 | + detailType: '', | ||
| 110 | + integralNameLike: '', | ||
| 111 | + amount: '', | ||
| 112 | + objType: '', | ||
| 113 | + orderId: '', | ||
| 114 | + mallApiCode: 'queryIntegralDetailBmoImpl' | ||
| 115 | + } | ||
| 116 | + }, | ||
| 117 | + page: { | ||
| 118 | + current: 1, | ||
| 119 | + size: 10, | ||
| 120 | + total: 0 | ||
| 121 | + } | ||
| 122 | + } | ||
| 123 | + }, | ||
| 124 | + created() { | ||
| 125 | + this._listIntegralDetails(this.page.current, this.page.size) | ||
| 126 | + }, | ||
| 127 | + methods: { | ||
| 128 | + async _listIntegralDetails(page, size) { | ||
| 129 | + try { | ||
| 130 | + this.loading = true | ||
| 131 | + this.integralDetailInfo.conditions.page = page | ||
| 132 | + this.integralDetailInfo.conditions.row = size | ||
| 133 | + | ||
| 134 | + const { data, total } = await getIntegralDetailList(this.integralDetailInfo.conditions) | ||
| 135 | + this.integralDetailInfo.integralDetails = data | ||
| 136 | + this.page.total = total | ||
| 137 | + } catch (error) { | ||
| 138 | + this.$message.error(this.$t('integralDetail.fetchError')) | ||
| 139 | + } finally { | ||
| 140 | + this.loading = false | ||
| 141 | + } | ||
| 142 | + }, | ||
| 143 | + _queryIntegralDetailMethod() { | ||
| 144 | + this.page.current = 1 | ||
| 145 | + this._listIntegralDetails(this.page.current, this.page.size) | ||
| 146 | + }, | ||
| 147 | + _switchIntegralObjType(objType) { | ||
| 148 | + this.integralDetailInfo.conditions.objType = objType | ||
| 149 | + this._listIntegralDetails(this.page.current, this.page.size) | ||
| 150 | + }, | ||
| 151 | + handleSizeChange(val) { | ||
| 152 | + this.page.size = val | ||
| 153 | + this._listIntegralDetails(this.page.current, this.page.size) | ||
| 154 | + }, | ||
| 155 | + handleCurrentChange(val) { | ||
| 156 | + this.page.current = val | ||
| 157 | + this._listIntegralDetails(this.page.current, this.page.size) | ||
| 158 | + } | ||
| 159 | + } | ||
| 160 | +} | ||
| 161 | +</script> | ||
| 162 | + | ||
| 163 | +<style lang="scss" scoped> | ||
| 164 | +.integral-detail-container { | ||
| 165 | + padding: 20px; | ||
| 166 | + | ||
| 167 | + .tree-card { | ||
| 168 | + height: 100%; | ||
| 169 | + | ||
| 170 | + .tree-list { | ||
| 171 | + list-style: none; | ||
| 172 | + padding: 0; | ||
| 173 | + margin: 0; | ||
| 174 | + | ||
| 175 | + .tree-item { | ||
| 176 | + padding: 10px; | ||
| 177 | + margin-bottom: 5px; | ||
| 178 | + text-align: center; | ||
| 179 | + cursor: pointer; | ||
| 180 | + border-radius: 4px; | ||
| 181 | + | ||
| 182 | + &:hover { | ||
| 183 | + background-color: #f5f7fa; | ||
| 184 | + } | ||
| 185 | + | ||
| 186 | + &.active { | ||
| 187 | + background-color: #409eff; | ||
| 188 | + color: white; | ||
| 189 | + } | ||
| 190 | + } | ||
| 191 | + } | ||
| 192 | + } | ||
| 193 | + | ||
| 194 | + .search-card { | ||
| 195 | + margin-bottom: 20px; | ||
| 196 | + | ||
| 197 | + .search-form { | ||
| 198 | + .el-form-item { | ||
| 199 | + margin-bottom: 0; | ||
| 200 | + } | ||
| 201 | + } | ||
| 202 | + } | ||
| 203 | + | ||
| 204 | + .pagination { | ||
| 205 | + margin-top: 20px; | ||
| 206 | + text-align: right; | ||
| 207 | + } | ||
| 208 | +} | ||
| 209 | +</style> | ||
| 0 | \ No newline at end of file | 210 | \ No newline at end of file |
src/views/mall/productSjLang.js
0 → 100644
| 1 | +export const messages = { | ||
| 2 | + en: { | ||
| 3 | + productSj: { | ||
| 4 | + search: { | ||
| 5 | + title: 'Search Conditions', | ||
| 6 | + prodName: 'Please enter product name' | ||
| 7 | + }, | ||
| 8 | + list: { | ||
| 9 | + title: 'Shelved Products', | ||
| 10 | + today: 'Today', | ||
| 11 | + all: 'All Shelved' | ||
| 12 | + }, | ||
| 13 | + table: { | ||
| 14 | + productId: 'Product ID', | ||
| 15 | + coverPhoto: 'Product Image', | ||
| 16 | + categoryName: 'Product Category', | ||
| 17 | + prodName: 'Product Name', | ||
| 18 | + sales: 'Sales', | ||
| 19 | + stock: 'Stock', | ||
| 20 | + price: 'Price', | ||
| 21 | + sort: 'Sort', | ||
| 22 | + state: 'Status' | ||
| 23 | + }, | ||
| 24 | + fetchError: 'Failed to fetch product list' | ||
| 25 | + } | ||
| 26 | + }, | ||
| 27 | + zh: { | ||
| 28 | + productSj: { | ||
| 29 | + search: { | ||
| 30 | + title: '查询条件', | ||
| 31 | + prodName: '请输入商品名称' | ||
| 32 | + }, | ||
| 33 | + list: { | ||
| 34 | + title: '上架商品', | ||
| 35 | + today: '今日上架', | ||
| 36 | + all: '所有上架' | ||
| 37 | + }, | ||
| 38 | + table: { | ||
| 39 | + productId: '商品ID', | ||
| 40 | + coverPhoto: '商品图片', | ||
| 41 | + categoryName: '商品分组', | ||
| 42 | + prodName: '商品名称', | ||
| 43 | + sales: '销量', | ||
| 44 | + stock: '库存', | ||
| 45 | + price: '价格', | ||
| 46 | + sort: '排序', | ||
| 47 | + state: '状态' | ||
| 48 | + }, | ||
| 49 | + fetchError: '获取商品列表失败' | ||
| 50 | + } | ||
| 51 | + } | ||
| 52 | +} | ||
| 0 | \ No newline at end of file | 53 | \ No newline at end of file |
src/views/mall/productSjList.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="product-sj-container"> | ||
| 3 | + <!-- 查询条件 --> | ||
| 4 | + <el-card class="search-wrapper"> | ||
| 5 | + <div slot="header" class="clearfix text-left"> | ||
| 6 | + <span>{{ $t('productSj.search.title') }}</span> | ||
| 7 | + </div> | ||
| 8 | + <el-row :gutter="20"> | ||
| 9 | + <el-col :span="6"> | ||
| 10 | + <el-input | ||
| 11 | + v-model="searchForm.prodName" | ||
| 12 | + :placeholder="$t('productSj.search.prodName')" | ||
| 13 | + clearable | ||
| 14 | + @keyup.enter.native="handleSearch" | ||
| 15 | + /> | ||
| 16 | + </el-col> | ||
| 17 | + <el-col :span="2"> | ||
| 18 | + <el-button type="primary" @click="handleSearch"> | ||
| 19 | + {{ $t('common.search') }} | ||
| 20 | + </el-button> | ||
| 21 | + </el-col> | ||
| 22 | + </el-row> | ||
| 23 | + </el-card> | ||
| 24 | + | ||
| 25 | + <!-- 商品列表 --> | ||
| 26 | + <el-card class="list-wrapper"> | ||
| 27 | + <div slot="header" class="clearfix text-left"> | ||
| 28 | + <span>{{ $t('productSj.list.title') }}</span> | ||
| 29 | + <div style="float: right;"> | ||
| 30 | + <el-button type="primary" size="small" @click="listProductsToDay"> | ||
| 31 | + <i class="el-icon-plus"></i> | ||
| 32 | + {{ $t('productSj.list.today') }} | ||
| 33 | + </el-button> | ||
| 34 | + <el-button type="primary" size="small" style="margin-left: 10px" @click="listProductsAll"> | ||
| 35 | + {{ $t('productSj.list.all') }} | ||
| 36 | + </el-button> | ||
| 37 | + </div> | ||
| 38 | + </div> | ||
| 39 | + | ||
| 40 | + <el-table v-loading="loading" :data="tableData" border style="width: 100%"> | ||
| 41 | + <el-table-column prop="productId" :label="$t('productSj.table.productId')" align="center" /> | ||
| 42 | + <el-table-column :label="$t('productSj.table.coverPhoto')" align="center"> | ||
| 43 | + <template slot-scope="scope"> | ||
| 44 | + <el-image | ||
| 45 | + style="width: 60px; height: 60px; border-radius: 5px;" | ||
| 46 | + :src="scope.row.coverPhoto" | ||
| 47 | + fit="cover" | ||
| 48 | + /> | ||
| 49 | + </template> | ||
| 50 | + </el-table-column> | ||
| 51 | + <el-table-column prop="categoryName" :label="$t('productSj.table.categoryName')" align="center" /> | ||
| 52 | + <el-table-column prop="prodName" :label="$t('productSj.table.prodName')" align="center" /> | ||
| 53 | + <el-table-column prop="sales" :label="$t('productSj.table.sales')" align="center" /> | ||
| 54 | + <el-table-column prop="stock" :label="$t('productSj.table.stock')" align="center" /> | ||
| 55 | + <el-table-column :label="$t('productSj.table.price')" align="center"> | ||
| 56 | + <template slot-scope="scope"> | ||
| 57 | + {{ scope.row.defaultSpecValue.price }} | ||
| 58 | + </template> | ||
| 59 | + </el-table-column> | ||
| 60 | + <el-table-column prop="sort" :label="$t('productSj.table.sort')" align="center" /> | ||
| 61 | + <el-table-column prop="stateName" :label="$t('productSj.table.state')" align="center" /> | ||
| 62 | + </el-table> | ||
| 63 | + | ||
| 64 | + <el-pagination | ||
| 65 | + :current-page.sync="page.current" | ||
| 66 | + :page-sizes="[10, 20, 30, 50]" | ||
| 67 | + :page-size="page.size" | ||
| 68 | + :total="page.total" | ||
| 69 | + layout="total, sizes, prev, pager, next, jumper" | ||
| 70 | + @size-change="handleSizeChange" | ||
| 71 | + @current-change="handleCurrentChange" | ||
| 72 | + /> | ||
| 73 | + </el-card> | ||
| 74 | + | ||
| 75 | + <delete-product ref="deleteProduct" @success="handleSuccess" /> | ||
| 76 | + </div> | ||
| 77 | +</template> | ||
| 78 | + | ||
| 79 | +<script> | ||
| 80 | +import { getAdminProductList } from '@/api/mall/productSjApi' | ||
| 81 | +import DeleteProduct from '@/components/mall/DeleteProduct' | ||
| 82 | + | ||
| 83 | +export default { | ||
| 84 | + name: 'ProductSjList', | ||
| 85 | + components: { | ||
| 86 | + DeleteProduct | ||
| 87 | + }, | ||
| 88 | + data() { | ||
| 89 | + return { | ||
| 90 | + loading: false, | ||
| 91 | + searchForm: { | ||
| 92 | + prodName: '', | ||
| 93 | + state: '2002', | ||
| 94 | + keyword: '', | ||
| 95 | + barCode: '', | ||
| 96 | + createTime: '', | ||
| 97 | + mallApiCode: 'queryAdminProductBmoImpl' | ||
| 98 | + }, | ||
| 99 | + tableData: [], | ||
| 100 | + page: { | ||
| 101 | + current: 1, | ||
| 102 | + size: 10, | ||
| 103 | + total: 0 | ||
| 104 | + } | ||
| 105 | + } | ||
| 106 | + }, | ||
| 107 | + created() { | ||
| 108 | + this.getList() | ||
| 109 | + }, | ||
| 110 | + methods: { | ||
| 111 | + async getList() { | ||
| 112 | + try { | ||
| 113 | + this.loading = true | ||
| 114 | + const params = { | ||
| 115 | + page: this.page.current, | ||
| 116 | + row: this.page.size, | ||
| 117 | + ...this.searchForm | ||
| 118 | + } | ||
| 119 | + const { data, total } = await getAdminProductList(params) | ||
| 120 | + this.tableData = data | ||
| 121 | + this.page.total = total | ||
| 122 | + } catch (error) { | ||
| 123 | + this.$message.error(this.$t('productSj.fetchError')) | ||
| 124 | + } finally { | ||
| 125 | + this.loading = false | ||
| 126 | + } | ||
| 127 | + }, | ||
| 128 | + handleSearch() { | ||
| 129 | + this.page.current = 1 | ||
| 130 | + this.getList() | ||
| 131 | + }, | ||
| 132 | + listProductsToDay() { | ||
| 133 | + this.searchForm.createTime = this.$dayjs().format('YYYY-MM-DD HH:mm:ss') | ||
| 134 | + this.handleSearch() | ||
| 135 | + }, | ||
| 136 | + listProductsAll() { | ||
| 137 | + this.searchForm.createTime = '' | ||
| 138 | + this.handleSearch() | ||
| 139 | + }, | ||
| 140 | + handleSizeChange(val) { | ||
| 141 | + this.page.size = val | ||
| 142 | + this.getList() | ||
| 143 | + }, | ||
| 144 | + handleCurrentChange(val) { | ||
| 145 | + this.page.current = val | ||
| 146 | + this.getList() | ||
| 147 | + }, | ||
| 148 | + handleSuccess() { | ||
| 149 | + this.getList() | ||
| 150 | + } | ||
| 151 | + } | ||
| 152 | +} | ||
| 153 | +</script> | ||
| 154 | + | ||
| 155 | +<style lang="scss" scoped> | ||
| 156 | +.product-sj-container { | ||
| 157 | + padding: 0; | ||
| 158 | + margin: 0; | ||
| 159 | + | ||
| 160 | + .search-wrapper { | ||
| 161 | + margin-bottom: 20px; | ||
| 162 | + } | ||
| 163 | + | ||
| 164 | + .list-wrapper { | ||
| 165 | + .el-pagination { | ||
| 166 | + margin-top: 20px; | ||
| 167 | + text-align: right; | ||
| 168 | + } | ||
| 169 | + } | ||
| 170 | +} | ||
| 171 | +</style> | ||
| 0 | \ No newline at end of file | 172 | \ No newline at end of file |
src/views/mall/storeOrderCartManageLang.js
0 → 100644
| 1 | +export const messages = { | ||
| 2 | + en: { | ||
| 3 | + storeOrderCartManage: { | ||
| 4 | + search: { | ||
| 5 | + title: 'Search Conditions', | ||
| 6 | + cartId: 'Order Number', | ||
| 7 | + state: 'Select Status', | ||
| 8 | + prodName: 'Enter Product Name', | ||
| 9 | + shop: 'Select Shop' | ||
| 10 | + }, | ||
| 11 | + list: { | ||
| 12 | + title: 'Order Information' | ||
| 13 | + }, | ||
| 14 | + table: { | ||
| 15 | + cartId: 'Order Number', | ||
| 16 | + appName: 'Platform', | ||
| 17 | + shopName: 'Shop', | ||
| 18 | + cartType: 'Type', | ||
| 19 | + service: 'Service', | ||
| 20 | + goods: 'Goods', | ||
| 21 | + prodName: 'Name', | ||
| 22 | + cartNum: 'Quantity', | ||
| 23 | + personName: 'User Name', | ||
| 24 | + payPrice: 'Payment Amount', | ||
| 25 | + stateName: 'Order Status', | ||
| 26 | + createTime: 'Creation Time' | ||
| 27 | + }, | ||
| 28 | + state: { | ||
| 29 | + unpurchased: 'Unpurchased', | ||
| 30 | + waitingDelivery: 'Waiting Delivery', | ||
| 31 | + waitingReceive: 'Waiting Receive', | ||
| 32 | + waitingComment: 'Waiting Comment', | ||
| 33 | + applyRefund: 'Apply Refund', | ||
| 34 | + refundSuccess: 'Refund Success', | ||
| 35 | + refunded: 'Refunded' | ||
| 36 | + }, | ||
| 37 | + fetchError: 'Failed to fetch order list', | ||
| 38 | + fetchShopsError: 'Failed to fetch shops' | ||
| 39 | + } | ||
| 40 | + }, | ||
| 41 | + zh: { | ||
| 42 | + storeOrderCartManage: { | ||
| 43 | + search: { | ||
| 44 | + title: '查询条件', | ||
| 45 | + cartId: '订单编号', | ||
| 46 | + state: '请选择状态', | ||
| 47 | + prodName: '请输入商品名称', | ||
| 48 | + shop: '请选择商铺' | ||
| 49 | + }, | ||
| 50 | + list: { | ||
| 51 | + title: '订单信息' | ||
| 52 | + }, | ||
| 53 | + table: { | ||
| 54 | + cartId: '订单号', | ||
| 55 | + appName: '平台', | ||
| 56 | + shopName: '商铺', | ||
| 57 | + cartType: '类型', | ||
| 58 | + service: '服务', | ||
| 59 | + goods: '商品', | ||
| 60 | + prodName: '名称', | ||
| 61 | + cartNum: '数量', | ||
| 62 | + personName: '用户名称', | ||
| 63 | + payPrice: '支付金额', | ||
| 64 | + stateName: '订单状态', | ||
| 65 | + createTime: '创建时间' | ||
| 66 | + }, | ||
| 67 | + state: { | ||
| 68 | + unpurchased: '未购买', | ||
| 69 | + waitingDelivery: '待发货', | ||
| 70 | + waitingReceive: '待收货', | ||
| 71 | + waitingComment: '待评价', | ||
| 72 | + applyRefund: '申请退款', | ||
| 73 | + refundSuccess: '退货成功', | ||
| 74 | + refunded: '已退款' | ||
| 75 | + }, | ||
| 76 | + fetchError: '获取订单列表失败', | ||
| 77 | + fetchShopsError: '获取商铺列表失败' | ||
| 78 | + } | ||
| 79 | + } | ||
| 80 | +} | ||
| 0 | \ No newline at end of file | 81 | \ No newline at end of file |
src/views/mall/storeOrderCartManageList.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="store-order-cart-manage-container"> | ||
| 3 | + <!-- 查询条件 --> | ||
| 4 | + <el-card class="search-wrapper"> | ||
| 5 | + <div slot="header" class="clearfix text-left"> | ||
| 6 | + <span>{{ $t('storeOrderCartManage.search.title') }}</span> | ||
| 7 | + </div> | ||
| 8 | + <el-row :gutter="20"> | ||
| 9 | + <el-col :span="4"> | ||
| 10 | + <el-input v-model="searchForm.cartId" :placeholder="$t('storeOrderCartManage.search.cartId')" clearable /> | ||
| 11 | + </el-col> | ||
| 12 | + <el-col :span="4"> | ||
| 13 | + <el-select v-model="searchForm.state" :placeholder="$t('storeOrderCartManage.search.state')" clearable> | ||
| 14 | + <el-option v-for="item in stateOptions" :key="item.value" :label="item.label" :value="item.value" /> | ||
| 15 | + </el-select> | ||
| 16 | + </el-col> | ||
| 17 | + <el-col :span="4"> | ||
| 18 | + <el-input v-model="searchForm.prodName" :placeholder="$t('storeOrderCartManage.search.prodName')" clearable /> | ||
| 19 | + </el-col> | ||
| 20 | + <el-col :span="4"> | ||
| 21 | + <el-select v-model="searchForm.shopId" :placeholder="$t('storeOrderCartManage.search.shop')" clearable> | ||
| 22 | + <el-option v-for="item in shops" :key="item.shopId" :label="item.shopName" :value="item.shopId" /> | ||
| 23 | + </el-select> | ||
| 24 | + </el-col> | ||
| 25 | + <el-col :span="4" > | ||
| 26 | + <el-button type="primary" @click="handleSearch"> | ||
| 27 | + {{ $t('common.search') }} | ||
| 28 | + </el-button> | ||
| 29 | + </el-col> | ||
| 30 | + </el-row> | ||
| 31 | + </el-card> | ||
| 32 | + | ||
| 33 | + <!-- 订单列表 --> | ||
| 34 | + <el-card class="list-wrapper"> | ||
| 35 | + <div slot="header" class="clearfix text-left"> | ||
| 36 | + <span>{{ $t('storeOrderCartManage.list.title') }}</span> | ||
| 37 | + </div> | ||
| 38 | + <el-table v-loading="loading" :data="tableData" border style="width: 100%"> | ||
| 39 | + <el-table-column prop="cartId" :label="$t('storeOrderCartManage.table.cartId')" align="center" /> | ||
| 40 | + <el-table-column prop="appName" :label="$t('storeOrderCartManage.table.appName')" align="center" /> | ||
| 41 | + <el-table-column prop="shopName" :label="$t('storeOrderCartManage.table.shopName')" align="center" /> | ||
| 42 | + <el-table-column :label="$t('storeOrderCartManage.table.cartType')" align="center"> | ||
| 43 | + <template slot-scope="scope"> | ||
| 44 | + {{ scope.row.cartType === '3307' ? $t('storeOrderCartManage.table.service') : | ||
| 45 | + $t('storeOrderCartManage.table.goods') }} | ||
| 46 | + </template> | ||
| 47 | + </el-table-column> | ||
| 48 | + <el-table-column :label="$t('storeOrderCartManage.table.prodName')" align="center"> | ||
| 49 | + <template slot-scope="scope"> | ||
| 50 | + {{ scope.row.prodName }} | ||
| 51 | + <span v-if="scope.row.cartType !== '3307'">({{ scope.row.specValue }})</span> | ||
| 52 | + </template> | ||
| 53 | + </el-table-column> | ||
| 54 | + <el-table-column prop="cartNum" :label="$t('storeOrderCartManage.table.cartNum')" align="center" /> | ||
| 55 | + <el-table-column prop="personName" :label="$t('storeOrderCartManage.table.personName')" align="center" /> | ||
| 56 | + <el-table-column prop="payPrice" :label="$t('storeOrderCartManage.table.payPrice')" align="center" /> | ||
| 57 | + <el-table-column prop="stateName" :label="$t('storeOrderCartManage.table.stateName')" align="center" /> | ||
| 58 | + <el-table-column prop="createTime" :label="$t('storeOrderCartManage.table.createTime')" align="center" /> | ||
| 59 | + </el-table> | ||
| 60 | + | ||
| 61 | + <el-pagination :current-page.sync="page.current" :page-sizes="[10, 20, 30, 50]" :page-size="page.size" | ||
| 62 | + :total="page.total" layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange" | ||
| 63 | + @current-change="handleCurrentChange" /> | ||
| 64 | + </el-card> | ||
| 65 | + </div> | ||
| 66 | +</template> | ||
| 67 | + | ||
| 68 | +<script> | ||
| 69 | +import { queryAdminStoreOrderCart, queryShopsByAdmin } from '@/api/mall/storeOrderCartManageApi' | ||
| 70 | + | ||
| 71 | +export default { | ||
| 72 | + name: 'StoreOrderCartManageList', | ||
| 73 | + data() { | ||
| 74 | + return { | ||
| 75 | + loading: false, | ||
| 76 | + searchForm: { | ||
| 77 | + cartId: '', | ||
| 78 | + state: '', | ||
| 79 | + shopId: '', | ||
| 80 | + prodName: '', | ||
| 81 | + mallApiCode: 'queryAdminStoreOrderCartBmoImpl' | ||
| 82 | + }, | ||
| 83 | + stateOptions: [ | ||
| 84 | + { value: '1001', label: this.$t('storeOrderCartManage.state.unpurchased') }, | ||
| 85 | + { value: '2002', label: this.$t('storeOrderCartManage.state.waitingDelivery') }, | ||
| 86 | + { value: '3003', label: this.$t('storeOrderCartManage.state.waitingReceive') }, | ||
| 87 | + { value: '4004', label: this.$t('storeOrderCartManage.state.waitingComment') }, | ||
| 88 | + { value: '5005', label: this.$t('storeOrderCartManage.state.applyRefund') }, | ||
| 89 | + { value: '6006', label: this.$t('storeOrderCartManage.state.refundSuccess') }, | ||
| 90 | + { value: '7007', label: this.$t('storeOrderCartManage.state.refunded') } | ||
| 91 | + ], | ||
| 92 | + shops: [], | ||
| 93 | + tableData: [], | ||
| 94 | + page: { | ||
| 95 | + current: 1, | ||
| 96 | + size: 10, | ||
| 97 | + total: 0 | ||
| 98 | + } | ||
| 99 | + } | ||
| 100 | + }, | ||
| 101 | + created() { | ||
| 102 | + this.getList() | ||
| 103 | + this.getShops() | ||
| 104 | + }, | ||
| 105 | + methods: { | ||
| 106 | + async getList() { | ||
| 107 | + try { | ||
| 108 | + this.loading = true | ||
| 109 | + const params = { | ||
| 110 | + ...this.searchForm, | ||
| 111 | + page: this.page.current, | ||
| 112 | + row: this.page.size | ||
| 113 | + } | ||
| 114 | + const { data, total } = await queryAdminStoreOrderCart(params) | ||
| 115 | + this.tableData = data | ||
| 116 | + this.page.total = total | ||
| 117 | + } catch (error) { | ||
| 118 | + this.$message.error(this.$t('storeOrderCartManage.fetchError')) | ||
| 119 | + } finally { | ||
| 120 | + this.loading = false | ||
| 121 | + } | ||
| 122 | + }, | ||
| 123 | + async getShops() { | ||
| 124 | + try { | ||
| 125 | + const params = { | ||
| 126 | + page: 1, | ||
| 127 | + row: 100, | ||
| 128 | + mallApiCode: 'queryShopsByAdminBmoImpl' | ||
| 129 | + } | ||
| 130 | + const { data } = await queryShopsByAdmin(params) | ||
| 131 | + this.shops = data | ||
| 132 | + } catch (error) { | ||
| 133 | + this.$message.error(this.$t('storeOrderCartManage.fetchShopsError')) | ||
| 134 | + } | ||
| 135 | + }, | ||
| 136 | + handleSearch() { | ||
| 137 | + this.page.current = 1 | ||
| 138 | + this.getList() | ||
| 139 | + }, | ||
| 140 | + handleSizeChange(val) { | ||
| 141 | + this.page.size = val | ||
| 142 | + this.getList() | ||
| 143 | + }, | ||
| 144 | + handleCurrentChange(val) { | ||
| 145 | + this.page.current = val | ||
| 146 | + this.getList() | ||
| 147 | + } | ||
| 148 | + } | ||
| 149 | +} | ||
| 150 | +</script> | ||
| 151 | + | ||
| 152 | +<style lang="scss" scoped> | ||
| 153 | +.store-order-cart-manage-container { | ||
| 154 | + padding: 20px; | ||
| 155 | + | ||
| 156 | + .search-wrapper { | ||
| 157 | + margin-bottom: 20px; | ||
| 158 | + } | ||
| 159 | + | ||
| 160 | + .list-wrapper { | ||
| 161 | + margin-bottom: 20px; | ||
| 162 | + } | ||
| 163 | + | ||
| 164 | + .el-pagination { | ||
| 165 | + margin-top: 20px; | ||
| 166 | + text-align: right; | ||
| 167 | + } | ||
| 168 | +} | ||
| 169 | +</style> | ||
| 0 | \ No newline at end of file | 170 | \ No newline at end of file |
src/views/mall/storeOrderCartReturnLang.js
0 → 100644
| 1 | +export const messages = { | ||
| 2 | + en: { | ||
| 3 | + storeOrderCartReturn: { | ||
| 4 | + search: { | ||
| 5 | + title: 'Search Conditions', | ||
| 6 | + cartId: 'Order Number', | ||
| 7 | + state: 'Please select status', | ||
| 8 | + prodName: 'Please enter product name' | ||
| 9 | + }, | ||
| 10 | + list: { | ||
| 11 | + title: 'Return Orders' | ||
| 12 | + }, | ||
| 13 | + table: { | ||
| 14 | + cartId: 'Order Number', | ||
| 15 | + prodName: 'Product Name', | ||
| 16 | + specValue: 'Product Specification', | ||
| 17 | + personName: 'User Name', | ||
| 18 | + returnPayPrice: 'Refund Amount', | ||
| 19 | + stateName: 'Order Status', | ||
| 20 | + returnReason: 'Refund Reason', | ||
| 21 | + createTime: 'Application Time' | ||
| 22 | + }, | ||
| 23 | + state: { | ||
| 24 | + all: 'All Status', | ||
| 25 | + applyRefund: 'Apply for Refund', | ||
| 26 | + returnSuccess: 'Return Success', | ||
| 27 | + refunded: 'Refunded' | ||
| 28 | + }, | ||
| 29 | + fetchError: 'Failed to fetch return orders' | ||
| 30 | + } | ||
| 31 | + }, | ||
| 32 | + zh: { | ||
| 33 | + storeOrderCartReturn: { | ||
| 34 | + search: { | ||
| 35 | + title: '查询条件', | ||
| 36 | + cartId: '订单编号', | ||
| 37 | + state: '请选择状态', | ||
| 38 | + prodName: '请输入商品名称' | ||
| 39 | + }, | ||
| 40 | + list: { | ||
| 41 | + title: '退货订单' | ||
| 42 | + }, | ||
| 43 | + table: { | ||
| 44 | + cartId: '订单号', | ||
| 45 | + prodName: '商品名称', | ||
| 46 | + specValue: '商品规格', | ||
| 47 | + personName: '用户名称', | ||
| 48 | + returnPayPrice: '退款金额', | ||
| 49 | + stateName: '订单状态', | ||
| 50 | + returnReason: '退款原因', | ||
| 51 | + createTime: '申请时间' | ||
| 52 | + }, | ||
| 53 | + state: { | ||
| 54 | + all: '全部状态', | ||
| 55 | + applyRefund: '申请退款', | ||
| 56 | + returnSuccess: '退货成功', | ||
| 57 | + refunded: '已退款' | ||
| 58 | + }, | ||
| 59 | + fetchError: '获取退货订单失败' | ||
| 60 | + } | ||
| 61 | + } | ||
| 62 | +} | ||
| 0 | \ No newline at end of file | 63 | \ No newline at end of file |
src/views/mall/storeOrderCartReturnList.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="store-order-cart-return-container"> | ||
| 3 | + <!-- 查询条件 --> | ||
| 4 | + <el-card class="search-wrapper"> | ||
| 5 | + <div slot="header" class="clearfix text-left"> | ||
| 6 | + <span>{{ $t('storeOrderCartReturn.search.title') }}</span> | ||
| 7 | + </div> | ||
| 8 | + <el-row :gutter="20"> | ||
| 9 | + <el-col :span="6"> | ||
| 10 | + <el-input v-model="searchForm.cartId" :placeholder="$t('storeOrderCartReturn.search.cartId')" clearable | ||
| 11 | + @keyup.enter.native="handleSearch" /> | ||
| 12 | + </el-col> | ||
| 13 | + <el-col :span="6"> | ||
| 14 | + <el-select v-model="searchForm.state" :placeholder="$t('storeOrderCartReturn.search.state')" clearable> | ||
| 15 | + <el-option v-for="item in stateOptions" :key="item.value" :label="item.label" :value="item.value" /> | ||
| 16 | + </el-select> | ||
| 17 | + </el-col> | ||
| 18 | + <el-col :span="6"> | ||
| 19 | + <el-input v-model="searchForm.prodName" :placeholder="$t('storeOrderCartReturn.search.prodName')" clearable | ||
| 20 | + @keyup.enter.native="handleSearch" /> | ||
| 21 | + </el-col> | ||
| 22 | + <el-col :span="6"> | ||
| 23 | + <el-button type="primary" @click="handleSearch"> | ||
| 24 | + {{ $t('common.search') }} | ||
| 25 | + </el-button> | ||
| 26 | + </el-col> | ||
| 27 | + </el-row> | ||
| 28 | + </el-card> | ||
| 29 | + | ||
| 30 | + <!-- 退货订单列表 --> | ||
| 31 | + <el-card class="list-wrapper"> | ||
| 32 | + <div slot="header" class="clearfix text-left"> | ||
| 33 | + <span>{{ $t('storeOrderCartReturn.list.title') }}</span> | ||
| 34 | + </div> | ||
| 35 | + <el-table v-loading="loading" :data="tableData" border style="width: 100%"> | ||
| 36 | + <el-table-column prop="cartId" :label="$t('storeOrderCartReturn.table.cartId')" align="center" /> | ||
| 37 | + <el-table-column prop="prodName" :label="$t('storeOrderCartReturn.table.prodName')" align="center" /> | ||
| 38 | + <el-table-column prop="specValue" :label="$t('storeOrderCartReturn.table.specValue')" align="center" /> | ||
| 39 | + <el-table-column prop="personName" :label="$t('storeOrderCartReturn.table.personName')" align="center" /> | ||
| 40 | + <el-table-column prop="returnPayPrice" :label="$t('storeOrderCartReturn.table.returnPayPrice')" align="center" /> | ||
| 41 | + <el-table-column prop="stateName" :label="$t('storeOrderCartReturn.table.stateName')" align="center" /> | ||
| 42 | + <el-table-column prop="returnReason" :label="$t('storeOrderCartReturn.table.returnReason')" align="center" /> | ||
| 43 | + <el-table-column prop="createTime" :label="$t('storeOrderCartReturn.table.createTime')" align="center" /> | ||
| 44 | + </el-table> | ||
| 45 | + | ||
| 46 | + <el-pagination :current-page.sync="page.current" :page-sizes="[10, 20, 30, 50]" :page-size="page.size" | ||
| 47 | + :total="page.total" layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange" | ||
| 48 | + @current-change="handleCurrentChange" /> | ||
| 49 | + </el-card> | ||
| 50 | + </div> | ||
| 51 | +</template> | ||
| 52 | + | ||
| 53 | +<script> | ||
| 54 | +import { getStoreOrderCartReturnList } from '@/api/mall/storeOrderCartReturnApi' | ||
| 55 | + | ||
| 56 | +export default { | ||
| 57 | + name: 'StoreOrderCartReturnList', | ||
| 58 | + data() { | ||
| 59 | + return { | ||
| 60 | + loading: false, | ||
| 61 | + searchForm: { | ||
| 62 | + cartId: '', | ||
| 63 | + state: '', | ||
| 64 | + prodName: '', | ||
| 65 | + mallApiCode: 'queryStoreOrderCartReturnBmoImpl' | ||
| 66 | + }, | ||
| 67 | + stateOptions: [ | ||
| 68 | + { value: '', label: this.$t('storeOrderCartReturn.state.all') }, | ||
| 69 | + { value: '5005', label: this.$t('storeOrderCartReturn.state.applyRefund') }, | ||
| 70 | + { value: '6006', label: this.$t('storeOrderCartReturn.state.returnSuccess') }, | ||
| 71 | + { value: '7007', label: this.$t('storeOrderCartReturn.state.refunded') } | ||
| 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 | + ...this.searchForm, | ||
| 90 | + page: this.page.current, | ||
| 91 | + row: this.page.size | ||
| 92 | + } | ||
| 93 | + const { data, total } = await getStoreOrderCartReturnList(params) | ||
| 94 | + this.tableData = data.map(item => { | ||
| 95 | + let specValue = '' | ||
| 96 | + if (item.productSpecDetails) { | ||
| 97 | + item.productSpecDetails.forEach(detail => { | ||
| 98 | + specValue += (detail.detailValue + '/') | ||
| 99 | + }) | ||
| 100 | + } | ||
| 101 | + return { | ||
| 102 | + ...item, | ||
| 103 | + specValue | ||
| 104 | + } | ||
| 105 | + }) | ||
| 106 | + this.page.total = total | ||
| 107 | + } catch (error) { | ||
| 108 | + this.$message.error(this.$t('storeOrderCartReturn.fetchError')) | ||
| 109 | + } finally { | ||
| 110 | + this.loading = false | ||
| 111 | + } | ||
| 112 | + }, | ||
| 113 | + handleSearch() { | ||
| 114 | + this.page.current = 1 | ||
| 115 | + this.getList() | ||
| 116 | + }, | ||
| 117 | + handleSizeChange(val) { | ||
| 118 | + this.page.size = val | ||
| 119 | + this.getList() | ||
| 120 | + }, | ||
| 121 | + handleCurrentChange(val) { | ||
| 122 | + this.page.current = val | ||
| 123 | + this.getList() | ||
| 124 | + } | ||
| 125 | + } | ||
| 126 | +} | ||
| 127 | +</script> | ||
| 128 | + | ||
| 129 | +<style lang="scss" scoped> | ||
| 130 | +.store-order-cart-return-container { | ||
| 131 | + padding: 20px; | ||
| 132 | + | ||
| 133 | + .search-wrapper { | ||
| 134 | + margin-bottom: 20px; | ||
| 135 | + | ||
| 136 | + .el-select { | ||
| 137 | + width: 100%; | ||
| 138 | + } | ||
| 139 | + } | ||
| 140 | + | ||
| 141 | + .el-pagination { | ||
| 142 | + margin-top: 20px; | ||
| 143 | + text-align: right; | ||
| 144 | + } | ||
| 145 | +} | ||
| 146 | +</style> | ||
| 0 | \ No newline at end of file | 147 | \ No newline at end of file |
src/views/mall/userIntegralLang.js
0 → 100644
| 1 | +export const messages = { | ||
| 2 | + en: { | ||
| 3 | + userIntegral: { | ||
| 4 | + search: { | ||
| 5 | + title: 'Search Conditions', | ||
| 6 | + integralName: 'Account Name', | ||
| 7 | + integralNamePlaceholder: 'Please enter account name' | ||
| 8 | + }, | ||
| 9 | + list: { | ||
| 10 | + title: 'User Points' | ||
| 11 | + }, | ||
| 12 | + table: { | ||
| 13 | + id: 'ID', | ||
| 14 | + name: 'Account Name', | ||
| 15 | + type: 'Object Type', | ||
| 16 | + userId: 'User ID', | ||
| 17 | + phone: 'Phone', | ||
| 18 | + amount: 'Points' | ||
| 19 | + }, | ||
| 20 | + type: { | ||
| 21 | + personal: 'Personal', | ||
| 22 | + merchant: 'Merchant' | ||
| 23 | + }, | ||
| 24 | + fetchError: 'Failed to fetch points data' | ||
| 25 | + }, | ||
| 26 | + common: { | ||
| 27 | + search: 'Search', | ||
| 28 | + manage: 'Manage' | ||
| 29 | + } | ||
| 30 | + }, | ||
| 31 | + zh: { | ||
| 32 | + userIntegral: { | ||
| 33 | + search: { | ||
| 34 | + title: '查询条件', | ||
| 35 | + integralName: '账户名称', | ||
| 36 | + integralNamePlaceholder: '请输入账户名称' | ||
| 37 | + }, | ||
| 38 | + list: { | ||
| 39 | + title: '用户积分' | ||
| 40 | + }, | ||
| 41 | + table: { | ||
| 42 | + id: '编号', | ||
| 43 | + name: '账户名称', | ||
| 44 | + type: '对象类型', | ||
| 45 | + userId: '用户编号', | ||
| 46 | + phone: '手机号', | ||
| 47 | + amount: '积分数' | ||
| 48 | + }, | ||
| 49 | + type: { | ||
| 50 | + personal: '个人', | ||
| 51 | + merchant: '商户' | ||
| 52 | + }, | ||
| 53 | + fetchError: '获取积分数据失败' | ||
| 54 | + }, | ||
| 55 | + common: { | ||
| 56 | + search: '查询', | ||
| 57 | + manage: '管理' | ||
| 58 | + } | ||
| 59 | + } | ||
| 60 | +} | ||
| 0 | \ No newline at end of file | 61 | \ No newline at end of file |
src/views/mall/userIntegralList.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="user-integral-container"> | ||
| 3 | + <el-row :gutter="20"> | ||
| 4 | + <el-col :span="3"> | ||
| 5 | + <el-card class="box-card"> | ||
| 6 | + <div class="type-selector"> | ||
| 7 | + <ul class="type-list"> | ||
| 8 | + <li v-for="type in integralTypes" :key="type.value" class="type-item" | ||
| 9 | + :class="{ 'active': searchForm.objType === type.value }" @click="switchIntegralType(type.value)"> | ||
| 10 | + {{ $t(`userIntegral.type.${type.label}`) }} | ||
| 11 | + </li> | ||
| 12 | + </ul> | ||
| 13 | + </div> | ||
| 14 | + </el-card> | ||
| 15 | + </el-col> | ||
| 16 | + <el-col :span="21"> | ||
| 17 | + <el-card class="box-card"> | ||
| 18 | + <div slot="header" class="clearfix text-left"> | ||
| 19 | + <span>{{ $t('userIntegral.search.title') }}</span> | ||
| 20 | + </div> | ||
| 21 | + <el-form :inline="true" :model="searchForm" class="search-form text-left"> | ||
| 22 | + <el-form-item :label="$t('userIntegral.search.integralName')"> | ||
| 23 | + <el-input v-model="searchForm.integralName" :placeholder="$t('userIntegral.search.integralNamePlaceholder')" | ||
| 24 | + clearable /> | ||
| 25 | + </el-form-item> | ||
| 26 | + <el-form-item> | ||
| 27 | + <el-button type="primary" @click="handleSearch"> | ||
| 28 | + {{ $t('common.search') }} | ||
| 29 | + </el-button> | ||
| 30 | + </el-form-item> | ||
| 31 | + </el-form> | ||
| 32 | + </el-card> | ||
| 33 | + | ||
| 34 | + <el-card class="box-card"> | ||
| 35 | + <div slot="header" class="clearfix text-left"> | ||
| 36 | + <span>{{ $t('userIntegral.list.title') }}</span> | ||
| 37 | + <el-button type="primary" size="mini" style="float: right;" @click="handleManage"> | ||
| 38 | + {{ $t('common.manage') }} | ||
| 39 | + </el-button> | ||
| 40 | + </div> | ||
| 41 | + <el-table v-loading="loading" :data="tableData" border style="width: 100%"> | ||
| 42 | + <el-table-column prop="integralId" :label="$t('userIntegral.table.id')" align="center" /> | ||
| 43 | + <el-table-column prop="integralName" :label="$t('userIntegral.table.name')" align="center" /> | ||
| 44 | + <el-table-column :label="$t('userIntegral.table.type')" align="center"> | ||
| 45 | + <template slot-scope="scope"> | ||
| 46 | + {{ scope.row.objType === '7007' ? $t('userIntegral.type.merchant') : $t('userIntegral.type.personal') }} | ||
| 47 | + </template> | ||
| 48 | + </el-table-column> | ||
| 49 | + <el-table-column prop="objId" :label="$t('userIntegral.table.userId')" align="center" /> | ||
| 50 | + <el-table-column prop="link" :label="$t('userIntegral.table.phone')" align="center" /> | ||
| 51 | + <el-table-column prop="amount" :label="$t('userIntegral.table.amount')" align="center" /> | ||
| 52 | + </el-table> | ||
| 53 | + <pagination :current-page="pagination.current" :page-size="pagination.size" :total="pagination.total" | ||
| 54 | + @size-change="handleSizeChange" @current-change="handleCurrentChange" /> | ||
| 55 | + </el-card> | ||
| 56 | + </el-col> | ||
| 57 | + </el-row> | ||
| 58 | + </div> | ||
| 59 | +</template> | ||
| 60 | + | ||
| 61 | +<script> | ||
| 62 | +import { queryIntegralList } from '@/api/mall/userIntegralApi' | ||
| 63 | +import Pagination from '@/components/mall/Pagination' | ||
| 64 | + | ||
| 65 | +export default { | ||
| 66 | + name: 'UserIntegralList', | ||
| 67 | + components: { | ||
| 68 | + Pagination | ||
| 69 | + }, | ||
| 70 | + data() { | ||
| 71 | + return { | ||
| 72 | + loading: false, | ||
| 73 | + integralTypes: [ | ||
| 74 | + { value: '6006', label: 'personal' }, | ||
| 75 | + { value: '7007', label: 'merchant' } | ||
| 76 | + ], | ||
| 77 | + searchForm: { | ||
| 78 | + integralName: '', | ||
| 79 | + objType: '6006', | ||
| 80 | + mallApiCode: 'queryIntegralBmoImpl' | ||
| 81 | + }, | ||
| 82 | + tableData: [], | ||
| 83 | + pagination: { | ||
| 84 | + current: 1, | ||
| 85 | + size: 10, | ||
| 86 | + total: 0 | ||
| 87 | + } | ||
| 88 | + } | ||
| 89 | + }, | ||
| 90 | + created() { | ||
| 91 | + this.getList() | ||
| 92 | + }, | ||
| 93 | + methods: { | ||
| 94 | + async getList() { | ||
| 95 | + try { | ||
| 96 | + this.loading = true | ||
| 97 | + const params = { | ||
| 98 | + page: this.pagination.current, | ||
| 99 | + row: this.pagination.size, | ||
| 100 | + ...this.searchForm | ||
| 101 | + } | ||
| 102 | + const { data, total } = await queryIntegralList(params) | ||
| 103 | + this.tableData = data | ||
| 104 | + this.pagination.total = total | ||
| 105 | + } catch (error) { | ||
| 106 | + this.$message.error(this.$t('userIntegral.fetchError')) | ||
| 107 | + } finally { | ||
| 108 | + this.loading = false | ||
| 109 | + } | ||
| 110 | + }, | ||
| 111 | + handleSearch() { | ||
| 112 | + this.pagination.current = 1 | ||
| 113 | + this.getList() | ||
| 114 | + }, | ||
| 115 | + handleManage() { | ||
| 116 | + const path = this.searchForm.objType === '6006' | ||
| 117 | + ? '/pages/admin/userIntegral' | ||
| 118 | + : '/pages/admin/storeIntegral' | ||
| 119 | + this.$router.push({ path }) | ||
| 120 | + }, | ||
| 121 | + switchIntegralType(type) { | ||
| 122 | + this.searchForm.objType = type | ||
| 123 | + this.handleSearch() | ||
| 124 | + }, | ||
| 125 | + handleSizeChange(val) { | ||
| 126 | + this.pagination.size = val | ||
| 127 | + this.getList() | ||
| 128 | + }, | ||
| 129 | + handleCurrentChange(val) { | ||
| 130 | + this.pagination.current = val | ||
| 131 | + this.getList() | ||
| 132 | + } | ||
| 133 | + } | ||
| 134 | +} | ||
| 135 | +</script> | ||
| 136 | + | ||
| 137 | +<style lang="scss" scoped> | ||
| 138 | +.user-integral-container { | ||
| 139 | + padding: 20px; | ||
| 140 | + | ||
| 141 | + .box-card { | ||
| 142 | + margin-bottom: 20px; | ||
| 143 | + } | ||
| 144 | + | ||
| 145 | + .type-selector { | ||
| 146 | + .type-list { | ||
| 147 | + list-style: none; | ||
| 148 | + padding: 0; | ||
| 149 | + margin: 0; | ||
| 150 | + | ||
| 151 | + .type-item { | ||
| 152 | + padding: 10px; | ||
| 153 | + text-align: center; | ||
| 154 | + cursor: pointer; | ||
| 155 | + border-radius: 4px; | ||
| 156 | + margin-bottom: 5px; | ||
| 157 | + transition: all 0.3s; | ||
| 158 | + | ||
| 159 | + &:hover { | ||
| 160 | + background-color: #f5f7fa; | ||
| 161 | + } | ||
| 162 | + | ||
| 163 | + &.active { | ||
| 164 | + background-color: #409eff; | ||
| 165 | + color: white; | ||
| 166 | + } | ||
| 167 | + } | ||
| 168 | + } | ||
| 169 | + } | ||
| 170 | + | ||
| 171 | + .search-form { | ||
| 172 | + margin-bottom: -18px; | ||
| 173 | + } | ||
| 174 | +} | ||
| 175 | +</style> | ||
| 0 | \ No newline at end of file | 176 | \ No newline at end of file |
src/views/user/userLoginLang.js
0 → 100644
| 1 | +export const messages = { | ||
| 2 | + en: { | ||
| 3 | + userLogin: { | ||
| 4 | + search: { | ||
| 5 | + title: 'Search Conditions', | ||
| 6 | + name: 'Please enter staff name', | ||
| 7 | + tel: 'Please enter phone number', | ||
| 8 | + startTime: 'Login start time', | ||
| 9 | + endTime: 'Login end time' | ||
| 10 | + }, | ||
| 11 | + table: { | ||
| 12 | + title: 'Login Logs', | ||
| 13 | + loginId: 'Login ID', | ||
| 14 | + parentOrgName: 'Company', | ||
| 15 | + orgName: 'Department', | ||
| 16 | + userName: 'Name', | ||
| 17 | + loginTime: 'Login Time', | ||
| 18 | + userId: 'Staff ID' | ||
| 19 | + }, | ||
| 20 | + allStores: 'All', | ||
| 21 | + fetchError: 'Failed to fetch login logs', | ||
| 22 | + storeFetchError: 'Failed to fetch store list' | ||
| 23 | + } | ||
| 24 | + }, | ||
| 25 | + zh: { | ||
| 26 | + userLogin: { | ||
| 27 | + search: { | ||
| 28 | + title: '查询条件', | ||
| 29 | + name: '请输入员工名称', | ||
| 30 | + tel: '请输入手机号', | ||
| 31 | + startTime: '登录开始时间', | ||
| 32 | + endTime: '登录结束时间' | ||
| 33 | + }, | ||
| 34 | + table: { | ||
| 35 | + title: '登录日志', | ||
| 36 | + loginId: '登录ID', | ||
| 37 | + parentOrgName: '公司', | ||
| 38 | + orgName: '部门', | ||
| 39 | + userName: '名称', | ||
| 40 | + loginTime: '登录时间', | ||
| 41 | + userId: '员工ID' | ||
| 42 | + }, | ||
| 43 | + allStores: '全部', | ||
| 44 | + fetchError: '获取登录日志失败', | ||
| 45 | + storeFetchError: '获取门店列表失败' | ||
| 46 | + } | ||
| 47 | + } | ||
| 48 | +} | ||
| 0 | \ No newline at end of file | 49 | \ No newline at end of file |
src/views/user/userLoginList.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="user-login-container"> | ||
| 3 | + <el-row :gutter="20"> | ||
| 4 | + <el-col :span="4"> | ||
| 5 | + <el-card class="store-list-card"> | ||
| 6 | + <div class="store-list"> | ||
| 7 | + <ul class="store-ul"> | ||
| 8 | + <li | ||
| 9 | + v-for="(item,index) in userLoginInfo.stores" | ||
| 10 | + :key="index" | ||
| 11 | + @click="swatchStore(item)" | ||
| 12 | + :class="{'selected-store':userLoginInfo.conditions.storeId == item.storeId}"> | ||
| 13 | + {{item.name}}<span v-if="item.storeTypeName">({{item.storeTypeName}})</span> | ||
| 14 | + </li> | ||
| 15 | + </ul> | ||
| 16 | + </div> | ||
| 17 | + </el-card> | ||
| 18 | + </el-col> | ||
| 19 | + <el-col :span="20"> | ||
| 20 | + <el-card class="search-card"> | ||
| 21 | + <div slot="header" class="clearfix text-left"> | ||
| 22 | + <span>{{ $t('userLogin.search.title') }}</span> | ||
| 23 | + </div> | ||
| 24 | + <el-row :gutter="20"> | ||
| 25 | + <el-col :span="4"> | ||
| 26 | + <el-input | ||
| 27 | + :placeholder="$t('userLogin.search.name')" | ||
| 28 | + v-model="userLoginInfo.conditions.name" | ||
| 29 | + clearable /> | ||
| 30 | + </el-col> | ||
| 31 | + <el-col :span="4"> | ||
| 32 | + <el-input | ||
| 33 | + type="number" | ||
| 34 | + :placeholder="$t('userLogin.search.tel')" | ||
| 35 | + v-model="userLoginInfo.conditions.tel" | ||
| 36 | + clearable /> | ||
| 37 | + </el-col> | ||
| 38 | + <el-col :span="4"> | ||
| 39 | + <el-date-picker | ||
| 40 | + v-model="userLoginInfo.conditions.startTime" | ||
| 41 | + type="datetime" | ||
| 42 | + :placeholder="$t('userLogin.search.startTime')" | ||
| 43 | + value-format="yyyy-MM-dd HH:mm:ss"> | ||
| 44 | + </el-date-picker> | ||
| 45 | + </el-col> | ||
| 46 | + <el-col :span="4"> | ||
| 47 | + <el-date-picker | ||
| 48 | + v-model="userLoginInfo.conditions.endTime" | ||
| 49 | + type="datetime" | ||
| 50 | + :placeholder="$t('userLogin.search.endTime')" | ||
| 51 | + value-format="yyyy-MM-dd HH:mm:ss"> | ||
| 52 | + </el-date-picker> | ||
| 53 | + </el-col> | ||
| 54 | + <el-col :span="4" > | ||
| 55 | + <el-button type="primary" @click="_queryUserLoginMethod"> | ||
| 56 | + <i class="el-icon-search"></i> {{ $t('common.search') }} | ||
| 57 | + </el-button> | ||
| 58 | + </el-col> | ||
| 59 | + </el-row> | ||
| 60 | + </el-card> | ||
| 61 | + | ||
| 62 | + <el-card class="table-card"> | ||
| 63 | + <div slot="header" class="clearfix text-left"> | ||
| 64 | + <span>{{ $t('userLogin.table.title') }}</span> | ||
| 65 | + </div> | ||
| 66 | + <el-table | ||
| 67 | + v-loading="loading" | ||
| 68 | + :data="userLoginInfo.logs" | ||
| 69 | + border | ||
| 70 | + style="width: 100%"> | ||
| 71 | + <el-table-column | ||
| 72 | + prop="loginId" | ||
| 73 | + :label="$t('userLogin.table.loginId')" | ||
| 74 | + align="center" /> | ||
| 75 | + <el-table-column | ||
| 76 | + prop="parentOrgName" | ||
| 77 | + :label="$t('userLogin.table.parentOrgName')" | ||
| 78 | + align="center"> | ||
| 79 | + <template slot-scope="scope"> | ||
| 80 | + {{ scope.row.parentOrgName || '-' }} | ||
| 81 | + </template> | ||
| 82 | + </el-table-column> | ||
| 83 | + <el-table-column | ||
| 84 | + prop="orgName" | ||
| 85 | + :label="$t('userLogin.table.orgName')" | ||
| 86 | + align="center" /> | ||
| 87 | + <el-table-column | ||
| 88 | + prop="userName" | ||
| 89 | + :label="$t('userLogin.table.userName')" | ||
| 90 | + align="center" /> | ||
| 91 | + <el-table-column | ||
| 92 | + prop="loginTime" | ||
| 93 | + :label="$t('userLogin.table.loginTime')" | ||
| 94 | + align="center" /> | ||
| 95 | + <el-table-column | ||
| 96 | + prop="userId" | ||
| 97 | + :label="$t('userLogin.table.userId')" | ||
| 98 | + align="center" /> | ||
| 99 | + </el-table> | ||
| 100 | + | ||
| 101 | + <el-pagination | ||
| 102 | + @size-change="handleSizeChange" | ||
| 103 | + @current-change="handleCurrentChange" | ||
| 104 | + :current-page="pagination.current" | ||
| 105 | + :page-sizes="[10, 20, 30, 50]" | ||
| 106 | + :page-size="pagination.size" | ||
| 107 | + layout="total, sizes, prev, pager, next, jumper" | ||
| 108 | + :total="pagination.total" | ||
| 109 | + style="margin-top: 20px;"> | ||
| 110 | + </el-pagination> | ||
| 111 | + </el-card> | ||
| 112 | + </el-col> | ||
| 113 | + </el-row> | ||
| 114 | + </div> | ||
| 115 | +</template> | ||
| 116 | + | ||
| 117 | +<script> | ||
| 118 | +import { queryUserLogin, listStores } from '@/api/user/userLoginApi' | ||
| 119 | + | ||
| 120 | +export default { | ||
| 121 | + name: 'UserLoginList', | ||
| 122 | + data() { | ||
| 123 | + return { | ||
| 124 | + loading: false, | ||
| 125 | + userLoginInfo: { | ||
| 126 | + logs: [], | ||
| 127 | + stores: [], | ||
| 128 | + conditions: { | ||
| 129 | + name: '', | ||
| 130 | + tel: '', | ||
| 131 | + storeId: '', | ||
| 132 | + startTime: '', | ||
| 133 | + endTime: '', | ||
| 134 | + page: 1, | ||
| 135 | + row: 10 | ||
| 136 | + } | ||
| 137 | + }, | ||
| 138 | + pagination: { | ||
| 139 | + current: 1, | ||
| 140 | + size: 10, | ||
| 141 | + total: 0 | ||
| 142 | + } | ||
| 143 | + } | ||
| 144 | + }, | ||
| 145 | + created() { | ||
| 146 | + this.loadData() | ||
| 147 | + this._listListStores() | ||
| 148 | + }, | ||
| 149 | + methods: { | ||
| 150 | + async loadData() { | ||
| 151 | + try { | ||
| 152 | + this.loading = true | ||
| 153 | + const params = { | ||
| 154 | + ...this.userLoginInfo.conditions, | ||
| 155 | + page: this.pagination.current, | ||
| 156 | + row: this.pagination.size | ||
| 157 | + } | ||
| 158 | + const { data, records } = await queryUserLogin(params) | ||
| 159 | + this.userLoginInfo.logs = data | ||
| 160 | + this.pagination.total = records | ||
| 161 | + } catch (error) { | ||
| 162 | + this.$message.error(this.$t('userLogin.fetchError')) | ||
| 163 | + } finally { | ||
| 164 | + this.loading = false | ||
| 165 | + } | ||
| 166 | + }, | ||
| 167 | + async _listListStores() { | ||
| 168 | + try { | ||
| 169 | + const params = { | ||
| 170 | + page: 1, | ||
| 171 | + row: 100 | ||
| 172 | + } | ||
| 173 | + const { data } = await listStores(params) | ||
| 174 | + this.userLoginInfo.stores = [ | ||
| 175 | + { storeId: '', name: this.$t('userLogin.allStores') }, | ||
| 176 | + ...data | ||
| 177 | + ] | ||
| 178 | + } catch (error) { | ||
| 179 | + this.$message.error(this.$t('userLogin.storeFetchError')) | ||
| 180 | + } | ||
| 181 | + }, | ||
| 182 | + swatchStore(item) { | ||
| 183 | + this.userLoginInfo.conditions.storeId = item.storeId | ||
| 184 | + this.pagination.current = 1 | ||
| 185 | + this.loadData() | ||
| 186 | + }, | ||
| 187 | + _queryUserLoginMethod() { | ||
| 188 | + this.pagination.current = 1 | ||
| 189 | + this.loadData() | ||
| 190 | + }, | ||
| 191 | + handleSizeChange(val) { | ||
| 192 | + this.pagination.size = val | ||
| 193 | + this.loadData() | ||
| 194 | + }, | ||
| 195 | + handleCurrentChange(val) { | ||
| 196 | + this.pagination.current = val | ||
| 197 | + this.loadData() | ||
| 198 | + } | ||
| 199 | + } | ||
| 200 | +} | ||
| 201 | +</script> | ||
| 202 | + | ||
| 203 | +<style lang="scss" scoped> | ||
| 204 | +.user-login-container { | ||
| 205 | + padding: 20px; | ||
| 206 | + | ||
| 207 | + .store-list-card { | ||
| 208 | + height: 100%; | ||
| 209 | + | ||
| 210 | + .store-list { | ||
| 211 | + .store-ul { | ||
| 212 | + list-style: none; | ||
| 213 | + padding: 0; | ||
| 214 | + margin: 0; | ||
| 215 | + | ||
| 216 | + li { | ||
| 217 | + padding: 10px; | ||
| 218 | + cursor: pointer; | ||
| 219 | + border-radius: 4px; | ||
| 220 | + margin-bottom: 5px; | ||
| 221 | + text-align: center; | ||
| 222 | + | ||
| 223 | + &:hover { | ||
| 224 | + background-color: #f5f7fa; | ||
| 225 | + } | ||
| 226 | + | ||
| 227 | + &.selected-store { | ||
| 228 | + background-color: #409eff; | ||
| 229 | + color: white; | ||
| 230 | + } | ||
| 231 | + } | ||
| 232 | + } | ||
| 233 | + } | ||
| 234 | + } | ||
| 235 | + | ||
| 236 | + .search-card { | ||
| 237 | + margin-bottom: 20px; | ||
| 238 | + } | ||
| 239 | +} | ||
| 240 | +</style> | ||
| 0 | \ No newline at end of file | 241 | \ No newline at end of file |