Compare commits

...

3 Commits

Author SHA1 Message Date
XiuYun CHEN
9355959b36 登录和接口请求 2025-08-05 10:52:22 +08:00
XiuYun CHEN
ef0b32cfe4 Merge branch 'master' of https://gitea.igandanyiyuan.com/gdxz/harmony
# Conflicts:
#	features/register/src/main/ets/view/LoginComp.ets
2025-08-05 09:58:30 +08:00
XiuYun CHEN
ad584a9860 登录 2025-08-05 09:56:53 +08:00
12 changed files with 271 additions and 84 deletions

View File

@ -26,12 +26,11 @@ import { KitLogger } from './logger/AppLogger';
import { LoggerKitImpl } from './logger/LoggerKitImpl';
import { ChatRepo } from './repo/ChatRepo';
import { saveLocalRevokeMessageFormOther } from './utils/MessageUtils';
import { router } from '@kit.ArkUI';
import { LengthMetrics, router } from '@kit.ArkUI';
import { HMRouterMgr } from '@hadss/hmrouter';
import { NotificationUtil } from '@itcast/basic';
import { ChangeUtil, NotificationUtil } from '@itcast/basic';
import { BusinessError } from '@kit.BasicServicesKit';
import { NotificationBasicOptions } from '@itcast/basic/src/main/ets/pushnotification/NotificationOptions';
export const currentConversationChanged: string = 'CurrentConversationChanged'
export class ChatKitClient {
@ -58,6 +57,7 @@ export class ChatKitClient {
appKey: appKey,
imVersion: IM_SDK_VERSION,
})
}
/**
@ -175,13 +175,33 @@ export class ChatKitClient {
console.info("netease ChatKitClient initListener ");
ChatKitClient.nim.loginService.on("onKickedOffline", (detail: V2NIMKickedOfflineDetail) => {
// const detail = ChatKitClient.nim.loginService.getKickedOfflineDetail()
console.log('Response onKickedOffline'+detail.clientType+' 22 '+detail.customClientType)
// console.log('Response onKickedOffline'+detail.clientType+' 22 '+detail.customClientType)
if(HMRouterMgr.getCurrentPathStack()!=null)
{
HMRouterMgr.removeAll()
router.replaceUrl({
url: 'pages/LoginPage/LoginPage', // 目标url
},router.RouterMode.Single)
router.clear()
}
let phone="ios";
switch(detail.clientType)
{
case 1:
phone="android";
break;
case 2:
phone="ios";
break;
case 16:
phone="web";
break;
default:
phone="其他设备";
break;
}
ChangeUtil.Logout(phone)
// router.replaceUrl({
// url: 'pages/LoginPage/LoginPage', // 目标url
// },router.RouterMode.Single)
// router.clear()
})
// 数据同步监听
ChatKitClient.nim.conversationService?.on('onSyncFinished', ChatKitClient.onSyncFinishedFun)
@ -223,4 +243,6 @@ export class ChatKitClient {
}
})
}
}

View File

@ -7,7 +7,7 @@ export struct PerfactInputSheet {
@Prop inputTitle:string = '';
@Prop inputPlaceholder:string = ''
@State inputText:string = ''
@State style:string = '0'//默认类型为注册时候的弹窗//1为普通确认取消输入框//2未普通弹框
@State style:string = '0'//默认类型为注册时候的弹窗//1为普通确认取消输入框//2未普通弹框//3为只有一个确定按钮的弹窗
// 添加回调函数属性
@State okColor:ResourceStr='#000000'
@State cancelColor:ResourceStr='#333333'
@ -195,6 +195,63 @@ export struct PerfactInputSheet {
}.margin({ top: 10, bottom: 10 }).width('100%')
}
.width('80%').backgroundColor(Color.White)
}.borderRadius(24)
}
else if(this.style=='3')
{
Row(){
Column() {
Text(this.inputTitle)
.fontSize(18)
.padding(20)
.width('100%')
.textAlign(TextAlign.Center)
.fontColor('#444444')
Row(){
Text(this.inputPlaceholder)
.fontColor('#444444')
.backgroundColor(Color.White)
.padding({left:10,right:10,bottom:20})
}
.backgroundColor(Color.White)
Text('').height(1).width('100%')
.backgroundColor($r('app.color.home_gray')).margin({top:10})
Row() {
// Text(this.cancelText)
// .fontSize(15)
// .fontColor(this.cancelColor)
// .textAlign(TextAlign.Center)
//
// .height(30).layoutWeight(1)
// .onClick(() => {
// if(this.needcancelCallBack)
// {
// this.inputCallBack(this.inputText, 'needcancelCallBack');
// }
// this.controller.close()
// })
// Text('').height(30).width(1)
// .backgroundColor($r('app.color.home_gray'))
Text(this.okText)
.textAlign(TextAlign.Center)
.fontColor(this.okColor)
.fontSize(15)
.onClick(() => {
this.controller.close()
this.inputCallBack(this.inputText, this.inputTitle);
})
.height(30).layoutWeight(1)
}.margin({ top: 10, bottom: 10 }).width('100%')
}
.width('80%').backgroundColor(Color.White)

View File

@ -10,7 +10,9 @@ import { i18n } from '@kit.LocalizationKit';
import { connection } from '@kit.NetworkKit';
import http from '@ohos.net.http'
import {BasicConstant} from '../constants/BasicConstant'
import { componentUtils } from '@kit.ArkUI';
import { componentUtils, router } from '@kit.ArkUI';
import { authStore } from './auth';
import { preferenceStore } from './PreferenceStore';
export class ChangeUtil {
/**
@ -312,4 +314,20 @@ export class ChangeUtil {
const height = componentInfo.size.height//3.38
return height
}
static Logout(phone:string)
{
authStore.delUser();
preferenceStore.clear()
preferenceStore.setItemBoolean('isLogin',false)
preferenceStore.setItemBoolean('isFirstRun',false)
// router.back()
router.replaceUrl({
url: 'pages/LoginPage/LoginPage', // 目标url
params: {
phone:phone
}
},router.RouterMode.Single)
router.clear()
}
}

View File

@ -7,6 +7,8 @@ import cryptoFramework from '@ohos.security.cryptoFramework';
import util from '@ohos.util';
import { BusinessError } from '@kit.BasicServicesKit';
import { rcp } from '@kit.RemoteCommunicationKit';
import { HashMap } from '@kit.ArkTS';
import { http } from '@kit.NetworkKit';
@Entry
@Component
@ -275,33 +277,71 @@ async function decryptString(str:string) {
// B2e%2B96mEodDQ5EIsmcpfh6cJbH7WhjSkXrIz8JtGf2gREqwSckolodE2%2FdNTTssxvwLTAltHlphKiSYWT91IpBUkt30diwj0VF1elbS193JwyOF4AU%2FhJ%2FRYQtxUHrB%2BlRo65QEhktb7z79lsRuJwUKISPEbTkrCVzRx9QDGcihdsOe44ABgLH%2BmyFhgEsMC
// B2e+96mEodDQ5EIsmcpfh6cJbH7WhjSkXrIz8JtGf2gREqwSckolodE2/dNTTssxvwLTAltHlphKiSYWT91IpBUkt30diwj0VF1elbS193JwyOF4AU/hJ/RYQtxUHrB+lRo65QEhktb7z79lsRuJwUKISPEbTkrCVzRx9QDGcihdsOe44ABgLH+myFhgEsMC
async function pushScanPage(str:string) {
const liceScanSuccess = `liveScanSuccess}${str}}${authStore.getUser().uuid},${authStore.getUser().realName},${authStore.getUser().photo}`
const textEncoder = new util.TextEncoder()
const inputData: Uint8Array = textEncoder.encodeInto(liceScanSuccess)
const scanData = await AESEncryptionDecryption.aes128Encrypt(inputData,BasicConstant.ExpertAesKey)
const base64Data = AESEncryptionDecryption.customBase64Encode(scanData)
const encodedString = encodeURIComponent(base64Data)
const postContent = new rcp.MultipartForm({
'message': encodedString
})
const session = rcp.createSession()
session.post(BasicConstant.sendWebsocketMsg, {
data: postContent,
headers: {
'Content-Type': 'application/json'
}
})
.then((response) => {
let json:Record<string,string> = JSON.parse(response+'') as Record<string,string>
if(json.code == '1') {
router.pushUrl({url:'pages/VideoPage/CustomScanPage'})
const liceScanSuccess = `videoScanSuccess}${str}}${authStore.getUser().uuid},${authStore.getUser().realName},${authStore.getUser().photo}`
// const textEncoder = new util.TextEncoder()
// const inputData: Uint8Array = textEncoder.encodeInto(liceScanSuccess)
// const scanData = await AESEncryptionDecryption.aes128Encrypt(inputData,BasicConstant.ExpertAesKey)
// const base64Data = AESEncryptionDecryption.customBase64Encode(scanData)
// const encodedString = encodeURIComponent(base64Data)
// let hashMap: HashMap<string, string> = new HashMap()
// hashMap.set('message',this.code)
const scanData =await AESEncryptionDecryption.aesEncrypt(liceScanSuccess,"deoep09_klodLdAo")
const encodedString = encodeURIComponent(scanData)
let httpRequest = http.createHttp();
let data = "message="+encodedString;
httpRequest.request(
BasicConstant.sendWebsocketMsg,
{
method: http.RequestMethod.POST,
// Optional, default is http.RequestMethod.GET//Developers can add header fields according to their own business needs
header: { 'Content-Type': 'application/x-www-form-urlencoded' }, // This field is used to pass content when using POST requests
extraData: data,
connectTimeout: 60000, // Optional, default is 60000ms
readTimeout: 60000, // Optional, default is 60000ms
}, (err, data) => {
if (!err) {
// Data.read is the HTTP response content, which can be parsed according to business needs
console.info('Result:' + JSON.stringify(data.result));
console.info('code:' +
JSON.stringify(data.responseCode)); // Data.reader is an HTTP response header that can be parsed according to business needs
console.info('header:' + JSON.stringify(data.header));
console.info('cookies:' +
JSON.stringify(data.cookies)); // Starting from API8
} else {
promptAction.showToast({ message: String(json.message), duration: 1000 })
console.info('error:' + JSON.stringify(err)); // Unsubscribe from HTTP response header events
httpRequest.off('headersReceive'); // When the request is exhausted, call the destroy method to actively destroy it.
httpRequest.destroy();
}
})
.catch((err: BusinessError) => {
console.error(`Response err: Code is ${JSON.stringify(err.code)}, message is ${JSON.stringify(err)}`);
})
// const postContent = new rcp.MultipartForm({
// 'message': encodedString
// })
// const postContent: rcp.RequestContent = {
// fields: {
// 'message': encodedString,
//
// }
// }
// const session = rcp.createSession()
// session.post(BasicConstant.sendWebsocketMsg, {
// data: postContent,
// headers: {
// 'Content-Type': 'application/x-www-form-urlencoded'
// }
// })
// .then((response) => {
// let json:Record<string,string> = JSON.parse(response+'') as Record<string,string>
// if(json.code == '1') {
// router.pushUrl({url:'pages/VideoPage/CustomScanPage'})
// } else {
// promptAction.showToast({ message: String(json.message), duration: 1000 })
// }
// })
// .catch((err: BusinessError) => {
// console.error(`Response err: Code is ${JSON.stringify(err.code)}, message is ${JSON.stringify(err)}`);
// })
// hdHttp.post<string>(BasicConstant.sendWebsocketMsg, {
// "message":base64Data
// } as Record<string,string>).then(async (res: HdResponse<string>) => {
@ -319,3 +359,4 @@ async function pushScanPage(str:string) {
}

View File

@ -14,15 +14,15 @@ export struct MessageComp {
// @Param pathStack: NavPathStack = new NavPathStack()
@Param onUreadMessageChange?: (unreadCount?: number) => void = undefined
loadUnreadApplication = async () => {
try {
const unreadCount = await ContactRepo.getAddApplicationUnreadCount()
} catch (err) {
console.log(err)
}
}
// loadUnreadApplication = async () => {
//
// try {
// const unreadCount = await ContactRepo.getAddApplicationUnreadCount()
//
// } catch (err) {
// console.log(err)
// }
// }
//获取会话列表未读数
@ -48,14 +48,14 @@ export struct MessageComp {
}
)
ChatKitClient.nim.friendService?.on('onFriendAddApplication', async (application: V2NIMFriendAddApplication) => {
await this.loadUnreadApplication()
})
try {
await this.loadUnreadApplication()
} catch (err) {
console.log(err)
}
// ChatKitClient.nim.friendService?.on('onFriendAddApplication', async (application: V2NIMFriendAddApplication) => {
// await this.loadUnreadApplication()
// })
// try {
// await this.loadUnreadApplication()
// } catch (err) {
// console.log(err)
// }
this.loadConfig()
this.loadUnreadMessageCount()
}

View File

@ -3,6 +3,7 @@ import {
applyListModel,
authStore, BasicConstant,
ChangeUtil,
EmptyViewComp,
hdHttp, HdLoadingDialog, HdResponse,
HdTwoNav,
PatientData,
@ -49,7 +50,7 @@ export struct PatientListComp {
@State delectuuid:string=''
@State delectname:string=''
@State positionDelete:number = 0
@State isEmptyViewVisible: boolean = false; // 控制显隐的状态变量
dialogDelete = new CustomDialogController({
builder: DelectDialog(
{
@ -123,20 +124,6 @@ export struct PatientListComp {
console.log('服务器返回的患者数据:', json);
if(json.data!=null)
{
// let regionRequestData: PatientsData[]=[...json.data]
// regionRequestData =[...json.data]
// regionRequestData.push(...json.data)
// regionRequestData.push(...json.data)
// regionRequestData.push(...json.data)
// regionRequestData.push(...json.data)
// regionRequestData.push(...json.data)
// regionRequestData.push(...json.data)
// regionRequestData.push(...json.data)
// regionRequestData.push(...json.data)
// regionRequestData.push(...json.data)
// regionRequestData.push(...json.data)
// regionRequestData.push(...json.data)
// this.collationData(regionRequestData);
if(json.data!=null&&json.data.length>0)
{
this.total=json.data.length
@ -146,6 +133,12 @@ export struct PatientListComp {
preferenceStore.setItemNumber('old_patient_num',this.total/10)
}
this.collationData(json.data);
this.isEmptyViewVisible=false
}
else
{
this.isEmptyViewVisible=true
this.dialog.close()
}
@ -198,7 +191,7 @@ export struct PatientListComp {
},rightItemAction2:()=>{
HMRouterMgr.push({pageUrl:'PatientsListSearchComp'})
}})
Stack({ }) {
Stack({ alignContent:Alignment.Top}) {
List({ scroller: this.scroller, space: 0, initialIndex: 0 }) {
ListItem() {
Column()
@ -303,6 +296,11 @@ export struct PatientListComp {
.onClick(() => {
HMRouterMgr.push({pageUrl:'PatientsGroup',param:"我的患者"})
})
if (this.isEmptyViewVisible){
EmptyViewComp({promptText:'暂无随访患者',isVisibility:this.isEmptyViewVisible})
.width('100%')
.height('60%')
}
ForEach(this.regionDataGroupsList, (regionDataGroups: Groups, index) => {
ListItemGroup({ header: this.itemHead(regionDataGroups.title) }) {
@ -475,6 +473,7 @@ export struct PatientListComp {
}.width('100%')
.height('100%')
}
private collationData(regionRequestData: PatientsData[]) {

View File

@ -8,7 +8,9 @@ import { deviceInfo } from '@kit.BasicServicesKit';
@Preview
@Component
export struct LoginComp {
@Link loginstatus: boolean;
@Link YX_accid:string
@Link YX_token:string
@State
mobile: string = ''
@State
@ -94,6 +96,8 @@ export struct LoginComp {
console.info(`Response login succeeded: ${res}`);
let json:LoginInfo = JSON.parse(res+'') as LoginInfo;
if(json.code=='1'||json.code=='200') {
this.YX_token=json.YX_token
this.YX_accid=json.YX_accid
preferenceStore.setItemString(BasicConstant.YX_accid,json.YX_accid)
preferenceStore.setItemString(BasicConstant.YX_token,json.YX_token)
this.arrToStringSpecialy(json.special)
@ -124,7 +128,6 @@ export struct LoginComp {
} else {
this.loadPatients()//登录成功后获取患者数据存入数据库
this.loginstatus=true
authStore.setUser(objs.data)
// emitter.emit({ eventId: 100401 })
logger.info('Response state'+state);

View File

@ -26,7 +26,7 @@ export struct LocalConversationPage {
this.viewModel.onUreadMessageChange = this.onUreadMessageChange
//初始化@ 服务
AitServer.instance.init()
// AitServer.instance.init()
this.viewModel.initConversation()
}

View File

@ -8,6 +8,7 @@
import common from '@ohos.app.ability.common'
import { LogLevel, NIMInitializeOptions, NIMInterface, NIMServiceOptions,
V2NIMEnableServiceType,
V2NIMLoginOption,
V2NIMProvidedServiceType } from '@nimsdk/base'
import { NIMSdk } from '@nimsdk/nim'
import { V2NIMTeamServiceImpl } from '@nimsdk/team'
@ -50,7 +51,9 @@ export class NimRepository {
async login(accountId: string, token: string, appKey: string) {
try {
console.debug(`Performance Test im start loginSuccess`)
await this.nim.loginService.login(accountId, token);
await this.nim.loginService.login(accountId, token, {
forceMode: true
} as V2NIMLoginOption);
console.error('----------- 登录成功 -----------')
// router.pushUrl({
// url: 'pages/Netease/imTabPage'

View File

@ -32,9 +32,13 @@ struct Home {
this.activeIndex = e.data.activeIndex
}
})
if(AppConfig.userId!='')
{
this.login(AppConfig.userId, AppConfig.userToken)//暂时隐蔽云信登录
}
}
onChangeIndex() {
if (this.activeIndex === 3) themeManager.settingStatusBarWhite()
else themeManager.settingStatusBarBlack()

View File

@ -1,13 +1,18 @@
import { LoginComp } from 'register'
import { NimRepository } from '../../entryability/NimRepository'
import { AppConfig } from '../../constants/AppConfig'
import { PerfactInputSheet } from '@itcast/basic/src/main/ets/Views/PerfactInputSheet'
import { LengthMetrics, router } from '@kit.ArkUI'
import { TimestampUtil } from '@itcast/basic'
@Entry
@Component
struct LoginPage {
@State params:Record<string, string> = router.getParams() as Record<string, string>;
@State YX_token: string=''
@State
@Watch('onLogins')
logins: boolean=false
YX_accid: string=''
login = async (accountId: string, token: string) => {
const nimRepository = NimRepository.getInstance(getContext(this))
try {
@ -18,7 +23,7 @@ struct LoginPage {
}
build() {
Column() {
LoginComp({ loginstatus: this.logins })
LoginComp({ YX_accid: this.YX_accid,YX_token:this.YX_token })
}
}
onLogins()
@ -27,5 +32,39 @@ struct LoginPage {
this.login(AppConfig.userId, AppConfig.userToken)
}
private dialog!:CustomDialogController;
@State inputPlaceholder:string=''
initDialog() {
this.dialog = new CustomDialogController({
builder:PerfactInputSheet({
controller:this.dialog,
inputTitle:'异地登录',
inputPlaceholder:this.inputPlaceholder,
style:'3',
}),
keyboardAvoidDistance: LengthMetrics.vp(0), // 设置弹窗底部与键盘顶部间距单位vp
alignment: DialogAlignment.Center,
customStyle: true,
autoCancel: false,
backgroundColor: ('rgba(0,0,0,0.5)'),
height: '100%'
})
}
aboutToAppear(): void {
this.initDialog()
let phone=this.params?this.params.phone:''
if( phone === null || phone === undefined||phone=='' )
{
}
else
{
this.inputPlaceholder='您的账号于'+ TimestampUtil.format(Date.now(),'YYYY-MM-DD HH:mm:ss')
+'在'+phone+'上登录。如果这不是您的操作,您的密码可能已泄露,请重新登录后尽快修改密码'
this.dialog.open()
}
}
}

View File

@ -1,4 +1,4 @@
import { authStore, BasicConstant, HdNav , preferenceStore} from '@itcast/basic';
import { authStore, BasicConstant, ChangeUtil, HdNav , preferenceStore} from '@itcast/basic';
import { bundleManager, common, ConfigurationConstant, Want } from '@kit.AbilityKit';
import { fileIo, storageStatistics } from '@kit.CoreFileKit';
import { promptAction, router } from '@kit.ArkUI';
@ -198,12 +198,13 @@ struct SettingPage {
.backgroundColor(Color.White)
.margin({top:10,left:10,right:10})
.onClick(()=>{
authStore.delUser();
preferenceStore.setItemBoolean('isLogin',false)
router.back()
router.replaceUrl({
url: 'pages/LoginPage/LoginPage', // 目标url
},router.RouterMode.Single)
ChangeUtil.Logout('')
// authStore.delUser();
// preferenceStore.setItemBoolean('isLogin',false)
// router.back()
// router.replaceUrl({
// url: 'pages/LoginPage/LoginPage', // 目标url
// },router.RouterMode.Single)
})
}
}