Web API应用架构在Winform混合框架中的应用(5)--系统级别字典和公司级别字典并存的处理方式

简介:

在我这个系列中,我主要以我正在开发的云会员管理系统为例进行介绍Web API的应用,由于云会员的数据设计是支持多个商家公司,而每个公司又可以包含多个店铺的,因此一些字典型的数据需要考虑这方面的不同。如对于证件类型,收费处理状态,民族,职称等这些固定化的内容,我们可以放到全局字典里面,但是对于一些如会员相关的字典数据,如产品单位、产品类型等内容,如果也全部规定为全局的系统字典,那么就缺乏灵活性,这些数据应该可以由各自进行差异化处理。

1、云会员系统的字典数据模型

我们先来了解下基于Web API接口的云会员管理系统的总体界面效果。

由于一般的云会员系统,都是允许用户注册一个公司,然后公司层面开设多个商铺的,如系统的登陆界面如下所示。

因此数据的范围需要考虑的更广,他们的关系如下所示。

而我们原先设计的字典模型如下所示。

而在公司数据这个层次上,我们需要考虑公司层级的数据字典存储,但是我们进一步分析可以看到,虽然数据字典数据是公司层级的,但是数据字典的类型(如证件类型、产品类型等)这些是固定不变的,也就是我们如果存储公司层级的字典数据,那么也只是需要存储对应的字典项目即可。因此我们可以增加多一个和TB_DictData的数据表类似的表进行存储即可,它的数据设计如下所示。

为了方便在系统里面使用同一的字典项目内容,我们创建一了一个统一的字典项目管理模块,也就是系统字典管理界面,如下所示。

2、公司层级的字典数据存储实现

有了上面的设计模型,相信大多数人员都可以想到它的具体实现思路了。

首先我们需要以系统字典数据为参考,如默认就是取系统的字典项目数据,如果公司级别的用户修改或者删除了字典数据内容,那么对应的字典类别的字典项目就应该以修改的为准了。

但是我们不可能为新建公司账户的时候,都为每个公司自动创建一份对应类型的字典数据,那样稍显麻烦,而且一开始就创建也比较麻烦。

先建立一个公司字典的数据管理界面,它和字典数据管理界面一样,不过是存储在另外一个表里面,自动根据当前用户的公司标识进行存储的。

批量添加公司字典的数据如下所示。

一般我们在使用公司层级的字典数据或者系统公共层级的字典数据的时候,都是根据字典类型进行判断的。

因此在公司层级根据字典项目类型获取数据的时候,我们在业务接口底层做了判断,判断如果对应公司的字典项没有数据,则复制一份过去,如果公司层次有对应的数据类型,那么就获取公司层级的字典项目数据即可。

具体的代码逻辑如下所示。

        /// <summary>
        /// 根据字典类型名称获取所有该类型的字典列表集合
        /// </summary>
        /// <param name="dictType">字典类型名称</param>
        /// <param name="corpId">公司ID</param>
        /// <returns></returns>
        public List<CorpDictDataInfo> FindByDictType(string dictTypeName, string corpId)
        {
            ICorpDictData dal = baseDal as ICorpDictData;
            List<CorpDictDataInfo> list = dal.FindByDictType(dictTypeName, corpId);

            //如果公司字典没有数据,则从系统字典获取
            if (list.Count == 0)
            {
                List<DictDataInfo> dict = BLLFactory<DictData>.Instance.FindByDictType(dictTypeName);
                foreach (DictDataInfo info in dict)
                {
                    list.Add(new CorpDictDataInfo(info, corpId));                    
                }

                //写入公司字典表,避免下次再去获取
                foreach (CorpDictDataInfo info in list)
                {
                    baseDal.Insert(info);
                }
            }
            return list;
        }

在Web API的控制器接口,还是和其他的处理一样,增加对应的参数处理即可。

        /// <summary>
        /// 根据字典类型名称获取所有该类型的字典列表集合
        /// </summary>
        /// <param name="dictType">字典类型名称</param>
        /// <param name="corpId">公司ID</param>
        /// <returns></returns>
        [HttpGet]
        public List<CorpDictDataInfo> FindByDictType(string dictTypeName, string corpId, string token)
        {          
            //令牌检查,不通过则抛出异常
            CheckResult checkResult = CheckToken(token);

            return BLLFactory<CorpDictData>.Instance.FindByDictType(dictTypeName, corpId);
        }

