首次提交

master
马超 2025-10-25 18:20:38 +08:00
commit 36b6c794df
162 changed files with 11188 additions and 0 deletions

15
.gitignore vendored Normal file
View File

@ -0,0 +1,15 @@
/node_modules
/oh_modules
/local.properties
/.idea
**/build
/.hvigor
.cxx
/.clangd
/.clang-format
/.clang-tidy
**/.test
/.appanalyzer
/entry/.preview/
/entry/build/
/entry/oh_modules/

10
AppScope/app.json5 Normal file
View File

@ -0,0 +1,10 @@
{
"app": {
"bundleName": "com.ruansee.macall.PersonalCenter",
"vendor": "example",
"versionCode": 1001,
"versionName": "1.0.1",
"icon": "$media:layered_image",
"label": "$string:app_name"
}
}

View File

@ -0,0 +1,22 @@
{
"string": [
{
"name": "app_name",
"value": "个人中心"
},
{
"name": "jiaMi_permission_reason",
"value": "需要加密服务支持"
},
{
"name": "call_permission_reason",
"value": "应用需要电话权限"
},
{
"name": "read_app_list_reason",
"value": "应用需要读取已安装应用列表权限"
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

View File

@ -0,0 +1,7 @@
{
"layered-image":
{
"background" : "$media:background",
"foreground" : "$media:foreground"
}
}

BIN
MdmTool.hap Normal file

Binary file not shown.

69
build-profile.json5 Normal file
View File

@ -0,0 +1,69 @@
{
"app": {
"signingConfigs": [
{
"name": "default",
"type": "HarmonyOS",
"material": {
"storeFile": "D:/HuaweiKey/ruansee.p12",
"storePassword": "000000194A79B357679283987E3A39F5A33CF415CCB392BCFD9BBDB86299490EEF3B09F21493711480",
"keyAlias": "ruansee",
"keyPassword": "00000019F91B99FBE167C23E51E1735C9B00302715D0E3C4200F7949A2F5B0C4CA699648E3FD946189",
"signAlg": "SHA256withECDSA",
"profile": "D:/HuaweiKey/pcenter/ah_pcenter_debug.p7b",
"certpath": "D:/HuaweiKey/pcenter/ah_pcenter_debug.cer"
}
},
{
"name": "wlwDebug",
"type": "HarmonyOS",
"material": {
"storeFile": "D:/HuaweiKey/ruansee.p12",
"storePassword": "00000019C7374A8EC1E56A7A61CE4FDB3C3632C487B5E049DF5A9F29528D05CC94EADE7FB5FD42902A",
"keyAlias": "ruansee",
"keyPassword": "0000001941853B3D69EBECD6347D12C2632C37CC23FFFD6301518D3065E1D8F3256C3DEB6E6294FB6C",
"signAlg": "SHA256withECDSA",
"profile": "D:/HuaweiKey/pcenter/pcenter_debugDebug.p7b",
"certpath": "D:/HuaweiKey/pcenter/pcenter_debug.cer"
}
}
],
"products": [
{
"name": "default",
"signingConfig": "wlwDebug",
"targetSdkVersion": "5.0.5(17)",
"compatibleSdkVersion": "5.0.0(12)",
"runtimeOS": "HarmonyOS",
"buildOption": {
"strictMode": {
"caseSensitiveCheck": true,
"useNormalizedOHMUrl": true
}
}
}
],
"buildModeSet": [
{
"name": "debug"
},
{
"name": "release"
}
]
},
"modules": [
{
"name": "entry",
"srcPath": "./entry",
"targets": [
{
"name": "default",
"applyToProducts": [
"default"
]
}
]
}
]
}

32
code-linter.json5 Normal file
View File

@ -0,0 +1,32 @@
{
"files": [
"**/*.ets"
],
"ignore": [
"**/src/ohosTest/**/*",
"**/src/test/**/*",
"**/src/mock/**/*",
"**/node_modules/**/*",
"**/oh_modules/**/*",
"**/build/**/*",
"**/.preview/**/*"
],
"ruleSet": [
"plugin:@performance/recommended",
"plugin:@typescript-eslint/recommended"
],
"rules": {
"@security/no-unsafe-aes": "error",
"@security/no-unsafe-hash": "error",
"@security/no-unsafe-mac": "warn",
"@security/no-unsafe-dh": "error",
"@security/no-unsafe-dsa": "error",
"@security/no-unsafe-ecdsa": "error",
"@security/no-unsafe-rsa-encrypt": "error",
"@security/no-unsafe-rsa-sign": "error",
"@security/no-unsafe-rsa-key": "error",
"@security/no-unsafe-dsa-key": "error",
"@security/no-unsafe-dh-key": "error",
"@security/no-unsafe-3des": "error"
}
}

6
entry/.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
/node_modules
/oh_modules
/.preview
/build
/.cxx
/.test

28
entry/build-profile.json5 Normal file
View File

@ -0,0 +1,28 @@
{
"apiType": "stageMode",
"buildOption": {
},
"buildOptionSet": [
{
"name": "release",
"arkOptions": {
"obfuscation": {
"ruleOptions": {
"enable": false,
"files": [
"./obfuscation-rules.txt"
]
}
}
}
},
],
"targets": [
{
"name": "default"
},
{
"name": "ohosTest",
}
]
}

6
entry/hvigorfile.ts Normal file
View File

@ -0,0 +1,6 @@
import { hapTasks } from '@ohos/hvigor-ohos-plugin';
export default {
system: hapTasks, /* 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

10
entry/oh-package.json5 Normal file
View File

@ -0,0 +1,10 @@
{
"name": "entry",
"version": "1.0.0",
"description": "Please describe the basic information.",
"main": "",
"author": "",
"license": "",
"dependencies": {}
}

View File

@ -0,0 +1,318 @@
import { StringUtils } from "../util/StringUtils";
import { geoLocationManager } from "@kit.LocationKit";
import { UserCache } from "./UserCache";
import { IdGeneratedUtils } from "../util/IdGeneratedUtils";
/**
* 统一认证系统的SysCode
*/
export const AUTH_SYSCODE = "11e8f9a0948a43d78f68c6af41c12242"
export const BASE_IMAGE_URL = "http://20.90.2.2/pcenter_img_out";
export class AppCache {
private static appCache: AppCache = new AppCache();
private idGeneratedUtils :IdGeneratedUtils|undefined=undefined;
/*请求服务的Ip*/
private ip: string | undefined = undefined
/*请求服务的端口*/
private port: string | undefined = undefined
private serviceNodeName:string = "/pcenter_app_out/"
//用于存放品高的Token
private pgToken :string| undefined = undefined;
//权限状态
private permissionsStatus: boolean = false;
/* TODO 临时人员ID 用于避免每次查询都直接改变peopleId导致查询失败后之前查询的人员信息和ID对不上 */
private peopleTemporarilyId: string = ""
/* TODO 人员ID 只有当查询成功时才将 tempPeopleId的值 赋给 peopleId */
private peopleId: string = ""
/*车辆ID*/
private carId: string = ""
/* TODO 主ID 由APP生成 传递给后端 */
private historyId: string = ""
/*物品ID*/
// private goodsId:string =""
/*缓存的物品数据*/
private goodsJson: string = ""
//本机IP
private localIp: string |undefined= "";
/*任务id*/
private taskId: string|undefined = ""
private taskName:string|undefined = ""
/*卡点id*/
private cardPointId: string|undefined = ""
private cardPointName :string|undefined= ""
//定位的坐标
private locationX: number = 0.0;
private locationY: number = 0.0;
//卡点的坐标
private cardPointX: string = "0.0";
private cardPointY: string = "0.0";
private locationAddress:string|undefined="";
private cardPointAddress:string|undefined="";
private constructor() {
}
//
public static getAppCache(): AppCache {
if (AppCache.appCache == null) {
AppCache.appCache = new AppCache()
}
return AppCache.appCache;
}
/**
* 服务节点
* @param ip
* @param port
* @param serviceName
*/
public setIpOrPort(ip:string,port:string,serviceNodeName:string){
this.ip = ip;
this.port = port;
this.serviceNodeName = serviceNodeName;
}
public getServiceAddress(){
return `http://${this.ip}:${this.port}${this.serviceNodeName}`
}
/**
* 获取一个随机ID 生存规则 四位随机数 + 随机UUID+ 四位随机数
* @returns
*/
public getRandomId(): string {
if (this.idGeneratedUtils == undefined) {
this.idGeneratedUtils = IdGeneratedUtils.getInstance(UserCache.getUserCache().getIdCardNum)
}
return this.idGeneratedUtils.generatedRandomID();
// return (Math.round(1000) + 1000) + util.generateRandomUUID(false) + (Math.round(1000) + 1000)
}
/**
* 将临时人员ID设为ID
* 在查询人员成功后调用
*/
public temporarilyPeopleIdEffect() {
this.peopleId = this.peopleTemporarilyId
this.peopleTemporarilyId = "";
}
/**
* TODO 创建一个临时的人员ID,用于查询人员信息时传参,当查询人员成功后,再赋值给{ peopleId }
*
*/
public createPeopleTemporarilyId() {
this.peopleTemporarilyId = this.getRandomId();
}
public getPeopleTemporarilyId(): string {
if (StringUtils.isNullOrEmpty(this.peopleTemporarilyId)) {
this.peopleTemporarilyId = this.getRandomId();
}
return this.peopleTemporarilyId;
}
public getPeopleId(): string {
if (StringUtils.isNullOrEmpty(this.peopleId)) {
this.peopleId = this.getPeopleTemporarilyId();
}
return this.peopleId
}
public getCarId(): string {
if (StringUtils.isNullOrEmpty(this.carId)) {
this.carId = this.getRandomId();
}
return this.carId;
}
public getHistoryId(): string {
if (StringUtils.isNullOrEmpty(this.historyId)) {
this.historyId = this.getRandomId();
}
return this.historyId;
}
/**
* TODO 仅在初始化页面和提交或移交完成后调用
* 重置ID
*/
public resetIds(){
this.historyId = this.getRandomId();
this.peopleId = this.getRandomId();
this.carId = this.getRandomId();
this.createPeopleTemporarilyId()
}
/**
* 提交成功重置id Submitted successfully
*/
public submitSuccessResetIDs(){
this.peopleId = ""
this.peopleTemporarilyId = ""
this.carId = ""
this.historyId = ""
this.peopleId = ""
this.peopleId = ""
}
/**
* 权限状态
* @returns
*/
get getPermissionsStatus(): boolean {
return this.permissionsStatus;
}
set setPermissionsStatus(permissionsStatus: boolean) {
this.permissionsStatus = permissionsStatus;
}
public setLocation(location :geoLocationManager.Location){
if (location == null) return
this.locationX = location.longitude;
this.locationY = location.latitude;
}
public getLocationX():number{
return this.locationX;
}
public getLocationY():number{
return this.locationY;
}
public setCardLocation(cardPointX:string,cardPointY:string,address:string){
this.cardPointX = cardPointX;
this.cardPointY = cardPointY;
this.cardPointAddress = address;
}
public getCardPointLocationX():string{
return this.cardPointX;
}
public getCardPointLocationY():string{
return this.cardPointY;
}
public set setLocalIp(localIp :string|undefined){
this.localIp = localIp;
}
public get getLocalIp():string|undefined{
return this.localIp;
}
public get getPgToken():string|undefined{
return this.pgToken
}
public set setPgToken(pgToken:string){
this.pgToken = pgToken;
}
public get getTaskId(){
if(StringUtils.isNullOrEmpty(this.taskId)){
return "";
}
if (this.taskId != undefined){
return this.taskId;
}
return ''
}
public set setTaskId(taskId:string|undefined){
this.taskId = taskId;
}
public get getTaskName():string{
if(StringUtils.isNullOrEmpty(this.taskName)){
return "";
}
if (this.taskName != undefined){
return this.taskName;
}
return ''
}
public set setTaskName(taskName:string|undefined){
this.taskName = taskName;
}
public get getCardPointIdId(){
if(StringUtils.isNullOrEmpty(this.cardPointId)){
return "";
}
if (this.cardPointId != undefined){
return this.cardPointId;
}
return ''
}
public set setCardPointId(cardPointId:string|undefined){
this.cardPointId = cardPointId;
}
public get getCardPointName():string{
if(StringUtils.isNullOrEmpty(this.cardPointName)){
return "";
}
if (this.cardPointName != undefined){
return this.cardPointName;
}
return ''
}
public set setCardPointName(cardPointName:string|undefined){
this.cardPointName = cardPointName;
}
public get getLocationAddress():string{
if(StringUtils.isNullOrEmpty(this.locationAddress)){
return "";
}
if (this.locationAddress != undefined){
return this.locationAddress;
}
return ''
}
public set setLocationAddress(locationAddress:string|undefined){
this.locationAddress = locationAddress;
}
public get getCardPointAddress():string{
if(StringUtils.isNullOrEmpty(this.cardPointAddress)){
return "";
}
if (this.cardPointAddress != undefined){
return this.cardPointAddress;
}
return ''
}
/**
* TODO 图片地址转换
* @param photoUrl 原始图片地址
* @returns
*/
convertPhotoUrl(photoUrl:string):string{
if (StringUtils.isNullOrEmpty(photoUrl)) return""
return photoUrl.replace("http://53.1.214.228:9000/ypc","http://20.90.2.2/rcwhy_image_out")
.replace("http://53.1.227.17:9000/ypc","http://20.90.2.2/rcwhy_image_out")
}
}

View File

@ -0,0 +1,46 @@
export class BaseUiModel {
baseType:number = 1
baseMsg:string = ""
}
export default class AppConstants {
/**
* Maximum width.
*/
static readonly PERCENTAGE_MAX: string = '100%';
/**
* 品高的appID和secret
*/
static readonly PG_APP_KEY_SECRET='ksSt5bxNze8SBsPXGt6f:pkPaXjZCHTnzhZhMAhAn8YYbZ6r2H7'
/**
* 盘查方式 - 输入
*/
static readonly CHECK_TYPE_INPUT = 0;
/**
* 盘查方式 - NFC读卡
*/
static readonly CHECK_TYPE_NFC = 1;
/**
* 盘查方式 - 人像识别
*/
static readonly CHECK_TYPE_FACE = 2;
/**
* 盘查方式 - 语音
*/
static readonly CHECK_TYPE_AUDIO = 3;
/**
* 盘查方式 - OCR识别
*/
static readonly CHECK_TYPE_OCR = 4;
/**
* 安徽地市
*/
static readonly AN_HUI_CITY_NAMES :string[] = ["省厅:3400", "合肥:3401", "芜湖:3402", "蚌埠:3403", "淮南:3404",
"马鞍山:3405", "淮北:3406", "铜陵:3407", "安庆:3408", "黄山:3410", "滁州:3411",
"阜阳:3412", "宿州:3413", "六安:3415", "亳州:3416", "池州:3417", "宣城:3418"];
}

View File

@ -0,0 +1,43 @@
import { AbilityConstant, AbilityStage, Configuration, Want } from "@kit.AbilityKit";
import { StringUtils } from "../util/StringUtils";
import { hilog } from "@kit.PerformanceAnalysisKit";
import { AppCache } from "./AppCache";
import { UserCache } from "./UserCache";
// import { tdvision } from "@kit.TdosVisionKit";
export class RuanseeAbilityStag extends AbilityStage{
public static appCache:AppCache;
public static userCache:UserCache;
onCreate(): void {
hilog.info(0x0000, 'RuanseeAbitityStag', '%{public}s', 'AbilityStage onCreate()');
RuanseeAbilityStag.appCache = AppCache.getAppCache();
RuanseeAbilityStag.appCache.setIpOrPort("20.90.2.2", "80","/pcenter_app_out/");
RuanseeAbilityStag.userCache = UserCache.getUserCache();
// tdvision.setup()
}
onAcceptWant(want: Want): string {
hilog.info(0x0000, 'RuanseeAbitityStag', '%{public}s', 'AbilityStage onAcceptWant()');
return StringUtils.get(want.abilityName,"");
}
onNewProcessRequest(want: Want): string {
hilog.info(0x0000, 'RuanseeAbitityStag', '%{public}s', 'AbilityStage onNewProcessRequest()');
return StringUtils.get(want.abilityName,"");
}
onMemoryLevel(level: AbilityConstant.MemoryLevel): void {
hilog.info(0x0000, 'RuanseeAbitityStag', '%{public}s', 'AbilityStage onMemoryLevel()');
}
onConfigurationUpdate(newConfig: Configuration): void {
hilog.info(0x0000, 'RuanseeAbitityStag', '%{public}s', 'AbilityStage onConfigurationUpdate()');
}
}

View File

@ -0,0 +1,189 @@
import { StringUtils } from "../util/StringUtils";
import { buffer, util } from "@kit.ArkTS";
import { UserInfoModel } from "../model/cacheModel/UserInfoModel";
import { AppCache } from "./AppCache";
export class UserCache {
public static userCache: UserCache = new UserCache();
private userName: string = "";
private userCode: string = "";
private deptName: string = "";
private deptCode: string = "";
private idCardNum: string = "";
private phoneNum: string = "";
private userInfo: string = "";
private authToken: string = ""
private profilePhoto: string = "";
private workPhone: string = "";
private email: string = ""
private age: number = 0
private birthdate: string = ""
private policeTypeId: string = ""
private policeTypeName: string = ""
private departmentCode: string = ""
private departmentName: string = ""
private constructor() {
}
public static getUserCache(): UserCache {
if (UserCache.userCache == null) {
UserCache.userCache = new UserCache();
}
return UserCache.userCache;
}
get getDepartmentCode(): string {
return this.departmentCode;
}
set setDepartmentCode(departmentCode: string) {
this.departmentCode = departmentCode;
}
get getDepartmentName(): string {
return this.departmentName;
}
set setDepartmentName(departmentName: string) {
this.departmentName = departmentName;
}
get getUserName(): string {
return this.userName;
}
set setUserName(userName: string) {
this.userName = userName;
}
get getUserCode(): string {
return this.userCode;
}
set setUserCode(userCode: string) {
this.userCode = userCode;
}
get getDeptName(): string {
return this.deptName;
}
set setDeptName(deptName: string) {
this.deptName = deptName;
}
get getDeptCode(): string {
return this.deptCode;
}
set setDeptCode(deptCode: string) {
this.deptCode = deptCode;
}
get getPhoneNum(): string {
return this.phoneNum;
}
set setPhoneNum(phoneNum: string) {
this.phoneNum = phoneNum;
}
get getIdCardNum(): string {
return this.idCardNum;
}
set setIdCardNum(idCardNum: string) {
this.idCardNum = idCardNum;
}
public getUserInfo(): string {
if (StringUtils.isNullOrEmpty(this.userInfo)) {
let cs: UserInfoModel = {
"userCode": UserCache.getUserCache().getUserCode,
"userName": UserCache.getUserCache().getUserName,
"deptName": UserCache.getUserCache().getDeptName,
"deptCode": UserCache.getUserCache().getDeptCode,
"idCardNum": UserCache.getUserCache().getIdCardNum,
"ip": AppCache.getAppCache().getLocalIp || "10.115.101.1",
"departmentCode": UserCache.getUserCache().getDepartmentCode,
"departmentName": UserCache.getUserCache().getDepartmentName,
}
let userInfo = JSON.stringify(cs)
let byte = new Uint8Array(buffer.from(userInfo, 'utf-8').buffer);
this.userInfo = new util.Base64Helper().encodeToStringSync(byte);
}
return this.userInfo
}
public set setUserInfo(userInfo: string) {
this.userInfo = userInfo;
}
get getAuthToken(): string {
return this.authToken;
}
set setAuthToken(authToken: string) {
this.authToken = authToken;
}
get getProfilePhoto(): string {
return this.profilePhoto;
}
set setProfilePhoto(profilePhoto: string) {
this.profilePhoto = profilePhoto;
}
get getWorkPhone(): string {
return this.workPhone;
}
set setWorkPhone(workPhone: string) {
this.workPhone = workPhone;
}
get getEmail(): string {
return this.email;
}
set setEmail(email: string) {
this.email = email;
}
get getAge(): number {
return this.age;
}
set setAge(age: number) {
this.age = age;
}
get getBirthdate(): string {
return this.birthdate;
}
set setBirthdate(birthdate: string) {
this.birthdate = birthdate;
}
get getPoliceTypeId(): string {
return this.policeTypeId;
}
set setPoliceTypeId(policeTypeId: string) {
this.policeTypeId = policeTypeId;
}
get getPoliceTypeName(): string {
return this.policeTypeName;
}
set setPoliceTypeName(policeTypeName: string) {
this.policeTypeName = policeTypeName;
}
}

View File

@ -0,0 +1 @@

View File

@ -0,0 +1,222 @@
import { bundleManager,abilityAccessCtrl, AbilityConstant, ConfigurationConstant,
Permissions,
UIAbility, Want,
common } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { window } from '@kit.ArkUI';
import { HMRouterMgr } from '@hadss/hmrouter';
import { } from '@kit.MDMKit';
import { AppCache } from '../app/AppCache';
import { UserCache } from '../app/UserCache';
import { FileUtils } from '../util/FileUtils';
import { DialogHelper } from '@pura/harmony-dialog';
import { ToastUtils } from '../util/ToasUtils';
import { UnauthorizedPermissionDialog } from '../ui/dialog/UnauthorizedPermissionDialog';
import { AppUtil } from '@pura/harmony-utils';
const DOMAIN = 0x0000;
export default class EntryAbility extends UIAbility {
/**
* TODO {
// "name": "ohos.permission.GET_INSTALLED_BUNDLE_LIST",
// "reason":"$string:read_app_list_reason",
// "usedScene":{
// "abilities":[
// ".EntryAbility"
// ],
// "when":"inuse"
// }
// },
*/
/**
* @param want
* @param launchParam
*/
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET);
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate');
HMRouterMgr.init({
context: this.context
})
AppUtil.init(this.context)
UserCache.getUserCache()
this.applyForPermission()
FileUtils.init(this.context)
//初始化数据库
// DBUtils.getInstance().HOInit(this.context)
// 在Ability中监听事件
this.context.eventHub.on('ui_event', (data:Array<Permissions>) => {
// console.log('Received UI event:', data);
if (data!=null) {
this.requestPermissionsFromUser(data)
}
});
//简单初始化1.0.8版本及以后)
//必须在UIAbility的onCreate方法里初始化context。
DialogHelper.setDefaultConfig((config) => {
config.uiAbilityContext = this.context;
})
}
onDestroy(): void {
this.context.eventHub.off("ui_event")
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy');
}
onWindowStageCreate(windowStage: window.WindowStage): void {
// Main window is created, set main page for this ability
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
windowStage.getMainWindow().then((window=>{
window.setWindowLayoutFullScreen(true)
}))
windowStage.loadContent('ui/pages/Index', (err) => {
if (err.code) {
hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err));
return;
}
hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.');
});
// set main window full screen
// this.setAppFullScreen(windowStage.getMainWindowSync());
}
onWindowStageDestroy(): void {
// Main window is destroyed, release UI related resources
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
}
onForeground(): void {
// Ability has brought to foreground
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground');
}
onBackground(): void {
// Ability has back to background
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground');
}
//申请权限
applyForPermission() {
let permissions = new Array<Permissions>();
permissions.push('ohos.permission.CAMERA')
permissions.push('ohos.permission.LOCATION')
permissions.push('ohos.permission.APPROXIMATELY_LOCATION')
// permissions.push('ohos.permission.GET_INSTALLED_BUNDLE_LIST')
this.checkPermissionGrant(permissions)
}
checkPermissionGrant(permissionArray: Array<Permissions>) {
let uiContext :common.UIAbilityContext = this.context as common.UIAbilityContext;
let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager()
// 获取应用程序的accessTokenID
let bundleInfo = bundleManager.getBundleInfoForSelfSync(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION)
let appInfo: bundleManager.ApplicationInfo = bundleInfo.appInfo
let tokenId: number = appInfo.accessTokenId
let wsqPermissionArray = new Array<Permissions>()
for (let i = 0; i < permissionArray.length; i++) {
let grantStatus = atManager.checkAccessTokenSync(tokenId, permissionArray[i])
if (grantStatus == abilityAccessCtrl.GrantStatus.PERMISSION_DENIED) {
wsqPermissionArray.push(permissionArray[i])
}
}
if (wsqPermissionArray.length>0) {
//有未申请的权限
this.requestPermissionsFromUser(wsqPermissionArray)
}else {
//授权成功
this.sendPermissionSuccess(uiContext)
}
}
/**
*AUTHOR:AbnerMing
*INTRODUCE:向用户获取权限授权
*/
requestPermissionsFromUser(permissions: Array<Permissions>) {
let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager()
let uiContext :common.UIAbilityContext = this.context as common.UIAbilityContext;
atManager.requestPermissionsFromUser(uiContext, permissions)
.then((data) => {
let grantStatus: Array<number> = data.authResults;
let length: number = grantStatus.length;
let notPermissions: Array<Permissions> =new Array<Permissions>();
for (let i = 0; i < length; i++) {
if (grantStatus[i] === 0) {
// 用户授权,可以继续访问目标操作
console.log("===用户授权")
} else {
// 用户拒绝授权,提示用户必须授权才能访问当前页面的功能,并引导用户到系统设置中打开相应的权限
notPermissions.push(permissions[i])
}
}
if (notPermissions.length > 0) {
//授权失败
this.applyPermissionAgain(uiContext,atManager, notPermissions)
}else {
//授权成功
this.sendPermissionSuccess(uiContext)
}
console.log("===权限授权成功")
})
.catch((err:Error) => {
console.error("===权限授权失败")
})
}
/**
* 重新申请授权
* @param uiContext
* @param atManager
* @param notPermissions
*/
applyPermissionAgain(uiContext :common.UIAbilityContext,atManager: abilityAccessCtrl.AtManager,notPermissions: Array<Permissions>){
ToastUtils.toastCenter("您拒绝了权限,请到设置里打开!")
atManager.requestPermissionOnSetting(uiContext,notPermissions)
.then((data) => {
let notAuthorizationCount = 0
data.forEach((item) => {
if (item == -1) {
notAuthorizationCount++
}
})
if (notAuthorizationCount == 0) {
//授权成功
this.sendPermissionSuccess(uiContext)
}else {
//授权失败
this.sendPermissionFailed(uiContext)
}
})
.catch((err:Error) => {
//授权失败
this.sendPermissionFailed(uiContext)
console.error("===权限授权失败")
})
// HMRouterMgr.replace({navigationId:'startNavigation',pageUrl:"MainPage"})
return
}
sendPermissionFailed(uiContext: common.UIAbilityContext){
setTimeout(()=>{
let dat = "NotPermissions"
uiContext.eventHub.emit('NotPermissions',dat);
},1000)
}
sendPermissionSuccess(uiContext: common.UIAbilityContext){
setTimeout(()=>{
let dat = "PermissionsSuccess"
uiContext.eventHub.emit('PermissionsSuccess',dat);
},1000)
}
}

View File

@ -0,0 +1,16 @@
import { hilog } from '@kit.PerformanceAnalysisKit';
import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit';
const DOMAIN = 0x0000;
export default class EntryBackupAbility extends BackupExtensionAbility {
async onBackup() {
hilog.info(DOMAIN, 'testTag', 'onBackup ok');
await Promise.resolve();
}
async onRestore(bundleVersion: BundleVersion) {
hilog.info(DOMAIN, 'testTag', 'onRestore ok %{public}s', JSON.stringify(bundleVersion));
await Promise.resolve();
}
}

View File

@ -0,0 +1,19 @@
export interface UserInfoModel{
"departmentCode": string;
"departmentName": string;
"userCode": string;
"userName": string;
"deptName": string;
"deptCode": string;
"idCardNum": string;
"ip": string;
}
export class WebUserInfoModel{
"userCode": string;
"userName": string;
"deptName": string;
"deptCode": string;
"idCardNum": string;
}

View File

@ -0,0 +1,19 @@
export interface GetAppListRequestModel{
name:string;
page:number;
pageSize: number;
}
export interface GetAppGuideRequestModel{
name:string;
cityNumber:string;
page:number;
pageSize: number;
}
export interface GuideRequest{
applicationId:string
}

View File

@ -0,0 +1,44 @@
import { BASE_IMAGE_URL } from "../../app/AppCache";
import { StringUtils } from "../../util/StringUtils";
export interface GetMsgListRequestModel {
state: number;
page: number;
pageSize: number;
}
export class AddFeedBackRequestModel {
applicationId: string = ""
alarmSignal: string = ""
alarmName: string = ""
type: string = ""
title: string = ""
content: string = ""
applicationName: string = ""
}
export class FeedBackBean {
baseType: number = 1
id: string = ""
type: number = 0
createTime: string = ""
title: string = ""
content: string = ""
applicationName: string = ""
replyStatus: number = 0
replyContent: string = ""
replier: string = ""
updateTime: string = ""
getReplyContent() :string{
if (StringUtils.isNullOrEmpty(this.replyContent)) {
return ""
}
let parts: string[] = [];
parts.push("<html><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=2.0, user-scalable=yes\" http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" /><body><p style=\"word-break:break-all; padding:12px;\">")
parts.push(this.replyContent.replaceAll("/prod-api/profile", BASE_IMAGE_URL+"/profile"))
parts.push("</body></html>")
return parts.join("")
}
}

View File

@ -0,0 +1,25 @@
export interface GetUserPhotoModel{
id:string;
token:string;
clientType:string;
imsi1:string;
deviceFlags:string;
sysCode:string;
}
export interface UpdateUserInfoModel{
token:string;
clientType:string;
imsi1:string;
deviceFlags:string;
sysCode:string;
workPhone:string;
}
export interface UploadFile{
contentType:string;
filename:string
}

View File

@ -0,0 +1,122 @@
import { FileUtil } from "@pura/harmony-utils"
import { StringUtils } from "../../util/StringUtils"
export class ApplicationTypeModel{
"推荐应用":Array<ApplicationModel>
"最新应用":Array<ApplicationModel>
}
export class ApplicationModel{
baseType:number = 1
name:string = ""
id:string = ""
//应用等级 3 = 原生应用 其他 H5应用
level:number=1
link:string = ""
//应用所在区类 1 = II类区 2 == III类区
type:number = 1
clientId:string = ""
clientSecret:string = ""
//图片地址
icon:string = ""
locationIcon:Resource=$r('app.media.icon_gd2')
//应用分类 情指应用 经侦、刑侦等
classification:string = ""
//应用厂商
serviceProvider:string = ""
packageName?:string
//运维人员
operationPerson:string = ""
phoneNumber?:string
//应用上架时间
applicationTime:string = ""
}
@Observed
export class AppDataModel{
baseType:number = 1
id:string = ""
isSelect:boolean = false
name:string = ""
//图片地址
icon:string = ""
link:string = ""
packageName?:string
effectiveness:number = 0
//应用等级 3 = 原生应用 其他 H5应用
level:number=1
//应用所在区类 1 = II类区 2 == III类区
type:number = 1
cityNumber:string = ""
//应用厂商
serviceProvider:string = ""
//运维人员
operationPerson:string = ""
//运维人员联系电话
phoneNumber:string = ""
clientId:string = ""
clientSecret:string = ""
state:string = ""
//备注
remark:string = ""
//操作指南
operationGuide:string = ""
isRecommend:number = 0
label:string = ""
attribution:number = 0
locationIcon:Resource=$r('app.media.icon_gd2')
}
export class AppGuideDetailsBean{
baseType:number = 1
id:string = ""
applicationId:string = ""
applicationName:string = ""
filePath:string = ""
type:number = 0
remark:string = ""
getName():string{
if(StringUtils.isNullOrEmpty(this.filePath))return ""
let index = this.filePath.lastIndexOf('/');
return this.filePath.substring(index+1)
}
getFileIcon(filePath: string): Resource {
let i = filePath.lastIndexOf("/");
let substring = filePath.substring(i + 1);
let flExt = FileUtil.getFileExtention(substring)
if (StringUtils.containsChar("doc,docx", flExt)) {
return $r('app.media.fileselect_img_doc')
}
if (StringUtils.containsChar("xls,xlsx", flExt)) {
return $r('app.media.fileselect_img_xls')
}
if (StringUtils.containsChar("rar,zip,7Z", flExt)) {
return $r('app.media.fileselect_img_zip')
}
if (flExt.endsWith("ppt")) {
return $r('app.media.fileselect_img_ppt')
}
if (flExt.endsWith("pfd")) {
return $r('app.media.fileselect_img_pfd')
}
if (flExt.endsWith("txt")) {
return $r('app.media.fileselect_img_txt')
}
return $r('app.media.fileselect_img_unknown')
}
}

View File

@ -0,0 +1,20 @@
export class BaseResultModel<T>{
msg?: string;
code?: number;
total?:number = 0;
data?:T;
rows?:T;
}
export class PageModel<T>{
total:number = 0;
rows?:Array<T>
}
export class PagingModel<T>{
counts:number = 0;
items?:Array<T>
}

View File

@ -0,0 +1,36 @@
export class MainMessageBean{
baseType:number =1;
id:string = ""
msgId:string = ""
appName:string = ""
msgType:string = ""
appIcon:string = ""
state:string = ""
/**
* 是否在个人中心APP内展示
* 0 :跳转第三方应用内展示
* 1 :直接在个人中心展示
* 默认值0
*/
appExhibition:number = 0;
/**
* ture 已读 false 未读
*/
isRead:boolean = false;
//
// drawable:Resource
applicationId:string = ""
msgTitle:string = ""
msgContent:string = ""
appId:string = ""
appUrl:string = ""
appSecret:string = ""
sendingTime:string = ""
}

View File

@ -0,0 +1,6 @@
export interface PgTokenModel{
access_token:string
refresh_token:string
}

View File

@ -0,0 +1,17 @@
export class QuestionModel {
baseType:number = 1
title: string = '';
data:Array<QuestionBean> = []
}
export class QuestionBean {
baseType:number = 2
problem:string = '';
reply:string = '';
extend:string = '';
guidance:string = '';
isShowSheet :boolean =false
}

View File

@ -0,0 +1,32 @@
export class AnHuiAddressModel {
address: string[][] = [
["省厅", "3400"],
["合肥", "3401"],
["芜湖", "3402"],
["蚌埠", "3403"],
["淮南", "3404"],
["马鞍山", "3405"],
["淮北", "3406"],
["铜陵", "3407"],
["安庆", "3408"],
["黄山", "3410"],
["滁州", "3411"],
["阜阳", "3412"],
["宿州", "3413"],
["六安", "3415"],
["亳州", "3416"],
["池州", "3417"],
["宣城", "3418"]
];
getAddress(code: string): string {
for (let i = 0; i < this.address.length; i++) {
if (this.address[i][1] == code) {
return this.address[i][0];
}
}
return "";
}
}

View File

@ -0,0 +1,7 @@
import { BaseUiModel } from "../../app/AppConstant";
export class AppModel extends BaseUiModel{
}

View File

@ -0,0 +1,74 @@
/**
* 统一认证
*/
export enum IAuthTaskType {
/**
* 获取token模式
*/
AUTH_TASK_TOKEN = 0,
/**
* token登录模式
*/
AUTH_TASK_USER = 1,
/**
* 登录页面模式
*/
AUTH_TASK_START_AUTH = 2,
/**
* 多因子绑定模式
*/
AUTH_TASK_BIND = 3,
/**
* 多因子解绑模式
*/
AUTH_TASK_UNBIND = 4,
/**
* 个人信息修改模式
*/
AUTH_TASK_SET_UP = 5,
}
export class AuthUserModel {
age?: number;
birthdate?: string;
code: string = '';
email?: string;
orderId: number;
orgId: string;
orgName: string;
phoneNum?: string;
policeTypeId: string;
policeTypeName: string;
profilePhoto?: string;
realName: string;
token: string;
userName: string;
userNum: string;
workPhone?: string;
sysTypeId: string;
constructor(code: string, orderId: number, orgId: string, orgName: string, policeTypeId: string,
policeTypeName: string, realName: string, token: string, userName: string, userNum: string,
sysTypeId: string, age?: number, birthdate?: string, email?: string, phoneNum?: string,
profilePhoto?: string, workPhone?: string) {
this.code = code;
this.orderId = orderId;
this.orgId = orgId;
this.orgName = orgName;
this.policeTypeId = policeTypeId;
this.policeTypeName = policeTypeName;
this.realName = realName;
this.token = token;
this.userName = userName;
this.userNum = userNum;
this.sysTypeId = sysTypeId;
this.age = age === undefined ? 0 : age;
this.birthdate = birthdate === undefined ? '' : birthdate;
this.email = email === undefined ? '' : email;
this.phoneNum = phoneNum === undefined ? '' : phoneNum;
this.profilePhoto = profilePhoto === undefined ? '' : profilePhoto;
this.workPhone = workPhone === undefined ? '' : workPhone;
}
}

View File

@ -0,0 +1,11 @@
export class BasePageResult{
//标识类型
type:number=0;
//第二标识
what:number=0;
//传递的参数
data?:ESObject;
}

View File

@ -0,0 +1,66 @@
export class SelectFileOptions {
/**
* 默认值false
*/
isCamera: boolean = true;
/**
* 默认值false
*/
isDCIM: boolean= true;
/**
* 默认值false
*/
isFileSelection: boolean= true;
/**
* 是否由H5自己实现false
*/
selfRealization: boolean = false;
/**
* 构造函数
* @param selfRealization 是否由H5自己实现
* @param isCamera 是否显示相机选项
* @param isDCIM 是否显示相册选项
* @param isFileSelection 是否显示文件选项
*/
constructor(selfRealization: boolean,isCamera: boolean, isDCIM: boolean, isFileSelection: boolean) {
this.isCamera = isCamera;
this.isDCIM = isDCIM;
this.isFileSelection = isFileSelection;
this.selfRealization = selfRealization;
}
/**
*
* @param selfRealization 是否由H5自己实现
* @param isCamera 是否显示相机选项
* @param isDCIM 是否显示相册选项
* @param isFileSelection 是否显示文件选项
*/
setConfig(selfRealization: boolean,isCamera: boolean, isDCIM: boolean, isFileSelection: boolean) {
this.isCamera = isCamera;
this.isDCIM = isDCIM;
this.isFileSelection = isFileSelection;
this.selfRealization = selfRealization;
}
/**
* 是否只配置了一个选项
* @return true 只配置了一个选项
* false 配置了多个选项
*/
onlyOneItemIsSelected():boolean{
let count = 0;
if (this.isCamera){
count++;
}
if (this.isDCIM){
count++;
}
if (this.isFileSelection){
count++;
}
return count==1;
}
}

View File

@ -0,0 +1,23 @@
export enum H5OperationType{
login,
readMessage,
search
}
export class WebAppPageParam {
appName :string = "";
appId:string = "";
secret :string= "";
linkUrl :string= "";
msgId?:string= "";
/*第三方应用对应的消息类型:当有的应用有多个消息类型时根据此参数判断*/
msgType? :string= "";
/*第三方应用的操作类型 默认为 login ,查看消息为: readMessage 查看搜索内容为search */
operationType :H5OperationType= H5OperationType.login;
searchType? :string= "";
searchJson? :string= "";
ywry? :string= "";
ywrylxdh? :string= "";
}

