完善功能

This commit is contained in:
wangxiaowei
2026-02-12 02:17:07 +08:00
parent 69f27feca0
commit 6731c05e3e
22 changed files with 1857 additions and 279 deletions

Binary file not shown.

26
src/api/order_store.ts Normal file
View File

@ -0,0 +1,26 @@
import request from '@/utils/request'
// 茶室订单表列表
export function apiOrderStoreLists(params: any) {
return request.get({ url: '/order_store/lists', params })
}
// 添加茶室订单表
export function apiOrderStoreAdd(params: any) {
return request.post({ url: '/order_store/add', params })
}
// 编辑茶室订单表
export function apiOrderStoreEdit(params: any) {
return request.post({ url: '/order_store/edit', params })
}
// 删除茶室订单表
export function apiOrderStoreDelete(params: any) {
return request.post({ url: '/order_store/delete', params })
}
// 茶室订单表详情
export function apiOrderStoreDetail(params: any) {
return request.get({ url: '/order_store/detail', params })
}

View File

@ -0,0 +1,26 @@
import request from '@/utils/request'
// 商家提现表列表
export function apiStoreUserReflectLists(params: any) {
return request.get({ url: '/store_user_reflect/lists', params })
}
// 添加商家提现表
export function apiStoreUserReflectAdd(params: any) {
return request.post({ url: '/store_user_reflect/add', params })
}
// 编辑商家提现表
export function apiStoreUserReflectEdit(params: any) {
return request.post({ url: '/store_user_reflect/edit', params })
}
// 删除商家提现表
export function apiStoreUserReflectDelete(params: any) {
return request.post({ url: '/store_user_reflect/delete', params })
}
// 商家提现表详情
export function apiStoreUserReflectDetail(params: any) {
return request.get({ url: '/store_user_reflect/detail', params })
}

View File

@ -0,0 +1,26 @@
import request from '@/utils/request'
// 茶艺师提现表列表
export function apiTeamasterUserReflectLists(params: any) {
return request.get({ url: '/teamaster_user_reflect/lists', params })
}
// 添加茶艺师提现表
export function apiTeamasterUserReflectAdd(params: any) {
return request.post({ url: '/teamaster_user_reflect/add', params })
}
// 编辑茶艺师提现表
export function apiTeamasterUserReflectEdit(params: any) {
return request.post({ url: '/teamaster_user_reflect/edit', params })
}
// 删除茶艺师提现表
export function apiTeamasterUserReflectDelete(params: any) {
return request.post({ url: '/teamaster_user_reflect/delete', params })
}
// 茶艺师提现表详情
export function apiTeamasterUserReflectDetail(params: any) {
return request.get({ url: '/teamaster_user_reflect/detail', params })
}

26
src/api/training.ts Normal file
View File

@ -0,0 +1,26 @@
import request from '@/utils/request'
// 培训表列表
export function apiTrainingLists(params: any) {
return request.get({ url: '/training/lists', params })
}
// 添加培训表
export function apiTrainingAdd(params: any) {
return request.post({ url: '/training/add', params })
}
// 编辑培训表
export function apiTrainingEdit(params: any) {
return request.post({ url: '/training/edit', params })
}
// 删除培训表
export function apiTrainingDelete(params: any) {
return request.post({ url: '/training/delete', params })
}
// 培训表详情
export function apiTrainingDetail(params: any) {
return request.get({ url: '/training/detail', params })
}

26
src/api/user_member.ts Normal file
View File

@ -0,0 +1,26 @@
import request from '@/utils/request'
// 会员表列表
export function apiUserMemberLists(params: any) {
return request.get({ url: '/user_member/lists', params })
}
// 添加会员表
export function apiUserMemberAdd(params: any) {
return request.post({ url: '/user_member/add', params })
}
// 编辑会员表
export function apiUserMemberEdit(params: any) {
return request.post({ url: '/user_member/edit', params })
}
// 删除会员表
export function apiUserMemberDelete(params: any) {
return request.post({ url: '/user_member/delete', params })
}
// 会员表详情
export function apiUserMemberDetail(params: any) {
return request.get({ url: '/user_member/detail', params })
}

View File

@ -14,12 +14,8 @@
<div class="text-tx-regular">账户余额</div>
<div class="mt-2 flex items-center">
¥{{ formData.user_money }}
<el-button
v-perms="['user.user/adjustMoney']"
type="primary"
link
@click="handleAdjust(formData.user_money)"
>
<el-button v-perms="['user.user/adjustMoney']" type="primary" link
@click="handleAdjust(formData.user_money)">
调整
</el-button>
</div>
@ -30,12 +26,8 @@
</el-form-item>
<el-form-item label="账号:">
{{ formData.account }}
<popover-input
class="ml-[10px]"
@confirm="handleEdit($event, 'account')"
:limit="32"
v-perms="['user.user/edit']"
>
<popover-input class="ml-[10px]" @confirm="handleEdit($event, 'account')" :limit="32"
v-perms="['user.user/edit']">
<el-button type="primary" link>
<icon name="el-icon-EditPen" />
</el-button>
@ -43,12 +35,8 @@
</el-form-item>
<el-form-item label="真实姓名:">
{{ formData.real_name || '-' }}
<popover-input
class="ml-[10px]"
@confirm="handleEdit($event, 'real_name')"
:limit="32"
v-perms="['user.user/edit']"
>
<popover-input class="ml-[10px]" @confirm="handleEdit($event, 'real_name')" :limit="32"
v-perms="['user.user/edit']">
<el-button type="primary" link>
<icon name="el-icon-EditPen" />
</el-button>
@ -56,26 +44,20 @@
</el-form-item>
<el-form-item label="性别:">
{{ formData.sex }}
<popover-input
class="ml-[10px]"
type="select"
:options="[
{
label: '未知',
value: 0
},
{
label: '男',
value: 1
},
{
label: '女',
value: 2
}
]"
@confirm="handleEdit($event, 'sex')"
v-perms="['user.user/edit']"
>
<popover-input class="ml-[10px]" type="select" :options="[
{
label: '未知',
value: 0
},
{
label: '男',
value: 1
},
{
label: '女',
value: 2
}
]" @confirm="handleEdit($event, 'sex')" v-perms="['user.user/edit']">
<el-button type="primary" link>
<icon name="el-icon-EditPen" />
</el-button>
@ -83,12 +65,8 @@
</el-form-item>
<el-form-item label="联系电话:">
{{ formData.mobile || '-' }}
<popover-input
class="ml-[10px]"
type="number"
@confirm="handleEdit($event, 'mobile')"
v-perms="['user.user/edit']"
>
<popover-input class="ml-[10px]" type="number" @confirm="handleEdit($event, 'mobile')"
v-perms="['user.user/edit']">
<el-button type="primary" link>
<icon name="el-icon-EditPen" />
</el-button>
@ -100,11 +78,7 @@
</el-form>
</el-card>
<account-adjust
v-model:show="adjustState.show"
:value="adjustState.value"
@confirm="handleConfirmAdjust"
/>
<account-adjust v-model:show="adjustState.show" :value="adjustState.value" @confirm="handleConfirmAdjust" />
</div>
</template>

View File

@ -3,38 +3,23 @@
<el-card class="!border-none" shadow="never">
<el-form ref="formRef" class="mb-[-16px]" :model="queryParams" :inline="true">
<el-form-item class="w-[280px]" label="用户信息">
<el-input
v-model="queryParams.keyword"
placeholder="账号/昵称/手机号码"
clearable
@keyup.enter="resetPage"
/>
<el-input v-model="queryParams.keyword" placeholder="账号/昵称/手机号码" clearable
@keyup.enter="resetPage" />
</el-form-item>
<el-form-item label="注册时间">
<daterange-picker
v-model:startTime="queryParams.create_time_start"
v-model:endTime="queryParams.create_time_end"
/>
<daterange-picker v-model:startTime="queryParams.create_time_start"
v-model:endTime="queryParams.create_time_end" />
</el-form-item>
<el-form-item class="w-[280px]" label="注册来源">
<el-select v-model="queryParams.channel">
<el-option
v-for="(item, key) in ClientMap"
:key="key"
:label="item"
:value="key"
/>
<el-option v-for="(item, key) in ClientMap" :key="key" :label="item" :value="key" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="resetPage">查询</el-button>
<el-button @click="resetParams">重置</el-button>
<export-data
class="ml-2.5"
:fetch-fun="getUserList"
:params="queryParams"
:page-size="pager.size"
/>
<export-data class="ml-2.5" :fetch-fun="getUserList" :params="queryParams"
:page-size="pager.size" />
</el-form-item>
</el-form>
</el-card>
@ -46,21 +31,18 @@
</template>
</el-table-column>
<el-table-column label="昵称" prop="nickname" min-width="100" />
<el-table-column label="账号" prop="account" min-width="120" />
<el-table-column label="手机号码" prop="mobile" min-width="100" />
<el-table-column label="注册来源" prop="channel" min-width="100" />
<el-table-column label="注册时间" prop="create_time" min-width="120" />
<el-table-column label="操作" width="120" fixed="right">
<template #default="{ row }">
<el-button v-perms="['user.user/detail']" type="primary" link>
<router-link
:to="{
path: getRoutePath('user.user/detail'),
query: {
id: row.id
}
}"
>
<router-link :to="{
path: getRoutePath('user.user/detail'),
query: {
id: row.id
}
}">
详情
</router-link>
</el-button>