在Facade层定义字典的对应接口的时候,我们的代码如下所示

        /// <summary>
        /// 根据字典类型名称获取所有该类型的字典列表集合
        /// </summary>
        /// <param name="dictType">字典类型名称</param>
        /// <param name="corpId">公司ID</param>
        /// <returns></returns>
        [OperationContract]
        List<CorpDictDataInfo> FindByDictType(string dictTypeName, string corpId);

在基于Web API的封装调用接口,我们的调用封装类如下所示。其中token以及Web API的相关参数处理,在基类模块进行了封装,减少了很多代码的拼接。

     /// </summary>
        /// <param name="dictType">字典类型名称</param>
        /// <param name="corpId">公司ID</param>
        /// <returns></returns>
        public List<CorpDictDataInfo> FindByDictType(string dictTypeName, string corpId)
        {
            var action = "FindByDictType";
            string url = GetTokenUrl(action) + string.Format("&dictTypeName={0}&corpId={1}", dictTypeName, corpId);

            List<CorpDictDataInfo> result = JsonHelper<List<CorpDictDataInfo>>.ConvertJson(url);
            return result;
        }

然后我们在界面上的字典项目下拉列表,则可以通过扩展函数的方式进行绑定。

        /// <summary>
        /// 初始化字典列表内容
        /// </summary>
        private void InitDictItem()
        {
            //初始化代码
            this.txtProductType.BindDictItemsByCorp("会员产品类型", LoginUserInfo.CompanyId);
        }
        /// <summary>
        /// 绑定下拉列表控件为指定的数据字典列表[如果公司字典记录不存在,则使用系统字典记录,否则使用公司记录]
        /// </summary>
        /// <param name="combo">下拉列表控件</param>
        /// <param name="dictTypeName">数据字典类型名称</param>
        public static void BindDictItemsByCorp(this ComboBoxEdit combo, string dictTypeName, string corpId)
        {
            BindDictItemsByCorp(combo, dictTypeName, corpId, null);
        }

        /// <summary>
        /// 绑定下拉列表控件为指定的数据字典列表[如果公司字典记录不存在,则使用系统字典记录,否则使用公司记录]
        /// </summary>
        /// <param name="combo">下拉列表控件</param>
        /// <param name="dictTypeName">数据字典类型名称</param>
        /// <param name="defaultValue">控件默认值</param>
        public static void BindDictItemsByCorp(this ComboBoxEdit combo, string dictTypeName, string corpId, string defaultValue)
        {
            Dictionary<string, string> dict = CallerFactory<ICorpDictDataService>.Instance.GetDictByDictType(dictTypeName, corpId);
            List<CListItem> itemList = new List<CListItem>();
            foreach (string key in dict.Keys)
            {
                itemList.Add(new CListItem(key, dict[key]));
            }

            BindDictItems(combo, itemList, defaultValue);
        }

以上就是一个整体性的思路,并在系统中能够顺利解决问题的做法,希望大家可以借鉴。

系列文章如下所示:

Web API应用架构在Winform混合框架中的应用(1)

Web API应用架构在Winform混合框架中的应用(2)--自定义异常结果的处理

Web API接口设计经验总结 

Web API应用架构在Winform混合框架中的应用(3)--Winfrom界面调用WebAPI的过程分解

Web API应用架构在Winform混合框架中的应用(4)--利用代码生成工具快速开发整套应用

Web API应用架构在Winform混合框架中的应用(5)--系统级别字典和公司级别字典并存的处理方式

本文转自博客园伍华聪的博客,原文链接:Web API应用架构在Winform混合框架中的应用(5)--系统级别字典和公司级别字典并存的处理方式,如需转载请自行联系原博主。



