From e1cac1af6129216da66e569ddec892dd1f07fe80 Mon Sep 17 00:00:00 2001
From: chen.lin <1442464845@qq.com>
Date: 星期三, 25 二月 2026 10:14:37 +0800
Subject: [PATCH] 站点复制功能

---
 rsf-admin/src/page/basicInfo/basStation/BasStationCreate.jsx                             |    6 ++-
 rsf-admin/src/page/basicInfo/basStation/BasStationList.jsx                               |   33 +++++++++++++++-
 rsf-server/src/main/java/com/vincent/rsf/server/system/controller/AuthController.java    |    1 
 rsf-server/src/main/java/com/vincent/rsf/server/system/service/UserService.java          |    5 ++
 rsf-admin/src/i18n/zh.js                                                                 |    3 +
 rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupList.jsx                               |   12 +++---
 rsf-admin/src/i18n/en.js                                                                 |    1 
 rsf-server/src/main/java/com/vincent/rsf/server/system/service/impl/UserServiceImpl.java |   12 ++++++
 8 files changed, 61 insertions(+), 12 deletions(-)

diff --git a/rsf-admin/src/i18n/en.js b/rsf-admin/src/i18n/en.js
index a5aa5f4..8ea701e 100644
--- a/rsf-admin/src/i18n/en.js
+++ b/rsf-admin/src/i18n/en.js
@@ -1446,6 +1446,7 @@
         confirm: 'confirm',
         cancel: "cancel",
         delete: 'Delete',
+        copy: 'copy',
         query: "Query",
         bulkExport: "Bulk Export",
         continue: 'Continue Receipt',
diff --git a/rsf-admin/src/i18n/zh.js b/rsf-admin/src/i18n/zh.js
index cdf460c..4e7d00f 100644
--- a/rsf-admin/src/i18n/zh.js
+++ b/rsf-admin/src/i18n/zh.js
@@ -536,7 +536,7 @@
                 name: "鐗╂枡鍒嗙粍鍚嶇О",
                 code: "鐗╂枡鍒嗙粍缂栫爜",
                 parentId: "涓婄骇鍚嶇О",
-                parCode: "涓婄骇缂栫爜",
+                parCode: "鐗╂枡璺緞缂栫爜",
             },
             warehouse: {
                 name: "浠撳簱鍚嶇О",
@@ -1516,6 +1516,7 @@
         confirmSelect: '纭閫夋嫨',
         cancel: "鍙栨秷",
         delete: '鍒犻櫎',
+        copy: '澶嶅埗',
         query: "鏌ヨ",
         top: "缃《",
         resort: "鎺掑簭",
diff --git a/rsf-admin/src/page/basicInfo/basStation/BasStationCreate.jsx b/rsf-admin/src/page/basicInfo/basStation/BasStationCreate.jsx
index b73e16b..5534a72 100644
--- a/rsf-admin/src/page/basicInfo/basStation/BasStationCreate.jsx
+++ b/rsf-admin/src/page/basicInfo/basStation/BasStationCreate.jsx
@@ -35,7 +35,7 @@
 import DictionaryArraySelect from "../../components/DictionaryArraySelect";
 
 const BasStationCreate = (props) => {
-    const { open, setOpen } = props;
+    const { open, setOpen , copyRecord = null, onClose} = props;
 
     const translate = useTranslate();
     const notify = useNotify();
@@ -43,6 +43,7 @@
     const handleClose = (event, reason) => {
         if (reason !== "backdropClick") {
             setOpen(false);
+            if (typeof onClose === 'function') {onClose();}
         }
     };
 
@@ -58,7 +59,8 @@
     return (
         <>
             <CreateBase
-                record={{}}
+              key={open ? (copyRecord ? 'copy' : 'new') : 'closed'}
+              record={copyRecord || {}}
                 transform={(data) => {
                     return data;
                 }}
diff --git a/rsf-admin/src/page/basicInfo/basStation/BasStationList.jsx b/rsf-admin/src/page/basicInfo/basStation/BasStationList.jsx
index 8e9407d..eb4489a 100644
--- a/rsf-admin/src/page/basicInfo/basStation/BasStationList.jsx
+++ b/rsf-admin/src/page/basicInfo/basStation/BasStationList.jsx
@@ -33,7 +33,8 @@
     DeleteButton,
 
 } from 'react-admin';
-import { Box, Typography, Card, Stack } from '@mui/material';
+import { Box, Typography, Card, Stack, Button } from '@mui/material';
+import ContentCopyIcon from '@mui/icons-material/ContentCopy';
 import { styled } from '@mui/material/styles';
 import BasStationCreate from "./BasStationCreate";
 import BasStationPanel from "./BasStationPanel";
@@ -59,7 +60,7 @@
     '& .column-name': {
     },
     '& .opt': {
-        width: 200
+        width: 220
     },
 }));
 
@@ -93,7 +94,29 @@
         resettable
     />,
 ]
