feat: update
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
// 登录
|
// 登录
|
||||||
export const loginApiUrl = "/guest/login";
|
export const loginApiUrl = "/guest/login";
|
||||||
|
|
||||||
// 配置
|
// 配置
|
||||||
export const getSystemConfigListApiUrl = "/system/config/list";
|
export const getSystemConfigListApiUrl = "/system/config/list";
|
||||||
export const getSystemConfigSaveApiUrl = "/system/config/save";
|
export const getSystemConfigSaveApiUrl = "/system/config/save";
|
||||||
|
|
||||||
@@ -23,23 +23,22 @@ export const getSystemUserInfoApiUrl = "/system/user/info";
|
|||||||
export const getSystemUserlistApiUrl = "/system/user/list";
|
export const getSystemUserlistApiUrl = "/system/user/list";
|
||||||
|
|
||||||
// 视频分类 /shipin/fenlei/list?page=1&limit=10&key=
|
// 视频分类 /shipin/fenlei/list?page=1&limit=10&key=
|
||||||
export const getShipinFenleiApiUrl = "/shipin/fenlei/list";
|
export const getVideoCategoryApiUrl = "/video/category/list";
|
||||||
// 视频列表 /shipin/main/list?page=1&limit=10&key=
|
export const getVideoListApiUrl = "/video/list";
|
||||||
export const getShipinMainListApiUrl = "/shipin/main/list";
|
|
||||||
// 视频列表 -批量设置每日推荐视频
|
// 视频列表 -批量设置每日推荐视频
|
||||||
export const getShipinMainMrtjApiUrl = "/shipin/main/mrtj";
|
export const getVideoSetLevelApiUrl = "/video/level/set";
|
||||||
export const getShipinMainVipApiUrl = "/shipin/main/vip";
|
export const getVideoSetBoxOfficeApiUrl = "/video/boxoffice/set";
|
||||||
|
|
||||||
// seo关键词
|
// seo关键词
|
||||||
export const getKeyWordListApiUrl = "/system/keyword/list";
|
export const getKeyWordListApiUrl = "/system/keyword/list";
|
||||||
export const getKeyWordSaveApiUrl = "/system/keyword/save";
|
export const getKeyWordSaveApiUrl = "/system/keyword/save";
|
||||||
export const getKeyWordDelApiUrl = "/system/keyword/del";
|
export const getKeyWordDelApiUrl = "/system/keyword/del";
|
||||||
|
|
||||||
// 小说分类
|
// 小说分类
|
||||||
export const getXiaoShuoFenleiApiUrl = "/novel/category/list";
|
export const getXiaoShuoFenleiApiUrl = "/novel/category/list";
|
||||||
// 小说章节
|
// 小说章节
|
||||||
export const getXiaoZhangJieYouApiUrl = "/xiaoshuo/zhangjie/list";
|
export const getXiaoZhangJieYouApiUrl = "/xiaoshuo/zhangjie/list";
|
||||||
// 小说列表
|
// 小说列表
|
||||||
export const getXiaoShuoMainListApiUrl = "/novel/list";
|
export const getXiaoShuoMainListApiUrl = "/novel/list";
|
||||||
|
|
||||||
// 广告分组 /guanggao/main/group/list?page=1&limit=10&key=
|
// 广告分组 /guanggao/main/group/list?page=1&limit=10&key=
|
||||||
@@ -67,7 +66,6 @@ export const getGuangGaoMainSaveApiUrl = "/guanggao/main/save";
|
|||||||
// 删除广告 /guanggao/main/group/del 传参form-data 参数 gg_id
|
// 删除广告 /guanggao/main/group/del 传参form-data 参数 gg_id
|
||||||
export const getGuangGaoMainDelApiUrl = "/guanggao/main/del";
|
export const getGuangGaoMainDelApiUrl = "/guanggao/main/del";
|
||||||
|
|
||||||
|
|
||||||
// 参数模板列表
|
// 参数模板列表
|
||||||
export const getTkdargListUrl = "/site/tkdarg/list";
|
export const getTkdargListUrl = "/site/tkdarg/list";
|
||||||
|
|
||||||
@@ -77,6 +75,3 @@ export const getTemplateListUrl = "/site/template/list";
|
|||||||
export const getSubjectFomartGroupList = "/site/subject/fomart/group/list";
|
export const getSubjectFomartGroupList = "/site/subject/fomart/group/list";
|
||||||
// 替换模板列表
|
// 替换模板列表
|
||||||
export const getSubjectFomartList = "/site/subject/fomart/list";
|
export const getSubjectFomartList = "/site/subject/fomart/list";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
import { ResPage } from "@/api/interface/index";
|
import { ResPage } from "@/api/interface/index";
|
||||||
import { fenLeiList } from "@/api/interface/video/fenlei";
|
import { fenLeiList } from "@/api/interface/video/fenlei";
|
||||||
import { getShipinFenleiApiUrl } from "@/api/config";
|
import { getVideoCategoryApiUrl } from "@/api/config";
|
||||||
import http from "@/api";
|
import http from "@/api";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @name 视频分类
|
* @name 视频分类
|
||||||
*/
|
*/
|
||||||
export const getList = (params: fenLeiList.ReqParams) => {
|
export const getList = (params: fenLeiList.ReqParams) => {
|
||||||
return http.get<ResPage<fenLeiList.ResList>>(getShipinFenleiApiUrl, params);
|
return http.get<ResPage<fenLeiList.ResList>>(getVideoCategoryApiUrl, params);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getAllList = () => {
|
export const getAllList = () => {
|
||||||
return http.get<ResPage<fenLeiList.ResList>>(getShipinFenleiApiUrl, { limit: 1000, page: 1 });
|
return http.get<ResPage<fenLeiList.ResList>>(getVideoCategoryApiUrl, { limit: 1000, page: 1 });
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,36 +1,24 @@
|
|||||||
import { ResPage, ResultData } from "@/api/interface/index";
|
import { ResPage, ResultData } from "@/api/interface/index";
|
||||||
import { VideoList } from "@/api/interface/video/list";
|
import { VideoList } from "@/api/interface/video/list";
|
||||||
import { VIDEO_PORT } from "@/api/config/servicePort";
|
import { getVideoListApiUrl, getVideoSetLevelApiUrl, getVideoSetBoxOfficeApiUrl } from "@/api/config";
|
||||||
import { getShipinMainListApiUrl, getShipinMainMrtjApiUrl, getShipinMainVipApiUrl } from "@/api/config";
|
|
||||||
import http from "@/api";
|
import http from "@/api";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @name 视频列表
|
* @name 视频列表
|
||||||
*/
|
*/
|
||||||
export const getVideoList = (params: VideoList.ReqParams) => {
|
export const getVideoList = (params: VideoList.ReqParams) => {
|
||||||
return http.get<ResPage<VideoList.ResList>>(getShipinMainListApiUrl, params);
|
return http.get<ResPage<VideoList.ResList>>(getVideoListApiUrl, params);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name 批量设置视频推荐等级
|
||||||
|
*/
|
||||||
|
export const setLevel = (params: VideoList.delParams) => {
|
||||||
|
return http.post<ResPage<ResultData>>(getVideoSetLevelApiUrl, params);
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* @name 设置视频
|
* @name 批量设置视频票房
|
||||||
*/
|
*/
|
||||||
export const saveData = (params: VideoList.saveParams) => {
|
export const setBoxOffice = (params: VideoList.delParams) => {
|
||||||
return http.post<ResPage<ResultData>>(VIDEO_PORT + `/save`, params);
|
return http.post<ResPage<ResultData>>(getVideoSetBoxOfficeApiUrl, params);
|
||||||
};
|
|
||||||
/**
|
|
||||||
* @name 批量设置视频
|
|
||||||
*/
|
|
||||||
export const batchData = (params: VideoList.delParams) => {
|
|
||||||
return http.post<ResPage<ResultData>>(getShipinMainMrtjApiUrl, params);
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* @name 批量设置vip视频
|
|
||||||
*/
|
|
||||||
export const batchVipData = (params: VideoList.delParams) => {
|
|
||||||
return http.post<ResPage<ResultData>>(getShipinMainVipApiUrl, params);
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* @name 删除视频
|
|
||||||
*/
|
|
||||||
export const deleteItem = (params: VideoList.delParams) => {
|
|
||||||
return http.post<ResPage<ResultData>>(VIDEO_PORT + `/del`, params);
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -421,7 +421,7 @@
|
|||||||
"icon": "VideoCameraFilled",
|
"icon": "VideoCameraFilled",
|
||||||
"title": "视频管理",
|
"title": "视频管理",
|
||||||
"isLink": "",
|
"isLink": "",
|
||||||
"isHide": true,
|
"isHide": false,
|
||||||
"isFull": false,
|
"isFull": false,
|
||||||
"isAffix": false,
|
"isAffix": false,
|
||||||
"isKeepAlive": true
|
"isKeepAlive": true
|
||||||
@@ -442,21 +442,7 @@
|
|||||||
"isKeepAlive": true
|
"isKeepAlive": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"path": "/video/nvyou/index",
|
|
||||||
"name": "videoNvYou",
|
|
||||||
"component": "/video/nvyou/index",
|
|
||||||
"meta": {
|
|
||||||
"an_id": 2307,
|
|
||||||
"icon": "Files",
|
|
||||||
"title": "明星列表",
|
|
||||||
"isLink": "",
|
|
||||||
"isHide": false,
|
|
||||||
"isFull": false,
|
|
||||||
"isAffix": false,
|
|
||||||
"isKeepAlive": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"path": "/video/index",
|
"path": "/video/index",
|
||||||
"name": "Video",
|
"name": "Video",
|
||||||
@@ -472,21 +458,7 @@
|
|||||||
"isKeepAlive": true
|
"isKeepAlive": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"path": "/tag/videoTag/index",
|
|
||||||
"name": "videoTag",
|
|
||||||
"component": "/tag/videoTag/index",
|
|
||||||
"meta": {
|
|
||||||
"an_id": 2105,
|
|
||||||
"icon": "Files",
|
|
||||||
"title": "标签列表",
|
|
||||||
"isLink": "",
|
|
||||||
"isHide": true,
|
|
||||||
"isFull": false,
|
|
||||||
"isAffix": false,
|
|
||||||
"isKeepAlive": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"path": "/searchGroup/index",
|
"path": "/searchGroup/index",
|
||||||
"name": "searchGroupIndex",
|
"name": "searchGroupIndex",
|
||||||
@@ -756,7 +728,6 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
"path": "/feedback",
|
"path": "/feedback",
|
||||||
"name": "feedback",
|
"name": "feedback",
|
||||||
@@ -811,7 +782,7 @@
|
|||||||
"icon": "CameraFilled",
|
"icon": "CameraFilled",
|
||||||
"title": "广告管理",
|
"title": "广告管理",
|
||||||
"isLink": "",
|
"isLink": "",
|
||||||
"isHide": true,
|
"isHide": false,
|
||||||
"isFull": false,
|
"isFull": false,
|
||||||
"isAffix": false,
|
"isAffix": false,
|
||||||
"isKeepAlive": true
|
"isKeepAlive": true
|
||||||
@@ -862,7 +833,7 @@
|
|||||||
"isKeepAlive": true
|
"isKeepAlive": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"path": "/ad/config",
|
"path": "/ad/config",
|
||||||
"name": "adConfig",
|
"name": "adConfig",
|
||||||
|
|||||||
@@ -10,7 +10,6 @@
|
|||||||
:hide-required-asterisk="drawerProps.isView"
|
:hide-required-asterisk="drawerProps.isView"
|
||||||
>
|
>
|
||||||
<div class="c-two-columns">
|
<div class="c-two-columns">
|
||||||
|
|
||||||
<el-form-item style="width: 45%" label="视图模板" prop="t_id">
|
<el-form-item style="width: 45%" label="视图模板" prop="t_id">
|
||||||
<el-select v-model="drawerProps.row.t_id" placeholder="请选择视图模板" clearable @change="handleSelectChange">
|
<el-select v-model="drawerProps.row.t_id" placeholder="请选择视图模板" clearable @change="handleSelectChange">
|
||||||
<el-option v-for="item in templateList" :key="item.t_id" :label="item.t_code" :value="item.t_id" />
|
<el-option v-for="item in templateList" :key="item.t_id" :label="item.t_code" :value="item.t_id" />
|
||||||
@@ -44,10 +43,9 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item style="width: 50%" label="站点名称" prop="d_name">
|
<el-form-item style="width: 50%" label="站点名称" prop="d_name">
|
||||||
<el-input v-model="drawerProps.row.d_name" placeholder="请输入站点名称" clearable />
|
<el-input v-model="drawerProps.row.d_name" placeholder="请输入站点名称" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="c-two-columns">
|
<div class="c-two-columns">
|
||||||
<el-form-item style="width: 50%" label="文字LOGO" prop="d_text_logo">
|
<el-form-item style="width: 50%" label="文字LOGO" prop="d_text_logo">
|
||||||
<el-input v-model="drawerProps.row.d_text_logo" placeholder="请输入文字LOGO" clearable />
|
<el-input v-model="drawerProps.row.d_text_logo" placeholder="请输入文字LOGO" clearable />
|
||||||
@@ -58,19 +56,17 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="c-two-columns">
|
<div class="c-two-columns">
|
||||||
<el-form-item style="width: 100%" label="首页title" prop="d_index_title" >
|
<el-form-item style="width: 100%" label="首页title" prop="d_index_title">
|
||||||
<el-input v-model="drawerProps.row.d_index_title" placeholder="请输入首页title" clearable />
|
<el-input v-model="drawerProps.row.d_index_title" placeholder="请输入首页title" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="c-two-columns">
|
<div class="c-two-columns">
|
||||||
|
|
||||||
<el-form-item style="width: 100%" label="首页keywords" prop="d_index_keywords" label-width="130px!important">
|
<el-form-item style="width: 100%" label="首页keywords" prop="d_index_keywords" label-width="130px!important">
|
||||||
<el-input v-model="drawerProps.row.d_index_keywords" placeholder="请输入首页keywords" clearable />
|
<el-input v-model="drawerProps.row.d_index_keywords" placeholder="请输入首页keywords" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
<div class="c-one-columns">
|
<div class="c-one-columns">
|
||||||
<el-form-item label="首页description" prop="d_index_description" label-width="130px!important">
|
<el-form-item label="首页description" prop="d_index_description" label-width="130px!important">
|
||||||
<el-input
|
<el-input
|
||||||
type="textarea"
|
type="textarea"
|
||||||
v-model="drawerProps.row.d_index_description"
|
v-model="drawerProps.row.d_index_description"
|
||||||
@@ -106,7 +102,7 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
<div class="c-one-columns">
|
<div class="c-one-columns">
|
||||||
<el-form-item label="统计代码" prop="d_statis">
|
<el-form-item label="统计代码" prop="d_statis">
|
||||||
<el-input
|
<el-input
|
||||||
type="textarea"
|
type="textarea"
|
||||||
v-model="drawerProps.row.d_statis"
|
v-model="drawerProps.row.d_statis"
|
||||||
@@ -120,7 +116,12 @@
|
|||||||
|
|
||||||
<div class="c-two-columns">
|
<div class="c-two-columns">
|
||||||
<el-form-item style="width: 45%" label="URL模板" prop="url_type">
|
<el-form-item style="width: 45%" label="URL模板" prop="url_type">
|
||||||
<el-select v-model="drawerProps.row.url_type" placeholder="请选择URL模板" clearable @change="handleSelectChangeUrl">
|
<el-select
|
||||||
|
v-model="drawerProps.row.url_type"
|
||||||
|
placeholder="请选择URL模板"
|
||||||
|
clearable
|
||||||
|
@change="handleSelectChangeUrl"
|
||||||
|
>
|
||||||
<el-option v-for="item in urlSubjectFomartGroup" :key="item.id" :label="item.name" :value="item.id" />
|
<el-option v-for="item in urlSubjectFomartGroup" :key="item.id" :label="item.name" :value="item.id" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -131,16 +132,18 @@
|
|||||||
|
|
||||||
<div class="c-two-columns">
|
<div class="c-two-columns">
|
||||||
<div v-for="(i, v) in drawerProps.row.t_cfg" :key="v" style="width: 50%">
|
<div v-for="(i, v) in drawerProps.row.t_cfg" :key="v" style="width: 50%">
|
||||||
<el-form-item :label="i.description" prop="t_cfg" label-width="260px!important" >
|
<el-form-item :label="i.description" prop="t_cfg" label-width="260px!important">
|
||||||
<el-select v-model="i.sfg_id" placeholder="请选择URL替换模板分组" >
|
<el-select v-model="i.sfg_id" placeholder="请选择URL替换模板分组">
|
||||||
<el-option v-for="item in subjectFomartGroup" :key="item.sfg_id" :label="item.sfg_name" :value="item.sfg_id" />
|
<el-option
|
||||||
|
v-for="item in subjectFomartGroup"
|
||||||
|
:key="item.sfg_id"
|
||||||
|
:label="item.sfg_name"
|
||||||
|
:value="item.sfg_id"
|
||||||
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<el-button @click="drawerVisible = false">取消</el-button>
|
<el-button @click="drawerVisible = false">取消</el-button>
|
||||||
@@ -162,7 +165,7 @@ type Options = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function countNovelInfoUrl(array) {
|
function countNovelInfoUrl(array) {
|
||||||
return array.filter(item => item.sfg_name.includes('排行榜URL')).length;
|
return array.filter(item => item.sfg_name.includes("排行榜列表URL")).length;
|
||||||
}
|
}
|
||||||
|
|
||||||
const templateList = ref();
|
const templateList = ref();
|
||||||
@@ -176,17 +179,15 @@ const subjectFomartGroup = ref();
|
|||||||
// 获取替换分组模板列表
|
// 获取替换分组模板列表
|
||||||
getSubjectFomartGroup().then(res => {
|
getSubjectFomartGroup().then(res => {
|
||||||
subjectFomartGroup.value = res.data.items;
|
subjectFomartGroup.value = res.data.items;
|
||||||
|
|
||||||
const intUrlTotal = countNovelInfoUrl(res.data.items);
|
const intUrlTotal = countNovelInfoUrl(res.data.items);
|
||||||
|
|
||||||
urlSubjectFomartGroup = Array.from({ length: intUrlTotal }, (_, index) => ({
|
urlSubjectFomartGroup = Array.from({ length: intUrlTotal }, (_, index) => ({
|
||||||
name: `URL 模板 ${index+=1}`,
|
name: `URL 模板 ${(index += 1)}`,
|
||||||
id: index // id 循环生成 1, 2, 3, 4, 5, 6
|
id: index // id 循环生成 1, 2, 3, 4, 5, 6
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const actions = ref<any[]>([]);
|
const actions = ref<any[]>([]);
|
||||||
// 添加参数配置
|
// 添加参数配置
|
||||||
const addParams = () => {
|
const addParams = () => {
|
||||||
@@ -508,7 +509,7 @@ const drawerProps = ref<DrawerProps>({
|
|||||||
// 接收父组件传过来的参数
|
// 接收父组件传过来的参数
|
||||||
const acceptParams = (params: DrawerProps) => {
|
const acceptParams = (params: DrawerProps) => {
|
||||||
drawerProps.value = params;
|
drawerProps.value = params;
|
||||||
drawerProps.value.row['url_type'] = 1;
|
drawerProps.value.row["url_type"] = 1;
|
||||||
rules.value = generateRules(formColumns.value);
|
rules.value = generateRules(formColumns.value);
|
||||||
drawerVisible.value = true;
|
drawerVisible.value = true;
|
||||||
actions.value = [];
|
actions.value = [];
|
||||||
@@ -521,17 +522,17 @@ const acceptParams = (params: DrawerProps) => {
|
|||||||
// actions.value = drawerProps.value.row.si_route_url;
|
// actions.value = drawerProps.value.row.si_route_url;
|
||||||
// }
|
// }
|
||||||
};
|
};
|
||||||
const handleSelectChange = (value) => {
|
const handleSelectChange = value => {
|
||||||
const matchedTemplate = templateList.value.find(item => item.t_id === value);
|
const matchedTemplate = templateList.value.find(item => item.t_id === value);
|
||||||
drawerProps.value.row.t_cfg = matchedTemplate.t_cfg_template
|
drawerProps.value.row.t_cfg = matchedTemplate.t_cfg_template;
|
||||||
}
|
};
|
||||||
const handleSelectChangeUrl = (value) => {
|
const handleSelectChangeUrl = value => {
|
||||||
var strKey = '模板';
|
var strKey = "模板";
|
||||||
var temp = drawerProps.value.row.t_cfg;
|
var temp = drawerProps.value.row.t_cfg;
|
||||||
for (const key in temp) {
|
for (const key in temp) {
|
||||||
if (key.includes("_URL") && key != 'PC_URL_PATH') {
|
if (key.includes("_URL") && key != "PC_URL_PATH") {
|
||||||
var newKey = temp[key].description.replace(/模板(\d+)/g, `模板${value}`);
|
var newKey = temp[key].description.replace(/模板(\d+)/g, `模板${value}`);
|
||||||
subjectFomartGroup.value.forEach((item) => {
|
subjectFomartGroup.value.forEach(item => {
|
||||||
if (item.sfg_description === newKey) {
|
if (item.sfg_description === newKey) {
|
||||||
temp[key].sfg_id = item.sfg_id;
|
temp[key].sfg_id = item.sfg_id;
|
||||||
temp[key].description = item.sfg_name;
|
temp[key].description = item.sfg_name;
|
||||||
@@ -539,10 +540,8 @@ const handleSelectChangeUrl = (value) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
drawerProps.value.row.t_cfg = temp
|
drawerProps.value.row.t_cfg = temp;
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 提交数据(新增/编辑)
|
// 提交数据(新增/编辑)
|
||||||
const ruleFormRef = ref<FormInstance>();
|
const ruleFormRef = ref<FormInstance>();
|
||||||
@@ -558,8 +557,8 @@ const handleSubmit = () => {
|
|||||||
// const matchedTemplate = templateList.value.find(item => item.t_id === params.t_id);
|
// const matchedTemplate = templateList.value.find(item => item.t_id === params.t_id);
|
||||||
// console.log(matchedTemplate)
|
// console.log(matchedTemplate)
|
||||||
// console.log(matchedTemplate.t_cfg_template)
|
// console.log(matchedTemplate.t_cfg_template)
|
||||||
|
|
||||||
console.log(params.t_cfg)
|
console.log(params.t_cfg);
|
||||||
await drawerProps.value.api!(params);
|
await drawerProps.value.api!(params);
|
||||||
ElMessage.success({ message: `${drawerProps.value.title}成功!` });
|
ElMessage.success({ message: `${drawerProps.value.title}成功!` });
|
||||||
drawerProps.value.getTableList!();
|
drawerProps.value.getTableList!();
|
||||||
|
|||||||
91
src/views/video/chapter/index.vue
Normal file
91
src/views/video/chapter/index.vue
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
<template>
|
||||||
|
<div class="table-box">
|
||||||
|
<ProTable
|
||||||
|
ref="proTable"
|
||||||
|
highlight-current-row
|
||||||
|
:columns="columns"
|
||||||
|
:request-api="getTableList"
|
||||||
|
:data-callback="dataCallback"
|
||||||
|
>
|
||||||
|
</ProTable>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="tsx" name="complexProTable">
|
||||||
|
import { reactive, ref } from "vue";
|
||||||
|
import ProTable from "@/components/ProTable/index.vue";
|
||||||
|
import { ProTableInstance, ColumnProps } from "@/components/ProTable/interface";
|
||||||
|
import { ChapterList } from "@/api/interface/novel/chapter";
|
||||||
|
import { getList } from "@/api/modules/novel/chapter";
|
||||||
|
|
||||||
|
// ProTable 实例
|
||||||
|
const proTable = ref<ProTableInstance>();
|
||||||
|
|
||||||
|
const initParam = reactive({
|
||||||
|
limit: 15,
|
||||||
|
page: 1
|
||||||
|
});
|
||||||
|
|
||||||
|
const dataCallback = (data: any) => {
|
||||||
|
return {
|
||||||
|
items: data.items,
|
||||||
|
total: data.total,
|
||||||
|
total_page: data.total_pages,
|
||||||
|
page: initParam.page,
|
||||||
|
limit: initParam.limit
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const getTableList = (params: any) => {
|
||||||
|
let newParams = JSON.parse(JSON.stringify(params));
|
||||||
|
initParam.page = newParams.page;
|
||||||
|
initParam.limit = newParams.limit;
|
||||||
|
return getList(newParams);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 表格配置项
|
||||||
|
const columns = reactive<ColumnProps<ChapterList.ResList>[]>([
|
||||||
|
{ type: "selection", fixed: "left", width: 50 },
|
||||||
|
{
|
||||||
|
prop: "key",
|
||||||
|
label: "搜索内容",
|
||||||
|
isShow: false,
|
||||||
|
search: {
|
||||||
|
el: "input"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: "xszj_id",
|
||||||
|
label: "ID",
|
||||||
|
width: 80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: "xszj_pai_xu",
|
||||||
|
label: "章节序号",
|
||||||
|
width: 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: "xszj_ming_zi",
|
||||||
|
label: "章节标题"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: "xszj_nei_rong",
|
||||||
|
label: "章节内容",
|
||||||
|
showOverflowTooltip: true,
|
||||||
|
render(scope) {
|
||||||
|
return (
|
||||||
|
<div class="fixed-width" v-html={scope.row.xszj_nei_rong}>
|
||||||
|
{scope.row.xszj_nei_rong}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ prop: "created_at", label: "添加时间", width: 170 }
|
||||||
|
]);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.el-upload--picture-card {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
229
src/views/video/component/chapterDrawer.vue
Normal file
229
src/views/video/component/chapterDrawer.vue
Normal file
@@ -0,0 +1,229 @@
|
|||||||
|
<template>
|
||||||
|
<el-drawer v-model="drawerVisible" :destroy-on-close="true" size="720" :title="`${drawerProps.title}`">
|
||||||
|
<el-form
|
||||||
|
ref="ruleFormRef"
|
||||||
|
label-width="90px"
|
||||||
|
label-suffix=" :"
|
||||||
|
:rules="rules"
|
||||||
|
:disabled="drawerProps.isView"
|
||||||
|
:model="drawerProps.row"
|
||||||
|
:hide-required-asterisk="drawerProps.isView"
|
||||||
|
>
|
||||||
|
<el-form-item v-for="e in formColumns" :key="e.label" :label="e.label" :prop="e.prop" :required="e.required">
|
||||||
|
<template v-if="e.type === 'switch'">
|
||||||
|
<el-switch
|
||||||
|
v-model="e.value"
|
||||||
|
:active-value="`${1}`"
|
||||||
|
:inactive-value="`${0}`"
|
||||||
|
active-text="上架"
|
||||||
|
inactive-text="下架"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template v-if="e.type === 'switch-index'">
|
||||||
|
<el-switch
|
||||||
|
v-model="e.value"
|
||||||
|
:active-value="`${1}`"
|
||||||
|
:inactive-value="`${0}`"
|
||||||
|
active-text="是"
|
||||||
|
inactive-text="否"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template v-if="e.type === 'radio'">
|
||||||
|
<el-radio-group v-model="e.value" class="ml-4">
|
||||||
|
<el-radio v-for="item in e.options" :key="item.value" :label="item.value" size="large">{{
|
||||||
|
item.label
|
||||||
|
}}</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</template>
|
||||||
|
<template v-if="e.type === 'select'">
|
||||||
|
<el-select filterable v-model="e.value" :placeholder="`请选择${e.label}`" clearable>
|
||||||
|
<el-option
|
||||||
|
v-for="(item, index) in e.options"
|
||||||
|
:key="index"
|
||||||
|
:label="getField(item, e.fieldNames?.label)"
|
||||||
|
:value="getField(item, e.fieldNames?.value)"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</template>
|
||||||
|
<template v-if="e.type === 'text'">
|
||||||
|
<el-input v-model="e.value" :placeholder="`请输入${e.label}`" clearable></el-input>
|
||||||
|
</template>
|
||||||
|
<template v-if="e.type === 'text-i'">
|
||||||
|
<el-input v-model="e.value" :placeholder="`请输入${e.label}`" clearable></el-input>
|
||||||
|
</template>
|
||||||
|
<template v-if="e.type === 'text-num'">
|
||||||
|
<el-input v-model="e.value" type="number" :placeholder="`请输入${e.label}`" clearable></el-input>
|
||||||
|
</template>
|
||||||
|
<template v-if="e.type === 'textarea'">
|
||||||
|
<el-input
|
||||||
|
type="textarea"
|
||||||
|
v-model="e.value"
|
||||||
|
maxlength="36500"
|
||||||
|
:autosize="{ minRows: 25, maxRows: 32 }"
|
||||||
|
:placeholder="`请输入${e.label}`"
|
||||||
|
show-word-limit
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="drawerVisible = false">取消</el-button>
|
||||||
|
<el-button v-show="!drawerProps.isView" type="primary" @click="handleSubmit">确定</el-button>
|
||||||
|
</template>
|
||||||
|
</el-drawer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts" name="UserDrawer">
|
||||||
|
import { ref, computed } from "vue";
|
||||||
|
import { ElMessage, FormInstance } from "element-plus";
|
||||||
|
import { ChapterList } from "@/api/interface/novel/chapter";
|
||||||
|
type Options = {
|
||||||
|
label: string;
|
||||||
|
value: string | number;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getField = (item: any, fieldName: string | undefined) => {
|
||||||
|
return fieldName ? item[fieldName] : "";
|
||||||
|
};
|
||||||
|
type Fields = {
|
||||||
|
label: string;
|
||||||
|
prop: string;
|
||||||
|
type: string;
|
||||||
|
value: any;
|
||||||
|
required: boolean;
|
||||||
|
options?: Options[];
|
||||||
|
fieldNames?: { label: string; value: string };
|
||||||
|
};
|
||||||
|
const generateRules = (fields: Fields[]) => {
|
||||||
|
return fields.reduce(
|
||||||
|
(acc, field) => {
|
||||||
|
const { type, required, label, prop } = field;
|
||||||
|
let message = "";
|
||||||
|
if (type === "select") {
|
||||||
|
message = `请选择${label}`;
|
||||||
|
}
|
||||||
|
if (type === "tag") {
|
||||||
|
message = `请选择${label}`;
|
||||||
|
}
|
||||||
|
if (type === "radio") {
|
||||||
|
message = `请选择${label}`;
|
||||||
|
}
|
||||||
|
if (type === "text") {
|
||||||
|
message = `请输入${label}`;
|
||||||
|
}
|
||||||
|
if (type === "text-i") {
|
||||||
|
message = `请输入${label}`;
|
||||||
|
}
|
||||||
|
if (type === "text-num") {
|
||||||
|
message = `请输入${label}`;
|
||||||
|
}
|
||||||
|
if (type === "image") {
|
||||||
|
message = `请上传${label}`;
|
||||||
|
}
|
||||||
|
if (type === "image-more") {
|
||||||
|
message = `请上传${label}`;
|
||||||
|
}
|
||||||
|
acc[prop] = [{ required, message }];
|
||||||
|
return acc;
|
||||||
|
},
|
||||||
|
{} as Record<string, any>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const formColumns = computed((): Fields[] => {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
label: "章节标题",
|
||||||
|
prop: "nc_title",
|
||||||
|
type: "text",
|
||||||
|
get value() {
|
||||||
|
return drawerProps.value.row!.nc_title;
|
||||||
|
},
|
||||||
|
set value(val) {
|
||||||
|
drawerProps.value.row!.nc_title = val;
|
||||||
|
},
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "章节序号",
|
||||||
|
prop: "nc_index",
|
||||||
|
type: "text-num",
|
||||||
|
get value() {
|
||||||
|
return drawerProps.value.row!.nc_index;
|
||||||
|
},
|
||||||
|
set value(val) {
|
||||||
|
drawerProps.value.row!.nc_index = val;
|
||||||
|
},
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "阅读次数",
|
||||||
|
prop: "nc_hits",
|
||||||
|
type: "text-num",
|
||||||
|
get value() {
|
||||||
|
return drawerProps.value.row!.nc_hits;
|
||||||
|
},
|
||||||
|
set value(val) {
|
||||||
|
drawerProps.value.row!.nc_hits = val;
|
||||||
|
},
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "章节内容",
|
||||||
|
prop: "nc_content",
|
||||||
|
type: "textarea",
|
||||||
|
get value() {
|
||||||
|
return drawerProps.value.row!.nc_content;
|
||||||
|
},
|
||||||
|
set value(val) {
|
||||||
|
drawerProps.value.row!.nc_content = val;
|
||||||
|
},
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
];
|
||||||
|
});
|
||||||
|
const rules = ref();
|
||||||
|
|
||||||
|
interface DrawerProps {
|
||||||
|
title: string;
|
||||||
|
isView: boolean;
|
||||||
|
row: Partial<ChapterList.ResList>;
|
||||||
|
api?: (params: any) => Promise<any>;
|
||||||
|
getTableList?: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const drawerVisible = ref(false);
|
||||||
|
const drawerProps = ref<DrawerProps>({
|
||||||
|
isView: false,
|
||||||
|
title: "",
|
||||||
|
row: {}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 接收父组件传过来的参数
|
||||||
|
const acceptParams = (params: DrawerProps) => {
|
||||||
|
drawerProps.value = params;
|
||||||
|
rules.value = generateRules(formColumns.value);
|
||||||
|
drawerVisible.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 提交数据(新增/编辑)
|
||||||
|
const ruleFormRef = ref<FormInstance>();
|
||||||
|
const handleSubmit = () => {
|
||||||
|
ruleFormRef.value!.validate(async valid => {
|
||||||
|
if (!valid) return;
|
||||||
|
try {
|
||||||
|
const params = { ...drawerProps.value.row };
|
||||||
|
await drawerProps.value.api!(params);
|
||||||
|
ElMessage.success({ message: `${drawerProps.value.title}成功!` });
|
||||||
|
drawerProps.value.getTableList!();
|
||||||
|
drawerVisible.value = false;
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
acceptParams
|
||||||
|
});
|
||||||
|
</script>
|
||||||
181
src/views/video/components/chapter.vue
Normal file
181
src/views/video/components/chapter.vue
Normal file
@@ -0,0 +1,181 @@
|
|||||||
|
<template>
|
||||||
|
<el-drawer v-model="drawerVisible" size="80%" title="章节列表" :destroy-on-close="true">
|
||||||
|
<ProTable
|
||||||
|
ref="proTable"
|
||||||
|
highlight-current-row
|
||||||
|
:columns="columns"
|
||||||
|
:request-api="getTableList"
|
||||||
|
:data-callback="dataCallback"
|
||||||
|
:init-param="initParam"
|
||||||
|
:is-displayed="isDisplayed"
|
||||||
|
:is-search-location="isSearchLocation"
|
||||||
|
>
|
||||||
|
<!-- 表格 header 按钮 -->
|
||||||
|
<template #tableHeader="scope">
|
||||||
|
<el-button type="primary" style="display: none" :icon="CirclePlus" @click="openDrawer(true)">
|
||||||
|
新增小说章节
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
style="display: none"
|
||||||
|
type="danger"
|
||||||
|
:icon="Delete"
|
||||||
|
plain
|
||||||
|
:disabled="!scope.isSelected"
|
||||||
|
@click="batchDelete(scope.selectedList)"
|
||||||
|
>
|
||||||
|
批量删除章节
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
<!-- 表格操作 -->
|
||||||
|
<template #operation="scope">
|
||||||
|
<el-button type="primary" link :icon="EditPen" @click="openDrawer(false, scope.row)">编辑</el-button>
|
||||||
|
<el-button type="danger" link :icon="Delete" @click="deleteAccount(scope.row)">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</ProTable>
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="drawerVisible = false">取消</el-button>
|
||||||
|
<el-button @click="drawerVisible = false" type="primary">确定</el-button>
|
||||||
|
</template>
|
||||||
|
<ChapterDrawer ref="chapterDrawerRef" />
|
||||||
|
</el-drawer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="tsx" name="UserDrawer">
|
||||||
|
import { ref, reactive } from "vue";
|
||||||
|
import ProTable from "@/components/ProTable/index.vue";
|
||||||
|
import { ColumnProps, ProTableInstance } from "@/components/ProTable/interface";
|
||||||
|
import { useHandleData } from "@/hooks/useHandleData";
|
||||||
|
import { Delete, EditPen, CirclePlus } from "@element-plus/icons-vue";
|
||||||
|
import { ChapterList } from "@/api/interface/novel/chapter";
|
||||||
|
import { getList, saveData, deleteItem } from "@/api/modules/novel/chapter";
|
||||||
|
import ChapterDrawer from "../component/chapterDrawer.vue";
|
||||||
|
// ProTable 实例
|
||||||
|
const proTable = ref<ProTableInstance>();
|
||||||
|
|
||||||
|
// 如果表格需要初始化请求参数,直接定义传给 ProTable(之后每次请求都会自动带上该参数,此参数更改之后也会一直带上,改变此参数会自动刷新表格数据)
|
||||||
|
const initParam = reactive({
|
||||||
|
xsxq_id: 0,
|
||||||
|
limit: 15,
|
||||||
|
page: 1
|
||||||
|
});
|
||||||
|
|
||||||
|
const dataCallback = (data: any) => {
|
||||||
|
return {
|
||||||
|
items: data.items,
|
||||||
|
total: data.total,
|
||||||
|
total_page: data.total_pages,
|
||||||
|
page: initParam.page,
|
||||||
|
limit: initParam.limit
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const getTableList = (params: any) => {
|
||||||
|
let newParams = JSON.parse(JSON.stringify(params));
|
||||||
|
initParam.page = newParams.page;
|
||||||
|
initParam.limit = newParams.limit;
|
||||||
|
return getList(newParams);
|
||||||
|
};
|
||||||
|
|
||||||
|
const isDisplayed = ref<any>(false);
|
||||||
|
const isSearchLocation = ref<any>(false);
|
||||||
|
|
||||||
|
// 表格配置项
|
||||||
|
const columns = reactive<ColumnProps<ChapterList.ResList>[]>([
|
||||||
|
{ type: "selection", fixed: "left", width: 50 },
|
||||||
|
{
|
||||||
|
prop: "key",
|
||||||
|
label: "搜索内容",
|
||||||
|
isShow: false,
|
||||||
|
search: {
|
||||||
|
el: "input"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: "xszj_id",
|
||||||
|
label: "ID",
|
||||||
|
width: 80
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: "xszj_pai_xu",
|
||||||
|
label: "章节序号",
|
||||||
|
width: 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: "xszj_ming_zi",
|
||||||
|
label: "章节标题"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: "xszj_nei_rong",
|
||||||
|
label: "章节内容",
|
||||||
|
showOverflowTooltip: true,
|
||||||
|
render(scope) {
|
||||||
|
return (
|
||||||
|
<div class="fixed-width" v-html={scope.row.xszj_nei_rong}>
|
||||||
|
{scope.row.xszj_nei_rong}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ prop: "created_at", label: "添加时间", width: 170 }
|
||||||
|
// { prop: "operation", label: "操作", fixed: "right", width: 200 }
|
||||||
|
]);
|
||||||
|
|
||||||
|
const drawerVisible = ref(false);
|
||||||
|
// 接收父组件传过来的参数
|
||||||
|
const acceptParams = (xsxq_id: number) => {
|
||||||
|
drawerVisible.value = true;
|
||||||
|
initParam.xsxq_id = xsxq_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 删除章节
|
||||||
|
const deleteAccount = async (params: ChapterList.ResList) => {
|
||||||
|
await useHandleData(deleteItem, { xszj_id: params.xszj_id, xsxq_id: initParam.xsxq_id }, "删除所选信息");
|
||||||
|
proTable.value?.getTableList();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 批量删除章节
|
||||||
|
const batchDelete = async (id: any[]) => {
|
||||||
|
const ids = id.map((item: ChapterList.ResList) => item.xszj_id);
|
||||||
|
await useHandleData(deleteItem, { xszj_id: ids.join(","), xsxq_id: initParam.xsxq_id }, "删除所选信息");
|
||||||
|
proTable.value?.clearSelection();
|
||||||
|
proTable.value?.getTableList();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 打开 drawer(新增、编辑)
|
||||||
|
const chapterDrawerRef = ref<InstanceType<typeof ChapterDrawer> | null>(null);
|
||||||
|
|
||||||
|
const openDrawer = (isEdit: boolean, row: Partial<ChapterList.ResList> = {}) => {
|
||||||
|
row.xsxq_id = initParam.xsxq_id;
|
||||||
|
const params = {
|
||||||
|
title: isEdit ? "新增小说章节" : "编辑小说章节",
|
||||||
|
row: { ...row },
|
||||||
|
api: saveData,
|
||||||
|
getTableList: proTable.value?.getTableList
|
||||||
|
};
|
||||||
|
chapterDrawerRef.value?.acceptParams(params as any);
|
||||||
|
};
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
acceptParams
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.demo-form-inline {
|
||||||
|
.el-form-item {
|
||||||
|
width: 420px;
|
||||||
|
}
|
||||||
|
:deep(.el-form-item__content) {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
align-items: flex-start;
|
||||||
|
.tips {
|
||||||
|
margin-left: 10px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #999999;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.btn-group {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -19,6 +19,15 @@
|
|||||||
inactive-text="下架"
|
inactive-text="下架"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
<template v-if="e.type === 'switch-index'">
|
||||||
|
<el-switch
|
||||||
|
v-model="e.value"
|
||||||
|
:active-value="`${1}`"
|
||||||
|
:inactive-value="`${0}`"
|
||||||
|
active-text="是"
|
||||||
|
inactive-text="否"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
<template v-if="e.type === 'radio'">
|
<template v-if="e.type === 'radio'">
|
||||||
<el-radio-group v-model="e.value" class="ml-4">
|
<el-radio-group v-model="e.value" class="ml-4">
|
||||||
<el-radio v-for="item in e.options" :key="item.value" :value="item.value" size="large">{{
|
<el-radio v-for="item in e.options" :key="item.value" :value="item.value" size="large">{{
|
||||||
@@ -27,7 +36,7 @@
|
|||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="e.type === 'select'">
|
<template v-if="e.type === 'select'">
|
||||||
<el-select filterable multiple v-model="e.value" :placeholder="`请选择${e.label}`" clearable>
|
<el-select filterable v-model="e.value" :placeholder="`请选择${e.label}`" clearable>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="(item, index) in e.options"
|
v-for="(item, index) in e.options"
|
||||||
:key="index"
|
:key="index"
|
||||||
@@ -49,20 +58,11 @@
|
|||||||
<el-input
|
<el-input
|
||||||
type="textarea"
|
type="textarea"
|
||||||
v-model="e.value"
|
v-model="e.value"
|
||||||
:rows="5"
|
|
||||||
maxlength="3650"
|
maxlength="3650"
|
||||||
:placeholder="`请输入${e.label}`"
|
:placeholder="`请输入${e.label}`"
|
||||||
show-word-limit
|
show-word-limit
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="e.type === 'text-i'">
|
|
||||||
<UploadImg disabled v-model:image-url="drawerProps.row!.v_cover" width="135px" height="135px" :file-size="3">
|
|
||||||
<template #empty>
|
|
||||||
<el-icon><Avatar /></el-icon>
|
|
||||||
<span>请上传封面</span>
|
|
||||||
</template>
|
|
||||||
</UploadImg>
|
|
||||||
</template>
|
|
||||||
<template v-if="e.type === 'tag'">
|
<template v-if="e.type === 'tag'">
|
||||||
<div class="tag-more-s">
|
<div class="tag-more-s">
|
||||||
<el-input
|
<el-input
|
||||||
@@ -103,6 +103,14 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<template v-if="e.type === 'text-i'">
|
||||||
|
<UploadImg disabled v-model:image-url="drawerProps.row!.n_cover" width="135px" height="135px" :file-size="3">
|
||||||
|
<template #empty>
|
||||||
|
<el-icon><Avatar /></el-icon>
|
||||||
|
<span>请上传封面</span>
|
||||||
|
</template>
|
||||||
|
</UploadImg>
|
||||||
|
</template>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
@@ -115,18 +123,19 @@
|
|||||||
<script setup lang="ts" name="UserDrawer">
|
<script setup lang="ts" name="UserDrawer">
|
||||||
import { ref, computed, reactive } from "vue";
|
import { ref, computed, reactive } from "vue";
|
||||||
import { ElMessage, FormInstance } from "element-plus";
|
import { ElMessage, FormInstance } from "element-plus";
|
||||||
import { VideoList } from "@/api/interface/video/list";
|
import { NovelList } from "@/api/interface/novel/list";
|
||||||
import { arrNoticeSwitch } from "@/utils/serviceDict";
|
import { arrNovelType } from "@/utils/serviceDict";
|
||||||
import { getTypeList } from "@/api/modules/tag/list";
|
import { getTypeList } from "@/api/modules/tag/list";
|
||||||
import UploadImg from "@/components/Upload/Img.vue";
|
import UploadImg from "@/components/Upload/Img.vue";
|
||||||
// import { extractURI } from "@/utils/eleValidate";
|
import { extractURI } from "@/utils/eleValidate";
|
||||||
import { getAllList } from "@/api/modules/site/list";
|
|
||||||
type Options = {
|
type Options = {
|
||||||
label: string;
|
label: string;
|
||||||
value: string | number;
|
value: string | number;
|
||||||
};
|
};
|
||||||
|
|
||||||
interface Item {
|
interface Item {
|
||||||
t_id: any;
|
t_id: any;
|
||||||
|
uri: any;
|
||||||
}
|
}
|
||||||
const getField = (item: any, fieldName: string | undefined) => {
|
const getField = (item: any, fieldName: string | undefined) => {
|
||||||
return fieldName ? item[fieldName] : "";
|
return fieldName ? item[fieldName] : "";
|
||||||
@@ -163,9 +172,6 @@ const generateRules = (fields: Fields[]) => {
|
|||||||
if (type === "text-num") {
|
if (type === "text-num") {
|
||||||
message = `请输入${label}`;
|
message = `请输入${label}`;
|
||||||
}
|
}
|
||||||
if (type === "textarea") {
|
|
||||||
message = `请输入${label}`;
|
|
||||||
}
|
|
||||||
if (type === "image") {
|
if (type === "image") {
|
||||||
message = `请上传${label}`;
|
message = `请上传${label}`;
|
||||||
}
|
}
|
||||||
@@ -180,11 +186,6 @@ const generateRules = (fields: Fields[]) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const TagList = ref([] as any);
|
const TagList = ref([] as any);
|
||||||
const getSiteList = ref([] as any);
|
|
||||||
getAllList().then(res => {
|
|
||||||
getSiteList.value = res.data.item;
|
|
||||||
});
|
|
||||||
|
|
||||||
const arrTagList = ref([] as any);
|
const arrTagList = ref([] as any);
|
||||||
const arrNewTagList = ref([] as any);
|
const arrNewTagList = ref([] as any);
|
||||||
const matchingObjects = ref([] as any); //选中相同
|
const matchingObjects = ref([] as any); //选中相同
|
||||||
@@ -194,7 +195,7 @@ const nonMatchingObjectsB = ref([] as any); //没有选中的
|
|||||||
const getTagList = async () => {
|
const getTagList = async () => {
|
||||||
try {
|
try {
|
||||||
const initParam = reactive({
|
const initParam = reactive({
|
||||||
t_type: 0,
|
t_type: 3,
|
||||||
limit: 3650,
|
limit: 3650,
|
||||||
page: 1,
|
page: 1,
|
||||||
t_hidden: 1
|
t_hidden: 1
|
||||||
@@ -252,7 +253,7 @@ function filteredTagList() {
|
|||||||
async function placeableCheckedCitiesChange(value) {
|
async function placeableCheckedCitiesChange(value) {
|
||||||
matchingObjects.value = [];
|
matchingObjects.value = [];
|
||||||
matchingObjectsA.value = [];
|
matchingObjectsA.value = [];
|
||||||
drawerProps.value.row.v_tag = value;
|
drawerProps.value.row.n_tags = value;
|
||||||
// 遍历第一个数组的每个元素
|
// 遍历第一个数组的每个元素
|
||||||
TagList.value.forEach(index => {
|
TagList.value.forEach(index => {
|
||||||
// 遍历第二个数组的每个元素
|
// 遍历第二个数组的每个元素
|
||||||
@@ -269,121 +270,104 @@ async function placeableCheckedCitiesChange(value) {
|
|||||||
nonMatchingObjects.value = arrNewTagList.value.filter(obj => !TagList.value.includes(obj.t_id));
|
nonMatchingObjects.value = arrNewTagList.value.filter(obj => !TagList.value.includes(obj.t_id));
|
||||||
nonMatchingObjectsB.value = arrNewTagList.value.filter(obj => !TagList.value.includes(obj.t_id));
|
nonMatchingObjectsB.value = arrNewTagList.value.filter(obj => !TagList.value.includes(obj.t_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
const formColumns = computed((): Fields[] => {
|
const formColumns = computed((): Fields[] => {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
label: "视频名称",
|
label: "小说名称",
|
||||||
prop: "v_name",
|
prop: "n_name",
|
||||||
type: "text",
|
type: "text",
|
||||||
get value() {
|
get value() {
|
||||||
return drawerProps.value.row!.v_name;
|
return drawerProps.value.row!.n_name;
|
||||||
},
|
},
|
||||||
set value(val) {
|
set value(val) {
|
||||||
drawerProps.value.row!.v_name = val;
|
drawerProps.value.row!.n_name = val;
|
||||||
},
|
},
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
label: "视频状态",
|
label: "小说作者",
|
||||||
prop: "v_status",
|
prop: "n_author",
|
||||||
|
type: "text",
|
||||||
|
get value() {
|
||||||
|
return drawerProps.value.row!.n_author;
|
||||||
|
},
|
||||||
|
set value(val) {
|
||||||
|
drawerProps.value.row!.n_author = val;
|
||||||
|
},
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "来源 ID",
|
||||||
|
prop: "n_source_id",
|
||||||
|
type: "text-num",
|
||||||
|
get value() {
|
||||||
|
return drawerProps.value.row!.n_source_id;
|
||||||
|
},
|
||||||
|
set value(val) {
|
||||||
|
drawerProps.value.row!.n_source_id = val;
|
||||||
|
},
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "小说状态",
|
||||||
|
prop: "n_at_status",
|
||||||
type: "switch",
|
type: "switch",
|
||||||
get value() {
|
get value() {
|
||||||
return String(drawerProps.value.row!.v_status);
|
return String(drawerProps.value.row!.n_at_status);
|
||||||
},
|
},
|
||||||
set value(val) {
|
set value(val) {
|
||||||
drawerProps.value.row!.v_status = val;
|
drawerProps.value.row!.n_at_status = val;
|
||||||
},
|
},
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "是否VIP",
|
label: "小说类型",
|
||||||
prop: "v_vip",
|
prop: "n_type",
|
||||||
type: "radio",
|
type: "radio",
|
||||||
get value() {
|
get value() {
|
||||||
return drawerProps.value.row!.v_vip;
|
return drawerProps.value.row!.n_type;
|
||||||
},
|
},
|
||||||
set value(val) {
|
set value(val) {
|
||||||
drawerProps.value.row!.v_vip = val;
|
drawerProps.value.row!.n_type = val;
|
||||||
},
|
},
|
||||||
options: arrNoticeSwitch,
|
options: arrNovelType,
|
||||||
fieldNames: { label: "label", value: "value" },
|
fieldNames: { label: "label", value: "value" },
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
|
// {
|
||||||
|
// label: "首页轮播状态",
|
||||||
|
// prop: "n_slide_status",
|
||||||
|
// type: "switch-index",
|
||||||
|
// get value() {
|
||||||
|
// return String(drawerProps.value.row!.n_slide_status);
|
||||||
|
// },
|
||||||
|
// set value(val) {
|
||||||
|
// drawerProps.value.row!.n_slide_status = val;
|
||||||
|
// },
|
||||||
|
// required: true
|
||||||
|
// },
|
||||||
|
|
||||||
|
// {
|
||||||
|
// label: "封面",
|
||||||
|
// prop: "n_cover",
|
||||||
|
// type: "text-i",
|
||||||
|
// get value() {
|
||||||
|
// return drawerProps.value.row!.n_cover;
|
||||||
|
// },
|
||||||
|
// set value(val) {
|
||||||
|
// drawerProps.value.row!.n_cover = val;
|
||||||
|
// },
|
||||||
|
// required: true
|
||||||
|
// },
|
||||||
{
|
{
|
||||||
label: "精彩站点",
|
label: "小说标签",
|
||||||
prop: "v_wonderful_site_id",
|
prop: "n_tags",
|
||||||
type: "select",
|
|
||||||
get value() {
|
|
||||||
return drawerProps.value.row!.v_wonderful_site_id;
|
|
||||||
},
|
|
||||||
set value(val) {
|
|
||||||
drawerProps.value.row!.v_wonderful_site_id = val;
|
|
||||||
},
|
|
||||||
options: getSiteList.value,
|
|
||||||
fieldNames: { label: "si_name", value: "si_id" },
|
|
||||||
required: false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "推荐站点",
|
|
||||||
prop: "v_recommend_site_id",
|
|
||||||
type: "select",
|
|
||||||
get value() {
|
|
||||||
return drawerProps.value.row!.v_recommend_site_id;
|
|
||||||
},
|
|
||||||
set value(val) {
|
|
||||||
drawerProps.value.row!.v_recommend_site_id = val;
|
|
||||||
},
|
|
||||||
options: getSiteList.value,
|
|
||||||
fieldNames: { label: "si_name", value: "si_id" },
|
|
||||||
required: false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "播放时长",
|
|
||||||
prop: "v_play_time",
|
|
||||||
type: "text",
|
|
||||||
get value() {
|
|
||||||
return drawerProps.value.row!.v_play_time;
|
|
||||||
},
|
|
||||||
set value(val) {
|
|
||||||
drawerProps.value.row!.v_play_time = val;
|
|
||||||
},
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "视频封面",
|
|
||||||
prop: "v_cover_edit",
|
|
||||||
type: "text",
|
|
||||||
get value() {
|
|
||||||
return drawerProps.value.row!.v_cover_edit;
|
|
||||||
},
|
|
||||||
set value(val) {
|
|
||||||
drawerProps.value.row!.v_cover_edit = val;
|
|
||||||
},
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "视频简介",
|
|
||||||
prop: "v_describe",
|
|
||||||
type: "textarea",
|
|
||||||
get value() {
|
|
||||||
return drawerProps.value.row!.v_describe;
|
|
||||||
},
|
|
||||||
set value(val) {
|
|
||||||
drawerProps.value.row!.v_describe = val;
|
|
||||||
},
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "视频标签",
|
|
||||||
prop: "v_tag",
|
|
||||||
type: "tag",
|
type: "tag",
|
||||||
get value() {
|
get value() {
|
||||||
return drawerProps.value.row!.v_tag;
|
return drawerProps.value.row!.n_tags;
|
||||||
},
|
},
|
||||||
set value(val) {
|
set value(val) {
|
||||||
drawerProps.value.row!.v_tag = val;
|
drawerProps.value.row!.n_tags = val;
|
||||||
},
|
},
|
||||||
options: arrTagList.value,
|
options: arrTagList.value,
|
||||||
fieldNames: { label: "label", value: "value" },
|
fieldNames: { label: "label", value: "value" },
|
||||||
@@ -396,7 +380,7 @@ const rules = ref();
|
|||||||
interface DrawerProps {
|
interface DrawerProps {
|
||||||
title: string;
|
title: string;
|
||||||
isView: boolean;
|
isView: boolean;
|
||||||
row: Partial<VideoList.ResList>;
|
row: Partial<NovelList.ResList>;
|
||||||
api?: (params: any) => Promise<any>;
|
api?: (params: any) => Promise<any>;
|
||||||
getTableList?: () => void;
|
getTableList?: () => void;
|
||||||
}
|
}
|
||||||
@@ -413,26 +397,16 @@ const acceptParams = (params: DrawerProps) => {
|
|||||||
drawerProps.value = params;
|
drawerProps.value = params;
|
||||||
rules.value = generateRules(formColumns.value);
|
rules.value = generateRules(formColumns.value);
|
||||||
drawerVisible.value = true;
|
drawerVisible.value = true;
|
||||||
if (drawerProps.value.title === "新增视频") {
|
|
||||||
drawerProps.value.row!.v_vip = 0;
|
|
||||||
drawerProps.value.row!.v_wonderful_status = 0;
|
|
||||||
drawerProps.value.row!.v_recommend_status = 0;
|
|
||||||
}
|
|
||||||
TagList.value = [];
|
TagList.value = [];
|
||||||
if (drawerProps.value.row.v_cover) {
|
if (drawerProps.value.title === "新增小说") {
|
||||||
drawerProps.value.row.v_cover_code = drawerProps.value.row.v_cover.code;
|
drawerProps.value.row!.n_type = 0;
|
||||||
drawerProps.value.row.v_cover_edit = drawerProps.value.row.v_cover.uri;
|
|
||||||
}
|
}
|
||||||
if (drawerProps.value.row.v_play_url_detail) {
|
if (drawerProps.value.row.n_cover) {
|
||||||
const data = drawerProps.value.row.v_play_url_detail;
|
drawerProps.value.row.n_cover_code = drawerProps.value.row.n_cover.code;
|
||||||
drawerProps.value.row.v_play_url = data[0];
|
drawerProps.value.row.n_cover = drawerProps.value.row.n_cover_detail;
|
||||||
}
|
}
|
||||||
if (drawerProps.value.row.v_down_url_detail) {
|
if (drawerProps.value.row.n_tags) {
|
||||||
const data = drawerProps.value.row.v_down_url_detail;
|
TagList.value = drawerProps.value.row.n_tags.map((obj: Item) => obj.t_id).map(Number);
|
||||||
drawerProps.value.row.v_down_url = data[0];
|
|
||||||
}
|
|
||||||
if (drawerProps.value.row.v_tag) {
|
|
||||||
TagList.value = drawerProps.value.row.v_tag.map((obj: Item) => obj.t_id).map(Number);
|
|
||||||
}
|
}
|
||||||
getTagList();
|
getTagList();
|
||||||
};
|
};
|
||||||
@@ -444,12 +418,13 @@ const handleSubmit = () => {
|
|||||||
if (!valid) return;
|
if (!valid) return;
|
||||||
try {
|
try {
|
||||||
const params = { ...drawerProps.value.row };
|
const params = { ...drawerProps.value.row };
|
||||||
let arrCoverData = {
|
let arrData = {
|
||||||
uri: params.v_cover_edit,
|
uri: extractURI(params.n_cover),
|
||||||
code: params.v_cover_code
|
code: params.n_cover_code
|
||||||
};
|
};
|
||||||
params.v_cover = arrCoverData;
|
|
||||||
params.v_tag = JSON.stringify(TagList.value);
|
params.n_cover = arrData;
|
||||||
|
params.n_tags = TagList.value;
|
||||||
await drawerProps.value.api!(params);
|
await drawerProps.value.api!(params);
|
||||||
ElMessage.success({ message: `${drawerProps.value.title}成功!` });
|
ElMessage.success({ message: `${drawerProps.value.title}成功!` });
|
||||||
drawerProps.value.getTableList!();
|
drawerProps.value.getTableList!();
|
||||||
|
|||||||
@@ -4,12 +4,8 @@
|
|||||||
ref="proTable"
|
ref="proTable"
|
||||||
highlight-current-row
|
highlight-current-row
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:init-param="initParam"
|
|
||||||
:request-api="getTableList"
|
:request-api="getTableList"
|
||||||
:data-callback="dataCallback"
|
:data-callback="dataCallback"
|
||||||
row-key="id"
|
|
||||||
:indent="20"
|
|
||||||
:search-col="{ xs: 1, sm: 1, md: 2, lg: 3, xl: 3 }"
|
|
||||||
>
|
>
|
||||||
</ProTable>
|
</ProTable>
|
||||||
</div>
|
</div>
|
||||||
@@ -17,11 +13,11 @@
|
|||||||
|
|
||||||
<script setup lang="tsx" name="complexProTable">
|
<script setup lang="tsx" name="complexProTable">
|
||||||
import { reactive, ref } from "vue";
|
import { reactive, ref } from "vue";
|
||||||
import { fenLeiList } from "@/api/interface/video/fenlei";
|
import { fenLeiList } from "@/api/interface/novel/fenlei";
|
||||||
import ProTable from "@/components/ProTable/index.vue";
|
import ProTable from "@/components/ProTable/index.vue";
|
||||||
import { ProTableInstance, ColumnProps } from "@/components/ProTable/interface";
|
import { ProTableInstance, ColumnProps } from "@/components/ProTable/interface";
|
||||||
import { getList } from "@/api/modules/video/fenlei";
|
import { getList } from "@/api/modules/video/fenlei";
|
||||||
import { arrPlanSwitch } from "@/utils/serviceDict";
|
|
||||||
// ProTable 实例
|
// ProTable 实例
|
||||||
const proTable = ref<ProTableInstance>();
|
const proTable = ref<ProTableInstance>();
|
||||||
|
|
||||||
@@ -31,31 +27,13 @@ const initParam = reactive({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const dataCallback = (data: any) => {
|
const dataCallback = (data: any) => {
|
||||||
let result = [] as any;
|
console.log(data);
|
||||||
data.items.forEach((item, index) => {
|
// 转换为数组
|
||||||
if (item.fl_pid === 0) {
|
const arr = Object.entries(data).map(([fl_id, fl_name]) => ({ fl_id: fl_id, fl_name }));
|
||||||
// Create a new first dimension entry
|
|
||||||
item.id = index + 1;
|
|
||||||
// item.fl_id = "";
|
|
||||||
const firstDimension = { ...item, children: [] };
|
|
||||||
// Find and add second dimension entries
|
|
||||||
data.items.forEach(subItem => {
|
|
||||||
if (subItem.fl_pid === item.fl_id) {
|
|
||||||
firstDimension.children.push(subItem);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
result.push(firstDimension);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
result.forEach(item => {
|
|
||||||
if (item.fl_pid === 0) {
|
|
||||||
item.fl_id = "";
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return {
|
return {
|
||||||
items: result,
|
items: arr,
|
||||||
total: data.total,
|
total: arr.length,
|
||||||
total_page: data.total_pages,
|
total_page: 1,
|
||||||
page: initParam.page,
|
page: initParam.page,
|
||||||
limit: initParam.limit
|
limit: initParam.limit
|
||||||
};
|
};
|
||||||
@@ -80,24 +58,17 @@ const columns = reactive<ColumnProps<fenLeiList.ResList>[]>([
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
prop: "fl_id",
|
prop: "fl_name",
|
||||||
label: "ID",
|
|
||||||
width: 100
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: "fl_mingzi",
|
|
||||||
label: "分类名称"
|
label: "分类名称"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
prop: "fl_leixing",
|
prop: "fl_id",
|
||||||
label: "类型",
|
label: "分类拼音"
|
||||||
tag: true,
|
|
||||||
enum: arrPlanSwitch,
|
|
||||||
render(scope) {
|
|
||||||
return (
|
|
||||||
<el-tag type={scope.row.fl_leixing ? "success" : "info"}>{scope.row.fl_leixing === 1 ? "其他" : "默认"}</el-tag>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// {
|
||||||
|
// prop: "fl_pinyin",
|
||||||
|
// label: "拼音"
|
||||||
|
// }
|
||||||
]);
|
]);
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -9,82 +9,114 @@
|
|||||||
>
|
>
|
||||||
<!-- 表格 header 按钮 -->
|
<!-- 表格 header 按钮 -->
|
||||||
<template #tableHeader="scope">
|
<template #tableHeader="scope">
|
||||||
|
<el-button type="primary" :icon="CirclePlus" @click="openSetDrawerRef(true)">批量设置等级</el-button>
|
||||||
|
<el-button type="primary" :icon="CirclePlus" @click="openSetPfDrawerRef(true)">批量设置票房</el-button>
|
||||||
|
<el-button type="primary" style="display: none" :icon="CirclePlus" @click="openDrawer(true)">新增</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
type="primary"
|
style="display: none"
|
||||||
:icon="EditPen"
|
type="danger"
|
||||||
|
:icon="Delete"
|
||||||
plain
|
plain
|
||||||
:disabled="!scope.isSelected"
|
:disabled="!scope.isSelected"
|
||||||
@click="batchModify(scope.selectedList)"
|
@click="batchDelete(scope.selectedList)"
|
||||||
>
|
>
|
||||||
批量设置每日推荐视频
|
批量删除
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
</template>
|
||||||
type="primary"
|
<!-- 表格操作 -->
|
||||||
:icon="EditPen"
|
<template #operation="scope">
|
||||||
plain
|
<el-button type="success" link :icon="ChatLineSquare" @click="openChapterDrawer(scope.row)">章节</el-button>
|
||||||
:disabled="!scope.isSelected"
|
<el-button type="primary" style="display: none" link :icon="EditPen" @click="openDrawer(false, scope.row)">
|
||||||
@click="batchVipDataBtn(scope.selectedList)"
|
编辑
|
||||||
>
|
</el-button>
|
||||||
批量设置vip
|
<el-button type="danger" style="display: none" link :icon="Delete" @click="deleteAccount(scope.row)">
|
||||||
|
删除
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
</ProTable>
|
</ProTable>
|
||||||
<ModifyDrawer ref="modifyDrawerRef" />
|
<Drawer ref="drawerRef" />
|
||||||
|
<SetDrawer ref="setDrawerRef" />
|
||||||
|
<SetPfDrawer ref="setPfDrawerRef" />
|
||||||
|
<ChapterDrawer ref="chapterDrawerRef" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="tsx" name="complexProTable">
|
<script setup lang="tsx" name="complexProTable">
|
||||||
import { ElImage } from "element-plus";
|
import { defineComponent, onMounted, h } from "vue";
|
||||||
import { reactive, ref } from "vue";
|
import { reactive, ref } from "vue";
|
||||||
import { VideoList } from "@/api/interface/video/list";
|
import { VideoList } from "@/api/interface/video/list";
|
||||||
import { useHandleData } from "@/hooks/useHandleData";
|
import { useHandleData } from "@/hooks/useHandleData";
|
||||||
import ProTable from "@/components/ProTable/index.vue";
|
import ProTable from "@/components/ProTable/index.vue";
|
||||||
import { EditPen } from "@element-plus/icons-vue";
|
import { Delete, EditPen, CirclePlus, ChatLineSquare } from "@element-plus/icons-vue";
|
||||||
import { ProTableInstance, ColumnProps } from "@/components/ProTable/interface";
|
import { ProTableInstance, ColumnProps } from "@/components/ProTable/interface";
|
||||||
import { getVideoList } from "@/api/modules/video/list";
|
import { getVideoList, setBoxOffice, setLevel } from "@/api/modules/video/list";
|
||||||
|
import Drawer from "./drawer.vue";
|
||||||
|
import SetDrawer from "./setDrawer.vue";
|
||||||
|
import SetPfDrawer from "./setPfDrawer.vue";
|
||||||
|
import ChapterDrawer from "./components/chapter.vue";
|
||||||
import { getAllList } from "@/api/modules/video/fenlei";
|
import { getAllList } from "@/api/modules/video/fenlei";
|
||||||
import { batchData, batchVipData } from "@/api/modules/video/list";
|
// import { LOSE_STR_KEY, LOGIN_URL } from "@/config";
|
||||||
import { LOSE_STR_KEY, LOGIN_URL } from "@/config";
|
|
||||||
import router from "@/routers";
|
import router from "@/routers";
|
||||||
import { h } from "vue";
|
import { getEndpointAllApi } from "@/api/modules/system/endpoint";
|
||||||
import { AsyncImageComponent } from "@/utils/decrypt";
|
|
||||||
import { arrNoticeSwitch } from "@/utils/serviceDict";
|
//端点列表
|
||||||
import ModifyDrawer from "./modifyDrawer.vue";
|
const Endpoints = ref([] as any);
|
||||||
// ProTable 实例
|
// ProTable 实例
|
||||||
const proTable = ref<ProTableInstance>();
|
const proTable = ref<ProTableInstance>();
|
||||||
|
|
||||||
// 视频分类
|
//小说分类
|
||||||
const getFenLeiList = ref([] as any);
|
// const getFenLeiList = ref([] as any);
|
||||||
getAllList().then(res => {
|
// getAllList().then(res => {
|
||||||
if (res.code === LOSE_STR_KEY) {
|
// if (res.code === LOSE_STR_KEY) {
|
||||||
router.replace(LOGIN_URL);
|
// router.replace(LOGIN_URL);
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
let arrFenlei = res.data.items;
|
// getFenLeiList.value = res.data.items;
|
||||||
getFenLeiList.value = arrFenlei;
|
// });
|
||||||
});
|
|
||||||
|
|
||||||
const initParam = reactive({
|
const initParam = reactive({
|
||||||
limit: 15,
|
limit: 15,
|
||||||
page: 1
|
page: 1
|
||||||
});
|
});
|
||||||
|
|
||||||
const dataCallback = (data: any) => {
|
const dataCallback = (data: any) => {
|
||||||
|
console.log(data);
|
||||||
|
// data.items.forEach((item: any) => {
|
||||||
|
// const DataString = JSON.parse(item.xsxq_feng_mian);
|
||||||
|
// const found = Endpoints.value.find(item2 => item2.zydd_code === DataString.code);
|
||||||
|
// if (found && found.zydd_domain) {
|
||||||
|
// item["https_cover_url"] = found.zydd_domain + DataString.uri;
|
||||||
|
// } else {
|
||||||
|
// item["https_cover_url"] = import.meta.env.VITE_API_URL + DataString.uri;
|
||||||
|
// }
|
||||||
|
// });
|
||||||
return {
|
return {
|
||||||
items: data.items,
|
items: data.data,
|
||||||
total: data.total,
|
total: data.total,
|
||||||
total_page: data.total_pages,
|
total_page: data.pages,
|
||||||
page: initParam.page,
|
page: initParam.page,
|
||||||
limit: initParam.limit
|
limit: initParam.limit
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const getTableList = (params: any) => {
|
const getTableList = async (params: any) => {
|
||||||
|
// 获取 getEndpointAllApi 的返回值
|
||||||
|
// const Configs = await getEndpointAllApi();
|
||||||
|
// Endpoints.value = Configs.data.items;
|
||||||
let newParams = JSON.parse(JSON.stringify(params));
|
let newParams = JSON.parse(JSON.stringify(params));
|
||||||
initParam.page = newParams.page;
|
initParam.page = newParams.page;
|
||||||
initParam.limit = newParams.limit;
|
initParam.limit = newParams.limit;
|
||||||
return getVideoList(newParams);
|
return getVideoList(newParams);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
created_at
|
||||||
|
:
|
||||||
|
{$date: {…}}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
// 表格配置项
|
// 表格配置项
|
||||||
const columns = reactive<ColumnProps<VideoList.ResList>[]>([
|
const columns = reactive<ColumnProps<VideoList.ResList>[]>([
|
||||||
{ type: "selection", fixed: "left", width: 50 },
|
{ type: "selection", fixed: "left", width: 50 },
|
||||||
@@ -96,125 +128,207 @@ const columns = reactive<ColumnProps<VideoList.ResList>[]>([
|
|||||||
el: "input"
|
el: "input"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
prop: "sp_id",
|
prop: "v_name",
|
||||||
label: "ID",
|
label: "名称",
|
||||||
width: 100
|
width: 120
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
prop: "sp_name",
|
prop: "v_level",
|
||||||
label: "名称"
|
label: "推荐等级",
|
||||||
},
|
width: 120
|
||||||
{
|
|
||||||
prop: "sp_fengmian_url",
|
|
||||||
label: "视频封面",
|
|
||||||
width: 120,
|
|
||||||
render(scope) {
|
|
||||||
return h(ElImage, {
|
|
||||||
style: "width: 98%; height: 30px; display: flex; align-items: center;",
|
|
||||||
src: scope.row.sp_fengmian_url,
|
|
||||||
previewSrcList: [scope.row.sp_fengmian_url],
|
|
||||||
hideOnClickModal: true,
|
|
||||||
zIndex: 999999999,
|
|
||||||
previewTeleported: true,
|
|
||||||
fit: "cover"
|
|
||||||
});
|
|
||||||
return <img src={scope.row.sp_fengmian_url} alt="视频封面" style="width: 100%; height: auto;" />;
|
|
||||||
return h(AsyncImageComponent, { url: scope.row.sp_fengmian_url });
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: "sp_is_vip",
|
|
||||||
label: "是否VIP",
|
|
||||||
width: 120,
|
|
||||||
fieldNames: { label: "label", value: "value" },
|
|
||||||
search: { el: "select", props: { filterable: true } },
|
|
||||||
enum: arrNoticeSwitch,
|
|
||||||
render(scope) {
|
|
||||||
return (
|
|
||||||
<el-tag type={scope.row.sp_is_vip === 0 ? "danger" : "success"}>{scope.row.sp_is_vip === 0 ? "否" : "是"}</el-tag>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: "sp_tui_jian_shi_jian",
|
|
||||||
label: "是否推荐",
|
|
||||||
width: 120,
|
|
||||||
fieldNames: { label: "label", value: "value" },
|
|
||||||
search: { el: "select", props: { filterable: true } },
|
|
||||||
enum: arrNoticeSwitch,
|
|
||||||
render(scope) {
|
|
||||||
return (
|
|
||||||
<el-tag type={scope.row.sp_tui_jian_shi_jian === 0 ? "danger" : "success"}>
|
|
||||||
{scope.row.sp_tui_jian_shi_jian === 0 ? "否" : "是"}
|
|
||||||
</el-tag>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: "fl_id",
|
|
||||||
label: "分类",
|
|
||||||
width: 120,
|
|
||||||
fieldNames: { label: "fl_mingzi", value: "fl_id" },
|
|
||||||
enum: getFenLeiList,
|
|
||||||
search: { el: "select", props: { filterable: true } }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: "sp_biaoqian",
|
|
||||||
label: "标签",
|
|
||||||
width: 250,
|
|
||||||
render(scope) {
|
|
||||||
if (scope.row.sp_biaoqian) {
|
|
||||||
if (Array.isArray(scope.row.sp_biaoqian)) {
|
|
||||||
return <span>{scope.row.sp_biaoqian.join(", ")}</span>;
|
|
||||||
} else {
|
|
||||||
const data = JSON.parse(scope.row.sp_biaoqian);
|
|
||||||
return <span>{data.join(", ")}</span>;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
prop: "sp_fangwen",
|
prop: "v_name_en",
|
||||||
label: "访问量",
|
label: "拼音",
|
||||||
width: 100
|
width: 120
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
prop: "v_pic",
|
||||||
|
label: "封面",
|
||||||
|
width: 120,
|
||||||
|
|
||||||
|
render(scope) {
|
||||||
|
return <img src={import.meta.env.VITE_API_URL + scope.row.v_pic} alt="封面" style="width: 100%; height: auto;" />;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
prop: "sp_shichang",
|
prop: "v_year",
|
||||||
label: "时长",
|
label: "年份"
|
||||||
width: 100
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
prop: "sp_source_code",
|
prop: "v_lang",
|
||||||
label: "源码",
|
label: "语言"
|
||||||
width: 200
|
|
||||||
},
|
},
|
||||||
{ prop: "created_at", label: "添加时间", width: 170 }
|
{
|
||||||
|
prop: "v_area",
|
||||||
|
label: "地区"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: "v_actor",
|
||||||
|
label: "演员"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: "v_director",
|
||||||
|
label: "导演"
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
prop: "v_parent_category",
|
||||||
|
label: "顶级分类",
|
||||||
|
width: 120
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: "v_category",
|
||||||
|
label: "分类",
|
||||||
|
width: 120
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
prop: "v_description",
|
||||||
|
label: "描述"
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// prop: "n_site_name",
|
||||||
|
// label: "源站"
|
||||||
|
// },
|
||||||
|
|
||||||
|
// { prop: "xsxq_source_code", label: "源码", width: 200 },
|
||||||
|
// { prop: "xsxq_zi_shu", label: "字数", width: 150 },
|
||||||
|
// { prop: "xsxq_jie_shao", label: "描述", width: 200 },
|
||||||
|
// { prop: "xsxq_geng_xin_shi_jian", label: "最后更新时间", width: 170 },
|
||||||
|
// { prop: "created_at", label: "添加时间", width: 170 },
|
||||||
|
{ prop: "v_publish_date", label: "更新时间", width: 170 }
|
||||||
|
// { prop: "operation", label: "操作", fixed: "right", width: 100 }
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// 批量修改视频信息
|
// 删除小说信息
|
||||||
const batchModify = async (id: any[]) => {
|
const deleteAccount = async (params: VideoList.ResList) => {
|
||||||
const ids = id.map((item: VideoList.ResList) => item.sp_id);
|
await useHandleData(deleteItem, { xsxq_id: params.xsxq_id }, "删除所选信息");
|
||||||
await useHandleData(batchData, { sp_id: ids.join(",") }, "批量设置所选信息为每日推荐视频");
|
|
||||||
proTable.value?.clearSelection();
|
|
||||||
proTable.value?.getTableList();
|
proTable.value?.getTableList();
|
||||||
};
|
};
|
||||||
|
|
||||||
// 批量修改视频vip
|
// 批量删除小说信息
|
||||||
const modifyDrawerRef = ref<InstanceType<typeof ModifyDrawer> | null>(null);
|
const batchDelete = async (id: any[]) => {
|
||||||
const batchVipDataBtn = async (id: any[], row: Partial<VideoList.ResList> = {}) => {
|
const ids = id.map((item: VideoList.ResList) => item.xsxq_id);
|
||||||
const ids = id.map((item: VideoList.ResList) => item.sp_id);
|
await useHandleData(deleteItem, { xsxq_id: ids.join(",") }, "删除所选信息");
|
||||||
row.sp_id = ids.join(",");
|
proTable.value?.clearSelection();
|
||||||
const params = {
|
proTable.value?.getTableList();
|
||||||
title: "批量编辑VIP视频",
|
|
||||||
row: { ...row },
|
|
||||||
api: batchVipData,
|
|
||||||
getTableList: proTable.value?.getTableList,
|
|
||||||
clearSelection: proTable.value?.clearSelection
|
|
||||||
};
|
|
||||||
modifyDrawerRef.value?.acceptParams(params as any);
|
|
||||||
};
|
};
|
||||||
|
// 打开 drawer(新增、编辑)
|
||||||
|
const drawerRef = ref<InstanceType<typeof Drawer> | null>(null);
|
||||||
|
const openDrawer = (isEdit: boolean, row: Partial<VideoList.ResList> = {}) => {
|
||||||
|
const params = {
|
||||||
|
title: isEdit ? "新增" : "编辑",
|
||||||
|
row: { ...row },
|
||||||
|
api: saveData,
|
||||||
|
getTableList: proTable.value?.getTableList
|
||||||
|
};
|
||||||
|
drawerRef.value?.acceptParams(params as any);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 批量设置推荐等级
|
||||||
|
const setDrawerRef = ref<InstanceType<typeof SetDrawer> | null>(null);
|
||||||
|
const openSetDrawerRef = (isEdit: boolean, row: Partial<VideoList.ResList> = {}) => {
|
||||||
|
const params = {
|
||||||
|
title: "批量设置等级",
|
||||||
|
row: { ...row },
|
||||||
|
api: setLevel,
|
||||||
|
getTableList: proTable.value?.getTableList
|
||||||
|
};
|
||||||
|
setDrawerRef.value?.acceptParams(params as any);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 批量设置推荐票房
|
||||||
|
const setPfDrawerRef = ref<InstanceType<typeof SetPfDrawer> | null>(null);
|
||||||
|
const openSetPfDrawerRef = (isEdit: boolean, row: Partial<VideoList.ResList> = {}) => {
|
||||||
|
const params = {
|
||||||
|
title: "批量设置票房",
|
||||||
|
row: { ...row },
|
||||||
|
api: setBoxOffice,
|
||||||
|
getTableList: proTable.value?.getTableList
|
||||||
|
};
|
||||||
|
setPfDrawerRef.value?.acceptParams(params as any);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 章节
|
||||||
|
const chapterDrawerRef = ref<InstanceType<typeof ChapterDrawer> | null>(null);
|
||||||
|
const openChapterDrawer = (row: Partial<VideoList.ResList> = {}) => {
|
||||||
|
chapterDrawerRef.value?.acceptParams(row.xsxq_id!);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 异步加载图片组件
|
||||||
|
const AsyncImageComponent = defineComponent({
|
||||||
|
props: {
|
||||||
|
url: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setup(props) {
|
||||||
|
const imageUrl = ref("");
|
||||||
|
const isLoading = ref(true);
|
||||||
|
const error = ref(null);
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
try {
|
||||||
|
const data = await fetchImageData(props.url);
|
||||||
|
const decodedImage = decode(data);
|
||||||
|
imageUrl.value = decodedImage;
|
||||||
|
isLoading.value = false;
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Error converting image to base64:", err);
|
||||||
|
error.value = err;
|
||||||
|
isLoading.value = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
if (isLoading.value) {
|
||||||
|
return h("el-image", { src: "Loading..." });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error.value) {
|
||||||
|
return h("el-image", { src: "无法加载" });
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<el-image
|
||||||
|
style="width: 98%; height: 30px;display: flex;align-items: center;"
|
||||||
|
src={imageUrl.value}
|
||||||
|
preview-src-list={[imageUrl.value]}
|
||||||
|
hide-on-click-modal={true}
|
||||||
|
z-index={999999999}
|
||||||
|
preview-teleported={true}
|
||||||
|
// fit="contain"
|
||||||
|
fit="cover"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 获取图片数据
|
||||||
|
async function fetchImageData(url) {
|
||||||
|
const response = await fetch(url);
|
||||||
|
const data = await response.arrayBuffer();
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解码图片函数
|
||||||
|
function decode(data, key = 0x88) {
|
||||||
|
let binary = "";
|
||||||
|
let bytes = new Uint8Array(data);
|
||||||
|
let len = bytes.byteLength;
|
||||||
|
for (let i = 0; i < len; i++) {
|
||||||
|
binary += String.fromCharCode(bytes[i] ^ key);
|
||||||
|
}
|
||||||
|
let src = window.btoa(binary);
|
||||||
|
let image = "data:image/jpeg;base64," + src;
|
||||||
|
return image;
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@@ -228,4 +342,8 @@ const batchVipDataBtn = async (id: any[], row: Partial<VideoList.ResList> = {})
|
|||||||
.el-table .success-row .el-table-fixed-column--left {
|
.el-table .success-row .el-table-fixed-column--left {
|
||||||
background-color: var(--el-color-success-light-9);
|
background-color: var(--el-color-success-light-9);
|
||||||
}
|
}
|
||||||
|
.tag {
|
||||||
|
margin-right: 10px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
366
src/views/video/setDrawer.vue
Normal file
366
src/views/video/setDrawer.vue
Normal file
@@ -0,0 +1,366 @@
|
|||||||
|
<template>
|
||||||
|
<el-drawer v-model="drawerVisible" :destroy-on-close="true" size="720" :title="`${drawerProps.title}`">
|
||||||
|
<el-form
|
||||||
|
ref="ruleFormRef"
|
||||||
|
label-width="150px"
|
||||||
|
label-suffix=" :"
|
||||||
|
:rules="rules"
|
||||||
|
:disabled="drawerProps.isView"
|
||||||
|
:model="drawerProps.row"
|
||||||
|
:hide-required-asterisk="drawerProps.isView"
|
||||||
|
>
|
||||||
|
<el-form-item v-for="e in formColumns" :key="e.label" :label="e.label" :prop="e.prop" :required="e.required">
|
||||||
|
<!-- <template v-if="e.type === 'switch'">
|
||||||
|
<el-switch
|
||||||
|
v-model="e.value"
|
||||||
|
:active-value="`${1}`"
|
||||||
|
:inactive-value="`${0}`"
|
||||||
|
active-text="上架"
|
||||||
|
inactive-text="下架"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template v-if="e.type === 'switch-index'">
|
||||||
|
<el-switch
|
||||||
|
v-model="e.value"
|
||||||
|
:active-value="`${1}`"
|
||||||
|
:inactive-value="`${0}`"
|
||||||
|
active-text="是"
|
||||||
|
inactive-text="否"
|
||||||
|
/>
|
||||||
|
</template> -->
|
||||||
|
<!-- <template v-if="e.type === 'radio'">
|
||||||
|
<el-radio-group v-model="e.value" class="ml-4">
|
||||||
|
<el-radio v-for="item in e.options" :key="item.value" :value="item.value" size="large">{{
|
||||||
|
item.label
|
||||||
|
}}</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</template>
|
||||||
|
<template v-if="e.type === 'select'">
|
||||||
|
<el-select filterable v-model="e.value" :placeholder="`请选择${e.label}`" clearable>
|
||||||
|
<el-option
|
||||||
|
v-for="(item, index) in e.options"
|
||||||
|
:key="index"
|
||||||
|
:label="getField(item, e.fieldNames?.label)"
|
||||||
|
:value="getField(item, e.fieldNames?.value)"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</template> -->
|
||||||
|
<template v-if="e.type === 'text'">
|
||||||
|
<el-input v-model="e.value" :placeholder="`请输入${e.label},多个使用, 分割`" clearable></el-input>
|
||||||
|
</template>
|
||||||
|
<template v-if="e.type === 'text-i'">
|
||||||
|
<el-input v-model="e.value" :placeholder="`请输入${e.label}`" clearable></el-input>
|
||||||
|
</template>
|
||||||
|
<template v-if="e.type === 'text-num'">
|
||||||
|
<el-input v-model="e.value" type="number" :placeholder="`请输入${e.label}`" clearable></el-input>
|
||||||
|
</template>
|
||||||
|
<template v-if="e.type === 'textarea'">
|
||||||
|
<el-input
|
||||||
|
type="textarea"
|
||||||
|
:rows="20"
|
||||||
|
v-model="e.value"
|
||||||
|
maxlength="365000"
|
||||||
|
:placeholder="`请输入${e.label},多个使用, 分割`"
|
||||||
|
show-word-limit
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<!-- <template v-if="e.type === 'tag'">
|
||||||
|
<div class="tag-more-s">
|
||||||
|
<el-input
|
||||||
|
v-model="drawerProps.row.searchText"
|
||||||
|
placeholder="请输入搜索内容"
|
||||||
|
clearable
|
||||||
|
@input="handleSearch"
|
||||||
|
/>
|
||||||
|
<div>
|
||||||
|
<span>选中标签:</span>
|
||||||
|
<div class="tag-more-h">
|
||||||
|
<el-checkbox-group v-model="TagList" @change="placeableCheckedCitiesChange">
|
||||||
|
<el-checkbox-button
|
||||||
|
class="vip-power"
|
||||||
|
v-for="item in matchingObjects"
|
||||||
|
:value="item.t_id"
|
||||||
|
:key="item.t_id"
|
||||||
|
>
|
||||||
|
{{ item.t_name }}
|
||||||
|
</el-checkbox-button>
|
||||||
|
</el-checkbox-group>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span>未选中标签:</span>
|
||||||
|
<div class="tag-more-h">
|
||||||
|
<el-checkbox-group v-model="TagList" @change="placeableCheckedCitiesChange">
|
||||||
|
<el-checkbox-button
|
||||||
|
class="vip-power"
|
||||||
|
v-for="item in nonMatchingObjects"
|
||||||
|
:value="item.t_id"
|
||||||
|
:key="item.t_id"
|
||||||
|
>
|
||||||
|
{{ item.t_name }}
|
||||||
|
</el-checkbox-button>
|
||||||
|
</el-checkbox-group>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template> -->
|
||||||
|
<!-- <template v-if="e.type === 'text-i'">
|
||||||
|
<UploadImg disabled v-model:image-url="drawerProps.row!.n_cover" width="135px" height="135px" :file-size="3">
|
||||||
|
<template #empty>
|
||||||
|
<el-icon><Avatar /></el-icon>
|
||||||
|
<span>请上传封面</span>
|
||||||
|
</template>
|
||||||
|
</UploadImg>
|
||||||
|
</template> -->
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="drawerVisible = false">取消</el-button>
|
||||||
|
<el-button v-show="!drawerProps.isView" type="primary" @click="handleSubmit">确定</el-button>
|
||||||
|
</template>
|
||||||
|
</el-drawer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts" name="UserDrawer">
|
||||||
|
import { ref, computed, reactive } from "vue";
|
||||||
|
import { ElMessage, FormInstance } from "element-plus";
|
||||||
|
// import { NovelList } from "@/api/interface/novel/list";
|
||||||
|
import { arrNovelType } from "@/utils/serviceDict";
|
||||||
|
// import { getTypeList } from "@/api/modules/tag/list";
|
||||||
|
// import UploadImg from "@/components/Upload/Img.vue";
|
||||||
|
import { extractURI } from "@/utils/eleValidate";
|
||||||
|
type Options = {
|
||||||
|
label: string;
|
||||||
|
value: string | number;
|
||||||
|
};
|
||||||
|
|
||||||
|
interface Item {
|
||||||
|
t_id: any;
|
||||||
|
uri: any;
|
||||||
|
}
|
||||||
|
// const getField = (item: any, fieldName: string | undefined) => {
|
||||||
|
// return fieldName ? item[fieldName] : "";
|
||||||
|
// };
|
||||||
|
type Fields = {
|
||||||
|
label: string;
|
||||||
|
prop: string;
|
||||||
|
type: string;
|
||||||
|
value: any;
|
||||||
|
required: boolean;
|
||||||
|
options?: Options[];
|
||||||
|
fieldNames?: { label: string; value: string };
|
||||||
|
};
|
||||||
|
const generateRules = (fields: Fields[]) => {
|
||||||
|
return fields.reduce(
|
||||||
|
(acc, field) => {
|
||||||
|
const { type, required, label, prop } = field;
|
||||||
|
let message = "";
|
||||||
|
|
||||||
|
if (type === "text") {
|
||||||
|
message = `请输入${label}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === "text-num") {
|
||||||
|
message = `请输入${label}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
acc[prop] = [{ required, message }];
|
||||||
|
return acc;
|
||||||
|
},
|
||||||
|
{} as Record<string, any>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const TagList = ref([] as any);
|
||||||
|
const arrTagList = ref([] as any);
|
||||||
|
const arrNewTagList = ref([] as any);
|
||||||
|
const matchingObjects = ref([] as any); //选中相同
|
||||||
|
const nonMatchingObjects = ref([] as any); //没有选中的
|
||||||
|
const matchingObjectsA = ref([] as any); //选中相同
|
||||||
|
const nonMatchingObjectsB = ref([] as any); //没有选中的
|
||||||
|
// const getTagList = async () => {
|
||||||
|
// try {
|
||||||
|
// const initParam = reactive({
|
||||||
|
// t_type: 3,
|
||||||
|
// limit: 3650,
|
||||||
|
// page: 1,
|
||||||
|
// t_hidden: 1
|
||||||
|
// });
|
||||||
|
// const siteRes = await getTypeList(initParam);
|
||||||
|
// arrTagList.value = siteRes.data.item;
|
||||||
|
// arrNewTagList.value = siteRes.data.item;
|
||||||
|
// matchingObjects.value = [];
|
||||||
|
// matchingObjectsA.value = [];
|
||||||
|
// // 遍历第一个数组的每个元素
|
||||||
|
// TagList.value.forEach(index => {
|
||||||
|
// // 遍历第二个数组的每个元素
|
||||||
|
// arrNewTagList.value.forEach(obj => {
|
||||||
|
// // 如果第二个数组中的元素的t_id与第一个数组中的元素相同,则将其添加到新数组中
|
||||||
|
// if (obj.t_id === index) {
|
||||||
|
// matchingObjects.value = [...matchingObjects.value, obj];
|
||||||
|
// matchingObjectsA.value = [...matchingObjectsA.value, obj];
|
||||||
|
// const matchingIds = matchingObjectsA.value.map(obj => obj.t_id);
|
||||||
|
// TagList.value = matchingIds;
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
// // 创建一个新数组,包含objectArray中id不存在于arrayA的元素
|
||||||
|
// nonMatchingObjects.value = arrNewTagList.value.filter(obj => !TagList.value.includes(obj.t_id));
|
||||||
|
// nonMatchingObjectsB.value = arrNewTagList.value.filter(obj => !TagList.value.includes(obj.t_id));
|
||||||
|
// } catch (error) {
|
||||||
|
// console.log(error);
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
|
||||||
|
// 处理搜索事件
|
||||||
|
function handleSearch() {
|
||||||
|
// 在输入事件中实时更新过滤后的标签列表
|
||||||
|
filteredTagList();
|
||||||
|
}
|
||||||
|
function filteredTagList() {
|
||||||
|
if (drawerProps.value.row!.searchText.length > 0) {
|
||||||
|
let arrData = arrTagList.value.filter(tag =>
|
||||||
|
tag.t_name.toLowerCase().includes(drawerProps.value.row!.searchText.toLowerCase())
|
||||||
|
);
|
||||||
|
if (arrData.length > 0) {
|
||||||
|
matchingObjects.value = matchingObjects.value.filter(objA => arrData.some(objB => objB.t_id === objA.t_id));
|
||||||
|
nonMatchingObjects.value = nonMatchingObjects.value.filter(objA => arrData.some(objB => objB.t_id === objA.t_id));
|
||||||
|
} else {
|
||||||
|
matchingObjects.value = [];
|
||||||
|
nonMatchingObjects.value = [];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
matchingObjects.value = matchingObjectsA.value;
|
||||||
|
nonMatchingObjects.value = nonMatchingObjectsB.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//标签数组
|
||||||
|
async function placeableCheckedCitiesChange(value) {
|
||||||
|
matchingObjects.value = [];
|
||||||
|
matchingObjectsA.value = [];
|
||||||
|
drawerProps.value.row.n_tags = value;
|
||||||
|
// 遍历第一个数组的每个元素
|
||||||
|
TagList.value.forEach(index => {
|
||||||
|
// 遍历第二个数组的每个元素
|
||||||
|
arrNewTagList.value.forEach(obj => {
|
||||||
|
// 如果第二个数组中的元素的t_id与第一个数组中的元素相同,则将其添加到新数组中
|
||||||
|
if (obj.t_id === index) {
|
||||||
|
matchingObjects.value = [...matchingObjects.value, obj];
|
||||||
|
matchingObjectsA.value = [...matchingObjectsA.value, obj];
|
||||||
|
const matchingIds = matchingObjectsA.value.map(obj => obj.t_id);
|
||||||
|
TagList.value = matchingIds;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
nonMatchingObjects.value = arrNewTagList.value.filter(obj => !TagList.value.includes(obj.t_id));
|
||||||
|
nonMatchingObjectsB.value = arrNewTagList.value.filter(obj => !TagList.value.includes(obj.t_id));
|
||||||
|
}
|
||||||
|
const formColumns = computed((): Fields[] => {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
label: "推荐等级",
|
||||||
|
prop: "v_level",
|
||||||
|
type: "text-num",
|
||||||
|
get value() {
|
||||||
|
return drawerProps.value.row!.v_level;
|
||||||
|
},
|
||||||
|
set value(val) {
|
||||||
|
drawerProps.value.row!.v_level = val;
|
||||||
|
},
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "视频名字",
|
||||||
|
prop: "keywords",
|
||||||
|
type: "textarea",
|
||||||
|
get value() {
|
||||||
|
return drawerProps.value.row!.keywords;
|
||||||
|
},
|
||||||
|
set value(val) {
|
||||||
|
drawerProps.value.row!.keywords = val;
|
||||||
|
},
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
];
|
||||||
|
});
|
||||||
|
const rules = ref();
|
||||||
|
|
||||||
|
interface DrawerProps {
|
||||||
|
title: string;
|
||||||
|
isView: boolean;
|
||||||
|
row: Partial<NovelList.ResList>;
|
||||||
|
api?: (params: any) => Promise<any>;
|
||||||
|
getTableList?: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const drawerVisible = ref(false);
|
||||||
|
const drawerProps = ref<DrawerProps>({
|
||||||
|
isView: false,
|
||||||
|
title: "",
|
||||||
|
row: {}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 接收父组件传过来的参数
|
||||||
|
const acceptParams = (params: DrawerProps) => {
|
||||||
|
drawerProps.value = params;
|
||||||
|
rules.value = generateRules(formColumns.value);
|
||||||
|
drawerVisible.value = true;
|
||||||
|
TagList.value = [];
|
||||||
|
if (drawerProps.value.title === "新增小说") {
|
||||||
|
drawerProps.value.row!.n_type = 0;
|
||||||
|
}
|
||||||
|
if (drawerProps.value.row.n_cover) {
|
||||||
|
drawerProps.value.row.n_cover_code = drawerProps.value.row.n_cover.code;
|
||||||
|
drawerProps.value.row.n_cover = drawerProps.value.row.n_cover_detail;
|
||||||
|
}
|
||||||
|
if (drawerProps.value.row.n_tags) {
|
||||||
|
TagList.value = drawerProps.value.row.n_tags.map((obj: Item) => obj.t_id).map(Number);
|
||||||
|
}
|
||||||
|
// getTagList();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 提交数据(新增/编辑)
|
||||||
|
const ruleFormRef = ref<FormInstance>();
|
||||||
|
const handleSubmit = () => {
|
||||||
|
ruleFormRef.value!.validate(async valid => {
|
||||||
|
if (!valid) return;
|
||||||
|
try {
|
||||||
|
const params = { ...drawerProps.value.row };
|
||||||
|
// let arrData = {
|
||||||
|
// uri: extractURI(params.n_cover),
|
||||||
|
// code: params.n_cover_code
|
||||||
|
// };
|
||||||
|
|
||||||
|
// params.n_cover = arrData;
|
||||||
|
// params.n_tags = TagList.value;
|
||||||
|
await drawerProps.value.api!(params);
|
||||||
|
ElMessage.success({ message: `${drawerProps.value.title}成功!` });
|
||||||
|
drawerProps.value.getTableList!();
|
||||||
|
drawerVisible.value = false;
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
acceptParams
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<style lang="scss">
|
||||||
|
.el-checkbox-button__inner {
|
||||||
|
margin-right: 10px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
border-left-color: #dcdfe6 !important;
|
||||||
|
}
|
||||||
|
.tag-more-h {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
.tag-more-s {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px;
|
||||||
|
border: 1px solid black;
|
||||||
|
box-shadow: 0 0 4px 2px rgb(0 0 0 / 90%);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
366
src/views/video/setPfDrawer.vue
Normal file
366
src/views/video/setPfDrawer.vue
Normal file
@@ -0,0 +1,366 @@
|
|||||||
|
<template>
|
||||||
|
<el-drawer v-model="drawerVisible" :destroy-on-close="true" size="720" :title="`${drawerProps.title}`">
|
||||||
|
<el-form
|
||||||
|
ref="ruleFormRef"
|
||||||
|
label-width="150px"
|
||||||
|
label-suffix=" :"
|
||||||
|
:rules="rules"
|
||||||
|
:disabled="drawerProps.isView"
|
||||||
|
:model="drawerProps.row"
|
||||||
|
:hide-required-asterisk="drawerProps.isView"
|
||||||
|
>
|
||||||
|
<el-form-item v-for="e in formColumns" :key="e.label" :label="e.label" :prop="e.prop" :required="e.required">
|
||||||
|
<!-- <template v-if="e.type === 'switch'">
|
||||||
|
<el-switch
|
||||||
|
v-model="e.value"
|
||||||
|
:active-value="`${1}`"
|
||||||
|
:inactive-value="`${0}`"
|
||||||
|
active-text="上架"
|
||||||
|
inactive-text="下架"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template v-if="e.type === 'switch-index'">
|
||||||
|
<el-switch
|
||||||
|
v-model="e.value"
|
||||||
|
:active-value="`${1}`"
|
||||||
|
:inactive-value="`${0}`"
|
||||||
|
active-text="是"
|
||||||
|
inactive-text="否"
|
||||||
|
/>
|
||||||
|
</template> -->
|
||||||
|
<!-- <template v-if="e.type === 'radio'">
|
||||||
|
<el-radio-group v-model="e.value" class="ml-4">
|
||||||
|
<el-radio v-for="item in e.options" :key="item.value" :value="item.value" size="large">{{
|
||||||
|
item.label
|
||||||
|
}}</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</template>
|
||||||
|
<template v-if="e.type === 'select'">
|
||||||
|
<el-select filterable v-model="e.value" :placeholder="`请选择${e.label}`" clearable>
|
||||||
|
<el-option
|
||||||
|
v-for="(item, index) in e.options"
|
||||||
|
:key="index"
|
||||||
|
:label="getField(item, e.fieldNames?.label)"
|
||||||
|
:value="getField(item, e.fieldNames?.value)"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</template> -->
|
||||||
|
<template v-if="e.type === 'text'">
|
||||||
|
<el-input v-model="e.value" :placeholder="`请输入${e.label},多个使用, 分割`" clearable></el-input>
|
||||||
|
</template>
|
||||||
|
<template v-if="e.type === 'text-i'">
|
||||||
|
<el-input v-model="e.value" :placeholder="`请输入${e.label}`" clearable></el-input>
|
||||||
|
</template>
|
||||||
|
<template v-if="e.type === 'text-num'">
|
||||||
|
<el-input v-model="e.value" type="number" :placeholder="`请输入${e.label}`" clearable></el-input>
|
||||||
|
</template>
|
||||||
|
<template v-if="e.type === 'textarea'">
|
||||||
|
<el-input
|
||||||
|
type="textarea"
|
||||||
|
:rows="20"
|
||||||
|
v-model="e.value"
|
||||||
|
maxlength="365000"
|
||||||
|
:placeholder="`请输入${e.label},多个使用, 分割`"
|
||||||
|
show-word-limit
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<!-- <template v-if="e.type === 'tag'">
|
||||||
|
<div class="tag-more-s">
|
||||||
|
<el-input
|
||||||
|
v-model="drawerProps.row.searchText"
|
||||||
|
placeholder="请输入搜索内容"
|
||||||
|
clearable
|
||||||
|
@input="handleSearch"
|
||||||
|
/>
|
||||||
|
<div>
|
||||||
|
<span>选中标签:</span>
|
||||||
|
<div class="tag-more-h">
|
||||||
|
<el-checkbox-group v-model="TagList" @change="placeableCheckedCitiesChange">
|
||||||
|
<el-checkbox-button
|
||||||
|
class="vip-power"
|
||||||
|
v-for="item in matchingObjects"
|
||||||
|
:value="item.t_id"
|
||||||
|
:key="item.t_id"
|
||||||
|
>
|
||||||
|
{{ item.t_name }}
|
||||||
|
</el-checkbox-button>
|
||||||
|
</el-checkbox-group>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span>未选中标签:</span>
|
||||||
|
<div class="tag-more-h">
|
||||||
|
<el-checkbox-group v-model="TagList" @change="placeableCheckedCitiesChange">
|
||||||
|
<el-checkbox-button
|
||||||
|
class="vip-power"
|
||||||
|
v-for="item in nonMatchingObjects"
|
||||||
|
:value="item.t_id"
|
||||||
|
:key="item.t_id"
|
||||||
|
>
|
||||||
|
{{ item.t_name }}
|
||||||
|
</el-checkbox-button>
|
||||||
|
</el-checkbox-group>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template> -->
|
||||||
|
<!-- <template v-if="e.type === 'text-i'">
|
||||||
|
<UploadImg disabled v-model:image-url="drawerProps.row!.n_cover" width="135px" height="135px" :file-size="3">
|
||||||
|
<template #empty>
|
||||||
|
<el-icon><Avatar /></el-icon>
|
||||||
|
<span>请上传封面</span>
|
||||||
|
</template>
|
||||||
|
</UploadImg>
|
||||||
|
</template> -->
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="drawerVisible = false">取消</el-button>
|
||||||
|
<el-button v-show="!drawerProps.isView" type="primary" @click="handleSubmit">确定</el-button>
|
||||||
|
</template>
|
||||||
|
</el-drawer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts" name="UserDrawer">
|
||||||
|
import { ref, computed, reactive } from "vue";
|
||||||
|
import { ElMessage, FormInstance } from "element-plus";
|
||||||
|
// import { NovelList } from "@/api/interface/novel/list";
|
||||||
|
import { arrNovelType } from "@/utils/serviceDict";
|
||||||
|
// import { getTypeList } from "@/api/modules/tag/list";
|
||||||
|
// import UploadImg from "@/components/Upload/Img.vue";
|
||||||
|
import { extractURI } from "@/utils/eleValidate";
|
||||||
|
type Options = {
|
||||||
|
label: string;
|
||||||
|
value: string | number;
|
||||||
|
};
|
||||||
|
|
||||||
|
interface Item {
|
||||||
|
t_id: any;
|
||||||
|
uri: any;
|
||||||
|
}
|
||||||
|
// const getField = (item: any, fieldName: string | undefined) => {
|
||||||
|
// return fieldName ? item[fieldName] : "";
|
||||||
|
// };
|
||||||
|
type Fields = {
|
||||||
|
label: string;
|
||||||
|
prop: string;
|
||||||
|
type: string;
|
||||||
|
value: any;
|
||||||
|
required: boolean;
|
||||||
|
options?: Options[];
|
||||||
|
fieldNames?: { label: string; value: string };
|
||||||
|
};
|
||||||
|
const generateRules = (fields: Fields[]) => {
|
||||||
|
return fields.reduce(
|
||||||
|
(acc, field) => {
|
||||||
|
const { type, required, label, prop } = field;
|
||||||
|
let message = "";
|
||||||
|
|
||||||
|
if (type === "text") {
|
||||||
|
message = `请输入${label}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === "text-num") {
|
||||||
|
message = `请输入${label}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
acc[prop] = [{ required, message }];
|
||||||
|
return acc;
|
||||||
|
},
|
||||||
|
{} as Record<string, any>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const TagList = ref([] as any);
|
||||||
|
const arrTagList = ref([] as any);
|
||||||
|
const arrNewTagList = ref([] as any);
|
||||||
|
const matchingObjects = ref([] as any); //选中相同
|
||||||
|
const nonMatchingObjects = ref([] as any); //没有选中的
|
||||||
|
const matchingObjectsA = ref([] as any); //选中相同
|
||||||
|
const nonMatchingObjectsB = ref([] as any); //没有选中的
|
||||||
|
// const getTagList = async () => {
|
||||||
|
// try {
|
||||||
|
// const initParam = reactive({
|
||||||
|
// t_type: 3,
|
||||||
|
// limit: 3650,
|
||||||
|
// page: 1,
|
||||||
|
// t_hidden: 1
|
||||||
|
// });
|
||||||
|
// const siteRes = await getTypeList(initParam);
|
||||||
|
// arrTagList.value = siteRes.data.item;
|
||||||
|
// arrNewTagList.value = siteRes.data.item;
|
||||||
|
// matchingObjects.value = [];
|
||||||
|
// matchingObjectsA.value = [];
|
||||||
|
// // 遍历第一个数组的每个元素
|
||||||
|
// TagList.value.forEach(index => {
|
||||||
|
// // 遍历第二个数组的每个元素
|
||||||
|
// arrNewTagList.value.forEach(obj => {
|
||||||
|
// // 如果第二个数组中的元素的t_id与第一个数组中的元素相同,则将其添加到新数组中
|
||||||
|
// if (obj.t_id === index) {
|
||||||
|
// matchingObjects.value = [...matchingObjects.value, obj];
|
||||||
|
// matchingObjectsA.value = [...matchingObjectsA.value, obj];
|
||||||
|
// const matchingIds = matchingObjectsA.value.map(obj => obj.t_id);
|
||||||
|
// TagList.value = matchingIds;
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
// // 创建一个新数组,包含objectArray中id不存在于arrayA的元素
|
||||||
|
// nonMatchingObjects.value = arrNewTagList.value.filter(obj => !TagList.value.includes(obj.t_id));
|
||||||
|
// nonMatchingObjectsB.value = arrNewTagList.value.filter(obj => !TagList.value.includes(obj.t_id));
|
||||||
|
// } catch (error) {
|
||||||
|
// console.log(error);
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
|
||||||
|
// 处理搜索事件
|
||||||
|
function handleSearch() {
|
||||||
|
// 在输入事件中实时更新过滤后的标签列表
|
||||||
|
filteredTagList();
|
||||||
|
}
|
||||||
|
function filteredTagList() {
|
||||||
|
if (drawerProps.value.row!.searchText.length > 0) {
|
||||||
|
let arrData = arrTagList.value.filter(tag =>
|
||||||
|
tag.t_name.toLowerCase().includes(drawerProps.value.row!.searchText.toLowerCase())
|
||||||
|
);
|
||||||
|
if (arrData.length > 0) {
|
||||||
|
matchingObjects.value = matchingObjects.value.filter(objA => arrData.some(objB => objB.t_id === objA.t_id));
|
||||||
|
nonMatchingObjects.value = nonMatchingObjects.value.filter(objA => arrData.some(objB => objB.t_id === objA.t_id));
|
||||||
|
} else {
|
||||||
|
matchingObjects.value = [];
|
||||||
|
nonMatchingObjects.value = [];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
matchingObjects.value = matchingObjectsA.value;
|
||||||
|
nonMatchingObjects.value = nonMatchingObjectsB.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//标签数组
|
||||||
|
async function placeableCheckedCitiesChange(value) {
|
||||||
|
matchingObjects.value = [];
|
||||||
|
matchingObjectsA.value = [];
|
||||||
|
drawerProps.value.row.n_tags = value;
|
||||||
|
// 遍历第一个数组的每个元素
|
||||||
|
TagList.value.forEach(index => {
|
||||||
|
// 遍历第二个数组的每个元素
|
||||||
|
arrNewTagList.value.forEach(obj => {
|
||||||
|
// 如果第二个数组中的元素的t_id与第一个数组中的元素相同,则将其添加到新数组中
|
||||||
|
if (obj.t_id === index) {
|
||||||
|
matchingObjects.value = [...matchingObjects.value, obj];
|
||||||
|
matchingObjectsA.value = [...matchingObjectsA.value, obj];
|
||||||
|
const matchingIds = matchingObjectsA.value.map(obj => obj.t_id);
|
||||||
|
TagList.value = matchingIds;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
nonMatchingObjects.value = arrNewTagList.value.filter(obj => !TagList.value.includes(obj.t_id));
|
||||||
|
nonMatchingObjectsB.value = arrNewTagList.value.filter(obj => !TagList.value.includes(obj.t_id));
|
||||||
|
}
|
||||||
|
const formColumns = computed((): Fields[] => {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
label: "票房",
|
||||||
|
prop: "v_box_office",
|
||||||
|
type: "text-num",
|
||||||
|
get value() {
|
||||||
|
return drawerProps.value.row!.v_box_office;
|
||||||
|
},
|
||||||
|
set value(val) {
|
||||||
|
drawerProps.value.row!.v_box_office = val;
|
||||||
|
},
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "视频名字",
|
||||||
|
prop: "keywords",
|
||||||
|
type: "textarea",
|
||||||
|
get value() {
|
||||||
|
return drawerProps.value.row!.keywords;
|
||||||
|
},
|
||||||
|
set value(val) {
|
||||||
|
drawerProps.value.row!.keywords = val;
|
||||||
|
},
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
];
|
||||||
|
});
|
||||||
|
const rules = ref();
|
||||||
|
|
||||||
|
interface DrawerProps {
|
||||||
|
title: string;
|
||||||
|
isView: boolean;
|
||||||
|
row: Partial<NovelList.ResList>;
|
||||||
|
api?: (params: any) => Promise<any>;
|
||||||
|
getTableList?: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const drawerVisible = ref(false);
|
||||||
|
const drawerProps = ref<DrawerProps>({
|
||||||
|
isView: false,
|
||||||
|
title: "",
|
||||||
|
row: {}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 接收父组件传过来的参数
|
||||||
|
const acceptParams = (params: DrawerProps) => {
|
||||||
|
drawerProps.value = params;
|
||||||
|
rules.value = generateRules(formColumns.value);
|
||||||
|
drawerVisible.value = true;
|
||||||
|
TagList.value = [];
|
||||||
|
if (drawerProps.value.title === "新增") {
|
||||||
|
drawerProps.value.row!.n_type = 0;
|
||||||
|
}
|
||||||
|
if (drawerProps.value.row.n_cover) {
|
||||||
|
drawerProps.value.row.n_cover_code = drawerProps.value.row.n_cover.code;
|
||||||
|
drawerProps.value.row.n_cover = drawerProps.value.row.n_cover_detail;
|
||||||
|
}
|
||||||
|
if (drawerProps.value.row.n_tags) {
|
||||||
|
TagList.value = drawerProps.value.row.n_tags.map((obj: Item) => obj.t_id).map(Number);
|
||||||
|
}
|
||||||
|
// getTagList();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 提交数据(新增/编辑)
|
||||||
|
const ruleFormRef = ref<FormInstance>();
|
||||||
|
const handleSubmit = () => {
|
||||||
|
ruleFormRef.value!.validate(async valid => {
|
||||||
|
if (!valid) return;
|
||||||
|
try {
|
||||||
|
const params = { ...drawerProps.value.row };
|
||||||
|
// let arrData = {
|
||||||
|
// uri: extractURI(params.n_cover),
|
||||||
|
// code: params.n_cover_code
|
||||||
|
// };
|
||||||
|
|
||||||
|
// params.n_cover = arrData;
|
||||||
|
// params.n_tags = TagList.value;
|
||||||
|
await drawerProps.value.api!(params);
|
||||||
|
ElMessage.success({ message: `${drawerProps.value.title}成功!` });
|
||||||
|
drawerProps.value.getTableList!();
|
||||||
|
drawerVisible.value = false;
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
acceptParams
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<style lang="scss">
|
||||||
|
.el-checkbox-button__inner {
|
||||||
|
margin-right: 10px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
border-left-color: #dcdfe6 !important;
|
||||||
|
}
|
||||||
|
.tag-more-h {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
.tag-more-s {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px;
|
||||||
|
border: 1px solid black;
|
||||||
|
box-shadow: 0 0 4px 2px rgb(0 0 0 / 90%);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
<el-drawer v-model="drawerVisible" :destroy-on-close="true" size="720" :title="`${drawerProps.title}`">
|
<el-drawer v-model="drawerVisible" :destroy-on-close="true" size="720" :title="`${drawerProps.title}`">
|
||||||
<el-form
|
<el-form
|
||||||
ref="ruleFormRef"
|
ref="ruleFormRef"
|
||||||
label-width="60px"
|
label-width="90px"
|
||||||
label-suffix=" :"
|
label-suffix=" :"
|
||||||
:rules="rules"
|
:rules="rules"
|
||||||
:disabled="drawerProps.isView"
|
:disabled="drawerProps.isView"
|
||||||
@@ -15,19 +15,19 @@
|
|||||||
v-model="e.value"
|
v-model="e.value"
|
||||||
:active-value="`${1}`"
|
:active-value="`${1}`"
|
||||||
:inactive-value="`${0}`"
|
:inactive-value="`${0}`"
|
||||||
active-text="显示"
|
active-text="上架"
|
||||||
inactive-text="隐藏"
|
inactive-text="下架"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="e.type === 'radio'">
|
<template v-if="e.type === 'radio'">
|
||||||
<el-radio-group v-model="e.value" class="ml-4">
|
<el-radio-group v-model="e.value" class="ml-4">
|
||||||
<el-radio v-for="item in e.options" :key="item.value" :label="item.value" size="large">{{
|
<el-radio v-for="item in e.options" :key="item.value" :value="item.value" size="large">{{
|
||||||
item.label
|
item.label
|
||||||
}}</el-radio>
|
}}</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="e.type === 'select'">
|
<template v-if="e.type === 'select'">
|
||||||
<el-select filterable v-model="e.value" :placeholder="`请选择${e.label}`" clearable>
|
<el-select filterable multiple v-model="e.value" :placeholder="`请选择${e.label}`" clearable>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="(item, index) in e.options"
|
v-for="(item, index) in e.options"
|
||||||
:key="index"
|
:key="index"
|
||||||
@@ -39,6 +39,9 @@
|
|||||||
<template v-if="e.type === 'text'">
|
<template v-if="e.type === 'text'">
|
||||||
<el-input v-model="e.value" :placeholder="`请输入${e.label}`" clearable></el-input>
|
<el-input v-model="e.value" :placeholder="`请输入${e.label}`" clearable></el-input>
|
||||||
</template>
|
</template>
|
||||||
|
<template v-if="e.type === 'text-i'">
|
||||||
|
<el-input v-model="e.value" :placeholder="`请输入${e.label}`" clearable></el-input>
|
||||||
|
</template>
|
||||||
<template v-if="e.type === 'text-num'">
|
<template v-if="e.type === 'text-num'">
|
||||||
<el-input v-model="e.value" type="number" :placeholder="`请输入${e.label}`" clearable></el-input>
|
<el-input v-model="e.value" type="number" :placeholder="`请输入${e.label}`" clearable></el-input>
|
||||||
</template>
|
</template>
|
||||||
@@ -46,11 +49,60 @@
|
|||||||
<el-input
|
<el-input
|
||||||
type="textarea"
|
type="textarea"
|
||||||
v-model="e.value"
|
v-model="e.value"
|
||||||
|
:rows="5"
|
||||||
maxlength="3650"
|
maxlength="3650"
|
||||||
:placeholder="`请输入${e.label}`"
|
:placeholder="`请输入${e.label}`"
|
||||||
show-word-limit
|
show-word-limit
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
<template v-if="e.type === 'text-i'">
|
||||||
|
<UploadImg disabled v-model:image-url="drawerProps.row!.v_cover" width="135px" height="135px" :file-size="3">
|
||||||
|
<template #empty>
|
||||||
|
<el-icon><Avatar /></el-icon>
|
||||||
|
<span>请上传封面</span>
|
||||||
|
</template>
|
||||||
|
</UploadImg>
|
||||||
|
</template>
|
||||||
|
<template v-if="e.type === 'tag'">
|
||||||
|
<div class="tag-more-s">
|
||||||
|
<el-input
|
||||||
|
v-model="drawerProps.row.searchText"
|
||||||
|
placeholder="请输入搜索内容"
|
||||||
|
clearable
|
||||||
|
@input="handleSearch"
|
||||||
|
/>
|
||||||
|
<div>
|
||||||
|
<span>选中标签:</span>
|
||||||
|
<div class="tag-more-h">
|
||||||
|
<el-checkbox-group v-model="TagList" @change="placeableCheckedCitiesChange">
|
||||||
|
<el-checkbox-button
|
||||||
|
class="vip-power"
|
||||||
|
v-for="item in matchingObjects"
|
||||||
|
:value="item.t_id"
|
||||||
|
:key="item.t_id"
|
||||||
|
>
|
||||||
|
{{ item.t_name }}
|
||||||
|
</el-checkbox-button>
|
||||||
|
</el-checkbox-group>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span>未选中标签:</span>
|
||||||
|
<div class="tag-more-h">
|
||||||
|
<el-checkbox-group v-model="TagList" @change="placeableCheckedCitiesChange">
|
||||||
|
<el-checkbox-button
|
||||||
|
class="vip-power"
|
||||||
|
v-for="item in nonMatchingObjects"
|
||||||
|
:value="item.t_id"
|
||||||
|
:key="item.t_id"
|
||||||
|
>
|
||||||
|
{{ item.t_name }}
|
||||||
|
</el-checkbox-button>
|
||||||
|
</el-checkbox-group>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
@@ -61,16 +113,21 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts" name="UserDrawer">
|
<script setup lang="ts" name="UserDrawer">
|
||||||
import { ref, computed } from "vue";
|
import { ref, computed, reactive } from "vue";
|
||||||
import { ElMessage, FormInstance } from "element-plus";
|
import { ElMessage, FormInstance } from "element-plus";
|
||||||
import { TagList } from "@/api/interface/tag/list";
|
import { VideoList } from "@/api/interface/video/list";
|
||||||
import { arrResourcesType } from "@/utils/serviceDict";
|
import { arrNoticeSwitch } from "@/utils/serviceDict";
|
||||||
|
import { getTypeList } from "@/api/modules/tag/list";
|
||||||
|
import UploadImg from "@/components/Upload/Img.vue";
|
||||||
|
// import { extractURI } from "@/utils/eleValidate";
|
||||||
|
import { getAllList } from "@/api/modules/site/list";
|
||||||
type Options = {
|
type Options = {
|
||||||
label: string;
|
label: string;
|
||||||
value: string | number;
|
value: string | number;
|
||||||
};
|
};
|
||||||
|
interface Item {
|
||||||
|
t_id: any;
|
||||||
|
}
|
||||||
const getField = (item: any, fieldName: string | undefined) => {
|
const getField = (item: any, fieldName: string | undefined) => {
|
||||||
return fieldName ? item[fieldName] : "";
|
return fieldName ? item[fieldName] : "";
|
||||||
};
|
};
|
||||||
@@ -91,12 +148,30 @@ const generateRules = (fields: Fields[]) => {
|
|||||||
if (type === "select") {
|
if (type === "select") {
|
||||||
message = `请选择${label}`;
|
message = `请选择${label}`;
|
||||||
}
|
}
|
||||||
|
if (type === "tag") {
|
||||||
|
message = `请选择${label}`;
|
||||||
|
}
|
||||||
|
if (type === "radio") {
|
||||||
|
message = `请选择${label}`;
|
||||||
|
}
|
||||||
if (type === "text") {
|
if (type === "text") {
|
||||||
message = `请输入${label}`;
|
message = `请输入${label}`;
|
||||||
}
|
}
|
||||||
|
if (type === "text-i") {
|
||||||
|
message = `请输入${label}`;
|
||||||
|
}
|
||||||
if (type === "text-num") {
|
if (type === "text-num") {
|
||||||
message = `请输入${label}`;
|
message = `请输入${label}`;
|
||||||
}
|
}
|
||||||
|
if (type === "textarea") {
|
||||||
|
message = `请输入${label}`;
|
||||||
|
}
|
||||||
|
if (type === "image") {
|
||||||
|
message = `请上传${label}`;
|
||||||
|
}
|
||||||
|
if (type === "image-more") {
|
||||||
|
message = `请上传${label}`;
|
||||||
|
}
|
||||||
acc[prop] = [{ required, message }];
|
acc[prop] = [{ required, message }];
|
||||||
return acc;
|
return acc;
|
||||||
},
|
},
|
||||||
@@ -104,57 +179,214 @@ const generateRules = (fields: Fields[]) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const TagList = ref([] as any);
|
||||||
|
const getSiteList = ref([] as any);
|
||||||
|
getAllList().then(res => {
|
||||||
|
getSiteList.value = res.data.item;
|
||||||
|
});
|
||||||
|
|
||||||
|
const arrTagList = ref([] as any);
|
||||||
|
const arrNewTagList = ref([] as any);
|
||||||
|
const matchingObjects = ref([] as any); //选中相同
|
||||||
|
const nonMatchingObjects = ref([] as any); //没有选中的
|
||||||
|
const matchingObjectsA = ref([] as any); //选中相同
|
||||||
|
const nonMatchingObjectsB = ref([] as any); //没有选中的
|
||||||
|
const getTagList = async () => {
|
||||||
|
try {
|
||||||
|
const initParam = reactive({
|
||||||
|
t_type: 0,
|
||||||
|
limit: 3650,
|
||||||
|
page: 1,
|
||||||
|
t_hidden: 1
|
||||||
|
});
|
||||||
|
const siteRes = await getTypeList(initParam);
|
||||||
|
arrTagList.value = siteRes.data.item;
|
||||||
|
arrNewTagList.value = siteRes.data.item;
|
||||||
|
matchingObjects.value = [];
|
||||||
|
matchingObjectsA.value = [];
|
||||||
|
// 遍历第一个数组的每个元素
|
||||||
|
TagList.value.forEach(index => {
|
||||||
|
// 遍历第二个数组的每个元素
|
||||||
|
arrNewTagList.value.forEach(obj => {
|
||||||
|
// 如果第二个数组中的元素的t_id与第一个数组中的元素相同,则将其添加到新数组中
|
||||||
|
if (obj.t_id === index) {
|
||||||
|
matchingObjects.value = [...matchingObjects.value, obj];
|
||||||
|
matchingObjectsA.value = [...matchingObjectsA.value, obj];
|
||||||
|
const matchingIds = matchingObjectsA.value.map(obj => obj.t_id);
|
||||||
|
TagList.value = matchingIds;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
// 创建一个新数组,包含objectArray中id不存在于arrayA的元素
|
||||||
|
nonMatchingObjects.value = arrNewTagList.value.filter(obj => !TagList.value.includes(obj.t_id));
|
||||||
|
nonMatchingObjectsB.value = arrNewTagList.value.filter(obj => !TagList.value.includes(obj.t_id));
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 处理搜索事件
|
||||||
|
function handleSearch() {
|
||||||
|
// 在输入事件中实时更新过滤后的标签列表
|
||||||
|
filteredTagList();
|
||||||
|
}
|
||||||
|
function filteredTagList() {
|
||||||
|
if (drawerProps.value.row!.searchText.length > 0) {
|
||||||
|
let arrData = arrTagList.value.filter(tag =>
|
||||||
|
tag.t_name.toLowerCase().includes(drawerProps.value.row!.searchText.toLowerCase())
|
||||||
|
);
|
||||||
|
if (arrData.length > 0) {
|
||||||
|
matchingObjects.value = matchingObjects.value.filter(objA => arrData.some(objB => objB.t_id === objA.t_id));
|
||||||
|
nonMatchingObjects.value = nonMatchingObjects.value.filter(objA => arrData.some(objB => objB.t_id === objA.t_id));
|
||||||
|
} else {
|
||||||
|
matchingObjects.value = [];
|
||||||
|
nonMatchingObjects.value = [];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
matchingObjects.value = matchingObjectsA.value;
|
||||||
|
nonMatchingObjects.value = nonMatchingObjectsB.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//标签数组
|
||||||
|
async function placeableCheckedCitiesChange(value) {
|
||||||
|
matchingObjects.value = [];
|
||||||
|
matchingObjectsA.value = [];
|
||||||
|
drawerProps.value.row.v_tag = value;
|
||||||
|
// 遍历第一个数组的每个元素
|
||||||
|
TagList.value.forEach(index => {
|
||||||
|
// 遍历第二个数组的每个元素
|
||||||
|
arrNewTagList.value.forEach(obj => {
|
||||||
|
// 如果第二个数组中的元素的t_id与第一个数组中的元素相同,则将其添加到新数组中
|
||||||
|
if (obj.t_id === index) {
|
||||||
|
matchingObjects.value = [...matchingObjects.value, obj];
|
||||||
|
matchingObjectsA.value = [...matchingObjectsA.value, obj];
|
||||||
|
const matchingIds = matchingObjectsA.value.map(obj => obj.t_id);
|
||||||
|
TagList.value = matchingIds;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
nonMatchingObjects.value = arrNewTagList.value.filter(obj => !TagList.value.includes(obj.t_id));
|
||||||
|
nonMatchingObjectsB.value = arrNewTagList.value.filter(obj => !TagList.value.includes(obj.t_id));
|
||||||
|
}
|
||||||
|
|
||||||
const formColumns = computed((): Fields[] => {
|
const formColumns = computed((): Fields[] => {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
label: "名称",
|
label: "视频名称",
|
||||||
prop: "t_name",
|
prop: "v_name",
|
||||||
type: "text",
|
type: "text",
|
||||||
get value() {
|
get value() {
|
||||||
return drawerProps.value.row!.t_name;
|
return drawerProps.value.row!.v_name;
|
||||||
},
|
},
|
||||||
set value(val) {
|
set value(val) {
|
||||||
drawerProps.value.row!.t_name = val;
|
drawerProps.value.row!.v_name = val;
|
||||||
},
|
},
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
label: "状态",
|
label: "视频状态",
|
||||||
prop: "t_hidden",
|
prop: "v_status",
|
||||||
type: "switch",
|
type: "switch",
|
||||||
get value() {
|
get value() {
|
||||||
return String(drawerProps.value.row!.t_hidden);
|
return String(drawerProps.value.row!.v_status);
|
||||||
},
|
},
|
||||||
set value(val) {
|
set value(val) {
|
||||||
drawerProps.value.row!.t_hidden = val;
|
drawerProps.value.row!.v_status = val;
|
||||||
},
|
},
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "类型",
|
label: "是否VIP",
|
||||||
prop: "t_type",
|
prop: "v_vip",
|
||||||
type: "select",
|
type: "radio",
|
||||||
get value() {
|
get value() {
|
||||||
return drawerProps.value.row!.t_type;
|
return drawerProps.value.row!.v_vip;
|
||||||
},
|
},
|
||||||
set value(val) {
|
set value(val) {
|
||||||
drawerProps.value.row!.t_type = val;
|
drawerProps.value.row!.v_vip = val;
|
||||||
},
|
},
|
||||||
options: arrResourcesType,
|
options: arrNoticeSwitch,
|
||||||
fieldNames: { label: "label", value: "value" },
|
fieldNames: { label: "label", value: "value" },
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "排序",
|
label: "精彩站点",
|
||||||
prop: "t_order",
|
prop: "v_wonderful_site_id",
|
||||||
type: "text-num",
|
type: "select",
|
||||||
get value() {
|
get value() {
|
||||||
return drawerProps.value.row!.t_order;
|
return drawerProps.value.row!.v_wonderful_site_id;
|
||||||
},
|
},
|
||||||
set value(val) {
|
set value(val) {
|
||||||
drawerProps.value.row!.t_order = val;
|
drawerProps.value.row!.v_wonderful_site_id = val;
|
||||||
},
|
},
|
||||||
|
options: getSiteList.value,
|
||||||
|
fieldNames: { label: "si_name", value: "si_id" },
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "推荐站点",
|
||||||
|
prop: "v_recommend_site_id",
|
||||||
|
type: "select",
|
||||||
|
get value() {
|
||||||
|
return drawerProps.value.row!.v_recommend_site_id;
|
||||||
|
},
|
||||||
|
set value(val) {
|
||||||
|
drawerProps.value.row!.v_recommend_site_id = val;
|
||||||
|
},
|
||||||
|
options: getSiteList.value,
|
||||||
|
fieldNames: { label: "si_name", value: "si_id" },
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "播放时长",
|
||||||
|
prop: "v_play_time",
|
||||||
|
type: "text",
|
||||||
|
get value() {
|
||||||
|
return drawerProps.value.row!.v_play_time;
|
||||||
|
},
|
||||||
|
set value(val) {
|
||||||
|
drawerProps.value.row!.v_play_time = val;
|
||||||
|
},
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "视频封面",
|
||||||
|
prop: "v_cover_edit",
|
||||||
|
type: "text",
|
||||||
|
get value() {
|
||||||
|
return drawerProps.value.row!.v_cover_edit;
|
||||||
|
},
|
||||||
|
set value(val) {
|
||||||
|
drawerProps.value.row!.v_cover_edit = val;
|
||||||
|
},
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "视频简介",
|
||||||
|
prop: "v_describe",
|
||||||
|
type: "textarea",
|
||||||
|
get value() {
|
||||||
|
return drawerProps.value.row!.v_describe;
|
||||||
|
},
|
||||||
|
set value(val) {
|
||||||
|
drawerProps.value.row!.v_describe = val;
|
||||||
|
},
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "视频标签",
|
||||||
|
prop: "v_tag",
|
||||||
|
type: "tag",
|
||||||
|
get value() {
|
||||||
|
return drawerProps.value.row!.v_tag;
|
||||||
|
},
|
||||||
|
set value(val) {
|
||||||
|
drawerProps.value.row!.v_tag = val;
|
||||||
|
},
|
||||||
|
options: arrTagList.value,
|
||||||
|
fieldNames: { label: "label", value: "value" },
|
||||||
required: true
|
required: true
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
@@ -164,7 +396,7 @@ const rules = ref();
|
|||||||
interface DrawerProps {
|
interface DrawerProps {
|
||||||
title: string;
|
title: string;
|
||||||
isView: boolean;
|
isView: boolean;
|
||||||
row: Partial<TagList.ResList>;
|
row: Partial<VideoList.ResList>;
|
||||||
api?: (params: any) => Promise<any>;
|
api?: (params: any) => Promise<any>;
|
||||||
getTableList?: () => void;
|
getTableList?: () => void;
|
||||||
}
|
}
|
||||||
@@ -181,6 +413,28 @@ const acceptParams = (params: DrawerProps) => {
|
|||||||
drawerProps.value = params;
|
drawerProps.value = params;
|
||||||
rules.value = generateRules(formColumns.value);
|
rules.value = generateRules(formColumns.value);
|
||||||
drawerVisible.value = true;
|
drawerVisible.value = true;
|
||||||
|
if (drawerProps.value.title === "新增视频") {
|
||||||
|
drawerProps.value.row!.v_vip = 0;
|
||||||
|
drawerProps.value.row!.v_wonderful_status = 0;
|
||||||
|
drawerProps.value.row!.v_recommend_status = 0;
|
||||||
|
}
|
||||||
|
TagList.value = [];
|
||||||
|
if (drawerProps.value.row.v_cover) {
|
||||||
|
drawerProps.value.row.v_cover_code = drawerProps.value.row.v_cover.code;
|
||||||
|
drawerProps.value.row.v_cover_edit = drawerProps.value.row.v_cover.uri;
|
||||||
|
}
|
||||||
|
if (drawerProps.value.row.v_play_url_detail) {
|
||||||
|
const data = drawerProps.value.row.v_play_url_detail;
|
||||||
|
drawerProps.value.row.v_play_url = data[0];
|
||||||
|
}
|
||||||
|
if (drawerProps.value.row.v_down_url_detail) {
|
||||||
|
const data = drawerProps.value.row.v_down_url_detail;
|
||||||
|
drawerProps.value.row.v_down_url = data[0];
|
||||||
|
}
|
||||||
|
if (drawerProps.value.row.v_tag) {
|
||||||
|
TagList.value = drawerProps.value.row.v_tag.map((obj: Item) => obj.t_id).map(Number);
|
||||||
|
}
|
||||||
|
getTagList();
|
||||||
};
|
};
|
||||||
|
|
||||||
// 提交数据(新增/编辑)
|
// 提交数据(新增/编辑)
|
||||||
@@ -189,7 +443,14 @@ const handleSubmit = () => {
|
|||||||
ruleFormRef.value!.validate(async valid => {
|
ruleFormRef.value!.validate(async valid => {
|
||||||
if (!valid) return;
|
if (!valid) return;
|
||||||
try {
|
try {
|
||||||
await drawerProps.value.api!(drawerProps.value.row);
|
const params = { ...drawerProps.value.row };
|
||||||
|
let arrCoverData = {
|
||||||
|
uri: params.v_cover_edit,
|
||||||
|
code: params.v_cover_code
|
||||||
|
};
|
||||||
|
params.v_cover = arrCoverData;
|
||||||
|
params.v_tag = JSON.stringify(TagList.value);
|
||||||
|
await drawerProps.value.api!(params);
|
||||||
ElMessage.success({ message: `${drawerProps.value.title}成功!` });
|
ElMessage.success({ message: `${drawerProps.value.title}成功!` });
|
||||||
drawerProps.value.getTableList!();
|
drawerProps.value.getTableList!();
|
||||||
drawerVisible.value = false;
|
drawerVisible.value = false;
|
||||||
@@ -203,3 +464,19 @@ defineExpose({
|
|||||||
acceptParams
|
acceptParams
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
<style lang="scss">
|
||||||
|
.el-checkbox-button__inner {
|
||||||
|
margin-right: 10px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
border-left-color: #dcdfe6 !important;
|
||||||
|
}
|
||||||
|
.tag-more-h {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
.tag-more-s {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px;
|
||||||
|
border: 1px solid black;
|
||||||
|
box-shadow: 0 0 4px 2px rgb(0 0 0 / 90%);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
103
src/views/videoFeedback/fenlei/index.vue
Normal file
103
src/views/videoFeedback/fenlei/index.vue
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
<template>
|
||||||
|
<div class="table-box">
|
||||||
|
<ProTable
|
||||||
|
ref="proTable"
|
||||||
|
highlight-current-row
|
||||||
|
:columns="columns"
|
||||||
|
:init-param="initParam"
|
||||||
|
:request-api="getTableList"
|
||||||
|
:data-callback="dataCallback"
|
||||||
|
row-key="id"
|
||||||
|
:indent="20"
|
||||||
|
:search-col="{ xs: 1, sm: 1, md: 2, lg: 3, xl: 3 }"
|
||||||
|
>
|
||||||
|
</ProTable>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="tsx" name="complexProTable">
|
||||||
|
import { reactive, ref } from "vue";
|
||||||
|
import { fenLeiList } from "@/api/interface/video/fenlei";
|
||||||
|
import ProTable from "@/components/ProTable/index.vue";
|
||||||
|
import { ProTableInstance, ColumnProps } from "@/components/ProTable/interface";
|
||||||
|
import { getList } from "@/api/modules/video/fenlei";
|
||||||
|
import { arrPlanSwitch } from "@/utils/serviceDict";
|
||||||
|
// ProTable 实例
|
||||||
|
const proTable = ref<ProTableInstance>();
|
||||||
|
|
||||||
|
const initParam = reactive({
|
||||||
|
limit: 15,
|
||||||
|
page: 1
|
||||||
|
});
|
||||||
|
|
||||||
|
const dataCallback = (data: any) => {
|
||||||
|
let result = [] as any;
|
||||||
|
data.items.forEach((item, index) => {
|
||||||
|
if (item.fl_pid === 0) {
|
||||||
|
// Create a new first dimension entry
|
||||||
|
item.id = index + 1;
|
||||||
|
// item.fl_id = "";
|
||||||
|
const firstDimension = { ...item, children: [] };
|
||||||
|
// Find and add second dimension entries
|
||||||
|
data.items.forEach(subItem => {
|
||||||
|
if (subItem.fl_pid === item.fl_id) {
|
||||||
|
firstDimension.children.push(subItem);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
result.push(firstDimension);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
result.forEach(item => {
|
||||||
|
if (item.fl_pid === 0) {
|
||||||
|
item.fl_id = "";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
items: result,
|
||||||
|
total: data.total,
|
||||||
|
total_page: data.total_pages,
|
||||||
|
page: initParam.page,
|
||||||
|
limit: initParam.limit
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const getTableList = (params: any) => {
|
||||||
|
let newParams = JSON.parse(JSON.stringify(params));
|
||||||
|
initParam.page = newParams.page;
|
||||||
|
initParam.limit = newParams.limit;
|
||||||
|
return getList(newParams);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 表格配置项
|
||||||
|
const columns = reactive<ColumnProps<fenLeiList.ResList>[]>([
|
||||||
|
{ type: "selection", fixed: "left", width: 50 },
|
||||||
|
{
|
||||||
|
prop: "key",
|
||||||
|
label: "搜索内容",
|
||||||
|
isShow: false,
|
||||||
|
search: {
|
||||||
|
el: "input"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: "fl_id",
|
||||||
|
label: "ID",
|
||||||
|
width: 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: "fl_mingzi",
|
||||||
|
label: "分类名称"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: "fl_leixing",
|
||||||
|
label: "类型",
|
||||||
|
tag: true,
|
||||||
|
enum: arrPlanSwitch,
|
||||||
|
render(scope) {
|
||||||
|
return (
|
||||||
|
<el-tag type={scope.row.fl_leixing ? "success" : "info"}>{scope.row.fl_leixing === 1 ? "其他" : "默认"}</el-tag>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
</script>
|
||||||
@@ -1,45 +1,93 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="table-box">
|
<div class="table-box">
|
||||||
<ProTable ref="proTable" highlight-current-row :columns="columns" :request-api="getList">
|
<ProTable
|
||||||
|
ref="proTable"
|
||||||
|
highlight-current-row
|
||||||
|
:columns="columns"
|
||||||
|
:request-api="getTableList"
|
||||||
|
:data-callback="dataCallback"
|
||||||
|
>
|
||||||
<!-- 表格 header 按钮 -->
|
<!-- 表格 header 按钮 -->
|
||||||
<template #tableHeader="scope">
|
<template #tableHeader="scope">
|
||||||
<el-button type="primary" style="display: none" :icon="CirclePlus" @click="openDrawer(true)">新增</el-button>
|
|
||||||
<el-button
|
<el-button
|
||||||
style="display: none"
|
type="primary"
|
||||||
type="danger"
|
:icon="EditPen"
|
||||||
:icon="Delete"
|
|
||||||
plain
|
plain
|
||||||
:disabled="!scope.isSelected"
|
:disabled="!scope.isSelected"
|
||||||
@click="batchDelete(scope.selectedList)"
|
@click="batchModify(scope.selectedList)"
|
||||||
>
|
>
|
||||||
批量删除标签
|
批量设置每日推荐视频
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
:icon="EditPen"
|
||||||
|
plain
|
||||||
|
:disabled="!scope.isSelected"
|
||||||
|
@click="batchVipDataBtn(scope.selectedList)"
|
||||||
|
>
|
||||||
|
批量设置vip
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
<!-- 表格操作 -->
|
|
||||||
<template #operation="scope">
|
|
||||||
<el-button type="primary" :icon="EditPen" @click="openDrawer(false, scope.row)">编辑</el-button>
|
|
||||||
<el-button type="danger" :icon="Delete" @click="deleteAccount(scope.row)">删除</el-button>
|
|
||||||
</template>
|
|
||||||
</ProTable>
|
</ProTable>
|
||||||
<Drawer ref="drawerRef" />
|
<ModifyDrawer ref="modifyDrawerRef" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="tsx" name="complexProTable">
|
<script setup lang="tsx" name="complexProTable">
|
||||||
|
import { ElImage } from "element-plus";
|
||||||
import { reactive, ref } from "vue";
|
import { reactive, ref } from "vue";
|
||||||
import { videoFeedbackList } from "@/api/interface/videoFeedback/list";
|
import { VideoList } from "@/api/interface/video/list";
|
||||||
import { useHandleData } from "@/hooks/useHandleData";
|
import { useHandleData } from "@/hooks/useHandleData";
|
||||||
import ProTable from "@/components/ProTable/index.vue";
|
import ProTable from "@/components/ProTable/index.vue";
|
||||||
import { Delete, EditPen, CirclePlus } from "@element-plus/icons-vue";
|
import { EditPen } from "@element-plus/icons-vue";
|
||||||
import { ProTableInstance, ColumnProps } from "@/components/ProTable/interface";
|
import { ProTableInstance, ColumnProps } from "@/components/ProTable/interface";
|
||||||
import { getList, saveData, deleteItem } from "@/api/modules/videoFeedback/list";
|
import { getVideoList } from "@/api/modules/video/list";
|
||||||
import Drawer from "./drawer.vue";
|
import { getAllList } from "@/api/modules/video/fenlei";
|
||||||
import { arrReasonType } from "@/utils/serviceDict";
|
import { batchData, batchVipData } from "@/api/modules/video/list";
|
||||||
|
import { LOSE_STR_KEY, LOGIN_URL } from "@/config";
|
||||||
|
import router from "@/routers";
|
||||||
|
import { h } from "vue";
|
||||||
|
import { AsyncImageComponent } from "@/utils/decrypt";
|
||||||
|
import { arrNoticeSwitch } from "@/utils/serviceDict";
|
||||||
|
import ModifyDrawer from "./modifyDrawer.vue";
|
||||||
// ProTable 实例
|
// ProTable 实例
|
||||||
const proTable = ref<ProTableInstance>();
|
const proTable = ref<ProTableInstance>();
|
||||||
|
|
||||||
|
// 视频分类
|
||||||
|
const getFenLeiList = ref([] as any);
|
||||||
|
getAllList().then(res => {
|
||||||
|
if (res.code === LOSE_STR_KEY) {
|
||||||
|
router.replace(LOGIN_URL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let arrFenlei = res.data.items;
|
||||||
|
getFenLeiList.value = arrFenlei;
|
||||||
|
});
|
||||||
|
|
||||||
|
const initParam = reactive({
|
||||||
|
limit: 15,
|
||||||
|
page: 1
|
||||||
|
});
|
||||||
|
const dataCallback = (data: any) => {
|
||||||
|
return {
|
||||||
|
items: data.items,
|
||||||
|
total: data.total,
|
||||||
|
total_page: data.total_pages,
|
||||||
|
page: initParam.page,
|
||||||
|
limit: initParam.limit
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const getTableList = (params: any) => {
|
||||||
|
let newParams = JSON.parse(JSON.stringify(params));
|
||||||
|
initParam.page = newParams.page;
|
||||||
|
initParam.limit = newParams.limit;
|
||||||
|
return getVideoList(newParams);
|
||||||
|
};
|
||||||
|
|
||||||
// 表格配置项
|
// 表格配置项
|
||||||
const columns = reactive<ColumnProps<videoFeedbackList.ResList>[]>([
|
const columns = reactive<ColumnProps<VideoList.ResList>[]>([
|
||||||
|
{ type: "selection", fixed: "left", width: 50 },
|
||||||
{
|
{
|
||||||
prop: "key",
|
prop: "key",
|
||||||
label: "搜索内容",
|
label: "搜索内容",
|
||||||
@@ -49,77 +97,123 @@ const columns = reactive<ColumnProps<videoFeedbackList.ResList>[]>([
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
prop: "vf_id",
|
prop: "sp_id",
|
||||||
label: "ID",
|
label: "ID",
|
||||||
width: 100
|
width: 100
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
prop: "mu_nickname",
|
prop: "sp_name",
|
||||||
label: "用户昵称"
|
label: "名称"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
prop: "vf_ip",
|
prop: "sp_fengmian_url",
|
||||||
label: "用户IP"
|
label: "视频封面",
|
||||||
|
width: 120,
|
||||||
|
render(scope) {
|
||||||
|
return h(ElImage, {
|
||||||
|
style: "width: 98%; height: 30px; display: flex; align-items: center;",
|
||||||
|
src: scope.row.sp_fengmian_url,
|
||||||
|
previewSrcList: [scope.row.sp_fengmian_url],
|
||||||
|
hideOnClickModal: true,
|
||||||
|
zIndex: 999999999,
|
||||||
|
previewTeleported: true,
|
||||||
|
fit: "cover"
|
||||||
|
});
|
||||||
|
return <img src={scope.row.sp_fengmian_url} alt="视频封面" style="width: 100%; height: auto;" />;
|
||||||
|
return h(AsyncImageComponent, { url: scope.row.sp_fengmian_url });
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
prop: "v_name",
|
prop: "sp_is_vip",
|
||||||
label: "视频名称"
|
label: "是否VIP",
|
||||||
},
|
width: 120,
|
||||||
|
fieldNames: { label: "label", value: "value" },
|
||||||
{
|
|
||||||
prop: "vf_status",
|
|
||||||
label: "状态",
|
|
||||||
search: { el: "select", props: { filterable: true } },
|
search: { el: "select", props: { filterable: true } },
|
||||||
enum: [
|
enum: arrNoticeSwitch,
|
||||||
{ label: "未解决", value: 0 },
|
|
||||||
{ label: "已解决", value: 1 }
|
|
||||||
],
|
|
||||||
render(scope) {
|
render(scope) {
|
||||||
return (
|
return (
|
||||||
<el-tag type={scope.row.vf_status === 0 ? "danger" : "success"}>
|
<el-tag type={scope.row.sp_is_vip === 0 ? "danger" : "success"}>{scope.row.sp_is_vip === 0 ? "否" : "是"}</el-tag>
|
||||||
{scope.row.vf_status === 0 ? "未解决" : "已解决"}
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: "sp_tui_jian_shi_jian",
|
||||||
|
label: "是否推荐",
|
||||||
|
width: 120,
|
||||||
|
fieldNames: { label: "label", value: "value" },
|
||||||
|
search: { el: "select", props: { filterable: true } },
|
||||||
|
enum: arrNoticeSwitch,
|
||||||
|
render(scope) {
|
||||||
|
return (
|
||||||
|
<el-tag type={scope.row.sp_tui_jian_shi_jian === 0 ? "danger" : "success"}>
|
||||||
|
{scope.row.sp_tui_jian_shi_jian === 0 ? "否" : "是"}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
prop: "vf_reason",
|
prop: "fl_id",
|
||||||
label: "类型",
|
label: "分类",
|
||||||
enum: arrReasonType,
|
width: 120,
|
||||||
|
fieldNames: { label: "fl_mingzi", value: "fl_id" },
|
||||||
|
enum: getFenLeiList,
|
||||||
search: { el: "select", props: { filterable: true } }
|
search: { el: "select", props: { filterable: true } }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
prop: "vf_remarks",
|
prop: "sp_biaoqian",
|
||||||
label: "备注"
|
label: "标签",
|
||||||
|
width: 250,
|
||||||
|
render(scope) {
|
||||||
|
if (scope.row.sp_biaoqian) {
|
||||||
|
if (Array.isArray(scope.row.sp_biaoqian)) {
|
||||||
|
return <span>{scope.row.sp_biaoqian.join(", ")}</span>;
|
||||||
|
} else {
|
||||||
|
const data = JSON.parse(scope.row.sp_biaoqian);
|
||||||
|
return <span>{data.join(", ")}</span>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
prop: "sp_fangwen",
|
||||||
|
label: "访问量",
|
||||||
|
width: 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: "sp_shichang",
|
||||||
|
label: "时长",
|
||||||
|
width: 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: "sp_source_code",
|
||||||
|
label: "源码",
|
||||||
|
width: 200
|
||||||
},
|
},
|
||||||
{ prop: "created_at", label: "添加时间", width: 170 }
|
{ prop: "created_at", label: "添加时间", width: 170 }
|
||||||
// { prop: "operation", label: "操作", fixed: "right", width: 230 }
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// 删除标签信息
|
// 批量修改视频信息
|
||||||
const deleteAccount = async (params: videoFeedbackList.ResList) => {
|
const batchModify = async (id: any[]) => {
|
||||||
await useHandleData(deleteItem, { vf_id: params.vf_id }, "删除所选信息");
|
const ids = id.map((item: VideoList.ResList) => item.sp_id);
|
||||||
proTable.value?.getTableList();
|
await useHandleData(batchData, { sp_id: ids.join(",") }, "批量设置所选信息为每日推荐视频");
|
||||||
};
|
|
||||||
|
|
||||||
// 批量删除标签信息
|
|
||||||
const batchDelete = async (id: any[]) => {
|
|
||||||
const ids = id.map((item: videoFeedbackList.ResList) => item.vf_id);
|
|
||||||
await useHandleData(deleteItem, { vf_id: ids.join(",") }, "删除所选信息");
|
|
||||||
proTable.value?.clearSelection();
|
proTable.value?.clearSelection();
|
||||||
proTable.value?.getTableList();
|
proTable.value?.getTableList();
|
||||||
};
|
};
|
||||||
// 打开 drawer(新增、编辑)
|
|
||||||
const drawerRef = ref<InstanceType<typeof Drawer> | null>(null);
|
|
||||||
|
|
||||||
const openDrawer = (isEdit: boolean, row: Partial<videoFeedbackList.ResList> = {}) => {
|
// 批量修改视频vip
|
||||||
|
const modifyDrawerRef = ref<InstanceType<typeof ModifyDrawer> | null>(null);
|
||||||
|
const batchVipDataBtn = async (id: any[], row: Partial<VideoList.ResList> = {}) => {
|
||||||
|
const ids = id.map((item: VideoList.ResList) => item.sp_id);
|
||||||
|
row.sp_id = ids.join(",");
|
||||||
const params = {
|
const params = {
|
||||||
title: isEdit ? "新增标签" : "编辑标签",
|
title: "批量编辑VIP视频",
|
||||||
row: { ...row },
|
row: { ...row },
|
||||||
api: saveData,
|
api: batchVipData,
|
||||||
getTableList: proTable.value?.getTableList
|
getTableList: proTable.value?.getTableList,
|
||||||
|
clearSelection: proTable.value?.clearSelection
|
||||||
};
|
};
|
||||||
drawerRef.value?.acceptParams(params as any);
|
modifyDrawerRef.value?.acceptParams(params as any);
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user