View File

@ -0,0 +1,130 @@
<template>
<div class="edit-popup">
<popup ref="popupRef" :title="popupTitle" :async="true" width="550px" @confirm="handleSubmit"
@close="handleClose">
<el-form ref="formRef" :model="formData" label-width="90px" :rules="formRules">
<el-form-item label="分类" prop="type_id">
<el-select class="flex-1" v-model="formData.type_id" clearable placeholder="请选择">
<el-option v-for="(item, index) in dictData.type_id" :key="index" :label="item.name"
:value="parseInt(item.value)" />
</el-select>
</el-form-item>
<el-form-item label="标题" prop="title">
<el-input v-model="formData.title" clearable placeholder="请输入标题" />
</el-form-item>
<el-form-item label="创建人" prop="admin_name">
<el-input v-model="formData.admin_name" clearable placeholder="请输入创建人" />
</el-form-item>
<el-form-item label="封面图" prop="image">
<material-picker v-model="formData.image" :limit="1" />
</el-form-item>
<el-form-item label="详情" prop="content">
<editor class="flex-1" v-model="formData.content" :height="500" />
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select class="flex-1" v-model="formData.status" clearable placeholder="请选择">
<el-option label="禁用" :value="0" />
<el-option label="启用" :value="1" />
</el-select>
</el-form-item>
</el-form>
</popup>
</div>
</template>
<script lang="ts" setup name="trainingEdit">
import type { FormInstance } from 'element-plus'
import Popup from '@/components/popup/index.vue'
import { apiTrainingAdd, apiTrainingEdit, apiTrainingDetail } from '@/api/training'
import { removeImageUrlPrefix } from '@/utils/util'
import type { PropType } from 'vue'
defineProps({
dictData: {
type: Object as PropType<Record<string, any[]>>,
default: () => ({})
}
})
const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const mode = ref('add')
// 弹窗标题
const popupTitle = computed(() => {
return mode.value == 'edit' ? '编辑培训表' : '新增培训表'
})
// 表单数据
const formData = reactive({
id: '',
type_id: '',
title: '',
admin_name: '',
image: '',
video: '',
content: '',
status: '',
dtime: '',
})
// 表单验证
const formRules = reactive<any>({
})
// 获取详情
const setFormData = async (data: Record<any, any>) => {
for (const key in formData) {
if (data[key] != null && data[key] != undefined) {
//@ts-ignore
formData[key] = data[key]
}
}
}
const getDetail = async (row: Record<string, any>) => {
const data = await apiTrainingDetail({
id: row.id
})
setFormData(data)
}
// 提交按钮
const handleSubmit = async () => {
await formRef.value?.validate()
let data = { ...formData, }
data.image = removeImageUrlPrefix(data.image)
mode.value == 'edit'
? await apiTrainingEdit(data)
: await apiTrainingAdd(data)
popupRef.value?.close()
emit('success')
}
//打开弹窗
const open = (type = 'add') => {
mode.value = type
popupRef.value?.open()
}
// 关闭回调
const handleClose = () => {
emit('close')
}
defineExpose({
open,
setFormData,
getDetail
})
</script>

View File

@ -0,0 +1,155 @@
<template>
<div>
<el-card class="!border-none mb-4" shadow="never">
<el-form class="mb-[-16px]" :model="queryParams" inline>
<!-- <el-form-item label="1茶艺师 2茶室" prop="type_id">
<el-select class="w-[280px]" v-model="queryParams.type_id" clearable placeholder="请选择1茶艺师 2茶室">
<el-option label="全部" value=""></el-option>
<el-option
v-for="(item, index) in dictData.type_id"
:key="index"
:label="item.name"
:value="item.value"
/>
</el-select>
</el-form-item> -->
<el-form-item label="标题" prop="title">
<el-input class="w-[280px]" v-model="queryParams.title" clearable placeholder="请输入标题" />
</el-form-item>
<el-form-item label="总部账号昵称" prop="admin_name">
<el-input class="w-[280px]" v-model="queryParams.admin_name" clearable placeholder="请输入总部账号昵称" />
</el-form-item>
<el-form-item label="详情" prop="content">
<el-input class="w-[280px]" v-model="queryParams.content" clearable placeholder="请输入详情" />
</el-form-item>
<!-- <el-form-item label="0禁用 1启用" prop="status">
<el-select class="w-[280px]" v-model="queryParams.status" clearable placeholder="请选择0禁用 1启用">
<el-option label="全部" value=""></el-option>
<el-option
v-for="(item, index) in dictData."
:key="index"
:label="item.name"
:value="item.value"
/>
</el-select>
</el-form-item> -->
<el-form-item>
<el-button type="primary" @click="resetPage">查询</el-button>
<el-button @click="resetParams">重置</el-button>
</el-form-item>
</el-form>
</el-card>
<el-card class="!border-none" v-loading="pager.loading" shadow="never">
<el-button v-perms="['training/add']" type="primary" @click="handleAdd">
<template #icon>
<icon name="el-icon-Plus" />
</template>
新增
</el-button>
<el-button v-perms="['training/delete']" :disabled="!selectData.length" @click="handleDelete(selectData)">
删除
</el-button>
<div class="mt-4">
<el-table :data="pager.lists" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" />
<el-table-column label="分类" prop="type_id">
<template #default="{ row }">
<dict-value :options="dictData.type_id" :value="row.type_id" />
</template>
</el-table-column>
<el-table-column label="标题" prop="title" show-overflow-tooltip />
<el-table-column label="总部账号昵称" prop="admin_name" show-overflow-tooltip />
<el-table-column label="封面图" prop="image" show-overflow-tooltip>
<template #default="{ row }">
<div><el-image style="width:50px;height:50px;" :src="row.image" /></div>
</template>
</el-table-column>
<el-table-column label="状态" prop="status">
<template #default="{ row }">
<span>{{ row.status == 0 ? '禁用' : '启用' }}</span>
</template>
</el-table-column>
<el-table-column label="创建时间" prop="dtime" show-overflow-tooltip />
<el-table-column label="操作" width="120" fixed="right">
<template #default="{ row }">
<el-button v-perms="['training/edit']" type="primary" link @click="handleEdit(row)">
编辑
</el-button>
<el-button v-perms="['training/delete']" type="danger" link @click="handleDelete(row.id)">
删除
</el-button>
</template>
</el-table-column>
</el-table>
</div>
<div class="flex mt-4 justify-end">
<pagination v-model="pager" @change="getLists" />
</div>
</el-card>
<edit-popup v-if="showEdit" ref="editRef" :dict-data="dictData" @success="getLists" @close="showEdit = false" />
</div>
</template>
<script lang="ts" setup name="trainingLists">
import { usePaging } from '@/hooks/usePaging'
import { useDictData } from '@/hooks/useDictOptions'
import { apiTrainingLists, apiTrainingDelete } from '@/api/training'
import { timeFormat } from '@/utils/util'
import feedback from '@/utils/feedback'
import EditPopup from './edit.vue'
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
// 是否显示编辑框
const showEdit = ref(false)
// 查询条件
const queryParams = reactive({
type_id: '',
title: '',
admin_name: '',
content: '',
status: ''
})
// 选中数据
const selectData = ref<any[]>([])
// 表格选择后回调事件
const handleSelectionChange = (val: any[]) => {
selectData.value = val.map(({ id }) => id)
}
// 获取字典数据
const { dictData } = useDictData('type_id')
// 分页相关
const { pager, getLists, resetParams, resetPage } = usePaging({
fetchFun: apiTrainingLists,
params: queryParams
})
// 添加
const handleAdd = async () => {
showEdit.value = true
await nextTick()
editRef.value?.open('add')
}
// 编辑
const handleEdit = async (data: any) => {
showEdit.value = true
await nextTick()
editRef.value?.open('edit')
editRef.value?.setFormData(data)
}
// 删除
const handleDelete = async (id: number | any[]) => {
await feedback.confirm('确定要删除?')
await apiTrainingDelete({ id })
getLists()
}
getLists()
</script>

View File