View File

@ -0,0 +1,267 @@
import { buffer, util } from "@kit.ArkTS";
import axios, { AxiosHeaders, AxiosProgressEvent, AxiosResponse, FormData } from "@ohos/axios";
import { PgTokenModel } from "../model/resultModel/PgResultModel";
import AppConstants from "../app/AppConstant";
import http from "../request/HttpUtils"
import { BaseResultModel, PagingModel } from "../model/resultModel/BaseResultModel";
import { AppDataModel, AppGuideDetailsBean, ApplicationTypeModel } from "../model/resultModel/ApplicationResultModel";
import {
AddFeedBackRequestModel,
FeedBackBean,
GetMsgListRequestModel
} from "../model/requestModel/MessageRequestModel";
import { MainMessageBean } from "../model/resultModel/MessageResultModel";
import { GetAppGuideRequestModel, GetAppListRequestModel, GuideRequest } from "../model/requestModel/AppRequestModel";
import { RuanseeAbilityStag } from "../app/RuanseeAbilityStag";
import { GetUserPhotoModel, UpdateUserInfoModel } from "../model/requestModel/UserInfoRequestModel";
import { AUTH_SYSCODE } from "../app/AppCache";
import fs from '@ohos.file.fs';
import { QuestionModel } from "../model/resultModel/QuestionModel";
import { request } from '@kit.BasicServicesKit';
import { BusinessError } from '@kit.BasicServicesKit';
/*获取品高认证*/
export const getPgToken = (data?: ESObject) => {
let byte = new Uint8Array(buffer.from(AppConstants.PG_APP_KEY_SECRET, 'utf-8').buffer);
let ac = new util.Base64Helper().encodeToStringSync(byte);
return http.postFromBody<PgTokenModel>("http://20.90.2.2/sso_out/oauth2/token?grant_type=client_credentials", data,
new AxiosHeaders({
'Authorization': 'Basic ' + ac,
'Content-Type': 'application/x-www-form-urlencoded'
}))
}
/**
* 获取推荐应用
*/
export const getRecommendApplication = () => {
return http.get<BaseResultModel<ApplicationTypeModel>>("app/v1/zamh/recommendApplication")
}
/**
* 获取消息列表
*/
export const getMessageList = (state: number, page: number, pageSize: number) => {
let param: GetMsgListRequestModel = {
state: state,
page: page,
pageSize: pageSize
}
return http.get<BaseResultModel<PagingModel<MainMessageBean>>>("app/v1/zamh/getMessage", param)
}
/**
* 获取应用列表
*/
export const getAppList = (name = "", page = 1, pageSize = 20) => {
let param: GetAppListRequestModel = {
name: name,
page: page,
pageSize: pageSize
}
return http.get<BaseResultModel<PagingModel<AppDataModel>>>("app/v1/zamh/getAllApplicationPage", param)
}
/**
* 添加反馈
*/
export const addFeedBack = (appId: string, appName: string, selectType: number, title: string, content: string) => {
let param: AddFeedBackRequestModel = {
applicationId: appId,
alarmSignal: RuanseeAbilityStag.userCache.getDepartmentCode,
alarmName: RuanseeAbilityStag.userCache.getDepartmentName,
type: selectType + "",
title: title,
content: content,
applicationName: appName
}
return http.post<BaseResultModel<string>>("app/v1/zamh/addFeedBack", param)
}
/**
* 获取我的反馈列表
*/
export const getMyFeedBackList = (page = 1, pageSize = 20) => {
let param: GetAppListRequestModel = {
name: "",
page: page,
pageSize: pageSize
}
return http.get<BaseResultModel<PagingModel<FeedBackBean>>>("app/v1/zamh/feedbackList", param)
}
/**
* 获取应用指南列表
*/
export const getAppGuideList = (appName: string, cityName: string, page = 1, pageSize = 20) => {
let param: GetAppGuideRequestModel = {
name: appName,
cityNumber: cityName,
page: page,
pageSize: pageSize
}
return http.get<BaseResultModel<PagingModel<AppDataModel>>>("app/v1/zamh/applicationHaveOperationGuide", param)
}
/**
* 获取应用指南
*/
export const operationGuideList = (applicationId: string) => {
let param: GuideRequest = {
applicationId: applicationId
}
return http.get<BaseResultModel<Array<AppGuideDetailsBean>>>("app/v1/zamh/operationGuideList", param)
}
export const downLoadUserPhoto = (filePath: string) => {
try {
fs.accessSync(filePath);
fs.unlinkSync(filePath);
} catch (err) {
}
let param: GetUserPhotoModel = {
id: RuanseeAbilityStag.userCache.getProfilePhoto,
token: RuanseeAbilityStag.userCache.getAuthToken,
clientType: "SERVER", //"SERVER",
imsi1: "",
deviceFlags: "",
sysCode: AUTH_SYSCODE
}
return axios({
url: 'http://20.90.2.2/UniAuth/api/sso/v1/download',
method: 'post',
params: param,
headers: new AxiosHeaders({
'Content-Type': `application/x-www-form-urlencoded;`
}),
filePath: filePath,
onDownloadProgress: (progressEvent: AxiosProgressEvent) => {
console.info("progress: ", progressEvent && progressEvent.loaded && progressEvent.total ?
Math.ceil(progressEvent.total / progressEvent.total * 100) : 0);
}
})
}
/**
* 修改手机号
*/
export const updateWorkPhone = (phone: string) => {
let param: UpdateUserInfoModel = {
token: RuanseeAbilityStag.userCache.getAuthToken,
clientType: "SERVER", //"SERVER",
imsi1: "",
deviceFlags: "",
sysCode: AUTH_SYSCODE,
workPhone: phone
}
return http.postFromBody<BaseResultModel<string>>("http://20.90.2.2/UniAuth/api/sso/v1/updateUserInfo", param,
new AxiosHeaders({
'Content-Type': `application/x-www-form-urlencoded;`
}),)
}
//上传文件
export const uploadUserPhoto = (filePath: string) => {
let formData = new FormData();
// 读取文件内容为ArrayBuffer
try {
let file = fs.openSync(filePath, fs.OpenMode.READ_ONLY);
let stat = fs.statSync(filePath);
let fileName: ESObject = {};
fileName['filename'] = file.name;
fileName['contentType'] = 'image/jpeg';
let arrayBuffer = new ArrayBuffer(stat.size);
fs.readSync(file.fd, arrayBuffer);
fs.closeSync(file);
formData.append('file', arrayBuffer, fileName);
} catch (e) {
console.info("上传文件失败", e);
}
formData.append('token', RuanseeAbilityStag.userCache.getAuthToken);
formData.append('clientType', 'SERVER');
formData.append('sysCode', AUTH_SYSCODE);
return http.post<BaseResultModel<string>>("http://20.90.2.2/UniAuth/api/sso/v1/uploadPhoto", formData,
new AxiosHeaders({
'Content-Type': 'multipart/form-data'
}))
}
/**
* 获取常见问题
*/
export const getQuestion = () => {
return http.get<BaseResultModel<Array<QuestionModel>>>("app/v1/question")
}
/**
* 获取应用列表
*/
export const applicationPage = (cityNumber: string, page: number, pageSize = 50, name?: string) => {
let param: ESObject = {}
param['cityNumber'] = cityNumber
param['page'] = page
param['pageSize'] = pageSize
param['name'] = name
param['attribution'] = 0
return http.get<BaseResultModel<PagingModel<AppDataModel>>>("app/v1/zamh/applicationPage", param)
}
/**
* 保存应用操作日志
*/
export const saveAppOperationLog = (appId: string, appName: string, type: string) => {
let param: ESObject = {}
param['appId'] = new String(appId)
param['appName'] = appName
param['operatorName'] = RuanseeAbilityStag.userCache.getUserName
param['operatorPoliceNumber'] = RuanseeAbilityStag.userCache.getUserCode
param['operatorIdCard'] = RuanseeAbilityStag.userCache.getIdCardNum
param['deptId'] = RuanseeAbilityStag.userCache.getDeptCode
param['deptName'] = RuanseeAbilityStag.userCache.getDeptName
param['type'] = type
let json = JSON.stringify(param)
return http.postFromJson<BaseResultModel<string>>("app/v1/zamh/addOperationRecords", json)
}
//发送消息已读
export const readMessage = (messageId: string) => {
let param: ESObject = {}
param['id'] = new String(messageId)
return http.get<BaseResultModel<string>>("app/v1/zamh/readMessage", param)
}
/**
* 下载文件
*/
export const downLoadFile = (url: string, filePath: string, callback: (progressEvent: AxiosProgressEvent) => void) => {
try {
fs.accessSync(filePath);
fs.unlinkSync(filePath);
} catch (err) {
console.error( err)
}
// return http.download(url,filePath,callback);
return axios({
url: url,
method: 'get',
headers: new AxiosHeaders({
'User-Agent': 'Mozilla/5.0 (兼容浏览器标识)',
'Content-Type': `application/x-www-form-urlencoded;`
}),
readTimeout:60000,
responseType:"array_buffer",
// context:getContext(this),
filePath: filePath,
onDownloadProgress:callback
// onDownloadProgress: (progressEvent: AxiosProgressEvent) => {
// console.info("progress: ", progressEvent && progressEvent.loaded && progressEvent.total ?
// Math.ceil(progressEvent.total / progressEvent.total * 100) : 0);
//
// }
})
}

View File

@ -0,0 +1,208 @@
import axios, {
AxiosError,
AxiosHeaders,
AxiosInstance,
AxiosProgressEvent,
AxiosRequestConfig,
AxiosResponse,
InternalAxiosRequestConfig,
} from "@ohos/axios";
import { AppCache } from '../app/AppCache';
import { UserCache } from '../app/UserCache';
import { StringUtils } from '../util/StringUtils';
// private _baseUrl: string = "http://192.168.43.98:8080/hc/phone/";
// axios 请求配置
const config: AxiosRequestConfig = {
// baseURL: AppCache.getAppCache().getServiceAddress(),
baseURL: "http://20.90.2.2/pcenter_app_out/",
timeout: 1000 * 30,
connectTimeout: 30 * 1000,
readTimeout: 30 * 1000,
}
// 定义返回值类型
interface Result<T = ESObject> {
code: number;
message: string;
data: T;
}
class Http {
// axios 实例
private instance: AxiosInstance;
// 构造函数初始化
constructor(config: AxiosRequestConfig) {
this.instance = axios.create(config);
//定义拦截器
this.interceptors();
}
private interceptors() {
// axios 发送请求之前的处理
this.instance.interceptors.request.use((config: InternalAxiosRequestConfig) => {
// 在请求头部携带token
let token = UserCache.getUserCache().getUserInfo();
if (token) {
// 把 token 放到 headers 里面
config.headers!['userInfo'] = token;
}
let pgToken = AppCache.getAppCache().getPgToken;
if (pgToken) {
config.headers!['Authorization'] = pgToken;
}
// 打印请求URL
console.log('请求URL: ' + config.url);
// 打印请求参数
if (config.params) {
console.log('请求参数(params): ' + JSON.stringify(config.params));
}
if (config.data) {
console.log('请求参数(data): ' + JSON.stringify(config.data));
}
if (config.headers) {
console.log('请求参数(data): ' + JSON.stringify(config.headers));
}
console.log('请求参数', JSON.stringify(config));
return config;
}, (error: ESObject) => {
error.data = {};
error.data.msg = '服务器异常,请联系管理员!'
return error;
})
// axios 请求返回之后的处理
// 请求返回处理
this.instance.interceptors.response.use((res: AxiosResponse) => {
let config:InternalAxiosRequestConfig = res.config
// 打印请求URL
console.log(`code: ${res.status} |: ${config.url}`);
// 打印请求参数
if (config.params) {
console.log('请求参数(params): ' + JSON.stringify(config.params));
}
if (config.data) {
console.log('请求参数(data): ' + JSON.stringify(config.data));
}
if (config.headers) {
console.log('请求参数(data): ' + JSON.stringify(config.headers));
}
if (res.config.responseType == 'array_buffer' || res.config.responseType == 'ARRAY_BUFFER') {
return res;
}
let msg = JSON.stringify(res.data);
msg = StringUtils.toJsonParaphrase(msg);
console.info('获取到的数据:' + msg);
if (res.status != 200) {
console.log(res.data.msg || '服务器出错啦');
return Promise.reject(res.data.msg || '服务器出错啦');
}
return res.data;
}, (error: AxiosError) => {
console.log('进入错误!');
// error.data = {};
if (error.code == "2300028") {
error.message = "网络超时";
} else {
if (error && error.response) {
switch (error.response.status) {
case 400:
error.message = "错误请求";
break;
case 401:
error.message = "未授权,请登录";
break;
case 403:
error.message = "拒绝访问";
break;
case 404:
error.message = "请求错误,未找到该资源";
break;
case 405:
error.message = "请求方法未允许";
break;
case 408:
error.message = "请求超时";
break;
case 500:
error.message = "服务器端出错";
break;
case 501:
error.message = "网络未实现";
break;
case 502:
error.message = "网络错误";
break;
case 503:
error.message = "服务不可用";
break;
case 504:
error.message = "网络超时";
break;
case 505:
error.message = "http版本不支持该请求";
break;
default:
error.message = `连接错误${error.response.status}`;
}
} else {
error.message = "连接到服务器失败";
}
}
console.log(error.message)
return Promise.reject(error);
})
}
// GET方法
get<T = Result>(url: string, params?: object, headers?: AxiosHeaders): Promise<T> {
return this.instance.get(url, { params, headers: headers });
}
// POST方法
post<T = Result>(url: string, data?: object, headers?: AxiosHeaders): Promise<T> {
return this.instance.post(url, data, { headers: headers });
}
// POST方法
postFromJson<T = Result>(url: string, data?: string): Promise<T> {
return this.instance.post(url, data,
{ headers: new AxiosHeaders({ 'Content-Type': 'application/json; charset=utf-8' }) });
}
// POST方法
postFromBody<T = Result>(url: string, data?: object, headers?: AxiosHeaders): Promise<T> {
return this.instance.post(url, null, { params: data, headers: headers });
}
// PUT方法
put<T = Result>(url: string, data?: object): Promise<T> {
return this.instance.put(url, data);
}
// DELETE方法
delete<T = Result>(url: string): Promise<T> {
return this.instance.delete(url);
}
/**
* 下载文件
* @param url
* @returns A required parameter cannot follow an optional parameter.
*/
download<T = Result>(url: string, filePath: string,
callback?: (progressEvent: AxiosProgressEvent) => void): Promise<T> {
return this.instance.post(url, null,{ filePath: filePath,responseType:'ARRAY_BUFFER',
headers:new AxiosHeaders({
'Content-Type': `application/x-www-form-urlencoded;`}),
onDownloadProgress: callback });
}
}
export default new Http(config);

View File

@ -0,0 +1,18 @@
export const cardRoundBorderStyle :BorderOptions={
width:$r('app.float.default_1'),
color:$r('app.color.white'),
radius:$r('app.float.default_5')
}
export const cardRoundBorderGreyStyle :BorderOptions={
width:$r('app.float.default_1'),
color:$r('app.color.colorGrey2'),
radius:$r('app.float.default_5')
}

View File

@ -0,0 +1,88 @@
import { HMRouterMgr } from "@hadss/hmrouter"
import { router } from "@kit.ArkUI"
import { StringUtils } from "../../util/StringUtils"
@Component
export struct BaseTopBar{
@State title:string|Resource=''
// @State subtitle:string|null=null
@State leftText:string|null=null
@State leftImage:Resource = $r('app.media.icon_back3')
@State rightText:string|null=null
@State rightImage:Resource |null =null
@State isBackImag:boolean = true
//回退
leftClickEvent?:()=>void
//右边按钮
rightClickEvent?:()=>void
build() {
Row() {
Row(){
Image(this.leftImage)
.width($r('app.float.default_24'))
.height($r('app.float.default_24'))
.visibility(this.isBackImag?Visibility.Visible:Visibility.None)
Text(this.leftText)
.fontColor($r('app.color.white'))
.fontSize($r('app.float.text_size_14'))
.visibility(StringUtils.isNullOrEmpty(this.leftText)?Visibility.None:Visibility.Visible)
}
.height("100%")
.width($r('app.float.default_68'))
.alignItems(VerticalAlign.Bottom)
.padding({ left:$r('app.float.default_10') })
.onTouch((event) => {
if (event.type === TouchType.Down) {
this.leftImage = $r('app.media.icon_back2');
} else if (event.type === TouchType.Up) {
this.leftImage = $r('app.media.icon_back3');
}
})
.onClick(() => {
if (!this.isBackImag)return
if (this.leftClickEvent) {
this.leftClickEvent()
}
HMRouterMgr.pop()
})
Text(this.title)
.fontColor($r('app.color.white'))
.fontSize($r('app.float.text_size_18'))
.layoutWeight(1)
.textAlign(TextAlign.Center)
.margin({ bottom: $r('app.float.default_2'), left: $r('app.float.default_10') ,right: $r('app.float.default_10') })
Row(){
Image(this.rightImage)
.width($r('app.float.default_24'))
.height($r('app.float.default_24'))
.visibility(this.rightImage == null?Visibility.None:Visibility.Visible)
Text(this.rightText)
.fontColor($r('app.color.white'))
.fontSize($r('app.float.text_size_14'))
.visibility(StringUtils.isNullOrEmpty(this.rightText)?Visibility.None:Visibility.Visible)
}
.alignItems(VerticalAlign.Bottom)
.height("100%")
.width($r('app.float.default_68'))
.padding({ right: $r('app.float.default_10') })
.onClick(() => {
if (this.rightClickEvent) {
this.rightClickEvent()
}
})
}
.alignItems(VerticalAlign.Bottom)
.padding({ bottom: 10 })
.width('100%')
.backgroundColor($r('app.color.bull'))
.height($r('app.float.default_88'))
}
}

View File

@ -0,0 +1,30 @@
import AppConstants from "../../app/AppConstant"
/**
* 空数据或者错误Item
*/
@Component
export struct EmptyOrErrorItemView {
@State type: number= 0
@State msg: string= "暂无数据"
build() {
Column() {
Image(this.type == 0 ? $r('app.media.icon_empty') : $r('app.media.icon_error2'))
.width($r('app.float.default_80'))
.height($r('app.float.default_80'))
Text(this.msg)
.fontSize($r('app.float.text_size_14'))
.fontColor($r('app.color.colorGrey6'))
.textAlign(TextAlign.Center)
.margin({ top: $r('app.float.default_10') })
}
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Center)
.width(AppConstants.PERCENTAGE_MAX)
.height(AppConstants.PERCENTAGE_MAX)
}
}

View File

@ -0,0 +1,51 @@
import { UserCache } from "../../app/UserCache"
import { DateFormat, DateUtils } from "../../util/DateUtils"
import { StringUtils } from "../../util/StringUtils"
/**
* 水印模块
* 水印内容:
* 应用名称
* 警号(姓名)
* 当前日期yyyy年MM月dd日
*/
@Component
export struct Watermark {
private settings: RenderingContextSettings = new RenderingContextSettings(true)
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
build() {
Canvas(this.context)
.width("100%")
.height("100%")
.hitTestBehavior(HitTestMode.Transparent)
.onReady(() => {
this.context.fillStyle = '#50AEAEAE'
this.context.font = "14vp"
this.context.textAlign = "left"
this.context.textBaseline = "middle"
// 在这里绘制文字水印,也可以是图片水印
for (let i = 0; i < this.context.width / 100; i++) {
this.context.translate(100 + (i * 30), 0)
let j = 0
for (; j < this.context.height / 100; j++) {
this.context.rotate(-Math.PI / 180 * 30)
// 此处水印数据是写死的,具体请替换为自己的水印
this.context.fillText(StringUtils.getResourceString(getContext(this), $r('app.string.app_name')), -60, -60)
this.context.fillText(`${UserCache.getUserCache().getUserName}(${UserCache.getUserCache().getUserCode})`, -60, -40)
this.context.fillText(DateUtils.formatDateStr(null, DateFormat.YYYYnMMyDDr), -60, -20)
this.context.rotate(Math.PI / 180 * 30)
this.context.translate(0, 150)
}
this.context.translate(0, -180 * j)
}
})
}
}
@Builder
export function createWaterMark() {
Watermark()
.hitTestBehavior(HitTestMode.None) // 必须设置其触摸测试为None或Transparent否则正常组件无法响应事件
}

View File

@ -0,0 +1,43 @@
import hilog from '@ohos.hilog'
@CustomDialog
export struct LoadingDialog{
@Prop loadingTips: string|Resource
// @State rotateAngle: number = 0
//弹窗控制器
controller: CustomDialogController
private tag: string = 'LoadingDialog'
aboutToAppear() {
hilog.debug(0xFFFF, this.tag ,"Loading展示》》》》》")
}
build() {
Stack() {
Column() {
LoadingProgress()
.width($r('app.float.default_48'))
.width($r('app.float.default_48'))
// Image($r('app.media.ic_load'))
// .height(50)
// .width(50)
// .rotate({angle: this.rotateAngle })
// .animation({
// duration: 800,
// iterations: -1,
// curve: Curve.Friction
// }).onAppear(() => {
// this.rotateAngle = 360
// })
Text(this.loadingTips)
.fontSize($r('app.float.text_size_15'))
.margin({ top: $r('app.float.default_10') ,left: $r('app.float.default_24'),right: $r('app.float.default_24')})
}
.justifyContent(FlexAlign.Center)
}
.height($r('app.float.default_150'))
.width($r('app.float.default_200'))
}
}

View File

@ -0,0 +1,77 @@
import AppConstants from "../../app/AppConstant"
import { cardRoundBorderStyle } from "../../style/BorderStyle"
@CustomDialog
export struct UnauthorizedPermissionDialog {
controller: CustomDialogController
submit?: () => void
cancel?: () => void
build() {
Column() {
Column() {
Text("提示信息")
.fontColor($r('app.color.colorGrey8'))
.fontSize($r('app.float.text_size_16'))
.width('95%')
.height($r('app.float.default_46'))
.textAlign(TextAlign.Center)
Divider()
.width('95%')
.height($r('app.float.default_1'))
.backgroundColor($r('app.color.colorGrey2'))
Text("由于您拒绝了应用的权限,应用无法正常运行,请前往设置页面授权!")
.fontColor($r('app.color.colorYellow8'))
.fontSize($r('app.float.text_size_16'))
.fontWeight(FontWeight.Bold)
.width('95%')
.textAlign(TextAlign.Center)
.margin({
top: $r('app.float.default_10'),
bottom: $r('app.float.default_10'),
left: $r('app.float.default_12'),
right: $r('app.float.default_12')
})
Row() {
Button("设置", { type: ButtonType.Normal })
.borderRadius(8)
.width($r('app.float.default_72'))
.height($r('app.float.default_40'))
.fontColor($r('app.color.white'))
.fontSize($r('app.float.text_size_14'))
.backgroundColor($r('app.color.bull'))
.onClick(() => {
if (this.submit) {
this.submit()
}
})
Button("退出APP", { type: ButtonType.Normal })
.borderRadius(8)
.width($r('app.float.default_72'))
.height($r('app.float.default_40'))
.fontColor($r('app.color.white'))
.margin({ left: $r('app.float.default_20') })
.fontSize($r('app.float.text_size_14'))
.backgroundColor($r('app.color.bull'))
.onClick(() => {
if (this.cancel) {
this.cancel()
}
})
}
.alignItems(VerticalAlign.Center)
.width(AppConstants.PERCENTAGE_MAX)
}
}
.width('95%')
.backgroundColor($r('app.color.white'))
.padding({ bottom: $r('app.float.default_12') })
.border(cardRoundBorderStyle)
}
}

View File

@ -0,0 +1,63 @@
import AppConstants from "../../app/AppConstant";
import { common } from "@kit.AbilityKit";
@Component
export struct WebAppErrorDialog {
@State message: string = "";
@State ywry: string = "";
@State ywryPhone: string = "";
build() {
Column() {
Text(this.message)
.fontColor($r('app.color.colorGrey8'))
.fontSize($r('app.float.text_size_14'))
Row() {
Text(this.ywry)
.fontColor($r('app.color.colorGrey8'))
.fontSize($r('app.float.text_size_14'))
Text(this.ywryPhone)
.fontColor($r('app.color.bull'))
.fontSize($r('app.float.text_size_14'))
.copyOption(CopyOptions.LocalDevice)
.decoration({
type: TextDecorationType.Underline,
color: Color.Blue,
style: TextDecorationStyle.SOLID
})
.onClick(()=>{
this.callPhone(this.ywryPhone)
})
}
.alignItems(VerticalAlign.Center)
.justifyContent(FlexAlign.Center)
.height($r('app.float.default_38'))
.width(AppConstants.PERCENTAGE_MAX)
}
.alignItems(HorizontalAlign.Center)
.width(AppConstants.PERCENTAGE_MAX)
}
callPhone(phone:string){
let context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
// 构造拨号参数
let want:Want = {
action: "ohos.intent.action.DIAL",
parameters: {
"uri": "tel:" + phone // 必须符合tel:协议格式
}
};
try {
context.startAbility(want).then(() => {
console.info("成功跳转拨号界面");
}).catch((err:Error) => {
console.error("跳转失败:" + JSON.stringify(err));
});
} catch (error) {
console.error("启动异常:" + JSON.stringify(error));
}
}
}

View File

@ -0,0 +1,564 @@
import { AxiosError, AxiosResponse } from "@ohos/axios";
import { FileUtil, JSONUtil, ToastUtil } from "@pura/harmony-utils";
import { BASE_IMAGE_URL } from "../../app/AppCache";
import AppConstants from "../../app/AppConstant";
import { UserCache } from "../../app/UserCache";
import { ApplicationModel } from "../../model/resultModel/ApplicationResultModel";
import { MainMessageBean } from "../../model/resultModel/MessageResultModel";
import {
downLoadUserPhoto,
getMessageList,
getRecommendApplication,
readMessage,
saveAppOperationLog
} from "../../request/Api";
import { cardRoundBorderGreyStyle, cardRoundBorderStyle } from "../../style/BorderStyle";
import { FileUtils } from "../../util/FileUtils";
import { StringUtils } from "../../util/StringUtils";
import { EmptyOrErrorItemView } from "../custom/EmptyOrErrorItemView";
import { RuanseeAbilityStag } from "../../app/RuanseeAbilityStag";
import { fileUri } from "@kit.CoreFileKit";
import { HMRouterMgr } from "@hadss/hmrouter";
import { common } from "@kit.AbilityKit";
import { H5OperationType, WebAppPageParam } from "../../model/uiModel/WebAppPageParam";
/**
* 主页组件
*/
@Preview({
title: 'ContentTable'
})
@Component
export struct HomeFragment {
@State appListData: Array<ApplicationModel> = []
@State tjyyHeight: Resource = $r('app.float.default_98');
@State msgListData: Array<MainMessageBean> = []
@State userPhoto: string | Resource = $r('app.media.icon_police_woman')
context = getContext(this) as common.UIAbilityContext;
allMessage?: () => void
aboutToAppear(): void {
setTimeout(() => {
this.getImage()
this.getRecommendApplicationList()
this.getMsgList();
}, 800)
this.context.eventHub.on("updateUserPhoto", () => {
this.userPhoto = fileUri.getUriFromPath(FileUtils.IMAGE_DIR + '/' + RuanseeAbilityStag.userCache.getProfilePhoto)
})
}
aboutToDisappear(): void {
this.context.eventHub.off("updateUserPhoto")
}
getImage() {
if (FileUtil.accessSync(FileUtils.IMAGE_DIR + '/' + RuanseeAbilityStag.userCache.getProfilePhoto)) {
this.userPhoto = fileUri.getUriFromPath(FileUtils.IMAGE_DIR + '/' + RuanseeAbilityStag.userCache.getProfilePhoto)
return
}
downLoadUserPhoto(FileUtils.IMAGE_DIR + '/' + RuanseeAbilityStag.userCache.getProfilePhoto)
.then((res: AxiosResponse) => {
console.info("result:" + JSON.stringify(res.data));
if (res.status == 200) {
this.userPhoto =
fileUri.getUriFromPath(FileUtils.IMAGE_DIR + '/' + RuanseeAbilityStag.userCache.getProfilePhoto)
}
})
.catch((error: AxiosError) => {
console.error("error:" + JSON.stringify(error));
})
}
getMsgList() {
getMessageList(0, 1, 6)
.then((res) => {
console.log("get 消息列表成功", JSONUtil.beanToJsonStr(res))
if (res.code == 20041) {
let data = res.data
if (data) {
data.counts;
let items = data.items;
if (items) {
this.msgListData = items;
}
if (!this.msgListData || this.msgListData.length < 1) {
this.handErrorOrEmPty(0, "暂无新消息!")
}
} else {
this.handErrorOrEmPty(0, "暂无新消息!")
}
} else {
this.handErrorOrEmPty(-1, StringUtils.get(res.msg, ""))
}
})
.catch((err: AxiosError) => {
console.error("get 消息列表失败", err)
this.handErrorOrEmPty(-1, err.message)
})
}
/**
* 错误或空处理
*/
handErrorOrEmPty(type: number, msg: string) {
let bean = new MainMessageBean()
bean.baseType = type;
bean.msgContent = msg;
this.msgListData = new Array<MainMessageBean>();
this.msgListData.push(bean)
}
/**
* 获取推荐应用列表
*/
getRecommendApplicationList() {
getRecommendApplication()
.then((res) => {
console.log("get 推荐应用列表成功", JSONUtil.beanToJsonStr(res))
if (res.code == 20041) {
let data = res.data;
if (data) {
let listData = new Array<ApplicationModel>()
let tjyy = data.推荐应用;
if (tjyy) {
tjyy.forEach((item) => {
listData.push(item)
})
}
let zxyy = data.最新应用;
if (zxyy) {
zxyy.forEach((item) => {
listData.push(item)
})
}
if (listData.length < 1) {
let bean = new ApplicationModel()
bean.baseType = 91
bean.name = "应用指南"
bean.locationIcon = $r('app.media.ic_zfjc')
this.appListData.push(bean)
let bean1 = new ApplicationModel()
bean1.baseType = 92
bean1.name = "常见问题"
bean1.locationIcon = $r('app.media.ic_zazh')
this.appListData.push(bean1)
let bean2 = new ApplicationModel()
bean2.baseType = 93
bean2.name = "意见反馈"
bean2.locationIcon = $r('app.media.ic_zazh')
this.appListData.push(bean2)
bean = new ApplicationModel()
bean.baseType = 99
bean.name = "更多应用"
bean.locationIcon = $r('app.media.icon_gd2')
this.appListData.push(bean)
// ToastUtil.showToast("暂无推荐应用")
return
}
if (listData.length >= 8) {
this.appListData = listData.slice(8)
let bean = this.appListData[7]
bean.baseType = 99
bean.name = "更多应用"
bean.locationIcon = $r('app.media.icon_gd2')
} else {
this.appListData = listData
let bean = new ApplicationModel()
bean.baseType = 99
bean.name = "更多应用"
bean.locationIcon = $r('app.media.icon_gd2')
this.appListData.push(bean)
}
if (listData.length > 4) {
this.tjyyHeight = $r('app.float.default_160')
} else {
this.tjyyHeight = $r('app.float.default_105')
}
}
}
})
.catch((err: AxiosError) => {
console.error("get 推荐应用列表失败", err)
})
}
skipMyUserInfo() {
HMRouterMgr.push({ navigationId: 'startNavigation', pageUrl: "MyUserInfoPage" })
}
readMsg(item: MainMessageBean) {
readMessage(item.id)
.then((res) => {
console.debug("发送点击:", JSONUtil.beanToJsonStr(res))
if (res.code == 20041) {
this.getMsgList()
}
})
.catch((error: AxiosError) => {
console.error("发送点击:", JSONUtil.beanToJsonStr(error))
})
}
build() {
Stack({ alignContent: Alignment.TopStart }) {
this.underlyingBackground()
this.mainContent()
}
.width(AppConstants.PERCENTAGE_MAX)
.height(AppConstants.PERCENTAGE_MAX)
.backgroundColor($r('app.color.page_background'))
}
/**
* 主界面
*/
@Builder
mainContent() {
Column() {
this.userInfoUI()
this.recommendedApplicationUI()
this.pendingMessageUI()
}
.width(AppConstants.PERCENTAGE_MAX)
.height(AppConstants.PERCENTAGE_MAX)
}
/**
* 待办消息区域
*/
@Builder
pendingMessageUI() {
Column() {
Row() {
Text("待办消息")
.fontSize($r('app.float.text_size_16'))
.fontColor($r('app.color.colorGrey8'))
.layoutWeight(1)
.textAlign(TextAlign.Start)
Text("全部消息")
.fontSize($r('app.float.text_size_14'))
.fontColor($r('app.color.colorGrey6'))
.textAlign(TextAlign.Start)
.onClick(() => {
if (this.allMessage) {
this.allMessage()
}
})
Image($r('app.media.arrow_right'))
.width($r('app.float.default_18'))
.height($r('app.float.default_18'))
.margin({ left: $r('app.float.default_8') });
}
.alignItems(VerticalAlign.Center)
.width(AppConstants.PERCENTAGE_MAX)
.padding({ left: $r('app.float.default_10'), right: $r('app.float.default_10') })
.height($r('app.float.default_40'))
Divider()
.width(AppConstants.PERCENTAGE_MAX)
.height($r('app.float.default_1'))
.backgroundColor($r('app.color.colorGrey2'))
List() {
ForEach(this.msgListData, (item: MainMessageBean, index) => {
if (item.baseType == 0 || item.baseType == -1) {
ListItem() {
EmptyOrErrorItemView({ type: item.baseType, msg: item.msgContent })
}
} else {
ListItem() {
this.msgItem(item)
}
.onClick(() => {
this.readMsg(item)
if (item.appExhibition == 0) {
let pageParam: WebAppPageParam = {
appName: item.appName,
appId: item.appId,
secret: item.appSecret,
linkUrl: item.appUrl,
operationType: H5OperationType.readMessage,
msgId: item.msgId,
msgType: item.msgType,
}
HMRouterMgr.push({ pageUrl: 'WebAppPages', param: pageParam })
return
}
HMRouterMgr.push({ pageUrl: 'MessageDetailsPage', param: item })
})
}
})
}
.margin({ left: $r('app.float.default_10'), right: $r('app.float.default_10') })
.width("95%")
.layoutWeight(1)
}
.margin($r('app.float.default_10'))
.width('95%')
.layoutWeight(1)
.backgroundColor($r('app.color.white'))
.border(cardRoundBorderStyle)
}
/**
* 消息列表
* @param item
*/
@Builder
msgItem(item: MainMessageBean) {
Column() {
Row() {
Text(item.msgTitle)
.fontSize($r('app.float.text_size_16'))
.fontColor($r('app.color.colorGrey8'))
.textAlign(TextAlign.Start)
.maxLines(1)
.ellipsisMode(EllipsisMode.END)
.layoutWeight(1)
Image($r('app.media.icon_not_record'))
.width($r('app.float.default_38'))
.height($r('app.float.default_30'))
.margin({ left: $r('app.float.default_8') })
}
.alignItems(VerticalAlign.Center)
.height($r('app.float.default_32'))
.margin({ left: $r('app.float.default_8'), right: $r('app.float.default_8') })
.width('95%')
Text(item.msgContent)
.fontSize($r('app.float.text_size_14'))
.fontColor($r('app.color.colorGrey6'))
.textAlign(TextAlign.Start)
.maxLines(2)
.ellipsisMode(EllipsisMode.END)
.width('95%')
.margin({ top: $r('app.float.default_5'), left: $r('app.float.default_8'), right: $r('app.float.default_8') })
Divider()
.width(AppConstants.PERCENTAGE_MAX)
.height($r('app.float.default_1'))
.margin({ top: $r('app.float.default_10') })
.backgroundColor($r('app.color.colorGrey2'))
Row() {
RelativeContainer() {
Image(BASE_IMAGE_URL + item.appIcon)
.width($r('app.float.default_22'))
.height($r('app.float.default_22'))
.alignRules({
middle: { anchor: '__container__', align: HorizontalAlign.Center }, // 水平居中
center: { anchor: '__container__', align: VerticalAlign.Center } // 垂直居中
})
.border({
radius: $r('app.float.default_5'),
})
Image($r('app.media.ic_unread_doit'))
.width($r('app.float.default_8'))
.height($r('app.float.default_8'))
.margin({ right: $r('app.float.default_2'), top: $r('app.float.default_2') })
.alignRules({
middle: { anchor: '__container__', align: HorizontalAlign.End }, // 水平居中
center: { anchor: '__container__', align: VerticalAlign.Top } // 垂直居中
})
}
.width($r('app.float.default_22'))
.height($r('app.float.default_22'))
Text(item.appName)
.fontSize($r('app.float.text_size_14'))
.fontColor($r('app.color.colorGrey8'))
.layoutWeight(1)
.margin({ left: $r('app.float.default_8') })
Text(item.sendingTime)
.fontSize($r('app.float.text_size_14'))
.fontColor($r('app.color.colorGrey6'))
.margin({ left: $r('app.float.default_5') })
}
.alignItems(VerticalAlign.Center)
.height($r('app.float.default_26'))
.width('95%')
.margin({ top: $r('app.float.default_5'), left: $r('app.float.default_8'), right: $r('app.float.default_8') })
}
.width("95%")
.height('auto')
.padding({ top: $r('app.float.default_10'), bottom: $r('app.float.default_10') })
.backgroundColor($r('app.color.white'))
.margin({ top: $r('app.float.default_10') })
.border(cardRoundBorderGreyStyle)
}
/**
* 错误或者空的消息列表显示
*/
@Builder
msgItemError(type: number, msg: string) {
Column() {
Image(type == 0 ? $r('app.media.icon_empty') : $r('app.media.icon_error2'))
.width($r('app.float.default_80'))
.height($r('app.float.default_80'))
Text(msg)
.fontSize($r('app.float.text_size_14'))
.fontColor($r('app.color.colorGrey6'))
.textAlign(TextAlign.Center)
.margin({ top: $r('app.float.default_10') })
}
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Center)
.width(AppConstants.PERCENTAGE_MAX)
.height(AppConstants.PERCENTAGE_MAX)
}
/**
* 推荐应用区域
*/
@Builder
recommendedApplicationUI() {
Column() {
Grid() {
ForEach(this.appListData, (item: ApplicationModel, index) => {
GridItem() {
Column() {
Image((item.baseType == 99 || item.baseType == 91 || item.baseType == 92 || item.baseType == 93) ?
item.locationIcon : BASE_IMAGE_URL + item.icon)
.size({
width: $r('app.float.default_36'),
height: $r('app.float.default_36')
})
.margin({ top: $r('app.float.default_8') });
Text(item.name)
.textAlign(TextAlign.Center)
.fontSize($r('app.float.text_size_14'))
.fontColor($r('app.color.colorGrey8'))
.margin({ top: $r('app.float.default_8') });
}
.height('auto')
.alignItems(HorizontalAlign.Center);
}
.onClick(() => {
if (item.baseType == 99) {
HMRouterMgr.push({ pageUrl: 'ApplicationWorkbenchPage' })
return
}
if (item.baseType == 91) {
HMRouterMgr.push({ pageUrl: 'ApplicationGuidePage' })
return
}
if (item.baseType == 92) {
HMRouterMgr.push({ pageUrl: 'FrequentlyQuestionsPage' })
return
}
if (item.baseType == 93) {
HMRouterMgr.push({ pageUrl: 'OpinionsSuggestionsPages' })
return
}
let pageParam: WebAppPageParam = {
appName: item.name,
appId: item.clientId,
secret: item.clientSecret,
linkUrl: item.link,
operationType: H5OperationType.login,
}
HMRouterMgr.push({ pageUrl: 'WebAppPages', param: pageParam })
})
});
}
.columnsTemplate('1fr 1fr 1fr 1fr') //一行有4列等分
.columnsGap($r('app.float.default_10')) //行间距
.rowsGap($r('app.float.default_10')); //列间距
}
.padding($r('app.float.default_10'))
.margin({ top: $r('app.float.default_10'), right: $r('app.float.default_10'), left: $r('app.float.default_10') })
.width('95%')
.height(this.tjyyHeight)
.backgroundColor($r('app.color.white'))
.border(cardRoundBorderStyle)
}
/**
* 用户信息区域
*/
@Builder
userInfoUI() {
Row() {
Image(this.userPhoto)
.size({
width: $r('app.float.default_63'),
height: $r('app.float.default_63')
})
.border({
radius: 50
})
.margin({ left: $r('app.float.default_15') });
Column() {
Row() {
Text(UserCache.getUserCache().getUserName)
.fontSize($r('app.float.default_16'))
.fontColor($r('app.color.white'));
Text(UserCache.getUserCache().getUserCode)
.fontSize($r('app.float.text_size_12'))
.fontColor($r('app.color.colorBluen8'))
.padding({
left: $r('app.float.default_8'),
right: $r('app.float.default_8'),
top: $r('app.float.default_2'),
bottom: $r('app.float.default_2')
})
.backgroundColor('#E9F4F3')
.border({
radius: 10
});
}
.alignItems(VerticalAlign.Center)
.justifyContent(FlexAlign.Start)
.onClick(() => {
this.skipMyUserInfo()
});
Text(UserCache.getUserCache().getDeptName)
.fontSize($r('app.float.default_16'))
.fontColor($r('app.color.white'))
.margin({ top: $r('app.float.default_8') })
.onClick(() => {
this.skipMyUserInfo()
});
}
.margin({ left: $r('app.float.default_10') })
.alignItems(HorizontalAlign.Start)
.layoutWeight(1);
}
.alignItems(VerticalAlign.Center)
.justifyContent(FlexAlign.Start)
.margin({ top: $r('app.float.default_28') })
.width(AppConstants.PERCENTAGE_MAX)
.height('13%')
.onClick(() => {
this.skipMyUserInfo()
})
}
/**
* 背景图片
*/
@Builder
underlyingBackground() {
Column() {
Image($r('app.media.bg_two'))
.width(AppConstants.PERCENTAGE_MAX)
.height('28%')
}
}
}

