You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
364 lines
9.8 KiB
364 lines
9.8 KiB
<template>
|
|
<div>
|
|
<div class="title">用户管理</div>
|
|
<el-form
|
|
ref="searchFormRef"
|
|
class="form"
|
|
:inline="true"
|
|
label-width="98px"
|
|
:model="queryParams"
|
|
>
|
|
<el-form-item label="用户名称" prop="username">
|
|
<el-input
|
|
clearable
|
|
placeholder="请输入"
|
|
style="width: 220px"
|
|
v-model="queryParams.username"
|
|
@keyup.enter="handleQuery"
|
|
/>
|
|
</el-form-item>
|
|
|
|
<el-form-item label-width="100px">
|
|
<el-button icon="Search" type="primary" @click="handleQuery"> 搜索 </el-button>
|
|
<el-button icon="RefreshRight" @click="resetQuery"> 重置 </el-button>
|
|
</el-form-item>
|
|
</el-form>
|
|
|
|
<div style="margin-bottom: 20px">
|
|
<el-button icon="Plus" type="primary" @click="add"> 新建 </el-button>
|
|
</div>
|
|
<div ref="tableContainerEl" class="table_border table">
|
|
<el-table
|
|
ref="tableRef"
|
|
:data="tableData"
|
|
v-loading="loading"
|
|
header-row-class-name="table-header"
|
|
>
|
|
<el-table-column align="center" label="用户名" prop="username" show-overflow-tooltip />
|
|
<el-table-column align="center" label="电话" prop="phone" show-overflow-tooltip />
|
|
<el-table-column align="center" label="邮件" prop="email" show-overflow-tooltip />
|
|
<el-table-column align="center" label="角色" prop="roles">
|
|
<template #default="{ row }">
|
|
{{ row.roles?.map((item) => item.name)?.join(',') }}
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column align="center" label="厂商" prop="vendors">
|
|
<template #default="{ row }">
|
|
{{ row.vendors?.map((item) => item.name)?.join(',') }}
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column align="center" label="操作" width="180">
|
|
<template #default="{ row }">
|
|
<div class="flex items-center">
|
|
<el-button link type="primary" @click="editRole(row)"> 分配角色 </el-button>
|
|
<el-button link type="primary" @click="edit(row)"> 编辑 </el-button>
|
|
|
|
<el-button link type="danger" @click="handleDelete(row)"> 删除 </el-button>
|
|
</div>
|
|
<template v-if="useUserStore().userInfo?.isAdmin">
|
|
<div class="flex items-center">
|
|
<el-button link type="primary" @click="order(row)"> 赠送套餐 </el-button>
|
|
<el-button link type="primary" @click="pay(row)"> 充值 </el-button>
|
|
</div>
|
|
<div class="flex items-center">
|
|
<el-button link type="primary" @click="vendor(row, 'authorize')">
|
|
分配厂商
|
|
</el-button>
|
|
<el-button
|
|
link
|
|
type="primary"
|
|
v-if="row.vendors?.length > 0"
|
|
@click="vendor(row, 'revoke')"
|
|
>
|
|
撤销厂商
|
|
</el-button>
|
|
</div>
|
|
</template>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
</div>
|
|
|
|
<pagination
|
|
v-show="total > 0"
|
|
:total="total"
|
|
v-model:limit="queryParams.limit"
|
|
v-model:page="queryParams.page"
|
|
@pagination="getList"
|
|
/>
|
|
|
|
<HandleDialog
|
|
v-if="isShowDialog"
|
|
:type="rowType"
|
|
:row="currentRow"
|
|
@closed="isShowDialog = false"
|
|
@on-success="getList"
|
|
/>
|
|
<RoleDialog
|
|
v-if="isShowRoleDialog"
|
|
:row="currentRow"
|
|
:roleList="roleList"
|
|
@closed="isShowRoleDialog = false"
|
|
@on-success="getList"
|
|
/>
|
|
|
|
<el-dialog
|
|
align-center
|
|
title="充值"
|
|
width="500"
|
|
v-model="isShowPayDialog"
|
|
@closed="payClosed"
|
|
:close-on-click-modal="false"
|
|
>
|
|
是否给【{{ currentRow.username }}】进行充值
|
|
<el-input-number v-model="pay_amount"></el-input-number>元
|
|
<template #footer>
|
|
<div class="dialog-footer">
|
|
<el-button @click="payClosed"> 取 消 </el-button>
|
|
<el-button type="primary" :loading="payLoading" @click="payConfirm"> 确 定 </el-button>
|
|
</div>
|
|
</template>
|
|
</el-dialog>
|
|
<el-dialog
|
|
align-center
|
|
title="赠送套餐"
|
|
width="500"
|
|
v-model="isShowOrderDialog"
|
|
@closed="orderClosed"
|
|
:close-on-click-modal="false"
|
|
>
|
|
是否给【{{ currentRow.username }}】进行赠送
|
|
<el-select v-model="order_id">
|
|
<el-option v-for="item in planList" :value="item.id" :label="item.name"></el-option>
|
|
</el-select>
|
|
<template #footer>
|
|
<div class="dialog-footer">
|
|
<el-button @click="orderClosed"> 取 消 </el-button>
|
|
<el-button type="primary" :loading="orderLoading" @click="orderConfirm">
|
|
确 定
|
|
</el-button>
|
|
</div>
|
|
</template>
|
|
</el-dialog>
|
|
<el-dialog
|
|
align-center
|
|
:title="currentType === 'authorize' ? '分配厂商' : '撤销厂商'"
|
|
width="500"
|
|
v-model="isShowVendorDialog"
|
|
@closed="vendorClosed"
|
|
:close-on-click-modal="false"
|
|
>
|
|
<el-checkbox-group v-model="vendorSelected">
|
|
<el-checkbox v-for="item in vendorListFilter" :label="item.name" :value="item.id" />
|
|
</el-checkbox-group>
|
|
<template #footer>
|
|
<div class="dialog-footer">
|
|
<el-button @click="vendorClosed"> 取 消 </el-button>
|
|
<el-button type="primary" :loading="vendorLoading" @click="vendorConfirm">
|
|
确 定
|
|
</el-button>
|
|
</div>
|
|
</template>
|
|
</el-dialog>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { useTableRPC } from '@/utils/hook'
|
|
import dayjs from 'dayjs'
|
|
import RPC from '@/utils/rpc'
|
|
import HandleDialog from './HandleDialog.vue'
|
|
import RoleDialog from './RoleDialog.vue'
|
|
import { useUserStore } from '@/stores/user'
|
|
|
|
const rowType = ref('')
|
|
const currentRow = ref(null)
|
|
const add = () => {
|
|
isShowDialog.value = true
|
|
currentRow.value = null
|
|
rowType.value = 'add'
|
|
}
|
|
const edit = (row) => {
|
|
isShowDialog.value = true
|
|
rowType.value = 'edit'
|
|
currentRow.value = row
|
|
}
|
|
const editRole = (row) => {
|
|
isShowRoleDialog.value = true
|
|
currentRow.value = row
|
|
}
|
|
|
|
const isShowRoleDialog = ref(false)
|
|
const roleList = ref([])
|
|
RPC.post('/role/list', { page: 1, limit: -1 }).then((res) => {
|
|
roleList.value = res.rows || []
|
|
})
|
|
|
|
const pay_amount = ref(0)
|
|
const isShowPayDialog = ref(false)
|
|
const payLoading = ref(false)
|
|
const payClosed = () => {
|
|
isShowPayDialog.value = false
|
|
currentRow.value = {}
|
|
}
|
|
const pay = (row) => {
|
|
currentRow.value = row
|
|
isShowPayDialog.value = true
|
|
pay_amount.value = 0
|
|
}
|
|
|
|
const payConfirm = () => {
|
|
if (!pay_amount.value) {
|
|
ElMessage.warning('请填写充值金额')
|
|
return
|
|
}
|
|
payLoading.value = true
|
|
RPC.post('/wallet/admin/recharge_and_pay', {
|
|
user_id: currentRow.value.id,
|
|
amount_cents: pay_amount.value * 100,
|
|
pay_channel: 'admin',
|
|
remark: '手动充值',
|
|
})
|
|
.then(() => {
|
|
isShowPayDialog.value = false
|
|
ElMessage.success('充值成功')
|
|
getList()
|
|
})
|
|
.finally(() => {
|
|
payLoading.value = false
|
|
})
|
|
}
|
|
|
|
const planList = ref([])
|
|
RPC.post('/membership_plan/list', { page: 0, limit: -1, orderby: [{ sort: 'asc' }] }).then(
|
|
(res) => {
|
|
planList.value = res.rows || []
|
|
},
|
|
)
|
|
|
|
const order_id = ref(0)
|
|
const isShowOrderDialog = ref(false)
|
|
const orderLoading = ref(false)
|
|
const orderClosed = () => {
|
|
isShowOrderDialog.value = false
|
|
currentRow.value = {}
|
|
order_id.value = null
|
|
}
|
|
const order = (row) => {
|
|
currentRow.value = row
|
|
isShowOrderDialog.value = true
|
|
order_id.value = null
|
|
}
|
|
|
|
const orderConfirm = () => {
|
|
if (!order_id) {
|
|
ElMessage.warning('请选择赠送套餐')
|
|
return
|
|
}
|
|
orderLoading.value = true
|
|
RPC.post('/membership/admin/order/create_and_pay', {
|
|
user_id: currentRow.value.id,
|
|
plan_id: order_id.value,
|
|
pay_channel: 'admin',
|
|
remark: '管理员手动完成',
|
|
})
|
|
.then(() => {
|
|
isShowOrderDialog.value = false
|
|
ElMessage.success('赠送成功')
|
|
getList()
|
|
})
|
|
.finally(() => {
|
|
orderLoading.value = false
|
|
})
|
|
}
|
|
|
|
const isShowVendorDialog = ref(false)
|
|
const vendorLoading = ref(false)
|
|
const vendorClosed = () => {
|
|
isShowVendorDialog.value = false
|
|
currentRow.value = {}
|
|
vendorSelected.value = []
|
|
}
|
|
const currentType = ref('')
|
|
const vendor = (row, type) => {
|
|
if (type === 'authorize') {
|
|
vendorListFilter.value = vendorList.value
|
|
vendorSelected.value = row.vendors.map((item) => item.vendor_id)
|
|
}
|
|
if (type === 'revoke') {
|
|
vendorListFilter.value = row.vendors.map((item) => {
|
|
return {
|
|
id: item.vendor_id,
|
|
...item,
|
|
}
|
|
})
|
|
}
|
|
currentType.value = type
|
|
currentRow.value = row
|
|
isShowVendorDialog.value = true
|
|
}
|
|
|
|
const vendorConfirm = () => {
|
|
if (vendorSelected?.value.length <= 0) {
|
|
ElMessage.warning('请选择厂商')
|
|
return
|
|
}
|
|
vendorLoading.value = true
|
|
RPC.post(`/vendor_user_${currentType.value}`, {
|
|
user_id: currentRow.value.id,
|
|
vendor_ids: vendorSelected.value,
|
|
})
|
|
.then(() => {
|
|
isShowVendorDialog.value = false
|
|
ElMessage.success('操作成功')
|
|
getList()
|
|
})
|
|
.finally(() => {
|
|
vendorLoading.value = false
|
|
})
|
|
}
|
|
|
|
const vendorList = ref([])
|
|
const vendorListFilter = ref([])
|
|
const vendorSelected = ref([])
|
|
RPC.post('/vendor/list', { page: 1, limit: -1 }).then((res) => {
|
|
vendorList.value = res.rows || []
|
|
})
|
|
|
|
const {
|
|
loading,
|
|
tableData,
|
|
tableRef,
|
|
searchFormRef,
|
|
total,
|
|
queryParams,
|
|
getList,
|
|
handleQuery,
|
|
resetQuery,
|
|
handleDelete,
|
|
isShowDialog,
|
|
maxHeight,
|
|
tableContainerEl,
|
|
} = useTableRPC({
|
|
queryParams: {},
|
|
remoteDataFn: '/user/list',
|
|
deleteConfig: {
|
|
remote: '/user/delete',
|
|
key: 'id',
|
|
message(row) {
|
|
return `确认删除 “${row.username}”`
|
|
},
|
|
},
|
|
})
|
|
|
|
getList()
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.title {
|
|
font-size: 20px;
|
|
font-weight: 700;
|
|
margin-bottom: 20px;
|
|
}
|
|
</style>
|