Initial commit: 风影 OA 全栈源码(API/Web/Flutter/IM)
含 Phase 1.1 IM seq 排序、断线重连、多端已读同步与微信式语音转文字 UI。 排除 node_modules、构建产物、安装包与 .env 密钥。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"apiType": "stageMode",
|
||||
"buildOption": {
|
||||
"resOptions": {
|
||||
"copyCodeResource": {
|
||||
"enable": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"buildOptionSet": [
|
||||
{
|
||||
"name": "release",
|
||||
"arkOptions": {
|
||||
"obfuscation": {
|
||||
"ruleOptions": {
|
||||
"enable": false,
|
||||
"files": []
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"targets": [
|
||||
{ "name": "default" }
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import { hapTasks } from '@ohos/hvigor-ohos-plugin';
|
||||
|
||||
export default {
|
||||
system: hapTasks,
|
||||
plugins: []
|
||||
};
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "entry",
|
||||
"version": "1.0.0",
|
||||
"description": "风影智慧办公",
|
||||
"main": "",
|
||||
"author": "",
|
||||
"license": "Proprietary",
|
||||
"dependencies": {}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
import { AbilityConstant, UIAbility, Want, abilityAccessCtrl, Permissions, common } from '@kit.AbilityKit';
|
||||
import { window } from '@kit.ArkUI';
|
||||
import { BusinessError } from '@kit.BasicServicesKit';
|
||||
import { hilog } from '@kit.PerformanceAnalysisKit';
|
||||
import { notificationManager } from '@kit.NotificationKit';
|
||||
import { pushService } from '@kit.PushKit';
|
||||
|
||||
const TAG = 'FengyingOA';
|
||||
const PERMS: Permissions[] = [
|
||||
'ohos.permission.CAMERA',
|
||||
'ohos.permission.MICROPHONE',
|
||||
'ohos.permission.APPROXIMATELY_LOCATION',
|
||||
'ohos.permission.LOCATION',
|
||||
'ohos.permission.READ_IMAGEVIDEO',
|
||||
'ohos.permission.WRITE_IMAGEVIDEO',
|
||||
];
|
||||
|
||||
export default class EntryAbility extends UIAbility {
|
||||
onCreate(want: Want, _launchParam: AbilityConstant.LaunchParam): void {
|
||||
AppStorage.setOrCreate('pushToken', '');
|
||||
AppStorage.setOrCreate('launchUri', want?.uri ?? '');
|
||||
notificationManager.requestEnableNotification(this.context).catch((err: BusinessError) => {
|
||||
hilog.warn(0x0000, TAG, 'notify perm %{public}s', JSON.stringify(err));
|
||||
});
|
||||
pushService.getToken().then((token: string) => {
|
||||
if (token) {
|
||||
AppStorage.setOrCreate('pushToken', token);
|
||||
hilog.info(0x0000, TAG, 'push token ok');
|
||||
}
|
||||
}).catch((err: BusinessError) => {
|
||||
hilog.error(0x0000, TAG, 'getToken %{public}d %{public}s', err.code, err.message);
|
||||
});
|
||||
}
|
||||
|
||||
onNewWant(want: Want): void {
|
||||
if (want?.uri) {
|
||||
AppStorage.setOrCreate('launchUri', want.uri);
|
||||
}
|
||||
}
|
||||
|
||||
onWindowStageCreate(windowStage: window.WindowStage): void {
|
||||
windowStage.loadContent('pages/Index').then(() => {
|
||||
this.askUserPerms();
|
||||
}).catch((err: BusinessError) => {
|
||||
hilog.error(0x0000, TAG, 'loadContent %{public}s', JSON.stringify(err));
|
||||
});
|
||||
}
|
||||
|
||||
private askUserPerms(): void {
|
||||
const ctx = this.context as common.UIAbilityContext;
|
||||
abilityAccessCtrl.createAtManager()
|
||||
.requestPermissionsFromUser(ctx, PERMS)
|
||||
.catch((err: BusinessError) => {
|
||||
hilog.warn(0x0000, TAG, 'user perm %{public}s', JSON.stringify(err));
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
import { webview } from '@kit.ArkWeb';
|
||||
import { hilog } from '@kit.PerformanceAnalysisKit';
|
||||
|
||||
const OA_URL = 'https://oa.fysxkj.com';
|
||||
const TAG = 'FengyingOA';
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct Index {
|
||||
controller: webview.WebviewController = new webview.WebviewController();
|
||||
@StorageLink('pushToken') pushToken: string = '';
|
||||
@StorageLink('launchUri') launchUri: string = '';
|
||||
|
||||
build() {
|
||||
Column() {
|
||||
Web({ src: OA_URL, controller: this.controller })
|
||||
.width('100%')
|
||||
.layoutWeight(1)
|
||||
.javaScriptAccess(true)
|
||||
.domStorageAccess(true)
|
||||
.fileAccess(true)
|
||||
.geolocationAccess(true)
|
||||
.mediaPlayGestureAccess(true)
|
||||
.onGeolocationShow((event) => {
|
||||
event.geolocation.invoke(event.origin, true, false);
|
||||
})
|
||||
.onPermissionRequest((event) => {
|
||||
event.request.grant(event.request.getAccessibleResource());
|
||||
})
|
||||
.onPageEnd(() => {
|
||||
this.injectNative();
|
||||
})
|
||||
}
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
}
|
||||
|
||||
private injectNative(): void {
|
||||
const token = this.pushToken.replace(/\\/g, '\\\\').replace(/'/g, "\\'");
|
||||
const deep = this.launchUri.replace(/\\/g, '\\\\').replace(/'/g, "\\'");
|
||||
const js = `
|
||||
(function(){
|
||||
window.__fyPushToken='${token}';
|
||||
window.__fyPushVendor='huawei';
|
||||
window.__fyDeepLink='${deep}';
|
||||
function once(){
|
||||
var t=sessionStorage.getItem('accessToken');
|
||||
if(!t || !window.__fyPushToken) return;
|
||||
if(window.__fyPushSent===t+window.__fyPushToken) return;
|
||||
window.__fyPushSent=t+window.__fyPushToken;
|
||||
fetch('/api/v1/push/devices',{
|
||||
method:'POST',
|
||||
headers:{'Content-Type':'application/json','Authorization':'Bearer '+t},
|
||||
body:JSON.stringify({vendor:'huawei',regId:window.__fyPushToken,brand:'HarmonyOS',model:'phone'})
|
||||
}).catch(function(){});
|
||||
}
|
||||
once();
|
||||
setInterval(once, 4000);
|
||||
})();
|
||||
`;
|
||||
this.controller.runJavaScript(js).catch(() => {
|
||||
hilog.warn(0x0000, TAG, 'inject js fail');
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { PushExtensionAbility, pushCommon } from '@kit.PushKit';
|
||||
import { hilog } from '@kit.PerformanceAnalysisKit';
|
||||
|
||||
const TAG = 'FengyingOA';
|
||||
|
||||
export default class PushMessageAbility extends PushExtensionAbility {
|
||||
onReceiveMessage(message: pushCommon.PushPayload): void {
|
||||
hilog.info(0x0000, TAG, 'push data %{public}s', JSON.stringify(message));
|
||||
}
|
||||
|
||||
onDestroy(): void {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
{
|
||||
"module": {
|
||||
"name": "entry",
|
||||
"type": "entry",
|
||||
"description": "$string:module_desc",
|
||||
"mainElement": "EntryAbility",
|
||||
"deviceTypes": ["phone", "tablet"],
|
||||
"deliveryWithInstall": true,
|
||||
"installationFree": false,
|
||||
"pages": "$profile:main_pages",
|
||||
"abilities": [
|
||||
{
|
||||
"name": "EntryAbility",
|
||||
"srcEntry": "./ets/entryability/EntryAbility.ets",
|
||||
"description": "$string:EntryAbility_desc",
|
||||
"icon": "$media:app_icon",
|
||||
"label": "$string:EntryAbility_label",
|
||||
"startWindowIcon": "$media:app_icon",
|
||||
"startWindowBackground": "$color:start_window_background",
|
||||
"exported": true,
|
||||
"skills": [
|
||||
{
|
||||
"entities": ["entity.system.home"],
|
||||
"actions": ["ohos.want.action.home"]
|
||||
},
|
||||
{
|
||||
"entities": ["entity.system.browsable"],
|
||||
"actions": ["ohos.want.action.viewData"],
|
||||
"uris": [
|
||||
{ "scheme": "fengyingoa", "host": "chat" },
|
||||
{ "scheme": "fengyingoa", "host": "qr" }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"extensionAbilities": [
|
||||
{
|
||||
"name": "PushMessageAbility",
|
||||
"srcEntry": "./ets/pushability/PushMessageAbility.ets",
|
||||
"type": "push",
|
||||
"exported": false,
|
||||
"description": "华为推送"
|
||||
}
|
||||
],
|
||||
"requestPermissions": [
|
||||
{ "name": "ohos.permission.INTERNET" },
|
||||
{ "name": "ohos.permission.GET_NETWORK_INFO" },
|
||||
{
|
||||
"name": "ohos.permission.CAMERA",
|
||||
"reason": "$string:perm_camera",
|
||||
"usedScene": { "abilities": ["EntryAbility"], "when": "inuse" }
|
||||
},
|
||||
{
|
||||
"name": "ohos.permission.MICROPHONE",
|
||||
"reason": "$string:perm_mic",
|
||||
"usedScene": { "abilities": ["EntryAbility"], "when": "inuse" }
|
||||
},
|
||||
{
|
||||
"name": "ohos.permission.APPROXIMATELY_LOCATION",
|
||||
"reason": "$string:perm_location",
|
||||
"usedScene": { "abilities": ["EntryAbility"], "when": "inuse" }
|
||||
},
|
||||
{
|
||||
"name": "ohos.permission.LOCATION",
|
||||
"reason": "$string:perm_location",
|
||||
"usedScene": { "abilities": ["EntryAbility"], "when": "inuse" }
|
||||
},
|
||||
{
|
||||
"name": "ohos.permission.READ_IMAGEVIDEO",
|
||||
"reason": "$string:perm_media",
|
||||
"usedScene": { "abilities": ["EntryAbility"], "when": "inuse" }
|
||||
},
|
||||
{
|
||||
"name": "ohos.permission.WRITE_IMAGEVIDEO",
|
||||
"reason": "$string:perm_media",
|
||||
"usedScene": { "abilities": ["EntryAbility"], "when": "inuse" }
|
||||
}
|
||||
],
|
||||
"metadata": [
|
||||
{
|
||||
"name": "client_id",
|
||||
"value": "6917615149085387132"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"color": [
|
||||
{ "name": "start_window_background", "value": "#5B4FE3" }
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"string": [
|
||||
{ "name": "module_desc", "value": "风影智慧办公鸿蒙客户端" },
|
||||
{ "name": "EntryAbility_desc", "value": "风影智慧办公" },
|
||||
{ "name": "EntryAbility_label", "value": "风影智慧办公" },
|
||||
{ "name": "perm_camera", "value": "用于扫码登录、拍照上传附件" },
|
||||
{ "name": "perm_mic", "value": "用于即时通讯语音消息" },
|
||||
{ "name": "perm_location", "value": "用于出差打卡、地图选点" },
|
||||
{ "name": "perm_media", "value": "用于选择和保存图片、文件" }
|
||||
]
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 4.1 KiB |
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"src": [
|
||||
"pages/Index"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{"agcgw":{"url":"connect-drcn.dbankcloud.cn","backurl":"connect-drcn.hispace.hicloud.com","websocketurl":"connect-ws-drcn.hispace.dbankcloud.cn","websocketbackurl":"connect-ws-drcn.hispace.dbankcloud.com"},"agcgw_all":{"SG":"connect-dra.dbankcloud.cn","SG_back":"connect-dra.hispace.hicloud.com","CN":"connect-drcn.dbankcloud.cn","CN_back":"connect-drcn.hispace.hicloud.com","RU":"connect-drru.hispace.dbankcloud.ru","RU_back":"connect-drru.hispace.dbankcloud.cn","DE":"connect-dre.dbankcloud.cn","DE_back":"connect-dre.hispace.hicloud.com"},"websocketgw_all":{"SG":"connect-ws-dra.hispace.dbankcloud.cn","SG_back":"connect-ws-dra.hispace.dbankcloud.com","CN":"connect-ws-drcn.hispace.dbankcloud.cn","CN_back":"connect-ws-drcn.hispace.dbankcloud.com","RU":"connect-ws-drru.hispace.dbankcloud.ru","RU_back":"connect-ws-drru.hispace.dbankcloud.cn","DE":"connect-ws-dre.hispace.dbankcloud.cn","DE_back":"connect-ws-dre.hispace.dbankcloud.com"},"client":{"cp_id":"10086000847744494","product_id":"101653523864520415","client_id":"1993069421077225280","client_secret":"[!00A9C94D03C4BF55EA6519B1CF01153AB697CC8211E399E829DA73A990F958613D6F5F01F1B8BA8CF74DB5933C003EAE4D1A1657300CA65BA1E683ADFBB26E6CCA45A3F7BB34D44507209E4BB2E5AFFE8E8638749171D9720E7B982E71D04C90A8]","project_id":"101653523864520415","app_id":"6917615149085387132","api_key":"[!004452080D1B4651C537B84F0961D936D6438A360469CDDFD0B606B67BA71B6DF1DCF265C6FB898FAB736110DFAB338E35D3F7B943D49CBA4C0680A8682E29F298CDC17AF4456F592F0AD5EA63DAD95EADE168E41FF71F2048E358A9B469E06D2B391F558B01802AD2558D763ABD03D93126D342B2B02B54B9D21A726B3D07CC5D]","package_name":"com.fengying.oa.mobile"},"oauth_client":{"client_id":"6917615149085387132","client_type":30},"app_info":{"app_id":"6917615149085387132","package_name":"com.fengying.oa.mobile"},"code":{"code1":"3349BBB4FB01961D41511945F371A779","code2":"0A2C1415D785F047B1C3D121AD7C7529","code3":"3C860679A443A35E092B4378B7E3466A","code4":"3DEE6F9A95E1D2512A921DA41B96ED82"},"service":{"analytics":{"collector_url":"datacollector-drcn.dt.hicloud.com,datacollector-drcn.dt.dbankcloud.cn","collector_url_cn":"datacollector-drcn.dt.hicloud.com,datacollector-drcn.dt.dbankcloud.cn","collector_url_de":"datacollector-dre.dt.hicloud.com,datacollector-dre.dt.dbankcloud.cn","collector_url_ru":"datacollector-drru.dt.dbankcloud.ru,datacollector-drru.dt.hicloud.com","collector_url_sg":"datacollector-dra.dt.hicloud.com,datacollector-dra.dt.dbankcloud.cn","resource_id":"p1","channel_id":""},"ml":{"mlservice_url":"ml-api-drcn.ai.dbankcloud.com,ml-api-drcn.ai.dbankcloud.cn"},"cloudstorage":{"storage_url":"https://agc-storage-drcn.platform.dbankcloud.cn","storage_url_ru":"https://agc-storage-drru.cloud.huawei.ru","storage_url_sg":"https://ops-dra.agcstorage.link","storage_url_de":"https://ops-dre.agcstorage.link","storage_url_cn":"https://agc-storage-drcn.platform.dbankcloud.cn","storage_url_ru_back":"https://agc-storage-drru.cloud.huawei.ru","storage_url_sg_back":"https://agc-storage-dra.cloud.huawei.asia","storage_url_de_back":"https://agc-storage-dre.cloud.huawei.eu","storage_url_cn_back":"https://agc-storage-drcn.cloud.huawei.com.cn"},"search":{"url":"https://search-drcn.cloud.huawei.com"},"edukit":{"edu_url":"edukit.cloud.huawei.com.cn","dh_url":"edukit.cloud.huawei.com.cn"}},"region":"CN","configuration_version":"3.0","appInfos":[{"package_name":"com.fengying.oa.mobile","client":{"client_secret":"[!007C7452FF690E0A79490D8BB5131A3AE11AAABC74685A7C5AF4CF72FB41C6987E3868AAFE41004FF5A80995FFB4D783723634ACA37F5248ABA50110BB687D1DBCDD1769F5896B688D788B32C26F7F960A0C10B8DC5D7B4BBAF06DAD603B6F3AC8]","app_id":"6917615149085387132","api_key":"[!006FD5F294EDA4E1636B94706055D7E9A80BF64D9DC898C6D5C929ABE8C626ABEEEDFA41EDFB04779BD60FF776C00D1ABC9108A9E98BE5A55ADD5F39DE84149EF1AAF494E9075A51594DA05CD2BB5816E35C8969AE95368AFB1166C3308A3542084BACE7F883CB6D020E7130ACB5AB2122B34AE2648D8DC0F5F4BFC054482A002E]"},"code":{"code1":"E371F4D9A118D7ADA53F1A5BEC3E15C6004674FE3E029E6435264AEBA83A26B1","code2":"2C669AB03EF94DE3EBB1976F8A7478A3E512B9D7D5DD5E26B3758AF83B52E0B5","code3":"FFA3797D46B5F30F4F741B79793C388352F77CB05796E76DC91325CD36DAE505","code4":"44302FD51983592DB6B3EB4FA6E74FB9"}}]}
|
||||
Reference in New Issue
Block a user