xray_rule_modal.html 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. {{define "ruleModal"}}
  2. <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">
  3. <a-form :colon="false" :label-col="{ md: {span:8} }" :wrapper-col="{ md: {span:14} }">
  4. <a-form-item label='Domain Matcher'>
  5. <a-select v-model="ruleModal.rule.domainMatcher" :dropdown-class-name="themeSwitcher.currentTheme">
  6. <a-select-option v-for="dm in ['','hybrid','linear']" :value="dm">[[ dm ]]</a-select-option>
  7. </a-select>
  8. </a-form-item>
  9. <a-form-item>
  10. <template slot="label">
  11. <a-tooltip>
  12. <template slot="title">
  13. <span>{{ i18n "pages.xray.rules.useComma" }}</span>
  14. </template> Source IPs <a-icon type="question-circle"></a-icon>
  15. </a-tooltip>
  16. </template>
  17. <a-input v-model.trim="ruleModal.rule.source"></a-input>
  18. </a-form-item>
  19. <a-form-item>
  20. <template slot="label">
  21. <a-tooltip>
  22. <template slot="title">
  23. <span>{{ i18n "pages.xray.rules.useComma" }}</span>
  24. </template> Source Port <a-icon type="question-circle"></a-icon>
  25. </a-tooltip>
  26. </template>
  27. <a-input v-model.trim="ruleModal.rule.sourcePort"></a-input>
  28. </a-form-item>
  29. <a-form-item label='Network'>
  30. <a-select v-model="ruleModal.rule.network" :dropdown-class-name="themeSwitcher.currentTheme">
  31. <a-select-option v-for="x in ['','TCP','UDP','TCP,UDP']" :value="x">[[ x ]]</a-select-option>
  32. </a-select>
  33. </a-form-item>
  34. <a-form-item label='Protocol'>
  35. <a-select v-model="ruleModal.rule.protocol" mode="multiple" :dropdown-class-name="themeSwitcher.currentTheme">
  36. <a-select-option v-for="x in ['http','tls','bittorrent']" :value="x">[[ x ]]</a-select-option>
  37. </a-select>
  38. </a-form-item>
  39. <a-form-item label='Attributes'>
  40. <a-button icon="plus" size="small" style="margin-left: 10px" @click="ruleModal.rule.attrs.push(['', ''])"></a-button>
  41. </a-form-item>
  42. <a-form-item :wrapper-col="{span: 24}">
  43. <a-input-group compact v-for="(attr,index) in ruleModal.rule.attrs">
  44. <a-input style="width: 50%" v-model="attr[0]" placeholder='{{ i18n "pages.inbounds.stream.general.name" }}'>
  45. <template slot="addonBefore" style="margin: 0;">[[ index+1 ]]</template>
  46. </a-input>
  47. <a-input style="width: 50%" v-model="attr[1]" placeholder='{{ i18n "pages.inbounds.stream.general.value" }}'>
  48. <a-button icon="minus" slot="addonAfter" size="small" @click="ruleModal.rule.attrs.splice(index,1)"></a-button>
  49. </a-input>
  50. </a-input-group>
  51. </a-form-item>
  52. <a-form-item>
  53. <template slot="label">
  54. <a-tooltip>
  55. <template slot="title">
  56. <span>{{ i18n "pages.xray.rules.useComma" }}</span>
  57. </template> IP <a-icon type="question-circle"></a-icon>
  58. </a-tooltip>
  59. </template>
  60. <a-input v-model.trim="ruleModal.rule.ip"></a-input>
  61. </a-form-item>
  62. <a-form-item>
  63. <template slot="label">
  64. <a-tooltip>
  65. <template slot="title">
  66. <span>{{ i18n "pages.xray.rules.useComma" }}</span>
  67. </template> Domain <a-icon type="question-circle"></a-icon>
  68. </a-tooltip>
  69. </template>
  70. <a-input v-model.trim="ruleModal.rule.domain"></a-input>
  71. </a-form-item>
  72. <a-form-item>
  73. <template slot="label">
  74. <a-tooltip>
  75. <template slot="title">
  76. <span>{{ i18n "pages.xray.rules.useComma" }}</span>
  77. </template> User <a-icon type="question-circle"></a-icon>
  78. </a-tooltip>
  79. </template>
  80. <a-input v-model.trim="ruleModal.rule.user"></a-input>
  81. </a-form-item>
  82. <a-form-item>
  83. <template slot="label">
  84. <a-tooltip>
  85. <template slot="title">
  86. <span>{{ i18n "pages.xray.rules.useComma" }}</span>
  87. </template> Port <a-icon type="question-circle"></a-icon>
  88. </a-tooltip>
  89. </template>
  90. <a-input v-model.trim="ruleModal.rule.port"></a-input>
  91. </a-form-item>
  92. <a-form-item label='Inbound Tags'>
  93. <a-select v-model="ruleModal.rule.inboundTag" mode="multiple" :dropdown-class-name="themeSwitcher.currentTheme">
  94. <a-select-option v-for="tag in ruleModal.inboundTags" :value="tag">[[ tag ]]</a-select-option>
  95. </a-select>
  96. </a-form-item>
  97. <a-form-item label='Outbound Tag'>
  98. <a-select v-model="ruleModal.rule.outboundTag" :dropdown-class-name="themeSwitcher.currentTheme">
  99. <a-select-option v-for="tag in ruleModal.outboundTags" :value="tag">[[ tag ]]</a-select-option>
  100. </a-select>
  101. </a-form-item>
  102. <a-form-item>
  103. <template slot="label">
  104. <a-tooltip>
  105. <template slot="title">
  106. <span>{{ i18n "pages.xray.balancer.balancerDesc" }}</span>
  107. </template> Balancer Tag <a-icon type="question-circle"></a-icon>
  108. </a-tooltip>
  109. </template>
  110. <a-select v-model="ruleModal.rule.balancerTag" :dropdown-class-name="themeSwitcher.currentTheme">
  111. <a-select-option v-for="tag in ruleModal.balancerTags" :value="tag">[[ tag ]]</a-select-option>
  112. </a-select>
  113. </a-form-item>
  114. </a-form>
  115. </a-modal>
  116. <script>
  117. const ruleModal = {
  118. title: '',
  119. visible: false,
  120. confirmLoading: false,
  121. okText: '{{ i18n "sure" }}',
  122. isEdit: false,
  123. confirm: null,
  124. rule: {
  125. type: "field",
  126. domainMatcher: "",
  127. domain: "",
  128. ip: "",
  129. port: "",
  130. sourcePort: "",
  131. network: "",
  132. source: "",
  133. user: "",
  134. inboundTag: [],
  135. protocol: [],
  136. attrs: [],
  137. outboundTag: "",
  138. balancerTag: "",
  139. },
  140. inboundTags: [],
  141. outboundTags: [],
  142. users: [],
  143. balancerTags: [],
  144. ok() {
  145. newRule = ruleModal.getResult();
  146. ObjectUtil.execute(ruleModal.confirm, newRule);
  147. },
  148. show({
  149. title = '',
  150. okText = '{{ i18n "sure" }}',
  151. rule,
  152. confirm = (rule) => {},
  153. isEdit = false
  154. }) {
  155. this.title = title;
  156. this.okText = okText;
  157. this.confirm = confirm;
  158. this.visible = true;
  159. if (isEdit) {
  160. this.rule.domainMatcher = rule.domainMatcher;
  161. this.rule.domain = rule.domain ? rule.domain.join(',') : [];
  162. this.rule.ip = rule.ip ? rule.ip.join(',') : [];
  163. this.rule.port = rule.port;
  164. this.rule.sourcePort = rule.sourcePort;
  165. this.rule.network = rule.network;
  166. this.rule.source = rule.source ? rule.source.join(',') : [];
  167. this.rule.user = rule.user ? rule.user.join(',') : [];
  168. this.rule.inboundTag = rule.inboundTag;
  169. this.rule.protocol = rule.protocol;
  170. this.rule.attrs = rule.attrs ? Object.entries(rule.attrs) : [];
  171. this.rule.outboundTag = rule.outboundTag;
  172. this.rule.balancerTag = rule.balancerTag ? rule.balancerTag : "";
  173. } else {
  174. this.rule = {
  175. domainMatcher: "",
  176. domain: "",
  177. ip: "",
  178. port: "",
  179. sourcePort: "",
  180. network: "",
  181. source: "",
  182. user: "",
  183. inboundTag: [],
  184. protocol: [],
  185. attrs: [],
  186. outboundTag: "",
  187. balancerTag: "",
  188. }
  189. }
  190. this.isEdit = isEdit;
  191. this.inboundTags = app.templateSettings.inbounds.filter((i) => !ObjectUtil.isEmpty(i.tag)).map(obj => obj.tag);
  192. this.inboundTags.push(...app.inboundTags);
  193. if (app.enableDNS && !ObjectUtil.isEmpty(app.dnsTag)) this.inboundTags.push(app.dnsTag)
  194. this.outboundTags = ["", ...app.templateSettings.outbounds.filter((o) => !ObjectUtil.isEmpty(o.tag)).map(obj => obj.tag)];
  195. if (app.templateSettings.reverse) {
  196. if (app.templateSettings.reverse.bridges) {
  197. this.inboundTags.push(...app.templateSettings.reverse.bridges.map(b => b.tag));
  198. }
  199. if (app.templateSettings.reverse.portals) this.outboundTags.push(...app.templateSettings.reverse.portals.map(b => b.tag));
  200. }
  201. if (app.templateSettings.routing && app.templateSettings.routing.balancers) {
  202. this.balancerTags = ["", ...app.templateSettings.routing.balancers.filter((o) => !ObjectUtil.isEmpty(o.tag)).map(obj => obj.tag)];
  203. }
  204. },
  205. close() {
  206. ruleModal.visible = false;
  207. ruleModal.loading(false);
  208. },
  209. loading(loading = true) {
  210. ruleModal.confirmLoading = loading;
  211. },
  212. getResult() {
  213. value = ruleModal.rule;
  214. rule = {};
  215. newRule = {};
  216. rule.type = "field";
  217. rule.domainMatcher = value.domainMatcher;
  218. rule.domain = value.domain.length > 0 ? value.domain.split(',') : [];
  219. rule.ip = value.ip.length > 0 ? value.ip.split(',') : [];
  220. rule.port = value.port;
  221. rule.sourcePort = value.sourcePort;
  222. rule.network = value.network;
  223. rule.source = value.source.length > 0 ? value.source.split(',') : [];
  224. rule.user = value.user.length > 0 ? value.user.split(',') : [];
  225. rule.inboundTag = value.inboundTag;
  226. rule.protocol = value.protocol;
  227. rule.attrs = Object.fromEntries(value.attrs);
  228. rule.outboundTag = value.outboundTag == "" ? undefined : value.outboundTag;
  229. rule.balancerTag = value.balancerTag == "" ? undefined : value.balancerTag;
  230. for (const [key, value] of Object.entries(rule)) {
  231. if (value !== null && value !== undefined && !(Array.isArray(value) && value.length === 0) && !(typeof value === 'object' && Object.keys(value).length === 0) && value !== '') {
  232. newRule[key] = value;
  233. }
  234. }
  235. return newRule;
  236. }
  237. };
  238. new Vue({
  239. delimiters: ['[[', ']]'],
  240. el: '#rule-modal',
  241. data: {
  242. ruleModal: ruleModal,
  243. }
  244. });
  245. </script>
  246. {{end}}