Merge branch 'lzwdev' into feature-20240104

master
blak-kong 2 years ago
commit 59b5348afa

@ -9,3 +9,6 @@ VUE_APP_BASE_API = '/prod-api'
# 路由懒加载 # 路由懒加载
VUE_CLI_BABEL_TRANSPILE_MODULES = true VUE_CLI_BABEL_TRANSPILE_MODULES = true
# 设置端口号
port=8080

@ -6,3 +6,6 @@ ENV = 'production'
# 花至管理系统/生产环境 # 花至管理系统/生产环境
VUE_APP_BASE_API = '/prod-api' VUE_APP_BASE_API = '/prod-api'
# 设置端口号
# port=8080

@ -5,6 +5,7 @@
"author": "花至", "author": "花至",
"license": "MIT", "license": "MIT",
"scripts": { "scripts": {
"local": "vue-cli-service serve --mode local",
"dev": "vue-cli-service serve --mode development", "dev": "vue-cli-service serve --mode development",
"build:prod": "vue-cli-service build", "build:prod": "vue-cli-service build",
"build:stage": "vue-cli-service build --mode staging", "build:stage": "vue-cli-service build --mode staging",
@ -51,7 +52,8 @@
"jsencrypt": "3.0.0-rc.1", "jsencrypt": "3.0.0-rc.1",
"npm": "^10.2.5", "npm": "^10.2.5",
"nprogress": "0.2.0", "nprogress": "0.2.0",
"quill": "^2.0.0-beta.0", "quill": "^2.0.0-dev.3",
"quill-better-table": "^1.2.10",
"screenfull": "5.0.2", "screenfull": "5.0.2",
"sortablejs": "1.10.2", "sortablejs": "1.10.2",
"vue": "2.6.12", "vue": "2.6.12",

@ -13,24 +13,37 @@
v-if="this.type == 'url'" v-if="this.type == 'url'"
> >
</el-upload> </el-upload>
<div class="editor" ref="editor" :style="styles"></div> <div class="editor" ref="editor" :style="styles">
<div>
{{ this.currentValue }}
</div>
</div>
</div> </div>
</template> </template>
<script> <script>
import Quill from "quill"; import Quill from 'quill'
import "quill/dist/quill.core.css"; import 'quill/dist/quill.core.css'
import "quill/dist/quill.snow.css"; import 'quill/dist/quill.snow.css'
import "quill/dist/quill.bubble.css"; import 'quill/dist/quill.bubble.css'
import { getToken } from "@/utils/auth"; import { getToken } from '@/utils/auth'
import QuillBetterTable from 'quill-better-table'
import 'quill-better-table/dist/quill-better-table.css'
Quill.register(
{
'modules/better-table': QuillBetterTable,
},
true
)
export default { export default {
name: "Editor", name: 'Editor',
props: { props: {
/* 编辑器的内容 */ /* 编辑器的内容 */
value: { value: {
type: String, type: String,
default: "", default: '',
}, },
/* 高度 */ /* 高度 */
height: { height: {
@ -55,60 +68,81 @@ export default {
/* 类型base64格式、url格式 */ /* 类型base64格式、url格式 */
type: { type: {
type: String, type: String,
default: "url", default: 'url',
}
}, },
/* 私有ID 用于同一页面下的不同富文本的表格修改 */
tableName: {
type: String,
default: 'mytable',
},
},
data() { data() {
return { return {
uploadUrl: process.env.VUE_APP_BASE_API + "/file/upload", // uploadUrl: process.env.VUE_APP_BASE_API + '/file/upload', //
headers: { headers: {
Authorization: "Bearer " + getToken() Authorization: 'Bearer ' + getToken(),
}, },
Quill: null, Quill: null,
currentValue: "", currentValue: '',
options: { options: {
theme: "snow", theme: 'snow',
bounds: document.body, bounds: document.body,
debug: "warn", debug: 'warn',
modules: { modules: {
table: false, // disable table module
'better-table': {
operationMenu: {
items: {
unmergeCells: {
text: 'Another unmerge cells name',
},
},
},
},
keyboard: {
bindings: QuillBetterTable.keyboardBindings,
},
// //
toolbar: [ toolbar: [
["bold", "italic", "underline", "strike"], // 线 线 ['bold', 'italic', 'underline', 'strike'], // 线 线
["blockquote", "code-block"], // ['blockquote', 'code-block'], //
[{ list: "ordered" }, { list: "bullet" }], // [{ list: 'ordered' }, { list: 'bullet' }], //
[{ indent: "-1" }, { indent: "+1" }], // [{ indent: '-1' }, { indent: '+1' }], //
[{ size: ["small", false, "large", "huge"] }], // [{ size: ['small', false, 'large', 'huge'] }], //
[{ header: [1, 2, 3, 4, 5, 6, false] }], // [{ header: [1, 2, 3, 4, 5, 6, false] }], //
[{ color: [] }, { background: [] }], // [{ color: [] }, { background: [] }], //
[{ align: [] }], // [{ align: [] }], //
["clean"], // ['clean'], //
["link", "image", "video"] // ['table'],
['link', 'image', 'video'], //
], ],
}, },
placeholder: "请输入内容", placeholder: '请输入内容',
readOnly: this.readOnly, readOnly: this.readOnly,
}, },
}; }
}, },
computed: { computed: {
styles() { styles() {
let style = {}; let style = {}
if (this.minHeight) { if (this.minHeight) {
style.minHeight = `${this.minHeight}px`; style.minHeight = `${this.minHeight}px`
} }
if (this.height) { if (this.height) {
style.height = `${this.height}px`; style.height = `${this.height}px`
} }
return style; return style
}, },
}, },
watch: { watch: {
value: { value: {
handler(val) { handler(val) {
if (val !== this.currentValue) { if (val !== this.currentValue) {
this.currentValue = val === null ? "" : val; this.currentValue = val === null ? '' : val
if (this.Quill) { let ele = document.body.querySelector(`#${this.tableName} .editor`)
this.Quill.pasteHTML(this.currentValue); if (ele) {
ele.children[0].innerHTML = this.currentValue
} }
} }
}, },
@ -116,159 +150,177 @@ export default {
}, },
}, },
mounted() { mounted() {
this.init(); this.init()
// this.addTableButton()
}, },
beforeDestroy() { beforeDestroy() {
this.Quill = null; this.Quill = null
}, },
methods: { methods: {
init() { init() {
const editor = this.$refs.editor; const editor = this.$refs.editor
this.Quill = new Quill(editor, this.options); this.Quill = new Quill(editor, this.options)
// //
if (this.type == 'url') { if (this.type == 'url') {
let toolbar = this.Quill.getModule("toolbar"); let toolbar = this.Quill.getModule('toolbar')
toolbar.addHandler("image", (value) => { toolbar.addHandler('image', (value) => {
if (value) { if (value) {
this.$refs.upload.$children[0].$refs.input.click(); this.$refs.upload.$children[0].$refs.input.click()
} else { } else {
this.quill.format("image", false); this.quill.format('image', false)
} }
}); })
} }
this.Quill.pasteHTML(this.currentValue); // this.Quill.pasteHTML(this.currentValue)
this.Quill.on("text-change", (delta, oldDelta, source) => { // this.Quill.setText(this.currentValue)
const html = this.$refs.editor.children[0].innerHTML;
const text = this.Quill.getText(); let tableModule = this.Quill.getModule('better-table')
const quill = this.Quill; let ele = document.body.querySelector(`#${this.tableName} .ql-table`)
this.currentValue = html; if (ele) {
this.$emit("input", html); ele.onclick = () => {
this.$emit("on-change", { html, text, quill }); tableModule.insertTable(3, 3)
}); }
this.Quill.on("text-change", (delta, oldDelta, source) => { }
this.$emit("on-text-change", delta, oldDelta, source);
}); this.Quill.on('text-change', (delta, oldDelta, source) => {
this.Quill.on("selection-change", (range, oldRange, source) => { const html = this.$refs.editor.children[0].innerHTML
this.$emit("on-selection-change", range, oldRange, source); const text = this.Quill.getText()
}); const quill = this.Quill
this.Quill.on("editor-change", (eventName, ...args) => { this.currentValue = html
this.$emit("on-editor-change", eventName, ...args); this.$emit('input', html)
}); this.$emit('on-change', { html, text, quill })
})
this.Quill.on('text-change', (delta, oldDelta, source) => {
this.$emit('on-text-change', delta, oldDelta, source)
})
this.Quill.on('selection-change', (range, oldRange, source) => {
this.$emit('on-selection-change', range, oldRange, source)
})
this.Quill.on('editor-change', (eventName, ...args) => {
this.$emit('on-editor-change', eventName, ...args)
})
},
addTableButton() {
let ele = document.getElementsByClassName('.ql-better-table')
console.log('ADD table', ele)
}, },
// //
handleBeforeUpload(file) { handleBeforeUpload(file) {
const type = ["image/jpeg", "image/jpg", "image/png", "image/svg"]; const type = ['image/jpeg', 'image/jpg', 'image/png', 'image/svg']
const isJPG = type.includes(file.type); const isJPG = type.includes(file.type)
// //
if (!isJPG) { if (!isJPG) {
this.$message.error(`图片格式错误!`); this.$message.error(`图片格式错误!`)
return false; return false
} }
// //
if (this.fileSize) { if (this.fileSize) {
const isLt = file.size / 1024 / 1024 < this.fileSize; const isLt = file.size / 1024 / 1024 < this.fileSize
if (!isLt) { if (!isLt) {
this.$message.error(`上传文件大小不能超过 ${this.fileSize} MB!`); this.$message.error(`上传文件大小不能超过 ${this.fileSize} MB!`)
return false; return false
} }
} }
return true; return true
}, },
handleUploadSuccess(res, file) { handleUploadSuccess(res, file) {
// //
if (res.code == 200) { if (res.code == 200) {
// //
let quill = this.Quill; let quill = this.Quill
// //
let length = quill.getSelection().index; let length = quill.getSelection().index
// res.url // res.url
quill.insertEmbed(length, "image", res.data.url); quill.insertEmbed(length, 'image', res.data.url)
// //
quill.setSelection(length + 1); quill.setSelection(length + 1)
} else { } else {
this.$message.error("图片插入失败"); this.$message.error('图片插入失败')
} }
}, },
handleUploadError() { handleUploadError() {
this.$message.error("图片插入失败"); this.$message.error('图片插入失败')
}, },
}, },
}; }
</script> </script>
<style> <style>
.editor, .ql-toolbar { .editor,
.ql-toolbar {
white-space: pre-wrap !important; white-space: pre-wrap !important;
line-height: normal !important; line-height: normal !important;
} }
.quill-img { .quill-img {
display: none; display: none;
} }
.ql-snow .ql-tooltip[data-mode="link"]::before { .ql-snow .ql-tooltip[data-mode='link']::before {
content: "请输入链接地址:"; content: '请输入链接地址:';
} }
.ql-snow .ql-tooltip.ql-editing a.ql-action::after { .ql-snow .ql-tooltip.ql-editing a.ql-action::after {
border-right: 0px; border-right: 0px;
content: "保存"; content: '保存';
padding-right: 0px; padding-right: 0px;
} }
.ql-snow .ql-tooltip[data-mode="video"]::before { .ql-snow .ql-tooltip[data-mode='video']::before {
content: "请输入视频地址:"; content: '请输入视频地址:';
} }
.ql-snow .ql-picker.ql-size .ql-picker-label::before, .ql-snow .ql-picker.ql-size .ql-picker-label::before,
.ql-snow .ql-picker.ql-size .ql-picker-item::before { .ql-snow .ql-picker.ql-size .ql-picker-item::before {
content: "14px"; content: '14px';
} }
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="small"]::before, .ql-snow .ql-picker.ql-size .ql-picker-label[data-value='small']::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="small"]::before { .ql-snow .ql-picker.ql-size .ql-picker-item[data-value='small']::before {
content: "10px"; content: '10px';
} }
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="large"]::before, .ql-snow .ql-picker.ql-size .ql-picker-label[data-value='large']::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="large"]::before { .ql-snow .ql-picker.ql-size .ql-picker-item[data-value='large']::before {
content: "18px"; content: '18px';
} }
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="huge"]::before, .ql-snow .ql-picker.ql-size .ql-picker-label[data-value='huge']::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="huge"]::before { .ql-snow .ql-picker.ql-size .ql-picker-item[data-value='huge']::before {
content: "32px"; content: '32px';
} }
.ql-snow .ql-picker.ql-header .ql-picker-label::before, .ql-snow .ql-picker.ql-header .ql-picker-label::before,
.ql-snow .ql-picker.ql-header .ql-picker-item::before { .ql-snow .ql-picker.ql-header .ql-picker-item::before {
content: "文本"; content: '文本';
} }
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="1"]::before, .ql-snow .ql-picker.ql-header .ql-picker-label[data-value='1']::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before { .ql-snow .ql-picker.ql-header .ql-picker-item[data-value='1']::before {
content: "标题1"; content: '标题1';
} }
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="2"]::before, .ql-snow .ql-picker.ql-header .ql-picker-label[data-value='2']::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before { .ql-snow .ql-picker.ql-header .ql-picker-item[data-value='2']::before {
content: "标题2"; content: '标题2';
} }
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="3"]::before, .ql-snow .ql-picker.ql-header .ql-picker-label[data-value='3']::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before { .ql-snow .ql-picker.ql-header .ql-picker-item[data-value='3']::before {
content: "标题3"; content: '标题3';
} }
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="4"]::before, .ql-snow .ql-picker.ql-header .ql-picker-label[data-value='4']::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before { .ql-snow .ql-picker.ql-header .ql-picker-item[data-value='4']::before {
content: "标题4"; content: '标题4';
} }
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="5"]::before, .ql-snow .ql-picker.ql-header .ql-picker-label[data-value='5']::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before { .ql-snow .ql-picker.ql-header .ql-picker-item[data-value='5']::before {
content: "标题5"; content: '标题5';
} }
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="6"]::before, .ql-snow .ql-picker.ql-header .ql-picker-label[data-value='6']::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before { .ql-snow .ql-picker.ql-header .ql-picker-item[data-value='6']::before {
content: "标题6"; content: '标题6';
} }
.ql-snow .ql-picker.ql-font .ql-picker-label::before, .ql-snow .ql-picker.ql-font .ql-picker-label::before,
.ql-snow .ql-picker.ql-font .ql-picker-item::before { .ql-snow .ql-picker.ql-font .ql-picker-item::before {
content: "标准字体"; content: '标准字体';
} }
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="serif"]::before, .ql-snow .ql-picker.ql-font .ql-picker-label[data-value='serif']::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="serif"]::before { .ql-snow .ql-picker.ql-font .ql-picker-item[data-value='serif']::before {
content: "衬线字体"; content: '衬线字体';
} }
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="monospace"]::before, .ql-snow .ql-picker.ql-font .ql-picker-label[data-value='monospace']::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="monospace"]::before { .ql-snow .ql-picker.ql-font .ql-picker-item[data-value='monospace']::before {
content: "等宽字体"; content: '等宽字体';
} }
</style> </style>

