如何移除VS Add-In残留的菜单项

本文介绍了如何解决Visual Studio中卸载Add-In后残留菜单项的问题。提供了两种实用的方法:一是利用devenv命令进行清除;二是通过工具栏自定义功能删除。这两种方法都能有效地帮助用户彻底移除不再使用的Add-In菜单。

昨天发现VS中有个多余的Add-In菜单项,我顿时想起了一位朋友的回复:

Add-in确实很好,但是社区的有些Addin很难卸载干净,不知道为什么。比如AnkhSvn,可能我的人品不好,卸载之后菜单栏里一直有AnkhSvn 的菜单,但是里面所有菜单项都不可用。唉,不管好不好用,至少要把自己加进去的东西删干净啊,此乃基本道德。

所以压力很大,就想找到办法来移除那些残留的菜单项,有两篇文章可以参考一下:

Deactivate and Remove an Add-in
How to get rid of a Visual Studio add-in

其中有两个比较简单易行的方法。

1)使用devenv命令

devenv.exe /resetaddin <Namespace.Class>

Namespace.Class即Add-In的实现类的完全限定名称,比如那个默认的Connect。对于我们开发的Add-In来说,可以查看.Addin文件中的<FullClassName></FullClassName>节点。

2)使用工具栏的自定义功能

我们可以把命令添加到工具栏,这也包括自定义的Add-In命令,方法是Tools->Customize…:

customize-commands

