@@ -153,6 +153,7 @@ export const AppVersionList = () => {
const isPublish = item.version === appVersion;
const color = isPublish ? 'bg-green-500' : '';
const isRunning = item.status === 'running';
+ console.log('appVersion', item, appVersion, versionStore.app);
return (
diff --git a/src/pages/app/edit/List.tsx b/src/pages/app/edit/List.tsx
index 00a699d..1dc7767 100644
--- a/src/pages/app/edit/List.tsx
+++ b/src/pages/app/edit/List.tsx
@@ -1,6 +1,6 @@
import { useShallow } from 'zustand/react/shallow';
import { useUserAppStore } from '../store';
-import { useEffect, useState } from 'react';
+import { useEffect, useMemo, useState } from 'react';
import { useModal } from '@kevisual/components/modal/Confirm.tsx';
import DeleteOutlined from '@ant-design/icons/DeleteOutlined';
@@ -12,7 +12,7 @@ import CodeOutlined from '@ant-design/icons/CodeOutlined';
import ShareAltOutlined from '@ant-design/icons/ShareAltOutlined';
import { FormControlLabel, Switch, useTheme } from '@mui/material';
import { isObjectNull } from '@/utils/is-null';
-import { useNewNavigate } from '@/modules';
+import { queryLogin, useNewNavigate } from '@/modules';
import { DialogActions, Tooltip } from '@mui/material';
import { marked } from 'marked';
import clsx from 'clsx';
@@ -28,6 +28,7 @@ import { TextField, InputAdornment } from '@mui/material';
import { useForm, Controller } from 'react-hook-form';
import { pick } from 'lodash-es';
import copy from 'copy-to-clipboard';
+import { useLayoutStore } from '@/modules/layout/store';
const FormModal = () => {
const defaultValues = {
@@ -75,6 +76,8 @@ const FormModal = () => {
const isEdit = containerStore?.userApp?.id;
const theme = useTheme();
const defaultProps = theme.components?.MuiTextField?.defaultProps as any;
+ const isAdmin = useLayoutStore(useShallow((state) => state.isAdmin));
+
return (
-
-
+
+
+
{containerStore.list.length > 0 &&
containerStore.list.map((item) => {
diff --git a/src/pages/user/admin/store/admin-store.ts b/src/pages/user/admin/store/admin-store.ts
new file mode 100644
index 0000000..1c0cc13
--- /dev/null
+++ b/src/pages/user/admin/store/admin-store.ts
@@ -0,0 +1,125 @@
+import { create } from 'zustand';
+import { query } from '@/modules';
+import { toast } from 'react-toastify';
+import { Result } from '@kevisual/query/query';
+type AdminStore = {
+ /**
+ * 创建新用户
+ * @returns
+ */
+ createNewUser: (data: any) => Promise
;
+ /**
+ * 删除用户
+ * @param id
+ */
+ deleteUser: (id: string) => Promise;
+ /**
+ * 更新用户
+ * @param id
+ * @param data
+ */
+ updateUser: (id: string, data: any) => Promise;
+
+ /**
+ * 重置密码
+ * @param id
+ */
+ resetPassword: (id: string, password?: string) => Promise;
+
+ /**
+ * 修改用户名
+ * @param id
+ * @param name
+ */
+ changeName: (id: string, name: string) => Promise>;
+
+ /**
+ * 检查用户是否存在
+ * @param name
+ * @returns
+ */
+ checkUserExist: (name: string) => Promise;
+};
+
+export const useAdminStore = create((set) => ({
+ createNewUser: async (data: any) => {
+ const res = await query.post({
+ path: 'user',
+ key: 'createNewUser',
+ data,
+ });
+ if (res.code === 200) {
+ toast.success('创建用户成功');
+ } else {
+ toast.error(res.message || '创建用户失败');
+ }
+ },
+ deleteUser: async (id: string) => {
+ const res = await query.post({
+ path: 'user',
+ key: 'deleteUser',
+ data: {
+ id,
+ },
+ });
+ if (res.code === 200) {
+ toast.success('删除用户成功');
+ } else {
+ toast.error(res.message || '删除用户失败');
+ }
+ },
+ updateUser: async (id: string, data: any) => {
+ console.log('updateUser', id, data);
+ },
+ resetPassword: async (id: string, password?: string) => {
+ const res = await query.post({
+ path: 'user',
+ key: 'resetPassword',
+ data: {
+ id,
+ password,
+ },
+ });
+ if (res.code === 200) {
+ if (res.data.password) {
+ toast.success('new password is ' + res.data.password);
+ } else {
+ toast.success('重置密码成功');
+ }
+ } else {
+ toast.error(res.message || '重置密码失败');
+ }
+ },
+ changeName: async (id: string, name: string) => {
+ const res = await query.post({
+ path: 'user',
+ key: 'changeName',
+ data: {
+ id,
+ newName: name,
+ },
+ });
+ if (res.code === 200) {
+ toast.success('修改用户名成功');
+ } else {
+ toast.error(res.message || '修改用户名失败');
+ }
+ return res;
+ },
+ checkUserExist: async (name: string) => {
+ const res = await query.post({
+ path: 'user',
+ key: 'checkUserExist',
+ data: {
+ username: name,
+ },
+ });
+ if (res.code === 200) {
+ const user = res.data || {};
+ return !!user.id;
+ } else {
+ toast.error(res.message || '检查用户是否存在,请求失败');
+ }
+ return null;
+ },
+}));
diff --git a/src/pages/user/edit/List.tsx b/src/pages/user/edit/List.tsx
index 563ecf3..4862e5f 100644
--- a/src/pages/user/edit/List.tsx
+++ b/src/pages/user/edit/List.tsx
@@ -1,22 +1,18 @@
import { Fragment, useEffect, useState } from 'react';
import { useUserStore } from '../store';
import { useShallow } from 'zustand/react/shallow';
-import EditOutlined from '@ant-design/icons/EditOutlined';
-import SaveOutlined from '@ant-design/icons/SaveOutlined';
-import DeleteOutlined from '@ant-design/icons/DeleteOutlined';
-import LeftOutlined from '@ant-design/icons/LeftOutlined';
-import PlusOutlined from '@ant-design/icons/PlusOutlined';
-import clsx from 'clsx';
import { isObjectNull } from '@/utils/is-null';
import { CardBlank } from '@kevisual/components/card/CardBlank.tsx';
-import { Dialog, ButtonGroup, Button, DialogContent, DialogTitle } from '@mui/material';
+import { Dialog, ButtonGroup, Button, DialogContent, DialogTitle, Tooltip } from '@mui/material';
import { IconButton } from '@kevisual/components/button/index.tsx';
import { useTranslation } from 'react-i18next';
import { useModal } from '@kevisual/components/modal/Confirm.tsx';
import { TextField } from '@mui/material';
import { useForm, Controller } from 'react-hook-form';
import { pick } from 'lodash-es';
-
+import { useAdminStore } from '../admin/store/admin-store';
+import { SquareAsterisk, Edit as EditOutlined, Trash as DeleteOutlined, Plus as PlusOutlined, UserPen } from 'lucide-react';
+import { toast } from 'react-toastify';
const FormModal = () => {
const { control, handleSubmit, reset } = useForm();
const userStore = useUserStore(
@@ -30,7 +26,7 @@ const FormModal = () => {
};
}),
);
-
+ const adminStore = useAdminStore(useShallow((state) => state));
useEffect(() => {
const open = userStore.showEdit;
if (open) {
@@ -46,7 +42,12 @@ const FormModal = () => {
const onFinish = (values: any) => {
const pickValues = pick(values, ['id', 'username', 'description']);
- userStore.updateData(pickValues);
+ if (pickValues.id) {
+ userStore.updateData(pickValues);
+ } else {
+ const newPickValues = pick(values, ['username', 'description', 'password']);
+ adminStore.createNewUser(newPickValues);
+ }
};
const onClose = () => {
@@ -69,7 +70,7 @@ const FormModal = () => {
}}>
{isEdit ? t('Edit') : t('Add')}
-
+
+
+ );
+};
+export const NameModal = () => {
+ const { control, handleSubmit, reset } = useForm();
+ const userStore = useUserStore(useShallow((state) => state));
+ const adminStore = useAdminStore(useShallow((state) => state));
+ const onFinish = async (values: any) => {
+ const check = await adminStore.checkUserExist(values.username);
+ if (check === false) {
+ const uid = userStore.formData.id;
+ if (!uid) {
+ toast.error('获取用户id失败');
+ return;
+ }
+ const res = await adminStore.changeName(uid, values.username);
+ if (res.code === 200) {
+ userStore.setShowNameEdit(false);
+ userStore.getList();
+ }
+ } else {
+ toast.error('用户名已存在,请重新输入');
+ }
+ };
+ const onClose = () => {
+ userStore.setShowNameEdit(false);
+ reset({});
+ userStore.setFormData({});
+ };
+ const { t } = useTranslation();
+ return (
+
+
{contextHolder}
);
diff --git a/src/pages/user/edit/Profile.tsx b/src/pages/user/edit/Profile.tsx
index 227e2a2..9aaf1e7 100644
--- a/src/pages/user/edit/Profile.tsx
+++ b/src/pages/user/edit/Profile.tsx
@@ -1,4 +1,4 @@
-import { TextField } from '@mui/material';
+import { InputAdornment, TextField, Tooltip } from '@mui/material';
import { useForm, Controller } from 'react-hook-form';
import { Button } from '@mui/material';
import { useUserStore } from '../store';
@@ -10,6 +10,8 @@ import UploadOutlined from '@ant-design/icons/UploadOutlined';
import PandaPNG from '@/assets/panda.png';
import { FileUpload } from '../module/FileUpload';
import { useTranslation } from 'react-i18next';
+import { Edit } from 'lucide-react';
+import { toast } from 'react-toastify';
export const Profile = () => {
const { t } = useTranslation();
@@ -73,7 +75,7 @@ export const Profile = () => {
}
};
return (
-
+
{t('Profile')}
{t('Edit your profile')}
@@ -87,7 +89,38 @@ export const Profile = () => {
}
+ render={({ field }) => (
+
+
+ {
+ console.log('onClick edit');
+ toast.info('联系客服修改,因为名称和上传文件绑定了。', {
+ autoClose: 20000,
+ });
+ }}
+ />
+
+
+ ),
+ onKeyDown: (event) => {
+ if (event.key === 'Enter') {
+ // setSearch(field.value);
+ }
+ },
+ },
+ }}
+ />
+ )}
/>
void;
+ showNameEdit: boolean;
+ setShowNameEdit: (showNameEdit: boolean) => void;
formData: any;
setFormData: (formData: any) => void;
loading: boolean;
@@ -18,6 +20,8 @@ export const useUserStore = create((set, get) => {
return {
showEdit: false,
setShowEdit: (showEdit) => set({ showEdit }),
+ showNameEdit: false,
+ setShowNameEdit: (showNameEdit) => set({ showNameEdit }),
formData: {},
setFormData: (formData) => set({ formData }),
loading: false,
diff --git a/submodules/query-config b/submodules/query-config
index 2068892..862b29c 160000
--- a/submodules/query-config
+++ b/submodules/query-config
@@ -1 +1 @@
-Subproject commit 20688920b8be1e25de032fc9e20499ca03a470f7
+Subproject commit 862b29cfa4e5faa4a581f0bc68d885c20da889dd
diff --git a/submodules/query-login b/submodules/query-login
index 98c8a2a..f8af245 160000
--- a/submodules/query-login
+++ b/submodules/query-login
@@ -1 +1 @@
-Subproject commit 98c8a2ad86331566058ca7cc12df5ee2b406fa2f
+Subproject commit f8af24506bdfdbd895be293c8fd8ce061c94e7af
diff --git a/submodules/store b/submodules/store
index 69784e8..d70118a 160000
--- a/submodules/store
+++ b/submodules/store
@@ -1 +1 @@
-Subproject commit 69784e8ed4f4546c91b2653adc75034e5946123c
+Subproject commit d70118ad3db513a4ae95a925f0dd651929a8f632
diff --git a/vite.config.ts b/vite.config.ts
index 0eb9f43..3a0a175 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -74,6 +74,10 @@ export default defineConfig({
port: 6020,
host: '0.0.0.0',
proxy: {
+ '/root/locales': {
+ target: 'https://kevisual.cn',
+ changeOrigin: true,
+ },
'/system/lib': {
target: 'https://kevisual.xiongxiao.me',
changeOrigin: true,
@@ -81,6 +85,7 @@ export default defineConfig({
'/api': {
target: 'http://localhost:4005',
changeOrigin: true,
+ ws: true,
rewrite: (path) => path.replace(/^\/api/, '/api'),
},
...proxy,