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, }; }, } });