Commit be326b71 authored by wanli's avatar wanli

feat(frontend/src/views/User/Login.vue): 前端登录

parent 498128c0
'''
Author: your name
Date: 2021-07-12 11:14:48
LastEditTime: 2021-07-12 11:29:36
LastEditTime: 2021-07-15 17:43:48
LastEditors: Please set LastEditors
Description: In User Settings Edit
FilePath: \evm-store\tools\build_out\controllers\appi.py
......
......@@ -147,7 +147,9 @@ class AppResource(object):
# 应用打包
# 插入一条打包记录
user = UserModel.query.filter(UserModel.id==params.get('user')).one_or_none()
logger.info(jwt)
user = UserModel.query.filter(UserModel.uuid==jwt.get('uuid')).one_or_none()
if not user:
return False, ResponseCode.USER_NOT_EXISTS
......
......@@ -65,8 +65,8 @@ class PostAppSchema(ma.SQLAlchemySchema):
app_icon = ma.auto_field()
app_version = ma.auto_field()
category = ma.auto_field()
category_2th = ma.auto_field()
developer = ma.auto_field()
category_2th = fields.String(required=False)
developer = fields.String(required=False)
app_screen_size = ma.auto_field()
app_arch = ma.auto_field()
app_review = ma.auto_field()
......
'''
Author: your name
Date: 2021-07-15 03:22:19
LastEditTime: 2021-07-15 10:20:28
LastEditors: Please set LastEditors
Description: In User Settings Edit
FilePath: \evm-store\tools\build_out\views\__init__.py
'''
#!/usr/bin/env python
# -*- coding: utf_8 -*-
from flask import Blueprint
from flask_restful import Api
from . import area
from . import app
from . import package
from . import user
from . import login
from . import device
from . import annex
from . import file
from . import monitorWatch
from . import monitorSystem
from . import monitorLvgl
from . import monitorImage
from . import monitorEvm
api_v1 = Blueprint('api_v1', __name__)
api = Api(api_v1)
api.add_resource(area.AreaResource, '/area/<string:uuid>')
api.add_resource(area.AreaResourceList, '/area')
api.add_resource(app.AppResource, '/app/<string:uuid>')
api.add_resource(app.AppResourceList, '/app')
api.add_resource(package.PackageResource, '/package/<string:uuid>')
api.add_resource(package.PackageResourceList, '/package')
api.add_resource(user.UserResource, '/user/<string:uuid>')
api.add_resource(user.UserResourceList, '/user')
api.add_resource(login.LoginResource, '/login/<string:uuid>')
api.add_resource(login.LoginResourceList, '/login')
api.add_resource(device.DeviceResource, '/device/<string:uuid>')
api.add_resource(device.DeviceResourceList, '/device')
api.add_resource(annex.AnnexResource, '/annex/<string:uuid>')
api.add_resource(annex.AnnexResourceList, '/annex')
api.add_resource(file.FileInit, "/file-manager/initialize")
api.add_resource(file.FileContent, "/file-manager/content")
api.add_resource(file.FileDisk, "/file-manager/disk")
api.add_resource(file.FileTree, "/file-manager/tree")
api.add_resource(file.FileDownload, "/file-manager/download")
api.add_resource(file.FilePrview, "/file-manager/preview")
api.add_resource(monitorWatch.MonitorWatchResource, '/monitorWatch/<string:uuid>')
api.add_resource(monitorWatch.MonitorWatchResourceList, '/monitorWatch')
api.add_resource(monitorSystem.MonitorSystemResource, '/monitorSystem/<string:uuid>')
api.add_resource(monitorSystem.MonitorSystemResourceList, '/monitorSystem')
api.add_resource(monitorLvgl.MonitorLvglResource, '/monitorLvgl/<string:uuid>')
api.add_resource(monitorLvgl.MonitorLvglResourceList, '/monitorLvgl')
api.add_resource(monitorImage.MonitorImageResource, '/monitorImage/<string:uuid>')
api.add_resource(monitorImage.MonitorImageResourceList, '/monitorImage')
api.add_resource(monitorEvm.MonitorEvmResource, '/monitorEvm/<string:uuid>')
api.add_resource(monitorEvm.MonitorEvmResourceList, '/monitorEvm')
# -*- coding: utf-8 -*-
'''
Author: your name
Date: 2021-07-15 03:22:19
LastEditTime: 2021-07-15 17:45:32
LastEditors: Please set LastEditors
Description: In User Settings Edit
FilePath: \evm-store\tools\build_out\views\__init__.py
'''
#!/usr/bin/env python
# -*- coding: utf_8 -*-
from flask import Blueprint
from flask_restful import Api
......@@ -9,6 +18,7 @@ from . import user
from . import login
from . import device
from . import annex
from . import file
from . import monitorWatch
from . import monitorSystem
from . import monitorLvgl
......@@ -41,6 +51,13 @@ api.add_resource(device.DeviceResourceList, '/device')
api.add_resource(annex.AnnexResource, '/annex/<string:uuid>')
api.add_resource(annex.AnnexResourceList, '/annex')
api.add_resource(file.FileInit, "/file-manager/initialize")
api.add_resource(file.FileContent, "/file-manager/content")
api.add_resource(file.FileDisk, "/file-manager/disk")
api.add_resource(file.FileTree, "/file-manager/tree")
api.add_resource(file.FileDownload, "/file-manager/download")
api.add_resource(file.FilePrview, "/file-manager/preview")
api.add_resource(monitorWatch.MonitorWatchResource, '/monitorWatch/<string:uuid>')
api.add_resource(monitorWatch.MonitorWatchResourceList, '/monitorWatch')
......
import os
from datetime import datetime
from flask import current_app, jsonify, request
from flask_restful import Resource
from flask_restful.reqparse import RequestParser
from flask_jwt_extended import ( jwt_required, get_jwt_identity )
from werkzeug.utils import secure_filename
from application.config import config
from application.signal_manager import signalManager
from models.app import postAppSchema, deleteAppSchema, getListAppSchema, getListAppsSchema, getAppSchema, putAppSchema
from webcreator.log import logger
......@@ -37,13 +41,56 @@ class AppResourceList(Resource):
@jwt_required(locations=["headers"])
def post(self):
try:
jwt = get_jwt_identity()
# 获取request.files参数
json_payload = request.json
data = postAppSchema.load(json_payload)
result, message = signalManager.actionPostApp.emit(data)
params = postAppSchema.load(json_payload)
now_str = datetime.now().strftime("%Y%m%d%H%M%S")
# 获取相对路径
dirname = "{}-{}-{}-{}".format(params["app_name"], params["app_version"], params["category"], now_str)
relative_path = os.sep.join([config.EPK_DIR, dirname])
# 获取最终存储的绝对路径
upload_path = os.path.normpath(os.sep.join([config.UPLOAD_ROOT_DIR, relative_path]))
if not os.path.exists(upload_path):
os.makedirs(upload_path)
files = []
# 应用logo
logo = request.files.get("logo")
if logo:
filename = secure_filename(logo.filename)
file_path = os.sep.join([upload_path, filename])
file_path = os.path.normpath(file_path)
logo.save(file_path)
params.update({ "app_icon": file_path })
# 应用源文件
fileList = request.files.getlist('fileList')
if fileList:
upload_path = os.sep.join([upload_path, "src"])
if not os.path.exists(upload_path):
os.mkdir(upload_path)
for f in fileList:
filename = secure_filename(f.filename)
file_path = os.sep.join([upload_path, filename])
file_path = os.path.normpath(file_path)
f.save(file_path)
files.append(file_path)
# obj = dict()
# obj['filename'] = binfile.filename
# obj['content'] = binfile.stream.read()
params.update({ "fileList": files, "epk_path": upload_path })
result, message = signalManager.actionPostApp.emit(params, jwt)
if result:
logger.warn(result)
return response_result(ResponseCode.HTTP_SUCCESS, data=result, msg=message)
return response_result(ResponseCode.HTTP_NOT_FOUND)
return response_result(message)
except Exception as e:
current_app.logger.error(e)
return response_result(ResponseCode.HTTP_SERVER_ERROR)
......@@ -95,8 +142,8 @@ class AppResource(Resource):
def delete(self, uuid):
try:
json_payload = request.json
print("========>", uuid, json_payload)
# data = deleteAppSchema.load(json_payload)
data = deleteAppSchema.load(json_payload)
print("========>", uuid, data, json_payload)
result, message = signalManager.actionDeleteApp.emit(uuid)
if result:
return response_result(ResponseCode.HTTP_SUCCESS, data=result, msg=message)
......
// set baseUrl
MIX_LFM_BASE_URL=http://my-url.loc/file-manager/
BASE_URL=http://localhost:3000/
// if you don't want to use csrf-token - you can off it
MIX_LFM_CSRF_TOKEN=OFF
\ No newline at end of file
CSRF_TOKEN=OFF
\ No newline at end of file
......@@ -9465,6 +9465,11 @@
"integrity": "sha1-dIkR+wT0imDEdxs3XKxFqA3xHAM=",
"dev": true
},
"js-cookie": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.1.tgz",
"integrity": "sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ=="
},
"js-message": {
"version": "1.0.5",
"resolved": "http://registry.npm.taobao.org/js-message/download/js-message-1.0.5.tgz",
......
......@@ -15,6 +15,7 @@
"codemirror": "^5.59.2",
"core-js": "^3.9.0",
"cropperjs": "^1.5.11",
"js-cookie": "^2.2.1",
"npm-check-updates": "^11.7.1",
"numeral": "^2.0.6",
"plyr": "^3.6.4",
......
......@@ -5,7 +5,7 @@
</template>
<script>
import { LocaleProvider, ConfigProvider, Input } from "ant-design-vue";
import { LocaleProvider, ConfigProvider } from "ant-design-vue";
export default {
components: {
LocaleProvider,
......
/*
* @Author: your name
* @Date: 2021-07-15 09:33:39
* @LastEditTime: 2021-07-15 19:22:09
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: \evm-store\tools\frontend\src\api\openapi.js
*/
import request from '@/utils/request'
export function users(params) {
......@@ -7,3 +15,19 @@ export function users(params) {
params
})
}
export function postLogin(params) {
return request({
url: '/api/v1/login',
method: 'post',
data: params
})
}
export function postApplication(params) {
return request({
url: "/api/v1/app",
method: "post",
data: params
})
}
\ No newline at end of file
/*
* @Author: your name
* @Date: 2021-07-15 09:33:39
* @LastEditTime: 2021-07-15 18:24:43
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: \evm-store\tools\frontend\src\defaultSettings.js
*/
export default {
navTheme: 'dark', // theme for nav menu
primaryColor: '#1890FF', // primary color of ant design
layout: 'sidemenu', // nav menu position: sidemenu or topmenu
contentWidth: 'Fluid', // layout of content: Fluid or Fixed, only works when layout is topmenu
fixedHeader: false, // sticky header
autoHideHeader: false, // auto hide header
fixSiderbar: false, // sticky siderbar
contentWidth: 'Fixed', // layout of content: Fluid or Fixed, only works when layout is topmenu
fixedHeader: true, // sticky header
autoHideHeader: true, // auto hide header
fixSiderbar: true, // sticky siderbar
leftMenuTitle: "EVM 应用商店", // 左侧边栏顶部名称
leftMenuIcon: "", // 左侧边栏顶部Logo
appSlogan: "EVM,致力于为互联网行业提供物联网解决方案", // 应用宣传文案
......
/*
* @Author: your name
* @Date: 2021-07-15 09:33:39
* @LastEditTime: 2021-07-15 20:32:40
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: \evm-store\tools\frontend\src\main.js
*/
import Vue from 'vue'
import App from './App'
import store from './store'
......
import Vue from 'vue'
import Router from 'vue-router'
import store from '../store'
import Vue from "vue";
import Router from "vue-router";
import store from "../store";
import UserLayout from '@/layouts/UserLayout'
import BasicLayout from '@/layouts/BasicLayout'
import BlankLayout from '@/layouts/BlankLayout'
import UserLayout from "@/layouts/UserLayout";
import BasicLayout from "@/layouts/BasicLayout";
import BlankLayout from "@/layouts/BlankLayout";
Vue.use(Router)
Vue.use(Router);
const router = new Router({
routes: [
// user
{
path: '/user',
path: "/user",
component: UserLayout,
children: [
{ path: '/user', redirect: '/user/login' },
{ path: '/user/login', component: () => import('@/views/User/Login') },
{ path: '/user/register', component: () => import('@/views/User/Register') },
{ path: "/user", redirect: "/user/login" },
{ path: "/user/login", component: () => import("@/views/User/Login") },
{
path: "/user/register",
component: () => import("@/views/User/Register"),
},
],
},
// app
{
path: '/',
path: "/",
component: BasicLayout,
children: [
// dashboard
{ path: '/', redirect: '/dashboard/analysis' },
{ path: "/", redirect: "/dashboard/analysis" },
{
path: '/dashboard',
name: 'dashboard',
path: "/dashboard",
name: "dashboard",
component: BlankLayout,
children: [
{ path: '/dashboard/analysis', name: 'analysis', component: () => import('@/views/Dashboard/Analysis') },
{
path: "/dashboard/analysis",
name: "analysis",
component: () => import("@/views/Dashboard/Analysis"),
},
// { path: '/dashboard/monitor', name: 'monitor', component: () => import('@/views/Dashboard/Analysis') },
{ path: '/dashboard/workplace', name: 'workplace', component: () => import('@/views/Dashboard/Workplace') },
]
{
path: "/dashboard/workplace",
name: "workplace",
component: () => import("@/views/Dashboard/Workplace"),
},
],
},
{
path: '/form',
name: 'form',
icon: 'form',
path: "/form",
name: "form",
icon: "form",
component: BlankLayout,
children: [
{ path: '/form/basic-form', name: 'basicform', component: () => import('@/views/Dashboard/Analysis') },
{
path: '/form/step-form',
name: 'stepform',
path: "/form/basic-form",
name: "basicform",
component: () => import("@/views/Dashboard/Analysis"),
},
{
path: "/form/step-form",
name: "stepform",
component: BlankLayout,
hideChildrenInMenu: true,
children: [
{
path: '/form/step-form/info',
name: 'info',
component: () => import('@/views/Dashboard/Analysis'),
path: "/form/step-form/info",
name: "info",
component: () => import("@/views/Dashboard/Analysis"),
},
]
],
},
{ path: '/form/advanced-form', name: 'advancedform', component: () => import('@/views/Dashboard/Analysis') },
]
{
path: "/form/advanced-form",
name: "advancedform",
component: () => import("@/views/Dashboard/Analysis"),
},
],
},
{
path: '/list',
icon: 'table',
name: 'list',
path: "/list",
icon: "table",
name: "list",
component: BlankLayout,
children: [
{
path: '/list/search',
name: 'searchlist',
path: "/list/search",
name: "searchlist",
component: BlankLayout,
children: [
{
path: '/list/search/articles',
name: 'articles',
path: "/list/search/articles",
name: "articles",
},
{
path: '/list/search/projects',
name: 'projects',
path: "/list/search/projects",
name: "projects",
},
{
path: '/list/search/applications',
name: 'applications',
path: "/list/search/applications",
name: "applications",
},
]
}
]
],
},
],
},
{
path: '/profile',
icon: 'profile',
name: 'profile',
path: "/profile",
icon: "profile",
name: "profile",
},
{
path: '/system',
name: 'system',
path: "/system",
name: "system",
component: BlankLayout,
children: [
{
path: '/system/setting',
name: 'setting',
path: "/system/setting",
name: "setting",
component: BlankLayout,
children: [
{
path: '/system/setting/menu',
name: 'menu',
component: () => import('@/views/System/Menu')
path: "/system/setting/menu",
name: "menu",
component: () => import("@/views/System/Menu"),
},
{
path: '/system/setting/module',
name: 'module',
component: () => import('@/views/System/Role')
path: "/system/setting/module",
name: "module",
component: () => import("@/views/System/Role"),
},
{
path: '/system/setting/config',
name: 'config',
component: () => import('@/views/System/Role')
path: "/system/setting/config",
name: "config",
component: () => import("@/views/System/Role"),
},
{
path: '/system/setting/dict',
name: 'dict',
component: () => import('@/views/System/Role')
path: "/system/setting/dict",
name: "dict",
component: () => import("@/views/System/Role"),
},
{
path: '/system/setting/area',
name: 'area',
component: () => import('@/views/System/Role')
path: "/system/setting/area",
name: "area",
component: () => import("@/views/System/Role"),
},
{
path: '/system/setting/file-manager',
name: 'file-manager',
component: () => import('@/views/FileManager/FileManager')
path: "/system/setting/file-manager",
name: "file-manager",
component: () => import("@/views/FileManager/FileManager"),
},
]
],
},
{
path: '/system/role',
name: 'role',
component: () => import('@/views/System/Role')
path: "/system/role",
name: "role",
component: () => import("@/views/System/Role"),
},
{
path: '/system/admin',
name: 'admin',
component: () => import('@/views/System/Role')
}
]
path: "/system/admin",
name: "admin",
component: () => import("@/views/System/Role"),
},
],
},
]
],
},
{
path: '/application',
icon: 'table',
name: 'application',
path: "/application",
icon: "table",
name: "application",
// redirect: '/application/index',
component: BasicLayout,
children: [
{ path: '/application', redirect: '/application/index' },
{ path: '/application/index', component: () => import('@/views/Application/Index') },
{ path: '/application/manager', component: () => import('@/views/Application/Manager') },
{ path: '/application/form', component: () => import('@/views/Application/Form') },
{ path: "/application", redirect: "/application/index" },
{
path: "/application/index",
component: () => import("@/views/Application/Index"),
},
{
path: "/application/manager",
component: () => import("@/views/Application/Manager"),
},
{
path: "/application/form",
component: () => import("@/views/Application/Form"),
},
],
}
]
})
},
],
});
router.afterEach(() => {
store.commit('global/UpdateBasicLayoutSpinning', false);
});
export default router
export default router;
/*
* @Author: your name
* @Date: 2021-07-15 09:33:39
* @LastEditTime: 2021-07-15 19:07:35
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: \evm-store\tools\frontend\src\store\index.js
*/
import Vue from 'vue'
import Vuex from 'vuex'
import fm from './file-manager'
import global from './modules/global'
import globalNav from './modules/global-nav'
import frontendLogin from './modules/frontend-login'
import frontendOpenapi from './modules/frontend-openapi'
Vue.use(Vuex)
......@@ -14,7 +23,8 @@ export default new Vuex.Store({
frontend: {
namespaced: true,
modules: {
openapi: frontendOpenapi
openapi: frontendOpenapi,
login: frontendLogin
}
},
global: {
......
// import Cookies from 'js-cookie'
import api from '~a/index'
import { setStore, removeStore } from '~u/storage'
/*
* @Author: your name
* @Date: 2021-07-15 09:33:39
* @LastEditTime: 2021-07-15 21:14:30
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: \evm-store\tools\frontend\src\store\modules\frontend-login.js
*/
import Cookies from "js-cookie";
import api from "@/utils/request";
const TokenKey = "Authorization";
const state = {
mobile:'',
// checkMobile: {
// mobile: '',
// data: '',
// },
}
mobile: "",
token: null,
userinfo: {},
// checkMobile: {
// mobile: '',
// data: '',
// },
};
const actions = {
async ['logoutClean']({ commit, rootState: { route: { path } } }, config) {
const { data: { code, data } } = await api.post('/auth/clean', { ...config })
if (code === '0') {
commit('removeAuthToken')
}
async ["logoutClean"](
{
commit,
rootState: {
route: { path },
},
},
}
config
) {
const {
data: { code, data },
} = await api.post("/auth/clean", { ...config });
if (code === "0") {
commit("removeAuthToken");
}
},
setToken({ commit }, token) {
commit("setToken", token);
},
removeToken({ commit }) {
commit("removeToken");
resetRouter();
},
setUserInfo({ commit }, userinfo) {
commit("setUserInfo", userinfo);
},
removeUserInfo({ commit }, userinfo) {
commit("removeUserInfo", userinfo);
},
};
const mutations = {
['receiveAuthToken'](state, payload) {
setStore('access_token', payload.access_token)
setStore('expires_in', payload.expires_in)
setStore('token_type', payload.token_type)
// Cookies.set('token', payload.access_token, { expires: (payload.expires_in / 86400) });
},
['removeAuthToken'](state) {
removeStore('access_token')
removeStore('expires_in')
removeStore('token_type')
// Cookies.remove('token')
},
['receiveMobile'](state, payload) {
state.mobile = payload;
},
}
["receiveAuthToken"](state, payload) {
Cookies.set(TokenKey, payload.access_token, {
expires: payload.expires_in / 86400,
});
},
["removeAuthToken"](state) {
Cookies.remove(TokenKey);
},
["receiveMobile"](state, payload) {
state.mobile = payload;
},
setToken: (state, token) => {
state.token = token;
Cookies.set(TokenKey, token);
},
removeToken: (state, token) => {
state.token = null;
Cookies.remove(TokenKey, token);
},
setUserInfo: (state, name) => {
state.userinfo = name;
Cookies.set("userinfo", name);
},
removeUserInfo: (state, name) => {
state.userinfo = null;
Cookies.remove("userinfo", name);
},
};
const getters = {
['getMobile'](state) {
return state.mobile
},
}
["getMobile"](state) {
return state.mobile;
},
["getToken"](state) {
return state.token;
},
["getUserInfo"](state) {
return state.userinfo;
},
};
export default {
namespaced: true,
state,
actions,
mutations,
getters
}
\ No newline at end of file
namespaced: true,
state,
actions,
mutations,
getters,
};
import { users } from '@/api/openapi'
/*
* @Author: your name
* @Date: 2021-07-15 09:33:39
* @LastEditTime: 2021-07-15 18:36:43
* @LastEditors: your name
* @Description: In User Settings Edit
* @FilePath: \evm-store\tools\frontend\src\store\modules\frontend-openapi.js
*/
import { users } from "@/api/openapi";
const state = {
loading: false,
users: {
data: [],
pagination: {
showSizeChanger: true,
}
}
}
loading: false,
users: {
data: [],
pagination: {
showSizeChanger: true,
},
},
};
const actions = {
['getUsers']({ commit, state }, config) {
state.loading = true
return new Promise((resolve, reject) => {
users(config).then(response => {
// console.log(response);
commit('setUsers', {
...response,
config
})
state.loading = false
resolve()
}).catch(error => {
state.loading = false
reject(error)
})
["getUsers"]({ commit, state }, config) {
state.loading = true;
return new Promise((resolve, reject) => {
users(config)
.then((response) => {
// console.log(response);
commit("setUsers", {
...response,
config,
});
state.loading = false;
resolve();
})
},
}
.catch((error) => {
state.loading = false;
reject(error);
});
});
},
};
const mutations = {
['setUsers'](state, { results, config }) {
state.users = {
data: results,
pagination: {
total: 200,
pageSize: config.results
}
}
}
}
["setUsers"](state, { results, config }) {
state.users = {
data: results,
pagination: {
total: 200,
pageSize: config.results,
},
};
},
};
const getters = {
['getUsers'](state) {
return state.users;
},
['loading'](state) {
return state.loading;
},
}
["getUsers"](state) {
return state.users;
},
["loading"](state) {
return state.loading;
},
};
export default {
namespaced: true,
state,
actions,
mutations,
getters
}
\ No newline at end of file
namespaced: true,
state,
actions,
mutations,
getters,
};
import Cookies from "js-cookie";
const TokenKey = "Authorization";
export function getToken() {
return Cookies.get(TokenKey);
}
export function setToken(token) {
return Cookies.set(TokenKey, token);
}
export function removeToken() {
return Cookies.remove(TokenKey);
}
import axios from 'axios'
import { message, Modal } from "ant-design-vue";
import qs from 'qs';
/*
* @Author: your name
* @Date: 2021-07-15 09:33:39
* @LastEditTime: 2021-07-15 21:15:15
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: \evm-store\tools\frontend\src\utils\request.js
*/
import axios from 'axios';
import store from "@/store";
import { message } from "ant-design-vue";
import { getToken } from "@/utils/auth";
// create an axios instance
const service = axios.create({
// baseURL: process.env.BASE_API, // api的base_url
timeout: 5000, // request timeout
baseURL: process.env.BASE_URL, // api的base_url
timeout: 15000, // request timeout
// responseType: "json",
// crossDomain: true,
// xhrFields: { withCredentials: true },
......@@ -18,20 +27,10 @@ const service = axios.create({
// request interceptor
service.interceptors.request.use(config => {
// Do something before request is sent
// if (getCookies(_CONST.TOKEN)) {
// config.headers['Authorization'] = 'Bearer ' + getCookies(_CONST.TOKEN) // 让每个请求携带token-- ['Authorization']为自定义key 请根据实际情况自行修改
// }
// 在发送请求之前做某件事
if (
config.method === "post" ||
config.method === "put" ||
config.method === "delete"
) {
// 序列化
config.data = qs.stringify(config.data);
if (store.state.frontend.login.token) {
// 让每个请求携带token-- ['Authorization']为自定义key 请根据实际情况自行修改
config.headers['Authorization'] = 'Bearer ' + getToken()
}
// console.log('config', config);
return config
}, error => {
// Do something with request error
......@@ -56,13 +55,8 @@ service.interceptors.response.use(
*/
// console.log('error', error)
const res = error.response;
// console.log(res);
if (res && res.data) {
const { code, error, error_description } = res.data;
// console.info(code)
// console.info(error)
// console.info(error_description)
const { code, msg } = res.data;
// 100401:非法的token; 100412:其他客户端登录了; 100413:Token 过期了;
if (code === 100401 || code === 100412 || code === 100413) {
// MessageBox.confirm('操作失败,原因:' + error + ',可以取消继续留在该页面,或者重新登录', '操作提示', {
......@@ -73,6 +67,7 @@ service.interceptors.response.use(
// removeCookies(_CONST.TOKEN);
// location.reload();// 为了重新实例化vue-router对象 避免bug
// })
message.error(msg, 3);
} else {
let error;
if (!error) {
......
......@@ -8,14 +8,14 @@
:wrapperCol="{ span: 10 }"
:required="true"
>
<a-input placeholder="给应用起个名字" />
<a-input v-model="post.app_name" placeholder="给应用起个名字" />
</a-form-item>
<a-form-item
label="打包算法"
:labelCol="{ span: 7 }"
:wrapperCol="{ span: 10 }"
>
<a-radio-group v-model="value" @change="onChange">
<a-radio-group v-model="post.algorithm" @change="onChange">
<a-radio-button value="zlib"> zlib </a-radio-button>
<a-radio-button value="eheatshrink"> eheatshrink </a-radio-button>
</a-radio-group>
......@@ -35,13 +35,14 @@
:required="true"
>
<a-select
mode="tags"
v-model="post.category"
mode="default"
style="width: 100%"
placeholder="应用所属类别"
@change="handleChange"
>
<a-select-option v-for="i in 25" :key="(i + 9).toString(36) + i">
{{ (i + 9).toString(36) + i }}
<a-select-option v-for="item in categoryList" :key="(item.value + 9).toString(36) + item.value">
{{ item.label }}
</a-select-option>
</a-select>
</a-form-item>
......@@ -56,8 +57,7 @@
list-type="picture-card"
class="avatar-uploader"
:show-upload-list="false"
action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
:before-upload="beforeUpload"
:before-upload="beforeLogoUpload"
@change="handleChange"
>
<img v-if="imageUrl" :src="imageUrl" alt="avatar" />
......@@ -73,7 +73,7 @@
:wrapperCol="{ span: 10 }"
:required="true"
>
<a-select :default-value="sizeList[0].label" style="width: 120px">
<a-select :default-value="sizeList[0].label" v-model="post.app_screen_size" style="width: 120px">
<a-select-option v-for="item in sizeList" :key="(item.value + 9).toString(36) + item.value" :value="item.label">
{{ item.label }}
</a-select-option>
......@@ -85,7 +85,7 @@
:wrapperCol="{ span: 10 }"
:required="true"
>
<a-select :default-value="portList[0].label" style="width: 120px">
<a-select :default-value="portList[0].label" v-model="post.app_arch" style="width: 120px">
<a-select-option v-for="item in portList" :key="(item.value + 9).toString(36) + item.value" :value="item.label">
{{ item.label }}
</a-select-option>
......@@ -96,7 +96,7 @@
:labelCol="{ span: 7 }"
:wrapperCol="{ span: 10 }"
>
<a-textarea rows="4" placeholder="请输入应用介绍" />
<a-textarea v-model="post.remarks" rows="4" placeholder="请输入应用介绍" />
</a-form-item>
<a-form-item
label="应用源文件"
......@@ -107,7 +107,7 @@
<a-upload-dragger
name="file"
:multiple="true"
action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
:before-upload="beforeUpload"
@change="handleSourceFileChange"
>
<p class="ant-upload-drag-icon">
......@@ -125,7 +125,7 @@
style="margin-top: 24px"
:wrapperCol="{ span: 10, offset: 7 }"
>
<a-button type="primary">提交</a-button>
<a-button type="primary" @click="onSumbit">提交</a-button>
<a-button style="margin-left: 8px">保存</a-button>
</a-form-item>
</a-form>
......@@ -156,6 +156,9 @@ import {
} from "ant-design-vue";
import PageHeaderWrapper from "@/components/PageHeaderWrapper";
import DescriptionItem from "@/components/DescriptionItem";
import { postApplication } from "@/api/openapi";
export default {
name: "BasicForm",
data() {
......@@ -163,10 +166,28 @@ export default {
loading: false,
imageUrl: "",
value: 1,
title: "编辑",
title: "添加",
post: {
app_version: '',
app_name: null,
app_icon: null,
app_version: null,
category: null,
app_screen_size: null,
app_arch: null,
remarks: null,
logo: null,
fileList: []
},
logo: null,
fileList: [],
categoryList: [
{ label: '影音视听', value: 1 },
{ label: '实用工具', value: 2 },
{ label: '图书阅读', value: 3 },
{ label: '学习教育', value: 4 },
{ label: '医疗健康', value: 5 },
{ label: '未定义', value: 6 }
],
sizeList: [
{ label: '240 * 240', value: 1 },
{ label: '390 * 390', value: 2 },
......@@ -210,18 +231,42 @@ export default {
ARangePicker: DatePicker.RangePicker,
},
methods: {
handleUploadChange(info) {
if (info.file.status === "uploading") {
this.loading = true;
return;
}
if (info.file.status === "done") {
// Get this url from response in real world.
getBase64(info.file.originFileObj, (imageUrl) => {
this.imageUrl = imageUrl;
this.loading = false;
});
handleRemove(file) {
const index = this.fileList.indexOf(file);
const newFileList = this.fileList.slice();
newFileList.splice(index, 1);
this.fileList = newFileList;
},
beforeLogoUpload(file) {
this.logo = file;
return false;
},
beforeUpload(file) {
this.fileList = [...this.fileList, file];
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
this.$message.error("Image must smaller than 2MB!");
}
return false;
},
handleUpload() {
this.uploading = true;
let formData = new FormData();
this.fileList.forEach(item => {
formData.append("fileList", item.file)
});
formData.append("logo", this.logo.file)
Object.keys(this.post).forEach(k => {
if (this.post[k] && typeof this.post[k] !== "object") {
formData.append(k, this.post[k])
}
});
this.postApplication(formData)
},
handleSourceFileChange(info) {
const status = info.file.status;
......@@ -234,24 +279,30 @@ export default {
this.$message.error(`${info.file.name} file upload failed.`);
}
},
beforeUpload(file) {
const isJpgOrPng =
file.type === "image/jpeg" || file.type === "image/png";
if (!isJpgOrPng) {
this.$message.error("You can only upload JPG file!");
}
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
this.$message.error("Image must smaller than 2MB!");
}
return isJpgOrPng && isLt2M;
},
onChange(e) {
console.log(`checked = ${e.target.value}`);
},
handleChange(value) {
console.log(`selected ${value}`);
},
postApplication(formData) {
postApplication(formData).then(res => {
console.log(res)
this.fileList = [];
this.logo = null;
this.post.fileList = [];
this.post.logo = null;
this.uploading = false;
this.$message.success('upload successfully.');
}).catch(err => {
console.log(err)
this.uploading = false;
this.$message.error('upload failed.');
})
},
onSumbit() {
this.handleUpload()
}
},
computed: {
desc() {
......@@ -259,7 +310,12 @@ export default {
},
},
created() {
console.log(this.$route.query);
const { type } = this.$route.query
if (type && type == "update") {
this.title = "更新"
} else {
this.title = "添加"
}
},
};
</script>
......
......@@ -179,7 +179,6 @@ import {
Field,
yuan,
MiniProgress
// MiniBar,
// MiniArea
} from "@/components/Charts";
......
<template>
<div class="ai-login-main">
<div class="ai-login">
<a-form
@submit="handleSubmit"
>
<a-form :form="form" @submit="handleSubmit">
<a-tabs
:animated="false"
:defaultActiveKey="activeKey"
......@@ -17,7 +15,7 @@
{ rules: [{ required: true, message: '请输入用户名!' }] },
]"
>
<a-input placeholder="用户名" size="large">
<a-input v-model="post.account" placeholder="用户名" size="large">
<a-icon type="user" style="color: rgba(0, 0, 0, 0.25)" />
</a-input>
</a-form-item>
......@@ -28,7 +26,12 @@
{ rules: [{ required: true, message: '请输入密码!' }] },
]"
>
<a-input type="password" placeholder="密码" size="large">
<a-input
v-model="post.password"
type="password"
placeholder="密码"
size="large"
>
<a-icon type="lock" style="color: rgba(0, 0, 0, 0.25)" />
</a-input>
</a-form-item>
......@@ -91,6 +94,7 @@
class="submit"
type="primary"
htmlType="submit"
@click="doLogin"
>
登录
</a-button>
......@@ -123,14 +127,21 @@ import {
} from "ant-design-vue";
import SendCaptchaButton from "@/components/SendCaptchaButton";
// import { mapGetters } from "vuex";
import { postLogin } from "@/api/openapi";
export default {
name: "ai-login",
data: () => ({
activeKey: "2",
activeKey: "1",
active: [],
submitting: false,
autoLogin: false,
start: false,
post: {
account: null,
password: null,
},
}),
components: {
AForm: Form,
......@@ -145,7 +156,22 @@ export default {
ACol: Col,
ASendCaptchaButton: SendCaptchaButton,
},
beforeCreate() {
this.form = this.$form.createForm(this, {});
},
methods: {
doLogin() {
postLogin(this.post)
.then((res) => {
this.$store.commit("frontend/login/setToken", res.data.token);
this.$store.commit("frontend/login/setUserInfo", { uuid: res.data.uuid, name: res.data.name });
message.success(res.msg)
this.$router.push({ path: "/" });
})
.catch((err) => {
message.error(err.msg)
});
},
onSwithAutoLogin(e) {
this.autoLogin = e.target.checked;
},
......@@ -159,18 +185,16 @@ export default {
this.active.push("captcha");
}
},
handleSubmit(e) {
window.console.log(e);
handleSubmit() {
this.form.validateFields(
this.active,
{
force: true,
},
(err, values) => {
window.console.log(values);
window.console.log(err, values);
if (!err) {
// console.log("Received values of form: ", values);
this.$router.push({ path: "/" });
console.log("Received values of form: ", values);
}
}
);
......
/*
* @Author: your name
* @Date: 2021-07-15 09:33:39
* @LastEditTime: 2021-07-15 18:29:06
* @LastEditors: your name
* @Description: In User Settings Edit
* @FilePath: \evm-store\tools\frontend\vue.config.js
*/
"use strict";
// 基础配置文件
const path = require("path");
......@@ -24,7 +32,7 @@ module.exports = {
// change xxx-api/login => mock/login
// detail: https://cli.vuejs.org/config/#devserver-proxy
"/api/v1": {
target: "http://127.0.0.1:5001/",
target: "http://127.0.0.1:3000/",
changeOrigin: true,
pathRewrite: {},
},
......
......@@ -6447,6 +6447,11 @@ js-base64@^2.1.8, js-base64@^2.1.9:
resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.6.4.tgz#f4e686c5de1ea1f867dbcad3d46d969428df98c4"
integrity sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==
js-cookie@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-2.2.1.tgz#69e106dc5d5806894562902aa5baec3744e9b2b8"
integrity sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==
js-levenshtein@^1.1.3:
version "1.1.6"
resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.6.tgz#c6cee58eb3550372df8deb85fad5ce66ce01d59d"
......
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