-
-
+
+
@@ -52,6 +55,18 @@
+
+
+
+
+ {{ t('layout.detectionLoginContent') }}
+
+
+
+
@@ -65,17 +80,43 @@ import useSystemStore from '@/stores/modules/system'
import useAppStore from '@/stores/modules/app'
import { useRoute, useRouter } from 'vue-router'
import { t } from '@/lang'
+import storage from '@/utils/storage'
+import useUserStore from '@/stores/modules/user'
const router = useRouter()
-
+const appType = storage.get('app_type')
const { toggle: toggleFullscreen, isFullscreen } = useFullscreen()
const systemStore = useSystemStore()
const appStore = useAppStore()
const route = useRoute()
const screenWidth = ref(window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth)
+// 检测登录 start
+const detectionLoginDialog = ref(false)
+const comparisonToken = ref('')
+const comparisonSiteId = ref('')
+if (storage.get('comparisonTokenStorage')) {
+ comparisonToken.value = storage.get('comparisonTokenStorage')
+ // storage.remove(['comparisonTokenStorage']);
+}
+if (storage.get('comparisonSiteIdStorage')) {
+ comparisonSiteId.value = storage.get('comparisonSiteIdStorage')
+ // storage.remove(['comparisonSiteIdStorage']);
+}
+// 监听标签页面切换
+document.addEventListener('visibilitychange', e => {
+ if (document.visibilityState === 'visible' && (comparisonSiteId.value != storage.get('siteId') || comparisonToken.value != storage.get('token'))) {
+ detectionLoginDialog.value = true
+ }
+})
+
+const detectionLoginFn = () => {
+ detectionLoginDialog.value = false
+ location.reload();
+}
+// 检测登录 end
-// 监听窗体宽度变化
onMounted(() => {
+ // 监听窗体宽度变化
window.onresize = () => {
return (() => {
screenWidth.value = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth
@@ -111,15 +152,15 @@ const refreshRouter = () => {
// 面包屑导航
const breadcrumb = computed(() => {
- const matched = route.matched
+ const matched = route.matched.filter(item => { return item.meta.title })
if (matched[0] && matched[0].path == '/') matched.splice(0, 1)
return matched
})
// 返回上一页
-const backFn = ()=>{
- router.go(-1);
-};
+const backFn = () => {
+ router.go(-1)
+}
+}
diff --git a/admin/src/router/index.ts b/admin/src/router/index.ts
index 02038c7ce..6198f0a5d 100644
--- a/admin/src/router/index.ts
+++ b/admin/src/router/index.ts
@@ -1,18 +1,29 @@
-import { createRouter, createWebHistory } from 'vue-router'
+import { createRouter, createWebHistory, RouteLocationRaw } from 'vue-router'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
-import { STATIC_ROUTES, NO_LOGIN_ROUTES, INDEX_ROUTE, findFirstValidRoute, DECORATE_ROUTER } from './routers'
+import { STATIC_ROUTES, NO_LOGIN_ROUTES, ROOT_ROUTER, ADMIN_ROUTE, SITE_ROUTE, DECORATE_ROUTER, findFirstValidRoute } from './routers'
import { language } from '@/lang'
import useSystemStore from '@/stores/modules/system'
import useUserStore from '@/stores/modules/user'
-import { setWindowTitle } from '@/utils/common'
+import { setWindowTitle, getAppType, urlToRouteRaw } from '@/utils/common'
import storage from '@/utils/storage'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
- routes: STATIC_ROUTES,
+ routes: [...STATIC_ROUTES, ADMIN_ROUTE, SITE_ROUTE]
})
+/**
+ * 重写push方法
+ */
+const originPush = router.push
+router.push = (to: RouteLocationRaw) => {
+ const route = typeof to == 'string' ? urlToRouteRaw(to) : to
+ const paths = route.path.split('/').filter((item: string) => { return item })
+ route.path = ['admin', 'site', 'decorate'].indexOf(paths[0]) == -1 ? `/${getAppType()}${route.path}` : route.path
+ return originPush(route)
+}
+
// 全局前置守卫
router.beforeEach(async (to, from, next) => {
NProgress.configure({ showSpinner: false })
@@ -23,19 +34,22 @@ router.beforeEach(async (to, from, next) => {
const userStore = useUserStore()
const siteInfo = storage.get('siteInfo') || false
let title = (to.meta?.title || '') + (siteInfo.site_name ? ('-' + siteInfo.site_name) : '')
+
// 设置网站标题
setWindowTitle(title)
// 加载语言包
await language.loadLocaleMessages(to.path, useSystemStore().lang);
+ const loginPath = to.path == '/' ? '/admin/login' : `${to.matched[0].path}/login`
+
// 判断是否需登录
if (NO_LOGIN_ROUTES.includes(to.path)) {
next()
} else if (userStore.token) {
// 如果已加载路由
if (userStore.routers.length) {
- if (to.path === '/login') {
- next('/')
+ if (to.path === loginPath) {
+ next(`/${getAppType()}`)
} else {
next()
}
@@ -45,8 +59,17 @@ router.beforeEach(async (to, from, next) => {
// 设置首页路由
const firstRoute = findFirstValidRoute(userStore.routers)
- INDEX_ROUTE.redirect = { name: firstRoute }
- router.addRoute(INDEX_ROUTE)
+ ROOT_ROUTER.redirect = { name: firstRoute }
+ router.addRoute(ROOT_ROUTER)
+
+ // 设置应用首页路由
+ if (getAppType() == 'admin') {
+ ADMIN_ROUTE.children[0].redirect = { name: firstRoute }
+ router.addRoute(ADMIN_ROUTE)
+ } else {
+ SITE_ROUTE.children[0].redirect = { name: firstRoute }
+ router.addRoute(SITE_ROUTE)
+ }
// 添加动态路由
userStore.routers.forEach(route => {
@@ -56,25 +79,35 @@ router.beforeEach(async (to, from, next) => {
router.addRoute(DECORATE_ROUTER)
return
}
+
if (!route.children) {
- router.addRoute('root', route)
+ if (route.meta.app == 'admin') {
+ router.addRoute(ADMIN_ROUTE.children[0].name, route)
+ } else {
+ router.addRoute(SITE_ROUTE.children[0].name, route)
+ }
return
}
+
// 动态添加可访问路由表
- router.addRoute(route)
+ if (route.meta.app == 'admin') {
+ router.addRoute(ADMIN_ROUTE.name, route)
+ } else {
+ router.addRoute(SITE_ROUTE.name, route)
+ }
})
next({ path: to.path, query: to.query, replace: true })
} catch (err) {
userStore.logout()
- next({ path: '/login', query: { redirect: to.fullPath } })
+ next({ path: loginPath, query: { redirect: to.fullPath } })
}
}
} else {
- if (to.path === '/login') {
+ if (to.path === loginPath) {
next()
} else {
- next({ path: '/login', query: { redirect: to.fullPath } })
+ next({ path: loginPath, query: { redirect: to.fullPath } })
}
}
})
diff --git a/admin/src/router/routers.ts b/admin/src/router/routers.ts
index 00fd18725..78495e335 100644
--- a/admin/src/router/routers.ts
+++ b/admin/src/router/routers.ts
@@ -4,52 +4,86 @@ import Decorate from '@/layout/decorate/index.vue'
// 静态路由
export const STATIC_ROUTES: Array
= [
- {
- path: `${import.meta.env.BASE_URL}`,
- component: Default,
- name: 'root'
- },
{
path: '/:pathMatch(.*)*',
component: () => import('@/views/error/404.vue')
- },
- {
- path: '/403',
- component: () => import('@/views/error/403.vue')
- },
- {
- path: '/login',
- component: () => import('@/views/login/index.vue')
- },
- {
- path: '/user',
- component: Default,
- children: [
- {
- path: 'center',
- meta: {
- type: 1,
- title: '个人中心'
- },
- component: () => import('@/views/index/personal.vue')
- }
- ]
}
]
// 免登录路由
export const NO_LOGIN_ROUTES: string[] = [
- '/403',
'/404'
]
-// 首页路由
-export const INDEX_ROUTE: RouteRecordRaw = {
+// 根路由
+export const ROOT_ROUTER: RouteRecordRaw = {
path: '/',
component: Default,
name: Symbol()
}
+// 平台端根路由
+export const ADMIN_ROUTE: RouteRecordRaw = {
+ path: '/admin',
+ name: Symbol('admin'),
+ children: [
+ {
+ path: '',
+ name: Symbol('adminRoot'),
+ component: Default
+ },
+ {
+ path: 'login',
+ component: () => import('@/views/login/index.vue')
+ },
+ {
+ path: 'user',
+ component: Default,
+ children: [
+ {
+ path: 'center',
+ meta: {
+ type: 1,
+ title: '个人中心'
+ },
+ component: () => import('@/views/index/personal.vue')
+ }
+ ]
+ }
+ ]
+}
+
+// 站点端路由
+export const SITE_ROUTE: RouteRecordRaw = {
+ path: '/site',
+ name: Symbol('site'),
+ children: [
+ {
+ path: '',
+ name: Symbol('siteRoot'),
+ component: Default
+ },
+ {
+ path: 'login',
+ component: () => import('@/views/login/index.vue')
+ },
+ {
+ path: 'user',
+ component: Default,
+ children: [
+ {
+ path: 'center',
+ meta: {
+ type: 1,
+ title: '个人中心'
+ },
+ component: () => import('@/views/index/personal.vue')
+ }
+ ]
+ }
+ ]
+}
+
// 装修路由
export const DECORATE_ROUTER: RouteRecordRaw = {
path: '/decorate',
@@ -70,7 +104,8 @@ interface Route {
type: string
},
children?: [],
- is_show: boolean
+ is_show: boolean,
+ app_type: string
}
/**
@@ -80,13 +115,14 @@ interface Route {
*/
const createRoute = function (route: Route, parentRoute: RouteRecordRaw | null = null): RouteRecordRaw {
const record: RouteRecordRaw = {
- path: parentRoute ? route.router_path : '/' + route.router_path,
+ path: parentRoute ? route.router_path : route.router_path != 'decorate' ? `/${route.app_type}/${route.router_path}` : `/${route.router_path}`,
name: parentRoute ? Symbol(`${parentRoute.path}/${route.router_path}`) : Symbol(`/${route.router_path}`),
meta: {
title: route.menu_name,
icon: route.icon,
type: route.menu_type,
- show: route.is_show
+ show: route.is_show,
+ app: route.app_type
}
}
if (route.menu_type == 0) {
diff --git a/admin/src/stores/modules/diy.ts b/admin/src/stores/modules/diy.ts
index 2320c836e..65bb30875 100644
--- a/admin/src/stores/modules/diy.ts
+++ b/admin/src/stores/modules/diy.ts
@@ -50,20 +50,19 @@ const useDiyStore = defineStore('diy', {
},
actions: {
// 添加组件
- addComponent(data: any) {
+ addComponent(key: string, data: any) {
// 加载完才能添加组件
- if(!this.load) return;
+ if (!this.load) return;
// 删除不用的字段
let component = cloneDeep(data);
component.id = this.generateRandom();
- component.componentName = component.name;
+ component.componentName = key;
component.componentTitle = component.title;
component.maxCount = component.max_count;
Object.assign(component, component.value);
- delete component.name;
delete component.title;
delete component.value;
delete component.type;
diff --git a/admin/src/stores/modules/user.ts b/admin/src/stores/modules/user.ts
index 5fe81bd36..8f22a50e2 100644
--- a/admin/src/stores/modules/user.ts
+++ b/admin/src/stores/modules/user.ts
@@ -1,9 +1,9 @@
import { defineStore } from 'pinia'
-import { getToken, setToken, removeToken } from '@/utils/common'
+import { getToken, setToken, removeToken, getAppType } from '@/utils/common'
import { login, getAuthMenus } from '@/api/auth'
import storage from '@/utils/storage'
import router from '@/router'
-import { formatRouters, INDEX_ROUTE } from '@/router/routers'
+import { formatRouters } from '@/router/routers'
import useTabbarStore from './tabbar'
interface User {
@@ -25,9 +25,9 @@ const useSystemStore = defineStore('user', {
}
},
actions: {
- login(form: object) {
+ login(form: object, app_type: any) {
return new Promise((resolve, reject) => {
- login(form)
+ login(form, app_type)
.then((res) => {
this.token = res.data.token
this.userInfo = res.data.userinfo
@@ -35,6 +35,8 @@ const useSystemStore = defineStore('user', {
storage.set({ key: 'userinfo', data: res.data.userinfo })
storage.set({ key: 'siteId', data: res.data.site_id })
storage.set({ key: 'siteInfo', data: res.data.site_info })
+ storage.set({ key: 'comparisonSiteIdStorage', data: res.data.site_id })
+ storage.set({ key: 'comparisonTokenStorage', data: res.data.token })
resolve(res)
})
.catch((error) => {
@@ -48,15 +50,10 @@ const useSystemStore = defineStore('user', {
this.siteInfo = {}
removeToken()
storage.remove(['userinfo', 'siteId', 'siteInfo'])
- // 清除路由
- this.routers.forEach(item => {
- router.removeRoute(item.name)
- })
- router.removeRoute(INDEX_ROUTE.name)
this.routers = []
// 清除tabbar
useTabbarStore().clearTab()
- router.push('/login')
+ router.push(`/${getAppType()}/login`)
},
getAuthMenus() {
return new Promise((resolve, reject) => {
diff --git a/admin/src/styles/iconfont.css b/admin/src/styles/iconfont.css
index 0e5098bb0..1c4ba1fe7 100644
--- a/admin/src/styles/iconfont.css
+++ b/admin/src/styles/iconfont.css
@@ -1,8 +1,8 @@
@font-face {
font-family: "iconfont"; /* Project id 3883393 */
- src: url('//at.alicdn.com/t/c/font_3883393_c2tb4v0fz24.woff2?t=1681374762000') format('woff2'),
- url('//at.alicdn.com/t/c/font_3883393_c2tb4v0fz24.woff?t=1681374762000') format('woff'),
- url('//at.alicdn.com/t/c/font_3883393_c2tb4v0fz24.ttf?t=1681374762000') format('truetype');
+ src: url('//at.alicdn.com/t/c/font_3883393_4jlgm3tby7.woff2?t=1683947082967') format('woff2'),
+ url('//at.alicdn.com/t/c/font_3883393_4jlgm3tby7.woff?t=1683947082967') format('woff'),
+ url('//at.alicdn.com/t/c/font_3883393_4jlgm3tby7.ttf?t=1683947082967') format('truetype');
}
.iconfont {
@@ -13,6 +13,46 @@
-moz-osx-font-smoothing: grayscale;
}
+.icontuikuanjilu:before {
+ content: "\e8cf";
+}
+
+.icongengxinhuancun:before {
+ content: "\e686";
+}
+
+.iconsixingjiance:before {
+ content: "\e645";
+}
+
+.iconzhuceshezhi:before {
+ content: "\e6ad";
+}
+
+.iconmanage-apply:before {
+ content: "\e619";
+}
+
+.iconyingyongguanli:before {
+ content: "\e61f";
+}
+
+.iconkaifazheguanli:before {
+ content: "\e624";
+}
+
+.iconlianmengguanli:before {
+ content: "\e65f";
+}
+
+.icondianzan:before {
+ content: "\ec7f";
+}
+
+.iconh5e:before {
+ content: "\e654";
+}
+
.iconyingyongshichang:before {
content: "\e618";
}
diff --git a/admin/src/utils/common.ts b/admin/src/utils/common.ts
index aed44a0cd..c27ceef6c 100644
--- a/admin/src/utils/common.ts
+++ b/admin/src/utils/common.ts
@@ -1,8 +1,9 @@
-import type {App} from 'vue'
+import type { App } from 'vue'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
-import {useCssVar, useTitle} from '@vueuse/core'
+import { useCssVar, useTitle } from '@vueuse/core'
import colorFunction from 'css-color-function'
import storage from './storage'
+import { useRoute } from 'vue-router'
/**
* 全局注册element-icon
@@ -45,6 +46,20 @@ export function setThemeColor(color: string, mode: string = 'light'): void {
})
}
+/**
+ * 获取当前访问应用类型
+ */
+export function getAppType() {
+ const path = location.pathname.split('/').filter((val) => { return val })
+
+ if (!path.length) {
+ return 'admin'
+ } else {
+ const app = path[0]
+ return app == 'decorate' ? 'site' : app
+ }
+}
+
/**
* 设置网站 title
* @param value
@@ -68,7 +83,7 @@ export function getToken(): null | string {
* @returns
*/
export function setToken(token: string): void {
- storage.set({key: 'token', data: token})
+ storage.set({ key: 'token', data: token })
}
/**
@@ -142,4 +157,20 @@ export function getWapDomain(): string {
} else {
return (import.meta.env.VITE_WAP_DOMAIN || location.origin + '/wap') + (storage.get('siteId') == 1 ? '' : '/s' + storage.get('siteId'));
}
+}
+
+/**
+ * url 转 route
+ * @param url
+ */
+export function urlToRouteRaw(url: string) {
+ const query = {}
+ const [path, param] = url.split('?')
+
+ param && param.split('&').forEach((str : string) => {
+ let [name, value] = str.split('=')
+ query[name] = value
+ })
+
+ return { path, query }
}
\ No newline at end of file
diff --git a/admin/src/utils/request.ts b/admin/src/utils/request.ts
index 180c8ee0c..ca266994f 100644
--- a/admin/src/utils/request.ts
+++ b/admin/src/utils/request.ts
@@ -52,7 +52,7 @@ class Request {
this.instance.interceptors.response.use(
(response: requestResponse) => {
const res = response.data
- if (res.code != 200) {
+ if (res.code != 1) {
this.handleAuthError(res.code)
if (response.config.showErrorMessage) ElMessage({ message: res.msg, type: 'error' })
return Promise.reject(new Error(res.msg || 'Error'))
diff --git a/admin/src/utils/storage.ts b/admin/src/utils/storage.ts
index 730090c24..7995c83b7 100644
--- a/admin/src/utils/storage.ts
+++ b/admin/src/utils/storage.ts
@@ -1,3 +1,5 @@
+import { getAppType } from './common'
+
interface setParam {
key: string,
data: any,
@@ -6,6 +8,11 @@ interface setParam {
}
class Storage {
+ private prefix = ''
+
+ public constructor() {
+ this.prefix = getAppType()
+ }
/**
* 设置缓存
@@ -13,7 +20,7 @@ class Storage {
*/
public set(param: setParam) {
try {
- window.localStorage.setItem(param.key, JSON.stringify(param.data))
+ window.localStorage.setItem(`${this.prefix}.${param.key}`, JSON.stringify(param.data))
typeof param.success == 'function' && param.success()
} catch (error) {
typeof param.fail == 'function' && param.fail(error)
@@ -27,7 +34,7 @@ class Storage {
*/
public get(key: string) {
try {
- const json: any = window.localStorage.getItem(key)
+ const json: any = window.localStorage.getItem(`${this.prefix}.${key}`)
return JSON.parse(json)
} catch (error) {
return null
@@ -39,8 +46,8 @@ class Storage {
* @param key
*/
public remove(key: string | string[]) {
- if (typeof key == 'string') window.localStorage.removeItem(key)
- else key.forEach(item => { window.localStorage.removeItem(item) })
+ if (typeof key == 'string') window.localStorage.removeItem(`${this.prefix}.${key}`)
+ else key.forEach(item => { window.localStorage.removeItem(`${this.prefix}.${item}`) })
}
/**
diff --git a/admin/src/views/app/index.vue b/admin/src/views/app/index.vue
new file mode 100644
index 000000000..dddca3a2a
--- /dev/null
+++ b/admin/src/views/app/index.vue
@@ -0,0 +1,63 @@
+
+
+
+
{{ listItems.name }}
+
+
+
+
+
+
+
{{ appItems.title }}
+
{{ appItems.desc }}
+
+
+
+
+
+
+
+
+
+
{{ appItems.title }}
+
{{ appItems.desc }}
+
+
+
+
+
+
+
+
+
+
diff --git a/admin/src/views/article/components/edit-category.vue b/admin/src/views/article/components/edit-category.vue
index 7c86005c1..e8e48f27d 100644
--- a/admin/src/views/article/components/edit-category.vue
+++ b/admin/src/views/article/components/edit-category.vue
@@ -1,14 +1,14 @@
-
-
+
+
-
+
{{ t('show') }}
@@ -32,9 +32,9 @@
import { ref, reactive, computed } from 'vue'
import { t } from '@/lang'
import type { FormInstance } from 'element-plus'
-import { addArticleCategory, updateArticleCategory, getArticleCategoryInfo } from '@/api/article'
+import { addArticleCategory, editArticleCategory, getArticleCategoryInfo } from '@/api/article'
-let popTitle:string = '';
+let popTitle: string = '';
let showDialog = ref(false)
const loading = ref(true)
@@ -42,7 +42,7 @@ const loading = ref(true)
/**
* 表单数据
*/
- const initialFormData = {
+const initialFormData = {
category_id: '',
name: '',
sort: '',
@@ -55,34 +55,34 @@ const formRef = ref()
// 表单验证规则
const formRules = computed(() => {
return {
- name: [
- { required: true, message: t('namePlaceholder'), trigger: 'blur' },
- {
- validator: (rule: any, value: string, callback: any) => {
- if (value.length > 20) {
- callback(new Error(t('nameMax')))
- }
-
- callback()
- },
- trigger: 'blur'
- }
- ],
- sort: [
- {
- validator: (rule: any, value: string, callback: any) => {
- if(value === "" || isNaN(value)){
- callback(new Error(t('sortNumber')))
- }
- if (parseInt(value) > 10000) {
- callback(new Error(t('sortBetween')))
- }
- callback()
- },
- trigger: 'blur'
- }
- ],
-
+ name: [
+ { required: true, message: t('namePlaceholder'), trigger: 'blur' },
+ {
+ validator: (rule: any, value: string, callback: any) => {
+ if (value.length > 20) {
+ callback(new Error(t('nameMax')))
+ }
+
+ callback()
+ },
+ trigger: 'blur'
+ }
+ ],
+ sort: [
+ {
+ validator: (rule: any, value: string, callback: any) => {
+ if (value === "" || isNaN(value)) {
+ callback(new Error(t('sortNumber')))
+ }
+ if (parseInt(value) > 10000) {
+ callback(new Error(t('sortBetween')))
+ }
+ callback()
+ },
+ trigger: 'blur'
+ }
+ ],
+
}
})
@@ -94,7 +94,7 @@ const emit = defineEmits(['complete'])
*/
const confirm = async (formEl: FormInstance | undefined) => {
if (loading.value || !formEl) return
- let save = formData.category_id ? updateArticleCategory : addArticleCategory
+ let save = formData.category_id ? editArticleCategory : addArticleCategory
await formEl.validate(async (valid) => {
if (valid) {
diff --git a/admin/src/views/article/edit.vue b/admin/src/views/article/edit.vue
index e46a3fe30..3057e26ea 100644
--- a/admin/src/views/article/edit.vue
+++ b/admin/src/views/article/edit.vue
@@ -1,7 +1,8 @@
-
+
@@ -62,10 +63,11 @@
import { ref, reactive, computed, watch } from 'vue'
import { t } from '@/lang'
import type { FormInstance, ElNotification } from 'element-plus'
-import { getArticleInfo, getArticleCategoryAll, addArticle, updateArticle } from '@/api/article'
+import { getArticleInfo, getArticleCategoryAll, addArticle, editArticle } from '@/api/article'
import { useRoute, useRouter } from 'vue-router'
import useTabbarStore from '@/stores/modules/tabbar'
import useAppStore from '@/stores/modules/app'
+import { ElMessage } from 'element-plus'
const route = useRoute()
const router = useRouter()
@@ -77,7 +79,7 @@ const appStore = useAppStore()
// 页面返回按钮
appStore.pageReturn = true;
-watch(route, (newX,oldX) => {
+watch(route, (newX, oldX) => {
appStore.pageReturn = false;
});
@@ -104,16 +106,23 @@ const formData: Record = reactive({ ...initialFormData })
const setFormData = async (id: number = 0) => {
loading.value = true;
Object.assign(formData, initialFormData)
- if(id){
+ if (id) {
const data = await (await getArticleInfo(id)).data
+ if (!data || Object.keys(data).length == 0) {
+ ElMessage.error(t('articleNull'))
+ setTimeout(() => {
+ router.go(-1);
+ }, 2000)
+ return false;
+ }
Object.keys(formData).forEach((key: string) => {
if (data[key] != undefined) formData[key] = data[key]
})
loading.value = false;
- }else{
+ } else {
loading.value = false;
}
-
+
}
if (id) setFormData(id)
@@ -139,9 +148,9 @@ const formRules = computed(() => {
{
validator: (rule: any, value: string, callback: any) => {
let content = value.replace(/<[^<>]+>/g, "").replace(/ /gi, "")
- if(!content && value.indexOf('img') === -1){
+ if (!content && value.indexOf('img') === -1) {
callback(new Error(t('contentPlaceholder')))
- }else callback()
+ } else callback()
},
trigger: ['blur', 'change']
}
@@ -155,7 +164,7 @@ const onSave = async (formEl: FormInstance | undefined) => {
if (valid) {
loading.value = true
const data = formData
- const save = id ? updateArticle : addArticle
+ const save = id ? editArticle : addArticle
save(data).then(res => {
loading.value = false
back();
diff --git a/admin/src/views/article/list.vue b/admin/src/views/article/list.vue
index db5639126..c637130d1 100644
--- a/admin/src/views/article/list.vue
+++ b/admin/src/views/article/list.vue
@@ -1,7 +1,7 @@
-
+
{{ t('addArticle') }}
@@ -14,8 +14,8 @@
-
+
@@ -34,18 +34,18 @@
-
+
-
-
+
+
-
+
+
+
-
-
{{ t('show') }}
@@ -83,8 +83,8 @@
-
+
diff --git a/admin/src/views/channel/pc/config.vue b/admin/src/views/channel/pc/config.vue
index fbac7de9f..4b20e466d 100644
--- a/admin/src/views/channel/pc/config.vue
+++ b/admin/src/views/channel/pc/config.vue
@@ -1,12 +1,21 @@
-
-
+
+
{{ t('pcInfo') }}
-
+
+
+
+
+
+
+ {{ t('copy') }}
+
+
+ {{t('clickVisit')}}
@@ -15,9 +24,65 @@
-
+
diff --git a/admin/src/views/channel/weapp/template.vue b/admin/src/views/channel/weapp/template.vue
index bfbda5edd..52676ad46 100644
--- a/admin/src/views/channel/weapp/template.vue
+++ b/admin/src/views/channel/weapp/template.vue
@@ -3,7 +3,7 @@
- {{t('operationTip')}} 1、{{ t('operationTipOne') }}
+ {{ t('operationTip') }} 1、{{ t('operationTipOne') }}
2、{{ t('operationTipTwo') }}
@@ -51,7 +51,7 @@
import { reactive, ref } from 'vue'
import { t } from '@/lang'
import { getTemplateList, getBatchAcquisition } from '@/api/weapp'
-import { updateMessageStatus } from '@/api/message'
+import { editMessageStatus } from '@/api/notice'
import { ElLoading } from 'element-plus'
const cronTableData = reactive({
@@ -105,7 +105,7 @@ const infoSwitch = (res) => {
data.value.key = res.key
data.value.type = 'weapp'
cronTableData.loading = true
- updateMessageStatus(data.value).then(res => {
+ editMessageStatus(data.value).then(res => {
loadCronList()
}).catch(() => {
cronTableData.loading = false
@@ -115,13 +115,15 @@ const infoSwitch = (res) => {
diff --git a/admin/src/views/channel/wechat/config.vue b/admin/src/views/channel/wechat/config.vue
index ddc67201a..ffac99c03 100644
--- a/admin/src/views/channel/wechat/config.vue
+++ b/admin/src/views/channel/wechat/config.vue
@@ -129,7 +129,7 @@
diff --git a/admin/src/views/diy/edit.vue b/admin/src/views/diy/edit.vue
index f5392d2a5..5ad54e1b0 100644
--- a/admin/src/views/diy/edit.vue
+++ b/admin/src/views/diy/edit.vue
@@ -1,365 +1,374 @@
+
+
+
+
+
+
+
{{ t('back') }}
+
+
+ | {{ t('decorating') }}:{{ diyStore.typeName }}
+
+
+
+ {{ t('save') }}
+
-
-
-
-
- | {{ t('decorating') }}:{{ diyStore.typeName }}
-
-
-
- {{ t('save') }}
-
+
-
+
-
+
+
+
+
+
+
+
+ {{ compItem.title }}
+
+
+
+
+
-
-
-
-
-
-
-
- {{compItem.title}}
-
-
-
-
-
+
-
+
-
+
+ {{
+ t('pageSet') }}
+
+
+ {{
+ diyStore.global.title }}
+
+
-
- {{ t('pageSet')}}
-
-
- {{ diyStore.global.title }}
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
+
+
+
-
-
-
+
-
+
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
-
-
-
-
+
+
\ No newline at end of file
+.edit-attribute-wrap .box-card {
+ border: none;
+}
\ No newline at end of file
diff --git a/admin/src/views/diy/index.vue b/admin/src/views/diy/index.vue
index d4192ee6d..924a84928 100644
--- a/admin/src/views/diy/index.vue
+++ b/admin/src/views/diy/index.vue
@@ -49,18 +49,21 @@
import {t} from '@/lang'
import {useRoute, useRouter} from 'vue-router'
import {getWeappConfig} from '@/api/weapp'
+ import {getUrl} from '@/api/sys'
import {useClipboard} from '@vueuse/core'
import {ElMessage} from 'element-plus'
import {img} from '@/utils/common'
- import {getWapDomain} from '@/utils/common'
import QRCode from "qrcode";
- const wapDomain = ref(getWapDomain() + '/pages/index/index')
+ const wapDomain = ref('')
const wapImage = ref('')
- QRCode.toDataURL(wapDomain.value, {errorCorrectionLevel: 'L', margin: 0, width: 100}).then(url => {
- wapImage.value = url
- })
+ getUrl().then((res:any)=>{
+ wapDomain.value = res.data.wap_url + '/pages/index/index'
+ QRCode.toDataURL(wapDomain.value, {errorCorrectionLevel: 'L', margin: 0, width: 100}).then(url => {
+ wapImage.value = url
+ })
+ });
const router = useRouter()
@@ -84,6 +87,7 @@
path: '/decorate/edit',
query: {name: 'DIY_INDEX'}
});
+
const toDecorate = () => {
router.push('/decorate/edit?name=DIY_INDEX')
// window.open(url.href);
diff --git a/admin/src/views/diy/list.vue b/admin/src/views/diy/list.vue
index 4b28a7d0c..cdbcfd19d 100644
--- a/admin/src/views/diy/list.vue
+++ b/admin/src/views/diy/list.vue
@@ -1,465 +1,507 @@
-
-
-
-
- {{ t('addDiyPage') }}
-
-
+
+
+
+
+ {{ t('addDiyPage') }}
+
+
-
-
-
-
-
-
- {{ t('search') }}
- {{ t('reset') }}
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ t('search') }}
- {{ t('reset') }}
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ t('search') }}
+ {{ t('reset') }}
+
+
+
+
+
+
+
+ {{ t('search') }}
+ {{ t('reset') }}
+
+
+
-
+
-
-
+
+
-
+
-
- {{ !diyPageTableData.loading ? t('emptyData') : '' }}
-
+
+ {{ !diyPageTableData.loading ? t('emptyData') : '' }}
+
-
-
-
-
- -
-
- {{ t('isUse') }}
- {{ t('unused') }}
-
-
-
-
+
+
+
+
+ -
+
+ {{ t('isUse') }}
+ {{ t('unused') }}
+
+
+
+
-
-
- {{ t('promote') }}
- {{ t('use') }}
- {{ t('shareSet') }}
- {{ t('edit') }}
- {{ t('delete') }}
-
-
+
+
+ {{ t('promote') }}
+ {{ t('use') }}
+ {{
+ t('shareSet') }}
+ {{ t('edit') }}
+ {{ t('delete') }}
+
+
-
-
-
-
-
-
-
-
-
- {{ !diyRouteTableData.loading ? t('emptyData') : '' }}
-
-
-
-
- {{ getWapDomain() + row.page }}
- {{ t('copy') }}
-
-
-
-
- {{ row.page }}
- {{ t('copy') }}
-
-
-
-
- {{ t('shareSet') }}
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+ {{ !diyRouteTableData.loading ? t('emptyData') : '' }}
+
+
+
+
+ {{ wapDomain + row.page }}
+ {{ t('copy')
+ }}
+
+
+
+
+ {{ row.page }}
+ {{ t('copy') }}
+
+
+
+
+ {{
+ t('shareSet') }}
+
+
+
+
-
+
-
+
-
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
-
-
-
-
- {{ sharePage }}
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+ {{ sharePage }}
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
-
- {{ t('copy') }}
-
-
-
-
-
-
-
+
+
+
+
+
+
+ {{ t('copy')
+ }}
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
+
-
+
\ No newline at end of file
diff --git a/admin/src/views/diy/member.vue b/admin/src/views/diy/member.vue
index fa910ab94..06bdb94d4 100644
--- a/admin/src/views/diy/member.vue
+++ b/admin/src/views/diy/member.vue
@@ -5,9 +5,6 @@
diff --git a/admin/src/views/error/404.vue b/admin/src/views/error/404.vue
index caa3d7f05..a4a5564b4 100644
--- a/admin/src/views/error/404.vue
+++ b/admin/src/views/error/404.vue
@@ -1,9 +1,56 @@
-
-
+
+
+
+ 404
+
+
页面不存在
+
+
+ {{ second }} 秒后返回上一页
+
+
+
+
+
diff --git a/admin/src/views/error/components/error.vue b/admin/src/views/error/components/error.vue
deleted file mode 100644
index c1d3dc92c..000000000
--- a/admin/src/views/error/components/error.vue
+++ /dev/null
@@ -1,58 +0,0 @@
-
-
-
-
- {{ code }}
-
-
{{ title }}
-
- {{ second }} 秒后返回上一页
-
-
-
-
-
-
-
-
diff --git a/admin/src/views/finance/cash_out.vue b/admin/src/views/finance/cash_out.vue
new file mode 100644
index 000000000..b518a398b
--- /dev/null
+++ b/admin/src/views/finance/cash_out.vue
@@ -0,0 +1,332 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ t('search') }}
+ {{ t('reset') }}
+
+
+
+
+
+
+
+ {{ !orderTableData.loading ? t('emptyData') : '' }}
+
+
+
+
+
+
+
+
+ {{ row.nickname || '' }}
+ {{ row.mobile || '' }}
+
+
+
+
+
+
+
+
+ {{ Transfertype[row.transfer_type].name }}
+
+
+
+
+
+
+
+ {{ t('actualTransferAmount') }} :{{ row.money }}
+ {{ t('cashOutCommission') }} :{{ row.service_money }}
+
+
+
+
+
+
+
+ {{ row.create_time || '' }}
+
+
+
+
+
+ {{ item }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ cashOutInfo.nickname }}
+
+
+ {{ cashOutInfo.account_type_name }}
+
+
+ {{ Transfertype[cashOutInfo.transfer_type].name }}
+
+
+ {{ cashOutInfo.apply_money }}
+
+
+ {{ cashOutInfo.service_money }}
+
+
+ {{ cashOutInfo.money }}
+
+
+ {{ cashOutInfo.status_name }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{t('isTransfer')}}
+
+
+
+
+
+
+
+
+
+
diff --git a/admin/src/views/finance/recharge/list.vue b/admin/src/views/finance/recharge/list.vue
index 1d14b2939..49b00fb02 100644
--- a/admin/src/views/finance/recharge/list.vue
+++ b/admin/src/views/finance/recharge/list.vue
@@ -2,7 +2,7 @@
-
+
+
+ {{t('refundContent')}}
+
+
+
+
-
-
diff --git a/admin/src/views/index/index.vue b/admin/src/views/index/index.vue
index 810dff494..8fe896404 100644
--- a/admin/src/views/index/index.vue
+++ b/admin/src/views/index/index.vue
@@ -4,31 +4,39 @@
-
-
-
-
- {{t('memberNumb')}}
-
-
-
-
+
+
+
- {{t('numberOfSites')}}
+ {{t('siteSum')}}
-
-
+
+
- {{t('numberOfVisitors')}}
+ {{t('memberSum')}}
+
+
+
+ {{t('appSum')}}
+
+
+
+
+
+
+ {{t('installAppSun')}}
+
+
+
@@ -40,21 +48,21 @@
-
+
-
{{t('articleList')}}
+
{{t('siteList')}}
-
+
-
{{t('memberManagement')}}
+
{{t('sitePackage')}}
-
+
-
{{t('balanceAccount')}}
+
{{t('newSite')}}
@@ -64,9 +72,9 @@
-
+
-
{{t('WebDecoration')}}
+
{{t('appMarketplace')}}
@@ -76,18 +84,18 @@
-
+
-
+
@@ -104,7 +112,7 @@
-