目录
相关文章
|
4月前
|
数据采集 机器学习/深度学习 运维
量化合约系统开发架构入门
量化合约系统核心在于数据、策略、风控与执行四大模块的协同,构建从数据到决策再到执行的闭环工作流。强调可追溯、可复现与可观测性,避免常见误区如重回测轻验证、忽视数据质量或滞后风控。初学者应以MVP为起点,结合回测框架与实时风控实践,逐步迭代。详见相关入门与实战资料。
|
4月前
|
前端开发 JavaScript BI
如何开发车辆管理系统中的车务管理板块(附架构图+流程图+代码参考)
本文介绍了中小企业如何通过车务管理模块提升车辆管理效率。许多企业在管理车辆时仍依赖人工流程,导致违章处理延误、年检过期、维修费用虚高等问题频发。将这些流程数字化,可显著降低合规风险、提升维修追溯性、优化调度与资产利用率。文章详细介绍了车务管理模块的功能清单、数据模型、系统架构、API与前端设计、开发技巧与落地建议,以及实现效果与验收标准。同时提供了数据库建表SQL、后端Node.js/TypeScript代码示例与前端React表单设计参考,帮助企业快速搭建并上线系统,实现合规与成本控制的双重优化。
|
4月前
|
人工智能 自然语言处理 安全
AI助教系统:基于大模型与智能体架构的新一代教育技术引擎
AI助教系统融合大语言模型、教育知识图谱、多模态交互与智能体架构,实现精准学情诊断、个性化辅导与主动教学。支持图文语音输入,本地化部署保障隐私,重构“教、学、评、辅”全链路,推动因材施教落地,助力教育数字化转型。(238字)
793 23
|
4月前
|
人工智能 JavaScript 前端开发
GenSX (不一样的AI应用框架)架构学习指南
GenSX 是一个基于 TypeScript 的函数式 AI 工作流框架,以“函数组合替代图编排”为核心理念。它通过纯函数组件、自动追踪与断点恢复等特性,让开发者用自然代码构建可追溯、易测试的 LLM 应用。支持多模型集成与插件化扩展,兼具灵活性与工程化优势。
350 6
|
4月前
|
存储 监控 安全
132_API部署:FastAPI与现代安全架构深度解析与LLM服务化最佳实践
在大语言模型(LLM)部署的最后一公里,API接口的设计与安全性直接决定了模型服务的可用性、稳定性与用户信任度。随着2025年LLM应用的爆炸式增长,如何构建高性能、高安全性的REST API成为开发者面临的核心挑战。FastAPI作为Python生态中最受青睐的Web框架之一,凭借其卓越的性能、强大的类型安全支持和完善的文档生成能力,已成为LLM服务化部署的首选方案。
|
4月前
|
存储 人工智能 搜索推荐
拔俗AI助教系统:基于大模型与智能体架构的新一代教育技术引擎
AI助教融合大语言模型、教育知识图谱、多模态感知与智能体技术,重构“教、学、评、辅”全链路。通过微调LLM、精准诊断错因、多模态交互与自主任务规划,实现个性化教学。轻量化部署与隐私保护设计保障落地安全,未来将向情感感知与教育深度协同演进。(238字)
463 0
|
4月前
|
机器学习/深度学习 人工智能 搜索推荐
拔俗AI学伴智能体系统:基于大模型与智能体架构的下一代个性化学习引擎
AI学伴智能体系统融合大模型、多模态理解与自主决策,打造具备思考能力的个性化学习伙伴。通过动态推理、长期记忆、任务规划与教学逻辑优化,实现千人千面的自适应教育,助力因材施教落地,推动教育公平与效率双提升。(238字)
616 0
|
4月前
|
机器学习/深度学习 自然语言处理 算法
48_动态架构模型:NAS在LLM中的应用
大型语言模型(LLM)在自然语言处理领域的突破性进展,很大程度上归功于其庞大的参数量和复杂的网络架构。然而,随着模型规模的不断增长,计算资源消耗、推理延迟和部署成本等问题日益凸显。如何在保持模型性能的同时,优化模型架构以提高效率,成为2025年大模型研究的核心方向之一。神经架构搜索(Neural Architecture Search, NAS)作为一种自动化的网络设计方法,正在为这一挑战提供创新性解决方案。本文将深入探讨NAS技术如何应用于LLM的架构优化,特别是在层数与维度调整方面的最新进展,并通过代码实现展示简单的NAS实验。
|
4月前
|
算法 Java Go
【GoGin】(1)上手Go Gin 基于Go语言开发的Web框架,本文介绍了各种路由的配置信息;包含各场景下请求参数的基本传入接收
gin 框架中采用的路优酷是基于httprouter做的是一个高性能的 HTTP 请求路由器,适用于 Go 语言。它的设计目标是提供高效的路由匹配和低内存占用,特别适合需要高性能和简单路由的应用场景。
385 4
|
8月前
|
缓存 JavaScript 前端开发
鸿蒙5开发宝藏案例分享---Web开发优化案例分享
本文深入解读鸿蒙官方文档中的 `ArkWeb` 性能优化技巧,从预启动进程到预渲染,涵盖预下载、预连接、预取POST等八大优化策略。通过代码示例详解如何提升Web页面加载速度,助你打造流畅的HarmonyOS应用体验。内容实用,按需选用,让H5页面快到飞起!