feat:后台页面

This commit is contained in:
dzc committed 2025-11-24 15:03:28 +08:00
1 parent 699d92a217
commit 55918f7d1a
12 files changed
+752 -175

No files matched your search

+5
View File
@@ -25,6 +25,10 @@ export default defineComponent({
gutter: {
type: String as PropType<string>,
default: '5px'
},
size: {
type: String as PropType<string>,
default: 'small'
}
},
setup(props) {
@@ -71,6 +75,7 @@ export default defineComponent({
return (
// 添加标签的文字颜色为白色,解决自定义背景颜色时标签文字看不清的问题
<ElTag
size={props.size}
style={dict?.cssClass ? 'color: #fff' : ''}
type={dict?.colorType || null}
color={dict?.cssClass && isHexColor(dict?.cssClass) ? dict?.cssClass : ''}
+10
View File
@@ -444,6 +444,16 @@ const remainingRouter: AppRouteRecordRaw[] = [
hidden: true
},
component: () => import('@/views/member/user/detail/index.vue')
},
{
path: 'recent/detail/:id',
name: 'MemberRecentDetail',
meta: {
title: '朋友圈详情',
noCache: true,
hidden: true
},
component: () => import('@/views/member/recent/router/recent.detail.vue')
}
]
},
+17 -11
View File
@@ -2,8 +2,8 @@
<ContentWrap>
<!-- 搜索工作栏 -->
<el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px">
<el-form-item label="用户名" prop="memberId">
<el-input v-model="queryParams.memberId" placeholder="请输入用户编号" clearable @keyup.enter="handleQuery"
<el-form-item label="用户名" prop="memberName">
<el-input v-model="queryParams.memberName" placeholder="请输入用户编号" clearable @keyup.enter="handleQuery"
class="!w-240px" />
</el-form-item>
<el-form-item label="反馈内容" prop="content">
@@ -22,10 +22,11 @@
<el-button @click="resetQuery">
<Icon icon="ep:refresh" class="mr-5px" /> 重置
</el-button>
<el-button type="primary" plain @click="openForm('create')" v-hasPermi="['member:feedback:create']">
<el-button type="primary" v-if="false" plain @click="openForm('create')"
v-hasPermi="['member:feedback:create']">
<Icon icon="ep:plus" class="mr-5px" /> 新增
</el-button>
<el-button type="success" plain @click="handleExport" :loading="exportLoading"
<el-button type="success" v-if="false" plain @click="handleExport" :loading="exportLoading"
v-hasPermi="['member:feedback:export']">
<Icon icon="ep:download" class="mr-5px" /> 导出
</el-button>
@@ -36,18 +37,21 @@
<!-- 列表 -->
<ContentWrap>
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
<el-table-column label="用户反馈id" align="center" prop="id" />
<el-table-column label="用户编号" align="center" prop="memberId" />
<el-table-column label="反馈内容" align="center" prop="content" />
<el-table-column label="反馈图片" align="center" prop="pic" />
<el-table-column label="用户编号" align="center" prop="memberName" />
<el-table-column label="反馈内容" align="center" width="500" prop="content" />
<el-table-column label="反馈图片" align="center" prop="pic">
<template #default="{ row }">
<PreviewImage :src="row.pic" />
</template>
</el-table-column>
<el-table-column label="创建时间" align="center" prop="createTime" :formatter="dateFormatter" width="180px" />
<el-table-column label="操作" align="center" min-width="120px">
<template #default="scope">
<el-button link type="primary" @click="openForm('update', scope.row.id)"
<template #default="{ row }">
<el-button v-if="false" link type="primary" @click="openForm('update', row.id)"
v-hasPermi="['member:feedback:update']">
编辑
</el-button>
<el-button link type="danger" @click="handleDelete(scope.row.id)" v-hasPermi="['member:feedback:delete']">
<el-button link type="danger" @click="handleDelete(row.id)" v-hasPermi="['member:feedback:delete']">
删除
</el-button>
</template>
@@ -67,6 +71,7 @@ import { dateFormatter } from '@/utils/formatTime'
import download from '@/utils/download'
import { FeedbackApi, FeedbackVO } from '@/api/member/feedback'
import FeedbackForm from './FeedbackForm.vue'
import { template } from 'lodash-es'
/** 用户反馈 列表 */
defineOptions({ name: 'Feedback' })
@@ -78,6 +83,7 @@ const loading = ref(true) // 列表的加载中
const list = ref<FeedbackVO[]>([]) // 列表的数据
const total = ref(0) // 列表的总页数
const queryParams = reactive({
memberName: '',
pageNo: 1,
pageSize: 10,
memberId: undefined,
+1 -7
View File
@@ -1,12 +1,6 @@
<template>
<Dialog :title="dialogTitle" v-model="dialogVisible">
<el-form
ref="formRef"
:model="formData"
:rules="formRules"
label-width="100px"
v-loading="formLoading"
>
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="100px" v-loading="formLoading">
<el-form-item label="用户编号" prop="memberId">
<el-input v-model="formData.memberId" placeholder="请输入用户编号" />
</el-form-item>
+87
View File
@@ -0,0 +1,87 @@
<!-- 点赞记录 -->
<template>
<ContentWrap>
<el-form ref="queryFormRef" :inline="true" :model="queryParams" class="-mb-15px" label-width="68px">
<el-form-item>
<el-button @click="handleQuery">
<Icon class="mr-5px" icon="ep:search" />
搜索
</el-button>
<el-button @click="resetQuery">
<Icon class="mr-5px" icon="ep:refresh" />
重置
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<ContentWrap class="min-h-[500px]">
<el-table v-loading="loading" :data="list" row-key="id">
<el-table-column label="操作人" align="center" prop="operatorMemberNickname" width="200px" />
<el-table-column label="描述" align="center">
<template #default="{ row }">
<div>
<span class="color-blue">{{ row.operatorMemberNickname }}</span>
<span>在</span>
<span class="color-red">{{ formatPast(row.createTime) }}</span>
<span>点赞了</span>
<span class="color-blue">{{ row.memberNickname }}</span>
<span>的动态</span>
</div>
</template>
</el-table-column>
<el-table-column label="操作时间" align="center" prop="createTime" :formatter="dateFormatter" width="180px" />
</el-table>
</ContentWrap>
<Pagination v-model:limit="queryParams.pageSize" v-model:page="queryParams.pageNo" :total="total"
@pagination="getList" />
</template>
<script lang="ts" setup>
import { FormInstance } from 'element-plus'
import { dateFormatter, formatPast } from '@/utils/formatTime'
import * as operationApi from "@/api/member/operation"
const queryFormRef = ref<FormInstance>()
const total = ref(0)
const loading = ref(true)
const list = ref([])
// 表单搜索
const queryParams = ref({
bizType: "1",
pageNo: 1,
pageSize: 10,
})
/** 搜索按钮操作 */
const handleQuery = async () => {
queryParams.value.pageNo = 1
await getList()
}
/** 重置按钮操作 */
const resetQuery = () => {
queryFormRef.value?.resetFields()
handleQuery()
}
/** 查询列表 */
const getList = async () => {
loading.value = true
try {
const data = await operationApi.OperationApi.getOperationPage(queryParams.value)
list.value = data.list
total.value = data.total
} finally {
loading.value = false
}
}
onMounted(() => {
getList()
})
</script>
+112
View File
@@ -0,0 +1,112 @@
<template>
<el-card shadow="never" class="w-full h-full m-0!">
<template #header>
<slot name="header"></slot>
</template>
<el-row>
<el-col :span="3">
<PreviewImage :src="recent.coverPic" />
</el-col>
<el-col :span="21">
<el-descriptions :column="2">
<el-descriptions-item>
<template #label>
<descriptions-item-label icon="ep:document" label="内容" />
</template>
<span class="user-cell">{{ recent.describe || '未知' }}</span>
</el-descriptions-item>
<el-descriptions-item>
<template #label>
<descriptions-item-label icon="ep:location" label="发布地址" />
</template>
<div class="recent-cell">
<div>省市区:</div>
<div>
<span>{{ recent.issueProvince || '未知' }}</span>-
<span>{{ recent.issueCity || '未知' }}</span>-
<span>{{ recent.issueDistrict || '未知' }}</span>
</div>
</div>
<div class="recent-cell">
<div>详细地址:</div>
<div>
<span>{{ recent.issueAddress || '未知' }}</span>
</div>
</div>
</el-descriptions-item>
</el-descriptions>
</el-col>
</el-row>
</el-card>
</template>
<script lang="ts" setup>
type Props = {
recent: any;
}
const props = withDefaults(defineProps<Props>(), {
recent: {}
})
</script>
<style lang="scss" scoped>
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
}
.recent-cell {
display: flex;
justify-content: flex-start;
align-items: center;
div {
display: inline-block;
text-align: left;
font-size: 13px;
}
div:first-child {
width: 70px;
}
div:last-child {
flex: 1;
color: lightblue;
}
}
::v-deep(.el-descriptions__table) {
tbody {
.el-descriptions__cell {
display: flex;
.el-descriptions__label {
width: 120px;
margin-right: 10px !important;
display: block;
text-align: left;
.cell-item {
font-size: 13px !important;
display: flex;
align-items: center;
i {
margin-right: 4px;
}
}
}
.el-descriptions__content {
flex: 1;
text-align: start;
}
}
}
}
</style>
@@ -0,0 +1,89 @@
<!-- 举报记录 -->
<template>
<ContentWrap>
<el-form ref="queryFormRef" :inline="true" :model="queryParams" class="-mb-15px" label-width="68px">
<el-form-item>
<el-button @click="handleQuery">
<Icon class="mr-5px" icon="ep:search" />
搜索
</el-button>
<el-button @click="resetQuery">
<Icon class="mr-5px" icon="ep:refresh" />
重置
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<ContentWrap class="min-h-[500px]">
<el-table v-loading="loading" :data="list" row-key="id">
<el-table-column label="操作人" align="center" prop="operatorMemberNickname" width="200px" />
<el-table-column label="描述" align="center">
<template #default="{ row }">
<div>
<span class="color-blue">{{ row.operatorMemberNickname }}</span>
<span>在</span>
<span class="color-red">{{ formatPast(row.createTime) }}</span>
<span>以</span>
<span class="color-red">低俗</span>
<span>理由,举报了</span>
<span class="color-blue">{{ row.memberNickname }}</span>
<span>的动态</span>
</div>
</template>
</el-table-column>
<el-table-column label="操作时间" align="center" prop="createTime" :formatter="dateFormatter" width="180px" />
</el-table>
</ContentWrap>
<Pagination v-model:limit="queryParams.pageSize" v-model:page="queryParams.pageNo" :total="total"
@pagination="getList" />
</template>
<script lang="ts" setup>
import { FormInstance } from 'element-plus'
import { dateFormatter, formatPast } from '@/utils/formatTime'
import * as operationApi from "@/api/member/operation"
const queryFormRef = ref<FormInstance>()
const total = ref(0)
const loading = ref(true)
const list = ref([])
// 表单搜索
const queryParams = ref({
bizType: "2",
pageNo: 1,
pageSize: 10,
})
/** 搜索按钮操作 */
const handleQuery = async () => {
queryParams.value.pageNo = 1
await getList()
}
/** 重置按钮操作 */
const resetQuery = () => {
queryFormRef.value?.resetFields()
handleQuery()
}
/** 查询列表 */
const getList = async () => {
loading.value = true
try {
const data = await operationApi.OperationApi.getOperationPage(queryParams.value)
list.value = data.list
total.value = data.total
} finally {
loading.value = false
}
}
onMounted(() => {
getList()
})
</script>
@@ -0,0 +1,87 @@
<!-- 黑名单 -->
<template>
<ContentWrap>
<el-form ref="queryFormRef" :inline="true" :model="queryParams" class="-mb-15px" label-width="68px">
<el-form-item>
<el-button @click="handleQuery">
<Icon class="mr-5px" icon="ep:search" />
搜索
</el-button>
<el-button @click="resetQuery">
<Icon class="mr-5px" icon="ep:refresh" />
重置
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<ContentWrap class="min-h-[500px]">
<el-table v-loading="loading" :data="list" row-key="id">
<el-table-column label="操作人" align="center" prop="operatorMemberNickname" width="200px" />
<el-table-column label="描述" align="center">
<template #default="{ row }">
<div>
<span class="color-blue">{{ row.operatorMemberNickname }}</span>
<span>在</span>
<span class="color-red">{{ formatPast(row.createTime) }}</span>
<span>拉黑了</span>
<span class="color-blue">{{ row.memberNickname }}</span>
<span>的动态</span>
</div>
</template>
</el-table-column>
<el-table-column label="操作时间" align="center" prop="createTime" :formatter="dateFormatter" width="180px" />
</el-table>
</ContentWrap>
<Pagination v-model:limit="queryParams.pageSize" v-model:page="queryParams.pageNo" :total="total"
@pagination="getList" />
</template>
<script lang="ts" setup>
import { FormInstance } from 'element-plus'
import { dateFormatter, formatPast } from '@/utils/formatTime'
import * as operationApi from "@/api/member/operation"
const queryFormRef = ref<FormInstance>()
const total = ref(0)
const loading = ref(true)
const list = ref([])
// 表单搜索
const queryParams = ref({
bizType: "3",
pageNo: 1,
pageSize: 10,
})
/** 搜索按钮操作 */
const handleQuery = async () => {
queryParams.value.pageNo = 1
await getList()
}
/** 重置按钮操作 */
const resetQuery = () => {
queryFormRef.value?.resetFields()
handleQuery()
}
/** 查询列表 */
const getList = async () => {
loading.value = true
try {
const data = await operationApi.OperationApi.getOperationPage(queryParams.value)
list.value = data.list
total.value = data.total
} finally {
loading.value = false
}
}
onMounted(() => {
getList()
})
</script>
+142 -16
View File
@@ -22,10 +22,10 @@
<el-button @click="resetQuery">
<Icon icon="ep:refresh" class="mr-5px" /> 重置
</el-button>
<el-button type="primary" plain @click="openForm('create')" v-hasPermi="['member:recent:create']">
<el-button v-if="false" type="primary" plain @click="openForm('create')" v-hasPermi="['member:recent:create']">
<Icon icon="ep:plus" class="mr-5px" /> 新增
</el-button>
<el-button type="success" plain @click="handleExport" :loading="exportLoading"
<el-button v-if="false" type="success" plain @click="handleExport" :loading="exportLoading"
v-hasPermi="['member:recent:export']">
<Icon icon="ep:download" class="mr-5px" /> 导出
</el-button>
@@ -36,24 +36,99 @@
<!-- 列表 -->
<ContentWrap>
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
<el-table-column label="收件地址编号" align="center" prop="id" />
<el-table-column label="用户编号" align="center" prop="memberId" />
<el-table-column label="主图" align="center" prop="coverPic" />
<el-table-column label="用户" align="center" width="250" prop="memberId">
<template #default="{ row }">
<div class="flex items-center gap-2">
<PreviewImage :src="row.member.memberAvatar" />
<div class="flex flex-col items-start">
<div class="flex items-center gap-1">
<div class="table-cell">
<span>昵称:</span>
<span>{{ row.member.memberNickname }}</span>
</div>
<div class="table-cell">
<span>年龄:</span>
<span>{{ row.member.memberAge || '未知' }}岁</span>
</div>
</div>
<div class="flex items-center gap-1">
<div class="table-cell">
<span>性别:</span>
<dict-tag size="" :type="DICT_TYPE.SYSTEM_USER_SEX" :value="row.member.memberSex" />
</div>
<div class="table-cell">
<span>职业:</span>
<span>{{ row.member.memberOcc || '未知' }}米</span>
</div>
</div>
<div class="flex items-center gap-1">
<div class="table-cell">
<span>身高:</span>
<span>{{ row.member.memberHeight || '未知' }}米</span>
</div>
<div class="table-cell">
<span>体重:</span>
<span>{{ row.member.memberWeight || '未知' }}kg</span>
</div>
</div>
</div>
</div>
</template>
</el-table-column>
<el-table-column label="发布地址" align="center" width="300">
<template #default="{ row }">
<div class="flex flex-col items-start">
<div class="font-size-[12px]">
<span>{{ row.issueProvince }}-</span>
<span>{{ row.issueCity }}-</span>
<span>{{ row.issueDistrict }}</span>
</div>
<div class="table-cell">
<span class="w-[55px]!">详细地址:</span>
<span>{{ row.issueAddress }}</span>
</div>
</div>
</template>
</el-table-column>
<el-table-column label="图片" align="center" prop="coverPic">
<template #default="{ row }">
<PreviewImage :src="row.coverPic" />
</template>
</el-table-column>
<el-table-column label="描述" align="center" prop="describe" />
<el-table-column label="发布-经度" align="center" prop="issueLong" />
<el-table-column label="发布-纬度" align="center" prop="issueLat" />
<el-table-column label="发布-省" align="center" prop="issueProvince" />
<el-table-column label="发布-市" align="center" prop="issueCity" />
<el-table-column label="发布-区" align="center" prop="issueDistrict" />
<el-table-column label="发布-详细地址" align="center" prop="issueAddress" />
<el-table-column label="统计" align="center" width="200">
<template #default="{ row }">
<div class="flex flex-col items-start">
<div class="flex items-center gap-2">
<div class="total-cell">
<span>点赞数量:</span>
<span>{{ row.operationTotal?.recentLikeTotal ?? 0 }}</span>
</div>
<div class="total-cell">
<span>举报数量:</span>
<span>{{ row.operationTotal?.recentReportTotal ?? 0 }}</span>
</div>
</div>
<div class="flex items-center gap-2">
<div class="total-cell">
<span>黑名单数量:</span>
<span>{{ row.operationTotal?.recentShieldTotal ?? 0 }}</span>
</div>
</div>
</div>
</template>
</el-table-column>
<el-table-column label="创建时间" align="center" prop="createTime" :formatter="dateFormatter" width="180px" />
<el-table-column label="操作" align="center" min-width="120px">
<template #default="scope">
<el-button link type="primary" @click="openForm('update', scope.row.id)"
<el-table-column label="操作" align="center" min-width="80px">
<template #default="{ row }">
<el-button link type="primary" @click="openDetail(row.id)">
详情
</el-button>
<el-button v-if="false" link type="primary" @click="openForm('update', row.id)"
v-hasPermi="['member:recent:update']">
编辑
</el-button>
<el-button link type="danger" @click="handleDelete(scope.row.id)" v-hasPermi="['member:recent:delete']">
<el-button link type="danger" @click="handleDelete(row.id)" v-hasPermi="['member:recent:delete']">
删除
</el-button>
</template>
@@ -69,6 +144,7 @@
</template>
<script setup lang="ts">
import { DICT_TYPE } from '@/utils/dict'
import { dateFormatter } from '@/utils/formatTime'
import download from '@/utils/download'
import { RecentApi, RecentVO } from '@/api/member/recent'
@@ -99,6 +175,12 @@ const queryParams = reactive({
const queryFormRef = ref() // 搜索的表单
const exportLoading = ref(false) // 导出的加载中
/** 打开会员详情 */
const { push } = useRouter()
const openDetail = (id: number) => {
push({ name: 'MemberRecentDetail', params: { id } })
}
/** 查询列表 */
const getList = async () => {
loading.value = true
@@ -161,4 +243,48 @@ const handleExport = async () => {
onMounted(() => {
getList()
})
</script>
</script>
<style lang="scss" scoped>
.table-cell {
display: flex;
justify-content: flex-start;
align-items: center;
span {
display: inline-block;
text-align: left;
font-size: 12px;
}
span:first-child {
width: 30px;
}
span:last-child {
flex: 1;
color: lightblue;
}
}
.total-cell {
display: flex;
justify-content: flex-start;
align-items: center;
span {
display: inline-block;
text-align: left;
font-size: 12px;
}
span:first-child {
width: 80px;
}
span:last-child {
flex: 1;
color: lightblue;
}
}
</style>
@@ -0,0 +1,129 @@
<template>
<ContentWrap>
<el-row :gutter="10">
<el-col :span="12">
<UserBasicInfo :user="user">
<template #header>
<div class="card-header">
<CardTitle title="基本信息" />
<el-button size="small" text type="primary" @click="openForm('update')">
编辑
</el-button>
</div>
</template>
</UserBasicInfo>
</el-col>
<el-col :span="12">
<RecentCard :recent="recent">
<template #header>
<div class="card-header">
<CardTitle title="朋友圈信息" />
</div>
</template>
</RecentCard>
</el-col>
</el-row>
<el-card shadow="never" style="width: 100%; margin-top: 20px">
<template #header>
<CardTitle title="朋友圈操作记录" />
</template>
<el-tabs>
<el-tab-pane label="点赞记录">
<LikePage />
</el-tab-pane>
<el-tab-pane label="举报记录">
<ReportPage />
</el-tab-pane>
<el-tab-pane label="黑名单记录">
<ShieldPage />
</el-tab-pane>
<el-tab-pane label="查看微信记录" />
<el-tab-pane label="访问记录" />
</el-tabs>
</el-card>
<!-- 表单弹窗:添加/修改 -->
<UserForm ref="formRef" @success="getUserData()" />
</ContentWrap>
</template>
<script setup lang="ts">
import UserBasicInfo from '@/views/member/user/detail/UserBasicInfo.vue'
import UserForm from '@/views/member/user/UserForm.vue'
import RecentCard from '@/views/member/recent/cmp/recent-card.vue'
import LikePage from "@/views/member/recent/cmp/like-page.vue"
import ReportPage from "@/views/member/recent/cmp/report-page.vue"
import ShieldPage from "@/views/member/recent/cmp/shield-page.vue"
import { useTagsViewStore } from '@/store/modules/tagsView'
import * as UserApi from '@/api/member/user'
import * as RecentApi from '@/api/member/recent'
const route = useRoute()
const { currentRoute } = useRouter()
const { delView } = useTagsViewStore()
const user = ref<any>({})
const recent = ref<any>({})
const loading = ref(true)
/** 获得朋友圈详情 */
const getRecentData = async (id: any) => {
try {
recent.value = await RecentApi.RecentApi.getRecent(id)
} catch (error) {
console.error("|获得朋友圈详情|,意外的错误", error)
}
}
/** 获得用户详情 */
const getUserData = async () => {
if (!recent.value.memberId) return
try {
user.value = await UserApi.getUser(recent.value.memberId)
} catch (error) {
console.error("|获得用户详情|,意外的错误", error)
}
}
/** 添加/修改用户 */
const formRef = ref()
const openForm = (type: string) => {
formRef.value.open(type, recent.value.memberId)
}
onMounted(async () => {
const id = route.params.id
if (!id) {
ElMessage.warning('参数错误,朋友圈编号不能为空!')
delView(unref(currentRoute))
return
}
try {
loading.value = true
await getRecentData(id)
if (recent.value && recent.value.memberId) {
await getUserData()
}
} finally {
loading.value = false
}
})
</script>
<style lang="scss" scoped>
.detail-info-item:first-child {
padding-left: 0 !important;
}
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
}
::v-deep(.el-card__header) {
padding: 8px 20px !important;
}
</style>
+42 -22
View File
@@ -4,16 +4,16 @@
<slot name="header"></slot>
</template>
<el-row v-if="mode === 'member'">
<el-col :span="4">
<ElAvatar :size="140" :src="user.avatar || undefined" shape="square" />
<el-col :span="3">
<PreviewImage :src="user.avatar" />
</el-col>
<el-col :span="20">
<el-col :span="21">
<el-descriptions :column="2">
<el-descriptions-item>
<template #label>
<descriptions-item-label icon="ep:user" label="用户名" />
</template>
{{ user.name || '空' }}
<span class="user-cell">{{ user.name || '未知' }}</span>
</el-descriptions-item>
<el-descriptions-item>
<template #label>
@@ -37,31 +37,31 @@
<template #label>
<descriptions-item-label icon="ep:location" label="所在地" />
</template>
{{ user.areaName }}
{{ user.areaName || "未知" }}
</el-descriptions-item>
<el-descriptions-item>
<template #label>
<descriptions-item-label icon="ep:position" label="注册 IP" />
</template>
{{ user.registerIp }}
{{ user.registerIp || "未知" }}
</el-descriptions-item>
<el-descriptions-item>
<template #label>
<descriptions-item-label icon="fa:birthday-cake" label="生日" />
</template>
{{ user.birthday ? formatDate(user.birthday as any) : '空' }}
{{ user.birthday ? formatDate(user.birthday as any) : "未知" }}
</el-descriptions-item>
<el-descriptions-item>
<template #label>
<descriptions-item-label icon="ep:calendar" label="注册时间" />
</template>
{{ user.createTime ? formatDate(user.createTime as any) : '空' }}
{{ user.createTime ? formatDate(user.createTime as any) : "未知" }}
</el-descriptions-item>
<el-descriptions-item>
<template #label>
<descriptions-item-label icon="ep:calendar" label="最后登录时间" />
</template>
{{ user.loginDate ? formatDate(user.loginDate as any) : '空' }}
{{ user.loginDate ? formatDate(user.loginDate as any) : "未知" }}
</el-descriptions-item>
</el-descriptions>
</el-col>
@@ -127,6 +127,7 @@
</template>
</el-card>
</template>
<script lang="ts" setup>
import { DICT_TYPE } from '@/utils/dict'
import { formatDate } from '@/utils/formatTime'
@@ -138,27 +139,46 @@ withDefaults(defineProps<{ user: UserApi.UserVO; mode?: string }>(), {
})
</script>
<style lang="scss" scoped>
.user-cell {
font-size: 13px;
}
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
}
::v-deep(.kefu-descriptions) {
.el-descriptions__cell {
display: flex;
align-items: center;
justify-content: space-between;
::v-deep(.el-descriptions__table) {
tbody {
display: grid;
grid-template-columns: repeat(2, 1fr);
column-gap: 40px;
.el-descriptions__label {
width: 120px;
display: block;
text-align: left;
}
.el-descriptions__cell {
display: flex;
.el-descriptions__content {
flex: 1;
text-align: end;
.el-descriptions__label {
width: 120px;
margin-right: 10px !important;
display: block;
text-align: left;
.cell-item {
font-size: 13px !important;
display: flex;
align-items: center;
i {
margin-right: 4px;
}
}
}
.el-descriptions__content {
flex: 1;
text-align: start;
}
}
}
}
+31 -119
View File
@@ -1,148 +1,64 @@
<template>
<!-- 搜索 -->
<ContentWrap>
<el-form
ref="queryFormRef"
:inline="true"
:model="queryParams"
class="-mb-15px"
label-width="68px"
>
<el-form ref="queryFormRef" :inline="true" :model="queryParams" class="-mb-15px" label-width="68px">
<el-form-item label="订单状态" prop="status">
<el-select v-model="queryParams.status" class="!w-280px" clearable placeholder="全部">
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.TRADE_ORDER_STATUS)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
<el-option v-for="dict in getIntDictOptions(DICT_TYPE.TRADE_ORDER_STATUS)" :key="dict.value"
:label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
<el-form-item label="支付方式" prop="payChannelCode">
<el-select
v-model="queryParams.payChannelCode"
class="!w-280px"
clearable
placeholder="全部"
>
<el-option
v-for="dict in getStrDictOptions(DICT_TYPE.PAY_CHANNEL_CODE)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
<el-select v-model="queryParams.payChannelCode" class="!w-280px" clearable placeholder="全部">
<el-option v-for="dict in getStrDictOptions(DICT_TYPE.PAY_CHANNEL_CODE)" :key="dict.value" :label="dict.label"
:value="dict.value" />
</el-select>
</el-form-item>
<el-form-item label="创建时间" prop="createTime">
<el-date-picker
v-model="queryParams.createTime"
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
class="!w-280px"
end-placeholder="自定义时间"
start-placeholder="自定义时间"
type="daterange"
value-format="YYYY-MM-DD HH:mm:ss"
/>
<el-date-picker v-model="queryParams.createTime"
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]" class="!w-280px" end-placeholder="自定义时间"
start-placeholder="自定义时间" type="daterange" value-format="YYYY-MM-DD HH:mm:ss" />
</el-form-item>
<el-form-item label="订单来源" prop="terminal">
<el-select v-model="queryParams.terminal" class="!w-280px" clearable placeholder="全部">
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.TERMINAL)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
<el-option v-for="dict in getIntDictOptions(DICT_TYPE.TERMINAL)" :key="dict.value" :label="dict.label"
:value="dict.value" />
</el-select>
</el-form-item>
<el-form-item label="订单类型" prop="type">
<el-select v-model="queryParams.type" class="!w-280px" clearable placeholder="全部">
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.TRADE_ORDER_TYPE)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
<el-option v-for="dict in getIntDictOptions(DICT_TYPE.TRADE_ORDER_TYPE)" :key="dict.value" :label="dict.label"
:value="dict.value" />
</el-select>
</el-form-item>
<el-form-item label="配送方式" prop="deliveryType">
<el-select v-model="queryParams.deliveryType" class="!w-280px" clearable placeholder="全部">
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.TRADE_DELIVERY_TYPE)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
<el-option v-for="dict in getIntDictOptions(DICT_TYPE.TRADE_DELIVERY_TYPE)" :key="dict.value"
:label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
<el-form-item
v-if="queryParams.deliveryType === DeliveryTypeEnum.EXPRESS.type"
label="快递公司"
prop="logisticsId"
>
<el-form-item v-if="queryParams.deliveryType === DeliveryTypeEnum.EXPRESS.type" label="快递公司" prop="logisticsId">
<el-select v-model="queryParams.logisticsId" class="!w-280px" clearable placeholder="全部">
<el-option
v-for="item in deliveryExpressList"
:key="item.id"
:label="item.name"
:value="item.id"
/>
<el-option v-for="item in deliveryExpressList" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
<el-form-item
v-if="queryParams.deliveryType === DeliveryTypeEnum.PICK_UP.type"
label="自提门店"
prop="pickUpStoreId"
>
<el-select
v-model="queryParams.pickUpStoreId"
class="!w-280px"
clearable
multiple
placeholder="全部"
>
<el-option
v-for="item in pickUpStoreList"
:key="item.id"
:label="item.name"
:value="item.id"
/>
<el-form-item v-if="queryParams.deliveryType === DeliveryTypeEnum.PICK_UP.type" label="自提门店" prop="pickUpStoreId">
<el-select v-model="queryParams.pickUpStoreId" class="!w-280px" clearable multiple placeholder="全部">
<el-option v-for="item in pickUpStoreList" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
<el-form-item
v-if="queryParams.deliveryType === DeliveryTypeEnum.PICK_UP.type"
label="核销码"
prop="pickUpVerifyCode"
>
<el-input
v-model="queryParams.pickUpVerifyCode"
class="!w-280px"
clearable
placeholder="请输入自提核销码"
@keyup.enter="handleQuery"
/>
<el-form-item v-if="queryParams.deliveryType === DeliveryTypeEnum.PICK_UP.type" label="核销码"
prop="pickUpVerifyCode">
<el-input v-model="queryParams.pickUpVerifyCode" class="!w-280px" clearable placeholder="请输入自提核销码"
@keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="聚合搜索">
<el-input
v-show="true"
v-model="queryParams[queryType.queryParam]"
class="!w-280px"
clearable
placeholder="请输入"
>
<el-input v-show="true" v-model="queryParams[queryType.queryParam]" class="!w-280px" clearable
placeholder="请输入">
<template #prepend>
<el-select
v-model="queryType.queryParam"
class="!w-110px"
clearable
placeholder="全部"
@change="inputChangeSelect"
>
<el-option
v-for="dict in dynamicSearchList"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
<el-select v-model="queryType.queryParam" class="!w-110px" clearable placeholder="全部"
@change="inputChangeSelect">
<el-option v-for="dict in dynamicSearchList" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</template>
</el-input>
@@ -174,12 +90,8 @@
</OrderTableColumn>
</el-table>
<!-- 分页 -->
<Pagination
v-model:limit="queryParams.pageSize"
v-model:page="queryParams.pageNo"
:total="total"
@pagination="getList"
/>
<Pagination v-model:limit="queryParams.pageSize" v-model:page="queryParams.pageNo" :total="total"
@pagination="getList" />
</ContentWrap>
</template>
<script lang="ts" setup>