410 lines
16 KiB
JavaScript
410 lines
16 KiB
JavaScript
import { groupBy, isEqual, uniq } from "oak-domain/lib/utils/lodash";
|
|
import { generateNewId, generateNewIdAsync } from "oak-domain/lib/utils/uuid";
|
|
export default OakComponent({
|
|
entity: 'applicationPassport',
|
|
isList: true,
|
|
projection: {
|
|
id: 1,
|
|
applicationId: 1,
|
|
application: {
|
|
id: 1,
|
|
name: 1,
|
|
type: 1,
|
|
systemId: 1,
|
|
},
|
|
passportId: 1,
|
|
passport: {
|
|
id: 1,
|
|
type: 1,
|
|
systemId: 1,
|
|
enabled: 1,
|
|
},
|
|
isDefault: 1,
|
|
allowPwd: 1,
|
|
},
|
|
properties: {
|
|
systemId: '',
|
|
},
|
|
filters: [
|
|
{
|
|
filter() {
|
|
const { systemId } = this.props;
|
|
return {
|
|
application: {
|
|
systemId,
|
|
},
|
|
passport: {
|
|
systemId,
|
|
type: {
|
|
$ne: 'password'
|
|
}
|
|
},
|
|
};
|
|
}
|
|
}
|
|
],
|
|
formData({ data }) {
|
|
const aps = data.filter((ele) => ele.$$deleteAt$$ !== 1);
|
|
return {
|
|
aps,
|
|
};
|
|
},
|
|
listeners: {
|
|
async 'aps,applications,passports'(prev, next) {
|
|
if (!this.arraysAreEqual(prev.aps, next.aps) || !this.arraysAreEqual(prev.applications, next.applications) || !this.arraysAreEqual(prev.passports, next.passports)) {
|
|
let apArray = [];
|
|
const records = groupBy(next.passports, 'type');
|
|
if (next.applications && next.applications.length > 0 && next.passports && next.passports.length > 0) {
|
|
for (const a of next.applications) {
|
|
let item = {
|
|
aId: a.id,
|
|
aName: a.name,
|
|
typeRecords: {},
|
|
defaultOptions: [],
|
|
defaultValue: '',
|
|
};
|
|
let typeRecords = {};
|
|
for (const key of Object.keys(records)) {
|
|
const r = records[key];
|
|
const render = this.getRender(key, r, a.type);
|
|
if (render === 'select') {
|
|
const passportOptions = r.map((ele) => {
|
|
const { disabled, disabledTip } = this.checkDisabled(a, ele);
|
|
return {
|
|
label: ele.type === 'email' ? ele.config.account : ele.config.appId,
|
|
value: ele.id,
|
|
apId: generateNewId(),
|
|
disabled,
|
|
disabledTip,
|
|
};
|
|
});
|
|
const d = !passportOptions.find((ele) => !ele.disabled);
|
|
let disabledTip = '';
|
|
if (d) {
|
|
disabledTip = '暂不支持该登录方式';
|
|
}
|
|
Object.assign(typeRecords, { [key]: { render, passportOptions, chekedValue: undefined, disabled: d, disabledTip } });
|
|
}
|
|
else {
|
|
const { disabled, disabledTip } = this.checkDisabled(a, r[0]);
|
|
const { showPwd, pwdDisabled, pwdDisabledTip } = this.checkPwd(r[0]);
|
|
const apId = await generateNewIdAsync();
|
|
Object.assign(typeRecords, { [key]: { render, pId: r[0].id, checked: false, disabled, disabledTip, apId, showPwd, allowPwd: undefined, pwdDisabled, pwdDisabledTip } });
|
|
}
|
|
}
|
|
Object.assign(item, { typeRecords });
|
|
apArray.push(item);
|
|
}
|
|
if (next.aps && next.aps.length > 0) {
|
|
for (const ap of next.aps) {
|
|
const aIdx = apArray.findIndex((ele) => ele.aId === ap.applicationId);
|
|
if (aIdx !== -1) {
|
|
const p = ap.passport;
|
|
const t = p.type;
|
|
if (apArray[aIdx].typeRecords[t].render === 'select') {
|
|
apArray[aIdx].typeRecords[t].checkedValue = p.id;
|
|
apArray[aIdx].typeRecords[t].apId = ap.id;
|
|
const option = apArray[aIdx].typeRecords[t].passportOptions?.find((ele) => ele.value === p.id);
|
|
option && Object.assign(option, { apId: ap.id });
|
|
}
|
|
else {
|
|
if (apArray[aIdx].typeRecords[t].pId === p.id) {
|
|
apArray[aIdx].typeRecords[t].checked = true;
|
|
apArray[aIdx].typeRecords[t].apId = ap.id;
|
|
apArray[aIdx].typeRecords[t].allowPwd = ap.allowPwd;
|
|
}
|
|
}
|
|
if (t === 'loginName') {
|
|
apArray[aIdx].typeRecords[t].pwdDisabledTip = '账号登录必须使用密码方式';
|
|
}
|
|
else {
|
|
apArray[aIdx].typeRecords[t].pwdDisabled = false;
|
|
}
|
|
apArray[aIdx].defaultOptions.push({
|
|
label: this.t(`passport:v.type.${p.type}`),
|
|
value: ap.id,
|
|
});
|
|
if (ap.isDefault) {
|
|
apArray[aIdx].defaultValue = ap.id;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
this.setState({
|
|
apArray,
|
|
});
|
|
}
|
|
}
|
|
},
|
|
data: {
|
|
applications: [],
|
|
passports: [],
|
|
apArray: [],
|
|
types: [],
|
|
},
|
|
lifetimes: {
|
|
async ready() {
|
|
const { systemId } = this.props;
|
|
const { data: applicationDatas } = await this.features.cache.refresh('application', {
|
|
data: {
|
|
id: 1,
|
|
name: 1,
|
|
type: 1,
|
|
config: 1,
|
|
systemId: 1,
|
|
},
|
|
filter: {
|
|
systemId,
|
|
}
|
|
});
|
|
const { data: passportDatas } = await this.features.cache.refresh('passport', {
|
|
data: {
|
|
id: 1,
|
|
type: 1,
|
|
config: 1,
|
|
enabled: 1,
|
|
systemId: 1,
|
|
},
|
|
filter: {
|
|
systemId,
|
|
enabled: true,
|
|
type: {
|
|
$ne: 'password',
|
|
}
|
|
},
|
|
sorter: [{
|
|
$attr: {
|
|
$$updateAt$$: 1,
|
|
},
|
|
$direction: 'desc'
|
|
}]
|
|
});
|
|
const applications = applicationDatas;
|
|
const passports = passportDatas;
|
|
const types = uniq(passports.map((ele) => ele.type));
|
|
this.setState({
|
|
applications,
|
|
passports,
|
|
types,
|
|
});
|
|
}
|
|
},
|
|
methods: {
|
|
arraysAreEqual(first, second) {
|
|
if (first?.length !== second?.length) {
|
|
return false;
|
|
}
|
|
for (let i = 0; i < first?.length; ++i) {
|
|
if (!isEqual(first[i], second[i])) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
},
|
|
checkDisabled(application, passport) {
|
|
const { type: aType, config: aConfig } = application;
|
|
const { type: pType, config: pConfig } = passport;
|
|
switch (pType) {
|
|
case 'sms':
|
|
if (!pConfig.mockSend) {
|
|
if (!pConfig.templateName) {
|
|
return {
|
|
disabled: true,
|
|
disabledTip: '手机号登录未配置验证码模板名称',
|
|
};
|
|
}
|
|
if (!pConfig.defaultOrigin) {
|
|
return {
|
|
disabled: true,
|
|
disabledTip: '手机号登录未配置默认渠道',
|
|
};
|
|
}
|
|
}
|
|
break;
|
|
case 'email':
|
|
if (!pConfig.mockSend) {
|
|
if (!pConfig.account) {
|
|
return {
|
|
disabled: true,
|
|
disabledTip: '邮箱登录未配置账号',
|
|
};
|
|
}
|
|
else if (!pConfig.subject) {
|
|
return {
|
|
disabled: true,
|
|
disabledTip: '邮箱登录未配置邮件主题',
|
|
};
|
|
}
|
|
else if ((!pConfig.text || !pConfig.text?.includes('${code}')) &&
|
|
(!pConfig.html || !pConfig.html?.includes('${code}'))) {
|
|
return {
|
|
disabled: true,
|
|
disabledTip: '邮箱登录未配置邮件内容模板',
|
|
};
|
|
}
|
|
}
|
|
break;
|
|
case 'wechatPublicForWeb':
|
|
if (!pConfig.appId) {
|
|
return {
|
|
disabled: true,
|
|
disabledTip: '公众号授权登录未配置appId',
|
|
};
|
|
}
|
|
break;
|
|
case 'wechatMpForWeb':
|
|
if (!pConfig.appId) {
|
|
return {
|
|
disabled: true,
|
|
disabledTip: '小程序授权登录未配置appId',
|
|
};
|
|
}
|
|
break;
|
|
case 'oauth':
|
|
if (!(pConfig.oauthIds && pConfig.oauthIds.length > 0)) {
|
|
return {
|
|
disabled: true,
|
|
disabledTip: 'OAuth授权登录未配置oauth供应商',
|
|
};
|
|
}
|
|
break;
|
|
case 'password':
|
|
return {
|
|
disabled: true,
|
|
disabledTip: '密码登录已调整',
|
|
};
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
switch (aType) {
|
|
case 'web':
|
|
if (pType === 'wechatWeb') {
|
|
//微信网站登录 application需配置微信网站appId
|
|
const { appId } = aConfig.wechat || {};
|
|
if (!appId || appId === '') {
|
|
return {
|
|
disabled: true,
|
|
disabledTip: '当前application未配置微信网站appId',
|
|
};
|
|
}
|
|
}
|
|
else if (pType === 'wechatMp' || pType === 'wechatPublic') {
|
|
return {
|
|
disabled: true,
|
|
disabledTip: '当前application不支持该登录方式',
|
|
};
|
|
}
|
|
break;
|
|
case 'wechatMp':
|
|
if (['wechatPublic', 'wechatWeb', 'wechatMpForWeb', 'wechatPublicForWeb', 'oauth'].includes(pType)) {
|
|
return {
|
|
disabled: true,
|
|
disabledTip: '当前application不支持该登录方式',
|
|
};
|
|
}
|
|
break;
|
|
case 'wechatPublic':
|
|
if (['wechatMp', 'wechatWeb', 'wechatMpForWeb', 'wechatPublicForWeb', 'oauth'].includes(pType)) {
|
|
return {
|
|
disabled: true,
|
|
disabledTip: '当前application不支持该登录方式',
|
|
};
|
|
}
|
|
break;
|
|
case 'native':
|
|
if (['wechatMp', 'wechatPublic', 'wechatWeb', 'wechatMpForWeb', 'wechatPublicForWeb', 'oauth'].includes(pType)) {
|
|
return {
|
|
disabled: true,
|
|
disabledTip: '当前application不支持该登录方式',
|
|
};
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return {
|
|
disabled: false,
|
|
disabledTip: undefined,
|
|
};
|
|
},
|
|
async onCheckedChange(aId, pId, checked, apId) {
|
|
const { passports } = this.state;
|
|
const passportType = passports?.find((ele) => ele.id === pId)?.type;
|
|
if (checked) {
|
|
//create applicationPassport
|
|
if (passportType === 'loginName') {
|
|
this.addItem({
|
|
applicationId: aId,
|
|
passportId: pId,
|
|
isDefault: true,
|
|
allowPwd: true,
|
|
});
|
|
}
|
|
else {
|
|
this.addItem({
|
|
applicationId: aId,
|
|
passportId: pId,
|
|
isDefault: true,
|
|
});
|
|
}
|
|
}
|
|
else {
|
|
//remove id为apId的applicationPassport
|
|
apId && this.removeItem(apId);
|
|
}
|
|
},
|
|
checkLastOne(aId, pId) {
|
|
const { apArray } = this.state;
|
|
const idx = apArray.findIndex((ele) => ele.aId === aId);
|
|
if (idx !== -1) {
|
|
const records = apArray[idx].typeRecords;
|
|
for (const key of Object.keys(records)) {
|
|
const r = records[key];
|
|
if ((r.checkedValue && r.checkedValue !== pId && !!r.checkedValue) || (r.pId && r.pId !== pId && !!r.checked)) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
return false;
|
|
},
|
|
async onSelectChange(aId, addPId, removeApId) {
|
|
if (removeApId) {
|
|
removeApId && this.removeItem(removeApId);
|
|
}
|
|
if (addPId) {
|
|
this.addItem({
|
|
applicationId: aId,
|
|
passportId: addPId,
|
|
isDefault: true,
|
|
});
|
|
}
|
|
},
|
|
getRender(pType, passports, aType) {
|
|
let render = 'switch';
|
|
if (passports.length > 1) {
|
|
if (aType === 'web' || (['wechatMp', 'wechatPublic'].includes(aType) && ['email', 'sms'].includes(pType))) {
|
|
render = 'select';
|
|
}
|
|
}
|
|
return render;
|
|
},
|
|
checkPwd(passport) {
|
|
const { type } = passport;
|
|
let showPwd = false, pwdDisabled = undefined, pwdDisabledTip = undefined;
|
|
if (['sms', 'email', 'loginName'].includes(type)) {
|
|
showPwd = true;
|
|
pwdDisabled = true;
|
|
pwdDisabledTip = '请先启用该登录方式';
|
|
}
|
|
return {
|
|
showPwd,
|
|
pwdDisabled,
|
|
pwdDisabledTip,
|
|
};
|
|
},
|
|
}
|
|
});
|