View File

@ -0,0 +1,277 @@
import { LitheRefresh, RefreshController } from "@abner/lithe_refresh";
import { AxiosError } from "@ohos/axios";
import { JSONUtil, ToastUtil } from "@pura/harmony-utils";
import AppConstants from "../../app/AppConstant"
import { MainMessageBean } from "../../model/resultModel/MessageResultModel";
import { getMessageList, readMessage, saveAppOperationLog } from "../../request/Api";
import { StringUtils } from "../../util/StringUtils";
import { BASE_IMAGE_URL } from "../../app/AppCache";
import { cardRoundBorderGreyStyle } from "../../style/BorderStyle";
import { EmptyOrErrorItemView } from "../custom/EmptyOrErrorItemView";
import { HMRouterMgr } from "@hadss/hmrouter";
import { H5OperationType, WebAppPageParam } from "../../model/uiModel/WebAppPageParam";
/**
* 主页组件
*/
@Preview({
title: 'ContentTable'
})
@Component
export struct MessageListFragment {
@State type: number = 0;
@State msgListData: Array<MainMessageBean> = []
controller: RefreshController = new RefreshController()
scroller: Scroller = new Scroller()
total: number = 0;
pageNum: number = 1;
isRefreshStatus: number = 0;
aboutToAppear(): void {
setTimeout(() => {
this.controller.isAutoRefresh = true;
}, 800)
}
getMsgList() {
getMessageList(this.type, this.pageNum, 30)
.then((res) => {
console.log("get 消息列表成功", JSONUtil.beanToJsonStr(res))
if (res.code == 20041) {
let data = res.data
if (data) {
let items = data.items;
if (items && items.length > 0) {
if (this.isRefreshStatus == 1) {
this.isRefreshStatus = 0
this.controller.finishRefresh()
this.msgListData = items;
}
if (this.isRefreshStatus == 2) {
this.isRefreshStatus = 0
this.controller.finishLoadMore()
items.forEach((item) => {
this.msgListData.push(item)
})
}
} else {
this.handErrorOrEmPty(0, "暂无新消息!")
}
} else {
this.handErrorOrEmPty(0, "暂无新消息!")
}
} else if (res.code == 20040) {
this.handErrorOrEmPty(0, "暂无新消息!")
} else {
this.handErrorOrEmPty(-1, StringUtils.get(res.msg, ""))
}
})
.catch((err: AxiosError) => {
console.error("get 消息列表失败", err)
this.handErrorOrEmPty(-1, err.message)
})
}
/**
* 错误或空处理
*/
handErrorOrEmPty(type: number, msg: string) {
// ToastUtil.showToast(msg)
if (this.isRefreshStatus == 1) {
this.isRefreshStatus = 0
this.controller.finishRefresh()
this.msgListData = new Array<MainMessageBean>();
let bean = new MainMessageBean()
bean.baseType = type;
bean.msgContent = msg;
this.msgListData.push(bean)
}
if (this.isRefreshStatus == 2) {
this.isRefreshStatus = 0
this.controller.finishLoadMore()
}
}
build() {
Column() {
LitheRefresh({
scroller: this.scroller,
controller: this.controller,
itemLayout: () => {
this.listView()
},
onRefresh: () => {
this.controller.closeLoadMore = false;
this.pageNum = 1;
this.isRefreshStatus = 1;
this.getMsgList()
},
onLoadMore: () => {
if (this.pageNum * 30 >= this.total) {
this.controller.finishLoadMore()
this.controller.closeLoadMore = true;
ToastUtil.showToast("没有更多数据!")
return
}
this.pageNum++;
this.isRefreshStatus = 2;
this.getMsgList()
}
})
.width(AppConstants.PERCENTAGE_MAX)
.layoutWeight(1)
}
.width(AppConstants.PERCENTAGE_MAX)
.height(AppConstants.PERCENTAGE_MAX)
}
@Builder
listView() {
List({ scroller: this.scroller, space: 10 }) {
ForEach(this.msgListData, (item: MainMessageBean) => {
if (item.baseType == 0 || item.baseType == -1) {
ListItem() {
EmptyOrErrorItemView({ type: item.baseType, msg: item.msgContent })
}
} else {
ListItem() {
this.itemView(item)
}
.onClick(() => {
if (this.type == 0) {
this.readMsg(item)
}
if (item.appExhibition == 0) {
let pageParam: WebAppPageParam = {
appName: item.appName,
appId: item.appId,
secret: item.appSecret,
linkUrl: item.appUrl,
operationType: H5OperationType.readMessage,
msgId: item.msgId,
msgType: item.msgType,
}
HMRouterMgr.push({ pageUrl: 'WebAppPages', param: pageParam })
return
}
HMRouterMgr.push({ pageUrl: 'MessageDetailsPage', param: item })
})
}
})
}
.divider({
strokeWidth: $r('app.float.default_1'),
color: $r('app.color.colorGrey2'),
startMargin: $r('app.float.default_63')
})
.listDirection(Axis.Vertical)
.scrollBar(BarState.Off)
.edgeEffect(EdgeEffect.None)
.width(AppConstants.PERCENTAGE_MAX)
.layoutWeight(1)
.nestedScroll({
scrollForward: NestedScrollMode.PARENT_FIRST,
scrollBackward: NestedScrollMode.PARENT_FIRST
})
}
readMsg(item: MainMessageBean) {
readMessage(item.id)
.then((res) => {
console.debug("发送点击:", JSONUtil.beanToJsonStr(res))
//java.lang.Integer cannot be cast to java.lang.String
if (res.code == 20041) {
this.controller.autoRefresh(true)
}
})
.catch((error: AxiosError) => {
console.error("发送点击:", JSONUtil.beanToJsonStr(error))
})
}
@Builder
itemView(item: MainMessageBean) {
Column() {
Row() {
Text(item.msgTitle)
.fontSize($r('app.float.text_size_16'))
.fontColor($r('app.color.colorGrey8'))
.textAlign(TextAlign.Start)
.maxLines(1)
.ellipsisMode(EllipsisMode.END)
.layoutWeight(1)
Image(this.type == 0 ? $r('app.media.icon_not_record') : $r('app.media.icon_record'))
.width($r('app.float.default_38'))
.height($r('app.float.default_30'))
.margin({ left: $r('app.float.default_8') })
}
.alignItems(VerticalAlign.Center)
.height($r('app.float.default_32'))
.margin({ left: $r('app.float.default_8'), right: $r('app.float.default_8') })
.width('95%')
Text(item.msgContent)
.fontSize($r('app.float.text_size_14'))
.fontColor($r('app.color.colorGrey6'))
.textAlign(TextAlign.Start)
.maxLines(2)
.ellipsisMode(EllipsisMode.END)
.width('95%')
.margin({ top: $r('app.float.default_5'), left: $r('app.float.default_8'), right: $r('app.float.default_8') })
Divider()
.width(AppConstants.PERCENTAGE_MAX)
.height($r('app.float.default_1'))
.margin({ top: $r('app.float.default_10') })
.backgroundColor($r('app.color.colorGrey2'))
Row() {
RelativeContainer() {
Image(BASE_IMAGE_URL + item.appIcon)
.width($r('app.float.default_22'))
.height($r('app.float.default_22'))
.alignRules({
middle: { anchor: '__container__', align: HorizontalAlign.Center }, // 水平居中
center: { anchor: '__container__', align: VerticalAlign.Center } // 垂直居中
})
.border({
radius: $r('app.float.default_5'),
})
Image($r('app.media.ic_unread_doit'))
.width($r('app.float.default_8'))
.height($r('app.float.default_8'))
.visibility(this.type == 0? Visibility.Visible: Visibility.None)
.margin({ right: $r('app.float.default_2'), top: $r('app.float.default_2') })
.alignRules({
middle: { anchor: '__container__', align: HorizontalAlign.End }, // 水平居中
center: { anchor: '__container__', align: VerticalAlign.Top } // 垂直居中
})
}
.width($r('app.float.default_22'))
.height($r('app.float.default_22'))
Text(item.appName)
.fontSize($r('app.float.text_size_14'))
.fontColor($r('app.color.colorGrey8'))
.layoutWeight(1)
.margin({ left: $r('app.float.default_8') })
Text(item.sendingTime)
.fontSize($r('app.float.text_size_14'))
.fontColor($r('app.color.colorGrey6'))
.margin({ left: $r('app.float.default_5') })
}
.alignItems(VerticalAlign.Center)
.height($r('app.float.default_26'))
.width('95%')
.margin({ top: $r('app.float.default_5'), left: $r('app.float.default_8'), right: $r('app.float.default_8') })
}
.width("95%")
.height('auto')
.padding({ top: $r('app.float.default_10'), bottom: $r('app.float.default_10') })
.backgroundColor($r('app.color.white'))
.margin({ left: $r('app.float.default_10'), right: $r('app.float.default_10') })
.border(cardRoundBorderGreyStyle)
}
}

View File

@ -0,0 +1,370 @@
import AppConstants from "../../app/AppConstant"
import { RuanseeAbilityStag } from "../../app/RuanseeAbilityStag"
import { HMRouterMgr } from "@hadss/hmrouter"
import { ToastUtil } from "@pura/harmony-utils/src/main/ets/action/ToastUtil"
import { FileUtil } from "@pura/harmony-utils"
import { FileUtils } from "../../util/FileUtils"
import { fileUri } from "@kit.CoreFileKit"
import { downLoadUserPhoto } from "../../request/Api"
import { AxiosError, AxiosResponse } from "@ohos/axios"
import { common } from "@kit.AbilityKit"
import { H5OperationType, WebAppPageParam } from "../../model/uiModel/WebAppPageParam"
/**
* 主页组件
*/
@Preview({
title: 'ContentTable'
})
@Component
export struct MyFragment {
@State userPhoto: string | Resource = $r('app.media.icon_police_woman')
context = getContext(this) as common.UIAbilityContext;
aboutToAppear(): void {
this.getImage()
this.context.eventHub.on("updateUserPhoto",()=>{
this.userPhoto = fileUri.getUriFromPath(FileUtils.IMAGE_DIR + '/' + RuanseeAbilityStag.userCache.getProfilePhoto)
})
}
aboutToDisappear(): void {
this.context.eventHub.off("updateUserPhoto")
}
build() {
Stack({ alignContent: Alignment.TopStart }) {
this.underlyingBackground()
this.mainContent()
}
.width(AppConstants.PERCENTAGE_MAX)
.height(AppConstants.PERCENTAGE_MAX)
.backgroundColor($r('app.color.page_background'))
}
getImage() {
if (FileUtil.accessSync(FileUtils.IMAGE_DIR + '/' + RuanseeAbilityStag.userCache.getProfilePhoto)) {
this.userPhoto = fileUri.getUriFromPath(FileUtils.IMAGE_DIR + '/' + RuanseeAbilityStag.userCache.getProfilePhoto)
return
}
downLoadUserPhoto(FileUtils.IMAGE_DIR + '/' + RuanseeAbilityStag.userCache.getProfilePhoto)
.then((res:AxiosResponse)=>{
console.info("result:"+ JSON.stringify(res.data));
if(res.status == 200){
this.userPhoto = fileUri.getUriFromPath(FileUtils.IMAGE_DIR + '/' + RuanseeAbilityStag.userCache.getProfilePhoto)
}
})
.catch((error:AxiosError)=> {
console.error("error:" + JSON.stringify(error));
})
}
skipMyUserInfo() {
HMRouterMgr.push({ navigationId: 'startNavigation', pageUrl: "MyUserInfoPage" })
}
/**
* 主内容
*/
@Builder
mainContent() {
Column() {
Stack({ alignContent: Alignment.Top }) {
Column() {
Row() {
//警号
Row() {
Text("NO·")
.fontColor($r('app.color.white'))
.fontSize($r('app.float.text_size_6'))
.backgroundColor($r('app.color.bull'))
.borderRadius(50)// 50是宽高的一半
.padding(3)
.border({ radius: $r('app.float.default_50') })
Text(RuanseeAbilityStag.userCache.getUserCode)
.fontSize($r('app.float.text_size_14'))
.fontColor($r('app.color.colorBluen6'))
.margin({ left: $r('app.float.default_5') })
}
.alignItems(VerticalAlign.Center)
.padding({
left: $r('app.float.default_5'),
right: $r('app.float.default_5'),
top: $r('app.float.default_3'),
bottom: $r('app.float.default_3')
})
.width('auto')
.height('auto')
.backgroundColor("#E9F4F3")
.border({ radius: $r('app.float.default_50') })
Blank()
.layoutWeight(1)
//修改图标
Image($r('app.media.icon_edit_info'))
.width($r('app.float.default_22'))
.height($r('app.float.default_22'))
.onClick(() => {
this.skipMyUserInfo()
})
}
.width(AppConstants.PERCENTAGE_MAX)
.padding({ left: $r('app.float.default_10'), right: $r('app.float.default_10') })
.alignItems(VerticalAlign.Center)
.margin({ top: $r('app.float.default_10') })
.height($r('app.float.default_40'))
.onClick(() => {
this.skipMyUserInfo()
})
Text(`姓名:${RuanseeAbilityStag.userCache.getUserName}`)
.fontColor($r('app.color.white'))
.fontSize($r('app.float.text_size_16'))
.margin({
left: $r('app.float.default_10'),
right: $r('app.float.default_10'),
top: $r('app.float.default_15')
})
Text(`工作号码:${RuanseeAbilityStag.userCache.getWorkPhone}`)
.fontColor($r('app.color.white'))
.fontSize($r('app.float.text_size_16'))
.margin({
left: $r('app.float.default_10'),
right: $r('app.float.default_10'),
top: $r('app.float.default_10')
})
Text(`单位:${RuanseeAbilityStag.userCache.getDeptName}`)
.fontColor($r('app.color.white'))
.fontSize($r('app.float.text_size_16'))
.margin({
left: $r('app.float.default_10'),
right: $r('app.float.default_10'),
top: $r('app.float.default_10')
})
}
.alignItems(HorizontalAlign.Start)
.width(AppConstants.PERCENTAGE_MAX)
.margin({
top: $r('app.float.default_80')
})
.border({ radius: $r('app.float.default_10') })
.borderRadius($r('app.float.default_10'))
.backgroundImageSize(ImageSize.FILL)
.height($r('app.float.default_160'))
.backgroundImagePosition(Alignment.Center) // 居中显示背景图
.backgroundImage($r('app.media.icon_my_userbg'))
.onClick(() => {
this.skipMyUserInfo()
})
Column() {
Column() {
Image(this.userPhoto)
.width($r('app.float.default_88'))
.height($r('app.float.default_88'))
.borderRadius(50)// 50是宽高的一半
.clip(true)// 裁剪超出圆角部分
.aspectRatio(1) // 确保宽高比例一致
}
.width($r('app.float.default_90'))
.height($r('app.float.default_90'))
.backgroundColor("#55e5e5e5")
.margin({ top: $r('app.float.default_48') })
.onClick(() => {
this.skipMyUserInfo()
})
.border({
width: $r('app.float.default_2'),
radius: $r('app.float.default_50'),
color: "#66e5e5e5"
})
}
.width(AppConstants.PERCENTAGE_MAX)
}
.padding({
left: $r('app.float.default_30'),
right: $r('app.float.default_30')
})
.width(AppConstants.PERCENTAGE_MAX)
.height('auto')
Column() {
Row() {
Column() {
Image($r('app.media.icon_operation_guide'))
.width($r('app.float.default_32'))
.height($r('app.float.default_32'))
Text("应用指南")
.fontSize($r('app.float.text_size_12'))
.fontColor($r('app.color.colorGrey8'))
.textAlign(TextAlign.Center)
.margin({ top: $r('app.float.default_8') })
}
.alignItems(HorizontalAlign.Center)
.justifyContent(FlexAlign.Center)
.padding({ top: $r('app.float.default_10'), bottom: $r('app.float.default_10') })
.height('auto')
.layoutWeight(1)
.onClick(() => {
HMRouterMgr.push({ navigationId: 'startNavigation', pageUrl: "ApplicationGuidePage" })
})
Column() {
Image($r('app.media.icon_feedback'))
.width($r('app.float.default_32'))
.height($r('app.float.default_32'))
Text("意见建议")
.fontSize($r('app.float.text_size_12'))
.fontColor($r('app.color.colorGrey8'))
.textAlign(TextAlign.Center)
.margin({ top: $r('app.float.default_8') })
}
.alignItems(HorizontalAlign.Center)
.justifyContent(FlexAlign.Center)
.padding({ top: $r('app.float.default_10'), bottom: $r('app.float.default_10') })
.height('auto')
.layoutWeight(1)
.onClick(() => {
HMRouterMgr.push({ navigationId: 'startNavigation', pageUrl: "OpinionsSuggestionsPages" })
})
Column() {
Image($r('app.media.icon_problen'))
.width($r('app.float.default_32'))
.height($r('app.float.default_32'))
Text("常见问题")
.fontSize($r('app.float.text_size_12'))
.fontColor($r('app.color.colorGrey8'))
.textAlign(TextAlign.Center)
.margin({ top: $r('app.float.default_8') })
}
.alignItems(HorizontalAlign.Center)
.justifyContent(FlexAlign.Center)
.padding({ top: $r('app.float.default_10'), bottom: $r('app.float.default_10') })
.height('auto')
.layoutWeight(1)
.onClick(() => {
HMRouterMgr.push({ navigationId: 'startNavigation', pageUrl: "FrequentlyQuestionsPage" })
})
}
.width(AppConstants.PERCENTAGE_MAX)
.height('auto')
.margin({ top: $r('app.float.default_10') })
Blank()
.backgroundColor($r('app.color.colorGrey2'))
.width(AppConstants.PERCENTAGE_MAX)
.height($r('app.float.default_10'))
.margin({ top: $r('app.float.default_10') })
Row() {
Image($r('app.media.icon_authen'))
.width($r('app.float.default_28'))
.height($r('app.float.default_28'))
Text("认证管理")
.fontSize($r('app.float.text_size_16'))
.fontColor($r('app.color.colorGrey8'))
.textAlign(TextAlign.Start)
.layoutWeight(1)
.margin({ left: $r('app.float.default_10') })
Image($r('app.media.arrow_right'))
.width($r('app.float.default_22'))
.height($r('app.float.default_22'))
}
.alignItems(VerticalAlign.Center)
.padding({ left: $r('app.float.default_10'), right: $r('app.float.default_10') })
.height($r('app.float.default_52'))
.margin({ top: $r('app.float.default_5') })
.onClick(() => {
ToastUtil.showToast("功能开发中...")
let pageParam :WebAppPageParam= {
appName: '测试应用',
appId: 'tastApp',
secret: "35DB4R4GHN658S",
linkUrl: "",
operationType:H5OperationType.login,
}
HMRouterMgr.push({pageUrl:'WebAppPages',param: pageParam})
})
Divider()
.backgroundColor($r('app.color.colorGrey2'))
.width(AppConstants.PERCENTAGE_MAX)
.height($r('app.float.default_1'))
Row() {
Image($r('app.media.icon_about'))
.width($r('app.float.default_28'))
.height($r('app.float.default_28'))
Text("关于")
.fontSize($r('app.float.text_size_16'))
.fontColor($r('app.color.colorGrey8'))
.textAlign(TextAlign.Start)
.layoutWeight(1)
.margin({ left: $r('app.float.default_10') })
Image($r('app.media.arrow_right'))
.width($r('app.float.default_22'))
.height($r('app.float.default_22'))
}
.alignItems(VerticalAlign.Center)
.padding({ left: $r('app.float.default_10'), right: $r('app.float.default_10') })
.height($r('app.float.default_52'))
.onClick(() => {
HMRouterMgr.push({ navigationId: 'startNavigation', pageUrl: "AboutPage" })
})
Divider()
.backgroundColor($r('app.color.colorGrey2'))
.width(AppConstants.PERCENTAGE_MAX)
.height($r('app.float.default_1'))
}
.width(AppConstants.PERCENTAGE_MAX)
.backgroundColor($r('app.color.white'))
.margin({ top: $r('app.float.default_20') })
.border({
radius: {
topLeft: $r('app.float.default_10'),
topRight: $r('app.float.default_10')
}
})
.layoutWeight(1)
}
.width(AppConstants.PERCENTAGE_MAX)
.height(AppConstants.PERCENTAGE_MAX)
}
/**
* 顶部背景图片
*/
@Builder
underlyingBackground() {
Column() {
Image($r('app.media.bg_two'))
.width(AppConstants.PERCENTAGE_MAX)
.height('40%')
}
}
}

View File

@ -0,0 +1,42 @@
import AppConstants from "../../app/AppConstant"
import { BaseTopBar } from "../custom/BaseTopTar"
import { MessageListFragment } from "./MessageListFragment"
/**
* 主页组件
*/
@Preview({
title: 'ContentTable'
})
@Component
export struct PendingMessagePage {
build() {
Column() {
BaseTopBar({
isBackImag:false,
title: $r('app.string.title_PendingMsg')
})
Tabs({ barPosition: BarPosition.Start }) {
TabContent() {
MessageListFragment({type:0})
}.tabBar(new SubTabBarStyle('未读消息'))
TabContent() {
MessageListFragment({type:1})
}.tabBar(new SubTabBarStyle('已读消息'))
}
.vertical(false)
.scrollable(true)
.barMode(BarMode.Fixed)
.width('100%')
.layoutWeight(1)
.backgroundColor(0xF1F3F5)
}
.width(AppConstants.PERCENTAGE_MAX)
.height(AppConstants.PERCENTAGE_MAX)
}
}

View File

@ -0,0 +1,264 @@
import { HMRouterMgr } from "@hadss/hmrouter";
import { AxiosError } from "@ohos/axios";
import { JSONUtil, ToastUtil } from "@pura/harmony-utils";
import { BASE_IMAGE_URL } from "../../app/AppCache";
import AppConstants from "../../app/AppConstant";
import { ApplicationModel } from "../../model/resultModel/ApplicationResultModel";
import { H5OperationType, WebAppPageParam } from "../../model/uiModel/WebAppPageParam";
import { getRecommendApplication } from "../../request/Api";
import { cardRoundBorderStyle } from "../../style/BorderStyle";
import { AppUtils } from "../../util/AppUtils";
import { BaseTopBar } from "../custom/BaseTopTar";
/**
* 主页组件
*/
@Preview({
title: 'ContentTable'
})
@Component
export struct WorkbenchFragment {
@State tjyyHeight: Resource = $r('app.float.default_92');
@State appListData: Array<ApplicationModel> = []
aboutToAppear(): void {
setTimeout(() => {
this.getRecommendApplicationList();
// this.getLocationApplicationList();
},800)
}
/**
* 获取本地应用列表 you must specify an option at least.
*/
getLocationApplicationList() {
new AppUtils().getAppList()
.then((res) => {
})
}
/**
* 获取推荐应用列表
*/
getRecommendApplicationList() {
getRecommendApplication()
.then((res) => {
console.log("get 推荐应用列表成功", JSONUtil.beanToJsonStr(res))
if (res.code == 20041) {
let data = res.data;
if (data) {
let listData = new Array<ApplicationModel>()
let tjyy = data.推荐应用;
if (tjyy) {
tjyy.forEach((item) => {
listData.push(item)
})
}
let zxyy = data.最新应用;
if (zxyy) {
zxyy.forEach((item) => {
listData.push(item)
})
}
if (listData.length < 1) {
let bean = new ApplicationModel()
bean.baseType = 91
bean.name = "应用指南"
bean.locationIcon = $r('app.media.ic_zfjc')
this.appListData.push(bean)
let bean1 = new ApplicationModel()
bean1.baseType = 92
bean1.name = "常见问题"
bean1.locationIcon = $r('app.media.ic_zazh')
this.appListData.push(bean1)
let bean2 = new ApplicationModel()
bean2.baseType = 93
bean2.name = "意见反馈"
bean2.locationIcon = $r('app.media.ic_zazh')
this.appListData.push(bean2)
bean = new ApplicationModel()
bean.baseType = 99
bean.name = "更多应用"
bean.locationIcon = $r('app.media.icon_gd2')
this.appListData.push(bean)
return
}
if (listData.length >= 8) {
this.appListData = listData.slice(8)
let bean = this.appListData[7]
bean.baseType = 99
bean.name = "更多应用"
bean.locationIcon = $r('app.media.icon_gd2')
}
this.appListData = listData
if (this.appListData.length > 4) {
this.tjyyHeight = $r('app.float.default_150')
} else {
this.tjyyHeight = $r('app.float.default_98')
}
}
}
})
.catch((err: AxiosError) => {
console.error("get 推荐应用列表失败", err)
})
}
build() {
Column(){
BaseTopBar({
isBackImag:false,
title: $r('app.string.title_Workbench')
})
Row(){
Divider()
.width($r('app.float.default_5'))
.height($r('app.float.default_14'))
.backgroundColor($r('app.color.bull'))
.margin({ left: $r('app.float.default_10') })
Text("推荐应用")
.fontSize($r('app.float.text_size_16'))
.fontColor($r('app.color.bull'))
.margin({ left: $r('app.float.default_8') })
}
.alignItems(VerticalAlign.Center)
.width(AppConstants.PERCENTAGE_MAX)
.height($r('app.float.default_40'))
this.recommendedApplicationUI()
Row(){
Divider()
.width($r('app.float.default_5'))
.height($r('app.float.default_14'))
.backgroundColor($r('app.color.bull'))
.margin({ left: $r('app.float.default_10') })
Text("自定义应用")
.fontSize($r('app.float.text_size_16'))
.fontColor($r('app.color.bull'))
.margin({ left: $r('app.float.default_8') })
}
.alignItems(VerticalAlign.Center)
.width(AppConstants.PERCENTAGE_MAX)
.margin({ top: $r('app.float.default_8')})
.height($r('app.float.default_40'))
this.locationApp();
}
.width(AppConstants.PERCENTAGE_MAX)
.height(AppConstants.PERCENTAGE_MAX)
}
/**
* 推荐应用区域
*/
@Builder
locationApp() {
Column() {
Grid() {
ForEach(this.appListData, (item: ApplicationModel, index) => {
GridItem() {
Column() {
Image(item.baseType == 99 ? item.locationIcon : BASE_IMAGE_URL + item.icon)
.size({
width: $r('app.float.default_36'),
height: $r('app.float.default_36')
})
.margin({ top: $r('app.float.default_8') });
Text(item.name)
.fontSize($r('app.float.text_size_14'))
.fontColor($r('app.color.colorGrey8'))
.margin({ top: $r('app.float.default_8') });
}
.alignItems(HorizontalAlign.Center);
};
});
}
.columnsTemplate('1fr 1fr 1fr 1fr') //一行有4列等分
.columnsGap($r('app.float.default_10')) //行间距
.rowsGap($r('app.float.default_10')); //列间距
}
.padding($r('app.float.default_10'))
.margin({ top: $r('app.float.default_10'), right: $r('app.float.default_10'), left: $r('app.float.default_10') })
.width('95%')
.height(this.tjyyHeight)
.backgroundColor($r('app.color.white'))
.border(cardRoundBorderStyle)
}
/**
* 推荐应用区域
*/
@Builder
recommendedApplicationUI() {
Column() {
Grid() {
ForEach(this.appListData, (item: ApplicationModel, index) => {
GridItem() {
Column() {
Image((item.baseType == 99||item.baseType == 91||item.baseType == 92||item.baseType == 93) ? item.locationIcon : BASE_IMAGE_URL + item.icon)
.size({
width: $r('app.float.default_36'),
height: $r('app.float.default_36')
})
.margin({ top: $r('app.float.default_8') });
Text(item.name)
.fontSize($r('app.float.text_size_14'))
.fontColor($r('app.color.colorGrey8'))
.margin({ top: $r('app.float.default_8') });
}
.alignItems(HorizontalAlign.Center);
}
.onClick(() => {
if (item.baseType == 99) {
HMRouterMgr.push({pageUrl:'ApplicationWorkbenchPage'})
return
}
if (item.baseType == 91) {
HMRouterMgr.push({pageUrl:'ApplicationGuidePage'})
return
}
if (item.baseType == 92) {
HMRouterMgr.push({pageUrl:'FrequentlyQuestionsPage'})
return
}
if (item.baseType == 93) {
HMRouterMgr.push({pageUrl:'OpinionsSuggestionsPages'})
return
}
let pageParam :WebAppPageParam= {
appName: item.name,
appId: item.clientId,
secret: item.clientSecret,
linkUrl: item.link,
operationType:H5OperationType.login,
}
HMRouterMgr.push({pageUrl:'WebAppPages',param: pageParam})
})
});
}
.columnsTemplate('1fr 1fr 1fr 1fr') //一行有4列等分
.columnsGap($r('app.float.default_10')) //行间距
.rowsGap($r('app.float.default_10')); //列间距
}
.padding($r('app.float.default_10'))
.margin({ top: $r('app.float.default_10'), right: $r('app.float.default_10'), left: $r('app.float.default_10') })
.width('95%')
.height(this.tjyyHeight)
.backgroundColor($r('app.color.white'))
.border(cardRoundBorderStyle)
}
}

View File

@ -0,0 +1,137 @@
import { HMRouter } from '@hadss/hmrouter';
import { bundleManager } from '@kit.AbilityKit';
import { BaseTopBar } from '../custom/BaseTopTar';
import { createWaterMark } from '../custom/Watermark';
@Preview
@HMRouter({ pageUrl: 'AboutPage' })
@Component
export struct AboutPage {
// @State about1: string = ' 民警可以使用个人中心查看基本信息,使用。'
// @State about2: string = ' 提供省厅、地市两级用户盘查统计实时展示分析、任务管理、卡点管理、本地临时关注人员车辆管理等功能。'
// @State about3: string = ' 2、实时比对车辆被盗抢库和临时布控库方便民警快速发现问题车辆。'
@State versionName: string = "1.0"
@State versionCode: string = "1"
aboutToAppear(): void {
this.getAppVersion()
}
/**
* 获取应用版本号
*/
async getAppVersion() {
let bundleFlags = bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION;
try {
// 使用await等待Promise的结果
const data = await bundleManager.getBundleInfoForSelf(bundleFlags);
if (data) {
console.info('FileUtil', 'getBundleInfoForSelf successfully. Data: %s', JSON.stringify(data));
this.versionName = data.versionName
this.versionCode = data.versionCode + ""
} else {
console.error('FileUtil', 'getBundleInfoForSelf returned an empty result.');
}
} catch (err) {
console.error('FileUtil', 'getBundleInfoForSelf failed: %s', err.message);
}
}
build() {
Column() {
BaseTopBar({
title:$r('app.string.title_About')
})
Column() {
Image($r('app.media.icon_applogin'))
.width($r('app.float.default_68'))
.height($r('app.float.default_68'))
Text($r('app.string.app_name'))
.fontColor($r('app.color.black'))
.fontWeight(FontWeight.Bold)
.fontSize($r('app.float.text_size_20'))
.margin({ top: $r('app.float.default_18') })
Column() {
Row() {
Text('版本号:')
.fontColor($r('app.color.grad'))
.fontSize($r('app.float.text_size_16'))
Text(this.versionCode)
.fontColor($r('app.color.colorGrey7'))
.fontSize($r('app.float.text_size_16'))
.margin({ left: $r('app.float.default_3') })
}
.width('100%')
Divider()
.height($r('app.float.default_1'))
.backgroundColor($r('app.color.page_background'))
.width('100%')
.margin({ top: $r('app.float.default_10') })
Row() {
Text('版本名称:')
.fontColor($r('app.color.grad'))
.fontSize($r('app.float.text_size_16'))
Text(this.versionName)
.fontColor($r('app.color.colorGrey7'))
.fontSize($r('app.float.text_size_16'))
.margin({ left: $r('app.float.default_3') })
}
.width('100%')
.margin({ top: $r('app.float.default_10') })
Divider()
.height($r('app.float.default_1'))
.backgroundColor($r('app.color.page_background'))
.width('100%')
.margin({ top: $r('app.float.default_10') })
Row() {
Text('检测更新:')
.fontColor($r('app.color.grad'))
.fontSize($r('app.float.text_size_16'))
Text("当前已是最新版本")
.fontColor($r('app.color.colorGrey7'))
.fontSize($r('app.float.text_size_16'))
.margin({ left: $r('app.float.default_3') })
}
.width('100%')
.margin({ top: $r('app.float.default_10') })
// Text('应用介绍')
// .fontColor($r('app.color.grad'))
// .fontSize($r('app.float.text_size_16'))
// .margin({ top: $r('app.float.default_10') })
}
.width('90%')
.padding($r('app.float.default_15'))
.margin({ top: $r('app.float.default_40') })
.backgroundColor($r('app.color.white'))
.border({
width: $r('app.float.default_1'),
color: $r('app.color.page_background'),
radius: $r('app.float.comm_image_radius')
})
}
.alignItems(HorizontalAlign.Center)
.justifyContent(FlexAlign.Center)
.margin({ bottom: $r('app.float.default_80') })
.width('100%')
.layoutWeight(1)
}
.width('100%')
.height('100%')
.backgroundColor($r('app.color.page_background'))
.overlay(createWaterMark())
}
}

View File