@ -1,37 +1,23 @@
<template>
<div>
<el-card class="!border-none" shadow="never">
<el-alert
type="warning"
title="温馨提示:用户账户变动记录"
:closable="false"
show-icon
></el-alert>
<el-alert type="warning" title="温馨提示:用户账户变动记录" :closable="false" show-icon></el-alert>
<el-form ref="formRef" class="mb-[-16px] mt-[16px]" :model="queryParams" :inline="true">
<el-form-item class="w-[280px]" label="用户信息">
<el-input
v-model="queryParams.user_info"
placeholder="请输入用户账号/昵称/手机号"
clearable
@keyup.enter="resetPage"
/>
<el-input v-model="queryParams.user_info" placeholder="请输入用户账号/昵称/手机号" clearable
@keyup.enter="resetPage" />
</el-form-item>
<el-form-item class="w-[280px]" label="变动类型">
<el-select v-model="queryParams.change_type">
<el-option label="全部" value />
<el-option
v-for="(value, key) in optionsData.change_type"
:key="key"
:label="value"
:value="key"
/>
<el-option v-for="key in Object.keys({ ...optionsData.change_type, ...changeTypeMap })"
:key="key" :label="changeTypeMap[key] ?? optionsData.change_type?.[key] ?? key"
:value="key" />
</el-select>
</el-form-item>
<el-form-item label="记录时间">
<daterange-picker
v-model:startTime="queryParams.start_time"
v-model:endTime="queryParams.end_time"
/>
<daterange-picker v-model:startTime="queryParams.start_time"
v-model:endTime="queryParams.end_time" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="resetPage">查询</el-button>
@ -45,28 +31,28 @@
<el-table-column label="用户昵称" min-width="160">
<template #default="{ row }">
<div class="flex items-center">
<image-contain
class="flex-none mr-2"
:src="row.avatar"
:width="40"
:height="40"
preview-teleported
fit="contain"
/>
<image-contain class="flex-none mr-2" :src="row.avatar" :width="40" :height="40"
preview-teleported fit="contain" />
{{ row.nickname }}
</div>
</template>
</el-table-column>
<el-table-column label="手机号码" prop="mobile" min-width="100" />
<el-table-column label="变动金额" prop="change_amount" min-width="100">
<el-table-column label="变动金额" prop="amount" min-width="100">
<template #default="{ row }">
<span :class="{ 'text-error': row.action == 2 }">
{{ row.change_amount }}
{{ row.amount }}
</span>
</template>
</el-table-column>
<el-table-column label="剩余金额" prop="left_amount" min-width="100" />
<el-table-column label="变动类型" prop="change_type_desc" min-width="120" />
<el-table-column label="变动前金额" prop="before_amount" min-width="100" />
<el-table-column label="剩余金额" prop="after_amount" min-width="100" />
<el-table-column label="变动类型" prop="change_type" min-width="120">
<template #default="{ row }">
{{ changeTypeMap[row.change_type] ?? optionsData.change_type?.[row.change_type] ??
row.change_type }}
</template>
</el-table-column>
<el-table-column label="来源单号" prop="source_sn" min-width="100" />
<el-table-column label="记录时间" prop="create_time" min-width="120" />
@ -82,6 +68,21 @@ import { accountLog, getUmChangeType } from '@/api/finance'
import { useDictOptions } from '@/hooks/useDictOptions'
import { usePaging } from '@/hooks/usePaging'
const changeTypeMap: Record<string, string> = {
0: '预定茶艺师',
1: '茶室支付',
2: '购买套餐',
3: '购买会员',
4: '充值',
5: '团购退款',
6: '包间退款',
7: '续费',
8: '门店取消平台余额订单退款',
9: '门店取消平台余额退款',
10: '门店取消微信退款',
20: '门店充值',
}
const queryParams = reactive({
user_info: '',
change_type: '',

View File

@ -1,28 +1,14 @@
<template>
<div>
<el-card class="!border-none" shadow="never">
<el-alert
type="warning"
title="温馨提示:用户充值记录"
:closable="false"
show-icon
></el-alert>
<el-alert type="warning" title="温馨提示:用户充值记录" :closable="false" show-icon></el-alert>
<el-form ref="formRef" class="mb-[-16px] mt-[16px]" :model="queryParams" :inline="true">
<el-form-item class="w-[280px]" label="充值单号">
<el-input
v-model="queryParams.sn"
placeholder="请输入充值单号"
clearable
@keyup.enter="resetPage"
/>
<el-input v-model="queryParams.sn" placeholder="请输入充值单号" clearable @keyup.enter="resetPage" />
</el-form-item>
<el-form-item class="w-[280px]" label="用户信息">
<el-input
v-model="queryParams.user_info"
placeholder="请输入用户账号/昵称/手机号"
clearable
@keyup.enter="resetPage"
/>
<el-input v-model="queryParams.user_info" placeholder="请输入用户账号/昵称/手机号" clearable
@keyup.enter="resetPage" />
</el-form-item>
<el-form-item class="w-[280px]" label="支付方式">
<el-select v-model="queryParams.pay_way">
@ -38,20 +24,14 @@
</el-select>
</el-form-item>
<el-form-item label="下单时间">
<daterange-picker
v-model:startTime="queryParams.start_time"
v-model:endTime="queryParams.end_time"
/>
<daterange-picker v-model:startTime="queryParams.start_time"
v-model:endTime="queryParams.end_time" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="resetPage">查询</el-button>
<el-button @click="resetParams">重置</el-button>
<export-data
class="ml-2.5"
:fetch-fun="rechargeLists"
:params="queryParams"
:page-size="pager.size"
/>
<export-data class="ml-2.5" :fetch-fun="rechargeLists" :params="queryParams"
:page-size="pager.size" />
</el-form-item>
</el-form>
</el-card>
@ -60,29 +40,21 @@
<el-table-column label="用户信息" min-width="160">
<template #default="{ row }">
<div class="flex items-center">
<image-contain
class="flex-none mr-2"
:src="row.avatar"
:width="40"
:height="40"
preview-teleported
fit="contain"
/>
<image-contain class="flex-none mr-2" :src="row.avatar" :width="40" :height="40"
preview-teleported fit="contain" />
{{ row.nickname }}
</div>
</template>
</el-table-column>
<el-table-column label="充值单号" prop="sn" min-width="190" />
<el-table-column label="充值单号" prop="order_sn" min-width="190" />
<el-table-column label="充值金额" prop="order_amount" min-width="100">
</el-table-column>
<el-table-column label="支付方式" prop="pay_way_text" min-width="100" />
<el-table-column label="支付状态" prop="" min-width="100">
<template #default="{ row }">
<span
:class="{
'text-error': row.pay_status == 0
}"
>
<span :class="{
'text-error': row.pay_status == 0
}">
{{ row.pay_status_text }}
</span>
</template>
@ -91,14 +63,8 @@
<el-table-column label="支付时间" prop="pay_time" min-width="180" />
<el-table-column label="操作" width="120" fixed="right">
<template #default="{ row }">
<el-button
v-if="row.pay_status == 1"
v-perms="['recharge.recharge/refund']"
type="primary"
link
:disabled="row.refund_status == 1"
@click="handleRefund(row.id)"
>
<el-button v-if="row.pay_status == 1" v-perms="['recharge.recharge/refund']" type="primary" link
:disabled="row.refund_status == 1" @click="handleRefund(row.id)">
退款
</el-button>
</template>

View File

@ -23,28 +23,14 @@
<el-card class="!border-none" shadow="never">
<el-form ref="formRef" class="mb-[-16px] mt-[16px]" :model="queryParams" :inline="true">
<el-form-item class="w-[280px]" label="退款单号">
<el-input
v-model="queryParams.sn"
placeholder="请输入退款单号"
clearable
@keyup.enter="resetPage"
/>
<el-input v-model="queryParams.sn" placeholder="请输入退款单号" clearable @keyup.enter="resetPage" />
</el-form-item>
<el-form-item class="w-[280px]" label="来源单号">
<el-input
v-model="queryParams.order_sn"
placeholder="请输入来源单号"
clearable
@keyup.enter="resetPage"
/>
<el-input v-model="queryParams.order_sn" placeholder="请输入来源单号" clearable @keyup.enter="resetPage" />
</el-form-item>
<el-form-item class="w-[280px]" label="用户信息">
<el-input
v-model="queryParams.user_info"
placeholder="请输入用户信息"
clearable
@keyup.enter="resetPage"
/>
<el-input v-model="queryParams.user_info" placeholder="请输入用户信息" clearable
@keyup.enter="resetPage" />
</el-form-item>
<el-form-item class="w-[280px]" label="退款类型">
<el-select v-model="queryParams.refund_type">
@ -53,10 +39,8 @@
</el-select>
</el-form-item>
<el-form-item label="记录时间">
<daterange-picker
v-model:startTime="queryParams.start_time"
v-model:endTime="queryParams.end_time"
/>
<daterange-picker v-model:startTime="queryParams.start_time"
v-model:endTime="queryParams.end_time" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="resetPage">查询</el-button>
@ -72,25 +56,14 @@
</el-card>
<el-card class="!border-none mt-4" shadow="never">
<el-tabs v-model="activeTab" @tab-change="handleTabChange">
<el-tab-pane
v-for="(item, index) in tabLists"
:label="`${item.name}(${pager.extend[item.numKey] ?? 0})`"
:name="index"
:key="index"
>
<el-tab-pane v-for="(item, index) in tabLists"
:label="`${item.name}(${pager.extend[item.numKey] ?? 0})`" :name="index" :key="index">
<el-table size="large" v-loading="pager.loading" :data="pager.lists">
<el-table-column label="退款单号" prop="sn" min-width="190" />
<el-table-column label="用户信息" min-width="160">
<template #default="{ row }">
<div class="flex items-center">
<image-contain
class="flex-none mr-2"
:src="row.avatar"
:width="40"
:height="40"
preview-teleported
fit="contain"
/>
<image-contain class="flex-none mr-2" :src="row.avatar" :width="40" :height="40"
preview-teleported fit="contain" />
{{ row.nickname }}
</div>
</template>
@ -117,21 +90,12 @@
<el-table-column label="记录时间" prop="create_time" min-width="180" />
<el-table-column label="操作" width="180" fixed="right">
<template #default="{ row }">
<el-button
v-perms="['finance.refund/log']"
type="primary"
link
@click="handleShowRefundLog(row.id)"
>
<el-button v-perms="['finance.refund/log']" type="primary" link
@click="handleShowRefundLog(row.id)">
退款日志
</el-button>
<el-button
v-if="row.refund_status == 2"
v-perms="['recharge.recharge/refundAgain']"
type="primary"
link
@click="handleRefund(row.id)"
>
<el-button v-if="row.refund_status == 2" v-perms="['recharge.recharge/refundAgain']"
type="primary" link @click="handleRefund(row.id)">
重新退款
</el-button>
</template>