-
+const CopyButton = ({ setCopyRecord, setCreateDialog }) => {
+    const record = useRecordContext();
+    const translate = useTranslate();
+    if (!record) return null;
+    return (
+        <Button
+            size="small"
+            startIcon={<ContentCopyIcon fontSize="small" />}
+            sx={{ padding: '1px', fontSize: '.75rem', minWidth: 'auto' }}
+            onClick={(e) => {
+                e.stopPropagation();
+                const { id, createTime, updateTime, createBy, updateBy, createBy$, updateBy$, ...rest } = record;
+                const copied = { ...rest };
+                if (record.areaIds) copied.areaIds = [...(Array.isArray(record.areaIds) ? record.areaIds : [])];
+                if (record.containerTypes) copied.containerTypes = [...(Array.isArray(record.containerTypes) ? record.containerTypes : [])];
+                setCopyRecord(copied);
+                setCreateDialog(true);
+            }}
+        >
+            {translate('toolbar.copy')}
+        </Button>
+    );
+};
 const BasStationList = () => {
     const translate = useTranslate();
 
@@ -101,6 +124,7 @@
     const [drawerVal, setDrawerVal] = useState(false);
     const [areaFieldDialog, setAreaFieldDialog] = useState(false);
     const [areaFieldDialog2, setAreaFieldDialog2] = useState(false);
+    const [copyRecord, setCopyRecord] = useState(null);
     return (
         <Box display="flex">
             <List
@@ -201,6 +225,7 @@
                     {/* <BooleanField source="statusBool" label="common.field.status" sortable={false} /> */}
                     <TextField source="memo" label="common.field.memo" sortable={false} />
                     <WrapperField cellClassName="opt" label="common.field.opt">
+                        <CopyButton setCopyRecord={setCopyRecord} setCreateDialog={setCreateDialog} />
                         <EditButton sx={{ padding: '1px', fontSize: '.75rem' }} />
                         <DeleteButton sx={{ padding: '1px', fontSize: '.75rem' }} mutationMode={OPERATE_MODE} />
                     </WrapperField>
@@ -210,6 +235,8 @@
             <BasStationCreate
                 open={createDialog}
                 setOpen={setCreateDialog}
+                copyRecord={copyRecord}
+                onClose={() => setCopyRecord(null)}
             />
 
             <PageDrawer
diff --git a/rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupList.jsx b/rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupList.jsx
index 61e2d69..a8cb90a 100644
--- a/rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupList.jsx
+++ b/rsf-admin/src/page/basicInfo/matnrGroup/MatnrGroupList.jsx
@@ -46,15 +46,15 @@
         minWidth: 80,
     },
     {
+      id: 'parCode',
+      label: 'table.field.matnrGroup.parCode',
+      minWidth: 100,
+    },
+    {
         id: 'name',
         label: 'table.field.matnrGroup.name',
         Width: 100,
-    },
-    // {
-    //     id: 'parCode',
-    //     label: 'table.field.matnrGroup.parCode',
-    //     minWidth: 100,
-    // }
+    }
 ];
 
 const getIconComponent = (iconStr) => {
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/system/controller/AuthController.java b/rsf-server/src/main/java/com/vincent/rsf/server/system/controller/AuthController.java
index 8551b63..09e34f3 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/system/controller/AuthController.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/system/controller/AuthController.java
@@ -80,6 +80,7 @@
                 configProperties.getTokenExpireTime(), configProperties.getTokenKey());
         userLoginService.saveAsync(user.getId(), accessToken, UserLogin.TYPE_LOGIN, user.getTenantId(), null, request);
         Tenant tenant = tenantService.getById(user.getTenantId());
+        user = userService.fillRoleIdsForResponse(user);
         return R.ok("Sign In Success").add(new LoginResult(accessToken, user, tenant.getName()));
     }
 
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/system/service/UserService.java b/rsf-server/src/main/java/com/vincent/rsf/server/system/service/UserService.java
index 9981a93..396ade9 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/system/service/UserService.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/system/service/UserService.java
@@ -17,6 +17,11 @@
 
     User setUserAuthInfo(User user);
 
+    /**
+     * 涓鸿繑鍥炵粰鍓嶇鐨� User 濉厖 roleIds锛屽彧鏌ヤ竴娆″簱锛岄伩鍏嶅悇澶勯噸澶嶅啓涓� @JsonIgnore 瀵艰嚧鍓嶇鎷夸笉鍒�
+     */
+    User fillRoleIdsForResponse(User user);
+
     boolean comparePassword(String dbPassword, String inputPassword);
 
     String encodePassword(String password);
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/system/service/impl/UserServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/system/service/impl/UserServiceImpl.java
index dea12b4..d532c92 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/system/service/impl/UserServiceImpl.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/system/service/impl/UserServiceImpl.java
@@ -5,6 +5,7 @@
 import com.vincent.rsf.server.common.domain.BaseParam;
 import com.vincent.rsf.server.common.domain.PageParam;
 import com.vincent.rsf.server.common.domain.PageResult;
+import com.vincent.rsf.server.system.entity.Role;
 import com.vincent.rsf.server.system.entity.User;
 import com.vincent.rsf.server.system.mapper.UserMapper;
 import com.vincent.rsf.server.system.service.RoleMenuService;
@@ -14,6 +15,7 @@
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
+import java.util.List;
 
 @Service("userService")
 public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
@@ -56,6 +58,16 @@
     }
 
     @Override
+    public User fillRoleIdsForResponse(User user) {
+        if (user == null || user.getId() == null) {
+            return user;
+        }
+        List<Role> roles = userRoleService.listByUserId(user.getId());
+        user.setRoleIds(roles.stream().map(Role::getId).toArray(Long[]::new));
+        return user;
+    }
+
+    @Override
     public boolean comparePassword(String dbPassword, String inputPassword) {
         return bCryptPasswordEncoder.matches(inputPassword, dbPassword);
     }

--
Gitblit v1.9.1