feat: use project standard search bar pattern for asset pages, add title/phone/date filters
This commit is contained in:
@@ -1,19 +1,39 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="asset-resource-container">
|
<div class="asset-resource-container">
|
||||||
<el-card shadow="never" class="!border-none">
|
<!-- 搜索区域 -->
|
||||||
<div class="mb-4 flex items-center gap-4 flex-wrap">
|
<el-card class="!border-none" shadow="never">
|
||||||
<el-button type="primary" @click="handleAdd">上传并分发资源</el-button>
|
<el-form class="ls-form" :model="searchData" inline>
|
||||||
<el-date-picker
|
<el-form-item class="w-[280px]" label="标题">
|
||||||
v-model="dateRange"
|
<el-input
|
||||||
type="daterange"
|
placeholder="请输入标题关键词"
|
||||||
range-separator="至"
|
v-model="searchData.title"
|
||||||
start-placeholder="开始日期"
|
clearable
|
||||||
end-placeholder="结束日期"
|
@keyup.enter="handleSearch"
|
||||||
value-format="YYYY-MM-DD"
|
/>
|
||||||
@change="handleDateChange"
|
</el-form-item>
|
||||||
clearable
|
<el-form-item label="上传时间">
|
||||||
style="width: 300px;"
|
<el-date-picker
|
||||||
/>
|
v-model="searchData.dateRange"
|
||||||
|
type="daterange"
|
||||||
|
range-separator="至"
|
||||||
|
start-placeholder="开始日期"
|
||||||
|
end-placeholder="结束日期"
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
clearable
|
||||||
|
style="width: 280px;"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="handleSearch">查询</el-button>
|
||||||
|
<el-button @click="handleReset">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<!-- 列表区域 -->
|
||||||
|
<el-card class="!border-none mt-4" shadow="never">
|
||||||
|
<div class="mb-4">
|
||||||
|
<el-button type="primary" @click="handleAdd">上传资源</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-tabs v-model="queryParams.type" @tab-change="handleTabChange">
|
<el-tabs v-model="queryParams.type" @tab-change="handleTabChange">
|
||||||
@@ -24,14 +44,14 @@
|
|||||||
|
|
||||||
<el-table :data="tableData" v-loading="loading">
|
<el-table :data="tableData" v-loading="loading">
|
||||||
<el-table-column prop="id" label="ID" width="80" />
|
<el-table-column prop="id" label="ID" width="80" />
|
||||||
<el-table-column prop="title" label="标题" />
|
<el-table-column prop="title" label="标题" min-width="150" />
|
||||||
<el-table-column label="预览">
|
<el-table-column label="预览" width="100">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-image v-if="row.type == 1" :src="row.file_url" style="width: 50px; height: 50px;" :preview-src-list="[row.file_url]" preview-teleported />
|
<el-image v-if="row.type == 1" :src="row.file_url" style="width: 50px; height: 50px;" :preview-src-list="[row.file_url]" preview-teleported />
|
||||||
<el-link v-else :href="row.file_url" target="_blank" type="primary">点击预览</el-link>
|
<el-link v-else :href="row.file_url" target="_blank" type="primary">点击预览</el-link>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="关联账号" show-overflow-tooltip>
|
<el-table-column label="关联账号" min-width="150" show-overflow-tooltip>
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-tag v-if="!row.users?.length" type="info" size="small">公开资源</el-tag>
|
<el-tag v-if="!row.users?.length" type="info" size="small">公开资源</el-tag>
|
||||||
<span v-else>{{ row.users?.map((u: any) => u.phone).join(', ') }}</span>
|
<span v-else>{{ row.users?.map((u: any) => u.phone).join(', ') }}</span>
|
||||||
@@ -58,9 +78,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<!-- 新增资源弹窗 -->
|
<!-- 新增/编辑资源弹窗 -->
|
||||||
<el-dialog v-model="dialogVisible" :title="isEdit ? '编辑资源' : '新增分发资源'" width="600px" destroy-on-close>
|
<el-dialog v-model="dialogVisible" :title="isEdit ? '编辑资源' : '新增分发资源'" width="600px" destroy-on-close>
|
||||||
<el-form ref="formRef" :model="formData" :rules="rules" label-width="100px">
|
<el-form ref="formRef" :model="formData" :rules="computedRules" label-width="100px">
|
||||||
<el-form-item label="资源类型" prop="type" v-if="!isEdit">
|
<el-form-item label="资源类型" prop="type" v-if="!isEdit">
|
||||||
<el-radio-group v-model="formData.type">
|
<el-radio-group v-model="formData.type">
|
||||||
<el-radio :label="1">图片</el-radio>
|
<el-radio :label="1">图片</el-radio>
|
||||||
@@ -99,7 +119,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, reactive, onMounted } from 'vue'
|
import { ref, reactive, computed, onMounted } from 'vue'
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
import { apiAssetResourceList, apiAssetResourceAdd, apiAssetResourceEdit, apiAssetResourceDelete, apiAssetUserList } from '@/api/asset'
|
import { apiAssetResourceList, apiAssetResourceAdd, apiAssetResourceEdit, apiAssetResourceDelete, apiAssetUserList } from '@/api/asset'
|
||||||
import MaterialPicker from '@/components/material/picker.vue'
|
import MaterialPicker from '@/components/material/picker.vue'
|
||||||
@@ -108,7 +128,12 @@ import Upload from '@/components/upload/index.vue'
|
|||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const tableData = ref([])
|
const tableData = ref([])
|
||||||
const total = ref(0)
|
const total = ref(0)
|
||||||
const dateRange = ref<string[]>([])
|
|
||||||
|
const searchData = reactive<any>({
|
||||||
|
title: '',
|
||||||
|
dateRange: []
|
||||||
|
})
|
||||||
|
|
||||||
const queryParams = reactive<any>({
|
const queryParams = reactive<any>({
|
||||||
type: '1',
|
type: '1',
|
||||||
page_no: 1,
|
page_no: 1,
|
||||||
@@ -131,15 +156,34 @@ const formData = reactive<any>({
|
|||||||
user_ids: []
|
user_ids: []
|
||||||
})
|
})
|
||||||
|
|
||||||
const rules = {
|
const computedRules = computed(() => {
|
||||||
title: [{ required: true, message: '请输入标题', trigger: 'blur' }],
|
if (isEdit.value) {
|
||||||
file_url: [{ required: true, message: '请输入或上传文件获取链接', trigger: 'blur' }]
|
return {
|
||||||
|
title: [{ required: true, message: '请输入标题', trigger: 'blur' }]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
title: [{ required: true, message: '请输入标题', trigger: 'blur' }],
|
||||||
|
file_url: [{ required: true, message: '请输入或上传文件获取链接', trigger: 'blur' }]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const buildQueryParams = () => {
|
||||||
|
const params: any = { ...queryParams }
|
||||||
|
if (searchData.title) {
|
||||||
|
params.title = searchData.title
|
||||||
|
}
|
||||||
|
if (searchData.dateRange && searchData.dateRange.length === 2) {
|
||||||
|
params.start_time = searchData.dateRange[0]
|
||||||
|
params.end_time = searchData.dateRange[1]
|
||||||
|
}
|
||||||
|
return params
|
||||||
}
|
}
|
||||||
|
|
||||||
const getList = async () => {
|
const getList = async () => {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
try {
|
try {
|
||||||
const res = await apiAssetResourceList(queryParams)
|
const res = await apiAssetResourceList(buildQueryParams())
|
||||||
tableData.value = res.lists
|
tableData.value = res.lists
|
||||||
total.value = res.count
|
total.value = res.count
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -158,19 +202,19 @@ const fetchUserOptions = async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleTabChange = () => {
|
const handleSearch = () => {
|
||||||
queryParams.page_no = 1
|
queryParams.page_no = 1
|
||||||
getList()
|
getList()
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleDateChange = (val: string[] | null) => {
|
const handleReset = () => {
|
||||||
if (val && val.length === 2) {
|
searchData.title = ''
|
||||||
queryParams.start_time = val[0]
|
searchData.dateRange = []
|
||||||
queryParams.end_time = val[1]
|
queryParams.page_no = 1
|
||||||
} else {
|
getList()
|
||||||
delete queryParams.start_time
|
}
|
||||||
delete queryParams.end_time
|
|
||||||
}
|
const handleTabChange = () => {
|
||||||
queryParams.page_no = 1
|
queryParams.page_no = 1
|
||||||
getList()
|
getList()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,27 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="asset-user-container">
|
<div class="asset-user-container">
|
||||||
<el-card shadow="never" class="!border-none">
|
<!-- 搜索区域 -->
|
||||||
|
<el-card class="!border-none" shadow="never">
|
||||||
|
<el-form class="ls-form" :model="searchData" inline>
|
||||||
|
<el-form-item class="w-[280px]" label="手机号">
|
||||||
|
<el-input
|
||||||
|
placeholder="请输入手机号"
|
||||||
|
v-model="searchData.phone"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleSearch"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="handleSearch">查询</el-button>
|
||||||
|
<el-button @click="handleReset">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<!-- 列表区域 -->
|
||||||
|
<el-card class="!border-none mt-4" shadow="never">
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<el-button type="primary" @click="handleAdd">新增分发账号</el-button>
|
<el-button type="primary" @click="handleAdd">新增账号</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-table :data="tableData" v-loading="loading">
|
<el-table :data="tableData" v-loading="loading">
|
||||||
@@ -65,7 +84,12 @@ import { apiAssetUserList, apiAssetUserAdd, apiAssetUserEdit, apiAssetUserDelete
|
|||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const tableData = ref([])
|
const tableData = ref([])
|
||||||
const total = ref(0)
|
const total = ref(0)
|
||||||
const queryParams = reactive({
|
|
||||||
|
const searchData = reactive({
|
||||||
|
phone: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
const queryParams = reactive<any>({
|
||||||
page_no: 1,
|
page_no: 1,
|
||||||
page_size: 15
|
page_size: 15
|
||||||
})
|
})
|
||||||
@@ -89,7 +113,8 @@ const rules = {
|
|||||||
const getList = async () => {
|
const getList = async () => {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
try {
|
try {
|
||||||
const res = await apiAssetUserList(queryParams)
|
const params = { ...queryParams, ...searchData }
|
||||||
|
const res = await apiAssetUserList(params)
|
||||||
tableData.value = res.lists
|
tableData.value = res.lists
|
||||||
total.value = res.count
|
total.value = res.count
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -99,6 +124,17 @@ const getList = async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleSearch = () => {
|
||||||
|
queryParams.page_no = 1
|
||||||
|
getList()
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleReset = () => {
|
||||||
|
searchData.phone = ''
|
||||||
|
queryParams.page_no = 1
|
||||||
|
getList()
|
||||||
|
}
|
||||||
|
|
||||||
const handleAdd = () => {
|
const handleAdd = () => {
|
||||||
dialogTitle.value = '新增账号'
|
dialogTitle.value = '新增账号'
|
||||||
Object.assign(formData, { id: '', phone: '', password: '', status: 1 })
|
Object.assign(formData, { id: '', phone: '', password: '', status: 1 })
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ class AssetResourceController extends BaseAdminController
|
|||||||
$pageNo = $this->request->get('page_no', 1);
|
$pageNo = $this->request->get('page_no', 1);
|
||||||
$pageSize = $this->request->get('page_size', 15);
|
$pageSize = $this->request->get('page_size', 15);
|
||||||
$type = $this->request->get('type');
|
$type = $this->request->get('type');
|
||||||
|
$title = $this->request->get('title', '');
|
||||||
$startTime = $this->request->get('start_time');
|
$startTime = $this->request->get('start_time');
|
||||||
$endTime = $this->request->get('end_time');
|
$endTime = $this->request->get('end_time');
|
||||||
|
|
||||||
@@ -23,6 +24,9 @@ class AssetResourceController extends BaseAdminController
|
|||||||
if ($type) {
|
if ($type) {
|
||||||
$where[] = ['type', '=', $type];
|
$where[] = ['type', '=', $type];
|
||||||
}
|
}
|
||||||
|
if ($title) {
|
||||||
|
$where[] = ['title', 'like', '%' . $title . '%'];
|
||||||
|
}
|
||||||
if ($startTime) {
|
if ($startTime) {
|
||||||
$where[] = ['create_time', '>=', strtotime($startTime)];
|
$where[] = ['create_time', '>=', strtotime($startTime)];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,9 +13,16 @@ class AssetUserController extends BaseAdminController
|
|||||||
{
|
{
|
||||||
$pageNo = $this->request->get('page_no', 1);
|
$pageNo = $this->request->get('page_no', 1);
|
||||||
$pageSize = $this->request->get('page_size', 15);
|
$pageSize = $this->request->get('page_size', 15);
|
||||||
|
$phone = $this->request->get('phone', '');
|
||||||
|
|
||||||
$count = AssetUser::count();
|
$where = [];
|
||||||
$lists = AssetUser::order('id', 'desc')
|
if ($phone) {
|
||||||
|
$where[] = ['phone', 'like', '%' . $phone . '%'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$count = AssetUser::where($where)->count();
|
||||||
|
$lists = AssetUser::where($where)
|
||||||
|
->order('id', 'desc')
|
||||||
->page($pageNo, $pageSize)
|
->page($pageNo, $pageSize)
|
||||||
->select();
|
->select();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user