Commit c8d09a08 authored by 罗超's avatar 罗超

初始化

parent 2b9c0db1
Pipeline #143 failed with stages
...@@ -3,5 +3,6 @@ ...@@ -3,5 +3,6 @@
"vetur.format.enable": false, "vetur.format.enable": false,
"eslint.validate": ["javascript", "javascriptreact", "typescript", "vue"], "eslint.validate": ["javascript", "javascriptreact", "typescript", "vue"],
"typescript.tsdk": "node_modules/typescript/lib", "typescript.tsdk": "node_modules/typescript/lib",
"vetur.experimental.templateInterpolationService": true "vetur.experimental.templateInterpolationService": true,
"vue-i18n.i18nPaths": "src/i18n"
} }
<!DOCTYPE html>
<html>
<head>
<title><%= productName %></title>
<meta charset="utf-8">
<meta name="description" content="<%= productDescription %>">
<meta name="format-detection" content="telephone=no">
<meta name="msapplication-tap-highlight" content="no">
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width<% if (ctx.mode.cordova || ctx.mode.capacitor) { %>, viewport-fit=cover<% } %>">
<link rel="icon" type="image/png" sizes="128x128" href="icons/favicon-128x128.png">
<link rel="icon" type="image/png" sizes="96x96" href="icons/favicon-96x96.png">
<link rel="icon" type="image/png" sizes="32x32" href="icons/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="icons/favicon-16x16.png">
<link rel="icon" type="image/ico" href="favicon.ico">
</head>
<body>
<!-- quasar:entry-point -->
</body>
</html>
{ {
"name": "ocss", "name": "bigwood",
"version": "0.0.1", "version": "0.0.1",
"description": "niuu bee", "description": "JVS 同業訂房網",
"productName": "Ocss App", "productName": "JVS 同業訂房網",
"author": "alex9012 <alex9012@vip.qq.com>", "author": "alex9012 <alex9012@vip.qq.com>",
"private": true, "private": true,
"scripts": { "scripts": {
"lint": "eslint --ext .js,.ts,.vue ./", "lint": "eslint --ext .js,.ts,.vue ./",
"format": "prettier --write \"**/*.{js,ts,vue,scss,html,md,json}\" --ignore-path .gitignore",
"test": "echo \"No test specified\" && exit 0" "test": "echo \"No test specified\" && exit 0"
}, },
"dependencies": { "dependencies": {
"@quasar/extras": "^1.0.0", "@quasar/extras": "^1.15.5",
"@types/lockr": "^0.8.7", "@types/lockr": "^0.8.7",
"@types/lodash": "^4.14.175", "@types/lodash": "^4.14.175",
"@types/webpack-env": "^1.16.2", "@types/webpack-env": "^1.16.2",
"axios": "^0.21.1", "axios": "^0.21.1",
"core-js": "^3.6.5", "core-js": "^3.6.5",
"js-md5": "^0.7.3",
"katex": "^0.13.18", "katex": "^0.13.18",
"lockr": "^0.9.0-beta.0", "lockr": "^0.9.0-beta.0",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"md5-ts": "^0.1.6",
"mermaid": "^8.12.1", "mermaid": "^8.12.1",
"quasar": "^2.0.0", "quasar": "^2.10.0",
"quasar-tiptap-branch": "^1.8.1", "quasar-tiptap-branch": "^1.8.1",
"vue": "^3.0.0",
"vue-i18n": "^9.0.0", "vue-i18n": "^9.0.0",
"vue-inline-svg": "^2.1.1",
"vue-router": "^4.0.0",
"vuex": "^4.0.1", "vuex": "^4.0.1",
"vuex-persistedstate": "^4.1.0" "vuex-persistedstate": "^4.1.0"
}, },
"devDependencies": { "devDependencies": {
"@babel/eslint-parser": "^7.13.14", "@typescript-eslint/eslint-plugin": "^5.10.0",
"@quasar/app": "^3.0.0", "@typescript-eslint/parser": "^5.10.0",
"eslint": "^8.10.0",
"eslint-plugin-vue": "^9.0.0",
"eslint-config-prettier": "^8.1.0",
"prettier": "^2.5.1",
"@types/node": "^12.20.21", "@types/node": "^12.20.21",
"@types/webpack-env": "^1.16.2", "@intlify/vite-plugin-vue-i18n": "^3.3.1",
"@typescript-eslint/eslint-plugin": "^4.31.1", "@quasar/app-vite": "^1.0.0",
"@typescript-eslint/parser": "^4.31.1", "autoprefixer": "^10.4.2",
"@vue/eslint-config-typescript": "^7.0.0", "typescript": "^4.5.4"
"eslint": "^7.32.0",
"eslint-plugin-vue": "^7.0.0"
}, },
"browserslist": [ "browserslist": [
"last 10 Chrome versions", "last 10 Chrome versions",
...@@ -49,7 +57,7 @@ ...@@ -49,7 +57,7 @@
"last 5 Opera versions" "last 5 Opera versions"
], ],
"engines": { "engines": {
"node": ">= 12.22.1", "node": "^18 || ^16 || ^14.19",
"npm": ">= 6.13.4", "npm": ">= 6.13.4",
"yarn": ">= 1.21.1" "yarn": ">= 1.21.1"
} }
......
...@@ -51,7 +51,10 @@ module.exports = configure(function (ctx) { ...@@ -51,7 +51,10 @@ module.exports = configure(function (ctx) {
// Full list of options: https://v2.quasar.dev/quasar-cli/quasar-conf-js#Property%3A-build // Full list of options: https://v2.quasar.dev/quasar-cli/quasar-conf-js#Property%3A-build
build: { build: {
vueRouterMode: 'history', // available values: 'hash', 'history' vueRouterMode: 'history', // available values: 'hash', 'history'
target: {
browser: [ 'es2019', 'edge88', 'firefox78', 'chrome87', 'safari13.1' ],
node: 'node16'
},
// transpile: false, // transpile: false,
// Add dependencies for transpiling with Babel (Array of string/regex) // Add dependencies for transpiling with Babel (Array of string/regex)
...@@ -61,19 +64,33 @@ module.exports = configure(function (ctx) { ...@@ -61,19 +64,33 @@ module.exports = configure(function (ctx) {
env: ctx.dev env: ctx.dev
? { ? {
BASE_APP_API: 'http://192.168.20.51:8088/api' BASE_APP_API: 'http://192.168.10.206:8015/api/common/post'
} }
: { : {
BASE_APP_API: 'https://eduapi.oytour.com/api' BASE_APP_API: 'https://reborn.oytour.com/api/common/post'
}, },
extendWebpack(cfg, { isServer, isClient }) { // extendWebpack(cfg, { isServer, isClient }) {
cfg.resolve.alias = { // cfg.resolve.alias = {
...cfg.resolve.alias, // ...cfg.resolve.alias,
'@': path.resolve(__dirname, './src') // '@': path.resolve(__dirname, './src')
} // }
}, // },
vitePlugins: [
[
'@intlify/vite-plugin-vue-i18n',
{
// if you want to use Vue I18n Legacy API, you need to set `compositionOnly: false`
// compositionOnly: false,
// you need to set i18n resource including paths !
include: path.resolve(__dirname, './src/i18n/**'),
},
],
],
// alias:[{
// '@': path.resolve(__dirname, './src')
// }],
// rtl: true, // https://v2.quasar.dev/options/rtl-support // rtl: true, // https://v2.quasar.dev/options/rtl-support
// preloadChunks: true, // preloadChunks: true,
// showProgress: false, // showProgress: false,
...@@ -85,9 +102,9 @@ module.exports = configure(function (ctx) { ...@@ -85,9 +102,9 @@ module.exports = configure(function (ctx) {
// https://v2.quasar.dev/quasar-cli/handling-webpack // https://v2.quasar.dev/quasar-cli/handling-webpack
// "chain" is a webpack-chain object https://github.com/neutrinojs/webpack-chain // "chain" is a webpack-chain object https://github.com/neutrinojs/webpack-chain
chainWebpack(/* chain */) { // chainWebpack(/* chain */) {
// // //
} // }
}, },
// Full list of options: https://v2.quasar.dev/quasar-cli/quasar-conf-js#Property%3A-devServer // Full list of options: https://v2.quasar.dev/quasar-cli/quasar-conf-js#Property%3A-devServer
...@@ -144,74 +161,91 @@ module.exports = configure(function (ctx) { ...@@ -144,74 +161,91 @@ module.exports = configure(function (ctx) {
// https://v2.quasar.dev/quasar-cli/developing-pwa/configuring-pwa // https://v2.quasar.dev/quasar-cli/developing-pwa/configuring-pwa
pwa: { pwa: {
workboxPluginMode: 'GenerateSW', // 'GenerateSW' or 'InjectManifest' // workboxPluginMode: 'generateSW', // 'GenerateSW' or 'InjectManifest'
workboxOptions: {}, // only for GenerateSW // workboxOptions: {}, // only for GenerateSW
// for the custom service worker ONLY (/src-pwa/custom-service-worker.[js|ts]) // // for the custom service worker ONLY (/src-pwa/custom-service-worker.[js|ts])
// if using workbox in InjectManifest mode // // if using workbox in InjectManifest mode
chainWebpackCustomSW(/* chain */) { // chainWebpackCustomSW(/* chain */) {
// // //
}, // },
manifest: { // manifest: {
name: 'Ocss App', // name: 'Ocss App',
short_name: 'Ocss App', // short_name: 'Ocss App',
description: 'niuu bee', // description: 'niuu bee',
display: 'standalone', // display: 'standalone',
orientation: 'portrait', // orientation: 'portrait',
background_color: '#ffffff', // background_color: '#ffffff',
theme_color: '#027be3', // theme_color: '#027be3',
icons: [ // icons: [
{ // {
src: 'icons/icon-128x128.png', // src: 'icons/icon-128x128.png',
sizes: '128x128', // sizes: '128x128',
type: 'image/png' // type: 'image/png'
}, // },
{ // {
src: 'icons/icon-192x192.png', // src: 'icons/icon-192x192.png',
sizes: '192x192', // sizes: '192x192',
type: 'image/png' // type: 'image/png'
}, // },
{ // {
src: 'icons/icon-256x256.png', // src: 'icons/icon-256x256.png',
sizes: '256x256', // sizes: '256x256',
type: 'image/png' // type: 'image/png'
}, // },
{ // {
src: 'icons/icon-384x384.png', // src: 'icons/icon-384x384.png',
sizes: '384x384', // sizes: '384x384',
type: 'image/png' // type: 'image/png'
}, // },
{ // {
src: 'icons/icon-512x512.png', // src: 'icons/icon-512x512.png',
sizes: '512x512', // sizes: '512x512',
type: 'image/png' // type: 'image/png'
} // }
] // ]
} // }
workboxMode: 'generateSW', // or 'injectManifest'
injectPwaMetaTags: true,
swFilename: 'sw.js',
manifestFilename: 'manifest.json',
useCredentialsForManifestTag: false,
// useFilenameHashes: true,
// extendGenerateSWOptions (cfg) {}
// extendInjectManifestOptions (cfg) {},
// extendManifestJson (json) {}
// extendPWACustomSWConf (esbuildConf) {}
}, },
// Full list of options: https://v2.quasar.dev/quasar-cli/developing-cordova-apps/configuring-cordova // Full list of options: https://v2.quasar.dev/quasar-cli-vite/developing-cordova-apps/configuring-cordova
cordova: { cordova: {
// noIosLegacyBuildFlag: true, // uncomment only if you know what you are doing // noIosLegacyBuildFlag: true, // uncomment only if you know what you are doing
}, },
// Full list of options: https://v2.quasar.dev/quasar-cli/developing-capacitor-apps/configuring-capacitor // Full list of options: https://v2.quasar.dev/quasar-cli-vite/developing-capacitor-apps/configuring-capacitor
capacitor: { capacitor: {
hideSplashscreen: true hideSplashscreen: true
}, },
// Full list of options: https://v2.quasar.dev/quasar-cli/developing-electron-apps/configuring-electron // Full list of options: https://v2.quasar.dev/quasar-cli-vite/developing-electron-apps/configuring-electron
electron: { electron: {
// extendElectronMainConf (esbuildConf)
// extendElectronPreloadConf (esbuildConf)
inspectPort: 5858,
bundler: 'packager', // 'packager' or 'builder' bundler: 'packager', // 'packager' or 'builder'
packager: { packager: {
// https://github.com/electron-userland/electron-packager/blob/master/docs/api.md#options // https://github.com/electron-userland/electron-packager/blob/master/docs/api.md#options
// OS X / Mac App Store // OS X / Mac App Store
// appBundleId: '', // appBundleId: '',
// appCategoryType: '', // appCategoryType: '',
// osxSign: '', // osxSign: '',
// protocol: 'myapp://path', // protocol: 'myapp://path',
// Windows only // Windows only
// win32metadata: { ... } // win32metadata: { ... }
}, },
...@@ -219,20 +253,18 @@ module.exports = configure(function (ctx) { ...@@ -219,20 +253,18 @@ module.exports = configure(function (ctx) {
builder: { builder: {
// https://www.electron.build/configuration/configuration // https://www.electron.build/configuration/configuration
appId: 'ocss' appId: 'bigwood'
}, }
},
// "chain" is a webpack-chain object https://github.com/neutrinojs/webpack-chain // Full list of options: https://v2.quasar.dev/quasar-cli-vite/developing-browser-extensions/configuring-bex
chainWebpack(/* chain */) { bex: {
// do something with the Electron main process Webpack cfg contentScripts: [
// extendWebpackMain also available besides this chainWebpackMain 'JVS'
}, ],
// "chain" is a webpack-chain object https://github.com/neutrinojs/webpack-chain // extendBexScriptsConf (esbuildConf) {}
chainWebpackPreload(/* chain */) { // extendBexManifestJson (json) {}
// do something with the Electron main process Webpack cfg
// extendWebpackPreload also available besides this chainWebpackPreload
}
} }
} }
}) })
...@@ -9,6 +9,10 @@ export enum RoleType { ...@@ -9,6 +9,10 @@ export enum RoleType {
'项目成员', '项目成员',
'项目访客' '项目访客'
} }
export enum ApiResult{
'SUCCESS' = 1,
'FAILED' = 0
}
/** /**
* @description 常用异常结果常量定义 * @description 常用异常结果常量定义
*/ */
......
import { AppStateType } from '@/store/modules/app/state'
import { UserStateType } from '@/store/modules/user/state' import { AppStateType } from '../store/modules/app/state'
import { TeamStateType } from '@/store/modules/user/modules/team/state' import { UserStateType } from '../store/modules/user/state'
import { TeamStateType } from '../store/modules/user/modules/team/state'
import { RoleType } from './enumHelper' import { RoleType } from './enumHelper'
// vuex state 的模块的类型 // vuex state 的模块的类型
...@@ -75,8 +76,9 @@ export interface HttpResponse { ...@@ -75,8 +76,9 @@ export interface HttpResponse {
status: number status: number
statusText: string statusText: string
data: { data: {
code: number resultCode: number
desc: string message: string
data: any
[key: string]: any [key: string]: any
} }
} }
...@@ -115,6 +117,12 @@ export interface TeamMemberType { ...@@ -115,6 +117,12 @@ export interface TeamMemberType {
cloudRole?: string cloudRole?: string
} }
export interface SitLang{
langName?:string,
langLocale?:string,
langIcon?:string
}
// 权限列表类型 // 权限列表类型
export interface RoleItemType { export interface RoleItemType {
......
<template> <template>
<router-view /> <router-view />
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue' import { defineComponent } from 'vue';
export default defineComponent({ export default defineComponent({
name: 'App' name: 'App'
}) });
</script> </script>
<style lang="sass"> <style lang="sass">
@import url('./css/font.sass') @import url('./css/font.sass')
@import url('//at.alicdn.com/t/c/font_3734871_9agx0gqqibi.css')
</style> </style>
import Axios, { AxiosResponse, AxiosRequestConfig, AxiosError } from 'axios' import Axios, { AxiosResponse, AxiosRequestConfig, AxiosError } from 'axios'
import router from '@/router/index' import router from '../router/index'
// import { message } from 'ant-design-vue' // import { message } from 'ant-design-vue'
import Store from '@/store' import Store from '../store'
import { Notify } from 'quasar' import { Notify } from 'quasar'
/** /**
...@@ -68,30 +68,33 @@ const service = Axios.create({ ...@@ -68,30 +68,33 @@ const service = Axios.create({
} }
}) })
/** /**
* @description 请求发起前的拦截器 * @description 请求发起前的拦截器
* @returns {AxiosRequestConfig} config * @returns {AxiosRequestConfig} config
*/ */
service.interceptors.request.use( service.interceptors.request.use(
async (config: AxiosRequestConfig) => { async (config: AxiosRequestConfig) => {
// 如果是获取token接口: // 如果是获取token接口:
if (config.url === '/auth/oauth/token') { // if (config.url === '/auth/oauth/token') {
//TODO:用户登录的特殊处理, // //TODO:用户登录的特殊处理,
} else { // } else {
// 如果保存有token,则取,否则不添加Authorization // // 如果保存有token,则取,否则不添加Authorization
if (localStorage.vuex && JSON.parse(localStorage.vuex).user?.token) { // if (localStorage.vuex && JSON.parse(localStorage.vuex).user?.token) {
//TODO:Access_TOKEN 的获取,需要根据实际业务情况进行调整 // //TODO:Access_TOKEN 的获取,需要根据实际业务情况进行调整
const token = Store.state.user?.token // const token = Store.state.user?.token
const tokenType = token.token_type // const tokenType = token.token_type
const accessToken = token.access_token // const accessToken = token.access_token
config.headers.Authorization = `${tokenType} ${accessToken}` // config.headers.Authorization = `${tokenType} ${accessToken}`
} // }
//TODO:包装一层MSG,但是微服务应该去掉此步骤 // //TODO:包装一层MSG,但是微服务应该去掉此步骤
config.data = { // config.data = {
Msg: config.data // Msg: config.data
} // }
} // }
return config return config
}, },
......
import Axios from './axios' import Axios from './axios'
import { HttpResponse } from '@/@types/index' import { HttpResponse } from '../@types/index'
/** /**
* @description 公共模块的的网络请求,所有通用 api 放在此处 * @description 公共模块的的网络请求,所有通用 api 放在此处
......
import service from "./axios";
import Store from '../store'
import md5 from "md5-ts";
import { HttpResponse } from "@/@types";
const request = (cmd:string,msg:any): Promise<HttpResponse>=>{
msg = msg??{}
let token = "";
let key = "";
let timestamp = (new Date()).valueOf();
if (localStorage.vuex && JSON.parse(localStorage.vuex).user?.token) {
token = Store.state.user?.token?.access_token
key = Store.state.user?.secretKey
}
var encodeMsg = encodeURIComponent(JSON.stringify(msg)).toLowerCase();
var md5Str = md5(`cmd=${cmd}&msg=${encodeMsg}&timestamp=${timestamp}&token=${token}&key=${key}`);
var postData = {
"msg": msg,
"cmd": cmd,
"timestamp": timestamp,
"token": token,
"sign": md5Str,
"languageId": 0
}
return service.post('', postData)
}
export default request;
\ No newline at end of file
...@@ -2,8 +2,9 @@ ...@@ -2,8 +2,9 @@
* 所有跟用户相关的接口(TODO:DEMO USER) * 所有跟用户相关的接口(TODO:DEMO USER)
*/ */
import { HttpResponse } from '@/@types' import { HttpResponse } from '../@types'
import Axios from './axios' import Axios from './axios'
import request from './request'
interface HttpParams { interface HttpParams {
coinName: string coinName: string
...@@ -12,14 +13,14 @@ interface HttpParams { ...@@ -12,14 +13,14 @@ interface HttpParams {
/** /**
* @interface loginParams -登录参数 * @interface loginParams -登录参数
* @property {string} grant_type -授权类型 * @property {string} account -账号
* @property {string} email -邮箱 * @property {string} password -密码
* @property {string} password -用户密码 * @property {string} platform -登陆平台(默认为0)
*/ */
interface LoginParams { interface LoginParams {
grant_type: string account: string
username: string
password: string password: string
platform: number
} }
/** /**
...@@ -88,14 +89,15 @@ export interface UserApi { ...@@ -88,14 +89,15 @@ export interface UserApi {
*/ */
class UserService { class UserService {
//#region 测试方法
// 登录 // 登录
static async login(params: LoginParams): Promise<HttpResponse> { // static async login(params: LoginParams): Promise<HttpResponse> {
return Axios('/auth/oauth/token', { // return Axios('/auth/oauth/token', {
method: 'post', // method: 'post',
responseType: 'json', // responseType: 'json',
params: params // params: params
}) // })
} // }
// 刷新令牌 // 刷新令牌
static async refreshToken(params: RefreshTokenParams): Promise<HttpResponse> { static async refreshToken(params: RefreshTokenParams): Promise<HttpResponse> {
...@@ -169,6 +171,11 @@ class UserService { ...@@ -169,6 +171,11 @@ class UserService {
data: params data: params
}) })
} }
//#endregion
static async login(params:any): Promise<HttpResponse> {
console.log(params)
return request("b2b_post_Login",params);
}
} }
export default UserService export default UserService
import { userDictionmary } from '@/config/dictionary' import { userDictionmary } from '../config/dictionary'
import { boot } from 'quasar/wrappers' import { boot } from 'quasar/wrappers'
export default boot(({ app }) => { export default boot(({ app }) => {
......
import { registeGlobalComponent } from '@/components' import { registeGlobalComponent } from '../components'
import { boot } from 'quasar/wrappers' import { boot } from 'quasar/wrappers'
export default boot(({ app }) => { export default boot(({ app }) => {
......
import { boot } from 'quasar/wrappers' // import { boot } from 'quasar/wrappers'
import { createI18n } from 'vue-i18n' // import { createI18n } from 'vue-i18n'
import messages from 'src/i18n' // import messages from 'src/i18n'
const i18n = createI18n({ // const i18n = createI18n({
locale: 'en-US', // locale: localStorage.getItem("lanuage")??'zh-TW',
messages // messages
}) // })
// export default boot(({ app }) => {
// // Set i18n instance on app
// app.use(i18n)
// })
// export { i18n }
import { boot } from 'quasar/wrappers';
import { createI18n } from 'vue-i18n';
import messages from 'src/i18n';
export type MessageLanguages = keyof typeof messages;
// Type-define 'en-US' as the master schema for the resource
export type MessageSchema = typeof messages['en-US'];
// See https://vue-i18n.intlify.dev/guide/advanced/typescript.html#global-resource-schema-type-definition
/* eslint-disable @typescript-eslint/no-empty-interface */
declare module 'vue-i18n' {
// define the locale messages schema
export interface DefineLocaleMessage extends MessageSchema {}
// define the datetime format schema
export interface DefineDateTimeFormat {}
// define the number format schema
export interface DefineNumberFormat {}
}
/* eslint-enable @typescript-eslint/no-empty-interface */
const i18n = createI18n({
locale: localStorage.getItem("lanuage")??'zh-TW',
legacy: false,
globalInjection:true,
messages,
});
export default boot(({ app }) => { export default boot(({ app }) => {
// Set i18n instance on app
app.use(i18n)
})
export { i18n } // Set i18n instance on app
app.use(i18n);
});
export { i18n }
\ No newline at end of file
import { AuthMenuType } from '@/@types' import { AuthMenuType } from '../@types'
import { ResultType } from '@/@types/enumHelper' import { ResultType } from '../@types/enumHelper'
import router from '@/router/index' import router from '../router/index'
import { getAuth, getUserAllMenu } from '@/utils/auth' import { getAuth, getUserAllMenu } from '../utils/auth'
import { LoadingBar } from 'quasar' import { LoadingBar } from 'quasar'
LoadingBar.setDefaults({ LoadingBar.setDefaults({
color: 'primary', color: 'primary',
...@@ -12,7 +12,7 @@ LoadingBar.setDefaults({ ...@@ -12,7 +12,7 @@ LoadingBar.setDefaults({
let loadAsyncRouter = false let loadAsyncRouter = false
const whiteList = ['/auth/login','/auth/regist'] const whiteList = ['/auth/login','/auth/regist','/auth/forget']
router.beforeEach((to, from, next) => { router.beforeEach((to, from, next) => {
localStorage.setItem('routerBefore', from.path) localStorage.setItem('routerBefore', from.path)
...@@ -72,6 +72,7 @@ router.beforeEach((to, from, next) => { ...@@ -72,6 +72,7 @@ router.beforeEach((to, from, next) => {
} }
} else { } else {
if (whiteList.indexOf(to.path) !== -1) { if (whiteList.indexOf(to.path) !== -1) {
console.log(whiteList,to.path)
next() next()
} else { } else {
next(`/auth/login?redirect=${decodeURIComponent(to.path)}`) // 否则全部重定向到登录页 next(`/auth/login?redirect=${decodeURIComponent(to.path)}`) // 否则全部重定向到登录页
......
<template> <template>
<span> <span>
<inline-svg :class="[`${color}`]" :src="require(`@/assets/svg/${icon}`)" :width="svgSize" :height="svgSize" :fill="svgColor" :stroke="svgColor" :title="tips" :aria-label="tips"></inline-svg> <inline-svg :class="[`${color}`]" :src="svgIcon" :width="svgSize" :height="svgSize" :fill="svgColor" :stroke="svgColor" :title="tips" :aria-label="tips"></inline-svg>
</span> </span>
</template> </template>
...@@ -42,7 +42,11 @@ export default { ...@@ -42,7 +42,11 @@ export default {
return tempColor.indexOf('#') != 0 ? `var(--q-${tempColor})` : tempColor return tempColor.indexOf('#') != 0 ? `var(--q-${tempColor})` : tempColor
}) })
return { svgSize, svgColor } const svgIcon = computed(() => {
return new URL(`../../assets/svg/${props.icon}`,import.meta.url).href
})
return { svgSize, svgColor,svgIcon }
} }
} }
</script> </script>
......
...@@ -7,9 +7,9 @@ import { kebabCase } from 'lodash' ...@@ -7,9 +7,9 @@ import { kebabCase } from 'lodash'
* @returns {void} void * @returns {void} void
*/ */
export function registeGlobalComponent(app: ReturnType<typeof createApp>): void { export function registeGlobalComponent(app: ReturnType<typeof createApp>): void {
const files = require.context('./global', true, /\.(vue|ts)$/) const files = import.meta.globEager("./global/*.(vue|ts)")//require.context('./global', true, /\.(vue|ts)$/)
files.keys().forEach(key => { Object.keys(files).forEach(key => {
const config = files(key) const config = files[key]
const name = kebabCase(key.replace(/^\.\//, '').replace(/\.\w+$/, '')) const name = kebabCase(key.replace(/^\.\//, '').replace(/\.\w+$/, ''))
app.component(name, config.default || config) app.component(name, config.default || config)
}) })
......
/** 跟应用全局相关的静态配置放在这里 */ /** 跟应用全局相关的静态配置放在这里 */
import { Notify } from 'quasar' import { Notify } from 'quasar'
import { i18n } from '../boot/i18n'
const AppConfig = { const AppConfig = {
$message: Notify $message: Notify
} }
const StaticConfig = { const StaticConfig = {
MaxPageSize: 1000, MaxPageSize: 1000,
appsuffix: '大水豚渠道管理系统' appsuffix: i18n.global.t("appsuffix")
} }
export { AppConfig, StaticConfig } export { AppConfig, StaticConfig }
// app global css in SCSS form // app global css in SCSS form
.q-px-xxl{
padding-left:5rem;
padding-right:5rem;
}
.q-py-xxl{
padding-top:5rem;
padding-bottom:5rem;
}
.q-pa-xxl{
padding:5rem;
}
.q-pl-xxl{
padding-left:5rem;
}
.q-pr-xxl{
padding-right:5rem;
}
.q-pt-xxl{
padding-top:5rem;
}
.q-pb-xxl{
padding-bottom:5rem;
}
#q-app{
height: 100vh;
}
\ No newline at end of file
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
.Poppins .Poppins
font-family: 'Poppins' font-family: 'Poppins'
body body
font-family: 'Poppins','Helvetica','sans-serif',pf font-family: 'Roboto', 'Arial','微軟正黑體修正', '微軟正黑體', "Microsoft JhengHei", 'sans-serif','pf'
color: var(--q-dark) color: var(--q-dark)
.no-underline .no-underline
text-decoration: none !important text-decoration: none !important
......
...@@ -25,9 +25,9 @@ ...@@ -25,9 +25,9 @@
// src/css/quasar.variables.scss // src/css/quasar.variables.scss
$primary: #04c8c8; $primary: #009ef7;
$secondary: #e4e6ef; $secondary: #e4e6ef;
$accent: #009ef7; $accent: #04c8c8;
$dark: #181c32; $dark: #181c32;
......
import enUS from './en-US' import enUS from './en-US'
import zhTW from './zh-TW'
export default { export default {
'en-US': enUS 'en-US': enUS,
'zh-TW': zhTW
} }
// This is just an example,
// so you can safely delete all default props below
export default {
failed: '執行失敗',
success: '執行成功',
appsuffix: "JVS同業預定系統",
lanuage:"系統語言",
login:{
notaccess:"沒有同業會員帳戶?",
registlink:"申請註冊",
title:"登入",
subTitle:"歡迎您的到來,開啟急速採購",
account:"帳戶(EMail)",
password:"密碼",
forgot:"忘記密碼?",
signin:"登入",
pageTitle:"登入",
ruleTipsAccount:"請填寫正確的郵箱帳號",
ruleTipsPwd:"請填寫密碼",
formTips:"請填寫登陸信息"
},
forget:{
pageTitle:"忘记密码",
title:"忘記密碼",
subtitle:"輸入您的郵箱,以重置密碼",
notaccess:"已經是會員了?",
registlink:"登錄",
account:"帳戶(EMail)",
submit:"提交"
}
}
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
<link rel="icon" type="image/ico" href="favicon.ico"> <link rel="icon" type="image/ico" href="favicon.ico">
</head> </head>
<body> <body>
<!-- DO NOT touch the following DIV -->
<div id="q-app"></div> <!-- quasar:entry-point -->
</body> </body>
</html> </html>
...@@ -97,13 +97,13 @@ const linksList = [ ...@@ -97,13 +97,13 @@ const linksList = [
] ]
import { defineComponent, ref, reactive, provide, watch } from 'vue' import { defineComponent, ref, reactive, provide, watch } from 'vue'
import Navs from '@/components/layout/navs.vue' import Navs from '../components/layout/navs.vue'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import useScrollModule from '@/module/scrollbar/scrollModule' import useScrollModule from '../module/scrollbar/scrollModule'
import { dispatchAction, getStoreGetter } from '@/store/utils' import { dispatchAction, getStoreGetter } from '../store/utils'
import { UserGetter } from '@/store/modules/user/getters' import { UserGetter } from '../store/modules/user/getters'
import { UserActionsType } from '@/store/modules/user/actions' import { UserActionsType } from '../store/modules/user/actions'
import router from '@/router' import router from '../router'
export default defineComponent({ export default defineComponent({
name: 'MainLayout', name: 'MainLayout',
......
import { StaticConfig } from '@/config/app' import { StaticConfig } from '../../config/app'
import { useMeta } from 'quasar' import { useMeta } from 'quasar'
import { ref } from 'vue' import { ref } from 'vue'
const userMetaTitleModule = () => { const userMetaTitleModule = () => {
const title = ref(StaticConfig.appsuffix) const title = ref(StaticConfig.appsuffix)
useMeta(() => { useMeta(() => {
......
import { ResultType } from '@/@types/enumHelper' import router from '../../router'
import router from '@/router' import { UserActionsType } from '../../store/modules/user/actions'
import { UserActionsType } from '@/store/modules/user/actions' import { dispatchAction, getStoreGetter, setStoreState } from '../../store/utils'
import { UserGetter } from '@/store/modules/user/getters' import message from '../../utils/message'
import { dispatchAction, getStoreGetter, setStoreState } from '@/store/utils'
import message from '@/utils/message'
import { reactive, ref } from 'vue' import { reactive, ref } from 'vue'
import { isEmail } from '../../utils/validate'
import { useI18n } from 'vue-i18n'
interface LoginParams { interface LoginParams {
username: string username: string
password: string password: string
...@@ -17,10 +17,10 @@ const userUserLoginModule = () => { ...@@ -17,10 +17,10 @@ const userUserLoginModule = () => {
password: '', password: '',
remeber: false remeber: false
}) })
const {t} = useI18n()
const userValidateRule = reactive({ const userValidateRule = reactive({
usernameRule: [(val: any) => !!val || '请填写账户信息'], usernameRule: [(val:any, rules:any) => rules.email(val) || t("login.ruleTipsAccount")],
userpasswordRule: [(val: any) => !!val || '请填写密码信息'] userpasswordRule: [(val: any) => !!val || t("login.ruleTipsPwd")]
}) })
const stateManager = reactive({ const stateManager = reactive({
subLogin: ref(false) subLogin: ref(false)
...@@ -28,56 +28,34 @@ const userUserLoginModule = () => { ...@@ -28,56 +28,34 @@ const userUserLoginModule = () => {
const usernameRef = ref(null) const usernameRef = ref(null)
const passwordRef = ref(null) const passwordRef = ref(null)
const loginSubmit = () => { const loginSubmit = async () => {
if (!stateManager.subLogin) { if (!stateManager.subLogin) {
stateManager.subLogin = true stateManager.subLogin = true
const ur = usernameRef as any //断言任意类型 const ur = usernameRef as any //断言任意类型
const pr = passwordRef as any const pr = passwordRef as any
ur.value.validate() ur.value.validate()
pr.value.validate() pr.value.validate()
if (ur.value.hasError || pr.value.hasError) { if (ur.value.hasError || pr.value.hasError) {
message.warnMsg('请完善登录信息') message.warnMsg(t("login.formTips"))
stateManager.subLogin = false stateManager.subLogin = false
} else { } else {
const param = {
setTimeout(() => { account: userModel.username,
//#region 测试使用 password: userModel.password,
const param = { platform: 0
username: userModel.username, }
password: userModel.password let r = await dispatchAction<UserActionsType>('user', 'userLogin', param) as [boolean,string]
} if(!r[0]){
message.errorMsg(r[1])
dispatchAction<UserActionsType>('user', 'userLogin', param) stateManager.subLogin=false
}
const menu:any = {
menuId: 1,
menuName: '首页',
menuUrl: '/index'
}
const menu2:any = {
menuId: 2,
menuName: '首页',
menuUrl: '/'
}
const menus: Array<any> = []
const auths = getStoreGetter<UserGetter>('user', 'getUserAllAuth')
if (auths != ResultType.EmptyArray) {
Object.assign(menus, ...auths)
}
menus.push(menu)
menus.push(menu2)
setStoreState('user', 'menuList', menus)
message.successMsg('登录成功')
stateManager.subLogin = false
router.push({
path: '/index'
})
//#endregion
}, 2000)
} }
} }
} }
return { userModel, usernameRef, passwordRef, userValidateRule, loginSubmit, stateManager } return { userModel, usernameRef, passwordRef, userValidateRule, loginSubmit, stateManager }
} }
......
import { AuthMenuType } from '@/@types' import { AuthMenuType } from '../../@types'
import { IndustryType, ResultType, ScaleType } from '@/@types/enumHelper' import { IndustryType, ResultType, ScaleType } from '../../@types/enumHelper'
import { userDictionmary } from '@/config/dictionary' import { userDictionmary } from '../../config/dictionary'
import router from '@/router' import router from '../../router'
import { UserGetter } from '@/store/modules/user/getters' import { UserGetter } from '../../store/modules/user/getters'
import { getStoreGetter, setStoreState } from '@/store/utils' import { getStoreGetter, setStoreState } from '../../store/utils'
import message from '@/utils/message' import message from '../../utils/message'
import { formatEnum } from '@/utils/tools' import { formatEnum } from '../../utils/tools'
import { SessionStorage } from 'quasar' import { SessionStorage } from 'quasar'
// import message from '@/utils/message' // import message from '@/utils/message'
import { nextTick, reactive, ref } from 'vue' import { nextTick, reactive, ref } from 'vue'
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { Todo, Meta } from '@/components/models' import { Todo, Meta } from '../components/models'
import ExampleComponent from 'components/CompositionComponent.vue' import ExampleComponent from 'components/CompositionComponent.vue'
import { defineComponent, ref } from 'vue' import { defineComponent, ref } from 'vue'
......
<template>
<div class="row full-height">
<div class="col q-pa-xl fit row justify-center height">
<div style="width:450px;" class="column justify-between content-between">
<div :class="{'row':$q.platform.is.desktop,'column':$q.platform.is.mobile}">
<div class="col" :class="{'text-center q-mb-md':$q.platform.is.mobile}">
<q-btn round flat>
<svg-icon icon="Navigation/Arrow-left.svg" :size="24"></svg-icon>
</q-btn>
</div>
<div class="text-grey-6 text-weight-bold col" :class="{'text-right':$q.platform.is.desktop,'text-center':$q.platform.is.mobile}">
<span>{{$t("forget.notaccess")}}</span>
<router-link :to="{ path: '/auth/regist' }" class="text-primary pfb text-subtitle">{{$t("forget.registlink")}}</router-link>
</div>
</div>
<div class="q-py-xxl full-width">
<div class="text-h3 text-weight-bold">{{$t("forget.title")}}</div>
<div class="text-grey-6 q-mt-sm q-mb-lg">{{$t("forget.subtitle")}}</div>
<div class="form-box q-my-lg">
<div class="q-mb-lg">
<q-input :label="$t('forget.account')" standout v-model="account" dense ref="accountRef" :rules="[(val:any, rules:any) => rules.email(val) || $t('login.ruleTipsAccount')]" />
</div>
</div>
<div class="row items-center" :class="{'row':$q.platform.is.desktop,'column':$q.platform.is.mobile}">
<div class="col">
<q-btn size="md" class="q-px-lg" color="primary" :loading="loading" @click="sendVerifyCode" unelevated :label="$t('forget.submit')" />
</div>
</div>
</div>
<div>
<q-select
borderless
v-model="currentLang"
:options="langs"
map-options
option-value="langLocale"
option-label="langName"
style="width:180px"
>
<template v-slot:selected>
{{$t("lanuage")}}
<q-chip
dense
square
color="white"
text-color="primary"
class="q-my-none q-ml-xs q-mr-none"
>
{{ currentLang.langName }}
</q-chip>
</template>
</q-select>
</div>
</div>
</div>
<div class="col right-bg full-height mobile-hide"></div>
</div>
</template>
<script lang="ts">
import { defineComponent, reactive } from 'vue'
import useMetaModule from '../../module/meta/metaModule'
import { useI18n } from 'vue-i18n'
import { getLangs } from "../../utils/tools";
import { SitLang } from '@/@types';
import svgIcon from '../../components/global/svg-icon.vue';
export default defineComponent({
components: { svgIcon },
setup() {
let { setTitle } = useMetaModule()
const dtNow = new Date().getFullYear()
const {locale,t } = useI18n();
setTitle(t("login.pageTitle"))
const data=reactive({
currentLang: {} as SitLang,
langs:[] as SitLang[],
account:'',
loading:false
})
data.langs=getLangs()
if(data.langs && data.langs.length>0){
data.currentLang = data.langs.find(x=> x.langLocale==locale.value) ?? {};
}
let methods = {
sendVerifyCode(){
}
}
return { ...data, ...methods }
}
})
</script>
<style>
.login-bg {
background-image: url(../../assets/images/8.png);
background-position-x: center;
background-position-y: bottom;
background-repeat: no-repeat;
background-size: contain;
}
.w-450 {
width: 450px;
box-shadow: 0 0.5rem 1.5rem 0.5rem rgba(0, 0, 0, 0.075) !important;
border-radius: 0.475rem !important;
}
.w-450-only {
width: 450px;
}
.right-bg{
background-image: url(../../assets/images/login-right-bg.png);
background-position-x: left;
background-position-y: center;
background-repeat: no-repeat;
background-size: cover;
}
.top-bg{
background-image: url(https://preview.keenthemes.com/metronic8/demo1/assets/media/auth/bg11.png);
background-position-x: -100px;
background-position-y: -85vh;
background-repeat: no-repeat;
background-size: cover;
}
</style>
<template> <template>
<div class="row"> <div class="row full-height">
<div class="col window-height column"> <!-- <div class="col window-height column">
<div class="col q-pa-lg flex justify-center items-center"> <div class="col q-pa-lg flex justify-center items-center">
<div class="relative-position"> <div class="relative-position">
<img src="../../assets/images/big-logo.png" style="height: 60px" class="q-mb-lg" alt="" /> <img src="../../assets/images/big-logo.png" style="height: 60px" class="q-mb-lg" alt="" />
...@@ -50,23 +50,101 @@ ...@@ -50,23 +50,101 @@
<router-link :to="{ path: '/auth/forget' }" class="f12 no-underline change-a-primary q-mr-md">技术支持</router-link> <router-link :to="{ path: '/auth/forget' }" class="f12 no-underline change-a-primary q-mr-md">技术支持</router-link>
</div> </div>
</div> </div>
</div> -->
<div class="col q-pa-xl fit row justify-center height">
<div style="width:450px;" class="column justify-between content-between">
<div :class="{'row':$q.platform.is.desktop,'column':$q.platform.is.mobile}">
<div class="col" :class="{'text-center q-mb-md':$q.platform.is.mobile}">
<img src="../../assets/images/lg-logo.png" style="width:80%;" />
</div>
<div class="text-grey-6 text-weight-bold col" :class="{'text-right':$q.platform.is.desktop,'text-center':$q.platform.is.mobile}">
<span>{{$t("login.notaccess")}}</span>
<router-link :to="{ path: '/auth/regist' }" class="text-primary pfb text-subtitle">{{$t("login.registlink")}}</router-link>
</div>
</div>
<div class="q-py-xxl full-width">
<div class="text-h3 text-weight-bold">{{$t("login.title")}}</div>
<div class="text-grey-6 q-mt-sm q-mb-lg">{{$t("login.subTitle")}}</div>
<div class="form-box q-my-lg">
<div class="q-mb-lg">
<q-input :label="$t('login.account')" standout v-model="userModel.username" dense ref="usernameRef" :rules="userValidateRule.usernameRule" />
</div>
<div>
<q-input :label="$t('login.password')" standout v-model="userModel.password" type="password" dense ref="passwordRef" :rules="userValidateRule.userpasswordRule" />
</div>
<div class="text-right">
<router-link :to="{ path: '/auth/forget' }" class="text-primary pfb text-body no-underline">{{$t("login.forgot")}}</router-link>
</div>
</div>
<div class="row items-center" :class="{'row':$q.platform.is.desktop,'column':$q.platform.is.mobile}">
<div class="col">
<q-btn size="md" class="q-px-lg" color="primary" :loading="stateManager.subLogin" @click="loginSubmit" unelevated :label="$t('login.signin')" />
</div>
<div class="col text-right" :class="{'q-mt-md':$q.platform.is.mobile}">
<span class="text-grey-6 q-mr-xs text-weight-bold">OR</span>
<q-btn size="md" color="primary" flat round icon="iconfont icon-google" />
<q-btn size="md" class="q-mx-xs" color="primary" flat round icon="iconfont icon-facebook" />
<q-btn size="md" color="primary" flat round icon="iconfont icon-apple" />
</div>
</div>
</div>
<div>
<q-select
borderless
v-model="currentLang"
:options="langs"
map-options
option-value="langLocale"
option-label="langName"
style="width:180px"
>
<template v-slot:selected>
{{$t("lanuage")}}
<q-chip
dense
square
color="white"
text-color="primary"
class="q-my-none q-ml-xs q-mr-none"
>
{{ currentLang.langName }}
</q-chip>
</template>
</q-select>
</div>
</div>
</div> </div>
<div class="col right-bg full-height mobile-hide"></div>
</div> </div>
</template> </template>
<script> <script lang="ts">
import { defineComponent } from 'vue' import { defineComponent, reactive } from 'vue'
import useLgoinModule from '@/module/user/loginModule' import useLgoinModule from '../../module/user/loginModule'
import useMetaModule from '@/module/meta/metaModule' import useMetaModule from '../../module/meta/metaModule'
import { useI18n } from 'vue-i18n'
import { getLangs } from "../../utils/tools";
import { SitLang } from '@/@types';
import {ref } from 'vue';
export default defineComponent({ export default defineComponent({
setup() { setup() {
//TODO: 缺陷,验证与提交应该使用Form表单来完成,不应该进行单个验证 //TODO: 缺陷,验证与提交应该使用Form表单来完成,不应该进行单个验证
let { userModel, usernameRef, passwordRef, userValidateRule, loginSubmit, stateManager } = useLgoinModule() let { userModel, usernameRef, passwordRef, userValidateRule, loginSubmit, stateManager } = useLgoinModule()
let { setTitle } = useMetaModule() let { setTitle } = useMetaModule()
setTitle('登录')
const dtNow = new Date().getFullYear() const dtNow = new Date().getFullYear()
return { userModel, usernameRef, passwordRef, userValidateRule, loginSubmit, dtNow, stateManager } const {locale,t } = useI18n();
setTitle(t("login.pageTitle"))
const data=reactive({
currentLang: {} as SitLang,
langs:[] as SitLang[]
})
data.langs=getLangs()
if(data.langs && data.langs.length>0){
data.currentLang = data.langs.find(x=> x.langLocale==locale.value) ?? {};
}
return { userModel, usernameRef, passwordRef, userValidateRule, loginSubmit, dtNow, stateManager,...data}
} }
}) })
</script> </script>
...@@ -87,4 +165,18 @@ export default defineComponent({ ...@@ -87,4 +165,18 @@ export default defineComponent({
.w-450-only { .w-450-only {
width: 450px; width: 450px;
} }
.right-bg{
background-image: url(../../assets/images/login-right-bg.png);
background-position-x: left;
background-position-y: center;
background-repeat: no-repeat;
background-size: cover;
}
.top-bg{
background-image: url(https://preview.keenthemes.com/metronic8/demo1/assets/media/auth/bg11.png);
background-position-x: -100px;
background-position-y: -85vh;
background-repeat: no-repeat;
background-size: cover;
}
</style> </style>
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<div class="w-600 col q-py-lg flex items-center"> <div class="w-600 col q-py-lg flex items-center">
<div class="form-box-diy col"> <div class="form-box-diy col">
<div class="text-center"> <div class="text-center">
<img src="@/assets/images/big-logo.png" height="60" alt="" /> <img src="../../assets/images/big-logo.png" height="60" alt="" />
</div> </div>
<q-card class="mycard q-mt-lg q-pa-xl"> <q-card class="mycard q-mt-lg q-pa-xl">
<q-tab-panels v-model="stateManager.currentSetup" animated> <q-tab-panels v-model="stateManager.currentSetup" animated>
...@@ -85,10 +85,10 @@ ...@@ -85,10 +85,10 @@
<script> <script>
import { defineComponent, onMounted } from 'vue' import { defineComponent, onMounted } from 'vue'
import useMetaModule from '@/module/meta/metaModule' import useMetaModule from '../../module/meta/metaModule'
import useUserRegistModule from '@/module/user/registModule' import useUserRegistModule from '../../module/user/registModule'
import verifyCodeBox from '@/components/common/verifyCode.vue' import verifyCodeBox from '../../components/common/verifyCode.vue'
import useScrollModule from '@/module/scrollbar/scrollModule' import useScrollModule from '../../module/scrollbar/scrollModule'
export default defineComponent({ export default defineComponent({
components: { components: {
verifyCodeBox verifyCodeBox
......
...@@ -3,22 +3,26 @@ import { RouteRecordRaw } from 'vue-router' ...@@ -3,22 +3,26 @@ import { RouteRecordRaw } from 'vue-router'
const routes: RouteRecordRaw[] = [ const routes: RouteRecordRaw[] = [
{ {
path: '/index', path: '/index',
component: () => import('@/layouts/MainLayout.vue'), component: () => import('../layouts/MainLayout.vue'),
children: [{ path: '', component: () => import('@/pages/Index.vue') }] children: [{ path: '', component: () => import('../pages/index.vue') }]
}, },
{ {
path:'/auth/login', path:'/auth/login',
component: () => import('@/pages/auth/login.vue') component: () => import('../pages/auth/login.vue')
}, },
{ {
path:'/auth/regist', path:'/auth/regist',
component: () => import('@/pages/auth/regist.vue') component: () => import('../pages/auth/regist.vue')
},
{
path:'/auth/forget',
component: () => import('../pages/auth/forget.vue')
}, },
// Always leave this as last one, // Always leave this as last one,
// but you can also remove it // but you can also remove it
{ {
path: '/:catchAll(.*)*', path: '/:catchAll(.*)*',
component: () => import('pages/Error404.vue') component: () => import('../pages/Error404.vue')
} }
] ]
......
/* eslint-disable */
/// <reference types="vite/client" />
// Mocks all files ending in `.vue` showing them as plain Vue instances // Mocks all files ending in `.vue` showing them as plain Vue instances
declare module '*.vue' { declare module '*.vue' {
import { ComponentOptions } from 'vue' import type { DefineComponent } from 'vue';
const component: ComponentOptions const component: DefineComponent<{}, {}, any>;
export default component export default component;
} }
\ No newline at end of file
...@@ -2,11 +2,11 @@ import { createStore, createLogger, Store } from 'vuex' ...@@ -2,11 +2,11 @@ import { createStore, createLogger, Store } from 'vuex'
import createPersistedState from 'vuex-persistedstate' import createPersistedState from 'vuex-persistedstate'
import mutations from './mutations' import mutations from './mutations'
import modules from './modules' import modules from './modules'
import { StateType } from '@/@types' import { StateType } from '../@types'
import { InjectionKey } from 'vue' import { InjectionKey } from 'vue'
export const key: InjectionKey<Store<StateType>> = Symbol() export const key: InjectionKey<Store<StateType>> = Symbol()
console.log(modules)
const store: Store<StateType> = createStore({ const store: Store<StateType> = createStore({
strict: !!process.env.DEBUGGING, strict: !!process.env.DEBUGGING,
mutations, mutations,
......
import { StateType } from '@/@types' import { StateType } from '../../../@types'
import { Module } from 'vuex' import { Module } from 'vuex'
const state = { const state = {
......
// https://vuex.vuejs.org/en/modules.html // https://vuex.vuejs.org/en/modules.html
const files = require.context('.', true, /\.ts$/) const files = import.meta.globEager("./**/*.ts") //require.context('.', true, /\.ts$/)
const modules: any = {} const modules: any = {}
console.log(files)
files.keys().forEach((key: string) => { Object.keys(files).forEach((key: string) => {
console.log(key)
if (key === './index.ts') return if (key === './index.ts') return
const path = key.replace(/(\.\/|\.ts)/g, '') const path = key.replace(/(\.\/|\.ts)/g, '')
const [namespace, imported] = path.split('/') const [namespace, imported] = path.split('/')
if (!modules[namespace]) { if (!modules[namespace]) {
...@@ -12,7 +14,7 @@ files.keys().forEach((key: string) => { ...@@ -12,7 +14,7 @@ files.keys().forEach((key: string) => {
namespaced: true namespaced: true
} }
} }
modules[namespace][imported] = files(key).default modules[namespace][imported] = files[key].default
}) })
export default modules export default modules
import UserService from '@/api/user' //import { message } from 'ant-design-vue';
import { ApiResult } from './../../../@types/enumHelper';
import UserService from '../../../api/user'
import { setStoreState } from '../../utils' import { setStoreState } from '../../utils'
import Store from '@/store' import Store from '../../../store'
import message from '../../../utils/message'
//import router from '../../../router';
/** /**
* @description 所有跟用户相关的内容 * @description 所有跟用户相关的内容
* @return status 返回状态 err_code:1,逻辑正确,err_code:0,发生错误。 * @return status 返回状态 err_code:1,逻辑正确,err_code:0,发生错误。
...@@ -39,37 +43,43 @@ const userActions = { ...@@ -39,37 +43,43 @@ const userActions = {
}, },
userLogin(params: { username: string; password: string }) { async userLogin({},params: { account: string; password: string, platform:number }):Promise<[boolean, string]> {
//TODO: 实现用户登录 let flag:[boolean,string] = [false,'']
// UserService.login(params).then(res=>{ try {
let param={
// }) 'account':params.account,
'password':params.password,
//测试伪造数据 'platform':params.platform
const loginUser = { }
email: 'alex9012@vip.qq.com', console.log(params)
type: 0, // 用户账号本身类型 0:主账号,1:子账号 let loginResult = await UserService.login(param)
userId: 1, if(loginResult.data.resultCode==ApiResult.SUCCESS){
username: params.username, message.successMsg('登录成功')
description: '', setStoreState('user', 'loginUserInfo', loginResult.data.data)
nickName: '罗超', setStoreState('user', 'menuList', loginResult.data.data.MenuList)
phone: '17308037817', const token = {
tenantId: 1, token_type: 'login_auth',
roleId: 1, access_token: loginResult.data.data.token
userAvatar: 'https://preview.keenthemes.com/metronic8/demo7/assets/media/avatars/150-26.jpg' }
} const expireTime = 72 * 60 * 60 * 1000 + new Date().getTime()
setStoreState('user', 'userDetail', loginUser) setStoreState('user', 'token', { ...token, expireTime })
const token = { flag[0]=true;
token_type: 'login_auth',
access_token: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' }else {
flag[1]=loginResult.data.message
flag[0] = false
}
} catch (error) {
flag[1]=error as string
flag[0] = false
} }
const expireTime = 60 * 72 * 1000 + new Date().getTime()
setStoreState('user', 'token', { ...token, expireTime }) return flag;
} }
} }
type UserActionsType = typeof userActions type UserActionsType = typeof userActions
export { UserActionsType } export { type UserActionsType }
export default userActions export default userActions
import { ResultType } from '@/@types/enumHelper' import { ResultType } from '../../../@types/enumHelper'
import store from '@/store' import store from '../../../store'
const userGetter = { const userGetter = {
getUserToken() { getUserToken() {
...@@ -18,5 +18,5 @@ const userGetter = { ...@@ -18,5 +18,5 @@ const userGetter = {
} }
type UserGetter = typeof userGetter type UserGetter = typeof userGetter
export { UserGetter } export { type UserGetter }
export default userGetter export default userGetter
import { Module } from 'vuex' import { Module } from 'vuex'
import { StateType } from '@/@types/index' import { StateType } from '../../../../../@types/index'
const state = { const state = {
teamName: '汉' teamName: '汉'
} }
...@@ -10,5 +10,5 @@ const ModuleTeam: Module<TeamStateType, StateType> = { ...@@ -10,5 +10,5 @@ const ModuleTeam: Module<TeamStateType, StateType> = {
...state ...state
} }
export { TeamStateType, state } export { type TeamStateType, state }
export default ModuleTeam export default ModuleTeam
import { StateType } from '@/@types' import { StateType } from '../../../@types'
import { Module } from 'vuex' import { Module } from 'vuex'
import ModuleTeam from './modules/team/state' import ModuleTeam from './modules/team/state'
interface Token { interface Token {
...@@ -6,17 +6,18 @@ interface Token { ...@@ -6,17 +6,18 @@ interface Token {
} }
const state = { const state = {
token: {} as Token, token: {} as Token,
secretKey: '',
userDetail: { userDetail: {
email: '', // email: '',
type: -1, // 用户账号本身类型 0:主账号,1:子账号 // type: -1, // 用户账号本身类型 0:主账号,1:子账号
userId: -1, // userId: -1,
username: '', // username: '',
description: '', // description: '',
nickName: '', // nickName: '',
phone: '', // phone: '',
tenantId: 0, // tenantId: 0,
roleId: 0, // roleId: 0,
userAvatar:'' // userAvatar:''
}, },
currentTeamRoleId: 0, // 当前所选择的团队用户所具有的权限 currentTeamRoleId: 0, // 当前所选择的团队用户所具有的权限
currentProjectRoleId: 0, // 当前所选择的项目用户所具有的权限 currentProjectRoleId: 0, // 当前所选择的项目用户所具有的权限
...@@ -32,5 +33,5 @@ const user: Module<UserStateType, StateType> = { ...@@ -32,5 +33,5 @@ const user: Module<UserStateType, StateType> = {
} }
} }
export { UserStateType, state } export { type UserStateType, state }
export default user export default user
import store from '@/store' import store from '../store'
// 定义 state 下的 module 值 // 定义 state 下的 module 值
type ModuleNameType = 'app' | 'console' | 'user' type ModuleNameType = 'app' | 'console' | 'user'
...@@ -36,7 +36,7 @@ export function setStoreState<T>(module: ModuleNameType, key: keyof T, value: an ...@@ -36,7 +36,7 @@ export function setStoreState<T>(module: ModuleNameType, key: keyof T, value: an
* @example 使用方法如下 const result = await dispatchActions<UserActionsType>('console','refreshToken',1) * @example 使用方法如下 const result = await dispatchActions<UserActionsType>('console','refreshToken',1)
*/ */
export function dispatchAction<T>(module: ModuleNameType, key: keyof T, value?: any) { export function dispatchAction<T>(module: ModuleNameType, key: keyof T, value?: any) {
store.dispatch(`${module}/${key}`, value) return store.dispatch(`${module}/${String(key)}`, value)
} }
/** /**
...@@ -45,5 +45,5 @@ export function dispatchAction<T>(module: ModuleNameType, key: keyof T, value?: ...@@ -45,5 +45,5 @@ export function dispatchAction<T>(module: ModuleNameType, key: keyof T, value?:
* @example 使用方法如下 const result = getStoreGetter<ConsoleGetterType>('console','list') * @example 使用方法如下 const result = getStoreGetter<ConsoleGetterType>('console','list')
*/ */
export function getStoreGetter<T>(module: ModuleNameType, key: keyof T) { export function getStoreGetter<T>(module: ModuleNameType, key: keyof T) {
return store.getters[`${module}/${key}`] return store.getters[`${module}/${String(key)}`]
} }
import { getStoreGetter } from '@/store/utils' import { getStoreGetter } from '../store/utils'
import { UserGetter } from '@/store/modules/user/getters' import { UserGetter } from '../store/modules/user/getters'
import { ResultType } from '@/@types/enumHelper' import { ResultType } from '../@types/enumHelper'
/** /**
* @description 获取授权信息 * @description 获取授权信息
*/ */
export function getAuth() { export function getAuth() {
const token = getStoreGetter<UserGetter>('user', 'getUserToken') const token = getStoreGetter<UserGetter>('user', 'getUserToken') ?? ResultType.Empty
console.log(token)
return token != ResultType.Empty return token != ResultType.Empty
} }
...@@ -15,7 +16,7 @@ export function getAuth() { ...@@ -15,7 +16,7 @@ export function getAuth() {
* @returns 菜单数组 * @returns 菜单数组
*/ */
export function getUserAllMenu() { export function getUserAllMenu() {
const auths = getStoreGetter<UserGetter>('user', 'getUserAllAuth') const auths = getStoreGetter<UserGetter>('user', 'getUserAllAuth')??[]
console.log(auths) console.log(auths)
return auths.length > 0 ? auths : ResultType.EmptyArray return auths.length > 0 ? auths : ResultType.EmptyArray
} }
import { SitLang } from './../@types/index';
/** /**
* @description 按照需要写入 必要可以注入全局 * @description 按照需要写入 必要可以注入全局
*/ */
...@@ -29,3 +30,13 @@ export function isNaNModified(inputStr: string) { ...@@ -29,3 +30,13 @@ export function isNaNModified(inputStr: string) {
const numericRepr = parseFloat(inputStr) const numericRepr = parseFloat(inputStr)
return isNaN(numericRepr) || numericRepr.toString().length != inputStr.length return isNaN(numericRepr) || numericRepr.toString().length != inputStr.length
} }
export function getLangs() {
const zhTw:SitLang={
langLocale:"zh-TW",
langName:"中文繁体"
}
let langs:SitLang[]=[]
langs.push(zhTw);
return langs
}
...@@ -27,6 +27,13 @@ export function validatAlphabets(str: string) { ...@@ -27,6 +27,13 @@ export function validatAlphabets(str: string) {
return reg.test(str) return reg.test(str)
} }
export function isEmail(account:string):boolean {
let serchfind:boolean;
let regexp = new RegExp('/^(([^<>()\[\]\\.,;:\[email protected]"]+(\.[^<>()\[\]\\.,;:\[email protected]"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/');
serchfind = regexp.test(account);
return serchfind
}
/** 比对数组是否相同 */ /** 比对数组是否相同 */
export function compareArray(arrA: any[], arrB: any[]) { export function compareArray(arrA: any[], arrB: any[]) {
let isSame = true let isSame = true
......
<div id="#kt_app_body_content" style="background-color:#D5D9E2; font-family:Arial,Helvetica,sans-serif; line-height: 1.5; min-height: 100%; font-weight: normal; font-size: 15px; color: #2F3044; margin:0; padding:0; width:100%;">
<div style="background-color:#ffffff; padding: 45px 0 34px 0; border-radius: 24px; margin:40px auto; max-width: 600px;">
<table align="center" border="0" cellpadding="0" cellspacing="0" width="100%" height="auto" style="border-collapse:collapse">
<tbody>
<tr>
<td align="center" valign="center" style="text-align:center; padding-bottom: 10px">
<!--begin:Email content-->
<div style="text-align:center; margin:0 60px 34px 60px">
<!--begin:Logo-->
<div style="margin-bottom: 10px">
<a href="http://b2b.jvs.oytour.com" rel="noopener" target="_blank">
<img alt="Logo" src="https://vt-im-bucket.oss-cn-chengdu.aliyuncs.com/mochat/202210261124201.png" style="height: 35px">
</a>
</div>
<!--end:Logo-->
<!--begin:Media-->
<div style="margin-bottom: 15px">
<img alt="Logo" src="https://vt-im-bucket.oss-cn-chengdu.aliyuncs.com/mochat/icon-positive-vote-2.svg">
</div>
<!--end:Media-->
<!--begin:Text-->
<div style="font-size: 14px; font-weight: 500; margin-bottom: 27px; font-family:Arial,Helvetica,sans-serif;">
<p style="margin-bottom:9px; color:#181C32; font-size: 22px; font-weight:700">It’s almost set!</p>
<p style="margin-bottom:2px; color:#7E8299">Please click the "Change Pass" button below</p>
<p style="margin-bottom:2px; color:#7E8299">Please do not send the link to other people</p>
<p style="margin-bottom:2px; color:#7E8299">and do not forward the email to other people</p>
</div>
<!--end:Text-->
<!--begin:Action-->
<a href="http://b2b.jvs.oytour.com/auth/newpassword" target="_blank" style="background-color:#50cd89; border-radius:6px;display:inline-block; padding:11px 19px; color: #FFFFFF; font-size: 14px; font-weight:500; font-family:Arial,Helvetica,sans-serif;">Change Password</a>
<!--end:Action-->
</div>
<!--end:Email content-->
</td>
</tr>
<tr>
<td align="center" valign="center" style="font-size: 13px; text-align:center; padding: 0 10px 10px 10px; font-weight: 500; color: #A1A5B7; font-family:Arial,Helvetica,sans-serif">
<p style="color:#181C32; font-size: 16px; font-weight: 600; margin-bottom:9px">It’s all about customers!</p>
<p style="margin-bottom:2px">Call our customer care number: +31 6 3344 55 56</p>
<p style="margin-bottom:4px">You may reach us at
<a rel="noopener" target="_blank" style="font-weight: 600">b2b.jvs.oytour.com</a>.</p>
<p>We serve Mon-Fri, 9AM-18AM</p>
</td>
</tr>
<tr>
<td align="center" valign="center" style="font-size: 13px; padding:0 15px; text-align:center; font-weight: 500; color: #A1A5B7;font-family:Arial,Helvetica,sans-serif">
<p>© Copyright JVS.
<a href="http://b2b.jvs.oytour.com" rel="noopener" target="_blank" style="font-weight: 600;font-family:Arial,Helvetica,sans-serif">Unsubscribe</a>&nbsp; from newsletter.</p>
</td>
</tr>
</tbody>
</table>
</div>
</div>
\ No newline at end of file
{ {
"extends": "@quasar/app/tsconfig-preset", "extends": "@quasar/app-vite/tsconfig-preset",
"compilerOptions": { "compilerOptions": {
"baseUrl": ".", "baseUrl": ".",
"paths": { "paths": {
"@/*": ["src/*"] "@/*": ["src/*"]
}, },
"types": [ "types": [
"node", "node"
"webpack-env" // here
] ]
} }
} }
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment