亚洲see少妇裸体pics,欧美日产欧美日产免费一区,亚洲综合av一区二区三区不卡,一区二区中文字幕无码成人片,一区二区三区四区高清无码

國際化和權限配置

國際化和權限配置指南

國際化配置

1. 添加新語(yǔ)言

src/locales/lang/ 目錄下添加語(yǔ)言文件:

// src/locales/lang/en_US.ts
export default {
  common: {
    confirm: 'Confirm',
    cancel: 'Cancel',
    save: 'Save',
    delete: 'Delete',
    edit: 'Edit',
    add: 'Add',
    search: 'Search',
    reset: 'Reset',
    loading: 'Loading...',
    noData: 'No Data',
    operation: 'Operation',
    status: 'Status',
    createTime: 'Create Time',
    updateTime: 'Update Time',
  },
  pages: {
    login: {
      title: 'Login',
      username: 'Username',
      password: 'Password',
      rememberMe: 'Remember me',
      forgotPassword: 'Forgot password?',
      loginButton: 'Sign In',
      registerButton: 'Sign Up',
    },
    dashboard: {
      title: 'Dashboard',
      welcome: 'Welcome back!',
      totalUsers: 'Total Users',
      totalOrders: 'Total Orders',
      totalRevenue: 'Total Revenue',
      growthRate: 'Growth Rate',
    },
    user: {
      title: 'User Management',
      list: 'User List',
      detail: 'User Detail',
      create: 'Create User',
      edit: 'Edit User',
      username: 'Username',
      email: 'Email',
      phone: 'Phone',
      role: 'Role',
      status: 'Status',
      lastLogin: 'Last Login',
    },
  },
  messages: {
    success: {
      save: 'Saved successfully',
      delete: 'Deleted successfully',
      update: 'Updated successfully',
      create: 'Created successfully',
    },
    error: {
      network: 'Network error',
      server: 'Server error',
      unauthorized: 'Unauthorized access',
      forbidden: 'Access forbidden',
      notFound: 'Resource not found',
    },
    confirm: {
      delete: 'Are you sure you want to delete this item?',
      logout: 'Are you sure you want to logout?',
    },
  },
};

2. 配置語(yǔ)言切換

編輯 src/locales/index.ts 文件:

import { createI18n } from 'vue-i18n';
import zh_CN from './lang/zh_CN';
import en_US from './lang/en_US';

const messages = {
  zh_CN,
  en_US,
};

// 獲取瀏覽器語(yǔ)言
function getBrowserLanguage() {
  const language = navigator.language.toLowerCase();
  if (language.includes('zh')) return 'zh_CN';
  if (language.includes('en')) return 'en_US';
  return 'zh_CN';
}

// 獲取存儲的語(yǔ)言或瀏覽器語(yǔ)言
function getStoredLanguage() {
  return localStorage.getItem('language') || getBrowserLanguage();
}

const i18n = createI18n({
  legacy: false,
  locale: getStoredLanguage(),
  fallbackLocale: 'zh_CN',
  messages,
  globalInjection: true,
});

export default i18n;

3. 語(yǔ)言切換組件

<!-- src/components/LanguageSwitcher.vue -->
<template>
  <t-dropdown :options="languageOptions" @click="handleLanguageChange">
    <t-button variant="text" :icon="TranslateIcon">
      {{ currentLanguageLabel }}
    </t-button>
  </t-dropdown>
</template>

<script setup lang="ts">
import { computed } from 'vue';
import { useI18n } from 'vue-i18n';
import { TranslateIcon } from 'tdesign-icons-vue-next';

const { locale, t } = useI18n();

const languageOptions = [
  { content: '簡(jiǎn)體中文', value: 'zh_CN' },
  { content: 'English', value: 'en_US' },
];

const currentLanguageLabel = computed(() => {
  const current = languageOptions.find(item => item.value === locale.value);
  return current?.content || '簡(jiǎn)體中文';
});

const handleLanguageChange = (data: any) => {
  locale.value = data.value;
  localStorage.setItem('language', data.value);
  
  // 刷新頁(yè)面以應用新語(yǔ)言
  window.location.reload();
};
</script>

