车间能级提升-智能设备管理系统
朱桂飞
2025-02-19 f9a12ecb4ea4b7b103b50634335704140237fef7
完成工具借用、归还相关
已添加18个文件
已修改17个文件
2084 ■■■■■ 文件已修改
eims-ui/apps/web-antd/src/api/eims/fixture-borrow/index.ts 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui/apps/web-antd/src/api/eims/fixture-borrow/model.d.ts 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui/apps/web-antd/src/views/eims/components/fixture-modal.vue 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui/apps/web-antd/src/views/eims/equ-statu/data.tsx 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui/apps/web-antd/src/views/eims/equ-statu/equ-statu-drawer.vue 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui/apps/web-antd/src/views/eims/equ-statu/index.vue 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui/apps/web-antd/src/views/eims/equ-trial/data.tsx 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui/apps/web-antd/src/views/eims/equ-trial/equ-trial-drawer.vue 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui/apps/web-antd/src/views/eims/equ-trial/index.vue 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui/apps/web-antd/src/views/eims/fixture-borrow/data.tsx 234 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui/apps/web-antd/src/views/eims/fixture-borrow/fixture-borrow-drawer.vue 242 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui/apps/web-antd/src/views/eims/fixture-borrow/index.vue 237 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui/apps/web-antd/src/views/eims/fixture/dashboard/data.tsx 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui/apps/web-antd/src/views/eims/fixture/dashboard/index.vue 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui/apps/web-antd/src/views/eims/fixture/dashboard/type.js 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui/apps/web-antd/src/views/eims/fixture/data.tsx 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui/apps/web-antd/src/views/eims/fixture/fixture-drawer.vue 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui/apps/web-antd/src/views/eims/fixture/index.vue 84 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui/apps/web-antd/src/views/eims/repair-req/index.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui/apps/web-antd/src/views/eims/repair-req/use-role-base-filters.ts 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui/packages/@core/base/shared/src/constants/dict-enum.ts 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/controller/EimsFixtureBorrowController.java 105 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/EimsFixture.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/EimsFixtureBorrow.java 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/bo/EimsFixtureBo.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/bo/EimsFixtureBorrowBo.java 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/vo/EimsFixtureBorrowVo.java 127 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/vo/EimsFixtureVo.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/mapper/EimsFixtureBorrowMapper.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/IEimsFixtureBorrowService.java 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/impl/EimsFixtureBorrowServiceImpl.java 211 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/impl/EimsFixtureServiceImpl.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/impl/EimsRepairReqServiceImpl.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/utils/DataFilterUtil.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/resources/mapper/eims/EimsFixtureBorrowMapper.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui/apps/web-antd/src/api/eims/fixture-borrow/index.ts
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,62 @@
import type { IDS, PageQuery, PageResult } from '#/api/common';
import type { FixBorrowVO } from '#/api/eims/fixture-borrow/model';
import { commonExport } from '#/api/helper';
import { requestClient } from '#/api/request';
enum Api {
  fixBorrowExport = '/eims/fixBorrow/export',
  fixBorrowImport = '/eims/fixBorrow/importData',
  fixBorrowList = '/eims/fixBorrow/list',
  root = '/eims/fixBorrow'
}
/**
 * æŸ¥è¯¢ã€å·¥å…·å€Ÿç”¨ã€‘列表
 * @param query
 * @returns {*}
 */
export function listFixBorrow(params?: PageQuery) {
  return requestClient.get<PageResult<FixBorrowVO>>(Api.fixBorrowList, { params });
}
/**
 * æŸ¥è¯¢ã€å·¥å…·å€Ÿç”¨ã€‘详细
 * @param fixId
 */
export function getFixBorrow(fixId: any) {
  return requestClient.get<FixBorrowVO>(`${Api.root}/${fixId}`);
}
/**
 * æ–°å¢žã€å·¥å…·å€Ÿç”¨ã€‘
 * @param data
 */
export function addFixBorrow(data: any) {
  return requestClient.postWithMsg<void>(Api.root, data);
}
/**
 * ä¿®æ”¹ã€å·¥å…·å€Ÿç”¨ã€‘
 * @param data
 */
export function updateFixBorrow(data: any) {
  return requestClient.putWithMsg<void>(Api.root, data);
}
/**
 * åˆ é™¤ã€å·¥å…·å€Ÿç”¨ã€‘
 * @param fixIds
 */
export function delFixBorrow(fixIds: IDS) {
  return requestClient.deleteWithMsg<void>(`${Api.root}/${fixIds}`);
}
/**
 * å¯¼å‡ºã€å·¥å…·å€Ÿç”¨ã€‘
 * @param data
 */
export function fixBorrowExport(data: any) {
  return commonExport(Api.fixBorrowExport, data);
}
eims-ui/apps/web-antd/src/api/eims/fixture-borrow/model.d.ts
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,66 @@
export interface FixBorrowVO {
  /**
   *
   */
  id: number | string;
  /**
   * å€Ÿç”¨å·¥å…·id
   */
  fixtureId: number | string;
  /**
   * å€Ÿç”¨å·¥å…·åç§°
   */
  fixtureName: string;
  /**
   * å€Ÿç”¨éƒ¨é—¨
   */
  borrowDept: number;
  /**
   * å€Ÿç”¨äºº
   */
  borrowUser: number;
  /**
   * ç»åŠžäºº
   */
  agentUser: number;
  /**
   * ç»åŠžäºº
   */
  agentUserName: string;
  /**
   * å€Ÿç”¨è®°å½•状态(字典)
   */
  status: string;
  /**
   * å€Ÿç”¨æ—¶é—´
   */
  borrowTime: string;
  /**
   * é¢„计归还时间
   */
  planReturnTime: string;
  /**
   * å½’还时间
   */
  returnTime: string;
  /**
   * å€Ÿç”¨ç†ç”±
   */
  borrowReason: string;
  /**
   * å¤‡æ³¨
   */
  remark: string;
}
eims-ui/apps/web-antd/src/views/eims/components/fixture-modal.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,49 @@
<script setup lang="ts">
import { ref } from 'vue';
import { useVbenModal } from '@vben/common-ui';
import { message } from 'ant-design-vue';
import InnerView from '#/views/eims/fixture/index.vue';
const emit = defineEmits<{ updateSelect: [any] }>();
const [BasicModal, modalApi] = useVbenModal({
  fullscreenButton: false,
  draggable: true,
  onCancel: handleCancel,
  onConfirm: handleConfirm
});
const innerView = ref();
async function handleConfirm() {
  try {
    modalApi.modalLoading(true);
    const tableSelect = innerView.value.tableSelect();
    if (tableSelect.length > 1) {
      message.error('最多只能选择一个工具!');
      modalApi.modalLoading(false);
      return false;
    }
    emit('updateSelect', tableSelect[0]);
    await handleCancel();
  } catch (error) {
    console.error(error);
  } finally {
    modalApi.modalLoading(false);
  }
}
async function handleCancel() {
  modalApi.close();
}
</script>
<template>
  <BasicModal :fullscreen-button="true" class="w-[800px]">
    <InnerView ref="innerView" />
  </BasicModal>
</template>
<style scoped></style>
eims-ui/apps/web-antd/src/views/eims/equ-statu/data.tsx
@@ -101,7 +101,16 @@
      allowClear: true,
      getPopupContainer
    },
    dependencies: {
      show: () => false,
      triggerFields: ['']
    },
    fieldName: 'equId',
    label: '设备id'
  },
  {
    component: 'Input',
    fieldName: 'equName',
    label: '设备名称'
  },
  {
eims-ui/apps/web-antd/src/views/eims/equ-statu/equ-statu-drawer.vue
@@ -1,14 +1,17 @@
<script setup lang="ts">
import { computed, ref } from 'vue';
import { useVbenDrawer } from '@vben/common-ui';
import { useVbenDrawer, useVbenModal } from '@vben/common-ui';
import { $t } from '@vben/locales';
import { addFullName, cloneDeep, getPopupContainer } from '@vben/utils';
import { InputSearch } from 'ant-design-vue';
import { useVbenForm } from '#/adapter/form';
import { listEqu } from '#/api/eims/equ';
import { addEquStatu, getEquStatu, updateEquStatu } from '#/api/eims/equ-statu';
import { getDeptTree, userList } from '#/api/system/user';
import equModal from '#/views/eims/components/equ-modal.vue';
import { drawerSchema } from './data';
@@ -46,12 +49,6 @@
    // åˆå§‹åŒ–
    await setupEquSelect();
    await setupDeptSelect();
    // è®¾å¤‡è¯¦æƒ…页打开指定设备id
    const { equId } = drawerApi.getData() as { equId?: number | string };
    if (equId) {
      await formApi.setValues({ equId});
    }
    // æ›´æ–° && èµ‹å€¼
    if (isUpdate.value && id) {
      const record = await getEquStatu(id);
@@ -60,17 +57,6 @@
        await setupUserOptions(record.userDept);
      }
    }
    // è®¾å¤‡id有值时不允许编辑(1.编辑 2.设备详情页打开)
    const flag = equId !== undefined || isUpdate.value;
    formApi.updateSchema([
      {
        componentProps: {
          disabled: flag
        },
        fieldName: 'equId'
      }
    ]);
    drawerApi.drawerLoading(false);
  }
});
@@ -78,7 +64,7 @@
async function setupEquSelect() {
  const equPageResult = await listEqu({
    pageNum: 1,
    pageSize: 1000,
    pageSize: 1000
  });
  // ä½¿ç”¨map来跟踪已经遇到的equId,使用filter来过滤掉重复的元素。
  const uniqueItems = equPageResult.rows.filter((item, index, self) => index === self.findIndex((tm) => tm.equId === item.equId));
@@ -200,10 +186,31 @@
  drawerApi.close();
  await formApi.resetForm();
}
// EQU modal
const [EquModal, equModalApi] = useVbenModal({
  connectedComponent: equModal,
  draggable: true,
  title: '选择成员'
});
function handleEquModal() {
  equModalApi.setData({});
  equModalApi.open();
}
async function selectEqu(equ: any) {
  await formApi.setValues({ 'equId': equ.equId, 'equName': equ.equName });
}
</script>
<template>
  <BasicDrawer :close-on-click-modal="false" :title="title" class="w-[600px]">
    <BasicForm />
    <BasicForm>
      <template #equName="slotProps">
        <InputSearch :enter-button="true" placeholder="请选择" @search="handleEquModal" v-bind="slotProps" />
      </template>
    </BasicForm>
    <EquModal :disabled="true" class="w-[1200px]" @update-equ="selectEqu" />
  </BasicDrawer>