@ -1,56 +1,58 @@
import router from './router' import router from "./router";
import store from './store' import store from "./store";
import { Message } from 'element-ui' import { Message } from "element-ui";
import NProgress from 'nprogress' import NProgress from "nprogress";
import 'nprogress/nprogress.css' import "nprogress/nprogress.css";
import { getToken } from '@/utils/auth' import { getToken } from "@/utils/auth";
import { isRelogin } from '@/utils/request' import { isRelogin } from "@/utils/request";
NProgress.configure({ showSpinner: false }) NProgress.configure({ showSpinner: false });
const whiteList = ['/login', '/register'] const whiteList = ["/login", "/register"];
router.beforeEach((to, from, next) => { router.beforeEach((to, from, next) => {
NProgress.start() NProgress.start();
if (getToken()) { if (getToken()) {
to.meta.title && store.dispatch('settings/setTitle', to.meta.title) to.meta.title && store.dispatch("settings/setTitle", to.meta.title);
/* has token*/ /* has token*/
if (to.path === '/login') { if (to.path === "/login") {
next({ path: '/' }) next({ path: "/" });
NProgress.done() NProgress.done();
} else { } else {
if (store.getters.roles.length === 0) { if (store.getters.roles.length === 0) {
isRelogin.show = true isRelogin.show = true;
// 判断当前用户是否已拉取完user_info信息 // 判断当前用户是否已拉取完user_info信息
store.dispatch('GetInfo').then(() => { store
isRelogin.show = false .dispatch("GetInfo")
store.dispatch('GenerateRoutes').then(accessRoutes => { .then(() => {
isRelogin.show = false;
store.dispatch("GenerateRoutes").then((accessRoutes) => {
// 根据roles权限生成可访问的路由表 // 根据roles权限生成可访问的路由表
router.addRoutes(accessRoutes) // 动态添加可访问路由表 router.addRoutes(accessRoutes); // 动态添加可访问路由表
next({ ...to, replace: true }) // hack方法 确保addRoutes已完成 next({ ...to, replace: true }); // hack方法 确保addRoutes已完成
}) });
}).catch(err => {
store.dispatch('LogOut').then(() => {
Message.error(err)
next({ path: '/' })
})
}) })
.catch((err) => {
store.dispatch("LogOut").then(() => {
Message.error(err);
next({ path: "/" });
});
});
} else { } else {
next() next();
} }
} }
} else { } else {
// 没有token
if (whiteList.indexOf(to.path) !== -1) { if (whiteList.indexOf(to.path) !== -1) {
// 在免登录白名单,直接进入 // 在免登录白名单,直接进入
next() next();
} else { } else {
next(`/login?redirect=${encodeURIComponent(to.fullPath)}`) // 否则全部重定向到登录页 next(`/login?redirect=${encodeURIComponent(to.fullPath)}`); // 否则全部重定向到登录页
NProgress.done() NProgress.done();
} }
} }
}) });
router.afterEach(() => { router.afterEach(() => {
NProgress.done() NProgress.done();
}) });

