yzx 2 mesiacov pred
rodič
commit
567d177ef0

+ 7 - 2
src/api/bpm/disbursement/index.ts

@@ -76,16 +76,21 @@ export const DisbursementApi = {
   getTeamMember: async (params: any) => {
     return await request.get({ url: `/bpm/disbursement/get-member`, params })
   },
+  
+  getValidTeamMembers: async (params: any) => {
+    return await request.get({ url: `/bpm/disbursement/get-valid-members`, params })
+  },
+  
   addTeamMember: async (data: any) => {
     return await request.post({ url: `/bpm/disbursement/add-member` , data })
   },
   deleteTeamMember: async (id: any, userId: any) => {
     return await request.delete({ url: `/bpm/disbursement/delete-member?id=` + id + "&userId=" + userId  })
   },
-  // 修改资金拨付流程表
+
   updateTeamMember: async (data: any) => {
     // console.log(data)
-    return await request.put({ url: `/bpm/disbursement/update-member`, data })
+    return await request.post({ url: `/bpm/disbursement/update-team-member`, data })
   },
 
 }

+ 52 - 1
src/api/gislayer/gisform/index.ts

@@ -19,6 +19,23 @@ export interface GisFormVO {
   shpName: string // shp表名
 }
 
+// 用户权限 VO
+export interface UserAuthorityVO {
+  userId: number      // 用户ID
+  maturityTime?: Date // 过期时间
+  onlyRead: number    // 权限类型: 1=管理权限, 2=操作权限, 3=只读权限
+  layer: string       // 图层名称
+  nickname?: string   // 用户昵称
+  deptName?: string   // 部门名称
+  mobile?: string     // 手机号码
+}
+
+// 团队成员批量更新 VO
+export interface TeamMemberUpdateVO {
+  layer: string               // 图层名称
+  list: UserAuthorityVO[]     // 成员列表
+}
+
 // 图层表单 API
 export const GisFormApi = {
   // 查询图层表单列表
@@ -48,6 +65,40 @@ export const GisFormApi = {
 
   // 导出图层表单 Excel
   exportGisForm: async (params) => {
-    return await request.download({ url: `/layer/gis-form/export-excel`, params })
+    return await request.download({ url: `/layer/gis-name/export-excel`, params })
+  },
+
+  setAuthority: async (data: any) => {
+    return await request.post({ url: `/layer/gis-name/set-authority`, data })
+  },
+
+  getAuthorityRole: async (layer: string) => {
+    return await request.get({ url: `/layer/gis-name/get-authority-role?layer=` + layer })
+  },
+
+  getAuthorityUser: async (layer: string) => {
+    return await request.get({ url: `/layer/gis-name/get-authority-user?layer=` + layer })
+  },
+  getTeamMember: async (params: any) => {
+    return await request.get({ url: `/layer/gis-name/get-member`, params })
+  },
+  addTeamMember: async (data: any) => {
+    return await request.post({ url: `/layer/gis-name/add-member` , data })
+  },
+  deleteTeamMember: async (layer: any, userId: any) => {
+    return await request.delete({ url: `/layer/gis-name/delete-member?layer=` + layer + "&userId=" + userId  })
+  },
+  getUserLayer:async (params: any) => {
+    return await request.get({ url: `/layer/gis-name/getlayerByUserId`, params })
+  },
+  
+  // 批量更新团队成员
+  updateTeamMember: async (data: any) => {
+    return await request.post({ url: `/layer/gis-name/update-team-member`, data })
+  },
+  
+  // 批量更新团队成员(有过期时间)
+  updateBatchMember: async (data: TeamMemberUpdateVO) => {
+    return await request.put({ url: `/layer/gis-name/update-batch-member`, data })
   },
 }

+ 0 - 1
src/api/layer/gisname/index.ts

@@ -1,5 +1,4 @@
 import request from '@/config/axios'
-import { pa } from 'element-plus/es/locale'
 
 // shp名 VO
 export interface GisNameVO {

+ 436 - 212
src/views/bpm/disbursement/AuthorityForm.vue

@@ -1,268 +1,492 @@
 <template>
-  <Dialog title="权限管理" v-model="dialogVisible" width="70%">
-    <el-form
-      ref="formRef"
-      :model="formData"
-      label-width="100px"
-      v-loading="formLoading"
-    >
-<!--      <el-form-item label="角色">-->
-<!--        <el-select v-model="formData.roleIds" multiple placeholder="请选择角色">-->
-<!--          <el-option v-for="item in roleList" :key="item.id" :label="item.name" :value="item.id" />-->
-<!--        </el-select>-->
-<!--      </el-form-item>-->
-
-<!--      <el-form-item label="用户">-->
-<!--        <el-select v-model="formData.userIds" multiple placeholder="请选择用户">-->
-<!--          <el-option v-for="item in userOptions" :key="item.id" :label="item.nickname" :value="item.id" />-->
-<!--        </el-select>-->
-<!--      </el-form-item>-->
-
-<!--      <el-form-item label="只读角色">-->
-<!--        <el-select v-model="formData.readRoleIds" multiple placeholder="请选择角色">-->
-<!--          <el-option v-for="item in roleList" :key="item.id" :label="item.name" :value="item.id" />-->
-<!--        </el-select>-->
-<!--      </el-form-item>-->
-
-<!--      <el-form-item label="只读用户">-->
-<!--        <el-select v-model="formData.readUserIds" multiple placeholder="请选择用户">-->
-<!--          <el-option v-for="item in userOptions" :key="item.id" :label="item.nickname" :value="item.id" />-->
-<!--        </el-select>-->
-<!--      </el-form-item>-->
-
-    </el-form>
+  <Dialog title="用户权限管理"  v-model="dialogVisible" width="75%">
     <ContentWrap>
-        <el-form
-          class="-mb-15px"
-          :model="queryParams"
-          ref="queryFormRef"
-          :inline="true"
-          label-width="100px"
-        >
-          <el-form-item label="昵称" prop="username">
-            <el-input
-              v-model="queryParams.nickname"
-              placeholder="请输入用户昵称"
-              clearable
-              @keyup.enter="handleQuery"
-              class="!w-240px"
-            />
-          </el-form-item>
-          <el-form-item label="手机号码" prop="mobile">
-            <el-input
-              v-model="queryParams.mobile"
-              placeholder="请输入手机号码"
-              clearable
-              @keyup.enter="handleQuery"
-              class="!w-240px"
-            />
-          </el-form-item>
-
-          <el-form-item>
-            <el-button @click="handleQuery"><Icon icon="ep:search" />搜索</el-button>
-            <el-button @click="resetQuery"><Icon icon="ep:refresh" />重置</el-button>
+      <!-- 搜索表单区域 -->
+      <el-form :model="queryParams" inline class="mb-15px">
+        <el-form-item label="用户昵称">
+          <el-input v-model="queryParams.nickname" placeholder="请输入用户昵称" clearable @keyup.enter="getList" />
+        </el-form-item>
+        <el-form-item label="手机号码">
+          <el-input v-model="queryParams.mobile" placeholder="请输入手机号码" clearable @keyup.enter="getList" />
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" @click="getList">
+            <Icon icon="ep:search" />搜索
+          </el-button>
+          <el-button
+@click="() => {
+            queryParams.nickname = undefined
+            queryParams.mobile = undefined
+            getList()
+          }">
+            <Icon icon="ep:refresh" />重置
+          </el-button>
+        </el-form-item>
+      </el-form>
 
-          </el-form-item>
-        </el-form>
-      </ContentWrap>
-    <ContentWrap>
-        <el-table v-loading="loading" :data="list">
-          <el-table-column label="用户编号" align="center" key="id" prop="id" />
-          <el-table-column
-            label="用户昵称"
-            align="center"
-            prop="nickname"
-            :show-overflow-tooltip="true"
-          />
-          <el-table-column
+      <!-- 用户列表表格 -->
+      <el-table v-loading="loading" :data="list" border stripe>
+        <!-- 用户选择 -->
+        <el-table-column label="用户" min-width="200">
+          <template #default="scope">
+            <div v-if="isSpecialUser(scope.row)" class="flex items-center">
+              {{ scope.row.nickname }}
+              <el-tag v-if="scope.row.type === 1" type="success" size="small" effect="dark" class="ml-5px">管理者</el-tag>
+              <el-tag v-if="scope.row.isSelf" type="info" size="small" effect="plain" class="ml-5px">创建者</el-tag>
+            </div>
+            <el-select
+                v-else
+                v-model="scope.row.userId"
+                placeholder="选择用户"
+                @change="handleUserChange(scope.row)"
+                filterable
+                clearable
+                class="w-full"
+            >
+              <el-option
+                  v-for="user in userOptions"
+                  :key="user.id"
+                  :label="user.nickname"
+                  :value="user.id"
+              />
+            </el-select>
+          </template>
+        </el-table-column>
+        <el-table-column
             label="部门"
             align="center"
-            key="deptName"
             prop="deptName"
+            min-width="120"
             :show-overflow-tooltip="true"
-          />
-          <el-table-column label="手机号码" align="center" prop="mobile" width="120" />
-          <el-table-column label="成员权限" key="status" min-width="200px">
-            <template #default="scope">
-              <el-select v-model="scope.row.onlyRead" laceholder="请选择成员权限"
-                @change="handlePermissionChange(scope.row)"
-                         :disabled="scope.row.isSelf"
-              >
-                <el-option label="管理权限" :value="1" />
-                <el-option label="操作权限" :value="2" />
-                <el-option label="只读权限" :value="3" />
-              </el-select>
-            </template>
-          </el-table-column>
-          <el-table-column label="操作" align="center" width="160">
-            <template #default="scope">
-              <div class="flex items-center justify-center">
-                <el-button
-                  type="primary"
-                  link
-                  @click="deleteQuery(scope.row.id)"
-                  :disabled="scope.row.isSelf"
-                >
-                  <Icon icon="ep:edit" />删除
-                </el-button>
+        />
+        <el-table-column label="手机号码" align="center" prop="mobile" min-width="120" />
+        <!-- 权限类型 -->
+        <el-table-column label="权限" width="120" align="center">
+          <template #default="scope">
+            <el-tag v-if="isSpecialUser(scope.row)" type="success">管理权限</el-tag>
+            <el-tag v-else type="success">查看权限</el-tag>
+
+          </template>
+        </el-table-column>
+        <el-table-column label="可巡检" width="120" align="center">
+          <template #default="scope">
+            <el-switch
+                v-model="scope.row.inspection"
+                :active-value="1"
+                :inactive-value="0"
+                active-text="是"
+                inactive-text="否"
+                class="ml-2"
+            />
+          </template>
+        </el-table-column>
+        <!-- 过期时间 -->
+        <el-table-column label="过期时间" min-width="220" align="center">
+          <template #default="scope">
+            <div v-if="isSpecialUser(scope.row)" class="flex flex-col items-center">
+              <span>永久有效</span> <el-tag type="success" size="small" effect="plain" class="mt-5px">管理部门</el-tag>
+            </div>
+            <div v-else>
+              <el-date-picker
+                  v-model="scope.row.maturityTime"
+                  type="datetime"
+                  placeholder="选择截止时间"
+                  class="w-full"
+                  @change="handleDateChange(scope.row)"
+                  :disabled-date="disabledDate"
+                  value-format="x"
+              />
+              <div class="mt-5px">
+                <el-tag v-if="scope.row.valid" type="success" size="small" effect="plain">
+                  <template v-if="scope.row.daysLeft">剩余 {{ scope.row.daysLeft }} 天</template>
+                  <template v-else>有效</template>
+                </el-tag>
+                <el-tag v-else-if="scope.row.valid === false" type="danger" size="small" effect="plain">已过期</el-tag>
               </div>
-            </template>
-          </el-table-column>
-        </el-table>
-        <Pagination
-          :total="total"
-          v-model:page="queryParams.pageNo"
-          v-model:limit="queryParams.pageSize"
-          @pagination="getList"
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column
+            label="创建时间"
+            align="center"
+            prop="createTime"
+            :formatter="dateFormatter"
+            min-width="150"
         />
-        <el-form :inline="true" label-width="100px">
-          <el-form-item label="添加用户">
-            <el-select v-model="queryParams.addUserId" placeholder="请选择用户" style="width: 200px;" >
-              <el-option v-for="item in userOptions" :key="item.id" :label="item.nickname" :value="item.id" />
-            </el-select>
-          </el-form-item>
-          <el-form-item>
-            <el-button @click="addQuery"><Icon icon="ep:plus" />添加</el-button>
-          </el-form-item>
-        </el-form>
+        <!-- 操作列 -->
+        <el-table-column label="操作" width="100" align="center" fixed="right">
+          <template #default="scope">
+            <el-tooltip v-if="isSpecialUser(scope.row)" content="权限角色无法删除" placement="top">
+              <span class="text-gray-400">
+                <Icon icon="ep:lock" />
+              </span>
+            </el-tooltip>
+            <el-button
+                v-else
+                type="danger"
+                link
+                @click="handleDeleteRow(scope.$index)"
+            >
+              <Icon icon="ep:delete" />删除
+            </el-button>
+          </template>
+        </el-table-column>
+      </el-table>
 
+      <!-- 添加按钮 -->
+      <div class="mt-15px flex justify-between">
+        <el-button @click="handleAddRow" type="primary">
+          <Icon icon="ep:plus" />添加用户
+        </el-button>
+        <div>
+          <span class="text-sm text-gray-500">总人数: {{ list.length }} 人</span>
+        </div>
+      </div>
     </ContentWrap>
+
     <template #footer>
-      <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
-      <el-button @click="dialogVisible = false">取 消</el-button>
+      <el-button @click="dialogVisible = false">取消</el-button>
+      <el-button @click="submitForm" type="primary" :loading="loading">提交</el-button>
     </template>
   </Dialog>
 </template>
+
 <script setup lang="ts">
-import { DisbursementApi } from '@/api/bpm/disbursement'
-import * as RoleApi from "@/api/system/role";
 import * as UserApi from "@/api/system/user";
-import  { ref }  from 'vue';
+import {DisbursementApi} from "@/api/bpm/disbursement";
+import {dateFormatter} from "@/utils/formatTime";
+import {ref, reactive, onMounted} from "vue";
+import {useMessage} from "@/hooks/web/useMessage";
+import { ElMessage, ElTable, ElTableColumn } from 'element-plus'
 
-/** 资金拨付流程表	 表单 */
-defineOptions({ name: 'AuthorityForm' })
-const { t } = useI18n() // 国际化
 const message = useMessage() // 消息弹窗
-const dialogVisible = ref(false) // 弹窗的是否展示
-const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
-const formRef = ref() // 表单 Ref
-const formData = ref({
-  addUserId : undefined,
-  projectId : undefined,
-  pageNo: 1,
-  pageSize: 10,
-  nickname: undefined,
-  mobile: undefined,
-  status: undefined,
-  deptId: undefined,
-  createTime: []
-})
-const loading = ref(true) // 列表的加载中
+const loading = ref(false) // 列表的加载中
 const total = ref(0) // 列表的总页数
-const list = ref([]) // 列表的数
+
+interface UserRow {
+  id?: number         // 记录ID
+  userId?: number      // 用户ID
+  maturityTime?: Date | string  // 过期时间
+  deptName?: string    // 部门名称
+  mobile?: string      // 手机号码
+  createTime?: Date | string    // 创建时间
+  onlyRead?: number    // 权限: 1=管理权限, 2=编辑, 3=只读
+  nickname?: string    // 用户昵称
+  type?: number        // 用户类型:1为管理者, 2为创建者
+  isSelf?: boolean     // 是否是当前用户
+  valid?: boolean      // 是否有效(未过期)
+  daysLeft?: number    // 剩余天数
+  inspection?: number  // 是否可巡检: 1=可以, 0=不可以
+}
+
 const queryParams = reactive({
-  addUserId : undefined,
-  projectId : -1,
+  addUserId: undefined,
+  projectId: -1,
   pageNo: 1,
   pageSize: 10,
   nickname: undefined,
   mobile: undefined,
   status: undefined,
   deptId: undefined,
-  createTime: []
+  createTime: [],
+  rows: {},
+})
+
+const submitData = ref({
+  projectId: undefined as number | undefined,
+  list: [] as UserRow[] // 用户ID => 过期时间
 })
-const queryFormRef = ref() // 搜索的表单
+
+// 判断是否为特殊用户(创建者或管理者)
+const isSpecialUser = (row: UserRow): boolean => {
+  return (row.type === 1) || (row.type === 2) || (row.isSelf === true);
+}
+
+// 禁用过去的日期
+const disabledDate = (time: Date) => {
+  return time.getTime() < Date.now() - 8.64e7; // 禁用今天之前的日期
+}
+
+// ---------- 核心数据 ----------
+const dialogVisible = ref(false)
+const list = ref<UserRow[]>([])          // 表格数据
+const userOptions = ref<UserApi.UserVO[]>([]) // 用户选项
+
+// ---------- 方法 ----------
+// 打开弹窗
+const open = async (projectId: number) => {
+
+  loading.value = true
+  dialogVisible.value = true
+  queryParams.projectId = projectId
+  submitData.value.projectId = projectId
+  // 加载用户选项
+  userOptions.value = await UserApi.getSimpleUserList()
+  // 加载已有数据
+  getList();
+}
 
 const getList = async () => {
   loading.value = true
   try {
-      const data = await DisbursementApi.getTeamMember(queryParams)
-      console.log(data)
-      list.value = data.list
-      total.value = data.total
+    const data = await DisbursementApi.getTeamMember(queryParams)
+    // 确保日期字段正确转换为Date对象
+    list.value = data.list.map(item => {
+      // 如果maturityTime是字符串,转换为Date对象以便于比较
+      if (item.maturityTime) {
+        if (typeof item.maturityTime === 'string') {
+          item.maturityTime = new Date(item.maturityTime);
+        }
+      } else {
+        // 默认7天后过期
+        item.maturityTime = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000);
+      }
+      
+      // 如果createTime是字符串,转换为Date对象
+      if (item.createTime && typeof item.createTime === 'string') {
+        item.createTime = new Date(item.createTime);
+      }
+      
+      // 默认权限为只读
+      if (item.onlyRead === undefined) {
+        item.onlyRead = 3;
+      }
+      
+      // 处理可巡检字段
+      if (item.canInspection !== undefined) {
+        item.inspection = item.canInspection;
+      } else {
+        item.inspection = 0; // 默认不可巡检
+      }
+      
+      // 更新过期状态和剩余天数
+      updateExpirationStatus(item);
+      
+      return item;
+    })
+    total.value = data.total
+    updateSubmitData() // 初始化提交数据
   } finally {
     loading.value = false
   }
 }
 
