| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246 | {{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 :colon="false" :label-col="{ md: {span:8} }" :wrapper-col="{ md: {span:14} }">    <a-form-item label='Domain Matcher'>      <a-select v-model="ruleModal.rule.domainMatcher" :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>    <a-form-item>      <template slot="label">        <a-tooltip>          <template slot="title">            <span>{{ i18n "pages.xray.rules.useComma" }}</span>          </template> Source IPs <a-icon type="question-circle"></a-icon>        </a-tooltip>      </template>      <a-input v-model.trim="ruleModal.rule.source"></a-input>    </a-form-item>    <a-form-item>      <template slot="label">        <a-tooltip>          <template slot="title">            <span>{{ i18n "pages.xray.rules.useComma" }}</span>          </template> Source Port <a-icon type="question-circle"></a-icon>        </a-tooltip>      </template>      <a-input v-model.trim="ruleModal.rule.sourcePort"></a-input>    </a-form-item>    <a-form-item label='Network'>      <a-select v-model="ruleModal.rule.network" :dropdown-class-name="themeSwitcher.currentTheme">        <a-select-option v-for="x in ['','TCP','UDP','TCP,UDP']" :value="x">[[ x ]]</a-select-option>      </a-select>    </a-form-item>    <a-form-item label='Protocol'>      <a-select v-model="ruleModal.rule.protocol" mode="multiple" :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>    <a-form-item label='Attributes'>      <a-button icon="plus" size="small" style="margin-left: 10px" @click="ruleModal.rule.attrs.push(['', ''])"></a-button>    </a-form-item>    <a-form-item :wrapper-col="{span: 24}">      <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 icon="minus" slot="addonAfter" size="small" @click="ruleModal.rule.attrs.splice(index,1)"></a-button>        </a-input>      </a-input-group>    </a-form-item>    <a-form-item>      <template slot="label">        <a-tooltip>          <template slot="title">            <span>{{ i18n "pages.xray.rules.useComma" }}</span>          </template> IP <a-icon type="question-circle"></a-icon>        </a-tooltip>      </template>      <a-input v-model.trim="ruleModal.rule.ip"></a-input>    </a-form-item>    <a-form-item>      <template slot="label">        <a-tooltip>          <template slot="title">            <span>{{ i18n "pages.xray.rules.useComma" }}</span>          </template> Domain <a-icon type="question-circle"></a-icon>        </a-tooltip>      </template>      <a-input v-model.trim="ruleModal.rule.domain"></a-input>    </a-form-item>    <a-form-item>      <template slot="label">        <a-tooltip>          <template slot="title">            <span>{{ i18n "pages.xray.rules.useComma" }}</span>          </template> User <a-icon type="question-circle"></a-icon>        </a-tooltip>      </template>      <a-input v-model.trim="ruleModal.rule.user"></a-input>    </a-form-item>    <a-form-item>      <template slot="label">        <a-tooltip>          <template slot="title">            <span>{{ i18n "pages.xray.rules.useComma" }}</span>          </template> Port <a-icon type="question-circle"></a-icon>        </a-tooltip>      </template>      <a-input v-model.trim="ruleModal.rule.port"></a-input>    </a-form-item>    <a-form-item label='Inbound Tags'>      <a-select v-model="ruleModal.rule.inboundTag" mode="multiple" :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>    <a-form-item label='Outbound Tag'>      <a-select v-model="ruleModal.rule.outboundTag" :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>    <a-form-item>      <template slot="label">        <a-tooltip>          <template slot="title">            <span>{{ i18n "pages.xray.balancer.balancerDesc" }}</span>          </template> Balancer Tag <a-icon type="question-circle"></a-icon>        </a-tooltip>      </template>      <a-select v-model="ruleModal.rule.balancerTag" :dropdown-class-name="themeSwitcher.currentTheme">        <a-select-option v-for="tag in ruleModal.balancerTags" :value="tag">[[ tag ]]</a-select-option>      </a-select>    </a-form-item>  </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: "",      balancerTag: "",    },    inboundTags: [],    outboundTags: [],    users: [],    balancerTags: [],    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;        this.rule.balancerTag = rule.balancerTag ? rule.balancerTag : "";      } else {        this.rule = {          domainMatcher: "",          domain: "",          ip: "",          port: "",          sourcePort: "",          network: "",          source: "",          user: "",          inboundTag: [],          protocol: [],          attrs: [],          outboundTag: "",          balancerTag: "",        }      }      this.isEdit = isEdit;      this.inboundTags = app.templateSettings.inbounds.filter((i) => !ObjectUtil.isEmpty(i.tag)).map(obj => obj.tag);      this.inboundTags.push(...app.inboundTags);      if (app.enableDNS && !ObjectUtil.isEmpty(app.dnsTag)) this.inboundTags.push(app.dnsTag)      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));      }      if (app.templateSettings.routing && app.templateSettings.routing.balancers) {        this.balancerTags = ["", ...app.templateSettings.routing.balancers.filter((o) => !ObjectUtil.isEmpty(o.tag)).map(obj => obj.tag)];      }    },    close() {      ruleModal.visible = false;      ruleModal.loading(false);    },    loading(loading = true) {      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 == "" ? undefined : value.outboundTag;      rule.balancerTag = value.balancerTag == "" ? undefined : value.balancerTag;      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}}
 |