@ -0,0 +1,356 @@
import { HMRouter, HMRouterMgr } from "@hadss/hmrouter";
import { ToastUtil } from "@pura/harmony-utils/src/main/ets/action/ToastUtil";
import { BASE_IMAGE_URL } from "../../app/AppCache";
import AppConstants from "../../app/AppConstant";
import { AppDataModel, AppGuideDetailsBean } from "../../model/resultModel/ApplicationResultModel";
import { StringUtils } from "../../util/StringUtils";
import { BaseTopBar } from "../custom/BaseTopTar";
import { createWaterMark } from "../custom/Watermark";
import { call } from "@kit.TelephonyKit";
import { StrUtil } from "@pura/harmony-utils/src/main/ets/utils/StrUtil";
import { LitheRefresh, RefreshController } from "@abner/lithe_refresh";
import { downLoadFile, operationGuideList } from "../../request/Api";
import { AxiosError, AxiosResponse } from "@ohos/axios";
import { EmptyOrErrorItemView } from "../custom/EmptyOrErrorItemView";
import { ToastUtils } from "../../util/ToasUtils";
import { plainToInstance } from "class-transformer";
import { cardRoundBorderStyle } from "../../style/BorderStyle";
import { FileUtil } from "@pura/harmony-utils";
import { FileUtils } from "../../util/FileUtils";
import { common } from "@kit.AbilityKit";
import { DialogHelper } from "@pura/harmony-dialog";
@Component
@HMRouter({ pageUrl: "ApplicationDetailsPage" })
export struct ApplicationDetailsPage {
context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
@State param: AppDataModel | undefined = undefined
@State appListData: AppGuideDetailsBean[] = []
controller: RefreshController = new RefreshController()
scroller: Scroller = new Scroller()
isRefreshStatus: number = 0;
aboutToAppear(): void {
this.param = HMRouterMgr.getCurrentParam() as AppDataModel;
if (!this.param) {
ToastUtil.showToast("参数错误!")
HMRouterMgr.pop()
return
}
setTimeout(() => {
this.controller.isAutoRefresh = true
}, 800)
}
/**
* 错误或空处理
*/
handErrorOrEmPty(type: number, msg: string) {
ToastUtils.toastBottom(msg)
if (this.isRefreshStatus == 1) {
this.controller.finishRefresh()
this.isRefreshStatus = 0
let bean = new AppGuideDetailsBean()
bean.baseType = type;
bean.remark = msg;
this.appListData = new Array<AppGuideDetailsBean>();
this.appListData.push(bean)
}
}
//342401199412220026
getAppDetails() {
operationGuideList(this.param!.id)
.then((res) => {
this.controller.finishRefresh()
if (res.code == 20041) {
let data = res.data;
if (data) {
this.appListData = new Array<AppGuideDetailsBean>();
this.isRefreshStatus = 0
data.forEach((bean) => {
let item = plainToInstance(AppGuideDetailsBean, bean)
this.appListData.push(item);
})
} else {
this.handErrorOrEmPty(0, "暂无数据")
}
} else {
this.handErrorOrEmPty(-1, StringUtils.get(res.msg, ""))
}
})
.catch((err: AxiosError) => {
this.handErrorOrEmPty(-1, err.message)
})
}
openOrDownLoad(item: AppGuideDetailsBean) {
if (FileUtil.accessSync(FileUtils.FILE_DIR + "/" + item.getName())) {
FileUtils.openWithThirdPartyApp(this.context,FileUtils.FILE_DIR + "/" + item.getName());
return
}
//自定义文字内容
let dialogId = DialogHelper.showLoadingDialog({
loadColor: Color.White,
content: "正在下载,请稍后...",
fontSize: 15,
backgroundColor: '#ED000000',
autoCancel: true,
onWillDismiss: () => {
DialogHelper.closeDialog(dialogId)
dialogId = ''
}
})
downLoadFile(BASE_IMAGE_URL+item.filePath, FileUtils.FILE_DIR + "/" + item.getName(), (progressEvent) => {
console.info("下载进度: ", progressEvent && progressEvent.loaded && progressEvent.total ?
Math.ceil(progressEvent.loaded / progressEvent.total * 100) +"%" : 0 +"%");
})
.then((res:AxiosResponse) => {
DialogHelper.closeDialog(dialogId)
if (res.status == 200) {
this.openOrDownLoad(item)
} else {
ToastUtils.toastBottom(`下载失败:${res.status}`)
}
})
.catch((err: AxiosError) => {
DialogHelper.closeDialog(dialogId)
ToastUtils.toastBottom(`下载失败:${err.message}`)
})
}
build() {
Column() {
BaseTopBar({
title: $r('app.string.title_guide_details')
})
Column() {
Row() {
Image(BASE_IMAGE_URL + this.param!.icon)
.width($r('app.float.default_46'))
.height($r('app.float.default_46'))
Column() {
Text(this.param!.name)
.fontSize($r('app.float.text_size_16'))
.fontColor($r('app.color.colorGrey8'))
.maxLines(1)
.ellipsisMode(EllipsisMode.END)
Text(this.param!.serviceProvider)
.fontSize($r('app.float.text_size_14'))
.fontColor($r('app.color.colorGrey6'))
.margin({ top: $r('app.float.default_5') })
.maxLines(1)
.ellipsisMode(EllipsisMode.END)
}
.alignItems(HorizontalAlign.Start)
.justifyContent(FlexAlign.Center)
.layoutWeight(1)
.margin({ left: $r('app.float.default_8') })
.height($r('app.float.default_60'))
}
.width(AppConstants.PERCENTAGE_MAX)
Row() {
Text('运维人员:')
.fontColor($r('app.color.colorGrey8'))
.fontSize($r('app.float.text_size_14'))
Text(StringUtils.get(this.param!.operationPerson, "暂无"))
.fontColor($r('app.color.colorGrey8'))
.fontSize($r('app.float.text_size_14'))
Blank()
.layoutWeight(1)
Text('联系电话:')
.fontColor($r('app.color.colorGrey8'))
.fontSize($r('app.float.text_size_14'))
Text(StringUtils.get(this.param!.phoneNumber, "暂无"))
.fontColor($r('app.color.bull'))
.fontSize($r('app.float.text_size_14'))
.decoration({
type: TextDecorationType.Underline,
color: Color.Blue,
style: TextDecorationStyle.SOLID
})
.onClick(() => {
if (StrUtil.isNotEmpty(this.param!.phoneNumber)) {
this.callPhone((StringUtils.get(this.param!.phoneNumber, "暂无")))
}
})
}
.width(AppConstants.PERCENTAGE_MAX)
.margin({ top: $r('app.float.default_10') })
Divider()
.color($r('app.color.colorGrey2'))
.backgroundColor($r('app.color.colorGrey2'))
.margin({ top: $r('app.float.default_10') })
Text("应用介绍:")
.fontColor($r('app.color.colorGrey8'))
.fontSize($r('app.float.text_size_16'))
.margin({ top: $r('app.float.default_10') })
.textAlign(TextAlign.Start)
.width(AppConstants.PERCENTAGE_MAX)
Text(StringUtils.get(this.param!.remark, "暂无"))
.fontColor($r('app.color.colorGrey6'))
.fontSize($r('app.float.text_size_14'))
.margin({ top: $r('app.float.default_10') })
.textAlign(TextAlign.Start)
.width(AppConstants.PERCENTAGE_MAX)
.margin({ top: $r('app.float.default_10') })
}
.padding({
top: $r('app.float.default_10'),
bottom: $r('app.float.default_10'),
left: $r('app.float.default_10'),
right: $r('app.float.default_10')
})
.width(AppConstants.PERCENTAGE_MAX)
.backgroundColor($r('app.color.white'))
LitheRefresh({
scroller: this.scroller,
controller: this.controller,
enableLoadMore: false,
itemLayout: () => {
this.listView()
},
onRefresh: () => {
this.isRefreshStatus = 1;
this.getAppDetails()
}
})
.width(AppConstants.PERCENTAGE_MAX)
.layoutWeight(1)
}
.width(AppConstants.PERCENTAGE_MAX)
.height(AppConstants.PERCENTAGE_MAX)
.overlay(createWaterMark())
.backgroundColor($r('app.color.page_background'))
}
@Builder
listView() {
List({ scroller: this.scroller, space: 10 }) {
ForEach(this.appListData, (item: AppGuideDetailsBean) => {
if (item.baseType == 0 || item.baseType == -1) {
ListItem() {
EmptyOrErrorItemView({ type: item.baseType, msg: item.remark });
}
} else {
ListItem() {
this.itemView(item)
}
.onClick(() => {
this.openOrDownLoad(item)
})
}
})
}
.listDirection(Axis.Horizontal)
.scrollBar(BarState.Off)
.edgeEffect(EdgeEffect.None)
.width(AppConstants.PERCENTAGE_MAX)
.layoutWeight(1)
.margin({ top: $r('app.float.default_10'), bottom: $r('app.float.default_20') })
.nestedScroll({
scrollForward: NestedScrollMode.PARENT_FIRST,
scrollBackward: NestedScrollMode.PARENT_FIRST
})
}
@Builder
itemView(item: AppGuideDetailsBean) {
if (item.type == 1) {
Column() {
Image(BASE_IMAGE_URL + item.filePath)
.width($r('app.float.default_110'))
.height($r('app.float.default_180'))
Text(item.getName())
.textAlign(TextAlign.Center)
.fontColor($r('app.color.colorBluen7'))
.width($r('app.float.default_110'))
.fontSize($r('app.float.text_size_14'))
.margin({ top: $r('app.float.default_10') })
}
.alignItems(HorizontalAlign.Center)
.justifyContent(FlexAlign.Center)
.width($r('app.float.default_160'))
.margin({ left: $r('app.float.default_10'), right: $r('app.float.default_10') })
.padding($r('app.float.default_10'))
.height(AppConstants.PERCENTAGE_MAX)
.backgroundColor($r('app.color.white'))
.border(cardRoundBorderStyle)
} else if (item.type == 2) {
Column() {
Video({
src: BASE_IMAGE_URL + item.filePath,
previewUri: BASE_IMAGE_URL + item.filePath
})
.width($r('app.float.default_110'))
.height($r('app.float.default_180'))
Text(item.getName())
.textAlign(TextAlign.Center)
.fontColor($r('app.color.colorBluen7'))
.fontSize($r('app.float.text_size_14'))
.width($r('app.float.default_110'))
.margin({ top: $r('app.float.default_10') })
}
.alignItems(HorizontalAlign.Center)
.justifyContent(FlexAlign.Center)
.width($r('app.float.default_160'))
.margin({ left: $r('app.float.default_10'), right: $r('app.float.default_10') })
.padding($r('app.float.default_10'))
.layoutWeight(1)
.backgroundColor($r('app.color.white'))
.border(cardRoundBorderStyle)
} else {
Column() {
Image(item.getFileIcon(item.filePath))
.width($r('app.float.default_110'))
.height($r('app.float.default_180'))
Text(item.getName())
.textAlign(TextAlign.Center)
.fontColor($r('app.color.colorBluen7'))
.fontSize($r('app.float.text_size_14'))
.width($r('app.float.default_110'))
.margin({ top: $r('app.float.default_10') })
}
.alignItems(HorizontalAlign.Center)
.justifyContent(FlexAlign.Center)
.width($r('app.float.default_160'))
.margin({ left: $r('app.float.default_10'), right: $r('app.float.default_10') })
.padding($r('app.float.default_10'))
.layoutWeight(1)
.backgroundColor($r('app.color.white'))
.border(cardRoundBorderStyle)
}
}
callPhone(phone: string) {
if (!call.hasVoiceCapability()) {
console.error('设备不支持拨号功能');
return;
}
call.makeCall("tel:" + phone, (err: Error) => {
if (err) {
console.error(`跳转失败:${err.message}`);
}
});
}
}

View File

@ -0,0 +1,365 @@
import { LitheRefresh, RefreshController } from "@abner/lithe_refresh";
import { HMRouter, HMRouterMgr } from "@hadss/hmrouter";
import { AxiosError } from "@ohos/axios";
import { ToastUtil } from "@pura/harmony-utils";
import { BASE_IMAGE_URL } from "../../app/AppCache";
import AppConstants from "../../app/AppConstant";
import { RuanseeAbilityStag } from "../../app/RuanseeAbilityStag";
import { AppDataModel } from "../../model/resultModel/ApplicationResultModel";
import { AnHuiAddressModel } from "../../model/uiModel/AnHuiAddressModel";
import { getAppGuideList } from "../../request/Api";
import { cardRoundBorderGreyStyle, cardRoundBorderStyle } from "../../style/BorderStyle";
import { StringUtils } from "../../util/StringUtils";
import { ToastUtils } from "../../util/ToasUtils";
import { BaseTopBar } from "../custom/BaseTopTar";
import { EmptyOrErrorItemView } from "../custom/EmptyOrErrorItemView";
import { createWaterMark } from "../custom/Watermark";
/**
* 应用指南
*/
@Component
@HMRouter({ pageUrl: 'ApplicationGuidePage' })
export struct ApplicationGuidePage {
@State inputContent: string | undefined = undefined
@State cityName: string = "省厅"
@State appListData: Array<AppDataModel> = []
cityCode: string = ""
controller: RefreshController = new RefreshController()
scroller: Scroller = new Scroller()
total: number = 0;
pageNum: number = 1;
isRefreshStatus: number = 0;
@State isShowPopup: boolean = false
@State cityList: Array<Array<string>> = []
aboutToAppear(): void {
this.cityCode = RuanseeAbilityStag.userCache.getDepartmentCode + "00000000";
this.cityName = RuanseeAbilityStag.userCache.getDepartmentName;
this.cityList = new AnHuiAddressModel().address
setTimeout(() => {
this.controller.isAutoRefresh = true;
}, 800)
}
getAppListData() {
getAppGuideList(StringUtils.get(this.inputContent, ""), this.cityCode, this.pageNum)
.then((res) => {
console.debug("getAppGuide", JSON.stringify(res))
if (res.code == 20041) {
let data = res.data;
if (data) {
this.total = data.counts
let items = data.items;
if (items) {
if (this.isRefreshStatus == 1) {
this.appListData = items
this.controller.finishRefresh()
this.isRefreshStatus = 0
}
if (this.isRefreshStatus == 2) {
this.controller.finishLoadMore()
this.isRefreshStatus = 0
items.forEach(item => {
this.appListData.push(item)
})
}
if (this.pageNum * 20 >= this.total) {
this.controller.closeLoadMore = true;
}
} else {
this.handErrorOrEmPty(0, "暂无应用")
}
} else {
this.handErrorOrEmPty(0, "暂无应用")
}
} else {
this.handErrorOrEmPty(-1, StringUtils.get(res.msg, ""))
}
})
.catch((error: AxiosError) => {
console.error("getAppGuide", JSON.stringify(error))
this.handErrorOrEmPty(-1, error.message)
})
}
/**
* 错误或空处理
*/
handErrorOrEmPty(type: number, msg: string) {
ToastUtils.toastBottom(msg)
if (this.isRefreshStatus == 1) {
this.controller.finishRefresh()
this.isRefreshStatus = 0
let bean = new AppDataModel()
bean.baseType = type;
bean.remark = msg;
this.appListData = new Array<AppDataModel>();
this.appListData.push(bean)
}
if (this.isRefreshStatus == 2) {
this.controller.finishLoadMore()
this.isRefreshStatus = 0
}
}
@Builder
selectCity() {
Column() {
Grid() {
ForEach(this.cityList, (item: Array<string>) => {
GridItem() {
Column() {
Text(item[0])
.fontColor($r('app.color.colorGrey8'))
.fontSize($r('app.float.text_size_14'))
}
.backgroundColor($r('app.color.white'))
.padding({
left: $r('app.float.default_10'),
right: $r('app.float.default_10'),
top: $r('app.float.default_5'),
bottom: $r('app.float.default_5')
})
.height($r('app.float.default_40'))
.width(AppConstants.PERCENTAGE_MAX)
.alignItems(HorizontalAlign.Center)
.justifyContent(FlexAlign.Center)
.border(cardRoundBorderGreyStyle)
}.onClick(() => {
this.cityCode = item[1]+"00000000";
this.cityName = item[0];
this.isShowPopup = false;
this.controller.isAutoRefresh = true;
})
})
}.width('90%')
.columnsTemplate('1fr 1fr 1fr')
.columnsGap(10)
.rowsGap(10)
}
.width(AppConstants.PERCENTAGE_MAX)
.height($r('app.float.default_350'))
.padding({
top: $r('app.float.default_10'),
right: $r('app.float.default_10')
})
.backgroundColor($r('app.color.page_background'))
.border({
radius: $r('app.float.default_3'),
})
}
build() {
Column() {
BaseTopBar({
title: $r('app.string.title_application_guide')
})
Row() {
TextInput({ text: this.inputContent, placeholder: "请输入应用名称进行搜索" })
.placeholderColor($r('app.color.colorGrey6'))
.fontSize($r('app.float.text_size_16'))
.fontColor($r('app.color.colorGrey8'))
.margin({
left: $r('app.float.default_10'),
})
.padding({
left: $r('app.float.default_5'),
right: $r('app.float.default_5'),
})
.onChange((text: string) => {
this.inputContent = text;
})
.height($r('app.float.default_40'))
.layoutWeight(1)
.textAlign(TextAlign.Start)
.border(cardRoundBorderGreyStyle)
.enterKeyType(EnterKeyType.Search)// 设置为搜索按钮
.onSubmit((enterKey: EnterKeyType, event: SubmitEvent) => {
// 点击搜索按钮时触发
this.controller.isAutoRefresh = true;
});
Row() {
Image($r('app.media.ic_filter'))
.width($r('app.float.default_14'))
.height($r('app.float.default_14'))
Text(this.cityName)
.fontColor($r('app.color.colorGrey8'))
.fontSize($r('app.float.text_size_14'))
}
.width("auto")
.alignItems(VerticalAlign.Center)
.justifyContent(FlexAlign.Center)
.padding({
left: $r('app.float.default_8'),
top: $r('app.float.default_3'),
right: $r('app.float.default_8'),
bottom: $r('app.float.default_3')
})
.height($r('app.float.default_40'))
.onClick(() => {
if (this.isRefreshStatus != 0) {
return
}
this.isShowPopup = true;
})
.bindPopup(this.isShowPopup, {
builder: () => this.selectCity(),
placement: Placement.Top,
mask: { color: 0x80000000 },
maskColor: 0x80000000,
onStateChange: (v) => {
this.isShowPopup = v.isVisible;
},
onWillDismiss: () => {
this.isShowPopup = false;
}
})
.border({
width: $r('app.float.default_1'),
color: $r('app.color.colorGrey2'),
radius: $r('app.float.default_8')
})
.margin({ left: $r('app.float.default_8') })
}
.alignItems(VerticalAlign.Top)
.padding({
left: $r('app.float.default_10'),
top: $r('app.float.default_5'),
right: $r('app.float.default_10'),
bottom: $r('app.float.default_5')
})
.height('auto')
.backgroundColor($r('app.color.white'))
LitheRefresh({
scroller: this.scroller,
controller: this.controller,
itemLayout: () => {
this.listView()
},
onRefresh: () => {
this.controller.closeLoadMore = false;
this.pageNum = 1;
this.isRefreshStatus = 1;
this.getAppListData()
},
onLoadMore: () => {
if (this.pageNum * 20 >= this.total) {
this.controller.finishLoadMore()
this.controller.closeLoadMore = true;
ToastUtil.showToast("没有更多数据!")
return
}
this.pageNum++;
this.isRefreshStatus = 2;
this.getAppListData()
}
})
.width(AppConstants.PERCENTAGE_MAX)
.layoutWeight(1)
}
.width(AppConstants.PERCENTAGE_MAX)
.height(AppConstants.PERCENTAGE_MAX)
.overlay(createWaterMark())
.backgroundColor($r('app.color.page_background'))
}
@Builder
listView() {
List({ scroller: this.scroller, space: 10 }) {
ForEach(this.appListData, (item: AppDataModel) => {
if (item.baseType == 0 || item.baseType == -1) {
ListItem() {
EmptyOrErrorItemView({ type: item.baseType, msg: item.remark });
}
} else {
ListItem() {
this.itemView(item)
}
.onClick(() => {
HMRouterMgr.push({pageUrl:"ApplicationDetailsPage",param:item})
})
}
})
}
.listDirection(Axis.Vertical)
.scrollBar(BarState.Off)
.edgeEffect(EdgeEffect.None)
.width(AppConstants.PERCENTAGE_MAX)
.layoutWeight(1)
.nestedScroll({
scrollForward: NestedScrollMode.PARENT_FIRST,
scrollBackward: NestedScrollMode.PARENT_FIRST
})
}
@Builder
itemView(item: AppDataModel) {
Column() {
Column() {
Row() {
Image(BASE_IMAGE_URL + item.icon)
.width($r('app.float.default_46'))
.height($r('app.float.default_46'))
Column() {
Text(item.name)
.fontSize($r('app.float.text_size_16'))
.fontColor($r('app.color.colorGrey8'))
.maxLines(1)
.ellipsisMode(EllipsisMode.END)
Text(item.serviceProvider)
.fontSize($r('app.float.text_size_14'))
.fontColor($r('app.color.colorGrey6'))
.margin({ top: $r('app.float.default_5') })
.maxLines(1)
.ellipsisMode(EllipsisMode.END)
}
.alignItems(HorizontalAlign.Start)
.justifyContent(FlexAlign.Center)
.layoutWeight(1)
.margin({ left: $r('app.float.default_8') })
.height($r('app.float.default_60'))
}
.width(AppConstants.PERCENTAGE_MAX)
Row() {
Text("查看指南")
.fontSize($r('app.float.text_size_14'))
.fontColor($r('app.color.colorGrey7'))
.layoutWeight(1)
.ellipsisMode(EllipsisMode.END)
Image($r('app.media.ic_look'))
.width($r('app.float.default_26'))
.height($r('app.float.default_26'))
}
.width(AppConstants.PERCENTAGE_MAX)
.backgroundColor("#F8F9FC")
.height($r('app.float.default_45'))
.padding({ left: $r('app.float.default_10'), right: $r('app.float.default_10') })
.margin({ top: $r('app.float.default_10') })
.border(cardRoundBorderStyle)
}
.width(AppConstants.PERCENTAGE_MAX)
.height("auto")
.padding($r('app.float.default_10'))
.backgroundColor($r('app.color.white'))
.border(cardRoundBorderGreyStyle)
}
.padding({ left: $r('app.float.default_10'), right: $r('app.float.default_10') })
.height("auto")
.width(AppConstants.PERCENTAGE_MAX)
}
}

View File

@ -0,0 +1,375 @@
import { LitheRefresh, RefreshController } from "@abner/lithe_refresh";
import { HMRouter, HMRouterMgr } from "@hadss/hmrouter";
import { AxiosError } from "@ohos/axios";
import { ToastUtil } from "@pura/harmony-utils";
import { BASE_IMAGE_URL } from "../../app/AppCache";
import AppConstants from "../../app/AppConstant";
import { RuanseeAbilityStag } from "../../app/RuanseeAbilityStag";
import { AppDataModel, ApplicationModel } from "../../model/resultModel/ApplicationResultModel";
import { BaseResultModel, PagingModel } from "../../model/resultModel/BaseResultModel";
import { AnHuiAddressModel } from "../../model/uiModel/AnHuiAddressModel";
import { H5OperationType, WebAppPageParam } from "../../model/uiModel/WebAppPageParam";
import { applicationPage } from "../../request/Api";
import { cardRoundBorderGreyStyle, cardRoundBorderStyle } from "../../style/BorderStyle";
import { StringUtils } from "../../util/StringUtils";
import { ToastUtils } from "../../util/ToasUtils";
import { EmptyOrErrorItemView } from "../custom/EmptyOrErrorItemView";
import { createWaterMark } from "../custom/Watermark";
/**
* 应用工作台页面
*/
@Component
@HMRouter({ pageUrl: 'ApplicationWorkbenchPage' })
export struct ApplicationWorkbenchPage {
@State selectValue: Array<AppDataModel> = new Array<AppDataModel>();
@State inputAppName: string = "";
@State leftImage: Resource = $r('app.media.icon_back3')
cityCode: string = ""
@State cityName: string = "省厅"
@State isShowPopup: boolean = false
@State cityList: Array<Array<string>> = []
controller: RefreshController = new RefreshController()
scroller: Scroller = new Scroller()
total: number = 0;
pageNum: number = 1;
isRefreshStatus: number = 0;
@State gridColumns: string = '1fr 1fr 1fr 1fr'
aboutToAppear(): void {
this.cityCode = RuanseeAbilityStag.userCache.getDepartmentCode + "00000000";
this.cityName = RuanseeAbilityStag.userCache.getDepartmentName;
this.cityList = new AnHuiAddressModel().address
setTimeout(() => {
this.controller.autoRefresh(true)
}, 500)
}
getAppListData() {
applicationPage(this.cityCode, this.pageNum, 50, this.inputAppName)
.then((res) => {
console.debug("获取应用列表成功", JSON.stringify(res))
if (res.code == 20041) {
let data = res.data;
if (data) {
this.total = data.counts
let list = data.items;
if (list) {
if (this.isRefreshStatus == 1) {
this.gridColumns = '1fr 1fr 1fr 1fr'
this.isRefreshStatus = 0
this.controller.finishRefresh()
this.selectValue = new Array<AppDataModel>();
list.forEach((item) => {
this.selectValue.push(item)
})
}
if (this.isRefreshStatus == 2) {
this.isRefreshStatus = 0
this.controller.finishLoadMore()
list.forEach((item) => {
this.selectValue.push(item)
})
}
} else {
this.handErrorOrEmPty(0, "暂无数据")
}
} else {
this.handErrorOrEmPty(0, "暂无数据")
}
} else {
this.handErrorOrEmPty(-1, StringUtils.get(res.msg, ""))
}
})
.catch((err: AxiosError) => {
console.debug("获取应用列表成功", JSON.stringify(err))
this.handErrorOrEmPty(-1, err.message)
})
}
/**
* 错误或空处理
*/
handErrorOrEmPty(type: number, msg: string) {
ToastUtils.toastBottom(msg)
if (this.isRefreshStatus == 1) {
this.gridColumns = '1fr'
this.controller.finishRefresh()
this.isRefreshStatus = 0
let bean = new AppDataModel()
bean.baseType = type;
bean.remark = msg;
this.selectValue = new Array<AppDataModel>();
this.selectValue.push(bean)
}
if (this.isRefreshStatus == 2) {
this.controller.finishLoadMore()
this.isRefreshStatus = 0
}
}
@Builder
selectCity() {
Column() {
Grid() {
ForEach(this.cityList, (item: Array<string>) => {
GridItem() {
Column() {
Text(item[0])
.fontColor($r('app.color.colorGrey8'))
.fontSize($r('app.float.text_size_14'))
}
.backgroundColor($r('app.color.white'))
.padding({
left: $r('app.float.default_10'),
right: $r('app.float.default_10'),
top: $r('app.float.default_5'),
bottom: $r('app.float.default_5')
})
.height($r('app.float.default_40'))
.width(AppConstants.PERCENTAGE_MAX)
.alignItems(HorizontalAlign.Center)
.justifyContent(FlexAlign.Center)
.border(cardRoundBorderGreyStyle)
}.onClick(() => {
this.cityCode = item[1] + "00000000";
this.cityName = item[0];
this.isShowPopup = false;
this.controller.autoRefresh(true)
})
})
}.width('90%')
.columnsTemplate('1fr 1fr 1fr')
.columnsGap(10)
.rowsGap(10)
}
.width(AppConstants.PERCENTAGE_MAX)
.height($r('app.float.default_350'))
.padding({
top: $r('app.float.default_10'),
right: $r('app.float.default_10')
})
.backgroundColor($r('app.color.page_background'))
.border({
radius: $r('app.float.default_3'),
})
}
@Builder
listView() {
Grid(this.scroller) {
ForEach(this.selectValue, (item: AppDataModel, index) => {
if (item.baseType == 0 || item.baseType == -1) {
GridItem() {
EmptyOrErrorItemView({ type: item.baseType, msg: item.remark })
}
} else {
GridItem() {
Column() {
Image(item.baseType == 99 ? item.locationIcon : BASE_IMAGE_URL + item.icon)
.size({
width: $r('app.float.default_36'),
height: $r('app.float.default_36')
})
.margin({ top: $r('app.float.default_8') });
Text(item.name)
.fontSize($r('app.float.text_size_14'))
.fontColor($r('app.color.colorGrey8'))
.textAlign(TextAlign.Center)
.margin({ top: $r('app.float.default_8') });
}
.alignItems(HorizontalAlign.Center);
}
.onClick(() => {
if (item.baseType == 99) {
HMRouterMgr.push({pageUrl:'ApplicationWorkbenchPage'})
return
}
if (item.baseType == 91) {
HMRouterMgr.push({pageUrl:'ApplicationGuidePage'})
return
}
if (item.baseType == 92) {
HMRouterMgr.push({pageUrl:'FrequentlyQuestionsPage'})
return
}
if (item.baseType == 93) {
HMRouterMgr.push({pageUrl:'OpinionsSuggestionsPages'})
return
}
let pageParam :WebAppPageParam= {
appName: item.name,
appId: item.clientId,
secret: item.clientSecret,
linkUrl: item.link,
operationType:H5OperationType.login,
}
HMRouterMgr.push({pageUrl:'WebAppPages',param: pageParam})
})
}
});
}
.columnsTemplate(this.gridColumns) //一行有4列等分
.columnsGap($r('app.float.default_10')) //行间距
.rowsGap($r('app.float.default_10')) //列间距
.scrollBar(BarState.Off)
.edgeEffect(EdgeEffect.None)
.width(AppConstants.PERCENTAGE_MAX)
.layoutWeight(1)
.padding({ left: 20, right: 20 })
.nestedScroll({
scrollForward: NestedScrollMode.PARENT_FIRST,
scrollBackward: NestedScrollMode.PARENT_FIRST
})
}
build() {
Column() {
Blank()
.width(AppConstants.PERCENTAGE_MAX)
.height($r('app.float.default_30'))
.backgroundColor($r('app.color.bull'))
this.topBar()
Column(){
LitheRefresh({
scroller: this.scroller,
controller: this.controller,
itemLayout: () => {
this.listView()
},
onRefresh: () => {
this.controller.closeLoadMore = false;
this.pageNum = 1;
this.isRefreshStatus = 1;
this.getAppListData()
},
onLoadMore: () => {
if (this.pageNum * 20 >= this.total) {
this.controller.finishLoadMore()
this.controller.closeLoadMore = true;
ToastUtil.showToast("没有更多数据!")
return
}
this.pageNum++;
this.isRefreshStatus = 2;
this.getAppListData()
}
})
.width(AppConstants.PERCENTAGE_MAX)
.height(AppConstants.PERCENTAGE_MAX)
.width(AppConstants.PERCENTAGE_MAX)
.backgroundColor($r('app.color.white'))
.border(cardRoundBorderStyle)
}
.padding($r('app.float.default_10'))
.layoutWeight(1)
}
.width(AppConstants.PERCENTAGE_MAX)
.height(AppConstants.PERCENTAGE_MAX)
.backgroundColor($r('app.color.page_background'))
.overlay(createWaterMark())
}
@Builder
topBar() {
Row() {
Row() {
Image(this.leftImage)
.width($r('app.float.default_24'))
.height($r('app.float.default_24'))
}
.height("100%")
.width('auto')
.alignItems(VerticalAlign.Center)
.padding({ left: $r('app.float.default_10') })
.onTouch((event) => {
if (event.type === TouchType.Down) {
this.leftImage = $r('app.media.icon_back2');
} else if (event.type === TouchType.Up) {
this.leftImage = $r('app.media.icon_back3');
}
})
.onClick(() => {
HMRouterMgr.pop()
})
Row() {
Image($r('app.media.icon_search'))
.width($r('app.float.default_18'))
.height($r('app.float.default_18'))
TextInput({ text: this.inputAppName, placeholder: '请输入应用名称' })
.fontColor($r('app.color.colorGrey8'))
.fontSize($r('app.float.text_size_14'))
.height($r('app.float.default_38'))
.backgroundColor(Color.Transparent)
.cancelButton({
style: CancelButtonStyle.INPUT, // 设置清除按钮样式为图标
icon: {
src: $r('app.media.icon_clean'), // 自定义图标资源路径
size: $r('app.float.default_18') // 图标尺寸单位vp若省略则默认24vp
}
})
.layoutWeight(1)
.textAlign(TextAlign.Start)
.onChange((value: string) => {
this.inputAppName = value;
})
.enterKeyType(EnterKeyType.Search)// 设置为搜索按钮
.onSubmit((enterKey: EnterKeyType, event: SubmitEvent) => {
// 点击搜索按钮时触发
this.controller.autoRefresh(true)
});
}
.alignItems(VerticalAlign.Center)
.layoutWeight(1)
.padding({ left: $r('app.float.default_10'), right: $r('app.float.default_10') })
.height($r('app.float.default_38'))
.margin({ left: $r('app.float.default_5') })
.backgroundColor($r('app.color.white'))
.border({
width: $r('app.float.default_1'),
color: $r('app.color.white'),
radius: $r('app.float.default_8')
})
Row() {
Image($r('app.media.ic_dropup'))
.width($r('app.float.default_24'))
.height($r('app.float.default_24'))
Text(this.cityName)
.fontColor($r('app.color.white'))
.fontSize($r('app.float.text_size_16'))
}
.alignItems(VerticalAlign.Center)
.height("100%")
.margin({ left: $r('app.float.default_5') })
.width('auto')
.padding({ right: $r('app.float.default_10') })
.bindPopup(this.isShowPopup, {
builder: () => this.selectCity(),
placement: Placement.Top,
mask: { color: 0x80000000 },
maskColor: 0x80000000,
onStateChange: (v) => {
this.isShowPopup = v.isVisible;
},
onWillDismiss: () => {
this.isShowPopup = false;
}
})
.onClick(() => {
this.isShowPopup = true
})
}
.alignItems(VerticalAlign.Center)
.width('100%')
.backgroundColor($r('app.color.bull'))
.height($r('app.float.default_58'))
}
}

View File

@ -0,0 +1,233 @@
import { HMRouter, HMRouterMgr } from "@hadss/hmrouter";
import { FeedBackBean } from "../../model/requestModel/MessageRequestModel";
import { BaseTopBar } from "../custom/BaseTopTar";
import AppConstants from "../../app/AppConstant";
import { createWaterMark } from "../custom/Watermark";
import { StringUtils } from "../../util/StringUtils";
import { cardRoundBorderStyle } from "../../style/BorderStyle";
import { ToastUtil } from "@pura/harmony-utils/src/main/ets/action/ToastUtil";
import { plainToInstance } from "class-transformer";
import { webview } from "@kit.ArkWeb";
import { StrUtil } from "@pura/harmony-utils/src/main/ets/utils/StrUtil";
/**
* 反馈详情
*/
@HMRouter({ pageUrl: 'FeedBackDetailsPage' })
@Component
export struct FeedBackDetailsPage {
@State param: FeedBackBean | undefined = undefined;
webController: webview.WebviewController = new webview.WebviewController();
aboutToAppear(): void {
let param = HMRouterMgr.getCurrentParam() as FeedBackBean;
if (!param) {
ToastUtil.showToast("参数错误")
HMRouterMgr.pop()
return
}
this.param = plainToInstance(FeedBackBean,param)
// if (StrUtil.isNotEmpty(this.param?.replyContent)){
// setTimeout(() => {
//
// },800)
// }
}
build() {
Column() {
BaseTopBar({
title: $r('app.string.title_feedback_details'),
})
Text(StringUtils.get(this.param?.title, ""))
.constraintSize({
minHeight: $r('app.float.default_40'),
})
.width(AppConstants.PERCENTAGE_MAX)
.backgroundColor($r('app.color.white'))
.fontColor($r('app.color.colorGrey8'))
.fontSize($r('app.float.text_size_16'))
.textAlign(TextAlign.Center)
.padding({
left: $r('app.float.default_10'),
right: $r('app.float.default_10'),
top: $r('app.float.default_8'),
bottom: $r('app.float.default_8'),
})
Scroll(){
Column() {
Row() {
Text(this.getTypeStr(StringUtils.getNumber(this.param?.type, 0)))
.fontColor($r('app.color.colorYellow7'))
.fontSize($r('app.float.text_size_10'))
.padding({
left: $r('app.float.default_5'),
right: $r('app.float.default_5'),
top: $r('app.float.default_2'),
bottom: $r('app.float.default_2')
})
.border({
width: $r('app.float.default_1'),
color: $r('app.color.colorYellow7'),
radius: $r('app.float.default_8')
})
Text(StringUtils.get(this.param!.applicationName,""))
.fontColor($r('app.color.colorBluen7'))
.fontSize($r('app.float.text_size_10'))
.padding({
left: $r('app.float.default_5'),
right: $r('app.float.default_5'),
top: $r('app.float.default_2'),
bottom: $r('app.float.default_2')
})
.border({
width: $r('app.float.default_1'),
color: $r('app.color.colorBluen7'),
radius: $r('app.float.default_8')
})
.margin({ left: $r('app.float.default_8') })
.visibility(StringUtils.isNullOrEmpty(this.param!.applicationName) ? Visibility.None : Visibility.Visible)
Text(this.getReplyStatusStr(this.param!.replyStatus))
.fontColor(this.param!.replyStatus == 0 ? $r('app.color.colorGrey6') : $r('app.color.colorGreen6'))
.fontSize($r('app.float.text_size_10'))
.padding({
left: $r('app.float.default_5'),
right: $r('app.float.default_5'),
top: $r('app.float.default_2'),
bottom: $r('app.float.default_2')
})
.border({
width: $r('app.float.default_1'),
color: this.param!.replyStatus == 0 ? $r('app.color.colorGrey6') : $r('app.color.colorGreen6'),
radius: $r('app.float.default_8')
})
.margin({ left: $r('app.float.default_8') })
}
.width(AppConstants.PERCENTAGE_MAX)
.alignItems(VerticalAlign.Center)
.justifyContent(FlexAlign.Start)
.margin({ top: $r('app.float.default_5') })
Text(this.param!.createTime)
.fontColor($r('app.color.colorGrey6'))
.fontSize($r('app.float.text_size_12'))
.width(AppConstants.PERCENTAGE_MAX)
.textAlign(TextAlign.End)
.margin({ top: $r('app.float.default_8') })
Column(){
Text("意见建议")
.fontColor($r('app.color.colorGrey8'))
.fontSize($r('app.float.text_size_16'))
.textAlign(TextAlign.Start)
.height($r('app.float.default_36'))
Divider()
.width(AppConstants.PERCENTAGE_MAX)
.height($r('app.float.default_1'))
.backgroundColor($r('app.color.colorGrey2'))
Text(this.param!.content)
.fontColor($r('app.color.colorGrey8'))
.fontSize($r('app.float.text_size_14'))
.textAlign(TextAlign.Start)
.margin({ top: $r('app.float.default_10') })
}
.backgroundColor($r('app.color.white'))
.alignItems(HorizontalAlign.Start)
.border(cardRoundBorderStyle)
.width(AppConstants.PERCENTAGE_MAX)
.height('auto')
.padding($r('app.float.default_10'))
.margin({ top: $r('app.float.default_10') })
Column(){
Text(StringUtils.get(this.param!.replier,"暂无"))
.fontColor($r('app.color.colorBluen6'))
.fontSize($r('app.float.text_size_16'))
.textAlign(TextAlign.Start)
.height($r('app.float.default_36'))
Divider()
.width(AppConstants.PERCENTAGE_MAX)
.height($r('app.float.default_1'))
.backgroundColor($r('app.color.colorGrey2'))
Web({src:"",controller: this.webController})
.width(AppConstants.PERCENTAGE_MAX)
.height("auto")
.zoomAccess(true)
.onAppear(() =>{
let data = this.param?.getReplyContent();
// 在组件引用上使用loadData方法
this.webController.loadData(data, "text/html", "UTF-8")
})
Divider()
.width(AppConstants.PERCENTAGE_MAX)
.height($r('app.float.default_1'))
.margin({ top: $r('app.float.default_8') })
.backgroundColor($r('app.color.colorGrey2'))
Text(this.param!.updateTime)
.fontColor($r('app.color.colorGrey6'))
.fontSize($r('app.float.text_size_12'))
.width(AppConstants.PERCENTAGE_MAX)
.textAlign(TextAlign.End)
.margin({ top: $r('app.float.default_8') })
}
.visibility(this.param!.replyStatus == 1? Visibility.Visible : Visibility.None)
.backgroundColor($r('app.color.white'))
.alignItems(HorizontalAlign.Start)
.border(cardRoundBorderStyle)
.width(AppConstants.PERCENTAGE_MAX)
.height('auto')
.padding($r('app.float.default_10'))
.margin({ top: $r('app.float.default_10') })
}
.width(AppConstants.PERCENTAGE_MAX)
.height(AppConstants.PERCENTAGE_MAX)
.padding({
left: $r('app.float.default_10'),
right: $r('app.float.default_10'),
})
}
.width(AppConstants.PERCENTAGE_MAX)
.layoutWeight(1)
}
.width(AppConstants.PERCENTAGE_MAX)
.height(AppConstants.PERCENTAGE_MAX)
.backgroundColor($r('app.color.page_background'))
.overlay(createWaterMark())
}
getTypeStr(type: number): string {
switch (type) {
case 1:
return "个人建议";
case 2:
return "软件问题";
case 3:
return "硬件问题";
case 4:
default:
return "其它";
}
}
getReplyStatusStr(replyStatus: number): string {
return replyStatus == 0 ? "未回复" : "已回复";
}
}

View File