-const roleList = ref([] as RoleApi.RoleVO[]) // 角色的列表
-const userOptions = ref<UserApi.UserVO[]>([]) // 用户列表
-/** 打开弹窗 */
-const open = async ( id : number) => {
-    queryParams.projectId = id
-    getList();
-    dialogVisible.value = true
-    resetForm()
-    // 修改时,设置数据
-    roleList.value = await RoleApi.getSimpleRoleList()
-    userOptions.value = await UserApi.getSimpleUserList()
+// 处理用户选择变更
+const handleUserChange = (row: UserRow) => {
+  if (row.userId) {
+    // 查找选中的用户信息并填充其他字段
+    const selectedUser = userOptions.value.find(user => user.id === row.userId)
+    if (selectedUser) {
+      // 填充用户信息
+      row.deptName = (selectedUser as any).deptName || '';
+      row.mobile = selectedUser.mobile || '';
+      row.nickname = selectedUser.nickname || '';
+      
+      // 设置默认权限和过期时间
+      if (row.onlyRead === undefined) {
+        row.onlyRead = 3; // 默认只读
+      }
+      if (row.inspection === undefined) {
+        row.inspection = 0; // 默认不可巡检
+      }
+      if (!row.maturityTime) {
+        // 默认7天后过期
+        const defaultDate = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000);
+        // 格式化为字符串
+        row.maturityTime = defaultDate.toISOString().substring(0, 19).replace('T', ' ');
+        // 更新过期状态
+        updateExpirationStatus(row);
+      }
+    }
+  } else {
+    // 清空其他字段
+    row.deptName = undefined
+    row.mobile = undefined
+    row.nickname = undefined
+  }
+  updateSubmitData()
 }
 
