Prechádzať zdrojové kódy

pms 查询指定角色的用户

zhangcl 1 mesiac pred
rodič
commit
e155b06807

+ 2 - 1
src/locales/zh-CN.ts

@@ -408,7 +408,7 @@ export default {
   profile: {
     user: {
       title: '个人信息',
-      username: '用户名称',
+      username: '用户账号',
       nickname: '用户昵称',
       mobile: '手机号码',
       email: '用户邮箱',
@@ -427,6 +427,7 @@ export default {
       userSocial: '社交信息'
     },
     rules: {
+      username: '请输入用户账号',
       nickname: '请输入用户昵称',
       mail: '请输入邮箱地址',
       truemail: '请输入正确的邮箱地址',

+ 1 - 12
src/views/pms/iotmainworkorder/DeviceAlarmBomList.vue

@@ -89,9 +89,6 @@
 
 <script setup lang="ts">
 import { DictDataVO } from '@/api/system/dict/dict.data'
-import * as ModelApi from '@/api/pms/model'
-import { DICT_TYPE } from '@/utils/dict'
-import { dateFormatter } from '@/utils/formatTime'
 import dayjs from 'dayjs'
 import { IotMainWorkOrderBomApi, IotMainWorkOrderBomVO } from '@/api/pms/iotmainworkorderbom'
 import { IotMaintenanceBomApi, IotMaintenanceBomVO } from '@/api/pms/iotmaintenancebom'
@@ -124,10 +121,6 @@ const selectRow = (row) => {
   dialogVisible.value = false
 }
 
-// 点击整行选中
-const handleRowClick = (row) => {
-  selectRow(row)
-}
 const open = async (id?: number, flag?: string, deviceId?: number) => {
   await nextTick() // 确保DOM更新完成
   queryParams.deviceId = deviceId
@@ -275,11 +268,7 @@ const resetQuery = () => {
   queryFormRef.value.resetFields()
   handleQuery()
 }
-/** 初始化 **/
-// onMounted(async () => {
-//   await getList()
-//   // 查询字典(精简)列表
-// })
+
 </script>
 <style lang="scss">
 .no-label-radio .el-radio__label {

+ 1 - 66
src/views/pms/iotmainworkorder/IotDeviceMainAlarm.vue

@@ -120,7 +120,6 @@ import download from '@/utils/download'
 import { IotDeviceApi, IotDeviceVO } from '@/api/pms/device'
 import { IotMainWorkOrderApi, IotMainWorkOrderVO } from '@/api/pms/iotmainworkorder'
 import { DICT_TYPE, getStrDictOptions } from '@/utils/dict'
-import { dateFormatter } from '@/utils/formatTime'
 import DeptTree from '@/views/system/user/DeptTree.vue'
 import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
 import DeviceAlarmBomList from "@/views/pms/iotmainworkorder/DeviceAlarmBomList.vue";
@@ -199,27 +198,13 @@ const handleQuery = () => {
   queryParams.pageNo = 1
   getList()
 }
-const moreQuery = (show) => {
-  ifShow.value = show
-}
+
 /** 重置按钮操作 */
 const resetQuery = () => {
   queryFormRef.value.resetFields()
   handleQuery()
 }
 
-/** 添加/修改操作 */
-const formRef = ref()
-const openForm = (type: string, id?: number) => {
-  //修改
-  if (typeof id === 'number') {
-    push({ name: 'DeviceDetailEdit', params: { id } })
-    return
-  }
-  // 新增
-  push({ name: 'ConfigDevicePerson', params: {} })
-}
-
 const getDistanceClass = (distance: number | string | null) => {
   if (distance === null || distance === undefined) return '';
 
@@ -251,61 +236,13 @@ const hasMaintenancePlan = (mainDistance: any) => {
   return mainDistance != null && mainDistance !== '';
 };
 
-/** 删除按钮操作 */
-const handleDelete = async (id: number) => {
-  try {
-    // 删除的二次确认
-    await message.delConfirm()
-    // 发起删除
-    await IotDeviceApi.deleteIotDevice(id)
-    message.success(t('common.delSuccess'))
-    // 刷新列表
-    await getList()
-  } catch {}
-}
-
-// 是否设置过责任人 下拉列表 模拟字典项
-const resultOptions = computed(() => [
-  {
-    label: '全部',
-    value: 'A' // 空值会触发 clearable 效果
-  },
-  {
-    label: '是',
-    value: 'Y' // 空值会触发 clearable 效果
-  },
-  {
-    label: '否',
-    value: 'N' // 空值会触发 clearable 效果
-  },
-])
-
 const handleDetail = (id: number) => {
   push({ name: 'DeviceDetailInfo', params: { id } })
 }
 
-const handleUpload = (id: number) => {
-  push({ name: 'DeviceUpload', params: { id } })
-}
-
-/** 查看设备责任人调整详情 */
-const currentDeviceId = ref() // 设备id
 const drawerVisible = ref<boolean>(false)
 const showDrawer = ref()
 
-const detail = (row: any) => {
-  // 如果有工单ID,跳转到保养工单详情页
-  if (row.workOrderId) {
-    push({ name: 'IotMainWorkOrderDetail', params: { id: row.workOrderId } })
-  } else if (row.planId) {
-    // 如果有计划ID,跳转到保养计划详情页
-    push({ name: 'IotMaintenancePlanDetail', params: { id: row.planId } })
-  }else {
-    // 两者都为空的情况处理
-    message.warning('当前设备无保养工单或保养计划')
-  }
-}
-
 const openBomForm = async (row) => {
   if (row.workOrderId) {
     flag.value = 'workOrder';
@@ -333,8 +270,6 @@ const handleExport = async () => {
 const { wsCache } = useCache()
 /** 初始化 **/
 onMounted(() => {
-  const user = wsCache.get(CACHE_KEY.USER)
-  // queryParams.deptId = user.user.deptId
   getList()
 })
 </script>

+ 207 - 0
src/views/system/role/RoleUsers.vue

@@ -0,0 +1,207 @@
+<template>
+  <Dialog v-model="dialogVisible"
+          :title="t('monitor.details')"
+          style="width: 1000px; max-height: 800px" @close="handleClose" >
+
+    <ContentWrap>
+      <el-form
+        class="-mb-15px"
+        :model="queryParams"
+        ref="queryFormRef"
+        :inline="true"
+        label-width="68px"
+      >
+        <el-form-item :label="t('profile.user.username')" prop="username" style="margin-left: 28px">
+          <el-input
+            v-model="queryParams.username"
+            :placeholder="t('profile.rules.username')"
+            clearable
+            @keyup.enter="handleQuery"
+            class="!w-200px"
+          />
+        </el-form-item>
+        <el-form-item :label="t('profile.user.nickname')" prop="nickname">
+          <el-input
+            v-model="queryParams.nickname"
+            :placeholder="t('profile.rules.nickname')"
+            clearable
+            @keyup.enter="handleQuery"
+            class="!w-200px"
+          />
+        </el-form-item>
+        <el-form-item>
+          <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" />
+            {{ t('workOrderMaterial.search') }}</el-button>
+          <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" />
+            {{ t('workOrderMaterial.reset') }}</el-button>
+        </el-form-item>
+      </el-form>
+    </ContentWrap>
+
+    <ContentWrap>
+      <el-table
+        v-loading="loading"
+        :data="list"
+        :stripe="true"
+        :show-overflow-tooltip="true"
+      >
+        <el-table-column :label="t('profile.user.username')" align="center" prop="username" />
+        <el-table-column :label="t('profile.user.nickname')" align="center" prop="nickname" />
+        <el-table-column :label="t('profile.user.dept')" align="center" prop="deptName" />
+        <el-table-column :label="t('profile.user.mobile')" align="center" prop="mobile" />
+        <el-table-column
+          :label="t('common.createTime')"
+          align="center"
+          prop="createTime"
+          :formatter="dateFormatter"
+          width="180"
+        />
+      </el-table>
+
+      <Pagination
+        :total="total"
+        v-model:page="queryParams.pageNo"
+        v-model:limit="queryParams.pageSize"
+        @pagination="getRoleUserList"
+      />
+    </ContentWrap>
+  </Dialog>
+</template>
+
+<script setup lang="ts">
+import { DictDataVO } from '@/api/system/dict/dict.data'
+import dayjs from 'dayjs'
+import { IotMaintenanceBomApi, IotMaintenanceBomVO } from '@/api/pms/iotmaintenancebom'
+import {propTypes} from "@/utils/propTypes";
+import * as UserApi from '@/api/system/user'
+import {dateFormatter} from "@/utils/formatTime";
+
+const { t } = useI18n() // 国际化
+const emit = defineEmits(['close']) // 定义 success 事件,用于操作成功后的回调
+const dialogVisible = ref(false) // 弹窗的是否展示
+const loading = ref(true) // 列表的加载中
+const queryFormRef = ref() // 搜索的表单
+const list = ref([]) // 列表的数据
+const total = ref(0) // 列表的总页数
+const queryParams = reactive({
+  pageNo: 1,
+  pageSize: 10,
+  roleId: undefined,
+  username: undefined,
+  nickname: undefined
+})
+
+const props = defineProps({
+  flag: propTypes.oneOfType<string | string[]>([String, Array<String>]).isRequired,
+})
+
+const selectedRow = ref(null)
+
+// 处理单选逻辑
+const selectRow = (row) => {
+  selectedRow.value = selectedRow.value?.id === row.id ? null : row
+  emit('choose', row)
+  dialogVisible.value = false
+}
+
+const open = async (roleId?: number) => {
+  await nextTick() // 确保DOM更新完成
+  queryParams.roleId = roleId
+  // 加载指定角色的用户列表
+  await getRoleUserList()
+  dialogVisible.value = true
+}
+
+defineExpose({ open }) // 提供 open 方法,用于打开弹窗
+
+const getRoleUserList = async () => {
+  loading.value = true
+  try {
+    const data = await UserApi.getUserPage(queryParams)
+    list.value = data.list
+    total.value = data.total
+  } finally {
+    loading.value = false
+  }
+}
+
+const handleClose = () => {
+  // 重置状态避免多个弹窗出现
+  dialogVisible.value = false
+  loading.value = false
+  list.value = []
+
+  // 通知父组件弹窗已关闭
+  emit('close')
+}
+
+// 计算 距离下次保养运行时长 H
+const calculateTimePeriod = (item: IotMaintenanceBomVO) => {
+  if (item.runningTimeRule === 0) {
+    const next = Number(item.nextRunningTime) || 0;
+    const totalRun = Number(item.totalRunTime) || 0;
+    const lastRun = Number(item.lastRunningTime) || 0;
+    const result = next - (totalRun - lastRun);
+    return Number(result.toFixed(2));
+  }
+  return typeof item.timePeriod === 'number'
+    ? Number(item.timePeriod.toFixed(2))
+    : item.timePeriod;
+};
+
+// 计算 距离下次保养公里数 KM
+const calculateKiloPeriod = (item: IotMaintenanceBomVO) => {
+  if (item.mileageRule === 0) {
+    const next = Number(item.nextRunningKilometers) || 0;
+    const totalRun = Number(item.totalMileage) || 0;
+    const lastRun = Number(item.lastRunningKilometers) || 0;
+    const result = next - (totalRun - lastRun);
+    return Number(result.toFixed(2));
+  }
+  return typeof item.kilometerCycle === 'number'
+    ? Number(item.kilometerCycle.toFixed(2))
+    : item.kilometerCycle;
+};
+
+// 计算下次保养日期
+const calculateNextNaturalDate = (item: IotMaintenanceBomVO): string => {
+  if (item.naturalDateRule !== 0 || !item.lastNaturalDate || !item.nextNaturalDate) {
+    return '-'
+  }
+  return dayjs(item.lastNaturalDate).add(item.nextNaturalDate, 'day').format('YYYY-MM-DD')
+}
+
+// 新增计算属性:控制时间相关列的显示
+const showTimeColumns = computed(() => {
+  return list.value.some(item => item.runningTimeRule === 0);
+});
+
+// 新增计算属性:控制里程相关列的显示
+const showMileageColumns = computed(() => {
+  return list.value.some(item => item.mileageRule === 0);
+});
+
+/** 搜索按钮操作 */
+const handleQuery = () => {
+  queryParams.pageNo = 1
+  getRoleUserList()
+}
+const choose = (row: DictDataVO) => {
+  emit('choose', row)
+  dialogVisible.value = false
+}
+/** 重置按钮操作 */
+const resetQuery = () => {
+  queryFormRef.value.resetFields()
+  handleQuery()
+}
+
+</script>
+<style lang="scss">
+.no-label-radio .el-radio__label {
+  display: none;
+}
+.no-label-radio .el-radio__inner {
+  margin-right: 0;
+}
+</style>

+ 80 - 37
src/views/system/role/index.vue

@@ -109,42 +109,61 @@
       />
       <el-table-column :width="300" align="center" label="操作">
         <template #default="scope">
-          <el-button
-            v-hasPermi="['system:role:update']"
-            link
-            type="primary"
-            @click="openForm('update', scope.row.id)"
-          >
-            编辑
-          </el-button>
-          <el-button
-            v-hasPermi="['system:permission:assign-role-menu']"
-            link
-            preIcon="ep:basketball"
-            title="菜单权限"
-            type="primary"
-            @click="openAssignMenuForm(scope.row)"
-          >
-            菜单权限
-          </el-button>
-          <el-button
-            v-hasPermi="['system:permission:assign-role-data-scope']"
-            link
-            preIcon="ep:coin"
-            title="数据权限"
-            type="primary"
-            @click="openDataPermissionForm(scope.row)"
-          >
-            数据权限
-          </el-button>
-          <el-button
-            v-hasPermi="['system:role:delete']"
-            link
-            type="danger"
-            @click="handleDelete(scope.row.id)"
-          >
-            删除
-          </el-button>
+          <div class="flex items-center justify-center">
+            <el-button
+              v-hasPermi="['system:role:update']"
+              link
+              type="primary"
+              @click="openForm('update', scope.row.id)"
+            >
+              编辑
+            </el-button>
+            <el-button
+              v-hasPermi="['system:permission:assign-role-menu']"
+              link
+              preIcon="ep:basketball"
+              title="菜单权限"
+              type="primary"
+              @click="openAssignMenuForm(scope.row)"
+            >
+              菜单权限
+            </el-button>
+            <el-button
+              v-hasPermi="['system:permission:assign-role-data-scope']"
+              link
+              preIcon="ep:coin"
+              title="数据权限"
+              type="primary"
+              @click="openDataPermissionForm(scope.row)"
+            >
+              数据权限
+            </el-button>
+            <el-dropdown
+              @command="(command) => handleCommand(command, scope.row)"
+              v-hasPermi="[
+                    'system:user:query',
+                    'system:role:delete'
+                  ]"
+            >
+              <el-button type="primary" link><Icon icon="ep:d-arrow-right" /> 更多</el-button>
+              <template #dropdown>
+                <el-dropdown-menu>
+                  <el-dropdown-item
+                    command="handleRoleUsers"
+                    v-if="checkPermi(['system:user:query'])"
+                  >
+                    <Icon icon="ep:user-filled" />用户
+                  </el-dropdown-item>
+                  <el-dropdown-item
+                    command="handleDelete"
+                    v-if="checkPermi(['system:role:delete'])"
+                  >
+                    <Icon icon="ep:delete" />删除
+                  </el-dropdown-item>
+                </el-dropdown-menu>
+              </template>
+            </el-dropdown>
+          </div>
         </template>
       </el-table-column>
     </el-table>
@@ -163,6 +182,8 @@
   <RoleAssignMenuForm ref="assignMenuFormRef" @success="getList" />
   <!-- 表单弹窗:数据权限 -->
   <RoleDataPermissionForm ref="dataPermissionFormRef" @success="getList" />
+  <!-- 查询绑定指定角色的用户 -->
+  <RoleUsers ref="userFormRef" />
 </template>
 <script lang="ts" setup>
 import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
@@ -172,12 +193,14 @@ import * as RoleApi from '@/api/system/role'
 import RoleForm from './RoleForm.vue'
 import RoleAssignMenuForm from './RoleAssignMenuForm.vue'
 import RoleDataPermissionForm from './RoleDataPermissionForm.vue'
+import RoleUsers from './RoleUsers.vue'
+import {checkPermi} from "@/utils/permission";
 
 defineOptions({ name: 'SystemRole' })
 
 const message = useMessage() // 消息弹窗
 const { t } = useI18n() // 国际化
-
+const userFormRef = ref()   // 查看绑定指定角色的用户列表
 const loading = ref(true) // 列表的加载中
 const total = ref(0) // 列表的总页数
 const list = ref([]) // 列表的数据
@@ -247,6 +270,11 @@ const handleDelete = async (id: number) => {
   } catch {}
 }
 
+const openUserForm = async (row) => {
+  console.log('打开窗口')
+  userFormRef.value.open(row.id)
+}
+
 /** 导出按钮操作 */
 const handleExport = async () => {
   try {
@@ -262,6 +290,21 @@ const handleExport = async () => {
   }
 }
 
+/** 操作分发 */
+const handleCommand = (command: string, row: RoleApi.RoleVO) => {
+  console.log('执行命令')
+  switch (command) {
+    case 'handleRoleUsers':
+      openUserForm(row)
+      break
+    case 'handleDelete':
+      handleDelete(row.id)
+      break
+    default:
+      break
+  }
+}
+
 /** 初始化 **/
 onMounted(() => {
   getList()