@ -0,0 +1,351 @@
import { LitheRefresh, RefreshController } from "@abner/lithe_refresh";
import { HMRouter, HMRouterMgr } from "@hadss/hmrouter";
import { AxiosError } from "@ohos/axios";
import { ObjectUtil, ToastUtil } from "@pura/harmony-utils";
import { BASE_IMAGE_URL } from "../../app/AppCache";
import AppConstants from "../../app/AppConstant";
import { QuestionBean, QuestionModel } from "../../model/resultModel/QuestionModel";
import { BasePageResult } from "../../model/uiModel/PageResultModel";
import { getQuestion } from "../../request/Api";
import { StringUtils } from "../../util/StringUtils";
import { BaseTopBar } from "../custom/BaseTopTar";
import { EmptyOrErrorItemView } from "../custom/EmptyOrErrorItemView";
import { createWaterMark } from "../custom/Watermark";
/**
* 常见问题
*/
@Component
@HMRouter({ pageUrl: 'FrequentlyQuestionsPage' })
export struct FrequentlyQuestionsPage {
@State dataList: Array<QuestionBean> = []
controller: RefreshController = new RefreshController()
scroller: Scroller = new Scroller()
isRefreshStatus: number = 0;
@State isShowBottomSheet:Array< boolean> = [];
aboutToAppear(): void {
setTimeout(() => {
this.controller.autoRefresh(true)
}, 500)
}
getDataList() {
getQuestion()
.then((res) => {
this.controller.finishRefresh()
this.isRefreshStatus = 0;
if (res.code == 20041) {
let data = res.data;
if (data) {
// let beanJG = new QuestionBean()
// beanJG.baseType = 4;
this.dataList = new Array()
this.isShowBottomSheet = new Array<boolean>();
data.forEach((item: QuestionModel) => {
let bean = new QuestionBean()
bean.baseType = 1;
bean.problem = item.title
this.dataList.push(bean)
this.isShowBottomSheet.push(false)
let beans = item.data;
if (beans) {
beans.forEach((item: QuestionBean) => {
let bean = ObjectUtil.objToClass(QuestionBean, item)
// let bean = plainToInstance(QuestionBean, item);
this.isShowBottomSheet.push(false)
bean.baseType = 2;
this.dataList.push(bean)
})
this.dataList[this.dataList.length-1].baseType = 3
}
})
if (this.dataList.length < 1) {
this.handErrorOrEmPty(0, "暂无常见问题!")
}
} else {
this.handErrorOrEmPty(0, "暂无常见问题!")
}
} else {
this.handErrorOrEmPty(-1, StringUtils.get(res.msg, res.code + ""))
}
})
.catch((err: AxiosError) => {
this.handErrorOrEmPty(-1, StringUtils.get(err.message, ""))
})
}
/**
* 错误或空处理
*/
handErrorOrEmPty(type: number, msg: string) {
ToastUtil.showToast(msg)
if (this.isRefreshStatus == 1) {
this.isRefreshStatus = 0
this.controller.finishRefresh()
this.dataList = new Array<QuestionBean>();
let bean = new QuestionBean()
bean.baseType = type;
bean.problem = msg;
this.dataList.push(bean)
}
}
@Builder
bottomSheet(item: QuestionBean) {
Column() {
Text($r('app.string.title_frequently_questions'))
.fontColor($r('app.color.bull'))
.fontSize($r('app.float.text_size_16'))
.width(AppConstants.PERCENTAGE_MAX)
.fontWeight(FontWeight.Bold)
.height($r('app.float.default_48'))
.textAlign(TextAlign.Center)
.align(Alignment.Center)
Divider()
.width(AppConstants.PERCENTAGE_MAX)
.height($r('app.float.default_1'))
.backgroundColor($r('app.color.colorGrey1'))
Scroll(){
Column() {
Text(item.problem)
.fontColor($r('app.color.colorBluen7'))
.fontSize($r('app.float.text_size_16'))
.width(AppConstants.PERCENTAGE_MAX)
.height($r('app.float.default_38'))
.textAlign(TextAlign.Start)
.padding({ left: $r('app.float.default_10'), right: $r('app.float.default_10') })
.backgroundColor($r('app.color.white'))
Divider()
.width(AppConstants.PERCENTAGE_MAX)
.height($r('app.float.default_1'))
.backgroundColor($r('app.color.colorGrey1'))
Text(StringUtils.get("\t\t"+item.reply.replace("\\n","\n").replace("\\t","\t"),"暂无"))
.fontColor($r('app.color.colorGrey8'))
.fontSize($r('app.float.text_size_14'))
.width(AppConstants.PERCENTAGE_MAX)
.padding({ left: $r('app.float.default_10'), right: $r('app.float.default_10') })
.height("auto")
.margin({top: $r('app.float.default_10'),bottom: $r('app.float.default_10')})
Divider()
.width(AppConstants.PERCENTAGE_MAX)
.height($r('app.float.default_1'))
.backgroundColor($r('app.color.colorGrey1'))
Text(item.extend)
.fontColor($r('app.color.colorGrey6'))
.fontSize($r('app.float.text_size_12'))
.width(AppConstants.PERCENTAGE_MAX)
.padding({ left: $r('app.float.default_10'), right: $r('app.float.default_10') })
.visibility(StringUtils.isNullOrEmpty(item.guidance)?Visibility.None:Visibility.Visible)
.textAlign(TextAlign.Start)
.margin({top: $r('app.float.default_10'),bottom: $r('app.float.default_10')})
Image(BASE_IMAGE_URL+item.guidance)
.width(AppConstants.PERCENTAGE_MAX)
.visibility(StringUtils.isNullOrEmpty(item.guidance)?Visibility.None:Visibility.Visible)
.height($r('app.float.default_240'))
}
.width(AppConstants.PERCENTAGE_MAX)
.height(AppConstants.PERCENTAGE_MAX)
.padding({bottom: $r('app.float.default_10')})
}
.width(AppConstants.PERCENTAGE_MAX)
.layoutWeight(1)
}
.width(AppConstants.PERCENTAGE_MAX)
.height(AppConstants.PERCENTAGE_MAX)
.backgroundColor($r('app.color.white'))
.border({
radius: {
topLeft: $r('app.float.default_10'),
topRight: $r('app.float.default_10')
}
})
}
build() {
Column() {
BaseTopBar({
title: $r('app.string.title_frequently_questions'),
})
LitheRefresh({
scroller: this.scroller,
controller: this.controller,
enableLoadMore: false,
itemLayout: () => {
this.listView()
},
onRefresh: () => {
this.controller.closeLoadMore = false;
this.isRefreshStatus = 1;
this.getDataList()
}
})
.width(AppConstants.PERCENTAGE_MAX)
.layoutWeight(1)
}
.width(AppConstants.PERCENTAGE_MAX)
.height(AppConstants.PERCENTAGE_MAX)
.overlay(createWaterMark())
.backgroundColor($r('app.color.page_background'))
}
@Builder
listView() {
List({ scroller: this.scroller }) {
ForEach(this.dataList, (item: QuestionBean,index:number) => {
if (item.baseType == 0 || item.baseType == -1) {
ListItem() {
EmptyOrErrorItemView({ type: item.baseType, msg: item.problem })
}
} else if (item.baseType == 1) {
ListItem() {
this.itemViewTop(item)
}
} else if (item.baseType == 2) {
ListItem() {
this.itemViewCenter(item)
}
.bindSheet(this.isShowBottomSheet[index], this.bottomSheet(item), {
height:'66.6%',
dragBar: true,
// detents:[$r('app.float.default_3')],
preferType: SheetType.BOTTOM,
showClose:false,
shouldDismiss: () => {
this.isShowBottomSheet[index] = false;
}
})
.onClick(() => {
this.isShowBottomSheet[index] = true;
})
} else if (item.baseType == 3) {
ListItem() {
this.itemViewBottom(item)
}
.bindSheet(this.isShowBottomSheet[index], this.bottomSheet(item), {
height:'66.6%',
dragBar: true,
showClose:false,
preferType: SheetType.BOTTOM,
shouldDismiss: () => {
this.isShowBottomSheet[index] = false;
}
})
.onClick(() => {
this.isShowBottomSheet[index] = true;
})
}
})
}
.listDirection(Axis.Vertical)
.scrollBar(BarState.Off)
.edgeEffect(EdgeEffect.None)
.width(AppConstants.PERCENTAGE_MAX)
.layoutWeight(1)
.nestedScroll({
scrollForward: NestedScrollMode.PARENT_FIRST,
scrollBackward: NestedScrollMode.PARENT_FIRST
})
}
@Builder
itemViewTop(item: QuestionBean) {
Row() {
Text(item.problem)
.fontColor($r('app.color.white'))
.fontSize($r('app.float.text_size_14'))
.width(AppConstants.PERCENTAGE_MAX)
.height(AppConstants.PERCENTAGE_MAX)
.textAlign(TextAlign.Start)
.padding({ left: $r('app.float.default_10'), right: $r('app.float.default_10') })
.backgroundColor($r('app.color.bull'))
.border({
radius: {
topLeft: $r('app.float.default_5'),
topRight: $r('app.float.default_5')
}
})
.align(Alignment.Center)
}
.padding({ top: $r('app.float.default_10'), left: $r('app.float.default_10'), right: $r('app.float.default_10') })
.width(AppConstants.PERCENTAGE_MAX)
.height($r('app.float.default_46'))
}
@Builder
itemViewCenter(item: QuestionBean) {
Column() {
Row() {
Text(item.problem)
.fontColor($r('app.color.colorGrey8'))
.fontSize($r('app.float.text_size_14'))
.height(AppConstants.PERCENTAGE_MAX)
.layoutWeight(1)
.textAlign(TextAlign.Start)
.align(Alignment.Center)
Image($r('app.media.arrow_right'))
.width($r('app.float.default_20'))
.height($r('app.float.default_20'))
.margin({ left: $r('app.float.default_10') })
}
.alignItems(VerticalAlign.Center)
.width(AppConstants.PERCENTAGE_MAX)
.height($r('app.float.default_46'))
.padding({ left: $r('app.float.default_10'), right: $r('app.float.default_10') })
.backgroundColor($r('app.color.white'))
Divider()
.width(AppConstants.PERCENTAGE_MAX)
.height($r('app.float.default_1'))
.backgroundColor($r('app.color.colorGrey2'))
}
.width(AppConstants.PERCENTAGE_MAX)
.height($r('app.float.default_47'))
.padding({ left: $r('app.float.default_10'), right: $r('app.float.default_10') })
}
@Builder
itemViewBottom(item: QuestionBean) {
Row() {
Row() {
Text(item.problem)
.fontColor($r('app.color.colorGrey8'))
.fontSize($r('app.float.text_size_14'))
.height(AppConstants.PERCENTAGE_MAX)
.layoutWeight(1)
.textAlign(TextAlign.Start)
.align(Alignment.Center)
Image($r('app.media.arrow_right'))
.width($r('app.float.default_20'))
.height($r('app.float.default_20'))
.margin({ left: $r('app.float.default_10') })
}
.alignItems(VerticalAlign.Center)
.width(AppConstants.PERCENTAGE_MAX)
.height(AppConstants.PERCENTAGE_MAX)
.padding({ left: $r('app.float.default_10'), right: $r('app.float.default_10') })
.backgroundColor($r('app.color.white'))
.border({
radius: {
bottomLeft: $r('app.float.default_5'),
bottomRight: $r('app.float.default_5')
}
})
}
.padding({ left: $r('app.float.default_10'), right: $r('app.float.default_10') })
.width(AppConstants.PERCENTAGE_MAX)
.height($r('app.float.default_46'))
}
}

View File

@ -0,0 +1,66 @@
import { AttributeUpdater } from '@kit.ArkUI';
import { HMDefaultGlobalAnimator, HMNavigation } from '@hadss/hmrouter';
@Entry
@Component
struct Index {
modifier: IndexNavModifier = new IndexNavModifier();
onPageShow(): void {
}
onPageHide(): void {
}
getToken() {
// getPgToken()
// .then((res) => {
// if (res) {
// AppCache.getAppCache().setPgToken = res.access_token;
// }
// console.info(JSON.stringify(res));
// })
// .catch((error: AxiosError) => {
// console.error(JSON.stringify(error));
// })
}
aboutToAppear() {
// this.getIpAddress();
// this.getToken()
}
build() {
Column() {
HMNavigation({
navigationId: 'startNavigation', homePageUrl: 'StartPage',
options: {
standardAnimator: HMDefaultGlobalAnimator.STANDARD_ANIMATOR,
dialogAnimator: HMDefaultGlobalAnimator.DIALOG_ANIMATOR,
modifier: this.modifier
}
}) {
}
}
.width('100%')
.height('100%')
.expandSafeArea([SafeAreaType.SYSTEM])
}
exitApp() {
// this.context.terminateSelf();
// let preferences = data_preferences.getPreferences(this.context, H_STORE);
// preferences.then((res) => {
// // res.clearSync();
// })
}
}
class IndexNavModifier extends AttributeUpdater<NavigationAttribute> {
initializeModifier(instance: NavigationAttribute): void {
instance.hideNavBar(true);
}
}

View File

@ -0,0 +1,134 @@
import { HMRouter } from '@hadss/hmrouter';
import { abilityAccessCtrl, bundleManager, common, Permissions } from '@kit.AbilityKit';
import AppConstants from '../../app/AppConstant';
import { FileUtils } from '../../util/FileUtils';
import { createWaterMark } from '../custom/Watermark';
import { HomeFragment } from '../fragment/HomeFragment';
import { MyFragment } from '../fragment/MyFragment';
import { PendingMessagePage } from '../fragment/PendingMessagePage';
import { WorkbenchFragment } from '../fragment/WorkbenchFragment';
@HMRouter({ pageUrl: 'MainPage' })
@Component
export struct MainPage {
context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
@State currentIndex: number = 0
private tabsController: TabsController = new TabsController()
// 记录上一次点击时间
private pretime: number = -1;
aboutToAppear(): void {
this.applyForPermission()
}
/**
* 申请权限
*/
applyForPermission() {
let permissions = new Array<Permissions>();
permissions.push('ohos.permission.LOCATION')
permissions.push('ohos.permission.APPROXIMATELY_LOCATION')
permissions.push('ohos.permission.CAMERA')
this.checkPermissionGrant(permissions)
}
/**
* 检测权限
* @param permissionArray
*/
checkPermissionGrant(permissionArray: Array<Permissions>) {
let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager()
// 获取应用程序的accessTokenID
let bundleInfo = bundleManager.getBundleInfoForSelfSync(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION)
let appInfo: bundleManager.ApplicationInfo = bundleInfo.appInfo
let tokenId: number = appInfo.accessTokenId
let wsqPermissionArray = new Array<Permissions>()
for (let i = 0; i < permissionArray.length; i++) {
let grantStatus = atManager.checkAccessTokenSync(tokenId, permissionArray[i])
if (grantStatus == abilityAccessCtrl.GrantStatus.PERMISSION_DENIED) {
wsqPermissionArray.push(permissionArray[i])
}
}
if (wsqPermissionArray.length > 0) {
//有未申请的权限发送到Ability,由 Ability 发起权限申请
// this.requestPermissionsFromUser(wsqPermissionArray)
this.context.eventHub.emit('ui_event', wsqPermissionArray);
} else {
//权限全部申请
this.initPage()
// this.getCurrentLocation()
}
}
initPage() {
FileUtils.createFileDir()
}
build() {
Column() {
Tabs({
barPosition: BarPosition.End,
controller: this.tabsController
}) {
TabContent(){
HomeFragment({
allMessage:()=>{
this.tabsController.changeIndex(1)
this.currentIndex =1
}
})
}
.tabBar(this.TabBuilder('首页', 0, $r('app.media.icon_main_home'), $r('app.media.icon_main_home_def')))
TabContent(){
PendingMessagePage()
}.tabBar(this.TabBuilder('待办', 1, $r('app.media.icon_main_message'), $r('app.media.icon_main_message_def')))
TabContent(){
WorkbenchFragment()
}.tabBar(this.TabBuilder('工作台', 2, $r('app.media.icon_main_work'), $r('app.media.icon_main_work_def')))
TabContent(){
MyFragment()
}.tabBar(this.TabBuilder('我的', 3, $r('app.media.icon_main_my'), $r('app.media.icon_main_my_def')))
}
.width(AppConstants.PERCENTAGE_MAX)
.height(AppConstants.PERCENTAGE_MAX)
.scrollable(false)
.barMode(BarMode.Fixed)
.barWidth('100%')
.barHeight('8.7%')
}
.width(AppConstants.PERCENTAGE_MAX)
.height(AppConstants.PERCENTAGE_MAX)
.backgroundColor($r('app.color.page_background'))
.overlay(createWaterMark())
}
// 自定义导航页签的样式
@Builder
TabBuilder(title: string, targetIndex: number, selectedImg: Resource, normalImg: Resource) {
Column() {
Image(this.currentIndex === targetIndex ? selectedImg : normalImg)
.size({ width: $r('app.float.default_24'), height: $r('app.float.default_24') })
.margin({top: $r('app.float.default_10')})
Text(title)
.fontColor(this.currentIndex === targetIndex ? $r('app.color.bull') : '#8a8a8a')
.fontSize($r('app.float.text_size_12'))
.margin({top: $r('app.float.default_5')})
}
.width('100%')
.height('100%')
.backgroundColor($r('app.color.white'))
.justifyContent(FlexAlign.Start)
.alignItems(HorizontalAlign.Center)
.padding({bottom: $r('app.float.default_28')})
.onClick(() => {
this.currentIndex = targetIndex
this.tabsController.changeIndex(this.currentIndex)
})
}
}

View File

@ -0,0 +1,99 @@
import { HMRouter, HMRouterMgr } from "@hadss/hmrouter";
import { ToastUtil } from "@pura/harmony-utils/src/main/ets/action/ToastUtil";
import { BASE_IMAGE_URL } from "../../app/AppCache";
import AppConstants from "../../app/AppConstant";
import { MainMessageBean } from "../../model/resultModel/MessageResultModel";
import { cardRoundBorderStyle } from "../../style/BorderStyle";
import { StringUtils } from "../../util/StringUtils";
import { BaseTopBar } from "../custom/BaseTopTar";
import { createWaterMark } from "../custom/Watermark";
@Component
@HMRouter({ pageUrl: 'MessageDetailsPage' })
export struct MessageDetailsPage {
@State param: MainMessageBean | undefined = undefined
aboutToAppear(): void {
this.param = HMRouterMgr.getCurrentParam() as MainMessageBean;
if (!this.param) {
ToastUtil.showToast('参数错误!')
HMRouterMgr.pop()
return
}
}
build() {
Column() {
BaseTopBar({
title: $r('app.string.title_msg_details')
})
Scroll() {
Column() {
Text(this.param!.msgTitle)
.fontColor($r('app.color.colorGrey8'))
.fontSize($r('app.float.text_size_18'))
.textAlign(TextAlign.Start)
.align(Alignment.Center)
.fontWeight(FontWeight.Bold)
.width(AppConstants.PERCENTAGE_MAX)
.height('auto')
Row() {
Image(BASE_IMAGE_URL + this.param!.appIcon)
.width($r('app.float.default_24'))
.height($r('app.float.default_24'))
Text(this.param!.appName)
.fontColor($r('app.color.colorBluen7'))
.fontSize($r('app.float.text_size_16'))
.textAlign(TextAlign.Start)
.fontWeight(FontWeight.Bold)
.width(AppConstants.PERCENTAGE_MAX)
.height('auto')
.margin({ left: $r('app.float.default_5') })
}
.width(AppConstants.PERCENTAGE_MAX)
.alignItems(VerticalAlign.Center)
.justifyContent(FlexAlign.Start)
.margin({ top: $r('app.float.default_10'), bottom: $r('app.float.default_10') })
Divider()
.width(AppConstants.PERCENTAGE_MAX)
.height($r('app.float.default_1'))
.backgroundColor($r('app.color.colorGrey1'))
Text("\t\t"+StringUtils.get(this.param!.msgContent, '暂无内容'))
.fontColor($r('app.color.colorGrey8'))
.fontSize($r('app.float.text_size_16'))
.textAlign(TextAlign.Start)
.align(Alignment.TopStart)
.fontWeight(FontWeight.Normal)
.width(AppConstants.PERCENTAGE_MAX)
.layoutWeight(1)
.margin({ top: $r('app.float.default_10'),bottom: $r('app.float.default_10') })
Text(this.param!.sendingTime)
.fontColor($r('app.color.colorGrey8'))
.fontSize($r('app.float.text_size_14'))
.textAlign(TextAlign.End)
.width(AppConstants.PERCENTAGE_MAX)
}
.width(AppConstants.PERCENTAGE_MAX)
.height(AppConstants.PERCENTAGE_MAX)
.backgroundColor($r('app.color.white'))
.padding($r('app.float.default_10'))
.border(cardRoundBorderStyle)
}
.width(AppConstants.PERCENTAGE_MAX)
.layoutWeight(1)
.padding($r('app.float.default_15'))
}
.width(AppConstants.PERCENTAGE_MAX)
.height(AppConstants.PERCENTAGE_MAX)
.backgroundColor($r('app.color.page_background'))
.overlay(createWaterMark())
}
}

View File

@ -0,0 +1,274 @@
import { LitheRefresh, RefreshController } from '@abner/lithe_refresh';
import { HMRouter, HMRouterMgr } from '@hadss/hmrouter';
import { AxiosError } from '@ohos/axios';
import { ToastUtil } from '@pura/harmony-utils';
import { plainToInstance } from 'class-transformer';
import AppConstants from '../../app/AppConstant';
import { FeedBackBean } from '../../model/requestModel/MessageRequestModel';
import { getMyFeedBackList } from '../../request/Api';
import { cardRoundBorderStyle } from '../../style/BorderStyle';
import { StringUtils } from '../../util/StringUtils';
import { ToastUtils } from '../../util/ToasUtils';
import { BaseTopBar } from '../custom/BaseTopTar';
import { EmptyOrErrorItemView } from '../custom/EmptyOrErrorItemView';
import { createWaterMark } from '../custom/Watermark';
@Component
@Preview
@HMRouter({ pageUrl: 'MyFeedBackPage' })
export struct MyFeedBackPage {
@State feedBackList: Array<FeedBackBean> = new Array<FeedBackBean>();
controller: RefreshController = new RefreshController()
scroller: Scroller = new Scroller()
total: number = 0;
pageNum: number = 1;
isRefreshStatus: number = 0;
aboutToAppear(): void {
setTimeout(() => {
this.controller.isAutoRefresh = true
}, 800)
}
getData() {
getMyFeedBackList(this.pageNum)
.then((res) => {
console.debug('get My Feedback', JSON.stringify(res))
if (res.code == 20041) {
let data = res.data;
if (data) {
this.total = data.counts;
let items = data.items;
if (items) {
if (this.isRefreshStatus == 1) {
this.feedBackList = items
this.controller.finishRefresh()
this.isRefreshStatus = 0
}
if (this.isRefreshStatus == 2) {
this.controller.finishLoadMore()
this.isRefreshStatus = 0
items.forEach(item => {
let bean = plainToInstance(FeedBackBean,item)
this.feedBackList.push(bean)
})
}
if (this.pageNum * 20>=this.total) {
this.controller.closeLoadMore = true;
}
} else {
this.handErrorOrEmPty(0, "暂无反馈记录")
}
} else {
this.handErrorOrEmPty(0, "暂无反馈记录")
}
} else {
this.handErrorOrEmPty(-1, StringUtils.get(res.msg, ""))
}
})
.catch((err: AxiosError) => {
console.error('get My Feedback', JSON.stringify(err))
this.handErrorOrEmPty(-1, err.message)
})
}
/**
* 错误或空处理
*/
handErrorOrEmPty(type: number, msg: string) {
ToastUtils.toastBottom(msg)
if (this.isRefreshStatus == 1) {
this.controller.finishRefresh()
this.isRefreshStatus = 0
let bean = new FeedBackBean()
bean.baseType = type;
bean.content = msg;
this.feedBackList = new Array<FeedBackBean>();
this.feedBackList.push(bean)
}
if (this.isRefreshStatus == 2) {
this.controller.finishLoadMore()
this.isRefreshStatus = 0
}
}
build() {
Column() {
BaseTopBar({
title: $r('app.string.title_my_feedback'),
})
LitheRefresh({
scroller: this.scroller,
controller: this.controller,
itemLayout: () => {
this.listView()
},
onRefresh: () => {
this.controller.closeLoadMore = false;
this.pageNum = 1;
this.isRefreshStatus = 1;
this.getData()
},
onLoadMore: () => {
if (this.pageNum * 20 >= this.total) {
this.controller.finishLoadMore()
this.controller.closeLoadMore = true;
ToastUtil.showToast("没有更多数据!")
return
}
this.pageNum++;
this.isRefreshStatus = 2;
this.getData()
}
})
.width(AppConstants.PERCENTAGE_MAX)
.layoutWeight(1)
}
.width(AppConstants.PERCENTAGE_MAX)
.height(AppConstants.PERCENTAGE_MAX)
.overlay(createWaterMark())
.backgroundColor($r('app.color.page_background'))
}
@Builder
listView() {
List({ scroller: this.scroller, space: 10 }) {
ForEach(this.feedBackList, (item: FeedBackBean) => {
if (item.baseType == 0 || item.baseType == -1) {
ListItem() {
EmptyOrErrorItemView({ type: item.baseType, msg: item.content })
}
} else {
ListItem() {
this.itemUI(item)
}
.onClick(()=>{
HMRouterMgr.push({ navigationId: 'startNavigation', pageUrl: "FeedBackDetailsPage",param:item })
})
}
})
}
.listDirection(Axis.Vertical)
.scrollBar(BarState.Off)
.edgeEffect(EdgeEffect.None)
.width(AppConstants.PERCENTAGE_MAX)
.layoutWeight(1)
.nestedScroll({
scrollForward: NestedScrollMode.PARENT_FIRST,
scrollBackward: NestedScrollMode.PARENT_FIRST
})
}
@Builder
itemUI(item: FeedBackBean) {
Column() {
Column() {
Text(item.title)
.fontColor($r('app.color.colorGrey8'))
.fontSize($r('app.float.text_size_16'))
.fontWeight(FontWeight.Bold)
.width(AppConstants.PERCENTAGE_MAX)
.textAlign(TextAlign.Start)
.maxLines(1)
.height($r('app.float.default_40'))
.ellipsisMode(EllipsisMode.END)
Row() {
Text(this.getTypeStr(item.type))
.fontColor($r('app.color.colorYellow7'))
.fontSize($r('app.float.text_size_10'))
.padding({
left: $r('app.float.default_5'),
right: $r('app.float.default_5'),
top: $r('app.float.default_2'),
bottom: $r('app.float.default_2')
})
.border({
width: $r('app.float.default_1'),
color: $r('app.color.colorYellow7'),
radius: $r('app.float.default_8')
})
Text(item.applicationName)
.fontColor($r('app.color.colorBluen7'))
.fontSize($r('app.float.text_size_10'))
.padding({
left: $r('app.float.default_5'),
right: $r('app.float.default_5'),
top: $r('app.float.default_2'),
bottom: $r('app.float.default_2')
})
.border({
width: $r('app.float.default_1'),
color: $r('app.color.colorBluen7'),
radius: $r('app.float.default_8')
})
.margin({ left: $r('app.float.default_8') })
.visibility(StringUtils.isNullOrEmpty(item.applicationName) ? Visibility.None : Visibility.Visible)
Text(this.getReplyStatusStr(item.replyStatus))
.fontColor(item.replyStatus == 0 ? $r('app.color.colorGrey6') : $r('app.color.colorGreen6'))
.fontSize($r('app.float.text_size_10'))
.padding({
left: $r('app.float.default_5'),
right: $r('app.float.default_5'),
top: $r('app.float.default_2'),
bottom: $r('app.float.default_2')
})
.border({
width: $r('app.float.default_1'),
color: item.replyStatus == 0 ? $r('app.color.colorGrey6') : $r('app.color.colorGreen6'),
radius: $r('app.float.default_8')
})
.margin({ left: $r('app.float.default_8') })
}
.alignItems(VerticalAlign.Center)
.justifyContent(FlexAlign.Start)
.margin({ top: $r('app.float.default_5') })
Text(item.content)
.fontColor($r('app.color.colorGrey6'))
.fontSize($r('app.float.text_size_14'))
.fontWeight(FontWeight.Bold)
.width(AppConstants.PERCENTAGE_MAX)
.textAlign(TextAlign.Start)
.maxLines(1)
.height($r('app.float.default_40'))
.ellipsisMode(EllipsisMode.END)
}
.padding($r('app.float.default_10'))
.width(AppConstants.PERCENTAGE_MAX)
.height("auto")
.alignItems(HorizontalAlign.Start)
.backgroundColor($r('app.color.white'))
.border(cardRoundBorderStyle)
}
.padding({ left: $r('app.float.default_10'), right: $r('app.float.default_10'), top: $r('app.float.default_10') })
.width(AppConstants.PERCENTAGE_MAX)
.height("auto")
.alignItems(HorizontalAlign.Start)
}
getTypeStr(type: number): string {
switch (type) {
case 1:
return "个人建议";
case 2:
return "软件问题";
case 3:
return "硬件问题";
case 4:
default:
return "其它";
}
}
getReplyStatusStr(replyStatus: number): string {
return replyStatus == 0 ? "未回复" : "已回复";
}
}

View File

@ -0,0 +1,439 @@
import { HMRouter } from "@hadss/hmrouter";
import { AxiosError, AxiosResponse } from "@ohos/axios";
import { DialogHelper } from "@pura/harmony-dialog";
import { FileUtil, ImageUtil, JSONUtil } from "@pura/harmony-utils";
import { ToastUtil } from "@pura/harmony-utils/src/main/ets/action/ToastUtil";
import AppConstants from "../../app/AppConstant";
import { RuanseeAbilityStag } from "../../app/RuanseeAbilityStag";
import { downLoadUserPhoto, updateWorkPhone, uploadUserPhoto } from "../../request/Api";
import { FileUtils } from "../../util/FileUtils";
import { StringUtils } from "../../util/StringUtils";
import { BaseTopBar } from "../custom/BaseTopTar";
import { createWaterMark } from "../custom/Watermark";
import { fileIo, fileUri, picker } from "@kit.CoreFileKit";
import { camera, cameraPicker } from "@kit.CameraKit";
import { photoAccessHelper } from "@kit.MediaLibraryKit";
import { DateUtil } from "@pura/harmony-utils/src/main/ets/utils/DateUtil";
import { StrUtil } from "@pura/harmony-utils/src/main/ets/utils/StrUtil";
import { common } from "@kit.AbilityKit";
import { preferences } from "@kit.ArkData";
@Component
@HMRouter({ pageUrl: "MyUserInfoPage" })
export struct MyUserInfoPage {
@State userPhoto: string | Resource = $r('app.media.icon_police_woman')
@State workPhone: string = RuanseeAbilityStag.userCache.getWorkPhone
dialogId: string = ''
aboutToAppear(): void {
this.getImage()
}
getImage() {
if (FileUtil.accessSync(FileUtils.IMAGE_DIR + '/' + RuanseeAbilityStag.userCache.getProfilePhoto)) {
this.userPhoto = fileUri.getUriFromPath(FileUtils.IMAGE_DIR + '/' + RuanseeAbilityStag.userCache.getProfilePhoto)
return
}
downLoadUserPhoto(FileUtils.IMAGE_DIR + '/' + RuanseeAbilityStag.userCache.getProfilePhoto)
.then((res: AxiosResponse) => {
console.info("result:" + JSON.stringify(res.data));
if (res.status == 200) {
this.userPhoto =
fileUri.getUriFromPath(FileUtils.IMAGE_DIR + '/' + RuanseeAbilityStag.userCache.getProfilePhoto)
}
})
.catch((error: AxiosError) => {
console.error("error:" + JSON.stringify(error));
})
}
showUpdatePhone() {
DialogHelper.showTextInputDialog({
title: "修改工作号码",
fontColor: $r('app.color.colorGrey8'),
fontSize: $r('app.float.text_size_16'),
inputHeight: $r('app.float.default_40'),
maxLength: 11,
defaultFocus: true,
inputBorder: {
width: $r('app.float.default_1'),
color: $r('app.color.colorGrey2'),
radius: $r('app.float.default_5'),
},
text: this.workPhone,
placeholder: '请输入手机号码',
placeholderColor: $r('app.color.colorGrey6'),
onAction: (action: number, dialogId: string, value: string) => {
DialogHelper.closeDialog(dialogId)
if (action == -1) {
}
if (action == -2) {
this.updatePhone(value);
}
}
})
}
updatePhone(value: string) {
if (StringUtils.isNullOrEmpty(value)) {
ToastUtil.showToast("请输入手机号码!")
return
}
if (this.workPhone == value) {
ToastUtil.showToast("请修改手机号码!")
return
}
updateWorkPhone(value)
.then((res) => {
console.debug("updatePhone", JSON.stringify(res))
ToastUtil.showToast(res.msg)
if (res.code == 200) {
this.workPhone = value
RuanseeAbilityStag.userCache.setWorkPhone = value
let context = getContext(this) as common.UIAbilityContext;
let pref = preferences.getPreferencesSync(context, { name: 'AppStore' });
pref.put('updateUserInfo',false)
}
})
.catch((err: AxiosError) => {
console.error("updatePhone", JSON.stringify(err))
ToastUtil.showToast("修改失败")
})
}
async selectImage() {
let photoSelectOptions = new photoAccessHelper.PhotoSelectOptions();
let photoPicker = new photoAccessHelper.PhotoViewPicker();
// 过滤选择媒体文件类型为IMAGE
photoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_VIDEO_TYPE;
// 设置最大选择数量
photoSelectOptions.maxSelectNumber = 1;
let chooseFile: picker.PhotoSelectResult = await photoPicker.select(photoSelectOptions);
let newFilePath = FileUtils.IMAGE_DIR + '/' + DateUtil.getTodayTime() + ".jpg";
let newFileUri = fileUri.getUriFromPath(newFilePath)
let isCopy = await FileUtils.copyToLocal(chooseFile.photoUris[0], newFileUri)
if (isCopy) {
newFileUri = await ImageUtil.compressPhoto(newFileUri, 260);
this.updatePhoto(newFileUri)
} else {
ToastUtil.showToast("复制文件失败!")
}
}
/**
* 拍照
*/
async takePhoto() {
let pathDir = FileUtils.IMAGE_DIR;
let fileName = `${new Date().getTime()}.JPEG`
let filePath = `${pathDir}/${fileName}`
let imageFileUri: string | undefined = undefined;
fileIo.createRandomAccessFileSync(filePath, fileIo.OpenMode.CREATE);
let fileUris = fileUri.getUriFromPath(filePath);
let pickerProfile: cameraPicker.PickerProfile = {
cameraPosition: camera.CameraPosition.CAMERA_POSITION_BACK,
saveUri: fileUris,
};
let result: cameraPicker.PickerResult =
await cameraPicker.pick(getContext(), [cameraPicker.PickerMediaType.PHOTO],
pickerProfile);
console.info(`picker resultCode: ${result.resultCode},resultUri: ${result.resultUri},mediaType: ${result.mediaType}`);
if (result.resultCode == 0) {
if (result.mediaType === cameraPicker.PickerMediaType.PHOTO) {
imageFileUri = result.resultUri
imageFileUri = await ImageUtil.compressPhoto(imageFileUri, 150);
this.updatePhoto(imageFileUri);
}
} else {
ToastUtil.showToast("取消选择")
}
}
/**
* 更新图片
* @param imageFileUri
*/
updatePhoto(imageFileUri: string) {
//自定义文字内容
this.dialogId = DialogHelper.showLoadingDialog({
loadColor: Color.White,
content: "正在上传,请稍后...",
fontSize: 15,
backgroundColor: '#ED000000',
autoCancel: true,
onWillDismiss: () => {
DialogHelper.closeDialog(this.dialogId)
this.dialogId = ''
}
})
//常见问题
uploadUserPhoto(imageFileUri)
.then((res) => {
DialogHelper.closeDialog(this.dialogId)
console.debug("updatePhoto", JSON.stringify(res))
if (res.code == 200) {
this.userPhoto = imageFileUri
let data = res.data;
if(data){
let id :string= data['id']
if(StrUtil.isNotEmpty(id)){
FileUtil.renameSync(FileUtil.getFilePath(imageFileUri),FileUtils.IMAGE_DIR+"/"+id);
RuanseeAbilityStag.userCache.setProfilePhoto = id
this.userPhoto = fileUri.getUriFromPath(FileUtils.IMAGE_DIR+"/"+id);
let context = getContext(this) as common.UIAbilityContext;
context.eventHub.emit('updateUserPhoto')
let pref = preferences.getPreferencesSync(context, { name: 'AppStore' });
pref.put('updateUserInfo',false)
}
}
}
})
.catch((err: AxiosError) => {
DialogHelper.closeDialog(this.dialogId)
console.error("updatePhoto", JSON.stringify(err))
})
}
showUpdatePhoto() {
//带标题
DialogHelper.showActionSheetDialog({
title: "选择头像",
titleFontColor: Color.Black,
cancelFontColor: Color.Red,
cancelFontWeight: FontWeight.Normal,
sheets: ['相机', '相册'],
onAction: (index) => {
switch (index) {
case 0:
this.takePhoto()
break;
case 1:
this.selectImage()
break;
}
}
})
}
build() {
Column() {
BaseTopBar({
title: $r('app.string.title_user_info'),
})
Row() {
Text("头像")
.fontColor($r('app.color.colorGrey8'))
.fontSize($r('app.float.text_size_16'))
Blank()
.layoutWeight(1)
Image(this.userPhoto)
.width($r('app.float.default_68'))
.height($r('app.float.default_52'))
.onClick(() => {
this.showUpdatePhoto()
})
Image($r('app.media.arrow_right'))
.width($r('app.float.default_22'))
.height($r('app.float.default_22'))
.margin({ left: $r('app.float.default_10') })
}
.padding($r('app.float.default_10'))
.width(AppConstants.PERCENTAGE_MAX)
.height('auto')
.alignItems(VerticalAlign.Center)
.backgroundColor($r('app.color.white'))
Divider()
.width(AppConstants.PERCENTAGE_MAX)
.height($r('app.float.default_1'))
.backgroundColor($r('app.color.colorGrey2'))
Row() {
Text("姓名")
.fontColor($r('app.color.colorGrey8'))
.fontSize($r('app.float.text_size_16'))
Blank()
.layoutWeight(1)
Text(RuanseeAbilityStag.userCache.getUserName)
.fontColor($r('app.color.colorGrey8'))
.fontSize($r('app.float.text_size_16'))
Image($r('app.media.arrow_right'))
.width($r('app.float.default_22'))
.height($r('app.float.default_22'))
.visibility(Visibility.Hidden)
.margin({ left: $r('app.float.default_10') })
}
.width(AppConstants.PERCENTAGE_MAX)
.alignItems(VerticalAlign.Center)
.backgroundColor($r('app.color.white'))
.padding($r('app.float.default_10'))
Divider()
.width(AppConstants.PERCENTAGE_MAX)
.height($r('app.float.default_1'))
.backgroundColor($r('app.color.colorGrey2'))
Row() {
Text("警号")
.fontColor($r('app.color.colorGrey8'))
.fontSize($r('app.float.text_size_16'))
Blank()
.layoutWeight(1)
Text(RuanseeAbilityStag.userCache.getUserCode)
.fontColor($r('app.color.colorGrey8'))
.fontSize($r('app.float.text_size_16'))
Image($r('app.media.arrow_right'))
.width($r('app.float.default_22'))
.height($r('app.float.default_22'))
.visibility(Visibility.Hidden)
.margin({ left: $r('app.float.default_10') })
}
.width(AppConstants.PERCENTAGE_MAX)
.alignItems(VerticalAlign.Center)
.backgroundColor($r('app.color.white'))
.padding($r('app.float.default_10'))
Blank()
.width(AppConstants.PERCENTAGE_MAX)
.height($r('app.float.default_10'))
Row() {
Text("职位")
.fontColor($r('app.color.colorGrey8'))
.fontSize($r('app.float.text_size_16'))
Blank()
.layoutWeight(1)
Text(StringUtils.get(RuanseeAbilityStag.userCache.getPoliceTypeName, "暂无"))
.fontColor($r('app.color.colorGrey8'))
.fontSize($r('app.float.text_size_16'))
Image($r('app.media.arrow_right'))
.width($r('app.float.default_22'))
.height($r('app.float.default_22'))
.visibility(Visibility.Hidden)
.margin({ left: $r('app.float.default_10') })
}
.width(AppConstants.PERCENTAGE_MAX)
.alignItems(VerticalAlign.Center)
.backgroundColor($r('app.color.white'))
.padding($r('app.float.default_10'))
Divider()
.width(AppConstants.PERCENTAGE_MAX)
.height($r('app.float.default_1'))
.backgroundColor($r('app.color.colorGrey2'))
Row() {
Text("单位")
.fontColor($r('app.color.colorGrey8'))
.fontSize($r('app.float.text_size_16'))
Blank()
.layoutWeight(1)
Text(RuanseeAbilityStag.userCache.getDeptName)
.fontColor($r('app.color.colorGrey8'))
.fontSize($r('app.float.text_size_16'))
Image($r('app.media.arrow_right'))
.width($r('app.float.default_22'))
.height($r('app.float.default_22'))
.visibility(Visibility.Hidden)
.margin({ left: $r('app.float.default_10') })
}
.width(AppConstants.PERCENTAGE_MAX)
.alignItems(VerticalAlign.Center)
.backgroundColor($r('app.color.white'))
.padding($r('app.float.default_10'))
Blank()
.width(AppConstants.PERCENTAGE_MAX)
.height($r('app.float.default_10'))
Row() {
Text("证件号码")
.fontColor($r('app.color.colorGrey8'))
.fontSize($r('app.float.text_size_16'))
Blank()
.layoutWeight(1)
Text(RuanseeAbilityStag.userCache.getIdCardNum)
.fontColor($r('app.color.colorGrey8'))
.fontSize($r('app.float.text_size_16'))
Image($r('app.media.arrow_right'))
.width($r('app.float.default_22'))
.height($r('app.float.default_22'))
.visibility(Visibility.Hidden)
.margin({ left: $r('app.float.default_10') })
}
.width(AppConstants.PERCENTAGE_MAX)
.alignItems(VerticalAlign.Center)
.backgroundColor($r('app.color.white'))
.padding($r('app.float.default_10'))
Divider()
.width(AppConstants.PERCENTAGE_MAX)
.height($r('app.float.default_1'))
.backgroundColor($r('app.color.colorGrey2'))
Row() {
Text("工作号码")
.fontColor($r('app.color.colorGrey8'))
.fontSize($r('app.float.text_size_16'))
Blank()
.layoutWeight(1)
Text(this.workPhone)
.fontColor($r('app.color.colorGrey8'))
.fontSize($r('app.float.text_size_16'))
Image($r('app.media.arrow_right'))
.width($r('app.float.default_22'))
.height($r('app.float.default_22'))
.margin({ left: $r('app.float.default_10') })
}
.width(AppConstants.PERCENTAGE_MAX)
.alignItems(VerticalAlign.Center)
.backgroundColor($r('app.color.white'))
.padding($r('app.float.default_10'))
.onClick(() => {
this.showUpdatePhone();
})
}
.width(AppConstants.PERCENTAGE_MAX)
.height(AppConstants.PERCENTAGE_MAX)
.overlay(createWaterMark())
.backgroundColor($r('app.color.page_background'))
}
}