</template>
eims-ui/apps/web-antd/src/views/eims/equ-statu/index.vue
@@ -52,6 +52,9 @@
  height: 'auto',
  keepSource: true,
  pagerConfig: {},
  toolbarConfig: {
    enabled: !props.equDetailFlag
  },
  proxyConfig: {
    ajax: {
      query: async ({ page }, formValues = {}) => {
eims-ui/apps/web-antd/src/views/eims/equ-trial/data.tsx
@@ -121,7 +121,16 @@
      allowClear: true,
      getPopupContainer
    },
    dependencies: {
      show: () => false,
      triggerFields: ['']
    },
    fieldName: 'equId',
    label: '设备id'
  },
  {
    component: 'Input',
    fieldName: 'equName',
    label: '设备名称'
  },
  {
eims-ui/apps/web-antd/src/views/eims/equ-trial/equ-trial-drawer.vue
@@ -1,14 +1,17 @@
<script setup lang="ts">
import { computed, ref } from 'vue';
import { useVbenDrawer } from '@vben/common-ui';
import { useVbenDrawer, useVbenModal } from '@vben/common-ui';
import { $t } from '@vben/locales';
import { addFullName, cloneDeep, getPopupContainer } from '@vben/utils';
import { InputSearch, Modal } from 'ant-design-vue';
import { useVbenForm } from '#/adapter/form';
import { listEqu } from '#/api/eims/equ';
import { addEquTrial, getEquTrial, updateEquTrial } from '#/api/eims/equ-trial';
import { getDeptTree, userList } from '#/api/system/user';
import equModal from '#/views/eims/components/equ-modal.vue';
import { drawerSchema } from './data';
@@ -172,6 +175,7 @@
    }
  ]);
}
async function handleConfirm() {
  try {
    drawerApi.drawerLoading(true);
@@ -194,10 +198,43 @@
  drawerApi.close();
  await formApi.resetForm();
}
// EQU modal
const [EquModal, equModalApi] = useVbenModal({
  connectedComponent: equModal,
  draggable: true,
  title: '选择成员'
});
function handleEquModal() {
  equModalApi.setData({});
  equModalApi.open();
}
async function selectEqu(equ: any) {
  // TODO ç¡®å®šä¸Žå­—典对应sys_equ_status
  if (equ.status !== null && equ.status === '0') {
    await formApi.setValues({ 'equId': equ.equId, 'equName': equ.equName });
  } else {
    Modal.confirm({
      title: '提示',
      okType: 'danger',
      content: `当前设备状态不属于试用设备,确认添加吗?`,
      onOk: async () => {
        await formApi.setValues({ 'equId': equ.equId, 'equName': equ.equName });
      }
    });
  }
}
</script>
<template>
  <BasicDrawer :close-on-click-modal="false" :title="title" class="w-[600px]">
    <BasicForm />
    <BasicForm>
      <template #equName="slotProps">
        <InputSearch :enter-button="true" placeholder="请选择" @search="handleEquModal" v-bind="slotProps" />
      </template>
    </BasicForm>
    <EquModal :disabled="true" class="w-[1200px]" @update-equ="selectEqu" />
  </BasicDrawer>
</template>
eims-ui/apps/web-antd/src/views/eims/equ-trial/index.vue
@@ -52,6 +52,9 @@
  height: 'auto',
  keepSource: true,
  pagerConfig: {},
  toolbarConfig: {
    enabled: !props.equDetailFlag
  },
  proxyConfig: {
    ajax: {
      query: async ({ page }, formValues = {}) => {
@@ -77,7 +80,7 @@
    // è¿œç¨‹æŽ’序
    remote: true,
    // æ”¯æŒå¤šå­—段排序 é»˜è®¤å…³é—­
    multiple: true,
    multiple: true
  },
  id: 'eims-equ-trial-index'
};
@@ -86,8 +89,8 @@
  formOptions,
  gridOptions,
  gridEvents: {
    sortChange: (sortParams) => vxeSortEvent(tableApi, sortParams),
  },
    sortChange: (sortParams) => vxeSortEvent(tableApi, sortParams)
  }
});
const [EquTrialDrawer, equTrialDrawerApi] = useVbenDrawer({
eims-ui/apps/web-antd/src/views/eims/fixture-borrow/data.tsx
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,234 @@
import type { VxeGridProps } from '#/adapter/vxe-table';
import { DictEnum } from '@vben/constants';
import { getPopupContainer } from '@vben/utils';
import { type FormSchemaGetter } from '#/adapter/form';
import { getDictOptions } from '#/utils/dict';
import { renderDict } from '#/utils/render';
export const querySchema: FormSchemaGetter = () => [
  {
    component: 'Input',
    fieldName: 'fixtureName',
    label: '工具名称'
  },
  {
    component: 'TreeSelect',
    // åœ¨drawer里更新 è¿™é‡Œä¸éœ€è¦é»˜è®¤çš„componentProps
    defaultValue: undefined,
    fieldName: 'borrowDept',
    label: '借用部门'
  },
  {
    component: 'Select',
    componentProps: {
      showSearch: true,
      allowClear: true,
      getPopupContainer
    },
    fieldName: 'borrowUser',
    label: '借用人'
  },
  {
    component: 'Select',
    componentProps: {
      options: getDictOptions(DictEnum.FIXTURE_BORROW_RECORD_STATUS)
    },
    fieldName: 'status',
    label: '借用状态'
  },
  {
    component: 'RangePicker',
    fieldName: 'borrowTime',
    label: '借用时间'
  }
];
export const columns: VxeGridProps['columns'] = [
  { type: 'checkbox', width: 60, fixed: 'left' },
  {
    title: '工具名称',
    field: 'fixtureName',
    minWidth: 100,
    fixed: 'left',
    slots: { default: 'fixtureName' }
  },
  {
    title: '借用状态',
    field: 'status',
    sortable: true,
    slots: {
      default: ({ row }) => {
        if (row.status === null || row.status === '') {
          return '';
        }
        return renderDict(row.status, DictEnum.FIXTURE_BORROW_RECORD_STATUS);
      }
    },
    minWidth: 100,
    fixed: 'left'
  },
  {
    title: '借用部门',
    field: 'borrowDeptName',
    minWidth: 120
  },
  {
    title: '借用人',
    field: 'borrowUserName',
    minWidth: 100
  },
  {
    title: '经办人',
    field: 'agentUserName',
    minWidth: 100
  },
  {
    title: '借用时间',
    field: 'borrowTime',
    minWidth: 120
  },
  {
    title: '借用原因',
    field: 'borrowReason',
    minWidth: 140
  },
  {
    title: '预计归还时间',
    field: 'planReturnTime',
    minWidth: 160
  },
  {
    title: '实际归还时间',
    field: 'returnTime',
    minWidth: 160
  },
  {
    field: 'action',
    fixed: 'right',
    slots: { default: 'action' },
    title: '操作',
    width: 200
  }
];
export const drawerSchema: FormSchemaGetter = () => [
  {
    component: 'Input',
    dependencies: {
      show: () => false,
      triggerFields: ['']
    },
    fieldName: 'id'
  },
  {
    component: 'Select',
    componentProps: {
      showSearch: true,
      allowClear: true,
      getPopupContainer
    },
    dependencies: {
      show: () => false,
      triggerFields: ['']
    },
    fieldName: 'fixtureId',
    label: '工具id',
    rules: 'required'
  },
  {
    component: 'Input',
    fieldName: 'fixtureName',
    label: '工具名称',
    rules: 'required'
  },
  {
    component: 'TreeSelect',
    // åœ¨drawer里更新 è¿™é‡Œä¸éœ€è¦é»˜è®¤çš„componentProps
    defaultValue: undefined,
    fieldName: 'borrowDept',
    label: '借用部门',
    rules: 'selectRequired'
  },
  {
    component: 'Select',
    componentProps: {
      showSearch: true,
      allowClear: true,
      getPopupContainer
    },
    fieldName: 'borrowUser',
    label: '借用人',
    rules: 'required'
  },
  {
    component: 'Select',
    componentProps: {
      showSearch: true,
      allowClear: true,
      getPopupContainer
    },
    fieldName: 'agentUser',
    dependencies: {
      show: () => false,
      triggerFields: ['']
    },
    label: '经办人'
  },
  {
    component: 'Input',
    fieldName: 'agentUserName',
    label: '经办人',
  },
  {
    component: 'RadioGroup',
    componentProps: {
      buttonStyle: 'solid',
      options: getDictOptions(DictEnum.FIXTURE_BORROW_RECORD_STATUS),
      optionType: 'button'
    },
    defaultValue: '0',
    fieldName: 'status',
    label: '借用状态'
  },
  {
    component: 'DatePicker',
    componentProps: {
      format: 'YYYY-MM-DD HH:mm:ss',
      showTime: true,
      valueFormat: 'YYYY-MM-DD HH:mm:ss',
      getPopupContainer
    },
    fieldName: 'borrowTime',
    label: '借用时间'
  },
  {
    component: 'Textarea',
    formItemClass: 'items-baseline',
    fieldName: 'borrowReason',
    label: '借用原因'
  },
  {
    component: 'DatePicker',
    componentProps: {
      format: 'YYYY-MM-DD HH:mm:ss',
      showTime: true,
      valueFormat: 'YYYY-MM-DD HH:mm:ss',
      getPopupContainer
    },
    fieldName: 'planReturnTime',
    label: '预计归还时间'
  },
  {
    component: 'DatePicker',
    componentProps: {
      format: 'YYYY-MM-DD HH:mm:ss',
      showTime: true,
      valueFormat: 'YYYY-MM-DD HH:mm:ss',
      getPopupContainer
    },
    fieldName: 'returnTime',
    label: '实际归还时间'
  }
];
eims-ui/apps/web-antd/src/views/eims/fixture-borrow/fixture-borrow-drawer.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,242 @@
<script setup lang="ts">
import { computed, ref } from 'vue';
import { useVbenDrawer, useVbenModal } from '@vben/common-ui';
import { $t } from '@vben/locales';
import { addFullName, cloneDeep, getPopupContainer } from '@vben/utils';
import { InputSearch } from 'ant-design-vue';
import { useVbenForm } from '#/adapter/form';
import { addFixBorrow, getFixBorrow, updateFixBorrow } from '#/api/eims/fixture-borrow';
import { userProfile } from '#/api/system/profile';
import { getDeptTree, userList } from '#/api/system/user';
import fixModal from '#/views/eims/components/fixture-modal.vue';
import userModal from '#/views/eims/components/user-modal.vue';
import { drawerSchema } from './data';
const emit = defineEmits<{ reload: [] }>();
const isUpdate = ref(false);
const title = computed(() => {
  return isUpdate.value ? $t('pages.common.edit') : $t('pages.common.add');
});
const [BasicForm, formApi] = useVbenForm({
  commonConfig: {
    formItemClass: 'col-span-2',
    componentProps: {
      class: 'w-full'
    },
    labelWidth: 120
  },
  schema: drawerSchema(),
  showDefaultActions: false,
  wrapperClass: 'grid-cols-2'
});
const [BasicDrawer, drawerApi] = useVbenDrawer({
  onCancel: handleCancel,
  onConfirm: handleConfirm,
  async onOpenChange(isOpen) {
    if (!isOpen) {
      return null;
    }
    drawerApi.drawerLoading(true);
    const { id } = drawerApi.getData() as { id?: number | string };
    isUpdate.value = !!id;
    // åˆå§‹åŒ–
    await setupDeptSelect();
    // ä»Žå·¥å…·å°è´¦é¡µé¢æ‰“开特殊处理
    const { fixturePage } = drawerApi.getData() as { fixturePage?: boolean };
    if (fixturePage) {
      formApi.updateSchema([
        {
          componentProps: {
            disabled: false
          },
          fieldName: 'fixtureName'
        }
      ]);
      await updateCustomData(drawerApi.getData());
    }
    formApi.updateSchema([
      {
        componentProps: {
          disabled: isUpdate.value || fixturePage
        },
        fieldName: 'fixtureName'
      }
    ]);
    // æ›´æ–° && èµ‹å€¼
    if (isUpdate.value && id) {
      const record = await getFixBorrow(id);
      await formApi.setValues(record);
      if (isUpdate.value && record.borrowDept) {
        await setupUserOptions(record.borrowDept);
      }
    }
    drawerApi.drawerLoading(false);
  }
});
/**
 * ä»Žè®¾å¤‡å°è´¦é¡µé¢æ‰“开更新部分数据
 * @param data
 */
async function updateCustomData(data: any) {
  const resp = await userProfile();
  const deptId = resp?.user?.deptId;
  await setupUserOptions(deptId);
  data.borrowDept = deptId;
  await formApi.setValues(data);
}
/**
 * ç”¨æˆ·çš„加载
 */
async function setupUserOptions(deptId: any) {
  const params = { deptId };
  const userPageResult = await userList({
    pageNum: 1,
    pageSize: 500,
    ...params
  });
  const options = userPageResult.rows.map((item) => ({
    label: item.nickName || item.userName,
    value: item.userId
  }));
  // ç­›é€‰
  const filterOption = (input: string, option: any) => {
    return option.label.toLowerCase().includes(input.toLowerCase());
  };
  const placeholder = options.length > 0 ? '请选择' : '该部门下暂无用户';
  formApi.updateSchema([
    {
      componentProps: { options, placeholder, filterOption },
      fieldName: 'borrowUser'
    }
  ]);
}
/**
 * åˆå§‹åŒ–部门选择
 */
async function setupDeptSelect() {
  // updateSchema
  const deptTree = await getDeptTree();
  // é€‰ä¸­åŽæ˜¾ç¤ºåœ¨è¾“入框的值 å³çˆ¶èŠ‚ç‚¹ / å­èŠ‚ç‚¹
  addFullName(deptTree, 'label', ' / ');
  formApi.updateSchema([
    {
      componentProps: (formModel) => ({
        class: 'w-full',
        fieldNames: {
          key: 'id',
          value: 'id',
          children: 'children'
        },
        getPopupContainer,
        async onSelect(deptId: number | string) {
          /** æ ¹æ®éƒ¨é—¨ID加载用户 */
          await setupUserOptions(deptId);
          /** å˜åŒ–后需要重新选择用户 */
          formModel.operatorId = undefined;
        },
        placeholder: '请选择',
        showSearch: true,
        treeData: deptTree,
        treeDefaultExpandAll: true,
        treeLine: { showLeafIcon: false },
        // ç­›é€‰çš„字段
        treeNodeFilterProp: 'label',
        // é€‰ä¸­åŽæ˜¾ç¤ºåœ¨è¾“入框的值
        treeNodeLabelProp: 'fullName'
      }),
      fieldName: 'borrowDept'
    }
  ]);
}
async function handleConfirm() {
  try {
    drawerApi.drawerLoading(true);
    const { valid } = await formApi.validate();
    if (!valid) {
      return;
    }
    const data = cloneDeep(await formApi.getValues());
    await (isUpdate.value ? updateFixBorrow(data) : addFixBorrow(data));
    emit('reload');
    await handleCancel();
  } catch (error) {
    console.error(error);
  } finally {
    drawerApi.drawerLoading(false);
  }
}
async function handleCancel() {
  drawerApi.close();
  await formApi.resetForm();
}
// user modal
const [UserModal, userModalApi] = useVbenModal({
  connectedComponent: userModal,
  draggable: true,
  title: '选择成员'
});
function handleUserModal() {
  userModalApi.setData({});
  userModalApi.open();
}
/**
 * æ›´æ–°é€‰æ‹©çš„æˆå‘˜
 * @param user
 */
async function selectUser(user: any) {
  await formApi.setValues({ 'agentUser': user.userId, 'agentUserName': user.nickName });
}
// user modal
const [FixModal, fixModalApi] = useVbenModal({
  connectedComponent: fixModal,
  draggable: true,
  title: '选择工具'
});
function handleFixModal() {
  fixModalApi.setData({});
  fixModalApi.open();
}
/**
 * æ›´æ–°é€‰æ‹©çš„工具
 * @param fix
 */
async function selectFix(fix: any) {
  await formApi.setValues({ 'fixtureId': fix.id, 'fixtureName': fix.fixtureName });
}
</script>
<template>
  <BasicDrawer :close-on-click-modal="false" :title="title" class="w-[600px]">
    <BasicForm>
      <template #agentUserName="slotProps">
        <InputSearch :enter-button="true" placeholder="请选择" @search="handleUserModal" v-bind="slotProps" />
      </template>
      <template #fixtureName="slotProps">
        <InputSearch :enter-button="true" placeholder="请选择" @search="handleFixModal" v-bind="slotProps" />
      </template>
    </BasicForm>
    <UserModal class="w-[1200px]" @select-user="selectUser" />
    <FixModal class="w-[1200px]" @update-select="selectFix" />
  </BasicDrawer>
</template>
eims-ui/apps/web-antd/src/views/eims/fixture-borrow/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,237 @@
<script setup lang="ts">
import type { Recordable } from '@vben/types';
import { onMounted } from 'vue';
import { Page, useVbenDrawer, type VbenFormProps } from '@vben/common-ui';
import { $t } from '@vben/locales';
import { addFullName, getPopupContainer, getVxePopupContainer } from '@vben/utils';
import { Modal, Popconfirm, Space } from 'ant-design-vue';
import { useVbenVxeGrid, vxeCheckboxChecked, type VxeGridProps, vxeSortEvent } from '#/adapter/vxe-table';
import { delFixBorrow, fixBorrowExport, listFixBorrow } from '#/api/eims/fixture-borrow';
import { getDeptTree, userList } from '#/api/system/user';
import { commonDownloadExcel } from '#/utils/file/download';
import { columns, querySchema } from './data';
import fixBorrowDrawer from './fixture-borrow-drawer.vue';
const formOptions: VbenFormProps = {
  commonConfig: {
    labelWidth: 80,
    componentProps: {
      allowClear: true
    }
  },
  schema: querySchema(),
  wrapperClass: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4',
  // æ—¥æœŸé€‰æ‹©æ ¼å¼åŒ–
  fieldMappingTime: [
    ['borrowTime', ['params[beginBorrowTime]', 'params[endBorrowTime]'], ['YYYY-MM-DD 00:00:00', 'YYYY-MM-DD 23:59:59']],
    ['planReturnTime', ['params[beginPlanReturnTime]', 'params[endPlanReturnTime]'], ['YYYY-MM-DD 00:00:00', 'YYYY-MM-DD 23:59:59']]
  ]
};
const gridOptions: VxeGridProps = {
  checkboxConfig: {
    // é«˜äº®
    highlight: true,
    // ç¿»é¡µæ—¶ä¿ç•™é€‰ä¸­çŠ¶æ€
    reserve: true
    // ç‚¹å‡»è¡Œé€‰ä¸­
    // trigger: 'row'
  },
  columns,
  height: 'auto',
  keepSource: true,
  pagerConfig: {},
  proxyConfig: {
    ajax: {
      query: async ({ page }, formValues = {}) => {
        return await listFixBorrow({
          pageNum: page.currentPage,
          pageSize: page.pageSize,
          ...formValues
        });
      }
    }
  },
  rowConfig: {
    isHover: true,
    keyField: 'id'
  },
  sortConfig: {
    // è¿œç¨‹æŽ’序
    remote: true,
    // æ”¯æŒå¤šå­—段排序 é»˜è®¤å…³é—­
    multiple: true
  },
  id: 'fixture-borrow-index'
};
const [BasicTable, tableApi] = useVbenVxeGrid({
  formOptions,
  gridOptions,
  gridEvents: {
    sortChange: (sortParams) => vxeSortEvent(tableApi, sortParams)
  }
});
const [FixBorrowDrawer, fixBorrowDrawerApi] = useVbenDrawer({
  connectedComponent: fixBorrowDrawer
});
function handleAdd() {
  fixBorrowDrawerApi.setData({});
  fixBorrowDrawerApi.open();
}
async function handleEdit(record: Recordable<any>) {
  fixBorrowDrawerApi.setData({ id: record.id });
  fixBorrowDrawerApi.open();
}
async function handleDelete(row: Recordable<any>) {
  await delFixBorrow(row.id);
  await tableApi.query();
}
function handleMultiDelete() {
  const rows = tableApi.grid.getCheckboxRecords();
  const ids = rows.map((row: any) => row.id);
  Modal.confirm({
    title: '提示',
    okType: 'danger',
    content: `确认删除选中的${ids.length}条记录吗?`,
    onOk: async () => {
      await delFixBorrow(ids);
      await tableApi.query();
    }
  });
}
function handleDownloadExcel() {
  commonDownloadExcel(fixBorrowExport, '工具借用记录', tableApi.formApi.form.values, {
    fieldMappingTime: formOptions.fieldMappingTime
  });
}
/**
 * ç”¨æˆ·çš„加载
 */
async function setupUserOptions(deptId: any) {
  const params = { deptId };
  const userPageResult = await userList({
    pageNum: 1,
    pageSize: 500,
    ...params
  });
  const options = userPageResult.rows.map((item) => ({
    label: item.nickName || item.userName,
    value: item.userId
  }));
  // ç­›é€‰
  const filterOption = (input: string, option: any) => {
    return option.label.toLowerCase().includes(input.toLowerCase());
  };
  const placeholder = options.length > 0 ? '请选择' : '该部门下暂无用户';
  tableApi.formApi.updateSchema([
    {
      componentProps: { options, placeholder, filterOption },
      fieldName: 'borrowUser'
    }
  ]);
}
/**
 * åˆå§‹åŒ–部门选择
 */
async function setupDeptSelect() {
  // updateSchema
  const deptTree = await getDeptTree();
  // é€‰ä¸­åŽæ˜¾ç¤ºåœ¨è¾“入框的值 å³çˆ¶èŠ‚ç‚¹ / å­èŠ‚ç‚¹
  addFullName(deptTree, 'label', ' / ');
  tableApi.formApi.updateSchema([
    {
      componentProps: (formModel) => ({
        class: 'w-full',
        fieldNames: {
          key: 'id',
          value: 'id',
          children: 'children'
        },
        getPopupContainer,
        async onSelect(deptId: number | string) {
          /** æ ¹æ®éƒ¨é—¨ID加载用户 */
          await setupUserOptions(deptId);
          /** å˜åŒ–后需要重新选择用户 */
          formModel.inventoryUser = undefined;
        },
        placeholder: '请选择',
        showSearch: true,
        treeData: deptTree,
        treeDefaultExpandAll: true,
        treeLine: { showLeafIcon: false },
        // ç­›é€‰çš„字段
        treeNodeFilterProp: 'label',
        // é€‰ä¸­åŽæ˜¾ç¤ºåœ¨è¾“入框的值
        treeNodeLabelProp: 'fullName'
      }),
      fieldName: 'borrowDept'
    }
  ]);
}
onMounted(async () => {
  await setupDeptSelect();
});
</script>
<template>
  <Page :auto-content-height="true">
    <div class="flex h-full gap-[8px]">
      <BasicTable class="flex-1 overflow-hidden" table-title="借用记录列表">
        <template #toolbar-tools>
          <Space>
            <a-button v-access:code="['eims:fixtureBorrow:export']" @click="handleDownloadExcel">
              {{ $t('pages.common.export') }}
            </a-button>
            <a-button
              :disabled="!vxeCheckboxChecked(tableApi)"
              danger
              type="primary"
              v-access:code="['eims:fixtureBorrow:remove']"
              @click="handleMultiDelete"
            >
              {{ $t('pages.common.delete') }}
            </a-button>
            <a-button type="primary" v-access:code="['eims:fixtureBorrow:add']" @click="handleAdd">
              {{ $t('pages.common.add') }}
            </a-button>
          </Space>
        </template>
        <template #fixtureName="{ row }">
          <Space>
            <span>{{ row.fixtureName }}</span>
          </Space>
        </template>
        <template #action="{ row }">
          <Space>
            <ghost-button v-access:code="['eims:fixtureBorrow:edit']" @click.stop="handleEdit(row)">
              {{ $t('pages.common.edit') }}
            </ghost-button>
            <Popconfirm :get-popup-container="getVxePopupContainer" placement="left" title="确认删除?" @confirm="handleDelete(row)">
              <ghost-button danger v-access:code="['eims:fixtureBorrow:remove']" @click.stop="">
                {{ $t('pages.common.delete') }}
              </ghost-button>
            </Popconfirm>
          </Space>
        </template>
      </BasicTable>
    </div>
    <FixBorrowDrawer @reload="tableApi.query()" />
  </Page>
</template>
eims-ui/apps/web-antd/src/views/eims/fixture/dashboard/data.tsx
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,91 @@
import type { AnalysisOverviewItem,  WorkbenchTrendItem } from '@vben/common-ui';
import { SvgBellIcon, SvgCakeIcon, SvgCardIcon, SvgDownloadIcon } from '@vben/icons';
export const overviewItems: AnalysisOverviewItem[] = [
  {
    icon: SvgCardIcon,
    title: '工具总数',
    totalTitle: '工具总数',
    totalValue: 120_000,
    value: 2000
  },
  {
    icon: SvgCakeIcon,
    title: '可用工具数',
    totalTitle: '可用工具数',
    totalValue: 500_000,
    value: 20_000
  },
  {
    icon: SvgDownloadIcon,
    title: '最近借出',
    totalTitle: '最近借出',
    totalValue: 120_000,
    value: 8000
  },
  {
    icon: SvgBellIcon,
    title: '最近更新',
    totalTitle: '最近更新',
    totalValue: 50_000,
    value: 5000
  }
];
export const trendItems: WorkbenchTrendItem[] = [
  {
    avatar: 'svg:avatar-1',
    content: `在 <a>开源组</a> åˆ›å»ºäº†é¡¹ç›® <a>Vue</a>`,
    date: '刚刚',
    title: '威廉',
  },
  {
    avatar: 'svg:avatar-2',
    content: `关注了 <a>威廉</a> `,
    date: '1个小时前',
    title: '艾文',
  },
  {
    avatar: 'svg:avatar-3',
    content: `发布了 <a>个人动态</a> `,
    date: '1天前',
    title: '克里斯',
  },
  {
    avatar: 'svg:avatar-4',
    content: `发表文章 <a>如何编写一个Vite插件</a> `,
    date: '2天前',
    title: 'Vben',
  },
  {
    avatar: 'svg:avatar-1',
    content: `回复了 <a>杰克</a> çš„问题 <a>如何进行项目优化?</a>`,
    date: '3天前',
    title: '皮特',
  },
  {
    avatar: 'svg:avatar-2',
    content: `关闭了问题 <a>如何运行项目</a> `,
    date: '1周前',
    title: '杰克',
  },
  {
    avatar: 'svg:avatar-3',
    content: `发布了 <a>个人动态</a> `,
    date: '1周前',
    title: '威廉',
  },
  {
    avatar: 'svg:avatar-4',
    content: `推送了代码到 <a>Github</a>`,
    date: '2021-04-01 20:00',
    title: '威廉',
  },
  {
    avatar: 'svg:avatar-4',
    content: `发表文章 <a>如何编写使用 Admin Vben</a> `,
    date: '2021-03-01 20:00',
    title: 'Vben',
  },
];
eims-ui/apps/web-antd/src/views/eims/fixture/dashboard/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,17 @@
<script setup lang="ts">
import { AnalysisOverview, Page, WorkbenchTrends } from '@vben/common-ui';
import { overviewItems, trendItems } from './data';
</script>
<template>
  <Page :auto-content-height="true">
    <div class="h-full">
      <AnalysisOverview :items="overviewItems" />
      <WorkbenchTrends :items="trendItems" class="mt-5" title="最新动态" />
      <div class="h-5"></div>
    </div>
  </Page>
</template>
<style scoped></style>
eims-ui/apps/web-antd/src/views/eims/fixture/dashboard/type.js
eims-ui/apps/web-antd/src/views/eims/fixture/data.tsx
@@ -27,6 +27,14 @@
    label: '工具状态'
  },
  {
    component: 'Select',
    componentProps: {
      options: getDictOptions(DictEnum.FIXTURE_BORROW_STATUS)
    },
    fieldName: 'borrowStatus',
    label: '借用状态'
  },
  {
    component: 'Input',
    fieldName: 'assetNo',
    label: '资产编号'
@@ -101,6 +109,21 @@
    fixed: 'left'
  },
  {
    title: '借用状态',
    field: 'borrowStatus',
    sortable: true,
    slots: {
      default: ({ row }) => {
        if (row.borrowStatus === null || row.borrowStatus === '') {
          return '';
        }
        return renderDict(row.borrowStatus, DictEnum.FIXTURE_BORROW_STATUS);
      }
    },
    minWidth: 100,
    fixed: 'left'
  },
  {
    title: '类型',
    field: 'fixtureTypeName',
    minWidth: 100
@@ -112,6 +135,11 @@
    minWidth: 140
  },
  {
    title: '借用人',
    field: 'borrowUserName',
    minWidth: 100
  },
  {
    title: '工具编码',
    field: 'fixtureCode',
    sortable: true,
eims-ui/apps/web-antd/src/views/eims/fixture/fixture-drawer.vue
@@ -36,8 +36,6 @@
const [BasicDrawer, drawerApi] = useVbenDrawer({
  onCancel: handleCancel,
  closeOnPressEscape: true,
  placement: 'left',
  onConfirm: handleConfirm,
  async onOpenChange(isOpen) {
    if (!isOpen) {
eims-ui/apps/web-antd/src/views/eims/fixture/index.vue
@@ -1,11 +1,12 @@
<script setup lang="ts">
import type { Recordable } from '@vben/types';
import { onMounted, ref } from 'vue';
import { useRouter } from 'vue-router';
import { computed, onMounted, ref } from 'vue';
import { useAccess } from '@vben/access';
import { Page, useVbenDrawer, useVbenModal, type VbenFormProps } from '@vben/common-ui';
import { $t } from '@vben/locales';
import { useUserStore } from '@vben/stores';
import { addFullName, getPopupContainer, getVxePopupContainer } from '@vben/utils';
import { Modal, Popconfirm, Space } from 'ant-design-vue';
@@ -14,14 +15,21 @@
import { delFixture, fixtureExport, listFixture } from '#/api/eims/fixture';
import { getDeptTree, userList } from '#/api/system/user';
import { commonDownloadExcel } from '#/utils/file/download';
import fixtureBorrowDrawer from '#/views/eims/fixture-borrow/fixture-borrow-drawer.vue';
import { columns, querySchema } from './data';
import fixtureDrawer from './fixture-drawer.vue';
import fixtureImportModal from './fixture-import-modal.vue';
import FixtureTypeTree from './fixture-type-tree.vue';
const userStore = useUserStore();
const userId = userStore.userInfo?.userId;
// å·¦è¾¹å·¥å…·ç±»åž‹
const selectTypeId = ref<string[]>([]);
defineExpose({
  tableSelect
});
const formOptions: VbenFormProps = {
  commonConfig: {
@@ -104,6 +112,10 @@
  connectedComponent: fixtureDrawer
});
const [FixtureBorrowDrawer, fixtureBorrowDrawerApi] = useVbenDrawer({
  connectedComponent: fixtureBorrowDrawer
});
/**
 * å¯¼å…¥
 */
@@ -143,17 +155,29 @@
    }
  });
}
function handleBorrow(row: Recordable<any>, status: string) {
  if (userId === null || userId === undefined || userId === '') {
    Modal.error({
      content: '获取用户信息失败,请重新登录后重试!',
      title: '提示'
    });
    return false;
  }
  // å·¥å…·å°è´¦å€Ÿç”¨çŠ¶æ€TODO fixture_borrow_status 0-空闲 1-借出
  if (status === '0') {
    // ç©ºé—²æ—¶å€Ÿå‡ºï¼Œæ–°å¢žä¸€æ¡å€Ÿå‡ºæ•°æ®
    fixtureBorrowDrawerApi.setData({ status, borrowUser: userId, fixtureId: row.id, fixtureName: row.fixtureName, fixturePage: true });
    fixtureBorrowDrawerApi.open();
  } else if (status === '1') {
    // å€Ÿå‡ºæ—¶å½’还,更新借出数据
    fixtureBorrowDrawerApi.setData({ id: row.curBorrowId });
    fixtureBorrowDrawerApi.open();
  }
}
function handleDownloadExcel() {
  commonDownloadExcel(fixtureExport, '工具台账', tableApi.formApi.form.values, {
    fieldMappingTime: formOptions.fieldMappingTime
  });
}
const router = useRouter();
function handleDetail(record: Recordable<any>) {
  router.push(`/fixture/detail/${record.id}`);
}
/**
@@ -226,6 +250,30 @@
onMounted(async () => {
  await setupDeptSelect();
});
const { hasAccessByRoles } = useAccess();
const isSuperAdmin = computed(() => hasAccessByRoles(['superadmin']));
/**
 * åªæœ‰å€Ÿç”¨ç”¨æˆ·å’Œç®¡ç†å‘˜å¯ä»¥ç‚¹å‡»å½’还
 */
function isBorrowUser(row: any) {
  return isSuperAdmin.value || row?.borrowUser === userId;
}
function isBorrow(row: any) {
  // TODO å¯¹åº”字典状态fixture_borrow_status 0-空闲 1-借出
  return row.borrowStatus === '0' || row.borrowStatus === null;
}
function isReturn(row: any) {
  // TODO å¯¹åº”字典状态fixture_borrow_status 0-空闲 1-借出
  return row.borrowStatus === '1';
}
// é€‰ä¸­æ•°æ®
function tableSelect() {
  return tableApi.grid.getCheckboxRecords();
}
</script>
<template>
@@ -256,19 +304,20 @@
          </Space>
        </template>
        <template #equName="{ row }">
          <Space>
            <a-button type="link" @click="handleDetail(row)"> {{ row.equName }}</a-button>
          </Space>
        </template>
        <template #action="{ row }">
          <Space>
            <ghost-button v-access:code="['eims:fixture:edit']" @click.stop="handleEdit(row)">
              {{ $t('pages.common.edit') }}
            </ghost-button>
            <ghost-button v-if="row.menuType !== 'F'" class="btn-success" v-access:code="['eims:fixture:list']" @click="handleDetail(row)">
              {{ $t('pages.common.info') }}
            <ghost-button v-if="isBorrow(row)" class="btn-success" v-access:code="['eims:fixture:borrow']" @click="handleBorrow(row, '0')">
              å€Ÿç”¨
            </ghost-button>
            <ghost-button
              v-else-if="isReturn(row) && isBorrowUser(row)"
              v-access:code="['eims:fixture:borrow']"
              @click="handleBorrow(row, '1')"
            >
              å½’还
            </ghost-button>
            <Popconfirm :get-popup-container="getVxePopupContainer" placement="left" title="确认删除?" @confirm="handleDelete(row)">
              <ghost-button danger v-access:code="['eims:fixture:remove']" @click.stop="">
@@ -280,6 +329,7 @@
      </BasicTable>
    </div>
    <FixtureDrawer @reload="tableApi.query()" />
    <FixtureBorrowDrawer @reload="tableApi.query()" />
    <FixtureImportModal @reload="tableApi.query()" />
  </Page>
</template>
eims-ui/apps/web-antd/src/views/eims/repair-req/index.vue
@@ -13,7 +13,6 @@
import { delRepairReq, listRepairReq, repairReqExport } from '#/api/eims/repair-req';
import { getDeptTree, userList } from '#/api/system/user';
import { commonDownloadExcel } from '#/utils/file/download';
import { useRoleBaseFilters } from '#/views/eims/repair-req/use-role-base-filters';
import { columns, querySchema } from './data';
import repairReqDrawer from './repair-req-drawer.vue';
@@ -51,8 +50,8 @@
        return await listRepairReq({
          pageNum: page.currentPage,
          pageSize: page.pageSize,
          ...formValues,
          ...useRoleBaseFilters()
          ...formValues
          // ...useRoleBaseFilters()
        });
      }
    }
