@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"extends": ["@commitlint/config-conventional"]
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
# 只在开发模式中被载入
|
||||||
|
VITE_PORT = 8001
|
||||||
|
|
||||||
|
# 网站根目录
|
||||||
|
VITE_PUBLIC_PATH = /
|
||||||
|
|
||||||
|
# 是否开启mock
|
||||||
|
VITE_USE_MOCK = false
|
||||||
|
|
||||||
|
# 网站前缀
|
||||||
|
VITE_BASE_URL = /
|
||||||
|
|
||||||
|
# 是否删除console
|
||||||
|
VITE_DROP_CONSOLE = true
|
||||||
|
|
||||||
|
# 跨域代理,可以配置多个,请注意不要换行
|
||||||
|
VITE_PROXY=[["/api","http://47.93.59.251:8311/jeecg-boot"]]
|
||||||
|
|
||||||
|
# API 接口地址
|
||||||
|
VITE_GLOB_API_URL =
|
||||||
|
|
||||||
|
# 图片上传地址
|
||||||
|
VITE_GLOB_UPLOAD_URL=
|
||||||
|
|
||||||
|
# 图片前缀地址
|
||||||
|
VITE_GLOB_IMG_URL="http://47.93.59.251:8311/jeecg-boot"
|
||||||
|
|
||||||
|
# 接口前缀
|
||||||
|
VITE_GLOB_API_URL_PREFIX = /api
|
@ -0,0 +1,130 @@
|
|||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
.pnpm-debug.log*
|
||||||
|
|
||||||
|
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||||
|
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||||
|
|
||||||
|
# Runtime data
|
||||||
|
pids
|
||||||
|
*.pid
|
||||||
|
*.seed
|
||||||
|
*.pid.lock
|
||||||
|
|
||||||
|
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||||
|
lib-cov
|
||||||
|
|
||||||
|
# Coverage directory used by tools like istanbul
|
||||||
|
coverage
|
||||||
|
*.lcov
|
||||||
|
|
||||||
|
# nyc test coverage
|
||||||
|
.nyc_output
|
||||||
|
|
||||||
|
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||||
|
.grunt
|
||||||
|
|
||||||
|
# Bower dependency directory (https://bower.io/)
|
||||||
|
bower_components
|
||||||
|
|
||||||
|
# node-waf configuration
|
||||||
|
.lock-wscript
|
||||||
|
|
||||||
|
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||||
|
build/Release
|
||||||
|
|
||||||
|
# Dependency directories
|
||||||
|
node_modules/
|
||||||
|
jspm_packages/
|
||||||
|
|
||||||
|
# Snowpack dependency directory (https://snowpack.dev/)
|
||||||
|
web_modules/
|
||||||
|
|
||||||
|
# TypeScript cache
|
||||||
|
*.tsbuildinfo
|
||||||
|
|
||||||
|
# Optional npm cache directory
|
||||||
|
.npm
|
||||||
|
|
||||||
|
# Optional eslint cache
|
||||||
|
.eslintcache
|
||||||
|
|
||||||
|
# Optional stylelint cache
|
||||||
|
.stylelintcache
|
||||||
|
|
||||||
|
# Microbundle cache
|
||||||
|
.rpt2_cache/
|
||||||
|
.rts2_cache_cjs/
|
||||||
|
.rts2_cache_es/
|
||||||
|
.rts2_cache_umd/
|
||||||
|
|
||||||
|
# Optional REPL history
|
||||||
|
.node_repl_history
|
||||||
|
|
||||||
|
# Output of 'npm pack'
|
||||||
|
*.tgz
|
||||||
|
|
||||||
|
# Yarn Integrity file
|
||||||
|
.yarn-integrity
|
||||||
|
|
||||||
|
# dotenv environment variable files
|
||||||
|
.env
|
||||||
|
.env.development.local
|
||||||
|
.env.test.local
|
||||||
|
.env.production.local
|
||||||
|
.env.local
|
||||||
|
|
||||||
|
# parcel-bundler cache (https://parceljs.org/)
|
||||||
|
.cache
|
||||||
|
.parcel-cache
|
||||||
|
|
||||||
|
# Next.js build output
|
||||||
|
.next
|
||||||
|
out
|
||||||
|
|
||||||
|
# Nuxt.js build / generate output
|
||||||
|
.nuxt
|
||||||
|
dist
|
||||||
|
|
||||||
|
# Gatsby files
|
||||||
|
.cache/
|
||||||
|
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||||
|
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||||
|
# public
|
||||||
|
|
||||||
|
# vuepress build output
|
||||||
|
.vuepress/dist
|
||||||
|
|
||||||
|
# vuepress v2.x temp and cache directory
|
||||||
|
.temp
|
||||||
|
.cache
|
||||||
|
|
||||||
|
# Docusaurus cache and generated files
|
||||||
|
.docusaurus
|
||||||
|
|
||||||
|
# Serverless directories
|
||||||
|
.serverless/
|
||||||
|
|
||||||
|
# FuseBox cache
|
||||||
|
.fusebox/
|
||||||
|
|
||||||
|
# DynamoDB Local files
|
||||||
|
.dynamodb/
|
||||||
|
|
||||||
|
# TernJS port file
|
||||||
|
.tern-port
|
||||||
|
|
||||||
|
# Stores VSCode versions used for testing VSCode extensions
|
||||||
|
.vscode-test
|
||||||
|
|
||||||
|
# yarn v2
|
||||||
|
.yarn/cache
|
||||||
|
.yarn/unplugged
|
||||||
|
.yarn/build-state.yml
|
||||||
|
.yarn/install-state.gz
|
||||||
|
.pnp.*
|
@ -0,0 +1,4 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
. "$(dirname -- "$0")/_/husky.sh"
|
||||||
|
|
||||||
|
node_modules/.bin/commitlint --edit ${1}
|
@ -0,0 +1,5 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
. "$(dirname -- "$0")/_/husky.sh"
|
||||||
|
|
||||||
|
# node_modules/.bin/lint-staged
|
||||||
|
date
|
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"recommendations": ["Vue.volar", "Vue.vscode-typescript-vue-plugin"]
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
// Enable the ESlint flat config support
|
||||||
|
"eslint.experimental.useFlatConfig": true,
|
||||||
|
|
||||||
|
// Disable the default formatter, use eslint instead
|
||||||
|
"prettier.enable": false,
|
||||||
|
"editor.formatOnSave": false,
|
||||||
|
|
||||||
|
// Auto fix
|
||||||
|
"editor.codeActionsOnSave": {
|
||||||
|
"source.fixAll.eslint": "explicit",
|
||||||
|
"source.organizeImports": "never"
|
||||||
|
},
|
||||||
|
|
||||||
|
// Silent the stylistic rules in you IDE, but still auto fix them
|
||||||
|
"eslint.rules.customizations": [
|
||||||
|
{ "rule": "style/*", "severity": "off" },
|
||||||
|
{ "rule": "format/*", "severity": "off" },
|
||||||
|
{ "rule": "*-indent", "severity": "off" },
|
||||||
|
{ "rule": "*-spacing", "severity": "off" },
|
||||||
|
{ "rule": "*-spaces", "severity": "off" },
|
||||||
|
{ "rule": "*-order", "severity": "off" },
|
||||||
|
{ "rule": "*-dangle", "severity": "off" },
|
||||||
|
{ "rule": "*-newline", "severity": "off" },
|
||||||
|
{ "rule": "*quotes", "severity": "off" },
|
||||||
|
{ "rule": "*semi", "severity": "off" }
|
||||||
|
],
|
||||||
|
|
||||||
|
// Enable eslint for all supported languages
|
||||||
|
"eslint.validate": [
|
||||||
|
"javascript",
|
||||||
|
"javascriptreact",
|
||||||
|
"typescript",
|
||||||
|
"typescriptreact",
|
||||||
|
"vue",
|
||||||
|
"html",
|
||||||
|
"markdown",
|
||||||
|
"json",
|
||||||
|
"jsonc",
|
||||||
|
"yaml"
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
## dev
|
||||||
|
|
||||||
|
1. 安装Node
|
||||||
|
2. 全局安装pnpm
|
||||||
|
3. pnpm install
|
||||||
|
4. pnpm serve
|
@ -0,0 +1,5 @@
|
|||||||
|
## TODO
|
||||||
|
|
||||||
|
1. 默认显示配置问题。对客户端来说,个性配置其实是个显示配置,配置在后端更为合理
|
||||||
|
2. 操作符的用处
|
||||||
|
3.
|
@ -0,0 +1,6 @@
|
|||||||
|
/**
|
||||||
|
* The name of the configuration file entered in the production environment
|
||||||
|
*/
|
||||||
|
export const GLOB_CONFIG_FILE_NAME = 'app.config.js'
|
||||||
|
|
||||||
|
export const OUTPUT_DIR = 'dist'
|
@ -0,0 +1,9 @@
|
|||||||
|
/**
|
||||||
|
* Get the configuration file variable name
|
||||||
|
* @param env
|
||||||
|
*/
|
||||||
|
export function getConfigFileName(env: Record<string, any>) {
|
||||||
|
return `__PRODUCTION__${env.VITE_GLOB_APP_SHORT_NAME || '__APP'}__CONF__`
|
||||||
|
.toUpperCase()
|
||||||
|
.replace(/\s/g, '')
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
/**
|
||||||
|
* Generate additional configuration files when used for packaging. The file can be configured with some global variables, so that it can be changed directly externally without repackaging
|
||||||
|
*/
|
||||||
|
import fs, { writeFileSync } from 'fs-extra'
|
||||||
|
import { GLOB_CONFIG_FILE_NAME, OUTPUT_DIR } from '../constant'
|
||||||
|
|
||||||
|
import { getEnvConfig, getRootPath } from '../utils'
|
||||||
|
import { getConfigFileName } from '../getConfigFileName'
|
||||||
|
|
||||||
|
function createConfig(
|
||||||
|
{
|
||||||
|
configName,
|
||||||
|
config,
|
||||||
|
configFileName = GLOB_CONFIG_FILE_NAME,
|
||||||
|
}: { configName: string, config: any, configFileName?: string } = { configName: '', config: {} },
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
const windowConf = `window.${configName}`
|
||||||
|
// Ensure that the variable will not be modified
|
||||||
|
const configStr = `${windowConf}=${JSON.stringify(config)};
|
||||||
|
Object.freeze(${windowConf});
|
||||||
|
Object.defineProperty(window, "${configName}", {
|
||||||
|
configurable: false,
|
||||||
|
writable: false,
|
||||||
|
});
|
||||||
|
`.replace(/\s/g, '')
|
||||||
|
fs.mkdirp(getRootPath(OUTPUT_DIR))
|
||||||
|
writeFileSync(getRootPath(`${OUTPUT_DIR}/${configFileName}`), configStr)
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function runBuildConfig() {
|
||||||
|
const config = getEnvConfig()
|
||||||
|
const configFileName = getConfigFileName(config)
|
||||||
|
createConfig({ config, configName: configFileName })
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
// #!/usr/bin/env node
|
||||||
|
|
||||||
|
import process from 'node:process'
|
||||||
|
import { runBuildConfig } from './buildConfig'
|
||||||
|
|
||||||
|
export async function runBuild() {
|
||||||
|
try {
|
||||||
|
const argvList = process.argv.splice(2)
|
||||||
|
|
||||||
|
// Generate configuration file
|
||||||
|
if (!argvList.includes('disabled-config'))
|
||||||
|
await runBuildConfig()
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
runBuild()
|
@ -0,0 +1,73 @@
|
|||||||
|
import fs from 'node:fs'
|
||||||
|
import path from 'node:path'
|
||||||
|
import process from 'node:process'
|
||||||
|
import dotenv from 'dotenv'
|
||||||
|
|
||||||
|
export function isDevFn(mode: string): boolean {
|
||||||
|
return mode === 'development'
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isProdFn(mode: string): boolean {
|
||||||
|
return mode === 'production'
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether to generate package preview
|
||||||
|
*/
|
||||||
|
export function isReportMode(): boolean {
|
||||||
|
return process.env.REPORT === 'true'
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read all environment variable configuration files to process.env
|
||||||
|
export function wrapperEnv(envConf: Recordable): ViteEnv {
|
||||||
|
const ret: any = {}
|
||||||
|
|
||||||
|
for (const envName of Object.keys(envConf)) {
|
||||||
|
let realName = envConf[envName].replace(/\\n/g, '\n')
|
||||||
|
realName = realName === 'true' ? true : realName === 'false' ? false : realName
|
||||||
|
|
||||||
|
if (envName === 'VITE_PORT')
|
||||||
|
realName = Number(realName)
|
||||||
|
|
||||||
|
if (envName === 'VITE_PROXY') {
|
||||||
|
try {
|
||||||
|
realName = JSON.parse(realName)
|
||||||
|
}
|
||||||
|
catch (error) {}
|
||||||
|
}
|
||||||
|
ret[envName] = realName
|
||||||
|
process.env[envName] = realName
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the environment variables starting with the specified prefix
|
||||||
|
* @param match prefix
|
||||||
|
* @param confFiles ext
|
||||||
|
*/
|
||||||
|
export function getEnvConfig(match = 'VITE_GLOB_', confFiles = ['.env', '.env.production']) {
|
||||||
|
let envConfig = {}
|
||||||
|
confFiles.forEach((item) => {
|
||||||
|
try {
|
||||||
|
const env = dotenv.parse(fs.readFileSync(path.resolve(process.cwd(), item)))
|
||||||
|
envConfig = { ...envConfig, ...env }
|
||||||
|
}
|
||||||
|
catch (error) {}
|
||||||
|
})
|
||||||
|
|
||||||
|
Object.keys(envConfig).forEach((key) => {
|
||||||
|
const reg = new RegExp(`^(${match})`)
|
||||||
|
if (!reg.test(key))
|
||||||
|
Reflect.deleteProperty(envConfig, key)
|
||||||
|
})
|
||||||
|
return envConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get user root directory
|
||||||
|
* @param dir file path
|
||||||
|
*/
|
||||||
|
export function getRootPath(...dir: string[]) {
|
||||||
|
return path.resolve(process.cwd(), ...dir)
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
/**
|
||||||
|
* Used to package and output gzip. Note that this does not work properly in Vite, the specific reason is still being investigated
|
||||||
|
* https://github.com/anncwb/vite-plugin-compression
|
||||||
|
*/
|
||||||
|
import type { Plugin } from 'vite'
|
||||||
|
|
||||||
|
import compressPlugin from 'vite-plugin-compression'
|
||||||
|
|
||||||
|
export function configCompressPlugin(
|
||||||
|
compress: 'gzip' | 'brotli' | 'none',
|
||||||
|
deleteOriginFile = false,
|
||||||
|
): Plugin | Plugin[] {
|
||||||
|
const compressList = compress.split(',')
|
||||||
|
|
||||||
|
const plugins: Plugin[] = []
|
||||||
|
|
||||||
|
if (compressList.includes('gzip')) {
|
||||||
|
plugins.push(
|
||||||
|
compressPlugin({
|
||||||
|
ext: '.gz',
|
||||||
|
deleteOriginFile,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (compressList.includes('brotli')) {
|
||||||
|
plugins.push(
|
||||||
|
compressPlugin({
|
||||||
|
ext: '.br',
|
||||||
|
algorithm: 'brotliCompress',
|
||||||
|
deleteOriginFile,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return plugins
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
/**
|
||||||
|
* Plugin to minimize and use ejs template syntax in index.html.
|
||||||
|
* https://github.com/anncwb/vite-plugin-html
|
||||||
|
*/
|
||||||
|
import type { PluginOption } from 'vite'
|
||||||
|
import { createHtmlPlugin } from 'vite-plugin-html'
|
||||||
|
import { GLOB_CONFIG_FILE_NAME } from '../../constant'
|
||||||
|
import pkg from '../../../package.json'
|
||||||
|
|
||||||
|
export function configHtmlPlugin(env: ViteEnv, isBuild: boolean) {
|
||||||
|
const { VITE_GLOB_APP_TITLE, VITE_PUBLIC_PATH } = env
|
||||||
|
|
||||||
|
const path = VITE_PUBLIC_PATH.endsWith('/') ? VITE_PUBLIC_PATH : `${VITE_PUBLIC_PATH}/`
|
||||||
|
|
||||||
|
const getAppConfigSrc = () => {
|
||||||
|
return `${path || '/'}${GLOB_CONFIG_FILE_NAME}?v=${pkg.version}-${new Date().getTime()}`
|
||||||
|
}
|
||||||
|
const htmlPlugin: PluginOption[] = createHtmlPlugin({
|
||||||
|
minify: isBuild,
|
||||||
|
inject: {
|
||||||
|
// Inject data into ejs template
|
||||||
|
data: {
|
||||||
|
title: VITE_GLOB_APP_TITLE,
|
||||||
|
},
|
||||||
|
tags: isBuild
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
tag: 'script',
|
||||||
|
attrs: {
|
||||||
|
src: getAppConfigSrc(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: [],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return htmlPlugin
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
import path from 'node:path'
|
||||||
|
import process from 'node:process'
|
||||||
|
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
|
||||||
|
|
||||||
|
export function configIconPlugin() {
|
||||||
|
const iconPlugin = createSvgIconsPlugin({
|
||||||
|
// Specify the icon folder to be cached
|
||||||
|
iconDirs: [path.resolve(process.cwd(), 'src/assets/icons')],
|
||||||
|
// Specify symbolId format
|
||||||
|
symbolId: 'icon-[dir]-[name]',
|
||||||
|
inject: 'body-last',
|
||||||
|
customDomId: '__svg__icons__dom__',
|
||||||
|
})
|
||||||
|
|
||||||
|
return iconPlugin
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
import type { Plugin, PluginOption } from 'vite'
|
||||||
|
import Components from 'unplugin-vue-components/vite'
|
||||||
|
import { NaiveUiResolver } from 'unplugin-vue-components/resolvers'
|
||||||
|
|
||||||
|
import vue from '@vitejs/plugin-vue'
|
||||||
|
|
||||||
|
import { configHtmlPlugin } from './html'
|
||||||
|
import { configMockPlugin } from './mock'
|
||||||
|
import { configCompressPlugin } from './compress'
|
||||||
|
import { configIconPlugin } from './icon'
|
||||||
|
|
||||||
|
export function createVitePlugins(viteEnv: ViteEnv, isBuild: boolean, prodMock) {
|
||||||
|
const { VITE_USE_MOCK, VITE_BUILD_COMPRESS, VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE } = viteEnv
|
||||||
|
|
||||||
|
const vitePlugins: (Plugin | Plugin[] | PluginOption[])[] = [
|
||||||
|
// have to
|
||||||
|
vue(),
|
||||||
|
|
||||||
|
// 按需引入NaiveUi且自动创建组件声明
|
||||||
|
Components({
|
||||||
|
dts: true,
|
||||||
|
resolvers: [NaiveUiResolver()],
|
||||||
|
}),
|
||||||
|
]
|
||||||
|
|
||||||
|
// vite-plugin-html
|
||||||
|
vitePlugins.push(configHtmlPlugin(viteEnv, isBuild))
|
||||||
|
|
||||||
|
// vite-plugin-mock
|
||||||
|
VITE_USE_MOCK && vitePlugins.push(configMockPlugin(isBuild, prodMock))
|
||||||
|
|
||||||
|
vitePlugins.push(configIconPlugin())
|
||||||
|
|
||||||
|
if (isBuild) {
|
||||||
|
// rollup-plugin-gzip
|
||||||
|
vitePlugins.push(
|
||||||
|
configCompressPlugin(VITE_BUILD_COMPRESS, VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return vitePlugins
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
/**
|
||||||
|
* Mock plugin for development and production.
|
||||||
|
* https://github.com/anncwb/vite-plugin-mock
|
||||||
|
*/
|
||||||
|
import { viteMockServe } from 'vite-plugin-mock'
|
||||||
|
|
||||||
|
export function configMockPlugin(isBuild: boolean, prodMock: boolean) {
|
||||||
|
return viteMockServe({
|
||||||
|
ignore: /^\_/,
|
||||||
|
mockPath: 'mock',
|
||||||
|
localEnabled: !isBuild,
|
||||||
|
prodEnabled: isBuild && prodMock,
|
||||||
|
injectCode: `
|
||||||
|
import { setupProdMockServer } from '../mock/_createProductionServer';
|
||||||
|
|
||||||
|
setupProdMockServer();
|
||||||
|
`,
|
||||||
|
})
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
/**
|
||||||
|
* Used to parse the .env.development proxy configuration
|
||||||
|
*/
|
||||||
|
import type { ProxyOptions } from 'vite'
|
||||||
|
|
||||||
|
type ProxyItem = [string, string]
|
||||||
|
|
||||||
|
type ProxyList = ProxyItem[]
|
||||||
|
|
||||||
|
type ProxyTargetList = Record<string, ProxyOptions & { rewrite: (path: string) => string }>
|
||||||
|
|
||||||
|
const httpsRE = /^https:\/\//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate proxy
|
||||||
|
* @param list
|
||||||
|
*/
|
||||||
|
export function createProxy(list: ProxyList = []) {
|
||||||
|
const ret: ProxyTargetList = {}
|
||||||
|
for (const [prefix, target] of list) {
|
||||||
|
const isHttps = httpsRE.test(target)
|
||||||
|
|
||||||
|
// https://github.com/http-party/node-http-proxy#options
|
||||||
|
ret[prefix] = {
|
||||||
|
target,
|
||||||
|
changeOrigin: true,
|
||||||
|
ws: true,
|
||||||
|
rewrite: path => path.replace(new RegExp(`^${prefix}`), ''),
|
||||||
|
// https is require secure=false
|
||||||
|
...(isHttps ? { secure: false } : {}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
/* prettier-ignore */
|
||||||
|
// @ts-nocheck
|
||||||
|
// Generated by unplugin-vue-components
|
||||||
|
// Read more: https://github.com/vuejs/core/pull/3399
|
||||||
|
export {}
|
||||||
|
|
||||||
|
declare module 'vue' {
|
||||||
|
export interface GlobalComponents {
|
||||||
|
Application: typeof import('./src/components/Application/Application.vue')['default']
|
||||||
|
BasicModal: typeof import('./src/components/Modal/BasicModal.vue')['default']
|
||||||
|
NAvatar: typeof import('naive-ui')['NAvatar']
|
||||||
|
NButton: typeof import('naive-ui')['NButton']
|
||||||
|
NCard: typeof import('naive-ui')['NCard']
|
||||||
|
NCheckbox: typeof import('naive-ui')['NCheckbox']
|
||||||
|
NCollapse: typeof import('naive-ui')['NCollapse']
|
||||||
|
NCollapseItem: typeof import('naive-ui')['NCollapseItem']
|
||||||
|
NConfigProvider: typeof import('naive-ui')['NConfigProvider']
|
||||||
|
NDatePicker: typeof import('naive-ui')['NDatePicker']
|
||||||
|
NDialogProvider: typeof import('naive-ui')['NDialogProvider']
|
||||||
|
NDivider: typeof import('naive-ui')['NDivider']
|
||||||
|
NDropdown: typeof import('naive-ui')['NDropdown']
|
||||||
|
NForm: typeof import('naive-ui')['NForm']
|
||||||
|
NFormItem: typeof import('naive-ui')['NFormItem']
|
||||||
|
NGi: typeof import('naive-ui')['NGi']
|
||||||
|
NGrid: typeof import('naive-ui')['NGrid']
|
||||||
|
NGridItem: typeof import('naive-ui')['NGridItem']
|
||||||
|
NImage: typeof import('naive-ui')['NImage']
|
||||||
|
NInput: typeof import('naive-ui')['NInput']
|
||||||
|
NMessageProvider: typeof import('naive-ui')['NMessageProvider']
|
||||||
|
NModal: typeof import('naive-ui')['NModal']
|
||||||
|
NNotificationProvider: typeof import('naive-ui')['NNotificationProvider']
|
||||||
|
NPopover: typeof import('naive-ui')['NPopover']
|
||||||
|
NPopselect: typeof import('naive-ui')['NPopselect']
|
||||||
|
NScrollbar: typeof import('naive-ui')['NScrollbar']
|
||||||
|
NSelect: typeof import('naive-ui')['NSelect']
|
||||||
|
NSlider: typeof import('naive-ui')['NSlider']
|
||||||
|
NSpace: typeof import('naive-ui')['NSpace']
|
||||||
|
NSpin: typeof import('naive-ui')['NSpin']
|
||||||
|
NSwitch: typeof import('naive-ui')['NSwitch']
|
||||||
|
NTabPane: typeof import('naive-ui')['NTabPane']
|
||||||
|
NTabs: typeof import('naive-ui')['NTabs']
|
||||||
|
NTag: typeof import('naive-ui')['NTag']
|
||||||
|
NTooltip: typeof import('naive-ui')['NTooltip']
|
||||||
|
NUpload: typeof import('naive-ui')['NUpload']
|
||||||
|
NUploadDragger: typeof import('naive-ui')['NUploadDragger']
|
||||||
|
Quill: typeof import('./src/components/RichEditor/Quill.vue')['default']
|
||||||
|
RouterLink: typeof import('vue-router')['RouterLink']
|
||||||
|
RouterView: typeof import('vue-router')['RouterView']
|
||||||
|
SvgIcon: typeof import('./src/components/Icon/SvgIcon.vue')['default']
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
// @ts-check
|
||||||
|
const antfu = require('@antfu/eslint-config').default
|
||||||
|
|
||||||
|
module.exports = antfu(
|
||||||
|
{
|
||||||
|
ignores: [
|
||||||
|
// eslint ignore globs here
|
||||||
|
'node_modules',
|
||||||
|
'.vscode',
|
||||||
|
'dist',
|
||||||
|
'/public',
|
||||||
|
'.husky',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
rules: {
|
||||||
|
// 允许使用 debugger
|
||||||
|
'no-debugger': 'off',
|
||||||
|
'unused-imports/no-unused-vars': 'off',
|
||||||
|
'unused-imports/no-unused-imports': 'off',
|
||||||
|
'jsdoc/require-returns-description': 'off',
|
||||||
|
'no-restricted-syntax': [
|
||||||
|
// eslint-disable-next-line node/prefer-global/process
|
||||||
|
process.env.MODE === 'production' ? 2 : 0,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
@ -0,0 +1,123 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-cmn-Hans" id="htmlRoot" data-theme="light">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible"/>
|
||||||
|
<meta content="webkit" name="renderer"/>
|
||||||
|
<meta
|
||||||
|
content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=0"
|
||||||
|
name="viewport"
|
||||||
|
/>
|
||||||
|
<link href="/favicon.ico" rel="icon"/>
|
||||||
|
<title><%= title %></title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="appProvider" style="display: none"></div>
|
||||||
|
<div id="app">
|
||||||
|
<style>
|
||||||
|
.first-loading-wrap {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
height: 100vh;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.first-loading-wrap > h1 {
|
||||||
|
font-size: 128px
|
||||||
|
}
|
||||||
|
|
||||||
|
.first-loading-wrap .loading-wrap {
|
||||||
|
padding: 98px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot {
|
||||||
|
animation: antRotate 1.2s infinite linear;
|
||||||
|
transform: rotate(45deg);
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 32px;
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
box-sizing: border-box
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot i {
|
||||||
|
width: 14px;
|
||||||
|
height: 14px;
|
||||||
|
position: absolute;
|
||||||
|
display: block;
|
||||||
|
background-color: #1890ff;
|
||||||
|
border-radius: 100%;
|
||||||
|
transform: scale(.75);
|
||||||
|
transform-origin: 50% 50%;
|
||||||
|
opacity: .3;
|
||||||
|
animation: antSpinMove 1s infinite linear alternate
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot i:nth-child(1) {
|
||||||
|
top: 0;
|
||||||
|
left: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot i:nth-child(2) {
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
-webkit-animation-delay: .4s;
|
||||||
|
animation-delay: .4s
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot i:nth-child(3) {
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
-webkit-animation-delay: .8s;
|
||||||
|
animation-delay: .8s
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot i:nth-child(4) {
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
-webkit-animation-delay: 1.2s;
|
||||||
|
animation-delay: 1.2s
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes antRotate {
|
||||||
|
to {
|
||||||
|
-webkit-transform: rotate(405deg);
|
||||||
|
transform: rotate(405deg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@-webkit-keyframes antRotate {
|
||||||
|
to {
|
||||||
|
-webkit-transform: rotate(405deg);
|
||||||
|
transform: rotate(405deg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes antSpinMove {
|
||||||
|
to {
|
||||||
|
opacity: 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@-webkit-keyframes antSpinMove {
|
||||||
|
to {
|
||||||
|
opacity: 1
|
||||||
|
}
|
||||||
|
}</style>
|
||||||
|
<div class="first-loading-wrap">
|
||||||
|
<div class="loading-wrap">
|
||||||
|
<span class="dot dot-spin"><i></i><i></i><i></i><i></i></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="selection-box" style="border: 1px dotted black;position: absolute;display: none;"></div>
|
||||||
|
<script>var globalThis = window;</script>
|
||||||
|
<script src="/src/main.ts" type="module"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,22 @@
|
|||||||
|
import { createProdMockServer } from 'vite-plugin-mock/es/createProdMockServer'
|
||||||
|
|
||||||
|
interface IModuleType {
|
||||||
|
default: any[]
|
||||||
|
}
|
||||||
|
|
||||||
|
const modules = import.meta.glob<IModuleType>('./**/*.ts', { eager: true })
|
||||||
|
|
||||||
|
const mockModules: any[] = []
|
||||||
|
Object.keys(modules).forEach((key) => {
|
||||||
|
if (key.includes('/_'))
|
||||||
|
return
|
||||||
|
|
||||||
|
mockModules.push(...modules[key].default)
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used in a production environment. Need to manually import all modules
|
||||||
|
*/
|
||||||
|
export function setupProdMockServer() {
|
||||||
|
createProdMockServer(mockModules)
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
import Mock from 'mockjs'
|
||||||
|
import { resultSuccess } from '../_util'
|
||||||
|
|
||||||
|
const Random = Mock.Random
|
||||||
|
|
||||||
|
const token = Random.string('upper', 32, 32)
|
||||||
|
|
||||||
|
const adminInfo = {
|
||||||
|
userId: '1',
|
||||||
|
username: 'admin',
|
||||||
|
realName: 'Admin',
|
||||||
|
avatar: Random.image(),
|
||||||
|
desc: 'manager',
|
||||||
|
password: Random.string('upper', 4, 16),
|
||||||
|
token,
|
||||||
|
permissions: [
|
||||||
|
{
|
||||||
|
label: '主控台',
|
||||||
|
value: 'home_main',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '任务审批',
|
||||||
|
value: 'task-main',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'AI工单',
|
||||||
|
value: 'worksheet-main',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
export default [
|
||||||
|
{
|
||||||
|
url: '/api/login',
|
||||||
|
timeout: 1000,
|
||||||
|
method: 'post',
|
||||||
|
response: () => {
|
||||||
|
return resultSuccess({ token })
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: '/api/admin_info',
|
||||||
|
timeout: 1000,
|
||||||
|
method: 'get',
|
||||||
|
response: () => {
|
||||||
|
// const token = getRequestToken(request);
|
||||||
|
// if (!token) return resultError('Invalid token');
|
||||||
|
return resultSuccess(adminInfo)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
@ -0,0 +1,78 @@
|
|||||||
|
{
|
||||||
|
"name": "image-ai-deduplication",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"serve": "pnpm run dev",
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "vite build && esno ./build/script/postBuild.ts",
|
||||||
|
"preview": "npm run build && vite preview",
|
||||||
|
"preview:dist": "vite preview",
|
||||||
|
"lint": "eslint .",
|
||||||
|
"lint:fix": "eslint . --fix",
|
||||||
|
"cleanup": "rimraf node_modules && rimraf pnpm-lock.yaml",
|
||||||
|
"prepare": "husky install"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@vueup/vue-quill": "^1.2.0",
|
||||||
|
"@vueuse/core": "^10.7.0",
|
||||||
|
"axios": "^1.4.0",
|
||||||
|
"date-fns": "^2.30.0",
|
||||||
|
"esno": "^0.16.3",
|
||||||
|
"file-saver": "^2.0.5",
|
||||||
|
"imagesloaded": "^5.0.0",
|
||||||
|
"lodash-es": "^4.17.21",
|
||||||
|
"masonry-layout": "^4.2.2",
|
||||||
|
"mitt": "^3.0.1",
|
||||||
|
"mockjs": "^1.1.0",
|
||||||
|
"naive-ui": "^2.34.4",
|
||||||
|
"pinia": "^2.0.33",
|
||||||
|
"qs": "^6.11.2",
|
||||||
|
"sortablejs": "^1.15.1",
|
||||||
|
"vue": "^3.3.8",
|
||||||
|
"vue-draggable-plus": "^0.3.5",
|
||||||
|
"vue-mousetrap": "^1.0.5",
|
||||||
|
"vue-router": "^4.1.6",
|
||||||
|
"vue-types": "^4.2.1",
|
||||||
|
"xlsx": "^0.18.5"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@antfu/eslint-config": "^2.3.3",
|
||||||
|
"@commitlint/cli": "^18.4.3",
|
||||||
|
"@commitlint/config-conventional": "^18.4.3",
|
||||||
|
"@types/imagesloaded": "^4.1.6",
|
||||||
|
"@types/lodash": "^4.14.197",
|
||||||
|
"@types/masonry-layout": "^4.2.7",
|
||||||
|
"@types/node": "^18.17.1",
|
||||||
|
"@types/sortablejs": "^1.15.7",
|
||||||
|
"@vitejs/plugin-vue": "^4.5.0",
|
||||||
|
"autoprefixer": "^10.4.13",
|
||||||
|
"core-js": "^3.32.0",
|
||||||
|
"dotenv": "^16.3.1",
|
||||||
|
"eslint": "^8.55.0",
|
||||||
|
"fs-extra": "^11.2.0",
|
||||||
|
"husky": "^8.0.0",
|
||||||
|
"less": "^4.2.0",
|
||||||
|
"less-loader": "^11.1.3",
|
||||||
|
"lint-staged": "^13.1.2",
|
||||||
|
"postcss": "^8.4.27",
|
||||||
|
"rimraf": "^4.2.0",
|
||||||
|
"sass": "^1.69.5",
|
||||||
|
"tailwindcss": "^3.3.3",
|
||||||
|
"typescript": "^4.9.5",
|
||||||
|
"unplugin-vue-components": "^0.26.0",
|
||||||
|
"vite": "^5.0.0",
|
||||||
|
"vite-plugin-compression": "^0.5.1",
|
||||||
|
"vite-plugin-html": "^3.2.0",
|
||||||
|
"vite-plugin-mock": "^2.9.8",
|
||||||
|
"vite-plugin-style-import": "^2.0.0",
|
||||||
|
"vite-plugin-svg-icons": "^2.0.1",
|
||||||
|
"vue-demi": "^0.13.11",
|
||||||
|
"vue-tsc": "^1.8.22"
|
||||||
|
},
|
||||||
|
"lint-staged": {
|
||||||
|
"*.{ts,tsx,vue}": [
|
||||||
|
"pnpm lint:fix"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
module.exports = {
|
||||||
|
plugins: {
|
||||||
|
tailwindcss: {},
|
||||||
|
autoprefixer: {},
|
||||||
|
},
|
||||||
|
}
|
After Width: | Height: | Size: 1.5 KiB |
@ -0,0 +1,57 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import { dateZhCN, zhCN } from 'naive-ui'
|
||||||
|
import { computed } from 'vue'
|
||||||
|
import { AppProvider } from '@/components/Application'
|
||||||
|
import { lighten } from '@/utils/index'
|
||||||
|
|
||||||
|
const getThemeOverrides = computed(() => {
|
||||||
|
const theme = '#1980FF'
|
||||||
|
const lightenStr = lighten(theme, 6)
|
||||||
|
|
||||||
|
return {
|
||||||
|
common: {
|
||||||
|
primaryColor: theme,
|
||||||
|
primaryColorHover: lightenStr,
|
||||||
|
primaryColorPressed: lightenStr,
|
||||||
|
primaryColorSuppl: theme,
|
||||||
|
},
|
||||||
|
Switch: {
|
||||||
|
railColorActive: '#07C984',
|
||||||
|
},
|
||||||
|
Input: {
|
||||||
|
borderHover: '0px',
|
||||||
|
borderFocus: '0px',
|
||||||
|
boxShadowFocus: '#ff0000',
|
||||||
|
},
|
||||||
|
Tag: {
|
||||||
|
colorCheckedHover: '#507afd',
|
||||||
|
colorCheckedPressed: '#507afd',
|
||||||
|
},
|
||||||
|
Slider: {
|
||||||
|
fillColor: '#1980FF',
|
||||||
|
dotBorderActive: '#1980FF',
|
||||||
|
fillColorHover: '#1980FF',
|
||||||
|
},
|
||||||
|
Card: {
|
||||||
|
padding: '0px',
|
||||||
|
},
|
||||||
|
Dropdown: {
|
||||||
|
optionColorHover: '#e8f2ff',
|
||||||
|
},
|
||||||
|
Upload: {
|
||||||
|
draggerBorder: '1px dashed #1980FF',
|
||||||
|
draggerBorderHover: '1px dashed #1980FF',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<NConfigProvider :locale="zhCN" :date-locale="dateZhCN" :theme-overrides="getThemeOverrides">
|
||||||
|
<AppProvider>
|
||||||
|
<RouterView />
|
||||||
|
</AppProvider>
|
||||||
|
</NConfigProvider>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="less"></style>
|
@ -0,0 +1,298 @@
|
|||||||
|
import { http } from '@/utils/http/axios'
|
||||||
|
import type { PageParam } from '/#/api'
|
||||||
|
import { ContentTypeEnum } from '@/enums/httpEnum'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取地区列表
|
||||||
|
* @param params
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export async function getRegionList(params: PageParam = { pageNo: 1, pageSize: 10 }): Promise<any> {
|
||||||
|
const res = await http.request({
|
||||||
|
url: `/ocr/ocrarea/listall`,
|
||||||
|
method: 'get',
|
||||||
|
params,
|
||||||
|
})
|
||||||
|
|
||||||
|
const { data } = res
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取图片类型列表
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export async function getPictureTypeList(): Promise<any> {
|
||||||
|
const res = await http.request({
|
||||||
|
url: `/ocr/ocrPicturetype/rootList`,
|
||||||
|
method: 'get',
|
||||||
|
headers: { 'Content-Type': ContentTypeEnum.FORM_DATA },
|
||||||
|
})
|
||||||
|
|
||||||
|
const { data } = res
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取提报人列表
|
||||||
|
* @param params
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export async function getPersonList(params: PageParam = { pageNo: 1, pageSize: 10 }) {
|
||||||
|
const res = await http.request({
|
||||||
|
url: `/ocr/ocrUpuser/listall`,
|
||||||
|
method: 'get',
|
||||||
|
params,
|
||||||
|
})
|
||||||
|
|
||||||
|
const { data } = res
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取计划列表
|
||||||
|
* @param params
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export async function getPlanList(params: PageParam = { pageNo: 1, pageSize: 10 }) {
|
||||||
|
const res = await http.request({
|
||||||
|
url: `/ocr/ocrPlan/listall`,
|
||||||
|
method: 'get',
|
||||||
|
params,
|
||||||
|
})
|
||||||
|
|
||||||
|
const { data } = res
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取图片真假原因字典
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export async function getTFList() {
|
||||||
|
const res = await http.request({
|
||||||
|
url: `/static/admin/web/distionary/bytypecode/imagetrueorfalse`,
|
||||||
|
method: 'get',
|
||||||
|
})
|
||||||
|
|
||||||
|
const list = res.data[0].distionaryList
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取分类列表
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export async function getIzShowList(): Promise<any> {
|
||||||
|
const res = await http.request({
|
||||||
|
url: `/ocr/ocrPictureclass/rootList`,
|
||||||
|
method: 'get',
|
||||||
|
headers: { 'Content-Type': ContentTypeEnum.FORM_DATA },
|
||||||
|
})
|
||||||
|
|
||||||
|
const { data } = res
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取izsearch列表
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export async function getIzSearchList(): Promise<any> {
|
||||||
|
const res = await http.request({
|
||||||
|
url: `/ocr/ocrPictureclass/todo`,
|
||||||
|
method: 'get',
|
||||||
|
})
|
||||||
|
|
||||||
|
const { data } = res
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取izsearchmanager列表
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export async function getIzsSearchManager(): Promise<any> {
|
||||||
|
const res = await http.request({
|
||||||
|
url: `/ocr/ocrPictureclass/todo`,
|
||||||
|
method: 'get',
|
||||||
|
})
|
||||||
|
|
||||||
|
const { data } = res
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取izproject列表
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export async function getIzProjectList(): Promise<any> {
|
||||||
|
const res = await http.request({
|
||||||
|
url: `/ocr/ocrPictureclass/todo`,
|
||||||
|
method: 'get',
|
||||||
|
})
|
||||||
|
|
||||||
|
const { data } = res
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取izcustomtype列表
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export async function getIzCustomtypeList(): Promise<any> {
|
||||||
|
const res = await http.request({
|
||||||
|
url: `/ocr/ocrPictureclass/todo`,
|
||||||
|
method: 'get',
|
||||||
|
})
|
||||||
|
|
||||||
|
const { data } = res
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取任务来源
|
||||||
|
* @param enabled
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export async function getIztaskrromList(enabled: string) {
|
||||||
|
const res = await http.request({
|
||||||
|
url: `/static/admin/web/distionary/bytypecode/IZTASKRROM`,
|
||||||
|
method: 'get',
|
||||||
|
params: { enabled },
|
||||||
|
})
|
||||||
|
|
||||||
|
const list = res.data[0].distionaryList
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取任务状态
|
||||||
|
* @param enabled
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export async function getIztaskstatusList(enabled: string) {
|
||||||
|
const res = await http.request({
|
||||||
|
url: `/static/admin/web/distionary/bytypecode/IZTASKSTATUS`,
|
||||||
|
method: 'get',
|
||||||
|
params: { enabled },
|
||||||
|
})
|
||||||
|
|
||||||
|
const list = res.data[0].distionaryList
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取省份
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export async function getIzvisitproList(): Promise<any> {
|
||||||
|
const res = await http.request({
|
||||||
|
url: `/ocr/ocrPictureclass/todo`,
|
||||||
|
method: 'get',
|
||||||
|
})
|
||||||
|
|
||||||
|
const { data } = res
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取厂商
|
||||||
|
* @param enabled
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export async function getIzfirmList(enabled: string) {
|
||||||
|
const res = await http.request({
|
||||||
|
url: `/static/admin/web/distionary/bytypecode/IZFIRM`,
|
||||||
|
method: 'get',
|
||||||
|
params: { enabled },
|
||||||
|
})
|
||||||
|
|
||||||
|
const list = res.data[0].distionaryList
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取产品名称
|
||||||
|
* @param enabled
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export async function getIzproductnameList(enabled: string) {
|
||||||
|
const res = await http.request({
|
||||||
|
url: `/static/admin/web/distionary/bytypecode/IZPRODUCTNAME`,
|
||||||
|
method: 'get',
|
||||||
|
params: { enabled },
|
||||||
|
})
|
||||||
|
|
||||||
|
const list = res.data[0].distionaryList
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取客户类型
|
||||||
|
* @param enabled
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export async function getIzfiled2List(enabled: string) {
|
||||||
|
const res = await http.request({
|
||||||
|
url: `/static/admin/web/distionary/bytypecode/IZCUSTOMTYPE`,
|
||||||
|
method: 'get',
|
||||||
|
params: { enabled },
|
||||||
|
headers: { 'Content-Type': ContentTypeEnum.FORM_DATA },
|
||||||
|
})
|
||||||
|
|
||||||
|
debugger
|
||||||
|
const list = res.data[0].distionaryList
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取客户名称
|
||||||
|
* @param enabled
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export async function getIzfiled3List(enabled: string) {
|
||||||
|
const res = await http.request({
|
||||||
|
url: `/static/admin/web/distionary/bytypecode/IZCUSTOMNAME`,
|
||||||
|
method: 'get',
|
||||||
|
params: { enabled },
|
||||||
|
headers: { 'Content-Type': ContentTypeEnum.FORM_DATA },
|
||||||
|
})
|
||||||
|
|
||||||
|
const list = res.data[0].distionaryList
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取客户级别
|
||||||
|
* @param enabled
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export async function getIzfiled6List(enabled: string) {
|
||||||
|
const res = await http.request({
|
||||||
|
url: `/static/admin/web/distionary/bytypecode/IZCUSTOMLEVEL`,
|
||||||
|
method: 'get',
|
||||||
|
params: { enabled },
|
||||||
|
headers: { 'Content-Type': ContentTypeEnum.FORM_DATA },
|
||||||
|
})
|
||||||
|
|
||||||
|
const list = res.data[0].distionaryList
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取项目类别
|
||||||
|
* @param enabled
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export async function getIzfiled17List(enabled: string) {
|
||||||
|
const res = await http.request({
|
||||||
|
url: `/static/admin/web/distionary/bytypecode/IZPROJECTTYPE`,
|
||||||
|
method: 'get',
|
||||||
|
params: { enabled },
|
||||||
|
headers: { 'Content-Type': ContentTypeEnum.FORM_DATA },
|
||||||
|
})
|
||||||
|
|
||||||
|
const list = res.data[0].distionaryList
|
||||||
|
return list
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
import type { FinalParam, ResetParam } from '/#/api'
|
||||||
|
import { http } from '@/utils/http/axios'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取审核列表
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export async function getFinalList(params: FinalParam) {
|
||||||
|
const res = await http.request({
|
||||||
|
url: `/flow/task/listfinal`,
|
||||||
|
method: 'get',
|
||||||
|
params,
|
||||||
|
})
|
||||||
|
|
||||||
|
const { data: { list, totalPage } } = res
|
||||||
|
return {
|
||||||
|
pageCount: totalPage,
|
||||||
|
data: list,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重置审批
|
||||||
|
* @param params
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export async function resetApproval(params: ResetParam) {
|
||||||
|
return http.request({
|
||||||
|
url: `/flow/task/removeTask`,
|
||||||
|
method: 'get',
|
||||||
|
params,
|
||||||
|
})
|
||||||
|
}
|
@ -0,0 +1,123 @@
|
|||||||
|
import { http } from '@/utils/http/axios'
|
||||||
|
import type { FilterCondition, FilterParam, FilterSearchParam, FilterUpdate, PageParam } from '/#/api'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取过滤条件列表
|
||||||
|
* @param params
|
||||||
|
* @returns 1
|
||||||
|
*/
|
||||||
|
export async function getConditionList(params: PageParam & FilterSearchParam): Promise<any> {
|
||||||
|
const res = await http.request({
|
||||||
|
url: `/ocr/ocrUsersearch/list`,
|
||||||
|
method: 'get',
|
||||||
|
params,
|
||||||
|
})
|
||||||
|
|
||||||
|
const { data: { records, pages } } = res
|
||||||
|
return {
|
||||||
|
pageCount: pages,
|
||||||
|
data: records,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加过滤条件
|
||||||
|
* @param params
|
||||||
|
*/
|
||||||
|
export async function addCondition(params: FilterCondition) {
|
||||||
|
return http.request({
|
||||||
|
url: `/ocr/ocrUsersearch/add`,
|
||||||
|
method: 'post',
|
||||||
|
params,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑过滤条件
|
||||||
|
* @param params
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export async function updateCondition(params: FilterUpdate) {
|
||||||
|
return http.request({
|
||||||
|
url: `/ocr/ocrUsersearch/edit`,
|
||||||
|
method: 'post',
|
||||||
|
params,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除过滤条件
|
||||||
|
* @param params
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export async function deleteCondition(params: { ids: string }) {
|
||||||
|
return http.request({
|
||||||
|
url: `/ocr/ocrUsersearch/deleteBatch`,
|
||||||
|
method: 'delete',
|
||||||
|
params,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取设置为显示的筛选
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export async function getFilter(): Promise<any> {
|
||||||
|
return http.request({
|
||||||
|
url: `/ocr/ocrSearchmanager/query`,
|
||||||
|
method: 'get',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置筛选
|
||||||
|
* @param params
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export async function setFilter(params: FilterParam): Promise<void> {
|
||||||
|
return http.request({
|
||||||
|
url: `/ocr/ocrSearchmanager/add`,
|
||||||
|
method: 'post',
|
||||||
|
params,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 收藏
|
||||||
|
* @param params
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export async function favorite(searchid: string): Promise<void> {
|
||||||
|
return http.request({
|
||||||
|
url: `/ocr/ocrUsersearch/collect`,
|
||||||
|
method: 'get',
|
||||||
|
params: { searchid },
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取消收藏
|
||||||
|
* @param params
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export async function unfavorite(searchid: string): Promise<void> {
|
||||||
|
return http.request({
|
||||||
|
url: `/ocr/ocrUsersearch/collectreset`,
|
||||||
|
method: 'get',
|
||||||
|
params: { searchid },
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param searchid 拖拽的id
|
||||||
|
* @param reorder 拖拽后的排序
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export async function sort(searchid: string, reorder: number): Promise<void> {
|
||||||
|
return http.request({
|
||||||
|
url: `/ocr/ocrUsersearch/reorder`,
|
||||||
|
method: 'get',
|
||||||
|
params: { searchid, reorder },
|
||||||
|
})
|
||||||
|
}
|
@ -0,0 +1,98 @@
|
|||||||
|
import { http } from '@/utils/http/axios'
|
||||||
|
import type { CheckParam, PageParam, QueryPictureParam, UploadParam } from '/#/api'
|
||||||
|
import { ContentTypeEnum } from '@/enums/httpEnum'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取查重列表
|
||||||
|
* @param params
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export async function getDeduplicationList(params: PageParam & QueryPictureParam): Promise<any> {
|
||||||
|
const res = await http.request({
|
||||||
|
url: `/ocr/ocrPicture/list`,
|
||||||
|
method: 'get',
|
||||||
|
params,
|
||||||
|
})
|
||||||
|
|
||||||
|
const { data: { records } } = res
|
||||||
|
return {
|
||||||
|
data: records,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传图片
|
||||||
|
* @param params
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export async function upload(params: UploadParam): Promise<{ data: string }> {
|
||||||
|
return http.request({
|
||||||
|
url: `/ocr/ocrPackagetask/upload`,
|
||||||
|
method: 'post',
|
||||||
|
params,
|
||||||
|
headers: { 'Content-Type': ContentTypeEnum.FORM_DATA },
|
||||||
|
})
|
||||||
|
|
||||||
|
// return new Promise((r, e) => {
|
||||||
|
// r({ url: 'https://picx.zhimg.com/70/v2-615f0ca70562a95edff5b10b393c18e4_1440w.avis?source=172ae18b&biz_tag=Post' })
|
||||||
|
// })
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询个人笔记
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export async function queryNote() {
|
||||||
|
return http.request({
|
||||||
|
url: `/ocr/ocrBooknote/query`,
|
||||||
|
method: 'get',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存个人笔记
|
||||||
|
* @param note
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export async function saveNote(note: string) {
|
||||||
|
return http.request({
|
||||||
|
url: `/ocr/ocrBooknote/add`,
|
||||||
|
method: 'post',
|
||||||
|
params: { notecontent: note },
|
||||||
|
headers: { 'Content-Type': ContentTypeEnum.FORM_DATA },
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 一键查重
|
||||||
|
* @param note
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export async function oneClickCheck(params: Partial<CheckParam> = { search_history: '0' }) {
|
||||||
|
return http.request({
|
||||||
|
url: `/ocr/ocrPicture/createorder`,
|
||||||
|
method: 'get',
|
||||||
|
params,
|
||||||
|
headers: { 'Content-Type': ContentTypeEnum.FORM_DATA },
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取图片列表
|
||||||
|
* @param params
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export async function getPictureList(params: any): Promise<any> {
|
||||||
|
const res = await http.request({
|
||||||
|
url: `/ocr/ocrPicture/list`,
|
||||||
|
method: 'get',
|
||||||
|
params,
|
||||||
|
headers: { 'Content-Type': ContentTypeEnum.FORM_DATA },
|
||||||
|
})
|
||||||
|
|
||||||
|
const { data: { records, pages } } = res
|
||||||
|
return {
|
||||||
|
pageCount: pages,
|
||||||
|
data: records,
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
import { http } from '@/utils/http/axios'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: 根据用户id获取用户菜单
|
||||||
|
*/
|
||||||
|
export function adminMenus() {
|
||||||
|
return http.request({
|
||||||
|
url: '/menus',
|
||||||
|
method: 'GET',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取tree菜单列表
|
||||||
|
* @param params
|
||||||
|
*/
|
||||||
|
export function getMenuList(params?) {
|
||||||
|
return http.request({
|
||||||
|
url: '/menu/list',
|
||||||
|
method: 'GET',
|
||||||
|
params,
|
||||||
|
})
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
import { http } from '@/utils/http/axios'
|
||||||
|
import type { ApprovalParam, PageParam } from '/#/api'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取审核列表
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export async function getApprovalList(params: PageParam, assigneeId: string) {
|
||||||
|
const res = await http.request({
|
||||||
|
url: `/flow/task/listdata`,
|
||||||
|
method: 'get',
|
||||||
|
params,
|
||||||
|
})
|
||||||
|
|
||||||
|
const { data: { list, totalPage } } = res
|
||||||
|
return {
|
||||||
|
pageCount: totalPage,
|
||||||
|
data: list,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 审核
|
||||||
|
* @param param
|
||||||
|
*/
|
||||||
|
export async function approval(params: ApprovalParam) {
|
||||||
|
return http.request({
|
||||||
|
url: `/flow/task/completeFlow`,
|
||||||
|
method: 'post',
|
||||||
|
params,
|
||||||
|
})
|
||||||
|
}
|
@ -0,0 +1,115 @@
|
|||||||
|
import { http } from '@/utils/http/axios'
|
||||||
|
import type { PageParam, PictureSortParam, SetTFParam } from '/#/api'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取任务包列表
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export async function getPackageList(params: PageParam) {
|
||||||
|
const res = await http.request({
|
||||||
|
url: `/ocr/ocrPackagetask/list`,
|
||||||
|
method: 'get',
|
||||||
|
params,
|
||||||
|
})
|
||||||
|
|
||||||
|
const { data: { records, pages } } = res
|
||||||
|
return {
|
||||||
|
pageCount: pages,
|
||||||
|
data: records,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取某个任务包内任务列表
|
||||||
|
* @param id 任务包id
|
||||||
|
* @param params
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export async function getPackageTaskList(packageid: string, params: PageParam) {
|
||||||
|
const res = await http.request({
|
||||||
|
url: `/backstage/jifen/ocrtaskchildpicture/listbypackageid/${packageid}`,
|
||||||
|
method: 'get',
|
||||||
|
params,
|
||||||
|
})
|
||||||
|
|
||||||
|
const { data: { records, pages } } = res
|
||||||
|
return {
|
||||||
|
pageCount: pages,
|
||||||
|
data: records,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取某个任务详情(字段信息)
|
||||||
|
* @param id 任务id
|
||||||
|
* @param packageid 任务包id
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export async function getTaskDetailInfo(taskId: string, packageid: string) {
|
||||||
|
const res = await http.request({
|
||||||
|
url: `/backstage/jifen/ocrtaskchildpicture/getdata/${taskId}/${packageid}`,
|
||||||
|
method: 'get',
|
||||||
|
})
|
||||||
|
|
||||||
|
return res.data
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取某个任务详情(相似图片列表)
|
||||||
|
* @param packageid 任务包id
|
||||||
|
* @param taskchildpictureid 任务详情的id
|
||||||
|
* @param params
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export async function getTaskDetailPictureList(packageid: string, taskchildpictureid: string, params: PageParam & PictureSortParam) {
|
||||||
|
const res = await http.request({
|
||||||
|
url: `/backstage/jifen/ocrtaskchildpicture/listbypictureid/${packageid}/${taskchildpictureid}`,
|
||||||
|
method: 'get',
|
||||||
|
params,
|
||||||
|
})
|
||||||
|
|
||||||
|
const { data: { records, pages } } = res
|
||||||
|
return {
|
||||||
|
pageCount: pages,
|
||||||
|
data: records,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置真假
|
||||||
|
* @param params
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export async function setTF(params: SetTFParam) {
|
||||||
|
return await http.request({
|
||||||
|
url: `/ocr/ocrPackagetask/ordertrueorfalse`,
|
||||||
|
method: 'post',
|
||||||
|
params,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清除之前标记的真假
|
||||||
|
* @param id
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export async function clearTF(id: string): Promise<any> {
|
||||||
|
return await http.request({
|
||||||
|
url: `/ocr/ocrPackagetask/listorderbytask`,
|
||||||
|
method: 'get',
|
||||||
|
params: { packageid: id },
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将任务包内的任务按相似度排序
|
||||||
|
* @param id
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export async function sort(id: string): Promise<any> {
|
||||||
|
return await http.request({
|
||||||
|
url: `/ocr/ocrPackagetask/listorderbytask`,
|
||||||
|
method: 'get',
|
||||||
|
params: { packageid: id },
|
||||||
|
})
|
||||||
|
}
|
After Width: | Height: | Size: 7.6 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 6.7 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 483 KiB |
After Width: | Height: | Size: 483 KiB |
After Width: | Height: | Size: 668 KiB |
After Width: | Height: | Size: 7.2 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 4.5 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 3.2 KiB |
After Width: | Height: | Size: 4.1 KiB |
After Width: | Height: | Size: 5.2 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 227 KiB |
After Width: | Height: | Size: 3.7 KiB |
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 356 B |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 966 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 7.0 KiB |
After Width: | Height: | Size: 844 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 3.9 KiB |
After Width: | Height: | Size: 208 KiB |
After Width: | Height: | Size: 6.7 KiB |
After Width: | Height: | Size: 3.0 KiB |