chenrui  2 years ago
parent
commit
00a78c8d9a

+ 2 - 0
package-lock.json

@@ -10,6 +10,7 @@
       "license": "MIT",
       "dependencies": {
         "@element-plus/icons-vue": "^2.0.9",
+        "@types/lodash": "^4.14.186",
         "axios": "0.21.3",
         "blueimp-md5": "^2.19.0",
         "echarts": "5.3.2",
@@ -18,6 +19,7 @@
         "file-saver": "^2.0.5",
         "js-cookie": "^3.0.1",
         "js-error-collection": "^1.0.7",
+        "lodash": "^4.17.21",
         "mitt": "^3.0.0",
         "moment-mini": "2.22.1",
         "nprogress": "0.2.0",

+ 14 - 7
src/router/routes/routes-file-two.ts

@@ -1,14 +1,21 @@
-import Layout from '@/layout'
+import Layout from "@/layout";
 
 const HomeRoutes = {
-  path: '/systemSettings',
+  path: "/systemSettings",
   component: Layout,
-  name: 'systemSettings',
-  redirect: '/systemSettings',
+  name: "systemSettings",
+  redirect: "/systemSettings",
   //using el svg icon, the elSvgIcon first when at the same time using elSvgIcon and icon
-  meta: { title: '系统配置', elSvgIcon: 'Fold', breadcrumb: false },
+  meta: { title: "系统配置", elSvgIcon: "Fold", breadcrumb: false },
   children: [
+    {
+      path: "/systemSettings/systemconfiguration",
+      name: "FlightQuery",
+      meta: { title: "菜单管理" },
+      component: () =>
+        import("@/views/systemSettings/systemconfiguration/index.vue"),
+    },
   ],
-}
+};
 
-export default [HomeRoutes]
+export default [HomeRoutes];

+ 760 - 0
src/views/systemSettings/systemconfiguration/index.vue

