易得天气
天气预报需要添加数据库能力,用以保存城市的天气数据
数据库使用的是:storm
"@zxhhyj/storm": "^2.0.2"
创建数据库
class AppDatabase extends Database {
initDb(context: Context): Promise<relationalStore.RdbStore> {
return relationalStore.getRdbStore(context, { name: "app.db", securityLevel: relationalStore.SecurityLevel.S1 })
}
readonly cityDataDao = TableCityData
}
export const myDatabase = Storm
.databaseBuilder(AppDatabase)
.setVersion(1)// 设置数据库的版本
.addMigrations(AutoMigration)// 设置当数据库未初始化时自动初始化,初始化后的版本号为 setVersion 设置版本号,即 1
.build()
定义表和实体
export interface CityData {
id?: number
key: string
city_level_name?: string
name?: string
street?: string
country?: string
upper?: string
prov?: string
prov_en?: string
cityid?: string
city_level_id?: string
isLocationCity: boolean
weatherData?: SimpleWeatherData
}
export class CityDataTable extends Table<CityData> {
readonly tableName = 't_city_data'
readonly id = Column.integer('id').primaryKey(true).bindTo(this, 'id')
readonly key = Column.text('key').default('').bindTo(this, 'key')
readonly city_level_name = Column.text('city_level_name').default('').bindTo(this, 'city_level_name')
readonly name = Column.text('name').default('').bindTo(this, 'name')
readonly street = Column.text('street').default('').bindTo(this, 'street')
readonly country = Column.text('country').default('').bindTo(this, 'country')
readonly upper = Column.text('upper').default('').bindTo(this, 'upper')
readonly prov = Column.text('prov').default('').bindTo(this, 'prov')
readonly prov_en = Column.text('prov_en').default('').bindTo(this, 'prov_en')
readonly cityid = Column.text('cityid').default('').bindTo(this, 'cityid')
readonly city_level_id = Column.text('city_level_id').default('').bindTo(this, 'city_level_id')
readonly isLocationCity = Column.boolean('isLocationCity').default(0).bindTo(this, 'isLocationCity')
readonly weatherData =
Column.references('simple_weather_data_id', TableSimpleWeatherData).default(null).bindTo(this, 'weatherData')
}
export const TableCityData = new CityDataTable()
export interface SimpleWeatherData {
id?: number
city: string
temp: number
tempHigh: number
tempLow: number
weatherType: string
weatherDesc: string
sunrise: string
sunset: string
}
export class SimpleWeatherDataTable extends Table<SimpleWeatherData> {
readonly tableName = 't_simple_weather_data'
readonly id = Column.integer('id').primaryKey(true).bindTo(this, 'id')
readonly city = Column.text('city').default('').bindTo(this, 'city')
readonly temp = Column.integer('temp').default(0).bindTo(this, 'temp')
readonly tempHigh = Column.integer('tempHigh').default(0).bindTo(this, 'tempHigh')
readonly tempLow = Column.integer('tempLow').default(0).bindTo(this, 'tempLow')
readonly weatherType = Column.text('weatherType').default('').bindTo(this, 'weatherType')
readonly weatherDesc = Column.text('weatherDesc').default('').bindTo(this, 'weatherDesc')
readonly sunrise = Column.text('sunrise').default('').bindTo(this, 'sunrise')
readonly sunset = Column.text('sunset').default('').bindTo(this, 'sunset')
}
export const TableSimpleWeatherData = new SimpleWeatherDataTable()
初始化数据库
export class AppAbilityStage extends AbilityStage {
async onCreate(): Promise<void> {
// 应用HAP首次加载时触发,可以在此执行该Module的初始化操作(例如资源预加载、线程创建等)。
// 在module.json5配置文件中,通过配置 srcEntry 参数来指定模块对应的代码路径,以作为HAP加载的入口。
// 初始化路由
ZRouter.initialize((config) => {
config.isLoggingEnabled = BuildProfile.DEBUG
config.isHSPModuleDependent = true
// 服务路由初始化配置,如果没有使用服务路由,可不设置
// config.loadDynamicModule = ['@hzw/hara', 'harb', 'hspc']
config.onDynamicLoadComplete = () => {
console.log("已完成所有模块的加载")
}
})
await myDatabase.init(this.context)
}
}
闪屏页修改
@Route({ name: RouterConstants.SPLASH_PAGE })
@ComponentV2
export struct SplashPage {
build() {
NavDestination() {
Column() {
Image($r('app.media.splash'))
.width('100%')
.height('100%')
.objectFit(ImageFit.Cover)
}
}
.hideTitleBar(true)
.height('100%')
.width('100%')
.onAppear(() => {
Logger.e('SplashPage aboutToAppear')
setTimeout(() => {
this.handle()
}, 800)
})
.onBackPressed(() => {
console.log('onBackPressed');
return true
})
}
handle() {
myDatabase.beginAsync((db) => {
let locationCity = db.cityDataDao.firstOrNull(it => it.equalTo(TableCityData.key, Constants.LOCATION_CITY_ID))
Logger.e('locationCity = ' + locationCity)
if (locationCity == null) {
locationCity = {
key: Constants.LOCATION_CITY_ID,
isLocationCity: true
}
db.cityDataDao.add(locationCity)
}
let currentCityId = PreferencesUtil.getStringSync(Constants.CURRENT_CITY_ID)
if (StrUtil.isNotEmpty(locationCity?.cityid) || StrUtil.isNotEmpty(currentCityId)) {
let currentCity = db.cityDataDao.firstOrNull(it => it.equalTo(TableCityData.key, currentCityId))
Logger.e('currentCity = ' + currentCity)
ZRouter.getInstance().replace(RouterConstants.WEATHER_MAIN_PAGE)
} else {
ZRouter.getInstance().replace(RouterConstants.SELECT_CITY_PAGE)
}
})
}
}
新增选择城市页面
@Route({ name: RouterConstants.SELECT_CITY_PAGE })
@ComponentV2
export struct SelectCityPage {
@Computed
get exitApp() {
return ZRouter.getInstance().getAllPathName().length <= 1;
}
@Builder
SearchContent() {
Search({
placeholder: '搜索城市(中文/拼音)',
icon: '/resources/base/media/ic_search_home.webp',
})
.backgroundColor($r('app.color.card_color_02'))
.placeholderFont({ size: 16 })
.placeholderColor($r('app.color.color_999999'))
.searchIcon({ color: $r('app.color.color_999999') })
.padding({ left: 8, right: 8 })
.layoutWeight(1)
}
build() {
NavDestination() {
Column() {
Row() {
this.SearchContent()
if (!this.exitApp) {
Text('取消')
.clickEffect({ level: ClickEffectLevel.HEAVY, scale: 0.8 })
.fontColor($r('app.color.color_999999'))
.fontSize(16)
.padding(8)
.onClick(() => {
ZRouter.getInstance().pop()
})
}
}
.padding({
left: 16,
top: 8,
right: 8,
bottom: 8,
})
Text('城市选择页面')
.fontColor(Color.Black)
.fontSize(16)
.layoutWeight(1)
}
.width('100%')
.height('100%')
}
.hideTitleBar(true)
.padding({ top: px2vp(AppUtil.getStatusBarHeight()) })
.height('100%')
.width('100%')
.onBackPressed(() => {
if (this.exitApp) {
AppUtil.getContext().terminateSelf()
return true
}
return false
})
}
}
逻辑是首次进app由于没有保存的城市数据,先进入城市选择页面让用户添加城市数据,下次进入app就直接展示天气页面