| | |
| | | ENV = 'development' |
| | | |
| | | # base api |
| | | VUE_APP_BASE_API = '/dev-api' |
| | | VUE_APP_BASE_API = 'http://192.168.3.88:18080/dream_test' |
| | |
| | | "test:ci": "npm run lint && npm run test:unit" |
| | | }, |
| | | "dependencies": { |
| | | "apollo-boost": "^0.4.9", |
| | | "apollo-cache-inmemory": "^1.6.6", |
| | | "apollo-client": "^2.6.10", |
| | | "apollo-link": "^1.2.14", |
| | | "apollo-link-context": "^1.0.20", |
| | | "apollo-link-http": "^1.5.17", |
| | | "axios": "0.18.1", |
| | | "core-js": "3.6.5", |
| | | "cors": "^2.8.5", |
| | | "element-ui": "2.13.2", |
| | | "graphql": "^16.9.0", |
| | | "graphql-tag": "^2.12.6", |
| | | "js-cookie": "2.2.0", |
| | | "normalize.css": "7.0.0", |
| | | "nprogress": "0.2.0", |
| | | "path-to-regexp": "2.4.0", |
| | | "vue": "2.6.10", |
| | | "vue-apollo": "^3.1.2", |
| | | "vue-router": "3.0.6", |
| | | "vue-wechat-login": "0.0.1", |
| | | "vuex": "3.1.0" |
| | | }, |
| | | "devDependencies": { |
| | |
| | | "serve-static": "1.13.2", |
| | | "svg-sprite-loader": "4.1.3", |
| | | "svgo": "1.2.2", |
| | | "vue-template-compiler": "2.6.10" |
| | | "vue-template-compiler": "2.6.10", |
| | | "vue-wxlogin": "^1.0.5" |
| | | }, |
| | | "browserslist": [ |
| | | "> 1%", |
New file |
| | |
| | | import apolloClient from "@/utils/graphql"; |
| | | import gql from "graphql-tag"; |
| | | |
| | | export function getData(params) { |
| | | return apolloClient.query({ |
| | | query: gql` |
| | | query vars($staffId: Int!, $keyword: String, $pageIn: PageIn!) { |
| | | findPlayerByStaff( |
| | | staffId: $staffId |
| | | keyword: $keyword |
| | | pageIn: $pageIn |
| | | ) { |
| | | ls { |
| | | id |
| | | name |
| | | gender |
| | | mobile |
| | | user { |
| | | id |
| | | name |
| | | wxOaOpenId |
| | | } |
| | | accs { |
| | | id |
| | | voucher { |
| | | id |
| | | voucherType |
| | | name |
| | | } |
| | | qty |
| | | freezeQty |
| | | amt |
| | | beginDate |
| | | endDate |
| | | modifyTime |
| | | } |
| | | } |
| | | pageOut { |
| | | total |
| | | index |
| | | size |
| | | } |
| | | } |
| | | } |
| | | `, |
| | | variables: params, |
| | | }); |
| | | } |
| | |
| | | |
| | | export function login(data) { |
| | | return request({ |
| | | url: '/vue-admin-template/user/login', |
| | | url: '/wx/web/login', |
| | | method: 'post', |
| | | data |
| | | }) |
| | | } |
| | | |
| | | export function getInfo(token) { |
| | | return request({ |
| | | url: '/vue-admin-template/user/info', |
| | |
| | | import Vue from 'vue' |
| | | import Vue from "vue"; |
| | | |
| | | import 'normalize.css/normalize.css' // A modern alternative to CSS resets |
| | | import "normalize.css/normalize.css"; // A modern alternative to CSS resets |
| | | |
| | | import ElementUI from 'element-ui' |
| | | import 'element-ui/lib/theme-chalk/index.css' |
| | | import ElementUI from "element-ui"; |
| | | import "element-ui/lib/theme-chalk/index.css"; |
| | | // import locale from 'element-ui/lib/locale/lang/en' // lang i18n |
| | | import locale from 'element-ui/lib/locale/lang/zh-CN'; |
| | | import '@/styles/index.scss' // global css |
| | | import locale from "element-ui/lib/locale/lang/zh-CN"; |
| | | import "@/styles/index.scss"; // global css |
| | | |
| | | import App from './App' |
| | | import store from './store' |
| | | import router from './router' |
| | | import App from "./App"; |
| | | import store from "./store"; |
| | | import router from "./router"; |
| | | |
| | | import '@/icons' // icon |
| | | import '@/permission' // permission control |
| | | import "@/icons"; // icon |
| | | import "@/permission"; // permission control |
| | | |
| | | // const cors = require('cors'); |
| | | // // 处理跨域请求 |
| | | // App.use(cors()); |
| | | // // 处理请求 |
| | | // App.use(express.json());//express.json=bodyParser.json |
| | | // App.use(express.urlencoded({ extended: true })); |
| | | /** |
| | | * If you don't want to use mock-server |
| | | * you want to use MockJs for mock api |
| | |
| | | * Currently MockJs will be used in the production environment, |
| | | * please remove it before going online ! ! ! |
| | | */ |
| | | if (process.env.NODE_ENV === 'production') { |
| | | const { mockXHR } = require('../mock') |
| | | mockXHR() |
| | | } |
| | | // if (process.env.NODE_ENV === 'production') { |
| | | // const { mockXHR } = require('../mock') |
| | | // mockXHR() |
| | | // } |
| | | Vue.use(ElementUI, { locale }); |
| | | |
| | | // set ElementUI lang to EN |
| | | Vue.use(ElementUI, { locale }) |
| | | // 如果想要中文版 element-ui,按如下方式声明 |
| | | // Vue.use(ElementUI,{ locale: zhCn }) |
| | | |
| | | Vue.config.productionTip = false |
| | | Vue.config.productionTip = false; |
| | | |
| | | new Vue({ |
| | | el: '#app', |
| | | el: "#app", |
| | | router, |
| | | store, |
| | | render: h => h(App) |
| | | }) |
| | | render: (h) => h(App), |
| | | }); |
| | |
| | | |
| | | const whiteList = ['/login'] // no redirect whitelist |
| | | |
| | | router.beforeEach(async(to, from, next) => { |
| | | // start progress bar |
| | | NProgress.start() |
| | | // router.beforeEach(async(to, from, next) => { |
| | | // // start progress bar |
| | | // NProgress.start() |
| | | |
| | | // set page title |
| | | document.title = getPageTitle(to.meta.title) |
| | | // // set page title |
| | | // document.title = getPageTitle(to.meta.title) |
| | | |
| | | // determine whether the user has logged in |
| | | const hasToken = getToken() |
| | | // // determine whether the user has logged in |
| | | // const hasToken = getToken() |
| | | |
| | | if (hasToken) { |
| | | if (to.path === '/login') { |
| | | // if is logged in, redirect to the home page |
| | | next({ path: '/' }) |
| | | NProgress.done() |
| | | } else { |
| | | const hasGetUserInfo = store.getters.name |
| | | if (hasGetUserInfo) { |
| | | next() |
| | | } else { |
| | | try { |
| | | // get user info |
| | | await store.dispatch('user/getInfo') |
| | | // if (hasToken) { |
| | | // if (to.path === '/login') { |
| | | // // if is logged in, redirect to the home page |
| | | // next({ path: '/' }) |
| | | // NProgress.done() |
| | | // } else { |
| | | // const hasGetUserInfo = store.getters.name |
| | | // if (hasGetUserInfo) { |
| | | // next() |
| | | // } else { |
| | | // try { |
| | | // // get user info |
| | | // await store.dispatch('user/getInfo') |
| | | |
| | | next() |
| | | } catch (error) { |
| | | // remove token and go to login page to re-login |
| | | await store.dispatch('user/resetToken') |
| | | Message.error(error || 'Has Error') |
| | | next(`/login?redirect=${to.path}`) |
| | | NProgress.done() |
| | | } |
| | | } |
| | | } |
| | | } else { |
| | | /* has no token*/ |
| | | // next() |
| | | // } catch (error) { |
| | | // // remove token and go to login page to re-login |
| | | // await store.dispatch('user/resetToken') |
| | | // Message.error(error || 'Has Error') |
| | | // next(`/login?redirect=${to.path}`) |
| | | // NProgress.done() |
| | | // } |
| | | // } |
| | | // } |
| | | // } else { |
| | | // /* has no token*/ |
| | | |
| | | if (whiteList.indexOf(to.path) !== -1) { |
| | | // in the free login whitelist, go directly |
| | | next() |
| | | } else { |
| | | // other pages that do not have permission to access are redirected to the login page. |
| | | next(`/login?redirect=${to.path}`) |
| | | NProgress.done() |
| | | } |
| | | } |
| | | }) |
| | | // if (whiteList.indexOf(to.path) !== -1) { |
| | | // // in the free login whitelist, go directly |
| | | // next() |
| | | // } else { |
| | | // // other pages that do not have permission to access are redirected to the login page. |
| | | // next(`/login?redirect=${to.path}`) |
| | | // NProgress.done() |
| | | // } |
| | | // } |
| | | // }) |
| | | |
| | | router.afterEach(() => { |
| | | // finish progress bar |
| | |
| | | name: 'Development', |
| | | component: () => import('@/views/development/index'), |
| | | meta: { title: '成长', icon: 'tree' } |
| | | }, |
| | | { |
| | | path: 'integral', |
| | | name: 'Integral', |
| | | component: () => import('@/views/integral/index'), |
| | | meta: { title: '积分', icon: 'tree' } |
| | | }, |
| | | { |
| | | path: 'rollCall', |
| | | name: 'RollCall', |
| | | component: () => import('@/views/rollCall/index'), |
| | | meta: { title: '点评', icon: 'tree' } |
| | | } |
| | | ] |
| | | }, |
New file |
| | |
| | | // import ApolloClient from 'apollo-boost'; |
| | | |
| | | // const apolloClient = new ApolloClient({ |
| | | // uri: 'http://127.0.0.1:7001/graphql' |
| | | // }) |
| | | |
| | | // export default apolloClient; |
| | | // 定义不同请求地址 |
| | | const EFORMURI = "http://192.168.3.88:18080/dream_test/graphql"; |
| | | const IOTURI = "https://www.9village.cn/dream_test" + "/graphql"; |
| | | // import ApolloClient from 'apollo-boost' //引入apollo-boost插件 |
| | | import { ApolloClient } from "apollo-client"; |
| | | import { createHttpLink } from "apollo-link-http"; |
| | | import { InMemoryCache } from "apollo-cache-inmemory"; |
| | | import { ApolloLink } from "apollo-link"; |
| | | |
| | | const httpLink = createHttpLink({ |
| | | uri: EFORMURI, //配置api调用连接 |
| | | }); |
| | | |
| | | const middlewareLink = new ApolloLink((operation, forward) => { |
| | | operation.setContext({ |
| | | headers: { |
| | | Authorization: 'eyJhbGciOiJIUzI1NiJ9.eyJleHBUaW1lIjoiMjAyNC8wNy8yNSAxMTozOSIsInVzZXJJZCI6MSwianRpIjoiZGVkZWRlMWQtYTU4MC00NDkxLWI0YzAtMjA5ODRjYTk3NmE3IiwiaWF0IjoxNzIxODcxNTYyLCJzdWIiOiJ5Y2wiLCJleHAiOjE3MjE4Nzg3NjJ9.gvEk8RHvJD7QQjr83XVwPe9msqEeVITXg3hIJRaNubI', |
| | | staffId: "1680", |
| | | playerId: '3350', |
| | | }, |
| | | }); //request拦截器 |
| | | |
| | | return forward(operation).map((response) => { |
| | | return response; |
| | | }); //response拦截器,但是此处并不能对错误响应进行拦截 |
| | | }); |
| | | |
| | | const authLink = middlewareLink.concat(httpLink); |
| | | |
| | | const defaultOptions = { |
| | | watchQuery: { |
| | | fetchPolicy: "network-only", |
| | | errorPolicy: "ignore", |
| | | }, |
| | | query: { |
| | | fetchPolicy: "network-only", |
| | | errorPolicy: "all", |
| | | }, |
| | | }; |
| | | |
| | | const apolloClient = new ApolloClient({ |
| | | link: authLink, |
| | | cache: new InMemoryCache(), |
| | | connectToDevTools: true, |
| | | defaultOptions: defaultOptions, |
| | | }); |
| | | // const apolloClient = new ApolloClient({ |
| | | // uri: 'https://countries.trevorblades.com/', |
| | | // headers:{ |
| | | // Authorization: 'eyJhbGciOiJIUzI1NiJ9.eyJleHBUaW1lIjoiMjAyNC8wNy8yNSAxMTozOSIsInVzZXJJZCI6MSwianRpIjoiZGVkZWRlMWQtYTU4MC00NDkxLWI0YzAtMjA5ODRjYTk3NmE3IiwiaWF0IjoxNzIxODcxNTYyLCJzdWIiOiJ5Y2wiLCJleHAiOjE3MjE4Nzg3NjJ9.gvEk8RHvJD7QQjr83XVwPe9msqEeVITXg3hIJRaNubI', |
| | | // staffId: "1680", |
| | | // playerId: '3350', |
| | | // } |
| | | // }) |
| | | //导出实例 |
| | | export default apolloClient; |
| | |
| | | element-loading-text="Loading" |
| | | fit |
| | | > |
| | | <el-table-column label="学员"> |
| | | <el-table-column label="课程"> |
| | | <template slot-scope=""> xxxxx </template> |
| | | </el-table-column> |
| | | <el-table-column label="时间" width="80"> |
| | | <template slot-scope=""> 男 </template> |
| | | </el-table-column> |
| | | <el-table-column label="标题" width="200"> |
| | | <el-table-column label="学员数" width="200"> |
| | | <template slot-scope=""> 10086 </template> |
| | | </el-table-column> |
| | | <el-table-column label="点评老师" width="200"> |
| | | <el-table-column label="已记录数" width="200"> |
| | | <template slot-scope=""> asfiaf </template> |
| | | </el-table-column> |
| | | <el-table-column label="操作" width=""> |
| | | <template slot-scope=""> 查看 </template> |
| | | <template slot-scope=""> 记录 </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-tab-pane> |
| | |
| | | </template> |
| | | |
| | | <script> |
| | | import { mapGetters } from 'vuex' |
| | | import { mapGetters } from "vuex"; |
| | | import { login } from "@/api/user"; |
| | | |
| | | export default { |
| | | name: 'Dashboard', |
| | | name: "Dashboard", |
| | | computed: { |
| | | ...mapGetters([ |
| | | 'name' |
| | | ]) |
| | | } |
| | | } |
| | | ...mapGetters(["name"]), |
| | | }, |
| | | created() { |
| | | this.getUserDate(); |
| | | }, |
| | | methods: { |
| | | getUserDate() { |
| | | console.log(123); |
| | | login({ |
| | | code: "031xHA00064oxS1Es0200cRzRF2xHA0t", |
| | | }).then((res) => { |
| | | console.log(res); |
| | | }); |
| | | }, |
| | | }, |
| | | }; |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
New file |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-tabs v-model="activeName" @tab-click="handleClick"> |
| | | <el-tab-pane label="按学员" name="first"> |
| | | <div style="display: flex; flex-direction: row-reverse"> |
| | | <div style="width: 300px"> |
| | | <el-input |
| | | placeholder="按标题搜索" |
| | | v-model="input3" |
| | | class="input-with-select" |
| | | size="small" |
| | | > |
| | | <el-button slot="append" icon="el-icon-search"></el-button> |
| | | </el-input> |
| | | </div> |
| | | </div> |
| | | <el-table |
| | | v-loading="listLoading" |
| | | :data="list" |
| | | element-loading-text="Loading" |
| | | fit |
| | | > |
| | | <el-table-column label="姓名"> |
| | | <template slot-scope=""> xxxxx </template> |
| | | </el-table-column> |
| | | <el-table-column label="积分" width="80"> |
| | | <template slot-scope=""> 男 </template> |
| | | </el-table-column> |
| | | <el-table-column label="更新时间" width="200"> |
| | | <template slot-scope=""> 10086 </template> |
| | | </el-table-column> |
| | | <el-table-column label="操作" width=""> |
| | | <template slot-scope=""> 兑换 发放 </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-tab-pane> |
| | | <el-tab-pane label="按班级" name="fourth"> |
| | | <div style="display: flex; flex-direction: row-reverse"> |
| | | <div style="width: 300px"> |
| | | <el-input |
| | | placeholder="按学员名称搜索" |
| | | v-model="input3" |
| | | class="input-with-select" |
| | | size="small" |
| | | > |
| | | <el-button slot="append" icon="el-icon-search"></el-button> |
| | | </el-input> |
| | | </div> |
| | | </div> |
| | | <el-table |
| | | v-loading="listLoading" |
| | | :data="list" |
| | | element-loading-text="Loading" |
| | | fit |
| | | > |
| | | <el-table-column label="班级"> |
| | | <template slot-scope=""> xxxxx </template> |
| | | </el-table-column> |
| | | <el-table-column label="学员人数" width="80"> |
| | | <template slot-scope=""> 男 </template> |
| | | </el-table-column> |
| | | <el-table-column label="操作" width=""> |
| | | <template slot-scope=""> 发放 </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-tab-pane> |
| | | </el-tabs> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import { getList } from "@/api/table"; |
| | | |
| | | export default { |
| | | filters: { |
| | | statusFilter(status) { |
| | | const statusMap = { |
| | | published: "success", |
| | | draft: "gray", |
| | | deleted: "danger", |
| | | }; |
| | | return statusMap[status]; |
| | | }, |
| | | }, |
| | | data() { |
| | | return { |
| | | list: null, |
| | | listLoading: true, |
| | | activeName: "first", |
| | | }; |
| | | }, |
| | | created() { |
| | | this.fetchData(); |
| | | }, |
| | | methods: { |
| | | fetchData() { |
| | | this.listLoading = true; |
| | | getList().then((response) => { |
| | | this.list = response.data.items; |
| | | this.listLoading = false; |
| | | }); |
| | | }, |
| | | }, |
| | | }; |
| | | </script> |
| | | |
| | |
| | | <template> |
| | | <div class="login-container"> |
| | | <el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" auto-complete="on" label-position="left"> |
| | | |
| | | <!-- <el-form |
| | | ref="loginForm" |
| | | :model="loginForm" |
| | | :rules="loginRules" |
| | | class="login-form" |
| | | auto-complete="on" |
| | | label-position="left" |
| | | > |
| | | <div class="title-container"> |
| | | <h3 class="title">Login Form</h3> |
| | | </div> |
| | |
| | | @keyup.enter.native="handleLogin" |
| | | /> |
| | | <span class="show-pwd" @click="showPwd"> |
| | | <svg-icon :icon-class="passwordType === 'password' ? 'eye' : 'eye-open'" /> |
| | | <svg-icon |
| | | :icon-class="passwordType === 'password' ? 'eye' : 'eye-open'" |
| | | /> |
| | | </span> |
| | | </el-form-item> |
| | | |
| | | <el-button :loading="loading" type="primary" style="width:100%;margin-bottom:30px;" @click.native.prevent="handleLogin">Login</el-button> |
| | | <el-button |
| | | :loading="loading" |
| | | type="primary" |
| | | style="width: 100%; margin-bottom: 30px" |
| | | @click.native.prevent="handleLogin" |
| | | >Login</el-button |
| | | > |
| | | |
| | | <div class="tips"> |
| | | <span style="margin-right:20px;">username: admin</span> |
| | | <span style="margin-right: 20px">username: admin</span> |
| | | <span> password: any</span> |
| | | </div> |
| | | |
| | | </el-form> |
| | | </el-form> --> |
| | | <div class="wxLogin"> |
| | | <el-card class="main_wx"> |
| | | <wxlogin |
| | | :appid="appid" |
| | | :redirect_uri="redirect_uri" |
| | | scope="snsapi_login" |
| | | :href="href" |
| | | :state="state" |
| | | ></wxlogin> |
| | | <el-button @click="handleLogin">开发环境专用偷渡按钮</el-button> |
| | | </el-card> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import { validUsername } from '@/utils/validate' |
| | | |
| | | import { validUsername } from "@/utils/validate"; |
| | | import wxlogin from "vue-wxlogin"; |
| | | export default { |
| | | name: 'Login', |
| | | name: "Login", |
| | | components: { wxlogin }, |
| | | data() { |
| | | const validateUsername = (rule, value, callback) => { |
| | | if (!validUsername(value)) { |
| | | callback(new Error('Please enter the correct user name')) |
| | | callback(new Error("Please enter the correct user name")); |
| | | } else { |
| | | callback() |
| | | callback(); |
| | | } |
| | | } |
| | | }; |
| | | const validatePassword = (rule, value, callback) => { |
| | | if (value.length < 6) { |
| | | callback(new Error('The password can not be less than 6 digits')) |
| | | callback(new Error("The password can not be less than 6 digits")); |
| | | } else { |
| | | callback() |
| | | callback(); |
| | | } |
| | | } |
| | | }; |
| | | return { |
| | | appid: "wx7103925df6236723", |
| | | redirect_uri: encodeURIComponent("https://www.9village.cn"), |
| | | state: "1", |
| | | href: "data:text/css;base64,LmltcG93ZXJCb3ggLnFyY29kZSB7CiAgICAgICAgICBib3JkZXI6IG5vbmU7CiAgICAgICAgICB3aWR0aDogMTQwcHg7CiAgICAgICAgICBoZWlnaHQ6IDE0MHB4OwogICAgICAgIH0=", // 自定义样式链接 |
| | | loginForm: { |
| | | username: 'admin', |
| | | password: '111111' |
| | | username: "admin", |
| | | password: "111111", |
| | | }, |
| | | loginRules: { |
| | | username: [{ required: true, trigger: 'blur', validator: validateUsername }], |
| | | password: [{ required: true, trigger: 'blur', validator: validatePassword }] |
| | | username: [ |
| | | { required: true, trigger: "blur", validator: validateUsername }, |
| | | ], |
| | | password: [ |
| | | { required: true, trigger: "blur", validator: validatePassword }, |
| | | ], |
| | | }, |
| | | loading: false, |
| | | passwordType: 'password', |
| | | redirect: undefined |
| | | } |
| | | passwordType: "password", |
| | | redirect: undefined, |
| | | }; |
| | | }, |
| | | watch: { |
| | | $route: { |
| | | handler: function(route) { |
| | | this.redirect = route.query && route.query.redirect |
| | | handler: function (route) { |
| | | this.redirect = route.query && route.query.redirect; |
| | | }, |
| | | immediate: true |
| | | } |
| | | immediate: true, |
| | | }, |
| | | }, |
| | | mounted() { |
| | | this.getWeChatUrl(); |
| | | }, |
| | | methods: { |
| | | getWeChatUrl() { |
| | | // api.wachatQrUrl().then(res => { |
| | | // if (res && res.code === '0000') { |
| | | // const data = res.data |
| | | // this.appid = data.appId |
| | | // this.redirect_uri = data.wxCallbackUrl + 'weChatLogin' |
| | | // } |
| | | // }) |
| | | }, |
| | | showPwd() { |
| | | if (this.passwordType === 'password') { |
| | | this.passwordType = '' |
| | | if (this.passwordType === "password") { |
| | | this.passwordType = ""; |
| | | } else { |
| | | this.passwordType = 'password' |
| | | this.passwordType = "password"; |
| | | } |
| | | this.$nextTick(() => { |
| | | this.$refs.password.focus() |
| | | }) |
| | | this.$refs.password.focus(); |
| | | }); |
| | | }, |
| | | handleLogin() { |
| | | this.$refs.loginForm.validate(valid => { |
| | | if (valid) { |
| | | this.loading = true |
| | | this.$store.dispatch('user/login', this.loginForm).then(() => { |
| | | this.$router.push({ path: this.redirect || '/' }) |
| | | this.loading = false |
| | | }).catch(() => { |
| | | this.loading = false |
| | | }) |
| | | } else { |
| | | console.log('error submit!!') |
| | | return false |
| | | } |
| | | }) |
| | | } |
| | | } |
| | | } |
| | | this.$router.push({ path: "/educational/student" }); |
| | | // this.$refs.loginForm.validate((valid) => { |
| | | // if (valid) { |
| | | // this.loading = true; |
| | | // this.$store |
| | | // .dispatch("user/login", this.loginForm) |
| | | // .then(() => { |
| | | // this.$router.push({ path: this.redirect || "/" }); |
| | | // this.loading = false; |
| | | // }) |
| | | // .catch(() => { |
| | | // this.loading = false; |
| | | // }); |
| | | // } else { |
| | | // console.log("error submit!!"); |
| | | // return false; |
| | | // } |
| | | // }); |
| | | }, |
| | | }, |
| | | }; |
| | | </script> |
| | | |
| | | <style lang="scss"> |
| | | /* 修复input 背景不协调 和光标变色 */ |
| | | /* Detail see https://github.com/PanJiaChen/vue-element-admin/pull/927 */ |
| | | |
| | | $bg:#283443; |
| | | $light_gray:#fff; |
| | | $bg: #283443; |
| | | $light_gray: #fff; |
| | | $cursor: #fff; |
| | | |
| | | @supports (-webkit-mask: none) and (not (cater-color: $cursor)) { |
| | |
| | | |
| | | /* reset element-ui css */ |
| | | .login-container { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | .el-input { |
| | | display: inline-block; |
| | | height: 47px; |
| | |
| | | color: #454545; |
| | | } |
| | | } |
| | | #weixin{ |
| | | /* background-color: #fcf; */ |
| | | display: flex; |
| | | justify-content: center; |
| | | margin-top: -20px; |
| | | } |
| | | </style> |
| | | |
| | | <style lang="scss" scoped> |
| | | $bg:#2d3a4b; |
| | | $dark_gray:#889aa4; |
| | | $light_gray:#eee; |
| | | $bg: #ffffff; |
| | | $dark_gray: #889aa4; |
| | | $light_gray: #eee; |
| | | |
| | | .login-container { |
| | | min-height: 100%; |
New file |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-tabs v-model="activeName" @tab-click="handleClick"> |
| | | <el-tab-pane label="按学员" name="first"> |
| | | <div style="display: flex; flex-direction: row-reverse"> |
| | | <div style="width: 300px"> |
| | | <el-input |
| | | placeholder="按标题搜索" |
| | | v-model="input3" |
| | | class="input-with-select" |
| | | size="small" |
| | | > |
| | | <el-button slot="append" icon="el-icon-search"></el-button> |
| | | </el-input> |
| | | </div> |
| | | </div> |
| | | <el-table |
| | | v-loading="listLoading" |
| | | :data="list" |
| | | element-loading-text="Loading" |
| | | fit |
| | | > |
| | | <el-table-column label="姓名"> |
| | | <template slot-scope=""> xxxxx </template> |
| | | </el-table-column> |
| | | <el-table-column label="课包/会员卡" width="80"> |
| | | <template slot-scope=""> 男 </template> |
| | | </el-table-column> |
| | | <el-table-column label="上课日期" width="200"> |
| | | <template slot-scope=""> 10086 </template> |
| | | </el-table-column> |
| | | <el-table-column label="课程时长" width="200"> |
| | | <template slot-scope=""> 10086 </template> |
| | | </el-table-column> |
| | | <el-table-column label="开始时间" width="200"> |
| | | <template slot-scope=""> 10086 </template> |
| | | </el-table-column> |
| | | <el-table-column label="课消数量" width="200"> |
| | | <template slot-scope=""> 10086 </template> |
| | | </el-table-column> |
| | | <el-table-column label="操作" width=""> |
| | | <template slot-scope=""> 兑换 发放 </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-tab-pane> |
| | | <el-tab-pane label="按班级" name="fourth"> |
| | | <div style="display: flex; flex-direction: row-reverse"> |
| | | <div style="width: 300px"> |
| | | <el-input |
| | | placeholder="按学员名称搜索" |
| | | v-model="input3" |
| | | class="input-with-select" |
| | | size="small" |
| | | > |
| | | <el-button slot="append" icon="el-icon-search"></el-button> |
| | | </el-input> |
| | | </div> |
| | | </div> |
| | | <el-table |
| | | v-loading="listLoading" |
| | | :data="list" |
| | | element-loading-text="Loading" |
| | | fit |
| | | > |
| | | <el-table-column label="班级"> |
| | | <template slot-scope=""> xxxxx </template> |
| | | </el-table-column> |
| | | <el-table-column label="学员人数" width="80"> |
| | | <template slot-scope=""> 男 </template> |
| | | </el-table-column> |
| | | <el-table-column label="操作" width=""> |
| | | <template slot-scope=""> 发放 </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-tab-pane> |
| | | </el-tabs> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import { getList } from "@/api/table"; |
| | | |
| | | export default { |
| | | filters: { |
| | | statusFilter(status) { |
| | | const statusMap = { |
| | | published: "success", |
| | | draft: "gray", |
| | | deleted: "danger", |
| | | }; |
| | | return statusMap[status]; |
| | | }, |
| | | }, |
| | | data() { |
| | | return { |
| | | list: null, |
| | | listLoading: true, |
| | | activeName: "first", |
| | | }; |
| | | }, |
| | | created() { |
| | | this.fetchData(); |
| | | }, |
| | | methods: { |
| | | fetchData() { |
| | | this.listLoading = true; |
| | | getList().then((response) => { |
| | | this.list = response.data.items; |
| | | this.listLoading = false; |
| | | }); |
| | | }, |
| | | }, |
| | | }; |
| | | </script> |
| | | |
| | |
| | | <el-tab-pane label="已过期" name="third" /> |
| | | <el-tab-pane label="已停用" name="fourth" /> |
| | | </el-tabs> |
| | | <div style="display: flex; flex-direction: row-reverse;"> |
| | | <div style="width: 300px;"> |
| | | <div style="display: flex; flex-direction: row-reverse"> |
| | | <div style="width: 300px"> |
| | | <el-input |
| | | placeholder="按姓名搜索" |
| | | v-model="input3" |
| | |
| | | <el-table-column label="账户" width=""> |
| | | <template slot-scope=""> asfiaf </template> |
| | | </el-table-column> |
| | | {{ accountList }} |
| | | <!-- <el-table-column label="Author" width="110" align="center"> |
| | | <template slot-scope="scope"> |
| | | <span>{{ scope.row.author }}</span> |
| | |
| | | </template> |
| | | |
| | | <script> |
| | | import { getList } from "@/api/table"; |
| | | import { getData } from "@/api/student"; |
| | | |
| | | export default { |
| | | filters: { |
| | |
| | | list: null, |
| | | listLoading: true, |
| | | activeName: "first", |
| | | data: { |
| | | staffId: "1680", |
| | | keyword: "", |
| | | pageIn: { |
| | | //可选,如果是分页查询,需要加上。 |
| | | index: 1, //必选 |
| | | size: 20, //每页的大小。默认20 |
| | | }, |
| | | }, |
| | | }; |
| | | }, |
| | | created() { |
| | |
| | | methods: { |
| | | fetchData() { |
| | | this.listLoading = true; |
| | | getList().then((response) => { |
| | | getData(this.data).then((response) => { |
| | | this.list = response.data.items; |
| | | this.listLoading = false; |
| | | }); |
| | |
| | | 'use strict' |
| | | const path = require('path') |
| | | const defaultSettings = require('./src/settings.js') |
| | | "use strict"; |
| | | const path = require("path"); |
| | | const defaultSettings = require("./src/settings.js"); |
| | | |
| | | function resolve(dir) { |
| | | return path.join(__dirname, dir) |
| | | return path.join(__dirname, dir); |
| | | } |
| | | |
| | | const name = defaultSettings.title || 'vue Admin Template' // page title |
| | | const name = defaultSettings.title || "vue Admin Template"; // page title |
| | | |
| | | // If your port is set to 80, |
| | | // use administrator privileges to execute the command line. |
| | | // For example, Mac: sudo npm run |
| | | // You can change the port by the following methods: |
| | | // port = 9528 npm run dev OR npm run dev --port = 9528 |
| | | const port = process.env.port || process.env.npm_config_port || 9528 // dev port |
| | | const port = process.env.port || process.env.npm_config_port || 9528; // dev port |
| | | |
| | | // All configuration item explanations can be find in https://cli.vuejs.org/config/ |
| | | module.exports = { |
| | |
| | | * In most cases please use '/' !!! |
| | | * Detail: https://cli.vuejs.org/config/#publicpath |
| | | */ |
| | | publicPath: '/', |
| | | outputDir: 'dist', |
| | | assetsDir: 'static', |
| | | lintOnSave: process.env.NODE_ENV === 'development', |
| | | publicPath: "/", |
| | | outputDir: "dist", |
| | | assetsDir: "static", |
| | | lintOnSave: process.env.NODE_ENV === "development", |
| | | productionSourceMap: false, |
| | | devServer: { |
| | | port: port, |
| | | open: true, |
| | | overlay: { |
| | | warnings: false, |
| | | errors: true |
| | | errors: true, |
| | | }, |
| | | before: require('./mock/mock-server.js') |
| | | proxy: { |
| | | [process.env.VUE_APP_BASE_API]: { |
| | | // 匹配所有以 '/dev-api'开头的请求路径 |
| | | target: "http://192.168.3.88:18080/dream_test", //类似于Nginx反向代理 |
| | | changeOrigin: true, // 支持跨域 |
| | | pathRewrite: { |
| | | // 重写路径: 去掉路径中开头的'/dev-api' |
| | | ["^" + process.env.VUE_APP_BASE_API]: "", |
| | | }, |
| | | }, |
| | | }, |
| | | }, |
| | | configureWebpack: { |
| | | // provide the app's title in webpack's name field, so that |
| | |
| | | name: name, |
| | | resolve: { |
| | | alias: { |
| | | '@': resolve('src') |
| | | } |
| | | } |
| | | "@": resolve("src"), |
| | | }, |
| | | }, |
| | | }, |
| | | chainWebpack(config) { |
| | | // it can improve the speed of the first screen, it is recommended to turn on preload |
| | | config.plugin('preload').tap(() => [ |
| | | config.plugin("preload").tap(() => [ |
| | | { |
| | | rel: 'preload', |
| | | rel: "preload", |
| | | // to ignore runtime.js |
| | | // https://github.com/vuejs/vue-cli/blob/dev/packages/@vue/cli-service/lib/config/app.js#L171 |
| | | fileBlacklist: [/\.map$/, /hot-update\.js$/, /runtime\..*\.js$/], |
| | | include: 'initial' |
| | | } |
| | | ]) |
| | | include: "initial", |
| | | }, |
| | | ]); |
| | | |
| | | // when there are many pages, it will cause too many meaningless requests |
| | | config.plugins.delete('prefetch') |
| | | config.plugins.delete("prefetch"); |
| | | |
| | | // set svg-sprite-loader |
| | | config.module.rule("svg").exclude.add(resolve("src/icons")).end(); |
| | | config.module |
| | | .rule('svg') |
| | | .exclude.add(resolve('src/icons')) |
| | | .end() |
| | | config.module |
| | | .rule('icons') |
| | | .rule("icons") |
| | | .test(/\.svg$/) |
| | | .include.add(resolve('src/icons')) |
| | | .include.add(resolve("src/icons")) |
| | | .end() |
| | | .use('svg-sprite-loader') |
| | | .loader('svg-sprite-loader') |
| | | .use("svg-sprite-loader") |
| | | .loader("svg-sprite-loader") |
| | | .options({ |
| | | symbolId: 'icon-[name]' |
| | | symbolId: "icon-[name]", |
| | | }) |
| | | .end() |
| | | .end(); |
| | | |
| | | config |
| | | .when(process.env.NODE_ENV !== 'development', |
| | | config => { |
| | | config |
| | | .plugin('ScriptExtHtmlWebpackPlugin') |
| | | .after('html') |
| | | .use('script-ext-html-webpack-plugin', [{ |
| | | config.when(process.env.NODE_ENV !== "development", (config) => { |
| | | config |
| | | .plugin("ScriptExtHtmlWebpackPlugin") |
| | | .after("html") |
| | | .use("script-ext-html-webpack-plugin", [ |
| | | { |
| | | // `runtime` must same as runtimeChunk name. default is `runtime` |
| | | inline: /runtime\..*\.js$/ |
| | | }]) |
| | | .end() |
| | | config |
| | | .optimization.splitChunks({ |
| | | chunks: 'all', |
| | | cacheGroups: { |
| | | libs: { |
| | | name: 'chunk-libs', |
| | | test: /[\\/]node_modules[\\/]/, |
| | | priority: 10, |
| | | chunks: 'initial' // only package third parties that are initially dependent |
| | | }, |
| | | elementUI: { |
| | | name: 'chunk-elementUI', // split elementUI into a single package |
| | | priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app |
| | | test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm |
| | | }, |
| | | commons: { |
| | | name: 'chunk-commons', |
| | | test: resolve('src/components'), // can customize your rules |
| | | minChunks: 3, // minimum common number |
| | | priority: 5, |
| | | reuseExistingChunk: true |
| | | } |
| | | } |
| | | }) |
| | | // https:// webpack.js.org/configuration/optimization/#optimizationruntimechunk |
| | | config.optimization.runtimeChunk('single') |
| | | } |
| | | ) |
| | | } |
| | | } |
| | | inline: /runtime\..*\.js$/, |
| | | }, |
| | | ]) |
| | | .end(); |
| | | config.optimization.splitChunks({ |
| | | chunks: "all", |
| | | cacheGroups: { |
| | | libs: { |
| | | name: "chunk-libs", |
| | | test: /[\\/]node_modules[\\/]/, |
| | | priority: 10, |
| | | chunks: "initial", // only package third parties that are initially dependent |
| | | }, |
| | | elementUI: { |
| | | name: "chunk-elementUI", // split elementUI into a single package |
| | | priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app |
| | | test: /[\\/]node_modules[\\/]_?element-ui(.*)/, // in order to adapt to cnpm |
| | | }, |
| | | commons: { |
| | | name: "chunk-commons", |
| | | test: resolve("src/components"), // can customize your rules |
| | | minChunks: 3, // minimum common number |
| | | priority: 5, |
| | | reuseExistingChunk: true, |
| | | }, |
| | | }, |
| | | }); |
| | | // https:// webpack.js.org/configuration/optimization/#optimizationruntimechunk |
| | | config.optimization.runtimeChunk("single"); |
| | | }); |
| | | }, |
| | | }; |