ClientQrModal.vue 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. <script setup>
  2. import { computed, ref, watch } from 'vue';
  3. import { useI18n } from 'vue-i18n';
  4. import { HttpUtil } from '@/utils';
  5. import QrPanel from '@/pages/inbounds/QrPanel.vue';
  6. const { t } = useI18n();
  7. const props = defineProps({
  8. open: { type: Boolean, default: false },
  9. client: { type: Object, default: null },
  10. subSettings: {
  11. type: Object,
  12. default: () => ({ enable: false, subURI: '', subJsonURI: '', subJsonEnable: false }),
  13. },
  14. });
  15. const emit = defineEmits(['update:open']);
  16. const links = ref([]);
  17. const loading = ref(false);
  18. const subLink = computed(() => {
  19. if (!props.client?.subId || !props.subSettings?.enable || !props.subSettings?.subURI) return '';
  20. return props.subSettings.subURI + props.client.subId;
  21. });
  22. const subJsonLink = computed(() => {
  23. if (!props.client?.subId || !props.subSettings?.enable) return '';
  24. if (!props.subSettings?.subJsonEnable || !props.subSettings?.subJsonURI) return '';
  25. return props.subSettings.subJsonURI + props.client.subId;
  26. });
  27. const activeKeys = computed(() => {
  28. const keys = [];
  29. if (subLink.value) keys.push('sub');
  30. if (subJsonLink.value) keys.push('subJson');
  31. if (links.value.length > 0) keys.push('l0');
  32. return keys;
  33. });
  34. const hasAnything = computed(
  35. () => !!subLink.value || !!subJsonLink.value || links.value.length > 0,
  36. );
  37. watch(() => props.open, async (next) => {
  38. if (!next || !props.client?.subId) {
  39. links.value = [];
  40. return;
  41. }
  42. loading.value = true;
  43. try {
  44. const msg = await HttpUtil.get(`/panel/api/clients/subLinks/${encodeURIComponent(props.client.subId)}`);
  45. links.value = msg?.success && Array.isArray(msg.obj) ? msg.obj : [];
  46. } finally {
  47. loading.value = false;
  48. }
  49. });
  50. function close() {
  51. emit('update:open', false);
  52. }
  53. </script>
  54. <template>
  55. <a-modal :open="open" :title="client ? client.email : t('qrCode')" :footer="null" :width="520" centered
  56. @cancel="close">
  57. <a-spin :spinning="loading">
  58. <div v-if="!client?.subId && !loading" class="empty">
  59. {{ t('pages.clients.noSubId') }}
  60. </div>
  61. <div v-else-if="!hasAnything && !loading" class="empty">
  62. {{ t('pages.clients.noLinks') }}
  63. </div>
  64. <a-collapse v-else :active-key="activeKeys" accordion>
  65. <a-collapse-panel v-if="subLink" key="sub" :header="t('subscription.title')">
  66. <QrPanel :value="subLink" :remark="`${client?.email || ''} — ${t('subscription.title')}`" />
  67. </a-collapse-panel>
  68. <a-collapse-panel v-if="subJsonLink" key="subJson" :header="`${t('subscription.title')} (JSON)`">
  69. <QrPanel :value="subJsonLink" :remark="`${client?.email || ''} — JSON`" />
  70. </a-collapse-panel>
  71. <a-collapse-panel v-for="(link, idx) in links" :key="`l${idx}`"
  72. :header="`${t('pages.clients.link')} ${idx + 1}`">
  73. <QrPanel :value="link" :remark="`${client?.email || ''} #${idx + 1}`" />
  74. </a-collapse-panel>
  75. </a-collapse>
  76. </a-spin>
  77. </a-modal>
  78. </template>
  79. <style scoped>
  80. .empty {
  81. padding: 24px;
  82. text-align: center;
  83. opacity: 0.6;
  84. }
  85. </style>