소스 검색

🍀增加代码预览功能

KaneLeung 1 년 전
부모
커밋
45302cc4bc

+ 61 - 27
Admin.NET/Admin.NET.Core/Service/CodeGen/SysCodeGenService.cs

@@ -311,7 +311,6 @@ public class SysCodeGenService : IDynamicApiController, ITransient
             input.GenerateType = "200";
 
         // 先删除该表已生成的菜单列表
-        var templatePathList = GetTemplatePathList(input);
         List<string> targetPathList;
         var zipPath = Path.Combine(App.WebHostEnvironment.WebRootPath, "CodeGen", input.TableName);
         if (input.GenerateType.StartsWith('1'))
@@ -344,11 +343,15 @@ public class SysCodeGenService : IDynamicApiController, ITransient
             PrintType = input.PrintType,
             PrintName = input.PrintName,
         };
+        //模板目录
+        var templatePathList = GetTemplatePathList(input);
+        var templatePath = Path.Combine(App.WebHostEnvironment.WebRootPath, "Template");
 
         for (var i = 0; i < templatePathList.Count; i++)
         {
-            if (!File.Exists(templatePathList[i])) continue;
-            var tContent = File.ReadAllText(templatePathList[i]);
+            var templateFilePath = Path.Combine(templatePath, templatePathList[i]);
+            if (!File.Exists(templateFilePath)) continue;
+            var tContent = File.ReadAllText(templateFilePath);
             var tResult = await _viewEngine.RunCompileFromCachedAsync(tContent, data, builderAction: builder =>
             {
                 builder.AddAssemblyReferenceByName("System.Linq");
@@ -377,6 +380,58 @@ public class SysCodeGenService : IDynamicApiController, ITransient
         }
     }
 
+    /// <summary>
+    /// 获取代码生成预览 🔖
+    /// </summary>
+    /// <returns></returns>
+    [DisplayName("获取代码生成预览")]
+    public async Task<Dictionary<string, string>> Preview(SysCodeGen input)
+    {
+        var tableFieldList = await _codeGenConfigService.GetList(new CodeGenConfig() { CodeGenId = input.Id }); // 字段集合
+        var queryWhetherList = tableFieldList.Where(u => u.QueryWhether == YesNoEnum.Y.ToString()).ToList(); // 前端查询集合
+        var joinTableList = tableFieldList.Where(u => u.EffectType == "Upload" || u.EffectType == "fk" || u.EffectType == "ApiTreeSelect").ToList(); // 需要连表查询的字段
+        (string joinTableNames, string lowerJoinTableNames) = GetJoinTableStr(joinTableList); // 获取连表的实体名和别名
+
+        var data = new CustomViewEngine(_db)
+        {
+            ConfigId = input.ConfigId,
+            AuthorName = input.AuthorName,
+            BusName = input.BusName,
+            NameSpace = input.NameSpace,
+            ClassName = input.TableName,
+            PagePath = input.PagePath,
+            ProjectLastName = input.NameSpace.Split('.').Last(),
+            QueryWhetherList = queryWhetherList,
+            TableField = tableFieldList,
+            IsJoinTable = joinTableList.Count > 0,
+            IsUpload = joinTableList.Where(u => u.EffectType == "Upload").Any(),
+            PrintType = input.PrintType,
+            PrintName = input.PrintName,
+        };
+
+        //模板目录
+        var templatePathList = GetTemplatePathList(input);
+        var templatePath = Path.Combine(App.WebHostEnvironment.WebRootPath, "Template");
+
+        var result = new Dictionary<string, string>();
+        for (var i = 0; i < templatePathList.Count; i++)
+        {
+            var templateFilePath = Path.Combine(templatePath, templatePathList[i]);
+            if (!File.Exists(templateFilePath)) continue;
+            var tContent = File.ReadAllText(templateFilePath);
+            var tResult = await _viewEngine.RunCompileFromCachedAsync(tContent, data, builderAction: builder =>
+            {
+                builder.AddAssemblyReferenceByName("System.Linq");
+                builder.AddAssemblyReferenceByName("System.Collections");
+                builder.AddUsing("System.Collections.Generic");
+                builder.AddUsing("System.Linq");
+            });
+            result.Add(templatePathList[i]?.TrimEnd(".vm"), tResult);
+        }
+
+        return result;
+    }
+
     /// <summary>
     /// 获取连表的实体名和别名
     /// </summary>
@@ -621,38 +676,17 @@ public class SysCodeGenService : IDynamicApiController, ITransient
     /// <returns></returns>
     private static List<string> GetTemplatePathList(SysCodeGen input)
     {
-        var templatePath = Path.Combine(App.WebHostEnvironment.WebRootPath, "Template");
         if (input.GenerateType.Substring(1, 1).Contains('1'))
         {
-            return new List<string>()
-            {
-                Path.Combine(templatePath , "index.vue.vm"),
-                Path.Combine(templatePath , "editDialog.vue.vm"),
-                Path.Combine(templatePath , "manage.js.vm"),
-            };
+            return new List<string>() { "index.vue.vm", "editDialog.vue.vm", "manage.js.vm" };
         }
         else if (input.GenerateType.Substring(1, 1).Contains('2'))
         {
-            return new List<string>()
-            {
-                Path.Combine(templatePath , "Service.cs.vm"),
-                Path.Combine(templatePath , "Input.cs.vm"),
-                Path.Combine(templatePath , "Output.cs.vm"),
-                Path.Combine(templatePath , "Dto.cs.vm"),
-            };
+            return new List<string>() { "Service.cs.vm", "Input.cs.vm", "Output.cs.vm", "Dto.cs.vm" };
         }
         else
         {
-            return new List<string>()
-            {
-                Path.Combine(templatePath , "Service.cs.vm"),
-                Path.Combine(templatePath , "Input.cs.vm"),
-                Path.Combine(templatePath , "Output.cs.vm"),
-                Path.Combine(templatePath , "Dto.cs.vm"),
-                Path.Combine(templatePath , "index.vue.vm"),
-                Path.Combine(templatePath , "editDialog.vue.vm"),
-                Path.Combine(templatePath , "manage.js.vm"),
-            };
+            return new List<string>() { "Service.cs.vm", "Input.cs.vm", "Output.cs.vm", "Dto.cs.vm", "index.vue.vm", "editDialog.vue.vm", "manage.js.vm" };
         }
     }
 

+ 77 - 71
Web/src/api-services/apis/sys-code-gen-api.ts

@@ -1,7 +1,7 @@
 /* tslint:disable */
 /* eslint-disable */
 /**
- * Admin.NET 通用权限开发平台
+ * 所有接口
  * 让 .NET 开发更简单、更通用、更流行。整合最新技术,模块插件式开发,前后端分离,开箱即用。<br/><u><b><font color='FF0000'> 👮不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!</font></b></u>
  *
  * OpenAPI spec version: 1.0.0
@@ -11,13 +11,13 @@
  * https://github.com/swagger-api/swagger-codegen.git
  * Do not edit the class manually.
  */
-
 import globalAxios, { AxiosResponse, AxiosInstance, AxiosRequestConfig } from 'axios';
 import { Configuration } from '../configuration';
 // Some imports not used depending on template conditions
 // @ts-ignore
 import { BASE_PATH, COLLECTION_FORMATS, RequestArgs, BaseAPI, RequiredError } from '../base';
 import { AddCodeGenInput } from '../models';
+import { AdminResultDictionaryStringString } from '../models';
 import { AdminResultListColumnOuput } from '../models';
 import { AdminResultListDatabaseOutput } from '../models';
 import { AdminResultListString } from '../models';
@@ -55,13 +55,6 @@ export const SysCodeGenApiAxiosParamCreator = function (configuration?: Configur
             const localVarQueryParameter = {} as any;
 
             // authentication Bearer required
-            // http bearer authentication required
-            if (configuration && configuration.accessToken) {
-                const accessToken = typeof configuration.accessToken === 'function'
-                    ? await configuration.accessToken()
-                    : await configuration.accessToken;
-                localVarHeaderParameter["Authorization"] = "Bearer " + accessToken;
-            }
 
             localVarHeaderParameter['Content-Type'] = 'application/json-patch+json';
 
@@ -102,13 +95,6 @@ export const SysCodeGenApiAxiosParamCreator = function (configuration?: Configur
             const localVarQueryParameter = {} as any;
 
             // authentication Bearer required
-            // http bearer authentication required
-            if (configuration && configuration.accessToken) {
-                const accessToken = typeof configuration.accessToken === 'function'
-                    ? await configuration.accessToken()
-                    : await configuration.accessToken;
-                localVarHeaderParameter["Authorization"] = "Bearer " + accessToken;
-            }
 
             const query = new URLSearchParams(localVarUrlObj.search);
             for (const key in localVarQueryParameter) {
@@ -157,13 +143,6 @@ export const SysCodeGenApiAxiosParamCreator = function (configuration?: Configur
             const localVarQueryParameter = {} as any;
 
             // authentication Bearer required
-            // http bearer authentication required
-            if (configuration && configuration.accessToken) {
-                const accessToken = typeof configuration.accessToken === 'function'
-                    ? await configuration.accessToken()
-                    : await configuration.accessToken;
-                localVarHeaderParameter["Authorization"] = "Bearer " + accessToken;
-            }
 
             const query = new URLSearchParams(localVarUrlObj.search);
             for (const key in localVarQueryParameter) {
@@ -200,13 +179,6 @@ export const SysCodeGenApiAxiosParamCreator = function (configuration?: Configur
             const localVarQueryParameter = {} as any;
 
             // authentication Bearer required
-            // http bearer authentication required
-            if (configuration && configuration.accessToken) {
-                const accessToken = typeof configuration.accessToken === 'function'
-                    ? await configuration.accessToken()
-                    : await configuration.accessToken;
-                localVarHeaderParameter["Authorization"] = "Bearer " + accessToken;
-            }
 
             const query = new URLSearchParams(localVarUrlObj.search);
             for (const key in localVarQueryParameter) {
@@ -244,13 +216,6 @@ export const SysCodeGenApiAxiosParamCreator = function (configuration?: Configur
             const localVarQueryParameter = {} as any;
 
             // authentication Bearer required
-            // http bearer authentication required
-            if (configuration && configuration.accessToken) {
-                const accessToken = typeof configuration.accessToken === 'function'
-                    ? await configuration.accessToken()
-                    : await configuration.accessToken;
-                localVarHeaderParameter["Authorization"] = "Bearer " + accessToken;
-            }
 
             localVarHeaderParameter['Content-Type'] = 'application/json-patch+json';
 
@@ -296,13 +261,6 @@ export const SysCodeGenApiAxiosParamCreator = function (configuration?: Configur
             const localVarQueryParameter = {} as any;
 
             // authentication Bearer required
-            // http bearer authentication required
-            if (configuration && configuration.accessToken) {
-                const accessToken = typeof configuration.accessToken === 'function'
-                    ? await configuration.accessToken()
-                    : await configuration.accessToken;
-                localVarHeaderParameter["Authorization"] = "Bearer " + accessToken;
-            }
 
             if (id !== undefined) {
                 localVarQueryParameter['Id'] = id;
@@ -344,13 +302,47 @@ export const SysCodeGenApiAxiosParamCreator = function (configuration?: Configur
             const localVarQueryParameter = {} as any;
 
             // authentication Bearer required
-            // http bearer authentication required
-            if (configuration && configuration.accessToken) {
-                const accessToken = typeof configuration.accessToken === 'function'
-                    ? await configuration.accessToken()
-                    : await configuration.accessToken;
-                localVarHeaderParameter["Authorization"] = "Bearer " + accessToken;
+
+            localVarHeaderParameter['Content-Type'] = 'application/json-patch+json';
+
+            const query = new URLSearchParams(localVarUrlObj.search);
+            for (const key in localVarQueryParameter) {
+                query.set(key, localVarQueryParameter[key]);
             }
+            for (const key in options.params) {
+                query.set(key, options.params[key]);
+            }
+            localVarUrlObj.search = (new URLSearchParams(query)).toString();
+            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
+            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
+            const needsSerialization = (typeof body !== "string") || localVarRequestOptions.headers['Content-Type'] === 'application/json';
+            localVarRequestOptions.data =  needsSerialization ? JSON.stringify(body !== undefined ? body : {}) : (body || "");
+
+            return {
+                url: localVarUrlObj.pathname + localVarUrlObj.search + localVarUrlObj.hash,
+                options: localVarRequestOptions,
+            };
+        },
+        /**
+         * 
+         * @summary 获取代码生成预览 🔖
+         * @param {SysCodeGen} [body] 
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        apiSysCodeGenPreviewPost: async (body?: SysCodeGen, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
+            const localVarPath = `/api/sysCodeGen/preview`;
+            // use dummy base URL string because the URL constructor only accepts absolute URLs.
+            const localVarUrlObj = new URL(localVarPath, 'https://example.com');
+            let baseOptions;
+            if (configuration) {
+                baseOptions = configuration.baseOptions;
+            }
+            const localVarRequestOptions :AxiosRequestConfig = { method: 'POST', ...baseOptions, ...options};
+            const localVarHeaderParameter = {} as any;
+            const localVarQueryParameter = {} as any;
+
+            // authentication Bearer required
 
             localVarHeaderParameter['Content-Type'] = 'application/json-patch+json';
 
@@ -392,13 +384,6 @@ export const SysCodeGenApiAxiosParamCreator = function (configuration?: Configur
             const localVarQueryParameter = {} as any;
 
             // authentication Bearer required
-            // http bearer authentication required
-            if (configuration && configuration.accessToken) {
-                const accessToken = typeof configuration.accessToken === 'function'
-                    ? await configuration.accessToken()
-                    : await configuration.accessToken;
-                localVarHeaderParameter["Authorization"] = "Bearer " + accessToken;
-            }
 
             localVarHeaderParameter['Content-Type'] = 'application/json-patch+json';
 
@@ -445,13 +430,6 @@ export const SysCodeGenApiAxiosParamCreator = function (configuration?: Configur
             const localVarQueryParameter = {} as any;
 
             // authentication Bearer required
-            // http bearer authentication required
-            if (configuration && configuration.accessToken) {
-                const accessToken = typeof configuration.accessToken === 'function'
-                    ? await configuration.accessToken()
-                    : await configuration.accessToken;
-                localVarHeaderParameter["Authorization"] = "Bearer " + accessToken;
-            }
 
             const query = new URLSearchParams(localVarUrlObj.search);
             for (const key in localVarQueryParameter) {
@@ -489,13 +467,6 @@ export const SysCodeGenApiAxiosParamCreator = function (configuration?: Configur
             const localVarQueryParameter = {} as any;
 
             // authentication Bearer required
-            // http bearer authentication required
-            if (configuration && configuration.accessToken) {
-                const accessToken = typeof configuration.accessToken === 'function'
-                    ? await configuration.accessToken()
-                    : await configuration.accessToken;
-                localVarHeaderParameter["Authorization"] = "Bearer " + accessToken;
-            }
 
             localVarHeaderParameter['Content-Type'] = 'application/json-patch+json';
 
@@ -623,6 +594,20 @@ export const SysCodeGenApiFp = function(configuration?: Configuration) {
                 return axios.request(axiosRequestArgs);
             };
         },
+        /**
+         * 
+         * @summary 获取代码生成预览 🔖
+         * @param {SysCodeGen} [body] 
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        async apiSysCodeGenPreviewPost(body?: SysCodeGen, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<AdminResultDictionaryStringString>>> {
+            const localVarAxiosArgs = await SysCodeGenApiAxiosParamCreator(configuration).apiSysCodeGenPreviewPost(body, options);
+            return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
+                const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
+                return axios.request(axiosRequestArgs);
+            };
+        },
         /**
          * 
          * @summary 代码生成到本地 🔖
@@ -743,6 +728,16 @@ export const SysCodeGenApiFactory = function (configuration?: Configuration, bas
         async apiSysCodeGenPagePost(body?: CodeGenInput, options?: AxiosRequestConfig): Promise<AxiosResponse<AdminResultSqlSugarPagedListSysCodeGen>> {
             return SysCodeGenApiFp(configuration).apiSysCodeGenPagePost(body, options).then((request) => request(axios, basePath));
         },
+        /**
+         * 
+         * @summary 获取代码生成预览 🔖
+         * @param {SysCodeGen} [body] 
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        async apiSysCodeGenPreviewPost(body?: SysCodeGen, options?: AxiosRequestConfig): Promise<AxiosResponse<AdminResultDictionaryStringString>> {
+            return SysCodeGenApiFp(configuration).apiSysCodeGenPreviewPost(body, options).then((request) => request(axios, basePath));
+        },
         /**
          * 
          * @summary 代码生成到本地 🔖
@@ -859,6 +854,17 @@ export class SysCodeGenApi extends BaseAPI {
     public async apiSysCodeGenPagePost(body?: CodeGenInput, options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminResultSqlSugarPagedListSysCodeGen>> {
         return SysCodeGenApiFp(this.configuration).apiSysCodeGenPagePost(body, options).then((request) => request(this.axios, this.basePath));
     }
+    /**
+     * 
+     * @summary 获取代码生成预览 🔖
+     * @param {SysCodeGen} [body] 
+     * @param {*} [options] Override http request option.
+     * @throws {RequiredError}
+     * @memberof SysCodeGenApi
+     */
+    public async apiSysCodeGenPreviewPost(body?: SysCodeGen, options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminResultDictionaryStringString>> {
+        return SysCodeGenApiFp(this.configuration).apiSysCodeGenPreviewPost(body, options).then((request) => request(this.axios, this.basePath));
+    }
     /**
      * 
      * @summary 代码生成到本地 🔖

+ 63 - 0
Web/src/api-services/models/sql-sugar-paged-list-approval-flow-output.ts

@@ -0,0 +1,63 @@
+/* tslint:disable */
+/* eslint-disable */
+/**
+ * 所有接口
+ * 让 .NET 开发更简单、更通用、更流行。整合最新技术,模块插件式开发,前后端分离,开箱即用。<br/><u><b><font color='FF0000'> 👮不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!</font></b></u>
+ *
+ * OpenAPI spec version: 1.0.0
+ * 
+ *
+ * NOTE: This class is auto generated by the swagger code generator program.
+ * https://github.com/swagger-api/swagger-codegen.git
+ * Do not edit the class manually.
+ */
+import { ApprovalFlowOutput } from './approval-flow-output';
+/**
+ * 分页泛型集合
+ * @export
+ * @interface SqlSugarPagedListApprovalFlowOutput
+ */
+export interface SqlSugarPagedListApprovalFlowOutput {
+    /**
+     * 页码
+     * @type {number}
+     * @memberof SqlSugarPagedListApprovalFlowOutput
+     */
+    page?: number;
+    /**
+     * 页容量
+     * @type {number}
+     * @memberof SqlSugarPagedListApprovalFlowOutput
+     */
+    pageSize?: number;
+    /**
+     * 总条数
+     * @type {number}
+     * @memberof SqlSugarPagedListApprovalFlowOutput
+     */
+    total?: number;
+    /**
+     * 总页数
+     * @type {number}
+     * @memberof SqlSugarPagedListApprovalFlowOutput
+     */
+    totalPages?: number;
+    /**
+     * 当前页集合
+     * @type {Array<ApprovalFlowOutput>}
+     * @memberof SqlSugarPagedListApprovalFlowOutput
+     */
+    items?: Array<ApprovalFlowOutput> | null;
+    /**
+     * 是否有上一页
+     * @type {boolean}
+     * @memberof SqlSugarPagedListApprovalFlowOutput
+     */
+    hasPrevPage?: boolean;
+    /**
+     * 是否有下一页
+     * @type {boolean}
+     * @memberof SqlSugarPagedListApprovalFlowOutput
+     */
+    hasNextPage?: boolean;
+}

+ 6 - 0
Web/src/theme/app.scss

@@ -311,6 +311,9 @@ body,
 /* 外边距、内边距全局样式
 ------------------------------- */
 @for $i from 1 through 35 {
+	.mg#{$i} {
+		margin: #{$i}px !important;
+	}
 	.mt#{$i} {
 		margin-top: #{$i}px !important;
 	}
@@ -323,6 +326,9 @@ body,
 	.ml#{$i} {
 		margin-left: #{$i}px !important;
 	}
+	.pd#{$i} {
+		padding: #{$i}px !important;
+	}
 	.pt#{$i} {
 		padding-top: #{$i}px !important;
 	}

+ 140 - 0
Web/src/views/system/codeGen/component/previewDialog.vue

@@ -0,0 +1,140 @@
+<template>
+	<div class="sys-codeGenPreview-container">
+		<el-dialog v-model="state.isShowDialog" draggable :close-on-click-modal="false" width="90vw">
+			<template #header>
+				<div style="color: #fff">
+					<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>
+					<span> {{ props.title }} </span>
+				</div>
+			</template>
+			<div :class="[state.current?.endsWith('cs') ? 'cs-style' : state.current?.endsWith('vue') ? 'vue-style' : 'js-style']">
+				<el-segmented v-model="state.current" :options="state.options" block @change="handleChange">
+					<template #default="{ item }">
+						<div class="pd4">
+							<SvgIcon :name="item.icon" class="mb4" />
+							<div>{{ item.label }}</div>
+						</div>
+					</template>
+				</el-segmented>
+			</div>
+			<div ref="monacoEditorRef" style="width: 100%; height: 660px; margin-top: 6px"></div>
+			<template #footer>
+				<span class="dialog-footer">
+					<el-button icon="ele-Close" @click="cancel">关 闭</el-button>
+					<el-button icon="ele-CopyDocument" type="primary" @click="handleCopy">复 制</el-button>
+				</span>
+			</template>
+		</el-dialog>
+	</div>
+</template>
+
+<script lang="ts" setup name="sysPreviewCode">
+import { reactive, ref, nextTick, toRaw } from 'vue';
+import * as monaco from 'monaco-editor';
+import jsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker';
+import cssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker';
+import htmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker';
+import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker';
+import EditorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker';
+import commonFunction from '/@/utils/commonFunction';
+
+import { getAPI } from '/@/utils/axios-utils';
+import { SysCodeGenApi } from '/@/api-services/api';
+
+const { copyText } = commonFunction();
+
+const props = defineProps({
+	title: String,
+});
+const monacoEditorRef = ref();
+const state = reactive({
+	isShowDialog: false,
+	options: [], //分段器的选项
+	current: '', // 选中的分段
+	codes: [], //预览的代码
+});
+
+// 防止 monaco 报黄
+self.MonacoEnvironment = {
+	getWorker: (_: string, label: string) => new EditorWorker(),
+};
+
+// 初始化monacoEditor对象
+var monacoEditor: any = null;
+const initMonacoEditor = () => {
+	monacoEditor = monaco.editor.create(monacoEditorRef.value, {
+		theme: 'vs-dark', // 主题 vs vs-dark hc-black
+		value: '', // 默认显示的值
+		language: 'csharp',
+		formatOnPaste: true,
+		wordWrap: 'on', //自动换行,注意大小写
+		wrappingIndent: 'indent',
+		folding: true, // 是否折叠
+		foldingHighlight: true, // 折叠等高线
+		foldingStrategy: 'indentation', // 折叠方式  auto | indentation
+		showFoldingControls: 'always', // 是否一直显示折叠 always | mouSEOver
+		disableLayerHinting: true, // 等宽优化
+		emptySelectionClipboard: false, // 空选择剪切板
+		selectionClipboard: false, // 选择剪切板
+		automaticLayout: true, // 自动布局
+		codeLens: false, // 代码镜头
+		scrollBeyondLastLine: false, // 滚动完最后一行后再滚动一屏幕
+		colorDecorators: true, // 颜色装饰器
+		accessibilitySupport: 'auto', // 辅助功能支持  "auto" | "off" | "on"
+		lineNumbers: 'on', // 行号 取值: "on" | "off" | "relative" | "interval" | function
+		lineNumbersMinChars: 5, // 行号最小字符   number
+		//enableSplitViewResizing: false,
+		readOnly: false, //是否只读  取值 true | false
+	});
+};
+
+// 打开弹窗
+const openDialog = async (row: any) => {
+	state.isShowDialog = true;
+	const { data } = await getAPI(SysCodeGenApi).apiSysCodeGenPreviewPost(row);
+	state.codes = data.result ?? [];
+	state.options = Object.keys(data.result).map((e) => {
+		let temp = { value: e, label: e };
+		if (['Service.cs', 'Input.cs', 'Output.cs', 'Dto.cs'].includes(e)) temp.icon = 'fa fa-hashtag';
+		else if (['index.vue', 'editDialog.vue'].includes(e)) temp.icon = 'fa fa-vimeo';
+		else temp.icon = 'fa fa-file-code-o';
+		return temp;
+	});
+	state.current = state.options?.[0]?.value ?? '';
+	if (monacoEditor == null) initMonacoEditor();
+	// 防止取不到
+	nextTick(() => {
+		monacoEditor.setValue(state.codes[state.current]);
+	});
+};
+
+// 分段器改变时切换代码
+const handleChange = (current: any) => {
+	monacoEditor.setValue(state.codes[current]);
+};
+
+// 取消
+const cancel = () => {
+	state.isShowDialog = false;
+};
+
+//复制代码
+const handleCopy = () => {
+	copyText(state.codes[state.current]);
+};
+
+// 导出对象
+defineExpose({ openDialog });
+</script>
+
+<style scoped>
+.cs-style .el-segmented {
+	--el-segmented-item-selected-bg-color: #5c2d91;
+}
+.vue-style .el-segmented {
+	--el-segmented-item-selected-bg-color: #42b883;
+}
+.js-style .el-segmented {
+	--el-segmented-item-selected-bg-color: #e44d26;
+}
+</style>

+ 12 - 1
Web/src/views/system/codeGen/index.vue

@@ -41,6 +41,7 @@
 				<el-table-column label="操作" width="200" fixed="right" align="center" show-overflow-tooltip>
 					<template #default="scope">
 						<el-button size="small" text type="primary" @click="handleGenerate(scope.row)">开始生成</el-button>
+						<el-button size="small" text type="primary" @click="handlePreview(scope.row)">预览</el-button>
 						<el-button size="small" text type="primary" @click="openConfigDialog(scope.row)">配置</el-button>
 						<el-button size="small" text type="primary" @click="openEditDialog(scope.row)">编辑</el-button>
 						<el-button size="small" text type="primary" @click="deleConfig(scope.row)">删除</el-button>
@@ -62,11 +63,12 @@
 
 		<EditCodeGenDialog :title="state.editMenuTitle" ref="EditCodeGenRef" @handleQuery="handleQuery" :application-namespaces="state.applicationNamespaces" />
 		<CodeConfigDialog ref="CodeConfigRef" @handleQuery="handleQuery" />
+		<PreviewDialog :title="state.editMenuTitle" ref="PreviewRef" />
 	</div>
 </template>
 
 <script lang="ts" setup name="sysCodeGen">
-import { onMounted, reactive, ref } from 'vue';
+import { onMounted, reactive, ref, defineAsyncComponent } from 'vue';
 import { ElMessageBox, ElMessage } from 'element-plus';
 import EditCodeGenDialog from './component/editCodeGenDialog.vue';
 import CodeConfigDialog from './component/genConfigDialog.vue';
@@ -76,8 +78,11 @@ import { getAPI } from '/@/utils/axios-utils';
 import { SysCodeGenApi } from '/@/api-services/api';
 import { SysCodeGen } from '/@/api-services/models';
 
+const PreviewDialog = defineAsyncComponent(() => import('./component/previewDialog.vue'));
+
 const EditCodeGenRef = ref<InstanceType<typeof EditCodeGenDialog>>();
 const CodeConfigRef = ref<InstanceType<typeof CodeConfigDialog>>();
+const PreviewRef = ref<InstanceType<typeof PreviewDialog>>();
 const state = reactive({
 	loading: false,
 	loading1: false,
@@ -190,4 +195,10 @@ const handleGenerate = (row: any) => {
 		})
 		.catch(() => {});
 };
+
+// 预览代码
+const handlePreview = (row: any) => {
+	state.editMenuTitle = '预览';
+	PreviewRef.value?.openDialog(row);
+};
 </script>