在上篇隨筆《基于Admin.NET框架的前端的一些改進和代碼生成處理(1)》中大致介紹了一些關于對Admin.NET框架的前端的改造作業,主要目的就是希望能夠增加前端代碼的簡潔性和可讀性,以及利用代碼生成工具來快速生成相關的代碼,從而減少開發程序中的繁瑣問題,本篇隨筆繼續探討一下,對其中一些模塊功能進行一些修改調整,涉及前后端的一起修改調整,
Admin.NET框架的后端基于基于Furion/.NET 6實作,底層集成SqlSugar;前端則是采用Vue-Next-Admin的前端框架,整體是一套非常不錯的框架,
1、增加批量添加字典專案
Admin.NET框架的字典管理專案界面如下所示,

它通過列出字典大類,然后在右邊入口進行字典專案的管理,以前我傾向于使用左右視圖分拆的方式,從而實作字典大類和字典專案的快捷管理,
如在隨筆《在Vue&Element前端專案中,對于字典串列的顯示處理 》中介紹到的字典綜合展示方式如下所示,

我們這里暫且不修改這個頁面,繼續查看其字典專案管理的界面如下所示,

其串列里面只有一個新增的操作,如果對于初始化字典,則是一份苦差事,反復的打開錄入是比較費時間的,我們可以使用慣用的方式,來批量錄入字典專案,來提高字典專案初始化處理的效率,
我們在原有界面上增加一個批量錄入,和批量洗掉的操作,如下界面所示,

批量新增字典專案的界面,如下所示,

如果字典值和編碼內容不一致,可以使用如下效果進行批量新增

批量添加字典專案的頁面,我們是作為一個組件頁面的方式添加,然后在頁面中應用組件即可,如下代碼所示,

對應的批量添加頁面里面,提交的時候,呼叫對應的API介面就可以了,如下代碼所示,
// 保存資料處理 async function submitData() { var formEl = editRef.value; if (!formEl) return; await formEl.validate(async (valid) => { if (valid) { //驗證成功,執行下面方法 var result = await dictdata.BatchAdd(editForm); //編輯保存 if (result) { $u.message.success('批量添加字典成功!'); // 提示資訊 emit('submit'); // 提示重繪資料 closeDialog(); // 重置視窗狀態 } else { $u.message.error('批量添加失敗'); } } }); }
對應的業務API類里面,定義對應的介面函式,
/** * 系統字典值表 管理Api */ class SysDictDataApi extends BaseApi<SysDictData, AddDictDataInput, UpdateDictDataInput> { ............ /** 批量添加字典專案 */ BatchAdd = async (data: object) => { const url = this.baseUrl + `/BatchAdd`; return await this.axiosInstance.post<UnifyResult<void>>(url, data) } } export default new SysDictDataApi('/api/sysDictData');
后端增加對應的處理介面,實作資料的批量添加即可,

至此,批量添加字典專案的操作,配合前端后端一起,就可以完成該操作了,

2、顯示/隱藏開發測驗選單
在Vue-Next-Admin的前端框架演示專案里面,本身提供了很多Demo案例的頁面展示,不過Admin.NET應該為了簡化框架的效果,從而把這些演示的案例選單移除了,不過視圖檔案依舊保存在專案里面,我們開發測驗程序中,有時候需要參考這些頁面效果,以便了解一些插件的功能和特點,因此可能偶爾需要使用了解下的,而在部署的時候,肯定是需要隱藏起來,不讓客戶使用這些Demo,否則增加煩惱,
為了更好的管控這些演示選單連接的入口,我們在原有選單的表里面增加一個Tag標簽,用來標識相關的選單功能,例如我們把測驗頁面的Tag標注為 dev, 而選單表里面本身有是否隱藏和是否啟用的設定,隱藏相對于選單而已不顯示(但包含路由),是否啟用相對于路由而言(禁用也就無法訪問選單的路由了),
我們通過這些設定資訊,可以對特定的標簽,啟用或者禁用,從而實作我們對開發測驗的選單頁面的顯示和隱藏操作,

