GoWindGoWind
Home
Framework
GoWind Toolkit
  • Open Source

    • GoWind Admin (Admin Platform)
    • GoWind CMS (Content Management)
    • GoWind UBA (Behavior Analytics)
    • GoWind Shop (E-commerce)
    • GoWind Kanban (Kanban Boards)
    • GoWind Ledger (Personal Finance)
    • GoWind ShortPlay (Short Drama)
    • GoWind Ops (Operations Platform)
    • RushWind (Rust Ecosystem)
  • Open Core (Community + Enterprise)

    • GoWind OA (Office Collaboration)
    • GoWind ERP (Procure-to-Pay)
    • GoWind WMS (Warehousing)
  • Commercial

    • GoWind IM (Instant Messaging)
    • GoWind IoT (IoT Platform)
    • GoWind Edu (AI Education)
    • GoWind MES (Manufacturing Execution)
    • GoWind CDC (Data Pipeline)
    • GoWind SDP (Zero-Trust Gateway)
    • GoWind Quant (Quant Research)
    • GoWind Trade Radar (Export Sourcing)
    • GoWind Game Radar (Game Greenlight)
  • 简体中文
  • English
GitHub
Home
Framework
GoWind Toolkit
  • Open Source

    • GoWind Admin (Admin Platform)
    • GoWind CMS (Content Management)
    • GoWind UBA (Behavior Analytics)
    • GoWind Shop (E-commerce)
    • GoWind Kanban (Kanban Boards)
    • GoWind Ledger (Personal Finance)
    • GoWind ShortPlay (Short Drama)
    • GoWind Ops (Operations Platform)
    • RushWind (Rust Ecosystem)
  • Open Core (Community + Enterprise)

    • GoWind OA (Office Collaboration)
    • GoWind ERP (Procure-to-Pay)
    • GoWind WMS (Warehousing)
  • Commercial

    • GoWind IM (Instant Messaging)
    • GoWind IoT (IoT Platform)
    • GoWind Edu (AI Education)
    • GoWind MES (Manufacturing Execution)
    • GoWind CDC (Data Pipeline)
    • GoWind SDP (Zero-Trust Gateway)
    • GoWind Quant (Quant Research)
    • GoWind Trade Radar (Export Sourcing)
    • GoWind Game Radar (Game Greenlight)
  • 简体中文
  • English
GitHub
  • Introduction

    • GoWind CMS Product Introduction
    • GoWind CMS Installation Guide
  • Backend

    • CMS Backend Architecture Overview
    • CMS Backend Modules Overview
    • CMS Protobuf API Definitions
    • CMS Configuration and Deployment Guide
    • Backend Extension Mechanisms Guide
  • Frontend

    • CMS Frontend Architecture
    • CMS Frontend Modules Overview
  • Getting Started

    • Adding a Content Type, Full Stack in Practice
    • Multi-Client API Client Code Generation Tutorial
  • Core Tutorials

    • Content Multilingual Translation Tutorial
    • Content Publishing Workflow Tutorial
    • Section Editor in Practice
    • Headless API Multi-Client Integration in Practice
    • Frontend Application Development in Practice
  • Intermediate Tutorials

    • Multi-Site Management in Practice
    • Media Asset Management in Practice
    • Comment System Tutorial
    • Event Bus Architecture in Practice
    • Lua Script Extensions in Practice
  • Advanced Topics

    • Permission System in Practice
    • Dual-Client Login Security in Practice
    • Encryption and Security Toolkit Tutorial
    • Full-Text Search in Practice
    • Task Scheduling in Practice
    • Real-Time Message Push (SSE) in Practice
    • Performance Monitoring in Practice
    • Dictionary Management System Tutorial
  • Full-Stack Guides

    • Full-Stack Integration in Practice
    • Three-Service Deployment Tutorial

Dictionary Management System Tutorial

GoWind CMS ships with complete data dictionary management, supporting hierarchical management of dictionary types and entries, usable for unified maintenance of enumerations such as content statuses, post types, and priorities. This tutorial explains the architecture and usage of the dictionary system.

Prerequisites

  • Have read CMS Backend Architecture Overview

1. Dictionary System Architecture

1.1 What Is a Data Dictionary

A data dictionary manages enumeration values and constant configurations in the system, avoiding hard-coding in code:

1.2 Dictionary vs Enum

AspectEnumData Dictionary
Defined inCodeDatabase
Change costRequires compilationRuntime
i18nHard-codedSupports translation
OrderingFixedAdjustable
ExtensionRequires code changesAdded directly in the admin console

2. Data Model

2.1 DictType (Dictionary Type)

// dict/service/v1/dict_type.proto
message DictType {
  optional uint32 id = 1;
  optional string name = 2 [json_name = "name"];         // Dictionary name
  optional string code = 3 [json_name = "code"];         // Dictionary code (unique)
  optional string description = 4 [json_name = "description"];
  optional Status status = 5;
  enum Status {
    DICT_TYPE_STATUS_ACTIVE = 0;
    DICT_TYPE_STATUS_INACTIVE = 1;
  }
  optional google.protobuf.Timestamp created_at = 100;
}

2.2 DictEntry (Dictionary Entry)