@ -1,10 +1,10 @@
import Vue from 'vue' import Vue from "vue";
import Router from 'vue-router' import Router from "vue-router";
Vue.use(Router) Vue.use(Router);
/* Layout */ /* Layout */
import Layout from '@/layout' import Layout from "@/layout";
/** /**
* Note: 路由配置项 * Note: 路由配置项
@ -31,153 +31,153 @@ import Layout from '@/layout'
// 公共路由 // 公共路由
export const constantRoutes = [ 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') component: () => import("@/views/redirect"),
} },
] ],
}, },
{ {
path: '/login', path: "/login",
component: () => import('@/views/login'), component: () => import("@/views/login"),
hidden: true hidden: true,
}, },
{ {
path: '/register', path: "/register",
component: () => import('@/views/register'), component: () => import("@/views/register"),
hidden: true hidden: true,
}, },
{ {
path: '/404', path: "/404",
component: () => import('@/views/error/404'), component: () => import("@/views/error/404"),
hidden: true hidden: true,
}, },
{ {
path: '/401', path: "/401",
component: () => import('@/views/error/401'), component: () => import("@/views/error/401"),
hidden: true hidden: true,
}, },
{ {
path: '', path: "",
component: Layout, component: Layout,
redirect: 'index', redirect: "index",
children: [ children: [
{ {
path: 'index', path: "index",
component: () => import('@/views/index'), component: () => import("@/views/index"),
name: 'Index', name: "Index",
meta: { title: '首页', icon: 'dashboard', affix: true } meta: { title: "首页", icon: "dashboard", affix: true },
} },
] ],
}, },
{ {
path: '/user', path: "/user",
component: Layout, component: Layout,
hidden: true, hidden: true,
redirect: 'noredirect', redirect: "noredirect",
children: [ children: [
{ {
path: 'profile', path: "profile",
component: () => import('@/views/system/user/profile/index'), component: () => import("@/views/system/user/profile/index"),
name: 'Profile', name: "Profile",
meta: { title: '个人中心', icon: 'user' } meta: { title: "个人中心", icon: "user" },
} },
] ],
} },
] ];
// 动态路由,基于用户权限动态去加载 // 动态路由,基于用户权限动态去加载
export const dynamicRoutes = [ export const dynamicRoutes = [
{ {
path: '/system/user-auth', path: "/system/user-auth",
component: Layout, component: Layout,
hidden: true, hidden: true,
permissions: ['system:user:edit'], permissions: ["system:user:edit"],
children: [ children: [
{ {
path: 'role/:userId(\\d+)', path: "role/:userId(\\d+)",
component: () => import('@/views/system/user/authRole'), component: () => import("@/views/system/user/authRole"),
name: 'AuthRole', name: "AuthRole",
meta: { title: '分配角色', activeMenu: '/system/user' } meta: { title: "分配角色", activeMenu: "/system/user" },
} },
] ],
}, },
{ {
path: '/system/role-auth', path: "/system/role-auth",
component: Layout, component: Layout,
hidden: true, hidden: true,
permissions: ['system:role:edit'], permissions: ["system:role:edit"],
children: [ children: [
{ {
path: 'user/:roleId(\\d+)', path: "user/:roleId(\\d+)",
component: () => import('@/views/system/role/authUser'), component: () => import("@/views/system/role/authUser"),
name: 'AuthUser', name: "AuthUser",
meta: { title: '分配用户', activeMenu: '/system/role' } meta: { title: "分配用户", activeMenu: "/system/role" },
} },
] ],
}, },
{ {
path: '/system/dict-data', path: "/system/dict-data",
component: Layout, component: Layout,
hidden: true, hidden: false,
permissions: ['system:dict:list'], // permissions: ["system:dict:list"],
children: [ children: [
{ {
path: 'index/:dictId(\\d+)', path: "index/:dictId(\\d+)",
component: () => import('@/views/system/dict/data'), component: () => import("@/views/system/dict/data"),
name: 'Data', name: "Data",
meta: { title: '字典数据', activeMenu: '/system/dict' } meta: { title: "字典数据", activeMenu: "/system/dict" },
} },
] ],
}, },
{ {
path: '/monitor/job-log', path: "/monitor/job-log",
component: Layout, component: Layout,
hidden: true, hidden: true,
permissions: ['monitor:job:list'], permissions: ["monitor:job:list"],
children: [ children: [
{ {
path: 'index/:jobId(\\d+)', path: "index/:jobId(\\d+)",
component: () => import('@/views/monitor/job/log'), component: () => import("@/views/monitor/job/log"),
name: 'JobLog', name: "JobLog",
meta: { title: '调度日志', activeMenu: '/monitor/job' } meta: { title: "调度日志", activeMenu: "/monitor/job" },
} },
] ],
}, },
{ {
path: '/tool/gen-edit', path: "/tool/gen-edit",
component: Layout, component: Layout,
hidden: true, hidden: true,
permissions: ['tool:gen:edit'], permissions: ["tool:gen:edit"],
children: [ children: [
{ {
path: 'index/:tableId(\\d+)', path: "index/:tableId(\\d+)",
component: () => import('@/views/tool/gen/editTable'), component: () => import("@/views/tool/gen/editTable"),
name: 'GenEdit', name: "GenEdit",
meta: { title: '修改生成配置', activeMenu: '/tool/gen' } meta: { title: "修改生成配置", activeMenu: "/tool/gen" },
} },
] ],
} },
] ];
// 防止连续点击多次路由报错 // 防止连续点击多次路由报错
let routerPush = Router.prototype.push; let routerPush = Router.prototype.push;
let routerReplace = Router.prototype.replace; let routerReplace = Router.prototype.replace;
// push // push
Router.prototype.push = function push(location) { Router.prototype.push = function push(location) {
return routerPush.call(this, location).catch(err => err) return routerPush.call(this, location).catch((err) => err);
} };
// replace // replace
Router.prototype.replace = function push(location) { Router.prototype.replace = function push(location) {
return routerReplace.call(this, location).catch(err => err) return routerReplace.call(this, location).catch((err) => err);
} };
export default new Router({ export default new Router({
mode: 'history', // 去掉url中的# mode: "history", // 去掉url中的#
scrollBehavior: () => ({ y: 0 }), scrollBehavior: () => ({ y: 0 }),
routes: constantRoutes routes: constantRoutes,
}) });

@ -1,114 +1,148 @@
import axios from 'axios' import axios from "axios";
import { Notification, MessageBox, Message, Loading } from 'element-ui' import { Notification, MessageBox, Message, Loading } from "element-ui";
import store from '@/store' import store from "@/store";
import { getToken } from '@/utils/auth' import { getToken } from "@/utils/auth";
import errorCode from '@/utils/errorCode' import errorCode from "@/utils/errorCode";
import { tansParams, blobValidate } from "@/utils/ruoyi"; import { tansParams, blobValidate } from "@/utils/ruoyi";
import cache from '@/plugins/cache' import cache from "@/plugins/cache";
import { saveAs } from 'file-saver' import { saveAs } from "file-saver";
let downloadLoadingInstance; let downloadLoadingInstance;
// 是否显示重新登录 // 是否显示重新登录
export let isRelogin = { show: false }; export let isRelogin = { show: false };
axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8' axios.defaults.headers["Content-Type"] = "application/json;charset=utf-8";
// 创建axios实例 // 创建axios实例
const service = axios.create({ const service = axios.create({
// axios中请求配置有baseURL选项表示请求URL公共部分 // axios中请求配置有baseURL选项表示请求URL公共部分
baseURL: process.env.VUE_APP_BASE_API, baseURL: process.env.VUE_APP_BASE_API,
// 超时 // 超时
timeout: 10000 timeout: 10000,
}) });
// request拦截器 // request拦截器
service.interceptors.request.use(config => { service.interceptors.request.use(
(config) => {
// 是否需要设置 token // 是否需要设置 token
const isToken = (config.headers || {}).isToken === false const isToken = (config.headers || {}).isToken === false;
// 是否需要防止数据重复提交 // 是否需要防止数据重复提交
const isRepeatSubmit = (config.headers || {}).repeatSubmit === false const isRepeatSubmit = (config.headers || {}).repeatSubmit === false;
if (getToken() && !isToken) { if (getToken() && !isToken) {
config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改 config.headers["Authorization"] = "Bearer " + getToken(); // 让每个请求携带自定义token 请根据实际情况自行修改
} }
// get请求映射params参数 // get请求映射params参数
if (config.method === 'get' && config.params) { if (config.method === "get" && config.params) {
let url = config.url + '?' + tansParams(config.params); let url = config.url + "?" + tansParams(config.params);
url = url.slice(0, -1); url = url.slice(0, -1);
config.params = {}; config.params = {};
config.url = url; config.url = url;
} }
if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) { if (
!isRepeatSubmit &&
(config.method === "post" || config.method === "put")
) {
const requestObj = { const requestObj = {
url: config.url, url: config.url,
data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data, data:
time: new Date().getTime() typeof config.data === "object"
} ? JSON.stringify(config.data)
: config.data,
time: new Date().getTime(),
};
const requestSize = Object.keys(JSON.stringify(requestObj)).length; // 请求数据大小 const requestSize = Object.keys(JSON.stringify(requestObj)).length; // 请求数据大小
const limitSize = 5 * 1024 * 1024; // 限制存放数据5M const limitSize = 5 * 1024 * 1024; // 限制存放数据5M
if (requestSize >= limitSize) { if (requestSize >= limitSize) {
console.warn(`[${config.url}]: ` + '请求数据大小超出允许的5M限制无法进行防重复提交验证。') console.warn(
`[${config.url}]: ` +
"请求数据大小超出允许的5M限制无法进行防重复提交验证。"
);
return config; return config;
} }
const sessionObj = cache.session.getJSON('sessionObj') const sessionObj = cache.session.getJSON("sessionObj");
if (sessionObj === undefined || sessionObj === null || sessionObj === '') { if (
cache.session.setJSON('sessionObj', requestObj) sessionObj === undefined ||
sessionObj === null ||
sessionObj === ""
) {
cache.session.setJSON("sessionObj", requestObj);
} else { } else {
const s_url = sessionObj.url; // 请求地址 const s_url = sessionObj.url; // 请求地址
const s_data = sessionObj.data; // 请求数据 const s_data = sessionObj.data; // 请求数据
const s_time = sessionObj.time; // 请求时间 const s_time = sessionObj.time; // 请求时间
const interval = 1000; // 间隔时间(ms),小于此时间视为重复提交 const interval = 1000; // 间隔时间(ms),小于此时间视为重复提交
if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) { if (
const message = '数据正在处理,请勿重复提交'; s_data === requestObj.data &&
console.warn(`[${s_url}]: ` + message) requestObj.time - s_time < interval &&
return Promise.reject(new Error(message)) s_url === requestObj.url
) {
const message = "数据正在处理,请勿重复提交";
console.warn(`[${s_url}]: ` + message);
return Promise.reject(new Error(message));
} else { } else {
cache.session.setJSON('sessionObj', requestObj) cache.session.setJSON("sessionObj", requestObj);
} }
} }
} }
return config return config;
}, error => { },
console.log(error) (error) => {
Promise.reject(error) console.log(error);
}) Promise.reject(error);
}
);
// 响应拦截器 // 响应拦截器
service.interceptors.response.use(res => { service.interceptors.response.use(
(res) => {
// 未设置状态码则默认成功状态 // 未设置状态码则默认成功状态
const code = res.data.code || 200; const code = res.data.code || 200;
// 获取错误信息 // 获取错误信息
const msg = errorCode[code] || res.data.msg || errorCode['default'] const msg = errorCode[code] || res.data.msg || errorCode["default"];
// 二进制数据则直接返回 // 二进制数据则直接返回
if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') { if (
return res.data res.request.responseType === "blob" ||
res.request.responseType === "arraybuffer"
) {
return res.data;
} }
if (code === 401) { if (code === 401) {
if (!isRelogin.show) { if (!isRelogin.show) {
isRelogin.show = true; isRelogin.show = true;
MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' }).then(() => { MessageBox.confirm(
"登录状态已过期,您可以继续留在该页面,或者重新登录",
"系统提示",
{
confirmButtonText: "重新登录",
cancelButtonText: "取消",
type: "warning",
}
)
.then(() => {
isRelogin.show = false; isRelogin.show = false;
store.dispatch('LogOut').then(() => { store.dispatch("LogOut").then(() => {
location.href = '/index'; location.href = "/index";
});
}) })
}).catch(() => { .catch(() => {
isRelogin.show = false; isRelogin.show = false;
}); });
} }
return Promise.reject('无效的会话,或者会话已过期,请重新登录。') return Promise.reject("无效的会话,或者会话已过期,请重新登录。");
} else if (code === 500) { } else if (code === 500) {
Message({ message: msg, type: 'error' }) Message({ message: msg, type: "error" });
return Promise.reject(new Error(msg)) return Promise.reject(new Error(msg));
} else if (code === 601) { } else if (code === 601) {
Message({ message: msg, type: 'warning' }) Message({ message: msg, type: "warning" });
return Promise.reject('error') return Promise.reject("error");
} else if (code !== 200) { } else if (code !== 200) {
Notification.error({ title: msg }) Notification.error({ title: msg });
return Promise.reject('error') return Promise.reject("error");
} else { } else {
return res.data return res.data;
} }
}, },
error => { (error) => {
console.log('err' + error) console.log("err" + error);
let { message } = error; let { message } = error;
if (message == "Network Error") { if (message == "Network Error") {
message = "后端接口连接异常"; message = "后端接口连接异常";
@ -117,36 +151,48 @@ service.interceptors.response.use(res => {
} else if (message.includes("Request failed with status code")) { } else if (message.includes("Request failed with status code")) {
message = "系统接口" + message.substr(message.length - 3) + "异常"; message = "系统接口" + message.substr(message.length - 3) + "异常";
} }
Message({ message: message, type: 'error', duration: 5 * 1000 }) Message({ message: message, type: "error", duration: 5 * 1000 });
return Promise.reject(error) return Promise.reject(error);
} }
) );
// 通用下载方法 // 通用下载方法
export function download(url, params, filename, config) { export function download(url, params, filename, config) {
downloadLoadingInstance = Loading.service({ text: "正在下载数据,请稍候", spinner: "el-icon-loading", background: "rgba(0, 0, 0, 0.7)", }) downloadLoadingInstance = Loading.service({
return service.post(url, params, { text: "正在下载数据,请稍候",
transformRequest: [(params) => { return tansParams(params) }], spinner: "el-icon-loading",
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, background: "rgba(0, 0, 0, 0.7)",
responseType: 'blob', });
...config return service
}).then(async (data) => { .post(url, params, {
transformRequest: [
(params) => {
return tansParams(params);
},
],
headers: { "Content-Type": "application/x-www-form-urlencoded" },
responseType: "blob",
...config,
})
.then(async (data) => {
const isBlob = blobValidate(data); const isBlob = blobValidate(data);
if (isBlob) { if (isBlob) {
const blob = new Blob([data]) const blob = new Blob([data]);
saveAs(blob, filename) saveAs(blob, filename);
} else { } else {
const resText = await data.text(); const resText = await data.text();
const rspObj = JSON.parse(resText); const rspObj = JSON.parse(resText);
const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default'] const errMsg =
errorCode[rspObj.code] || rspObj.msg || errorCode["default"];
Message.error(errMsg); Message.error(errMsg);
} }
downloadLoadingInstance.close(); downloadLoadingInstance.close();
}).catch((r) => {
console.error(r)
Message.error('下载文件出现错误,请联系管理员!')
downloadLoadingInstance.close();
}) })
.catch((r) => {
console.error(r);
Message.error("下载文件出现错误,请联系管理员!");
downloadLoadingInstance.close();
});
} }
export default service export default service;

@ -1,6 +1,11 @@
<template> <template>
<div class="login"> <div class="login">
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form"> <el-form
ref="loginForm"
:model="loginForm"
:rules="loginRules"
class="login-form"
>
<h3 class="title">花至后台管理系统</h3> <h3 class="title">花至后台管理系统</h3>
<el-form-item prop="username"> <el-form-item prop="username">
<el-input <el-input
@ -9,7 +14,11 @@
auto-complete="off" auto-complete="off"
placeholder="账号" placeholder="账号"
> >
<svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon" /> <svg-icon
slot="prefix"
icon-class="user"
class="el-input__icon input-icon"
/>
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item prop="password"> <el-form-item prop="password">
@ -20,7 +29,11 @@
placeholder="密码" placeholder="密码"
@keyup.enter.native="handleLogin" @keyup.enter.native="handleLogin"
> >
<svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" /> <svg-icon
slot="prefix"
icon-class="password"
class="el-input__icon input-icon"
/>
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item prop="code" v-if="captchaEnabled"> <el-form-item prop="code" v-if="captchaEnabled">
@ -31,26 +44,36 @@
style="width: 63%" style="width: 63%"
@keyup.enter.native="handleLogin" @keyup.enter.native="handleLogin"
> >
<svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon" /> <svg-icon
slot="prefix"
icon-class="validCode"
class="el-input__icon input-icon"
/>
</el-input> </el-input>
<div class="login-code"> <div class="login-code">
<img :src="codeUrl" @click="getCode" class="login-code-img" /> <img :src="codeUrl" @click="getCode" class="login-code-img" />
</div> </div>
</el-form-item> </el-form-item>
<el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;"></el-checkbox> <el-checkbox
<el-form-item style="width:100%;"> v-model="loginForm.rememberMe"
style="margin: 0px 0px 25px 0px"
>记住密码</el-checkbox
>
<el-form-item style="width: 100%">
<el-button <el-button
:loading="loading" :loading="loading"
size="medium" size="medium"
type="primary" type="primary"
style="width:100%;" style="width: 100%"
@click.native.prevent="handleLogin" @click.native.prevent="handleLogin"
> >
<span v-if="!loading"> </span> <span v-if="!loading"> </span>
<span v-else> ...</span> <span v-else> ...</span>
</el-button> </el-button>
<div style="float: right;" v-if="register"> <div style="float: right" v-if="register">
<router-link class="link-type" :to="'/register'">立即注册</router-link> <router-link class="link-type" :to="'/register'"
>立即注册</router-link
>
</div> </div>
</el-form-item> </el-form-item>
</el-form> </el-form>
@ -62,97 +85,106 @@
</template> </template>
<script> <script>
import { getCodeImg } from "@/api/login"; import { getCodeImg } from '@/api/login'
import Cookies from "js-cookie"; import Cookies from 'js-cookie'
import { encrypt, decrypt } from '@/utils/jsencrypt' import { encrypt, decrypt } from '@/utils/jsencrypt'
export default { export default {
name: "Login", name: 'Login',
data() { data() {
return { return {
codeUrl: "", codeUrl: '',
loginForm: { loginForm: {
username: "admin", username: 'admin',
password: "admin123", password: 'admin123',
rememberMe: false, rememberMe: false,
code: "", code: '',
uuid: "" uuid: '',
}, },
loginRules: { loginRules: {
username: [ username: [
{ required: true, trigger: "blur", message: "请输入您的账号" } { required: true, trigger: 'blur', message: '请输入您的账号' },
], ],
password: [ password: [
{ required: true, trigger: "blur", message: "请输入您的密码" } { required: true, trigger: 'blur', message: '请输入您的密码' },
], ],
code: [{ required: true, trigger: "change", message: "请输入验证码" }] code: [{ required: true, trigger: 'change', message: '请输入验证码' }],
}, },
loading: false, loading: false,
// //
captchaEnabled: true, captchaEnabled: true,
// //
register: false, register: false,
redirect: undefined redirect: undefined,
}; }
}, },
watch: { watch: {
$route: { $route: {
handler: function (route) { handler: function (route) {
this.redirect = route.query && route.query.redirect; this.redirect = route.query && route.query.redirect
},
immediate: true,
}, },
immediate: true
}
}, },
created() { created() {
this.getCode(); this.getCode()
this.getCookie(); this.getCookie()
}, },
methods: { methods: {
getCode() { getCode() {
getCodeImg().then(res => { getCodeImg().then((res) => {
this.captchaEnabled = res.captchaEnabled === undefined ? true : res.captchaEnabled; this.captchaEnabled =
res.captchaEnabled === undefined ? true : res.captchaEnabled
if (this.captchaEnabled) { if (this.captchaEnabled) {
this.codeUrl = "data:image/gif;base64," + res.img; this.codeUrl = 'data:image/gif;base64,' + res.img
this.loginForm.uuid = res.uuid; this.loginForm.uuid = res.uuid
} }
}); })
}, },
getCookie() { getCookie() {
const username = Cookies.get("username"); const username = Cookies.get('username')
const password = Cookies.get("password"); const password = Cookies.get('password')
const rememberMe = Cookies.get('rememberMe') const rememberMe = Cookies.get('rememberMe')
this.loginForm = { this.loginForm = {
username: username === undefined ? this.loginForm.username : username, username: username === undefined ? this.loginForm.username : username,
password: password === undefined ? this.loginForm.password : decrypt(password), password:
rememberMe: rememberMe === undefined ? false : Boolean(rememberMe) password === undefined ? this.loginForm.password : decrypt(password),
}; rememberMe: rememberMe === undefined ? false : Boolean(rememberMe),
}
}, },
handleLogin() { handleLogin() {
this.$refs.loginForm.validate(valid => { this.$refs.loginForm.validate((valid) => {
if (valid) { if (valid) {
this.loading = true; this.loading = true
if (this.loginForm.rememberMe) { if (this.loginForm.rememberMe) {
Cookies.set("username", this.loginForm.username, { expires: 30 }); Cookies.set('username', this.loginForm.username, { expires: 30 })
Cookies.set("password", encrypt(this.loginForm.password), { expires: 30 }); Cookies.set('password', encrypt(this.loginForm.password), {
Cookies.set('rememberMe', this.loginForm.rememberMe, { expires: 30 }); expires: 30,
})
Cookies.set('rememberMe', this.loginForm.rememberMe, {
expires: 30,
})
} else { } else {
Cookies.remove("username"); Cookies.remove('username')
Cookies.remove("password"); Cookies.remove('password')
Cookies.remove('rememberMe'); Cookies.remove('rememberMe')
} }
this.$store.dispatch("Login", this.loginForm).then(() => { this.$store
this.$router.push({ path: this.redirect || "/" }).catch(()=>{}); .dispatch('Login', this.loginForm)
}).catch(() => { .then(() => {
this.loading = false; this.$router.push({ path: this.redirect || '/' }).catch(() => {})
})
.catch(() => {
this.loading = false
if (this.captchaEnabled) { if (this.captchaEnabled) {
this.getCode(); this.getCode()
}
});
} }
}); })
} }
})
},
},
} }
};
</script> </script>
<style rel="stylesheet/scss" lang="scss"> <style rel="stylesheet/scss" lang="scss">
@ -161,7 +193,7 @@ export default {
justify-content: center; justify-content: center;
align-items: center; align-items: center;
height: 100%; height: 100%;
background-image: url("../assets/images/login-background.jpg"); background-image: url('../assets/images/login-background.jpg');
background-size: cover; background-size: cover;
} }
.title { .title {

@ -5,7 +5,12 @@
<el-form ref="form" :model="userAgreementFrom" label-width="80px"> <el-form ref="form" :model="userAgreementFrom" label-width="80px">
<el-row> <el-row>
<el-col :span="20"> <el-col :span="20">
<editor v-model="userAgreementFrom.userAgreement" :min-height="580"/> <editor
id="editor1"
tableName="editor1"
v-model="userAgreementFrom.userAgreement"
:min-height="580"
/>
</el-col> </el-col>
</el-row> </el-row>
</el-form> </el-form>
@ -14,7 +19,12 @@
<el-form ref="form" :model="privacyAgreementFrom" label-width="80px"> <el-form ref="form" :model="privacyAgreementFrom" label-width="80px">
<el-row> <el-row>
<el-col :span="20"> <el-col :span="20">
<editor v-model="privacyAgreementFrom.privacyAgreement" :min-height="580"/> <editor
id="editor2"
tableName="editor2"
v-model="privacyAgreementFrom.privacyAgreement"
:min-height="580"
/>
</el-col> </el-col>
</el-row> </el-row>
</el-form> </el-form>
@ -23,7 +33,12 @@
<el-form ref="form" :model="integralRuleFrom" label-width="80px"> <el-form ref="form" :model="integralRuleFrom" label-width="80px">
<el-row> <el-row>
<el-col :span="20"> <el-col :span="20">
<editor v-model="integralRuleFrom.integralRule" :min-height="580"/> <editor
id="editor3"
tableName="editor3"
v-model="integralRuleFrom.integralRule"
:min-height="580"
/>
</el-col> </el-col>
</el-row> </el-row>
</el-form> </el-form>
@ -32,37 +47,68 @@
<el-form ref="form" :model="aboutUsFrom" label-width="80px"> <el-form ref="form" :model="aboutUsFrom" label-width="80px">
<el-row> <el-row>
<el-col :span="20"> <el-col :span="20">
<editor v-model="aboutUsFrom.aboutUs" :min-height="580"/> <editor
id="editor4"
tableName="editor4"
v-model="aboutUsFrom.aboutUs"
:min-height="580"
/>
</el-col> </el-col>
</el-row> </el-row>
</el-form> </el-form>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="蓝牙指引权限" name="bluetoothGuidancePermissions"> <el-tab-pane label="蓝牙指引权限" name="bluetoothGuidancePermissions">
<el-form ref="form" :model="bluetoothGuidancePermissionsFrom" label-width="80px"> <el-form
ref="form"
:model="bluetoothGuidancePermissionsFrom"
label-width="80px"
>
<el-row> <el-row>
<el-col :span="20"> <el-col :span="20">
<editor v-model="bluetoothGuidancePermissionsFrom.bluetoothGuidancePermissions" :min-height="580"/> <editor
id="editor5"
tableName="editor5"
v-model="
bluetoothGuidancePermissionsFrom.bluetoothGuidancePermissions
"
:min-height="580"
/>
</el-col> </el-col>
</el-row> </el-row>
</el-form> </el-form>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="定位指引权限" name="locationGuidancePermissions"> <el-tab-pane label="定位指引权限" name="locationGuidancePermissions">
<el-form ref="form" :model="locationGuidancePermissionsFrom" label-width="80px"> <el-form
ref="form"
:model="locationGuidancePermissionsFrom"
label-width="80px"
>
<el-row> <el-row>
<el-col :span="20"> <el-col :span="20">
<editor v-model="locationGuidancePermissionsFrom.locationGuidancePermissions" :min-height="580"/> <editor
id="editor6"
tableName="editor6"
v-model="
locationGuidancePermissionsFrom.locationGuidancePermissions
"
:min-height="580"
/>
</el-col> </el-col>
</el-row> </el-row>
</el-form> </el-form>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="联系客服" name="contactWorker"> <el-tab-pane label="联系客服" name="contactWorker">
<div class="block" style="float: left; margin-left: 3%; margin-top: 3%"> <div class="block" style="float: left; margin-left: 3%; margin-top: 3%">
<el-image :src="contactWorkerFrom.contactWorkerSrc" style="width: 330px;height: 461px;"> <el-image
<div slot="placeholder" class="image-slot"><span class="dot"></span> :src="contactWorkerFrom.contactWorkerSrc"
style="width: 330px; height: 461px"
>
<div slot="placeholder" class="image-slot">
<span class="dot"></span>
</div> </div>
</el-image> </el-image>
</div> </div>
<div style="float: left;margin-left: 10%;margin-top: 10%;"> <div style="float: left; margin-left: 10%; margin-top: 10%">
<el-upload <el-upload
ref="upload" ref="upload"
:limit="1" :limit="1"
@ -75,41 +121,72 @@
drag drag
> >
<i class="el-icon-upload"></i> <i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处<em>点击上传</em></div> <div class="el-upload__text">
<div class="el-upload__tip" slot="tip">请上传联系客服页面图片建议尺寸为330px*461px</div> 将文件拖到此处<em>点击上传</em>
</div>
<div class="el-upload__tip" slot="tip">
请上传联系客服页面图片建议尺寸为330px*461px
</div>
</el-upload> </el-upload>
</div> </div>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="商城链接/版本管理" name="otherSetting"> <el-tab-pane label="商城链接/版本管理" name="otherSetting">
<el-form ref="form" :model="otherForm" :rules="rules" label-width="150px" style="margin-top: 1%"> <el-form
ref="form"
:model="otherForm"
:rules="rules"
label-width="150px"
style="margin-top: 1%"
>
<el-divider content-position="left">商城设置</el-divider> <el-divider content-position="left">商城设置</el-divider>
<el-form-item label="跳转商城appid" prop="skipAppid"> <el-form-item label="跳转商城appid" prop="skipAppid">
<el-input v-model="otherForm.skipAppid" style="width: 70%"></el-input> <el-input
v-model="otherForm.skipAppid"
style="width: 70%"
></el-input>
</el-form-item> </el-form-item>
<el-form-item label="跳转商城路径:" prop="skipPath"> <el-form-item label="跳转商城路径:" prop="skipPath">
<el-input v-model="otherForm.skipPath" style="width: 70%"></el-input> <el-input
v-model="otherForm.skipPath"
style="width: 70%"
></el-input>
</el-form-item> </el-form-item>
<el-divider content-position="left">版本管理设置</el-divider> <el-divider content-position="left">版本管理设置</el-divider>
<el-form-item label="当前版本:" prop="sysVersion"> <el-form-item label="当前版本:" prop="sysVersion">
<el-input v-model="otherForm.sysVersion" style="width: 70%"></el-input> <el-input
v-model="otherForm.sysVersion"
style="width: 70%"
></el-input>
</el-form-item> </el-form-item>
</el-form> </el-form>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
<div style="margin-left: 76%;margin-top: 2%" v-show="this.activeName != 'contactWorker'"> <div
style="margin-left: 76%; margin-top: 2%"
v-show="this.activeName != 'contactWorker'"
>
<el-button type="primary" @click="submitForm"> </el-button> <el-button type="primary" @click="submitForm"> </el-button>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import { listSetting, getSetting, delSetting, addSetting, updateSetting } from "@/api/system/systemSetting"; import {
import { listOtherSetting, addOtherSetting, updateOtherSetting} from "@/api/system/otherSetting"; listSetting,
import {getToken} from "@/utils/auth"; getSetting,
delSetting,
addSetting,
updateSetting,
} from '@/api/system/systemSetting'
import {
listOtherSetting,
addOtherSetting,
updateOtherSetting,
} from '@/api/system/otherSetting'
import { getToken } from '@/utils/auth'
export default { export default {
name: "Setting", name: 'Setting',
data() { data() {
return { return {
// //
@ -128,7 +205,7 @@ export default {
// //
settingList: [], settingList: [],
// //
title: "", title: '',
activeName: 'userAgreement', activeName: 'userAgreement',
// //
open: false, open: false,
@ -137,15 +214,15 @@ export default {
// //
open: false, open: false,
// //
title: "", title: '',
// //
isUploading: false, isUploading: false,
// //
updateSupport: 0, updateSupport: 0,
// //
headers: { Authorization: "Bearer " + getToken() }, headers: { Authorization: 'Bearer ' + getToken() },
// //
url: process.env.VUE_APP_BASE_API + "/file/upload" url: process.env.VUE_APP_BASE_API + '/file/upload',
}, },
// //
queryParams: { queryParams: {
@ -165,15 +242,11 @@ export default {
status: null, status: null,
}, },
// //
form: { form: {},
otherForm: {},
},
otherForm: {
},
userAgreementFrom: { userAgreementFrom: {
userAgreement: null, userAgreement: null,
userAgreementId: null userAgreementId: null,
}, },
privacyAgreementFrom: { privacyAgreementFrom: {
privacyAgreement: null, privacyAgreement: null,
@ -193,11 +266,11 @@ export default {
}, },
locationGuidancePermissionsFrom: { locationGuidancePermissionsFrom: {
locationGuidancePermissions: null, locationGuidancePermissions: null,
locationGuidancePermissionsId: null locationGuidancePermissionsId: null,
}, },
contactWorkerFrom: { contactWorkerFrom: {
contactWorkerSrc: null, contactWorkerSrc: null,
contactWorkerId: null contactWorkerId: null,
}, },
// //
rules: { rules: {
@ -210,176 +283,197 @@ export default {
sysVersion: [ sysVersion: [
{ required: true, message: '请输入当前版本', trigger: 'blur' }, { required: true, message: '请输入当前版本', trigger: 'blur' },
], ],
},
} }
};
}, },
created() { created() {
this.getList(); this.getList()
}, },
methods: { methods: {
handleClick(tab, event) { handleClick(tab, event) {
console.log(tab, event); console.log(tab, event)
}, },
/** 提交按钮 */ /** 提交按钮 */
submitForm() { submitForm() {
if (this.activeName == 'userAgreement') { if (this.activeName == 'userAgreement') {
if (this.userAgreementFrom.userAgreementId != null) { if (this.userAgreementFrom.userAgreementId != null) {
this.form.id = this.userAgreementFrom.userAgreementId; this.form.id = this.userAgreementFrom.userAgreementId
} }
this.form.key = 'USER_AGREEMENT'; this.form.key = 'USER_AGREEMENT'
if (!this.userAgreementFrom.userAgreement) { if (!this.userAgreementFrom.userAgreement) {
this.$modal.msgError('用户协议内容不能为空'); this.$modal.msgError('用户协议内容不能为空')
return ; return
} }
this.form.value = this.userAgreementFrom.userAgreement; this.form.value = this.userAgreementFrom.userAgreement
this.form.instructions = '用户协议'; this.form.instructions = '用户协议'
} }
if (this.activeName == 'privacyAgreement') { if (this.activeName == 'privacyAgreement') {
if (this.privacyAgreementFrom.privacyAgreementId != null) { if (this.privacyAgreementFrom.privacyAgreementId != null) {
this.form.id = this.privacyAgreementFrom.privacyAgreementId; this.form.id = this.privacyAgreementFrom.privacyAgreementId
} }
this.form.key = 'PRIVACY_AGREEMENT'; this.form.key = 'PRIVACY_AGREEMENT'
if (!this.privacyAgreementFrom.privacyAgreement) { if (!this.privacyAgreementFrom.privacyAgreement) {
this.$modal.msgError('隐私协议内容不能为空'); this.$modal.msgError('隐私协议内容不能为空')
return ; return
} }
this.form.instructions = '隐私协议'; this.form.instructions = '隐私协议'
this.form.value = this.privacyAgreementFrom.privacyAgreement; this.form.value = this.privacyAgreementFrom.privacyAgreement
} }
if (this.activeName == 'integralRule') { if (this.activeName == 'integralRule') {
if (this.integralRuleFrom.integralRuleId != null) { if (this.integralRuleFrom.integralRuleId != null) {
this.form.id = this.integralRuleFrom.integralRuleId; this.form.id = this.integralRuleFrom.integralRuleId
} }
this.form.key = 'INTEGRAL_RULE'; this.form.key = 'INTEGRAL_RULE'
if (!this.integralRuleFrom.integralRule) { if (!this.integralRuleFrom.integralRule) {
this.$modal.msgError('积分规则内容不能为空'); this.$modal.msgError('积分规则内容不能为空')
return ; return
} }
this.form.instructions = '积分规则'; this.form.instructions = '积分规则'
this.form.value = this.integralRuleFrom.integralRule; this.form.value = this.integralRuleFrom.integralRule
} }
if (this.activeName == 'aboutUs') { if (this.activeName == 'aboutUs') {
if (this.aboutUsFrom.aboutUsId != null) { if (this.aboutUsFrom.aboutUsId != null) {
this.form.id = this.aboutUsFrom.aboutUsId; this.form.id = this.aboutUsFrom.aboutUsId
} }
this.form.key = 'ABOUT_US'; this.form.key = 'ABOUT_US'
if (!this.aboutUsFrom.aboutUs) { if (!this.aboutUsFrom.aboutUs) {
this.$modal.msgError('关于我们内容不能为空'); this.$modal.msgError('关于我们内容不能为空')
return ; return
} }
this.form.instructions = '关于我们'; this.form.instructions = '关于我们'
this.form.value = this.aboutUsFrom.aboutUs; this.form.value = this.aboutUsFrom.aboutUs
} }
if (this.activeName == 'bluetoothGuidancePermissions') { if (this.activeName == 'bluetoothGuidancePermissions') {
if (this.bluetoothGuidancePermissionsFrom.bluetoothGuidancePermissionsId != null) { if (
this.form.id = this.bluetoothGuidancePermissionsFrom.bluetoothGuidancePermissionsId; this.bluetoothGuidancePermissionsFrom
} .bluetoothGuidancePermissionsId != null
this.form.key = 'BLUETOOTH_GUIDANCE_PERMISSIONS'; ) {
if (!this.bluetoothGuidancePermissionsFrom.bluetoothGuidancePermissions) { this.form.id =
this.$modal.msgError('蓝牙指引权限内容不能为空'); this.bluetoothGuidancePermissionsFrom.bluetoothGuidancePermissionsId
return ; }
} this.form.key = 'BLUETOOTH_GUIDANCE_PERMISSIONS'
this.form.instructions = '蓝牙指引权限'; if (
this.form.value = this.bluetoothGuidancePermissionsFrom.bluetoothGuidancePermissions; !this.bluetoothGuidancePermissionsFrom.bluetoothGuidancePermissions
) {
this.$modal.msgError('蓝牙指引权限内容不能为空')
return
}
this.form.instructions = '蓝牙指引权限'
this.form.value =
this.bluetoothGuidancePermissionsFrom.bluetoothGuidancePermissions
} }
if (this.activeName == 'locationGuidancePermissions') { if (this.activeName == 'locationGuidancePermissions') {
if (this.locationGuidancePermissionsFrom.locationGuidancePermissionsId != null) { if (
this.form.id = this.locationGuidancePermissionsFrom.locationGuidancePermissionsId; this.locationGuidancePermissionsFrom.locationGuidancePermissionsId !=
} null
this.form.key = 'LOCATION_GUIDANCE_PERMISSIONS'; ) {
this.form.id =
this.locationGuidancePermissionsFrom.locationGuidancePermissionsId
}
this.form.key = 'LOCATION_GUIDANCE_PERMISSIONS'
if (!this.locationGuidancePermissionsFrom.locationGuidancePermissions) { if (!this.locationGuidancePermissionsFrom.locationGuidancePermissions) {
this.$modal.msgError('定位指引权限内容不能为空'); this.$modal.msgError('定位指引权限内容不能为空')
return ; return
} }
this.form.instructions = '定位指引权限'; this.form.instructions = '定位指引权限'
this.form.value = this.locationGuidancePermissionsFrom.locationGuidancePermissions; this.form.value =
this.locationGuidancePermissionsFrom.locationGuidancePermissions
} }
if (this.form.value) {
this.form.value = this.form.value.replace(/\\/g, '') //
console.log(" this.form.value", this.form.value)
}
if (this.activeName != 'otherSetting') { if (this.activeName != 'otherSetting') {
if (this.form.id != null) { if (this.form.id != null) {
updateSetting(this.form).then(response => { updateSetting(this.form).then((response) => {
this.$modal.msgSuccess("修改成功"); this.$modal.msgSuccess('修改成功')
this.open = false; this.open = false
this.getList(); this.getList()
}); })
} else { } else {
addSetting(this.form).then(response => { addSetting(this.form).then((response) => {
this.$modal.msgSuccess("保存成功"); this.$modal.msgSuccess('保存成功')
this.open = false; this.open = false
this.getList(); this.getList()
}); })
} }
this.form.id = null; this.form.id = null
this.form.value = null; this.form.value = null
} else { } else {
this.$refs["form"].validate(valid => { this.$refs['form'].validate((valid) => {
if (valid) { if (valid) {
// //
if (this.otherForm.id != null) { if (this.otherForm.id != null) {
updateOtherSetting(this.otherForm).then(response => { updateOtherSetting(this.otherForm).then((response) => {
this.$modal.msgSuccess("修改成功"); this.$modal.msgSuccess('修改成功')
this.open = false; this.open = false
this.getList(); this.getList()
}); })
} else { } else {
addOtherSetting(this.otherForm).then(response => { addOtherSetting(this.otherForm).then((response) => {
this.$modal.msgSuccess("保存成功"); this.$modal.msgSuccess('保存成功')
this.open = false; this.open = false
this.getList(); this.getList()
}); })
} }
} }
}); })
} }
}, },
/** 查询平台参数设置列表 */ /** 查询平台参数设置列表 */
/** USER_AGREEMENT-用户协议 PRIVACY_AGREEMENT-隐私协议 INTEGRAL_RULE-积分规则 ABOUT_US-关于我们 BLUETOOTH_GUIDANCE_PERMISSIONS-蓝牙指引权限 LOCATION_GUIDANCE_PERMISSIONS - 定位指引权限 CONTACT_WORKER-联系客服 */ /** USER_AGREEMENT-用户协议 PRIVACY_AGREEMENT-隐私协议 INTEGRAL_RULE-积分规则 ABOUT_US-关于我们 BLUETOOTH_GUIDANCE_PERMISSIONS-蓝牙指引权限 LOCATION_GUIDANCE_PERMISSIONS - 定位指引权限 CONTACT_WORKER-联系客服 */
getList() { getList() {
this.loading = true; this.loading = true
listSetting(this.queryParams).then(response => { listSetting(this.queryParams).then((response) => {
this.settingList = response.rows; this.settingList = JSON.parse(JSON.stringify(response.rows))
this.total = response.total; this.total = response.total
this.loading = false; this.loading = false
// //
this.settingList.forEach((item) => { this.settingList.forEach((item) => {
if (item.key == 'USER_AGREEMENT') { if (item.key == 'USER_AGREEMENT') {
this.userAgreementFrom.userAgreement = item.value; this.userAgreementFrom.userAgreement = item.value
this.userAgreementFrom.userAgreementId = item.id; this.userAgreementFrom.userAgreementId = item.id
} }
if (item.key == 'PRIVACY_AGREEMENT') { if (item.key == 'PRIVACY_AGREEMENT') {
this.privacyAgreementFrom.privacyAgreement = item.value; this.privacyAgreementFrom.privacyAgreement = item.value
this.privacyAgreementFrom.privacyAgreementId = item.id; this.privacyAgreementFrom.privacyAgreementId = item.id
} }
if (item.key == 'INTEGRAL_RULE') { if (item.key == 'INTEGRAL_RULE') {
this.integralRuleFrom.integralRule = item.value; this.integralRuleFrom.integralRule = item.value
this.integralRuleFrom.integralRuleId = item.id; this.integralRuleFrom.integralRuleId = item.id
} }
if (item.key == 'ABOUT_US') { if (item.key == 'ABOUT_US') {
this.aboutUsFrom.aboutUs = item.value; this.aboutUsFrom.aboutUs = item.value
this.aboutUsFrom.aboutUsId = item.id; this.aboutUsFrom.aboutUsId = item.id
} }
if (item.key == 'BLUETOOTH_GUIDANCE_PERMISSIONS') { if (item.key == 'BLUETOOTH_GUIDANCE_PERMISSIONS') {
this.bluetoothGuidancePermissionsFrom.bluetoothGuidancePermissions = item.value; this.bluetoothGuidancePermissionsFrom.bluetoothGuidancePermissions =
this.bluetoothGuidancePermissionsFrom.bluetoothGuidancePermissionsId = item.id; item.value
this.bluetoothGuidancePermissionsFrom.bluetoothGuidancePermissionsId =
item.id
} }
if (item.key == 'LOCATION_GUIDANCE_PERMISSIONS') { if (item.key == 'LOCATION_GUIDANCE_PERMISSIONS') {
this.locationGuidancePermissionsFrom.locationGuidancePermissions = item.value; this.locationGuidancePermissionsFrom.locationGuidancePermissions =
this.locationGuidancePermissionsFrom.locationGuidancePermissionsId = item.id; item.value
this.locationGuidancePermissionsFrom.locationGuidancePermissionsId =
item.id
} }
if (item.key == 'CONTACT_WORKER') { if (item.key == 'CONTACT_WORKER') {
this.contactWorkerFrom.contactWorkerSrc = item.pictureUrl; this.contactWorkerFrom.contactWorkerSrc = item.pictureUrl
this.contactWorkerFrom.contactWorkerId = item.id; this.contactWorkerFrom.contactWorkerId = item.id
} }
}) })
}); })
listOtherSetting(this.otherQueryParams).then(response => { listOtherSetting(this.otherQueryParams).then((response) => {
this.otherForm = response.rows.length >0 ? response.rows[0]: {}; this.otherForm = response.rows.length > 0 ? response.rows[0] : {}
this.loading = false; this.loading = false
}); })
}, },
// //
cancel() { cancel() {
this.open = false; this.open = false
this.reset(); this.reset()
}, },
// //
reset() { reset() {
@ -393,41 +487,41 @@ export default {
createTime: null, createTime: null,
updateBy: null, updateBy: null,
updateTime: null, updateTime: null,
remark: null remark: null,
}; }
this.resetForm("form"); this.resetForm('form')
}, },
/** 搜索按钮操作 */ /** 搜索按钮操作 */
handleQuery() { handleQuery() {
this.queryParams.pageNum = 1; this.queryParams.pageNum = 1
this.getList(); this.getList()
}, },
/** 重置按钮操作 */ /** 重置按钮操作 */
resetQuery() { resetQuery() {
this.resetForm("queryForm"); this.resetForm('queryForm')
this.handleQuery(); this.handleQuery()
}, },
// //
handleSelectionChange(selection) { handleSelectionChange(selection) {
this.ids = selection.map(item => item.id) this.ids = selection.map((item) => item.id)
this.single = selection.length !== 1 this.single = selection.length !== 1
this.multiple = !selection.length this.multiple = !selection.length
}, },
/** 新增按钮操作 */ /** 新增按钮操作 */
handleAdd() { handleAdd() {
this.reset(); this.reset()
this.open = true; this.open = true
this.title = "添加平台参数设置"; this.title = '添加平台参数设置'
}, },
/** 修改按钮操作 */ /** 修改按钮操作 */
handleUpdate(row) { handleUpdate(row) {
this.reset(); this.reset()
const id = row.id || this.ids const id = row.id || this.ids
getSetting(id).then(response => { getSetting(id).then((response) => {
this.form = response.data; this.form = response.data
this.open = true; this.open = true
this.title = "修改平台参数设置"; this.title = '修改平台参数设置'
}); })
}, },
// //
handleFileUploadProgress(event, file, fileList) { handleFileUploadProgress(event, file, fileList) {
@ -438,29 +532,29 @@ export default {
handleFileSuccess(response, file, fileList) { handleFileSuccess(response, file, fileList) {
console.log('上传后的结果==>', JSON.stringify(response)) console.log('上传后的结果==>', JSON.stringify(response))
if (response.code == '200') { if (response.code == '200') {
this.contactWorkerFrom.contactWorkerSrc = response.data.url; this.contactWorkerFrom.contactWorkerSrc = response.data.url
this.form.key = 'CONTACT_WORKER'; this.form.key = 'CONTACT_WORKER'
this.form.instructions = '联系客服'; this.form.instructions = '联系客服'
this.form.pictureUrl = this.contactWorkerFrom.contactWorkerSrc; this.form.pictureUrl = this.contactWorkerFrom.contactWorkerSrc
if (this.contactWorkerFrom.contactWorkerId != null) { if (this.contactWorkerFrom.contactWorkerId != null) {
this.form.id = this.contactWorkerFrom.contactWorkerId; this.form.id = this.contactWorkerFrom.contactWorkerId
} }
// //
if (this.form.id != null) { if (this.form.id != null) {
updateSetting(this.form).then(response => { updateSetting(this.form).then((response) => {
this.$modal.msgSuccess("修改成功"); this.$modal.msgSuccess('修改成功')
this.open = false; this.open = false
this.getList(); this.getList()
}); })
} else { } else {
addSetting(this.form).then(response => { addSetting(this.form).then((response) => {
this.$modal.msgSuccess("保存成功"); this.$modal.msgSuccess('保存成功')
this.open = false; this.open = false
this.getList(); this.getList()
}); })
} }
this.form.id = null; this.form.id = null
this.form.pictureUrl = null; this.form.pictureUrl = null
} }
// this.upload.open = false; // this.upload.open = false;
// this.upload.isUploading = false; // this.upload.isUploading = false;
@ -470,20 +564,28 @@ export default {
}, },
/** 删除按钮操作 */ /** 删除按钮操作 */
handleDelete(row) { handleDelete(row) {
const ids = row.id || this.ids; const ids = row.id || this.ids
this.$modal.confirm('是否确认删除平台参数设置编号为"' + ids + '"的数据项?').then(function() { this.$modal
return delSetting(ids); .confirm('是否确认删除平台参数设置编号为"' + ids + '"的数据项?')
}).then(() => { .then(function () {
this.getList(); return delSetting(ids)
this.$modal.msgSuccess("删除成功"); })
}).catch(() => {}); .then(() => {
this.getList()
this.$modal.msgSuccess('删除成功')
})
.catch(() => {})
}, },
/** 导出按钮操作 */ /** 导出按钮操作 */
handleExport() { handleExport() {
this.download('system/setting/export', { this.download(
...this.queryParams 'system/setting/export',
}, `setting_${new Date().getTime()}.xlsx`) {
} ...this.queryParams,
},
`setting_${new Date().getTime()}.xlsx`
)
},
},
} }
};
</script> </script>

