init
32
fuintCashier/src/index.ejs
Normal file
@@ -0,0 +1,32 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>fuintCashier</title>
|
||||
<% if (htmlWebpackPlugin.options.nodeModules) { %>
|
||||
<!-- Add `node_modules/` to global paths so `require` works properly in development -->
|
||||
<script>
|
||||
require('module').globalPaths.push('<%= htmlWebpackPlugin.options.nodeModules.replace(/\\/g, '\\\\') %>')
|
||||
</script>
|
||||
<% } %>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<!-- Set `__static` path to static files in production -->
|
||||
<% if (!process.browser) { %>
|
||||
<script>
|
||||
if (process.env.NODE_ENV !== 'development') {
|
||||
window.__static = require('path').join(__dirname, '/static').replace(/\\/g, '\\\\')
|
||||
} else {
|
||||
window.__static = `http://localhost:${process.env.PORT}/static`
|
||||
}
|
||||
if (process.env.NODE_ENV !== 'development') window.__lib = process.env.libPath
|
||||
</script>
|
||||
<% } %>
|
||||
|
||||
<!-- webpack builds are automatically injected -->
|
||||
</body>
|
||||
|
||||
</html>
|
||||
12
fuintCashier/src/main/config/DisableButton.js
Normal file
@@ -0,0 +1,12 @@
|
||||
import { globalShortcut } from 'electron'
|
||||
import { DisableF12 } from "./const"
|
||||
|
||||
export default {
|
||||
Disablef12() {
|
||||
if (process.env.NODE_ENV === 'production' && DisableF12) {
|
||||
globalShortcut.register('f12', () => {
|
||||
console.log('用户试图启动控制台')
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
17
fuintCashier/src/main/config/StaticPath.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// 这里定义了静态文件路径的位置
|
||||
import path from 'path'
|
||||
import { DllFolder } from '@config/index'
|
||||
|
||||
/**
|
||||
* Set `__static` path to static files in production
|
||||
* https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-static-assets.html
|
||||
*/
|
||||
// 这个瓜皮全局变量只能在单个js中生效,而并不是整个主进程中
|
||||
if (process.env.NODE_ENV !== 'development') {
|
||||
global.__static = path.join(__dirname, '/static').replace(/\\/g, '\\\\')
|
||||
process.env.libPath = path.join(__dirname, '..', '..', '..', '..', `${DllFolder}`).replace(/\\/g, '\\\\')
|
||||
}
|
||||
|
||||
export const winURL = process.env.NODE_ENV === 'development' ? `http://localhost:${process.env.PORT}` : `file://${__dirname}/index.html`
|
||||
export const loadingURL = process.env.NODE_ENV === 'development' ? `http://localhost:${process.env.PORT}/static/loader.html` : `file://${__static}/loader.html`
|
||||
export const libPath = process.env.libPath
|
||||
7
fuintCashier/src/main/config/const.js
Normal file
@@ -0,0 +1,7 @@
|
||||
export const UseStartupChart = true
|
||||
export const IsUseSysTitle = false
|
||||
export const BuiltInServerPort = 25565
|
||||
export const hotPublishUrl = ""
|
||||
export const hotPublishConfigName = "update-config"
|
||||
export const openDevTools = false
|
||||
export const DisableF12 = true
|
||||
6
fuintCashier/src/main/config/hotPublish.js
Normal file
@@ -0,0 +1,6 @@
|
||||
import { hotPublishUrl, hotPublishConfigName } from './const'
|
||||
|
||||
export const hotPublishConfig = {
|
||||
url: hotPublishUrl,
|
||||
configName: hotPublishConfigName
|
||||
}
|
||||
68
fuintCashier/src/main/config/menu.js
Normal file
@@ -0,0 +1,68 @@
|
||||
// 这里是定义菜单的地方,详情请查看 https://electronjs.org/docs/api/menu
|
||||
const { dialog } = require('electron')
|
||||
const os = require('os')
|
||||
const version = require('../../../package.json').version
|
||||
const menu = [
|
||||
{
|
||||
label: '开始',
|
||||
submenu: [{
|
||||
label: '快速重启',
|
||||
accelerator: 'F5',
|
||||
role: 'reload'
|
||||
}, {
|
||||
label: '退出',
|
||||
accelerator: 'CmdOrCtrl+F4',
|
||||
role: 'close'
|
||||
}]
|
||||
},
|
||||
{
|
||||
label: '编辑',
|
||||
submenu: [{
|
||||
label: '撤销',
|
||||
accelerator: 'CmdOrCtrl+Z',
|
||||
role: 'undo'
|
||||
},
|
||||
{
|
||||
label: '重做',
|
||||
accelerator: 'Shift+CmdOrCtrl+Z',
|
||||
role: 'redo'
|
||||
},
|
||||
{
|
||||
label: '剪切',
|
||||
accelerator: 'CmdOrCtrl+X',
|
||||
role: 'cut'
|
||||
},
|
||||
{
|
||||
label: '复制',
|
||||
accelerator: 'CmdOrCtrl+C',
|
||||
role: 'copy'
|
||||
},
|
||||
{
|
||||
label: '粘贴',
|
||||
accelerator: 'CmdOrCtrl+V',
|
||||
role: 'paste'
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
label: '帮助',
|
||||
submenu: [{
|
||||
label: '关于',
|
||||
role: 'about',
|
||||
click: function () {
|
||||
info()
|
||||
}
|
||||
}]
|
||||
}]
|
||||
function info() {
|
||||
dialog.showMessageBox({
|
||||
title: '关于',
|
||||
type: 'info',
|
||||
message: 'fuint收银系统',
|
||||
detail: `版本信息:${version}\n引擎版本:${process.versions.v8}\n当前系统:${os.type()} ${os.arch()} ${os.release()}`,
|
||||
noLink: true,
|
||||
buttons: ['查看官网', '确定']
|
||||
})
|
||||
}
|
||||
export default menu
|
||||
41
fuintCashier/src/main/index.js
Normal file
@@ -0,0 +1,41 @@
|
||||
'use strict'
|
||||
|
||||
import { app } from 'electron'
|
||||
import initWindow from './services/windowManager'
|
||||
import DisableButton from './config/DisableButton'
|
||||
import electronDevtoolsInstaller, { VUEJS_DEVTOOLS } from 'electron-devtools-installer'
|
||||
|
||||
function onAppReady () {
|
||||
initWindow()
|
||||
DisableButton.Disablef12()
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
electronDevtoolsInstaller(VUEJS_DEVTOOLS)
|
||||
.then((name) => console.log(`installed: ${name}`))
|
||||
.catch(err => console.log('Unable to install `vue-devtools`: \n', err))
|
||||
}
|
||||
}
|
||||
// 禁止程序多开,此处需要单例锁的同学打开注释即可
|
||||
const gotTheLock = app.requestSingleInstanceLock()
|
||||
if(!gotTheLock){
|
||||
app.quit()
|
||||
}
|
||||
app.isReady() ? onAppReady() : app.on('ready', onAppReady)
|
||||
// 解决9.x跨域异常问题
|
||||
app.commandLine.appendSwitch('disable-features', 'OutOfBlinkCors')
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
// 所有平台均为所有窗口关闭就退出软件
|
||||
app.quit()
|
||||
})
|
||||
app.on('browser-window-created', () => {
|
||||
console.log('window-created')
|
||||
})
|
||||
|
||||
if (process.defaultApp) {
|
||||
if (process.argv.length >= 2) {
|
||||
app.removeAsDefaultProtocolClient('electron-vue-template')
|
||||
console.log('框架特殊性开发环境下无法使用')
|
||||
}
|
||||
} else {
|
||||
app.setAsDefaultProtocolClient('electron-vue-template')
|
||||
}
|
||||
44
fuintCashier/src/main/server/index.js
Normal file
@@ -0,0 +1,44 @@
|
||||
/* eslint-disable prefer-promise-reject-errors */
|
||||
import app from './server'
|
||||
import http from 'http'
|
||||
import config from '@config'
|
||||
const port = config.BuiltInServerPort
|
||||
var server = null
|
||||
app.set('port', port)
|
||||
|
||||
export default {
|
||||
StatrServer () {
|
||||
return new Promise((resolve, reject) => {
|
||||
server = http.createServer(app)
|
||||
server.listen(port)
|
||||
server.on('error', (error) => {
|
||||
switch (error.code) {
|
||||
case 'EACCES':
|
||||
reject('权限不足内置服务器启动失败,请使用管理员权限运行。')
|
||||
break
|
||||
case 'EADDRINUSE':
|
||||
reject('内置服务器端口已被占用,请检查。')
|
||||
break
|
||||
default:
|
||||
reject(error)
|
||||
}
|
||||
})
|
||||
server.on('listening', () => {
|
||||
resolve('服务端运行中')
|
||||
})
|
||||
})
|
||||
},
|
||||
StopServer () {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (server) {
|
||||
server.close()
|
||||
server.on('close', () => {
|
||||
server = null
|
||||
resolve(1)
|
||||
})
|
||||
} else {
|
||||
reject('服务端尚未开启')
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
14
fuintCashier/src/main/server/server.js
Normal file
@@ -0,0 +1,14 @@
|
||||
import express from 'express'
|
||||
const app = express()
|
||||
|
||||
app.get('/message', (req, res) => {
|
||||
res.send('这是来自node服务端的信息')
|
||||
})
|
||||
|
||||
app.post('/message', (req, res) => {
|
||||
if (req) {
|
||||
res.send(req + '--来自node')
|
||||
}
|
||||
})
|
||||
|
||||
export default app
|
||||
91
fuintCashier/src/main/services/HotUpdater.js
Normal file
@@ -0,0 +1,91 @@
|
||||
/**
|
||||
* power by biuuu
|
||||
*/
|
||||
|
||||
import { emptyDir, createWriteStream, readFile, copy, remove } from 'fs-extra'
|
||||
import { join, resolve } from 'path'
|
||||
import { promisify } from 'util'
|
||||
import { pipeline } from 'stream'
|
||||
import { app } from 'electron'
|
||||
import { gt } from 'semver'
|
||||
import { createHmac } from 'crypto'
|
||||
import extract from 'extract-zip'
|
||||
import { version } from '../../../package.json'
|
||||
import { hotPublishConfig } from '../config/hotPublish'
|
||||
import axios from 'axios'
|
||||
|
||||
const streamPipeline = promisify(pipeline)
|
||||
const appPath = app.getAppPath()
|
||||
const updatePath = resolve(appPath, '..', '..', 'update')
|
||||
const request = axios.create()
|
||||
|
||||
/**
|
||||
* @param data 文件流
|
||||
* @param type 类型,默认sha256
|
||||
* @param key 密钥,用于匹配计算结果
|
||||
* @returns {string} 计算结果
|
||||
* @author umbrella22
|
||||
* @date 2021-03-05
|
||||
*/
|
||||
function hash(data, type = 'sha256', key = 'Sky') {
|
||||
const hmac = createHmac(type, key)
|
||||
hmac.update(data)
|
||||
return hmac.digest('hex')
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param url 下载地址
|
||||
* @param filePath 文件存放地址
|
||||
* @returns {void}
|
||||
* @author umbrella22
|
||||
* @date 2021-03-05
|
||||
*/
|
||||
async function download(url, filePath) {
|
||||
const res = await request({ url, responseType: "stream" })
|
||||
await streamPipeline(res.data, createWriteStream(filePath))
|
||||
}
|
||||
|
||||
const updateInfo = {
|
||||
status: 'init',
|
||||
message: ''
|
||||
}
|
||||
|
||||
/**
|
||||
* @param windows 指主窗口
|
||||
* @returns {void}
|
||||
* @author umbrella22
|
||||
* @date 2021-03-05
|
||||
*/
|
||||
export const updater = async (windows) => {
|
||||
try {
|
||||
const res = await request({ url: `${hotPublishConfig.url}/${hotPublishConfig.configName}.json?time=${new Date().getTime()}`, })
|
||||
if (gt(res.data.version, version)) {
|
||||
await emptyDir(updatePath)
|
||||
const filePath = join(updatePath, res.data.name)
|
||||
updateInfo.status = 'downloading'
|
||||
if (windows) windows.webContents.send('hot-update-status', updateInfo);
|
||||
await download(`${hotPublishConfig.url}/${res.data.name}`, filePath);
|
||||
const buffer = await readFile(filePath)
|
||||
const sha256 = hash(buffer)
|
||||
if (sha256 !== res.data.hash) throw new Error('sha256 error')
|
||||
const appPathTemp = join(updatePath, 'temp')
|
||||
await extract(filePath, { dir: appPathTemp })
|
||||
updateInfo.status = 'moving'
|
||||
if (windows) windows.webContents.send('hot-update-status', updateInfo);
|
||||
await remove(join(`${appPath}`, 'dist'));
|
||||
await remove(join(`${appPath}`, 'package.json'));
|
||||
await copy(appPathTemp, appPath)
|
||||
updateInfo.status = 'finished'
|
||||
if (windows) windows.webContents.send('hot-update-status', updateInfo);
|
||||
}
|
||||
|
||||
|
||||
} catch (error) {
|
||||
updateInfo.status = 'failed'
|
||||
updateInfo.message = error
|
||||
if (windows) windows.webContents.send('hot-update-status', updateInfo)
|
||||
}
|
||||
}
|
||||
|
||||
export const getUpdateInfo = () => updateInfo
|
||||
76
fuintCashier/src/main/services/checkupdate.js
Normal file
@@ -0,0 +1,76 @@
|
||||
import { autoUpdater } from 'electron-updater'
|
||||
/**
|
||||
* -1 检查更新失败 0 正在检查更新 1 检测到新版本,准备下载 2 未检测到新版本 3 下载中 4 下载完成
|
||||
**/
|
||||
class Update {
|
||||
mainWindow
|
||||
constructor() {
|
||||
autoUpdater.setFeedURL('http://127.0.0.1:25565/')
|
||||
|
||||
// 当更新发生错误的时候触发。
|
||||
autoUpdater.on('error', (err) => {
|
||||
console.log('更新出现错误', err.message)
|
||||
if (err.message.includes('sha512 checksum mismatch')) {
|
||||
this.Message(this.mainWindow, -1, 'sha512校验失败')
|
||||
} else {
|
||||
this.Message(this.mainWindow, -1, '错误信息请看主进程控制台')
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
// 当开始检查更新的时候触发
|
||||
autoUpdater.on('checking-for-update', (event, arg) => {
|
||||
console.log('开始检查更新')
|
||||
this.Message(this.mainWindow, 0)
|
||||
})
|
||||
|
||||
// 发现可更新数据时
|
||||
autoUpdater.on('update-available', (event, arg) => {
|
||||
console.log('有更新')
|
||||
this.Message(this.mainWindow, 1)
|
||||
})
|
||||
|
||||
// 没有可更新数据时
|
||||
autoUpdater.on('update-not-available', (event, arg) => {
|
||||
console.log('没有更新')
|
||||
this.Message(this.mainWindow, 2)
|
||||
})
|
||||
|
||||
// 下载监听
|
||||
autoUpdater.on('download-progress', (progressObj) => {
|
||||
this.Message(this.mainWindow, 3, progressObj)
|
||||
})
|
||||
|
||||
// 下载完成
|
||||
autoUpdater.on('update-downloaded', () => {
|
||||
console.log('done')
|
||||
this.Message(this.mainWindow, 4)
|
||||
})
|
||||
}
|
||||
// 负责向渲染进程发送信息
|
||||
Message(mainWindow, type, data) {
|
||||
console.log('发送消息')
|
||||
const senddata = {
|
||||
state: type,
|
||||
msg: data || ''
|
||||
}
|
||||
mainWindow.webContents.send('update-msg', senddata)
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 执行自动更新检查
|
||||
checkUpdate(mainWindow) {
|
||||
this.mainWindow = mainWindow
|
||||
autoUpdater.checkForUpdates().catch(err => {
|
||||
console.log('网络连接问题', err)
|
||||
})
|
||||
}
|
||||
|
||||
// 退出并安装
|
||||
quitInstall() {
|
||||
autoUpdater.quitAndInstall()
|
||||
}
|
||||
}
|
||||
|
||||
export default Update
|
||||
63
fuintCashier/src/main/services/downloadFile.js
Normal file
@@ -0,0 +1,63 @@
|
||||
/* eslint-disable no-case-declarations */
|
||||
import { app, dialog } from 'electron'
|
||||
import path from 'path'
|
||||
import os from 'os'
|
||||
// 版本以package.json为基准。
|
||||
const version = require('../../../package.json').version
|
||||
// 您的下载地址
|
||||
const baseUrl = 'http://127.0.0.1:25565/'
|
||||
var Sysarch = null
|
||||
var defaultDownloadUrL = null
|
||||
// 识别操作系统位数D
|
||||
os.arch().includes('64') ? Sysarch = 'win64' : Sysarch = 'win32'
|
||||
// 识别操作系统
|
||||
// linux自己修改后缀名哦,我没有linux就没有测试了
|
||||
if (os.platform().includes('win32')) {
|
||||
defaultDownloadUrL = baseUrl + `electron_${version}_${Sysarch}.exe?${new Date().getTime()}`
|
||||
} else if (os.platform().includes('linux')) {
|
||||
defaultDownloadUrL = baseUrl + `electron_${version}_${Sysarch}?${new Date().getTime()}`
|
||||
} else {
|
||||
defaultDownloadUrL = baseUrl + `electron_${version}_mac.dmg?${new Date().getTime()}`
|
||||
}
|
||||
export default {
|
||||
download(mainWindow, downloadUrL) {
|
||||
mainWindow.webContents.downloadURL(downloadUrL || defaultDownloadUrL)
|
||||
mainWindow.webContents.session.on('will-download', (event, item, webContents) => {
|
||||
// 将文件保存在系统的下载目录
|
||||
const filePath = path.join(app.getPath('downloads'), item.getFilename())
|
||||
// 自动保存
|
||||
item.setSavePath(filePath)
|
||||
// 下载进度
|
||||
item.on('updated', (event, state) => {
|
||||
switch (state) {
|
||||
case 'progressing':
|
||||
mainWindow.webContents.send('download-progress', (item.getReceivedBytes() / item.getTotalBytes() * 100).toFixed(0))
|
||||
break
|
||||
case 'interrupted ':
|
||||
mainWindow.webContents.send('download-paused', true)
|
||||
break
|
||||
default:
|
||||
|
||||
break
|
||||
}
|
||||
})
|
||||
// 下载完成或失败
|
||||
item.once('done', (event, state) => {
|
||||
switch (state) {
|
||||
case 'completed':
|
||||
const data = {
|
||||
filePath
|
||||
}
|
||||
mainWindow.webContents.send('download-done', data)
|
||||
break
|
||||
case 'interrupted':
|
||||
mainWindow.webContents.send('download-error', true)
|
||||
dialog.showErrorBox('下载出错', '由于网络或其他未知原因导致下载出错.')
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
169
fuintCashier/src/main/services/ipcMain.js
Normal file
@@ -0,0 +1,169 @@
|
||||
import { ipcMain, dialog, BrowserWindow } from 'electron'
|
||||
import Server from '../server/index'
|
||||
import { winURL } from '../config/StaticPath'
|
||||
import downloadFile from './downloadFile'
|
||||
import Update from './checkupdate'
|
||||
import { updater } from './HotUpdater'
|
||||
import {platform} from "os";
|
||||
|
||||
export default {
|
||||
Mainfunc(IsUseSysTitle) {
|
||||
const allUpdater = new Update();
|
||||
ipcMain.handle('IsUseSysTitle', async () => {
|
||||
return IsUseSysTitle
|
||||
})
|
||||
ipcMain.handle('windows-mini', (event, args) => {
|
||||
BrowserWindow.fromWebContents(event.sender)?.minimize()
|
||||
})
|
||||
ipcMain.handle('window-max', async (event, args) => {
|
||||
if (BrowserWindow.fromWebContents(event.sender)?.isMaximized()) {
|
||||
BrowserWindow.fromWebContents(event.sender)?.unmaximize()
|
||||
return { status: false }
|
||||
} else {
|
||||
BrowserWindow.fromWebContents(event.sender)?.maximize()
|
||||
return { status: true }
|
||||
}
|
||||
})
|
||||
ipcMain.handle('window-close', (event, args) => {
|
||||
BrowserWindow.fromWebContents(event.sender)?.close()
|
||||
})
|
||||
ipcMain.handle('start-download', (event, msg) => {
|
||||
downloadFile.download(BrowserWindow.fromWebContents(event.sender), msg.downloadUrL)
|
||||
})
|
||||
ipcMain.handle('check-update', (event, args) => {
|
||||
allUpdater.checkUpdate(BrowserWindow.fromWebContents(event.sender))
|
||||
})
|
||||
ipcMain.handle('confirm-update', () => {
|
||||
allUpdater.quitInstall()
|
||||
})
|
||||
ipcMain.handle('hot-update', (event, arg) => {
|
||||
updater(BrowserWindow.fromWebContents(event.sender))
|
||||
})
|
||||
ipcMain.handle('open-messagebox', async (event, arg) => {
|
||||
const res = await dialog.showMessageBox(BrowserWindow.fromWebContents(event.sender), {
|
||||
type: arg.type || 'info',
|
||||
title: arg.title || '',
|
||||
buttons: arg.buttons || [],
|
||||
message: arg.message || '',
|
||||
noLink: arg.noLink || true
|
||||
})
|
||||
return res
|
||||
})
|
||||
ipcMain.handle('open-errorbox', (event, arg) => {
|
||||
dialog.showErrorBox(
|
||||
arg.title,
|
||||
arg.message
|
||||
)
|
||||
})
|
||||
ipcMain.handle('statr-server', async () => {
|
||||
try {
|
||||
const serveStatus = await Server.StatrServer()
|
||||
return serveStatus
|
||||
} catch (error) {
|
||||
dialog.showErrorBox(
|
||||
'错误',
|
||||
error
|
||||
)
|
||||
}
|
||||
})
|
||||
ipcMain.handle('stop-server', async (event, arg) => {
|
||||
try {
|
||||
const serveStatus = await Server.StopServer()
|
||||
return serveStatus
|
||||
} catch (error) {
|
||||
dialog.showErrorBox(
|
||||
'错误',
|
||||
error
|
||||
)
|
||||
}
|
||||
})
|
||||
let childWin = null;
|
||||
let cidArray = [];
|
||||
ipcMain.handle('open-win', (event, arg) => {
|
||||
let cidJson = { id: null, url: '' }
|
||||
let data = cidArray.filter((currentValue) => {
|
||||
if (currentValue.url === arg.url) {
|
||||
return currentValue
|
||||
}
|
||||
})
|
||||
if (data.length > 0) {
|
||||
//获取当前窗口
|
||||
let currentWindow = BrowserWindow.fromId(data[0].id)
|
||||
//聚焦窗口
|
||||
currentWindow.focus();
|
||||
} else {
|
||||
//获取主窗口ID
|
||||
let parentID = event.sender.id
|
||||
//创建窗口
|
||||
childWin = new BrowserWindow({
|
||||
width: arg?.width || 842,
|
||||
height: arg?.height || 595,
|
||||
//width 和 height 将设置为 web 页面的尺寸(译注: 不包含边框), 这意味着窗口的实际尺寸将包括窗口边框的大小,稍微会大一点。
|
||||
useContentSize: true,
|
||||
//自动隐藏菜单栏,除非按了Alt键。
|
||||
autoHideMenuBar: true,
|
||||
//窗口大小是否可调整
|
||||
resizable: arg?.resizable ?? false,
|
||||
//窗口的最小高度
|
||||
minWidth: arg?.minWidth || 842,
|
||||
show: arg?.show ?? false,
|
||||
//窗口透明度
|
||||
opacity: arg?.opacity || 1.0,
|
||||
//当前窗口的父窗口ID
|
||||
parent: parentID,
|
||||
frame: IsUseSysTitle,
|
||||
icon: '',
|
||||
webPreferences: {
|
||||
nodeIntegration: true,
|
||||
webSecurity: false,
|
||||
//使用webview标签 必须开启
|
||||
webviewTag: arg?.webview ?? false,
|
||||
// 如果是开发模式可以使用devTools
|
||||
devTools: process.env.NODE_ENV === 'development',
|
||||
// 在macos中启用橡皮动画
|
||||
scrollBounce: process.platform === 'darwin',
|
||||
// 临时修复打开新窗口报错
|
||||
contextIsolation: false
|
||||
}
|
||||
})
|
||||
childWin.loadURL(winURL + `#${arg.url}`)
|
||||
cidJson.id = childWin?.id
|
||||
cidJson.url = arg.url
|
||||
cidArray.push(cidJson)
|
||||
childWin.webContents.once('dom-ready', () => {
|
||||
childWin.show()
|
||||
childWin.webContents.send('send-data', arg.sendData)
|
||||
if (arg.IsPay) {
|
||||
// 检查支付时候自动关闭小窗口
|
||||
const testUrl = setInterval(() => {
|
||||
const Url = childWin.webContents.getURL()
|
||||
if (Url.includes(arg.PayUrl)) {
|
||||
childWin.close()
|
||||
}
|
||||
}, 1200)
|
||||
childWin.on('close', () => {
|
||||
clearInterval(testUrl)
|
||||
})
|
||||
}
|
||||
})
|
||||
childWin.on('closed', () => {
|
||||
childWin = null
|
||||
let index = cidArray.indexOf(cidJson)
|
||||
if (index > -1) {
|
||||
cidArray.splice(index, 1);
|
||||
}
|
||||
})
|
||||
}
|
||||
childWin.on('maximize', () => {
|
||||
if (cidJson.id != null) {
|
||||
BrowserWindow.fromId(cidJson.id).webContents.send("w-max", true)
|
||||
}
|
||||
})
|
||||
childWin.on('unmaximize', () => {
|
||||
if (cidJson.id != null) {
|
||||
BrowserWindow.fromId(cidJson.id).webContents.send("w-max", false)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
105
fuintCashier/src/main/services/windowManager.js
Normal file
@@ -0,0 +1,105 @@
|
||||
import { BrowserWindow, Menu, app } from 'electron'
|
||||
import { platform } from "os"
|
||||
import menuconfig from '../config/menu'
|
||||
import { openDevTools, IsUseSysTitle, UseStartupChart } from '../config/const'
|
||||
import setIpc from './ipcMain'
|
||||
import { winURL, loadingURL } from '../config/StaticPath'
|
||||
|
||||
var loadWindow = null
|
||||
var mainWindow = null
|
||||
setIpc.Mainfunc(IsUseSysTitle)
|
||||
|
||||
function createMainWindow() {
|
||||
/**
|
||||
* Initial window options
|
||||
*/
|
||||
mainWindow = new BrowserWindow({
|
||||
height: 800,
|
||||
useContentSize: true,
|
||||
width: 1700,
|
||||
color: "#ffffff",
|
||||
backgroundColor: "#ffffff",
|
||||
minWidth: 1000,
|
||||
show: false,
|
||||
frame: IsUseSysTitle,
|
||||
icon: '',
|
||||
titleBarStyle: platform().includes('win32') ? 'default' : 'hidden',
|
||||
webPreferences: {
|
||||
contextIsolation: false,
|
||||
nodeIntegration: true,
|
||||
webSecurity: false,
|
||||
// 如果是开发模式可以使用devTools
|
||||
devTools: process.env.NODE_ENV === 'development' || openDevTools,
|
||||
// devTools: true,
|
||||
// 在macos中启用橡皮动画
|
||||
scrollBounce: process.platform === 'darwin'
|
||||
}
|
||||
})
|
||||
// 这里设置只有开发环境才注入显示开发者模式
|
||||
if (process.env.NODE_ENV === 'development' || openDevTools) {
|
||||
menuconfig.push({
|
||||
label: '设置',
|
||||
submenu: [{
|
||||
label: '开发者模式',
|
||||
accelerator: 'CmdOrCtrl+I',
|
||||
role: 'toggledevtools'
|
||||
}]
|
||||
})
|
||||
}
|
||||
// 载入菜单
|
||||
const menu = Menu.buildFromTemplate(menuconfig)
|
||||
Menu.setApplicationMenu(menu)
|
||||
mainWindow.loadURL(winURL)
|
||||
|
||||
mainWindow.webContents.once('dom-ready', () => {
|
||||
mainWindow.show()
|
||||
if (process.env.NODE_ENV === 'development' || openDevTools) mainWindow.webContents.openDevTools(true)
|
||||
if (UseStartupChart) loadWindow.destroy()
|
||||
})
|
||||
mainWindow.on('maximize', () => {
|
||||
mainWindow.webContents.send("w-max", true)
|
||||
})
|
||||
mainWindow.on('unmaximize', () => {
|
||||
mainWindow.webContents.send("w-max", false)
|
||||
})
|
||||
mainWindow.on('closed', () => {
|
||||
mainWindow = null
|
||||
app.quit();
|
||||
})
|
||||
}
|
||||
|
||||
function loadingWindow() {
|
||||
loadWindow = new BrowserWindow({
|
||||
width: 400,
|
||||
height: 600,
|
||||
frame: false,
|
||||
backgroundColor: '#fff',
|
||||
color: '#fff',
|
||||
skipTaskbar: true,
|
||||
transparent: true,
|
||||
resizable: false,
|
||||
icon: '',
|
||||
webPreferences: { experimentalFeatures: true }
|
||||
})
|
||||
|
||||
loadWindow.loadURL(loadingURL)
|
||||
|
||||
loadWindow.show()
|
||||
|
||||
setTimeout(() => {
|
||||
createMainWindow()
|
||||
}, 2000)
|
||||
|
||||
loadWindow.on('closed', () => {
|
||||
loadWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
function initWindow() {
|
||||
if (UseStartupChart) {
|
||||
return loadingWindow()
|
||||
} else {
|
||||
return createMainWindow()
|
||||
}
|
||||
}
|
||||
export default initWindow
|
||||
17
fuintCashier/src/renderer/App.vue
Normal file
@@ -0,0 +1,17 @@
|
||||
<template>
|
||||
<div id="app">
|
||||
<c-header></c-header>
|
||||
<transition name="fade" mode="out-in">
|
||||
<router-view></router-view>
|
||||
</transition>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import CHeader from "./components/title";
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
/* CSS */
|
||||
</style>
|
||||
58
fuintCashier/src/renderer/api/balance.js
Normal file
@@ -0,0 +1,58 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 分页查询余额明细列表
|
||||
export function getBalanceList(query) {
|
||||
return request({
|
||||
url: 'backendApi/balance/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询明细详情
|
||||
export function getBalanceInfo(memberId) {
|
||||
return request({
|
||||
url: 'backendApi/balance/info/' + memberId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 更新状态
|
||||
export function updateBalanceStatus(id, status) {
|
||||
const data = {
|
||||
id,
|
||||
status
|
||||
}
|
||||
return request({
|
||||
url: 'backendApi/balance/updateStatus',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 获取配置信息
|
||||
export function getSettingInfo() {
|
||||
return request({
|
||||
url: 'backendApi/balance/setting',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 保存配置
|
||||
export function saveSetting(data) {
|
||||
return request({
|
||||
url: 'backendApi/balance/saveSetting',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 确定充值
|
||||
export function doRecharge(data) {
|
||||
return request({
|
||||
url: 'backendApi/balance/doRecharge',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
124
fuintCashier/src/renderer/api/cashier.js
Normal file
@@ -0,0 +1,124 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 初始化数据
|
||||
export function init(userId, cateId, page, pageSize) {
|
||||
return request({
|
||||
url: 'backendApi/cashier/init/' + userId,
|
||||
method: 'get',
|
||||
params: { cateId: cateId, page: page, pageSize: pageSize }
|
||||
})
|
||||
}
|
||||
|
||||
// 查询商品详情
|
||||
export function getGoodsInfo(goodsId) {
|
||||
return request({
|
||||
url: 'backendApi/cashier/getGoodsInfo/' + goodsId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 查询商品
|
||||
export function searchGoods(data) {
|
||||
return request({
|
||||
url: 'backendApi/cashier/searchGoods',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 查询会员信息
|
||||
export function getMemberInfo(data) {
|
||||
return request({
|
||||
url: 'backendApi/cashier/getMemberInfo',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 查询会员信息
|
||||
export function getMemberInfoById(userId) {
|
||||
return request({
|
||||
url: 'backendApi/cashier/getMemberInfoById/' + userId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 获取购物车列表
|
||||
export function getCartList(data) {
|
||||
return request({
|
||||
url: 'clientApi/cart/list',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 保存购物车
|
||||
export function saveCart(data) {
|
||||
return request({
|
||||
url: 'clientApi/cart/save',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除购物车
|
||||
export function removeFromCart(data) {
|
||||
return request({
|
||||
url: 'clientApi/cart/clear',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 提交结算
|
||||
export function submitSettlement(data) {
|
||||
return request({
|
||||
url: 'clientApi/settlement/submit',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 发起支付
|
||||
export function doPay(params) {
|
||||
return request({
|
||||
url: 'clientApi/pay/doPay',
|
||||
method: 'get',
|
||||
params: params
|
||||
})
|
||||
}
|
||||
|
||||
// 获取订单列表
|
||||
export function getOrderList(data) {
|
||||
return request({
|
||||
url: 'backendApi/order/latest',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 执行挂单
|
||||
export function doHangUp(data) {
|
||||
return request({
|
||||
url: 'backendApi/cashier/doHangUp',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 获取挂单
|
||||
export function getHangUpList() {
|
||||
return request({
|
||||
url: 'backendApi/cashier/getHangUpList',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 删除挂单
|
||||
export function removeHangUp(data) {
|
||||
return request({
|
||||
url: 'clientApi/cart/clear',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
75
fuintCashier/src/renderer/api/coupon.js
Normal file
@@ -0,0 +1,75 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 分页查询卡券列表
|
||||
export function getCouponList(query) {
|
||||
return request({
|
||||
url: 'backendApi/coupon/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询卡券信息
|
||||
export function getCouponInfo(id) {
|
||||
return request({
|
||||
url: 'backendApi/coupon/info/' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 更新状态
|
||||
export function updateCouponStatus(id, status) {
|
||||
const data = {
|
||||
id,
|
||||
status
|
||||
}
|
||||
return request({
|
||||
url: 'backendApi/coupon/updateStatus',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除卡券
|
||||
export function deleteCoupon(id) {
|
||||
return request({
|
||||
url: 'backendApi/coupon/delete/' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 保存卡券
|
||||
export function saveCoupon(data) {
|
||||
return request({
|
||||
url: 'backendApi/coupon/save',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 查询卡券核销信息
|
||||
export function getConfirmInfo(data) {
|
||||
return request({
|
||||
url: 'backendApi/doConfirm/info',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 执行核销
|
||||
export function doConfirm(data) {
|
||||
return request({
|
||||
url: 'backendApi/doConfirm/doConfirm',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 发放卡券
|
||||
export function sendCoupon(params) {
|
||||
return request({
|
||||
url: 'backendApi/coupon/sendCoupon',
|
||||
method: 'get',
|
||||
params: params
|
||||
})
|
||||
}
|
||||
76
fuintCashier/src/renderer/api/goods.js
Normal file
@@ -0,0 +1,76 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 分页查询商品列表
|
||||
export function getGoodsList(query) {
|
||||
return request({
|
||||
url: 'backendApi/goods/goods/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询商品详情
|
||||
export function getGoodsInfo(goodsId) {
|
||||
return request({
|
||||
url: 'backendApi/goods/goods/info/' + goodsId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 更新状态
|
||||
export function updateGoodsStatus(id, status) {
|
||||
const data = {
|
||||
id,
|
||||
status
|
||||
}
|
||||
return request({
|
||||
url: 'backendApi/goods/goods/updateStatus',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 保存分类数据
|
||||
export function saveGoods(data) {
|
||||
return request({
|
||||
url: 'backendApi/goods/goods/save',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 保存商品规格名称
|
||||
export function saveSpecName(data) {
|
||||
return request({
|
||||
url: 'backendApi/goods/goods/saveSpecName',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 保存商品规格值
|
||||
export function saveSpecValue(data) {
|
||||
return request({
|
||||
url: 'backendApi/goods/goods/saveSpecValue',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除商品规格
|
||||
export function deleteSpec(query) {
|
||||
return request({
|
||||
url: 'backendApi/goods/goods/deleteSpec',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 删除商品规格值
|
||||
export function deleteSpecValue(query) {
|
||||
return request({
|
||||
url: 'backendApi/goods/goods/deleteSpecValue',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
51
fuintCashier/src/renderer/api/login.js
Normal file
@@ -0,0 +1,51 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 登录方法
|
||||
export function login(username, password, captchaCode, uuid) {
|
||||
const data = {
|
||||
username,
|
||||
password,
|
||||
captchaCode,
|
||||
uuid
|
||||
}
|
||||
return request({
|
||||
url: 'backendApi/login/doLogin',
|
||||
headers: {
|
||||
isToken: false
|
||||
},
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 获取用户详细信息
|
||||
export function getInfo() {
|
||||
return request({
|
||||
url: 'backendApi/login/getInfo',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 退出方法
|
||||
export function logout() {
|
||||
return request({
|
||||
url: 'backendApi/login/logout',
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
|
||||
// 获取验证码
|
||||
export function getCodeImg() {
|
||||
return request({
|
||||
url: 'clientApi/captcha/getCode?v='+Math.random(),
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 系统消息
|
||||
export function message () {
|
||||
return request({
|
||||
url: 'clientApi/captcha/message',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
65
fuintCashier/src/renderer/api/member.js
Normal file
@@ -0,0 +1,65 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 分页查询会员列表
|
||||
export function getMemberList(query) {
|
||||
return request({
|
||||
url: 'backendApi/member/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询会员信息
|
||||
export function getMemberInfo(memberId) {
|
||||
return request({
|
||||
url: 'backendApi/member/info/' + memberId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 查询会员设置
|
||||
export function getMemberSetting() {
|
||||
return request({
|
||||
url: 'backendApi/member/setting',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 保存会员设置
|
||||
export function saveSetting(data) {
|
||||
return request({
|
||||
url: 'backendApi/member/saveSetting',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 更新会员状态
|
||||
export function updateMemberStatus(userId, status) {
|
||||
const data = {
|
||||
userId,
|
||||
status
|
||||
}
|
||||
return request({
|
||||
url: 'backendApi/member/updateStatus',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除会员信息
|
||||
export function deleteMember(memberId) {
|
||||
return request({
|
||||
url: 'backendApi/member/delete/' + memberId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 保存数据
|
||||
export function saveMember(data) {
|
||||
return request({
|
||||
url: 'backendApi/member/save',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
83
fuintCashier/src/renderer/api/order.js
Normal file
@@ -0,0 +1,83 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 分页查询订单列表
|
||||
export function getOrderList(data) {
|
||||
return request({
|
||||
url: 'backendApi/order/list',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 查询订单信息
|
||||
export function getOrderInfo(orderId) {
|
||||
return request({
|
||||
url: 'backendApi/order/info/' + orderId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 更新订单状态
|
||||
export function updateOrderStatus(orderId, status) {
|
||||
const data = {
|
||||
orderId,
|
||||
status
|
||||
}
|
||||
return request({
|
||||
url: 'backendApi/order/updateStatus',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除订单
|
||||
export function deleteOrder(orderId) {
|
||||
return request({
|
||||
url: 'backendApi/order/delete/' + orderId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 保存订单数据
|
||||
export function saveOrder(data) {
|
||||
return request({
|
||||
url: 'backendApi/order/save',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 验证核销订单
|
||||
export function verifyOrder(data) {
|
||||
return request({
|
||||
url: 'backendApi/order/verify',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 提交发货信息
|
||||
export function delivered(data) {
|
||||
return request({
|
||||
url: 'backendApi/order/delivered',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 获取配置信息
|
||||
export function getSettingInfo() {
|
||||
return request({
|
||||
url: 'backendApi/order/setting',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 保存配置
|
||||
export function saveSetting(data) {
|
||||
return request({
|
||||
url: 'backendApi/order/saveSetting',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
58
fuintCashier/src/renderer/api/point.js
Normal file
@@ -0,0 +1,58 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 分页查询积分明细列表
|
||||
export function getPointList(query) {
|
||||
return request({
|
||||
url: 'backendApi/point/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询明细详情
|
||||
export function getPointInfo(memberId) {
|
||||
return request({
|
||||
url: 'backendApi/point/info/' + memberId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 更新状态
|
||||
export function updatePointStatus(id, status) {
|
||||
const data = {
|
||||
id,
|
||||
status
|
||||
}
|
||||
return request({
|
||||
url: 'backendApi/point/updateStatus',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 获取配置信息
|
||||
export function getSettingInfo() {
|
||||
return request({
|
||||
url: 'backendApi/point/setting',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 保存配置
|
||||
export function saveSetting(data) {
|
||||
return request({
|
||||
url: 'backendApi/point/saveSetting',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 确定充值
|
||||
export function doRecharge(data) {
|
||||
return request({
|
||||
url: 'backendApi/point/doRecharge',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
44
fuintCashier/src/renderer/api/refund.js
Normal file
@@ -0,0 +1,44 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 分页查询退款订单列表
|
||||
export function getRefundList(query) {
|
||||
return request({
|
||||
url: 'backendApi/refund/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询订单信息
|
||||
export function getRefundInfo(refundId) {
|
||||
return request({
|
||||
url: 'backendApi/refund/info/' + refundId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 订单退款
|
||||
export function doRefund(data) {
|
||||
return request({
|
||||
url: 'backendApi/refund/doRefund',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除退款订单
|
||||
export function deleteRefund(refundId) {
|
||||
return request({
|
||||
url: 'backendApi/refund/delete/' + refundId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 保存退款订单
|
||||
export function saveRefund(data) {
|
||||
return request({
|
||||
url: 'backendApi/refund/save',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
10
fuintCashier/src/renderer/api/staff.js
Normal file
@@ -0,0 +1,10 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 分页查询员工列表
|
||||
export function getStaffList(query) {
|
||||
return request({
|
||||
url: 'backendApi/staff/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
0
fuintCashier/src/renderer/assets/.gitkeep
Normal file
BIN
fuintCashier/src/renderer/assets/404_images/404.png
Normal file
|
After Width: | Height: | Size: 96 KiB |
BIN
fuintCashier/src/renderer/assets/404_images/404_cloud.png
Normal file
|
After Width: | Height: | Size: 4.7 KiB |
BIN
fuintCashier/src/renderer/assets/images/avatar.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
fuintCashier/src/renderer/assets/images/bg.png
Normal file
|
After Width: | Height: | Size: 134 KiB |
BIN
fuintCashier/src/renderer/assets/images/cashier.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
fuintCashier/src/renderer/assets/images/goods.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
fuintCashier/src/renderer/assets/images/hot.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
fuintCashier/src/renderer/assets/images/life.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
fuintCashier/src/renderer/assets/images/love.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
fuintCashier/src/renderer/assets/images/noGoods.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
fuintCashier/src/renderer/assets/images/office.png
Normal file
|
After Width: | Height: | Size: 504 B |
BIN
fuintCashier/src/renderer/assets/images/order.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
fuintCashier/src/renderer/assets/logo.png
Normal file
|
After Width: | Height: | Size: 60 KiB |
BIN
fuintCashier/src/renderer/assets/user.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
51
fuintCashier/src/renderer/components/Breadcrumb/index.vue
Normal file
@@ -0,0 +1,51 @@
|
||||
<template>
|
||||
<el-breadcrumb class="app-breadcrumb" separator="/">
|
||||
<transition-group name="breadcrumb">
|
||||
<el-breadcrumb-item v-for="(item,index) in levelList" :key="item.path" v-if="item.meta.title">
|
||||
<span v-if="item.redirect==='noredirect'||index==levelList.length-1" class="no-redirect">{{item.meta.title}}</span>
|
||||
<router-link v-else :to="item.redirect||item.path">{{item.meta.title}}</router-link>
|
||||
</el-breadcrumb-item>
|
||||
</transition-group>
|
||||
</el-breadcrumb>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
created() {
|
||||
this.getBreadcrumb()
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
levelList: null
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
$route() {
|
||||
this.getBreadcrumb()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getBreadcrumb() {
|
||||
let matched = this.$route.matched.filter(item => item.name)
|
||||
const first = matched[0]
|
||||
if (first && first.name !== 'dashboard') {
|
||||
matched = [{ path: '/dashboard', meta: { title: '总览' }}].concat(matched)
|
||||
}
|
||||
this.levelList = matched
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
.app-breadcrumb.el-breadcrumb {
|
||||
display: inline-block;
|
||||
font-size: 14px;
|
||||
line-height: 50px;
|
||||
margin-left: 10px;
|
||||
.no-redirect {
|
||||
color: #97a8be;
|
||||
cursor: text;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
46
fuintCashier/src/renderer/components/Hamburger/index.vue
Normal file
@@ -0,0 +1,46 @@
|
||||
<template>
|
||||
<div>
|
||||
<svg t="1492500959545" @click="toggleClick" class="hamburger" :class="{ 'is-active': isActive }" style=""
|
||||
viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1691"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64">
|
||||
<path
|
||||
d="M966.8023 568.849776 57.196677 568.849776c-31.397081 0-56.850799-25.452695-56.850799-56.850799l0 0c0-31.397081 25.452695-56.849776 56.850799-56.849776l909.605623 0c31.397081 0 56.849776 25.452695 56.849776 56.849776l0 0C1023.653099 543.397081 998.200404 568.849776 966.8023 568.849776z"
|
||||
p-id="1692"></path>
|
||||
<path
|
||||
d="M966.8023 881.527125 57.196677 881.527125c-31.397081 0-56.850799-25.452695-56.850799-56.849776l0 0c0-31.397081 25.452695-56.849776 56.850799-56.849776l909.605623 0c31.397081 0 56.849776 25.452695 56.849776 56.849776l0 0C1023.653099 856.07443 998.200404 881.527125 966.8023 881.527125z"
|
||||
p-id="1693"></path>
|
||||
<path
|
||||
d="M966.8023 256.17345 57.196677 256.17345c-31.397081 0-56.850799-25.452695-56.850799-56.849776l0 0c0-31.397081 25.452695-56.850799 56.850799-56.850799l909.605623 0c31.397081 0 56.849776 25.452695 56.849776 56.850799l0 0C1023.653099 230.720755 998.200404 256.17345 966.8023 256.17345z"
|
||||
p-id="1694"></path>
|
||||
</svg>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
defineProps({
|
||||
isActive: {
|
||||
type: Boolean
|
||||
}
|
||||
})
|
||||
const emits = defineEmits(['toggle-click'])
|
||||
const toggleClick = () => {
|
||||
emits('toggle-click')
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.hamburger {
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
transform: rotate(90deg);
|
||||
transition: .38s;
|
||||
transform-origin: 50% 50%;
|
||||
}
|
||||
|
||||
.hamburger.is-active {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
</style>
|
||||
340
fuintCashier/src/renderer/components/LandingPage.vue
Normal file
@@ -0,0 +1,340 @@
|
||||
<template>
|
||||
<div id="wrapper">
|
||||
<img id="logo" :src="logo" alt="electron-vue" style="display: none"/>
|
||||
<main style="display: none">
|
||||
<div class="left-side">
|
||||
<span class="title">{{ $t("welcome") }}</span>
|
||||
<system-information></system-information>
|
||||
<div v-if="textarray.length === 0">
|
||||
<span>{{ text }}</span>
|
||||
</div>
|
||||
<div v-for="(itme, index) in textarray" :key="index" v-else>
|
||||
<span>{{ itme._id }}</span>
|
||||
<span>{{ itme.name }}</span>
|
||||
<span>{{ itme.age }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="right-side">
|
||||
<div class="doc">
|
||||
<div class="title alt">{{ $t("buttonTips") }}</div>
|
||||
<el-button type="primary" round @click="open()">{{
|
||||
$t("buttons.console")
|
||||
}}</el-button>
|
||||
<el-button type="primary" round @click="CheckUpdate('one')">{{
|
||||
$t("buttons.checkUpdate")
|
||||
}}</el-button>
|
||||
</div>
|
||||
<div class="doc">
|
||||
<el-button type="primary" round @click="CheckUpdate('two')">{{
|
||||
$t("buttons.checkUpdate2")
|
||||
}}</el-button>
|
||||
<el-button type="primary" round @click="StartServer">{{
|
||||
$t("buttons.startServer")
|
||||
}}</el-button>
|
||||
<el-button type="primary" round @click="StopServer">{{
|
||||
$t("buttons.stopServer")
|
||||
}}</el-button>
|
||||
<el-button type="primary" round @click="getMessage">{{
|
||||
$t("buttons.viewMessage")
|
||||
}}</el-button>
|
||||
</div>
|
||||
<div class="doc">
|
||||
<el-button type="primary" round @click="openNewWin">{{
|
||||
$t("buttons.openNewWindow")
|
||||
}}</el-button>
|
||||
<el-button type="primary" round @click="openDocument">{{
|
||||
$t("buttons.openDocument")
|
||||
}}</el-button>
|
||||
<el-button type="primary" round @click="changeLanguage">{{
|
||||
$t("buttons.changeLanguage")
|
||||
}}</el-button>
|
||||
</div>
|
||||
<div class="doc">
|
||||
<el-pagination :current-page="1" :page-sizes="[100, 200, 300, 400]" :page-size="100"
|
||||
layout="total, sizes, prev, pager, next, jumper" :total="400">
|
||||
</el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<el-dialog title="进度" :visible.sync="dialogVisible" :before-close="handleClose" center width="14%" top="45vh">
|
||||
<div class="conten">
|
||||
<el-progress type="dashboard" :percentage="percentage" :color="colors" :status="progressStaus"></el-progress>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SystemInformation from "./LandingPage/SystemInformation";
|
||||
import { message } from "@/api/login";
|
||||
import { ipcRenderer, shell } from "electron";
|
||||
export default {
|
||||
name: "landing-page",
|
||||
components: { SystemInformation },
|
||||
data: () => ({
|
||||
newdata: {
|
||||
name: "yyy",
|
||||
age: "12",
|
||||
},
|
||||
logo: require("@/assets/logo.png"),
|
||||
textarray: [],
|
||||
percentage: 0,
|
||||
colors: [
|
||||
{ color: "#f56c6c", percentage: 20 },
|
||||
{ color: "#e6a23c", percentage: 40 },
|
||||
{ color: "#6f7ad3", percentage: 60 },
|
||||
{ color: "#1989fa", percentage: 80 },
|
||||
{ color: "#5cb87a", percentage: 100 },
|
||||
],
|
||||
dialogVisible: false,
|
||||
progressStaus: null,
|
||||
filePath: "",
|
||||
}),
|
||||
created() {
|
||||
console.log("环境打印示例");
|
||||
console.log("__lib路径", __lib);
|
||||
console.log("环境变量", process.env.userConfig);
|
||||
ipcRenderer.on("download-progress", (event, arg) => {
|
||||
this.percentage = Number(arg);
|
||||
});
|
||||
ipcRenderer.on("download-error", (event, arg) => {
|
||||
if (arg) {
|
||||
this.progressStaus = "exception";
|
||||
this.percentage = 40;
|
||||
this.colors = "#d81e06";
|
||||
}
|
||||
});
|
||||
ipcRenderer.on("download-paused", (event, arg) => {
|
||||
if (arg) {
|
||||
this.progressStaus = "warning";
|
||||
this.$alert("下载由于未知原因被中断!", "提示", {
|
||||
confirmButtonText: "重试",
|
||||
callback: (action) => {
|
||||
ipcRenderer.invoke("satrt-download");
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
ipcRenderer.on("download-done", (event, age) => {
|
||||
this.filePath = age.filePath;
|
||||
this.progressStaus = "success";
|
||||
console.log("下载完成啦");
|
||||
this.$alert("更新下载完成!", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
callback: (action) => {
|
||||
shell.openPath(this.filePath);
|
||||
},
|
||||
});
|
||||
});
|
||||
ipcRenderer.on("update-msg", (event, age) => {
|
||||
console.log("update-msg", age);
|
||||
switch (age.state) {
|
||||
case -1:
|
||||
const msgdata = {
|
||||
title: "发生错误",
|
||||
message: age.msg,
|
||||
};
|
||||
this.dialogVisible = false;
|
||||
ipcRenderer.invoke("open-errorbox", msgdata);
|
||||
break;
|
||||
case 0:
|
||||
this.$message("正在检查更新");
|
||||
break;
|
||||
case 1:
|
||||
this.$message({
|
||||
type: "success",
|
||||
message: "已检查到新版本,开始下载",
|
||||
});
|
||||
this.dialogVisible = true;
|
||||
break;
|
||||
case 2:
|
||||
this.$message({ type: "success", message: "无新版本" });
|
||||
break;
|
||||
case 3:
|
||||
this.percentage = age.msg.percent.toFixed(1);
|
||||
break;
|
||||
case 4:
|
||||
this.progressStaus = "success";
|
||||
this.$alert("更新下载完成!", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
callback: (action) => {
|
||||
ipcRenderer.invoke("confirm-update");
|
||||
},
|
||||
});
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
ipcRenderer.on('hot-update-status', (event, arg) => {
|
||||
console.log(arg);
|
||||
if (arg.status === 'finished') {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: '热更新成功'
|
||||
});
|
||||
}
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
openNewWin() {
|
||||
let data = {
|
||||
url: "/form/index",
|
||||
resizable: true,
|
||||
};
|
||||
ipcRenderer.invoke("open-win", data);
|
||||
},
|
||||
openDocument() {
|
||||
shell.openExternal("https://zh-sky.gitee.io/electron-vue-template-doc/Overview/#%E5%8A%9F%E8%83%BD")
|
||||
},
|
||||
getMessage() {
|
||||
message().then((res) => {
|
||||
this.$alert(res.data, "提示", {
|
||||
confirmButtonText: "确定",
|
||||
});
|
||||
});
|
||||
},
|
||||
StopServer() {
|
||||
ipcRenderer.invoke("stop-server").then((res) => {
|
||||
this.$message({
|
||||
type: "success",
|
||||
message: "已关闭",
|
||||
});
|
||||
});
|
||||
},
|
||||
StartServer() {
|
||||
ipcRenderer.invoke("statr-server").then((res) => {
|
||||
if (res) {
|
||||
this.$message({
|
||||
type: "success",
|
||||
message: res,
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
// 获取electron方法
|
||||
open() { },
|
||||
CheckUpdate(data) {
|
||||
switch (data) {
|
||||
case "one":
|
||||
ipcRenderer.invoke("check-update").then((res) => {
|
||||
console.log("启动检查");
|
||||
});
|
||||
|
||||
break;
|
||||
case "two":
|
||||
ipcRenderer.invoke("start-download").then(() => {
|
||||
this.dialogVisible = true;
|
||||
});
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
handleClose() {
|
||||
this.dialogVisible = false;
|
||||
},
|
||||
changeLanguage() {
|
||||
let lang = this.$i18n.locale === "zh-CN" ? "en" : "zh-CN";
|
||||
this.$i18n.locale = lang;
|
||||
},
|
||||
},
|
||||
destroyed() {
|
||||
console.log("销毁了哦");
|
||||
ipcRenderer.removeAllListeners("confirm-message");
|
||||
ipcRenderer.removeAllListeners("download-done");
|
||||
ipcRenderer.removeAllListeners("download-paused");
|
||||
ipcRenderer.removeAllListeners("confirm-stop");
|
||||
ipcRenderer.removeAllListeners("confirm-start");
|
||||
ipcRenderer.removeAllListeners("confirm-download");
|
||||
ipcRenderer.removeAllListeners("download-progress");
|
||||
ipcRenderer.removeAllListeners("download-error");
|
||||
ipcRenderer.removeAllListeners("update-msg");
|
||||
},
|
||||
computed: {
|
||||
text() {
|
||||
return this.$i18n.t("waitDataLoading");
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: "Source Sans Pro", sans-serif;
|
||||
}
|
||||
|
||||
#wrapper {
|
||||
padding: 60px 80px;
|
||||
}
|
||||
|
||||
#logo {
|
||||
height: auto;
|
||||
margin-bottom: 20px;
|
||||
width: 420px;
|
||||
}
|
||||
|
||||
main {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
main>div {
|
||||
flex-basis: 50%;
|
||||
}
|
||||
|
||||
.left-side {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.welcome {
|
||||
color: #555;
|
||||
font-size: 23px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.title {
|
||||
color: #2c3e50;
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.title.alt {
|
||||
font-size: 18px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.doc {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.doc p {
|
||||
color: black;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.doc .el-button {
|
||||
margin-top: 10px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.doc .el-button+.el-button {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.conten {
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,75 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="title">{{ $t("about.system") }}</div>
|
||||
<div class="items">
|
||||
<div class="item" v-for="(item, index) in tips" :key="index">
|
||||
<div class="name" v-text="item.name" />
|
||||
<div class="value" v-text="item.value" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { platform, release, arch } from "os";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
tips() {
|
||||
return [
|
||||
{ name: this.$i18n.t("about.language"), value: this.$i18n.t("about.languageValue") },
|
||||
{ name: this.$i18n.t("about.currentPagePath"), value: this.$route.path },
|
||||
{ name: this.$i18n.t("about.currentPageName"), value: this.$route.name },
|
||||
{ name: this.$i18n.t("about.vueVersion"), value: require("vue/package.json").version },
|
||||
{
|
||||
name: this.$i18n.t("about.electronVersion"),
|
||||
value: process.versions.electron || "浏览器环境",
|
||||
},
|
||||
{ name: this.$i18n.t("about.nodeVersion"), value: process.versions.node || "浏览器环境" },
|
||||
{ name: this.$i18n.t("about.systemPlatform"), value: platform() },
|
||||
{ name: this.$i18n.t("about.systemVersion"), value: release() },
|
||||
{ name: this.$i18n.t("about.systemArch"), value: arch() + "位" },
|
||||
{ name: this.$i18n.t("about.currentEnvironment"), value: process.env?.NODE_ENV }
|
||||
]
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
console.log(this.$route);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.title {
|
||||
color: #888;
|
||||
font-size: 18px;
|
||||
font-weight: initial;
|
||||
letter-spacing: 0.25px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.items {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 6px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
.item .name {
|
||||
color: #6a6a6a;
|
||||
margin-right: 6px;
|
||||
}
|
||||
|
||||
.item .value {
|
||||
color: #35495e;
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
114
fuintCashier/src/renderer/components/Pagination/index.vue
Normal file
@@ -0,0 +1,114 @@
|
||||
<template>
|
||||
<div :class="{'hidden':hidden}" class="pagination-container">
|
||||
<el-pagination
|
||||
:background="background"
|
||||
:current-page.sync="currentPage"
|
||||
:page-size.sync="pageSize"
|
||||
:layout="layout"
|
||||
:page-sizes="pageSizes"
|
||||
:pager-count="pagerCount"
|
||||
:total="total"
|
||||
v-bind="$attrs"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { scrollTo } from '@/utils/scroll-to'
|
||||
|
||||
export default {
|
||||
name: 'Pagination',
|
||||
props: {
|
||||
total: {
|
||||
required: true,
|
||||
type: Number
|
||||
},
|
||||
page: {
|
||||
type: Number,
|
||||
default: 1
|
||||
},
|
||||
limit: {
|
||||
type: Number,
|
||||
default: 20
|
||||
},
|
||||
pageSizes: {
|
||||
type: Array,
|
||||
default() {
|
||||
return [10, 20, 30, 50]
|
||||
}
|
||||
},
|
||||
// 移动端页码按钮的数量端默认值5
|
||||
pagerCount: {
|
||||
type: Number,
|
||||
default: document.body.clientWidth < 992 ? 5 : 7
|
||||
},
|
||||
layout: {
|
||||
type: String,
|
||||
default: 'total, sizes, prev, pager, next, jumper'
|
||||
},
|
||||
background: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
autoScroll: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
hidden: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
currentPage: {
|
||||
get() {
|
||||
return this.page
|
||||
},
|
||||
set(val) {
|
||||
this.$emit('update:page', val)
|
||||
}
|
||||
},
|
||||
pageSize: {
|
||||
get() {
|
||||
return this.limit
|
||||
},
|
||||
set(val) {
|
||||
this.$emit('update:limit', val)
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleSizeChange(val) {
|
||||
if (this.currentPage * val > this.total) {
|
||||
this.currentPage = 1
|
||||
}
|
||||
this.$emit('pagination', { page: this.currentPage, limit: val })
|
||||
if (this.autoScroll) {
|
||||
scrollTo(0, 800)
|
||||
}
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.$emit('pagination', { page: val, limit: this.pageSize })
|
||||
if (this.autoScroll) {
|
||||
scrollTo(0, 800)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.pagination-container {
|
||||
background: #fff;
|
||||
padding: 32px 16px;
|
||||
}
|
||||
.pagination-container.hidden {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
57
fuintCashier/src/renderer/components/ScrollBar/index.vue
Normal file
@@ -0,0 +1,57 @@
|
||||
<template>
|
||||
<div class="scroll-container" ref="scrollContainer" @wheel.prevent="handleScroll" >
|
||||
<div class="scroll-wrapper" ref="scrollWrapper" :style="{top: top + 'px'}">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const delta = 15
|
||||
|
||||
export default {
|
||||
name: 'scrollBar',
|
||||
data() {
|
||||
return {
|
||||
top: 0
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleScroll(e) {
|
||||
const eventDelta = e.wheelDelta || -e.deltaY * 3
|
||||
const $container = this.$refs.scrollContainer
|
||||
const $containerHeight = $container.offsetHeight
|
||||
const $wrapper = this.$refs.scrollWrapper
|
||||
const $wrapperHeight = $wrapper.offsetHeight
|
||||
if (eventDelta > 0) {
|
||||
this.top = Math.min(0, this.top + eventDelta)
|
||||
} else {
|
||||
if ($containerHeight - delta < $wrapperHeight) {
|
||||
if (this.top < -($wrapperHeight - $containerHeight + delta)) {
|
||||
this.top = this.top
|
||||
} else {
|
||||
this.top = Math.max(this.top + eventDelta, $containerHeight - $wrapperHeight - delta)
|
||||
}
|
||||
} else {
|
||||
this.top = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
@import '../../styles/variables.scss';
|
||||
|
||||
.scroll-container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: $menuBg;
|
||||
.scroll-wrapper {
|
||||
position: absolute;
|
||||
width: 100%!important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
42
fuintCashier/src/renderer/components/SvgIcon/index.vue
Normal file
@@ -0,0 +1,42 @@
|
||||
<template>
|
||||
<svg :class="svgClass" aria-hidden="true">
|
||||
<use :xlink:href="iconName"></use>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'svg-icon',
|
||||
props: {
|
||||
iconClass: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
className: {
|
||||
type: String
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
iconName() {
|
||||
return `#icon-${this.iconClass}`
|
||||
},
|
||||
svgClass() {
|
||||
if (this.className) {
|
||||
return 'svg-icon ' + this.className
|
||||
} else {
|
||||
return 'svg-icon'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.svg-icon {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
vertical-align: -0.15em;
|
||||
fill: currentColor;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,112 @@
|
||||
<template>
|
||||
<div class="upload-container">
|
||||
<el-button
|
||||
:style="{ background: color, borderColor: color }"
|
||||
icon="el-icon-upload"
|
||||
size="mini"
|
||||
type="primary"
|
||||
@click="dialogVisible = true"
|
||||
>上传图片</el-button
|
||||
>
|
||||
<el-dialog :visible.sync="dialogVisible">
|
||||
<el-upload
|
||||
ref="upload"
|
||||
:multiple="true"
|
||||
:file-list="fileList"
|
||||
:show-file-list="true"
|
||||
:on-remove="handleRemove"
|
||||
:on-success="handleSuccess"
|
||||
:on-error="handleError"
|
||||
:data="picPostData"
|
||||
class="editor-slide-upload"
|
||||
action="https://jsonplaceholder.typicode.com/post/"
|
||||
list-type="picture-card"
|
||||
:limit="5"
|
||||
>
|
||||
<el-button size="small" type="primary">点击上传</el-button>
|
||||
</el-upload>
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit">确定</el-button>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "EditorSlideUpload",
|
||||
props: {
|
||||
color: {
|
||||
type: String,
|
||||
default: "#1890ff",
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dialogVisible: false,
|
||||
listObj: {},
|
||||
fileList: [],
|
||||
picPostData: {},
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
checkAllSuccess() {
|
||||
return Object.keys(this.listObj).every(
|
||||
(item) => this.listObj[item].hasSuccess
|
||||
);
|
||||
},
|
||||
handleSubmit() {
|
||||
const arr = Object.keys(this.listObj).map((v) => this.listObj[v]);
|
||||
console.log(arr);
|
||||
if (!this.checkAllSuccess()) {
|
||||
this.$message(
|
||||
"请等待所有图片上传完成,如果存在网络问题请刷新当前页重新上传"
|
||||
);
|
||||
return;
|
||||
}
|
||||
this.$emit("successCBK", arr);
|
||||
this.listObj = {};
|
||||
this.fileList = [];
|
||||
this.dialogVisible = false;
|
||||
},
|
||||
handleSuccess(response, file) {
|
||||
console.log("file", file);
|
||||
console.log("handleSuccess", response);
|
||||
const uid = file.uid;
|
||||
const objKeyArr = Object.keys(this.listObj);
|
||||
for (let i = 0, len = objKeyArr.length; i < len; i++) {
|
||||
if (this.listObj[objKeyArr[i]].uid === uid) {
|
||||
this.listObj[objKeyArr[i]].url = this.config.qiniuHost + response.key;
|
||||
this.listObj[objKeyArr[i]].hasSuccess = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
handleRemove(file) {
|
||||
const uid = file.uid;
|
||||
const objKeyArr = Object.keys(this.listObj);
|
||||
for (let i = 0, len = objKeyArr.length; i < len; i++) {
|
||||
if (this.listObj[objKeyArr[i]].uid === uid) {
|
||||
delete this.listObj[objKeyArr[i]];
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
handleError(err) {
|
||||
console.log(err);
|
||||
this.$alert(err, "发生错误", {
|
||||
confirmButtonText: "确定",
|
||||
callback: (action) => {},
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.editor-slide-upload {
|
||||
margin-bottom: 20px;
|
||||
::v-deep .el-upload--picture-card {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,60 @@
|
||||
let callbacks = []
|
||||
|
||||
function loadedTinymce () {
|
||||
// to fixed https://github.com/PanJiaChen/vue-element-admin/issues/2144
|
||||
// check is successfully downloaded script
|
||||
return window.tinymce
|
||||
}
|
||||
|
||||
const dynamicLoadScript = (src, callback) => {
|
||||
const existingScript = document.getElementById(src)
|
||||
const cb = callback || function () {}
|
||||
|
||||
if (!existingScript) {
|
||||
const script = document.createElement('script')
|
||||
console.log(src)
|
||||
script.src = src // src url for the third-party library being loaded.
|
||||
script.id = src
|
||||
document.body.appendChild(script)
|
||||
callbacks.push(cb)
|
||||
const onEnd = 'onload' in script ? stdOnEnd : ieOnEnd
|
||||
onEnd(script)
|
||||
}
|
||||
|
||||
if (existingScript && cb) {
|
||||
if (loadedTinymce()) {
|
||||
cb(null, existingScript)
|
||||
} else {
|
||||
callbacks.push(cb)
|
||||
}
|
||||
}
|
||||
|
||||
function stdOnEnd (script) {
|
||||
script.onload = function () {
|
||||
// this.onload = null here is necessary
|
||||
// because even IE9 works not like others
|
||||
this.onerror = this.onload = null
|
||||
for (const cb of callbacks) {
|
||||
cb(null, script)
|
||||
}
|
||||
callbacks = null
|
||||
}
|
||||
script.onerror = function () {
|
||||
this.onerror = this.onload = null
|
||||
cb(new Error('无法加载 ' + src), script)
|
||||
}
|
||||
}
|
||||
|
||||
function ieOnEnd (script) {
|
||||
script.onreadystatechange = function () {
|
||||
if (this.readyState !== 'complete' && this.readyState !== 'loaded') return
|
||||
this.onreadystatechange = null
|
||||
for (const cb of callbacks) {
|
||||
cb(null, script) // there is no way to catch loading errors in IE8
|
||||
}
|
||||
callbacks = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default dynamicLoadScript
|
||||
223
fuintCashier/src/renderer/components/Tinymce/index.vue
Normal file
@@ -0,0 +1,223 @@
|
||||
<template>
|
||||
<div
|
||||
:class="{ fullscreen: fullscreen }"
|
||||
class="tinymce-container"
|
||||
:style="{ width: containerWidth }"
|
||||
>
|
||||
<textarea :id="tinymceId" class="tinymce-textarea" />
|
||||
<div class="editor-custom-btn-container">
|
||||
<editorImage
|
||||
color="#1890ff"
|
||||
class="editor-upload-btn"
|
||||
@successCBK="imageSuccessCBK"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/**
|
||||
* docs:
|
||||
* https://panjiachen.github.io/vue-element-admin-site/feature/component/rich-editor.html#tinymce
|
||||
*/
|
||||
import editorImage from "./components/EditorImage";
|
||||
import plugins from "./plugins";
|
||||
import toolbar from "./toolbar";
|
||||
import load from "./dynamicLoadScript";
|
||||
|
||||
const tinymceFile = `${
|
||||
process.browser ? "static" : __static
|
||||
}/tinymce/tinymce.min.js`;
|
||||
|
||||
export default {
|
||||
name: "Tinymce",
|
||||
components: { editorImage },
|
||||
props: {
|
||||
id: {
|
||||
type: String,
|
||||
default: function () {
|
||||
return (
|
||||
"vue-tinymce-" +
|
||||
+new Date() +
|
||||
((Math.random() * 1000).toFixed(0) + "")
|
||||
);
|
||||
},
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
toolbar: {
|
||||
type: Array,
|
||||
required: false,
|
||||
default() {
|
||||
return [];
|
||||
},
|
||||
},
|
||||
menubar: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
height: {
|
||||
type: [Number, String],
|
||||
required: false,
|
||||
default: 360,
|
||||
},
|
||||
width: {
|
||||
type: [Number, String],
|
||||
required: false,
|
||||
default: "auto",
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
hasChange: false,
|
||||
hasInit: false,
|
||||
tinymceId: this.id,
|
||||
fullscreen: false,
|
||||
languageTypeList: {
|
||||
zh: "zh_CN",
|
||||
},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
containerWidth() {
|
||||
const width = this.width;
|
||||
if (/^[\d]+(\.[\d]+)?$/.test(width)) {
|
||||
// matches `100`, `'100'`
|
||||
return `${width}px`;
|
||||
}
|
||||
return width;
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
value(val) {
|
||||
if (!this.hasChange && this.hasInit) {
|
||||
this.$nextTick(() =>
|
||||
window.tinymce.get(this.tinymceId).setContent(val || "")
|
||||
);
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
activated() {
|
||||
if (window.tinymce) {
|
||||
this.initTinymce();
|
||||
}
|
||||
},
|
||||
deactivated() {
|
||||
this.destroyTinymce();
|
||||
},
|
||||
destroyed() {
|
||||
this.destroyTinymce();
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
// dynamic load tinymce from cdn
|
||||
load(tinymceFile, (err) => {
|
||||
if (err) {
|
||||
this.$message.error(err.message);
|
||||
return;
|
||||
}
|
||||
this.initTinymce();
|
||||
});
|
||||
},
|
||||
initTinymce() {
|
||||
const _this = this;
|
||||
window.tinymce.init({
|
||||
selector: `#${this.tinymceId}`,
|
||||
language: this.languageTypeList["zh"],
|
||||
min_height: this.height,
|
||||
body_class: "panel-body ",
|
||||
draggable_modal: true,
|
||||
object_resizing: false,
|
||||
toolbar: this.toolbar.length > 0 ? this.toolbar : toolbar,
|
||||
menubar: this.menubar,
|
||||
plugins: plugins,
|
||||
fontsize_formats: "12px 14px 16px 18px 24px 36px 48px 56px 72px",
|
||||
font_formats:
|
||||
"微软雅黑=Microsoft YaHei,Helvetica Neue,PingFang SC,sans-serif;苹果苹方=PingFang SC,Microsoft YaHei,sans-serif;宋体=simsun,serif;仿宋体=FangSong,serif;黑体=SimHei,sans-serif;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;",
|
||||
end_container_on_empty_block: true,
|
||||
powerpaste_word_import: "clean",
|
||||
code_dialog_height: 450,
|
||||
code_dialog_width: 1000,
|
||||
custom_undo_redo_levels: 50,
|
||||
advlist_bullet_styles: "square",
|
||||
advlist_number_styles: "default",
|
||||
imagetools_cors_hosts: ["www.tinymce.com", "codepen.io"],
|
||||
default_link_target: "_blank",
|
||||
link_title: false,
|
||||
branding: false,
|
||||
nonbreaking_force_tab: true, // inserting nonbreaking space need Nonbreaking Space Plugin
|
||||
init_instance_callback: (editor) => {
|
||||
if (_this.value) {
|
||||
editor.setContent(_this.value);
|
||||
}
|
||||
_this.hasInit = true;
|
||||
editor.on("NodeChange Change KeyUp SetContent", () => {
|
||||
this.hasChange = true;
|
||||
this.$emit("input", editor.getContent());
|
||||
});
|
||||
},
|
||||
setup(editor) {
|
||||
editor.on("FullscreenStateChanged", (e) => {
|
||||
_this.fullscreen = e.state;
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
destroyTinymce() {
|
||||
const tinymce = window.tinymce.get(this.tinymceId);
|
||||
if (this.fullscreen) {
|
||||
tinymce.execCommand("mceFullScreen");
|
||||
}
|
||||
|
||||
if (tinymce) {
|
||||
tinymce.destroy();
|
||||
}
|
||||
},
|
||||
setContent(value) {
|
||||
window.tinymce.get(this.tinymceId).setContent(value);
|
||||
},
|
||||
getContent() {
|
||||
window.tinymce.get(this.tinymceId).getContent();
|
||||
},
|
||||
imageSuccessCBK(arr) {
|
||||
const _this = this;
|
||||
arr.forEach((v) => {
|
||||
window.tinymce
|
||||
.get(_this.tinymceId)
|
||||
.insertContent(`<img class="wscnph" src="${v.url}" >`);
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.tinymce-container {
|
||||
position: relative;
|
||||
line-height: normal;
|
||||
}
|
||||
.tinymce-container >>> .mce-fullscreen {
|
||||
z-index: 10000;
|
||||
}
|
||||
.tinymce-textarea {
|
||||
visibility: hidden;
|
||||
z-index: -1;
|
||||
}
|
||||
.editor-custom-btn-container {
|
||||
position: absolute;
|
||||
right: 4px;
|
||||
top: 4px;
|
||||
}
|
||||
.fullscreen .editor-custom-btn-container {
|
||||
z-index: 10000;
|
||||
position: fixed;
|
||||
}
|
||||
.editor-upload-btn {
|
||||
display: inline-block;
|
||||
}
|
||||
</style>
|
||||
7
fuintCashier/src/renderer/components/Tinymce/plugins.js
Normal file
@@ -0,0 +1,7 @@
|
||||
// Any plugins you want to use has to be imported
|
||||
// Detail plugins list see https://www.tinymce.com/docs/plugins/
|
||||
// Custom builds see https://www.tinymce.com/download/custom-builds/
|
||||
|
||||
const plugins = ['print preview searchreplace autolink directionality visualblocks visualchars fullscreen image link media template code codesample table charmap hr pagebreak nonbreaking anchor insertdatetime advlist lists wordcount imagetools help emoticons autoresize']
|
||||
|
||||
export default plugins
|
||||
9
fuintCashier/src/renderer/components/Tinymce/toolbar.js
Normal file
@@ -0,0 +1,9 @@
|
||||
// Here is a list of the toolbar
|
||||
// Detail list see https://www.tinymce.com/docs/advanced/editor-control-identifiers/#toolbarcontrols
|
||||
|
||||
// eslint-disable-next-line no-multi-str
|
||||
const toolbar = ['code undo redo restoredraft | cut copy paste pastetext | forecolor backcolor bold italic underline strikethrough link anchor | alignleft aligncenter alignright alignjustify outdent indent | \
|
||||
styleselect formatselect fontselect fontsizeselect | bullist numlist | blockquote subscript superscript removeformat | \
|
||||
table image media charmap emoticons hr pagebreak insertdatetime print preview | fullscreen | bdmap indent2em lineheight formatpainter axupimgs']
|
||||
|
||||
export default toolbar
|
||||
116
fuintCashier/src/renderer/components/title/index.vue
Normal file
@@ -0,0 +1,116 @@
|
||||
<!-- -->
|
||||
<template>
|
||||
<div class="window-title" v-if="!IsUseSysTitle&&!IsWeb">
|
||||
<!-- 软件logo预留位置 -->
|
||||
<div style="-webkit-app-region: drag;" class="logo" v-if="isNotMac">
|
||||
<svg-icon icon-class="electron-logo"></svg-icon>
|
||||
</div>
|
||||
<!-- 菜单栏位置 -->
|
||||
<div></div>
|
||||
<!-- 中间标题位置 -->
|
||||
<div style="-webkit-app-region: drag;" class="title"></div>
|
||||
<div class="controls-container" v-if="isNotMac">
|
||||
<div class="windows-icon-bg" @click="Mini">
|
||||
<svg-icon icon-class="mini" class-name="icon-size"></svg-icon>
|
||||
</div>
|
||||
<div class="windows-icon-bg" @click="MixOrReduction">
|
||||
<svg-icon v-if="mix" icon-class="reduction" class-name="icon-size"></svg-icon>
|
||||
<svg-icon v-else icon-class="mix" class-name="icon-size"></svg-icon>
|
||||
</div>
|
||||
<div class="windows-icon-bg close-icon" @click="Close">
|
||||
<svg-icon icon-class="close" class-name="icon-size"></svg-icon>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ipcRenderer } from "electron";
|
||||
export default {
|
||||
data: () => ({
|
||||
mix: false,
|
||||
IsUseSysTitle: false,
|
||||
isNotMac: process.platform !== "darwin",
|
||||
IsWeb: process.env.IS_WEB
|
||||
}),
|
||||
|
||||
components: {},
|
||||
created() {
|
||||
ipcRenderer.invoke("IsUseSysTitle").then(res => {
|
||||
this.IsUseSysTitle = res;
|
||||
});
|
||||
},
|
||||
|
||||
mounted() {
|
||||
ipcRenderer.on("w-max",(event,state)=>{
|
||||
this.mix = state
|
||||
})
|
||||
},
|
||||
|
||||
methods: {
|
||||
Mini() {
|
||||
ipcRenderer.invoke("windows-mini");
|
||||
},
|
||||
MixOrReduction() {
|
||||
ipcRenderer.invoke("window-max").then(res=>{
|
||||
this.mix = res.status
|
||||
})
|
||||
},
|
||||
Close() {
|
||||
ipcRenderer.invoke("window-close");
|
||||
}
|
||||
},
|
||||
destroyed() {
|
||||
ipcRenderer.removeAllListeners("w-max");
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style rel='stylesheet/scss' lang='scss' scoped>
|
||||
.window-title {
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
display: flex;
|
||||
-webkit-app-region: drag;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
z-index: 99999;
|
||||
.title {
|
||||
text-align: center;
|
||||
}
|
||||
.logo {
|
||||
margin-left: 20px;
|
||||
}
|
||||
.controls-container {
|
||||
display: flex;
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
z-index: 3000;
|
||||
-webkit-app-region: no-drag;
|
||||
height: 100%;
|
||||
width: 138px;
|
||||
margin-left: auto;
|
||||
.windows-icon-bg {
|
||||
display: inline-block;
|
||||
-webkit-app-region: no-drag;
|
||||
height: 100%;
|
||||
width: 33.34%;
|
||||
color: rgba(129, 129, 129, 0.6);
|
||||
.icon-size {
|
||||
width: 12px;
|
||||
height: 15px;
|
||||
}
|
||||
}
|
||||
.windows-icon-bg:hover {
|
||||
background-color: rgba(182, 182, 182, 0.2);
|
||||
color: #333;
|
||||
}
|
||||
.close-icon:hover {
|
||||
background-color: rgba(232, 17, 35, 0.9);
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
64
fuintCashier/src/renderer/directive/dialog/drag.js
Normal file
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* v-dialogDrag 弹窗拖拽
|
||||
* Copyright (c) 2022 fuint
|
||||
*/
|
||||
|
||||
export default {
|
||||
bind(el, binding, vnode, oldVnode) {
|
||||
const value = binding.value
|
||||
if (value == false) return
|
||||
// 获取拖拽内容头部
|
||||
const dialogHeaderEl = el.querySelector('.el-dialog__header');
|
||||
const dragDom = el.querySelector('.el-dialog');
|
||||
dialogHeaderEl.style.cursor = 'move';
|
||||
// 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null);
|
||||
const sty = dragDom.currentStyle || window.getComputedStyle(dragDom, null);
|
||||
dragDom.style.position = 'absolute';
|
||||
dragDom.style.marginTop = 0;
|
||||
let width = dragDom.style.width;
|
||||
if (width.includes('%')) {
|
||||
width = +document.body.clientWidth * (+width.replace(/\%/g, '') / 100);
|
||||
} else {
|
||||
width = +width.replace(/\px/g, '');
|
||||
}
|
||||
dragDom.style.left = `${(document.body.clientWidth - width) / 2}px`;
|
||||
// 鼠标按下事件
|
||||
dialogHeaderEl.onmousedown = (e) => {
|
||||
// 鼠标按下,计算当前元素距离可视区的距离 (鼠标点击位置距离可视窗口的距离)
|
||||
const disX = e.clientX - dialogHeaderEl.offsetLeft;
|
||||
const disY = e.clientY - dialogHeaderEl.offsetTop;
|
||||
|
||||
// 获取到的值带px 正则匹配替换
|
||||
let styL, styT;
|
||||
|
||||
// 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px
|
||||
if (sty.left.includes('%')) {
|
||||
styL = +document.body.clientWidth * (+sty.left.replace(/\%/g, '') / 100);
|
||||
styT = +document.body.clientHeight * (+sty.top.replace(/\%/g, '') / 100);
|
||||
} else {
|
||||
styL = +sty.left.replace(/\px/g, '');
|
||||
styT = +sty.top.replace(/\px/g, '');
|
||||
};
|
||||
|
||||
// 鼠标拖拽事件
|
||||
document.onmousemove = function (e) {
|
||||
// 通过事件委托,计算移动的距离 (开始拖拽至结束拖拽的距离)
|
||||
const l = e.clientX - disX;
|
||||
const t = e.clientY - disY;
|
||||
|
||||
let finallyL = l + styL
|
||||
let finallyT = t + styT
|
||||
|
||||
// 移动当前元素
|
||||
dragDom.style.left = `${finallyL}px`;
|
||||
dragDom.style.top = `${finallyT}px`;
|
||||
|
||||
};
|
||||
|
||||
document.onmouseup = function (e) {
|
||||
document.onmousemove = null;
|
||||
document.onmouseup = null;
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
34
fuintCashier/src/renderer/directive/dialog/dragHeight.js
Normal file
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* v-dialogDragWidth 可拖动弹窗高度(右下角)
|
||||
* Copyright (c) 2022 fuint
|
||||
*/
|
||||
|
||||
export default {
|
||||
bind(el) {
|
||||
const dragDom = el.querySelector('.el-dialog');
|
||||
const lineEl = document.createElement('div');
|
||||
lineEl.style = 'width: 6px; background: inherit; height: 10px; position: absolute; right: 0; bottom: 0; margin: auto; z-index: 1; cursor: nwse-resize;';
|
||||
lineEl.addEventListener('mousedown',
|
||||
function(e) {
|
||||
// 鼠标按下,计算当前元素距离可视区的距离
|
||||
const disX = e.clientX - el.offsetLeft;
|
||||
const disY = e.clientY - el.offsetTop;
|
||||
// 当前宽度 高度
|
||||
const curWidth = dragDom.offsetWidth;
|
||||
const curHeight = dragDom.offsetHeight;
|
||||
document.onmousemove = function(e) {
|
||||
e.preventDefault(); // 移动时禁用默认事件
|
||||
// 通过事件委托,计算移动的距离
|
||||
const xl = e.clientX - disX;
|
||||
const yl = e.clientY - disY
|
||||
dragDom.style.width = `${curWidth + xl}px`;
|
||||
dragDom.style.height = `${curHeight + yl}px`;
|
||||
};
|
||||
document.onmouseup = function(e) {
|
||||
document.onmousemove = null;
|
||||
document.onmouseup = null;
|
||||
};
|
||||
}, false);
|
||||
dragDom.appendChild(lineEl);
|
||||
}
|
||||
}
|
||||
30
fuintCashier/src/renderer/directive/dialog/dragWidth.js
Normal file
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* v-dialogDragWidth 可拖动弹窗宽度(右侧边)
|
||||
* Copyright (c) 2022 fuint
|
||||
*/
|
||||
|
||||
export default {
|
||||
bind(el) {
|
||||
const dragDom = el.querySelector('.el-dialog');
|
||||
const lineEl = document.createElement('div');
|
||||
lineEl.style = 'width: 5px; background: inherit; height: 80%; position: absolute; right: 0; top: 0; bottom: 0; margin: auto; z-index: 1; cursor: w-resize;';
|
||||
lineEl.addEventListener('mousedown',
|
||||
function (e) {
|
||||
// 鼠标按下,计算当前元素距离可视区的距离
|
||||
const disX = e.clientX - el.offsetLeft;
|
||||
// 当前宽度
|
||||
const curWidth = dragDom.offsetWidth;
|
||||
document.onmousemove = function (e) {
|
||||
e.preventDefault(); // 移动时禁用默认事件
|
||||
// 通过事件委托,计算移动的距离
|
||||
const l = e.clientX - disX;
|
||||
dragDom.style.width = `${curWidth + l}px`;
|
||||
};
|
||||
document.onmouseup = function (e) {
|
||||
document.onmousemove = null;
|
||||
document.onmouseup = null;
|
||||
};
|
||||
}, false);
|
||||
dragDom.appendChild(lineEl);
|
||||
}
|
||||
}
|
||||
23
fuintCashier/src/renderer/directive/index.js
Normal file
@@ -0,0 +1,23 @@
|
||||
import hasRole from './permission/hasRole'
|
||||
import hasPermi from './permission/hasPermi'
|
||||
import dialogDrag from './dialog/drag'
|
||||
import dialogDragWidth from './dialog/dragWidth'
|
||||
import dialogDragHeight from './dialog/dragHeight'
|
||||
import clipboard from './module/clipboard'
|
||||
|
||||
const install = function(Vue) {
|
||||
Vue.directive('hasRole', hasRole)
|
||||
Vue.directive('hasPermi', hasPermi)
|
||||
Vue.directive('clipboard', clipboard)
|
||||
Vue.directive('dialogDrag', dialogDrag)
|
||||
Vue.directive('dialogDragWidth', dialogDragWidth)
|
||||
Vue.directive('dialogDragHeight', dialogDragHeight)
|
||||
}
|
||||
|
||||
if (window.Vue) {
|
||||
window['hasRole'] = hasRole
|
||||
window['hasPermi'] = hasPermi
|
||||
Vue.use(install); // eslint-disable-line
|
||||
}
|
||||
|
||||
export default install
|
||||
54
fuintCashier/src/renderer/directive/module/clipboard.js
Normal file
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* v-clipboard 文字复制剪贴
|
||||
* Copyright (c) 2022 fuint
|
||||
*/
|
||||
|
||||
import Clipboard from 'clipboard'
|
||||
export default {
|
||||
bind(el, binding, vnode) {
|
||||
switch (binding.arg) {
|
||||
case 'success':
|
||||
el._vClipBoard_success = binding.value;
|
||||
break;
|
||||
case 'error':
|
||||
el._vClipBoard_error = binding.value;
|
||||
break;
|
||||
default: {
|
||||
const clipboard = new Clipboard(el, {
|
||||
text: () => binding.value,
|
||||
action: () => binding.arg === 'cut' ? 'cut' : 'copy'
|
||||
});
|
||||
clipboard.on('success', e => {
|
||||
const callback = el._vClipBoard_success;
|
||||
callback && callback(e);
|
||||
});
|
||||
clipboard.on('error', e => {
|
||||
const callback = el._vClipBoard_error;
|
||||
callback && callback(e);
|
||||
});
|
||||
el._vClipBoard = clipboard;
|
||||
}
|
||||
}
|
||||
},
|
||||
update(el, binding) {
|
||||
if (binding.arg === 'success') {
|
||||
el._vClipBoard_success = binding.value;
|
||||
} else if (binding.arg === 'error') {
|
||||
el._vClipBoard_error = binding.value;
|
||||
} else {
|
||||
el._vClipBoard.text = function () { return binding.value; };
|
||||
el._vClipBoard.action = () => binding.arg === 'cut' ? 'cut' : 'copy';
|
||||
}
|
||||
},
|
||||
unbind(el, binding) {
|
||||
if (!el._vClipboard) return
|
||||
if (binding.arg === 'success') {
|
||||
delete el._vClipBoard_success;
|
||||
} else if (binding.arg === 'error') {
|
||||
delete el._vClipBoard_error;
|
||||
} else {
|
||||
el._vClipBoard.destroy();
|
||||
delete el._vClipBoard;
|
||||
}
|
||||
}
|
||||
}
|
||||
23
fuintCashier/src/renderer/directive/permission/hasPermi.js
Normal file
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* v-hasPermi 操作权限处理
|
||||
* Copyright https://www.fuint.cn
|
||||
*/
|
||||
export default {
|
||||
inserted(el, binding, vnode) {
|
||||
const { value } = binding
|
||||
const all_permission = "*:*:*";
|
||||
const permissions = localStorage.getItem("permissions") ? JSON.parse(localStorage.getItem("permissions")) : [];
|
||||
|
||||
if (permissions.length > 0 && value && value instanceof Array && value.length > 0) {
|
||||
const permissionFlag = value
|
||||
const hasPermissions = permissions.some(permission => {
|
||||
return all_permission === permission || permissionFlag.includes(permission)
|
||||
})
|
||||
if (!hasPermissions) {
|
||||
el.parentNode && el.parentNode.removeChild(el)
|
||||
}
|
||||
} else {
|
||||
throw new Error(`请设置操作权限标签值`)
|
||||
}
|
||||
}
|
||||
}
|
||||
22
fuintCashier/src/renderer/directive/permission/hasRole.js
Normal file
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* v-hasRole 角色权限处理
|
||||
* Copyright (c) 2023 https://www.fuint.cn
|
||||
*/
|
||||
export default {
|
||||
inserted(el, binding, vnode) {
|
||||
const { value } = binding
|
||||
const super_admin = "admin";
|
||||
const roles = localStorage.getItem("roles") ? localStorage.getItem("roles") : [];
|
||||
if (roles.length > 0 && value && value instanceof Array && value.length > 0) {
|
||||
const roleFlag = value
|
||||
const hasRole = roles.some(role => {
|
||||
return super_admin === role || roleFlag.includes(role)
|
||||
})
|
||||
if (!hasRole) {
|
||||
el.parentNode && el.parentNode.removeChild(el)
|
||||
}
|
||||
} else {
|
||||
throw new Error(`请设置角色权限标签值"`)
|
||||
}
|
||||
}
|
||||
}
|
||||
17
fuintCashier/src/renderer/error.js
Normal file
@@ -0,0 +1,17 @@
|
||||
import Vue from 'vue'
|
||||
|
||||
Vue.config.errorHandler = function (err, vm, info) {
|
||||
Vue.nextTick(() => {
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
console.group('%c >>>>>> 错误信息 >>>>>>', 'color:red')
|
||||
console.log(`%c ${info}`, 'color:blue')
|
||||
console.groupEnd()
|
||||
console.group('%c >>>>>> 发生错误的Vue 实例对象 >>>>>>', 'color:green')
|
||||
console.log(vm)
|
||||
console.groupEnd()
|
||||
console.group('%c >>>>>> 发生错误的原因及位置 >>>>>>', 'color:red')
|
||||
console.error(err)
|
||||
console.groupEnd()
|
||||
}
|
||||
})
|
||||
}
|
||||
7
fuintCashier/src/renderer/hooks/use-router.js
Normal file
@@ -0,0 +1,7 @@
|
||||
import { getCurrentInstance } from 'vue'
|
||||
export const useRoute = () => {
|
||||
return getCurrentInstance()?.proxy.$route
|
||||
}
|
||||
export const useRouter = () => {
|
||||
return getCurrentInstance()?.proxy.$router
|
||||
}
|
||||
25
fuintCashier/src/renderer/i18n/index.js
Normal file
@@ -0,0 +1,25 @@
|
||||
export default function loadLanguage() {
|
||||
const context = require.context("./languages", false, /([a-z_]+)\.js$/i)
|
||||
|
||||
const languages = context
|
||||
.keys()
|
||||
.map((key) => ({ key, name: key.match(/([a-z_-]+)\.js$/i)[1] }))
|
||||
.reduce(
|
||||
(languages, {key, name}) => {
|
||||
let lang;
|
||||
try {
|
||||
// 引入 element-ui 语言包
|
||||
lang = Object.assign(context(key).lang, require(`element-ui/lib/locale/lang/${name}`).default);
|
||||
} catch(err) {
|
||||
lang = context(key).lang
|
||||
}
|
||||
return {
|
||||
...languages,
|
||||
[name]: lang
|
||||
}
|
||||
},
|
||||
{}
|
||||
)
|
||||
|
||||
return languages
|
||||
}
|
||||
30
fuintCashier/src/renderer/i18n/languages/en.js
Normal file
@@ -0,0 +1,30 @@
|
||||
export const lang = {
|
||||
welcome: "Welcome use the framework",
|
||||
buttonTips: "You can click buttons to experience",
|
||||
waitDataLoading: "Wait data loading",
|
||||
about: {
|
||||
system: "About system",
|
||||
language: "language:",
|
||||
languageValue: "English",
|
||||
currentPagePath: "current page path:",
|
||||
currentPageName: "current page name:",
|
||||
vueVersion: "Vue version:",
|
||||
electronVersion: "Electron version:",
|
||||
nodeVersion: "Node version:",
|
||||
systemPlatform: "system platform:",
|
||||
systemVersion: "system version:",
|
||||
systemArch: "system arch:",
|
||||
currentEnvironment:"current environment:"
|
||||
},
|
||||
buttons: {
|
||||
console: "Console",
|
||||
checkUpdate: "Check update",
|
||||
checkUpdate2: "Check update(plan 2)",
|
||||
startServer: "Start server",
|
||||
stopServer: "Stop server",
|
||||
viewMessage: "view message",
|
||||
openNewWindow: "Open new window",
|
||||
openDocument: "Open document",
|
||||
changeLanguage: "Change language"
|
||||
}
|
||||
}
|
||||
30
fuintCashier/src/renderer/i18n/languages/zh-CN.js
Normal file
@@ -0,0 +1,30 @@
|
||||
export const lang = {
|
||||
welcome: "欢迎进入本框架",
|
||||
buttonTips: "您可以点击的按钮测试功能",
|
||||
waitDataLoading: "等待数据读取",
|
||||
about: {
|
||||
system: "关于系统",
|
||||
language: "语言:",
|
||||
languageValue: "中文简体",
|
||||
currentPagePath: "当前页面路径:",
|
||||
currentPageName: "当前页面名称:",
|
||||
vueVersion: "Vue版本:",
|
||||
electronVersion: "Electron版本:",
|
||||
nodeVersion: "Node版本:",
|
||||
systemPlatform: "系统平台:",
|
||||
systemVersion: "系统版本:",
|
||||
systemArch: "系统位数:",
|
||||
currentEnvironment:'当前环境:'
|
||||
},
|
||||
buttons: {
|
||||
console: "控制台打印",
|
||||
checkUpdate: "检查更新",
|
||||
checkUpdate2: "检查更新(第二种方法)",
|
||||
startServer: "启动内置服务端",
|
||||
stopServer: "关闭内置服务端",
|
||||
viewMessage: "查看消息",
|
||||
openNewWindow: "打开新窗口",
|
||||
openDocument: "打开文档",
|
||||
changeLanguage: "切换语言"
|
||||
}
|
||||
}
|
||||
9
fuintCashier/src/renderer/icons/index.js
Normal file
@@ -0,0 +1,9 @@
|
||||
import Vue from 'vue'
|
||||
import SvgIcon from '@/components/SvgIcon'// svg组件
|
||||
|
||||
// register globally
|
||||
Vue.component('svg-icon', SvgIcon)
|
||||
|
||||
const requireAll = requireContext => requireContext.keys().map(requireContext)
|
||||
const req = require.context('./svg', false, /\.svg$/)
|
||||
requireAll(req)
|
||||
1
fuintCashier/src/renderer/icons/svg/close.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width='11' height='11' viewBox='0 0 11 11' class="icon" xmlns='http://www.w3.org/2000/svg'><path d='M6.279 5.5L11 10.221l-.779.779L5.5 6.279.779 11 0 10.221 4.721 5.5 0 .779.779 0 5.5 4.721 10.221 0 11 .779 6.279 5.5z'/></svg>
|
||||
|
After Width: | Height: | Size: 366 B |
529
fuintCashier/src/renderer/icons/svg/electron-logo.svg
Normal file
@@ -0,0 +1,529 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="256px" height="256px" viewBox="0 0 256 256" enable-background="new 0 0 256 256" xml:space="preserve"> <image id="image0" width="256" height="256" x="0" y="0"
|
||||
href="data:image/png;base64,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" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 40 KiB |
1
fuintCashier/src/renderer/icons/svg/example.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1511504199105" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1815" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><defs><style type="text/css"></style></defs><path d="M770.56 460.8h250.88C998.4 220.16 803.84 25.6 563.2 2.56v250.88c104.96 20.48 186.88 102.4 207.36 207.36z m0 0M460.8 253.44V2.56C220.16 25.6 25.6 220.16 2.56 460.8h250.88c20.48-104.96 102.4-186.88 207.36-207.36z m0 0M563.2 770.56v250.88c243.2-23.04 435.2-217.6 460.8-460.8H773.12C750.08 668.16 668.16 750.08 563.2 770.56z m0 0M253.44 563.2H2.56c23.04 243.2 217.6 435.2 460.8 460.8V773.12C355.84 750.08 273.92 668.16 253.44 563.2z m0 0" fill="" p-id="1816"></path></svg>
|
||||
|
After Width: | Height: | Size: 852 B |
1
fuintCashier/src/renderer/icons/svg/eye-open.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1577518173588" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6318" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M512 128q69.675 0 135.51 21.163t115.498 54.997 93.483 74.837 73.685 82.006 51.67 74.837 32.17 54.827L1024 512q-2.347 4.992-6.315 13.483T998.87 560.17t-31.658 51.669-44.331 59.99-56.832 64.34-69.504 60.16-82.347 51.5-94.848 34.687T512 896q-69.675 0-135.51-21.163t-115.498-54.826-93.483-74.326-73.685-81.493-51.67-74.496-32.17-54.997L0 513.707q2.347-4.992 6.315-13.483t18.816-34.816 31.658-51.84 44.331-60.33 56.832-64.683 69.504-60.331 82.347-51.84 94.848-34.816T512 128.085z m0 85.333q-46.677 0-91.648 12.331t-81.152 31.83-70.656 47.146-59.648 54.485-48.853 57.686-37.675 52.821-26.325 43.99q12.33 21.674 26.325 43.52t37.675 52.351 48.853 57.003 59.648 53.845T339.2 767.02t81.152 31.488T512 810.667t91.648-12.331 81.152-31.659 70.656-46.848 59.648-54.186 48.853-57.344 37.675-52.651T927.957 512q-12.33-21.675-26.325-43.648t-37.675-52.65-48.853-57.345-59.648-54.186-70.656-46.848-81.152-31.659T512 213.334z m0 128q70.656 0 120.661 50.006T682.667 512 632.66 632.661 512 682.667 391.339 632.66 341.333 512t50.006-120.661T512 341.333z m0 85.334q-35.328 0-60.33 25.002T426.666 512t25.002 60.33T512 597.334t60.33-25.002T597.334 512t-25.002-60.33T512 426.666z" p-id="6319"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
1
fuintCashier/src/renderer/icons/svg/eye.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1503993826520" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7878" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><defs><style type="text/css"></style></defs><path d="M941.677063 391.710356c9.337669-14.005992 6.224772-32.68133-6.224772-43.575447-14.005992-10.894118-32.68133-7.78122-43.575447 6.224771-1.556449 1.556449-174.300768 205.426673-379.727441 205.426673-199.200878 0-379.727441-205.426673-381.28389-206.982098-10.894118-12.450567-31.124881-14.005992-43.575448-3.112898-12.450567 10.894118-14.005992 31.124881-3.112897 43.575448 3.112897 4.668323 40.46255 46.687322 99.600439 93.375667l-79.369676 82.48155c-12.450567 12.450567-10.894118 32.68133 1.556449 43.575448 3.112897 6.224772 10.894118 9.337669 18.675338 9.337669 7.78122 0 15.562441-3.112897 21.787213-9.337669l85.594447-88.706321c40.46255 28.013007 88.706321 54.469566 141.619438 73.14388L340.959485 707.631586c-4.668323 17.118889 4.669346 34.237779 21.787213 38.906101h9.337669c14.005992 0 26.456558-9.337669 29.568432-23.343661l32.68133-110.494556c24.90011 4.668323 51.356668 7.78122 77.813227 7.78122s52.913117-3.112897 77.813227-7.78122l32.68133 108.938108c3.112897 14.005992 17.118889 23.343661 29.569456 23.343661 3.112897 0 6.224772 0 7.78122-1.556449 17.118889-4.669346 26.456558-21.787212 21.788236-38.906102l-32.68133-108.938108c52.913117-18.675338 101.156888-45.131897 141.619438-73.14388l84.037998 87.150896c6.224772 6.224772 14.005992 9.337669 21.787212 9.337669 7.78122 0 15.562441-3.112897 21.787212-9.337669 12.450567-12.450567 12.450567-31.124881 1.556449-43.575448l-79.369675-82.48155c63.808258-46.688345 101.158934-91.820242 101.158934-91.820242z" p-id="7879"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
1
fuintCashier/src/renderer/icons/svg/form.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1511504319223" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3230" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><defs><style type="text/css"></style></defs><path d="M942.827259 80.3367c-11.42419-11.406794-26.41051-17.117866-41.377386-17.117866-14.985296 0-29.952172 5.711072-41.358967 17.117866L719.392444 221.014696l-19.441794 19.441794L681.577187 258.832 569.516971 370.909611 375.99749 564.411697l0 0.019443 0 84.372619 81.145112 0 0.010233 0 95.418186-95.435583 213.398228-213.400275 3.14155-3.14155-0.019443 0 9.979282-9.977235 0 0L942.827259 163.073052C965.697129 140.259464 965.697129 103.186104 942.827259 80.3367z" p-id="3231"></path><path d="M793.542234 367.521444 580.14196 580.939115 484.72582 676.376745 473.299583 687.800935 457.152834 687.800935 375.99749 687.800935 337.000314 687.800935 337.000314 648.803759 337.000314 564.411697 337.000314 548.264948 348.424504 536.838711 541.943986 343.338672 654.004201 231.259014 665.428392 219.834824 64.020082 219.834824 64.020082 960.781166 804.966425 960.781166 804.966425 356.116697 796.607036 364.475062Z" p-id="3232"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
1
fuintCashier/src/renderer/icons/svg/logo.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1564902100209" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="840" xmlns:xlink="http://www.w3.org/1999/xlink" width="300" height="300"><defs><style type="text/css"></style></defs><path d="M615.6 123.6h165.5L512 589.7 242.9 123.6H63.5L512 900.4l448.5-776.9z" fill="#41B883" p-id="841"></path><path d="M781.1 123.6H615.6L512 303 408.4 123.6H242.9L512 589.7z" fill="#34495E" p-id="842"></path></svg>
|
||||
|
After Width: | Height: | Size: 584 B |
1
fuintCashier/src/renderer/icons/svg/mini.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width='11' height='11' viewBox='0 0 11 11' class='icon' xmlns='http://www.w3.org/2000/svg'><path d='M11 4.399V5.5H0V4.399h11z'/></svg>
|
||||
|
After Width: | Height: | Size: 274 B |
1
fuintCashier/src/renderer/icons/svg/mix.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width='11' height='11' viewBox='0 0 11 11' class='icon' xmlns='http://www.w3.org/2000/svg'><path d='M11 0v11H0V0h11zM9.899 1.101H1.1V9.9h8.8V1.1z'/></svg>
|
||||
|
After Width: | Height: | Size: 294 B |
1
fuintCashier/src/renderer/icons/svg/nested.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1529559567446" class="icon" style="" viewBox="0 0 1167 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1767" xmlns:xlink="http://www.w3.org/1999/xlink" width="227.9296875" height="200"><defs><style type="text/css"></style></defs><path d="M0.015952 74.459413A2.286 2.286 1440 1 0 145.85218 74.459413 2.286 2.286 1440 1 0 0.015952 74.459413zM291.720312 1.525347 1166.801488 1.525347 1166.801488 147.361574 291.720312 147.361574zM291.720312 366.163773A2.286 2.286 1440 1 0 437.55654 366.163773 2.286 2.286 1440 1 0 291.720312 366.163773zM583.424672 293.229707 1166.801488 293.229707 1166.801488 439.065934 583.424672 439.065934zM291.720312 949.540588A2.286 2.286 1440 1 0 437.55654 949.540588 2.286 2.286 1440 1 0 291.720312 949.540588zM583.424672 876.638427 1166.801488 876.638427 1166.801488 1022.474654 583.424672 1022.474654zM583.424672 657.836228A2.286 2.286 1440 1 0 729.2609 657.836228 2.286 2.286 1440 1 0 583.424672 657.836228zM875.129032 584.934067 1166.801488 584.934067 1166.801488 730.770294 875.129032 730.770294z" p-id="1768"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
1
fuintCashier/src/renderer/icons/svg/password.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1503994678729" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="9229" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><defs><style type="text/css"></style></defs><path d="M780.8 354.579692 665.6 354.579692 665.6 311.689846c0-72.310154-19.849846-193.299692-153.6-193.299692-138.870154 0-153.6 135.049846-153.6 193.299692l0 42.889846L243.2 354.579692 243.2 311.689846C243.2 122.249846 348.790154 0 512 0s268.8 122.249846 268.8 311.689846L780.8 354.579692zM588.8 669.420308C588.8 625.900308 554.220308 590.769231 512 590.769231s-76.8 35.131077-76.8 78.651077c0 29.459692 15.399385 54.468923 38.439385 67.820308l0 89.639385c0 21.740308 17.250462 39.699692 38.4 39.699692s38.4-17.959385 38.4-39.699692l0-89.639385C573.44 723.889231 588.8 698.88 588.8 669.420308zM896 512l0 393.609846c0 65.260308-51.869538 118.390154-115.2 118.390154L243.2 1024c-63.291077 0-115.2-53.129846-115.2-118.390154L128 512c0-65.220923 51.869538-118.390154 115.2-118.390154l537.6 0C844.130462 393.609846 896 446.779077 896 512z" p-id="9230"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
1
fuintCashier/src/renderer/icons/svg/reduction.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width='11' height='11' viewBox='0 0 11 11' class="icon" xmlns='http://www.w3.org/2000/svg'><path d='M11 8.798H8.798V11H0V2.202h2.202V0H11v8.798zm-3.298-5.5h-6.6v6.6h6.6v-6.6zM9.9 1.1H3.298v1.101h5.5v5.5h1.1v-6.6z'/></svg>
|
||||
|
After Width: | Height: | Size: 361 B |
1
fuintCashier/src/renderer/icons/svg/table.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1511504440567" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5070" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><defs><style type="text/css"></style></defs><path d="M568.6 0h454.9v454.9H568.6V0z m0 568.6h454.9v454.9H568.6V568.6zM0 568.6h454.9v454.9H0V568.6zM0 0h454.9v454.9H0V0z" fill="" p-id="5071"></path></svg>
|
||||
|
After Width: | Height: | Size: 532 B |
1
fuintCashier/src/renderer/icons/svg/tree.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1511512690058" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3507" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><defs><style type="text/css"></style></defs><path d="M1013.703 693.345c6.865 6.865 10.297 14.874 10.297 24.027l0 205.944c0 9.916-3.432 18.115-10.297 24.599-6.865 6.483-15.255 9.725-25.171 9.725L782.588 957.64c-9.153 0-17.162-3.242-24.027-9.725-6.865-6.483-10.297-14.683-10.297-24.599L748.264 717.372c0-6.102 1.526-11.823 4.577-17.162s7.246-9.534 12.586-12.586 11.06-4.577 17.162-4.577l77.801 0L860.39 546.896c0-4.577-1.144-8.772-3.432-12.586s-5.339-6.865-9.153-9.153-8.009-3.432-12.585-3.432L543.464 521.725l0 161.323 77.801 0c9.153 0 17.162 3.432 24.027 10.297s10.297 14.874 10.297 24.027l0 205.944c0 6.102-1.526 11.823-4.577 17.162s-7.246 9.534-12.585 12.585-11.06 4.577-17.162 4.577L415.321 957.64c-6.102 0-11.823-1.526-17.162-4.577s-9.725-7.246-13.158-12.585-5.149-11.06-5.149-17.162L379.852 717.372c0-9.153 3.432-17.162 10.297-24.027s15.255-10.297 25.171-10.297l76.657 0L491.977 521.725 188.782 521.725c-7.628 0-13.92 2.479-18.878 7.437-4.958 4.958-7.437 10.869-7.437 17.734l0 136.152 77.801 0c9.916 0 18.115 3.432 24.599 10.297s9.725 14.874 9.725 24.027l0 205.944c0 9.916-3.242 18.115-9.725 24.599-6.483 6.483-14.683 9.725-24.599 9.725L34.324 957.64c-3.814 0-7.437-0.572-10.869-1.716-3.432-1.144-6.483-2.67-9.153-4.577-2.67-1.907-5.149-4.386-7.437-7.437-2.288-3.051-4.004-6.293-5.149-9.725C0.572 930.753 0 927.13 0 923.316L0 717.372c0-3.051 0.381-6.102 1.144-9.153s1.907-5.721 3.432-8.009 3.432-4.577 5.721-6.865 4.577-4.195 6.865-5.721 4.958-2.67 8.009-3.432 6.102-1.144 9.153-1.144l77.801 0L112.125 495.41c0-6.865 2.479-12.776 7.437-17.734s10.869-7.437 17.734-7.437l354.682 0L491.978 342.096l-76.657 0c-9.916 0-18.306-3.432-25.171-10.297s-10.297-14.874-10.297-24.027L379.853 101.828c0-9.916 3.432-18.306 10.297-25.171s15.255-10.297 25.171-10.297l205.944 0c6.102 0 11.823 1.716 17.162 5.149 5.339 3.432 9.534 7.818 12.585 13.158 3.051 5.339 4.577 11.06 4.577 17.162l0 205.944c0 9.153-3.432 17.162-10.297 24.027s-14.874 10.297-24.027 10.297l-77.801 0 0 128.143L885.56 470.24c7.628 0 13.92 2.479 18.878 7.437s7.437 10.869 7.437 17.734l0 187.638 76.657 0C998.448 683.048 1006.838 686.48 1013.703 693.345z" p-id="3508"></path></svg>
|
||||
|
After Width: | Height: | Size: 2.4 KiB |
1
fuintCashier/src/renderer/icons/svg/user.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1503993891882" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7986" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><defs><style type="text/css"></style></defs><path d="M504.951 511.98c93.49 0 169.28-74.002 169.28-165.26 0-91.276-75.79-165.248-169.28-165.248-93.486 0-169.287 73.972-169.279 165.248-0.001 91.258 75.793 165.26 169.28 165.26z m77.6 55.098H441.466c-120.767 0-218.678 95.564-218.678 213.45V794.3c0 48.183 97.911 48.229 218.678 48.229H582.55c120.754 0 218.66-1.78 218.66-48.229v-13.77c0-117.887-97.898-213.45-218.66-213.45z" p-id="7987"></path></svg>
|
||||
|
After Width: | Height: | Size: 777 B |
14
fuintCashier/src/renderer/layout/components/AppMain.vue
Normal file
@@ -0,0 +1,14 @@
|
||||
<template>
|
||||
<section class="app-main">
|
||||
<transition name="fade" mode="out-in">
|
||||
<router-view />
|
||||
</transition>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { defineComponent } from "vue";
|
||||
defineComponent({
|
||||
name: "AppMain"
|
||||
});
|
||||
</script>
|
||||
174
fuintCashier/src/renderer/layout/components/Navbar.vue
Normal file
@@ -0,0 +1,174 @@
|
||||
<template>
|
||||
<el-menu :class="'navbar-header-fixed' + (isMac ? ' dragTitle' : '')" mode="horizontal">
|
||||
<div class="top-right">
|
||||
<div class="hb-bd">
|
||||
<hamburger class="hamburger-container" @toggle-click="toggleSideBar" :isActive="sidebarComp.opened"></hamburger>
|
||||
<breadcrumb></breadcrumb>
|
||||
</div>
|
||||
|
||||
<div class="top-select">
|
||||
<div class="go-index">{{ time }}</div>
|
||||
<div class="select-right">
|
||||
<el-dropdown trigger="click">
|
||||
<div>
|
||||
<el-image :src="userImage" class="avatar">
|
||||
<div slot="error" class="image-slot">
|
||||
<i class="el-icon-picture-outline"></i>
|
||||
</div>
|
||||
</el-image>
|
||||
<div class="el-dropdown-link">
|
||||
你好: {{ userName }}
|
||||
<i class="el-icon-arrow-down el-icon--right"></i>
|
||||
</div>
|
||||
</div>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<router-link to="/">
|
||||
<el-dropdown-item>返回首页</el-dropdown-item>
|
||||
</router-link>
|
||||
<el-dropdown-item @click.native="logout">
|
||||
<span>切换账号</span>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="logout">
|
||||
<span>退出登录</span>
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-menu>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted, onUnmounted, computed, defineComponent } from "vue";
|
||||
import { useAppStore } from "@/store/app"
|
||||
import { useUserStore } from "@/store/user"
|
||||
import { format } from "date-fns";
|
||||
import Breadcrumb from "@/components/Breadcrumb";
|
||||
import Hamburger from "@/components/Hamburger";
|
||||
import userImage from "@/assets/user.png"
|
||||
import { Message } from "element-ui"
|
||||
import { useRouter } from "@/hooks/use-router";
|
||||
|
||||
defineComponent({
|
||||
name: 'Navbar'
|
||||
})
|
||||
|
||||
const time = ref("")
|
||||
const isMac = process.platform === "darwin"
|
||||
let timer = null
|
||||
onMounted(() => {
|
||||
timer = setInterval(() => {
|
||||
time.value = format(new Date(), "yyyy/MM/dd HH:mm");
|
||||
}, 60000);
|
||||
})
|
||||
onUnmounted(() => {
|
||||
clearInterval(timer);
|
||||
timer = null;
|
||||
})
|
||||
|
||||
const { ToggleSideBar, sidebarStatus } = useAppStore()
|
||||
const sidebarComp = computed(() => sidebarStatus)
|
||||
const toggleSideBar = () => {
|
||||
ToggleSideBar()
|
||||
}
|
||||
|
||||
const { logOut, name } = useUserStore()
|
||||
const router = useRouter()
|
||||
const userName = computed(() => name)
|
||||
const logout = () => {
|
||||
logOut().then(() => {
|
||||
Message({
|
||||
message: "退出成功",
|
||||
type: "success"
|
||||
});
|
||||
router.push('/login')
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
.navbar-header-fixed {
|
||||
transition: width 0.28s;
|
||||
width: calc(100% - 256px);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: fixed;
|
||||
right: 0;
|
||||
z-index: 1002;
|
||||
height: 62px;
|
||||
|
||||
.hamburger-container {
|
||||
line-height: 58px;
|
||||
height: 50px;
|
||||
float: left;
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 199px;
|
||||
height: 62px;
|
||||
}
|
||||
|
||||
.top-right {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #ffffff;
|
||||
justify-content: space-between;
|
||||
padding: 0 19px;
|
||||
|
||||
.hb-bd {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
margin-right: 10px;
|
||||
|
||||
::v-deep img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
.top-select {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.go-index {
|
||||
color: #333333;
|
||||
font-weight: 400;
|
||||
margin-right: 20px;
|
||||
padding-right: 20px;
|
||||
border-right: 1px solid #cccccc;
|
||||
}
|
||||
|
||||
.select-right ::v-deep .el-dropdown>span {
|
||||
font-size: 6px;
|
||||
}
|
||||
|
||||
.select-right {
|
||||
.el-dropdown-link {
|
||||
color: #333333;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
::v-deep .el-dropdown-selfdefine {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dragTitle {
|
||||
-webkit-app-region: drag;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
<template>
|
||||
<div v-if="!item.hidden && item.children" class="menu-wrapper" :class="collapse ? `` : `active-menu-wrapper`">
|
||||
<div v-if="item.onlyShowfirst">
|
||||
<router-link v-if="OneShowingChild(item.children[0]) && !onlyOneChild.children && !item.alwaysShow"
|
||||
:to="resolvePath(onlyOneChild.path)">
|
||||
<el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{ 'submenu-title-noDropdown': !isNest }">
|
||||
<svg-icon v-if="onlyOneChild.meta && onlyOneChild.meta.icon" :icon-class="onlyOneChild.meta.icon"></svg-icon>
|
||||
<span v-if="onlyOneChild.meta && onlyOneChild.meta.title" slot="title">{{ onlyOneChild.meta.title }}</span>
|
||||
</el-menu-item>
|
||||
</router-link>
|
||||
</div>
|
||||
|
||||
<div v-else>
|
||||
<router-link v-if="hasOneShowingChild(item.children) && !onlyOneChild.children && !item.alwaysShow"
|
||||
:to="resolvePath(onlyOneChild.path)">
|
||||
<el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{ 'submenu-title-noDropdown': !isNest }">
|
||||
<svg-icon v-if="onlyOneChild.meta && onlyOneChild.meta.icon" :icon-class="onlyOneChild.meta.icon"></svg-icon>
|
||||
<span v-if="onlyOneChild.meta && onlyOneChild.meta.title" slot="title">{{ onlyOneChild.meta.title }}</span>
|
||||
</el-menu-item>
|
||||
</router-link>
|
||||
|
||||
<el-submenu v-else :index="item.name || item.path">
|
||||
<template slot="title">
|
||||
<svg-icon v-if="item.meta && item.meta.icon" :icon-class="item.meta.icon"></svg-icon>
|
||||
<span v-if="item.meta && item.meta.title" slot="title">{{ item.meta.title }}</span>
|
||||
</template>
|
||||
|
||||
<template v-for="child in item.children" v-if="!child.hidden">
|
||||
<sidebar-item :is-nest="true" class="nest-menu" v-if="child.children && child.children.length > 0" :item="child"
|
||||
:key="child.path" :base-path="resolvePath(child.path)"></sidebar-item>
|
||||
|
||||
<router-link v-else :to="resolvePath(child.path)" :key="child.name">
|
||||
<el-menu-item :index="resolvePath(child.path)">
|
||||
<svg-icon v-if="child.meta && child.meta.icon" :icon-class="child.meta.icon"></svg-icon>
|
||||
<span v-if="child.meta && child.meta.title" slot="title">{{ child.meta.title }}</span>
|
||||
</el-menu-item>
|
||||
</router-link>
|
||||
</template>
|
||||
</el-submenu>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: "SidebarItem",
|
||||
props: {
|
||||
// route配置json
|
||||
item: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
isNest: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
basePath: {
|
||||
type: String,
|
||||
default: ""
|
||||
},
|
||||
collapse: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
onlyOneChild: null
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
hasOneShowingChild(children) {
|
||||
const showingChildren = children.filter(item => {
|
||||
if (item.hidden) {
|
||||
return false;
|
||||
} else {
|
||||
this.onlyOneChild = item;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
if (showingChildren.length === 1) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
resolvePath(...paths) {
|
||||
return this.basePath + "/" + paths[0];
|
||||
},
|
||||
OneShowingChild(children) {
|
||||
this.onlyOneChild = children;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.menu-wrapper {
|
||||
|
||||
::v-deep .el-menu-item,
|
||||
.el-submenu__title {
|
||||
height: 46px;
|
||||
line-height: 46px;
|
||||
}
|
||||
|
||||
::v-deep .el-menu-item {
|
||||
padding: 0 20px 0 12px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,49 @@
|
||||
<template>
|
||||
<scroll-bar>
|
||||
<el-menu mode="vertical" :show-timeout="200" :default-active="$route.path" :collapse="isCollapse">
|
||||
<Logo :collapse="isCollapse" />
|
||||
</el-menu>
|
||||
</scroll-bar>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, defineComponent } from "vue";
|
||||
import SidebarItem from "./SidebarItem";
|
||||
import ScrollBar from "@/components/ScrollBar";
|
||||
import Logo from "./logo";
|
||||
import { useAppStore } from "@/store/app"
|
||||
import { usePermissionStore } from "@/store/permission"
|
||||
defineComponent({
|
||||
name: 'Sidebar'
|
||||
})
|
||||
const { sidebarStatus } = useAppStore()
|
||||
const { routers } = usePermissionStore()
|
||||
|
||||
const routes_list = computed(() => routers)
|
||||
|
||||
const isCollapse = computed(() => !sidebarStatus.opened)
|
||||
</script>
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
.title {
|
||||
text-align: center;
|
||||
line-height: 64px;
|
||||
height: 64px;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
color: #333333;
|
||||
background-color: #ffffff;
|
||||
padding: 0 20px;
|
||||
|
||||
.logo-set {
|
||||
width: 21px;
|
||||
height: 21px;
|
||||
}
|
||||
}
|
||||
|
||||
.minititle {
|
||||
padding: 0 10px;
|
||||
transition: padding 0.28s;
|
||||
overflow: hidden;
|
||||
width: 180px;
|
||||
}
|
||||
</style>
|
||||
80
fuintCashier/src/renderer/layout/components/Sidebar/logo.vue
Normal file
@@ -0,0 +1,80 @@
|
||||
<template>
|
||||
<div class="sidebar-logo-container" :class="{'collapse':collapse}">
|
||||
<transition name="sidebarLogoFade">
|
||||
<router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/">
|
||||
<div class="sidebar-title">{{ title }}</div>
|
||||
</router-link>
|
||||
<router-link v-else key="expand" class="sidebar-logo-link" to="/">
|
||||
<div class="sidebar-title">{{ title }}</div>
|
||||
</router-link>
|
||||
</transition>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "SidebarLogo",
|
||||
props: {
|
||||
collapse: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
title: "fuint",
|
||||
};
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
.sidebarLogoFade-enter-active {
|
||||
transition: opacity .28s;
|
||||
}
|
||||
|
||||
.sidebarLogoFade-enter,
|
||||
.sidebarLogoFade-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.sidebar-logo-container {
|
||||
box-shadow: 2px 0 6px rgba(0,21,41,.15);
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 61px;
|
||||
line-height: 61px;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
background-color: #ffffff;
|
||||
|
||||
& > .sidebar-logo-link {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
& > .sidebar-logo {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
vertical-align: middle;
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
& > .sidebar-title {
|
||||
display: inline-block;
|
||||
margin: 0;
|
||||
color: #333;
|
||||
font-weight: 600;
|
||||
line-height: 50px;
|
||||
font-size: 14px;
|
||||
font-family: Avenir, Helvetica Neue, Arial, Helvetica, sans-serif;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
}
|
||||
.collapse {
|
||||
.sidebar-logo {
|
||||
margin-right: 0px !important;
|
||||
margin-left: 0px !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
62
fuintCashier/src/renderer/layout/index.vue
Normal file
@@ -0,0 +1,62 @@
|
||||
<template>
|
||||
<div class="app-wrapper" :class="IsUseSysTitle ? 'UseSysTitle' : 'NoUseSysTitle'">
|
||||
<div :class="classObj">
|
||||
<navbar></navbar>
|
||||
<div class="container-set">
|
||||
<sidebar class="sidebar-container" :class="IsUseSysTitle ? 'UseSysTitle' : 'NoUseSysTitle'"></sidebar>
|
||||
<div class="main-container">
|
||||
<app-main></app-main>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed } from "vue";
|
||||
import AppMain from "./components/AppMain";
|
||||
import Navbar from "./components/Navbar";
|
||||
import Sidebar from "./components/Sidebar";
|
||||
import { useAppStore } from "@/store/app";
|
||||
import { ipcRenderer } from "electron";
|
||||
|
||||
const { sidebarStatus } = useAppStore();
|
||||
const IsUseSysTitle = ref(false);
|
||||
const sidebarSwitch = computed(() => sidebarStatus.opened)
|
||||
|
||||
ipcRenderer.invoke("IsUseSysTitle").then(res => {
|
||||
IsUseSysTitle.value = res;
|
||||
});
|
||||
|
||||
const classObj = computed(() => {
|
||||
return {
|
||||
hideSidebar: !sidebarSwitch.value,
|
||||
openSidebar: sidebarSwitch.value
|
||||
};
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
@import "@/styles/mixin.scss";
|
||||
|
||||
.app-wrapper {
|
||||
@include clearfix;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
.container-set {
|
||||
position: relative;
|
||||
padding-top: 62px;
|
||||
}
|
||||
}
|
||||
|
||||
.UseSysTitle {
|
||||
top: 0px;
|
||||
}
|
||||
|
||||
.NoUseSysTitle {
|
||||
top: 38px
|
||||
}
|
||||
</style>
|
||||
71
fuintCashier/src/renderer/main.js
Normal file
@@ -0,0 +1,71 @@
|
||||
import Vue from 'vue'
|
||||
import { ipcRenderer } from 'electron'
|
||||
import { createPinia, PiniaVuePlugin } from 'pinia'
|
||||
import Router from 'vue-router'
|
||||
|
||||
import App from './App'
|
||||
import router from './router'
|
||||
import { usePermission } from './permission'
|
||||
import directive from './directive'
|
||||
// 分页组件
|
||||
import Pagination from "@/components/Pagination";
|
||||
// 打印插件
|
||||
import Print from 'vue-print-nb'
|
||||
// 引用element
|
||||
import ElementUI from 'element-ui'
|
||||
import { getName, resetForm, addDateRange, parseTime } from '@/utils/fuint'
|
||||
import 'element-ui/lib/theme-chalk/index.css'
|
||||
// 日志
|
||||
import './error'
|
||||
import './icons'
|
||||
import '@/styles/index.scss'
|
||||
import '@/styles/dark-mode.scss'
|
||||
import '@/styles/fuint.scss'
|
||||
|
||||
// 引入 i18n 语言包
|
||||
import VueI18n from 'vue-i18n'
|
||||
import loadLanguage from "./i18n"
|
||||
const languages = loadLanguage()
|
||||
const pinia = createPinia()
|
||||
|
||||
// 全局组件挂载
|
||||
Vue.component('Pagination', Pagination)
|
||||
Vue.prototype.getName = getName
|
||||
Vue.prototype.resetForm = resetForm
|
||||
Vue.prototype.addDateRange = addDateRange
|
||||
Vue.prototype.parseTime = parseTime
|
||||
|
||||
if (!process.env.IS_WEB) {
|
||||
ipcRenderer.invoke("IsUseSysTitle").then(res => {
|
||||
if (!res) {
|
||||
require('@/styles/custom-title.scss')
|
||||
}
|
||||
});
|
||||
}
|
||||
Vue.use(PiniaVuePlugin) // 确保pinia在最先挂载
|
||||
Vue.use(directive)
|
||||
Vue.use(Print);
|
||||
Vue.use(Router)
|
||||
// 创建 i18n
|
||||
Vue.use(VueI18n) // 新版本必须要这个,不知道为什么
|
||||
|
||||
usePermission() // 放在后面,确保加载顺序
|
||||
|
||||
const i18n = new VueI18n({
|
||||
locale: 'zh-CN', // 设置默认语言
|
||||
messages: languages, // 设置语言包
|
||||
});
|
||||
Vue.use(ElementUI, {
|
||||
i18n: (key, value) => i18n.t(key, value)
|
||||
})
|
||||
|
||||
Vue.config.productionTip = false
|
||||
|
||||
new Vue({
|
||||
components: { App },
|
||||
router,
|
||||
pinia,
|
||||
i18n,
|
||||
template: '<App/>',
|
||||
}).$mount('#app')
|
||||
|
||||
50
fuintCashier/src/renderer/permission.js
Normal file
@@ -0,0 +1,50 @@
|
||||
import router from './router'
|
||||
import Performance from '@/tools/performance'
|
||||
import { usePermissionStore } from "@/store/permission"
|
||||
import { useUserStore } from "@/store/user"
|
||||
|
||||
export function usePermission() {
|
||||
let end = null
|
||||
const whiteList = ['/login'] // 不重定向白名单
|
||||
router.beforeEach(async (to, from, next) => {
|
||||
const { GenerateRoutes, routers } = usePermissionStore()
|
||||
const { GetUserInfo, token, roles, logOut } = useUserStore()
|
||||
end = Performance.startExecute(`${from.path} => ${to.path} 路由耗时`) /// 路由性能监控
|
||||
if (token) {
|
||||
if (to.path === '/login') {
|
||||
next({ path: '/' })
|
||||
} else {
|
||||
const hasRoles = roles && roles.length > 0;
|
||||
if (hasRoles && routers && routers.length > 0) {
|
||||
next()
|
||||
} else {
|
||||
try {
|
||||
const roles = await GetUserInfo()
|
||||
const accessRoutes = await GenerateRoutes(roles)
|
||||
accessRoutes.forEach(item => {
|
||||
router.addRoute(item)
|
||||
})
|
||||
next({ ...to, replace: true })
|
||||
} catch (error) {
|
||||
await logOut()
|
||||
console.error(error)
|
||||
next('/login')
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
if (whiteList.includes(to.path)) {
|
||||
next()
|
||||
} else {
|
||||
next('/login')
|
||||
}
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
end()
|
||||
}, 0)
|
||||
})
|
||||
|
||||
router.afterEach(() => { })
|
||||
}
|
||||
40
fuintCashier/src/renderer/router/constantRouterMap.js
Normal file
@@ -0,0 +1,40 @@
|
||||
import Layout from '@/layout'
|
||||
/**
|
||||
* hidden: true if `hidden:true` will not show in the sidebar(default is false)
|
||||
* alwaysShow: true if set true, will always show the root menu, whatever its child routes length
|
||||
* if not set alwaysShow, only more than one route under the children
|
||||
* it will becomes nested mode, otherwise not show the root menu
|
||||
* redirect: noredirect if `redirect:noredirect` will no redirct in the breadcrumb
|
||||
* name:'router-name' the name is used by <keep-alive> (must set!!!)
|
||||
* meta : {
|
||||
title: 'title' the name show in submenu and breadcrumb (recommend set)
|
||||
icon: 'svg-name' the icon show in the sidebar,
|
||||
}
|
||||
**/
|
||||
|
||||
/**
|
||||
* hidden: true 如果在模板中使用该选项,则不会在侧栏显示该路由(例如:Dashboard),如果是在第一个子路由中使用,侧栏则只显示第一个子路由的名字和图标(例如: Form)
|
||||
* alwaysShow: true 如果设置为true它则会始终显示根菜单,无视自路由长度,没有设置的话,就会折叠起来(不清楚为什么没有作用,可能是我写错位置了?)
|
||||
* redirect: noredirect 若设置为noredirect则顶部面包屑不能够为其重定向.
|
||||
* onlyShowfirst: false 若该设置为true时,将会无视其有多少个孩子路由,只会显示第一个子路由并将其设置为根菜单
|
||||
* name:'router-name' 路由名称,此项为必须填写项
|
||||
* meta : {
|
||||
title: 'title' 这里的名字决定了面包屑和侧栏的名字
|
||||
icon: 'svg-name' 当你在svg文件夹内加入了你的图标,那么在这里填写图标名他就会显示在侧栏
|
||||
}
|
||||
**/
|
||||
export default [
|
||||
{
|
||||
path: '/cashier',
|
||||
component: Layout,
|
||||
meta: { roles: ['admin', 'common', 'user'] },
|
||||
children: [
|
||||
{
|
||||
path: 'index',
|
||||
name: '收银',
|
||||
component: () => import('@/views/cashier/index'),
|
||||
meta: { title: '收银', icon: 'table' }
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
43
fuintCashier/src/renderer/router/index.js
Normal file
@@ -0,0 +1,43 @@
|
||||
import Router from 'vue-router'
|
||||
import Layout from '@/layout'
|
||||
// 引入路由表
|
||||
import asyncRouterMap from './constantRouterMap'
|
||||
|
||||
export const constantRouterMap = [{
|
||||
path: '/',
|
||||
component: Layout,
|
||||
redirect: '/dashboard',
|
||||
name: '主页',
|
||||
hidden: true,
|
||||
children: [{
|
||||
path: 'dashboard',
|
||||
name: '总览',
|
||||
component: () => import('@/views/home')
|
||||
}]
|
||||
}, {
|
||||
path: '/login',
|
||||
component: () => import('@/views/login'),
|
||||
hidden: true
|
||||
}, {
|
||||
path: '/cashier',
|
||||
component: () => import('@/views/cashier'),
|
||||
hidden: true
|
||||
} , {
|
||||
path: '/setting',
|
||||
component: () => import('@/views/setting'),
|
||||
hidden: true
|
||||
}]
|
||||
export const asyncRoutes = asyncRouterMap
|
||||
|
||||
const createRouter = () => new Router({
|
||||
scrollBehavior: () => ({ y: 0 }),
|
||||
routes: constantRouterMap
|
||||
})
|
||||
|
||||
export function resetRouter() {
|
||||
const newRouter = createRouter()
|
||||
router.matcher = newRouter.matcher
|
||||
}
|
||||
const router = createRouter()
|
||||
|
||||
export default router
|
||||
29
fuintCashier/src/renderer/store/app.js
Normal file
@@ -0,0 +1,29 @@
|
||||
import { defineStore } from "pinia"
|
||||
|
||||
const state = () => ({
|
||||
sidebarStatus: {
|
||||
opened: !+localStorage.getItem('sidebarStatus'),
|
||||
withoutAnimation: false
|
||||
},
|
||||
device: 'desktop'
|
||||
})
|
||||
|
||||
export const useAppStore = defineStore({
|
||||
id: 'app',
|
||||
state,
|
||||
actions: {
|
||||
ToggleSideBar() {
|
||||
if (this.sidebarStatus.opened) {
|
||||
localStorage.setItem('sidebarStatus', 1)
|
||||
} else {
|
||||
localStorage.setItem('sidebarStatus', 0)
|
||||
}
|
||||
this.sidebarStatus.opened = !this.sidebarStatus.opened
|
||||
},
|
||||
CloseSideBar({ withoutAnimation }) {
|
||||
localStorage.setItem('sidebarStatus', 1)
|
||||
this.sidebarStatus.opened = false
|
||||
this.sidebarStatus.withoutAnimation = withoutAnimation
|
||||
}
|
||||
}
|
||||
})
|
||||
68
fuintCashier/src/renderer/store/permission.js
Normal file
@@ -0,0 +1,68 @@
|
||||
import { defineStore } from "pinia"
|
||||
|
||||
// 需要在头部传入路由表并且在用户登录的时候进行此操作
|
||||
// 引入路由表
|
||||
import { constantRouterMap, asyncRoutes } from '@/router'
|
||||
|
||||
/**
|
||||
* 通过meta.role判断是否与当前用户权限匹配,此处也可以根据自己的需求进行修改。比如按位与
|
||||
* @param roles 权限
|
||||
* @param route 总的路由表
|
||||
*/
|
||||
function hasPermission(roles, route) {
|
||||
if (route.meta && route.meta.roles) {
|
||||
console.log(route.meta, roles.some(role => route.meta.roles.includes(role)))
|
||||
return roles.some(role => route.meta.roles.includes(role))
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归过滤异步路由表,返回符合用户角色权限的路由表
|
||||
* @param routes 需要筛选的路由表
|
||||
* @param roles 权限
|
||||
*/
|
||||
function filterAsyncRouter(routes, roles) {
|
||||
const res = []
|
||||
|
||||
routes.forEach(route => {
|
||||
const tmp = { ...route }
|
||||
|
||||
if (hasPermission(roles, tmp)) {
|
||||
if (tmp.children) {
|
||||
tmp.children = filterAsyncRouter(tmp.children, roles)
|
||||
}
|
||||
res.push(tmp)
|
||||
}
|
||||
})
|
||||
return res
|
||||
}
|
||||
|
||||
export const usePermissionStore = defineStore({
|
||||
id: 'permission',
|
||||
state: () => ({
|
||||
routers: [],
|
||||
}),
|
||||
actions: {
|
||||
GenerateRoutes(roles) {
|
||||
return new Promise(resolve => {
|
||||
let accessedRouters = []
|
||||
// 在这里当是管理员权限时,就给予所有的路由表
|
||||
if (roles === 'admin') {
|
||||
accessedRouters = asyncRoutes
|
||||
} else {
|
||||
accessedRouters = filterAsyncRouter(asyncRoutes, roles)
|
||||
}
|
||||
this.routers = constantRouterMap.concat(accessedRouters)
|
||||
resolve(this.routers)
|
||||
})
|
||||
},
|
||||
ResetRoutes() {
|
||||
return new Promise(resolve => {
|
||||
this.routers = []
|
||||
resolve()
|
||||
})
|
||||
}
|
||||
},
|
||||
})
|
||||
72
fuintCashier/src/renderer/store/user.js
Normal file
@@ -0,0 +1,72 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { resetRouter } from '@/router'
|
||||
import { usePermissionStore } from './permission'
|
||||
import { login, getInfo } from '@/api/login'
|
||||
|
||||
const TokenKey = 'Access-Token'
|
||||
const store = () => {
|
||||
return {
|
||||
token: JSON.parse(localStorage.getItem(TokenKey)),
|
||||
name: JSON.parse(localStorage.getItem('name')),
|
||||
roles: JSON.parse(localStorage.getItem('roles'))
|
||||
}
|
||||
}
|
||||
|
||||
export const useUserStore = defineStore({
|
||||
id: 'user',
|
||||
store,
|
||||
actions: {
|
||||
login(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const { username } = data;
|
||||
const { password } = data;
|
||||
const { captchaCode } = data;
|
||||
const { uuid } = data;
|
||||
|
||||
login(username, password, captchaCode, uuid).then(res => {
|
||||
console.log('登录返回信息:', res.data);
|
||||
localStorage.setItem(TokenKey, res.data.token);
|
||||
this.token = res.data.token;
|
||||
localStorage.setItem("roles", JSON.stringify(["admin"]));
|
||||
localStorage.setItem("name", "Super Admin");
|
||||
this.name = "Super Admin";
|
||||
this.roles = ["admin"];
|
||||
|
||||
resolve()
|
||||
}).catch(error => {
|
||||
reject(error);
|
||||
})
|
||||
})
|
||||
|
||||
},
|
||||
logOut() {
|
||||
return new Promise((resolve, reject) => {
|
||||
const { ResetRoutes } = usePermissionStore()
|
||||
localStorage.setItem(TokenKey, "");
|
||||
localStorage.setItem("roles", JSON.stringify([]));
|
||||
localStorage.setItem("name", "");
|
||||
this.token = "";
|
||||
this.name = "";
|
||||
this.roles = [];
|
||||
ResetRoutes();
|
||||
resetRouter();
|
||||
resolve();
|
||||
})
|
||||
},
|
||||
GetUserInfo() {
|
||||
return new Promise((resolve, reject) => {
|
||||
getInfo().then(res => {
|
||||
const user = res.data.accountInfo;
|
||||
localStorage.setItem("name", user.accountName);
|
||||
localStorage.setItem("permissions", JSON.stringify(res.data.permissions));
|
||||
localStorage.setItem("roles", JSON.stringify(res.data.roles));
|
||||
this.name = user.accountName;
|
||||
this.roles = res.data.roles;
|
||||
resolve(this.roles);
|
||||
}).catch(error => {
|
||||
reject(error)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
35
fuintCashier/src/renderer/styles/custom-container.scss
Normal file
@@ -0,0 +1,35 @@
|
||||
.top-nav {
|
||||
display: flex;
|
||||
height: 80px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.line {
|
||||
background-color: #eeeeee;
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
margin-bottom: 30px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.line-pop {
|
||||
background-color: #eeeeee;
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
}
|
||||
.popo-order{
|
||||
padding-bottom: 8px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.popo-work{
|
||||
padding-top: 8px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.tip-line {
|
||||
background-color: #eeeeee;
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
margin-bottom: 10px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
9
fuintCashier/src/renderer/styles/custom-title.scss
Normal file
@@ -0,0 +1,9 @@
|
||||
// 降低消息高度
|
||||
// 当启用自定义标题时使用
|
||||
.el-message {
|
||||
top: 50px !important;
|
||||
}
|
||||
|
||||
.el-notification {
|
||||
top: 38px !important;
|
||||
}
|
||||
18
fuintCashier/src/renderer/styles/dark-mode.scss
Normal file
@@ -0,0 +1,18 @@
|
||||
@media (prefers-color-scheme: dark) {
|
||||
|
||||
/** 深色模式 */
|
||||
/** 黑了,但没完全黑 */
|
||||
body {
|
||||
background: #333;
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
|
||||
/** 亮色模式 */
|
||||
body {
|
||||
background: #fff;
|
||||
color: black;
|
||||
}
|
||||
}
|
||||
116
fuintCashier/src/renderer/styles/element-ui.scss
Normal file
@@ -0,0 +1,116 @@
|
||||
//to reset element-ui default css
|
||||
.el-upload {
|
||||
input[type="file"] {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.el-upload__input {
|
||||
display: none;
|
||||
}
|
||||
|
||||
//暂时性解决diolag 问题 https://github.com/ElemeFE/element/issues/2461
|
||||
.el-dialog {
|
||||
transform: none;
|
||||
left: 0;
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
//element ui upload
|
||||
.upload-container {
|
||||
.el-upload {
|
||||
width: 100%;
|
||||
|
||||
.el-upload-dragger {
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.fixed-width {
|
||||
.el-button--mini {
|
||||
padding: 7px 10px;
|
||||
width: 60px;
|
||||
}
|
||||
}
|
||||
|
||||
.status-col {
|
||||
.cell {
|
||||
padding: 0 10px;
|
||||
text-align: center;
|
||||
.el-tag {
|
||||
margin-right: 0px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// common dialog
|
||||
.common-dialog {
|
||||
.el-dialog {
|
||||
border: solid 0px #00acac;
|
||||
}
|
||||
.el-dialog__header{
|
||||
background: #00acac;
|
||||
padding: 10px;
|
||||
}
|
||||
.el-dialog__headerbtn {
|
||||
top: 15px;
|
||||
}
|
||||
.el-dialog__body {
|
||||
padding: 30px;
|
||||
}
|
||||
.el-dialog__title,.el-dialog__close{
|
||||
color: #fff;
|
||||
font-size: 14px;
|
||||
}
|
||||
.el-dialog__title,.el-dialog__close:hover{
|
||||
color: #fff;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
// main button
|
||||
.main-button {
|
||||
background: #00acac;
|
||||
line-height: 40px;
|
||||
padding: 0px 20px 0px 20px;
|
||||
height: 40px;
|
||||
}
|
||||
.main-button-mini {
|
||||
background: #00acac;
|
||||
padding: 5px 8px 5px 8px;
|
||||
}
|
||||
.main-button-middle {
|
||||
background: #00acac;
|
||||
padding: 8px 12px 8px 12px;
|
||||
}
|
||||
.main-button:hover {
|
||||
background: #077171;
|
||||
}
|
||||
.main-button-mini:hover {
|
||||
background: #077171;
|
||||
}
|
||||
.main-button-middle:hover {
|
||||
background: #077171;
|
||||
}
|
||||
.main-button-reset {
|
||||
background: #ffffff;
|
||||
}
|
||||
.main-button-reset:hover {
|
||||
background: #f5f5f5;
|
||||
color: #333333;
|
||||
}
|
||||
.do-button {
|
||||
background: #ff5b57;
|
||||
line-height: 40px;
|
||||
padding: 0px 20px 0px 20px;
|
||||
height: 40px;
|
||||
border: solid 1px #cccccc;
|
||||
}
|
||||
.do-button:hover {
|
||||
background: #ff5b33;
|
||||
border: solid 1px #ff5b57;
|
||||
}
|
||||
|
||||
|
||||
400
fuintCashier/src/renderer/styles/fuint.scss
Normal file
@@ -0,0 +1,400 @@
|
||||
/**
|
||||
* 通用css样式布局处理
|
||||
* Copyright (c) https://www.fuint.cn
|
||||
*/
|
||||
/** 基础通用 **/
|
||||
.pt5 {
|
||||
padding-top: 5px;
|
||||
}
|
||||
.pr5 {
|
||||
padding-right: 5px;
|
||||
}
|
||||
.pb5 {
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
.mt5 {
|
||||
margin-top: 5px;
|
||||
}
|
||||
.mr5 {
|
||||
margin-right: 5px;
|
||||
}
|
||||
.mb5 {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.mb8 {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.ml5 {
|
||||
margin-left: 5px;
|
||||
}
|
||||
.mt10 {
|
||||
margin-top: 10px;
|
||||
}
|
||||
.mr10 {
|
||||
margin-right: 10px;
|
||||
}
|
||||
.mb10 {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.ml10 {
|
||||
margin-left: 10px;
|
||||
}
|
||||
.mt20 {
|
||||
margin-top: 20px;
|
||||
}
|
||||
.mr20 {
|
||||
margin-right: 20px;
|
||||
}
|
||||
.mb20 {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.ml20 {
|
||||
margin-left: 20px;
|
||||
}
|
||||
.h1, .h2, .h3, .h4, .h5, .h6, h1, h2, h3, h4, h5, h6 {
|
||||
font-family: inherit;
|
||||
font-weight: 500;
|
||||
line-height: 1.1;
|
||||
color: inherit;
|
||||
}
|
||||
.main-panel {
|
||||
border: solid 1px #ccc;
|
||||
padding: 25px 10px 20px 10px;
|
||||
.input {
|
||||
width: 450px;
|
||||
}
|
||||
.min-input {
|
||||
width: 240px;
|
||||
}
|
||||
.el-upload {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
line-height: 88px;
|
||||
}
|
||||
.el-upload-list__item {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
}
|
||||
.footer {
|
||||
margin-left: 80px;
|
||||
}
|
||||
}
|
||||
.el-dialog:not(.is-fullscreen) {
|
||||
margin-top: 6vh !important;
|
||||
}
|
||||
.el-dialog__wrapper.scrollbar .el-dialog .el-dialog__body {
|
||||
overflow: auto;
|
||||
overflow-x: hidden;
|
||||
max-height: 70vh;
|
||||
padding: 10px 20px 0;
|
||||
}
|
||||
.el-table {
|
||||
.el-table__header-wrapper, .el-table__fixed-header-wrapper {
|
||||
th {
|
||||
word-break: break-word;
|
||||
background-color: #f8f8f9;
|
||||
color: #515a6e;
|
||||
height: 40px;
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
.el-table__body-wrapper {
|
||||
.el-button [class*="el-icon-"] + span {
|
||||
margin-left: 1px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** 表单布局 **/
|
||||
.form-header {
|
||||
font-size:15px;
|
||||
color:#6379bb;
|
||||
border-bottom:1px solid #ddd;
|
||||
margin:8px 10px 25px 10px;
|
||||
padding-bottom:5px
|
||||
}
|
||||
|
||||
/** 表单提示 **/
|
||||
.form-tips {
|
||||
font-size: 12px;
|
||||
color: #888;
|
||||
height: 25px;
|
||||
padding-left: 5px;
|
||||
line-height: 25px;
|
||||
}
|
||||
|
||||
/** 表格布局 **/
|
||||
.pagination-container {
|
||||
position: relative;
|
||||
height: 25px;
|
||||
margin-bottom: 10px;
|
||||
margin-top: 15px;
|
||||
padding: 10px 20px !important;
|
||||
}
|
||||
|
||||
/* tree border */
|
||||
.tree-border {
|
||||
margin-top: 5px;
|
||||
border: 1px solid #e5e6e7;
|
||||
background: #FFFFFF none;
|
||||
border-radius:4px;
|
||||
}
|
||||
|
||||
.pagination-container .el-pagination {
|
||||
right: 0;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
@media ( max-width : 768px) {
|
||||
.pagination-container .el-pagination > .el-pagination__jump {
|
||||
display: none !important;
|
||||
}
|
||||
.pagination-container .el-pagination > .el-pagination__sizes {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.el-table .fixed-width .el-button--mini {
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
width: inherit;
|
||||
}
|
||||
|
||||
/** 表格更多操作下拉样式 */
|
||||
.el-table .el-dropdown-link {
|
||||
cursor: pointer;
|
||||
color: #00acac;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.el-table .el-dropdown, .el-icon-arrow-down {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.el-tree-node__content > .el-checkbox {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.list-group-striped > .list-group-item {
|
||||
border-left: 0;
|
||||
border-right: 0;
|
||||
border-radius: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.list-group {
|
||||
padding-left: 0px;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.list-group-item {
|
||||
border-bottom: 1px solid #e7eaec;
|
||||
border-top: 1px solid #e7eaec;
|
||||
margin-bottom: -1px;
|
||||
padding: 11px 0px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.pull-right {
|
||||
float: right !important;
|
||||
}
|
||||
|
||||
.el-card__header {
|
||||
padding: 14px 15px 7px;
|
||||
min-height: 40px;
|
||||
}
|
||||
|
||||
.el-card__body {
|
||||
padding: 15px 20px 20px 20px;
|
||||
}
|
||||
|
||||
.card-box {
|
||||
padding-right: 15px;
|
||||
padding-left: 15px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.main-text {
|
||||
color: #00acac;
|
||||
}
|
||||
.main-text:hover {
|
||||
color: #04cdcd;
|
||||
}
|
||||
|
||||
/* button color */
|
||||
.el-button--cyan.is-active,
|
||||
.el-button--cyan:active {
|
||||
background: #20B2AA;
|
||||
border-color: #20B2AA;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.el-button--cyan:focus,
|
||||
.el-button--cyan:hover {
|
||||
background: #48D1CC;
|
||||
border-color: #48D1CC;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.el-button--cyan {
|
||||
background-color: #20B2AA;
|
||||
border-color: #20B2AA;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
/* text color */
|
||||
.text-navy {
|
||||
color: #1ab394;
|
||||
}
|
||||
|
||||
.text-primary {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.text-success {
|
||||
color: #00acac;
|
||||
}
|
||||
|
||||
.text-info {
|
||||
color: #23c6c8;
|
||||
}
|
||||
|
||||
.text-warning {
|
||||
color: #f8ac59;
|
||||
}
|
||||
|
||||
.text-danger {
|
||||
color: #ed5565;
|
||||
}
|
||||
|
||||
.text-muted {
|
||||
color: #888888;
|
||||
}
|
||||
|
||||
/* image */
|
||||
.img-circle {
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.img-lg {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
}
|
||||
|
||||
.avatar-upload-preview {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translate(50%, -50%);
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 0 4px #ccc;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 拖拽列样式 */
|
||||
.sortable-ghost{
|
||||
opacity: .8;
|
||||
color: #fff!important;
|
||||
background: #42b983!important;
|
||||
}
|
||||
|
||||
.top-right-btn {
|
||||
position: relative;
|
||||
float: right;
|
||||
}
|
||||
.no-border {
|
||||
border: none;
|
||||
}
|
||||
.list-img {
|
||||
width: 58px;
|
||||
height: 48px;
|
||||
border-radius: 5px;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
.list-avatar {
|
||||
width: 45px;
|
||||
height: 45px;
|
||||
border-radius: 30px;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
.el-upload {
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
line-height: 150px;
|
||||
}
|
||||
.mini-btn {
|
||||
padding: 4px 8px 4px 8px;
|
||||
}
|
||||
.status-active {
|
||||
color: #52c41a;
|
||||
background: #f6ffed;
|
||||
border: #b7eb8f solid 1px;
|
||||
border-radius: 20px;
|
||||
display: block;
|
||||
font-size: 90%;
|
||||
text-align: center;
|
||||
line-height: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
.status-disabled {
|
||||
color: #f5222d;
|
||||
background: #fff1f0;
|
||||
border: #ffa39e solid 1px;
|
||||
border-radius: 20px;
|
||||
font-size: 90%;
|
||||
display: block;
|
||||
text-align: center;
|
||||
line-height: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
.status-normal {
|
||||
color: #666666;
|
||||
background: #ffffff;
|
||||
border: #666666 solid 1px;
|
||||
border-radius: 24px;
|
||||
display: block;
|
||||
font-size: 90%;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
line-height: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
.nav-icon {
|
||||
cursor: pointer;
|
||||
}
|
||||
.nav-tool {
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
.icon {
|
||||
margin-left: 10px;
|
||||
margin-top: 6px;
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
clear: both;
|
||||
display: block;
|
||||
}
|
||||
.name {
|
||||
font-size: 12px;
|
||||
clear: both;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
line-height: 20px;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.el-pagination.is-background .el-pager li:not(.disabled).active {
|
||||
background-color: #00acac;
|
||||
}
|
||||
|
||||
.el-tabs__item.is-active {
|
||||
color: #00acac;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.el-tabs--border-card > .el-tabs__header .el-tabs__item.is-active {
|
||||
color: #00acac;
|
||||
font-weight: bold;
|
||||
}
|
||||
69
fuintCashier/src/renderer/styles/index.scss
Normal file
@@ -0,0 +1,69 @@
|
||||
@import './variables.scss';
|
||||
@import './mixin.scss';
|
||||
@import './transition.scss';
|
||||
@import './element-ui.scss';
|
||||
@import './sidebar.scss';
|
||||
|
||||
body {
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
svg {
|
||||
display: inline-block !important;
|
||||
}
|
||||
|
||||
html {
|
||||
box-sizing: border-box;
|
||||
|
||||
::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
*,
|
||||
*:before,
|
||||
*:after {
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
div:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
a:focus,
|
||||
a:active {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
a,
|
||||
a:focus,
|
||||
a:hover {
|
||||
cursor: pointer;
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.clearfix {
|
||||
&:after {
|
||||
visibility: hidden;
|
||||
display: block;
|
||||
font-size: 0;
|
||||
content: " ";
|
||||
clear: both;
|
||||
height: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// main-container全局样式
|
||||
.app-main {
|
||||
min-height: 100%
|
||||
}
|
||||
|
||||
.app-container {
|
||||
padding: 20px;
|
||||
}
|
||||