View File

@ -0,0 +1,284 @@
<template>
<div class="edit-popup">
<popup ref="popupRef" :title="popupTitle" :async="true" width="550px" @confirm="handleSubmit"
@close="handleClose">
<el-form ref="formRef" :model="formData" label-width="90px" :rules="formRules">
<el-form-item label="订单编号" prop="order_sn">
<el-input v-model="formData.order_sn" clearable disabled />
</el-form-item>
<el-form-item label="预约茶室" prop="store_name">
<el-input v-model="formData.store_name" clearable disabled />
</el-form-item>
<el-form-item label="预约包间" prop="room_name">
<el-input v-model="formData.room_name" clearable disabled />
</el-form-item>
<el-form-item label="用户名称" prop="nickname">
<el-input v-model="formData.nickname" clearable disabled />
</el-form-item>
<el-form-item label="用户手机号" prop="mobile">
<el-input v-model="formData.mobile" clearable disabled />
</el-form-item>
<el-form-item label="预约日期" prop="day_title">
<el-input v-model="formData.day_title" clearable disabled />
</el-form-item>
<el-form-item label="预约时间" prop="day_time">
<el-input v-model="formData.day_time" clearable disabled />
</el-form-item>
<el-form-item label="开始时间" prop="start_time">
<el-input v-model="formData.start_time" clearable disabled />
</el-form-item>
<el-form-item label="结束时间" prop="end_time">
<el-input v-model="formData.end_time" clearable disabled />
</el-form-item>
<el-form-item label="小时数" prop="hours">
<el-input v-model="formData.hours" clearable disabled />
</el-form-item>
<el-form-item label="预约时间段" prop="timeslot">
<el-input type="textarea" v-model="formData.timeslot" disabled></el-input>
</el-form-item>
<el-form-item label="包间单价" prop="room_price">
<el-input v-model="formData.room_price" clearable disabled />
</el-form-item>
<el-form-item label="包间总价" prop="room_all_price">
<el-input v-model="formData.room_all_price" clearable disabled />
</el-form-item>
<el-form-item label="优惠券价格" prop="coupon_price">
<el-input v-model="formData.coupon_price" clearable disabled />
</el-form-item>
<el-form-item label="团购优惠价" prop="group_price">
<el-input v-model="formData.group_price" clearable disabled />
</el-form-item>
<el-form-item label="会员优惠价" prop="member_price">
<el-input v-model="formData.member_price" clearable disabled />
</el-form-item>
<el-form-item label="实付价格" prop="order_amount">
<el-input v-model="formData.order_amount" clearable disabled />
</el-form-item>
<el-form-item label="是否使用会员优惠价" prop="is_member_price" disabled>
<el-select class="flex-1" v-model="formData.is_member_price" clearable disabled>
<el-option label="否" :value="0" />
<el-option label="是" :value="1" />
</el-select>
</el-form-item>
<el-form-item label="平台服务费" prop="service_price">
<el-input v-model="formData.service_price" clearable disabled />
</el-form-item>
<el-form-item label="平台收入" prop="store_income_price">
<el-input v-model="formData.store_income_price" clearable disabled />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="formData.remark" clearable disabled />
</el-form-item>
<el-form-item label="是否释放" prop="is_release">
<el-select class="flex-1" v-model="formData.is_release" clearable disabled>
<el-option label="否" :value="0" />
<el-option label="是" :value="1" />
</el-select>
</el-form-item>
<el-form-item label="是否续单" prop="is_renewal">
<el-select class="flex-1" v-model="formData.is_renewal" clearable disabled>
<el-option label="否" :value="0" />
<el-option label="是" :value="1" />
</el-select>
</el-form-item>
<el-form-item label="是否为转让订单" prop="is_transfer">
<el-select class="flex-1" v-model="formData.is_transfer" clearable disabled>
<el-option label="否" :value="0" />
<el-option label="是" :value="1" />
</el-select>
</el-form-item>
<el-form-item label="续订时间" prop="renew_dtime">
<el-input v-model="formData.renew_dtime" clearable disabled />
</el-form-item>
<el-form-item label="续订小时" prop="renew_hour">
<el-input v-model="formData.renew_hour" clearable disabled />
</el-form-item>
<el-form-item label="续费金额" prop="renew_price">
<el-input v-model="formData.renew_price" clearable disabled />
</el-form-item>
<el-form-item label="支付方式" prop="pay_way">
<el-select class="flex-1" v-model="formData.pay_way" clearable disabled>
<el-option label="——" :value="0" />
<el-option label="余额支付" :value="1" />
<el-option label="微信支付" :value="2" />
<el-option label="门店支付" :value="3" />
<el-option label="管理员添加" :value="4" />
</el-select>
</el-form-item>
<el-form-item label="管理者预定" prop="store_user_order">
<el-select class="flex-1" v-model="formData.store_user_order" clearable disabled>
<el-option label="否" :value="0" />
<el-option label="是" :value="1" />
</el-select>
</el-form-item>
<el-form-item label="订单状态" prop="order_status">
<el-select class="flex-1" v-model="formData.order_status" clearable disabled>
<el-option label="未支付" :value="0" />
<el-option label="预约单" :value="1" />
<el-option label="消费中" :value="2" />
<el-option label="已完结" :value="3" />
<el-option label="已取消" :value="4" />
<el-option label="已退款" :value="5" />
</el-select>
</el-form-item>
<el-form-item label="支付状态" prop="pay_status">
<el-select class="flex-1" v-model="formData.pay_status" clearable disabled>
<el-option label="未支付" :value="0" />
<el-option label="已支付" :value="1" />
</el-select>
</el-form-item>
<el-form-item label="大门密码" prop="gate_key">
<el-input v-model="formData.gate_key" clearable disabled />
</el-form-item>
<el-form-item label="包间密码" prop="room_key">
<el-input v-model="formData.room_key" clearable disabled />
</el-form-item>
<el-form-item label="包间门锁id" prop="roomcardpwd_id">
<el-input v-model="formData.roomcardpwd_id" clearable disabled />
</el-form-item>
<el-form-item label="大门门锁Id" prop="storecardpwd_id">
<el-input v-model="formData.storecardpwd_id" clearable disabled />
</el-form-item>
<el-form-item label="是否已下发门锁" prop="is_lockpwd">
<el-select class="flex-1" v-model="formData.pay_status" clearable disabled>
<el-option label="否" :value="0" />
<el-option label="是" :value="1" />
</el-select>
</el-form-item>
</el-form>
</popup>
</div>
</template>
<script lang="ts" setup name="orderStoreEdit">
import type { FormInstance } from 'element-plus'
import Popup from '@/components/popup/index.vue'
import { apiOrderStoreAdd, apiOrderStoreEdit, apiOrderStoreDetail } from '@/api/order_store'
import { timeFormat } from '@/utils/util'
import type { PropType } from 'vue'
defineProps({
dictData: {
type: Object as PropType<Record<string, any[]>>,
default: () => ({})
}
})
const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const mode = ref('add')
// 弹窗标题
const popupTitle = computed(() => {
return mode.value = '订单详情'
})
// 表单数据
const formData = reactive({
id: '',
order_sn: '',
transaction_id: '',
store_id: '',
room_id: '',
user_id: '',
day_title: '',
day_time: '',
start_time: '',
end_time: '',
hours: '',
timeslot: '',
room_price: '',
room_all_price: '',
user_coupon_id: '',
coupon_price: '',
group_coupon_id: '',
group_price: '',
member_price: '',
order_amount: '',
is_member_price: '',
service_price: '',
store_income_price: '',
earnings_price: '',
remark: '',
is_release: '',
order_terminal: '',
is_renewal: '',
is_transfer: '',
transfer_order_id: '',
renew_dtime: '',
renew_hour: '',
renew_price: '',
pay_way: '',
store_user_order: '',
order_status: '',
pay_status: '',
gate_key: '',
room_key: '',
roomcardpwd_id: '',
storecardpwd_id: '',
is_lockpwd: '',
dtime: '',
update_dtime: '',
store_name: '',
room_name: '',
nickname: '',
mobile: '',
})
// 表单验证
const formRules = reactive<any>({
})
// 获取详情
const setFormData = async (data: Record<any, any>) => {
for (const key in formData) {
if (data[key] != null && data[key] != undefined) {
//@ts-ignore
formData[key] = data[key]
}
}
}
const getDetail = async (row: Record<string, any>) => {
const data = await apiOrderStoreDetail({
id: row.id
})
setFormData(data)
}
// 提交按钮
const handleSubmit = async () => {
await formRef.value?.validate()
const data = { ...formData, }
mode.value == 'edit'
? await apiOrderStoreEdit(data)
: await apiOrderStoreAdd(data)
popupRef.value?.close()
emit('success')
}
//打开弹窗
const open = (type = 'add') => {
mode.value = type
popupRef.value?.open()
}
// 关闭回调
const handleClose = () => {
emit('close')
}
defineExpose({
open,
setFormData,
getDetail
})
</script>