eims-ui/apps/web-antd/src/views/eims/repair-req/use-role-base-filters.ts
@@ -22,5 +22,7 @@
  if (repair.value) {
    params.status = '0';
  }
  console.info('useRoleBaseFilters');
  console.info(params);
  return { params };
}
eims-ui/packages/@core/base/shared/src/constants/dict-enum.ts
@@ -1,9 +1,11 @@
export enum DictEnum {
  EIMS_EQU_UNIT = 'eims_equ_unit', // è®¾å¤‡ç›˜ç‚¹çŠ¶æ€
  EIMS_FIXTURE_STATUS = 'eims_fixture_status', // è®¾å¤‡ç›˜ç‚¹çŠ¶æ€
  EIMS_FIXTURE_STATUS = 'eims_fixture_status', // å·¥å…·ï¼ˆæ²»å…·ï¼‰çŠ¶æ€
  EIMS_INVENTORY_DETAIL_STATU = 'inventory_detail_statu', // è®¾å¤‡ç›˜ç‚¹çŠ¶æ€
  EIMS_INVENTORY_STATU = 'inventory_statu', // è®¾å¤‡ç›˜ç‚¹çŠ¶æ€
  EQU_IMPORT_STATU = 'equ_import_status', // è®¾å¤‡å¯¼å…¥çŠ¶æ€
  FIXTURE_BORROW_RECORD_STATUS = 'fixture_borrow_record_status', // å·¥å…·ï¼ˆæ²»å…·ï¼‰å€Ÿç”¨è®°å½•状态
  FIXTURE_BORROW_STATUS = 'fixture_borrow_status', // å·¥å…·ï¼ˆæ²»å…·ï¼‰å€Ÿç”¨çŠ¶æ€
  REPAIR_FAULT_TYPE = 'repair_fault_type', // æŠ¥ä¿®çŠ¶æ€
  REPAIR_REQ_STATUS = 'repair_req_status', // æŠ¥ä¿®çŠ¶æ€
  REPAIR_REQ_TYPE = 'repair_req_type', // æŠ¥ä¿®ç±»åž‹
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/controller/EimsFixtureBorrowController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,105 @@
package org.dromara.eims.controller;
import java.util.List;
import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.web.core.BaseController;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.eims.domain.vo.EimsFixtureBorrowVo;
import org.dromara.eims.domain.bo.EimsFixtureBorrowBo;
import org.dromara.eims.service.IEimsFixtureBorrowService;
import org.dromara.common.mybatis.core.page.TableDataInfo;
/**
 * å€Ÿç”¨è®°å½•
 *
 * @author zhuguifei
 * @date 2025-02-18
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/eims/fixBorrow")
public class EimsFixtureBorrowController extends BaseController {
    private final IEimsFixtureBorrowService eimsFixtureBorrowService;
    /**
     * æŸ¥è¯¢å€Ÿç”¨è®°å½•列表
     */
    @SaCheckPermission("eims:fixtureBorrow:list")
    @GetMapping("/list")
    public TableDataInfo<EimsFixtureBorrowVo> list(EimsFixtureBorrowBo bo, PageQuery pageQuery) {
        return eimsFixtureBorrowService.queryPageList(bo, pageQuery);
    }
    /**
     * å¯¼å‡ºå€Ÿç”¨è®°å½•列表
     */
    @SaCheckPermission("eims:fixtureBorrow:export")
    @Log(title = "借用记录", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(EimsFixtureBorrowBo bo, HttpServletResponse response) {
        List<EimsFixtureBorrowVo> list = eimsFixtureBorrowService.queryList(bo);
        ExcelUtil.exportExcel(list, "借用记录", EimsFixtureBorrowVo.class, response);
    }
    /**
     * èŽ·å–å€Ÿç”¨è®°å½•è¯¦ç»†ä¿¡æ¯
     *
     * @param id ä¸»é”®
     */
    @SaCheckPermission("eims:fixtureBorrow:query")
    @GetMapping("/{id}")
    public R<EimsFixtureBorrowVo> getInfo(@NotNull(message = "主键不能为空")
                                     @PathVariable Long id) {
        return R.ok(eimsFixtureBorrowService.queryById(id));
    }
    /**
     * æ–°å¢žå€Ÿç”¨è®°å½•
     */
    @SaCheckPermission("eims:fixtureBorrow:add")
    @Log(title = "借用记录", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping()
    public R<Void> add(@Validated(AddGroup.class) @RequestBody EimsFixtureBorrowBo bo) {
        return toAjax(eimsFixtureBorrowService.insertByBo(bo));
    }
    /**
     * ä¿®æ”¹å€Ÿç”¨è®°å½•
     */
    @SaCheckPermission("eims:fixtureBorrow:edit")
    @Log(title = "借用记录", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PutMapping()
    public R<Void> edit(@Validated(EditGroup.class) @RequestBody EimsFixtureBorrowBo bo) {
        return toAjax(eimsFixtureBorrowService.updateByBo(bo));
    }
    /**
     * åˆ é™¤å€Ÿç”¨è®°å½•
     *
     * @param ids ä¸»é”®ä¸²
     */
    @SaCheckPermission("eims:fixtureBorrow:remove")
    @Log(title = "借用记录", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public R<Void> remove(@NotEmpty(message = "主键不能为空")
                          @PathVariable Long[] ids) {
        return toAjax(eimsFixtureBorrowService.deleteWithValidByIds(List.of(ids), true));
    }
}
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/EimsFixture.java
@@ -60,6 +60,11 @@
    private Long borrowUser;
    /**
     * å€Ÿç”¨çŠ¶æ€
     */
    private String borrowStatus;
    /**
     * çŠ¶æ€ï¼ˆå­—å…¸ï¼‰
     */
    private String status;
@@ -106,5 +111,10 @@
     */
    private String remark;
    /**
     * å½“前借用记录id
     */
    private Long curBorrowId;
}
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/EimsFixtureBorrow.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,88 @@
package org.dromara.eims.domain;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.io.Serial;
/**
 * å·¥å…·å€Ÿç”¨å¯¹è±¡ eims_fixture_borrow
 *
 * @author zhuguifei
 * @date 2025-02-18
 */
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("eims_fixture_borrow")
public class EimsFixtureBorrow extends BaseEntity {
    @Serial
    private static final long serialVersionUID = 1L;
    /**
     *
     */
    @TableId(value = "id")
    private Long id;
    /**
     * å€Ÿç”¨å·¥å…·id
     */
    private Long fixtureId;
    /**
     * å€Ÿç”¨å·¥å…·åç§°
     */
    private String fixtureName;
    /**
     * å€Ÿç”¨éƒ¨é—¨
     */
    private Long borrowDept;
    /**
     * å€Ÿç”¨äºº
     */
    private Long borrowUser;
    /**
     * ç»åŠžäºº
     */
    private Long agentUser;
    /**
     * å€Ÿç”¨è®°å½•状态(字典)
     */
    private String status;
    /**
     * å€Ÿç”¨æ—¶é—´
     */
    private Date borrowTime;
    /**
     * é¢„计归还时间
     */
    private Date planReturnTime;
    /**
     * å½’还时间
     */
    private Date returnTime;
    /**
     * å€Ÿç”¨ç†ç”±
     */
    private String borrowReason;
    /**
     * å¤‡æ³¨
     */
    private String remark;
}
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/bo/EimsFixtureBo.java
@@ -1,5 +1,8 @@
package org.dromara.eims.domain.bo;
import com.alibaba.excel.annotation.ExcelProperty;
import org.dromara.common.excel.annotation.ExcelDictFormat;
import org.dromara.common.excel.convert.ExcelDictConvert;
import org.dromara.eims.domain.EimsFixture;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import org.dromara.common.core.validate.AddGroup;
@@ -60,6 +63,11 @@
    private Long borrowUser;
    /**
     * å€Ÿç”¨çŠ¶æ€
     */
    private String borrowStatus;
    /**
     * çŠ¶æ€ï¼ˆå­—å…¸ï¼‰
     */
    private String status;
@@ -106,5 +114,10 @@
     */
    private String remark;
    /**
     * å½“前借用记录id
     */
    private Long curBorrowId;
}
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/bo/EimsFixtureBorrowBo.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,95 @@
package org.dromara.eims.domain.bo;
import org.dromara.eims.domain.EimsFixtureBorrow;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.*;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
/**
 * å·¥å…·å€Ÿç”¨ä¸šåŠ¡å¯¹è±¡ eims_fixture_borrow
 *
 * @author zhuguifei
 * @date 2025-02-18
 */
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = EimsFixtureBorrow.class, reverseConvertGenerate = false)
public class EimsFixtureBorrowBo extends BaseEntity {
    /**
     *
     */
    @NotNull(message = "不能为空", groups = { EditGroup.class })
    private Long id;
    /**
     * å€Ÿç”¨å·¥å…·id
     */
    @NotNull(message = "借用工具id不能为空", groups = { AddGroup.class, EditGroup.class })
    private Long fixtureId;
    /**
     * å€Ÿç”¨å·¥å…·åç§°
     */
    @NotBlank(message = "借用工具名称不能为空", groups = { AddGroup.class, EditGroup.class })
    private String fixtureName;
    /**
     * å€Ÿç”¨éƒ¨é—¨
     */
    @NotNull(message = "借用部门不能为空", groups = { AddGroup.class, EditGroup.class })
    private Long borrowDept;
    /**
     * å€Ÿç”¨äºº
     */
    @NotNull(message = "借用人不能为空", groups = { AddGroup.class, EditGroup.class })
    private Long borrowUser;
    /**
     * ç»åŠžäºº
     */
    private Long agentUser;
    /**
     * å€Ÿç”¨è®°å½•状态(字典)
     */
    @NotBlank(message = "借用记录状态(字典)不能为空", groups = { AddGroup.class, EditGroup.class })
    private String status;
    /**
     * å€Ÿç”¨æ—¶é—´
     */
    @NotNull(message = "借用时间不能为空", groups = { AddGroup.class, EditGroup.class })
    private Date borrowTime;
    /**
     * é¢„计归还时间
     */
    @NotNull(message = "预计归还时间不能为空", groups = { AddGroup.class, EditGroup.class })
    private Date planReturnTime;
    /**
     * å½’还时间
     */
    private Date returnTime;
    /**
     * å€Ÿç”¨ç†ç”±
     */
    @NotBlank(message = "借用理由不能为空", groups = { AddGroup.class, EditGroup.class })
    private String borrowReason;
    /**
     * å¤‡æ³¨
     */
    private String remark;
}
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/vo/EimsFixtureBorrowVo.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,127 @@
package org.dromara.eims.domain.vo;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.dromara.common.translation.annotation.Translation;
import org.dromara.common.translation.constant.TransConstant;
import org.dromara.eims.domain.EimsFixtureBorrow;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import org.dromara.common.excel.annotation.ExcelDictFormat;
import org.dromara.common.excel.convert.ExcelDictConvert;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
 * å·¥å…·å€Ÿç”¨è§†å›¾å¯¹è±¡ eims_fixture_borrow
 *
 * @author zhuguifei
 * @date 2025-02-18
 */
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = EimsFixtureBorrow.class)
public class EimsFixtureBorrowVo implements Serializable {
    @Serial
    private static final long serialVersionUID = 1L;
    /**
     *
     */
    @ExcelProperty(value = "")
    private Long id;
    /**
     * å€Ÿç”¨å·¥å…·id
     */
    @ExcelProperty(value = "借用工具id")
    private Long fixtureId;
    /**
     * å€Ÿç”¨å·¥å…·åç§°
     */
    @ExcelProperty(value = "借用工具名称")
    private String fixtureName;
    /**
     * å€Ÿç”¨éƒ¨é—¨
     */
    private Long borrowDept;
    /**
     * å€Ÿç”¨éƒ¨é—¨
     */
    @ExcelProperty(value = "借用部门")
    @Translation(type = TransConstant.DEPT_ID_TO_NAME, mapper = "borrowDept")
    private String borrowDeptName;
    /**
     * å€Ÿç”¨äºº
     */
    private Long borrowUser;
    /**
     * å€Ÿç”¨äºº
     */
    @ExcelProperty(value = "借用人")
    @Translation(type = TransConstant.USER_ID_TO_NICKNAME, mapper = "borrowUser")
    private String borrowUserName;
    /**
     * ç»åŠžäºº
     */
    private Long agentUser;
    /**
     * ç»åŠžäºº
     */
    @ExcelProperty(value = "经办人")
    @Translation(type = TransConstant.USER_ID_TO_NICKNAME, mapper = "agentUser")
    private Long agentUserName;
    /**
     * å€Ÿç”¨è®°å½•状态(字典)
     */
    @ExcelProperty(value = "借用记录状态", converter = ExcelDictConvert.class)
    @ExcelDictFormat(dictType = "fixture_borrow_record_status")
    private String status;
    /**
     * å€Ÿç”¨æ—¶é—´
     */
    @ExcelProperty(value = "借用时间")
    private Date borrowTime;
    /**
     * é¢„计归还时间
     */
    @ExcelProperty(value = "预计归还时间")
    private Date planReturnTime;
    /**
     * å½’还时间
     */
    @ExcelProperty(value = "归还时间")
    private Date returnTime;
    /**
     * å€Ÿç”¨ç†ç”±
     */
    @ExcelProperty(value = "借用理由")
    private String borrowReason;
    /**
     * å¤‡æ³¨
     */
    @ExcelProperty(value = "备注")
    private String remark;
}
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/vo/EimsFixtureVo.java
@@ -85,8 +85,16 @@
    private Long borrowUser;
    /**
     * å€Ÿç”¨çŠ¶æ€
     */
    @ExcelProperty(value = "借用状态", converter = ExcelDictConvert.class)
    @ExcelDictFormat(dictType = "fixture_borrow_status")
    private String borrowStatus;
    /**
     * å€Ÿç”¨äºº
     */
    @Translation(type = TransConstant.USER_ID_TO_NICKNAME, mapper = "borrowUser")
    private String borrowUserName;
    /**
@@ -146,5 +154,10 @@
    @ExcelProperty(value = "备注")
    private String remark;
    /**
     * å½“前借用记录id
     */
    private Long curBorrowId;
}
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/mapper/EimsFixtureBorrowMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,15 @@
package org.dromara.eims.mapper;
import org.dromara.eims.domain.EimsFixtureBorrow;
import org.dromara.eims.domain.vo.EimsFixtureBorrowVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
 * å·¥å…·å€Ÿç”¨Mapper接口
 *
 * @author zhuguifei
 * @date 2025-02-18
 */