将需要移除的命令拖到工具栏上,关闭对话框。如果Add-In已经卸载了,那么它的功能自然是不可用的了,此时点击工具栏的相应按钮,VS就会报错,此时就可以选择将其移除了。

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <conio.h> // 用于getch()函数实现按键等待功能 #define FILENAME "inventory.dat" // 数据文件名 #define MAX_PRODUCTS 100 // 最大商品数量 // 日期结构体 typedef struct { int year; // 生产年份 int month; // 生产月份 int day; // 生产日期 } Date; // 商品信息结构体 typedef struct { char id[20]; // 商品编号 char name[50]; // 商品名称 char model[50]; // 商品型号 char manufacturer[50]; // 生产厂家 char brand[50]; // 品牌 char category[50]; // 商品类别 Date production_date; // 生产日期 int quantity; // 库存数量 float price; // 商品价格 } Product; // 全局变量声明 Product products[MAX_PRODUCTS]; // 商品信息数组 int product_count = 0; // 当前商品数量 // 函数声明 void load_data(); // 从文件加载数据 void save_data(); // 保存数据到文件 void main_menu(); // 主菜单系统 void add_product(); // 添加新产品 void display_all(); // 显示所有产品 void search_menu(); // 搜索菜单 void search_by_name(); // 按名称搜索 void search_by_category(); // 按类别搜索 void search_by_price_range(); // 按价格范围搜索 void sort_menu(); // 排序菜单 void sort_by_name(); // 按名称排序 void sort_by_category(); // 按类别排序 void sort_by_price(); // 按价格排序 void delete_product(); // 删除产品 void modify_product(); // 修改产品 void stock_in(); // 商品入库 void stock_out(); // 商品出库 /​**​ * 主函数 - 程序入口点 * @return 程序退出状态 */ int main() { load_data(); // 程序启动时加载数据 main_menu(); // 进入主菜单 return 0; // 程序正常退出 } /​**​ * 从文件加载商品数据 */ void load_data() { FILE *file = fopen(FILENAME, "rb"); // 以二进制只读模式打开文件 // 检查文件是否成功打开 if (file != NULL) { // 先读取商品数量 fread(&product_count, sizeof(int), 1, file); // 再读取所有商品数据 fread(products, sizeof(Product), product_count, file); fclose(file); // 关闭文件 printf("成功加载 %d 条商品数据\n", product_count); } else { printf("数据文件不存在,将创建新文件\n"); } } /​**​ * 保存商品数据到文件 */ void save_data() { FILE *file = fopen(FILENAME, "wb"); // 以二进制写模式打开文件 // 检查文件是否成功打开 if (file != NULL) { // 先写入商品数量 fwrite(&product_count, sizeof(int), 1, file); // 再写入所有商品数据 fwrite(products, sizeof(Product), product_count, file); fclose(file); // 关闭文件 } else { printf("错误:无法保存数据文件!\n"); } } /​**​ * 主菜单系统 */ void main_menu() { int choice; // 用户选择 do { system("cls"); // 清屏命令,提供清晰界面 // 显示主菜单 printf("\n===== 家电库存管理系统 =====\n"); printf("1. 添加新产品\n"); printf("2. 显示所有产品\n"); printf("3. 搜索产品\n"); printf("4. 排序产品\n"); printf("5. 删除产品\n"); printf("6. 修改产品\n"); printf("7. 商品入库\n"); printf("8. 商品出库\n"); printf("0. 退出系统\n"); printf("==============================\n"); printf("请选择操作:"); scanf("%d", &choice); // 获取用户输入 // 根据用户选择调用相应功能 switch (choice) { case 1: add_product(); break; // 添加新产品 case 2: display_all(); break; // 显示所有产品 case 3: search_menu(); break; // 进入搜索菜单 case 4: sort_menu(); break; // 进入排序菜单 case 5: delete_product(); break; // 删除产品 case 6: modify_product(); break; // 修改产品信息 case 7: stock_in(); break; // 商品入库 case 8: stock_out(); break; // 商品出库 case 0: save_data(); // 退出前保存数据 printf("感谢使用家电库存管理系统!\n"); break; default: printf("无效的选择,请重新输入!\n"); getch(); // 等待用户按键 } } while (choice != 0); // 循环直到用户选择退出 } /​**​ * 添加新产品功能 */ void add_product() { // 检查库存是否已满 if (product_count >= MAX_PRODUCTS) { printf("错误:库存已满,无法添加新产品!\n"); getch(); // 等待用户按键 return; } // 创建新产品对象 Product new_product; printf("\n===== 添加新产品 =====\n"); // 收集商品信息 printf("编号:"); scanf("%19s", new_product.id); // 限制输入长度 printf("名称:"); scanf("%49s", new_product.name); printf("型号:"); scanf("%49s", new_product.model); printf("生产厂家:"); scanf("%49s", new_product.manufacturer); printf("品牌:"); scanf("%49s", new_product.brand); printf("类别:"); scanf("%49s", new_product.category); printf("生产日期(年 月 日):"); scanf("%d %d %d", &new_product.production_date.year, &new_product.production_date.month, &new_product.production_date.day); printf("数量:"); scanf("%d", &new_product.quantity); printf("价格:"); scanf("%f", &new_product.price); // 将新产品添加到数组 products[product_count] = new_product; product_count++; // 商品计数增加 save_data(); // 保存更改 printf("\n产品添加成功!当前商品总数:%d\n", product_count); getch(); // 等待用户按键 } /​**​ * 显示所有产品信息 */ void display_all() { system("cls"); // 清屏 printf("\n===== 所有产品列表 =====\n"); printf("ID\t名称\t\t型号\t类别\t库存\t价格\n"); printf("--------------------------------------------------------------\n"); // 遍历并显示所有商品 for (int i = 0; i < product_count; i++) { printf("%s\t%-10s\t%s\t%s\t%d\t¥%.2f\n", products[i].id, products[i].name, products[i].model, products[i].category, products[i].quantity, products[i].price); } printf("\n总计: %d 件商品\n", product_count); getch(); // 等待用户按键 } /​**​ * 搜索功能菜单 */ void search_menu() { int choice; // 用户选择 do { system("cls"); // 清屏 printf("\n===== 搜索选项 =====\n"); printf("1. 按名称搜索\n"); printf("2. 按类别搜索\n"); printf("3. 按价格范围搜索\n"); printf("0. 返回主菜单\n"); printf("请选择:"); scanf("%d", &choice); // 根据用户选择调用不同搜索功能 switch (choice) { case 1: search_by_name(); break; case 2: search_by_category(); break; case 3: search_by_price_range(); break; } } while (choice != 0); // 循环直到用户选择返回 } /​**​ * 按名称搜索产品 */ void search_by_name() { char keyword[50]; int found = 0; // 是否找到匹配项 printf("输入要搜索的产品名称:"); scanf("%49s", keyword); printf("\n搜索结果:\n"); printf("ID\t名称\t\t型号\t库存\t价格\n"); printf("------------------------------------------------\n"); // 遍历商品数组查找匹配项 for (int i = 0; i < product_count; i++) { // 使用strstr函数进行子串匹配(模糊搜索) if (strstr(products[i].name, keyword) != NULL) { printf("%s\t%-10s\t%s\t%d\t¥%.2f\n", products[i].id, products[i].name, products[i].model, products[i].quantity, products[i].price); found++; // 增加找到的计数 } } if (found == 0) { printf("未找到匹配的产品\n"); } else { printf("\n共找到 %d 条匹配记录\n", found); } getch(); // 等待用户按键 } /​**​ * 按类别搜索产品 */ void search_by_category() { char category[50]; int found = 0; printf("输入要搜索的类别:"); scanf("%49s", category); printf("\n搜索结果:\n"); printf("ID\t名称\t\t型号\t库存\t价格\n"); printf("------------------------------------------------\n"); // 遍历商品数组查找精确匹配 for (int i = 0; i < product_count; i++) { if (strcmp(products[i].category, category) == 0) { printf("%s\t%-10s\t%s\t%d\t¥%.2f\n", products[i].id, products[i].name, products[i].model, products[i].quantity, products[i].price); found++; } } if (found == 0) { printf("未找到匹配的产品\n"); } else { printf("\n共找到 %d 条匹配记录\n", found); } getch(); // 等待用户按键 } /​**​ * 按价格范围搜索产品 */ void search_by_price_range() { float min_price, max_price; int found = 0; printf("输入最低价格:"); scanf("%f", &min_price); printf("输入最高价格:"); scanf("%f", &max_price); // 确保价格范围有效 if (min_price > max_price) { float temp = min_price; min_price = max_price; max_price = temp; printf("已自动交换价格区间为: ¥%.2f - ¥%.2f\n", min_price, max_price); } printf("\n搜索结果(价格范围: ¥%.2f - ¥%.2f):\n", min_price, max_price); printf("ID\t名称\t\t型号\t库存\t价格\n"); printf("------------------------------------------------\n"); // 遍历商品数组查找在价格范围内的产品 for (int i = 0; i < product_count; i++) { if (products[i].price >= min_price && products[i].price <= max_price) { printf("%s\t%-10s\t%s\t%d\t¥%.2f\n", products[i].id, products[i].name, products[i].model, products[i].quantity, products[i].price); found++; } } if (found == 0) { printf("未找到匹配的产品\n"); } else { printf("\n共找到 %d 条匹配记录\n", found); } getch(); // 等待用户按键 } /​**​ * 排序功能菜单 */ void sort_menu() { int choice; // 用户选择 do { system("cls"); // 清屏 printf("\n===== 排序选项 =====\n"); printf("1. 按名称排序\n"); printf("2. 按类别排序\n"); printf("3. 按价格排序\n"); printf("0. 返回主菜单\n"); printf("请选择:"); scanf("%d", &choice); // 根据用户选择调用不同排序功能 switch (choice) { case 1: sort_by_name(); display_all(); // 排序后显示结果 break; case 2: sort_by_category(); display_all(); break; case 3: sort_by_price(); display_all(); break; } } while (choice != 0); // 循环直到用户选择返回 } /​**​ * 按名称排序(升序) */ void sort_by_name() { // 使用冒泡排序算法 for (int i = 0; i < product_count - 1; i++) { for (int j = 0; j < product_count - i - 1; j++) { // 比较相邻两个商品的名称 if (strcmp(products[j].name, products[j+1].name) > 0) { // 交换位置 Product temp = products[j]; products[j] = products[j+1]; products[j+1] = temp; } } } printf("产品已按名称排序\n"); } /​**​ * 按类别排序(升序) */ void sort_by_category() { // 使用冒泡排序算法 for (int i = 0; i < product_count - 1; i++) { for (int j = 0; j < product_count - i - 1; j++) { // 比较相邻两个商品的类别 if (strcmp(products[j].category, products[j+1].category) > 0) { // 交换位置 Product temp = products[j]; products[j] = products[j+1]; products[j+1] = temp; } } } printf("产品已按类别排序\n"); } /​**​ * 按价格排序(升序) */ void sort_by_price() { // 使用冒泡排序算法 for (int i = 0; i < product_count - 1; i++) { for (int j = 0; j < product_count - i - 1; j++) { // 比较相邻两个商品的价格 if (products[j].price > products[j+1].price) { // 交换位置 Product temp = products[j]; products[j] = products[j+1]; products[j+1] = temp; } } } printf("产品已按价格排序\n"); } /​**​ * 删除产品功能 */ void delete_product() { char id[20]; int found = 0; // 是否找到匹配项 printf("输入要删除的产品ID:"); scanf("%19s", id); // 遍历查找匹配产品 for (int i = 0; i < product_count; i++) { if (strcmp(products[i].id, id) == 0) { found = 1; printf("找到产品: %s (%s), 库存: %d\n", products[i].name, products[i].model, products[i].quantity); char confirm; printf("确认删除?(y/n): "); scanf(" %c", &confirm); // 注意空格用于跳过换行符 if (confirm == 'y' || confirm == 'Y') { // 移动数组元素覆盖要删除的商品 for (int j = i; j < product_count - 1; j++) { products[j] = products[j+1]; } product_count--; // 商品数量减少 save_data(); // 保存更改 printf("产品删除成功!\n"); } else { printf("删除操作已取消\n"); } break; } } if (!found) { printf("未找到该产品!\n"); } getch(); // 等待用户按键 } /​**​ * 修改产品信息 */ void modify_product() { char id[20]; int found = 0; printf("输入要修改的产品ID:"); scanf("%19s", id); // 遍历查找匹配产品 for (int i = 0; i < product_count; i++) { if (strcmp(products[i].id, id) == 0) { found = 1; Product *p = &products[i]; // 获取产品指针方便修改 printf("\n===== 修改产品信息 =====\n"); printf("当前名称: %s\n", p->name); printf("新名称 (按回车跳过): "); getchar(); // 清除输入缓冲区 fgets(p->name, 50, stdin); p->name[strcspn(p->name, "\n")] = 0; // 移除换行符 printf("当前型号: %s\n", p->model); printf("新型号 (按回车跳过): "); fgets(p->model, 50, stdin); p->model[strcspn(p->model, "\n")] = 0; printf("当前厂家: %s\n", p->manufacturer); printf("新厂家 (按回车跳过): "); fgets(p->manufacturer, 50, stdin); p->manufacturer[strcspn(p->manufacturer, "\n")] = 0; printf("当前品牌: %s\n", p->brand); printf("新品牌 (按回车跳过): "); fgets(p->brand, 50, stdin); p->brand[strcspn(p->brand, "\n")] = 0; printf("当前类别: %s\n", p->category); printf("新类别 (按回车跳过): "); fgets(p->category, 50, stdin); p->category[strcspn(p->category, "\n")] = 0; printf("当前价格: %.2f\n", p->price); printf("新价格 (-1跳过): "); float new_price; scanf("%f", &new_price); if (new_price > 0) { p->price = new_price; } save_data(); // 保存更改 printf("产品信息修改成功!\n"); break; } } if (!found) { printf("未找到该产品!\n"); } getch(); // 等待用户按键 } /​**​ * 商品入库功能 */ void stock_in() { char id[20]; int amount; int found = 0; printf("输入产品ID:"); scanf("%19s", id); printf("输入入库数量:"); scanf("%d", &amount); // 验证入库数量 if (amount <= 0) { printf("错误:入库数量必须大于0!\n"); getch(); return; } // 遍历查找匹配产品 for (int i = 0; i < product_count; i++) { if (strcmp(products[i].id, id) == 0) { found = 1; products[i].quantity += amount; // 增加库存 save_data(); // 保存更改 printf("入库成功!当前库存:%d\n", products[i].quantity); break; } } if (!found) { printf("未找到该产品!\n"); } getch(); // 等待用户按键 } /​**​ * 商品出库功能 */ void stock_out() { char id[20]; int amount; int found = 0; printf("输入产品ID:"); scanf("%19s", id); printf("输入出库数量:"); scanf("%d", &amount); // 验证出库数量 if (amount <= 0) { printf("错误:出库数量必须大于0!\n"); getch(); return; } // 遍历查找匹配产品 for (int i = 0; i < product_count; i++) { if (strcmp(products[i].id, id) == 0) { found = 1; // 检查库存是否足够 if (products[i].quantity >= amount) { products[i].quantity -= amount; // 减少库存 save_data(); // 保存更改 printf("出库成功!当前库存:%d\n", products[i].quantity); } else { printf("库存不足!当前库存:%d,出库需求:%d\n", products[i].quantity, amount); } break; } } if (!found) { printf("未找到该产品!\n"); } getch(); // 等待用户按键 }代码纠错
06-18
<template> <!-- 模板部分保持不变 --> <div class="app-container"> <!-- 物料类型数据 --> <el-row :gutter="20"> <!--物料类型数据--> <splitpanes :horizontal="appStore.device === 'mobile'" class="default-theme"> <pane size="16"> <el-col> <div class="head-container"> <el-input v-model="materiaTypelName" placeholder="请输入物料类型名称" clearable prefix-icon="Search" style="margin-bottom: 20px"/> </div> <div class="head-container"> <el-tree :data="typeOptions" :props="{ label: 'label', children: 'children' }" :expand-on-click-node="false" :filter-node-method="filterNode" ref="treeRef" node-key="id" highlight-current default-expand-all @node-click="handleNodeClick"/> </div> </el-col> </pane> <!-- 属性数据--> <pane size="84"> <el-col> <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px"> <el-form-item label="编号" prop="number"> <el-input v-model="queryParams.number" placeholder="请输入编号" clearable @keyup.enter.native="handleQuery" style="width: 240px"/> </el-form-item> <el-form-item label="名称" prop="name"> <el-input v-model="queryParams.name" placeholder="请输入名称" clearable @keyup.enter.native="handleQuery" style="width: 240px"/> </el-form-item> <el-form-item label="状态" prop="status"> <el-select v-model="queryParams.status" placeholder="请选择状态" clearable style="width: 240px"> <el-option v-for="dict in mdm_common_status_list" :key="dict.value" :label="dict.label" :value="dict.value"/> </el-select> </el-form-item> <el-form-item> <el-button type="primary" icon="search" @click="handleQuery">搜索</el-button> <el-button icon="refresh" @click="resetQuery">重置</el-button> </el-form-item> </el-form> <el-row :gutter="10" class="mb8"> <el-col :span="1.5"> <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['mdm:typeAttr:add']" >新增 </el-button> </el-col> <el-col :span="1.5"> <el-button type="success" plain icon="edit" :disabled="single" @click="handleUpdate" v-hasPermi="['mdm:typeAttr:edit']" >修改 </el-button> </el-col> <el-col :span="1.5"> <el-button type="danger" plain icon="delete" :disabled="multiple" @click="handleDelete" v-hasPermi="['mdm:typeAttr:remove']" >删除 </el-button> </el-col> <el-col :span="1.5"> <el-button type="warning" plain icon="download" @click="handleExport" v-hasPermi="['mdm:typeAttr:export']" >导出 </el-button> </el-col> <el-col :span="1.5"> <el-button type="info" plain icon="upload" @click="handleImport" v-hasPermi="['mdm:typeAttr:import']" >导入 </el-button> </el-col> <el-col :span="1.5"> <el-button type="warning" plain icon="edit" @click="handleUrlUpdate" v-hasPermi="['mdm:mdmMaterialType:edit']"> 编辑命名规则 </el-button> </el-col> <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> </el-row> <el-table v-loading="loading" :data="typeAttrList" @selection-change="handleSelectionChange"> <el-table-column type="selection" width="45" align="center" fixed/> <el-table-column label="编号" align="center" prop="number"/> <el-table-column label="名称" align="center" prop="name"/> <el-table-column label="类型名称" align="center" prop="typemgrName" width="140"/> <el-table-column label="类型编号" align="center" prop="typemgrNum" width="140"/> <el-table-column label="字段类型" align="center" prop="dataType"> <template #default="scope"> <dict-tag :options="mdm_common_column_type" :value="scope.row.dataType"/> </template> </el-table-column> <el-table-column label="文本最大长度" align="center" prop="length" width="120"/> <el-table-column label="数值最大值" align="center" prop="maxVal" width="120"/> <el-table-column label="数值最小值" align="center" prop="minVal" width="120"/> <el-table-column label="默认值" align="center" prop="defaultVal"/> <el-table-column label="枚举ID" align="center" prop="enumerateId"/> <el-table-column label="枚举表" align="center" prop="enumerateTable"/> <el-table-column label="单位" align="center" prop="unit"/> <el-table-column label="是否必填" align="center" prop="isNull"> <template #default="scope"> <dict-tag :options="mdm_common_flag_list" :value="scope.row.isNull"/> </template> </el-table-column> <el-table-column label="弹窗编辑器ID" align="center" prop="popupEditId" width="120"/> <el-table-column label="URL地址" align="center" prop="href"/> <el-table-column label="是否可查询" align="center" prop="isQuery" width="120"> <template #default="scope"> <dict-tag :options="mdm_common_flag_list" :value="scope.row.isQuery"/> </template> </el-table-column> <el-table-column label="是否表单显示" align="center" prop="isShowForm" width="120"> <template #default="scope"> <dict-tag :options="mdm_common_flag_list" :value="scope.row.isShowForm"/> </template> </el-table-column> <el-table-column label="是否列表显示" align="center" prop="isShowList" width="120"> <template #default="scope"> <dict-tag :options="mdm_common_flag_list" :value="scope.row.isShowList"/> </template> </el-table-column> <el-table-column label="是否只读" align="center" prop="isReadOnly"> <template #default="scope"> <dict-tag :options="mdm_common_flag_list" :value="scope.row.isReadOnly"/> </template> </el-table-column> <el-table-column label="表单排序" align="center" prop="orderNum"/> <el-table-column label="是否支持排序" align="center" prop="sortFlag" width="120"> <template #default="scope"> <dict-tag :options="mdm_common_flag_list" :value="scope.row.sortFlag"/> </template> </el-table-column> <el-table-column label="数值是否有公差" align="center" prop="isTolerance" width="120"> <template #default="scope"> <dict-tag :options="mdm_common_flag_list" :value="scope.row.isTolerance"/> </template> </el-table-column> <el-table-column label="正则表达式校验" align="center" prop="regularCheck" width="120"/> <el-table-column label="状态" align="center" prop="status"> <template #default="scope"> <dict-tag :options="mdm_common_status_list" :value="scope.row.status"/> </template> </el-table-column> <el-table-column label="合法值" align="center" prop="validStr" width="150"/> <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="240" fixed="right"> <template #default="scope"> <el-button link icon="edit" type="primary" @click="handleUpdate(scope.row)" v-hasPermi="['mdm:typeAttr:edit']" >修改 </el-button> <el-button link type="primary" icon="delete" @click="handleDelete(scope.row)" v-hasPermi="['mdm:typeAttr:remove']" >删除 </el-button> <el-button link type="primary" icon="edit" @click="eidtValid(scope.row)" v-hasPermi="['mdm:typeAttr:remove']" >编辑合法值 </el-button> </template> </el-table-column> </el-table> <pagination v-show="total>0" :total="total" v-model:page="queryParams.pageNum" v-model::limit="queryParams.pageSize" @pagination="getList"/> </el-col> </pane> </splitpanes> </el-row> <!-- 添加或修改属性规则对话框 --> <el-dialog :title="title" v-model="open" width="850px" append-to-body> <el-form :model="form" :rules="rules" ref="formRef" label-width="120px"> <!-- 基本信息 --> <el-row> <el-col :span="12"> <el-form-item label="编号" prop="number"> <el-input v-model="form.number" placeholder="请输入编号" style="width: 240px"/> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="名称" prop="name"> <el-input v-model="form.name" placeholder="请输入名称" style="width: 240px"/> </el-form-item> </el-col> </el-row> <el-row> <el-col :span="12"> <el-form-item label="类型ID" prop="typemgrId"> <el-tree-select v-model="form.typemgrId" :data="typeOptions" :props="{ value: 'id', label: 'label', children: 'children' }" value-key="id" :current-node-key="form.typemgrId" placeholder="请选择物料类型" check-strictly style="width: 240px"/> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="字段类型" prop="dataType"> <el-select v-model="form.dataType" placeholder="请选择字段类型" style="width: 240px"> <el-option v-for="dict in mdm_common_column_type" :key="dict.value" :label="dict.label" :value="dict.value" ></el-option> </el-select> </el-form-item> </el-col> </el-row> <!-- 数值与文本配置 --> <el-row> <el-col :span="12"> <el-form-item label="文本最大长度" prop="length"> <el-input v-model="form.length" placeholder="请输入文本最大长度" style="width: 240px"/> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="数值最大值" prop="maxVal"> <el-input v-model="form.maxVal" placeholder="请输入数值最大值" style="width: 240px"/> </el-form-item> </el-col> </el-row> <el-row> <el-col :span="12"> <el-form-item label="数值最小值" prop="minVal"> <el-input v-model="form.minVal" placeholder="请输入数值最小值" style="width: 240px"/> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="默认值" prop="defaultVal"> <el-input v-model="form.defaultVal" placeholder="请输入默认值" style="width: 240px"/> </el-form-item> </el-col> </el-row> <el-row> <el-col :span="12"> <el-form-item label="枚举ID" prop="enumerateId"> <el-input v-model="form.enumerateId" placeholder="请输入枚举ID" style="width: 240px"/> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="正则表达式校验" prop="regularCheck"> <el-input v-model="form.regularCheck" placeholder="请输入正则表达式校验" style="width: 240px"/> </el-form-item> </el-col> </el-row> <el-row> <el-col :span="12"> <el-form-item label="枚举表" prop="enumerateTable"> <el-input v-model="form.enumerateTable" placeholder="请输入枚举表" style="width: 240px"/> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="单位" prop="unit"> <el-input v-model="form.unit" placeholder="请输入单位" style="width: 240px"/> </el-form-item> </el-col> </el-row> <!-- 状态与布尔选项 --> <el-row> <el-col :span="12"> <el-form-item label="是否必填" prop="isNull"> <el-select v-model="form.isNull" placeholder="请选择是否必填" style="width: 240px"> <el-option v-for="dict in mdm_common_flag_list" :key="dict.value" :label="dict.label" :value="dict.value" ></el-option> </el-select> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="是否可查询" prop="isQuery"> <el-select v-model="form.isQuery" placeholder="请选择是否可查询" style="width: 240px"> <el-option v-for="dict in mdm_common_flag_list" :key="dict.value" :label="dict.label" :value="dict.value" ></el-option> </el-select> </el-form-item> </el-col> </el-row> <el-row> <el-col :span="12"> <el-form-item label="是否表单显示" prop="isShowForm"> <el-select v-model="form.isShowForm" placeholder="请选择是否表单显示" style="width: 240px"> <el-option v-for="dict in mdm_common_flag_list " :key="dict.value" :label="dict.label" :value="dict.value" ></el-option> </el-select> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="是否列表显示" prop="isShowList"> <el-select v-model="form.isShowList" placeholder="请选择是否列表显示" style="width: 240px"> <el-option v-for="dict in mdm_common_flag_list" :key="dict.value" :label="dict.label" :value="dict.value" ></el-option> </el-select> </el-form-item> </el-col> </el-row> <el-row> <el-col :span="12"> <el-form-item label="是否只读" prop="isReadOnly"> <el-select v-model="form.isReadOnly" placeholder="请选择是否只读" style="width: 240px"> <el-option v-for="dict in mdm_common_flag_list" :key="dict.value" :label="dict.label" :value="dict.value" ></el-option> </el-select> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="是否支持排序" prop="sortFlag"> <el-select v-model="form.sortFlag" placeholder="请选择是否支持排序" style="width: 240px"> <el-option v-for="dict in mdm_common_flag_list" :key="dict.value" :label="dict.label" :value="dict.value" ></el-option> </el-select> </el-form-item> </el-col> </el-row> <el-row> <el-col :span="12"> <el-form-item label="数值是否有公差" prop="isTolerance"> <el-select v-model="form.isTolerance" placeholder="请选择数值是否有公差" style="width: 240px"> <el-option v-for="dict in mdm_common_flag_list" :key="dict.value" :label="dict.label" :value="dict.value" ></el-option> </el-select> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="表单排序" prop="orderNum"> <el-input v-model="form.orderNum" placeholder="请输入表单排序" style="width: 240px"/> </el-form-item> </el-col> </el-row> <!-- 高级设置 --> <el-row> <el-col :span="12"> <el-form-item label="弹窗编辑器ID" prop="popupEditId"> <el-input v-model="form.popupEditId" placeholder="请输入弹窗编辑器ID" style="width: 240px"/> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="URL地址" prop="href"> <el-input v-model="form.href" placeholder="请输入URL地址" style="width: 240px"/> </el-form-item> </el-col> </el-row> <el-row> <el-col :span="12"> <el-form-item label="状态" prop="status"> <el-radio-group v-model="form.status"> <el-radio v-for="dict in mdm_common_status_list" :key="dict.value" :value="dict.value" >{{ dict.label }} </el-radio> </el-radio-group> </el-form-item> </el-col> </el-row> </el-form> <template #footer> <div slot="footer" class="dialog-footer"> <el-button type="primary" @click="submitForm">确 定</el-button> <el-button @click="cancel">取 消</el-button> </div> </template> </el-dialog> <!-- 修改命名规则对话框--> <el-dialog title="修改命名规则" v-model="openUrledit" width="500px" append-to-body> <el-form ref="urlformRef" :model="urlform" :rules="urlEditrules" label-width="80px"> <el-form-item label="命名规则" prop="namingrule"> <el-input v-model="urlform.namingrule" placeholder="请输入命名规则"/> </el-form-item> </el-form> <template #footer> <div slot="footer" class="dialog-footer"> <el-button type="primary" @click="submitFormNamingrule">确 定</el-button> <el-button @click="cancelSubmitUrlEdit">取 消</el-button> </div> </template> </el-dialog> <!-- 合法值列表对话框 --> <el-dialog :title="validtitle" v-model="validOpen" width="650px" append-to-body> <el-row :gutter="10" class="mb8"> <el-col :span="1.5"> <el-button type="primary" plain icon="plus" @click="handleValidAdd" v-hasPermi="['mdm:validlist:add']" >新增 </el-button> </el-col> <el-col :span="1.5"> <el-button type="success" plain icon="edit" :disabled="validsingle" @click="handleValidUpdate" v-hasPermi="['mdm:validlist:edit']" >修改 </el-button> </el-col> <el-col :span="1.5"> <el-button type="danger" plain icon="delete" :disabled="validMultiple" @click="handleValidDeleteBtn" v-hasPermi="['mdm:validlist:remove']" >删除 </el-button> </el-col> </el-row> <el-table v-loading="validTableLoading" :data="validlistList" @selection-change="handleValidSelectionChange"> <el-table-column type="selection" width="55" align="center"/> <!-- <el-table-column label="ID" align="center" prop="id" />--> <el-table-column label="合法值名称" align="center" prop="name"/> <el-table-column label="排序" align="center" prop="orderNum"/> <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> <template #default="scope"> <el-button link icon="edit" @click="handleValidUpdate(scope.row)" v-hasPermi="['mdm:validlist:edit']" >修改 </el-button> <el-button link icon="delete" @click="handleValidDelete(scope.row)" v-hasPermi="['mdm:validlist:remove']" >删除 </el-button> </template> </el-table-column> </el-table> <template #footer> <div slot="footer" class="dialog-footer"> <el-button type="primary" @click="validSubmitForm">关 闭</el-button> </div> </template> </el-dialog> <!-- 添加或修改合法值列表对话框 --> <el-dialog :title="validAddtitle" v-model="validAddOpen" width="500px" append-to-body> <el-form ref="validformRef" :model="validform" :rules="validRules" label-width="80px"> <el-form-item label="合法值名称" prop="name" label-width="95px"> <el-input v-model="validform.name" placeholder="请输入合法值名称"/> </el-form-item> <el-form-item label="排序" prop="orderNum" label-width="95px"> <el-input v-model="validform.orderNum" placeholder="请输入排序"/> </el-form-item> </el-form> <template #footer> <div slot="footer" class="dialog-footer"> <el-button type="primary" @click="validAddSubmitForm">确 定</el-button> <el-button @click="validAddCancel">取 消</el-button> </div> </template> </el-dialog> </div> </template> <script setup name="typeAtrr"> import {listTypeAttr, getTypeAttr, delTypeAttr, addTypeAttr, updateTypeAttr} from "@/api/mdm/typeAttr"; import {getMdmMaterialType, updateMdmMaterialType} from "@/api/mdm/mdmMaterialType"; import {treeselect} from "@/api/mdm/mdmMaterialType"; import {listValidlist, getValidlist, delValidlist, addValidlist, updateValidlist} from "@/api/mdm/validlist"; import {getToken} from "@/utils/auth"; import "splitpanes/dist/splitpanes.css" import useAppStore from '@/store/modules/app' import {Splitpanes, Pane} from "splitpanes" const {proxy} = getCurrentInstance(); const appStore = useAppStore() // 使用字典 const { mdm_common_flag_list, mdm_common_status_list, mdm_common_column_type } = proxy.useDict("mdm_common_flag_list", "mdm_common_status_list", "mdm_common_column_type"); // 响应式状态 const loading = ref(true); const showSearch = ref(true); const open = ref(false); const validOpen = ref(false); const validAddOpen = ref(false); const openUrledit = ref(false); const title = ref(''); const validtitle = ref(''); const validAddtitle = ref(''); const total = ref(0); const single = ref(true); const multiple = ref(true); const validsingle = ref(false); const validMultiple = ref(true); const validTableLoading = ref(true); const materiaTypelName = ref(''); const typeOptions = ref([]); const typeAttrList = ref([]); const validlistList = ref([]); const queryFormRef = ref(null); const formRef = ref(null); const validformRef = ref(null); const urlformRef = ref(null); const uploadRef = ref(null); // 查询参数 const queryParams = reactive({ pageNum: 1, pageSize: 10, number: null, name: null, typemgrId: null, dataType: null, length: null, maxVal: null, minVal: null, defaultVal: null, validList: null, enumerateId: null, enumerateTable: null, unit: null, isNull: null, popupEditId: null, href: null, isQuery: null, isShowForm: null, isShowList: null, isReadOnly: null, orderNum: null, sortFlag: null, isTolerance: null, regularCheck: null, status: null, }); // 表单数据 const data = reactive({ form: { id: null, number: null, name: null, typemgrId: null, dataType: null, length: null, maxVal: null, minVal: null, defaultVal: null, validList: null, enumerateId: null, enumerateTable: null, unit: null, isNull: null, popupEditId: null, href: null, isQuery: null, isShowForm: null, isShowList: null, isReadOnly: null, orderNum: null, sortFlag: null, isTolerance: null, regularCheck: null, status: null }, //合法值 validform: { id: null, attributeId: null, name: null, orderNum: null, }, //命名规则 urlform: { id: null, namingrule: null, } }); const {form, validform, urlform} = toRefs(data); // 上传配置 const upload = reactive({ open: false, title: "", isUploading: false, updateSupport: 0, headers: {Authorization: "Bearer " + getToken()}, url: import.meta.env.VITE_APP_BASE_API + "/mdm/typeAttr/importData" }); // 选中ID集合 const ids = ref([]); const validIds = ref([]); // 当前选中属性行 const selectedAttrRow = ref(null); // 表单验证规则 const rules = reactive({ number: [{required: true, message: "编号不能为空", trigger: "blur"}], name: [{required: true, message: "名称不能为空", trigger: "blur"}], typemgrId: [{required: true, message: "类型ID不能为空", trigger: "blur"}], dataType: [{required: true, message: "字段类型不能为空", trigger: "change"}], }); const urlEditrules = reactive({ namingrule: [{required: true, message: "命名规则不能为空", trigger: "blur"}], }); const validRules = reactive({ name: [{required: true, message: "名称不能为空", trigger: "blur"}], }); // 监听物料类型名称变化 watch(materiaTypelName, (val) => { proxy.$refs["treeRef"].filter(val); }); // 获取列表 function getList() { console.log("========属性规则getList======"); loading.value = true; try { listTypeAttr(queryParams).then(response => { console.log("========属性规则getList======", response); typeAttrList.value = response.rows; total.value = response.total; }) } catch (error) { console.error('获取列表失败:', error); // ElMessage.error('获取数据失败'); } finally { loading.value = false; } }; function resetFormState() { form.value = { id: null, number: null, name: null, typemgrId: null, dataType: null, length: null, maxVal: null, minVal: null, defaultVal: null, validList: null, enumerateId: null, enumerateTable: null, unit: null, isNull: null, popupEditId: null, href: null, isQuery: null, isShowForm: null, isShowList: null, isReadOnly: null, orderNum: null, sortFlag: null, isTolerance: null, regularCheck: null, status: null }; proxy.resetForm("formRef"); }; function resetValidAddForm() { validform.value = { id: null, attributeId: null, name: null, orderNum: null } proxy.resetForm("validformRef"); }; function resetUrlForm() { urlform.value = { id: null, namingrule: null } proxy.resetForm("urlformRef"); }; function handleQuery() { queryParams.pageNum = 1; getList(); }; function resetQuery() { proxy.resetForm("queryForm"); handleQuery(); }; function handleSelectionChange(selection) { ids.value = selection.map(item => item.id); single.value = selection.length != 1; multiple.value = !selection.length; }; function handleAdd() { resetFormState(); // getTreeselect(); open.value = true; title.value = "添加属性规则"; }; function handleUpdate(row) { resetFormState(); // getTreeselect() const id = row.id || ids.value; getTypeAttr(id).then(response => { open.value = true; title.value = "修改属性规则"; form.value = response.data; }); }; function submitForm() { proxy.$refs["formRef"].validate(valid => { if (valid) { if (form.value.id != null) { updateTypeAttr(form.value).then(response => { proxy.$modal.msgSuccess("修改成功"); open.value = false; getList(); }); } else { // console.log(form.value); addTypeAttr(form.value).then(response => { proxy.$modal.msgSuccess("新增成功"); open.value = false; getList(); }); } } }) }; function cancel() { open.value = false; resetFormState(); }; function handleDelete(row) { // console.log('删除ids', ids.value); const delIds = row.id || ids.value; proxy.$modal.confirm('是否确认删除属性规则编号为"' + delIds + '"的数据项?').then(function () { return delTypeAttr(delIds); }).then(() => { getList(); proxy.$modal.msgSuccess("删除成功"); }).catch(() => { }); }; function handleExport() { proxy.download('mdm/typeAttr/export', { ...queryParams.value }, `typeAttr_${new Date().getTime()}.xlsx`) }; function filterNode(value, data) { if (!value) return true; return data.label.includes(value); }; function handleNodeClick(data) { queryParams.typemgrId = data.id; handleQuery(); }; function getTreeselect() { const response = treeselect().then(response => { console.log('获取树形数据成功:', response); typeOptions.value = response.data; }); }; function eidtValid(row) { selectedAttrRow.value = row; getValidDataList(row); }; function getValidDataList(row) { validOpen.value = true; validTableLoading.value = true; try { const query = { pageNum: 1, pageSize: 1000, attributeId: row.id }; listValidlist(query).then(response => { // console.log('获取合法值列表成功:', response); validlistList.value = response.rows; }); } catch (error) { // console.error('获取合法值列表失败:', error); // ElMessage.error('获取合法值列表失败'); } finally { validTableLoading.value = false; } }; function validSubmitForm() { validOpen.value = false; }; function handleValidAdd() { validAddOpen.value = true; validAddtitle.value = "添加合法值"; resetValidAddForm(); }; function validAddSubmitForm() { console.log('添加合法值', selectedAttrRow.value.id); validform.value.attributeId = selectedAttrRow.value.id proxy.$refs["validformRef"].validate(valid => { if (valid) { if (validform.value.id != null) { updateValidlist(validform.value).then(response => { proxy.$modal.msgSuccess("修改成功"); validAddOpen.value = false; getValidDataList(selectedAttrRow.value); }); } else { addValidlist(validform.value).then(response => { proxy.$modal.msgSuccess("新增成功"); validAddOpen.value = false; getValidDataList(selectedAttrRow.value); }); } } }); }; function validAddCancel() { validAddOpen.value = false; resetValidAddForm(); }; function handleValidSelectionChange(selection) { validIds.value = selection.map(item => item.id); validsingle.value = selection.length !== 1; validMultiple.value = !selection.length; }; function handleValidDeleteBtn() { const ids = validIds.value; proxy.$modal.confirm('是否确认删除合法值列表编号为"' + ids + '"的数据项?').then(function () { return delValidlist(ids); }).then(() => { proxy.$modal.msgSuccess("删除成功"); getValidDataList(selectedAttrRow.value); }).catch(() => { }); }; function handleValidDelete(row) { const ids = row.id; proxy.$modal.confirm('是否确认删除合法值列表编号为"' + ids + '"的数据项?').then(function () { return delValidlist(ids); }).then(() => { getValidDataListByAttrId(row.attributeId); proxy.$modal.msgSuccess("删除成功"); }).catch(() => { }); }; function getValidDataListByAttrId(attrId) { const query = { pageNum: 1, pageSize: 1000, attributeId: attrId }; try { listValidlist(query).then(response => { validlistList.value = response.rows; }); } catch (error) { console.error('获取合法值列表失败:', error); } }; function handleUrlUpdate() { // openUrledit.value = true; resetUrlForm(); // console.log('修改命名规则'); const currentNode = proxy.$refs.treeRef.getCurrentNode(); // const currentNode = treeRef.value.getCurrentNode(); if (!currentNode) { proxy.$modal.msgWarning("请先在左侧树中选择一个物料类型"); return; } console.log('进入到', currentNode.id); getMdmMaterialType(currentNode.id).then(response => { openUrledit.value = true; // console.log('获取数据成功:', response); urlform.value = response.data; }); }; function submitFormNamingrule() { proxy.$refs["urlformRef"].validate(valid => { if (valid) { if (urlform.value.id != null) { updateMdmMaterialType(urlform.value).then(response => { proxy.$modal.msgSuccess("修改成功"); openUrledit.value = false; }); } } }); }; function cancelSubmitUrlEdit() { openUrledit.value = false; resetUrlForm(); }; function handleImport() { upload.title = "导入属性"; upload.open = true; }; function importTemplate() { // 下载模板实现(需根据实际API调整) console.log('下载模板'); }; function handleFileUploadProgress() { upload.isUploading = true; }; function handleFileSuccess(response) { upload.open = false; upload.isUploading = false; if (uploadRef.value) { uploadRef.value.clearFiles(); } ElMessageBox.alert( `<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>${response.msg}</div>`, "导入结果", {dangerouslyUseHTMLString: true} ); getList(); }; function submitFileForm() { if (uploadRef.value) { uploadRef.value.submit(); } }; // 编辑合法值 function handleValidUpdate(row) { resetValidAddForm() const id = row.id || validIds.value getValidlist(id).then(response => { validform.value = response.data; validAddOpen.value = true; title.value = "修改合法值列表"; }); } getTreeselect() getList() </script> 只有首次能够进入 ,再次进入会是空白 ,而且其他菜单也显示不出来了
最新发布
07-10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值