View File

@ -0,0 +1,218 @@
<template>
<div>
<el-card class="!border-none mb-4" shadow="never">
<el-form class="mb-[-16px]" :model="queryParams" inline>
<el-form-item label="订单编号" prop="order_sn">
<el-input class="w-[280px]" v-model="queryParams.order_sn" clearable placeholder="请输入订单编号" />
</el-form-item>
<el-form-item label="茶室名称" prop="store_id">
<el-input class="w-[280px]" v-model="queryParams.store_name" clearable placeholder="请输入茶室名称" />
</el-form-item>
<el-form-item label="包间名称" prop="room_id">
<el-input class="w-[280px]" v-model="queryParams.roome_name" clearable placeholder="请输入包间名称" />
</el-form-item>
<el-form-item label="用户昵称" prop="nickname">
<el-input class="w-[280px]" v-model="queryParams.nickname" clearable placeholder="请输入用户昵称" />
</el-form-item>
<el-form-item label="用户手机号" prop="mobile">
<el-input class="w-[280px]" v-model="queryParams.mobile" clearable placeholder="请输入用户手机号" />
</el-form-item>
<el-form-item label="下单时间" prop="dtime">
<daterange-picker v-model:startTime="queryParams.start_time"
v-model:endTime="queryParams.end_time" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="resetPage">查询</el-button>
<el-button @click="resetParams">重置</el-button>
</el-form-item>
</el-form>
</el-card>
<el-card class="!border-none" v-loading="pager.loading" shadow="never">
<div class="mt-4">
<el-table :data="pager.lists" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" />
<el-table-column label="订单编号" prop="order_sn" show-overflow-tooltip />
<!-- <el-table-column label="茶室id" prop="store_id">
<template #default="{ row }">
<dict-value :options="dictData." :value="row.store_id" />
</template>
</el-table-column>
<el-table-column label="包间id" prop="room_id">
<template #default="{ row }">
<dict-value :options="dictData." :value="row.room_id" />
</template>
</el-table-column> -->
<el-table-column label="用户信息" width="200">
<template #default="{ row }">
<div>用户名称: {{ row.nickname }}</div>
<div>手机号: {{ row.mobile }}</div>
<div><el-image style="width:50px;height:50px;" :src="row.avatar" /></div>
</template>
</el-table-column>
<el-table-column label="预定信息" width="300">
<template #default="{ row }">
<div>预定茶室: {{ row.store_name }}</div>
<div>预定包间: {{ row.room_name }}</div>
<div>预定日期: {{ row.day_time }}</div>
<div>预定小时数: {{ row.hours }}小时</div>
</template>
</el-table-column>
<el-table-column label="价格信息" width="200">
<template #default="{ row }">
<div>包间单价: {{ row.room_price }}</div>
<div>包间总价: {{ row.room_all_price }}</div>
<div>优惠券价格: {{ row.coupon_price }}</div>
<div>团购优惠价: {{ row.group_price }}</div>
<div>会员优惠价: {{ row.member_price }}</div>
</template>
</el-table-column>
<el-table-column label="是否使用会员优惠价" prop="is_member_price" show-overflow-tooltip>
<template #default="{ row }">
<span>{{ row.is_member_price == 1 ? '是' : '否' }}</span>
</template>
</el-table-column>
<el-table-column label="实付价格" prop="order_amount" show-overflow-tooltip />
<el-table-column label="平台服务费" prop="service_price" show-overflow-tooltip />
<el-table-column label="备注" prop="remark" show-overflow-tooltip />
<el-table-column label="是否释放" prop="is_release" show-overflow-tooltip>
<template #default="{ row }">
<span>{{ row.is_release == 1 ? '是' : '否' }}</span>
</template>
</el-table-column>
<!-- <el-table-column label="终端1小程序" prop="order_terminal" show-overflow-tooltip /> -->
<el-table-column label="是否续单" prop="is_renewal" show-overflow-tooltip>
<template #default="{ row }">
<span>{{ row.is_renewal == 1 ? '是' : '否' }}</span>
</template>
</el-table-column>
<el-table-column label="转让单" prop="is_transfer" show-overflow-tooltip>
<template #default="{ row }">
<span>{{ row.is_transfer == 1 ? '是' : '否' }}</span>
</template>
</el-table-column>
<el-table-column label="续订时间" prop="renew_dtime" show-overflow-tooltip />
<el-table-column label="续订小时" prop="renew_hour" show-overflow-tooltip />
<el-table-column label="续费金额" prop="renew_price" show-overflow-tooltip />
<el-table-column label="支付方式" prop="pay_way" show-overflow-tooltip>
<template #default="{ row }">
{{ payWayMap[row.pay_way] ?? row.pay_way }}
</template>
</el-table-column>
<el-table-column label="订单状态" prop="order_status" show-overflow-tooltip>
<template #default="{ row }">
{{ orderStatusMap[row.order_status] ?? row.order_status }}
</template>
</el-table-column>
<el-table-column label="支付状态" prop="pay_status" show-overflow-tooltip>
<template #default="{ row }">
<span>{{ row.is_lockpwd == 1 ? '已支付' : '未支付' }}</span>
</template>
</el-table-column>
<el-table-column label="是否已下发门锁" prop="is_lockpwd" show-overflow-tooltip>
<template #default="{ row }">
<span>{{ row.is_lockpwd == 1 ? '是' : '否' }}</span>
</template>
</el-table-column>
<el-table-column label="操作" width="120" fixed="right">
<template #default="{ row }">
<el-button v-perms="['order_store/edit']" type="primary" link @click="handleEdit(row)">
查看
</el-button>
</template>
</el-table-column>
</el-table>
</div>
<div class="flex mt-4 justify-end">
<pagination v-model="pager" @change="getLists" />
</div>
</el-card>
<edit-popup v-if="showEdit" ref="editRef" :dict-data="dictData" @success="getLists" @close="showEdit = false" />
</div>
</template>
<script lang="ts" setup name="orderStoreLists">
import { usePaging } from '@/hooks/usePaging'
import { useDictData } from '@/hooks/useDictOptions'
import { apiOrderStoreLists, apiOrderStoreDelete } from '@/api/order_store'
import { timeFormat } from '@/utils/util'
import feedback from '@/utils/feedback'
import EditPopup from './edit.vue'
import store from '@/stores'
const payWayMap: Record<string, string> = {
0: '——',
1: '余额支付',
2: '微信支付',
3: '门店支付',
4: '管理员添加',
}
const orderStatusMap: Record<string, string> = {
0: '未支付',
1: '预约单',
2: '消费中',
3: '已完结',
4: '已取消',
5: '已退款',
}
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
// 是否显示编辑框
const showEdit = ref(false)
// 查询条件
const queryParams = reactive({
order_sn: '',
transaction_id: '',
store_name: '',
roome_name: '',
nickname: '',
mobile: '',
dtime: '',
start_time: '',
end_time: ''
})
// 选中数据
const selectData = ref<any[]>([])
// 表格选择后回调事件
const handleSelectionChange = (val: any[]) => {
selectData.value = val.map(({ id }) => id)
}
// 获取字典数据
const { dictData } = useDictData('')
// 分页相关
const { pager, getLists, resetParams, resetPage } = usePaging({
fetchFun: apiOrderStoreLists,
params: queryParams
})
// 添加
const handleAdd = async () => {
showEdit.value = true
await nextTick()
editRef.value?.open('add')
}
// 编辑
const handleEdit = async (data: any) => {
showEdit.value = true
await nextTick()
editRef.value?.open('edit')
editRef.value?.setFormData(data)
}
// 删除
const handleDelete = async (id: number | any[]) => {
await feedback.confirm('确定要删除?')
await apiOrderStoreDelete({ id })
getLists()
}
getLists()
</script>

View File

