Procházet zdrojové kódy

feat: 新增常用工具管理页;物料管理新增导入功能

mnisting před 5 měsíci
rodič
revize
d84d4bc238

+ 99 - 86
src/router/index.js

@@ -1,6 +1,6 @@
-import { createWebHistory, createRouter } from 'vue-router'
+import { createWebHistory, createRouter } from "vue-router";
 /* Layout */
-import Layout from '@/layoutMain'
+import Layout from "@/layoutMain";
 
 /**
  * Note: 路由配置项
@@ -27,40 +27,40 @@ import Layout from '@/layoutMain'
 // 公共路由
 export const constantRoutes = [
   {
-    path: '/redirect',
+    path: "/redirect",
     component: Layout,
     hidden: true,
     children: [
       {
-        path: '/redirect/:path(.*)',
-        component: () => import('@/views/redirect/index.vue')
-      }
-    ]
+        path: "/redirect/:path(.*)",
+        component: () => import("@/views/redirect/index.vue"),
+      },
+    ],
   },
   {
-    path: '/login',
-    component: () => import('@/views/login'),
-    hidden: true
+    path: "/login",
+    component: () => import("@/views/login"),
+    hidden: true,
   },
   {
-    path: '/register',
-    component: () => import('@/views/register'),
-    hidden: true
+    path: "/register",
+    component: () => import("@/views/register"),
+    hidden: true,
   },
   {
     path: "/:pathMatch(.*)*",
-    component: () => import('@/views/error/404'),
-    hidden: true
+    component: () => import("@/views/error/404"),
+    hidden: true,
   },
   {
-    path: '/401',
-    component: () => import('@/views/error/401'),
-    hidden: true
+    path: "/401",
+    component: () => import("@/views/error/401"),
+    hidden: true,
   },
   {
-    path: '/',
+    path: "/",
     component: Layout,
-    redirect: '/material',
+    redirect: "/material",
     // children: [
     //   {
     //     path: 'index',
@@ -72,129 +72,142 @@ export const constantRoutes = [
   },
 
   {
-    path: '/',
+    path: "/",
     component: Layout,
-    meta: { title: '', icon: ''},
+    meta: { title: "", icon: "" },
     children: [
       {
-        path: 'material',
-        component: () => import('@/views/material/index'),
-        name: 'Material',
-        meta: { noCache: true , title: '工具管理', icon: 'tool' },
+        path: "material",
+        component: () => import("@/views/material/index"),
+        name: "Material",
+        meta: { noCache: true, title: "工具管理", icon: "tool" },
       },
-    ]
+    ],
   },
   {
-    path: '/',
+    path: "/",
     component: Layout,
-    meta: { title: '', icon: ''},
+    meta: { title: "", icon: "" },
     children: [
       {
-        path: 'classification',
-        component: () => import('@/views/classification/index'),
-        name: 'Classification',
-        meta: { noCache: true ,title: '分类管理', icon: 'tree-table'}
+        path: "classification",
+        component: () => import("@/views/classification/index"),
+        name: "Classification",
+        meta: { noCache: true, title: "分类管理", icon: "tree-table" },
       },
-    ]
+    ],
   },
   {
-    path: '/',
+    path: "/",
     component: Layout,
-    meta: { title: '', icon: ''},
+    meta: { title: "", icon: "" },
     hidden: true,
     children: [
       {
-        path: 'toolsMaterial',
-        component: () => import('@/views/toolsMaterial/index'),
-        name: 'toolsMaterial',
-        meta: { title: '物料管理', icon: 'component' },
+        path: "toolsMaterial",
+        component: () => import("@/views/toolsMaterial/index"),
+        name: "toolsMaterial",
+        meta: { title: "物料管理", icon: "component" },
+      },
+    ],
+  },
+  {
+    path: "/",
+    component: Layout,
+    meta: { title: "", icon: "" },
+    children: [
+      {
+        path: "commonTools",
+        component: () => import("@/views/commonTools/index"),
+        name: "CommonTools",
+        meta: { noCache: true, title: "常用工具管理", icon: "system" },
       },
-    ]
+    ],
   },
-]
+];
 
 // 动态路由,基于用户权限动态去加载
 export const dynamicRoutes = [
   {
-    path: '/system/user-auth',
+    path: "/system/user-auth",
     component: Layout,
     hidden: true,
-    permissions: ['system:user:edit'],
+    permissions: ["system:user:edit"],
     children: [
       {
-        path: 'role/:userId(\\d+)',
-        component: () => import('@/views/system/user/authRole'),
-        name: 'AuthRole',
-        meta: { title: '分配角色', activeMenu: '/system/user' }
-      }
-    ]
+        path: "role/:userId(\\d+)",
+        component: () => import("@/views/system/user/authRole"),
+        name: "AuthRole",
+        meta: { title: "分配角色", activeMenu: "/system/user" },
+      },
+    ],
   },
   {
-    path: '/system/role-auth',
+    path: "/system/role-auth",
     component: Layout,
     hidden: true,
-    permissions: ['system:role:edit'],
+    permissions: ["system:role:edit"],
     children: [
       {
-        path: 'user/:roleId(\\d+)',
-        component: () => import('@/views/system/role/authUser'),
-        name: 'AuthUser',
-        meta: { title: '分配用户', activeMenu: '/system/role' }
-      }
-    ]
+        path: "user/:roleId(\\d+)",
+        component: () => import("@/views/system/role/authUser"),
+        name: "AuthUser",
+        meta: { title: "分配用户", activeMenu: "/system/role" },
+      },
+    ],
   },
   {
-    path: '/system/dict-data',
+    path: "/system/dict-data",
     component: Layout,
     hidden: true,
-    permissions: ['system:dict:list'],
+    permissions: ["system:dict:list"],
     children: [
       {
-        path: 'index/:dictId(\\d+)',
-        component: () => import('@/views/system/dict/data'),
-        name: 'Data',
-        meta: { title: '字典数据', activeMenu: '/system/dict' }
-      }
-    ]
+        path: "index/:dictId(\\d+)",
+        component: () => import("@/views/system/dict/data"),
+        name: "Data",
+        meta: { title: "字典数据", activeMenu: "/system/dict" },
+      },
+    ],
   },
   {
-    path: '/monitor/job-log',
+    path: "/monitor/job-log",
     component: Layout,
     hidden: true,
-    permissions: ['monitor:job:list'],
+    permissions: ["monitor:job:list"],
     children: [
       {
-        path: 'index/:jobId(\\d+)',
-        component: () => import('@/views/monitor/job/log'),
-        name: 'JobLog',
-        meta: { title: '调度日志', activeMenu: '/monitor/job' }
-      }
-    ]
+        path: "index/:jobId(\\d+)",
+        component: () => import("@/views/monitor/job/log"),
+        name: "JobLog",
+        meta: { title: "调度日志", activeMenu: "/monitor/job" },
+      },
+    ],
   },
   {
-    path: '/tool/gen-edit',
+    path: "/tool/gen-edit",
     component: Layout,
     hidden: true,
-    permissions: ['tool:gen:edit'],
+    permissions: ["tool:gen:edit"],
     children: [
       {
-        path: 'index/:tableId(\\d+)',
-        component: () => import('@/views/tool/gen/editTable'),
-        name: 'GenEdit',
-        meta: { title: '修改生成配置', activeMenu: '/tool/gen' }
-      }
-    ]
-  }
-]
+        path: "index/:tableId(\\d+)",
+        component: () => import("@/views/tool/gen/editTable"),
+        name: "GenEdit",
+        meta: { title: "修改生成配置", activeMenu: "/tool/gen" },
+      },
+    ],
+  },
+];
 
 const router = createRouter({
   history: createWebHistory(),
   routes: constantRoutes,
   scrollBehavior(to, from, savedPosition) {
     if (savedPosition) {
-      return savedPosition
+      return savedPosition;
     } else {
-      return { top: 0 }
+      return { top: 0 };
     }
   },
 });

+ 100 - 0
src/views/commonTools/hooks/useSubmitForm.js

@@ -0,0 +1,100 @@
+import { toolAdd, toolUpdate } from "@/api/bussiness";
+// 提交表单的 hooks
+const useSubmitForm = (getList) => {
+  const { proxy } = getCurrentInstance();
+  // 弹窗是否打开
+  const open = ref(false);
+  // 弹窗的标题
+  const title = ref("");
+  // 表单的 loading 状态
+  const formLoading = ref(false);
+  // 提交表单loading
+  const submitLoading = ref(false);
+  const data = reactive({
+    // 表单数据
+    form: {
+      toolName: undefined,
+    },
+    // 表单规则
+    rules: {
+      toolName: [
+        { required: true, message: "工具名称不能为空", trigger: "blur" },
+      ],
+    },
+  });
+
+  const { form, rules } = toRefs(data);
+
+  // 表单重置
+  const reset = () => {
+    form.value = {
+      toolName: undefined,
+    };
+    proxy.resetForm("toolTypesRef");
+  };
+
+  // 更新工具
+  const updateToolType = () => {
+    const baseParams = {
+      ...form.value,
+    };
+    toolUpdate(baseParams)
+      .then((res) => {
+        proxy.$modal.msgSuccess("修改成功");
+        open.value = false;
+        getList();
+      })
+      .finally(() => {
+        submitLoading.value = false;
+      });
+  };
+
+  // 添加工具
+  const addToolType = () => {
+    const params = {
+      ...form.value,
+    };
+    toolAdd(params)
+      .then((res) => {
+        proxy.$modal.msgSuccess("新增成功");
+        submitLoading.value = false;
+        open.value = false;
+        getList();
+      })
+      .finally(() => {
+        submitLoading.value = false;
+      });
+  };
+
+  // 提交按钮
+  const submitForm = () => {
+    proxy.$refs["toolTypesRef"].validate((valid) => {
+      if (valid) {
+        submitLoading.value = true;
+        if (form.value.id != undefined) {
+          updateToolType();
+        } else {
+          addToolType();
+        }
+      }
+    });
+  };
+  // 取消按钮
+  const cancel = () => {
+    open.value = false;
+    reset();
+  };
+  return {
+    title,
+    open,
+    form,
+    rules,
+    formLoading,
+    submitLoading,
+    reset,
+    submitForm,
+    cancel,
+  };
+};
+
+export default useSubmitForm;

+ 83 - 0
src/views/commonTools/hooks/useTable.js

@@ -0,0 +1,83 @@
+import { getToolDetailById, toolDelete } from "@/api/bussiness";
+
+// 数据表格的 hooks
+const useTable = (getList, reset, open, title, form, formLoading) => {
+  const { proxy } = getCurrentInstance();
+  // 表格数据列表
+  const toolList = ref([]);
+  // 表格loading状态
+  const loading = ref(true);
+  // 表格勾选框选中的 id 列表
+  const ids = ref([]);
+  // 多个勾选时为 true 其他为 false
+  const single = ref(true);
+  // 只要有勾选项就为 true
+  const multiple = ref(true);
+
+  // 多选框选中数据
+  const handleSelectionChange = (selection) => {
+    ids.value = selection.map((item) => item.id);
+    single.value = selection.length != 1;
+    multiple.value = !selection.length;
+  };
+
+  // 新增按钮操作
+  const handleAdd = (row) => {
+    reset();
+    open.value = true;
+    title.value = "添加工具";
+  };
+
+  // 点击表格上的修改按钮
+  // const handleSelecterUpdate = () => {
+  //   const targetId = ids.value[0];
+  //   formLoading.value = true;
+  //   getToolDetailById(targetId).then((res) => {
+  //     handleUpdate(res.data);
+  //   });
+  // };
+
+  // 修改按钮操作
+  const handleUpdate = (row) => {
+    reset();
+    open.value = true;
+    formLoading.value = true;
+    getToolDetailById(row.id)
+      .then((res) => {
+        form.value = {
+          id: row.id,
+          toolName: res.data.toolName,
+        };
+        title.value = "修改工具";
+      })
+      .finally(() => (formLoading.value = false));
+  };
+  // 删除按钮操作
+  const handleDelete = (row) => {
+    const toolIds = row.id || ids.value;
+    proxy.$modal
+      .confirm("是否确认删除该常用工具?")
+      .then(function () {
+        return toolDelete(toolIds);
+      })
+      .then(() => {
+        getList();
+        proxy.$modal.msgSuccess("删除成功");
+      })
+      .catch(() => {});
+  };
+
+  return {
+    toolList,
+    loading,
+    single,
+    multiple,
+    handleAdd,
+    // handleSelecterUpdate,
+    handleUpdate,
+    handleDelete,
+    handleSelectionChange,
+  };
+};
+
+export default useTable;

+ 140 - 0
src/views/commonTools/index.vue

@@ -0,0 +1,140 @@
+<template>
+  <div class="app-container">
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button type="primary" plain icon="Plus" @click="handleAdd"
+          >新增</el-button
+        >
+      </el-col>
+      <!-- <el-col :span="1.5">
+        <el-button
+          type="success"
+          plain
+          icon="Edit"
+          :disabled="single"
+          @click="handleSelecterUpdate"
+          >修改</el-button
+        >
+      </el-col> -->
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="Delete"
+          :disabled="multiple"
+          @click="handleDelete"
+          >删除</el-button
+        >
+      </el-col>
+      <right-toolbar :search="false" @queryTable="getList"></right-toolbar>
+    </el-row>
+    <el-table
+      v-loading="loading"
+      :data="toolList"
+      row-key="id"
+      @selection-change="handleSelectionChange"
+    >
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="工具名称" prop="toolName" />
+      <el-table-column
+        label="操作"
+        width="220"
+        align="center"
+        class-name="small-padding fixed-width"
+      >
+        <template #default="scope">
+          <el-button
+            link
+            type="primary"
+            icon="Edit"
+            @click="handleUpdate(scope.row)"
+            >修改</el-button
+          >
+          <el-button
+            link
+            type="danger"
+            icon="Delete"
+            @click="handleDelete(scope.row)"
+            >删除</el-button
+          >
+        </template>
+      </el-table-column>
+    </el-table>
+    <!-- 添加或修改弹窗 -->
+    <el-dialog
+      :title="title"
+      v-model="open"
+      width="500px"
+      append-to-body
+      :close-on-click-modal="false"
+    >
+      <el-form
+        ref="toolTypesRef"
+        :model="form"
+        :rules="rules"
+        label-width="80px"
+        v-loading="formLoading"
+      >
+        <el-form-item label="工具名称" prop="toolName">
+          <el-input v-model="form.toolName" placeholder="请输入工具名称" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <div style="text-align: center">
+          <el-button type="primary" :loading="submitLoading" @click="submitForm"
+            >确 定</el-button
+          >
+          <el-button @click="cancel">取 消</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup name="CommonTools">
+import useSubmitForm from "./hooks/useSubmitForm.js";
+import useTable from "./hooks/useTable.js";
+import { listTools } from "@/api/bussiness";
+
+// 查询分类列表
+const getList = (params) => {
+  loading.value = true;
+  listTools({
+    ...params,
+    pageNum: 1,
+    pageSize: 10,
+    level: "3",
+    delFlag: "0",
+  }).then((res) => {
+    toolList.value = res.rows;
+    loading.value = false;
+  });
+};
+
+// 提交表单
+const {
+  title,
+  open,
+  form,
+  rules,
+  formLoading,
+  submitLoading,
+  reset,
+  submitForm,
+  cancel,
+} = useSubmitForm(getList);
+// 表格列表
+const {
+  toolList,
+  loading,
+  single,
+  multiple,
+  handleAdd,
+  handleUpdate,
+  // handleSelecterUpdate,
+  handleDelete,
+  handleSelectionChange,
+} = useTable(getList, reset, open, title, form, formLoading);
+
+getList();
+</script>

+ 102 - 0
src/views/toolsMaterial/index.vue

@@ -117,6 +117,11 @@
             >删除</el-button
           >
         </el-col>
+        <el-col :span="1.5">
+          <el-button type="primary" plain icon="Delete" @click="handleImport"
+            >导入</el-button
+          >
+        </el-col>
         <right-toolbar
           v-model:showSearch="showSearch"
           @queryTable="handleQuery"
@@ -207,15 +212,62 @@
         </div>
       </template>
     </el-dialog>
+
+    <!-- 导入弹框 -->
+    <el-dialog
+      :title="upload.title"
+      v-model="upload.open"
+      width="50vw"
+      append-to-body
+      :close-on-click-modal="false"
+    >
+      <el-upload
+        ref="uploadRef"
+        :limit="1"
+        accept=".xlsx, .xls"
+        :headers="upload.headers"
+        :action="upload.url"
+        :disabled="upload.isUploading"
+        :on-progress="handleFileUploadProgress"
+        :on-success="handleFileSuccess"
+        :auto-upload="false"
+        drag
+      >
+        <el-icon class="el-icon--upload"><upload-filled /></el-icon>
+        <div class="el-upload__text">
+          将文件拖到此处,或
+          <em>点击上传</em>
+        </div>
+        <div class="el-upload__tip" slot="tip">
+          <el-link
+            type="warning"
+            style="font-size: 13px; margin: 10px"
+            @click="importTemplate"
+            >下载模板</el-link
+          >
+        </div>
+        <div class="el-upload__tip" style="color: red" slot="tip">
+          提示:仅允许导入“xls”或“xlsx”格式文件!
+        </div>
+      </el-upload>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitFileForm">确 定</el-button>
+          <el-button @click="upload.open = false">取 消</el-button>
+        </div>
+      </template>
+    </el-dialog>
   </div>
 </template>
 
 <script setup name="ToolsMaterial">
+import { reactive } from "vue";
 import useInit from "./hooks/useInit";
 import useSearchForm from "./hooks/useSearchForm.js";
 import useSubmitForm from "./hooks/useSubmitForm.js";
 import useTable from "./hooks/useTable.js";
 import { listFileByBasisId } from "@/api/bussiness";
+import { getToken } from "@/utils/auth";
 
 const { proxy } = getCurrentInstance();
 
@@ -229,6 +281,20 @@ const pager = ref({
 // 表格总数据量
 const total = ref(0);
 
+// 用户导入参数
+const upload = reactive({
+  // 是否显示弹出层(用户导入)
+  open: false,
+  // 弹出层标题(用户导入)
+  title: "导入",
+  // 是否禁用上传
+  isUploading: false,
+  // 设置上传的请求头部
+  headers: { Authorization: "Bearer " + getToken() },
+  // 上传的地址
+  url: import.meta.env.VITE_APP_BASE_API + "/system/user/importData",
+});
+
 // 查询当前工具的物料列表。
 const getList = (params = {}) => {
   loading.value = true;
@@ -277,6 +343,42 @@ watch(
     immediate: true,
   }
 );
+
+// 导入
+const handleImport = () => {
+  upload.title = "物料导入";
+  upload.open = true;
+};
+// 下载模版
+const importTemplate = () => {
+  proxy.download(
+    "system/user/importTemplate",
+    {},
+    `user_template_${new Date().getTime()}.xlsx`
+  );
+};
+// 文件上传中
+const handleFileUploadProgress = (event, file, fileList) => {
+  upload.isUploading = true;
+};
+// 文件上传成功
+const handleFileSuccess = (response, file, fileList) => {
+  upload.open = false;
+  upload.isUploading = false;
+  proxy.$refs["uploadRef"].handleRemove(file);
+  proxy.$alert(
+    "<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" +
+      response.msg +
+      "</div>",
+    "导入结果",
+    { dangerouslyUseHTMLString: true }
+  );
+  getList();
+};
+// 提交上传文件
+const submitFileForm = () => {
+  proxy.$refs["uploadRef"].submit();
+};
 </script>
 
 <style lang="scss" scoped>