第一次提交

This commit is contained in:
xiaoxiao
2025-05-09 15:47:54 +08:00
parent 25e596b591
commit f9d7986df0
357 changed files with 26943 additions and 0 deletions
+6
View File
@@ -0,0 +1,6 @@
/node_modules
/oh_modules
/.preview
/build
/.cxx
/.test
+17
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;
}
+13
View File
@@ -0,0 +1,13 @@
export { MyHomePage } from './src/main/ets/pages/MyHomePage'
export { ChangePasswordComp } from './src/main/ets/view/ChangePasswordComp'
export { ForgetPasswordComp } from './src/main/ets/view/ForgetPasswordComp'
export { ChangePhoneComp } from './src/main/ets/view/ChangePhoneComp'
export { ChooseEmailComp } from './src/main/ets/view/ChooseEmailComp'
export { ChooseOfficePhoneComp } from './src/main/ets/view/ChooseOfficePhoneComp'
export { EditUserDataComp } from './src/main/ets/view/EditUserDataComp'
+31
View File
@@ -0,0 +1,31 @@
{
"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
@@ -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. */
}
+23
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
+18
View File
@@ -0,0 +1,18 @@
{
"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"
},
"packages": {
"@itcast/basic@../../commons/basic": {
"name": "@itcast/basic",
"version": "1.0.0",
"resolved": "../../commons/basic",
"registryType": "local"
}
}
}
+11
View File
@@ -0,0 +1,11 @@
{
"name": "mypage",
"version": "1.0.0",
"description": "Please describe the basic information.",
"main": "Index.ets",
"author": "",
"license": "Apache-2.0",
"dependencies": {
"@itcast/basic": "file:../../commons/basic"
}
}
@@ -0,0 +1,14 @@
export class MyPageSectionClass {
id:string = '';
imageSrc:ResourceStr = '';
title:string = '';
path:string = '';
constructor(id:string,imageSrc:ResourceStr,title:string,path:string) {
this.id = id;
this.imageSrc = imageSrc;
this.title = title;
this.path = path;
}
}
@@ -0,0 +1,42 @@
import { HeaderView } from '../view/HeaderView'
import { HdNav, getTimeText, hdHttp, HdUser } from '@itcast/basic'
import { OneSection } from '../view/OneSection'
import { TwoSection } from '../view/TwoSection'
import { ThreeSection } from '../view/ThreeSection'
import { FourSection } from '../view/FourSection'
import { OtherList } from '../view/OtherList'
import { emitter } from '@kit.BasicServicesKit'
@Component
export struct MyHomePage {
@State title: string = '我的';
@StorageProp('topHeight')
topHeight: number = 0
scroller = new Scroller()
build() {
Column() {
HdNav({ title: '我的', showLeftIcon:false , showRightIcon: false, hasBorder: true })
Scroll(this.scroller) {
Column() {
HeaderView()
// OneSection()
// TwoSection()
// ThreeSection()
FourSection()
OtherList()
}
}
.width('100%')
.height('100%')
.layoutWeight(1)
.scrollBar(BarState.Off)
.align(Alignment.TopStart)
}
.width('100%')
.height('100%')
.backgroundColor('#F1F3F5')
}
}
@@ -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,101 @@
import promptAction from '@ohos.promptAction';
import { router } from '@kit.ArkUI'
@Preview
@Component
export struct ChangePasswordComp {
@State oldPassword: string = ''
@State newPassword: string = ''
@State confirmPassword: string = ''
build() {
Column() {
// 原密码输入框
TextInput({ placeholder: '请输入原密码' })
.width('95%')
.height(40)
.margin({ top: 10 })
.borderWidth(1)
.borderRadius(8)
.borderColor('#cccccc')
.type(InputType.Password)
.onChange((value: string) => {
this.oldPassword = value
})
// 新密码输入框
TextInput({ placeholder: '新密码(6~16位数字字母组合)' })
.width('95%')
.height(40)
.margin({ top: 10 })
.borderWidth(1)
.borderRadius(8)
.borderColor('#cccccc')
.type(InputType.Password)
.onChange((value: string) => {
this.newPassword = value
})
// 确认新密码输入框
TextInput({ placeholder: '确认新密码' })
.width('95%')
.height(40)
.margin({ top: 10 })
.borderWidth(1)
.borderRadius(8)
.borderColor('#cccccc')
.type(InputType.Password)
.onChange((value: string) => {
this.confirmPassword = value
})
// 忘记密码链接
Text('忘记密码?')
.fontSize(14)
.fontColor('#666666')
.margin({ top: 12 })
.onClick(() => {
// 处理忘记密码逻辑
router.pushUrl({url:'pages/MinePage/ForgetPassword'})
})
// 确定按钮
Button({ type: ButtonType.Normal }){
Text('确 定')
}
.width('90%')
.height(40)
.position({x:'5%',y:'80%'})
.backgroundColor('#ffffff')
.borderColor($r('app.color.main_color'))
.borderRadius(8)
.borderWidth(1)
.fontColor($r('app.color.main_color'))
.onClick(() => {
// 处理密码修改提交逻辑
this.handleSubmit()
})
}
.width('100%')
.height('100%')
.backgroundColor(Color.White)
}
// 提交处理函数
private handleSubmit() {
// 这里添加密码验证和提交逻辑
// 验证规则示例:
if (this.newPassword !== this.confirmPassword) {
promptAction.showToast({message:'两次输入的新密码不一致'})
return
}
const passwordRegex = /^(?=.*[a-zA-Z])(?=.*\d)[a-zA-Z\d]{6,16}$/
if (!passwordRegex.test(this.newPassword)) {
promptAction.showToast({message:'密码必须为6-16位数字字母组合'})
return
}
// 调用修改密码接口...
}
}
@@ -0,0 +1,121 @@
import promptAction from '@ohos.promptAction';
@Preview
@Component
export struct ChangePhoneComp {
@State phoneNumber: string = ''
@State smsCode: string = ''
@State countdown: number = 0
// 验证码倒计时
private startCountdown() {
this.countdown = 60
const timer = setInterval(() => {
if (this.countdown > 0) {
this.countdown--
} else {
clearInterval(timer)
}
}, 1000)
}
build() {
Column() {
// 手机号输入框
Row() {
Image($r('app.media.icon_phone'))
.width(18)
.height(18)
.objectFit(ImageFit.Contain)
.margin({left:10})
TextInput({ placeholder: '请输入手机号码' })
.fontSize(16)
.backgroundColor(Color.White)
.onChange((value: string) => {
this.phoneNumber = value
})
}
.margin({ top: 10 })
.width('95%')
.height(48)
.borderRadius(4)
.borderWidth(1)
.borderColor('#CCCCCC')
// 验证码输入区域
Row() {
Row() {
Image($r('app.media.icon_verification_code'))
.width(18)
.height(18)
.objectFit(ImageFit.Contain)
.margin({left:10})
TextInput({ placeholder: '请输入验证码' })
.fontSize(16)
.backgroundColor(Color.White)
}
.margin({ top: 10 })
.width('60%')
.height(48)
.borderRadius(4)
.borderWidth(1)
.borderColor('#CCCCCC')
Button({type:ButtonType.Normal}){
Text(this.countdown ? `${this.countdown}s` : '获取验证码')
}
.width('37%')
.height(32)
.borderRadius(5)
.borderColor('#8B2316')
.borderWidth(1)
.backgroundColor(Color.White)
.fontColor('#8B2316')
.fontSize(12)
.margin({ top: 10 })
.enabled(this.countdown === 0)
.onClick(() => {
if (this.phoneNumber.length >= 11) {
this.startCountdown()
} else {
promptAction.showToast({message:'请输入手机号'})
}
})
}
.width('95%')
.justifyContent(FlexAlign.SpaceBetween)
// 登录按钮
Button({type:ButtonType.Normal}){
Text('登 录')
}
.width('90%')
.height(48)
.borderRadius(8)
.borderWidth(1)
.borderColor('#8B2316')
.backgroundColor(Color.White)
.fontColor('#8B2316')
.fontSize(18)
.position({x:'5%',y:'80%'})
.onClick(() => {
// 处理登录逻辑
if (!/^1[3-9]\d{9}$/.test(this.phoneNumber)) {
promptAction.showToast({message:'请输入有效手机号'})
return
}
if (!this.smsCode) {
promptAction.showToast({message:'请输入验证码'})
return
}
// 执行登录操作...
})
}
.width('100%')
.height('100%')
.backgroundColor('#FFFFFF')
}
}
@@ -0,0 +1,78 @@
import promptAction from '@ohos.promptAction';
import { authStore } from '@itcast/basic';
@Preview
@Component
export struct ChooseEmailComp {
@State phoneNumber: string = ''
@State countdown: number = 0
// 验证码倒计时
private startCountdown() {
this.countdown = 60
const timer = setInterval(() => {
if (this.countdown > 0) {
this.countdown--
} else {
clearInterval(timer)
}
}, 1000)
}
build() {
Column() {
// 手机号输入框
Row() {
TextInput({ placeholder: authStore.getUser().email.length>0?authStore.getUser().email:'请输入您的邮箱' })
.fontSize(16)
.backgroundColor(Color.White)
.onChange((value: string) => {
this.phoneNumber = value
})
}
.margin({ top: 10 })
.width('95%')
.height(48)
.borderRadius(4)
.borderWidth(1)
.borderColor('#CCCCCC')
// 验证码输入区域
Row() {
Text('请填写您的真实邮箱,以便联系上您')
.fontSize(15)
.fontColor('#333333')
.width('95%')
}
.margin({top:15})
.width('95%')
.justifyContent(FlexAlign.SpaceBetween)
// 登录按钮
Button({type:ButtonType.Normal}){
Text('保 存')
}
.width('90%')
.height(48)
.borderRadius(8)
.borderWidth(1)
.borderColor('#8B2316')
.backgroundColor(Color.White)
.fontColor('#8B2316')
.fontSize(18)
.position({x:'5%',y:'80%'})
.onClick(() => {
// 处理登录逻辑
if (!/^1[3-9]\d{9}$/.test(this.phoneNumber)) {
promptAction.showToast({message:'请输入有效手机号'})
return
}
// 执行登录操作...
})
}
.width('100%')
.height('100%')
.backgroundColor('#FFFFFF')
}
}
@@ -0,0 +1,84 @@
import promptAction from '@ohos.promptAction';
import { authStore } from '@itcast/basic';
@Preview
@Component
export struct ChooseOfficePhoneComp {
@State phoneNumber: string = ''
@State smsCode: string = ''
@State countdown: number = 0
// 验证码倒计时
private startCountdown() {
this.countdown = 60
const timer = setInterval(() => {
if (this.countdown > 0) {
this.countdown--
} else {
clearInterval(timer)
}
}, 1000)
}
build() {
Column() {
// 手机号输入框
Row() {
TextInput({ placeholder: authStore.getUser().officePhone.length>0?authStore.getUser().officePhone:'请输入科室号码' })
.fontSize(16)
.backgroundColor(Color.White)
.onChange((value: string) => {
this.phoneNumber = value
})
}
.margin({ top: 10 })
.width('95%')
.height(48)
.borderRadius(4)
.borderWidth(1)
.borderColor('#CCCCCC')
// 验证码输入区域
Row() {
Text('请填写您的真实科室电话,以便联系上您')
.fontSize(15)
.fontColor('#333333')
.width('95%')
}
.margin({top:15})
.width('95%')
.justifyContent(FlexAlign.SpaceBetween)
// 登录按钮
Button({type:ButtonType.Normal}){
Text('保 存')
}
.width('90%')
.height(48)
.borderRadius(8)
.borderWidth(1)
.borderColor('#8B2316')
.backgroundColor(Color.White)
.fontColor('#8B2316')
.fontSize(18)
.position({x:'5%',y:'80%'})
.onClick(() => {
// 处理登录逻辑
if (!/^1[3-9]\d{9}$/.test(this.phoneNumber)) {
promptAction.showToast({message:'请输入有效手机号'})
return
}
if (!this.smsCode) {
promptAction.showToast({message:'请输入验证码'})
return
}
// 执行登录操作...
})
}
.width('100%')
.height('100%')
.backgroundColor('#FFFFFF')
}
}
@@ -0,0 +1,71 @@
import { formatDate } from '../util/DateUtils'
@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)
}
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,275 @@
import { hdHttp, HdResponse,BasicConstant, logger,LoginInfo, authStore } from '@itcast/basic'
import HashMap from '@ohos.util.HashMap'
import { BusinessError } from '@kit.BasicServicesKit';
import { promptAction, router } from '@kit.ArkUI'
import { EditUserDataItem } from './EditUserDataItem'
import { PhotoActionSheet } from './PhotoActionSheet'
import { DatePickerDialog } from './DatePickerDialog'
import { OfficeSelectedSheet } from './OfficeSelectedSheet'
import { PositionSelectedSheet } from './PositionSelectedSheet'
import { http } from '@kit.NetworkKit';
interface LoginParams {
uuid: string
}
@Component
export struct EditUserDataComp {
@State photoPath:string = BasicConstant.imageHeader+authStore.getUser().photo;
@State name:string = authStore.getUser().realName;
@State sex:string = authStore.getUser().sex == 0 ? '男' : '女';
@State birthday:string = authStore.getUser().birthDate;
@State phone:string = authStore.getUser().mobile;
@State email:string = authStore.getUser().email;
@State hospatilName:string = authStore.getUser().hospitalName;
@State officeName:string = authStore.getUser().officeName;
@State officePhone:string = authStore.getUser().officePhone;
@State positionName:string = authStore.getUser().positionName;
@State certificate:string = authStore.getUser().certificate;
@State certificatePhoto:string = BasicConstant.imageHeader+authStore.getUser().certificateImg;
@State diseaseName:string = '';
@State intro:string = authStore.getUser().intro;
private photoSheetDialog!: CustomDialogController;
private datePickerDialog!: CustomDialogController;
private officePickerDialog!: CustomDialogController;
private positionPickerDialog!: CustomDialogController;
private certificatePhotoSheetDialog!: CustomDialogController;
aboutToAppear() {
this.initPhotoDialog();
this.initDatePickerDialog();
this.initOfficePickerDialog();
this.initPositionPickerDialog();
this.initCerficatePhotoDialog();
this.uploadUserDataAction();
console.log('用户资料:'+authStore.getUser().specialy);
}
uploadUserDataAction() {
const hashMap: HashMap<string, string> = new HashMap();
const userDataUrl:string = BasicConstant.urlExpert+'getExpertByUuid';
hashMap.set('uuid',authStore.getUser().uuid)
hdHttp.post<string>(userDataUrl, {
uuid: authStore.getUser().uuid,
} as LoginParams).then(async (res: HdResponse<string>) => {
logger.info('Response login111'+res);
console.info(`Response login succeeded333: ${res}`);
}).catch((err: BusinessError) => {
console.info(`Response login fail222222222222222: ${err}`);
})
// hdHttp.oldPost<string>(userDataUrl,hashMap).then(async (res: HdResponse<string>) => {
// console.info(`Response officelist succeeded: ${res}`);
// let json:LoginInfo = JSON.parse(res+'') as LoginInfo;
// if(json.code=='1') {
// authStore.setUser(json.data)
// console.log('用户信息成功:', json);
// } else {
// console.error('用户信息失败:'+json.message)
// promptAction.showToast({ message: json.message, duration: 1000 })
// }
// }).catch((err: BusinessError) => {
// console.error(`Response login fail: ${err}`);
// })
// hdHttp.httpReq<string>(userDataUrl,hashMap).then(async (res: HdResponse<string>) => {
// logger.info('Response officelist success'+res);
// console.info(`Response officelist succeeded: ${res}`);
// let json:LoginInfo = JSON.parse(res+'') as LoginInfo;
// if(json.code=='1') {
// authStore.setUser(json.data)
// console.log('用户信息成功:', json);
// } else {
// console.error('用户信息失败:'+json.message)
// promptAction.showToast({ message: json.message, duration: 1000 })
// }
// }).catch((err: BusinessError) => {
// console.info(`Response login fail: ${err}`);
// })
}
arrToStringSpecialy(specialy: Array<object>) {
// 声明类型化数组
let zhuangArr: string[] = [];
// 获取响应数据中的specialy数组(需根据实际API调整类型)
const array = specialy['specialy'] as Array<Record<string, string>>;
// 遍历提取diseaseName
if (specialy) {
zhuangArr = array
.filter(item => item['diseaseName']) // 过滤空值[8](@ref)
.map(item => item['diseaseName'] ?? ''); // 安全转换[9](@ref)
}
// 拼接为逗号分隔字符串
const DiseaseName = zhuangArr.join(','); // 等效componentsJoinedByString[8](@ref)
return DiseaseName;
}
private initPhotoDialog() {
this.photoSheetDialog = new CustomDialogController({
builder: PhotoActionSheet({
controller: this.photoSheetDialog,
onPhotoSelected: (uri: string) => {
this.photoPath = uri;
console.log('Selected image URI:', uri);
}
}),
alignment: DialogAlignment.Bottom,
customStyle: true,
autoCancel: false,
backgroundColor: ('rgba(0,0,0,0.5)'),
height: '100%'
});
}
private initOfficePickerDialog() {
this.officePickerDialog = new CustomDialogController({
builder:OfficeSelectedSheet({
controller:this.officePickerDialog,
officeSelected: (name:string , uuid:string) => {
this.officeName = name;
}
}),
alignment: DialogAlignment.Bottom,
customStyle: true,
autoCancel: false,
backgroundColor: ('rgba(0,0,0,0.5)'),
height: '100%'
})
}
private initPositionPickerDialog() {
this.positionPickerDialog = new CustomDialogController({
builder:PositionSelectedSheet({
controller:this.officePickerDialog,
officeSelected: (name:string , uuid:string) => {
this.positionName = name;
}
}),
alignment: DialogAlignment.Bottom,
customStyle: true,
autoCancel: false,
backgroundColor: ('rgba(0,0,0,0.5)'),
height: '100%'
})
}
private initDatePickerDialog() {
this.datePickerDialog = new CustomDialogController({
builder: DatePickerDialog({
controller:this.datePickerDialog,
dateSelected:(date:string) => {
this.birthday = date;
}
}),
alignment: DialogAlignment.Bottom,
customStyle: true,
autoCancel: false,
backgroundColor: ('rgba(0,0,0,0.5)'),
height: '100%'
});
}
private initCerficatePhotoDialog() {
this.certificatePhotoSheetDialog = new CustomDialogController({
builder: PhotoActionSheet({
controller: this.certificatePhotoSheetDialog,
onPhotoSelected: (uri: string) => {
this.certificatePhoto = uri;
console.log('Selected image URI:', uri);
}
}),
alignment: DialogAlignment.Bottom,
customStyle: true,
autoCancel: false,
backgroundColor: ('rgba(0,0,0,0.5)'),
height: '100%'
});
}
build() {
Scroll() {
Column() {
// 第一部分:基本资料
Column() {
Column(){
Text('基本资料')
.fontSize(16)
.margin({left:15})
.fontColor($r('app.color.main_color'))
}
.width('100%')
.height(17)
.backgroundColor(Color.Gray)
.alignItems(HorizontalAlign.Start)
// 基本信息字段
EditUserDataItem({ label: '头像', required: true, content: this.photoPath, hasArrow: true })
.onClick(()=>this.photoSheetDialog.open())
EditUserDataItem({ label: '姓名', required: true, content: this.name })
EditUserDataItem({ label: '性别', required: true, content: this.sex })
EditUserDataItem({ label: '出生日期', content: this.birthday , hasArrow: true})
.onClick(()=>this.datePickerDialog.open())
EditUserDataItem({ label: '手机号码', required: true, content: this.phone , hasArrow: true})
.onClick(()=>{
router.pushUrl({
url:'pages/MinePage/ChangePhonePage'
})
})
EditUserDataItem({ label: '邮箱', content: this.email , hasArrow: true})
.onClick(()=>{
router.pushUrl({
url:'pages/MinePage/ChooseEmail'
})
})
}
.height('auto')
// 第二部分:专业资料
Column() {
Column(){
Text('专业资料')
.fontSize(16)
.margin({left:15})
.fontColor($r('app.color.main_color'))
}
.width('100%')
.height(17)
.backgroundColor(Color.Gray)
.alignItems(HorizontalAlign.Start)
EditUserDataItem({ label: '医院', required: true, content: this.hospatilName })
EditUserDataItem({ label: '科室', required: true, content: this.officeName, hasArrow: true })
.onClick(()=>this.officePickerDialog.open())
EditUserDataItem({ label: '科室电话', required: true, content: this.officePhone, hasArrow: true })
.onClick(()=>{
router.pushUrl({
url:'pages/MinePage/ChooseOfficePhone'
})
})
EditUserDataItem({ label: '职称', required: true, content: this.positionName, hasArrow: true })
.onClick(()=>this.positionPickerDialog.open())
EditUserDataItem({ label: '执业医师证编号', required: true, content: this.certificate })
EditUserDataItem({ label: '执业医师证图片或胸牌', required: true, content: this.certificatePhoto })
.onClick(()=>this.certificatePhotoSheetDialog.open())
EditUserDataItem({ label: '专长', required: true, content: this.diseaseName , hasArrow: true})
EditUserDataItem({ label: '个人简介', content: this.intro, hasArrow: true })
.onClick(()=>{
router.pushUrl({
url:'pages/MinePage/EditIntroductionPage'
})
})
}
.height('auto')
}
.width('100%')
.height('100%')
.layoutWeight(1)// 占据剩余空间
}
.height('auto')
.scrollBar(BarState.Off)
.scrollable(ScrollDirection.Vertical)
.backgroundColor('#ffffff')
}
}
@@ -0,0 +1,68 @@
@Component
export struct EditUserDataItem {
private label: string = ''
private required: boolean = false
@Prop content: string = ''
private hasArrow: boolean = false
build() {
Column() {
Row() {
Row() {
Text(this.label)
.fontSize(16)
.fontColor('#333333')
.margin({ left: 15 })
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($r('app.media.userPhoto_default'))
.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)
.onComplete(() => console.log('图片加载完成'))
.onError(() => console.error('图片加载失败'+this.content))
.width(60)
.height(40)
.margin({ right: this.hasArrow?0:10 })
} else {
Text(this.content)
.fontSize(16)
.fontColor('#333333')
.margin({ right: this.hasArrow?0:10 })
}
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)
Divider()
.color('#F4F4F4')
.strokeWidth(1)
.height(1)
.margin({ left: 10, top: 0 })
}
}
}
@@ -0,0 +1,149 @@
import promptAction from '@ohos.promptAction';
import { router } from '@kit.ArkUI';
@Preview
@Component
export struct ForgetPasswordComp {
@State phoneNumber: string = ''
@State smsCode: string = ''
@State password: string = ''
@State showPassword: boolean = false
@State countdown: number = 0
@State passWordSrc1: Resource = $r('app.media.icon_forgetpassword_show');
@State passWordSrc2: Resource = $r('app.media.icon_forgetpassword');
// 验证码倒计时
private startCountdown() {
this.countdown = 60
const timer = setInterval(() => {
if (this.countdown > 0) {
this.countdown--
} else {
clearInterval(timer)
}
}, 1000)
}
build() {
Column() {
Row() {
Image($r('app.media.icon_phone'))
.width(18)
.height(18)
.objectFit(ImageFit.Contain)
.margin({left:10})
// 手机号输入框
TextInput({ placeholder: '请输入手机号码' })
.fontSize(16)
.backgroundColor(Color.White)
.onChange((value: string) => {
this.phoneNumber = value
})
}
.margin({ top: 10 })
.width('95%')
.height(48)
.borderRadius(4)
.borderWidth(1)
.borderColor('#CCCCCC')
// 验证码输入区域
Row() {
Row() {
Image($r('app.media.icon_verification_code'))
.width(18)
.height(18)
.objectFit(ImageFit.Contain)
.margin({left:10})
TextInput({ placeholder: '请输入验证码' })
.fontSize(16)
.backgroundColor(Color.White)
}
.margin({ top: 10 })
.width('60%')
.height(48)
.borderRadius(4)
.borderWidth(1)
.borderColor('#CCCCCC')
Button({type:ButtonType.Normal}){
Text(this.countdown ? `${this.countdown}s` : '获取验证码')
}
.width('37%')
.height(32)
.borderRadius(5)
.borderColor($r('app.color.main_color'))
.borderWidth(1)
.backgroundColor(Color.White)
.fontColor($r('app.color.main_color'))
.fontSize(12)
.margin({ top: 10 })
.enabled(this.countdown === 0)
.onClick(() => {
if (this.phoneNumber.length >= 11) {
this.startCountdown()
} else {
promptAction.showToast({message:'请输入手机号'})
}
})
}
.width('95%')
.justifyContent(FlexAlign.SpaceBetween)
Row() {
Image($r('app.media.icon_forgetpassword_show'))
.width(18)
.height(18)
.objectFit(ImageFit.Contain)
.margin({left:10})
// 密码输入框
TextInput({ placeholder: '6~16位数字字母组合' })
.fontSize(16)
.width('95%')
.backgroundColor(Color.White)
.type(this.showPassword ? InputType.Normal : InputType.Password)
.passwordIcon({ onIconSrc: this.passWordSrc1, offIconSrc: this.passWordSrc2 })
}
.margin({ top: 10 })
.width('95%')
.height(48)
.borderRadius(4)
.borderWidth(1)
.borderColor('#CCCCCC')
// 登录按钮
Button({type:ButtonType.Normal}){
Text('登 录')
}
.width('90%')
.height(48)
.margin({ top: 40 })
.borderRadius(8)
.backgroundColor($r('app.color.main_color'))
.fontColor('#FFFFFF')
.fontSize(18)
.onClick(() => {
// 处理登录逻辑
if (!/^1[3-9]\d{9}$/.test(this.phoneNumber)) {
promptAction.showToast({message:'请输入有效手机号'})
return
}
if (!this.smsCode) {
promptAction.showToast({message:'请输入验证码'})
return
}
if (!/^(?=.*[a-zA-Z])(?=.*\d)[\w]{6,16}$/.test(this.password)) {
promptAction.showToast({message:'密码格式不正确'})
return
}
// 执行登录操作...
})
}
.width('100%')
.height('100%')
.backgroundColor('#FFFFFF')
}
}
@@ -0,0 +1,152 @@
import { it } from "@ohos/hypium";
import { MyPageSectionClass } from "../model/MyPageSectionClass";
import { MyPageSectionItem } from '../view/MyPageSectionItem'
import { common, Want } from '@kit.AbilityKit';
import notificationManager from '@ohos.notificationManager';
import { Theme } from "@ohos.arkui.theme";
import { BusinessError } from "@kit.BasicServicesKit";
import emitter from '@ohos.events.emitter';
@Component
export struct FourSection {
@State sectionTitle: string = "常规操作";
@State currentIndex: number = 0;
@State pushStatus: string = '通知已开';
@State refreshFlag: boolean = false;
@State fourSectionList:Array<MyPageSectionClass> = [
new MyPageSectionClass('oneItem',$r('app.media.app_icon'),'微信绑定','/pages/MyHomePage'),
new MyPageSectionClass('twoItem',$r('app.media.app_icon'),'更换手机号','/pages/MyHomePage'),
new MyPageSectionClass('threeItem',$r('app.media.app_icon'),this.pushStatus,'/pages/MyHomePage'),
new MyPageSectionClass('fourItem',$r('app.media.app_icon'),'发现新版本','/pages/MyHomePage')
];
aboutToAppear() {
console.log('FourSection aboutToAppear!');
this.checkNotificationStatus();
// 监听通知状态变化事件
emitter.on('notification_status_changed', this.onNotificationChanged);
}
aboutToDisappear() {
// 取消事件监听
emitter.off('notification_status_changed', this.onNotificationChanged);
}
private onNotificationChanged = () => {
console.log('收到通知状态变化事件');
this.checkNotificationStatus();
}
private getPagedItems(): Array<Array<MyPageSectionClass>> {
const pages: Array<Array<MyPageSectionClass>> = [];
const itemsPerPage = 4;
for (let i = 0; i < this.fourSectionList.length; i += itemsPerPage) {
pages.push(this.fourSectionList.slice(i, i + itemsPerPage));
}
return pages;
}
async checkNotificationStatus() {
try {
let isEnabled = await notificationManager.isNotificationEnabledSync();
console.log('当前通知状态:', isEnabled);
this.pushStatus = isEnabled ? '通知已开' : '通知已关';
// 更新数组中的标题
this.fourSectionList = this.fourSectionList.map((item, index) => {
if (index === 2) {
return new MyPageSectionClass(item.id, item.imageSrc, this.pushStatus, item.path);
}
return item;
});
} catch (error) {
console.error('Failed to check notification status:', error);
}
}
private handleNotificationClick() {
let want: Want = {
bundleName: 'com.huawei.hmos.settings',
abilityName: 'com.huawei.hmos.settings.MainAbility',
uri: 'application_info_entry',
parameters: {
pushParams: 'com.example.expert'
}
};
const context = getContext(this) as common.UIAbilityContext;
// 发送全局事件
emitter.emit('notification_status_changed');
context.startAbility(want).catch((err:BusinessError) => {
console.error('Failed to start ability:', err);
});
}
build() {
Column() {
// 标题
Text(this.sectionTitle)
.fontSize(17)
.fontWeight(FontWeight.Bold)
.margin({ top: 10, left: 13 })
.height(42)
Column() {
Stack({ alignContent: Alignment.Bottom }) {
Swiper() {
ForEach(this.getPagedItems(), (pageItems: Array<MyPageSectionClass>, index?: number) => {
Grid() {
ForEach(pageItems, (item: MyPageSectionClass) => {
GridItem() {
MyPageSectionItem({ sectionItem: item })
}
.onClick(()=>{
if (item.title.includes('通知')) {
this.handleNotificationClick();
}
})
}, (item: MyPageSectionClass) => item.id)
}
.columnsTemplate('1fr 1fr 1fr 1fr')
.columnsGap(8)
.rowsGap(8)
.height('100%')
.width('100%')
})
}
.index(this.currentIndex)
.onChange((index: number) => {
this.currentIndex = index;
})
.height(78)
.indicator(false)
if (this.fourSectionList.length > 4) {
Row() {
ForEach(new Array(Math.ceil(this.fourSectionList.length / 4)).fill(0), (item: number, idx: number) => {
Row()
.width('50%')
.height(6)
.borderRadius(3)
.backgroundColor(this.currentIndex === idx ? '#8B2316' :
'#D8D8D8')// .margin({ right: idx !== Math.ceil(this.oneSectionList.length / 4) - 1 ? 0 : 0 })
.margin({ right: 0 })
}, (item: number, index: number) => index.toString())
}
.justifyContent(FlexAlign.Center)
.backgroundColor('#D8D8D8')
.height(6)
.width(23)
.borderRadius(3)
.margin({ bottom: 8 })
}
}
}
.padding({ left: 20, right: 20 })
}
.alignItems(HorizontalAlign.Start)
.backgroundColor(Color.White)
.borderRadius(5)
.margin({ top: 10, left: 10, right: 10 })
}
}
@@ -0,0 +1,81 @@
import { HeroPopWindow } from '../view/HeroPopWindow'
import { router } from '@kit.ArkUI'
@Preview
@Component
export struct HeaderView {
@State heroIndex: number = 0 // 当前页索引
private scrollerForList: Scroller = new Scroller()
private heroList: string[] = ['2020年英雄榜','2021年英雄榜','2022年英雄榜','2023年英雄榜','2024年英雄榜']
dialogController: CustomDialogController = new CustomDialogController({
builder: HeroPopWindow(),
alignment: DialogAlignment.Center,
customStyle: true
})
handleAvatarClick() {
router.pushUrl({url:'pages/MinePage/EditUserDataPage'})
}
build() {
// Row() {
Column({space:5}) {
Row({space:10}) {
Image($r('app.media.app_icon'))
.margin({left:15})
.width(60)
.height(60)
.borderRadius(30)
.objectFit(ImageFit.Fill)
.onClick(()=>this.handleAvatarClick())
Column({space:5}) {
Text('段钟平专家工作室')
.fontSize(18)
.fontColor('#333')
.onClick(()=>this.handleAvatarClick())
List({space:5,initialIndex:this.heroIndex,scroller:this.scrollerForList}) {
ForEach(this.heroList, (item: string,index:number) => {
ListItem() {
Row() {
Image($r('app.media.app_icon'))
.width(13)
.height(13)
.margin({left:7})
Text(item)
.fontColor(Color.White)
.fontSize(11)
.margin({left:4,right:10})
}
.height(18)
// .width('autp')
.margin({right:5})
.borderRadius(9)
.borderWidth(1)
.borderColor(Color.White)
.onClick(() => {
console.log('Show HeroPopWindow');
})
.onClick(()=>this.dialogController.open())
}
})
}
.listDirection(Axis.Horizontal)
.scrollBar(BarState.Off)
.width('100%')
.height(18)
}
.alignItems(HorizontalAlign.Start)
.height(60)
.width('70%')
.margin({top:22})
}
.width('100%')
.height(97)
}
.width('100%')
.height(97)
.backgroundColor(Color.Green)
}
// }
}
@@ -0,0 +1,83 @@
import { it } from "@ohos/hypium";
@CustomDialog
export struct HeroPopWindow {
private years: string[] = ['2019年英雄榜','2018年英雄榜','2017年英雄榜','2016年英雄榜','2015年英雄榜'];
controller: CustomDialogController;
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,19 @@
import { MyPageSectionClass } from "../model/MyPageSectionClass"
@Component
export struct MyPageSectionItem {
@Prop sectionItem: MyPageSectionClass;
build() {
Column(){
Image(this.sectionItem.imageSrc)
.backgroundColor(Color.Gray)
.width(35).height(35)
.borderRadius(17.5)
Text(this.sectionItem.title)
.fontSize(12)
.fontColor(Color.Black)
.margin({top:6})
}
}
}
@@ -0,0 +1,103 @@
import { hdHttp, HdResponse,BasicConstant, logger,RequestDefaultModel, Data } from '@itcast/basic'
import { promptAction } from '@kit.ArkUI'
import HashMap from '@ohos.util.HashMap';
import { BusinessError } from '@kit.BasicServicesKit';
interface DefaultData {
'officeName':string;
'officeUuid':string;
}
@CustomDialog
export struct OfficeSelectedSheet {
controller: CustomDialogController;
@State officeNameArr:Array<string> = [];
private officeArr:Array<DefaultData> = [];
@Prop selectedOffice:object = new Object;
@State selectedModel:DefaultData = { officeName: '', officeUuid: '' };
// 添加回调函数属性
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>) => {
logger.info('Response officelist success'+res);
console.info(`Response officelist succeeded: ${res}`);
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);
} else {
console.error('科室数据失败:'+json.message)
promptAction.showToast({ message: json.message, duration: 1000 })
}
}).catch((err: BusinessError) => {
console.info(`Response login 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.officeName, this.selectedModel.officeUuid);
})
}
.height(40)
TextPicker({
range:this.officeNameArr
})
.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,88 @@
import { it } from "@ohos/hypium";
import { MyPageSectionClass } from "../model/MyPageSectionClass";
import { MyPageSectionItem } from '../view/MyPageSectionItem'
@Preview
@Component
export struct OneSection {
@State sectionTitle: string = "随访服务";
@State currentIndex: number = 0;
@State oneSectionList: Array<MyPageSectionClass> = [
new MyPageSectionClass('oneItem', $r('app.media.app_icon'), '患者审核', '/pages/MyHomePage'),
new MyPageSectionClass('twoItem', $r('app.media.app_icon'), '患者分组', '/pages/MyHomePage'),
new MyPageSectionClass('threeItem', $r('app.media.app_icon'), '群发消息', '/pages/MyHomePage'),
new MyPageSectionClass('fourItem', $r('app.media.app_icon'), '随访二维码', '/pages/MyHomePage'),
new MyPageSectionClass('fiveItem', $r('app.media.app_icon'), '出诊计划', '/pages/MyHomePage')
];
private getPagedItems(): Array<Array<MyPageSectionClass>> {
const pages: Array<Array<MyPageSectionClass>> = [];
const itemsPerPage = 4;
for (let i = 0; i < this.oneSectionList.length; i += itemsPerPage) {
pages.push(this.oneSectionList.slice(i, i + itemsPerPage));
}
return pages;
}
build() {
Column() {
// 标题
Text(this.sectionTitle)
.fontSize(17)
.fontWeight(FontWeight.Bold)
.margin({ top: 10, left: 13 })
.height(42)
Column() {
Stack({ alignContent: Alignment.Bottom }) {
Swiper() {
ForEach(this.getPagedItems(), (pageItems: Array<MyPageSectionClass>, index?: number) => {
Grid() {
ForEach(pageItems, (item: MyPageSectionClass) => {
GridItem() {
MyPageSectionItem({ sectionItem: item })
}
}, (item: MyPageSectionClass) => item.id)
}
.columnsTemplate('1fr 1fr 1fr 1fr')
.columnsGap(8)
.rowsGap(8)
.height('100%')
.width('100%')
})
}
.index(this.currentIndex)
.onChange((index: number) => {
this.currentIndex = index;
})
.height(78)
.indicator(false)
Row() {
ForEach(new Array(Math.ceil(this.oneSectionList.length / 4)).fill(0), (item: number, idx: number) => {
Row()
.width('50%')
.height(6)
.borderRadius(3)
.backgroundColor(this.currentIndex === idx ? '#8B2316' : '#D8D8D8')
// .margin({ right: idx !== Math.ceil(this.oneSectionList.length / 4) - 1 ? 0 : 0 })
.margin({ right:0 })
}, (item: number, index: number) => index.toString())
}
.justifyContent(FlexAlign.Center)
.backgroundColor('#D8D8D8')
.height(6)
.width(23)
.borderRadius(3)
.margin({ bottom: 8 })
}
}
.padding({ left: 20, right: 20 })
}
.alignItems(HorizontalAlign.Start)
.backgroundColor(Color.White)
.borderRadius(5)
.margin({ top: 10, left: 10, right: 10 })
}
}
@@ -0,0 +1,70 @@
import { router } from '@kit.ArkUI'
class ListClass {
id: number = 0;
imageSrc: ResourceStr = '';
content: string = ''
constructor(id: number, imageSrc: ResourceStr, content: string) {
this.id = id
this.imageSrc = imageSrc;
this.content = content;
}
}
@Preview
@Component
export struct OtherList {
@State otherList:Array<ListClass>=[
// new ListClass(1,$r('app.media.app_icon'),'福利卡兑换'),
// new ListClass(2,$r('app.media.app_icon'),'发票管理'),
// new ListClass(3,$r('app.media.app_icon'),'常用银行卡'),
new ListClass(4,$r('app.media.app_icon'),'设置与帮助')
]
build() {
Row() {
List() {
ForEach(this.otherList,(model:ListClass)=>{
ListItem(){
Column(){
Row() {
Image(model.imageSrc)
.width(22)
.height(22)
.margin({left:15})
Text(model.content)
.fontSize(12)
.margin({left:10})
Blank()
Image($r('sys.media.ohos_ic_public_arrow_right'))
.width(15)
.height(15)
.margin({right:10})
}
.width('100%')
.height(52)
.justifyContent(FlexAlign.SpaceBetween)
.onClick(()=>{
router.pushUrl({url:'pages/MinePage/SettingPage'})
})
if (model.id <= 3) {
Divider()
.color('#F4F4F4')
.strokeWidth(1)
.height(1)
.margin({left:10,top:0})
}
}
.justifyContent(FlexAlign.Start)
}
.height(53)
})
}
.backgroundColor(Color.White)
.borderRadius(5)
.margin({top:10,left:10,right:10})
}
}
}
@@ -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,103 @@
import { hdHttp, HdResponse,BasicConstant, logger,RequestDefaultModel, Data } from '@itcast/basic'
import { promptAction } from '@kit.ArkUI'
import HashMap from '@ohos.util.HashMap';
import { BusinessError } from '@kit.BasicServicesKit';
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: '' };
// 添加回调函数属性
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>) => {
logger.info('Response officelist success'+res);
console.info(`Response officelist succeeded: ${res}`);
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);
console.log('职称名称数组:', this.officeNameArr);
} else {
console.error('职称数据失败:'+json.message)
promptAction.showToast({ message: json.message, duration: 1000 })
}
}).catch((err: BusinessError) => {
console.info(`Response login 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
})
.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,91 @@
import { it } from "@ohos/hypium";
import { MyPageSectionClass } from "../model/MyPageSectionClass";
import { MyPageSectionItem } from '../view/MyPageSectionItem'
@Preview
@Component
export struct ThreeSection {
@State sectionTitle:string="账户明细";
@State currentIndex: number = 0;
@State threeSectionList:Array<MyPageSectionClass> = [
new MyPageSectionClass('oneItem',$r('app.media.app_icon'),'我的账户','/pages/MyHomePage'),
new MyPageSectionClass('twoItem',$r('app.media.app_icon'),'我的积分','/pages/MyHomePage'),
new MyPageSectionClass('threeItem',$r('app.media.app_icon'),'我的福利','/pages/MyHomePage'),
new MyPageSectionClass('fourItem',$r('app.media.app_icon'),'我的鲜花','/pages/MyHomePage'),
new MyPageSectionClass('fiveItem',$r('app.media.app_icon'),'课件明细','/pages/MyHomePage'),
new MyPageSectionClass('fiveItem',$r('app.media.app_icon'),'课程明细','/pages/MyHomePage')
];
private getPagedItems(): Array<Array<MyPageSectionClass>> {
const pages: Array<Array<MyPageSectionClass>> = [];
const itemsPerPage = 4;
for (let i = 0; i < this.threeSectionList.length; i += itemsPerPage) {
pages.push(this.threeSectionList.slice(i, i + itemsPerPage));
}
return pages;
}
build() {
Column() {
// 标题
Text(this.sectionTitle)
.fontSize(17)
.fontWeight(FontWeight.Bold)
.margin({ top: 10, left: 13 })
.height(42)
Column() {
Stack({ alignContent: Alignment.Bottom }) {
Swiper() {
ForEach(this.getPagedItems(), (pageItems: Array<MyPageSectionClass>, index?: number) => {
Grid() {
ForEach(pageItems, (item: MyPageSectionClass) => {
GridItem() {
MyPageSectionItem({ sectionItem: item })
}
}, (item: MyPageSectionClass) => item.id)
}
.columnsTemplate('1fr 1fr 1fr 1fr')
.columnsGap(8)
.rowsGap(8)
.height('100%')
.width('100%')
})
}
.index(this.currentIndex)
.onChange((index: number) => {
this.currentIndex = index;
})
.height(78)
.indicator(false)
if (this.threeSectionList.length > 4) {
Row() {
ForEach(new Array(Math.ceil(this.threeSectionList.length / 4)).fill(0), (item: number, idx: number) => {
Row()
.width('50%')
.height(6)
.borderRadius(3)
.backgroundColor(this.currentIndex === idx ? '#8B2316' :
'#D8D8D8')// .margin({ right: idx !== Math.ceil(this.oneSectionList.length / 4) - 1 ? 0 : 0 })
.margin({ right: 0 })
}, (item: number, index: number) => index.toString())
}
.justifyContent(FlexAlign.Center)
.backgroundColor('#D8D8D8')
.height(6)
.width(23)
.borderRadius(3)
.margin({ bottom: 8 })
}
}
}
.padding({ left: 20, right: 20 })
}
.alignItems(HorizontalAlign.Start)
.backgroundColor(Color.White)
.borderRadius(5)
.margin({ top: 10, left: 10, right: 10 })
}
}
@@ -0,0 +1,89 @@
import { it } from "@ohos/hypium";
import { MyPageSectionClass } from "../model/MyPageSectionClass";
import { MyPageSectionItem } from '../view/MyPageSectionItem'
@Preview
@Component
export struct TwoSection {
@State sectionTitle:string="学习进步";
@State currentIndex: number = 0;
@State twoSectionList:Array<MyPageSectionClass> = [
new MyPageSectionClass('oneItem',$r('app.media.app_icon'),'我的视频','/pages/MyHomePage'),
new MyPageSectionClass('twoItem',$r('app.media.app_icon'),'我的课程','/pages/MyHomePage'),
new MyPageSectionClass('threeItem',$r('app.media.app_icon'),'我的下载','/pages/MyHomePage'),
new MyPageSectionClass('fourItem',$r('app.media.app_icon'),'我的收藏','/pages/MyHomePage')
];
private getPagedItems(): Array<Array<MyPageSectionClass>> {
const pages: Array<Array<MyPageSectionClass>> = [];
const itemsPerPage = 4;
for (let i = 0; i < this.twoSectionList.length; i += itemsPerPage) {
pages.push(this.twoSectionList.slice(i, i + itemsPerPage));
}
return pages;
}
build() {
Column() {
// 标题
Text(this.sectionTitle)
.fontSize(17)
.fontWeight(FontWeight.Bold)
.margin({ top: 10, left: 13 })
.height(42)
Column() {
Stack({ alignContent: Alignment.Bottom }) {
Swiper() {
ForEach(this.getPagedItems(), (pageItems: Array<MyPageSectionClass>, index?: number) => {
Grid() {
ForEach(pageItems, (item: MyPageSectionClass) => {
GridItem() {
MyPageSectionItem({ sectionItem: item })
}
}, (item: MyPageSectionClass) => item.id)
}
.columnsTemplate('1fr 1fr 1fr 1fr')
.columnsGap(8)
.rowsGap(8)
.height('100%')
.width('100%')
})
}
.index(this.currentIndex)
.onChange((index: number) => {
this.currentIndex = index;
})
.height(78)
.indicator(false)
if (this.twoSectionList.length > 4) {
Row() {
ForEach(new Array(Math.ceil(this.twoSectionList.length / 4)).fill(0), (item: number, idx: number) => {
Row()
.width('50%')
.height(6)
.borderRadius(3)
.backgroundColor(this.currentIndex === idx ? '#8B2316' :
'#D8D8D8')// .margin({ right: idx !== Math.ceil(this.oneSectionList.length / 4) - 1 ? 0 : 0 })
.margin({ right: 0 })
}, (item: number, index: number) => index.toString())
}
.justifyContent(FlexAlign.Center)
.backgroundColor('#D8D8D8')
.height(6)
.width(23)
.borderRadius(3)
.margin({ bottom: 8 })
}
}
}
.padding({ left: 20, right: 20 })
}
.alignItems(HorizontalAlign.Start)
.backgroundColor(Color.White)
.borderRadius(5)
.margin({ top: 10, left: 10, right: 10 })
}
}
+11
View File
@@ -0,0 +1,11 @@
{
"module": {
"name": "mypage",
"type": "har",
"deviceTypes": [
"default",
"tablet",
"2in1"
]
}
}
@@ -0,0 +1,8 @@
{
"float": [
{
"name": "page_text_font_size",
"value": "50fp"
}
]
}
@@ -0,0 +1,8 @@
{
"string": [
{
"name": "page_show",
"value": "page from package"
}
]
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

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: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

@@ -0,0 +1,35 @@
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);
})
})
}
@@ -0,0 +1,5 @@
import abilityTest from './Ability.test';
export default function testsuite() {
abilityTest();
}
+13
View File
@@ -0,0 +1,13 @@
{
"module": {
"name": "mypage_test",
"type": "feature",
"deviceTypes": [
"default",
"tablet",
"2in1"
],
"deliveryWithInstall": true,
"installationFree": false
}
}
+5
View File
@@ -0,0 +1,5 @@
import localUnitTest from './LocalUnit.test';
export default function testsuite() {
localUnitTest();
}
@@ -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);
});
});
}