Explorar o código

表格组件格式化方法优化

@dongkboy hai 1 ano
pai
achega
e2e19ff899

+ 4 - 4
.env.development

@@ -1,11 +1,11 @@
 # 应用配置面板
-VITE_APP_SETTING = true
+VITE_APP_SETTING = false
 # 页面标题
 VITE_APP_TITLE = 掌柜运营平台
 # 接口请求地址,会设置到 axios 的 baseURL 参数上
 # VITE_APP_API_BASEURL = https://test.baoxianzhanggui.com/web-api #默认地址
-VITE_APP_API_BASEURL = http://192.168.0.55:8001  #董鑫
-# VITE_APP_API_BASEURL = http://192.168.0.253:8001  #田智
+# VITE_APP_API_BASEURL = http://192.168.0.55:8001  #董鑫
+VITE_APP_API_BASEURL = http://192.168.0.253:8001  #田智
 
 # 调试工具,可设置 eruda 或 vconsole,如果不需要开启则留空
 VITE_APP_DEBUG_TOOL =
@@ -15,5 +15,5 @@ VITE_APP_DISABLE_DEVTOOL = false
 # 是否开启代理
 VITE_OPEN_PROXY = false
 # 是否开启开发者工具
-VITE_OPEN_DEVTOOLS = true
+VITE_OPEN_DEVTOOLS = false
 

+ 2 - 1
src/api/modules/dept.ts