-defineExpose({ open }) // 提供 open 方法,用于打开弹窗
-
-/** 提交表单 */
-const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
-const submitForm = async () => {
-    formLoading.value = true
-    try {
-        console.log(formData.value)
+// 处理权限变更
+const handlePermissionChange = (row: UserRow) => {
+  updateSubmitData()
+}
 
-        await DisbursementApi.setAuthority(formData.value);
+// 处理日期变更
+const handleDateChange = (row: UserRow) => {
+  updateExpirationStatus(row);
+  updateSubmitData();
+}
 
-        message.success(t('common.createSuccess'))
-        dialogVisible.value = false
-        // 发送操作成功的事件
-        emit('success')
-    } finally {
-        formLoading.value = false
+// 更新过期状态和剩余天数
+const updateExpirationStatus = (row: UserRow) => {
+  if (row.maturityTime) {
+    const maturityDate = typeof row.maturityTime === 'string' 
+      ? new Date(row.maturityTime)
+      : row.maturityTime;
+    const now = new Date();
+    row.valid = maturityDate > now;
+    
+    if (row.valid) {
+      // 计算剩余天数
+      const diffTime = maturityDate.getTime() - now.getTime();
+      row.daysLeft = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
+    } else {
+      row.daysLeft = 0;
     }
+  }
 }
 
-/** 重置按钮操作 */
-const addQuery = async () => {
-  await  DisbursementApi.addTeamMember(queryParams)
-  message.success(t('common.createSuccess'))
-  queryFormRef.value?.resetFields()
-  handleQuery()
+// 添加行
+const handleAddRow = () => {
+  // 默认7天后过期的日期
+  const defaultDate = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000);
+  const formattedDate = defaultDate.toISOString().substring(0, 19).replace('T', ' ');
+  
+  const newRow = { 
+    userId: undefined, 
+    maturityTime: formattedDate,
+    onlyRead: 3, // 默认只读 
+    valid: true,
+    daysLeft: 7,
+    inspection: 0 // 默认不可巡检
+  };
+  
+  list.value.push(newRow);
+  updateSubmitData();
 }
 
-
-/** 搜索按钮操作 */
-const handleQuery = () => {
-  queryParams.pageNo = 1
-  getList()
+// 删除行
+const handleDeleteRow = (index: number) => {
+  if (isSpecialUser(list.value[index])) {
+    message.warning('无法删除管理者或创建者')
+    return
+  }
+  list.value.splice(index, 1)
+  updateSubmitData()
 }
 
-/** 重置按钮操作 */
-const resetQuery = () => {
-  queryFormRef.value?.resetFields()
-  handleQuery()
+// 更新提交数据
+const updateSubmitData = () => {
+  submitData.value.list = list.value
+    .filter(row => row.userId && !isSpecialUser(row))
+    .map(row => {
+      // 确保maturityTime是正确的格式
+      let maturityTime = row.maturityTime;
+      if (maturityTime instanceof Date) {
+        maturityTime = maturityTime.toISOString().substring(0, 19).replace('T', ' ');
+      }
+      
+      return {
+        userId: row.userId,
+        maturityTime: maturityTime,
+        onlyRead: row.onlyRead || 3,
+        canInspection: row.inspection || 0
+      };
+    });
 }
 
-/** 删除人员按钮操作 */
-const deleteQuery = async (id : any) => {
-  await DisbursementApi.deleteTeamMember(queryParams.projectId,id)
-  message.success("删除成功!")
-  queryFormRef.value?.resetFields()
-  handleQuery()
+// 验证表单数据
+const validateForm = (): boolean => {
+  // 检查是否有未完成的行(排除特殊用户)
+  const incompleteRows = list.value
+    .filter(row => !isSpecialUser(row))
+    .filter(row => (row.userId && !row.maturityTime) || (!row.userId && row.maturityTime))
+  
+  if (incompleteRows.length > 0) {
+    message.warning('请完善所有用户的信息')
+    return false
+  }
+  
+  // 检查是否有重复的用户
+  const userIds = list.value.map(row => row.userId).filter(Boolean)
+  if (new Set(userIds).size !== userIds.length) {
+    message.warning('存在重复选择的用户,请检查')
+    return false
+  }
+  
+  return true
 }
 
-const handlePermissionChange =async (row) =>{
+// 提交表单
+const submitForm = async () => {
+  if (!validateForm()) return
+  
   loading.value = true
-  await DisbursementApi.updateTeamMember(row)
-  message.success("更新成功!")
-  loading.value = false
-}
-/** 重置表单 */
-const resetForm = () => {
-  formData.value = {
-    id: -1 ,
-    roleIds: [],
-    userIds :[],
-    userIds :[],
-    readRoleIds: [],
-    readUserIds :[]
+  try {
+    // 准备提交数据
+    const submitList = list.value
+      .filter(row => row.userId && !isSpecialUser(row))
+      .map(row => {
+        // 确保maturityTime是正确的格式
+        let maturityTime = row.maturityTime;
+        if (maturityTime instanceof Date) {
+          maturityTime = maturityTime.toISOString().substring(0, 19).replace('T', ' ');
+        }
+        
+        return {
+          userId: row.userId,
+          maturityTime: maturityTime,
+          onlyRead: row.onlyRead || 3,
+          canInspection: row.inspection || 0
+        };
+      });
+    
+    // 提交数据 - 使用批量更新接口
+    await DisbursementApi.updateTeamMember({
+      projectId: queryParams.projectId,
+      list: submitList
+    });
+    
+    message.success('操作成功');
+    dialogVisible.value = false;
+  } catch (error) {
+    console.error('提交失败:', error);
+    message.error('操作失败');
+  } finally {
+    loading.value = false;
   }
-  formRef.value?.resetFields()
 }
+
+defineExpose({ open }) // 暴露 open 方法
 </script>
+
+<style scoped>
+.ml-5px {
+  margin-left: 5px;
+}
+.mt-5px {
+  margin-top: 5px;
+}
+.text-gray-400 {
+  color: #9ca3af;
+}
+.text-gray-500 {
+  color: #6b7280;
+}
+.flex {
+  display: flex;
+}
+.items-center {
+  align-items: center;
+}
+.justify-center {
+  justify-content: center;
+}
+.justify-between {
+  justify-content: space-between;
+}
+.flex-col {
+  flex-direction: column;
+}
+.text-sm {
+  font-size: 0.875rem;
+  line-height: 1.25rem;
+}
+.mb-15px {
+  margin-bottom: 15px;
+}
+.w-full {
+  width: 100% !important;
+}
+</style>

+ 488 - 0
src/views/layer/gisname/AuthorityForm.vue

@@ -0,0 +1,488 @@
+<template>
+  <Dialog title="用户权限管理" v-model="dialogVisible" width="75%">
+    <ContentWrap>
+      <!-- 搜索表单区域 -->
+      <el-form :model="queryParams" inline class="mb-15px">
+        <el-form-item label="用户昵称">
+          <el-input v-model="queryParams.nickname" placeholder="请输入用户昵称" clearable @keyup.enter="getList" />
+        </el-form-item>
+        <el-form-item label="手机号码">
+          <el-input v-model="queryParams.mobile" placeholder="请输入手机号码" clearable @keyup.enter="getList" />
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" @click="getList">
+            <Icon icon="ep:search" />搜索
+          </el-button>
+          <el-button
+@click="() => {
+            queryParams.nickname = undefined
+            queryParams.mobile = undefined
+            getList()
+          }">
+            <Icon icon="ep:refresh" />重置
+          </el-button>
+        </el-form-item>
+      </el-form>
+
+      <!-- 用户列表表格 -->
+      <el-table v-loading="loading" :data="list" border stripe>
+        <!-- 用户选择 -->
+        <el-table-column label="用户" min-width="200">
+          <template #default="scope">
+            <div v-if="isSpecialUser(scope.row)" class="flex items-center">
+              {{ scope.row.nickname }}
+              <el-tag v-if="scope.row.isSelf" type="info" size="small" effect="plain" class="ml-5px">当前用户</el-tag>
+            </div>
+            <el-select
+                v-else
+                v-model="scope.row.userId"
+                placeholder="选择用户"
+                @change="handleUserChange(scope.row)"
+                filterable
+                clearable
+                class="w-full"
+            >
+              <el-option
+                  v-for="user in userOptions"
+                  :key="user.id"
+                  :label="user.nickname"
+                  :value="user.id"
+              />
+            </el-select>
+          </template>
+        </el-table-column>
+        <el-table-column
+            label="部门"
+            align="center"
+            prop="deptName"
+            min-width="120"
+            :show-overflow-tooltip="true"
+        />
+        <el-table-column label="手机号码" align="center" prop="mobile" min-width="120" />
+
+        <!-- 过期时间 -->
+        <el-table-column label="过期时间" min-width="220" align="center">
+          <template #default="scope">
+            <div v-if="isSpecialUser(scope.row)" class="flex flex-col items-center">
+              <span>永久有效</span> 
+              <el-tag type="success" size="small" effect="plain" class="mt-5px">系统角色</el-tag>
+            </div>
+            <div v-else>
+              <el-date-picker
+                  v-model="scope.row.maturityTime"
+                  type="datetime"
+                  placeholder="选择截止时间"
+                  class="w-full"
+                  @change="handleDateChange(scope.row)"
+                  :disabled-date="disabledDate"
+                  value-format="x"
+              />
+              <div class="mt-5px">
+                <el-tag v-if="scope.row.valid" type="success" size="small" effect="plain">
+                  <template v-if="scope.row.daysLeft">剩余 {{ scope.row.daysLeft }} 天</template>
+                  <template v-else>有效</template>
+                </el-tag>
+                <el-tag v-else-if="scope.row.valid === false" type="danger" size="small" effect="plain">已过期</el-tag>
+              </div>
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column
+            label="创建时间"
+            align="center"
+            prop="createTime"
+            :formatter="dateFormatter"
+            min-width="150"
+        />
+        <!-- 操作列 -->
+        <el-table-column label="操作" width="100" align="center" fixed="right">
+          <template #default="scope">
+            <el-tooltip v-if="isSpecialUser(scope.row)" content="权限角色无法删除" placement="top">
+              <span class="text-gray-400">
+                <Icon icon="ep:lock" />
+              </span>
+            </el-tooltip>
+            <el-button
+                v-else
+                type="danger"
+                link
+                @click="handleDeleteRow(scope.$index)"
+            >
+              <Icon icon="ep:delete" />删除
+            </el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <!-- 添加按钮 -->
+      <div class="mt-15px flex justify-between">
+        <el-button @click="handleAddRow" type="primary">
+          <Icon icon="ep:plus" />添加用户
+        </el-button>
+        <div>
+          <span class="text-sm text-gray-500">总人数: {{ list.length }} 人</span>
+        </div>
+      </div>
+    </ContentWrap>
+
+    <template #footer>
+      <el-button @click="dialogVisible = false">取消</el-button>
+      <el-button @click="submitForm" type="primary" :loading="loading">提交</el-button>
+    </template>
+  </Dialog>
+</template>
+
+<script setup lang="ts">
+import { GisFormApi } from '@/api/gislayer/gisform/index.ts'
+import * as UserApi from "@/api/system/user";
+import { dateFormatter } from "@/utils/formatTime";
+import { ref, reactive, onMounted } from "vue";
+import { useMessage } from "@/hooks/web/useMessage";
+import { ElMessage, ElTable, ElTableColumn } from 'element-plus'
+
+/** 图层权限表单 */
+defineOptions({ name: 'LayerAuthorityForm' })
+const message = useMessage() // 消息弹窗
+const loading = ref(false) // 列表的加载中
+const total = ref(0) // 列表的总页数
+
+interface UserRow {
+  id?: number         // 记录ID
+  userId?: number      // 用户ID
+  maturityTime?: Date | string  // 过期时间
+  deptName?: string    // 部门名称
+  mobile?: string      // 手机号码
+  createTime?: Date | string    // 创建时间
+  onlyRead?: number    // 权限类型:1=管理权限, 2=操作权限, 3=只读权限
+  nickname?: string    // 用户昵称
+  isSelf?: boolean     // 是否是当前用户
+  valid?: boolean      // 是否有效(未过期)
+  daysLeft?: number    // 剩余天数
+  layer?: string       // 图层名称
+  isDeleted?: boolean  // 是否标记为删除(本地状态)
+}
+
+const dialogVisible = ref(false)
+const list = ref<UserRow[]>([])          // 表格数据
+const userOptions = ref<UserApi.UserVO[]>([]) // 用户选项
+const deletedUserIds = ref<number[]>([]) // 存储已标记为删除的用户ID
+
+const queryParams = reactive({
+  addUserId: undefined,
+  layer: undefined,
+  pageNo: 1,
+  pageSize: 10,
+  nickname: undefined,
+  mobile: undefined,
+  status: undefined,
+  deptId: undefined,
+  createTime: [],
+})
+
+const submitData = ref({
+  layer: undefined as string | undefined,
+  list: [] as UserRow[],
+  deletedUserIds: [] as number[] // 存储要删除的用户ID
+})
+
+// 判断是否为特殊用户(管理者或当前用户)
+const isSpecialUser = (row: UserRow): boolean => {
+  return (row.onlyRead === 1) || (row.isSelf === true);
+}
+
+// 禁用过去的日期
+const disabledDate = (time: Date) => {
+  return time.getTime() < Date.now() - 8.64e7; // 禁用今天之前的日期
+}
+
+// 打开弹窗
+const open = async (shpName: string) => {
+  dialogVisible.value = true
+  queryParams.layer = shpName
+  submitData.value.layer = shpName
+  
+  // 重置删除列表
+  deletedUserIds.value = []
+  
+  // 加载用户选项
+  userOptions.value = await UserApi.getSimpleUserList()
+  
+  // 加载已有数据
+  getList();
+}
+
+const getList = async () => {
+  loading.value = true
+  try {
+    const data = await GisFormApi.getTeamMember(queryParams)
+    // 处理数据,确保日期字段格式正确
+    list.value = data.list.map(item => {
+      // 如果maturityTime是字符串,转换为Date对象以便于比较
+      if (item.maturityTime) {
+        if (typeof item.maturityTime === 'string') {
+          item.maturityTime = new Date(item.maturityTime);
+        }
+      } else {
+        // 默认7天后过期
+        item.maturityTime = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000);
+      }
+      
+      // 如果createTime是字符串,转换为Date对象
+      if (item.createTime && typeof item.createTime === 'string') {
+        item.createTime = new Date(item.createTime);
+      }
+      
+      // 默认权限为只读
+      if (item.onlyRead === undefined) {
+        item.onlyRead = 3;
+      }
+      
+      // 更新过期状态和剩余天数
+      updateExpirationStatus(item);
+      
+      return item;
+    });
+    
+    total.value = data.total
+    updateSubmitData() // 初始化提交数据
+  } finally {
+    loading.value = false
+  }
+}
+
+// 处理用户选择变更
+const handleUserChange = (row: UserRow) => {
+  if (row.userId) {
+    // 查找选中的用户信息并填充其他字段
+    const selectedUser = userOptions.value.find(user => user.id === row.userId)
+    if (selectedUser) {
+      // 填充用户信息
+      row.deptName = (selectedUser as any).deptName || '';
+      row.mobile = selectedUser.mobile || '';
+      row.nickname = selectedUser.nickname || '';
+      
+      // 设置默认权限和过期时间
+      if (row.onlyRead === undefined) {
+        row.onlyRead = 3; // 默认只读
+      }
+      if (!row.maturityTime) {
+        // 默认7天后过期
+        const defaultDate = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000);
+        // 格式化为字符串
+        row.maturityTime = defaultDate.toISOString().substring(0, 19).replace('T', ' ');
+        // 更新过期状态
+        updateExpirationStatus(row);
+      }
+    }
+  } else {
+    // 清空其他字段
+    row.deptName = undefined
+    row.mobile = undefined
+    row.nickname = undefined
+  }
+  updateSubmitData()
+}
+
+// 处理权限变更
+const handlePermissionChange = (row: UserRow) => {
+  updateSubmitData()
+}
+
+// 处理日期变更
+const handleDateChange = (row: UserRow) => {
+  updateExpirationStatus(row);
+  updateSubmitData();
+}
+
+// 更新过期状态和剩余天数
+const updateExpirationStatus = (row: UserRow) => {
+  if (row.maturityTime) {
+    const maturityDate = typeof row.maturityTime === 'string' 
+      ? new Date(row.maturityTime)
+      : row.maturityTime;
+    const now = new Date();
+    row.valid = maturityDate > now;
+    
+    if (row.valid) {
+      // 计算剩余天数
+      const diffTime = maturityDate.getTime() - now.getTime();
+      row.daysLeft = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
+    } else {
+      row.daysLeft = 0;
+    }
+  }
+}
+
+// 添加行
+const handleAddRow = () => {
+  // 默认7天后过期的日期
+  const defaultDate = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000);
+  const formattedDate = defaultDate.toISOString().substring(0, 19).replace('T', ' ');
+  
+  const newRow = { 
+    userId: undefined, 
+    maturityTime: formattedDate,
+    onlyRead: 3, // 默认只读 
+    valid: true,
+    daysLeft: 7,
+    layer: queryParams.layer
+  };
+  
+  list.value.push(newRow);
+  updateSubmitData();
+}
+
+// 删除行
+const handleDeleteRow = (index: number) => {
+  const row = list.value[index];
+  
+  if (isSpecialUser(row)) {
+    message.warning('无法删除管理者或当前用户')
+    return
+  }
+  
+  // 如果是已有记录(有ID),将用户ID添加到要删除的列表中
+  if (row.id && row.userId) {
+    deletedUserIds.value.push(row.userId);
+  }
+  
+  // 从列表中移除
+  list.value.splice(index, 1);
+  updateSubmitData();
+}
+
+// 更新提交数据
+const updateSubmitData = () => {
+  // 更新要提交的用户列表
+  submitData.value.list = list.value
+    .filter(row => row.userId && !isSpecialUser(row))
+    .map(row => {
+      // 确保maturityTime是正确的格式
+      let maturityTime = row.maturityTime;
+      if (maturityTime instanceof Date) {
+        maturityTime = maturityTime.toISOString().substring(0, 19).replace('T', ' ');
+      }
+      
+      return {
+        userId: row.userId,
+        maturityTime: maturityTime,
+        onlyRead: row.onlyRead || 3,
+        layer: queryParams.layer
+      };
+    });
+    
+  // 更新要删除的用户ID列表
+  submitData.value.deletedUserIds = [...deletedUserIds.value];
+}
+
+// 验证表单数据
+const validateForm = (): boolean => {
+  // 检查是否有未完成的行(排除特殊用户)
+  const incompleteRows = list.value
+    .filter(row => !isSpecialUser(row))
+    .filter(row => (row.userId && !row.maturityTime) || (!row.userId && row.maturityTime))
+  
+  if (incompleteRows.length > 0) {
+    message.warning('请完善所有用户的信息')
+    return false
+  }
+  
+  // 检查是否有重复的用户
+  const userIds = list.value.map(row => row.userId).filter(Boolean)
+  if (new Set(userIds).size !== userIds.length) {
+    message.warning('存在重复选择的用户,请检查')
+    return false
+  }
+  
+  return true
+}
+
+/** 提交表单 */
+const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
+const submitForm = async () => {
+  if (!validateForm()) return
+  
+  loading.value = true
+  try {
+    // 准备提交数据
+    const submitList = list.value
+      .filter(row => row.userId && !isSpecialUser(row))
+      .map(row => {
+        // 确保maturityTime是正确的格式
+        let maturityTime = row.maturityTime;
+        if (maturityTime instanceof Date) {
+          maturityTime = maturityTime.toISOString().substring(0, 19).replace('T', ' ');
+        }
+        
+        return {
+          userId: row.userId,
+          maturityTime: maturityTime,
+          onlyRead: row.onlyRead || 3,
+          layer: queryParams.layer
+        };
+      });
+    
+    // 处理删除操作 - 如果有需要删除的用户ID,则传递给后端
+    const submitData = {
+      layer: queryParams.layer,
+      list: submitList,
+      deletedUserIds: deletedUserIds.value
+    };
+    
+    // 提交数据 - 使用批量更新接口,同时处理删除
+    await GisFormApi.updateBatchMember(submitData);
+    
+    message.success('操作成功');
+    dialogVisible.value = false;
+    // 发送操作成功的事件
+    emit('success')
+  } catch (error) {
+    console.error('提交失败:', error);
+    message.error('操作失败');
+  } finally {
+    loading.value = false;
+  }
+}
+
+defineExpose({ open }) // 暴露 open 方法,用于打开弹窗
+</script>
+
+<style scoped>
+.ml-5px {
+  margin-left: 5px;
+}
+.mt-5px {
+  margin-top: 5px;
+}
+.text-gray-400 {
+  color: #9ca3af;
+}
+.text-gray-500 {
+  color: #6b7280;
+}
+.flex {
+  display: flex;
+}
+.items-center {
+  align-items: center;
+}
+.justify-center {
+  justify-content: center;
+}
+.justify-between {
+  justify-content: space-between;
+}
+.flex-col {
+  flex-direction: column;
+}
+.text-sm {
+  font-size: 0.875rem;
+  line-height: 1.25rem;
+}
+.mb-15px {
+  margin-bottom: 15px;
+}
+.w-full {
+  width: 100% !important;
+}
+</style>

+ 17 - 2
src/views/layer/gisname/index.vue

@@ -134,7 +134,7 @@
       <el-table-column label="描述" align="center" prop="description" />
       <el-table-column label="符号化模型" align="center" prop="symbolizeModel" />
       <el-table-column label="文本显示" align="center" prop="textDisplay" />
-      <el-table-column label="操作" align="center">
+      <el-table-column label="操作" align="center" width="250">
         <template #default="scope">
           <el-button
             link
@@ -152,6 +152,13 @@
           >
             删除
           </el-button>
+            <el-button
+                    link
+                    type="primary"
+                    @click="authority(scope.row.shpName)"
+            >
+                权限
+            </el-button>
         </template>
       </el-table-column>
     </el-table>
@@ -166,6 +173,8 @@
 
   <!-- 表单弹窗:添加/修改 -->
   <GisNameForm ref="formRef" @success="getList" />
+  <AuthorityForm ref="authorityRef" @success="getList" />
+
 </template>
 
 <script setup lang="ts">
@@ -175,6 +184,7 @@ import download from '@/utils/download'
 import { GisNameApi, GisNameVO } from '@/api/layer/gisname'
 import GisNameForm from './GisNameForm.vue'
 
+import AuthorityForm from './AuthorityForm.vue'
 /** shp名 列表 */
 defineOptions({ name: 'GisName' })
 
@@ -204,7 +214,8 @@ const exportLoading = ref(false) // 导出的加载中
 const getList = async () => {
   loading.value = true
   try {
-    const data = await GisNameApi.getShpAllRow(queryParams)
+    console.log(queryParams, 'queryParams')
+    const data = await GisNameApi.getGisNamePage(queryParams)
     list.value = data.list
     total.value = data.total
   } finally {
@@ -258,6 +269,10 @@ const handleExport = async () => {
   }
 }
 
+const authorityRef = ref();
+const authority = (shpName?: string) => {
+    authorityRef.value.open(shpName)
+}
 /** 初始化 **/
 onMounted(() => {
   getList()

+ 264 - 0
src/views/system/user/AuthorityForm.vue

@@ -0,0 +1,264 @@
+<template>
+  <Dialog title="权限管理" v-model="dialogVisible" width="70%">
+    <el-form
+      ref="formRef"
+      :model="formData"
+      label-width="100px"
+      v-loading="formLoading"
+    >
+<!--      <el-form-item label="角色">-->
+<!--        <el-select v-model="formData.roleIds" multiple placeholder="请选择角色">-->
+<!--          <el-option v-for="item in roleList" :key="item.id" :label="item.name" :value="item.id" />-->
+<!--        </el-select>-->
+<!--      </el-form-item>-->
+
+<!--      <el-form-item label="用户">-->
+<!--        <el-select v-model="formData.userIds" multiple placeholder="请选择用户">-->
+<!--          <el-option v-for="item in userOptions" :key="item.id" :label="item.nickname" :value="item.id" />-->
+<!--        </el-select>-->
+<!--      </el-form-item>-->
+
+<!--      <el-form-item label="只读角色">-->
+<!--        <el-select v-model="formData.readRoleIds" multiple placeholder="请选择角色">-->
+<!--          <el-option v-for="item in roleList" :key="item.id" :label="item.name" :value="item.id" />-->
+<!--        </el-select>-->
+<!--      </el-form-item>-->
+
+<!--      <el-form-item label="只读用户">-->
+<!--        <el-select v-model="formData.readUserIds" multiple placeholder="请选择用户">-->
+<!--          <el-option v-for="item in userOptions" :key="item.id" :label="item.nickname" :value="item.id" />-->
+<!--        </el-select>-->
+<!--      </el-form-item>-->
+
+    </el-form>
+    <ContentWrap>
+        <el-form
+          class="-mb-15px"
+          :model="queryParams"
+          ref="queryFormRef"
+          :inline="true"
+          label-width="100px"
+        >
+          <el-form-item label="昵称" prop="username">
+            <el-input
+              v-model="queryParams.nickname"
+              placeholder="请输入用户昵称"
+              clearable
+              @keyup.enter="handleQuery"
+              class="!w-240px"
+            />
+          </el-form-item>
+          <el-form-item label="手机号码" prop="mobile">
+            <el-input
+              v-model="queryParams.mobile"
+              placeholder="请输入手机号码"
+              clearable
+              @keyup.enter="handleQuery"
+              class="!w-240px"
+            />
+          </el-form-item>
+
+          <el-form-item>
+            <el-button @click="handleQuery"><Icon icon="ep:search" />搜索</el-button>
+            <el-button @click="resetQuery"><Icon icon="ep:refresh" />重置</el-button>
+
+          </el-form-item>
+        </el-form>
+      </ContentWrap>
+    <ContentWrap>
+        <el-table v-loading="loading" :data="list">
+          <el-table-column
+            label="图层"
+            align="center"
+            key="layer"
+            prop="layer"
+            :show-overflow-tooltip="true"
+          />
+          <el-table-column
+              label="到期时间"
+              align="center"
+              prop="maturityTime"
+              :formatter="dateFormatter"
+              width="180"
+          />
+          <el-table-column
+              label="创建时间"
+              align="center"
+              prop="createTime"
+              :formatter="dateFormatter"
+              width="180"
+          />
+          <el-table-column label="操作" align="center" width="160">
+            <template #default="scope">
+              <div class="flex items-center justify-center">
+                <el-button
+                  type="primary"
+                  link
+                  @click="deleteQuery(scope.row.id)"
+                  :disabled="scope.row.isSelf"
+                >
+                  <Icon icon="ep:edit" />删除
+                </el-button>
+              </div>
+            </template>
+          </el-table-column>
+        </el-table>
+        <Pagination
+          :total="total"
+          v-model:page="queryParams.pageNo"
+          v-model:limit="queryParams.pageSize"
+          @pagination="getList"
+        />
+        <el-form :inline="true" label-width="100px">
+          <el-form-item label="添加用户">
+            <el-select v-model="queryParams.addUserId" placeholder="请选择用户" style="width: 200px;" >
+              <el-option v-for="item in userOptions" :key="item.id" :label="item.nickname" :value="item.id" />
+            </el-select>
+          </el-form-item>
+          <el-form-item>
+            <el-button @click="addQuery"><Icon icon="ep:plus" />添加</el-button>
+          </el-form-item>
+        </el-form>
+
+    </ContentWrap>
+    <template #footer>
+      <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
+      <el-button @click="dialogVisible = false">取 消</el-button>
+    </template>
+  </Dialog>
+</template>
+<script setup lang="ts">
+import { GisFormApi } from '@/api/gislayer/gisform/index.ts'
+import * as RoleApi from "@/api/system/role";
+import * as UserApi from "@/api/system/user";
+import  { ref }  from 'vue';
+import {dateFormatter} from "@/utils/formatTime";
+
+/** 资金拨付流程表	 表单 */
+defineOptions({ name: 'LayerAuthorityForm' })
+const { t } = useI18n() // 国际化
+const message = useMessage() // 消息弹窗
+const dialogVisible = ref(false) // 弹窗的是否展示
+const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
+const formRef = ref() // 表单 Ref
+const formData = ref({
+  addUserId : undefined,
+  projectId : undefined,
+  pageNo: 1,
+  pageSize: 10,
+  nickname: undefined,
+  mobile: undefined,
+  status: undefined,
+  deptId: undefined,
+  createTime: []
+})
+const loading = ref(true) // 列表的加载中
+const total = ref(0) // 列表的总页数
+const list = ref([]) // 列表的数
+const queryParams = reactive({
+  addUserId : undefined,
+  layer : undefined,
+  pageNo: 1,
+  pageSize: 10,
+  nickname: undefined,
+  mobile: undefined,
+  status: undefined,
+  deptId: undefined,
+  createTime: [],
+  userId : undefined
+})
+const queryFormRef = ref() // 搜索的表单
+
+const getList = async () => {
+  loading.value = true
+  try {
+      const data = await GisFormApi.getUserLayer(queryParams)
+      console.log(data)
+      list.value = data.list
+      total.value = data.total
+  } finally {
+    loading.value = false
+  }
+}
+
+const roleList = ref([] as RoleApi.RoleVO[]) // 角色的列表
+const userOptions = ref<UserApi.UserVO[]>([]) // 用户列表
+/** 打开弹窗 */
+const open = async ( userId : any) => {
+    queryParams.userId = userId
+    getList();
+    dialogVisible.value = true
+    resetForm()
+    // 修改时,设置数据
+    roleList.value = await RoleApi.getSimpleRoleList()
+    userOptions.value = await UserApi.getSimpleUserList()
+}
+
+defineExpose({ open }) // 提供 open 方法,用于打开弹窗
+
+/** 提交表单 */
+const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
+const submitForm = async () => {
+    formLoading.value = true
+    try {
+        console.log(formData.value)
+
+        await GisFormApi.setAuthority(formData.value);
+
+        message.success(t('common.createSuccess'))
+        dialogVisible.value = false
+        // 发送操作成功的事件
+        emit('success')
+    } finally {
+        formLoading.value = false
+    }
+}
+
+/** 重置按钮操作 */
+const addQuery = async () => {
+  await  GisFormApi.addTeamMember(queryParams)
+  message.success(t('common.createSuccess'))
+  queryFormRef.value?.resetFields()
+  handleQuery()
+}
+
+
+/** 搜索按钮操作 */
+const handleQuery = () => {
+  queryParams.pageNo = 1
+  getList()
+}
+
+/** 重置按钮操作 */
+const resetQuery = () => {
+  queryFormRef.value?.resetFields()
+  handleQuery()
+}
+
+/** 删除人员按钮操作 */
+const deleteQuery = async (id : any) => {
+  await GisFormApi.deleteTeamMember(queryParams.layer,id)
+  message.success("删除成功!")
+  queryFormRef.value?.resetFields()
+  handleQuery()
+}
+
+// const handlePermissionChange =async (row) =>{
+//   loading.value = true
+//   await GisFormApi.updateTeamMember(row)
+//   message.success("更新成功!")
+//   loading.value = false
+// }
+/** 重置表单 */
+const resetForm = () => {
+  formData.value = {
+    id: -1 ,
+    roleIds: [],
+    userIds :[],
+    userIds :[],
+    readRoleIds: [],
+    readUserIds :[]
+  }
+  formRef.value?.resetFields()
+}
+</script>

+ 18 - 1
src/views/system/user/index.vue

@@ -175,7 +175,7 @@
             :formatter="dateFormatter"
             width="180"
           />
-          <el-table-column label="操作" align="center" width="160">
+          <el-table-column label="操作" align="center" width="200">
             <template #default="scope">
               <div class="flex items-center justify-center">
                 <el-button
@@ -186,6 +186,13 @@
                 >
                   <Icon icon="ep:edit" />修改
                 </el-button>
+                <el-button
+                    link
+                    type="primary"
+                    @click="authority(scope.row.id)"
+                >
+                  图层权限
+                </el-button>
                 <el-dropdown
                   @command="(command) => handleCommand(command, scope.row)"
                   v-hasPermi="[
@@ -238,6 +245,8 @@
   <UserImportForm ref="importFormRef" @success="getList" />
   <!-- 分配角色 -->
   <UserAssignRoleForm ref="assignRoleFormRef" @success="getList" />
+
+  <AuthorityForm ref="authorityRef" @success="getList" />
 </template>
 <script lang="ts" setup>
 import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
@@ -251,6 +260,8 @@ import UserForm from './UserForm.vue'
 import UserImportForm from './UserImportForm.vue'
 import UserAssignRoleForm from './UserAssignRoleForm.vue'
 import DeptTree from './DeptTree.vue'
+import GisNameForm from "@/views/layer/gisname/GisNameForm.vue";
+import AuthorityForm from "./AuthorityForm.vue";
 
 defineOptions({ name: 'SystemUser' })
 
@@ -404,6 +415,12 @@ const handleRole = (row: UserApi.UserVO) => {
   assignRoleFormRef.value.open(row)
 }
 
+const authorityRef = ref();
+
+const authority = (id ?: number) => {
+  authorityRef.value.open(id)
+}
+
 /** 初始化 */
 onMounted(() => {
   getList()