Unverified Commit 2f3ef296 authored by 端午安康's avatar 端午安康 Committed by GitHub
Browse files

Merge pull request #1 from linlinjava/master

update
parents a2f77152 83711ec2
...@@ -6,7 +6,7 @@ spring: ...@@ -6,7 +6,7 @@ spring:
datasource: datasource:
druid: druid:
url: jdbc:mysql://localhost:3306/litemall?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&allowPublicKeyRetrieval=true&verifyServerCertificate=false&useSSL=false url: jdbc:mysql://localhost:3306/litemall?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&allowPublicKeyRetrieval=true&verifyServerCertificate=false&useSSL=false
driver-class-name: com.mysql.jdbc.Driver driver-class-name: com.mysql.cj.jdbc.Driver
username: litemall username: litemall
password: litemall123456 password: litemall123456
initial-size: 10 initial-size: 10
......
...@@ -16,10 +16,16 @@ cat $LITEMALL_HOME/litemall-db/sql/litemall_schema.sql > $LITEMALL_HOME/deploy/d ...@@ -16,10 +16,16 @@ cat $LITEMALL_HOME/litemall-db/sql/litemall_schema.sql > $LITEMALL_HOME/deploy/d
cat $LITEMALL_HOME/litemall-db/sql/litemall_table.sql >> $LITEMALL_HOME/deploy/db/litemall.sql cat $LITEMALL_HOME/litemall-db/sql/litemall_table.sql >> $LITEMALL_HOME/deploy/db/litemall.sql
cat $LITEMALL_HOME/litemall-db/sql/litemall_data.sql >> $LITEMALL_HOME/deploy/db/litemall.sql cat $LITEMALL_HOME/litemall-db/sql/litemall_data.sql >> $LITEMALL_HOME/deploy/db/litemall.sql
cd $LITEMALL_HOME/litemall-admin
# 安装阿里node镜像工具 # 安装阿里node镜像工具
npm install -g cnpm --registry=https://registry.npm.taobao.org npm install -g cnpm --registry=https://registry.npm.taobao.org
# 安装node项目依赖环境
# 打包litemall-admin
cd $LITEMALL_HOME/litemall-admin
cnpm install
cnpm run build:dep
# 打包litemall-vue
cd $LITEMALL_HOME/litemall-vue
cnpm install cnpm install
cnpm run build:dep cnpm run build:dep
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* vue-router * vue-router
* axios * axios
* element * element
* vue-element-admin 4.2.1 * vue-element-admin 4.3.0
* 其他,见package.json * 其他,见package.json
* 管理后台后端, 即litemall-admin-api模块 * 管理后台后端, 即litemall-admin-api模块
* Spring Boot 2.x * Spring Boot 2.x
...@@ -18,9 +18,6 @@ ...@@ -18,9 +18,6 @@
* `缺失`首页中实现一些小组件,同时点击能够跳转相应页面 * `缺失`首页中实现一些小组件,同时点击能够跳转相应页面
* `缺失`支持导出表所有数据 * `缺失`支持导出表所有数据
* `改善`管理员登录页面打开慢,优化速度
* `改善`地址优化,目前每一次点击都会请求后台,应该缓存已有的数据
* `改善`vue和vue-element-admin等及时更新
## 4.1 litemall-admin-api ## 4.1 litemall-admin-api
......
...@@ -1339,11 +1339,11 @@ litemall-admin编译得到的前端文件在第一次加载时相当耗时,这 ...@@ -1339,11 +1339,11 @@ litemall-admin编译得到的前端文件在第一次加载时相当耗时,这
这里deploy部署方式比较简单不灵活,开发者可以参考开发自己的项目脚本。 这里deploy部署方式比较简单不灵活,开发者可以参考开发自己的项目脚本。
#### 1.7.2.2 .gitlab-ci.yml部署 #### 1.7.2.2 docker部署
目前不支持 当前项目存在docker部署文件夹,这个是上述1.5.1节部署腾讯云服务器所采取的一些脚本。
#### 1.7.2.3 docker部署 #### 1.7.2.3 .gitlab-ci.yml部署
目前不支持 目前不支持
......
...@@ -5,8 +5,8 @@ spring: ...@@ -5,8 +5,8 @@ spring:
encoding: UTF-8 encoding: UTF-8
datasource: datasource:
druid: druid:
url: jdbc:mysql://mysql:3306/litemall?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&allowPublicKeyRetrieval=true&verifyServerCertificate=false&useSSL=false url: jdbc:mysql://mysql:3306/litemall?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&allowPublicKeyRetrieval=true&verifyServerCertificate=false&useSSL=true
driver-class-name: com.mysql.jdbc.Driver driver-class-name: com.mysql.cj.jdbc.Driver
username: litemall username: litemall
password: litemall123456 password: litemall123456
initial-size: 10 initial-size: 10
......
...@@ -16,10 +16,16 @@ cat $LITEMALL_HOME/litemall-db/sql/litemall_schema.sql > $LITEMALL_HOME/docker/d ...@@ -16,10 +16,16 @@ cat $LITEMALL_HOME/litemall-db/sql/litemall_schema.sql > $LITEMALL_HOME/docker/d
cat $LITEMALL_HOME/litemall-db/sql/litemall_table.sql >> $LITEMALL_HOME/docker/db/init-sql/litemall.sql cat $LITEMALL_HOME/litemall-db/sql/litemall_table.sql >> $LITEMALL_HOME/docker/db/init-sql/litemall.sql
cat $LITEMALL_HOME/litemall-db/sql/litemall_data.sql >> $LITEMALL_HOME/docker/db/init-sql/litemall.sql cat $LITEMALL_HOME/litemall-db/sql/litemall_data.sql >> $LITEMALL_HOME/docker/db/init-sql/litemall.sql
cd $LITEMALL_HOME/litemall-admin
# 安装阿里node镜像工具 # 安装阿里node镜像工具
npm install -g cnpm --registry=https://registry.npm.taobao.org npm install -g cnpm --registry=https://registry.npm.taobao.org
# 安装node项目依赖环境
# 打包litemall-admin
cd $LITEMALL_HOME/litemall-admin
cnpm install
cnpm run build:dep
# 打包litemall-vue
cd $LITEMALL_HOME/litemall-vue
cnpm install cnpm install
cnpm run build:dep cnpm run build:dep
......
...@@ -12,12 +12,16 @@ import org.linlinjava.litemall.db.service.LitemallUserService; ...@@ -12,12 +12,16 @@ import org.linlinjava.litemall.db.service.LitemallUserService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import java.util.List; import java.util.List;
import javax.validation.constraints.NotNull;
@RestController @RestController
@RequestMapping("/admin/user") @RequestMapping("/admin/user")
@Validated @Validated
...@@ -38,4 +42,17 @@ public class AdminUserController { ...@@ -38,4 +42,17 @@ public class AdminUserController {
List<LitemallUser> userList = userService.querySelective(username, mobile, page, limit, sort, order); List<LitemallUser> userList = userService.querySelective(username, mobile, page, limit, sort, order);
return ResponseUtil.okList(userList); return ResponseUtil.okList(userList);
} }
@RequiresPermissions("admin:user:list")
@RequiresPermissionsDesc(menu = {"用户管理", "会员管理"}, button = "详情")
@GetMapping("/detail")
public Object userDetail(@NotNull Integer id) {
LitemallUser user=userService.findById(id);
return ResponseUtil.ok(user);
}
@RequiresPermissions("admin:user:list")
@RequiresPermissionsDesc(menu = {"用户管理", "会员管理"}, button = "编辑")
@PostMapping("/update")
public Object userUpdate(@RequestBody LitemallUser user) {
return ResponseUtil.ok(userService.updateById(user));
}
} }
{ {
"name": "litemall-admin", "name": "litemall-admin",
"version": "1.0.0", "version": "1.0.0",
"description": "litemall-admin basing on vue-element-admin 4.2.1", "description": "litemall-admin basing on vue-element-admin 4.3.0",
"author": "linlinjava <linlinjava@163.com>", "author": "linlinjava <linlinjava@163.com>",
"license": "MIT", "license": "MIT",
"scripts": { "scripts": {
...@@ -50,13 +50,14 @@ ...@@ -50,13 +50,14 @@
"clipboard": "2.0.4", "clipboard": "2.0.4",
"connect": "3.6.6", "connect": "3.6.6",
"echarts": "4.2.1", "echarts": "4.2.1",
"element-ui": "2.12.0", "element-ui": "2.13.2",
"file-saver": "1.3.8", "file-saver": "1.3.8",
"js-cookie": "2.2.0", "js-cookie": "2.2.0",
"normalize.css": "7.0.0", "normalize.css": "7.0.0",
"nprogress": "0.2.0", "nprogress": "0.2.0",
"path-to-regexp": "2.4.0", "path-to-regexp": "2.4.0",
"screenfull": "4.2.0", "screenfull": "4.2.0",
"script-loader": "0.7.2",
"vue": "2.6.10", "vue": "2.6.10",
"vue-count-to": "1.0.13", "vue-count-to": "1.0.13",
"vue-router": "3.0.2", "vue-router": "3.0.2",
...@@ -83,11 +84,10 @@ ...@@ -83,11 +84,10 @@
"html-webpack-plugin": "3.2.0", "html-webpack-plugin": "3.2.0",
"husky": "1.3.1", "husky": "1.3.1",
"lint-staged": "8.1.5", "lint-staged": "8.1.5",
"node-sass": "^4.9.0", "sass": "^1.26.2",
"runjs": "^4.3.2", "runjs": "^4.3.2",
"sass-loader": "^7.1.0", "sass-loader": "^7.1.0",
"script-ext-html-webpack-plugin": "2.1.3", "script-ext-html-webpack-plugin": "2.1.3",
"script-loader": "0.7.2",
"serve-static": "^1.13.2", "serve-static": "^1.13.2",
"svg-sprite-loader": "4.1.3", "svg-sprite-loader": "4.1.3",
"svgo": "1.2.0", "svgo": "1.2.0",
......
...@@ -8,6 +8,22 @@ export function fetchList(query) { ...@@ -8,6 +8,22 @@ export function fetchList(query) {
}) })
} }
export function userDetail(id) {
return request({
url: '/user/detail',
method: 'get',
params: {id}
})
}
export function updateUser(data) {
return request({
url: '/user/update',
method: 'post',
data
})
}
export function listAddress(query) { export function listAddress(query) {
return request({ return request({
url: '/address/list', url: '/address/list',
...@@ -47,4 +63,3 @@ export function listHistory(query) { ...@@ -47,4 +63,3 @@ export function listHistory(query) {
params: query params: query
}) })
} }
...@@ -42,7 +42,7 @@ export default { ...@@ -42,7 +42,7 @@ export default {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
/deep/ .el-badge__content.is-fixed.is-dot { ::v-deep .el-badge__content.is-fixed.is-dot {
right: 5px; right: 5px;
top: 10px; top: 10px;
} }
......
<template> <template>
<el-scrollbar ref="scrollContainer" :vertical="false" class="scroll-container" @wheel.native.prevent="handleScroll"> <el-scrollbar ref="scrollContainer" :vertical="false" class="scroll-container" @wheel.native.prevent="handleScroll">
<slot/> <slot />
</el-scrollbar> </el-scrollbar>
</template> </template>
...@@ -80,7 +80,7 @@ export default { ...@@ -80,7 +80,7 @@ export default {
position: relative; position: relative;
overflow: hidden; overflow: hidden;
width: 100%; width: 100%;
/deep/ { ::v-deep {
.el-scrollbar__bar { .el-scrollbar__bar {
bottom: 0px; bottom: 0px;
} }
......
...@@ -28,7 +28,7 @@ router.beforeEach((to, from, next) => { ...@@ -28,7 +28,7 @@ router.beforeEach((to, from, next) => {
store.dispatch('GetUserInfo').then(res => { // 拉取user_info store.dispatch('GetUserInfo').then(res => { // 拉取user_info
const perms = res.data.data.perms // note: perms must be a array! such as: ['GET /aaa','POST /bbb'] const perms = res.data.data.perms // note: perms must be a array! such as: ['GET /aaa','POST /bbb']
store.dispatch('GenerateRoutes', { perms }).then(() => { // 根据perms权限生成可访问的路由表 store.dispatch('GenerateRoutes', { perms }).then(() => { // 根据perms权限生成可访问的路由表
router.addRoutes(store.getters.addRouters) // 动态添加可访问路由表 router.addRoutes(store.getters.addRoutes) // 动态添加可访问路由表
next({ ...to, replace: true }) // hack方法 确保addRoutes已完成 ,set the replace: true so the navigation will not leave a history record next({ ...to, replace: true }) // hack方法 确保addRoutes已完成 ,set the replace: true so the navigation will not leave a history record
}) })
}).catch((err) => { }).catch((err) => {
......
...@@ -24,14 +24,14 @@ import Layout from '@/views/layout/Layout' ...@@ -24,14 +24,14 @@ import Layout from '@/views/layout/Layout'
noCache: true if true ,the page will no be cached(default is false) noCache: true if true ,the page will no be cached(default is false)
} }
**/ **/
export const constantRouterMap = [ export const constantRoutes = [
{ {
path: '/redirect', path: '/redirect',
component: Layout, component: Layout,
hidden: true, hidden: true,
children: [ children: [
{ {
path: '/redirect/:path*', path: '/redirect/:path(.*)',
component: () => import('@/views/redirect/index') component: () => import('@/views/redirect/index')
} }
] ]
...@@ -71,13 +71,7 @@ export const constantRouterMap = [ ...@@ -71,13 +71,7 @@ export const constantRouterMap = [
} }
] ]
export default new Router({ export const asyncRoutes = [
// mode: 'history', // require service support
scrollBehavior: () => ({ y: 0 }),
routes: constantRouterMap
})
export const asyncRouterMap = [
{ {
path: '/user', path: '/user',
component: Layout, component: Layout,
...@@ -612,3 +606,19 @@ export const asyncRouterMap = [ ...@@ -612,3 +606,19 @@ export const asyncRouterMap = [
{ path: '*', redirect: '/404', hidden: true } { path: '*', redirect: '/404', hidden: true }
] ]
const createRouter = () => new Router({
// mode: 'history', // require service support
scrollBehavior: () => ({ y: 0 }),
routes: constantRoutes
})
const router = createRouter()
// Detail see: https://github.com/vuejs/vue-router/issues/1234#issuecomment-357941465
export function resetRouter() {
const newRouter = createRouter()
router.matcher = newRouter.matcher // reset router
}
export default router
...@@ -8,12 +8,9 @@ const getters = { ...@@ -8,12 +8,9 @@ const getters = {
token: state => state.user.token, token: state => state.user.token,
avatar: state => state.user.avatar, avatar: state => state.user.avatar,
name: state => state.user.name, name: state => state.user.name,
introduction: state => state.user.introduction,
status: state => state.user.status,
roles: state => state.user.roles, roles: state => state.user.roles,
perms: state => state.user.perms, perms: state => state.user.perms,
setting: state => state.user.setting, permission_routes: state => state.permission.routes,
permission_routers: state => state.permission.routers, addRoutes: state => state.permission.addRoutes
addRouters: state => state.permission.addRouters
} }
export default getters export default getters
import { asyncRouterMap, constantRouterMap } from '@/router' import { asyncRoutes, constantRoutes } from '@/router'
/** /**
* 通过meta.perms判断是否与当前用户权限匹配 * 通过meta.perms判断是否与当前用户权限匹配
...@@ -15,16 +15,16 @@ function hasPermission(perms, route) { ...@@ -15,16 +15,16 @@ function hasPermission(perms, route) {
/** /**
* 递归过滤异步路由表,返回符合用户角色权限的路由表 * 递归过滤异步路由表,返回符合用户角色权限的路由表
* @param routes asyncRouterMap * @param routes asyncRoutes
* @param perms * @param perms
*/ */
function filterAsyncRouter(routes, perms) { function filterAsyncRoutes(routes, perms) {
const res = [] const res = []
routes.forEach(route => { routes.forEach(route => {
const tmp = { ...route } const tmp = { ...route }
if (tmp.children) { if (tmp.children) {
tmp.children = filterAsyncRouter(tmp.children, perms) tmp.children = filterAsyncRoutes(tmp.children, perms)
if (tmp.children && tmp.children.length > 0) { if (tmp.children && tmp.children.length > 0) {
res.push(tmp) res.push(tmp)
} }
...@@ -40,26 +40,26 @@ function filterAsyncRouter(routes, perms) { ...@@ -40,26 +40,26 @@ function filterAsyncRouter(routes, perms) {
const permission = { const permission = {
state: { state: {
routers: constantRouterMap, routes: constantRoutes,
addRouters: [] addRoutes: []
}, },
mutations: { mutations: {
SET_ROUTERS: (state, routers) => { SET_ROUTES: (state, routes) => {
state.addRouters = routers state.addRoutes = routes
state.routers = constantRouterMap.concat(routers) state.routes = constantRoutes.concat(routes)
} }
}, },
actions: { actions: {
GenerateRoutes({ commit }, data) { GenerateRoutes({ commit }, data) {
return new Promise(resolve => { return new Promise(resolve => {
const { perms } = data const { perms } = data
let accessedRouters let accessedRoutes
if (perms.includes('*')) { if (perms.includes('*')) {
accessedRouters = asyncRouterMap accessedRoutes = asyncRoutes
} else { } else {
accessedRouters = filterAsyncRouter(asyncRouterMap, perms) accessedRoutes = filterAsyncRoutes(asyncRoutes, perms)
} }
commit('SET_ROUTERS', accessedRouters) commit('SET_ROUTES', accessedRoutes)
resolve() resolve()
}) })
} }
......
import { loginByUsername, logout, getUserInfo } from '@/api/login' import { loginByUsername, logout, getUserInfo } from '@/api/login'
import { getToken, setToken, removeToken } from '@/utils/auth' import { getToken, setToken, removeToken } from '@/utils/auth'
import router, { resetRouter } from '@/router'
const user = { const user = {
state: { state: {
user: '', user: '',
status: '',
code: '',
token: getToken(), token: getToken(),
name: '', name: '',
avatar: '', avatar: '',
introduction: '',
roles: [], roles: [],
perms: [], perms: []
setting: {
articlePlatform: []
}
}, },
mutations: { mutations: {
SET_CODE: (state, code) => {
state.code = code
},
SET_TOKEN: (state, token) => { SET_TOKEN: (state, token) => {
state.token = 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) => { SET_NAME: (state, name) => {
state.name = name state.name = name
}, },
...@@ -78,7 +61,6 @@ const user = { ...@@ -78,7 +61,6 @@ const user = {
commit('SET_ROLES', data.roles) commit('SET_ROLES', data.roles)
commit('SET_NAME', data.name) commit('SET_NAME', data.name)
commit('SET_AVATAR', data.avatar) commit('SET_AVATAR', data.avatar)
commit('SET_INTRODUCTION', data.introduction)
resolve(response) resolve(response)
}).catch(error => { }).catch(error => {
reject(error) reject(error)
...@@ -86,28 +68,20 @@ const user = { ...@@ -86,28 +68,20 @@ const user = {
}) })
}, },
// 第三方验证登录
// 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 }) { LogOut({ commit, state, dispatch }) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
logout(state.token).then(() => { logout(state.token).then(() => {
commit('SET_TOKEN', '') commit('SET_TOKEN', '')
commit('SET_ROLES', []) commit('SET_ROLES', [])
commit('SET_PERMS', []) commit('SET_PERMS', [])
removeToken() removeToken()
resetRouter()
// reset visited views and cached views
// to fixed https://github.com/PanJiaChen/vue-element-admin/issues/2485
dispatch('tagsView/delAllViews', null, { root: true })
resolve() resolve()
}).catch(error => { }).catch(error => {
reject(error) reject(error)
...@@ -119,6 +93,7 @@ const user = { ...@@ -119,6 +93,7 @@ const user = {
FedLogOut({ commit }) { FedLogOut({ commit }) {
return new Promise(resolve => { return new Promise(resolve => {
commit('SET_TOKEN', '') commit('SET_TOKEN', '')
commit('SET_ROLES', [])
removeToken() removeToken()
resolve() resolve()
}) })
...@@ -126,19 +101,23 @@ const user = { ...@@ -126,19 +101,23 @@ const user = {
// 动态修改权限 // 动态修改权限
ChangeRoles({ commit, dispatch }, role) { ChangeRoles({ commit, dispatch }, role) {
return new Promise(resolve => { return new Promise(async resolve => {
commit('SET_TOKEN', role) commit('SET_TOKEN', role)
setToken(role) setToken(role)
getUserInfo(role).then(response => {
const data = response.data const { roles } = await dispatch('GetUserInfo')
commit('SET_ROLES', data.roles)
commit('SET_PERMS', data.perms) resetRouter()
commit('SET_NAME', data.name)
commit('SET_AVATAR', data.avatar) const accessRoutes = await dispatch('permission/generateRoutes', roles, { root: true })
commit('SET_INTRODUCTION', data.introduction)
dispatch('GenerateRoutes', data) // 动态修改权限后 重绘侧边菜单 // dynamically add accessible routes
resolve() router.addRoutes(accessRoutes)
})
// reset visited views and cached views
dispatch('tagsView/delAllViews', null, { root: true })
resolve()
}) })
} }
} }
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
.fixed-width { .fixed-width {
.el-button--mini { .el-button--mini {
padding: 7px 10px; padding: 7px 10px;
width: 60px; min-width: 60px;
} }
} }
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
/* theme color */ /* theme color */
$--color-primary: #1890ff; $--color-primary: #1890ff;
$--color-success: #13ce66; $--color-success: #13ce66;
$--color-warning: #FFBA00; $--color-warning: #ffba00;
$--color-danger: #ff4949; $--color-danger: #ff4949;
// $--color-info: #1E1E1E; // $--color-info: #1E1E1E;
...@@ -17,10 +17,10 @@ $--button-font-weight: 400; ...@@ -17,10 +17,10 @@ $--button-font-weight: 400;
$--border-color-light: #dfe4ed; $--border-color-light: #dfe4ed;
$--border-color-lighter: #e6ebf5; $--border-color-lighter: #e6ebf5;
$--table-border:1px solid#dfe6ec; $--table-border: 1px solid #dfe6ec;
/* icon font path, required */ /* icon font path, required */
$--font-path: '~element-ui/lib/theme-chalk/fonts'; $--font-path: "~element-ui/lib/theme-chalk/fonts";
@import "~element-ui/packages/theme-chalk/src/index"; @import "~element-ui/packages/theme-chalk/src/index";
......
...@@ -57,6 +57,11 @@ ...@@ -57,6 +57,11 @@
margin-right: 16px; margin-right: 16px;
} }
.sub-el-icon {
margin-right: 12px;
margin-left: -2px;
}
.el-menu { .el-menu {
border: none; border: none;
height: 100%; height: 100%;
...@@ -105,6 +110,11 @@ ...@@ -105,6 +110,11 @@
.svg-icon { .svg-icon {
margin-left: 20px; margin-left: 20px;
} }
.sub-el-icon {
margin-right: 12px;
margin-left: -2px;
}
} }
} }
...@@ -118,6 +128,11 @@ ...@@ -118,6 +128,11 @@
margin-left: 20px; margin-left: 20px;
} }
.sub-el-icon {
margin-right: 12px;
margin-left: -2px;
}
.el-submenu__icon-arrow { .el-submenu__icon-arrow {
display: none; display: none;
} }
...@@ -178,6 +193,10 @@ ...@@ -178,6 +193,10 @@
.svg-icon { .svg-icon {
margin-right: 16px; margin-right: 16px;
} }
.sub-el-icon {
margin-right: 12px;
margin-left: -2px;
}
} }
.nest-menu .el-submenu>.el-submenu__title, .nest-menu .el-submenu>.el-submenu__title,
......
/* eslint-disable */ /* eslint-disable */
require('script-loader!file-saver'); import { saveAs } from 'file-saver'
import XLSX from 'xlsx' import XLSX from 'xlsx'
function generateArray(table) { function generateArray(table) {
...@@ -145,20 +145,34 @@ export function export_table_to_excel(id) { ...@@ -145,20 +145,34 @@ export function export_table_to_excel(id) {
} }
export function export_json_to_excel({ export function export_json_to_excel({
multiHeader = [],
header, header,
data, data,
filename, filename,
merges = [],
autoWidth = true, autoWidth = true,
bookType= 'xlsx' bookType = 'xlsx'
} = {}) { } = {}) {
/* original data */ /* original data */
filename = filename || 'excel-list' filename = filename || 'excel-list'
data = [...data] data = [...data]
data.unshift(header); data.unshift(header);
for (let i = multiHeader.length - 1; i > -1; i--) {
data.unshift(multiHeader[i])
}
var ws_name = "SheetJS"; var ws_name = "SheetJS";
var wb = new Workbook(), var wb = new Workbook(),
ws = sheet_from_array_of_arrays(data); ws = sheet_from_array_of_arrays(data);
if (merges.length > 0) {
if (!ws['!merges']) ws['!merges'] = [];
merges.forEach(item => {
ws['!merges'].push(XLSX.utils.decode_range(item))
})
}
if (autoWidth) { if (autoWidth) {
/*设置worksheet每列的最大宽度*/ /*设置worksheet每列的最大宽度*/
const colWidth = data.map(row => row.map(val => { const colWidth = data.map(row => row.map(val => {
......
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