4. 在組件中使用國際化

<template>
  <div class="user-form">
    <t-form :data="formData" :rules="rules">
      <t-form-item :label="$t('pages.user.username')" name="username">
        <t-input v-model="formData.username" :placeholder="$t('pages.user.username')" />
      </t-form-item>
      
      <t-form-item :label="$t('pages.user.email')" name="email">
        <t-input v-model="formData.email" :placeholder="$t('pages.user.email')" />
      </t-form-item>
      
      <t-form-item>
        <t-button theme="primary" @click="handleSubmit">
          {{ $t('common.save') }}
        </t-button>
        <t-button @click="handleCancel">
          {{ $t('common.cancel') }}
        </t-button>
      </t-form-item>
    </t-form>
  </div>
</template>

<script setup lang="ts">
import { reactive } from 'vue';
import { useI18n } from 'vue-i18n';

const { t } = useI18n();

const formData = reactive({
  username: '',
  email: '',
});

// 使用國際化的表單驗證規則
const rules = {
  username: [
    { required: true, message: t('pages.user.username') + t('common.required'), type: 'error' },
  ],
  email: [
    { required: true, message: t('pages.user.email') + t('common.required'), type: 'error' },
    { email: true, message: t('pages.user.email') + t('common.formatError'), type: 'error' },
  ],
};
</script>

權限配置

1. 權限常量定義

// src/constants/permission.ts
export const PERMISSIONS = {
  // 用戶(hù)管理
  USER_VIEW: 'user:view',
  USER_CREATE: 'user:create',
  USER_EDIT: 'user:edit',
  USER_DELETE: 'user:delete',
  
  // 角色管理
  ROLE_VIEW: 'role:view',
  ROLE_CREATE: 'role:create',
  ROLE_EDIT: 'role:edit',
  ROLE_DELETE: 'role:delete',
  
  // 系統設置
  SYSTEM_CONFIG: 'system:config',
  SYSTEM_LOG: 'system:log',
} as const;

export const ROLES = {
  ADMIN: 'admin',
  USER: 'user',
  GUEST: 'guest',
} as const;

2. 權限工具函數

// src/utils/permission.ts
import { useUserStore } from '@/store/modules/user';

/**
 * 檢查是否有指定權限
 */
export function hasPermission(permission: string | string[]): boolean {
  const userStore = useUserStore();
  const userPermissions = userStore.permissions;
  
  if (Array.isArray(permission)) {
    return permission.some(p => userPermissions.includes(p));
  }
  
  return userPermissions.includes(permission);
}

/**
 * 檢查是否有指定角色
 */
export function hasRole(role: string | string[]): boolean {
  const userStore = useUserStore();
  const userRoles = userStore.roles;
  
  if (Array.isArray(role)) {
    return role.some(r => userRoles.includes(r));
  }
  
  return userRoles.includes(role);
}

/**
 * 檢查是否有任意權限
 */
export function hasAnyPermission(permissions: string[]): boolean {
  return permissions.some(permission => hasPermission(permission));
}

/**
 * 檢查是否有所有權限
 */
export function hasAllPermissions(permissions: string[]): boolean {
  return permissions.every(permission => hasPermission(permission));
}

/**
 * 是否為管理員
 */
export function isAdmin(): boolean {
  return hasRole('admin');
}

3. 權限指令

// src/directives/permission.ts
import type { App, Directive } from 'vue';
import { hasPermission, hasRole } from '@/utils/permission';

// 權限指令
const permissionDirective: Directive = {
  mounted(el, binding) {
    const { value } = binding;
    
    if (value && !hasPermission(value)) {
      el.style.display = 'none';
    }
  },
  updated(el, binding) {
    const { value } = binding;
    
    if (value && !hasPermission(value)) {
      el.style.display = 'none';
    } else {
      el.style.display = '';
    }
  },
};

// 角色指令
const roleDirective: Directive = {
  mounted(el, binding) {
    const { value } = binding;
    
    if (value && !hasRole(value)) {
      el.style.display = 'none';
    }
  },
  updated(el, binding) {
    const { value } = binding;
    
    if (value && !hasRole(value)) {
      el.style.display = 'none';
    } else {
      el.style.display = '';
    }
  },
};

