feat: 电子药箱小程序 - 4Tab药品管理
- 电子药箱: 药品库存管理 + 手动录入 + 今日用药打卡 - 药品百科: 搜索 + 分类筛选 + 20种药品静态数据 - 惠教中心: 4条药品使用指南课程 - 我的: 家庭成员信息管理 - 自定义TabBar + navigation-bar组件 - SVG药品分类插图
This commit is contained in:
@@ -0,0 +1,206 @@
|
||||
interface PlayerProperties {
|
||||
isPlayback: boolean;
|
||||
isLiving: boolean;
|
||||
pullUrlInfo: {
|
||||
rtmpUrl: string;
|
||||
rtmpOriaacUrl: string;
|
||||
hlsOriaacUrl: string;
|
||||
hlsUrl: string;
|
||||
};
|
||||
vodInfo: {
|
||||
state: number;
|
||||
pullUrl: string;
|
||||
};
|
||||
}
|
||||
|
||||
interface PlayerData {
|
||||
liveUrl: string;
|
||||
vodUrl: string;
|
||||
isPlaying: boolean;
|
||||
showVideo: boolean;
|
||||
fullScreen: boolean;
|
||||
height: number;
|
||||
retryCount: number;
|
||||
maxRetryCount: number;
|
||||
}
|
||||
|
||||
interface PlayerComponent extends WechatMiniprogram.Component.TrivialInstance {
|
||||
data: PlayerData;
|
||||
properties: PlayerProperties;
|
||||
videoContext: WechatMiniprogram.VideoContext | null;
|
||||
}
|
||||
|
||||
Component({
|
||||
properties: {
|
||||
isPlayback: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
isLiving: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
pullUrlInfo: {
|
||||
type: Object,
|
||||
value: {
|
||||
rtmpUrl: "",
|
||||
rtmpOriaacUrl: "",
|
||||
hlsOriaacUrl: "",
|
||||
hlsUrl: "",
|
||||
},
|
||||
},
|
||||
vodInfo: {
|
||||
type: Object,
|
||||
value: {
|
||||
state: 0,
|
||||
pullUrl: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
data: {
|
||||
liveUrl: "",
|
||||
vodUrl: "",
|
||||
isPlaying: false,
|
||||
fullScreen: false,
|
||||
height: 0,
|
||||
showVideo: true,
|
||||
retryCount: 0,
|
||||
maxRetryCount: 3,
|
||||
},
|
||||
|
||||
lifetimes: {
|
||||
attached(this: PlayerComponent) {
|
||||
this.initPlayer();
|
||||
},
|
||||
detached(this: PlayerComponent) {
|
||||
this.cleanup();
|
||||
},
|
||||
},
|
||||
|
||||
observers: {
|
||||
"isLiving, pullUrlInfo": function (
|
||||
this: PlayerComponent,
|
||||
isLiving: boolean,
|
||||
pullUrlInfo: PlayerProperties["pullUrlInfo"]
|
||||
) {
|
||||
if (isLiving && pullUrlInfo.rtmpUrl) {
|
||||
this.setData({ liveUrl: pullUrlInfo.rtmpUrl });
|
||||
} else {
|
||||
this.setData({ liveUrl: "" });
|
||||
}
|
||||
},
|
||||
vodInfo: function (
|
||||
this: PlayerComponent,
|
||||
data: PlayerProperties["vodInfo"]
|
||||
) {
|
||||
if (data && data.pullUrl) {
|
||||
this.setData({
|
||||
vodUrl: data.pullUrl,
|
||||
isPlaying: true,
|
||||
showVideo: true,
|
||||
});
|
||||
this.playVideo();
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
playVideo(this: PlayerComponent) {
|
||||
if (!this.videoContext || !this.data.showVideo) return;
|
||||
setTimeout(() => {
|
||||
try {
|
||||
this.videoContext?.play();
|
||||
} catch (error) {
|
||||
this.handlePlayError();
|
||||
}
|
||||
}, 500);
|
||||
},
|
||||
|
||||
handlePlayError(this: PlayerComponent) {
|
||||
const { retryCount, maxRetryCount } = this.data;
|
||||
if (retryCount < maxRetryCount) {
|
||||
this.setData({ retryCount: retryCount + 1 });
|
||||
setTimeout(() => {
|
||||
this.playVideo();
|
||||
}, 2000);
|
||||
} else {
|
||||
this.setData({
|
||||
showVideo: false,
|
||||
retryCount: 0,
|
||||
});
|
||||
wx.showToast({
|
||||
title: "播放失败,请检查网络连接",
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
initPlayer(this: PlayerComponent) {
|
||||
try {
|
||||
const sysInfo = wx.getSystemInfoSync();
|
||||
this.setData({ height: sysInfo.screenHeight });
|
||||
this.videoContext = wx.createVideoContext("vodVideo", this);
|
||||
} catch (err) {
|
||||
console.error("初始化播放器失败:", err);
|
||||
wx.showToast({ title: "播放器初始化失败", icon: "none" });
|
||||
}
|
||||
},
|
||||
|
||||
onLiveStateChange(
|
||||
this: PlayerComponent,
|
||||
event: WechatMiniprogram.CustomEvent
|
||||
) {
|
||||
const code = event.detail.code;
|
||||
const stateMap: Record<number, string> = {
|
||||
2001: "已连接",
|
||||
2002: "已断开",
|
||||
2003: "缓冲中",
|
||||
2004: "播放开始",
|
||||
2005: "播放结束",
|
||||
2006: "加载中",
|
||||
};
|
||||
console.log("直播状态:", stateMap[code] || `未知(${code})`);
|
||||
},
|
||||
|
||||
onLiveError(this: PlayerComponent, event: WechatMiniprogram.CustomEvent) {
|
||||
const errCode = event.detail.errCode;
|
||||
const errorMap: Record<number, string> = {
|
||||
10001: "系统错误",
|
||||
10002: "网络错误",
|
||||
10003: "解码错误",
|
||||
10004: "直播流不存在",
|
||||
};
|
||||
const msg = errorMap[errCode] || `直播错误: ${event.detail.errMsg}`;
|
||||
wx.showToast({ title: msg, icon: "none" });
|
||||
},
|
||||
|
||||
onVideoPlay(this: PlayerComponent) {
|
||||
this.setData({ isPlaying: true, retryCount: 0, showVideo: true });
|
||||
},
|
||||
onVideoPause(this: PlayerComponent) {
|
||||
this.setData({ isPlaying: false });
|
||||
},
|
||||
onVideoEnded(this: PlayerComponent) {
|
||||
this.setData({ isPlaying: false });
|
||||
},
|
||||
onVideoError(this: PlayerComponent, err: WechatMiniprogram.CustomEvent) {
|
||||
if (err) {
|
||||
this.setData({ isPlaying: false, showVideo: false });
|
||||
this.triggerEvent("controlstoggle", { state: 2 });
|
||||
}
|
||||
},
|
||||
|
||||
cleanup(this: PlayerComponent) {
|
||||
this.videoContext = null;
|
||||
this.setData({
|
||||
liveUrl: "",
|
||||
vodUrl: "",
|
||||
isPlaying: false,
|
||||
fullScreen: false,
|
||||
showVideo: true,
|
||||
retryCount: 0,
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user