-
-
{{
- $t('pages.setting.editSource.template') }}
-
- {{ $t('pages.setting.editSource.templateTip') }}
-
-
-
-
-
-
+
+
+
+
+
+
- {{
+ {{
$t('pages.setting.editSource.action.source') }}
-
+
+
+
+
{{ $t('pages.setting.editSource.reqHeaderTitle') }}
+
+
+
+
{{ $t('pages.setting.editSource.reqBodyTitle') }}
+
+
+
+
+
+
@@ -228,7 +261,7 @@ import JSON5 from "json5";
import { computed, nextTick, onBeforeUnmount, onMounted, reactive, ref, watch } from 'vue';
import { useRouter } from 'vue-router';
import { MessagePlugin } from 'tdesign-vue-next';
-import { BugIcon, DeleteIcon, FileDownloadIcon, FileExportIcon, FileImportIcon, HelpRectangleIcon, InternetIcon, GestureClickIcon } from 'tdesign-icons-vue-next';
+import { BugIcon, DeleteIcon, ExtensionIcon, FileDownloadIcon, FileExportIcon, FileImportIcon, HelpRectangleIcon, InternetIcon, GestureClickIcon, TransformIcon } from 'tdesign-icons-vue-next';
import jsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker';
import htmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker';
import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker';
@@ -273,6 +306,13 @@ let form = ref({
template: 'mxpro',
url: '',
nav: 'debug',
+ req: {
+ method: 'GET',
+ header: '',
+ body: '',
+ url: '',
+ contentType: 'application/json'
+ },
detail: {
ids: ''
},
@@ -315,7 +355,8 @@ let form = ref({
const isVisible = reactive({
template: false,
player: false,
- help: false
+ help: false,
+ reqParam: false
});
const formDialog = reactive({
@@ -361,6 +402,44 @@ interface EditorConfig {
wordWrap: WordWrapOptions;
}
+const reqMethods = [
+ {
+ label: 'GET',
+ value: 'GET',
+ },
+ {
+ label: 'POST',
+ value: 'POST',
+ },
+ {
+ label: 'DELETE',
+ value: 'DELETE',
+ },
+ {
+ label: 'PUT',
+ value: 'PUT',
+ },
+ {
+ label: 'OPTIONS',
+ value: 'OPTIONS',
+ },
+ {
+ label: 'HEAD',
+ value: 'HEAD',
+ }
+];
+
+const reqContentTypes = [
+ {
+ label: 'application/json',
+ value: 'application/json',
+ },
+ {
+ label: 'application/x-www-form-urlencoded',
+ value: 'application/x-www-form-urlencoded',
+ },
+];
+
const config = reactive({
theme: systemTheme.value === 'light' ? 'vs' : 'vs-dark',
language: 'javascript',
@@ -676,6 +755,13 @@ const performAction = async (type, requestData = {}) => {
};
const res: any = await t3Work({ type, data: requestData });
form.value.content.debug = res.data as string;
+ switch (type) {
+ case 'play':
+ if (res.data?.url) form.value.player.url = res.data.url;
+ break;
+ case 'detail':
+ break;
+ }
form.value.action = type;
changeNav('debug', type);
MessagePlugin.success(t('pages.setting.data.success'));
@@ -787,12 +873,43 @@ const actionPlayer = async (url = "") => {
};
const getSource = async () => {
- const url = form.value.url;
- if (url) {
- const res = await getConfig(url);
- form.value.content.source = res;
+ let { url, method, header, body, contentType } = form.value.req;
+ header = header ? header : '{}';
+ body = body ? body : '{}';
+
+ if (!url) return;
+
+ try {
+ const parsedHeader = JSON5.parse(header);
+ let parsedBody = JSON5.parse(body);
+
+ if (method !== 'GET' && parsedBody) {
+ parsedHeader['Content-Type'] = contentType;
+ if (contentType === 'application/x-www-form-urlencoded') {
+ parsedBody instanceof URLSearchParams
+ ? parsedBody
+ : (parsedBody = new URLSearchParams(parsedBody));
+ }
+ }
+
+ const response = await getConfig(url, method, parsedHeader, parsedBody);
+
+ form.value.content.source = response;
changeNav('source', 'html');
- };
+ } catch (error) {
+ console.error('Error parsing header or body:', error);
+ }
+};
+
+const showReqParamDialog = () => {
+ isVisible.reqParam = true;
+};
+
+const reqCancel = (e) => {
+ form.value.req.header = '';
+ form.value.req.body = '';
+ form.value.req.contentType = 'application/json';
+ e.preventDefault();
};
const showTemplateDialog = () => {
@@ -979,6 +1096,34 @@ const proxyEvent = async () => {
:deep(.t-input-adornment) {
width: 100%;
+
+ .input-container {
+ width: inherit;
+ background-color: var(--td-bg-content-input) !important;
+ display: flex;
+ flex-direction: row;
+ flex-wrap: nowrap;
+ align-items: center;
+ justify-content: space-between;
+
+ .method {
+ margin-right: 5px;
+ width: 24px;
+ height: 24px;
+ border-radius: var(--td-radius-default);
+ background-color: var(--td-bg-color-component);
+ display: flex;
+ flex-direction: row;
+ align-content: center;
+ align-items: center;
+ justify-content: center;
+ cursor: pointer;
+ }
+
+ .contentType {
+ margin-bottom: 5px;
+ }
+ }
}
}
@@ -1185,7 +1330,8 @@ const proxyEvent = async () => {
:deep(.t-input),
:deep(.t-input-number__increase),
:deep(.t-input-number__decrease),
-:deep(.t-input-adornment__text) {
+:deep(.t-input-adornment__text),
+:deep(.t-textarea__inner) {
background-color: var(--td-bg-content-input) !important;
border-color: transparent;
box-shadow: none;
diff --git a/src/renderer/src/utils/tool.ts b/src/renderer/src/utils/tool.ts
index cd6ae51e1..04974a7cd 100644
--- a/src/renderer/src/utils/tool.ts
+++ b/src/renderer/src/utils/tool.ts
@@ -4,20 +4,36 @@ import ip from 'ip';
axios.defaults.withCredentials = true; //让ajax携带cookie
-const getConfig = async (url, header = {}) => {
+const getConfig = async (url: string, method = 'GET', headers = {}, body = {}) => {
try {
- let res;
- if( header ) res = await axios.get(url, {headers: { ...header }});
- else res = await axios.get(url);
- let response;
+ const customHeaders = {
+ 'Cookie': 'custom-cookie',
+ 'User-Agent': 'custom-ua',
+ 'Referer': 'custom-referer',
+ };
+ for (const [originalHeader, customHeader] of Object.entries(customHeaders)) {
+ if (headers.hasOwnProperty(originalHeader)) {
+ headers[customHeader] = headers[originalHeader];
+ delete headers[originalHeader];
+ }
+ }
+
+ const response = await axios({
+ method,
+ url,
+ data: method !== 'GET' ? body : undefined,
+ headers: headers || undefined
+ })
+
+ let responseData;
try {
- response = JSON5.parse(res.data);
- } catch (err) {
- response = res.data;
+ responseData = JSON5.parse(response.data);
+ } catch (parseError) {
+ responseData = response.data;
}
- return response || false;
+ return responseData || false;
} catch (err) {
throw err;
}
@@ -25,9 +41,9 @@ const getConfig = async (url, header = {}) => {
// 判断媒体类型
const checkMediaType = async (url: string): Promise => {
- const supportedFormats: string[] = ['mp4', 'mkv', 'flv', 'm3u8', 'avi'];
+ const supportedFormats: string[] = ['mp4', 'mkv', 'flv', 'm3u8', 'avi', 'magnet'];
- if (url.startsWith('http')) {
+ if (url.startsWith('http') || url.startsWith('magnet')) {
const fileType = supportedFormats.find(format => url.includes(format));
if (fileType) {
return fileType;
@@ -92,7 +108,7 @@ const checkLiveM3U8 = async(url: string): Promise =>{
try {
const res = await axios.get(url);
const m3u8Content = res.data;
-
+
const isLiveStream = !(
m3u8Content.indexOf('#EXT-X-ENDLIST') !== -1 ||
(m3u8Content.indexOf('#EXT-X-PLAYLIST-TYPE') !== -1 &&
@@ -100,7 +116,7 @@ const checkLiveM3U8 = async(url: string): Promise =>{
(m3u8Content.indexOf('#EXT-X-MEDIA-SEQUENCE') !== -1 &&
parseInt(m3u8Content.match(/#EXT-X-MEDIA-SEQUENCE:(\d+)/)[1]) === 0)
);
-
+
return isLiveStream;
} catch (err) {
return false;
@@ -116,4 +132,4 @@ const copyToClipboardApi = async (text: string): Promise => {
}
};
-export { getConfig, getMeadiaType, checkMediaType, checkUrlIpv6, checkLiveM3U8, copyToClipboardApi }
\ No newline at end of file
+export { getConfig, getMeadiaType, checkMediaType, checkUrlIpv6, checkLiveM3U8, copyToClipboardApi }