View File

@ -0,0 +1,380 @@
import { HMRouter, HMRouterMgr } from "@hadss/hmrouter";
import { ToastUtil } from "@pura/harmony-utils/src/main/ets/action/ToastUtil";
import AppConstants from "../../app/AppConstant";
import { AppDataModel } from "../../model/resultModel/ApplicationResultModel";
import { BasePageResult } from "../../model/uiModel/PageResultModel";
import { addFeedBack } from "../../request/Api";
import { cardRoundBorderGreyStyle, cardRoundBorderStyle } from "../../style/BorderStyle";
import { StringUtils } from "../../util/StringUtils";
import { BaseTopBar } from "../custom/BaseTopTar";
import { createWaterMark } from "../custom/Watermark";
import { router } from "@kit.ArkUI";
/**
* 意见建议页面
*/
@Component
@Preview
@HMRouter({ pageUrl: 'OpinionsSuggestionsPages' })
export struct OpinionsSuggestionsPages {
@State selectType: number = 1;
@State inputTitle: string = "";
@State inputContent: string = "";
@State appName: string = "";
appId: string = "";
textInputController: TextInputController = new TextInputController()
textAreaController: TextInputController = new TextInputController()
aboutToAppear(): void {
}
submit() {
if (this.selectType == 2 && StringUtils.isNullOrEmpty(this.appName)) {
ToastUtil.showToast("请选择应用!")
return
}
if (StringUtils.isNullOrEmpty(this.inputTitle)) {
ToastUtil.showToast("请输入标题!")
return
}
if (StringUtils.isNullOrEmpty(this.inputContent)) {
ToastUtil.showToast("请输入内容!")
return
}
addFeedBack(this.appId, this.appName, this.selectType, this.inputTitle, this.inputContent)
.then((res) => {
console.debug("submit feedBack", JSON.stringify(res))
ToastUtil.showToast(res.msg)
if (res.code == 20011) {
setTimeout(() => {
HMRouterMgr.pop()
}, 800)
}
})
.catch((err: Error) => {
console.error("submit feedBack", JSON.stringify(err))
ToastUtil.showToast(err.message)
})
}
build() {
Column() {
BaseTopBar({
title: $r('app.string.title_Feedback'),
rightText: "我的反馈",
rightClickEvent: () => {
HMRouterMgr.push({ navigationId: 'startNavigation', pageUrl: "MyFeedBackPage" })
}
})
Scroll() {
Column() {
//上部分
this.topModel()
this.bottomModel()
}
.padding({
left: $r('app.float.default_15'),
right: $r('app.float.default_15')
})
.width(AppConstants.PERCENTAGE_MAX)
.height(AppConstants.PERCENTAGE_MAX)
}
.width(AppConstants.PERCENTAGE_MAX)
.layoutWeight(1)
Column() {
Button("提交反馈", { type: ButtonType.Normal })
.borderRadius(8)
.width(AppConstants.PERCENTAGE_MAX)
.height($r('app.float.default_40'))
.fontColor($r('app.color.white'))
.fontSize($r('app.float.text_size_14'))
.backgroundColor($r('app.color.bull'))
.onClick(() => {
this.submit()
})
}
.padding({
left: $r('app.float.default_15'),
right: $r('app.float.default_15')
, bottom: $r('app.float.default_28')
})
.width(AppConstants.PERCENTAGE_MAX)
.height('auto')
}
.width(AppConstants.PERCENTAGE_MAX)
.height(AppConstants.PERCENTAGE_MAX)
.backgroundColor($r('app.color.page_background'))
.overlay(createWaterMark())
// .onVisibleAreaChange([0.5, 1], (isVisible) => {
// if (isVisible) {
// let param = HMRouterMgr.getCurrentParam() as BasePageResult;
// if (param) {
// let data = param.data as AppDataModel;
// if (data) {
// this.appName = data.name
// this.appId = data.id
// }
// router.getParams()
// }
// }
// })
}
@Builder
bottomModel() {
//上部分
Column() {
Row() {
Text("*")
.fontColor($r('app.color.colorRed9'))
.margin({ top: $r('app.float.default_5') })
.fontSize($r('app.float.text_size_16'));
Text("反馈标题")
.fontColor($r('app.color.colorGrey8'))
.fontSize($r('app.float.text_size_16'))
.margin({ top: $r('app.float.default_5') });
}
.justifyContent(FlexAlign.Start)
.alignItems(VerticalAlign.Center)
.width(AppConstants.PERCENTAGE_MAX);
TextInput({ text: this.inputTitle, placeholder: '请输入标题', controller: this.textInputController })
.placeholderColor(Color.Grey)
.placeholderFont({ size: 14, weight: 400 })
.caretColor(Color.Blue)
.width(AppConstants.PERCENTAGE_MAX)
.height($r('app.float.default_46'))
.margin({ top: $r('app.float.default_10') })
.fontSize(14)
.fontColor($r('app.color.colorGrey8'))
.backgroundColor($r('app.color.colorGrey1'))
.border(cardRoundBorderStyle)
.padding({ left: $r('app.float.default_10'), right: $r('app.float.default_10') })
.onChange((value: string) => {
this.inputTitle = value
})
Divider()
.width(AppConstants.PERCENTAGE_MAX)
.height($r('app.float.default_1'))
.color($r('app.color.colorGrey3'))
.margin({ top: $r('app.float.default_10') });
Row() {
Text("*")
.fontColor($r('app.color.colorRed9'))
.margin({ top: $r('app.float.default_5') })
.fontSize($r('app.float.text_size_16'));
Text("反馈内容")
.fontColor($r('app.color.colorGrey8'))
.fontSize($r('app.float.text_size_16'))
.margin({ top: $r('app.float.default_5') });
}
.justifyContent(FlexAlign.Start)
.alignItems(VerticalAlign.Center)
.width(AppConstants.PERCENTAGE_MAX)
.margin({ top: $r('app.float.default_10') });
TextArea({
text: this.inputContent,
placeholder: '请输入反馈内容(500字以内)',
controller: this.textAreaController
})
.placeholderColor(Color.Grey)
.placeholderFont({ size: 14, weight: 400 })
.caretColor(Color.Blue)
.width(AppConstants.PERCENTAGE_MAX)
.height($r('app.float.default_180'))
.margin({ top: $r('app.float.default_10') })
.fontSize(14)
.fontColor($r('app.color.colorGrey8'))
.backgroundColor($r('app.color.colorGrey1'))
.border(cardRoundBorderStyle)
.padding({ left: $r('app.float.default_10'), right: $r('app.float.default_10') })
.onChange((value: string) => {
this.inputContent = value
})
}
.padding($r('app.float.default_10'))
.alignItems(HorizontalAlign.Start)
.width(AppConstants.PERCENTAGE_MAX)
.margin({ top: $r('app.float.default_10') })
.backgroundColor($r('app.color.white'))
.border(cardRoundBorderStyle)
}
@Builder
topModel() {
//上部分
Column() {
Text("反馈类型")
.fontColor($r('app.color.colorGrey8'))
.fontSize($r('app.float.text_size_16'));
//类型选项
Row() {
Text("个人建议")
.fontColor(this.selectType == 1 ? $r('app.color.white') : $r('app.color.colorGrey7'))
.fontSize($r('app.float.text_size_14'))
.padding({
left: $r('app.float.default_10'),
right: $r('app.float.default_10'),
top: $r('app.float.default_8'),
bottom: $r('app.float.default_8')
})
.backgroundColor(this.selectType == 1 ? $r('app.color.bull') : $r('app.color.white'))
.border(cardRoundBorderGreyStyle)
.onClick(() => {
if (this.selectType == 1) {
return;
}
this.selectType = 1;
});
Blank()
.layoutWeight(1);
Text("软件问题")
.fontColor(this.selectType == 2 ? $r('app.color.white') : $r('app.color.colorGrey7'))
.fontSize($r('app.float.text_size_14'))
.padding({
left: $r('app.float.default_10'),
right: $r('app.float.default_10'),
top: $r('app.float.default_8'),
bottom: $r('app.float.default_8')
})
.backgroundColor(this.selectType == 2 ? $r('app.color.bull') : $r('app.color.white'))
.border(cardRoundBorderGreyStyle)
.onClick(() => {
if (this.selectType == 2) {
return;
}
this.selectType = 2;
});
Blank()
.layoutWeight(1);
Text("硬件问题")
.fontColor(this.selectType == 3 ? $r('app.color.white') : $r('app.color.colorGrey7'))
.fontSize($r('app.float.text_size_14'))
.padding({
left: $r('app.float.default_10'),
right: $r('app.float.default_10'),
top: $r('app.float.default_8'),
bottom: $r('app.float.default_8')
})
.backgroundColor(this.selectType == 3 ? $r('app.color.bull') : $r('app.color.white'))
.border(cardRoundBorderGreyStyle)
.onClick(() => {
if (this.selectType == 3) {
return;
}
this.selectType = 3;
});
Blank()
.layoutWeight(1);
Text("其他")
.fontColor(this.selectType == 4 ? $r('app.color.white') : $r('app.color.colorGrey7'))
.fontSize($r('app.float.text_size_14'))
.padding({
left: $r('app.float.default_10'),
right: $r('app.float.default_10'),
top: $r('app.float.default_8'),
bottom: $r('app.float.default_8')
})
.backgroundColor(this.selectType == 4 ? $r('app.color.bull') : $r('app.color.white'))
.border(cardRoundBorderGreyStyle)
.onClick(() => {
if (this.selectType == 4) {
return;
}
this.selectType = 4;
});
}
.margin({ top: $r('app.float.default_10') })
.width(AppConstants.PERCENTAGE_MAX);
Divider()
.width(AppConstants.PERCENTAGE_MAX)
.height($r('app.float.default_1'))
.color($r('app.color.colorGrey3'))
.margin({ top: $r('app.float.default_10') });
Row() {
Text("*")
.fontColor($r('app.color.colorRed9'))
.fontSize($r('app.float.text_size_16'))
.margin({ top: $r('app.float.default_5') })
.visibility(this.selectType == 2 ? Visibility.Visible : Visibility.Hidden);
Text("反馈应用")
.fontColor($r('app.color.colorGrey8'))
.fontSize($r('app.float.text_size_16'))
.margin({ top: $r('app.float.default_5') });
}
.justifyContent(FlexAlign.Start)
.alignItems(VerticalAlign.Center)
.margin({ top: $r('app.float.default_10') })
.width(AppConstants.PERCENTAGE_MAX);
Row() {
Text(StringUtils.get(this.appName, "请选择"))
.fontColor(StringUtils.isNullOrEmpty(this.appName) ? $r('app.color.colorGrey6') : $r('app.color.colorGrey8'))
.fontSize($r('app.float.text_size_16'))
.layoutWeight(1)
.maxLines(1)
.ellipsisMode(EllipsisMode.END)
.textAlign(TextAlign.Start);
Image($r('app.media.arrow_right'))
.width($r('app.float.default_20'))
.height($r('app.float.default_20'));
}
.padding({ left: $r('app.float.default_5'), right: $r('app.float.default_5') })
.justifyContent(FlexAlign.Start)
.alignItems(VerticalAlign.Center)
.height($r('app.float.default_46'))
.margin({ top: $r('app.float.default_10') })
.width(AppConstants.PERCENTAGE_MAX)
.backgroundColor($r('app.color.colorGrey1'))
.border(cardRoundBorderStyle)
.onClick(() => {
HMRouterMgr.push({ navigationId: 'startNavigation', pageUrl: "SelectAppListPage" }, {
onResult: (result) => {
let param = result.result as BasePageResult
if (param) {
let data = param.data as AppDataModel
if (data) {
this.appName = data.name
this.appId = data.id
}
}
}
})
});
}
.padding($r('app.float.default_10'))
.alignItems(HorizontalAlign.Start)
.width(AppConstants.PERCENTAGE_MAX)
.margin({ top: $r('app.float.default_10') })
.backgroundColor($r('app.color.white'))
.border(cardRoundBorderStyle)
}
}

View File

@ -0,0 +1,242 @@
import { AxiosError } from "@ohos/axios";
import { ToastUtil } from "@pura/harmony-utils";
import AppConstants from "../../app/AppConstant";
import { cardRoundBorderGreyStyle } from "../../style/BorderStyle";
import { StringUtils } from "../../util/StringUtils";
import { ToastUtils } from "../../util/ToasUtils";
import { BaseTopBar } from "../custom/BaseTopTar";
import { HMRouter, HMRouterMgr } from "@hadss/hmrouter";
import { createWaterMark } from "../custom/Watermark";
import { AppDataModel } from "../../model/resultModel/ApplicationResultModel";
import { getAppList } from "../../request/Api";
import { LitheRefresh, RefreshController } from "@abner/lithe_refresh";
import { EmptyOrErrorItemView } from "../custom/EmptyOrErrorItemView";
import { SelectAppItem } from "../view/SelectAppItem";
import { BasePageResult } from "../../model/uiModel/PageResultModel";
import { plainToInstance } from "class-transformer";
/**
* 选择任务
*/
@Preview
@Component
@HMRouter({ pageUrl: 'SelectAppListPage' })
export struct SelectAppListPage {
@State inputContent: string | undefined = undefined
@State selectValue: Array<AppDataModel> = new Array<AppDataModel>();
private selectItem: AppDataModel | undefined;
controller: RefreshController = new RefreshController()
scroller: Scroller = new Scroller()
total: number = 0;
pageNum: number = 1;
isRefreshStatus: number = 0;
aboutToAppear(): void {
setTimeout(() => {
this.controller.isAutoRefresh = true
}, 800)
}
getAppListData() {
getAppList(StringUtils.get(this.inputContent, ""), this.pageNum)
.then((res) => {
console.debug(JSON.stringify(res))
if (res.code != 20041) {
this.handErrorOrEmPty(-1, StringUtils.get(res.msg, ""))
return
}
let data = res.data;
if (!data) {
this.handErrorOrEmPty(0, StringUtils.get(res.msg, "暂无应用"))
return
}
this.total = data.counts;
let dataList = data.items;
if (!dataList || dataList.length < 1) {
this.handErrorOrEmPty(0, StringUtils.get(res.msg, "暂无应用"))
return
}
if (this.isRefreshStatus == 1) {
this.controller.finishRefresh()
this.isRefreshStatus = 0
this.selectValue = new Array<AppDataModel>();
dataList.forEach(item => {
this.selectValue.push(plainToInstance(AppDataModel, item));
})
}
if (this.isRefreshStatus == 2) {
this.controller.finishLoadMore()
this.isRefreshStatus = 0
dataList.forEach(item => {
this.selectValue.push(item);
})
}
if (this.pageNum * 20 >= this.total) {
this.controller.closeLoadMore = true
}
})
.catch((e: AxiosError) => {
this.handErrorOrEmPty(-1, `查询任务失败:${e.message}`)
})
}
/**
* 错误或空处理
*/
handErrorOrEmPty(type: number, msg: string) {
ToastUtils.toastBottom(msg)
if (this.isRefreshStatus == 1) {
this.controller.finishRefresh()
this.isRefreshStatus = 0
let bean = new AppDataModel()
bean.baseType = type;
bean.remark = msg;
this.selectValue = new Array<AppDataModel>();
this.selectValue.push(bean)
}
if (this.isRefreshStatus == 2) {
this.controller.finishLoadMore()
this.isRefreshStatus = 0
}
}
submit() {
if (!this.selectItem) {
ToastUtil.showLong("请先选择应用")
return
}
let param = new BasePageResult()
param.type = 1;
param.data = this.selectItem
HMRouterMgr.pop({ pageUrl: "OpinionsSuggestionsPages", param: param })
}
build() {
Column() {
BaseTopBar({
title: $r('app.string.title_select_app'),
})
TextInput({ text: this.inputContent, placeholder: "请输入应用名称进行搜索" })
.placeholderColor($r('app.color.colorGrey6'))
.fontSize($r('app.float.text_size_16'))
.fontColor($r('app.color.colorGrey8'))
.margin({
left: $r('app.float.default_10'),
right: $r('app.float.default_10'),
top: $r('app.float.default_10')
})
.padding({
left: $r('app.float.default_5'),
right: $r('app.float.default_5'),
})
.onChange((text: string) => {
this.inputContent = text;
})
.height($r('app.float.default_40'))
.width('96%')
.textAlign(TextAlign.Start)
.border(cardRoundBorderGreyStyle)
.enterKeyType(EnterKeyType.Search)// 设置为搜索按钮
.onSubmit((enterKey: EnterKeyType, event: SubmitEvent) => {
// 点击搜索按钮时触发
this.controller.isAutoRefresh = true;
});
// ListView({
// data: this.selectValue,
// })
LitheRefresh({
scroller: this.scroller,
controller: this.controller,
itemLayout: () => {
this.listView()
},
onRefresh: () => {
this.controller.closeLoadMore = false;
this.pageNum = 1;
this.isRefreshStatus = 1;
this.getAppListData()
},
onLoadMore: () => {
if (this.pageNum * 20 >= this.total) {
this.controller.finishLoadMore()
this.controller.closeLoadMore = true;
ToastUtil.showToast("没有更多数据!")
return
}
this.pageNum++;
this.isRefreshStatus = 2;
this.getAppListData()
}
})
.width(AppConstants.PERCENTAGE_MAX)
.layoutWeight(1)
Button("完成", { type: ButtonType.Normal, stateEffect: true })
.fontSize($r('app.float.text_size_16'))
.fontColor($r('app.color.white'))
.backgroundColor($r('app.color.bull'))
.borderRadius(8)
.margin({
left: $r('app.float.default_10'),
right: $r('app.float.default_10'),
bottom: $r('app.float.default_28'),
})
.onClick(() => {
this.submit();
})
.width('95%');
}
.width(AppConstants.PERCENTAGE_MAX)
.height(AppConstants.PERCENTAGE_MAX)
.backgroundColor($r('app.color.page_background'))
.overlay(createWaterMark())
}
@Builder
listView() {
List({ scroller: this.scroller, space: 10 }) {
ForEach(this.selectValue, (item: AppDataModel) => {
if (item.baseType == 0 || item.baseType == -1) {
ListItem() {
EmptyOrErrorItemView({ type: item.baseType, msg: item.remark })
}
} else {
ListItem() {
SelectAppItem({
item: item,
onSelect: (item: AppDataModel) => {
this.selectItem = item;
this.updateCardDataStatus(item)
}
})
}
}
})
}
.divider({
strokeWidth: $r('app.float.default_1'),
color: $r('app.color.colorGrey2'),
startMargin: $r('app.float.default_63')
})
.listDirection(Axis.Vertical)
.scrollBar(BarState.Off)
.edgeEffect(EdgeEffect.None)
.width(AppConstants.PERCENTAGE_MAX)
.layoutWeight(1)
.nestedScroll({
scrollForward: NestedScrollMode.PARENT_FIRST,
scrollBackward: NestedScrollMode.PARENT_FIRST
})
}
updateCardDataStatus(item: AppDataModel) {
// 遍历所有项只将当前选中的项设为true其他设为false
this.selectValue.forEach(selectedItem => {
selectedItem.isSelect = (item.id === selectedItem.id);
});
}
}

View File

@ -0,0 +1,321 @@
import { HMRouter, HMRouterMgr } from '@hadss/hmrouter';
import { common } from '@kit.AbilityKit';
import { AppCache, AUTH_SYSCODE } from '../../app/AppCache';
import { UserCache } from '../../app/UserCache';
import { StringUtils } from '../../util/StringUtils';
import { UserInfoModel } from '../../model/cacheModel/UserInfoModel';
import { buffer, util } from '@kit.ArkTS';
import { connection } from '@kit.NetworkKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { ToastUtils } from '../../util/ToasUtils';
import { createWaterMark } from '../custom/Watermark';
import { AuthUserModel, IAuthTaskType } from '../../model/uiModel/IAuthTaskType';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { RuanseeAbilityStag } from '../../app/RuanseeAbilityStag';
import { DialogAction, ToastUtil } from '@pura/harmony-utils';
import { AnHuiAddressModel } from '../../model/uiModel/AnHuiAddressModel';
import { DialogHelper } from '@pura/harmony-dialog';
import { preferences } from '@kit.ArkData';
@HMRouter({ pageUrl: 'StartPage' })
@Component
export struct StartPage {
@State message: string = '正在初始化...';
context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
ipAddress: string | undefined = undefined
aboutToAppear() {
this.context.eventHub.on('NotPermissions', (data: string) => {
if (data) {
this.showNotPermissionsDialog()
}
});
this.context.eventHub.on('PermissionsSuccess', (data: string) => {
RuanseeAbilityStag.appCache.setPermissionsStatus = true
this.getIpAddress();
});
}
aboutToDisappear(): void {
this.context.eventHub.off('NotPermissions')
this.context.eventHub.off('PermissionsSuccess')
}
onPageHide(): void {
}
onPageShow(): void {
}
showNotPermissionsDialog() {
let dialogID = DialogHelper.showAlertDialog({
content: "由于您拒绝了应用的权限,应用无法正常运行,请前往设置页面授权!",
onAction: (action) => {
if (action == DialogAction.ONE) {
DialogHelper.closeDialog(dialogID)
HMRouterMgr.pop({ pageUrl: 'StartPage' })
this.context.terminateSelf()
} else if (action == DialogAction.TWO) {
DialogHelper.closeDialog(dialogID)
// 确认操作处理
this.jumpToAppDetails()
HMRouterMgr.pop({ pageUrl: 'StartPage' })
this.context.terminateSelf()
}
}
})
}
jumpToAppDetails() {
const context = getContext() as common.UIAbilityContext;
context.startAbility({
bundleName: 'com.huawei.hmos.settings',
abilityName: 'com.huawei.hmos.settings.MainAbility',
uri: 'application_info_entry', // 固定值表示应用详情页
parameters: {
pushParams: context.abilityInfo.bundleName // 当前应用包名
}
});
}
//TODO 测试登录信息
testLogin(){
let userCache = RuanseeAbilityStag.userCache
userCache.setUserName = "陈乐(测试账号)"
userCache.setUserCode = "999013"
userCache.setDeptCode = '340012000000'
userCache.setDeptName = "测试单位001"
userCache.setIdCardNum = "420113199310297548"
// userCache.setAuthToken = authUserModel.token
// userCache.setProfilePhoto = StringUtils.get(authUserModel.profilePhoto, "")
userCache.setPhoneNum = '18815656560'
// userCache.setEmail = StringUtils.get(authUserModel.email, "")
userCache.setWorkPhone = '19915155150'
// userCache.setPoliceTypeId = StringUtils.get(authUserModel.policeTypeId, "")
// userCache.setPoliceTypeName = StringUtils.get(authUserModel.policeTypeName, "")
userCache.setBirthdate = '19931029'
userCache.setAge = 32
let departmentCode = userCache.getDeptCode.substring(0, 4)
let departmentName = new AnHuiAddressModel().getAddress(departmentCode)
userCache.setDepartmentCode = departmentCode
userCache.setDepartmentName = departmentName
this.handUserInfo(this.ipAddress)
}
authLogin() {
let pref = preferences.getPreferencesSync(this.context, { name: 'AppStore' });
let isUpdate = pref.getSync('updateUserInfo',false)
let want: Want = {
bundleName: 'hm.anhui.police.auth',
abilityName: 'OhosAuthAbility',
parameters: {
'action': 'getAuthUser',
// 'IAuthTaskType': isUpdate?IAuthTaskType.AUTH_TASK_START_AUTH:IAuthTaskType.AUTH_TASK_USER,
'IAuthTaskType': IAuthTaskType.AUTH_TASK_USER,
'packageName': 'com.ycgis.macall.personalcenter',
'sysCode': AUTH_SYSCODE
}
};
try {
this.context.startAbilityForResult(want, (err: BusinessError, result: common.AbilityResult) => {
if (err.code) {
// 处理业务逻辑错误
console.error(`startAbility failed, code is ${err.code}, message is ${err.message}`);
return;
}
// 执行正常业务
console.info(`startAbility succeed resultCode${result.resultCode} result:${JSON.stringify(result)} want:${JSON.stringify(want)}`);
if (result.resultCode === -1) {
this.message = '未获取到用户信息';
return;
}
pref.put('updateUserInfo',false)
const iAuthTaskType = result.want?.parameters?.IAuthTaskType
const message = result.want?.parameters?.message
if (iAuthTaskType === IAuthTaskType.AUTH_TASK_USER) {
this.message = `开始处理认证数据`;
let authUser = result.want?.parameters?.authUser;
hilog.info(0x0000, 'carousel', '%{public}s', `authUser:${authUser}`);
if (result.resultCode === 200) {
// 获取到用户信息
let authUserModel = JSON.parse(StringUtils.get(authUser, "")) as AuthUserModel
if (authUserModel) {
let userCache = RuanseeAbilityStag.userCache
userCache.setUserName = authUserModel.realName
userCache.setUserCode = authUserModel.userNum
userCache.setDeptCode = authUserModel.orgId
userCache.setDeptName = authUserModel.orgName
userCache.setIdCardNum = authUserModel.code
userCache.setAuthToken = authUserModel.token
userCache.setProfilePhoto = StringUtils.get(authUserModel.profilePhoto, "")
userCache.setPhoneNum = StringUtils.get(authUserModel.phoneNum, "")
userCache.setEmail = StringUtils.get(authUserModel.email, "")
userCache.setWorkPhone = StringUtils.get(authUserModel.workPhone, "")
userCache.setPoliceTypeId = StringUtils.get(authUserModel.policeTypeId, "")
userCache.setPoliceTypeName = StringUtils.get(authUserModel.policeTypeName, "")
userCache.setBirthdate = StringUtils.get(authUserModel.birthdate, "")
userCache.setAge = StringUtils.getNumber(authUserModel.age, 0)
let departmentCode = userCache.getDeptCode.substring(0, 4)
userCache.setDepartmentCode = departmentCode
userCache.setDepartmentName = new AnHuiAddressModel().getAddress(departmentCode)
this.handUserInfo(this.ipAddress)
} else {
this.loginError(`获取用户信息失败!${message}}`);
}
} else if (result.resultCode === 100) {
this.message = `用户主动关闭登录页面,未获取到用户信息`;
this.loginError(`用户主动关闭登录页面,未获取到用户信息`);
} else {
this.message = `未获取到用户信息,错误码(${result.resultCode})`;
this.loginError(`未获取到用户信息,错误码(${result.resultCode})`);
}
} else {
this.message = `获取用户信息失败:${result.want?.parameters?.message}`;
this.loginError(`获取用户信息失败:${result.want?.parameters?.message}`);
}
});
} catch (err) {
// 处理入参错误异常
let code = (err as BusinessError).code;
let message = (err as BusinessError).message;
console.error(`startAbility failed, code is ${code}, message is ${message}`);
this.loginError(`startAbility failed, code is ${code}, message is ${message}`);
}
}
loginError(msg: string) {
ToastUtil.showLong(msg)
setTimeout(() => {
HMRouterMgr.pop({ pageUrl: 'StartPage' })
this.context.terminateSelf()
}, 1500)
}
handUserInfo(ipAddress: string | undefined) {
let appCache = AppCache.getAppCache();
let userCache = UserCache.getUserCache();
appCache.setIpOrPort('20.90.2.2', '80', "/ypc_test_out/")
//设置用户信息,后期改成单点登录获取用户信息
// userCache.setUserName = "陈乐(测试)"
// userCache.setUserCode = "999013"
// userCache.setDeptName = "测试单位001"
// userCache.setDeptCode = "340012000000"
// userCache.setIdCardNum = "420113199310297548"
// let departmentCode = userCache.getUserCode.substring(0, 4)
// let departmentName = new AnHuiAddressModel().getAddress(departmentCode)
// userCache.setDepartmentCode = departmentCode
// userCache.setDepartmentName = departmentName
//本机IP
appCache.setLocalIp = StringUtils.get(ipAddress, "10.115.101.1");
let userInfos = userCache.getUserInfo();
if (StringUtils.isNullOrEmpty(userInfos)) {
let cs: UserInfoModel = {
"userCode": userCache.getUserCode,
"userName": userCache.getUserName,
"deptName": userCache.getDeptName,
"deptCode": userCache.getDeptCode,
"idCardNum": userCache.getIdCardNum,
"ip": appCache.setLocalIp,
"departmentCode": userCache.getDepartmentCode,
"departmentName": userCache.getDepartmentName,
}
let userInfo = JSON.stringify(cs)
let byte = new Uint8Array(buffer.from(userInfo, 'utf-8').buffer);
userCache.setUserInfo = new util.Base64Helper().encodeToStringSync(byte);
}
setTimeout(() => {
this.message = "正在获取用户信息..."
if (appCache.getPermissionsStatus) {
this.jumpAdPage();
}
}, 500)
}
/**
* 获取IP地址
*/
getIpAddress() {
let defNet = connection.getDefaultNet()
defNet.then((netHandle: connection.NetHandle) => {
connection.getConnectionProperties(netHandle, (error: BusinessError, data: connection.ConnectionProperties) => {
if (error) {
console.error(`Failed to get connection properties. Code:${error.code}, message:${error.message}`);
ToastUtils.toastBottom("获取IP地址失败")
// this.testLogin()
this.authLogin()
return;
}
console.info("Succeeded to get data: " + JSON.stringify(data));
try {
let ip = data['linkAddresses'][0]['address']['address']
console.info('本地ip', ip)
this.ipAddress = ip
// this.testLogin()
this.authLogin()
} catch (e) {
console.error("e", JSON.stringify(e));
ToastUtils.toastBottom("获取IP地址失败")
// this.testLogin()
this.authLogin()
}
});
}).catch((error: Error) => {
console.error("e", JSON.stringify(error));
this.loginError(error.message);
})
}
build() {
Column() {
Image($r('app.media.icon_applogin'))
.width(100)
.aspectRatio(1)
.margin({ top: 190 });
Text($r('app.string.EntryAbility_label'))
.fontSize($r('app.float.text_size_24'))
.fontColor($r('app.color.bull'))
.fontWeight(700)
.letterSpacing(1)
.margin({
top: $r('app.float.default_20'),
bottom: $r('app.float.default_8')
})
Text(this.message)
.fontColor($r('app.color.grad'))
.fontSize($r("app.float.text_size_14"))
.margin({ top: 32 })
Text($r('app.string.ownership_dept'))
.fontColor($r('app.color.grad'))
.fontSize($r("app.float.text_size_14"))
.height('100%')
.margin({ bottom: $r('app.float.default_20') })
}
.width('100%')
.height('100%')
.expandSafeArea([SafeAreaType.SYSTEM])
.overlay(createWaterMark())
}
/**
* 跳转主页
*/
jumpAdPage() {
setTimeout(() => {
this.message = "正在跳转..."
HMRouterMgr.replace({ navigationId: 'startNavigation', pageUrl: "MainPage" })
}, 800);
}
}

View File

