This commit is contained in:
chy
2025-06-26 14:30:57 +08:00
parent db5d707e54
commit 310308c7d9
25 changed files with 3194 additions and 74 deletions

View File

@ -11,8 +11,6 @@
<el-table-column prop="name" label="商户名称" header-align="center" align="center" />
<el-table-column prop="contactName" label="联系人" header-align="center" align="center" />
<el-table-column prop="contactPhone" label="联系电话" header-align="center" align="center" />
<el-table-column prop="contactEmail" label="联系邮箱" header-align="center" align="center" />
<el-table-column prop="address" label="地址" header-align="center" align="center" />
<el-table-column prop="auditAt" label="通过时间" header-align="center" align="center" />
<el-table-column prop="expireAt" label="服务到期时间" header-align="center" align="center" />
<el-table-column prop="status" label="状态" header-align="center" align="center">
@ -44,11 +42,134 @@
:merchant-data="currentMerchant"
@success="handleEditSuccess"
/>
<!-- 门店列表弹窗 -->
<el-dialog
:title="currentMerchant.name + ' - 门店列表'"
:visible.sync="storeDialogVisible"
:close-on-click-modal="false"
class="store-dialog"
width="100%"
:fullscreen="true"
:show-close="false"
:append-to-body="true"
>
<div class="store-list-container">
<div class="store-list-header">
<div class="left">
<div class="back-btn" @click="handleBack">
<i class="el-icon-arrow-left"></i>
<span>返回</span>
</div>
</div>
<el-button type="primary" @click="handleAddStore">新增门店</el-button>
</div>
<el-table
v-loading="storeLoading"
:data="storeList"
border={false}
class="custom-table"
header-row-class-name="custom-header"
row-class-name="custom-row"
>
<el-table-column prop="name" label="门店名称" header-align="center" align="center" />
<el-table-column prop="storeCode" label="门店编号" header-align="center" align="center" />
<el-table-column prop="address" label="门店地址" header-align="center" align="center">
<template slot-scope="scope">
{{ scope.row.address || '-' }}
</template>
</el-table-column>
<el-table-column prop="contactName" label="联系人姓名" header-align="center" align="center">
<template slot-scope="scope">
{{ scope.row.contactName || '-' }}
</template>
</el-table-column>
<el-table-column prop="contactPhone" label="联系人电话" header-align="center" align="center">
<template slot-scope="scope">
{{ scope.row.contactPhone || '-' }}
</template>
</el-table-column>
<el-table-column prop="status" label="状态" header-align="center" align="center">
<template slot-scope="scope">
<span :class="['status-tag', scope.row.status === 1 ? 'status-normal' : 'status-block']">
{{ scope.row.status === 1 ? '营业中' : '已关闭' }}
</span>
</template>
</el-table-column>
<el-table-column prop="createdAt" label="创建时间" header-align="center" align="center">
<template slot-scope="scope">
{{ scope.row.createdAt || '-' }}
</template>
</el-table-column>
<el-table-column label="操作" width="180" header-align="center" align="center">
<template slot-scope="scope">
<el-button type="text" size="mini" class="edit-btn" @click="handleEditStore(scope.row)">编辑</el-button>
<el-button type="text" size="mini" class="delete-btn" @click="handleDeleteStore(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<div class="pagination-container">
<el-pagination
background
layout="prev, pager, next"
:total="storeTotal"
:page-size="storeQuery.size"
:current-page="storeQuery.page"
@current-change="handleStorePageChange"
/>
</div>
</div>
</el-dialog>
<!-- 门店编辑弹窗 -->
<el-dialog
:title="storeDialogType === 'add' ? '新增门店' : '编辑门店'"
:visible.sync="storeEditDialogVisible"
width="500px"
:close-on-click-modal="false"
@closed="handleStoreDialogClosed"
class="store-edit-dialog"
>
<el-form
ref="storeForm"
:model="storeForm"
:rules="storeRules"
label-width="100px"
size="medium"
>
<el-form-item label="门店名称" prop="name">
<el-input v-model="storeForm.name" placeholder="请输入门店名称" />
</el-form-item>
<el-form-item label="门店编号" prop="storeCode" v-if="storeDialogType === 'edit'">
<el-input v-model="storeForm.storeCode" placeholder="请输入门店编号" disabled />
</el-form-item>
<el-form-item label="门店地址" prop="address">
<el-input v-model="storeForm.address" placeholder="请输入门店地址" />
</el-form-item>
<el-form-item label="联系人姓名" prop="contactName">
<el-input v-model="storeForm.contactName" placeholder="请输入联系人姓名" />
</el-form-item>
<el-form-item label="联系人电话" prop="contactPhone">
<el-input v-model="storeForm.contactPhone" placeholder="请输入联系人电话" />
</el-form-item>
<el-form-item label="状态" prop="status">
<el-radio-group v-model="storeForm.status">
<el-radio :label="1">营业中</el-radio>
<el-radio :label="0">已关闭</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="storeEditDialogVisible = false"> </el-button>
<el-button type="primary" :loading="storeSubmitLoading" @click="handleStoreSubmit"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { merchantList } from '@/api/merchant'
import { getStoreList } from '@/api/store'
import MerchantEdit from './merchant-edit.vue'
export default {
@ -61,7 +182,52 @@ export default {
loading: false,
tableData: [],
editDialogVisible: false,
currentMerchant: {}
currentMerchant: {},
// 门店列表相关数据
storeDialogVisible: false,
storeEditDialogVisible: false,
storeLoading: false,
storeList: [],
storeTotal: 0,
storeQuery: {
page: 1,
size: 10,
merchantId: undefined
},
// 门店弹窗相关数据
storeDialogType: 'add', // add 或 edit
storeSubmitLoading: false,
storeForm: {
name: '',
storeCode: '',
address: '',
contactName: '',
contactPhone: '',
status: 1
},
storeRules: {
name: [
{ required: true, message: '请输入门店名称', trigger: 'blur' },
{ min: 2, max: 50, message: '长度在 2 到 50 个字符', trigger: 'blur' }
],
storeCode: [
{ required: true, message: '请输入门店编号', trigger: 'blur' },
{ min: 2, max: 20, message: '长度在 2 到 20 个字符', trigger: 'blur' }
],
address: [
{ required: true, message: '请输入门店地址', trigger: 'blur' }
],
contactName: [
{ required: true, message: '请输入联系人姓名', trigger: 'blur' }
],
contactPhone: [
{ required: true, message: '请输入联系人电话', trigger: 'blur' },
{ pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号码', trigger: 'blur' }
],
status: [
{ required: true, message: '请选择状态', trigger: 'change' }
]
}
}
},
created() {
@ -90,8 +256,36 @@ export default {
this.editDialogVisible = true
},
handleViewStores(row) {
// TODO: 实现查看门店功能
this.$message.info('查看门店功能开发中')
this.currentMerchant = row
this.storeQuery.merchantId = row.id
this.storeDialogVisible = true
this.getStoreList()
},
handleBack() {
this.storeDialogVisible = false
this.storeList = []
this.storeTotal = 0
this.currentMerchant = {}
},
async getStoreList() {
this.storeLoading = true
try {
const res = await getStoreList(this.storeQuery)
if (res.code === 0) {
this.storeList = res.data.list
this.storeTotal = res.data.total
} else {
this.$message.error(res.message || '获取门店列表失败')
}
} catch (error) {
this.$message.error('获取门店列表失败')
} finally {
this.storeLoading = false
}
},
handleStorePageChange(page) {
this.storeQuery.page = page
this.getStoreList()
},
async handleToggleStatus(row) {
try {
@ -110,6 +304,61 @@ export default {
},
handleEditSuccess() {
this.getList()
},
handleAddStore() {
this.storeDialogType = 'add'
this.storeEditDialogVisible = true
},
handleEditStore(row) {
this.storeDialogType = 'edit'
this.storeForm = {
id: row.id,
name: row.name,
storeCode: row.storeCode,
address: row.address,
contactName: row.contactName,
contactPhone: row.contactPhone,
status: row.status
}
this.storeEditDialogVisible = true
},
handleDeleteStore(row) {
this.$confirm('确认删除该门店吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.$message.info('删除门店功能待实现ID' + row.id)
}).catch(() => {})
},
handleStoreDialogClosed() {
this.$refs.storeForm && this.$refs.storeForm.resetFields()
this.storeForm = {
name: '',
storeCode: '',
address: '',
contactName: '',
contactPhone: '',
status: 1
}
},
handleStoreSubmit() {
this.$refs.storeForm.validate(async valid => {
if (!valid) return
this.storeSubmitLoading = true
try {
// TODO: 调用新增/编辑门店接口
const action = this.storeDialogType === 'add' ? '新增' : '编辑'
this.$message.success(`${action}成功`)
this.storeEditDialogVisible = false
this.getStoreList()
} catch (error) {
this.$message.error('操作失败')
} finally {
this.storeSubmitLoading = false
}
})
}
}
}
@ -183,4 +432,91 @@ export default {
font-weight: 500;
margin-left: 8px;
}
.store-list-container {
padding: 20px;
height: 100%;
overflow-y: auto;
}
.store-list-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
padding-bottom: 16px;
border-bottom: 1px solid #f0f0f0;
background: #fff;
position: sticky;
top: 0;
z-index: 1;
.left {
display: flex;
align-items: center;
}
}
.back-btn {
display: flex;
align-items: center;
cursor: pointer;
font-size: 14px;
color: #303133;
padding: 8px 0;
i {
margin-right: 4px;
font-size: 16px;
}
&:hover {
color: #409EFF;
}
}
.merchant-name {
margin-left: 16px;
font-size: 16px;
font-weight: 500;
color: #303133;
}
.store-dialog {
::v-deep .el-dialog__header {
display: none;
}
::v-deep .el-dialog__body {
padding: 0;
height: 100%;
}
}
.store-edit-dialog {
::v-deep .el-dialog__body {
padding: 20px 30px;
}
::v-deep .el-form-item__label {
text-align: left;
}
::v-deep .el-input__inner {
text-align: left;
}
::v-deep .el-radio-group {
text-align: left;
}
}
.pagination-container {
margin-top: 20px;
text-align: right;
}
.dialog-footer {
text-align: right;
}
</style>

