Commit aec557e9 authored by Junling Bu's avatar Junling Bu
Browse files

chore[litemall-vue]: 参考litemall-admin结构,重新调整litemall-vue的src结构

parent 8d262f8b
import dayjs from 'dayjs';
import { isNumber } from 'lodash';
export const dateFormat = (value, format = 'YYYY-MM-DD') =>
value ? dayjs(value * 1000).format(format) : '';
export const yuan = value =>
isNumber(value) ? ${(value / 100).toFixed(2)}` : value;
export default {
install(Vue) {
Vue.filter('yuan', yuan);
Vue.filter('dateFormat', dateFormat);
}
};
import dayjs from 'dayjs';
import { isNumber } from 'lodash';
export const dateFormat = (value, format = 'YYYY-MM-DD') =>
value ? dayjs(value * 1000).format(format) : '';
export const yuan = value =>
isNumber(value) ? ${(value / 100).toFixed(2)}` : value;
export default {
install(Vue) {
Vue.filter('yuan', yuan);
Vue.filter('dateFormat', dateFormat);
}
};
import Vue from 'vue';
import App from './App.vue';
import router from './vue/router';
import router from './router';
import store from './store'
import './assets/scss/global.scss';
import '@/assets/scss/iconfont/iconfont.css';
import VeeValidate, { Validator } from 'vee-validate';
import VueCountdown from '@/vue/plugins/vue-countdown';
import VueCountdown from '@/plugins/vue-countdown';
import zhCN from 'vee-validate/dist/locale/zh_CN';
import axios from '@/vue/plugins/axios';
import filters from '@/vue/filter';
import axios from '@/plugins/axios';
import filters from '@/filter';
Vue.use(VueCountdown);
Vue.use(axios);
......@@ -41,5 +42,6 @@ Vue.config.productionTip = false;
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app');
export default {
props: {
goods: {
type: Object,
default: () => ({})
}
},
computed: {
goodsStatusToMe() {
const is_buy = this.goods.is_buy;
const is_collect = this.goods.is_collect;
return is_buy ? '我购买过' : is_collect ? '我收藏过' : '';
}
},
methods: {
OnClick() {
this.$emit('click');
}
}
};
export default {
props: {
goods: {
type: Object,
default: () => ({})
}
},
computed: {
goodsStatusToMe() {
const is_buy = this.goods.is_buy;
const is_collect = this.goods.is_collect;
return is_buy ? '我购买过' : is_collect ? '我收藏过' : '';
}
},
methods: {
OnClick() {
this.$emit('click');
}
}
};
export default {
data() {
return {
pages: {
perPage: 8,
currPage: 1,
pageCount: 1
},
loading: false,
finished: false,
isEmpty: false
};
},
methods: {
async resetInit() {
this.resetData();
const page = await this.initData();
this.$nextTick(() => {
this.setPages(page);
});
},
isFinished() {
this.finished = true;
this.loading = false;
},
async loadMore() {
console.log('loadmore');
const {
pages: { pageCount, currPage }
} = this;
const finish = pageCount < currPage;
if (finish) {
this.isFinished();
} else {
this.setPages(await this.initData(true));
}
this.loading = false;
},
nextPage(pageCount = 1) {
this.pages.currPage += 1;
this.pages.pageCount = pageCount;
this.loading = false;
},
setPages(page = {}) {
this.isEmpty = page.totalCount === 0;
if (page.totalCount <= this.pages.perPage) {
// 不满一页
this.isFinished();
} else {
// 下一页
this.nextPage(page.pageCount);
}
},
resetData() {
this.pages = {
perPage: 8,
currPage: 1,
pageCount: 1
};
this.loading = true;
this.finished = false;
this.isEmpty = false;
}
}
};
export default {
data() {
return {
pages: {
perPage: 8,
currPage: 1,
pageCount: 1
},
loading: false,
finished: false,
isEmpty: false
};
},
methods: {
async resetInit() {
this.resetData();
const page = await this.initData();
this.$nextTick(() => {
this.setPages(page);
});
},
isFinished() {
this.finished = true;
this.loading = false;
},
async loadMore() {
console.log('loadmore');
const {
pages: { pageCount, currPage }
} = this;
const finish = pageCount < currPage;
if (finish) {
this.isFinished();
} else {
this.setPages(await this.initData(true));
}
this.loading = false;
},
nextPage(pageCount = 1) {
this.pages.currPage += 1;
this.pages.pageCount = pageCount;
this.loading = false;
},
setPages(page = {}) {
this.isEmpty = page.totalCount === 0;
if (page.totalCount <= this.pages.perPage) {
// 不满一页
this.isFinished();
} else {
// 下一页
this.nextPage(page.pageCount);
}
},
resetData() {
this.pages = {
perPage: 8,
currPage: 1,
pageCount: 1
};
this.loading = true;
this.finished = false;
this.isEmpty = false;
}
}
};
import axios from 'axios';
import _ from 'lodash';
import qs from 'qs';
import { Dialog, Toast } from 'vant';
import Vue from 'vue';
Vue.use(Toast);
const instance = axios.create({
timeout: 5000,
baseURL: ''
});
instance.interceptors.request.use(
config => {
if (!config.headers['X-Litemall-Token']) {
config.headers['X-Litemall-Token'] = `${window.localStorage.getItem(
'Authorization'
) || ''}`;
}
return config;
},
err => Promise.reject(err)
);
instance.interceptors.response.use(
res => {
let litemall = _.has(res.data, 'errno') && res.data.errno !== 0;
let oldmall = _.has(res.data, 'success') && !res.data.success;
if (litemall || oldmall) {
switch (res.data.code || res.data.errno) {
case 422: {
const flag = Array.isArray(res.data.data) && res.data.data.length;
Dialog.alert({
message: flag ? res.data.data[0].message : res.data.message
});
break;
}
case 401:
break;
case 404:
break;
case 740: {
Toast.fail('优惠券已经领取过');
break;
}
case 501: {
Toast.fail('请登录');
setTimeout(() => {
window.location = '#/login/'
}, 1500)
break;
}
default:
Toast.fail(res.data.errmsg)
}
return Promise.reject(res);
}
return res;
},
error => {
Dialog.alert({
title: '警告',
message: error.message
});
return Promise.reject(error);
}
);
const post = (url, data, config = {}) => instance.post(url, data, config);
const put = (url, data, config = {}) => instance.put(url, data, config);
const get = (url, params, config = {}) =>
instance.get(url, {
params,
...config
});
const deleteMethod = (url, config = {}) =>
instance({
url,
method: 'delete',
...config
});
export default {
install(Vue) {
Vue.prototype.$reqGet = get;
Vue.prototype.$reqPost = post;
Vue.prototype.$reqPut = put;
Vue.prototype.$reqDel = deleteMethod;
}
};
import axios from 'axios';
import _ from 'lodash';
import qs from 'qs';
import { Dialog, Toast } from 'vant';
import Vue from 'vue';
Vue.use(Toast);
const instance = axios.create({
timeout: 5000,
baseURL: ''
});
instance.interceptors.request.use(
config => {
if (!config.headers['X-Litemall-Token']) {
config.headers['X-Litemall-Token'] = `${window.localStorage.getItem(
'Authorization'
) || ''}`;
}
return config;
},
err => Promise.reject(err)
);
instance.interceptors.response.use(
res => {
let litemall = _.has(res.data, 'errno') && res.data.errno !== 0;
let oldmall = _.has(res.data, 'success') && !res.data.success;
if (litemall || oldmall) {
switch (res.data.code || res.data.errno) {
case 422: {
const flag = Array.isArray(res.data.data) && res.data.data.length;
Dialog.alert({
message: flag ? res.data.data[0].message : res.data.message
});
break;
}
case 401:
break;
case 404:
break;
case 740: {
Toast.fail('优惠券已经领取过');
break;
}
case 501: {
Toast.fail('请登录');
setTimeout(() => {
window.location = '#/login/'
}, 1500)
break;
}
default:
Toast.fail(res.data.errmsg)
}
return Promise.reject(res);
}
return res;
},
error => {
Dialog.alert({
title: '警告',
message: error.message
});
return Promise.reject(error);
}
);
const post = (url, data, config = {}) => instance.post(url, data, config);
const put = (url, data, config = {}) => instance.put(url, data, config);
const get = (url, params, config = {}) =>
instance.get(url, {
params,
...config
});
const deleteMethod = (url, config = {}) =>
instance({
url,
method: 'delete',
...config
});
export default {
install(Vue) {
Vue.prototype.$reqGet = get;
Vue.prototype.$reqPost = post;
Vue.prototype.$reqPut = put;
Vue.prototype.$reqDel = deleteMethod;
}
};
import VueCountdown from '@xkeshi/vue-countdown';
export default {
install(Vue) {
Vue.component('countdown', VueCountdown);
}
};
import VueCountdown from '@xkeshi/vue-countdown';
export default {
install(Vue) {
Vue.component('countdown', VueCountdown);
}
};
const Tabbar = () =>
import(/* webpackChunkName: "Tabbar" */ '@/vue/components/Tabbar/');
import asyncLoader from 'core/async-loader';
export default [
{
path: '/',
name: 'home',
components: {
default: asyncLoader('home/tabbar-home'),
tabbar: Tabbar
},
meta: {
keepAlive: true
}
},
{
path: '*',
redirect: {
name: 'home'
}
}
];
const Tabbar = () => import('@/components/Tabbar/');
export default [
{
path: '/',
name: 'home',
components: {
default: () => import('@/views/home/tabbar-home'),
tabbar: Tabbar
},
meta: {
keepAlive: true
}
},
{
path: '*',
redirect: {
name: 'home'
}
}
];
import Vue from 'vue';
import Router from 'vue-router';
import { getLocalStorage } from '@/core/utils/local-storage';
import home from './home';
import items from './items';
import user from './user';
import order from './order';
import login from './login';
Vue.use(Router);
const RouterModel = new Router({
routes: [...home, ...items, ...user, ...order, ...login]
});
RouterModel.beforeEach((to, from, next) => {
const { Authorization, user_id } = getLocalStorage(
'Authorization',
'user_id'
);
if (!Authorization && !user_id) {
if (to.meta.login) {
next({ name: 'login', query: { redirect: to.name } });
return;
}
}
next();
});
export default RouterModel;
import Vue from 'vue';
import Router from 'vue-router';
import { getLocalStorage } from '@/utils/local-storage';
import home from './home';
import items from './items';
import user from './user';
import order from './order';
import login from './login';
Vue.use(Router);
const RouterModel = new Router({
routes: [...home, ...items, ...user, ...order, ...login]
});
RouterModel.beforeEach((to, from, next) => {
const { Authorization, user_id } = getLocalStorage(
'Authorization',
'user_id'
);
if (!Authorization && !user_id) {
if (to.meta.login) {
next({ name: 'login', query: { redirect: to.name } });
return;
}
}
next();
});
export default RouterModel;
import asyncLoader from 'core/async-loader';
const Tabbar = () =>
import(/* webpackChunkName: "Tabbar" */ '@/vue/components/Tabbar/');
export default [
{
path: '/items',
name: 'class',
meta: {
keepAlive: true
},
components: {
default: asyncLoader('items/tabbar-class'),
tabbar: Tabbar
}
},
{
path: '/items/search',
name: 'search',
meta: {
keepAlive: true
},
component: asyncLoader('items/search')
},
{
path: '/items/search/result',
name: 'search-result',
meta: {
keepAlive: true
},
component: asyncLoader('items/search-result'),
props: route => route.query
},
{
path: '/items/detail/:itemId',
name: 'detail',
props: true,
component: asyncLoader('items/detail')
},
{
path: '/items/list',
name: 'list',
component: asyncLoader('items/list'),
props: route => ({
itemClass: +route.query.itemClass
})
}
];
const Tabbar = () =>
import(/* webpackChunkName: "Tabbar" */ '@/components/Tabbar/');
export default [
{
path: '/items',
name: 'class',
meta: {
keepAlive: true
},
components: {
default: () => import('@/views/items/tabbar-class'),
tabbar: Tabbar
}
},
{
path: '/items/search',
name: 'search',
meta: {
keepAlive: true
},
component: () => import('@/views/items/search')
},
{
path: '/items/search/result',
name: 'search-result',
meta: {
keepAlive: true
},
component: () => import('@/views/items/search-result'),
props: route => route.query
},
{
path: '/items/detail/:itemId',
name: 'detail',
props: true,
component: () => import('@/views/items/detail')
},
{
path: '/items/list',
name: 'list',
component: () => import('@/views/items/list'),
props: route => ({
itemClass: +route.query.itemClass
})
}
];
import asyncLoader from 'core/async-loader';
const login = asyncLoader('login/login');
const registerGetCode = asyncLoader('login/register-getCode');
const registerSubmit = asyncLoader('login/register-submit');
const registerStatus = asyncLoader('login/register-status');
const forget = asyncLoader('login/forget');
const forgetReset = asyncLoader('login/forget-reset');
const forgetStatus = asyncLoader('login/forget-status');
export default [
{
path: '/login',
name: 'login',
component: login
},
{
path: '/login/registerGetCode',
name: 'registerGetCode',
component: registerGetCode
},
{
path: '/login/registerSubmit',
name: 'registerSubmit',
component: registerSubmit
},
{
path: '/login/registerStatus/:status',
name: 'registerStatus',
props: true,
component: registerStatus
},
{
path: '/login/forget',
name: 'forget',
component: forget
},
{
path: '/login/forget/reset',
name: 'forgetReset',
component: forgetReset
},
{
path: '/login/forget/reset/:status',
name: 'forgetStatus',
props: true,
component: forgetStatus
}
];
export default [
{
path: '/login',
name: 'login',
component: () => import('@/views/login/login')
},
{
path: '/login/registerGetCode',
name: 'registerGetCode',
component: () => import('@/views/login/register-getCode')
},
{
path: '/login/registerSubmit',
name: 'registerSubmit',
component: () => import('@/views/login/register-submit')
},
{
path: '/login/registerStatus/:status',
name: 'registerStatus',
props: true,
component: () => import('@/views/login/register-status')
},
{
path: '/login/forget',
name: 'forget',
component: () => import('@/views/login/forget')
},
{
path: '/login/forget/reset',
name: 'forgetReset',
component: () => import('@/views/login/forget-reset')
},
{
path: '/login/forget/reset/:status',
name: 'forgetStatus',
props: true,
component: () => import('@/views/login/forget-status')
}
];
import asyncLoader from 'core/async-loader';
const tab_cart = asyncLoader('order/tabbar-cart');
const PlaceOrderEntity = asyncLoader('order/place-order-entity');
const orderDetail = asyncLoader('order/orderDetail');
const PlaceOrderVirtual = asyncLoader('order/place-order-virtual');
const Payment = asyncLoader('order/payment');
const PaymentStatus = asyncLoader('order/payment-status');
const Tabbar = () =>
import(/* webpackChunkName: "Tabbar" */ '@/vue/components/Tabbar/');
export default [
{
path: '/order',
name: 'cart',
meta: {
login: true
},
components: { default: tab_cart, tabbar: Tabbar }
},
{
path: '/order/placeOrderEntity',
name: 'placeOrderEntity',
component: PlaceOrderEntity
},
{
path: '/order/orderDetail',
name: 'orderDetail',
component: orderDetail
},
{
path: '/order/placeOrderVirtual',
name: 'placeOrderVirtual',
component: PlaceOrderVirtual
},
{
path: '/order/payment',
name: 'payment',
component: Payment
},
{
path: '/order/payment/:status',
name: 'paymentStatus',
component: PaymentStatus,
props: true
}
];
const Tabbar = () => import('@/components/Tabbar/');
export default [
{
path: '/order',
name: 'cart',
meta: {
login: true
},
components: {
default: () => import('@/views/order/tabbar-cart'),
tabbar: Tabbar
}
},
{
path: '/order/placeOrderEntity',
name: 'placeOrderEntity',
component: () => import('@/views/order/place-order-entity')
},
{
path: '/order/orderDetail',
name: 'orderDetail',
component: () => import('@/views/order/orderDetail')
},
{
path: '/order/placeOrderVirtual',
name: 'placeOrderVirtual',
component: () => import('@/views/order/place-order-virtual')
},
{
path: '/order/payment',
name: 'payment',
component: () => import('@/views/order/payment')
},
{
path: '/order/payment/:status',
name: 'paymentStatus',
component: () => import('@/views/order/payment-status'),
props: true
}
];
import asyncLoader from 'core/async-loader';
const tab_user = () => import('@/views/user/tabbar-user');
const UserCollect = () => import('@/views/user/module-collect');
const UserInvitation = () => import('@/views/user/module-invitation');
const UserAddress = () => import('@/views/user/module-address');
const UserAddressEdit = () => import('@/views/user/module-address-edit');
const UserServer = () => import('@/views/user/module-server');
const tab_user = asyncLoader('user/tabbar-user');
const UserCollect = asyncLoader('user/module-collect');
const UserInvitation = asyncLoader('user/module-invitation');
const UserAddress = asyncLoader('user/module-address');
const UserAddressEdit = asyncLoader('user/module-address-edit');
const UserServer = asyncLoader('user/module-server');
const UserInformation = () => import('@/views/user/user-information-set');
const UserInfo_SetBg = () => import('@/views/user/user-information-set/set-bg');
const UserInfo_SetMobile = () => import('@/views/user/user-information-set/set-mobile');
const UserInfo_SetNickname = () => import('@/views/user/user-information-set/set-nickname');
const UserInfo_SetPassword = () => import('@/views/user/user-information-set/set-password');
const UserInformation = asyncLoader('user/user-information-set');
const UserInfo_SetBg = asyncLoader('user/user-information-set/set-bg');
const UserInfo_SetMobile = asyncLoader('user/user-information-set/set-mobile');
const UserInfo_SetNickname = asyncLoader(
'user/user-information-set/set-nickname'
);
const UserInfo_SetPassword = asyncLoader(
'user/user-information-set/set-password'
);
const UserOrderEntityList = () => import('@/views/user/order-entity-list');
const UserOrderEleList = () => import('@/views/user/order-ele-list');
const UserRefundList = () => import('@/views/user/refund-list');
const UserOrderEntityList = asyncLoader('user/order-entity-list');
const UserOrderEleList = asyncLoader('user/order-ele-list');
const UserRefundList = asyncLoader('user/refund-list');
const Tabbar = () =>
import(/* webpackChunkName: "Tabbar" */ '@/vue/components/Tabbar/');
const Tabbar = () => import('@/components/Tabbar/');
export default [
{
......
const getters = {
sidebar: state => state.app.sidebar,
language: state => state.app.language,
size: state => state.app.size,
device: state => state.app.device,
token: state => state.user.token,
avatar: state => state.user.avatar,
name: state => state.user.name,
introduction: state => state.user.introduction,
status: state => state.user.status,
roles: state => state.user.roles,
perms: state => state.user.perms,
setting: state => state.user.setting
}
export default getters
import Vue from 'vue'
import Vuex from 'vuex'
import app from './modules/app'
import user from './modules/user'
import getters from './getters'
Vue.use(Vuex)
const store = new Vuex.Store({
modules: {
app,
user
},
getters
})
export default store
import Cookies from 'js-cookie'
const app = {
state: {
sidebar: {
opened: !+Cookies.get('sidebarStatus'),
withoutAnimation: false
},
device: 'desktop',
language: Cookies.get('language') || 'en',
size: Cookies.get('size') || 'medium'
},
mutations: {
TOGGLE_SIDEBAR: state => {
if (state.sidebar.opened) {
Cookies.set('sidebarStatus', 1)
} else {
Cookies.set('sidebarStatus', 0)
}
state.sidebar.opened = !state.sidebar.opened
state.sidebar.withoutAnimation = false
},
CLOSE_SIDEBAR: (state, withoutAnimation) => {
Cookies.set('sidebarStatus', 1)
state.sidebar.opened = false
state.sidebar.withoutAnimation = withoutAnimation
},
TOGGLE_DEVICE: (state, device) => {
state.device = device
},
SET_LANGUAGE: (state, language) => {
state.language = language
Cookies.set('language', language)
},
SET_SIZE: (state, size) => {
state.size = size
Cookies.set('size', size)
}
},
actions: {
toggleSideBar({ commit }) {
commit('TOGGLE_SIDEBAR')
},
closeSideBar({ commit }, { withoutAnimation }) {
commit('CLOSE_SIDEBAR', withoutAnimation)
},
toggleDevice({ commit }, device) {
commit('TOGGLE_DEVICE', device)
},
setLanguage({ commit }, language) {
commit('SET_LANGUAGE', language)
},
setSize({ commit }, size) {
commit('SET_SIZE', size)
}
}
}
export default app
import { loginByUsername, logout, getUserInfo } from '@/api/user'
import { getToken, setToken, removeToken } from '@/utils/auth'
const user = {
state: {
user: '',
status: '',
code: '',
token: getToken(),
name: '',
avatar: '',
introduction: '',
roles: [],
perms: [],
setting: {
articlePlatform: []
}
},
mutations: {
SET_CODE: (state, code) => {
state.code = code
},
SET_TOKEN: (state, token) => {
state.token = token
},
SET_INTRODUCTION: (state, introduction) => {
state.introduction = introduction
},
SET_SETTING: (state, setting) => {
state.setting = setting
},
SET_STATUS: (state, status) => {
state.status = status
},
SET_NAME: (state, name) => {
state.name = name
},
SET_AVATAR: (state, avatar) => {
state.avatar = avatar
},
SET_ROLES: (state, roles) => {
state.roles = roles
},
SET_PERMS: (state, perms) => {
state.perms = perms
}
},
actions: {
// 用户名登录
LoginByUsername({ commit }, userInfo) {
const username = userInfo.username.trim()
return new Promise((resolve, reject) => {
loginByUsername(username, userInfo.password).then(response => {
const token = response.data.data
commit('SET_TOKEN', token)
setToken(token)
resolve()
}).catch(error => {
reject(error)
})
})
},
// 获取用户信息
GetUserInfo({ commit, state }) {
return new Promise((resolve, reject) => {
getUserInfo(state.token).then(response => {
const data = response.data.data
if (data.perms && data.perms.length > 0) { // 验证返回的perms是否是一个非空数组
commit('SET_PERMS', data.perms)
} else {
reject('getInfo: perms must be a non-null array !')
}
commit('SET_ROLES', data.roles)
commit('SET_NAME', data.name)
commit('SET_AVATAR', data.avatar)
commit('SET_INTRODUCTION', data.introduction)
resolve(response)
}).catch(error => {
reject(error)
})
})
},
// 第三方验证登录
// LoginByThirdparty({ commit, state }, code) {
// return new Promise((resolve, reject) => {
// commit('SET_CODE', code)
// loginByThirdparty(state.status, state.email, state.code).then(response => {
// commit('SET_TOKEN', response.data.token)
// setToken(response.data.token)
// resolve()
// }).catch(error => {
// reject(error)
// })
// })
// },
// 登出
LogOut({ commit, state }) {
return new Promise((resolve, reject) => {
logout(state.token).then(() => {
commit('SET_TOKEN', '')
commit('SET_ROLES', [])
commit('SET_PERMS', [])
removeToken()
resolve()
}).catch(error => {
reject(error)
})
})
},
// 前端 登出
FedLogOut({ commit }) {
return new Promise(resolve => {
commit('SET_TOKEN', '')
removeToken()
resolve()
})
},
// 动态修改权限
ChangeRoles({ commit, dispatch }, role) {
return new Promise(resolve => {
commit('SET_TOKEN', role)
setToken(role)
getUserInfo(role).then(response => {
const data = response.data
commit('SET_ROLES', data.roles)
commit('SET_PERMS', data.perms)
commit('SET_NAME', data.name)
commit('SET_AVATAR', data.avatar)
commit('SET_INTRODUCTION', data.introduction)
dispatch('GenerateRoutes', data) // 动态修改权限后 重绘侧边菜单
resolve()
})
})
}
}
}
export default user
import Cookies from 'js-cookie'
const TokenKey = 'X-Litemall-Admin-Token'
export function getToken() {
return Cookies.get(TokenKey)
}
export function setToken(token) {
return Cookies.set(TokenKey, token)
}
export function removeToken() {
return Cookies.remove(TokenKey)
}
Supports Markdown
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