mirror of
				https://github.com/MHSanaei/3x-ui.git
				synced 2025-10-27 10:30:08 +00:00 
			
		
		
		
	Compare commits
	
		
			3 commits
		
	
	
		
			c6d27a4463
			...
			a0dd101d97
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | a0dd101d97 | ||
|   | 700cf9c10b | ||
|   | 697cd5e6d9 | 
					 26 changed files with 164 additions and 96 deletions
				
			
		|  | @ -10,7 +10,7 @@ | ||||||
|         <a-tag color="purple" class="qr-tag"><span>{{ i18n "pages.settings.subSettings"}}</span></a-tag> |         <a-tag color="purple" class="qr-tag"><span>{{ i18n "pages.settings.subSettings"}}</span></a-tag> | ||||||
|         <tr-qr-bg class="qr-bg-sub"> |         <tr-qr-bg class="qr-bg-sub"> | ||||||
|           <tr-qr-bg-inner class="qr-bg-sub-inner"> |           <tr-qr-bg-inner class="qr-bg-sub-inner"> | ||||||
|             <canvas @click="qrModal.copy(genSubLink(qrModal.client.subId))" id="qrCode-sub" class="qr-cv"></canvas> |             <canvas @click="copy(genSubLink(qrModal.client.subId))" id="qrCode-sub" class="qr-cv"></canvas> | ||||||
|           </tr-qr-bg-inner> |           </tr-qr-bg-inner> | ||||||
|         </tr-qr-bg> |         </tr-qr-bg> | ||||||
|       </tr-qr-box> |       </tr-qr-box> | ||||||
|  | @ -18,7 +18,7 @@ | ||||||
|         <a-tag color="purple" class="qr-tag"><span>{{ i18n "pages.settings.subSettings"}} Json</span></a-tag> |         <a-tag color="purple" class="qr-tag"><span>{{ i18n "pages.settings.subSettings"}} Json</span></a-tag> | ||||||
|         <tr-qr-bg class="qr-bg-sub"> |         <tr-qr-bg class="qr-bg-sub"> | ||||||
|           <tr-qr-bg-inner class="qr-bg-sub-inner"> |           <tr-qr-bg-inner class="qr-bg-sub-inner"> | ||||||
|             <canvas @click="qrModal.copy(genSubJsonLink(qrModal.client.subId))" id="qrCode-subJson" class="qr-cv"></canvas> |             <canvas @click="copy(genSubJsonLink(qrModal.client.subId))" id="qrCode-subJson" class="qr-cv"></canvas> | ||||||
|           </tr-qr-bg-inner> |           </tr-qr-bg-inner> | ||||||
|         </tr-qr-bg> |         </tr-qr-bg> | ||||||
|       </tr-qr-box> |       </tr-qr-box> | ||||||
|  | @ -27,7 +27,7 @@ | ||||||
|       <tr-qr-box class="qr-box"> |       <tr-qr-box class="qr-box"> | ||||||
|         <a-tag color="green" class="qr-tag"><span>[[ row.remark ]]</span></a-tag> |         <a-tag color="green" class="qr-tag"><span>[[ row.remark ]]</span></a-tag> | ||||||
|         <tr-qr-bg class="qr-bg"> |         <tr-qr-bg class="qr-bg"> | ||||||
|           <canvas @click="qrModal.copy(row.link)" :id="'qrCode-'+index" class="qr-cv"></canvas> |           <canvas @click="copy(row.link)" :id="'qrCode-'+index" class="qr-cv"></canvas> | ||||||
|         </tr-qr-bg> |         </tr-qr-bg> | ||||||
|       </tr-qr-box> |       </tr-qr-box> | ||||||
|     </template> |     </template> | ||||||
|  |  | ||||||
|  | @ -422,16 +422,16 @@ | ||||||
|                     </a-input> |                     </a-input> | ||||||
|                   </a-form-item> |                   </a-form-item> | ||||||
|                   <a-form-item> |                   <a-form-item> | ||||||
|                     <password-input autocomplete="password" name="password" icon="lock" v-model.trim="user.password" |                     <a-password-input autocomplete="password" name="password" icon="lock" v-model.trim="user.password" | ||||||
|                                     placeholder='{{ i18n "password" }}' |                                     placeholder='{{ i18n "password" }}' | ||||||
|                                     @keydown.enter.native="login"> |                                     @keydown.enter.native="login"> | ||||||
|                     </password-input> |                     </a-password-input> | ||||||
|                   </a-form-item> |                   </a-form-item> | ||||||
|                   <a-form-item v-if="secretEnable"> |                   <a-form-item v-if="secretEnable"> | ||||||
|                     <password-input autocomplete="secret" name="secret" icon="key" v-model.trim="user.loginSecret" |                     <a-password-input autocomplete="secret" name="secret" icon="key" v-model.trim="user.loginSecret" | ||||||
|                                     placeholder='{{ i18n "secretToken" }}' |                                     placeholder='{{ i18n "secretToken" }}' | ||||||
|                                     @keydown.enter.native="login"> |                                     @keydown.enter.native="login"> | ||||||
|                     </password-input> |                     </a-password-input> | ||||||
|                   </a-form-item> |                   </a-form-item> | ||||||
|                   <a-form-item> |                   <a-form-item> | ||||||
|                     <a-row justify="center" class="centered"> |                     <a-row justify="center" class="centered"> | ||||||
|  | @ -461,7 +461,7 @@ | ||||||
|                   </a-form-item> |                   </a-form-item> | ||||||
|                   <a-form-item> |                   <a-form-item> | ||||||
|                     <a-row justify="center" class="centered"> |                     <a-row justify="center" class="centered"> | ||||||
|                       <theme-switch-login></theme-switch-login> |                       <a-theme-switch-login></a-theme-switch-login> | ||||||
|                     </a-row> |                     </a-row> | ||||||
|                   </a-form-item> |                   </a-form-item> | ||||||
|                 </a-form> |                 </a-form> | ||||||
|  |  | ||||||
|  | @ -106,9 +106,9 @@ | ||||||
|             <a-date-picker v-if="datepicker == 'gregorian'" :show-time="{ format: 'HH:mm:ss' }" |             <a-date-picker v-if="datepicker == 'gregorian'" :show-time="{ format: 'HH:mm:ss' }" | ||||||
|                 format="YYYY-MM-DD HH:mm:ss" :dropdown-class-name="themeSwitcher.currentTheme" |                 format="YYYY-MM-DD HH:mm:ss" :dropdown-class-name="themeSwitcher.currentTheme" | ||||||
|                 v-model="clientsBulkModal.expiryTime"></a-date-picker> |                 v-model="clientsBulkModal.expiryTime"></a-date-picker> | ||||||
|             <persian-datepicker v-else placeholder='{{ i18n "pages.settings.datepickerPlaceholder" }}' |             <a-persian-datepicker v-else placeholder='{{ i18n "pages.settings.datepickerPlaceholder" }}' | ||||||
|                 value="clientsBulkModal.expiryTime" v-model="clientsBulkModal.expiryTime"> |                 value="clientsBulkModal.expiryTime" v-model="clientsBulkModal.expiryTime"> | ||||||
|             </persian-datepicker> |             </a-persian-datepicker> | ||||||
|         </a-form-item> |         </a-form-item> | ||||||
|         <a-form-item v-if="clientsBulkModal.expiryTime != 0"> |         <a-form-item v-if="clientsBulkModal.expiryTime != 0"> | ||||||
|             <template slot="label"> |             <template slot="label"> | ||||||
|  |  | ||||||
|  | @ -34,7 +34,7 @@ | ||||||
| 
 | 
 | ||||||