@ -11,6 +11,14 @@ const name = process.env.VUE_APP_TITLE || "花至管理系统"; // 网页标题
const port = process.env.port || process.env.npm_config_port || 80; // 端口 const port = process.env.port || process.env.npm_config_port || 80; // 端口
function getTargetUrl() {
if (process.env.NODE_ENV === "local") {
return "http://110.41.134.131:8080";
} else {
return `http://localhost:8080`;
}
}
// vue.config.js 配置说明 // vue.config.js 配置说明
//官方vue.config.js 参考文档 https://cli.vuejs.org/zh/config/#css-loaderoptions //官方vue.config.js 参考文档 https://cli.vuejs.org/zh/config/#css-loaderoptions
// 这里只列一部分,具体配置参考文档 // 这里只列一部分,具体配置参考文档
@ -35,7 +43,9 @@ module.exports = {
proxy: { proxy: {
// detail: https://cli.vuejs.org/config/#devserver-proxy // detail: https://cli.vuejs.org/config/#devserver-proxy
[process.env.VUE_APP_BASE_API]: { [process.env.VUE_APP_BASE_API]: {
target: `http://110.41.134.131:8080`, // target: `http://110.41.134.131:8080`,
target: `http://192.168.10.147:8080`,
changeOrigin: true, changeOrigin: true,
pathRewrite: { pathRewrite: {
["^" + process.env.VUE_APP_BASE_API]: "", ["^" + process.env.VUE_APP_BASE_API]: "",

Loading…
Cancel
Save