851 lines
26 KiB
JavaScript
851 lines
26 KiB
JavaScript
const jwt = require("jsonwebtoken");
|
||
const { ObjectId } = require("mongodb");
|
||
const utils = require("./account-utils.js");
|
||
const api = require("../../api");
|
||
const jwtUtils = require("../../utils/jwt-utils");
|
||
const tokenStore = require("../../middleware/useTokenStore");
|
||
const SECRET_KEY = process.env.CONFIG_JWT_SECRET_KEY || "YOUCAN365";
|
||
const TOKEN_EXPIRES = process.env.CONFIG_JWT_EXPIRE_TIME || "1d";
|
||
|
||
|
||
let db = null;
|
||
// 自定义默认密码
|
||
const defaultPassword = "zytzyy6789";
|
||
exports.main = async (event, mongodb, req) => {
|
||
db = mongodb;
|
||
switch (event.type) {
|
||
case "updatePassword":
|
||
return await exports.updatePassword(event);
|
||
case "login":
|
||
return await exports.login(event, req);
|
||
case "simpleLogin":
|
||
return await exports.simpleLogin(event);
|
||
case "loginout":
|
||
return await loginout(event, req);
|
||
case "loginWithToken":
|
||
return await exports.loginWithToken(event);
|
||
case "refreshToken":
|
||
return await refreshToken(event);
|
||
case "getLoginLog":
|
||
return await getLoginLog(event);
|
||
case "resetPassword":
|
||
return await resetPassword(event);
|
||
case "getAccountList":
|
||
return await getAccountList(event);
|
||
case "getAccountOptions":
|
||
return await getAccountOptions(event);
|
||
case "setAccountState":
|
||
return await setAccountState(event);
|
||
case "addCorpAccount":
|
||
return await addCorpAccount(event);
|
||
case "editCorpAccount":
|
||
return await editCorpAccount(event);
|
||
case "updateAccountDrugStoreId":
|
||
return updateAccountDrugStoreId(event);
|
||
}
|
||
};
|
||
|
||
function getIp(req) {
|
||
return req.headers['x-forwarded-for'] ||
|
||
req.headers['x-real-ip'] ||
|
||
req.connection.remoteAddress ||
|
||
req.socket.remoteAddress ||
|
||
req.connection.socket.remoteAddress ||
|
||
'';
|
||
}
|
||
|
||
// 修改密码
|
||
exports.updatePassword = async (event) => {
|
||
const { corpId, username, oldPassword, newPassword } = event;
|
||
try {
|
||
// 查询员工账户里的account是否存在
|
||
const user = await db.collection("corp-member").findOne(
|
||
{ corpId, mobile: username } // 查询条件
|
||
);
|
||
// 如果不存在,则提示账户不存在
|
||
if (!user) {
|
||
return {
|
||
success: false,
|
||
message: "账户不存在",
|
||
};
|
||
}
|
||
const { password = "" } = user || {};
|
||
if (
|
||
(password && password !== oldPassword) ||
|
||
(!password && oldPassword !== defaultPassword)
|
||
) {
|
||
return {
|
||
success: false,
|
||
message: "原密码错误",
|
||
};
|
||
}
|
||
// 更新密码
|
||
await db.collection("corp-member").updateOne(
|
||
{ corpId, mobile: username }, // 查询条件
|
||
{ $set: { password: newPassword, updateTime: Date.now() } } // 更新内容
|
||
);
|
||
return {
|
||
success: true,
|
||
message: "更新成功",
|
||
};
|
||
} catch (error) {
|
||
return {
|
||
success: false,
|
||
message: error.message,
|
||
};
|
||
}
|
||
};
|
||
|
||
exports.simpleLogin = async (event) => {
|
||
const { corpId, username, password, fetchPharmacy } = event;
|
||
const platform = typeof event.platform === 'string' ? event.platform.trim().toUpperCase() : '';
|
||
|
||
if (typeof corpId !== 'string' || corpId.trim() === '') {
|
||
return { success: false, message: "机构ID不能为空" };
|
||
}
|
||
if (typeof username !== 'string' || username.trim() === '') {
|
||
return { success: false, message: "账号不能为空" };
|
||
}
|
||
if (typeof password !== 'string' || password.trim() === '') {
|
||
return { success: false, message: "密码不能为空" };
|
||
}
|
||
|
||
try {
|
||
const user = await db.collection("corp-member").findOne({ corpId, mobile: username });
|
||
if (!user) {
|
||
return { success: false, message: "账户不存在或者密码不正确" };
|
||
}
|
||
if (user.accountState !== "enable") {
|
||
return { success: false, message: "账户未启用,请联系管理员" };
|
||
}
|
||
|
||
const { password: dbPassword = "" } = user || {};
|
||
if (!dbPassword) {
|
||
if (password === defaultPassword) {
|
||
return { success: false, message: "密码未设置" };
|
||
}
|
||
return { success: false, message: "默认密码不正确" };
|
||
}
|
||
|
||
if (password !== dbPassword) {
|
||
return { success: false, message: "账户不存在或者密码不正确" };
|
||
}
|
||
|
||
if (fetchPharmacy && typeof user.drugStoreId === 'string' && user.drugStoreId.trim()) {
|
||
const api = require("../../api");
|
||
const res = await api.getInternetHospitalApi({
|
||
type: "getDrugStoreList",
|
||
storeId: user.drugStoreId,
|
||
pageSize: 1,
|
||
});
|
||
const drugStore = Array.isArray(res.list) && res.list[0] ? res.list[0] : null;
|
||
user.drugStore = drugStore;
|
||
}
|
||
|
||
const { password: _password, ...data } = user;
|
||
const loginId = new ObjectId().toString();
|
||
|
||
return {
|
||
success: true,
|
||
message: "登录成功",
|
||
user: { ...data, loginId },
|
||
};
|
||
} catch (error) {
|
||
return { success: false, message: error.message };
|
||
}
|
||
};
|
||
|
||
// 登陆账号
|
||
exports.login = async (event, req) => {
|
||
const { corpId, username, password, fetchPharmacy } = event;
|
||
// 规范 platform:去空格并转为大写,方便后续判断(例如 'pc' / 'PC' / ' Pc ' 都视为 PC)
|
||
const platform = typeof event.platform === 'string' ? event.platform.trim().toUpperCase() : '';
|
||
try {
|
||
// 查询员工账户里的account是否存在
|
||
const user = await db.collection("corp-member").findOne(
|
||
{ corpId, mobile: username } // 查询条件
|
||
);
|
||
// 如果不存在,则提示账户不存在
|
||
if (!user) {
|
||
return {
|
||
success: false,
|
||
message: "账户不存在或者密码不正确",
|
||
};
|
||
}
|
||
if (user.accountState !== "enable") {
|
||
return { success: false, message: "账户未启用,请联系管理员" };
|
||
}
|
||
const { password: dbPassword = "" } = user || {};
|
||
if (!dbPassword) {
|
||
if (password === defaultPassword) {
|
||
return {
|
||
success: false,
|
||
message: "密码未设置",
|
||
};
|
||
} else {
|
||
return {
|
||
success: false,
|
||
message: "默认密码不正确",
|
||
};
|
||
}
|
||
}
|
||
if (password !== dbPassword) {
|
||
return {
|
||
success: false,
|
||
message: "账户不存在或者密码不正确",
|
||
};
|
||
}
|
||
|
||
|
||
if (fetchPharmacy && typeof user.drugStoreId === 'string' && user.drugStoreId.trim()) {
|
||
const api = require("../../api");
|
||
const res = await api.getInternetHospitalApi({
|
||
type: "getDrugStoreList",
|
||
storeId: user.drugStoreId,
|
||
pageSize: 1,
|
||
});
|
||
const drugStore =
|
||
Array.isArray(res.list) && res.list[0] ? res.list[0] : null;
|
||
user.drugStore = drugStore;
|
||
}
|
||
|
||
const { password: _password, ...data } = user;
|
||
const loginId = new ObjectId().toString();
|
||
|
||
// 使用统一的 JWT 工具生成 token
|
||
const tokens = jwtUtils.generateTokens({
|
||
userId: user._id.toString(),
|
||
platform: platform,
|
||
username: user.mobile,
|
||
corpId: corpId,
|
||
role: user.roleIds || [],
|
||
mobile: user.mobile,
|
||
drugStoreId: user.drugStoreId || '',
|
||
loginId: loginId
|
||
});
|
||
|
||
await addLoginLog(data, loginId, platform, getIp(req), tokens.accessToken);
|
||
|
||
return {
|
||
success: true,
|
||
message: "登录成功",
|
||
user: { ...data, loginId },
|
||
accessToken: tokens.accessToken,
|
||
refreshToken: tokens.refreshToken,
|
||
expiresIn: tokens.expiresIn,
|
||
tokenType: "Bearer",
|
||
// 保持向后兼容,同时提供旧的 token 字段
|
||
token: tokens.accessToken
|
||
};
|
||
} catch (error) {
|
||
return {
|
||
success: false,
|
||
message: error.message,
|
||
};
|
||
}
|
||
};
|
||
|
||
exports.loginWithToken = async function (ctx) {
|
||
const { token, corpId: reqCorpId } = ctx;
|
||
if (typeof token !== "string" || token.trim() === "") {
|
||
return { success: false, message: "token无效" };
|
||
}
|
||
|
||
// 先尝试使用统一的 JWT 验证
|
||
let user = await getUserFromToken(token);
|
||
|
||
// 如果统一验证失败,尝试使用旧的验证方式(向后兼容)
|
||
if (!user) {
|
||
user = await getUserFromTokenLegacy(token);
|
||
}
|
||
|
||
if (!user) {
|
||
return { success: false, message: "登录已失效,请重新登录" };
|
||
}
|
||
|
||
// 支持两种数据结构:新的 userId/username 和旧的 mobile
|
||
const mobile = user.username || user.mobile;
|
||
const userId = user.userId;
|
||
const drugStoreId = user.drugStoreId;
|
||
const corpId = user.corpId;
|
||
|
||
if (!mobile || reqCorpId !== corpId) {
|
||
return { success: false, message: "登录已失效,请重新登录" };
|
||
}
|
||
|
||
// 构建查询条件
|
||
const query = { corpId, mobile };
|
||
if (drugStoreId) {
|
||
query.drugStoreId = drugStoreId;
|
||
}
|
||
|
||
const account = await db.collection("corp-member").findOne(query);
|
||
|
||
if (!account) {
|
||
return { success: false, message: "登录已失效,请重新登录" };
|
||
}
|
||
|
||
if (account.accountState !== "enable") {
|
||
return { success: false, message: "账户未启用,请联系管理员" };
|
||
}
|
||
|
||
// 获取药店信息
|
||
if (drugStoreId) {
|
||
const api = require("../../api");
|
||
const res = await api.getInternetHospitalApi({
|
||
type: "getDrugStoreList",
|
||
storeId: drugStoreId,
|
||
pageSize: 1,
|
||
});
|
||
const drugStore =
|
||
Array.isArray(res.list) && res.list[0] ? res.list[0] : null;
|
||
account.drugStore = drugStore;
|
||
}
|
||
|
||
return { success: true, user: account, message: "登录成功" };
|
||
};
|
||
|
||
async function loginout(ctx) {
|
||
try {
|
||
const query = {
|
||
corpId: typeof ctx.corpId === "string" ? ctx.corpId.trim() : "",
|
||
loginId: typeof ctx.loginId === "string" ? ctx.loginId.trim() : "",
|
||
userId: typeof ctx.userId === "string" ? ctx.userId.trim() : "",
|
||
type: { $in: ["login", "loginout"] },
|
||
};
|
||
const list = await db.collection("login-log").find(query).toArray();
|
||
const login = list.find((item) => item.type === "login");
|
||
const logout = list.find((item) => item.type === "loginout");
|
||
if (login && !logout) {
|
||
const { _id, ...rest } = login;
|
||
await db
|
||
.collection("login-log")
|
||
.insertOne({ ...rest, type: "loginout", createTime: Date.now() });
|
||
}
|
||
return { success: true, message: "登出成功" };
|
||
} catch (e) {
|
||
return { success: false, message: e.message };
|
||
}
|
||
}
|
||
|
||
// 使用统一的 JWT 验证(新)
|
||
function getUserFromToken(token) {
|
||
return new Promise((resolve) => {
|
||
const secret = process.env.JWT_SECRET || 'your-secret-key';
|
||
jwt.verify(token, secret, (err, user) => {
|
||
if (err) return resolve(null);
|
||
resolve(user);
|
||
});
|
||
});
|
||
}
|
||
|
||
// 使用旧的 JWT 验证(向后兼容)
|
||
function getUserFromTokenLegacy(token) {
|
||
return new Promise((resolve) => {
|
||
jwt.verify(token, SECRET_KEY, (err, user) => {
|
||
if (err) return resolve(null);
|
||
resolve(user);
|
||
});
|
||
});
|
||
}
|
||
|
||
// Token 刷新功能
|
||
async function refreshToken(ctx) {
|
||
const { refreshToken } = ctx;
|
||
|
||
if (!refreshToken) {
|
||
return {
|
||
success: false,
|
||
message: '刷新令牌不能为空'
|
||
};
|
||
}
|
||
|
||
const result = jwtUtils.refreshAccessToken(refreshToken);
|
||
|
||
return {
|
||
success: true,
|
||
message: 'Token 刷新成功',
|
||
accessToken: result.accessToken,
|
||
expiresIn: result.expiresIn,
|
||
tokenType: 'Bearer'
|
||
};
|
||
}
|
||
|
||
async function getLoginLog(ctx) {
|
||
const { corpId, accountId, userId } = ctx;
|
||
try {
|
||
if (corpId && typeof corpId !== "string") {
|
||
return { success: false, message: "机构id无效" };
|
||
}
|
||
if (accountId && typeof accountId !== "string") {
|
||
return { success: false, message: "账号id无效" };
|
||
}
|
||
if (userId && typeof userId !== "string") {
|
||
return { success: false, message: "用户id无效" };
|
||
}
|
||
const query = {
|
||
corpId,
|
||
accountId,
|
||
userId,
|
||
};
|
||
const page = Number.isInteger(ctx.page) && ctx.page > 0 ? ctx.page : 1;
|
||
const pageSize =
|
||
Number.isInteger(ctx.pageSize) && ctx.pageSize > 0 ? ctx.pageSize : 10;
|
||
const total = await db.collection("login-log").countDocuments(query);
|
||
const list = await db
|
||
.collection("login-log")
|
||
.find(query)
|
||
.skip(page * pageSize - pageSize)
|
||
.limit(pageSize)
|
||
.sort({ createTime: -1 })
|
||
.toArray();
|
||
return { success: true, data: list, message: "获取登录日志成功", total };
|
||
} catch (e) {
|
||
return { success: false, message: e.message };
|
||
}
|
||
}
|
||
|
||
async function addLoginLog(ctx, loginId, platform, ip, token) {
|
||
const { corpId, _id, userid: userId } = ctx;
|
||
try {
|
||
const { insertedId } = await db
|
||
.collection("login-log")
|
||
.insertOne({
|
||
corpId,
|
||
accountId: _id.toString(),
|
||
userId,
|
||
createTime: Date.now(),
|
||
loginId,
|
||
type: "login",
|
||
ip: typeof ip === "string" ? ip.trim() : "",
|
||
platform: ["PC", "MATEPAD"].includes(platform) ? platform : "",
|
||
token
|
||
});
|
||
if (insertedId) {
|
||
tokenStore.setToken(_id.toString(), token);
|
||
}
|
||
return { success: true, message: "添加登录日志成功" };
|
||
} catch (e) {
|
||
console.log('addLoginLog error:', e)
|
||
return { success: false, message: e.message };
|
||
}
|
||
}
|
||
|
||
async function resetPassword(ctx) {
|
||
// const { corpId, userId, accountId } = ctx;
|
||
const corpId = typeof ctx.corpId === "string" ? ctx.corpId.trim() : "";
|
||
const userId = typeof ctx.userId === "string" ? ctx.userId.trim() : "";
|
||
const accountId =
|
||
typeof ctx.accountId === "string" ? ctx.accountId.trim() : "";
|
||
if (!corpId || !userId || !accountId) {
|
||
return { success: false, message: "参数错误,缺少必要的参数" };
|
||
}
|
||
try {
|
||
const query = { corpId, userid: userId };
|
||
if (ObjectId.isValid(accountId)) {
|
||
query["$or"] = [{ _id: new ObjectId(accountId) }, { _id: accountId }];
|
||
} else {
|
||
query._id = accountId; // 如果不是ObjectId,则直接使用accountId
|
||
}
|
||
const res = await db
|
||
.collection("corp-member")
|
||
.updateOne(query, {
|
||
$set: { password: defaultPassword, updateTime: Date.now() },
|
||
});
|
||
if (res.modifiedCount === 1) {
|
||
return {
|
||
success: true,
|
||
message: "重置密码成功",
|
||
password: defaultPassword,
|
||
};
|
||
}
|
||
return {
|
||
success: false,
|
||
message: "重置密码失败",
|
||
};
|
||
} catch (error) {
|
||
return {
|
||
success: false,
|
||
message: error.message,
|
||
};
|
||
}
|
||
}
|
||
|
||
async function addCorpAccount(ctx) {
|
||
try {
|
||
const { success, message, data } = utils.getAccountData(ctx);
|
||
if (!success) {
|
||
return { success, message };
|
||
}
|
||
|
||
const { relatedHlwPeople, ...accountData } = data;
|
||
if (/\W/.test(accountData.mobile)) {
|
||
return { success: false, message: "登录账号不能包含特殊字符" };
|
||
}
|
||
|
||
// 校验 phone 字段是否存在
|
||
if (!accountData.phone || typeof accountData.phone !== 'string' || accountData.phone.trim() === '') {
|
||
return { success: false, message: "手机号不能为空" };
|
||
}
|
||
|
||
const sameMobile = { corpId: data.corpId, mobile: data.mobile }; // 账号相同
|
||
const samePhone = { corpId: data.corpId, phone: data.phone }; // 手机号相同
|
||
const sameRelatedPeople = relatedHlwPeople
|
||
? [{ corpId: data.corpId, relatedHlwPeople }]
|
||
: []; // 关联人员相同
|
||
const account = await db
|
||
.collection("corp-member")
|
||
.findOne(
|
||
{ $or: [sameMobile, samePhone, ...sameRelatedPeople] },
|
||
{ projection: { mobile: 1, phone: 1, relatedHlwPeople: 1 } }
|
||
);
|
||
if (account && account.mobile === data.mobile) {
|
||
return { success: false, message: "该账号已存在" };
|
||
} else if (account && account.phone === data.phone) {
|
||
return { success: false, message: "该手机号已被使用" };
|
||
} else if (account) {
|
||
return { success: false, message: "该人员已关联其他账号" };
|
||
}
|
||
if (
|
||
typeof relatedHlwPeople === "string" &&
|
||
relatedHlwPeople.trim() !== ""
|
||
) {
|
||
const { success, message, data } = await api.getInternetHospitalApi({
|
||
type: "getHlwPersonList",
|
||
page: 1,
|
||
pageSize: 1,
|
||
doctorNo: relatedHlwPeople,
|
||
});
|
||
const doctor = Array.isArray(data) && data[0] ? data[0] : null;
|
||
if (!success || !doctor) {
|
||
return {
|
||
success: false,
|
||
message: message || "关联人员信息不正确或者不存在",
|
||
};
|
||
}
|
||
if (["doctor", "pharmacist"].includes(doctor.job)) {
|
||
accountData[doctor.job === "doctor" ? "doctorNo" : "workNo"] =
|
||
doctor.doctorNo;
|
||
}
|
||
}
|
||
const res = await db.collection("corp-member").insertOne({
|
||
...accountData,
|
||
relatedHlwPeople,
|
||
password: defaultPassword,
|
||
createTime: Date.now(),
|
||
accountState: "enable",
|
||
});
|
||
return { success: true, message: "新增账户成功", id: res.insertedId };
|
||
} catch (e) {
|
||
return { success: false, message: e.message || "新增账户失败" };
|
||
}
|
||
}
|
||
|
||
async function editCorpAccount(ctx) {
|
||
if (typeof ctx.id !== "string" || ctx.id.trim() === "") {
|
||
return { success: false, message: "账号id无效" };
|
||
}
|
||
try {
|
||
const { success, message, data } = utils.getAccountData(ctx, false);
|
||
if (!success) {
|
||
return { success, message };
|
||
}
|
||
if (JSON.stringify(data) === "{}") {
|
||
return { success: true, message: "没有需要更新的字段" };
|
||
}
|
||
const record = await db.collection("corp-member").findOne(
|
||
{
|
||
$or: [
|
||
{
|
||
corpId: typeof ctx.corpId == "string" ? ctx.corpId : "",
|
||
_id: ObjectId.isValid(ctx.id) ? new ObjectId(ctx.id) : ctx.id,
|
||
},
|
||
{
|
||
corpId: typeof ctx.corpId == "string" ? ctx.corpId : "",
|
||
_id: ctx.id,
|
||
},
|
||
],
|
||
},
|
||
{ projection: { _id: 1, mobile: 1, phone: 1, doctorNo: 1, workNo: 1, corpId: 1 } }
|
||
);
|
||
if (!record) {
|
||
return { success: false, message: "账号不存在" };
|
||
}
|
||
const { relatedHlwPeople, mobile, userid, ...accountData } = data;
|
||
if (/\W/.test(accountData.mobile)) {
|
||
return { success: false, message: "登录账号不能包含特殊字符" };
|
||
}
|
||
if (
|
||
record.mobile &&
|
||
accountData.mobile &&
|
||
accountData.mobile !== record.mobile
|
||
) {
|
||
return { success: false, message: "登录账号不能修改" };
|
||
}
|
||
|
||
const sameMobile = { corpId: data.corpId, mobile: data.mobile }; // 账号相同
|
||
const samePhone = accountData.phone ? { corpId: data.corpId, phone: accountData.phone } : null; // 手机号相同
|
||
const sameRelatedPeople =
|
||
typeof relatedHlwPeople == "string" && relatedHlwPeople
|
||
? [{ corpId: data.corpId, relatedHlwPeople }]
|
||
: []; // 关联人员相同
|
||
|
||
const queryConditions = [sameMobile, ...sameRelatedPeople];
|
||
if (samePhone) {
|
||
queryConditions.push(samePhone);
|
||
}
|
||
|
||
const account = await db.collection("corp-member").findOne(
|
||
{ $or: queryConditions, _id: { $ne: record._id } }, // 排除当前账号
|
||
{ projection: { mobile: 1, phone: 1, doctorNo: 1, workNo: 1 } }
|
||
);
|
||
if (account && account.mobile === data.mobile) {
|
||
return { success: false, message: "该账号已存在" };
|
||
} else if (account && accountData.phone && account.phone === accountData.phone) {
|
||
return { success: false, message: "该手机号已被使用" };
|
||
} else if (account) {
|
||
return { success: false, message: "该人员已关联其他账号" };
|
||
}
|
||
if (
|
||
typeof relatedHlwPeople === "string" &&
|
||
relatedHlwPeople.trim() !== ""
|
||
) {
|
||
const { success, message, data } = await api.getInternetHospitalApi({
|
||
type: "getHlwPersonList",
|
||
corpId: record.corpId,
|
||
page: 1,
|
||
pageSize: 1,
|
||
doctorNo: relatedHlwPeople,
|
||
});
|
||
const doctor = Array.isArray(data) && data[0] ? data[0] : null;
|
||
if (!success || !doctor) {
|
||
return {
|
||
success: false,
|
||
message: message || "关联人员信息不正确或者不存在",
|
||
};
|
||
}
|
||
if (record.doctorNo) {
|
||
accountData.doctorNo = "";
|
||
}
|
||
if (record.workNo) {
|
||
accountData.workNo = "";
|
||
}
|
||
if (["doctor", "pharmacist"].includes(doctor.job)) {
|
||
accountData[doctor.job === "doctor" ? "doctorNo" : "workNo"] =
|
||
doctor.doctorNo;
|
||
}
|
||
accountData.relatedHlwPeople = relatedHlwPeople;
|
||
} else if (relatedHlwPeople === "") {
|
||
if (record.doctorNo) {
|
||
accountData.doctorNo = "";
|
||
}
|
||
if (record.workNo) {
|
||
accountData.workNo = "";
|
||
}
|
||
accountData.relatedHlwPeople = "";
|
||
}
|
||
const res = await db
|
||
.collection("corp-member")
|
||
.updateOne({ _id: record._id }, { $set: accountData });
|
||
if (res.matchedCount === 0) {
|
||
return { success: false, message: "修改账户失败" };
|
||
}
|
||
return { success: true, message: "修改账户成功" };
|
||
} catch (e) {
|
||
return { success: false, message: e.message || "修改账户失败" };
|
||
}
|
||
}
|
||
|
||
async function getAccountList(ctx) {
|
||
const page = Number.isInteger(ctx.page) ? ctx.page : 1;
|
||
const pageSize = Number.isInteger(ctx.pageSize) ? ctx.pageSize : 10;
|
||
try {
|
||
const query = { corpId: typeof ctx.corpId === "string" ? ctx.corpId : "" };
|
||
if (typeof ctx.roleId === "string" && ctx.roleId.trim() !== "") {
|
||
query["roleIds"] = { $in: [ctx.roleId] };
|
||
}
|
||
if (typeof ctx.name === "string" && ctx.name.trim() !== "") {
|
||
query["anotherName"] = { $regex: ctx.name, $options: "i" };
|
||
}
|
||
if (typeof ctx.mobile === "string" && ctx.mobile.trim() !== "") {
|
||
query["mobile"] = { $regex: ctx.mobile.trim(), $options: "i" };
|
||
}
|
||
if (typeof ctx.accountState === "boolean") {
|
||
query["accountState"] = ctx.accountState ? "enable" : "disable";
|
||
}
|
||
const list = await db
|
||
.collection("corp-member")
|
||
.aggregate([
|
||
{ $match: query },
|
||
{ $sort: { createTime: -1, _id: -1 } },
|
||
{
|
||
$lookup: {
|
||
from: "sys-role",
|
||
localField: "roleIds",
|
||
foreignField: "_id",
|
||
pipeline: [{ $project: { roleName: 1, _id: 0 } }],
|
||
as: "roles",
|
||
},
|
||
},
|
||
{
|
||
$lookup: {
|
||
from: "login-log",
|
||
let: { accountId: { $toString: "$_id" } },
|
||
pipeline: [
|
||
{
|
||
$match: {
|
||
$expr: { $eq: ["$accountId", "$$accountId"] },
|
||
type: "login",
|
||
},
|
||
},
|
||
{ $sort: { createTime: -1 } },
|
||
{ $limit: 1 },
|
||
{ $project: { _id: 0, createTime: 1, ip: 1 } },
|
||
],
|
||
as: "lastLogin",
|
||
},
|
||
},
|
||
{
|
||
$project: {
|
||
_id: 1,
|
||
anotherName: 1,
|
||
mobile: 1,
|
||
phone: 1,
|
||
accountState: 1,
|
||
roles: 1,
|
||
roleIds: 1,
|
||
lastLogin: 1,
|
||
userid: 1,
|
||
doctorNo: 1,
|
||
workNo: 1,
|
||
relatedHlwPeople: 1,
|
||
},
|
||
},
|
||
{ $skip: (page - 1) * pageSize },
|
||
{ $limit: pageSize },
|
||
])
|
||
.toArray();
|
||
const total = await db.collection("corp-member").countDocuments(query);
|
||
return { success: true, message: "获取成功", list, total };
|
||
} catch (e) {
|
||
return { success: false, message: e.message || "获取失败" };
|
||
}
|
||
}
|
||
|
||
async function setAccountState(ctx) {
|
||
const { corpId, accountIds, state } = ctx;
|
||
const accountIdList = Array.isArray(accountIds)
|
||
? accountIds.filter((i) => typeof i === "string")
|
||
: [];
|
||
try {
|
||
const ids = [];
|
||
for (const id of accountIdList) {
|
||
if (ObjectId.isValid(id)) {
|
||
ids.push(new ObjectId(id), id);
|
||
} else if (typeof id === "string" && id.trim() !== "") {
|
||
ids.push(id.trim());
|
||
}
|
||
}
|
||
if (typeof state !== "boolean") {
|
||
return { success: false, message: "参数错误" };
|
||
}
|
||
const res = await db
|
||
.collection("corp-member")
|
||
.updateMany(
|
||
{ _id: { $in: ids }, corpId: typeof corpId === "string" ? corpId : "" },
|
||
{ $set: { accountState: state ? "enable" : "disable" } }
|
||
);
|
||
return { success: true, message: "设置成功", data: res };
|
||
} catch (e) {
|
||
return { success: false, message: e.message || "设置失败" };
|
||
}
|
||
}
|
||
|
||
async function getAccountOptions(ctx) {
|
||
try {
|
||
const query = { corpId: typeof ctx.corpId === "string" ? ctx.corpId : "" };
|
||
const list = await db
|
||
.collection("corp-member")
|
||
.find(query, { projection: { anotherName: 1, _id: 1 } })
|
||
.toArray();
|
||
return { success: true, message: "获取成功", list };
|
||
} catch (e) {
|
||
return { success: false, message: e.message || "获取失败" };
|
||
}
|
||
}
|
||
|
||
async function updateAccountDrugStoreId(ctx) {
|
||
const corpId = typeof ctx.corpId === "string" ? ctx.corpId.trim() : "";
|
||
const drugStoreId =
|
||
typeof ctx.drugStoreId === "string" ? ctx.drugStoreId.trim() : "";
|
||
const oldDrugStoreId =
|
||
typeof ctx.oldDrugStoreId === "string" ? ctx.oldDrugStoreId.trim() : "";
|
||
const accountId =
|
||
typeof ctx.accountId === "string" ? ctx.accountId.trim() : "";
|
||
const oldAccountId =
|
||
typeof ctx.oldAccountId === "string" ? ctx.oldAccountId.trim() : "";
|
||
|
||
try {
|
||
let account = null;
|
||
let oldAccount = null;
|
||
if (accountId) {
|
||
const query = ObjectId.isValid(accountId)
|
||
? {
|
||
$or: [
|
||
{ corpId, _id: new ObjectId(accountId) },
|
||
{ corpId, _id: accountId },
|
||
],
|
||
}
|
||
: { corpId, _id: accountId };
|
||
account = await db.collection("corp-member").findOne(query, { _id: 1 });
|
||
if (!account) {
|
||
return { success: false, message: "关联账号不存在" };
|
||
}
|
||
}
|
||
if (oldAccountId) {
|
||
const oldQuery = ObjectId.isValid(oldAccountId)
|
||
? {
|
||
$or: [
|
||
{ corpId, _id: new ObjectId(oldAccountId) },
|
||
{ corpId, _id: oldAccountId },
|
||
],
|
||
}
|
||
: { corpId, _id: oldAccountId };
|
||
oldAccount = await db
|
||
.collection("corp-member")
|
||
.findOne(oldQuery, { _id: 1 });
|
||
}
|
||
if (oldAccount) {
|
||
await db
|
||
.collection("corp-member")
|
||
.updateMany({ _id: oldAccount._id }, { $set: { drugStoreId: "" } });
|
||
}
|
||
if (oldDrugStoreId && account) {
|
||
await db
|
||
.collection("corp-member")
|
||
.updateMany(
|
||
{ corpId, drugStoreId: oldDrugStoreId, _id: { $ne: account._id } },
|
||
{ $set: { drugStoreId: "" } }
|
||
);
|
||
await db
|
||
.collection("corp-member")
|
||
.updateMany({ _id: account._id }, { $set: { drugStoreId } });
|
||
} else if (oldDrugStoreId) {
|
||
await db
|
||
.collection("corp-member")
|
||
.updateMany(
|
||
{ corpId, drugStoreId: oldDrugStoreId },
|
||
{ $set: { drugStoreId } }
|
||
);
|
||
} else if (account) {
|
||
await db
|
||
.collection("corp-member")
|
||
.updateMany({ _id: account._id }, { $set: { drugStoreId } });
|
||
}
|
||
|
||
return { success: true, message: "更新成功" };
|
||
} catch (e) {
|
||
return { success: false, message: e.message || "更新失败" };
|
||
}
|
||
}
|