@ -0,0 +1,127 @@
<template>
<div class="edit-popup">
<popup ref="popupRef" :title="popupTitle" :async="true" width="550px" @confirm="handleSubmit"
@close="handleClose">
<el-form ref="formRef" :model="formData" label-width="90px" :rules="formRules">
<el-form-item label="用户id" prop="user_id">
<el-input v-model="formData.user_id" clearable placeholder="请输入用户id" />
</el-form-item>
<el-form-item label="到期时间" prop="expiration_time">
<el-date-picker class="flex-1 !flex" v-model="formData.expiration_time" clearable type="datetime"
value-format="YYYY-MM-DD HH:mm:ss" placeholder="选择到期时间">
</el-date-picker>
</el-form-item>
<el-form-item label="创建时间" prop="dtime">
<el-date-picker class="flex-1 !flex" v-model="formData.dtime" clearable type="datetime"
value-format="YYYY-MM-DD HH:mm:ss" placeholder="选择创建时间">
</el-date-picker>
</el-form-item>
<!-- <el-form-item label="" prop="status">
<el-select class="flex-1" v-model="formData.status" clearable placeholder="请选择">
<el-option
v-for="(item, index) in dictData."
:key="index"
:label="item.name"
:value="parseInt(item.value)"
/>
</el-select>
</el-form-item> -->
</el-form>
</popup>
</div>
</template>
<script lang="ts" setup name="userMemberEdit">
import type { FormInstance } from 'element-plus'
import Popup from '@/components/popup/index.vue'
import { apiUserMemberAdd, apiUserMemberEdit, apiUserMemberDetail } from '@/api/user_member'
import { timeFormat } from '@/utils/util'
import type { PropType } from 'vue'
defineProps({
dictData: {
type: Object as PropType<Record<string, any[]>>,
default: () => ({})
}
})
const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const mode = ref('add')
// 弹窗标题
const popupTitle = computed(() => {
return mode.value == 'edit' ? '编辑会员表' : '新增会员表'
})
// 表单数据
const formData = reactive({
id: '',
user_id: '',
expiration_time: '',
dtime: '',
update_dtime: '',
status: '',
})
// 表单验证
const formRules = reactive<any>({
})
// 获取详情
const setFormData = async (data: Record<any, any>) => {
for (const key in formData) {
if (data[key] != null && data[key] != undefined) {
//@ts-ignore
formData[key] = data[key]
}
}
//@ts-ignore
formData.expiration_time = timeFormat(formData.expiration_time, 'yyyy-mm-dd hh:MM:ss')
//@ts-ignore
formData.dtime = timeFormat(formData.dtime, 'yyyy-mm-dd hh:MM:ss')
}
const getDetail = async (row: Record<string, any>) => {
const data = await apiUserMemberDetail({
id: row.id
})
setFormData(data)
}
// 提交按钮
const handleSubmit = async () => {
await formRef.value?.validate()
const data = { ...formData, }
mode.value == 'edit'
? await apiUserMemberEdit(data)
: await apiUserMemberAdd(data)
popupRef.value?.close()
emit('success')
}
//打开弹窗
const open = (type = 'add') => {
mode.value = type
popupRef.value?.open()
}
// 关闭回调
const handleClose = () => {
emit('close')
}
defineExpose({
open,
setFormData,
getDetail
})
</script>

View File

@ -0,0 +1,148 @@
<template>
<div>
<el-card class="!border-none mb-4" shadow="never">
<el-form class="mb-[-16px]" :model="queryParams" inline>
<el-form-item label="到期时间" prop="expiration_time">
<daterange-picker v-model:startTime="queryParams.start_time"
v-model:endTime="queryParams.end_time" />
</el-form-item>
<el-form-item label="创建时间" prop="dtime">
<daterange-picker v-model:startTime="queryParams.start_time"
v-model:endTime="queryParams.end_time" />
</el-form-item>
<!-- <el-form-item label="" prop="status">
<el-select class="w-[280px]" v-model="queryParams.status" clearable placeholder="请选择">
<el-option label="全部" value=""></el-option>
<el-option
v-for="(item, index) in dictData."
:key="index"
:label="item.name"
:value="item.value"
/>
</el-select>
</el-form-item> -->
<el-form-item>
<el-button type="primary" @click="resetPage">查询</el-button>
<el-button @click="resetParams">重置</el-button>
</el-form-item>
</el-form>
</el-card>
<el-card class="!border-none" v-loading="pager.loading" shadow="never">
<!-- <el-button v-perms="['user_member/add']" type="primary" @click="handleAdd">
<template #icon>
<icon name="el-icon-Plus" />
</template>
新增
</el-button> -->
<el-button v-perms="['user_member/delete']" :disabled="!selectData.length"
@click="handleDelete(selectData)">
删除
</el-button>
<div class="mt-4">
<el-table :data="pager.lists" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" />
<el-table-column label="用户id" prop="user_id" show-overflow-tooltip />
<el-table-column label="用户头像" prop="avatar" show-overflow-tooltip>
<template #default="{ row }">
<el-image style="width:50px;height:50px;" :src="row.avatar" />
</template>
</el-table-column>
<el-table-column label="用户昵称" prop="nickname" show-overflow-tooltip />
<el-table-column label="手机号码" prop="mobile" show-overflow-tooltip />
<el-table-column label="到期时间" prop="expiration_time">
<template #default="{ row }">
<span>{{ row.expiration_time ? timeFormat(row.expiration_time, 'yyyy-mm-dd hh:MM:ss') : ''
}}</span>
</template>
</el-table-column>
<el-table-column label="创建时间" prop="dtime">
<template #default="{ row }">
<span>{{ row.dtime ? timeFormat(row.dtime, 'yyyy-mm-dd hh:MM:ss') : '' }}</span>
</template>
</el-table-column>
<el-table-column label="操作" width="120" fixed="right">
<template #default="{ row }">
<!-- <el-button v-perms="['user_member/edit']" type="primary" link @click="handleEdit(row)">
编辑
</el-button> -->
<el-button v-perms="['user_member/delete']" type="danger" link
@click="handleDelete(row.id)">
删除
</el-button>
</template>
</el-table-column>
</el-table>
</div>
<div class="flex mt-4 justify-end">
<pagination v-model="pager" @change="getLists" />
</div>
</el-card>
<edit-popup v-if="showEdit" ref="editRef" :dict-data="dictData" @success="getLists" @close="showEdit = false" />
</div>
</template>
<script lang="ts" setup name="userMemberLists">
import { usePaging } from '@/hooks/usePaging'
import { useDictData } from '@/hooks/useDictOptions'
import { apiUserMemberLists, apiUserMemberDelete } from '@/api/user_member'
import { timeFormat } from '@/utils/util'
import feedback from '@/utils/feedback'
import EditPopup from './edit.vue'
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
// 是否显示编辑框
const showEdit = ref(false)
// 查询条件
const queryParams = reactive({
expiration_time: '',
dtime: '',
status: '',
start_time: '',
end_time: ''
})
// 选中数据
const selectData = ref<any[]>([])
// 表格选择后回调事件
const handleSelectionChange = (val: any[]) => {
selectData.value = val.map(({ id }) => id)
}
// 获取字典数据
const { dictData } = useDictData('')
// 分页相关
const { pager, getLists, resetParams, resetPage } = usePaging({
fetchFun: apiUserMemberLists,
params: queryParams
})
// 添加
const handleAdd = async () => {
showEdit.value = true
await nextTick()
editRef.value?.open('add')
}
// 编辑
const handleEdit = async (data: any) => {
showEdit.value = true
await nextTick()
editRef.value?.open('edit')
editRef.value?.setFormData(data)
}
// 删除
const handleDelete = async (id: number | any[]) => {
await feedback.confirm('确定要删除?')
await apiUserMemberDelete({ id })
getLists()
}
getLists()
</script>

View File

