init
This commit is contained in:
347
src/views/app_manage/menu_list.vue
Normal file
347
src/views/app_manage/menu_list.vue
Normal file
@@ -0,0 +1,347 @@
|
||||
<template>
|
||||
<div class="card">
|
||||
<el-space>
|
||||
<el-button type="primary" icon="Plus" @click="addHandle">添加菜单</el-button>
|
||||
</el-space>
|
||||
<div class="mt15">
|
||||
<el-space>
|
||||
<el-select placeholder="请选择分组" v-model="tableOptions.navcode">
|
||||
<el-option :value="item.id" :label="item.name" v-for="item in menuGroups" :key="item.id"></el-option>
|
||||
</el-select>
|
||||
<el-select placeholder="请选择导航" v-model="tableOptions.navName">
|
||||
<el-option :value="item.id" :label="item.name" v-for="item in navcodes" :key="item.id"></el-option>
|
||||
</el-select>
|
||||
<el-button type="primary" icon="Search" @click="searchHandle">搜索</el-button>
|
||||
<el-button icon="RefreshRight" @click="resizeTable">重置</el-button>
|
||||
</el-space>
|
||||
</div>
|
||||
<div class="table mt15">
|
||||
<el-table ref="table" :data="tableOptions.list" border height="100%" v-loading="tableOptions.loading">
|
||||
<el-table-column prop="id" label="ID" width="50"></el-table-column>
|
||||
<el-table-column label="图标" width="100">
|
||||
<template #default="scope">
|
||||
<el-image style="width: 50px; height: 50px" :src="scope.row.icon" preview-teleported
|
||||
hide-on-click-modal :preview-src-list="[scope.row.icon]" fit="cover">
|
||||
</el-image>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="menuGroup" label="分组">
|
||||
<template #default="scope">
|
||||
<el-text>{{ menuGroups.find(item => item.id == scope.row.menuGroup).name }}</el-text>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="name" label="名称"></el-table-column>
|
||||
<el-table-column prop="navName" label="导航"></el-table-column>
|
||||
<el-table-column prop="url" label="链接"></el-table-column>
|
||||
<el-table-column label="是否显示" width="100">
|
||||
<template #default="scope">
|
||||
<el-text v-if="scope.row.visible == 0" type="info">不显示</el-text>
|
||||
<el-text v-if="scope.row.visible == 1" type="primary">显示</el-text>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="是否小程序" width="100">
|
||||
<template #default="scope">
|
||||
<el-text v-if="scope.row.isapplets == 0" type="info">否</el-text>
|
||||
<el-text v-if="scope.row.isapplets == 1" type="primary">是</el-text>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="是否uniapp" width="100">
|
||||
<template #default="scope">
|
||||
<el-text v-if="scope.row.isuniapp == 0" type="info">否</el-text>
|
||||
<el-text v-if="scope.row.isuniapp == 1" type="primary">是</el-text>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="显示(安卓/iso)" width="100">
|
||||
<template #default="scope">
|
||||
<el-text v-if="scope.row.isandroidenabled == 0" type="info">否</el-text>
|
||||
<el-text v-if="scope.row.isandroidenabled == 1" type="primary">是</el-text>
|
||||
<el-text type="info">/</el-text>
|
||||
<el-text v-if="scope.row.isiphoneenabled == 0" type="info">否</el-text>
|
||||
<el-text v-if="scope.row.isiphoneenabled == 1" type="primary">是</el-text>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="username" label="小程序ID"></el-table-column>
|
||||
<el-table-column prop="path" label="跳转路径/uniApp路径"></el-table-column>
|
||||
<el-table-column prop="createTime" label="创建时间">
|
||||
<template #default="scope">
|
||||
{{ dayjs(scope.row.createTime).format('YYYY-MM-DD HH:mm:ss') }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="updateTime" label="更新时间">
|
||||
<template #default="scope">
|
||||
{{ dayjs(scope.row.updateTime).format('YYYY-MM-DD HH:mm:ss') }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="140">
|
||||
<template #default="scope">
|
||||
<el-button type="primary" size="small" icon="EditPen">编辑</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="mt15">
|
||||
<el-pagination layout="prev, pager, next, total, sizes, jumper" background
|
||||
v-model:current-page="tableOptions.pageNum" v-model:page-size="tableOptions.pageSzie"
|
||||
:page-size="tableOptions.pageSzie" :page-sizes="[10, 20, 30, 50]" :total="tableOptions.total"
|
||||
@size-change="paginationChange" @current-change="paginationChange" />
|
||||
</div>
|
||||
</div>
|
||||
<el-dialog title="增加菜单" v-model="showDialog" @closed="dialogClosed">
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="100">
|
||||
<el-form-item prop="name" label="菜单名称">
|
||||
<el-input placeholder="请输入菜单名称" v-model="form.name" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="code" label="菜单code">
|
||||
<el-input placeholder="请输入菜单code" v-model="form.code" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="sort" label="排序">
|
||||
<el-input placeholder="请输入菜单排序" v-model="form.sort" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="url" label="图片url">
|
||||
<el-upload ref="uploadRef" v-model:file-list="fileList" :limit="1" :on-exceed="handleExceed"
|
||||
list-type="picture" :auto-upload="false" @change="selectFile" @remove="removeFile">
|
||||
<template #trigger>
|
||||
<el-button type="primary" icon="Picture">选择图片</el-button>
|
||||
</template>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
<el-form-item prop="navcode" label="导航">
|
||||
<el-select v-model="form.navcode">
|
||||
<el-option :label="item.name" :value="item.id" v-for="item in navcodes" :key="item.id"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item prop="menuGroup" label="分组">
|
||||
<el-select v-model="form.menuGroup">
|
||||
<el-option :label="item.name" :value="item.id" v-for="item in menuGroups" :key="item.id"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item prop="type" label="是否显示">
|
||||
<el-radio-group v-model="form.visible">
|
||||
<el-radio :label="1">是</el-radio>
|
||||
<el-radio :label="0">否</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item prop="type" label="安卓是否显示">
|
||||
<el-radio-group v-model="form.isAndroidEnabled">
|
||||
<el-radio :label="1">是</el-radio>
|
||||
<el-radio :label="0">否</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item prop="type" label="ios是否显示">
|
||||
<el-radio-group v-model="form.isIphoneEnabled">
|
||||
<el-radio :label="1">是</el-radio>
|
||||
<el-radio :label="0">否</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-space>
|
||||
<el-button @click="showDialog = false">取消</el-button>
|
||||
<el-button type="primary" :loading="formLoading" @click="submitHandle">提交</el-button>
|
||||
</el-space>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { dayjs } from 'element-plus';
|
||||
import { appMenuPage, getDictGroup, uploadOSS, appMenuSave } from '@/api/home.js'
|
||||
import { onMounted, reactive } from 'vue';
|
||||
|
||||
const table = ref(null)
|
||||
const navcodes = ref([])
|
||||
const menuGroups = ref([])
|
||||
// 表格参数
|
||||
const tableOptions = reactive({
|
||||
loading: true,
|
||||
navcode: '',
|
||||
navName: '',
|
||||
list: [],
|
||||
total: 0,
|
||||
pageNum: 1,
|
||||
pageSzie: 10
|
||||
})
|
||||
|
||||
// 添加菜单
|
||||
function addHandle() {
|
||||
showDialog.value = true
|
||||
}
|
||||
|
||||
// 重置表格
|
||||
function resizeTable() {
|
||||
tableOptions.navcode = ''
|
||||
tableOptions.navName = ''
|
||||
searchHandle()
|
||||
}
|
||||
|
||||
// 搜索
|
||||
function searchHandle() {
|
||||
tableOptions.pageNum = 1;
|
||||
paginationChange()
|
||||
}
|
||||
// 分页回调
|
||||
function paginationChange() {
|
||||
tableOptions.loading = true
|
||||
appMenuPageAjax()
|
||||
}
|
||||
|
||||
// app菜单list
|
||||
async function appMenuPageAjax() {
|
||||
try {
|
||||
const res = await appMenuPage({
|
||||
page: tableOptions.pageNum,
|
||||
size: tableOptions.pageSzie
|
||||
})
|
||||
tableOptions.loading = false
|
||||
tableOptions.list = res.list
|
||||
tableOptions.total = res.total
|
||||
table.value.setScrollTop(0)
|
||||
} catch (error) { }
|
||||
}
|
||||
|
||||
// 获取分组字典值
|
||||
async function getMenuGrounp() {
|
||||
try {
|
||||
const res = await getDictGroup('APP_MENU_GROUP')
|
||||
menuGroups.value = res
|
||||
} catch (error) { }
|
||||
}
|
||||
// 获取导航字典值
|
||||
async function getNavCodes() {
|
||||
try {
|
||||
const res = await getDictGroup('APP_MENU_NAV')
|
||||
navcodes.value = res
|
||||
} catch (error) { }
|
||||
}
|
||||
|
||||
// 显示添加表单
|
||||
const showDialog = ref(false)
|
||||
const formLoading = ref(false)
|
||||
const formRef = ref(null)
|
||||
const fileList = ref([])
|
||||
|
||||
// 创建表单
|
||||
const form = reactive({
|
||||
name: '', // 菜单名称
|
||||
code: '', // 菜单code
|
||||
sort: '', // 排序
|
||||
url: '', // 图标
|
||||
navcode: '', // 导航选择
|
||||
menuGroup: '', // 分组
|
||||
visible: 1, // 是否显示0否1是
|
||||
isAndroidEnabled: 1, // 安卓是否显示
|
||||
isIphoneEnabled: 1, // ios是否显示
|
||||
})
|
||||
|
||||
|
||||
// 校验是否选择图片
|
||||
const imgValidate = (rule, value, callback) => {
|
||||
if (fileList.value.length <= 0) {
|
||||
return callback(new Error('请选择图片'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
|
||||
// 表单校验规则
|
||||
const rules = reactive({
|
||||
name: [
|
||||
{
|
||||
required: true,
|
||||
message: '',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
code: [
|
||||
{
|
||||
required: true,
|
||||
message: '',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
sort: [
|
||||
{
|
||||
required: true,
|
||||
message: '',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
url: [
|
||||
{
|
||||
required: true,
|
||||
validator: imgValidate,
|
||||
trigger: 'change'
|
||||
}
|
||||
],
|
||||
navcode: [
|
||||
{
|
||||
required: true,
|
||||
message: '',
|
||||
trigger: 'change'
|
||||
}
|
||||
],
|
||||
menuGroup: [
|
||||
{
|
||||
required: true,
|
||||
message: '',
|
||||
trigger: 'change'
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
// 只能选择一个文件,替换之前的文件
|
||||
const handleExceed = (files) => {
|
||||
uploadRef.value.clearFiles()
|
||||
const file = files[0]
|
||||
file.uid = genFileId()
|
||||
uploadRef.value.handleStart(file)
|
||||
form.url = ''
|
||||
}
|
||||
|
||||
// 选择图片
|
||||
const selectFile = async (file) => {
|
||||
fileList.value = [file]
|
||||
}
|
||||
|
||||
// 移除图片
|
||||
const removeFile = async () => {
|
||||
fileList.value = []
|
||||
form.url = ''
|
||||
}
|
||||
|
||||
// 表单关闭
|
||||
function dialogClosed() {
|
||||
formRef.value.resetFields()
|
||||
fileList.value = []
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const submitHandle = async () => {
|
||||
await formRef.value.validate(async (vaild) => {
|
||||
if (vaild) {
|
||||
try {
|
||||
formLoading.value = true
|
||||
form.url = await uploadOSS(fileList.value[0].raw)
|
||||
await appMenuSave(form)
|
||||
formLoading.value = false
|
||||
showDialog.value = false
|
||||
ElMessage.success('添加成功')
|
||||
paginationChange()
|
||||
} catch (error) {
|
||||
formLoading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await getMenuGrounp()
|
||||
await getNavCodes()
|
||||
await appMenuPageAjax()
|
||||
})
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.table {
|
||||
height: calc(100vh - 356px);
|
||||
}
|
||||
</style>
|
||||
12
src/views/demo/demo11.vue
Normal file
12
src/views/demo/demo11.vue
Normal file
@@ -0,0 +1,12 @@
|
||||
<template>
|
||||
<div class="demo">
|
||||
<h2>demo11</h2>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
let aa = ref('')
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
12
src/views/demo/demo12.vue
Normal file
12
src/views/demo/demo12.vue
Normal file
@@ -0,0 +1,12 @@
|
||||
<template>
|
||||
<div class="demo">
|
||||
<h2>demo12</h2>
|
||||
<router-view></router-view>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
let aa = ref("");
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
11
src/views/demo/demo121.vue
Normal file
11
src/views/demo/demo121.vue
Normal file
@@ -0,0 +1,11 @@
|
||||
<template>
|
||||
<div class="demo">
|
||||
<h2>demo121</h2>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
let aa = ref("");
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
9
src/views/demo/demo122.vue
Normal file
9
src/views/demo/demo122.vue
Normal file
@@ -0,0 +1,9 @@
|
||||
<template>
|
||||
<div class="demo">
|
||||
<h2>demo122</h2>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup></script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
12
src/views/demo/demo13.vue
Normal file
12
src/views/demo/demo13.vue
Normal file
@@ -0,0 +1,12 @@
|
||||
<template>
|
||||
<div class="demo">
|
||||
<h2>demo13</h2>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
let aa = ref('')
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
11
src/views/demo/demo21.vue
Normal file
11
src/views/demo/demo21.vue
Normal file
@@ -0,0 +1,11 @@
|
||||
<template>
|
||||
<div class="demo">
|
||||
<h2>demo21</h2>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
let aa = ref('')
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
11
src/views/demo/demo22.vue
Normal file
11
src/views/demo/demo22.vue
Normal file
@@ -0,0 +1,11 @@
|
||||
<template>
|
||||
<div class="demo">
|
||||
<h2>demo22</h2>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
let aa = ref('')
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
11
src/views/demo/demo23.vue
Normal file
11
src/views/demo/demo23.vue
Normal file
@@ -0,0 +1,11 @@
|
||||
<template>
|
||||
<div class="demo">
|
||||
<h2>demo23</h2>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
let aa = ref('')
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
200
src/views/device/device_list.vue
Normal file
200
src/views/device/device_list.vue
Normal file
@@ -0,0 +1,200 @@
|
||||
<template>
|
||||
<div class="card">
|
||||
<div class="data_row">
|
||||
<div class="item">
|
||||
<div class="icon">
|
||||
<img class="img" src="@/assets/icon_dev1.png">
|
||||
</div>
|
||||
<div class="info">
|
||||
<div class="title">总设备数</div>
|
||||
<div class="num">
|
||||
<count-to :start-val="0" :end-val="deviceData.sumCount" :duration="1000" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="icon">
|
||||
<img class="img" src="@/assets/icon_dev2.png">
|
||||
</div>
|
||||
<div class="info">
|
||||
<div class="title">已激活数</div>
|
||||
<div class="num">
|
||||
<count-to :start-val="0" :end-val="deviceData.activityCount" :duration="1000" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="icon">
|
||||
<img class="img" src="@/assets/icon_dev3.png">
|
||||
</div>
|
||||
<div class="info">
|
||||
<div class="title">未激活数</div>
|
||||
<div class="num">
|
||||
<count-to :start-val="0" :end-val="deviceData.sellCount" :duration="1000" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card mt15">
|
||||
<el-space class="pb15">
|
||||
<el-input placeholder="请输入商户编号搜索" v-model="tableOptions.merchantCode" style="width: 200px;" />
|
||||
<el-button type="primary" icon="Search" @click="searchHandle">搜索</el-button>
|
||||
</el-space>
|
||||
<div class="table">
|
||||
<el-table :data="tableOptions.list" size="large" stripe border height="100%" v-loading="tableOptions.loading">
|
||||
<el-table-column prop="merchantCode" label="商户号"></el-table-column>
|
||||
<el-table-column prop="snNo" label="设备号"></el-table-column>
|
||||
<el-table-column prop="actMercName" label="商户名"></el-table-column>
|
||||
<el-table-column prop="phone" label="联系电话"></el-table-column>
|
||||
<el-table-column prop="status" label="激活状态">
|
||||
<template #default="scope">
|
||||
<el-tag type="success" disable-transitions v-if="scope.row.status == 3">已激活</el-tag>
|
||||
<el-tag type="warning" disable-transitions v-else>未激活</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="countSum" label="收单笔数"></el-table-column>
|
||||
<el-table-column prop="consumeFee" label="收单总额"></el-table-column>
|
||||
<el-table-column prop="loginName" label="上级名称"></el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="mt15">
|
||||
<el-pagination layout="prev, pager, next, total, sizes, jumper" background
|
||||
v-model:current-page="tableOptions.pageNum" v-model:page-size="tableOptions.pageSzie"
|
||||
:page-size="tableOptions.pageSzie" :page-sizes="[10, 20, 30, 50]" :total="tableOptions.total"
|
||||
@size-change="paginationChange" @current-change="paginationChange" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onMounted, reactive } from 'vue';
|
||||
import { getSumDeviceStock, getDeviceStockInfo } from '@/api/device.js'
|
||||
|
||||
const deviceData = reactive({
|
||||
sumCount: 0,
|
||||
activityCount: 0,
|
||||
sellCount: 0
|
||||
})
|
||||
|
||||
// 表格参数
|
||||
const tableOptions = reactive({
|
||||
loading: true,
|
||||
merchantCode: '',
|
||||
list: [],
|
||||
total: 0,
|
||||
pageNum: 1,
|
||||
pageSzie: 10
|
||||
})
|
||||
|
||||
// 搜索
|
||||
function searchHandle() {
|
||||
tableOptions.pageNum = 1;
|
||||
paginationChange()
|
||||
}
|
||||
|
||||
// 分页回调
|
||||
function paginationChange() {
|
||||
tableOptions.loading = true
|
||||
getDeviceStockInfoHandle()
|
||||
}
|
||||
|
||||
// 获取当前用户设备总数
|
||||
async function getSumDeviceStockHandle() {
|
||||
try {
|
||||
const { sumCount, activityCount, sellCount } = await getSumDeviceStock()
|
||||
deviceData.sumCount = sumCount
|
||||
deviceData.activityCount = activityCount
|
||||
deviceData.sellCount = sellCount
|
||||
} catch (error) { }
|
||||
}
|
||||
|
||||
// 获取设备列表
|
||||
async function getDeviceStockInfoHandle() {
|
||||
try {
|
||||
const { total, list } = await getDeviceStockInfo({
|
||||
merchantCode: tableOptions.merchantCode,
|
||||
pageNum: tableOptions.pageNum,
|
||||
pageSize: tableOptions.pageSzie
|
||||
})
|
||||
tableOptions.loading = false
|
||||
tableOptions.total = total
|
||||
tableOptions.list = list
|
||||
} catch (error) {
|
||||
tableOptions.loading = false
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getSumDeviceStockHandle()
|
||||
getDeviceStockInfoHandle()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.table {
|
||||
height: calc(100vh - 456px);
|
||||
}
|
||||
|
||||
.data_row {
|
||||
display: flex;
|
||||
padding: 24px 0;
|
||||
|
||||
.item {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
padding-left: 50px;
|
||||
|
||||
&:not(:last-child) {
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
height: 100%;
|
||||
border-right: 1px solid #ececec;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.icon {
|
||||
$size: 50px;
|
||||
width: $size;
|
||||
height: $size;
|
||||
|
||||
.img {
|
||||
width: $size;
|
||||
height: $size;
|
||||
}
|
||||
}
|
||||
|
||||
.info {
|
||||
flex: 1;
|
||||
padding-left: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
|
||||
.title {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.num {
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
padding-top: 10px;
|
||||
|
||||
.i {
|
||||
font-size: 12px;
|
||||
position: relative;
|
||||
bottom: 1px;
|
||||
right: -4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
10
src/views/error/401.vue
Normal file
10
src/views/error/401.vue
Normal file
@@ -0,0 +1,10 @@
|
||||
<template>
|
||||
<div class="401">
|
||||
<h1>401</h1>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
44
src/views/error/404.vue
Normal file
44
src/views/error/404.vue
Normal file
@@ -0,0 +1,44 @@
|
||||
<template>
|
||||
<div class="empty-404">
|
||||
<img src="../../assets/images/404.png">
|
||||
<p class="tips">您访问的页面不存在</p>
|
||||
<el-button @click="goRoute">{{ countDown }}s 返回</el-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const router = useRouter()
|
||||
function goRoute() {
|
||||
router.push('/home');
|
||||
}
|
||||
let countDown = ref(5)
|
||||
let timer = setInterval(() => {
|
||||
countDown.value--
|
||||
if (countDown.value == 0) {
|
||||
goRoute()
|
||||
}
|
||||
}, 1000)
|
||||
onUnmounted(() => {
|
||||
clearInterval(timer)
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.empty-404 {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.tips {
|
||||
font-size: 40px;
|
||||
line-height: 100px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
215
src/views/home.vue
Normal file
215
src/views/home.vue
Normal file
@@ -0,0 +1,215 @@
|
||||
<template>
|
||||
<div class="card">
|
||||
<div class="header_title">
|
||||
欢迎回来!{{ storeUser.userInfo.loginName }}
|
||||
</div>
|
||||
<div class="data_row">
|
||||
<div class="item">
|
||||
<div class="icon">
|
||||
<img class="img" src="../assets/home_icon1.png">
|
||||
</div>
|
||||
<div class="info">
|
||||
<div class="title">团队总流水</div>
|
||||
<div class="num">
|
||||
<count-to :start-val="0" :decimals="2" :end-val="homeData.sumConsumeFee" :duration="1000" />
|
||||
<!-- {{ homeData.sumConsumeFee }} -->
|
||||
<span class="i">元</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="icon">
|
||||
<img class="img" src="../assets/home_icon2.png">
|
||||
</div>
|
||||
<div class="info">
|
||||
<div class="title">总收益</div>
|
||||
<div class="num">
|
||||
<count-to :start-val="0" :decimals="2" :end-val="homeData.sumfansShareMoney" :duration="1000" />
|
||||
<span class="i">元</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="icon">
|
||||
<img class="img" src="../assets/home_icon3.png">
|
||||
</div>
|
||||
<div class="info">
|
||||
<div class="title">今日收益</div>
|
||||
<div class="num">
|
||||
<count-to :start-val="0" :decimals="2" :end-val="homeData.yestedayShareMoney" :duration="1000" />
|
||||
<span class="i">元</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="icon">
|
||||
<img class="img" src="../assets/home_icon4.png">
|
||||
</div>
|
||||
<div class="info">
|
||||
<div class="title">推广费率</div>
|
||||
<div class="num">
|
||||
{{ homeData.currentFee }}
|
||||
<span class="i">%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card mt15">
|
||||
<chart-card :user-id="storeUser.userInfo.userId" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { getIndexData } from '@/api/home.js'
|
||||
import { useUser } from "@/store/user.js";
|
||||
import chartCard from '@/components/chartCard.vue';
|
||||
|
||||
const storeUser = useUser();
|
||||
|
||||
let homeData = reactive({
|
||||
sumConsumeFee: 0,
|
||||
sumfansShareMoney: 0,
|
||||
yestedayShareMoney: 0,
|
||||
currentFee: 0
|
||||
})
|
||||
|
||||
// 获取首页数据
|
||||
async function getIndexDataHandle() {
|
||||
try {
|
||||
const res = await getIndexData()
|
||||
homeData.sumConsumeFee = res.sumConsumeFee
|
||||
homeData.sumfansShareMoney = res.sumfansShareMoney
|
||||
homeData.yestedayShareMoney = res.yestedayShareMoney
|
||||
homeData.currentFee = res.currentFee
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getIndexDataHandle()
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.header_title {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
padding: 15px 0 30px 0;
|
||||
border-bottom: 1px solid #ececec;
|
||||
}
|
||||
|
||||
.data_row {
|
||||
display: flex;
|
||||
padding: 50px 0;
|
||||
|
||||
.item {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
padding-left: 50px;
|
||||
|
||||
&:not(:last-child) {
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
height: 100%;
|
||||
border-right: 1px solid #ececec;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.icon {
|
||||
$size: 55px;
|
||||
width: $size;
|
||||
height: $size;
|
||||
border-radius: 50%;
|
||||
background-color: #F2F3F5;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.img {
|
||||
$size: 30px;
|
||||
width: $size;
|
||||
height: $size;
|
||||
object-fit: contain;
|
||||
}
|
||||
}
|
||||
|
||||
.info {
|
||||
flex: 1;
|
||||
padding-left: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
|
||||
.title {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.num {
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
padding-top: 10px;
|
||||
|
||||
.i {
|
||||
font-size: 12px;
|
||||
position: relative;
|
||||
bottom: 1px;
|
||||
right: -4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.userInfo {
|
||||
padding: 20px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0 20px;
|
||||
border: 1px solid #eee;
|
||||
background-color: #fff;
|
||||
|
||||
.name {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
.charts-case {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
grid-template-rows: repeat(2, 1fr);
|
||||
gap: 10px;
|
||||
grid-template-areas:
|
||||
"a b"
|
||||
"c c";
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.charts-chunk {
|
||||
border: 1px solid #eee;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.charts-chunk:nth-child(0) {
|
||||
grid-area: a;
|
||||
}
|
||||
|
||||
.charts-chunk:nth-child(1) {
|
||||
grid-area: b;
|
||||
}
|
||||
|
||||
.charts-chunk:last-child {
|
||||
grid-area: c;
|
||||
}
|
||||
</style>
|
||||
3
src/views/layout/bridge.vue
Normal file
3
src/views/layout/bridge.vue
Normal file
@@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<router-view></router-view>
|
||||
</template>
|
||||
219
src/views/layout/components/configure.vue
Normal file
219
src/views/layout/components/configure.vue
Normal file
@@ -0,0 +1,219 @@
|
||||
<template>
|
||||
<el-drawer class="vab-drawer" size="400px" :model-value="props.modelValue" :before-close="close">
|
||||
<template #header>
|
||||
<h4>配置</h4>
|
||||
</template>
|
||||
<template #default>
|
||||
<el-divider>
|
||||
<span>布局切换</span>
|
||||
</el-divider>
|
||||
<el-row :gutter="10" class="vab-row">
|
||||
<el-col :span="9" class="list-title"> 布局 </el-col>
|
||||
<el-col :span="15">
|
||||
<el-select v-model="getConfigure.menuMode" placeholder="请选择布局" @change="changeMenuMode(getConfigure.menuMode)">
|
||||
<el-option v-for="(item, index) in layoutModeEnum.key" :key="item" :label="layoutModeEnum.value[index]" :value="item" />
|
||||
</el-select>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-divider>
|
||||
<span>主题配置</span>
|
||||
</el-divider>
|
||||
<el-row :gutter="10" class="vab-row">
|
||||
<el-col :span="9" class="list-title"> 主题色 </el-col>
|
||||
<el-col :span="15">
|
||||
<el-color-picker v-model="getConfigure.themeColor" @change="setConfigure('themeColor')" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-divider>
|
||||
<span>标签</span>
|
||||
</el-divider>
|
||||
<el-row :gutter="10" class="vab-row">
|
||||
<el-col :span="9" class="list-title"> 标签风格 </el-col>
|
||||
<el-col :span="15">
|
||||
<el-select v-model="getConfigure.navbarMode" placeholder="请选择布局">
|
||||
<el-option v-for="(item, index) in navbarModeEnum.key" :key="item" :label="navbarModeEnum.value[index]" :value="item" />
|
||||
</el-select>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="10" class="vab-row">
|
||||
<el-col :span="9" class="list-title"> 标签图标 </el-col>
|
||||
<el-col :span="15">
|
||||
<el-switch v-model="getConfigure.navbarIcon" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-divider>
|
||||
<span>菜单</span>
|
||||
</el-divider>
|
||||
<el-row :gutter="10" class="vab-row">
|
||||
<el-col :span="9" class="list-title"> 菜单背景 </el-col>
|
||||
<el-col :span="15">
|
||||
<el-color-picker v-if="getConfigure.menuMode == layoutModeEnum.key[0]" v-model="getConfigure.menuBGColor" @change="setConfigure('menuBGColor')" />
|
||||
<el-color-picker v-else-if="getConfigure.menuMode == layoutModeEnum.key[1]" v-model="getConfigure.columnBgColor" @change="setConfigure('columnBgColor')" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="10" class="vab-row">
|
||||
<el-col :span="9" class="list-title"> 菜单文字颜色 </el-col>
|
||||
<el-col :span="15">
|
||||
<el-color-picker v-model="getConfigure.textColor" @change="setConfigure('textColor')" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="10" class="vab-row">
|
||||
<el-col :span="9" class="list-title"> 菜单活跃文字颜色 </el-col>
|
||||
<el-col :span="15">
|
||||
<el-color-picker v-model="getConfigure.activeTextColor" @change="setConfigure('activeTextColor')" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="10" class="vab-row">
|
||||
<el-col :span="9" class="list-title">菜单的 Logo</el-col>
|
||||
<el-col :span="15">
|
||||
<el-switch v-model="getConfigure.showMenuLogo" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-divider>
|
||||
<span>过度</span>
|
||||
</el-divider>
|
||||
<el-row :gutter="10" class="vab-row">
|
||||
<el-col :span="9" class="list-title">
|
||||
组件切换过度
|
||||
<el-tooltip class="box-item" effect="dark" content="开启组件切换过渡时,组件只能有一个根元素。" placement="top">
|
||||
<SvgIcon name="QuestionFilled" color="#909399" style="margin-left: 5px"></SvgIcon>
|
||||
</el-tooltip>
|
||||
</el-col>
|
||||
<el-col :span="15">
|
||||
<el-switch v-model="getConfigure.componentTransition" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="10" class="vab-row">
|
||||
<el-col :span="9" class="list-title">组件过渡</el-col>
|
||||
<el-col :span="15">
|
||||
<el-select v-model="getConfigure.componentTransitionMode" placeholder="请选择过度模式">
|
||||
<el-option v-for="(item, index) in componentTransitionEnum.key" :key="item" :label="componentTransitionEnum.value[index]" :value="item" />
|
||||
</el-select>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
<template #footer>
|
||||
<div style="flex: auto">
|
||||
<el-button type="primary" @click="confirm">保存</el-button>
|
||||
<el-button @click="recovery">恢复默认</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-drawer>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useConfigure } from "@/store/configure.js";
|
||||
|
||||
// 控制组件的显示
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
const emits = defineEmits(["update:modelValue"]);
|
||||
function close() {
|
||||
emits("update:modelValue", !props.modelValue);
|
||||
}
|
||||
|
||||
// 获取配置
|
||||
const storeConfigure = useConfigure();
|
||||
const { configure } = storeToRefs(storeConfigure);
|
||||
const getConfigure = computed(() => {
|
||||
return configure.value;
|
||||
});
|
||||
|
||||
// 获取枚举值
|
||||
const { layoutModeEnum, navbarModeEnum, setColorEnum, componentTransitionEnum } = ENUMS;
|
||||
|
||||
// 切换侧边导航的布局
|
||||
function changeMenuMode(mode) {
|
||||
switch (mode) {
|
||||
case layoutModeEnum.key[0]:
|
||||
_hook.useCssVar("--el-menu-bg-color", storeConfigure.configure.menuBGColor);
|
||||
break;
|
||||
case layoutModeEnum.key[1]:
|
||||
_hook.useCssVar("--el-menu-bg-color", "#ffffff");
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
// 设置配置
|
||||
function setConfigure(type) {
|
||||
_hook.useCssVar(setColorEnum[type], getConfigure.value[type]);
|
||||
switch (type) {
|
||||
case "themeColor":
|
||||
_hook.useCssVar("--el-menu-hover-bg-color", storeConfigure.configure.themeColor);
|
||||
[3, 5, 7, 8, 9].forEach((i) => {
|
||||
_hook.useCssVar(`--el-color-primary-light-${i}`, _hook.useLightColor(getConfigure.value[type], `0.${i}`));
|
||||
});
|
||||
break;
|
||||
case "menuBGColor":
|
||||
storeConfigure.change("columnBgColor", storeConfigure.configure.menuBGColor);
|
||||
_hook.useCssVar("--admin-column-bg-color", storeConfigure.configure.menuBGColor);
|
||||
break;
|
||||
case "columnBgColor":
|
||||
storeConfigure.change("menuBGColor", storeConfigure.configure.columnBgColor);
|
||||
break;
|
||||
case "activeTextColor":
|
||||
_hook.useCssVar("--el-menu-hover-text-color", storeConfigure.configure.activeTextColor);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
// 保存配置
|
||||
function confirm() {
|
||||
_hook.useLocalStorage.set("configure", storeConfigure.configure);
|
||||
ElMessage({
|
||||
message: "配置保存成功",
|
||||
type: "success",
|
||||
});
|
||||
}
|
||||
|
||||
// 恢复默认
|
||||
function recovery() {
|
||||
_hook.useLocalStorage.remove("configure");
|
||||
storeConfigure.$reset();
|
||||
|
||||
// 初始化颜色
|
||||
_hook.useCssVar("--el-color-primary", storeConfigure.configure.themeColor);
|
||||
switch (storeConfigure.configure.menuMode) {
|
||||
case layoutModeEnum.key[0]:
|
||||
_hook.useCssVar("--el-menu-bg-color", storeConfigure.configure.menuBGColor);
|
||||
break;
|
||||
case layoutModeEnum.key[1]:
|
||||
_hook.useCssVar("--el-menu-bg-color", "#ffffff");
|
||||
break;
|
||||
default:
|
||||
}
|
||||
_hook.useCssVar("--admin-column-bg-color", storeConfigure.configure.menuBGColor);
|
||||
_hook.useCssVar("--el-menu-text-color", storeConfigure.configure.textColor);
|
||||
_hook.useCssVar("--el-menu-active-color", storeConfigure.configure.activeTextColor);
|
||||
[3, 5, 7, 8, 9].forEach((i) => {
|
||||
_hook.useCssVar(`--el-color-primary-light-${i}`, _hook.useLightColor(storeConfigure.configure.themeColor, `0.${i}`));
|
||||
});
|
||||
|
||||
ElMessage({
|
||||
message: "配置已恢复默认",
|
||||
type: "success",
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.vab-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.list-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 15px;
|
||||
line-height: 1;
|
||||
color: --el-text-color-secondary;
|
||||
}
|
||||
</style>
|
||||
121
src/views/layout/components/navBar.vue
Normal file
121
src/views/layout/components/navBar.vue
Normal file
@@ -0,0 +1,121 @@
|
||||
<template>
|
||||
<div class="navbar-case">
|
||||
<Transition name="navbar" mode="out-in">
|
||||
<navbar-mode-a v-if="configure.navbarMode == navbarModeEnum.key[0]"></navbar-mode-a>
|
||||
<navbar-mode-b v-else-if="configure.navbarMode == navbarModeEnum.key[1]"></navbar-mode-b>
|
||||
<navbar-mode-c v-else-if="configure.navbarMode == navbarModeEnum.key[2]"></navbar-mode-c>
|
||||
</Transition>
|
||||
<div class="menu">
|
||||
<el-dropdown @visible-change="changeDropdownVisible">
|
||||
<div class="flex align-center" style="gap: 0 10px">
|
||||
<SvgIcon class="menu-icon" :style="menuIconStyle" name="Menu"></SvgIcon>
|
||||
</div>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item v-for="item in menuItem" :key="item.title" @click="setNavList(item.type)">
|
||||
<SvgIcon :name="item.icon"></SvgIcon>
|
||||
<span>{{ item.title }}</span>
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import navbarModeA from "./navbar-modeA.vue";
|
||||
import navbarModeB from "./navbar-modeB.vue";
|
||||
import navbarModeC from "./navbar-modeC.vue";
|
||||
import { useConfigure } from "@/store/configure.js";
|
||||
import { useRoutes } from "@/store/routes.js";
|
||||
const storeRoutes = useRoutes();
|
||||
|
||||
// 获取枚举值
|
||||
const { navbarModeEnum } = ENUMS;
|
||||
|
||||
// 获取配置
|
||||
const storeConfigure = useConfigure();
|
||||
const { configure } = storeToRefs(storeConfigure);
|
||||
|
||||
// 下拉菜单
|
||||
let menuItem = [
|
||||
{
|
||||
title: "关闭其他",
|
||||
icon: "Close",
|
||||
type: "else",
|
||||
},
|
||||
{
|
||||
title: "关闭左侧",
|
||||
icon: "Back",
|
||||
type: "left",
|
||||
},
|
||||
{
|
||||
title: "关闭右侧",
|
||||
icon: "Right",
|
||||
type: "right",
|
||||
},
|
||||
{
|
||||
title: "关闭全部",
|
||||
icon: "Close",
|
||||
type: "all",
|
||||
},
|
||||
];
|
||||
let menuIconStyle = reactive({
|
||||
transform: `rotate(0deg)`,
|
||||
color: "",
|
||||
});
|
||||
|
||||
/**
|
||||
* @description: 下拉菜单的显示与隐藏
|
||||
* @param {Bool} bool: true显示 false隐藏
|
||||
*/
|
||||
function changeDropdownVisible(bool) {
|
||||
menuIconStyle.transform = bool ? "rotate(45deg)" : "rotate(0deg)";
|
||||
menuIconStyle.color = bool ? storeConfigure.configure.themeColor : "";
|
||||
}
|
||||
|
||||
// 设置 nav 的列表
|
||||
const router = useRouter();
|
||||
function setNavList(type) {
|
||||
storeRoutes.setNavList(type).then(() => {
|
||||
router.push("/");
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// 导航栏动画
|
||||
.navbar-enter-active,
|
||||
.navbar-leave-active {
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
|
||||
.navbar-enter-from,
|
||||
.navbar-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.navbar-case {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
background-color: var(--el-color-info-light-9);
|
||||
}
|
||||
|
||||
.menu {
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
// background-color: var(--el-bg-color);
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
|
||||
.menu-icon {
|
||||
font-size: 20px;
|
||||
color: var(--el-text-color-secondary);
|
||||
transition: all 0.3s;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
169
src/views/layout/components/navbar-modeA.vue
Normal file
169
src/views/layout/components/navbar-modeA.vue
Normal file
@@ -0,0 +1,169 @@
|
||||
<template>
|
||||
<div class="navBar-list-mode-a">
|
||||
<div :class="[storeRoutes.activeRoute == item[0] ? 'list-active' : 'list']" @click="goRoute(item[0])"
|
||||
v-for="item in storeRoutes.navList">
|
||||
<SvgIcon class="list-icon" v-if="storeConfigure.configure.navbarIcon" :name="item[1]?.meta?.icon"></SvgIcon>
|
||||
<span class="list-title">{{ item[1]?.meta?.title || item[0] }}</span>
|
||||
<SvgIcon class="list-close" name="Close" v-if="item[0] !== '/home'" @click.stop="closeNavbarItem(item[0])">
|
||||
</SvgIcon>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useRoutes } from '@/store/routes.js'
|
||||
import { useConfigure } from '@/store/configure.js'
|
||||
const storeRoutes = useRoutes()
|
||||
const storeConfigure = useConfigure()
|
||||
const router = useRouter()
|
||||
|
||||
/**
|
||||
* @description: 路由跳转
|
||||
* @param {String} route: 要跳转的路由
|
||||
*/
|
||||
function goRoute(route) {
|
||||
router.push(route)
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 关闭导航的某一项
|
||||
* @param {String} route: 要关闭的当前项
|
||||
*/
|
||||
function closeNavbarItem(route) {
|
||||
storeRoutes.deleteNavItem(route).then(res => {
|
||||
goRoute(res[0])
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.navBar-list-mode-a {
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
padding: 0 30px;
|
||||
height: 50px;
|
||||
overflow: hidden;
|
||||
|
||||
&:hover {
|
||||
overflow: overlay;
|
||||
overflow-y: hidden;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
height: 6px;
|
||||
background-color: #f1f1f1;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background-color: #ccc;
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.list-icon {
|
||||
font-size: 16px;
|
||||
bottom: -0.2em;
|
||||
color: var(--el-text-color-primary);
|
||||
}
|
||||
|
||||
.list-title {
|
||||
padding: 0 5px;
|
||||
font-size: 14px;
|
||||
color: var(--el-text-color-primary);
|
||||
}
|
||||
|
||||
.list-close {
|
||||
font-size: 14px;
|
||||
transform: scale(0, 0);
|
||||
transition: all 0.3s;
|
||||
bottom: -0.18em;
|
||||
color: var(--el-text-color-primary);
|
||||
}
|
||||
|
||||
.list {
|
||||
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
flex-shrink: 0;
|
||||
text-align: center;
|
||||
overflow: visible;
|
||||
line-height: 16px;
|
||||
font-size: 16px;
|
||||
padding: 0 10px;
|
||||
display: inline-block;
|
||||
height: 35px;
|
||||
line-height: 35px;
|
||||
transition: all .3s cubic-bezier(.645, .045, .355, 1) !important;
|
||||
|
||||
&:hover {
|
||||
padding: 0 20px;
|
||||
|
||||
&::after {
|
||||
z-index: -1;
|
||||
content: ' ';
|
||||
position: absolute;
|
||||
left: -10px;
|
||||
right: -10px;
|
||||
height: 100%;
|
||||
background-color: var(--el-color-info-light-7);
|
||||
-webkit-mask: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAANoAAAAkBAMAAAAdqzmBAAAAMFBMVEVHcEwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlTPQ5AAAAD3RSTlMAr3DvEM8wgCBA379gj5//tJBPAAAAnUlEQVRIx2NgAAM27fj/tAO/xBsYkIHyf9qCT8iWMf6nNQhAsk2f5rYheY7Dnua2/U+A28ZEe8v+F9Ax2v7/F4DbxkUH2wzgtvHTwbYPo7aN2jZq26hto7aN2jZq25Cy7Qvctnw62PYNbls9HWz7S8/G6//PsI6H4396gAUQy1je08W2jxDbpv6nD4gB2uWp+J9eYPsEhv/0BPS1DQBvoBLVZ3BppgAAAABJRU5ErkJggg==);
|
||||
mask: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAANoAAAAkBAMAAAAdqzmBAAAAMFBMVEVHcEwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlTPQ5AAAAD3RSTlMAr3DvEM8wgCBA379gj5//tJBPAAAAnUlEQVRIx2NgAAM27fj/tAO/xBsYkIHyf9qCT8iWMf6nNQhAsk2f5rYheY7Dnua2/U+A28ZEe8v+F9Ax2v7/F4DbxkUH2wzgtvHTwbYPo7aN2jZq26hto7aN2jZq25Cy7Qvctnw62PYNbls9HWz7S8/G6//PsI6H4396gAUQy1je08W2jxDbpv6nD4gB2uWp+J9eYPsEhv/0BPS1DQBvoBLVZ3BppgAAAABJRU5ErkJggg==);
|
||||
-webkit-mask-size: 100% 100%;
|
||||
mask-size: 100% 100%;
|
||||
}
|
||||
|
||||
.list-close {
|
||||
transform: scale(1, 1);
|
||||
|
||||
&:hover {
|
||||
background-color: var(--el-text-color-primary);
|
||||
color: #fff;
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.list-active {
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
flex-shrink: 0;
|
||||
overflow: visible;
|
||||
color: var(--el-color-primary);
|
||||
padding: 0 20px;
|
||||
display: inline-block;
|
||||
height: 35px;
|
||||
line-height: 35px;
|
||||
|
||||
&::before {
|
||||
z-index: -1;
|
||||
content: ' ';
|
||||
position: absolute;
|
||||
left: -10px;
|
||||
right: -10px;
|
||||
height: 100%;
|
||||
background-color: var(--el-color-primary-light-9);
|
||||
-webkit-mask: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAANoAAAAkBAMAAAAdqzmBAAAAMFBMVEVHcEwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlTPQ5AAAAD3RSTlMAr3DvEM8wgCBA379gj5//tJBPAAAAnUlEQVRIx2NgAAM27fj/tAO/xBsYkIHyf9qCT8iWMf6nNQhAsk2f5rYheY7Dnua2/U+A28ZEe8v+F9Ax2v7/F4DbxkUH2wzgtvHTwbYPo7aN2jZq26hto7aN2jZq25Cy7Qvctnw62PYNbls9HWz7S8/G6//PsI6H4396gAUQy1je08W2jxDbpv6nD4gB2uWp+J9eYPsEhv/0BPS1DQBvoBLVZ3BppgAAAABJRU5ErkJggg==);
|
||||
mask: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAANoAAAAkBAMAAAAdqzmBAAAAMFBMVEVHcEwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlTPQ5AAAAD3RSTlMAr3DvEM8wgCBA379gj5//tJBPAAAAnUlEQVRIx2NgAAM27fj/tAO/xBsYkIHyf9qCT8iWMf6nNQhAsk2f5rYheY7Dnua2/U+A28ZEe8v+F9Ax2v7/F4DbxkUH2wzgtvHTwbYPo7aN2jZq26hto7aN2jZq25Cy7Qvctnw62PYNbls9HWz7S8/G6//PsI6H4396gAUQy1je08W2jxDbpv6nD4gB2uWp+J9eYPsEhv/0BPS1DQBvoBLVZ3BppgAAAABJRU5ErkJggg==);
|
||||
-webkit-mask-size: 100% 100%;
|
||||
mask-size: 100% 100%;
|
||||
}
|
||||
|
||||
.list-icon,
|
||||
.list-title,
|
||||
.list-close {
|
||||
color: inherit;
|
||||
transform: scale(1, 1);
|
||||
}
|
||||
|
||||
.list-close {
|
||||
&:hover {
|
||||
background-color: var(--el-color-primary);
|
||||
color: #fff;
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
138
src/views/layout/components/navbar-modeB.vue
Normal file
138
src/views/layout/components/navbar-modeB.vue
Normal file
@@ -0,0 +1,138 @@
|
||||
<template>
|
||||
<div class="navBar-list-mode-b">
|
||||
<div class="list" :class="[storeRoutes.activeRoute == item[0] ? 'list-active' : '']" @click="goRoute(item[0])"
|
||||
v-for="item in storeRoutes.navList">
|
||||
<SvgIcon class="list-icon" v-if="storeConfigure.configure.navbarIcon" :name="item[1]?.meta?.icon"></SvgIcon>
|
||||
<span class="list-title">{{ item[1]?.meta?.title || item[0] }}</span>
|
||||
<SvgIcon class="list-close" name="Close" v-if="item[0] !== '/home'" @click.stop="closeNavbarItem(item[0])">
|
||||
</SvgIcon>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
|
||||
import { useRoutes } from '@/store/routes.js'
|
||||
import { useConfigure } from '@/store/configure.js'
|
||||
|
||||
const storeRoutes = useRoutes()
|
||||
const storeConfigure = useConfigure()
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
/**
|
||||
* @description: 路由跳转
|
||||
* @param {String} route: 要跳转的路由
|
||||
*/
|
||||
function goRoute(route) {
|
||||
router.push(route)
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 关闭导航的某一项
|
||||
* @param {String} route: 要关闭的当前项
|
||||
*/
|
||||
function closeNavbarItem(route) {
|
||||
storeRoutes.deleteNavItem(route).then(res => {
|
||||
goRoute(res[0])
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.navBar-list-mode-b {
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0 5px;
|
||||
padding: 0 15px;
|
||||
height: 60px;
|
||||
overflow: hidden;
|
||||
|
||||
&:hover {
|
||||
overflow: overlay;
|
||||
overflow-y: hidden;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
height: 6px;
|
||||
background-color: #f1f1f1;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background-color: #ccc;
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.list-icon {
|
||||
font-size: 16px;
|
||||
line-height: 1;
|
||||
color: var(--el-text-color-primary);
|
||||
bottom: 0.05em;
|
||||
}
|
||||
|
||||
.list-title {
|
||||
padding: 0 5px;
|
||||
font-size: 14px;
|
||||
line-height: 1;
|
||||
color: var(--el-text-color-primary);
|
||||
}
|
||||
|
||||
.list-close {
|
||||
font-size: 0px;
|
||||
transform: scale(0, 0);
|
||||
transition: all 0.3s;
|
||||
color: var(--el-text-color-primary);
|
||||
}
|
||||
|
||||
.list {
|
||||
cursor: pointer;
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
height: 30px;
|
||||
padding: 0 10px;
|
||||
border: 1px solid var(--el-color-info-light-7);
|
||||
background-color: #fff;
|
||||
border-radius: 4px;
|
||||
|
||||
&.list-active {
|
||||
color: var(--el-color-primary);
|
||||
border: 1px solid var(--el-color-primary);
|
||||
background-color: var(--el-color-primary-light-9);
|
||||
|
||||
&:hover {
|
||||
background-color: var(--el-color-primary);
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: var(--el-color-info-light-7);
|
||||
|
||||
.list-icon,
|
||||
.list-title,
|
||||
.list-close {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.list-close {
|
||||
font-size: 14px;
|
||||
transform: scale(1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
.list-close {
|
||||
&:hover {
|
||||
background-color: var(--el-text-color-primary);
|
||||
color: #fff;
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
176
src/views/layout/components/navbar-modeC.vue
Normal file
176
src/views/layout/components/navbar-modeC.vue
Normal file
@@ -0,0 +1,176 @@
|
||||
<template>
|
||||
<div class="navBar-list-mode-c">
|
||||
<div :class="[storeRoutes.activeRoute == item[0] ? 'list-active' : 'list']" @click="goRoute(item[0])" v-for="item in storeRoutes.navList">
|
||||
<SvgIcon class="list-icon" v-if="storeConfigure.configure.navbarIcon" :name="item[1]?.meta?.icon"></SvgIcon>
|
||||
<span class="list-title">{{ item[1]?.meta?.title || item[0] }}</span>
|
||||
<SvgIcon class="list-close" name="Close" v-if="item[0] !== '/home'" @click.stop="closeNavbarItem(item[0])"> </SvgIcon>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useRoutes } from "@/store/routes.js";
|
||||
import { useConfigure } from "@/store/configure.js";
|
||||
|
||||
const storeRoutes = useRoutes();
|
||||
const storeConfigure = useConfigure();
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
/**
|
||||
* @description: 路由跳转
|
||||
* @param {String} route: 要跳转的路由
|
||||
*/
|
||||
function goRoute(route) {
|
||||
router.push(route);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 关闭导航的某一项
|
||||
* @param {String} route: 要关闭的当前项
|
||||
*/
|
||||
function closeNavbarItem(route) {
|
||||
storeRoutes.deleteNavItem(route).then((res) => {
|
||||
goRoute(res[0]);
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.navBar-list-mode-c {
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0 5px;
|
||||
padding: 0 30px;
|
||||
height: 50px;
|
||||
overflow: hidden;
|
||||
|
||||
&:hover {
|
||||
overflow: overlay;
|
||||
overflow-y: hidden;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
height: 6px;
|
||||
background-color: #f1f1f1;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background-color: #ccc;
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.list-icon {
|
||||
font-size: 16px;
|
||||
line-height: 1;
|
||||
color: var(--el-text-color-primary);
|
||||
bottom: 0.05em;
|
||||
}
|
||||
|
||||
.list-title {
|
||||
padding: 0 5px;
|
||||
font-size: 14px;
|
||||
line-height: 1;
|
||||
color: var(--el-text-color-primary);
|
||||
}
|
||||
|
||||
.list-close {
|
||||
font-size: 0px;
|
||||
transform: scale(0, 0);
|
||||
transition: all 0.3s;
|
||||
color: var(--el-text-color-primary);
|
||||
}
|
||||
|
||||
.list {
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
height: 35px;
|
||||
padding: 0 10px;
|
||||
|
||||
&::after {
|
||||
content: " ";
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
height: 2px;
|
||||
width: 0;
|
||||
background-color: var(--el-color-primary);
|
||||
transition: width 0.3s;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: var(--el-color-primary-light-9);
|
||||
|
||||
.list-icon,
|
||||
.list-title,
|
||||
.list-close {
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
|
||||
.list-close {
|
||||
font-size: 14px;
|
||||
transform: scale(1, 1);
|
||||
}
|
||||
|
||||
&::after {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.list-close {
|
||||
&:hover {
|
||||
background-color: var(--el-color-primary);
|
||||
color: #fff;
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.list-active {
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: var(--el-color-primary);
|
||||
height: 35px;
|
||||
padding: 0 10px;
|
||||
background-color: var(--el-color-primary-light-9);
|
||||
|
||||
&::after {
|
||||
content: " ";
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
height: 2px;
|
||||
width: 100%;
|
||||
background-color: var(--el-color-primary);
|
||||
}
|
||||
|
||||
.list-icon,
|
||||
.list-title,
|
||||
.list-close {
|
||||
color: inherit;
|
||||
transform: scale(1, 1);
|
||||
}
|
||||
|
||||
.list-close {
|
||||
font-size: 14px;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--el-color-primary);
|
||||
color: #fff;
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
139
src/views/layout/components/pageHeader.vue
Normal file
139
src/views/layout/components/pageHeader.vue
Normal file
@@ -0,0 +1,139 @@
|
||||
<template>
|
||||
<div class="pageHeader">
|
||||
<div class="routes-case">
|
||||
<SvgIcon class="sidebar-icon" :name="storeConfigure.configure.collapse ? 'Expand' : 'Fold'" size="20" color="#555"
|
||||
@click="changeSidebar"></SvgIcon>
|
||||
<el-breadcrumb separator="/">
|
||||
<!-- <transition-group name="breadcrumb"> -->
|
||||
<el-breadcrumb-item v-for="item in storeRoutes.breadcrumb" :key="item.path">
|
||||
<span style="color: #333;">{{ item?.meta?.title || item.path
|
||||
}}</span></el-breadcrumb-item>
|
||||
<!-- </transition-group> -->
|
||||
</el-breadcrumb>
|
||||
</div>
|
||||
<div class="info-case">
|
||||
<!-- <SvgIcon class="info-icon" name="Operation" @click="operationFunction('operation')"></SvgIcon> -->
|
||||
<SvgIcon class="info-icon" name="Refresh" @click="operationFunction('refresh')"></SvgIcon>
|
||||
<el-dropdown style="cursor: pointer" @visible-change="changeDropdownVisible">
|
||||
<div class="flex align-center" style="gap: 0 10px">
|
||||
<!-- <img class="info-avatar" :src="storeUser.userInfo.avatar" alt="" srcset="" /> -->
|
||||
<p class="info-name">{{ storeUser.userInfo.loginName }}</p>
|
||||
<SvgIcon color="#333" name="arrow-down"></SvgIcon>
|
||||
</div>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<!-- <el-dropdown-item>个人中心</el-dropdown-item> -->
|
||||
<el-dropdown-item @click="logOut">退出登录</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useConfigure } from "@/store/configure.js";
|
||||
import { useUser } from "@/store/user.js";
|
||||
import { useRoutes } from "@/store/routes.js";
|
||||
const storeUser = useUser();
|
||||
const storeRoutes = useRoutes();
|
||||
|
||||
// 获取配置
|
||||
const storeConfigure = useConfigure();
|
||||
|
||||
// 侧边栏导航的收起与展开
|
||||
function changeSidebar() {
|
||||
storeConfigure.change("collapse", !storeConfigure.configure.collapse);
|
||||
}
|
||||
|
||||
// 下拉菜单
|
||||
let showDropdown = ref(false);
|
||||
let rotateUserIcon = ref("0deg");
|
||||
function changeDropdownVisible() {
|
||||
showDropdown.value = !showDropdown.value;
|
||||
rotateUserIcon.value = showDropdown.value ? "180deg" : "0deg";
|
||||
}
|
||||
|
||||
// info 中的按钮操作
|
||||
const emits = defineEmits(["operation"]);
|
||||
function operationFunction(type) {
|
||||
emits("operation", type);
|
||||
}
|
||||
|
||||
// 退出登录
|
||||
function logOut() {
|
||||
// 清除缓存 / token 等
|
||||
_hook.useLocalStorage.clear();
|
||||
// 使用 reload 时,不需要调用 resetRoute() 重置路由
|
||||
// 且刷新页面时 pinia 数据会重置
|
||||
window.location.reload();
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// 面包屑的动画
|
||||
.breadcrumb-enter-active,
|
||||
.breadcrumb-leave-active {
|
||||
transition: all 0.5s ease;
|
||||
}
|
||||
|
||||
.breadcrumb-enter-from,
|
||||
.breadcrumb-leave-active {
|
||||
opacity: 0;
|
||||
transform: translateX(20px);
|
||||
}
|
||||
|
||||
.breadcrumb-leave-active {
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
transition: all 0s ease;
|
||||
}
|
||||
|
||||
.pageHeader {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 20px;
|
||||
height: 60px;
|
||||
// border-bottom: 1px solid #efefef;
|
||||
}
|
||||
|
||||
.routes-case {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.sidebar-icon {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.info-case {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0 16px;
|
||||
|
||||
.info-icon {
|
||||
cursor: pointer;
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: var(--el-color-primary);
|
||||
transform: scale(1.2, 1.2);
|
||||
}
|
||||
}
|
||||
|
||||
.info-avatar {
|
||||
border-radius: 2px;
|
||||
width: 35px;
|
||||
height: 35px;
|
||||
}
|
||||
|
||||
.info-name {
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
124
src/views/layout/components/sidebar-modeA-sub.vue
Normal file
124
src/views/layout/components/sidebar-modeA-sub.vue
Normal file
@@ -0,0 +1,124 @@
|
||||
<template>
|
||||
<template v-if="props.item.children">
|
||||
<el-sub-menu
|
||||
:class="{ 'menu-sub-modeA': configure.menuMode == layoutModeEnum.key[0], 'menu-sub-modeB': configure.menuMode == layoutModeEnum.key[1] }"
|
||||
v-if="!props.item.meta?.isHide" :index="props.item?.path">
|
||||
<template #title>
|
||||
<SvgIcon class="route-icon" :name="props.item?.meta?.icon"></SvgIcon>
|
||||
<span class="route-title">{{ props.item?.meta?.title || props.item?.path }}</span>
|
||||
</template>
|
||||
<sidebar-modeA-sub v-for="route in props.item?.children" :item="route" :key="route.path"></sidebar-modeA-sub>
|
||||
</el-sub-menu>
|
||||
<template v-else>
|
||||
<sidebar-modeA-sub v-for="route in props.item?.children" :item="route" :key="route.path"></sidebar-modeA-sub>
|
||||
</template>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-menu-item
|
||||
:class="{ 'active-menu': activeMenuCount(), 'is-active': activeMenuCount(), 'menu-modeA': configure.menuMode == layoutModeEnum.key[0], 'menu-modeB': configure.menuMode == layoutModeEnum.key[1] }"
|
||||
v-if="!props.item?.meta?.isHide" :index="props.item?.path">
|
||||
<SvgIcon class="route-icon" :name="props.item?.meta?.icon"></SvgIcon>
|
||||
<span class="route-title">{{ props.item?.meta?.title || props.item?.path }}</span>
|
||||
</el-menu-item>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useRoutes } from "@/store/routes.js";
|
||||
import { useConfigure } from "@/store/configure.js";
|
||||
import { useRoute } from 'vue-router'
|
||||
|
||||
const storeRoutes = useRoutes();
|
||||
const route = useRoute();
|
||||
|
||||
// 获取配置
|
||||
const storeConfigure = useConfigure();
|
||||
const { configure } = storeToRefs(storeConfigure);
|
||||
|
||||
const props = defineProps({
|
||||
item: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
|
||||
// 获取枚举值
|
||||
const { layoutModeEnum } = ENUMS;
|
||||
|
||||
function activeMenuCount() {
|
||||
if (route.meta.activeMenu) {
|
||||
return props.item?.path == route.meta.activeMenu
|
||||
} else {
|
||||
return storeRoutes.activeRoute == props.item?.path
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.menu-sub-modeA {
|
||||
.el-sub-menu__title {
|
||||
&:hover {
|
||||
background-color: rgba(0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.menu-sub-modeB {
|
||||
.el-sub-menu__title {
|
||||
margin: 0 5px;
|
||||
|
||||
color: var(--el-text-color-primary);
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
.el-icon {
|
||||
color: var(--el-text-color-primary);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.menu-modeA {
|
||||
&:hover {
|
||||
// color: var(--el-menu-active-color);
|
||||
// background-color: var(--el-color-primary-light-3);
|
||||
background-color: #efefef;
|
||||
}
|
||||
}
|
||||
|
||||
.menu-modeA.active-menu {
|
||||
background-color: var(--el-color-primary);
|
||||
}
|
||||
|
||||
.menu-modeB {
|
||||
margin: 5px;
|
||||
border-radius: 5px;
|
||||
|
||||
.route-title,
|
||||
.route-icon {
|
||||
color: var(--el-text-color-primary);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: var(--el-color-primary-light-9);
|
||||
|
||||
.route-title,
|
||||
.route-icon {
|
||||
color: var(--el-color-primary-light-3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.menu-modeB.active-menu {
|
||||
background-color: var(--el-color-primary-light-9);
|
||||
|
||||
.route-title,
|
||||
.route-icon {
|
||||
color: var(--el-color-primary-light-3);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
77
src/views/layout/components/sidebar-modeA.vue
Normal file
77
src/views/layout/components/sidebar-modeA.vue
Normal file
@@ -0,0 +1,77 @@
|
||||
<template>
|
||||
<div class="sidebar-mode-a">
|
||||
<div class="logo-case" v-if="configure.showMenuLogo">
|
||||
<img class="logo" src="/logo.png" alt="logo" srcset="" />
|
||||
<transition name="el-fade-in">
|
||||
<span v-show="!storeConfigure.configure.collapse" style="margin-left: 10px;">{{ storeConfigure.projectName
|
||||
}}</span>
|
||||
</transition>
|
||||
</div>
|
||||
<el-menu @select="goRoute" :collapse="configure.collapse" :default-active="defaultActive" style="border-right: none"
|
||||
class="el-menu-vertical-demo">
|
||||
<sidebar-modea-sub v-for="route in props.list" :key="route.path" :item="route" />
|
||||
</el-menu>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useConfigure } from "@/store/configure.js";
|
||||
import sidebarModeaSub from "./sidebar-modeA-sub.vue";
|
||||
|
||||
const props = defineProps({
|
||||
list: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return [];
|
||||
},
|
||||
required: true,
|
||||
},
|
||||
width: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
let width = ref(props.width);
|
||||
|
||||
// 获取配置
|
||||
const storeConfigure = useConfigure();
|
||||
const { configure, defaultActive } = storeToRefs(storeConfigure);
|
||||
|
||||
/**
|
||||
* @description: 路由跳转
|
||||
* @param {String} index: 路由
|
||||
*/
|
||||
const router = useRouter();
|
||||
function goRoute(index) {
|
||||
router.push(index);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.el-menu-vertical-demo:not(.el-menu--collapse) {
|
||||
width: v-bind(width);
|
||||
}
|
||||
|
||||
.sidebar-mode-a {
|
||||
overflow-y: scroll;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.logo-case {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
overflow: hidden;
|
||||
|
||||
.logo {
|
||||
height: 30px;
|
||||
border-radius: 6px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
150
src/views/layout/components/sidebar-modeB.vue
Normal file
150
src/views/layout/components/sidebar-modeB.vue
Normal file
@@ -0,0 +1,150 @@
|
||||
<template>
|
||||
<div class="sidebar-mode-b">
|
||||
<el-scrollbar class="scrollbar">
|
||||
<div class="route-list" :class="{ 'active-route-list': storeRoutes.breadcrumbKeys.includes(item.path) }" v-for="item in data.routesList" @click="goRoute(item.path)">
|
||||
<SvgIcon class="route-icon" size="16" :name="item?.meta?.icon"></SvgIcon>
|
||||
<span class="route-title">{{ item?.meta?.title || item.path }}</span>
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
<div :class="['sidebar-mode-b-menu', configure.collapse ? 'sidebar-switch' : 'sidebar-open']">
|
||||
<sidebar-mode-a menu-trigger="hover" :list="data.activeRouteChildren" width="190px"></sidebar-mode-a>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import sidebarModeA from "./sidebar-modeA.vue";
|
||||
import { useRoutes } from "@/store/routes.js";
|
||||
import { useConfigure } from "@/store/configure.js";
|
||||
|
||||
// 获取配置
|
||||
const storeConfigure = useConfigure();
|
||||
const { configure } = storeToRefs(storeConfigure);
|
||||
const route = useRoute();
|
||||
|
||||
// 获取路由 store
|
||||
const storeRoutes = useRoutes();
|
||||
|
||||
const data = reactive({
|
||||
routesList: [],
|
||||
activeRouteChildren: [],
|
||||
});
|
||||
|
||||
/**
|
||||
* @description: 过滤侧栏可显示的一级路由
|
||||
* @param {Array} routes: 路由列表
|
||||
* @return {Array} 过滤好的路由
|
||||
*/
|
||||
function filterRoute(routes) {
|
||||
let arr = [];
|
||||
routes.forEach((i) => {
|
||||
if (i?.meta?.isHide == false || i?.meta?.isHide == undefined) {
|
||||
arr.push(i);
|
||||
} else {
|
||||
if (i?.children?.length > 0) {
|
||||
arr = filterRoute(i.children);
|
||||
}
|
||||
}
|
||||
});
|
||||
return arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 路由跳转
|
||||
* @param {String} index: 路由
|
||||
*/
|
||||
const router = useRouter();
|
||||
function goRoute(index) {
|
||||
router.push(index);
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
data.routesList = filterRoute(storeRoutes.routesList);
|
||||
data.activeRouteChildren = storeRoutes.allRoutes[route.matched[1].path].children;
|
||||
if (data.activeRouteChildren.length == 0) {
|
||||
storeConfigure.change("collapse", true);
|
||||
}
|
||||
});
|
||||
|
||||
watch(
|
||||
() => storeRoutes.breadcrumbKeys,
|
||||
() => {
|
||||
data.activeRouteChildren = storeRoutes.allRoutes[route.matched[1].path]?.children;
|
||||
if (data?.activeRouteChildren?.length == 0) {
|
||||
storeConfigure.change("collapse", true);
|
||||
} else {
|
||||
storeConfigure.change("collapse", false);
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.sidebar-mode-b {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.scrollbar {
|
||||
border-right: 1px solid var(--el-border-color-lighter);
|
||||
}
|
||||
|
||||
.route-list {
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: space-evenly;
|
||||
border-radius: 5px;
|
||||
margin: 5px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--el-color-primary-light-3);
|
||||
|
||||
.route-icon,
|
||||
.route-title {
|
||||
color: var(--el-menu-active-color);
|
||||
}
|
||||
}
|
||||
|
||||
.route-icon,
|
||||
.route-title {
|
||||
text-align: center;
|
||||
color: var(--el-menu-text-color);
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.active-route-list {
|
||||
background-color: var(--el-color-primary-light-3);
|
||||
|
||||
.route-icon,
|
||||
.route-title {
|
||||
color: var(--el-menu-active-color);
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-switch {
|
||||
width: 0px;
|
||||
overflow: hidden;
|
||||
transition: width 0.3s;
|
||||
}
|
||||
|
||||
.sidebar-open {
|
||||
width: 190px;
|
||||
overflow: hidden;
|
||||
transition: width 0.3s;
|
||||
}
|
||||
|
||||
.sidebar-mode-b-menu {
|
||||
overflow-y: scroll;
|
||||
background-color: var(--el-color-white);
|
||||
height: 100%;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
202
src/views/layout/layout.vue
Normal file
202
src/views/layout/layout.vue
Normal file
@@ -0,0 +1,202 @@
|
||||
<template>
|
||||
<div class="layout-container">
|
||||
<div class="layout-case">
|
||||
<div class="sidebar">
|
||||
<!-- 侧边栏的布局模式 -->
|
||||
<sidebar-mode-a v-if="getConfigure.menuMode == layoutModeEnum.key[0]" :list="storeRoutes.routesList"
|
||||
width="260px"></sidebar-mode-a>
|
||||
<sidebar-mode-b v-else-if="getConfigure.menuMode == layoutModeEnum.key[1]"></sidebar-mode-b>
|
||||
</div>
|
||||
<div class="layout-case" style="flex-direction: column">
|
||||
<header class="header">
|
||||
<page-header @operation="operation"></page-header>
|
||||
<navbar></navbar>
|
||||
</header>
|
||||
<main class="main">
|
||||
<!-- <router-view v-slot="{ Component }" v-if="isRefreshRoute">
|
||||
<transition :name="getConfigure.componentTransitionMode" mode="out-in"
|
||||
v-if="getConfigure.componentTransition">
|
||||
<keep-alive :include="storeRoutes.cachedRoute">
|
||||
<component :is="Component" />
|
||||
</keep-alive>
|
||||
</transition>
|
||||
<keep-alive v-else :include="storeRoutes.cachedRoute">
|
||||
<component :is="Component" />
|
||||
</keep-alive>
|
||||
</router-view> -->
|
||||
<router-view v-slot="{ Component }">
|
||||
<!-- <transition :name="getConfigure.componentTransitionMode" mode="out-in"> -->
|
||||
<!-- <keep-alive :include="storeRoutes.cachedRoute"> -->
|
||||
<component :is="Component" />
|
||||
<!-- </keep-alive> -->
|
||||
<!-- </transition> -->
|
||||
<!-- <keep-alive v-else :include="storeRoutes.cachedRoute"> -->
|
||||
<!-- <component v-else :is="Component" /> -->
|
||||
<!-- </keep-alive> -->
|
||||
</router-view>
|
||||
</main>
|
||||
<div class="version">©银收客 v{{ packageData.version }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<c-configure v-model="bools.showConfigure"></c-configure>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import sidebarModeA from "./components/sidebar-modeA.vue";
|
||||
import sidebarModeB from "./components/sidebar-modeB.vue";
|
||||
import pageHeader from "./components/pageHeader.vue";
|
||||
import navbar from "./components/navBar.vue";
|
||||
import cConfigure from "./components/configure.vue";
|
||||
import { useConfigure } from "@/store/configure.js";
|
||||
import { useRoutes } from "@/store/routes.js";
|
||||
import NProgress from "nprogress";
|
||||
import "nprogress/nprogress.css";
|
||||
const storeRoutes = useRoutes();
|
||||
import packageData from '../../../package.json'
|
||||
|
||||
// 获取枚举值
|
||||
const { layoutModeEnum } = ENUMS;
|
||||
|
||||
// 获取配置
|
||||
const storeConfigure = useConfigure();
|
||||
const { configure } = storeToRefs(storeConfigure);
|
||||
const getConfigure = computed(() => {
|
||||
return configure.value;
|
||||
});
|
||||
|
||||
// 控制操作的布尔值
|
||||
const bools = reactive({
|
||||
showConfigure: false,
|
||||
});
|
||||
|
||||
// 页头的操作
|
||||
function operation(type) {
|
||||
switch (type) {
|
||||
case "operation":
|
||||
bools.showConfigure = true;
|
||||
break;
|
||||
case "refresh":
|
||||
reload();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 局部组件刷新
|
||||
const isRefreshRoute = ref(true);
|
||||
function reload() {
|
||||
NProgress.start();
|
||||
isRefreshRoute.value = false;
|
||||
nextTick(() => {
|
||||
isRefreshRoute.value = true;
|
||||
NProgress.done();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.vab-drawer .el-drawer__header {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.el-icon .el-sub-menu__icon-arrow {
|
||||
color: var(--el-text-color-primary);
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.layout-container {
|
||||
--versionH: 50px;
|
||||
}
|
||||
|
||||
.version {
|
||||
height: var(--versionH);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 14px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
// 页面切换的动画 模式 A
|
||||
.mainA-enter-active,
|
||||
.mainA-leave-active {
|
||||
transition: all 0.5s ease;
|
||||
}
|
||||
|
||||
.mainA-enter-from,
|
||||
.mainA-leave-active {
|
||||
opacity: 0;
|
||||
transform: translateY(100px);
|
||||
}
|
||||
|
||||
.mainA-leave-active {
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
transition: all 0s ease;
|
||||
}
|
||||
|
||||
// 页面切换的动画 模式 B
|
||||
.mainB-enter-active,
|
||||
.mainB-leave-active {
|
||||
transition: all 0.5s ease;
|
||||
}
|
||||
|
||||
.mainB-enter-from,
|
||||
.mainB-leave-active {
|
||||
opacity: 0;
|
||||
transform: translateX(100px);
|
||||
}
|
||||
|
||||
.mainB-leave-active {
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
transition: all 0s ease;
|
||||
}
|
||||
|
||||
.layout-container {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: auto;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.layout-case {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex: 1;
|
||||
flex-basis: auto;
|
||||
box-sizing: border-box;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
background-color: var(--admin-column-bg-color);
|
||||
}
|
||||
|
||||
.header {
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.main {
|
||||
height: calc(100vh - 60px * 2 - var(--versionH));
|
||||
display: block;
|
||||
flex: 1;
|
||||
flex-basis: auto;
|
||||
box-sizing: border-box;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
padding: 0 15px 15px;
|
||||
background: var(--el-color-info-light-9);
|
||||
@extend .scrollbar-y;
|
||||
}
|
||||
</style>
|
||||
169
src/views/login/login.vue
Normal file
169
src/views/login/login.vue
Normal file
@@ -0,0 +1,169 @@
|
||||
<template>
|
||||
<div class="login-case">
|
||||
<div class="form-case">
|
||||
<span class="Hello">Hello !</span>
|
||||
<span class="title">欢迎来到银收客</span>
|
||||
<el-form ref="ruleFormRef" :rules="rules" :model="form">
|
||||
<el-form-item prop="loginName">
|
||||
<el-input class="inp" v-model="form.loginName" clearable autocomplete="new-password" size="large"
|
||||
:prefix-icon="User" placeholder="请输入账号" style="width: 100%;" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="password">
|
||||
<el-input class="inp" v-model="form.password" clearable autocomplete="new-password" size="large" type="password"
|
||||
:prefix-icon="Lock" placeholder="请输入密码" style="width: 100%;" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-select v-model="form.userType" placeholder="请选择机构类型" size="large" style="width: 100%;">
|
||||
<el-option key="MG" label="平台" value="MG"></el-option>
|
||||
<el-option key="FO" label="大机构" value="FO"></el-option>
|
||||
<el-option key="SO" label="小机构" value="SO"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item prop="code">
|
||||
<div class="code-case">
|
||||
<el-input class="inp" v-model="form.code" clearable autocomplete="new-password" size="large"
|
||||
:prefix-icon="CircleCheck" width="100px" placeholder="验证码" />
|
||||
<verificationCode @getCode="getCode" :key="verificationCodeKey"></verificationCode>
|
||||
</div>
|
||||
</el-form-item> -->
|
||||
<el-form-item>
|
||||
<el-button type="primary" size="large" :loading="loading" @click="login" style="width: 100%;">登录</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import verificationCode from "@/components/verificationCode.vue";
|
||||
import { User, Lock, CircleCheck } from "@element-plus/icons-vue";
|
||||
import { useUser } from "@/store/user.js";
|
||||
const ruleFormRef = ref("");
|
||||
const store = useUser();
|
||||
const router = useRouter();
|
||||
const loading = ref(false)
|
||||
|
||||
onMounted(() => {
|
||||
// ElMessage({
|
||||
// message: "请使用用户名为 admin、yonghu1、yonghu2 进行登录测试,来获取不同的权限",
|
||||
// type: "success",
|
||||
// duration: 5000,
|
||||
// });
|
||||
});
|
||||
|
||||
let verificationCodeKey = ref(0);
|
||||
let trueCode = ref("");
|
||||
|
||||
/**
|
||||
* @description: 获取正确的验证码值
|
||||
* @param {*} code: 正确的验证码
|
||||
*/
|
||||
function getCode(code) {
|
||||
trueCode.value = code;
|
||||
}
|
||||
|
||||
const form = reactive({
|
||||
loginName: "",
|
||||
password: "",
|
||||
userType: 'MG',
|
||||
code: "",
|
||||
});
|
||||
/**
|
||||
* @description: 自定义验证 - 验证账号
|
||||
*/
|
||||
function checkName(rule, value, callback) {
|
||||
if (value === "") {
|
||||
callback(new Error("账号不可为空"));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 自定义验证 - 验证验证码
|
||||
*/
|
||||
function checkCode(rule, value, callback) {
|
||||
if (value === "") {
|
||||
callback(new Error("验证码不可为空"));
|
||||
} else if (value !== trueCode.value) {
|
||||
verificationCodeKey.value++;
|
||||
callback(new Error("验证码不正确"));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
|
||||
// form 验证
|
||||
const rules = reactive({
|
||||
loginName: [{ validator: checkName, required: true, trigger: "blur" }],
|
||||
password: [{ required: true, message: "密码不可为空", trigger: "blur" }],
|
||||
code: [{ validator: checkCode, required: true, trigger: "blur" }],
|
||||
});
|
||||
|
||||
// 登录
|
||||
async function login() {
|
||||
//通过 ref 的值触发验证
|
||||
await ruleFormRef.value.validate((valid) => {
|
||||
if (valid) {
|
||||
loading.value = true
|
||||
const params = {
|
||||
loginName: form.loginName,
|
||||
password: form.password,
|
||||
userType: form.userType
|
||||
};
|
||||
store.userlogin(params).then((res) => {
|
||||
router.replace("/home");
|
||||
}).catch(err => {
|
||||
loading.value = false
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
// 回车键触发登录操作
|
||||
_hook.useKeyStroke("Enter", login);
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.login-case {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: url('../../assets/logo_bg.png') no-repeat right bottom / contain;
|
||||
}
|
||||
|
||||
.form-case {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
// height: 450px;
|
||||
left: 20%;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.Hello {
|
||||
font-weight: bold;
|
||||
font-size: 30px;
|
||||
color: #000;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-weight: 600;
|
||||
font-size: 40px;
|
||||
color: #000;
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
|
||||
.code-case {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
.inp {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
36
src/views/makes/svgIcon.vue
Normal file
36
src/views/makes/svgIcon.vue
Normal file
@@ -0,0 +1,36 @@
|
||||
<template>
|
||||
<div class="svgIcon">
|
||||
<el-card header="SvgIcon ( 仅支持 ElementPlus Icon )">
|
||||
<SvgIcon name="ElementPlus" size="50" color="#409eff"></SvgIcon>
|
||||
</el-card>
|
||||
<el-card header="参数" style="margin-top: 20px">
|
||||
<el-table :data="tableData">
|
||||
<el-table-column prop="param" label="参数" />
|
||||
<el-table-column prop="explain" label="说明" />
|
||||
<el-table-column prop="type" label="类型" />
|
||||
</el-table>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const tableData = [
|
||||
{
|
||||
param: "name",
|
||||
explain: "svg 图标名字",
|
||||
type: "String",
|
||||
},
|
||||
{
|
||||
param: "size",
|
||||
explain: "svg 大小",
|
||||
type: "String / Number",
|
||||
},
|
||||
{
|
||||
param: "color",
|
||||
explain: "svg 颜色",
|
||||
type: "String",
|
||||
},
|
||||
];
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
336
src/views/organization/agent_list.vue
Normal file
336
src/views/organization/agent_list.vue
Normal file
@@ -0,0 +1,336 @@
|
||||
<template>
|
||||
<div class="card">
|
||||
<div class="pb15" v-permission="['SO']">
|
||||
<el-row>
|
||||
<el-space>
|
||||
<el-button type="primary" icon="Plus" @click="showDialog = true">添加代理</el-button>
|
||||
</el-space>
|
||||
</el-row>
|
||||
</div>
|
||||
<el-space>
|
||||
<el-input placeholder="请输入机构代码搜索" v-model="tableOptions.agencyCode" style="width: 200px;" />
|
||||
<el-button type="primary" icon="Search" @click="searchHandle">搜索</el-button>
|
||||
</el-space>
|
||||
<div class="table mt15">
|
||||
<el-table :data="tableOptions.list" size="large" stripe border height="100%" v-loading="tableOptions.loading">
|
||||
<el-table-column prop="id" label="代理id"></el-table-column>
|
||||
<el-table-column prop="agencyName" label="代理名称">
|
||||
<template #default="scope">
|
||||
<el-text>{{ scope.row.agencyName || scope.row.agencyCode }}</el-text>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="agencyCode" label="代理代码"></el-table-column>
|
||||
<el-table-column prop="current_fee" label="推广费率">
|
||||
<template #default="scope" v-permission="['MG']">
|
||||
<el-link type="primary" icon="EditPen" @click="eitorFeeHandle(scope.row)">{{ scope.row.current_fee
|
||||
}}%</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="parentLoginName" label="上级机构代码"></el-table-column>
|
||||
<el-table-column prop="sumConsumeFee" label="总流水">
|
||||
<template #default="scope">
|
||||
<el-text>{{ scope.row.sumConsumeFee.toFixed(2) }}</el-text>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="yestedayConsumeFee" label="今日流水"></el-table-column>
|
||||
<el-table-column prop="sumfansShareMoney" label="总收益">
|
||||
<template #default="scope">
|
||||
<el-link type="primary" icon="search" @click="showTotalEarnings(scope.row.id)">
|
||||
{{ scope.row.sumfansShareMoney }}
|
||||
</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="yestedayShareMoney" label="今日收益"></el-table-column>
|
||||
<el-table-column prop="sumAccount" label="商家数量"></el-table-column>
|
||||
<el-table-column label="操作">
|
||||
<template #default="scope">
|
||||
<el-button size="small" type="primary" icon="DataLine"
|
||||
@click="checkChartHandle(scope.row.id)">详细数据</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="mt15">
|
||||
<el-pagination layout="prev, pager, next, total, sizes, jumper" background
|
||||
v-model:current-page="tableOptions.pageNum" v-model:page-size="tableOptions.pageSzie"
|
||||
:page-size="tableOptions.pageSzie" :page-sizes="[10, 20, 30, 50]" :total="tableOptions.total"
|
||||
@size-change="paginationChange" @current-change="paginationChange" />
|
||||
</div>
|
||||
<el-dialog title="修改推广费率" v-model="showFeeDialog" @closed="feeDialogClosed">
|
||||
<el-form ref="formFeeRef" :model="feeForm" :rules="feeRules" label-width="100">
|
||||
<el-form-item prop="fee" label="推广费率">
|
||||
<el-input placeholder="请输入推广费率" v-model="feeForm.fee">
|
||||
<template #append>%</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-space>
|
||||
<el-button @click="showFeeDialog = false">取消</el-button>
|
||||
<el-button type="primary" :loading="showFeeLoading" @click="feeSubmitHandle">提交</el-button>
|
||||
</el-space>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<el-dialog title="添加代理" v-model="showDialog" @closed="dialogClosed">
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="100">
|
||||
<el-form-item label="代理类型">
|
||||
<el-select v-model="form.userType" disabled>
|
||||
<el-option :key="item.type_code" :label="item.type_name" :value="item.type_code"
|
||||
v-for="item in organizationList" key="item.type_code"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item prop="agencyName" label="代理名称">
|
||||
<el-input placeholder="请输入机构名称" v-model="form.agencyName" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="angencyCode" label="代理代码">
|
||||
<el-input placeholder="请输入机构代码" :maxlength="11" show-word-limit v-model="form.angencyCode" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="passowrd" label="密码">
|
||||
<el-input type="password" show-password placeholder="请输入密码" :maxlength="11" v-model="form.passowrd" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="fee" label="推广费率">
|
||||
<el-input placeholder="请输入推广费率" v-model="form.fee">
|
||||
<template #append>%</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="phone" label="联系方式">
|
||||
<el-input placeholder="请输入手机号" v-model="form.phone" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-space>
|
||||
<el-button @click="showDialog = false">取消</el-button>
|
||||
<el-button type="primary" :loading="formLoading" @click="submitHandle">提交</el-button>
|
||||
</el-space>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<totalEarnings ref="totalEarningsRef" />
|
||||
<el-dialog title="详细数据" width="90%" v-model="showChartCard">
|
||||
<chart-card v-if="showChartCard" :user-id="userId" />
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { addAgency, queryAgency, modifyFee } from '@/api/organization.js'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { validPhone, organizationList, addOrganizations } from '@/utils'
|
||||
import { onMounted, reactive } from 'vue';
|
||||
import { useUser } from '@/store/user.js'
|
||||
|
||||
// 图表相关
|
||||
import chartCard from '@/components/chartCard.vue';
|
||||
const showChartCard = ref(false)
|
||||
const userId = ref()
|
||||
function checkChartHandle(id) {
|
||||
userId.value = id
|
||||
showChartCard.value = true
|
||||
}
|
||||
|
||||
// totalEarnings组件相关
|
||||
import totalEarnings from '@/components/totalEarnings.vue';
|
||||
const totalEarningsRef = ref('')
|
||||
function showTotalEarnings(parent_user_id) {
|
||||
totalEarningsRef.value.show(parent_user_id)
|
||||
}
|
||||
|
||||
const storeUser = useUser()
|
||||
|
||||
// 显示添加表单
|
||||
const showDialog = ref(false)
|
||||
const formLoading = ref(false)
|
||||
const showFeeDialog = ref(false)
|
||||
const showFeeLoading = ref(false)
|
||||
|
||||
// 获取添加小机构表单实例
|
||||
let formRef = ref(null)
|
||||
// 获取修改费率表单实例
|
||||
let formFeeRef = ref(null)
|
||||
|
||||
// 创建表单
|
||||
const form = reactive({
|
||||
agencyName: '',
|
||||
angencyCode: '',
|
||||
passowrd: '',
|
||||
fee: '',
|
||||
userType: addOrganizations[storeUser.userInfo.userType],
|
||||
phone: '',
|
||||
})
|
||||
|
||||
// 创建修改费率表单
|
||||
const feeForm = reactive({
|
||||
id: '',
|
||||
fee: ''
|
||||
})
|
||||
const feeRules = reactive({
|
||||
fee: [
|
||||
{
|
||||
required: true,
|
||||
message: '',
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
// 表格参数
|
||||
const tableOptions = reactive({
|
||||
loading: true,
|
||||
agencyCode: '',
|
||||
list: [],
|
||||
total: 0,
|
||||
pageNum: 1,
|
||||
pageSzie: 10
|
||||
})
|
||||
|
||||
// 自定义校验密码
|
||||
function passowrdValidate(rule, value, callback) {
|
||||
if (!value) {
|
||||
return callback(new Error(''))
|
||||
} else if (value.length < 6) {
|
||||
return callback(new Error('密码最少6位'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
|
||||
// 自定义校验手机号
|
||||
function phoneValidate(rule, value, callback) {
|
||||
if (!value) {
|
||||
return callback(new Error(''))
|
||||
} else if (!validPhone(value)) {
|
||||
return callback(new Error('请输入正确的手机号'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
|
||||
// 创建form校验规则
|
||||
const rules = reactive({
|
||||
agencyName: [
|
||||
{
|
||||
required: true,
|
||||
message: '',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
angencyCode: [
|
||||
{
|
||||
required: true,
|
||||
message: '',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
passowrd: [
|
||||
{
|
||||
required: true,
|
||||
validator: passowrdValidate,
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
fee: [
|
||||
{
|
||||
required: true,
|
||||
message: '',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
phone: [
|
||||
{
|
||||
required: true,
|
||||
validator: phoneValidate,
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
// 表单关闭
|
||||
function dialogClosed() {
|
||||
formRef.value.resetFields()
|
||||
}
|
||||
|
||||
// 修改费率关闭
|
||||
function feeDialogClosed() {
|
||||
formFeeRef.value.resetFields()
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const submitHandle = async () => {
|
||||
await formRef.value.validate(async (vaild, fields) => {
|
||||
if (vaild) {
|
||||
try {
|
||||
formLoading.value = true
|
||||
await addAgency(form)
|
||||
formLoading.value = false
|
||||
showDialog.value = false
|
||||
ElMessage.success('添加成功')
|
||||
paginationChange()
|
||||
} catch (error) {
|
||||
formLoading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 提交修改费率
|
||||
async function feeSubmitHandle() {
|
||||
await formFeeRef.value.validate(async (vaild) => {
|
||||
if (vaild) {
|
||||
try {
|
||||
showFeeLoading.value = true
|
||||
await modifyFee(feeForm)
|
||||
showFeeLoading.value = false
|
||||
showFeeDialog.value = false
|
||||
ElMessage.success('添加成功')
|
||||
paginationChange()
|
||||
} catch (error) {
|
||||
showFeeLoading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 修改费率
|
||||
function eitorFeeHandle(row) {
|
||||
feeForm.id = row.id
|
||||
feeForm.fee = row.current_fee
|
||||
showFeeDialog.value = true
|
||||
}
|
||||
|
||||
// 搜索
|
||||
function searchHandle() {
|
||||
tableOptions.pageNum = 1;
|
||||
paginationChange()
|
||||
}
|
||||
|
||||
// 分页回调
|
||||
function paginationChange() {
|
||||
tableOptions.loading = true
|
||||
queryAgencyHandle()
|
||||
}
|
||||
|
||||
// 获取机构列表
|
||||
async function queryAgencyHandle() {
|
||||
try {
|
||||
const res = await queryAgency({
|
||||
agencyCode: tableOptions.agencyCode,
|
||||
pageNum: tableOptions.pageNum,
|
||||
pageSzie: tableOptions.pageSzie,
|
||||
userType: 'AG',
|
||||
isExtend: ''
|
||||
})
|
||||
tableOptions.loading = false
|
||||
tableOptions.list = res.list
|
||||
tableOptions.total = res.total
|
||||
} catch (error) { }
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
queryAgencyHandle()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.table {
|
||||
height: calc(100vh - 355px);
|
||||
}
|
||||
</style>
|
||||
336
src/views/organization/big_organization.vue
Normal file
336
src/views/organization/big_organization.vue
Normal file
@@ -0,0 +1,336 @@
|
||||
<template>
|
||||
<div class="card">
|
||||
<div class="pb15">
|
||||
<el-row v-permission="['MG']">
|
||||
<el-space>
|
||||
<el-button type="primary" icon="Plus" @click="showDialog = true">添加大机构</el-button>
|
||||
</el-space>
|
||||
</el-row>
|
||||
</div>
|
||||
<el-space>
|
||||
<el-input placeholder="请输入机构代码搜索" v-model="tableOptions.agencyCode" style="width: 200px;" />
|
||||
<el-button type="primary" icon="Search" @click="searchHandle">搜索</el-button>
|
||||
</el-space>
|
||||
<div class="table mt15">
|
||||
<el-table :data="tableOptions.list" size="large" stripe border v-loading="tableOptions.loading">
|
||||
<el-table-column prop="id" label="机构id"></el-table-column>
|
||||
<el-table-column prop="agencyName" label="机构名称">
|
||||
<template #default="scope">
|
||||
<el-text>{{ scope.row.agencyName || scope.row.agencyCode }}</el-text>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="agencyCode" label="机构代码"></el-table-column>
|
||||
<el-table-column prop="current_fee" label="推广费率">
|
||||
<template #default="scope">
|
||||
<el-link type="primary" icon="EditPen" @click="eitorFeeHandle(scope.row)">
|
||||
{{ scope.row.current_fee }}%
|
||||
</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="parentLoginName" label="上级机构代码"></el-table-column>
|
||||
<el-table-column prop="sumConsumeFee" label="总流水">
|
||||
<template #default="scope">
|
||||
<el-text>{{ scope.row.sumConsumeFee.toFixed(2) }}</el-text>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="yestedayConsumeFee" label="今日流水"></el-table-column>
|
||||
<el-table-column prop="sumfansShareMoney" label="总收益">
|
||||
<template #default="scope">
|
||||
<el-link type="primary" icon="search" @click="showTotalEarnings(scope.row.id)">
|
||||
{{ scope.row.sumfansShareMoney }}
|
||||
</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="yestedayShareMoney" label="今日收益"></el-table-column>
|
||||
<el-table-column prop="sumAccount" label="商家数量"></el-table-column>
|
||||
<el-table-column label="操作">
|
||||
<template #default="scope">
|
||||
<el-button size="small" type="primary" icon="DataLine"
|
||||
@click="checkChartHandle(scope.row.id)">详细数据</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="mt15">
|
||||
<el-pagination layout="prev, pager, next, total, sizes, jumper" background
|
||||
v-model:current-page="tableOptions.pageNum" v-model:page-size="tableOptions.pageSzie"
|
||||
:page-size="tableOptions.pageSzie" :page-sizes="[10, 20, 30, 50]" :total="tableOptions.total"
|
||||
@size-change="paginationChange" @current-change="paginationChange" />
|
||||
</div>
|
||||
<el-dialog title="修改推广费率" v-model="showFeeDialog" @closed="feeDialogClosed">
|
||||
<el-form ref="formFeeRef" :model="feeForm" :rules="feeRules" label-width="100">
|
||||
<el-form-item prop="fee" label="推广费率">
|
||||
<el-input placeholder="请输入推广费率" v-model="feeForm.fee">
|
||||
<template #append>%</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-space>
|
||||
<el-button @click="showFeeDialog = false">取消</el-button>
|
||||
<el-button type="primary" :loading="showFeeLoading" @click="feeSubmitHandle">提交</el-button>
|
||||
</el-space>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<el-dialog title="添加大机构" v-model="showDialog" @closed="dialogClosed">
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="100">
|
||||
<el-form-item label="机构类型">
|
||||
<el-select v-model="form.userType" disabled>
|
||||
<el-option :key="item.type_code" :label="item.type_name" :value="item.type_code"
|
||||
v-for="item in organizationList" key="item.type_code"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item prop="agencyName" label="机构名称">
|
||||
<el-input placeholder="请输入机构名称" v-model="form.agencyName" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="angencyCode" label="机构代码">
|
||||
<el-input placeholder="请输入机构代码" :maxlength="11" show-word-limit v-model="form.angencyCode" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="passowrd" label="密码">
|
||||
<el-input type="password" show-password placeholder="请输入密码" :maxlength="11" v-model="form.passowrd" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="fee" label="推广费率">
|
||||
<el-input placeholder="请输入推广费率" v-model="form.fee">
|
||||
<template #append>%</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="phone" label="联系方式">
|
||||
<el-input placeholder="请输入手机号" v-model="form.phone" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-space>
|
||||
<el-button @click="showDialog = false">取消</el-button>
|
||||
<el-button type="primary" :loading="formLoading" @click="submitHandle">提交</el-button>
|
||||
</el-space>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<totalEarnings ref="totalEarningsRef" />
|
||||
<el-dialog title="详细数据" width="90%" v-model="showChartCard">
|
||||
<chart-card v-if="showChartCard" :user-id="userId" />
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { addAgency, queryAgency, modifyFee } from '@/api/organization.js'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { validPhone, organizationList, addOrganizations } from '@/utils'
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
import { useUser } from '@/store/user.js'
|
||||
|
||||
import chartCard from '@/components/chartCard.vue';
|
||||
const showChartCard = ref(false)
|
||||
const userId = ref()
|
||||
function checkChartHandle(id) {
|
||||
userId.value = id
|
||||
showChartCard.value = true
|
||||
}
|
||||
|
||||
const storeUser = useUser()
|
||||
|
||||
// totalEarnings组件相关
|
||||
import totalEarnings from '@/components/totalEarnings.vue';
|
||||
const totalEarningsRef = ref('')
|
||||
function showTotalEarnings(parent_user_id) {
|
||||
totalEarningsRef.value.show(parent_user_id)
|
||||
}
|
||||
|
||||
// 显示添加表单
|
||||
const showDialog = ref(false)
|
||||
const formLoading = ref(false)
|
||||
const showFeeDialog = ref(false)
|
||||
const showFeeLoading = ref(false)
|
||||
|
||||
// 获取添加小机构表单实例
|
||||
let formRef = ref(null)
|
||||
// 获取修改费率表单实例
|
||||
let formFeeRef = ref(null)
|
||||
|
||||
// 创建表单
|
||||
const form = reactive({
|
||||
agencyName: '',
|
||||
angencyCode: '',
|
||||
passowrd: '',
|
||||
fee: '',
|
||||
userType: addOrganizations[storeUser.userInfo.userType],
|
||||
phone: ''
|
||||
})
|
||||
|
||||
// 创建修改费率表单
|
||||
const feeForm = reactive({
|
||||
id: '',
|
||||
fee: ''
|
||||
})
|
||||
const feeRules = reactive({
|
||||
fee: [
|
||||
{
|
||||
required: true,
|
||||
message: '',
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
// 表格参数
|
||||
const tableOptions = reactive({
|
||||
loading: true,
|
||||
agencyCode: '',
|
||||
list: [],
|
||||
total: 0,
|
||||
pageNum: 1,
|
||||
pageSzie: 10
|
||||
})
|
||||
|
||||
// 自定义校验密码
|
||||
function passowrdValidate(rule, value, callback) {
|
||||
if (!value) {
|
||||
return callback(new Error(''))
|
||||
} else if (value.length < 6) {
|
||||
return callback(new Error('密码最少6位'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
|
||||
// 自定义校验手机号
|
||||
function phoneValidate(rule, value, callback) {
|
||||
if (!value) {
|
||||
return callback(new Error(''))
|
||||
} else if (!validPhone(value)) {
|
||||
return callback(new Error('请输入正确的手机号'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
|
||||
// 创建form校验规则
|
||||
const rules = reactive({
|
||||
agencyName: [
|
||||
{
|
||||
required: true,
|
||||
message: '',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
angencyCode: [
|
||||
{
|
||||
required: true,
|
||||
message: '',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
passowrd: [
|
||||
{
|
||||
required: true,
|
||||
validator: passowrdValidate,
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
fee: [
|
||||
{
|
||||
required: true,
|
||||
message: '',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
phone: [
|
||||
{
|
||||
required: true,
|
||||
validator: phoneValidate,
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
// 表单关闭
|
||||
function dialogClosed() {
|
||||
formRef.value.resetFields()
|
||||
}
|
||||
|
||||
// 修改费率关闭
|
||||
function feeDialogClosed() {
|
||||
formFeeRef.value.resetFields()
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const submitHandle = async () => {
|
||||
await formRef.value.validate(async (vaild, fields) => {
|
||||
if (vaild) {
|
||||
try {
|
||||
formLoading.value = true
|
||||
await addAgency(form)
|
||||
formLoading.value = false
|
||||
showDialog.value = false
|
||||
ElMessage.success('添加成功')
|
||||
paginationChange()
|
||||
} catch (error) {
|
||||
formLoading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 提交修改费率
|
||||
async function feeSubmitHandle() {
|
||||
await formFeeRef.value.validate(async (vaild) => {
|
||||
if (vaild) {
|
||||
try {
|
||||
showFeeLoading.value = true
|
||||
await modifyFee(feeForm)
|
||||
showFeeLoading.value = false
|
||||
showFeeDialog.value = false
|
||||
ElMessage.success('添加成功')
|
||||
paginationChange()
|
||||
} catch (error) {
|
||||
showFeeLoading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 修改费率
|
||||
function eitorFeeHandle(row) {
|
||||
feeForm.id = row.id
|
||||
feeForm.fee = row.current_fee
|
||||
showFeeDialog.value = true
|
||||
}
|
||||
|
||||
// 搜索
|
||||
function searchHandle() {
|
||||
tableOptions.pageNum = 1;
|
||||
paginationChange()
|
||||
}
|
||||
|
||||
// 分页回调
|
||||
function paginationChange() {
|
||||
tableOptions.loading = true
|
||||
queryAgencyHandle()
|
||||
}
|
||||
|
||||
// 获取机构列表
|
||||
async function queryAgencyHandle() {
|
||||
try {
|
||||
const res = await queryAgency({
|
||||
agencyCode: tableOptions.agencyCode,
|
||||
pageNum: tableOptions.pageNum,
|
||||
pageSzie: tableOptions.pageSzie,
|
||||
userType: 'FO',
|
||||
isExtend: ''
|
||||
})
|
||||
tableOptions.loading = false
|
||||
tableOptions.list = res.list
|
||||
tableOptions.total = res.total
|
||||
} catch (error) { }
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
queryAgencyHandle()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.table {
|
||||
height: calc(100vh - 358px);
|
||||
}
|
||||
</style>
|
||||
60
src/views/organization/components/UploadCard.vue
Normal file
60
src/views/organization/components/UploadCard.vue
Normal file
@@ -0,0 +1,60 @@
|
||||
<template>
|
||||
<el-upload ref="uploadRef" v-model:file-list="fileList" list-type="picture-card" :limit="1" :on-exceed="handleExceed"
|
||||
:auto-upload="false" @change="selectFile" @remove="removeFile" @preview="previewHandle">
|
||||
<el-icon>
|
||||
<Plus />
|
||||
</el-icon>
|
||||
</el-upload>
|
||||
<el-dialog v-model="show" title="图片预览" width="30%">
|
||||
<img class="img" w-full :src="imgUrl" alt="Preview Image" />
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { defineExpose } from 'vue'
|
||||
import { genFileId } from 'element-plus'
|
||||
const show = ref(false)
|
||||
const imgUrl = ref('')
|
||||
|
||||
const uploadRef = ref(null)
|
||||
const fileList = ref([])
|
||||
|
||||
const emit = defineEmits(['selectFile', 'removeFile'])
|
||||
|
||||
// 只能选择一个文件,替换之前的文件
|
||||
const handleExceed = (files) => {
|
||||
uploadRef.value.clearFiles()
|
||||
const file = files[0]
|
||||
file.uid = genFileId()
|
||||
uploadRef.value.handleStart(file)
|
||||
}
|
||||
// 选择图片
|
||||
const selectFile = async (file) => {
|
||||
emit('selectFile', file)
|
||||
fileList.value = [file]
|
||||
}
|
||||
// 移除图片
|
||||
const removeFile = async (file) => {
|
||||
fileList.value = []
|
||||
emit('removeFile')
|
||||
}
|
||||
// 预览图片
|
||||
function previewHandle({ url }) {
|
||||
show.value = true
|
||||
imgUrl.value = url
|
||||
}
|
||||
// 父级传值
|
||||
const pselectFile = async (file) => {
|
||||
fileList.value = [file]
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
pselectFile
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.img {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
80
src/views/organization/components/aisleInfo.vue
Normal file
80
src/views/organization/components/aisleInfo.vue
Normal file
@@ -0,0 +1,80 @@
|
||||
<!-- 通道进件信息 -->
|
||||
<template>
|
||||
<el-form ref="formRef" :model="form" label-width="120" label-position="left">
|
||||
<div class="title_wrap">
|
||||
<el-text>通道进件组1</el-text>
|
||||
</div>
|
||||
<el-form-item label="审核备注组" class="mt15">
|
||||
<el-select v-model="form.remarkGroup">
|
||||
<el-option :value="0" label="退回" />
|
||||
<el-option :value="1" label="通过" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="审核备注">
|
||||
<el-input type="textarea" :autosize="{ minRows: 4 }" v-model="form.remark" placeholder="请输入审核备注"
|
||||
style="width: 50%" />
|
||||
</el-form-item>
|
||||
<el-form-item label="通道选择">
|
||||
<el-radio-group disabled v-model="form.aisle">
|
||||
<el-radio :label="1">随行付</el-radio>
|
||||
<el-radio :label="2">银盛</el-radio>
|
||||
<el-radio :label="3">拉卡拉</el-radio>
|
||||
<el-radio :label="4">银盛D1</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="默认结算方式">
|
||||
<el-input v-model="form.settle" placeholder="请输入默认结算方式" style="width: 50%" />
|
||||
</el-form-item>
|
||||
<el-form-item label="审核状态">
|
||||
<el-input v-model="form.authStatus" disabled style="width: 50%" />
|
||||
</el-form-item>
|
||||
<div class="title_wrap">
|
||||
<el-text>通道进件组2</el-text>
|
||||
</div>
|
||||
<el-form-item label="审核备注组" class="mt15">
|
||||
<el-select v-model="form.remarkGroup">
|
||||
<el-option :value="0" label="退回" />
|
||||
<el-option :value="1" label="通过" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="审核备注">
|
||||
<el-input type="textarea" :autosize="{ minRows: 4 }" v-model="form.remark" placeholder="请输入审核备注"
|
||||
style="width: 50%" />
|
||||
</el-form-item>
|
||||
<el-form-item label="通道选择">
|
||||
<el-radio-group disabled v-model="form.aisle">
|
||||
<el-radio :label="1">随行付</el-radio>
|
||||
<el-radio :label="2">银盛</el-radio>
|
||||
<el-radio :label="3">拉卡拉</el-radio>
|
||||
<el-radio :label="4">银盛D1</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="默认结算方式">
|
||||
<el-input v-model="form.settle" placeholder="请输入默认结算方式" style="width: 50%" />
|
||||
</el-form-item>
|
||||
<el-form-item label="审核状态">
|
||||
<el-input v-model="form.authStatus" disabled style="width: 50%" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-space>
|
||||
<el-button type="primary">通过</el-button>
|
||||
<el-button type="danger">驳回</el-button>
|
||||
<el-button type="danger">驳回并禁止进件</el-button>
|
||||
</el-space>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const form = reactive({
|
||||
remarkGroup: 0,
|
||||
remark: '',
|
||||
aisle: '',
|
||||
settle: '',
|
||||
authStatus: ''
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import './common.scss';
|
||||
</style>
|
||||
359
src/views/organization/components/authentication.vue
Normal file
359
src/views/organization/components/authentication.vue
Normal file
@@ -0,0 +1,359 @@
|
||||
<!-- 实名认证信息 -->
|
||||
<template>
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="120" label-position="left">
|
||||
<el-row :gutter="gutter">
|
||||
<el-col :span="span">
|
||||
<el-form-item prop="username" label="推广员名称">
|
||||
<el-input v-model="form.username" placeholder="请输入推广员名称" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="span">
|
||||
<el-form-item prop="loginname" label="登录账号">
|
||||
<el-input v-model="form.loginname" placeholder="请输入登录账号" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<div class="title_wrap">
|
||||
<el-text>实名身份证</el-text>
|
||||
</div>
|
||||
<el-row :gutter="gutter" class="mt15">
|
||||
<el-col :span="span">
|
||||
<el-form-item prop="idCard.certname" label="姓名">
|
||||
<el-input v-model="form.idCard.certname" placeholder="请输入姓名" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="span">
|
||||
<el-form-item prop="idCard.certno" label="身份证号码">
|
||||
<el-input v-model="form.idCard.certno" placeholder="请输入身份证号码" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="gutter">
|
||||
<el-col :span="span">
|
||||
<el-form-item prop="idCard.certstarttime" label="发放日期">
|
||||
<el-date-picker style="width: 100%;" v-model="form.idCard.certstarttime" type="date"
|
||||
placeholder="请选择发放日期" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="span">
|
||||
<el-form-item prop="idCard.certendtime" label="失效日期">
|
||||
<el-date-picker style="width: 100%;" v-model="form.idCard.certendtime" type="date"
|
||||
placeholder="请选择发放日期" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="gutter">
|
||||
<el-col :span="span">
|
||||
<el-form-item prop="idCard.imgpositive" label="身份证正面">
|
||||
<uploadCard ref="idCardRef1" @selectFile="file => form.idCard.imgpositive = file"
|
||||
@removeFile="form.idCard.imgpositive = ''" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="span">
|
||||
<el-form-item prop="idCard.imgnegative" label="身份证反面">
|
||||
<uploadCard ref="idCardRef2" @selectFile="file => form.idCard.imgnegative = file"
|
||||
@removeFile="form.idCard.imgnegative = ''" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<div class="title_wrap">
|
||||
<el-text>实名银行卡</el-text>
|
||||
</div>
|
||||
<el-row :gutter="gutter" class="mt15">
|
||||
<el-col :span="span">
|
||||
<el-form-item prop="bankCard.bankcardno" label="银行卡号">
|
||||
<el-input v-model="form.bankCard.bankcardno" placeholder="请输入银行卡号" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="span">
|
||||
<el-form-item prop="bankCard.phone" label="预留手机号">
|
||||
<el-input v-model="form.bankCard.phone" placeholder="请输入预留手机号" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="gutter">
|
||||
<el-col :span="span">
|
||||
<el-form-item prop="bankCard.bank" label="开户行地区">
|
||||
<address-card ref="addressRef" placeholder="请选择开户行地区" style="width: 100%;"
|
||||
@change="selectBankAddress" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="span"></el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="gutter">
|
||||
<el-col :span="span">
|
||||
<el-form-item prop="bankCard.bankname" label="开户银行">
|
||||
<el-select style="width: 100%;" v-model="form.bankCard.bankname" placeholder="请选择开户银行"
|
||||
@change="banknameChange">
|
||||
<el-option v-for="item in bankList" :key="item" :value="item" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="span">
|
||||
<el-form-item prop="bankCard.contactline" label="开户支行">
|
||||
<el-select style="width: 100%;" v-model="form.bankCard.contactline" placeholder="请选择开户支行">
|
||||
<el-option :label="item.cnapsName" :value="item.cnapsCode" v-for="item in bankBranchs"
|
||||
:key="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="gutter">
|
||||
<el-col :span="span">
|
||||
<el-form-item prop="bankCard.imgurl" label="银行卡照片">
|
||||
<upload-card ref="uploadBank" @selectFile="file => form.bankCard.imgurl = file"
|
||||
@removeFile="form.bankCard.imgurl = ''" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="submitHandle">立即提交</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import bankList from './bankList'
|
||||
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { uploadOSS } from '@/api/home.js'
|
||||
import uploadCard from './uploadCard.vue'
|
||||
import addressCard from '@/components/addressCard.vue'
|
||||
import { merchantInfoDetail, getBranchList, updatePromoterInformation } from '@/api/shop.js'
|
||||
import { useRoute } from 'vue-router'
|
||||
const route = useRoute()
|
||||
|
||||
const formRef = ref(null)
|
||||
const idCardRef1 = ref(null)
|
||||
const idCardRef2 = ref(null)
|
||||
const uploadBank = ref(null)
|
||||
const addressRef = ref(null)
|
||||
|
||||
const bankBranchs = ref([])
|
||||
|
||||
const span = ref(10)
|
||||
const gutter = ref(50)
|
||||
|
||||
const form = reactive({
|
||||
status: '',
|
||||
id: '',
|
||||
merchantcode: route.query.merchantcode,
|
||||
userid: route.query.id,
|
||||
username: route.query.name,
|
||||
loginname: route.query.account,
|
||||
idCard: {
|
||||
id: '',
|
||||
userid: '',
|
||||
certname: '',
|
||||
certno: '',
|
||||
certstarttime: '',
|
||||
certendtime: '',
|
||||
imgpositive: '',
|
||||
imgnegative: ''
|
||||
},
|
||||
bankCard: {
|
||||
id: '',
|
||||
userid: '',
|
||||
bankcardno: '',
|
||||
phone: '',
|
||||
branchprovince: '',
|
||||
branchcity: '',
|
||||
brancharea: '',
|
||||
bankname: '',
|
||||
contactline: '',
|
||||
imgurl: '',
|
||||
branchProvinceCode: '',
|
||||
branchCityCode: '',
|
||||
branchAreaCode: ''
|
||||
}
|
||||
})
|
||||
|
||||
const rules = reactive({
|
||||
username: [
|
||||
{
|
||||
required: true,
|
||||
message: '',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
loginname: [
|
||||
{
|
||||
required: true,
|
||||
message: '',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
idCard: {
|
||||
certname: [
|
||||
{
|
||||
required: true,
|
||||
message: '',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
certno: [
|
||||
{
|
||||
required: true,
|
||||
message: '',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
certstarttime: [
|
||||
{
|
||||
required: true,
|
||||
message: '',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
certendtime: [
|
||||
{
|
||||
required: true,
|
||||
message: '',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
imgpositive: [
|
||||
{
|
||||
required: true,
|
||||
message: '请选择身份证正面照片',
|
||||
trigger: 'change'
|
||||
}
|
||||
],
|
||||
imgnegative: [
|
||||
{
|
||||
required: true,
|
||||
message: '请选择身份证反面照片',
|
||||
trigger: 'change'
|
||||
}
|
||||
]
|
||||
},
|
||||
bankCard: {
|
||||
bankcardno: [
|
||||
{
|
||||
required: true,
|
||||
message: '',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
phone: [
|
||||
{
|
||||
required: true,
|
||||
message: '',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
bankname: [
|
||||
{
|
||||
required: true,
|
||||
message: '',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
bank: [
|
||||
{
|
||||
required: true,
|
||||
validator: (rule, value, callback) => {
|
||||
if (!form.bankCard.branchprovince || !form.bankCard.branchcity || !form.bankCard.brancharea) {
|
||||
return callback(new Error('请完善开户行地区信息'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
},
|
||||
trigger: 'change'
|
||||
}
|
||||
],
|
||||
contactline: [
|
||||
{
|
||||
required: true,
|
||||
message: '',
|
||||
trigger: 'change'
|
||||
}
|
||||
],
|
||||
imgurl: [
|
||||
{
|
||||
required: true,
|
||||
message: '请选择银行卡照片',
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
// 获取省市区
|
||||
function selectBankAddress(e) {
|
||||
if (e[1].label != form.bankCard.branchcity) {
|
||||
form.bankCard.bankname = ''
|
||||
form.bankCard.contactline = ''
|
||||
}
|
||||
form.bankCard.branchprovince = e[0].label
|
||||
form.bankCard.branchcity = e[1].label
|
||||
form.bankCard.brancharea = e[2].label
|
||||
|
||||
form.bankCard.branchProvinceCode = e[0].code
|
||||
form.bankCard.branchCityCode = e[1].code
|
||||
form.bankCard.branchAreaCode = e[2].code
|
||||
}
|
||||
|
||||
// 确认选择开户银行
|
||||
async function banknameChange(val, city) {
|
||||
try {
|
||||
if (form.bankCard.branchcity || city) {
|
||||
const res = await getBranchList({
|
||||
bankName: val,
|
||||
cityName: city || form.bankCard.branchcity
|
||||
})
|
||||
form.bankCard.contactline = ''
|
||||
bankBranchs.value = res.branchList
|
||||
}
|
||||
} catch (error) { }
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
async function submitHandle() {
|
||||
await formRef.value.validate(async vaild => {
|
||||
if (vaild) {
|
||||
try {
|
||||
if (form.idCard.imgpositive.uid) {
|
||||
form.idCard.imgpositive = await uploadOSS(form.idCard.imgpositive.raw)
|
||||
}
|
||||
if (form.idCard.imgnegative.uid) {
|
||||
form.idCard.imgnegative = await uploadOSS(form.idCard.imgnegative.raw)
|
||||
}
|
||||
if (form.bankCard.imgurl.uid) {
|
||||
form.bankCard.imgurl = await uploadOSS(form.bankCard.imgurl.raw)
|
||||
}
|
||||
await updatePromoterInformation(form)
|
||||
ElMessage.success('提交成功')
|
||||
} catch (error) {
|
||||
console.log('334:提交表单===', error)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 获取实名认证信息
|
||||
async function merchantInfoDetailAjax() {
|
||||
try {
|
||||
const res = await merchantInfoDetail(route.query.id)
|
||||
await banknameChange(res.bankCard.bankname, res.bankCard.branchcity)
|
||||
form.id = res.id
|
||||
form.status = res.status
|
||||
form.bankCard = res.bankCard
|
||||
form.idCard = res.idCard
|
||||
idCardRef1.value.pselectFile({ url: res.idCard.imgpositive })
|
||||
idCardRef2.value.pselectFile({ url: res.idCard.imgnegative })
|
||||
uploadBank.value.pselectFile({ url: res.bankCard.imgurl })
|
||||
addressRef.value.setValue([res.bankCard.branchProvinceCode, res.bankCard.branchCityCode, res.bankCard.branchAreaCode])
|
||||
} catch (error) {
|
||||
console.log('获取实名认证信息:', error)
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
merchantInfoDetailAjax()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import './common.scss';
|
||||
</style>
|
||||
19
src/views/organization/components/bankList.js
Normal file
19
src/views/organization/components/bankList.js
Normal file
@@ -0,0 +1,19 @@
|
||||
export default [
|
||||
'工商银行',
|
||||
'交通银行',
|
||||
'招商银行',
|
||||
'民生银行',
|
||||
'中信银行',
|
||||
'浦发银行',
|
||||
'兴业银行',
|
||||
'光大银行',
|
||||
'广发银行',
|
||||
'平安银行',
|
||||
'北京银行',
|
||||
'华夏银行',
|
||||
'农业银行',
|
||||
'建设银行',
|
||||
'邮政储蓄银行',
|
||||
'中国银行',
|
||||
'宁波银行'
|
||||
]
|
||||
20
src/views/organization/components/common.scss
Normal file
20
src/views/organization/components/common.scss
Normal file
@@ -0,0 +1,20 @@
|
||||
.title_wrap {
|
||||
padding: 14px 20px;
|
||||
background-color: #f9f9f9;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
:deep(.el-text) {
|
||||
align-self: flex-start;
|
||||
}
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
width: 4px;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
background-color: var(--el-color-primary);
|
||||
}
|
||||
}
|
||||
374
src/views/organization/components/settleInfo.vue
Normal file
374
src/views/organization/components/settleInfo.vue
Normal file
@@ -0,0 +1,374 @@
|
||||
<!-- 结算信息 -->
|
||||
<template>
|
||||
<el-row :gutter="gutter">
|
||||
<el-col :span="span">
|
||||
<el-form ref="d1FormRef" :model="d1Form" label-width="120" label-position="left">
|
||||
<div class="title_wrap">
|
||||
<el-text>D1</el-text>
|
||||
<el-text type="danger" size="small" style="margin-top: 6px;">小微
|
||||
(注:请保持银行卡信息(证件号码、开户名、卡号、预留手机号)的匹配性)</el-text>
|
||||
</div>
|
||||
<el-form-item label="开户行地区" class="mt15">
|
||||
<address-card ref="d1AddressRef" placeholder="请选择开户行地区" @change="d1SelectBankAddress"
|
||||
style="width: 80%;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="开户银行">
|
||||
<el-select style="width: 80%;" v-model="d1Form.bankCard.bankname" placeholder="请选择开户银行"
|
||||
@change="d1BanknameChange">
|
||||
<el-option v-for="item in bankList" :key="item" :value="item" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="开户支行">
|
||||
<el-select style="width: 80%;" v-model="d1Form.bankCard.contactline" placeholder="请选择开户支行">
|
||||
<el-option :label="item.cnapsName" :value="item.cnapsCode" v-for="item in bankBranchs"
|
||||
:key="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="支行联行号">
|
||||
<el-input v-model="d1Form.bankCard.contactline" disabled placeholder="请输入支行联行号" style="width: 80%;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="开户名">
|
||||
<el-input v-model="d1Form.bankCard.bankholder" placeholder="请输入开户名" style="width: 80%;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="开户账号">
|
||||
<el-input v-model="d1Form.bankCard.bankcardno" placeholder="请输入开户账号" style="width: 80%;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="预留手机号">
|
||||
<el-input v-model="d1Form.bankCard.phone" placeholder="请输入预留手机号" style="width: 80%;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="身份证号码">
|
||||
<el-input v-model="d1Form.idcard.certno" placeholder="请输入身份证号码" style="width: 80%;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="发放日期">
|
||||
<el-date-picker style="width: 80%;" v-model="d1Form.idcard.createtime" type="date"
|
||||
placeholder="请选择发放日期" />
|
||||
</el-form-item>
|
||||
<el-form-item label="失效日期">
|
||||
<el-date-picker style="width: 80%;" v-model="d1Form.idcard.certendtime" type="date"
|
||||
placeholder="请选择失效日期" />
|
||||
</el-form-item>
|
||||
<el-form-item label="身份证正面">
|
||||
<uploadCard ref="d1idcardRef1" @selectFile="file => d1Form.idcard.imgpositive = file"
|
||||
@removeFile="d1Form.idcard.imgpositive = ''" />
|
||||
</el-form-item>
|
||||
<el-form-item label="身份证反面">
|
||||
<uploadCard ref="d1idcardRef2" @selectFile="file => d1Form.idcard.imgnegative = file"
|
||||
@removeFile="d1Form.idcard.imgnegative = ''" />
|
||||
</el-form-item>
|
||||
<el-form-item label="结算卡图片">
|
||||
<uploadCard ref="d1BankRef3" @selectFile="file => d1Form.bankCard.imgurl = file"
|
||||
@removeFile="d1Form.bankCard.imgurl = ''" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="d1SubmitHandle">保存-D1</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-col>
|
||||
<el-col :span="span">
|
||||
<el-form ref="d0FormRef" :model="d0Form" label-width="120" label-position="left">
|
||||
<div class="title_wrap">
|
||||
<el-text>D0</el-text>
|
||||
<el-text type="danger" size="small" style="margin-top: 6px;">小微
|
||||
(注:请保持银行卡信息(证件号码、开户名、卡号、预留手机号)的匹配性)</el-text>
|
||||
</div>
|
||||
<el-form-item label="开户行地区" class="mt15">
|
||||
<address-card ref="d0AddressRef" placeholder="请选择开户行地区" @change="d0SelectBankAddress"
|
||||
style="width: 80%;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="开户银行">
|
||||
<el-select style="width: 80%;" v-model="d0Form.bankCard.bankname" placeholder="请选择开户银行"
|
||||
@change="d0BanknameChange">
|
||||
<el-option v-for="item in bankList" :key="item" :value="item" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="开户支行">
|
||||
<el-select style="width: 80%;" v-model="d0Form.bankCard.contactline" placeholder="请选择开户支行">
|
||||
<el-option :label="item.cnapsName" :value="item.cnapsCode" v-for="item in bankBranchs"
|
||||
:key="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="支行联行号">
|
||||
<el-input v-model="d0Form.bankCard.contactline" disabled placeholder="请输入支行联行号" style="width: 80%;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="开户名">
|
||||
<el-input v-model="d0Form.bankCard.bankholder" placeholder="请输入开户名" style="width: 80%;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="开户账号">
|
||||
<el-input v-model="d0Form.bankCard.bankcardno" placeholder="请输入开户账号" style="width: 80%;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="预留手机号">
|
||||
<el-input v-model="d0Form.bankCard.phone" placeholder="请输入预留手机号" style="width: 80%;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="身份证号码">
|
||||
<el-input v-model="d0Form.idcard.certno" placeholder="请输入身份证号码" style="width: 80%;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="发放日期">
|
||||
<el-date-picker style="width: 80%;" v-model="d0Form.idcard.createtime" type="date"
|
||||
placeholder="请选择发放日期" />
|
||||
</el-form-item>
|
||||
<el-form-item label="失效日期">
|
||||
<el-date-picker style="width: 80%;" v-model="d0Form.idcard.certendtime" type="date"
|
||||
placeholder="请选择失效日期" />
|
||||
</el-form-item>
|
||||
<el-form-item label="身份证正面">
|
||||
<uploadCard ref="d0idcardRef1" @selectFile="file => d0Form.idcard.imgpositive = file"
|
||||
@removeFile="d0Form.idcard.imgpositive = ''" />
|
||||
</el-form-item>
|
||||
<el-form-item label="身份证反面">
|
||||
<uploadCard ref="d0idcardRef2" @selectFile="file => d0Form.idcard.imgnegative = file"
|
||||
@removeFile="d0Form.idcard.imgnegative = ''" />
|
||||
</el-form-item>
|
||||
<el-form-item label="结算卡图片">
|
||||
<uploadCard ref="d0BankRef3" @selectFile="file => d0Form.bankCard.imgurl = file"
|
||||
@removeFile="d0Form.bankCard.imgurl = ''" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="d0SubmitHandle">保存-D0</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import bankList from './bankList';
|
||||
|
||||
import addressCard from '@/components/addressCard.vue'
|
||||
import uploadCard from './uploadCard.vue'
|
||||
|
||||
import { uploadOSS } from '@/api/home.js'
|
||||
import { merchBaseAccount, getBranchList, updateAccount } from '@/api/shop.js'
|
||||
|
||||
import { useRoute } from 'vue-router'
|
||||
const route = useRoute()
|
||||
|
||||
const span = ref(12)
|
||||
const gutter = ref(50)
|
||||
|
||||
const d1FormRef = ref(null)
|
||||
const d1AddressRef = ref(null)
|
||||
const d1idcardRef1 = ref(null)
|
||||
const d1idcardRef2 = ref(null)
|
||||
const d1BankRef3 = ref(null)
|
||||
const bankBranchs = ref([])
|
||||
const d1Form = reactive({
|
||||
userid: route.query.id,
|
||||
channeltype: 'D1',
|
||||
bankCard: {
|
||||
id: '',
|
||||
userid: '',
|
||||
bankholder: '',
|
||||
bankcardno: '',
|
||||
bankname: '',
|
||||
branchname: '',
|
||||
accounttype: '',
|
||||
contactline: '',
|
||||
branchprovince: '',
|
||||
branchProvinceCode: '',
|
||||
branchcity: '',
|
||||
branchCityCode: '',
|
||||
brancharea: '',
|
||||
branchAreaCode: '',
|
||||
bankaddressno: '',
|
||||
phone: '',
|
||||
imgurl: ''
|
||||
},
|
||||
idcard: {
|
||||
id: '',
|
||||
userid: '',
|
||||
usertype: '',
|
||||
certtype: '',
|
||||
certno: '',
|
||||
certname: '',
|
||||
certstarttime: '',
|
||||
certendtime: '',
|
||||
certaddress: '',
|
||||
createtime: '',
|
||||
updatetime: '',
|
||||
imgpositive: '',
|
||||
imgnegative: '',
|
||||
virtypeflag: ''
|
||||
}
|
||||
})
|
||||
|
||||
// d1获取省市区
|
||||
function d1SelectBankAddress(e) {
|
||||
if (e[1].label != d1Form.bankCard.branchcity) {
|
||||
d1Form.bankCard.bankname = ''
|
||||
d1Form.bankCard.contactline = ''
|
||||
}
|
||||
d1Form.bankCard.branchprovince = e[0].label
|
||||
d1Form.bankCard.branchcity = e[1].label
|
||||
d1Form.bankCard.brancharea = e[2].label
|
||||
|
||||
d1Form.bankCard.branchProvinceCode = e[0].code
|
||||
d1Form.bankCard.branchCityCode = e[1].code
|
||||
d1Form.bankCard.branchAreaCode = e[2].code
|
||||
}
|
||||
|
||||
// d1确认选择开户银行
|
||||
async function d1BanknameChange(val, city) {
|
||||
try {
|
||||
if (d1Form.bankCard.branchcity || city) {
|
||||
const res = await getBranchList({
|
||||
bankName: val,
|
||||
cityName: city || d1Form.bankCard.branchcity
|
||||
})
|
||||
d1Form.bankCard.contactline = ''
|
||||
bankBranchs.value = res.branchList
|
||||
}
|
||||
} catch (error) {
|
||||
console.log('确认选择开户银行error', error)
|
||||
}
|
||||
}
|
||||
|
||||
// D1提交表单
|
||||
async function d1SubmitHandle() {
|
||||
try {
|
||||
if (d1Form.idcard.imgpositive.uid) {
|
||||
d1Form.idcard.imgpositive = await uploadOSS(d1Form.idcard.imgpositive.raw)
|
||||
}
|
||||
if (d1Form.idcard.imgnegative.uid) {
|
||||
d1Form.idcard.imgnegative = await uploadOSS(d1Form.idcard.imgnegative.raw)
|
||||
}
|
||||
if (d1Form.bankCard.imgurl.uid) {
|
||||
d1Form.bankCard.imgurl = await uploadOSS(d1Form.bankCard.imgurl.raw)
|
||||
}
|
||||
await updateAccount(d1Form)
|
||||
ElMessage.success('提交成功')
|
||||
} catch (error) {
|
||||
console.log('D1提交表单error', error)
|
||||
}
|
||||
}
|
||||
|
||||
const d0AddressRef = ref(null)
|
||||
const d0idcardRef1 = ref(null)
|
||||
const d0idcardRef2 = ref(null)
|
||||
const d0BankRef3 = ref(null)
|
||||
const d0FormRef = ref(null)
|
||||
const d0Form = reactive({
|
||||
userid: route.query.id,
|
||||
channeltype: 'D0',
|
||||
bankCard: {
|
||||
id: '',
|
||||
userid: '',
|
||||
bankholder: '',
|
||||
bankcardno: '',
|
||||
bankname: '',
|
||||
branchname: '',
|
||||
accounttype: '',
|
||||
contactline: '',
|
||||
branchprovince: '',
|
||||
branchProvinceCode: '',
|
||||
branchcity: '',
|
||||
branchCityCode: '',
|
||||
brancharea: '',
|
||||
branchAreaCode: '',
|
||||
bankaddressno: '',
|
||||
phone: '',
|
||||
imgurl: ''
|
||||
},
|
||||
idcard: {
|
||||
id: '',
|
||||
userid: '',
|
||||
usertype: '',
|
||||
certtype: '',
|
||||
certno: '',
|
||||
certname: '',
|
||||
certstarttime: '',
|
||||
certendtime: '',
|
||||
certaddress: '',
|
||||
createtime: '',
|
||||
updatetime: '',
|
||||
imgpositive: '',
|
||||
imgnegative: '',
|
||||
virtypeflag: ''
|
||||
}
|
||||
})
|
||||
const d0Rule = reactive({})
|
||||
|
||||
// d0获取省市区
|
||||
function d0SelectBankAddress(e) {
|
||||
if (e[1].label != d0Form.bankCard.branchcity) {
|
||||
d0Form.bankCard.bankname = ''
|
||||
d0Form.bankCard.contactline = ''
|
||||
}
|
||||
d0Form.bankCard.branchprovince = e[0].label
|
||||
d0Form.bankCard.branchcity = e[1].label
|
||||
d0Form.bankCard.brancharea = e[2].label
|
||||
|
||||
d0Form.bankCard.branchProvinceCode = e[0].code
|
||||
d0Form.bankCard.branchCityCode = e[1].code
|
||||
d0Form.bankCard.branchAreaCode = e[2].code
|
||||
}
|
||||
|
||||
// d0确认选择开户银行
|
||||
async function d0BanknameChange(val, city) {
|
||||
try {
|
||||
if (d0Form.bankCard.branchcity || city) {
|
||||
const res = await getBranchList({
|
||||
bankName: val,
|
||||
cityName: city || d0Form.bankCard.branchcity
|
||||
})
|
||||
d0Form.bankCard.contactline = ''
|
||||
bankBranchs.value = res.branchList
|
||||
}
|
||||
} catch (error) {
|
||||
console.log('确认选择开户银行error', error)
|
||||
}
|
||||
}
|
||||
|
||||
// D0提交表单
|
||||
async function d0SubmitHandle() {
|
||||
try {
|
||||
if (d0Form.idcard.imgpositive.uid) {
|
||||
d0Form.idcard.imgpositive = await uploadOSS(d0Form.idcard.imgpositive.raw)
|
||||
}
|
||||
if (d0Form.idcard.imgnegative.uid) {
|
||||
d0Form.idcard.imgnegative = await uploadOSS(d0Form.idcard.imgnegative.raw)
|
||||
}
|
||||
if (d0Form.bankCard.imgurl.uid) {
|
||||
d0Form.bankCard.imgurl = await uploadOSS(d0Form.bankCard.imgurl.raw)
|
||||
}
|
||||
await updateAccount(d0Form)
|
||||
ElMessage.success('提交成功')
|
||||
} catch (error) {
|
||||
console.log('d0提交表单error', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 结算信息
|
||||
async function merchBaseAccountAjax() {
|
||||
try {
|
||||
const res = await merchBaseAccount(route.query.id)
|
||||
await d1BanknameChange(res.D1.bankCard.bankname, res.D1.bankCard.branchcity)
|
||||
await d0BanknameChange(res.D1.bankCard.bankname, res.D1.bankCard.branchcity)
|
||||
|
||||
d1Form.bankCard = res.D1.bankCard
|
||||
d1Form.idcard = res.D1.idCard
|
||||
|
||||
d0Form.bankCard = res.D0.bankCard
|
||||
d0Form.idcard = res.D0.idCard
|
||||
|
||||
d1idcardRef1.value.pselectFile({ url: res.D1.idCard.imgpositive })
|
||||
d1idcardRef2.value.pselectFile({ url: res.D1.idCard.imgnegative })
|
||||
d1BankRef3.value.pselectFile({ url: res.D1.bankCard.imgurl })
|
||||
d1AddressRef.value.setValue([res.D1.bankCard.branchProvinceCode, res.D1.bankCard.branchCityCode, res.D1.bankCard.branchAreaCode])
|
||||
|
||||
d0idcardRef1.value.pselectFile({ url: res.D0.idCard.imgpositive })
|
||||
d0idcardRef2.value.pselectFile({ url: res.D0.idCard.imgnegative })
|
||||
d0BankRef3.value.pselectFile({ url: res.D0.bankCard.imgurl })
|
||||
d0AddressRef.value.setValue([res.D0.bankCard.branchProvinceCode, res.D0.bankCard.branchCityCode, res.D0.bankCard.branchAreaCode])
|
||||
} catch (error) {
|
||||
console.log('结算信息error:', error)
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
merchBaseAccountAjax()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import './common.scss';
|
||||
</style>
|
||||
279
src/views/organization/components/shopInfo.vue
Normal file
279
src/views/organization/components/shopInfo.vue
Normal file
@@ -0,0 +1,279 @@
|
||||
<!-- 商户基本信息组件 -->
|
||||
<template>
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="120" label-position="left">
|
||||
<el-row :gutter="gutter">
|
||||
<el-col :span="span">
|
||||
<el-form-item prop="merchantname" label="商户名称">
|
||||
<el-input v-model="form.merchantname" placeholder="请输入商户名称" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="span">
|
||||
<el-form-item label="商户类型">
|
||||
<el-input v-model="form.merchanttype" readonly placeholder="请输入商户类型" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="gutter">
|
||||
<el-col :span="span">
|
||||
<el-form-item prop="alias" label="商户简称">
|
||||
<el-input v-model="form.alias" placeholder="请输入商户简称" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="span">
|
||||
<el-form-item prop="contactname" label="商户联系人">
|
||||
<el-input v-model="form.contactname" placeholder="请输入商户联系人" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="gutter">
|
||||
<el-col :span="span">
|
||||
<el-form-item prop="email" label="联系人邮箱">
|
||||
<el-input v-model="form.email" placeholder="请输入联系人邮箱" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="span">
|
||||
<el-form-item prop="contactmobile" label="联系人电话">
|
||||
<el-input v-model="form.contactmobile" placeholder="请输入联系人电话" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="gutter">
|
||||
<el-col :span="span">
|
||||
<el-form-item prop="mcc" label="经营类目">
|
||||
<el-input v-model="form.mccname" suffix-icon="ArrowDown" readonly placeholder="请选择经营类目"
|
||||
@click="showDialog = true" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="gutter">
|
||||
<el-col :span="span">
|
||||
<el-form-item prop="province" label="商户地址">
|
||||
<address-card ref="addressRef" placeholder="请选择商户地址" style="width: 100%;" @change="selectBankAddress" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="gutter">
|
||||
<el-col :span="span">
|
||||
<el-form-item prop="address" label="详细地址">
|
||||
<el-input v-model="form.address" placeholder="请输入详细地址" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="gutter">
|
||||
<el-col :span="span">
|
||||
<el-form-item prop="picUrl6" label="门头照">
|
||||
<upload-card ref="uploadRef1" @selectFile="file => form.picUrl6 = file"
|
||||
@removeFile="form.picUrl6 = ''" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="span">
|
||||
<el-form-item prop="picUrl6" label="收银台照">
|
||||
<upload-card ref="uploadRef2" @selectFile="file => form.picUrl8 = file"
|
||||
@removeFile="form.picUrl8 = ''" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="span">
|
||||
<el-form-item prop="picUrl6" label="门店内场景照">
|
||||
<upload-card ref="uploadRef3" @selectFile="file => form.picUrl9 = file"
|
||||
@removeFile="form.picUrl9 = ''" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="submitHandel">立即提交</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-dialog title="经营类目" v-model="showDialog" @open="mccOpen">
|
||||
<el-space>
|
||||
<el-input v-model="mccTable.keyWord" placeholder="请输入关键字搜索"></el-input>
|
||||
<el-button type="primary" icon="Search" @click="mccOpen">搜索</el-button>
|
||||
</el-space>
|
||||
<div class="mt15">
|
||||
<el-table :data="mccTable.list" v-loading="mccTable.loading">
|
||||
<el-table-column prop="fId" label="id"></el-table-column>
|
||||
<el-table-column prop="fMccCode" label="code"></el-table-column>
|
||||
<el-table-column prop="fMccTxt" label="三级类目名称"></el-table-column>
|
||||
<el-table-column label="操作" width="100">
|
||||
<template #default="scope">
|
||||
<el-button type="primary" size="small" @click="selectMcc(scope.row)">选择</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="mt15">
|
||||
<el-pagination layout="prev, pager, next, total, sizes, jumper" background
|
||||
v-model:current-page="mccTable.pageNum" v-model:page-size="mccTable.pageSize" :page-size="mccTable.pageSize"
|
||||
:page-sizes="[10, 20, 30, 50]" :total="mccTable.total" @size-change="paginationChange"
|
||||
@current-change="paginationChange" />
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import uploadCard from './uploadCard.vue'
|
||||
import addressCard from '@/components/addressCard.vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
||||
import { uploadOSS } from '@/api/home.js'
|
||||
import { mccPageData, merchBaseInfo, updateMerchantInformation } from '@/api/shop.js'
|
||||
|
||||
import { useRoute } from 'vue-router'
|
||||
import { reactive } from 'vue';
|
||||
import { ElDialog } from 'element-plus';
|
||||
const route = useRoute()
|
||||
|
||||
const span = ref(8)
|
||||
const gutter = ref(50)
|
||||
|
||||
const formRef = ref(null)
|
||||
const addressRef = ref(null)
|
||||
const uploadRef1 = ref(null)
|
||||
const uploadRef2 = ref(null)
|
||||
const uploadRef3 = ref(null)
|
||||
|
||||
const form = reactive({
|
||||
id: '',
|
||||
userid: route.query.id,
|
||||
merchantname: '',
|
||||
merchanttype: '',
|
||||
merchantcode: route.query.merchantcode,
|
||||
alias: '',
|
||||
contactname: '',
|
||||
email: '',
|
||||
contactmobile: '',
|
||||
mcc: '',
|
||||
mccname: '',
|
||||
province: '',
|
||||
provinceCode: '',
|
||||
city: '',
|
||||
cityCode: '',
|
||||
district: '',
|
||||
districtCode: '',
|
||||
address: '',
|
||||
picUrl6: '',
|
||||
picUrl8: '',
|
||||
picUrl9: '',
|
||||
picUrl101: '',
|
||||
picUrl102: ''
|
||||
})
|
||||
|
||||
const rules = reactive({})
|
||||
|
||||
// 获取省市区
|
||||
function selectBankAddress(e) {
|
||||
form.province = e[0].label
|
||||
form.city = e[1].label
|
||||
form.district = e[2].label
|
||||
|
||||
form.provinceCode = e[0].code
|
||||
form.cityCode = e[1].code
|
||||
form.districtCode = e[2].code
|
||||
}
|
||||
|
||||
// 立即提交
|
||||
async function submitHandel() {
|
||||
await formRef.value.validate(async (vaild) => {
|
||||
if (vaild) {
|
||||
if (form.picUrl6.uid) {
|
||||
form.picUrl6 = await uploadOSS(form.picUrl6.raw)
|
||||
}
|
||||
if (form.picUrl8.uid) {
|
||||
form.picUrl8 = await uploadOSS(form.picUrl8.raw)
|
||||
}
|
||||
if (form.picUrl9.uid) {
|
||||
form.picUrl9 = await uploadOSS(form.picUrl9.raw)
|
||||
}
|
||||
await updateMerchantInformation(form)
|
||||
ElMessage.success('修改成功')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 获取经营类目
|
||||
const showDialog = ref(false)
|
||||
const mccTable = reactive({
|
||||
loading: true,
|
||||
keyWord: '',
|
||||
list: [],
|
||||
total: 0,
|
||||
pageNum: 1,
|
||||
pageSize: 10
|
||||
})
|
||||
|
||||
function mccOpen() {
|
||||
mccTable.pageNum = 1
|
||||
paginationChange()
|
||||
}
|
||||
|
||||
function paginationChange() {
|
||||
mccTable.loading = true
|
||||
mccPageDataAjax()
|
||||
}
|
||||
|
||||
async function mccPageDataAjax() {
|
||||
try {
|
||||
const res = await mccPageData({
|
||||
current: mccTable.pageNum,
|
||||
size: mccTable.pageSize,
|
||||
keyWord: mccTable.keyWord
|
||||
})
|
||||
mccTable.loading = false
|
||||
mccTable.list = res.list
|
||||
mccTable.total = res.total
|
||||
} catch (error) {
|
||||
console.log('获取经营类目err===', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 选择mcc
|
||||
function selectMcc(row) {
|
||||
form.mccname = `${row.fMccTxt}[${row.fMccCode}]`
|
||||
form.mcc = row.fMccCode
|
||||
showDialog.value = false
|
||||
}
|
||||
|
||||
// 商户基本信息
|
||||
async function merchBaseInfoAjax() {
|
||||
try {
|
||||
const res = await merchBaseInfo(route.query.id)
|
||||
const m = {
|
||||
1: '小微',
|
||||
2: '个体',
|
||||
3: '企业'
|
||||
}
|
||||
form.id = res.merchantBaseInfo.id
|
||||
form.merchantname = res.merchantBaseInfo.merchantname
|
||||
form.merchanttype = m[res.merchantBaseInfo.merchanttype]
|
||||
form.alias = res.merchantBaseInfo.alias
|
||||
form.contactname = res.merchantBaseInfo.contactname
|
||||
form.email = res.merchantBaseInfo.email
|
||||
form.contactmobile = res.merchantBaseInfo.contactmobile
|
||||
form.mcc = res.merchantBaseInfo.mcc
|
||||
form.mccname = `${res.merchantBaseInfo.mccname}[${res.merchantBaseInfo.mcc}]`
|
||||
form.province = res.merchantBaseInfo.province
|
||||
form.city = res.merchantBaseInfo.city
|
||||
form.district = res.merchantBaseInfo.district
|
||||
form.address = res.merchantBaseInfo.address
|
||||
addressRef.value.setValue([res.merchantBaseInfo.provinceCode, res.merchantBaseInfo.cityCode, res.merchantBaseInfo.districtCode])
|
||||
|
||||
form.picUrl6 = res.merchantImagesList.find(item => item.photoType == '06').picurl
|
||||
uploadRef1.value.pselectFile({ url: form.picUrl6 })
|
||||
|
||||
form.picUrl8 = res.merchantImagesList.find(item => item.photoType == '08').picurl
|
||||
uploadRef2.value.pselectFile({ url: form.picUrl8 })
|
||||
|
||||
form.picUrl9 = res.merchantImagesList.find(item => item.photoType == '09').picurl
|
||||
uploadRef3.value.pselectFile({ url: form.picUrl9 })
|
||||
} catch (error) {
|
||||
console.log('商户基本信息err===', error)
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
merchBaseInfoAjax()
|
||||
mccPageDataAjax()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
131
src/views/organization/maker_apply.vue
Normal file
131
src/views/organization/maker_apply.vue
Normal file
@@ -0,0 +1,131 @@
|
||||
<template>
|
||||
<div class="card">
|
||||
<el-space>
|
||||
<el-input v-model="tableOptions.phone" placeholder="请输入手机号" style="width: 200px;" />
|
||||
<el-input v-model="tableOptions.name" placeholder="请输入姓名" style="width: 200px;" />
|
||||
<el-button type="primary" icon="Search" @click="searchHandle">搜索</el-button>
|
||||
<el-button icon="RefreshRight" @click="resizeTable">重置</el-button>
|
||||
</el-space>
|
||||
<div class="table mt15">
|
||||
<el-table ref="table" :data="tableOptions.list" border height="100%" v-loading="tableOptions.loading">
|
||||
<el-table-column prop="userId" label="id"></el-table-column>
|
||||
<el-table-column prop="name" label="姓名"></el-table-column>
|
||||
<el-table-column prop="phone" label="电话"></el-table-column>
|
||||
<el-table-column prop="status" label="状态">
|
||||
<template #default="scope">
|
||||
<el-tag type="info" disable-transitions round v-if="scope.row.status == 0">申请中</el-tag>
|
||||
<el-tag type="success" disable-transitions round v-if="scope.row.status == 1">已通过</el-tag>
|
||||
<el-tag type="danger" disable-transitions round v-if="scope.row.status == 5">已驳回</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" label="创建时间">
|
||||
<template #default="scope">
|
||||
<el-text>{{ dayjs(scope.row.createTime).format('YYYY-MM-DD HH:mm:ss') }}</el-text>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="120">
|
||||
<template #default="scope">
|
||||
<template v-if="scope.row.status == 0">
|
||||
<el-popconfirm title="是否通过审核?" width="200" confirm-button-text="通过" cancel-button-text="驳回"
|
||||
@cancel="checkHandle(scope.row, 5)" @confirm="checkHandle(scope.row, 1)">
|
||||
<template #reference>
|
||||
<el-button type="primary" size="small" icon="EditPen">待审核</el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-button type="default" size="small" icon="EditPen" disabled v-if="scope.row.status == 1">
|
||||
已通过
|
||||
</el-button>
|
||||
<el-button type="default" size="small" icon="EditPen" disabled v-if="scope.row.status == 5">
|
||||
已驳回
|
||||
</el-button>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="mt15">
|
||||
<el-pagination layout="prev, pager, next, total, sizes, jumper" background
|
||||
v-model:current-page="tableOptions.pageNum" v-model:page-size="tableOptions.pageSzie"
|
||||
:page-size="tableOptions.pageSzie" :page-sizes="[10, 20, 30, 50]" :total="tableOptions.total"
|
||||
@size-change="paginationChange" @current-change="paginationChange" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onMounted } from 'vue';
|
||||
import { dayjs, ElMessage } from 'element-plus';
|
||||
import { getUserMark, updateUserMark } from '@/api/shop.js'
|
||||
|
||||
const table = ref(null)
|
||||
|
||||
|
||||
// 表格参数
|
||||
const tableOptions = reactive({
|
||||
loading: true,
|
||||
phone: '',
|
||||
name: '',
|
||||
list: [],
|
||||
total: 0,
|
||||
pageNum: 1,
|
||||
pageSize: 10
|
||||
})
|
||||
|
||||
// 重置表格
|
||||
function resizeTable() {
|
||||
tableOptions.phone = ''
|
||||
tableOptions.name = ''
|
||||
searchHandle()
|
||||
}
|
||||
|
||||
// 搜索
|
||||
function searchHandle() {
|
||||
tableOptions.pageNum = 1;
|
||||
paginationChange()
|
||||
}
|
||||
|
||||
// 分页回调
|
||||
function paginationChange() {
|
||||
tableOptions.loading = true
|
||||
getUserMarkAjax()
|
||||
}
|
||||
|
||||
// 审核
|
||||
async function checkHandle(row, type) {
|
||||
try {
|
||||
await updateUserMark({
|
||||
status: type,
|
||||
id: row.userId,
|
||||
remark: ''
|
||||
})
|
||||
ElMessage.success('提交成功')
|
||||
resizeTable()
|
||||
} catch (error) {
|
||||
}
|
||||
}
|
||||
|
||||
// 获取创客审核列表
|
||||
async function getUserMarkAjax() {
|
||||
try {
|
||||
const res = await getUserMark({
|
||||
phone: tableOptions.phone,
|
||||
name: tableOptions.name,
|
||||
pageNum: tableOptions.pageNum,
|
||||
pageSize: tableOptions.pageSize
|
||||
})
|
||||
tableOptions.loading = false
|
||||
tableOptions.list = res.list
|
||||
tableOptions.total = res.total
|
||||
table.value.setScrollTop(0)
|
||||
} catch (error) {
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getUserMarkAjax()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
333
src/views/organization/mini_organization.vue
Normal file
333
src/views/organization/mini_organization.vue
Normal file
@@ -0,0 +1,333 @@
|
||||
<template>
|
||||
<div class="card">
|
||||
<div class="pb15" v-permission="['FO']">
|
||||
<el-button type="primary" icon="Plus" @click="showDialog = true">添加小机构</el-button>
|
||||
</div>
|
||||
<el-space>
|
||||
<el-input placeholder="请输入机构代码搜索" v-model="tableOptions.agencyCode" style="width: 200px;" />
|
||||
<el-button type="primary" icon="Search" @click="searchHandle">搜索</el-button>
|
||||
</el-space>
|
||||
<div class="table mt15">
|
||||
<el-table :data="tableOptions.list" size="large" stripe border v-loading="tableOptions.loading">
|
||||
<el-table-column prop="id" label="机构id"></el-table-column>
|
||||
<el-table-column prop="agencyName" label="机构名称">
|
||||
<template #default="scope">
|
||||
<el-text>{{ scope.row.agencyName || scope.row.agencyCode }}</el-text>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="agencyCode" label="机构代码"></el-table-column>
|
||||
<el-table-column prop="current_fee" label="推广费率">
|
||||
<template #default="scope" v-permission="['FO']">
|
||||
<el-link icon="EditPen" type="primary" @click="eitorFeeHandle(scope.row)">
|
||||
{{ scope.row.current_fee }}%
|
||||
</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="parentLoginName" label="上级机构代码"></el-table-column>
|
||||
<el-table-column prop="sumConsumeFee" label="总流水">
|
||||
<template #default="scope">
|
||||
<el-text>{{ scope.row.sumConsumeFee.toFixed(2) }}</el-text>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="yestedayConsumeFee" label="今日流水"></el-table-column>
|
||||
<el-table-column prop="sumfansShareMoney" label="总收益">
|
||||
<template #default="scope">
|
||||
<el-link type="primary" icon="search" @click="showTotalEarnings(scope.row.id)">
|
||||
{{ scope.row.sumfansShareMoney }}
|
||||
</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="yestedayShareMoney" label="今日收益"></el-table-column>
|
||||
<el-table-column prop="sumAccount" label="商家数量"></el-table-column>
|
||||
<el-table-column label="操作">
|
||||
<template #default="scope">
|
||||
<el-button size="small" type="primary" icon="DataLine"
|
||||
@click="checkChartHandle(scope.row.id)">详细数据</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="mt15">
|
||||
<el-pagination layout="prev, pager, next, total, sizes, jumper" background
|
||||
v-model:current-page="tableOptions.pageNum" v-model:page-size="tableOptions.pageSzie"
|
||||
:page-size="tableOptions.pageSzie" :page-sizes="[10, 20, 30, 50]" :total="tableOptions.total"
|
||||
@size-change="paginationChange" @current-change="paginationChange" />
|
||||
</div>
|
||||
<el-dialog title="修改推广费率" v-model="showFeeDialog" @closed="feeDialogClosed">
|
||||
<el-form ref="formFeeRef" :model="feeForm" :rules="feeRules" label-width="100">
|
||||
<el-form-item prop="fee" label="推广费率">
|
||||
<el-input placeholder="请输入推广费率" v-model="feeForm.fee">
|
||||
<template #append>%</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-space>
|
||||
<el-button @click="showFeeDialog = false">取消</el-button>
|
||||
<el-button type="primary" :loading="showFeeLoading" @click="feeSubmitHandle">提交</el-button>
|
||||
</el-space>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<el-dialog title="添加小机构" v-model="showDialog" @closed="dialogClosed">
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="100">
|
||||
<el-form-item label="机构类型">
|
||||
<el-select v-model="form.userType" disabled>
|
||||
<el-option :key="item.type_code" :label="item.type_name" :value="item.type_code"
|
||||
v-for="item in organizationList" key="item.type_code"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item prop="agencyName" label="机构名称">
|
||||
<el-input placeholder="请输入机构名称" v-model="form.agencyName" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="angencyCode" label="机构代码">
|
||||
<el-input placeholder="请输入机构代码" :maxlength="11" show-word-limit v-model="form.angencyCode" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="passowrd" label="密码">
|
||||
<el-input type="password" show-password placeholder="请输入密码" :maxlength="11" v-model="form.passowrd" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="fee" label="推广费率">
|
||||
<el-input placeholder="请输入推广费率" v-model="form.fee">
|
||||
<template #append>%</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="phone" label="联系方式">
|
||||
<el-input placeholder="请输入手机号" v-model="form.phone" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-space>
|
||||
<el-button @click="showDialog = false">取消</el-button>
|
||||
<el-button type="primary" :loading="formLoading" @click="submitHandle">提交</el-button>
|
||||
</el-space>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<totalEarnings ref="totalEarningsRef" />
|
||||
<el-dialog title="详细数据" width="90%" v-model="showChartCard">
|
||||
<chart-card v-if="showChartCard" :user-id="userId" />
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { addAgency, queryAgency, modifyFee } from '@/api/organization.js'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { validPhone, organizationList, addOrganizations } from '@/utils'
|
||||
import { onMounted, reactive } from 'vue';
|
||||
import { useUser } from '@/store/user.js'
|
||||
|
||||
// 图表相关
|
||||
import chartCard from '@/components/chartCard.vue';
|
||||
const showChartCard = ref(false)
|
||||
const userId = ref()
|
||||
function checkChartHandle(id) {
|
||||
userId.value = id
|
||||
showChartCard.value = true
|
||||
}
|
||||
|
||||
// totalEarnings组件相关
|
||||
import totalEarnings from '@/components/totalEarnings.vue';
|
||||
const totalEarningsRef = ref('')
|
||||
function showTotalEarnings(parent_user_id) {
|
||||
totalEarningsRef.value.show(parent_user_id)
|
||||
}
|
||||
|
||||
const storeUser = useUser()
|
||||
|
||||
// 显示添加表单
|
||||
const showDialog = ref(false)
|
||||
const formLoading = ref(false)
|
||||
const showFeeDialog = ref(false)
|
||||
const showFeeLoading = ref(false)
|
||||
|
||||
// 获取添加小机构表单实例
|
||||
let formRef = ref(null)
|
||||
// 获取修改费率表单实例
|
||||
let formFeeRef = ref(null)
|
||||
|
||||
// 创建表单
|
||||
const form = reactive({
|
||||
agencyName: '',
|
||||
angencyCode: '',
|
||||
passowrd: '',
|
||||
fee: '',
|
||||
userType: addOrganizations[storeUser.userInfo.userType],
|
||||
phone: ''
|
||||
})
|
||||
|
||||
// 创建修改费率表单
|
||||
const feeForm = reactive({
|
||||
id: '',
|
||||
fee: ''
|
||||
})
|
||||
const feeRules = reactive({
|
||||
fee: [
|
||||
{
|
||||
required: true,
|
||||
message: '',
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
// 表格参数
|
||||
const tableOptions = reactive({
|
||||
loading: true,
|
||||
agencyCode: '',
|
||||
list: [],
|
||||
total: 0,
|
||||
pageNum: 1,
|
||||
pageSzie: 10
|
||||
})
|
||||
|
||||
// 自定义校验密码
|
||||
function passowrdValidate(rule, value, callback) {
|
||||
if (!value) {
|
||||
return callback(new Error(''))
|
||||
} else if (value.length < 6) {
|
||||
return callback(new Error('密码最少6位'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
|
||||
// 自定义校验手机号
|
||||
function phoneValidate(rule, value, callback) {
|
||||
if (!value) {
|
||||
return callback(new Error(''))
|
||||
} else if (!validPhone(value)) {
|
||||
return callback(new Error('请输入正确的手机号'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
|
||||
// 创建form校验规则
|
||||
const rules = reactive({
|
||||
agencyName: [
|
||||
{
|
||||
required: true,
|
||||
message: '',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
angencyCode: [
|
||||
{
|
||||
required: true,
|
||||
message: '',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
passowrd: [
|
||||
{
|
||||
required: true,
|
||||
validator: passowrdValidate,
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
fee: [
|
||||
{
|
||||
required: true,
|
||||
message: '',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
phone: [
|
||||
{
|
||||
required: true,
|
||||
validator: phoneValidate,
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
// 表单关闭
|
||||
function dialogClosed() {
|
||||
formRef.value.resetFields()
|
||||
}
|
||||
|
||||
// 修改费率关闭
|
||||
function feeDialogClosed() {
|
||||
formFeeRef.value.resetFields()
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const submitHandle = async () => {
|
||||
await formRef.value.validate(async (vaild, fields) => {
|
||||
if (vaild) {
|
||||
try {
|
||||
formLoading.value = true
|
||||
await addAgency(form)
|
||||
formLoading.value = false
|
||||
showDialog.value = false
|
||||
ElMessage.success('添加成功')
|
||||
paginationChange()
|
||||
} catch (error) {
|
||||
formLoading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 提交修改费率
|
||||
async function feeSubmitHandle() {
|
||||
await formFeeRef.value.validate(async (vaild) => {
|
||||
if (vaild) {
|
||||
try {
|
||||
showFeeLoading.value = true
|
||||
await modifyFee(feeForm)
|
||||
showFeeLoading.value = false
|
||||
showFeeDialog.value = false
|
||||
ElMessage.success('添加成功')
|
||||
paginationChange()
|
||||
} catch (error) {
|
||||
showFeeLoading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 修改费率
|
||||
function eitorFeeHandle(row) {
|
||||
feeForm.id = row.id
|
||||
feeForm.fee = row.current_fee
|
||||
showFeeDialog.value = true
|
||||
}
|
||||
|
||||
// 搜索
|
||||
function searchHandle() {
|
||||
tableOptions.pageNum = 1;
|
||||
paginationChange()
|
||||
}
|
||||
|
||||
// 分页回调
|
||||
function paginationChange() {
|
||||
tableOptions.loading = true
|
||||
queryAgencyHandle()
|
||||
}
|
||||
|
||||
// 获取机构列表
|
||||
async function queryAgencyHandle() {
|
||||
try {
|
||||
const res = await queryAgency({
|
||||
agencyCode: tableOptions.agencyCode,
|
||||
pageNum: tableOptions.pageNum,
|
||||
pageSzie: tableOptions.pageSzie,
|
||||
userType: 'SO',
|
||||
isExtend: ''
|
||||
})
|
||||
tableOptions.loading = false
|
||||
tableOptions.list = res.list
|
||||
tableOptions.total = res.total
|
||||
} catch (error) { }
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
queryAgencyHandle()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.table {
|
||||
height: calc(100vh - 310px);
|
||||
}
|
||||
</style>
|
||||
339
src/views/organization/one_promotion_list.vue
Normal file
339
src/views/organization/one_promotion_list.vue
Normal file
@@ -0,0 +1,339 @@
|
||||
<template>
|
||||
<div class="card">
|
||||
<!-- <el-row>
|
||||
<el-space>
|
||||
<el-button type="primary" icon="Plus" @click="showDialog = true" v-permission="['SO']">添加大机构</el-button>
|
||||
</el-space>
|
||||
</el-row> -->
|
||||
<el-space>
|
||||
<el-input placeholder="请输入机构代码搜索" v-model="tableOptions.agencyCode" style="width: 200px;" />
|
||||
<el-button type="primary" icon="Search" @click="searchHandle">搜索</el-button>
|
||||
</el-space>
|
||||
<div class="table mt15">
|
||||
<el-table :data="tableOptions.list" size="large" stripe border height="100%" v-loading="tableOptions.loading">
|
||||
<el-table-column prop="id" label="机构id"></el-table-column>
|
||||
<el-table-column prop="agencyName" label="代理名称">
|
||||
<template #default="scope">
|
||||
<el-text>{{ scope.row.agencyName || scope.row.agencyCode }}</el-text>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="agencyCode" label="机构代码"></el-table-column>
|
||||
<el-table-column prop="current_fee" label="推广费率">
|
||||
<template #default="scope">
|
||||
<el-text>{{ scope.row.current_fee }}%</el-text>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="parentLoginName" label="上级机构代码"></el-table-column>
|
||||
<el-table-column prop="sumConsumeFee" label="总流水">
|
||||
<template #default="scope">
|
||||
<el-text>{{ scope.row.sumConsumeFee.toFixed(2) }}</el-text>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="yestedayConsumeFee" label="今日流水"></el-table-column>
|
||||
<el-table-column prop="sumfansShareMoney" label="总收益">
|
||||
<template #default="scope">
|
||||
<el-link type="primary" icon="search" @click="showTotalEarnings(scope.row.id)">
|
||||
{{ scope.row.sumfansShareMoney }}
|
||||
</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="yestedayShareMoney" label="今日收益"></el-table-column>
|
||||
<el-table-column prop="sumAccount" label="商家数量"></el-table-column>
|
||||
<el-table-column label="操作">
|
||||
<template #default="scope">
|
||||
<el-button size="small" type="primary" icon="DataLine"
|
||||
@click="checkChartHandle(scope.row.id)">详细数据</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- <el-table-column label="操作">
|
||||
<template #default="scope">
|
||||
<el-button type="primary" size="small" icon="EditPen" @click="eitorFeeHandle(scope.row)"
|
||||
v-permission="['SO']">修改费率</el-button>
|
||||
</template>
|
||||
</el-table-column> -->
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="mt15">
|
||||
<el-pagination layout="prev, pager, next, total, sizes, jumper" background
|
||||
v-model:current-page="tableOptions.pageNum" v-model:page-size="tableOptions.pageSzie"
|
||||
:page-size="tableOptions.pageSzie" :page-sizes="[10, 20, 30, 50]" :total="tableOptions.total"
|
||||
@size-change="paginationChange" @current-change="paginationChange" />
|
||||
</div>
|
||||
<el-dialog title="修改推广费率" v-model="showFeeDialog" @closed="feeDialogClosed">
|
||||
<el-form ref="formFeeRef" :model="feeForm" :rules="feeRules" label-width="100">
|
||||
<el-form-item prop="fee" label="推广费率">
|
||||
<el-input placeholder="请输入推广费率" v-model="feeForm.fee">
|
||||
<template #append>%</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-space>
|
||||
<el-button @click="showFeeDialog = false">取消</el-button>
|
||||
<el-button type="primary" :loading="showFeeLoading" @click="feeSubmitHandle">提交</el-button>
|
||||
</el-space>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<el-dialog title="添加大机构" v-model="showDialog" @closed="dialogClosed">
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="100">
|
||||
<el-form-item label="机构类型">
|
||||
<el-select v-model="form.userType" disabled>
|
||||
<el-option :key="item.type_code" :label="item.type_name" :value="item.type_code"
|
||||
v-for="item in organizationList" key="item.type_code"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item prop="agencyName" label="机构名称">
|
||||
<el-input placeholder="请输入机构名称" v-model="form.agencyName" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="angencyCode" label="机构代码">
|
||||
<el-input placeholder="请输入机构代码" :maxlength="11" show-word-limit v-model="form.angencyCode" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="passowrd" label="密码">
|
||||
<el-input type="password" show-password placeholder="请输入密码" :maxlength="11" v-model="form.passowrd" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="fee" label="推广费率">
|
||||
<el-input placeholder="请输入推广费率" v-model="form.fee">
|
||||
<template #append>%</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="phone" label="联系方式">
|
||||
<el-input placeholder="请输入手机号" v-model="form.phone" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-space>
|
||||
<el-button @click="showDialog = false">取消</el-button>
|
||||
<el-button type="primary" :loading="formLoading" @click="submitHandle">提交</el-button>
|
||||
</el-space>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<totalEarnings ref="totalEarningsRef" />
|
||||
<el-dialog title="详细数据" width="90%" v-model="showChartCard">
|
||||
<chart-card v-if="showChartCard" :user-id="userId" />
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { addAgency, queryAgency, modifyFee } from '@/api/organization.js'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { validPhone, organizationList, addOrganizations } from '@/utils'
|
||||
import { onMounted, reactive } from 'vue';
|
||||
import { useUser } from '@/store/user.js'
|
||||
|
||||
// 图表相关
|
||||
import chartCard from '@/components/chartCard.vue';
|
||||
const showChartCard = ref(false)
|
||||
const userId = ref()
|
||||
function checkChartHandle(id) {
|
||||
userId.value = id
|
||||
showChartCard.value = true
|
||||
}
|
||||
|
||||
// totalEarnings组件相关
|
||||
import totalEarnings from '@/components/totalEarnings.vue';
|
||||
const totalEarningsRef = ref('')
|
||||
function showTotalEarnings(parent_user_id) {
|
||||
totalEarningsRef.value.show(parent_user_id)
|
||||
}
|
||||
|
||||
const storeUser = useUser()
|
||||
|
||||
// 显示添加表单
|
||||
const showDialog = ref(false)
|
||||
const formLoading = ref(false)
|
||||
const showFeeDialog = ref(false)
|
||||
const showFeeLoading = ref(false)
|
||||
|
||||
// 获取添加小机构表单实例
|
||||
let formRef = ref(null)
|
||||
// 获取修改费率表单实例
|
||||
let formFeeRef = ref(null)
|
||||
|
||||
// 创建表单
|
||||
const form = reactive({
|
||||
agencyName: '',
|
||||
angencyCode: '',
|
||||
passowrd: '',
|
||||
fee: '',
|
||||
userType: addOrganizations[storeUser.userInfo.userType],
|
||||
phone: ''
|
||||
})
|
||||
|
||||
// 创建修改费率表单
|
||||
const feeForm = reactive({
|
||||
id: '',
|
||||
fee: ''
|
||||
})
|
||||
const feeRules = reactive({
|
||||
fee: [
|
||||
{
|
||||
required: true,
|
||||
message: '',
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
// 表格参数
|
||||
const tableOptions = reactive({
|
||||
loading: true,
|
||||
agencyCode: '',
|
||||
list: [],
|
||||
total: 0,
|
||||
pageNum: 1,
|
||||
pageSzie: 10
|
||||
})
|
||||
|
||||
// 自定义校验密码
|
||||
function passowrdValidate(rule, value, callback) {
|
||||
if (!value) {
|
||||
return callback(new Error(''))
|
||||
} else if (value.length < 6) {
|
||||
return callback(new Error('密码最少6位'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
|
||||
// 自定义校验手机号
|
||||
function phoneValidate(rule, value, callback) {
|
||||
if (!value) {
|
||||
return callback(new Error(''))
|
||||
} else if (!validPhone(value)) {
|
||||
return callback(new Error('请输入正确的手机号'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
|
||||
// 创建form校验规则
|
||||
const rules = reactive({
|
||||
agencyName: [
|
||||
{
|
||||
required: true,
|
||||
message: '',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
angencyCode: [
|
||||
{
|
||||
required: true,
|
||||
message: '',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
passowrd: [
|
||||
{
|
||||
required: true,
|
||||
validator: passowrdValidate,
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
fee: [
|
||||
{
|
||||
required: true,
|
||||
message: '',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
phone: [
|
||||
{
|
||||
required: true,
|
||||
validator: phoneValidate,
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
// 表单关闭
|
||||
function dialogClosed() {
|
||||
formRef.value.resetFields()
|
||||
}
|
||||
|
||||
// 修改费率关闭
|
||||
function feeDialogClosed() {
|
||||
formFeeRef.value.resetFields()
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const submitHandle = async () => {
|
||||
await formRef.value.validate(async (vaild, fields) => {
|
||||
if (vaild) {
|
||||
try {
|
||||
formLoading.value = true
|
||||
await addAgency(form)
|
||||
formLoading.value = false
|
||||
showDialog.value = false
|
||||
ElMessage.success('添加成功')
|
||||
paginationChange()
|
||||
} catch (error) {
|
||||
formLoading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 提交修改费率
|
||||
async function feeSubmitHandle() {
|
||||
await formFeeRef.value.validate(async (vaild) => {
|
||||
if (vaild) {
|
||||
try {
|
||||
showFeeLoading.value = true
|
||||
await modifyFee(feeForm)
|
||||
showFeeLoading.value = false
|
||||
showFeeDialog.value = false
|
||||
ElMessage.success('添加成功')
|
||||
paginationChange()
|
||||
} catch (error) {
|
||||
showFeeLoading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 修改费率
|
||||
function eitorFeeHandle(row) {
|
||||
feeForm.id = row.id
|
||||
feeForm.fee = row.current_fee
|
||||
showFeeDialog.value = true
|
||||
}
|
||||
|
||||
// 搜索
|
||||
function searchHandle() {
|
||||
tableOptions.pageNum = 1;
|
||||
paginationChange()
|
||||
}
|
||||
|
||||
// 分页回调
|
||||
function paginationChange() {
|
||||
tableOptions.loading = true
|
||||
queryAgencyHandle()
|
||||
}
|
||||
|
||||
// 获取机构列表
|
||||
async function queryAgencyHandle() {
|
||||
try {
|
||||
const res = await queryAgency({
|
||||
agencyCode: tableOptions.agencyCode,
|
||||
pageNum: tableOptions.pageNum,
|
||||
pageSzie: tableOptions.pageSzie,
|
||||
userType: 'FB',
|
||||
isExtend: ''
|
||||
})
|
||||
tableOptions.loading = false
|
||||
tableOptions.list = res.list
|
||||
tableOptions.total = res.total
|
||||
} catch (error) { }
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
queryAgencyHandle()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.table {
|
||||
height: calc(100vh - 310px);
|
||||
}
|
||||
</style>
|
||||
167
src/views/organization/shop_detail.vue
Normal file
167
src/views/organization/shop_detail.vue
Normal file
@@ -0,0 +1,167 @@
|
||||
<template>
|
||||
<div class="card">
|
||||
<div class="nav_wrap">
|
||||
<el-radio-group v-model="type">
|
||||
<el-radio-button :label="item.type" v-for="item in navs" :key="item.type">{{ item.label }}</el-radio-button>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
<div class="container mt15">
|
||||
<div class="compont_wrap">
|
||||
<!-- <authentication v-if="type == 1" />
|
||||
<shopInfo v-if="type == 2" />
|
||||
<settleInfo v-if="type == 3" />
|
||||
<aisleInfo v-if="type == 4" /> -->
|
||||
<component :is="componentList[type]" />
|
||||
</div>
|
||||
<div class="shop_info">
|
||||
<div class="header">
|
||||
<el-text size="large">商户关联信息</el-text>
|
||||
</div>
|
||||
<div class="title_wrap">
|
||||
<el-text>身份信息关联(进件成功的)商户数量</el-text>
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="row">
|
||||
<el-space>
|
||||
<el-text>实名身份证</el-text>
|
||||
<el-text type="warning" tag="ins">{{ authInfo.CertNoCount }}</el-text>
|
||||
</el-space>
|
||||
</div>
|
||||
<div class="row">
|
||||
<el-space>
|
||||
<el-text>结算身份证</el-text>
|
||||
<el-text type="warning" tag="ins">{{ authInfo.countMbiName }}</el-text>
|
||||
</el-space>
|
||||
</div>
|
||||
<div class="row">
|
||||
<el-space>
|
||||
<el-text>同名商户</el-text>
|
||||
<el-text type="warning" tag="ins">{{ authInfo.countAccountCount }}</el-text>
|
||||
</el-space>
|
||||
</div>
|
||||
</div>
|
||||
<div class="title_wrap">
|
||||
<el-text>用户IP记录</el-text>
|
||||
</div>
|
||||
<div class="mt15">
|
||||
<el-table :data="tableOptions.list" border height="200" v-loading="tableOptions.loading">
|
||||
<el-table-column prop="id" label="ID"></el-table-column>
|
||||
</el-table>
|
||||
<div class="mt15">
|
||||
<el-pagination layout="prev, pager, next, total, sizes, jumper" background
|
||||
v-model:current-page="tableOptions.pageNum" v-model:page-size="tableOptions.pageSzie" small
|
||||
:page-size="tableOptions.pageSzie" :page-sizes="[10, 20, 30, 50]" :total="tableOptions.total"
|
||||
@size-change="paginationChange" @current-change="paginationChange" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { connectInfo } from '@/api/shop.js'
|
||||
|
||||
import authentication from './components/authentication.vue'
|
||||
import shopInfo from './components/shopInfo.vue'
|
||||
import settleInfo from './components/settleInfo.vue'
|
||||
import aisleInfo from './components/aisleInfo.vue'
|
||||
|
||||
import { useRoute } from 'vue-router'
|
||||
const route = useRoute()
|
||||
|
||||
const authInfo = ref({})
|
||||
|
||||
const type = ref(1)
|
||||
|
||||
const componentList = {
|
||||
1: authentication,
|
||||
2: shopInfo,
|
||||
3: settleInfo,
|
||||
4: aisleInfo
|
||||
}
|
||||
|
||||
const navs = ref([
|
||||
{
|
||||
type: 1,
|
||||
label: '实名认证信息'
|
||||
},
|
||||
{
|
||||
type: 2,
|
||||
label: '商户基本信息'
|
||||
},
|
||||
{
|
||||
type: 3,
|
||||
label: '结算信息'
|
||||
},
|
||||
{
|
||||
type: 4,
|
||||
label: '通道进件信息'
|
||||
}
|
||||
])
|
||||
|
||||
// 表格参数
|
||||
const tableOptions = reactive({
|
||||
loading: true,
|
||||
list: [],
|
||||
total: 0,
|
||||
pageNum: 1,
|
||||
pageSzie: 10
|
||||
})
|
||||
|
||||
// 分页回调
|
||||
function paginationChange() {
|
||||
tableOptions.loading = true
|
||||
}
|
||||
|
||||
// 实名认证信息页面(实名个数)
|
||||
async function connectInfoAjax() {
|
||||
try {
|
||||
const res = await connectInfo(route.query.id)
|
||||
authInfo.value = res
|
||||
} catch (error) {
|
||||
console.log('实名认证信息页面error:', error)
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
tableOptions.loading = false
|
||||
connectInfoAjax()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import './components/common.scss';
|
||||
|
||||
.nav_wrap {
|
||||
padding-bottom: 15px;
|
||||
border-bottom: 1px solid #ececec;
|
||||
}
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
|
||||
.compont_wrap {
|
||||
flex: 2;
|
||||
padding-right: 20px;
|
||||
}
|
||||
|
||||
.shop_info {
|
||||
flex: 1;
|
||||
|
||||
.header {
|
||||
padding-bottom: 14px;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 14px 20px;
|
||||
|
||||
.row {
|
||||
&:not(:first-child) {
|
||||
margin-top: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
542
src/views/organization/shop_list.vue
Normal file
542
src/views/organization/shop_list.vue
Normal file
@@ -0,0 +1,542 @@
|
||||
<template>
|
||||
<div class="card">
|
||||
<div class="data_row">
|
||||
<div class="item">
|
||||
<div class="icon">
|
||||
<img class="img" src="@/assets/home_icon6.png">
|
||||
</div>
|
||||
<div class="info">
|
||||
<div class="title">商家总数</div>
|
||||
<div class="num">
|
||||
<count-to :start-val="0" :end-val="topData.sumCountNum" :duration="1000" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="icon">
|
||||
<img class="img" src="@/assets/home_icon7.png">
|
||||
</div>
|
||||
<div class="info">
|
||||
<div class="title">认证商家</div>
|
||||
<div class="num">
|
||||
<count-to :start-val="0" :end-val="topData.countNum" :duration="1000" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="icon">
|
||||
<img class="img" src="@/assets/home_icon8.png">
|
||||
</div>
|
||||
<div class="info">
|
||||
<div class="title">未认证商家</div>
|
||||
<div class="num">
|
||||
<count-to :start-val="0" :end-val="topData.subNum" :duration="1000" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="item">
|
||||
<div class="icon">
|
||||
<img class="img" src="../assets/home_icon2.png">
|
||||
</div>
|
||||
<div class="info">
|
||||
<div class="title">总收益</div>
|
||||
<div class="num">
|
||||
<count-to :start-val="0" :decimals="2" :end-val="homeData.sumfansShareMoney" :duration="1000" />
|
||||
<span class="i">元</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="icon">
|
||||
<img class="img" src="../assets/home_icon3.png">
|
||||
</div>
|
||||
<div class="info">
|
||||
<div class="title">今日收益</div>
|
||||
<div class="num">
|
||||
<count-to :start-val="0" :decimals="2" :end-val="homeData.yestedayShareMoney" :duration="1000" />
|
||||
<span class="i">元</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="icon">
|
||||
<img class="img" src="../assets/home_icon4.png">
|
||||
</div>
|
||||
<div class="info">
|
||||
<div class="title">推广费率</div>
|
||||
<div class="num">
|
||||
{{ homeData.currentFee }}
|
||||
<span class="i">%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
<div class="card mt15">
|
||||
<el-space>
|
||||
<el-input placeholder="请输入商户登录号" v-model="tableOptions.agencyCode" style="width: 200px;" />
|
||||
<el-input placeholder="请输入商户号" v-model="tableOptions.merchantCode" style="width: 200px;" />
|
||||
<el-input placeholder="请输入商户号" v-model="tableOptions.phone" style="width: 200px;" />
|
||||
<el-input placeholder="请输入用户ID" v-model="tableOptions.reqUserId" style="width: 200px;" />
|
||||
<el-select placeholder="请选择进件状态" v-model="tableOptions.status">
|
||||
<el-option :value="0" label="待审核"></el-option>
|
||||
<el-option :value="1" label="审核中"></el-option>
|
||||
<el-option :value="2" label="审核失败"></el-option>
|
||||
<el-option :value="3" label="审核通过"></el-option>
|
||||
</el-select>
|
||||
<el-select placeholder="请选择类型" v-model="tableOptions.merchantType">
|
||||
<el-option :value="1" label="小微"></el-option>
|
||||
<el-option :value="2" label="个体"></el-option>
|
||||
<el-option :value="3" label="企业"></el-option>
|
||||
</el-select>
|
||||
<el-button type="primary" icon="Search" @click="searchHandle">搜索</el-button>
|
||||
<el-button icon="RefreshRight" @click="resizeTable">重置</el-button>
|
||||
</el-space>
|
||||
<div class="table mt15">
|
||||
<el-table ref="table" :data="tableOptions.list" size="large" stripe border height="100%"
|
||||
v-loading="tableOptions.loading">
|
||||
<el-table-column prop="id" label="ID"></el-table-column>
|
||||
<el-table-column prop="agencyName" label="商家名称">
|
||||
<template #default="scope">
|
||||
<el-text>{{ scope.row.agencyName || scope.row.agencyCode }}</el-text>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- <el-table-column prop="current_fee" label="推广费率">
|
||||
<template #default="scope">
|
||||
<el-text type="info" v-if="scope.row.is_extend == 0">无</el-text>
|
||||
<el-text type="primary" v-else>{{ scope.row.current_fee }}%</el-text>
|
||||
</template>
|
||||
</el-table-column> -->
|
||||
<!-- <el-table-column prop="sumConsumeFee" label="总流水">
|
||||
<template #default="scope">
|
||||
<el-text>{{ scope.row.sumConsumeFee.toFixed(2) }}</el-text>
|
||||
</template>
|
||||
</el-table-column> -->
|
||||
<el-table-column prop="sumfansShareMoney" label="累计收款">
|
||||
<template #default="scope">
|
||||
<el-link type="primary" icon="search" @click="showTotalEarnings(scope.row.id)">
|
||||
{{ scope.row.sumConsumeFee }}
|
||||
</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="yestedayConsumeFee" label="昨日收款"></el-table-column>
|
||||
<el-table-column prop="sumfansShareMoney" label="累计收益"></el-table-column>
|
||||
<el-table-column label="商户基本信息">
|
||||
<template #default="scope">
|
||||
<div class="column">
|
||||
<el-text type="primary" size="small">{{ scope.row.merchantBaseInfo.merchantTypeName }}</el-text>
|
||||
<el-text size="small">{{ scope.row.merchantCode }}</el-text>
|
||||
<el-text type="success" size="small">{{ scope.row.merchantBaseInfo.alias }}</el-text>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="进件审核状态" align="center">
|
||||
<el-table-column label="随行付">
|
||||
<template #default="scope">
|
||||
<div class="column">
|
||||
<el-text :type="filterData(scope.row.merchantChannel, 1).type" size="small">
|
||||
{{ filterData(scope.row.merchantChannel, 1).text }}
|
||||
</el-text>
|
||||
<template v-if="filterData(scope.row.merchantChannel,
|
||||
1).text != '-'">
|
||||
<el-text size="small">
|
||||
{{ filterData(scope.row.merchantChannel,
|
||||
1).data.merchantId }}
|
||||
</el-text>
|
||||
<el-text type="info" size="small">
|
||||
{{ dayjs(filterData(scope.row.merchantChannel,
|
||||
1).data.updateTime).format('YYYY-MM-DD HH:mm:ss') }}
|
||||
</el-text>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="银盛D1">
|
||||
<template #default="scope">
|
||||
<div class="column">
|
||||
<el-text :type="filterData(scope.row.merchantChannel, 6).type" size="small">
|
||||
{{ filterData(scope.row.merchantChannel, 6).text }}
|
||||
</el-text>
|
||||
<template v-if="filterData(scope.row.merchantChannel,
|
||||
6).text != '-'">
|
||||
<el-text size="small">
|
||||
{{ filterData(scope.row.merchantChannel,
|
||||
6).data.merchantId }}
|
||||
</el-text>
|
||||
<el-text type="info" size="small">
|
||||
{{ dayjs(filterData(scope.row.merchantChannel,
|
||||
6).data.updateTime).format('YYYY-MM-DD HH:mm:ss') }}
|
||||
</el-text>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="银盛">
|
||||
<template #default="scope">
|
||||
<div class="column">
|
||||
<el-text :type="filterData(scope.row.merchantChannel, 4).type" size="small">
|
||||
{{ filterData(scope.row.merchantChannel, 4).text }}
|
||||
</el-text>
|
||||
<template v-if="filterData(scope.row.merchantChannel,
|
||||
4).text != '-'">
|
||||
<el-text size="small">
|
||||
{{ filterData(scope.row.merchantChannel,
|
||||
4).data.merchantId }}
|
||||
</el-text>
|
||||
<el-text type="info" size="small">
|
||||
{{ dayjs(filterData(scope.row.merchantChannel,
|
||||
4).data.updateTime).format('YYYY-MM-DD HH:mm:ss') }}
|
||||
</el-text>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="拉卡拉">
|
||||
<template #default="scope">
|
||||
<div class="column">
|
||||
<el-text :type="filterData(scope.row.merchantChannel, 5).type" size="small">
|
||||
{{ filterData(scope.row.merchantChannel, 5).text }}
|
||||
</el-text>
|
||||
<template v-if="filterData(scope.row.merchantChannel,
|
||||
5).text != '-'">
|
||||
<el-text size="small">
|
||||
{{ filterData(scope.row.merchantChannel,
|
||||
5).data.merchantId }}
|
||||
</el-text>
|
||||
<el-text type="info" size="small">
|
||||
{{ dayjs(filterData(scope.row.merchantChannel,
|
||||
5).data.updateTime).format('YYYY-MM-DD HH:mm:ss') }}
|
||||
</el-text>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table-column>
|
||||
<el-table-column label="创客等级" align="center">
|
||||
<template #default="scope">
|
||||
<el-tag type="info" disable-transitions v-if="scope.row.is_extend == 0">普通商户</el-tag>
|
||||
<el-tag type="success" disable-transitions v-if="scope.row.is_extend == 1">初级创客</el-tag>
|
||||
<el-tag type="warning" disable-transitions v-if="scope.row.is_extend == 2">高级创客</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" fixed="right">
|
||||
<template #default="scope">
|
||||
<RouterLink
|
||||
:to="{ name: 'shop_detail', query: { id: scope.row.id, name: scope.row.agencyName, account: scope.row.agencyCode, merchantcode: scope.row.merchantCode } }">
|
||||
<el-button type="primary" size="small" icon="Search" v-permission="['MG']">
|
||||
详情
|
||||
</el-button>
|
||||
</RouterLink>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="mt15">
|
||||
<el-pagination layout="prev, pager, next, total, sizes, jumper" background
|
||||
v-model:current-page="tableOptions.pageNum" v-model:page-size="tableOptions.pageSzie"
|
||||
:page-size="tableOptions.pageSzie" :page-sizes="[10, 20, 30, 50]" :total="tableOptions.total"
|
||||
@size-change="paginationChange" @current-change="paginationChange" />
|
||||
</div>
|
||||
<el-dialog v-model="showDialog" title="累计收益" width="80%">
|
||||
<el-space>
|
||||
<el-input placeholder="请输入订单号搜索" v-model="dialogTableOptions.orderNumber" style="width: 200px;" />
|
||||
<el-input placeholder="请输入商户号搜索" v-model="dialogTableOptions.merchantCode" style="width: 200px;" />
|
||||
<el-button type="primary" icon="Search" @click="dialogSearchHandle">搜索</el-button>
|
||||
</el-space>
|
||||
<div class="mt15">
|
||||
<el-table :data="dialogTableOptions.list" v-loading="dialogTableOptions.loading">
|
||||
<el-table-column prop="orderNumber" label="订单号"></el-table-column>
|
||||
<el-table-column prop="merchantCode" label="商户号"></el-table-column>
|
||||
<el-table-column prop="consumeFee" label="交易金额"></el-table-column>
|
||||
<el-table-column prop="current_fee" label="推广费率">
|
||||
<template #default="scope">
|
||||
<el-text type="primary">{{ scope.row.currentFee }}%</el-text>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="loginName" label="名称">
|
||||
<template #default="scope">
|
||||
<el-text>{{ scope.row.loginName }}</el-text>
|
||||
<el-tag disable-transitions style="margin-left: 8px;">{{ typeNames[scope.row.typeCode]
|
||||
}}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="merchantName" label="商户名称">
|
||||
</el-table-column>
|
||||
<el-table-column prop="createDt" label="时间">
|
||||
<template #default="scope">
|
||||
{{ dayjs(scope.row.createDt).format('YYYY-MM-DD HH:mm:ss') }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="mt15">
|
||||
<el-pagination layout="prev, pager, next, total, sizes, jumper"
|
||||
v-model:current-page="dialogTableOptions.pageNum" v-model:page-size="dialogTableOptions.pageSzie"
|
||||
:page-size="dialogTableOptions.pageSzie" :page-sizes="[10, 20, 30, 50]"
|
||||
:total="dialogTableOptions.total" @size-change="dialogPaginationChange"
|
||||
@current-change="dialogPaginationChange" />
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { queryCustormerFlow, queryCustormSum } from '@/api/shop.js'
|
||||
import { onMounted, reactive } from 'vue';
|
||||
import { dayjs } from 'element-plus';
|
||||
import { typeNames } from '@/utils/index.js'
|
||||
import { queryOrder } from '@/api/organization.js'
|
||||
|
||||
const table = ref('')
|
||||
const showDialog = ref(false)
|
||||
// 表格参数
|
||||
const dialogTableOptions = reactive({
|
||||
loading: true,
|
||||
reqUserId: '', // 上级id
|
||||
orderNumber: '', // 订单号
|
||||
merchantCode: '', // 商户号
|
||||
list: [],
|
||||
total: 0,
|
||||
pageNum: 1,
|
||||
pageSzie: 10
|
||||
})
|
||||
|
||||
// 搜索
|
||||
function dialogSearchHandle() {
|
||||
dialogTableOptions.pageNum = 1;
|
||||
dialogPaginationChange()
|
||||
}
|
||||
|
||||
// 分页回调
|
||||
function dialogPaginationChange() {
|
||||
dialogTableOptions.loading = true
|
||||
getTableDate()
|
||||
}
|
||||
|
||||
// 获取机构列表
|
||||
async function getTableDate() {
|
||||
try {
|
||||
const res = await queryOrder({
|
||||
reqUserId: dialogTableOptions.reqUserId,
|
||||
orderNumber: dialogTableOptions.orderNumber,
|
||||
merchantCode: dialogTableOptions.merchantCode,
|
||||
pageNum: dialogTableOptions.pageNum,
|
||||
pageSzie: dialogTableOptions.pageSzie
|
||||
})
|
||||
dialogTableOptions.loading = false
|
||||
dialogTableOptions.list = res.list
|
||||
dialogTableOptions.total = res.total
|
||||
} catch (error) { }
|
||||
}
|
||||
|
||||
// 显示收益明细
|
||||
function showTotalEarnings(parent_user_id) {
|
||||
dialogTableOptions.reqUserId = parent_user_id
|
||||
showDialog.value = true
|
||||
getTableDate()
|
||||
}
|
||||
|
||||
// ===================
|
||||
|
||||
// 顶部数据
|
||||
const topData = reactive({
|
||||
countNum: 0, // 认证数量
|
||||
subNum: 0, // 未认证数量
|
||||
sumCountNum: 0, // 总数
|
||||
})
|
||||
|
||||
// 表格参数
|
||||
const tableOptions = reactive({
|
||||
loading: true,
|
||||
agencyCode: '', // 商户登录号
|
||||
merchantCode: '', // 商户号
|
||||
phone: '',
|
||||
status: '', // 进件状态。0或无、待审核,1、审核中 2、审核失败 3、审核通过
|
||||
merchantType: '', // 1:小微 2:个体 3:企业
|
||||
reqUserId: '', // 用户id
|
||||
list: [],
|
||||
total: 0,
|
||||
pageNum: 1,
|
||||
pageSzie: 10
|
||||
})
|
||||
|
||||
// 重置表格
|
||||
function resizeTable() {
|
||||
tableOptions.agencyCode = ''
|
||||
tableOptions.merchantCode = ''
|
||||
tableOptions.status = ''
|
||||
tableOptions.merchantType = ''
|
||||
tableOptions.reqUserId = ''
|
||||
searchHandle()
|
||||
}
|
||||
|
||||
// 搜索
|
||||
function searchHandle() {
|
||||
tableOptions.pageNum = 1;
|
||||
paginationChange()
|
||||
}
|
||||
|
||||
// 分页回调
|
||||
function paginationChange() {
|
||||
tableOptions.loading = true
|
||||
queryCustormerFlowHandle()
|
||||
}
|
||||
|
||||
// 获取机构列表
|
||||
async function queryCustormerFlowHandle() {
|
||||
try {
|
||||
const res = await queryCustormerFlow({
|
||||
agencyCode: tableOptions.agencyCode,
|
||||
merchantCode: tableOptions.merchantCode,
|
||||
phone: tableOptions.phone,
|
||||
status: tableOptions.status,
|
||||
merchantType: tableOptions.merchantType,
|
||||
reqUserId: tableOptions.reqUserId,
|
||||
pageNum: tableOptions.pageNum,
|
||||
pageSzie: tableOptions.pageSzie,
|
||||
userType: 'MC',
|
||||
isExtend: 'shop'
|
||||
})
|
||||
tableOptions.loading = false
|
||||
tableOptions.list = res.list
|
||||
tableOptions.total = res.total
|
||||
table.value.setScrollTop(0)
|
||||
} catch (error) { }
|
||||
}
|
||||
|
||||
// 商户列表数据统计
|
||||
const queryCustormSumAjax = async () => {
|
||||
try {
|
||||
const res = await queryCustormSum()
|
||||
topData.countNum = res.countNum
|
||||
topData.subNum = res.subNum
|
||||
topData.sumCountNum = res.sumCountNum
|
||||
} catch (error) { }
|
||||
}
|
||||
|
||||
// 过滤进件数据
|
||||
function filterData(arr, type) {
|
||||
const m = {
|
||||
0: {
|
||||
text: '待审核',
|
||||
type: 'info',
|
||||
data: ''
|
||||
},
|
||||
1: {
|
||||
text: '审核中',
|
||||
type: 'warning',
|
||||
data: ''
|
||||
},
|
||||
2: {
|
||||
text: '审核失败',
|
||||
type: 'danger',
|
||||
data: ''
|
||||
},
|
||||
3: {
|
||||
text: '审核通过',
|
||||
type: 'success',
|
||||
data: ''
|
||||
},
|
||||
4: {
|
||||
text: '-',
|
||||
type: 'info',
|
||||
data: ''
|
||||
}
|
||||
}
|
||||
const res = arr.find(item => item.channel == type).baseInfo;
|
||||
if (!!res && m[res.status]) {
|
||||
m[res.status].data = res
|
||||
}
|
||||
return (res ? m[res.status] : m[4]) || m[4]
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
queryCustormerFlowHandle()
|
||||
queryCustormSumAjax()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.el-text {
|
||||
align-self: flex-start;
|
||||
}
|
||||
</style>
|
||||
<style scoped lang="scss">
|
||||
.column {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.table {
|
||||
height: calc(100vh - 435px);
|
||||
}
|
||||
|
||||
.data_row {
|
||||
display: flex;
|
||||
padding: 12px 0;
|
||||
|
||||
.item {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
padding-left: 50px;
|
||||
|
||||
&:not(:last-child) {
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
height: 100%;
|
||||
border-right: 1px solid #ececec;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.icon {
|
||||
$size: 55px;
|
||||
width: $size;
|
||||
height: $size;
|
||||
border-radius: 50%;
|
||||
background-color: #F2F3F5;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.img {
|
||||
$size: 30px;
|
||||
width: $size;
|
||||
height: $size;
|
||||
object-fit: contain;
|
||||
}
|
||||
}
|
||||
|
||||
.info {
|
||||
flex: 1;
|
||||
padding-left: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
|
||||
.title {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.num {
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
padding-top: 10px;
|
||||
|
||||
.i {
|
||||
font-size: 12px;
|
||||
position: relative;
|
||||
bottom: 1px;
|
||||
right: -4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
339
src/views/organization/two_promotion_list.vue
Normal file
339
src/views/organization/two_promotion_list.vue
Normal file
@@ -0,0 +1,339 @@
|
||||
<template>
|
||||
<div class="card">
|
||||
<!-- <el-row>
|
||||
<el-space>
|
||||
<el-button type="primary" icon="Plus" @click="showDialog = true" v-permission="['SO']">添加大机构</el-button>
|
||||
</el-space>
|
||||
</el-row> -->
|
||||
<el-space>
|
||||
<el-input placeholder="请输入机构代码搜索" v-model="tableOptions.agencyCode" style="width: 200px;" />
|
||||
<el-button type="primary" icon="Search" @click="searchHandle">搜索</el-button>
|
||||
</el-space>
|
||||
<div class="table mt15">
|
||||
<el-table :data="tableOptions.list" size="large" stripe border height="100%" v-loading="tableOptions.loading">
|
||||
<el-table-column prop="id" label="机构id"></el-table-column>
|
||||
<el-table-column prop="agencyName" label="机构名称">
|
||||
<template #default="scope">
|
||||
<el-text>{{ scope.row.agencyName || scope.row.agencyCode }}</el-text>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="agencyCode" label="机构代码"></el-table-column>
|
||||
<el-table-column prop="current_fee" label="推广费率">
|
||||
<template #default="scope">
|
||||
<el-text>{{ scope.row.current_fee }}%</el-text>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="parentLoginName" label="上级机构代码"></el-table-column>
|
||||
<el-table-column prop="sumConsumeFee" label="总流水">
|
||||
<template #default="scope">
|
||||
<el-text>{{ scope.row.sumConsumeFee.toFixed(2) }}</el-text>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="yestedayConsumeFee" label="今日流水"></el-table-column>
|
||||
<el-table-column prop="sumfansShareMoney" label="总收益">
|
||||
<template #default="scope">
|
||||
<el-link type="primary" icon="search" @click="showTotalEarnings(scope.row.id)">
|
||||
{{ scope.row.sumfansShareMoney }}
|
||||
</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="yestedayShareMoney" label="今日收益"></el-table-column>
|
||||
<el-table-column prop="sumAccount" label="商家数量"></el-table-column>
|
||||
<el-table-column label="操作">
|
||||
<template #default="scope">
|
||||
<el-button size="small" type="primary" icon="DataLine"
|
||||
@click="checkChartHandle(scope.row.id)">详细数据</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- <el-table-column label="操作">
|
||||
<template #default="scope">
|
||||
<el-button type="primary" size="small" icon="EditPen" @click="eitorFeeHandle(scope.row)"
|
||||
v-permission="['SO']">修改费率</el-button>
|
||||
</template>
|
||||
</el-table-column> -->
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="mt15">
|
||||
<el-pagination layout="prev, pager, next, total, sizes, jumper" background
|
||||
v-model:current-page="tableOptions.pageNum" v-model:page-size="tableOptions.pageSzie"
|
||||
:page-size="tableOptions.pageSzie" :page-sizes="[10, 20, 30, 50]" :total="tableOptions.total"
|
||||
@size-change="paginationChange" @current-change="paginationChange" />
|
||||
</div>
|
||||
<el-dialog title="修改推广费率" v-model="showFeeDialog" @closed="feeDialogClosed">
|
||||
<el-form ref="formFeeRef" :model="feeForm" :rules="feeRules" label-width="100">
|
||||
<el-form-item prop="fee" label="推广费率">
|
||||
<el-input placeholder="请输入推广费率" v-model="feeForm.fee">
|
||||
<template #append>%</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-space>
|
||||
<el-button @click="showFeeDialog = false">取消</el-button>
|
||||
<el-button type="primary" :loading="showFeeLoading" @click="feeSubmitHandle">提交</el-button>
|
||||
</el-space>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<el-dialog title="添加大机构" v-model="showDialog" @closed="dialogClosed">
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="100">
|
||||
<el-form-item label="机构类型">
|
||||
<el-select v-model="form.userType" disabled>
|
||||
<el-option :key="item.type_code" :label="item.type_name" :value="item.type_code"
|
||||
v-for="item in organizationList" key="item.type_code"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item prop="agencyName" label="机构名称">
|
||||
<el-input placeholder="请输入机构名称" v-model="form.agencyName" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="angencyCode" label="机构代码">
|
||||
<el-input placeholder="请输入机构代码" :maxlength="11" show-word-limit v-model="form.angencyCode" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="passowrd" label="密码">
|
||||
<el-input type="password" show-password placeholder="请输入密码" :maxlength="11" v-model="form.passowrd" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="fee" label="推广费率">
|
||||
<el-input placeholder="请输入推广费率" v-model="form.fee">
|
||||
<template #append>%</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="phone" label="联系方式">
|
||||
<el-input placeholder="请输入手机号" v-model="form.phone" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-space>
|
||||
<el-button @click="showDialog = false">取消</el-button>
|
||||
<el-button type="primary" :loading="formLoading" @click="submitHandle">提交</el-button>
|
||||
</el-space>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<totalEarnings ref="totalEarningsRef" />
|
||||
<el-dialog title="详细数据" width="90%" v-model="showChartCard">
|
||||
<chart-card v-if="showChartCard" :user-id="userId" />
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { addAgency, queryAgency, modifyFee } from '@/api/organization.js'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { validPhone, organizationList, addOrganizations } from '@/utils'
|
||||
import { onMounted, reactive } from 'vue';
|
||||
import { useUser } from '@/store/user.js'
|
||||
|
||||
// 图表相关
|
||||
import chartCard from '@/components/chartCard.vue';
|
||||
const showChartCard = ref(false)
|
||||
const userId = ref()
|
||||
function checkChartHandle(id) {
|
||||
userId.value = id
|
||||
showChartCard.value = true
|
||||
}
|
||||
|
||||
// totalEarnings组件相关
|
||||
import totalEarnings from '@/components/totalEarnings.vue';
|
||||
const totalEarningsRef = ref('')
|
||||
function showTotalEarnings(parent_user_id) {
|
||||
totalEarningsRef.value.show(parent_user_id)
|
||||
}
|
||||
|
||||
const storeUser = useUser()
|
||||
|
||||
// 显示添加表单
|
||||
const showDialog = ref(false)
|
||||
const formLoading = ref(false)
|
||||
const showFeeDialog = ref(false)
|
||||
const showFeeLoading = ref(false)
|
||||
|
||||
// 获取添加小机构表单实例
|
||||
let formRef = ref(null)
|
||||
// 获取修改费率表单实例
|
||||
let formFeeRef = ref(null)
|
||||
|
||||
// 创建表单
|
||||
const form = reactive({
|
||||
agencyName: '',
|
||||
angencyCode: '',
|
||||
passowrd: '',
|
||||
fee: '',
|
||||
userType: addOrganizations[storeUser.userInfo.userType],
|
||||
phone: ''
|
||||
})
|
||||
|
||||
// 创建修改费率表单
|
||||
const feeForm = reactive({
|
||||
id: '',
|
||||
fee: ''
|
||||
})
|
||||
const feeRules = reactive({
|
||||
fee: [
|
||||
{
|
||||
required: true,
|
||||
message: '',
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
// 表格参数
|
||||
const tableOptions = reactive({
|
||||
loading: true,
|
||||
agencyCode: '',
|
||||
list: [],
|
||||
total: 0,
|
||||
pageNum: 1,
|
||||
pageSzie: 10
|
||||
})
|
||||
|
||||
// 自定义校验密码
|
||||
function passowrdValidate(rule, value, callback) {
|
||||
if (!value) {
|
||||
return callback(new Error(''))
|
||||
} else if (value.length < 6) {
|
||||
return callback(new Error('密码最少6位'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
|
||||
// 自定义校验手机号
|
||||
function phoneValidate(rule, value, callback) {
|
||||
if (!value) {
|
||||
return callback(new Error(''))
|
||||
} else if (!validPhone(value)) {
|
||||
return callback(new Error('请输入正确的手机号'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
|
||||
// 创建form校验规则
|
||||
const rules = reactive({
|
||||
agencyName: [
|
||||
{
|
||||
required: true,
|
||||
message: '',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
angencyCode: [
|
||||
{
|
||||
required: true,
|
||||
message: '',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
passowrd: [
|
||||
{
|
||||
required: true,
|
||||
validator: passowrdValidate,
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
fee: [
|
||||
{
|
||||
required: true,
|
||||
message: '',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
phone: [
|
||||
{
|
||||
required: true,
|
||||
validator: phoneValidate,
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
// 表单关闭
|
||||
function dialogClosed() {
|
||||
formRef.value.resetFields()
|
||||
}
|
||||
|
||||
// 修改费率关闭
|
||||
function feeDialogClosed() {
|
||||
formFeeRef.value.resetFields()
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const submitHandle = async () => {
|
||||
await formRef.value.validate(async (vaild, fields) => {
|
||||
if (vaild) {
|
||||
try {
|
||||
formLoading.value = true
|
||||
await addAgency(form)
|
||||
formLoading.value = false
|
||||
showDialog.value = false
|
||||
ElMessage.success('添加成功')
|
||||
paginationChange()
|
||||
} catch (error) {
|
||||
formLoading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 提交修改费率
|
||||
async function feeSubmitHandle() {
|
||||
await formFeeRef.value.validate(async (vaild) => {
|
||||
if (vaild) {
|
||||
try {
|
||||
showFeeLoading.value = true
|
||||
await modifyFee(feeForm)
|
||||
showFeeLoading.value = false
|
||||
showFeeDialog.value = false
|
||||
ElMessage.success('添加成功')
|
||||
paginationChange()
|
||||
} catch (error) {
|
||||
showFeeLoading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 修改费率
|
||||
function eitorFeeHandle(row) {
|
||||
feeForm.id = row.id
|
||||
feeForm.fee = row.current_fee
|
||||
showFeeDialog.value = true
|
||||
}
|
||||
|
||||
// 搜索
|
||||
function searchHandle() {
|
||||
tableOptions.pageNum = 1;
|
||||
paginationChange()
|
||||
}
|
||||
|
||||
// 分页回调
|
||||
function paginationChange() {
|
||||
tableOptions.loading = true
|
||||
queryAgencyHandle()
|
||||
}
|
||||
|
||||
// 获取机构列表
|
||||
async function queryAgencyHandle() {
|
||||
try {
|
||||
const res = await queryAgency({
|
||||
agencyCode: tableOptions.agencyCode,
|
||||
pageNum: tableOptions.pageNum,
|
||||
pageSzie: tableOptions.pageSzie,
|
||||
userType: 'SB',
|
||||
isExtend: ''
|
||||
})
|
||||
tableOptions.loading = false
|
||||
tableOptions.list = res.list
|
||||
tableOptions.total = res.total
|
||||
} catch (error) { }
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
queryAgencyHandle()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.table {
|
||||
height: calc(100vh - 310px);
|
||||
}
|
||||
</style>
|
||||
14
src/views/other/resize.vue
Normal file
14
src/views/other/resize.vue
Normal file
@@ -0,0 +1,14 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<textarea v-size-ob="ob" cols="30" rows="10"></textarea>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
function ob(size) {
|
||||
console.log('🎨 size >>> ', size)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
45
src/views/other/watermark.vue
Normal file
45
src/views/other/watermark.vue
Normal file
@@ -0,0 +1,45 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<el-button type="primary" @click="set">添加水印</el-button>
|
||||
<el-button type="primary" @click="remove">移除水印</el-button>
|
||||
<el-button type="primary" @click="dialogVisible = true">自定义水印</el-button>
|
||||
<el-dialog v-model="dialogVisible" title="温馨提示" width="500px">
|
||||
<el-input v-model="text" placeholder="请填写自定义水印" />
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="custom">确认</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import watermark from "@/utils/watermark.js";
|
||||
|
||||
function set() {
|
||||
watermark.set();
|
||||
}
|
||||
function remove() {
|
||||
watermark.remove();
|
||||
}
|
||||
|
||||
let text = ref("Vue3 ElePlus Admin");
|
||||
let dialogVisible = ref(false);
|
||||
function custom() {
|
||||
watermark.set(text.value);
|
||||
dialogVisible.value = false;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.dialog-footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
margin-top: 10px;
|
||||
}
|
||||
</style>
|
||||
305
src/views/promotion/promotion_list.vue
Normal file
305
src/views/promotion/promotion_list.vue
Normal file
@@ -0,0 +1,305 @@
|
||||
<template>
|
||||
<div class="card">
|
||||
<el-space>
|
||||
<el-button type="primary" icon="Plus" @click="addHandle">添加推广图</el-button>
|
||||
</el-space>
|
||||
<div class="table mt15">
|
||||
<el-table :data="tableOptions.list" size="large" stripe border height="100%" v-loading="tableOptions.loading">
|
||||
<el-table-column prop="id" label="ID"></el-table-column>
|
||||
<el-table-column prop="code" label="CODE"></el-table-column>
|
||||
<el-table-column prop="name" label="名字"></el-table-column>
|
||||
<el-table-column label="状态" width="80">
|
||||
<template #default="scope">
|
||||
<el-tag type="success" disable-transitions v-if="scope.row.type == 1">开启</el-tag>
|
||||
<el-tag type="warning" disable-transitions v-if="scope.row.type == 0">关闭</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="机型状态" width="120">
|
||||
<template #default="scope">
|
||||
<div class="mode_wrap">
|
||||
<el-tag type="success" disable-transitions v-if="scope.row.android == 1">安卓开启</el-tag>
|
||||
<el-tag type="warning" disable-transitions v-if="scope.row.android == 0">安卓关闭</el-tag>
|
||||
<div class="height"></div>
|
||||
<el-tag type="success" disable-transitions v-if="scope.row.ios == 1">IOS开启</el-tag>
|
||||
<el-tag type="warning" disable-transitions v-if="scope.row.ios == 0">IOS关闭</el-tag>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="图片">
|
||||
<template #default="scope">
|
||||
<el-image style="width: 50px; height: 50px" :src="scope.row.content" preview-teleported
|
||||
hide-on-click-modal :preview-src-list="[scope.row.content]" fit="cover">
|
||||
</el-image>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="updateTime" label="时间">
|
||||
<template #default="scope">
|
||||
{{ dayjs(scope.row.updateTime).format('YYYY/MM/DD HH:mm:ss') }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="140">
|
||||
<template #default="scope">
|
||||
<el-button type="primary" size="small" icon="EditPen"
|
||||
@click="editorHandle(scope.row)">编辑</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="mt15">
|
||||
<el-pagination layout="prev, pager, next, total, sizes, jumper" background
|
||||
v-model:current-page="tableOptions.pageNum" v-model:page-size="tableOptions.pageSzie"
|
||||
:page-size="tableOptions.pageSzie" :page-sizes="[10, 20, 30, 50]" :total="tableOptions.total"
|
||||
@size-change="paginationChange" @current-change="paginationChange" />
|
||||
</div>
|
||||
</div>
|
||||
<el-dialog :title="type == 1 ? '添加推广图' : '编辑推广图'" v-model="showDialog" @closed="dialogClosed">
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="140">
|
||||
<el-form-item prop="code" label="CODE" v-if="type == 1">
|
||||
<el-input placeholder="请输入图片code" v-model="form.code" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="name" label="图片名称" v-if="type == 1">
|
||||
<el-input placeholder="请输入图片名称" v-model="form.name" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="type" label="是否开启" v-if="type == 2">
|
||||
<el-radio-group v-model="form.type">
|
||||
<el-radio label="1">开启</el-radio>
|
||||
<el-radio label="0">关闭</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item prop="android" label="安卓是否开启" v-if="type == 2 && form.type == 1">
|
||||
<el-radio-group v-model="form.android">
|
||||
<el-radio label="1">开启</el-radio>
|
||||
<el-radio label="0">关闭</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item prop="ios" label="IOS是否开启" v-if="type == 2 && form.type == 1">
|
||||
<el-radio-group v-model="form.ios">
|
||||
<el-radio label="1">开启</el-radio>
|
||||
<el-radio label="0">关闭</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item prop="content" label="图片url">
|
||||
<el-upload ref="uploadRef" v-model:file-list="fileList" :limit="1" :on-exceed="handleExceed"
|
||||
list-type="picture" :auto-upload="false" @change="selectFile" @remove="removeFile">
|
||||
<template #trigger>
|
||||
<el-button type="primary" icon="Picture">选择图片</el-button>
|
||||
</template>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-space>
|
||||
<el-button @click="showDialog = false">取消</el-button>
|
||||
<el-button type="primary" :loading="formLoading" @click="submitHandle">提交</el-button>
|
||||
</el-space>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { dayjs, genFileId } from 'element-plus'
|
||||
import { uploadOSS } from '@/api/home.js'
|
||||
import { promotionImageList, insert, updateById } from '@/api/promotion.js'
|
||||
import { ref } from 'vue';
|
||||
|
||||
// 显示添加表单
|
||||
const type = ref(1) // 1添加 2编辑
|
||||
const showDialog = ref(false)
|
||||
const formLoading = ref(false)
|
||||
// 获取添加小机构表单实例
|
||||
let formRef = ref(null)
|
||||
let uploadRef = ref(null)
|
||||
const fileList = ref([])
|
||||
|
||||
// 表单关闭
|
||||
function dialogClosed() {
|
||||
formRef.value.resetFields()
|
||||
}
|
||||
|
||||
// 创建表单
|
||||
const form = reactive({
|
||||
code: '',
|
||||
name: '',
|
||||
content: '',
|
||||
type: '',
|
||||
android: '',
|
||||
ios: '',
|
||||
id: ''
|
||||
})
|
||||
|
||||
// 校验是否选择图片
|
||||
const imgValidate = (rule, value, callback) => {
|
||||
if (fileList.value.length <= 0) {
|
||||
return callback(new Error('请选择图片'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
|
||||
// 创建form校验规则
|
||||
const rules = reactive({
|
||||
code: [
|
||||
{
|
||||
required: true,
|
||||
message: '',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
name: [
|
||||
{
|
||||
required: true,
|
||||
message: '',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
content: [
|
||||
{
|
||||
required: true,
|
||||
validator: imgValidate,
|
||||
trigger: 'change'
|
||||
}
|
||||
],
|
||||
type: [
|
||||
{
|
||||
required: true,
|
||||
message: '请选择是否开启',
|
||||
trigger: 'change'
|
||||
}
|
||||
],
|
||||
android: [
|
||||
{
|
||||
required: true,
|
||||
message: '请选择安卓是否开启',
|
||||
trigger: 'change'
|
||||
}
|
||||
],
|
||||
ios: [
|
||||
{
|
||||
required: true,
|
||||
message: '请选择iOS是否开启',
|
||||
trigger: 'change'
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
// 只能选择一个文件,替换之前的文件
|
||||
const handleExceed = (files) => {
|
||||
uploadRef.value.clearFiles()
|
||||
const file = files[0]
|
||||
file.uid = genFileId()
|
||||
uploadRef.value.handleStart(file)
|
||||
form.content = ''
|
||||
}
|
||||
|
||||
// 选择图片
|
||||
const selectFile = async (file) => {
|
||||
// console.log('添加', file)
|
||||
fileList.value = [file]
|
||||
}
|
||||
|
||||
// 移除图片
|
||||
const removeFile = async (file) => {
|
||||
// console.log('移除', file.uid)
|
||||
fileList.value = []
|
||||
form.content = ''
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const submitHandle = async () => {
|
||||
await formRef.value.validate(async (vaild) => {
|
||||
if (vaild) {
|
||||
try {
|
||||
formLoading.value = true
|
||||
if (type.value == 1) {
|
||||
form.content = await uploadOSS(fileList.value[0].raw)
|
||||
await insert(form)
|
||||
ElMessage.success('添加成功')
|
||||
} else {
|
||||
if (!form.content) {
|
||||
form.content = await uploadOSS(fileList.value[0].raw)
|
||||
}
|
||||
await updateById(form)
|
||||
ElMessage.success('修改成功')
|
||||
}
|
||||
formLoading.value = false
|
||||
showDialog.value = false
|
||||
promotionImageListAjax()
|
||||
} catch (error) {
|
||||
formLoading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// ============================
|
||||
|
||||
// 表格参数
|
||||
const tableOptions = reactive({
|
||||
loading: true,
|
||||
agencyCode: '',
|
||||
list: [],
|
||||
total: 0,
|
||||
pageNum: 1,
|
||||
pageSize: 10
|
||||
})
|
||||
|
||||
// 分页回调
|
||||
function paginationChange() {
|
||||
tableOptions.loading = true
|
||||
queryAgencyHandle()
|
||||
}
|
||||
|
||||
// 添加推广图
|
||||
const addHandle = () => {
|
||||
type.value = 1
|
||||
showDialog.value = true
|
||||
}
|
||||
|
||||
// 编辑
|
||||
const editorHandle = async (row) => {
|
||||
showDialog.value = true
|
||||
type.value = 2
|
||||
form.content = row.content
|
||||
form.id = JSON.stringify(row.id)
|
||||
form.type = row.type
|
||||
form.android = row.android
|
||||
form.ios = row.ios
|
||||
|
||||
fileList.value = [{
|
||||
name: `${row.content.slice(0, 19)}...`,
|
||||
url: row.content
|
||||
}]
|
||||
}
|
||||
|
||||
// 推广宽图列表
|
||||
const promotionImageListAjax = async () => {
|
||||
try {
|
||||
const { total, list } = await promotionImageList({
|
||||
pageNum: tableOptions.pageNum,
|
||||
pageSize: tableOptions.pageSize
|
||||
})
|
||||
tableOptions.loading = false
|
||||
tableOptions.list = list
|
||||
tableOptions.total = total
|
||||
} catch (error) { }
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
promotionImageListAjax()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.table {
|
||||
height: calc(100vh - 310px);
|
||||
}
|
||||
|
||||
.mode_wrap {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.height {
|
||||
height: 4px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
291
src/views/setting/appid_manage.vue
Normal file
291
src/views/setting/appid_manage.vue
Normal file
@@ -0,0 +1,291 @@
|
||||
<template>
|
||||
<div class="card">
|
||||
<el-space>
|
||||
<el-button type="primary" icon="Plus" @click="addHandle">添加菜单</el-button>
|
||||
</el-space>
|
||||
<div class="mt15">
|
||||
<el-space>
|
||||
<el-input placeholder="请输入appid搜索" v-model="tableOptions.appId" style="width: 200px;" />
|
||||
<el-button type="primary" icon="Search" @click="searchHandle">搜索</el-button>
|
||||
<el-button icon="RefreshRight" @click="resizeTable">重置</el-button>
|
||||
</el-space>
|
||||
</div>
|
||||
<div class="table mt15">
|
||||
<el-table ref="table" :data="tableOptions.list" border height="100%" v-loading="tableOptions.loading">
|
||||
<el-table-column prop="id" label="ID" width="50"></el-table-column>
|
||||
<el-table-column prop="appId" label="商户号"></el-table-column>
|
||||
<el-table-column prop="merchantName" label="商户名称"></el-table-column>
|
||||
<!-- <el-table-column prop="storeName" label="店铺名称"></el-table-column> -->
|
||||
<el-table-column prop="ip" label="允许访问的ip"></el-table-column>
|
||||
<el-table-column prop="publicKey" label="公钥">
|
||||
<template #default="scope">
|
||||
<el-popover title="点击复制" effect="dark" :width="500" :content="scope.row.publicKey">
|
||||
<template #reference>
|
||||
<el-text type="primary" tag="ins" truncated @click="copyHandle(scope.row.publicKey)">
|
||||
<el-icon>
|
||||
<CopyDocument />
|
||||
</el-icon>
|
||||
{{ scope.row.publicKey }}
|
||||
</el-text>
|
||||
</template>
|
||||
</el-popover>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="privateKey" label="私钥">
|
||||
<template #default="scope">
|
||||
<el-popover title="点击复制" effect="dark" :width="500" :content="scope.row.privateKey">
|
||||
<template #reference>
|
||||
<el-text type="primary" tag="ins" truncated @click="copyHandle(scope.row.privateKey)">
|
||||
<el-icon>
|
||||
<CopyDocument />
|
||||
</el-icon>
|
||||
{{ scope.row.privateKey }}
|
||||
</el-text>
|
||||
</template>
|
||||
</el-popover>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" label="创建时间">
|
||||
<template #default="scope">
|
||||
<el-text>{{ scope.row.createTime && dayjs(scope.row.createTime).format('YYYY-MM-DD HH:mm:ss')
|
||||
}}</el-text>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="updateTime" label="更新时间">
|
||||
<template #default="scope">
|
||||
<el-text>{{ scope.row.updateTime && dayjs(scope.row.updateTime).format('YYYY-MM-DD HH:mm:ss')
|
||||
}}</el-text>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="100">
|
||||
<template #default="scope">
|
||||
<el-button type="primary" size="small" icon="Edit" @click="editorHandle(scope.row)">编辑</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="mt15">
|
||||
<el-pagination layout="prev, pager, next, total, sizes, jumper" background
|
||||
v-model:current-page="tableOptions.pageNum" v-model:page-size="tableOptions.pageSzie"
|
||||
:page-size="tableOptions.pageSzie" :page-sizes="[10, 20, 30, 50]" :total="tableOptions.total"
|
||||
@size-change="paginationChange" @current-change="paginationChange" />
|
||||
</div>
|
||||
</div>
|
||||
<el-dialog title="新增api" v-model="showDialog" @closed="dialogClosed">
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="120" label-position="left">
|
||||
<el-form-item prop="appId" label="appId" v-if="type == 1">
|
||||
<el-input placeholder="请输入appId" v-model="form.appId" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="ip" label="ip">
|
||||
<el-input type="textarea" :autosize="{ minRows: 2 }" placeholder="请输入ip,多个ip用,分割" v-model="form.ip" />
|
||||
</el-form-item>
|
||||
<el-form-item label="编辑公钥/私钥" v-if="type == 2">
|
||||
<el-switch v-model="showKey"></el-switch>
|
||||
</el-form-item>
|
||||
<template v-if="showKey">
|
||||
<el-form-item prop="publicKey" label="公钥">
|
||||
<el-input type="textarea" :autosize="{ minRows: 2 }" placeholder="请输入公钥" v-model="form.publicKey" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="privateKey" label="私钥">
|
||||
<el-input type="textarea" :autosize="{ minRows: 2 }" placeholder="请输入私钥" v-model="form.privateKey" />
|
||||
<el-text type="warning" size="small" v-if="type == 2">注意:更改公钥/密钥会导致打印机无法使用</el-text>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="success" icon="Connection" :loading="keyLoading"
|
||||
@click="createKeyAjax">一键获取公钥/私钥</el-button>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-space>
|
||||
<el-button @click="showDialog = false">取消</el-button>
|
||||
<el-button type="primary" :loading="formLoading" @click="submitHandle">提交</el-button>
|
||||
</el-space>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import useClipboard from 'vue-clipboard3'
|
||||
import { dayjs, ElMessage } from 'element-plus'
|
||||
import { querySystemApis, createKey, initApi, modfityApi } from '@/api/setting.js'
|
||||
const { toClipboard } = useClipboard()
|
||||
|
||||
const showKey = ref(true)
|
||||
|
||||
const table = ref(null)
|
||||
// 表格参数
|
||||
const tableOptions = reactive({
|
||||
loading: true,
|
||||
appId: '',
|
||||
list: [],
|
||||
total: 0,
|
||||
pageNum: 1,
|
||||
pageSzie: 10
|
||||
})
|
||||
|
||||
// 显示添加表单
|
||||
const showDialog = ref(false)
|
||||
const formLoading = ref(false)
|
||||
const type = ref(1) // 1添加 2编辑
|
||||
const formRef = ref(null)
|
||||
const keyLoading = ref(false)
|
||||
|
||||
// 创建表单
|
||||
const form = reactive({
|
||||
id: '',
|
||||
appId: '',
|
||||
ip: '',
|
||||
publicKey: '',
|
||||
privateKey: ''
|
||||
})
|
||||
|
||||
// 表单校验规则
|
||||
const rules = reactive({
|
||||
appId: [
|
||||
{
|
||||
required: true,
|
||||
message: '',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
ip: [
|
||||
{
|
||||
required: true,
|
||||
message: '',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
publicKey: [
|
||||
{
|
||||
required: true,
|
||||
message: '',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
privateKey: [
|
||||
{
|
||||
required: true,
|
||||
message: '',
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
// 编辑
|
||||
function editorHandle(row) {
|
||||
showDialog.value = true
|
||||
showKey.value = false
|
||||
type.value = 2
|
||||
form.id = row.id
|
||||
form.ip = row.ip
|
||||
form.publicKey = row.publicKey
|
||||
form.privateKey = row.privateKey
|
||||
}
|
||||
|
||||
// 复制
|
||||
async function copyHandle(text) {
|
||||
try {
|
||||
await toClipboard(text)
|
||||
ElMessage.success('复制成功')
|
||||
} catch (error) {
|
||||
ElMessage.error('复制失败,请重试')
|
||||
}
|
||||
}
|
||||
|
||||
// 获取密钥对
|
||||
async function createKeyAjax() {
|
||||
try {
|
||||
keyLoading.value = true
|
||||
const res = await createKey()
|
||||
ElMessage.success('获取成功')
|
||||
keyLoading.value = false
|
||||
form.publicKey = res.publicKey
|
||||
form.privateKey = res.privateKey
|
||||
} catch (error) {
|
||||
keyLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 表单关闭
|
||||
function dialogClosed() {
|
||||
formRef.value.resetFields()
|
||||
form.id = ''
|
||||
form.appId = ''
|
||||
form.ip = ''
|
||||
form.publicKey = ''
|
||||
form.privateKey = ''
|
||||
}
|
||||
|
||||
// 添加
|
||||
function addHandle() {
|
||||
type.value = 1
|
||||
showDialog.value = true
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const submitHandle = async () => {
|
||||
await formRef.value.validate(async (vaild) => {
|
||||
if (vaild) {
|
||||
try {
|
||||
formLoading.value = true
|
||||
if (type.value == 1) {
|
||||
await initApi(form)
|
||||
} else {
|
||||
await modfityApi(form)
|
||||
}
|
||||
formLoading.value = false
|
||||
showDialog.value = false
|
||||
ElMessage.success(type.value == 1 ? '添加成功' : '编辑成功')
|
||||
paginationChange()
|
||||
} catch (error) {
|
||||
formLoading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 重置表格
|
||||
function resizeTable() {
|
||||
tableOptions.appId = ''
|
||||
searchHandle()
|
||||
}
|
||||
|
||||
// 搜索
|
||||
function searchHandle() {
|
||||
tableOptions.pageNum = 1;
|
||||
paginationChange()
|
||||
}
|
||||
|
||||
// 分页回调
|
||||
function paginationChange() {
|
||||
tableOptions.loading = true
|
||||
getTableData()
|
||||
}
|
||||
|
||||
// 获取appid 信息
|
||||
async function getTableData() {
|
||||
try {
|
||||
const res = await querySystemApis({
|
||||
appId: tableOptions.appId,
|
||||
pageNum: tableOptions.pageNum,
|
||||
pageSize: tableOptions.pageSzie
|
||||
})
|
||||
tableOptions.loading = false
|
||||
tableOptions.list = res.list
|
||||
tableOptions.total = res.total
|
||||
table.value.setScrollTop(0)
|
||||
} catch (error) { }
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getTableData()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.table {
|
||||
height: calc(100vh - 356px);
|
||||
}
|
||||
</style>
|
||||
218
src/views/system/menuMange.vue
Normal file
218
src/views/system/menuMange.vue
Normal file
@@ -0,0 +1,218 @@
|
||||
<template>
|
||||
<div class="card">
|
||||
<div>
|
||||
<el-space>
|
||||
<el-button type="primary" icon="Plus" @click="showDialogHandle">添加菜单</el-button>
|
||||
</el-space>
|
||||
</div>
|
||||
<div class="mt15">
|
||||
<el-table :data="tableData" style="width: 100%;">
|
||||
<el-table-column prop="date" label="Date" width="180" />
|
||||
<el-table-column prop="name" label="Name" width="180" />
|
||||
<el-table-column prop="address" label="Address" />
|
||||
</el-table>
|
||||
</div>
|
||||
<el-dialog v-model="showDialog" title="添加菜单" @closed="dialogClose">
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="100">
|
||||
<el-form-item label="类型">
|
||||
<el-radio-group v-model="form.is_menu">
|
||||
<el-radio :label="1" border>菜单</el-radio>
|
||||
<el-radio :label="0" border>按钮</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item prop="name" :label="form.is_menu ? '菜单标识' : '按钮标识'">
|
||||
<el-input :placeholder="form.is_menu ? '请输入菜单标识' : '请输入按钮标识'" clearable v-model="form.name" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="title" :label="form.is_menu ? '菜单标题' : '按钮标题'">
|
||||
<el-input :placeholder="form.is_menu ? '请输入菜单标题' : '请输入按钮标题'" clearable v-model="form.title" />
|
||||
</el-form-item>
|
||||
<template v-if="form.is_menu">
|
||||
<el-form-item prop="path" label="菜单地址">
|
||||
<el-input placeholder="请输入菜单地址" clearable v-model="form.path" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="component" label="组件地址">
|
||||
<el-input placeholder="请输入组件地址" clearable v-model="form.component" />
|
||||
</el-form-item>
|
||||
<el-form-item label="菜单重定向">
|
||||
<el-input placeholder="请输入重定向地址" clearable v-model="form.redirect" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="icon" label="菜单图标">
|
||||
<el-input placeholder="请选择菜单图标" clearable v-model="form.icon" suffix-icon="ArrowRight" readonly
|
||||
style="width: 150px;" @click="showIconDialog = true" />
|
||||
<el-button :icon="form.icon" v-show="form.icon" style="margin-left: 10px;"></el-button>
|
||||
</el-form-item>
|
||||
<el-form-item label="是否隐藏">
|
||||
<el-radio-group v-model="form.isHide">
|
||||
<el-radio :label="false" border>显示</el-radio>
|
||||
<el-radio :label="true" border>隐藏</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-space>
|
||||
<el-button @click="showDialog = false">取消</el-button>
|
||||
<el-button type="primary" @click="submitHandle">提交</el-button>
|
||||
</el-space>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<el-dialog v-model="showIconDialog" title="选择图标" @opened="iconLoading = false">
|
||||
<div class="icon_list">
|
||||
<div class="item" v-for="item in ElIcons" :key="item" @click="selectIocnHandle(item.name)">
|
||||
<SvgIcon :name="item.name" size="30"></SvgIcon>
|
||||
<span class="name">{{ item.name }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import * as ElIcons from '@element-plus/icons-vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
||||
// 获取表单ref
|
||||
let formRef = ref(null);
|
||||
|
||||
// 控制选择图片显示
|
||||
let showIconDialog = ref(false)
|
||||
|
||||
const tableData = [
|
||||
{
|
||||
date: '2016-05-03',
|
||||
name: 'Tom',
|
||||
address: 'No. 189, Grove St, Los Angeles',
|
||||
},
|
||||
{
|
||||
date: '2016-05-02',
|
||||
name: 'Tom',
|
||||
address: 'No. 189, Grove St, Los Angeles',
|
||||
},
|
||||
{
|
||||
date: '2016-05-04',
|
||||
name: 'Tom',
|
||||
address: 'No. 189, Grove St, Los Angeles',
|
||||
}
|
||||
]
|
||||
|
||||
const formType = ref(1);
|
||||
|
||||
const form = reactive({
|
||||
id: '',
|
||||
pid: 0,
|
||||
is_menu: 1,
|
||||
path: '',
|
||||
name: '',
|
||||
component: '',
|
||||
redirect: '',
|
||||
title: '',
|
||||
icon: '',
|
||||
isHide: false
|
||||
})
|
||||
|
||||
const rules = reactive({
|
||||
path: [
|
||||
{
|
||||
required: true,
|
||||
message: '',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
name: [
|
||||
{
|
||||
required: true,
|
||||
message: '',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
title: [
|
||||
{
|
||||
required: true,
|
||||
message: '',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
component: [
|
||||
{
|
||||
required: true,
|
||||
message: '',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
btn_name: [
|
||||
{
|
||||
required: true,
|
||||
message: '',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
btn_title: [
|
||||
{
|
||||
required: true,
|
||||
message: '',
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
const showDialog = ref(false)
|
||||
|
||||
// 关闭dialog
|
||||
const dialogClose = () => {
|
||||
formRef.value.resetFields()
|
||||
}
|
||||
|
||||
// 显示dialog
|
||||
const showDialogHandle = () => {
|
||||
showDialog.value = true
|
||||
formType.value = 1
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const submitHandle = async () => {
|
||||
await formRef.value.validate((vaild, fields) => {
|
||||
if (vaild) {
|
||||
console.log('通过')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 选择icon
|
||||
const selectIocnHandle = (name) => {
|
||||
console.log(name)
|
||||
form.icon = name
|
||||
showIconDialog.value = false
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.icon_list {
|
||||
height: 50vh;
|
||||
overflow-y: auto;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.item {
|
||||
flex: 0 0 25%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 60px;
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
background-color: #efefef;
|
||||
}
|
||||
|
||||
.name {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
20
src/views/tools/editor.vue
Normal file
20
src/views/tools/editor.vue
Normal file
@@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<el-card shadow="hover" header="wangeditor 富文本编辑器">
|
||||
<Editor v-model:get-html="state.editor.htmlVal" v-model:get-text="state.editor.textVal" :disable="state.editor.disable" />
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Editor from "@/components/editor.vue";
|
||||
|
||||
// 定义变量内容
|
||||
const state = reactive({
|
||||
editor: {
|
||||
htmlVal: "<h1>wangeditor 富文本编辑器</h1>",
|
||||
textVal: "wangeditor 富文本编辑器",
|
||||
disable: false,
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
440
src/views/total_earnings/total_earnings_list.vue
Normal file
440
src/views/total_earnings/total_earnings_list.vue
Normal file
@@ -0,0 +1,440 @@
|
||||
<template>
|
||||
<div class="card">
|
||||
<div class="data_row">
|
||||
<div class="item">
|
||||
<div class="icon">
|
||||
<img class="img" src="@/assets/icon_earnings2.png">
|
||||
</div>
|
||||
<div class="info">
|
||||
<div class="title">总收益</div>
|
||||
<div class="num">
|
||||
<count-to :start-val="0" :end-val="earnings.sumProfit" :duration="1000" :decimals="2" prefix="¥" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="icon">
|
||||
<img class="img" src="@/assets/icon_earnings1.png">
|
||||
</div>
|
||||
<div class="info">
|
||||
<div class="title">可提现收益</div>
|
||||
<div class="num">
|
||||
<count-to :start-val="0" :end-val="earnings.availableBalance" :duration="1000" :decimals="2"
|
||||
prefix="¥" />
|
||||
</div>
|
||||
<div class="btn_wrap">
|
||||
<div class="btn">
|
||||
<el-button type="primary" size="small" icon="CreditCard"
|
||||
@click="showWithdraw = true">申请提现</el-button>
|
||||
</div>
|
||||
<div class="btn">
|
||||
<el-button type="warning" size="small" icon="Document"
|
||||
@click="getUserOutFlowHandleResize">提现记录</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="icon">
|
||||
<img class="img" src="@/assets/icon_earnings3.png">
|
||||
</div>
|
||||
<div class="info">
|
||||
<div class="title">提现中收益</div>
|
||||
<div class="num">
|
||||
<count-to :start-val="0" :end-val="earnings.fronZenAmt" :duration="1000" :decimals="2" prefix="¥" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card mt15">
|
||||
<el-space>
|
||||
<el-input placeholder="请输入订单号搜索" v-model="tableOptions.orderNumber" style="width: 200px;" />
|
||||
<el-input placeholder="请输入商户号搜索" v-model="tableOptions.merchantCode" style="width: 200px;" />
|
||||
<el-button type="primary" icon="Search" @click="searchHandle">搜索</el-button>
|
||||
</el-space>
|
||||
<div class="mt15">
|
||||
<div class="table">
|
||||
<el-table :data="tableOptions.list" size="large" stripe border height="100%"
|
||||
v-loading="tableOptions.loading">
|
||||
<el-table-column prop="price" label="收益"></el-table-column>
|
||||
<el-table-column prop="consumeFee" label="收款金额"></el-table-column>
|
||||
<!-- <el-table-column prop="loginName" label="名称"></el-table-column> -->
|
||||
<el-table-column prop="merchantName" label="商家名称"></el-table-column>
|
||||
<el-table-column prop="merchantName" label="收益来源">
|
||||
<template #default="scope">
|
||||
<el-text>{{ scope.row.loginName }}</el-text>
|
||||
<el-tag disable-transitions style="margin-left: 8px;">{{ typeNames[scope.row.typeCode]
|
||||
}}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createDt" label="时间">
|
||||
<template #default="scope">
|
||||
{{ dayjs(scope.row.createDt).format('YYYY-MM-DD HH:mm:ss') }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt15">
|
||||
<el-pagination layout="prev, pager, next, total, sizes, jumper" background
|
||||
v-model:current-page="tableOptions.pageNum" v-model:page-size="tableOptions.pageSize"
|
||||
:page-size="tableOptions.pageSize" :page-sizes="[10, 20, 30, 50]" :total="tableOptions.total"
|
||||
@size-change="paginationChange" @current-change="paginationChange" />
|
||||
</div>
|
||||
</div>
|
||||
<el-dialog v-model="showWithdraw" title="申请提现" width="600" @closed="formRef.resetFields()">
|
||||
<el-space>
|
||||
<el-form ref="formRef" :model="form" :rules="rules">
|
||||
<el-form-item label="提现金额" prop="num">
|
||||
<el-space>
|
||||
<el-input placeholder="请输入提现金额" clearable style="width: 300px;" :model-value="form.num"
|
||||
@input="numInput" />
|
||||
<el-button type="primary" @click="form.num = ((earnings.availableBalance / 100) * 100).toFixed(2)">
|
||||
全部提现(¥{{ ((earnings.availableBalance / 100) * 100).toFixed(2) }})
|
||||
</el-button>
|
||||
</el-space>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-space>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="showWithdraw = false">取消</el-button>
|
||||
<el-button type="primary" :loading="form.loading" @click="submitHandle">确定</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<el-dialog v-model="records.show" title="提现记录">
|
||||
<el-row>
|
||||
<el-select v-model="records.status" @change="recordsPaginationChange">
|
||||
<el-option label="全部" value="" key="" />
|
||||
<el-option label="待审核" :value="0" :key="0" />
|
||||
<el-option label="审核通过" :value="1" :key="1" />
|
||||
<el-option label="提现失败" :value="2" :key="2" />
|
||||
<el-option label="审核中" :value="3" :key="3" />
|
||||
</el-select>
|
||||
</el-row>
|
||||
<div class="records_table mt15">
|
||||
<el-table :data="records.list" size="large" border height="100%" v-loading="records.loading">
|
||||
<el-table-column prop="id" label="机构id"></el-table-column>
|
||||
<el-table-column prop="cashAmt" label="提现金额">
|
||||
<template #default="scope">
|
||||
<el-text type="primary">{{ scope.row.cashamt }}元</el-text>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createDt" label="提现时间" width="250">
|
||||
<template #default="scope">
|
||||
<el-text>{{ dayjs(scope.row.createdt).format('YYYY-MM-DD HH:mm:ss') }}</el-text>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态">
|
||||
<template #default="scope">
|
||||
<el-tag type="info" disable-transitions v-if="scope.row.status == 0">待审核</el-tag>
|
||||
<el-tag type="success" disable-transitions v-if="scope.row.status == 1">提现成功</el-tag>
|
||||
<el-tag type="warning" disable-transitions v-if="scope.row.status == 2">提现失败</el-tag>
|
||||
<el-tag type="info" disable-transitions v-if="scope.row.status == 3">审核中</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="cashStatus" label="上级审核信息">
|
||||
<template #default="scope">
|
||||
<el-link type="primary" icon="Search"
|
||||
@click="showCheckModle(scope.$index, scope.row.cashstatus)">查看进度</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="mt15">
|
||||
<el-pagination layout="prev, pager, next, total, sizes, jumper" background
|
||||
v-model:current-page="records.pageNum" v-model:page-size="records.pageSize" :page-size="records.pageSize"
|
||||
:page-sizes="[10, 20, 30, 50]" :total="records.total" @size-change="recordsPaginationChange"
|
||||
@current-change="recordsPaginationChange" />
|
||||
</div>
|
||||
<el-dialog v-model="records.showProgress" title="审核进度">
|
||||
<el-steps :active="rowProgressActive" align-center>
|
||||
<el-step :title="typeNames[item.userType]" :description="statusEmun[item.status]"
|
||||
v-for="(item, index) in rowProgress" :key="index"></el-step>
|
||||
</el-steps>
|
||||
<div style="padding-bottom: 28px;"></div>
|
||||
</el-dialog>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import hooks from '@/hooks'
|
||||
import { dayjs } from 'element-plus';
|
||||
import { typeNames, clearNoNum } from '@/utils/index.js'
|
||||
import { queryProfit, getUserBalance, withdrawalProfit, getUserOutFlow } from '@/api/organization.js'
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
||||
// 表格参数
|
||||
const tableOptions = reactive({
|
||||
loading: true,
|
||||
reqUserId: '', // 上级id
|
||||
orderNumber: '', // 订单号
|
||||
merchantCode: '', // 商户号
|
||||
list: [],
|
||||
total: 0,
|
||||
pageNum: 1,
|
||||
pageSize: 10
|
||||
})
|
||||
|
||||
// 收益数据
|
||||
const earnings = reactive({
|
||||
sumProfit: 0,
|
||||
availableBalance: 0,
|
||||
fronZenAmt: 0
|
||||
})
|
||||
|
||||
// 显示提现弹窗
|
||||
const formRef = ref()
|
||||
const showWithdraw = ref(false)
|
||||
|
||||
const form = reactive({
|
||||
num: '',
|
||||
loading: false
|
||||
})
|
||||
|
||||
const rules = reactive({
|
||||
num: [
|
||||
{
|
||||
required: true,
|
||||
message: '',
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
// 格式化数字
|
||||
function numInput(e) {
|
||||
let n = clearNoNum({ value: e })
|
||||
if (n <= earnings.availableBalance) {
|
||||
form.num = n
|
||||
} else {
|
||||
form.num = ((earnings.availableBalance / 100) * 100).toFixed(2)
|
||||
}
|
||||
}
|
||||
|
||||
// 提交提现申请
|
||||
async function submitHandle() {
|
||||
await formRef.value.validate(async (valid) => {
|
||||
if (valid) {
|
||||
try {
|
||||
form.loading = true
|
||||
await withdrawalProfit({
|
||||
amount: form.num
|
||||
})
|
||||
form.loading = false
|
||||
showWithdraw.value = false
|
||||
getUserBalanceHandle()
|
||||
} catch (error) {
|
||||
form.loading = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 提现记录
|
||||
const records = reactive({
|
||||
show: false,
|
||||
showProgress: false,
|
||||
loading: false,
|
||||
status: '',
|
||||
list: [],
|
||||
total: 0,
|
||||
pageNum: 1,
|
||||
pageSize: 10
|
||||
})
|
||||
// 当前表格索引
|
||||
const rowIndex = ref(0)
|
||||
// 当前进度数组
|
||||
const rowProgress = ref([])
|
||||
// 当前进度索引
|
||||
const rowProgressActive = ref(0)
|
||||
// 状态枚举
|
||||
const statusEmun = ref({
|
||||
"0": '待审核',
|
||||
"1": '审核通过',
|
||||
"2": '提现失败',
|
||||
"3": '审核中'
|
||||
})
|
||||
|
||||
// 查看当前进度
|
||||
function showCheckModle(row, cashStatus) {
|
||||
if (cashStatus) {
|
||||
records.showProgress = true
|
||||
rowIndex.value = row
|
||||
console.log(JSON.parse(cashStatus))
|
||||
rowProgress.value = JSON.parse(cashStatus)
|
||||
|
||||
rowProgress.value.map((item, index) => {
|
||||
if (item.status != 0) {
|
||||
rowProgressActive.value = index + 1
|
||||
}
|
||||
})
|
||||
} else {
|
||||
ElMessage.error('暂时无法查看,请稍后再试!')
|
||||
}
|
||||
}
|
||||
|
||||
// 提现记录分页回调
|
||||
function recordsPaginationChange() {
|
||||
getUserOutFlowHandle()
|
||||
}
|
||||
|
||||
// 重新获取提现记录
|
||||
function getUserOutFlowHandleResize() {
|
||||
records.show = true
|
||||
records.pageNum = 1
|
||||
records.loading = true
|
||||
getUserOutFlowHandle()
|
||||
}
|
||||
|
||||
// 获取提现流水
|
||||
async function getUserOutFlowHandle() {
|
||||
try {
|
||||
const { total, list } = await getUserOutFlow({
|
||||
status: records.status,
|
||||
pageNum: records.pageNum,
|
||||
pageSize: records.pageSize
|
||||
})
|
||||
records.loading = false
|
||||
records.list = list
|
||||
records.total = total
|
||||
} catch (error) {
|
||||
records.loading = false
|
||||
}
|
||||
}
|
||||
|
||||
// 搜索
|
||||
function searchHandle() {
|
||||
tableOptions.pageNum = 1;
|
||||
paginationChange()
|
||||
}
|
||||
|
||||
// 分页回调
|
||||
function paginationChange() {
|
||||
tableOptions.loading = true
|
||||
getTableDate()
|
||||
}
|
||||
|
||||
// 获取机构列表
|
||||
async function getTableDate() {
|
||||
try {
|
||||
const res = await queryProfit({
|
||||
reqUserId: hooks.useLocalStorage.get('userInfo').userId,
|
||||
orderNumber: tableOptions.orderNumber,
|
||||
merchantCode: tableOptions.merchantCode,
|
||||
pageNum: tableOptions.pageNum,
|
||||
pageSize: tableOptions.pageSize
|
||||
})
|
||||
tableOptions.loading = false
|
||||
tableOptions.list = res.list
|
||||
tableOptions.total = res.total
|
||||
} catch (error) { }
|
||||
}
|
||||
|
||||
// 查询用户总收益和可提收益,冻结收益 ,已提收益
|
||||
async function getUserBalanceHandle() {
|
||||
try {
|
||||
const res = await getUserBalance()
|
||||
earnings.sumProfit = res.sumProfit
|
||||
earnings.availableBalance = res.availableBalance
|
||||
earnings.fronZenAmt = res.fronZenAmt
|
||||
} catch (error) { }
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getTableDate()
|
||||
getUserBalanceHandle()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.table {
|
||||
height: calc(100vh - 455px);
|
||||
}
|
||||
|
||||
.records_table {
|
||||
height: 50vh;
|
||||
}
|
||||
|
||||
.data_row {
|
||||
display: flex;
|
||||
padding: 24px 0;
|
||||
|
||||
.item {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
padding-left: 50px;
|
||||
|
||||
&:not(:last-child) {
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
height: 100%;
|
||||
border-right: 1px solid #ececec;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.icon {
|
||||
$size: 50px;
|
||||
width: $size;
|
||||
height: $size;
|
||||
|
||||
.img {
|
||||
width: $size;
|
||||
height: $size;
|
||||
}
|
||||
}
|
||||
|
||||
.info {
|
||||
flex: 1;
|
||||
padding-left: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
|
||||
.title {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.num {
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
padding-top: 10px;
|
||||
|
||||
.i {
|
||||
font-size: 12px;
|
||||
position: relative;
|
||||
bottom: 1px;
|
||||
right: -4px;
|
||||
}
|
||||
}
|
||||
|
||||
.btn_wrap {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 14%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.btn {
|
||||
flex: 1;
|
||||
|
||||
&:last-child {
|
||||
margin-top: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
202
src/views/withdraw/withdraw_list.vue
Normal file
202
src/views/withdraw/withdraw_list.vue
Normal file
@@ -0,0 +1,202 @@
|
||||
<template>
|
||||
<div class="card">
|
||||
<el-space>
|
||||
<el-input placeholder="用户名称" v-model="tableOptions.userName" style="width: 200px;" />
|
||||
<el-input placeholder="商户号" v-model="tableOptions.merchantCode" style="width: 200px;" />
|
||||
<el-select v-model="tableOptions.status">
|
||||
<el-option key="" value="" label="全部"></el-option>
|
||||
<el-option :key="0" :value="0" label="待审核"></el-option>
|
||||
<el-option :key="1" :value="1" label="提现成功"></el-option>
|
||||
<el-option :key="2" :value="2" label="提现失败"></el-option>
|
||||
<el-option :key="3" :value="3" label="审核中"></el-option>
|
||||
</el-select>
|
||||
<el-button type="primary" icon="Search" @click="searchHandle">搜索</el-button>
|
||||
</el-space>
|
||||
<div class="table mt15">
|
||||
<el-table :data="tableOptions.list" size="large" stripe border height="100%" v-loading="tableOptions.loading">
|
||||
<el-table-column prop="id" label="机构id"></el-table-column>
|
||||
<el-table-column prop="merchantCode" label="商户号"></el-table-column>
|
||||
<el-table-column prop="userName" label="商户名称"></el-table-column>
|
||||
<el-table-column prop="accountNo" label="账户号"></el-table-column>
|
||||
<el-table-column prop="cashAmt" label="提现金额">
|
||||
<template #default="scope">
|
||||
<el-text type="primary">{{ scope.row.cashAmt }}元</el-text>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="userId" label="用户id"></el-table-column>
|
||||
<el-table-column prop="createDt" label="提现时间">
|
||||
<template #default="scope">
|
||||
<el-text>{{ dayjs(scope.row.createDt).format('YYYY-MM-DD HH:mm:ss') }}</el-text>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="typeCode" label="提现人身份">
|
||||
<template #default="scope">
|
||||
<el-tag disable-transitions>{{ typeNames[scope.row.typeCode] }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态">
|
||||
<template #default="scope">
|
||||
<el-tag type="info" v-if="scope.row.status == 0">待审核</el-tag>
|
||||
<el-tag type="success" v-if="scope.row.status == 1">提现成功</el-tag>
|
||||
<el-tag type="warning" v-if="scope.row.status == 2">提现失败</el-tag>
|
||||
<el-tag type="info" v-if="scope.row.status == 3">审核中</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="cashStatus" label="上级审核信息">
|
||||
<template #default="scope">
|
||||
<el-link type="primary" icon="Search"
|
||||
@click="showCheckModle(scope.$index, scope.row.cashStatus)">查看进度</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作">
|
||||
<template #default="scope">
|
||||
<template v-if="scope.row.show && scope.row.status != 2">
|
||||
<el-popconfirm title="是否审核通过?" width="200" confirm-button-text="通过" cancel-button-text="驳回"
|
||||
@cancel="checkHandle(scope.row, 2)" @confirm="checkHandle(scope.row, 1)">
|
||||
<template #reference>
|
||||
<el-button type="primary" size="small" icon="EditPen">审核</el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-button type="default" size="small" icon="EditPen" disabled>
|
||||
审核
|
||||
</el-button>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="mt15">
|
||||
<el-pagination layout="prev, pager, next, total, sizes, jumper" background
|
||||
v-model:current-page="tableOptions.pageNum" v-model:page-size="tableOptions.pageSize"
|
||||
:page-size="tableOptions.pageSize" :page-sizes="[10, 20, 30, 50]" :total="tableOptions.total"
|
||||
@size-change="paginationChange" @current-change="paginationChange" />
|
||||
</div>
|
||||
<el-dialog v-model="show" title="审核进度">
|
||||
<el-steps :active="rowProgressActive" align-center>
|
||||
<el-step :title="typeNames[item.userType]" :description="statusEmun[item.status]"
|
||||
v-for="(item, index) in rowProgress" :key="index"></el-step>
|
||||
</el-steps>
|
||||
<div style="padding-bottom: 28px;"></div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { getOutFlow, modifyOutFlow } from '@/api/withdraw.js'
|
||||
import { onMounted, reactive, ref } from 'vue'
|
||||
import { typeNames } from '@/utils/index.js'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { dayjs } from 'element-plus'
|
||||
import hooks from '@/hooks'
|
||||
|
||||
// 显示进度dialog
|
||||
const show = ref(false)
|
||||
// 当前表格索引
|
||||
const rowIndex = ref(0)
|
||||
// 当前进度数组
|
||||
const rowProgress = ref([])
|
||||
// 当前进度索引
|
||||
const rowProgressActive = ref(0)
|
||||
// 状态枚举
|
||||
const statusEmun = ref({
|
||||
"0": '待审核',
|
||||
"1": '审核通过',
|
||||
"2": '提现失败',
|
||||
"3": '审核中'
|
||||
})
|
||||
|
||||
// 查看当前进度
|
||||
function showCheckModle(row, cashStatus) {
|
||||
show.value = true
|
||||
rowIndex.value = row
|
||||
console.log(JSON.parse(cashStatus))
|
||||
rowProgress.value = JSON.parse(cashStatus)
|
||||
|
||||
rowProgress.value.map((item, index) => {
|
||||
if (item.status != 0) {
|
||||
rowProgressActive.value = index + 1
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 审核操作
|
||||
async function checkHandle(row, status) {
|
||||
try {
|
||||
await modifyOutFlow({
|
||||
id: row.id,
|
||||
status: status
|
||||
})
|
||||
ElMessage.success('提交成功')
|
||||
paginationChange()
|
||||
} catch (error) { }
|
||||
}
|
||||
|
||||
// 表格参数
|
||||
const tableOptions = reactive({
|
||||
loading: true,
|
||||
userName: '',
|
||||
merchantCode: '',
|
||||
status: 0,
|
||||
list: [],
|
||||
total: 0,
|
||||
pageNum: 1,
|
||||
pageSize: 10
|
||||
})
|
||||
|
||||
// 搜索
|
||||
function searchHandle() {
|
||||
tableOptions.pageNum = 1;
|
||||
getOutFlowHandle()
|
||||
}
|
||||
|
||||
// 分页回调
|
||||
function paginationChange() {
|
||||
tableOptions.loading = true
|
||||
getOutFlowHandle()
|
||||
}
|
||||
|
||||
// 提现申请查询
|
||||
async function getOutFlowHandle() {
|
||||
try {
|
||||
const res = await getOutFlow({
|
||||
userName: tableOptions.userName,
|
||||
merchantCode: tableOptions.merchantCode,
|
||||
status: tableOptions.status,
|
||||
pageNum: tableOptions.pageNum,
|
||||
pageSize: tableOptions.pageSize
|
||||
})
|
||||
|
||||
const userInfo = hooks.useLocalStorage.get('userInfo')
|
||||
const data = [...res.list];
|
||||
|
||||
// console.log(userInfo.userType)
|
||||
|
||||
for (let item of data) {
|
||||
item.show = false;
|
||||
const arr = JSON.parse(item.cashStatus);
|
||||
// console.log(arr);
|
||||
for (let child of arr) {
|
||||
if (child.userType == userInfo.userType && child.status == 0) {
|
||||
item.show = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tableOptions.loading = false
|
||||
tableOptions.list = data
|
||||
tableOptions.total = res.total
|
||||
} catch (error) { }
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getOutFlowHandle()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.table {
|
||||
height: calc(100vh - 310px);
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user