@ -0,0 +1,708 @@
import { HMRouter, HMRouterMgr } from "@hadss/hmrouter";
import { common } from "@kit.AbilityKit";
import AppConstants from "../../app/AppConstant";
import { createWaterMark } from "../custom/Watermark";
import { webview } from "@kit.ArkWeb";
import { fileIo, fileUri, picker } from "@kit.CoreFileKit";
import { photoAccessHelper } from "@kit.MediaLibraryKit";
import { WebUserInfoModel } from "../../model/cacheModel/UserInfoModel";
import { RuanseeAbilityStag } from "../../app/RuanseeAbilityStag";
import { StringUtils } from "../../util/StringUtils";
import JiaMi from "../../util/JiaMi";
import { H5OperationType, WebAppPageParam } from "../../model/uiModel/WebAppPageParam";
import { SelectFileOptions } from "../../model/uiModel/SelectFileOptions";
import { window } from "@kit.ArkUI";
import { DialogHelper } from "@pura/harmony-dialog";
import { call } from "@kit.TelephonyKit";
import { StrUtil } from "@pura/harmony-utils/src/main/ets/utils/StrUtil";
import { FileUtils } from "../../util/FileUtils";
import { camera, cameraPicker } from "@kit.CameraKit";
import { ImageUtil, ToastUtil } from "@pura/harmony-utils";
@Preview
@HMRouter({ pageUrl: 'WebAppPages' })
@Component
export struct WebAppPages {
webController: webview.WebviewController = new webview.WebviewController();
context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
@State statusBarColor: string | Resource = $r('app.color.bull')
@State statusBarHeight: number = 34
@State topBarVisible: boolean = true;
@State hmMethodInterface: HMMethodInterface = new HMMethodInterface()
@State leftImage: Resource = $r('app.media.icon_back3')
@State title: string | Resource = ''
@State currentIndex: number = 0
/**
* 标题栏是否深色模式
*/
@State isBlackFontColor: boolean = false
fileSelector: SelectFileOptions = new SelectFileOptions(false,true,true,true)
///////////////// 接收参数 //////////////////
h5AppParam:WebAppPageParam = new WebAppPageParam()
@State loadUrl :string|Resource = $rawfile('TestJs.html')
/////////////////////////////////
aboutToAppear(): void {
this.h5AppParam = HMRouterMgr.getCurrentParam() as WebAppPageParam
if (!this.h5AppParam) {
DialogHelper.showToastTip({
message: "错误的应用参数",
imageRes: $r('app.media.icon_tips_error'),
duration: 1000,
})
setTimeout(() => {
HMRouterMgr.pop()
}, 1200)
return
}
this.title = this.h5AppParam.appName
this.hmMethodInterface.bindComponent(this)
this.handUrl();
setTimeout(() => {
this.webController.loadUrl(this.loadUrl)
}, 800)
}
handUrl() {
if (StringUtils.isNullOrEmpty(this.h5AppParam!.linkUrl)){
this.loadUrl = $rawfile('TestJs.html')
return
}
if (StringUtils.containsChar(this.h5AppParam.linkUrl,"?")){
this.loadUrl = `${this.h5AppParam.linkUrl}&userInfo=${this.hmMethodInterface.getUserInfo()}`
}else {
this.loadUrl = `${this.h5AppParam.linkUrl}?userInfo=${this.hmMethodInterface.getUserInfo()}`
}
if(this.h5AppParam!.operationType == H5OperationType.login){
this.loadUrl = `${this.loadUrl}?operation_type=login`
return
}
if(this.h5AppParam!.operationType == H5OperationType.readMessage){
if(StringUtils.isNullOrEmpty(this.h5AppParam!.msgId)){
this.loadUrl = `${this.loadUrl}?operation_type=login`
return
}
this.loadUrl = `${this.loadUrl}?operation_type=readMessage&msg_id=${StringUtils.get(this.h5AppParam!.msgId,"")}`
if (StrUtil.isNotEmpty(this.h5AppParam!.msgType)) {
this.loadUrl = `${this.loadUrl}?msg_type=${StringUtils.get(this.h5AppParam!.msgType,"")}`
}
}
if(this.h5AppParam!.operationType == H5OperationType.search){
this.loadUrl = `${this.loadUrl}?operation_type=search&search_type=${StringUtils.get(this.h5AppParam!.searchType,"")}`
}
}
/**
* 文件选择器
* @param result
* @returns
*/
async selectImage(result: FileSelectorResult): Promise<void> {
let photoSelectOptions = new photoAccessHelper.PhotoSelectOptions();
let photoPicker = new photoAccessHelper.PhotoViewPicker();
// 过滤选择媒体文件类型为IMAGE
photoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_VIDEO_TYPE;
// 设置最大选择数量
photoSelectOptions.maxSelectNumber = 1;
let chooseFile: picker.PhotoSelectResult = await photoPicker.select(photoSelectOptions);
// 获取选择的文件列表
result.handleFileList(chooseFile.photoUris);
}
async selectFile(result: FileSelectorResult) {
console.log('MyFileUploader onShowFileSelector invoked')
const documentSelectOptions = new picker.DocumentSelectOptions();
let uri: string | null = null;
documentSelectOptions.maxSelectNumber = 1;
const documentViewPicker = new picker.DocumentViewPicker();
documentViewPicker.select(documentSelectOptions).then((documentSelectResult) => {
uri = documentSelectResult[0];
console.info('documentViewPicker.select to file succeed and uri is:' + uri);
if (result) {
result.handleFileList([uri]);
}
}).catch((err: Error) => {
console.error(`Invoke documentViewPicker.select failed, code is ${err.message}, message is ${err.message}`);
})
}
/**
* 拍照
*/
async takePhoto(webResult: FileSelectorResult) {
let pathDir = FileUtils.IMAGE_DIR;
let fileName = `${new Date().getTime()}.JPEG`
let filePath = `${pathDir}/${fileName}`
let imageFileUri: string | undefined = undefined;
fileIo.createRandomAccessFileSync(filePath, fileIo.OpenMode.CREATE);
let fileUris = fileUri.getUriFromPath(filePath);
let pickerProfile: cameraPicker.PickerProfile = {
cameraPosition: camera.CameraPosition.CAMERA_POSITION_BACK,
saveUri: fileUris,
};
let result: cameraPicker.PickerResult =
await cameraPicker.pick(getContext(), [cameraPicker.PickerMediaType.PHOTO],
pickerProfile);
console.info(`picker resultCode: ${result.resultCode},resultUri: ${result.resultUri},mediaType: ${result.mediaType}`);
if (result.resultCode == 0) {
if (result.mediaType === cameraPicker.PickerMediaType.PHOTO) {
imageFileUri = result.resultUri
imageFileUri = await ImageUtil.compressPhoto(imageFileUri, 150);
webResult.handleFileList([imageFileUri])
}
} else {
ToastUtil.showToast("取消选择")
}
}
showUpdatePhoto(selectItems:Array<string>,webResult: FileSelectorResult) {
//带标题
DialogHelper.showActionSheetDialog({
title: "选择文件",
titleFontColor: Color.Black,
cancelFontColor: Color.Red,
cancelFontWeight: FontWeight.Normal,
sheets: selectItems,
onAction: (index) => {
let item = selectItems[index]
if(item == '相机拍摄'){
this.takePhoto(webResult)
}
if(item == '相册选择'){
this.selectImage(webResult)
}
if(item == '文件选择'){
this.selectFile(webResult)
}
}
})
}
build() {
Column() {
Blank()
.width(AppConstants.PERCENTAGE_MAX)
.height(this.statusBarHeight)
.color(this.statusBarColor)
this.topBar()
this.webView()
}
.width(AppConstants.PERCENTAGE_MAX)
.height(AppConstants.PERCENTAGE_MAX)
.padding({bottom: $r('app.float.default_28')})
.overlay(createWaterMark())
}
@Builder
webView() {
//// 设置为同步渲染模式
Web({ src: "", controller: this.webController, renderMode: RenderMode.SYNC_RENDER })
// .layoutMode(WebLayoutMode.FIT_CONTENT)// 设置为Web组件大小自适应页面内容
.overScrollMode(OverScrollMode.NEVER)// 设置过滚动模式为关闭状态
.fileAccess(true)
.javaScriptAccess(true)
.layoutWeight(1)
.width(AppConstants.PERCENTAGE_MAX)
.javaScriptProxy({
object: this.hmMethodInterface,
name: "callByAndroid",
methodList: ["isTitleBlock", "getUserInfo", "setUploadFileOptions", "onBack", "exitToHome",
"setSystemStatusBarStyle", "showNetPermission","reloadPage"],
asyncMethodList: ["asyncTest"],
controller: this.webController,
})
.defaultFixedFontSize(14)
.defaultFontSize(14)
.minFontSize(14)
.minLogicalFontSize(13)
.mixedMode(MixedMode.All)
.zoomAccess(false)
.databaseAccess(true)
.domStorageAccess(true)
.horizontalScrollBarAccess(false)// .cacheMode(CacheMode.Online)
.copyOptions(CopyOptions.LocalDevice)
.onLoadIntercept((event) => {
if (event.data.getRequestUrl().startsWith('tel:')) {
call.makeCall(event.data.getRequestUrl().substring(4));
return true; // 阻止默认跳转
}
return false;
})
.onAlert((event) => { //网页加载时弹出提示框
if (event) {
console.log("event.url:" + event.url);
console.log("event.message:" + event.message);
AlertDialog.show({
title: 'onAlert',
message: event.message,
primaryButton: {
value: '取消',
action: () => {
event.result.handleCancel();
}
},
secondaryButton: {
value: '确定',
action: () => {
event.result.handleConfirm();
}
},
cancel: () => {
event.result.handleCancel();
}
})
}
return false;
})
.onErrorReceive((event) => { //网页加载遇到错误时触发该回调
if (event) {
console.log('getErrorInfo:' + event.error.getErrorInfo());
console.log('getErrorCode:' + event.error.getErrorCode());
console.log('url:' + event.request.getRequestUrl());
console.log('isMainFrame:' + event.request.isMainFrame());
console.log('isRedirect:' + event.request.isRedirect());
console.log('isRequestGesture:' + event.request.isRequestGesture());
console.log('getRequestHeader_headerKey:' + event.request.getRequestHeader().toString());
let result = event.request.getRequestHeader();
console.log('The request header result size is ' + result.length);
for (let i of result) {
console.log('The request header key is : ' + i.headerKey + ', value is : ' + i.headerValue);
}
}
})
.onDownloadStart((event) => { //通知主应用开始下载一个文件。
if (event) {
console.log('url:' + event.url)
console.log('userAgent:' + event.userAgent)
console.log('contentDisposition:' + event.contentDisposition)
console.log('contentLength:' + event.contentLength)
console.log('mimetype:' + event.mimetype)
}
})
.onHttpErrorReceive((event) => { //网页加载资源遇到的HTTP错误响应码>=400)时触发该回调。
if (event) {
console.log('url:' + event.request.getRequestUrl());
console.log('isMainFrame:' + event.request.isMainFrame());
console.log('isRedirect:' + event.request.isRedirect());
console.log('isRequestGesture:' + event.request.isRequestGesture());
console.log('getResponseData:' + event.response.getResponseData());
console.log('getResponseEncoding:' + event.response.getResponseEncoding());
console.log('getResponseMimeType:' + event.response.getResponseMimeType());
console.log('getResponseCode:' + event.response.getResponseCode());
console.log('getReasonMessage:' + event.response.getReasonMessage());
let result = event.request.getRequestHeader();
console.log('The request header result size is ' + result.length);
for (let i of result) {
console.log('The request header key is : ' + i.headerKey + ' , value is : ' + i.headerValue);
}
let resph = event.response.getResponseHeader();
console.log('The response header result size is ' + resph.length);
for (let i of resph) {
console.log('The response header key is : ' + i.headerKey + ' , value is : ' + i.headerValue);
}
}
})
.onPageBegin((event) => { //网页开始加载时触发该回调
if (event) {
console.log('url:' + event.url);
}
})
.onPageEnd((event) => { //网页加载完成时触发该回调
if (event) {
console.log('url:' + event.url);
}
})
.onProgressChange((event) => { //网页加载进度变化时触发该回调
if (event) {
console.log('newProgress:' + event.newProgress);
}
})
.onTitleReceive((event) => {
if (event) {
console.log('title:' + event.title);
}
})
.onRenderExited((event) => { //应用渲染进程异常退出时触发该回调
if (event) {
console.log('reason:' + event.renderExitReason);
}
})
.onShowFileSelector((event) => {
if (this.fileSelector) {
if (this.fileSelector.selfRealization) {
return true
}
if (this.fileSelector.onlyOneItemIsSelected()) {
if(this.fileSelector.isCamera){
//相机拍照
this.takePhoto(event.result)
}
if(this.fileSelector.isFileSelection){
//文件选择
this.selectFile(event.result)
}
if(this.fileSelector.isDCIM){
//图库
this.selectImage(event.result)
}
return true;
}else {
let selectItems = new Array<string>();
if(this.fileSelector.isCamera) {
selectItems.push('相机拍摄')
}
if(this.fileSelector.isDCIM) {
selectItems.push('相册选择')
}
if(this.fileSelector.isFileSelection) {
selectItems.push('文件选择')
}
this.showUpdatePhoto(selectItems, event.result);
}
return true;
}
/**
* 调用此函数以处理具有“文件”输入类型的HTML表单。如果不调用此函数或返回false
* Web组件会提供默认的“选择文件”处理界面。如果返回true应用可以自定义“选择文件”的响应行为。
*/
event.fileSelector.getMode()
event.fileSelector.getAcceptType()
event.fileSelector.getMimeTypes()
event.fileSelector.isCapture()
if (event.fileSelector) {
}
return true;
})
.onPermissionRequest((event) => { //通知收到获取权限请求
if (event) {
AlertDialog.show({
title: 'title',
message: 'text',
primaryButton: {
value: 'deny',
action: () => {
event.request.deny();
}
},
secondaryButton: {
value: 'onConfirm',
action: () => {
event.request.grant(event.request.getAccessibleResource());
}
},
cancel: () => {
event.request.deny();
}
})
}
})
.onGeolocationShow((event) => { //通知用户收到地理位置信息获取请求。
if (event) {
AlertDialog.show({
title: 'title',
message: 'text',
confirm: {
value: 'onConfirm',
action: () => {
event.geolocation.invoke(event.origin, true, true);
}
},
cancel: () => {
event.geolocation.invoke(event.origin, false, true);
}
})
}
})
}
@Builder
topBar() {
Row() {
Row() {
Image(this.leftImage)
.width($r('app.float.default_24'))
.height($r('app.float.default_24'))
}
.height("100%")
.width($r('app.float.default_68'))
.alignItems(VerticalAlign.Center)
.padding({ left: $r('app.float.default_10') })
.onTouch((event) => {
if (event.type === TouchType.Down) {
this.leftImage = $r('app.media.icon_back2');
} else if (event.type === TouchType.Up) {
if (this.isBlackFontColor) {
this.leftImage = $r('app.media.icon_back_black');
} else {
this.leftImage = $r('app.media.icon_back3');
}
}
})
.onClick(() => {
if (this.webController.accessBackward()) {
this.webController.backward()
} else {
HMRouterMgr.pop()
}
})
Text(this.title)
.fontColor(this.isBlackFontColor ? $r('app.color.colorGrey8') : $r('app.color.white'))
.fontSize($r('app.float.text_size_18'))
.layoutWeight(1)
.height("100%")
.textAlign(TextAlign.Center)
.align(Alignment.Center)
.margin({
left: $r('app.float.default_10'),
right: $r('app.float.default_10')
})
Row() {
Image(this.isBlackFontColor ? $r('app.media.icon_refresh_grad') : $r('app.media.icon_refresh'))
.width($r('app.float.default_24'))
.height($r('app.float.default_24'))
.onClick(() => {
this.webController.refresh()
})
Image(this.isBlackFontColor ? $r('app.media.icon_over_back') : $r('app.media.icon_over'))
.width($r('app.float.default_24'))
.height($r('app.float.default_24'))
.margin({ left: $r('app.float.default_5') })
.onClick(() => {
HMRouterMgr.pop({ navigationId: 'startNavigation', pageUrl: "MainPage" })
})
}
.alignItems(VerticalAlign.Center)
.height("100%")
.width($r('app.float.default_68'))
.padding({ right: $r('app.float.default_10') })
}
.alignItems(VerticalAlign.Center)
.width('100%')
.visibility(this.topBarVisible ? Visibility.Visible : Visibility.None)
.backgroundColor(this.statusBarColor)
.height($r('app.float.default_40'))
}
hideTopBar(isShow: boolean) {
this.topBarVisible = isShow;
}
/**
* 设置状态栏颜色
* @param statusBarColor
*/
setStatusBarColor(statusBarColor: string) {
// 在UIAbility或UI组件中执行需确保已获取Window对象
let sysBarProps: window.SystemBarProperties = {
statusBarContentColor: statusBarColor, // 白色文字/图标
statusBarColor: '#00000000' // 黑色背景
};
this.context.windowStage.getMainWindow()
.then((windows) => {
if (windows) {
windows.setWindowSystemBarProperties(sysBarProps)
.then(() => {
console.info('状态栏颜色修改成功');
})
.catch((err: Error) => {
console.error(`修改失败,信息: ${err.message}`);
});
}
})
.catch((err: Error) => {
console.error(`获取window失败信息: ${err.message}`);
})
}
@Builder
errorDialog(message: string, ywry: string, ywryPhone: string) {
Column() {
Text(message)
.fontColor($r('app.color.colorGrey8'))
.fontSize($r('app.float.text_size_14'))
Row() {
Text(ywry)
.fontColor($r('app.color.colorGrey8'))
.fontSize($r('app.float.text_size_14'))
Text(ywryPhone)
.fontColor($r('app.color.bull'))
.fontSize($r('app.float.text_size_14'))
.copyOption(CopyOptions.LocalDevice)
.decoration({
type: TextDecorationType.Underline,
color: Color.Blue,
style: TextDecorationStyle.WAVY
})
.onClick(() => {
this.callPhone(ywryPhone)
})
}
.alignItems(VerticalAlign.Center)
.justifyContent(FlexAlign.Center)
.height($r('app.float.default_38'))
.width(AppConstants.PERCENTAGE_MAX)
}
.alignItems(HorizontalAlign.Center)
.width(AppConstants.PERCENTAGE_MAX)
}
callPhone(phone: string) {
if (!call.hasVoiceCapability()) {
console.error('设备不支持拨号功能');
return;
}
call.makeCall("tel:" + phone, (err: Error) => {
if (err) {
console.error(`跳转失败:${err.message}`);
}
});
}
}
class HMMethodInterface {
private componentRef: WebAppPages | null = null;
bindComponent(ref: WebAppPages) {
this.componentRef = ref;
}
isTitleBlock(isShow: boolean) {
this.componentRef?.hideTopBar(isShow);
}
/**
* 获取加密用户信息
* @returns
*/
getUserInfo(): string {
let userData: WebUserInfoModel = new WebUserInfoModel();
userData.userCode = RuanseeAbilityStag.userCache.getUserCode
userData.userName = RuanseeAbilityStag.userCache.getUserName
userData.deptName = RuanseeAbilityStag.userCache.getDeptName
userData.deptCode = RuanseeAbilityStag.userCache.getDeptCode
userData.idCardNum = RuanseeAbilityStag.userCache.getIdCardNum
let userInfo = JSON.stringify(userData)
let jmData = StringUtils.get(new JiaMi().desCrypto(userInfo,this.componentRef!.h5AppParam.appId, this.componentRef!.h5AppParam.secret), "")
console.debug("加密后数据:", jmData)
return jmData
}
/**
* TODO 该方法不能弹出选择框此方法是在JS调用选择文件方法之前调用的。在使用JS调选择文件时将根据此方法的配置做对应操作
* 配置上传文件选择项。此方法再调用上传文件的事件之前调用,如果不调用则默认 selfRealization = false , 其他参数默认为 true
* 详情查看 {@link WebViewPresenter#mWebChromeClient} 的 onShowFileChooser(WebView, ValueCallback<Uri[]> , FileChooserParams ) 方法
*
* @param selfRealization 是否由JS自己实现文件选择上传。
* PS: true:由JS自己实现Android原生不做操作不会弹出选择框,.值为false时将原生代码将拦截操作并根据下面参数配置弹出选择框。
* @param isCamera PS:是否支持相机拍照: true = 支持相机拍照上传false = 不支持相机拍照上传值为false时弹出框将没有相机选项
* @param isDCIM PS:是否支持相册选择: true = 支持相册选择上传false = 不支持相册选择上传值为false时弹出框将没有相册选项
* @param isFileSelection PS:是否支持文件选择: true = 支持文件选择上传false = 不支持文件选择上传值为false时弹出框将没有文件选择选项
* TODO 当且仅当 selfRealization = true && (isCamera | isDCIM | isFileSelection ) 只有一个为 true 时 将没有弹框,直接跳转对应操作
*/
setUploadFileOptions(selfRealization: boolean, isCamera: boolean, isDCIM: boolean, isFileSelection: boolean) {
if (this.componentRef) {
if (!this.componentRef.fileSelector) {
this.componentRef.fileSelector = new SelectFileOptions(selfRealization, isCamera, isDCIM, isFileSelection);
} else {
this.componentRef.fileSelector.setConfig(selfRealization, isCamera, isDCIM, isFileSelection)
}
}
}
/**
* 调用返回按钮
*/
onBack() {
if (this.componentRef) {
if (this.componentRef.webController.accessBackward()) {
this.componentRef.webController.backward()
} else {
HMRouterMgr.pop()
}
}
}
/**
* 退出到主页
*/
exitToHome() {
HMRouterMgr.pop()
}
/**
* 设置状态栏颜色及状态栏图标字体颜色深浅模式
*
* @param statusBarColor 状态栏颜色 值为字符串 格式为:#ffffff
* @param isBlackFontColor 是否为 true 为黑色字体 | false 为白色字体
*/
setSystemStatusBarStyle(statusBarColor: string, isBlackFontColor: boolean) {
if (this.componentRef) {
let effectiveColor = "#3255E3";
if (StringUtils.strictCheckHexColor(statusBarColor)) {
effectiveColor = statusBarColor;
}
this.componentRef.statusBarColor = effectiveColor
this.componentRef.isBlackFontColor = isBlackFontColor
if (isBlackFontColor) {
this.componentRef.leftImage = $r('app.media.icon_back_black')
this.componentRef.setStatusBarColor("#000000")
// setStatusBarColor(this.context, bg, content);
} else {
this.componentRef.leftImage = $r('app.media.icon_back3')
this.componentRef.setStatusBarColor("#ffffff")
// setStatusBarColor(this.context, bg, content);
}
}
}
/**
* 弹出提示框
*
* @param title 提示标题
* @param msg 提示内容
* @param lxryName 联系人员
* @param lxryPhone 联系电话
*/
showNetPermission(title = "重要提醒", msg: string, lxryName: string, lxryPhone: string) {
//自定义文本内容,使用全局 @Builder 和 自定义组件
DialogHelper.showCustomContentDialog({
title: title,
contentBuilder: () => {
this.componentRef?.errorDialog(msg, lxryName, lxryPhone)
},
buttons: [
{ value: '确定', fontColor: Color.Black }
],
onAction: (action, dialogId, value) => {
if (action === -1) {
DialogHelper.closeDialog(dialogId)
HMRouterMgr.pop()
}
}
})
}
/**
* 刷新页面
*/
reloadPage() {
if (this.componentRef) {
this.componentRef.webController.refresh()
}
}
}

View File

@ -0,0 +1,56 @@
import { BASE_IMAGE_URL } from "../../app/AppCache";
import AppConstants from "../../app/AppConstant";
import { AppDataModel } from "../../model/resultModel/ApplicationResultModel";
@Component
export struct SelectAppItem {
@ObjectLink item: AppDataModel;
onSelect?: (item: AppDataModel) => void
build() {
Row() {
Radio({
value: 'Radio1', group: 'radioGroup',
indicatorType: RadioIndicatorType.TICK
})
.checked(this.item.isSelect)
.height($r('app.float.default_20'))
.width($r('app.float.default_20'))
.onChange((isChecked: boolean) => {
// 只有选中时才触发选择事件,实现单选
if (isChecked && this.onSelect) {
this.onSelect(this.item)
}
})
Image(BASE_IMAGE_URL+this.item.icon)
.width($r('app.float.default_24'))
.height($r('app.float.default_24'))
.margin({left: $r('app.float.default_8'), right: $r('app.float.default_5')})
Text(this.item.name)
.layoutWeight(1)
.fontColor(this.item.isSelect ? $r('app.color.colorBluen8') : $r('app.color.colorGrey7'))
.fontSize($r('app.float.text_size_14'))
.onClick(() => {
// 点击文本时触发选择
if (this.onSelect) {
this.onSelect(this.item)
}
})
}
.width(AppConstants.PERCENTAGE_MAX)
.padding({
left: $r('app.float.default_10'),
right: $r('app.float.default_10'),
top: $r('app.float.default_6'),
bottom: $r('app.float.default_6')
})
// 添加按压效果提升用户体验
.useEffect(true)
.backgroundColor(this.item.isSelect
? $r('app.color.colorBluen1')
: Color.Transparent)
}
}

View File

@ -0,0 +1,30 @@
import bundleManager from '@ohos.bundle.bundleManager';
import { BusinessError } from '@ohos.base';
import hilog from '@ohos.hilog';
let bundleFlags = bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION;
export class AppUtils {
async getAppList() {
try {
bundleManager.getAllBundleInfo(bundleFlags, (err, data) => {
if (err) {
hilog.error(0x0000, 'testTag', 'getAllBundleInfo failed: %{public}s', err.message);
} else {
data.forEach((bundleInfo) => {
let appInfo = bundleInfo.appInfo;
hilog.info(0x0000, 'testTag', 'appInfo: %{public}s', JSON.stringify(appInfo));
});
hilog.info(0x0000, 'testTag', 'getAllBundleInfo successfully: %{public}s', JSON.stringify(data));
}
});
} catch (err) {
let message = (err as BusinessError).message;
//onForeground
hilog.error(0x0000, 'testTag', 'getAllBundleInfo failed: %{public}s', message);
}
}
}

View File

@ -0,0 +1,10 @@
import { ArrayList } from "@kit.ArkTS";
export class ArrayListUtils {
static contain<T>(dataList: ArrayList<T>, data: T): boolean {
return dataList.has(data);
}
}

View File

@ -0,0 +1,53 @@
import { buffer } from '@kit.ArkTS';
import { fileIo } from '@kit.CoreFileKit';
import { fileUri } from "@kit.CoreFileKit";
import { hilog } from '@kit.PerformanceAnalysisKit';
import { image } from '@kit.ImageKit';
export class BitMapUtils{
/**
* 保存图片到本地
* @param data 图片base64
* @param filesDir 保存目录
* @param fileName 保存的文件名
* @returns
*/
static async writeFile(data: string, filesDir :string,fileName:string): Promise<string> {
let fileAbsolutelyPath =""
try {
let filePath = filesDir+"/" + fileName;
// uri = fileUri.getUriFromPath(filePath);
fileAbsolutelyPath = filePath
let file = fileIo.openSync(filePath, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE);
console.info("file fd: " + file.fd);
const reg = new RegExp("data:image/\\w+;base64,")
const base64 = data.replace(reg, "");
console.log("base64flag", base64)
const dataBuffer = buffer.from(base64, 'base64')
let writeLen = fileIo.writeSync(file.fd, dataBuffer.buffer);
hilog.info(0xA0c0d0,'文件长度',writeLen+"")
fileIo.closeSync(file);
} catch (Error) {
hilog.error(0xA0c0d0,'Error',Error.code)
}
return fileAbsolutelyPath;
}
static async copyPixelMap(pm: image.PixelMap): Promise<image.PixelMap> {
const imageInfo: image.ImageInfo = await pm.getImageInfo();
const buffer: ArrayBuffer = new ArrayBuffer(pm.getPixelBytesNumber());
// TODO 知识点通过readPixelsToBuffer实现PixelMap的深拷贝其中readPixelsToBuffer输出为BGRA_8888
await pm.readPixelsToBuffer(buffer);
// TODO 知识点readPixelsToBuffer输出为BGRA_8888,此处createPixelMap需转为RGBA_8888
const opts: image.InitializationOptions = {
editable: true,
pixelFormat: image.PixelMapFormat.RGBA_F16,
size: { height: imageInfo.size.height, width: imageInfo.size.width }
};
return await image.createPixelMap(buffer, opts);
}
}
// data为需要转换的base64字符串返回沙箱路径uri

View File

@ -0,0 +1,26 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { util } from '@kit.ArkTS';
export function bufferToString(buffer: ArrayBufferLike): string {
let textDecoder = util.TextDecoder.create('utf-8', {
ignoreBOM: true
});
let result = textDecoder.decodeToString(new Uint8Array(buffer), {
stream: true
});
return result;
}

View File

@ -0,0 +1,6 @@
export class Constant{
public static REFRESH_PULL_TO_REFRESH : string = "下拉可以刷新";
public static REFRESH_FREE_TO_REFRESH :string = "释放立即刷新"
public static REFRESH_REFRESHING :string ="正在刷新";
public static REFRESH_SUCCESS :string="刷新成功"
}

View File

@ -0,0 +1,371 @@
export enum DateFormat {
//'yyyy-mm-dd'
YYYY_MM_DD,
//'yyyy-mm-dd HH:mm:ss'
YYYY_MM_DDkHHdMMdSS,
//'yyyy-mm-dd HH:mm:ss.sss'
YYYY_MM_DDkHHdMMdSSdSSS,
//yyyy/mm/dd
YYYYxMMxDD,
//yyyy/mm/dd HH:mm:ss
YYYYxMMxDDkHHdMMdSS,
//yyyy/mm/dd HH:mm:ss.sss
YYYYxMMxDDkHHdMMdSSdSSS,
//yyyy年mm月dd
YYYYnMMyDDr,
//yyyy年mm月dd日 HH:mm:ss
YYYYnMMyDDrkHHdMMdSS,
//yyyy年mm月dd日 HH:mm:ss.sss
YYYYnMMyDDrkHHdMMdSSdSSS,
}
export class DateUtils {
static formatDateStr(nowData: Date | undefined | null, format: DateFormat | undefined | null): string {
if (nowData == null || nowData == undefined) {
nowData = new Date();
}
//年
let year = nowData.getFullYear()
//月
let month = ("0" + (nowData.getMonth() + 1)).slice(-2); // 月份是从0开始计数的所以需要加1
//日
let day = ("0" + nowData.getDate()).slice(-2); // 为了保证始终是两位数不足两位前面补0
//时
let hours = nowData.getHours()>9?nowData.getHours():`0${nowData.getHours()}`;
//分
let minutes = nowData.getMinutes()>9?nowData.getMinutes():`0${nowData.getMinutes()}`;
//秒
let seconds = nowData.getSeconds()>9?nowData.getSeconds():`0${nowData.getSeconds()}`;
//毫秒
let milliSeconds = nowData.getMilliseconds();
if (format == null || format == undefined) {
format = DateFormat.YYYY_MM_DDkHHdMMdSS
}
if (format == DateFormat.YYYY_MM_DD) {
return year + "-" + month + "-" + day
}
if (format == DateFormat.YYYY_MM_DDkHHdMMdSS) {
return year + "-" + month + "-" + day + " " + hours + ":" + minutes + ":" + seconds
}
if (format == DateFormat.YYYY_MM_DDkHHdMMdSSdSSS) {
return year + "-" + month + "-" + day + " " + hours + ":" + minutes + ":" + seconds + "." + milliSeconds
}
if (format == DateFormat.YYYYxMMxDD) {
return year + "/" + month + "/" + day
}
if (format == DateFormat.YYYYxMMxDDkHHdMMdSS) {
return year + "/" + month + "/" + day + " " + hours + ":" + minutes + ":" + seconds
}
if (format == DateFormat.YYYYxMMxDDkHHdMMdSSdSSS) {
return year + "/" + month + "/" + day + " " + hours + ":" + minutes + ":" + seconds + "." + milliSeconds
}
if (format == DateFormat.YYYYnMMyDDr) {
return year + "年" + month + "月" + day + "日"
}
if (format == DateFormat.YYYYnMMyDDrkHHdMMdSS) {
return year + "年" + month + "月" + day + "日 " + hours + ":" + minutes + ":" + seconds
}
if (format == DateFormat.YYYYnMMyDDrkHHdMMdSSdSSS) {
return year + "年" + month + "月" + day + "日 " + hours + ":" + minutes + ":" + seconds + "." + milliSeconds
}
return year + "-" + month + "-" + day
}
static pastStrDate(strDate: string | null): Date | null {
if (strDate == null) {
return null;
}
let formatting = strDate.trim()
// .replaceAll(' ', '')
// .replace(' ', '')
// .replaceAll('-', "")
// .replace('-', "")
// .replaceAll('.', "")
// .replace('.', "")
// .replaceAll('/', "")
// .replace('/', "")
// .replace('年', "")
// .replace('月', "")
// .replace('日', "")
// .replaceAll(':', "")
// .replace(':', "")
// .replaceAll('—', "")
// .replace('—', "")
// .replaceAll('', "")
// .replace('', "")
// .replaceAll('。', "")
// .replace('。', "")
// .trim()
let f = new Array();
for (let i = 0; i < formatting.length; i++) {
let s = formatting.charAt(i);
if (!this.isNum(s)) {
f.push(s)
}
}
for (let i = 0; i < f.length; i++) {
formatting = formatting.replace(f[i], "")
}
switch (formatting.length) {
case 4:
return new Date(formatting)
case 6: //202306
let y = formatting.substring(0, 4)
let m = formatting.substring(4, 6)
return new Date(y + "-" + m)
case 8: //20230612
y = formatting.substring(0, 4)
m = formatting.substring(4, 6)
let d = formatting.substring(6, 8)
return new Date(y + "-" + m + "-" + d)
case 10: //2023061211
y = formatting.substring(0, 4)
m = formatting.substring(4, 6)
d = formatting.substring(6, 8)
let h = formatting.substring(8, 10)
return new Date(y + "-" + m + "-" + d + " " + h)
case 12: //2023061211
y = formatting.substring(0, 4)
m = formatting.substring(4, 6)
d = formatting.substring(6, 8)
h = formatting.substring(8, 10)
let f = formatting.substring(10, 12)
return new Date(y + "-" + m + "-" + d + " " + h + ":" + f)
case 14: //20230612101533
y = formatting.substring(0, 4)
m = formatting.substring(4, 6)
d = formatting.substring(6, 8)
h = formatting.substring(8, 10)
f = formatting.substring(10, 12)
let ms = formatting.substring(12, 14)
return new Date(y + "-" + m + "-" + d + " " + h + ":" + f + ":" + ms)
case 17: //20230612101533333
y = formatting.substring(0, 4)
m = formatting.substring(4, 6)
d = formatting.substring(6, 8)
h = formatting.substring(8, 10)
f = formatting.substring(10, 12)
ms = formatting.substring(12, 14)
let hms = formatting.substring(14, 17)
return new Date(y + "-" + m + "-" + d + " " + h + ":" + f + ":" + ms + '.' + hms)
default :
return null
}
}
/**
* "M/D/YY, h:mm A" "yyyy-MM-dd HH:mm:ss"
* @param dateStr 8/12/25, 3:23 PM
* @returns 2025-08-12 15:23:00
*/
static formatMdyHmA(dateStr: string): string {
if (dateStr == null||dateStr == undefined ||dateStr.toString().trim().length<1) {
return "";
}
// 解析原始时间字符串
const [datePart, timePart] = dateStr.split(", ");
const [month, day, year] = datePart.split("/").map(Number);
const [time, period] = timePart.split(" ");
const [hoursStr, minutesStr] = time.split(":");
let hours = parseInt(hoursStr, 10);
const minutes = parseInt(minutesStr, 10);
// 处理 AM/PM
if (period === "PM" && hours < 12) hours += 12;
if (period === "AM" && hours === 12) hours = 0;
// 补零操作
const pad = (num: number) => num.toString().padStart(2, "0");
return "yyyy-MM-dd HH:mm:ss"
.replace("yyyy", `${2000 + year}`) // 假设年份简写为后两位如25表示2025
.replace("MM", pad(month))
.replace("dd", pad(day))
.replace("HH", pad(hours))
.replace("mm", pad(minutes))
.replace("ss", "00"); // 秒数未提供,默认补零
}
/**
*
*
* @param val
*/
public static isNum(val: string): boolean {
const reg = new RegExp('^[0-9]*$');
return val != null && "" != (val) && reg.test(val);
}
/**
*
* @param nowData
* @returns yyyy-MM-dd
*/
static getNowDats(nowData: Date | null): string {
if (!nowData) {
nowData = new Date();
}
let year = nowData.getFullYear()
let month = ("0" + (nowData.getMonth() + 1)).slice(-2); // 月份是从0开始计数的所以需要加1
let day = ("0" + nowData.getDate()).slice(-2); // 为了保证始终是两位数不足两位前面补0
return year + "-" + month + "-" + day
}
/**
*
* @param nowData
* @returns yyyy-MM-dd
*/
static getWeekFirstDay(nowData: Date | null): string {
if (!nowData) {
nowData = new Date();
}
const currentDay = nowData.getDay(); // 0星期日到 6星期六
let firstDay = new Date()
firstDay.setDate(nowData.getDate() - currentDay + 1)
return firstDay.getFullYear() + "-" + ("0" + (firstDay.getMonth() + 1)).slice(-2) + "-" +
("0" + firstDay.getDate()).slice(-2);
}
/**
*
* @param nowData
* @returns yyyy-MM-dd
*/
static getWeekLastDay(nowData: Date | null): string {
if (!nowData) {
nowData = new Date();
}
const currentDay = nowData.getDay(); // 0星期日到 6星期六
let lastDay = new Date()
lastDay.setDate(nowData.getDate() + (6 - currentDay + 1))
return lastDay.getFullYear() + "-" + ("0" + (lastDay.getMonth() + 1)).slice(-2) + "-" +
("0" + lastDay.getDate()).slice(-2);
}
/**
*
* @param nowData
* @returns yyyy-MM-dd
*/
static getLastDayOfMonth(nowData: Date | null): string {
if (!nowData) {
nowData = new Date();
}
let year = nowData.getFullYear(); // 获取当前年份
let month = nowData.getMonth(); // 获取当前月份从0开始
// 创建一个表示当前月份最后一天的Date对象
let lastDayOfMonth = new Date(year, month + 1, 0);
return lastDayOfMonth.getFullYear() + "-" + ("0" + (lastDayOfMonth.getMonth() + 1)).slice(-2) + "-" +
("0" + lastDayOfMonth.getDate()).slice(-2);
}
/**
*
* @param dateTime
* @returns
*/
static getWeek(dateTime: Date): number {
const temptTime = new Date(dateTime);
const weekday = temptTime.getDay() || 7; // 周几 (0-60代表星期天)
// 调整日期到上周一
temptTime.setDate(temptTime.getDate() - weekday + 1);
const firstDay = new Date(temptTime.getFullYear(), 0, 1);
// 获取第一周的第一天
const dayOfWeek = firstDay.getDay();
const spendDay = dayOfWeek === 0 ? 7 : 7 - dayOfWeek + 1;
// 计算周数
const startOfYear = new Date(temptTime.getFullYear(), 0, 1 + spendDay);
const days = Math.ceil((temptTime.getTime() - startOfYear.getTime()) / 86400000);
return Math.ceil(days / 7);
}
/**
* `几秒前``几分钟前``几小时前``几天前`
* @param param new Date()
* @param format
* @returns
*/
static formatPast(param: string | Date, format: string = 'YYYY-mm-dd'): string {
const time = new Date().getTime();
let t = typeof param === 'string' || param instanceof Date ? new Date(param).getTime() : param;
const diff = time - t;
if (diff < 10000) {
return '刚刚';
} // 10秒内
if (diff < 60000) {
return `${Math.floor(diff / 1000)}秒前`;
} // 少于1分钟
if (diff < 3600000) {
return `${Math.floor(diff / 60000)}分钟前`;
} // 少于1小时
if (diff < 86400000) {
return `${Math.floor(diff / 3600000)}小时前`;
} // 少于24小时
if (diff < 259200000) {
return `${Math.floor(diff / 86400000)}天前`;
} // 少于3天
return DateUtils.formatDate(new Date(param), format); // 超过3天
}
/**
*
* @param date new Date()
* @param format
* @returns
*/
static formatDate(date: Date, format: string): string {
const week: { [key: string]: string } = {
'0': '日',
'1': '一',
'2': '二',
'3': '三',
'4': '四',
'5': '五',
'6': '六',
};
const quarter: { [key: string]: string } = {
'1': '一',
'2': '二',
'3': '三',
'4': '四'
};
const we = date.getDay(); // 星期
const z = DateUtils.getWeek(date); // 周
const qut = Math.floor((date.getMonth() + 3) / 3).toString(); // 季度
const opt: { [key: string]: string } = {
'Y+': date.getFullYear().toString(),
'm+': (date.getMonth() + 1).toString(),
'd+': date.getDate().toString(),
'H+': date.getHours().toString(),
'M+': date.getMinutes().toString(),
'S+': date.getSeconds().toString(),
'q+': quarter[qut], // 季度
};
// 处理格式中的特殊标记
format = format.replace(/(W+)/, (match) => match.length > 1 ? `${week[we]}` : week[we]);
format = format.replace(/(Q+)/, (match) => match.length === 4 ? `${quarter[qut]}季度` : quarter[qut]);
format = format.replace(/(Z+)/, (match) => match.length === 3 ? `${z}` : `${z}`);
// 替换日期格式中的部分
Object.keys(opt).forEach((key) => {
const reg = new RegExp(`(${key})`);
format = format.replace(reg, (match) => match.length === 1 ? opt[key] : opt[key].padStart(match.length, '0'));
});
return format;
}
}

View File

