subweb/src/views/home/HomeForm.vue

348 lines
10 KiB
Vue
Raw Normal View History

2022-07-01 14:32:25 +08:00
<template>
<div class="box">
<form method="post" action="#">
<div class="row gtr-uniform gtr-50">
2022-07-11 13:16:52 +08:00
<div class="col-12">
<textarea
id="message"
v-model.trim="inputs.inputValue"
:placeholder="inputs.placeholder"
rows="3"
></textarea>
</div>
2022-07-01 14:32:25 +08:00
<div
class="col-4 col-4-mobilep list"
style="text-align: center; padding-top: 20px"
>
<select v-model="targetType" @change="selectTarget($event)">
<option
v-for="option in targetTypes"
:key="option"
:value="option.value"
>
{{ option.text }}
</option>
</select>
</div>
<div
class="col-4 col-4-mobilep list"
style="text-align: center; padding-top: 20px"
>
<select id="selectApi" v-model="api" @change="selectApi($event)">
<option v-for="option in apis" :key="option" :value="option.value">
{{ option.text }}
</option>
</select>
</div>
<div
class="col-4 col-4-mobilep"
style="text-align: center; padding-top: 20px"
>
<input
v-model="manualApiUrl"
type="text"
:disabled="isManualApi"
placeholder="示例https://sub.ops.ci"
/>
</div>
<div
v-show="isShowMoreConfig"
class="col-12"
style="text-align: center; padding-top: 0px"
>
<div class="col-12" style="text-align: center; padding-top: 30px">
<input
type="text"
:placeholder="'Include可选'"
v-model="moreConfig.include"
/>
</div>
<div class="col-12" style="text-align: center; padding-top: 20px">
<input
type="text"
:placeholder="'Exclude可选'"
v-model="moreConfig.exclude"
/>
</div>
<div class="col-12" style="text-align: center; padding-top: 20px">
<input
type="text"
:placeholder="'远程配置:可选'"
v-model="moreConfig.remoteconfig"
/>
</div>
<div
class="col-12 col-12-narrower"
style="text-align: center; padding-top: 20px"
>
<input type="checkbox" id="emoji" v-model="moreConfig.emoji" />
<label for="emoji">Emoji</label>
<input type="checkbox" id="udp" v-model="moreConfig.udp" />
<label for="udp">开启UDP</label>
<input type="checkbox" id="sort" v-model="moreConfig.sort" />
<label for="sort">排序节点</label>
<input type="checkbox" id="scv" v-model="moreConfig.scv" />
<label for="scv">关闭证书检查</label>
<input type="checkbox" id="nodelist" v-model="moreConfig.list" />
<label for="nodelist">Node List</label>
</div>
</div>
<div
class="col-6 col-6-mobilep"
style="text-align: center; padding-top: 20px"
>
<ul class="actions">
<li>
2022-07-04 13:22:36 +08:00
<input type="button" value="订阅转换" @click="checkAll()" />
2022-07-01 14:32:25 +08:00
</li>
<!-- <li><input type="reset" value="重置内容" class="alt" /></li> -->
<li>
<input
type="button"
value="可选参数"
class="alt"
@click="showMoreConfig()"
/>
</li>
</ul>
</div>
2022-08-04 12:05:47 +08:00
<div class="col-10" style="text-align: center; padding-top: 20px">
2022-07-01 14:32:25 +08:00
<input
type="text"
readOnly="true"
2022-07-04 13:22:36 +08:00
placeholder="点击订阅转换获取链接"
2022-07-01 14:32:25 +08:00
v-model.trim="returnUrl"
/>
</div>
2022-08-04 12:05:47 +08:00
<div
class="col-2 col-2-mobilep"
style="text-align: center; padding-top: 20px"
>
<ul class="actions">
<li>
2022-08-05 13:51:40 +08:00
<input
type="button"
value="复制"
@click="toCopy(this.returnUrl, '订阅链接')"
/>
</li>
</ul>
</div>
<div class="col-10" style="text-align: center; padding-top: 20px">
<input
type="text"
readOnly="true"
placeholder="点击生成短链接"
v-model.trim="returnShortUrl"
/>
</div>
<div
class="col-2 col-2-mobilep"
style="text-align: center; padding-top: 20px"
>
<ul class="actions">
<li>
<input type="button" value="短链" @click="getShortUrl()" />
2022-08-04 12:05:47 +08:00
</li>
</ul>
</div>
2022-07-01 14:32:25 +08:00
</div>
</form>
</div>
<DialogLayOut
:dialogVisible="dialogVisible"
@closed="resetDialog"
:message="dialogMessage"
></DialogLayOut>
</template>
<script>
2022-08-05 13:51:40 +08:00
import { request } from 'network';
2022-07-01 14:32:25 +08:00
import utils from './utils.js';
import DialogLayOut from 'components/common/dialog/DialogLayOut.vue';
export default {
name: 'HomeForm',
components: {
DialogLayOut,
},
setup() {
const ENV = {
DEFAULT_MORECONFIG: {
include: '',
exclude: '',
remoteconfig: '',
emoji: true,
udp: true,
sort: false,
scv: false,
list: false,
},
};
return {
ENV,
};
},
data() {
return {
moreConfig: {},
isShowMoreConfig: false,
urls: [],
returnUrl: '',
2022-08-05 13:51:40 +08:00
returnShortUrl: '',
2022-07-11 16:17:01 +08:00
apiUrl: window.config.apiUrl,
2022-08-05 13:51:40 +08:00
shortUrl: window.config.shortUrl,
2022-07-01 14:32:25 +08:00
manualApiUrl: '',
isManualApi: true,
api: 'default',
apis: [
2022-07-11 16:17:01 +08:00
{ value: 'default', text: window.config.apiUrl },
2022-07-01 14:32:25 +08:00
{ value: 'manual', text: '自定义后端 API 地址' },
],
2022-07-11 13:16:52 +08:00
inputs: {
buttonClass: '',
inputValue: '',
placeholder:
'多订阅链接或节点请确保每行一条\n支持手动使用"|"分割多链接或节点',
},
2022-07-01 14:32:25 +08:00
targetType: 'clash',
targetTypes: [
{ value: 'clash', text: 'Clash' },
{ value: 'clashr', text: 'ClashR' },
{ value: 'v2ray', text: 'V2Ray' },
{ value: 'quan', text: 'Quantumult' },
{ value: 'quanx', text: 'Quantumult X' },
{ value: 'surge&ver=2', text: 'SurgeV2' },
{ value: 'surge&ver=3', text: 'SurgeV3' },
{ value: 'surge&ver=4', text: 'SurgeV4' },
{ value: 'surfboard', text: 'Surfboard' },
{ value: 'ss', text: 'SS (SIP002)' },
{ value: 'sssub', text: 'SS Android' },
{ value: 'ssd', text: 'SSD' },
{ value: 'ssr', text: 'SSR' },
{ value: 'loon', text: 'Loon' },
],
dialogVisible: false,
dialogMessage: '',
};
},
created() {
this.moreConfig = this.ENV.DEFAULT_MORECONFIG;
},
methods: {
showMoreConfig() {
if (this.isShowMoreConfig) {
this.isShowMoreConfig = false;
} else {
this.isShowMoreConfig = true;
}
},
resetDialog() {
this.dialogVisible = false;
},
selectApi(event) {
if (event.target.value == 'manual') {
this.isManualApi = false;
} else {
this.isManualApi = true;
}
},
selectTarget(event) {
this.targetType = event.target.value;
},
checkUrls() {
2022-07-11 13:16:52 +08:00
if (this.inputs.inputValue == '') {
this.dialogMessage = '请填写正确的订阅地址';
this.dialogVisible = true;
return false;
} else {
this.urls = this.inputs.inputValue;
return true;
2022-07-01 14:32:25 +08:00
}
},
checkApi() {
var apiSelect = document.getElementById('selectApi');
var i = apiSelect.selectedIndex;
if (apiSelect.options[i].value == 'manual') {
this.apiUrl = this.manualApiUrl;
if (!utils.regexCheck(this.apiUrl)) {
this.dialogMessage = '请填写正确的 API 地址';
this.dialogVisible = true;
return false;
} else if (this.apiUrl.split('').slice(-1) == '/') {
this.apiUrl = this.apiUrl.substr(0, this.apiUrl.length - 1);
return true;
} else {
return true;
}
} else {
this.apiUrl = apiSelect.options[i].text;
return true;
}
},
getFinalUrl() {
this.returnUrl = utils.getSubLink(
this.urls,
this.apiUrl,
this.targetType,
this.isShowMoreConfig,
this.moreConfig
);
},
checkAll() {
if (this.checkUrls() && this.checkApi()) {
this.getFinalUrl();
}
},
2022-08-05 13:51:40 +08:00
toCopy(url, title) {
if (!url) {
2022-08-04 12:05:47 +08:00
this.dialogMessage = '内容为空,请先订阅转换.';
this.dialogVisible = true;
} else {
var copyInput = document.createElement('input');
2022-08-05 13:51:40 +08:00
copyInput.setAttribute('value', url);
2022-08-04 12:05:47 +08:00
document.body.appendChild(copyInput);
copyInput.select();
try {
var copyed = document.execCommand('copy');
if (copyed) {
document.body.removeChild(copyInput);
2022-08-05 13:51:40 +08:00
this.dialogMessage = title + '复制成功';
2022-08-04 12:05:47 +08:00
this.dialogVisible = true;
}
} catch {
this.dialogMessage = '复制失败,请检查浏览器兼容.';
this.dialogVisible = true;
}
}
},
2022-08-05 13:51:40 +08:00
getShortUrl() {
if (this.returnUrl == '') {
this.dialogMessage = '内容为空,请先订阅转换.';
this.dialogVisible = true;
} else {
let data = new FormData();
data.append('longUrl', btoa(this.returnUrl));
request({
method: 'post',
url: this.shortUrl + '/short',
header: {
'Content-Type': 'application/form-data; charset=utf-8',
},
data: data,
})
.then((res) => {
if (res.data.Code === 1 && res.data.ShortUrl !== '') {
this.returnShortUrl = res.data.ShortUrl;
this.toCopy(res.data.ShortUrl, '短链接');
}
})
.catch(() => {
this.dialogMessage = '短链接生成失败';
this.dialogVisible = true;
});
}
},
2022-07-01 14:32:25 +08:00
},
};
</script>