public interface EimsFixtureBorrowMapper extends BaseMapperPlus<EimsFixtureBorrow, EimsFixtureBorrowVo> {
}
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/IEimsFixtureBorrowService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,68 @@
package org.dromara.eims.service;
import org.dromara.eims.domain.vo.EimsFixtureBorrowVo;
import org.dromara.eims.domain.bo.EimsFixtureBorrowBo;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import java.util.Collection;
import java.util.List;
/**
 * å·¥å…·å€Ÿç”¨Service接口
 *
 * @author zhuguifei
 * @date 2025-02-18
 */
public interface IEimsFixtureBorrowService {
    /**
     * æŸ¥è¯¢å·¥å…·å€Ÿç”¨
     *
     * @param id ä¸»é”®
     * @return å·¥å…·å€Ÿç”¨
     */
    EimsFixtureBorrowVo queryById(Long id);
    /**
     * åˆ†é¡µæŸ¥è¯¢å·¥å…·å€Ÿç”¨åˆ—表
     *
     * @param bo        æŸ¥è¯¢æ¡ä»¶
     * @param pageQuery åˆ†é¡µå‚æ•°
     * @return å·¥å…·å€Ÿç”¨åˆ†é¡µåˆ—表
     */
    TableDataInfo<EimsFixtureBorrowVo> queryPageList(EimsFixtureBorrowBo bo, PageQuery pageQuery);
    /**
     * æŸ¥è¯¢ç¬¦åˆæ¡ä»¶çš„工具借用列表
     *
     * @param bo æŸ¥è¯¢æ¡ä»¶
     * @return å·¥å…·å€Ÿç”¨åˆ—表
     */
    List<EimsFixtureBorrowVo> queryList(EimsFixtureBorrowBo bo);
    /**
     * æ–°å¢žå·¥å…·å€Ÿç”¨
     *
     * @param bo å·¥å…·å€Ÿç”¨
     * @return æ˜¯å¦æ–°å¢žæˆåŠŸ
     */
    Boolean insertByBo(EimsFixtureBorrowBo bo);
    /**
     * ä¿®æ”¹å·¥å…·å€Ÿç”¨
     *
     * @param bo å·¥å…·å€Ÿç”¨
     * @return æ˜¯å¦ä¿®æ”¹æˆåŠŸ
     */
    Boolean updateByBo(EimsFixtureBorrowBo bo);
    /**
     * æ ¡éªŒå¹¶æ‰¹é‡åˆ é™¤å·¥å…·å€Ÿç”¨ä¿¡æ¯
     *
     * @param ids     å¾…删除的主键集合
     * @param isValid æ˜¯å¦è¿›è¡Œæœ‰æ•ˆæ€§æ ¡éªŒ
     * @return æ˜¯å¦åˆ é™¤æˆåŠŸ
     */
    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/impl/EimsFixtureBorrowServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,211 @@
package org.dromara.eims.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.eims.domain.EimsEquType;
import org.dromara.eims.domain.EimsFixture;
import org.dromara.eims.domain.vo.EimsEquTypeVo;
import org.dromara.eims.domain.vo.EimsFixtureVo;
import org.dromara.eims.mapper.EimsFixtureMapper;
import org.dromara.system.domain.SysDept;
import org.dromara.system.domain.vo.SysDeptVo;
import org.dromara.system.mapper.SysDeptMapper;
import org.dromara.system.service.ISysDeptService;
import org.springframework.stereotype.Service;
import org.dromara.eims.domain.bo.EimsFixtureBorrowBo;
import org.dromara.eims.domain.vo.EimsFixtureBorrowVo;
import org.dromara.eims.domain.EimsFixtureBorrow;
import org.dromara.eims.mapper.EimsFixtureBorrowMapper;
import org.dromara.eims.service.IEimsFixtureBorrowService;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Collection;
/**
 * å·¥å…·å€Ÿç”¨Service业务层处理
 *
 * @author zhuguifei
 * @date 2025-02-18
 */
@RequiredArgsConstructor
@Service
public class EimsFixtureBorrowServiceImpl implements IEimsFixtureBorrowService {
    private final EimsFixtureBorrowMapper baseMapper;
    private final EimsFixtureMapper fixtureMapper;
    private final SysDeptMapper sysDeptMapper;
    /**
     * æŸ¥è¯¢å·¥å…·å€Ÿç”¨
     *
     * @param id ä¸»é”®
     * @return å·¥å…·å€Ÿç”¨
     */
    @Override
    public EimsFixtureBorrowVo queryById(Long id){
        return baseMapper.selectVoById(id);
    }
    /**
     * åˆ†é¡µæŸ¥è¯¢å·¥å…·å€Ÿç”¨åˆ—表
     *
     * @param bo        æŸ¥è¯¢æ¡ä»¶
     * @param pageQuery åˆ†é¡µå‚æ•°
     * @return å·¥å…·å€Ÿç”¨åˆ†é¡µåˆ—表
     */
    @Override
    public TableDataInfo<EimsFixtureBorrowVo> queryPageList(EimsFixtureBorrowBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<EimsFixtureBorrow> lqw = buildQueryWrapper(bo);
        Page<EimsFixtureBorrowVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }
    /**
     * æŸ¥è¯¢ç¬¦åˆæ¡ä»¶çš„工具借用列表
     *
     * @param bo æŸ¥è¯¢æ¡ä»¶
     * @return å·¥å…·å€Ÿç”¨åˆ—表
     */
    @Override
    public List<EimsFixtureBorrowVo> queryList(EimsFixtureBorrowBo bo) {
        LambdaQueryWrapper<EimsFixtureBorrow> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }
    private LambdaQueryWrapper<EimsFixtureBorrow> buildQueryWrapper(EimsFixtureBorrowBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<EimsFixtureBorrow> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getFixtureId() != null, EimsFixtureBorrow::getFixtureId, bo.getFixtureId());
        lqw.like(StringUtils.isNotBlank(bo.getFixtureName()), EimsFixtureBorrow::getFixtureName, bo.getFixtureName());
        lqw.eq(bo.getBorrowUser() != null, EimsFixtureBorrow::getBorrowUser, bo.getBorrowUser());
        lqw.eq(bo.getAgentUser() != null, EimsFixtureBorrow::getAgentUser, bo.getAgentUser());
        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), EimsFixtureBorrow::getStatus, bo.getStatus());
        lqw.between(params.get("beginBorrowTime") != null && params.get("endBorrowTime") != null,
            EimsFixtureBorrow::getBorrowTime ,params.get("beginBorrowTime"), params.get("endBorrowTime"));
        lqw.between(params.get("beginPlanReturnTime") != null && params.get("endPlanReturnTime") != null,
            EimsFixtureBorrow::getPlanReturnTime ,params.get("beginPlanReturnTime"), params.get("endPlanReturnTime"));
        lqw.eq(bo.getReturnTime() != null, EimsFixtureBorrow::getReturnTime, bo.getReturnTime());
        lqw.eq(StringUtils.isNotBlank(bo.getBorrowReason()), EimsFixtureBorrow::getBorrowReason, bo.getBorrowReason());
        /**
         * æŸ¥è¯¢éƒ¨é—¨ä¸‹æ‰€æœ‰å­éƒ¨é—¨
         */
        if (bo.getBorrowDept() != null ) {
            List<Long> allDescendantIds = getAllDescendantIds(bo.getBorrowDept());
            lqw.in(bo.getBorrowDept() != null ,EimsFixtureBorrow::getBorrowDept, allDescendantIds);
        }
        return lqw;
    }
    /**
     * æ ¹æ®id,获取所有后代id
     * @param rootId
     * @return
     */
    public List<Long> getAllDescendantIds(Long rootId) {
        List<Long> result = new ArrayList<>();
        result.add(rootId);
        collectDescendants(rootId, result);
        return result;
    }
    private void collectDescendants(Long currentId, List<Long> collector) {
        QueryWrapper<SysDept> sysDeptWrapper = new QueryWrapper<>();
        sysDeptWrapper.lambda().eq(SysDept::getParentId, currentId);
        List<SysDeptVo> children = sysDeptMapper.selectVoList(sysDeptWrapper);
        if (children != null && !children.isEmpty()) {
            for (SysDeptVo child : children) {
                Long childId = child.getDeptId();
                collector.add(childId);
                collectDescendants(childId, collector);
            }
        }
    }
    /**
     * æ–°å¢žå·¥å…·å€Ÿç”¨
     *
     * @param bo å·¥å…·å€Ÿç”¨
     * @return æ˜¯å¦æ–°å¢žæˆåŠŸ
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean insertByBo(EimsFixtureBorrowBo bo) {
        EimsFixtureBorrow add = MapstructUtils.convert(bo, EimsFixtureBorrow.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
            //同时更新工具台账表中借用人
            EimsFixtureVo eimsFixtureVo = fixtureMapper.selectVoById(bo.getFixtureId());
            eimsFixtureVo.setBorrowUser(LoginHelper.getUserId());
            //设置工具台账状态为借用
            eimsFixtureVo.setBorrowStatus("1");//TODO ä¿æŒå­—典数据一致fixture_borrow_status
            //更新工具台账当前借用记录id
            eimsFixtureVo.setCurBorrowId(add.getId());
            eimsFixtureVo.setBorrowDept(LoginHelper.getDeptId());
            EimsFixture fixture = MapstructUtils.convert(eimsFixtureVo, EimsFixture.class);
            fixtureMapper.updateById(fixture);
        }
        return flag;
    }
    /**
     * ä¿®æ”¹å·¥å…·å€Ÿç”¨
     *
     * @param bo å·¥å…·å€Ÿç”¨
     * @return æ˜¯å¦ä¿®æ”¹æˆåŠŸ
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateByBo(EimsFixtureBorrowBo bo) {
        EimsFixtureBorrow update = MapstructUtils.convert(bo, EimsFixtureBorrow.class);
        validEntityBeforeSave(update);
        //设置工具台账状态为归还 TODO ä¿æŒå­—典数据一致fixture_borrow_record_status
        if(bo.getStatus().equals("1")){
            EimsFixtureVo eimsFixtureVo = fixtureMapper.selectVoById(bo.getFixtureId());
            //设置工具台账状态为归还
            eimsFixtureVo.setBorrowStatus("0"); //TODO ä¿æŒå­—典数据一致fixture_borrow_status
            EimsFixture fixture = MapstructUtils.convert(eimsFixtureVo, EimsFixture.class);
            fixtureMapper.updateById(fixture);
        }
        return baseMapper.updateById(update) > 0;
    }
    /**
     * ä¿å­˜å‰çš„æ•°æ®æ ¡éªŒ
     */
    private void validEntityBeforeSave(EimsFixtureBorrow entity){
        //TODO åšä¸€äº›æ•°æ®æ ¡éªŒ,如唯一约束
    }
    /**
     * æ ¡éªŒå¹¶æ‰¹é‡åˆ é™¤å·¥å…·å€Ÿç”¨ä¿¡æ¯
     *
     * @param ids     å¾…删除的主键集合
     * @param isValid æ˜¯å¦è¿›è¡Œæœ‰æ•ˆæ€§æ ¡éªŒ
     * @return æ˜¯å¦åˆ é™¤æˆåŠŸ
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO åšä¸€äº›ä¸šåŠ¡ä¸Šçš„æ ¡éªŒ,判断是否需要校验
        }
        return baseMapper.deleteByIds(ids) > 0;
    }
}
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/impl/EimsFixtureServiceImpl.java
@@ -100,6 +100,7 @@
        lqw.eq(StringUtils.isNotBlank(bo.getFixtureDesc()), EimsFixture::getFixtureDesc, bo.getFixtureDesc());
        lqw.eq(bo.getBorrowDept()!=null, EimsFixture::getBorrowDept, bo.getBorrowDept());
        lqw.eq(bo.getBorrowUser()!=null, EimsFixture::getBorrowUser, bo.getBorrowUser());
        lqw.eq(StringUtils.isNotEmpty(bo.getBorrowStatus()), EimsFixture::getBorrowStatus, bo.getBorrowStatus());
        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), EimsFixture::getStatus, bo.getStatus());
        lqw.like(StringUtils.isNotBlank(bo.getAssetNo()), EimsFixture::getAssetNo, bo.getAssetNo());
        lqw.like(StringUtils.isNotBlank(bo.getModelNo()), EimsFixture::getModelNo, bo.getModelNo());
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/service/impl/EimsRepairReqServiceImpl.java
@@ -10,7 +10,12 @@
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.dromara.eims.domain.EimsEqu;
import org.dromara.eims.domain.EimsFixtureBorrow;
import org.dromara.eims.domain.vo.EimsInventoryDetailVo;
import org.dromara.eims.utils.DataFilterUtil;
import org.dromara.system.domain.SysDept;
import org.dromara.system.domain.vo.SysDeptVo;
import org.dromara.system.mapper.SysDeptMapper;
import org.springframework.stereotype.Service;
import org.dromara.eims.domain.bo.EimsRepairReqBo;
import org.dromara.eims.domain.vo.EimsRepairReqVo;
@@ -18,6 +23,7 @@
import org.dromara.eims.mapper.EimsRepairReqMapper;
import org.dromara.eims.service.IEimsRepairReqService;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Collection;
@@ -33,6 +39,7 @@
public class EimsRepairReqServiceImpl implements IEimsRepairReqService {
    private final EimsRepairReqMapper baseMapper;
    private final SysDeptMapper sysDeptMapper;
    /**
     * æŸ¥è¯¢æ•…障报修
@@ -61,6 +68,7 @@
    @Override
    public TableDataInfo<EimsRepairReqVo> queryPageListCustom(EimsRepairReqBo bo, PageQuery pageQuery) {
        DataFilterUtil.getInstance().filterRepairReq(bo);
        Page<EimsRepairReqVo> page = baseMapper.selectRepairReqList(pageQuery.build(), buildWrapper(bo));
        return TableDataInfo.build(page);
    }
@@ -71,7 +79,6 @@
        qw.like(StringUtils.isNotBlank(bo.getCode()),"a.code", bo.getCode());
        qw.eq(StringUtils.isNotBlank(bo.getStatus()), "a.status", bo.getStatus());
        qw.eq(bo.getReqTime() != null, "a.req_time", bo.getReqTime());
        qw.eq(bo.getReqDept() != null, "a.req_dept", bo.getReqDept());
        qw.eq(bo.getReqUser() != null,"a.req_user", bo.getReqUser());
        qw.eq(StringUtils.isNotBlank(bo.getUrgencyLevel()), "a.urgency_level", bo.getUrgencyLevel());
        qw.eq(StringUtils.isNotBlank(bo.getReqType()), "a.req_type", bo.getReqType());
@@ -83,9 +90,48 @@
        qw.eq(params.containsKey("status"), "a.status", params.get("status"));
        qw.between(params.get("beginReqTime") != null && params.get("endReqTime") != null,
            "a.req_time", params.get("beginReqTime"), params.get("endReqTime"));
        qw.eq(bo.getCreateBy()!=null, "a.create_by", bo.getCreateBy());
        qw.eq(StringUtils.isNotEmpty(bo.getStatus()), "a.status", bo.getStatus());
        /**
         * æŸ¥è¯¢éƒ¨é—¨ä¸‹æ‰€æœ‰å­éƒ¨é—¨
         */
        if (bo.getReqDept() != null) {
            List<Long> allDescendantIds = getAllDescendantIds(bo.getReqDept());
            qw.in(bo.getReqDept() != null, "a.req_dept", allDescendantIds);
        }
        return qw;
    }
    /**
     * æ ¹æ®id,获取所有后代id
     *
     * @param rootId
     * @return
     */
    public List<Long> getAllDescendantIds(Long rootId) {
        List<Long> result = new ArrayList<>();
        result.add(rootId);
        collectDescendants(rootId, result);
        return result;
    }
    private void collectDescendants(Long currentId, List<Long> collector) {
        QueryWrapper<SysDept> sysDeptWrapper = new QueryWrapper<>();
        sysDeptWrapper.lambda().eq(SysDept::getParentId, currentId);
        List<SysDeptVo> children = sysDeptMapper.selectVoList(sysDeptWrapper);
        if (children != null && !children.isEmpty()) {
            for (SysDeptVo child : children) {
                Long childId = child.getDeptId();
                collector.add(childId);
                collectDescendants(childId, collector);
            }
        }
    }
    /**
     * æŸ¥è¯¢ç¬¦åˆæ¡ä»¶çš„æ•…障报修列表
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/utils/DataFilterUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,42 @@
package org.dromara.eims.utils;
import org.dromara.common.core.domain.model.LoginUser;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.eims.domain.bo.EimsRepairReqBo;
import java.util.Set;
/**
 * è‡ªå®šä¹‰æ•°æ®éš”离
 */