| {{define "commonSider"}} | {{define "commonSider"}} | ||||||
| <a-layout-sider :theme="themeSwitcher.currentTheme" id="sider" collapsible breakpoint="md"> | <a-layout-sider :theme="themeSwitcher.currentTheme" id="sider" collapsible breakpoint="md"> | ||||||
|   <theme-switch></theme-switch> |   <a-theme-switch></a-theme-switch> | ||||||
|   <a-menu :theme="themeSwitcher.currentTheme" mode="inline" :selected-keys="['{{ .request_uri }}']" @click="({key}) => key.startsWith('http') ? window.open(key) : location.href = key"> |   <a-menu :theme="themeSwitcher.currentTheme" mode="inline" :selected-keys="['{{ .request_uri }}']" @click="({key}) => key.startsWith('http') ? window.open(key) : location.href = key"> | ||||||
|     {{template "menuItems" .}} |     {{template "menuItems" .}} | ||||||
|   </a-menu> |   </a-menu> | ||||||
|  | @ -43,7 +43,7 @@ | ||||||
|   <div class="drawer-handle" @click="siderDrawer.change()" slot="handle"> |   <div class="drawer-handle" @click="siderDrawer.change()" slot="handle"> | ||||||
|     <a-icon :type="siderDrawer.visible ? 'close' : 'menu-fold'"></a-icon> |     <a-icon :type="siderDrawer.visible ? 'close' : 'menu-fold'"></a-icon> | ||||||
|   </div> |   </div> | ||||||
|   <theme-switch></theme-switch> |   <a-theme-switch></a-theme-switch> | ||||||
|   <a-menu :theme="themeSwitcher.currentTheme" mode="inline" :selected-keys="['{{ .request_uri }}']" @click="({key}) => key.startsWith('http') ? window.open(key) : location.href = key"> |   <a-menu :theme="themeSwitcher.currentTheme" mode="inline" :selected-keys="['{{ .request_uri }}']" @click="({key}) => key.startsWith('http') ? window.open(key) : location.href = key"> | ||||||
|     {{template "menuItems" .}} |     {{template "menuItems" .}} | ||||||
|   </a-menu> |   </a-menu> | ||||||
|  |  | ||||||
|  | @ -1,26 +1,46 @@ | ||||||
| {{define "component/passwordInput"}} | {{define "component/passwordInput"}} | ||||||
| <template> | <template> | ||||||
|     <a-input :value="value" :type="showPassword ? 'text' : 'password'" |   <a-input :value="value" :type="showPassword ? 'text' : 'password'" :placeholder="placeholder" | ||||||
|              :placeholder="placeholder" |     :autocomplete="autocomplete" :name="name" @input="$emit('input', $event.target.value)"> | ||||||
|              :autocomplete="autocomplete" |     <template v-if="icon" #prefix> | ||||||
|              :name="name" |       <a-icon :type="icon" style="font-size: 16px;" /> | ||||||
|              @input="$emit('input', $event.target.value)"> |     </template> | ||||||
|         <template v-if="icon" #prefix> |     <template #addonAfter> | ||||||
|             <a-icon :type="icon" style="font-size: 16px;" /> |       <a-icon :type="showPassword ? 'eye-invisible' : 'eye'" @click="toggleShowPassword" style="font-size: 16px;" /> | ||||||
|         </template> |     </template> | ||||||
|         <template #addonAfter> |   </a-input> | ||||||
|             <a-icon :type="showPassword ? 'eye-invisible' : 'eye'" |  | ||||||
|                     @click="toggleShowPassword" |  | ||||||
|                     style="font-size: 16px;" /> |  | ||||||
|         </template> |  | ||||||
|     </a-input> |  | ||||||
| </template> | </template> | ||||||
| {{end}} | {{end}} | ||||||
| 
 | 
 | ||||||
