agent-allow-table

This commit is contained in:
xiaomlove
2021-04-15 19:20:32 +08:00
parent 3f13ec875f
commit dc7aa33036
10 changed files with 817 additions and 421 deletions

724
admin/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -32,6 +32,7 @@
</template>
<el-menu-item-group>
<el-menu-item index="/swiper"><i class="el-icon-picture" />轮播图配置</el-menu-item>
<el-menu-item index="/agent-allow"><i class="el-icon-picture" />允许客户端</el-menu-item>
<el-menu-item index="/hot"><i class="el-icon-star-on" />热销商品配置</el-menu-item>
<el-menu-item index="/new"><i class="el-icon-sell" />新品上线配置</el-menu-item>
<el-menu-item index="/recommend"><i class="el-icon-thumb" />为你推荐配置</el-menu-item>

100
admin/src/main.js vendored
View File

@@ -1,52 +1,84 @@
import { createApp } from 'vue'
import ElementPlus from 'element-plus';
import { ElButton, ElContainer, ElAside, ElHeader, ElMain, ElFooter, ElMenu, ElSubmenu, ElMenuItemGroup, ElMenuItem, ElForm, ElFormItem, ElInput, ElPopover, ElTag, ElCard, ElTable, ElTableColumn, ElPagination, ElDialog, ElPopconfirm, ElUpload, ElLoading, ElSelect, ElOption, ElRadioGroup, ElRadio, ElCascader, ElCheckbox, ElInputNumber } from 'element-plus'
import App from './App.vue'
import router from './router/index'
import 'element-plus/lib/theme-chalk/index.css'
// import 'element-plus/lib/theme-chalk/index.css'
// 修改后的主题样式必须放在最后面
import '../theme/index.css'
const orderStatus = {
0: '待支付',
1: '已支付',
2: '配货完成',
3: '出库成功',
4: '交易成功',
'-1': '手动关闭',
'-2': '超时关闭',
'-3': '商家关闭'
0: '待支付',
1: '已支付',
2: '配货完成',
3: '出库成功',
4: '交易成功',
'-1': '手动关闭',
'-2': '超时关闭',
'-3': '商家关闭'
}
const app = createApp(App)
// 全局过滤器
app.config.globalProperties.$filters = {
orderMap(status) {
return orderStatus[status] || '未知状态'
},
prefix(url) {
if (url && url.startsWith('http')) {
return url
} else {
url = `http://backend-api-02.newbee.ltd${url}`
return url
orderMap(status) {
return orderStatus[status] || '未知状态'
},
prefix(url) {
if (url && url.startsWith('http')) {
return url
} else {
url = `http://backend-api-02.newbee.ltd${url}`
return url
}
},
resetImgUrl(imgObj, imgSrc, maxErrorNum) {
if (maxErrorNum > 0) {
imgObj.onerror = function() {
resetImgUrl(imgObj, imgSrc, maxErrorNum - 1)
}
setTimeout(function() {
imgObj.src = imgSrc
}, 500)
} else {
imgObj.onerror = null
imgObj.src = imgSrc
}
}
},
resetImgUrl(imgObj, imgSrc, maxErrorNum) {
if (maxErrorNum > 0) {
imgObj.onerror = function() {
resetImgUrl(imgObj, imgSrc, maxErrorNum - 1)
}
setTimeout(function() {
imgObj.src = imgSrc
}, 500)
} else {
imgObj.onerror = null
imgObj.src = imgSrc
}
}
}
app.use(router).use(ElementPlus)
app.use(router)
app.use(ElButton)
.use(ElContainer)
.use(ElAside)
.use(ElHeader)
.use(ElMain)
.use(ElFooter)
.use(ElMenu)
.use(ElSubmenu)
.use(ElMenuItemGroup)
.use(ElMenuItem)
.use(ElForm)
.use(ElFormItem)
.use(ElInput)
.use(ElPopover)
.use(ElTag)
.use(ElCard)
.use(ElTable)
.use(ElTableColumn)
.use(ElPagination)
.use(ElDialog)
.use(ElPopconfirm)
.use(ElUpload)
.use(ElLoading)
.use(ElSelect)
.use(ElOption)
.use(ElRadioGroup)
.use(ElRadio)
.use(ElCascader)
.use(ElCheckbox)
.use(ElInputNumber)
app.mount('#app')

View File

@@ -88,8 +88,13 @@ const router = createRouter({
path: '/account',
name: 'account',
component: () => import(/* webpackChunkName: "account" */ '../views/Account.vue')
}
},
{
path: '/agent-allow',
name: 'agent-allow',
component: () => import(/* webpackChunkName: "account" */ '../views/AgentAllow/index.vue')
}
]
})
export default router
export default router

11
admin/src/utils/api.js vendored Normal file
View File

@@ -0,0 +1,11 @@
import axios from "./axios";
const baseUrl = 'http://nexus-php8.tinyhd.net/api/';
const api = {
listAllowAgent: (params = {}) => {
return axios.get(baseUrl + 'agent-allow', {params: params});
}
}
export default api

