1.2.0部分代码

This commit is contained in:
xiaoxiao 2025-08-27 16:11:20 +08:00
parent ca7d1dd379
commit e89a5f15ce
74 changed files with 2704 additions and 192 deletions

View File

@ -2,8 +2,8 @@
"app": {
"bundleName": "cn.shangyu.gdxzExports",
"vendor": "example",
"versionCode": 1000000,
"versionName": "1.0.0",
"versionCode": 1000003,
"versionName": "1.1.0",
"icon": "$media:layered_image",
"label": "$string:app_name"
}

View File

@ -109,4 +109,8 @@ export { customAttachment } from './src/main/ets/models/customAttachment'
export { ImageUtil } from './src/main/ets/utils/ImageUtil'
export { compressedImage,saveImageToGallery,CompressedImageInfo } from './src/main/ets/utils/ImageCompressUtils'
export { compressedImage,saveImageToGallery,CompressedImageInfo } from './src/main/ets/utils/ImageCompressUtils'
export { ScreeningView } from './src/main/ets/Views/ScreeningView'
export { TagListModel, TagList} from './src/main/ets/models/TagListModel'

View File

@ -0,0 +1,107 @@
import { TagList, TagListModel } from "../models/TagListModel";
import { promptAction } from "@kit.ArkUI";
import { HashMap } from "@kit.ArkTS";
import { BusinessError } from "@kit.BasicServicesKit";
import { hdHttp, HdResponse } from "../utils/request";
import { BasicConstant } from "../constants/BasicConstant";
@Component
export struct ScreeningView {
@State tags:TagList[] = []
@Prop selectedArray:TagList[] = []
@Prop type:string = '0'
private isSelectedItem?: (value: TagList[]) => void;
aboutToAppear(): void {
let hashMap: HashMap<string, string> = new HashMap();
hdHttp.post<string>(BasicConstant.tagList,{
type:this.type
} as TagModel).then(async (res: HdResponse<string>) => {
let json:TagListModel = JSON.parse(res+'') as TagListModel;
if (json.code == '1') {
this.tags = json.data
}
}).catch((err: BusinessError) => {
console.error('Response tagList'+err)
})
}
build() {
Column() {
Grid() {
ForEach(this.tags, (item: TagList, index: number) => {
GridItem() {
Text(item.NAME)
.height(25)
.width('100%')
.padding({left:5,right:5})
.fontWeight(FontWeight.Regular)
.fontSize(13)
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.fontColor(this.selectedArray.some(selected=>selected.ID === item.ID)?$r('app.color.top_title'): $r('app.color.999999'))
// .fontColor(this.selectedArray.indexOf(item)!=-1 ? $r('app.color.top_title'): $r('app.color.999999'))
.textAlign(TextAlign.Center)
.border({ width: 1, color:this.selectedArray.some(selected=>selected.ID === item.ID)? $r('app.color.top_title'): '#999999' })
.borderRadius(30)
.onClick(() => {
const targetIndex = this.selectedArray.findIndex(
selected => selected.ID === item.ID
);
if(targetIndex !== -1) {
const newSelected = [...this.selectedArray];
newSelected.splice(targetIndex, 1);
this.selectedArray = newSelected;
} else {
if (this.selectedArray.length >= 3) {
promptAction.showToast({ message: '最多选择三个标签!', duration: 1000 });
return;
}
this.selectedArray.push(item)
}
})
}
})
}
.padding(10)
.columnsTemplate('1fr 1fr 1fr 1fr')
.columnsGap(10)
.rowsGap(10)
.backgroundColor(Color.White)
.height('100%')
.width('100%')
.layoutWeight(1)
Row() {
Text('重置').height(40)
.textAlign(TextAlign.Center)
.fontColor($r('app.color.top_title') )
.border({ width: 1, color: $r('app.color.top_title') })
.borderRadius(5)
.layoutWeight(1)
.margin({left:15})
.onClick(()=>{
this.selectedArray= [];
})
Text('确定')
.height(40)
.fontColor(Color.White).textAlign(TextAlign.Center)
.border({ width: 1, color: $r('app.color.top_title') })
.borderRadius(5)
.layoutWeight(1)
.backgroundColor($r('app.color.top_title'))
.margin({left:10,right:15})
.onClick(()=>{
this.isSelectedItem?.(this.selectedArray)
})
}.width('100%')
.height(60)
.backgroundColor(Color.White)
}
.width('100%')
.height('100%')
}
}
interface TagModel {
type:string
}

View File

