xray_rule_modal.html 11 KB

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