Sfoglia il codice sorgente

下线视频上传入口,新增一次性版本升级提示

- 移除上传内容管理页的「+ 上传视频」「修改视频」入口及登录引导逻辑
- 移除选视频弹窗中的「我的上传」来源(公众号/企微)
- 删除 uploadVideoModal、OSSSDK 及 crypto-js / xml-js 依赖
- 清理 getUploadVideoContentListApi / getTempStsToken / uploadPublishVideo 三个接口常量
- 首次进入上传内容管理页弹一次「版本升级」提示

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
刘立冬 16 ore fa
parent
commit
1a38c786d6

+ 0 - 3
package.json

@@ -14,14 +14,12 @@
     "@tailwindcss/cli": "^4.1.3",
     "antd": "^5.27.4",
     "axios": "^1.8.4",
-    "crypto-js": "^4.2.0",
     "lodash": "^4.17.21",
     "lodash-es": "^4.17.21",
     "qrcode.react": "^4.2.0",
     "react": "^18.3.1",
     "react-dom": "^18.3.1",
     "react-router-dom": "^6.23.1",
-    "xml-js": "^1.6.11",
     "zustand": "^4.5.2"
   },
   "devDependencies": {
@@ -32,7 +30,6 @@
     "@types/node": "^22.14.0",
     "@types/react": "^18.3.3",
     "@types/react-dom": "^18.3.0",
-    "@types/xml-js": "^1.0.0",
     "@typescript-eslint/parser": "^6.0.0",
     "@vitejs/plugin-react-swc": "^3.5.0",
     "autoprefixer": "^10.4.21",

+ 1 - 4
src/http/api.ts

@@ -35,7 +35,6 @@ export const deleteQwPlanApi = `${import.meta.env.VITE_API_URL}/contentPlatform/
 export const getVideoContentCategoryListApi = `${import.meta.env.VITE_API_URL}/contentPlatform/plan/videoContentCategoryList`
 export const getVideoContentCoverFrameListApi = `${import.meta.env.VITE_API_URL}/contentPlatform/plan/videoContentCoverFrameList`
 export const getVideoContentListApi = `${import.meta.env.VITE_API_URL}/contentPlatform/plan/videoContentList`
-export const getUploadVideoContentListApi = `${import.meta.env.VITE_API_URL}/contentPlatform/plan/upload/videoContentList`
 export const getShareQrPic = `${import.meta.env.VITE_API_URL}/contentPlatform/plan/qw/getSharePic`
 export const getShareQrLink = `${import.meta.env.VITE_API_URL}/contentPlatform/plan/getShareUrlLink`
 
@@ -54,10 +53,8 @@ export const getNoticeList = `${import.meta.env.VITE_API_URL}/contentPlatform/no
 export const readNotice = `${import.meta.env.VITE_API_URL}/contentPlatform/notice/read`
 export const readAllNotice = `${import.meta.env.VITE_API_URL}/contentPlatform/notice/readAll`
 
-// 文件上传
-export const getTempStsToken = `${import.meta.env.VITE_API_URL}/file/getTempStsToken`
+// 上传内容查询/删除(已不支持新增上传,仅保留历史查询)
 export const uploadContentList = `${import.meta.env.VITE_API_URL}/contentPlatform/uploadContent/list`
-export const uploadPublishVideo = `${import.meta.env.VITE_API_URL}/contentPlatform/uploadContent/publishVideo`
 export const uploadDeleteVideo = `${import.meta.env.VITE_API_URL}/contentPlatform/uploadContent/deleteVideo`
 
 // 设置绑定微信用户

+ 0 - 105
src/utils/OSSSDK/api/index.ts

@@ -1,105 +0,0 @@
-import axios from 'axios';
-import convert from 'xml-js';
-
-const instance = axios.create({
-    timeout: 240000,
-    validateStatus: function (status) {
-        return status < 600;
-    },
-    headers: {
-        'content-type': 'application/octet-stream',
-    }
-});
-
-instance.interceptors.response.use((res) => {
-    return res;
-}, function (err) {
-    return Promise.reject(err);
-});
-
-export default {
-    post (url: string, params?: any, config?: any) {
-        const myConfig: any = {};
-        if (config) {
-            Object.assign(myConfig, config);
-        }
-
-        return new Promise((resolve, reject) => {
-            const _startTime = new Date().getTime();
-            instance.post(url, params as any, myConfig).then(res => {
-                const _endTime = new Date().getTime();
-                (res as any).dTime = _endTime - _startTime;
-                if (res.status === 200) {
-                    resolve(res);
-                } else {
-                    const parseData = JSON.parse(convert.xml2json(res.data as any, {
-                        compact: true,
-                        spaces: 4,
-                        ignoreCdata: true,
-                        ignoreDeclaration: true
-                    } as any));
-                    (res as any).data = (parseData as any)['Error'];
-                    reject(res);
-                }
-            }).catch((err: any) => {
-                const _endTime = new Date().getTime();
-                err.dTime = _endTime - _startTime;
-                err.url = url;
-                reject(err);
-            });
-        });
-    },
-    get (url: string, params?: any, config?: any) {
-        const myConfig: any = {};
-        if (config) {
-            Object.assign(myConfig, config);
-        }
-        return new Promise((resolve, reject) => {
-            if (params) {
-                (myConfig as any).params = params;
-            }
-            instance.get(url, myConfig).then(res => {
-                if (res.status === 200) {
-                    resolve(res);
-                } else {
-                    reject(res);
-                }
-            }).catch((err: any) => {
-                reject(err);
-            });
-        });
-    },
-
-    upload (url: string, file: Blob, config?: any) {
-        const myConfig: any = {};
-        if (config) {
-            Object.assign(myConfig, config);
-        }
-        return new Promise((resolve, reject) => {
-            const _startTime = new Date().getTime();
-            instance.put(url, file, myConfig).then(res => {
-                const _endTime = new Date().getTime();
-                (res as any).dTime = _endTime - _startTime;
-                if (res.status === 200) {
-                    resolve(res);
-                } else {
-                    const parseData = JSON.parse(convert.xml2json(res.data as any, {
-                        compact: true,
-                        spaces: 4,
-                        ignoreCdata: true,
-                        ignoreDeclaration: true
-                    } as any));
-                    (res as any).data = (parseData as any)['Error'];
-                    reject(res);
-                }
-            }).catch((err: any) => {
-                const _endTime = new Date().getTime();
-                err.dTime = _endTime - _startTime;
-                err.url = url;
-                reject(err);
-            });
-        });
-    }
-};
-
-

+ 0 - 58
src/utils/OSSSDK/api/methodList.ts

@@ -1,58 +0,0 @@
-import ajax from './index';
-import signUtils from '../utils/signUtils';
-import { xml2js } from 'xml-js';
-
-const initiateMultipartUpload = (creds: any, subres: any, headerConfig?: Record<string, any>) => {
-    const _initializeUrl = `${creds['host']}${creds['fileName']}?uploads=`;
-    const requestHeader = signUtils.authorization({
-        method: 'post'
-    }, creds, subres, headerConfig);
-    return new Promise((resolve, reject) => {
-        ajax.post(_initializeUrl, null, {
-            headers: requestHeader
-        }).then((res: any) => {
-            const parseRes: any = (xml2js as any)(res.data, { compact: true, spaces: 4 } as any);
-            const _params: any = {};
-            Object.keys(parseRes['InitiateMultipartUploadResult'] || {}).forEach((key: string) => {
-                _params[key] = parseRes['InitiateMultipartUploadResult'][key]['_text'];
-            });
-            resolve(_params);
-        }).catch((err: any) => {
-            reject(err);
-        });
-    });
-};
-
-const completeMultipartUpload = (creds: any, listData: any[], _subres: any) => {
-    const partsXml = listData.map((item: any) => {
-        return `<Part><PartNumber>${item.partNumber}</PartNumber><ETag>${item.eTag}</ETag></Part>`;
-    }).join('');
-
-    const xmlData = `<?xml version="1.0" encoding="utf-8"?><CompleteMultipartUpload>${partsXml}</CompleteMultipartUpload>`;
-
-    const _completeMultipartUploadUrl = `${creds['host']}${creds['fileName']}?uploadId=${_subres['uploadId']}`;
-    const requestHeader = signUtils.authorization({
-        method: 'post',
-        'content-type': 'application/xml'
-    }, creds, _subres);
-    delete (requestHeader as any)['content-type'];
-    return new Promise((resolve, reject) => {
-        ajax.post(_completeMultipartUploadUrl, xmlData as any, {
-            headers: {
-                'content-type': 'application/xml',
-                ...requestHeader
-            }
-        }).then((res: any) => {
-            resolve(res);
-        }).catch((err: any) => {
-            reject(err);
-        });
-    });
-};
-
-export {
-    initiateMultipartUpload,
-    completeMultipartUpload
-};
-
-

+ 0 - 7
src/utils/OSSSDK/errorList.ts

@@ -1,7 +0,0 @@
-export default {
-    cancel: 'cancel',
-    netErr: 'network error',
-    serverErr: 'server Error'
-};
-
-

+ 0 - 47
src/utils/OSSSDK/fileOprs.ts

@@ -1,47 +0,0 @@
-export default class FileOpr {
-    _file: File | any = null;
-    _defaultChunkSize: number = 1024 * 1024;
-    _minChunkSize: number = 0;
-    _partsNumber: number = 0;
-
-    constructor (file: File) {
-        this._file = file;
-        if (Math.ceil(file.size / this._defaultChunkSize) <= 1) {
-            this._minChunkSize = 500 * 1024;
-            this._partsNumber = Math.ceil(file.size / this._minChunkSize);
-        } else if (Math.ceil(file.size / this._defaultChunkSize) < 10000) {
-            this._partsNumber = Math.ceil(file.size / this._defaultChunkSize);
-        } else {
-            this._partsNumber = 10000;
-            this._minChunkSize = Math.ceil(this._file.size / 10000);
-        }
-    }
-
-    _fileSlice (sliceIndex: number) {
-        const partSize = this._minChunkSize === 0 ? this._defaultChunkSize : this._minChunkSize,
-            _start = sliceIndex * partSize,
-            _end = _start + partSize > this._file.size ? this._file.size : _start + partSize;
-
-        const partBlob = this._file.slice(_start, _end);
-
-        return {
-            file: partBlob as Blob,
-            partNumber: sliceIndex + 1,
-            partSize: (partBlob as Blob).size
-        };
-    }
-
-    getSliceArr (startPartNumber: number, num: number) {
-        const sliceArr: any[] = [];
-        while (sliceArr.length < num) {
-            sliceArr.push(this._fileSlice(startPartNumber + sliceArr.length - 1));
-        }
-        return sliceArr;
-    }
-
-    getPartsNumber () {
-        return this._partsNumber;
-    }
-}
-
-

+ 0 - 347
src/utils/OSSSDK/index.ts

@@ -1,347 +0,0 @@
-import ajax from './api/index';
-import FileOprs from './fileOprs';
-import axios from 'axios';
-import { arrayUnique, errHandler } from './utils/tools';
-import signUtils from './utils/signUtils';
-import errList from './errorList';
-import { initiateMultipartUpload, completeMultipartUpload } from './api/methodList';
-import defaultsDeep from 'lodash/defaultsDeep';
-
-type AnyFunction = (...args: any[]) => any;
-
-export default class OSSSDK {
-    static opts: { log: boolean; timeGap: number } = {
-        log: false,
-        timeGap: 0,
-    };
-
-    _fileOperator: any = null;
-    _userProcessHandler: AnyFunction | null = null;
-    _uploadParams: any = null;
-    _creds: any = null;
-    _checkpoint: any[] = [];
-    _lastGeneratePartNum: number = 0;
-    _parrallel: number = 5;
-    _threadQueue: Array<any> = [];
-    _nowThreadNum: number = 0;
-    _retryTimes: number = 0;
-    _delayTime: number = 0;
-    _isManualStop: boolean = false;
-    _lastSpeedCheckIndex: number = 0;
-    _speedAnalyzeTimes: number = 1;
-    _speed: string = '0.00';
-    _isComplete: boolean = false;
-    _headerConfig: any = null;
-
-    constructor (file: File, creds: any, handler?: AnyFunction, options?: Record<string, any>) {
-        try {
-            if (!file) throw new Error('file is should not null');
-            if (!creds) throw new Error('creds is should not null');
-            if (handler) {
-                this._userProcessHandler = handler;
-            }
-            this._creds = creds;
-            this._fileOperator = new FileOprs(file);
-            if (options) {
-                Object.keys(options).forEach(key => {
-                    (this as any)['_' + key] = (options as any)[key];
-                });
-            }
-        } catch (err: any) {
-            throw new Error(err.toString());
-        }
-    }
-
-    static config (options?: Partial<typeof OSSSDK.opts>) {
-        OSSSDK.opts = defaultsDeep(options || {}, OSSSDK.opts);
-    }
-
-    updateConfig (creds: any) {
-        this._creds = creds;
-    }
-
-    _initUpload (): Promise<any> {
-        return new Promise((resolve, reject) => {
-            if (!this._uploadParams) {
-                const _subres: any = { 'uploads': '' };
-                initiateMultipartUpload(this._creds, _subres, this._headerConfig).then(res => {
-                    this._uploadParams = res || {};
-                    resolve(res);
-                }).catch((err: any) => {
-                    this._uploadParams = null;
-                    reject(errHandler(err, 'initUpload'));
-                });
-            } else {
-                resolve(this._uploadParams);
-            }
-        });
-    }
-
-    _generateJob (threadIndex: number): any {
-        if (this._lastGeneratePartNum < this._fileOperator.getPartsNumber()) {
-            this._lastGeneratePartNum = this._lastGeneratePartNum + 1;
-
-            const fileItem = this._fileOperator._fileSlice(this._lastGeneratePartNum - 1);
-
-            const url = this._creds['host'] + this._creds['fileName'] +
-                `?partNumber=${fileItem.partNumber}&uploadId=${this._uploadParams['UploadId']}`;
-
-            const _subres: any = { 'partNumber': fileItem['partNumber'], 'uploadId': this._uploadParams['UploadId'] };
-            const requestHeader = signUtils.authorization({
-                method: 'put'
-            }, this._creds, _subres, this._headerConfig);
-            if (this._isManualStop) {
-                return {
-                    threadIndex: threadIndex,
-                    run: () => {
-                        return new Promise((_, reject) => {
-                            this._reset(threadIndex, fileItem);
-                            reject('stop');
-                        });
-                    }
-                };
-            } else {
-                if (new Date().getTime() > new Date(this._creds.expiration).getTime()) {
-                    return {
-                        threadIndex: threadIndex,
-                        run: () => {
-                            return new Promise((_, reject) => {
-                                this._reset(threadIndex, fileItem);
-                                reject(errHandler(new Error('InvalidAccessKeyId') as any, 'multipartUpload', fileItem));
-                            });
-                        }
-                    };
-                } else {
-                    return this._jobThread(fileItem, url, requestHeader, threadIndex);
-                }
-            }
-        } else {
-            return {
-                threadIndex: threadIndex,
-                run: () => {
-                    return new Promise((resolve) => {
-                        this._threadQueue[threadIndex - 1].status = 'complete';
-                        resolve('complete');
-                    });
-                }
-            };
-        }
-    }
-
-    _jobThread (fileItem: any, url: string, requestHeader: any, threadIndex: number) {
-        return {
-            threadIndex: threadIndex,
-            run: () => {
-                return new Promise((resolve, reject) => {
-                    if (this._threadQueue.filter((item: any) => item.status === 'stop').length > 0) {
-                        this._reset(threadIndex, fileItem);
-                        reject(errList.cancel);
-                    } else {
-                        ajax.upload(url, fileItem.file, {
-                            cancelToken: new axios.CancelToken((c) => {
-                                this._threadQueue[threadIndex - 1].cancel = () => {
-                                    c('stop');
-                                };
-                            }),
-                            headers: requestHeader
-                        }).then((res: any) => {
-                            this._processHandler(fileItem, res, this._userProcessHandler || undefined);
-                            if (this._checkpoint.length === this._fileOperator.getPartsNumber()) {
-                                this._threadQueue[threadIndex - 1].status = 'complete';
-                                resolve('complete');
-                            } else {
-                                resolve(this._generateJob(threadIndex).run());
-                            }
-                        }).catch((err: any) => {
-                            this._reset(threadIndex, fileItem);
-                            reject(errHandler(err, 'multipartUpload', fileItem));
-                        });
-                    }
-                });
-            }
-        };
-    }
-
-    _processHandler (fileItem: any, res: any, _userProcessHandler?: AnyFunction) {
-        const processItem = {
-            donePartNum: fileItem.partNumber,
-            etag: res.headers.etag,
-            dTime: res.dTime,
-            percent: (Array.from(new Set(this._checkpoint.map(item => item.donePartNum))).length + 1) / this._fileOperator.getPartsNumber()
-        };
-        this._checkpoint.push(processItem);
-
-        if (_userProcessHandler) {
-            res.partSize = fileItem.partSize;
-            _userProcessHandler(this._checkpoint, OSSSDK.opts.log ? res : undefined);
-        }
-    }
-
-    _reset (threadIndex: number, fileItem: any) {
-        this._threadQueue[threadIndex - 1].status = 'stop';
-        this._threadQueue[threadIndex - 1].startPartNumber = fileItem.partNumber;
-        this._threadQueue[threadIndex - 1].cancel = null;
-        this._lastGeneratePartNum--;
-        this._lastSpeedCheckIndex = this._checkpoint.length ? this._checkpoint.length : 0;
-        this._speedAnalyzeTimes = 1;
-        this._nowThreadNum = 0;
-    }
-
-    async _createThreads (): Promise<any> {
-        try {
-            const jobQueue: any[] = [];
-            while (this._nowThreadNum < this._parrallel) {
-                this._nowThreadNum++;
-                jobQueue.push(this._generateJob(this._nowThreadNum));
-            }
-
-            jobQueue.forEach((job: any) => {
-                this._threadQueue.push({
-                    threadIndex: job.threadIndex,
-                    status: 'processing',
-                    thread: null,
-                    cancel: null,
-                    startPartNumber: null,
-                });
-                this._threadQueue[this._threadQueue.length - 1].thread = job.run();
-            });
-        } catch (err: any) {
-            return errHandler(err, 'createThreads');
-        }
-    }
-
-    async _activeThreads (): Promise<any> {
-        try {
-            if (this._threadQueue.length === 0) {
-                return this._createThreads();
-            } else {
-                const _partNumList = this._threadQueue.map((item: any) => {
-                    return item.startPartNumber;
-                }).filter((num: any) => !!num).sort((a: number, b: number) => a - b);
-
-                this._lastGeneratePartNum = _partNumList.length > 0 ? _partNumList[0] - 1 : 0;
-                const jobQueue: any[] = [];
-                while (this._nowThreadNum < this._parrallel) {
-                    this._nowThreadNum++;
-                    jobQueue.push(this._generateJob(this._nowThreadNum));
-                    this._threadQueue[this._nowThreadNum - 1].status = 'processing';
-                    this._threadQueue[this._nowThreadNum - 1].cancel = null;
-                    this._threadQueue[this._nowThreadNum - 1].startPartNumber = null;
-                }
-
-                jobQueue.forEach((job: any, index: number) => {
-                    this._threadQueue[index].thread = job.run();
-                });
-            }
-        } catch (err: any) {
-            return errHandler(err, 'activeThreads');
-        }
-    }
-
-    mergeMultiParts (): Promise<any> {
-        return new Promise((resolve, reject) => {
-            try {
-                const _listData = arrayUnique(this._checkpoint, 'donePartNum').map((item: any) => {
-                    return {
-                        partNumber: item.donePartNum,
-                        eTag: item.etag
-                    };
-                }).sort((c1: any, c2: any) => {
-                    if(c1.partNumber > c2.partNumber) {
-                        return 1;
-                    } else if(c1.partNumber < c2.partNumber) {
-                        return -1;
-                    } else {
-                        return 0;
-                    }
-                });
-                const _subres: any = { 'uploadId': this._uploadParams['UploadId'] };
-                completeMultipartUpload(this._creds, _listData, _subres).then(() => {
-                    resolve(void 0);
-                }).catch((err: any) => {
-                    reject(errHandler(err, 'mergeMultiParts'));
-                });
-            } catch (err: any) {
-                reject(errHandler(err, 'mergeMultiParts'));
-            }
-        });
-    }
-
-    multipartUpload (): Promise<any> {
-        return new Promise((resolve, reject) => {
-            this._initUpload().then(() => {
-                this._createThreads().then(() => {
-                    Promise.all(this._threadQueue.map((item: any) => item.thread)).then(() => {
-                        this._isComplete = true;
-                        this.mergeMultiParts().then(() => {
-                            resolve(void 0);
-                        }).catch((err: any) => {
-                            reject(err);
-                        });
-                    }).catch((err: any) => {
-                        this.cancelUpload();
-                        setTimeout(() => {
-                            reject(err);
-                        }, 300);
-                    });
-                }).catch((err: any) => {
-                    reject(err);
-                });
-            }).catch((err: any) => {
-                reject(err);
-            });
-        });
-    }
-
-    resumeMultipartUpload (): Promise<any> {
-        if(this._isManualStop) this._isManualStop = false;
-        return new Promise((resolve, reject) => {
-            this._initUpload().then(() => {
-                this._activeThreads().then(() => {
-                    Promise.all(this._threadQueue.map((item: any) => item.thread)).then(() => {
-                        this._isComplete = true;
-                        this.mergeMultiParts().then((res: any) => {
-                            resolve(res);
-                        }).catch((err: any) => {
-                            reject(err);
-                        });
-                    }).catch((err: any) => {
-                        this.cancelUpload();
-                        setTimeout(() => {
-                            reject(err);
-                        }, 300);
-                    });
-                }).catch((err: any) => {
-                    reject(err);
-                });
-            }).catch((err: any) => {
-                reject(err);
-            });
-        });
-    }
-
-    cancelUpload () {
-        if (!this._isComplete) {
-            this._isManualStop = true;
-            this._threadQueue.forEach((thread: any) => {
-                if (thread.cancel) {
-                    thread.cancel();
-                }
-                thread.cancel = null;
-            });
-        }
-    }
-
-    getSpeed (callback?: (speed: string) => void) {
-        return setInterval(() => {
-            const _partNums = this._checkpoint.length ? this._checkpoint.length - this._lastSpeedCheckIndex : 0;
-            this._speed = ((_partNums) / this._speedAnalyzeTimes).toFixed(2);
-            this._speedAnalyzeTimes += 1;
-            if (callback) {
-                callback(this._speed);
-            }
-        }, 1000);
-    }
-}
-
-

+ 0 - 16
src/utils/OSSSDK/utils/InterceptArr.ts

@@ -1,16 +0,0 @@
-export const arrIntercept = (arr: any[], proxyMethods: string[], handler: () => void) => {
-    const arrProto = Array.prototype as any;
-    proxyMethods.forEach(method => {
-        Object.defineProperty(arr, method, {
-            value: function mutator (...args: any[]) {
-                handler();
-                return arrProto[method].apply(this, args);
-            },
-            enumerable: false,
-            writable: true,
-            configurable: true
-        });
-    });
-};
-
-

+ 0 - 80
src/utils/OSSSDK/utils/signUtils.ts

@@ -1,80 +0,0 @@
-import cryptoBase64 from 'crypto-js/enc-base64';
-import cryptoHmacSHA1 from 'crypto-js/hmac-sha1';
-import OSSSDK from '../index';
-export default {
-    authorization (options: any, creds: any, subres: any, headerConfig?: Record<string, any>) {
-        const requestHeader = this._generateRequestHeader(options, creds, headerConfig);
-        const authResource = this._getResource(creds, subres);
-        const stringToSign = this._buildCanonicalString(options.method.toUpperCase(), authResource, requestHeader);
-        return {
-            'authorization': `OSS ${creds.accessKeyId}:${this._computeSignature(creds.accessKeySecret, stringToSign)}`,
-            ...requestHeader
-        };
-    },
-    _generateRequestHeader (options: any, creds: any, headerConfig?: Record<string, any>) {
-        const headers: Record<string, string> = {
-            'x-oss-date': new Date(new Date().getTime() - OSSSDK.opts.timeGap).toUTCString(),
-            'content-type': options['content-type'] || 'application/octet-stream'
-        };
-
-        if (headerConfig && Object.keys(headerConfig).length > 0) {
-            Object.keys(headerConfig).forEach(key => {
-                (headers as any)[key] = (headerConfig as any)[key]
-            });
-        }
-
-        if (creds['securityToken']) {
-            (headers as any)['x-oss-security-token'] = creds['securityToken'];
-        }
-
-        return headers;
-    },
-    _getResource (creds: any, subres: any) {
-        let resource = '/';
-        if (creds.bucket) resource += `${creds.bucket}/`;
-        if (creds.fileName) resource += `${creds.fileName}`;
-        Object.keys(subres).forEach((key, index) => {
-            resource += `${index ? '&' : '?'}${key}${subres[key] ? '=' + subres[key] : ''}`;
-        });
-        return resource;
-    },
-    _buildCanonicalString (method: string, resourcePath: string, requestHeader: any) {
-        requestHeader = requestHeader || {};
-        const headers = requestHeader || {};
-        const OSS_PREFIX = 'x-oss-';
-        const ossHeaders: string[] = [];
-        const headersToSign: Record<string, string> = {} as any;
-
-        let signContent: any[] = [
-            method.toUpperCase(),
-            headers['Content-Md5'] || '',
-            headers['Content-Type'] || headers['Content-Type'.toLowerCase()],
-            headers['x-oss-date']
-        ];
-
-        Object.keys(headers).forEach((key) => {
-            const lowerKey = key.toLowerCase();
-            if (lowerKey.indexOf(OSS_PREFIX) === 0) {
-                (headersToSign as any)[lowerKey] = String(headers[key]).trim();
-            }
-        });
-
-        Object.keys(headersToSign).sort().forEach((key) => {
-            ossHeaders.push(`${key}:${(headersToSign as any)[key]}`);
-        });
-
-        signContent = signContent.concat(ossHeaders);
-        signContent.push(resourcePath);
-        return signContent.join('\n');
-    },
-    _computeSignature (accessKeySecret: string, canonicalString: string) {
-        try {
-            return cryptoBase64.stringify(cryptoHmacSHA1(canonicalString, accessKeySecret));
-        } catch (e) {
-            console.log(new Error(e as any));
-        }
-    },
-
-};
-
-

+ 0 - 74
src/utils/OSSSDK/utils/tools.ts

@@ -1,74 +0,0 @@
-export const arrange = (source: number[]) => {
-    let t: number | undefined;
-    let ta: number[] | undefined;
-    const r: number[][] = [];
-
-    source.forEach(function (v) {
-        if (t === v) {
-            (ta as number[]).push(t as number);
-            t = (t as number) + 1;
-            return;
-        }
-
-        ta = [v];
-        t = v + 1;
-        r.push(ta);
-    });
-
-    return r;
-};
-
-export const arrayUnique = (arr: any[], name: string) => {
-    const _map = new Map<string, { index: number }>();
-    const _result: any[] = [];
-
-    return arr.reduce((item: any[], next: any) => {
-        if(_map.has(next[name] + '')) {
-            item.splice((_map.get(next[name] + '') as { index: number }).index, 1, next);
-        } else {
-            item.push(next);
-            _map.set(next[name] + '', { index: item.length - 1 });
-        }
-
-        return item;
-    }, _result);
-};
-
-export const errHandler = (err: any, step: string, fileItem?: any) => {
-    try {
-        const errLog: any = { step: step, message: {} };
-        if (err.status) {
-            errLog.errName = err.data['Code']['_text'];
-            const _logSet: any = {
-                ...err.config.headers,
-                ...err.headers,
-                url: err.config['url'],
-                hostId: err.data['HostId']['_text'],
-                status: err.status,
-                statusText: err.statusText,
-                dTime: err.dTime,
-            };
-            if (fileItem) _logSet.partSize = fileItem.partSize;
-            Object.keys(_logSet).forEach(key => {
-                errLog.message[key.toLowerCase()] = _logSet[key.toString()];
-            });
-        } else {
-            errLog.errName = err.message;
-            errLog.dTime = err.dTime;
-            errLog.url = err.url;
-            if (fileItem) errLog.partSize = fileItem.partSize;
-        }
-        return errLog;
-    } catch (e) {
-        const errLog: any = { step: step };
-        errLog.errName = 'parseLogError';
-        (errLog as any).message = err;
-        return errLog;
-    }
-};
-
-export const timeSkewedHandle = () => {
-
-};
-
-

+ 0 - 7
src/utils/OSSSDK/utils/validator.ts

@@ -1,7 +0,0 @@
-export const configValid = (config: any) => {
-    if (!config) {
-        throw new Error();
-    }
-};
-
-

+ 0 - 150
src/views/publishContent/videos/components/uploadVideoModal/README.md

@@ -1,150 +0,0 @@
-# UploadVideoModal 组件
-
-基于Vue代码重构的React视频上传模态框组件,集成了OSSSDK进行文件上传。
-
-## 功能特性
-
-- ✅ 视频文件选择和验证(仅支持视频文件,最大500MB)
-- ✅ 封面图片选择和验证(仅支持图片文件,最大5MB)
-- ✅ 自动上传:选择文件后立即开始上传
-- ✅ 分片上传进度显示
-- ✅ 实时上传速度监控
-- ✅ 断点续传和重试机制
-- ✅ 视频标题编辑
-- ✅ 错误处理和用户友好的提示
-- ✅ 响应式设计
-
-## 使用方法
-
-```tsx
-import UploadVideoModal from './components/uploadVideoModal';
-
-function VideoUploadPage() {
-  const [modalVisible, setModalVisible] = useState(false);
-  const [loading, setLoading] = useState(false);
-
-  const handleUploadSuccess = (videoInfo: any) => {
-    console.log('视频上传成功:', videoInfo);
-    // 处理上传成功后的逻辑
-  };
-
-  return (
-    <div>
-      <Button onClick={() => setModalVisible(true)}>
-        上传视频
-      </Button>
-      
-      <UploadVideoModal
-        visible={modalVisible}
-        onClose={() => setModalVisible(false)}
-        onOk={handleUploadSuccess}
-        isLoading={loading}
-      />
-    </div>
-  );
-}
-```
-
-## Props
-
-| 属性 | 类型 | 默认值 | 说明 |
-|------|------|--------|------|
-| visible | boolean | - | 模态框是否显示 |
-| onClose | () => void | - | 关闭模态框回调 |
-| onOk | (videoInfo: any) => void | - | 上传成功回调 |
-| isLoading | boolean | false | 发布按钮加载状态 |
-
-## 组件结构
-
-```
-uploadVideoModal/
-├── index.tsx          # 主组件文件
-├── index.module.css   # 样式文件
-└── README.md          # 使用文档
-```
-
-## 技术实现
-
-### 核心依赖
-- **OSSSDK**: 本地OSS上传SDK,支持分片上传和断点续传
-- **Ant Design**: UI组件库
-- **React Hooks**: 状态管理和生命周期
-
-### 主要功能模块
-
-1. **视频文件上传管理**
-   - 视频文件类型和大小验证(最大500MB)
-   - 文件信息显示
-   - 上传状态管理
-   - 实时速度监控
-   - 选择文件后自动开始上传
-
-2. **封面图片上传管理**
-   - 图片文件类型和大小验证(最大5MB)
-   - 文件信息显示
-   - 上传状态管理
-   - 使用标准HTTP上传(参考editTitleCoverModal逻辑)
-   - 选择文件后自动开始上传
-
-3. **OSS集成**
-   - 获取上传凭证(仅支持视频文件)
-   - 初始化上传器
-   - 分片上传进度回调
-   - 断点续传支持
-
-4. **进度监控**
-   - 实时进度显示
-   - 上传速度计算(仅视频)
-   - 状态文本提示
-
-5. **错误处理**
-   - 重试机制
-   - 用户友好的错误提示
-   - 手动重试功能
-
-6. **视频信息编辑**
-   - 视频标题编辑
-   - 表单验证
-
-## 样式特性
-
-- 现代化UI设计
-- 响应式布局
-- 动画效果
-- 状态指示器
-- 主题色彩统一
-
-## 注意事项
-
-1. **API接口**: 需要根据实际后端API调整接口地址和参数格式
-2. **文件限制**: 当前限制视频文件最大500MB,图片文件最大5MB,可根据需要调整
-3. **重试机制**: 支持手动重试功能
-4. **浏览器兼容**: 需要支持File API和现代JavaScript特性
-
-## 自定义配置
-
-可以通过修改组件内部配置来调整:
-- 视频文件大小限制
-- 图片文件大小限制
-- 上传超时时间
-- 样式主题
-
-## 更新日志
-
-- v1.2.0: 自动上传版本
-  - 选择文件后自动开始上传
-  - 移除手动上传按钮
-  - 优化用户体验和操作流程
-
-- v1.1.0: 简化版本
-  - 支持视频和封面上传
-  - 仅保留视频标题编辑
-  - 移除复杂的分类和设置选项
-  - 优化UI布局和用户体验
-  - 封面上传使用标准HTTP上传(参考editTitleCoverModal逻辑)
-
-- v1.0.0: 基于Vue代码重构的初始版本
-  - 实现基础文件上传功能
-  - 集成OSSSDK
-  - 添加视频信息编辑
-  - 实现错误处理和重试机制

+ 0 - 269
src/views/publishContent/videos/components/uploadVideoModal/index.module.css

@@ -1,269 +0,0 @@
-.upload-video-modal {
-  padding: 20px 0;
-}
-
-.upload-section {
-  margin-bottom: 24px;
-  padding: 20px;
-  background: #fafafa;
-  border-radius: 8px;
-  border: 1px dashed #d9d9d9;
-}
-
-.file-info {
-  margin-top: 12px;
-  padding: 12px;
-  background: #fff;
-  border-radius: 6px;
-  border: 1px solid #e8e8e8;
-}
-
-.file-info p {
-  margin: 4px 0;
-  color: #666;
-  font-size: 14px;
-}
-
-.upload-progress-section {
-  margin-bottom: 24px;
-  padding: 20px;
-  background: #fff;
-  border-radius: 8px;
-  border: 1px solid #e8e8e8;
-}
-
-.progress-info {
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-  margin-bottom: 12px;
-}
-
-.file-name {
-  font-weight: 500;
-  color: #333;
-  font-size: 14px;
-}
-
-.upload-speed {
-  color: #1890ff;
-  font-size: 12px;
-  font-weight: 500;
-}
-
-.progress-text {
-  margin-top: 8px;
-  text-align: center;
-  color: #666;
-  font-size: 12px;
-}
-
-.video-info-section {
-  margin-bottom: 24px;
-  padding: 20px;
-  background: #fff;
-  border-radius: 8px;
-  border: 1px solid #e8e8e8;
-}
-
-.action-section {
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-  padding: 16px 20px;
-  background: #f8f9fa;
-  border-radius: 8px;
-  border: 1px solid #e8e8e8;
-}
-
-.left-actions {
-  flex: 1;
-}
-
-.right-actions {
-  flex: 1;
-  text-align: right;
-}
-
-/* 上传按钮样式 */
-.upload-section .ant-upload {
-  width: 100%;
-}
-
-.upload-section .ant-upload .ant-btn {
-  width: 100%;
-  height: 48px;
-  border: 1px dashed #d9d9d9;
-  background: #fff;
-  color: #666;
-  font-size: 14px;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  transition: all 0.3s;
-}
-
-.upload-section .ant-upload .ant-btn:hover {
-  border-color: #1890ff;
-  color: #1890ff;
-}
-
-/* 进度条样式 */
-.upload-progress-section .ant-progress {
-  margin: 12px 0;
-}
-
-.upload-progress-section .ant-progress-bg {
-  background: linear-gradient(90deg, #ff4383 0%, #ff6b9d 100%);
-}
-
-/* 更多设置按钮样式 */
-.more-btn {
-  display: inline-flex;
-  align-items: center;
-  color: #acacac;
-  font-size: 14px;
-  cursor: pointer;
-  transition: color 0.3s;
-}
-
-.more-btn:hover {
-  color: #1890ff;
-}
-
-.more-btn .anticon {
-  margin-right: 4px;
-}
-
-/* 发布按钮样式 */
-.publish-btn {
-  width: 104px;
-  height: 42px;
-  background: rgba(17, 17, 17, 0.01);
-  border: 1px solid rgba(236, 92, 142, 0.3);
-  border-radius: 6px;
-  color: #ec5c8e;
-  display: inline-flex;
-  align-items: center;
-  justify-content: center;
-  cursor: pointer;
-  transition: all 0.3s;
-  font-size: 14px;
-}
-
-.publish-btn:hover {
-  background: rgba(236, 92, 142, 0.1);
-  border-color: rgba(236, 92, 142, 0.5);
-}
-
-.publish-btn.disable {
-  background: rgba(17, 17, 17, 0.01) !important;
-  opacity: 0.5 !important;
-  cursor: not-allowed;
-}
-
-/* 重试按钮样式 */
-.retry-btn {
-  color: #fff;
-  background-color: #f2584f;
-  border-color: #f2584f;
-}
-
-.retry-btn:hover {
-  background-color: rgba(242, 88, 79, 0.8);
-  border-color: rgba(242, 88, 79, 0.8);
-}
-
-/* 表单样式 */
-.video-info-section .ant-form-item {
-  margin-bottom: 16px;
-}
-
-.video-info-section .ant-form-item-label > label {
-  color: #333;
-  font-weight: 500;
-}
-
-.video-info-section .ant-input,
-.video-info-section .ant-select-selector,
-.video-info-section .ant-input-number {
-  border-radius: 6px;
-}
-
-.video-info-section .ant-input:focus,
-.video-info-section .ant-input-focused {
-  border-color: #1890ff;
-  box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
-}
-
-/* 响应式设计 */
-@media (max-width: 768px) {
-  .action-section {
-    flex-direction: column;
-    gap: 12px;
-  }
-  
-  .left-actions,
-  .right-actions {
-    width: 100%;
-    text-align: center;
-  }
-  
-  .upload-section,
-  .upload-progress-section,
-  .video-info-section,
-  .action-section {
-    margin: 0 0 16px 0;
-    padding: 16px;
-  }
-}
-
-/* 动画效果 */
-.upload-progress-section {
-  animation: fadeInUp 0.3s ease-out;
-}
-
-.video-info-section {
-  animation: fadeInUp 0.3s ease-out;
-}
-
-@keyframes fadeInUp {
-  from {
-    opacity: 0;
-    transform: translateY(20px);
-  }
-  to {
-    opacity: 1;
-    transform: translateY(0);
-  }
-}
-
-/* 状态指示器 */
-.status-indicator {
-  display: inline-flex;
-  align-items: center;
-  gap: 4px;
-  font-size: 12px;
-  padding: 2px 8px;
-  border-radius: 12px;
-}
-
-.status-indicator.uploading {
-  color: #1890ff;
-  background: rgba(24, 144, 255, 0.1);
-}
-
-.status-indicator.uploaded {
-  color: #52c41a;
-  background: rgba(82, 196, 26, 0.1);
-}
-
-.status-indicator.error {
-  color: #f2584f;
-  background: rgba(242, 88, 79, 0.1);
-}
-
-.status-indicator.waiting {
-  color: #faad14;
-  background: rgba(250, 173, 20, 0.1);
-}

+ 0 - 632
src/views/publishContent/videos/components/uploadVideoModal/index.tsx

@@ -1,632 +0,0 @@
-import { Button, Modal, Upload, Progress, message, Form, Input, Space } from "antd";
-import { UploadOutlined, ReloadOutlined, PlusOutlined } from "@ant-design/icons";
-import React, { useState, useEffect, useCallback } from "react";
-import OSSSDK from "../../../../../utils/OSSSDK";
-import http from "../../../../../http";
-import styles from "./index.module.css";
-import type { UploadFile, UploadProps } from "antd/es/upload/interface";
-import { getAccessToken } from "../../../../../http/sso";
-import { adFileUpload, getTempStsToken, uploadPublishVideo } from "../../../../../http/api";
-
-interface UploadVideoModalProps {
-  visible: boolean;
-  onClose: () => void;
-  onOk?: (videoInfo: any) => void;
-  isLoading?: boolean;
-  videoInfo?: any;
-}
-
-interface UploadStatus {
-  isUploading: boolean;
-  isUploaded: boolean;
-  isError: boolean;
-  errType?: string;
-}
-
-interface UploadCreds {
-  host: string;
-  hosts: string[];
-  fileName: string;
-  upload: string;
-  accessKeyId: string;
-  accessKeySecret: string;
-  securityToken: string;
-  expiration: string;
-}
-
-const UploadVideoModal: React.FC<UploadVideoModalProps> = ({ 
-  visible, 
-  onClose, 
-  onOk, 
-  videoInfo
-}) => {
-  // 视频文件状态
-  const [videoFile, setVideoFile] = useState<File & { localUrl?: string } | null>(null);
-  const [videoUploadProgress, setVideoUploadProgress] = useState(0);
-  const [videoUploadStatus, setVideoUploadStatus] = useState<UploadStatus>({
-    isUploading: false,
-    isUploaded: false,
-    isError: false
-  });
-
-  // 封面文件状态
-  const [coverFileList, setCoverFileList] = useState<UploadFile[]>([]);
-  const [coverUploadStatus, setCoverUploadStatus] = useState<UploadStatus>({
-    isUploading: false,
-    isUploaded: false,
-    isError: false
-  });
-
-  // OSS相关状态
-  const [videoCreds, setVideoCreds] = useState<UploadCreds | null>(null);
-  const [videoUploader, setVideoUploader] = useState<OSSSDK | null>(null);
-  const [videoUrl, setVideoUrl] = useState('');
-  
-  // 重试相关状态
-  const [speedTimer, setSpeedTimer] = useState<NodeJS.Timeout | null>(null);
-
-  // 表单引用
-  const [form] = Form.useForm();
-  const [isEditMode, setIsEditMode] = useState(false);
-
-  // 视频预览
-  const [videoPreviewOpen, setVideoPreviewOpen] = useState(false);
-  const [isVideoHovering, setIsVideoHovering] = useState(false);
-  // 发布视频loading状态
-  const [publishLoading, setPublishLoading] = useState(false);
-
-  // 重置状态
-  const resetStates = useCallback(() => {
-    // 重置视频文件状态
-    setVideoFile(null);
-    setVideoUploadProgress(0);
-    setVideoUploadStatus({
-      isUploading: false,
-      isUploaded: false,
-      isError: false
-    });
-
-    // 重置封面文件状态
-    setCoverFileList([]);
-    setCoverUploadStatus({
-      isUploading: false,
-      isUploaded: false,
-      isError: false
-    });
-
-    // 重置OSS状态
-    setVideoCreds(null);
-    setVideoUploader(null);
-    setVideoUrl('');
-    setIsEditMode(false);
-
-    if (speedTimer) {
-      clearInterval(speedTimer);
-      setSpeedTimer(null);
-    }
-    form.resetFields();
-  }, [speedTimer, form]);
-
-  // 组件卸载时清理
-  useEffect(() => {
-    return () => {
-      if (speedTimer) clearInterval(speedTimer);
-      if (videoUploader) {
-        videoUploader.cancelUpload();
-      }
-    };
-	}, [speedTimer, videoUploader]);
-
-	useEffect(() => {
-		if (videoFile) {
-			startVideoUpload(videoFile);
-		}
-	}, [videoFile]);
-
-	// 当videoInfo发生变化时,初始化表单和状态
-	useEffect(() => {
-		if (visible && videoInfo) {
-			setIsEditMode(true);
-			setVideoUploadProgress(100);
-			// 填充表单数据
-			form.setFieldsValue({
-				title: videoInfo.title,
-			});
-			// 设置视频URL和状态
-			setVideoUrl(videoInfo.videoUrl);
-			setVideoUploadStatus({
-				isUploading: false,
-				isUploaded: true,
-				isError: false
-			});
-			// 设置封面文件
-			if (videoInfo.coverUrl) {
-				setCoverFileList([{
-					uid: '-1',
-					name: videoInfo.coverName || 'cover.jpg',
-					status: 'done',
-					url: videoInfo.coverUrl,
-					response: {
-						data: {
-							fileUrl: videoInfo.coverUrl
-						}
-					}
-				}]);
-				setCoverUploadStatus({
-					isUploading: false,
-					isUploaded: true,
-					isError: false
-				});
-			}
-			// 对于编辑模式,我们需要创建一个模拟的videoFile对象来显示视频预览
-			if (videoInfo.videoUrl) {
-				// 提取文件名作为显示名称
-				const fileName = videoInfo.videoName || videoInfo.videoUrl.split('/').pop() || 'video.mp4';
-				setVideoFile({
-					localUrl: videoInfo.videoUrl,
-					name: fileName,
-					type: 'video/mp4',
-					size: 0 // 实际项目中可能需要从服务器获取文件大小
-				} as File & { localUrl?: string });
-			}
-		}
-	}, [visible, videoInfo, form]);
-
-  // 获取上传凭证
-  const getSignature = async (fileType: number, uploadId?: string): Promise<UploadCreds> => {
-    try {
-      const params: any = { fileType };
-      if (uploadId) {
-        params.uploadId = uploadId;
-      }
-      // 这里需要根据实际API接口调整
-      const response = await http.post<any>(getTempStsToken, params);
-
-      if (response.code === 0) {
-        const credsData = response.data;
-        if (fileType === 2) { // 视频文件
-          setVideoUrl(credsData.fileName);
-        }
-        return credsData;
-      } else {
-        throw new Error(response.data.msg || '获取签名失败');
-      }
-    } catch (error) {
-      console.error('获取签名失败:', error);
-      throw error;
-    }
-  };
-
-  // 初始化视频上传器
-  const initVideoUploader = async (creds: UploadCreds): Promise<OSSSDK> => {
-    if (!videoFile) {
-      throw new Error('视频文件不存在');
-    }
-
-    const uploader = new OSSSDK(videoFile, creds, (checkpoint: any[]) => {
-      // 更新上传进度
-      const progress = Number((checkpoint[checkpoint.length - 1].percent * 100).toFixed(2));
-      setVideoUploadProgress(progress);
-    });
-
-    return uploader;
-  };
-
-
-  // 开始视频上传
-  const startVideoUpload = async (file?: File) => {
-    const targetFile = file || videoFile;
-    if (!targetFile) {
-      message.error('请先选择视频文件');
-      return;
-    }
-
-    try {
-      setVideoUploadStatus(prev => ({ ...prev, isUploading: true, isError: false }));
-
-      // 获取上传凭证
-      const uploadCreds = await getSignature(2); // 2表示视频文件
-      setVideoCreds(uploadCreds);
-
-      // 初始化上传器
-      const uploaderInstance = await initVideoUploader(uploadCreds);
-      setVideoUploader(uploaderInstance);
-
-      // 开始上传
-      await uploaderInstance.multipartUpload();
-
-      // 上传完成
-      setVideoUploadStatus(prev => ({ ...prev, isUploading: false, isUploaded: true }));
-			if (!isEditMode) {
-				message.success('视频上传成功');
-			}
-    } catch (error: any) {
-      console.error('视频上传失败:', error);
-      setVideoUploadStatus(prev => ({ ...prev, isUploading: false, isError: true, errType: 'uploadError' }));
-      message.error('视频上传失败,请重试');
-    }
-  };
-
-  // 封面上传处理函数
-  const handleCoverUploadChange: UploadProps['onChange'] = ({ fileList: newFileList }) => {
-    // 只保留最新的文件
-    setCoverFileList(newFileList.slice(-1));
-
-    // 如果上传成功,更新状态
-    if (newFileList.length > 0 && newFileList[0].status === 'done') {
-      setCoverUploadStatus(prev => ({ ...prev, isUploaded: true, isError: false }));
-      message.success('封面上传成功');
-    } else if (newFileList.length > 0 && newFileList[0].status === 'error') {
-      setCoverUploadStatus(prev => ({ ...prev, isError: true }));
-      message.error('封面上传失败');
-    } else if (newFileList.length > 0 && newFileList[0].status === 'uploading') {
-      setCoverUploadStatus(prev => ({ ...prev, isUploading: true, isError: false }));
-    }
-  };
-
-  // 封面文件验证
-  const checkCoverFile = (file: UploadFile) => {
-    if ((file.size || 0) > 5 * 1024 * 1024) {
-      message.error('图片大小不能超过5MB');
-      return Upload.LIST_IGNORE; // 阻止上传
-    }
-    return true; // 允许上传
-  };
-
-  // 重试视频上传
-  const handleVideoRetry = async () => {
-    setVideoUploadStatus(prev => ({ ...prev, isError: false }));
-    
-    if (videoUploader && videoCreds) {
-      try {
-        setVideoUploadStatus(prev => ({ ...prev, isUploading: true }));
-
-        // 重新获取凭证
-        const newCreds = await getSignature(2, videoCreds.upload);
-        setVideoCreds(newCreds);
-        videoUploader.updateConfig(newCreds);
-        
-        // 断点续传
-        await videoUploader.resumeMultipartUpload();
-        
-        setVideoUploadStatus(prev => ({ ...prev, isUploading: false, isUploaded: true }));
-        message.success('视频上传成功');
-        
-      } catch (error) {
-        console.error('重试视频上传失败:', error);
-        setVideoUploadStatus(prev => ({ ...prev, isUploading: false, isError: true }));
-        message.error('重试失败');
-      }
-    }
-  };
-
-  // 取消视频上传
-  const cancelVideoUpload = () => {
-    if (videoUploader) {
-      videoUploader.cancelUpload();
-    }
-    setVideoUploadStatus(prev => ({ ...prev, isUploading: false }));
-    message.info('已取消视频上传');
-  };
-
-  // 发布视频
-  const publishVideo = async () => {
-    if (!videoUploadStatus.isUploaded) {
-      message.warning('请等待视频上传完成');
-      return;
-    }
-
-    // 表单校验
-    try {
-      await form.validateFields();
-    } catch (error) {
-      message.warning('请填写完整的视频信息');
-      return;
-    }
-
-    // 校验封面是否上传
-    if (coverFileList.length === 0 || !coverUploadStatus.isUploaded) {
-      message.warning('请上传视频封面');
-      return;
-    }
-
-    try {
-      // 设置loading状态为true
-      setPublishLoading(true);
-      
-      const formData = form.getFieldsValue();
-
-      const publishData = {
-        ...formData,
-        videoUrl: isEditMode ? videoUrl : (videoCreds?.fileName || videoUrl),
-        coverUrl: coverFileList.length > 0 ? coverFileList[0].response.data.fileUrl : '',
-        fileExtensions: 'mp4', // 可以根据文件类型动态设置
-        ...(isEditMode && videoInfo?.videoId && { videoId: videoInfo.videoId })
-      };
-
-      // 这里需要根据实际API接口调整
-      const response = await http.post<any>(uploadPublishVideo, publishData);
-      if (response.code === 0) {
-        message.success('发布成功');
-        onOk?.(response.data);
-        onClose();
-        resetStates();
-      } else {
-        message.error(response.msg || '发布失败');
-      }
-    } catch (error) {
-      console.error('发布失败:', error);
-      message.error('发布失败,请重试');
-    } finally {
-      // 请求结束后(无论成功或失败),设置loading状态为false
-      setPublishLoading(false);
-    }
-  };
-
-  // 视频文件上传前处理
-  const beforeVideoUpload = (file: File & { localUrl?: string }) => {
-    // 验证文件类型
-    const isVideo = file.type.startsWith('video/');
-    if (!isVideo) {
-      message.error('只能上传视频文件!');
-      return false;
-    }
-
-    // 验证文件大小 (例如:限制500MB)
-    const isLt500M = file.size / 1024 / 1024 < 500;
-    if (!isLt500M) {
-      message.error('视频大小不能超过500MB!');
-      return false;
-		}
-		
-		file.localUrl = URL.createObjectURL(file);
-
-    setVideoFile(file);
-    setVideoUploadProgress(0);
-    setVideoUploadStatus({
-      isUploading: false,
-      isUploaded: false,
-      isError: false
-    });
-    
-    return false; // 阻止自动上传
-  };
-
-  // 删除视频文件
-  const handleVideoRemove = () => {
-    setVideoFile(null);
-    setVideoUploadProgress(0);
-    setVideoUploadStatus({
-      isUploading: false,
-      isUploaded: false,
-      isError: false
-    });
-    if (videoUploader) {
-      videoUploader.cancelUpload();
-    }
-  };
-
-  // 删除封面文件
-  const handleCoverRemove = () => {
-    setCoverFileList([]);
-    setCoverUploadStatus({
-      isUploading: false,
-      isUploaded: false,
-      isError: false
-    });
-  };
-
-  // 获取视频进度文本
-  const getVideoProgressText = () => {
-    if (videoUploadStatus.isError) {
-      return '上传失败,点击重试重新上传';
-    } else if (!videoUploadStatus.isUploading && videoUploadStatus.isUploaded) {
-      return '上传完成';
-    } else if (!videoUploadStatus.isUploading && !videoUploadStatus.isUploaded) {
-      return '等待中...';
-    } else {
-      return '';
-    }
-  };
-
-  // 获取封面进度文本
-  const getCoverProgressText = () => {
-    if (coverUploadStatus.isError) {
-      return '上传失败,请重新选择文件';
-    } else if (!coverUploadStatus.isUploading && coverUploadStatus.isUploaded) {
-      return '上传完成';
-    } else if (coverFileList.length > 0 && coverFileList[0].status === 'uploading') {
-      return '上传中...';
-    } else {
-      return '';
-    }
-  };
-
-
-  return (
-    <>
-    <Modal 
-      open={visible} 
-      onCancel={() => {
-        onClose();
-        resetStates();
-      }} 
-      footer={null}
-      width={800}
-      title={isEditMode ? "修改视频" : "上传视频"}
-      destroyOnHidden
-    >
-      <div className={styles['upload-video-modal']}>
-        {/* 视频上传区域:上传成功后隐藏选择模块 */}
-        {!videoFile && (
-          <div className={styles['upload-section']}>
-            <h4>视频文件</h4>
-            <Upload
-              fileList={[]}
-              beforeUpload={beforeVideoUpload}
-              onRemove={handleVideoRemove}
-              accept="video/*"
-              maxCount={1}
-              showUploadList={false}
-            >
-              <Button icon={<UploadOutlined />} disabled={videoUploadStatus.isUploading}>
-                选择视频文件
-              </Button>
-            </Upload>
-          </div>
-        )}
-
-        {/* 视频上传进度区域 */}
-        {videoFile && (
-          <div className={styles['upload-progress-section']}>
-            <div style={{ display: 'flex', gap: 16, alignItems: 'center' }}>
-              <div 
-                style={{ width: 124, height: 104, background: '#fafafa', border: '1px dashed #d9d9d9', borderRadius: 8, display: 'flex', alignItems: 'center', justifyContent: 'center', overflow: 'hidden', position: 'relative' }}
-                onMouseEnter={() => setIsVideoHovering(true)}
-                onMouseLeave={() => setIsVideoHovering(false)}
-              >
-                <video src={videoFile.localUrl} style={{ width: '100%', height: '100%', objectFit: 'cover' }} muted />
-                {!videoUploadStatus.isUploading && isVideoHovering && (
-                  <div style={{ position: 'absolute', inset: 0, background: 'rgba(0,0,0,0.35)' }}>
-                    <div style={{ position: 'absolute', left: 0, right: 0, bottom: 0, display: 'flex', justifyContent: 'center', padding: 8, gap: 3 }}>
-                      <Button size="small" type="primary" onClick={() => setVideoPreviewOpen(true)}>
-                        预览
-                      </Button>
-                      {!isEditMode &&
-                        <Button size="small" danger onClick={handleVideoRemove}>
-                          删除
-                        </Button>
-                      }
-                    </div>
-                  </div>
-                )}
-              </div>
-
-              <div style={{ flex: 1 }}>
-                <div className={styles['progress-info']}>
-                  <span className={styles['file-name']}>{videoFile.name}</span>
-                </div>
-                <Progress 
-                  percent={videoUploadProgress} 
-                  status={videoUploadStatus.isError ? 'exception' : 'active'}
-                  strokeColor={videoUploadStatus.isError ? '#F2584F' : '#FF4383'}
-                />
-                {!isEditMode ? <div className={styles['progress-text']}>{getVideoProgressText()}</div> : null}
-              </div>
-            </div>
-          </div>
-        )}
-
-        {/* 封面上传区域 */}
-        <div className={styles['upload-section']}>
-          <h4>封面图片</h4>
-          <Upload
-            action={adFileUpload}
-            headers={{
-              token: getAccessToken()
-            }}
-            accept="image/*"
-            listType="picture-card"
-            beforeUpload={checkCoverFile}
-            onChange={handleCoverUploadChange}
-            fileList={coverFileList}
-            showUploadList={{ showPreviewIcon: false }}
-            maxCount={1}
-            data={{ fileType: 'PICTURE' }}
-            onRemove={handleCoverRemove}
-          >
-            {coverFileList.length >= 1 ? null : (
-              <button style={{ border: 0, background: 'none' }} type="button">
-                <PlusOutlined />
-                <div style={{ marginTop: 8 }}>
-                  {coverUploadStatus.isUploaded ? '已选择封面' : '上传封面'}
-                </div>
-              </button>
-            )}
-          </Upload>
-          
-          {!isEditMode && getCoverProgressText() && (
-            <div className={styles['progress-text']}>{getCoverProgressText()}</div>
-          )}
-        </div>
-
-        {/* 视频信息编辑区域 */}
-        <div className={styles['video-info-section']}>
-          <Form form={form} layout="vertical">
-            <Form.Item
-              label="视频标题"
-              name="title"
-              rules={[{ required: true, message: '请输入视频标题' }]}
-            >
-              <Input placeholder="请输入视频标题" />
-            </Form.Item>
-          </Form>
-        </div>
-
-        {/* 操作按钮区域 */}
-        <div className={styles['action-section']}>
-          <div className={styles['right-actions']}>
-            <Space>
-              {/* 视频上传操作 */}
-              {videoFile && !isEditMode && (
-                <>
-                  {videoUploadStatus.isUploading && (
-                    <Button onClick={cancelVideoUpload}>
-                      取消视频上传
-                    </Button>
-                  )}
-                  
-                  {videoUploadStatus.isError && (
-                    <Button 
-                      type="primary" 
-                      danger
-                      icon={<ReloadOutlined />}
-                      onClick={handleVideoRetry}
-                      className={styles['retry-btn']}
-                    >
-                      重试视频
-                    </Button>
-                  )}
-
-                  {!videoUploadStatus.isUploading && videoUploadStatus.isUploaded && (
-                    <Button 
-                      danger
-                      onClick={handleVideoRemove}
-                    >
-                      删除已上传视频
-                    </Button>
-                  )}
-                </>
-              )}
-
-              {/* 发布按钮 */}
-              {videoUploadStatus.isUploaded && (
-                <Button 
-                  type="primary" 
-                  onClick={publishVideo}
-                  loading={publishLoading}
-                >
-                  发布视频
-                </Button>
-              )}
-            </Space>
-          </div>
-        </div>
-      </div>
-    </Modal>
-    {/* 视频预览弹窗 */}
-    <Modal
-      open={videoPreviewOpen}
-      onCancel={() => setVideoPreviewOpen(false)}
-      footer={null}
-      width={720}
-      title="预览视频"
-      destroyOnHidden
-    >
-      <video src={videoFile?.localUrl} style={{ height: '100%', margin: '0 auto' }} controls />
-    </Modal>
-    </>
-  );
-};
-
-export default UploadVideoModal;

+ 16 - 79
src/views/publishContent/videos/index.tsx

@@ -3,15 +3,15 @@ import React, { useState, useEffect } from 'react';
 import styles from './index.module.css';
 import http from '@src/http/index';
 import { uploadContentList, uploadDeleteVideo } from "@src/http/api";
-import UploadVideoModal from './components/uploadVideoModal';
 import { enumToOptions } from '@src/utils/helper';
 import { UploadContentResponse } from './type';
 import dayjs from 'dayjs';
 import VideoPlayModal from '../weCom/components/videoPlayModal';
-import { UserInfo } from '../../setting/type';
-// Define a type for the expected API response (adjust if needed based on actual API)
+
 const TableHeight = window.innerHeight - 380;
 
+const UPLOAD_DEPRECATED_NOTICE_KEY = 'pq_upload_deprecated_notice_v1';
+
 enum AuditStatus {
 	待审核 = 0,
 	审核中 = 1,
@@ -29,35 +29,22 @@ const MyVideos: React.FC = () => {
 	const [pageSize, setPageSize] = useState(10);
 
 	const [isVideoPlayModalVisible, setIsVideoPlayModalVisible] = useState<boolean>(false);
-	const [isShowUploadVideoModal, setIsShowUploadVideoModal] = useState(false);
 	const [playVideoUrl, setPlayVideoUrl] = useState('');
 	const [playVideoTitle, setPlayVideoTitle] = useState('');
-	const [isAddPlanLoading] = useState(false);
-	const [editingVideo, setEditingVideo] = useState<any>(null);
-	const [pqUserInfo, setPqUserInfo] = useState<UserInfo | null>(null);
-	const [showLoginModal, setShowLoginModal] = useState(false);
-	
-	// 页面加载时调用getTableData和检查用户登录状态
+
 	useEffect(() => {
 		getTableData();
-		checkUserLoginStatus();
-	}, []);
-
-	// 检查用户登录状态
-	const checkUserLoginStatus = () => {
-		const userInfoStr = localStorage.getItem('pq_userInfo');
-		if (userInfoStr) {
-			try {
-				const userInfo = JSON.parse(userInfoStr) as UserInfo;
-				setPqUserInfo(userInfo);
-			} catch (error) {
-				console.error('解析用户信息失败', error);
-				setPqUserInfo(null);
-			}
-		} else {
-			setPqUserInfo(null);
+		if (localStorage.getItem(UPLOAD_DEPRECATED_NOTICE_KEY) !== '1') {
+			Modal.info({
+				title: '版本升级',
+				content: '当前只可查询历史上传内容,已不支持上传',
+				okText: '我知道了',
+				onOk: () => {
+					localStorage.setItem(UPLOAD_DEPRECATED_NOTICE_KEY, '1');
+				},
+			});
 		}
-	};
+	}, []);
 
 	const getTableData = async (_pageNum?: number, _pageSize?: number) => {
 		setIsLoading(true);
@@ -117,7 +104,7 @@ const MyVideos: React.FC = () => {
 			title: '操作',
 			render: (_, record) => {
 				return <>
-					{record.auditStatus === 3 ? <><span className="text-blue-500 underline cursor-pointer" onClick={() => { handleEditVideo(record) }}>修改视频</span>&emsp;</> : record.auditStatus === 2 ? <><span className="text-blue-500 underline cursor-pointer" onClick={() => { uploadPublishVideo(record) }}>创建发布</span>&emsp;</> : ''}
+					{record.auditStatus === 2 ? <><span className="text-blue-500 underline cursor-pointer" onClick={() => { uploadPublishVideo(record) }}>创建发布</span>&emsp;</> : ''}
 					<Popconfirm
 						title="确定删除该视频吗?"
 						okText="确定"
@@ -130,27 +117,6 @@ const MyVideos: React.FC = () => {
 		}
 	]
 
-	const handleUploadVideo = () => {
-		// 检查用户是否已登录
-		if (!pqUserInfo) {
-			setShowLoginModal(true);
-			return;
-		}
-		setEditingVideo(null);
-		setIsShowUploadVideoModal(true);
-		getTableData(pageNum, pageSize)
-	}
-
-	const handleEditVideo = (record: any) => {
-		// 检查用户是否已登录
-		if (!pqUserInfo) {
-			setShowLoginModal(true);
-			return;
-		}
-		setEditingVideo(record);
-		setIsShowUploadVideoModal(true);
-	}
-
 	const playVideo = (record: any) => () => {
 		setPlayVideoUrl(record.videoUrl);
 		setIsVideoPlayModalVisible(true);
@@ -177,18 +143,11 @@ const MyVideos: React.FC = () => {
 		return location.href = '/publishContent/wegzh/' + record.videoId;
 	}
 
-	// 引导用户去登录
-	const goToLogin = () => {
-		setShowLoginModal(false);
-		window.location.href = '/setting';
-	}
-
 	return (
 		<Spin spinning={isLoading}>
 			<div className="rounded-lg">
 				<div className="flex justify-between items-center mb-3">
 					<div className="text-lg font-medium">上传内容管理</div>
-					<Button type="primary" onClick={handleUploadVideo}>+ 上传视频</Button>
 				</div>
 				{/* 搜索区域 */}
 				<div className="flex flex-wrap gap-4 mb-3">
@@ -218,7 +177,7 @@ const MyVideos: React.FC = () => {
 
 					<Button type="primary" className="ml-2" onClick={() => getTableData(1)}>搜索</Button>
 				</div>
-				
+
 				<Table
 					rowKey={(record) => record.id}
 					className={styles.antTable}
@@ -237,34 +196,12 @@ const MyVideos: React.FC = () => {
 						}
 					}}
 				/>
-				<UploadVideoModal
-					visible={isShowUploadVideoModal}
-					onClose={() => {
-						setIsShowUploadVideoModal(false);
-					}}
-					onOk={handleUploadVideo}
-					isLoading={isAddPlanLoading}
-					videoInfo={editingVideo}
-				/>
 				<VideoPlayModal
 					visible={isVideoPlayModalVisible}
 					onClose={() => setIsVideoPlayModalVisible(false)}
 					videoUrl={playVideoUrl}
 					title={playVideoTitle}
 				/>
-				<Modal
-					visible={showLoginModal}
-					title="请先登录"
-					onCancel={() => setShowLoginModal(false)}
-					footer={null}
-				>
-					<div className="text-center py-6">
-						<p className="mb-4">您需要先登录才能上传或编辑视频</p>
-						<Button type="primary" onClick={goToLogin}>
-							去登录
-						</Button>
-					</div>
-				</Modal>
 			</div>
 		</Spin>
 	);

+ 2 - 25
src/views/publishContent/weCom/components/videoSelectModal/index.tsx

@@ -14,16 +14,11 @@ import {
 import { CheckCircleFilled, CaretRightFilled } from '@ant-design/icons';
 import { VideoListResponse } from '@src/views/publishContent/weGZH/components/types';
 import http from '@src/http';
-import { getVideoContentListApi, getUploadVideoContentListApi } from '@src/http/api';
+import { getVideoContentListApi } from '@src/http/api';
 import { useVideoCategoryOptions } from '@src/views/publishContent/weGZH/hooks/useVideoCategoryOptions';
 import { WeComPlanType, WeVideoItem, VideoSearchPlanType } from '@src/views/publishContent/weCom/type'
 import { enumToOptions } from '@src/utils/helper';
 
-export enum VideoLibraryType {
-	平台视频库 = 0,
-	我的上传 = 1,
-}
-
 const { Text, Paragraph } = Typography;
 
 interface VideoSelectModalProps {
@@ -54,7 +49,6 @@ const VideoSelectModal: React.FC<VideoSelectModalProps> = ({ visible, onClose, o
 	const [videoListAll, setVideoListAll] = useState<WeVideoItem[]>([]);
 	const [selectedVideoIds, setSelectedVideoIds] = useState<Set<number>>(new Set(initialSelectedIds));
 	const [playingVideo, setPlayingVideo] = useState<WeVideoItem | null>(null);
-	const [videoLibraryType, setVideoLibraryType] = useState<VideoLibraryType>(VideoLibraryType.平台视频库);
 	const MAX_SELECTION = 3;
 
 	const getVideoList = async (pageNum?: number, _pageSize?: number) => {
@@ -62,9 +56,6 @@ const VideoSelectModal: React.FC<VideoSelectModalProps> = ({ visible, onClose, o
 		setCurrentPage(pageNum || currentPage);
 		setPageSize(_pageSize || pageSize);
 
-		// 根据视频库类型选择不同的API
-		const apiUrl = videoLibraryType === VideoLibraryType.平台视频库 ? getVideoContentListApi : getUploadVideoContentListApi;
-
 		const requestParams = {
 			category,
 			title: searchTerm,
@@ -74,7 +65,7 @@ const VideoSelectModal: React.FC<VideoSelectModalProps> = ({ visible, onClose, o
 			pageSize: _pageSize || pageSize,
 		};
 
-		const res = await http.post<VideoListResponse>(apiUrl, requestParams).catch(() => {
+		const res = await http.post<VideoListResponse>(getVideoContentListApi, requestParams).catch(() => {
 			message.error('获取视频列表失败');
 		}).finally(() => {
 			setLoading(false);
@@ -87,11 +78,6 @@ const VideoSelectModal: React.FC<VideoSelectModalProps> = ({ visible, onClose, o
 		}
 	}
 
-	// 监听视频库类型变化,重新加载数据
-	useEffect(() => {
-		getVideoList();
-	}, [videoLibraryType]);
-
 	useEffect(() => {
 		getVideoList();
 	}, []);
@@ -199,15 +185,6 @@ const VideoSelectModal: React.FC<VideoSelectModalProps> = ({ visible, onClose, o
 				}
 			>
 				<div className="flex flex-wrap gap-2 mb-6">
-					<div className="flex items-center gap-2">
-						<span className="text-gray-600">视频来源:</span>
-						<Select
-							style={{ width: 120 }}
-							value={videoLibraryType}
-							onChange={setVideoLibraryType}
-							options={enumToOptions(VideoLibraryType)}
-						/>
-					</div>
 					<div className="flex items-center gap-2">
 						<span className="text-gray-600">排序选项:</span>
 						<Select

+ 0 - 12
src/views/publishContent/weGZH/components/publishPlanModal/index.tsx

@@ -1,5 +1,4 @@
 import React, { useEffect, useState } from 'react';
-import { useParams } from 'react-router-dom';
 import { Modal, Form, Select, Button, Card, Typography, message } from 'antd';
 import { CloseOutlined, PlusOutlined, EditOutlined, CaretRightFilled } from '@ant-design/icons';
 import VideoSelectModal from '../videoSelectModal';
@@ -7,7 +6,6 @@ import EditTitleCoverModal from '../editTitleCoverModal';
 import { VideoItem } from '../types'; // Import from common types
 import { GzhPlanDataType, GzhPlanType } from '../../hooks/useGzhPlanList';
 import { useAccountOptions } from '../../hooks/useAccountOptions';
-import { VideoLibraryType } from '@src/views/publishContent/weCom/components/videoSelectModal';
 
 const { Option } = Select;
 const { Paragraph } = Typography;
@@ -26,23 +24,14 @@ interface AddPunlishPlanModalProps {
 const AddPunlishPlanModal: React.FC<AddPunlishPlanModalProps> = ({ visible, isSubmiting, onCancel, onOk, actionType, planType, editPlanData, videoId }) => {
 	const [form] = Form.useForm();
 	const type = Form.useWatch('type', form);
-	const { code } = useParams<{ code?: string }>();
 	const selectVideoType = Form.useWatch('selectVideoType', form);
 	const [selectedVideos, setSelectedVideos] = useState<VideoItem[]>([]);
 	const [isVideoSelectVisible, setIsVideoSelectVisible] = useState(false);
 	const [playingVideo, setPlayingVideo] = useState<VideoItem | null>(null); // State for video player modal
 	const [editingVideo, setEditingVideo] = useState<VideoItem | null>(null); // State for editing modal
 	const [initialSelectedVideoId, setInitialSelectedVideoId] = useState<string | null>(null); // State for initial video selection
-	const [videoLibraryType, setVideoLibraryType] = useState<VideoLibraryType>(VideoLibraryType.平台视频库);
 	const { accountOptions, getAccountList } = useAccountOptions();
 
-	// 处理code参数
-	useEffect(() => {
-		if (code) {
-			setVideoLibraryType(VideoLibraryType.我的上传);
-		}
-	}, [code]);
-
 	useEffect(() => {
 		if (actionType === 'edit') {
 			form.setFieldsValue({...editPlanData, type: editPlanData?.type.toString()});
@@ -334,7 +323,6 @@ const AddPunlishPlanModal: React.FC<AddPunlishPlanModalProps> = ({ visible, isSu
 				onOk={handleVideoSelectionOk}
 				selectedVideos={selectedVideos}
 				initialSelectedIds={initialSelectedVideoId ? [Number(initialSelectedVideoId)] : selectedVideos.map(v => v.videoId)}
-				defaultVideoLibraryType={videoLibraryType}
 			/>
 
 			{/* Video Player Modal */}

+ 0 - 1
src/views/publishContent/weGZH/components/types.ts

@@ -11,7 +11,6 @@ export interface VideoItem {
 	videoId: number,
 	industryFissionRate: number,
 	channelFissionRate: number,
-	videoLibraryType?: number;
 	recommendScore: number,
 } 
 

+ 4 - 38
src/views/publishContent/weGZH/components/videoSelectModal/index.tsx

@@ -14,9 +14,9 @@ import {
 import { CheckCircleFilled, CaretRightFilled } from '@ant-design/icons';
 import { VideoItem, VideoListResponse } from '../types';
 import http from '@src/http';
-import { getVideoContentListApi, getUploadVideoContentListApi } from '@src/http/api';
+import { getVideoContentListApi } from '@src/http/api';
 import { useVideoCategoryOptions } from '../../hooks/useVideoCategoryOptions';
-import { VideoSortType, VideoLibraryType } from '@src/views/publishContent/weCom/components/videoSelectModal';
+import { VideoSortType } from '@src/views/publishContent/weCom/components/videoSelectModal';
 import { GzhPlanType } from '../../hooks/useGzhPlanList';
 import { VideoSearchPlanType } from '@src/views/publishContent/weCom/type';
 import { enumToOptions } from '@src/utils/helper';
@@ -30,10 +30,9 @@ interface VideoSelectModalProps {
 	onOk: (selectedVideos: VideoItem[]) => void;
 	initialSelectedIds?: number[];
 	selectedVideos?: VideoItem[];
-	defaultVideoLibraryType?: VideoLibraryType;
 }
 
-const VideoSelectModal: React.FC<VideoSelectModalProps> = ({ planType, visible, onClose, onOk, initialSelectedIds = [], selectedVideos = [], defaultVideoLibraryType }) => {
+const VideoSelectModal: React.FC<VideoSelectModalProps> = ({ planType, visible, onClose, onOk, initialSelectedIds = [], selectedVideos = [] }) => {
 	const { videoCategoryOptions } = useVideoCategoryOptions();
 	const [category, setCategory] = useState<string>();
 	const [sort, setSort] = useState<VideoSortType>(VideoSortType.推荐指数);
@@ -46,16 +45,8 @@ const VideoSelectModal: React.FC<VideoSelectModalProps> = ({ planType, visible,
 	const [videoListAll, setVideoListAll] = useState<VideoItem[]>([]);
 	const [selectedVideoIds, setSelectedVideoIds] = useState<Set<number>>(new Set(initialSelectedIds));
 	const [playingVideo, setPlayingVideo] = useState<VideoItem | null>(null);
-	const [videoLibraryType, setVideoLibraryType] = useState<VideoLibraryType>(defaultVideoLibraryType || VideoLibraryType.平台视频库);
 	const MAX_SELECTION = 3;
 
-	// 当默认视频来源变化时更新状态
-	useEffect(() => {
-		if (defaultVideoLibraryType) {
-			setVideoLibraryType(defaultVideoLibraryType);
-		}
-	}, [defaultVideoLibraryType]);
-
 	const getVideoListType = (planType: GzhPlanType) => {
 		if (planType === GzhPlanType.自动回复) {
 			return VideoSearchPlanType.自动回复;
@@ -70,8 +61,6 @@ const VideoSelectModal: React.FC<VideoSelectModalProps> = ({ planType, visible,
 		setLoading(true);
 		setCurrentPage(pageNum || currentPage);
 		setPageSize(_pageSize || pageSize);
-		// 根据视频库类型选择不同的API
-		const apiUrl = videoLibraryType === VideoLibraryType.平台视频库 ? getVideoContentListApi : getUploadVideoContentListApi;
 
 		const requestParams = {
 			category,
@@ -82,26 +71,18 @@ const VideoSelectModal: React.FC<VideoSelectModalProps> = ({ planType, visible,
 			pageSize: _pageSize || pageSize,
 		};
 
-		const res = await http.post<VideoListResponse>(apiUrl, requestParams).catch(() => {
+		const res = await http.post<VideoListResponse>(getVideoContentListApi, requestParams).catch(() => {
 			message.error('获取视频列表失败');
 		}).finally(() => {
 			setLoading(false);
 		});
 		if (res && res.code === 0) {
-			selectedVideos = selectedVideos.filter(item => item.videoLibraryType === videoLibraryType)
 			setVideoList([...selectedVideos, ...res.data.objs.filter(v => !selectedVideos.find(ov => ov.videoId === v.videoId))]);
 			setVideoListAll(old => [...old, ...res.data.objs.filter(v => !old.find(ov => ov.videoId === v.videoId))]);
 			setTotal(res.data.totalSize);
 		}
 	}
 
-	// 监听视频库类型变化,重新加载数据
-	useEffect(() => {
-		if (visible) {
-			getVideoList();
-		}
-	}, [videoLibraryType, visible]);
-
 	useEffect(() => {
 		if (visible) {
 			setVideoList(selectedVideos);
@@ -141,12 +122,6 @@ const VideoSelectModal: React.FC<VideoSelectModalProps> = ({ planType, visible,
 
 	const handleOk = () => {
 		const _selectedVideos = videoListAll.filter(video => selectedVideoIds.has(video.videoId));
-		_selectedVideos.forEach(video => {
-			// 加入视频库类型
-			if (!('videoLibraryType' in video)) {
-				video.videoLibraryType = videoLibraryType
-			}
-		});
 		onOk(_selectedVideos);
 		onClose();
 	};
@@ -194,15 +169,6 @@ const VideoSelectModal: React.FC<VideoSelectModalProps> = ({ planType, visible,
 				}
 			>
 				<div className="flex flex-wrap gap-2 mb-6">
-					<div className="flex items-center gap-2">
-						<span className="text-gray-600">视频来源:</span>
-						<Select
-							style={{ width: 120 }}
-							value={videoLibraryType}
-							onChange={setVideoLibraryType}
-							options={enumToOptions(VideoLibraryType)}
-						/>
-					</div>
 					<div className="flex items-center gap-2">
 						<span className="text-gray-600">排序选项:</span>
 						<Select