注册资料

This commit is contained in:
xiaoxiao
2025-05-20 14:23:03 +08:00
parent f821535e18
commit 09a6f13e1d
80 changed files with 1102 additions and 1038 deletions
+12
View File
@@ -2,6 +2,8 @@ export { hdHttp, HdResponse } from './src/main/ets/utils/request'
export { authStore, HdUser, AUTH_STORE_KEY } from './src/main/ets/utils/auth'
export { perfactAuth } from './src/main/ets/utils/PerfactAuth'
export { logger } from './src/main/ets/utils/logger'
export { getTimeText, getPercentText } from './src/main/ets/utils/base'
@@ -32,4 +34,14 @@ export { AESEncryptionDecryption } from './src/main/ets/utils/AESEncryptionDecry
export { HdGrid } from './src/main/ets/components/HdGrid'
export { PhotoActionSheet } from './src/main/ets/Views/PhotoActionSheet'
export { DatePickerDialog } from './src/main/ets/Views/DatePickerDialog'
export { OfficeSelectedSheet } from './src/main/ets/Views/OfficeSelectedSheet'
export { PositionSelectedSheet } from './src/main/ets/Views/PositionSelectedSheet'
export { SpecialitySelectedSheet } from './src/main/ets/Views/SpecialitySelectedSheet'
+1 -1
View File
@@ -6,6 +6,6 @@
"author": "",
"license": "Apache-2.0",
"dependencies": {
"mypage": "file:../../features/mypage"
}
}
@@ -0,0 +1,73 @@
import { formatDate } from '../utils/DateUtils'
import { authStore } from '../utils/auth'
@CustomDialog
export struct DatePickerDialog {
@Prop selectedDateString:string = formatDate(new Date(),'YYYY-MM-DD');
controller: CustomDialogController;
// 添加回调函数属性
private dateSelected: (date: string) => void = () => {};
// 修改构造函数
constructor(controller: CustomDialogController, dateSelected: (date: string) => void) {
super();
this.controller = controller;
this.dateSelected = dateSelected;
}
// 初始化日期范围(示例为1930-至今)
private dateOptions: DatePickerOptions = {
start: new Date('1930-01-01'),
end: new Date(this.selectedDateString),
selected: new Date(authStore.getUser().birthDate?authStore.getUser().birthDate:'1930-01-01'),
}
build() {
Column() {
// 操作按钮区域
Row({space:70}) {
Button('取消')
.layoutWeight(1)
.backgroundColor(Color.Transparent)
.fontColor($r('app.color.main_color'))
.backgroundColor(Color.White)
.width(80)
.onClick(() => {
this.controller.close()
})
Text('请选择出生日期')
.fontSize(15)
.fontColor('#666666')
Button('确定')
.layoutWeight(1)
.backgroundColor(Color.Transparent)
.fontColor($r('app.color.main_color'))
.backgroundColor(Color.White)
.width(80)
.onClick(() => {
this.controller.close()
this.dateSelected(this.selectedDateString)
})
}
.height(40)
// 日期选择器主体
DatePicker(this.dateOptions)
.lunar(false) // 禁用农历显示[1](@ref)
.selectedTextStyle({
color: '#007AFF',
font: { size: 20, weight: FontWeight.Medium }
})
.onDateChange((selected:Date)=>{
this.selectedDateString = formatDate(selected,'YYYY-MM-DD');
console.info('select current date is: ' + formatDate(selected,'YYYY-MM-DD'));
})
}
.width('100%')
.height(240)
.backgroundColor(Color.White)
}
}
@@ -0,0 +1,79 @@
@Component
export struct EditUserDataItem {
private label: string = ''
private required: boolean = false
@Prop content: string = ''
private hasArrow: boolean = false
@Prop isLine:boolean = true;
build() {
Column() {
Row() {
Row() {
Text(this.label)
.fontSize(16)
.fontColor('#333333')
.margin({ left: this.isLine?15:10 })
if (this.required) {
Text('*')
.margin({ left: 0 })
.fontSize(16)
.fontColor($r('app.color.main_color'))
}
}
.layoutWeight(1)//权重自定义
.justifyContent(FlexAlign.Start)
Row({space:5}) {
if (this.label == '头像') {
Image(this.content)
.alt(this.isLine?$r('app.media.userPhoto_default'):$r('app.media.icon_touxiang_persion_ws'))
.onComplete(() => console.log('图片加载完成'))
.onError(() => console.error('图片加载失败'+this.content))
.width(40)
.height(40)
.margin({ right: this.hasArrow?0:10 })
.borderRadius(8)
} else if (this.label == '执业医师证图片或胸牌') {
Image(this.content)
.alt(this.isLine?null:$r('app.media.icon_xiongpai_ws'))
.onComplete(() => console.log('图片加载完成'))
.onError(() => console.error('图片加载失败'+this.content))
.width(60)
.height(40)
.margin({ right: this.hasArrow?0:10 })
} else {
Text(this.content)
.fontSize(14)
.fontColor('#333333')
.width('auto')
.constraintSize({
maxWidth:this.label='专长(可选一到十项)'?'50%':'70%'
})
.textOverflow({ overflow: TextOverflow.Ellipsis })
.maxLines(1)
.margin({right: this.hasArrow?0:10 })
.textAlign(TextAlign.End)
}
if (this.hasArrow) {
Image($r('sys.media.ohos_ic_public_arrow_right'))
.width(15)
.height(15)
.margin({ right: 10 })
}
}
.justifyContent(FlexAlign.End)
}
.height(50)
.alignItems(VerticalAlign.Center)
if (this.isLine) {
Divider()
.color('#F4F4F4')
.strokeWidth(1)
.height(1)
.margin({ left: 10, top: 0 })
}
}
}
}
@@ -0,0 +1,113 @@
import HashMap from '@ohos.util.HashMap';
import { promptAction } from '@kit.ArkUI'
import { BusinessError } from '@kit.BasicServicesKit';
import { RequestDefaultModel } from '../models/RequestDefaultModel'
import { hdHttp, HdResponse } from '../utils/request'
import { BasicConstant } from '../constants/BasicConstant'
interface DefaultData {
}
@CustomDialog
export struct HeroPopWindow {
@Prop heroId:string = '';
@State detailsData:object = new Object;
private years: string[] = ['2019年英雄榜','2018年英雄榜','2017年英雄榜','2016年英雄榜','2015年英雄榜'];
controller: CustomDialogController;
heroDetailsRequestUrl:string = BasicConstant.urlExpertAPI+'gethonorDetail'
hashMap: HashMap<string, string> = new HashMap();
updateHeroDetailsAction(){
this.hashMap.set('id',this.heroId);
hdHttp.httpReq<string>(this.heroDetailsRequestUrl,this.hashMap).then(async (res: HdResponse<string>) => {
let json:RequestDefaultModel = JSON.parse(res+'') as RequestDefaultModel;
if(json.code=='1') {
this.detailsData = json.data;
} else {
console.error('英雄榜失败:'+json.message)
promptAction.showToast({ message: json.message, duration: 1000 })
}
}).catch((err: BusinessError) => {
console.info(`Response fail: ${err}`);
})
}
build() {
Stack() {
//半透明黑色背景
Column().width('100%').height('100%').backgroundColor('#50000000')
//弹窗主体
Column() {
//头部图标
Image($r('app.media.heroPop_headericon'))
.width(80)
.height(80)
.margin({top:-25})
.zIndex(2)
//标题和正文范围
Column() {
Text('肝胆英雄榜')
.fontSize(20)
.fontColor('#673986')
.margin({top:20})
Grid() {
ForEach(this.years,(item:string)=>{
GridItem({style:GridItemStyle.PLAIN}) {
Text(item)
.fontSize(10)
.fontColor(Color.Black)
.backgroundColor(Color.White) // 添加背景色确保可见
.textAlign(TextAlign.Center)
.width('100%') // 确保文本容器宽度
}
.height(20)
.width('48%')
.padding(5)
.borderRadius(10)
.borderWidth(1)
.borderColor(Color.Red)
})
}
.columnsGap(10)
.rowsGap(10)
.padding(10)
.width('100%')
.height('auto')
Text('感谢有您,一路相伴。"肝胆英雄榜"是由国内最具影响力的肝胆病互联网线上服务平台-\n' +
'肝胆相照依据肝胆病医生在各自领域年度所做工作,综合评选出来的最认可的"肝胆好医生",授予证书并赠送精美感恩好礼。\n' +
'目前"肝胆英雄榜"荣誉包括:"护肝大使"护肝新量""公益之星""科普达入"、"视频之星"、"人气科室"及"宣传之星"等。')
.fontSize(12)
.fontColor('#666666')
.textAlign(TextAlign.Start)
.lineHeight(20)
.width('90%')
.margin({bottom:10})
}
.zIndex(1)
.margin({top:-10,bottom:10})
.justifyContent(FlexAlign.Center)
.backgroundColor(Color.White)
.borderRadius(16)
.height('auto')
.width('90%')
//删除按钮
Button() {
Image($r('app.media.heropop_delete'))
.width(30)
.height(30)
}
.zIndex(3)
.position({ x: '88%', y: 10 })
.onClick(() => this.controller.close())
}
.width('90%')
.backgroundImage($r('app.media.heroPop_bg'))
.backgroundImageSize(ImageSize.Cover)
.borderRadius(16)
}
}
}
@@ -0,0 +1,118 @@
import { BasicConstant } from '../constants/BasicConstant'
import { RequestDefaultModel } from '../models/RequestDefaultModel'
import { promptAction } from '@kit.ArkUI'
import HashMap from '@ohos.util.HashMap';
import { BusinessError } from '@kit.BasicServicesKit';
import { authStore } from '../utils/auth'
import { hdHttp, HdResponse } from '../utils/request'
interface DefaultData {
'officeName':string;
'officeUuid':string;
}
@CustomDialog
export struct OfficeSelectedSheet {
controller: CustomDialogController;
@State officeNameArr:Array<string> = [];
private officeArr:Array<DefaultData> = [];
@State selectedModel:DefaultData = { officeName: '', officeUuid: '' };
@State selectedIndex:number = 0;
// 添加回调函数属性
private officeSelected: (name:string , uuid:string) => void = () => {};
// 修改构造函数
constructor(controller: CustomDialogController, officeSelected: (name: string,uuid:string) => void) {
super();
this.controller = controller;
this.officeSelected = officeSelected;
}
officeRequestUrl:string = BasicConstant.urlExpert+'officeList'
hashMap: HashMap<string, string> = new HashMap();
aboutToAppear(): void {
this.uploadOffice();
}
uploadOffice() {
hdHttp.httpReq<string>(this.officeRequestUrl,this.hashMap).then(async (res: HdResponse<string>) => {
let json:RequestDefaultModel = JSON.parse(res+'') as RequestDefaultModel;
if(json.code=='1') {
this.officeArr = json.data as DefaultData[];
this.officeNameArr = json.data.map(item => item.officeName);
console.log('科室名称数组:', this.officeNameArr);
for (let index = 0; index < this.officeNameArr.length; index++) {
const officeObject = this.officeArr[index] as DefaultData;
const name = this.officeNameArr[index];
if (name == authStore.getUser().officeName) {
this.selectedIndex = index;
this.selectedModel = {officeName:name,officeUuid:officeObject.officeUuid}
} else {
const defaultModel = this.officeArr[0] as DefaultData;
this.selectedIndex = 0;
this.selectedModel = {officeName:defaultModel.officeName,officeUuid:defaultModel.officeUuid};
}
}
} else {
console.error('科室数据失败:'+json.message)
promptAction.showToast({ message: json.message, duration: 1000 })
}
}).catch((err: BusinessError) => {
console.info(`Response fail: ${err}`);
})
}
build() {
Column() {
// 操作按钮区域
Row({space:70}) {
Button('取消')
.layoutWeight(1)
// .backgroundColor(Color.Transparent)
.fontColor($r('app.color.main_color'))
.backgroundColor(Color.White)
.width(80)
.onClick(() => {
this.controller.close()
})
Text('请选择科室')
.fontSize(15)
.fontColor('#666666')
Button('确定')
.layoutWeight(1)
.fontColor($r('app.color.main_color'))
.backgroundColor(Color.White)
.width(80)
.onClick(() => {
this.controller.close()
this.officeSelected(this.selectedModel.officeName, this.selectedModel.officeUuid);
})
}
.height(40)
TextPicker({
range:this.officeNameArr,
selected:this.selectedIndex
})
.canLoop(false)
.selectedTextStyle({
color: '#007AFF',
font: { size: 20, weight: FontWeight.Medium }
})
.onChange((name: string | string[], index: number | number[]) => {
// 处理单列选择场景
if (typeof index === "number" && this.officeArr[index]) {
this.selectedModel = this.officeArr[index];
}
})
}
.width('100%')
.height(240)
.backgroundColor(Color.White)
}
}
@@ -0,0 +1,77 @@
import { promptAction } from '@kit.ArkUI'
@CustomDialog
export struct PerfactInputSheet {
controller:CustomDialogController;
@Prop inputTitle:string = '';
@Prop inputPlaceholder:string = ''
@State inputText:string = ''
// 添加回调函数属性
private inputCallBack: (input: string,title:string) => void = () => {};
// 修改构造函数
constructor(controller: CustomDialogController, inputCallBack: (input: string,title:string) => void) {
super();
this.controller = controller;
this.inputCallBack = inputCallBack;
}
build() {
Column() {
// 操作按钮区域
Row() {
Button('取消')
.layoutWeight(1)
.backgroundColor(Color.Transparent)
.fontColor($r('app.color.main_color'))
.backgroundColor('#EEEEEE')
.width('15%')
.fontSize(15)
.onClick(() => {
this.controller.close()
})
Text(this.inputTitle)
.width('65%')
.fontSize(15)
.fontColor('#333333')
.textAlign(TextAlign.Center)
Button('确定')
.layoutWeight(1)
.fontSize(15)
.backgroundColor(Color.Transparent)
.fontColor($r('app.color.main_color'))
.backgroundColor('#EEEEEE')
.width('15%')
.onClick(() => {
if (this.inputText.length <= 0) {
promptAction.showToast({ message: '输入不能为空', duration: 1000 })
return;
}
this.controller.close()
this.inputCallBack(this.inputText, this.inputTitle);
})
}
.height(30)
Row(){
TextInput({
placeholder: this.inputPlaceholder
})
.height(50)
.fontColor(Color.Black)
.backgroundColor(Color.White)
.onChange((value: string) => {
this.inputText = value;
})
}
.backgroundColor(Color.White)
}
.width('100%')
.height(100)
.backgroundColor('#EEEEEE')
}
}
@@ -0,0 +1,145 @@
import picker from '@ohos.file.picker';
import { BusinessError } from '@ohos.base';
import photoAccessHelper from '@ohos.file.photoAccessHelper';
import common from '@ohos.app.ability.common';
import { cameraPicker, camera } from '@kit.CameraKit'
import { abilityAccessCtrl } from '@kit.AbilityKit';
@CustomDialog
export struct PhotoActionSheet {
controller: CustomDialogController;
// 添加回调函数属性
private onPhotoSelected: (uri: string) => void = () => {};
// 修改构造函数
constructor(controller: CustomDialogController, onPhotoSelected: (uri: string) => void) {
super();
this.controller = controller;
this.onPhotoSelected = onPhotoSelected;
}
async checkCameraPermission(): Promise<boolean> {
const atManager = abilityAccessCtrl.createAtManager();
const grantStatus = await atManager.checkAccessToken(
globalThis.abilityContext.applicationInfo.accessTokenId,
'ohos.permission.CAMERA'
);
return grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED;
}
build() {
Column() {
// 操作按钮区域
Column() {
Row() {
// 拍摄照片按钮
Column() {
Image($r('app.media.icon_camera'))
.width(40)
.height(40)
Text('拍摄照片')
.fontSize(15)
.margin({top:10})
.fontColor($r('app.color.main_color'))
}
.width('50%')
.height(80)
.onClick(() => {
const context = getContext() as common.UIAbilityContext;
const cameras = camera.getCameraManager(context).getSupportedCameras();
cameras.forEach(device => {
console.log('Camera type:', device.cameraPosition);
});
this.openSystemCamera();
this.animateHide();
})
.padding(20)
// 相册照片按钮
Column() {
Image($r('app.media.ixon_album'))
.width(40)
.height(40)
Text('相册照片')
.fontSize(15)
.margin({top:10})
.fontColor($r('app.color.main_color'))
}
.width('50%')
.height(80)
.onClick(() => {
this.selectPhoto();
this.animateHide()
})
.padding(20)
}
}
.backgroundColor(Color.White)
Divider()
.color('#999999')
.strokeWidth(5)
.height(5)
.margin({top:20})
// 取消按钮
Button('取消')
.width('100%')
.height(50)
.fontColor('#999999')
.backgroundColor(Color.White)
.onClick(() => this.animateHide())
}
.width('100%')
.height(150)
.backgroundColor(Color.White)
}
animateHide() {
this.controller.close();
}
// 打开相机
private async openSystemCamera() {
try {
const pickerProfile: cameraPicker.PickerProfile = {
cameraPosition: camera.CameraPosition.CAMERA_POSITION_BACK,
videoDuration: 15 // 录像时设置最大时长(秒)
};
const result = await cameraPicker.pick(
getContext(),
[cameraPicker.PickerMediaType.PHOTO], // 可替换为VIDEO
pickerProfile
);
if (result.resultCode === 0) {
console.log('Photo URI:', result.resultUri);
// 处理拍摄结果
}
} catch (error) {
console.error('Camera error:', error.code);
}
}
// 资源被选中回调,返回资源的信息,以及选中方式
private selectPhoto() {
let photoSelectOptions = new picker.PhotoSelectOptions();
photoSelectOptions.MIMEType = picker.PhotoViewMIMETypes.IMAGE_TYPE;
photoSelectOptions.maxSelectNumber = 1;
let photoViewPicker = new picker.PhotoViewPicker();
photoViewPicker.select(photoSelectOptions)
.then((photoSelectResult) => {
console.info('PhotoViewPicker.select successfully, photoSelectResult uri: ' +
JSON.stringify(photoSelectResult));
if (photoSelectResult.photoUris && photoSelectResult.photoUris.length > 0) {
this.onPhotoSelected(photoSelectResult.photoUris[0]);
}
})
.catch((err: BusinessError) => {
console.error('PhotoViewPicker.select failed with err: ' + err);
});
}
}
@@ -0,0 +1,121 @@
import { BasicConstant } from '../constants/BasicConstant'
import { RequestDefaultModel } from '../models/RequestDefaultModel'
import { promptAction } from '@kit.ArkUI'
import HashMap from '@ohos.util.HashMap';
import { BusinessError } from '@kit.BasicServicesKit';
import { authStore } from '../utils/auth'
import { hdHttp, HdResponse } from '../utils/request'
interface DefaultData {
'name':string;
'uuid':string;
}
@CustomDialog
export struct PositionSelectedSheet {
controller: CustomDialogController;
@State officeNameArr:Array<string> = [];
private officeArr:Array<DefaultData> = [];
@Prop selectedOffice:object = new Object;
@State selectedModel:DefaultData = { name: '', uuid: '' };
@State selectedIndex:number = 0;
// 添加回调函数属性
private officeSelected: (name:string , uuid:string) => void = () => {};
// 修改构造函数
constructor(controller: CustomDialogController, officeSelected: (name: string,uuid:string) => void) {
super();
this.controller = controller;
this.officeSelected = officeSelected;
}
officeRequestUrl:string = BasicConstant.urlExpert+'positionList'
hashMap: HashMap<string, string> = new HashMap();
aboutToAppear(): void {
this.uploadOffice();
}
uploadOffice() {
hdHttp.httpReq<string>(this.officeRequestUrl,this.hashMap).then(async (res: HdResponse<string>) => {
let json:RequestDefaultModel = JSON.parse(res+'') as RequestDefaultModel;
if(json.code=='1') {
this.officeArr = json.data as DefaultData[];
this.officeNameArr = json.data.map(item => item.name);
for (let index = 0; index < this.officeNameArr.length; index++) {
const object = this.officeArr[index] as DefaultData;
const nameIndex = this.officeNameArr[index];
if (nameIndex == authStore.getUser().positionName) {
this.selectedIndex = index;
this.selectedModel = {name:nameIndex,uuid:object.uuid};
break;
} else {
const defaultModel = this.officeArr[0] as DefaultData;
this.selectedIndex = 0;
this.selectedModel = {name:defaultModel.name,uuid:defaultModel.uuid};
}
}
console.log('职称名称数组:', this.officeNameArr);
} else {
console.error('职称数据失败:'+json.message)
promptAction.showToast({ message: json.message, duration: 1000 })
}
}).catch((err: BusinessError) => {
console.info(`Response fail: ${err}`);
})
}
build() {
Column() {
// 操作按钮区域
Row({space:70}) {
Button('取消')
.layoutWeight(1)
.backgroundColor(Color.Transparent)
.fontColor($r('app.color.main_color'))
.backgroundColor(Color.White)
.width(80)
.onClick(() => {
this.controller.close()
})
Text('请选择职称')
.fontSize(15)
.fontColor('#666666')
Button('确定')
.layoutWeight(1)
.backgroundColor(Color.Transparent)
.fontColor($r('app.color.main_color'))
.backgroundColor(Color.White)
.width(80)
.onClick(() => {
this.controller.close()
this.officeSelected(this.selectedModel.name, this.selectedModel.uuid);
})
}
.height(40)
TextPicker({
range:this.officeNameArr,
selected:this.selectedIndex
})
.canLoop(false)
.selectedTextStyle({
color: '#007AFF',
font: { size: 20, weight: FontWeight.Medium }
})
.onChange((name: string | string[], index: number | number[]) => {
// 处理单列选择场景
if (typeof index === "number" && this.officeArr[index]) {
this.selectedModel = this.officeArr[index];
}
})
}
.width('100%')
.height(240)
.backgroundColor(Color.White)
}
}
@@ -0,0 +1,68 @@
@CustomDialog
export struct SexSelectedSheet {
controller:CustomDialogController;
@State sexNameArr:Array<string> = ['男','女'];
@Prop selectedSex:number = 0;
// 添加回调函数属性
private sexSelected: (index: number) => void = () => {};
// 修改构造函数
constructor(controller: CustomDialogController, sexSelected: (index: number) => void) {
super();
this.controller = controller;
this.sexSelected = sexSelected;
}
build() {
Column() {
// 操作按钮区域
Row({space:70}) {
Button('取消')
.layoutWeight(1)
.backgroundColor(Color.Transparent)
.fontColor($r('app.color.main_color'))
.backgroundColor(Color.White)
.width(80)
.onClick(() => {
this.controller.close()
})
Text('请选择性别')
.fontSize(15)
.fontColor('#666666')
Button('确定')
.layoutWeight(1)
.backgroundColor(Color.Transparent)
.fontColor($r('app.color.main_color'))
.backgroundColor(Color.White)
.width(80)
.onClick(() => {
this.controller.close()
this.sexSelected(this.selectedSex);
})
}
.height(40)
TextPicker({
range:this.sexNameArr,
})
.canLoop(false)
.selectedTextStyle({
color: '#007AFF',
font: { size: 20, weight: FontWeight.Medium }
})
.onChange((name: string | string[], index: number | number[]) => {
// 处理单列选择场景
if (typeof index === "number") {
this.selectedSex = index;
}
})
}
.width('100%')
.height(240)
.backgroundColor(Color.White)
}
}
@@ -0,0 +1,140 @@
import HashMap from '@ohos.util.HashMap';
import { promptAction } from '@kit.ArkUI'
import { BusinessError } from '@kit.BasicServicesKit';
import { RequestDefaultModel } from '../models/RequestDefaultModel'
import { hdHttp, HdResponse } from '../utils/request'
import { BasicConstant } from '../constants/BasicConstant'
interface DefaultData {
'name':string;
'uuid':string;
}
@CustomDialog
export struct SpecialitySelectedSheet {
controller: CustomDialogController;
@State specialityArr:Array<DefaultData> = [];
@State selectedNames: Array<string> = [];
@State selectedTags: Array<string> = [];
// 添加回调函数属性
private specialitySelected: (seletedTags:string,selectedNames:string) => void = () => {};
// 修改构造函数
constructor(controller: CustomDialogController, specialitySelected: (seletedTags:string,selectedNames:string) => void) {
super();
this.controller = controller;
this.specialitySelected = specialitySelected;
}
aboutToAppear(): void {
this.uploadSpeciality();
}
uploadSpeciality() {
const officeRequestUrl:string = BasicConstant.urlExpert+'disease'
const hashMap: HashMap<string, string> = new HashMap();
hdHttp.httpReq<string>(officeRequestUrl,hashMap).then(async (res: HdResponse<string>) => {
let json:RequestDefaultModel = JSON.parse(res+'') as RequestDefaultModel;
if(json.code=='1') {
this.specialityArr = json.data as DefaultData[];
console.log('请求专长接口成功,信息:', this.specialityArr);
} else {
console.error('请求专长接口失败:'+json.message)
promptAction.showToast({ message: json.message, duration: 1000 })
}
}).catch((err: BusinessError) => {
console.info(`Response fail: ${err}`);
})
}
build() {
Column() {
// 操作按钮区域
Row({space:70}) {
Button('取消')
.layoutWeight(1)
.backgroundColor(Color.Transparent)
.fontColor($r('app.color.main_color'))
.backgroundColor(Color.White)
.width(80)
.onClick(() => {
this.controller.close()
})
Text('请选择专长')
.fontSize(15)
.fontColor('#666666')
Button('确定')
.layoutWeight(1)
.backgroundColor(Color.Transparent)
.fontColor($r('app.color.main_color'))
.backgroundColor(Color.White)
.width(80)
.onClick(() => {
this.controller.close()
// 拼接为逗号分隔字符串
const diseaseUuid = this.selectedTags.join(',');
const diseaseName = this.selectedNames.join(',');
console.log('当前选中标签的uuid字符串:', diseaseUuid);
console.log('当前选中标签的name字符串:', diseaseName);
this.specialitySelected(diseaseUuid,diseaseName);
})
}
.height(40)
Grid() {
ForEach(this.specialityArr, (data: DefaultData) => {
GridItem() {
// 单个标签组件
Text(data.name)
.fontSize(12)
.width('100%')
.height(30)
.textAlign(TextAlign.Center)
.backgroundColor(this.isSelected(data.uuid) ? '#b58078' : '#FFFFFF')
.onClick(() => {
this.handleTagClick(data.uuid,data.name)
})
}
.height(30)
.width('25%') // 四等分宽度
.borderWidth(1)
.borderColor(Color.Gray)
})
}
}
.width('100%')
.height(240)
.backgroundColor(Color.White)
}
// 判断是否选中
private isSelected(uuid: string): boolean {
return this.selectedTags.includes(uuid)
}
private handleTagClick(uuid: string,name:string) {
const index = this.selectedTags.indexOf(uuid);
if (index === -1) {
// 添加选中(限制最多10个)
if (this.selectedTags.length >= 10) {
promptAction.showToast({ message: '最多可选择十项!', duration: 1000 });
return;
}
this.selectedTags = [...this.selectedTags, uuid];
this.selectedNames = [...this.selectedNames,name];
} else {
// 取消选中
const newSelected = [...this.selectedTags];
newSelected.splice(index, 1);
this.selectedTags = newSelected;
const nameSelected = [...this.selectedNames];
nameSelected.splice(index, 1);
this.selectedNames = nameSelected;
}
console.log('当前选中标签:', this.selectedTags)
}
}
+18 -10
View File
@@ -1,4 +1,5 @@
import { router } from '@kit.ArkUI'
import { emitter } from '@kit.BasicServicesKit'
@Builder
function defaultBuilder(): void {
@@ -34,23 +35,30 @@ export struct HdNav {
@BuilderParam
menuBuilder: () => void = defaultBuilder
// 添加右侧点击处理
private onRightItemClick() {
emitter.emit({
eventId: 250516,
priority: emitter.EventPriority.HIGH
})
}
build() {
Row({ space: 16 }) {
Row() {
if (this.showLeftIcon) {
Image(this.leftIcon)
.size({ width: 24, height: 24 })
.margin({left:-5})
.onClick(() => router.back())
.fillColor($r('app.color.black'))
}
else {
} else {
Blank()
.width(24)
}
Row() {
if (this.title) {
Text(this.title)
.fontWeight(600)
// .fontWeight(600)
.layoutWeight(1)
.textAlign(TextAlign.Center)
.fontSize(20)
@@ -62,6 +70,7 @@ export struct HdNav {
}
}
.height(56)
.width(150)
.layoutWeight(1)
if (this.showRightIcon) {
@@ -69,14 +78,14 @@ export struct HdNav {
.size({ width: 24, height: 24 })
.objectFit(ImageFit.Contain)
.bindMenu(this.menuBuilder)
} else if (this.showRightText)
{
.onClick(()=>this.onRightItemClick())
} else if (this.showRightText) {
Text(this.rightText)
.fontSize(16)
.fontColor(this.textColor)
.margin({right:10})
}
else {
.onClick(()=>this.onRightItemClick())
// .margin({right:10})
} else {
Blank()
.width(24)
}
@@ -85,6 +94,5 @@ export struct HdNav {
.height(56 + this.topHeight)
.width('100%')
.backgroundColor(this.bgColor)
}
}
@@ -50,4 +50,6 @@ export interface ExpertData{
state:number;
realName:string;
specialy:Array<object>;
diseaseName:string;
diseaseUuid:string;
}
@@ -0,0 +1,25 @@
type DateFormat = 'YYYY-MM-DD' | 'MM/DD/YYYY' | 'DD-MMM-YYYY' | 'YYYY年MM月DD日' | 'YYYYMMDD';
export function formatDate(date: Date,pattern:DateFormat = 'YYYY-MM-DD'): string {
const padZero = (num: number): string => num.toString().padStart(2, '0');
const year = date.getFullYear();
const month = padZero(date.getMonth() + 1); // 月份修正[7,8](@ref)
const day = padZero(date.getDate());
// 模式映射逻辑(核心补全部分)
switch (pattern) {
case 'YYYY-MM-DD':
return `${year}-${month}-${day}`;
case 'MM/DD/YYYY':
return `${month}/${day}/${year}`;
case 'DD-MMM-YYYY':
const months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
return `${day}-${months[date.getMonth()]}-${year}`; // 月份缩写处理[4](@ref)
case 'YYYY年MM月DD日':
return `${year}年${month}月${day}日`; // 中文格式[5](@ref)
case 'YYYYMMDD':
return `${year}${month}${day}`; // 紧凑格式
default:
throw new Error(`Unsupported format pattern: ${pattern}`);
}
}
@@ -0,0 +1,44 @@
import { preferences } from '@kit.ArkData'
import { ExpertData } from '../models/RequestDefaultModel'
export const AUTH_STORE_KEY = 'perfactAuth'
class PerfactAuth {
store: preferences.Preferences | null = null
getStore() {
if (!this.store) {
this.store = preferences.getPreferencesSync(getContext(), { name: AUTH_STORE_KEY })
}
return this.store
}
async setUser(phone:string,user: ExpertData) {
AppStorage.setOrCreate(phone, user)
await this.getStore().put(phone, JSON.stringify(user))
await this.getStore().flush()
}
async updateUser(phone:string,user: ExpertData) {
AppStorage.setOrCreate(phone, user)
await this.getStore().put(phone, JSON.stringify(user))
await this.getStore().flush()
}
async delUser(phone:string) {
AppStorage.setOrCreate(phone, {})
await this.getStore().put(phone, '{}')
await this.getStore().flush()
}
initUser() {
const json = this.getStore().getSync(AUTH_STORE_KEY, '{}') as string
AppStorage.setOrCreate(AUTH_STORE_KEY, JSON.parse(json))
}
getUser(phone:string) {
return AppStorage.get<ExpertData>(phone) || {} as ExpertData
}
}
export const perfactAuth = new PerfactAuth()
+17
View File
@@ -2,6 +2,7 @@ import { preferences } from '@kit.ArkData'
import { router } from '@kit.ArkUI'
import { Data } from '../models/LoginInfoModel'
import { ExpertData } from '../models/RequestDefaultModel'
import { BusinessError } from '@kit.BasicServicesKit'
export interface HdUser {
id: string
@@ -38,6 +39,18 @@ class AuthStore {
await this.getStore().flush()
}
async setPerfactUser(mobile:string,user:ExpertData) {
AppStorage.setOrCreate('mobile', mobile)
await this.getStore().put(mobile, JSON.stringify(user))
await this.getStore().flush((err:BusinessError)=>{
if (err) {
console.error('保存失败',err.code,err.message)
} else {
console.info('保存成功',JSON.stringify(user))
}
})
}
async delUser() {
AppStorage.setOrCreate('user', {})
await this.getStore().put(AUTH_STORE_KEY, '{}')
@@ -53,6 +66,10 @@ class AuthStore {
return AppStorage.get<Data>('user') || {} as Data
}
getPerfactUser(phone:string) {
return AppStorage.get<ExpertData>(phone) || {} as ExpertData
}
checkAuth(options: router.RouterOptions | Function) {
// if (this.getUser().token) {
// if (typeof options === 'function') {
+1 -1
View File
@@ -150,7 +150,7 @@ class HdHttp {
logger.info('Response httpReq:' + data.result);
let json:TimestampBean = JSON.parse(data.result.toString()) as TimestampBean;
let tp = json.timestamp;
datas.set("user_uuid", authStore.getUser().uuid?authStore.getUser().uuid:'');
datas.set("user_uuid", authStore.getUser().uuid?authStore.getUser().uuid:'5kO57cuAL8seXQpxgtc');
datas.set("client_type", 'A');
datas.set("version",'4.0.0' );
datas.set('timestamp',tp+'');
Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

-6
View File
@@ -1,6 +0,0 @@
/node_modules
/oh_modules
/.preview
/build
/.cxx
/.test
-1
View File
@@ -1 +0,0 @@
export { MainPage } from './src/main/ets/components/MainPage';
-31
View File
@@ -1,31 +0,0 @@
{
"apiType": "stageMode",
"buildOption": {
},
"buildOptionSet": [
{
"name": "release",
"arkOptions": {
"obfuscation": {
"ruleOptions": {
"enable": false,
"files": [
"./obfuscation-rules.txt"
]
},
"consumerFiles": [
"./consumer-rules.txt"
]
}
},
},
],
"targets": [
{
"name": "default"
},
{
"name": "ohosTest"
}
]
}
-6
View File
@@ -1,6 +0,0 @@
import { harTasks } from '@ohos/hvigor-ohos-plugin';
export default {
system: harTasks, /* Built-in plugin of Hvigor. It cannot be modified. */
plugins:[] /* Custom plugin to extend the functionality of Hvigor. */
}
@@ -1,23 +0,0 @@
# Define project specific obfuscation rules here.
# You can include the obfuscation configuration files in the current module's build-profile.json5.
#
# For more details, see
# https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5
# Obfuscation options:
# -disable-obfuscation: disable all obfuscations
# -enable-property-obfuscation: obfuscate the property names
# -enable-toplevel-obfuscation: obfuscate the names in the global scope
# -compact: remove unnecessary blank spaces and all line feeds
# -remove-log: remove all console.* statements
# -print-namecache: print the name cache that contains the mapping from the old names to new names
# -apply-namecache: reuse the given cache file
# Keep options:
# -keep-property-name: specifies property names that you want to keep
# -keep-global-name: specifies names that you want to keep in the global scope
-enable-property-obfuscation
-enable-toplevel-obfuscation
-enable-filename-obfuscation
-enable-export-obfuscation
-9
View File
@@ -1,9 +0,0 @@
{
"name": "uicomponents",
"version": "1.0.0",
"description": "Please describe the basic information.",
"main": "Index.ets",
"author": "",
"license": "Apache-2.0",
"dependencies": {}
}
@@ -1,19 +0,0 @@
@Component
export struct MainPage {
@State message: string = 'Hello World';
build() {
Row() {
Column() {
Text(this.message)
.fontSize($r('app.float.page_text_font_size'))
.fontWeight(FontWeight.Bold)
.onClick(() => {
this.message = 'Welcome';
})
}
.width('100%')
}
.height('100%')
}
}
@@ -1,11 +0,0 @@
{
"module": {
"name": "uicomponents",
"type": "har",
"deviceTypes": [
"default",
"tablet",
"2in1"
]
}
}
@@ -1,8 +0,0 @@
{
"float": [
{
"name": "page_text_font_size",
"value": "50fp"
}
]
}
@@ -1,8 +0,0 @@
{
"string": [
{
"name": "page_show",
"value": "page from package"
}
]
}
@@ -1,35 +0,0 @@
import { hilog } from '@kit.PerformanceAnalysisKit';
import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';
export default function abilityTest() {
describe('ActsAbilityTest', () => {
// Defines a test suite. Two parameters are supported: test suite name and test suite function.
beforeAll(() => {
// Presets an action, which is performed only once before all test cases of the test suite start.
// This API supports only one parameter: preset action function.
})
beforeEach(() => {
// Presets an action, which is performed before each unit test case starts.
// The number of execution times is the same as the number of test cases defined by **it**.
// This API supports only one parameter: preset action function.
})
afterEach(() => {
// Presets a clear action, which is performed after each unit test case ends.
// The number of execution times is the same as the number of test cases defined by **it**.
// This API supports only one parameter: clear action function.
})
afterAll(() => {
// Presets a clear action, which is performed after all test cases of the test suite end.
// This API supports only one parameter: clear action function.
})
it('assertContain', 0, () => {
// Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function.
hilog.info(0x0000, 'testTag', '%{public}s', 'it begin');
let a = 'abc';
let b = 'b';
// Defines a variety of assertion methods, which are used to declare expected boolean conditions.
expect(a).assertContain(b);
expect(a).assertEqual(a);
})
})
}
@@ -1,5 +0,0 @@
import abilityTest from './Ability.test';
export default function testsuite() {
abilityTest();
}
@@ -1,13 +0,0 @@
{
"module": {
"name": "uicomponents_test",
"type": "feature",
"deviceTypes": [
"default",
"tablet",
"2in1"
],
"deliveryWithInstall": true,
"installationFree": false
}
}
@@ -1,5 +0,0 @@
import localUnitTest from './LocalUnit.test';
export default function testsuite() {
localUnitTest();
}
@@ -1,33 +0,0 @@
import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';
export default function localUnitTest() {
describe('localUnitTest', () => {
// Defines a test suite. Two parameters are supported: test suite name and test suite function.
beforeAll(() => {
// Presets an action, which is performed only once before all test cases of the test suite start.
// This API supports only one parameter: preset action function.
});
beforeEach(() => {
// Presets an action, which is performed before each unit test case starts.
// The number of execution times is the same as the number of test cases defined by **it**.
// This API supports only one parameter: preset action function.
});
afterEach(() => {
// Presets a clear action, which is performed after each unit test case ends.
// The number of execution times is the same as the number of test cases defined by **it**.
// This API supports only one parameter: clear action function.
});
afterAll(() => {
// Presets a clear action, which is performed after all test cases of the test suite end.
// This API supports only one parameter: clear action function.
});
it('assertContain', 0, () => {
// Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function.
let a = 'abc';
let b = 'b';
// Defines a variety of assertion methods, which are used to declare expected boolean conditions.
expect(a).assertContain(b);
expect(a).assertEqual(a);
});
});
}
-6
View File
@@ -1,6 +0,0 @@
/node_modules
/oh_modules
/.preview
/build
/.cxx
/.test
-17
View File
@@ -1,17 +0,0 @@
/**
* Use these variables when you tailor your ArkTS code. They must be of the const type.
*/
export const HAR_VERSION = '1.0.0';
export const BUILD_MODE_NAME = 'debug';
export const DEBUG = true;
export const TARGET_NAME = 'default';
/**
* BuildProfile Class is used only for compatibility purposes.
*/
export default class BuildProfile {
static readonly HAR_VERSION = HAR_VERSION;
static readonly BUILD_MODE_NAME = BUILD_MODE_NAME;
static readonly DEBUG = DEBUG;
static readonly TARGET_NAME = TARGET_NAME;
}
-4
View File
@@ -1,4 +0,0 @@
export { logger } from './src/main/ets/request/logger'
export { Base64Util } from './src/main/ets/request/Base64Util'
export { HdResponse } from './src/main/ets/request/request'
export { ChangeUtil } from './src/main/ets/request/ChangeUtil'
-31
View File
@@ -1,31 +0,0 @@
{
"apiType": "stageMode",
"buildOption": {
},
"buildOptionSet": [
{
"name": "release",
"arkOptions": {
"obfuscation": {
"ruleOptions": {
"enable": false,
"files": [
"./obfuscation-rules.txt"
]
},
"consumerFiles": [
"./consumer-rules.txt"
]
}
},
},
],
"targets": [
{
"name": "default"
},
{
"name": "ohosTest"
}
]
}
View File
-6
View File
@@ -1,6 +0,0 @@
import { harTasks } from '@ohos/hvigor-ohos-plugin';
export default {
system: harTasks, /* Built-in plugin of Hvigor. It cannot be modified. */
plugins:[] /* Custom plugin to extend the functionality of Hvigor. */
}
-23
View File
@@ -1,23 +0,0 @@
# Define project specific obfuscation rules here.
# You can include the obfuscation configuration files in the current module's build-profile.json5.
#
# For more details, see
# https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5
# Obfuscation options:
# -disable-obfuscation: disable all obfuscations
# -enable-property-obfuscation: obfuscate the property names
# -enable-toplevel-obfuscation: obfuscate the names in the global scope
# -compact: remove unnecessary blank spaces and all line feeds
# -remove-log: remove all console.* statements
# -print-namecache: print the name cache that contains the mapping from the old names to new names
# -apply-namecache: reuse the given cache file
# Keep options:
# -keep-property-name: specifies property names that you want to keep
# -keep-global-name: specifies names that you want to keep in the global scope
-enable-property-obfuscation
-enable-toplevel-obfuscation
-enable-filename-obfuscation
-enable-export-obfuscation
-19
View File
@@ -1,19 +0,0 @@
{
"meta": {
"stableOrder": true
},
"lockfileVersion": 3,
"ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.",
"specifiers": {
"@ohos/crypto-js@^2.0.4": "@ohos/crypto-js@2.0.4"
},
"packages": {
"@ohos/crypto-js@2.0.4": {
"name": "@ohos/crypto-js",
"version": "2.0.4",
"integrity": "sha512-589ur6oqU1UNibqefMly2cwEeEhkSoCAA3uc+oNUwRnYYtevn/kQnO+Coi36N+VJSeeg/uFzZk1K/wUMdovpOA==",
"resolved": "https://repo.harmonyos.com/ohpm/@ohos/crypto-js/-/crypto-js-2.0.4.har",
"registryType": "ohpm"
}
}
}
-13
View File
@@ -1,13 +0,0 @@
{
"name": "utils",
"version": "1.0.0",
"description": "Please describe the basic information.",
"main": "Index.ets",
"author": "",
"license": "Apache-2.0",
"dependencies": {
"@ohos/crypto-js": "^2.0.4"
},
"devDependencies": {},
"dynamicDependencies": {}
}
@@ -1,84 +0,0 @@
import util from '@ohos.util';
import { buffer } from '@kit.ArkTS';
/**
* Base64 工具类
* author: 鸿蒙布道师
* since: 2025/03/31
*/
export class Base64Util {
/**
* 创建 Base64Helper 实例
* @returns Base64Helper 实例
*/
private static createBase64Helper(): util.Base64Helper {
return new util.Base64Helper();
}
/**
* 编码为 Uint8Array(异步)
* @param array 输入的 Uint8Array 数据
* @returns 编码后的 Uint8Array 对象
*/
static encode(array: Uint8Array): Promise<Uint8Array> {
const base64 = Base64Util.createBase64Helper();
return base64.encode(array);
}
/**
* 编码为 Uint8Array(同步)
* @param array 输入的 Uint8Array 数据
* @returns 编码后的 Uint8Array 对象
*/
static encodeSync(array: Uint8Array): Uint8Array {
const base64 = Base64Util.createBase64Helper();
return base64.encodeSync(array);
}
/**
* 编码为字符串(异步)
* @param array 输入的 Uint8Array 数据
* @param options 可选参数
* @returns 编码后的字符串
*/
static encodeToStr(array: Uint8Array, options?: util.Type): Promise<string> {
const base64 = Base64Util.createBase64Helper();
return base64.encodeToString(array, options);
}
/**
* 编码为字符串(同步)
* @param array 输入的 Uint8Array 数据
* @param options 可选参数
* @returns 编码后的字符串
*/
static encodeToStrSync(keyValueStr:string): string {
let array: Uint8Array=new Uint8Array(buffer.from(keyValueStr, 'utf-8').buffer)
const base64 = Base64Util.createBase64Helper();
return base64.encodeToStringSync(array, util.Type.BASIC).replaceAll("=", "");
}
/**
* 解码为 Uint8Array(异步)
* @param input 输入的 Uint8Array 或字符串
* @param options 可选参数
* @returns 解码后的 Uint8Array 对象
*/
static decode(input: Uint8Array | string, options?: util.Type): Promise<Uint8Array> {
const base64 = Base64Util.createBase64Helper();
return base64.decode(input, options);
}
/**
* 解码为 Uint8Array(同步)
* @param input 输入的 Uint8Array 或字符串
* @param options 可选参数
* @returns 解码后的 Uint8Array 对象
*/
static decodeSync(input: Uint8Array | string, options?: util.Type): Uint8Array {
const base64 = Base64Util.createBase64Helper();
return base64.decodeSync(input, options);
}
}
@@ -1,61 +0,0 @@
import HashMap from '@ohos.util.HashMap';
import { Base64Util } from './Base64Util';
export class ChangeUtil {
/**
* 将HashMap转成JsonString
* @param map
* @returns
*/
static map2Json(map:HashMap<string, string>): string {
let jsonObject: Record<string, Object> = {};
map.forEach((value, key) => {
if(key != undefined && value != undefined){
jsonObject[key] = value;
}
})
return JSON.stringify(jsonObject);
}
static getSign(extraDatas1:HashMap<string, string>): string {
let secret= extraDatas1.get("timestamp")
if(secret!=null) {
let keyValueStr: string = "";
let entriesArray: Array<string> = Array.from(extraDatas1.keys());
entriesArray.sort();
let sortedMap:HashMap<string, string> = new HashMap();
entriesArray.forEach((value: string, index: number) => {
sortedMap.set(value,extraDatas1.get(value));
keyValueStr +=value+extraDatas1.get(value)
});
keyValueStr = keyValueStr.replace(" ", "");
keyValueStr = keyValueStr + CryptoJS.MD5(secret).toString();
let Md5keyValueStr: string = CryptoJS.MD5(keyValueStr).toString();
let base64Str:string=Base64Util.encodeToStrSync(Md5keyValueStr);
return base64Str;
}
else
{
return '';
}
}
static isMobileNum(mobiles:string): boolean {
const reg2: RegExp = new RegExp('^(1[3-9])[0-9]{9}$')
return reg2.test(mobiles);
}
static isPassword(password:string): boolean {
const reg2: RegExp = new RegExp('^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,16}$')
return reg2.test(password);
}
}
@@ -1,33 +0,0 @@
import hilog from '@ohos.hilog'
const DOMAIN = 0xFF09
const PREFIX = 'PASS_INTERVIEW_LOGGER'
const FORMAT = '%{public}s, %{public}s'
class Logger {
debug(...args: string[]) {
hilog.debug(DOMAIN, PREFIX, FORMAT, args)
}
info(...args: string[]) {
hilog.info(DOMAIN, PREFIX, FORMAT, args)
}
warn(...args: string[]) {
hilog.warn(DOMAIN, PREFIX, FORMAT, args)
}
error(...args: string[]) {
hilog.error(DOMAIN, PREFIX, FORMAT, args)
}
fatal(...args: string[]) {
hilog.fatal(DOMAIN, PREFIX, FORMAT, args)
}
isLoggable(level: hilog.LogLevel) {
hilog.isLoggable(DOMAIN, PREFIX, level)
}
}
export const logger = new Logger()
@@ -1,288 +0,0 @@
import { http } from '@kit.NetworkKit';
import { promptAction, router } from '@kit.ArkUI';
import { BusinessError } from '@ohos.base';
import { HashMap } from '@kit.ArkTS';
import { CryptoJS } from '@ohos/crypto-js'
import { Base64Util } from './Base64Util';
import { ChangeUtil } from './ChangeUtil'
import { logger } from './logger'
interface HdRequestOptions {
baseURL?: string
}
type HdParams = Record<string, string | number | boolean>
export interface HdResponse<T> {
code: number
message: string
data: T
}
export interface TimestampBean {
timestamp:string
}
class HdHttp {
baseURL: string
constructor(options: HdRequestOptions) {
this.baseURL = options.baseURL || ''
}
private request1<T>(path: string, method: http.RequestMethod = http.RequestMethod.GET, extraDatas:HashMap<string, string>) {
const httpInstance = http.createHttp()
let fullUrl = this.baseURL + path
let promise = httpInstance.request(
// 请求url地址
fullUrl,
{
// 请求方式
method: http.RequestMethod.POST,
// 可选,默认为60s
connectTimeout: 60000,
// 可选,默认为60s
readTimeout: 60000,
// 开发者根据自身业务需要添加header字段
header: {
'Content-Type': 'application/json',
'sign':this.getSign(extraDatas)
},
extraData:ChangeUtil.map2Json(extraDatas)
});
logger.info('Response JSON.stringify(extraDatas)' + ChangeUtil.map2Json(extraDatas))
return promise.then((data) => {
logger.info('Response request:' + data.result);
if (data.result) {
const result = data.result as HdResponse<T>
logger.info('Response result:' + result);
return result
}
return Promise.reject(data.result)
// if (data.responseCode === http.ResponseCode.OK) {
// console.info('Response request:' + data.result);
//
// }
// else
// {
//
// }
// return Promise.reject(data.result)
}
).catch((err:BusinessError) => {
logger.info('Response httpReq request:' + JSON.stringify(err));
return Promise.reject(err)
}).finally(() => {
httpInstance.destroy()
})
}
private request<T>(path: string, method: http.RequestMethod = http.RequestMethod.POST, extraDatas :HashMap<string, string>) {
const httpInstance = http.createHttp()
const options: http.HttpRequestOptions = {
method: http.RequestMethod.POST,
// 可选,默认为60s
connectTimeout: 60000,
// 可选,默认为60s
readTimeout: 60000,
// 开发者根据自身业务需要添加header字段
header: {
'Content-Type': 'application/json',
'sign':this.getSign(extraDatas)
},
extraData:ChangeUtil.map2Json(extraDatas)
}
let fullUrl = this.baseURL + path
return httpInstance.request(fullUrl, options).then((res) => {
logger.info('Response fullUrl:' +fullUrl+ res.result);
const result = res.result as HdResponse<T>
return result
}).catch((err: BusinessError) => {
logger.info(fullUrl+`Response succeeded: ${err}`);
promptAction.showToast({ message: err.message || '网络错误' })
return Promise.reject(err)
}).finally(() => {
httpInstance.destroy()
})
}
private requestafter<T>(path: string, method: http.RequestMethod = http.RequestMethod.GET, extraData?: Object) {
const httpInstance = http.createHttp()
const options: http.HttpRequestOptions = {
method: http.RequestMethod.GET,
// 可选,默认为60s
connectTimeout: 60000,
// 可选,默认为60s
readTimeout: 60000,
// 开发者根据自身业务需要添加header字段
header: {
'Content-Type': 'application/json'
}
}
let fullUrl = this.baseURL + path
if (method === http.RequestMethod.GET && extraData) {
const strArr = Object.keys(extraData)
.filter(key => (extraData as HdParams)[key] !== undefined)
.map(key => `${key}=${(extraData as HdParams)[key]}`)
fullUrl += `?${strArr.join('&')}`
} else {
options.extraData = extraData
}
return httpInstance.request(fullUrl, options).then((res) => {
return Promise.reject(res.result)
}).catch((err: BusinessError) => {
logger.error(fullUrl+`Response succeeded: ${err}+${err.name}+${err.message}+${err.data}+${err.stack}`);
// logger.error(fullUrl, err.code?.toString(), err.message)
promptAction.showToast({ message: err.message || '网络错误' })
return Promise.reject(err)
}).finally(() => {
httpInstance.destroy()
})
}
get<T>(url: string, data?: Object): Promise<HdResponse<T>> {
return this.requestafter<T>(url, http.RequestMethod.GET, data)
}
post<T>(url: string, data?: Object): Promise<HdResponse<T>> {
return this.requestafter<T>(url, http.RequestMethod.POST, data)
}
put<T>(url: string, data?: Object): Promise<HdResponse<T>> {
return this.requestafter<T>(url, http.RequestMethod.PUT, data)
}
delete<T>(url: string, data?: Object): Promise<HdResponse<T>> {
return this.requestafter<T>(url, http.RequestMethod.DELETE, data)
}
posts<T>(url: string, data: HashMap<string, string>): Promise<HdResponse<T>> {
return this.request<T>(url, http.RequestMethod.POST, data)
}
httpReq<T>(url: string, datas: HashMap<string, string>): Promise<HdResponse<T>> {
// 创建httpRequest对象。
let httpRequest = http.createHttp();
let url1 = "https://dev-app.igandan.com/app/manager/getSystemTimeStamp";
let promise = httpRequest.request(
// 请求url地址
url1,
{
// 请求方式
method: http.RequestMethod.GET,
// 可选,默认为60s
connectTimeout: 60000,
// 可选,默认为60s
readTimeout: 60000,
// 开发者根据自身业务需要添加header字段
header: {
'Content-Type': 'application/json'
}
});
// 处理响应结果。
return promise.then((data) => {
if (data.responseCode === http.ResponseCode.OK) {
logger.info('Response httpReq:' + data.result);
let json:TimestampBean = JSON.parse(data.result.toString()) as TimestampBean;
let tp = json.timestamp;
datas.set("user_uuid", '');
datas.set("client_type", 'A');
datas.set("version",'4.0.0' );
datas.set('timestamp',tp+'');
return this.posts<T>(url, datas);
}
else
{
return this.posts<T>(url, datas);
}
}
).catch((err:BusinessError) => {
logger.info('Response httpReq error:' + JSON.stringify(err));
return Promise.reject(err);
}).finally(() => {
httpRequest.destroy()
})
}
httpReqSimply<T>(url: string) {
// 创建httpRequest对象。
let httpRequest = http.createHttp();
let promise = httpRequest.request(
// 请求url地址
url,
{
// 请求方式
method: http.RequestMethod.POST,
// 可选,默认为60s
connectTimeout: 60000,
// 可选,默认为60s
readTimeout: 60000,
// 开发者根据自身业务需要添加header字段
header: {
'Content-Type': 'application/json'
}
});
// 处理响应结果。
return promise.then((data) => {
logger.info('Response httpReqSimply:' + JSON.stringify(data));
const result = data.result as HdResponse<T>
return result
}
).catch((err:BusinessError) => {
logger.info('Response httpReq error:' + JSON.stringify(err));
return Promise.reject(err);
}).finally(() => {
httpRequest.destroy()
})
}
getSign(extraDatas1:HashMap<string, string>): string {
let secret= extraDatas1.get("timestamp")
if(secret!=null) {
let keyValueStr: string = "";
let entriesArray: Array<string> = Array.from(extraDatas1.keys());
entriesArray.sort();
let sortedMap:HashMap<string, string> = new HashMap();
entriesArray.forEach((value: string, index: number) => {
sortedMap.set(value,extraDatas1.get(value));
keyValueStr +=value+extraDatas1.get(value)
});
keyValueStr = keyValueStr.replace(" ", "");
keyValueStr = keyValueStr + CryptoJS.MD5(secret).toString();
let Md5keyValueStr: string = CryptoJS.MD5(keyValueStr).toString();
let base64Str:string=Base64Util.encodeToStrSync(Md5keyValueStr);
return base64Str;
}
else
{
return '';
}
}
}
export const hdHttp = new HdHttp({ baseURL: '' })
-11
View File
@@ -1,11 +0,0 @@
{
"module": {
"name": "utils",
"type": "har",
"deviceTypes": [
"default",
"tablet",
"2in1"
]
}
}
@@ -1,8 +0,0 @@
{
"float": [
{
"name": "page_text_font_size",
"value": "50fp"
}
]
}
@@ -1,8 +0,0 @@
{
"string": [
{
"name": "page_show",
"value": "page from package"
}
]
}
@@ -1,35 +0,0 @@
import { hilog } from '@kit.PerformanceAnalysisKit';
import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';
export default function abilityTest() {
describe('ActsAbilityTest', () => {
// Defines a test suite. Two parameters are supported: test suite name and test suite function.
beforeAll(() => {
// Presets an action, which is performed only once before all test cases of the test suite start.
// This API supports only one parameter: preset action function.
})
beforeEach(() => {
// Presets an action, which is performed before each unit test case starts.
// The number of execution times is the same as the number of test cases defined by **it**.
// This API supports only one parameter: preset action function.
})
afterEach(() => {
// Presets a clear action, which is performed after each unit test case ends.
// The number of execution times is the same as the number of test cases defined by **it**.
// This API supports only one parameter: clear action function.
})
afterAll(() => {
// Presets a clear action, which is performed after all test cases of the test suite end.
// This API supports only one parameter: clear action function.
})
it('assertContain', 0, () => {
// Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function.
hilog.info(0x0000, 'testTag', '%{public}s', 'it begin');
let a = 'abc';
let b = 'b';
// Defines a variety of assertion methods, which are used to declare expected boolean conditions.
expect(a).assertContain(b);
expect(a).assertEqual(a);
})
})
}
@@ -1,5 +0,0 @@
import abilityTest from './Ability.test';
export default function testsuite() {
abilityTest();
}
-13
View File
@@ -1,13 +0,0 @@
{
"module": {
"name": "utils_test",
"type": "feature",
"deviceTypes": [
"default",
"tablet",
"2in1"
],
"deliveryWithInstall": true,
"installationFree": false
}
}
-5
View File
@@ -1,5 +0,0 @@
import localUnitTest from './LocalUnit.test';
export default function testsuite() {
localUnitTest();
}
-33
View File
@@ -1,33 +0,0 @@
import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';
export default function localUnitTest() {
describe('localUnitTest', () => {
// Defines a test suite. Two parameters are supported: test suite name and test suite function.
beforeAll(() => {
// Presets an action, which is performed only once before all test cases of the test suite start.
// This API supports only one parameter: preset action function.
});
beforeEach(() => {
// Presets an action, which is performed before each unit test case starts.
// The number of execution times is the same as the number of test cases defined by **it**.
// This API supports only one parameter: preset action function.
});
afterEach(() => {
// Presets a clear action, which is performed after each unit test case ends.
// The number of execution times is the same as the number of test cases defined by **it**.
// This API supports only one parameter: clear action function.
});
afterAll(() => {
// Presets a clear action, which is performed after all test cases of the test suite end.
// This API supports only one parameter: clear action function.
});
it('assertContain', 0, () => {
// Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function.
let a = 'abc';
let b = 'b';
// Defines a variety of assertion methods, which are used to declare expected boolean conditions.
expect(a).assertContain(b);
expect(a).assertEqual(a);
});
});
}