// dict/service/v1/dict_entry.proto
message DictEntry {
  optional uint32 id = 1;
  optional uint32 dict_type_id = 2 [json_name = "dictTypeId"];
  optional string label = 3;           // Display name
  optional string value = 4;           // Dictionary value
  optional uint32 sort = 5;            // Sort order
  optional string css_class = 6 [json_name = "cssClass"]; // CSS style
  optional bool is_default = 7 [json_name = "isDefault"]; // Whether it is the default value
  optional Status status = 8;
  repeated DictEntryI18n i18n = 20 [json_name = "i18n"];  // i18n
}

// Dictionary entry i18n
message DictEntryI18n {
  optional uint32 id = 1;
  optional uint32 dict_entry_id = 2 [json_name = "dictEntryId"];
  optional string language_code = 3 [json_name = "languageCode"];
  optional string label = 4;           // Translated display name
}

3. Admin API

3.1 Dictionary Type Endpoints

# Get the dictionary type list
GET /admin/v1/dict-types?page=1&pageSize=20

# Create a dictionary type
POST /admin/v1/dict-types
{
  "name": "Post Status",
  "code": "post_status",
  "description": "Post publishing status"
}

# Update
PUT /admin/v1/dict-types/1

# Delete
DELETE /admin/v1/dict-types/1

3.2 Dictionary Entry Endpoints

# Get the entry list (filtered by type)
GET /admin/v1/dict-entries?dictTypeId=1

# Create an entry
POST /admin/v1/dict-entries
{
  "dictTypeId": 1,
  "label": "Pending Review",
  "value": "3",
  "sort": 1,
  "isDefault": false,
  "i18n": [
    { "languageCode": "zh-CN", "label": "待审核" },
    { "languageCode": "en-US", "label": "Pending Review" }
  ]
}

4. Common CMS Dictionaries

Dictionary CodeDescriptionEntry Examples
post_statusPost statusDraft/Pending Review/Published/Offline
comment_statusComment statusPending/Approved/Rejected
media_typeMedia typeImage/Video/Audio/Document
site_themeSite themeLight/Dark/Minimal/Magazine
nav_typeNavigation typeTop navigation/Footer/Sidebar
priorityPriorityHigh/Medium/Low

5. Admin Console

5.1 Dictionary Management Page

<!-- views/system/dict/index.vue -->
<script setup lang="ts">
const activeTab = ref('types');
const selectedType = ref(null);
</script>

<template>
  <Page title="Dictionary Management">
    <Tabs v-model:activeKey="activeTab">
      <!-- Dictionary type management -->
      <TabPane key="types" tab="Dictionary Types">
        <Table :data="dictTypes">
          <TableColumn title="Name" data-index="name" />
          <TableColumn title="Code" data-index="code" />
          <TableColumn title="Description" data-index="description" />
          <TableColumn title="Actions">
            <template #default="{ record }">
              <Button @click="selectedType = record; activeTab = 'entries'">Manage Entries</Button>
            </template>
          </TableColumn>
        </Table>
      </TabPane>

      <!-- Dictionary entry management -->
      <TabPane key="entries" tab="Dictionary Entries" :disabled="!selectedType">
        <DictEntryManager :dict-type="selectedType" />
      </TabPane>
    </Tabs>
  </Page>
</template>

5.2 Using Dictionaries in the Frontend

// Composable: fetch a dictionary
export function useDict(code: string, locale?: string) {
  return useQuery({
    queryKey: ['dict', code, locale],
    queryFn: () => apiClient.dictService.GetByCode({ code, locale }),
    staleTime: 5 * 60 * 1000, // 5-minute cache
  });
}

// Usage in a component
const { data: postStatusDict } = useDict('post_status', 'zh-CN');
// postStatusDict.items = [{ label: 'Draft', value: '0' }, ...]

6. Cache Optimization

// Dictionary data changes infrequently; use Redis caching
func (s *DictService) GetByCode(ctx context.Context, code string) ([]*dictV1.DictEntry, error) {
    cacheKey := fmt.Sprintf("dict:%s", code)

    // Try the cache first
    if cached, err := s.redis.Get(ctx, cacheKey).Result(); err == nil {
        var entries []*dictV1.DictEntry
        json.Unmarshal([]byte(cached), &entries)
        return entries, nil
    }

    // Query the database
    entries, err := s.dictRepo.GetByCode(ctx, code)
    if err != nil {
        return nil, err
    }

    // Write to the cache
    data, _ := json.Marshal(entries)
    s.redis.Set(ctx, cacheKey, data, 30*time.Minute)

    return entries, nil
}

// Clear the cache when a dictionary is updated
func (s *DictService) UpdateEntry(ctx context.Context, req *dictV1.UpdateDictEntryRequest) error {
    if err := s.dictRepo.UpdateEntry(ctx, req); err != nil {
        return err
    }
    s.redis.Del(ctx, fmt.Sprintf("dict:%s", req.DictTypeCode))
    return nil
}

7. Checklist

ItemDescription
DictType schemaDictionary types
DictEntry schemaDictionary entries + i18n
Admin APIType + entry CRUD
Admin pageType management + entry management
Dictionary usageuseDict composable
CachingRedis cache

Related Documentation

  • CMS Backend Architecture Overview
  • CMS Backend Modules Overview
  • Content Multilingual Translation in Practice
Edit this page
Last Updated:: 11/3/26, 2:14 PM
Contributors: Bobo
Prev
Performance Monitoring in Practice