這個修改處理,必須結合后端進行相關資料表結構調整,以及相關的代碼屬性調整,在資料庫增加一個Tag屬性欄位,然后修改物體物件定義,
/// <summary> /// 系統選單表 /// </summary> [SugarTable(null, "系統選單表")] [SystemTable] public class SysMenu : EntityBase { .................... /// <summary> /// 標簽 /// </summary> [SugarColumn(ColumnDescription = "標簽", Length = 256)] [MaxLength(256)] public string? Tag { get; set; } }
以及在相關的Dto物件上增加相關的屬性,
public class MenuInput { /// <summary> /// 標題 /// </summary> public string Title { get; set; } /// <summary> /// 標簽 /// </summary> public string? Tag { get; set; } /// <summary> /// 選單型別(1目錄 2選單 3按鈕) /// </summary> public MenuTypeEnum? Type { get; set; } }
為了隱藏或者顯示選單,我們需要在后端增加一個介面函式,介面函式會通過代理注入的方式提供相關的控制器介面入口,從而給前端訪問處理的,
/// <summary> /// 隱藏/啟用開發測驗頁面選單(對標記tag為dev的,進行隱藏或者啟用) /// </summary> /// <returns></returns> [DisplayName("隱藏/啟用開發測驗頁面選單")] public async Task HideOrShowDevMenu() { var tagFlag = "dev"; var hideState = await _sysMenuRep.IsAnyAsync(u => u.Tag == tagFlag && u.IsHide); var newHide = !hideState; var newState = hideState ? StatusEnum.Enable : StatusEnum.Disable; //更新特定欄位(同時隱藏和禁用) await _sysMenuRep.UpdateAsync( u => new SysMenu { IsHide = newHide, Status = newState }, u => u.Tag == tagFlag); }
我們通過判斷當前記錄的隱藏狀態和啟用狀態,從而給他一個反轉值,然后根據條件更新相關的記錄即可,
前端開發的時候,我們除了也是相應增加對應的Tag屬性,也需要配合后端,手工添加一個對應的方法呼叫,如下代碼所示,
import { BaseApi } from './base-api';
import { SysMenu, UpdateMenuInput, AddMenuInput, MenuOutput } from '/@/api/models';
/** 選單管理Api */
class SysMenuApi extends BaseApi<SysMenu, AddMenuInput, UpdateMenuInput> {
/**隱藏/啟用開發測驗頁面選單(對標記tag為dev的,進行隱藏或者啟用) */
HideOrShowDevMenu = async () => {
const url = this.baseUrl + `/HideOrShowDevMenu`;
return await this.axiosInstance.post<UnifyResult<void>>(url, null)
}
}
export default new SysMenuApi('/api/sysMenu');
這里只需要注意前端的呼叫api路徑,以及回傳結果即可,
根據Vue-Next-Admin的前端的測驗選單的頁面資訊,我們添加了相關的測驗案例選單,并給它們統一打上dev的標簽,添加后的選單串列界面如下所示,

然后在界面上增加一個操作入口,如下所示,

來操作測驗案例選單的啟用或者禁用處理即可,
const hideOrShowDevMenu = () => { var tips = '您確認要隱藏/啟用開發測驗頁面?'; //(對記錄標記tag為dev的,進行隱藏或者啟用) $u.message.confirm(tips).then(async () => { await menuApi.HideOrShowDevMenu(); $u.message.success('操作成功,請重繪選單頁面,查看變化,'); setTimeout(() => { window.location.reload(); }, 1000); }); }
其中 $u.message 是我們注入的一個全域物件的呼叫方式,具體操作方式,請參考隨筆《在基于vue-next-admin的Vue3+TypeScript前端專案中,為了使用方便全域掛載物件介面》進行了解,
這樣顯示/禁用測驗案例的選單,就可以正常的隨意處理了,

3、檔案管理增加分組ID
Admin.NET框架的檔案表結構如下所示,

我在以前使用檔案的時候,傾向于添加一個附件組,這樣在實際業務處理的時候,不用記錄多個附件ID的記錄,只需要參考一個附件組的ID即可,因此我也希望保留這個方式來系結多個附件的展示處理,
因此在原有表的基礎上增加一個GroupId的欄位,如下所示,

調整前后端的代碼,讓它和其他欄位一樣能夠生效,
例如后端進行分頁查詢的時候,我們增加對分組ID的判別,如下代碼所示,
/// <summary> /// 獲取檔案分頁串列 /// </summary> /// <param name="input"></param> /// <returns></returns> [DisplayName("獲取檔案分頁串列")] public async Task<SqlSugarPagedList<SysFile>> GetPage([FromQuery] PageFileInput input) { return await _sysFileRep.AsQueryable() .WhereIF(!string.IsNullOrWhiteSpace(input.FileName), u => u.FileName.Contains(input.FileName.Trim())) //增加分組ID查詢 .WhereIF(!string.IsNullOrWhiteSpace(input.GroupId), u => u.GroupId.Equals(input.GroupId.Trim(), StringComparison.OrdinalIgnoreCase)) .WhereIF(!string.IsNullOrWhiteSpace(input.StartTime.ToString()) && !string.IsNullOrWhiteSpace(input.EndTime.ToString()), u => u.CreateTime >= input.StartTime && u.CreateTime <= input.EndTime) .OrderBy(u => u.CreateTime, OrderByType.Desc) .ToPagedListAsync(input.Page, input.PageSize); }
另外我們增加一個根據分組ID進行查詢串列的操作,便于我們在前端根據分組獲得對應的檔案串列,
/// <summary> /// 獲取指定附件組GUID的附件串列 /// </summary> /// <param name="groupId">附件組GUID</param> /// <returns></returns> [DisplayName("獲取指定附件組GUID的附件串列")] public async Task<List<SysFile>> GetFilesByGroupId(string groupId) { var list = new List<SysFile>(); if(!string.IsNullOrWhiteSpace(groupId)) { list = await _sysFileRep.GetListAsync(u => u.GroupId == groupId); } return list; }
其他地方進行適當的調整,以便能夠使得分組ID真正的好用,便利即可,
在前端代碼里面,我們增加對應分組ID查詢檔案的介面,如下代碼所示,
import { BaseNormal } from './base-api';
import { FileInput, FileOutput, SysFile } from '/@/api/models';
/**
* 系統檔案 管理Api
*/
class SysFileApi extends BaseNormal {
.............
/**獲取指定附件組ID的附件串列 */
GetFilesByGroupId = async (groupId: string) => {
const url = this.baseUrl + `/FilesByGroupId/${groupId}`;
return await this.axiosInstance.get<UnifyResult<Array<SysFile>>>(url, { params: null })
}
}
export default new SysFileApi('/api/sysFile');
在查看附件或者上傳附件的時候,我們指定對應的groupId就可以了,由于為了方便展示附件串列,我們通過自定義組件的方式,系結它的分組ID進行處理,
<div> <my-upload v-model="attachGroupId" :data="{ groupId: attachGroupId, path: '' }" :is-avatar-upload="false" :show-file-list="true" :is-show-tip="true" /> </div> <div> <my-attachment v-model="attachGroupId"></my-attachment> </div>
例如附件串列,我們在請求資料的時候,如下代碼所示,
getData() { // console.log(this.modelValue); if (!isEmpty(this.modelValue)) { fileApi.GetFilesByGroupId(this.modelValue).then(data =https://www.cnblogs.com/wuhuacong/archive/2023/03/29/> { this.attachFiles = data.data.result!; // 生成并添加預覽圖片串列 this.imageList = []; this.attachFiles.map(item => { if (item.url && this.isImage(item)) { this.imageList.push(item.url!); } }); }); }
附件串列的界面效果如下所示,可以通過系結GroupId的方式,展示多個附件串列了,

如果需要上傳,那么使用封裝的上傳附件的控制元件展示,并系結對應的GroupId就可以展示多個檔案串列了

專注于代碼生成工具、.Net/.NetCore 框架架構及軟體開發,以及各種Vue.js的前端技術應用,著有Winform開發框架/混合式開發框架、微信開發框架、Bootstrap開發框架、ABP開發框架、SqlSugar開發框架等框架產品, 轉載請注明出處:撰寫人:伍華聰 http://www.iqidi.com
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/548648.html
標籤:其他
上一篇:前端設計模式——依賴注入模式