@ -0,0 +1,110 @@
import { common } from "@kit.AbilityKit";
import { OpenFiles } from "./OpenFiles";
import { filePreview } from "@kit.PreviewKit";
import { fileUri } from "@kit.CoreFileKit";
const MineType: Record<string, string> = {
'txt': 'text/plain',
'cpp': 'text/x-c++src',
'c': 'text/x-csrc',
'h': 'text/x-chdr',
'java': 'text/x-java',
'xhtml': 'application/xhtml+xml',
'xml': 'text/xml',
'html': 'text/html',
'htm': 'text/html',
'jpg': 'image/jpeg',
'png': 'image/png',
'gif': 'image/gif',
'webp': 'image/webp',
'bmp': 'image/bmp',
'svg': 'image/svg+xml',
'm4a': 'audio/mp4a-latm',
'aac': 'audio/aac',
'mp3': 'audio/mpeg',
'ogg': 'audio/ogg',
'wav': 'audio/x-wav',
'mp4': 'video/mp4',
'mkv': 'video/x-matroska',
'ts': 'video/mp2ts',
'pdf': 'application/pdf',
'doc': 'application/msword',
'docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'xls': 'application/vnd.ms-excel',
'xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'ppt': 'application/vnd.ms-powerpoint',
'pptx': 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
'csv': 'text/comma-separated-values',
}
export class FileMd5Utils {
static openFile(context: common.UIAbilityContext, fileName: string, filePath: string) {
if (FileMd5Utils.checkEndsWithInStringArray(fileName, ['.png', '.gif', '.jpg', '.jpeg', '.bmp'])) {
context.startAbility(OpenFiles.getImageFileIntent(FileMd5Utils.getUriFromPath(filePath)))
} else if (FileMd5Utils.checkEndsWithInStringArray(fileName, ['.htm', '.html', '.php', '.jsp'])) {
context.startAbility(OpenFiles.getHtmlFileIntent(FileMd5Utils.getUriFromPath(filePath)))
} else if (FileMd5Utils.checkEndsWithInStringArray(fileName, ['.jar', '.zip', '.rar', '.gz', '.img'])) {
context.startAbility(OpenFiles.getApkFileIntent(FileMd5Utils.getUriFromPath(filePath)))
} else if (FileMd5Utils.checkEndsWithInStringArray(fileName, ['.mp3', '.wav', '.ogg', '.midi'])) {
context.startAbility(OpenFiles.getAudioFileIntent(FileMd5Utils.getUriFromPath(filePath)))
} else if (FileMd5Utils.checkEndsWithInStringArray(fileName, ['.mp4', '.rmvb', '.avi', '.flv'])) {
context.startAbility(OpenFiles.getVideoFileIntent(FileMd5Utils.getUriFromPath(filePath)))
} else if (FileMd5Utils.checkEndsWithInStringArray(fileName, ['.txt','.java','.c','.cpp','.py','.xml','.json','.log'])) {
context.startAbility(OpenFiles.getTextFileIntent(FileMd5Utils.getUriFromPath(filePath)))
} else if (FileMd5Utils.checkEndsWithInStringArray(fileName, ['.pdf'])) {
context.startAbility(OpenFiles.getPdfFileIntent(FileMd5Utils.getUriFromPath(filePath)))
} else if (FileMd5Utils.checkEndsWithInStringArray(fileName, ['.doc', '.docx'])) {
context.startAbility(OpenFiles.getWordFileWant(FileMd5Utils.getUriFromPath(filePath)))
} else if (FileMd5Utils.checkEndsWithInStringArray(fileName, ['.xls', '.xlsx'])) {
context.startAbility(OpenFiles.getExcelFileIntent(FileMd5Utils.getUriFromPath(filePath)))
} else if (FileMd5Utils.checkEndsWithInStringArray(fileName, ['.ppt', '.pptx'])) {
context.startAbility(OpenFiles.getPPTFileIntent(FileMd5Utils.getUriFromPath(filePath)))
} else {
return false;
}
return true;
}
/**
* 检查文件后缀
*
* @param checkItsEnd
* @param fileEndings
* @return
*/
static checkEndsWithInStringArray(checkItsEnd: string, fileEndings: string[]): boolean {
for (let i = 0; i < fileEndings.length; i++) {
if (checkItsEnd.endsWith(fileEndings[i])) {
return true;
}
}
return false;
}
/**
* 获取文件的资源路径
* @param filePath 文件路径
* @returns file://开头的系统资源路径
*/
static getUriFromPath(filePath: string) {
if (filePath.startsWith('file:')) {
return filePath;
}
return fileUri.getUriFromPath(filePath);
}
static openPreview(context: Context, fileName: string, filePath: string) {
let fileInfo: filePreview.PreviewInfo = {
title: fileName,
uri: fileUri.getUriFromPath(filePath),
mimeType: FileMd5Utils.getMimeType(fileName)
};
return filePreview.openPreview(context, fileInfo);
}
static getMimeType(fileName: string) {
const fileType: string = fileName.substring(fileName.lastIndexOf('.') + 1)
return MineType[fileType] || ''
}
}

View File

@ -0,0 +1,96 @@
import { FileUtil } from "@pura/harmony-utils";
import fs from '@ohos.file.fs';
import { common } from "@kit.AbilityKit";
import { uniformTypeDescriptor } from '@kit.ArkData';
import { FileMd5Utils } from "./FileMd5Utils";
export class FileUtils {
public static ROOT_DIR: string
public static ID_CARD_DIR: string
public static FILE_DIR: string
public static IMAGE_DIR: string
public static LOG_DIR: string
constructor() {
}
/**
* 初始化应用路径
* @param uiContext
*/
public static init(context: Context) {
if (context) {
FileUtils.ROOT_DIR = context.filesDir;
FileUtils.ID_CARD_DIR = context.filesDir + "/IdCardPhoto";
FileUtils.FILE_DIR = context.filesDir + "/File";
FileUtils.IMAGE_DIR = context.filesDir + "/Image";
FileUtils.LOG_DIR = context.filesDir + "/Log";
}
}
public static createFileDir() {
if (!FileUtil.accessSync(FileUtils.ID_CARD_DIR)) {
FileUtil.mkdirSync(FileUtils.ID_CARD_DIR)
}
if (!FileUtil.accessSync(FileUtils.FILE_DIR)) {
FileUtil.mkdirSync(FileUtils.FILE_DIR)
}
if (!FileUtil.accessSync(FileUtils.IMAGE_DIR)) {
FileUtil.mkdirSync(FileUtils.IMAGE_DIR)
}
if (!FileUtil.accessSync(FileUtils.LOG_DIR)) {
FileUtil.mkdirSync(FileUtils.LOG_DIR)
}
}
public static async copyToLocal(src: string, dest: string): Promise<boolean> {
// 创建目标路径(示例使用应用缓存目录)
try {
// 打开输入输出流
let srcFile = await fs.open(src, fs.OpenMode.READ_ONLY);
let destFile = await fs.open(dest, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE);
// 执行复制操作
await fs.copyFile(srcFile.fd, destFile.fd);
fs.closeSync(srcFile.fd)
fs.closeSync(destFile.fd)
return true
// 关闭文件描述符
} catch (err) {
console.error(`文件复制失败: ${err.code}, ${err.message}`);
return false
}
}
private static MATCH_ARRAY: string[][] = [
["docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"],
[".", "application/msword"],
["xls", "application/vnd.ms-excel"],
["xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"],
["ppt", "application/vnd.ms-powerpoint"],
["pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation"],
["zip", "application/zip"],
["txt", "text/plain"],
["jpg", "image/jpeg"],
["jpeg", "image/jpeg"],
["png", "image/png"],
["gif", "image/gif"],
["mp3", "audio/mpeg"],
["mp4", "video/mp4"],
["m4u", "video/vnd.mpegurl"],
["m4v", "video/x-m4v"],
["avi", "video/x-msvideo"],
["pdf", "application/pdf"],
]
static async openWithThirdPartyApp(context: common.UIAbilityContext, filePath: string) {
// let fileExt = FileUtil.getFileExtention(filePath)
// let fileUri = FileUtil.getFileUri(filePath).toString();
FileMd5Utils.openFile(context, FileUtil.getFileName(filePath), filePath)
return
}
}

View File

@ -0,0 +1,143 @@
import { StringUtils } from "./StringUtils";
export class IdCardNumUtils {
/**
* 验证身份证号
* @param idCardNum 身份证号
* @returns true or false
*/
public static validateIdCardNum(idCardNum: string): boolean {
if (idCardNum == null) {
return false;
}
let idCardNumS = idCardNum.trim();
if (idCardNumS.length != 18) {
return false;
}
if (!IdCardNumUtils.checkCode(idCardNumS)) {
return false
}
const date = idCardNumS.substring(6, 14)
if (!IdCardNumUtils.checkDate(date)) {
return false
}
if (IdCardNumUtils.checkProv(idCardNumS.substring(0, 2))) {
return true
}
return false;
}
/**
* 数字验证
*
* @param val 需要验证的字符串
*/
public static isNum(val: string): boolean {
const reg = new RegExp('^[0-9]*$');
return val != null && "" != (val) && reg.test(val);
}
// 省份
public static checkProv(val: string) {
const pattern = /^[1-9][0-9]/
const provs: Record<number, string> = {
11: '北京',
12: '天津',
13: '河北',
14: '山西',
15: '内蒙古',
21: '辽宁',
22: '吉林',
23: '黑龙江 ',
31: '上海',
32: '江苏',
33: '浙江',
34: '安徽',
35: '福建',
36: '江西',
37: '山东',
41: '河南',
42: '湖北 ',
43: '湖南',
44: '广东',
45: '广西',
46: '海南',
50: '重庆',
51: '四川',
52: '贵州',
53: '云南',
54: '西藏 ',
61: '陕西',
62: '甘肃',
63: '青海',
64: '宁夏',
65: '新疆',
71: '台湾',
81: '香港',
82: '澳门'
}
if (pattern.test(val)) {
if (provs[val]) {
return true
}
}
return false
}
// 出生日期
private static checkDate(val: string) {
const pattern =
/^(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)$/
if (pattern.test(val)) {
const year = val.substring(0, 4)
const month = val.substring(4, 6)
const date = val.substring(6, 8)
const date2 = new Date(year + '-' + month + '-' + date)
if (date2 && date2.getMonth() === parseInt(month) - 1) {
return true
}
}
return false
}
// 校验码校验
private static checkCode(val: string) {
const p =
/^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/
const factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
const parity = [1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2]
const code = val.substring(17)
if (p.test(val)) {
let sum = 0
for (let i = 0; i < 17; i++) {
sum += Number(val.charAt(i)) * factor[i]
}
if (parity[sum % 11].toString() === code.toUpperCase()) {
return true
}
}
return false
}
public static isCarNumberNO(carNumber: string): boolean {
if (StringUtils.isNullOrEmpty(carNumber)) {
return false;
}
//两车同用
const carTreg =
/^([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[a-zA-Z](([ADF]((?![IO])[a-zA-Z0-9](?![IO]))[0-9]{4})|([0-9]{5}[ADF]))|[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-Z0-9]{4}[A-Z0-9挂学警港澳]{1})$/
return carTreg.test(carNumber);
}
//简称
public static isJc(cph: string): boolean {
if (StringUtils.isNullOrEmpty(cph)) {
return false;
}
const ss = /^[A-Z]$/;
return ss.test(cph);
}
}

View File

@ -0,0 +1,36 @@
import { util } from "@kit.ArkTS";
import { StrUtil } from "@pura/harmony-utils/src/main/ets/utils/StrUtil";
export class IdGeneratedUtils {
private static idGeneratedUtils = new IdGeneratedUtils("");
private static idCardNum: string = "";
private constructor(idCardNum: string) {
IdGeneratedUtils.idCardNum = idCardNum
}
public static getInstance(idCardNum: string): IdGeneratedUtils {
if (IdGeneratedUtils.idGeneratedUtils == null || IdGeneratedUtils.idCardNum !== idCardNum) {
IdGeneratedUtils.idGeneratedUtils = new IdGeneratedUtils(idCardNum)
}
return IdGeneratedUtils.idGeneratedUtils;
}
public generatedRandomID(): string {
let uuid = util.generateRandomUUID(false).replaceAll("-", "").replaceAll("-", "");
if (StrUtil.isNotEmpty(IdGeneratedUtils.idCardNum)) {
let start = IdGeneratedUtils.idCardNum.substring(0, IdGeneratedUtils.idCardNum.length - 1);
let end = IdGeneratedUtils.idCardNum.substring(IdGeneratedUtils.idCardNum.length - 1);
let startStr = parseInt(start).toString(16).toUpperCase()
return startStr + end + uuid + (this.getRandomInt(1,1000) + 1000);
}else {
return Date.now()+uuid+ (this.getRandomInt(1,1000) + 1000);
}
}
// 生成指定范围的随机整数
getRandomInt(min: number, max: number): number {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
}

View File

@ -0,0 +1,108 @@
import { CryptoJS } from '@ohos/crypto-js'
import { buffer, util } from '@kit.ArkTS';
/**
* DES 加密工具类ArkTS 版本)
*/
class JiaMi {
/**
* 使用 key 对 data 进行 DES 加密,并返回 Base64 编码字符串
* @param data 待加密的字符串UTF-8
* @param id 用户ID
* @param secret 密钥
* @returns Base64 编码的加密字符串,失败返回 null
*/
desCrypto(data: string, id: string, secret: string): string | null {
const key = `${id}:${secret}`;
return this.desCryptoWithKey(data, key);
}
/**
* 使用指定 key 对 data 进行 DES 加密
* @param data 待加密的字符串
* @param key 密钥字符串
* @returns Base64 编码的加密字符串,失败返回 null
*/
desCryptoWithKey(data: string, key: string) {
const keyHex = CryptoJS.enc.Utf8.parse(key);
const encrypted = CryptoJS.DES.encrypt(data, keyHex, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
return encrypted.toString(); // 默认就是 Base64
let new_key = CryptoJS.enc.Utf8.parse(key);
// let iv:CryptoJS.lib.WordArray = CryptoJS.lib.WordArray.create(uintArray)
let encryptd = CryptoJS.DES.encrypt(data, new_key, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7,
// iv:iv
})
let words = encryptd.ciphertext;
let sigBytes = words.sigBytes;
let uint8Array = new Uint8Array(sigBytes);
for (let i = 0; i < sigBytes; i++) {
uint8Array[i] = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
}
return new util.Base64Helper().encodeToStringSync(uint8Array)
// let jiMw = new util.Base64Helper().decodeSync(jiemiDa)
return encryptd.toString();
}
/**
* DES 解密Base64 输入,返回字符串)
* @param encryptData Base64 编码的密文 03962723612
* @param key 密钥
* @returns 明文字符串
* @throws 错误信息
*/
decrypt(encryptData: string, key: string): string {
let new_key = CryptoJS.enc.Utf8.parse(key);
let uintArray = new Uint8Array([1,2,3,4,5,6,7,8])
let iv:CryptoJS.lib.WordArray = CryptoJS.lib.WordArray.create(uintArray)
let bytes = CryptoJS.DES.decrypt(encryptData, new_key, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7,
// iv:iv
})
let result = bytes.toString(CryptoJS.enc.Utf8);
return result.toString();
}
/**
* 使用 id 和 secret 解密
* @param encryptData Base64 密文
* @param id 用户ID
* @param secret 密钥
* @returns 明文字符串
* @throws 错误信息
*/
decryptWithId(encryptData: string, id: string, secret: string): string {
const key = `${id}:${secret}`;
return this.decrypt(encryptData, key);
}
/**
* 辅助函数:将密钥补全或截断为 8 字节DES 要求)
* @param key 原始密钥字符串
* @returns 8 字节长度的字符串
*/
private static padKeyTo8Bytes(key: string): string {
let keyStr = key;
if (keyStr.length < 8) {
// 不足8字节补空格或可改为补0或其他
keyStr = keyStr.padEnd(8, ' ');
} else if (keyStr.length > 8) {
// 超过8字节截断
keyStr = keyStr.substring(0, 8);
}
return keyStr;
}
}
export default JiaMi;

View File

@ -0,0 +1,93 @@
import { Want, wantConstant } from "@kit.AbilityKit";
export class OpenFiles {
static getWordFileWant(filePath: string) {
let wantInfo: Want = {
uri: filePath,
type: 'application/msword',
flags: wantConstant.Flags.FLAG_AUTH_READ_URI_PERMISSION,
}
return wantInfo
}
static getPdfFileIntent(filePath: string) {
let wantInfo: Want = {
uri: filePath,
type: 'application/pdf',
flags: wantConstant.Flags.FLAG_AUTH_READ_URI_PERMISSION,
}
return wantInfo
}
static getHtmlFileIntent(filePath: string) {
let wantInfo: Want = {
uri: filePath,
type: 'text/html',
flags: wantConstant.Flags.FLAG_AUTH_READ_URI_PERMISSION,
}
return wantInfo
}
static getApkFileIntent(filePath: string) {
let wantInfo: Want = {
uri: filePath,
type: 'application/x-rar-compressed',
flags: wantConstant.Flags.FLAG_AUTH_READ_URI_PERMISSION,
}
return wantInfo
}
static getAudioFileIntent(filePath: string) {
let wantInfo: Want = {
uri: filePath,
type: 'audio/mpeg',
flags: wantConstant.Flags.FLAG_AUTH_READ_URI_PERMISSION,
}
return wantInfo
}
static getVideoFileIntent(filePath: string) {
let wantInfo: Want = {
uri: filePath,
type: 'video/mp4',
flags: wantConstant.Flags.FLAG_AUTH_READ_URI_PERMISSION,
}
return wantInfo
}
static getTextFileIntent(filePath: string) {
let wantInfo: Want = {
uri: filePath,
type: 'text/plain',
flags: wantConstant.Flags.FLAG_AUTH_READ_URI_PERMISSION,
}
return wantInfo
}
static getExcelFileIntent(filePath: string) {
let wantInfo: Want = {
uri: filePath,
type: 'application/vnd.ms-excel',
flags: wantConstant.Flags.FLAG_AUTH_READ_URI_PERMISSION,
}
return wantInfo
}
static getPPTFileIntent(filePath: string) {
let wantInfo: Want = {
uri: filePath,
type: 'application/vnd.ms-powerpoint',
flags: wantConstant.Flags.FLAG_AUTH_READ_URI_PERMISSION,
}
return wantInfo
}
static getImageFileIntent(filePath: string) {
let wantInfo: Want = {
uri: filePath,
type: 'image/jpeg',
flags: wantConstant.Flags.FLAG_AUTH_READ_URI_PERMISSION,
}
return wantInfo
}
}

View File

@ -0,0 +1,26 @@
import image from '@ohos.multimedia.image';
import buffer from '@ohos.buffer';
export class PixelMapUtils {
static async pixelMapToBase64(pixelMap: image.PixelMap): Promise<string> {
// 1. 创建图像打包器
const imagePacker = image.createImagePacker();
// 2. 设置打包选项 (PNG格式)
const packOpts: image.PackingOption = {
format: "image/png",
quality: 100 // 最高质量
};
// 3. 打包到内存缓冲区
const arrayBuffer = await imagePacker.packing(pixelMap, packOpts);
// 4. 转换为Base64
const base64Data = buffer.from(arrayBuffer).toString('base64');
// 5. 添加Data URL前缀
return base64Data;
}
}

View File

@ -0,0 +1,21 @@
import { bundleManager } from "@kit.AbilityKit";
export class ReadLocationAppUtils {
// 获取所有已安装的应用包信息
// async getAllApplications() {
// try {
// const bundleInfos = await bundleManager.getAllBundleInfo(bundleManager.BundleFlag.GET_BUNDLE_DEFAULT);
// console.log('Installed applications:', bundleInfos);
//
// // 遍历应用信息
// bundleInfos.forEach(bundleInfo => {
// console.log('Bundle Name:', bundleInfo.name);
// console.log('Bundle Label:', bundleInfo.label);
// console.log('Version Code:', bundleInfo.versionCode);
// });
// } catch (error) {
// console.error('Failed to get bundle info:', error);
// }
// }
}

View File

@ -0,0 +1 @@
import { StringUtils } from "./StringUtils"

View File

@ -0,0 +1,192 @@
import { resourceManager } from "@kit.LocalizationKit";
import { IdCardNumUtils } from "./IdCardNumUtils";
export class StringUtils {
/**
* 获取字符串, 如果为空则返回默认值, 如果非空则返回该值并拼接endStr到末尾
* @param value 要获取的字符串
* @param defValue 默认值
* @param endStr 要拼接的字符串
* @returns value+endStr || defValue
*/
static get(value: string | Object | undefined | null, defValue: string, endStr?: string): string {
if (StringUtils.isNullOrEmpty(value)) {
return defValue;
}
if (endStr) {
return String(value) + endStr;
}
return String(value);
}
/**
* 判断值是否为空
* @param value
* @returns
*/
static isNullOrEmpty(value: string | Object | undefined | null): boolean {
return value == null || value == undefined || value.toString().trim().length < 1;
}
/**
* 获取数字, 如果为空或者不是数字类型的字符则返回默认值, 如果是number或者数字字符串者返回该值的number值
* @param value 要获取的字符串
* @param defValue 默认值
* @returns value|| defValue
*/
static getNumber(value: string | number | null | undefined, defValue: number = 0): number {
// 处理空值和未定义情况
if (value === null || value === undefined) {
return defValue;
}
// 处理数字类型直接返回
if (typeof value === 'number') {
return value;
}
// 处理字符串类型
if (typeof value === 'string') {
// 去除首尾空格
const trimmedValue = value.trim();
// 正则验证数字格式(包含整数、小数、科学计数法)
const isNumeric = /^[-+]?(\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)?$/.test(trimmedValue);
// 有效数字则进行转换
if (isNumeric) {
const numberValue = Number(trimmedValue);
return Number.isNaN(numberValue) ? defValue : numberValue;
}
}
// 非数字类型返回默认值
return defValue;
}
/**
*
* @param str 待查找源字符串
* @param char 待匹配的目标
* @returns true 表示包含 false 表示不包含
*/
static containsChar(str: string, char: string): boolean {
//当 str 内含有 char 则返回 char所在位置索引 即 返回值大与 -1
return str.indexOf(char) > -1;
}
/**
* 去除JSON字符串 转义字符
* @param value 需要转译的字符
* @return 转译后的JSON格式数据
*/
public static toJsonParaphrase(value: string): string {
if (value == null || value.length < 1) {
return "";
}
let isJx = true;
while (isJx) {
//去除 \\
if (StringUtils.containsChar(value, "\\\\")) {
value = value.replace("\\\\", "").replaceAll("\\\\", "");
}
isJx = StringUtils.containsChar(value, "\\\\");
}
isJx = true;
while (isJx) {
//转 \" 替换为 "
if (StringUtils.containsChar(value, "\\\"")) {
value = value.replace("\\\"", "\"").replaceAll("\\\"", "\"");
}
isJx = StringUtils.containsChar(value, "\\\"");
}
isJx = true;
while (isJx) {
//转 "{ 替换为 {
if (StringUtils.containsChar(value, "\"{")) {
value = value.replace("\"{", "{").replaceAll("\"{", "{");
}
isJx = StringUtils.containsChar(value, "\"{");
}
isJx = true;
while (isJx) {
//转 }" 替换为 }
if (StringUtils.containsChar(value, "}\"")) {
value = value.replace("}\"", "}").replaceAll("}\"", "}");
}
isJx = StringUtils.containsChar(value, "}\"");
}
isJx = true;
while (isJx) {
//转 "[ 替换为 [
if (StringUtils.containsChar(value, "\"[")) {
value = value.replace("\"[", "[").replaceAll("\"[", "[");
}
isJx = StringUtils.containsChar(value, "\"[");
}
isJx = true;
while (isJx) {
//转 ]" 替换为 ]
if (StringUtils.containsChar(value, "]\"")) {
value = value.replace("]\"", "]").replaceAll("]\"", "]");
}
isJx = StringUtils.containsChar(value, "]\"");
}
return value;
}
/**
* 生成指定范围内的随机数
* @param min 最小数(包含)
* @param max 最大数(不包含)
* @return 随机数
*/
public static randomNumber(min: number, max: number): number {
return Math.floor(Math.random() * (max - min) + min);
}
/**
* 获取资源字符串
* @param context
* @param resource
* @returns
*/
public static getResourceString(context: Context, resource: Resource): string {
let resourceString: string = '';
try {
resourceString = context.resourceManager.getStringSync(resource.id);
} catch (error) {
console.error('getResourceString err:' + JSON.stringify(error));
}
return resourceString;
}
/**
* 检查16进制颜色
* @param colorStr
* @returns
*/
public static isValidHexColor(colorStr: string): boolean {
// 正则表达式匹配标准格式
const hexRegex = /^#?([A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})$/
return hexRegex.test(colorStr)
}
/**
* 严格检查16进制颜色
* @param colorStr
* @returns
*/
public static strictCheckHexColor(colorStr: string): boolean {
if (!StringUtils.isValidHexColor(colorStr)) return false
try {
// 移除#符号并补齐透明度通道
const cleanStr = colorStr.replace('#', '')
const fullHex = cleanStr.length === 6 ? `FF${cleanStr}` : cleanStr
// 尝试转换为数值验证有效性
const colorValue = parseInt(fullHex, 16)
return !isNaN(colorValue) && colorValue >= 0
} catch {
return false
}
}
}

View File

@ -0,0 +1,19 @@
import { promptAction } from "@kit.ArkUI";
export class ToastUtils{
public static toastCenter(msg:string|Resource){
promptAction.showToast({
message: msg,
duration: 1200,
alignment:Alignment.Center
})
}
public static toastBottom(msg:string|Resource){
promptAction.showToast({
message: msg,
duration: 1200,
bottom: 100
})
}
}

View File

@ -0,0 +1,26 @@
import vibrator from "@ohos.vibrator"
export class VibratorUtils{
static startVibrator(){
vibrator.startVibration({type:"time",duration:1000},{usage:'alarm'})
.then(()=>{
console.warn("开始震动成功!")
})
.catch((error:Error)=>{
console.error("开始震动失败:"+JSON.stringify(error))
})
}
static stopVibrator(){
vibrator.stopVibration()
.then(()=>{
console.warn("停止震动成功!")
})
.catch((error:Error)=>{
console.error("停止震动失败:"+JSON.stringify(error))
})
}
}

157
entry/src/main/module.json5 Normal file
View File

@ -0,0 +1,157 @@
{
"module": {
"name": "entry",
"type": "entry",
"description": "$string:module_desc",
"mainElement": "EntryAbility",
"srcEntry": './ets/app/RuanseeAbilityStag.ets',
"deviceTypes": [
"phone"
],
"deliveryWithInstall": true,
"installationFree": false,
"pages": "$profile:main_pages",
"requestPermissions": [
{
"name": "ohos.permission.GET_BUNDLE_INFO",
"reason": "$string:app_name",
"usedScene": {
"abilities": [
".EntryAbility"
],
"when": "inuse"
}
},
{
"name": "ohos.permission.ACCELEROMETER",
"reason": "$string:app_name",
"usedScene": {
"abilities": [
".EntryAbility"
],
"when": "inuse"
}
},
{
"name": "ohos.permission.INTERNET",
"usedScene": {
"when": "always"
}
},
{
"name": "ohos.permission.GET_NETWORK_INFO"
},
// 震动权限
{
"name": 'ohos.permission.VIBRATE',
"reason": "$string:app_name",
"usedScene": {
"abilities": [
".EntryAbility"
],
"when": "inuse"
}
},
{
"name": "ohos.permission.CAMERA",
"reason": "$string:app_name",
"usedScene": {
"abilities": [
"EntryAbility"
]
}
},
{
"name": "ohos.permission.READ_MEDIA",
"reason": "$string:app_name",
"usedScene": {
"abilities": [
"EntryAbility"
]
}
},
{
"name": "ohos.permission.WRITE_MEDIA",
"reason": "$string:app_name",
"usedScene": {
"abilities": [
"EntryAbility"
]
}
},
{
"name": "ohos.permission.LOCATION",
"reason": "$string:app_name",
"usedScene": {
"abilities": [
"EntryAbility"
],
"when": "inuse"
}
},
{
"name": "ohos.permission.APPROXIMATELY_LOCATION",
"reason": "$string:app_name",
"usedScene": {
"abilities": [
"EntryAbility"
],
"when": "inuse"
}
},
{
"name": "ohos.permission.LOCATION_IN_BACKGROUND",
"reason": "$string:app_name",
"usedScene": {
"abilities": [
"EntryAbility"
],
"when": "inuse"
}
}
],
"abilities": [
{
"name": "EntryAbility",
"srcEntry": "./ets/entryability/EntryAbility.ets",
"description": "$string:EntryAbility_desc",
"icon": "$media:icon_applogin",
"label": "$string:EntryAbility_label",
"startWindowIcon": "$media:icon_applogin",
"startWindowBackground": "$color:start_window_background",
"exported": true,
"skills": [
{
"entities": [
"entity.system.home"
],
"actions": [
"action.system.home",
"ohos.want.action.viewData"
],
"uris": [
{
"scheme": "file",
"type": "application/\*"
}
]
}
]
}
],
"extensionAbilities": [
{
"name": "EntryBackupAbility",
"srcEntry": "./ets/entrybackupability/EntryBackupAbility.ets",
"type": "backup",
"exported": false,
"metadata": [
{
"name": "ohos.extension.backup",
"resource": "$profile:backup_config"
}
],
}
]
}
}

View File

@ -0,0 +1,301 @@
{
"color": [
{
"name": "start_window_background",
"value": "#FFFFFF"
},
{
"name": "total_background",
"value": "#FF1954EE"
},
{
"name": "hc_an_bk",
"value": "#FF2170eb"
},
{
"name": "hc_an_bj",
"value": "#12ffffff"
},
{
"name": "page_background",
"value": "#F3F7FA"
},
{
"name": "divider_background",
"value": "#FFB8B8B8"
},
{
"name": "time_background",
"value": "#a0C7CDD0"
},
{
"name": "read",
"value": "#FFEE1939"
},
{
"name": "white",
"value": "#FFFFFF"
},
{
"name": "green",
"value": "#FF19EE35"
},
{
"name": "grad",
"value": "#FF646464"
},
{
"name": "black",
"value": "#FF1D1D1D"
},
{
"name": "bull",
"value": "#1264DE"
},
{
"name": "colorRed9",
"value": "#e63119"
},
{
"name": "colorBluen12",
"value": "#5BC5D5E2"
},
{
"name": "detailsBackdrop",
"value": "#fff4f8fa"
},
{
"name": "peopletype1",
"value": "#c8f49f"
},
{
"name": "peopletype2",
"value": "#a3d273"
},
{
"name": "peopletype3",
"value": "#06e45f"
},
{
"name": "peopletype4",
"value": "#fae2ba"
},
{
"name": "peopletype5",
"value": "#e9bf95"
},
{
"name": "peopletype6",
"value": "#e4872a"
},
{
"name": "peopletype7",
"value": "#FFE99595"
},
{
"name": "peopletype8",
"value": "#FFE42A2A"
},
{
"name": "state_styles_pressed",
"value": "#868B95"
},
{
"name": "state_styles_normal",
"value": "#B5B7BF"
},
{
"name": "delete_key_background",
"value": "#A8ABB7"
},
{
"name": "delete_key_shadow",
"value": "#76787C"
},
{
"name": "search_background_normal",
"value": "#0A59F7"
},
{
"name": "font_background_white",
"value": "#FFFFFF"
},
{
"name": "keyboard_background_color",
"value": "#DADFE6"
},
{
"name": "search_background_color",
"value": "#F2F2F2"
},
{
"name": "search_font_color",
"value": "#000000"
},
{
"name": "font_color",
"value": "#222222"
},
{
"name": "main_tj_a",
"value": "#FFD5EBF5"
},
{
"name": "main_tj_b",
"value": "#E9FDE5"
},
{
"name": "main_tj_c",
"value": "#FDF9E5"
},
{
"name": "main_tj_d",
"value": "#FF93C1F1"
},
{
"name": "colorBluen8",
"value": "#0A87CC"
},
{
"name": "colorBluen7",
"value": "#0785c9"
},
{
"name": "colorBluen6",
"value": "#1f94d3"
},
{
"name": "colorBluen5",
"value": "#67bdec"
},
{
"name": "colorBluen4",
"value": "#67bbe9"
},
{
"name": "colorBluen3",
"value": "#80cdf7"
},
{
"name": "colorBluen2",
"value": "#a7defc"
},
{
"name": "colorBluen1",
"value": "#e1f3fd"
},
{
"name": "colorBluen",
"value": "#E6F5FF"
},
{
"name": "colorGreen1",
"value": "#e8f5e9"
},
{
"name": "colorGreen2",
"value": "#c8e6c9"
},
{
"name": "colorGreen3",
"value": "#a5d6a7"
},
{
"name": "colorGreen4",
"value": "#81c784"
},
{
"name": "colorGreen5",
"value": "#66bb6a"
},
{
"name": "colorGreen6",
"value": "#43a047"
},
{
"name": "colorGreen7",
"value": "#388e3c"
},
{
"name": "colorGreen",
"value": "#2DED36"
},
{
"name": "colorYellow",
"value": "#F19149"
},
{
"name": "colorYellow1",
"value": "#fff3e0"
},
{
"name": "colorYellow2",
"value": "#ffe0b2"
},
{
"name": "colorYellow3",
"value": "#ffcc80"
},
{
"name": "colorYellow4",
"value": "#ffb74d"
},
{
"name": "colorYellow5",
"value": "#ffa726"
},
{
"name": "colorYellow6",
"value": "#fb8c00"
},
{
"name": "colorYellow7",
"value": "#f57c00"
},
{
"name": "colorYellow8",
"value": "#ff8304"
},
{
"name": "colorGrey1",
"value": "#f5f5f5"
},
{
"name": "colorGreyte",
"value": "#e5e5e5"
},
{
"name": "colorGrey2",
"value": "#eeeeee"
},
{
"name": "colorGrey3",
"value": "#e8e8e8"
},
{
"name": "colorGrey4",
"value": "#b2b2b2"
},
{
"name": "colorGrey5",
"value": "#888888"
},
{
"name": "colorGrey6",
"value": "#626262"
},
{
"name": "colorGrey7",
"value": "#323232"
},
{
"name": "colorGrey8",
"value": "#fe131313"
}
]
}

View File

@ -0,0 +1,360 @@
{
"float": [
{
"name": "down_image_size",
"value": "36vp"
},
{
"name": "down_image_margin",
"value": "10vp"
},
{
"name": "search_height",
"value": "40vp"
},
{
"name": "search_margin",
"value": "16vp"
},
{
"name": "search_border_radius",
"value": "20vp"
},
{
"name": "default_1",
"value": "1vp"
},
{
"name": "default_2",
"value": "2vp"
},
{
"name": "default_3",
"value": "3vp"
},
{
"name": "default_5",
"value": "5vp"
},
{
"name": "default_6",
"value": "6vp"
},
{
"name": "default_8",
"value": "8vp"
},
{
"name": "default_10",
"value": "10vp"
},
{
"name": "default_12",
"value": "12vp"
},
{
"name": "default_14",
"value": "14vp"
},
{
"name": "default_15",
"value": "15vp"
},
{
"name": "default_16",
"value": "16vp"
},
{
"name": "default_18",
"value": "18vp"
},
{
"name": "default_20",
"value": "20vp"
},
{
"name": "default_22",
"value": "22vp"
},
{
"name": "default_23",
"value": "23vp"
},
{
"name": "default_24",
"value": "24vp"
},
{
"name": "default_25",
"value": "25vp"
},
{
"name": "default_26",
"value": "26vp"
},
{
"name": "default_28",
"value": "28vp"
},
{
"name": "default_30",
"value": "30vp"
},
{
"name": "default_32",
"value": "32vp"
},
{
"name": "default_35",
"value": "35vp"
},
{
"name": "default_36",
"value": "36vp"
},
{
"name": "default_38",
"value": "38vp"
},
{
"name": "default_40",
"value": "40vp"
},
{
"name": "default_43",
"value": "43vp"
},
{
"name": "default_45",
"value": "45vp"
},
{
"name": "default_46",
"value": "46vp"
},
{
"name": "default_47",
"value": "47vp"
},
{
"name": "default_48",
"value": "48vp"
},
{
"name": "default_52",
"value": "52vp"
},
{
"name": "default_50",
"value": "50vp"
},
{
"name": "default_58",
"value": "58vp"
},
{
"name": "default_60",
"value": "60vp"
},
{
"name": "default_63",
"value": "63vp"
},
{
"name": "default_68",
"value": "68vp"
},
{
"name": "default_66",
"value": "66vp"
},
{
"name": "default_72",
"value": "72vp"
},
{
"name": "default_80",
"value": "80vp"
},
{
"name": "default_84",
"value": "84vp"
},
{
"name": "default_88",
"value": "88vp"
},
{
"name": "default_90",
"value": "90vp"
},
{
"name": "default_92",
"value": "92vp"
},
{
"name": "default_94",
"value": "94vp"
},
{
"name": "default_98",
"value": "98vp"
},
{
"name": "default_100",
"value": "100vp"
},
{
"name": "default_105",
"value": "105vp"
},
{
"name": "default_110",
"value": "110vp"
},
{
"name": "default_115",
"value": "115vp"
},
{
"name": "default_120",
"value": "120vp"
},
{
"name": "default_125",
"value": "125vp"
},
{
"name": "default_130",
"value": "130vp"
},
{
"name": "default_150",
"value": "150vp"
},
{
"name": "default_160",
"value": "160vp"
},
{
"name": "default_170",
"value": "170vp"
},
{
"name": "default_180",
"value": "180vp"
},
{
"name": "default_185",
"value": "185vp"
},
{
"name": "default_190",
"value": "190vp"
},
{
"name": "default_200",
"value": "200vp"
},
{
"name": "default_240",
"value": "240vp"
},
{
"name": "default_300",
"value": "300vp"
},
{
"name": "default_350",
"value": "350vp"
},
{
"name": "default_400",
"value": "400vp"
},
{
"name": "delete_image_size",
"value": "30vp"
},
{
"name": "shift_image_size",
"value": "30vp"
},
{
"name": "keyboard_height",
"value": "255vp"
},
{
"name": "keyboard_height_2",
"value": "290vp"
},
{
"name": "comm_image_radius",
"value": "4vp"
},
{
"name": "text_size_5",
"value": "5fp"
},
{
"name": "text_size_6",
"value": "6fp"
},
{
"name": "text_size_8",
"value": "8fp"
},
{
"name": "text_size_10",
"value": "10fp"
},
{
"name": "text_size_12",
"value": "12fp"
},
{
"name": "text_size_14",
"value": "14fp"
},
{
"name": "text_size_15",
"value": "15fp"
},
{
"name": "text_size_16",
"value": "16fp"
},
{
"name": "text_size_18",
"value": "18fp"
},
{
"name": "text_size_20",
"value": "20fp"
},
{
"name": "text_size_22",
"value": "22fp"
},
{
"name": "text_size_24",
"value": "24fp"
},
{
"name": "text_size_28",
"value": "28fp"
},
{
"name": "text_size_32",
"value": "32fp"
},
{
"name": "text_size_38",
"value": "38fp"
},
{
"name": "text_size_42",
"value": "42fp"
}
]
}

View File

@ -0,0 +1,72 @@
{
"string": [
{
"name": "module_desc",
"value": "module description"
},
{
"name": "EntryAbility_desc",
"value": "description"
},
{
"name": "EntryAbility_label",
"value": "个人中心"
},
{
"name": "ownership_dept",
"value": "安徽省公安厅"
},
{
"name": "title_PendingMsg",
"value": "待办消息"
},
{
"name": "title_Workbench",
"value": "工作台"
},
{
"name": "title_About",
"value": "关于"
},
{
"name": "title_Feedback",
"value": "意见反馈"
},
{
"name": "loading_hint",
"value": "正在加载,请稍后..."
},
{
"name": "title_select_app",
"value": "选择应用"
},
{
"name": "title_my_feedback",
"value": "我的反馈"
},
{
"name": "title_feedback_details",
"value": "反馈详情"
},
{
"name": "title_application_guide",
"value": "应用指南"
},
{
"name": "title_guide_details",
"value": "指南详情"
},
{
"name": "title_user_info",
"value": "个人中心"
},
{
"name": "title_frequently_questions",
"value": "常见问题"
},
{
"name": "title_msg_details",
"value": "消息详情"
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 407 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 392 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Some files were not shown because too many files have changed in this diff Show More