浏览代码

机构管理

tongshangming 3 年之前
父节点
当前提交
5fba7400b3

+ 21 - 0
src/api/org.ts

@@ -0,0 +1,21 @@
+import request from '@/utils/request'
+
+export function createOrg(data: any) {
+  return request.post('/createOrg', data)
+}
+
+export function updateOrg(data: any) {
+  return request.post('/updateOrg', data)
+}
+
+export function deleteOrg(data: any) {
+  return request.post('/deleteOrg', data)
+}
+
+export function findOrg(data: any) {
+  return request.get('/findOrg', data)
+}
+
+export function getOrgList(data?: any) {
+  return request.get('/getOrgList', data)
+}

+ 21 - 0
src/assets/main.css

@@ -13,3 +13,24 @@ a {
   --el-card-padding: 16px;
   border: none !important;
 }
+
+::-webkit-scrollbar {
+  z-index: 11;
+  width: 6px;
+  height: 6px;
+}
+::-webkit-scrollbar-thumb {
+  border-radius: 5px;
+  width: 6px;
+  background: #909399;
+}
+::-webkit-scrollbar-corner {
+  background: #fff;
+}
+::-webkit-scrollbar-track {
+  background: #fff;
+}
+::-webkit-scrollbar-track-piece {
+  background: #fff;
+  width: 6px;
+}

+ 2 - 0
src/components.d.ts

@@ -58,6 +58,8 @@ declare module '@vue/runtime-core' {
     IEpRefresh: typeof import('~icons/ep/refresh')['default']
     IEpSearch: typeof import('~icons/ep/search')['default']
     IEpUser: typeof import('~icons/ep/user')['default']
+    OrgLayout: typeof import('./components/org/OrgLayout.vue')['default']
+    OrgList: typeof import('./components/org/OrgList.vue')['default']
     ProForm: typeof import('./components/form/ProForm.vue')['default']
     ProTable: typeof import('./components/ProTable.vue')['default']
     RouterLink: typeof import('vue-router')['RouterLink']

+ 23 - 0
src/components/org/OrgLayout.vue

@@ -0,0 +1,23 @@
+<script lang="ts" setup>
+import { useUserStore } from '@/stores/user'
+
+const userStore = useUserStore()
+const userInfo = ref<any>({})
+userInfo.value = userStore.user
+
+const emits = defineEmits(['click'])
+const handleClick = (item: any) => {
+  emits('click', item)
+}
+</script>
+
+<template>
+  <div class="flex" style="height: calc(100vh - 101px - var(--main-padding) * 2)">
+    <org-list @click="handleClick"></org-list>
+    <div class="flex-grow bg-white ml-[16px]">
+      <slot :orgId="userInfo.orgId"></slot>
+    </div>
+  </div>
+</template>
+
+<style lang="scss" scoped></style>

+ 165 - 0
src/components/org/OrgList.vue

@@ -0,0 +1,165 @@
+<script lang="ts" setup>
+import { ElMessageBox, ElMessage } from 'element-plus'
+import { createOrg, deleteOrg, updateOrg, findOrg, getOrgList } from '@/api/org'
+import type { BasicForm } from '@/types/form'
+
+const emits = defineEmits(['click'])
+
+const orgList = ref<any>([])
+const curOrg = ref<any>({})
+const loaded = ref(false)
+const query = ref({
+  name: ''
+})
+
+const fetchOrgList = () => {
+  getOrgList(query.value)
+    .then(res => {
+      orgList.value = res.data.list
+      orgList.value.length && handleOrgClick(orgList.value[0])
+    })
+    .finally(() => {
+      loaded.value = true
+    })
+}
+watch(
+  query,
+  () => {
+    fetchOrgList()
+  },
+  {
+    immediate: true
+  }
+)
+// 更新
+// const updateOrgFunc = async row => {
+//   const res = await findOrg({ ID: row.ID })
+//   type.value = 'update'
+//   if (res.code === 0) {
+//     formData.value = res.data.reorg
+//     dialogFormVisible.value = true
+//   }
+// }
+// 删除
+const handleDel = async (row: any) => {
+  if (!curOrg.id) {
+    return ElMessage({
+      type: 'error',
+      message: '请先选择需要删除的项'
+    })
+  }
+  ElMessageBox.confirm('确定要删除吗?', '提示', {
+    confirmButtonText: '确定',
+    cancelButtonText: '取消',
+    type: 'warning'
+  }).then(async () => {
+    const res = await deleteOrg({ ID: row.ID })
+    if (res) {
+      ElMessage({
+        type: 'success',
+        message: '删除成功'
+      })
+
+      fetchOrgList()
+    }
+  })
+}
+
+const handleOrgClick = (item: any) => {
+  curOrg.value = item
+  formData.value = item
+  emits('click', item)
+}
+
+// ============== 表单部分开始 ===============
+const formData = ref<any>({})
+const dialogVisible = ref(false)
+const formConfig = reactive<BasicForm>({
+  span: 12,
+  formItems: [
+    {
+      label: '组织名称',
+      value: '',
+      name: 'name',
+      type: 'input',
+      rules: [{ required: true, message: '请输入组织名称', trigger: 'blur' }],
+      search: true
+    },
+    {
+      label: '联系人姓名',
+      value: '',
+      name: 'contact',
+      type: 'input'
+    },
+    {
+      label: '联系人电话',
+      value: '',
+      name: 'phone',
+      type: 'input',
+      search: true,
+      props: {
+        maxlength: 11
+      }
+    },
+
+    {
+      label: '所属区域',
+      value: '',
+      name: 'role',
+      type: 'select',
+      options: []
+    },
+    {
+      label: '详细地址',
+      value: true,
+      name: 'state',
+      type: 'switch'
+    }
+  ]
+})
+// ============== 表单部分结束 ===============
+</script>
+
+<template>
+  <div class="flex flex-col w-[300px] bg-white h-full">
+    <div class="p-[10px] flex-shrink-0">
+      <el-input placeholder="请输入组织名称" v-model="query.name"></el-input>
+    </div>
+    <div class="org-list h-full flex-grow overflow-auto">
+      <div
+        class="p-[15px] cursor-pointer org-item"
+        :class="{ active: curOrg.id === item.id }"
+        v-for="item in orgList"
+        :key="item.id"
+      >
+        <div class="" @click="handleOrgClick(item)" :title="item.name">{{ item.name }}</div>
+      </div>
+      <el-empty v-if="!orgList.length && loaded" :image-size="100"></el-empty>
+    </div>
+    <el-space class="p-[10px] flex-shrink-0">
+      <el-button icon="plus" type="primary" size="small" @click="dialogVisible = true"></el-button>
+      <el-button icon="delete" type="danger" size="small" @click="handleDel"></el-button>
+      <el-button icon="refresh" size="small" @click="fetchOrgList"></el-button>
+    </el-space>
+  </div>
+
+  <dialog-form
+    v-model="dialogVisible"
+    :formConfig="formConfig"
+    :formData="formData"
+    :create="createOrg"
+    :update="updateOrg"
+    v-if="dialogVisible"
+  />
+</template>
+
+<style lang="scss" scoped>
+.org-list {
+  border-top: 1px solid var(--el-border-color);
+  border-bottom: 1px solid var(--el-border-color);
+}
+.active,
+.org-item:hover {
+  background-color: var(--el-color-primary-light-9);
+}
+</style>

+ 19 - 0
src/router/asyncRouter.ts

@@ -47,6 +47,25 @@ const asyncRouter: RouteRecordRaw[] = [
       }
     ]
   },