@ -22,8 +22,12 @@ export struct HdNav {
@Prop
rightIcon: ResourceStr = $r('sys.media.ohos_ic_public_more')
@Prop
twoRightIcon: ResourceStr = $r('sys.media.ohos_ic_public_more')
@Prop
showRightIcon: boolean = true
@Prop
showTwoRightItem: boolean = false
@Prop
showLeftIcon: boolean = true
@Prop
showRightText: boolean = false
@ -41,6 +45,8 @@ export struct HdNav {
isLeftAction: boolean = false
// 添加右侧点击函数
private rightItemAction:()=> void = () => {};
// 添加右侧第二个按钮的点击函数
private twoRightItemAction:()=> void = () => {};
// 添加左侧点击函数
private leftItemAction:()=> void = () => {};
@ -74,20 +80,29 @@ export struct HdNav {
this.titleBuilder()
}
}
.margin({left:this.showTwoRightItem?20:0})
.height(56)
.width(150)
.layoutWeight(1)
if (this.showRightIcon) {
Row()
{
Row() {
Image(this.rightIcon)
.size({ width: 24, height: 24 })
.objectFit(ImageFit.Contain)
.bindMenu(this.menuBuilder)
.onClick(()=>this.rightItemAction())
if (this.showTwoRightItem) {
Image(this.twoRightIcon)
.margin({left:15})
.size({ width: 24, height: 24 })
.objectFit(ImageFit.Contain)
.bindMenu(this.menuBuilder)
.onClick(()=>this.twoRightItemAction())
}
}
.size({ width: 50, height: 50 }).justifyContent(FlexAlign.End)
.size(this.showTwoRightItem?{width:70,height:50}:{ width: 50, height: 50 })
.justifyContent(FlexAlign.End)
} else if (this.showRightText) {
Text(this.rightText)

View File

@ -6,27 +6,28 @@ export class BasicConstant {
static readonly getzcxy = "https://doc.igandan.com/app/integral/hmos_expert_zcxy.html";// 注册协议正式地址
//测试环境
// static readonly urlExpertAPI = "https://dev-app.igandan.com/app/expertAPI/";
// static readonly urlExpertApp = "https://dev-app.igandan.com/app/expertApp/"
// static readonly urlHtml = "http://dev-doc.igandan.com/app/"
// static readonly urlImage = "https://dev-doc.igandan.com/app/"
// static readonly urlExpert = "https://dev-app.igandan.com/app/expert/"
// static readonly wxUrl = "https://dev-wx.igandan.com/";
// static readonly polvId = "11";//保利威视学员id
// static readonly urlApp="https://dev-app.igandan.com/app/"
static readonly urlExpertAPI = "https://dev-app.igandan.com/app/expertAPI/";
static readonly urlExpertApp = "https://dev-app.igandan.com/app/expertApp/"
static readonly urlHtml = "http://dev-doc.igandan.com/app/"
static readonly urlImage = "https://dev-doc.igandan.com/app/"
static readonly urlExpert = "https://dev-app.igandan.com/app/expert/"
static readonly wxUrl = "https://dev-wx.igandan.com/";
static readonly polvId = "11";//保利威视学员id
static readonly urlApp="https://dev-app.igandan.com/app/"
//正式环境
static readonly urlExpertAPI = "https://app.igandan.com/app/expertAPI/";
static readonly urlExpertApp = "http://app.igandan.com/app/expertApp/"
static readonly urlHtml = "http://doc.igandan.com/app/"
static readonly urlImage = "http://doc.igandan.com/app/"
static readonly urlExpert = "http://app.igandan.com/app/expert/"
static readonly wxUrl = "https://wx.igandan.com/";// 微信服务器地址
static readonly polvId = "21";//保利威视学员id
static readonly urlApp="http://app.igandan.com/app/"
// static readonly urlExpertAPI = "https://app.igandan.com/app/expertAPI/";
// static readonly urlExpertApp = "http://app.igandan.com/app/expertApp/"
// static readonly urlHtml = "http://doc.igandan.com/app/"
// static readonly urlImage = "http://doc.igandan.com/app/"
// static readonly urlExpert = "http://app.igandan.com/app/expert/"
// static readonly wxUrl = "https://wx.igandan.com/";// 微信服务器地址
// static readonly polvId = "21";//保利威视学员id
// static readonly urlApp="http://app.igandan.com/app/"
static readonly getSystemTimeStamp = BasicConstant.urlApp+'manager/getSystemTimeStamp'
static readonly addBonusPoints = BasicConstant.urlExpertApp+'addBonusPoints'
static readonly indexV2 = BasicConstant.urlExpertAPI+'indexV2';//首页轮播
static readonly getAppActivity = BasicConstant.urlExpertAPI+'getAppActivity'
static readonly applyList = BasicConstant.urlExpert+'applyList'
static readonly groupList = BasicConstant.urlExpertApp+'groupList'
static readonly isMaiLanExpert = BasicConstant.urlExpertAPI+'isMaiLanExpert'
@ -72,7 +73,11 @@ export class BasicConstant {
static readonly meetingHistoryList = BasicConstant.urlExpertAPI + "meetingHistoryList";
static readonly videoRoll = BasicConstant.urlExpertAPI + "videoRoll";
static readonly expertVideoTypeList = BasicConstant.urlExpertAPI + "expertVideoTypeList";
static readonly patientVideoNew = BasicConstant.urlExpertApp + 'patientVideoNew';
static readonly videoByKeyWordsNew = BasicConstant.urlExpertApp + "videoByKeyWordsNew";
static readonly patientVideoByKeyWordsNew = BasicConstant.urlExpertApp + 'patientVideoByKeyWordsNew'
static readonly feedBack = BasicConstant.urlExpert+'feedBack'
static readonly ganDanFileByKeyWords = BasicConstant.urlExpertAPI+'ganDanFileByKeyWords'//肝胆课件
static readonly tagList = BasicConstant.urlExpertApp + "tagList";
static readonly meetingListBySearch = BasicConstant.urlExpertAPI + "meetingListBySearch";
static readonly videoBySearchNew = BasicConstant.urlExpertApp+'videoBySearchNew';//搜索肝胆视频列表

View File

@ -52,7 +52,9 @@ export interface Data{
state:number;
realName:string;
specialy:Array<object>;
special:SpecialDisease[];
YX_accid:string;
YX_token:string
}
export interface BaseBean{

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,3 @@
-keep-file-name
-keep-property-name
-keep-global-name

View File

@ -0,0 +1,3 @@
-keep-file-name
-keep-property-name
-keep-global-name

View File

@ -30,4 +30,6 @@ export { VideoSelected } from './src/main/ets/pages/VideoSelected'
export { videoTools } from './src/main/ets/polyv/VideoUtil'
export { CustomScanResultComp }from './src/main/ets/components/CustomScanResultComp'
export { CustomScanResultComp }from './src/main/ets/components/CustomScanResultComp'
export { EducationVideo } from './src/main/ets/pages/EducationVideo'

View File

@ -6,6 +6,7 @@ import { router } from '@kit.ArkUI'
export struct HomeSwiperComp {
@Prop newslist: newsModel[];
@Prop expertData:expertDetailModel;
@State isSuccessImage:boolean = false
build() {
Column() {
@ -13,17 +14,21 @@ export struct HomeSwiperComp {
ForEach(this.newslist, (item: newsModel,index:number) => {
Stack({alignContent:Alignment.Center}) {
Image(item.headImg)
.alt($r('app.media.home_top_scroll_default'))
.objectFit(ImageFit.Fill)// 图片填充模式
.onComplete(() => {
this.isSuccessImage = true
})
.width('100%').height('100%')
if (index == 0) {
Column({space:5}){
Text(this.expertData.realName+'专家工作室')
.fontSize(19)
.fontColor(Color.White)
.fontColor(this.isSuccessImage?Color.White:Color.Black)
.margin({left:20,top:60})
Text(this.expertData.hospitalName)
.fontSize(16)
.fontColor(Color.White)
.fontColor(this.isSuccessImage?Color.White:Color.Black)
.margin({left:20})
}.width('100%').alignItems(HorizontalAlign.Start)
}

View File

@ -12,6 +12,7 @@ export struct ListCompGandan {
@State isEmptyViewVisible: boolean = false; // 控制显隐的状态变量
@Prop@Watch('onUpdate') sort:string='2'
@Prop pageType:string = ''
// @Consume@Watch('gotoTop')
// toTop:boolean;
@Prop@Watch('onUpdate')
@ -67,7 +68,7 @@ export struct ListCompGandan {
this.hashMap.set('page', this.page+"")
this.hashMap.set("sort", this.sort);
this.hashMap.set('typeUuid', this.type_uuid)
hdHttp.httpReq<string>(BasicConstant.videoByKeyWordsNew,this.hashMap).then(async (res: HdResponse<string>) => {
hdHttp.httpReq<string>(this.pageType=='患教视频'?BasicConstant.patientVideoByKeyWordsNew:BasicConstant.videoByKeyWordsNew,this.hashMap).then(async (res: HdResponse<string>) => {
logger.info('Response videoByTypeNew'+res);
let json:VideoMoreModel = JSON.parse(res+'') as VideoMoreModel;
this.dialog.close()

View File

@ -19,10 +19,13 @@ import { BusinessError } from '@kit.BasicServicesKit';
import { VideoTypeModel,TypeList,VideoType } from '../model/VideoTypeModel'
import { ArrayList } from '@kit.ArkTS';
import { ListCompGandan } from '../components/ListCompGandan'
import { TagListModel,TagList } from '../model/TagListModel'
import { TagListModel,TagList } from '@itcast/basic/src/main/ets/models/TagListModel'
import { promptAction } from '@kit.ArkUI'
import { it } from '@ohos/hypium';
@Component
export struct SecondaryLink {
@Prop pageType:string = ''
@State currentTagIndex: number = 0; // 一级列表焦点索引值
@State currentTagIndex2: number = -1; // 2级列表焦点索引值
@State private tagLists:VideoType[] = []; // 一级列表数据
@ -112,7 +115,7 @@ export struct SecondaryLink {
Row().height(10).width('100%') .backgroundColor('#efefef')
Stack({alignContent:Alignment.Top})
{
ListCompGandan({ sort:this.sort,type_uuid:this.type_uuid,keywords:this.keywords}).padding({left:10,right:10})
ListCompGandan({ pageType:this.pageType,sort:this.sort,type_uuid:this.type_uuid,keywords:this.keywords}).padding({left:10,right:10})
if(this.isOpenSelect1)
{
Column()
@ -126,6 +129,8 @@ export struct SecondaryLink {
.padding({left:5,right:5})
.fontWeight(FontWeight.Regular)
.fontSize(13)
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.fontColor(this.tagPosition.indexOf(item)!=-1 ? $r('app.color.top_title'): $r('app.color.848284'))
.textAlign(TextAlign.Center)
.border({ width: 1, color:this.tagPosition.indexOf(item)!=-1 ? $r('app.color.top_title'): '#999999' })
@ -213,76 +218,110 @@ export struct SecondaryLink {
}
if(this.isOpenSelect)
{
Row() {
// TODO:知识点: 2.一级列表绑定Scroller对象
List() {
// 性能知识点此处为横向列表列表项确定且数量较少使用了ForEach在列表项多的情况下推荐使用LazyForeEach
ForEach(this.tagLists, (item: VideoType, index: number) => {
ListItem() {
Text(item.name)
.width('100%')
.padding(10)
.fontWeight(FontWeight.Regular)
.fontSize(15)
.fontColor(this.currentTagIndex === index ? $r('app.color.top_title'): $r('app.color.848284'))
.textAlign(TextAlign.Center)
.backgroundColor(this.currentTagIndex === index ? $r('sys.color.ohos_id_color_background') : '')
.onClick(() => {
this.currentTagIndex = index;
this.contentData=this.arrayList[index];
})
}
})
}
.backgroundColor('#efefef')
.width('27%')
.height('100%')
// 二级列表
List() {
if(this.currentTagIndex==0)
{
ListItem() {
Row() {
Text('全部视频')
.fontSize(15)
.padding(10)
.fontColor(this.currentTagIndex2 === -2 ? $r('app.color.top_title'): $r('app.color.848284'))
if (this.pageType == '患教视频') {
Row() {
List() {
ForEach(this.tagLists, (item: VideoType, index: number) => {
ListItem() {
Column() {
Text(item.name)
.width('100%')
.padding(10)
.fontWeight(FontWeight.Regular)
.fontSize(15)
.fontColor(this.currentTagIndex === index ? $r('app.color.top_title') : Color.Gray)
.onClick(() => {
this.currentTagIndex = index;
this.videoTitle = item.name
this.type_uuid = item.uuid
this.changeSelectRescourse()
})
Blank()
.width('95%')
.height(0.5)
.backgroundColor(Color.Gray)
.margin({left:10,right:10})
}
}
}.onClick(()=>{
this.videoTitle='全部视频'
this.currentTagIndex2=-2
this.changeSelectRescourse()
this.type_uuid=''
})
}
ForEach(this.contentData, (item: TypeList,index: number) => {
ListItem() {
Row() {
.backgroundColor(Color.White)
.width('100%')
.height('100%')
}.width('100%').alignItems(VerticalAlign.Top)
} else {
Row() {
// TODO:知识点: 2.一级列表绑定Scroller对象
List() {
// 性能知识点此处为横向列表列表项确定且数量较少使用了ForEach在列表项多的情况下推荐使用LazyForeEach
ForEach(this.tagLists, (item: VideoType, index: number) => {
ListItem() {
Text(item.name)
.fontSize(15)
.width('100%')
.padding(10)
.fontColor(this.currentTagIndex2 === index&& this.videoTitle==item.name ? $r('app.color.top_title'): $r('app.color.848284'))
.fontWeight(FontWeight.Regular)
.fontSize(15)
.fontColor(this.currentTagIndex === index ? $r('app.color.top_title') : $r('app.color.848284'))
.textAlign(TextAlign.Center)
.backgroundColor(this.currentTagIndex === index ? $r('sys.color.ohos_id_color_background') : '')
.onClick(() => {
this.currentTagIndex = index;
this.contentData = this.arrayList[index];
})
}
}.onClick(()=>{
this.currentTagIndex2=index
this.videoTitle=item.name
this.type_uuid=item.uuid
this.changeSelectRescourse()
})
}
.backgroundColor('#efefef')
.width('27%')
.height('100%')
// 二级列表
List() {
if (this.currentTagIndex == 0) {
ListItem() {
Row() {
Text('全部视频')
.fontSize(15)
.padding(10)
.fontColor(this.currentTagIndex2 === -2 ? $r('app.color.top_title') : $r('app.color.848284'))
}
}.onClick(() => {
this.videoTitle = '全部视频'
this.currentTagIndex2 = -2
this.changeSelectRescourse()
this.type_uuid = ''
})
}
ForEach(this.contentData, (item: TypeList, index: number) => {
ListItem() {
Row() {
Text(item.name)
.fontSize(15)
.padding(10)
.fontColor(this.currentTagIndex2 === index && this.videoTitle == item.name ?
$r('app.color.top_title') : $r('app.color.848284'))
}
}.onClick(() => {
this.currentTagIndex2 = index
this.videoTitle = item.name
this.type_uuid = item.uuid
this.changeSelectRescourse()
})
})
}
.backgroundColor(Color.White)
.layoutWeight(1)
.divider({
strokeWidth: 1,
color: $r('app.color.common_gray_border'),
startMargin: 10,
endMargin: 10
})
}
.backgroundColor(Color.White)
.layoutWeight(1)
.divider({
strokeWidth: 1,
color: $r('app.color.common_gray_border'),
startMargin:10,
endMargin:10
})
.height('100%')
}.width('100%').alignItems(VerticalAlign.Top)
.height('100%')
}.width('100%').alignItems(VerticalAlign.Top)
}
}
}
@ -290,81 +329,117 @@ export struct SecondaryLink {
}
}
changeSelectRescourse()
{
changeSelectRescourse() {
this.videoImg=$r('app.media.video_select')
this.videoImgt=$r('app.media.select_video')
this.videoText=$r('app.color.top_title')
this.isOpenSelect=false
}
initList()
{
initList() {
let hashMap: HashMap<string, string> = new HashMap();
hdHttp.httpReq<string>(BasicConstant.expertVideoTypeList,hashMap).then(async (res: HdResponse<string>) => {
hdHttp.httpReq<string>(this.pageType=='患教视频'?BasicConstant.patientVideoNew:BasicConstant.expertVideoTypeList,hashMap).then(async (res: HdResponse<string>) => {
let json:VideoTypeModel = JSON.parse(res+'') as VideoTypeModel;
this.tagLists=json.data
for (let i = 0;i<this.tagLists.length;i++){
let datatagname=json.data[i].list;
let k:number[]=[];
for(let j=0;j<datatagname.length;j++)
{
let s:string;
if ("z-BMS专家端"==(datatagname[j].name)){
k.push(j);
if (this.pageType=='患教视频') {
this.tagLists.push({name:'全部视频',uuid:''} as VideoType)
for (let j = 0; j < json.data.length; j++) {
let s: string;
if ("z-BMS专家端" == (json.data[j].name)) {
}
let title:string = datatagname[j].name
let digit:boolean = ChangeUtil.isFirstDigit(title.charAt(0));//判断首位是否是数字
let asciiAlpha :boolean= ChangeUtil.isLetter(title.charAt(0));//字母
if(digit||asciiAlpha){
let substring:string = '';
if (title.length>=4){
substring = title.substring(0, 4);//取出来前4位
}else if(title.length>=3){
substring = title.substring(0, 3);//取出来前3位
}else if (title.length>=2){
substring = title.substring(0, 2);//取出来前2位
let title: string = json.data[j].name
let itemUuid:string = json.data[j].uuid
let digit: boolean = ChangeUtil.isFirstDigit(title.charAt(0)); //判断首位是否是数字
let asciiAlpha: boolean = ChangeUtil.isLetter(title.charAt(0)); //字母
if (digit || asciiAlpha) {
let substring: string = '';
if (title.length >= 4) {
substring = title.substring(0, 4); //取出来前4位
} else if (title.length >= 3) {
substring = title.substring(0, 3); //取出来前3位
} else if (title.length >= 2) {
substring = title.substring(0, 2); //取出来前2位
}
if (substring.includes("-")){//含有-
let split: string[] = substring.split("-");
if (split.length>1){
if (substring.includes("---")) { //含有-
let split: string[] = substring.split("---");
if (split.length > 1) {
s = split[split.length - 1] + title.substring(4, title.length);
}else {
s = title.substring(4, title.length);
} else {
s = title.substring(4, title.length);
}
datatagname[j].name=s;
this.tagLists.push({name:s,uuid:itemUuid} as VideoType)
} else if (substring.includes("--")) {
let split: string[] = substring.split("--");
if (split.length > 1) {
s = split[split.length - 1] + title.substring(4, title.length);
} else {
s = title.substring(4, title.length);
}
this.tagLists.push({name:s,uuid:itemUuid} as VideoType)
} else if (substring.includes("-")) {
let split: string[] = substring.split("-");
if (split.length > 1) {
s = split[split.length - 1] + title.substring(4, title.length);
} else {
s = title.substring(4, title.length);
}
this.tagLists.push({name:s,uuid:itemUuid} as VideoType)
} else {
this.tagLists.push({name:title,uuid:itemUuid} as VideoType)
}
} else {
this.tagLists.push({name:title,uuid:itemUuid} as VideoType)
}
}
const indexesToRemove = new Set(k); // 使用 Set 提高查找效率
const newArr = datatagname.filter((_, index) => !indexesToRemove.has(index));
this.arrayList.add(newArr)
k=[]
} else {
this.tagLists = json.data
for (let i = 0; i < this.tagLists.length; i++) {
let datatagname = json.data[i].list;
let k: number[] = [];
for (let j = 0; j < datatagname.length; j++) {
let s: string;
if ("z-BMS专家端" == (datatagname[j].name)) {
k.push(j);
}
let title: string = datatagname[j].name
let digit: boolean = ChangeUtil.isFirstDigit(title.charAt(0)); //判断首位是否是数字
let asciiAlpha: boolean = ChangeUtil.isLetter(title.charAt(0)); //字母
if (digit || asciiAlpha) {
let substring: string = '';
if (title.length >= 4) {
substring = title.substring(0, 4); //取出来前4位
} else if (title.length >= 3) {
substring = title.substring(0, 3); //取出来前3位
} else if (title.length >= 2) {
substring = title.substring(0, 2); //取出来前2位
}
if (substring.includes("-")) {
let split: string[] = substring.split("-");
if (split.length > 1) {
s = split[split.length - 1] + title.substring(4, title.length);
} else {
s = title.substring(4, title.length);
}
datatagname[j].name = s;
}
}
}
const indexesToRemove = new Set(k); // 使用 Set 提高查找效率
const newArr = datatagname.filter((_, index) => !indexesToRemove.has(index));
this.arrayList.add(newArr)
k = []
}
}
this.contentData=this.arrayList[0];
}).catch((err: BusinessError) => {
})
let hashMap1: HashMap<string, string> = new HashMap();
hashMap1.set("type", "2")
hdHttp.post<string>(BasicConstant.tagList,{
type:'2'
type:this.pageType=='患教视频'?'5':'2'
} as TagModel).then(async (res: HdResponse<string>) => {
let json:TagListModel = JSON.parse(res+'') as TagListModel;
this.tags=json.data
}).catch((err: BusinessError) => {
})
}
}
interface TagModel
{
interface TagModel {
type:string
}

View File

@ -5,7 +5,7 @@ export interface VideoTypeModel {
}
export interface VideoType{
uuid:string;
name:string;
list:TypeList[];
}

View File

@ -0,0 +1,26 @@
import { SecondaryLink } from '../components/SecondaryLink';
import router from '@ohos.router';
import { HdNav } from '@itcast/basic'
@Component
export struct EducationVideo {
@State isShowNaviLeft:boolean = false
@State rightBottom:string = ''
@State rightBottomPath:string = ''
@State rightBottomTitle:string = ''
build() {
Column() {
HdNav({ title: '患教视频', showRightIcon: true, showLeftIcon:true,showRightText:false,rightIcon:$r('app.media.selected_hospital_ws'),rightItemAction:()=>{
router.pushUrl({
url:'pages/SearchPage/VideoSearchPage',
params:{'pageName':'视频'}
})
}})
SecondaryLink({pageType:'患教视频'}).layoutWeight(1)
}.width('100%')
.height('100%')
.backgroundColor($r('app.color.top_bg'))
}
}

View File

@ -6,7 +6,7 @@ import { HomeReplayVideoComp } from '../components/HomeReplayVideoComp'
import { getDisplayWindowWidth } from 'media-player-common'
import { BusinessError } from '@kit.BasicServicesKit';
import HashMap from '@ohos.util.HashMap';
import { BasicConstant,hdHttp, HdResponse ,logger,HdHomeNav} from '@itcast/basic/Index'
import { BasicConstant,hdHttp, HdResponse ,logger,HdHomeNav, ChangeUtil} from '@itcast/basic/Index'
import { HomeModel,dataModel, newsModel,iconsModel } from '../model/HomeModel';
import { DefaultHintProWindows,SignPopWindow,HdLoadingDialog } from '@itcast/basic'
import { promptAction, router } from '@kit.ArkUI';
@ -21,6 +21,9 @@ export struct HomePage {
// toTop:boolean;
@State hintMessage:string = '';
@State signData:Record<string,string> = {};
@State rightBottom:string = ''
@State rightBottomPath:string = ''
@State rightBottomTitle:string = ''
scroller:Scroller = new Scroller()
@ -64,10 +67,12 @@ export struct HomePage {
gotoTop() {
this.scroller.scrollToIndex(0);
this.initData()
this.getAppActivity()
}
aboutToAppear(): void {
this.initData()
this.getAppActivity()
}
initData() {
@ -112,6 +117,25 @@ export struct HomePage {
})
}
getAppActivity() {
const hashMap: HashMap<string, string> = new HashMap()
this.dialog.open()
hashMap.clear()
hashMap.set('id','6')
hdHttp.httpReq<string>(BasicConstant.getAppActivity,hashMap).then(async (res: HdResponse<string>) => {
logger.info('Response addBonusPoints'+res)
this.dialog.close()
let json:Record<string,string | Record<string,string>> = JSON.parse(res+'') as Record<string,string | Record<string,string>>
if (json.code == '200') {
this.rightBottom = json.data['img']
this.rightBottomPath = json.data['url_path']
this.rightBottomTitle = json.data['name']
}
}).catch((err: BusinessError) => {
this.dialog.close()
})
}
build() {
Stack(){
Scroll(this.scroller) {
@ -164,6 +188,19 @@ export struct HomePage {
})
}
})
Image(BasicConstant.urlImage+this.rightBottom)
.width(76)
.height(40)
.position({ x: '100%', y: '100%' })
.translate({ x: -76, y: -76 })
.visibility(ChangeUtil.stringIsUndefinedAndNull(this.rightBottom)?Visibility.None:Visibility.Visible)
.onClick(()=>{
router.pushUrl({
url: 'pages/WebView/WebPage',
params: {'title':this.rightBottomTitle,'url':this.rightBottomPath}
})
})
}
.alignContent(Alignment.Top)
.backgroundColor('#f4f4f4')

View File

@ -1,10 +1,11 @@
import { HdNav } from '@itcast/basic'
import { ListCompBack } from '../components/ListCompBack'
import { router } from '@kit.ArkUI';
@Entry
@Component
export struct PlayBack {
@State params:Record<string, string> = router.getParams() as Record<string, string>
@State notselectImg: ResourceStr = $r('app.media.triangle_normal');
@State selectImg: ResourceStr = $r('app.media.triangle_green_theme');
@State yearWords:Array<string> =[]
@ -16,22 +17,32 @@ export struct PlayBack {
@State timeText:string='会议时间';
@State typeText:string='会议类别';
@State type:string='';
onPageShow(): void {
console.log('VideoPage onPageShow!');
}
@State isShowNaviRight:boolean = false
onPageHide(): void {
console.log('VideoPage onPageHide!');
}
aboutToAppear(): void {
this.getSelect()
if (this.params) {
if (this.params["pageName"] == '肝胆视频') {
this.isShowNaviRight = true
}
}
}
build() {
Column()
{
HdNav({ title: '肝胆回放', showRightIcon: false, showLeftIcon: true})
if (this.isShowNaviRight) {
HdNav({ title: '肝胆视频', showRightIcon: true, showLeftIcon:true,showRightText:false,showTwoRightItem:true,twoRightIcon:$r('app.media.video_gandan_navigation2'),rightIcon:$r('app.media.selected_hospital_ws'),rightItemAction:()=>{
router.pushUrl({
url:'pages/SearchPage/VideoSearchPage',
params:{'pageName':'视频'}
})
},twoRightItemAction:()=>{
router.back()
}})
} else {
HdNav({ title: '肝胆回放', showRightIcon: false, showLeftIcon: true})
}
Row() {
Row() {

View File

@ -1,14 +1,18 @@
import { SecondaryLink } from '../components/SecondaryLink';
import router from '@ohos.router';
import { BasicConstant, HdNav } from '@itcast/basic'
import { BasicConstant, ChangeUtil, hdHttp, HdNav, HdResponse } from '@itcast/basic'
import { SwiperComp } from '../components/SwiperComp'
import { emitter } from '@kit.BasicServicesKit';
import { BusinessError, emitter } from '@kit.BasicServicesKit';
import { getDisplayWindowWidth } from 'media-player-common'
import { HashMap } from '@kit.ArkTS';
@Component
export struct VideoGandan {
@State params:Record<string, string> = router.getParams() as Record<string, string>
@State isShowNaviLeft:boolean = false
@State rightBottom:string = ''
@State rightBottomPath:string = ''
@State rightBottomTitle:string = ''
aboutToAppear(): void {
if (this.params) {
@ -16,19 +20,73 @@ export struct VideoGandan {
this.isShowNaviLeft = true
}
}
this.getAppActivity()
}
getAppActivity() {
const hashMap: HashMap<string, string> = new HashMap()
hashMap.clear()
hashMap.set('id','6')
hdHttp.httpReq<string>(BasicConstant.getAppActivity,hashMap).then(async (res: HdResponse<string>) => {
let json:Record<string,string | Record<string,string>> = JSON.parse(res+'') as Record<string,string | Record<string,string>>
if (json.code == '200') {
this.rightBottom = json.data['img']
this.rightBottomPath = json.data['url_path']
this.rightBottomTitle = json.data['name']
}
}).catch((err: BusinessError) => {
})
}
build() {
Column() {
HdNav({ title: '肝胆视频', showRightIcon: true, showLeftIcon: this.isShowNaviLeft,showRightText:false,rightIcon:$r('app.media.selected_hospital_ws'),rightItemAction:()=>{
HdNav({ title: '肝胆视频', showRightIcon: true, showLeftIcon: this.isShowNaviLeft,showRightText:false,showTwoRightItem:true,twoRightIcon:$r('app.media.video_gandan_navigation_change'),rightIcon:$r('app.media.selected_hospital_ws'),rightItemAction:()=>{
router.pushUrl({
url:'pages/SearchPage/VideoSearchPage',
params:{'pageName':'视频'}
})
},twoRightItemAction:()=>{
router.pushUrl({
url:'pages/VideoPage/PlayBackPage',
params:{'pageName':'肝胆视频'}
})
}})
SwiperComp().height(getDisplayWindowWidth().vp / 16 * 9)
SecondaryLink().layoutWeight(1)
SecondaryLink({pageType:'肝胆视频'})
.margin({bottom:55})
.layoutWeight(1)
Row(){
Image($r('app.media.video_gandan_bottom_icon'))
.size({width:22,height:22})
Text('患教视频')
.fontSize(16)
.fontColor(Color.White)
}
.justifyContent(FlexAlign.Center)
.width('100%')
.height(53)
.position({y:'94%'})
.backgroundColor('rgb(63,199,193)')
.onClick(() => {
router.pushUrl({
url: 'pages/VideoPage/EducationVideoPage'
})
})
Image(BasicConstant.urlImage+this.rightBottom)
.width(76)
.height(40)
.position({ x: '100%', y: '100%' })
.translate({ x: -76, y: -126 })
.visibility(ChangeUtil.stringIsUndefinedAndNull(this.rightBottom)?Visibility.None:Visibility.Visible)
.onClick(()=>{
router.pushUrl({
url: 'pages/WebView/WebPage',
params: {'title':this.rightBottomTitle,'url':this.rightBottomPath}
})
})
}.width('100%')
.height('100%')
.backgroundColor($r('app.color.top_bg'))

View File

@ -99,7 +99,7 @@ export struct VideoPage {
.layoutWeight(1)
.justifyContent(FlexAlign.Center)
.onClick(() => {
router.pushUrl({url:'pages/VideoPage/PlayBackPage'})
router.pushUrl({url:'pages/VideoPage/PlayBackPage', params:{'pageName':'肝胆会议'}})
})

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -4,7 +4,7 @@ import { PerfactInputSheet } from '@itcast/basic/src/main/ets/Views/PerfactInput
import { LengthMetrics, router } from '@kit.ArkUI'
import { ChatKitClient } from '@nimkit/chatkit';
import { StringIsEmpty } from '@nimkit/common';
import { PatientTBean } from '../model/TeachModel';
import { PatientTBean } from '@itcast/basic/src/main/ets/models/TeachModel';
@Preview

View File

@ -3,7 +3,7 @@ import { HMRouter, HMRouterMgr } from '@hadss/hmrouter'
import { PullToRefreshLayout, RefreshController } from 'refreshlib'
import { HashMap } from '@kit.ArkTS';
import { BusinessError } from '@kit.BasicServicesKit';
import { PatientTBean, TeachModel } from '../model/TeachModel';
import { PatientTBean, TeachModel } from '@itcast/basic/src/main/ets/models/TeachModel';
import { promptAction } from '@kit.ArkUI';
import { ItemCompTeach } from '../components/ItemCompTeach';
import { PatientVBean, TeachVideoModel } from '../model/TeachVideoModel';

View File

@ -3,7 +3,7 @@ import { HMRouter, HMRouterMgr, HMRouterPathCallback, HMRouterPathInfo } from '@
import { PullToRefreshLayout, RefreshController } from 'refreshlib'
import { HashMap } from '@kit.ArkTS';
import { BusinessError } from '@kit.BasicServicesKit';
import { PatientTBean, TeachModel } from '../model/TeachModel';
import { PatientTBean, TeachModel } from '@itcast/basic/src/main/ets/models/TeachModel';
import { promptAction } from '@kit.ArkUI';
import { ItemCompTeach } from '../components/ItemCompTeach';
import { StringIsEmpty } from '@nimkit/common';

View File

@ -0,0 +1,647 @@
import { HMRouter, HMRouterMgr } from "@hadss/hmrouter";
import {
authStore,
BasicConstant,
ChangePhotoGrids, ChangeUtil,
compressedImage,
hdHttp,
HdLoadingDialog,
HdNav,
HdResponse,
logger,
PhotoActionSheet, TimestampUtil, ViewImageInfo } from "@itcast/basic";
import { promptAction } from "@kit.ArkUI";
import { BusinessError } from "@kit.BasicServicesKit";
import { rcp } from "@kit.RemoteCommunicationKit";
import { image } from "@kit.ImageKit";
import { fileIo } from "@kit.CoreFileKit";
import { buffer } from "@kit.ArkTS";
import { ImageCompressor,ImageCompressOptions } from "../utils/ImageCompressor";
@HMRouter({pageUrl:'CopyAddAndEditRecordComp'})
@Component
export struct CopyAddAndEditRecordComp {
@State photos: string[] = []
@State base64Array:string[] = []
@State maxSelectNumber: number = 8
private params: ESObject = HMRouterMgr.getCurrentParam()
private photoSheetDialog!: CustomDialogController;
@State nowDate:Date = new Date
@State creat_time:string = TimestampUtil.format(this.nowDate,'YYYY-MM-DD')
@State recordUuid:string = ''
@State inputContent:string = ''
@State
@Watch('onAddImg')
addImg: boolean=false
@State
@Watch('onRemoveImg')
removeImg: boolean=false
@State removeIndex: number = 0
dialog: CustomDialogController = new CustomDialogController({
builder: HdLoadingDialog({ message: '加载中...' }),
customStyle: true,
alignment: DialogAlignment.Center
})
onAddImg() {
this.photoSheetDialog.open()
}
onRemoveImg() {
this.photos.splice(this.removeIndex, 1)
this.maxSelectNumber = 8 - this.photos.length;
// this.convertUrisOrUrlsToBase64(this.photos).then(base64Array => {
// console.info('转换结果:', base64Array+'转换个数:'+base64Array.length)
// this.base64Array = base64Array
// }).catch((err:BusinessError) => {
// console.error('批量转换失败:', err)
// })
}
aboutToAppear(): void {
this.initPhotoDialog()
if (this.params) {
if (this.params["model"]) {
const model:recordList = this.params["model"]
this.photos.push(...this.changeToImgs(model.photo))
this.inputContent = model.des
this.recordUuid = model.uuid
this.creat_time = model.create_date
this.maxSelectNumber = 8 - this.photos.length
// this.convertUrisOrUrlsToBase64(this.photos).then(base64Array => {
// console.info('转换结果:', base64Array+'转换个数:'+base64Array.length)
// this.base64Array = base64Array
// }).catch((err:BusinessError) => {
// console.error('批量转换失败:', err)
// })
}
}
}
async submitData() {
if (ChangeUtil.stringIsUndefinedAndNull(this.creat_time)) {
promptAction.showToast({ message:'请选择日期', duration: 1000 })
return
}
if (ChangeUtil.stringIsUndefinedAndNull(this.inputContent)) {
promptAction.showToast({ message:'请描述患者病情', duration: 1000 })
return
}
this.dialog.open()
this.base64Array =await this.convertUrisOrUrlsToBase64(this.photos)
const requestUrl = this.recordUuid?BasicConstant.upConditionRecord:BasicConstant.addConditionRecord
const entity: rcp.MultipartForm = this.recordUuid? new rcp.MultipartForm({
"uuid":this.recordUuid,
"des":this.inputContent,
"create_date":this.creat_time
}) : new rcp.MultipartForm({
"expert_uuid":authStore.getUser().uuid,
"patient_uuid":this.params["patient_uuid"],
"des":this.inputContent,
"create_date":this.creat_time
})
this.base64Array.forEach((base64Str: string, index: number) => {
if (index < 8) {
entity.fields[`img${index + 1}`] = base64Str;
}
})
const session = rcp.createSession();
session.post(requestUrl, entity)
.then((response) => {
this.dialog.close();
logger.info('Response '+requestUrl+':'+response);
let json:Record<string,string | Record<string,string> | Array<Record<string,string>>> = JSON.parse(response+'') as Record<string,string | Record<string,string> | Array<Record<string,string>>>;
if(json.code == '1') {
HMRouterMgr.pop({param:{"isRefresh":"1"}})
promptAction.showToast({ message:'提交病情记录成功', duration: 1000 })
} else {
console.error('获取患者信息失败:'+json.message)
promptAction.showToast({ message: String(json.message), duration: 1000 })
}
})
.catch((err: BusinessError) => {
this.dialog.close();
console.error(`Response fails: ${err}`);
})
}
deleteTecordData() {
const entity = {
"uuid": this.recordUuid
} as Record<string,string>
this.dialog.open()
hdHttp.post<string>(BasicConstant.delConditionRecord, entity).then(async (res: HdResponse<string>) => {
this.dialog.close();
logger.info('Response delConditionRecord'+res);
let json:Record<string,string | Record<string,string> | Array<Record<string,string>>> = JSON.parse(res+'') as Record<string,string | Record<string,string> | Array<Record<string,string>>>;
if(json.code == '1') {
HMRouterMgr.pop({param:{"isRefresh":"1"}})
promptAction.showToast({ message:'删除病情记录成功', duration: 1000 })
} else {
console.error('删除病情记录信息失败:'+json.message)
promptAction.showToast({ message: String(json.message), duration: 1000 })
}
}).catch((err: BusinessError) => {
this.dialog.close();
console.error(`Response fails: ${err}`);
})
}
build() {
Column() {
HdNav({title:'病情记录',isLeftAction:true,showRightIcon:false,showRightText:true,rightText:'提交',rightItemAction:()=>{
this.submitData()
},leftItemAction:()=>{
HMRouterMgr.pop()
}})
this.contentView()
if (this.params){
if (this.params["model"]) {
Text('删除该条记录')
.textAlign(TextAlign.Center)
.fontSize(16)
.fontColor(Color.White)
.backgroundColor($r('app.color.main_color'))
.width('90%')
.height(50)
.borderRadius(5)
.margin({left:10,right:10,bottom:20})
.onClick(()=>{
this.deleteTecordData()
})
}
}
}
.width('100%')
}
@Builder
contentView() {
Row(){
Text('日期')
.fontColor($r('app.color.main_color'))
.margin({left:10})
.layoutWeight(1)
Text(this.creat_time)
.margin({right:10})
.onClick(()=>{
this.selectedData()
})
}
.width('100%')
.height(50)
.margin({top:5})
Blank()
.width('100%')
.height(0.5)
.margin({left:10})
.backgroundColor('#999999')
TextArea({
placeholder:'请描述患者病情',
text:this.inputContent
})
.backgroundColor(Color.White)
.margin({top:10})
.width('100%')
.height(150)
.onChange((values:string)=>{
this.inputContent = values
})
ChangePhotoGrids({
imgList:this.changeToImg(this.photos),
maxSelectNumber:8,
addImg:this.addImg,
removeImg:this.removeImg,
removeIndex:this.removeIndex
})
.height(200)
.padding({top:10})
.backgroundColor('#f4f4f4')
Blank()
.layoutWeight(1)
}
changeToImg( imgListurl:string[]) {
let imgListtmps:ViewImageInfo[]=[]
imgListurl.forEach((url: string) => {
let item = {uri:url} as ViewImageInfo
imgListtmps.push(item)
})
return imgListtmps
}
changeToImgs( imgListurl:string[]) {
let imgListtmps:string[]=[]
imgListurl.forEach((url: string) => {
let item = BasicConstant.urlHtml + url
imgListtmps.push(item)
})
return imgListtmps
}
private initPhotoDialog() {
this.photoSheetDialog = new CustomDialogController({
builder: PhotoActionSheet({
controller: this.photoSheetDialog,
maxSelectNumber:this.maxSelectNumber,
onPhotoSelected: async (uris: string[] | string) => {
let selectedUris: string[] = [];
if (Array.isArray(uris)) {
selectedUris = uris;
} else if (typeof uris === 'string') {
selectedUris = [uris];
}
this.photos.push(...selectedUris);
this.maxSelectNumber = 8 - this.photos.length
exampleUsage(this.photos)
// this.convertUrisOrUrlsToBase64(this.photos).then(base64Array => {
// console.info('转换结果:', base64Array+'转换个数:'+base64Array.length)
// this.base64Array = base64Array
// }).catch((err:BusinessError) => {
// console.error('批量转换失败:', err)
// })
}
}),
alignment: DialogAlignment.Bottom,
customStyle: true,
autoCancel: false,
backgroundColor: ('rgba(0,0,0,0.5)'),
height: '100%'
});
}
selectedData(){
CalendarPickerDialog.show({
selected: new Date(),
backgroundColor: Color.White,
backgroundBlurStyle: BlurStyle.NONE,
shadow: ShadowStyle.OUTER_FLOATING_SM,
onAccept: (value) => {
const today = new Date();
today.setHours(0, 0, 0, 0);
const selected = new Date(value);
selected.setHours(0, 0, 0, 0);
if (selected < today) {
promptAction.showToast({ message: '只能选择今天及以后的日期', duration: 1500 })
return
}
this.creat_time = TimestampUtil.format(value,'YYYY-MM-DD')
}
})
}
async convertUrisOrUrlsToBase64(items: string[]): Promise<string[]> {
const results: string[] = [];
const MAX_SIZE_KB = 200; // 最大200KB
for (const item of items) {
try {
let base64Str: string;
// 处理本地文件URI
if (item.startsWith('file://')) {
base64Str = await this.compressLocalImageToTargetSize(item, MAX_SIZE_KB);
}
// 处理网络URL
else if (item.startsWith('http://') || item.startsWith('https://') || ChangeUtil.isImageFileByRegex(item)) {
base64Str = await this.compressNetworkImageToTargetSize(item, MAX_SIZE_KB);
}
// 处理其他类型资源
else {
throw new Error(`不支持的URI格式: ${item}`);
}
results.push(base64Str);
} catch (err) {
console.error(`转换失败: ${JSON.stringify(err)}`);
// 可以选择跳过失败项或使用默认图片
results.push('');
}
}
return results;
}
// 压缩本地图片到目标大小
private async compressLocalImageToTargetSize(uri: string, maxSizeKB: number): Promise<string> {
try {
// 打开文件
const file = await fileIo.open(uri, fileIo.OpenMode.READ_ONLY);
const imageSource = image.createImageSource(file.fd);
// 获取图片信息
const imageInfo = await imageSource.getImageInfo();
const originalSize = (await fileIo.stat(uri)).size;
// 如果原始图片已经小于目标大小,直接返回
if (originalSize <= maxSizeKB * 1024) {
const buffers = await this.readLocalFile(uri);
await fileIo.close(file.fd);
imageSource.release();
return buffer.from(buffers).toString('base64');
}
// 渐进式压缩策略
let quality = 90;
let scaleFactor = 1.0;
let compressedBuffer: ArrayBuffer;
do {
// 计算新的尺寸
const newWidth = Math.floor(imageInfo.size.width * scaleFactor);
const newHeight = Math.floor(imageInfo.size.height * scaleFactor);
// 创建解码选项
const decodingOptions: image.DecodingOptions = {
desiredSize: { width: newWidth, height: newHeight },
desiredPixelFormat:image.PixelMapFormat.RGBA_8888,
// desiredPixelFormat: image.PixelFormat.RGBA_8888,
};
// 获取像素图
const pixelMap = await imageSource.createPixelMap(decodingOptions);
// 使用ImagePacker进行压缩
const imagePacker = image.createImagePacker();
const option: image.PackingOption = {
format: "image/jpeg",
quality: quality,
};
compressedBuffer = await imagePacker.packing(pixelMap, option);
// 释放资源
pixelMap.release();
imagePacker.release();
// 调整压缩参数
if (compressedBuffer.byteLength > maxSizeKB * 1024) {
if (quality > 50) {
// 优先降低质量
quality -= 10;
} else if (scaleFactor > 0.4) {
// 其次缩小尺寸
scaleFactor *= 0.8;
quality = 70; // 重置质量为中等值
} else {
// 已经达到最小尺寸和最低质量,强制使用当前结果
break;
}
}
} while (compressedBuffer.byteLength > maxSizeKB * 1024);
// 转换为Base64
const base64Str = buffer.from(compressedBuffer).toString('base64');
// 释放资源
await fileIo.close(file.fd);
imageSource.release();
return base64Str;
} catch (err) {
throw new Error(`本地图片压缩失败: ${JSON.stringify(err)}`);
}
}
// 压缩网络图片到目标大小
private async compressNetworkImageToTargetSize(url: string, maxSizeKB: number): Promise<string> {
try {
// 下载网络资源
const arrayBuffer = await ChangeUtil.downloadNetworkResource(url);
// 如果下载的图片已经小于目标大小,直接返回
if (arrayBuffer.byteLength <= maxSizeKB * 1024) {
return buffer.from(arrayBuffer).toString('base64');
}
// 创建临时文件
const tempUri = await this.saveToTempFile(arrayBuffer);
try {
// 使用本地压缩方法处理
const result = await this.compressLocalImageToTargetSize(tempUri, maxSizeKB);
// 删除临时文件
await this.deleteTempFile(tempUri);
return result;
} catch (err) {
// 确保临时文件被删除
await this.deleteTempFile(tempUri);
throw new Error(`网络图片处理失败: ${JSON.stringify(err)}`);
}
} catch (err) {
throw new Error(`网络图片处理失败: ${JSON.stringify(err)}`);
}
}
// async convertUrisOrUrlsToBase64(items: string[]): Promise<string[]> {
// const results: string[] = [];
// const MAX_SIZE_KB = 500; // 最大500KB
//
// for (const item of items) {
// try {
// let base64Str: string;
//
// // 处理本地文件URI
// if (item.startsWith('file://')) {
// base64Str = await this.processLocalImage(item, MAX_SIZE_KB);
// }
// // 处理网络URL
// else if (item.startsWith('http://') || item.startsWith('https://') || ChangeUtil.isImageFileByRegex(item)) {
// base64Str = await this.processNetworkImage(item, MAX_SIZE_KB);
// }
// // 处理其他类型资源
// else {
// throw new Error(`不支持的URI格式: ${item}`);
// }
//
// results.push(base64Str);
// } catch (err) {
// console.error(`转换失败: ${JSON.stringify(err)}`);
// results.push(''); // 失败时返回空字符串
// }
// }
// return results;
// }
//
// // 处理本地图片
// private async processLocalImage(uri: string, maxSizeKB: number): Promise<string> {
// try {
// // 创建图片源
// const fileSource = await fileIo.open(uri, fileIo.OpenMode.READ_ONLY);
// const imageSource = image.createImageSource(fileSource.fd);
//
// // 获取原始图片信息
// const pixelMap = await imageSource.createPixelMap();
// const originalWidth = pixelMap.getPixelBytesNumber();
//
// // 计算压缩比例目标500KB以内
// let quality = 0.9;
// let targetWidth = 800; // 初始目标宽度
//
// // 如果原始图片太大,逐步压缩
// if (originalWidth > maxSizeKB * 1024) {
// quality = Math.min(0.6, (maxSizeKB * 1024) / originalWidth);
// targetWidth = Math.min(800, Math.sqrt((maxSizeKB * 1024) / originalWidth) * 100);
// }
//
// // 压缩图片
// const compressedImageInfo = await compressedImage(pixelMap, targetWidth);
// const compressedUri = compressedImageInfo.imageUri;
//
// // 读取压缩后的图片
// const compressedBuffer = await this.readLocalFile(compressedUri);
//
// // 如果还是太大,进一步压缩
// if (compressedBuffer.byteLength > maxSizeKB * 1024) {
// const imagePackerApi = image.createImagePacker();
// const packOpts: image.PackingOption = {
// format: "image/jpeg",
// quality: Math.max(0.3, quality * 0.8) // 进一步降低质量
// };
//
// const finalBuffer = await imagePackerApi.packing(imageSource, packOpts);
// const finalBase64 = buffer.from(finalBuffer).toString('base64');
//
// // 清理资源
// imagePackerApi.release();
// imageSource.release();
// await fileIo.close(fileSource.fd);
//
// return finalBase64;
// }
//
// // 转换为Base64
// const base64Str = buffer.from(compressedBuffer).toString('base64');
//
// // 清理资源
// imageSource.release();
// await fileIo.close(fileSource.fd);
//
// return base64Str;
//
// } catch (err) {
// throw new Error(`本地图片处理失败: ${JSON.stringify(err)}`);
// }
// }
//
// // 处理网络图片
// private async processNetworkImage(url: string, maxSizeKB: number): Promise<string> {
// try {
// // 下载网络资源
// const arrayBuffer = await ChangeUtil.downloadNetworkResource(url);
//
// // 如果下载的图片太大,进行压缩
// if (arrayBuffer.byteLength > maxSizeKB * 1024) {
// // 创建临时文件来压缩
// const tempUri = await this.saveToTempFile(arrayBuffer);
// const compressedBase64 = await this.processLocalImage(tempUri, maxSizeKB);
//
// // 清理临时文件
// await this.deleteTempFile(tempUri);
//
// return compressedBase64;
// }
//
// // 直接转换为Base64
// return buffer.from(arrayBuffer).toString('base64');
//
// } catch (err) {
// throw new Error(`网络图片处理失败: ${JSON.stringify(err)}`);
// }
// }
//
// 保存到临时文件
private async saveToTempFile(arrayBuffer: ArrayBuffer): Promise<string> {
try {
// 使用应用缓存目录作为临时目录
const context = getContext(this);
const tempDir = context.cacheDir;
const tempFileName = `temp_${Date.now()}.jpg`;
const tempPath = `${tempDir}/${tempFileName}`;
const file = await fileIo.open(tempPath, fileIo.OpenMode.CREATE | fileIo.OpenMode.WRITE_ONLY);
await fileIo.write(file.fd, arrayBuffer);
await fileIo.close(file.fd);
return tempPath;
} catch (err) {
throw new Error(`临时文件保存失败: ${JSON.stringify(err)}`);
}
}
// 删除临时文件
private async deleteTempFile(uri: string): Promise<void> {
try {
await fileIo.unlink(uri);
} catch (err) {
console.warn(`临时文件删除失败: ${JSON.stringify(err)}`);
}
}
// 优化后的本地文件读取方法
async readLocalFile(uri: string): Promise<ArrayBuffer> {
try {
// 使用异步方式读取,避免阻塞
const file = await fileIo.open(uri, fileIo.OpenMode.READ_ONLY);
const stat = await fileIo.stat(uri);
const size = stat.size;
// 限制文件大小,避免内存溢出
if (size > 10 * 1024 * 1024) { // 10MB限制
throw new Error('文件过大超过10MB限制');
}
const buffer = new ArrayBuffer(size);
await fileIo.read(file.fd, buffer);
await fileIo.close(file);
return buffer;
} catch (err) {
throw new Error(`文件读取失败: ${JSON.stringify(err)}`);
}
}
}
interface recordList {
create_date: string
des: string
patient_uuid: string
expert_uuid: string
uuid:string
photo:Array<string>
lineHeight:Length
}
async function exampleUsage(imageUris:string[]) {
try {
const options = {
maxSizeKB: 200, // 目标大小200KB
quality: 85, // 初始质量85%
maxWidth: 1200, // 最大宽度1200px
maxHeight: 1200, // 最大高度1200px
outputFormat: 'image/jpeg' // 输出格式
} as ImageCompressOptions;
const results = await ImageCompressor.compressImages(imageUris, options);
results.forEach(result => {
if (result.success) {
console.info(`图片压缩成功: ${result.uri}`);
console.info(`原始大小: ${result.originalSize}字节`);
console.info(`压缩后大小: ${result.compressedSize}字节`);
console.info(`Base64数据长度: ${result.base64.length}`);
} else {
console.error(`图片压缩失败: ${result.uri}, 错误: ${result.error}`);
}
});
} catch (error) {
console.error(`批量压缩失败: ${error.message}`);
}
}

View File

@ -60,7 +60,7 @@ export struct RecordTheIllnessComp {
build() {
Column() {
HdNav({isLeftAction:true,title:'病情记录',showRightText:false,rightIcon:$r('app.media.record_add_list'),rightItemAction:()=>{
HMRouterMgr.push({pageUrl:'AddAndEditRecordComp',param:{"patient_uuid":this.params.patient_uuid}},{
HMRouterMgr.push({pageUrl:'CopyAddAndEditRecordComp',param:{"patient_uuid":this.params.patient_uuid}},{
onResult:(popInfo:HMPopInfo)=>{
if (popInfo && popInfo.result && popInfo.result["isRefresh"] !== undefined) {
this.pageNumber = 1
@ -172,7 +172,7 @@ export struct RecordTheIllnessComp {
}
.width('100%')
.onClick(()=>{
HMRouterMgr.push({pageUrl:'AddAndEditRecordComp',param:{"model":item}},{
HMRouterMgr.push({pageUrl:'CopyAddAndEditRecordComp',param:{"model":item}},{
onResult:(popInfo:HMPopInfo)=>{
if (popInfo && popInfo.result && popInfo.result["isRefresh"] !== undefined) {
this.pageNumber = 1

View File

@ -0,0 +1,293 @@
import { image } from '@kit.ImageKit';
import { fileIo } from '@kit.CoreFileKit';
import { buffer } from '@kit.ArkTS';
import { BusinessError } from '@kit.BasicServicesKit';
/**
* 图片压缩选项接口
*/
export interface ImageCompressOptions {
maxSizeKB: number; // 目标最大大小(KB)
quality?: number; // 初始质量(0-100)默认80
maxWidth?: number; // 最大宽度默认1200
maxHeight?: number; // 最大高度默认1200
outputFormat?: string; // 输出格式,默认'image/jpeg'
}
/**
* 压缩结果接口
*/
export interface CompressResult {
uri: string; // 原始URI
base64: string; // 压缩后的base64数据
success: boolean; // 是否成功
error?: string; // 错误信息(如果有)
originalSize: number; // 原始大小(字节)
compressedSize: number; // 压缩后大小(字节)
}
/**
* 图片压缩工具类
*/
interface GeneratedTypeLiteralInterface_1 {
width: number;
height: number;
}
export class ImageCompressor {
/**
* 批量压缩图片
* @param uris 图片URI数组
* @param options 压缩选项
* @returns 压缩结果数组
*/
static async compressImages(
uris: string[],
options: ImageCompressOptions
): Promise<CompressResult[]> {
const results: CompressResult[] = [];
// 并行处理所有图片 - 修复类型问题
const compressPromises: Promise<CompressResult>[] = uris.map((uri: string): Promise<CompressResult> => {
return ImageCompressor.compressSingleImage(uri, options)
.catch((error: Error): CompressResult => {
// 明确返回符合 CompressResult 接口的对象
const errorResult: CompressResult = {
uri: uri,
base64: '',
success: false,
error: error.message,
originalSize: 0,
compressedSize: 0
};
return errorResult;
});
});
// 等待所有压缩操作完成
const compressedResults = await Promise.all(compressPromises);
results.push(...compressedResults);
return results;
}
/**
* 压缩单张图片
* @param uri 图片URI
* @param options 压缩选项
* @returns 压缩结果
*/
private static async compressSingleImage(
uri: string,
options: ImageCompressOptions
): Promise<CompressResult> {
// 设置默认选项
const compressOptions: Required<ImageCompressOptions> = {
maxSizeKB: options.maxSizeKB,
quality: options.quality ?? 80,
maxWidth: options.maxWidth ?? 1200,
maxHeight: options.maxHeight ?? 1200,
outputFormat: options.outputFormat ?? 'image/jpeg'
};
try {
// 获取原始图片信息
const originalSize = await ImageCompressor.getFileSize(uri);
// 如果已经是目标大小以下直接转换为base64
if (originalSize <= compressOptions.maxSizeKB * 1024) {
const fileBuffer = await ImageCompressor.readFileToBuffer(uri);
const base64Data = buffer.from(fileBuffer).toString('base64');
return {
uri,
base64: base64Data,
success: true,
originalSize,
compressedSize: originalSize
};
}
// 打开图片源
const imageSource = await ImageCompressor.createImageSource(uri);
// 获取图片信息
const imageInfo = await imageSource.getImageInfo();
// 计算目标尺寸(保持宽高比)
const targetSize = ImageCompressor.calculateTargetSize(
imageInfo.size.width,
imageInfo.size.height,
compressOptions.maxWidth,
compressOptions.maxHeight
);
// 渐进式压缩直到达到目标大小
const compressedBuffer = await ImageCompressor.progressiveCompression(
imageSource,
targetSize,
compressOptions
);
// 转换为base64
const base64Data = buffer.from(compressedBuffer).toString('base64');
// 释放资源
imageSource.release();
return {
uri,
base64: base64Data,
success: true,
originalSize,
compressedSize: compressedBuffer.byteLength
};
} catch (error) {
throw new Error(`压缩图片失败: ${error.message}`);
}
}
/**
* 渐进式压缩图片直到达到目标大小
*/
private static async progressiveCompression(
imageSource: image.ImageSource,
targetSize: GeneratedTypeLiteralInterface_1,
options: Required<ImageCompressOptions>
): Promise<ArrayBuffer> {
let quality = options.quality;
let scaleFactor = 1.0;
let compressedBuffer: ArrayBuffer;
do {
// 创建解码选项
const decodingOptions: image.DecodingOptions = {
desiredSize: {
width: Math.floor(targetSize.width * scaleFactor),
height: Math.floor(targetSize.height * scaleFactor)
},
desiredPixelFormat: image.PixelMapFormat.RGBA_8888,
};
// 获取像素图
const pixelMap = await imageSource.createPixelMap(decodingOptions);
// 使用ImagePacker进行压缩
const imagePacker = image.createImagePacker();
const packOptions: image.PackingOption = {
format: options.outputFormat,
quality: quality,
};
compressedBuffer = await imagePacker.packing(pixelMap, packOptions);
// 释放资源
pixelMap.release();
imagePacker.release();
// 调整压缩参数
if (compressedBuffer.byteLength > options.maxSizeKB * 1024) {
if (quality > 50) {
// 优先降低质量
quality -= 10;
} else if (scaleFactor > 0.4) {
// 其次缩小尺寸
scaleFactor *= 0.8;
quality = 70; // 重置质量为中等值
} else {
// 已经达到最小尺寸和最低质量,强制使用当前结果
break;
}
}
} while (compressedBuffer.byteLength > options.maxSizeKB * 1024);
return compressedBuffer;
}
/**
* 计算目标尺寸(保持宽高比)
*/
private static calculateTargetSize(
originalWidth: number,
originalHeight: number,
maxWidth: number,
maxHeight: number
): GeneratedTypeLiteralInterface_1 {
let width = originalWidth;
let height = originalHeight;
// 如果宽度超过最大值,按比例缩放
if (width > maxWidth) {
const ratio = maxWidth / width;
width = maxWidth;
height = height * ratio;
}
// 如果高度超过最大值,按比例缩放
if (height > maxHeight) {
const ratio = maxHeight / height;
height = maxHeight;
width = width * ratio;
}
return { width: Math.floor(width), height: Math.floor(height) };
}
/**
* 创建图片源
*/
private static async createImageSource(uri: string): Promise<image.ImageSource> {
try {
if (uri.startsWith('file://')) {
const file = await fileIo.open(uri, fileIo.OpenMode.READ_ONLY);
return image.createImageSource(file.fd);
} else {
return image.createImageSource(uri);
}
} catch (error) {
throw new Error(`创建图片源失败: ${error.message}`);
}
}
/**
* 获取文件大小
*/
private static async getFileSize(uri: string): Promise<number> {
try {
if (uri.startsWith('file://')) {
const realUri = uri.substring(7); // 移除file://前缀
const stat = await fileIo.stat(realUri);
return stat.size;
} else {
// 对于网络图片,可能需要通过其他方式获取大小
// 这里简单返回0实际应用中可能需要实现网络图片大小获取
return 0;
}
} catch (error) {
console.warn(`获取文件大小失败: ${error.message}`);
return 0;
}
}
/**
* 读取文件到缓冲区
*/
private static async readFileToBuffer(uri: string): Promise<ArrayBuffer> {
try {
let realUri = uri;
if (uri.startsWith('file://')) {
realUri = uri.substring(7); // 移除file://前缀
}
const file = await fileIo.open(realUri, fileIo.OpenMode.READ_ONLY);
const stat = await fileIo.stat(realUri);
const fileBuffer = new ArrayBuffer(stat.size);
await fileIo.read(file.fd, fileBuffer);
await fileIo.close(file.fd);
return fileBuffer;
} catch (error) {
throw new Error(`读取文件失败: ${error.message}`);
}
}
}

View File

@ -1,5 +1,6 @@
import { authStore, hdHttp, HdResponse,HdNav,BasicConstant, logger,LoginInfo,ChangeUtil,
patientDbManager } from '@itcast/basic'
patientDbManager,
DefaultHintProWindows} from '@itcast/basic'
import { promptAction, router } from '@kit.ArkUI'
import { BusinessError } from '@kit.BasicServicesKit';
import HashMap from '@ohos.util.HashMap';
@ -38,6 +39,31 @@ export struct LoginComp {
hashMap: HashMap<string, string> = new HashMap();
private hintWindowDialog!: CustomDialogController
@State smsMessage:string = ''
private hintPopWindowDialog() {
this.hintWindowDialog = new CustomDialogController({
builder:DefaultHintProWindows({
controller:this.hintWindowDialog,
message:this.smsMessage,
cancleTitle:'',
confirmTitleColor: '#333333',
selectedButton: (index:number)=>{
this.hintWindowDialog.close();
}
}),
alignment: DialogAlignment.Center,
cornerRadius:24,
backgroundColor: ('rgba(0,0,0,0.5)'),
})
}
aboutToAppear(): void {
this.hintPopWindowDialog()
}
dialog = new CustomDialogController({
builder: PrivacyDialog({
isPassLogin:this.isPassLogin,
@ -96,11 +122,6 @@ 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)
this.getSaveUserInfor(1,json)
} else {
promptAction.showToast({ message: json.message, duration: 1000 })
@ -128,6 +149,19 @@ export struct LoginComp {
} else {
this.loadPatients()//登录成功后获取患者数据存入数据库
if (this.isPassLogin) {
this.YX_token=objs.YX_token
this.YX_accid=objs.YX_accid
preferenceStore.setItemString(BasicConstant.YX_accid,objs.YX_accid)
preferenceStore.setItemString(BasicConstant.YX_token,objs.YX_token)
this.arrToStringSpecialy(objs.special)
} else {
this.YX_token=objs.data.YX_token
this.YX_accid=objs.data.YX_accid
preferenceStore.setItemString(BasicConstant.YX_accid,objs.data.YX_accid)
preferenceStore.setItemString(BasicConstant.YX_token,objs.data.YX_token)
this.arrToStringSpecialy(objs.data.special)
}
authStore.setUser(objs.data)
// emitter.emit({ eventId: 100401 })
logger.info('Response state'+state);
@ -167,6 +201,14 @@ export struct LoginComp {
this.hashMap.set('mobile',this.mobile)
this.hashMap.set('type','7')
hdHttp.httpReq<string>(BasicConstant.urlExpertAPI+'smsSend',this.hashMap).then(async (res: HdResponse<string>) => {
let json:Record<string,string> = JSON.parse(res+'') as Record<string,string>
if (json.code == '200') {
this.istime=true
this.startTime()
} else {
this.smsMessage = json.message
this.hintWindowDialog.open()
}
}).catch((err: BusinessError) => {
this.loading = false
console.info(`Response login succeeded: ${err}`);
@ -255,8 +297,6 @@ export struct LoginComp {
else
{
this.getMessage()
this.istime=true
this.startTime()
}
})

View File

@ -0,0 +1,17 @@
/**
* 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;
}

5
features/study/Index.ets Normal file
View File

@ -0,0 +1,5 @@
export { SchoolhouseComp } from './src/main/ets/components/SchoolhouseComp';
export { KeepStudyComp } from './src/main/ets/components/KeepStudyComp';
export { CoursewareComp } from './src/main/ets/components/CoursewareComp';

View File

@ -0,0 +1,6 @@
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. */
}

View File

@ -0,0 +1,23 @@
# 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

View File

@ -0,0 +1,25 @@
{
"meta": {
"stableOrder": true
},
"lockfileVersion": 3,
"ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.",
"specifiers": {
"@itcast/basic@../../commons/basic": "@itcast/basic@../../commons/basic",
"refreshlib@../../RefreshLib": "refreshlib@../../RefreshLib"
},
"packages": {
"@itcast/basic@../../commons/basic": {
"name": "@itcast/basic",
"version": "1.0.0",
"resolved": "../../commons/basic",
"registryType": "local"
},
"refreshlib@../../RefreshLib": {
"name": "refreshlib",
"version": "1.0.0",
"resolved": "../../RefreshLib",
"registryType": "local"
}
}
}

View File

@ -0,0 +1,12 @@
{
"name": "study",
"version": "1.0.0",
"description": "Please describe the basic information.",
"main": "Index.ets",
"author": "",
"license": "Apache-2.0",
"dependencies": {
"@itcast/basic": "file:../../commons/basic",
"refreshlib": "file:../../RefreshLib"
}
}

View File

@ -0,0 +1,253 @@
import {
authStore,
BasicConstant,
DefaultHintProWindows,
EmptyViewComp, hdHttp, HdLoadingDialog, HdNav,
HdResponse,
ScreeningView, TagList } from "@itcast/basic"
import { promptAction, router } from "@kit.ArkUI"
import { PullToRefreshLayout, RefreshController } from "refreshlib";
import { HashMap } from "@kit.ArkTS";
import { BusinessError } from "@kit.BasicServicesKit";
import { KeJianModel, KeJianRequest } from "../models/KeJianModel";
import { KeJianItemComp } from "../views/KeJianItemComp";
@Component
export struct CoursewareComp {
@State isHotOrNew:boolean = false
@State isShowSC:boolean = false
@State isEmptyViewVisible: boolean = false; // 控制显隐的状态变量
@State sort:string = '0'
@State pageNumber:number = 1;
@State totalPageNumer:number = 1;
@State selectedTag:TagList[] = []
scroller = new Scroller();
public controller:RefreshController = new RefreshController();
@State keyWordsStr:string = ''
@State data : KeJianModel[] = [];
alertView:CustomDialogController = new CustomDialogController({
builder:DefaultHintProWindows({
title:'提示',
message:'肝胆相照将稍后与您沟通课件分享\n谢谢您的支持',
cancleTitleColor: '#333333',
confirmTitleColor: $r('app.color.main_color'),
selectedButton: (index:number)=>{
if (index === 1) {
this.commitKeJian()
}
this.alertView.close();
}
}),
alignment: DialogAlignment.Center,
cornerRadius:24,
backgroundColor: ('rgba(0,0,0,0.5)'),
})
dialog: CustomDialogController = new CustomDialogController({
builder: HdLoadingDialog({ message: '加载中...' }),
customStyle: true,
alignment: DialogAlignment.Center
})
aboutToAppear() {
this.getApplyList();
}
getApplyList() {
const hashMap: HashMap<string, string> = new HashMap();
hashMap.set('page',this.pageNumber.toString());
hashMap.set("sort", this.sort);
hashMap.set("keywords", String(this.keyWordsStr));
this.dialog.open()
hdHttp.httpReq<string>(BasicConstant.ganDanFileByKeyWords,hashMap).then(async (res: HdResponse<string>) => {
this.dialog.close();
let json:KeJianRequest = JSON.parse(res+'') as KeJianRequest;
if(json.code == '200') {
if(this.pageNumber==1) {
this.data=[]
if(json.data!=null) {
this.data = json.data.list;
}
} else if(this.pageNumber>1) {
this.data.push(...json.data.list)
}
this.totalPageNumer = json.data.totalPage;
if (this.data.length > 0) {
this.isEmptyViewVisible = false;
} else {
this.isEmptyViewVisible = true;
}
} else {
promptAction.showToast({ message: json.message, duration: 1000 })
}
}).catch((err: BusinessError) => {
this.dialog.close();
this.controller.refreshError();
console.info(`Response fails: ${err}`);
})
}
commitKeJian() {
const entity = {
"content":'我要共享课件',
"expertUuid": authStore.getUser().uuid
} as Record<string,string>
this.dialog.open()
hdHttp.post<string>(BasicConstant.feedBack, entity).then(async (res: HdResponse<string>) => {
this.dialog.close();
console.info('Response delConditionRecord'+res);
let json:Record<string,string | Record<string,string> | Array<Record<string,string>>> = JSON.parse(res+'') as Record<string,string | Record<string,string> | Array<Record<string,string>>>;
if(json.code == '1') {
promptAction.showToast({ message:'谢谢您的支持', duration: 1000 })
} else {
console.error('删除病情记录信息失败:'+json.message)
promptAction.showToast({ message: String(json.message), duration: 1000 })
}
}).catch((err: BusinessError) => {
this.dialog.close();
console.error(`Response fails: ${err}`);
promptAction.showToast({ message: String('分享失败,请重试'), duration: 1000 })
})
}
build() {
Column() {
HdNav({ title: '肝胆课件',showRightIcon: true,rightIcon:$r('app.media.selected_hospital_ws') ,showRightText:false,
rightItemAction:()=>{
router.pushUrl({
url:'pages/SearchPage/VideoSearchPage',
params:{'pageName':'视频'}
})
}})
Column(){
Row(){
Row(){
Text(this.isHotOrNew?'最热':'最新')
.fontSize(16)
.fontColor($r('app.color.main_color'))
Image(this.isHotOrNew?$r('app.media.cb_hot'):$r('app.media.cb_new'))
.width(16)
.height(16)
}
.layoutWeight(1)
.justifyContent(FlexAlign.Center)
.onClick(()=>{
this.isHotOrNew = !this.isHotOrNew
if (this.isHotOrNew) {
this.sort = '1'
} else {
this.sort = '0'
}
this.pageNumber = 1;
this.getApplyList();
})
Blank()
.width(1)
.height(20)
.backgroundColor('#f4f4f4')
Row(){
Text('筛选')
.fontSize(16)
.fontColor(this.selectedTag.length>0?$r('app.color.main_color'):Color.Gray)
Image(this.selectedTag.length>0?$r('app.media.cb_screen_yes'):$r('app.media.cb_screen_no'))
.width(16)
.height(16)
}
.layoutWeight(1)
.justifyContent(FlexAlign.Center)
.onClick(()=>{
this.isShowSC = !this.isShowSC
})
}
.width('100%')
.height(45)
.backgroundColor(Color.White)
}
.width('100%')
.height(50)
.backgroundColor('#f4f4f4')
if (this.isEmptyViewVisible){
EmptyViewComp({promptText:'暂无课件',isVisibility:this.isEmptyViewVisible}).layoutWeight(1)
} else {
PullToRefreshLayout({
scroller:this.scroller,
viewKey:"ListPage",
controller:this.controller,
contentView:()=>{
this.contentView()
},
onRefresh:()=>{
this.pageNumber = 1;
this.getApplyList();
setTimeout(() => {
this.controller.refreshSuccess()
}, 1000)
},
onCanPullRefresh:()=>{
if (!this.scroller.currentOffset()) {
/*处理无数据,为空的情况*/
return true
}
//如果列表到顶返回true表示可以下拉返回false表示无法下拉
return this.scroller.currentOffset().yOffset <= 0
},
onLoad:()=>{
this.pageNumber++;
this.getApplyList();
setTimeout(() => {
this.controller.loadSuccess()
}, 1000)
},
onCanPullLoad: () => {
if (this.pageNumber >= this.totalPageNumer) {
return false;
} else {
return true;
}
}
}).width('100%').layoutWeight(1).clip(true)
}
Image($r('app.media.kejian_list_right_bottom'))
.width(76)
.height(40)
.position({ x: '100%', y: '100%' })
.translate({ x: -76, y: -106 })
.onClick(()=>{this.alertView.open()})
if (this.isShowSC) {
ScreeningView({type:'6',selectedArray:this.selectedTag,isSelectedItem:(value: TagList[])=>{
this.selectedTag = value
this.isShowSC = false
this.keyWordsStr = value.map(tag => tag.NAME).join(",")
this.pageNumber = 1;
this.getApplyList();
}})
.width('100%')
.height('calc(100% - 152vp)')
}
}
.height('100%')
.width('100%')
.backgroundColor('#F1F3F5')
}
@Builder
contentView() {
List({ scroller: this.scroller }) {
ForEach(this.data, (item: KeJianModel) => {
ListItem() {
KeJianItemComp({item:item})
}
})
}
.width('100%')
.height('100%')
.edgeEffect(EdgeEffect.None)
.scrollBar(BarState.Off)
}
}

View File

@ -0,0 +1,84 @@
import { HdNav } from "@itcast/basic"
import { router } from "@kit.ArkUI"
@Component
export struct KeepStudyComp {
build() {
Column() {
HdNav({title:'继续教育',showLeftIcon:false,showRightIcon:false,showRightText:false})
Row(){
Image($r('app.media.keepStudy_video_icon'))
.width(50)
.height(50)
.margin({left:10})
.objectFit(ImageFit.Fill)
Column(){
Text('肝胆视频')
.fontSize(16)
Text('数千集精彩报告等您来看')
.fontSize(14)
.margin({top:5})
.fontColor($r('app.color.common_gray_02'))
}
.alignItems(HorizontalAlign.Start)
.margin({left:10,right:10})
.layoutWeight(1)
Image($r('app.media.arrow_right'))
.width(12)
.height(15)
.margin({right:10})
}
.width('95%')
.height(90)
.borderRadius(3)
.backgroundColor(Color.White)
.margin({left:10,top:10,right:10})
.onClick(()=>{
router.pushUrl({
url:'pages/VideoPage/VideoGandanPage',
params:{"page":"首页"}
})
})
Row(){
Image($r('app.media.keepStudy_kejian'))
.width(50)
.height(50)
.margin({left:10})
.objectFit(ImageFit.Fill)
Column(){
Text('肝胆课件')
.fontSize(16)
Text('国内专业优质肝胆课件共享平台')
.fontSize(14)
.margin({top:5})
.fontColor($r('app.color.common_gray_02'))
}
.alignItems(HorizontalAlign.Start)
.margin({left:10,right:10})
.layoutWeight(1)
.onClick(()=>{
router.pushUrl({
url:'pages/Courseware/CoursewarePage'
})
})
Image($r('app.media.arrow_right'))
.width(12)
.height(15)
.margin({right:10})
}
.width('95%')
.height(90)
.borderRadius(3)
.backgroundColor(Color.White)
.margin({left:10,top:10,right:10})
}
.width('100%')
.height('100%')
.backgroundColor('#F1F3F5')
}
}

View File

@ -0,0 +1,290 @@
import {
authStore,
BasicConstant, EmptyViewComp, hdHttp, HdLoadingDialog, HdNav,
HdResponse,
ScreeningView, TagList } from "@itcast/basic"
import { promptAction, router } from "@kit.ArkUI"
import { PullToRefreshLayout, RefreshController } from "refreshlib"
import { PatientTBean, TeachModel } from '@itcast/basic/src/main/ets/models/TeachModel';
import { ItemCompTeach } from "../views/ItemCompTeach";
import { BusinessError } from "@kit.BasicServicesKit";
import { HashMap } from "@kit.ArkTS";
import { it } from "@ohos/hypium";
@Preview
@Component
export struct SchoolhouseComp {
@State isHotOrNew:boolean = false
@State isShowSC:boolean = false
@State selectedTag:TagList[] = []
@State isEmptyViewVisible: boolean = false; // 控制显隐的状态变量
public controller:RefreshController = new RefreshController();
scroller = new Scroller();
@State pageNumber:number = 1;
@State totalPageNumer:number = 1;
@State data:PatientTBean[]=[];
@State sort:string = '1'
@State keyWordsStr:string = ''
dialog: CustomDialogController = new CustomDialogController({
builder: HdLoadingDialog({ message: '加载中...' }),
customStyle: true,
alignment: DialogAlignment.Center
})
aboutToAppear() {
this.getApplyList();
}
getApplyList() {
const hashMap: HashMap<string, string> = new HashMap();
hashMap.set('page',this.pageNumber.toString());
hashMap.set("type", this.sort);
hashMap.set("keywords", String(this.keyWordsStr));
this.dialog.open()
hdHttp.httpReq<string>(BasicConstant.polularScienceArticleListByKeywordsNew,hashMap).then(async (res: HdResponse<string>) => {
this.dialog.close();
let json:TeachModel = JSON.parse(res+'') as TeachModel;
if(json.code == '1') {
if(this.pageNumber==1) {
this.data=[]
if(json.data!=null) {
this.data = json.data;
}
} else if(this.pageNumber>1) {
this.data.push(...json.data)
}
this.totalPageNumer =json.totalPage;
if (this.data.length > 0) {
this.isEmptyViewVisible = false;
} else {
this.isEmptyViewVisible = true;
}
} else {
promptAction.showToast({ message: json.message, duration: 1000 })
}
}).catch((err: BusinessError) => {
this.dialog.close();
this.controller.refreshError();
console.info(`Response fails: ${err}`);
})
}
build() {
Column() {
HdNav({ title: '患教学堂', showLeftIcon:false , showRightIcon: true,rightIcon:$r('app.media.schoolhouse_navigation_right'),showRightText:false,
rightItemAction:()=>{
router.pushUrl({
url: 'pages/WebView/WebPage',
params: {'title':'投稿','url':'http://doc.igandan.com/app/html/news/f771025027f2486493d9daa7eb0d9b11.html'}
})
}})
Column(){
Row(){
Text('患教文库')
.fontSize(18)
.fontColor($r('app.color.main_color'))
.height('100%')
.textAlign(TextAlign.Center)
.layoutWeight(1)
Blank()
.width(1)
.height('100%')
.backgroundColor('#f4f4f4')
Text('患教视频')
.fontSize(18)
.fontColor(Color.Gray)
.height('100%')
.textAlign(TextAlign.Center)
.layoutWeight(1)
.onClick(()=>{
router.pushUrl({
url: 'pages/VideoPage/EducationVideoPage'
})
})
Blank()
.width(1)
.height('100%')
.backgroundColor('#f4f4f4')
Text('常见问题')
.fontSize(18)
.fontColor(Color.Gray)
.height('100%')
.textAlign(TextAlign.Center)
.layoutWeight(1)
.onClick(()=>{
router.pushUrl({
url: 'pages/WebView/WebPage',
params: {'title':'常见问题','url':BasicConstant.wxUrl+'wxPatient/index.htm#/problem?link=share'}
})
})
}
.width('100%')
.height(45)
Blank()
.width('100%')
.height(1)
.backgroundColor('#f4f4f4')
Row(){
Row(){
Image($r('app.media.search_no'))
.width(16)
.height(16)
Text('搜索')
.fontSize(16)
.fontColor(Color.Gray)
}
.layoutWeight(1)
.justifyContent(FlexAlign.Center)
.onClick(()=>{
router.pushUrl({
url:'pages/SearchPage/VideoSearchPage',
params:{'pageName':'视频'}
})
})
Blank()
.width(1)
.height(20)
.backgroundColor('#f4f4f4')
Row(){
Text(this.isHotOrNew?'最热':'最新')
.fontSize(16)
.fontColor($r('app.color.main_color'))
Image(this.isHotOrNew?$r('app.media.cb_hot'):$r('app.media.cb_new'))
.width(16)
.height(16)
}
.layoutWeight(1)
.justifyContent(FlexAlign.Center)
.onClick(()=>{
this.isHotOrNew = !this.isHotOrNew
if (this.isHotOrNew) {
this.sort = '2'
} else {
this.sort = '1'
}
this.pageNumber = 1;
this.getApplyList();
})
Blank()
.width(1)
.height(20)
.backgroundColor('#f4f4f4')
Row(){
Text('筛选')
.fontSize(16)
.fontColor(this.selectedTag.length>0?$r('app.color.main_color'):Color.Gray)
Image(this.selectedTag.length>0?$r('app.media.cb_screen_yes'):$r('app.media.cb_screen_no'))
.width(16)
.height(16)
}
.layoutWeight(1)
.justifyContent(FlexAlign.Center)
.onClick(()=>{
this.isShowSC = !this.isShowSC
})
}
.width('100%')
.height(45)
}
.width('100%')
.height(92)
.backgroundColor(Color.White)
if (this.isEmptyViewVisible){
EmptyViewComp({promptText:'暂无科普内容',isVisibility:this.isEmptyViewVisible}).layoutWeight(1)
} else {
PullToRefreshLayout({
scroller:this.scroller,
viewKey:"ListPage",
controller:this.controller,
contentView:()=>{
this.contentView()
},
onRefresh:()=>{
this.pageNumber = 1;
this.getApplyList();
setTimeout(() => {
this.controller.refreshSuccess()
}, 1000)
},
onCanPullRefresh:()=>{
if (!this.scroller.currentOffset()) {
/*处理无数据,为空的情况*/
return true
}
//如果列表到顶返回true表示可以下拉返回false表示无法下拉
return this.scroller.currentOffset().yOffset <= 0
},
onLoad:()=>{
this.pageNumber++;
this.getApplyList();
setTimeout(() => {
this.controller.loadSuccess()
}, 1000)
},
onCanPullLoad: () => {
if (this.pageNumber >= this.totalPageNumer) {
return false;
} else {
return true;
}
}
}).width('100%').layoutWeight(1).clip(true)
}
if (this.isShowSC) {
ScreeningView({type:'4',selectedArray:this.selectedTag,isSelectedItem:(value: TagList[])=>{
this.selectedTag = value
this.isShowSC = false
this.keyWordsStr = value.map(tag => tag.NAME).join(",")
this.pageNumber = 1;
this.getApplyList();
}})
.width('100%')
.height('calc(100% - 182vp)')
}
}
.height('100%')
.width('100%')
.backgroundColor('#F1F3F5')
}
@Builder
contentView(){
List({ scroller: this.scroller }) {
ForEach(this.data, (item: PatientTBean, index) => {
ListItem() {
ItemCompTeach({item:item})
.onClick(()=>{this.pushDetailsView(item)})
}
})
}
.width('100%')
.height('100%')
.edgeEffect(EdgeEffect.None)
}
private pushDetailsView(item: PatientTBean) {
const entity = {
"news_article_uuid":item.uuid,
"user_uuid": authStore.getUser().uuid,
"type":'2'
} as Record<string,string>
this.dialog.open()
hdHttp.post<string>(BasicConstant.read, entity).then(async (res: HdResponse<string>) => {
this.dialog.close();
console.info('Response delConditionRecord'+res);
let json:Record<string,string | Record<string,string> | Array<Record<string,string>>> = JSON.parse(res+'') as Record<string,string | Record<string,string> | Array<Record<string,string>>>;
if(json.code == '1') {
router.pushUrl({url:"pages/WebView/EducationDetailsWebPage",params:{"model":item}})
}
}).catch((err: BusinessError) => {
this.dialog.close();
console.error(`Response fails: ${err}`);
promptAction.showToast({ message: String('患教文库数据请求失败!'), duration: 1000 })
})
}
}

View File

@ -0,0 +1,35 @@
export interface KeJianRequest {
code:string;
data:KeJianList;
message:string;
}
export interface KeJianList {
list:KeJianModel[]
totalPage:number
pageNumber:number
pageSize:number
totalRow:number
}
export interface KeJianModel{
uuid:string;
title:string;
type:string;
price:string;
readnum:string;
providername:string;
hospitalname:string;
discount:string;
preview_path:string;
tags:string;
order_id:string;
downloadername:string;
author:string;
download_path:string;
order_status:string;
create_date:string;
sort:string;
provider:string;
status:string
}

View File

@ -0,0 +1,68 @@
import { BasicConstant, TimestampUtil } from '@itcast/basic';
import { PatientTBean } from '@itcast/basic/src/main/ets/models/TeachModel';
@Preview
@Component
export struct ItemCompTeach {
@Prop item:PatientTBean;
aboutToAppear(): void {
}
build() {
Column() {
Row() {
Image(BasicConstant.urlHtml+this.item.imgPath).width(114).height(76).alt($r('app.media.home_scroll_default1'))
Column() {
Text(this.item.topic).fontColor($r('app.color.common_gray_01')).fontSize(16) .textOverflow({ overflow: TextOverflow.Ellipsis }).height(40)
.ellipsisMode(EllipsisMode.END).maxLines(2) .textAlign(TextAlign.Start).align(Alignment.TopStart)
.width('100%')
Row() {
Row() {
Text('今日')
.borderRadius(30)
.fontColor(Color.White)
.backgroundColor('#f24d57')
.fontSize(11)
.padding({ left: 5, right: 5,top:2,bottom:2 })
.visibility(TimestampUtil.isToday(this.item.modifyDate) ? Visibility.Visible : Visibility.None)
Text(this.item.modifyDate.length > 10 ? this.item.modifyDate.substring(5, 10) : this.item.modifyDate)
.fontColor($r('app.color.common_gray_03'))
.fontSize(12)
.visibility(!TimestampUtil.isToday(this.item.modifyDate) ? Visibility.Visible : Visibility.None)
}.width(80).align(Alignment.Start)
Row() {
Image($r('app.media.read_commient')).width(10).height(10)
Text(this.item.readnum > 100000 ? this.item.readnum * 1.000 / 10000.00 + '万' : this.item.readnum + '')
.fontColor($r('app.color.common_gray_03')).padding({left:3})
.fontSize(12)
}.width(80).align(Alignment.Start)
Row() {
Image($r('app.media.argee_commient')).width(10).height(10)
Text(this.item.agreenum > 100000 ? this.item.agreenum * 1.000 / 10000.00 + '万' : this.item.agreenum + '')
.fontColor($r('app.color.common_gray_03')).padding({left:3})
.fontSize(12)
}.width(80).align(Alignment.Start)
}
.margin({top:10})
.width('100%')
}.padding({left:10})
.layoutWeight(1)
}.alignSelf(ItemAlign.Start)
.width('100%')
.padding(10)
.onClick(() => {
})
Text().backgroundColor($r('app.color.efefef')).width('100%').height(1)
}
.backgroundColor(Color.White)
}
}

View File

@ -0,0 +1,139 @@
import { ChangeUtil } from "@itcast/basic";
import { KeJianModel } from "../models/KeJianModel";
@Component
export struct KeJianItemComp {
@Prop item:KeJianModel
build() {
Column() {
Row() {
Image(this.item.type == 'pptx' ? $r('app.media.kejian_type_ppt') :
this.item.type == 'pdf' ? $r('app.media.kejian_type_pdff') :
this.item.type == 'docx' || this.item.type == 'doc' ? $r('app.media.kejian_type_wordd') :
$r('app.media.kejian_type_pdff'))
.margin({ left: 10 })
.size({ width: 60, height: 72 })
Column() {
Text(this.item.title)
.maxLines(2)
.fontSize(16)
Text(this.contentShow(this.item.providername,this.item.hospitalname))
.fontSize(14)
.maxLines(1)
.fontColor('#888888')
.textOverflow({ overflow: TextOverflow.Ellipsis })
.margin({ top: 5, right: 10 })
Row() {
Row() {
Image($r('app.media.read_commient'))
.size({ width: 18, height: 18 })
Text(this.item.readnum + '人阅读')
.margin({ left: 2 })
.fontColor('#999999')
.fontSize(14)
}
.margin({ top: 12 })
if (this.item.price == '0') {
Row() {
Image($r('app.media.kejian_download_icon'))
.size({ width: 15, height: 15 })
Text('免费')
.margin({ left: 2 })
.fontColor('#999999')
.fontSize(14)
}
.margin({ top: 12 ,left: 10 })
} else {
if (Number(this.item.price) > 0) {
if (this.item.discount == '1') {
Row() {
Image($r('app.media.kejian_download_icon'))
.size({ width: 15, height: 15 })
Text('¥')
.margin({ left: 2 })
.fontSize(13)
.fontColor(Color.Red)
Text(this.formatPrice(this.item.price))
.fontColor(Color.Red)
.fontSize(16)
}
.margin({ top: 12 ,left: 10 })
} else if (this.item.discount == '0') {
Row() {
Image($r('app.media.kejian_download_icon'))
.size({ width: 15, height: 15 })
Text('免费')
.margin({ left: 2 })
.fontColor('#999999')
.fontSize(14)
}
.margin({ top: 12 ,left: 10 })
} else if (this.item.discount == '-1') {
} else {
Row() {
Image($r('app.media.kejian_download_icon'))
.size({ width: 15, height: 15 })
Text('¥')
.margin({ left: 2 })
.fontSize(13)
.fontColor(Color.Red)
Text(this.formatPrice2(this.item.price, this.item.discount))
.fontColor(Color.Red)
.fontSize(16)
Text('原价')
.margin({ left: 10 })
.fontSize(12)
.fontColor('#999999')
Text('¥'+this.formatPrice(this.item.price))
.fontSize(12)
.fontColor('#999999')
.decoration({ type: TextDecorationType.LineThrough })
}
.margin({ top: 12 ,left: 10 })
}
}
}
}
.alignItems(VerticalAlign.Bottom)
}
.width('80%')
.margin({ left: 10, right: 10 })
.alignItems(HorizontalAlign.Start)
}
.width('100%')
.padding({top:10,bottom:10})
Blank()
.width('100%')
.height(0.5)
.backgroundColor(Color.Gray)
}
.width('100%')
.backgroundColor(Color.White)
}
private formatPrice(priceStr: string): string {
let priceInFen = parseFloat(priceStr);
let priceInYuan = priceInFen / 100;
return `${priceInYuan.toFixed(2)}`;
}
private formatPrice2(priceStr: string,discount: string): string {
let priceInFen = parseFloat(priceStr);
let priceInYuan = priceInFen / 100 * parseFloat(discount);
return `${priceInYuan.toFixed(2)}`;
}
private contentShow(name:string,hospital:string):string {
let newname:string = ''
let newhospital:string = ''
if (!ChangeUtil.stringIsUndefinedAndNull(name)) {
newname = name
}
if (!ChangeUtil.stringIsUndefinedAndNull(hospital)) {
newhospital = hospital
}
return `${newname} ${newhospital}`
}
}

View File

@ -0,0 +1,11 @@
{
"module": {
"name": "study",
"type": "har",
"deviceTypes": [
"default",
"tablet",
"2in1"
]
}
}

View File

@ -0,0 +1,8 @@
{
"float": [
{
"name": "page_text_font_size",
"value": "50fp"
}
]
}

View File

@ -0,0 +1,8 @@
{
"string": [
{
"name": "page_show",
"value": "page from package"
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -0,0 +1,5 @@
import abilityTest from './Ability.test';
export default function testsuite() {
abilityTest();
}

View File

@ -0,0 +1,13 @@
{
"module": {
"name": "study_test",
"type": "feature",
"deviceTypes": [
"default",
"tablet",
"2in1"
],
"deliveryWithInstall": true,
"installationFree": false
}
}

View File

@ -0,0 +1,5 @@
import localUnitTest from './LocalUnit.test';
export default function testsuite() {
localUnitTest();
}

View File

@ -0,0 +1,33 @@
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);
});
});
}

View File

@ -0,0 +1,3 @@
-keep-file-name
-keep-property-name
-keep-global-name

View File

@ -0,0 +1,3 @@
-keep-file-name
-keep-property-name
-keep-global-name

View File

@ -0,0 +1,13 @@
import { CoursewareComp } from 'study';
@Entry
@Component
struct CoursewarePage {
build() {
Column() {
CoursewareComp()
}
.height('100%')
.width('100%')
}
}

View File

@ -4,6 +4,7 @@ import { TabBarCompModel } from '../../models/TabBarCompModel'
import { TabBarItems } from '../../contants/TabBarItems'
import { BasicConstant,AESEncryptionDecryption,authStore,preferenceStore } from '@itcast/basic'
import mediaquery from '@ohos.mediaquery';
import { KeepStudyComp, SchoolhouseComp } from 'study'
@Component
export struct TabBarComp {
@ -48,41 +49,50 @@ export struct TabBarComp {
index: this.activeIndex
}) {
TabContent() {
if (this.activeIndex === 0) HomePage()
}
.tabBar(this.TabBarBuilder( {
defaultIcon: $r('app.media.home_default_icon'),
activeIcon: $r('app.media.home_selected_icon'),
label: '首页'
}, 0))
.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM])
TabContent() {
if (this.activeIndex === 1) VideoPage()
if (this.activeIndex === 0) HomePage()
}
.tabBar(this.TabBarBuilder( {
defaultIcon: $r('app.media.home_default_icon'),
activeIcon: $r('app.media.home_selected_icon'),
label: '首页'
}, 0))
.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM])
TabContent() {
if (this.activeIndex === 1) SchoolhouseComp()
}
.tabBar(this.TabBarBuilder({
defaultIcon: $r('app.media.new_home_huaunjiao_icon'),
activeIcon: $r('app.media.new_home_huaunjiao_SelectedIcon'),
label: '患教学堂'
}, 1))
.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM])
TabContent() {
if (this.activeIndex === 2) VideoPage()
}
.tabBar(this.TabBarBuilder({
defaultIcon: $r('app.media.home_my_meeting_nor'),
activeIcon: $r('app.media.home_my_meeting_sel'),
label: '会议·直播'
}, 1))
.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM])
TabContent() {
if (this.activeIndex === 2) VideoGandan()
}
.tabBar(this.TabBarBuilder({
defaultIcon: $r('app.media.video_tabbar_icon'),
activeIcon: $r('app.media.video_tabbar_selected_icon'),
label: '视频'
}, 2))
.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM])
TabContent() {
if (this.activeIndex === 3) MyHomePage()
if (this.activeIndex === 3) KeepStudyComp()
}
.tabBar(this.TabBarBuilder({
defaultIcon: $r('app.media.new_nextStudy_default'),
activeIcon: $r('app.media.new_nextStudy_selected'),
label: '继续教育'
}, 3))
.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM])
TabContent() {
if (this.activeIndex === 4) MyHomePage()
}
.tabBar(this.TabBarBuilder({
defaultIcon: $r('app.media.my_tabbar_icon'),
activeIcon: $r('app.media.my_tabbar_selected_icon'),
label: '我的'
}, 3))
}, 4))
.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM])
}

View File

@ -0,0 +1,13 @@
import { EducationVideo } from 'home'
@Entry
@Component
struct EducationVideoPage {
build() {
Column() {
EducationVideo()
}
.height('100%')
.width('100%')
}
}

View File

@ -0,0 +1,87 @@
import webview from '@ohos.web.webview';
import { BasicConstant, HdNav, preferenceStore } from '@itcast/basic';
import router from '@ohos.router';
import { image } from '@kit.ImageKit';
import { photoAccessHelper } from '@kit.MediaLibraryKit';
import { promptAction } from '@kit.ArkUI';
import { fileIo, fileUri } from '@kit.CoreFileKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { PatientTBean } from '@itcast/basic/src/main/ets/models/TeachModel';
@Entry
@Component
struct EducationDetailsWebPage {
private controller: webview.WebviewController = new webview.WebviewController();
@State params:RouteParams = router.getParams() as RouteParams;
// 修改为移动端User-Agent解决链接中有视频的问题
private customUserAgent: string = 'Mozilla/5.0 (Linux; Android 10; HarmonyOS) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 gdxz-expert';
@State contentWidth: number = 0;
@State contentHeight: number = 0;
@State url: string = BasicConstant.urlHtml+this.params.model.path;
@State title: string = '患教详情';
onBackPress(): boolean | void {
if (this.controller.accessStep(-1)) {
this.controller.backward();
return true;
}
return false;
}
build() {
Column() {
HdNav({ title: this.title, showRightIcon: false, hasBorder: true ,isLeftAction:true,leftItemAction:()=>{
if (this.controller.accessBackward()) {
this.controller.backward();
} else {
router.back();
}
}})
Web({
src: this.url,
controller: this.controller
})
.id('webView')
.mixedMode(MixedMode.All)
.overScrollMode(OverScrollMode.ALWAYS)
.domStorageAccess(true)
.onControllerAttached(() => {
let userAgent = this.controller.getUserAgent() + this.customUserAgent;
this.controller.setCustomUserAgent(userAgent);
})
.onPageEnd(() => {
// 注入JS获取body高度
this.controller.runJavaScript(
'document.documentElement.scrollWidth', (error, result) => {
if (!error) this.contentWidth = Number(result);
}
);
this.controller.runJavaScript('document.body.scrollHeight',(error,result)=>{
if (!error) this.contentHeight = Number(result);
})
})
.width('100%')
.layoutWeight(1)
.height('calc(100% - 80vp)')
Row(){
Row(){
Image('')
.size({width:20,height:20})
}
.margin({left:15,top:12})
}
.alignItems(VerticalAlign.Top)
.backgroundColor(Color.White)
}
.width('100%')
.height('100%')
}
}
interface RouteParams {
model:PatientTBean
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@ -46,6 +46,9 @@
"pages/VideoPage/PLVMediaPlayerOnlyVideoPage",
"pages/Netease/OutpatientPage",
"pages/PatientsPage/GroupSendMessagePage",
"pages/VideoPage/CustomScanResultPage"
"pages/VideoPage/CustomScanResultPage",
"pages/VideoPage/EducationVideoPage",
"pages/Courseware/CoursewarePage",
"pages/WebView/EducationDetailsWebPage"
]
}

View File

@ -0,0 +1,3 @@
-keep-file-name
-keep-property-name
-keep-global-name

View File

@ -0,0 +1,3 @@
-keep-file-name
-keep-property-name
-keep-global-name