feat: os demo

This commit is contained in:
gaoshuaixing
2024-12-28 18:59:20 +08:00
parent 185ba574ab
commit 624ac2e604
22 changed files with 258 additions and 1121 deletions

View File

@@ -1,66 +0,0 @@
'use strict';
const path = require('path');
const { getBaseDir } = require('ee-core/ps');
const { getMainWindow } = require('ee-core/electron/window');
/**
* 硬件设备 - 功能demo
* @class
*/
class HardwareController {
/**
* 获取打印机列表
*/
async getPrinterList () {
//主线程获取打印机列表
const win = getMainWindow();
const list = await win.webContents.getPrintersAsync();
return list;
}
/**
* 打印
*/
print (args, event) {
const { view, deviceName } = args;
let content = null;
if (view.type == 'html') {
content = path.join('file://', getBaseDir(), view.content)
} else {
content = view.content;
}
let opt = {
title: 'printer window',
x: 10,
y: 10,
width: 980,
height: 650
}
const name = 'window-printer';
const printWindow = Addon.get('window').create(name, opt);
printWindow.loadURL(content);
printWindow.webContents.once('did-finish-load', () => {
// 页面完全加载完成后,开始打印
printWindow.webContents.print({
silent: false, // 显示打印对话框
printBackground: true,
deviceName,
}, (success, failureReason) => {
const channel = 'controller.hardware.printStatus';
event.reply(`${channel}`, { success, failureReason });
printWindow.close();
});
});
return true;
}
}
HardwareController.toString = () => '[class HardwareController]';
module.exports = HardwareController;

View File

@@ -1,14 +1,11 @@
'use strict';
const _ = require('lodash');
const fs = require('fs');
const path = require('path');
const {
app: electronApp, dialog, shell, Notification,
powerMonitor, screen, nativeTheme
} = require('electron');
// const { isProd, getBaseDir } = require('ee-core/ps');
// const { getConfig } = require('ee-core/config');
// const { isFileProtocol } = require('ee-core/utils/is');
const { windowService } = require('../service/os/window');
/**
@@ -18,45 +15,45 @@ const { windowService } = require('../service/os/window');
class OsController {
/**
* 所有方法接收两个参数
* @param args 前端传的参数
* @param event - ipc通信时才有值。详情见控制器文档
* All methods receive two parameters
* @param args Parameters transmitted by the frontend
* @param event - Values are only available during IPC communication. For details, please refer to the controller documentation
*/
/**
* 消息提示对话框
* Message prompt dialog box
*/
messageShow() {
dialog.showMessageBoxSync({
type: 'info', // "none", "info", "error", "question" 或者 "warning"
title: '自定义标题-message',
message: '自定义消息内容',
detail: '其它的额外信息'
title: 'Custom Title',
message: 'Customize message content',
detail: 'Other additional information'
})
return '打开了消息框';
return 'Opened the message box';
}
/**
* 消息提示与确认对话框
* Message prompt and confirmation dialog box
*/
messageShowConfirm() {
const res = dialog.showMessageBoxSync({
type: 'info',
title: '自定义标题-message',
message: '自定义消息内容',
detail: '其它的额外信息',
cancelId: 1, // 用于取消对话框的按钮的索引
defaultId: 0, // 设置默认选中的按钮
buttons: ['确认', '取消'], // 按钮及索引
title: 'Custom Title',
message: 'Customize message content',
detail: 'Other additional information',
cancelId: 1, // Index of buttons used to cancel dialog boxes
defaultId: 0, // Set default selected button
buttons: ['confirm', 'cancel'],
})
let data = (res === 0) ? '点击确认按钮' : '点击取消按钮';
let data = (res === 0) ? 'click the confirm button' : 'click the cancel button';
return data;
}
/**
* 选择目录
* Select Directory
*/
selectFolder() {
const filePaths = dialog.showOpenDialogSync({
@@ -71,7 +68,7 @@ class OsController {
}
/**
* 打开目录
* open directory
*/
openDirectory(args) {
const { id } = args;
@@ -90,7 +87,7 @@ class OsController {
}
/**
* 选择图片
* Select Picture
*/
selectPic() {
const filePaths = dialog.showOpenDialogSync({
@@ -103,35 +100,19 @@ class OsController {
if (_.isEmpty(filePaths)) {
return null
}
return filePaths[0];
try {
const data = fs.readFileSync(filePaths[0]);
const pic = 'data:image/jpeg;base64,' + data.toString('base64');
return pic;
} catch (err) {
console.error(err);
return null;
}
}
/**
* 加载视图内容
*/
loadViewContent(args) {
const { type, content } = args;
let contentUrl = content;
if (type == 'html') {
contentUrl = path.join('file://', electronApp.getAppPath(), content);
}
Services.get('os').createBrowserView(contentUrl);
return true
}
/**
* 移除视图内容
*/
removeViewContent() {
Services.get('os').removeBrowserView();
return true
}
/**
* 打开新窗口
* Open a new window
*/
createWindow(args) {
const wcid = windowService.createWindow(args);
@@ -163,7 +144,7 @@ class OsController {
}
/**
* 创建系统通知
* Create system notifications
*/
sendNotification(args, event) {
const { title, subtitle, body, silent} = args;
@@ -185,140 +166,10 @@ class OsController {
if (!_.isEmpty(silent)) {
options.silent = silent;
}
Services.get('os').createNotification(options, event);
windowService.createNotification(options, event);
return true
}
/**
* 电源监控
*/
initPowerMonitor(args, event) {
const channel = 'controller.os.initPowerMonitor';
powerMonitor.on('on-ac', (e) => {
let data = {
type: 'on-ac',
msg: '接入了电源'
}
event.reply(`${channel}`, data)
});
powerMonitor.on('on-battery', (e) => {
let data = {
type: 'on-battery',
msg: '使用电池中'
}
event.reply(`${channel}`, data)
});
powerMonitor.on('lock-screen', (e) => {
let data = {
type: 'lock-screen',
msg: '锁屏了'
}
event.reply(`${channel}`, data)
});
powerMonitor.on('unlock-screen', (e) => {
let data = {
type: 'unlock-screen',
msg: '解锁了'
}
event.reply(`${channel}`, data)
});
return true
}
/**
* 获取屏幕信息
*/
getScreen(args) {
let data = [];
let res = {};
if (args == 0) {
let res = screen.getCursorScreenPoint();
data = [
{
title: '横坐标',
desc: res.x
},
{
title: '纵坐标',
desc: res.y
},
]
return data;
}
if (args == 1) {
res = screen.getPrimaryDisplay();
}
if (args == 2) {
let resArr = screen.getAllDisplays();
// 数组,只取一个吧
res = resArr[0];
}
// Log.info('[electron] [ipc] [example] [getScreen] res:', res);
data = [
{
title: '分辨率',
desc: res.bounds.width + ' x ' + res.bounds.height
},
{
title: '单色显示器',
desc: res.monochrome ? '是' : '否'
},
{
title: '色深',
desc: res. colorDepth
},
{
title: '色域',
desc: res.colorSpace
},
{
title: 'scaleFactor',
desc: res.scaleFactor
},
{
title: '加速器',
desc: res.accelerometerSupport
},
{
title: '触控',
desc: res.touchSupport == 'unknown' ? '不支持' : '支持'
},
]
return data;
}
/**
* 获取系统主题
*/
getTheme() {
let theme = 'system';
if (nativeTheme.shouldUseHighContrastColors) {
theme = 'light';
} else if (nativeTheme.shouldUseInvertedColorScheme) {
theme = 'dark';
}
return theme;
}
/**
* 设置系统主题
*/
setTheme(args) {
// TODO 好像没有什么明显效果
nativeTheme.themeSource = args;
return args;
}
}
}
OsController.toString = () => '[class OsController]';

View File

@@ -1,88 +0,0 @@
'use strict';
const { BrowserView, Notification } = require('electron');
const { getMainWindow } = require('ee-core/electron/window');
/**
* os
* @class
*/
class OsService {
constructor() {
this.myBrowserView = null;
this.myNotification = null;
}
/**
* createBrowserView
*/
createBrowserView(contentUrl) {
// electron 实验性功能,慎用
const win = getMainWindow();
this.myBrowserView = new BrowserView();
win.setBrowserView(this.myBrowserView);
this.myBrowserView.setBounds({
x: 300,
y: 170,
width: 650,
height: 400
});
this.myBrowserView.webContents.loadURL(contentUrl);
}
/**
* removeBrowserView
*/
removeBrowserView() {
// one
this.myBrowserView.webContents.loadURL('about:blank')
// two - electron 11 remove destroy()
// this.myBrowserView.webContents.destroy();
// three
// this.myBrowserView.webContents.forcefullyCrashRenderer()
// fore
// this.myBrowserView.webContents.close
}
/**
* createNotification
*/
createNotification(options, event) {
const channel = 'controller.os.sendNotification';
this.myNotification = new Notification(options);
if (options.clickEvent) {
this.myNotification.on('click', (e) => {
let data = {
type: 'click',
msg: '您点击了通知消息'
}
event.reply(`${channel}`, data)
});
}
if (options.closeEvent) {
this.myNotification.on('close', (e) => {
let data = {
type: 'close',
msg: '您关闭了通知消息'
}
event.reply(`${channel}`, data)
});
}
this.myNotification.show();
}
}
OsService.toString = () => '[class OsService]';
module.exports = {
OsService,
osService: new OsService()
};

View File

@@ -2,7 +2,7 @@
const path = require('path');
const { app: electronApp } = require('electron');
const { BrowserWindow, BrowserView, Notification } = require('electron');
const { BrowserWindow, Notification } = require('electron');
const { getMainWindow } = require('ee-core/electron/window');
const { isProd, getBaseDir } = require('ee-core/ps');
@@ -13,7 +13,6 @@ const { isProd, getBaseDir } = require('ee-core/ps');
class WindowService {
constructor() {
this.myBrowserView = null;
this.myNotification = null;
this.windows = {}
}
@@ -66,7 +65,7 @@ class WindowService {
}
/**
* 获取窗口contents id
* Get window contents id
*/
getWCid(args) {
const { windowName } = args;
@@ -94,6 +93,36 @@ class WindowService {
}
}
/**
* createNotification
*/
createNotification(options, event) {
const channel = 'controller.os.sendNotification';
this.myNotification = new Notification(options);
if (options.clickEvent) {
this.myNotification.on('click', (e) => {
let data = {
type: 'click',
msg: '您点击了通知消息'
}
event.reply(`${channel}`, data)
});
}
if (options.closeEvent) {
this.myNotification.on('close', (e) => {
let data = {
type: 'close',
msg: '您关闭了通知消息'
}
event.reply(`${channel}`, data)
});
}
this.myNotification.show();
}
}
WindowService.toString = () => '[class WindowService]';

View File

@@ -52,13 +52,6 @@ const ipcApiRoute = {
window2ToWindow1: 'controller.os.window2ToWindow1',
},
// hardware
hardware: {
getPrinterList: 'controller.hardware.getPrinterList',
print: 'controller.hardware.print',
printStatus: 'controller.hardware.printStatus',
},
// effect
effect: {
selectFile: 'controller.effect.selectFile',

View File

@@ -53,18 +53,12 @@ export default {
params: {},
},
'menu_3' : {
icon: 'icon-xiangji',
title: '硬件',
pageName: 'Hardware',
params: {},
},
'menu_4' : {
icon: 'icon-liuxing',
title: '特效',
pageName: 'Effect',
params: {},
},
'menu_5' : {
'menu_4' : {
icon: 'icon-gouwu',
title: 'cross',
pageName: 'Cross',

View File

@@ -28,20 +28,6 @@
import subMenu from '@/router/subMenu';
export default {
// setup() {
// const state = reactive({
// selectedKeys: ['menu_100'],
// });
// const handleClick = e => {
// state.selectedKeys = [e.key];
// };
// return {
// state,
// handleClick,
// };
// },
props: {
id: {
type: String,

View File

@@ -94,28 +94,9 @@ const constantRouterMap = [
path: '/os/theme/index',
name: 'OsThemeIndex',
component: () => import('@/views/os/theme/Index.vue')
},
{
path: '/os/system/index',
name: 'OsSystemIndex',
component: () => import('@/views/os/system/Index.vue')
},
},
]
},
{
path: '/hardware',
name: 'Hardware',
component: () => import('@/layouts/Menu.vue'),
props: { id: 'hardware' },
redirect: { name: 'HardwarePrinterIndex' },
children: [
{
path: '/hardware/printer/index',
name: 'HardwarePrinterIndex',
component: () => import('@/views/hardware/printer/Index.vue')
},
]
},
{
path: '/effect',
name: 'Effect',

View File

@@ -38,90 +38,58 @@ export default {
params: {}
},
},
os: {
'menu_100' : {
icon: 'profile',
title: '文件',
pageName: 'OsFileIndex',
params: {}
},
'menu_101' : {
icon: 'profile',
title: '视图',
pageName: 'OsWindowViewIndex',
params: {}
},
'menu_102' : {
icon: 'profile',
title: '窗口',
pageName: 'OsWindowIndex',
params: {}
},
'menu_103' : {
icon: 'profile',
title: '桌面通知',
pageName: 'OsNotificationIndex',
params: {}
},
'menu_104' : {
icon: 'profile',
title: '电源监控',
pageName: 'OsPowerMonitorIndex',
params: {}
},
'menu_105' : {
icon: 'profile',
title: '屏幕信息',
pageName: 'OsScreenIndex',
params: {}
},
'menu_106' : {
icon: 'profile',
title: '系统主题',
pageName: 'OsThemeIndex',
params: {}
},
'menu_110' : {
icon: 'profile',
title: '图片',
pageName: 'OsFilePic',
params: {}
},
},
hardware: {
'menu_100' : {
icon: 'profile',
title: '打印机',
pageName: 'HardwarePrinterIndex',
params: {}
}
os: {
'menu_100' : {
icon: 'profile',
title: '文件',
pageName: 'OsFileIndex',
params: {}
},
effect: {
'menu_100' : {
icon: 'profile',
title: '登录',
pageName: 'EffectLoginIndex',
params: {}
}
'menu_102' : {
icon: 'profile',
title: '窗口',
pageName: 'OsWindowIndex',
params: {}
},
cross: {
'menu_100' : {
icon: 'profile',
title: 'go服务',
pageName: 'CrossGoIndex',
params: {}
},
'menu_110' : {
icon: 'profile',
title: 'java服务',
pageName: 'CrossJavaIndex',
params: {}
},
'menu_120' : {
icon: 'profile',
title: 'python服务',
pageName: 'CrossPythonIndex',
params: {}
},
'menu_103' : {
icon: 'profile',
title: '桌面通知',
pageName: 'OsNotificationIndex',
params: {}
},
'menu_110' : {
icon: 'profile',
title: '图片',
pageName: 'OsFilePic',
params: {}
},
},
effect: {
'menu_100' : {
icon: 'profile',
title: '登录',
pageName: 'EffectLoginIndex',
params: {}
}
},
cross: {
'menu_100' : {
icon: 'profile',
title: 'go服务',
pageName: 'CrossGoIndex',
params: {}
},
'menu_110' : {
icon: 'profile',
title: 'java服务',
pageName: 'CrossJavaIndex',
params: {}
},
'menu_120' : {
icon: 'profile',
title: 'python服务',
pageName: 'CrossPythonIndex',
params: {}
},
},
}

View File

@@ -12,24 +12,17 @@
</div>
</div>
</template>
<script>
<script setup>
import { ipcApiRoute } from '@/api';
import { ipc } from '@/utils/ipcRenderer';
import { useRouter } from 'vue-router';
export default {
data() {
return {
};
},
methods: {
loginWindow () {
this.$router.push({ name: 'SpecialLoginWindow', params: {}});
ipc.invoke(ipcApiRoute.effect.loginWindow, {width: 400, height: 300}).then(r => {
//
})
},
}
};
const router = useRouter();
function loginWindow() {
router.push({ name: 'SpecialLoginWindow'});
ipc.invoke(ipcApiRoute.effect.loginWindow, {width: 400, height: 300});
}
</script>
<style lang="less" scoped>
#effect-login-index {

View File

@@ -10,29 +10,23 @@
</div>
</div>
</template>
<script>
<script setup>
import { ipcApiRoute } from '@/api';
import { ipc } from '@/utils/ipcRenderer';
import { ref } from 'vue';
import { useRouter } from 'vue-router';
const router = useRouter();
const loading = ref(false);
const loginText = ref('正在登陆......');
export default {
data() {
return {
loading: false,
loginText: '正在登陆......'
};
},
methods: {
login() {
this.loading = true;
setTimeout(() => {
this.$router.push({ name: 'Framework', params: {}});
ipc.invoke(ipcApiRoute.effect.restoreWindow, {width: 980, height: 650}).then(r => {
//
})
}, 2000);
}
}
};
const login = () => {
loading.value = true;
setTimeout(() => {
router.push({ name: 'Framework'});
ipc.invoke(ipcApiRoute.effect.restoreWindow, {width: 980, height: 650})
}, 2000);
}
</script>
<style lang="less" scoped>
#effect-login-window {

View File

@@ -1,101 +0,0 @@
<template>
<div id="app-hw-bluetooth">
<div class="one-block-1">
<span>
1. 打印机设备
</span>
</div>
<div class="one-block-2">
<a-button @click="getPrinter()"> 获取打印机列表 </a-button>
</div>
<div class="one-block-2">
<a-list size="small" bordered :data-source="printerList">
<template #renderItem="{ item }">
<a-list-item>
{{ item.displayName }} {{ defaultDevice(item) }}
</a-list-item>
</template>
<template #header>
<div>设备列表</div>
</template>
</a-list>
</div>
<div class="one-block-1">
<span>
2. 打印内容
</span>
</div>
<div class="one-block-2">
<a-button @click="doPrint(0)"> 打印一个页面 </a-button>
</div>
</div>
</template>
<script>
import { ipcApiRoute } from '@/api';
import { ipc } from '@/utils/ipcRenderer';
import { toRaw } from 'vue';
export default {
data() {
return {
defaultDeviceName: '',
printerList: [],
views: [
{
type: 'html',
content: '/public/html/view_example.html'
},
],
};
},
mounted () {
this.init();
},
methods: {
init () {
// 避免重复监听,或者将 on 功能写到一个统一的地方,只加载一次
ipc.removeAllListeners(ipcApiRoute.hardware.printStatus);
ipc.on(ipcApiRoute.hardware.printStatus, (event, result) => {
console.log('result', result);
this.$message.info('打印中...');
})
},
getPrinter () {
ipc.invoke(ipcApiRoute.hardware.getPrinterList, {}).then(res => {
this.printerList = res;
})
},
doPrint (index) {
console.log('defaultDeviceName:', this.defaultDeviceName)
const params = {
view: toRaw(this.views[index]),
deviceName: this.defaultDeviceName
};
ipc.send(ipcApiRoute.hardware.print, params)
},
defaultDevice (item) {
let desc = "";
if (item.isDefault) {
desc = "- 默认";
this.defaultDeviceName = item.name;
}
return desc;
}
}
};
</script>
<style lang="less" scoped>
#app-hw-bluetooth {
padding: 0px 10px;
text-align: left;
width: 100%;
.one-block-1 {
font-size: 16px;
padding-top: 10px;
}
.one-block-2 {
padding-top: 10px;
}
}
</style>

View File

@@ -1,5 +1,5 @@
<template>
<div id="app-base-file">
<div id="app-os-file">
<div class="one-block-1">
<span>
1. 系统原生对话框
@@ -34,7 +34,7 @@
</span>
</div>
<div class="one-block-2">
<a-list :grid="{ gutter: 16, column: 4 }" :data-source="file_list">
<a-list :grid="{ gutter: 16, column: 4 }" :data-source="fileList">
<template #renderItem="{ item }">
<a-list-item @click="openDirectry(item.id)">
<a-card :title="item.content">
@@ -44,24 +44,20 @@
</a-card>
</a-list-item>
</template>
<!-- <a-list-item slot="renderItem" slot-scope="item" @click="openDirectry(item.id)">
<a-card :title="item.content">
<a-button type="link">
打开
</a-button>
</a-card>
</a-list-item> -->
</a-list>
</div>
<div class="footer">
</div>
</div>
</template>
<script>
<script setup>
import { ipcApiRoute } from '@/api';
import { ipc } from '@/utils/ipcRenderer';
import storage from 'store2';
import { ref, onMounted } from 'vue';
import { message } from 'ant-design-vue';
const fileList = [
{
content: '【下载】目录',
@@ -81,60 +77,33 @@ const fileList = [
}
];
export default {
data() {
return {
file_list: fileList,
image_info: [],
num: 0,
servicAddress: '',
dir_path: "D:\\www\\ee",
};
},
mounted () {
this.getHost();
},
methods: {
getHost () {
ipc.invoke(ipcApiRoute.framework.checkHttpServer, {}).then(r => {
if (r.enable) {
this.servicAddress = r.server;
storage.set('httpServiceConfig', r);
const dir_path = ref('D:\\www\\ee');
// url转换
const host = r.server || 'http://localhost:7071';
let uri = ipcApiRoute.framework.uploadFile;
let url = uri.split('.').join('/');
this.action_url = host + '/' + url;
}
})
},
openDirectry (id) {
ipc.invoke(ipcApiRoute.os.openDirectory, {id: id}).then(res => {
//console.log('res:', res)
})
},
selectDir() {
ipc.invoke(ipcApiRoute.os.selectFolder, '').then(r => {
this.dir_path = r;
this.$message.info(r);
})
},
messageShow() {
ipc.invoke(ipcApiRoute.os.messageShow, '').then(r => {
this.$message.info(r);
})
},
messageShowConfirm() {
ipc.invoke(ipcApiRoute.os.messageShowConfirm, '').then(r => {
this.$message.info(r);
})
},
}
};
function openDirectry (id) {
ipc.invoke(ipcApiRoute.os.openDirectory, {id: id})
}
function selectDir() {
ipc.invoke(ipcApiRoute.os.selectFolder).then(r => {
dir_path.value = r;
message.info(r);
})
}
function messageShow() {
ipc.invoke(ipcApiRoute.os.messageShow).then(r => {
message.info(r);
})
}
function messageShowConfirm() {
ipc.invoke(ipcApiRoute.os.messageShowConfirm).then(r => {
message.info(r);
})
}
</script>
<style lang="less" scoped>
#app-base-file {
#app-os-file {
padding: 0px 10px;
text-align: left;
width: 100%;

View File

@@ -17,24 +17,18 @@
</div>
</div>
</template>
<script>
<script setup>
import { ipcApiRoute } from '@/api';
import { ipc } from '@/utils/ipcRenderer';
import { ref } from 'vue';
export default {
data() {
return {
picPath: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png'
};
},
methods: {
selectPic () {
ipc.invoke(ipcApiRoute.os.selectPic, {}).then(r => {
this.picPath = r;
})
},
}
};
const picPath = ref('https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png');
function selectPic() {
ipc.invoke(ipcApiRoute.os.selectPic).then(r => {
picPath.value = r;
})
}
</script>
<style lang="less" scoped>
#os-file-pic {

View File

@@ -1,5 +1,5 @@
<template>
<div id="app-base-notification">
<div id="app-os-notification">
<div class="one-block-1">
<span>
1. 弹出桌面通知
@@ -15,67 +15,63 @@
</div>
</div>
</template>
<script>
<script setup>
import { ipcApiRoute } from '@/api';
import { ipc } from '@/utils/ipcRenderer';
import { toRaw } from 'vue';
import { onMounted } from 'vue';
import { message } from 'ant-design-vue';
export default {
data() {
return {
views: [
{
type: 'main',
title: '通知标题',
subtitle: '副标题', // macOS系统专有属性
body: '这是通知内容-默认',
silent: true,
},
{
type: 'main',
title: '提示音',
subtitle: '副标题-提示音',
body: '这是通知内容-提示音',
silent: false,
},
{
type: 'main',
title: '点击通知事件',
subtitle: '副标题-点击通知事件',
body: '这是通知内容-点击通知事件',
clickEvent: true
},
{
type: 'main',
title: '关闭通知事件',
subtitle: '副标题-关闭通知事件',
body: '这是通知内容-点击通知事件',
closeEvent: true
},
],
};
const views = [
{
type: 'main',
title: '通知标题',
subtitle: '副标题', // macOS系统专有属性
body: '这是通知内容-默认',
silent: true,
},
mounted () {
this.init();
{
type: 'main',
title: '提示音',
subtitle: '副标题-提示音',
body: '这是通知内容-提示音',
silent: false,
},
methods: {
init () {
// 避免重复监听,或者将 on 功能写到一个统一的地方,只加载一次
ipc.removeAllListeners(ipcApiRoute.os.sendNotification);
ipc.on(ipcApiRoute.os.sendNotification, (event, result) => {
if (Object.prototype.toString.call(result) == '[object Object]') {
this.$message.info(result.msg);
}
})
},
sendNotification (index) {
ipc.send(ipcApiRoute.os.sendNotification, toRaw(this.views[index]));
},
}
};
{
type: 'main',
title: '点击通知事件',
subtitle: '副标题-点击通知事件',
body: '这是通知内容-点击通知事件',
clickEvent: true
},
{
type: 'main',
title: '关闭通知事件',
subtitle: '副标题-关闭通知事件',
body: '这是通知内容-点击通知事件',
closeEvent: true
},
]
onMounted(() => {
init()
})
function init() {
// Avoid duplicate monitoring, or write the on function to a unified place and load it only once
ipc.removeAllListeners(ipcApiRoute.os.sendNotification);
ipc.on(ipcApiRoute.os.sendNotification, (event, result) => {
if (Object.prototype.toString.call(result) == '[object Object]') {
message.info(result.msg);
}
})
}
function sendNotification (index) {
ipc.send(ipcApiRoute.os.sendNotification, views[index]);
}
</script>
<style lang="less" scoped>
#app-base-notification {
#app-os-notification {
padding: 0px 10px;
text-align: left;
width: 100%;

View File

@@ -1,59 +0,0 @@
<template>
<div id="app-base-powermonitor">
<div class="one-block-1">
<span>
1. 监控电源状态
</span>
</div>
<div class="one-block-2">
<a-space>
<p>* 当前状态{{ currentStatus }}</p>
</a-space>
<p>* 拔掉电源使用电池供电</p>
<p>* 接入电源</p>
<p>* 锁屏</p>
<p>* 解锁</p>
</div>
</div>
</template>
<script>
import { ipcApiRoute } from '@/api';
import { ipc } from '@/utils/ipcRenderer';
export default {
data() {
return {
currentStatus: '无',
};
},
mounted () {
this.init();
},
methods: {
init () {
ipc.removeAllListeners(ipcApiRoute.os.initPowerMonitor);
ipc.on(ipcApiRoute.os.initPowerMonitor, (event, result) => {
if (Object.prototype.toString.call(result) == '[object Object]') {
this.currentStatus = result.msg;
this.$message.info(result.msg);
}
})
ipc.send(ipcApiRoute.os.initPowerMonitor, '');
}
}
};
</script>
<style lang="less" scoped>
#app-base-powermonitor {
padding: 0px 10px;
text-align: left;
width: 100%;
.one-block-1 {
font-size: 16px;
padding-top: 10px;
}
.one-block-2 {
padding-top: 10px;
}
}
</style>

View File

@@ -1,61 +0,0 @@
<template>
<div id="app-base-screen">
<div class="one-block-1">
<span>
1. 屏幕信息
</span>
</div>
<div class="one-block-2">
<a-space>
<a-button @click="getScreen(0)">获取当前鼠标位置</a-button>
<a-button @click="getScreen(1)">获取主屏幕</a-button>
<a-button @click="getScreen(2)">获取所有屏幕</a-button>
</a-space>
</div>
<div class="one-block-1">
<span>
结果
</span>
</div>
<div class="one-block-2">
<a-descriptions title="">
<a-descriptions-item v-for="(info, index) in data" :key="index" :label="info.title" >
{{ info.desc }}
</a-descriptions-item>
</a-descriptions>
</div>
</div>
</template>
<script>
import { ipcApiRoute } from '@/api';
import { ipc } from '@/utils/ipcRenderer';
export default {
data() {
return {
data: [],
};
},
methods: {
getScreen (index) {
ipc.invoke(ipcApiRoute.os.getScreen, index).then(result => {
this.data = result;
})
},
}
};
</script>
<style lang="less" scoped>
#app-base-screen {
padding: 0px 10px;
text-align: left;
width: 100%;
.one-block-1 {
font-size: 16px;
padding-top: 10px;
}
.one-block-2 {
padding-top: 10px;
}
}
</style>

View File

@@ -1,5 +1,5 @@
<template>
<div id="app-base-subwindow-ipc">
<div id="app-os-subwindow-ipc">
<div class="one-block-1">
<span>
1. 发送异步消息
@@ -126,7 +126,7 @@ function sendTosubWindow () {
}
</script>
<style lang="less" scoped>
#app-base-subwindow-ipc {
#app-os-subwindow-ipc {
padding: 0px 10px;
text-align: left;
width: 100%;

View File

@@ -1,69 +0,0 @@
<template>
<div id="app-base-system-launch">
<div class="one-block-2">
<a-list class="set-auto" itemLayout="horizontal">
<a-list-item style="text-align: left;">
<a-list-item-meta>
<template v-slot:title>
<a>启动</a>
</template>
<template v-slot:description>
<span>
开机自动启动
</span>
</template>
</a-list-item-meta>
<template v-slot:actions>
<a-switch v-model="autoLaunchChecked" checkedChildren="开" unCheckedChildren="关" @change="autoLaunchChange()" />
</template>
</a-list-item>
</a-list>
</div>
</div>
</template>
<script>
import { ipcApiRoute } from '@/api';
import { ipc } from '@/utils/ipcRenderer';
export default {
data () {
return {
autoLaunchChecked: false
}
},
mounted () {
this.init();
},
methods: {
init () {
// todo .....
ipc.invoke(ipcApiRoute.autoLaunch, 'check').then(result => {
console.log('[ipcRenderer] [autoLaunch] result:', result)
this.autoLaunchChecked = result.status;
})
},
autoLaunchChange (checkStatus) {
console.log('[ipcRenderer] [autoLaunch] self.autoLaunchChecked:', this.autoLaunchChecked)
},
}
}
</script>
<style lang="less" scoped>
#app-base-system-launch {
padding: 0px 10px;
text-align: left;
width: 100%;
.one-block-1 {
font-size: 16px;
padding-top: 10px;
}
.one-block-2 {
padding-top: 10px;
}
.set-auto {
.ant-list-item:last-child {
border-bottom: 1px solid #e8e8e8;
}
}
}
</style>

View File

@@ -1,83 +0,0 @@
<template>
<div id="app-base-screen">
<div class="one-block-1">
<span>
1. 系统主题模式
</span>
</div>
<div class="one-block-2">
<a-space>
<a-button @click="getTheme()">获取模式</a-button>
</a-space>
<span>
结果{{ currentThemeMode }}
</span>
</div>
<div class="one-block-1">
2. 设置主题模式请自行实现前端UI效果
</div>
<div class="one-block-2">
<a-radio-group v-model="currentThemeMode" @change="setTheme">
<a-radio :value="themeList[0]">
{{ themeList[0] }}
</a-radio>
<a-radio :value="themeList[1]">
{{ themeList[1] }}
</a-radio>
<a-radio :value="themeList[2]">
{{ themeList[2] }}
</a-radio>
</a-radio-group>
</div>
</div>
</template>
<script>
import { ipcApiRoute } from '@/api';
import { ipc } from '@/utils/ipcRenderer';
export default {
data() {
return {
currentThemeMode: '',
themeList: [
'system',
'light',
'dark'
]
};
},
mounted () {
},
methods: {
setTheme (e) {
this.currentThemeMode = e.target.value;
console.log('setTheme currentThemeMode:', this.currentThemeMode)
ipc.invoke(ipcApiRoute.os.setTheme, this.currentThemeMode).then(result => {
console.log('result:', result)
this.currentThemeMode = result;
})
},
getTheme () {
ipc.invoke(ipcApiRoute.os.getTheme).then(result => {
console.log('result:', result)
this.currentThemeMode = result;
})
},
}
};
</script>
<style lang="less" scoped>
#app-base-screen {
padding: 0px 10px;
text-align: left;
width: 100%;
.one-block-1 {
font-size: 16px;
padding-top: 10px;
}
.one-block-2 {
padding-top: 10px;
}
}
</style>

View File

@@ -1,5 +1,5 @@
<template>
<div id="app-base-window">
<div id="app-os-window">
<div class="one-block-1">
<span>
1. 新窗口中加载web内容
@@ -32,47 +32,37 @@
</div>
</div>
</template>
<script>
<script setup>
import { ipcApiRoute } from '@/api';
import { ipc } from '@/utils/ipcRenderer';
import { toRaw } from 'vue';
export default {
data() {
return {
views: [
{
type: 'web',
content: 'https://www.bilibili.com/',
windowName: 'window-web',
windowTitle: 'bilibili'
},
{
type: 'html',
content: '/public/html/view_example.html',
windowName: 'window-html',
windowTitle: 'html window'
},
{
type: 'vue',
content: '#/special/subwindow',
windowName: 'window-vue',
windowTitle: 'vue window'
},
],
};
const views = [
{
type: 'web',
content: 'https://www.bilibili.com/',
windowName: 'window-web',
windowTitle: 'bilibili'
},
methods: {
createWindow (index) {
ipc.invoke(ipcApiRoute.os.createWindow, toRaw(this.views[index])).then(r => {
console.log(r);
})
},
}
};
{
type: 'html',
content: '/public/html/view_example.html',
windowName: 'window-html',
windowTitle: 'html window'
},
{
type: 'vue',
content: '#/special/subwindow',
windowName: 'window-vue',
windowTitle: 'vue window'
},
];
function createWindow(index) {
ipc.invoke(ipcApiRoute.os.createWindow, views[index])
}
</script>
<style lang="less" scoped>
#app-base-window {
#app-os-window {
padding: 0px 10px;
text-align: left;
width: 100%;

View File

@@ -1,74 +0,0 @@
<template>
<div id="app-base-window-view">
<div class="one-block-1">
<span>
1. 嵌入web内容
</span>
</div>
<div class="one-block-2">
<a-space>
<a-button @click="loadViewContent(0)">加载百度页面</a-button>
<a-button @click="removeViewContent(0)">移除百度页面</a-button>
</a-space>
</div>
<div class="one-block-1">
<span>
2. 嵌入html内容
</span>
</div>
<div class="one-block-2">
<a-space>
<a-button @click="loadViewContent(1)">加载html页面</a-button>
<a-button @click="removeViewContent(1)">移除html页面</a-button>
</a-space>
</div>
</div>
</template>
<script>
import { ipcApiRoute } from '@/api';
import { ipc } from '@/utils/ipcRenderer';
import { toRaw } from 'vue';
export default {
data() {
return {
views: [
{
type: 'web',
content: 'https://www.baidu.com/'
},
{
type: 'html',
content: '/public/html/view_example.html'
},
],
};
},
methods: {
loadViewContent (index) {
ipc.invoke(ipcApiRoute.os.loadViewContent, toRaw(this.views[index])).then(r => {
console.log(r);
})
},
removeViewContent (index) {
ipc.invoke(ipcApiRoute.os.removeViewContent, toRaw(this.views[index])).then(r => {
console.log(r);
})
},
}
};
</script>
<style lang="less" scoped>
#app-base-window-view {
padding: 0px 10px;
text-align: left;
width: 100%;
.one-block-1 {
font-size: 16px;
padding-top: 10px;
}
.one-block-2 {
padding-top: 10px;
}
}
</style>