+  {
+    path: '/org',
+    name: 'org',
+    meta: {
+      title: '组织机构',
+      icon: 'icon-system'
+    },
+    children: [
+      {
+        path: 'orgList',
+        name: 'orgList',
+        component: () => import('@/views/org/Org.vue'),
+        meta: {
+          title: '机构管理',
+          icon: 'user'
+        }
+      }
+    ]
+  },
   {
     path: '/result',
     name: 'result',

+ 3 - 3
src/stores/user.ts

@@ -6,12 +6,12 @@ export const useUserStore = defineStore({
   state: () => ({
     user: {},
     flag: false,
-    token: localStorage.getItem('token') || ''
+    token: localStorage.getItem('token') || 't'
   }),
   actions: {
     async getUserInfo() {
-      const userRes: any = await getUserInfo()
-      this.user = userRes.infos[0]
+      // const userRes: any = await getUserInfo()
+      // this.user = userRes.infos[0]
       this.flag = true
     },
     async login(data: any) {

+ 73 - 0
src/views/org/Org.vue

@@ -0,0 +1,73 @@
+<script setup lang="ts">
+import type { BasicForm } from '@/types/form'
+import { createOrg, updateOrg, findOrg } from '@/api/org'
+
+const curOrg = ref<any>({})
+const handleOrgClick = (item: any) => {
+  curOrg.value = item
+  formData.value = item
+}
+
+const formData = ref<any>({})
+const formRef = ref('')
+const formConfig = reactive<BasicForm>({
+  span: 24,
+  formItems: [
+    {
+      label: '组织名称',
+      value: '',
+      name: 'name',
+      type: 'input',
+      rules: [{ required: true, message: '请输入组织名称', trigger: 'blur' }],
+      search: true
+    },
+    {
+      label: '联系人姓名',
+      value: '',
+      name: 'contact',
+      type: 'input'
+    },
+    {
+      label: '联系人电话',
+      value: '',
+      name: 'phone',
+      type: 'input',
+      search: true,
+      props: {
+        maxlength: 11
+      }
+    },
+
+    {
+      label: '所属区域',
+      value: '',
+      name: 'role',
+      type: 'select',
+      options: []
+    },
+    {
+      label: '详细地址',
+      value: true,
+      name: 'state',
+      type: 'switch'
+    }
+  ]
+})
+</script>
+
+<template>
+  <org-layout @click="handleOrgClick">
+    <pro-form
+      v-if="curOrg.id"
+      class="p-[15px]"
+      ref="formRef"
+      :formConfig="formConfig"
+      :formData="formData"
+      :create="createOrg"
+      :update="updateOrg"
+    ></pro-form>
+    <el-empty v-else description="请选择左侧数据后操作"></el-empty>
+  </org-layout>
+</template>
+
+<style lang="scss" scoped></style>

+ 0 - 0
src/views/org/Role.vue