View File

@ -11,8 +11,7 @@
<el-table-column prop="name" label="商户名称" header-align="center" align="center" />
<el-table-column prop="contactName" label="联系人" header-align="center" align="center" />
<el-table-column prop="contactPhone" label="联系电话" header-align="center" align="center" />
<el-table-column prop="contactEmail" label="联系邮箱" header-align="center" align="center" />
<el-table-column prop="address" label="地址" header-align="center" align="center" />
<el-table-column prop="applicationReason" label="申请原因" header-align="center" align="center" />
<el-table-column prop="createdAt" label="申请时间" header-align="center" align="center" />
<el-table-column prop="status" label="状态" header-align="center" align="center">
<template slot-scope="scope">
@ -66,12 +65,27 @@ export default {
async handleApprove(row) {
try {
await this.$confirm('确认通过该商户的审核吗?', '提示', {
type: 'warning'
type: 'warning',
confirmButtonText: '确定',
cancelButtonText: '取消'
})
// 选择服务到期时间
const { value: serviceExpire } = await this.$prompt(
'请选择服务到期时间',
'服务到期时间',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
inputType: 'date',
inputPattern: /.*/, // 允许为空
inputValue: ''
}
)
const res = await merchantAudit({
id: row.id,
auditStatus: 2,
auditRemark: '审核通过'
auditRemark: '审核通过',
serviceExpire
})
if (res.code === 0) {
this.$message.success('审核通过成功')

View File

@ -11,8 +11,6 @@
<el-table-column prop="name" label="商户名称" header-align="center" align="center" />
<el-table-column prop="contactName" label="联系人" header-align="center" align="center" />
<el-table-column prop="contactPhone" label="联系电话" header-align="center" align="center" />
<el-table-column prop="contactEmail" label="联系邮箱" header-align="center" align="center" />
<el-table-column prop="address" label="地址" header-align="center" align="center" />
<el-table-column prop="auditAt" label="拒绝时间" header-align="center" align="center" />
<el-table-column prop="rejectReason" label="拒绝原因" header-align="center" align="center" />
<el-table-column prop="status" label="状态" header-align="center" align="center">

View File

@ -91,6 +91,8 @@ export default {
padding: 20px;
background: #fff;
border-radius: 4px;
position: relative;
min-height: 100vh;
}
.search-area {
margin-bottom: 20px;
@ -120,4 +122,29 @@ export default {
padding: 20px;
border-radius: 4px;
}
::v-deep .el-dialog {
margin: 0 !important;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100% !important;
height: 100%;
border-radius: 0;
.el-dialog__header {
padding: 20px;
border-bottom: 1px solid #e4e7ed;
}
.el-dialog__body {
height: calc(100% - 120px);
padding: 20px;
overflow-y: auto;
}
.el-dialog__footer {
padding: 20px;
border-top: 1px solid #e4e7ed;
}
}
</style>