export function setupPermissionDirectives(app: App) {
  app.directive('permission', permissionDirective);
  app.directive('role', roleDirective);
}

4. 在組件中使用權限

<template>
  <div class="user-management">
    <!-- 使用權限指令 -->
    <t-button 
      v-permission="PERMISSIONS.USER_CREATE"
      theme="primary" 
      @click="handleCreate"
    >
      {{ $t('common.add') }}
    </t-button>
    
    <!-- 使用角色指令 -->
    <t-button 
      v-role="ROLES.ADMIN"
      theme="danger" 
      @click="handleDeleteAll"
    >
      批量刪除
    </t-button>
    
    <!-- 使用函數判斷 -->
    <t-button 
      v-if="hasPermission(PERMISSIONS.USER_EDIT)"
      @click="handleEdit"
    >
      {{ $t('common.edit') }}
    </t-button>
    
    <t-table :columns="columns" :data="tableData">
      <template #operation="{ row }">
        <t-button 
          v-permission="PERMISSIONS.USER_EDIT"
          size="small" 
          @click="handleEdit(row)"
        >
          編輯
        </t-button>
        <t-button 
          v-permission="PERMISSIONS.USER_DELETE"
          theme="danger" 
          size="small" 
          @click="handleDelete(row)"
        >
          刪除
        </t-button>
      </template>
    </t-table>
  </div>
</template>

<script setup lang="ts">
import { hasPermission, hasRole } from '@/utils/permission';
import { PERMISSIONS, ROLES } from '@/constants/permission';
</script>

5. 路由權限守衛

// src/permission.ts
import router from '@/router';
import { useUserStore } from '@/store';
import { hasPermission, hasRole } from '@/utils/permission';
import { MessagePlugin } from 'tdesign-vue-next';

// 白名單路由(不需要登錄)
const whiteList = ['/login', '/register', '/404', '/403'];

router.beforeEach(async (to, from, next) => {
  const userStore = useUserStore();
  
  // 檢查是否已登錄
  if (!userStore.token) {
    if (whiteList.includes(to.path)) {
      next();
    } else {
      next('/login');
    }
    return;
  }
  
  // 如果已登錄但沒(méi)有用戶(hù)信息,獲取用戶(hù)信息
  if (!userStore.userInfo) {
    try {
      await userStore.fetchUserInfo();
    } catch (error) {
      userStore.logout();
      next('/login');
      return;
    }
  }
  
  // 檢查路由權限
  if (to.meta.roles && !hasRole(to.meta.roles)) {
    MessagePlugin.error('您沒(méi)有權限訪(fǎng)問(wèn)該頁(yè)面');
    next('/403');
    return;
  }
  
  if (to.meta.permissions && !hasPermission(to.meta.permissions)) {
    MessagePlugin.error('您沒(méi)有權限訪(fǎng)問(wèn)該頁(yè)面');
    next('/403');
    return;
  }
  
  next();
});

6. 權限管理頁(yè)面示例