@@ -0,0 +1,760 @@
+<template>
+  <div class="airportInfo scroll-y">
+    <div class="wrap">
+      <Minheader :is-auth="true" :is-statuser="true" @addForm="addForm">
+        <template #header>
+          <div class="status flex-wrap">
+            <div class="manageTitle">菜单管理</div>
+          </div>
+        </template></Minheader
+      >
+      <div class="app-containers">
+        <el-table
+          :data="tableData"
+          style="width: 100%"
+          :row-style="rowStyle"
+          :row-class-name="tableRowClassName"
+          :cell-class-name="cellClassName"
+          :row-key="
+            props.tableProperty.rowKey
+              ? props.tableProperty.rowKey
+              : tablePropertyDefault.rowKey
+          "
+          :height="
+            props.tableProperty.height
+              ? props.tableProperty.height
+              : tablePropertyDefault.height
+          "
+          :max-height="
+            props.tableProperty.maxHeight
+              ? props.tableProperty.maxHeight
+              : tablePropertyDefault.maxHeight
+          "
+          :stripe="
+            props.tableProperty.stripe
+              ? props.tableProperty.stripe
+              : tablePropertyDefault.stripe
+          "
+          :border="
+            props.tableProperty.border
+              ? props.tableProperty.border
+              : tablePropertyDefault.border
+          "
+          :highlight-current-row="
+            props.tableProperty.highlightCurrentRow
+              ? props.tableProperty.highlightCurrentRow
+              : tablePropertyDefault.highlightCurrentRow
+          "
+          :header-cell-class-name="
+            props.tableProperty.headerRowClassName
+              ? props.tableProperty.headerRowClassName
+              : tablePropertyDefault.headerRowClassName
+          "
+          :tooltip-effect="
+            props.tableProperty.tooltipEffect
+              ? props.tableProperty.tooltipEffect
+              : tablePropertyDefault.tooltipEffect
+          "
+          :show-summary="
+            props.tableProperty.showSummary
+              ? props.tableProperty.showSummary
+              : tablePropertyDefault.showSummary
+          "
+        >
+          <el-table-column label="菜单名称" class="infinite-list-item">
+            <template #default="scope">
+              <div style="display: flex; align-items: center">
+                <el-icon><timer /></el-icon>
+                <span style="margin-left: 10px">{{ scope.row.menuName }}</span>
+              </div>
+            </template>
+          </el-table-column>
+          <el-table-column
+            prop="menuCode"
+            label="菜单编码"
+            class="infinite-list-item"
+          />
+          <el-table-column
+            prop="treeSort"
+            label="排序"
+            class="infinite-list-item"
+          />
+          <el-table-column
+            prop="menuType"
+            label="菜单类型"
+            class="infinite-list-item"
+          >
+            <template #default="scope">
+              <div class="catalogue">
+                <span>{{ scope.row.menuType }}</span>
+              </div>
+            </template>
+          </el-table-column>
+          <el-table-column
+            prop="visible"
+            label="可见"
+            class="infinite-list-item"
+          />
+          <el-table-column
+            prop="perms"
+            label="权限标识"
+            class="infinite-list-item"
+          />
+          <el-table-column
+            prop="component"
+            label="组件路径"
+            class="infinite-list-item"
+          />
+          <el-table-column label="状态" class="infinite-list-item">
+            <template #default="scope">
+              <div style="display: flex; align-items: center">
+                <div class="log"></div>
+                <span style="margin-left: 10px">{{ scope.row.status }}</span>
+              </div>
+            </template>
+          </el-table-column>
+          <el-table-column
+            v-if="tableBtnGroup.length"
+            label="操作"
+            width="300px"
+            :align="props.tableColumnProperty.align"
+          >
+            <template #default="scope">
+              <el-button
+                v-for="(btn, index) in tableBtnGroup"
+                :key="index"
+                size="small"
+                @click="handleClick(scope.$index, scope.row, btn.param)"
+                :class="btn.className"
+                >{{ btn.name }}</el-button
+              >
+            </template>
+          </el-table-column>
+        </el-table>
+        <!-- <DataTable
+          :tableHeader="state.list"
+          :tableData="tableData"
+          :tableBtnGroup="tableBtnGroup"
+          :tableProperty="{ rowKey: 'ID' }"
+          @btnClick="btnClick"
+        /> -->
+      </div>
+      <Dialog
+        width="628px"
+        :flag="flag"
+        :type="type"
+        :msgTitle="msgTitle"
+        @resetForm="resetForm"
+        @delRest="delRest"
+      >
+        <div class="diacont">
+          <el-form
+            :model="tableForm"
+            :rules="formRules"
+            ref="systemconfiguration"
+          >
+            <el-row :gutter="24">
+              <el-col :span="12">
+                <el-form-item label="上级菜单" size="default">
+                  <el-select
+                    style="width: 100%"
+                    v-model="tableForm.parentId"
+                    class="input-shadow"
+                    filterable
+                    default-first-option
+                    clearable
+                    placeholder="主目录"
+                  >
+                    <el-option
+                      v-for="item in tableOptionser"
+                      :key="item.v"
+                      :label="item.k"
+                      :value="item.v"
+                    >
+                    </el-option>
+                  </el-select>
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item
+                  label="菜单类型"
+                  size="default"
+                  :rules="formRules.isNotNull"
+                  prop="menuType"
+                >
+                  <el-radio-group v-model="tableForm.menuType" size="default">
+                    <el-radio-button label="目录" />
+                    <el-radio-button label="菜单" />
+                    <el-radio-button label="按钮" />
+                  </el-radio-group>
+                </el-form-item>
+              </el-col>
+              <el-col>
+                <el-form-item label="图标" size="default">
+                  <el-select
+                    style="width: 100%"
+                    v-model="tableForm.icon"
+                    class="input-shadow"
+                    filterable
+                    default-first-option
+                    clearable
+                    placeholder=""
+                  >
+                    <el-option
+                      v-for="item in tableOptionser"
+                      :key="item.v"
+                      :label="item.k"
+                      :value="item.v"
+                    >
+                    </el-option>
+                  </el-select>
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item
+                  label="菜单编码"
+                  size="default"
+                  :rules="formRules.isNotNull"
+                  prop="menuCode"
+                >
+                  <el-input
+                    v-model="tableForm.menuCode"
+                    placeholder="请输入菜单编码"
+                  />
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item
+                  label="菜单名称"
+                  size="default"
+                  :rules="formRules.isNotNull"
+                  prop="menuName"
+                >
+                  <el-input
+                    v-model="tableForm.menuName"
+                    placeholder="请输入菜单名称"
+                  />
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item
+                  label="排序"
+                  size="default"
+                  :rules="formRules.isNotNull"
+                  prop="treeSort"
+                >
+                  <el-input v-model="tableForm.treeSort" placeholder="" />
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item
+                  label="是否外链"
+                  size="default"
+                  :rules="formRules.isNotNull"
+                  prop="isFrame"
+                >
+                  <el-radio-group v-model="tableForm.isFrame" size="default">
+                    <el-radio-button label="是" />
+                    <el-radio-button label="否" />
+                  </el-radio-group>
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item
+                  label="路由地址"
+                  size="default"
+                  :rules="formRules.isNotNull"
+                  prop="path"
+                >
+                  <el-input v-model="tableForm.path" placeholder="" />
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item
+                  label="是否显示"
+                  size="default"
+                  :rules="formRules.isNotNull"
+                  prop="visible"
+                >
+                  <el-radio-group v-model="tableForm.visible" size="default">
+                    <el-radio-button label="是" />
+                    <el-radio-button label="否" />
+                  </el-radio-group>
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item
+                  label="组件路径"
+                  size="default"
+                  :rules="formRules.isNotNull"
+                  prop="component"
+                >
+                  <el-input v-model="tableForm.component" placeholder="" />
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item
+                  label="权限标识"
+                  size="default"
+                  :rules="formRules.isNotNull"
+                  prop="perms"
+                >
+                  <el-input v-model="tableForm.perms" placeholder="" />
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item
+                  label="状态"
+                  size="default"
+                  :rules="formRules.isNotNull"
+                  prop="status"
+                >
+                  <el-radio-group v-model="tableForm.status" size="default">
+                    <el-radio-button label="开启" />
+                    <el-radio-button label="关闭" />
+                  </el-radio-group>
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item
+                  label="是否缓存"
+                  size="default"
+                  :rules="formRules.isNotNull"
+                  prop="isCache"
+                >
+                  <el-radio-group v-model="tableForm.isCache" size="default">
+                    <el-radio-button label="缓存" />
+                    <el-radio-button label="不缓存" />
+                  </el-radio-group>
+                </el-form-item>
+              </el-col>
+              <el-col>
+                <el-form-item label="备注" size="default">
+                  <el-input
+                    type="textarea"
+                    v-model="tableForm.remark"
+                    placeholder="请输入备注"
+                  />
+                </el-form-item>
+              </el-col>
+            </el-row>
+          </el-form>
+        </div>
+      </Dialog>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import DataTable from "@/components/tableTemp/index.vue";
+import Minheader from "@/components/minheader/index.vue";
+import Dialog from "@/components/dialog/index.vue";
+import { Timer } from "@element-plus/icons-vue";
+const formRules = useElement().formRules;
+const router = useRouter();
+const props = defineProps({
+  //表格参数
+  tableProperty: {
+    type: Object,
+    default: {
+      height: "100%",
+      maxHeight: "100%",
+      stripe: true,
+      border: true,
+      highlightCurrentRow: false,
+      rowClassName: "rowClass",
+      headerRowClassName: "headerRowClass",
+      tooltipEffect: "light",
+      showSummary: false,
+      rowKey: "",
+    },
+  },
+  //公共表头参数
+  tableColumnProperty: {
+    type: Object,
+    default: {
+      width: "",
+      fixed: "",
+      sortable: false,
+      showOverflowTooltip: false,
+      align: "center",
+      headerAlign: "",
+    },
+  },
+});
+//表格参数
+const tablePropertyDefault = {
+  height: "100%",
+  maxHeight: "100%",
+  stripe: true,
+  border: true,
+  highlightCurrentRow: false,
+  rowClassName: "rowClass",
+  headerRowClassName: "headerRowClass",
+  tooltipEffect: "light",
+  showSummary: false,
+  rowKey: "",
+};
+const tableOptionser = ref([]); //弹窗下拉
+const flag = ref<Boolean>(false); //弹窗开关
+const type = ref<String>(""); //判断是否删除
+const TagsAll = ref<Array>([]);
+const currentval = ref<String>("");
+const TagsAlls = ref<Array>([]);
+const currentvals = ref<String>("");
+const msgTitle = ref<String>("新增登录策略"); //弹窗标题
+const tableColsCopys = reactive<Object>({}); //弹窗
+const tableForm = reactive({
+  parentId: "",
+  menuType: "目录",
+  icon: "",
+  menuCode: "",
+  menuName: "",
+  treeSort: "",
+  isFrame: "否",
+  path: "",
+  visible: "是",
+  component: "",
+  perms: "",
+  status: "关闭",
+  isCache: "不缓存",
+  remark: "",
+}); //弹窗内容
+//列表
+const tableData = ref([
+  {
+    menuName: "测试",
+    menuCode: "测试",
+    treeSort: "测试",
+    menuType: "测试",
+    visible: "测试",
+    perms: "测试",
+    component: "测试",
+    status: "测试",
+  },
+]);
+//表头
+const state = reactive({
+  list: [
+    { label: "名称", key: "name" },
+    { label: "有效日期", key: "china" },
+    { label: "有效时间", key: "englin" },
+    { label: "黑名单", key: "two" },
+    { label: "白名单", key: "three" },
+    { label: "描述", key: "text" },
+  ],
+  listLoading: true,
+});
+const tableBtnGroup = ref([
+  {
+    name: "修改",
+    className: "editBtn",
+    param: 2,
+  },
+  {
+    name: "添加子菜单",
+    className: "editBtn",
+    param: 4,
+  },
+  {
+    name: "删除",
+    className: "delBtn",
+    param: 3,
+  },
+]);
+//新增
+const addForm = () => {
+  msgTitle.value = "新增菜单";
+  flag.value = true;
+  type.value = "";
+};
+//取消
+const resetForm = () => {
+  flag.value = false;
+  tableForm.name = "";
+  tableForm.china = "";
+  tableForm.englin = "";
+  tableForm.two = "";
+  tableForm.three = "";
+  tableForm.text = "";
+  TagsAll.value = [];
+  TagsAlls.value = [];
+};
+//编辑
+// const editDialog = (data) => {
+//   msgTitle.value = "编辑航司信息维护";
+//   flag.value = true;
+//   type.value = "";
+//   tableForm.name = data.name;
+//   tableForm.china = data.china;
+//   tableForm.englin = data.englin;
+//   tableForm.two = data.two;
+//   tableForm.three = data.three;
+//   tableForm.text = data.text;
+// };
+//编辑-删除
+const btnClick = (row, index, param) => {
+  if (param === 2) {
+    router.push({ path: "/systemSettings/securityPolicyedit" });
+    // msgTitle.value = "编辑登录策略";
+    // flag.value = true;
+    // type.value = "";
+    // tableForm.name = index.name;
+    // tableForm.china = index.china;
+    // tableForm.englin = index.englin;
+    // tableForm.two = index.two;
+    // tableForm.three = index.three;
+    // tableForm.text = index.text;
+  } else if (param === 3) {
+    msgTitle.value = "删除航司信息维护";
+    flag.value = true;
+    type.value = "del";
+  } else if (param === 4) {
+  }
+};
+//删除
+const eleDialog = () => {
+  msgTitle.value = "删除登录策略";
+  flag.value = true;
+  type.value = "del";
+};
+//删除
+const delRest = () => {
+  flag.value = false;
+};
+//按钮点击index为当前行序号 row 为当前行 param按钮类型判断参数由父组件传过来
+const handleClick = (index: number, row: Object, param: number) => {
+  if (param === 2) {
+    msgTitle.value = "编辑菜单";
+    flag.value = true;
+    type.value = "";
+  } else if (param === 3) {
+    msgTitle.value = "删除";
+    flag.value = true;
+    type.value = "del";
+  }
+};
+//行公共样式
+const rowStyle = (row: Object, rowIndex: number) => {
+  let styleJson: Object = {
+    height: "50px",
+    fontSize: "14px",
+    color: "#101116",
+  };
+  return styleJson;
+};
+//表格行class样式 可通过父组件直接传class名称修改当前行样式
+const tableRowClassName = (row: Object, rowIndex: number) => {
+  if (row.row.rowClass) {
+    return row.row.rowClass;
+  }
+  return "";
+};
+//向父组件传参 btnClick:点击按钮后    load  触发下拉加载   cellClass 修改某一行class的触发条件
+const emit = defineEmits(["btnClick", "load", "cellClass"]);
+//给某一格加class
+const cellClass = ref("");
+const cellClassName = (row: Object) => {
+  emit("cellClass", row);
+  return cellClass.value;
+};
+const removeTag = (index) => {
+  TagsAll.value.splice(index, 1);
+};
+const addTags = () => {
+  if (currentval) {
+    TagsAll.value.push(currentval.value);
+    currentval.value = "";
+  }
+};
+const deleteTags = () => {
+  TagsAlls.value.pop();
+};
+const removeTags = (index) => {
+  TagsAlls.value.splice(index, 1);
+};
+const addTagss = () => {
+  if (currentvals) {
+    TagsAlls.value.push(currentvals.value);
+    currentvals.value = "";
+  }
+};
+const deleteTagss = () => {
+  TagsAlls.value.pop();
+};
+// const inputStyle = () => {
+//   let style = {};
+//   style.width = `${inputLength}px`;
+//   return style;
+// };
+defineExpose({
+  cellClass,
+});
+</script>
+<style lang="scss" scoped>
+::v-deep .el-form-item__label {
+  width: 100px;
+}
+::v-deep .el-radio-button__original-radio:checked + .el-radio-button__inner {
+  color: #fff;
+  background-color: #ac014d;
+  box-shadow: none;
+}
+.catalogue {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  border-radius: 4px;
+  background: red;
+  color: #fff;
+  padding: 4px 10px;
+}
+.log {
+  width: 10px;
+  height: 10px;
+  border-radius: 50%;
+  background: greenyellow;
+}
+.app-containers {
+  height: calc(100vh - 180px);
+}
+.infinite-list {
+  height: 300px;
+  padding: 0;
+  margin: 0;
+  list-style: none;
+}
+.infinite-list .infinite-list-item {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  height: 50px;
+  background: var(--el-color-primary-light-9);
+  margin: 10px;
+  color: var(--el-color-primary);
+}
+.infinite-list .infinite-list-item + .list-item {
+  margin-top: 10px;
+}
+::v-deep.el-table .rowClass {
+  height: 40px;
+  font-size: 14px;
+  color: #101116;
+}
+::v-deep.el-table .headerRowClass {
+  height: 40px;
+  background: #ffffff;
+  font-size: 14px;
+  font-weight: bold;
+  color: #101116;
+}
+::v-deep .el-table--small .cell {
+  display: flex;
+  justify-content: center;
+}
+::v-deep.el-table .editBtn {
+  background: #ffffff;
+  border: 1px solid #f79ec6;
+  box-shadow: 0px 3px 3px 0px rgba(0, 0, 0, 0.06);
+  border-radius: 4px;
+  font-size: 12px;
+  font-weight: 400;
+  color: #ac014d;
+}
+
+::v-deep.el-table .delBtn {
+  background: #eb2f3b;
+  box-shadow: 0px 3px 3px 0px rgba(0, 0, 0, 0.06);
+  border-radius: 4px;
+  font-size: 12px;
+  font-weight: 400;
+  color: #ffffff;
+  border: none;
+}
+::v-deep.el-table--striped
+  .el-table__body
+  tr.el-table__row--striped
+  td.el-table__cell {
+  background-color: #f0f3f7;
+}
+::v-deep.el-table thead.is-group th.el-table__cell {
+  background: #fff;
+}
+.father_box {
+  width: 100%;
+  /* width: 300px; */
+  box-sizing: border-box;
+  background-color: white;
+  border: 1px solid #dcdee2;
+  border-radius: 4px;
+  font-size: 12px;
+  text-align: left;
+  padding-left: 5px;
+  word-wrap: break-word;
+  overflow: hidden;
+}
+/* 标签 */
+.spanbox {
+  display: inline-block;
+  font-size: 14px;
+  margin: 0px 4px 0px 0;
+  background: #dfe3ea;
+  border: 1px solid #e8eaec;
+  border-radius: 3px;
+}
+.tagspan {
+  height: 24px;
+  line-height: 22px;
+  max-width: 99%;
+  position: relative;
+  display: inline-block;
+  padding-left: 8px;
+  color: #495060;
+  font-size: 14px;
+  cursor: pointer;
+  opacity: 1;
+  vertical-align: middle;
+  overflow: hidden;
+  transition: 0.25s linear;
+  color: rgb(26, 26, 26);
+  font-weight: 600;
+}
+.span_close {
+  padding: 0 4px 0 4px;
+  opacity: 1;
+  -webkit-filter: none;
+  filter: none;
+  color: rgb(26, 26, 26);
+  font-weight: 600;
+}
+.span_close:after {
+  content: "\00D7";
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+  /* line-height: 27px; */
+  transition: 0.3s, color 0s;
+}
+/* input */
+.inputTag {
+  font-size: 16px;
+  border: none;
+  box-shadow: none;
+  outline: none;
+  background-color: transparent;
+  padding: 0;
+  width: auto;
+  min-width: 250px;
+  vertical-align: top;
+  height: 32px;
+  color: #495060;
+  line-height: 32px;
+}
+.father_box {
+  ::v-deep .el-input__wrapper:hover {
+    box-shadow: 0 0 0 0;
+  }
+  ::v-deep .el-input__wrapper {
+    box-shadow: 0 0 0 0;
+  }
+}
+</style>