@ -1,11 +1,7 @@
<template>
<div>
<el-card class="!border-none mb-4" shadow="never">
<el-form
class="mb-[-16px]"
:model="queryParams"
inline
>
<el-form class="mb-[-16px]" :model="queryParams" inline>
<el-form-item label="订单编号" prop="order_sn">
<el-input class="w-[280px]" v-model="queryParams.order_sn" clearable placeholder="请输入订单编号" />
</el-form-item>
@ -15,65 +11,43 @@
<el-form-item label="茶艺师昵称" prop="nickname">
<el-input class="w-[280px]" v-model="queryParams.nickname" clearable placeholder="请输入茶艺师昵称" />
</el-form-item>
<el-form-item label="服务日期" prop="day_time">
<el-date-picker
class="w-[280px]"
v-model="queryParams.day_time"
type="date"
placeholder="请选择服务日期"
value-format="YYYY-MM-DD"
clearable
/>
<el-form-item class="w-[280px]" label="服务日期" prop="day_time">
<el-date-picker v-model="queryParams.day_time" type="date" placeholder="请选择服务日期"
value-format="YYYY-MM-DD" clearable />
</el-form-item>
<el-form-item label="服务方式" prop="server_type">
<el-select class="w-[280px]" v-model="queryParams.server_type" clearable placeholder="请选择服务方式">
<el-form-item class="w-[280px]" label="服务方式" prop="server_type">
<el-select v-model="queryParams.server_type" clearable placeholder="请选择服务方式">
<el-option label="全部" :value="3"></el-option>
<el-option label="到店服务" :value="1"></el-option>
<el-option label="上门服务" :value="2"></el-option>
</el-select>
</el-form-item>
<el-form-item label="是否使用茶具" prop="is_teacup">
<el-select class="w-[280px]" v-model="queryParams.is_teacup" clearable placeholder="请选择是否使用茶具">
<el-form-item class="w-[280px]" label="是否使用茶具" prop="is_teacup">
<el-select v-model="queryParams.is_teacup" clearable placeholder="请选择是否使用茶具">
<el-option label="全部" value=""></el-option>
<el-option
v-for="(item, index) in dictData.is_teacup"
:key="index"
:label="item.name"
:value="item.value"
/>
<el-option v-for="(item, index) in dictData.is_teacup" :key="index" :label="item.name"
:value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="支付方式" prop="pay_way">
<el-select class="w-[280px]" v-model="queryParams.pay_way" clearable placeholder="请选择支付方式">
<el-form-item class="w-[280px]" label="支付方式" prop="pay_way">
<el-select v-model="queryParams.pay_way" clearable placeholder="请选择支付方式">
<el-option label="全部" value=""></el-option>
<el-option
v-for="(item, index) in dictData.pay_way"
:key="index"
:label="item.name"
:value="item.value"
/>
<el-option v-for="(item, index) in dictData.pay_way" :key="index" :label="item.name"
:value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="订单状态" prop="order_status">
<el-select class="w-[280px]" v-model="queryParams.order_status" clearable placeholder="请选择订单状态">
<el-form-item class="w-[280px]" label="订单状态" prop="order_status">
<el-select v-model="queryParams.order_status" clearable placeholder="请选择订单状态">
<el-option label="全部" value=""></el-option>
<el-option
v-for="(item, index) in dictData.order_status"
:key="index"
:label="item.name"
:value="item.value"
/>
<el-option v-for="(item, index) in dictData.order_status" :key="index" :label="item.name"
:value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="支付状态" prop="pay_status">
<el-select class="w-[280px]" v-model="queryParams.pay_status" clearable placeholder="请选择支付状态">
<el-form-item class="w-[280px]" label="支付状态" prop="pay_status">
<el-select v-model="queryParams.pay_status" clearable placeholder="请选择支付状态">
<el-option label="全部" value=""></el-option>
<el-option
v-for="(item, index) in dictData.pay_status"
:key="index"
:label="item.name"
:value="item.value"
/>
<el-option v-for="(item, index) in dictData.pay_status" :key="index" :label="item.name"
:value="item.value" />
</el-select>
</el-form-item>
<el-form-item>
@ -87,15 +61,11 @@
<template #icon>
<icon name="el-icon-Plus" />
</template>
新增
</el-button>
<el-button
v-perms="['order_teamaster/delete']"
:disabled="!selectData.length"
@click="handleDelete(selectData)"
>
删除
</el-button> -->
新增
</el-button>
<el-button v-perms="['order_teamaster/delete']" :disabled="!selectData.length" @click="handleDelete(selectData)">
删除
</el-button> -->
<div class="mt-4">
<el-table :data="pager.lists" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" />
@ -155,13 +125,8 @@
<el-table-column label="打卡时间" prop="img_time" show-overflow-tooltip />
<el-table-column label="打卡照片" prop="img">
<template #default="{ row }">
<el-image
v-if="row.img"
style="width: 60px; height: 60px"
:src="row.img"
:preview-src-list="[row.img]"
fit="cover"
/>
<el-image v-if="row.img" style="width: 60px; height: 60px;" :src="row.img"
:preview-src-list="[row.img]" fit="cover" preview-teleported />
<span v-else class="text-gray-400">无图片</span>
</template>
</el-table-column>
@ -273,4 +238,3 @@ const getServerTypeLabel = (value: number | string) => {
getLists()
</script>

View File

@ -0,0 +1,138 @@
<template>
<div class="edit-popup">
<popup ref="popupRef" :title="popupTitle" :async="true" width="550px" @confirm="handleSubmit"
@close="handleClose">
<el-form ref="formRef" :model="formData" label-width="90px" :rules="formRules">
<el-form-item label="订单编号" prop="order_sn">
<el-input v-model="formData.order_sn" clearable disabled />
</el-form-item>
<el-form-item label="用户昵称" prop="nickname">
<el-input v-model="formData.nickname" clearable disabled />
</el-form-item>
<el-form-item label="联系方式" prop="mobile">
<el-input v-model="formData.mobile" clearable disabled />
</el-form-item>
<el-form-item label="银行卡" prop="bank_card">
<el-input v-model="formData.bank_card" clearable disabled />
</el-form-item>
<el-form-item label="开户行" prop="bank_name">
<el-input v-model="formData.bank_name" clearable disabled />
</el-form-item>
<el-form-item label="开户行-分行" prop="bank_open_name">
<el-input v-model="formData.bank_open_name" clearable disabled />
</el-form-item>
<el-form-item label="店铺名称" prop="name">
<el-input v-model="formData.name" clearable disabled />
</el-form-item>
<el-form-item label="提现金额" prop="amount">
<el-input v-model="formData.amount" clearable disabled />
</el-form-item>
<el-form-item label="提现状态" prop="status">
<el-select class="flex-1" v-model="formData.status" clearable placeholder="请选择">
<el-option label="待审核" :value="0"></el-option>
<el-option label="通过" :value="1"></el-option>
<el-option label="拒绝" :value="2"></el-option>
</el-select>
</el-form-item>
</el-form>
</popup>
</div>
</template>
<script lang="ts" setup name="storeUserReflectEdit">
import type { FormInstance } from 'element-plus'
import Popup from '@/components/popup/index.vue'
import { apiStoreUserReflectAdd, apiStoreUserReflectEdit, apiStoreUserReflectDetail } from '@/api/store_user_reflect'
import { timeFormat } from '@/utils/util'
import type { PropType } from 'vue'
defineProps({
dictData: {
type: Object as PropType<Record<string, any[]>>,
default: () => ({})
}
})
const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const mode = ref('add')
// 弹窗标题
const popupTitle = computed(() => {
return mode.value == '提现审核'
})
// 表单数据
const formData = reactive({
id: '',
order_sn: '',
user_id: '',
bank_id: '',
store_id: '',
amount: '',
status: '',
nickname: '',
mobile: '',
bank_card: '',
bank_name: '',
bank_open_name: '',
name: ''
})
// 表单验证
const formRules = reactive<any>({
})
// 获取详情
const setFormData = async (data: Record<any, any>) => {
for (const key in formData) {
if (data[key] != null && data[key] != undefined) {
//@ts-ignore
formData[key] = data[key]
}
}
}
const getDetail = async (row: Record<string, any>) => {
const data = await apiStoreUserReflectDetail({
id: row.id
})
setFormData(data)
}
// 提交按钮
const handleSubmit = async () => {
await formRef.value?.validate()
const data = { ...formData, }
mode.value == 'edit'
? await apiStoreUserReflectEdit(data)
: await apiStoreUserReflectAdd(data)
popupRef.value?.close()
emit('success')
}
//打开弹窗
const open = (type = 'add') => {
mode.value = type
popupRef.value?.open()
}
// 关闭回调
const handleClose = () => {
emit('close')
}
defineExpose({
open,
setFormData,
getDetail
})
</script>

View File

@ -0,0 +1,136 @@
<template>
<div>
<el-card class="!border-none mb-4" shadow="never">
<el-form class="mb-[-16px]" :model="queryParams" inline>
<el-form-item label="订单编号" prop="order_sn">
<el-input class="w-[280px]" v-model="queryParams.order_sn" clearable placeholder="请输入订单编号" />
</el-form-item>
<el-form-item class="w-[280px]" label="提现状态" prop="status">
<el-select v-model="queryParams.status" clearable placeholder="请选择">
<el-option label="全部" value=""></el-option>
<el-option label="待审核" value="0"></el-option>
<el-option label="已通过" value="1"></el-option>
<el-option label="已拒绝" value="2"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="resetPage">查询</el-button>
<el-button @click="resetParams">重置</el-button>
</el-form-item>
</el-form>
</el-card>
<el-card class="!border-none" v-loading="pager.loading" shadow="never">
<el-button v-perms="['store_user_reflect/delete']" :disabled="!selectData.length"
@click="handleDelete(selectData)">
删除
</el-button>
<div class="mt-4">
<el-table :data="pager.lists" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" />
<el-table-column label="订单编号" prop="order_sn" show-overflow-tooltip />
<el-table-column label="用户信息" prop="nickname" show-overflow-tooltip>
<template #default="{ row }">
<div>昵称{{ row.nickname }}</div>
<div>联系方式{{ row.mobile }}</div>
<div><el-image style="width:50px;height:50px;" :src="row.avatar" /></div>
</template>
</el-table-column>
<el-table-column label="店铺名称" prop="name" show-overflow-tooltip />
<el-table-column label="银行卡" prop="bank_card" show-overflow-tooltip>
<template #default="{ row }">
<div>卡号{{ row.bank_card }}</div>
<div>开户行{{ row.bank_name }} {{ row.bank_open_name }}</div>
</template>
</el-table-column>
<el-table-column label="提现金额" prop="amount" show-overflow-tooltip />
<el-table-column label="提现状态" prop="status">
<template #default="{ row }">
<span v-if="row.status == 0">待审核</span>
<span v-if="row.status == 1">已通过</span>
<span v-if="row.status == 2">已拒绝</span>
</template>
</el-table-column>
<el-table-column label="操作" width="120" fixed="right">
<template #default="{ row }">
<el-button v-perms="['store_user_reflect/edit']" type="primary" link
@click="handleEdit(row)">
编辑
</el-button>
<!-- <el-button v-perms="['store_user_reflect/delete']" type="danger" link
@click="handleDelete(row.id)">
删除
</el-button> -->
</template>
</el-table-column>
</el-table>
</div>
<div class="flex mt-4 justify-end">
<pagination v-model="pager" @change="getLists" />
</div>
</el-card>
<edit-popup v-if="showEdit" ref="editRef" :dict-data="dictData" @success="getLists" @close="showEdit = false" />
</div>
</template>
<script lang="ts" setup name="storeUserReflectLists">
import { usePaging } from '@/hooks/usePaging'
import { useDictData } from '@/hooks/useDictOptions'
import { apiStoreUserReflectLists, apiStoreUserReflectDelete } from '@/api/store_user_reflect'
import { timeFormat } from '@/utils/util'
import feedback from '@/utils/feedback'
import EditPopup from './edit.vue'
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
// 是否显示编辑框
const showEdit = ref(false)
// 查询条件
const queryParams = reactive({
order_sn: '',
store_id: '',
dtime: '',
status: ''
})
// 选中数据
const selectData = ref<any[]>([])
// 表格选择后回调事件
const handleSelectionChange = (val: any[]) => {
selectData.value = val.map(({ id }) => id)
}
// 获取字典数据
const { dictData } = useDictData('')
// 分页相关
const { pager, getLists, resetParams, resetPage } = usePaging({
fetchFun: apiStoreUserReflectLists,
params: queryParams
})
// 添加
const handleAdd = async () => {
showEdit.value = true
await nextTick()
editRef.value?.open('add')
}
// 编辑
const handleEdit = async (data: any) => {
showEdit.value = true
await nextTick()
editRef.value?.open('edit')
editRef.value?.setFormData(data)
}
// 删除
const handleDelete = async (id: number | any[]) => {
await feedback.confirm('确定要删除?')
await apiStoreUserReflectDelete({ id })
getLists()
}
getLists()
</script>

View File

@ -0,0 +1,134 @@
<template>
<div class="edit-popup">
<popup ref="popupRef" :title="popupTitle" :async="true" width="550px" @confirm="handleSubmit"
@close="handleClose">
<el-form ref="formRef" :model="formData" label-width="90px" :rules="formRules">
<el-form-item label="订单编号" prop="order_sn">
<el-input v-model="formData.order_sn" clearable placeholder="请输入订单编号" disabled />
</el-form-item>
<el-form-item label="用户昵称" prop="nickname">
<el-input v-model="formData.nickname" clearable disabled />
</el-form-item>
<el-form-item label="联系方式" prop="mobile">
<el-input v-model="formData.mobile" clearable disabled />
</el-form-item>
<el-form-item label="银行卡" prop="bank_card">
<el-input v-model="formData.bank_card" clearable disabled />
</el-form-item>
<el-form-item label="开户行" prop="bank_name">
<el-input v-model="formData.bank_name" clearable disabled />
</el-form-item>
<el-form-item label="开户行-分行" prop="bank_open_name">
<el-input v-model="formData.bank_open_name" clearable disabled />
</el-form-item>
<el-form-item label="提现金额" prop="amount">
<el-input v-model="formData.amount" clearable placeholder="请输入体现金额" disabled />
</el-form-item>
<el-form-item label="提现状态" prop="status">
<el-select class="flex-1" v-model="formData.status" clearable placeholder="请选择">
<el-option label="待审核" :value="0"></el-option>
<el-option label="通过" :value="1"></el-option>
<el-option label="拒绝" :value="2"></el-option>
</el-select>
</el-form-item>
</el-form>
</popup>
</div>
</template>
<script lang="ts" setup name="teamasterUserReflectEdit">
import type { FormInstance } from 'element-plus'
import Popup from '@/components/popup/index.vue'
import { apiTeamasterUserReflectAdd, apiTeamasterUserReflectEdit, apiTeamasterUserReflectDetail } from '@/api/teamaster_user_reflect'
import { timeFormat } from '@/utils/util'
import type { PropType } from 'vue'
defineProps({
dictData: {
type: Object as PropType<Record<string, any[]>>,
default: () => ({})
}
})
const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const mode = ref('add')
// 弹窗标题
const popupTitle = computed(() => {
return mode.value == '提现审核'
})
// 表单数据
const formData = reactive({
id: '',
order_sn: '',
team_user_id: '',
bank_id: '',
amount: '',
dtime: '',
status: '',
nickname: '',
mobile: '',
bank_card: '',
bank_name: '',
bank_open_name: ''
})
// 表单验证
const formRules = reactive<any>({
})
// 获取详情
const setFormData = async (data: Record<any, any>) => {
for (const key in formData) {
if (data[key] != null && data[key] != undefined) {
//@ts-ignore
formData[key] = data[key]
}
}
}
const getDetail = async (row: Record<string, any>) => {
const data = await apiTeamasterUserReflectDetail({
id: row.id
})
setFormData(data)
}
// 提交按钮
const handleSubmit = async () => {
await formRef.value?.validate()
const data = { ...formData, }
mode.value == 'edit'
? await apiTeamasterUserReflectEdit(data)
: await apiTeamasterUserReflectAdd(data)
popupRef.value?.close()
emit('success')
}
//打开弹窗
const open = (type = 'add') => {
mode.value = type
popupRef.value?.open()
}
// 关闭回调
const handleClose = () => {
emit('close')
}
defineExpose({
open,
setFormData,
getDetail
})
</script>

View File

@ -0,0 +1,127 @@
<template>
<div>
<el-card class="!border-none mb-4" shadow="never">
<el-form class="mb-[-16px]" :model="queryParams" inline>
<el-form-item label="订单编号" prop="order_sn">
<el-input class="w-[280px]" v-model="queryParams.order_sn" clearable placeholder="请输入订单编号" />
</el-form-item>
<el-form-item class="w-[280px]" label="提现状态" prop="status">
<el-select v-model="queryParams.status" clearable placeholder="请选择">
<el-option label="全部" value=""></el-option>
<el-option label="待审核" value="0"></el-option>
<el-option label="已通过" value="1"></el-option>
<el-option label="已拒绝" value="2"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="resetPage">查询</el-button>
<el-button @click="resetParams">重置</el-button>
</el-form-item>
</el-form>
</el-card>
<el-card class="!border-none" v-loading="pager.loading" shadow="never">
<div class="mt-4">
<el-table :data="pager.lists" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" />
<el-table-column label="订单编号" prop="order_sn" show-overflow-tooltip />
<el-table-column label="用户信息" prop="nickname" show-overflow-tooltip>
<template #default="{ row }">
<div>姓名{{ row.nickname }}</div>
<div>联系方式{{ row.mobile }}</div>
<div><el-image style="width:50px;height:50px;" :src="row.avatar" /></div>
</template>
</el-table-column>
<el-table-column label="银行卡" prop="bank_card" show-overflow-tooltip>
<template #default="{ row }">
<div>卡号{{ row.bank_card }}</div>
<div>开户行{{ row.bank_name }} {{ row.bank_open_name }}</div>
<div>绑定手机号{{ row.bank_mobile }}</div>
</template>
</el-table-column>
<el-table-column label="提现金额" prop="amount" show-overflow-tooltip />
<el-table-column label="提现状态" prop="status">
<template #default="{ row }">
<span v-if="row.status == 0">待审核</span>
<span v-if="row.status == 1">已通过</span>
<span v-if="row.status == 2">已拒绝</span>
</template>
</el-table-column>
<el-table-column label="操作" width="120" fixed="right">
<template #default="{ row }">
<el-button v-perms="['teamaster_user_reflect/edit']" type="primary" link
@click="handleEdit(row)">
编辑
</el-button>
</template>
</el-table-column>
</el-table>
</div>
<div class="flex mt-4 justify-end">
<pagination v-model="pager" @change="getLists" />
</div>
</el-card>
<edit-popup v-if="showEdit" ref="editRef" :dict-data="dictData" @success="getLists" @close="showEdit = false" />
</div>
</template>
<script lang="ts" setup name="teamasterUserReflectLists">
import { usePaging } from '@/hooks/usePaging'
import { useDictData } from '@/hooks/useDictOptions'
import { apiTeamasterUserReflectLists, apiTeamasterUserReflectDelete } from '@/api/teamaster_user_reflect'
import { timeFormat } from '@/utils/util'
import feedback from '@/utils/feedback'
import EditPopup from './edit.vue'
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
// 是否显示编辑框
const showEdit = ref(false)
// 查询条件
const queryParams = reactive({
order_sn: '',
dtime: '',
status: ''
})
// 选中数据
const selectData = ref<any[]>([])
// 表格选择后回调事件
const handleSelectionChange = (val: any[]) => {
selectData.value = val.map(({ id }) => id)
}
// 获取字典数据
const { dictData } = useDictData('')
// 分页相关
const { pager, getLists, resetParams, resetPage } = usePaging({
fetchFun: apiTeamasterUserReflectLists,
params: queryParams
})
// 添加
const handleAdd = async () => {
showEdit.value = true
await nextTick()
editRef.value?.open('add')
}
// 编辑
const handleEdit = async (data: any) => {
showEdit.value = true
await nextTick()
editRef.value?.open('edit')
editRef.value?.setFormData(data)
}
// 删除
const handleDelete = async (id: number | any[]) => {
await feedback.confirm('确定要删除?')
await apiTeamasterUserReflectDelete({ id })
getLists()
}
getLists()
</script>