第一次更新,完成了初版调整

This commit is contained in:
2026-09-07 22:05:51 +08:00
parent b5a26a8848
commit 4d6a7e7aac
198 changed files with 6142 additions and 3856 deletions
-140
View File
@@ -1,140 +0,0 @@
<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-range-picker format="YYYY-MM-DD" v-decorator="['last_called_at']" />
</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="account_id"
:loading="isLoading"
:columns="columns"
:data="loadData"
:pageSize="15"
>
<!-- 公司 -->
<span slot="company" slot-scope="text, item">
<p class="twoline-hide" style="width: 100px;">{{ item.company.name }}</p>
</span>
<!-- 最后使用时间 -->
<span slot="last_called_at" slot-scope="text, item">
<p class="twoline-hide" style="width: 150px;">{{ item.last_called_at | dateFormat }}</p>
</span>
</s-table>
</a-card>
</template>
<script>
import * as Api from '@/api/account'
import { STable } from '@/components/Table'
export default {
name: 'Index',
components: {
STable
},
data () {
return {
// 当前表单元素
searchForm: this.$form.createForm(this),
// 查询参数
queryParam: {},
// 正在加载
isLoading: false,
// 表头
columns: [
{
title: 'ID',
dataIndex: 'account_id'
},
{
title: '公司信息',
dataIndex: 'company',
scopedSlots: { customRender: 'company' }
},
{
title: '用户编号',
dataIndex: 'userNo'
},
{
title: '用户姓名',
dataIndex: 'userName'
},
{
title: '手机号',
dataIndex: 'mobile'
},
{
title: '用户角色',
dataIndex: 'userType',
scopedSlots: { customRender: 'userType' }
},
{
title: '用户身份证号',
dataIndex: 'userIdCard'
},
{
title: '最后使用时间',
dataIndex: 'last_called_at',
scopedSlots: { customRender: 'last_called_at' }
},
{
title: '注册时间',
dataIndex: 'create_time'
}
],
// 加载数据方法 必须为 Promise 对象
loadData: param => {
return Api.list({ ...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>
-184
View File
@@ -1,184 +0,0 @@
<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-input
placeholder="请输入公司名称"
v-decorator="['name', {rules: [{required: true, min: 2, message: '请输入至少2个字符'}]}]"
/>
</a-form-item>
<a-form-item label="公司地址" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-input
placeholder="请输入公司地址"
v-decorator="['address', {rules: [{required: true, min: 2, message: '请输入至少2个字符'}]}]"
/>
</a-form-item>
<a-form-item label="纳税识别号" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-input
placeholder="请输入纳税识别号"
v-decorator="['tin', {rules: [{required: true, min: 2, message: '请输入至少2个字符'}]}]"
/>
</a-form-item>
<a-form-item label="联系人" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-input
placeholder="请输入联系人"
v-decorator="['contact_name', {rules: [{required: false}]}]"
/>
</a-form-item>
<a-form-item label="联系电话" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-input
placeholder="请输入联系电话"
v-decorator="['contact_tel', {rules: [{required: false}]}]"
/>
</a-form-item>
<a-form-item label="身份证号" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-input
placeholder="请输入身份证号"
v-decorator="['idcard', {rules: [{required: false}]}]"
/>
</a-form-item>
<a-form-item label="请求地址" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-input
placeholder="请输入请求地址"
v-decorator="['url', {rules: [{required: false}]}]"
/>
</a-form-item>
<a-form-item label="公司编号(平台提供)" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-input
placeholder="请输入公司编号"
v-decorator="['orgNo', {rules: [{required: false}]}]"
/>
</a-form-item>
<a-form-item label="appKey(平台提供)" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-input
placeholder="请输入公司appKey"
v-decorator="['appKey', {rules: [{required: false}]}]"
/>
</a-form-item>
<a-form-item label="公司私钥(平台提供)" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-textarea class="company-textarea" v-decorator="['privateKey']" placeholder="请输入公司私钥base64编码" />
</a-form-item>
<a-form-item label="公司公钥(平台提供)" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-textarea class="company-textarea" v-decorator="['publicKey']" placeholder="请输入公司公钥base64编码" />
</a-form-item>
<a-form-item label="平台公钥(平台提供)" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-textarea class="company-textarea" v-decorator="['platformPublicKey']" placeholder="请输入平台公钥base64编码" />
</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 CompanyApi from '@/api/company'
import CompanyModel from '@/common/model/company/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: CompanyModel.formData
}
},
// 初始化数据
created () {
this.isLoading = true
// 获取form所需的数据
CompanyModel.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
CompanyApi.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>
-341
View File
@@ -1,341 +0,0 @@
<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 class="search-btn">
<a-button type="primary" icon="search" html-type="submit">搜索</a-button>
</a-form-item>
</a-form>
</a-row>
<!-- 操作板块 -->
<div class="row-item-tab clearfix">
<a-button
v-if="$auth('/company/create')"
class="fl-l"
type="primary"
icon="plus"
@click="handleCreate"
>新增</a-button>
<div v-if="selectedRowKeys.length" class="button-group">
<a-button-group class="ml-10">
<a-button v-action:delete icon="delete" @click="handleDelete(selectedRowKeys)">删除</a-button>
</a-button-group>
<a-button-group class="ml-10">
<a-button
v-action:status
icon="arrow-up"
@click="handleUpdateStatus(selectedRowKeys, true)"
>启用</a-button>
<a-button
v-action:status
icon="arrow-down"
@click="handleUpdateStatus(selectedRowKeys, false)"
>停用</a-button>
<a-button v-action:delete icon="delete" @click="handleDelete(selectedRowKeys)">删除</a-button>
</a-button-group>
</div>
</div>
</div>
<s-table
ref="table"
rowKey="company_id"
:loading="isLoading"
:columns="columns"
:data="loadData"
:rowSelection="rowSelection"
:pageSize="15"
:scroll="{ x: 1450 }"
>
<!-- 公司地址 -->
<span slot="address" slot-scope="text">
<p class="twoline-hide" style="width: 400px;">{{ text }}</p>
</span>
<!-- 公司状态 -->
<span slot="status" slot-scope="text, item">
<a-tag
class="cur-p"
:color="text === 10 ? 'green' : 'red'"
@click="handleUpdateStatus([item.company_id], text !== 10)"
>{{ text === 10 ? '启用' : '停用' }}</a-tag>
</span>
<!-- 操作项 -->
<div class="actions" slot="action" slot-scope="text, item">
<a v-action:stock @click="handleStock([item.company_id])">更新库存</a>
<a title="公司对接参数" v-action:para @click="handleApiPara(item)">对接参数</a>
<a title="公司充值" v-action:recharge @click="handleRecharge(item)">充值</a>
<a title="创建用户" v-action:account @click="handleAccount(item)">创建用户</a>
<router-link v-if="$auth('/company/update')" :to="{ path: '/company/update', query: { companyId: item.company_id } }">编辑</router-link>
<a v-action:delete @click="handleDelete([item.company_id])">删除</a>
</div>
</s-table>
<RechargeForm ref="RechargeForm" @handleSubmit="handleRefresh" />
<ApiParaForm ref="ApiParaForm" @handleSubmit="handleRefresh" />
<AccountForm ref="AccountForm" @handleSubmit="handleRefresh" />
</a-card>
</template>
<script>
import * as CompanyApi from '@/api/company'
import { ContentHeader, STable } from '@/components'
import { CompanyStatusEnum } from '@/common/enum/company'
import { RechargeForm, ApiParaForm, AccountForm } from './modules'
import { assignment, inArray } from '@/utils/util'
// 表格表头
const columns = [
{
title: '公司ID',
width: '70px',
dataIndex: 'company_id'
},
{
title: '公司编号',
width: '150px',
dataIndex: 'orgNo'
},
{
title: '公司名称',
width: '150px',
dataIndex: 'name'
},
{
title: '公司地址',
width: '400px',
dataIndex: 'address'
},
{
title: '纳税识别号',
width: '200px',
dataIndex: 'tin'
},
{
title: '余额',
width: '150px',
dataIndex: 'balance'
},
{
title: '状态',
width: '100px',
dataIndex: 'status',
scopedSlots: { customRender: 'status' }
},
/*{
title: '联系人',
width: '150px',
dataIndex: 'contact_name'
},
{
title: '联系电话',
width: '150px',
dataIndex: 'contact_tel'
},
{
title: '身份证号',
width: '150px',
dataIndex: 'idcard'
},*/
{
title: '可下单数量',
width: '100px',
dataIndex: 'canOrderNum'
},
{
title: '未使用数量',
width: '100px',
dataIndex: 'unUseNum'
},
{
title: '已使用数量',
width: '100px',
dataIndex: 'useNum'
},
{
title: '创建时间',
width: '100px',
dataIndex: 'create_time'
},
{
title: '操作',
dataIndex: 'action',
width: '300px',
fixed: 'right',
scopedSlots: { customRender: 'action' }
}
]
export default {
name: 'Index',
components: {
ContentHeader,
RechargeForm,
ApiParaForm,
AccountForm,
STable
},
data () {
return {
// 当前表单元素
searchForm: this.$form.createForm(this),
// 查询参数
queryParam: {},
// 正在加载
isLoading: false,
// 表头
columns,
// 选择的元素
selectedRowKeys: [],
// 加载数据方法 必须为 Promise 对象
loadData: param => {
return CompanyApi.list({ ...param, ...this.queryParam })
.then(response => {
return response.data.list
})
}
}
},
beforeCreate () {
// 批量给当前实例赋值
assignment(this, {
inArray,
CompanyStatusEnum
})
},
created () {
},
computed: {
rowSelection () {
return {
selectedRowKeys: this.selectedRowKeys,
onChange: this.onSelectChange
}
}
},
methods: {
/**
* 选中项发生变化时的回调
*/
onSelectChange (selectedRowKeys) {
this.selectedRowKeys = selectedRowKeys
},
// 确认搜索
handleSearch (e) {
e.preventDefault()
this.searchForm.validateFields((error, values) => {
if (!error) {
this.queryParam = { ...this.queryParam, ...values }
this.handleRefresh(true)
}
})
},
// 重置搜索表单
handleReset () {
this.searchForm.resetFields()
},
// 修改商品状态(上下架)
handleUpdateStatus (companyIds, state = true) {
if (!this.$auth('/company/changeState')) {
return false
}
this.isLoading = true
CompanyApi.changeState({ companyIds, state })
.then(result => {
// 显示成功
this.$message.success(result.message, 1.5)
this.handleRefresh()
})
.finally(result => { this.isLoading = false })
},
// 商户充值
handleRecharge (item) {
this.$refs.RechargeForm.handle(item)
},
// 商户对接参数
handleApiPara (item) {
this.$refs.ApiParaForm.handle(item)
},
// 商户对接参数
handleAccount (item) {
this.$refs.AccountForm.handle(item)
},
/**
* 删除记录
*/
handleDelete (companyIds) {
const app = this
const modal = this.$confirm({
title: '您确定要删除该记录吗?',
content: '删除后不可恢复',
onOk () {
return CompanyApi.deleted(companyIds)
.then(result => {
app.$message.success(result.message, 1.5)
app.handleRefresh()
})
.finally(result => {
modal.destroy()
})
}
})
},
/**
* 更新库存
*/
handleStock (companyIds) {
const app = this
const modal = this.$confirm({
title: '执行此操作将更新商品可用库存',
content: '',
onOk () {
return CompanyApi.stock(companyIds)
.then(result => {
app.$message.success(result.message, 1.5)
app.handleRefresh()
})
.finally(result => {
modal.destroy()
})
}
})
},
/**
* 新增记录
*/
handleCreate () {
this.$router.push('/company/create')
},
/**
* 刷新列表
* @param Boolean bool 强制刷新到第一页
*/
handleRefresh (bool = false) {
this.selectedRowKeys = []
this.$refs.table.refresh(bool)
}
}
}
</script>
<style lang="less" scoped>
.ant-card-body {
padding: 22px 29px 25px;
}
// 筛选tab
.tab-list {
margin-right: 20px;
}
</style>
-210
View File
@@ -1,210 +0,0 @@
<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-input
placeholder="请输入公司名称"
v-decorator="['name', {rules: [{required: true, min: 2, message: '请输入至少2个字符'}]}]"
/>
</a-form-item>
<a-form-item label="公司地址" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-input
placeholder="请输入公司地址"
v-decorator="['address', {rules: [{required: true, min: 2, message: '请输入至少2个字符'}]}]"
/>
</a-form-item>
<a-form-item label="纳税识别号" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-input
placeholder="请输入纳税识别号"
v-decorator="['tin', {rules: [{required: true, min: 2, message: '请输入至少2个字符'}]}]"
/>
</a-form-item>
<a-form-item label="联系人" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-input
placeholder="请输入联系人"
v-decorator="['contact_name', {rules: [{required: false}]}]"
/>
</a-form-item>
<a-form-item label="联系电话" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-input
placeholder="请输入联系电话"
v-decorator="['contact_tel', {rules: [{required: false}]}]"
/>
</a-form-item>
<a-form-item label="身份证号" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-input
placeholder="请输入身份证号"
v-decorator="['idcard', {rules: [{required: false}]}]"
/>
</a-form-item>
<a-form-item label="请求地址" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-input
placeholder="请输入请求地址"
v-decorator="['url', {rules: [{required: false}]}]"
/>
</a-form-item>
<a-form-item label="公司编号(平台提供)" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-input
placeholder="请输入公司编号"
v-decorator="['orgNo', {rules: [{required: false}]}]"
/>
</a-form-item>
<a-form-item label="appKey(平台提供)" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-input
placeholder="请输入公司appKey"
v-decorator="['appKey', {rules: [{required: false}]}]"
/>
</a-form-item>
<a-form-item label="公司私钥(平台提供)" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-textarea class="company-textarea" v-decorator="['privateKey']" placeholder="请输入公司私钥base64编码" />
</a-form-item>
<a-form-item label="公司公钥(平台提供)" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-textarea class="company-textarea" v-decorator="['publicKey']" placeholder="请输入公司公钥base64编码" />
</a-form-item>
<a-form-item label="平台公钥(平台提供)" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-textarea class="company-textarea" v-decorator="['platformPublicKey']" placeholder="请输入平台公钥base64编码" />
</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 CompanyApi from '@/api/company'
import { InputNumberGroup } from '@/components'
import CompanyModel from '@/common/model/company/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
companyId: null,
// 表单数据
formData: CompanyModel.formData
}
},
created () {
// 初始化数据
this.initData()
},
beforeDestroy () {
// 销毁商户详情
CompanyModel.formData.company = {}
},
methods: {
// 初始化数据
initData () {
// 记录商户ID
this.companyId = this.$route.query.companyId
// 获取form所需的数据
this.isLoading = true
CompanyModel.getFromData(this.companyId)
.then(() => {
// 商户表单数据
if (!isEmptyObject(this.form.getFieldsValue())) {
this.form.setFieldsValue(CompanyModel.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
CompanyApi.edit({ companyId: this.companyId, 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>
@@ -1,146 +0,0 @@
<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="company" slot-scope="text, item">
<p class="twoline-hide" style="width: 150px;">{{ item.name }}</p>
</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/company/balance'
import { STable } from '@/components/Table'
import SceneEnum from '@/common/enum/company/balance/log/Scene'
export default {
name: 'Index',
components: {
STable
},
data () {
return {
// 枚举类
SceneEnum,
// 当前表单元素
searchForm: this.$form.createForm(this),
// 查询参数
queryParam: {},
// 正在加载
isLoading: false,
// 表头
columns: [
{
title: 'ID',
dataIndex: 'log_id'
},
{
title: '公司信息',
dataIndex: 'company',
scopedSlots: { customRender: 'company' }
},
{
title: '余额变动场景',
dataIndex: 'scene',
scopedSlots: { customRender: 'scene' }
},
{
title: '变动金额',
dataIndex: 'money'
},
{
title: '描述/说明',
width: '260px',
dataIndex: 'describe'
},
{
title: '管理员备注',
width: '260px',
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>
@@ -1,123 +0,0 @@
<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">
<template>
<a-form-item class="mb-5" label="公司ID" :labelCol="labelCol" :wrapperCol="wrapperCol">
<span>{{ record.company_id }}</span>
</a-form-item>
<a-form-item class="mb-5" label="公司名称" :labelCol="labelCol" :wrapperCol="wrapperCol">
<span>{{ record.name }}</span>
</a-form-item>
<a-form-item label="创建用户数" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-input-number
:min="1"
v-decorator="[`users`, { initialValue: '', rules: [{ required: true, message: '请输入用户数' }] }]"
/>
</a-form-item>
</template>
</a-form>
</a-spin>
</a-modal>
</template>
<script>
// import pick from 'lodash.pick'
import * as Api from '@/api/company'
export default {
components: {
},
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
},
/**
* 确认按钮
*/
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 } = this
this.confirmLoading = true
values.company_id = record.company_id
Api.account({ companyId: record.company_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" scoped>
.ant-modal-body {
padding-top: 0 !important;
}
.ant-form-item {
margin-bottom: 15px;
}
.ant-tabs-nav .ant-tabs-tab {
padding: 10px 16px;
}
</style>
@@ -1,108 +0,0 @@
<template>
<a-modal
class="noborder"
:title="title"
:width="900"
:visible="visible"
:confirmLoading="confirmLoading"
:maskClosable="false"
@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="请求地址" :labelCol="labelCol" :wrapperCol="wrapperCol">
<span>{{ record.url }}</span>
</a-form-item>
<a-form-item class="mb-5" label="公司编号" :labelCol="labelCol" :wrapperCol="wrapperCol">
<span>{{ record.orgNo }}</span>
</a-form-item>
<a-form-item class="mb-5" label="公司appKey" :labelCol="labelCol" :wrapperCol="wrapperCol">
<span>{{ record.appKey }}</span>
</a-form-item>
<a-form-item class="mb-5" label="公司私钥" :labelCol="labelCol" :wrapperCol="wrapperCol">
<span>{{ record.privateKey }}</span>
</a-form-item>
<a-form-item class="mb-5" label="公司公钥" :labelCol="labelCol" :wrapperCol="wrapperCol">
<span>{{ record.publicKey }}</span>
</a-form-item>
<a-form-item class="mb-5" label="平台公司公钥" :labelCol="labelCol" :wrapperCol="wrapperCol">
<span>{{ record.platformPublicKey }}</span>
</a-form-item>
</template>
</a-tab-pane>
</a-tabs>
</a-form>
</a-spin>
</a-modal>
</template>
<script>
// import pick from 'lodash.pick'
// 充值类型枚举: 余额
const RECHARGE_TYPE_BALANCE = 'balance'
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,
// 当前记录
record: {}
}
},
methods: {
// 显示对话框
handle (record) {
// 显示窗口
this.visible = true
// 当前记录
this.record = record
},
// 切换tabs事件
onChangeTabs (activeKey) {
this.activeKey = activeKey
},
/**
* 关闭对话框事件
*/
handleCancel () {
this.visible = false
this.form.resetFields()
}
}
}
</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>
@@ -1,190 +0,0 @@
<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.company_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.company_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/company'
// 充值类型枚举: 余额
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({ companyId: record.company_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>
@@ -1,9 +0,0 @@
import RechargeForm from './RechargeForm'
import ApiParaForm from './ApiParaForm'
import AccountForm from './AccountForm'
export {
RechargeForm,
ApiParaForm,
AccountForm
}
-29
View File
@@ -1,29 +0,0 @@
.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;
}
.company-textarea{
height: 80px;
}
+1 -14
View File
@@ -39,7 +39,6 @@
v-decorator="['callback', {rules: [{required: true, min: 2, message: '请输入至少2个字符'}]}]"
/>
</a-form-item>
<MultiGoods ref="MultiGoods" :goodsList="formData.goods" @change="handleGoodsChange" />
</div>
</div>
@@ -54,12 +53,8 @@
<script>
import * as PartnersApi from '@/api/partners'
import PartnersModel from '@/common/model/partners/Index'
import MultiGoods from './modules/MultiGoods'
export default {
components: {
MultiGoods
},
data () {
return {
// 默认的标签索引
@@ -74,8 +69,7 @@ export default {
// 当前表单元素
form: this.$form.createForm(this),
// 表单数据
formData: PartnersModel.formData,
goodsList: []
formData: PartnersModel.formData
}
},
// 初始化数据
@@ -117,8 +111,6 @@ export default {
this.onTargetTabError(errors)
return false
}
// 整理商品数据
values.goodsList = this.goodsList
// 提交到后端api
this.onFormSubmit(values)
return true
@@ -146,11 +138,6 @@ export default {
.finally(() => {
this.isLoading = false
})
},
handleGoodsChange (val) {
// console.log('最新商品列表:', val)
this.goodsList = val
}
}
+2 -12
View File
@@ -39,7 +39,6 @@
v-decorator="['callback', {rules: [{required: true, min: 2, message: '请输入至少2个字符'}]}]"
/>
</a-form-item>
<MultiGoods ref="MultiGoods" :goodsList="formData.goods" :defaultGoodsList="formData.partners.goodsList" @change="handleGoodsChange" />
</div>
</div>
@@ -55,13 +54,11 @@
import * as PartnersApi from '@/api/partners'
import { InputNumberGroup } from '@/components'
import PartnersModel from '@/common/model/partners/Index'
import MultiGoods from './modules/MultiGoods'
import { isEmptyObject } from '@/utils/util'
export default {
components: {
InputNumberGroup,
MultiGoods
InputNumberGroup
},
data () {
return {
@@ -79,8 +76,7 @@ export default {
// 合作商ID
partnersId: null,
// 表单数据
formData: PartnersModel.formData,
goodsList: []
formData: PartnersModel.formData
}
},
created () {
@@ -137,8 +133,6 @@ export default {
this.onTargetTabError(errors)
return false
}
// 整理商品数据
values.goodsList = this.goodsList
// 提交到后端api
this.onFormSubmit(values)
return true
@@ -172,10 +166,6 @@ export default {
.finally(() => {
this.isLoading = false
})
},
handleGoodsChange (val) {
this.goodsList = val
}
}
@@ -1,273 +0,0 @@
<template>
<div>
<a-form-item
label="对接商品"
:labelCol="labelCol"
:wrapperCol="wrapperCol"
>
<!-- 添加按钮 -->
<div class="sku-batch">
<a-button @click="handleAddGoods">添加商品</a-button>
</div>
<!-- 商品列表 -->
<a-table
class="sku-list"
:columns="columns"
:dataSource="multiGoodsData"
:scroll="{ x: true }"
:pagination="false"
bordered
rowKey="row_id"
>
<!-- 选择商品 -->
<template slot="goods_id" slot-scope="text, item">
<a-select
v-model="item.goods_id"
placeholder="请选择商品"
style="width: 100%"
@change="emitChange"
>
<a-select-option
v-for="(sub_item, index) in goodsList"
:key="index"
:value="sub_item.goods_id"
>
{{ sub_item.goods_name }}
</a-select-option>
</a-select>
</template>
<!-- 分配数量 -->
<template slot="allot_num" slot-scope="text, item">
<a-input-number
v-model="item.allot_num"
size="small"
:precision="0"
@change="emitChange"
/>
</template>
<!-- 库存数量 -->
<template slot="stock_num" slot-scope="text, item">
{{ item.stock_num }}
</template>
<!-- 删除操作 -->
<template slot="action" slot-scope="text, item">
<a @click="handleDelete(item)">删除</a>
</template>
</a-table>
</a-form-item>
</div>
</template>
<script>
import PropTypes from 'ant-design-vue/es/_util/vue-types'
// 表格表头
const columns = [
{
title: '商品',
dataIndex: 'goods_id',
width: 120,
scopedSlots: { customRender: 'goods_id' }
},
{
title: '分配数量',
dataIndex: 'allot_num',
width: 120,
scopedSlots: { customRender: 'allot_num' }
},
{
title: '库存数量',
dataIndex: 'stock_num',
width: 120,
scopedSlots: { customRender: 'stock_num' }
},
{
title: '操作',
dataIndex: 'action',
width: '150px',
scopedSlots: { customRender: 'action' }
}
]
export default {
props: {
goodsList: PropTypes.any,
defaultGoodsList: PropTypes.array.def([]),
isGoodsLocked: PropTypes.bool.def(false)
},
data () {
return {
columns,
labelCol: { span: 3 },
wrapperCol: { span: 21 },
multiGoodsData: []
}
},
watch: {
defaultGoodsList (val) {
if (val.length) {
this.getData()
}
}
},
created () {
this.getData()
},
methods: {
getData () {
this.multiGoodsData = this.defaultGoodsList.map((item, index) => ({
...item,
row_id: item.row_id || Date.now() + index
}))
this.emitChange()
},
handleAddGoods () {
this.multiGoodsData.push({
goods_id: null,
allot_num: 1,
stock_num: 0,
row_id: Date.now()
})
this.emitChange()
},
handleDelete (record) {
this.multiGoodsData = this.multiGoodsData.filter(item => item !== record)
this.emitChange()
},
emitChange () {
this.$emit('change', this.multiGoodsData)
}
}
}
</script>
<style lang="less" scoped>
// 商品多规格
.spec-group {
width: 895px;
margin-bottom: 15px;
line-height: normal;
.ant-input {
height: 28px;
padding: 4px 11px;
font-size: @font-size-base;
line-height: 1.5;
&::placeholder {
font-size: @font-size-base;
}
}
.form-item-help {
line-height: 36px;
}
.spec-group-item {
background: #f4f5f9;
padding: 7px 12px;
line-height: 28px;
.group-item-input {
float: left;
width: 180px;
}
.group-item-delete {
font-size: 12px;
float: right;
}
}
.spec-value {
background: #fbfbfb;
padding: 8px 35px;
.spec-value-add,
.spec-value-item {
float: left;
margin-bottom: 6px;
margin-top: 6px;
}
.spec-value-add {
height: 28px;
line-height: 28px;
a {
font-size: 12px;
}
}
.spec-value-item {
position: relative;
margin-right: 20px;
.value-item-input {
width: 186px;
}
&:hover {
.icon-close {
display: block;
}
}
.icon-close {
display: none;
position: absolute;
top: -8px;
right: -8px;
cursor: pointer;
font-size: 16px;
color: #7d7d7d;
}
}
}
}
// 添加规格按钮
.spec-group-add-btn {
font-size: @font-size-base;
}
// 批量设置sku
.sku-batch {
line-height: 40px;
margin-bottom: 12px;
.title {
line-height: 28px;
margin-right: 15px;
font-size: @font-size-base;
}
/deep/.ant-input,
/deep/.ant-input-number {
width: 120px;
margin-right: 15px;
}
/deep/.ant-input {
width: 140px;
}
}
// sku列表
.sku-list {
width: 895px;
/deep/.ant-table-thead > tr > th,
/deep/.ant-table-tbody > tr > td {
white-space: nowrap;
}
/deep/.ant-table-tbody > tr > td {
padding: 12px 18px;
}
/deep/.ant-input-sm,
/deep/.ant-input-number-sm {
height: 28px;
}
/deep/.ant-input-number-sm input {
height: 26px;
}
}
</style>
@@ -1,9 +1,7 @@
import RechargeForm from './RechargeForm'
import ApiParaForm from './ApiParaForm'
import MultiGoods from '../../partners/modules/MultiGoods'
export {
RechargeForm,
ApiParaForm,
MultiGoods
ApiParaForm
}
+64 -38
View File
@@ -5,13 +5,16 @@
<!-- 搜索板块 -->
<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 label="司机手机号">
<a-input v-decorator="['search']" placeholder="请输入司机手机号" />
</a-form-item>
<a-form-item label="商品编码">
<a-input v-decorator="['goods_no']" placeholder="商品编码" />
<a-form-item label="司机姓名">
<a-input v-decorator="['driver_name']" placeholder="请输入司机姓名" />
</a-form-item>
<a-form-item label="分油状态">
<a-form-item label="单号">
<a-input v-decorator="['orderNo']" placeholder="油卡编号/销售单号/批次号/运单号" />
</a-form-item>
<a-form-item label="发放状态">
<a-select v-decorator="['oil_status', { initialValue: -1 }]">
<a-select-option :value="-1">全部</a-select-option>
<a-select-option
@@ -21,7 +24,15 @@
>{{ item.name }}</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="使用状态">
<a-form-item label="企油通发放态">
<a-select v-decorator="['oil_status_zsy', { initialValue: -1 }]">
<a-select-option :value="-1">全部</a-select-option>
<a-select-option :value="0">未提交</a-select-option>
<a-select-option :value="2">发放成功</a-select-option>
<a-select-option :value="3">发放失败</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="加油核销">
<a-select v-decorator="['use_status', { initialValue: -1 }]">
<a-select-option :value="-1">全部</a-select-option>
<a-select-option
@@ -55,7 +66,7 @@
</a-row>
<!-- 操作板块 -->
<div class="row-item-tab clearfix flex-box">
<span class="form-total">油卡金额:¥{{ total_money }}</span>
<span class="form-total">发放总金额:¥{{ total_money }}</span>
</div>
</div>
<s-table
@@ -66,52 +77,62 @@
:data="loadData"
:pageSize="15"
>
<span slot="goods" slot-scope="text">
<GoodsItem
:data="{
image: text.images[0].file.preview_url,
imageAlt: '商品图片',
title: text.goods_name,
goods_no: text.goods_no,
goodsProps: text.goods_props
}"
/>
</span>
<span slot="partners" slot-scope="text">
<p>{{ text.name }}</p>
</span>
<div slot="driver" slot-scope="item">
<p class="mtb-2">{{ item.driver_name || '-' }}</p>
<p class="mtb-2 f-13">{{ item.mobile }}</p>
</div>
<div slot="qyt" slot-scope="item">
<p class="mtb-2 f-13">批次:{{ item.batch_no || '-' }}</p>
<p class="mtb-2 f-13">运单:{{ item.waybill_no || '-' }}</p>
</div>
<div slot="consume" slot-scope="item">
<template v-if="item.use_status === 1">
<p class="mtb-2 f-13">{{ item.station_name || '-' }}</p>
<p class="mtb-2 f-13">{{ item.oil_name }} {{ item.litter }}L</p>
<p class="mtb-2 f-13">实付:¥{{ (item.pay_fee / 100).toFixed(2) }}</p>
</template>
<span v-else>-</span>
</div>
<div slot="status" slot-scope="item">
<p class="mtb-2">
<span class="f-13">分油状态:</span>
<span class="f-13">发放状态:</span>
<a-tag
:color="item.oil_status == OilStatusEnum.OIL.value ? 'green' : ''"
>{{ OilStatusEnum[item.oil_status].name }}</a-tag>
</p>
<p class="mtb-2">
<span class="f-13">使用状态:</span>
<span class="f-13">加油核销:</span>
<a-tag
:color="item.use_status == UseStatusEnum.USE.value ? 'green' : ''"
>{{ UseStatusEnum[item.use_status].name }}</a-tag>
</p>
<p class="mtb-2">
<span class="f-13">企油通:</span>
<a-tag :color="qytColor(item.oil_status_zsy)">{{ qytText(item.oil_status_zsy) }}</a-tag>
</p>
<p v-if="item.oil_text" class="mtb-2 f-13 order-remark">{{ item.oil_text }}</p>
</div>
<div class="actions" slot="action" slot-scope="item">
<!--有付款权限,订单状态为进行中,已支付,并且未使用-->
<a
v-if="(inArray(item.oil_status_zsy, [3])) && item.oil_status === 0 && item.oilCardType === 'zsy_ticket'"
@click="handleShare(item)"
>手动分油</a>
>重新发放</a>
<a
v-if="(inArray(item.oil_status_zsy, [2])) && item.oil_status === 1 && item.use_status === 0 && item.oilCardType === 'zsy_ticket'"
@click="handlePay(item)"
>付款码</a>
>加油链接</a>
<a
v-if="(inArray(item.oil_status_zsy, [2])) && item.oil_status === 1 && item.oilCardType === 'zsy_ticket'"
@click="handleOil(item)"
>分油结果回调</a>
>重推发放结果</a>
<a
v-if="(inArray(item.oil_status_zsy, [2])) && item.oil_status === 1 && item.use_status === 1 && item.oilCardType === 'zsy_ticket'"
@click="handleUse(item)"
>使用结果回调</a>
>重推加油结果</a>
</div>
</s-table>
<ShareForm ref="ShareForm" @handleSubmit="handleRefresh" />
@@ -123,7 +144,7 @@
<script>
import * as Api from '@/api/partners/order'
import { STable, GoodsItem } from '@/components/Table'
import { STable } from '@/components/Table'
import {
OilStatusEnum, UseStatusEnum
} from '@/common/enum/order'
@@ -136,7 +157,6 @@ export default {
name: 'Index',
components: {
STable,
GoodsItem,
ShareForm,
PayForm,
OilForm,
@@ -162,9 +182,8 @@ export default {
scopedSlots: { customRender: 'oilCardNo' }
},
{
title: '分油记录编号',
dataIndex: 'shareNo',
scopedSlots: { customRender: 'shareNo' }
title: '企油通单号',
scopedSlots: { customRender: 'qyt' }
},
{
title: '对接公司内部销售单号',
@@ -172,23 +191,21 @@ export default {
scopedSlots: { customRender: 'partners_order_no' }
},
{
title: '油卡数量',
title: '数量',
dataIndex: 'total_num',
scopedSlots: { customRender: 'total_num' }
},
{
title: '油卡金额',
title: '发放金额',
dataIndex: 'total_price'
},
{
title: '商品信息',
dataIndex: 'goods',
scopedSlots: { customRender: 'goods' }
title: '司机',
scopedSlots: { customRender: 'driver' }
},
{
title: '手机号',
dataIndex: 'mobile',
scopedSlots: { customRender: 'mobile' }
title: '加油信息',
scopedSlots: { customRender: 'consume' }
},
{
title: '合作商',
@@ -256,7 +273,16 @@ export default {
})
},
// 手动分油
// 企油通发放态文案
qytText (v) {
return { 0: '未提交', 1: '处理中', 2: '发放成功', 3: '发放失败' }[v] || '未知'
},
// 企油通发放态颜色
qytColor (v) {
return { 2: 'green', 3: 'red' }[v] || ''
},
// 重新发放
handleShare (record) {
this.$refs.ShareForm.show(record)
},
@@ -37,7 +37,7 @@ export default {
data () {
return {
// 对话框标题
title: '手动分油',
title: '重推发放结果',
// 标签布局属性
labelCol: { span: 7 },
// 输入框布局属性
@@ -1,18 +1,28 @@
<template>
<a-modal
:title="title"
:width="560"
:width="520"
:visible="visible"
:isLoading="isLoading"
:confirmLoading="isLoading"
:maskClosable="false"
@ok="handleCancel"
@cancel="handleCancel"
>
<a-spin :spinning="isLoading">
<a-form :form="form">
<iframe :src="qrCodeValue" width="200px" height="200px"></iframe>
</a-form>
<div v-if="qrCodeValue" class="qyt-h5">
<div class="qyt-h5__tip">司机扫码即可进入企油通加油页(免登),也可直接把下方链接发给司机。</div>
<div class="qyt-h5__qr">
<vue-qr :text="qrCodeValue" :size="200" :margin="6" />
</div>
<a-input-search
class="qyt-h5__url"
:value="qrCodeValue"
readonly
enter-button="复制"
@search="handleCopy"
/>
</div>
<a-empty v-else description="正在获取加油链接…" />
</a-spin>
</a-modal>
</template>
@@ -28,24 +38,16 @@ export default {
data () {
return {
// 对话框标题
title: '支付码',
// 标签布局属性
labelCol: { span: 7 },
// 输入框布局属性
wrapperCol: { span: 13 },
title: '加油链接',
// modal(对话框)是否可见
visible: false,
// modal(对话框)确定按钮 loading
// 加载中
isLoading: false,
// 当前表单元素
form: this.$form.createForm(this),
// 当前记录
record: {},
// 企油通 H5 免登加油地址
qrCodeValue: ''
}
},
created () {
},
methods: {
@@ -53,47 +55,64 @@ export default {
* 显示对话框
*/
show (record) {
// 显示窗口
this.visible = true
// 当前记录
this.record = record
this.qrCodeValue = ''
this.getQrCode()
},
/**
* 确认按钮
*/
handleSubmit (e) {
e.preventDefault()
// 表单验证
const { form: { validateFields } } = this
validateFields((errors, values) => {
// 提交到后端api
!errors && this.onFormSubmit(values)
})
},
/**
* 关闭对话框事件
*/
handleCancel () {
this.visible = false
this.form.resetFields()
this.qrCodeValue = ''
},
/**
* 获取支付二维码
*/
* 复制链接
*/
handleCopy () {
const input = document.createElement('input')
input.value = this.qrCodeValue
document.body.appendChild(input)
input.select()
document.execCommand('copy')
document.body.removeChild(input)
this.$message.success('链接已复制', 1.5)
},
/**
* 获取企油通 H5 免登加油地址(7.15)
*/
getQrCode () {
this.isLoading = true
Api.qrCode({ orderId: this.record.order_id })
.then((result) => {
// 显示成功
.then(result => {
this.qrCodeValue = result.data.qrCode
})
.finally(() => {
this.isLoading = false
})
}
}
}
</script>
<style lang="less" scoped>
.qyt-h5 {
text-align: center;
&__tip {
color: #969799;
font-size: 13px;
margin-bottom: 12px;
}
&__qr {
margin-bottom: 14px;
}
&__url {
margin-top: 4px;
}
}
</style>
@@ -37,7 +37,7 @@ export default {
data () {
return {
// 对话框标题
title: '手动分油',
title: '重新发放',
// 标签布局属性
labelCol: { span: 7 },
// 输入框布局属性
@@ -37,7 +37,7 @@ export default {
data () {
return {
// 对话框标题
title: '手动分油',
title: '重推加油结果',
// 标签布局属性
labelCol: { span: 7 },
// 输入框布局属性
-13
View File
@@ -9,19 +9,6 @@
<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"
+1 -9
View File
@@ -75,12 +75,10 @@
<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>
@@ -88,7 +86,7 @@
import * as Api from '@/api/user'
import * as GradeApi from '@/api/user/grade'
import { STable } from '@/components'
import { GradeForm, RechargeForm, OilForm } from './modules'
import { GradeForm, RechargeForm } from './modules'
import PlatformIcon from '@/components/PlatformIcon'
export default {
@@ -97,7 +95,6 @@ export default {
STable,
GradeForm,
RechargeForm,
OilForm,
PlatformIcon
},
data () {
@@ -216,11 +213,6 @@ export default {
})
},
// 用户分油
handleOil (item) {
this.$refs.OilForm.handle(item)
},
/**
* 刷新列表
* @param Boolean bool 强制刷新到第一页
-13
View File
@@ -9,19 +9,6 @@
<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"
@@ -1,230 +0,0 @@
<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>
+1 -2
View File
@@ -1,5 +1,4 @@
import GradeForm from './GradeForm'
import RechargeForm from './RechargeForm'
import OilForm from './OilForm'
export { GradeForm, RechargeForm, OilForm }
export { GradeForm, RechargeForm }