| {{define "component/password"}} | {{define "component/password"}} | ||||||
| <script> | <script> | ||||||
|   Vue.component('password-input', { |   Vue.component('a-password-input', { | ||||||
|     props: ["title", "value", "placeholder", "icon", "autocomplete", "name"], |     props: { | ||||||
|  |       'title': { | ||||||
|  |         type: String, | ||||||
|  |         required: false, | ||||||
|  |       }, | ||||||
|  |       'value': { | ||||||
|  |         type: String, | ||||||
|  |         required: false, | ||||||
|  |       }, | ||||||
|  |       'placeholder': { | ||||||
|  |         type: String, | ||||||
|  |         required: false, | ||||||
|  |       }, | ||||||
|  |       'autocomplete': { | ||||||
|  |         type: String, | ||||||
|  |         required: false, | ||||||
|  |       }, | ||||||
|  |       'name': { | ||||||
|  |         type: String, | ||||||
|  |         required: false, | ||||||
|  |       }, | ||||||
|  |       'icon': { | ||||||
|  |         type: undefined, | ||||||
|  |         required: false | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     template: `{{template "component/passwordInput"}}`, |     template: `{{template "component/passwordInput"}}`, | ||||||
|     data() { |     data() { | ||||||
|       return { |       return { | ||||||
|  |  | ||||||
|  | @ -2,10 +2,10 @@ | ||||||
| <template> | <template> | ||||||
|     <div> |     <div> | ||||||
|         <a-input :value="value" type="text" v-model="date" data-jdp class="persian-datepicker" |         <a-input :value="value" type="text" v-model="date" data-jdp class="persian-datepicker" | ||||||
|                  @input="$emit('input', convertToGregorian($event.target.value)); jalaliDatepicker.hide();" |             @input="$emit('input', convertToGregorian($event.target.value)); jalaliDatepicker.hide();" | ||||||
|                  :placeholder="placeholder"> |             :placeholder="placeholder"> | ||||||
|             <template #addonAfter> |             <template #addonAfter> | ||||||
|                 <a-icon type="calendar" style="font-size: 14px; opacity: 0.5;"/> |                 <a-icon type="calendar" style="font-size: 14px; opacity: 0.5;" /> | ||||||
|             </template> |             </template> | ||||||
|         </a-input> |         </a-input> | ||||||
|     </div> |     </div> | ||||||
|  | @ -13,15 +13,27 @@ | ||||||
| {{end}} | {{end}} | ||||||
| 
 | 
 | ||||||
| {{define "component/persianDatepicker"}} | {{define "component/persianDatepicker"}} | ||||||
| <link rel="stylesheet" href="{{ .base_path }}assets/persian-datepicker/persian-datepicker.min.css?{{ .cur_ver }}"/> | <link rel="stylesheet" href="{{ .base_path }}assets/persian-datepicker/persian-datepicker.min.css?{{ .cur_ver }}" /> | ||||||
| <script src="{{ .base_path }}assets/moment/moment-jalali.min.js?{{ .cur_ver }}"></script> | <script src="{{ .base_path }}assets/moment/moment-jalali.min.js?{{ .cur_ver }}"></script> | ||||||
| <script src="{{ .base_path }}assets/persian-datepicker/persian-datepicker.min.js?{{ .cur_ver }}"></script> | <script src="{{ .base_path }}assets/persian-datepicker/persian-datepicker.min.js?{{ .cur_ver }}"></script> | ||||||
| <script> | <script> | ||||||
| 
 |  | ||||||
|     const persianDatepicker = {}; |     const persianDatepicker = {}; | ||||||
| 
 | 
 | ||||||
|     Vue.component('persian-datepicker', { |     Vue.component('a-persian-datepicker', { | ||||||
|         props: ['placeholder', 'format', 'value'], |         props: { | ||||||
|  |             'format': { | ||||||
|  |                 type: undefined, | ||||||
|  |                 required: false, | ||||||
|  |             }, | ||||||
|  |             'value': { | ||||||
|  |                 type: String, | ||||||
|  |                 required: false, | ||||||
|  |             }, | ||||||
|  |             'placeholder': { | ||||||
|  |                 type: String, | ||||||
|  |                 required: false, | ||||||
|  |             }, | ||||||
|  |         }, | ||||||
|         template: `{{template "component/persianDatepickerTemplate"}}`, |         template: `{{template "component/persianDatepickerTemplate"}}`, | ||||||
|         data() { |         data() { | ||||||
|             return { |             return { | ||||||
|  |  | ||||||
|  | @ -21,7 +21,24 @@ | ||||||
| {{define "component/setting"}} | {{define "component/setting"}} | ||||||
| <script> | <script> | ||||||
|     Vue.component('a-setting-list-item', { |     Vue.component('a-setting-list-item', { | ||||||
|         props: ["title", "description", "paddings"], |         props: { | ||||||
|  |             'title': { | ||||||
|  |                 type: String, | ||||||
|  |                 required: true, | ||||||
|  |             }, | ||||||
|  |             'description': { | ||||||
|  |                 type: String, | ||||||
|  |                 required: false, | ||||||
|  |             }, | ||||||
|  |             'paddings': { | ||||||
|  |                 type: String, | ||||||
|  |                 required: false, | ||||||
|  |                 defaultValue: "default", | ||||||
|  |                 validator: function (value) { | ||||||
|  |                     return ['small', 'default'].includes(value) | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         }, | ||||||
|         template: `{{ template "component/settingListItem" }}`, |         template: `{{ template "component/settingListItem" }}`, | ||||||
|         computed: { |         computed: { | ||||||
|             padding() { |             padding() { | ||||||
|  | @ -29,7 +46,7 @@ | ||||||
|                     case "small": |                     case "small": | ||||||
|                         return "10px 20px !important" |                         return "10px 20px !important" | ||||||
|                         break; |                         break; | ||||||
|                     default: |                     case "default": | ||||||
|                         return "20px !important" |                         return "20px !important" | ||||||
|                         break; |                         break; | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|  | @ -1,9 +1,5 @@ | ||||||
| {{define "component/sortableTableTrigger"}} | {{define "component/sortableTableTrigger"}} | ||||||
| <a-icon type="drag" | <a-icon type="drag" class="sortable-icon" style="cursor: move;" @mouseup="mouseUpHandler" @mousedown="mouseDownHandler" | ||||||
|   class="sortable-icon" |  | ||||||
|   style="cursor: move;" |  | ||||||
|   @mouseup="mouseUpHandler" |  | ||||||
|   @mousedown="mouseDownHandler" |  | ||||||
|   @click="clickHandler" /> |   @click="clickHandler" /> | ||||||
| {{end}} | {{end}} | ||||||
| 
 | 
 | ||||||
|  | @ -28,7 +24,16 @@ | ||||||
|         newElementIndex: null, |         newElementIndex: null, | ||||||
|       }; |       }; | ||||||
|     }, |     }, | ||||||
|     props: ['data-source', 'customRow'], |     props: { | ||||||
|  |       'data-source': { | ||||||
|  |         type: undefined, | ||||||
|  |         required: false, | ||||||
|  |       }, | ||||||
|  |       'customRow': { | ||||||
|  |         type: undefined, | ||||||
|  |         required: false, | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     inheritAttrs: false, |     inheritAttrs: false, | ||||||
|     provide() { |     provide() { | ||||||
|       const sortable = {} |       const sortable = {} | ||||||
|  | @ -44,7 +49,7 @@ | ||||||
|         sortable, |         sortable, | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     render: function(createElement) { |     render: function (createElement) { | ||||||
|       return createElement('a-table', { |       return createElement('a-table', { | ||||||
|         class: { |         class: { | ||||||
|           'ant-table-is-sorting': this.isDragging(), |           'ant-table-is-sorting': this.isDragging(), | ||||||
|  | @ -59,7 +64,7 @@ | ||||||
|           drop: (e) => this.dropHandler(e), |           drop: (e) => this.dropHandler(e), | ||||||
|         }, |         }, | ||||||
|         scopedSlots: this.$scopedSlots, |         scopedSlots: this.$scopedSlots, | ||||||
|       }, this.$slots.default, ) |       }, this.$slots.default,) | ||||||
|     }, |     }, | ||||||
|     created() { |     created() { | ||||||
|       this.$memoSort = {}; |       this.$memoSort = {}; | ||||||
|  | @ -163,9 +168,14 @@ | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   }); |   }); | ||||||
|   Vue.component('table-sort-trigger', { |   Vue.component('a-table-sort-trigger', { | ||||||
|     template: `{{template "component/sortableTableTrigger"}}`, |     template: `{{template "component/sortableTableTrigger"}}`, | ||||||
|     props: ['item-index'], |     props: { | ||||||
|  |       'item-index': { | ||||||
|  |         type: undefined, | ||||||
|  |         required: false | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     inject: ['sortable'], |     inject: ['sortable'], | ||||||
|     methods: { |     methods: { | ||||||
|       mouseDownHandler(e) { |       mouseDownHandler(e) { | ||||||
|  | @ -190,25 +200,31 @@ | ||||||
|       display: none; |       display: none; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  | 
 | ||||||
|   .ant-table-is-sorting .draggable-row td { |   .ant-table-is-sorting .draggable-row td { | ||||||
|     background-color: #ffffff !important; |     background-color: #ffffff !important; | ||||||
|   } |   } | ||||||
|  | 
 | ||||||
|   .dark .ant-table-is-sorting .draggable-row td { |   .dark .ant-table-is-sorting .draggable-row td { | ||||||
|     background-color: var(--dark-color-surface-100) !important; |     background-color: var(--dark-color-surface-100) !important; | ||||||
|   } |   } | ||||||
|  | 
 | ||||||
|   .ant-table-is-sorting .dragging td { |   .ant-table-is-sorting .dragging td { | ||||||
|     background-color: rgb(232 244 242) !important; |     background-color: rgb(232 244 242) !important; | ||||||
|     color: rgba(0, 0, 0, 0.3); |     color: rgba(0, 0, 0, 0.3); | ||||||
|   } |   } | ||||||
|  | 
 | ||||||
|   .dark .ant-table-is-sorting .dragging td { |   .dark .ant-table-is-sorting .dragging td { | ||||||
|     background-color: var(--dark-color-table-hover) !important; |     background-color: var(--dark-color-table-hover) !important; | ||||||
|     color: rgba(255, 255, 255, 0.3); |     color: rgba(255, 255, 255, 0.3); | ||||||
|   } |   } | ||||||
|  | 
 | ||||||
|   .ant-table-is-sorting .dragging { |   .ant-table-is-sorting .dragging { | ||||||
|     opacity: 1; |     opacity: 1; | ||||||
|     box-shadow: 1px -2px 2px #008771; |     box-shadow: 1px -2px 2px #008771; | ||||||
|     transition: all 0.2s; |     transition: all 0.2s; | ||||||
|   } |   } | ||||||
|  | 
 | ||||||
|   .ant-table-is-sorting .dragging .ant-table-row-index { |   .ant-table-is-sorting .dragging .ant-table-row-index { | ||||||
|     opacity: 0.3; |     opacity: 0.3; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  | @ -6,9 +6,13 @@ | ||||||
|         <a-icon type="bulb" :theme="themeSwitcher.isDarkTheme ? 'filled' : 'outlined'"></a-icon> |         <a-icon type="bulb" :theme="themeSwitcher.isDarkTheme ? 'filled' : 'outlined'"></a-icon> | ||||||
|         <span>Theme</span> |         <span>Theme</span> | ||||||
|       </span> |       </span> | ||||||
|       <a-menu-item id="change-theme" class="ant-menu-theme-switch" @mousedown="themeSwitcher.animationsOff()"> Dark <a-switch style="margin-left: 2px;" size="small" :default-checked="themeSwitcher.isDarkTheme" @change="themeSwitcher.toggleTheme()"></a-switch> |       <a-menu-item id="change-theme" class="ant-menu-theme-switch" @mousedown="themeSwitcher.animationsOff()"> Dark | ||||||
|  |         <a-switch style="margin-left: 2px;" size="small" :default-checked="themeSwitcher.isDarkTheme" | ||||||
|  |           @change="themeSwitcher.toggleTheme()"></a-switch> | ||||||
|       </a-menu-item> |       </a-menu-item> | ||||||
|       <a-menu-item id="change-theme-ultra" v-if="themeSwitcher.isDarkTheme" class="ant-menu-theme-switch" @mousedown="themeSwitcher.animationsOffUltra()"> Ultra <a-checkbox style="margin-left: 2px;" :checked="themeSwitcher.isUltra" @click="themeSwitcher.toggleUltra()"></a-checkbox> |       <a-menu-item id="change-theme-ultra" v-if="themeSwitcher.isDarkTheme" class="ant-menu-theme-switch" | ||||||
|  |         @mousedown="themeSwitcher.animationsOffUltra()"> Ultra <a-checkbox style="margin-left: 2px;" | ||||||
|  |           :checked="themeSwitcher.isUltra" @click="themeSwitcher.toggleUltra()"></a-checkbox> | ||||||
|       </a-menu-item> |       </a-menu-item> | ||||||
|     </a-sub-menu> |     </a-sub-menu> | ||||||
|   </a-menu> |   </a-menu> | ||||||
|  | @ -17,12 +21,15 @@ | ||||||
| 
 | 
 | ||||||
| {{define "component/themeSwitchTemplateLogin"}} | {{define "component/themeSwitchTemplateLogin"}} | ||||||
| <template> | <template> | ||||||
|   <a-menu @mousedown="themeSwitcher.animationsOff()" id="change-theme" :theme="themeSwitcher.currentTheme" mode="inline" selected-keys=""> |   <a-menu @mousedown="themeSwitcher.animationsOff()" id="change-theme" :theme="themeSwitcher.currentTheme" mode="inline" | ||||||
|  |     selected-keys=""> | ||||||
|     <a-menu-item mode="inline" class="ant-menu-theme-switch"> |     <a-menu-item mode="inline" class="ant-menu-theme-switch"> | ||||||
|       <a-icon type="bulb" :theme="themeSwitcher.isDarkTheme ? 'filled' : 'outlined'"></a-icon> |       <a-icon type="bulb" :theme="themeSwitcher.isDarkTheme ? 'filled' : 'outlined'"></a-icon> | ||||||
|       <a-switch size="small" :default-checked="themeSwitcher.isDarkTheme" @change="themeSwitcher.toggleTheme()"></a-switch> |       <a-switch size="small" :default-checked="themeSwitcher.isDarkTheme" | ||||||
|  |         @change="themeSwitcher.toggleTheme()"></a-switch> | ||||||
|       <template v-if="themeSwitcher.isDarkTheme"> |       <template v-if="themeSwitcher.isDarkTheme"> | ||||||
|         <a-checkbox style="margin-left: 1rem; vertical-align: middle;" :checked="themeSwitcher.isUltra" @click="themeSwitcher.toggleUltra()">Ultra</a-checkbox> |         <a-checkbox style="margin-left: 1rem; vertical-align: middle;" :checked="themeSwitcher.isUltra" | ||||||
|  |           @click="themeSwitcher.toggleUltra()">Ultra</a-checkbox> | ||||||
|       </template> |       </template> | ||||||
|     </a-menu-item> |     </a-menu-item> | ||||||
|   </a-menu> |   </a-menu> | ||||||
|  | @ -83,8 +90,7 @@ | ||||||
|     }; |     }; | ||||||
|   } |   } | ||||||
|   const themeSwitcher = createThemeSwitcher(); |   const themeSwitcher = createThemeSwitcher(); | ||||||
|   Vue.component('theme-switch', { |   Vue.component('a-theme-switch', { | ||||||
|     props: [], |  | ||||||
|     template: `{{template "component/themeSwitchTemplate"}}`, |     template: `{{template "component/themeSwitchTemplate"}}`, | ||||||
|     data: () => ({ |     data: () => ({ | ||||||
|       themeSwitcher |       themeSwitcher | ||||||
|  | @ -96,8 +102,7 @@ | ||||||
|       document.getElementById('message').className = themeSwitcher.currentTheme; |       document.getElementById('message').className = themeSwitcher.currentTheme; | ||||||
|     } |     } | ||||||
|   }); |   }); | ||||||
|   Vue.component('theme-switch-login', { |   Vue.component('a-theme-switch-login', { | ||||||
|     props: [], |  | ||||||
|     template: `{{template "component/themeSwitchTemplateLogin"}}`, |     template: `{{template "component/themeSwitchTemplateLogin"}}`, | ||||||
|     data: () => ({ |     data: () => ({ | ||||||
|       themeSwitcher |       themeSwitcher | ||||||
|  |  | ||||||
|  | @ -154,8 +154,8 @@ | ||||||
|         </template> |         </template> | ||||||
|         <a-date-picker v-if="datepicker == 'gregorian'" :show-time="{ format: 'HH:mm:ss' }" format="YYYY-MM-DD HH:mm:ss" |         <a-date-picker v-if="datepicker == 'gregorian'" :show-time="{ format: 'HH:mm:ss' }" format="YYYY-MM-DD HH:mm:ss" | ||||||
|             :dropdown-class-name="themeSwitcher.currentTheme" v-model="client._expiryTime"></a-date-picker> |             :dropdown-class-name="themeSwitcher.currentTheme" v-model="client._expiryTime"></a-date-picker> | ||||||
|         <persian-datepicker v-else placeholder='{{ i18n "pages.settings.datepickerPlaceholder" }}' |         <a-persian-datepicker v-else placeholder='{{ i18n "pages.settings.datepickerPlaceholder" }}' | ||||||
|                             value="client._expiryTime" v-model="client._expiryTime"></persian-datepicker> |                             value="client._expiryTime" v-model="client._expiryTime"></a-persian-datepicker> | ||||||
|         <a-tag color="red" v-if="isEdit && isExpiry">Expired</a-tag> |         <a-tag color="red" v-if="isEdit && isExpiry">Expired</a-tag> | ||||||
|     </a-form-item> |     </a-form-item> | ||||||
|     <a-form-item v-if="client.expiryTime != 0"> |     <a-form-item v-if="client.expiryTime != 0"> | ||||||
|  |  | ||||||
|  | @ -57,9 +57,9 @@ | ||||||
|         <a-date-picker style="width: 100%;" v-if="datepicker == 'gregorian'" :show-time="{ format: 'HH:mm:ss' }" |         <a-date-picker style="width: 100%;" v-if="datepicker == 'gregorian'" :show-time="{ format: 'HH:mm:ss' }" | ||||||
|             format="YYYY-MM-DD HH:mm:ss" :dropdown-class-name="themeSwitcher.currentTheme" |             format="YYYY-MM-DD HH:mm:ss" :dropdown-class-name="themeSwitcher.currentTheme" | ||||||
|             v-model="dbInbound._expiryTime"></a-date-picker> |             v-model="dbInbound._expiryTime"></a-date-picker> | ||||||
|         <persian-datepicker v-else placeholder='{{ i18n "pages.settings.datepickerPlaceholder" }}' |         <a-persian-datepicker v-else placeholder='{{ i18n "pages.settings.datepickerPlaceholder" }}' | ||||||
|             value="dbInbound._expiryTime" v-model="dbInbound._expiryTime"> |             value="dbInbound._expiryTime" v-model="dbInbound._expiryTime"> | ||||||
|         </persian-datepicker> |         </a-persian-datepicker> | ||||||
|     </a-form-item> |     </a-form-item> | ||||||
| </a-form> | </a-form> | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -271,7 +271,7 @@ | ||||||
|                     <a-setting-list-item paddings="small"> |                     <a-setting-list-item paddings="small"> | ||||||
|                       <template #title>{{ i18n "pages.settings.currentPassword"}}</template> |                       <template #title>{{ i18n "pages.settings.currentPassword"}}</template> | ||||||
|                       <template #control> |                       <template #control> | ||||||
|                         <password-input autocomplete="current-password" v-model="user.oldPassword"></password-input> |                         <a-password-input autocomplete="current-password" v-model="user.oldPassword"></a-password-input> | ||||||
|                       </template> |                       </template> | ||||||
|                     </a-setting-list-item> |                     </a-setting-list-item> | ||||||
|                     <a-setting-list-item paddings="small"> |                     <a-setting-list-item paddings="small"> | ||||||
|  | @ -283,7 +283,7 @@ | ||||||
|                     <a-setting-list-item paddings="small"> |                     <a-setting-list-item paddings="small"> | ||||||
|                       <template #title>{{ i18n "pages.settings.newPassword"}}</template> |                       <template #title>{{ i18n "pages.settings.newPassword"}}</template> | ||||||
|                       <template #control> |                       <template #control> | ||||||
|                         <password-input autocomplete="new-password" v-model="user.newPassword"></password-input> |                         <a-password-input autocomplete="new-password" v-model="user.newPassword"></a-password-input> | ||||||
|                       </template> |                       </template> | ||||||
|                     </a-setting-list-item> |                     </a-setting-list-item> | ||||||
|                     <a-list-item> |                     <a-list-item> | ||||||
|  |  | ||||||
|  | @ -348,7 +348,7 @@ | ||||||
|                         :indent-size="0"  |                         :indent-size="0"  | ||||||
|                         v-on:onSort="replaceRule"> |                         v-on:onSort="replaceRule"> | ||||||
|                     <template slot="action" slot-scope="text, rule, index"> |                     <template slot="action" slot-scope="text, rule, index"> | ||||||
|                         <table-sort-trigger :item-index="index"></table-sort-trigger> |                         <a-table-sort-trigger :item-index="index"></a-table-sort-trigger> | ||||||
|                         <span class="ant-table-row-index"> [[ index+1 ]] </span> |                         <span class="ant-table-row-index"> [[ index+1 ]] </span> | ||||||
|                         <a-dropdown :trigger="['click']"> |                         <a-dropdown :trigger="['click']"> | ||||||
|                         <a-icon @click="e => e.preventDefault()" type="more" style="font-size: 16px; text-decoration: bold;"></a-icon> |                         <a-icon @click="e => e.preventDefault()" type="more" style="font-size: 16px; text-decoration: bold;"></a-icon> | ||||||
|  | @ -806,16 +806,16 @@ | ||||||
|             { title: 'Port', dataIndex: 'sourcePort', align: 'center', width: 10, ellipsis: true } ]}, |             { title: 'Port', dataIndex: 'sourcePort', align: 'center', width: 10, ellipsis: true } ]}, | ||||||
|         { title: '{{ i18n "pages.inbounds.network"}}', children: [ |         { title: '{{ i18n "pages.inbounds.network"}}', children: [ | ||||||
|             { title: 'L4', dataIndex: 'network', align: 'center', width: 10 }, |             { title: 'L4', dataIndex: 'network', align: 'center', width: 10 }, | ||||||
|             { title: 'Protocol', dataIndex: 'protocol', align: 'center', width: 10, ellipsis: true }, |             { title: 'Protocol', dataIndex: 'protocol', align: 'center', width: 15, ellipsis: true }, | ||||||
|             { title: 'Attrs', dataIndex: 'attrs', align: 'center', width: 20, ellipsis: true } ]},  |             { title: 'Attrs', dataIndex: 'attrs', align: 'center', width: 10, ellipsis: true } ]},  | ||||||
|         { title: '{{ i18n "pages.xray.rules.dest"}}', children: [ |         { title: '{{ i18n "pages.xray.rules.dest"}}', children: [ | ||||||
|             { title: 'IP', dataIndex: 'ip', align: 'center', width: 20, ellipsis: true }, |             { title: 'IP', dataIndex: 'ip', align: 'center', width: 20, ellipsis: true }, | ||||||
|             { title: 'Domain', dataIndex: 'domain', align: 'center', width: 20, ellipsis: true }, |             { title: 'Domain', dataIndex: 'domain', align: 'center', width: 20, ellipsis: true }, | ||||||
|             { title: 'Port', dataIndex: 'port', align: 'center', width: 10, ellipsis: true }]}, |             { title: 'Port', dataIndex: 'port', align: 'center', width: 10, ellipsis: true }]}, | ||||||
|         { title: '{{ i18n "pages.xray.rules.inbound"}}', children: [ |         { title: '{{ i18n "pages.xray.rules.inbound"}}', children: [ | ||||||
|             { title: 'Inbound Tag', dataIndex: 'inboundTag', align: 'center', width: 15, ellipsis: true }, |             { title: 'Tag', dataIndex: 'inboundTag', align: 'center', width: 15, ellipsis: true }, | ||||||
|             { title: 'Client Email', dataIndex: 'user', align: 'center', width: 20, ellipsis: true }]}, |             { title: 'Client Email', dataIndex: 'user', align: 'center', width: 20, ellipsis: true }]}, | ||||||
|         { title: '{{ i18n "pages.xray.rules.outbound"}}', dataIndex: 'outboundTag', align: 'center', width: 15 }, |         { title: '{{ i18n "pages.xray.rules.outbound"}}', dataIndex: 'outboundTag', align: 'center', width: 17 }, | ||||||
|         { title: '{{ i18n "pages.xray.rules.balancer"}}', dataIndex: 'balancerTag', align: 'center', width: 15 }, |         { title: '{{ i18n "pages.xray.rules.balancer"}}', dataIndex: 'balancerTag', align: 'center', width: 15 }, | ||||||
|     ]; |     ]; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -307,8 +307,6 @@ func (t *Tgbot) answerCommand(message *telego.Message, chatId int64, isAdmin boo | ||||||
| 		onlyMessage = true | 		onlyMessage = true | ||||||
| 		if isAdmin { | 		if isAdmin { | ||||||
| 			if len(commandArgs) == 0 { | 			if len(commandArgs) == 0 { | ||||||
| 				msg += t.I18nBot("tgbot.commands.restartUsage") |  | ||||||
| 			} else if strings.ToLower(commandArgs[0]) == "force" { |  | ||||||
| 				if t.xrayService.IsXrayRunning() { | 				if t.xrayService.IsXrayRunning() { | ||||||
| 					err := t.xrayService.RestartXray(true) | 					err := t.xrayService.RestartXray(true) | ||||||
| 					if err != nil { | 					if err != nil { | ||||||
|  |  | ||||||
|  | @ -518,9 +518,9 @@ | ||||||
| "status" = "✅ Bot is OK!" | "status" = "✅ Bot is OK!" | ||||||
| "usage" = "❗ Please provide a text to search!" | "usage" = "❗ Please provide a text to search!" | ||||||
| "getID" = "🆔 Your ID: <code>{{ .ID }}</code>" | "getID" = "🆔 Your ID: <code>{{ .ID }}</code>" | ||||||
| "helpAdminCommands" = "To restart Xray Core:\r\n<code>/restart force</code>\r\n\r\nTo search for a client email:\r\n<code>/usage [Email]</code>\r\n\r\nTo search for inbounds (with client stats):\r\n<code>/inbound [Remark]</code>\r\n\r\nTelegram Chat ID:\r\n<code>/id</code>" | "helpAdminCommands" = "To restart Xray Core:\r\n<code>/restart</code>\r\n\r\nTo search for a client email:\r\n<code>/usage [Email]</code>\r\n\r\nTo search for inbounds (with client stats):\r\n<code>/inbound [Remark]</code>\r\n\r\nTelegram Chat ID:\r\n<code>/id</code>" | ||||||
| "helpClientCommands" = "To search for statistics, use the following command:\r\n\r\n<code>/usage [Email]</code>\r\n\r\nTelegram Chat ID:\r\n<code>/id</code>" | "helpClientCommands" = "To search for statistics, use the following command:\r\n\r\n<code>/usage [Email]</code>\r\n\r\nTelegram Chat ID:\r\n<code>/id</code>" | ||||||
| "restartUsage" = "\r\n\r\n<code>/restart force</code>" | "restartUsage" = "\r\n\r\n<code>/restart</code>" | ||||||
| "restartSuccess" = "✅ Operation successful!" | "restartSuccess" = "✅ Operation successful!" | ||||||
| "restartFailed" = "❗ Error in operation.\r\n\r\n<code>Error: {{ .Error }}</code>." | "restartFailed" = "❗ Error in operation.\r\n\r\n<code>Error: {{ .Error }}</code>." | ||||||
| "xrayNotRunning" = "❗ Xray Core is not running." | "xrayNotRunning" = "❗ Xray Core is not running." | ||||||
|  |  | ||||||
|  | @ -518,9 +518,9 @@ | ||||||
| "status" = "✅ ¡El bot está bien!" | "status" = "✅ ¡El bot está bien!" | ||||||
| "usage" = "❗ ¡Por favor proporciona un texto para buscar!" | "usage" = "❗ ¡Por favor proporciona un texto para buscar!" | ||||||
| "getID" = "🆔 Tu ID: <code>{{ .ID }}</code>" | "getID" = "🆔 Tu ID: <code>{{ .ID }}</code>" | ||||||
| "helpAdminCommands" = "Para reiniciar Xray Core:\r\n<code>/restart force</code>\r\n\r\nPara buscar un correo electrónico de cliente:\r\n<code>/usage [Correo electrónico]</code>\r\n\r\nPara buscar entradas (con estadísticas de cliente):\r\n<code>/inbound [Observación]</code>\r\n\r\nID de Chat de Telegram:\r\n<code>/id</code>" | "helpAdminCommands" = "Para reiniciar Xray Core:\r\n<code>/restart</code>\r\n\r\nPara buscar un correo electrónico de cliente:\r\n<code>/usage [Correo electrónico]</code>\r\n\r\nPara buscar entradas (con estadísticas de cliente):\r\n<code>/inbound [Observación]</code>\r\n\r\nID de Chat de Telegram:\r\n<code>/id</code>" | ||||||
| "helpClientCommands" = "Para buscar estadísticas, utiliza el siguiente comando:\r\n<code>/usage [Correo electrónico]</code>\r\n\r\nID de Chat de Telegram:\r\n<code>/id</code>" | "helpClientCommands" = "Para buscar estadísticas, utiliza el siguiente comando:\r\n<code>/usage [Correo electrónico]</code>\r\n\r\nID de Chat de Telegram:\r\n<code>/id</code>" | ||||||
| "restartUsage" = "\r\n\r\n<code>/restart force</code>" | "restartUsage" = "\r\n\r\n<code>/restart</code>" | ||||||
| "restartSuccess" = "✅ ¡Operación exitosa!" | "restartSuccess" = "✅ ¡Operación exitosa!" | ||||||
| "restartFailed" = "❗ Error en la operación.\r\n\r\n<code>Error: {{ .Error }}</code>." | "restartFailed" = "❗ Error en la operación.\r\n\r\n<code>Error: {{ .Error }}</code>." | ||||||
| "xrayNotRunning" = "❗ Xray Core no está en ejecución." | "xrayNotRunning" = "❗ Xray Core no está en ejecución." | ||||||
|  |  | ||||||
|  | @ -518,9 +518,9 @@ | ||||||
| "status" = "✅ ربات در حالت عادی است!" | "status" = "✅ ربات در حالت عادی است!" | ||||||
| "usage" = "❗ لطفاً یک متن برای جستجو وارد کنید!" | "usage" = "❗ لطفاً یک متن برای جستجو وارد کنید!" | ||||||
| "getID" = "🆔 شناسه شما: <code>{{ .ID }}</code>" | "getID" = "🆔 شناسه شما: <code>{{ .ID }}</code>" | ||||||
| "helpAdminCommands" = "برای راهاندازی مجدد Xray Core:\r\n<code>/restart force</code>\r\n\r\nبرای جستجوی ایمیل مشتری:\r\n<code>/usage [ایمیل]</code>\r\n\r\nبرای جستجوی ورودیها (با آمار مشتری):\r\n<code>/inbound [توضیحات]</code>\r\n\r\nشناسه گفتگوی تلگرام:\r\n<code>/id</code>" | "helpAdminCommands" = "برای راهاندازی مجدد Xray Core:\r\n<code>/restart</code>\r\n\r\nبرای جستجوی ایمیل مشتری:\r\n<code>/usage [ایمیل]</code>\r\n\r\nبرای جستجوی ورودیها (با آمار مشتری):\r\n<code>/inbound [توضیحات]</code>\r\n\r\nشناسه گفتگوی تلگرام:\r\n<code>/id</code>" | ||||||
| "helpClientCommands" = "برای جستجوی آمار، از دستور زیر استفاده کنید:\r\n<code>/usage [ایمیل]</code>\r\n\r\nشناسه گفتگوی تلگرام:\r\n<code>/id</code>" | "helpClientCommands" = "برای جستجوی آمار، از دستور زیر استفاده کنید:\r\n<code>/usage [ایمیل]</code>\r\n\r\nشناسه گفتگوی تلگرام:\r\n<code>/id</code>" | ||||||
| "restartUsage" = "\r\n\r\n<code>/restart force</code>" | "restartUsage" = "\r\n\r\n<code>/restart</code>" | ||||||
| "restartSuccess" = "✅ عملیات با موفقیت انجام شد!" | "restartSuccess" = "✅ عملیات با موفقیت انجام شد!" | ||||||
| "restartFailed" = "❗ خطا در عملیات.\r\n\r\n<code>خطا: {{ .Error }}</code>." | "restartFailed" = "❗ خطا در عملیات.\r\n\r\n<code>خطا: {{ .Error }}</code>." | ||||||
| "xrayNotRunning" = "❗ Xray Core در حال اجرا نیست." | "xrayNotRunning" = "❗ Xray Core در حال اجرا نیست." | ||||||
|  |  | ||||||
|  | @ -517,9 +517,9 @@ | ||||||
| "status" = "✅ Bot dalam keadaan baik!" | "status" = "✅ Bot dalam keadaan baik!" | ||||||
| "usage" = "❗ Harap berikan teks untuk mencari!" | "usage" = "❗ Harap berikan teks untuk mencari!" | ||||||
| "getID" = "🆔 ID Anda: <code>{{ .ID }}</code>" | "getID" = "🆔 ID Anda: <code>{{ .ID }}</code>" | ||||||
| "helpAdminCommands" = "Untuk memulai ulang Xray Core:\r\n<code>/restart force</code>\r\n\r\nUntuk mencari email klien:\r\n<code>/usage [Email]</code>\r\n\r\nUntuk mencari inbound (dengan statistik klien):\r\n<code>/inbound [Catatan]</code>\r\n\r\nID Obrolan Telegram:\r\n<code>/id</code>" | "helpAdminCommands" = "Untuk memulai ulang Xray Core:\r\n<code>/restart</code>\r\n\r\nUntuk mencari email klien:\r\n<code>/usage [Email]</code>\r\n\r\nUntuk mencari inbound (dengan statistik klien):\r\n<code>/inbound [Catatan]</code>\r\n\r\nID Obrolan Telegram:\r\n<code>/id</code>" | ||||||
| "helpClientCommands" = "Untuk mencari statistik, gunakan perintah berikut:\r\n<code>/usage [Email]</code>\r\n\r\nID Obrolan Telegram:\r\n<code>/id</code>" | "helpClientCommands" = "Untuk mencari statistik, gunakan perintah berikut:\r\n<code>/usage [Email]</code>\r\n\r\nID Obrolan Telegram:\r\n<code>/id</code>" | ||||||
| "restartUsage" = "\r\n\r\n<code>/restart force</code>" | "restartUsage" = "\r\n\r\n<code>/restart</code>" | ||||||
| "restartSuccess" = "✅ Operasi berhasil!" | "restartSuccess" = "✅ Operasi berhasil!" | ||||||
| "restartFailed" = "❗ Kesalahan dalam operasi.\r\n\r\n<code>Error: {{ .Error }}</code>." | "restartFailed" = "❗ Kesalahan dalam operasi.\r\n\r\n<code>Error: {{ .Error }}</code>." | ||||||
| "xrayNotRunning" = "❗ Xray Core tidak berjalan." | "xrayNotRunning" = "❗ Xray Core tidak berjalan." | ||||||
|  |  | ||||||
|  | @ -518,9 +518,9 @@ | ||||||
| "status" = "✅ ボットは正常に動作しています!" | "status" = "✅ ボットは正常に動作しています!" | ||||||
| "usage" = "❗ 検索するテキストを入力してください!" | "usage" = "❗ 検索するテキストを入力してください!" | ||||||
| "getID" = "🆔 あなたのIDは:<code>{{ .ID }}</code>" | "getID" = "🆔 あなたのIDは:<code>{{ .ID }}</code>" | ||||||
| "helpAdminCommands" = "Xray Coreを再起動するには:\r\n<code>/restart force</code>\r\n\r\nクライアントの電子メールを検索するには:\r\n<code>/usage [電子メール]</code>\r\n\r\nインバウンド(クライアントの統計情報を含む)を検索するには:\r\n<code>/inbound [備考]</code>\r\n\r\nTelegramチャットID:\r\n<code>/id</code>" | "helpAdminCommands" = "Xray Coreを再起動するには:\r\n<code>/restart</code>\r\n\r\nクライアントの電子メールを検索するには:\r\n<code>/usage [電子メール]</code>\r\n\r\nインバウンド(クライアントの統計情報を含む)を検索するには:\r\n<code>/inbound [備考]</code>\r\n\r\nTelegramチャットID:\r\n<code>/id</code>" | ||||||
| "helpClientCommands" = "統計情報を検索するには、次のコマンドを使用してください:\r\n<code>/usage [電子メール]</code>\r\n\r\nTelegramチャットID:\r\n<code>/id</code>" | "helpClientCommands" = "統計情報を検索するには、次のコマンドを使用してください:\r\n<code>/usage [電子メール]</code>\r\n\r\nTelegramチャットID:\r\n<code>/id</code>" | ||||||
| "restartUsage" = "\r\n\r\n<code>/restart force</code>" | "restartUsage" = "\r\n\r\n<code>/restart</code>" | ||||||
| "restartSuccess" = "✅ 操作成功!" | "restartSuccess" = "✅ 操作成功!" | ||||||
| "restartFailed" = "❗ 操作エラー。\r\n\r\n<code>エラー: {{ .Error }}</code>" | "restartFailed" = "❗ 操作エラー。\r\n\r\n<code>エラー: {{ .Error }}</code>" | ||||||
| "xrayNotRunning" = "❗ Xray Core は動作していません。" | "xrayNotRunning" = "❗ Xray Core は動作していません。" | ||||||
|  |  | ||||||
|  | @ -518,9 +518,9 @@ | ||||||
| "status" = "✅ Bot está OK!" | "status" = "✅ Bot está OK!" | ||||||
| "usage" = "❗ Por favor, forneça um texto para pesquisar!" | "usage" = "❗ Por favor, forneça um texto para pesquisar!" | ||||||
| "getID" = "🆔 Seu ID: <code>{{ .ID }}</code>" | "getID" = "🆔 Seu ID: <code>{{ .ID }}</code>" | ||||||
| "helpAdminCommands" = "Para reiniciar o Xray Core:\r\n<code>/restart force</code>\r\n\r\nPara pesquisar por um email de cliente:\r\n<code>/usage [Email]</code>\r\n\r\nPara pesquisar por inbounds (com estatísticas do cliente):\r\n<code>/inbound [Remark]</code>\r\n\r\nTelegram Chat ID:\r\n<code>/id</code>" | "helpAdminCommands" = "Para reiniciar o Xray Core:\r\n<code>/restart</code>\r\n\r\nPara pesquisar por um email de cliente:\r\n<code>/usage [Email]</code>\r\n\r\nPara pesquisar por inbounds (com estatísticas do cliente):\r\n<code>/inbound [Remark]</code>\r\n\r\nTelegram Chat ID:\r\n<code>/id</code>" | ||||||
| "helpClientCommands" = "Para pesquisar por estatísticas, use o seguinte comando:\r\n\r\n<code>/usage [Email]</code>\r\n\r\nTelegram Chat ID:\r\n<code>/id</code>" | "helpClientCommands" = "Para pesquisar por estatísticas, use o seguinte comando:\r\n\r\n<code>/usage [Email]</code>\r\n\r\nTelegram Chat ID:\r\n<code>/id</code>" | ||||||
| "restartUsage" = "\r\n\r\n<code>/restart force</code>" | "restartUsage" = "\r\n\r\n<code>/restart</code>" | ||||||
| "restartSuccess" = "✅ Operação bem-sucedida!" | "restartSuccess" = "✅ Operação bem-sucedida!" | ||||||
| "restartFailed" = "❗ Erro na operação.\r\n\r\n<code>Erro: {{ .Error }}</code>." | "restartFailed" = "❗ Erro na operação.\r\n\r\n<code>Erro: {{ .Error }}</code>." | ||||||
| "xrayNotRunning" = "❗ Xray Core não está em execução." | "xrayNotRunning" = "❗ Xray Core não está em execução." | ||||||
|  |  | ||||||
|  | @ -518,9 +518,9 @@ | ||||||
| "status" = "✅ Бот работает нормально!" | "status" = "✅ Бот работает нормально!" | ||||||
| "usage" = "❗ Пожалуйста, укажите текст для поиска!" | "usage" = "❗ Пожалуйста, укажите текст для поиска!" | ||||||
| "getID" = "🆔 Ваш ID: <code>{{ .ID }}</code>" | "getID" = "🆔 Ваш ID: <code>{{ .ID }}</code>" | ||||||
| "helpAdminCommands" = "Для перезапуска Xray Core:\r\n<code>/restart force</code>\r\n\r\nДля поиска электронной почты клиента:\r\n<code>/usage [Email]</code>\r\n\r\nДля поиска входящих (со статистикой клиента):\r\n<code>/inbound [Примечание]</code>\r\n\r\nID чата Telegram:\r\n<code>/id</code>" | "helpAdminCommands" = "Для перезапуска Xray Core:\r\n<code>/restart</code>\r\n\r\nДля поиска электронной почты клиента:\r\n<code>/usage [Email]</code>\r\n\r\nДля поиска входящих (со статистикой клиента):\r\n<code>/inbound [Примечание]</code>\r\n\r\nID чата Telegram:\r\n<code>/id</code>" | ||||||
| "helpClientCommands" = "Для поиска статистики используйте следующую команду:\r\n<code>/usage [Email]</code>\r\n\r\nID чата Telegram:\r\n<code>/id</code>" | "helpClientCommands" = "Для поиска статистики используйте следующую команду:\r\n<code>/usage [Email]</code>\r\n\r\nID чата Telegram:\r\n<code>/id</code>" | ||||||
| "restartUsage" = "\r\n\r\n<code>/restart force</code>" | "restartUsage" = "\r\n\r\n<code>/restart</code>" | ||||||
| "restartSuccess" = "✅ Операция успешно завершена!" | "restartSuccess" = "✅ Операция успешно завершена!" | ||||||
| "restartFailed" = "❗ Ошибка в операции.\r\n\r\n<code>Ошибка: {{ .Error }}</code>." | "restartFailed" = "❗ Ошибка в операции.\r\n\r\n<code>Ошибка: {{ .Error }}</code>." | ||||||
| "xrayNotRunning" = "❗ Xray Core не запущен." | "xrayNotRunning" = "❗ Xray Core не запущен." | ||||||
|  |  | ||||||
|  | @ -518,9 +518,9 @@ | ||||||
| "status" = "✅ Bot çalışıyor!" | "status" = "✅ Bot çalışıyor!" | ||||||
| "usage" = "❗ Lütfen aramak için bir metin sağlayın!" | "usage" = "❗ Lütfen aramak için bir metin sağlayın!" | ||||||
| "getID" = "🆔 Kimliğiniz: <code>{{ .ID }}</code>" | "getID" = "🆔 Kimliğiniz: <code>{{ .ID }}</code>" | ||||||
| "helpAdminCommands" = "Xray Core'u yeniden başlatmak için:\r\n<code>/restart force</code>\r\n\r\nBir müşteri e-postasını aramak için:\r\n<code>/usage [E-posta]</code>\r\n\r\nGelenleri aramak için (müşteri istatistikleri ile):\r\n<code>/inbound [Açıklama]</code>\r\n\r\nTelegram Sohbet Kimliği:\r\n<code>/id</code>" | "helpAdminCommands" = "Xray Core'u yeniden başlatmak için:\r\n<code>/restart</code>\r\n\r\nBir müşteri e-postasını aramak için:\r\n<code>/usage [E-posta]</code>\r\n\r\nGelenleri aramak için (müşteri istatistikleri ile):\r\n<code>/inbound [Açıklama]</code>\r\n\r\nTelegram Sohbet Kimliği:\r\n<code>/id</code>" | ||||||
| "helpClientCommands" = "İstatistikleri aramak için şu komutu kullanın:\r\n\r\n<code>/usage [E-posta]</code>\r\n\r\nTelegram Sohbet Kimliği:\r\n<code>/id</code>" | "helpClientCommands" = "İstatistikleri aramak için şu komutu kullanın:\r\n\r\n<code>/usage [E-posta]</code>\r\n\r\nTelegram Sohbet Kimliği:\r\n<code>/id</code>" | ||||||
| "restartUsage" = "\r\n\r\n<code>/restart force</code>" | "restartUsage" = "\r\n\r\n<code>/restart</code>" | ||||||
| "restartSuccess" = "✅ İşlem başarılı!" | "restartSuccess" = "✅ İşlem başarılı!" | ||||||
| "restartFailed" = "❗ İşlem hatası.\r\n\r\n<code>Hata: {{ .Error }}</code>." | "restartFailed" = "❗ İşlem hatası.\r\n\r\n<code>Hata: {{ .Error }}</code>." | ||||||
| "xrayNotRunning" = "❗ Xray Core çalışmıyor." | "xrayNotRunning" = "❗ Xray Core çalışmıyor." | ||||||
|  |  | ||||||
|  | @ -518,9 +518,9 @@ | ||||||
| "status" = "✅ Бот в порядку!" | "status" = "✅ Бот в порядку!" | ||||||
| "usage" = "❗ Введіть текст для пошуку!" | "usage" = "❗ Введіть текст для пошуку!" | ||||||
| "getID" = "🆔 Ваш ідентифікатор: <code>{{ .ID }}</code>" | "getID" = "🆔 Ваш ідентифікатор: <code>{{ .ID }}</code>" | ||||||
| "helpAdminCommands" = "Для перезапуску Xray Core:\r\n<code>/restart force</code>\r\n\r\nДля пошуку електронної пошти клієнта:\r\n<code>/usage [Електронна пошта]</code>\r\n\r\nДля пошуку вхідних (зі статистикою клієнта):\r\n<code>/inbound [Примітка]</code>\r\n\r\nID чату Telegram:\r\n<code>/id</code>" | "helpAdminCommands" = "Для перезапуску Xray Core:\r\n<code>/restart</code>\r\n\r\nДля пошуку електронної пошти клієнта:\r\n<code>/usage [Електронна пошта]</code>\r\n\r\nДля пошуку вхідних (зі статистикою клієнта):\r\n<code>/inbound [Примітка]</code>\r\n\r\nID чату Telegram:\r\n<code>/id</code>" | ||||||
| "helpClientCommands" = "Для пошуку статистики використовуйте наступну команду:\r\n<code>/usage [Електронна пошта]</code>\r\n\r\nID чату Telegram:\r\n<code>/id</code>" | "helpClientCommands" = "Для пошуку статистики використовуйте наступну команду:\r\n<code>/usage [Електронна пошта]</code>\r\n\r\nID чату Telegram:\r\n<code>/id</code>" | ||||||
| "restartUsage" = "\r\n\r\n<code>/restart force</code>" | "restartUsage" = "\r\n\r\n<code>/restart</code>" | ||||||
| "restartSuccess" = "✅ Операція успішна!" | "restartSuccess" = "✅ Операція успішна!" | ||||||
| "restartFailed" = "❗ Помилка в операції.\r\n\r\n<code>Помилка: {{ .Error }}</code>." | "restartFailed" = "❗ Помилка в операції.\r\n\r\n<code>Помилка: {{ .Error }}</code>." | ||||||
| "xrayNotRunning" = "❗ Xray Core не запущений." | "xrayNotRunning" = "❗ Xray Core не запущений." | ||||||
|  |  | ||||||
|  | @ -518,9 +518,9 @@ | ||||||
| "status" = "✅ Bot hoạt động bình thường!" | "status" = "✅ Bot hoạt động bình thường!" | ||||||
| "usage" = "❗ Vui lòng cung cấp văn bản để tìm kiếm!" | "usage" = "❗ Vui lòng cung cấp văn bản để tìm kiếm!" | ||||||
| "getID" = "🆔 ID của bạn: <code>{{ .ID }}</code>" | "getID" = "🆔 ID của bạn: <code>{{ .ID }}</code>" | ||||||
| "helpAdminCommands" = "Để khởi động lại Xray Core:\r\n<code>/restart force</code>\r\n\r\nĐể tìm kiếm email của khách hàng:\r\n<code>/usage [Email]</code>\r\n\r\nĐể tìm kiếm các nhập (với số liệu thống kê của khách hàng):\r\n<code>/inbound [Ghi chú]</code>\r\n\r\nID Trò chuyện Telegram:\r\n<code>/id</code>" | "helpAdminCommands" = "Để khởi động lại Xray Core:\r\n<code>/restart</code>\r\n\r\nĐể tìm kiếm email của khách hàng:\r\n<code>/usage [Email]</code>\r\n\r\nĐể tìm kiếm các nhập (với số liệu thống kê của khách hàng):\r\n<code>/inbound [Ghi chú]</code>\r\n\r\nID Trò chuyện Telegram:\r\n<code>/id</code>" | ||||||
| "helpClientCommands" = "Để tìm kiếm thống kê, sử dụng lệnh sau:\r\n<code>/usage [Email]</code>\r\n\r\nID Trò chuyện Telegram:\r\n<code>/id</code>" | "helpClientCommands" = "Để tìm kiếm thống kê, sử dụng lệnh sau:\r\n<code>/usage [Email]</code>\r\n\r\nID Trò chuyện Telegram:\r\n<code>/id</code>" | ||||||
| "restartUsage" = "\r\n\r\n<code>/restart force</code>" | "restartUsage" = "\r\n\r\n<code>/restart</code>" | ||||||
| "restartSuccess" = "✅ Hoạt động thành công!" | "restartSuccess" = "✅ Hoạt động thành công!" | ||||||
| "restartFailed" = "❗ Lỗi trong quá trình hoạt động.\r\n\r\n<code>Lỗi: {{ .Error }}</code>." | "restartFailed" = "❗ Lỗi trong quá trình hoạt động.\r\n\r\n<code>Lỗi: {{ .Error }}</code>." | ||||||
| "xrayNotRunning" = "❗ Xray Core không chạy." | "xrayNotRunning" = "❗ Xray Core không chạy." | ||||||
|  |  | ||||||
|  | @ -518,9 +518,9 @@ | ||||||
| "status" = "✅ 机器人正常运行!" | "status" = "✅ 机器人正常运行!" | ||||||
| "usage" = "❗ 请输入要搜索的文本!" | "usage" = "❗ 请输入要搜索的文本!" | ||||||
| "getID" = "🆔 您的 ID 为:<code>{{ .ID }}</code>" | "getID" = "🆔 您的 ID 为:<code>{{ .ID }}</code>" | ||||||
| "helpAdminCommands" = "要重新启动 Xray Core:\r\n<code>/restart force</code>\r\n\r\n要搜索客户电子邮件:\r\n<code>/usage [电子邮件]</code>\r\n\r\n要搜索入站(带有客户统计数据):\r\n<code>/inbound [备注]</code>\r\n\r\nTelegram聊天ID:\r\n<code>/id</code>" | "helpAdminCommands" = "要重新启动 Xray Core:\r\n<code>/restart</code>\r\n\r\n要搜索客户电子邮件:\r\n<code>/usage [电子邮件]</code>\r\n\r\n要搜索入站(带有客户统计数据):\r\n<code>/inbound [备注]</code>\r\n\r\nTelegram聊天ID:\r\n<code>/id</code>" | ||||||
| "helpClientCommands" = "要搜索统计数据,请使用以下命令:\r\n<code>/usage [电子邮件]</code>\r\n\r\nTelegram聊天ID:\r\n<code>/id</code>" | "helpClientCommands" = "要搜索统计数据,请使用以下命令:\r\n<code>/usage [电子邮件]</code>\r\n\r\nTelegram聊天ID:\r\n<code>/id</code>" | ||||||
| "restartUsage" = "\r\n\r\n<code>/restart force</code>" | "restartUsage" = "\r\n\r\n<code>/restart</code>" | ||||||
| "restartSuccess" = "✅ 操作成功!" | "restartSuccess" = "✅ 操作成功!" | ||||||
| "restartFailed" = "❗ 操作错误。\r\n\r\n<code>错误: {{ .Error }}</code>." | "restartFailed" = "❗ 操作错误。\r\n\r\n<code>错误: {{ .Error }}</code>." | ||||||
| "xrayNotRunning" = "❗ Xray Core 未运行。" | "xrayNotRunning" = "❗ Xray Core 未运行。" | ||||||
|  |  | ||||||
|  | @ -518,9 +518,9 @@ | ||||||
| "status" = "✅ 機器人正常執行!" | "status" = "✅ 機器人正常執行!" | ||||||
| "usage" = "❗ 請輸入要搜尋的文字!" | "usage" = "❗ 請輸入要搜尋的文字!" | ||||||
| "getID" = "🆔 您的 ID 為:<code>{{ .ID }}</code>" | "getID" = "🆔 您的 ID 為:<code>{{ .ID }}</code>" | ||||||
| "helpAdminCommands" = "要重新啟動 Xray Core:\r\n<code>/restart force</code>\r\n\r\n要搜尋客戶電子郵件:\r\n<code>/usage [電子郵件]</code>\r\n\r\n要搜尋入站(帶有客戶統計資料):\r\n<code>/inbound [備註]</code>\r\n\r\nTelegram聊天ID:\r\n<code>/id</code>" | "helpAdminCommands" = "要重新啟動 Xray Core:\r\n<code>/restart</code>\r\n\r\n要搜尋客戶電子郵件:\r\n<code>/usage [電子郵件]</code>\r\n\r\n要搜尋入站(帶有客戶統計資料):\r\n<code>/inbound [備註]</code>\r\n\r\nTelegram聊天ID:\r\n<code>/id</code>" | ||||||
| "helpClientCommands" = "要搜尋統計資料,請使用以下命令:\r\n<code>/usage [電子郵件]</code>\r\n\r\nTelegram聊天ID:\r\n<code>/id</code>" | "helpClientCommands" = "要搜尋統計資料,請使用以下命令:\r\n<code>/usage [電子郵件]</code>\r\n\r\nTelegram聊天ID:\r\n<code>/id</code>" | ||||||
| "restartUsage" = "\r\n\r\n<code>/restart force</code>" | "restartUsage" = "\r\n\r\n<code>/restart</code>" | ||||||
| "restartSuccess" = "✅ 操作成功!" | "restartSuccess" = "✅ 操作成功!" | ||||||
| "restartFailed" = "❗ 操作錯誤。\r\n\r\n<code>錯誤: {{ .Error }}</code>." | "restartFailed" = "❗ 操作錯誤。\r\n\r\n<code>錯誤: {{ .Error }}</code>." | ||||||
| "xrayNotRunning" = "❗ Xray Core 未運行。" | "xrayNotRunning" = "❗ Xray Core 未運行。" | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue