16 Commits

Author SHA1 Message Date
3136352472 5d2285ac8b fix 5 years ago
3136352472 bf07d7c470 自动弹出流程申请单 5 years ago
3136352472 0542bc7102 fix 5 years ago
3136352472 a7e4df094f fix 5 years ago
3136352472 66821cf3a4 通知 5 years ago
3136352472 f6d5e61c6c 添加任务 5 years ago
3136352472 db6e6a2368 添加文档 5 years ago
3136352472 db815358cb 同步分支中的评论 5 years ago
3136352472 8e79e37958 fix 5 years ago
3136352472 4bff00b1ea Merge branch 'master' of https://git.ouxuan.net/3136352472/ouxuan.oa 5 years ago
3136352472 acf6470e01 fix 5 years ago
3136352472 0386c7820d fix mac 5 years ago
3136352472 a94d8362a5 fix 5 years ago
3136352472 40e1835fdf mac版本打包配置 5 years ago
3136352472 8f5c2d4982 加班申请菜单 5 years ago
3136352472 5690e5fe42 文档更新 5 years ago
  1. 1
      .gitignore
  2. 52
      README.md
  3. 41
      lib/data.js
  4. 61
      lib/http.js
  5. 3
      lib/main.js
  6. 48
      lib/tray.js
  7. 34
      lib/web/data.js
  8. 130
      lib/web/main.js
  9. 22
      main.js
  10. 3
      package.json
  11. 10
      res/post-commit

1
.gitignore

@ -3,3 +3,4 @@ build
data
task.json
username.json
package-lock.json

52
README.md

@ -1,45 +1,13 @@
# electron-quick-start
# 欧轩OA管理协助工具
**Clone and run for a quick way to see Electron in action.**
This is a minimal Electron application based on the [Quick Start Guide](https://electronjs.org/docs/tutorial/quick-start) within the Electron documentation.
### 扩展功能
+ 自动登录
+ 托盘常驻
+ 托盘管理任务
+ 关联相关项目
+ 项目分支根据任务自动创建
+ 每次在分支提交会把提交内容同步到相关任务的评论中
**Use this app along with the [Electron API Demos](https://electronjs.org/#get-started) app for API code examples to help you get started.**
A basic Electron application needs just these files:
- `package.json` - Points to the app's main file and lists its details and dependencies.
- `main.js` - Starts the app and creates a browser window to render HTML. This is the app's **main process**.
- `index.html` - A web page to render. This is the app's **renderer process**.
You can learn more about each of these components within the [Quick Start Guide](https://electronjs.org/docs/tutorial/quick-start).
## To Use
To clone and run this repository you'll need [Git](https://git-scm.com) and [Node.js](https://nodejs.org/en/download/) (which comes with [npm](http://npmjs.com)) installed on your computer. From your command line:
```bash
# Clone this repository
git clone https://github.com/electron/electron-quick-start
# Go into the repository
cd electron-quick-start
# Install dependencies
npm install
# Run the app
npm start
```
Note: If you're using Linux Bash for Windows, [see this guide](https://www.howtogeek.com/261575/how-to-run-graphical-linux-desktop-applications-from-windows-10s-bash-shell/) or use `node` from the command prompt.
## Resources for Learning Electron
- [electronjs.org/docs](https://electronjs.org/docs) - all of Electron's documentation
- [electronjs.org/community#boilerplates](https://electronjs.org/community#boilerplates) - sample starter apps created by the community
- [electron/electron-quick-start](https://github.com/electron/electron-quick-start) - a very basic starter Electron app
- [electron/simple-samples](https://github.com/electron/simple-samples) - small applications with ideas for taking them further
- [electron/electron-api-demos](https://github.com/electron/electron-api-demos) - an Electron app that teaches you how to use Electron
- [hokein/electron-sample-apps](https://github.com/hokein/electron-sample-apps) - small demo apps for the various Electron APIs
## License
[CC0 1.0 (Public Domain)](LICENSE.md)
### 同步评论功能
> 每次进行commit时会将内容同步到相应的任务中,如果希望忽略该条提交同步,请以-作为内容开头

41
lib/data.js

@ -51,4 +51,43 @@ exports.SyncConfig = function (config) {
if (fs.readFileSync(pathJoin("data/config.json")) + "" != JSON.stringify(config) + "") {
fs.writeFileSync(pathJoin("data/config.json"), JSON.stringify(config))
}
}
}
exports.AddCommitToQueue = function (data) {
if (!fs.existsSync(pathJoin("data/commit-queue.json"))) {
fs.writeFileSync(pathJoin("data/commit-queue.json"), "[]")
}
let all = fs.readFileSync(pathJoin("data/commit-queue.json"))
all = JSON.parse(all);
all.push(data);
fs.writeFileSync(pathJoin("data/commit-queue.json"), JSON.stringify(all))
}
exports.PopCommitByQueue = function () {
if (!fs.existsSync(pathJoin("data/commit-queue.json"))) {
fs.writeFileSync(pathJoin("data/commit-queue.json"), "[]")
}
let all = fs.readFileSync(pathJoin("data/commit-queue.json"))
all = JSON.parse(all);
var data = all.pop();
fs.writeFileSync(pathJoin("data/commit-queue.json"), JSON.stringify(all))
return data;
}
exports.ignoreDaibMap = {}
if (!fs.existsSync(pathJoin("data/ignore-daib-map.json"))) {
fs.writeFileSync(pathJoin("data/ignore-daib-map.json"), JSON.stringify({}));
}
exports.GetIgnoreDaibMap = function () {
return JSON.parse(fs.readFileSync(pathJoin("data/ignore-daib-map.json")))
}
exports.SyncIgnoreDaibMap = function (result) {
if (fs.readFileSync(pathJoin("data/ignore-daib-map.json")) + "" != JSON.stringify(result) + "") {
fs.writeFileSync(pathJoin("data/ignore-daib-map.json"), JSON.stringify(result))
}
}

61
lib/http.js

@ -0,0 +1,61 @@
const { Notification } = require('electron')
var http = require("http");
var querystring = require("querystring");
var url = require("url");
const path = require('path')
const libdata = require(path.join(__dirname, 'data.js'));
exports.start = function () {
http.createServer(function (request, response) {
var pathname = url.parse(request.url).pathname;
if (HttpMap[pathname]) {
HttpMap[pathname](request, response)
} else {
response.end("请求未定义");
}
}).listen(37188);
}
HttpMap = {
"/commit": function (request, response) {
let query = querystring.parse(url.parse(request.url).query);
let branch = query["branch"];
let commit = query["commit"];
if (!branch || !commit) {
console.log([branch, commit]);
response.end("error");
return;
}
let branchSplit = branch.split("-");
let commitSplit = commit.split(" ");
if (branchSplit.length < 2 || commitSplit.length < 2) {
console.log([branch, commit, "error"]);
response.end("error");
return;
}
let id = branchSplit[0];
let hash = commitSplit.shift();
commit = commitSplit.join(" ");
if (commit[0] == '-' || commit[0] == '#') {
console.log([branch, commit, "skip commit"]);
(new Notification({
title: "有一条新的提交被忽略",
body: `分支:${branch} 提交内容:${commit}`
})).show()
response.end("skip commit");
return;
}
libdata.AddCommitToQueue({
id: id,
branch: branch,
hash: hash,
commit: commit,
});
console.log([branch, commit, "success"]);
response.end("success");
}
}

3
lib/main.js

@ -14,7 +14,6 @@ exports.createMainWindow = function () {
preload: path.join(__dirname, 'web/main.js')
}
})
// and load the index.html of the app.
exports.MainWindow.loadURL('http://oa.ouxuan.net/?d=we&m=login')
@ -23,7 +22,7 @@ exports.createMainWindow = function () {
exports.MainWindow.hide();
});
exports.MainWindow.isClose = false;
exports.MainWindow.isClose = true;
exports.MainWindow.on("close", function (event) {
if (!exports.MainWindow.isClose) {
event.preventDefault();

48
lib/tray.js

@ -1,5 +1,5 @@
const { ipcMain, app, Menu, Tray, BrowserWindow, dialog } = require('electron')
const { ipcMain, app, Menu, Tray, BrowserWindow, dialog, Notification } = require('electron')
const path = require('path')
const fs = require('fs');
@ -10,17 +10,39 @@ const git = require(path.join(__dirname, 'git.js'));
const mainwin = require(path.join(__dirname, 'main.js'));
let tray = null
ipcMain.on('new-notification', (event, title, body, url) => {
let n = new Notification({
title: title,
body: body,
})
n.on('click', function () {
console.log(url);
if (url) {
mainwin.MainWindow.loadURL(url)
mainwin.MainWindow.show();
}
})
n.show()
});
ipcMain.on('new-task-notification', (event) => {
tray.displayBalloon({
(new Notification({
title: "可能有新的任务",
content: `当前总任务数${libdata.GetConfig().DaibanCount}`
})
body: `当前总任务数${libdata.GetConfig().DaibanCount}`
})).show()
});
ipcMain.on('test', (event, a, b, c) => {
console.log(event, a, b, c)
})
let isUpdate = false;
ipcMain.on('put-in-tray', (event) => {
if (!tray) {
mainwin.MainWindow.isClose = false;
tray = new Tray(path.join(__dirname, '../windows-icon.png'))
tray.on("double-click", function () {
@ -56,7 +78,8 @@ ipcMain.on('put-in-tray', (event) => {
label: "切换到该任务分支",
click: (function () {
let project_name = i;
let title = data[project_name][k]["title"];
let id = data[project_name][k]["id"];
let title = `${id}-${data[project_name][k]["title"]}`;
return function () {
if (!project_map[project_name] || project_map[project_name] == "") {
dialog.showErrorBox(`无法切换分支`, `该项目找不到所在路径(${project_name})`);
@ -66,6 +89,7 @@ ipcMain.on('put-in-tray', (event) => {
const simpleGit = require('simple-git')(workingDirPath);
git.autoCheckoutLocalBranch(simpleGit, title, function () {
console.log("autoCheckoutLocalBranch")
fs.copyFileSync(path.join(__dirname, '../res/post-commit'), path.join(workingDirPath, ".git//hooks/post-commit"))
if (ot[project_name] && ot[project_name] != "" && project_map[project_name] && project_map[project_name] != "") {
var exec = require('child_process').execFile;
exec("cmd.exe", ["/c", "start", "", ot[project_name], project_map[project_name]], function (err, data) {
@ -166,6 +190,20 @@ ipcMain.on('put-in-tray', (event) => {
tray.popUpContextMenu(Menu.buildFromTemplate(result.concat({
type: "separator"
},{
label: "添加任务",
click: function (menuItem, browserWindow, event) {
mainwin.MainWindow.loadURL(`http://oa.ouxuan.net/index.php?a=lum&m=input&d=flow&num=work&show=we`)
mainwin.MainWindow.show();
},
}, {
label: "加班申请",
click: function (menuItem, browserWindow, event) {
mainwin.MainWindow.loadURL(`http://oa.ouxuan.net/?a=lum&m=input&d=flow&num=jiaban&show=we`)
mainwin.MainWindow.show();
},
}, {
type: "separator"
}, {
label: "仅查看未完成",
type: "checkbox",

34
lib/web/data.js

@ -94,6 +94,9 @@ exports.syncTaskToFile = function (cb) {
project_map[i] = "";
}
}
if (!project_map){
project_map = {};
}
fs.writeFileSync(libdata2.ProjectMapPath, JSON.stringify(project_map))
if (cb) cb();
})
@ -105,3 +108,34 @@ exports.getTask = function () {
exports.getProjectMap = function () {
return JSON.parse(fs.readFileSync(libdata2.ProjectMapPath));
}
exports.getTaskById = function (id) {
var result = {
"单号": "-",
"标题": "-",
"类型": "-",
"等级": "-",
"分配给": "-",
"所属项目": "-",
"说明": "-",
"开始时间": "-",
"创建人": "-",
"创建时间": "-",
}
$.ajax({
url: `http://oa.ouxuan.net/task.php?a=x&num=work&show=we&mid=${id}`,
async: false,
success: function (html) {
var last = "";
$(html).find("div").each(function (item) {
if (result[last]) {
result[last] = $(this).text();
}
last = $(this).text()
})
}
});
return result;
}

130
lib/web/main.js

@ -3,6 +3,7 @@ const path = require('path')
const libdata = require(path.join(__dirname, "data.js"));
const libdata2 = require(path.join(__dirname, "../data.js"));
const ipc = require('electron').ipcRenderer
const dialog = require('electron').remote.dialog
function get(name) {
@ -13,21 +14,146 @@ function get(name) {
var config = libdata2.GetConfig();
var lastTime = config["loadhit-lastTime"];
if (!lastTime) {
lastTime = config["loadhit-lastTime"] = Date.parse(new Date()) / 1000;
libdata2.SyncConfig(config);
}
window.addEventListener('DOMContentLoaded', () => {
libdata.syncTaskToFile(function () {
ipc.send('put-in-tray')
})
setInterval(function () {
if (libdata.syncDaibanCount()) {
ipc.send('new-task-notification')
console.log("通知中...")
libdata.syncTaskToFile();
}
}, 5 * 1000)
function Loadhit() {
setTimeout(() => {
let url = `http://oa.ouxuan.net/api.php?m=indexreim&a=loadhit&cfrom=mweb&time=${lastTime}`;
$.get(url, function (data) {
data = JSON.parse(data);
console.log(data);
if (data.code == 200) {
data = data.data;
if (data.rows.length > 0) {
lastTime = data.loadtime;
config = libdata2.GetConfig();
config["loadhit-lastTime"] = lastTime;
libdata2.SyncConfig(config);
for (var i = 0; i < data.rows.length; i++) {
var xgurlSplice = data.rows[i].xgurl.split("|")
if (xgurlSplice[0] == "work") {
let id = xgurlSplice[1];
let taskData = libdata.getTaskById(id);
let taskUrl = `http://oa.ouxuan.net/task.php?a=x&num=work&show=mweb&mid=${id}`;
ipc.send('new-notification'
, `${taskData["标题"]}`
, `${taskData["创建人"]} ${taskData["所属项目"]} ${taskData["创建时间"]}\n说明:${taskData["说明"]}`
, taskUrl)
}
}
Loadhit()
}
}
})
}, 5000);
}
Loadhit();
function CommitByQueue() {
setTimeout(() => {
let item = libdata2.PopCommitByQueue();
console.log("PopCommitByQueue")
if (item && item.id) {
console.log(item)
let data = {
sm: item.commit,
name: "评论",
mid: item.id,
modenum: "work"
};
$.ajax({
url: "http://oa.ouxuan.net/index.php?a=pinglun&m=flowopt&d=flow&ajaxbool=true",
async: false,
data: data,
success: function () {
ipc.send('new-notification', "有一条新的评论被同步", `分支:${item.branch} 评论内容:${item.commit}`)
}
});
}
CommitByQueue();
}, 1000);
}
CommitByQueue();
function doDaib() {
let igdbmap = libdata2.GetIgnoreDaibMap()
let url = `http://oa.ouxuan.net/api.php?m=index&a=getyydata&page=1&event=daib&num=daiban`;
$.get(url, function (data) {
data = JSON.parse(data);
if (data.code == 200) {
data = data["data"]["rows"]
for (var i in data) {
if (data[i]["modenum"] != "work" && !igdbmap[data[i]["id"]]) {
console.log(data[i]["cont"].replace("<br>", "\n", -1))
let index = dialog.showMessageBoxSync({
type: "info",
buttons: ["通过", "拒绝", "忽略"],
defaultId: 2,
cancelId: 2,
title: data[i]["modename"],
message: data[i]["cont"].replace(/<br>/g, "\n")
});
switch (index) {
case 0:
$.post("http://oa.ouxuan.net/index.php?a=check&m=flowopt&d=flow&ajaxbool=true", {
tuiid: 0,
mid: data[i]["id"],
modenum: data[i]["modenum"],
zt: 1,
}, function (raw) {
console.log("通过")
console.log(raw)
})
break;
case 1:
break;
case 2:
igdbmap = libdata2.GetIgnoreDaibMap();
igdbmap[data[i]["id"]] = true;
libdata2.SyncIgnoreDaibMap();
break;
default:
}
console.log(index);
}
}
setTimeout(() => {
doDaib()
}, 10 * 1000);
}
});
}
doDaib()
let m = get("m");
if (PageJs[m]) {

22
main.js

@ -1,9 +1,10 @@
// Modules to control application life and create native browser window
const { app, BrowserWindow } = require('electron')
const { app, BrowserWindow, Notification } = require('electron')
const path = require('path')
const main = require(path.join(__dirname, "lib/main.js"))
const mhttp = require(path.join(__dirname, "lib/http.js"))
app.setAppUserModelId(process.execPath);
// This method will be called when Electron has finished
@ -15,6 +16,23 @@ app.whenReady().then(function () {
main.createMainWindow()
const tray = require(path.join(__dirname, "lib/tray.js"))
if (app.dock) {
app.dock.hide();
}
mhttp.start();
if (Notification.isSupported()) {
(new Notification({
title: "启动",
body: "ouxuan.oa已经启动"
})).show()
} else {
dialog.showErrorBox(`警告`, `桌面通知无法被支持`);
}
// tray.createTrayWindow()
})

3
package.json

@ -4,7 +4,8 @@
"main": "main.js",
"scripts": {
"start": "electron .",
"package": "electron-packager ./ ouxuan.oa --out ./build --overwrite --icon=favicon"
"package": "electron-packager ./ ouxuan.oa --out ./build --overwrite --icon=favicon",
"package-mac": "electron-packager ./ ouxuan.oa --out ./build --overwrite --icon=favicon --platform=darwin"
},
"devDependencies": {
"electron": "^8.2.1",

10
res/post-commit

@ -0,0 +1,10 @@
#!/bin/sh
branch=`git symbolic-ref --short -q HEAD`
commit=`git log -1 --oneline $branch`
branchencode=`echo -n "$branch" | xxd -ps | tr -d '\n' | sed -r 's/(..)/%\1/g'`
commitencode=`echo -n "$commit" | xxd -ps | tr -d '\n' | sed -r 's/(..)/%\1/g'`
curl "http://127.0.0.1:37188/commit?branch=${branchencode}&commit=${commitencode}"
echo 分支[$branch][$commit]
exit 0
Loading…
Cancel
Save