feat(M08-B): 补保洁员资料细节
This commit is contained in:
@@ -10,11 +10,13 @@ export interface ManagedUser {
|
||||
userType: string;
|
||||
status: string;
|
||||
nickname: string;
|
||||
avatarUrl: string;
|
||||
maskedPhone: string;
|
||||
maskedLastIp: string;
|
||||
note: string;
|
||||
roles: string[];
|
||||
storeIds: string[];
|
||||
wechatMiniappBound: boolean;
|
||||
registeredAt: Date;
|
||||
lastLoginAt: Date | null;
|
||||
}
|
||||
@@ -42,9 +44,11 @@ interface UserRow extends RowDataPacket {
|
||||
userType: string;
|
||||
status: string;
|
||||
nickname: string;
|
||||
avatarUrl: string;
|
||||
phone: string;
|
||||
lastIp: string | null;
|
||||
note: string;
|
||||
wechatMiniappBound: number;
|
||||
registeredAt: Date;
|
||||
lastLoginAt: Date | null;
|
||||
}
|
||||
@@ -99,9 +103,15 @@ export class UserManagementRepository {
|
||||
params
|
||||
);
|
||||
const [rows] = await this.pool.execute<UserRow[]>(
|
||||
`SELECT u.id, u.user_type AS userType, u.status, u.nickname, u.phone,
|
||||
`SELECT u.id, u.user_type AS userType, u.status, u.nickname,
|
||||
u.avatar_url AS avatarUrl, u.phone,
|
||||
u.created_at AS registeredAt, u.last_login_at AS lastLoginAt,
|
||||
COALESCE(p.note, '') AS note,
|
||||
EXISTS (
|
||||
SELECT 1 FROM qipai_user_identities i
|
||||
WHERE i.tenant_id = u.tenant_id AND i.user_id = u.id
|
||||
AND i.provider = 'WECHAT_MINIAPP' AND i.deleted_at IS NULL
|
||||
) AS wechatMiniappBound,
|
||||
(SELECT s.ip FROM qipai_auth_sessions s
|
||||
WHERE s.tenant_id = u.tenant_id AND s.user_id = u.id
|
||||
ORDER BY s.created_at DESC LIMIT 1) AS lastIp
|
||||
@@ -117,11 +127,13 @@ export class UserManagementRepository {
|
||||
userType: row.userType,
|
||||
status: row.status,
|
||||
nickname: row.nickname,
|
||||
avatarUrl: row.avatarUrl,
|
||||
maskedPhone: maskPhone(row.phone),
|
||||
maskedLastIp: maskIp(row.lastIp ?? ''),
|
||||
note: row.note,
|
||||
roles: await this.getCodes('role', input.actor.tenantId, String(row.id)),
|
||||
storeIds: await this.getCodes('store', input.actor.tenantId, String(row.id)),
|
||||
wechatMiniappBound: Boolean(row.wechatMiniappBound),
|
||||
registeredAt: row.registeredAt,
|
||||
lastLoginAt: row.lastLoginAt
|
||||
})));
|
||||
|
||||
@@ -50,6 +50,7 @@ const token = signAccessToken({
|
||||
}, secret, 900);
|
||||
let createdInput;
|
||||
let listedInput;
|
||||
let updatedInput;
|
||||
const app = await buildApp({
|
||||
userManagement: {
|
||||
jwtSecret: secret,
|
||||
@@ -81,7 +82,10 @@ const app = await buildApp({
|
||||
createdInput = input;
|
||||
return { userId: '22' };
|
||||
},
|
||||
async updateUser() { return { userId: '22' }; },
|
||||
async updateUser(_actor, _userId, input) {
|
||||
updatedInput = input;
|
||||
return { userId: '22' };
|
||||
},
|
||||
async resetSessions() { return { userId: '22', revokedSessions: 2 }; }
|
||||
}
|
||||
}
|
||||
@@ -111,6 +115,22 @@ assert.equal(listedInput.role, 'CLEANER');
|
||||
assert.equal(listedInput.status, 'ACTIVE');
|
||||
assert.equal(listedInput.search, '保洁');
|
||||
|
||||
const updated = await app.inject({
|
||||
method: 'PATCH',
|
||||
url: '/admin-api/users/22',
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
payload: {
|
||||
nickname: '保洁一号',
|
||||
phone: '13800138009',
|
||||
roles: ['CLEANER'],
|
||||
storeIds: ['11'],
|
||||
note: '夜班'
|
||||
}
|
||||
});
|
||||
assert.equal(updated.statusCode, 200);
|
||||
assert.equal(updatedInput.phone, '13800138009');
|
||||
assert.deepEqual(updatedInput.roles, ['CLEANER']);
|
||||
|
||||
const unauthenticated = await app.inject({ method: 'GET', url: '/admin-api/users' });
|
||||
assert.equal(unauthenticated.statusCode, 401);
|
||||
await app.close();
|
||||
|
||||
Reference in New Issue
Block a user