@@ -13,7 +13,8 @@ const dept = (axiosInstance: ApiInstance) => ({
   //机构批量删除
   deptBatchDeleteDept: (data: any) => axiosInstance.post('dept/batchDeleteDept', data),
   //机构树形查询
-  getDeptTree: (data?: any) => axiosInstance.post('dept/getDeptTree', data),
+  getDeptTree: (data?: any) => axiosInstance.post('dept/getDeptTreePlatform', data),
+
   //机构区划查询
   queryTree: () => axiosInstance.post('area/queryTree'),
   // 机构信息查询

+ 40 - 48
src/components/Table/index.vue

@@ -11,7 +11,7 @@
         <!-- 空内容自定义 -->
         <template #empty>
           <div class="flex f-c a-c ">
-            <el-empty   image="../../../src/assets/images/empty.png" />
+            <el-empty image="../../../src/assets/images/empty.png" />
           </div>
         </template>
         <el-table-column type="selection" v-if="showSelect" :selectable="selectable" width="55" />
@@ -22,26 +22,17 @@
             <slot name="search" :slotData="column"></slot>
           </template>
           <template #default="scope">
-            <component v-if="column.formatter"
-              :is="column.formatter(scope.row, column, scope.row[column.prop], scope.$index)" class="routerlick" />
-            <span v-else>{{ scope.row[column.prop] }}</span>
+            <RouterLink v-if="column.component === 'RouterLink'" :to="getRouterLinkTo(scope.row, column)" class="custom-link">
+              {{ scope.row[column.prop] }}
+            </RouterLink>
+            <el-tag v-else-if="column.component === 'Tag'" :type="getTagTypeAndText(scope.row, column).type">
+              {{ getTagTypeAndText(scope.row, column).text }}
+            </el-tag>
+            <ImagePreview v-else-if="column.component === 'Image'" :src="getImgTo(scope.row, column)" width="50px" height="50px"></ImagePreview>
+            <span v-else>
+              {{ getDisplayText(scope.row, column) }}
+            </span>
           </template>
-          <!-- <template #default="{ row }">
-            <template v-if="row._edit">
-              <el-input v-if="
-                column.prop === 'Date' || column.prop === 'Name' || column.prop === 'Organization'
-              " v-model="row[column.prop]" />
-              <el-select v-if="column.prop === 'Tag'" v-model="Tagvalue">
-                <el-option v-for="(type, label) in tagTypes" :key="label" :label="label" :value="label" />
-              </el-select>
-            </template>
-            <template v-else>
-              <span v-if="column.prop !== 'Tag'">{{ row[column.prop] }}</span>
-              <el-tag v-if="column.prop === 'Tag'" :type="getTagType(row[column.prop])">{{
-                row[column.prop]
-              }}</el-tag>
-            </template>
-          </template> -->
         </el-table-column>
         <el-table-column label="操作" fixed="right" :width="props.columnheight">
           <template #default="scope">
@@ -73,9 +64,6 @@ import type { TableInstance } from "element-plus";
 interface TableRow {
   [key: string]: any;
 }
-interface TagTypes {
-  [key: string]: string;
-}
 const emit = defineEmits(['getList', 'selectAllChange', 'selectionChange']);
 const props = defineProps<{
   tableData: Array<TableRow>;
@@ -86,6 +74,7 @@ const props = defineProps<{
     sortable?: boolean;
     width?: string;
     style?: string;
+    component?: string,
     formatter?: (row: any, column: any, cellValue: any, index: number) => any;
 
   }[];
@@ -99,6 +88,12 @@ const props = defineProps<{
   showIndex: boolean;
   tableheight?: (number | string),
 }>();
+interface Row {
+  [key: string]: any; // 假设Row是一个具有任意属性的对象
+}
+interface RouterLink {
+  name: string;
+}
 const tableHeight = ref(props.tableheight); // 初始化表格高度
 const newSelectionList = ref<string[]>([]);
 const multipleTableRef = ref<TableInstance>();
@@ -116,7 +111,6 @@ onMounted(() => {
     if (tableElement) {
       const offsetTop = tableElement.offsetTop; // 获取 offsetTop
       let height = window.innerHeight;
-      console.log(height)
       tableHeight.value = height - offsetTop - 270 + "px";
     }
   }, 10);
@@ -124,16 +118,8 @@ onMounted(() => {
 
 });
 const selectable = () => true;
-const Tagvalue = ref("");
-const tagTypes: TagTypes = {
-  '公司': "primary",
-  '甲方': "success",
-  '合作伙伴': "primary"
-};
 const handleSizeChange = (val: number) => {
-
   props.pageInfo.pageSize = val
-
   emit('getList', props.pageInfo);
 }
 //多选
@@ -166,22 +152,23 @@ const handleCurrentChange = (val: number) => {
 
 
 }
-const getTagType = (tag: string) => {
-  return tagTypes[tag] || tagTypes["公司"];
-};
-const handleEdit = (scope: { row: TableRow }) => {
-  Tagvalue.value = scope.row.Tag || "";
-  scope.row._edit = true;
-};
-const handleSave = (scope: { row: TableRow }) => {
-  scope.row.Tag = Tagvalue.value;
-  scope.row._edit = false;
-};
-const handleCancle = (scope: { row: TableRow }) => {
-  scope.row._edit = false;
-};
-const headClass = (scope: { row: TableRow }) => {
-  // return 'background:#F8F8F9'
+//空值处理
+const displayValue = (value: any) => {
+  return value === null || value === undefined || value === '' ? '-' : value;
+}
+// 格式化内容配置
+function getRouterLinkTo(row: Row, column: any): RouterLink {
+  return column.formatter ? column.formatter(row, column, row[column.prop]) : { name: 'OrganizationAdd' };
+}
+function getImgTo(row: Row, column: any) {
+  return row[column.prop];
+}
+function getTagTypeAndText(row: Row, column: any) {
+  // 使用 formatter 返回一个对象,包含 type 和 text
+  return column.formatter ? column.formatter(row, column, row[column.prop]) : { type: 'primary', text: row[column.prop] };
+}
+function getDisplayText(row: Row, column: any): string {
+  return column.formatter ? column.formatter(row, column, row[column.prop]) :displayValue(row[column.prop]);
 }
 </script>
 <style lang="scss" scoped>
@@ -196,6 +183,11 @@ const headClass = (scope: { row: TableRow }) => {
   height: auto;
 }
 
+.custom-link {
+  color: #0083ff; /* 设置文字颜色 */
+  text-decoration: none; /* 去掉下划线 */
+}
+
 .table_box {
   flex: 1;
   margin-bottom: 10px;

+ 79 - 80
src/components/TableTree/index.vue

@@ -6,24 +6,39 @@
       </div>
       <el-table ref="TableTreeRef" class="custom-table"
         :header-cell-style="{ 'background-color': '#EEF1F6', 'border-bottom': '1px solid #EEF1F6', 'font-size': '15px', 'color': '#333', 'padding': '10px 0' }"
-        :data="props.tableData" :height="tableHeight" table-layout="fixed" row-key="id" default-expand-all row-class-name="cellClass"
-        style="width: 100%;">
+        :data="props.tableData" :height="tableHeight" table-layout="fixed" row-key="id" default-expand-all
+        row-class-name="cellClass" style="width: 100%;">
+        <!-- 空内容自定义 -->
+        <template #empty>
+          <div class="flex f-c a-c ">
+            <el-empty image="../../../src/assets/images/empty.png" />
+          </div>
+        </template>
         <el-table-column type="selection" v-if="showSelect" :selectable="selectable" width="55" />
         <el-table-column v-if="showIndex" type="index" label="序号" width="55" />
         <el-table-column v-for="column in columns" :key="column.prop" :prop="column.prop" :label="column.label"
-          :sortable="column.sortable ? 'custom' : false" :width="column.width">
+          :sortable="column.sortable ? 'custom' : false" :width="column.width" :align="column.align?column.align:'center'" >
           <template #default="scope">
-            <component v-if="column.formatter"
-              :is="column.formatter(scope.row, column, scope.row[column.prop], scope.$index)" class="routerlick" />
-            <span v-else>{{ scope.row[column.prop] }}</span>
+            <RouterLink v-if="column.component === 'RouterLink'" :to="getRouterLinkTo(scope.row, column)" class="custom-link">
+              {{ scope.row[column.prop] }}
+            </RouterLink>
+            <el-tag v-else-if="column.component === 'Tag'" :type="getTagTypeAndText(scope.row, column).type">
+              {{ getTagTypeAndText(scope.row, column).text }}
+            </el-tag>
+            <ImagePreview v-else-if="column.component === 'Image'" :src="getImgTo(scope.row, column)" width="50px" height="50px"></ImagePreview>
+            <span v-else>
+              {{ getDisplayText(scope.row, column) }}
+            </span>
           </template>
           <template #header>
             <slot name="search" :slotData="column"></slot>
           </template>
         </el-table-column>
-        <el-table-column label="操作" fixed="right" :width="props.columnheight">
+        <el-table-column label="操作" fixed="right" :width="props.columnheight" align="center">
           <template #default="scope">
-            <slot name="operation" class="operationClass" :operationData="scope.row"></slot>
+            <div class="flex j-c a-c">
+              <slot name="operation" class="operationClass" :operationData="scope.row"></slot>
+            </div>
           </template>
         </el-table-column>
       </el-table>
@@ -39,8 +54,11 @@ import type { TableInstance } from "element-plus";
 interface TableRow {
   [key: string]: any;
 }
-interface TagTypes {
-  [key: string]: string;
+interface Row {
+  [key: string]: any; // 假设Row是一个具有任意属性的对象
+}
+interface RouterLink {
+  name: string;
 }
 const emit = defineEmits([]);
 const props = defineProps<{
@@ -52,6 +70,8 @@ const props = defineProps<{
     sortable?: boolean;
     width?: string;
     style?: string;
+    align?:string,
+    component?:string,
     formatter?: (row: any, column: any, cellValue: any, index: number) => any;
 
   }[];
@@ -83,33 +103,24 @@ onMounted(() => {
 
 
 });
+//空值处理
+const displayValue = (value: any) => {
+  return value === null || value === undefined || value === '' ? '-' : value;
+}
 const selectable = () => true;
-const Tagvalue = ref("");
-const tagTypes: TagTypes = {
-  '公司': "primary",
-  '甲方': "success",
-  '合作伙伴': "primary"
-};
-
-//多选
-
-
-const getTagType = (tag: string) => {
-  return tagTypes[tag] || tagTypes["公司"];
-};
-const handleEdit = (scope: { row: TableRow }) => {
-  Tagvalue.value = scope.row.Tag || "";
-  scope.row._edit = true;
-};
-const handleSave = (scope: { row: TableRow }) => {
-  scope.row.Tag = Tagvalue.value;
-  scope.row._edit = false;
-};
-const handleCancle = (scope: { row: TableRow }) => {
-  scope.row._edit = false;
-};
-const headClass = (scope: { row: TableRow }) => {
-  // return 'background:#F8F8F9'
+// 格式化内容配置
+function getRouterLinkTo(row: Row, column: any): RouterLink {
+  return column.formatter ? column.formatter(row, column, row[column.prop]) : { name: 'OrganizationAdd' };
+}
+function getImgTo(row: Row, column: any) {
+  return row[column.prop];
+}
+function getTagTypeAndText(row: Row, column: any) {
+  // 使用 formatter 返回一个对象,包含 type 和 text
+  return column.formatter ? column.formatter(row, column, row[column.prop]) : { type: 'primary', text: row[column.prop] };
+}
+function getDisplayText(row: Row, column: any): string {
+  return column.formatter ? column.formatter(row, column, row[column.prop]) :displayValue(row[column.prop]);
 }
 </script>
 <style lang="scss" scoped>
@@ -138,12 +149,6 @@ const headClass = (scope: { row: TableRow }) => {
     }
   }
 
-  :deep(.cell) {
-    display: flex;
-    align-items: center;
-    justify-content: center;
-  }
-
   .table-title-btn {
     margin-bottom: 20px;
 
@@ -153,46 +158,40 @@ const headClass = (scope: { row: TableRow }) => {
   }
 }
 
-.page_box {
-  display: flex;
-  align-items: center;
-  justify-content: flex-end;
-}
-
 /* 自定义树状表格图标 */
 
-/* 有子节点 且未展开 */
-.custom-table :deep(.el-table__expand-icon) {
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  width: 18px;
-  height: 18px;
-  background: url("../../assets/icons/caretRight.svg") no-repeat;
-  background-size: auto;
-
-  svg {
-    display: none;
-  }
-}
-
-/* 有子节点 且已展开 */
-.custom-table :deep(.el-table__expand-icon--expanded) {
-  display: inline-block;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  width: 18px;
-  height: 18px;
-  content: "";
-  background: url("../../assets/icons/caretRight.svg") no-repeat;
-  background-size: auto;
-  transform: rotate(90deg);
-
-  svg {
-    display: none;
-  }
-}
+// /* 有子节点 且未展开 */
+// .custom-table :deep(.el-table__expand-icon) {
+//   display: flex;
+//   align-items: center;
+//   justify-content: center;
+//   width: 18px;
+//   height: 18px;
+//   background: url("../../assets/icons/caretRight.svg") no-repeat;
+//   background-size: auto;
+
+//   svg {
+//     display: none;
+//   }
+// }
+
+// /* 有子节点 且已展开 */
+// .custom-table :deep(.el-table__expand-icon--expanded) {
+//   display: inline-block;
+//   display: flex;
+//   align-items: center;
+//   justify-content: center;
+//   width: 18px;
+//   height: 18px;
+//   content: "";
+//   background: url("../../assets/icons/caretRight.svg") no-repeat;
+//   background-size: auto;
+//   transform: rotate(90deg);
+
+//   svg {
+//     display: none;
+//   }
+// }
 
 :deep(.el-table) {
   .el-table__row--level-1 {

+ 2 - 2
src/router/modules/personnel.ts

@@ -9,9 +9,9 @@ const routes: RouteRecordRaw = {
   name: 'Personnel',
   meta: {
     title: '成员管理',
-    icon:'user'
+    icon:'user',
   },
-  children: [
+    children: [
     {
       path: 'memberManagement',
       name: 'MemberManagement',

+ 5 - 5
src/store/modules/route.ts

@@ -171,11 +171,11 @@ const useRouteStore = defineStore(
     }
     // 生成路由(后端获取)
     async function generateRoutesAtBack() {
-      await apiApp.routeList().then((res) => {
-        // 设置 routes 数据
-        routesRaw.value = converDeprecatedAttribute(formatBackRoutes(res.data) as any)
-        isGenerate.value = true
-      }).catch(() => {})
+      // await apiApp.routeList().then((res) => {
+      //   // 设置 routes 数据
+      //   routesRaw.value = converDeprecatedAttribute(formatBackRoutes(res.data) as any)
+      //   isGenerate.value = true
+      // }).catch(() => {})
     }
     // 生成路由(文件系统生成)
     function generateRoutesAtFilesystem(asyncRoutes: RouteRecordRaw[]) {

+ 30 - 5
src/views/organizationManagement/organization/organizationAdd.vue

@@ -144,15 +144,14 @@
 
 <script lang="ts" setup>
 import { ref, reactive } from 'vue'
-import { FormRules, UploadFile, FormInstance, ComponentSize, ElMessage, UploadUserFile } from 'element-plus';
-import { regionData, codeToText } from "element-china-area-data";
+import { FormRules, UploadFile, FormInstance, ComponentSize, ElMessage } from 'element-plus';
 import { useRoute } from 'vue-router';
 import api from '@/api';
 import router from '@/router';
 const route = useRoute();
 const id = ref(route.query.id);//id参数
-const provinceoptions = ref<string[]>([])//省市区回显数据
-const areaOptions = ref(regionData)//省市区数据
+const provinceoptions = ref()//省市区回显数据
+const areaOptions = ref()//省市区数据
 const uploadDisabled = ref(false)
 const dialogImageUrl = ref('')
 const dialogVisible = ref(false)
@@ -161,6 +160,9 @@ const fromSize = ref<ComponentSize>('large')
 const userNameShow = ref(false)
 const props = {
   expandTrigger: 'hover' as const,
+  value: 'areaCode',
+  label: 'areaCname',
+  children: 'child'
 }
 const sysIconList = reactive({
   url: "",
@@ -251,6 +253,7 @@ const sysformRules = ref<FormRules>({
 
 });
 onBeforeMount(() => {
+  queryTreeQuery();//获取区划数据
   if (id.value) {
     detailQuery();
   }
@@ -265,12 +268,28 @@ const userAccountblur = (event: any) => {
   });
 
 }
+//获取区划数据
+const queryTreeQuery = () => {
+  api.dept.queryTree().then((res: any) => {
+    if (res.code == '200') {
+      areaOptions.value = res.data;
+    } else {
+      ElMessage({
+        type: 'success',
+        message: res.msg,
+        plain: true,
+      })
+    }
+  });
+}
 //详情查询
 const detailQuery = () => {
   api.tenantApi.sysGet({ id: id.value }).then((res: any) => {
     if (res.code == '200') {
       sysform.value = res.data;
       sysIconList.url = res.data.sysIconUrl
+      provinceoptions.value = [res.data.provinceId, res.data.cityId, res.data.districtId]
+
       console.log(sysIconList.url)
     } else {
       ElMessage({
@@ -301,10 +320,14 @@ const detailUpdate = () => {
   });
 }
 const provinceChange = (value: any) => {
-  if (value[0] != null && value[1] != null && value[2] != null) {
+  if ( value && value[0] != null && value[1] != null && value[2] != null) {
     sysform.value.provinceId = value[0];
     sysform.value.cityId = value[1];
     sysform.value.districtId = value[2];
+  }else{
+    sysform.value.provinceId = "";
+    sysform.value.cityId = "";
+    sysform.value.districtId = "";
   }
 }
 const handleRemove = (file: UploadFile) => {
@@ -338,6 +361,8 @@ const submitForm = async (formEl: FormInstance | undefined) => {
     if (valid) {
       if (id.value) {
         detailUpdate();
+        router.back();
+
       } else {
         api.tenantApi.sysAdd(sysform.value).then((res: any) => {
           if (res.code == 200) {

+ 14 - 13
src/views/organizationManagement/organization/organizationDetail.vue

@@ -58,7 +58,7 @@
               <el-descriptions-item label="简称:">{{ tenantInfo.shortName }}</el-descriptions-item>
               <el-descriptions-item label="类型:">{{ sysTypematch(tenantInfo.sysType) }}</el-descriptions-item>
               <el-descriptions-item label="地区:">
-                {{ tenantInfo.contactAdress }}
+                {{ tenantInfo.division }}
               </el-descriptions-item>
               <el-descriptions-item label="详细地址:">{{ tenantInfo.address }}</el-descriptions-item>
               <el-descriptions-item label="品牌logo:">
@@ -134,7 +134,7 @@
 <script lang='ts' setup>
 import { ref, nextTick } from 'vue'
 import { useRoute, useRouter } from 'vue-router';
-import { TabsPaneContext, ElMessage, ElMessageBox } from 'element-plus'
+import { ElMessage, ElMessageBox } from 'element-plus'
 import ImagePreview from '@/components/ImagePreview/index.vue';
 
 import api from '@/api';
@@ -147,7 +147,7 @@ const activeName = ref()//默认标签页
 const tableData = ref([]);//机构数据
 const mainElement = ref<HTMLElement | null>(null);
 const containerLeftHeight = ref('0px');
-const dialogVisible=ref(false)
+const dialogVisible = ref(false)
 onMounted(() => {
   activeName.value = typeName.value;
   nextTick(() => {
@@ -157,15 +157,16 @@ onMounted(() => {
     }
   });
 });
-const exhibitionScopeformatter = (row: any, column: any, cellValue: any) => {
-  let exhibitionScope = row.exhibitionScope;
-  let sysType = exhibitionScope.join(',');
-  return () => h('div', {}, sysType);
-};
 const columns = [
-  { prop: "name", label: "机构名称", width: '300', },
-  { prop: "comType", label: "机构类型", width: '120', },
-  { prop: "exhibitionScope", label: "营业范围", width: '200', formatter: exhibitionScopeformatter },
+  { prop: "name", label: "机构名称", width: '300', align: 'left' },
+  { prop: "comType", label: "机构类型", width: '120', formatter: (row: any) => { let comType = sysTypematch(row.comType); return comType } },
+  {
+    prop: "exhibitionScope", label: "营业范围", width: '200', formatter: (row: any) => {
+      let exhibitionScope = row.exhibitionScope;
+      let sysType = exhibitionScope.join(',');
+      return sysType;
+    }
+  },
   { prop: "division", label: "所属地区" },
   { prop: "leaderId", label: "负责人", width: '120', },
 
@@ -261,7 +262,7 @@ const del = () => {
       confirmButtonText: '确定删除',
       cancelButtonText: '取消',
       type: 'error',
-      center:true,
+      center: true,
     }
   )
     .then(() => {
@@ -289,7 +290,7 @@ const disable = () => {
       confirmButtonText: '确定禁用',
       cancelButtonText: '取消',
       type: 'error',
-      center:true,
+      center: true,
     }
   )
     .then(async () => {

+ 57 - 71
src/views/organizationManagement/organization/organizationlist.vue

@@ -98,13 +98,10 @@
 <script lang="ts" setup>
 import { ref, reactive } from 'vue'
 import api from '@/api';
-import { h } from 'vue'
 import { RouterLink, useRouter } from "vue-router";
-import ImagePreview from '@/components/ImagePreview/index.vue';
-import { regionData, codeToText } from "element-china-area-data";
-import { ElMessage, ElMessageBox, ElTag } from 'element-plus'
+import { ElMessage, ElMessageBox } from 'element-plus'
 import useAuth from '@/utils/composables/useAuth'
-const { auth, authAll } = useAuth()
+const { auth } = useAuth()
 interface PageInfo {
   pageNum: number;
   pageSize: number;
@@ -113,10 +110,13 @@ interface PageInfo {
 }
 const props = {
   expandTrigger: 'hover' as const,
+  value: 'areaCode',
+  label: 'areaCname',
+  children: 'child'
 }
 const sysUpAndDownList = ref<string[]>([])//选中id
 const provinceoptions = ref<string[]>([])//省市区回显数据
-const areaOptions = ref(regionData)//省市区数据
+const areaOptions = ref()//省市区数据
 const provinceChange = (value: any) => {
   if (value && value[0] != null && value[1] != null && value[2] != null) {
     formInline.provinceId = value[0];
@@ -168,9 +168,24 @@ const formInline = reactive({
 const tableData = ref([]);
 onBeforeMount(() => {
   if (auth('organizationlist.view')) {
-    findpage();
+    findpage();//列表数据
+    queryTreeQuery();//区划数据
   }
 });
+//获取区划数据
+const queryTreeQuery = () => {
+  api.dept.queryTree().then((res: any) => {
+    if (res.code == '200') {
+      areaOptions.value = res.data;
+    } else {
+      ElMessage({
+        type: 'success',
+        message: res.msg,
+        plain: true,
+      })
+    }
+  });
+}
 function findpage() {
   api.tenantApi.sysList({ pageNum: pageInfo.value.pageNum, pageSize: pageInfo.value.pageSize, ...formInline }).then((res: any) => {
     if (res.code == 200) {
@@ -182,69 +197,40 @@ function findpage() {
 
   })
 }
-const deptCountformatter = (row: any, column: any, cellValue: any) => {
-  return () => h('div', {}, [
-    row.id
-      ? h(RouterLink, {
-        to: { name: auth('organizationlist.view') ? 'OrganizationDetail' : '', query: { id: row.id, code: row.sysCode, typeName: 'organization' } },
-        style: { color: '#3498db', textDecoration: 'none' },
-      }, { default: () => row.deptCount || 'N/A' })
-      : h('span', { style: { color: 'gray' } }, 'Loading...') // 加载状态或占位符
-  ]);
-
-};
-const sysNameformatter = (row: any, column: any, cellValue: any) => {
-  return () => h('div', {}, [
-    row.id
-      ? h(RouterLink, {
-        to: { name: auth('organizationlist.view') ? 'OrganizationDetail' : '', query: { id: row.id, code: row.sysCode, typeName: 'tenantInfo' } },
-        style: { color: '#3498db', textDecoration: 'none' },
-      }, { default: () => row.sysName || 'N/A' })
-      : h('span', { style: { color: 'gray' } }, 'Loading...') // 加载状态或占位符
-  ]);
-};
-const imgformatter = (row: any, column: any, cellValue: any) => {
-  // 返回虚拟 DOM,使用 `<ImagePreview>` 组件
-  return h('div', {}, [
-    h(ImagePreview, {
-      src: row.sysIconUrl, // 显示图片的路径(替换为你的实际数据属性)
-      width: '50px',
-      height: '50px',
-      style: {
-        cursor: 'pointer',
-      },
-    }),
-  ]);
-};
-const typeformatter = (row: any, column: any, cellValue: any) => {
-  let sysType = '';
-  sysTypelist.value.map(ele => {
-    if (ele.id == row.sysType) {
-      sysType = ele.name;
-    }
-  })
-
-  return () => h('div', {}, sysType);
-};
-const cityformatter = (row: any, column: any, cellValue: any) => {
-  return () => h('div', {}, `${codeToText[row.provinceId]}-${codeToText[row.cityId]}-${codeToText[row.districtId]}`);
-};
-const statusformatter = (row: any, column: any, cellValue: any) => {
-  let available = row.available;
-  if (available) {
-    return () => h(ElTag, { type: 'primary' }, '启用');
-  } else {
-    return () => h(ElTag, { type: 'danger' }, '禁用');
-  }
-};
 const columns = [
   { prop: "sysCode", label: "编码", width: '120', },
-  { prop: "sysName", label: "租户名称", width: '120', formatter: sysNameformatter },
-  { prop: "sysIcon", label: "租户图标", width: '120', formatter: imgformatter },
-  { prop: "sysType", label: "租户类型", width: '120', formatter: typeformatter },
-  { prop: "provinceId", label: "所在地区", formatter: cityformatter },
-  { prop: "deptCount", label: "下级机构", formatter: deptCountformatter },
-  { prop: "available", label: "状态", width: '120', formatter: statusformatter },
+  {
+    prop: "sysName", label: "租户名称", width: '120', component: "RouterLink",
+    formatter: (row: any) => ({ name: 'OrganizationDetail', query: { id: row.id, code: row.sysCode, typeName: 'tenantInfo' } })
+  },
+  { prop: "sysIconUrl", label: "租户图标", width: '120', component: 'Image' },
+  {
+    prop: "sysType", label: "租户类型", width: '120', formatter: (row: any) => {
+      let sysType = '';
+      sysTypelist.value.map(ele => {
+        if (ele.id == row.sysType) {
+          sysType = ele.name;
+        }
+      })
+      return sysType
+    }
+  },
+  { prop: "division", label: "所在地区", },
+  {
+    prop: "deptCount", label: "下级机构",
+    component: "RouterLink",
+    formatter: (row: any) => ({ name: 'OrganizationDetail', query: { id: row.id, code: row.sysCode, typeName: 'organization' } })
+  },
+  {
+    prop: "available", label: "状态", width: '120', component: "Tag",
+    formatter: (row: any) => {
+      if (row.available) {
+        return { type: 'primary', text: '启用' };
+      } else {
+        return { type: 'danger', text: '禁用' };
+      }
+    }
+  },
   { prop: "createTime", label: "创建时间", width: '180', },
   { prop: "createBy", label: "创建人", width: '120', },
 ];
@@ -276,7 +262,7 @@ const del = (value: string) => {
       confirmButtonText: '确定删除',
       cancelButtonText: '取消',
       type: 'error',
-      center:true,
+      center: true,
     }
   )
     .then(() => {
@@ -329,7 +315,7 @@ const batchDel = () => {
       confirmButtonText: '确定删除',
       cancelButtonText: '取消',
       type: 'error',
-      center:true,
+      center: true,
     }
   )
     .then(() => {
@@ -359,7 +345,7 @@ const batchdisable = () => {
       confirmButtonText: '确定禁用',
       cancelButtonText: '取消',
       type: 'error',
-      center:true,
+      center: true,
     }
   )
     .then(async () => {

+ 23 - 30
src/views/organizationManagement/organization/subOrganizatioAdd.vue

@@ -13,10 +13,10 @@
             </el-form-item>
           </ElCol>
           <ElCol :md="24" :lg="12">
-            <el-form-item label="上级机构" prop="parentId" >
-              <el-cascader v-model="parentIdareaOptionsValue" :disabled="parentIdShow" placeholder="请选择地区" style="width: 100%;" filterable
-                clearable :options="parentIdareaOptions" :props="parentIdprops" @change="parentIdChange"
-                :show-all-levels="false" />
+            <el-form-item label="上级机构" prop="parentId">
+              <el-cascader v-model="parentIdareaOptionsValue" :disabled="parentIdShow" placeholder="请选择地区"
+                style="width: 100%;" filterable clearable :options="parentIdareaOptions" :props="parentIdprops"
+                @change="parentIdChange" :show-all-levels="false" />
             </el-form-item>
           </ElCol>
           <ElCol :md="24" :lg="12">
@@ -45,12 +45,6 @@
               <el-input v-model="deptform.address" placeholder="请输入机构地址" />
             </el-form-item>
           </ElCol>
-          <ElCol :md="24" :lg="12">
-            <el-form-item label="机构负责人" prop="leaderId">
-              <el-input v-model="deptform.leaderId" placeholder="请输入机构负责人" />
-
-            </el-form-item>
-          </ElCol>
         </el-form>
       </ElRow>
 
@@ -83,7 +77,7 @@ const deptId = ref(route.query.deptId)//编辑数据id标识
 const parentId = ref(route.query.parentId)//上级id标识
 const provinceoptionsValue = ref()//省市区回显数据
 const areaOptions = ref()//省市区数据
-const parentIdShow=ref(false);//上级机构是否可修改
+const parentIdShow = ref(false);//上级机构是否可修改
 const parentIdareaOptions = ref();//上级机构数据
 const parentIdareaOptionsValue = ref();//上级机构回显数据
 const dialogImageUrl = ref('')
@@ -112,7 +106,6 @@ const deptform = ref({
   city: "",//市
   area: "",//区
   address: "",//机构地址
-  leaderId: "32131",//负责人id
   systemCode: code.value,//租户名称
   id: deptId.value,
 })
@@ -165,13 +158,14 @@ onBeforeMount(() => {
   queryTreeQuery();//获取区划数据
   deptInfo();//获取机构信息详情
 
-  if(parentId.value){
-    parentIdareaOptionsValue.value=parentId.value;
+  if (parentId.value) {
+    parentIdareaOptionsValue.value = parentId.value;
     //子机构向下添加,上级机构无法修改
 
-    parentIdShow.value=true;
+    parentIdShow.value = true;
   }
 });
+
 //获取上级机构
 const getDeptTree = () => {
   api.dept.getDeptTree({ sysCode: code.value }).then((res: any) => {
@@ -212,7 +206,6 @@ const deptInfo = () => {
         provinceoptionsValue.value = [res.data.province, res.data.city, res.data.area]
         deptform.value.exhibitionScope = res.data.exhibitionScope;
         deptform.value.address = res.data.address;
-        deptform.value.leaderId = res.data.leaderId;
         deptform.value.province = res.data.province;
         deptform.value.city = res.data.city;
         deptform.value.area = res.data.area;
@@ -273,24 +266,24 @@ const submitForm = async (formEl: FormInstance | undefined) => {
             router.back();
           }
         })
-      }else{
+      } else {
         api.dept.deptAdd(deptform.value).then((res: any) => {
-        if (res.code == 200) {
-          ElMessage({
-            type: 'success',
-            message: res.msg,
-            plain: true,
-          })
-          router.back();
-        }
-      })
+          if (res.code == 200) {
+            ElMessage({
+              type: 'success',
+              message: res.msg,
+              plain: true,
+            })
+            router.back();
+          }
+        })
       }
     } else {
       ElMessage({
-            type: 'error',
-            message: '信息不完整',
-            plain: true,
-          })
+        type: 'error',
+        message: '信息不完整',
+        plain: true,
+      })
     }
   })
 }

+ 7 - 10
src/views/personnel/memberAdd.vue

@@ -43,11 +43,8 @@
 
 <!-- 行为区域 -->
 <script lang='ts' setup>
-import { ref, reactive } from 'vue'
-import api from '@/api'
-import { FormRules, FormInstance, ComponentSize, ElMessage } from 'element-plus';
-const roleList = ref([])
-const memberformRef = ref<FormInstance>()
+import { ref } from 'vue'
+import { FormRules, ComponentSize } from 'element-plus';
 const fromSize = ref<ComponentSize>('large')
 const memberformRules = ref<FormRules>({
   username: [
@@ -70,12 +67,12 @@ onBeforeMount(() => {
   roleListfun();
 })
 const roleListfun = () => {
-  api.roleApi.roleList({ pageNum: 1, pageSize: 20, name: "" }).then((res: any) => {
-    if (res.code == 200) {
-      roleList.value = res.data;
+  // api.roleApi.roleList({ pageNum: 1, pageSize: 20, name: "" }).then((res: any) => {
+  //   if (res.code == 200) {
+  //     roleList.value = res.data;
 
-    }
-  })
+  //   }
+  // })
 }
 </script>
 <!-- 样式区域 -->

+ 51 - 36
src/views/personnel/memberManagement.vue

@@ -20,7 +20,8 @@
           <ElCol :md="8">
             <ElFormItem>
               <div class="flex j-end" style="width: 100%;">
-                <el-button type="primary" @click="memberQuery" v-auth="'member.view'" @keydown.enter="handleEnter">查询</el-button>
+                <el-button type="primary" @click="memberQuery" v-auth="'member.view'"
+                  @keydown.enter="handleEnter">查询</el-button>
                 <el-button type="default" @click="resetForm" v-auth="'member.view'">重置</el-button>
               </div>
             </ElFormItem>
@@ -29,7 +30,8 @@
       </ElForm>
       <ElDivider border-style="dashed"></ElDivider>
       <Table :tableData="tableData" :columns="columns" :showIndex="false" :columnheight="200" :showSelect="true"
-        :pageInfo="pageInfo" @getList="getList" @selectAllChange="handleSelectionChange" @selectionChange="selectionChange">
+        :pageInfo="pageInfo" @getList="getList" @selectAllChange="handleSelectionChange"
+        @selectionChange="selectionChange">
         <template v-slot:table-title-btn>
           <el-button type="primary" @click="userAdd" v-auth="'member.add'">
             添加成员
@@ -54,7 +56,8 @@
           </el-dropdown>
         </template>
         <template v-slot:operation="scope">
-          <el-button type="primary" link @click="tenantUpdate(scope.operationData.id)" v-auth="'member.edit'"> 编辑 </el-button>
+          <el-button type="primary" link @click="tenantUpdate(scope.operationData.id)" v-auth="'member.edit'"> 编辑
+          </el-button>
           <el-dropdown placement="bottom-start" v-auth="'member.delete'">
             <span class="el-dropdown-link">
               更 多
@@ -91,8 +94,8 @@
             </el-form-item>
           </ElCol>
           <ElCol :md="24" :lg="12">
-            <el-form-item label="角色" prop="roleNameList">
-              <el-select v-model="memberform.roleNameList" multiple placeholder="请选择角色" style="width: 100%;">
+            <el-form-item label="角色" prop="roleIdList">
+              <el-select v-model="memberform.roleIdList" multiple placeholder="请选择角色" style="width: 100%;">
                 <el-option :label="item.name" :value="item.id" v-for="(item, index) in roleLists" :key="index" />
               </el-select>
             </el-form-item>
@@ -115,12 +118,8 @@
 <script lang="ts" setup>
 import { ref, reactive } from 'vue'
 import api from '@/api';
-import { h } from 'vue'
-import { RouterLink, useRouter } from "vue-router";
-// import ImagePreview from '@/components/ImagePreview/index.vue';
-import { ElMessage, ElTag, ElMessageBox } from 'element-plus'
+import { ElMessage, ElMessageBox } from 'element-plus'
 import { FormRules, FormInstance, ComponentSize } from 'element-plus';
-
 interface PageInfo {
   pageNum: number;
   pageSize: number;
@@ -140,11 +139,10 @@ const sysUpAndDownList = ref<string[]>([])//选中id
 const roleLists = ref<roleLists[]>([])//角色列表
 const dialogTitle = ref('添加成员')//弹窗title
 const dialogType = ref('add')//弹窗title
-const router = useRouter();
 const memberform = reactive({
   username: "",//机构名称
   mobile: "",//上级机构
-  roleNameList: [],
+  roleIdList: [],
   id: '',
 })
 const memberformRules = ref<FormRules>({
@@ -152,7 +150,7 @@ const memberformRules = ref<FormRules>({
     { required: true, trigger: 'blur', message: '请输入姓名' },
     { min: 2, max: 20, message: '请输入2~20个字符', trigger: 'blur' },
   ],
-  roleNameList: [
+  roleIdList: [
     { required: true, trigger: 'change', message: '请选择角色' },
   ],
   mobile: [
@@ -165,7 +163,7 @@ const pageInfo = ref({
   pageNum: 1,
   pageSize: 20,
   sizes: [10, 20, 30, 40, 50],
-  total: 100,
+  total: 0,
 });
 //检索条件
 const formInline = reactive({
@@ -254,28 +252,31 @@ function handleEnter(e: any) {
     memberQuery()
   }
 }
-const statusformatter = (row: any, column: any, cellValue: any) => {
-  let accountStatus = row.accountStatus;
-  if (accountStatus) {
-    return () => h(ElTag, { type: 'primary' }, '启用');
-  } else {
-    return () => h(ElTag, { type: 'danger' }, '禁用');
-  }
-};
-const roleNameformatter = (row: any, column: any, cellValue: any) => {
-  let roleNameList = row.roleNameList;
-  let roleName = roleNameList.join(',');
-  return () => h('div', {}, roleName);
-};
 const columns = [
   { prop: "username", label: "姓名", width: '120', },
   { prop: "mobile", label: "手机号", width: '120' },
   { prop: "id", label: "工号", width: '180', },
-  { prop: "roleNameList", label: "角色",formatter: roleNameformatter },
-  { prop: "accountStatus", label: "状态", formatter: statusformatter },
-
+  {
+    prop: "roleNameList", label: "角色", formatter: (row: any) => {
+      let roleNameList = row.roleNameList;
+      if (roleNameList) {
+        let roleName = roleNameList.join(',');
+        return roleName;
+      } else {
+        return roleNameList;
+      }
+    }
+  },
+  {
+    prop: "accountStatus", label: "状态", component: 'Tag', formatter: (row: any) => {
+      if (row.accountStatus) {
+        return { type: 'primary', text: '启用' };
+      } else {
+        return { type: 'danger', text: '禁用' };
+      }
+    }
+  },
 ];
-
 function getList(item: PageInfo) {
   pageInfo.value.pageNum = item.pageNum;
   pageInfo.value.pageSize = item.pageSize;
@@ -283,12 +284,26 @@ function getList(item: PageInfo) {
 function tenantUpdate(id: string) {
   dialogTitle.value = '编辑成员';
   dialogType.value = 'edit';
+  memberform.roleIdList = [];
+  let userlist: any = [];
   api.member.userGet({ id: id }).then((res: any) => {
     if (res.code == '200') {
       memberform.id = res.data.id;
       memberform.username = res.data.username;
       memberform.mobile = res.data.mobile;
-      memberform.roleNameList = res.data.roleNameList;
+      roleLists.value.map((val: any) => {
+        if (res.data.roleNameList) {
+          res.data.roleNameList.map((value: any) => {
+            if (value === val.name) {
+              userlist.push(val.id)
+            }
+          })
+          memberform.roleIdList = userlist;
+        } else {
+          memberform.roleIdList = [];
+        }
+
+      })
       UpdatedialogVisible.value = true;
     } else {
       ElMessage({
@@ -315,7 +330,7 @@ const del = (value: string) => {
       confirmButtonText: '确认删除',
       cancelButtonText: '取消',
       type: 'error',
-      center:true,
+      center: true,
     }
   )
     .then(() => {
@@ -351,7 +366,7 @@ const disable = (value: string) => {
       confirmButtonText: '确认禁用',
       cancelButtonText: '取消',
       type: 'error',
-      center:true,
+      center: true,
     }
   )
     .then(() => {
@@ -376,7 +391,7 @@ const batchDel = () => {
       cancelButtonText: '取消',
       type: 'error',
       confirmButtonClass: 'el-button--danger',
-      center:true,
+      center: true,
     }
   )
     .then(() => {
@@ -411,7 +426,7 @@ const batchdisable = () => {
       confirmButtonText: '确认禁用',
       cancelButtonText: '取消',
       type: 'error',
-      center:true,
+      center: true,
     }
   )
     .then(async () => {

+ 0 - 19
src/views/personnel/roleManagement.vue

@@ -92,8 +92,6 @@ import { preprocessRoutes, convertToTreeData, TreeNode } from '@/utils/composabl
 import { Search } from '@element-plus/icons-vue'
 import api from '@/api'
 import Message from 'vue-m-message'
-import useAuth from '@/utils/composables/useAuth'
-const { auth, authAll } = useAuth()
 onBeforeMount(() => {
   rolequery()//角色列表
   // 对 asyncRoutes 进行预处理并转换为树形结构
@@ -113,8 +111,6 @@ interface Perm {
 const treeRef = ref<InstanceType<typeof ElTree>>();
 const roleName = ref<string>("");
 const roleId = ref<string>("");
-const PageNum = ref<number>(1);
-const PageSize = ref<number>(20);
 const checkedKeys = ref<string[]>([])
 const identifier = ref(false)
 const roleInfo = reactive<{
@@ -220,16 +216,8 @@ function roleDelClick() {
   })
 
 
-}
-function pageChange(e: number) {
-  PageNum.value = e;
-  PageSize.value = 20;
-}
-function sizeChange(val: number) {
-  PageSize.value = val;
 }
 async function roleitemClick(item: { id: string }) {
-  if(auth('role.add')){
     await api.roleApi.roleGet({ roleId: item.id }).then((res: any) => {
     if (res.code === 200) {
       checkedKeys.value = res.data.perms.map((val: Perm) => val.id);
@@ -241,13 +229,6 @@ async function roleitemClick(item: { id: string }) {
       roleId.value = res.data.id;
     }
   })
-  }else{
-    ElMessage({
-          type: 'success',
-          message: '没有权限获取角色数据',
-          plain: true,
-        })
-  }
 
 }
 async function rolequery() {