初始化项目

This commit is contained in:
2026-09-01 22:15:50 +08:00
commit b5a26a8848
11217 changed files with 1710987 additions and 0 deletions
+177
View File
@@ -0,0 +1,177 @@
<template>
<a-card :bordered="false">
<div class="card-title">{{ $route.meta.title }}</div>
<a-spin :spinning="isLoading">
<a-form :form="form" @submit="handleSubmit" :selfUpdate="true">
<a-tabs :activeKey="tabKey" :tabBarStyle="{marginBottom: '30px'}" @change="handleTabs">
<a-tab-pane :key="0" tab="基本信息"></a-tab-pane>
</a-tabs>
<div class="tabs-content">
<!-- 基本信息 -->
<div class="tab-pane" v-show="tabKey == 0">
<a-form-item label="分油公司" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-select
style="width: 300px"
v-decorator="['company_id', {rules: [{required: true, message: '请选择分油公司'}]}]"
placeholder="请选择商户"
>
<a-select-option
v-for="(item, index) in formData.companyList"
:key="index"
:value="item.company_id"
>{{ item.name }}</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="商户" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-select
style="width: 300px"
v-decorator="['merchant_id', {rules: [{required: true, message: '请选择商户'}]}]"
placeholder="请选择商户"
>
<a-select-option
v-for="(item, index) in formData.merchantList"
:key="index"
:value="item.merchant_id"
>{{ item.name }}</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="用户角色" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-select
v-decorator="['userType', {rules: [{required: true, message: '请选择用户角色'}]}]"
placeholder="请选择用户角色"
>
<a-select-option
v-for="(item, index) in ['user', 'admin']"
:key="index"
:value="item"
>{{ item }}</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="用户名称" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-input
placeholder="请输入用户名称"
v-decorator="['userName', {rules: [{required: true, min: 2, message: '请输入至少2个字符'}]}]"
/>
</a-form-item>
<a-form-item label="用户手机号" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-input
placeholder="请输入用户手机号"
v-decorator="['mobile', {rules: [{required: true, min: 2, message: '请输入至少2个字符'}]}]"
/>
</a-form-item>
<a-form-item label="用户身份证号" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-input
placeholder="请输入用户身份证号"
v-decorator="['userIdCard', {rules: [{required: false}]}]"
/>
</a-form-item>
</div>
</div>
<a-form-item class="mt-20" :wrapper-col="{ span: wrapperCol.span, offset: labelCol.span }">
<a-button type="primary" html-type="submit" :loading="isBtnLoading">提交</a-button>
</a-form-item>
</a-form>
</a-spin>
</a-card>
</template>
<script>
import * as UserApi from '@/api/user'
import UserModel from '@/common/model/user/Index'
export default {
components: {
},
data () {
return {
// 默认的标签索引
tabKey: 0,
// 标签布局属性
labelCol: { span: 3 },
// 输入框布局属性
wrapperCol: { span: 10 },
// loading状态
isLoading: false,
isBtnLoading: false,
// 当前表单元素
form: this.$form.createForm(this),
// 表单数据
formData: UserModel.formData
}
},
// 初始化数据
created () {
this.isLoading = true
// 获取form所需的数据
UserModel.getFromData()
.then(() => {
this.isLoading = false
})
},
methods: {
// 手动强制更新页面
onForceUpdate (bool = false) {
this.$forceUpdate()
// bool为true时再执行一次 $forceUpdate, 特殊情况下需执行两次,原因如下:
// 第一次执行 $forceUpdate时, 新元素绑定v-decorator无法获取到form.getFieldValue
bool && setTimeout(() => {
this.$forceUpdate()
}, 10)
},
// 切换tab选项卡
handleTabs (key) {
this.tabKey = key
},
/**
* 确认按钮
*/
handleSubmit (e) {
e.preventDefault()
// 表单验证
const { form: { validateFields } } = this
validateFields((errors, values) => {
// 定位到错误的tab选项卡
if (errors) {
this.onTargetTabError(errors)
return false
}
// 提交到后端api
this.onFormSubmit(values)
return true
})
},
/**
* 提交到后端api
*/
onFormSubmit (values) {
this.isLoading = true
this.isBtnLoading = true
UserApi.add({ form: values })
.then(result => {
// 显示提示信息
this.$message.success(result.message, 1.5)
// 跳转到列表页
setTimeout(() => {
this.$router.push('./index')
}, 1500)
})
.catch(() => {
this.isBtnLoading = false
})
.finally(() => {
this.isLoading = false
})
}
}
}
</script>
<style lang="less" scoped>
@import './style.less';
</style>
+240
View File
@@ -0,0 +1,240 @@
<template>
<a-card :bordered="false">
<div class="card-title">{{ $route.meta.title }}</div>
<div class="table-operator">
<!-- 搜索板块 -->
<a-row class="row-item-search">
<a-form class="search-form" :form="searchForm" layout="inline" @submit="handleSearch">
<a-form-item label="昵称/手机号">
<a-input v-decorator="['search']" placeholder="请输入昵称/手机号" />
</a-form-item>
<a-form-item label="会员等级">
<a-select v-decorator="['gradeId', { initialValue: 0 }]">
<a-select-option :value="0">全部</a-select-option>
<a-select-option
v-for="(item, index) in gradeList"
:key="index"
:value="item.grade_id"
>{{ item.name }}</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="注册时间">
<a-range-picker format="YYYY-MM-DD" v-decorator="['betweenTime']" />
</a-form-item>
<a-form-item class="search-btn">
<a-button type="primary" icon="search" html-type="submit">搜索</a-button>
</a-form-item>
</a-form>
</a-row>
</div>
<s-table
ref="table"
rowKey="user_id"
:loading="isLoading"
:columns="columns"
:data="loadData"
:pageSize="15"
>
<!-- 会员头像 -->
<span slot="avatar_url" slot-scope="text">
<div class="avatar">
<img v-if="text" width="45" height="45" :src="text" alt="用户头像" />
<img v-else width="45" height="45" src="~@/assets/img/default-avatar.png" alt="用户头像" />
</div>
</span>
<span slot="main_info" slot-scope="item">
<p>{{ item.nick_name }}</p>
<p class="c-p">{{ item.mobile }}</p>
</span>
<!-- 会员等级 -->
<span slot="grade" slot-scope="text">
<a-tag v-if="text">{{ text.name }}</a-tag>
<span v-else>--</span>
</span>
<!-- 余额/积分 -->
<span slot="balance" slot-scope="text, item">
<p>
<span>余额:</span>
<span class="c-p">{{ text }}</span>
</p>
<p>
<span>积分:</span>
<span class="c-p">{{ item.points }}</span>
</p>
</span>
<!-- 实际消费金额 -->
<span slot="expend_money" slot-scope="text">
<span class="c-p">{{ text }}</span>
</span>
<!-- 注册来源 -->
<span slot="platform" class="platform" slot-scope="text">
<platform-icon :name="text" :showTips="true" :iconSize="17" />
</span>
<!-- 操作 -->
<span class="actions" slot="action" slot-scope="item">
<a title="会员充值" v-action:recharge @click="handleRecharge(item)">充值</a>
<a title="会员等级" v-action:grade @click="handleGrade(item)">等级</a>
<a v-action:delete @click="handleDelete(item)">删除</a>
<!-- <a title="用户分油" v-action:oil @click="handleOil(item)">分油</a>-->
</span>
</s-table>
<GradeForm ref="GradeForm" :gradeList="gradeList" @handleSubmit="handleRefresh" />
<RechargeForm ref="RechargeForm" @handleSubmit="handleRefresh" />
<OilForm ref="OilForm" @handleSubmit="handleRefresh" />
</a-card>
</template>
<script>
import * as Api from '@/api/user'
import * as GradeApi from '@/api/user/grade'
import { STable } from '@/components'
import { GradeForm, RechargeForm, OilForm } from './modules'
import PlatformIcon from '@/components/PlatformIcon'
export default {
name: 'Index',
components: {
STable,
GradeForm,
RechargeForm,
OilForm,
PlatformIcon
},
data () {
return {
// 当前表单元素
searchForm: this.$form.createForm(this),
// 查询参数
queryParam: {},
// 正在加载
isLoading: false,
// 表头
columns: [
{
title: '会员ID',
dataIndex: 'user_id'
},
{
title: '会员头像',
dataIndex: 'avatar_url',
scopedSlots: { customRender: 'avatar_url' }
},
{
title: '昵称/手机号',
scopedSlots: { customRender: 'main_info' }
},
{
title: '会员等级',
dataIndex: 'grade',
scopedSlots: { customRender: 'grade' }
},
{
title: '余额/积分',
dataIndex: 'balance',
scopedSlots: { customRender: 'balance' }
},
{
title: '实际消费金额',
dataIndex: 'expend_money',
scopedSlots: { customRender: 'expend_money' }
},
{
title: '注册来源',
dataIndex: 'platform',
scopedSlots: { customRender: 'platform' }
},
{
title: '注册时间',
dataIndex: 'create_time'
},
{
title: '操作',
// dataIndex: 'action',
width: '180px',
scopedSlots: { customRender: 'action' }
}
],
// 加载数据方法 必须为 Promise 对象
loadData: param => {
return Api.list({ ...param, ...this.queryParam })
.then(response => response.data.list)
},
// 会员等级列表
gradeList: []
}
},
created () {
// 获取会员等级列表
this.getGradeList()
},
methods: {
// 获取会员等级列表
getGradeList () {
GradeApi.all().then(result => {
this.gradeList = result.data.list
})
},
// 修改会员等级
handleGrade (item) {
this.$refs.GradeForm.handle(item)
},
// 会员充值
handleRecharge (item) {
this.$refs.RechargeForm.handle(item)
},
/**
* 删除记录
*/
handleDelete (item) {
const app = this
const modal = this.$confirm({
title: '您确定要删除该记录吗?',
content: '删除后不可恢复',
onOk () {
return Api.deleted({ userId: item.user_id })
.then((result) => {
app.$message.success(result.message, 1.5)
app.handleRefresh()
})
.finally(result => modal.destroy())
}
})
},
// 确认搜索
handleSearch (e) {
e.preventDefault()
this.searchForm.validateFields((error, values) => {
if (!error) {
this.queryParam = { ...this.queryParam, ...values }
this.handleRefresh(true)
}
})
},
// 用户分油
handleOil (item) {
this.$refs.OilForm.handle(item)
},
/**
* 刷新列表
* @param Boolean bool 强制刷新到第一页
*/
handleRefresh (bool = false) {
this.$refs.table.refresh(bool)
}
}
}
</script>
<style lang="less" scoped>
.ant-card-body {
padding: 22px 29px 25px;
}
</style>
+210
View File
@@ -0,0 +1,210 @@
<template>
<a-card :bordered="false">
<div class="card-title">{{ $route.meta.title }}</div>
<a-spin :spinning="isLoading">
<a-form :form="form" @submit="handleSubmit" :selfUpdate="true">
<a-tabs :activeKey="tabKey" :tabBarStyle="{marginBottom: '30px'}" @change="handleTabs">
<a-tab-pane :key="0" tab="基本信息"></a-tab-pane>
</a-tabs>
<div class="tabs-content">
<!-- 基本信息 -->
<div class="tab-pane" v-show="tabKey == 0">
<a-form-item label="分油公司" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-select
style="width: 300px"
v-decorator="['company_id', {rules: [{required: true, message: '请选择分油公司'}]}]"
placeholder="请选择商户"
>
<a-select-option
v-for="(item, index) in formData.companyList"
:key="index"
:value="item.company_id"
>{{ item.name }}</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="商户" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-select
style="width: 300px"
v-decorator="['merchant_id', {rules: [{required: true, message: '请选择商户'}]}]"
placeholder="请选择商户"
>
<a-select-option
v-for="(item, index) in formData.merchantList"
:key="index"
:value="item.merchant_id"
>{{ item.name }}</a-select-option>
</a-select>
<div class="form-item-help">
<router-link
target="_blank"
:to="{ path: '/shop/create' }"
>新增店铺</router-link>
<a href="javascript:;" @click="onReloadShopList">刷新</a>
</div>
</a-form-item>
<a-form-item label="用户角色" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-select
v-decorator="['userType', {rules: [{required: true, message: '请选择用户角色'}]}]"
placeholder="请选择用户角色"
>
<a-select-option
v-for="(item, index) in ['user', 'admin']"
:key="index"
:value="item"
>{{ item }}</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="用户名称" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-input
placeholder="请输入用户名称"
v-decorator="['userName', {rules: [{required: true, min: 2, message: '请输入至少2个字符'}]}]"
/>
</a-form-item>
<a-form-item label="用户手机号" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-input
placeholder="请输入用户手机号"
v-decorator="['mobile', {rules: [{required: true, min: 2, message: '请输入至少2个字符'}]}]"
/>
</a-form-item>
<a-form-item label="用户身份证号" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-input
placeholder="请输入用户身份证号"
v-decorator="['userIdCard', {rules: [{required: false}]}]"
/>
</a-form-item>
</div>
</div>
<a-form-item class="mt-20" :wrapper-col="{ span: wrapperCol.span, offset: labelCol.span }">
<a-button type="primary" html-type="submit" :loading="isBtnLoading">提交</a-button>
</a-form-item>
</a-form>
</a-spin>
</a-card>
</template>
<script>
import * as UserApi from '@/api/user'
import { InputNumberGroup } from '@/components'
import UserModel from '@/common/model/user/Index'
import { isEmptyObject } from '@/utils/util'
export default {
components: {
InputNumberGroup
},
data () {
return {
// 默认的标签索引
tabKey: 0,
// 标签布局属性
labelCol: { span: 3 },
// 输入框布局属性
wrapperCol: { span: 10 },
// loading状态
isLoading: false,
isBtnLoading: false,
// 当前表单元素
form: this.$form.createForm(this),
// 商户ID
userId: null,
// 表单数据
formData: UserModel.formData
}
},
created () {
// 初始化数据
this.initData()
},
beforeDestroy () {
// 销毁商户详情
UserModel.formData.user = {}
},
methods: {
// 初始化数据
initData () {
// 记录商户ID
this.userId = this.$route.query.userId
// 获取form所需的数据
this.isLoading = true
UserModel.getFromData(this.userId)
.then(() => {
// 商户表单数据
if (!isEmptyObject(this.form.getFieldsValue())) {
this.form.setFieldsValue(UserModel.getFieldsValue())
}
this.isLoading = false
})
},
// 手动强制更新页面
onForceUpdate (bool = false) {
this.$forceUpdate()
// bool为true时再执行一次 $forceUpdate, 特殊情况下需执行两次,原因如下:
// 第一次执行 $forceUpdate时, 新元素绑定v-decorator无法获取到form.getFieldValue
bool && setTimeout(() => {
this.$forceUpdate()
}, 10)
},
// 切换tab选项卡
handleTabs (key) {
this.tabKey = key
},
/**
* 确认按钮
*/
handleSubmit (e) {
e.preventDefault()
// 表单验证
const { form: { validateFields } } = this
validateFields((errors, values) => {
// 定位到错误的tab选项卡
if (errors) {
this.onTargetTabError(errors)
return false
}
// 提交到后端api
this.onFormSubmit(values)
return true
})
},
/**
* 定位到错误的tab选项卡
*/
onTargetTabError (errors) {
},
/**
* 提交到后端api
*/
onFormSubmit (values) {
this.isLoading = true
this.isBtnLoading = true
UserApi.edit({ userId: this.userId, form: values })
.then(result => {
// 显示提示信息
this.$message.success(result.message, 1.5)
// 跳转到列表页
setTimeout(() => {
this.$router.push('./index')
}, 1500)
})
.catch(() => {
this.isBtnLoading = false
})
.finally(() => {
this.isLoading = false
})
}
}
}
</script>
<style lang="less" scoped>
@import './style.less';
</style>
+145
View File
@@ -0,0 +1,145 @@
<template>
<a-card :bordered="false">
<div class="card-title">{{ $route.meta.title }}</div>
<div class="table-operator">
<!-- 搜索板块 -->
<a-row class="row-item-search">
<a-form class="search-form" :form="searchForm" layout="inline" @submit="handleSearch">
<a-form-item label="会员昵称">
<a-input v-decorator="['search']" placeholder="请输入会员昵称" />
</a-form-item>
<a-form-item label="余额变动场景">
<a-select v-decorator="['scene', { initialValue: 0 }]">
<a-select-option :value="0">全部</a-select-option>
<a-select-option
v-for="(item, index) in SceneEnum.data"
:key="index"
:value="item.value"
>{{ item.name }}</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="变动时间">
<a-range-picker format="YYYY-MM-DD" v-decorator="['betweenTime']" />
</a-form-item>
<a-form-item class="search-btn">
<a-button type="primary" icon="search" html-type="submit">搜索</a-button>
</a-form-item>
</a-form>
</a-row>
</div>
<s-table
ref="table"
rowKey="log_id"
:loading="isLoading"
:columns="columns"
:data="loadData"
:pageSize="15"
>
<!-- 会员信息 -->
<span slot="user" slot-scope="text">
<UserItem :user="text" />
</span>
<!-- 余额变动场景 -->
<span slot="scene" slot-scope="text">
<a-tag>{{ SceneEnum[text].name }}</a-tag>
</span>
</s-table>
</a-card>
</template>
<script>
import * as Api from '@/api/user/balance'
import { STable, UserItem } from '@/components/Table'
import SceneEnum from '@/common/enum/user/balance/log/Scene'
export default {
name: 'Index',
components: {
STable,
UserItem
},
data () {
return {
// 枚举类
SceneEnum,
// 当前表单元素
searchForm: this.$form.createForm(this),
// 查询参数
queryParam: {},
// 正在加载
isLoading: false,
// 表头
columns: [
{
title: 'ID',
dataIndex: 'log_id'
},
{
title: '会员信息',
dataIndex: 'user',
scopedSlots: { customRender: 'user' }
},
{
title: '余额变动场景',
dataIndex: 'scene',
scopedSlots: { customRender: 'scene' }
},
{
title: '变动金额',
dataIndex: 'money'
},
{
title: '描述/说明',
dataIndex: 'describe'
},
{
title: '管理员备注',
dataIndex: 'remark'
},
{
title: '变动时间',
dataIndex: 'create_time'
}
],
// 加载数据方法 必须为 Promise 对象
loadData: param => {
return Api.log({ ...param, ...this.queryParam })
.then(response => {
return response.data.list
})
}
}
},
created () {
},
methods: {
/**
* 刷新列表
* @param Boolean bool 强制刷新到第一页
*/
handleRefresh (bool = false) {
this.$refs.table.refresh(bool)
},
// 确认搜索
handleSearch (e) {
e.preventDefault()
this.searchForm.validateFields((error, values) => {
if (!error) {
this.queryParam = { ...this.queryParam, ...values }
this.handleRefresh(true)
}
})
}
}
}
</script>
<style lang="less" scoped>
.ant-card-body {
padding: 22px 29px 25px;
}
</style>
+150
View File
@@ -0,0 +1,150 @@
<template>
<a-card :bordered="false">
<div class="card-title">{{ $route.meta.title }}</div>
<div class="table-operator">
<a-button v-action:add type="primary" icon="plus" @click="handleAdd">新增</a-button>
</div>
<s-table
ref="table"
rowKey="grade_id"
:loading="isLoading"
:columns="columns"
:data="loadData"
:pageSize="15"
>
<!-- 升级条件 -->
<span slot="upgrade" slot-scope="text">消费满{{ text.expend_money }}元</span>
<!-- 等级权益 -->
<span slot="equity" slot-scope="text">{{ text.discount }}折</span>
<!-- 状态 -->
<span slot="status" slot-scope="text">
<a-tag :color="text ? 'green' : ''">{{ text ? '启用' : '禁用' }}</a-tag>
</span>
<!-- 操作 -->
<span slot="action" slot-scope="text, item">
<a v-action:edit style="margin-right: 8px;" @click="handleEdit(item)">编辑</a>
<a v-action:delete @click="handleDelete(item)">删除</a>
</span>
</s-table>
<AddForm ref="AddForm" @handleSubmit="handleRefresh" />
<EditForm ref="EditForm" @handleSubmit="handleRefresh" />
</a-card>
</template>
<script>
import * as Api from '@/api/user/grade'
import { STable } from '@/components'
import { AddForm, EditForm } from './modules'
export default {
name: 'Index',
components: {
STable,
AddForm,
EditForm
},
data () {
return {
// 查询参数
queryParam: {},
// 正在加载
isLoading: false,
// 表头
columns: [
{
title: '等级ID',
dataIndex: 'grade_id'
},
{
title: '等级名称',
dataIndex: 'name'
},
{
title: '等级权重',
dataIndex: 'weight'
},
{
title: '升级条件',
dataIndex: 'upgrade',
scopedSlots: { customRender: 'upgrade' }
},
{
title: '等级权益',
dataIndex: 'equity',
scopedSlots: { customRender: 'equity' }
},
{
title: '状态',
dataIndex: 'status',
scopedSlots: { customRender: 'status' }
},
{
title: '添加时间',
dataIndex: 'create_time'
},
{
title: '操作',
dataIndex: 'action',
width: '180px',
scopedSlots: { customRender: 'action' }
}
],
// 加载数据方法 必须为 Promise 对象
loadData: param => {
return Api.list({ ...param, ...this.queryParam })
.then(response => {
return response.data.list
})
}
}
},
created () {
},
methods: {
/**
* 新增记录
*/
handleAdd () {
this.$refs.AddForm.add()
},
/**
* 编辑记录
*/
handleEdit (item) {
this.$refs.EditForm.edit(item)
},
/**
* 删除记录
*/
handleDelete (item) {
const app = this
const modal = this.$confirm({
title: '您确定要删除该记录吗?',
content: '删除后不可恢复',
onOk () {
return Api.deleted({ gradeId: item.grade_id })
.then((result) => {
app.$message.success(result.message, 1.5)
app.handleRefresh()
})
.finally(result => {
modal.destroy()
})
}
})
},
/**
* 刷新列表
* @param Boolean bool 强制刷新到第一页
*/
handleRefresh (bool = false) {
this.$refs.table.refresh(bool)
}
}
}
</script>
@@ -0,0 +1,161 @@
<template>
<a-modal
:title="title"
:width="720"
:visible="visible"
:confirmLoading="confirmLoading"
:maskClosable="false"
@ok="handleSubmit"
@cancel="handleCancel"
>
<a-spin :spinning="confirmLoading">
<a-form :form="form">
<a-form-item
label="等级名称"
:labelCol="labelCol"
:wrapperCol="wrapperCol"
extra="例如:大众会员、黄金会员、铂金会员、钻石会员"
>
<a-input v-decorator="['name', {rules: [{required: true, message: '请输入等级名称'}]}]" />
</a-form-item>
<a-form-item
label="等级权重"
:labelCol="labelCol"
:wrapperCol="wrapperCol"
extra="会员等级的权重,数字越大 等级越高"
>
<a-select v-decorator="['weight', {rules: [{required: true, message: '请选择等级权重'}]}]">
<a-select-option
v-for="(value, index) in weights"
:key="index"
:value="value"
>{{ value }}</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="升级条件" :labelCol="labelCol" :wrapperCol="wrapperCol">
<InputNumberGroup
addonBefore="实际消费金额满"
addonAfter="元"
:inputProps="{ min: 0.01 }"
v-decorator="['upgrade.expend_money', { rules: [{ required: true, message: '升级条件不能为空' }] }]"
/>
<div class="form-item-help">
<p class="extra">用户的实际消费金额满足后,自动升级</p>
</div>
</a-form-item>
<a-form-item label="等级权益" :labelCol="labelCol" :wrapperCol="wrapperCol">
<InputNumberGroup
addonBefore="折扣率"
addonAfter="折"
:inputProps="{ min: 0, max: 9.9 }"
v-decorator="['equity.discount', { rules: [{ required: true, message: '等级权益不能为空' }] }]"
/>
<div class="form-item-help">
<p class="extra">折扣率范围0.0-9.9,例如: 9.8代表98折,0代表不折扣</p>
</div>
</a-form-item>
<a-form-item label="状态" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-radio-group v-decorator="['status', {initialValue: 1, rules: [{required: true}]}]">
<a-radio :value="1">启用</a-radio>
<a-radio :value="0">禁用</a-radio>
</a-radio-group>
</a-form-item>
<a-form-item label="排序" :labelCol="labelCol" :wrapperCol="wrapperCol" extra="数字越小越靠前">
<a-input-number
:min="0"
v-decorator="['sort', {initialValue: 100, rules: [{required: true, message: '请输入排序值'}]}]"
/>
</a-form-item>
</a-form>
</a-spin>
</a-modal>
</template>
<script>
import * as Api from '@/api/user/grade'
import { InputNumberGroup } from '@/components'
// 生成等级权重
const weights = []
for (let i = 1; i <= 20; i++) {
weights.push(i)
}
export default {
components: {
InputNumberGroup
},
data () {
return {
// 对话框标题
title: '新增会员等级',
// 标签布局属性
labelCol: { span: 7 },
// 输入框布局属性
wrapperCol: { span: 13 },
// modal(对话框)是否可见
visible: false,
// modal(对话框)确定按钮 loading
confirmLoading: false,
// 当前表单元素
form: this.$form.createForm(this),
// 等级权重
weights
}
},
created () {
},
methods: {
/**
* 显示对话框
*/
add () {
// 显示窗口
this.visible = true
},
/**
* 确认按钮
*/
handleSubmit (e) {
e.preventDefault()
// 表单验证
const { form: { validateFields } } = this
validateFields((errors, values) => {
// 提交到后端api
!errors && this.onFormSubmit(values)
})
},
/**
* 关闭对话框事件
*/
handleCancel () {
this.visible = false
this.form.resetFields()
},
/**
* 提交到后端api
*/
onFormSubmit (values) {
this.confirmLoading = true
Api.add({ form: values })
.then((result) => {
// 显示成功
this.$message.success(result.message, 1.5)
// 关闭对话框事件
this.handleCancel()
// 通知父端组件提交完成了
this.$emit('handleSubmit', values)
})
.finally(() => {
this.confirmLoading = false
})
}
}
}
</script>
@@ -0,0 +1,183 @@
<template>
<a-modal
:title="title"
:width="720"
:visible="visible"
:confirmLoading="confirmLoading"
:maskClosable="false"
@ok="handleSubmit"
@cancel="handleCancel"
>
<a-spin :spinning="confirmLoading">
<a-form :form="form">
<a-form-item
label="等级名称"
:labelCol="labelCol"
:wrapperCol="wrapperCol"
extra="例如:大众会员、黄金会员、铂金会员、钻石会员"
>
<a-input v-decorator="['name', {rules: [{required: true, message: '请输入等级名称'}]}]" />
</a-form-item>
<a-form-item
label="等级权重"
:labelCol="labelCol"
:wrapperCol="wrapperCol"
extra="会员等级的权重,数字越大 等级越高"
>
<a-select v-decorator="['weight', {rules: [{required: true, message: '请选择等级权重'}]}]">
<a-select-option
v-for="(value, index) in weights"
:key="index"
:value="value"
>{{ value }}</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="升级条件" :labelCol="labelCol" :wrapperCol="wrapperCol">
<InputNumberGroup
addonBefore="实际消费金额满"
addonAfter="元"
:inputProps="{ min: 0.01 }"
v-decorator="['upgrade.expend_money', { rules: [{ required: true, message: '升级条件不能为空' }] }]"
/>
<div class="form-item-help">
<p class="extra">用户的实际消费金额满足后,自动升级</p>
</div>
</a-form-item>
<a-form-item label="等级权益" :labelCol="labelCol" :wrapperCol="wrapperCol">
<InputNumberGroup
addonBefore="折扣率"
addonAfter="折"
:inputProps="{ min: 0, max: 9.9 }"
v-decorator="['equity.discount', { rules: [{ required: true, message: '等级权益不能为空' }] }]"
/>
<div class="form-item-help">
<p class="extra">折扣率范围0.0-9.9,例如: 9.8代表98折,0代表不折扣</p>
</div>
</a-form-item>
<a-form-item label="状态" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-radio-group v-decorator="['status', {initialValue: 1, rules: [{required: true}]}]">
<a-radio :value="1">启用</a-radio>
<a-radio :value="0">禁用</a-radio>
</a-radio-group>
</a-form-item>
<a-form-item label="排序" :labelCol="labelCol" :wrapperCol="wrapperCol" extra="数字越小越靠前">
<a-input-number
:min="0"
v-decorator="['sort', {initialValue: 100, rules: [{required: true, message: '请输入排序值'}]}]"
/>
</a-form-item>
</a-form>
</a-spin>
</a-modal>
</template>
<script>
import pick from 'lodash.pick'
import * as Api from '@/api/user/grade'
import { InputNumberGroup } from '@/components'
// 生成等级权重
const weights = []
for (let i = 1; i <= 20; i++) {
weights.push(i)
}
export default {
components: {
InputNumberGroup
},
data () {
return {
// 对话框标题
title: '编辑会员等级',
// 标签布局属性
labelCol: { span: 7 },
// 输入框布局属性
wrapperCol: { span: 13 },
// modal(对话框)是否可见
visible: false,
// modal(对话框)确定按钮 loading
confirmLoading: false,
// 当前表单元素
form: this.$form.createForm(this),
// 等级权重
weights,
// 当前记录
record: {}
}
},
created () {
},
methods: {
/**
* 显示对话框
*/
edit (record) {
// 显示窗口
this.visible = true
// 当前记录
this.record = record
// 设置默认值
this.setFieldsValue()
},
/**
* 设置默认值
*/
setFieldsValue () {
const { record, form: { setFieldsValue } } = this
record.cascader = [
record.province_id,
record.city_id,
record.region_id
]
this.$nextTick(() => {
setFieldsValue(pick(record, ['name', 'weight', 'upgrade', 'equity', 'status', 'sort']))
})
},
/**
* 确认按钮
*/
handleSubmit (e) {
e.preventDefault()
// 表单验证
const { form: { validateFields } } = this
validateFields((errors, values) => {
// 提交到后端api
!errors && this.onFormSubmit(values)
})
},
/**
* 关闭对话框事件
*/
handleCancel () {
this.visible = false
this.form.resetFields()
},
/**
* 提交到后端api
*/
onFormSubmit (values) {
this.confirmLoading = true
Api.edit({ gradeId: this.record.grade_id, form: values })
.then((result) => {
// 显示成功
this.$message.success(result.message, 1.5)
// 关闭对话框事件
this.handleCancel()
// 通知父端组件提交完成了
this.$emit('handleSubmit', values)
})
.finally(() => {
this.confirmLoading = false
})
}
}
}
</script>
@@ -0,0 +1,4 @@
import AddForm from './AddForm'
import EditForm from './EditForm'
export { AddForm, EditForm }
@@ -0,0 +1,143 @@
<template>
<a-modal
class="noborder"
:title="title"
:width="520"
:visible="visible"
:confirmLoading="confirmLoading"
:maskClosable="false"
@ok="handleSubmit"
@cancel="handleCancel"
>
<a-spin :spinning="confirmLoading">
<a-form :form="form">
<a-form-item label="会员ID" :labelCol="labelCol" :wrapperCol="wrapperCol">
<span>{{ record.user_id }}</span>
</a-form-item>
<a-form-item label="会员等级" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-select
placeholder="请选择会员等级"
v-decorator="['grade_id', { rules: [{ required: true }] }]"
>
<a-select-option :value="0">无等级</a-select-option>
<a-select-option
v-for="(item, index) in gradeList"
:key="index"
:value="item.grade_id"
>{{ item.name }}</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="管理员备注" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-textarea
placeholder="请输入管理员备注"
:rows="3"
v-decorator="['remark', { rules: [{ required: true, message: '请输入管理员备注' }] }]"
/>
</a-form-item>
</a-form>
</a-spin>
</a-modal>
</template>
<script>
import pick from 'lodash.pick'
import * as Api from '@/api/user'
export default {
components: {
},
props: {
// 会员等级列表
gradeList: {
type: Array,
required: true
}
},
data () {
return {
// 对话框标题
title: '设置会员等级',
// 标签布局属性
labelCol: { span: 7 },
// 输入框布局属性
wrapperCol: { span: 13 },
// modal(对话框)是否可见
visible: false,
// modal(对话框)确定按钮 loading
confirmLoading: false,
// 当前表单元素
form: this.$form.createForm(this),
// 当前记录
record: {}
}
},
methods: {
// 显示对话框
handle (record) {
// 显示窗口
this.visible = true
// 当前记录
this.record = record
// 设置默认值
this.setFieldsValue()
},
/**
* 设置默认值
*/
setFieldsValue () {
const { record, form: { setFieldsValue } } = this
this.$nextTick(() => {
setFieldsValue(pick(record, ['grade_id']))
})
},
/**
* 确认按钮
*/
handleSubmit (e) {
e.preventDefault()
// 表单验证
const { form: { validateFields } } = this
validateFields((errors, values) => {
// 提交到后端api
!errors && this.onFormSubmit(values)
})
},
/**
* 关闭对话框事件
*/
handleCancel () {
this.visible = false
this.form.resetFields()
},
/**
* 提交到后端api
*/
onFormSubmit (values) {
this.confirmLoading = true
Api.grade({ userId: this.record.user_id, form: values })
.then((result) => {
// 显示成功
this.$message.success(result.message, 1.5)
// 关闭对话框事件
this.handleCancel()
// 通知父端组件提交完成了
this.$emit('handleSubmit', values)
})
.finally(() => {
this.confirmLoading = false
})
}
}
}
</script>
<style lang="less">
.ant-form-item {
margin-bottom: 15px;
}
</style>
@@ -0,0 +1,230 @@
<template>
<a-modal
class="noborder"
:title="title"
:width="520"
:visible="visible"
:confirmLoading="confirmLoading"
:maskClosable="false"
@ok="handleSubmit"
@cancel="handleCancel"
>
<a-spin :spinning="confirmLoading">
<a-form :form="form">
<a-tabs :activeKey="activeKey" @change="onChangeTabs">
<a-tab-pane :key="OIL_TYPE" tab="用户分油">
<template v-if="activeKey === OIL_TYPE">
<a-form-item class="mb-5" label="用户昵称" :labelCol="labelCol" :wrapperCol="wrapperCol">
<span>{{ record.nick_name ? record.nick_name : '无' }}</span>
</a-form-item>
<a-form-item class="mb-5" label="手机号" :labelCol="labelCol" :wrapperCol="wrapperCol">
<span>{{ record.mobile }}</span>
</a-form-item>
<a-form-item class="mb-5" label="卡券类型" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-select @change="typeChange" v-decorator="[`oilCardType`, { rules: [{required: true, message: '请选择卡券类型'}], initialValue: 'zsy_ticket' }]">
<a-select-option
v-for="(item, index) in OilCardTypeEnum.data"
:key="index"
:value="item.value"
>{{ item.name }}</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="所属省份" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-select
style="width: 300px"
@change="handleChange"
v-decorator="['province', {rules: [{required: true, message: '请选择所属省份'}]}]"
placeholder="请选择所属省份"
>
<a-select-option
v-for="(item, index) in province"
:key="index"
:value="item"
>{{ item }}</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="油券" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-select
style="width: 300px"
v-decorator="['goods_id', {rules: []}]"
placeholder="请选择油券"
>
<a-select-option
v-for="(item, index) in goods"
:key="index"
:value="item.goods_id"
>{{ item.goods_name }}</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="分油金额" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-input-number
placeholder="卡券类型为油卡时填写"
:min="0.01"
v-decorator="[`amount`, { initialValue: '', rules: [] }]"
/>
</a-form-item>
<a-form-item label="管理员备注" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-textarea
placeholder="请输入管理员备注"
:rows="3"
v-decorator="[`buyer_remark`, { rules: [{ required: true, message: '请输入管理员备注' }] }]"
/>
</a-form-item>
</template>
</a-tab-pane>
</a-tabs>
</a-form>
</a-spin>
</a-modal>
</template>
<script>
// import pick from 'lodash.pick'
import * as Api from '@/api/user'
import * as GoodsApi from '@/api/goods'
import {
OilCardTypeEnum
} from '@/common/enum/order'
import { assignment, inArray } from '@/utils/util'
// 充值类型枚举: 余额
const OIL_TYPE = 'oil'
export default {
components: {
},
data () {
return {
// 对话框标题
title: '用户分油',
// 标签布局属性
labelCol: { span: 7 },
// 输入框布局属性
wrapperCol: { span: 13 },
// modal(对话框)是否可见
visible: false,
// modal(对话框)确定按钮 loading
confirmLoading: false,
// 当前表单元素
form: this.$form.createForm(this),
// 当前tab索引
activeKey: OIL_TYPE,
// 类型
OIL_TYPE,
// 当前记录
record: {},
oilCardType: 'zsy_ticket',
pro: '',
province: [],
goods: []
}
},
beforeCreate () {
// 批量给当前实例赋值
assignment(this, {
inArray,
OilCardTypeEnum
})
},
created () {
this.getProvinceList()
},
methods: {
// 显示对话框
handle (record) {
// 显示窗口
this.visible = true
// 当前记录
this.record = record
},
// 切换tabs事件
onChangeTabs (activeKey) {
this.activeKey = activeKey
},
/**
* 确认按钮
*/
handleSubmit (e) {
e.preventDefault()
// 表单验证
const { form: { validateFields } } = this
validateFields((errors, values) => {
// 提交到后端api
!errors && this.onFormSubmit(values)
})
},
/**
* 关闭对话框事件
*/
handleCancel () {
this.visible = false
this.form.resetFields()
},
/**
* 提交到后端api
*/
onFormSubmit (values) {
const { record, activeKey } = this
this.confirmLoading = true
Api.oil({ userId: record.user_id, target: activeKey, form: values })
.then((result) => {
// 显示成功
this.$message.success(result.message, 1.5)
// 关闭对话框事件
this.handleCancel()
// 通知父端组件提交完成了
this.$emit('handleSubmit', values)
})
.finally(() => {
this.confirmLoading = false
})
},
typeChange (value, option) {
this.oilCardType = value
this.getGoodsList(this.pro, value)
},
handleChange (value, option) {
this.pro = value
this.getGoodsList(value, this.oilCardType)
},
// 获取商品
getGoodsList (province, oilCardType) {
return new Promise((resolve, reject) => {
GoodsApi.all({ province, oilCardType })
.then(result => {
this.goods = result.data.list
resolve()
})
})
},
// 获取省份
getProvinceList () {
return new Promise((resolve, reject) => {
GoodsApi.province()
.then(result => {
this.province = result.data.list
resolve()
})
})
}
}
}
</script>
<style lang="less" scoped>
.ant-modal-body {
padding-top: 0 !important;
}
.ant-form-item {
margin-bottom: 15px;
}
.ant-tabs-nav .ant-tabs-tab {
padding: 10px 16px;
}
</style>
@@ -0,0 +1,190 @@
<template>
<a-modal
class="noborder"
:title="title"
:width="520"
:visible="visible"
:confirmLoading="confirmLoading"
:maskClosable="false"
@ok="handleSubmit"
@cancel="handleCancel"
>
<a-spin :spinning="confirmLoading">
<a-form :form="form">
<a-tabs :activeKey="activeKey" @change="onChangeTabs">
<a-tab-pane :key="RECHARGE_TYPE_BALANCE" tab="充值余额">
<template v-if="activeKey === RECHARGE_TYPE_BALANCE">
<a-form-item class="mb-5" label="会员ID" :labelCol="labelCol" :wrapperCol="wrapperCol">
<span>{{ record.user_id }}</span>
</a-form-item>
<a-form-item class="mb-5" label="当前余额" :labelCol="labelCol" :wrapperCol="wrapperCol">
<span class="c-p">{{ record.balance }}</span>
</a-form-item>
<a-form-item label="充值方式" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-radio-group
v-decorator="[`${RECHARGE_TYPE_BALANCE}.mode`, { initialValue: 'inc', rules: [{ required: true }] }]"
>
<a-radio value="inc">增加</a-radio>
<a-radio value="dec">减少</a-radio>
<a-radio value="final">最终金额</a-radio>
</a-radio-group>
</a-form-item>
<a-form-item label="变更金额" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-input-number
:min="0.01"
v-decorator="[`${RECHARGE_TYPE_BALANCE}.money`, { initialValue: '', rules: [{ required: true, message: '请输入变更的金额' }] }]"
/>
</a-form-item>
<a-form-item label="管理员备注" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-textarea
placeholder="请输入管理员备注"
:rows="3"
v-decorator="[`${RECHARGE_TYPE_BALANCE}.remark`, { rules: [{ required: true, message: '请输入管理员备注' }] }]"
/>
</a-form-item>
</template>
</a-tab-pane>
<a-tab-pane :key="RECHARGE_TYPE_POINTS" tab="充值积分">
<template v-if="activeKey === RECHARGE_TYPE_POINTS">
<a-form-item class="mb-5" label="会员ID" :labelCol="labelCol" :wrapperCol="wrapperCol">
<span>{{ record.user_id }}</span>
</a-form-item>
<a-form-item class="mb-5" label="当前积分" :labelCol="labelCol" :wrapperCol="wrapperCol">
<span class="c-p">{{ record.points }}</span>
</a-form-item>
<a-form-item label="充值方式" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-radio-group
v-decorator="[`${RECHARGE_TYPE_POINTS}.mode`, { initialValue: 'inc', rules: [{ required: true }] }]"
>
<a-radio value="inc">增加</a-radio>
<a-radio value="dec">减少</a-radio>
<a-radio value="final">最终积分</a-radio>
</a-radio-group>
</a-form-item>
<a-form-item label="变更数量" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-input-number
:min="0.01"
v-decorator="[`${RECHARGE_TYPE_POINTS}.value`, { initialValue: '', rules: [{ required: true, message: '请输入变更的金数量' }] }]"
/>
</a-form-item>
<a-form-item label="管理员备注" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-textarea
placeholder="请输入管理员备注"
:rows="3"
v-decorator="[`${RECHARGE_TYPE_POINTS}.remark`, { rules: [{ required: true, message: '请输入管理员备注' }] }]"
/>
</a-form-item>
</template>
</a-tab-pane>
</a-tabs>
</a-form>
</a-spin>
</a-modal>
</template>
<script>
// import pick from 'lodash.pick'
import * as Api from '@/api/user'
// 充值类型枚举: 余额
const RECHARGE_TYPE_BALANCE = 'balance'
// 充值类型枚举: 积分
const RECHARGE_TYPE_POINTS = 'points'
export default {
components: {
},
data () {
return {
// 对话框标题
title: '会员充值',
// 标签布局属性
labelCol: { span: 7 },
// 输入框布局属性
wrapperCol: { span: 13 },
// modal(对话框)是否可见
visible: false,
// modal(对话框)确定按钮 loading
confirmLoading: false,
// 当前表单元素
form: this.$form.createForm(this),
// 当前tab索引
activeKey: RECHARGE_TYPE_BALANCE,
// 充值类型
RECHARGE_TYPE_BALANCE,
RECHARGE_TYPE_POINTS,
// 当前记录
record: {}
}
},
methods: {
// 显示对话框
handle (record) {
// 显示窗口
this.visible = true
// 当前记录
this.record = record
},
// 切换tabs事件
onChangeTabs (activeKey) {
this.activeKey = activeKey
},
/**
* 确认按钮
*/
handleSubmit (e) {
e.preventDefault()
// 表单验证
const { form: { validateFields } } = this
validateFields((errors, values) => {
// 提交到后端api
!errors && this.onFormSubmit(values)
})
},
/**
* 关闭对话框事件
*/
handleCancel () {
this.visible = false
this.form.resetFields()
},
/**
* 提交到后端api
*/
onFormSubmit (values) {
const { record, activeKey } = this
this.confirmLoading = true
Api.recharge({ userId: record.user_id, target: activeKey, form: values })
.then((result) => {
// 显示成功
this.$message.success(result.message, 1.5)
// 关闭对话框事件
this.handleCancel()
// 通知父端组件提交完成了
this.$emit('handleSubmit', values)
})
.finally(() => {
this.confirmLoading = false
})
}
}
}
</script>
<style lang="less" scoped>
.ant-modal-body {
padding-top: 0 !important;
}
.ant-form-item {
margin-bottom: 15px;
}
.ant-tabs-nav .ant-tabs-tab {
padding: 10px 16px;
}
</style>
@@ -0,0 +1,5 @@
import GradeForm from './GradeForm'
import RechargeForm from './RechargeForm'
import OilForm from './OilForm'
export { GradeForm, RechargeForm, OilForm }
+177
View File
@@ -0,0 +1,177 @@
<template>
<a-card :bordered="false">
<div class="card-title">{{ $route.meta.title }}</div>
<div class="table-operator">
<!-- 搜索板块 -->
<a-row class="row-item-search">
<a-form class="search-form" :form="searchForm" layout="inline" @submit="handleSearch">
<a-form-item label="会员昵称/订单号">
<a-input v-decorator="['search']" placeholder="请输入会员昵称/订单号" />
</a-form-item>
<a-form-item label="充值方式">
<a-select v-decorator="['recharge_type', { initialValue: 0 }]">
<a-select-option :value="0">全部</a-select-option>
<a-select-option
v-for="(item, index) in RechargeTypeEnum.data"
:key="index"
:value="item.value"
>{{ item.name }}</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="支付状态">
<a-select v-decorator="['pay_status', { initialValue: 0 }]">
<a-select-option :value="0">全部</a-select-option>
<a-select-option :value="10">待支付</a-select-option>
<a-select-option :value="20">已支付</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="付款时间">
<a-range-picker format="YYYY-MM-DD" v-decorator="['betweenTime']" />
</a-form-item>
<a-form-item class="search-btn">
<a-button type="primary" icon="search" html-type="submit">搜索</a-button>
</a-form-item>
</a-form>
</a-row>
</div>
<s-table
ref="table"
rowKey="order_id"
:loading="isLoading"
:columns="columns"
:data="loadData"
:pageSize="15"
>
<!-- 会员信息 -->
<span slot="user" slot-scope="text">
<UserItem :user="text" />
</span>
<!-- 套餐名称 -->
<span slot="order_plan" slot-scope="text">
<a-tag v-if="text">{{ text.plan_name }}</a-tag>
<span v-else>--</span>
</span>
<!-- 充值方式 -->
<span slot="recharge_type" slot-scope="text">
<a-tag>{{ RechargeTypeEnum[text].name }}</a-tag>
</span>
<!-- 状态 -->
<span slot="pay_status" slot-scope="text">
<a-tag :color="text == 20 ? 'green' : ''">{{ text == 20 ? '已支付' : '待支付' }}</a-tag>
</span>
</s-table>
</a-card>
</template>
<script>
import * as Api from '@/api/user/recharge'
import { STable, UserItem } from '@/components/Table'
import PayStatusEnum from '@/common/enum/recharge/order/PayStatus'
import RechargeTypeEnum from '@/common/enum/recharge/order/RechargeType'
export default {
name: 'Index',
components: {
STable,
UserItem
},
data () {
return {
// 枚举类
PayStatusEnum,
RechargeTypeEnum,
// 当前表单元素
searchForm: this.$form.createForm(this),
// 查询参数
queryParam: {},
// 正在加载
isLoading: false,
// 表头
columns: [
{
title: 'ID',
dataIndex: 'order_id'
},
{
title: '会员信息',
dataIndex: 'user',
scopedSlots: { customRender: 'user' }
},
{
title: '订单号',
dataIndex: 'order_no'
},
{
title: '充值方式',
dataIndex: 'recharge_type',
scopedSlots: { customRender: 'recharge_type' }
},
{
title: '套餐名称',
dataIndex: 'order_plan',
scopedSlots: { customRender: 'order_plan' }
},
{
title: '支付金额',
dataIndex: 'pay_price'
},
{
title: '赠送金额',
dataIndex: 'gift_money'
},
{
title: '支付状态',
dataIndex: 'pay_status',
scopedSlots: { customRender: 'pay_status' }
},
{
title: '付款时间',
dataIndex: 'pay_time'
},
{
title: '创建时间',
dataIndex: 'create_time'
}
],
// 加载数据方法 必须为 Promise 对象
loadData: param => {
return Api.order({ ...param, ...this.queryParam })
.then(response => {
return response.data.list
})
}
}
},
created () {
},
methods: {
/**
* 刷新列表
* @param Boolean bool 强制刷新到第一页
*/
handleRefresh (bool = false) {
this.$refs.table.refresh(bool)
},
// 确认搜索
handleSearch (e) {
e.preventDefault()
this.searchForm.validateFields((error, values) => {
if (!error) {
this.queryParam = { ...this.queryParam, ...values }
this.handleRefresh(true)
}
})
}
}
}
</script>
<style lang="less" scoped>
.ant-card-body {
padding: 22px 29px 25px;
}
</style>
+25
View File
@@ -0,0 +1,25 @@
.tabs-content {
.tab-pane {
animation: fadenum 0.6s ease;
}
}
/deep/.ant-form-item-control {
padding-left: 10px;
.ant-form-item-control {
padding-left: 0;
}
}
.ant-form-item {
margin-bottom: 18px;
.ant-form-item {
margin-bottom: 0;
}
}
.input-number-group {
margin: 3px 0;
}