feat: add resource edit functionality and time range filter in admin panel
This commit is contained in:
@@ -21,6 +21,9 @@ export function apiAssetResourceList(params: any) {
|
|||||||
export function apiAssetResourceAdd(params: any) {
|
export function apiAssetResourceAdd(params: any) {
|
||||||
return request.post({ url: '/asset.AssetResource/add', params })
|
return request.post({ url: '/asset.AssetResource/add', params })
|
||||||
}
|
}
|
||||||
|
export function apiAssetResourceEdit(params: any) {
|
||||||
|
return request.post({ url: '/asset.AssetResource/edit', params })
|
||||||
|
}
|
||||||
export function apiAssetResourceDelete(params: any) {
|
export function apiAssetResourceDelete(params: any) {
|
||||||
return request.post({ url: '/asset.AssetResource/delete', params })
|
return request.post({ url: '/asset.AssetResource/delete', params })
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,19 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="asset-resource-container">
|
<div class="asset-resource-container">
|
||||||
<el-card shadow="never" class="!border-none">
|
<el-card shadow="never" class="!border-none">
|
||||||
<div class="mb-4">
|
<div class="mb-4 flex items-center gap-4 flex-wrap">
|
||||||
<el-button type="primary" @click="handleAdd">上传并分发资源</el-button>
|
<el-button type="primary" @click="handleAdd">上传并分发资源</el-button>
|
||||||
|
<el-date-picker
|
||||||
|
v-model="dateRange"
|
||||||
|
type="daterange"
|
||||||
|
range-separator="至"
|
||||||
|
start-placeholder="开始日期"
|
||||||
|
end-placeholder="结束日期"
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
@change="handleDateChange"
|
||||||
|
clearable
|
||||||
|
style="width: 300px;"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-tabs v-model="queryParams.type" @tab-change="handleTabChange">
|
<el-tabs v-model="queryParams.type" @tab-change="handleTabChange">
|
||||||
@@ -22,12 +33,14 @@
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="关联账号" show-overflow-tooltip>
|
<el-table-column label="关联账号" show-overflow-tooltip>
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<span>{{ row.users?.map((u: any) => u.phone).join(', ') || '未关联' }}</span>
|
<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>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="create_time" label="上传时间" width="180" />
|
<el-table-column prop="create_time" label="上传时间" width="180" />
|
||||||
<el-table-column label="操作" width="120" fixed="right">
|
<el-table-column label="操作" width="150" fixed="right">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
|
<el-button type="primary" link @click="handleEdit(row)">编辑</el-button>
|
||||||
<el-button type="danger" link @click="handleDelete(row)">删除</el-button>
|
<el-button type="danger" link @click="handleDelete(row)">删除</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
@@ -46,9 +59,9 @@
|
|||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<!-- 新增资源弹窗 -->
|
<!-- 新增资源弹窗 -->
|
||||||
<el-dialog v-model="dialogVisible" title="新增分发资源" 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="rules" label-width="100px">
|
||||||
<el-form-item label="资源类型" prop="type">
|
<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>
|
||||||
<el-radio :label="2">视频</el-radio>
|
<el-radio :label="2">视频</el-radio>
|
||||||
@@ -58,7 +71,7 @@
|
|||||||
<el-form-item label="标题" prop="title">
|
<el-form-item label="标题" prop="title">
|
||||||
<el-input v-model="formData.title" placeholder="请输入资源标题" />
|
<el-input v-model="formData.title" placeholder="请输入资源标题" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="资源文件" prop="file_url">
|
<el-form-item label="资源文件" prop="file_url" v-if="!isEdit">
|
||||||
<material-picker v-if="formData.type === 1" v-model="formData.file_url" :limit="1" type="image" />
|
<material-picker v-if="formData.type === 1" v-model="formData.file_url" :limit="1" type="image" />
|
||||||
<upload v-else-if="formData.type === 2" type="video" direct :multiple="false" :limit="1" :show-progress="true" @success="handleUploadSuccess">
|
<upload v-else-if="formData.type === 2" type="video" direct :multiple="false" :limit="1" :show-progress="true" @success="handleUploadSuccess">
|
||||||
<el-button type="primary">上传视频 (OSS直传)</el-button>
|
<el-button type="primary">上传视频 (OSS直传)</el-button>
|
||||||
@@ -71,7 +84,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="关联账号" prop="user_ids">
|
<el-form-item label="关联账号" prop="user_ids">
|
||||||
<el-select v-model="formData.user_ids" multiple filterable placeholder="不选择则为公开资源" clearable>
|
<el-select v-model="formData.user_ids" multiple filterable placeholder="不选择则为公开资源" clearable style="width: 100%;">
|
||||||
<el-option v-for="item in userOptions" :key="item.id" :label="item.phone" :value="item.id" />
|
<el-option v-for="item in userOptions" :key="item.id" :label="item.phone" :value="item.id" />
|
||||||
</el-select>
|
</el-select>
|
||||||
<div style="font-size: 12px; color: #909399; margin-top: 4px;">不选择账号则资源为公开资源,所有人可见</div>
|
<div style="font-size: 12px; color: #909399; margin-top: 4px;">不选择账号则资源为公开资源,所有人可见</div>
|
||||||
@@ -79,7 +92,7 @@
|
|||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<el-button @click="dialogVisible = false">取消</el-button>
|
<el-button @click="dialogVisible = false">取消</el-button>
|
||||||
<el-button type="primary" @click="submitForm" :loading="submitLoading">确定发布</el-button>
|
<el-button type="primary" @click="submitForm" :loading="submitLoading">{{ isEdit ? '保存修改' : '确定发布' }}</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
@@ -88,14 +101,15 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, reactive, onMounted } from 'vue'
|
import { ref, reactive, onMounted } from 'vue'
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
import { apiAssetResourceList, apiAssetResourceAdd, 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'
|
||||||
import Upload from '@/components/upload/index.vue'
|
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 queryParams = reactive({
|
const dateRange = ref<string[]>([])
|
||||||
|
const queryParams = reactive<any>({
|
||||||
type: '1',
|
type: '1',
|
||||||
page_no: 1,
|
page_no: 1,
|
||||||
page_size: 15
|
page_size: 15
|
||||||
@@ -104,10 +118,12 @@ const queryParams = reactive({
|
|||||||
const dialogVisible = ref(false)
|
const dialogVisible = ref(false)
|
||||||
const submitLoading = ref(false)
|
const submitLoading = ref(false)
|
||||||
const formRef = ref()
|
const formRef = ref()
|
||||||
|
const isEdit = ref(false)
|
||||||
|
const editId = ref(0)
|
||||||
|
|
||||||
const userOptions = ref<any[]>([])
|
const userOptions = ref<any[]>([])
|
||||||
|
|
||||||
const formData = reactive({
|
const formData = reactive<any>({
|
||||||
type: 1,
|
type: 1,
|
||||||
title: '',
|
title: '',
|
||||||
file_url: '',
|
file_url: '',
|
||||||
@@ -147,12 +163,40 @@ const handleTabChange = () => {
|
|||||||
getList()
|
getList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleDateChange = (val: string[] | null) => {
|
||||||
|
if (val && val.length === 2) {
|
||||||
|
queryParams.start_time = val[0]
|
||||||
|
queryParams.end_time = val[1]
|
||||||
|
} else {
|
||||||
|
delete queryParams.start_time
|
||||||
|
delete queryParams.end_time
|
||||||
|
}
|
||||||
|
queryParams.page_no = 1
|
||||||
|
getList()
|
||||||
|
}
|
||||||
|
|
||||||
const handleAdd = () => {
|
const handleAdd = () => {
|
||||||
|
isEdit.value = false
|
||||||
|
editId.value = 0
|
||||||
Object.assign(formData, { type: parseInt(queryParams.type), title: '', file_url: '', cover_url: '', user_ids: [] })
|
Object.assign(formData, { type: parseInt(queryParams.type), title: '', file_url: '', cover_url: '', user_ids: [] })
|
||||||
fetchUserOptions()
|
fetchUserOptions()
|
||||||
dialogVisible.value = true
|
dialogVisible.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleEdit = (row: any) => {
|
||||||
|
isEdit.value = true
|
||||||
|
editId.value = row.id
|
||||||
|
Object.assign(formData, {
|
||||||
|
type: row.type,
|
||||||
|
title: row.title,
|
||||||
|
file_url: row.file_url,
|
||||||
|
cover_url: row.cover_url || '',
|
||||||
|
user_ids: row.users?.map((u: any) => u.id) || []
|
||||||
|
})
|
||||||
|
fetchUserOptions()
|
||||||
|
dialogVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
const handleUploadSuccess = (response: any) => {
|
const handleUploadSuccess = (response: any) => {
|
||||||
formData.file_url = response?.data?.uri || response?.data?.url || ''
|
formData.file_url = response?.data?.uri || response?.data?.url || ''
|
||||||
ElMessage.success('上传成功')
|
ElMessage.success('上传成功')
|
||||||
@@ -175,8 +219,17 @@ const submitForm = async () => {
|
|||||||
if (valid) {
|
if (valid) {
|
||||||
submitLoading.value = true
|
submitLoading.value = true
|
||||||
try {
|
try {
|
||||||
await apiAssetResourceAdd(formData)
|
if (isEdit.value) {
|
||||||
ElMessage.success('上传分发成功')
|
await apiAssetResourceEdit({
|
||||||
|
id: editId.value,
|
||||||
|
title: formData.title,
|
||||||
|
user_ids: formData.user_ids
|
||||||
|
})
|
||||||
|
ElMessage.success('编辑成功')
|
||||||
|
} else {
|
||||||
|
await apiAssetResourceAdd(formData)
|
||||||
|
ElMessage.success('上传分发成功')
|
||||||
|
}
|
||||||
dialogVisible.value = false
|
dialogVisible.value = false
|
||||||
getList()
|
getList()
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|||||||
@@ -16,11 +16,19 @@ 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');
|
||||||
|
$startTime = $this->request->get('start_time');
|
||||||
|
$endTime = $this->request->get('end_time');
|
||||||
|
|
||||||
$where = [];
|
$where = [];
|
||||||
if ($type) {
|
if ($type) {
|
||||||
$where[] = ['type', '=', $type];
|
$where[] = ['type', '=', $type];
|
||||||
}
|
}
|
||||||
|
if ($startTime) {
|
||||||
|
$where[] = ['create_time', '>=', strtotime($startTime)];
|
||||||
|
}
|
||||||
|
if ($endTime) {
|
||||||
|
$where[] = ['create_time', '<=', strtotime($endTime) + 86399];
|
||||||
|
}
|
||||||
|
|
||||||
$count = AssetResource::where($where)->count();
|
$count = AssetResource::where($where)->count();
|
||||||
$lists = AssetResource::with('users')
|
$lists = AssetResource::with('users')
|
||||||
@@ -77,6 +85,55 @@ class AssetResourceController extends BaseAdminController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @notes 编辑资源(修改标题、关联账号)
|
||||||
|
*/
|
||||||
|
public function edit()
|
||||||
|
{
|
||||||
|
$params = $this->request->post();
|
||||||
|
$id = $params['id'] ?? 0;
|
||||||
|
if (empty($id)) {
|
||||||
|
return $this->fail('缺少参数');
|
||||||
|
}
|
||||||
|
|
||||||
|
$resource = AssetResource::find($id);
|
||||||
|
if (!$resource) {
|
||||||
|
return $this->fail('资源不存在');
|
||||||
|
}
|
||||||
|
|
||||||
|
Db::startTrans();
|
||||||
|
try {
|
||||||
|
// 更新标题
|
||||||
|
if (!empty($params['title'])) {
|
||||||
|
$resource->title = $params['title'];
|
||||||
|
$resource->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重新绑定用户(先删后加)
|
||||||
|
if (isset($params['user_ids'])) {
|
||||||
|
AssetUserResource::where('resource_id', $id)->delete();
|
||||||
|
$userIds = is_array($params['user_ids']) ? $params['user_ids'] : [];
|
||||||
|
if (!empty($userIds)) {
|
||||||
|
$userResources = [];
|
||||||
|
foreach ($userIds as $userId) {
|
||||||
|
$userResources[] = [
|
||||||
|
'user_id' => $userId,
|
||||||
|
'resource_id' => $id,
|
||||||
|
'create_time' => time(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
(new AssetUserResource())->saveAll($userResources);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Db::commit();
|
||||||
|
return $this->success('编辑成功');
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
Db::rollback();
|
||||||
|
return $this->fail('操作失败: ' . $e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @notes 删除资源
|
* @notes 删除资源
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user