<!-- src/pages/system/permission.vue -->
<template>
  <div class="permission-management">
    <t-card title="權限管理">
      <template #actions>
        <t-button 
          v-permission="PERMISSIONS.ROLE_CREATE"
          theme="primary" 
          @click="handleCreateRole"
        >
          添加角色
        </t-button>
      </template>
      
      <t-table :columns="columns" :data="roleList" :loading="loading">
        <template #permissions="{ row }">
          <t-tag 
            v-for="permission in row.permissions" 
            :key="permission"
            size="small"
            style="margin-right: 4px;"
          >
            {{ getPermissionLabel(permission) }}
          </t-tag>
        </template>
        
        <template #operation="{ row }">
          <t-button 
            v-permission="PERMISSIONS.ROLE_EDIT"
            size="small" 
            @click="handleEditRole(row)"
          >
            編輯
          </t-button>
          <t-button 
            v-permission="PERMISSIONS.ROLE_DELETE"
            theme="danger" 
            size="small" 
            @click="handleDeleteRole(row)"
          >
            刪除
          </t-button>
        </template>
      </t-table>
    </t-card>
    
    <!-- 角色編輯對話(huà)框 -->
    <t-dialog 
      v-model:visible="dialogVisible" 
      :title="isEdit ? '編輯角色' : '添加角色'"
      @confirm="handleSaveRole"
    >
      <t-form :data="roleForm" :rules="rules">
        <t-form-item label="角色名稱(chēng)" name="name">
          <t-input v-model="roleForm.name" placeholder="請輸入角色名稱(chēng)" />
        </t-form-item>
        
        <t-form-item label="角色描述" name="description">
          <t-textarea v-model="roleForm.description" placeholder="請輸入角色描述" />
        </t-form-item>
        
        <t-form-item label="權限配置" name="permissions">
          <t-tree 
            v-model:checked="roleForm.permissions"
            :data="permissionTree"
            checkable
            expand-all
          />
        </t-form-item>
      </t-form>
    </t-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue';
import { PERMISSIONS } from '@/constants/permission';
import { hasPermission } from '@/utils/permission';

const loading = ref(false);
const dialogVisible = ref(false);
const isEdit = ref(false);
const roleList = ref([]);

const roleForm = reactive({
  id: '',
  name: '',
  description: '',
  permissions: [],
});

const columns = [
  { colKey: 'name', title: '角色名稱(chēng)' },
  { colKey: 'description', title: '描述' },
  { colKey: 'permissions', title: '權限', cell: 'permissions' },
  { colKey: 'operation', title: '操作', cell: 'operation' },
];

const permissionTree = [
  {
    value: 'user',
    label: '用戶(hù)管理',
    children: [
      { value: 'user:view', label: '查看用戶(hù)' },
      { value: 'user:create', label: '創(chuàng  )建用戶(hù)' },
      { value: 'user:edit', label: '編輯用戶(hù)' },
      { value: 'user:delete', label: '刪除用戶(hù)' },
    ],
  },
  {
    value: 'role',
    label: '角色管理',
    children: [
      { value: 'role:view', label: '查看角色' },
      { value: 'role:create', label: '創(chuàng  )建角色' },
      { value: 'role:edit', label: '編輯角色' },
      { value: 'role:delete', label: '刪除角色' },
    ],
  },
];

const getPermissionLabel = (permission: string) => {
  // 根據權限代碼返回中文標簽
  const permissionMap: Record<string, string> = {
    'user:view': '查看用戶(hù)',
    'user:create': '創(chuàng  )建用戶(hù)',
    'user:edit': '編輯用戶(hù)',
    'user:delete': '刪除用戶(hù)',
    // ... 更多權限映射
  };
  return permissionMap[permission] || permission;
};

const handleCreateRole = () => {
  isEdit.value = false;
  Object.assign(roleForm, {
    id: '',
    name: '',
    description: '',
    permissions: [],
  });
  dialogVisible.value = true;
};

const handleEditRole = (role: any) => {
  isEdit.value = true;
  Object.assign(roleForm, role);
  dialogVisible.value = true;
};

const handleSaveRole = async () => {
  // 保存角色邏輯
  try {
    if (isEdit.value) {
      await updateRole(roleForm);
    } else {
      await createRole(roleForm);
    }
    dialogVisible.value = false;
    fetchRoleList();
  } catch (error) {
    console.error('保存角色失敗:', error);
  }
};

const fetchRoleList = async () => {
  loading.value = true;
  try {
    roleList.value = await getRoleList();
  } catch (error) {
    console.error('獲取角色列表失敗:', error);
  } finally {
    loading.value = false;
  }
};

onMounted(() => {
  fetchRoleList();
});
</script>

這個(gè)權限配置指南涵蓋了完整的國際化和權限管理功能,包括多語(yǔ)言支持、權限檢查、路由守衛和權限管理界面等。

文章目錄

    亚洲see少妇裸体pics,欧美日产欧美日产免费一区,亚洲综合av一区二区三区不卡,一区二区中文字幕无码成人片,一区二区三区四区高清无码