Skip to content

Commit

Permalink
feat: update customer service nickname & email
Browse files Browse the repository at this point in the history
  • Loading branch information
sdjdd committed Jan 22, 2024
1 parent fd29f05 commit 3cfad5d
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 17 deletions.
16 changes: 15 additions & 1 deletion next/api/src/controller/customer-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class FindCustomerServicePipe {
}
}

const roleSchema = z.union([z.literal('admin'), z.literal('customerService')]);
const roleSchema = z.enum(['admin', 'customerService']);
const rolesSchema = z.array(roleSchema).nonempty();

const createCustomerServiceSchema = z.object({
Expand All @@ -54,6 +54,8 @@ type AddCategoryData = z.infer<typeof addCategorySchema>;
const updateCustomerServiceSchema = z.object({
active: z.boolean().optional(),
roles: rolesSchema.optional(),
nickname: z.string().optional(),
email: z.string().optional(),
});
type UpdateCustomerServiceData = z.infer<typeof updateCustomerServiceSchema>;

Expand Down Expand Up @@ -133,6 +135,18 @@ export class CustomerServiceController {
processQueue.push(roleService.updateUserCSRoleTo(data.roles, user.id));
}

if (data.nickname || data.email) {
processQueue.push(
user.update(
{
name: data.nickname,
email: data.email,
},
{ useMasterKey: true }
)
);
}

await Promise.all(processQueue);

return {};
Expand Down
2 changes: 2 additions & 0 deletions next/api/src/controller/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ type AuthData = z.infer<typeof authSchema>;
const preCraeteSchema = z.object({
email: z.string().email().optional(),
username: z.string().optional(),
nickname: z.string().optional(),
});
type PreCreateUserData = z.infer<typeof preCraeteSchema>;

Expand Down Expand Up @@ -204,6 +205,7 @@ export class UserController {
{
// username might be `""`
username: username ? username : email,
name: data.nickname,
email,
password: Math.random().toString(),
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { forwardRef } from 'react';
import { Form, FormInstance, Input } from 'antd';

import { CSRole } from '@/api/customer-service';
import { RoleCheckboxGroup } from '@/App/Admin/components/RoleCheckboxGroup';

export interface CustomerServiceFormData {
nickname?: string;
email?: string;
roles?: CSRole[];
}

export interface CustomerServiceFormProps {
initData?: Partial<CustomerServiceFormData>;
onSubmit?: (data: CustomerServiceFormData) => void;
}

export const CustomerServiceForm = forwardRef<FormInstance, CustomerServiceFormProps>(
({ initData, onSubmit }, ref) => {
const handleSubmit = (data: CustomerServiceFormData) => {
onSubmit?.({
nickname: data.nickname || undefined,
email: data.email || undefined,
roles: data.roles || [],
});
};

return (
<Form ref={ref} layout="vertical" initialValues={initData} onFinish={handleSubmit}>
<Form.Item name="nickname" label="昵称">
<Input />
</Form.Item>
<Form.Item name="email" label="邮箱">
<Input />
</Form.Item>
<Form.Item
name="roles"
label="角色"
rules={[{ type: 'array', min: 1 }]}
style={{ marginBottom: 0 }}
>
<RoleCheckboxGroup />
</Form.Item>
</Form>
);
}
);
40 changes: 27 additions & 13 deletions next/web/src/App/Admin/Settings/Members/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,19 @@ import {
useDeleteCustomerService,
useUpdateCustomerService,
} from '@/api/customer-service';
import { Button, Modal, Popover, Table, message } from '@/components/antd';
import { Button, Modal, Popover, Table, message, FormInstance } from '@/components/antd';
import { Category, Retry, UserSelect } from '@/components/common';
import { UserLabel } from '@/App/Admin/components';
import { groupBy, sortBy } from 'lodash-es';
import { RoleCheckboxGroup } from '../../components/RoleCheckboxGroup';
import { CustomerServiceForm, CustomerServiceFormData } from './components/CustomerServiceForm';

function MemberActions({
id,
nickname,
active,
onEdit,
}: CustomerServiceSchema & { onEdit?: () => void }) {
}: Pick<CustomerServiceSchema, 'id' | 'nickname' | 'active'> & { onEdit?: () => void }) {
const queryClient = useQueryClient();

const { mutate: update, isLoading: isUpdating } = useUpdateCustomerService({
Expand Down Expand Up @@ -133,20 +134,20 @@ function AddUserModal({ visible, onHide }: AddUserModalProps) {
}

interface EditUserModalRef {
open: (id: string, roles: CSRole[]) => void;
open: (id: string, data: CustomerServiceFormData) => void;
}

const EditUserModal = forwardRef<EditUserModalRef>((_, ref) => {
const [userId, setUserId] = useState<string | undefined>();
const [roles, setRoles] = useState<CSRole[] | undefined>();
const [data, setData] = useState<CustomerServiceFormData>();
const [visible, setVisible] = useState(false);

const queryClient = useQueryClient();

useImperativeHandle(ref, () => ({
open: (id, roles) => {
open: (id, data) => {
setUserId(id);
setRoles(roles);
setData(data);
setVisible(true);
},
}));
Expand All @@ -160,17 +161,24 @@ const EditUserModal = forwardRef<EditUserModalRef>((_, ref) => {
},
});

const formRef = useRef<FormInstance>(null);

return (
<Modal
visible={visible}
destroyOnClose
open={visible}
title="更新客服"
onOk={() => update({ id: userId!, roles })}
onOk={() => formRef.current?.submit()}
confirmLoading={isUpdating}
okButtonProps={{ disabled: isUpdating || !userId || roles?.length === 0 }}
okButtonProps={{ disabled: isUpdating || !userId }}
onCancel={() => setVisible(false)}
cancelButtonProps={{ disabled: isUpdating }}
>
<RoleCheckboxGroup value={roles} onChange={(v) => setRoles(v as CSRole[])} />
<CustomerServiceForm
ref={formRef}
initData={data}
onSubmit={(data) => update({ ...data, id: userId! })}
/>
</Modal>
);
});
Expand Down Expand Up @@ -280,11 +288,17 @@ export function Members() {
<Table.Column
key="actions"
title="操作"
render={(_, v: CustomerService) => (
render={(u: CustomerService) => (
<MemberActions
{...v}
id={u.id}
nickname={u.nickname}
active={u.active}
onEdit={() => {
editUserModalRef.current?.open(v.id, v.roles);
editUserModalRef.current?.open(u.id, {
nickname: u.nickname,
email: u.email,
roles: u.roles,
});
}}
/>
)}
Expand Down
14 changes: 12 additions & 2 deletions next/web/src/App/Admin/Settings/Users/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,27 @@ export function NewUser() {
control={control}
name="username"
render={({ field }) => (
<Form.Item label="Username" htmlFor="username">
<Form.Item label="用户名" htmlFor="username">
<Input {...field} autoFocus id="username" />
</Form.Item>
)}
/>

<Controller
control={control}
name="nickname"
render={({ field }) => (
<Form.Item label="昵称" htmlFor="nickname">
<Input {...field} autoFocus id="nickname" />
</Form.Item>
)}
/>

<Controller
control={control}
name="email"
render={({ field }) => (
<Form.Item label="Email" htmlFor="email">
<Form.Item label="邮箱" htmlFor="email">
<Input type="email" {...field} id="email" />
</Form.Item>
)}
Expand Down
4 changes: 3 additions & 1 deletion next/web/src/api/customer-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,11 @@ async function addCustomerService(data: AddCustomerServiceData) {
}

export interface UpdateCustomerServiceData {
id: string;
active?: boolean;
roles?: CSRole[];
id: string;
nickname?: string;
email?: string;
}

async function updateCustomerService({ id, ...data }: UpdateCustomerServiceData) {
Expand Down
1 change: 1 addition & 0 deletions next/web/src/api/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export const useUser = (id: string, options?: UseQueryOptions<UserSchema, Error>

export interface CreateUserData {
username?: string;
nickname?: string;
email?: string;
}

Expand Down

0 comments on commit 3cfad5d

Please sign in to comment.