123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277 |
- {{define "ruleModal"}}
- <a-modal id="rule-modal" v-model="ruleModal.visible" :title="ruleModal.title" @ok="ruleModal.ok"
- :confirm-loading="ruleModal.confirmLoading" :closable="true" :mask-closable="false"
- :ok-text="ruleModal.okText" cancel-text='{{ i18n "close" }}' :class="themeSwitcher.currentTheme">
- <a-form layout="inline">
- <table width="100%" class="ant-table-tbody">
- <tr>
- <td style="width: 30%;">Domain Matcher</td>
- <td>
- <a-form-item>
- <a-select v-model="ruleModal.rule.domainMatcher" style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme">
- <a-select-option v-for="dm in ['','hybrid','linear']" :value="dm">[[ dm ]]</a-select-option>
- </a-select>
- </a-form-item>
- </td>
- </tr>
- <tr>
- <td>Source IPs
- <a-tooltip>
- <template slot="title">
- <span>{{ i18n "pages.xray.rules.useComma" }}</span>
- </template>
- <a-icon type="question-circle"></a-icon>
- </a-tooltip>
- </td>
- <td>
- <a-form-item>
- <a-input v-model.trim="ruleModal.rule.source" style="width: 250px"></a-input>
- </a-form-item>
- </td>
- </tr>
- <tr>
- <td>Source Port
- <a-tooltip>
- <template slot="title">
- <span>{{ i18n "pages.xray.rules.useComma" }}</span>
- </template>
- <a-icon type="question-circle"></a-icon>
- </a-tooltip>
- </td>
- <td>
- <a-form-item>
- <a-input v-model.trim="ruleModal.rule.sourcePort" style="width: 250px"></a-input>
- </a-form-item>
- </td>
- </tr>
- <tr>
- <td>Network</td>
- <td>
- <a-form-item>
- <a-select v-model="ruleModal.rule.network" style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme">
- <a-select-option v-for="x in ['','tcp','tdp','tcp,udp']" :value="x">[[ x ]]</a-select-option>
- </a-select>
- </a-form-item>
- </td>
- </tr>
- <tr>
- <td>Protocol</td>
- <td>
- <a-form-item>
- <a-select v-model="ruleModal.rule.protocol" style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme">
- <a-select-option v-for="x in ['','http','tls','bittorrent']" :value="x">[[ x ]]</a-select-option>
- </a-select>
- </a-form-item>
- </td>
- </tr>
- <tr>
- <td colspan="2">
- <a-form-item>
- <span>Attributes</span>
- <a-button size="small" style="margin-left: 10px" @click="ruleModal.rule.attrs.push(['', ''])">+</a-button>
- <a-input-group compact v-for="(attr,index) in ruleModal.rule.attrs">
- <a-input style="width: 50%" v-model="attr[0]" placeholder='{{ i18n "pages.inbounds.stream.general.name" }}'>
- <template slot="addonBefore" style="margin: 0;">[[ index+1 ]]</template>
- </a-input>
- <a-input style="width: 50%" v-model="attr[1]" placeholder='{{ i18n "pages.inbounds.stream.general.value" }}'>
- <a-button slot="addonAfter" size="small" @click="ruleModal.rule.attrs.splice(index,1)">-</a-button>
- </a-input>
- </a-input-group>
- </a-form-item>
- </td>
- </tr>
- <tr>
- <td>IP
- <a-tooltip>
- <template slot="title">
- <span>{{ i18n "pages.xray.rules.useComma" }}</span>
- </template>
- <a-icon type="question-circle"></a-icon>
- </a-tooltip>
- </td>
- <td>
- <a-form-item>
- <a-input v-model.trim="ruleModal.rule.ip" style="width: 250px"></a-input>
- </a-form-item>
- </td>
- </tr>
- <tr>
- <td>Domain
- <a-tooltip>
- <template slot="title">
- <span>{{ i18n "pages.xray.rules.useComma" }}</span>
- </template>
- <a-icon type="question-circle"></a-icon>
- </a-tooltip>
- </td>
- <td>
- <a-form-item>
- <a-input v-model.trim="ruleModal.rule.domain" style="width: 250px"></a-input>
- </a-form-item>
- </td>
- </tr>
- <tr>
- <td>Port
- <a-tooltip>
- <template slot="title">
- <span>{{ i18n "pages.xray.rules.useComma" }}</span>
- </template>
- <a-icon type="question-circle"></a-icon>
- </a-tooltip>
- </td>
- <td>
- <a-form-item>
- <a-input v-model.trim="ruleModal.rule.port" style="width: 250px"></a-input>
- </a-form-item>
- </td>
- </tr>
- <tr>
- <td>Inbound Tags</td>
- <td>
- <a-form-item>
- <a-select v-model="ruleModal.rule.inboundTag" mode="multiple" style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme">
- <a-select-option v-for="tag in ruleModal.inboundTags" :value="tag">[[ tag ]]</a-select-option>
- </a-select>
- </a-form-item>
- </td>
- </tr>
- <tr>
- <td>Outbound Tag</td>
- <td>
- <a-form-item>
- <a-select v-model="ruleModal.rule.outboundTag" style="width: 250px;" :dropdown-class-name="themeSwitcher.currentTheme">
- <a-select-option v-for="tag in ruleModal.outboundTags" :value="tag">[[ tag ]]</a-select-option>
- </a-select>
- </a-form-item>
- </td>
- </tr>
- </table>
- </a-form>
- </a-modal>
- <script>
- const ruleModal = {
- title: '',
- visible: false,
- confirmLoading: false,
- okText: '{{ i18n "sure" }}',
- isEdit: false,
- confirm: null,
- rule: {
- type: "field",
- domainMatcher: "",
- domain: "",
- ip: "",
- port: "",
- sourcePort: "",
- network: "",
- source: "",
- user: "",
- inboundTag: [],
- protocol: [],
- attrs: [],
- outboundTag: "",
- },
- inboundTags: [],
- outboundTags: [],
- users: [],
- balancerTag: [],
- ok() {
- newRule = ruleModal.getResult();
- ObjectUtil.execute(ruleModal.confirm, newRule);
- },
- show({ title='', okText='{{ i18n "sure" }}', rule, confirm=(rule)=>{}, isEdit=false }) {
- this.title = title;
- this.okText = okText;
- this.confirm = confirm;
- this.visible = true;
- if(isEdit) {
- this.rule.domainMatcher = rule.domainMatcher;
- this.rule.domain = rule.domain ? rule.domain.join(',') : [];
- this.rule.ip = rule.ip ? rule.ip.join(',') : [];
- this.rule.port = rule.port;
- this.rule.sourcePort = rule.sourcePort;
- this.rule.network = rule.network;
- this.rule.source = rule.source ? rule.source.join(',') : [];
- this.rule.user = rule.user ? rule.user.join(',') : [];
- this.rule.inboundTag = rule.inboundTag;
- this.rule.protocol = rule.protocol;
- this.rule.attrs = rule.attrs ? Object.entries(rule.attrs) : [];
- this.rule.outboundTag = rule.outboundTag;
- } else {
- this.rule = {
- domainMatcher: "",
- domain: "",
- ip: "",
- port: "",
- sourcePort: "",
- network: "",
- source: "",
- user: "",
- inboundTag: [],
- protocol: [],
- attrs: [],
- outboundTag: "",
- }
- }
- this.isEdit = isEdit;
- this.inboundTags = app.templateSettings.inbounds.filter((i) => !ObjectUtil.isEmpty(i.tag)).map(obj => obj.tag);
- this.inboundTags.push(...app.inboundTags);
- this.outboundTags = app.templateSettings.outbounds.filter((o) => !ObjectUtil.isEmpty(o.tag)).map(obj => obj.tag);
- if(app.templateSettings.reverse){
- if(app.templateSettings.reverse.bridges) {
- this.inboundTags.push(...app.templateSettings.reverse.bridges.map(b => b.tag));
- }
- if(app.templateSettings.reverse.portals) this.outboundTags.push(...app.templateSettings.reverse.portals.map(b => b.tag));
- }
- },
- close() {
- ruleModal.visible = false;
- ruleModal.loading(false);
- },
- loading(loading) {
- ruleModal.confirmLoading = loading;
- },
- getResult() {
- value = ruleModal.rule;
- rule = {};
- newRule = {};
- rule.type = "field";
- rule.domainMatcher = value.domainMatcher;
- rule.domain = value.domain.length>0 ? value.domain.split(',') : [];
- rule.ip = value.ip.length>0 ? value.ip.split(',') : [];
- rule.port = value.port;
- rule.sourcePort = value.sourcePort;
- rule.network = value.network;
- rule.source = value.source.length>0 ? value.source.split(',') : [];
- rule.user = value.user.length>0 ? value.user.split(',') : [];
- rule.inboundTag = value.inboundTag;
- rule.protocol = value.protocol;
- rule.attrs = Object.fromEntries(value.attrs);
- rule.outboundTag = value.outboundTag;
- for (const [key, value] of Object.entries(rule)) {
- if (
- value !== null &&
- value !== undefined &&
- !(Array.isArray(value) && value.length === 0) &&
- !(typeof value === 'object' && Object.keys(value).length === 0) &&
- value !== ''
- ) {
- newRule[key] = value;
- }
- }
- return newRule;
- }
- };
- new Vue({
- delimiters: ['[[', ']]'],
- el: '#rule-modal',
- data: {
- ruleModal: ruleModal,
- }
- });
- </script>
- {{end}}
|