View File

@@ -17,11 +17,12 @@ axios.defaults.headers.post['Content-Type'] = 'application/json'
// 请求拦截器,内部根据返回值,重新组装,统一管理。
axios.interceptors.response.use(res => {
console.log(res)
if (typeof res.data !== 'object') {
ElMessage.error('服务端异常!')
return Promise.reject(res)
}
if (res.data.resultCode != 200) {
if (res.data.resultCode && res.data.resultCode != 200) {
if (res.data.message) ElMessage.error(res.data.message)
if (res.data.resultCode == 419) {
router.push({ path: '/login' })
@@ -32,4 +33,4 @@ axios.interceptors.response.use(res => {
return res.data.data
})
export default axios
export default axios

View File

@@ -42,5 +42,6 @@ export const pathMap = {
guest: '会员管理',
order: '订单管理',
order_detail: '订单详情',
account: '修改账户'
}
account: '修改账户',
"agent-allow": "允许客户端"
}

View File

@@ -0,0 +1,172 @@
<template>
<el-dialog
:title="type == 'add' ? '添加轮播图' : '修改轮播图'"
v-model="visible"
width="400px"
>
<el-form :model="ruleForm" :rules="rules" ref="formRef" label-width="100px" class="good-form">
<el-form-item label="图片" prop="url">
<el-upload
class="avatar-uploader"
:action="uploadImgServer"
accept="jpg,jpeg,png"
:headers="{
token: token
}"
:show-file-list="false"
:before-upload="handleBeforeUpload"
:on-success="handleUrlSuccess"
>
<img style="width: 200px; height: 100px; border: 1px solid #e9e9e9;" v-if="ruleForm.url" :src="ruleForm.url" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
</el-form-item>
<el-form-item label="跳转链接" prop="link">
<el-input type="text" v-model="ruleForm.link"></el-input>
</el-form-item>
<el-form-item label="排序值" prop="sort">
<el-input type="number" v-model="ruleForm.sort"></el-input>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="visible = false"> </el-button>
<el-button type="primary" @click="submitForm"> </el-button>
</span>
</template>
</el-dialog>
</template>
<script>
import { reactive, ref, toRefs } from 'vue'
import axios from '@/utils/axios'
import { localGet, uploadImgServer, hasEmoji } from '@/utils'
import { ElMessage } from 'element-plus'
export default {
name: 'DialogAddSwiper',
props: {
type: String,
reload: Function
},
setup(props) {
const formRef = ref(null)
const state = reactive({
uploadImgServer,
token: localGet('token') || '',
visible: false,
ruleForm: {
url: '',
link: '',
sort: ''
},
rules: {
url: [
{ required: 'true', message: '图片不能为空', trigger: ['change'] }
],
sort: [
{ required: 'true', message: '排序不能为空', trigger: ['change'] }
]
},
id: ''
})
// 获取详情
const getDetail = (id) => {
axios.get(`/carousels/${id}`).then(res => {
state.ruleForm = {
url: res.carouselUrl,
link: res.redirectUrl,
sort: res.carouselRank
}
})
}
const handleBeforeUpload = (file) => {
const sufix = file.name.split('.')[1] || ''
if (!['jpg', 'jpeg', 'png'].includes(sufix)) {
ElMessage.error('请上传 jpg、jpeg、png 格式的图片')
return false
}
}
// 上传图片
const handleUrlSuccess = (val) => {
state.ruleForm.url = val.data || ''
}
// 开启弹窗
const open = (id) => {
state.visible = true
if (id) {
state.id = id
getDetail(id)
} else {
state.ruleForm = {
url: '',
link: '',
sort: ''
}
}
}
// 关闭弹窗
const close = () => {
state.visible = false
}
const submitForm = () => {
console.log(formRef.value.validate)
formRef.value.validate((valid) => {
if (valid) {
if (hasEmoji(state.ruleForm.link)) {
ElMessage.error('不要输入表情包,再输入就打死你个龟孙儿~')
return
}
if (props.type == 'add') {
axios.post('/carousels', {
carouselUrl: state.ruleForm.url,
redirectUrl: state.ruleForm.link,
carouselRank: state.ruleForm.sort
}).then(() => {
ElMessage.success('添加成功')
state.visible = false
if (props.reload) props.reload()
})
} else {
axios.put('/carousels', {
carouselId: state.id,
carouselUrl: state.ruleForm.url,
redirectUrl: state.ruleForm.link,
carouselRank: state.ruleForm.sort
}).then(() => {
ElMessage.success('修改成功')
state.visible = false
if (props.reload) props.reload()
})
}
}
})
}
return {
...toRefs(state),
open,
close,
formRef,
handleBeforeUpload,
handleUrlSuccess,
submitForm
}
}
}
</script>
<style scoped>
.avatar-uploader {
width: 100px;
height: 100px;
color: #ddd;
font-size: 30px;
}
.avatar-uploader-icon {
display: block;
width: 100%;
height: 100%;
border: 1px solid #e9e9e9;
padding: 32px 17px;
}
</style>

View File

@@ -0,0 +1,210 @@
<template>
<el-card class="swiper-container">
<template #header>
<div class="header">
<el-button type="primary" size="small" icon="el-icon-plus" @click="handleAdd">增加</el-button>
<el-popconfirm
title="确定删除吗?"
@confirm="handleDelete"
>
<template #reference>
<el-button type="danger" size="small" icon="el-icon-delete">批量删除</el-button>
</template>
</el-popconfirm>
</div>
</template>
<el-table
v-loading="loading"
ref="multipleTable"
:data="tableData"
tooltip-effect="dark"
style="width: 100%"
@selection-change="handleSelectionChange">
<el-table-column
type="selection"
>
</el-table-column>
<el-table-column
label="ID"
prop="id"
width="60"
>
</el-table-column>
<el-table-column
label="起始名称"
prop="start_name"
>
</el-table-column>
<el-table-column
label="Agent 起始"
prop="agent_start"
>
</el-table-column>
<el-table-column
label="Agent 模式串"
prop="agent_pattern"
>
</el-table-column>
<el-table-column
prop="peer_id_start"
label="Peer ID 起始"
>
</el-table-column>
<el-table-column
prop="peer_id_pattern"
label="Peer ID 模式串"
>
</el-table-column>
<el-table-column
label="操作"
width="100"
>
<template #default="scope">
<a style="cursor: pointer; margin-right: 10px" @click="handleEdit(scope.row.carouselId)">修改</a>
<el-popconfirm
title="确定删除吗?"
@confirm="handleDeleteOne(scope.row.carouselId)"
>
<template #reference>
<a style="cursor: pointer">删除</a>
</template>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<!--总数超过一页再展示分页器-->
<el-pagination
background
layout="prev, pager, next"
:total="total"
:page-size="pageSize"
:current-page="currentPage"
@current-change="changePage"
/>
</el-card>
<DialogAddSwiper ref='addGood' :reload="getCarousels" :type="type" />
</template>
<script>
import { onMounted, reactive, ref, toRefs } from 'vue'
import { ElMessage } from 'element-plus'
import DialogAddSwiper from '@/components/DialogAddSwiper.vue'
import AgentAllowForm from './form.vue'
import axios from '@/utils/axios'
import api from '@/utils/api'
export default {
name: 'Swiper',
components: {
DialogAddSwiper
},
setup() {
const multipleTable = ref(null)
const addGood = ref(null)
const state = reactive({
loading: false,
tableData: [], // 数据列表
multipleSelection: [], // 选中项
total: 0, // 总条数
currentPage: 1, // 当前页
pageSize: 10, // 分页大小
type: 'add', // 操作类型
})
onMounted(() => {
// getCarousels()
listAgentAllow()
})
// 获取轮播图列表
const getCarousels = () => {
// state.loading = true
// axios.get('/carousels', {
// params: {
// pageNumber: state.currentPage,
// pageSize: state.pageSize
// }
// }).then(res => {
// state.tableData = res.list
// state.total = res.totalCount
// state.currentPage = res.currPage
// state.loading = false
// })
}
const listAgentAllow = () => {
state.loading = true
api.listAllowAgent({page: state.currentPage}).then(res => {
state.tableData = res.data
state.total = res.meta.total
state.currentPage = res.meta.current_page
state.pageSize = res.meta.per_page
state.loading = false
})
}
// 添加轮播项
const handleAdd = () => {
state.type = 'add'
addGood.value.open()
}
// 修改轮播图
const handleEdit = (id) => {
state.type = 'edit'
addGood.value.open(id)
}
// 选择项
const handleSelectionChange = (val) => {
state.multipleSelection = val
}
// 批量删除
const handleDelete = () => {
if (!state.multipleSelection.length) {
ElMessage.error('请选择项')
return
}
axios.delete('/carousels', {
data: {
ids: state.multipleSelection.map(i => i.carouselId)
}
}).then(() => {
ElMessage.success('删除成功')
getCarousels()
})
}
// 单个删除
const handleDeleteOne = (id) => {
axios.delete('/carousels', {
data: {
ids: [id]
}
}).then(() => {
ElMessage.success('删除成功')
getCarousels()
})
}
const changePage = (val) => {
state.currentPage = val
listAgentAllow()
}
return {
...toRefs(state),
multipleTable,
handleSelectionChange,
addGood,
handleAdd,
handleEdit,
handleDelete,
handleDeleteOne,
getCarousels,
changePage
}
}
}
</script>
<style scoped>
.swiper-container {
min-height: 100%;
}
.el-card.is-always-shadow {
min-height: 100%!important;
}
</style>

View File

@@ -9,6 +9,7 @@ const baseUrl = {
release: './'
}
// https://vitejs.dev/config/
export default ({ mode }) => defineConfig({
plugins: [