public class DataFilterUtil {
    //TODO ä¿æŒä¸Žæ•°æ®åº“一直 å®šä¹‰è§’色类型 operator-操作工 repair-维修工
    private  enum Role {
        operator, repair
    }
    private static final DataFilterUtil INSTANCE = new DataFilterUtil();
    private DataFilterUtil() {
    }
    public static DataFilterUtil getInstance() {
        return INSTANCE;
    }
    //报修单
    public void filterRepairReq(EimsRepairReqBo bo){
        LoginUser loginUser = LoginHelper.getLoginUser();
        if (loginUser == null)  return;
        Set<String> rolePermission = loginUser.getRolePermission();
        if (rolePermission == null)  return;
        if (rolePermission.contains(Role.operator.name())) {
            //维修工只能查询自己的数据
            bo.setCreateBy(loginUser.getUserId());
        }else if (rolePermission.contains(Role.repair.name())) {
            //TODO ç»´ä¿®å·¥åªèƒ½æŸ¥è¯¢æœªæŽ¥å•状态的报修单(具体状态参考字典repair_req_status)
            bo.setStatus("0");
        }
        System.err.println(loginUser);
    }
}
eims/ruoyi-modules/lb-eims/src/main/resources/mapper/eims/EimsFixtureBorrowMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.eims.mapper.EimsFixtureBorrowMapper">
</mapper>