mirror of
https://github.com/electron-vite/electron-vite-vue
synced 2025-04-25 22:16:59 +08:00
init
This commit is contained in:
parent
3d3daf1db5
commit
49d36516c1
41
electron/main/gpt/getLink.ts
Normal file
41
electron/main/gpt/getLink.ts
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
import { clog } from "../poe/login";
|
||||||
|
import { login } from "./login";
|
||||||
|
|
||||||
|
export async function getLink(options) {
|
||||||
|
const log = clog(options)
|
||||||
|
log('开始', { ident: 'gpt-link' })
|
||||||
|
const page = await login(options)
|
||||||
|
|
||||||
|
// await page.waitForTimeout(500)
|
||||||
|
|
||||||
|
await page.waitForSelector('body > div.absolute.inset-0')
|
||||||
|
await page.evaluate(() => {
|
||||||
|
const $mark = document.querySelector("body > div.absolute.inset-0")
|
||||||
|
if ($mark) $mark.hidden = true
|
||||||
|
document.body.style.pointerEvents = 'all'
|
||||||
|
})
|
||||||
|
|
||||||
|
log('隐藏欢迎页面')
|
||||||
|
|
||||||
|
await page.waitForSelector('.gold-new-button', { visible: true })
|
||||||
|
log('等待升级plus按钮出现')
|
||||||
|
await page.waitForTimeout(500)
|
||||||
|
|
||||||
|
log('开始点击升级plus按钮')
|
||||||
|
await page.click('.gold-new-button')
|
||||||
|
|
||||||
|
const [response] = await Promise.all([
|
||||||
|
page.waitForNavigation({ waitUntil: 'domcontentloaded' }),
|
||||||
|
page.evaluate((selector, searchText) => {
|
||||||
|
const elements = Array.from(document.querySelectorAll(selector));
|
||||||
|
const target = elements.find(el => el.textContent.trim() === searchText);
|
||||||
|
target && target.click()
|
||||||
|
}, 'button', 'Upgrade plan')
|
||||||
|
])
|
||||||
|
|
||||||
|
if (response.ok()) {
|
||||||
|
const url = response._request._frame._url
|
||||||
|
log('获取链接成功', { result: url, type: 'success' })
|
||||||
|
return url
|
||||||
|
}
|
||||||
|
}
|
45
electron/main/gpt/index.ts
Normal file
45
electron/main/gpt/index.ts
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import { ipcMain } from 'electron'
|
||||||
|
import { getLink } from './getLink'
|
||||||
|
import { validate } from './validate'
|
||||||
|
import { browser } from './login'
|
||||||
|
|
||||||
|
const parseAccount = text => text.split('\n').filter(Boolean).map(v => {
|
||||||
|
v = v.split(/(——|-)+/).filter(v => !['-', '——'].includes(v))
|
||||||
|
return v
|
||||||
|
})
|
||||||
|
|
||||||
|
ipcMain.handle('gpt-link', async (event, arg) => {
|
||||||
|
const { text } = arg
|
||||||
|
const accounts = parseAccount(text)
|
||||||
|
|
||||||
|
const links = []
|
||||||
|
for(let i = 0; i < accounts.length; i++) {
|
||||||
|
const [user, pass] = accounts[i]
|
||||||
|
const link = await getLink({ user, pass, index: i, id: user })
|
||||||
|
links.push({
|
||||||
|
i,
|
||||||
|
user,
|
||||||
|
link
|
||||||
|
})
|
||||||
|
console.log('process', i, user, link)
|
||||||
|
}
|
||||||
|
browser && browser.close()
|
||||||
|
})
|
||||||
|
|
||||||
|
ipcMain.handle('gpt-result', async (event, arg) => {
|
||||||
|
const { text } = arg
|
||||||
|
const accounts = parseAccount(text)
|
||||||
|
|
||||||
|
const links = []
|
||||||
|
for(let i = 0; i < accounts.length; i++) {
|
||||||
|
const [user, pass] = accounts[i]
|
||||||
|
const link = await validate({ user, pass, index: i, id: user })
|
||||||
|
links.push({
|
||||||
|
i,
|
||||||
|
user,
|
||||||
|
link
|
||||||
|
})
|
||||||
|
console.log('process', i, user, link)
|
||||||
|
}
|
||||||
|
// browser && browser.close()
|
||||||
|
})
|
100
electron/main/gpt/login.ts
Normal file
100
electron/main/gpt/login.ts
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
import type { Browser, Page } from 'puppeteer'
|
||||||
|
import puppeteer from 'puppeteer-extra'
|
||||||
|
import StealthPlugin from 'puppeteer-extra-plugin-stealth'
|
||||||
|
import { randomNum } from '../tools'
|
||||||
|
import { win } from '../index'
|
||||||
|
import { clog } from '../poe/login'
|
||||||
|
puppeteer.use(StealthPlugin())
|
||||||
|
|
||||||
|
let id
|
||||||
|
export let browser: Browser | undefined
|
||||||
|
/**
|
||||||
|
* 登录google
|
||||||
|
*/
|
||||||
|
export async function login(options, tryCount = 1): Promise<Page> {
|
||||||
|
let resolve, reject
|
||||||
|
const log = clog(options)
|
||||||
|
const p = new Promise((res, rej) => {
|
||||||
|
resolve = res
|
||||||
|
reject = rej
|
||||||
|
})
|
||||||
|
id = options.id
|
||||||
|
const env = {
|
||||||
|
GUSER: options.user,
|
||||||
|
GPASS: options.pass
|
||||||
|
}
|
||||||
|
|
||||||
|
if (browser) await browser.close()
|
||||||
|
|
||||||
|
browser = await puppeteer.launch({ headless: false })
|
||||||
|
const page = await browser.newPage()
|
||||||
|
await page.setExtraHTTPHeaders({
|
||||||
|
'accept-language': 'en-US,en;q=0.9,hy;q=0.8'
|
||||||
|
})
|
||||||
|
|
||||||
|
log('开始访问 gpt')
|
||||||
|
await page.goto('https://chat.openai.com/auth/login')
|
||||||
|
await page.waitForSelector('button')
|
||||||
|
|
||||||
|
// log('准备进入 google 登录页')
|
||||||
|
const [response] = await Promise.all([
|
||||||
|
page.waitForNavigation(() => location.href.startsWith('https://auth0.openai.com/u/login/identifier')),
|
||||||
|
page.click('button')
|
||||||
|
])
|
||||||
|
// log('已进入 google 登录页')
|
||||||
|
|
||||||
|
if (!response.ok()) return log('进入 google 登录页失败')
|
||||||
|
|
||||||
|
log('准备输入账号')
|
||||||
|
await page.type('#username', env.GUSER)
|
||||||
|
await Promise.all([
|
||||||
|
page.waitForNavigation(),
|
||||||
|
page.keyboard.press('Enter')
|
||||||
|
])
|
||||||
|
|
||||||
|
log('已输入账号,准备输入密码')
|
||||||
|
await page.waitForSelector('#password', { visible: true })
|
||||||
|
await page.type('#password', env.GPASS)
|
||||||
|
log('已输入密码,开始登录')
|
||||||
|
|
||||||
|
await Promise.all([
|
||||||
|
page.waitForNavigation(() => location.href === 'https://chat.openai.com/'),
|
||||||
|
page.keyboard.press('Enter')
|
||||||
|
])
|
||||||
|
log('登录成功')
|
||||||
|
resolve(page)
|
||||||
|
|
||||||
|
// if (response.ok()) {
|
||||||
|
// await page.waitForSelector('input[type="email"]')
|
||||||
|
// log('准备输入账号')
|
||||||
|
// await page.type('input[type="email"]', env.GUSER)
|
||||||
|
// await Promise.all([
|
||||||
|
// page.waitForNavigation(),
|
||||||
|
// await page.keyboard.press('Enter')
|
||||||
|
// ])
|
||||||
|
// log('已输入账号,准备输入密码')
|
||||||
|
// await page.waitForSelector('input[type="password"]', { visible: true })
|
||||||
|
// await page.type('input[type="password"]', env.GPASS)
|
||||||
|
// log('已输入密码,开始登录')
|
||||||
|
// await Promise.all([
|
||||||
|
// page.waitForFunction(() => location.href === 'https://poe.com/'),
|
||||||
|
// await page.keyboard.press('Enter')
|
||||||
|
// ])
|
||||||
|
|
||||||
|
// log('登录成功,准备进入 poe')
|
||||||
|
|
||||||
|
// return page
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (tryCount < 4) {
|
||||||
|
// log(`google 登录失败,准备 ${tryCount} 次重试`)
|
||||||
|
// await page.close()
|
||||||
|
// return await loginGoogle(options, tryCount + 1)
|
||||||
|
// } else {
|
||||||
|
// log('google 登录失败,重试次数已达上限')
|
||||||
|
// reject('google 登录失败')
|
||||||
|
// }
|
||||||
|
|
||||||
|
return p
|
||||||
|
// return Promise.reject('google 登录失败')
|
||||||
|
}
|
27
electron/main/gpt/validate.ts
Normal file
27
electron/main/gpt/validate.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import { clog } from "../poe/login";
|
||||||
|
import { login } from "./login";
|
||||||
|
|
||||||
|
export async function validate(options) {
|
||||||
|
const log = clog(options)
|
||||||
|
log('开始', { ident: 'gpt-validate' })
|
||||||
|
const page = await login(options)
|
||||||
|
|
||||||
|
await page.waitForSelector('body > div.absolute.inset-0')
|
||||||
|
await page.evaluate(() => {
|
||||||
|
const $mark = document.querySelector("body > div.absolute.inset-0")
|
||||||
|
if ($mark) $mark.hidden = true
|
||||||
|
document.body.style.pointerEvents = 'all'
|
||||||
|
})
|
||||||
|
log('隐藏欢迎页面,开始检测')
|
||||||
|
|
||||||
|
await page.waitForTimeout(2000)
|
||||||
|
|
||||||
|
const isSuccess = await page.evaluate((selector, searchText) => {
|
||||||
|
const elements = Array.from(document.querySelectorAll(selector));
|
||||||
|
const target = elements.find(el => el.textContent.trim() === searchText);
|
||||||
|
return !!target
|
||||||
|
}, 'button', 'GPT-4')
|
||||||
|
log('获取链接成功', { result: isSuccess ? '充值成功😘' : '充值失败😭', type: isSuccess ? 'success' : 'fail' })
|
||||||
|
|
||||||
|
console.log(isSuccess)
|
||||||
|
}
|
@ -1,6 +1,8 @@
|
|||||||
import { app, BrowserWindow, shell, ipcMain } from 'electron'
|
import { app, BrowserWindow, shell, ipcMain } from 'electron'
|
||||||
import { release } from 'node:os'
|
import { release } from 'node:os'
|
||||||
import { join } from 'node:path'
|
import { join } from 'node:path'
|
||||||
|
import './poe/index'
|
||||||
|
import './gpt/index'
|
||||||
|
|
||||||
// The built directory structure
|
// The built directory structure
|
||||||
//
|
//
|
||||||
@ -34,7 +36,7 @@ if (!app.requestSingleInstanceLock()) {
|
|||||||
// Read more on https://www.electronjs.org/docs/latest/tutorial/security
|
// Read more on https://www.electronjs.org/docs/latest/tutorial/security
|
||||||
// process.env['ELECTRON_DISABLE_SECURITY_WARNINGS'] = 'true'
|
// process.env['ELECTRON_DISABLE_SECURITY_WARNINGS'] = 'true'
|
||||||
|
|
||||||
let win: BrowserWindow | null = null
|
export let win: BrowserWindow | null = null
|
||||||
// Here, you can also use other preload
|
// Here, you can also use other preload
|
||||||
const preload = join(__dirname, '../preload/index.js')
|
const preload = join(__dirname, '../preload/index.js')
|
||||||
const url = process.env.VITE_DEV_SERVER_URL
|
const url = process.env.VITE_DEV_SERVER_URL
|
||||||
@ -43,6 +45,8 @@ const indexHtml = join(process.env.DIST, 'index.html')
|
|||||||
async function createWindow() {
|
async function createWindow() {
|
||||||
win = new BrowserWindow({
|
win = new BrowserWindow({
|
||||||
title: 'Main window',
|
title: 'Main window',
|
||||||
|
width: 1000,
|
||||||
|
height: 800,
|
||||||
icon: join(process.env.PUBLIC, 'favicon.ico'),
|
icon: join(process.env.PUBLIC, 'favicon.ico'),
|
||||||
webPreferences: {
|
webPreferences: {
|
||||||
preload,
|
preload,
|
||||||
|
52
electron/main/poe/getLink.js
Normal file
52
electron/main/poe/getLink.js
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
import { clog, loginGoogle } from './login'
|
||||||
|
import { readFileSync, writeFileSync } from 'fs'
|
||||||
|
import path from 'path'
|
||||||
|
import { EOL } from 'os'
|
||||||
|
|
||||||
|
export async function getLink(options) {
|
||||||
|
const log = clog(options)
|
||||||
|
log('开始', { ident: 'poe-link' })
|
||||||
|
const page = await loginGoogle(options)
|
||||||
|
|
||||||
|
await Promise.all([
|
||||||
|
page.waitForNavigation(),
|
||||||
|
page.goto('https://poe.com/settings')
|
||||||
|
])
|
||||||
|
|
||||||
|
log('已进入设置页面, 检查中')
|
||||||
|
|
||||||
|
// page.waitForTimeout(1000)
|
||||||
|
await page.waitForSelector('[class*=SettingsSubscriptionSection_subscribeButton]')
|
||||||
|
log('1, 开始点击显示订阅套餐按钮')
|
||||||
|
await page.click('[class*=SettingsSubscriptionSection_subscribeButton]')
|
||||||
|
log('2, 开始点击显示更多套餐')
|
||||||
|
await page.waitForSelector('[class*=WebSubscriptionFreeTrial_viewAllPlansButton]')
|
||||||
|
await page.click('[class*=WebSubscriptionFreeTrial_viewAllPlansButton]')
|
||||||
|
log('3, 开始点击最后一个套餐')
|
||||||
|
await page.waitForSelector('[class*=WebSubscriptionPaywall_plans]')
|
||||||
|
await page.click('[class*=WebSubscriptionPaywall_plans] > button:last-child')
|
||||||
|
|
||||||
|
// 点击订阅
|
||||||
|
log('4, 开始点击订阅')
|
||||||
|
page.click('[class*=WebSubscriptionPaywall_button]')
|
||||||
|
const [response] = await Promise.all([
|
||||||
|
page.waitForNavigation({ waitUntil: 'domcontentloaded' }),
|
||||||
|
])
|
||||||
|
|
||||||
|
if (response.ok()) {
|
||||||
|
const url = response._request._frame._url
|
||||||
|
log('获取链接成功', { result: url, type: 'success' })
|
||||||
|
return url
|
||||||
|
|
||||||
|
// if (options.index === 0) {
|
||||||
|
// writeFileSync(resolve('./hao.txt'), '', 'utf8')
|
||||||
|
// }
|
||||||
|
// const fileContent = readFileSync(resolve('./hao.txt'), 'utf8')
|
||||||
|
// writeFileSync(resolve('./hao.txt'), fileContent + `${EOL}${options.index + 1} ${options.user}${EOL}${url}`, 'utf8')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function resolve(url) {
|
||||||
|
return path.resolve(__dirname, '../src/poe/', url)
|
||||||
|
}
|
0
electron/main/poe/hao.txt
Normal file
0
electron/main/poe/hao.txt
Normal file
62
electron/main/poe/index.js
Normal file
62
electron/main/poe/index.js
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
import { getLink } from './getLink'
|
||||||
|
import { validate } from './validate'
|
||||||
|
import { ipcMain } from 'electron'
|
||||||
|
import { browser } from './login'
|
||||||
|
|
||||||
|
// import './openBrowser'
|
||||||
|
// suzzettedeanne2393@gmail.com----zebulonlawayne3013----zebulonlawayne4749@outlook.com
|
||||||
|
const text = `
|
||||||
|
`
|
||||||
|
|
||||||
|
export const parseAccount = text => text.split('\n').filter(Boolean).map(v => {
|
||||||
|
v = v.split(/(——|-)+/).filter(v => !['-', '——'].includes(v))
|
||||||
|
return v
|
||||||
|
})
|
||||||
|
|
||||||
|
ipcMain.handle('getLink', async (event, arg) => {
|
||||||
|
const { text } = arg
|
||||||
|
const accounts = parseAccount(text)
|
||||||
|
|
||||||
|
const links = []
|
||||||
|
for(let i = 0; i < accounts.length; i++) {
|
||||||
|
const [user, pass, auxiliary] = accounts[i]
|
||||||
|
const link = await getLink({ user, pass, auxiliary, index: i, id: user })
|
||||||
|
// .catch(err => {
|
||||||
|
// console.log('error ->', err)
|
||||||
|
// })
|
||||||
|
links.push({
|
||||||
|
i,
|
||||||
|
user,
|
||||||
|
link
|
||||||
|
})
|
||||||
|
console.log('process', i, user, link)
|
||||||
|
}
|
||||||
|
browser && browser.close()
|
||||||
|
return links
|
||||||
|
})
|
||||||
|
|
||||||
|
ipcMain.handle('poe-result', async (event, arg) => {
|
||||||
|
const { text } = arg
|
||||||
|
const accounts = parseAccount(text)
|
||||||
|
|
||||||
|
const links = []
|
||||||
|
for(let i = 0; i < accounts.length; i++) {
|
||||||
|
const [user, pass, auxiliary] = accounts[i]
|
||||||
|
const link = await validate({ user, pass, auxiliary, index: i, id: user })
|
||||||
|
// .catch(err => {
|
||||||
|
// console.log('error ->', err)
|
||||||
|
// })
|
||||||
|
links.push({
|
||||||
|
i,
|
||||||
|
user,
|
||||||
|
link
|
||||||
|
})
|
||||||
|
console.log('process', i, user, link)
|
||||||
|
}
|
||||||
|
browser && browser.close()
|
||||||
|
return links
|
||||||
|
})
|
||||||
|
ipcMain.handle('stop', async (event, arg) => {
|
||||||
|
browser && browser.close()
|
||||||
|
return true
|
||||||
|
})
|
89
electron/main/poe/login.js
Normal file
89
electron/main/poe/login.js
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
import puppeteer from 'puppeteer-extra'
|
||||||
|
import StealthPlugin from 'puppeteer-extra-plugin-stealth'
|
||||||
|
import { randomNum } from '../tools'
|
||||||
|
import { win } from '../index'
|
||||||
|
puppeteer.use(StealthPlugin())
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
let id
|
||||||
|
export let browser
|
||||||
|
/**
|
||||||
|
* 登录google
|
||||||
|
*/
|
||||||
|
export async function loginGoogle(options, tryCount = 1) {
|
||||||
|
let resolve, reject
|
||||||
|
const log = clog(options)
|
||||||
|
const p = new Promise((res, rej) => {
|
||||||
|
resolve = res
|
||||||
|
reject = rej
|
||||||
|
})
|
||||||
|
id = options.id
|
||||||
|
const env = {
|
||||||
|
GUSER: options.user,
|
||||||
|
GPASS: options.pass
|
||||||
|
}
|
||||||
|
|
||||||
|
if (browser) await browser.close()
|
||||||
|
|
||||||
|
browser = await puppeteer.launch({ headless: false })
|
||||||
|
const page = await browser.newPage()
|
||||||
|
await page.setExtraHTTPHeaders({
|
||||||
|
'accept-language': 'en-US,en;q=0.9,hy;q=0.8'
|
||||||
|
})
|
||||||
|
|
||||||
|
log('开始访问 poe')
|
||||||
|
await page.goto('https://poe.com')
|
||||||
|
log('已进入 poe')
|
||||||
|
await page.waitForTimeout(randomNum(1000, 2600))
|
||||||
|
|
||||||
|
log('准备进入 google 登录页')
|
||||||
|
const [response] = await Promise.all([
|
||||||
|
page.waitForNavigation(() => location.href.startsWith('https://accounts.google.com')),
|
||||||
|
page.click('.ContinueWithGoogleButton_buttonContentWrapper__Mrp0W')
|
||||||
|
])
|
||||||
|
log('已进入 google 登录页')
|
||||||
|
|
||||||
|
if (response.ok()) {
|
||||||
|
await page.waitForSelector('input[type="email"]')
|
||||||
|
log('准备输入账号')
|
||||||
|
await page.type('input[type="email"]', env.GUSER)
|
||||||
|
await Promise.all([
|
||||||
|
page.waitForNavigation(),
|
||||||
|
await page.keyboard.press('Enter')
|
||||||
|
])
|
||||||
|
log('已输入账号,准备输入密码')
|
||||||
|
await page.waitForSelector('input[type="password"]', { visible: true })
|
||||||
|
await page.type('input[type="password"]', env.GPASS)
|
||||||
|
log('已输入密码,开始登录')
|
||||||
|
await Promise.all([
|
||||||
|
page.waitForFunction(() => location.href === 'https://poe.com/'),
|
||||||
|
await page.keyboard.press('Enter')
|
||||||
|
])
|
||||||
|
|
||||||
|
log('登录成功,准备进入 poe')
|
||||||
|
|
||||||
|
return page
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tryCount < 4) {
|
||||||
|
log(`google 登录失败,准备 ${tryCount} 次重试`)
|
||||||
|
await page.close()
|
||||||
|
return await loginGoogle(options, tryCount + 1)
|
||||||
|
} else {
|
||||||
|
log('google 登录失败,重试次数已达上限')
|
||||||
|
reject('google 登录失败')
|
||||||
|
}
|
||||||
|
|
||||||
|
return p
|
||||||
|
// return Promise.reject('google 登录失败')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function clog(options) {
|
||||||
|
return (info, data = {}) => {
|
||||||
|
if (win) {
|
||||||
|
win.webContents.send('progress', {...options, info, ...data})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
8
electron/main/poe/openBrowser.js
Normal file
8
electron/main/poe/openBrowser.js
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import puppeteer from 'puppeteer-extra'
|
||||||
|
import StealthPlugin from 'puppeteer-extra-plugin-stealth'
|
||||||
|
puppeteer.use(StealthPlugin())
|
||||||
|
|
||||||
|
;(async () => {
|
||||||
|
const browser = await puppeteer.launch({ headless: false })
|
||||||
|
browser.newPage()
|
||||||
|
})()
|
39
electron/main/poe/validate.js
Normal file
39
electron/main/poe/validate.js
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import { clog, loginGoogle } from './login'
|
||||||
|
import { readFileSync, writeFileSync } from 'fs'
|
||||||
|
import path from 'path'
|
||||||
|
import { EOL } from 'os'
|
||||||
|
|
||||||
|
export async function validate (options) {
|
||||||
|
const log = clog(options)
|
||||||
|
log('开始', { ident: 'poe-validate' })
|
||||||
|
const page = await loginGoogle(options)
|
||||||
|
|
||||||
|
await Promise.all([
|
||||||
|
page.waitForNavigation(),
|
||||||
|
page.goto('https://poe.com/settings')
|
||||||
|
])
|
||||||
|
|
||||||
|
log('已进入设置页面, 检查中', { ident: 'poe-validate' })
|
||||||
|
|
||||||
|
const length = await page.$$eval('.SettingsSubscriptionSection_botLimitSection__j4mSO > div:first-child > div', (doms) => doms.length)
|
||||||
|
// page.close()
|
||||||
|
|
||||||
|
// if (options.index === 0) {
|
||||||
|
// writeFileSync(resolve('./validate.txt'), '', 'utf8')
|
||||||
|
// }
|
||||||
|
// const fileContent = readFileSync(resolve('./validate.txt'), 'utf8')
|
||||||
|
const resultTxt = length === 1 ? '失败😭' : '成功😘'
|
||||||
|
// writeFileSync(resolve('./validate.txt'), fileContent + `${options.index + 1} ${options.user}----${resultTxt}${EOL}`, 'utf8')
|
||||||
|
|
||||||
|
log(resultTxt, { type: length === 1 ? 'fail' : 'success', result: length === 1 ? '失败😭' : '成功😘' })
|
||||||
|
// // 不成功
|
||||||
|
// if (length === 1) {
|
||||||
|
|
||||||
|
// } else {
|
||||||
|
// log('充值成功😘')
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolve (url) {
|
||||||
|
return path.resolve(__dirname, '../src/poe/', url)
|
||||||
|
}
|
5
electron/main/tools.js
Normal file
5
electron/main/tools.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
|
||||||
|
//生成从minNum到maxNum的随机数
|
||||||
|
export function randomNum (min, max) {
|
||||||
|
return parseInt(Math.random() * (max - min + 1) + min)
|
||||||
|
}
|
20
package.json
20
package.json
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "electron-vue-vite",
|
"name": "poe_gpt",
|
||||||
"version": "2.0.0",
|
"version": "1.0.0",
|
||||||
"main": "dist-electron/main/index.js",
|
"main": "dist-electron/main/index.js",
|
||||||
"description": "Really simple Electron + Vue + Vite boilerplate.",
|
"description": "Really simple Electron + Vue + Vite boilerplate.",
|
||||||
"author": "草鞋没号 <308487730@qq.com>",
|
"author": "草鞋没号 <308487730@qq.com>",
|
||||||
@ -20,18 +20,32 @@
|
|||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"build": "vue-tsc --noEmit && vite build && electron-builder",
|
"build": "vite build && electron-builder",
|
||||||
|
"build:64": "vite build && electron-builder --win --x64",
|
||||||
|
"build:32": "vite build && electron-builder --win --x32",
|
||||||
"preview": "vite preview"
|
"preview": "vite preview"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vitejs/plugin-vue": "^4.1.0",
|
"@vitejs/plugin-vue": "^4.1.0",
|
||||||
|
"@vitejs/plugin-vue-jsx": "^3.0.1",
|
||||||
"electron": "^25.0.1",
|
"electron": "^25.0.1",
|
||||||
"electron-builder": "^23.6.0",
|
"electron-builder": "^23.6.0",
|
||||||
"typescript": "^5.0.2",
|
"typescript": "^5.0.2",
|
||||||
|
"unplugin-auto-import": "^0.16.4",
|
||||||
|
"unplugin-vue-components": "^0.25.0",
|
||||||
"vite": "^4.1.4",
|
"vite": "^4.1.4",
|
||||||
"vite-plugin-electron": "^0.11.2",
|
"vite-plugin-electron": "^0.11.2",
|
||||||
"vite-plugin-electron-renderer": "^0.14.1",
|
"vite-plugin-electron-renderer": "^0.14.1",
|
||||||
"vue": "^3.2.47",
|
"vue": "^3.2.47",
|
||||||
"vue-tsc": "^1.2.0"
|
"vue-tsc": "^1.2.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@vueuse/core": "^10.1.2",
|
||||||
|
"naive-ui": "^2.34.4",
|
||||||
|
"puppeteer": "^13.3.2",
|
||||||
|
"puppeteer-extra": "^3.3.6",
|
||||||
|
"puppeteer-extra-plugin-stealth": "^2.11.2",
|
||||||
|
"sass": "^1.62.1",
|
||||||
|
"unocss": "^0.52.7"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
299
src/App.vue
299
src/App.vue
@ -1,51 +1,268 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="tsx">
|
||||||
import HelloWorld from './components/HelloWorld.vue'
|
import { ipcRenderer } from 'electron'
|
||||||
|
import { NButton } from 'naive-ui'
|
||||||
|
import { useClipboard } from '@vueuse/core'
|
||||||
|
const input = ref('upperside79@mail.com----Hellowpo!')
|
||||||
|
|
||||||
console.log("[App.vue]", `Hello world from Electron ${process.versions.electron}!`)
|
const result = ref('')
|
||||||
|
|
||||||
|
const list = ref<any[]>([
|
||||||
|
{
|
||||||
|
"user": "jannettamoses5977@gmail.com",
|
||||||
|
"pass": "kenyatearle7610",
|
||||||
|
"auxiliary": "kenyatearle8223@outlook.com",
|
||||||
|
"index": 0,
|
||||||
|
"id": "jannettamoses5977@gmail.com",
|
||||||
|
"info": "成功😘",
|
||||||
|
"ident": "poe-link",
|
||||||
|
"type": "success",
|
||||||
|
"result": "成功😘"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"user": "tylanindea7687@gmail.com",
|
||||||
|
"pass": "adalbertokanisha4845",
|
||||||
|
"auxiliary": "adalbertokanisha8803@yandex.com",
|
||||||
|
"index": 1,
|
||||||
|
"id": "tylanindea7687@gmail.com",
|
||||||
|
"info": "成功😘",
|
||||||
|
"ident": "poe-validate",
|
||||||
|
"type": "success",
|
||||||
|
"result": "成功😘"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"user": "bayanjae8652@gmail.com",
|
||||||
|
"pass": "lorenarosamond4075",
|
||||||
|
"auxiliary": "lorenarosamond8958@outlook.com",
|
||||||
|
"index": 2,
|
||||||
|
"id": "bayanjae8652@gmail.com",
|
||||||
|
"info": "成功😘",
|
||||||
|
"ident": "poe-validate",
|
||||||
|
"type": "fail",
|
||||||
|
"result": "成功😘"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"user": "geneviashametra1019@gmail.com",
|
||||||
|
"pass": "sheypervis2156",
|
||||||
|
"auxiliary": "sheypervis0163@qq.com",
|
||||||
|
"index": 3,
|
||||||
|
"id": "geneviashametra1019@gmail.com",
|
||||||
|
"info": "成功😘",
|
||||||
|
"ident": "poe-validate",
|
||||||
|
"type": "success",
|
||||||
|
"result": "成功😘"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"user": "marikamelindasue5911@gmail.com",
|
||||||
|
"pass": "ambrbreeann4103",
|
||||||
|
"auxiliary": "ambrbreeann5643@icloud.com",
|
||||||
|
"index": 4,
|
||||||
|
"id": "marikamelindasue5911@gmail.com",
|
||||||
|
"info": "成功😘",
|
||||||
|
"ident": "poe-validate",
|
||||||
|
"type": "success",
|
||||||
|
"result": "成功😘"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"user": "caterinereba2981@gmail.com",
|
||||||
|
"pass": "arvisleo0563",
|
||||||
|
"auxiliary": "arvisleo1265@zoho.com",
|
||||||
|
"index": 5,
|
||||||
|
"id": "caterinereba2981@gmail.com",
|
||||||
|
"info": "成功😘",
|
||||||
|
"ident": "poe-validate",
|
||||||
|
"type": "success",
|
||||||
|
"result": "成功😘"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"user": "adairaderrell9992@gmail.com",
|
||||||
|
"pass": "adairaderrell8698",
|
||||||
|
"auxiliary": "adairaderrell1859@hotmail.com",
|
||||||
|
"index": 6,
|
||||||
|
"id": "adairaderrell9992@gmail.com",
|
||||||
|
"info": "成功😘",
|
||||||
|
"ident": "poe-validate",
|
||||||
|
"type": "success",
|
||||||
|
"result": "成功😘"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"user": "nishadarrow0444@gmail.com",
|
||||||
|
"pass": "cliftontiffani7462",
|
||||||
|
"auxiliary": "cliftontiffani2263@hotmail.com",
|
||||||
|
"index": 7,
|
||||||
|
"id": "nishadarrow0444@gmail.com",
|
||||||
|
"info": "成功😘",
|
||||||
|
"ident": "poe-validate",
|
||||||
|
"type": "success",
|
||||||
|
"result": "成功😘"
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
|
ipcRenderer.on('progress', (event, args) => {
|
||||||
|
console.log('progress', args);
|
||||||
|
|
||||||
|
const { user } = args
|
||||||
|
const target = list.value.find((item) => item.user === user)
|
||||||
|
|
||||||
|
if (target) {
|
||||||
|
Object.assign(target, args)
|
||||||
|
} else {
|
||||||
|
list.value.push(args)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
function getLink(val?: string) {
|
||||||
|
ipcRenderer.invoke('getLink', { text: val || input.value }).then((res) => {
|
||||||
|
console.log(res);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function getResult(val?: string) {
|
||||||
|
ipcRenderer.invoke('poe-result', { text: val || input.value }).then((res) => {
|
||||||
|
console.log(res);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function stopHandler() {
|
||||||
|
ipcRenderer.invoke('stop')
|
||||||
|
}
|
||||||
|
|
||||||
|
function gptLinkHandler() {
|
||||||
|
ipcRenderer.invoke('gpt-link', { text: input.value })
|
||||||
|
}
|
||||||
|
|
||||||
|
function gptResultHandler() {
|
||||||
|
ipcRenderer.invoke('gpt-result', { text: input.value })
|
||||||
|
}
|
||||||
|
|
||||||
|
const listSuccess = computed(() => {
|
||||||
|
return list.value.filter((item) => item.type === 'success')
|
||||||
|
})
|
||||||
|
const listFail = computed(() => {
|
||||||
|
return list.value.filter((item) => item.type !== 'success')
|
||||||
|
})
|
||||||
|
|
||||||
|
const { copy } = useClipboard()
|
||||||
|
function copyText(item: any) {
|
||||||
|
copy(item.user + '----' + (item.result || ''))
|
||||||
|
}
|
||||||
|
function copyAccount(item: any) {
|
||||||
|
copy(item.user + '----' + item.pass + '----' + item.auxiliary)
|
||||||
|
}
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
title: '序列',
|
||||||
|
render: (row, index) => h('span', undefined, index + 1),
|
||||||
|
width: 60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '邮箱',
|
||||||
|
key: 'user',
|
||||||
|
width: 300
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '进度',
|
||||||
|
key: 'info',
|
||||||
|
width: 220
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '结果',
|
||||||
|
key: 'result',
|
||||||
|
ellipsis: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
width: 230,
|
||||||
|
align: 'left',
|
||||||
|
fixed: 'right',
|
||||||
|
render: (row: any) => {
|
||||||
|
/**
|
||||||
|
* poe-link
|
||||||
|
* 再次提链: [type: fail, loading: false]
|
||||||
|
* 复制链接: [type: success, loading: false]
|
||||||
|
* 充值结果: [type: success, loading: false]
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* poe-validate
|
||||||
|
* 充值结果: [type: fail, loading: false]
|
||||||
|
*/
|
||||||
|
const rechargeResult = () => {
|
||||||
|
let link = row.ident === 'poe-link' && !row.loading
|
||||||
|
let validate = row.ident === 'poe-validate' && row.type !== 'success' && !row.loading
|
||||||
|
return link || validate
|
||||||
|
}
|
||||||
|
|
||||||
|
return <n-space>
|
||||||
|
{row.ident === 'poe-link' && row.type === 'success' && !row.loading
|
||||||
|
? <NButton text type="primary" onClick={() => copyText(`${row.user}\n${row.result}`)}>复制链接</NButton>
|
||||||
|
: null
|
||||||
|
}
|
||||||
|
{row.ident === 'poe-link' && row.type !== 'success' && !row.loading
|
||||||
|
? <NButton text type="primary" onClick={() => getLink(`${row.user}----${row.pass}----${row.auxiliary}`)}>再次提链</NButton>
|
||||||
|
: null
|
||||||
|
}
|
||||||
|
|
||||||
|
<NButton text type="primary" onClick={() => copyAccount(row)}>复制帐密</NButton>
|
||||||
|
|
||||||
|
{rechargeResult() //.ident === 'poe-link' && row.type === 'success' && !row.loading
|
||||||
|
? <NButton text type="info" onClick={() => getResult(`${row.user}----${row.pass}----${row.auxiliary}`)}>充值结果</NButton>
|
||||||
|
: null
|
||||||
|
}
|
||||||
|
|
||||||
|
</n-space>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<a href="https://www.electronjs.org/" target="_blank">
|
<div class="left" flex-1>
|
||||||
<img src="./assets/electron.svg" class="logo electron" alt="Electron logo" />
|
<p>帐密</p>
|
||||||
</a>
|
<textarea class="textarea w-full" v-model="input" rows="10" />
|
||||||
<a href="https://vitejs.dev/" target="_blank">
|
|
||||||
<img src="./assets/vite.svg" class="logo" alt="Vite logo" />
|
<div>
|
||||||
</a>
|
<div flex gap-3 mt-3 items-center>
|
||||||
<a href="https://vuejs.org/" target="_blank">
|
<span w-15>poe:</span>
|
||||||
<img src="./assets/vue.svg" class="logo vue" alt="Vue logo" />
|
<NButton type="primary" dashed @click="getLink()">提取链接</NButton>
|
||||||
</a>
|
<NButton type="primary" dashed @click="getResult()">充值结果</NButton>
|
||||||
</div>
|
</div>
|
||||||
<HelloWorld msg="Electron + Vite + Vue" />
|
<div flex gap-3 mt-3 items-center>
|
||||||
<div class="flex-center">
|
<span w-15>gpt:</span>
|
||||||
Place static files into the <code>/public</code> folder
|
<NButton type="primary" dashed @click="gptLinkHandler">gpt提链</NButton>
|
||||||
<img style="width: 2.4em; margin-left: .4em;" src="/logo.svg" alt="Logo">
|
<NButton type="primary" dashed @click="gptResultHandler">充值结果</NButton>
|
||||||
|
</div>
|
||||||
|
<div flex gap-3 mt-3 items-center>
|
||||||
|
<span w-15>操作:</span>
|
||||||
|
<NButton type="primary" dashed @click="stopHandler">停止</NButton>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="right" flex-1>
|
||||||
|
<p>结果</p>
|
||||||
|
|
||||||
|
<n-space mb-3>
|
||||||
|
<n-button type="primary" dashed>复制全部成功 {{ listSuccess.length }}个</n-button>
|
||||||
|
<n-button type="error" dashed>复制全部失败 {{ listFail.length }}个</n-button>
|
||||||
|
</n-space>
|
||||||
|
<NDataTable :data="list" :columns="columns" :scroll-x="1000">
|
||||||
|
</NDataTable>
|
||||||
|
|
||||||
|
<div w-full h-40></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre>{{ list }}</pre>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style>
|
<style lang="scss" scoped>
|
||||||
.flex-center {
|
.textarea:nth-of-type() {
|
||||||
display: flex;
|
width: 100%;
|
||||||
align-items: center;
|
display: block;
|
||||||
justify-content: center;
|
border: 1px solid #ccc;
|
||||||
}
|
border-radius: 4px;
|
||||||
|
padding: 10px;
|
||||||
.logo {
|
box-sizing: border-box;
|
||||||
height: 6em;
|
font-size: 14px;
|
||||||
padding: 1.5em;
|
|
||||||
will-change: filter;
|
|
||||||
transition: filter 300ms;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo.electron:hover {
|
|
||||||
filter: drop-shadow(0 0 2em #9FEAF9);
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo:hover {
|
|
||||||
filter: drop-shadow(0 0 2em #646cffaa);
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo.vue:hover {
|
|
||||||
filter: drop-shadow(0 0 2em #42b883aa);
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
178
src/auto-imports.d.ts
vendored
Normal file
178
src/auto-imports.d.ts
vendored
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
/* prettier-ignore */
|
||||||
|
// @ts-nocheck
|
||||||
|
// Generated by unplugin-auto-import
|
||||||
|
export {}
|
||||||
|
declare global {
|
||||||
|
const EffectScope: typeof import('vue')['EffectScope']
|
||||||
|
const computed: typeof import('vue')['computed']
|
||||||
|
const createApp: typeof import('vue')['createApp']
|
||||||
|
const customRef: typeof import('vue')['customRef']
|
||||||
|
const defineAsyncComponent: typeof import('vue')['defineAsyncComponent']
|
||||||
|
const defineComponent: typeof import('vue')['defineComponent']
|
||||||
|
const effectScope: typeof import('vue')['effectScope']
|
||||||
|
const getCurrentInstance: typeof import('vue')['getCurrentInstance']
|
||||||
|
const getCurrentScope: typeof import('vue')['getCurrentScope']
|
||||||
|
const h: typeof import('vue')['h']
|
||||||
|
const inject: typeof import('vue')['inject']
|
||||||
|
const isProxy: typeof import('vue')['isProxy']
|
||||||
|
const isReactive: typeof import('vue')['isReactive']
|
||||||
|
const isReadonly: typeof import('vue')['isReadonly']
|
||||||
|
const isRef: typeof import('vue')['isRef']
|
||||||
|
const markRaw: typeof import('vue')['markRaw']
|
||||||
|
const nextTick: typeof import('vue')['nextTick']
|
||||||
|
const onActivated: typeof import('vue')['onActivated']
|
||||||
|
const onBeforeMount: typeof import('vue')['onBeforeMount']
|
||||||
|
const onBeforeUnmount: typeof import('vue')['onBeforeUnmount']
|
||||||
|
const onBeforeUpdate: typeof import('vue')['onBeforeUpdate']
|
||||||
|
const onDeactivated: typeof import('vue')['onDeactivated']
|
||||||
|
const onErrorCaptured: typeof import('vue')['onErrorCaptured']
|
||||||
|
const onMounted: typeof import('vue')['onMounted']
|
||||||
|
const onRenderTracked: typeof import('vue')['onRenderTracked']
|
||||||
|
const onRenderTriggered: typeof import('vue')['onRenderTriggered']
|
||||||
|
const onScopeDispose: typeof import('vue')['onScopeDispose']
|
||||||
|
const onServerPrefetch: typeof import('vue')['onServerPrefetch']
|
||||||
|
const onUnmounted: typeof import('vue')['onUnmounted']
|
||||||
|
const onUpdated: typeof import('vue')['onUpdated']
|
||||||
|
const provide: typeof import('vue')['provide']
|
||||||
|
const reactive: typeof import('vue')['reactive']
|
||||||
|
const readonly: typeof import('vue')['readonly']
|
||||||
|
const ref: typeof import('vue')['ref']
|
||||||
|
const resolveComponent: typeof import('vue')['resolveComponent']
|
||||||
|
const shallowReactive: typeof import('vue')['shallowReactive']
|
||||||
|
const shallowReadonly: typeof import('vue')['shallowReadonly']
|
||||||
|
const shallowRef: typeof import('vue')['shallowRef']
|
||||||
|
const toRaw: typeof import('vue')['toRaw']
|
||||||
|
const toRef: typeof import('vue')['toRef']
|
||||||
|
const toRefs: typeof import('vue')['toRefs']
|
||||||
|
const toValue: typeof import('vue')['toValue']
|
||||||
|
const triggerRef: typeof import('vue')['triggerRef']
|
||||||
|
const unref: typeof import('vue')['unref']
|
||||||
|
const useAttrs: typeof import('vue')['useAttrs']
|
||||||
|
const useCssModule: typeof import('vue')['useCssModule']
|
||||||
|
const useCssVars: typeof import('vue')['useCssVars']
|
||||||
|
const useSlots: typeof import('vue')['useSlots']
|
||||||
|
const watch: typeof import('vue')['watch']
|
||||||
|
const watchEffect: typeof import('vue')['watchEffect']
|
||||||
|
const watchPostEffect: typeof import('vue')['watchPostEffect']
|
||||||
|
const watchSyncEffect: typeof import('vue')['watchSyncEffect']
|
||||||
|
}
|
||||||
|
// for type re-export
|
||||||
|
declare global {
|
||||||
|
// @ts-ignore
|
||||||
|
export type { Component, ComponentPublicInstance, ComputedRef, InjectionKey, PropType, Ref, VNode } from 'vue'
|
||||||
|
}
|
||||||
|
// for vue template auto import
|
||||||
|
import { UnwrapRef } from 'vue'
|
||||||
|
declare module 'vue' {
|
||||||
|
interface ComponentCustomProperties {
|
||||||
|
readonly EffectScope: UnwrapRef<typeof import('vue')['EffectScope']>
|
||||||
|
readonly computed: UnwrapRef<typeof import('vue')['computed']>
|
||||||
|
readonly createApp: UnwrapRef<typeof import('vue')['createApp']>
|
||||||
|
readonly customRef: UnwrapRef<typeof import('vue')['customRef']>
|
||||||
|
readonly defineAsyncComponent: UnwrapRef<typeof import('vue')['defineAsyncComponent']>
|
||||||
|
readonly defineComponent: UnwrapRef<typeof import('vue')['defineComponent']>
|
||||||
|
readonly effectScope: UnwrapRef<typeof import('vue')['effectScope']>
|
||||||
|
readonly getCurrentInstance: UnwrapRef<typeof import('vue')['getCurrentInstance']>
|
||||||
|
readonly getCurrentScope: UnwrapRef<typeof import('vue')['getCurrentScope']>
|
||||||
|
readonly h: UnwrapRef<typeof import('vue')['h']>
|
||||||
|
readonly inject: UnwrapRef<typeof import('vue')['inject']>
|
||||||
|
readonly isProxy: UnwrapRef<typeof import('vue')['isProxy']>
|
||||||
|
readonly isReactive: UnwrapRef<typeof import('vue')['isReactive']>
|
||||||
|
readonly isReadonly: UnwrapRef<typeof import('vue')['isReadonly']>
|
||||||
|
readonly isRef: UnwrapRef<typeof import('vue')['isRef']>
|
||||||
|
readonly markRaw: UnwrapRef<typeof import('vue')['markRaw']>
|
||||||
|
readonly nextTick: UnwrapRef<typeof import('vue')['nextTick']>
|
||||||
|
readonly onActivated: UnwrapRef<typeof import('vue')['onActivated']>
|
||||||
|
readonly onBeforeMount: UnwrapRef<typeof import('vue')['onBeforeMount']>
|
||||||
|
readonly onBeforeUnmount: UnwrapRef<typeof import('vue')['onBeforeUnmount']>
|
||||||
|
readonly onBeforeUpdate: UnwrapRef<typeof import('vue')['onBeforeUpdate']>
|
||||||
|
readonly onDeactivated: UnwrapRef<typeof import('vue')['onDeactivated']>
|
||||||
|
readonly onErrorCaptured: UnwrapRef<typeof import('vue')['onErrorCaptured']>
|
||||||
|
readonly onMounted: UnwrapRef<typeof import('vue')['onMounted']>
|
||||||
|
readonly onRenderTracked: UnwrapRef<typeof import('vue')['onRenderTracked']>
|
||||||
|
readonly onRenderTriggered: UnwrapRef<typeof import('vue')['onRenderTriggered']>
|
||||||
|
readonly onScopeDispose: UnwrapRef<typeof import('vue')['onScopeDispose']>
|
||||||
|
readonly onServerPrefetch: UnwrapRef<typeof import('vue')['onServerPrefetch']>
|
||||||
|
readonly onUnmounted: UnwrapRef<typeof import('vue')['onUnmounted']>
|
||||||
|
readonly onUpdated: UnwrapRef<typeof import('vue')['onUpdated']>
|
||||||
|
readonly provide: UnwrapRef<typeof import('vue')['provide']>
|
||||||
|
readonly reactive: UnwrapRef<typeof import('vue')['reactive']>
|
||||||
|
readonly readonly: UnwrapRef<typeof import('vue')['readonly']>
|
||||||
|
readonly ref: UnwrapRef<typeof import('vue')['ref']>
|
||||||
|
readonly resolveComponent: UnwrapRef<typeof import('vue')['resolveComponent']>
|
||||||
|
readonly shallowReactive: UnwrapRef<typeof import('vue')['shallowReactive']>
|
||||||
|
readonly shallowReadonly: UnwrapRef<typeof import('vue')['shallowReadonly']>
|
||||||
|
readonly shallowRef: UnwrapRef<typeof import('vue')['shallowRef']>
|
||||||
|
readonly toRaw: UnwrapRef<typeof import('vue')['toRaw']>
|
||||||
|
readonly toRef: UnwrapRef<typeof import('vue')['toRef']>
|
||||||
|
readonly toRefs: UnwrapRef<typeof import('vue')['toRefs']>
|
||||||
|
readonly toValue: UnwrapRef<typeof import('vue')['toValue']>
|
||||||
|
readonly triggerRef: UnwrapRef<typeof import('vue')['triggerRef']>
|
||||||
|
readonly unref: UnwrapRef<typeof import('vue')['unref']>
|
||||||
|
readonly useAttrs: UnwrapRef<typeof import('vue')['useAttrs']>
|
||||||
|
readonly useCssModule: UnwrapRef<typeof import('vue')['useCssModule']>
|
||||||
|
readonly useCssVars: UnwrapRef<typeof import('vue')['useCssVars']>
|
||||||
|
readonly useSlots: UnwrapRef<typeof import('vue')['useSlots']>
|
||||||
|
readonly watch: UnwrapRef<typeof import('vue')['watch']>
|
||||||
|
readonly watchEffect: UnwrapRef<typeof import('vue')['watchEffect']>
|
||||||
|
readonly watchPostEffect: UnwrapRef<typeof import('vue')['watchPostEffect']>
|
||||||
|
readonly watchSyncEffect: UnwrapRef<typeof import('vue')['watchSyncEffect']>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
declare module '@vue/runtime-core' {
|
||||||
|
interface ComponentCustomProperties {
|
||||||
|
readonly EffectScope: UnwrapRef<typeof import('vue')['EffectScope']>
|
||||||
|
readonly computed: UnwrapRef<typeof import('vue')['computed']>
|
||||||
|
readonly createApp: UnwrapRef<typeof import('vue')['createApp']>
|
||||||
|
readonly customRef: UnwrapRef<typeof import('vue')['customRef']>
|
||||||
|
readonly defineAsyncComponent: UnwrapRef<typeof import('vue')['defineAsyncComponent']>
|
||||||
|
readonly defineComponent: UnwrapRef<typeof import('vue')['defineComponent']>
|
||||||
|
readonly effectScope: UnwrapRef<typeof import('vue')['effectScope']>
|
||||||
|
readonly getCurrentInstance: UnwrapRef<typeof import('vue')['getCurrentInstance']>
|
||||||
|
readonly getCurrentScope: UnwrapRef<typeof import('vue')['getCurrentScope']>
|
||||||
|
readonly h: UnwrapRef<typeof import('vue')['h']>
|
||||||
|
readonly inject: UnwrapRef<typeof import('vue')['inject']>
|
||||||
|
readonly isProxy: UnwrapRef<typeof import('vue')['isProxy']>
|
||||||
|
readonly isReactive: UnwrapRef<typeof import('vue')['isReactive']>
|
||||||
|
readonly isReadonly: UnwrapRef<typeof import('vue')['isReadonly']>
|
||||||
|
readonly isRef: UnwrapRef<typeof import('vue')['isRef']>
|
||||||
|
readonly markRaw: UnwrapRef<typeof import('vue')['markRaw']>
|
||||||
|
readonly nextTick: UnwrapRef<typeof import('vue')['nextTick']>
|
||||||
|
readonly onActivated: UnwrapRef<typeof import('vue')['onActivated']>
|
||||||
|
readonly onBeforeMount: UnwrapRef<typeof import('vue')['onBeforeMount']>
|
||||||
|
readonly onBeforeUnmount: UnwrapRef<typeof import('vue')['onBeforeUnmount']>
|
||||||
|
readonly onBeforeUpdate: UnwrapRef<typeof import('vue')['onBeforeUpdate']>
|
||||||
|
readonly onDeactivated: UnwrapRef<typeof import('vue')['onDeactivated']>
|
||||||
|
readonly onErrorCaptured: UnwrapRef<typeof import('vue')['onErrorCaptured']>
|
||||||
|
readonly onMounted: UnwrapRef<typeof import('vue')['onMounted']>
|
||||||
|
readonly onRenderTracked: UnwrapRef<typeof import('vue')['onRenderTracked']>
|
||||||
|
readonly onRenderTriggered: UnwrapRef<typeof import('vue')['onRenderTriggered']>
|
||||||
|
readonly onScopeDispose: UnwrapRef<typeof import('vue')['onScopeDispose']>
|
||||||
|
readonly onServerPrefetch: UnwrapRef<typeof import('vue')['onServerPrefetch']>
|
||||||
|
readonly onUnmounted: UnwrapRef<typeof import('vue')['onUnmounted']>
|
||||||
|
readonly onUpdated: UnwrapRef<typeof import('vue')['onUpdated']>
|
||||||
|
readonly provide: UnwrapRef<typeof import('vue')['provide']>
|
||||||
|
readonly reactive: UnwrapRef<typeof import('vue')['reactive']>
|
||||||
|
readonly readonly: UnwrapRef<typeof import('vue')['readonly']>
|
||||||
|
readonly ref: UnwrapRef<typeof import('vue')['ref']>
|
||||||
|
readonly resolveComponent: UnwrapRef<typeof import('vue')['resolveComponent']>
|
||||||
|
readonly shallowReactive: UnwrapRef<typeof import('vue')['shallowReactive']>
|
||||||
|
readonly shallowReadonly: UnwrapRef<typeof import('vue')['shallowReadonly']>
|
||||||
|
readonly shallowRef: UnwrapRef<typeof import('vue')['shallowRef']>
|
||||||
|
readonly toRaw: UnwrapRef<typeof import('vue')['toRaw']>
|
||||||
|
readonly toRef: UnwrapRef<typeof import('vue')['toRef']>
|
||||||
|
readonly toRefs: UnwrapRef<typeof import('vue')['toRefs']>
|
||||||
|
readonly toValue: UnwrapRef<typeof import('vue')['toValue']>
|
||||||
|
readonly triggerRef: UnwrapRef<typeof import('vue')['triggerRef']>
|
||||||
|
readonly unref: UnwrapRef<typeof import('vue')['unref']>
|
||||||
|
readonly useAttrs: UnwrapRef<typeof import('vue')['useAttrs']>
|
||||||
|
readonly useCssModule: UnwrapRef<typeof import('vue')['useCssModule']>
|
||||||
|
readonly useCssVars: UnwrapRef<typeof import('vue')['useCssVars']>
|
||||||
|
readonly useSlots: UnwrapRef<typeof import('vue')['useSlots']>
|
||||||
|
readonly watch: UnwrapRef<typeof import('vue')['watch']>
|
||||||
|
readonly watchEffect: UnwrapRef<typeof import('vue')['watchEffect']>
|
||||||
|
readonly watchPostEffect: UnwrapRef<typeof import('vue')['watchPostEffect']>
|
||||||
|
readonly watchSyncEffect: UnwrapRef<typeof import('vue')['watchSyncEffect']>
|
||||||
|
}
|
||||||
|
}
|
17
src/components.d.ts
vendored
Normal file
17
src/components.d.ts
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
/* prettier-ignore */
|
||||||
|
// @ts-nocheck
|
||||||
|
// Generated by unplugin-vue-components
|
||||||
|
// Read more: https://github.com/vuejs/core/pull/3399
|
||||||
|
import '@vue/runtime-core'
|
||||||
|
|
||||||
|
export {}
|
||||||
|
|
||||||
|
declare module '@vue/runtime-core' {
|
||||||
|
export interface GlobalComponents {
|
||||||
|
HelloWorld: typeof import('./components/HelloWorld.vue')['default']
|
||||||
|
NButton: typeof import('naive-ui')['NButton']
|
||||||
|
NDataTable: typeof import('naive-ui')['NDataTable']
|
||||||
|
NSpace: typeof import('naive-ui')['NSpace']
|
||||||
|
}
|
||||||
|
}
|
@ -3,6 +3,9 @@ import "./style.css"
|
|||||||
import App from './App.vue'
|
import App from './App.vue'
|
||||||
import './samples/node-api'
|
import './samples/node-api'
|
||||||
|
|
||||||
|
import 'uno.css'
|
||||||
|
|
||||||
|
|
||||||
createApp(App)
|
createApp(App)
|
||||||
.mount('#app')
|
.mount('#app')
|
||||||
.$nextTick(() => {
|
.$nextTick(() => {
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
button:focus{outline-color: transparent !important;}
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
|
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
@ -27,8 +29,8 @@ body {
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
place-items: center;
|
place-items: center;
|
||||||
min-width: 320px;
|
width: 100%;
|
||||||
min-height: 100vh;
|
height: 100vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
@ -66,11 +68,14 @@ code {
|
|||||||
padding: 2em;
|
padding: 2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
button,input,textarea{outline: none;}
|
||||||
|
|
||||||
#app {
|
#app {
|
||||||
max-width: 1280px;
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: 2rem;
|
padding: 2rem;
|
||||||
text-align: center;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (prefers-color-scheme: light) {
|
@media (prefers-color-scheme: light) {
|
||||||
|
35
unocss.config.ts
Normal file
35
unocss.config.ts
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import {
|
||||||
|
defineConfig,
|
||||||
|
presetAttributify,
|
||||||
|
presetIcons,
|
||||||
|
presetUno,
|
||||||
|
presetWebFonts,
|
||||||
|
// transformerDirectives,
|
||||||
|
// transformerVariantGroup,
|
||||||
|
} from 'unocss'
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
// shortcuts: [
|
||||||
|
// ['btn', 'px-4 py-1 rounded inline-block bg-teal-600 text-white cursor-pointer hover:bg-teal-700 disabled:cursor-default disabled:bg-gray-600 disabled:opacity-50'],
|
||||||
|
// ['icon-btn', 'text-[0.9em] inline-block cursor-pointer select-none opacity-75 transition duration-200 ease-in-out hover:opacity-100 hover:text-teal-600 !outline-none'],
|
||||||
|
// ],
|
||||||
|
presets: [
|
||||||
|
presetUno(),
|
||||||
|
presetAttributify(),
|
||||||
|
presetIcons({
|
||||||
|
scale: 1.2,
|
||||||
|
warn: true,
|
||||||
|
}),
|
||||||
|
presetWebFonts({
|
||||||
|
fonts: {
|
||||||
|
sans: 'DM Sans',
|
||||||
|
serif: 'DM Serif Display',
|
||||||
|
mono: 'DM Mono',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
// transformers: [
|
||||||
|
// transformerDirectives(),
|
||||||
|
// transformerVariantGroup(),
|
||||||
|
// ],
|
||||||
|
})
|
@ -2,8 +2,13 @@ import { rmSync } from 'node:fs'
|
|||||||
import { defineConfig } from 'vite'
|
import { defineConfig } from 'vite'
|
||||||
import vue from '@vitejs/plugin-vue'
|
import vue from '@vitejs/plugin-vue'
|
||||||
import electron from 'vite-plugin-electron'
|
import electron from 'vite-plugin-electron'
|
||||||
|
import Components from 'unplugin-vue-components/vite'
|
||||||
|
import { NaiveUiResolver } from 'unplugin-vue-components/resolvers'
|
||||||
import renderer from 'vite-plugin-electron-renderer'
|
import renderer from 'vite-plugin-electron-renderer'
|
||||||
import pkg from './package.json'
|
import pkg from './package.json'
|
||||||
|
import Unocss from 'unocss/vite'
|
||||||
|
import AutoImport from 'unplugin-auto-import/vite'
|
||||||
|
import vueJsx from '@vitejs/plugin-vue-jsx'
|
||||||
|
|
||||||
// https://vitejs.dev/config/
|
// https://vitejs.dev/config/
|
||||||
export default defineConfig(({ command }) => {
|
export default defineConfig(({ command }) => {
|
||||||
@ -16,6 +21,27 @@ export default defineConfig(({ command }) => {
|
|||||||
return {
|
return {
|
||||||
plugins: [
|
plugins: [
|
||||||
vue(),
|
vue(),
|
||||||
|
vueJsx(),
|
||||||
|
Unocss(),
|
||||||
|
AutoImport({
|
||||||
|
imports: [
|
||||||
|
'vue',
|
||||||
|
],
|
||||||
|
dts: 'src/auto-imports.d.ts',
|
||||||
|
dirs: [],
|
||||||
|
vueTemplate: true,
|
||||||
|
}),
|
||||||
|
// https://github.com/antfu/unplugin-vue-components
|
||||||
|
Components({
|
||||||
|
resolvers: [NaiveUiResolver()],
|
||||||
|
// allow auto load markdown components under `./src/components/`
|
||||||
|
extensions: ['vue', 'md'],
|
||||||
|
// allow auto import and register components used in markdown
|
||||||
|
include: [/\.vue$/, /\.vue\?vue/, /\.md$/],
|
||||||
|
dts: 'src/components.d.ts',
|
||||||
|
}),
|
||||||
|
|
||||||
|
|
||||||
electron([
|
electron([
|
||||||
{
|
{
|
||||||
// Main-Process entry file of the Electron App.
|
// Main-Process entry file of the Electron App.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user